Commit 373f4acf authored by eroman@chromium.org's avatar eroman@chromium.org

[webcrypto] Enable wrap/unwrap for SPKI and PKCS8.

(Does not yet address AES-KW, which is currently only exposed for wrapping/unwrapping of 'raw' format).

BUG=373555,245025

Review URL: https://codereview.chromium.org/299843014

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@273071 0039d316-1c4b-4281-b951-d872f2087c98
parent 8023bc89
...@@ -865,26 +865,15 @@ Status WrapKey(blink::WebCryptoKeyFormat format, ...@@ -865,26 +865,15 @@ Status WrapKey(blink::WebCryptoKeyFormat format,
if (wrapping_algorithm.id() != wrapping_key.algorithm().id()) if (wrapping_algorithm.id() != wrapping_key.algorithm().id())
return Status::ErrorUnexpected(); return Status::ErrorUnexpected();
switch (format) { if (format == blink::WebCryptoKeyFormatRaw &&
case blink::WebCryptoKeyFormatRaw: wrapping_algorithm.id() == blink::WebCryptoAlgorithmIdAesKw) {
if (wrapping_algorithm.id() == blink::WebCryptoAlgorithmIdAesKw) { // AES-KW is a special case, due to NSS's implementation only
// AES-KW is a special case, due to NSS's implementation only // supporting C_Wrap/C_Unwrap with AES-KW
// supporting C_Wrap/C_Unwrap with AES-KW return WrapKeyRaw(key_to_wrap, wrapping_key, wrapping_algorithm, buffer);
return WrapKeyRaw(
key_to_wrap, wrapping_key, wrapping_algorithm, buffer);
}
return WrapKeyExportAndEncrypt(
format, key_to_wrap, wrapping_key, wrapping_algorithm, buffer);
case blink::WebCryptoKeyFormatJwk:
return WrapKeyExportAndEncrypt(
format, key_to_wrap, wrapping_key, wrapping_algorithm, buffer);
case blink::WebCryptoKeyFormatSpki:
case blink::WebCryptoKeyFormatPkcs8:
return Status::ErrorUnsupported(); // TODO(padolph)
default:
NOTREACHED();
return Status::ErrorUnsupported();
} }
return WrapKeyExportAndEncrypt(
format, key_to_wrap, wrapping_key, wrapping_algorithm, buffer);
} }
Status UnwrapKey(blink::WebCryptoKeyFormat format, Status UnwrapKey(blink::WebCryptoKeyFormat format,
...@@ -908,43 +897,27 @@ Status UnwrapKey(blink::WebCryptoKeyFormat format, ...@@ -908,43 +897,27 @@ Status UnwrapKey(blink::WebCryptoKeyFormat format,
if (status.IsError()) if (status.IsError())
return status; return status;
switch (format) { if (format == blink::WebCryptoKeyFormatRaw &&
case blink::WebCryptoKeyFormatRaw: wrapping_algorithm.id() == blink::WebCryptoAlgorithmIdAesKw) {
if (wrapping_algorithm.id() == blink::WebCryptoAlgorithmIdAesKw) { // AES-KW is a special case, due to NSS's implementation only
// AES-KW is a special case, due to NSS's implementation only // supporting C_Wrap/C_Unwrap with AES-KW
// supporting C_Wrap/C_Unwrap with AES-KW return UnwrapKeyRaw(wrapped_key_data,
return UnwrapKeyRaw(wrapped_key_data, wrapping_key,
wrapping_key, wrapping_algorithm,
wrapping_algorithm, algorithm,
algorithm, extractable,
extractable, usage_mask,
usage_mask, key);
key);
}
return UnwrapKeyDecryptAndImport(format,
wrapped_key_data,
wrapping_key,
wrapping_algorithm,
algorithm,
extractable,
usage_mask,
key);
case blink::WebCryptoKeyFormatJwk:
return UnwrapKeyDecryptAndImport(format,
wrapped_key_data,
wrapping_key,
wrapping_algorithm,
algorithm,
extractable,
usage_mask,
key);
case blink::WebCryptoKeyFormatSpki:
case blink::WebCryptoKeyFormatPkcs8:
return Status::ErrorUnsupported(); // TODO(padolph)
default:
NOTREACHED();
return Status::ErrorUnsupported();
} }
return UnwrapKeyDecryptAndImport(format,
wrapped_key_data,
wrapping_key,
wrapping_algorithm,
algorithm,
extractable,
usage_mask,
key);
} }
// Note that this function is called from the target Blink thread. // Note that this function is called from the target Blink thread.
......
...@@ -3960,6 +3960,117 @@ TEST_F(SharedCryptoTest, MAYBE(GenerateRsaSsaKeyPairIntersectUsages)) { ...@@ -3960,6 +3960,117 @@ TEST_F(SharedCryptoTest, MAYBE(GenerateRsaSsaKeyPairIntersectUsages)) {
EXPECT_EQ(blink::WebCryptoKeyUsageSign, private_key.usages()); EXPECT_EQ(blink::WebCryptoKeyUsageSign, private_key.usages());
} }
// Generate an AES-CBC key and an RSA key pair. Use the AES-CBC key to wrap the
// key pair (using SPKI format for public key, PKCS8 format for private key).
// Then unwrap the wrapped key pair and verify that the key data is the same.
TEST_F(SharedCryptoTest, MAYBE(WrapUnwrapRoundtripSpkiPkcs8UsingAesCbc)) {
// Generate the wrapping key.
blink::WebCryptoKey wrapping_key = blink::WebCryptoKey::createNull();
ASSERT_EQ(Status::Success(),
GenerateSecretKey(CreateAesCbcKeyGenAlgorithm(128),
true,
blink::WebCryptoKeyUsageWrapKey |
blink::WebCryptoKeyUsageUnwrapKey,
&wrapping_key));
// Generate an RSA key pair to be wrapped.
const unsigned int modulus_length = 256;
const std::vector<uint8> public_exponent = HexStringToBytes("010001");
blink::WebCryptoKey public_key = blink::WebCryptoKey::createNull();
blink::WebCryptoKey private_key = blink::WebCryptoKey::createNull();
ASSERT_EQ(Status::Success(),
GenerateKeyPair(CreateRsaHashedKeyGenAlgorithm(
blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5,
blink::WebCryptoAlgorithmIdSha256,
modulus_length,
public_exponent),
true,
0,
&public_key,
&private_key));
// Export key pair as SPKI + PKCS8
std::vector<uint8> public_key_spki;
ASSERT_EQ(
Status::Success(),
ExportKey(blink::WebCryptoKeyFormatSpki, public_key, &public_key_spki));
std::vector<uint8> private_key_pkcs8;
ASSERT_EQ(
Status::Success(),
ExportKey(
blink::WebCryptoKeyFormatPkcs8, private_key, &private_key_pkcs8));
// Wrap the key pair.
blink::WebCryptoAlgorithm wrap_algorithm =
CreateAesCbcAlgorithm(std::vector<uint8>(16, 0));
std::vector<uint8> wrapped_public_key;
ASSERT_EQ(Status::Success(),
WrapKey(blink::WebCryptoKeyFormatSpki,
public_key,
wrapping_key,
wrap_algorithm,
&wrapped_public_key));
std::vector<uint8> wrapped_private_key;
ASSERT_EQ(Status::Success(),
WrapKey(blink::WebCryptoKeyFormatPkcs8,
private_key,
wrapping_key,
wrap_algorithm,
&wrapped_private_key));
// Unwrap the key pair.
blink::WebCryptoAlgorithm rsa_import_algorithm =
CreateRsaHashedImportAlgorithm(blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5,
blink::WebCryptoAlgorithmIdSha256);
blink::WebCryptoKey unwrapped_public_key = blink::WebCryptoKey::createNull();
ASSERT_EQ(Status::Success(),
UnwrapKey(blink::WebCryptoKeyFormatSpki,
CryptoData(wrapped_public_key),
wrapping_key,
wrap_algorithm,
rsa_import_algorithm,
true,
0,
&unwrapped_public_key));
blink::WebCryptoKey unwrapped_private_key = blink::WebCryptoKey::createNull();
ASSERT_EQ(Status::Success(),
UnwrapKey(blink::WebCryptoKeyFormatPkcs8,
CryptoData(wrapped_private_key),
wrapping_key,
wrap_algorithm,
rsa_import_algorithm,
true,
0,
&unwrapped_private_key));
// Export unwrapped key pair as SPKI + PKCS8
std::vector<uint8> unwrapped_public_key_spki;
ASSERT_EQ(Status::Success(),
ExportKey(blink::WebCryptoKeyFormatSpki,
unwrapped_public_key,
&unwrapped_public_key_spki));
std::vector<uint8> unwrapped_private_key_pkcs8;
ASSERT_EQ(Status::Success(),
ExportKey(blink::WebCryptoKeyFormatPkcs8,
unwrapped_private_key,
&unwrapped_private_key_pkcs8));
EXPECT_EQ(public_key_spki, unwrapped_public_key_spki);
EXPECT_EQ(private_key_pkcs8, unwrapped_private_key_pkcs8);
EXPECT_NE(public_key_spki, wrapped_public_key);
EXPECT_NE(private_key_pkcs8, wrapped_private_key);
}
} // namespace webcrypto } // namespace webcrypto
} // namespace content } // namespace content
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment