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

Side by Side Diff: content/renderer/webcrypto/webcrypto_impl.cc

Issue 76363006: [webcrypto] Add JWK import of RSA public key for NSS. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 7 years, 1 month 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 (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 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
126 GetInnerHashAlgorithm(alg2))) { 126 GetInnerHashAlgorithm(alg2))) {
127 return true; 127 return true;
128 } 128 }
129 return false; 129 return false;
130 } 130 }
131 return true; 131 return true;
132 } 132 }
133 return false; 133 return false;
134 } 134 }
135 135
136 bool GetDecodedUrl64ValueByKey(
137 const base::DictionaryValue& dict,
138 const std::string& key,
139 std::string* decoded) {
140 std::string value_url64;
141 if (!dict.GetString(key, &value_url64) ||
142 !Base64DecodeUrlSafe(value_url64, decoded) ||
143 !decoded->size()) {
144 return false;
145 }
146 return true;
147 }
148
136 } // namespace 149 } // namespace
137 150
138 WebCryptoImpl::WebCryptoImpl() { 151 WebCryptoImpl::WebCryptoImpl() {
139 Init(); 152 Init();
140 } 153 }
141 154
142 void WebCryptoImpl::encrypt( 155 void WebCryptoImpl::encrypt(
143 const blink::WebCryptoAlgorithm& algorithm, 156 const blink::WebCryptoAlgorithm& algorithm,
144 const blink::WebCryptoKey& key, 157 const blink::WebCryptoKey& key,
145 const unsigned char* data, 158 const unsigned char* data,
(...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after
476 // inconsistent with input: error 489 // inconsistent with input: error
477 // 4. JWK alg valid AND input algorithm specified, both consistent: use 490 // 4. JWK alg valid AND input algorithm specified, both consistent: use
478 // input value (because it has potentially more details) 491 // input value (because it has potentially more details)
479 // 5. JWK alg missing AND input algorithm isNull: error 492 // 5. JWK alg missing AND input algorithm isNull: error
480 // 6. JWK alg missing AND input algorithm specified: use input value 493 // 6. JWK alg missing AND input algorithm specified: use input value
481 blink::WebCryptoAlgorithm algorithm = 494 blink::WebCryptoAlgorithm algorithm =
482 blink::WebCryptoAlgorithm::createNull(); 495 blink::WebCryptoAlgorithm::createNull();
483 std::string jwk_alg_value; 496 std::string jwk_alg_value;
484 if (dict_value->GetString("alg", &jwk_alg_value)) { 497 if (dict_value->GetString("alg", &jwk_alg_value)) {
485 // JWK alg present 498 // JWK alg present
499
500 // TODO(padolph): Validate alg vs kty. For example kty="RSA" implies alg can
501 // only be from the RSA family.
502
486 const blink::WebCryptoAlgorithm jwk_algorithm = 503 const blink::WebCryptoAlgorithm jwk_algorithm =
487 jwk_alg_factory.Get().CreateAlgorithmFromName(jwk_alg_value); 504 jwk_alg_factory.Get().CreateAlgorithmFromName(jwk_alg_value);
488 if (jwk_algorithm.isNull()) { 505 if (jwk_algorithm.isNull()) {
489 // JWK alg unrecognized 506 // JWK alg unrecognized
490 return false; // case 1 507 return false; // case 1
491 } 508 }
492 // JWK alg valid 509 // JWK alg valid
493 if (algorithm_or_null.isNull()) { 510 if (algorithm_or_null.isNull()) {
494 // input algorithm not specified 511 // input algorithm not specified
495 algorithm = jwk_algorithm; // case 2 512 algorithm = jwk_algorithm; // case 2
(...skipping 28 matching lines...) Expand all
524 return false; 541 return false;
525 } 542 }
526 if ((jwk_usage_mask & usage_mask) != usage_mask) { 543 if ((jwk_usage_mask & usage_mask) != usage_mask) {
527 // A usage_mask must be a subset of jwk_usage_mask. 544 // A usage_mask must be a subset of jwk_usage_mask.
528 return false; 545 return false;
529 } 546 }
530 } 547 }
531 548
532 // JWK keying material --> ImportKeyInternal() 549 // JWK keying material --> ImportKeyInternal()
533 if (jwk_kty_value == "oct") { 550 if (jwk_kty_value == "oct") {
534 std::string jwk_k_value_url64; 551
535 if (!dict_value->GetString("k", &jwk_k_value_url64)) 552 std::string jwk_k_value;
553 if (!GetDecodedUrl64ValueByKey(*dict_value, "k", &jwk_k_value))
536 return false; 554 return false;
537 std::string jwk_k_value;
538 if (!Base64DecodeUrlSafe(jwk_k_value_url64, &jwk_k_value) ||
539 !jwk_k_value.size()) {
540 return false;
541 }
542 555
543 // TODO(padolph): Some JWK alg ID's embed information about the key length 556 // TODO(padolph): Some JWK alg ID's embed information about the key length
544 // in the alg ID string. For example "A128" implies the JWK carries 128 bits 557 // in the alg ID string. For example "A128" implies the JWK carries 128 bits
545 // of key material, and "HS512" implies the JWK carries _at least_ 512 bits 558 // of key material, and "HS512" implies the JWK carries _at least_ 512 bits
546 // of key material. For such keys validate the actual key length against the 559 // of key material. For such keys validate the actual key length against the
547 // value in the ID. 560 // value in the ID.
548 561
549 return ImportKeyInternal(blink::WebCryptoKeyFormatRaw, 562 return ImportKeyInternal(blink::WebCryptoKeyFormatRaw,
550 reinterpret_cast<const uint8*>(jwk_k_value.data()), 563 reinterpret_cast<const uint8*>(jwk_k_value.data()),
551 jwk_k_value.size(), 564 jwk_k_value.size(),
552 algorithm, 565 algorithm,
553 extractable, 566 extractable,
554 usage_mask, 567 usage_mask,
555 key); 568 key);
556 } else if (jwk_kty_value == "RSA") { 569 } else if (jwk_kty_value == "RSA") {
557 // TODO(padolph): JWK import RSA public key 570
558 return false; 571 // An RSA public key must have an "n" (modulus) and an "e" (exponent) entry
572 // in the JWK, while an RSA private key must have those, plus at least a "d"
573 // (private exponent) entry.
574 // See http://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-18,
575 // section 6.3.
576
577 // RSA private key import is not currently supported, so fail here if a "d"
578 // entry is found.
579 // TODO(padolph): Support RSA private key import.
580 if (dict_value->HasKey("d"))
581 return false;
582
583 std::string jwk_n_value;
584 if (!GetDecodedUrl64ValueByKey(*dict_value, "n", &jwk_n_value))
585 return false;
586 std::string jwk_e_value;
587 if (!GetDecodedUrl64ValueByKey(*dict_value, "e", &jwk_e_value))
588 return false;
589
590 return ImportRsaPublicKeyInternal(
591 reinterpret_cast<const uint8*>(jwk_n_value.data()),
592 jwk_n_value.size(),
593 reinterpret_cast<const uint8*>(jwk_e_value.data()),
594 jwk_e_value.size(),
595 algorithm,
596 extractable,
597 usage_mask,
598 key);
599
559 } else { 600 } else {
560 return false; 601 return false;
561 } 602 }
562 603
563 return true; 604 return true;
564 } 605 }
565 606
566 } // namespace content 607 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698