Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(399)

Side by Side Diff: content/child/webcrypto/jwk.cc

Issue 287133004: [webcrypto] Add JWK import/export of RSA private keys (NSS). (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix comment typeo Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | content/child/webcrypto/platform_crypto.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
123 // | "A192GCM" | AES GCM using 192 bit keys | 123 // | "A192GCM" | AES GCM using 192 bit keys |
124 // | "A256GCM" | AES GCM using 256 bit keys | 124 // | "A256GCM" | AES GCM using 256 bit keys |
125 // | "A128CBC" | AES in Cipher Block Chaining Mode (CBC) with PKCS #5 | 125 // | "A128CBC" | AES in Cipher Block Chaining Mode (CBC) with PKCS #5 |
126 // | | padding [NIST.800-38A] | 126 // | | padding [NIST.800-38A] |
127 // | "A192CBC" | AES CBC using 192 bit keys | 127 // | "A192CBC" | AES CBC using 192 bit keys |
128 // | "A256CBC" | AES CBC using 256 bit keys | 128 // | "A256CBC" | AES CBC using 256 bit keys |
129 // +--------------+-------------------------------------------------------+ 129 // +--------------+-------------------------------------------------------+
130 // 130 //
131 // kty-specific parameters 131 // kty-specific parameters
132 // The value of kty determines the type and content of the keying material 132 // The value of kty determines the type and content of the keying material
133 // carried in the JWK to be imported. Currently only two possibilities are 133 // carried in the JWK to be imported.
134 // supported: a raw key or an RSA public key. RSA private keys are not 134 // // - kty == "oct" (symmetric or other raw key)
135 // supported because typical applications seldom need to import a private key,
136 // and the large number of JWK parameters required to describe one.
137 // - kty == "oct" (symmetric or other raw key)
138 // +-------+--------------------------------------------------------------+ 135 // +-------+--------------------------------------------------------------+
139 // | "k" | Contains the value of the symmetric (or other single-valued) | 136 // | "k" | Contains the value of the symmetric (or other single-valued) |
140 // | | key. It is represented as the base64url encoding of the | 137 // | | key. It is represented as the base64url encoding of the |
141 // | | octet sequence containing the key value. | 138 // | | octet sequence containing the key value. |
142 // +-------+--------------------------------------------------------------+ 139 // +-------+--------------------------------------------------------------+
143 // - kty == "RSA" (RSA public key) 140 // - kty == "RSA" (RSA public key)
144 // +-------+--------------------------------------------------------------+ 141 // +-------+--------------------------------------------------------------+
145 // | "n" | Contains the modulus value for the RSA public key. It is | 142 // | "n" | Contains the modulus value for the RSA public key. It is |
146 // | | represented as the base64url encoding of the value's | 143 // | | represented as the base64url encoding of the value's |
147 // | | unsigned big endian representation as an octet sequence. | 144 // | | unsigned big endian representation as an octet sequence. |
148 // +-------+--------------------------------------------------------------+ 145 // +-------+--------------------------------------------------------------+
149 // | "e" | Contains the exponent value for the RSA public key. It is | 146 // | "e" | Contains the exponent value for the RSA public key. It is |
150 // | | represented as the base64url encoding of the value's | 147 // | | represented as the base64url encoding of the value's |
151 // | | unsigned big endian representation as an octet sequence. | 148 // | | unsigned big endian representation as an octet sequence. |
152 // +-------+--------------------------------------------------------------+ 149 // +-------+--------------------------------------------------------------+
150 // - If key == "RSA" and the "d" parameter is present then it is a private key.
151 // All the parameters above for public keys apply, as well as the following.
152 // (Note that except for "d", all of these are optional):
153 // +-------+--------------------------------------------------------------+
154 // | "d" | Contains the private exponent value for the RSA private key. |
155 // | | It is represented as the base64url encoding of the value's |
156 // | | unsigned big endian representation as an octet sequence. |
157 // +-------+--------------------------------------------------------------+
158 // | "p" | Contains the first prime factor value for the RSA private |
159 // | | key. It is represented as the base64url encoding of the |
160 // | | value's |
161 // | | unsigned big endian representation as an octet sequence. |
162 // +-------+--------------------------------------------------------------+
163 // | "q" | Contains the second prime factor value for the RSA private |
164 // | | key. It is represented as the base64url encoding of the |
165 // | | value's unsigned big endian representation as an octet |
166 // | | sequence. |
167 // +-------+--------------------------------------------------------------+
168 // | "dp" | Contains the first factor CRT exponent value for the RSA |
169 // | | private key. It is represented as the base64url encoding of |
170 // | | the value's unsigned big endian representation as an octet |
171 // | | sequence. |
172 // +-------+--------------------------------------------------------------+
173 // | "dq" | Contains the second factor CRT exponent value for the RSA |
174 // | | private key. It is represented as the base64url encoding of |
175 // | | the value's unsigned big endian representation as an octet |
176 // | | sequence. |
177 // +-------+--------------------------------------------------------------+
178 // | "dq" | Contains the first CRT coefficient value for the RSA private |
179 // | | key. It is represented as the base64url encoding of the |
180 // | | value's unsigned big endian representation as an octet |
181 // | | sequence. |
182 // +-------+--------------------------------------------------------------+
153 // 183 //
154 // Consistency and conflict resolution 184 // Consistency and conflict resolution
155 // The 'algorithm', 'extractable', and 'usage_mask' input parameters 185 // The 'algorithm', 'extractable', and 'usage_mask' input parameters
156 // may be different than the corresponding values inside the JWK. The Web 186 // may be different than the corresponding values inside the JWK. The Web
157 // Crypto spec says that if a JWK value is present but is inconsistent with 187 // Crypto spec says that if a JWK value is present but is inconsistent with
158 // the input value, it is an error and the operation must fail. If no 188 // the input value, it is an error and the operation must fail. If no
159 // inconsistency is found then the input parameters are used. 189 // inconsistency is found then the input parameters are used.
160 // 190 //
161 // algorithm 191 // algorithm
162 // If the JWK algorithm is provided, it must match the web crypto input 192 // If the JWK algorithm is provided, it must match the web crypto input
(...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after
423 Status status = GetJwkString(dict, path, &base64_string); 453 Status status = GetJwkString(dict, path, &base64_string);
424 if (status.IsError()) 454 if (status.IsError())
425 return status; 455 return status;
426 456
427 if (!Base64DecodeUrlSafe(base64_string, result)) 457 if (!Base64DecodeUrlSafe(base64_string, result))
428 return Status::ErrorJwkBase64Decode(path); 458 return Status::ErrorJwkBase64Decode(path);
429 459
430 return Status::Success(); 460 return Status::Success();
431 } 461 }
432 462
463 // Extracts the optional string property with key |path| from |dict| and saves
464 // the base64url-decoded bytes to |*result|. If the property exist and is not a
465 // string, or could not be base64url-decoded, returns an error. In the case
466 // where the property does not exist, |result| is guaranteed to be empty.
467 Status GetOptionalJwkBytes(base::DictionaryValue* dict,
468 const std::string& path,
469 std::string* result,
470 bool* property_exists) {
471 std::string base64_string;
472 Status status =
473 GetOptionalJwkString(dict, path, &base64_string, property_exists);
474 if (status.IsError())
475 return status;
476
477 if (!*property_exists) {
478 result->clear();
479 return Status::Success();
480 }
481
482 if (!Base64DecodeUrlSafe(base64_string, result))
483 return Status::ErrorJwkBase64Decode(path);
484
485 return Status::Success();
486 }
487
433 // Extracts the optional boolean property with key |path| from |dict| and saves 488 // Extracts the optional boolean property with key |path| from |dict| and saves
434 // the result to |*result| if it was found. If the property exists and is not a 489 // the result to |*result| if it was found. If the property exists and is not a
435 // boolean, returns an error. Otherwise returns success, and sets 490 // boolean, returns an error. Otherwise returns success, and sets
436 // |*property_exists| if it was found. 491 // |*property_exists| if it was found.
437 Status GetOptionalJwkBool(base::DictionaryValue* dict, 492 Status GetOptionalJwkBool(base::DictionaryValue* dict,
438 const std::string& path, 493 const std::string& path,
439 bool* result, 494 bool* result,
440 bool* property_exists) { 495 bool* property_exists) {
441 *property_exists = false; 496 *property_exists = false;
442 base::Value* value = NULL; 497 base::Value* value = NULL;
(...skipping 30 matching lines...) Expand all
473 const std::vector<uint8>& public_exponent, 528 const std::vector<uint8>& public_exponent,
474 base::DictionaryValue* jwk_dict) { 529 base::DictionaryValue* jwk_dict) {
475 DCHECK(jwk_dict); 530 DCHECK(jwk_dict);
476 DCHECK(modulus.size()); 531 DCHECK(modulus.size());
477 DCHECK(public_exponent.size()); 532 DCHECK(public_exponent.size());
478 jwk_dict->SetString("kty", "RSA"); 533 jwk_dict->SetString("kty", "RSA");
479 jwk_dict->SetString("n", Base64EncodeUrlSafe(modulus)); 534 jwk_dict->SetString("n", Base64EncodeUrlSafe(modulus));
480 jwk_dict->SetString("e", Base64EncodeUrlSafe(public_exponent)); 535 jwk_dict->SetString("e", Base64EncodeUrlSafe(public_exponent));
481 } 536 }
482 537
538 // Writes an RSA private key to a JWK dictionary
539 Status ExportRsaPrivateKeyJwk(const blink::WebCryptoKey& key,
540 base::DictionaryValue* jwk_dict) {
541 platform::PrivateKey* private_key;
542 Status status = ToPlatformPrivateKey(key, &private_key);
543 if (status.IsError())
544 return status;
545
546 // TODO(eroman): Copying the key properties to temporary vectors is
547 // inefficient. Once there aren't two implementations of platform_crypto this
548 // and other code will be easier to streamline.
549 std::vector<uint8> modulus;
550 std::vector<uint8> public_exponent;
551 std::vector<uint8> private_exponent;
552 std::vector<uint8> prime1;
553 std::vector<uint8> prime2;
554 std::vector<uint8> exponent1;
555 std::vector<uint8> exponent2;
556 std::vector<uint8> coefficient;
557
558 status = platform::ExportRsaPrivateKey(private_key,
559 &modulus,
560 &public_exponent,
561 &private_exponent,
562 &prime1,
563 &prime2,
564 &exponent1,
565 &exponent2,
566 &coefficient);
567 if (status.IsError())
568 return status;
569
570 jwk_dict->SetString("kty", "RSA");
571 jwk_dict->SetString("n", Base64EncodeUrlSafe(modulus));
572 jwk_dict->SetString("e", Base64EncodeUrlSafe(public_exponent));
573 jwk_dict->SetString("d", Base64EncodeUrlSafe(private_exponent));
574 // Although these are "optional" in the JWA, WebCrypto spec requires them to
575 // be emitted.
576 jwk_dict->SetString("p", Base64EncodeUrlSafe(prime1));
577 jwk_dict->SetString("q", Base64EncodeUrlSafe(prime2));
578 jwk_dict->SetString("dp", Base64EncodeUrlSafe(exponent1));
579 jwk_dict->SetString("dq", Base64EncodeUrlSafe(exponent2));
580 jwk_dict->SetString("qi", Base64EncodeUrlSafe(coefficient));
581
582 return Status::Success();
583 }
584
483 // Writes a Web Crypto usage mask to a JWK dictionary. 585 // Writes a Web Crypto usage mask to a JWK dictionary.
484 void WriteKeyOps(blink::WebCryptoKeyUsageMask key_usages, 586 void WriteKeyOps(blink::WebCryptoKeyUsageMask key_usages,
485 base::DictionaryValue* jwk_dict) { 587 base::DictionaryValue* jwk_dict) {
486 jwk_dict->Set("key_ops", CreateJwkKeyOpsFromWebCryptoUsages(key_usages)); 588 jwk_dict->Set("key_ops", CreateJwkKeyOpsFromWebCryptoUsages(key_usages));
487 } 589 }
488 590
489 // Writes a Web Crypto extractable value to a JWK dictionary. 591 // Writes a Web Crypto extractable value to a JWK dictionary.
490 void WriteExt(bool extractable, base::DictionaryValue* jwk_dict) { 592 void WriteExt(bool extractable, base::DictionaryValue* jwk_dict) {
491 jwk_dict->SetBoolean("ext", extractable); 593 jwk_dict->SetBoolean("ext", extractable);
492 } 594 }
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
585 NOTREACHED(); 687 NOTREACHED();
586 return Status::ErrorUnexpected(); 688 return Status::ErrorUnexpected();
587 } 689 }
588 break; 690 break;
589 default: 691 default:
590 return Status::ErrorUnsupported(); 692 return Status::ErrorUnsupported();
591 } 693 }
592 return Status::Success(); 694 return Status::Success();
593 } 695 }
594 696
595 bool IsRsaPublicKey(const blink::WebCryptoKey& key) { 697 bool IsRsaKey(const blink::WebCryptoKey& key) {
596 if (key.type() != blink::WebCryptoKeyTypePublic)
597 return false;
598 const blink::WebCryptoAlgorithmId algorithm_id = key.algorithm().id(); 698 const blink::WebCryptoAlgorithmId algorithm_id = key.algorithm().id();
599 return algorithm_id == blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5 || 699 return algorithm_id == blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5 ||
600 algorithm_id == blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5 || 700 algorithm_id == blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5 ||
601 algorithm_id == blink::WebCryptoAlgorithmIdRsaOaep; 701 algorithm_id == blink::WebCryptoAlgorithmIdRsaOaep;
602 } 702 }
603 703
604 // TODO(padolph): This function is duplicated in shared_crypto.cc 704 Status ImportRsaKey(base::DictionaryValue* dict,
605 Status ToPlatformPublicKey(const blink::WebCryptoKey& key, 705 const blink::WebCryptoAlgorithm& algorithm,
606 platform::PublicKey** out) { 706 bool extractable,
607 *out = static_cast<platform::Key*>(key.handle())->AsPublicKey(); 707 blink::WebCryptoKeyUsageMask usage_mask,
608 if (!*out) 708 blink::WebCryptoKey* key) {
609 return Status::ErrorUnexpectedKeyType(); 709 // An RSA public key must have an "n" (modulus) and an "e" (exponent) entry
610 return Status::Success(); 710 // in the JWK, while an RSA private key must have those, plus at least a "d"
711 // (private exponent) entry.
712 // See http://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-18,
713 // section 6.3.
714 std::string jwk_n_value;
715 Status status = GetJwkBytes(dict, "n", &jwk_n_value);
716 if (status.IsError())
717 return status;
718 std::string jwk_e_value;
719 status = GetJwkBytes(dict, "e", &jwk_e_value);
720 if (status.IsError())
721 return status;
722
723 if (!dict->HasKey("d")) {
724 return platform::ImportRsaPublicKey(algorithm,
725 extractable,
726 usage_mask,
727 CryptoData(jwk_n_value),
728 CryptoData(jwk_e_value),
729 key);
730 }
731
732 std::string jwk_d_value;
733 status = GetJwkBytes(dict, "d", &jwk_d_value);
734 if (status.IsError())
735 return status;
736
737 // The "p", "q", "dp", "dq", and "qi" properties are optional. Treat these
738 // properties the same if they are unspecified, as if they were specified-but
739 // empty, since ImportRsaPrivateKey() doesn't do validation checks anyway.
740
741 std::string jwk_p_value;
742 bool has_p;
743 status = GetOptionalJwkBytes(dict, "p", &jwk_p_value, &has_p);
744 if (status.IsError())
745 return status;
746
747 std::string jwk_q_value;
748 bool has_q;
749 status = GetOptionalJwkBytes(dict, "q", &jwk_q_value, &has_q);
750 if (status.IsError())
751 return status;
752
753 std::string jwk_dp_value;
754 bool has_dp;
755 status = GetOptionalJwkBytes(dict, "dp", &jwk_dp_value, &has_dp);
756 if (status.IsError())
757 return status;
758
759 std::string jwk_dq_value;
760 bool has_dq;
761 status = GetOptionalJwkBytes(dict, "dq", &jwk_dq_value, &has_dq);
762 if (status.IsError())
763 return status;
764
765 std::string jwk_qi_value;
766 bool has_qi;
767 status = GetOptionalJwkBytes(dict, "qi", &jwk_qi_value, &has_qi);
768 if (status.IsError())
769 return status;
770
771 int num_optional_properties = has_p + has_q + has_dp + has_dq + has_qi;
772 if (num_optional_properties != 0 && num_optional_properties != 5)
773 return Status::ErrorJwkIncompleteOptionalRsaPrivateKey();
774
775 return platform::ImportRsaPrivateKey(
776 algorithm,
777 extractable,
778 usage_mask,
779 CryptoData(jwk_n_value), // modulus
780 CryptoData(jwk_e_value), // public_exponent
781 CryptoData(jwk_d_value), // private_exponent
782 CryptoData(jwk_p_value), // prime1
783 CryptoData(jwk_q_value), // prime2
784 CryptoData(jwk_dp_value), // exponent1
785 CryptoData(jwk_dq_value), // exponent2
786 CryptoData(jwk_qi_value), // coefficient
787 key);
611 } 788 }
612 789
613 } // namespace 790 } // namespace
614 791
792 // TODO(eroman): Split this up into smaller functions.
615 Status ImportKeyJwk(const CryptoData& key_data, 793 Status ImportKeyJwk(const CryptoData& key_data,
616 const blink::WebCryptoAlgorithm& algorithm, 794 const blink::WebCryptoAlgorithm& algorithm,
617 bool extractable, 795 bool extractable,
618 blink::WebCryptoKeyUsageMask usage_mask, 796 blink::WebCryptoKeyUsageMask usage_mask,
619 blink::WebCryptoKey* key) { 797 blink::WebCryptoKey* key) {
620 if (!key_data.byte_length()) 798 if (!key_data.byte_length())
621 return Status::ErrorImportEmptyKeyData(); 799 return Status::ErrorImportEmptyKeyData();
622 DCHECK(key); 800 DCHECK(key);
623 801
624 // Parse the incoming JWK JSON. 802 // Parse the incoming JWK JSON.
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
740 return Status::ErrorJwkIncorrectKeyLength(); 918 return Status::ErrorJwkIncorrectKeyLength();
741 } 919 }
742 920
743 return ImportKey(blink::WebCryptoKeyFormatRaw, 921 return ImportKey(blink::WebCryptoKeyFormatRaw,
744 CryptoData(jwk_k_value), 922 CryptoData(jwk_k_value),
745 algorithm, 923 algorithm,
746 extractable, 924 extractable,
747 usage_mask, 925 usage_mask,
748 key); 926 key);
749 } 927 }
750 if (jwk_kty_value == "RSA") {
751 // An RSA public key must have an "n" (modulus) and an "e" (exponent) entry
752 // in the JWK, while an RSA private key must have those, plus at least a "d"
753 // (private exponent) entry.
754 // See http://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-18,
755 // section 6.3.
756 928
757 // RSA private key import is not currently supported, so fail here if a "d" 929 if (jwk_kty_value == "RSA")
758 // entry is found. 930 return ImportRsaKey(dict_value, algorithm, extractable, usage_mask, key);
759 // TODO(padolph): Support RSA private key import.
760 if (dict_value->HasKey("d"))
761 return Status::ErrorJwkRsaPrivateKeyUnsupported();
762
763 std::string jwk_n_value;
764 status = GetJwkBytes(dict_value, "n", &jwk_n_value);
765 if (status.IsError())
766 return status;
767 std::string jwk_e_value;
768 status = GetJwkBytes(dict_value, "e", &jwk_e_value);
769 if (status.IsError())
770 return status;
771
772 return platform::ImportRsaPublicKey(algorithm,
773 extractable,
774 usage_mask,
775 CryptoData(jwk_n_value),
776 CryptoData(jwk_e_value),
777 key);
778
779 }
780 931
781 return Status::ErrorJwkUnrecognizedKty(); 932 return Status::ErrorJwkUnrecognizedKty();
782 } 933 }
783 934
784 Status ExportKeyJwk(const blink::WebCryptoKey& key, 935 Status ExportKeyJwk(const blink::WebCryptoKey& key,
785 std::vector<uint8>* buffer) { 936 std::vector<uint8>* buffer) {
786 DCHECK(key.extractable()); 937 DCHECK(key.extractable());
787 base::DictionaryValue jwk_dict; 938 base::DictionaryValue jwk_dict;
788 Status status = Status::OperationError(); 939 Status status = Status::OperationError();
789 940
790 switch (key.type()) { 941 switch (key.type()) {
791 case blink::WebCryptoKeyTypeSecret: { 942 case blink::WebCryptoKeyTypeSecret: {
792 std::vector<uint8> exported_key; 943 std::vector<uint8> exported_key;
793 status = ExportKey(blink::WebCryptoKeyFormatRaw, key, &exported_key); 944 status = ExportKey(blink::WebCryptoKeyFormatRaw, key, &exported_key);
794 if (status.IsError()) 945 if (status.IsError())
795 return status; 946 return status;
796 WriteSecretKey(exported_key, &jwk_dict); 947 WriteSecretKey(exported_key, &jwk_dict);
797 break; 948 break;
798 } 949 }
799 case blink::WebCryptoKeyTypePublic: { 950 case blink::WebCryptoKeyTypePublic: {
800 // Currently only RSA public key export is supported. 951 // TODO(eroman): Update when there are asymmetric keys other than RSA.
801 if (!IsRsaPublicKey(key)) 952 if (!IsRsaKey(key))
802 return Status::ErrorUnsupported(); 953 return Status::ErrorUnsupported();
803 platform::PublicKey* public_key; 954 platform::PublicKey* public_key;
804 status = ToPlatformPublicKey(key, &public_key); 955 status = ToPlatformPublicKey(key, &public_key);
805 if (status.IsError()) 956 if (status.IsError())
806 return status; 957 return status;
807 std::vector<uint8> modulus; 958 std::vector<uint8> modulus;
808 std::vector<uint8> public_exponent; 959 std::vector<uint8> public_exponent;
809 status = 960 status =
810 platform::ExportRsaPublicKey(public_key, &modulus, &public_exponent); 961 platform::ExportRsaPublicKey(public_key, &modulus, &public_exponent);
811 if (status.IsError()) 962 if (status.IsError())
812 return status; 963 return status;
813 WriteRsaPublicKey(modulus, public_exponent, &jwk_dict); 964 WriteRsaPublicKey(modulus, public_exponent, &jwk_dict);
814 break; 965 break;
815 } 966 }
816 case blink::WebCryptoKeyTypePrivate: // TODO(padolph) 967 case blink::WebCryptoKeyTypePrivate: {
968 // TODO(eroman): Update when there are asymmetric keys other than RSA.
969 if (!IsRsaKey(key))
970 return Status::ErrorUnsupported();
971
972 status = ExportRsaPrivateKeyJwk(key, &jwk_dict);
973 if (status.IsError())
974 return status;
975 break;
976 }
977
817 default: 978 default:
818 return Status::ErrorUnsupported(); 979 return Status::ErrorUnsupported();
819 } 980 }
820 981
821 WriteKeyOps(key.usages(), &jwk_dict); 982 WriteKeyOps(key.usages(), &jwk_dict);
822 WriteExt(key.extractable(), &jwk_dict); 983 WriteExt(key.extractable(), &jwk_dict);
823 status = WriteAlg(key.algorithm(), &jwk_dict); 984 status = WriteAlg(key.algorithm(), &jwk_dict);
824 if (status.IsError()) 985 if (status.IsError())
825 return status; 986 return status;
826 987
827 std::string json; 988 std::string json;
828 base::JSONWriter::Write(&jwk_dict, &json); 989 base::JSONWriter::Write(&jwk_dict, &json);
829 buffer->assign(json.data(), json.data() + json.size()); 990 buffer->assign(json.data(), json.data() + json.size());
830 return Status::Success(); 991 return Status::Success();
831 } 992 }
832 993
833 } // namespace webcrypto 994 } // namespace webcrypto
834 995
835 } // namespace content 996 } // namespace content
OLDNEW
« no previous file with comments | « no previous file | content/child/webcrypto/platform_crypto.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698