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/renderer/webcrypto/platform_crypto.h" | 5 #include "content/renderer/webcrypto/platform_crypto.h" |
6 | 6 |
7 #include <cryptohi.h> | 7 #include <cryptohi.h> |
8 #include <pk11pub.h> | 8 #include <pk11pub.h> |
9 #include <sechash.h> | 9 #include <sechash.h> |
10 | 10 |
11 #include <vector> | 11 #include <vector> |
12 | 12 |
13 #include "base/lazy_instance.h" | 13 #include "base/lazy_instance.h" |
14 #include "base/logging.h" | 14 #include "base/logging.h" |
15 #include "content/renderer/webcrypto/crypto_data.h" | 15 #include "content/renderer/webcrypto/crypto_data.h" |
16 #include "content/renderer/webcrypto/webcrypto_util.h" | 16 #include "content/renderer/webcrypto/webcrypto_util.h" |
17 #include "crypto/nss_util.h" | 17 #include "crypto/nss_util.h" |
18 #include "crypto/scoped_nss_types.h" | 18 #include "crypto/scoped_nss_types.h" |
19 #include "third_party/WebKit/public/platform/WebArrayBuffer.h" | 19 #include "third_party/WebKit/public/platform/WebArrayBuffer.h" |
20 #include "third_party/WebKit/public/platform/WebCryptoAlgorithm.h" | 20 #include "third_party/WebKit/public/platform/WebCryptoAlgorithm.h" |
21 #include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h" | 21 #include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h" |
22 #ifdef WEBCRYPTO_HAS_KEY_ALGORITHM | |
23 #include "third_party/WebKit/public/platform/WebCryptoKeyAlgorithm.h" | 22 #include "third_party/WebKit/public/platform/WebCryptoKeyAlgorithm.h" |
24 #endif | |
25 | 23 |
26 #if defined(USE_NSS) | 24 #if defined(USE_NSS) |
27 #include <dlfcn.h> | 25 #include <dlfcn.h> |
28 #endif | 26 #endif |
29 | 27 |
30 // At the time of this writing: | 28 // At the time of this writing: |
31 // * Windows and Mac builds ship with their own copy of NSS (3.15+) | 29 // * Windows and Mac builds ship with their own copy of NSS (3.15+) |
32 // * Linux builds use the system's libnss, which is 3.14 on Debian (but 3.15+ | 30 // * Linux builds use the system's libnss, which is 3.14 on Debian (but 3.15+ |
33 // on other distros). | 31 // on other distros). |
34 // | 32 // |
(...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
363 } | 361 } |
364 | 362 |
365 CK_MECHANISM_TYPE WebCryptoAlgorithmToGenMechanism( | 363 CK_MECHANISM_TYPE WebCryptoAlgorithmToGenMechanism( |
366 const blink::WebCryptoAlgorithm& algorithm) { | 364 const blink::WebCryptoAlgorithm& algorithm) { |
367 switch (algorithm.id()) { | 365 switch (algorithm.id()) { |
368 case blink::WebCryptoAlgorithmIdAesCbc: | 366 case blink::WebCryptoAlgorithmIdAesCbc: |
369 case blink::WebCryptoAlgorithmIdAesGcm: | 367 case blink::WebCryptoAlgorithmIdAesGcm: |
370 case blink::WebCryptoAlgorithmIdAesKw: | 368 case blink::WebCryptoAlgorithmIdAesKw: |
371 return CKM_AES_KEY_GEN; | 369 return CKM_AES_KEY_GEN; |
372 case blink::WebCryptoAlgorithmIdHmac: | 370 case blink::WebCryptoAlgorithmIdHmac: |
373 #ifdef WEBCRYPTO_HAS_KEY_ALGORITHM | |
374 return WebCryptoHashToHMACMechanism(algorithm.hmacKeyGenParams()->hash()); | 371 return WebCryptoHashToHMACMechanism(algorithm.hmacKeyGenParams()->hash()); |
375 #else | |
376 return WebCryptoHashToHMACMechanism(algorithm.hmacKeyParams()->hash()); | |
377 #endif | |
378 default: | 372 default: |
379 return CKM_INVALID_MECHANISM; | 373 return CKM_INVALID_MECHANISM; |
380 } | 374 } |
381 } | 375 } |
382 | 376 |
383 // Converts a (big-endian) WebCrypto BigInteger, with or without leading zeros, | 377 // Converts a (big-endian) WebCrypto BigInteger, with or without leading zeros, |
384 // to unsigned long. | 378 // to unsigned long. |
385 bool BigIntegerToLong(const uint8* data, | 379 bool BigIntegerToLong(const uint8* data, |
386 unsigned int data_size, | 380 unsigned int data_size, |
387 unsigned long* result) { | 381 unsigned long* result) { |
(...skipping 13 matching lines...) Expand all Loading... |
401 } | 395 } |
402 return true; | 396 return true; |
403 } | 397 } |
404 | 398 |
405 bool IsAlgorithmRsa(const blink::WebCryptoAlgorithm& algorithm) { | 399 bool IsAlgorithmRsa(const blink::WebCryptoAlgorithm& algorithm) { |
406 return algorithm.id() == blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5 || | 400 return algorithm.id() == blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5 || |
407 algorithm.id() == blink::WebCryptoAlgorithmIdRsaOaep || | 401 algorithm.id() == blink::WebCryptoAlgorithmIdRsaOaep || |
408 algorithm.id() == blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5; | 402 algorithm.id() == blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5; |
409 } | 403 } |
410 | 404 |
411 #ifdef WEBCRYPTO_HAS_KEY_ALGORITHM | |
412 bool CreatePublicKeyAlgorithm(const blink::WebCryptoAlgorithm& algorithm, | 405 bool CreatePublicKeyAlgorithm(const blink::WebCryptoAlgorithm& algorithm, |
413 SECKEYPublicKey* key, | 406 SECKEYPublicKey* key, |
414 blink::WebCryptoKeyAlgorithm* key_algorithm) { | 407 blink::WebCryptoKeyAlgorithm* key_algorithm) { |
415 // TODO(eroman): What about other key types rsaPss, rsaOaep. | 408 // TODO(eroman): What about other key types rsaPss, rsaOaep. |
416 if (!key || key->keyType != rsaKey) | 409 if (!key || key->keyType != rsaKey) |
417 return false; | 410 return false; |
418 | 411 |
419 unsigned int modulus_length_bits = SECKEY_PublicKeyStrength(key) * 8; | 412 unsigned int modulus_length_bits = SECKEY_PublicKeyStrength(key) * 8; |
420 CryptoData public_exponent(key->u.rsa.publicExponent.data, | 413 CryptoData public_exponent(key->u.rsa.publicExponent.data, |
421 key->u.rsa.publicExponent.len); | 414 key->u.rsa.publicExponent.len); |
(...skipping 22 matching lines...) Expand all Loading... |
444 return false; | 437 return false; |
445 } | 438 } |
446 } | 439 } |
447 | 440 |
448 bool CreatePrivateKeyAlgorithm(const blink::WebCryptoAlgorithm& algorithm, | 441 bool CreatePrivateKeyAlgorithm(const blink::WebCryptoAlgorithm& algorithm, |
449 SECKEYPrivateKey* key, | 442 SECKEYPrivateKey* key, |
450 blink::WebCryptoKeyAlgorithm* key_algorithm) { | 443 blink::WebCryptoKeyAlgorithm* key_algorithm) { |
451 return CreatePublicKeyAlgorithm( | 444 return CreatePublicKeyAlgorithm( |
452 algorithm, SECKEY_ConvertToPublicKey(key), key_algorithm); | 445 algorithm, SECKEY_ConvertToPublicKey(key), key_algorithm); |
453 } | 446 } |
454 #endif | |
455 | 447 |
456 } // namespace | 448 } // namespace |
457 | 449 |
458 Status ImportKeyRaw(const blink::WebCryptoAlgorithm& algorithm, | 450 Status ImportKeyRaw(const blink::WebCryptoAlgorithm& algorithm, |
459 const CryptoData& key_data, | 451 const CryptoData& key_data, |
460 bool extractable, | 452 bool extractable, |
461 blink::WebCryptoKeyUsageMask usage_mask, | 453 blink::WebCryptoKeyUsageMask usage_mask, |
462 blink::WebCryptoKey* key) { | 454 blink::WebCryptoKey* key) { |
463 | 455 |
464 DCHECK(!algorithm.isNull()); | 456 DCHECK(!algorithm.isNull()); |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
513 mechanism, | 505 mechanism, |
514 PK11_OriginUnwrap, | 506 PK11_OriginUnwrap, |
515 CKA_FLAGS_ONLY, | 507 CKA_FLAGS_ONLY, |
516 &key_item, | 508 &key_item, |
517 flags, | 509 flags, |
518 false, | 510 false, |
519 NULL)); | 511 NULL)); |
520 if (!pk11_sym_key.get()) | 512 if (!pk11_sym_key.get()) |
521 return Status::Error(); | 513 return Status::Error(); |
522 | 514 |
523 #ifdef WEBCRYPTO_HAS_KEY_ALGORITHM | |
524 blink::WebCryptoKeyAlgorithm key_algorithm; | 515 blink::WebCryptoKeyAlgorithm key_algorithm; |
525 if (!CreateSecretKeyAlgorithm( | 516 if (!CreateSecretKeyAlgorithm( |
526 algorithm, key_data.byte_length(), &key_algorithm)) | 517 algorithm, key_data.byte_length(), &key_algorithm)) |
527 return Status::ErrorUnexpected(); | 518 return Status::ErrorUnexpected(); |
528 #else | |
529 const blink::WebCryptoAlgorithm& key_algorithm = algorithm; | |
530 #endif | |
531 | 519 |
532 *key = blink::WebCryptoKey::create(new SymKey(pk11_sym_key.Pass()), | 520 *key = blink::WebCryptoKey::create(new SymKey(pk11_sym_key.Pass()), |
533 blink::WebCryptoKeyTypeSecret, | 521 blink::WebCryptoKeyTypeSecret, |
534 extractable, | 522 extractable, |
535 key_algorithm, | 523 key_algorithm, |
536 usage_mask); | 524 usage_mask); |
537 return Status::Success(); | 525 return Status::Success(); |
538 } | 526 } |
539 | 527 |
540 Status ExportKeyRaw(SymKey* key, blink::WebArrayBuffer* buffer) { | 528 Status ExportKeyRaw(SymKey* key, blink::WebArrayBuffer* buffer) { |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
613 SECKEY_ExtractPublicKey(spki.get())); | 601 SECKEY_ExtractPublicKey(spki.get())); |
614 if (!sec_public_key) | 602 if (!sec_public_key) |
615 return Status::Error(); | 603 return Status::Error(); |
616 | 604 |
617 const KeyType sec_key_type = SECKEY_GetPublicKeyType(sec_public_key.get()); | 605 const KeyType sec_key_type = SECKEY_GetPublicKeyType(sec_public_key.get()); |
618 blink::WebCryptoAlgorithm algorithm = | 606 blink::WebCryptoAlgorithm algorithm = |
619 ResolveNssKeyTypeWithInputAlgorithm(sec_key_type, algorithm_or_null); | 607 ResolveNssKeyTypeWithInputAlgorithm(sec_key_type, algorithm_or_null); |
620 if (algorithm.isNull()) | 608 if (algorithm.isNull()) |
621 return Status::Error(); | 609 return Status::Error(); |
622 | 610 |
623 #ifdef WEBCRYPTO_HAS_KEY_ALGORITHM | |
624 blink::WebCryptoKeyAlgorithm key_algorithm; | 611 blink::WebCryptoKeyAlgorithm key_algorithm; |
625 if (!CreatePublicKeyAlgorithm( | 612 if (!CreatePublicKeyAlgorithm( |
626 algorithm, sec_public_key.get(), &key_algorithm)) | 613 algorithm, sec_public_key.get(), &key_algorithm)) |
627 return Status::ErrorUnexpected(); | 614 return Status::ErrorUnexpected(); |
628 #else | |
629 const blink::WebCryptoAlgorithm& key_algorithm = algorithm; | |
630 #endif | |
631 | 615 |
632 *key = blink::WebCryptoKey::create(new PublicKey(sec_public_key.Pass()), | 616 *key = blink::WebCryptoKey::create(new PublicKey(sec_public_key.Pass()), |
633 blink::WebCryptoKeyTypePublic, | 617 blink::WebCryptoKeyTypePublic, |
634 extractable, | 618 extractable, |
635 key_algorithm, | 619 key_algorithm, |
636 usage_mask); | 620 usage_mask); |
637 | 621 |
638 return Status::Success(); | 622 return Status::Success(); |
639 } | 623 } |
640 | 624 |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
683 } | 667 } |
684 DCHECK(seckey_private_key); | 668 DCHECK(seckey_private_key); |
685 crypto::ScopedSECKEYPrivateKey private_key(seckey_private_key); | 669 crypto::ScopedSECKEYPrivateKey private_key(seckey_private_key); |
686 | 670 |
687 const KeyType sec_key_type = SECKEY_GetPrivateKeyType(private_key.get()); | 671 const KeyType sec_key_type = SECKEY_GetPrivateKeyType(private_key.get()); |
688 blink::WebCryptoAlgorithm algorithm = | 672 blink::WebCryptoAlgorithm algorithm = |
689 ResolveNssKeyTypeWithInputAlgorithm(sec_key_type, algorithm_or_null); | 673 ResolveNssKeyTypeWithInputAlgorithm(sec_key_type, algorithm_or_null); |
690 if (algorithm.isNull()) | 674 if (algorithm.isNull()) |
691 return Status::Error(); | 675 return Status::Error(); |
692 | 676 |
693 #ifdef WEBCRYPTO_HAS_KEY_ALGORITHM | |
694 blink::WebCryptoKeyAlgorithm key_algorithm; | 677 blink::WebCryptoKeyAlgorithm key_algorithm; |
695 if (!CreatePrivateKeyAlgorithm(algorithm, private_key.get(), &key_algorithm)) | 678 if (!CreatePrivateKeyAlgorithm(algorithm, private_key.get(), &key_algorithm)) |
696 return Status::ErrorUnexpected(); | 679 return Status::ErrorUnexpected(); |
697 #else | |
698 const blink::WebCryptoAlgorithm& key_algorithm = algorithm; | |
699 #endif | |
700 | 680 |
701 *key = blink::WebCryptoKey::create(new PrivateKey(private_key.Pass()), | 681 *key = blink::WebCryptoKey::create(new PrivateKey(private_key.Pass()), |
702 blink::WebCryptoKeyTypePrivate, | 682 blink::WebCryptoKeyTypePrivate, |
703 extractable, | 683 extractable, |
704 key_algorithm, | 684 key_algorithm, |
705 usage_mask); | 685 usage_mask); |
706 | 686 |
707 return Status::Success(); | 687 return Status::Success(); |
708 } | 688 } |
709 | 689 |
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
963 CKM_RSA_PKCS_KEY_PAIR_GEN, | 943 CKM_RSA_PKCS_KEY_PAIR_GEN, |
964 &rsa_gen_params, | 944 &rsa_gen_params, |
965 &sec_public_key, | 945 &sec_public_key, |
966 attribute_flags, | 946 attribute_flags, |
967 operation_flags, | 947 operation_flags, |
968 operation_flags_mask, | 948 operation_flags_mask, |
969 NULL)); | 949 NULL)); |
970 if (!private_key) | 950 if (!private_key) |
971 return Status::Error(); | 951 return Status::Error(); |
972 | 952 |
973 #ifdef WEBCRYPTO_HAS_KEY_ALGORITHM | |
974 blink::WebCryptoKeyAlgorithm key_algorithm; | 953 blink::WebCryptoKeyAlgorithm key_algorithm; |
975 if (!CreatePublicKeyAlgorithm(algorithm, sec_public_key, &key_algorithm)) | 954 if (!CreatePublicKeyAlgorithm(algorithm, sec_public_key, &key_algorithm)) |
976 return Status::ErrorUnexpected(); | 955 return Status::ErrorUnexpected(); |
977 #else | |
978 const blink::WebCryptoAlgorithm& key_algorithm = algorithm; | |
979 #endif | |
980 | 956 |
981 *public_key = blink::WebCryptoKey::create( | 957 *public_key = blink::WebCryptoKey::create( |
982 new PublicKey(crypto::ScopedSECKEYPublicKey(sec_public_key)), | 958 new PublicKey(crypto::ScopedSECKEYPublicKey(sec_public_key)), |
983 blink::WebCryptoKeyTypePublic, | 959 blink::WebCryptoKeyTypePublic, |
984 true, | 960 true, |
985 key_algorithm, | 961 key_algorithm, |
986 usage_mask); | 962 usage_mask); |
987 *private_key = | 963 *private_key = |
988 blink::WebCryptoKey::create(new PrivateKey(scoped_sec_private_key.Pass()), | 964 blink::WebCryptoKey::create(new PrivateKey(scoped_sec_private_key.Pass()), |
989 blink::WebCryptoKeyTypePrivate, | 965 blink::WebCryptoKeyTypePrivate, |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1042 crypto::ScopedPK11Slot slot(PK11_GetInternalKeySlot()); | 1018 crypto::ScopedPK11Slot slot(PK11_GetInternalKeySlot()); |
1043 if (!slot) | 1019 if (!slot) |
1044 return Status::Error(); | 1020 return Status::Error(); |
1045 | 1021 |
1046 crypto::ScopedPK11SymKey pk11_key( | 1022 crypto::ScopedPK11SymKey pk11_key( |
1047 PK11_KeyGen(slot.get(), mech, NULL, keylen_bytes, NULL)); | 1023 PK11_KeyGen(slot.get(), mech, NULL, keylen_bytes, NULL)); |
1048 | 1024 |
1049 if (!pk11_key) | 1025 if (!pk11_key) |
1050 return Status::Error(); | 1026 return Status::Error(); |
1051 | 1027 |
1052 #ifdef WEBCRYPTO_HAS_KEY_ALGORITHM | |
1053 blink::WebCryptoKeyAlgorithm key_algorithm; | 1028 blink::WebCryptoKeyAlgorithm key_algorithm; |
1054 if (!CreateSecretKeyAlgorithm(algorithm, keylen_bytes, &key_algorithm)) | 1029 if (!CreateSecretKeyAlgorithm(algorithm, keylen_bytes, &key_algorithm)) |
1055 return Status::ErrorUnexpected(); | 1030 return Status::ErrorUnexpected(); |
1056 #else | |
1057 const blink::WebCryptoAlgorithm& key_algorithm = algorithm; | |
1058 #endif | |
1059 | 1031 |
1060 *key = blink::WebCryptoKey::create(new SymKey(pk11_key.Pass()), | 1032 *key = blink::WebCryptoKey::create(new SymKey(pk11_key.Pass()), |
1061 key_type, | 1033 key_type, |
1062 extractable, | 1034 extractable, |
1063 key_algorithm, | 1035 key_algorithm, |
1064 usage_mask); | 1036 usage_mask); |
1065 return Status::Success(); | 1037 return Status::Success(); |
1066 } | 1038 } |
1067 | 1039 |
1068 Status ImportRsaPublicKey(const blink::WebCryptoAlgorithm& algorithm, | 1040 Status ImportRsaPublicKey(const blink::WebCryptoAlgorithm& algorithm, |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1109 SEC_ASN1EncodeItem(NULL, NULL, &pubkey_in, rsa_public_key_template)); | 1081 SEC_ASN1EncodeItem(NULL, NULL, &pubkey_in, rsa_public_key_template)); |
1110 if (!pubkey_der) | 1082 if (!pubkey_der) |
1111 return Status::Error(); | 1083 return Status::Error(); |
1112 | 1084 |
1113 // Import the DER-encoded public key to create an RSA SECKEYPublicKey. | 1085 // Import the DER-encoded public key to create an RSA SECKEYPublicKey. |
1114 crypto::ScopedSECKEYPublicKey pubkey( | 1086 crypto::ScopedSECKEYPublicKey pubkey( |
1115 SECKEY_ImportDERPublicKey(pubkey_der.get(), CKK_RSA)); | 1087 SECKEY_ImportDERPublicKey(pubkey_der.get(), CKK_RSA)); |
1116 if (!pubkey) | 1088 if (!pubkey) |
1117 return Status::Error(); | 1089 return Status::Error(); |
1118 | 1090 |
1119 #ifdef WEBCRYPTO_HAS_KEY_ALGORITHM | |
1120 blink::WebCryptoKeyAlgorithm key_algorithm; | 1091 blink::WebCryptoKeyAlgorithm key_algorithm; |
1121 if (!CreatePublicKeyAlgorithm(algorithm, pubkey.get(), &key_algorithm)) | 1092 if (!CreatePublicKeyAlgorithm(algorithm, pubkey.get(), &key_algorithm)) |
1122 return Status::ErrorUnexpected(); | 1093 return Status::ErrorUnexpected(); |
1123 #else | |
1124 const blink::WebCryptoAlgorithm& key_algorithm = algorithm; | |
1125 #endif | |
1126 | 1094 |
1127 *key = blink::WebCryptoKey::create(new PublicKey(pubkey.Pass()), | 1095 *key = blink::WebCryptoKey::create(new PublicKey(pubkey.Pass()), |
1128 blink::WebCryptoKeyTypePublic, | 1096 blink::WebCryptoKeyTypePublic, |
1129 extractable, | 1097 extractable, |
1130 key_algorithm, | 1098 key_algorithm, |
1131 usage_mask); | 1099 usage_mask); |
1132 return Status::Success(); | 1100 return Status::Success(); |
1133 } | 1101 } |
1134 | 1102 |
1135 } // namespace platform | 1103 } // namespace platform |
1136 | 1104 |
1137 } // namespace webcrypto | 1105 } // namespace webcrypto |
1138 | 1106 |
1139 } // namespace content | 1107 } // namespace content |
OLD | NEW |