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" | |
24 #endif | |
22 | 25 |
23 #if defined(USE_NSS) | 26 #if defined(USE_NSS) |
24 #include <dlfcn.h> | 27 #include <dlfcn.h> |
25 #endif | 28 #endif |
26 | 29 |
27 // At the time of this writing: | 30 // At the time of this writing: |
28 // * Windows and Mac builds ship with their own copy of NSS (3.15+) | 31 // * Windows and Mac builds ship with their own copy of NSS (3.15+) |
29 // * Linux builds use the system's libnss, which is 3.14 on Debian (but 3.15+ | 32 // * Linux builds use the system's libnss, which is 3.14 on Debian (but 3.15+ |
30 // on other distros). | 33 // on other distros). |
31 // | 34 // |
(...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
360 } | 363 } |
361 | 364 |
362 CK_MECHANISM_TYPE WebCryptoAlgorithmToGenMechanism( | 365 CK_MECHANISM_TYPE WebCryptoAlgorithmToGenMechanism( |
363 const blink::WebCryptoAlgorithm& algorithm) { | 366 const blink::WebCryptoAlgorithm& algorithm) { |
364 switch (algorithm.id()) { | 367 switch (algorithm.id()) { |
365 case blink::WebCryptoAlgorithmIdAesCbc: | 368 case blink::WebCryptoAlgorithmIdAesCbc: |
366 case blink::WebCryptoAlgorithmIdAesGcm: | 369 case blink::WebCryptoAlgorithmIdAesGcm: |
367 case blink::WebCryptoAlgorithmIdAesKw: | 370 case blink::WebCryptoAlgorithmIdAesKw: |
368 return CKM_AES_KEY_GEN; | 371 return CKM_AES_KEY_GEN; |
369 case blink::WebCryptoAlgorithmIdHmac: | 372 case blink::WebCryptoAlgorithmIdHmac: |
373 #ifdef WEBCRYPTO_HAS_KEY_ALGORITHM | |
374 return WebCryptoHashToHMACMechanism(algorithm.hmacKeyGenParams()->hash()); | |
375 #else | |
370 return WebCryptoHashToHMACMechanism(algorithm.hmacKeyParams()->hash()); | 376 return WebCryptoHashToHMACMechanism(algorithm.hmacKeyParams()->hash()); |
377 #endif | |
371 default: | 378 default: |
372 return CKM_INVALID_MECHANISM; | 379 return CKM_INVALID_MECHANISM; |
373 } | 380 } |
374 } | 381 } |
375 | 382 |
376 // Converts a (big-endian) WebCrypto BigInteger, with or without leading zeros, | 383 // Converts a (big-endian) WebCrypto BigInteger, with or without leading zeros, |
377 // to unsigned long. | 384 // to unsigned long. |
378 bool BigIntegerToLong(const uint8* data, | 385 bool BigIntegerToLong(const CryptoData& data, unsigned long* result) { |
379 unsigned int data_size, | 386 if (!data.byte_length()) |
380 unsigned long* result) { | |
381 // TODO(padolph): Is it correct to say that empty data is an error, or does it | |
382 // mean value 0? See https://www.w3.org/Bugs/Public/show_bug.cgi?id=23655 | |
383 if (data_size == 0) | |
384 return false; | 387 return false; |
385 | 388 |
386 *result = 0; | 389 *result = 0; |
387 for (size_t i = 0; i < data_size; ++i) { | 390 for (size_t i = 0; i < data.byte_length(); ++i) { |
388 size_t reverse_i = data_size - i - 1; | 391 size_t reverse_i = data.byte_length() - i - 1; |
389 | 392 |
390 if (reverse_i >= sizeof(unsigned long) && data[i]) | 393 if (reverse_i >= sizeof(unsigned long) && data.bytes()[i]) |
391 return false; // Too large for a long. | 394 return false; // Too large for a long. |
392 | 395 |
393 *result |= data[i] << 8 * reverse_i; | 396 *result |= data.bytes()[i] << 8 * reverse_i; |
394 } | 397 } |
395 return true; | 398 return true; |
396 } | 399 } |
397 | 400 |
398 bool IsAlgorithmRsa(const blink::WebCryptoAlgorithm& algorithm) { | 401 bool IsAlgorithmRsa(const blink::WebCryptoAlgorithm& algorithm) { |
399 return algorithm.id() == blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5 || | 402 return algorithm.id() == blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5 || |
400 algorithm.id() == blink::WebCryptoAlgorithmIdRsaOaep || | 403 algorithm.id() == blink::WebCryptoAlgorithmIdRsaOaep || |
401 algorithm.id() == blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5; | 404 algorithm.id() == blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5; |
402 } | 405 } |
403 | 406 |
407 #ifdef WEBCRYPTO_HAS_KEY_ALGORITHM | |
408 bool CreatePublicKeyAlgorithm(const blink::WebCryptoAlgorithm& algorithm, | |
409 SECKEYPublicKey* key, | |
410 blink::WebCryptoKeyAlgorithm* key_algorithm) { | |
411 if (!key || key->keyType != rsaKey) | |
Ryan Sleevi
2014/02/25 22:26:26
rsaPssKey
rsaOaepKey
eroman
2014/02/25 23:26:47
Added a TODO.
I don't want to add that handling u
| |
412 return false; | |
413 | |
414 unsigned int modulus_length_bits = SECKEY_PublicKeyStrength(key) * 8; | |
415 CryptoData public_exponent(key->u.rsa.publicExponent.data, | |
416 key->u.rsa.publicExponent.len); | |
417 | |
418 if (algorithm.paramsType() == | |
419 blink::WebCryptoAlgorithmParamsTypeRsaHashedImportParams || | |
420 algorithm.paramsType() == | |
421 blink::WebCryptoAlgorithmParamsTypeRsaHashedKeyGenParams) { | |
422 *key_algorithm = blink::WebCryptoKeyAlgorithm::adoptParamsAndCreate( | |
423 algorithm.id(), | |
424 new blink::WebCryptoRsaHashedKeyAlgorithmParams( | |
425 modulus_length_bits, | |
426 public_exponent.bytes(), | |
427 public_exponent.byte_length(), | |
428 GetInnerHashAlgorithm(algorithm))); | |
429 return true; | |
430 } | |
431 | |
432 if (algorithm.paramsType() == | |
433 blink::WebCryptoAlgorithmParamsTypeRsaKeyGenParams || | |
434 algorithm.paramsType() == blink::WebCryptoAlgorithmParamsTypeNone) { | |
Ryan Sleevi
2014/02/25 22:26:26
Does it make sense to make these a set of switch s
eroman
2014/02/25 23:26:47
Yes, that makes more sense.
Done.
Thanks
| |
435 *key_algorithm = blink::WebCryptoKeyAlgorithm::adoptParamsAndCreate( | |
436 algorithm.id(), | |
437 new blink::WebCryptoRsaKeyAlgorithmParams( | |
438 modulus_length_bits, | |
439 public_exponent.bytes(), | |
440 public_exponent.byte_length())); | |
441 return true; | |
442 } | |
443 | |
444 return false; | |
445 } | |
446 | |
447 bool CreatePrivateKeyAlgorithm(const blink::WebCryptoAlgorithm& algorithm, | |
448 SECKEYPrivateKey* key, | |
449 blink::WebCryptoKeyAlgorithm* key_algorithm) { | |
450 return CreatePublicKeyAlgorithm( | |
451 algorithm, SECKEY_ConvertToPublicKey(key), key_algorithm); | |
452 } | |
453 #endif | |
454 | |
404 } // namespace | 455 } // namespace |
405 | 456 |
406 Status ImportKeyRaw(const blink::WebCryptoAlgorithm& algorithm, | 457 Status ImportKeyRaw(const blink::WebCryptoAlgorithm& algorithm, |
407 const CryptoData& key_data, | 458 const CryptoData& key_data, |
408 bool extractable, | 459 bool extractable, |
409 blink::WebCryptoKeyUsageMask usage_mask, | 460 blink::WebCryptoKeyUsageMask usage_mask, |
410 blink::WebCryptoKey* key) { | 461 blink::WebCryptoKey* key) { |
411 | 462 |
412 DCHECK(!algorithm.isNull()); | 463 DCHECK(!algorithm.isNull()); |
413 | 464 |
414 // TODO(bryaneyler): Need to split handling for symmetric and asymmetric keys. | 465 // TODO(bryaneyler): Need to split handling for symmetric and asymmetric keys. |
415 // Currently only supporting symmetric. | 466 // Currently only supporting symmetric. |
416 CK_MECHANISM_TYPE mechanism = CKM_INVALID_MECHANISM; | 467 CK_MECHANISM_TYPE mechanism = CKM_INVALID_MECHANISM; |
417 // Flags are verified at the Blink layer; here the flags are set to all | 468 // Flags are verified at the Blink layer; here the flags are set to all |
418 // possible operations for this key type. | 469 // possible operations for this key type. |
419 CK_FLAGS flags = 0; | 470 CK_FLAGS flags = 0; |
420 | 471 |
421 switch (algorithm.id()) { | 472 switch (algorithm.id()) { |
422 case blink::WebCryptoAlgorithmIdHmac: { | 473 case blink::WebCryptoAlgorithmIdHmac: { |
423 const blink::WebCryptoHmacParams* params = algorithm.hmacParams(); | 474 const blink::WebCryptoAlgorithm& hash = GetInnerHashAlgorithm(algorithm); |
424 if (!params) | |
425 return Status::ErrorUnexpected(); | |
426 | 475 |
427 mechanism = WebCryptoHashToHMACMechanism(params->hash()); | 476 mechanism = WebCryptoHashToHMACMechanism(hash); |
428 if (mechanism == CKM_INVALID_MECHANISM) | 477 if (mechanism == CKM_INVALID_MECHANISM) |
429 return Status::ErrorUnsupported(); | 478 return Status::ErrorUnsupported(); |
430 | 479 |
431 flags |= CKF_SIGN | CKF_VERIFY; | 480 flags |= CKF_SIGN | CKF_VERIFY; |
432 | |
433 break; | 481 break; |
434 } | 482 } |
435 case blink::WebCryptoAlgorithmIdAesCbc: { | 483 case blink::WebCryptoAlgorithmIdAesCbc: { |
436 mechanism = CKM_AES_CBC; | 484 mechanism = CKM_AES_CBC; |
437 flags |= CKF_ENCRYPT | CKF_DECRYPT; | 485 flags |= CKF_ENCRYPT | CKF_DECRYPT; |
438 break; | 486 break; |
439 } | 487 } |
440 case blink::WebCryptoAlgorithmIdAesKw: { | 488 case blink::WebCryptoAlgorithmIdAesKw: { |
441 mechanism = CKM_NSS_AES_KEY_WRAP; | 489 mechanism = CKM_NSS_AES_KEY_WRAP; |
442 flags |= CKF_WRAP | CKF_WRAP; | 490 flags |= CKF_WRAP | CKF_WRAP; |
(...skipping 21 matching lines...) Expand all Loading... | |
464 mechanism, | 512 mechanism, |
465 PK11_OriginUnwrap, | 513 PK11_OriginUnwrap, |
466 CKA_FLAGS_ONLY, | 514 CKA_FLAGS_ONLY, |
467 &key_item, | 515 &key_item, |
468 flags, | 516 flags, |
469 false, | 517 false, |
470 NULL)); | 518 NULL)); |
471 if (!pk11_sym_key.get()) | 519 if (!pk11_sym_key.get()) |
472 return Status::Error(); | 520 return Status::Error(); |
473 | 521 |
522 #ifdef WEBCRYPTO_HAS_KEY_ALGORITHM | |
523 blink::WebCryptoKeyAlgorithm key_algorithm; | |
524 if (!CreateSecretKeyAlgorithm( | |
525 algorithm, key_data.byte_length(), &key_algorithm)) | |
526 return Status::ErrorUnexpected(); | |
527 #else | |
528 const blink::WebCryptoAlgorithm& key_algorithm = algorithm; | |
529 #endif | |
530 | |
474 *key = blink::WebCryptoKey::create(new SymKey(pk11_sym_key.Pass()), | 531 *key = blink::WebCryptoKey::create(new SymKey(pk11_sym_key.Pass()), |
475 blink::WebCryptoKeyTypeSecret, | 532 blink::WebCryptoKeyTypeSecret, |
476 extractable, | 533 extractable, |
477 algorithm, | 534 key_algorithm, |
478 usage_mask); | 535 usage_mask); |
479 return Status::Success(); | 536 return Status::Success(); |
480 } | 537 } |
481 | 538 |
482 Status ExportKeyRaw(SymKey* key, blink::WebArrayBuffer* buffer) { | 539 Status ExportKeyRaw(SymKey* key, blink::WebArrayBuffer* buffer) { |
483 if (PK11_ExtractKeyValue(key->key()) != SECSuccess) | 540 if (PK11_ExtractKeyValue(key->key()) != SECSuccess) |
484 return Status::Error(); | 541 return Status::Error(); |
485 | 542 |
486 const SECItem* key_data = PK11_GetKeyData(key->key()); | 543 const SECItem* key_data = PK11_GetKeyData(key->key()); |
487 if (!key_data) | 544 if (!key_data) |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
526 default: | 583 default: |
527 break; | 584 break; |
528 } | 585 } |
529 return blink::WebCryptoAlgorithm::createNull(); | 586 return blink::WebCryptoAlgorithm::createNull(); |
530 } | 587 } |
531 | 588 |
532 } // namespace | 589 } // namespace |
533 | 590 |
534 Status ImportKeySpki(const blink::WebCryptoAlgorithm& algorithm_or_null, | 591 Status ImportKeySpki(const blink::WebCryptoAlgorithm& algorithm_or_null, |
535 const CryptoData& key_data, | 592 const CryptoData& key_data, |
536 bool extractable, | |
537 blink::WebCryptoKeyUsageMask usage_mask, | 593 blink::WebCryptoKeyUsageMask usage_mask, |
538 blink::WebCryptoKey* key) { | 594 blink::WebCryptoKey* key) { |
539 | 595 |
540 DCHECK(key); | 596 DCHECK(key); |
541 | 597 |
542 if (!key_data.byte_length()) | 598 if (!key_data.byte_length()) |
543 return Status::ErrorImportEmptyKeyData(); | 599 return Status::ErrorImportEmptyKeyData(); |
544 DCHECK(key_data.bytes()); | 600 DCHECK(key_data.bytes()); |
545 | 601 |
546 // The binary blob 'key_data' is expected to be a DER-encoded ASN.1 Subject | 602 // The binary blob 'key_data' is expected to be a DER-encoded ASN.1 Subject |
547 // Public Key Info. Decode this to a CERTSubjectPublicKeyInfo. | 603 // Public Key Info. Decode this to a CERTSubjectPublicKeyInfo. |
548 SECItem spki_item = MakeSECItemForBuffer(key_data); | 604 SECItem spki_item = MakeSECItemForBuffer(key_data); |
549 const ScopedCERTSubjectPublicKeyInfo spki( | 605 const ScopedCERTSubjectPublicKeyInfo spki( |
550 SECKEY_DecodeDERSubjectPublicKeyInfo(&spki_item)); | 606 SECKEY_DecodeDERSubjectPublicKeyInfo(&spki_item)); |
551 if (!spki) | 607 if (!spki) |
552 return Status::Error(); | 608 return Status::Error(); |
553 | 609 |
554 crypto::ScopedSECKEYPublicKey sec_public_key( | 610 crypto::ScopedSECKEYPublicKey sec_public_key( |
555 SECKEY_ExtractPublicKey(spki.get())); | 611 SECKEY_ExtractPublicKey(spki.get())); |
556 if (!sec_public_key) | 612 if (!sec_public_key) |
557 return Status::Error(); | 613 return Status::Error(); |
558 | 614 |
559 const KeyType sec_key_type = SECKEY_GetPublicKeyType(sec_public_key.get()); | 615 const KeyType sec_key_type = SECKEY_GetPublicKeyType(sec_public_key.get()); |
560 blink::WebCryptoAlgorithm algorithm = | 616 blink::WebCryptoAlgorithm algorithm = |
561 ResolveNssKeyTypeWithInputAlgorithm(sec_key_type, algorithm_or_null); | 617 ResolveNssKeyTypeWithInputAlgorithm(sec_key_type, algorithm_or_null); |
562 if (algorithm.isNull()) | 618 if (algorithm.isNull()) |
563 return Status::Error(); | 619 return Status::Error(); |
564 | 620 |
621 #ifdef WEBCRYPTO_HAS_KEY_ALGORITHM | |
622 blink::WebCryptoKeyAlgorithm key_algorithm; | |
623 if (!CreatePublicKeyAlgorithm( | |
624 algorithm, sec_public_key.get(), &key_algorithm)) | |
625 return Status::ErrorUnexpected(); | |
626 #else | |
627 const blink::WebCryptoAlgorithm& key_algorithm = algorithm; | |
628 #endif | |
629 | |
565 *key = blink::WebCryptoKey::create(new PublicKey(sec_public_key.Pass()), | 630 *key = blink::WebCryptoKey::create(new PublicKey(sec_public_key.Pass()), |
566 blink::WebCryptoKeyTypePublic, | 631 blink::WebCryptoKeyTypePublic, |
567 extractable, | 632 true, |
568 algorithm, | 633 key_algorithm, |
569 usage_mask); | 634 usage_mask); |
570 | 635 |
571 return Status::Success(); | 636 return Status::Success(); |
572 } | 637 } |
573 | 638 |
574 Status ExportKeySpki(PublicKey* key, blink::WebArrayBuffer* buffer) { | 639 Status ExportKeySpki(PublicKey* key, blink::WebArrayBuffer* buffer) { |
575 const crypto::ScopedSECItem spki_der( | 640 const crypto::ScopedSECItem spki_der( |
576 SECKEY_EncodeDERSubjectPublicKeyInfo(key->key())); | 641 SECKEY_EncodeDERSubjectPublicKeyInfo(key->key())); |
577 if (!spki_der) | 642 if (!spki_der) |
578 return Status::Error(); | 643 return Status::Error(); |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
616 } | 681 } |
617 DCHECK(seckey_private_key); | 682 DCHECK(seckey_private_key); |
618 crypto::ScopedSECKEYPrivateKey private_key(seckey_private_key); | 683 crypto::ScopedSECKEYPrivateKey private_key(seckey_private_key); |
619 | 684 |
620 const KeyType sec_key_type = SECKEY_GetPrivateKeyType(private_key.get()); | 685 const KeyType sec_key_type = SECKEY_GetPrivateKeyType(private_key.get()); |
621 blink::WebCryptoAlgorithm algorithm = | 686 blink::WebCryptoAlgorithm algorithm = |
622 ResolveNssKeyTypeWithInputAlgorithm(sec_key_type, algorithm_or_null); | 687 ResolveNssKeyTypeWithInputAlgorithm(sec_key_type, algorithm_or_null); |
623 if (algorithm.isNull()) | 688 if (algorithm.isNull()) |
624 return Status::Error(); | 689 return Status::Error(); |
625 | 690 |
691 #ifdef WEBCRYPTO_HAS_KEY_ALGORITHM | |
692 blink::WebCryptoKeyAlgorithm key_algorithm; | |
693 if (!CreatePrivateKeyAlgorithm(algorithm, private_key.get(), &key_algorithm)) | |
694 return Status::ErrorUnexpected(); | |
695 #else | |
696 const blink::WebCryptoAlgorithm& key_algorithm = algorithm; | |
697 #endif | |
698 | |
626 *key = blink::WebCryptoKey::create(new PrivateKey(private_key.Pass()), | 699 *key = blink::WebCryptoKey::create(new PrivateKey(private_key.Pass()), |
627 blink::WebCryptoKeyTypePrivate, | 700 blink::WebCryptoKeyTypePrivate, |
628 extractable, | 701 extractable, |
629 algorithm, | 702 key_algorithm, |
630 usage_mask); | 703 usage_mask); |
631 | 704 |
632 return Status::Success(); | 705 return Status::Success(); |
633 } | 706 } |
634 | 707 |
635 // ----------------------------------- | 708 // ----------------------------------- |
636 // Hmac | 709 // Hmac |
637 // ----------------------------------- | 710 // ----------------------------------- |
638 | 711 |
639 Status SignHmac(SymKey* key, | 712 Status SignHmac(SymKey* key, |
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
833 mode, key, data, iv, additional_data, tag_length_bits, buffer); | 906 mode, key, data, iv, additional_data, tag_length_bits, buffer); |
834 } | 907 } |
835 | 908 |
836 // ----------------------------------- | 909 // ----------------------------------- |
837 // Key generation | 910 // Key generation |
838 // ----------------------------------- | 911 // ----------------------------------- |
839 | 912 |
840 Status GenerateRsaKeyPair(const blink::WebCryptoAlgorithm& algorithm, | 913 Status GenerateRsaKeyPair(const blink::WebCryptoAlgorithm& algorithm, |
841 bool extractable, | 914 bool extractable, |
842 blink::WebCryptoKeyUsageMask usage_mask, | 915 blink::WebCryptoKeyUsageMask usage_mask, |
916 unsigned int modulus_length_bits, | |
917 const CryptoData& public_exponent, | |
918 const blink::WebCryptoAlgorithm& hash_or_null, | |
843 blink::WebCryptoKey* public_key, | 919 blink::WebCryptoKey* public_key, |
844 blink::WebCryptoKey* private_key) { | 920 blink::WebCryptoKey* private_key) { |
845 const blink::WebCryptoRsaKeyGenParams* const params = | |
846 algorithm.rsaKeyGenParams(); | |
847 DCHECK(params); | |
848 | |
849 crypto::ScopedPK11Slot slot(PK11_GetInternalKeySlot()); | 921 crypto::ScopedPK11Slot slot(PK11_GetInternalKeySlot()); |
850 if (!slot) | 922 if (!slot) |
851 return Status::Error(); | 923 return Status::Error(); |
852 | 924 |
853 unsigned long public_exponent; | 925 unsigned long public_exponent_long; |
854 if (!params->modulusLengthBits()) | 926 if (!BigIntegerToLong(public_exponent, &public_exponent_long) || |
855 return Status::ErrorGenerateRsaZeroModulus(); | 927 !public_exponent_long) { |
856 | |
857 if (!BigIntegerToLong(params->publicExponent().data(), | |
858 params->publicExponent().size(), | |
859 &public_exponent) || | |
860 !public_exponent) { | |
861 return Status::ErrorGenerateKeyPublicExponent(); | 928 return Status::ErrorGenerateKeyPublicExponent(); |
862 } | 929 } |
863 | 930 |
864 PK11RSAGenParams rsa_gen_params; | 931 PK11RSAGenParams rsa_gen_params; |
865 rsa_gen_params.keySizeInBits = params->modulusLengthBits(); | 932 rsa_gen_params.keySizeInBits = modulus_length_bits; |
866 rsa_gen_params.pe = public_exponent; | 933 rsa_gen_params.pe = public_exponent_long; |
867 | 934 |
868 // Flags are verified at the Blink layer; here the flags are set to all | 935 // Flags are verified at the Blink layer; here the flags are set to all |
869 // possible operations for the given key type. | 936 // possible operations for the given key type. |
870 CK_FLAGS operation_flags; | 937 CK_FLAGS operation_flags; |
871 switch (algorithm.id()) { | 938 switch (algorithm.id()) { |
872 case blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5: | 939 case blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5: |
873 case blink::WebCryptoAlgorithmIdRsaOaep: | 940 case blink::WebCryptoAlgorithmIdRsaOaep: |
874 operation_flags = CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP; | 941 operation_flags = CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP; |
875 break; | 942 break; |
876 case blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5: | 943 case blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5: |
(...skipping 15 matching lines...) Expand all Loading... | |
892 CKM_RSA_PKCS_KEY_PAIR_GEN, | 959 CKM_RSA_PKCS_KEY_PAIR_GEN, |
893 &rsa_gen_params, | 960 &rsa_gen_params, |
894 &sec_public_key, | 961 &sec_public_key, |
895 attribute_flags, | 962 attribute_flags, |
896 operation_flags, | 963 operation_flags, |
897 operation_flags_mask, | 964 operation_flags_mask, |
898 NULL)); | 965 NULL)); |
899 if (!private_key) | 966 if (!private_key) |
900 return Status::Error(); | 967 return Status::Error(); |
901 | 968 |
969 #ifdef WEBCRYPTO_HAS_KEY_ALGORITHM | |
970 blink::WebCryptoKeyAlgorithm key_algorithm; | |
971 if (!CreatePublicKeyAlgorithm(algorithm, sec_public_key, &key_algorithm)) | |
972 return Status::ErrorUnexpected(); | |
973 #else | |
974 const blink::WebCryptoAlgorithm& key_algorithm = algorithm; | |
975 #endif | |
976 | |
902 *public_key = blink::WebCryptoKey::create( | 977 *public_key = blink::WebCryptoKey::create( |
903 new PublicKey(crypto::ScopedSECKEYPublicKey(sec_public_key)), | 978 new PublicKey(crypto::ScopedSECKEYPublicKey(sec_public_key)), |
904 blink::WebCryptoKeyTypePublic, | 979 blink::WebCryptoKeyTypePublic, |
905 true, | 980 true, |
906 algorithm, | 981 key_algorithm, |
907 usage_mask); | 982 usage_mask); |
908 *private_key = | 983 *private_key = |
909 blink::WebCryptoKey::create(new PrivateKey(scoped_sec_private_key.Pass()), | 984 blink::WebCryptoKey::create(new PrivateKey(scoped_sec_private_key.Pass()), |
910 blink::WebCryptoKeyTypePrivate, | 985 blink::WebCryptoKeyTypePrivate, |
911 extractable, | 986 extractable, |
912 algorithm, | 987 key_algorithm, |
913 usage_mask); | 988 usage_mask); |
914 | 989 |
915 return Status::Success(); | 990 return Status::Success(); |
916 } | 991 } |
917 | 992 |
918 void Init() { crypto::EnsureNSSInit(); } | 993 void Init() { crypto::EnsureNSSInit(); } |
919 | 994 |
920 Status DigestSha(blink::WebCryptoAlgorithmId algorithm, | 995 Status DigestSha(blink::WebCryptoAlgorithmId algorithm, |
921 const CryptoData& data, | 996 const CryptoData& data, |
922 blink::WebArrayBuffer* buffer) { | 997 blink::WebArrayBuffer* buffer) { |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
963 crypto::ScopedPK11Slot slot(PK11_GetInternalKeySlot()); | 1038 crypto::ScopedPK11Slot slot(PK11_GetInternalKeySlot()); |
964 if (!slot) | 1039 if (!slot) |
965 return Status::Error(); | 1040 return Status::Error(); |
966 | 1041 |
967 crypto::ScopedPK11SymKey pk11_key( | 1042 crypto::ScopedPK11SymKey pk11_key( |
968 PK11_KeyGen(slot.get(), mech, NULL, keylen_bytes, NULL)); | 1043 PK11_KeyGen(slot.get(), mech, NULL, keylen_bytes, NULL)); |
969 | 1044 |
970 if (!pk11_key) | 1045 if (!pk11_key) |
971 return Status::Error(); | 1046 return Status::Error(); |
972 | 1047 |
1048 #ifdef WEBCRYPTO_HAS_KEY_ALGORITHM | |
1049 blink::WebCryptoKeyAlgorithm key_algorithm; | |
1050 if (!CreateSecretKeyAlgorithm(algorithm, keylen_bytes, &key_algorithm)) | |
1051 return Status::ErrorUnexpected(); | |
1052 #else | |
1053 const blink::WebCryptoAlgorithm& key_algorithm = algorithm; | |
1054 #endif | |
1055 | |
973 *key = blink::WebCryptoKey::create(new SymKey(pk11_key.Pass()), | 1056 *key = blink::WebCryptoKey::create(new SymKey(pk11_key.Pass()), |
974 key_type, | 1057 key_type, |
975 extractable, | 1058 extractable, |
976 algorithm, | 1059 key_algorithm, |
977 usage_mask); | 1060 usage_mask); |
978 return Status::Success(); | 1061 return Status::Success(); |
979 } | 1062 } |
980 | 1063 |
981 Status ImportRsaPublicKey(const blink::WebCryptoAlgorithm& algorithm, | 1064 Status ImportRsaPublicKey(const blink::WebCryptoAlgorithm& algorithm, |
982 bool extractable, | 1065 bool extractable, |
983 blink::WebCryptoKeyUsageMask usage_mask, | 1066 blink::WebCryptoKeyUsageMask usage_mask, |
984 const CryptoData& modulus_data, | 1067 const CryptoData& modulus_data, |
985 const CryptoData& exponent_data, | 1068 const CryptoData& exponent_data, |
986 blink::WebCryptoKey* key) { | 1069 blink::WebCryptoKey* key) { |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1022 SEC_ASN1EncodeItem(NULL, NULL, &pubkey_in, rsa_public_key_template)); | 1105 SEC_ASN1EncodeItem(NULL, NULL, &pubkey_in, rsa_public_key_template)); |
1023 if (!pubkey_der) | 1106 if (!pubkey_der) |
1024 return Status::Error(); | 1107 return Status::Error(); |
1025 | 1108 |
1026 // Import the DER-encoded public key to create an RSA SECKEYPublicKey. | 1109 // Import the DER-encoded public key to create an RSA SECKEYPublicKey. |
1027 crypto::ScopedSECKEYPublicKey pubkey( | 1110 crypto::ScopedSECKEYPublicKey pubkey( |
1028 SECKEY_ImportDERPublicKey(pubkey_der.get(), CKK_RSA)); | 1111 SECKEY_ImportDERPublicKey(pubkey_der.get(), CKK_RSA)); |
1029 if (!pubkey) | 1112 if (!pubkey) |
1030 return Status::Error(); | 1113 return Status::Error(); |
1031 | 1114 |
1115 #ifdef WEBCRYPTO_HAS_KEY_ALGORITHM | |
1116 blink::WebCryptoKeyAlgorithm key_algorithm; | |
1117 if (!CreatePublicKeyAlgorithm(algorithm, pubkey.get(), &key_algorithm)) | |
1118 return Status::ErrorUnexpected(); | |
1119 #else | |
1120 const blink::WebCryptoAlgorithm& key_algorithm = algorithm; | |
1121 #endif | |
1122 | |
1032 *key = blink::WebCryptoKey::create(new PublicKey(pubkey.Pass()), | 1123 *key = blink::WebCryptoKey::create(new PublicKey(pubkey.Pass()), |
1033 blink::WebCryptoKeyTypePublic, | 1124 blink::WebCryptoKeyTypePublic, |
1034 extractable, | 1125 extractable, |
1035 algorithm, | 1126 key_algorithm, |
1036 usage_mask); | 1127 usage_mask); |
1037 return Status::Success(); | 1128 return Status::Success(); |
1038 } | 1129 } |
1039 | 1130 |
1040 } // namespace platform | 1131 } // namespace platform |
1041 | 1132 |
1042 } // namespace webcrypto | 1133 } // namespace webcrypto |
1043 | 1134 |
1044 } // namespace content | 1135 } // namespace content |
OLD | NEW |