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 |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
50 struct CK_GCM_PARAMS { | 50 struct CK_GCM_PARAMS { |
51 CK_BYTE_PTR pIv; | 51 CK_BYTE_PTR pIv; |
52 CK_ULONG ulIvLen; | 52 CK_ULONG ulIvLen; |
53 CK_BYTE_PTR pAAD; | 53 CK_BYTE_PTR pAAD; |
54 CK_ULONG ulAADLen; | 54 CK_ULONG ulAADLen; |
55 CK_ULONG ulTagBits; | 55 CK_ULONG ulTagBits; |
56 }; | 56 }; |
57 #endif // !defined(CKM_AES_GCM) | 57 #endif // !defined(CKM_AES_GCM) |
58 | 58 |
59 // Signature for PK11_Encrypt and PK11_Decrypt. | 59 // Signature for PK11_Encrypt and PK11_Decrypt. |
60 typedef SECStatus | 60 typedef SECStatus (*PK11_EncryptDecryptFunction)(PK11SymKey*, |
61 (*PK11_EncryptDecryptFunction)( | 61 CK_MECHANISM_TYPE, |
62 PK11SymKey*, CK_MECHANISM_TYPE, SECItem*, | 62 SECItem*, |
63 unsigned char*, unsigned int*, unsigned int, | 63 unsigned char*, |
64 const unsigned char*, unsigned int); | 64 unsigned int*, |
| 65 unsigned int, |
| 66 const unsigned char*, |
| 67 unsigned int); |
65 | 68 |
66 // Singleton to abstract away dynamically loading libnss3.so | 69 // Singleton to abstract away dynamically loading libnss3.so |
67 class AesGcmSupport { | 70 class AesGcmSupport { |
68 public: | 71 public: |
69 bool IsSupported() const { | 72 bool IsSupported() const { return pk11_encrypt_func_ && pk11_decrypt_func_; } |
70 return pk11_encrypt_func_ && pk11_decrypt_func_; | |
71 } | |
72 | 73 |
73 // Returns NULL if unsupported. | 74 // Returns NULL if unsupported. |
74 PK11_EncryptDecryptFunction pk11_encrypt_func() const { | 75 PK11_EncryptDecryptFunction pk11_encrypt_func() const { |
75 return pk11_encrypt_func_; | 76 return pk11_encrypt_func_; |
76 } | 77 } |
77 | 78 |
78 // Returns NULL if unsupported. | 79 // Returns NULL if unsupported. |
79 PK11_EncryptDecryptFunction pk11_decrypt_func() const { | 80 PK11_EncryptDecryptFunction pk11_decrypt_func() const { |
80 return pk11_decrypt_func_; | 81 return pk11_decrypt_func_; |
81 } | 82 } |
82 | 83 |
83 private: | 84 private: |
84 friend struct base::DefaultLazyInstanceTraits<AesGcmSupport>; | 85 friend struct base::DefaultLazyInstanceTraits<AesGcmSupport>; |
85 | 86 |
86 AesGcmSupport() { | 87 AesGcmSupport() { |
87 #if !defined(USE_NSS) | 88 #if !defined(USE_NSS) |
88 // Using a bundled version of NSS that is guaranteed to have this symbol. | 89 // Using a bundled version of NSS that is guaranteed to have this symbol. |
89 pk11_encrypt_func_ = PK11_Encrypt; | 90 pk11_encrypt_func_ = PK11_Encrypt; |
90 pk11_decrypt_func_ = PK11_Decrypt; | 91 pk11_decrypt_func_ = PK11_Decrypt; |
91 #else | 92 #else |
92 // Using system NSS libraries and PCKS #11 modules, which may not have the | 93 // Using system NSS libraries and PCKS #11 modules, which may not have the |
93 // necessary function (PK11_Encrypt) or mechanism support (CKM_AES_GCM). | 94 // necessary function (PK11_Encrypt) or mechanism support (CKM_AES_GCM). |
94 | 95 |
95 // If PK11_Encrypt() was successfully resolved, then NSS will support | 96 // If PK11_Encrypt() was successfully resolved, then NSS will support |
96 // AES-GCM directly. This was introduced in NSS 3.15. | 97 // AES-GCM directly. This was introduced in NSS 3.15. |
97 pk11_encrypt_func_ = | 98 pk11_encrypt_func_ = reinterpret_cast<PK11_EncryptDecryptFunction>( |
98 reinterpret_cast<PK11_EncryptDecryptFunction>( | 99 dlsym(RTLD_DEFAULT, "PK11_Encrypt")); |
99 dlsym(RTLD_DEFAULT, "PK11_Encrypt")); | 100 pk11_decrypt_func_ = reinterpret_cast<PK11_EncryptDecryptFunction>( |
100 pk11_decrypt_func_ = | 101 dlsym(RTLD_DEFAULT, "PK11_Decrypt")); |
101 reinterpret_cast<PK11_EncryptDecryptFunction>( | |
102 dlsym(RTLD_DEFAULT, "PK11_Decrypt")); | |
103 #endif | 102 #endif |
104 } | 103 } |
105 | 104 |
106 PK11_EncryptDecryptFunction pk11_encrypt_func_; | 105 PK11_EncryptDecryptFunction pk11_encrypt_func_; |
107 PK11_EncryptDecryptFunction pk11_decrypt_func_; | 106 PK11_EncryptDecryptFunction pk11_decrypt_func_; |
108 }; | 107 }; |
109 | 108 |
110 base::LazyInstance<AesGcmSupport>::Leaky g_aes_gcm_support = | 109 base::LazyInstance<AesGcmSupport>::Leaky g_aes_gcm_support = |
111 LAZY_INSTANCE_INITIALIZER; | 110 LAZY_INSTANCE_INITIALIZER; |
112 | 111 |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
165 }; | 164 }; |
166 | 165 |
167 namespace { | 166 namespace { |
168 | 167 |
169 // Creates a SECItem for the data in |buffer|. This does NOT make a copy, so | 168 // Creates a SECItem for the data in |buffer|. This does NOT make a copy, so |
170 // |buffer| should outlive the SECItem. | 169 // |buffer| should outlive the SECItem. |
171 SECItem MakeSECItemForBuffer(const CryptoData& buffer) { | 170 SECItem MakeSECItemForBuffer(const CryptoData& buffer) { |
172 SECItem item = { | 171 SECItem item = { |
173 siBuffer, | 172 siBuffer, |
174 // NSS requires non-const data even though it is just for input. | 173 // NSS requires non-const data even though it is just for input. |
175 const_cast<unsigned char*>(buffer.bytes()), | 174 const_cast<unsigned char*>(buffer.bytes()), buffer.byte_length()}; |
176 buffer.byte_length() | |
177 }; | |
178 return item; | 175 return item; |
179 } | 176 } |
180 | 177 |
181 HASH_HashType WebCryptoAlgorithmToNSSHashType( | 178 HASH_HashType WebCryptoAlgorithmToNSSHashType( |
182 blink::WebCryptoAlgorithmId algorithm) { | 179 blink::WebCryptoAlgorithmId algorithm) { |
183 switch (algorithm) { | 180 switch (algorithm) { |
184 case blink::WebCryptoAlgorithmIdSha1: | 181 case blink::WebCryptoAlgorithmIdSha1: |
185 return HASH_AlgSHA1; | 182 return HASH_AlgSHA1; |
186 case blink::WebCryptoAlgorithmIdSha224: | 183 case blink::WebCryptoAlgorithmIdSha224: |
187 return HASH_AlgSHA224; | 184 return HASH_AlgSHA224; |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
279 return Status::Error(); | 276 return Status::Error(); |
280 } | 277 } |
281 | 278 |
282 ShrinkBuffer(buffer, final_output_chunk_len + output_len); | 279 ShrinkBuffer(buffer, final_output_chunk_len + output_len); |
283 return Status::Success(); | 280 return Status::Success(); |
284 } | 281 } |
285 | 282 |
286 // Helper to either encrypt or decrypt for AES-GCM. The result of encryption is | 283 // Helper to either encrypt or decrypt for AES-GCM. The result of encryption is |
287 // the concatenation of the ciphertext and the authentication tag. Similarly, | 284 // the concatenation of the ciphertext and the authentication tag. Similarly, |
288 // this is the expectation for the input to decryption. | 285 // this is the expectation for the input to decryption. |
289 Status AesGcmEncryptDecrypt( | 286 Status AesGcmEncryptDecrypt(EncryptOrDecrypt mode, |
290 EncryptOrDecrypt mode, | 287 SymKey* key, |
291 SymKey* key, | 288 const CryptoData& data, |
292 const CryptoData& data, | 289 const CryptoData& iv, |
293 const CryptoData& iv, | 290 const CryptoData& additional_data, |
294 const CryptoData& additional_data, | 291 unsigned int tag_length_bits, |
295 unsigned int tag_length_bits, | 292 blink::WebArrayBuffer* buffer) { |
296 blink::WebArrayBuffer* buffer) { | |
297 if (!g_aes_gcm_support.Get().IsSupported()) | 293 if (!g_aes_gcm_support.Get().IsSupported()) |
298 return Status::ErrorUnsupported(); | 294 return Status::ErrorUnsupported(); |
299 | 295 |
300 // TODO(eroman): Is this necessary? | 296 // TODO(eroman): Is this necessary? |
301 if ((tag_length_bits % 8) != 0) | 297 if ((tag_length_bits % 8) != 0) |
302 return Status::ErrorInvalidAesGcmTagLength(); | 298 return Status::ErrorInvalidAesGcmTagLength(); |
303 unsigned int tag_length_bytes = tag_length_bits / 8; | 299 unsigned int tag_length_bytes = tag_length_bits / 8; |
304 | 300 |
305 CK_GCM_PARAMS gcm_params = {0}; | 301 CK_GCM_PARAMS gcm_params = {0}; |
306 gcm_params.pIv = const_cast<unsigned char*>(iv.bytes()); | 302 gcm_params.pIv = const_cast<unsigned char*>(iv.bytes()); |
(...skipping 29 matching lines...) Expand all Loading... |
336 // From the analysis of that bug it looks like it might be safe to pass a | 332 // From the analysis of that bug it looks like it might be safe to pass a |
337 // correctly sized buffer but lie about its size. Since resizing the | 333 // correctly sized buffer but lie about its size. Since resizing the |
338 // WebCryptoArrayBuffer is expensive that hack may be worth looking into. | 334 // WebCryptoArrayBuffer is expensive that hack may be worth looking into. |
339 buffer_size = data.byte_length(); | 335 buffer_size = data.byte_length(); |
340 } | 336 } |
341 | 337 |
342 *buffer = blink::WebArrayBuffer::create(buffer_size, 1); | 338 *buffer = blink::WebArrayBuffer::create(buffer_size, 1); |
343 unsigned char* buffer_data = reinterpret_cast<unsigned char*>(buffer->data()); | 339 unsigned char* buffer_data = reinterpret_cast<unsigned char*>(buffer->data()); |
344 | 340 |
345 PK11_EncryptDecryptFunction func = | 341 PK11_EncryptDecryptFunction func = |
346 (mode == ENCRYPT) ? g_aes_gcm_support.Get().pk11_encrypt_func() : | 342 (mode == ENCRYPT) ? g_aes_gcm_support.Get().pk11_encrypt_func() |
347 g_aes_gcm_support.Get().pk11_decrypt_func(); | 343 : g_aes_gcm_support.Get().pk11_decrypt_func(); |
348 | 344 |
349 unsigned int output_len = 0; | 345 unsigned int output_len = 0; |
350 SECStatus result = func(key->key(), CKM_AES_GCM, ¶m, | 346 SECStatus result = func(key->key(), |
351 buffer_data, &output_len, buffer->byteLength(), | 347 CKM_AES_GCM, |
352 data.bytes(), data.byte_length()); | 348 ¶m, |
| 349 buffer_data, |
| 350 &output_len, |
| 351 buffer->byteLength(), |
| 352 data.bytes(), |
| 353 data.byte_length()); |
353 | 354 |
354 if (result != SECSuccess) | 355 if (result != SECSuccess) |
355 return Status::Error(); | 356 return Status::Error(); |
356 | 357 |
357 // Unfortunately the buffer needs to be shrunk for decryption (see the NSS bug | 358 // Unfortunately the buffer needs to be shrunk for decryption (see the NSS bug |
358 // above). | 359 // above). |
359 ShrinkBuffer(buffer, output_len); | 360 ShrinkBuffer(buffer, output_len); |
360 | 361 |
361 return Status::Success(); | 362 return Status::Success(); |
362 } | 363 } |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
398 } | 399 } |
399 | 400 |
400 bool IsAlgorithmRsa(const blink::WebCryptoAlgorithm& algorithm) { | 401 bool IsAlgorithmRsa(const blink::WebCryptoAlgorithm& algorithm) { |
401 return algorithm.id() == blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5 || | 402 return algorithm.id() == blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5 || |
402 algorithm.id() == blink::WebCryptoAlgorithmIdRsaOaep || | 403 algorithm.id() == blink::WebCryptoAlgorithmIdRsaOaep || |
403 algorithm.id() == blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5; | 404 algorithm.id() == blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5; |
404 } | 405 } |
405 | 406 |
406 } // namespace | 407 } // namespace |
407 | 408 |
408 Status ImportKeyRaw( | 409 Status ImportKeyRaw(const blink::WebCryptoAlgorithm& algorithm, |
409 const blink::WebCryptoAlgorithm& algorithm, | 410 const CryptoData& key_data, |
410 const CryptoData& key_data, | 411 bool extractable, |
411 bool extractable, | 412 blink::WebCryptoKeyUsageMask usage_mask, |
412 blink::WebCryptoKeyUsageMask usage_mask, | 413 blink::WebCryptoKey* key) { |
413 blink::WebCryptoKey* key) { | |
414 | 414 |
415 DCHECK(!algorithm.isNull()); | 415 DCHECK(!algorithm.isNull()); |
416 | 416 |
417 // TODO(bryaneyler): Need to split handling for symmetric and asymmetric keys. | 417 // TODO(bryaneyler): Need to split handling for symmetric and asymmetric keys. |
418 // Currently only supporting symmetric. | 418 // Currently only supporting symmetric. |
419 CK_MECHANISM_TYPE mechanism = CKM_INVALID_MECHANISM; | 419 CK_MECHANISM_TYPE mechanism = CKM_INVALID_MECHANISM; |
420 // Flags are verified at the Blink layer; here the flags are set to all | 420 // Flags are verified at the Blink layer; here the flags are set to all |
421 // possible operations for this key type. | 421 // possible operations for this key type. |
422 CK_FLAGS flags = 0; | 422 CK_FLAGS flags = 0; |
423 | 423 |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
475 return Status::Error(); | 475 return Status::Error(); |
476 | 476 |
477 *key = blink::WebCryptoKey::create(new SymKey(pk11_sym_key.Pass()), | 477 *key = blink::WebCryptoKey::create(new SymKey(pk11_sym_key.Pass()), |
478 blink::WebCryptoKeyTypeSecret, | 478 blink::WebCryptoKeyTypeSecret, |
479 extractable, | 479 extractable, |
480 algorithm, | 480 algorithm, |
481 usage_mask); | 481 usage_mask); |
482 return Status::Success(); | 482 return Status::Success(); |
483 } | 483 } |
484 | 484 |
485 Status ExportKeyRaw( | 485 Status ExportKeyRaw(SymKey* key, blink::WebArrayBuffer* buffer) { |
486 SymKey* key, | |
487 blink::WebArrayBuffer* buffer) { | |
488 if (PK11_ExtractKeyValue(key->key()) != SECSuccess) | 486 if (PK11_ExtractKeyValue(key->key()) != SECSuccess) |
489 return Status::Error(); | 487 return Status::Error(); |
490 | 488 |
491 const SECItem* key_data = PK11_GetKeyData(key->key()); | 489 const SECItem* key_data = PK11_GetKeyData(key->key()); |
492 if (!key_data) | 490 if (!key_data) |
493 return Status::Error(); | 491 return Status::Error(); |
494 | 492 |
495 *buffer = CreateArrayBuffer(key_data->data, key_data->len); | 493 *buffer = CreateArrayBuffer(key_data->data, key_data->len); |
496 | 494 |
497 return Status::Success(); | 495 return Status::Success(); |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
529 // TODO(padolph): Handle other key types. | 527 // TODO(padolph): Handle other key types. |
530 break; | 528 break; |
531 default: | 529 default: |
532 break; | 530 break; |
533 } | 531 } |
534 return blink::WebCryptoAlgorithm::createNull(); | 532 return blink::WebCryptoAlgorithm::createNull(); |
535 } | 533 } |
536 | 534 |
537 } // namespace | 535 } // namespace |
538 | 536 |
539 Status ImportKeySpki( | 537 Status ImportKeySpki(const blink::WebCryptoAlgorithm& algorithm_or_null, |
540 const blink::WebCryptoAlgorithm& algorithm_or_null, | 538 const CryptoData& key_data, |
541 const CryptoData& key_data, | 539 bool extractable, |
542 bool extractable, | 540 blink::WebCryptoKeyUsageMask usage_mask, |
543 blink::WebCryptoKeyUsageMask usage_mask, | 541 blink::WebCryptoKey* key) { |
544 blink::WebCryptoKey* key) { | |
545 | 542 |
546 DCHECK(key); | 543 DCHECK(key); |
547 | 544 |
548 if (!key_data.byte_length()) | 545 if (!key_data.byte_length()) |
549 return Status::ErrorImportEmptyKeyData(); | 546 return Status::ErrorImportEmptyKeyData(); |
550 DCHECK(key_data.bytes()); | 547 DCHECK(key_data.bytes()); |
551 | 548 |
552 // The binary blob 'key_data' is expected to be a DER-encoded ASN.1 Subject | 549 // The binary blob 'key_data' is expected to be a DER-encoded ASN.1 Subject |
553 // Public Key Info. Decode this to a CERTSubjectPublicKeyInfo. | 550 // Public Key Info. Decode this to a CERTSubjectPublicKeyInfo. |
554 SECItem spki_item = MakeSECItemForBuffer(key_data); | 551 SECItem spki_item = MakeSECItemForBuffer(key_data); |
555 const ScopedCERTSubjectPublicKeyInfo spki( | 552 const ScopedCERTSubjectPublicKeyInfo spki( |
556 SECKEY_DecodeDERSubjectPublicKeyInfo(&spki_item)); | 553 SECKEY_DecodeDERSubjectPublicKeyInfo(&spki_item)); |
557 if (!spki) | 554 if (!spki) |
558 return Status::Error(); | 555 return Status::Error(); |
559 | 556 |
560 crypto::ScopedSECKEYPublicKey sec_public_key( | 557 crypto::ScopedSECKEYPublicKey sec_public_key( |
561 SECKEY_ExtractPublicKey(spki.get())); | 558 SECKEY_ExtractPublicKey(spki.get())); |
562 if (!sec_public_key) | 559 if (!sec_public_key) |
563 return Status::Error(); | 560 return Status::Error(); |
564 | 561 |
565 const KeyType sec_key_type = SECKEY_GetPublicKeyType(sec_public_key.get()); | 562 const KeyType sec_key_type = SECKEY_GetPublicKeyType(sec_public_key.get()); |
566 blink::WebCryptoAlgorithm algorithm = | 563 blink::WebCryptoAlgorithm algorithm = |
567 ResolveNssKeyTypeWithInputAlgorithm(sec_key_type, algorithm_or_null); | 564 ResolveNssKeyTypeWithInputAlgorithm(sec_key_type, algorithm_or_null); |
568 if (algorithm.isNull()) | 565 if (algorithm.isNull()) |
569 return Status::Error(); | 566 return Status::Error(); |
570 | 567 |
571 *key = blink::WebCryptoKey::create( | 568 *key = blink::WebCryptoKey::create(new PublicKey(sec_public_key.Pass()), |
572 new PublicKey(sec_public_key.Pass()), | 569 blink::WebCryptoKeyTypePublic, |
573 blink::WebCryptoKeyTypePublic, | 570 extractable, |
574 extractable, | 571 algorithm, |
575 algorithm, | 572 usage_mask); |
576 usage_mask); | |
577 | 573 |
578 return Status::Success(); | 574 return Status::Success(); |
579 } | 575 } |
580 | 576 |
581 Status ExportKeySpki( | 577 Status ExportKeySpki(PublicKey* key, blink::WebArrayBuffer* buffer) { |
582 PublicKey* key, | |
583 blink::WebArrayBuffer* buffer) { | |
584 const crypto::ScopedSECItem spki_der( | 578 const crypto::ScopedSECItem spki_der( |
585 SECKEY_EncodeDERSubjectPublicKeyInfo(key->key())); | 579 SECKEY_EncodeDERSubjectPublicKeyInfo(key->key())); |
586 if (!spki_der) | 580 if (!spki_der) |
587 return Status::Error(); | 581 return Status::Error(); |
588 | 582 |
589 DCHECK(spki_der->data); | 583 DCHECK(spki_der->data); |
590 DCHECK(spki_der->len); | 584 DCHECK(spki_der->len); |
591 | 585 |
592 *buffer = CreateArrayBuffer(spki_der->data, spki_der->len); | 586 *buffer = CreateArrayBuffer(spki_der->data, spki_der->len); |
593 | 587 |
594 return Status::Success(); | 588 return Status::Success(); |
595 } | 589 } |
596 | 590 |
597 Status ImportKeyPkcs8( | 591 Status ImportKeyPkcs8(const blink::WebCryptoAlgorithm& algorithm_or_null, |
598 const blink::WebCryptoAlgorithm& algorithm_or_null, | 592 const CryptoData& key_data, |
599 const CryptoData& key_data, | 593 bool extractable, |
600 bool extractable, | 594 blink::WebCryptoKeyUsageMask usage_mask, |
601 blink::WebCryptoKeyUsageMask usage_mask, | 595 blink::WebCryptoKey* key) { |
602 blink::WebCryptoKey* key) { | |
603 | 596 |
604 DCHECK(key); | 597 DCHECK(key); |
605 | 598 |
606 if (!key_data.byte_length()) | 599 if (!key_data.byte_length()) |
607 return Status::ErrorImportEmptyKeyData(); | 600 return Status::ErrorImportEmptyKeyData(); |
608 DCHECK(key_data.bytes()); | 601 DCHECK(key_data.bytes()); |
609 | 602 |
610 // The binary blob 'key_data' is expected to be a DER-encoded ASN.1 PKCS#8 | 603 // The binary blob 'key_data' is expected to be a DER-encoded ASN.1 PKCS#8 |
611 // private key info object. | 604 // private key info object. |
612 SECItem pki_der = MakeSECItemForBuffer(key_data); | 605 SECItem pki_der = MakeSECItemForBuffer(key_data); |
613 | 606 |
614 SECKEYPrivateKey* seckey_private_key = NULL; | 607 SECKEYPrivateKey* seckey_private_key = NULL; |
615 crypto::ScopedPK11Slot slot(PK11_GetInternalSlot()); | 608 crypto::ScopedPK11Slot slot(PK11_GetInternalSlot()); |
616 if (PK11_ImportDERPrivateKeyInfoAndReturnKey( | 609 if (PK11_ImportDERPrivateKeyInfoAndReturnKey(slot.get(), |
617 slot.get(), | 610 &pki_der, |
618 &pki_der, | 611 NULL, // nickname |
619 NULL, // nickname | 612 NULL, // publicValue |
620 NULL, // publicValue | 613 false, // isPerm |
621 false, // isPerm | 614 false, // isPrivate |
622 false, // isPrivate | 615 KU_ALL, // usage |
623 KU_ALL, // usage | 616 &seckey_private_key, |
624 &seckey_private_key, | 617 NULL) != SECSuccess) { |
625 NULL) != SECSuccess) { | |
626 return Status::Error(); | 618 return Status::Error(); |
627 } | 619 } |
628 DCHECK(seckey_private_key); | 620 DCHECK(seckey_private_key); |
629 crypto::ScopedSECKEYPrivateKey private_key(seckey_private_key); | 621 crypto::ScopedSECKEYPrivateKey private_key(seckey_private_key); |
630 | 622 |
631 const KeyType sec_key_type = SECKEY_GetPrivateKeyType(private_key.get()); | 623 const KeyType sec_key_type = SECKEY_GetPrivateKeyType(private_key.get()); |
632 blink::WebCryptoAlgorithm algorithm = | 624 blink::WebCryptoAlgorithm algorithm = |
633 ResolveNssKeyTypeWithInputAlgorithm(sec_key_type, algorithm_or_null); | 625 ResolveNssKeyTypeWithInputAlgorithm(sec_key_type, algorithm_or_null); |
634 if (algorithm.isNull()) | 626 if (algorithm.isNull()) |
635 return Status::Error(); | 627 return Status::Error(); |
636 | 628 |
637 *key = blink::WebCryptoKey::create( | 629 *key = blink::WebCryptoKey::create(new PrivateKey(private_key.Pass()), |
638 new PrivateKey(private_key.Pass()), | 630 blink::WebCryptoKeyTypePrivate, |
639 blink::WebCryptoKeyTypePrivate, | 631 extractable, |
640 extractable, | 632 algorithm, |
641 algorithm, | 633 usage_mask); |
642 usage_mask); | |
643 | 634 |
644 return Status::Success(); | 635 return Status::Success(); |
645 } | 636 } |
646 | 637 |
647 // ----------------------------------- | 638 // ----------------------------------- |
648 // Hmac | 639 // Hmac |
649 // ----------------------------------- | 640 // ----------------------------------- |
650 | 641 |
651 Status SignHmac( | 642 Status SignHmac(SymKey* key, |
652 SymKey* key, | 643 const blink::WebCryptoAlgorithm& hash, |
653 const blink::WebCryptoAlgorithm& hash, | 644 const CryptoData& data, |
654 const CryptoData& data, | 645 blink::WebArrayBuffer* buffer) { |
655 blink::WebArrayBuffer* buffer) { | |
656 DCHECK_EQ(PK11_GetMechanism(key->key()), WebCryptoHashToHMACMechanism(hash)); | 646 DCHECK_EQ(PK11_GetMechanism(key->key()), WebCryptoHashToHMACMechanism(hash)); |
657 | 647 |
658 SECItem param_item = { siBuffer, NULL, 0 }; | 648 SECItem param_item = {siBuffer, NULL, 0}; |
659 SECItem data_item = MakeSECItemForBuffer(data); | 649 SECItem data_item = MakeSECItemForBuffer(data); |
660 // First call is to figure out the length. | 650 // First call is to figure out the length. |
661 SECItem signature_item = { siBuffer, NULL, 0 }; | 651 SECItem signature_item = {siBuffer, NULL, 0}; |
662 | 652 |
663 if (PK11_SignWithSymKey(key->key(), | 653 if (PK11_SignWithSymKey(key->key(), |
664 PK11_GetMechanism(key->key()), | 654 PK11_GetMechanism(key->key()), |
665 ¶m_item, | 655 ¶m_item, |
666 &signature_item, | 656 &signature_item, |
667 &data_item) != SECSuccess) { | 657 &data_item) != SECSuccess) { |
668 return Status::Error(); | 658 return Status::Error(); |
669 } | 659 } |
670 | 660 |
671 DCHECK_NE(0u, signature_item.len); | 661 DCHECK_NE(0u, signature_item.len); |
(...skipping 10 matching lines...) Expand all Loading... |
682 } | 672 } |
683 | 673 |
684 DCHECK_EQ(buffer->byteLength(), signature_item.len); | 674 DCHECK_EQ(buffer->byteLength(), signature_item.len); |
685 return Status::Success(); | 675 return Status::Success(); |
686 } | 676 } |
687 | 677 |
688 // ----------------------------------- | 678 // ----------------------------------- |
689 // RsaEsPkcs1v1_5 | 679 // RsaEsPkcs1v1_5 |
690 // ----------------------------------- | 680 // ----------------------------------- |
691 | 681 |
692 Status EncryptRsaEsPkcs1v1_5( | 682 Status EncryptRsaEsPkcs1v1_5(PublicKey* key, |
693 PublicKey* key, | 683 const CryptoData& data, |
694 const CryptoData& data, | 684 blink::WebArrayBuffer* buffer) { |
695 blink::WebArrayBuffer* buffer) { | |
696 const unsigned int encrypted_length_bytes = | 685 const unsigned int encrypted_length_bytes = |
697 SECKEY_PublicKeyStrength(key->key()); | 686 SECKEY_PublicKeyStrength(key->key()); |
698 | 687 |
699 // RSAES can operate on messages up to a length of k - 11, where k is the | 688 // RSAES can operate on messages up to a length of k - 11, where k is the |
700 // octet length of the RSA modulus. | 689 // octet length of the RSA modulus. |
701 if (encrypted_length_bytes < 11 || | 690 if (encrypted_length_bytes < 11 || |
702 encrypted_length_bytes - 11 < data.byte_length()) | 691 encrypted_length_bytes - 11 < data.byte_length()) |
703 return Status::ErrorDataTooLarge(); | 692 return Status::ErrorDataTooLarge(); |
704 | 693 |
705 *buffer = blink::WebArrayBuffer::create(encrypted_length_bytes, 1); | 694 *buffer = blink::WebArrayBuffer::create(encrypted_length_bytes, 1); |
706 unsigned char* const buffer_data = | 695 unsigned char* const buffer_data = |
707 reinterpret_cast<unsigned char*>(buffer->data()); | 696 reinterpret_cast<unsigned char*>(buffer->data()); |
708 | 697 |
709 if (PK11_PubEncryptPKCS1(key->key(), | 698 if (PK11_PubEncryptPKCS1(key->key(), |
710 buffer_data, | 699 buffer_data, |
711 const_cast<unsigned char*>(data.bytes()), | 700 const_cast<unsigned char*>(data.bytes()), |
712 data.byte_length(), | 701 data.byte_length(), |
713 NULL) != SECSuccess) { | 702 NULL) != SECSuccess) { |
714 return Status::Error(); | 703 return Status::Error(); |
715 } | 704 } |
716 return Status::Success(); | 705 return Status::Success(); |
717 } | 706 } |
718 | 707 |
719 Status DecryptRsaEsPkcs1v1_5( | 708 Status DecryptRsaEsPkcs1v1_5(PrivateKey* key, |
720 PrivateKey* key, | 709 const CryptoData& data, |
721 const CryptoData& data, | 710 blink::WebArrayBuffer* buffer) { |
722 blink::WebArrayBuffer* buffer) { | |
723 const int modulus_length_bytes = PK11_GetPrivateModulusLen(key->key()); | 711 const int modulus_length_bytes = PK11_GetPrivateModulusLen(key->key()); |
724 if (modulus_length_bytes <= 0) | 712 if (modulus_length_bytes <= 0) |
725 return Status::ErrorUnexpected(); | 713 return Status::ErrorUnexpected(); |
726 const unsigned int max_output_length_bytes = modulus_length_bytes; | 714 const unsigned int max_output_length_bytes = modulus_length_bytes; |
727 | 715 |
728 *buffer = blink::WebArrayBuffer::create(max_output_length_bytes, 1); | 716 *buffer = blink::WebArrayBuffer::create(max_output_length_bytes, 1); |
729 unsigned char* const buffer_data = | 717 unsigned char* const buffer_data = |
730 reinterpret_cast<unsigned char*>(buffer->data()); | 718 reinterpret_cast<unsigned char*>(buffer->data()); |
731 | 719 |
732 unsigned int output_length_bytes = 0; | 720 unsigned int output_length_bytes = 0; |
733 if (PK11_PrivDecryptPKCS1(key->key(), | 721 if (PK11_PrivDecryptPKCS1(key->key(), |
734 buffer_data, | 722 buffer_data, |
735 &output_length_bytes, | 723 &output_length_bytes, |
736 max_output_length_bytes, | 724 max_output_length_bytes, |
737 const_cast<unsigned char*>(data.bytes()), | 725 const_cast<unsigned char*>(data.bytes()), |
738 data.byte_length()) != SECSuccess) { | 726 data.byte_length()) != SECSuccess) { |
739 return Status::Error(); | 727 return Status::Error(); |
740 } | 728 } |
741 DCHECK_LE(output_length_bytes, max_output_length_bytes); | 729 DCHECK_LE(output_length_bytes, max_output_length_bytes); |
742 ShrinkBuffer(buffer, output_length_bytes); | 730 ShrinkBuffer(buffer, output_length_bytes); |
743 return Status::Success(); | 731 return Status::Success(); |
744 } | 732 } |
745 | 733 |
746 // ----------------------------------- | 734 // ----------------------------------- |
747 // RsaSsaPkcs1v1_5 | 735 // RsaSsaPkcs1v1_5 |
748 // ----------------------------------- | 736 // ----------------------------------- |
749 | 737 |
750 Status SignRsaSsaPkcs1v1_5( | 738 Status SignRsaSsaPkcs1v1_5(PrivateKey* key, |
751 PrivateKey* key, | 739 const blink::WebCryptoAlgorithm& hash, |
752 const blink::WebCryptoAlgorithm& hash, | 740 const CryptoData& data, |
753 const CryptoData& data, | 741 blink::WebArrayBuffer* buffer) { |
754 blink::WebArrayBuffer* buffer) { | |
755 // Pick the NSS signing algorithm by combining RSA-SSA (RSA PKCS1) and the | 742 // Pick the NSS signing algorithm by combining RSA-SSA (RSA PKCS1) and the |
756 // inner hash of the input Web Crypto algorithm. | 743 // inner hash of the input Web Crypto algorithm. |
757 SECOidTag sign_alg_tag; | 744 SECOidTag sign_alg_tag; |
758 switch (hash.id()) { | 745 switch (hash.id()) { |
759 case blink::WebCryptoAlgorithmIdSha1: | 746 case blink::WebCryptoAlgorithmIdSha1: |
760 sign_alg_tag = SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION; | 747 sign_alg_tag = SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION; |
761 break; | 748 break; |
762 case blink::WebCryptoAlgorithmIdSha224: | 749 case blink::WebCryptoAlgorithmIdSha224: |
763 sign_alg_tag = SEC_OID_PKCS1_SHA224_WITH_RSA_ENCRYPTION; | 750 sign_alg_tag = SEC_OID_PKCS1_SHA224_WITH_RSA_ENCRYPTION; |
764 break; | 751 break; |
(...skipping 16 matching lines...) Expand all Loading... |
781 data.byte_length(), | 768 data.byte_length(), |
782 key->key(), | 769 key->key(), |
783 sign_alg_tag) != SECSuccess) { | 770 sign_alg_tag) != SECSuccess) { |
784 return Status::Error(); | 771 return Status::Error(); |
785 } | 772 } |
786 | 773 |
787 *buffer = CreateArrayBuffer(signature_item->data, signature_item->len); | 774 *buffer = CreateArrayBuffer(signature_item->data, signature_item->len); |
788 return Status::Success(); | 775 return Status::Success(); |
789 } | 776 } |
790 | 777 |
791 Status VerifyRsaSsaPkcs1v1_5( | 778 Status VerifyRsaSsaPkcs1v1_5(PublicKey* key, |
792 PublicKey* key, | 779 const blink::WebCryptoAlgorithm& hash, |
793 const blink::WebCryptoAlgorithm& hash, | 780 const CryptoData& signature, |
794 const CryptoData& signature, | 781 const CryptoData& data, |
795 const CryptoData& data, | 782 bool* signature_match) { |
796 bool* signature_match) { | |
797 const SECItem signature_item = MakeSECItemForBuffer(signature); | 783 const SECItem signature_item = MakeSECItemForBuffer(signature); |
798 | 784 |
799 SECOidTag hash_alg_tag; | 785 SECOidTag hash_alg_tag; |
800 switch (hash.id()) { | 786 switch (hash.id()) { |
801 case blink::WebCryptoAlgorithmIdSha1: | 787 case blink::WebCryptoAlgorithmIdSha1: |
802 hash_alg_tag = SEC_OID_SHA1; | 788 hash_alg_tag = SEC_OID_SHA1; |
803 break; | 789 break; |
804 case blink::WebCryptoAlgorithmIdSha224: | 790 case blink::WebCryptoAlgorithmIdSha224: |
805 hash_alg_tag = SEC_OID_SHA224; | 791 hash_alg_tag = SEC_OID_SHA224; |
806 break; | 792 break; |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
847 blink::WebArrayBuffer* buffer) { | 833 blink::WebArrayBuffer* buffer) { |
848 // TODO(eroman): Inline. | 834 // TODO(eroman): Inline. |
849 return AesGcmEncryptDecrypt( | 835 return AesGcmEncryptDecrypt( |
850 mode, key, data, iv, additional_data, tag_length_bits, buffer); | 836 mode, key, data, iv, additional_data, tag_length_bits, buffer); |
851 } | 837 } |
852 | 838 |
853 // ----------------------------------- | 839 // ----------------------------------- |
854 // Key generation | 840 // Key generation |
855 // ----------------------------------- | 841 // ----------------------------------- |
856 | 842 |
857 Status GenerateRsaKeyPair( | 843 Status GenerateRsaKeyPair(const blink::WebCryptoAlgorithm& algorithm, |
858 const blink::WebCryptoAlgorithm& algorithm, | 844 bool extractable, |
859 bool extractable, | 845 blink::WebCryptoKeyUsageMask usage_mask, |
860 blink::WebCryptoKeyUsageMask usage_mask, | 846 blink::WebCryptoKey* public_key, |
861 blink::WebCryptoKey* public_key, | 847 blink::WebCryptoKey* private_key) { |
862 blink::WebCryptoKey* private_key) { | |
863 const blink::WebCryptoRsaKeyGenParams* const params = | 848 const blink::WebCryptoRsaKeyGenParams* const params = |
864 algorithm.rsaKeyGenParams(); | 849 algorithm.rsaKeyGenParams(); |
865 DCHECK(params); | 850 DCHECK(params); |
866 | 851 |
867 crypto::ScopedPK11Slot slot(PK11_GetInternalKeySlot()); | 852 crypto::ScopedPK11Slot slot(PK11_GetInternalKeySlot()); |
868 if (!slot) | 853 if (!slot) |
869 return Status::Error(); | 854 return Status::Error(); |
870 | 855 |
871 unsigned long public_exponent; | 856 unsigned long public_exponent; |
872 if (!params->modulusLengthBits()) | 857 if (!params->modulusLengthBits()) |
873 return Status::ErrorGenerateRsaZeroModulus(); | 858 return Status::ErrorGenerateRsaZeroModulus(); |
874 | 859 |
875 if (!BigIntegerToLong(params->publicExponent().data(), | 860 if (!BigIntegerToLong(params->publicExponent().data(), |
876 params->publicExponent().size(), | 861 params->publicExponent().size(), |
877 &public_exponent) || !public_exponent) { | 862 &public_exponent) || |
| 863 !public_exponent) { |
878 return Status::ErrorGenerateKeyPublicExponent(); | 864 return Status::ErrorGenerateKeyPublicExponent(); |
879 } | 865 } |
880 | 866 |
881 PK11RSAGenParams rsa_gen_params; | 867 PK11RSAGenParams rsa_gen_params; |
882 rsa_gen_params.keySizeInBits = params->modulusLengthBits(); | 868 rsa_gen_params.keySizeInBits = params->modulusLengthBits(); |
883 rsa_gen_params.pe = public_exponent; | 869 rsa_gen_params.pe = public_exponent; |
884 | 870 |
885 // Flags are verified at the Blink layer; here the flags are set to all | 871 // Flags are verified at the Blink layer; here the flags are set to all |
886 // possible operations for the given key type. | 872 // possible operations for the given key type. |
887 CK_FLAGS operation_flags; | 873 CK_FLAGS operation_flags; |
888 switch (algorithm.id()) { | 874 switch (algorithm.id()) { |
889 case blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5: | 875 case blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5: |
890 case blink::WebCryptoAlgorithmIdRsaOaep: | 876 case blink::WebCryptoAlgorithmIdRsaOaep: |
891 operation_flags = CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP; | 877 operation_flags = CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP; |
892 break; | 878 break; |
893 case blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5: | 879 case blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5: |
894 operation_flags = CKF_SIGN | CKF_VERIFY; | 880 operation_flags = CKF_SIGN | CKF_VERIFY; |
895 break; | 881 break; |
896 default: | 882 default: |
897 NOTREACHED(); | 883 NOTREACHED(); |
898 return Status::ErrorUnexpected(); | 884 return Status::ErrorUnexpected(); |
899 } | 885 } |
900 const CK_FLAGS operation_flags_mask = CKF_ENCRYPT | CKF_DECRYPT | | 886 const CK_FLAGS operation_flags_mask = |
901 CKF_SIGN | CKF_VERIFY | CKF_WRAP | | 887 CKF_ENCRYPT | CKF_DECRYPT | CKF_SIGN | CKF_VERIFY | CKF_WRAP | CKF_UNWRAP; |
902 CKF_UNWRAP; | |
903 const PK11AttrFlags attribute_flags = 0; // Default all PK11_ATTR_ flags. | 888 const PK11AttrFlags attribute_flags = 0; // Default all PK11_ATTR_ flags. |
904 | 889 |
905 // Note: NSS does not generate an sec_public_key if the call below fails, | 890 // Note: NSS does not generate an sec_public_key if the call below fails, |
906 // so there is no danger of a leaked sec_public_key. | 891 // so there is no danger of a leaked sec_public_key. |
907 SECKEYPublicKey* sec_public_key; | 892 SECKEYPublicKey* sec_public_key; |
908 crypto::ScopedSECKEYPrivateKey scoped_sec_private_key( | 893 crypto::ScopedSECKEYPrivateKey scoped_sec_private_key( |
909 PK11_GenerateKeyPairWithOpFlags(slot.get(), | 894 PK11_GenerateKeyPairWithOpFlags(slot.get(), |
910 CKM_RSA_PKCS_KEY_PAIR_GEN, | 895 CKM_RSA_PKCS_KEY_PAIR_GEN, |
911 &rsa_gen_params, | 896 &rsa_gen_params, |
912 &sec_public_key, | 897 &sec_public_key, |
913 attribute_flags, | 898 attribute_flags, |
914 operation_flags, | 899 operation_flags, |
915 operation_flags_mask, | 900 operation_flags_mask, |
916 NULL)); | 901 NULL)); |
917 if (!private_key) | 902 if (!private_key) |
918 return Status::Error(); | 903 return Status::Error(); |
919 | 904 |
920 *public_key = blink::WebCryptoKey::create( | 905 *public_key = blink::WebCryptoKey::create( |
921 new PublicKey(crypto::ScopedSECKEYPublicKey(sec_public_key)), | 906 new PublicKey(crypto::ScopedSECKEYPublicKey(sec_public_key)), |
922 blink::WebCryptoKeyTypePublic, | 907 blink::WebCryptoKeyTypePublic, |
923 true, | 908 true, |
924 algorithm, | 909 algorithm, |
925 usage_mask); | 910 usage_mask); |
926 *private_key = blink::WebCryptoKey::create( | 911 *private_key = |
927 new PrivateKey(scoped_sec_private_key.Pass()), | 912 blink::WebCryptoKey::create(new PrivateKey(scoped_sec_private_key.Pass()), |
928 blink::WebCryptoKeyTypePrivate, | 913 blink::WebCryptoKeyTypePrivate, |
929 extractable, | 914 extractable, |
930 algorithm, | 915 algorithm, |
931 usage_mask); | 916 usage_mask); |
932 | 917 |
933 return Status::Success(); | 918 return Status::Success(); |
934 } | 919 } |
935 | 920 |
936 void Init() { | 921 void Init() { crypto::EnsureNSSInit(); } |
937 crypto::EnsureNSSInit(); | |
938 } | |
939 | 922 |
940 Status DigestSha( | 923 Status DigestSha(blink::WebCryptoAlgorithmId algorithm, |
941 blink::WebCryptoAlgorithmId algorithm, | 924 const CryptoData& data, |
942 const CryptoData& data, | 925 blink::WebArrayBuffer* buffer) { |
943 blink::WebArrayBuffer* buffer) { | |
944 HASH_HashType hash_type = WebCryptoAlgorithmToNSSHashType(algorithm); | 926 HASH_HashType hash_type = WebCryptoAlgorithmToNSSHashType(algorithm); |
945 if (hash_type == HASH_AlgNULL) | 927 if (hash_type == HASH_AlgNULL) |
946 return Status::ErrorUnsupported(); | 928 return Status::ErrorUnsupported(); |
947 | 929 |
948 HASHContext* context = HASH_Create(hash_type); | 930 HASHContext* context = HASH_Create(hash_type); |
949 if (!context) | 931 if (!context) |
950 return Status::Error(); | 932 return Status::Error(); |
951 | 933 |
952 HASH_Begin(context); | 934 HASH_Begin(context); |
953 | 935 |
954 HASH_Update(context, data.bytes(), data.byte_length()); | 936 HASH_Update(context, data.bytes(), data.byte_length()); |
955 | 937 |
956 unsigned int hash_result_length = HASH_ResultLenContext(context); | 938 unsigned int hash_result_length = HASH_ResultLenContext(context); |
957 DCHECK_LE(hash_result_length, static_cast<size_t>(HASH_LENGTH_MAX)); | 939 DCHECK_LE(hash_result_length, static_cast<size_t>(HASH_LENGTH_MAX)); |
958 | 940 |
959 *buffer = blink::WebArrayBuffer::create(hash_result_length, 1); | 941 *buffer = blink::WebArrayBuffer::create(hash_result_length, 1); |
960 | 942 |
961 unsigned char* digest = reinterpret_cast<unsigned char*>(buffer->data()); | 943 unsigned char* digest = reinterpret_cast<unsigned char*>(buffer->data()); |
962 | 944 |
963 unsigned int result_length = 0; | 945 unsigned int result_length = 0; |
964 HASH_End(context, digest, &result_length, hash_result_length); | 946 HASH_End(context, digest, &result_length, hash_result_length); |
965 | 947 |
966 HASH_Destroy(context); | 948 HASH_Destroy(context); |
967 | 949 |
968 if (result_length != hash_result_length) | 950 if (result_length != hash_result_length) |
969 return Status::ErrorUnexpected(); | 951 return Status::ErrorUnexpected(); |
970 return Status::Success(); | 952 return Status::Success(); |
971 } | 953 } |
972 | 954 |
973 Status GenerateSecretKey( | 955 Status GenerateSecretKey(const blink::WebCryptoAlgorithm& algorithm, |
974 const blink::WebCryptoAlgorithm& algorithm, | 956 bool extractable, |
975 bool extractable, | 957 blink::WebCryptoKeyUsageMask usage_mask, |
976 blink::WebCryptoKeyUsageMask usage_mask, | 958 unsigned keylen_bytes, |
977 unsigned keylen_bytes, | 959 blink::WebCryptoKey* key) { |
978 blink::WebCryptoKey* key) { | |
979 CK_MECHANISM_TYPE mech = WebCryptoAlgorithmToGenMechanism(algorithm); | 960 CK_MECHANISM_TYPE mech = WebCryptoAlgorithmToGenMechanism(algorithm); |
980 blink::WebCryptoKeyType key_type = blink::WebCryptoKeyTypeSecret; | 961 blink::WebCryptoKeyType key_type = blink::WebCryptoKeyTypeSecret; |
981 | 962 |
982 if (mech == CKM_INVALID_MECHANISM) | 963 if (mech == CKM_INVALID_MECHANISM) |
983 return Status::ErrorUnsupported(); | 964 return Status::ErrorUnsupported(); |
984 | 965 |
985 crypto::ScopedPK11Slot slot(PK11_GetInternalKeySlot()); | 966 crypto::ScopedPK11Slot slot(PK11_GetInternalKeySlot()); |
986 if (!slot) | 967 if (!slot) |
987 return Status::Error(); | 968 return Status::Error(); |
988 | 969 |
989 crypto::ScopedPK11SymKey pk11_key( | 970 crypto::ScopedPK11SymKey pk11_key( |
990 PK11_KeyGen(slot.get(), mech, NULL, keylen_bytes, NULL)); | 971 PK11_KeyGen(slot.get(), mech, NULL, keylen_bytes, NULL)); |
991 | 972 |
992 if (!pk11_key) | 973 if (!pk11_key) |
993 return Status::Error(); | 974 return Status::Error(); |
994 | 975 |
995 *key = blink::WebCryptoKey::create(new SymKey(pk11_key.Pass()), | 976 *key = blink::WebCryptoKey::create(new SymKey(pk11_key.Pass()), |
996 key_type, | 977 key_type, |
997 extractable, | 978 extractable, |
998 algorithm, | 979 algorithm, |
999 usage_mask); | 980 usage_mask); |
1000 return Status::Success(); | 981 return Status::Success(); |
1001 } | 982 } |
1002 | 983 |
1003 Status ImportRsaPublicKey( | 984 Status ImportRsaPublicKey(const blink::WebCryptoAlgorithm& algorithm, |
1004 const blink::WebCryptoAlgorithm& algorithm, | 985 bool extractable, |
1005 bool extractable, | 986 blink::WebCryptoKeyUsageMask usage_mask, |
1006 blink::WebCryptoKeyUsageMask usage_mask, | 987 const CryptoData& modulus_data, |
1007 const CryptoData& modulus_data, | 988 const CryptoData& exponent_data, |
1008 const CryptoData& exponent_data, | 989 blink::WebCryptoKey* key) { |
1009 blink::WebCryptoKey* key) { | |
1010 | 990 |
1011 if (!modulus_data.byte_length()) | 991 if (!modulus_data.byte_length()) |
1012 return Status::ErrorImportRsaEmptyModulus(); | 992 return Status::ErrorImportRsaEmptyModulus(); |
1013 | 993 |
1014 if (!exponent_data.byte_length()) | 994 if (!exponent_data.byte_length()) |
1015 return Status::ErrorImportRsaEmptyExponent(); | 995 return Status::ErrorImportRsaEmptyExponent(); |
1016 | 996 |
1017 DCHECK(modulus_data.bytes()); | 997 DCHECK(modulus_data.bytes()); |
1018 DCHECK(exponent_data.bytes()); | 998 DCHECK(exponent_data.bytes()); |
1019 | 999 |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1058 algorithm, | 1038 algorithm, |
1059 usage_mask); | 1039 usage_mask); |
1060 return Status::Success(); | 1040 return Status::Success(); |
1061 } | 1041 } |
1062 | 1042 |
1063 } // namespace platform | 1043 } // namespace platform |
1064 | 1044 |
1065 } // namespace webcrypto | 1045 } // namespace webcrypto |
1066 | 1046 |
1067 } // namespace content | 1047 } // namespace content |
OLD | NEW |