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 "content/child/webcrypto/platform_crypto.h" | 5 #include "content/child/webcrypto/platform_crypto.h" |
6 | 6 |
7 #include <cryptohi.h> | 7 #include <cryptohi.h> |
8 #include <pk11pub.h> | 8 #include <pk11pub.h> |
| 9 #include <secerr.h> |
9 #include <sechash.h> | 10 #include <sechash.h> |
10 #include <secoid.h> | 11 #include <secoid.h> |
11 | 12 |
12 #include <vector> | 13 #include <vector> |
13 | 14 |
14 #include "base/lazy_instance.h" | 15 #include "base/lazy_instance.h" |
15 #include "base/logging.h" | 16 #include "base/logging.h" |
16 #include "content/child/webcrypto/crypto_data.h" | 17 #include "content/child/webcrypto/crypto_data.h" |
17 #include "content/child/webcrypto/status.h" | 18 #include "content/child/webcrypto/status.h" |
18 #include "content/child/webcrypto/webcrypto_util.h" | 19 #include "content/child/webcrypto/webcrypto_util.h" |
(...skipping 481 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
500 crypto::ScopedSECItem param_item( | 501 crypto::ScopedSECItem param_item( |
501 PK11_ParamFromIV(CKM_NSS_AES_KEY_WRAP, &iv_item)); | 502 PK11_ParamFromIV(CKM_NSS_AES_KEY_WRAP, &iv_item)); |
502 if (!param_item) | 503 if (!param_item) |
503 return Status::ErrorUnexpected(); | 504 return Status::ErrorUnexpected(); |
504 | 505 |
505 SECItem cipher_text = MakeSECItemForBuffer(wrapped_key_data); | 506 SECItem cipher_text = MakeSECItemForBuffer(wrapped_key_data); |
506 | 507 |
507 // The plaintext length is always 64 bits less than the data size. | 508 // The plaintext length is always 64 bits less than the data size. |
508 const unsigned int plaintext_length = wrapped_key_data.byte_length() - 8; | 509 const unsigned int plaintext_length = wrapped_key_data.byte_length() - 8; |
509 | 510 |
| 511 #if defined(USE_NSS) |
| 512 // Part of workaround for |
| 513 // https://bugzilla.mozilla.org/show_bug.cgi?id=981170. See the explanation |
| 514 // later in this function. |
| 515 PORT_SetError(0); |
| 516 #endif |
| 517 |
510 crypto::ScopedPK11SymKey new_key(PK11_UnwrapSymKey(wrapping_key->key(), | 518 crypto::ScopedPK11SymKey new_key(PK11_UnwrapSymKey(wrapping_key->key(), |
511 CKM_NSS_AES_KEY_WRAP, | 519 CKM_NSS_AES_KEY_WRAP, |
512 param_item.get(), | 520 param_item.get(), |
513 &cipher_text, | 521 &cipher_text, |
514 mechanism, | 522 mechanism, |
515 flags, | 523 flags, |
516 plaintext_length)); | 524 plaintext_length)); |
517 // TODO(padolph): Use NSS PORT_GetError() and friends to report a more | 525 // TODO(padolph): Use NSS PORT_GetError() and friends to report a more |
518 // accurate error, providing if doesn't leak any information to web pages | 526 // accurate error, providing if doesn't leak any information to web pages |
519 // about other web crypto users, key details, etc. | 527 // about other web crypto users, key details, etc. |
520 if (!new_key) | 528 if (!new_key) |
521 return Status::Error(); | 529 return Status::Error(); |
522 | 530 |
523 // TODO(padolph): Change to "defined(USE_NSS)" once the NSS fix for | 531 #if defined(USE_NSS) |
524 // https://bugzilla.mozilla.org/show_bug.cgi?id=981170 rolls into chromium. | 532 // Workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=981170 |
525 #if 1 | 533 // which was fixed in NSS 3.16.0. |
526 // ------- Start NSS bug workaround | 534 // If unwrap fails, NSS nevertheless returns a valid-looking PK11SymKey, |
527 // Workaround for https://code.google.com/p/chromium/issues/detail?id=349939 | 535 // with a reasonable length but with key data pointing to uninitialized |
528 // If unwrap fails, NSS nevertheless returns a valid-looking PK11SymKey, with | 536 // memory. |
529 // a reasonable length but with key data pointing to uninitialized memory. | 537 // To understand this workaround see the fix for 981170: |
530 // This workaround re-wraps the key and compares the result with the incoming | 538 // https://hg.mozilla.org/projects/nss/rev/753bb69e543c |
531 // data, and fails if there is a difference. This prevents returning a bad key | 539 if (!NSS_VersionCheck("3.16") && PORT_GetError() == SEC_ERROR_BAD_DATA) |
532 // to the caller. | |
533 const unsigned int output_length = wrapped_key_data.byte_length(); | |
534 std::vector<unsigned char> buffer(output_length, 0); | |
535 SECItem wrapped_key_item = MakeSECItemForBuffer(CryptoData(buffer)); | |
536 if (SECSuccess != PK11_WrapSymKey(CKM_NSS_AES_KEY_WRAP, | |
537 param_item.get(), | |
538 wrapping_key->key(), | |
539 new_key.get(), | |
540 &wrapped_key_item)) { | |
541 return Status::Error(); | 540 return Status::Error(); |
542 } | |
543 if (wrapped_key_item.len != wrapped_key_data.byte_length() || | |
544 memcmp(wrapped_key_item.data, | |
545 wrapped_key_data.bytes(), | |
546 wrapped_key_item.len) != 0) { | |
547 return Status::Error(); | |
548 } | |
549 // ------- End NSS bug workaround | |
550 #endif | 541 #endif |
551 | 542 |
552 *unwrapped_key = new_key.Pass(); | 543 *unwrapped_key = new_key.Pass(); |
553 return Status::Success(); | 544 return Status::Success(); |
554 } | 545 } |
555 | 546 |
556 // From PKCS#1 [http://tools.ietf.org/html/rfc3447]: | 547 // From PKCS#1 [http://tools.ietf.org/html/rfc3447]: |
557 // | 548 // |
558 // RSAPrivateKey ::= SEQUENCE { | 549 // RSAPrivateKey ::= SEQUENCE { |
559 // version Version, | 550 // version Version, |
(...skipping 925 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1485 key_algorithm, | 1476 key_algorithm, |
1486 usage_mask); | 1477 usage_mask); |
1487 return Status::Success(); | 1478 return Status::Success(); |
1488 } | 1479 } |
1489 | 1480 |
1490 } // namespace platform | 1481 } // namespace platform |
1491 | 1482 |
1492 } // namespace webcrypto | 1483 } // namespace webcrypto |
1493 | 1484 |
1494 } // namespace content | 1485 } // namespace content |
OLD | NEW |