OLD | NEW |
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 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 <algorithm> | 7 #include <algorithm> |
8 #include <functional> | 8 #include <functional> |
9 #include <map> | 9 #include <map> |
10 #include "base/json/json_reader.h" | 10 #include "base/json/json_reader.h" |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
141 case blink::WebCryptoAlgorithmIdAesGcm: | 141 case blink::WebCryptoAlgorithmIdAesGcm: |
142 case blink::WebCryptoAlgorithmIdAesCtr: | 142 case blink::WebCryptoAlgorithmIdAesCtr: |
143 return true; | 143 return true; |
144 default: | 144 default: |
145 NOTREACHED(); // Not a supported algorithm. | 145 NOTREACHED(); // Not a supported algorithm. |
146 break; | 146 break; |
147 } | 147 } |
148 return false; | 148 return false; |
149 } | 149 } |
150 | 150 |
| 151 bool GetDecodedUrl64ValueByKey( |
| 152 const base::DictionaryValue& dict, |
| 153 const std::string& key, |
| 154 std::string* decoded) { |
| 155 std::string value_url64; |
| 156 if (!dict.GetString(key, &value_url64) || |
| 157 !webcrypto::Base64DecodeUrlSafe(value_url64, decoded) || |
| 158 !decoded->size()) { |
| 159 return false; |
| 160 } |
| 161 return true; |
| 162 } |
| 163 |
151 } // namespace | 164 } // namespace |
152 | 165 |
153 WebCryptoImpl::WebCryptoImpl() { | 166 WebCryptoImpl::WebCryptoImpl() { |
154 Init(); | 167 Init(); |
155 } | 168 } |
156 | 169 |
157 void WebCryptoImpl::encrypt( | 170 void WebCryptoImpl::encrypt( |
158 const blink::WebCryptoAlgorithm& algorithm, | 171 const blink::WebCryptoAlgorithm& algorithm, |
159 const blink::WebCryptoKey& key, | 172 const blink::WebCryptoKey& key, |
160 const unsigned char* data, | 173 const unsigned char* data, |
(...skipping 343 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
504 // 3. JWK alg valid AND input algorithm specified, but JWK value | 517 // 3. JWK alg valid AND input algorithm specified, but JWK value |
505 // inconsistent with input: error | 518 // inconsistent with input: error |
506 // 4. JWK alg valid AND input algorithm specified, both consistent: use | 519 // 4. JWK alg valid AND input algorithm specified, both consistent: use |
507 // input value (because it has potentially more details) | 520 // input value (because it has potentially more details) |
508 // 5. JWK alg missing AND input algorithm isNull: error | 521 // 5. JWK alg missing AND input algorithm isNull: error |
509 // 6. JWK alg missing AND input algorithm specified: use input value | 522 // 6. JWK alg missing AND input algorithm specified: use input value |
510 blink::WebCryptoAlgorithm algorithm = blink::WebCryptoAlgorithm::createNull(); | 523 blink::WebCryptoAlgorithm algorithm = blink::WebCryptoAlgorithm::createNull(); |
511 std::string jwk_alg_value; | 524 std::string jwk_alg_value; |
512 if (dict_value->GetString("alg", &jwk_alg_value)) { | 525 if (dict_value->GetString("alg", &jwk_alg_value)) { |
513 // JWK alg present | 526 // JWK alg present |
| 527 |
| 528 // TODO(padolph): Validate alg vs kty. For example kty="RSA" implies alg can |
| 529 // only be from the RSA family. |
| 530 |
514 const blink::WebCryptoAlgorithm jwk_algorithm = | 531 const blink::WebCryptoAlgorithm jwk_algorithm = |
515 jwk_alg_factory.Get().CreateAlgorithmFromName(jwk_alg_value); | 532 jwk_alg_factory.Get().CreateAlgorithmFromName(jwk_alg_value); |
516 if (jwk_algorithm.isNull()) { | 533 if (jwk_algorithm.isNull()) { |
517 // JWK alg unrecognized | 534 // JWK alg unrecognized |
518 return false; // case 1 | 535 return false; // case 1 |
519 } | 536 } |
520 // JWK alg valid | 537 // JWK alg valid |
521 if (algorithm_or_null.isNull()) { | 538 if (algorithm_or_null.isNull()) { |
522 // input algorithm not specified | 539 // input algorithm not specified |
523 algorithm = jwk_algorithm; // case 2 | 540 algorithm = jwk_algorithm; // case 2 |
(...skipping 28 matching lines...) Expand all Loading... |
552 return false; | 569 return false; |
553 } | 570 } |
554 if ((jwk_usage_mask & usage_mask) != usage_mask) { | 571 if ((jwk_usage_mask & usage_mask) != usage_mask) { |
555 // A usage_mask must be a subset of jwk_usage_mask. | 572 // A usage_mask must be a subset of jwk_usage_mask. |
556 return false; | 573 return false; |
557 } | 574 } |
558 } | 575 } |
559 | 576 |
560 // JWK keying material --> ImportKeyInternal() | 577 // JWK keying material --> ImportKeyInternal() |
561 if (jwk_kty_value == "oct") { | 578 if (jwk_kty_value == "oct") { |
562 std::string jwk_k_value_url64; | 579 |
563 if (!dict_value->GetString("k", &jwk_k_value_url64)) | 580 std::string jwk_k_value; |
| 581 if (!GetDecodedUrl64ValueByKey(*dict_value, "k", &jwk_k_value)) |
564 return false; | 582 return false; |
565 std::string jwk_k_value; | |
566 if (!webcrypto::Base64DecodeUrlSafe(jwk_k_value_url64, &jwk_k_value) || | |
567 !jwk_k_value.size()) { | |
568 return false; | |
569 } | |
570 | 583 |
571 // TODO(padolph): Some JWK alg ID's embed information about the key length | 584 // TODO(padolph): Some JWK alg ID's embed information about the key length |
572 // in the alg ID string. For example "A128" implies the JWK carries 128 bits | 585 // in the alg ID string. For example "A128" implies the JWK carries 128 bits |
573 // of key material, and "HS512" implies the JWK carries _at least_ 512 bits | 586 // of key material, and "HS512" implies the JWK carries _at least_ 512 bits |
574 // of key material. For such keys validate the actual key length against the | 587 // of key material. For such keys validate the actual key length against the |
575 // value in the ID. | 588 // value in the ID. |
576 | 589 |
577 return ImportKeyInternal(blink::WebCryptoKeyFormatRaw, | 590 return ImportKeyInternal(blink::WebCryptoKeyFormatRaw, |
578 reinterpret_cast<const uint8*>(jwk_k_value.data()), | 591 reinterpret_cast<const uint8*>(jwk_k_value.data()), |
579 jwk_k_value.size(), | 592 jwk_k_value.size(), |
580 algorithm, | 593 algorithm, |
581 extractable, | 594 extractable, |
582 usage_mask, | 595 usage_mask, |
583 key); | 596 key); |
584 } else if (jwk_kty_value == "RSA") { | 597 } else if (jwk_kty_value == "RSA") { |
585 // TODO(padolph): JWK import RSA public key | 598 |
586 return false; | 599 // An RSA public key must have an "n" (modulus) and an "e" (exponent) entry |
| 600 // in the JWK, while an RSA private key must have those, plus at least a "d" |
| 601 // (private exponent) entry. |
| 602 // See http://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-18, |
| 603 // section 6.3. |
| 604 |
| 605 // RSA private key import is not currently supported, so fail here if a "d" |
| 606 // entry is found. |
| 607 // TODO(padolph): Support RSA private key import. |
| 608 if (dict_value->HasKey("d")) |
| 609 return false; |
| 610 |
| 611 std::string jwk_n_value; |
| 612 if (!GetDecodedUrl64ValueByKey(*dict_value, "n", &jwk_n_value)) |
| 613 return false; |
| 614 std::string jwk_e_value; |
| 615 if (!GetDecodedUrl64ValueByKey(*dict_value, "e", &jwk_e_value)) |
| 616 return false; |
| 617 |
| 618 return ImportRsaPublicKeyInternal( |
| 619 reinterpret_cast<const uint8*>(jwk_n_value.data()), |
| 620 jwk_n_value.size(), |
| 621 reinterpret_cast<const uint8*>(jwk_e_value.data()), |
| 622 jwk_e_value.size(), |
| 623 algorithm, |
| 624 extractable, |
| 625 usage_mask, |
| 626 key); |
| 627 |
587 } else { | 628 } else { |
588 return false; | 629 return false; |
589 } | 630 } |
590 | 631 |
591 return true; | 632 return true; |
592 } | 633 } |
593 | 634 |
594 } // namespace content | 635 } // namespace content |
OLD | NEW |