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

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

Issue 205913002: [webcrypto] Add JWK RSA public key export for NSS. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebase Created 6 years, 9 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
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 <algorithm> 5 #include <algorithm>
6 #include <functional> 6 #include <functional>
7 #include <map> 7 #include <map>
8 #include "base/json/json_reader.h" 8 #include "base/json/json_reader.h"
9 #include "base/json/json_writer.h" 9 #include "base/json/json_writer.h"
10 #include "base/lazy_instance.h" 10 #include "base/lazy_instance.h"
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
85 blink::WebCryptoAlgorithmIdSha1>); 85 blink::WebCryptoAlgorithmIdSha1>);
86 alg_to_info_["HS256"] = 86 alg_to_info_["HS256"] =
87 JwkAlgorithmInfo(&BindAlgorithmId<CreateHmacImportAlgorithm, 87 JwkAlgorithmInfo(&BindAlgorithmId<CreateHmacImportAlgorithm,
88 blink::WebCryptoAlgorithmIdSha256>); 88 blink::WebCryptoAlgorithmIdSha256>);
89 alg_to_info_["HS384"] = 89 alg_to_info_["HS384"] =
90 JwkAlgorithmInfo(&BindAlgorithmId<CreateHmacImportAlgorithm, 90 JwkAlgorithmInfo(&BindAlgorithmId<CreateHmacImportAlgorithm,
91 blink::WebCryptoAlgorithmIdSha384>); 91 blink::WebCryptoAlgorithmIdSha384>);
92 alg_to_info_["HS512"] = 92 alg_to_info_["HS512"] =
93 JwkAlgorithmInfo(&BindAlgorithmId<CreateHmacImportAlgorithm, 93 JwkAlgorithmInfo(&BindAlgorithmId<CreateHmacImportAlgorithm,
94 blink::WebCryptoAlgorithmIdSha512>); 94 blink::WebCryptoAlgorithmIdSha512>);
95 alg_to_info_["RS1"] =
96 JwkAlgorithmInfo(&BindAlgorithmId<CreateRsaSsaImportAlgorithm,
97 blink::WebCryptoAlgorithmIdSha1>);
95 alg_to_info_["RS256"] = 98 alg_to_info_["RS256"] =
96 JwkAlgorithmInfo(&BindAlgorithmId<CreateRsaSsaImportAlgorithm, 99 JwkAlgorithmInfo(&BindAlgorithmId<CreateRsaSsaImportAlgorithm,
97 blink::WebCryptoAlgorithmIdSha256>); 100 blink::WebCryptoAlgorithmIdSha256>);
98 alg_to_info_["RS384"] = 101 alg_to_info_["RS384"] =
99 JwkAlgorithmInfo(&BindAlgorithmId<CreateRsaSsaImportAlgorithm, 102 JwkAlgorithmInfo(&BindAlgorithmId<CreateRsaSsaImportAlgorithm,
100 blink::WebCryptoAlgorithmIdSha384>); 103 blink::WebCryptoAlgorithmIdSha384>);
101 alg_to_info_["RS512"] = 104 alg_to_info_["RS512"] =
102 JwkAlgorithmInfo(&BindAlgorithmId<CreateRsaSsaImportAlgorithm, 105 JwkAlgorithmInfo(&BindAlgorithmId<CreateRsaSsaImportAlgorithm,
103 blink::WebCryptoAlgorithmIdSha512>); 106 blink::WebCryptoAlgorithmIdSha512>);
104 alg_to_info_["RSA1_5"] = JwkAlgorithmInfo( 107 alg_to_info_["RSA1_5"] = JwkAlgorithmInfo(
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after
288 // base64url encoding of the raw key. 291 // base64url encoding of the raw key.
289 DCHECK(!raw_key.isNull()); 292 DCHECK(!raw_key.isNull());
290 DCHECK(raw_key.data()); 293 DCHECK(raw_key.data());
291 DCHECK(raw_key.byteLength()); 294 DCHECK(raw_key.byteLength());
292 unsigned int key_length_bytes = raw_key.byteLength(); 295 unsigned int key_length_bytes = raw_key.byteLength();
293 const base::StringPiece key_str(static_cast<const char*>(raw_key.data()), 296 const base::StringPiece key_str(static_cast<const char*>(raw_key.data()),
294 key_length_bytes); 297 key_length_bytes);
295 jwk_dict->SetString("k", Base64EncodeUrlSafe(key_str)); 298 jwk_dict->SetString("k", Base64EncodeUrlSafe(key_str));
296 } 299 }
297 300
301 // Writes an RSA public key to a JWK dictionary
302 void WriteRsaPublicKey(const std::vector<uint8>& modulus,
303 const std::vector<uint8>& public_exponent,
304 base::DictionaryValue* jwk_dict) {
305 DCHECK(jwk_dict);
306 DCHECK(modulus.size());
307 DCHECK(public_exponent.size());
308 jwk_dict->SetString("kty", "RSA");
309 jwk_dict->SetString("n", Base64EncodeUrlSafe(modulus));
310 jwk_dict->SetString("e", Base64EncodeUrlSafe(public_exponent));
311 }
312
298 // Writes a Web Crypto usage mask to a JWK dictionary. 313 // Writes a Web Crypto usage mask to a JWK dictionary.
299 void WriteKeyOps(blink::WebCryptoKeyUsageMask key_usages, 314 void WriteKeyOps(blink::WebCryptoKeyUsageMask key_usages,
300 base::DictionaryValue* jwk_dict) { 315 base::DictionaryValue* jwk_dict) {
301 jwk_dict->Set("key_ops", CreateJwkKeyOpsFromWebCryptoUsages(key_usages)); 316 jwk_dict->Set("key_ops", CreateJwkKeyOpsFromWebCryptoUsages(key_usages));
302 } 317 }
303 318
304 // Writes a Web Crypto extractable value to a JWK dictionary. 319 // Writes a Web Crypto extractable value to a JWK dictionary.
305 void WriteExt(bool extractable, base::DictionaryValue* jwk_dict) { 320 void WriteExt(bool extractable, base::DictionaryValue* jwk_dict) {
306 jwk_dict->SetBoolean("ext", extractable); 321 jwk_dict->SetBoolean("ext", extractable);
307 } 322 }
308 323
309 // Writes a Web Crypto algorithm to a JWK dictionary. 324 // Writes a Web Crypto algorithm to a JWK dictionary.
310 Status WriteAlg(const blink::WebCryptoKeyAlgorithm& algorithm, 325 Status WriteAlg(const blink::WebCryptoKeyAlgorithm& algorithm,
311 unsigned int raw_key_length_bytes, 326 unsigned int raw_key_length_bytes,
eroman 2014/03/24 22:05:51 Please delete this parameter (makes the caller ugl
padolph 2014/03/25 01:10:28 Done.
312 base::DictionaryValue* jwk_dict) { 327 base::DictionaryValue* jwk_dict) {
313 switch (algorithm.paramsType()) { 328 switch (algorithm.paramsType()) {
314 case blink::WebCryptoKeyAlgorithmParamsTypeAes: { 329 case blink::WebCryptoKeyAlgorithmParamsTypeAes: {
315 const char* aes_prefix = ""; 330 const char* aes_prefix = "";
316 switch (raw_key_length_bytes) { 331 switch (raw_key_length_bytes) {
eroman 2014/03/24 22:05:51 Instead we can use: algorithm.aesParams()->length
padolph 2014/03/25 01:10:28 Done.
317 case 16: 332 case 16:
318 aes_prefix = "A128"; 333 aes_prefix = "A128";
319 break; 334 break;
320 case 24: 335 case 24:
321 aes_prefix = "A192"; 336 aes_prefix = "A192";
322 break; 337 break;
323 case 32: 338 case 32:
324 aes_prefix = "A256"; 339 aes_prefix = "A256";
325 break; 340 break;
326 default: 341 default:
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
363 case blink::WebCryptoAlgorithmIdSha512: 378 case blink::WebCryptoAlgorithmIdSha512:
364 jwk_dict->SetString("alg", "HS512"); 379 jwk_dict->SetString("alg", "HS512");
365 break; 380 break;
366 default: 381 default:
367 NOTREACHED(); 382 NOTREACHED();
368 return Status::ErrorUnexpected(); 383 return Status::ErrorUnexpected();
369 } 384 }
370 break; 385 break;
371 } 386 }
372 case blink::WebCryptoKeyAlgorithmParamsTypeRsa: 387 case blink::WebCryptoKeyAlgorithmParamsTypeRsa:
388 switch (algorithm.id()) {
389 case blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5:
390 jwk_dict->SetString("alg", "RSA1_5");
391 break;
392 default:
393 NOTREACHED();
394 return Status::ErrorUnexpected();
395 }
396 break;
373 case blink::WebCryptoKeyAlgorithmParamsTypeRsaHashed: 397 case blink::WebCryptoKeyAlgorithmParamsTypeRsaHashed:
374 // TODO(padolph): Handle RSA key 398 switch (algorithm.rsaHashedParams()->hash().id()) {
375 return Status::ErrorUnsupported(); 399 case blink::WebCryptoAlgorithmIdRsaOaep:
400 jwk_dict->SetString("alg", "RSA-OAEP");
401 break;
402 case blink::WebCryptoAlgorithmIdSha1:
403 jwk_dict->SetString("alg", "RS1");
404 break;
405 case blink::WebCryptoAlgorithmIdSha256:
406 jwk_dict->SetString("alg", "RS256");
407 break;
408 case blink::WebCryptoAlgorithmIdSha384:
409 jwk_dict->SetString("alg", "RS384");
410 break;
411 case blink::WebCryptoAlgorithmIdSha512:
412 jwk_dict->SetString("alg", "RS512");
413 break;
414 default:
415 NOTREACHED();
416 return Status::ErrorUnexpected();
417 }
418 break;
376 default: 419 default:
377 return Status::ErrorUnsupported(); 420 return Status::ErrorUnsupported();
378 } 421 }
379 return Status::Success(); 422 return Status::Success();
380 } 423 }
381 424
425 bool IsRsaPublicKey(const blink::WebCryptoKey& key) {
426 if (key.type() != blink::WebCryptoKeyTypePublic)
427 return false;
428 const blink::WebCryptoAlgorithmId algorithm_id = key.algorithm().id();
429 return algorithm_id == blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5 ||
430 algorithm_id == blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5 ||
431 algorithm_id == blink::WebCryptoAlgorithmIdRsaOaep;
432 }
433
434 // TODO(padolph): This function is duplicated in shared_crypto.cc
435 Status ToPlatformPublicKey(const blink::WebCryptoKey& key,
436 platform::PublicKey** out) {
437 *out = static_cast<platform::Key*>(key.handle())->AsPublicKey();
438 if (!*out)
439 return Status::ErrorUnexpectedKeyType();
440 return Status::Success();
441 }
442
382 } // namespace 443 } // namespace
383 444
384 Status ImportKeyJwk(const CryptoData& key_data, 445 Status ImportKeyJwk(const CryptoData& key_data,
385 const blink::WebCryptoAlgorithm& algorithm, 446 const blink::WebCryptoAlgorithm& algorithm,
386 bool extractable, 447 bool extractable,
387 blink::WebCryptoKeyUsageMask usage_mask, 448 blink::WebCryptoKeyUsageMask usage_mask,
388 blink::WebCryptoKey* key) { 449 blink::WebCryptoKey* key) {
389 // TODO(padolph): Generalize this comment to include export, and move to top 450 // TODO(padolph): Generalize this comment to include export, and move to top
390 // of file. 451 // of file.
391 452
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
471 // 532 //
472 // - alg (Algorithm) 533 // - alg (Algorithm)
473 // See http://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-18 534 // See http://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-18
474 // +--------------+-------------------------------------------------------+ 535 // +--------------+-------------------------------------------------------+
475 // | Digital Signature or MAC Algorithm | 536 // | Digital Signature or MAC Algorithm |
476 // +--------------+-------------------------------------------------------+ 537 // +--------------+-------------------------------------------------------+
477 // | "HS1" | HMAC using SHA-1 hash algorithm | 538 // | "HS1" | HMAC using SHA-1 hash algorithm |
478 // | "HS256" | HMAC using SHA-256 hash algorithm | 539 // | "HS256" | HMAC using SHA-256 hash algorithm |
479 // | "HS384" | HMAC using SHA-384 hash algorithm | 540 // | "HS384" | HMAC using SHA-384 hash algorithm |
480 // | "HS512" | HMAC using SHA-512 hash algorithm | 541 // | "HS512" | HMAC using SHA-512 hash algorithm |
542 // | "RS1" | RSASSA using SHA-1 hash algorithm
481 // | "RS256" | RSASSA using SHA-256 hash algorithm | 543 // | "RS256" | RSASSA using SHA-256 hash algorithm |
482 // | "RS384" | RSASSA using SHA-384 hash algorithm | 544 // | "RS384" | RSASSA using SHA-384 hash algorithm |
483 // | "RS512" | RSASSA using SHA-512 hash algorithm | 545 // | "RS512" | RSASSA using SHA-512 hash algorithm |
484 // +--------------+-------------------------------------------------------| 546 // +--------------+-------------------------------------------------------|
485 // | Key Management Algorithm | 547 // | Key Management Algorithm |
486 // +--------------+-------------------------------------------------------+ 548 // +--------------+-------------------------------------------------------+
487 // | "RSA1_5" | RSAES-PKCS1-V1_5 [RFC3447] | 549 // | "RSA1_5" | RSAES-PKCS1-V1_5 [RFC3447] |
488 // | "RSA-OAEP" | RSAES using Optimal Asymmetric Encryption Padding | 550 // | "RSA-OAEP" | RSAES using Optimal Asymmetric Encryption Padding |
489 // | | (OAEP) [RFC3447], with the default parameters | 551 // | | (OAEP) [RFC3447], with the default parameters |
490 // | | specified by RFC3447 in Section A.2.1 | 552 // | | specified by RFC3447 in Section A.2.1 |
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after
707 CryptoData(jwk_e_value), 769 CryptoData(jwk_e_value),
708 key); 770 key);
709 771
710 } 772 }
711 773
712 return Status::ErrorJwkUnrecognizedKty(); 774 return Status::ErrorJwkUnrecognizedKty();
713 } 775 }
714 776
715 Status ExportKeyJwk(const blink::WebCryptoKey& key, 777 Status ExportKeyJwk(const blink::WebCryptoKey& key,
716 blink::WebArrayBuffer* buffer) { 778 blink::WebArrayBuffer* buffer) {
779 DCHECK(key.extractable());
717 base::DictionaryValue jwk_dict; 780 base::DictionaryValue jwk_dict;
718 Status status = Status::Error(); 781 Status status = Status::Error();
719 blink::WebArrayBuffer exported_key;
720 782
721 if (key.type() == blink::WebCryptoKeyTypeSecret) { 783 unsigned int key_length_bytes = 0;
eroman 2014/03/24 22:05:51 Delete this variable WriteAlg() no longer needs it
padolph 2014/03/25 01:10:28 Done.
722 status = ExportKey(blink::WebCryptoKeyFormatRaw, key, &exported_key); 784 switch (key.type()) {
723 if (status.IsError()) 785 case blink::WebCryptoKeyTypeSecret: {
724 return status; 786 blink::WebArrayBuffer exported_key;
725 WriteSecretKey(exported_key, &jwk_dict); 787 status = ExportKey(blink::WebCryptoKeyFormatRaw, key, &exported_key);
726 } else { 788 if (status.IsError())
727 // TODO(padolph): Handle asymmetric keys, at least the public key. 789 return status;
728 return Status::ErrorUnsupported(); 790 key_length_bytes = exported_key.byteLength();
791 WriteSecretKey(exported_key, &jwk_dict);
792 break;
793 }
794 case blink::WebCryptoKeyTypePublic: {
795 // Currently only RSA public key export is supported.
796 if (!IsRsaPublicKey(key))
797 return Status::ErrorUnsupported();
798 platform::PublicKey* public_key;
799 status = ToPlatformPublicKey(key, &public_key);
800 if (status.IsError())
801 return status;
802 std::vector<uint8> modulus, public_exponent;
eroman 2014/03/24 22:05:51 Please put these on two separate lines: std::vect
padolph 2014/03/25 01:10:28 Done.
803 status =
804 platform::ExportRsaPublicKey(public_key, &modulus, &public_exponent);
805 if (status.IsError())
806 return status;
807 WriteRsaPublicKey(modulus, public_exponent, &jwk_dict);
808 break;
809 }
810 case blink::WebCryptoKeyTypePrivate: // TODO(padolph)
811 default:
812 return Status::ErrorUnsupported();
729 } 813 }
730 814
731 WriteKeyOps(key.usages(), &jwk_dict); 815 WriteKeyOps(key.usages(), &jwk_dict);
732 WriteExt(key.extractable(), &jwk_dict); 816 WriteExt(key.extractable(), &jwk_dict);
733 status = WriteAlg(key.algorithm(), exported_key.byteLength(), &jwk_dict); 817 status = WriteAlg(key.algorithm(), key_length_bytes, &jwk_dict);
734 if (status.IsError()) 818 if (status.IsError())
735 return status; 819 return status;
736 820
737 std::string json; 821 std::string json;
738 base::JSONWriter::Write(&jwk_dict, &json); 822 base::JSONWriter::Write(&jwk_dict, &json);
739 *buffer = CreateArrayBuffer(reinterpret_cast<const uint8*>(json.data()), 823 *buffer = CreateArrayBuffer(reinterpret_cast<const uint8*>(json.data()),
740 json.size()); 824 json.size());
741 return Status::Success(); 825 return Status::Success();
742 } 826 }
743 827
744 } // namespace webcrypto 828 } // namespace webcrypto
745 829
746 } // namespace content 830 } // namespace content
OLDNEW
« no previous file with comments | « no previous file | content/child/webcrypto/platform_crypto.h » ('j') | content/child/webcrypto/platform_crypto_nss.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698