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 <secerr.h> |
10 #include <sechash.h> | 10 #include <sechash.h> |
11 | 11 |
12 #include <vector> | 12 #include <vector> |
13 | 13 |
14 #include "base/lazy_instance.h" | 14 #include "base/lazy_instance.h" |
15 #include "base/logging.h" | 15 #include "base/logging.h" |
| 16 #include "base/memory/scoped_ptr.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" |
19 #include "crypto/nss_util.h" | 20 #include "crypto/nss_util.h" |
20 #include "crypto/scoped_nss_types.h" | 21 #include "crypto/scoped_nss_types.h" |
21 #include "third_party/WebKit/public/platform/WebArrayBuffer.h" | 22 #include "third_party/WebKit/public/platform/WebArrayBuffer.h" |
22 #include "third_party/WebKit/public/platform/WebCryptoAlgorithm.h" | 23 #include "third_party/WebKit/public/platform/WebCryptoAlgorithm.h" |
23 #include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h" | 24 #include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h" |
24 #include "third_party/WebKit/public/platform/WebCryptoKeyAlgorithm.h" | 25 #include "third_party/WebKit/public/platform/WebCryptoKeyAlgorithm.h" |
25 | 26 |
(...skipping 630 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
656 SECITEM_FreeItem(&out->prime2, PR_FALSE); | 657 SECITEM_FreeItem(&out->prime2, PR_FALSE); |
657 SECITEM_FreeItem(&out->exponent1, PR_FALSE); | 658 SECITEM_FreeItem(&out->exponent1, PR_FALSE); |
658 SECITEM_FreeItem(&out->exponent2, PR_FALSE); | 659 SECITEM_FreeItem(&out->exponent2, PR_FALSE); |
659 SECITEM_FreeItem(&out->coefficient, PR_FALSE); | 660 SECITEM_FreeItem(&out->coefficient, PR_FALSE); |
660 } | 661 } |
661 }; | 662 }; |
662 #endif // defined(USE_NSS) | 663 #endif // defined(USE_NSS) |
663 | 664 |
664 } // namespace | 665 } // namespace |
665 | 666 |
| 667 class DigestorNSS : public blink::WebCryptoDigestor { |
| 668 public: |
| 669 explicit DigestorNSS(blink::WebCryptoAlgorithmId algorithm_id) |
| 670 : hash_context_(NULL), algorithm_id_(algorithm_id) {} |
| 671 |
| 672 virtual ~DigestorNSS() { |
| 673 if (!hash_context_) |
| 674 return; |
| 675 |
| 676 HASH_Destroy(hash_context_); |
| 677 hash_context_ = NULL; |
| 678 } |
| 679 |
| 680 virtual bool consume(const unsigned char* data, unsigned int size) { |
| 681 return ConsumeWithStatus(data, size).IsSuccess(); |
| 682 } |
| 683 |
| 684 Status ConsumeWithStatus(const unsigned char* data, unsigned int size) { |
| 685 // Initialize everything if the object hasn't been initialized yet. |
| 686 if (!hash_context_) { |
| 687 Status error = Init(); |
| 688 if (!error.IsSuccess()) |
| 689 return error; |
| 690 } |
| 691 |
| 692 HASH_Update(hash_context_, data, size); |
| 693 |
| 694 return Status::Success(); |
| 695 } |
| 696 |
| 697 virtual bool finish(unsigned char*& result_data, |
| 698 unsigned int& result_data_size) { |
| 699 Status error = FinishInternal(result_, &result_data_size); |
| 700 if (!error.IsSuccess()) |
| 701 return false; |
| 702 result_data = result_; |
| 703 return true; |
| 704 } |
| 705 |
| 706 Status FinishWithWebArrayAndStatus(blink::WebArrayBuffer* result) { |
| 707 if (!hash_context_) |
| 708 return Status::ErrorUnexpected(); |
| 709 |
| 710 unsigned int result_length = HASH_ResultLenContext(hash_context_); |
| 711 *result = blink::WebArrayBuffer::create(result_length, 1); |
| 712 unsigned char* digest = reinterpret_cast<unsigned char*>(result->data()); |
| 713 unsigned int digest_size; // ignored |
| 714 return FinishInternal(digest, &digest_size); |
| 715 } |
| 716 |
| 717 private: |
| 718 Status Init() { |
| 719 HASH_HashType hash_type = WebCryptoAlgorithmToNSSHashType(algorithm_id_); |
| 720 |
| 721 if (hash_type == HASH_AlgNULL) |
| 722 return Status::ErrorUnsupported(); |
| 723 |
| 724 hash_context_ = HASH_Create(hash_type); |
| 725 if (!hash_context_) |
| 726 return Status::Error(); |
| 727 |
| 728 HASH_Begin(hash_context_); |
| 729 |
| 730 return Status::Success(); |
| 731 } |
| 732 |
| 733 Status FinishInternal(unsigned char* result, unsigned int* result_size) { |
| 734 if (!hash_context_) { |
| 735 Status error = Init(); |
| 736 if (!error.IsSuccess()) |
| 737 return error; |
| 738 } |
| 739 |
| 740 unsigned int hash_result_length = HASH_ResultLenContext(hash_context_); |
| 741 DCHECK_LE(hash_result_length, static_cast<size_t>(HASH_LENGTH_MAX)); |
| 742 |
| 743 HASH_End(hash_context_, result, result_size, hash_result_length); |
| 744 |
| 745 if (*result_size != hash_result_length) |
| 746 return Status::ErrorUnexpected(); |
| 747 return Status::Success(); |
| 748 } |
| 749 |
| 750 HASHContext* hash_context_; |
| 751 blink::WebCryptoAlgorithmId algorithm_id_; |
| 752 unsigned char result_[HASH_LENGTH_MAX]; |
| 753 }; |
| 754 |
666 Status ImportKeyRaw(const blink::WebCryptoAlgorithm& algorithm, | 755 Status ImportKeyRaw(const blink::WebCryptoAlgorithm& algorithm, |
667 const CryptoData& key_data, | 756 const CryptoData& key_data, |
668 bool extractable, | 757 bool extractable, |
669 blink::WebCryptoKeyUsageMask usage_mask, | 758 blink::WebCryptoKeyUsageMask usage_mask, |
670 blink::WebCryptoKey* key) { | 759 blink::WebCryptoKey* key) { |
671 | 760 |
672 DCHECK(!algorithm.isNull()); | 761 DCHECK(!algorithm.isNull()); |
673 | 762 |
674 CK_MECHANISM_TYPE mechanism; | 763 CK_MECHANISM_TYPE mechanism; |
675 CK_FLAGS flags; | 764 CK_FLAGS flags; |
(...skipping 527 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1203 usage_mask); | 1292 usage_mask); |
1204 | 1293 |
1205 return Status::Success(); | 1294 return Status::Success(); |
1206 } | 1295 } |
1207 | 1296 |
1208 void Init() { crypto::EnsureNSSInit(); } | 1297 void Init() { crypto::EnsureNSSInit(); } |
1209 | 1298 |
1210 Status DigestSha(blink::WebCryptoAlgorithmId algorithm, | 1299 Status DigestSha(blink::WebCryptoAlgorithmId algorithm, |
1211 const CryptoData& data, | 1300 const CryptoData& data, |
1212 blink::WebArrayBuffer* buffer) { | 1301 blink::WebArrayBuffer* buffer) { |
1213 HASH_HashType hash_type = WebCryptoAlgorithmToNSSHashType(algorithm); | 1302 DigestorNSS digestor(algorithm); |
1214 if (hash_type == HASH_AlgNULL) | 1303 Status error = digestor.ConsumeWithStatus(data.bytes(), data.byte_length()); |
1215 return Status::ErrorUnsupported(); | 1304 if (!error.IsSuccess()) |
| 1305 return error; |
| 1306 return digestor.FinishWithWebArrayAndStatus(buffer); |
| 1307 } |
1216 | 1308 |
1217 HASHContext* context = HASH_Create(hash_type); | 1309 scoped_ptr<blink::WebCryptoDigestor> CreateDigestor( |
1218 if (!context) | 1310 blink::WebCryptoAlgorithmId algorithm_id) { |
1219 return Status::Error(); | 1311 return scoped_ptr<blink::WebCryptoDigestor>(new DigestorNSS(algorithm_id)); |
1220 | |
1221 HASH_Begin(context); | |
1222 | |
1223 HASH_Update(context, data.bytes(), data.byte_length()); | |
1224 | |
1225 unsigned int hash_result_length = HASH_ResultLenContext(context); | |
1226 DCHECK_LE(hash_result_length, static_cast<size_t>(HASH_LENGTH_MAX)); | |
1227 | |
1228 *buffer = blink::WebArrayBuffer::create(hash_result_length, 1); | |
1229 | |
1230 unsigned char* digest = reinterpret_cast<unsigned char*>(buffer->data()); | |
1231 | |
1232 unsigned int result_length = 0; | |
1233 HASH_End(context, digest, &result_length, hash_result_length); | |
1234 | |
1235 HASH_Destroy(context); | |
1236 | |
1237 if (result_length != hash_result_length) | |
1238 return Status::ErrorUnexpected(); | |
1239 return Status::Success(); | |
1240 } | 1312 } |
1241 | 1313 |
1242 Status GenerateSecretKey(const blink::WebCryptoAlgorithm& algorithm, | 1314 Status GenerateSecretKey(const blink::WebCryptoAlgorithm& algorithm, |
1243 bool extractable, | 1315 bool extractable, |
1244 blink::WebCryptoKeyUsageMask usage_mask, | 1316 blink::WebCryptoKeyUsageMask usage_mask, |
1245 unsigned keylen_bytes, | 1317 unsigned keylen_bytes, |
1246 blink::WebCryptoKey* key) { | 1318 blink::WebCryptoKey* key) { |
1247 CK_MECHANISM_TYPE mech = WebCryptoAlgorithmToGenMechanism(algorithm); | 1319 CK_MECHANISM_TYPE mech = WebCryptoAlgorithmToGenMechanism(algorithm); |
1248 blink::WebCryptoKeyType key_type = blink::WebCryptoKeyTypeSecret; | 1320 blink::WebCryptoKeyType key_type = blink::WebCryptoKeyTypeSecret; |
1249 | 1321 |
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1507 key_algorithm, | 1579 key_algorithm, |
1508 usage_mask); | 1580 usage_mask); |
1509 return Status::Success(); | 1581 return Status::Success(); |
1510 } | 1582 } |
1511 | 1583 |
1512 } // namespace platform | 1584 } // namespace platform |
1513 | 1585 |
1514 } // namespace webcrypto | 1586 } // namespace webcrypto |
1515 | 1587 |
1516 } // namespace content | 1588 } // namespace content |
OLD | NEW |