1/*- 2 * Copyright 2014 Square Inc. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package jose 18 19import ( 20 "bytes" 21 "crypto/cipher" 22 "crypto/rand" 23 "crypto/sha256" 24 "io" 25 "testing" 26 27 "golang.org/x/crypto/pbkdf2" 28) 29 30func TestInvalidSymmetricAlgorithms(t *testing.T) { 31 _, err := newSymmetricRecipient("XYZ", []byte{}) 32 if err != ErrUnsupportedAlgorithm { 33 t.Error("should not accept invalid algorithm") 34 } 35 36 enc := &symmetricKeyCipher{} 37 _, err = enc.encryptKey([]byte{}, "XYZ") 38 if err != ErrUnsupportedAlgorithm { 39 t.Error("should not accept invalid algorithm") 40 } 41} 42 43func TestAeadErrors(t *testing.T) { 44 aead := &aeadContentCipher{ 45 keyBytes: 16, 46 authtagBytes: 16, 47 getAead: func(key []byte) (cipher.AEAD, error) { 48 return nil, ErrCryptoFailure 49 }, 50 } 51 52 parts, err := aead.encrypt([]byte{}, []byte{}, []byte{}) 53 if err != ErrCryptoFailure { 54 t.Error("should handle aead failure") 55 } 56 57 _, err = aead.decrypt([]byte{}, []byte{}, parts) 58 if err != ErrCryptoFailure { 59 t.Error("should handle aead failure") 60 } 61} 62 63func TestInvalidKey(t *testing.T) { 64 gcm := newAESGCM(16).(*aeadContentCipher) 65 _, err := gcm.getAead([]byte{}) 66 if err == nil { 67 t.Error("should not accept invalid key") 68 } 69} 70 71func TestStaticKeyGen(t *testing.T) { 72 key := make([]byte, 32) 73 io.ReadFull(rand.Reader, key) 74 75 gen := &staticKeyGenerator{key: key} 76 if gen.keySize() != len(key) { 77 t.Error("static key generator reports incorrect size") 78 } 79 80 generated, _, err := gen.genKey() 81 if err != nil { 82 t.Error("static key generator should always succeed", err) 83 } 84 if !bytes.Equal(generated, key) { 85 t.Error("static key generator returns different data") 86 } 87} 88 89func TestAeadInvalidInput(t *testing.T) { 90 sample := []byte("1234567890123456") 91 tt := []aeadParts{ 92 {}, 93 {iv: sample, tag: sample}, 94 } 95 for _, tc := range tt { 96 aead := newAESGCM(16).(*aeadContentCipher) 97 _, err := aead.decrypt(sample, []byte{}, &tc) 98 if err != ErrCryptoFailure { 99 t.Error("should handle aead failure") 100 } 101 } 102} 103 104func TestVectorsAESGCM(t *testing.T) { 105 // Source: http://tools.ietf.org/html/draft-ietf-jose-json-web-encryption-29#appendix-A.1 106 plaintext := []byte{ 107 84, 104, 101, 32, 116, 114, 117, 101, 32, 115, 105, 103, 110, 32, 108 111, 102, 32, 105, 110, 116, 101, 108, 108, 105, 103, 101, 110, 99, 109 101, 32, 105, 115, 32, 110, 111, 116, 32, 107, 110, 111, 119, 108, 110 101, 100, 103, 101, 32, 98, 117, 116, 32, 105, 109, 97, 103, 105, 111 110, 97, 116, 105, 111, 110, 46} 112 113 aad := []byte{ 114 101, 121, 74, 104, 98, 71, 99, 105, 79, 105, 74, 83, 85, 48, 69, 115 116, 84, 48, 70, 70, 85, 67, 73, 115, 73, 109, 86, 117, 89, 121, 73, 116 54, 73, 107, 69, 121, 78, 84, 90, 72, 81, 48, 48, 105, 102, 81} 117 118 expectedCiphertext := []byte{ 119 229, 236, 166, 241, 53, 191, 115, 196, 174, 43, 73, 109, 39, 122, 120 233, 96, 140, 206, 120, 52, 51, 237, 48, 11, 190, 219, 186, 80, 111, 121 104, 50, 142, 47, 167, 59, 61, 181, 127, 196, 21, 40, 82, 242, 32, 122 123, 143, 168, 226, 73, 216, 176, 144, 138, 247, 106, 60, 16, 205, 123 160, 109, 64, 63, 192} 124 125 expectedAuthtag := []byte{ 126 92, 80, 104, 49, 133, 25, 161, 215, 173, 101, 219, 211, 136, 91, 210, 145} 127 128 // Mock random reader 129 RandReader = bytes.NewReader([]byte{ 130 177, 161, 244, 128, 84, 143, 225, 115, 63, 180, 3, 255, 107, 154, 131 212, 246, 138, 7, 110, 91, 112, 46, 34, 105, 47, 130, 203, 46, 122, 132 234, 64, 252, 227, 197, 117, 252, 2, 219, 233, 68, 180, 225, 77, 219}) 133 defer resetRandReader() 134 135 enc := newAESGCM(32) 136 key, _, _ := randomKeyGenerator{size: 32}.genKey() 137 out, err := enc.encrypt(key, aad, plaintext) 138 if err != nil { 139 t.Error("Unable to encrypt:", err) 140 return 141 } 142 143 if bytes.Compare(out.ciphertext, expectedCiphertext) != 0 { 144 t.Error("Ciphertext did not match") 145 } 146 if bytes.Compare(out.tag, expectedAuthtag) != 0 { 147 t.Error("Auth tag did not match") 148 } 149} 150 151func TestVectorPBES2_HS256A_128KW(t *testing.T) { 152 cipher := &symmetricKeyCipher{ 153 key: []byte("Thus from my lips, by yours, my sin is purged."), 154 p2c: 4096, 155 p2s: []byte{ 156 217, 96, 147, 112, 150, 117, 70, 157 247, 127, 8, 155, 137, 174, 42, 80, 215, 158 }, 159 } 160 161 cek := []byte{ 162 111, 27, 25, 52, 66, 29, 20, 78, 92, 176, 56, 240, 65, 208, 82, 112, 163 161, 131, 36, 55, 202, 236, 185, 172, 129, 23, 153, 194, 195, 48, 164 253, 182, 165 } 166 167 // PBES2-HS256+A128KW || 0x00 || p2s 168 salt := []byte{ 169 80, 66, 69, 83, 50, 45, 72, 83, 50, 53, 54, 43, 65, 49, 50, 56, 75, 170 87, 0, 217, 96, 147, 112, 150, 117, 70, 247, 127, 8, 155, 137, 174, 171 42, 80, 215, 172 } 173 174 expectedDerivedKey := []byte{ 175 110, 171, 169, 92, 129, 92, 109, 117, 233, 242, 116, 233, 170, 14, 176 24, 75} 177 178 expectedEncryptedKey := []byte{ 179 78, 186, 151, 59, 11, 141, 81, 240, 213, 245, 83, 211, 53, 188, 134, 180 188, 66, 125, 36, 200, 222, 124, 5, 103, 249, 52, 117, 184, 140, 81, 181 246, 158, 161, 177, 20, 33, 245, 57, 59, 4} 182 183 derivedKey := pbkdf2.Key(cipher.key, salt, cipher.p2c, 16, sha256.New) 184 if bytes.Compare(derivedKey, expectedDerivedKey) != 0 { 185 t.Error("Derived key did not match") 186 } 187 188 encryptedKey, err := cipher.encryptKey(cek, PBES2_HS256_A128KW) 189 if err != nil { 190 t.Fatal("Unable to encrypt:", err) 191 } 192 193 if bytes.Compare(encryptedKey.encryptedKey, expectedEncryptedKey) != 0 { 194 t.Error("Encrypted key did not match") 195 } 196} 197