Skip to content
Permalink
Browse files
[WebCrypto] Remove the KeyAlgorithm type hierarchy
https://bugs.webkit.org/show_bug.cgi?id=175750

Patch by Sam Weinig <sam@webkit.org> on 2017-08-19
Reviewed by Chris Dumez.

Removes the unnecessary indirection that existed to generate a
KeyAlgorithm dictionary (or rather, one of its derived dictionaries)
for a CryptoKey. We were calling the virtual buildAlgorithm(), which
return a std::unique_ptr<KeyAlgorithm>, which we then casted to the
correct derived class and called dictionary() on. This can now be
simplified by making each CryptoKey derived class override a function
that returns the KeyAlgorithm variant.

* crypto/CryptoKey.cpp:
(WebCore::CryptoKey::algorithm const): Deleted.
* crypto/CryptoKey.h:
(WebCore::CryptoKey::extractable const):
(WebCore::KeyAlgorithm::~KeyAlgorithm): Deleted.
(WebCore::KeyAlgorithm::name const): Deleted.
(WebCore::KeyAlgorithm::KeyAlgorithm): Deleted.
* crypto/gcrypt/CryptoKeyRSAGCrypt.cpp:
(WebCore::CryptoKeyRSA::algorithm const):
(WebCore::CryptoKeyRSA::buildAlgorithm const): Deleted.
* crypto/keys/CryptoKeyAES.cpp:
(WebCore::CryptoKeyAES::algorithm const):
(WebCore::AesKeyAlgorithm::dictionary const): Deleted.
(WebCore::CryptoKeyAES::buildAlgorithm const): Deleted.
* crypto/keys/CryptoKeyAES.h:
* crypto/keys/CryptoKeyEC.cpp:
(WebCore::CryptoKeyEC::algorithm const):
(WebCore::EcKeyAlgorithm::dictionary const): Deleted.
(WebCore::CryptoKeyEC::buildAlgorithm const): Deleted.
* crypto/keys/CryptoKeyEC.h:
(WebCore::EcKeyAlgorithm::EcKeyAlgorithm): Deleted.
(WebCore::EcKeyAlgorithm::namedCurve const): Deleted.
* crypto/keys/CryptoKeyHMAC.cpp:
(WebCore::CryptoKeyHMAC::algorithm const):
(WebCore::HmacKeyAlgorithm::dictionary const): Deleted.
(WebCore::CryptoKeyHMAC::buildAlgorithm const): Deleted.
* crypto/keys/CryptoKeyHMAC.h:
* crypto/keys/CryptoKeyRSA.cpp:
(WebCore::RsaKeyAlgorithm::dictionary const): Deleted.
(WebCore::RsaHashedKeyAlgorithm::dictionary const): Deleted.
* crypto/keys/CryptoKeyRSA.h:
(WebCore::RsaKeyAlgorithm::RsaKeyAlgorithm): Deleted.
(WebCore::RsaKeyAlgorithm::modulusLength const): Deleted.
(WebCore::RsaKeyAlgorithm::publicExponent const): Deleted.
* crypto/keys/CryptoKeyRaw.cpp:
(WebCore::CryptoKeyRaw::algorithm const):
(WebCore::RawKeyAlgorithm::dictionary const): Deleted.
(WebCore::CryptoKeyRaw::buildAlgorithm const): Deleted.
* crypto/keys/CryptoKeyRaw.h:
(WebCore::RawKeyAlgorithm::RawKeyAlgorithm): Deleted.
* crypto/mac/CryptoKeyRSAMac.cpp:
(WebCore::CryptoKeyRSA::algorithm const):
(WebCore::CryptoKeyRSA::buildAlgorithm const): Deleted.

Canonical link: https://commits.webkit.org/192415@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@220954 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
Sam Weinig authored and webkit-commit-queue committed Aug 19, 2017
1 parent 08aeec6 commit b9f9e9c092a60cf3bf4385ee43f50f017148d483
Showing 15 changed files with 139 additions and 272 deletions.
@@ -1,3 +1,62 @@
2017-08-19 Sam Weinig <sam@webkit.org>

[WebCrypto] Remove the KeyAlgorithm type hierarchy
https://bugs.webkit.org/show_bug.cgi?id=175750

Reviewed by Chris Dumez.

Removes the unnecessary indirection that existed to generate a
KeyAlgorithm dictionary (or rather, one of its derived dictionaries)
for a CryptoKey. We were calling the virtual buildAlgorithm(), which
return a std::unique_ptr<KeyAlgorithm>, which we then casted to the
correct derived class and called dictionary() on. This can now be
simplified by making each CryptoKey derived class override a function
that returns the KeyAlgorithm variant.

* crypto/CryptoKey.cpp:
(WebCore::CryptoKey::algorithm const): Deleted.
* crypto/CryptoKey.h:
(WebCore::CryptoKey::extractable const):
(WebCore::KeyAlgorithm::~KeyAlgorithm): Deleted.
(WebCore::KeyAlgorithm::name const): Deleted.
(WebCore::KeyAlgorithm::KeyAlgorithm): Deleted.
* crypto/gcrypt/CryptoKeyRSAGCrypt.cpp:
(WebCore::CryptoKeyRSA::algorithm const):
(WebCore::CryptoKeyRSA::buildAlgorithm const): Deleted.
* crypto/keys/CryptoKeyAES.cpp:
(WebCore::CryptoKeyAES::algorithm const):
(WebCore::AesKeyAlgorithm::dictionary const): Deleted.
(WebCore::CryptoKeyAES::buildAlgorithm const): Deleted.
* crypto/keys/CryptoKeyAES.h:
* crypto/keys/CryptoKeyEC.cpp:
(WebCore::CryptoKeyEC::algorithm const):
(WebCore::EcKeyAlgorithm::dictionary const): Deleted.
(WebCore::CryptoKeyEC::buildAlgorithm const): Deleted.
* crypto/keys/CryptoKeyEC.h:
(WebCore::EcKeyAlgorithm::EcKeyAlgorithm): Deleted.
(WebCore::EcKeyAlgorithm::namedCurve const): Deleted.
* crypto/keys/CryptoKeyHMAC.cpp:
(WebCore::CryptoKeyHMAC::algorithm const):
(WebCore::HmacKeyAlgorithm::dictionary const): Deleted.
(WebCore::CryptoKeyHMAC::buildAlgorithm const): Deleted.
* crypto/keys/CryptoKeyHMAC.h:
* crypto/keys/CryptoKeyRSA.cpp:
(WebCore::RsaKeyAlgorithm::dictionary const): Deleted.
(WebCore::RsaHashedKeyAlgorithm::dictionary const): Deleted.
* crypto/keys/CryptoKeyRSA.h:
(WebCore::RsaKeyAlgorithm::RsaKeyAlgorithm): Deleted.
(WebCore::RsaKeyAlgorithm::modulusLength const): Deleted.
(WebCore::RsaKeyAlgorithm::publicExponent const): Deleted.
* crypto/keys/CryptoKeyRaw.cpp:
(WebCore::CryptoKeyRaw::algorithm const):
(WebCore::RawKeyAlgorithm::dictionary const): Deleted.
(WebCore::CryptoKeyRaw::buildAlgorithm const): Deleted.
* crypto/keys/CryptoKeyRaw.h:
(WebCore::RawKeyAlgorithm::RawKeyAlgorithm): Deleted.
* crypto/mac/CryptoKeyRSAMac.cpp:
(WebCore::CryptoKeyRSA::algorithm const):
(WebCore::CryptoKeyRSA::buildAlgorithm const): Deleted.

2017-08-19 Sam Weinig <sam@webkit.org>

[Mac] Change uint8_t* to Vector<uint8_t> type in all crypto algorithm implementation
@@ -29,11 +29,6 @@
#if ENABLE(SUBTLE_CRYPTO)

#include "CryptoAlgorithmRegistry.h"
#include "CryptoKeyAES.h"
#include "CryptoKeyEC.h"
#include "CryptoKeyHMAC.h"
#include "CryptoKeyRSA.h"
#include "CryptoKeyRaw.h"
#include <wtf/CryptographicallyRandomNumber.h>

namespace WebCore {
@@ -50,27 +45,6 @@ CryptoKey::~CryptoKey()
{
}

auto CryptoKey::algorithm() const -> AlgorithmVariant
{
std::unique_ptr<KeyAlgorithm> algorithm = buildAlgorithm();
switch (algorithm->keyAlgorithmClass()) {
case KeyAlgorithmClass::AES:
return downcast<AesKeyAlgorithm>(*algorithm).dictionary();
case KeyAlgorithmClass::EC:
return downcast<EcKeyAlgorithm>(*algorithm).dictionary();
case KeyAlgorithmClass::HMAC:
return downcast<HmacKeyAlgorithm>(*algorithm).dictionary();
case KeyAlgorithmClass::HRSA:
return downcast<RsaHashedKeyAlgorithm>(*algorithm).dictionary();
case KeyAlgorithmClass::RSA:
return downcast<RsaKeyAlgorithm>(*algorithm).dictionary();
case KeyAlgorithmClass::Raw:
return downcast<RawKeyAlgorithm>(*algorithm).dictionary();
}

RELEASE_ASSERT_NOT_REACHED();
}

auto CryptoKey::usages() const -> Vector<CryptoKeyUsage>
{
// The result is ordered alphabetically.
@@ -45,8 +45,6 @@

namespace WebCore {

class CryptoAlgorithmDescriptionBuilder;

enum class CryptoKeyClass {
AES,
EC,
@@ -55,50 +53,20 @@ enum class CryptoKeyClass {
Raw,
};

enum class KeyAlgorithmClass {
AES,
EC,
HMAC,
HRSA,
RSA,
Raw,
};

class KeyAlgorithm {
public:
virtual ~KeyAlgorithm()
{
}

virtual KeyAlgorithmClass keyAlgorithmClass() const = 0;

const String& name() const { return m_name; }

protected:
explicit KeyAlgorithm(const String& name)
: m_name(name)
{
}

private:
String m_name;
};

class CryptoKey : public ThreadSafeRefCounted<CryptoKey> {
public:
using Type = CryptoKeyType;
using AlgorithmVariant = Variant<CryptoKeyAlgorithm, CryptoAesKeyAlgorithm, CryptoEcKeyAlgorithm, CryptoHmacKeyAlgorithm, CryptoRsaHashedKeyAlgorithm, CryptoRsaKeyAlgorithm>;
using KeyAlgorithm = Variant<CryptoKeyAlgorithm, CryptoAesKeyAlgorithm, CryptoEcKeyAlgorithm, CryptoHmacKeyAlgorithm, CryptoRsaHashedKeyAlgorithm, CryptoRsaKeyAlgorithm>;

CryptoKey(CryptoAlgorithmIdentifier, Type, bool extractable, CryptoKeyUsageBitmap);
virtual ~CryptoKey();

Type type() const;
bool extractable() const { return m_extractable; }
AlgorithmVariant algorithm() const;
Vector<CryptoKeyUsage> usages() const;
virtual KeyAlgorithm algorithm() const = 0;

virtual CryptoKeyClass keyClass() const = 0;
virtual std::unique_ptr<KeyAlgorithm> buildAlgorithm() const = 0;

CryptoAlgorithmIdentifier algorithmIdentifier() const { return m_algorithmIdentifier; }
CryptoKeyUsageBitmap usagesBitmap() const { return m_usages; }
@@ -126,9 +94,4 @@ SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::ToClassName) \
static bool isType(const WebCore::CryptoKey& key) { return key.keyClass() == WebCore::KeyClass; } \
SPECIALIZE_TYPE_TRAITS_END()

#define SPECIALIZE_TYPE_TRAITS_KEY_ALGORITHM(ToClassName, KeyAlgorithmClass) \
SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::ToClassName) \
static bool isType(const WebCore::KeyAlgorithm& algorithm) { return algorithm.keyAlgorithmClass() == WebCore::KeyAlgorithmClass; } \
SPECIALIZE_TYPE_TRAITS_END()

#endif // ENABLE(SUBTLE_CRYPTO)
@@ -33,6 +33,9 @@
#include "CryptoKeyRSAComponents.h"
#include "GCryptUtilities.h"
#include "ScriptExecutionContext.h"
#include <JavaScriptCore/GenericTypedArrayViewInlines.h>
#include <JavaScriptCore/JSGenericTypedArrayViewInlines.h>
#include <heap/HeapInlines.h>
#include <pal/crypto/gcrypt/Handle.h>
#include <pal/crypto/gcrypt/Utilities.h>
#include <pal/crypto/tasn1/Utilities.h>
@@ -619,15 +622,25 @@ ExceptionOr<Vector<uint8_t>> CryptoKeyRSA::exportPkcs8() const
return WTFMove(result.value());
}

std::unique_ptr<KeyAlgorithm> CryptoKeyRSA::buildAlgorithm() const
auto CryptoKeyRSA::algorithm() const -> KeyAlgorithm
{
String name = CryptoAlgorithmRegistry::singleton().name(algorithmIdentifier());
size_t modulusLength = getRSAModulusLength(m_platformKey);
Vector<uint8_t> publicExponent = getRSAKeyParameter(m_platformKey, "e");
auto modulusLength = getRSAModulusLength(m_platformKey);
auto publicExponent = getRSAKeyParameter(m_platformKey, "e");

if (m_restrictedToSpecificHash) {
CryptoRsaHashedKeyAlgorithm result;
result.name = CryptoAlgorithmRegistry::singleton().name(algorithmIdentifier());
result.modulusLength = modulusLength;
result.publicExponent = Uint8Array::create(publicExponent.data(), publicExponent.size());
result.hash.name = CryptoAlgorithmRegistry::singleton().name(m_hash);
return result;
}

if (m_restrictedToSpecificHash)
return std::make_unique<RsaHashedKeyAlgorithm>(name, modulusLength, WTFMove(publicExponent), CryptoAlgorithmRegistry::singleton().name(m_hash));
return std::make_unique<RsaKeyAlgorithm>(name, modulusLength, WTFMove(publicExponent));
CryptoRsaKeyAlgorithm result;
result.name = CryptoAlgorithmRegistry::singleton().name(algorithmIdentifier());
result.modulusLength = modulusLength;
result.publicExponent = Uint8Array::create(publicExponent.data(), publicExponent.size());
return result;
}

std::unique_ptr<CryptoKeyRSAComponents> CryptoKeyRSA::exportData() const
@@ -37,14 +37,6 @@

namespace WebCore {

CryptoAesKeyAlgorithm AesKeyAlgorithm::dictionary() const
{
CryptoAesKeyAlgorithm result;
result.name = this->name();
result.length = this->length();
return result;
}

static inline bool lengthIsValid(size_t length)
{
return (length == CryptoKeyAES::s_length128) || (length == CryptoKeyAES::s_length192) || (length == CryptoKeyAES::s_length256);
@@ -130,9 +122,12 @@ ExceptionOr<size_t> CryptoKeyAES::getKeyLength(const CryptoAlgorithmParameters&
return aesParameters.length;
}

std::unique_ptr<KeyAlgorithm> CryptoKeyAES::buildAlgorithm() const
auto CryptoKeyAES::algorithm() const -> KeyAlgorithm
{
return std::make_unique<AesKeyAlgorithm>(CryptoAlgorithmRegistry::singleton().name(algorithmIdentifier()), m_key.size() * 8);
CryptoAesKeyAlgorithm result;
result.name = CryptoAlgorithmRegistry::singleton().name(algorithmIdentifier());
result.length = m_key.size() * 8;
return result;
}

} // namespace WebCore
@@ -39,24 +39,6 @@ class CryptoAlgorithmParameters;

struct JsonWebKey;

class AesKeyAlgorithm final : public KeyAlgorithm {
public:
AesKeyAlgorithm(const String& name, size_t length)
: KeyAlgorithm(name)
, m_length(length)
{
}

KeyAlgorithmClass keyAlgorithmClass() const final { return KeyAlgorithmClass::AES; }

CryptoAesKeyAlgorithm dictionary() const;

size_t length() const { return m_length; }

private:
size_t m_length;
};

class CryptoKeyAES final : public CryptoKey {
public:
static const int s_length128 = 128;
@@ -87,7 +69,7 @@ class CryptoKeyAES final : public CryptoKey {
CryptoKeyAES(CryptoAlgorithmIdentifier, const Vector<uint8_t>& key, bool extractable, CryptoKeyUsageBitmap);
CryptoKeyAES(CryptoAlgorithmIdentifier, Vector<uint8_t>&& key, bool extractable, CryptoKeyUsageBitmap);

std::unique_ptr<KeyAlgorithm> buildAlgorithm() const final;
KeyAlgorithm algorithm() const final;

Vector<uint8_t> m_key;
};
@@ -96,6 +78,4 @@ class CryptoKeyAES final : public CryptoKey {

SPECIALIZE_TYPE_TRAITS_CRYPTO_KEY(CryptoKeyAES, CryptoKeyClass::AES)

SPECIALIZE_TYPE_TRAITS_KEY_ALGORITHM(AesKeyAlgorithm, KeyAlgorithmClass::AES)

#endif // ENABLE(SUBTLE_CRYPTO)
@@ -34,14 +34,6 @@

namespace WebCore {

CryptoEcKeyAlgorithm EcKeyAlgorithm::dictionary() const
{
CryptoEcKeyAlgorithm result;
result.name = this->name();
result.namedCurve = this->namedCurve();
return result;
}

static const char* const P256 = "P-256";
static const char* const P384 = "P-384";

@@ -207,18 +199,21 @@ bool CryptoKeyEC::isValidECAlgorithm(CryptoAlgorithmIdentifier algorithm)
return algorithm == CryptoAlgorithmIdentifier::ECDSA || algorithm == CryptoAlgorithmIdentifier::ECDH;
}

std::unique_ptr<KeyAlgorithm> CryptoKeyEC::buildAlgorithm() const
auto CryptoKeyEC::algorithm() const -> KeyAlgorithm
{
String name = CryptoAlgorithmRegistry::singleton().name(algorithmIdentifier());
CryptoEcKeyAlgorithm result;
result.name = CryptoAlgorithmRegistry::singleton().name(algorithmIdentifier());

switch (m_curve) {
case NamedCurve::P256:
return std::make_unique<EcKeyAlgorithm>(name, String(P256));
result.namedCurve = ASCIILiteral(P256);
break;
case NamedCurve::P384:
return std::make_unique<EcKeyAlgorithm>(name, String(P384));
result.namedCurve = ASCIILiteral(P384);
break;
}

ASSERT_NOT_REACHED();
return nullptr;
return result;
}

} // namespace WebCore
@@ -47,27 +47,9 @@ namespace WebCore {

struct JsonWebKey;

class EcKeyAlgorithm : public KeyAlgorithm {
public:
EcKeyAlgorithm(const String& name, const String& curve)
: KeyAlgorithm(name)
, m_curve(curve)
{
}

KeyAlgorithmClass keyAlgorithmClass() const override { return KeyAlgorithmClass::EC; }

const String& namedCurve() const { return m_curve; }

CryptoEcKeyAlgorithm dictionary() const;

private:
String m_curve;
};

class CryptoKeyEC final : public CryptoKey {
public:
// FIXME: https://bugs.webkit.org/show_bug.cgi?id=169231
// FIXME: Add support for Elliptic Curve P-521 (https://webkit.org/b/169231)
enum class NamedCurve {
P256,
P384,
@@ -101,7 +83,7 @@ class CryptoKeyEC final : public CryptoKey {

CryptoKeyClass keyClass() const final { return CryptoKeyClass::EC; }

std::unique_ptr<KeyAlgorithm> buildAlgorithm() const final;
KeyAlgorithm algorithm() const final;

static std::optional<CryptoKeyPair> platformGeneratePair(CryptoAlgorithmIdentifier, NamedCurve, bool extractable, CryptoKeyUsageBitmap);
static RefPtr<CryptoKeyEC> platformImportRaw(CryptoAlgorithmIdentifier, NamedCurve, Vector<uint8_t>&& keyData, bool extractable, CryptoKeyUsageBitmap);
@@ -122,6 +104,4 @@ class CryptoKeyEC final : public CryptoKey {

SPECIALIZE_TYPE_TRAITS_CRYPTO_KEY(CryptoKeyEC, CryptoKeyClass::EC)

SPECIALIZE_TYPE_TRAITS_KEY_ALGORITHM(EcKeyAlgorithm, KeyAlgorithmClass::EC)

#endif // ENABLE(SUBTLE_CRYPTO)

0 comments on commit b9f9e9c

Please sign in to comment.