OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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/webcrypto_impl.h" | 5 #include "content/renderer/webcrypto/webcrypto_impl.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 473 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
484 void WebCryptoImpl::Init() { | 484 void WebCryptoImpl::Init() { |
485 crypto::EnsureNSSInit(); | 485 crypto::EnsureNSSInit(); |
486 } | 486 } |
487 | 487 |
488 bool WebCryptoImpl::EncryptInternal( | 488 bool WebCryptoImpl::EncryptInternal( |
489 const blink::WebCryptoAlgorithm& algorithm, | 489 const blink::WebCryptoAlgorithm& algorithm, |
490 const blink::WebCryptoKey& key, | 490 const blink::WebCryptoKey& key, |
491 const unsigned char* data, | 491 const unsigned char* data, |
492 unsigned data_size, | 492 unsigned data_size, |
493 blink::WebArrayBuffer* buffer) { | 493 blink::WebArrayBuffer* buffer) { |
| 494 |
| 495 DCHECK_EQ(algorithm.id(), key.algorithm().id()); |
| 496 DCHECK(key.handle()); |
| 497 DCHECK(buffer); |
| 498 |
494 if (algorithm.id() == blink::WebCryptoAlgorithmIdAesCbc) { | 499 if (algorithm.id() == blink::WebCryptoAlgorithmIdAesCbc) { |
495 return AesCbcEncryptDecrypt( | 500 return AesCbcEncryptDecrypt( |
496 CKA_ENCRYPT, algorithm, key, data, data_size, buffer); | 501 CKA_ENCRYPT, algorithm, key, data, data_size, buffer); |
| 502 } else if (algorithm.id() == blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5) { |
| 503 |
| 504 // RSAES encryption does not support empty input |
| 505 if (!data_size) |
| 506 return false; |
| 507 DCHECK(data); |
| 508 |
| 509 if (key.type() != blink::WebCryptoKeyTypePublic) |
| 510 return false; |
| 511 |
| 512 PublicKeyHandle* const public_key = |
| 513 reinterpret_cast<PublicKeyHandle*>(key.handle()); |
| 514 |
| 515 const unsigned encrypted_length_bytes = |
| 516 SECKEY_PublicKeyStrength(public_key->key()); |
| 517 |
| 518 // RSAES can operate on messages up to a length of k - 11, where k is the |
| 519 // octet length of the RSA modulus. |
| 520 if (encrypted_length_bytes < 11 || encrypted_length_bytes - 11 < data_size) |
| 521 return false; |
| 522 |
| 523 *buffer = blink::WebArrayBuffer::create(encrypted_length_bytes, 1); |
| 524 unsigned char* const buffer_data = |
| 525 reinterpret_cast<unsigned char*>(buffer->data()); |
| 526 |
| 527 if (PK11_PubEncryptPKCS1(public_key->key(), |
| 528 buffer_data, |
| 529 const_cast<unsigned char*>(data), |
| 530 data_size, |
| 531 NULL) != SECSuccess) { |
| 532 return false; |
| 533 } |
| 534 return true; |
497 } | 535 } |
498 | 536 |
499 return false; | 537 return false; |
500 } | 538 } |
501 | 539 |
502 bool WebCryptoImpl::DecryptInternal( | 540 bool WebCryptoImpl::DecryptInternal( |
503 const blink::WebCryptoAlgorithm& algorithm, | 541 const blink::WebCryptoAlgorithm& algorithm, |
504 const blink::WebCryptoKey& key, | 542 const blink::WebCryptoKey& key, |
505 const unsigned char* data, | 543 const unsigned char* data, |
506 unsigned data_size, | 544 unsigned data_size, |
507 blink::WebArrayBuffer* buffer) { | 545 blink::WebArrayBuffer* buffer) { |
| 546 |
| 547 DCHECK_EQ(algorithm.id(), key.algorithm().id()); |
| 548 DCHECK(key.handle()); |
| 549 DCHECK(buffer); |
| 550 |
508 if (algorithm.id() == blink::WebCryptoAlgorithmIdAesCbc) { | 551 if (algorithm.id() == blink::WebCryptoAlgorithmIdAesCbc) { |
509 return AesCbcEncryptDecrypt( | 552 return AesCbcEncryptDecrypt( |
510 CKA_DECRYPT, algorithm, key, data, data_size, buffer); | 553 CKA_DECRYPT, algorithm, key, data, data_size, buffer); |
| 554 } else if (algorithm.id() == blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5) { |
| 555 |
| 556 // RSAES decryption does not support empty input |
| 557 if (!data_size) |
| 558 return false; |
| 559 DCHECK(data); |
| 560 |
| 561 if (key.type() != blink::WebCryptoKeyTypePrivate) |
| 562 return false; |
| 563 |
| 564 PrivateKeyHandle* const private_key = |
| 565 reinterpret_cast<PrivateKeyHandle*>(key.handle()); |
| 566 |
| 567 const int modulus_length_bytes = |
| 568 PK11_GetPrivateModulusLen(private_key->key()); |
| 569 if (modulus_length_bytes <= 0) |
| 570 return false; |
| 571 const unsigned max_output_length_bytes = modulus_length_bytes; |
| 572 |
| 573 *buffer = blink::WebArrayBuffer::create(max_output_length_bytes, 1); |
| 574 unsigned char* const buffer_data = |
| 575 reinterpret_cast<unsigned char*>(buffer->data()); |
| 576 |
| 577 unsigned output_length_bytes = 0; |
| 578 if (PK11_PrivDecryptPKCS1(private_key->key(), |
| 579 buffer_data, |
| 580 &output_length_bytes, |
| 581 max_output_length_bytes, |
| 582 const_cast<unsigned char*>(data), |
| 583 data_size) != SECSuccess) { |
| 584 return false; |
| 585 } |
| 586 DCHECK_LE(output_length_bytes, max_output_length_bytes); |
| 587 WebCryptoImpl::ShrinkBuffer(buffer, output_length_bytes); |
| 588 return true; |
511 } | 589 } |
512 | 590 |
513 return false; | 591 return false; |
514 } | 592 } |
515 | 593 |
516 bool WebCryptoImpl::DigestInternal( | 594 bool WebCryptoImpl::DigestInternal( |
517 const blink::WebCryptoAlgorithm& algorithm, | 595 const blink::WebCryptoAlgorithm& algorithm, |
518 const unsigned char* data, | 596 const unsigned char* data, |
519 unsigned data_size, | 597 unsigned data_size, |
520 blink::WebArrayBuffer* buffer) { | 598 blink::WebArrayBuffer* buffer) { |
(...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
851 break; | 929 break; |
852 } | 930 } |
853 default: | 931 default: |
854 return false; | 932 return false; |
855 } | 933 } |
856 | 934 |
857 return true; | 935 return true; |
858 } | 936 } |
859 | 937 |
860 } // namespace content | 938 } // namespace content |
OLD | NEW |