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 242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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; | 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 usages = 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, |
270 CryptoData(json_vec), | 270 CryptoData(json_vec), |
271 algorithm, | 271 algorithm, |
272 extractable, | 272 extractable, |
273 usage_mask, | 273 usages, |
274 &key)); | 274 &key)); |
275 EXPECT_TRUE(key.handle()); | 275 EXPECT_TRUE(key.handle()); |
276 EXPECT_EQ(blink::WebCryptoKeyTypeSecret, key.type()); | 276 EXPECT_EQ(blink::WebCryptoKeyTypeSecret, key.type()); |
277 EXPECT_EQ(extractable, key.extractable()); | 277 EXPECT_EQ(extractable, key.extractable()); |
278 EXPECT_EQ(blink::WebCryptoAlgorithmIdHmac, key.algorithm().id()); | 278 EXPECT_EQ(blink::WebCryptoAlgorithmIdHmac, key.algorithm().id()); |
279 EXPECT_EQ(blink::WebCryptoAlgorithmIdSha256, | 279 EXPECT_EQ(blink::WebCryptoAlgorithmIdSha256, |
280 key.algorithm().hmacParams()->hash().id()); | 280 key.algorithm().hmacParams()->hash().id()); |
281 EXPECT_EQ(320u, key.algorithm().hmacParams()->lengthBits()); | 281 EXPECT_EQ(320u, key.algorithm().hmacParams()->lengthBits()); |
282 EXPECT_EQ(blink::WebCryptoKeyUsageVerify, key.usages()); | 282 EXPECT_EQ(blink::WebCryptoKeyUsageVerify, key.usages()); |
283 key = blink::WebCryptoKey::createNull(); | 283 key = blink::WebCryptoKey::createNull(); |
284 | 284 |
285 // Consistency rules when JWK value exists: Fail if inconsistency is found. | 285 // Consistency rules when JWK value exists: Fail if inconsistency is found. |
286 | 286 |
287 // Pass: All input values are consistent with the JWK values. | 287 // Pass: All input values are consistent with the JWK values. |
288 dict.Clear(); | 288 dict.Clear(); |
289 dict.SetString("kty", "oct"); | 289 dict.SetString("kty", "oct"); |
290 dict.SetString("alg", "HS256"); | 290 dict.SetString("alg", "HS256"); |
291 dict.SetString("use", "sig"); | 291 dict.SetString("use", "sig"); |
292 dict.SetBoolean("ext", false); | 292 dict.SetBoolean("ext", false); |
293 dict.SetString("k", "l3nZEgZCeX8XRwJdWyK3rGB8qwjhdY8vOkbIvh4lxTuMao9Y_--hdg"); | 293 dict.SetString("k", "l3nZEgZCeX8XRwJdWyK3rGB8qwjhdY8vOkbIvh4lxTuMao9Y_--hdg"); |
294 json_vec = MakeJsonVector(dict); | 294 json_vec = MakeJsonVector(dict); |
295 EXPECT_EQ(Status::Success(), | 295 EXPECT_EQ(Status::Success(), |
296 ImportKey(blink::WebCryptoKeyFormatJwk, | 296 ImportKey(blink::WebCryptoKeyFormatJwk, |
297 CryptoData(json_vec), | 297 CryptoData(json_vec), |
298 algorithm, | 298 algorithm, |
299 extractable, | 299 extractable, |
300 usage_mask, | 300 usages, |
301 &key)); | 301 &key)); |
302 | 302 |
303 // Extractable cases: | 303 // Extractable cases: |
304 // 1. input=T, JWK=F ==> fail (inconsistent) | 304 // 1. input=T, JWK=F ==> fail (inconsistent) |
305 // 4. input=F, JWK=F ==> pass, result extractable is F | 305 // 4. input=F, JWK=F ==> pass, result extractable is F |
306 // 2. input=T, JWK=T ==> pass, result extractable is T | 306 // 2. input=T, JWK=T ==> pass, result extractable is T |
307 // 3. input=F, JWK=T ==> pass, result extractable is F | 307 // 3. input=F, JWK=T ==> pass, result extractable is F |
308 EXPECT_EQ(Status::ErrorJwkExtInconsistent(), | 308 EXPECT_EQ(Status::ErrorJwkExtInconsistent(), |
309 ImportKey(blink::WebCryptoKeyFormatJwk, | 309 ImportKey(blink::WebCryptoKeyFormatJwk, |
310 CryptoData(json_vec), | 310 CryptoData(json_vec), |
311 algorithm, | 311 algorithm, |
312 true, | 312 true, |
313 usage_mask, | 313 usages, |
314 &key)); | 314 &key)); |
315 EXPECT_EQ(Status::Success(), | 315 EXPECT_EQ(Status::Success(), |
316 ImportKey(blink::WebCryptoKeyFormatJwk, | 316 ImportKey(blink::WebCryptoKeyFormatJwk, |
317 CryptoData(json_vec), | 317 CryptoData(json_vec), |
318 algorithm, | 318 algorithm, |
319 false, | 319 false, |
320 usage_mask, | 320 usages, |
321 &key)); | 321 &key)); |
322 EXPECT_FALSE(key.extractable()); | 322 EXPECT_FALSE(key.extractable()); |
323 dict.SetBoolean("ext", true); | 323 dict.SetBoolean("ext", true); |
324 EXPECT_EQ(Status::Success(), | 324 EXPECT_EQ(Status::Success(), |
325 ImportKeyJwkFromDict(dict, algorithm, true, usage_mask, &key)); | 325 ImportKeyJwkFromDict(dict, algorithm, true, usages, &key)); |
326 EXPECT_TRUE(key.extractable()); | 326 EXPECT_TRUE(key.extractable()); |
327 EXPECT_EQ(Status::Success(), | 327 EXPECT_EQ(Status::Success(), |
328 ImportKeyJwkFromDict(dict, algorithm, false, usage_mask, &key)); | 328 ImportKeyJwkFromDict(dict, algorithm, false, usages, &key)); |
329 EXPECT_FALSE(key.extractable()); | 329 EXPECT_FALSE(key.extractable()); |
330 dict.SetBoolean("ext", true); // restore previous value | 330 dict.SetBoolean("ext", true); // restore previous value |
331 | 331 |
332 // Fail: Input algorithm (AES-CBC) is inconsistent with JWK value | 332 // Fail: Input algorithm (AES-CBC) is inconsistent with JWK value |
333 // (HMAC SHA256). | 333 // (HMAC SHA256). |
334 dict.Clear(); | 334 dict.Clear(); |
335 dict.SetString("kty", "oct"); | 335 dict.SetString("kty", "oct"); |
336 dict.SetString("alg", "HS256"); | 336 dict.SetString("alg", "HS256"); |
337 dict.SetString("k", "l3nZEgZCeX8XRwJdWyK3rGB8qwjhdY8vOkbIvh4lxTuMao9Y_--hdg"); | 337 dict.SetString("k", "l3nZEgZCeX8XRwJdWyK3rGB8qwjhdY8vOkbIvh4lxTuMao9Y_--hdg"); |
338 EXPECT_EQ( | 338 EXPECT_EQ( |
(...skipping 13 matching lines...) Expand all Loading... |
352 &key)); | 352 &key)); |
353 | 353 |
354 // Fail: Input algorithm (HMAC SHA1) is inconsistent with JWK value | 354 // Fail: Input algorithm (HMAC SHA1) is inconsistent with JWK value |
355 // (HMAC SHA256). | 355 // (HMAC SHA256). |
356 EXPECT_EQ( | 356 EXPECT_EQ( |
357 Status::ErrorJwkAlgorithmInconsistent(), | 357 Status::ErrorJwkAlgorithmInconsistent(), |
358 ImportKey(blink::WebCryptoKeyFormatJwk, | 358 ImportKey(blink::WebCryptoKeyFormatJwk, |
359 CryptoData(json_vec), | 359 CryptoData(json_vec), |
360 CreateHmacImportAlgorithm(blink::WebCryptoAlgorithmIdSha1), | 360 CreateHmacImportAlgorithm(blink::WebCryptoAlgorithmIdSha1), |
361 extractable, | 361 extractable, |
362 usage_mask, | 362 usages, |
363 &key)); | 363 &key)); |
364 | 364 |
365 // Pass: JWK alg missing but input algorithm specified: use input value | 365 // Pass: JWK alg missing but input algorithm specified: use input value |
366 dict.Remove("alg", NULL); | 366 dict.Remove("alg", NULL); |
367 EXPECT_EQ(Status::Success(), | 367 EXPECT_EQ(Status::Success(), |
368 ImportKeyJwkFromDict( | 368 ImportKeyJwkFromDict( |
369 dict, | 369 dict, |
370 CreateHmacImportAlgorithm(blink::WebCryptoAlgorithmIdSha256), | 370 CreateHmacImportAlgorithm(blink::WebCryptoAlgorithmIdSha256), |
371 extractable, | 371 extractable, |
372 usage_mask, | 372 usages, |
373 &key)); | 373 &key)); |
374 EXPECT_EQ(blink::WebCryptoAlgorithmIdHmac, algorithm.id()); | 374 EXPECT_EQ(blink::WebCryptoAlgorithmIdHmac, algorithm.id()); |
375 dict.SetString("alg", "HS256"); | 375 dict.SetString("alg", "HS256"); |
376 | 376 |
377 // Fail: Input usage_mask (encrypt) is not a subset of the JWK value | 377 // Fail: Input usages (encrypt) is not a subset of the JWK value |
378 // (sign|verify). Moreover "encrypt" is not a valid usage for HMAC. | 378 // (sign|verify). Moreover "encrypt" is not a valid usage for HMAC. |
379 EXPECT_EQ(Status::ErrorCreateKeyBadUsages(), | 379 EXPECT_EQ(Status::ErrorCreateKeyBadUsages(), |
380 ImportKey(blink::WebCryptoKeyFormatJwk, | 380 ImportKey(blink::WebCryptoKeyFormatJwk, |
381 CryptoData(json_vec), | 381 CryptoData(json_vec), |
382 algorithm, | 382 algorithm, |
383 extractable, | 383 extractable, |
384 blink::WebCryptoKeyUsageEncrypt, | 384 blink::WebCryptoKeyUsageEncrypt, |
385 &key)); | 385 &key)); |
386 | 386 |
387 // Fail: Input usage_mask (encrypt|sign|verify) is not a subset of the JWK | 387 // Fail: Input usages (encrypt|sign|verify) is not a subset of the JWK |
388 // value (sign|verify). Moreover "encrypt" is not a valid usage for HMAC. | 388 // value (sign|verify). Moreover "encrypt" is not a valid usage for HMAC. |
389 usage_mask = blink::WebCryptoKeyUsageEncrypt | blink::WebCryptoKeyUsageSign | | 389 usages = blink::WebCryptoKeyUsageEncrypt | blink::WebCryptoKeyUsageSign | |
390 blink::WebCryptoKeyUsageVerify; | 390 blink::WebCryptoKeyUsageVerify; |
391 EXPECT_EQ(Status::ErrorCreateKeyBadUsages(), | 391 EXPECT_EQ(Status::ErrorCreateKeyBadUsages(), |
392 ImportKey(blink::WebCryptoKeyFormatJwk, | 392 ImportKey(blink::WebCryptoKeyFormatJwk, |
393 CryptoData(json_vec), | 393 CryptoData(json_vec), |
394 algorithm, | 394 algorithm, |
395 extractable, | 395 extractable, |
396 usage_mask, | 396 usages, |
397 &key)); | 397 &key)); |
398 | 398 |
399 // TODO(padolph): kty vs alg consistency tests: Depending on the kty value, | 399 // TODO(padolph): kty vs alg consistency tests: Depending on the kty value, |
400 // only certain alg values are permitted. For example, when kty = "RSA" alg | 400 // only certain alg values are permitted. For example, when kty = "RSA" alg |
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; | 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 usages = 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"); |
422 dict.SetString("alg", "HS256"); | 422 dict.SetString("alg", "HS256"); |
423 dict.SetString("use", "sig"); | 423 dict.SetString("use", "sig"); |
424 dict.SetBoolean("ext", false); | 424 dict.SetBoolean("ext", false); |
425 dict.SetString("k", "l3nZEgZCeX8XRwJdWyK3rGB8qwjhdY8vOkbIvh4lxTuMao9Y_--hdg"); | 425 dict.SetString("k", "l3nZEgZCeX8XRwJdWyK3rGB8qwjhdY8vOkbIvh4lxTuMao9Y_--hdg"); |
426 | 426 |
427 ASSERT_EQ( | 427 ASSERT_EQ(Status::Success(), |
428 Status::Success(), | 428 ImportKeyJwkFromDict(dict, algorithm, extractable, usages, &key)); |
429 ImportKeyJwkFromDict(dict, algorithm, extractable, usage_mask, &key)); | |
430 | 429 |
431 EXPECT_EQ(blink::WebCryptoAlgorithmIdSha256, | 430 EXPECT_EQ(blink::WebCryptoAlgorithmIdSha256, |
432 key.algorithm().hmacParams()->hash().id()); | 431 key.algorithm().hmacParams()->hash().id()); |
433 | 432 |
434 const std::vector<uint8_t> message_raw = HexStringToBytes( | 433 const std::vector<uint8_t> message_raw = HexStringToBytes( |
435 "b1689c2591eaf3c9e66070f8a77954ffb81749f1b00346f9dfe0b2ee905dcc288baf4a" | 434 "b1689c2591eaf3c9e66070f8a77954ffb81749f1b00346f9dfe0b2ee905dcc288baf4a" |
436 "92de3f4001dd9f44c468c3d07d6c6ee82faceafc97c2fc0fc0601719d2dcd0aa2aec92" | 435 "92de3f4001dd9f44c468c3d07d6c6ee82faceafc97c2fc0fc0601719d2dcd0aa2aec92" |
437 "d1b0ae933c65eb06a03c9c935c2bad0459810241347ab87e9f11adb30415424c6c7f5f" | 436 "d1b0ae933c65eb06a03c9c935c2bad0459810241347ab87e9f11adb30415424c6c7f5f" |
438 "22a003b8ab8de54f6ded0e3ab9245fa79568451dfa258e"); | 437 "22a003b8ab8de54f6ded0e3ab9245fa79568451dfa258e"); |
439 | 438 |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
536 true, | 535 true, |
537 blink::WebCryptoKeyUsageSign, | 536 blink::WebCryptoKeyUsageSign, |
538 &key)); | 537 &key)); |
539 } | 538 } |
540 | 539 |
541 } // namespace | 540 } // namespace |
542 | 541 |
543 } // namespace webcrypto | 542 } // namespace webcrypto |
544 | 543 |
545 } // namespace content | 544 } // namespace content |
OLD | NEW |