 Chromium Code Reviews
 Chromium Code Reviews Issue 178073007:
  [webcrypto] Update to use the KeyAlgorithm.  (Closed) 
  Base URL: svn://svn.chromium.org/chrome/trunk/src
    
  
    Issue 178073007:
  [webcrypto] Update to use the KeyAlgorithm.  (Closed) 
  Base URL: svn://svn.chromium.org/chrome/trunk/src| 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 |