From 1d8719a1488c5ffbf64e149d0fab42a50e9e34f4 Mon Sep 17 00:00:00 2001 From: Matt Silverlock Date: Thu, 24 Jul 2014 19:35:35 +0800 Subject: [PATCH] Changed references to encrypt/decrypt to mask/unmask. This change clarifies the actual operation taking place. --- context.go | 6 +++--- context_test.go | 4 ++-- crypto.go | 12 ++++++------ crypto_test.go | 22 +++++++++++----------- handler.go | 2 +- handler_test.go | 8 ++++---- token.go | 22 +++++++++++----------- token_test.go | 2 +- 8 files changed, 39 insertions(+), 39 deletions(-) diff --git a/context.go b/context.go index 1d55fce..cce2594 100644 --- a/context.go +++ b/context.go @@ -10,7 +10,7 @@ import ( // and not using gorilla's package just because. type csrfContext struct { - // The encrypted, base64 encoded token + // The masked, base64 encoded token // That's suitable for use in form fields, etc. token string // reason for the failure of CSRF check @@ -60,7 +60,7 @@ func Reason(req *http.Request) error { return ctx.reason } -// Takes a raw token, encrypts it with a per-request key, +// Takes a raw token, masks it with a per-request key, // encodes in base64 and makes it available to the wrapped handler func ctxSetToken(req *http.Request, token []byte) { cmMutex.Lock() @@ -72,7 +72,7 @@ func ctxSetToken(req *http.Request, token []byte) { contextMap[req] = ctx } - ctx.token = b64encode(encryptToken(token)) + ctx.token = b64encode(maskToken(token)) } func ctxSetReason(req *http.Request, reason error) { diff --git a/context_test.go b/context_test.go index f9ffdf5..3df674e 100644 --- a/context_test.go +++ b/context_test.go @@ -43,7 +43,7 @@ func TestSetsTokenCorrectly(t *testing.T) { got := contextMap[req].token - if !bytes.Equal(token, decryptToken(b64decode(got))) { + if !bytes.Equal(token, unmaskToken(b64decode(got))) { t.Errorf("Token set incorrectly: expected %v, got %v", token, got) } } @@ -60,7 +60,7 @@ func TestGetsTokenCorrectly(t *testing.T) { ctxSetToken(req, intended) token = Token(req) - decToken := decryptToken(b64decode(token)) + decToken := unmaskToken(b64decode(token)) if !bytes.Equal(intended, decToken) { t.Errorf("Token has been set to %v, but it's %v", intended, token) } diff --git a/crypto.go b/crypto.go index b2e4dc4..2d18895 100644 --- a/crypto.go +++ b/crypto.go @@ -5,7 +5,7 @@ import ( "io" ) -// Encrypts / decrypts the given data *in place* +// Masks/unmasks the given data *in place* // with the given key // Slices must be of the same length, or oneTimePad will panic func oneTimePad(data, key []byte) { @@ -19,27 +19,27 @@ func oneTimePad(data, key []byte) { } } -func encryptToken(data []byte) []byte { +func maskToken(data []byte) []byte { if len(data) != tokenLength { return nil } // tokenLength*2 == len(enckey + token) result := make([]byte, 2*tokenLength) - // the first half of the result is the encryption key - // the second half is the encrypted token + // the first half of the result is the OTP + // the second half is the masked token itself key := result[:tokenLength] token := result[tokenLength:] copy(token, data) - // generate the encryption key + // generate the random token io.ReadFull(rand.Reader, key) oneTimePad(token, key) return result } -func decryptToken(data []byte) []byte { +func unmaskToken(data []byte) []byte { if len(data) != tokenLength*2 { return nil } diff --git a/crypto_test.go b/crypto_test.go index 65b1e76..fb1afd5 100644 --- a/crypto_test.go +++ b/crypto_test.go @@ -17,7 +17,7 @@ func TestOtpPanicsOnLengthMismatch(t *testing.T) { }() oneTimePad(data, key) } -func TestOtpEncryptsCorrectly(t *testing.T) { +func TestOtpMasksCorrectly(t *testing.T) { data := []byte("Inventors of the shish-kebab") key := []byte("They stop Cthulhu eating ye.") // precalculated @@ -27,12 +27,12 @@ func TestOtpEncryptsCorrectly(t *testing.T) { oneTimePad(data, key) if !bytes.Equal(data, expected) { - t.Errorf("oneTimePad encrypted the data incorrectly: expected %#v, got %#v", + t.Errorf("oneTimePad masked the data incorrectly: expected %#v, got %#v", expected, data) } } -func TestOtpDecryptsCorrectly(t *testing.T) { +func TestOtpUnmasksCorrectly(t *testing.T) { orig := []byte("a very secret message") data := make([]byte, len(orig)) copy(data, orig) @@ -51,10 +51,10 @@ func TestOtpDecryptsCorrectly(t *testing.T) { } } -func TestEncryptsTokenCorrectly(t *testing.T) { +func TestMasksTokenCorrectly(t *testing.T) { // needs to be of tokenLength token := []byte("12345678901234567890123456789012") - fullToken := encryptToken(token) + fullToken := maskToken(token) if len(fullToken) != 2*tokenLength { t.Errorf("len(fullToken) is not %d, but %d", 2*tokenLength, len(fullToken)) @@ -63,21 +63,21 @@ func TestEncryptsTokenCorrectly(t *testing.T) { key := fullToken[:tokenLength] encToken := fullToken[tokenLength:] - // perform decryption + // perform unmasking oneTimePad(encToken, key) if !bytes.Equal(encToken, token) { - t.Errorf("Decrypted token is invalid: expected %v, got %v", token, encToken) + t.Errorf("Unmasked token is invalid: expected %v, got %v", token, encToken) } } -func TestDecryptsTokenCorrectly(t *testing.T) { +func TestUnmasksTokenCorrectly(t *testing.T) { token := []byte("12345678901234567890123456789012") - fullToken := encryptToken(token) + fullToken := maskToken(token) - decToken := decryptToken(fullToken) + decToken := unmaskToken(fullToken) if !bytes.Equal(decToken, token) { - t.Errorf("Decrypted token is invalid: expected %v, got %v", token, decToken) + t.Errorf("Unmasked token is invalid: expected %v, got %v", token, decToken) } } diff --git a/handler.go b/handler.go index 95e0403..cc184f2 100644 --- a/handler.go +++ b/handler.go @@ -180,7 +180,7 @@ func (h *CSRFHandler) RegenerateToken(w http.ResponseWriter, r *http.Request) st } func (h *CSRFHandler) setTokenCookie(w http.ResponseWriter, r *http.Request, token []byte) { - // ctxSetToken() does the encryption for us + // ctxSetToken() does the masking for us ctxSetToken(r, token) cookie := h.baseCookie diff --git a/handler_test.go b/handler_test.go index e0c25c3..6537fa5 100644 --- a/handler_test.go +++ b/handler_test.go @@ -26,7 +26,7 @@ func TestRegenerateToken(t *testing.T) { writer := httptest.NewRecorder() req := dummyGet() - token := b64encode(decryptToken(b64decode(hand.RegenerateToken(writer, req)))) + token := b64encode(unmaskToken(b64decode(hand.RegenerateToken(writer, req)))) header := writer.Header().Get("Set-Cookie") expectedPart := fmt.Sprintf("csrf_token=%s;", token) @@ -57,7 +57,7 @@ func TestsetTokenCookie(t *testing.T) { expected_part, header) } - tokenInContext := decryptToken(b64decode(Token(req))) + tokenInContext := unmaskToken(b64decode(Token(req))) if !bytes.Equal(tokenInContext, token) { t.Errorf("RegenerateToken didn't set the token in the context map!"+ " Expected %v, got %v", token, tokenInContext) @@ -240,7 +240,7 @@ func TestCorrectTokenPasses(t *testing.T) { t.Fatal("Cookie was not found in the response.") } - finalToken := b64encode(encryptToken(b64decode(cookie.Value))) + finalToken := b64encode(maskToken(b64decode(cookie.Value))) vals := [][]string{ {"name", "Jolene"}, @@ -288,7 +288,7 @@ func TestPrefersHeaderOverFormValue(t *testing.T) { t.Fatal("Cookie was not found in the response.") } - finalToken := b64encode(encryptToken(b64decode(cookie.Value))) + finalToken := b64encode(maskToken(b64decode(cookie.Value))) vals := [][]string{ {"name", "Jolene"}, diff --git a/token.go b/token.go index 13907b0..f0f478b 100644 --- a/token.go +++ b/token.go @@ -15,13 +15,13 @@ const ( /* There are two types of tokens. -* The unencrypted "real" token consists of 32 random bytes. +* The unmasked "real" token consists of 32 random bytes. It is stored in a cookie (base64-encoded) and it's the "reference" value that sent tokens get compared to. -* The encrypted "sent" token consists of 64 bytes: - 32 byte key used for one-time pad encryption and - 32 byte "real" token encrypted with the said key. +* The masked "sent" token consists of 64 bytes: + 32 byte key used for one-time pad masking and + 32 byte "real" token masked with the said key. It is used as a value (base64-encoded as well) in forms and/or headers. @@ -59,24 +59,24 @@ func b64decode(data string) []byte { // Verifies the sent token equals the real one // and returns a bool value indicating if tokens are equal. -// Supports encrypted tokens. +// Supports masked tokens. func verifyToken(realToken, sentToken []byte) bool { realN := len(realToken) sentN := len(sentToken) - // sentN == tokenLength means the token is unencrypted - // sentN == 2*tokenLength means the token is encrypted + // sentN == tokenLength means the token is unmasked + // sentN == 2*tokenLength means the token is masked. if realN == tokenLength && sentN == 2*tokenLength { - return verifyEncrypted(realToken, sentToken) + return verifyMasked(realToken, sentToken) } else { return false } } -// Verifies the encrypted token -func verifyEncrypted(realToken, sentToken []byte) bool { - sentPlain := decryptToken(sentToken) +// Verifies the masked token +func verifyMasked(realToken, sentToken []byte) bool { + sentPlain := unmaskToken(sentToken) return subtle.ConstantTimeCompare(realToken, sentPlain) == 1 } diff --git a/token_test.go b/token_test.go index dc88324..39652e4 100644 --- a/token_test.go +++ b/token_test.go @@ -54,7 +54,7 @@ func TestVerifyTokenChecksLengthCorrectly(t *testing.T) { } } -func TestVerifiesEncryptedTokenCorrectly(t *testing.T) { +func TestVerifiesMaskedTokenCorrectly(t *testing.T) { realToken := []byte("qwertyuiopasdfghjklzxcvbnm123456") sentToken := []byte("qwertyuiopasdfghjklzxcvbnm123456" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +