2019-05-24 17:06:48 +01:00
package encryption
2015-06-23 07:23:39 -04:00
import (
2020-05-21 11:29:45 -07:00
"crypto/rand"
2016-06-20 07:17:39 -04:00
"encoding/base64"
2020-05-11 17:09:00 -07:00
"fmt"
2020-05-21 11:29:45 -07:00
"io"
2015-06-23 07:23:39 -04:00
"testing"
2017-10-23 12:23:46 -04:00
"github.com/stretchr/testify/assert"
2015-06-23 07:23:39 -04:00
)
func TestEncodeAndDecodeAccessToken ( t * testing . T ) {
const secret = "0123456789abcdefghijklmnopqrstuv"
const token = "my access token"
2020-07-13 12:56:05 -07:00
cfb , err := NewCFBCipher ( [ ] byte ( secret ) )
assert . NoError ( t , err )
c := NewBase64Cipher ( cfb )
2016-06-20 07:17:39 -04:00
2020-05-09 17:01:51 -07:00
encoded , err := c . Encrypt ( [ ] byte ( token ) )
2016-06-20 07:17:39 -04:00
assert . Equal ( t , nil , err )
decoded , err := c . Decrypt ( encoded )
assert . Equal ( t , nil , err )
2020-05-09 17:01:51 -07:00
assert . NotEqual ( t , [ ] byte ( token ) , encoded )
assert . Equal ( t , [ ] byte ( token ) , decoded )
2016-06-20 07:17:39 -04:00
}
func TestEncodeAndDecodeAccessTokenB64 ( t * testing . T ) {
2018-11-29 14:26:41 +00:00
const secretBase64 = "A3Xbr6fu6Al0HkgrP1ztjb-mYiwmxgNPP-XbNsz1WBk="
2016-06-20 07:17:39 -04:00
const token = "my access token"
2018-11-29 14:26:41 +00:00
secret , err := base64 . URLEncoding . DecodeString ( secretBase64 )
assert . Equal ( t , nil , err )
2020-07-13 12:56:05 -07:00
cfb , err := NewCFBCipher ( [ ] byte ( secret ) )
assert . NoError ( t , err )
c := NewBase64Cipher ( cfb )
2015-06-23 07:23:39 -04:00
2020-05-09 17:01:51 -07:00
encoded , err := c . Encrypt ( [ ] byte ( token ) )
2015-06-23 07:23:39 -04:00
assert . Equal ( t , nil , err )
decoded , err := c . Decrypt ( encoded )
assert . Equal ( t , nil , err )
2020-05-09 17:01:51 -07:00
assert . NotEqual ( t , [ ] byte ( token ) , encoded )
assert . Equal ( t , [ ] byte ( token ) , decoded )
}
2020-05-09 17:34:32 -07:00
func TestEncryptAndDecrypt ( t * testing . T ) {
2020-05-10 09:44:04 -07:00
// Test our 2 cipher types
2020-05-10 13:24:29 -07:00
cipherInits := map [ string ] func ( [ ] byte ) ( Cipher , error ) {
2020-05-10 10:15:51 -07:00
"CFB" : NewCFBCipher ,
"GCM" : NewGCMCipher ,
}
2020-05-10 13:24:29 -07:00
for name , initCipher := range cipherInits {
t . Run ( name , func ( t * testing . T ) {
// Test all 3 valid AES sizes
for _ , secretSize := range [ ] int { 16 , 24 , 32 } {
2020-05-11 17:09:00 -07:00
t . Run ( fmt . Sprintf ( "%d" , secretSize ) , func ( t * testing . T ) {
2020-05-10 13:24:29 -07:00
secret := make ( [ ] byte , secretSize )
_ , err := io . ReadFull ( rand . Reader , secret )
2020-05-10 10:15:51 -07:00
assert . Equal ( t , nil , err )
2020-05-10 13:24:29 -07:00
// Test Standard & Base64 wrapped
cstd , err := initCipher ( secret )
2020-05-10 10:15:51 -07:00
assert . Equal ( t , nil , err )
2020-07-13 12:56:05 -07:00
cb64 := NewBase64Cipher ( cstd )
2020-05-10 10:15:51 -07:00
2020-05-10 13:24:29 -07:00
ciphers := map [ string ] Cipher {
"Standard" : cstd ,
"Base64" : cb64 ,
}
for cName , c := range ciphers {
t . Run ( cName , func ( t * testing . T ) {
// Test various sizes sessions might be
for _ , dataSize := range [ ] int { 10 , 100 , 1000 , 5000 , 10000 } {
2020-05-11 17:09:00 -07:00
t . Run ( fmt . Sprintf ( "%d" , dataSize ) , func ( t * testing . T ) {
runEncryptAndDecrypt ( t , c , dataSize )
2020-05-10 13:24:29 -07:00
} )
}
} )
}
} )
}
} )
2020-05-10 09:44:04 -07:00
}
}
2020-05-11 17:09:00 -07:00
func runEncryptAndDecrypt ( t * testing . T , c Cipher , dataSize int ) {
data := make ( [ ] byte , dataSize )
_ , err := io . ReadFull ( rand . Reader , data )
assert . Equal ( t , nil , err )
// Ensure our Encrypt function doesn't encrypt in place
immutableData := make ( [ ] byte , len ( data ) )
copy ( immutableData , data )
encrypted , err := c . Encrypt ( data )
assert . Equal ( t , nil , err )
assert . NotEqual ( t , encrypted , data )
// Encrypt didn't operate in-place on []byte
assert . Equal ( t , data , immutableData )
// Ensure our Decrypt function doesn't decrypt in place
immutableEnc := make ( [ ] byte , len ( encrypted ) )
copy ( immutableEnc , encrypted )
decrypted , err := c . Decrypt ( encrypted )
assert . Equal ( t , nil , err )
// Original data back
assert . Equal ( t , data , decrypted )
// Decrypt didn't operate in-place on []byte
assert . Equal ( t , encrypted , immutableEnc )
// Encrypt/Decrypt actually did something
assert . NotEqual ( t , encrypted , decrypted )
}
2020-05-10 09:44:04 -07:00
func TestDecryptCFBWrongSecret ( t * testing . T ) {
2020-05-09 17:34:32 -07:00
secret1 := [ ] byte ( "0123456789abcdefghijklmnopqrstuv" )
secret2 := [ ] byte ( "9876543210abcdefghijklmnopqrstuv" )
2020-05-10 09:44:04 -07:00
c1 , err := NewCFBCipher ( secret1 )
assert . Equal ( t , nil , err )
2020-05-09 17:34:32 -07:00
2020-05-10 09:44:04 -07:00
c2 , err := NewCFBCipher ( secret2 )
assert . Equal ( t , nil , err )
2020-05-09 17:34:32 -07:00
2020-05-10 09:44:04 -07:00
data := [ ] byte ( "f3928pufm982374dj02y485dsl34890u2t9nd4028s94dm58y2394087dhmsyt29h8df" )
2020-05-09 17:01:51 -07:00
2020-05-10 09:44:04 -07:00
ciphertext , err := c1 . Encrypt ( data )
assert . Equal ( t , nil , err )
2020-05-09 17:34:32 -07:00
2020-05-10 09:44:04 -07:00
wrongData , err := c2 . Decrypt ( ciphertext )
assert . Equal ( t , nil , err )
assert . NotEqual ( t , data , wrongData )
2020-05-09 17:34:32 -07:00
}
func TestDecryptGCMWrongSecret ( t * testing . T ) {
2020-05-09 17:01:51 -07:00
secret1 := [ ] byte ( "0123456789abcdefghijklmnopqrstuv" )
secret2 := [ ] byte ( "9876543210abcdefghijklmnopqrstuv" )
2020-05-09 17:34:32 -07:00
c1 , err := NewGCMCipher ( secret1 )
2020-05-09 17:01:51 -07:00
assert . Equal ( t , nil , err )
2020-05-09 17:34:32 -07:00
c2 , err := NewGCMCipher ( secret2 )
2020-05-09 17:01:51 -07:00
assert . Equal ( t , nil , err )
data := [ ] byte ( "f3928pufm982374dj02y485dsl34890u2t9nd4028s94dm58y2394087dhmsyt29h8df" )
ciphertext , err := c1 . Encrypt ( data )
assert . Equal ( t , nil , err )
2020-05-09 17:34:32 -07:00
// GCM is authenticated - this should lead to message authentication failed
_ , err = c2 . Decrypt ( ciphertext )
assert . Error ( t , err )
2020-05-09 17:01:51 -07:00
}
2020-05-10 13:24:29 -07:00
// Encrypt with GCM, Decrypt with CFB: Results in Garbage data
func TestGCMtoCFBErrors ( t * testing . T ) {
2020-05-09 17:01:51 -07:00
// Test all 3 valid AES sizes
for _ , secretSize := range [ ] int { 16 , 24 , 32 } {
2020-05-11 17:09:00 -07:00
t . Run ( fmt . Sprintf ( "%d" , secretSize ) , func ( t * testing . T ) {
2020-05-10 10:15:51 -07:00
secret := make ( [ ] byte , secretSize )
_ , err := io . ReadFull ( rand . Reader , secret )
2020-05-09 17:01:51 -07:00
assert . Equal ( t , nil , err )
2020-05-10 10:15:51 -07:00
gcm , err := NewGCMCipher ( secret )
2020-05-09 17:01:51 -07:00
assert . Equal ( t , nil , err )
2020-05-10 10:15:51 -07:00
cfb , err := NewCFBCipher ( secret )
2020-05-09 17:01:51 -07:00
assert . Equal ( t , nil , err )
2020-05-10 10:15:51 -07:00
// Test various sizes sessions might be
for _ , dataSize := range [ ] int { 10 , 100 , 1000 , 5000 , 10000 } {
2020-05-11 17:09:00 -07:00
t . Run ( fmt . Sprintf ( "%d" , dataSize ) , func ( t * testing . T ) {
2020-05-10 13:24:29 -07:00
data := make ( [ ] byte , dataSize )
_ , err := io . ReadFull ( rand . Reader , data )
assert . Equal ( t , nil , err )
encrypted , err := gcm . Encrypt ( data )
assert . Equal ( t , nil , err )
assert . NotEqual ( t , encrypted , data )
decrypted , err := cfb . Decrypt ( encrypted )
assert . Equal ( t , nil , err )
// Data is mangled
assert . NotEqual ( t , data , decrypted )
assert . NotEqual ( t , encrypted , decrypted )
} )
2020-05-10 10:15:51 -07:00
}
} )
2020-05-09 17:01:51 -07:00
}
2020-05-10 13:24:29 -07:00
}
2020-05-09 17:01:51 -07:00
2020-05-10 13:24:29 -07:00
// Encrypt with CFB, Decrypt with GCM: Results in errors
func TestCFBtoGCMErrors ( t * testing . T ) {
2020-05-09 17:34:32 -07:00
// Test all 3 valid AES sizes
for _ , secretSize := range [ ] int { 16 , 24 , 32 } {
2020-05-11 17:09:00 -07:00
t . Run ( fmt . Sprintf ( "%d" , secretSize ) , func ( t * testing . T ) {
2020-05-10 10:15:51 -07:00
secret := make ( [ ] byte , secretSize )
_ , err := io . ReadFull ( rand . Reader , secret )
assert . Equal ( t , nil , err )
2020-05-09 17:01:51 -07:00
2020-05-10 10:15:51 -07:00
gcm , err := NewGCMCipher ( secret )
2020-05-09 17:34:32 -07:00
assert . Equal ( t , nil , err )
2020-05-09 17:01:51 -07:00
2020-05-10 10:15:51 -07:00
cfb , err := NewCFBCipher ( secret )
2020-05-09 17:34:32 -07:00
assert . Equal ( t , nil , err )
2020-05-09 17:01:51 -07:00
2020-05-10 10:15:51 -07:00
// Test various sizes sessions might be
for _ , dataSize := range [ ] int { 10 , 100 , 1000 , 5000 , 10000 } {
2020-05-11 17:09:00 -07:00
t . Run ( fmt . Sprintf ( "%d" , dataSize ) , func ( t * testing . T ) {
2020-05-10 13:24:29 -07:00
data := make ( [ ] byte , dataSize )
_ , err := io . ReadFull ( rand . Reader , data )
assert . Equal ( t , nil , err )
2020-05-10 10:15:51 -07:00
2020-05-10 13:24:29 -07:00
encrypted , err := cfb . Encrypt ( data )
assert . Equal ( t , nil , err )
assert . NotEqual ( t , encrypted , data )
2020-05-10 10:15:51 -07:00
2020-05-10 13:24:29 -07:00
// GCM is authenticated - this should lead to message authentication failed
_ , err = gcm . Decrypt ( encrypted )
assert . Error ( t , err )
} )
2020-05-10 10:15:51 -07:00
}
} )
2020-05-09 17:34:32 -07:00
}
2015-06-23 07:23:39 -04:00
}