 Chromium Code Reviews
 Chromium Code Reviews Issue 205913002:
  [webcrypto] Add JWK RSA public key export for NSS.  (Closed) 
  Base URL: https://chromium.googlesource.com/chromium/src.git@master
    
  
    Issue 205913002:
  [webcrypto] Add JWK RSA public key export for NSS.  (Closed) 
  Base URL: https://chromium.googlesource.com/chromium/src.git@master| Index: content/child/webcrypto/jwk.cc | 
| diff --git a/content/child/webcrypto/jwk.cc b/content/child/webcrypto/jwk.cc | 
| index 8e9e11c5de087f42a44047ba9390692d379640f0..c8fdfe3400096eebc1610e0a17d5f5e9612f30db 100644 | 
| --- a/content/child/webcrypto/jwk.cc | 
| +++ b/content/child/webcrypto/jwk.cc | 
| @@ -92,6 +92,9 @@ class JwkAlgorithmRegistry { | 
| alg_to_info_["HS512"] = | 
| JwkAlgorithmInfo(&BindAlgorithmId<CreateHmacImportAlgorithm, | 
| blink::WebCryptoAlgorithmIdSha512>); | 
| + alg_to_info_["RS1"] = | 
| + JwkAlgorithmInfo(&BindAlgorithmId<CreateRsaSsaImportAlgorithm, | 
| + blink::WebCryptoAlgorithmIdSha1>); | 
| alg_to_info_["RS256"] = | 
| JwkAlgorithmInfo(&BindAlgorithmId<CreateRsaSsaImportAlgorithm, | 
| blink::WebCryptoAlgorithmIdSha256>); | 
| @@ -295,6 +298,18 @@ void WriteSecretKey(const blink::WebArrayBuffer& raw_key, | 
| jwk_dict->SetString("k", Base64EncodeUrlSafe(key_str)); | 
| } | 
| +// Writes an RSA public key to a JWK dictionary | 
| +void WriteRsaPublicKey(const std::vector<uint8>& modulus, | 
| + const std::vector<uint8>& public_exponent, | 
| + base::DictionaryValue* jwk_dict) { | 
| + DCHECK(jwk_dict); | 
| + DCHECK(modulus.size()); | 
| + DCHECK(public_exponent.size()); | 
| + jwk_dict->SetString("kty", "RSA"); | 
| + jwk_dict->SetString("n", Base64EncodeUrlSafe(modulus)); | 
| + jwk_dict->SetString("e", Base64EncodeUrlSafe(public_exponent)); | 
| +} | 
| + | 
| // Writes a Web Crypto usage mask to a JWK dictionary. | 
| void WriteKeyOps(blink::WebCryptoKeyUsageMask key_usages, | 
| base::DictionaryValue* jwk_dict) { | 
| @@ -370,15 +385,61 @@ Status WriteAlg(const blink::WebCryptoKeyAlgorithm& algorithm, | 
| break; | 
| } | 
| case blink::WebCryptoKeyAlgorithmParamsTypeRsa: | 
| + switch (algorithm.id()) { | 
| + case blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5: | 
| + jwk_dict->SetString("alg", "RSA1_5"); | 
| + break; | 
| + default: | 
| + NOTREACHED(); | 
| + return Status::ErrorUnexpected(); | 
| + } | 
| + break; | 
| case blink::WebCryptoKeyAlgorithmParamsTypeRsaHashed: | 
| - // TODO(padolph): Handle RSA key | 
| - return Status::ErrorUnsupported(); | 
| + switch (algorithm.rsaHashedParams()->hash().id()) { | 
| + case blink::WebCryptoAlgorithmIdRsaOaep: | 
| + jwk_dict->SetString("alg", "RSA-OAEP"); | 
| + break; | 
| + case blink::WebCryptoAlgorithmIdSha1: | 
| + jwk_dict->SetString("alg", "RS1"); | 
| + break; | 
| + case blink::WebCryptoAlgorithmIdSha256: | 
| + jwk_dict->SetString("alg", "RS256"); | 
| + break; | 
| + case blink::WebCryptoAlgorithmIdSha384: | 
| + jwk_dict->SetString("alg", "RS384"); | 
| + break; | 
| + case blink::WebCryptoAlgorithmIdSha512: | 
| + jwk_dict->SetString("alg", "RS512"); | 
| + break; | 
| + default: | 
| + NOTREACHED(); | 
| + return Status::ErrorUnexpected(); | 
| + } | 
| + break; | 
| default: | 
| return Status::ErrorUnsupported(); | 
| } | 
| return Status::Success(); | 
| } | 
| +bool IsRsaPublicKey(const blink::WebCryptoKey& key) { | 
| + if (key.type() != blink::WebCryptoKeyTypePublic) | 
| + return false; | 
| + const blink::WebCryptoAlgorithmId algorithm_id = key.algorithm().id(); | 
| + return algorithm_id == blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5 || | 
| + algorithm_id == blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5 || | 
| + algorithm_id == blink::WebCryptoAlgorithmIdRsaOaep; | 
| +} | 
| + | 
| +// TODO(padolph): This function is duplicated in shared_crypto.cc | 
| +Status ToPlatformPublicKey(const blink::WebCryptoKey& key, | 
| + platform::PublicKey** out) { | 
| + *out = static_cast<platform::Key*>(key.handle())->AsPublicKey(); | 
| + if (!*out) | 
| + return Status::ErrorUnexpectedKeyType(); | 
| + return Status::Success(); | 
| +} | 
| + | 
| } // namespace | 
| Status ImportKeyJwk(const CryptoData& key_data, | 
| @@ -478,6 +539,7 @@ Status ImportKeyJwk(const CryptoData& key_data, | 
| // | "HS256" | HMAC using SHA-256 hash algorithm | | 
| // | "HS384" | HMAC using SHA-384 hash algorithm | | 
| // | "HS512" | HMAC using SHA-512 hash algorithm | | 
| + // | "RS1" | RSASSA using SHA-1 hash algorithm | 
| // | "RS256" | RSASSA using SHA-256 hash algorithm | | 
| // | "RS384" | RSASSA using SHA-384 hash algorithm | | 
| // | "RS512" | RSASSA using SHA-512 hash algorithm | | 
| @@ -714,23 +776,45 @@ Status ImportKeyJwk(const CryptoData& key_data, | 
| Status ExportKeyJwk(const blink::WebCryptoKey& key, | 
| blink::WebArrayBuffer* buffer) { | 
| + DCHECK(key.extractable()); | 
| base::DictionaryValue jwk_dict; | 
| Status status = Status::Error(); | 
| - blink::WebArrayBuffer exported_key; | 
| - if (key.type() == blink::WebCryptoKeyTypeSecret) { | 
| - status = ExportKey(blink::WebCryptoKeyFormatRaw, key, &exported_key); | 
| - if (status.IsError()) | 
| - return status; | 
| - WriteSecretKey(exported_key, &jwk_dict); | 
| - } else { | 
| - // TODO(padolph): Handle asymmetric keys, at least the public key. | 
| - return Status::ErrorUnsupported(); | 
| + 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.
 | 
| + switch (key.type()) { | 
| + case blink::WebCryptoKeyTypeSecret: { | 
| + blink::WebArrayBuffer exported_key; | 
| + status = ExportKey(blink::WebCryptoKeyFormatRaw, key, &exported_key); | 
| + if (status.IsError()) | 
| + return status; | 
| + key_length_bytes = exported_key.byteLength(); | 
| + WriteSecretKey(exported_key, &jwk_dict); | 
| + break; | 
| + } | 
| + case blink::WebCryptoKeyTypePublic: { | 
| + // Currently only RSA public key export is supported. | 
| + if (!IsRsaPublicKey(key)) | 
| + return Status::ErrorUnsupported(); | 
| + platform::PublicKey* public_key; | 
| + status = ToPlatformPublicKey(key, &public_key); | 
| + if (status.IsError()) | 
| + return status; | 
| + 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.
 | 
| + status = | 
| + platform::ExportRsaPublicKey(public_key, &modulus, &public_exponent); | 
| + if (status.IsError()) | 
| + return status; | 
| + WriteRsaPublicKey(modulus, public_exponent, &jwk_dict); | 
| + break; | 
| + } | 
| + case blink::WebCryptoKeyTypePrivate: // TODO(padolph) | 
| + default: | 
| + return Status::ErrorUnsupported(); | 
| } | 
| WriteKeyOps(key.usages(), &jwk_dict); | 
| WriteExt(key.extractable(), &jwk_dict); | 
| - status = WriteAlg(key.algorithm(), exported_key.byteLength(), &jwk_dict); | 
| + status = WriteAlg(key.algorithm(), key_length_bytes, &jwk_dict); | 
| if (status.IsError()) | 
| return status; |