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 "jwk.h" | 5 #include "jwk.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <functional> | 8 #include <functional> |
9 #include <map> | 9 #include <map> |
10 | 10 |
(...skipping 491 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
502 if (!dict->Get(path, &value)) | 502 if (!dict->Get(path, &value)) |
503 return Status::Success(); | 503 return Status::Success(); |
504 | 504 |
505 if (!value->GetAsBoolean(result)) | 505 if (!value->GetAsBoolean(result)) |
506 return Status::ErrorJwkPropertyWrongType(path, "boolean"); | 506 return Status::ErrorJwkPropertyWrongType(path, "boolean"); |
507 | 507 |
508 *property_exists = true; | 508 *property_exists = true; |
509 return Status::Success(); | 509 return Status::Success(); |
510 } | 510 } |
511 | 511 |
512 // Returns true if the set bits in b make up a subset of the set bits in a. | |
513 bool ContainsKeyUsages(blink::WebCryptoKeyUsageMask a, | |
514 blink::WebCryptoKeyUsageMask b) { | |
515 return (a & b) == b; | |
516 } | |
517 | |
518 // Writes a secret/symmetric key to a JWK dictionary. | 512 // Writes a secret/symmetric key to a JWK dictionary. |
519 void WriteSecretKey(const std::vector<uint8>& raw_key, | 513 void WriteSecretKey(const std::vector<uint8>& raw_key, |
520 base::DictionaryValue* jwk_dict) { | 514 base::DictionaryValue* jwk_dict) { |
521 DCHECK(jwk_dict); | 515 DCHECK(jwk_dict); |
522 jwk_dict->SetString("kty", "oct"); | 516 jwk_dict->SetString("kty", "oct"); |
523 // For a secret/symmetric key, the only extra JWK field is 'k', containing the | 517 // For a secret/symmetric key, the only extra JWK field is 'k', containing the |
524 // base64url encoding of the raw key. | 518 // base64url encoding of the raw key. |
525 const base::StringPiece key_str( | 519 const base::StringPiece key_str( |
526 reinterpret_cast<const char*>(Uint8VectorStart(raw_key)), raw_key.size()); | 520 reinterpret_cast<const char*>(Uint8VectorStart(raw_key)), raw_key.size()); |
527 jwk_dict->SetString("k", Base64EncodeUrlSafe(key_str)); | 521 jwk_dict->SetString("k", Base64EncodeUrlSafe(key_str)); |
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
707 return Status::ErrorUnexpected(); | 701 return Status::ErrorUnexpected(); |
708 } | 702 } |
709 break; | 703 break; |
710 default: | 704 default: |
711 return Status::ErrorUnsupported(); | 705 return Status::ErrorUnsupported(); |
712 } | 706 } |
713 return Status::Success(); | 707 return Status::Success(); |
714 } | 708 } |
715 | 709 |
716 bool IsRsaKey(const blink::WebCryptoKey& key) { | 710 bool IsRsaKey(const blink::WebCryptoKey& key) { |
717 const blink::WebCryptoAlgorithmId algorithm_id = key.algorithm().id(); | 711 return IsAlgorithmRsa(key.algorithm().id()); |
718 return algorithm_id == blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5 || | |
719 algorithm_id == blink::WebCryptoAlgorithmIdRsaOaep; | |
720 } | 712 } |
721 | 713 |
722 Status ImportRsaKey(base::DictionaryValue* dict, | 714 Status ImportRsaKey(base::DictionaryValue* dict, |
723 const blink::WebCryptoAlgorithm& algorithm, | 715 const blink::WebCryptoAlgorithm& algorithm, |
724 bool extractable, | 716 bool extractable, |
725 blink::WebCryptoKeyUsageMask usage_mask, | 717 blink::WebCryptoKeyUsageMask usage_mask, |
726 blink::WebCryptoKey* key) { | 718 blink::WebCryptoKey* key) { |
727 // An RSA public key must have an "n" (modulus) and an "e" (exponent) entry | 719 // An RSA public key must have an "n" (modulus) and an "e" (exponent) entry |
728 // in the JWK, while an RSA private key must have those, plus at least a "d" | 720 // in the JWK, while an RSA private key must have those, plus at least a "d" |
729 // (private exponent) entry. | 721 // (private exponent) entry. |
730 // See http://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-18, | 722 // See http://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-18, |
731 // section 6.3. | 723 // section 6.3. |
732 std::string jwk_n_value; | 724 std::string jwk_n_value; |
733 Status status = GetJwkBytes(dict, "n", &jwk_n_value); | 725 Status status = GetJwkBytes(dict, "n", &jwk_n_value); |
734 if (status.IsError()) | 726 if (status.IsError()) |
735 return status; | 727 return status; |
736 std::string jwk_e_value; | 728 std::string jwk_e_value; |
737 status = GetJwkBytes(dict, "e", &jwk_e_value); | 729 status = GetJwkBytes(dict, "e", &jwk_e_value); |
738 if (status.IsError()) | 730 if (status.IsError()) |
739 return status; | 731 return status; |
740 | 732 |
741 if (!dict->HasKey("d")) { | 733 bool is_public_key = !dict->HasKey("d"); |
| 734 |
| 735 // Now that the key type is known, do an additional check on the usages to |
| 736 // make sure they are all applicable for this algorithm + key type. |
| 737 status = CheckKeyUsages(algorithm.id(), |
| 738 is_public_key ? blink::WebCryptoKeyTypePublic |
| 739 : blink::WebCryptoKeyTypePrivate, |
| 740 usage_mask); |
| 741 |
| 742 if (status.IsError()) |
| 743 return status; |
| 744 |
| 745 if (is_public_key) { |
742 return platform::ImportRsaPublicKey(algorithm, | 746 return platform::ImportRsaPublicKey(algorithm, |
743 extractable, | 747 extractable, |
744 usage_mask, | 748 usage_mask, |
745 CryptoData(jwk_n_value), | 749 CryptoData(jwk_n_value), |
746 CryptoData(jwk_e_value), | 750 CryptoData(jwk_e_value), |
747 key); | 751 key); |
748 } | 752 } |
749 | 753 |
750 std::string jwk_d_value; | 754 std::string jwk_d_value; |
751 status = GetJwkBytes(dict, "d", &jwk_d_value); | 755 status = GetJwkBytes(dict, "d", &jwk_d_value); |
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1005 | 1009 |
1006 std::string json; | 1010 std::string json; |
1007 base::JSONWriter::Write(&jwk_dict, &json); | 1011 base::JSONWriter::Write(&jwk_dict, &json); |
1008 buffer->assign(json.data(), json.data() + json.size()); | 1012 buffer->assign(json.data(), json.data() + json.size()); |
1009 return Status::Success(); | 1013 return Status::Success(); |
1010 } | 1014 } |
1011 | 1015 |
1012 } // namespace webcrypto | 1016 } // namespace webcrypto |
1013 | 1017 |
1014 } // namespace content | 1018 } // namespace content |
OLD | NEW |