OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/logging.h" | 5 #include "base/logging.h" |
6 #include "base/stl_util.h" | 6 #include "base/stl_util.h" |
7 #include "content/child/webcrypto/algorithm_dispatch.h" | 7 #include "content/child/webcrypto/algorithm_dispatch.h" |
8 #include "content/child/webcrypto/crypto_data.h" | 8 #include "content/child/webcrypto/crypto_data.h" |
9 #include "content/child/webcrypto/status.h" | 9 #include "content/child/webcrypto/status.h" |
10 #include "content/child/webcrypto/test/test_helpers.h" | 10 #include "content/child/webcrypto/test/test_helpers.h" |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
111 &signature_match)); | 111 &signature_match)); |
112 EXPECT_FALSE(signature_match); | 112 EXPECT_FALSE(signature_match); |
113 } | 113 } |
114 } | 114 } |
115 | 115 |
116 TEST(WebCryptoHmacTest, GenerateKeyIsRandom) { | 116 TEST(WebCryptoHmacTest, GenerateKeyIsRandom) { |
117 // Generate a small sample of HMAC keys. | 117 // Generate a small sample of HMAC keys. |
118 std::vector<std::vector<uint8_t> > keys; | 118 std::vector<std::vector<uint8_t> > keys; |
119 for (int i = 0; i < 16; ++i) { | 119 for (int i = 0; i < 16; ++i) { |
120 std::vector<uint8_t> key_bytes; | 120 std::vector<uint8_t> key_bytes; |
121 blink::WebCryptoKey key = blink::WebCryptoKey::createNull(); | 121 blink::WebCryptoKey key; |
122 blink::WebCryptoAlgorithm algorithm = | 122 blink::WebCryptoAlgorithm algorithm = |
123 CreateHmacKeyGenAlgorithm(blink::WebCryptoAlgorithmIdSha1, 512); | 123 CreateHmacKeyGenAlgorithm(blink::WebCryptoAlgorithmIdSha1, 512); |
124 ASSERT_EQ(Status::Success(), GenerateSecretKey(algorithm, true, 0, &key)); | 124 ASSERT_EQ(Status::Success(), GenerateSecretKey(algorithm, true, 0, &key)); |
125 EXPECT_FALSE(key.isNull()); | 125 EXPECT_FALSE(key.isNull()); |
126 EXPECT_TRUE(key.handle()); | 126 EXPECT_TRUE(key.handle()); |
127 EXPECT_EQ(blink::WebCryptoKeyTypeSecret, key.type()); | 127 EXPECT_EQ(blink::WebCryptoKeyTypeSecret, key.type()); |
128 EXPECT_EQ(blink::WebCryptoAlgorithmIdHmac, key.algorithm().id()); | 128 EXPECT_EQ(blink::WebCryptoAlgorithmIdHmac, key.algorithm().id()); |
129 EXPECT_EQ(blink::WebCryptoAlgorithmIdSha1, | 129 EXPECT_EQ(blink::WebCryptoAlgorithmIdSha1, |
130 key.algorithm().hmacParams()->hash().id()); | 130 key.algorithm().hmacParams()->hash().id()); |
131 EXPECT_EQ(512u, key.algorithm().hmacParams()->lengthBits()); | 131 EXPECT_EQ(512u, key.algorithm().hmacParams()->lengthBits()); |
132 | 132 |
133 std::vector<uint8_t> raw_key; | 133 std::vector<uint8_t> raw_key; |
134 ASSERT_EQ(Status::Success(), | 134 ASSERT_EQ(Status::Success(), |
135 ExportKey(blink::WebCryptoKeyFormatRaw, key, &raw_key)); | 135 ExportKey(blink::WebCryptoKeyFormatRaw, key, &raw_key)); |
136 EXPECT_EQ(64U, raw_key.size()); | 136 EXPECT_EQ(64U, raw_key.size()); |
137 keys.push_back(raw_key); | 137 keys.push_back(raw_key); |
138 } | 138 } |
139 // Ensure all entries in the key sample set are unique. This is a simplistic | 139 // Ensure all entries in the key sample set are unique. This is a simplistic |
140 // estimate of whether the generated keys appear random. | 140 // estimate of whether the generated keys appear random. |
141 EXPECT_FALSE(CopiesExist(keys)); | 141 EXPECT_FALSE(CopiesExist(keys)); |
142 } | 142 } |
143 | 143 |
144 // If the key length is not provided, then the block size is used. | 144 // If the key length is not provided, then the block size is used. |
145 TEST(WebCryptoHmacTest, GenerateKeyNoLengthSha1) { | 145 TEST(WebCryptoHmacTest, GenerateKeyNoLengthSha1) { |
146 blink::WebCryptoKey key = blink::WebCryptoKey::createNull(); | 146 blink::WebCryptoKey key; |
147 blink::WebCryptoAlgorithm algorithm = | 147 blink::WebCryptoAlgorithm algorithm = |
148 CreateHmacKeyGenAlgorithm(blink::WebCryptoAlgorithmIdSha1, 0); | 148 CreateHmacKeyGenAlgorithm(blink::WebCryptoAlgorithmIdSha1, 0); |
149 ASSERT_EQ(Status::Success(), GenerateSecretKey(algorithm, true, 0, &key)); | 149 ASSERT_EQ(Status::Success(), GenerateSecretKey(algorithm, true, 0, &key)); |
150 EXPECT_TRUE(key.handle()); | 150 EXPECT_TRUE(key.handle()); |
151 EXPECT_EQ(blink::WebCryptoKeyTypeSecret, key.type()); | 151 EXPECT_EQ(blink::WebCryptoKeyTypeSecret, key.type()); |
152 EXPECT_EQ(blink::WebCryptoAlgorithmIdHmac, key.algorithm().id()); | 152 EXPECT_EQ(blink::WebCryptoAlgorithmIdHmac, key.algorithm().id()); |
153 EXPECT_EQ(blink::WebCryptoAlgorithmIdSha1, | 153 EXPECT_EQ(blink::WebCryptoAlgorithmIdSha1, |
154 key.algorithm().hmacParams()->hash().id()); | 154 key.algorithm().hmacParams()->hash().id()); |
155 EXPECT_EQ(512u, key.algorithm().hmacParams()->lengthBits()); | 155 EXPECT_EQ(512u, key.algorithm().hmacParams()->lengthBits()); |
156 std::vector<uint8_t> raw_key; | 156 std::vector<uint8_t> raw_key; |
157 ASSERT_EQ(Status::Success(), | 157 ASSERT_EQ(Status::Success(), |
158 ExportKey(blink::WebCryptoKeyFormatRaw, key, &raw_key)); | 158 ExportKey(blink::WebCryptoKeyFormatRaw, key, &raw_key)); |
159 EXPECT_EQ(64U, raw_key.size()); | 159 EXPECT_EQ(64U, raw_key.size()); |
160 } | 160 } |
161 | 161 |
162 // If the key length is not provided, then the block size is used. | 162 // If the key length is not provided, then the block size is used. |
163 TEST(WebCryptoHmacTest, GenerateKeyNoLengthSha512) { | 163 TEST(WebCryptoHmacTest, GenerateKeyNoLengthSha512) { |
164 blink::WebCryptoKey key = blink::WebCryptoKey::createNull(); | 164 blink::WebCryptoKey key; |
165 blink::WebCryptoAlgorithm algorithm = | 165 blink::WebCryptoAlgorithm algorithm = |
166 CreateHmacKeyGenAlgorithm(blink::WebCryptoAlgorithmIdSha512, 0); | 166 CreateHmacKeyGenAlgorithm(blink::WebCryptoAlgorithmIdSha512, 0); |
167 ASSERT_EQ(Status::Success(), GenerateSecretKey(algorithm, true, 0, &key)); | 167 ASSERT_EQ(Status::Success(), GenerateSecretKey(algorithm, true, 0, &key)); |
168 EXPECT_EQ(blink::WebCryptoAlgorithmIdHmac, key.algorithm().id()); | 168 EXPECT_EQ(blink::WebCryptoAlgorithmIdHmac, key.algorithm().id()); |
169 EXPECT_EQ(blink::WebCryptoAlgorithmIdSha512, | 169 EXPECT_EQ(blink::WebCryptoAlgorithmIdSha512, |
170 key.algorithm().hmacParams()->hash().id()); | 170 key.algorithm().hmacParams()->hash().id()); |
171 EXPECT_EQ(1024u, key.algorithm().hmacParams()->lengthBits()); | 171 EXPECT_EQ(1024u, key.algorithm().hmacParams()->lengthBits()); |
172 std::vector<uint8_t> raw_key; | 172 std::vector<uint8_t> raw_key; |
173 ASSERT_EQ(Status::Success(), | 173 ASSERT_EQ(Status::Success(), |
174 ExportKey(blink::WebCryptoKeyFormatRaw, key, &raw_key)); | 174 ExportKey(blink::WebCryptoKeyFormatRaw, key, &raw_key)); |
175 EXPECT_EQ(128U, raw_key.size()); | 175 EXPECT_EQ(128U, raw_key.size()); |
176 } | 176 } |
177 | 177 |
178 TEST(WebCryptoHmacTest, ImportKeyJwkKeyOpsSignVerify) { | 178 TEST(WebCryptoHmacTest, ImportKeyJwkKeyOpsSignVerify) { |
179 blink::WebCryptoKey key = blink::WebCryptoKey::createNull(); | 179 blink::WebCryptoKey key; |
180 base::DictionaryValue dict; | 180 base::DictionaryValue dict; |
181 dict.SetString("kty", "oct"); | 181 dict.SetString("kty", "oct"); |
182 dict.SetString("k", "GADWrMRHwQfoNaXU5fZvTg=="); | 182 dict.SetString("k", "GADWrMRHwQfoNaXU5fZvTg=="); |
183 base::ListValue* key_ops = new base::ListValue; | 183 base::ListValue* key_ops = new base::ListValue; |
184 dict.Set("key_ops", key_ops); // Takes ownership. | 184 dict.Set("key_ops", key_ops); // Takes ownership. |
185 | 185 |
186 key_ops->AppendString("sign"); | 186 key_ops->AppendString("sign"); |
187 | 187 |
188 EXPECT_EQ(Status::Success(), | 188 EXPECT_EQ(Status::Success(), |
189 ImportKeyJwkFromDict( | 189 ImportKeyJwkFromDict( |
(...skipping 13 matching lines...) Expand all Loading... |
203 CreateHmacImportAlgorithm(blink::WebCryptoAlgorithmIdSha256), | 203 CreateHmacImportAlgorithm(blink::WebCryptoAlgorithmIdSha256), |
204 false, | 204 false, |
205 blink::WebCryptoKeyUsageVerify, | 205 blink::WebCryptoKeyUsageVerify, |
206 &key)); | 206 &key)); |
207 | 207 |
208 EXPECT_EQ(blink::WebCryptoKeyUsageVerify, key.usages()); | 208 EXPECT_EQ(blink::WebCryptoKeyUsageVerify, key.usages()); |
209 } | 209 } |
210 | 210 |
211 // Test 'use' inconsistent with 'key_ops'. | 211 // Test 'use' inconsistent with 'key_ops'. |
212 TEST(WebCryptoHmacTest, ImportKeyJwkUseInconsisteWithKeyOps) { | 212 TEST(WebCryptoHmacTest, ImportKeyJwkUseInconsisteWithKeyOps) { |
213 blink::WebCryptoKey key = blink::WebCryptoKey::createNull(); | 213 blink::WebCryptoKey key; |
214 base::DictionaryValue dict; | 214 base::DictionaryValue dict; |
215 dict.SetString("kty", "oct"); | 215 dict.SetString("kty", "oct"); |
216 dict.SetString("k", "GADWrMRHwQfoNaXU5fZvTg=="); | 216 dict.SetString("k", "GADWrMRHwQfoNaXU5fZvTg=="); |
217 base::ListValue* key_ops = new base::ListValue; | 217 base::ListValue* key_ops = new base::ListValue; |
218 dict.Set("key_ops", key_ops); // Takes ownership. | 218 dict.Set("key_ops", key_ops); // Takes ownership. |
219 | 219 |
220 dict.SetString("alg", "HS256"); | 220 dict.SetString("alg", "HS256"); |
221 dict.SetString("use", "sig"); | 221 dict.SetString("use", "sig"); |
222 key_ops->AppendString("sign"); | 222 key_ops->AppendString("sign"); |
223 key_ops->AppendString("verify"); | 223 key_ops->AppendString("verify"); |
224 key_ops->AppendString("encrypt"); | 224 key_ops->AppendString("encrypt"); |
225 EXPECT_EQ(Status::ErrorJwkUseAndKeyopsInconsistent(), | 225 EXPECT_EQ(Status::ErrorJwkUseAndKeyopsInconsistent(), |
226 ImportKeyJwkFromDict( | 226 ImportKeyJwkFromDict( |
227 dict, | 227 dict, |
228 CreateHmacImportAlgorithm(blink::WebCryptoAlgorithmIdSha256), | 228 CreateHmacImportAlgorithm(blink::WebCryptoAlgorithmIdSha256), |
229 false, | 229 false, |
230 blink::WebCryptoKeyUsageSign | blink::WebCryptoKeyUsageVerify, | 230 blink::WebCryptoKeyUsageSign | blink::WebCryptoKeyUsageVerify, |
231 &key)); | 231 &key)); |
232 } | 232 } |
233 | 233 |
234 // Test JWK composite 'sig' use | 234 // Test JWK composite 'sig' use |
235 TEST(WebCryptoHmacTest, ImportKeyJwkUseSig) { | 235 TEST(WebCryptoHmacTest, ImportKeyJwkUseSig) { |
236 blink::WebCryptoKey key = blink::WebCryptoKey::createNull(); | 236 blink::WebCryptoKey key; |
237 base::DictionaryValue dict; | 237 base::DictionaryValue dict; |
238 dict.SetString("kty", "oct"); | 238 dict.SetString("kty", "oct"); |
239 dict.SetString("k", "GADWrMRHwQfoNaXU5fZvTg=="); | 239 dict.SetString("k", "GADWrMRHwQfoNaXU5fZvTg=="); |
240 | 240 |
241 dict.SetString("use", "sig"); | 241 dict.SetString("use", "sig"); |
242 EXPECT_EQ(Status::Success(), | 242 EXPECT_EQ(Status::Success(), |
243 ImportKeyJwkFromDict( | 243 ImportKeyJwkFromDict( |
244 dict, | 244 dict, |
245 CreateHmacImportAlgorithm(blink::WebCryptoAlgorithmIdSha256), | 245 CreateHmacImportAlgorithm(blink::WebCryptoAlgorithmIdSha256), |
246 false, | 246 false, |
247 blink::WebCryptoKeyUsageSign | blink::WebCryptoKeyUsageVerify, | 247 blink::WebCryptoKeyUsageSign | blink::WebCryptoKeyUsageVerify, |
248 &key)); | 248 &key)); |
249 | 249 |
250 EXPECT_EQ(blink::WebCryptoKeyUsageSign | blink::WebCryptoKeyUsageVerify, | 250 EXPECT_EQ(blink::WebCryptoKeyUsageSign | blink::WebCryptoKeyUsageVerify, |
251 key.usages()); | 251 key.usages()); |
252 } | 252 } |
253 | 253 |
254 TEST(WebCryptoHmacTest, ImportJwkInputConsistency) { | 254 TEST(WebCryptoHmacTest, ImportJwkInputConsistency) { |
255 // The Web Crypto spec says that if a JWK value is present, but is | 255 // The Web Crypto spec says that if a JWK value is present, but is |
256 // inconsistent with the input value, the operation must fail. | 256 // inconsistent with the input value, the operation must fail. |
257 | 257 |
258 // Consistency rules when JWK value is not present: Inputs should be used. | 258 // Consistency rules when JWK value is not present: Inputs should be used. |
259 blink::WebCryptoKey key = blink::WebCryptoKey::createNull(); | 259 blink::WebCryptoKey key; |
260 bool extractable = false; | 260 bool extractable = false; |
261 blink::WebCryptoAlgorithm algorithm = | 261 blink::WebCryptoAlgorithm algorithm = |
262 CreateHmacImportAlgorithm(blink::WebCryptoAlgorithmIdSha256); | 262 CreateHmacImportAlgorithm(blink::WebCryptoAlgorithmIdSha256); |
263 blink::WebCryptoKeyUsageMask usage_mask = blink::WebCryptoKeyUsageVerify; | 263 blink::WebCryptoKeyUsageMask usage_mask = blink::WebCryptoKeyUsageVerify; |
264 base::DictionaryValue dict; | 264 base::DictionaryValue dict; |
265 dict.SetString("kty", "oct"); | 265 dict.SetString("kty", "oct"); |
266 dict.SetString("k", "l3nZEgZCeX8XRwJdWyK3rGB8qwjhdY8vOkbIvh4lxTuMao9Y_--hdg"); | 266 dict.SetString("k", "l3nZEgZCeX8XRwJdWyK3rGB8qwjhdY8vOkbIvh4lxTuMao9Y_--hdg"); |
267 std::vector<uint8_t> json_vec = MakeJsonVector(dict); | 267 std::vector<uint8_t> json_vec = MakeJsonVector(dict); |
268 EXPECT_EQ(Status::Success(), | 268 EXPECT_EQ(Status::Success(), |
269 ImportKey(blink::WebCryptoKeyFormatJwk, | 269 ImportKey(blink::WebCryptoKeyFormatJwk, |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
401 // must be of the RSA family, or when kty = "oct" alg must be symmetric | 401 // must be of the RSA family, or when kty = "oct" alg must be symmetric |
402 // algorithm. | 402 // algorithm. |
403 | 403 |
404 // TODO(padolph): key_ops consistency tests | 404 // TODO(padolph): key_ops consistency tests |
405 } | 405 } |
406 | 406 |
407 TEST(WebCryptoHmacTest, ImportJwkHappy) { | 407 TEST(WebCryptoHmacTest, ImportJwkHappy) { |
408 // This test verifies the happy path of JWK import, including the application | 408 // This test verifies the happy path of JWK import, including the application |
409 // of the imported key material. | 409 // of the imported key material. |
410 | 410 |
411 blink::WebCryptoKey key = blink::WebCryptoKey::createNull(); | 411 blink::WebCryptoKey key; |
412 bool extractable = false; | 412 bool extractable = false; |
413 blink::WebCryptoAlgorithm algorithm = | 413 blink::WebCryptoAlgorithm algorithm = |
414 CreateHmacImportAlgorithm(blink::WebCryptoAlgorithmIdSha256); | 414 CreateHmacImportAlgorithm(blink::WebCryptoAlgorithmIdSha256); |
415 blink::WebCryptoKeyUsageMask usage_mask = blink::WebCryptoKeyUsageSign; | 415 blink::WebCryptoKeyUsageMask usage_mask = blink::WebCryptoKeyUsageSign; |
416 | 416 |
417 // Import a symmetric key JWK and HMAC-SHA256 sign() | 417 // Import a symmetric key JWK and HMAC-SHA256 sign() |
418 // Uses the first SHA256 test vector from the HMAC sample set above. | 418 // Uses the first SHA256 test vector from the HMAC sample set above. |
419 | 419 |
420 base::DictionaryValue dict; | 420 base::DictionaryValue dict; |
421 dict.SetString("kty", "oct"); | 421 dict.SetString("kty", "oct"); |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
481 CreateHmacImportAlgorithm(blink::WebCryptoAlgorithmIdSha512), | 481 CreateHmacImportAlgorithm(blink::WebCryptoAlgorithmIdSha512), |
482 0, | 482 0, |
483 "HS512"); | 483 "HS512"); |
484 } | 484 } |
485 | 485 |
486 TEST(WebCryptoHmacTest, ExportJwkEmptyKey) { | 486 TEST(WebCryptoHmacTest, ExportJwkEmptyKey) { |
487 const blink::WebCryptoAlgorithm import_algorithm = | 487 const blink::WebCryptoAlgorithm import_algorithm = |
488 CreateHmacImportAlgorithm(blink::WebCryptoAlgorithmIdSha1); | 488 CreateHmacImportAlgorithm(blink::WebCryptoAlgorithmIdSha1); |
489 | 489 |
490 blink::WebCryptoKeyUsageMask usages = blink::WebCryptoKeyUsageSign; | 490 blink::WebCryptoKeyUsageMask usages = blink::WebCryptoKeyUsageSign; |
491 blink::WebCryptoKey key = blink::WebCryptoKey::createNull(); | 491 blink::WebCryptoKey key; |
492 | 492 |
493 // Import a zero-byte HMAC key. | 493 // Import a zero-byte HMAC key. |
494 const char key_data_hex[] = ""; | 494 const char key_data_hex[] = ""; |
495 key = ImportSecretKeyFromRaw( | 495 key = ImportSecretKeyFromRaw( |
496 HexStringToBytes(key_data_hex), import_algorithm, usages); | 496 HexStringToBytes(key_data_hex), import_algorithm, usages); |
497 EXPECT_EQ(0u, key.algorithm().hmacParams()->lengthBits()); | 497 EXPECT_EQ(0u, key.algorithm().hmacParams()->lengthBits()); |
498 | 498 |
499 // Export the key in JWK format and validate. | 499 // Export the key in JWK format and validate. |
500 std::vector<uint8_t> json; | 500 std::vector<uint8_t> json; |
501 ASSERT_EQ(Status::Success(), | 501 ASSERT_EQ(Status::Success(), |
(...skipping 18 matching lines...) Expand all Loading... |
520 ExportKey(blink::WebCryptoKeyFormatRaw, key, &exported_key_data)); | 520 ExportKey(blink::WebCryptoKeyFormatRaw, key, &exported_key_data)); |
521 | 521 |
522 EXPECT_EQ(0u, exported_key_data.size()); | 522 EXPECT_EQ(0u, exported_key_data.size()); |
523 } | 523 } |
524 | 524 |
525 // Import a huge hmac key (UINT_MAX bytes). This will fail before actually | 525 // Import a huge hmac key (UINT_MAX bytes). This will fail before actually |
526 // reading the bytes, as the key is too large. | 526 // reading the bytes, as the key is too large. |
527 TEST(WebCryptoHmacTest, ImportRawKeyTooLarge) { | 527 TEST(WebCryptoHmacTest, ImportRawKeyTooLarge) { |
528 CryptoData big_data(NULL, UINT_MAX); // Invalid data of big length. | 528 CryptoData big_data(NULL, UINT_MAX); // Invalid data of big length. |
529 | 529 |
530 blink::WebCryptoKey key = blink::WebCryptoKey::createNull(); | 530 blink::WebCryptoKey key; |
531 EXPECT_EQ( | 531 EXPECT_EQ( |
532 Status::ErrorDataTooLarge(), | 532 Status::ErrorDataTooLarge(), |
533 ImportKey(blink::WebCryptoKeyFormatRaw, | 533 ImportKey(blink::WebCryptoKeyFormatRaw, |
534 CryptoData(big_data), | 534 CryptoData(big_data), |
535 CreateHmacImportAlgorithm(blink::WebCryptoAlgorithmIdSha1), | 535 CreateHmacImportAlgorithm(blink::WebCryptoAlgorithmIdSha1), |
536 true, | 536 true, |
537 blink::WebCryptoKeyUsageSign, | 537 blink::WebCryptoKeyUsageSign, |
538 &key)); | 538 &key)); |
539 } | 539 } |
540 | 540 |
541 } // namespace | 541 } // namespace |
542 | 542 |
543 } // namespace webcrypto | 543 } // namespace webcrypto |
544 | 544 |
545 } // namespace content | 545 } // namespace content |
OLD | NEW |