Commit 9b747eaf authored by eroman's avatar eroman Committed by Commit bot

Refactor the interface for generating keys.

This allows the removal of the IsAlgorithmAsymmetric() helper.

BUG=407846

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

Cr-Commit-Position: refs/heads/master@{#300219}
parent 1c141bed
......@@ -102,45 +102,16 @@ Status Digest(const blink::WebCryptoAlgorithm& algorithm,
return impl->Digest(algorithm, data, buffer);
}
Status GenerateSecretKey(const blink::WebCryptoAlgorithm& algorithm,
Status GenerateKey(const blink::WebCryptoAlgorithm& algorithm,
bool extractable,
blink::WebCryptoKeyUsageMask usage_mask,
blink::WebCryptoKey* key) {
GenerateKeyResult* result) {
const AlgorithmImplementation* impl = NULL;
Status status = GetAlgorithmImplementation(algorithm.id(), &impl);
if (status.IsError())
return status;
status = impl->VerifyKeyUsagesBeforeGenerateKey(usage_mask);
if (status.IsError())
return status;
return impl->GenerateSecretKey(algorithm, extractable, usage_mask, key);
}
Status GenerateKeyPair(const blink::WebCryptoAlgorithm& algorithm,
bool extractable,
blink::WebCryptoKeyUsageMask combined_usage_mask,
blink::WebCryptoKey* public_key,
blink::WebCryptoKey* private_key) {
const AlgorithmImplementation* impl = NULL;
Status status = GetAlgorithmImplementation(algorithm.id(), &impl);
if (status.IsError())
return status;
blink::WebCryptoKeyUsageMask public_usage_mask;
blink::WebCryptoKeyUsageMask private_usage_mask;
status = impl->VerifyKeyUsagesBeforeGenerateKeyPair(
combined_usage_mask, &public_usage_mask, &private_usage_mask);
if (status.IsError())
return status;
return impl->GenerateKeyPair(algorithm,
extractable,
public_usage_mask,
private_usage_mask,
public_key,
private_key);
return impl->GenerateKey(algorithm, extractable, usage_mask, result);
}
// Note that this function may be called from the target Blink thread.
......
......@@ -18,6 +18,7 @@ namespace webcrypto {
class AlgorithmImplementation;
class CryptoData;
class GenerateKeyResult;
class Status;
// These functions provide an entry point for synchronous webcrypto operations.
......@@ -42,18 +43,10 @@ CONTENT_EXPORT Status Digest(const blink::WebCryptoAlgorithm& algorithm,
const CryptoData& data,
std::vector<uint8_t>* buffer);
CONTENT_EXPORT Status
GenerateSecretKey(const blink::WebCryptoAlgorithm& algorithm,
bool extractable,
blink::WebCryptoKeyUsageMask usage_mask,
blink::WebCryptoKey* key);
CONTENT_EXPORT Status
GenerateKeyPair(const blink::WebCryptoAlgorithm& algorithm,
CONTENT_EXPORT Status GenerateKey(const blink::WebCryptoAlgorithm& algorithm,
bool extractable,
blink::WebCryptoKeyUsageMask usage_mask,
blink::WebCryptoKey* public_key,
blink::WebCryptoKey* private_key);
GenerateKeyResult* result);
CONTENT_EXPORT Status ImportKey(blink::WebCryptoKeyFormat format,
const CryptoData& key_data,
......
......@@ -52,34 +52,11 @@ Status AlgorithmImplementation::Digest(
return Status::ErrorUnsupported();
}
Status AlgorithmImplementation::VerifyKeyUsagesBeforeGenerateKey(
blink::WebCryptoKeyUsageMask usage_mask) const {
return Status::ErrorUnsupported();
}
Status AlgorithmImplementation::VerifyKeyUsagesBeforeGenerateKeyPair(
blink::WebCryptoKeyUsageMask usage_mask,
blink::WebCryptoKeyUsageMask* public_usage_mask,
blink::WebCryptoKeyUsageMask* private_usage_mask) const {
*public_usage_mask = *private_usage_mask = 0;
return Status::ErrorUnsupported();
}
Status AlgorithmImplementation::GenerateSecretKey(
Status AlgorithmImplementation::GenerateKey(
const blink::WebCryptoAlgorithm& algorithm,
bool extractable,
blink::WebCryptoKeyUsageMask usage_mask,
blink::WebCryptoKey* key) const {
return Status::ErrorUnsupported();
}
Status AlgorithmImplementation::GenerateKeyPair(
const blink::WebCryptoAlgorithm& algorithm,
bool extractable,
blink::WebCryptoKeyUsageMask public_usage_mask,
blink::WebCryptoKeyUsageMask private_usage_mask,
blink::WebCryptoKey* public_key,
blink::WebCryptoKey* private_key) const {
GenerateKeyResult* result) const {
return Status::ErrorUnsupported();
}
......
......@@ -16,6 +16,7 @@ namespace content {
namespace webcrypto {
class CryptoData;
class GenerateKeyResult;
class Status;
// AlgorithmImplementation is a base class for *executing* the operations of an
......@@ -71,32 +72,14 @@ class AlgorithmImplementation {
const CryptoData& data,
std::vector<uint8_t>* buffer) const;
// VerifyKeyUsagesBeforeGenerateKey() must be called prior to
// GenerateSecretKey() to validate the requested key usages.
virtual Status VerifyKeyUsagesBeforeGenerateKey(
blink::WebCryptoKeyUsageMask usage_mask) const;
// This method corresponds to Web Crypto's crypto.subtle.generateKey().
virtual Status GenerateSecretKey(const blink::WebCryptoAlgorithm& algorithm,
//
// Implementations MUST verify |usage_mask| and return an error if it is not
// appropriate.
virtual Status GenerateKey(const blink::WebCryptoAlgorithm& algorithm,
bool extractable,
blink::WebCryptoKeyUsageMask usage_mask,
blink::WebCryptoKey* key) const;
// VerifyKeyUsagesBeforeGenerateKeyPair() must be called prior to
// GenerateKeyPair() to validate the requested key usages.
virtual Status VerifyKeyUsagesBeforeGenerateKeyPair(
blink::WebCryptoKeyUsageMask combined_usage_mask,
blink::WebCryptoKeyUsageMask* public_usage_mask,
blink::WebCryptoKeyUsageMask* private_usage_mask) const;
// This method corresponds to Web Crypto's crypto.subtle.generateKey().
virtual Status GenerateKeyPair(
const blink::WebCryptoAlgorithm& algorithm,
bool extractable,
blink::WebCryptoKeyUsageMask public_usage_mask,
blink::WebCryptoKeyUsageMask private_usage_mask,
blink::WebCryptoKey* public_key,
blink::WebCryptoKey* private_key) const;
GenerateKeyResult* result) const;
// -----------------------------------------------
// Key import
......
// 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/generate_key_result.h"
#include "base/logging.h"
namespace content {
namespace webcrypto {
GenerateKeyResult::GenerateKeyResult()
: type_(TYPE_NULL),
secret_key_(blink::WebCryptoKey::createNull()),
public_key_(blink::WebCryptoKey::createNull()),
private_key_(blink::WebCryptoKey::createNull()) {
}
GenerateKeyResult::Type GenerateKeyResult::type() const {
return type_;
}
const blink::WebCryptoKey& GenerateKeyResult::secret_key() const {
DCHECK_EQ(TYPE_SECRET_KEY, type_);
return secret_key_;
}
const blink::WebCryptoKey& GenerateKeyResult::public_key() const {
DCHECK_EQ(TYPE_PUBLIC_PRIVATE_KEY_PAIR, type_);
return public_key_;
}
const blink::WebCryptoKey& GenerateKeyResult::private_key() const {
DCHECK_EQ(TYPE_PUBLIC_PRIVATE_KEY_PAIR, type_);
return private_key_;
}
void GenerateKeyResult::AssignSecretKey(const blink::WebCryptoKey& key) {
type_ = TYPE_SECRET_KEY;
secret_key_ = key;
}
void GenerateKeyResult::AssignKeyPair(const blink::WebCryptoKey& public_key,
const blink::WebCryptoKey& private_key) {
type_ = TYPE_PUBLIC_PRIVATE_KEY_PAIR;
public_key_ = public_key;
private_key_ = private_key;
}
void GenerateKeyResult::Complete(blink::WebCryptoResult* out) const {
switch (type_) {
case TYPE_NULL:
NOTREACHED();
break;
case TYPE_SECRET_KEY:
out->completeWithKey(secret_key());
break;
case TYPE_PUBLIC_PRIVATE_KEY_PAIR:
out->completeWithKeyPair(public_key(), private_key());
break;
}
}
} // namespace webcrypto
} // namespace content
// 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 CONTENT_CHILD_WEBCRYPTO_GENERATE_KEY_RESULT_H_
#define CONTENT_CHILD_WEBCRYPTO_GENERATE_KEY_RESULT_H_
#include "content/common/content_export.h"
#include "third_party/WebKit/public/platform/WebCrypto.h"
namespace content {
namespace webcrypto {
// This is the result object when generating keys. It encapsulates either a
// secret key, or a public/private key pair.
class CONTENT_EXPORT GenerateKeyResult {
public:
enum Type {
// An empty (or "null") result.
TYPE_NULL,
// The result is a secret key, accessible through secret_key()
TYPE_SECRET_KEY,
// The result is a public/private key pair, accessible through public_key()
// and private_key()
TYPE_PUBLIC_PRIVATE_KEY_PAIR
};
// Initializes a "null" instance.
GenerateKeyResult();
Type type() const;
const blink::WebCryptoKey& secret_key() const;
const blink::WebCryptoKey& public_key() const;
const blink::WebCryptoKey& private_key() const;
void AssignSecretKey(const blink::WebCryptoKey& key);
void AssignKeyPair(const blink::WebCryptoKey& public_key,
const blink::WebCryptoKey& private_key);
// Sends the key(s) to the Blink result. Should not be called for "null"
// results.
void Complete(blink::WebCryptoResult* out) const;
private:
Type type_;
blink::WebCryptoKey secret_key_;
blink::WebCryptoKey public_key_;
blink::WebCryptoKey private_key_;
};
} // namespace webcrypto
} // namespace content
#endif // CONTENT_CHILD_WEBCRYPTO_GENERATE_KEY_RESULT_H_
......@@ -153,13 +153,17 @@ class AesGcmImplementation : public AesAlgorithm {
return AesAlgorithm::VerifyKeyUsagesBeforeImportKey(format, usage_mask);
}
virtual Status VerifyKeyUsagesBeforeGenerateKey(
blink::WebCryptoKeyUsageMask usage_mask) const override {
virtual Status GenerateKey(const blink::WebCryptoAlgorithm& algorithm,
bool extractable,
blink::WebCryptoKeyUsageMask usage_mask,
GenerateKeyResult* result) const override {
// Prevent generating AES-GCM keys if it is unavailable.
Status status = NssSupportsAesGcm();
if (status.IsError())
return status;
return AesAlgorithm::VerifyKeyUsagesBeforeGenerateKey(usage_mask);
return AesAlgorithm::GenerateKey(
algorithm, extractable, usage_mask, result);
}
virtual Status Encrypt(const blink::WebCryptoAlgorithm& algorithm,
......
......@@ -38,19 +38,16 @@ AesAlgorithm::AesAlgorithm(CK_MECHANISM_TYPE import_mechanism,
jwk_suffix_(jwk_suffix) {
}
Status AesAlgorithm::VerifyKeyUsagesBeforeGenerateKey(
blink::WebCryptoKeyUsageMask usage_mask) const {
return CheckKeyCreationUsages(all_key_usages_, usage_mask);
}
Status AesAlgorithm::GenerateSecretKey(
const blink::WebCryptoAlgorithm& algorithm,
Status AesAlgorithm::GenerateKey(const blink::WebCryptoAlgorithm& algorithm,
bool extractable,
blink::WebCryptoKeyUsageMask usage_mask,
blink::WebCryptoKey* key) const {
GenerateKeyResult* result) const {
Status status = CheckKeyCreationUsages(all_key_usages_, usage_mask);
if (status.IsError())
return status;
unsigned int keylen_bits;
Status status =
GetAesKeyGenLengthInBits(algorithm.aesKeyGenParams(), &keylen_bits);
status = GetAesKeyGenLengthInBits(algorithm.aesKeyGenParams(), &keylen_bits);
if (status.IsError())
return status;
......@@ -60,7 +57,7 @@ Status AesAlgorithm::GenerateSecretKey(
usage_mask,
keylen_bits / 8,
CKM_AES_KEY_GEN,
key);
result);
}
Status AesAlgorithm::VerifyKeyUsagesBeforeImportKey(
......
......@@ -36,13 +36,10 @@ class AesAlgorithm : public AlgorithmImplementation {
AesAlgorithm(CK_MECHANISM_TYPE import_mechanism,
const std::string& jwk_suffix);
virtual Status VerifyKeyUsagesBeforeGenerateKey(
blink::WebCryptoKeyUsageMask usage_mask) const override;
virtual Status GenerateSecretKey(const blink::WebCryptoAlgorithm& algorithm,
virtual Status GenerateKey(const blink::WebCryptoAlgorithm& algorithm,
bool extractable,
blink::WebCryptoKeyUsageMask usage_mask,
blink::WebCryptoKey* key) const override;
GenerateKeyResult* result) const override;
virtual Status VerifyKeyUsagesBeforeImportKey(
blink::WebCryptoKeyFormat format,
......
......@@ -55,10 +55,14 @@ class HmacImplementation : public AlgorithmImplementation {
public:
HmacImplementation() {}
virtual Status GenerateSecretKey(const blink::WebCryptoAlgorithm& algorithm,
virtual Status GenerateKey(const blink::WebCryptoAlgorithm& algorithm,
bool extractable,
blink::WebCryptoKeyUsageMask usage_mask,
blink::WebCryptoKey* key) const override {
GenerateKeyResult* result) const override {
Status status = CheckKeyCreationUsages(kAllKeyUsages, usage_mask);
if (status.IsError())
return status;
const blink::WebCryptoHmacKeyGenParams* params =
algorithm.hmacKeyGenParams();
......@@ -68,7 +72,7 @@ class HmacImplementation : public AlgorithmImplementation {
return Status::ErrorUnsupported();
unsigned int keylen_bits = 0;
Status status = GetHmacKeyGenLengthInBits(params, &keylen_bits);
status = GetHmacKeyGenLengthInBits(params, &keylen_bits);
if (status.IsError())
return status;
......@@ -78,7 +82,7 @@ class HmacImplementation : public AlgorithmImplementation {
usage_mask,
keylen_bits / 8,
mechanism,
key);
result);
}
virtual Status VerifyKeyUsagesBeforeImportKey(
......@@ -93,11 +97,6 @@ class HmacImplementation : public AlgorithmImplementation {
}
}
virtual Status VerifyKeyUsagesBeforeGenerateKey(
blink::WebCryptoKeyUsageMask usage_mask) const override {
return CheckKeyCreationUsages(kAllKeyUsages, usage_mask);
}
virtual Status ImportKeyRaw(const CryptoData& key_data,
const blink::WebCryptoAlgorithm& algorithm,
bool extractable,
......
......@@ -6,6 +6,7 @@
#include "base/logging.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/nss/key_nss.h"
#include "content/child/webcrypto/nss/util_nss.h"
......@@ -505,31 +506,24 @@ Status ImportRsaPublicKey(const blink::WebCryptoAlgorithm& algorithm,
} // namespace
Status RsaHashedAlgorithm::VerifyKeyUsagesBeforeGenerateKeyPair(
Status RsaHashedAlgorithm::GenerateKey(
const blink::WebCryptoAlgorithm& algorithm,
bool extractable,
blink::WebCryptoKeyUsageMask combined_usage_mask,
blink::WebCryptoKeyUsageMask* public_usage_mask,
blink::WebCryptoKeyUsageMask* private_usage_mask) const {
GenerateKeyResult* result) const {
Status status = CheckKeyCreationUsages(
all_public_key_usages_ | all_private_key_usages_, combined_usage_mask);
if (status.IsError())
return status;
*public_usage_mask = combined_usage_mask & all_public_key_usages_;
*private_usage_mask = combined_usage_mask & all_private_key_usages_;
return Status::Success();
}
const blink::WebCryptoKeyUsageMask public_usage_mask =
combined_usage_mask & all_public_key_usages_;
const blink::WebCryptoKeyUsageMask private_usage_mask =
combined_usage_mask & all_private_key_usages_;
Status RsaHashedAlgorithm::GenerateKeyPair(
const blink::WebCryptoAlgorithm& algorithm,
bool extractable,
blink::WebCryptoKeyUsageMask public_usage_mask,
blink::WebCryptoKeyUsageMask private_usage_mask,
blink::WebCryptoKey* public_key,
blink::WebCryptoKey* private_key) const {
unsigned int public_exponent = 0;
unsigned int modulus_length_bits = 0;
Status status = GetRsaKeyGenParameters(algorithm.rsaHashedKeyGenParams(),
status = GetRsaKeyGenParameters(algorithm.rsaHashedKeyGenParams(),
&public_exponent,
&modulus_length_bits);
if (status.IsError())
......@@ -591,17 +585,21 @@ Status RsaHashedAlgorithm::GenerateKeyPair(
scoped_ptr<PrivateKeyNss> private_key_handle(
new PrivateKeyNss(scoped_sec_private_key.Pass(), CryptoData(pkcs8_data)));
*public_key = blink::WebCryptoKey::create(public_key_handle.release(),
blink::WebCryptoKey public_key =
blink::WebCryptoKey::create(public_key_handle.release(),
blink::WebCryptoKeyTypePublic,
true,
key_algorithm,
public_usage_mask);
*private_key = blink::WebCryptoKey::create(private_key_handle.release(),
blink::WebCryptoKey private_key =
blink::WebCryptoKey::create(private_key_handle.release(),
blink::WebCryptoKeyTypePrivate,
extractable,
key_algorithm,
private_usage_mask);
result->AssignKeyPair(public_key, private_key);
return Status::Success();
}
......
......@@ -43,18 +43,10 @@ class RsaHashedAlgorithm : public AlgorithmImplementation {
virtual const char* GetJwkAlgorithm(
const blink::WebCryptoAlgorithmId hash) const = 0;
virtual Status VerifyKeyUsagesBeforeGenerateKeyPair(
blink::WebCryptoKeyUsageMask combined_usage_mask,
blink::WebCryptoKeyUsageMask* public_usage_mask,
blink::WebCryptoKeyUsageMask* private_usage_mask) const override;
virtual Status GenerateKeyPair(
const blink::WebCryptoAlgorithm& algorithm,
virtual Status GenerateKey(const blink::WebCryptoAlgorithm& algorithm,
bool extractable,
blink::WebCryptoKeyUsageMask public_usage_mask,
blink::WebCryptoKeyUsageMask private_usage_mask,
blink::WebCryptoKey* public_key,
blink::WebCryptoKey* private_key) const override;
blink::WebCryptoKeyUsageMask usage_mask,
GenerateKeyResult* result) const override;
virtual Status VerifyKeyUsagesBeforeImportKey(
blink::WebCryptoKeyFormat format,
......
......@@ -168,15 +168,15 @@ class RsaOaepImplementation : public RsaHashedAlgorithm {
blink::WebCryptoKeyUsageDecrypt |
blink::WebCryptoKeyUsageUnwrapKey) {}
virtual Status VerifyKeyUsagesBeforeGenerateKeyPair(
blink::WebCryptoKeyUsageMask combined_usage_mask,
blink::WebCryptoKeyUsageMask* public_usage_mask,
blink::WebCryptoKeyUsageMask* private_usage_mask) const override {
virtual Status GenerateKey(const blink::WebCryptoAlgorithm& algorithm,
bool extractable,
blink::WebCryptoKeyUsageMask usage_mask,
GenerateKeyResult* result) const override {
Status status = NssSupportsRsaOaep();
if (status.IsError())
return status;
return RsaHashedAlgorithm::VerifyKeyUsagesBeforeGenerateKeyPair(
combined_usage_mask, public_usage_mask, private_usage_mask);
return RsaHashedAlgorithm::GenerateKey(
algorithm, extractable, usage_mask, result);
}
virtual Status VerifyKeyUsagesBeforeImportKey(
......
......@@ -6,6 +6,7 @@
#include "base/logging.h"
#include "content/child/webcrypto/crypto_data.h"
#include "content/child/webcrypto/generate_key_result.h"
#include "content/child/webcrypto/nss/key_nss.h"
#include "content/child/webcrypto/nss/util_nss.h"
#include "content/child/webcrypto/status.h"
......@@ -22,7 +23,7 @@ Status GenerateSecretKeyNss(const blink::WebCryptoKeyAlgorithm& algorithm,
blink::WebCryptoKeyUsageMask usage_mask,
unsigned keylen_bytes,
CK_MECHANISM_TYPE mechanism,
blink::WebCryptoKey* key) {
GenerateKeyResult* result) {
DCHECK_NE(CKM_INVALID_MECHANISM, mechanism);
crypto::ScopedPK11Slot slot(PK11_GetInternalKeySlot());
......@@ -45,11 +46,13 @@ Status GenerateSecretKeyNss(const blink::WebCryptoKeyAlgorithm& algorithm,
scoped_ptr<SymKeyNss> handle(new SymKeyNss(
pk11_key.Pass(), CryptoData(key_data->data, key_data->len)));
*key = blink::WebCryptoKey::create(handle.release(),
result->AssignSecretKey(
blink::WebCryptoKey::create(handle.release(),
blink::WebCryptoKeyTypeSecret,
extractable,
algorithm,
usage_mask);
usage_mask));
return Status::Success();
}
......
......@@ -14,6 +14,7 @@ namespace content {
namespace webcrypto {
class CryptoData;
class GenerateKeyResult;
class Status;
Status GenerateSecretKeyNss(const blink::WebCryptoKeyAlgorithm& algorithm,
......@@ -21,7 +22,7 @@ Status GenerateSecretKeyNss(const blink::WebCryptoKeyAlgorithm& algorithm,
blink::WebCryptoKeyUsageMask usage_mask,
unsigned keylen_bytes,
CK_MECHANISM_TYPE mechanism,
blink::WebCryptoKey* key);
GenerateKeyResult* result);
Status ImportKeyRawNss(const CryptoData& key_data,
const blink::WebCryptoKeyAlgorithm& algorithm,
......
......@@ -30,19 +30,16 @@ AesAlgorithm::AesAlgorithm(const std::string& jwk_suffix)
jwk_suffix_(jwk_suffix) {
}
Status AesAlgorithm::VerifyKeyUsagesBeforeGenerateKey(
blink::WebCryptoKeyUsageMask usage_mask) const {
return CheckKeyCreationUsages(all_key_usages_, usage_mask);
}
Status AesAlgorithm::GenerateSecretKey(
const blink::WebCryptoAlgorithm& algorithm,
Status AesAlgorithm::GenerateKey(const blink::WebCryptoAlgorithm& algorithm,
bool extractable,
blink::WebCryptoKeyUsageMask usage_mask,
blink::WebCryptoKey* key) const {
GenerateKeyResult* result) const {
Status status = CheckKeyCreationUsages(all_key_usages_, usage_mask);
if (status.IsError())
return status;
unsigned int keylen_bits;
Status status =
GetAesKeyGenLengthInBits(algorithm.aesKeyGenParams(), &keylen_bits);
status = GetAesKeyGenLengthInBits(algorithm.aesKeyGenParams(), &keylen_bits);
if (status.IsError())
return status;
......@@ -51,7 +48,7 @@ Status AesAlgorithm::GenerateSecretKey(
extractable,
usage_mask,
keylen_bits / 8,
key);
result);
}
Status AesAlgorithm::VerifyKeyUsagesBeforeImportKey(
......
......@@ -28,13 +28,10 @@ class AesAlgorithm : public AlgorithmImplementation {
// algorithms (supports usages for: encrypt, decrypt, wrap, unwrap).
explicit AesAlgorithm(const std::string& jwk_suffix);
virtual Status VerifyKeyUsagesBeforeGenerateKey(
blink::WebCryptoKeyUsageMask usage_mask) const override;
virtual Status GenerateSecretKey(const blink::WebCryptoAlgorithm& algorithm,
virtual Status GenerateKey(const blink::WebCryptoAlgorithm& algorithm,
bool extractable,
blink::WebCryptoKeyUsageMask usage_mask,
blink::WebCryptoKey* key) const override;
GenerateKeyResult* result) const override;
virtual Status VerifyKeyUsagesBeforeImportKey(
blink::WebCryptoKeyFormat format,
......
......@@ -70,15 +70,19 @@ class HmacImplementation : public AlgorithmImplementation {
public:
HmacImplementation() {}
virtual Status GenerateSecretKey(const blink::WebCryptoAlgorithm& algorithm,
virtual Status GenerateKey(const blink::WebCryptoAlgorithm& algorithm,
bool extractable,
blink::WebCryptoKeyUsageMask usage_mask,
blink::WebCryptoKey* key) const override {
GenerateKeyResult* result) const override {
Status status = CheckKeyCreationUsages(kAllKeyUsages, usage_mask);
if (status.IsError())
return status;
const blink::WebCryptoHmacKeyGenParams* params =
algorithm.hmacKeyGenParams();
unsigned int keylen_bits = 0;
Status status = GetHmacKeyGenLengthInBits(params, &keylen_bits);
status = GetHmacKeyGenLengthInBits(params, &keylen_bits);
if (status.IsError())
return status;
......@@ -87,7 +91,7 @@ class HmacImplementation : public AlgorithmImplementation {
extractable,
usage_mask,
keylen_bits / 8,
key);
result);
}
virtual Status VerifyKeyUsagesBeforeImportKey(
......@@ -102,11 +106,6 @@ class HmacImplementation : public AlgorithmImplementation {
}
}
virtual Status VerifyKeyUsagesBeforeGenerateKey(
blink::WebCryptoKeyUsageMask usage_mask) const override {
return CheckKeyCreationUsages(kAllKeyUsages, usage_mask);
}
virtual Status ImportKeyRaw(const CryptoData& key_data,
const blink::WebCryptoAlgorithm& algorithm,
bool extractable,
......
......@@ -10,6 +10,7 @@
#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/status.h"
......@@ -228,34 +229,27 @@ Status ImportRsaPublicKey(const blink::WebCryptoAlgorithm& algorithm,
} // namespace
Status RsaHashedAlgorithm::VerifyKeyUsagesBeforeGenerateKeyPair(
Status RsaHashedAlgorithm::GenerateKey(
const blink::WebCryptoAlgorithm& algorithm,
bool extractable,
blink::WebCryptoKeyUsageMask combined_usage_mask,
blink::WebCryptoKeyUsageMask* public_usage_mask,
blink::WebCryptoKeyUsageMask* private_usage_mask) const {
GenerateKeyResult* result) const {
Status status = CheckKeyCreationUsages(
all_public_key_usages_ | all_private_key_usages_, combined_usage_mask);
if (status.IsError())
return status;
*public_usage_mask = combined_usage_mask & all_public_key_usages_;
*private_usage_mask = combined_usage_mask & all_private_key_usages_;
const blink::WebCryptoKeyUsageMask public_usage_mask =
combined_usage_mask & all_public_key_usages_;
const blink::WebCryptoKeyUsageMask private_usage_mask =
combined_usage_mask & all_private_key_usages_;
return Status::Success();
}
Status RsaHashedAlgorithm::GenerateKeyPair(
const blink::WebCryptoAlgorithm& algorithm,
bool extractable,
blink::WebCryptoKeyUsageMask public_usage_mask,
blink::WebCryptoKeyUsageMask private_usage_mask,
blink::WebCryptoKey* public_key,
blink::WebCryptoKey* private_key) const {
const blink::WebCryptoRsaHashedKeyGenParams* params =
algorithm.rsaHashedKeyGenParams();
unsigned int public_exponent = 0;
unsigned int modulus_length_bits = 0;
Status status =
status =
GetRsaKeyGenParameters(params, &public_exponent, &modulus_length_bits);
if (status.IsError())
return status;
......@@ -290,6 +284,9 @@ Status RsaHashedAlgorithm::GenerateKeyPair(
return Status::OperationError();
}
blink::WebCryptoKey public_key = blink::WebCryptoKey::createNull();
blink::WebCryptoKey private_key = blink::WebCryptoKey::createNull();
// 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(),
......@@ -297,16 +294,21 @@ Status RsaHashedAlgorithm::GenerateKeyPair(
params->hash(),
true,
public_usage_mask,
public_key);
&public_key);
if (status.IsError())
return status;
return CreateWebCryptoPrivateKey(private_pkey.Pass(),
status = CreateWebCryptoPrivateKey(private_pkey.Pass(),
algorithm.id(),
params->hash(),
extractable,
private_usage_mask,
private_key);
&private_key);
if (status.IsError())
return status;
result->AssignKeyPair(public_key, private_key);
return Status::Success();
}
Status RsaHashedAlgorithm::VerifyKeyUsagesBeforeImportKey(
......
......@@ -38,18 +38,10 @@ class RsaHashedAlgorithm : public AlgorithmImplementation {
virtual const char* GetJwkAlgorithm(
const blink::WebCryptoAlgorithmId hash) const = 0;
virtual Status VerifyKeyUsagesBeforeGenerateKeyPair(
blink::WebCryptoKeyUsageMask combined_usage_mask,
blink::WebCryptoKeyUsageMask* public_usage_mask,
blink::WebCryptoKeyUsageMask* private_usage_mask) const override;
virtual Status GenerateKeyPair(
const blink::WebCryptoAlgorithm& algorithm,
virtual Status GenerateKey(const blink::WebCryptoAlgorithm& algorithm,
bool extractable,
blink::WebCryptoKeyUsageMask public_usage_mask,
blink::WebCryptoKeyUsageMask private_usage_mask,
blink::WebCryptoKey* public_key,
blink::WebCryptoKey* private_key) const override;
blink::WebCryptoKeyUsageMask usage_mask,
GenerateKeyResult* result) const override;
virtual Status VerifyKeyUsagesBeforeImportKey(
blink::WebCryptoKeyFormat format,
......
......@@ -8,6 +8,7 @@
#include <openssl/rand.h>
#include "content/child/webcrypto/crypto_data.h"
#include "content/child/webcrypto/generate_key_result.h"
#include "content/child/webcrypto/openssl/key_openssl.h"
#include "content/child/webcrypto/status.h"
#include "crypto/openssl_util.h"
......@@ -21,7 +22,7 @@ Status GenerateSecretKeyOpenSsl(const blink::WebCryptoKeyAlgorithm& algorithm,
bool extractable,
blink::WebCryptoKeyUsageMask usage_mask,
unsigned keylen_bytes,
blink::WebCryptoKey* key) {
GenerateKeyResult* result) {
crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
std::vector<unsigned char> random_bytes(keylen_bytes, 0);
......@@ -31,12 +32,13 @@ Status GenerateSecretKeyOpenSsl(const blink::WebCryptoKeyAlgorithm& algorithm,
return Status::OperationError();
}
*key =
result->AssignSecretKey(
blink::WebCryptoKey::create(new SymKeyOpenSsl(CryptoData(random_bytes)),
blink::WebCryptoKeyTypeSecret,
extractable,
algorithm,
usage_mask);
usage_mask));
return Status::Success();
}
......
......@@ -12,13 +12,14 @@ namespace content {
namespace webcrypto {
class CryptoData;
class GenerateKeyResult;
class Status;
Status GenerateSecretKeyOpenSsl(const blink::WebCryptoKeyAlgorithm& algorithm,
bool extractable,
blink::WebCryptoKeyUsageMask usage_mask,
unsigned keylen_bytes,
blink::WebCryptoKey* key);
GenerateKeyResult* result);
Status ImportKeyRawOpenSsl(const CryptoData& key_data,
const blink::WebCryptoKeyAlgorithm& algorithm,
......
......@@ -17,6 +17,7 @@
#include "base/values.h"
#include "content/child/webcrypto/algorithm_dispatch.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/status.h"
#include "content/child/webcrypto/webcrypto_util.h"
......@@ -580,6 +581,42 @@ void ImportExportJwkSymmetricKey(
EXPECT_BYTES_EQ_HEX(key_hex, key_raw_out);
}
Status GenerateSecretKey(const blink::WebCryptoAlgorithm& algorithm,
bool extractable,
blink::WebCryptoKeyUsageMask usage_mask,
blink::WebCryptoKey* key) {
GenerateKeyResult result;
Status status = GenerateKey(algorithm, extractable, usage_mask, &result);
if (status.IsError())
return status;
if (result.type() != GenerateKeyResult::TYPE_SECRET_KEY)
return Status::ErrorUnexpected();
*key = result.secret_key();
return Status::Success();
}
Status GenerateKeyPair(const blink::WebCryptoAlgorithm& algorithm,
bool extractable,
blink::WebCryptoKeyUsageMask usage_mask,
blink::WebCryptoKey* public_key,
blink::WebCryptoKey* private_key) {
GenerateKeyResult result;
Status status = GenerateKey(algorithm, extractable, usage_mask, &result);
if (status.IsError())
return status;
if (result.type() != GenerateKeyResult::TYPE_PUBLIC_PRIVATE_KEY_PAIR)
return Status::ErrorUnexpected();
*public_key = result.public_key();
*private_key = result.private_key();
return Status::Success();
}
} // namespace webcrypto
} // namesapce content
......@@ -170,6 +170,19 @@ void ImportExportJwkSymmetricKey(
blink::WebCryptoKeyUsageMask usages,
const std::string& jwk_alg);
// Wrappers around GenerateKey() which expect the result to be either a secret
// key or a public/private keypair. If the result does not match the
// expectation, then it fails with Status::ErrorUnexpected().
Status GenerateSecretKey(const blink::WebCryptoAlgorithm& algorithm,
bool extractable,
blink::WebCryptoKeyUsageMask usage_mask,
blink::WebCryptoKey* key);
Status GenerateKeyPair(const blink::WebCryptoAlgorithm& algorithm,
bool extractable,
blink::WebCryptoKeyUsageMask usage_mask,
blink::WebCryptoKey* public_key,
blink::WebCryptoKey* private_key);
} // namespace webcrypto
} // namesapce content
......
......@@ -17,6 +17,7 @@
#include "base/threading/worker_pool.h"
#include "content/child/webcrypto/algorithm_dispatch.h"
#include "content/child/webcrypto/crypto_data.h"
#include "content/child/webcrypto/generate_key_result.h"
#include "content/child/webcrypto/status.h"
#include "content/child/webcrypto/structured_clone.h"
#include "content/child/webcrypto/webcrypto_util.h"
......@@ -215,20 +216,13 @@ struct GenerateKeyState : public BaseState {
: BaseState(result),
algorithm(algorithm),
extractable(extractable),
usage_mask(usage_mask),
public_key(blink::WebCryptoKey::createNull()),
private_key(blink::WebCryptoKey::createNull()),
is_asymmetric(false) {}
usage_mask(usage_mask) {}
const blink::WebCryptoAlgorithm algorithm;
const bool extractable;
const blink::WebCryptoKeyUsageMask usage_mask;
// If |is_asymmetric| is false, then |public_key| is understood to mean the
// symmetric key, and |private_key| is unused.
blink::WebCryptoKey public_key;
blink::WebCryptoKey private_key;
bool is_asymmetric;
webcrypto::GenerateKeyResult generate_key_result;
};
struct ImportKeyState : public BaseState {
......@@ -401,10 +395,7 @@ void DoGenerateKeyReply(scoped_ptr<GenerateKeyState> state) {
if (state->status.IsError()) {
CompleteWithError(state->status, &state->result);
} else {
if (state->is_asymmetric)
state->result.completeWithKeyPair(state->public_key, state->private_key);
else
state->result.completeWithKey(state->public_key);
state->generate_key_result.Complete(&state->result);
}
}
......@@ -412,37 +403,10 @@ void DoGenerateKey(scoped_ptr<GenerateKeyState> passed_state) {
GenerateKeyState* state = passed_state.get();
if (state->cancelled())
return;
state->is_asymmetric =
webcrypto::IsAlgorithmAsymmetric(state->algorithm.id());
if (state->is_asymmetric) {
state->status = webcrypto::GenerateKeyPair(state->algorithm,
state->status = webcrypto::GenerateKey(state->algorithm,
state->extractable,
state->usage_mask,
&state->public_key,
&state->private_key);
if (state->status.IsSuccess()) {
DCHECK(state->public_key.handle());
DCHECK(state->private_key.handle());
DCHECK_EQ(state->algorithm.id(), state->public_key.algorithm().id());
DCHECK_EQ(state->algorithm.id(), state->private_key.algorithm().id());
DCHECK_EQ(true, state->public_key.extractable());
DCHECK_EQ(state->extractable, state->private_key.extractable());
}
} else {
blink::WebCryptoKey* key = &state->public_key;
state->status = webcrypto::GenerateSecretKey(
state->algorithm, state->extractable, state->usage_mask, key);
if (state->status.IsSuccess()) {
DCHECK(key->handle());
DCHECK_EQ(state->algorithm.id(), key->algorithm().id());
DCHECK_EQ(state->extractable, key->extractable());
DCHECK_EQ(state->usage_mask, key->usages());
}
}
&state->generate_key_result);
state->origin_thread->PostTask(
FROM_HERE, base::Bind(DoGenerateKeyReply, Passed(&passed_state)));
}
......
......@@ -140,12 +140,6 @@ bool IsAlgorithmRsa(blink::WebCryptoAlgorithmId alg_id) {
alg_id == blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5;
}
bool IsAlgorithmAsymmetric(blink::WebCryptoAlgorithmId alg_id) {
// TODO(padolph): include all other asymmetric algorithms once they are
// defined, e.g. EC and DH.
return IsAlgorithmRsa(alg_id);
}
// The WebCrypto spec defines the default value for the tag length, as well as
// the allowed values for tag length.
Status GetAesGcmTagLengthInBits(const blink::WebCryptoAesGcmParams* params,
......
......@@ -52,7 +52,6 @@ bool KeyUsageAllows(const blink::WebCryptoKey& key,
const blink::WebCryptoKeyUsage usage);
bool IsAlgorithmRsa(blink::WebCryptoAlgorithmId alg_id);
bool IsAlgorithmAsymmetric(blink::WebCryptoAlgorithmId alg_id);
Status GetAesGcmTagLengthInBits(const blink::WebCryptoAesGcmParams* params,
unsigned int* tag_length_bits);
......
......@@ -217,6 +217,8 @@
'child/webcrypto/algorithm_registry.h',
'child/webcrypto/crypto_data.cc',
'child/webcrypto/crypto_data.h',
'child/webcrypto/generate_key_result.cc',
'child/webcrypto/generate_key_result.h',
'child/webcrypto/jwk.cc',
'child/webcrypto/jwk.h',
'child/webcrypto/platform_crypto.h',
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment