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

Unified 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | content/child/webcrypto/platform_crypto.h » ('j') | content/child/webcrypto/platform_crypto.h » ('J')
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: content/child/webcrypto/jwk.cc
diff --git a/content/child/webcrypto/jwk.cc b/content/child/webcrypto/jwk.cc
index 8e9e11c5de087f42a44047ba9390692d379640f0..0f5ab6777424881bba41cd90b5d219dae63607e4 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,32 @@ 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 blink::WebArrayBuffer& modulus,
+ const blink::WebArrayBuffer& public_exponent,
+ base::DictionaryValue* jwk_dict) {
+ DCHECK(jwk_dict);
+ jwk_dict->SetString("kty", "RSA");
+
+ DCHECK(!modulus.isNull());
+ DCHECK(modulus.data());
+ DCHECK(modulus.byteLength());
+ const unsigned int modulus_length_bytes = modulus.byteLength();
+ const base::StringPiece modulus_str(static_cast<const char*>(modulus.data()),
eroman 2014/03/21 02:30:51 There are now 3 places in the code which do this i
padolph 2014/03/24 04:28:28 Done.
+ modulus_length_bytes);
+ jwk_dict->SetString("n", Base64EncodeUrlSafe(modulus_str));
+
+ DCHECK(!public_exponent.isNull());
eroman 2014/03/21 02:30:51 my preference is to put all input dchecks at the t
padolph 2014/03/24 04:28:28 Done.
+ DCHECK(public_exponent.data());
+ DCHECK(public_exponent.byteLength());
+ const unsigned int public_exponent_length_bytes =
+ public_exponent.byteLength();
+ const base::StringPiece public_exponent_str(
+ static_cast<const char*>(public_exponent.data()),
+ public_exponent_length_bytes);
+ jwk_dict->SetString("e", Base64EncodeUrlSafe(public_exponent_str));
+}
+
// Writes a Web Crypto usage mask to a JWK dictionary.
void WriteKeyOps(blink::WebCryptoKeyUsageMask key_usages,
base::DictionaryValue* jwk_dict) {
@@ -370,15 +399,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;
+ case blink::WebCryptoAlgorithmIdRsaOaep:
eroman 2014/03/21 02:30:51 I don't believe this is correct. In WebCrypto RSA
padolph 2014/03/24 04:28:28 Done.
+ jwk_dict->SetString("alg", "RSA-OAEP");
+ 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::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 +553,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 +790,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;
+ 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;
+ blink::WebArrayBuffer modulus, public_exponent;
+ 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;
« no previous file with comments | « no previous file | content/child/webcrypto/platform_crypto.h » ('j') | content/child/webcrypto/platform_crypto.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698