summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoreroman <eroman@chromium.org>2015-10-01 12:38:04 -0700
committerCommit bot <commit-bot@chromium.org>2015-10-01 19:40:33 +0000
commitab1308a6162d76b060d0e02d9ffadacd526627ed (patch)
tree1380b79e0687c43cf217093d05947bb072f4e9e3
parentc6ce7678b2d6d02dd1f47f330a5aed368fcb9c6a (diff)
downloadchromium_src-ab1308a6162d76b060d0e02d9ffadacd526627ed.zip
chromium_src-ab1308a6162d76b060d0e02d9ffadacd526627ed.tar.gz
chromium_src-ab1308a6162d76b060d0e02d9ffadacd526627ed.tar.bz2
Finish re-organizing the components/webcrypto files
webcrypto_util.h and util_openssl have been deleted. The final file naming and organization for the various "utility" code is: * blink_key_handle.h -- Code for creating and extracting values from blink::WebCryptoKeyHandle. * secret_key_util.h -- Common code used by symmetric key algorithms. * asymmetric_key_util.h -- Common code used by asymmetric key algorithms. * test_helpers.h -- Common code used by unit tests. * util.h -- Common code that didn't quite fit into the other _util files. There isn't enough stuff in here yet to justify finer grained file structure. Review URL: https://codereview.chromium.org/1360253003 Cr-Commit-Position: refs/heads/master@{#351865}
-rw-r--r--components/webcrypto/BUILD.gn12
-rw-r--r--components/webcrypto/algorithm_dispatch.cc1
-rw-r--r--components/webcrypto/algorithm_implementation.cc2
-rw-r--r--components/webcrypto/algorithms/aes.cc19
-rw-r--r--components/webcrypto/algorithms/aes_cbc.cc5
-rw-r--r--components/webcrypto/algorithms/aes_cbc_unittest.cc2
-rw-r--r--components/webcrypto/algorithms/aes_ctr.cc5
-rw-r--r--components/webcrypto/algorithms/aes_ctr_unittest.cc2
-rw-r--r--components/webcrypto/algorithms/aes_gcm.cc5
-rw-r--r--components/webcrypto/algorithms/aes_gcm_unittest.cc2
-rw-r--r--components/webcrypto/algorithms/aes_kw.cc4
-rw-r--r--components/webcrypto/algorithms/aes_kw_unittest.cc2
-rw-r--r--components/webcrypto/algorithms/asymmetric_key_util.cc (renamed from components/webcrypto/algorithms/util_openssl.cc)141
-rw-r--r--components/webcrypto/algorithms/asymmetric_key_util.h (renamed from components/webcrypto/algorithms/util_openssl.h)69
-rw-r--r--components/webcrypto/algorithms/ec.cc29
-rw-r--r--components/webcrypto/algorithms/ecdh.cc5
-rw-r--r--components/webcrypto/algorithms/ecdh_unittest.cc2
-rw-r--r--components/webcrypto/algorithms/ecdsa.cc7
-rw-r--r--components/webcrypto/algorithms/ecdsa_unittest.cc1
-rw-r--r--components/webcrypto/algorithms/hkdf.cc9
-rw-r--r--components/webcrypto/algorithms/hmac.cc13
-rw-r--r--components/webcrypto/algorithms/hmac_unittest.cc2
-rw-r--r--components/webcrypto/algorithms/pbkdf2.cc10
-rw-r--r--components/webcrypto/algorithms/rsa.cc83
-rw-r--r--components/webcrypto/algorithms/rsa_oaep.cc7
-rw-r--r--components/webcrypto/algorithms/rsa_oaep_unittest.cc1
-rw-r--r--components/webcrypto/algorithms/rsa_pss_unittest.cc1
-rw-r--r--components/webcrypto/algorithms/rsa_sign.cc6
-rw-r--r--components/webcrypto/algorithms/rsa_ssa_unittest.cc2
-rw-r--r--components/webcrypto/algorithms/secret_key_util.cc11
-rw-r--r--components/webcrypto/algorithms/secret_key_util.h7
-rw-r--r--components/webcrypto/algorithms/sha.cc11
-rw-r--r--components/webcrypto/algorithms/sha_unittest.cc2
-rw-r--r--components/webcrypto/algorithms/test_helpers.cc20
-rw-r--r--components/webcrypto/algorithms/test_helpers.h14
-rw-r--r--components/webcrypto/algorithms/util.cc127
-rw-r--r--components/webcrypto/algorithms/util.h96
-rw-r--r--components/webcrypto/blink_key_handle.cc (renamed from components/webcrypto/key.cc)3
-rw-r--r--components/webcrypto/blink_key_handle.h (renamed from components/webcrypto/key.h)14
-rw-r--r--components/webcrypto/jwk.cc2
-rw-r--r--components/webcrypto/status_unittest.cc1
-rw-r--r--components/webcrypto/webcrypto.gyp12
-rw-r--r--components/webcrypto/webcrypto_impl.cc1
-rw-r--r--components/webcrypto/webcrypto_util.cc168
-rw-r--r--components/webcrypto/webcrypto_util.h97
45 files changed, 543 insertions, 492 deletions
diff --git a/components/webcrypto/BUILD.gn b/components/webcrypto/BUILD.gn
index 3472831..aebf172 100644
--- a/components/webcrypto/BUILD.gn
+++ b/components/webcrypto/BUILD.gn
@@ -20,6 +20,8 @@ source_set("webcrypto") {
"algorithms/aes_ctr.cc",
"algorithms/aes_gcm.cc",
"algorithms/aes_kw.cc",
+ "algorithms/asymmetric_key_util.cc",
+ "algorithms/asymmetric_key_util.h",
"algorithms/ec.cc",
"algorithms/ec.h",
"algorithms/ecdh.cc",
@@ -37,22 +39,20 @@ source_set("webcrypto") {
"algorithms/secret_key_util.cc",
"algorithms/secret_key_util.h",
"algorithms/sha.cc",
- "algorithms/util_openssl.cc",
- "algorithms/util_openssl.h",
+ "algorithms/util.cc",
+ "algorithms/util.h",
+ "blink_key_handle.cc",
+ "blink_key_handle.h",
"crypto_data.cc",
"crypto_data.h",
"generate_key_result.cc",
"generate_key_result.h",
"jwk.cc",
"jwk.h",
- "key.cc",
- "key.h",
"status.cc",
"status.h",
"webcrypto_impl.cc",
"webcrypto_impl.h",
- "webcrypto_util.cc",
- "webcrypto_util.h",
]
deps = [
diff --git a/components/webcrypto/algorithm_dispatch.cc b/components/webcrypto/algorithm_dispatch.cc
index feacd23..63f529b 100644
--- a/components/webcrypto/algorithm_dispatch.cc
+++ b/components/webcrypto/algorithm_dispatch.cc
@@ -11,7 +11,6 @@
#include "components/webcrypto/crypto_data.h"
#include "components/webcrypto/generate_key_result.h"
#include "components/webcrypto/status.h"
-#include "components/webcrypto/webcrypto_util.h"
#include "crypto/openssl_util.h"
#include "third_party/WebKit/public/platform/WebCryptoKeyAlgorithm.h"
diff --git a/components/webcrypto/algorithm_implementation.cc b/components/webcrypto/algorithm_implementation.cc
index 5f54791..8db7482 100644
--- a/components/webcrypto/algorithm_implementation.cc
+++ b/components/webcrypto/algorithm_implementation.cc
@@ -4,7 +4,7 @@
#include "components/webcrypto/algorithm_implementation.h"
-#include "components/webcrypto/key.h"
+#include "components/webcrypto/blink_key_handle.h"
#include "components/webcrypto/status.h"
namespace webcrypto {
diff --git a/components/webcrypto/algorithms/aes.cc b/components/webcrypto/algorithms/aes.cc
index f42d508..09dbfd4 100644
--- a/components/webcrypto/algorithms/aes.cc
+++ b/components/webcrypto/algorithms/aes.cc
@@ -6,11 +6,10 @@
#include "base/logging.h"
#include "components/webcrypto/algorithms/secret_key_util.h"
+#include "components/webcrypto/blink_key_handle.h"
#include "components/webcrypto/crypto_data.h"
#include "components/webcrypto/jwk.h"
-#include "components/webcrypto/key.h"
#include "components/webcrypto/status.h"
-#include "components/webcrypto/webcrypto_util.h"
#include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h"
#include "third_party/WebKit/public/platform/WebCryptoKeyAlgorithm.h"
@@ -31,6 +30,14 @@ std::string MakeJwkAesAlgorithmName(const std::string& suffix,
return std::string();
}
+// Synthesizes an import algorithm given a key algorithm, so that
+// deserialization can re-use the ImportKey*() methods.
+blink::WebCryptoAlgorithm SynthesizeImportAlgorithmForClone(
+ const blink::WebCryptoKeyAlgorithm& algorithm) {
+ return blink::WebCryptoAlgorithm::adoptParamsAndCreate(algorithm.id(),
+ nullptr);
+}
+
} // namespace
AesAlgorithm::AesAlgorithm(blink::WebCryptoKeyUsageMask all_key_usages,
@@ -50,7 +57,7 @@ Status AesAlgorithm::GenerateKey(const blink::WebCryptoAlgorithm& algorithm,
bool extractable,
blink::WebCryptoKeyUsageMask usages,
GenerateKeyResult* result) const {
- Status status = CheckKeyCreationUsages(all_key_usages_, usages, false);
+ Status status = CheckSecretKeyCreationUsages(all_key_usages_, usages);
if (status.IsError())
return status;
@@ -74,7 +81,7 @@ Status AesAlgorithm::VerifyKeyUsagesBeforeImportKey(
switch (format) {
case blink::WebCryptoKeyFormatRaw:
case blink::WebCryptoKeyFormatJwk:
- return CheckKeyCreationUsages(all_key_usages_, usages, false);
+ return CheckSecretKeyCreationUsages(all_key_usages_, usages);
default:
return Status::ErrorUnsupportedImportKeyFormat();
}
@@ -164,8 +171,8 @@ Status AesAlgorithm::DeserializeKeyForClone(
blink::WebCryptoKeyUsageMask usages,
const CryptoData& key_data,
blink::WebCryptoKey* key) const {
- return ImportKeyRaw(key_data, CreateAlgorithm(algorithm.id()), extractable,
- usages, key);
+ return ImportKeyRaw(key_data, SynthesizeImportAlgorithmForClone(algorithm),
+ extractable, usages, key);
}
Status AesAlgorithm::GetKeyLength(
diff --git a/components/webcrypto/algorithms/aes_cbc.cc b/components/webcrypto/algorithms/aes_cbc.cc
index 849f181..0d9c88e 100644
--- a/components/webcrypto/algorithms/aes_cbc.cc
+++ b/components/webcrypto/algorithms/aes_cbc.cc
@@ -9,11 +9,10 @@
#include "base/numerics/safe_math.h"
#include "base/stl_util.h"
#include "components/webcrypto/algorithms/aes.h"
-#include "components/webcrypto/algorithms/util_openssl.h"
+#include "components/webcrypto/algorithms/util.h"
+#include "components/webcrypto/blink_key_handle.h"
#include "components/webcrypto/crypto_data.h"
-#include "components/webcrypto/key.h"
#include "components/webcrypto/status.h"
-#include "components/webcrypto/webcrypto_util.h"
#include "crypto/openssl_util.h"
#include "crypto/scoped_openssl_types.h"
#include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h"
diff --git a/components/webcrypto/algorithms/aes_cbc_unittest.cc b/components/webcrypto/algorithms/aes_cbc_unittest.cc
index 2aec041..44f07ea 100644
--- a/components/webcrypto/algorithms/aes_cbc_unittest.cc
+++ b/components/webcrypto/algorithms/aes_cbc_unittest.cc
@@ -3,11 +3,11 @@
// found in the LICENSE file.
#include "base/stl_util.h"
+#include "base/values.h"
#include "components/webcrypto/algorithm_dispatch.h"
#include "components/webcrypto/algorithms/test_helpers.h"
#include "components/webcrypto/crypto_data.h"
#include "components/webcrypto/status.h"
-#include "components/webcrypto/webcrypto_util.h"
#include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h"
#include "third_party/WebKit/public/platform/WebCryptoKeyAlgorithm.h"
diff --git a/components/webcrypto/algorithms/aes_ctr.cc b/components/webcrypto/algorithms/aes_ctr.cc
index 9c9892c..f4c16b6 100644
--- a/components/webcrypto/algorithms/aes_ctr.cc
+++ b/components/webcrypto/algorithms/aes_ctr.cc
@@ -10,11 +10,10 @@
#include "base/numerics/safe_math.h"
#include "base/stl_util.h"
#include "components/webcrypto/algorithms/aes.h"
-#include "components/webcrypto/algorithms/util_openssl.h"
+#include "components/webcrypto/algorithms/util.h"
+#include "components/webcrypto/blink_key_handle.h"
#include "components/webcrypto/crypto_data.h"
-#include "components/webcrypto/key.h"
#include "components/webcrypto/status.h"
-#include "components/webcrypto/webcrypto_util.h"
#include "crypto/openssl_util.h"
#include "crypto/scoped_openssl_types.h"
#include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h"
diff --git a/components/webcrypto/algorithms/aes_ctr_unittest.cc b/components/webcrypto/algorithms/aes_ctr_unittest.cc
index c9c26f8..9bdbf38 100644
--- a/components/webcrypto/algorithms/aes_ctr_unittest.cc
+++ b/components/webcrypto/algorithms/aes_ctr_unittest.cc
@@ -3,11 +3,11 @@
// found in the LICENSE file.
#include "base/stl_util.h"
+#include "base/values.h"
#include "components/webcrypto/algorithm_dispatch.h"
#include "components/webcrypto/algorithms/test_helpers.h"
#include "components/webcrypto/crypto_data.h"
#include "components/webcrypto/status.h"
-#include "components/webcrypto/webcrypto_util.h"
#include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h"
#include "third_party/WebKit/public/platform/WebCryptoKeyAlgorithm.h"
diff --git a/components/webcrypto/algorithms/aes_gcm.cc b/components/webcrypto/algorithms/aes_gcm.cc
index 57fa77f..3685bd9 100644
--- a/components/webcrypto/algorithms/aes_gcm.cc
+++ b/components/webcrypto/algorithms/aes_gcm.cc
@@ -8,11 +8,10 @@
#include "base/logging.h"
#include "base/stl_util.h"
#include "components/webcrypto/algorithms/aes.h"
-#include "components/webcrypto/algorithms/util_openssl.h"
+#include "components/webcrypto/algorithms/util.h"
+#include "components/webcrypto/blink_key_handle.h"
#include "components/webcrypto/crypto_data.h"
-#include "components/webcrypto/key.h"
#include "components/webcrypto/status.h"
-#include "components/webcrypto/webcrypto_util.h"
#include "crypto/openssl_util.h"
#include "crypto/scoped_openssl_types.h"
#include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h"
diff --git a/components/webcrypto/algorithms/aes_gcm_unittest.cc b/components/webcrypto/algorithms/aes_gcm_unittest.cc
index 60e8582..94ba9be 100644
--- a/components/webcrypto/algorithms/aes_gcm_unittest.cc
+++ b/components/webcrypto/algorithms/aes_gcm_unittest.cc
@@ -3,11 +3,11 @@
// found in the LICENSE file.
#include "base/stl_util.h"
+#include "base/values.h"
#include "components/webcrypto/algorithm_dispatch.h"
#include "components/webcrypto/algorithms/test_helpers.h"
#include "components/webcrypto/crypto_data.h"
#include "components/webcrypto/status.h"
-#include "components/webcrypto/webcrypto_util.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h"
#include "third_party/WebKit/public/platform/WebCryptoKeyAlgorithm.h"
diff --git a/components/webcrypto/algorithms/aes_kw.cc b/components/webcrypto/algorithms/aes_kw.cc
index 89ef6d3..295d911 100644
--- a/components/webcrypto/algorithms/aes_kw.cc
+++ b/components/webcrypto/algorithms/aes_kw.cc
@@ -9,9 +9,9 @@
#include "base/numerics/safe_math.h"
#include "base/stl_util.h"
#include "components/webcrypto/algorithms/aes.h"
-#include "components/webcrypto/algorithms/util_openssl.h"
+#include "components/webcrypto/algorithms/util.h"
+#include "components/webcrypto/blink_key_handle.h"
#include "components/webcrypto/crypto_data.h"
-#include "components/webcrypto/key.h"
#include "components/webcrypto/status.h"
#include "crypto/openssl_util.h"
#include "crypto/scoped_openssl_types.h"
diff --git a/components/webcrypto/algorithms/aes_kw_unittest.cc b/components/webcrypto/algorithms/aes_kw_unittest.cc
index a2e0837..3002544 100644
--- a/components/webcrypto/algorithms/aes_kw_unittest.cc
+++ b/components/webcrypto/algorithms/aes_kw_unittest.cc
@@ -3,11 +3,11 @@
// found in the LICENSE file.
#include "base/stl_util.h"
+#include "base/values.h"
#include "components/webcrypto/algorithm_dispatch.h"
#include "components/webcrypto/algorithms/test_helpers.h"
#include "components/webcrypto/crypto_data.h"
#include "components/webcrypto/status.h"
-#include "components/webcrypto/webcrypto_util.h"
#include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h"
#include "third_party/WebKit/public/platform/WebCryptoKeyAlgorithm.h"
diff --git a/components/webcrypto/algorithms/util_openssl.cc b/components/webcrypto/algorithms/asymmetric_key_util.cc
index 34b26a4..9abd47c 100644
--- a/components/webcrypto/algorithms/util_openssl.cc
+++ b/components/webcrypto/algorithms/asymmetric_key_util.cc
@@ -1,20 +1,16 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
+// Copyright 2015 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 "components/webcrypto/algorithms/util_openssl.h"
+#include "components/webcrypto/algorithms/asymmetric_key_util.h"
-#include <openssl/evp.h>
#include <openssl/pkcs12.h>
-#include <openssl/rand.h>
-#include "base/stl_util.h"
-#include "components/webcrypto/algorithm_implementations.h"
+#include "components/webcrypto/algorithms/util.h"
+#include "components/webcrypto/blink_key_handle.h"
#include "components/webcrypto/crypto_data.h"
#include "components/webcrypto/generate_key_result.h"
-#include "components/webcrypto/key.h"
#include "components/webcrypto/status.h"
-#include "components/webcrypto/webcrypto_util.h"
#include "crypto/openssl_util.h"
namespace webcrypto {
@@ -61,72 +57,6 @@ Status ExportPKeyPkcs8(EVP_PKEY* key, std::vector<uint8_t>* buffer) {
} // namespace
-const EVP_MD* GetDigest(blink::WebCryptoAlgorithmId id) {
- switch (id) {
- case blink::WebCryptoAlgorithmIdSha1:
- return EVP_sha1();
- case blink::WebCryptoAlgorithmIdSha256:
- return EVP_sha256();
- case blink::WebCryptoAlgorithmIdSha384:
- return EVP_sha384();
- case blink::WebCryptoAlgorithmIdSha512:
- return EVP_sha512();
- default:
- return NULL;
- }
-}
-
-Status AeadEncryptDecrypt(EncryptOrDecrypt mode,
- const std::vector<uint8_t>& raw_key,
- const CryptoData& data,
- unsigned int tag_length_bytes,
- const CryptoData& iv,
- const CryptoData& additional_data,
- const EVP_AEAD* aead_alg,
- std::vector<uint8_t>* buffer) {
- crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
- EVP_AEAD_CTX ctx;
-
- if (!aead_alg)
- return Status::ErrorUnexpected();
-
- if (!EVP_AEAD_CTX_init(&ctx, aead_alg, vector_as_array(&raw_key),
- raw_key.size(), tag_length_bytes, NULL)) {
- return Status::OperationError();
- }
-
- crypto::ScopedOpenSSL<EVP_AEAD_CTX, EVP_AEAD_CTX_cleanup> ctx_cleanup(&ctx);
-
- size_t len;
- int ok;
-
- if (mode == DECRYPT) {
- if (data.byte_length() < tag_length_bytes)
- return Status::ErrorDataTooSmall();
-
- buffer->resize(data.byte_length() - tag_length_bytes);
-
- ok = EVP_AEAD_CTX_open(&ctx, vector_as_array(buffer), &len, buffer->size(),
- iv.bytes(), iv.byte_length(), data.bytes(),
- data.byte_length(), additional_data.bytes(),
- additional_data.byte_length());
- } else {
- // No need to check for unsigned integer overflow here (seal fails if
- // the output buffer is too small).
- buffer->resize(data.byte_length() + EVP_AEAD_max_overhead(aead_alg));
-
- ok = EVP_AEAD_CTX_seal(&ctx, vector_as_array(buffer), &len, buffer->size(),
- iv.bytes(), iv.byte_length(), data.bytes(),
- data.byte_length(), additional_data.bytes(),
- additional_data.byte_length());
- }
-
- if (!ok)
- return Status::OperationError();
- buffer->resize(len);
- return Status::Success();
-}
-
Status CreateWebCryptoPublicKey(crypto::ScopedEVP_PKEY public_key,
const blink::WebCryptoKeyAlgorithm& algorithm,
bool extractable,
@@ -163,6 +93,20 @@ Status CreateWebCryptoPrivateKey(crypto::ScopedEVP_PKEY private_key,
return Status::Success();
}
+Status CheckPrivateKeyCreationUsages(
+ blink::WebCryptoKeyUsageMask all_possible_usages,
+ blink::WebCryptoKeyUsageMask actual_usages) {
+ return CheckKeyCreationUsages(all_possible_usages, actual_usages,
+ EmptyUsagePolicy::REJECT_EMPTY);
+}
+
+Status CheckPublicKeyCreationUsages(
+ blink::WebCryptoKeyUsageMask all_possible_usages,
+ blink::WebCryptoKeyUsageMask actual_usages) {
+ return CheckKeyCreationUsages(all_possible_usages, actual_usages,
+ EmptyUsagePolicy::ALLOW_EMPTY);
+}
+
Status ImportUnverifiedPkeyFromSpki(const CryptoData& key_data,
int expected_pkey_id,
crypto::ScopedEVP_PKEY* pkey) {
@@ -200,14 +144,51 @@ Status ImportUnverifiedPkeyFromPkcs8(const CryptoData& key_data,
return Status::Success();
}
-BIGNUM* CreateBIGNUM(const std::string& n) {
- return BN_bin2bn(reinterpret_cast<const uint8_t*>(n.data()), n.size(), NULL);
+Status VerifyUsagesBeforeImportAsymmetricKey(
+ blink::WebCryptoKeyFormat format,
+ blink::WebCryptoKeyUsageMask all_public_key_usages,
+ blink::WebCryptoKeyUsageMask all_private_key_usages,
+ blink::WebCryptoKeyUsageMask usages) {
+ switch (format) {
+ case blink::WebCryptoKeyFormatSpki:
+ return CheckPublicKeyCreationUsages(all_public_key_usages, usages);
+ case blink::WebCryptoKeyFormatPkcs8:
+ return CheckPrivateKeyCreationUsages(all_private_key_usages, usages);
+ case blink::WebCryptoKeyFormatJwk: {
+ // 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 (CheckPublicKeyCreationUsages(all_public_key_usages, usages)
+ .IsError() &&
+ CheckPrivateKeyCreationUsages(all_private_key_usages, usages)
+ .IsError()) {
+ return Status::ErrorCreateKeyBadUsages();
+ }
+ return Status::Success();
+ }
+ default:
+ return Status::ErrorUnsupportedImportKeyFormat();
+ }
}
-std::vector<uint8_t> BIGNUMToVector(const BIGNUM* n) {
- std::vector<uint8_t> v(BN_num_bytes(n));
- BN_bn2bin(n, vector_as_array(&v));
- return v;
+Status GetUsagesForGenerateAsymmetricKey(
+ blink::WebCryptoKeyUsageMask combined_usages,
+ blink::WebCryptoKeyUsageMask all_public_usages,
+ blink::WebCryptoKeyUsageMask all_private_usages,
+ blink::WebCryptoKeyUsageMask* public_usages,
+ blink::WebCryptoKeyUsageMask* private_usages) {
+ // Ensure that the combined usages is a subset of the total possible usages.
+ Status status =
+ CheckKeyCreationUsages(all_public_usages | all_private_usages,
+ combined_usages, EmptyUsagePolicy::ALLOW_EMPTY);
+ if (status.IsError())
+ return status;
+
+ *public_usages = combined_usages & all_public_usages;
+ *private_usages = combined_usages & all_private_usages;
+
+ // Ensure that the private key has non-empty usages.
+ return CheckPrivateKeyCreationUsages(all_private_usages, *private_usages);
}
} // namespace webcrypto
diff --git a/components/webcrypto/algorithms/util_openssl.h b/components/webcrypto/algorithms/asymmetric_key_util.h
index f3e4dda..51ed79a 100644
--- a/components/webcrypto/algorithms/util_openssl.h
+++ b/components/webcrypto/algorithms/asymmetric_key_util.h
@@ -1,44 +1,21 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
+// Copyright 2015 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.
-#ifndef COMPONENTS_WEBCRYPTO_ALGORITHMS_UTIL_OPENSSL_H_
-#define COMPONENTS_WEBCRYPTO_ALGORITHMS_UTIL_OPENSSL_H_
-
-#include <string>
-#include <vector>
-
-#include <openssl/base.h>
+#ifndef COMPONENTS_WEBCRYPTO_ALGORITHMS_ASYMMETRIC_KEY_UTIL_
+#define COMPONENTS_WEBCRYPTO_ALGORITHMS_ASYMMETRIC_KEY_UTIL_
#include "crypto/scoped_openssl_types.h"
#include "third_party/WebKit/public/platform/WebCryptoAlgorithm.h"
#include "third_party/WebKit/public/platform/WebCryptoKey.h"
+// This file contains functions shared by multiple asymmetric key algorithms.
+
namespace webcrypto {
class CryptoData;
-class GenerateKeyResult;
class Status;
-// The values of these constants correspond with the "enc" parameter of
-// EVP_CipherInit_ex(), do not change.
-enum EncryptOrDecrypt { DECRYPT = 0, ENCRYPT = 1 };
-
-const EVP_MD* GetDigest(blink::WebCryptoAlgorithmId id);
-
-// Does either encryption or decryption for an AEAD algorithm.
-// * |mode| controls whether encryption or decryption is done
-// * |aead_alg| the algorithm (for instance AES-GCM)
-// * |buffer| where the ciphertext or plaintext is written to.
-Status AeadEncryptDecrypt(EncryptOrDecrypt mode,
- const std::vector<uint8_t>& raw_key,
- const CryptoData& data,
- unsigned int tag_length_bytes,
- const CryptoData& iv,
- const CryptoData& additional_data,
- const EVP_AEAD* aead_alg,
- std::vector<uint8_t>* buffer);
-
// Creates a WebCrypto public key given an EVP_PKEY. This step includes
// exporting the key to SPKI format, for use by serialization later.
Status CreateWebCryptoPublicKey(crypto::ScopedEVP_PKEY public_key,
@@ -55,6 +32,19 @@ Status CreateWebCryptoPrivateKey(crypto::ScopedEVP_PKEY private_key,
blink::WebCryptoKeyUsageMask usages,
blink::WebCryptoKey* key);
+// Checks that a private key can be created using |actual_usages|, where
+// |all_possible_usages| is the full set of allowed private key usages. Note
+// that private keys are not allowed to have empty usages.
+Status CheckPrivateKeyCreationUsages(
+ blink::WebCryptoKeyUsageMask all_possible_usages,
+ blink::WebCryptoKeyUsageMask actual_usages);
+
+// Checks that a public key can be created using |actual_usages|, where
+// |all_possible_usages| is the full set of allowed public key usages
+Status CheckPublicKeyCreationUsages(
+ blink::WebCryptoKeyUsageMask all_possible_usages,
+ blink::WebCryptoKeyUsageMask actual_usages);
+
// Imports SPKI bytes to an EVP_PKEY for a public key. The resulting asymmetric
// key may be invalid, and should be verified using something like
// RSA_check_key(). The only validation performed by this function is to ensure
@@ -71,12 +61,23 @@ Status ImportUnverifiedPkeyFromPkcs8(const CryptoData& key_data,
int expected_pkey_id,
crypto::ScopedEVP_PKEY* pkey);
-// Allocates a new BIGNUM given a std::string big-endian representation.
-BIGNUM* CreateBIGNUM(const std::string& n);
-
-// Converts a BIGNUM to a big endian byte array.
-std::vector<uint8_t> BIGNUMToVector(const BIGNUM* n);
+// Verifies that |usages| is valid when importing a key of the given format.
+Status VerifyUsagesBeforeImportAsymmetricKey(
+ blink::WebCryptoKeyFormat format,
+ blink::WebCryptoKeyUsageMask all_public_key_usages,
+ blink::WebCryptoKeyUsageMask all_private_key_usages,
+ blink::WebCryptoKeyUsageMask usages);
+
+// Splits the combined usages given to GenerateKey() into the respective usages
+// for the public key and private key. Returns an error if the usages are
+// invalid.
+Status GetUsagesForGenerateAsymmetricKey(
+ blink::WebCryptoKeyUsageMask combined_usages,
+ blink::WebCryptoKeyUsageMask all_public_usages,
+ blink::WebCryptoKeyUsageMask all_private_usages,
+ blink::WebCryptoKeyUsageMask* public_usages,
+ blink::WebCryptoKeyUsageMask* private_usages);
} // namespace webcrypto
-#endif // COMPONENTS_WEBCRYPTO_ALGORITHMS_UTIL_OPENSSL_H_
+#endif // COMPONENTS_WEBCRYPTO_ALGORITHMS_ASYMMETRIC_KEY_UTIL_
diff --git a/components/webcrypto/algorithms/ec.cc b/components/webcrypto/algorithms/ec.cc
index 49abbad..20baa57 100644
--- a/components/webcrypto/algorithms/ec.cc
+++ b/components/webcrypto/algorithms/ec.cc
@@ -11,13 +11,13 @@
#include "base/logging.h"
#include "base/stl_util.h"
-#include "components/webcrypto/algorithms/util_openssl.h"
+#include "components/webcrypto/algorithms/asymmetric_key_util.h"
+#include "components/webcrypto/algorithms/util.h"
+#include "components/webcrypto/blink_key_handle.h"
#include "components/webcrypto/crypto_data.h"
#include "components/webcrypto/generate_key_result.h"
#include "components/webcrypto/jwk.h"
-#include "components/webcrypto/key.h"
#include "components/webcrypto/status.h"
-#include "components/webcrypto/webcrypto_util.h"
#include "crypto/openssl_util.h"
#include "crypto/scoped_openssl_types.h"
#include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h"
@@ -209,6 +209,15 @@ Status GetPublicKey(EC_KEY* ec,
return Status::Success();
}
+// Synthesizes an import algorithm given a key algorithm, so that
+// deserialization can re-use the ImportKey*() methods.
+blink::WebCryptoAlgorithm SynthesizeImportAlgorithmForClone(
+ const blink::WebCryptoKeyAlgorithm& algorithm) {
+ return blink::WebCryptoAlgorithm::adoptParamsAndCreate(
+ algorithm.id(), new blink::WebCryptoEcKeyImportParams(
+ algorithm.ecParams()->namedCurve()));
+}
+
} // namespace
Status EcAlgorithm::GenerateKey(const blink::WebCryptoAlgorithm& algorithm,
@@ -379,9 +388,12 @@ Status EcAlgorithm::ImportKeyJwk(const CryptoData& key_data,
bool is_private_key = jwk.HasMember("d");
// Now that the key type is known, verify the usages.
- status = CheckKeyCreationUsages(
- is_private_key ? all_private_key_usages_ : all_public_key_usages_, usages,
- !is_private_key);
+ if (is_private_key) {
+ status = CheckPrivateKeyCreationUsages(all_private_key_usages_, usages);
+ } else {
+ status = CheckPublicKeyCreationUsages(all_public_key_usages_, usages);
+ }
+
if (status.IsError())
return status;
@@ -525,11 +537,12 @@ Status EcAlgorithm::DeserializeKeyForClone(
blink::WebCryptoKeyUsageMask usages,
const CryptoData& key_data,
blink::WebCryptoKey* key) const {
- blink::WebCryptoAlgorithm import_algorithm = CreateEcImportAlgorithm(
- algorithm.id(), algorithm.ecParams()->namedCurve());
+ blink::WebCryptoAlgorithm import_algorithm =
+ SynthesizeImportAlgorithmForClone(algorithm);
Status status;
+ // The serialized data will be either SPKI or PKCS8 formatted.
switch (type) {
case blink::WebCryptoKeyTypePublic:
status =
diff --git a/components/webcrypto/algorithms/ecdh.cc b/components/webcrypto/algorithms/ecdh.cc
index fb63ec2..9da36e9 100644
--- a/components/webcrypto/algorithms/ecdh.cc
+++ b/components/webcrypto/algorithms/ecdh.cc
@@ -10,12 +10,11 @@
#include "base/stl_util.h"
#include "components/webcrypto/algorithm_implementation.h"
#include "components/webcrypto/algorithms/ec.h"
-#include "components/webcrypto/algorithms/util_openssl.h"
+#include "components/webcrypto/algorithms/util.h"
+#include "components/webcrypto/blink_key_handle.h"
#include "components/webcrypto/crypto_data.h"
#include "components/webcrypto/generate_key_result.h"
-#include "components/webcrypto/key.h"
#include "components/webcrypto/status.h"
-#include "components/webcrypto/webcrypto_util.h"
#include "crypto/openssl_util.h"
#include "crypto/scoped_openssl_types.h"
#include "crypto/secure_util.h"
diff --git a/components/webcrypto/algorithms/ecdh_unittest.cc b/components/webcrypto/algorithms/ecdh_unittest.cc
index 9c5b057..961c6d5 100644
--- a/components/webcrypto/algorithms/ecdh_unittest.cc
+++ b/components/webcrypto/algorithms/ecdh_unittest.cc
@@ -4,11 +4,11 @@
#include "base/stl_util.h"
#include "components/webcrypto/algorithm_dispatch.h"
+#include "components/webcrypto/algorithms/ec.h"
#include "components/webcrypto/algorithms/test_helpers.h"
#include "components/webcrypto/crypto_data.h"
#include "components/webcrypto/jwk.h"
#include "components/webcrypto/status.h"
-#include "components/webcrypto/webcrypto_util.h"
#include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h"
#include "third_party/WebKit/public/platform/WebCryptoKeyAlgorithm.h"
diff --git a/components/webcrypto/algorithms/ecdsa.cc b/components/webcrypto/algorithms/ecdsa.cc
index 18857c7..367e0f0 100644
--- a/components/webcrypto/algorithms/ecdsa.cc
+++ b/components/webcrypto/algorithms/ecdsa.cc
@@ -10,12 +10,11 @@
#include "base/stl_util.h"
#include "components/webcrypto/algorithm_implementation.h"
#include "components/webcrypto/algorithms/ec.h"
-#include "components/webcrypto/algorithms/util_openssl.h"
+#include "components/webcrypto/algorithms/util.h"
+#include "components/webcrypto/blink_key_handle.h"
#include "components/webcrypto/crypto_data.h"
#include "components/webcrypto/generate_key_result.h"
-#include "components/webcrypto/key.h"
#include "components/webcrypto/status.h"
-#include "components/webcrypto/webcrypto_util.h"
#include "crypto/openssl_util.h"
#include "crypto/scoped_openssl_types.h"
#include "crypto/secure_util.h"
@@ -34,7 +33,7 @@ Status GetPKeyAndDigest(const blink::WebCryptoAlgorithm& algorithm,
EVP_PKEY** pkey,
const EVP_MD** digest) {
*pkey = GetEVP_PKEY(key);
- *digest = GetDigest(algorithm.ecdsaParams()->hash().id());
+ *digest = GetDigest(algorithm.ecdsaParams()->hash());
if (!*digest)
return Status::ErrorUnsupported();
return Status::Success();
diff --git a/components/webcrypto/algorithms/ecdsa_unittest.cc b/components/webcrypto/algorithms/ecdsa_unittest.cc
index b753f48..4b2e651 100644
--- a/components/webcrypto/algorithms/ecdsa_unittest.cc
+++ b/components/webcrypto/algorithms/ecdsa_unittest.cc
@@ -8,7 +8,6 @@
#include "components/webcrypto/crypto_data.h"
#include "components/webcrypto/jwk.h"
#include "components/webcrypto/status.h"
-#include "components/webcrypto/webcrypto_util.h"
#include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h"
#include "third_party/WebKit/public/platform/WebCryptoKeyAlgorithm.h"
diff --git a/components/webcrypto/algorithms/hkdf.cc b/components/webcrypto/algorithms/hkdf.cc
index d02560d..0ccb8579 100644
--- a/components/webcrypto/algorithms/hkdf.cc
+++ b/components/webcrypto/algorithms/hkdf.cc
@@ -9,11 +9,10 @@
#include "base/stl_util.h"
#include "components/webcrypto/algorithm_implementation.h"
#include "components/webcrypto/algorithms/secret_key_util.h"
-#include "components/webcrypto/algorithms/util_openssl.h"
+#include "components/webcrypto/algorithms/util.h"
+#include "components/webcrypto/blink_key_handle.h"
#include "components/webcrypto/crypto_data.h"
-#include "components/webcrypto/key.h"
#include "components/webcrypto/status.h"
-#include "components/webcrypto/webcrypto_util.h"
#include "crypto/openssl_util.h"
#include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h"
#include "third_party/WebKit/public/platform/WebCryptoKeyAlgorithm.h"
@@ -34,7 +33,7 @@ class HkdfImplementation : public AlgorithmImplementation {
blink::WebCryptoKeyUsageMask usages) const override {
if (format != blink::WebCryptoKeyFormatRaw)
return Status::ErrorUnsupportedImportKeyFormat();
- return CheckKeyCreationUsages(kValidUsages, usages, false);
+ return CheckSecretKeyCreationUsages(kValidUsages, usages);
}
Status ImportKeyRaw(const CryptoData& key_data,
@@ -59,7 +58,7 @@ class HkdfImplementation : public AlgorithmImplementation {
const blink::WebCryptoHkdfParams* params = algorithm.hkdfParams();
- const EVP_MD* digest_algorithm = GetDigest(params->hash().id());
+ const EVP_MD* digest_algorithm = GetDigest(params->hash());
if (!digest_algorithm)
return Status::ErrorUnsupported();
diff --git a/components/webcrypto/algorithms/hmac.cc b/components/webcrypto/algorithms/hmac.cc
index 021facd..28ef3a0 100644
--- a/components/webcrypto/algorithms/hmac.cc
+++ b/components/webcrypto/algorithms/hmac.cc
@@ -9,12 +9,11 @@
#include "base/stl_util.h"
#include "components/webcrypto/algorithm_implementation.h"
#include "components/webcrypto/algorithms/secret_key_util.h"
-#include "components/webcrypto/algorithms/util_openssl.h"
+#include "components/webcrypto/algorithms/util.h"
+#include "components/webcrypto/blink_key_handle.h"
#include "components/webcrypto/crypto_data.h"
#include "components/webcrypto/jwk.h"
-#include "components/webcrypto/key.h"
#include "components/webcrypto/status.h"
-#include "components/webcrypto/webcrypto_util.h"
#include "crypto/openssl_util.h"
#include "crypto/secure_util.h"
#include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h"
@@ -26,7 +25,7 @@ namespace {
Status GetDigestBlockSizeBits(const blink::WebCryptoAlgorithm& algorithm,
unsigned int* block_size_bits) {
- const EVP_MD* md = GetDigest(algorithm.id());
+ const EVP_MD* md = GetDigest(algorithm);
if (!md)
return Status::ErrorUnsupported();
*block_size_bits = static_cast<unsigned int>(8 * EVP_MD_block_size(md));
@@ -89,7 +88,7 @@ Status SignHmac(const std::vector<uint8_t>& raw_key,
std::vector<uint8_t>* buffer) {
crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
- const EVP_MD* digest_algorithm = GetDigest(hash.id());
+ const EVP_MD* digest_algorithm = GetDigest(hash);
if (!digest_algorithm)
return Status::ErrorUnsupported();
size_t hmac_expected_length = EVP_MD_size(digest_algorithm);
@@ -116,7 +115,7 @@ class HmacImplementation : public AlgorithmImplementation {
bool extractable,
blink::WebCryptoKeyUsageMask usages,
GenerateKeyResult* result) const override {
- Status status = CheckKeyCreationUsages(kAllKeyUsages, usages, false);
+ Status status = CheckSecretKeyCreationUsages(kAllKeyUsages, usages);
if (status.IsError())
return status;
@@ -146,7 +145,7 @@ class HmacImplementation : public AlgorithmImplementation {
switch (format) {
case blink::WebCryptoKeyFormatRaw:
case blink::WebCryptoKeyFormatJwk:
- return CheckKeyCreationUsages(kAllKeyUsages, usages, false);
+ return CheckSecretKeyCreationUsages(kAllKeyUsages, usages);
default:
return Status::ErrorUnsupportedImportKeyFormat();
}
diff --git a/components/webcrypto/algorithms/hmac_unittest.cc b/components/webcrypto/algorithms/hmac_unittest.cc
index 11aa759..4c8a67a 100644
--- a/components/webcrypto/algorithms/hmac_unittest.cc
+++ b/components/webcrypto/algorithms/hmac_unittest.cc
@@ -4,11 +4,11 @@
#include "base/logging.h"
#include "base/stl_util.h"
+#include "base/values.h"
#include "components/webcrypto/algorithm_dispatch.h"
#include "components/webcrypto/algorithms/test_helpers.h"
#include "components/webcrypto/crypto_data.h"
#include "components/webcrypto/status.h"
-#include "components/webcrypto/webcrypto_util.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h"
#include "third_party/WebKit/public/platform/WebCryptoKeyAlgorithm.h"
diff --git a/components/webcrypto/algorithms/pbkdf2.cc b/components/webcrypto/algorithms/pbkdf2.cc
index 609e744..b5cf5ca 100644
--- a/components/webcrypto/algorithms/pbkdf2.cc
+++ b/components/webcrypto/algorithms/pbkdf2.cc
@@ -5,11 +5,10 @@
#include "base/stl_util.h"
#include "components/webcrypto/algorithm_implementation.h"
#include "components/webcrypto/algorithms/secret_key_util.h"
-#include "components/webcrypto/algorithms/util_openssl.h"
+#include "components/webcrypto/algorithms/util.h"
+#include "components/webcrypto/blink_key_handle.h"
#include "components/webcrypto/crypto_data.h"
-#include "components/webcrypto/key.h"
#include "components/webcrypto/status.h"
-#include "components/webcrypto/webcrypto_util.h"
#include "crypto/openssl_util.h"
#include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h"
#include "third_party/WebKit/public/platform/WebCryptoKeyAlgorithm.h"
@@ -30,7 +29,7 @@ class Pbkdf2Implementation : public AlgorithmImplementation {
blink::WebCryptoKeyUsageMask usages) const override {
switch (format) {
case blink::WebCryptoKeyFormatRaw:
- return CheckKeyCreationUsages(kAllKeyUsages, usages, false);
+ return CheckSecretKeyCreationUsages(kAllKeyUsages, usages);
default:
return Status::ErrorUnsupportedImportKeyFormat();
}
@@ -64,8 +63,7 @@ class Pbkdf2Implementation : public AlgorithmImplementation {
const blink::WebCryptoPbkdf2Params* params = algorithm.pbkdf2Params();
- const blink::WebCryptoAlgorithm& hash = params->hash();
- const EVP_MD* digest_algorithm = GetDigest(hash.id());
+ const EVP_MD* digest_algorithm = GetDigest(params->hash());
if (!digest_algorithm)
return Status::ErrorUnsupported();
diff --git a/components/webcrypto/algorithms/rsa.cc b/components/webcrypto/algorithms/rsa.cc
index d99f909..892a5a0 100644
--- a/components/webcrypto/algorithms/rsa.cc
+++ b/components/webcrypto/algorithms/rsa.cc
@@ -8,13 +8,13 @@
#include "base/logging.h"
#include "base/stl_util.h"
-#include "components/webcrypto/algorithms/util_openssl.h"
+#include "components/webcrypto/algorithms/asymmetric_key_util.h"
+#include "components/webcrypto/algorithms/util.h"
+#include "components/webcrypto/blink_key_handle.h"
#include "components/webcrypto/crypto_data.h"
#include "components/webcrypto/generate_key_result.h"
#include "components/webcrypto/jwk.h"
-#include "components/webcrypto/key.h"
#include "components/webcrypto/status.h"
-#include "components/webcrypto/webcrypto_util.h"
#include "crypto/openssl_util.h"
#include "crypto/scoped_openssl_types.h"
#include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h"
@@ -104,6 +104,26 @@ Status ReadRsaKeyJwk(const CryptoData& key_data,
return Status::Success();
}
+// Converts a (big-endian) WebCrypto BigInteger, with or without leading zeros,
+// to unsigned int.
+bool BigIntegerToUint(const uint8_t* data,
+ size_t data_size,
+ unsigned int* result) {
+ if (data_size == 0)
+ return false;
+
+ *result = 0;
+ for (size_t i = 0; i < data_size; ++i) {
+ size_t reverse_i = data_size - i - 1;
+
+ if (reverse_i >= sizeof(*result) && data[i])
+ return false; // Too large for a uint.
+
+ *result |= data[i] << 8 * reverse_i;
+ }
+ return true;
+}
+
// Creates a blink::WebCryptoAlgorithm having the modulus length and public
// exponent of |key|.
Status CreateRsaHashedKeyAlgorithm(
@@ -228,6 +248,22 @@ Status ImportRsaPublicKey(const blink::WebCryptoAlgorithm& algorithm,
extractable, usages, key);
}
+// Converts a BIGNUM to a big endian byte array.
+std::vector<uint8_t> BIGNUMToVector(const BIGNUM* n) {
+ std::vector<uint8_t> v(BN_num_bytes(n));
+ BN_bn2bin(n, vector_as_array(&v));
+ return v;
+}
+
+// Synthesizes an import algorithm given a key algorithm, so that
+// deserialization can re-use the ImportKey*() methods.
+blink::WebCryptoAlgorithm SynthesizeImportAlgorithmForClone(
+ const blink::WebCryptoKeyAlgorithm& algorithm) {
+ return blink::WebCryptoAlgorithm::adoptParamsAndCreate(
+ algorithm.id(), new blink::WebCryptoRsaHashedImportParams(
+ algorithm.rsaHashedParams()->hash()));
+}
+
} // namespace
Status RsaHashedAlgorithm::GenerateKey(
@@ -247,12 +283,29 @@ Status RsaHashedAlgorithm::GenerateKey(
const blink::WebCryptoRsaHashedKeyGenParams* params =
algorithm.rsaHashedKeyGenParams();
+ unsigned int modulus_length_bits = params->modulusLengthBits();
+
+ // Limit the RSA key sizes to:
+ // * Multiple of 8 bits
+ // * 256 bits to 16K bits
+ //
+ // These correspond with limitations at the time there was an NSS WebCrypto
+ // implementation. However in practice the upper bound is also helpful
+ // because generating large RSA keys is very slow.
+ if (modulus_length_bits < 256 || modulus_length_bits > 16384 ||
+ (modulus_length_bits % 8) != 0) {
+ return Status::ErrorGenerateRsaUnsupportedModulus();
+ }
+
unsigned int public_exponent = 0;
- unsigned int modulus_length_bits = 0;
- status =
- GetRsaKeyGenParameters(params, &public_exponent, &modulus_length_bits);
- if (status.IsError())
- return status;
+ if (!BigIntegerToUint(params->publicExponent().data(),
+ params->publicExponent().size(), &public_exponent)) {
+ return Status::ErrorGenerateKeyPublicExponent();
+ }
+
+ // OpenSSL hangs when given bad public exponents. Use a whitelist.
+ if (public_exponent != 3 && public_exponent != 65537)
+ return Status::ErrorGenerateKeyPublicExponent();
crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
@@ -380,9 +433,12 @@ Status RsaHashedAlgorithm::ImportKeyJwk(
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 (jwk.is_private_key) {
+ status = CheckPrivateKeyCreationUsages(all_private_key_usages_, usages);
+ } else {
+ status = CheckPublicKeyCreationUsages(all_public_key_usages_, usages);
+ }
+
if (status.IsError())
return status;
@@ -465,11 +521,12 @@ Status RsaHashedAlgorithm::DeserializeKeyForClone(
blink::WebCryptoKeyUsageMask usages,
const CryptoData& key_data,
blink::WebCryptoKey* key) const {
- blink::WebCryptoAlgorithm import_algorithm = CreateRsaHashedImportAlgorithm(
- algorithm.id(), algorithm.rsaHashedParams()->hash().id());
+ blink::WebCryptoAlgorithm import_algorithm =
+ SynthesizeImportAlgorithmForClone(algorithm);
Status status;
+ // The serialized data will be either SPKI or PKCS8 formatted.
switch (type) {
case blink::WebCryptoKeyTypePublic:
status =
diff --git a/components/webcrypto/algorithms/rsa_oaep.cc b/components/webcrypto/algorithms/rsa_oaep.cc
index f68a411..5a697095 100644
--- a/components/webcrypto/algorithms/rsa_oaep.cc
+++ b/components/webcrypto/algorithms/rsa_oaep.cc
@@ -6,9 +6,9 @@
#include "base/stl_util.h"
#include "components/webcrypto/algorithms/rsa.h"
-#include "components/webcrypto/algorithms/util_openssl.h"
+#include "components/webcrypto/algorithms/util.h"
+#include "components/webcrypto/blink_key_handle.h"
#include "components/webcrypto/crypto_data.h"
-#include "components/webcrypto/key.h"
#include "components/webcrypto/status.h"
#include "crypto/openssl_util.h"
#include "crypto/scoped_openssl_types.h"
@@ -42,8 +42,7 @@ Status CommonEncryptDecrypt(InitFunc init_func,
crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
EVP_PKEY* pkey = GetEVP_PKEY(key);
- const EVP_MD* digest =
- GetDigest(key.algorithm().rsaHashedParams()->hash().id());
+ const EVP_MD* digest = GetDigest(key.algorithm().rsaHashedParams()->hash());
if (!digest)
return Status::ErrorUnsupported();
diff --git a/components/webcrypto/algorithms/rsa_oaep_unittest.cc b/components/webcrypto/algorithms/rsa_oaep_unittest.cc
index 6d3811a..32cd135 100644
--- a/components/webcrypto/algorithms/rsa_oaep_unittest.cc
+++ b/components/webcrypto/algorithms/rsa_oaep_unittest.cc
@@ -9,7 +9,6 @@
#include "components/webcrypto/crypto_data.h"
#include "components/webcrypto/jwk.h"
#include "components/webcrypto/status.h"
-#include "components/webcrypto/webcrypto_util.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h"
#include "third_party/WebKit/public/platform/WebCryptoKeyAlgorithm.h"
diff --git a/components/webcrypto/algorithms/rsa_pss_unittest.cc b/components/webcrypto/algorithms/rsa_pss_unittest.cc
index 00ef290..e8b2bfd 100644
--- a/components/webcrypto/algorithms/rsa_pss_unittest.cc
+++ b/components/webcrypto/algorithms/rsa_pss_unittest.cc
@@ -9,7 +9,6 @@
#include "components/webcrypto/crypto_data.h"
#include "components/webcrypto/jwk.h"
#include "components/webcrypto/status.h"
-#include "components/webcrypto/webcrypto_util.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h"
#include "third_party/WebKit/public/platform/WebCryptoKey.h"
diff --git a/components/webcrypto/algorithms/rsa_sign.cc b/components/webcrypto/algorithms/rsa_sign.cc
index 97522ce..5c038b5 100644
--- a/components/webcrypto/algorithms/rsa_sign.cc
+++ b/components/webcrypto/algorithms/rsa_sign.cc
@@ -5,9 +5,9 @@
#include "base/numerics/safe_math.h"
#include "base/stl_util.h"
#include "components/webcrypto/algorithms/rsa_sign.h"
-#include "components/webcrypto/algorithms/util_openssl.h"
+#include "components/webcrypto/algorithms/util.h"
+#include "components/webcrypto/blink_key_handle.h"
#include "components/webcrypto/crypto_data.h"
-#include "components/webcrypto/key.h"
#include "components/webcrypto/status.h"
#include "crypto/openssl_util.h"
#include "crypto/scoped_openssl_types.h"
@@ -24,7 +24,7 @@ Status GetPKeyAndDigest(const blink::WebCryptoKey& key,
const EVP_MD** digest) {
*pkey = GetEVP_PKEY(key);
- *digest = GetDigest(key.algorithm().rsaHashedParams()->hash().id());
+ *digest = GetDigest(key.algorithm().rsaHashedParams()->hash());
if (!*digest)
return Status::ErrorUnsupported();
diff --git a/components/webcrypto/algorithms/rsa_ssa_unittest.cc b/components/webcrypto/algorithms/rsa_ssa_unittest.cc
index 60caa508..31cc967 100644
--- a/components/webcrypto/algorithms/rsa_ssa_unittest.cc
+++ b/components/webcrypto/algorithms/rsa_ssa_unittest.cc
@@ -4,11 +4,11 @@
#include "base/logging.h"
#include "base/stl_util.h"
+#include "base/values.h"
#include "components/webcrypto/algorithm_dispatch.h"
#include "components/webcrypto/algorithms/test_helpers.h"
#include "components/webcrypto/crypto_data.h"
#include "components/webcrypto/status.h"
-#include "components/webcrypto/webcrypto_util.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h"
#include "third_party/WebKit/public/platform/WebCryptoKey.h"
diff --git a/components/webcrypto/algorithms/secret_key_util.cc b/components/webcrypto/algorithms/secret_key_util.cc
index 8e20144..dcdecfa 100644
--- a/components/webcrypto/algorithms/secret_key_util.cc
+++ b/components/webcrypto/algorithms/secret_key_util.cc
@@ -7,12 +7,12 @@
#include <openssl/rand.h>
#include "base/stl_util.h"
+#include "components/webcrypto/algorithms/util.h"
+#include "components/webcrypto/blink_key_handle.h"
#include "components/webcrypto/crypto_data.h"
#include "components/webcrypto/generate_key_result.h"
#include "components/webcrypto/jwk.h"
-#include "components/webcrypto/key.h"
#include "components/webcrypto/status.h"
-#include "components/webcrypto/webcrypto_util.h"
#include "crypto/openssl_util.h"
namespace webcrypto {
@@ -51,6 +51,13 @@ Status CreateWebCryptoSecretKey(const CryptoData& key_data,
return Status::Success();
}
+Status CheckSecretKeyCreationUsages(
+ blink::WebCryptoKeyUsageMask all_possible_usages,
+ blink::WebCryptoKeyUsageMask actual_usages) {
+ return CheckKeyCreationUsages(all_possible_usages, actual_usages,
+ EmptyUsagePolicy::REJECT_EMPTY);
+}
+
void WriteSecretKeyJwk(const CryptoData& raw_key_data,
const std::string& algorithm,
bool extractable,
diff --git a/components/webcrypto/algorithms/secret_key_util.h b/components/webcrypto/algorithms/secret_key_util.h
index 19ebdbb..cfef769 100644
--- a/components/webcrypto/algorithms/secret_key_util.h
+++ b/components/webcrypto/algorithms/secret_key_util.h
@@ -30,7 +30,7 @@ Status GenerateWebCryptoSecretKey(const blink::WebCryptoKeyAlgorithm& algorithm,
unsigned int keylen_bits,
GenerateKeyResult* result);
-// Creates a WebCrypto secret key given a the raw data. The provided |key_data|
+// Creates a WebCrypto secret key given the raw data. The provided |key_data|
// will be copied into the new key. This function does not do any validation
// checks for the provided parameters.
Status CreateWebCryptoSecretKey(const CryptoData& key_data,
@@ -39,6 +39,11 @@ Status CreateWebCryptoSecretKey(const CryptoData& key_data,
blink::WebCryptoKeyUsageMask usages,
blink::WebCryptoKey* key);
+// Checks that |actual_usages| is a non-empty subset of |all_possible_usages|.
+Status CheckSecretKeyCreationUsages(
+ blink::WebCryptoKeyUsageMask all_possible_usages,
+ blink::WebCryptoKeyUsageMask actual_usages);
+
// Writes a JWK-formatted symmetric key to |jwk_key_data|.
// * raw_key_data: The actual key data
// * algorithm: The JWK algorithm name (i.e. "alg")
diff --git a/components/webcrypto/algorithms/sha.cc b/components/webcrypto/algorithms/sha.cc
index cd1a333..2d8b544 100644
--- a/components/webcrypto/algorithms/sha.cc
+++ b/components/webcrypto/algorithms/sha.cc
@@ -9,10 +9,9 @@
#include "base/logging.h"
#include "base/stl_util.h"
#include "components/webcrypto/algorithm_implementation.h"
-#include "components/webcrypto/algorithms/util_openssl.h"
+#include "components/webcrypto/algorithms/util.h"
#include "components/webcrypto/crypto_data.h"
#include "components/webcrypto/status.h"
-#include "components/webcrypto/webcrypto_util.h"
#include "crypto/openssl_util.h"
#include "crypto/scoped_openssl_types.h"
@@ -24,9 +23,9 @@ namespace {
// part of WebCrypto, that allows chunks of data to be streamed in before
// computing a SHA-* digest (as opposed to ShaImplementation, which computes
// digests over complete messages)
-class DigestorOpenSsl : public blink::WebCryptoDigestor {
+class DigestorImpl : public blink::WebCryptoDigestor {
public:
- explicit DigestorOpenSsl(blink::WebCryptoAlgorithmId algorithm_id)
+ explicit DigestorImpl(blink::WebCryptoAlgorithmId algorithm_id)
: initialized_(false),
digest_context_(EVP_MD_CTX_create()),
algorithm_id_(algorithm_id) {}
@@ -112,7 +111,7 @@ class ShaImplementation : public AlgorithmImplementation {
Status Digest(const blink::WebCryptoAlgorithm& algorithm,
const CryptoData& data,
std::vector<uint8_t>* buffer) const override {
- DigestorOpenSsl digestor(algorithm.id());
+ DigestorImpl digestor(algorithm.id());
Status error = digestor.ConsumeWithStatus(data.bytes(), data.byte_length());
// http://crbug.com/366427: the spec does not define any other failures for
// digest, so none of the subsequent errors are spec compliant.
@@ -130,7 +129,7 @@ scoped_ptr<AlgorithmImplementation> CreateShaImplementation() {
scoped_ptr<blink::WebCryptoDigestor> CreateDigestorImplementation(
blink::WebCryptoAlgorithmId algorithm) {
- return scoped_ptr<blink::WebCryptoDigestor>(new DigestorOpenSsl(algorithm));
+ return scoped_ptr<blink::WebCryptoDigestor>(new DigestorImpl(algorithm));
}
} // namespace webcrypto
diff --git a/components/webcrypto/algorithms/sha_unittest.cc b/components/webcrypto/algorithms/sha_unittest.cc
index bc0d04f..4e82d98 100644
--- a/components/webcrypto/algorithms/sha_unittest.cc
+++ b/components/webcrypto/algorithms/sha_unittest.cc
@@ -4,11 +4,11 @@
#include "base/logging.h"
#include "base/stl_util.h"
+#include "base/values.h"
#include "components/webcrypto/algorithm_dispatch.h"
#include "components/webcrypto/algorithms/test_helpers.h"
#include "components/webcrypto/crypto_data.h"
#include "components/webcrypto/status.h"
-#include "components/webcrypto/webcrypto_util.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h"
#include "third_party/WebKit/public/platform/WebCryptoKey.h"
diff --git a/components/webcrypto/algorithms/test_helpers.cc b/components/webcrypto/algorithms/test_helpers.cc
index b096ac3..22db00f 100644
--- a/components/webcrypto/algorithms/test_helpers.cc
+++ b/components/webcrypto/algorithms/test_helpers.cc
@@ -21,7 +21,6 @@
#include "components/webcrypto/generate_key_result.h"
#include "components/webcrypto/jwk.h"
#include "components/webcrypto/status.h"
-#include "components/webcrypto/webcrypto_util.h"
#include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h"
#include "third_party/WebKit/public/platform/WebCryptoKeyAlgorithm.h"
#include "third_party/re2/re2/re2.h"
@@ -663,4 +662,23 @@ blink::WebCryptoAlgorithm CreateHmacImportAlgorithmNoLength(
new blink::WebCryptoHmacImportParams(CreateAlgorithm(hash_id), false, 0));
}
+blink::WebCryptoAlgorithm CreateAlgorithm(blink::WebCryptoAlgorithmId id) {
+ return blink::WebCryptoAlgorithm::adoptParamsAndCreate(id, nullptr);
+}
+
+blink::WebCryptoAlgorithm CreateRsaHashedImportAlgorithm(
+ blink::WebCryptoAlgorithmId id,
+ blink::WebCryptoAlgorithmId hash_id) {
+ DCHECK(blink::WebCryptoAlgorithm::isHash(hash_id));
+ return blink::WebCryptoAlgorithm::adoptParamsAndCreate(
+ id, new blink::WebCryptoRsaHashedImportParams(CreateAlgorithm(hash_id)));
+}
+
+blink::WebCryptoAlgorithm CreateEcImportAlgorithm(
+ blink::WebCryptoAlgorithmId id,
+ blink::WebCryptoNamedCurve named_curve) {
+ return blink::WebCryptoAlgorithm::adoptParamsAndCreate(
+ id, new blink::WebCryptoEcKeyImportParams(named_curve));
+}
+
} // namespace webcrypto
diff --git a/components/webcrypto/algorithms/test_helpers.h b/components/webcrypto/algorithms/test_helpers.h
index 1887255..3cc87d2 100644
--- a/components/webcrypto/algorithms/test_helpers.h
+++ b/components/webcrypto/algorithms/test_helpers.h
@@ -217,6 +217,20 @@ blink::WebCryptoAlgorithm CreateHmacImportAlgorithm(
blink::WebCryptoAlgorithm CreateHmacImportAlgorithmNoLength(
blink::WebCryptoAlgorithmId hash_id);
+// Creates a WebCryptoAlgorithm without any parameters.
+blink::WebCryptoAlgorithm CreateAlgorithm(blink::WebCryptoAlgorithmId id);
+
+// Creates an import algorithm for RSA algorithms that take a hash.
+// It is an error to call this with a hash_id that is not a SHA*.
+blink::WebCryptoAlgorithm CreateRsaHashedImportAlgorithm(
+ blink::WebCryptoAlgorithmId id,
+ blink::WebCryptoAlgorithmId hash_id);
+
+// Creates an import algorithm for EC keys.
+blink::WebCryptoAlgorithm CreateEcImportAlgorithm(
+ blink::WebCryptoAlgorithmId id,
+ blink::WebCryptoNamedCurve named_curve);
+
} // namespace webcrypto
#endif // COMPONENTS_WEBCRYPTO_ALGORITHMS_TEST_HELPERS_H_
diff --git a/components/webcrypto/algorithms/util.cc b/components/webcrypto/algorithms/util.cc
new file mode 100644
index 0000000..43e728c
--- /dev/null
+++ b/components/webcrypto/algorithms/util.cc
@@ -0,0 +1,127 @@
+// 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 "components/webcrypto/algorithms/util.h"
+
+#include <openssl/aead.h>
+#include <openssl/bn.h>
+#include <openssl/digest.h>
+
+#include "base/logging.h"
+#include "base/stl_util.h"
+#include "components/webcrypto/crypto_data.h"
+#include "components/webcrypto/status.h"
+#include "crypto/openssl_util.h"
+#include "crypto/scoped_openssl_types.h"
+
+namespace webcrypto {
+
+const EVP_MD* GetDigest(const blink::WebCryptoAlgorithm& hash_algorithm) {
+ return GetDigest(hash_algorithm.id());
+}
+
+const EVP_MD* GetDigest(blink::WebCryptoAlgorithmId id) {
+ switch (id) {
+ case blink::WebCryptoAlgorithmIdSha1:
+ return EVP_sha1();
+ case blink::WebCryptoAlgorithmIdSha256:
+ return EVP_sha256();
+ case blink::WebCryptoAlgorithmIdSha384:
+ return EVP_sha384();
+ case blink::WebCryptoAlgorithmIdSha512:
+ return EVP_sha512();
+ default:
+ return NULL;
+ }
+}
+
+void TruncateToBitLength(size_t length_bits, std::vector<uint8_t>* bytes) {
+ size_t length_bytes = NumBitsToBytes(length_bits);
+
+ if (bytes->size() != length_bytes) {
+ CHECK_LT(length_bytes, bytes->size());
+ bytes->resize(length_bytes);
+ }
+
+ size_t remainder_bits = length_bits % 8;
+
+ // Zero any "unused bits" in the final byte.
+ if (remainder_bits)
+ (*bytes)[bytes->size() - 1] &= ~((0xFF) >> remainder_bits);
+}
+
+Status CheckKeyCreationUsages(blink::WebCryptoKeyUsageMask all_possible_usages,
+ blink::WebCryptoKeyUsageMask actual_usages,
+ EmptyUsagePolicy empty_usage_policy) {
+ if (actual_usages == 0 &&
+ empty_usage_policy == EmptyUsagePolicy::REJECT_EMPTY) {
+ return Status::ErrorCreateKeyEmptyUsages();
+ }
+
+ if (!ContainsKeyUsages(all_possible_usages, actual_usages))
+ return Status::ErrorCreateKeyBadUsages();
+ return Status::Success();
+}
+
+bool ContainsKeyUsages(blink::WebCryptoKeyUsageMask a,
+ blink::WebCryptoKeyUsageMask b) {
+ return (a & b) == b;
+}
+
+BIGNUM* CreateBIGNUM(const std::string& n) {
+ return BN_bin2bn(reinterpret_cast<const uint8_t*>(n.data()), n.size(), NULL);
+}
+
+Status AeadEncryptDecrypt(EncryptOrDecrypt mode,
+ const std::vector<uint8_t>& raw_key,
+ const CryptoData& data,
+ unsigned int tag_length_bytes,
+ const CryptoData& iv,
+ const CryptoData& additional_data,
+ const EVP_AEAD* aead_alg,
+ std::vector<uint8_t>* buffer) {
+ crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
+ EVP_AEAD_CTX ctx;
+
+ if (!aead_alg)
+ return Status::ErrorUnexpected();
+
+ if (!EVP_AEAD_CTX_init(&ctx, aead_alg, vector_as_array(&raw_key),
+ raw_key.size(), tag_length_bytes, NULL)) {
+ return Status::OperationError();
+ }
+
+ crypto::ScopedOpenSSL<EVP_AEAD_CTX, EVP_AEAD_CTX_cleanup> ctx_cleanup(&ctx);
+
+ size_t len;
+ int ok;
+
+ if (mode == DECRYPT) {
+ if (data.byte_length() < tag_length_bytes)
+ return Status::ErrorDataTooSmall();
+
+ buffer->resize(data.byte_length() - tag_length_bytes);
+
+ ok = EVP_AEAD_CTX_open(&ctx, vector_as_array(buffer), &len, buffer->size(),
+ iv.bytes(), iv.byte_length(), data.bytes(),
+ data.byte_length(), additional_data.bytes(),
+ additional_data.byte_length());
+ } else {
+ // No need to check for unsigned integer overflow here (seal fails if
+ // the output buffer is too small).
+ buffer->resize(data.byte_length() + EVP_AEAD_max_overhead(aead_alg));
+
+ ok = EVP_AEAD_CTX_seal(&ctx, vector_as_array(buffer), &len, buffer->size(),
+ iv.bytes(), iv.byte_length(), data.bytes(),
+ data.byte_length(), additional_data.bytes(),
+ additional_data.byte_length());
+ }
+
+ if (!ok)
+ return Status::OperationError();
+ buffer->resize(len);
+ return Status::Success();
+}
+
+} // namespace webcrypto
diff --git a/components/webcrypto/algorithms/util.h b/components/webcrypto/algorithms/util.h
new file mode 100644
index 0000000..8fa2926
--- /dev/null
+++ b/components/webcrypto/algorithms/util.h
@@ -0,0 +1,96 @@
+// 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.
+
+#ifndef COMPONENTS_WEBCRYPTO_ALGORITHMS_UTIL_H_
+#define COMPONENTS_WEBCRYPTO_ALGORITHMS_UTIL_H_
+
+#include <string>
+#include <vector>
+
+#include <openssl/base.h>
+
+#include "third_party/WebKit/public/platform/WebCryptoAlgorithm.h"
+#include "third_party/WebKit/public/platform/WebCryptoKey.h"
+
+// This file contains miscellaneous helpers that don't belong in any of the
+// other *_util.h
+
+namespace webcrypto {
+
+class CryptoData;
+class GenerateKeyResult;
+class Status;
+
+// Returns the EVP_MD that corresponds with |hash_algorithm|, or nullptr on
+// failure.
+const EVP_MD* GetDigest(const blink::WebCryptoAlgorithm& hash_algorithm);
+
+// Returns the EVP_MD that corresponds with |id|, or nullptr on failure.
+const EVP_MD* GetDigest(blink::WebCryptoAlgorithmId id);
+
+// Truncates an octet string to a particular bit length. This is accomplished by
+// resizing to the closest byte length, and then zero-ing the unused
+// least-significant bits of the final byte.
+//
+// It is an error to call this function with a bit length that is larger than
+// that of |bytes|.
+//
+// TODO(eroman): This operation is not yet defined by the WebCrypto spec,
+// however this is a reasonable interpretation:
+// https://www.w3.org/Bugs/Public/show_bug.cgi?id=27402
+void TruncateToBitLength(size_t length_bits, std::vector<uint8_t>* bytes);
+
+// Rounds a bit count (up) to the nearest byte count.
+//
+// This is mathematically equivalent to (x + 7) / 8, however has no
+// possibility of integer overflow.
+template <typename T>
+T NumBitsToBytes(T x) {
+ return (x / 8) + (7 + (x % 8)) / 8;
+}
+
+enum class EmptyUsagePolicy {
+ // Allow keys to have empty usages.
+ ALLOW_EMPTY,
+
+ // Do not allow keys to have empty usages.
+ REJECT_EMPTY,
+};
+
+// Verifies whether a key can be created using |actual_usages| when the
+// algorithm supports |all_possible_usages|.
+Status CheckKeyCreationUsages(blink::WebCryptoKeyUsageMask all_possible_usages,
+ blink::WebCryptoKeyUsageMask actual_usages,
+ EmptyUsagePolicy empty_usage_policy);
+
+// TODO(eroman): This doesn't really belong in this file. Move it into Blink
+// instead.
+//
+// Returns true if the set bits in b make up a subset of the set bits in a.
+bool ContainsKeyUsages(blink::WebCryptoKeyUsageMask a,
+ blink::WebCryptoKeyUsageMask b);
+
+// Allocates a new BIGNUM given a std::string big-endian representation.
+BIGNUM* CreateBIGNUM(const std::string& n);
+
+// The values of these constants correspond with the "enc" parameter of
+// EVP_CipherInit_ex(), do not change.
+enum EncryptOrDecrypt { DECRYPT = 0, ENCRYPT = 1 };
+
+// Does either encryption or decryption for an AEAD algorithm.
+// * |mode| controls whether encryption or decryption is done
+// * |aead_alg| the algorithm (for instance AES-GCM)
+// * |buffer| where the ciphertext or plaintext is written to.
+Status AeadEncryptDecrypt(EncryptOrDecrypt mode,
+ const std::vector<uint8_t>& raw_key,
+ const CryptoData& data,
+ unsigned int tag_length_bytes,
+ const CryptoData& iv,
+ const CryptoData& additional_data,
+ const EVP_AEAD* aead_alg,
+ std::vector<uint8_t>* buffer);
+
+} // namespace webcrypto
+
+#endif // COMPONENTS_WEBCRYPTO_ALGORITHMS_UTIL_H_
diff --git a/components/webcrypto/key.cc b/components/webcrypto/blink_key_handle.cc
index 3fe3fe8..6b8c1f4 100644
--- a/components/webcrypto/key.cc
+++ b/components/webcrypto/blink_key_handle.cc
@@ -2,13 +2,12 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "components/webcrypto/key.h"
+#include "components/webcrypto/blink_key_handle.h"
#include "base/logging.h"
#include "base/macros.h"
#include "components/webcrypto/crypto_data.h"
#include "components/webcrypto/status.h"
-#include "components/webcrypto/webcrypto_util.h"
namespace webcrypto {
diff --git a/components/webcrypto/key.h b/components/webcrypto/blink_key_handle.h
index 60fa5d4..049657c 100644
--- a/components/webcrypto/key.h
+++ b/components/webcrypto/blink_key_handle.h
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef COMPONENTS_WEBCRYPTO_KEY_H_
-#define COMPONENTS_WEBCRYPTO_KEY_H_
+#ifndef COMPONENTS_WEBCRYPTO_BLINK_KEY_HANDLE_H_
+#define COMPONENTS_WEBCRYPTO_BLINK_KEY_HANDLE_H_
#include <openssl/base.h>
#include <stdint.h>
@@ -13,6 +13,14 @@
#include "crypto/scoped_openssl_types.h"
#include "third_party/WebKit/public/platform/WebCryptoKey.h"
+// Blink keys (blink::WebCryptoKey) have an associated key handle
+// (blink::WebCryptoKeyHandle) used to store custom data. This is where the
+// underlying EVP_PKEY is stored for asymmetric keys, or an std::vector
+// containing the bytes for symmetric keys.
+//
+// This file contains helpers for creating the key handles, and extracting
+// properties from it.
+
namespace webcrypto {
class CryptoData;
@@ -50,4 +58,4 @@ blink::WebCryptoKeyHandle* CreateAsymmetricKeyHandle(
} // namespace webcrypto
-#endif // COMPONENTS_WEBCRYPTO_KEY_H_
+#endif // COMPONENTS_WEBCRYPTO_BLINK_KEY_HANDLE_H_
diff --git a/components/webcrypto/jwk.cc b/components/webcrypto/jwk.cc
index 1a3245a..023ea82 100644
--- a/components/webcrypto/jwk.cc
+++ b/components/webcrypto/jwk.cc
@@ -12,9 +12,9 @@
#include "base/stl_util.h"
#include "base/strings/string_piece.h"
#include "base/strings/stringprintf.h"
+#include "components/webcrypto/algorithms/util.h"
#include "components/webcrypto/crypto_data.h"
#include "components/webcrypto/status.h"
-#include "components/webcrypto/webcrypto_util.h"
// JSON Web Key Format (JWK) is defined by:
// http://tools.ietf.org/html/draft-ietf-jose-json-web-key
diff --git a/components/webcrypto/status_unittest.cc b/components/webcrypto/status_unittest.cc
index 3102f77..ad79136 100644
--- a/components/webcrypto/status_unittest.cc
+++ b/components/webcrypto/status_unittest.cc
@@ -7,7 +7,6 @@
#include "components/webcrypto/algorithms/test_helpers.h"
#include "components/webcrypto/crypto_data.h"
#include "components/webcrypto/status.h"
-#include "components/webcrypto/webcrypto_util.h"
#include "third_party/WebKit/public/platform/WebCryptoAlgorithm.h"
#include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h"
#include "third_party/WebKit/public/platform/WebCryptoKeyAlgorithm.h"
diff --git a/components/webcrypto/webcrypto.gyp b/components/webcrypto/webcrypto.gyp
index fef6ead..e4cf9af 100644
--- a/components/webcrypto/webcrypto.gyp
+++ b/components/webcrypto/webcrypto.gyp
@@ -30,6 +30,8 @@
'algorithms/aes_ctr.cc',
'algorithms/aes_gcm.cc',
'algorithms/aes_kw.cc',
+ 'algorithms/asymmetric_key_util.cc',
+ 'algorithms/asymmetric_key_util.h',
'algorithms/ec.cc',
'algorithms/ec.h',
'algorithms/ecdh.cc',
@@ -47,22 +49,20 @@
'algorithms/secret_key_util.cc',
'algorithms/secret_key_util.h',
'algorithms/sha.cc',
- 'algorithms/util_openssl.cc',
- 'algorithms/util_openssl.h',
+ 'algorithms/util.cc',
+ 'algorithms/util.h',
+ 'blink_key_handle.cc',
+ 'blink_key_handle.h',
'crypto_data.cc',
'crypto_data.h',
'generate_key_result.cc',
'generate_key_result.h',
'jwk.cc',
'jwk.h',
- 'key.cc',
- 'key.h',
'status.cc',
'status.h',
'webcrypto_impl.cc',
'webcrypto_impl.h',
- 'webcrypto_util.cc',
- 'webcrypto_util.h',
],
},
],
diff --git a/components/webcrypto/webcrypto_impl.cc b/components/webcrypto/webcrypto_impl.cc
index cdc075c..71d4b2b 100644
--- a/components/webcrypto/webcrypto_impl.cc
+++ b/components/webcrypto/webcrypto_impl.cc
@@ -19,7 +19,6 @@
#include "components/webcrypto/crypto_data.h"
#include "components/webcrypto/generate_key_result.h"
#include "components/webcrypto/status.h"
-#include "components/webcrypto/webcrypto_util.h"
#include "third_party/WebKit/public/platform/WebCryptoKeyAlgorithm.h"
#include "third_party/WebKit/public/platform/WebString.h"
diff --git a/components/webcrypto/webcrypto_util.cc b/components/webcrypto/webcrypto_util.cc
deleted file mode 100644
index 26d428f..0000000
--- a/components/webcrypto/webcrypto_util.cc
+++ /dev/null
@@ -1,168 +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 "components/webcrypto/webcrypto_util.h"
-
-#include "base/logging.h"
-#include "components/webcrypto/status.h"
-#include "third_party/WebKit/public/platform/WebCryptoAlgorithm.h"
-#include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h"
-#include "third_party/WebKit/public/platform/WebCryptoKeyAlgorithm.h"
-
-namespace webcrypto {
-
-namespace {
-
-// Converts a (big-endian) WebCrypto BigInteger, with or without leading zeros,
-// to unsigned int.
-bool BigIntegerToUint(const uint8_t* data,
- size_t data_size,
- unsigned int* result) {
- if (data_size == 0)
- return false;
-
- *result = 0;
- for (size_t i = 0; i < data_size; ++i) {
- size_t reverse_i = data_size - i - 1;
-
- if (reverse_i >= sizeof(*result) && data[i])
- return false; // Too large for a uint.
-
- *result |= data[i] << 8 * reverse_i;
- }
- return true;
-}
-
-
-} // namespace
-
-blink::WebCryptoAlgorithm CreateAlgorithm(blink::WebCryptoAlgorithmId id) {
- return blink::WebCryptoAlgorithm::adoptParamsAndCreate(id, NULL);
-}
-
-blink::WebCryptoAlgorithm CreateRsaHashedImportAlgorithm(
- blink::WebCryptoAlgorithmId id,
- blink::WebCryptoAlgorithmId hash_id) {
- DCHECK(blink::WebCryptoAlgorithm::isHash(hash_id));
- return blink::WebCryptoAlgorithm::adoptParamsAndCreate(
- id, new blink::WebCryptoRsaHashedImportParams(CreateAlgorithm(hash_id)));
-}
-
-blink::WebCryptoAlgorithm CreateEcImportAlgorithm(
- blink::WebCryptoAlgorithmId id,
- blink::WebCryptoNamedCurve named_curve) {
- return blink::WebCryptoAlgorithm::adoptParamsAndCreate(
- id, new blink::WebCryptoEcKeyImportParams(named_curve));
-}
-
-bool ContainsKeyUsages(blink::WebCryptoKeyUsageMask a,
- blink::WebCryptoKeyUsageMask b) {
- return (a & b) == b;
-}
-
-
-Status CheckKeyCreationUsages(blink::WebCryptoKeyUsageMask all_possible_usages,
- blink::WebCryptoKeyUsageMask actual_usages,
- bool allow_empty_usages) {
- if (!allow_empty_usages && actual_usages == 0)
- return Status::ErrorCreateKeyEmptyUsages();
-
- if (!ContainsKeyUsages(all_possible_usages, actual_usages))
- return Status::ErrorCreateKeyBadUsages();
- return Status::Success();
-}
-
-Status GetRsaKeyGenParameters(
- const blink::WebCryptoRsaHashedKeyGenParams* params,
- unsigned int* public_exponent,
- unsigned int* modulus_length_bits) {
- *modulus_length_bits = params->modulusLengthBits();
-
- // Limit the RSA key sizes to:
- // * Multiple of 8 bits
- // * 256 bits to 16K bits
- // This corresponds to the values that NSS would allow, which was relevant
- // back when Chromium's WebCrypto supported both OpenSSL and NSS.
- if (*modulus_length_bits < 256 || *modulus_length_bits > 16384 ||
- (*modulus_length_bits % 8) != 0) {
- return Status::ErrorGenerateRsaUnsupportedModulus();
- }
-
- if (!BigIntegerToUint(params->publicExponent().data(),
- params->publicExponent().size(), public_exponent)) {
- return Status::ErrorGenerateKeyPublicExponent();
- }
-
- // OpenSSL hangs when given bad public exponents. Use a whitelist to avoid
- // feeding OpenSSL data that could hang.
- if (*public_exponent != 3 && *public_exponent != 65537)
- return Status::ErrorGenerateKeyPublicExponent();
-
- return Status::Success();
-}
-
-Status VerifyUsagesBeforeImportAsymmetricKey(
- blink::WebCryptoKeyFormat format,
- blink::WebCryptoKeyUsageMask all_public_key_usages,
- blink::WebCryptoKeyUsageMask all_private_key_usages,
- blink::WebCryptoKeyUsageMask usages) {
- switch (format) {
- case blink::WebCryptoKeyFormatSpki:
- return CheckKeyCreationUsages(all_public_key_usages, usages, true);
- case blink::WebCryptoKeyFormatPkcs8:
- return CheckKeyCreationUsages(all_private_key_usages, usages, false);
- case blink::WebCryptoKeyFormatJwk: {
- // 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_public_key_usages, usages, true)
- .IsError() &&
- CheckKeyCreationUsages(all_private_key_usages, usages, false)
- .IsError()) {
- return Status::ErrorCreateKeyBadUsages();
- }
- return Status::Success();
- }
- default:
- return Status::ErrorUnsupportedImportKeyFormat();
- }
-}
-
-void TruncateToBitLength(size_t length_bits, std::vector<uint8_t>* bytes) {
- size_t length_bytes = NumBitsToBytes(length_bits);
-
- if (bytes->size() != length_bytes) {
- CHECK_LT(length_bytes, bytes->size());
- bytes->resize(length_bytes);
- }
-
- size_t remainder_bits = length_bits % 8;
-
- // Zero any "unused bits" in the final byte
- if (remainder_bits)
- (*bytes)[bytes->size() - 1] &= ~((0xFF) >> remainder_bits);
-}
-
-
-Status GetUsagesForGenerateAsymmetricKey(
- blink::WebCryptoKeyUsageMask combined_usages,
- blink::WebCryptoKeyUsageMask all_public_usages,
- blink::WebCryptoKeyUsageMask all_private_usages,
- blink::WebCryptoKeyUsageMask* public_usages,
- blink::WebCryptoKeyUsageMask* private_usages) {
- Status status = CheckKeyCreationUsages(all_public_usages | all_private_usages,
- combined_usages, true);
- if (status.IsError())
- return status;
-
- *public_usages = combined_usages & all_public_usages;
- *private_usages = combined_usages & all_private_usages;
-
- if (*private_usages == 0)
- return Status::ErrorCreateKeyEmptyUsages();
-
- return Status::Success();
-}
-
-} // namespace webcrypto
diff --git a/components/webcrypto/webcrypto_util.h b/components/webcrypto/webcrypto_util.h
deleted file mode 100644
index b9b69d0..0000000
--- a/components/webcrypto/webcrypto_util.h
+++ /dev/null
@@ -1,97 +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.
-
-#ifndef COMPONENTS_WEBCRYPTO_WEBCRYPTO_UTIL_H_
-#define COMPONENTS_WEBCRYPTO_WEBCRYPTO_UTIL_H_
-
-#include <stdint.h>
-#include <string>
-
-#include "base/values.h"
-#include "third_party/WebKit/public/platform/WebCryptoAlgorithm.h"
-#include "third_party/WebKit/public/platform/WebCryptoKey.h"
-
-// TODO(eroman): The remaining functions in this file need to be sorted
-// out. They should be moved to a more domain specific location (for
-// instance test helpers, asymmetric algorithm helpers, etc.).
-
-namespace webcrypto {
-
-class Status;
-
-// Creates a WebCryptoAlgorithm without any parameters.
-blink::WebCryptoAlgorithm CreateAlgorithm(blink::WebCryptoAlgorithmId id);
-
-// Creates an import algorithm for RSA algorithms that take a hash.
-// It is an error to call this with a hash_id that is not a SHA*.
-blink::WebCryptoAlgorithm CreateRsaHashedImportAlgorithm(
- blink::WebCryptoAlgorithmId id,
- blink::WebCryptoAlgorithmId hash_id);
-
-// Creates an import algorithm for EC keys.
-blink::WebCryptoAlgorithm CreateEcImportAlgorithm(
- blink::WebCryptoAlgorithmId id,
- blink::WebCryptoNamedCurve named_curve);
-
-// Returns true if the set bits in b make up a subset of the set bits in a.
-bool ContainsKeyUsages(blink::WebCryptoKeyUsageMask a,
- blink::WebCryptoKeyUsageMask b);
-
-Status CheckKeyCreationUsages(blink::WebCryptoKeyUsageMask all_possible_usages,
- blink::WebCryptoKeyUsageMask actual_usages,
- bool allow_empty_usages);
-
-// Extracts the public exponent and modulus length from the Blink parameters.
-// On success it is guaranteed that:
-// * public_exponent is either 3 or 65537
-// * modulus_length_bits is a multiple of 8
-// * modulus_length is >= 256
-// * modulus_length is <= 16K
-Status GetRsaKeyGenParameters(
- const blink::WebCryptoRsaHashedKeyGenParams* params,
- unsigned int* public_exponent,
- unsigned int* modulus_length_bits);
-
-// Verifies that |usages| is valid when importing a key of the given format.
-Status VerifyUsagesBeforeImportAsymmetricKey(
- blink::WebCryptoKeyFormat format,
- blink::WebCryptoKeyUsageMask all_public_key_usages,
- blink::WebCryptoKeyUsageMask all_private_key_usages,
- blink::WebCryptoKeyUsageMask usages);
-
-// Truncates an octet string to a particular bit length. This is accomplished by
-// resizing to the closest byte length, and then zero-ing the unused
-// least-significant bits of the final byte.
-//
-// It is an error to call this function with a bit length that is larger than
-// that of |bytes|.
-//
-// TODO(eroman): This operation is not yet defined by the WebCrypto spec,
-// however this is a reasonable interpretation:
-// https://www.w3.org/Bugs/Public/show_bug.cgi?id=27402
-void TruncateToBitLength(size_t length_bits, std::vector<uint8_t>* bytes);
-
-// Rounds a bit count (up) to the nearest byte count.
-//
-// This is mathematically equivalent to (x + 7) / 8, however has no
-// possibility of integer overflow.
-template <typename T>
-T NumBitsToBytes(T x) {
- return (x / 8) + (7 + (x % 8)) / 8;
-}
-
-
-// Splits the combined usages given to GenerateKey() into the respective usages
-// for the public key and private key. Returns an error if the usages are
-// invalid.
-Status GetUsagesForGenerateAsymmetricKey(
- blink::WebCryptoKeyUsageMask combined_usages,
- blink::WebCryptoKeyUsageMask all_public_usages,
- blink::WebCryptoKeyUsageMask all_private_usages,
- blink::WebCryptoKeyUsageMask* public_usages,
- blink::WebCryptoKeyUsageMask* private_usages);
-
-} // namespace webcrypto
-
-#endif // COMPONENTS_WEBCRYPTO_WEBCRYPTO_UTIL_H_