Chromium Code Reviews| 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 |