Index: content/child/webcrypto/openssl/rsa_key_openssl.cc |
diff --git a/content/child/webcrypto/openssl/rsa_key_openssl.cc b/content/child/webcrypto/openssl/rsa_key_openssl.cc |
index 554b55c726857846d1b07a4fede0863dc5f622e7..3527770d9f82d5832fc1bd463bdf32f524381c9b 100644 |
--- a/content/child/webcrypto/openssl/rsa_key_openssl.cc |
+++ b/content/child/webcrypto/openssl/rsa_key_openssl.cc |
@@ -5,7 +5,6 @@ |
#include "content/child/webcrypto/openssl/rsa_key_openssl.h" |
#include <openssl/evp.h> |
-#include <openssl/pkcs12.h> |
#include "base/logging.h" |
#include "base/stl_util.h" |
@@ -13,6 +12,7 @@ |
#include "content/child/webcrypto/generate_key_result.h" |
#include "content/child/webcrypto/jwk.h" |
#include "content/child/webcrypto/openssl/key_openssl.h" |
+#include "content/child/webcrypto/openssl/util_openssl.h" |
#include "content/child/webcrypto/status.h" |
#include "content/child/webcrypto/webcrypto_util.h" |
#include "crypto/openssl_util.h" |
@@ -26,42 +26,6 @@ namespace webcrypto { |
namespace { |
-Status ExportPKeySpki(EVP_PKEY* key, std::vector<uint8_t>* buffer) { |
- crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE); |
- crypto::ScopedBIO bio(BIO_new(BIO_s_mem())); |
- |
- // TODO(eroman): Use the OID specified by webcrypto spec. |
- // http://crbug.com/373545 |
- if (!i2d_PUBKEY_bio(bio.get(), key)) |
- return Status::ErrorUnexpected(); |
- |
- char* data = NULL; |
- long len = BIO_get_mem_data(bio.get(), &data); |
- if (!data || len < 0) |
- return Status::ErrorUnexpected(); |
- |
- buffer->assign(data, data + len); |
- return Status::Success(); |
-} |
- |
-Status ExportPKeyPkcs8(EVP_PKEY* key, std::vector<uint8_t>* buffer) { |
- crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE); |
- crypto::ScopedBIO bio(BIO_new(BIO_s_mem())); |
- |
- // TODO(eroman): Use the OID specified by webcrypto spec. |
- // http://crbug.com/373545 |
- if (!i2d_PKCS8PrivateKeyInfo_bio(bio.get(), key)) |
- return Status::ErrorUnexpected(); |
- |
- char* data = NULL; |
- long len = BIO_get_mem_data(bio.get(), &data); |
- if (!data || len < 0) |
- return Status::ErrorUnexpected(); |
- |
- buffer->assign(data, data + len); |
- return Status::Success(); |
-} |
- |
// Creates a blink::WebCryptoAlgorithm having the modulus length and public |
// exponent of |key|. |
Status CreateRsaHashedKeyAlgorithm( |
@@ -90,7 +54,8 @@ Status CreateRsaHashedKeyAlgorithm( |
return Status::Success(); |
} |
-Status CreateWebCryptoPrivateKey( |
+// Creates a WebCryptoKey that wraps |private_key|. |
+Status CreateWebCryptoRsaPrivateKey( |
crypto::ScopedEVP_PKEY private_key, |
const blink::WebCryptoAlgorithmId rsa_algorithm_id, |
const blink::WebCryptoAlgorithm& hash, |
@@ -103,23 +68,12 @@ Status CreateWebCryptoPrivateKey( |
if (status.IsError()) |
return status; |
- // Serialize the key at creation time so that if structured cloning is |
- // requested it can be done synchronously from the Blink thread. |
- std::vector<uint8_t> pkcs8_data; |
- status = ExportPKeyPkcs8(private_key.get(), &pkcs8_data); |
- if (status.IsError()) |
- return status; |
- |
- *key = blink::WebCryptoKey::create( |
- new AsymKeyOpenSsl(private_key.Pass(), CryptoData(pkcs8_data)), |
- blink::WebCryptoKeyTypePrivate, |
- extractable, |
- key_algorithm, |
- usages); |
- return Status::Success(); |
+ return CreateWebCryptoPrivateKey(private_key.Pass(), key_algorithm, |
+ extractable, usages, key); |
} |
-Status CreateWebCryptoPublicKey( |
+// Creates a WebCryptoKey that wraps |public_key|. |
+Status CreateWebCryptoRsaPublicKey( |
crypto::ScopedEVP_PKEY public_key, |
const blink::WebCryptoAlgorithmId rsa_algorithm_id, |
const blink::WebCryptoAlgorithm& hash, |
@@ -132,20 +86,8 @@ Status CreateWebCryptoPublicKey( |
if (status.IsError()) |
return status; |
- // Serialize the key at creation time so that if structured cloning is |
- // requested it can be done synchronously from the Blink thread. |
- std::vector<uint8_t> spki_data; |
- status = ExportPKeySpki(public_key.get(), &spki_data); |
- if (status.IsError()) |
- return status; |
- |
- *key = blink::WebCryptoKey::create( |
- new AsymKeyOpenSsl(public_key.Pass(), CryptoData(spki_data)), |
- blink::WebCryptoKeyTypePublic, |
- extractable, |
- key_algorithm, |
- usages); |
- return Status::Success(); |
+ return CreateWebCryptoPublicKey(public_key.Pass(), key_algorithm, extractable, |
+ usages, key); |
} |
// Converts a BIGNUM to a big endian byte array. |
@@ -191,12 +133,9 @@ Status ImportRsaPrivateKey(const blink::WebCryptoAlgorithm& algorithm, |
if (!pkey || !EVP_PKEY_set1_RSA(pkey.get(), rsa.get())) |
return Status::OperationError(); |
- return CreateWebCryptoPrivateKey(pkey.Pass(), |
- algorithm.id(), |
- algorithm.rsaHashedImportParams()->hash(), |
- extractable, |
- usages, |
- key); |
+ return CreateWebCryptoRsaPrivateKey(pkey.Pass(), algorithm.id(), |
+ algorithm.rsaHashedImportParams()->hash(), |
+ extractable, usages, key); |
} |
Status ImportRsaPublicKey(const blink::WebCryptoAlgorithm& algorithm, |
@@ -218,12 +157,9 @@ Status ImportRsaPublicKey(const blink::WebCryptoAlgorithm& algorithm, |
if (!pkey || !EVP_PKEY_set1_RSA(pkey.get(), rsa.get())) |
return Status::OperationError(); |
- return CreateWebCryptoPublicKey(pkey.Pass(), |
- algorithm.id(), |
- algorithm.rsaHashedImportParams()->hash(), |
- extractable, |
- usages, |
- key); |
+ return CreateWebCryptoRsaPublicKey(pkey.Pass(), algorithm.id(), |
+ algorithm.rsaHashedImportParams()->hash(), |
+ extractable, usages, key); |
} |
} // namespace |
@@ -288,21 +224,15 @@ Status RsaHashedAlgorithm::GenerateKey( |
// Note that extractable is unconditionally set to true. This is because per |
// the WebCrypto spec generated public keys are always public. |
- status = CreateWebCryptoPublicKey(public_pkey.Pass(), |
- algorithm.id(), |
- params->hash(), |
- true, |
- public_usages, |
- &public_key); |
+ status = CreateWebCryptoRsaPublicKey(public_pkey.Pass(), algorithm.id(), |
+ params->hash(), true, public_usages, |
+ &public_key); |
if (status.IsError()) |
return status; |
- status = CreateWebCryptoPrivateKey(private_pkey.Pass(), |
- algorithm.id(), |
- params->hash(), |
- extractable, |
- private_usages, |
- &private_key); |
+ status = CreateWebCryptoRsaPrivateKey(private_pkey.Pass(), algorithm.id(), |
+ params->hash(), extractable, |
+ private_usages, &private_key); |
if (status.IsError()) |
return status; |
@@ -322,10 +252,8 @@ Status RsaHashedAlgorithm::VerifyKeyUsagesBeforeImportKey( |
// The JWK could represent either a public key or private key. The usages |
// must make sense for one of the two. The usages will be checked again by |
// ImportKeyJwk() once the key type has been determined. |
- if (CheckKeyCreationUsages(all_private_key_usages_, usages) |
- .IsSuccess() || |
- CheckKeyCreationUsages(all_public_key_usages_, usages) |
- .IsSuccess()) { |
+ if (CheckKeyCreationUsages(all_private_key_usages_, usages).IsSuccess() || |
+ CheckKeyCreationUsages(all_public_key_usages_, usages).IsSuccess()) { |
return Status::Success(); |
} |
return Status::ErrorCreateKeyBadUsages(); |
@@ -340,30 +268,13 @@ Status RsaHashedAlgorithm::ImportKeyPkcs8( |
bool extractable, |
blink::WebCryptoKeyUsageMask usages, |
blink::WebCryptoKey* key) const { |
- if (!key_data.byte_length()) |
- return Status::ErrorImportEmptyKeyData(); |
- |
- crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE); |
- |
- crypto::ScopedBIO bio(BIO_new_mem_buf(const_cast<uint8_t*>(key_data.bytes()), |
- key_data.byte_length())); |
- if (!bio.get()) |
- return Status::ErrorUnexpected(); |
- |
- crypto::ScopedOpenSSL<PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO_free>::Type |
- p8inf(d2i_PKCS8_PRIV_KEY_INFO_bio(bio.get(), NULL)); |
- if (!p8inf.get()) |
- return Status::DataError(); |
- |
- crypto::ScopedEVP_PKEY private_key(EVP_PKCS82PKEY(p8inf.get())); |
- if (!private_key.get()) |
- return Status::DataError(); |
- |
- if (EVP_PKEY_id(private_key.get()) != EVP_PKEY_RSA) |
- return Status::DataError(); // Data did not define an RSA key. |
+ crypto::ScopedEVP_PKEY private_key; |
+ Status status = |
+ ImportUnverifiedPkeyFromPkcs8(key_data, EVP_PKEY_RSA, &private_key); |
+ if (status.IsError()) |
+ return status; |
- // Verify the parameters of the key (because EVP_PKCS82PKEY() happily imports |
- // invalid keys). |
+ // Verify the parameters of the key. |
crypto::ScopedRSA rsa(EVP_PKEY_get1_RSA(private_key.get())); |
if (!rsa.get()) |
return Status::ErrorUnexpected(); |
@@ -373,12 +284,9 @@ Status RsaHashedAlgorithm::ImportKeyPkcs8( |
// TODO(eroman): Validate the algorithm OID against the webcrypto provided |
// hash. http://crbug.com/389400 |
- return CreateWebCryptoPrivateKey(private_key.Pass(), |
- algorithm.id(), |
- algorithm.rsaHashedImportParams()->hash(), |
- extractable, |
- usages, |
- key); |
+ return CreateWebCryptoRsaPrivateKey(private_key.Pass(), algorithm.id(), |
+ algorithm.rsaHashedImportParams()->hash(), |
+ extractable, usages, key); |
} |
Status RsaHashedAlgorithm::ImportKeySpki( |
@@ -387,32 +295,18 @@ Status RsaHashedAlgorithm::ImportKeySpki( |
bool extractable, |
blink::WebCryptoKeyUsageMask usages, |
blink::WebCryptoKey* key) const { |
- if (!key_data.byte_length()) |
- return Status::ErrorImportEmptyKeyData(); |
- |
- crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE); |
- |
- crypto::ScopedBIO bio(BIO_new_mem_buf(const_cast<uint8_t*>(key_data.bytes()), |
- key_data.byte_length())); |
- if (!bio.get()) |
- return Status::ErrorUnexpected(); |
- |
- crypto::ScopedEVP_PKEY public_key(d2i_PUBKEY_bio(bio.get(), NULL)); |
- if (!public_key.get()) |
- return Status::DataError(); |
- |
- if (EVP_PKEY_id(public_key.get()) != EVP_PKEY_RSA) |
- return Status::DataError(); // Data did not define an RSA key. |
+ crypto::ScopedEVP_PKEY public_key; |
+ Status status = |
+ ImportUnverifiedPkeyFromSpki(key_data, EVP_PKEY_RSA, &public_key); |
+ if (status.IsError()) |
+ return status; |
// TODO(eroman): Validate the algorithm OID against the webcrypto provided |
// hash. http://crbug.com/389400 |
- return CreateWebCryptoPublicKey(public_key.Pass(), |
- algorithm.id(), |
- algorithm.rsaHashedImportParams()->hash(), |
- extractable, |
- usages, |
- key); |
+ return CreateWebCryptoRsaPublicKey(public_key.Pass(), algorithm.id(), |
+ algorithm.rsaHashedImportParams()->hash(), |
+ extractable, usages, key); |
} |
Status RsaHashedAlgorithm::ImportKeyJwk( |
@@ -444,12 +338,8 @@ Status RsaHashedAlgorithm::ImportKeyJwk( |
return jwk.is_private_key |
? ImportRsaPrivateKey(algorithm, extractable, usages, jwk, key) |
- : ImportRsaPublicKey(algorithm, |
- extractable, |
- usages, |
- CryptoData(jwk.n), |
- CryptoData(jwk.e), |
- key); |
+ : ImportRsaPublicKey(algorithm, extractable, usages, |
+ CryptoData(jwk.n), CryptoData(jwk.e), key); |
} |
Status RsaHashedAlgorithm::ExportKeyPkcs8(const blink::WebCryptoKey& key, |
@@ -472,8 +362,8 @@ Status RsaHashedAlgorithm::ExportKeyJwk(const blink::WebCryptoKey& key, |
std::vector<uint8_t>* buffer) const { |
crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE); |
- EVP_PKEY* public_key = AsymKeyOpenSsl::Cast(key)->key(); |
- crypto::ScopedRSA rsa(EVP_PKEY_get1_RSA(public_key)); |
+ EVP_PKEY* pkey = AsymKeyOpenSsl::Cast(key)->key(); |
+ crypto::ScopedRSA rsa(EVP_PKEY_get1_RSA(pkey)); |
if (!rsa.get()) |
return Status::ErrorUnexpected(); |
@@ -485,11 +375,8 @@ Status RsaHashedAlgorithm::ExportKeyJwk(const blink::WebCryptoKey& key, |
switch (key.type()) { |
case blink::WebCryptoKeyTypePublic: |
WriteRsaPublicKeyJwk(CryptoData(BIGNUMToVector(rsa->n)), |
- CryptoData(BIGNUMToVector(rsa->e)), |
- jwk_algorithm, |
- key.extractable(), |
- key.usages(), |
- buffer); |
+ CryptoData(BIGNUMToVector(rsa->e)), jwk_algorithm, |
+ key.extractable(), key.usages(), buffer); |
return Status::Success(); |
case blink::WebCryptoKeyTypePrivate: |
WriteRsaPrivateKeyJwk(CryptoData(BIGNUMToVector(rsa->n)), |
@@ -500,9 +387,7 @@ Status RsaHashedAlgorithm::ExportKeyJwk(const blink::WebCryptoKey& key, |
CryptoData(BIGNUMToVector(rsa->dmp1)), |
CryptoData(BIGNUMToVector(rsa->dmq1)), |
CryptoData(BIGNUMToVector(rsa->iqmp)), |
- jwk_algorithm, |
- key.extractable(), |
- key.usages(), |
+ jwk_algorithm, key.extractable(), key.usages(), |
buffer); |
return Status::Success(); |