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 | 11 |
11 #include <vector> | 12 #include <vector> |
12 | 13 |
13 #include "base/lazy_instance.h" | 14 #include "base/lazy_instance.h" |
14 #include "base/logging.h" | 15 #include "base/logging.h" |
15 #include "content/child/webcrypto/crypto_data.h" | 16 #include "content/child/webcrypto/crypto_data.h" |
16 #include "content/child/webcrypto/status.h" | 17 #include "content/child/webcrypto/status.h" |
17 #include "content/child/webcrypto/webcrypto_util.h" | 18 #include "content/child/webcrypto/webcrypto_util.h" |
18 #include "crypto/nss_util.h" | 19 #include "crypto/nss_util.h" |
(...skipping 480 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
499 crypto::ScopedSECItem param_item( | 500 crypto::ScopedSECItem param_item( |
500 PK11_ParamFromIV(CKM_NSS_AES_KEY_WRAP, &iv_item)); | 501 PK11_ParamFromIV(CKM_NSS_AES_KEY_WRAP, &iv_item)); |
501 if (!param_item) | 502 if (!param_item) |
502 return Status::ErrorUnexpected(); | 503 return Status::ErrorUnexpected(); |
503 | 504 |
504 SECItem cipher_text = MakeSECItemForBuffer(wrapped_key_data); | 505 SECItem cipher_text = MakeSECItemForBuffer(wrapped_key_data); |
505 | 506 |
506 // The plaintext length is always 64 bits less than the data size. | 507 // The plaintext length is always 64 bits less than the data size. |
507 const unsigned int plaintext_length = wrapped_key_data.byte_length() - 8; | 508 const unsigned int plaintext_length = wrapped_key_data.byte_length() - 8; |
508 | 509 |
510 #if defined(USE_NSS) | |
511 PORT_SetError(0); | |
wtc
2014/03/25 02:02:01
Nit: add a comment to note this is part of the wor
eroman
2014/03/25 02:07:05
Done.
| |
512 #endif | |
513 | |
509 crypto::ScopedPK11SymKey new_key(PK11_UnwrapSymKey(wrapping_key->key(), | 514 crypto::ScopedPK11SymKey new_key(PK11_UnwrapSymKey(wrapping_key->key(), |
510 CKM_NSS_AES_KEY_WRAP, | 515 CKM_NSS_AES_KEY_WRAP, |
511 param_item.get(), | 516 param_item.get(), |
512 &cipher_text, | 517 &cipher_text, |
513 mechanism, | 518 mechanism, |
514 flags, | 519 flags, |
515 plaintext_length)); | 520 plaintext_length)); |
521 | |
522 #if defined(USE_NSS) | |
523 // Workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=981170 | |
524 // which was fixed in NSS 3.16.0. | |
525 // If unwrap fails, NSS nevertheless returns a valid-looking PK11SymKey, | |
526 // with a reasonable length but with key data pointing to uninitialized | |
527 // memory. | |
528 // To understand this workaround see the fix for 981170: | |
529 // https://hg.mozilla.org/projects/nss/rev/753bb69e543c | |
530 if (!NSS_VersionCheck("3.16") && PORT_GetError() == SEC_ERROR_BAD_DATA) | |
531 return Status::Error(); | |
532 #endif | |
wtc
2014/03/25 02:02:01
Nit: it may be better to put the workaround after
eroman
2014/03/25 02:07:05
Done.
| |
533 | |
516 // TODO(padolph): Use NSS PORT_GetError() and friends to report a more | 534 // TODO(padolph): Use NSS PORT_GetError() and friends to report a more |
517 // accurate error, providing if doesn't leak any information to web pages | 535 // accurate error, providing if doesn't leak any information to web pages |
518 // about other web crypto users, key details, etc. | 536 // about other web crypto users, key details, etc. |
519 if (!new_key) | 537 if (!new_key) |
520 return Status::Error(); | 538 return Status::Error(); |
521 | 539 |
522 // TODO(padolph): Change to "defined(USE_NSS)" once the NSS fix for | |
523 // https://bugzilla.mozilla.org/show_bug.cgi?id=981170 rolls into chromium. | |
524 #if 1 | |
525 // ------- Start NSS bug workaround | |
526 // Workaround for https://code.google.com/p/chromium/issues/detail?id=349939 | |
527 // If unwrap fails, NSS nevertheless returns a valid-looking PK11SymKey, with | |
528 // a reasonable length but with key data pointing to uninitialized memory. | |
529 // This workaround re-wraps the key and compares the result with the incoming | |
530 // data, and fails if there is a difference. This prevents returning a bad key | |
531 // to the caller. | |
532 const unsigned int output_length = wrapped_key_data.byte_length(); | |
533 std::vector<unsigned char> buffer(output_length, 0); | |
534 SECItem wrapped_key_item = MakeSECItemForBuffer(CryptoData(buffer)); | |
535 if (SECSuccess != PK11_WrapSymKey(CKM_NSS_AES_KEY_WRAP, | |
536 param_item.get(), | |
537 wrapping_key->key(), | |
538 new_key.get(), | |
539 &wrapped_key_item)) { | |
540 return Status::Error(); | |
541 } | |
542 if (wrapped_key_item.len != wrapped_key_data.byte_length() || | |
543 memcmp(wrapped_key_item.data, | |
544 wrapped_key_data.bytes(), | |
545 wrapped_key_item.len) != 0) { | |
546 return Status::Error(); | |
547 } | |
548 // ------- End NSS bug workaround | |
549 #endif | |
550 | 540 |
551 *unwrapped_key = new_key.Pass(); | 541 *unwrapped_key = new_key.Pass(); |
552 return Status::Success(); | 542 return Status::Success(); |
553 } | 543 } |
554 | 544 |
555 } // namespace | 545 } // namespace |
556 | 546 |
557 Status ImportKeyRaw(const blink::WebCryptoAlgorithm& algorithm, | 547 Status ImportKeyRaw(const blink::WebCryptoAlgorithm& algorithm, |
558 const CryptoData& key_data, | 548 const CryptoData& key_data, |
559 bool extractable, | 549 bool extractable, |
(...skipping 763 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1323 key_algorithm, | 1313 key_algorithm, |
1324 usage_mask); | 1314 usage_mask); |
1325 return Status::Success(); | 1315 return Status::Success(); |
1326 } | 1316 } |
1327 | 1317 |
1328 } // namespace platform | 1318 } // namespace platform |
1329 | 1319 |
1330 } // namespace webcrypto | 1320 } // namespace webcrypto |
1331 | 1321 |
1332 } // namespace content | 1322 } // namespace content |
OLD | NEW |