| Index: content/child/webcrypto/jwk.cc
|
| diff --git a/content/child/webcrypto/jwk.cc b/content/child/webcrypto/jwk.cc
|
| index 8e9e11c5de087f42a44047ba9390692d379640f0..16e16fb58b64717fc1721ab91f6178958ad9a2fd 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) {
|
| @@ -308,19 +323,19 @@ void WriteExt(bool extractable, base::DictionaryValue* jwk_dict) {
|
|
|
| // Writes a Web Crypto algorithm to a JWK dictionary.
|
| Status WriteAlg(const blink::WebCryptoKeyAlgorithm& algorithm,
|
| - unsigned int raw_key_length_bytes,
|
| base::DictionaryValue* jwk_dict) {
|
| switch (algorithm.paramsType()) {
|
| case blink::WebCryptoKeyAlgorithmParamsTypeAes: {
|
| + DCHECK(algorithm.aesParams());
|
| const char* aes_prefix = "";
|
| - switch (raw_key_length_bytes) {
|
| - case 16:
|
| + switch (algorithm.aesParams()->lengthBits()) {
|
| + case 128:
|
| aes_prefix = "A128";
|
| break;
|
| - case 24:
|
| + case 192:
|
| aes_prefix = "A192";
|
| break;
|
| - case 32:
|
| + case 256:
|
| aes_prefix = "A256";
|
| break;
|
| default:
|
| @@ -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,44 @@ 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();
|
| + switch (key.type()) {
|
| + case blink::WebCryptoKeyTypeSecret: {
|
| + blink::WebArrayBuffer exported_key;
|
| + status = ExportKey(blink::WebCryptoKeyFormatRaw, key, &exported_key);
|
| + if (status.IsError())
|
| + return status;
|
| + 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;
|
| + std::vector<uint8> 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(), &jwk_dict);
|
| if (status.IsError())
|
| return status;
|
|
|
|
|