Index: content/child/webcrypto/openssl/rsa_hashed_algorithm_openssl.cc |
diff --git a/content/child/webcrypto/openssl/rsa_hashed_algorithm_openssl.cc b/content/child/webcrypto/openssl/rsa_hashed_algorithm_openssl.cc |
deleted file mode 100644 |
index 1db15dbd24a981b181e2d8e2ae93dcf904870f31..0000000000000000000000000000000000000000 |
--- a/content/child/webcrypto/openssl/rsa_hashed_algorithm_openssl.cc |
+++ /dev/null |
@@ -1,434 +0,0 @@ |
-// Copyright 2014 The Chromium Authors. All rights reserved. |
-// Use of this source code is governed by a BSD-style license that can be |
-// found in the LICENSE file. |
- |
-#include "content/child/webcrypto/openssl/rsa_hashed_algorithm_openssl.h" |
- |
-#include <openssl/evp.h> |
- |
-#include "base/logging.h" |
-#include "base/stl_util.h" |
-#include "content/child/webcrypto/crypto_data.h" |
-#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" |
-#include "crypto/scoped_openssl_types.h" |
-#include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h" |
-#include "third_party/WebKit/public/platform/WebCryptoKeyAlgorithm.h" |
- |
-namespace content { |
- |
-namespace webcrypto { |
- |
-namespace { |
- |
-// Creates a blink::WebCryptoAlgorithm having the modulus length and public |
-// exponent of |key|. |
-Status CreateRsaHashedKeyAlgorithm( |
- blink::WebCryptoAlgorithmId rsa_algorithm, |
- blink::WebCryptoAlgorithmId hash_algorithm, |
- EVP_PKEY* key, |
- blink::WebCryptoKeyAlgorithm* key_algorithm) { |
- DCHECK_EQ(EVP_PKEY_RSA, EVP_PKEY_id(key)); |
- |
- crypto::ScopedRSA rsa(EVP_PKEY_get1_RSA(key)); |
- if (!rsa.get()) |
- return Status::ErrorUnexpected(); |
- |
- unsigned int modulus_length_bits = BN_num_bits(rsa.get()->n); |
- |
- // Convert the public exponent to big-endian representation. |
- std::vector<uint8_t> e(BN_num_bytes(rsa.get()->e)); |
- if (e.size() == 0) |
- return Status::ErrorUnexpected(); |
- if (e.size() != BN_bn2bin(rsa.get()->e, &e[0])) |
- return Status::ErrorUnexpected(); |
- |
- *key_algorithm = blink::WebCryptoKeyAlgorithm::createRsaHashed( |
- rsa_algorithm, modulus_length_bits, &e[0], e.size(), hash_algorithm); |
- |
- return Status::Success(); |
-} |
- |
-// Creates a WebCryptoKey that wraps |private_key|. |
-Status CreateWebCryptoRsaPrivateKey( |
- crypto::ScopedEVP_PKEY private_key, |
- const blink::WebCryptoAlgorithmId rsa_algorithm_id, |
- const blink::WebCryptoAlgorithm& hash, |
- bool extractable, |
- blink::WebCryptoKeyUsageMask usages, |
- blink::WebCryptoKey* key) { |
- blink::WebCryptoKeyAlgorithm key_algorithm; |
- Status status = CreateRsaHashedKeyAlgorithm( |
- rsa_algorithm_id, hash.id(), private_key.get(), &key_algorithm); |
- if (status.IsError()) |
- return status; |
- |
- return CreateWebCryptoPrivateKey(private_key.Pass(), key_algorithm, |
- extractable, usages, key); |
-} |
- |
-// Creates a WebCryptoKey that wraps |public_key|. |
-Status CreateWebCryptoRsaPublicKey( |
- crypto::ScopedEVP_PKEY public_key, |
- const blink::WebCryptoAlgorithmId rsa_algorithm_id, |
- const blink::WebCryptoAlgorithm& hash, |
- bool extractable, |
- blink::WebCryptoKeyUsageMask usages, |
- blink::WebCryptoKey* key) { |
- blink::WebCryptoKeyAlgorithm key_algorithm; |
- Status status = CreateRsaHashedKeyAlgorithm(rsa_algorithm_id, hash.id(), |
- public_key.get(), &key_algorithm); |
- if (status.IsError()) |
- return status; |
- |
- return CreateWebCryptoPublicKey(public_key.Pass(), key_algorithm, extractable, |
- usages, key); |
-} |
- |
-Status ImportRsaPrivateKey(const blink::WebCryptoAlgorithm& algorithm, |
- bool extractable, |
- blink::WebCryptoKeyUsageMask usages, |
- const JwkRsaInfo& params, |
- blink::WebCryptoKey* key) { |
- crypto::ScopedRSA rsa(RSA_new()); |
- |
- rsa->n = CreateBIGNUM(params.n); |
- rsa->e = CreateBIGNUM(params.e); |
- rsa->d = CreateBIGNUM(params.d); |
- rsa->p = CreateBIGNUM(params.p); |
- rsa->q = CreateBIGNUM(params.q); |
- rsa->dmp1 = CreateBIGNUM(params.dp); |
- rsa->dmq1 = CreateBIGNUM(params.dq); |
- rsa->iqmp = CreateBIGNUM(params.qi); |
- |
- if (!rsa->n || !rsa->e || !rsa->d || !rsa->p || !rsa->q || !rsa->dmp1 || |
- !rsa->dmq1 || !rsa->iqmp) { |
- return Status::OperationError(); |
- } |
- |
- // TODO(eroman): This should really be a DataError, however for compatibility |
- // with NSS it is an OperationError. |
- if (!RSA_check_key(rsa.get())) |
- return Status::OperationError(); |
- |
- // Create a corresponding EVP_PKEY. |
- crypto::ScopedEVP_PKEY pkey(EVP_PKEY_new()); |
- if (!pkey || !EVP_PKEY_set1_RSA(pkey.get(), rsa.get())) |
- return Status::OperationError(); |
- |
- return CreateWebCryptoRsaPrivateKey(pkey.Pass(), algorithm.id(), |
- algorithm.rsaHashedImportParams()->hash(), |
- extractable, usages, key); |
-} |
- |
-Status ImportRsaPublicKey(const blink::WebCryptoAlgorithm& algorithm, |
- bool extractable, |
- blink::WebCryptoKeyUsageMask usages, |
- const CryptoData& n, |
- const CryptoData& e, |
- blink::WebCryptoKey* key) { |
- crypto::ScopedRSA rsa(RSA_new()); |
- |
- rsa->n = BN_bin2bn(n.bytes(), n.byte_length(), NULL); |
- rsa->e = BN_bin2bn(e.bytes(), e.byte_length(), NULL); |
- |
- if (!rsa->n || !rsa->e) |
- return Status::OperationError(); |
- |
- // Create a corresponding EVP_PKEY. |
- crypto::ScopedEVP_PKEY pkey(EVP_PKEY_new()); |
- if (!pkey || !EVP_PKEY_set1_RSA(pkey.get(), rsa.get())) |
- return Status::OperationError(); |
- |
- return CreateWebCryptoRsaPublicKey(pkey.Pass(), algorithm.id(), |
- algorithm.rsaHashedImportParams()->hash(), |
- extractable, usages, key); |
-} |
- |
-} // namespace |
- |
-Status RsaHashedAlgorithm::GenerateKey( |
- const blink::WebCryptoAlgorithm& algorithm, |
- bool extractable, |
- blink::WebCryptoKeyUsageMask combined_usages, |
- GenerateKeyResult* result) const { |
- blink::WebCryptoKeyUsageMask public_usages = 0; |
- blink::WebCryptoKeyUsageMask private_usages = 0; |
- |
- Status status = GetUsagesForGenerateAsymmetricKey( |
- combined_usages, all_public_key_usages_, all_private_key_usages_, |
- &public_usages, &private_usages); |
- if (status.IsError()) |
- return status; |
- |
- const blink::WebCryptoRsaHashedKeyGenParams* params = |
- algorithm.rsaHashedKeyGenParams(); |
- |
- unsigned int public_exponent = 0; |
- unsigned int modulus_length_bits = 0; |
- status = |
- GetRsaKeyGenParameters(params, &public_exponent, &modulus_length_bits); |
- if (status.IsError()) |
- return status; |
- |
- crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE); |
- |
- // Generate an RSA key pair. |
- crypto::ScopedRSA rsa_private_key(RSA_new()); |
- crypto::ScopedBIGNUM bn(BN_new()); |
- if (!rsa_private_key.get() || !bn.get() || |
- !BN_set_word(bn.get(), public_exponent)) { |
- return Status::OperationError(); |
- } |
- |
- if (!RSA_generate_key_ex(rsa_private_key.get(), modulus_length_bits, bn.get(), |
- NULL)) { |
- return Status::OperationError(); |
- } |
- |
- // Construct an EVP_PKEY for the private key. |
- crypto::ScopedEVP_PKEY private_pkey(EVP_PKEY_new()); |
- if (!private_pkey || |
- !EVP_PKEY_set1_RSA(private_pkey.get(), rsa_private_key.get())) { |
- return Status::OperationError(); |
- } |
- |
- // Construct an EVP_PKEY for the public key. |
- crypto::ScopedRSA rsa_public_key(RSAPublicKey_dup(rsa_private_key.get())); |
- crypto::ScopedEVP_PKEY public_pkey(EVP_PKEY_new()); |
- if (!public_pkey || |
- !EVP_PKEY_set1_RSA(public_pkey.get(), rsa_public_key.get())) { |
- return Status::OperationError(); |
- } |
- |
- blink::WebCryptoKey public_key; |
- blink::WebCryptoKey private_key; |
- |
- // Note that extractable is unconditionally set to true. This is because per |
- // the WebCrypto spec generated public keys are always extractable. |
- status = CreateWebCryptoRsaPublicKey(public_pkey.Pass(), algorithm.id(), |
- params->hash(), true, public_usages, |
- &public_key); |
- if (status.IsError()) |
- return status; |
- |
- status = CreateWebCryptoRsaPrivateKey(private_pkey.Pass(), algorithm.id(), |
- params->hash(), extractable, |
- private_usages, &private_key); |
- if (status.IsError()) |
- return status; |
- |
- result->AssignKeyPair(public_key, private_key); |
- return Status::Success(); |
-} |
- |
-Status RsaHashedAlgorithm::VerifyKeyUsagesBeforeImportKey( |
- blink::WebCryptoKeyFormat format, |
- blink::WebCryptoKeyUsageMask usages) const { |
- return VerifyUsagesBeforeImportAsymmetricKey(format, all_public_key_usages_, |
- all_private_key_usages_, usages); |
-} |
- |
-Status RsaHashedAlgorithm::ImportKeyPkcs8( |
- const CryptoData& key_data, |
- const blink::WebCryptoAlgorithm& algorithm, |
- bool extractable, |
- blink::WebCryptoKeyUsageMask usages, |
- blink::WebCryptoKey* key) const { |
- 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. |
- crypto::ScopedRSA rsa(EVP_PKEY_get1_RSA(private_key.get())); |
- if (!rsa.get()) |
- return Status::ErrorUnexpected(); |
- if (!RSA_check_key(rsa.get())) |
- return Status::DataError(); |
- |
- // TODO(eroman): Validate the algorithm OID against the webcrypto provided |
- // hash. http://crbug.com/389400 |
- |
- return CreateWebCryptoRsaPrivateKey(private_key.Pass(), algorithm.id(), |
- algorithm.rsaHashedImportParams()->hash(), |
- extractable, usages, key); |
-} |
- |
-Status RsaHashedAlgorithm::ImportKeySpki( |
- const CryptoData& key_data, |
- const blink::WebCryptoAlgorithm& algorithm, |
- bool extractable, |
- blink::WebCryptoKeyUsageMask usages, |
- blink::WebCryptoKey* key) const { |
- 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 CreateWebCryptoRsaPublicKey(public_key.Pass(), algorithm.id(), |
- algorithm.rsaHashedImportParams()->hash(), |
- extractable, usages, key); |
-} |
- |
-Status RsaHashedAlgorithm::ImportKeyJwk( |
- const CryptoData& key_data, |
- const blink::WebCryptoAlgorithm& algorithm, |
- bool extractable, |
- blink::WebCryptoKeyUsageMask usages, |
- blink::WebCryptoKey* key) const { |
- crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE); |
- |
- const char* jwk_algorithm = |
- GetJwkAlgorithm(algorithm.rsaHashedImportParams()->hash().id()); |
- |
- if (!jwk_algorithm) |
- return Status::ErrorUnexpected(); |
- |
- JwkRsaInfo jwk; |
- Status status = |
- ReadRsaKeyJwk(key_data, jwk_algorithm, extractable, usages, &jwk); |
- if (status.IsError()) |
- return status; |
- |
- // Once the key type is known, verify the usages. |
- status = CheckKeyCreationUsages( |
- jwk.is_private_key ? all_private_key_usages_ : all_public_key_usages_, |
- usages, !jwk.is_private_key); |
- if (status.IsError()) |
- return status; |
- |
- return jwk.is_private_key |
- ? ImportRsaPrivateKey(algorithm, extractable, usages, jwk, key) |
- : ImportRsaPublicKey(algorithm, extractable, usages, |
- CryptoData(jwk.n), CryptoData(jwk.e), key); |
-} |
- |
-Status RsaHashedAlgorithm::ExportKeyPkcs8(const blink::WebCryptoKey& key, |
- std::vector<uint8_t>* buffer) const { |
- if (key.type() != blink::WebCryptoKeyTypePrivate) |
- return Status::ErrorUnexpectedKeyType(); |
- *buffer = AsymKeyOpenSsl::Cast(key)->serialized_key_data(); |
- return Status::Success(); |
-} |
- |
-Status RsaHashedAlgorithm::ExportKeySpki(const blink::WebCryptoKey& key, |
- std::vector<uint8_t>* buffer) const { |
- if (key.type() != blink::WebCryptoKeyTypePublic) |
- return Status::ErrorUnexpectedKeyType(); |
- *buffer = AsymKeyOpenSsl::Cast(key)->serialized_key_data(); |
- return Status::Success(); |
-} |
- |
-Status RsaHashedAlgorithm::ExportKeyJwk(const blink::WebCryptoKey& key, |
- std::vector<uint8_t>* buffer) const { |
- crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE); |
- |
- EVP_PKEY* pkey = AsymKeyOpenSsl::Cast(key)->key(); |
- crypto::ScopedRSA rsa(EVP_PKEY_get1_RSA(pkey)); |
- if (!rsa.get()) |
- return Status::ErrorUnexpected(); |
- |
- const char* jwk_algorithm = |
- GetJwkAlgorithm(key.algorithm().rsaHashedParams()->hash().id()); |
- if (!jwk_algorithm) |
- return Status::ErrorUnexpected(); |
- |
- switch (key.type()) { |
- case blink::WebCryptoKeyTypePublic: |
- WriteRsaPublicKeyJwk(CryptoData(BIGNUMToVector(rsa->n)), |
- CryptoData(BIGNUMToVector(rsa->e)), jwk_algorithm, |
- key.extractable(), key.usages(), buffer); |
- return Status::Success(); |
- case blink::WebCryptoKeyTypePrivate: |
- WriteRsaPrivateKeyJwk(CryptoData(BIGNUMToVector(rsa->n)), |
- CryptoData(BIGNUMToVector(rsa->e)), |
- CryptoData(BIGNUMToVector(rsa->d)), |
- CryptoData(BIGNUMToVector(rsa->p)), |
- CryptoData(BIGNUMToVector(rsa->q)), |
- CryptoData(BIGNUMToVector(rsa->dmp1)), |
- CryptoData(BIGNUMToVector(rsa->dmq1)), |
- CryptoData(BIGNUMToVector(rsa->iqmp)), |
- jwk_algorithm, key.extractable(), key.usages(), |
- buffer); |
- return Status::Success(); |
- |
- default: |
- return Status::ErrorUnexpected(); |
- } |
-} |
- |
-Status RsaHashedAlgorithm::SerializeKeyForClone( |
- const blink::WebCryptoKey& key, |
- blink::WebVector<uint8_t>* key_data) const { |
- key_data->assign(AsymKeyOpenSsl::Cast(key)->serialized_key_data()); |
- return Status::Success(); |
-} |
- |
-// TODO(eroman): Defer import to the crypto thread. http://crbug.com/430763 |
-Status RsaHashedAlgorithm::DeserializeKeyForClone( |
- const blink::WebCryptoKeyAlgorithm& algorithm, |
- blink::WebCryptoKeyType type, |
- bool extractable, |
- blink::WebCryptoKeyUsageMask usages, |
- const CryptoData& key_data, |
- blink::WebCryptoKey* key) const { |
- blink::WebCryptoAlgorithm import_algorithm = CreateRsaHashedImportAlgorithm( |
- algorithm.id(), algorithm.rsaHashedParams()->hash().id()); |
- |
- Status status; |
- |
- switch (type) { |
- case blink::WebCryptoKeyTypePublic: |
- status = |
- ImportKeySpki(key_data, import_algorithm, extractable, usages, key); |
- break; |
- case blink::WebCryptoKeyTypePrivate: |
- status = |
- ImportKeyPkcs8(key_data, import_algorithm, extractable, usages, key); |
- break; |
- default: |
- return Status::ErrorUnexpected(); |
- } |
- |
- // There is some duplicated information in the serialized format used by |
- // structured clone (since the KeyAlgorithm is serialized separately from the |
- // key data). Use this extra information to further validate what was |
- // deserialized from the key data. |
- |
- if (algorithm.id() != key->algorithm().id()) |
- return Status::ErrorUnexpected(); |
- |
- if (key->type() != type) |
- return Status::ErrorUnexpected(); |
- |
- if (algorithm.rsaHashedParams()->modulusLengthBits() != |
- key->algorithm().rsaHashedParams()->modulusLengthBits()) { |
- return Status::ErrorUnexpected(); |
- } |
- |
- if (algorithm.rsaHashedParams()->publicExponent().size() != |
- key->algorithm().rsaHashedParams()->publicExponent().size() || |
- 0 != |
- memcmp(algorithm.rsaHashedParams()->publicExponent().data(), |
- key->algorithm().rsaHashedParams()->publicExponent().data(), |
- key->algorithm().rsaHashedParams()->publicExponent().size())) { |
- return Status::ErrorUnexpected(); |
- } |
- |
- return Status::Success(); |
-} |
- |
-} // namespace webcrypto |
- |
-} // namespace content |