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 <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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |