diff options
Diffstat (limited to 'Source/WebCore/crypto/keys')
-rw-r--r-- | Source/WebCore/crypto/keys/CryptoKeyAES.cpp | 67 | ||||
-rw-r--r-- | Source/WebCore/crypto/keys/CryptoKeyAES.h | 57 | ||||
-rw-r--r-- | Source/WebCore/crypto/keys/CryptoKeyDataOctetSequence.h | 20 | ||||
-rw-r--r-- | Source/WebCore/crypto/keys/CryptoKeyDataRSAComponents.cpp | 31 | ||||
-rw-r--r-- | Source/WebCore/crypto/keys/CryptoKeyDataRSAComponents.h | 30 | ||||
-rw-r--r-- | Source/WebCore/crypto/keys/CryptoKeyHMAC.cpp | 81 | ||||
-rw-r--r-- | Source/WebCore/crypto/keys/CryptoKeyHMAC.h | 59 | ||||
-rw-r--r-- | Source/WebCore/crypto/keys/CryptoKeyRSA.cpp | 153 | ||||
-rw-r--r-- | Source/WebCore/crypto/keys/CryptoKeyRSA.h | 94 | ||||
-rw-r--r-- | Source/WebCore/crypto/keys/CryptoKeySerializationRaw.cpp | 83 | ||||
-rw-r--r-- | Source/WebCore/crypto/keys/CryptoKeySerializationRaw.h | 65 |
11 files changed, 630 insertions, 110 deletions
diff --git a/Source/WebCore/crypto/keys/CryptoKeyAES.cpp b/Source/WebCore/crypto/keys/CryptoKeyAES.cpp index c25bae626..43175641b 100644 --- a/Source/WebCore/crypto/keys/CryptoKeyAES.cpp +++ b/Source/WebCore/crypto/keys/CryptoKeyAES.cpp @@ -28,20 +28,33 @@ #if ENABLE(SUBTLE_CRYPTO) -#include "CryptoAlgorithmDescriptionBuilder.h" #include "CryptoAlgorithmRegistry.h" #include "CryptoKeyDataOctetSequence.h" +#include "JsonWebKey.h" +#include <wtf/text/Base64.h> #include <wtf/text/WTFString.h> namespace WebCore { -CryptoKeyAES::CryptoKeyAES(CryptoAlgorithmIdentifier algorithm, const Vector<uint8_t>& key, bool extractable, CryptoKeyUsage usage) +static inline bool lengthIsValid(size_t length) +{ + return (length == CryptoKeyAES::s_length128) || (length == CryptoKeyAES::s_length192) || (length == CryptoKeyAES::s_length256); +} + +CryptoKeyAES::CryptoKeyAES(CryptoAlgorithmIdentifier algorithm, const Vector<uint8_t>& key, bool extractable, CryptoKeyUsageBitmap usage) : CryptoKey(algorithm, CryptoKeyType::Secret, extractable, usage) , m_key(key) { ASSERT(isValidAESAlgorithm(algorithm)); } +CryptoKeyAES::CryptoKeyAES(CryptoAlgorithmIdentifier algorithm, Vector<uint8_t>&& key, bool extractable, CryptoKeyUsageBitmap usage) + : CryptoKey(algorithm, CryptoKeyType::Secret, extractable, usage) + , m_key(WTFMove(key)) +{ + ASSERT(isValidAESAlgorithm(algorithm)); +} + CryptoKeyAES::~CryptoKeyAES() { } @@ -56,23 +69,59 @@ bool CryptoKeyAES::isValidAESAlgorithm(CryptoAlgorithmIdentifier algorithm) || algorithm == CryptoAlgorithmIdentifier::AES_KW; } -PassRefPtr<CryptoKeyAES> CryptoKeyAES::generate(CryptoAlgorithmIdentifier algorithm, size_t lengthBits, bool extractable, CryptoKeyUsage usages) +RefPtr<CryptoKeyAES> CryptoKeyAES::generate(CryptoAlgorithmIdentifier algorithm, size_t lengthBits, bool extractable, CryptoKeyUsageBitmap usages) { - if (lengthBits % 8) + if (!lengthIsValid(lengthBits)) return nullptr; return adoptRef(new CryptoKeyAES(algorithm, randomData(lengthBits / 8), extractable, usages)); } -void CryptoKeyAES::buildAlgorithmDescription(CryptoAlgorithmDescriptionBuilder& builder) const +RefPtr<CryptoKeyAES> CryptoKeyAES::importRaw(CryptoAlgorithmIdentifier algorithm, Vector<uint8_t>&& keyData, bool extractable, CryptoKeyUsageBitmap usages) +{ + if (!lengthIsValid(keyData.size() * 8)) + return nullptr; + return adoptRef(new CryptoKeyAES(algorithm, WTFMove(keyData), extractable, usages)); +} + +RefPtr<CryptoKeyAES> CryptoKeyAES::importJwk(CryptoAlgorithmIdentifier algorithm, JsonWebKey&& keyData, bool extractable, CryptoKeyUsageBitmap usages, CheckAlgCallback&& callback) +{ + if (keyData.kty != "oct") + return nullptr; + if (keyData.k.isNull()) + return nullptr; + Vector<uint8_t> octetSequence; + if (!base64URLDecode(keyData.k, octetSequence)) + return nullptr; + if (!callback(octetSequence.size() * 8, keyData.alg)) + return nullptr; + if (usages && !keyData.use.isNull() && keyData.use != "enc") + return nullptr; + if (keyData.key_ops && ((keyData.usages & usages) != usages)) + return nullptr; + if (keyData.ext && !keyData.ext.value() && extractable) + return nullptr; + + return adoptRef(new CryptoKeyAES(algorithm, WTFMove(octetSequence), extractable, usages)); +} + +JsonWebKey CryptoKeyAES::exportJwk() const +{ + JsonWebKey result; + result.kty = "oct"; + result.k = base64URLEncode(m_key); + result.key_ops = usages(); + result.ext = extractable(); + return result; +} + +std::unique_ptr<KeyAlgorithm> CryptoKeyAES::buildAlgorithm() const { - CryptoKey::buildAlgorithmDescription(builder); - builder.add("length", m_key.size() * 8); + return std::make_unique<AesKeyAlgorithm>(CryptoAlgorithmRegistry::singleton().name(algorithmIdentifier()), m_key.size() * 8); } std::unique_ptr<CryptoKeyData> CryptoKeyAES::exportData() const { - ASSERT(extractable()); - return CryptoKeyDataOctetSequence::create(m_key); + return std::make_unique<CryptoKeyDataOctetSequence>(m_key); } } // namespace WebCore diff --git a/Source/WebCore/crypto/keys/CryptoKeyAES.h b/Source/WebCore/crypto/keys/CryptoKeyAES.h index 4e0d5f787..471491d94 100644 --- a/Source/WebCore/crypto/keys/CryptoKeyAES.h +++ b/Source/WebCore/crypto/keys/CryptoKeyAES.h @@ -23,52 +23,73 @@ * THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef CryptoKeyAES_h -#define CryptoKeyAES_h +#pragma once #include "CryptoAlgorithmIdentifier.h" #include "CryptoKey.h" +#include <wtf/Function.h> #include <wtf/Vector.h> #if ENABLE(SUBTLE_CRYPTO) namespace WebCore { +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; } + + size_t length() const { return m_length; } + +private: + size_t m_length; +}; + class CryptoKeyAES final : public CryptoKey { public: - static PassRefPtr<CryptoKeyAES> create(CryptoAlgorithmIdentifier algorithm, const Vector<uint8_t>& key, bool extractable, CryptoKeyUsage usage) + static const int s_length128 = 128; + static const int s_length192 = 192; + static const int s_length256 = 256; + + static Ref<CryptoKeyAES> create(CryptoAlgorithmIdentifier algorithm, const Vector<uint8_t>& key, bool extractable, CryptoKeyUsageBitmap usage) { - return adoptRef(new CryptoKeyAES(algorithm, key, extractable, usage)); + return adoptRef(*new CryptoKeyAES(algorithm, key, extractable, usage)); } virtual ~CryptoKeyAES(); static bool isValidAESAlgorithm(CryptoAlgorithmIdentifier); - static PassRefPtr<CryptoKeyAES> generate(CryptoAlgorithmIdentifier, size_t lengthBits, bool extractable, CryptoKeyUsage); + static RefPtr<CryptoKeyAES> generate(CryptoAlgorithmIdentifier, size_t lengthBits, bool extractable, CryptoKeyUsageBitmap); + static RefPtr<CryptoKeyAES> importRaw(CryptoAlgorithmIdentifier, Vector<uint8_t>&& keyData, bool extractable, CryptoKeyUsageBitmap); + using CheckAlgCallback = Function<bool(size_t, const String&)>; + static RefPtr<CryptoKeyAES> importJwk(CryptoAlgorithmIdentifier, JsonWebKey&&, bool extractable, CryptoKeyUsageBitmap, CheckAlgCallback&&); - virtual CryptoKeyClass keyClass() const override { return CryptoKeyClass::AES; } + CryptoKeyClass keyClass() const final { return CryptoKeyClass::AES; } const Vector<uint8_t>& key() const { return m_key; } + JsonWebKey exportJwk() const; private: - CryptoKeyAES(CryptoAlgorithmIdentifier, const Vector<uint8_t>& key, bool extractable, CryptoKeyUsage); + CryptoKeyAES(CryptoAlgorithmIdentifier, const Vector<uint8_t>& key, bool extractable, CryptoKeyUsageBitmap); + CryptoKeyAES(CryptoAlgorithmIdentifier, Vector<uint8_t>&& key, bool extractable, CryptoKeyUsageBitmap); - virtual void buildAlgorithmDescription(CryptoAlgorithmDescriptionBuilder&) const override; - virtual std::unique_ptr<CryptoKeyData> exportData() const override; + std::unique_ptr<KeyAlgorithm> buildAlgorithm() const final; + std::unique_ptr<CryptoKeyData> exportData() const final; Vector<uint8_t> m_key; }; -inline bool isCryptoKeyAES(const CryptoKey& key) -{ - return key.keyClass() == CryptoKeyClass::AES; -} - -CRYPTO_KEY_TYPE_CASTS(CryptoKeyAES) - } // namespace WebCore -#endif // ENABLE(SUBTLE_CRYPTO) +SPECIALIZE_TYPE_TRAITS_CRYPTO_KEY(CryptoKeyAES, CryptoKeyClass::AES) +SPECIALIZE_TYPE_TRAITS_KEY_ALGORITHM(AesKeyAlgorithm, KeyAlgorithmClass::AES) -#endif // CryptoKeyAES_h +#endif // ENABLE(SUBTLE_CRYPTO) diff --git a/Source/WebCore/crypto/keys/CryptoKeyDataOctetSequence.h b/Source/WebCore/crypto/keys/CryptoKeyDataOctetSequence.h index 4f88b7e45..645f8eef3 100644 --- a/Source/WebCore/crypto/keys/CryptoKeyDataOctetSequence.h +++ b/Source/WebCore/crypto/keys/CryptoKeyDataOctetSequence.h @@ -23,8 +23,7 @@ * THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef CryptoKeyDataOctetSequence_h -#define CryptoKeyDataOctetSequence_h +#pragma once #include "CryptoKeyData.h" #include <wtf/Vector.h> @@ -35,28 +34,17 @@ namespace WebCore { class CryptoKeyDataOctetSequence final : public CryptoKeyData { public: - static std::unique_ptr<CryptoKeyDataOctetSequence> create(const Vector<uint8_t>& keyData) - { - return std::unique_ptr<CryptoKeyDataOctetSequence>(new CryptoKeyDataOctetSequence(keyData)); - } + explicit CryptoKeyDataOctetSequence(const Vector<uint8_t>&); virtual ~CryptoKeyDataOctetSequence(); const Vector<uint8_t>& octetSequence() const { return m_keyData; } private: - CryptoKeyDataOctetSequence(const Vector<uint8_t>&); - Vector<uint8_t> m_keyData; }; -inline bool isCryptoKeyDataOctetSequence(const CryptoKeyData& data) -{ - return data.format() == CryptoKeyData::Format::OctetSequence; -} - -CRYPTO_KEY_DATA_CASTS(CryptoKeyDataOctetSequence) - } // namespace WebCore +SPECIALIZE_TYPE_TRAITS_CRYPTO_KEY_DATA(CryptoKeyDataOctetSequence, CryptoKeyData::Format::OctetSequence) + #endif // ENABLE(SUBTLE_CRYPTO) -#endif // CryptoKeyDataOctetSequence_h diff --git a/Source/WebCore/crypto/keys/CryptoKeyDataRSAComponents.cpp b/Source/WebCore/crypto/keys/CryptoKeyDataRSAComponents.cpp index e48492618..eed6cd0ff 100644 --- a/Source/WebCore/crypto/keys/CryptoKeyDataRSAComponents.cpp +++ b/Source/WebCore/crypto/keys/CryptoKeyDataRSAComponents.cpp @@ -38,6 +38,14 @@ CryptoKeyDataRSAComponents::CryptoKeyDataRSAComponents(const Vector<uint8_t>& mo { } +CryptoKeyDataRSAComponents::CryptoKeyDataRSAComponents(Vector<uint8_t>&& modulus, Vector<uint8_t>&& exponent) + : CryptoKeyData(CryptoKeyData::Format::RSAComponents) + , m_type(Type::Public) + , m_modulus(WTFMove(modulus)) + , m_exponent(WTFMove(exponent)) +{ +} + CryptoKeyDataRSAComponents::CryptoKeyDataRSAComponents(const Vector<uint8_t>& modulus, const Vector<uint8_t>& exponent, const Vector<uint8_t>& privateExponent) : CryptoKeyData(CryptoKeyData::Format::RSAComponents) , m_type(Type::Private) @@ -48,6 +56,16 @@ CryptoKeyDataRSAComponents::CryptoKeyDataRSAComponents(const Vector<uint8_t>& mo { } +CryptoKeyDataRSAComponents::CryptoKeyDataRSAComponents(Vector<uint8_t>&& modulus, Vector<uint8_t>&& exponent, Vector<uint8_t>&& privateExponent) + : CryptoKeyData(CryptoKeyData::Format::RSAComponents) + , m_type(Type::Private) + , m_modulus(WTFMove(modulus)) + , m_exponent(WTFMove(exponent)) + , m_privateExponent(WTFMove(privateExponent)) + , m_hasAdditionalPrivateKeyParameters(false) +{ +} + CryptoKeyDataRSAComponents::CryptoKeyDataRSAComponents(const Vector<uint8_t>& modulus, const Vector<uint8_t>& exponent, const Vector<uint8_t>& privateExponent, const PrimeInfo& firstPrimeInfo, const PrimeInfo& secondPrimeInfo, const Vector<PrimeInfo>& otherPrimeInfos) : CryptoKeyData(CryptoKeyData::Format::RSAComponents) , m_type(Type::Private) @@ -61,6 +79,19 @@ CryptoKeyDataRSAComponents::CryptoKeyDataRSAComponents(const Vector<uint8_t>& mo { } +CryptoKeyDataRSAComponents::CryptoKeyDataRSAComponents(Vector<uint8_t>&& modulus, Vector<uint8_t>&& exponent, Vector<uint8_t>&& privateExponent, PrimeInfo&& firstPrimeInfo, PrimeInfo&& secondPrimeInfo, Vector<PrimeInfo>&& otherPrimeInfos) + : CryptoKeyData(CryptoKeyData::Format::RSAComponents) + , m_type(Type::Private) + , m_modulus(WTFMove(modulus)) + , m_exponent(WTFMove(exponent)) + , m_privateExponent(WTFMove(privateExponent)) + , m_hasAdditionalPrivateKeyParameters(true) + , m_firstPrimeInfo(WTFMove(firstPrimeInfo)) + , m_secondPrimeInfo(WTFMove(secondPrimeInfo)) + , m_otherPrimeInfos(WTFMove(otherPrimeInfos)) +{ +} + CryptoKeyDataRSAComponents::~CryptoKeyDataRSAComponents() { } diff --git a/Source/WebCore/crypto/keys/CryptoKeyDataRSAComponents.h b/Source/WebCore/crypto/keys/CryptoKeyDataRSAComponents.h index 113fd5106..294b912d4 100644 --- a/Source/WebCore/crypto/keys/CryptoKeyDataRSAComponents.h +++ b/Source/WebCore/crypto/keys/CryptoKeyDataRSAComponents.h @@ -23,8 +23,7 @@ * THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef CryptoKeyDataRSAComponents_h -#define CryptoKeyDataRSAComponents_h +#pragma once #include "CryptoKeyData.h" #include <wtf/Vector.h> @@ -50,16 +49,28 @@ public: { return std::unique_ptr<CryptoKeyDataRSAComponents>(new CryptoKeyDataRSAComponents(modulus, exponent)); } + static std::unique_ptr<CryptoKeyDataRSAComponents> createPublic(Vector<uint8_t>&& modulus, Vector<uint8_t>&& exponent) + { + return std::unique_ptr<CryptoKeyDataRSAComponents>(new CryptoKeyDataRSAComponents(WTFMove(modulus), WTFMove(exponent))); + } static std::unique_ptr<CryptoKeyDataRSAComponents> createPrivate(const Vector<uint8_t>& modulus, const Vector<uint8_t>& exponent, const Vector<uint8_t>& privateExponent) { return std::unique_ptr<CryptoKeyDataRSAComponents>(new CryptoKeyDataRSAComponents(modulus, exponent, privateExponent)); } + static std::unique_ptr<CryptoKeyDataRSAComponents> createPrivate(Vector<uint8_t>&& modulus, Vector<uint8_t>&& exponent, Vector<uint8_t>&& privateExponent) + { + return std::unique_ptr<CryptoKeyDataRSAComponents>(new CryptoKeyDataRSAComponents(WTFMove(modulus), WTFMove(exponent), WTFMove(privateExponent))); + } static std::unique_ptr<CryptoKeyDataRSAComponents> createPrivateWithAdditionalData(const Vector<uint8_t>& modulus, const Vector<uint8_t>& exponent, const Vector<uint8_t>& privateExponent, const PrimeInfo& firstPrimeInfo, const PrimeInfo& secondPrimeInfo, const Vector<PrimeInfo>& otherPrimeInfos) { return std::unique_ptr<CryptoKeyDataRSAComponents>(new CryptoKeyDataRSAComponents(modulus, exponent, privateExponent, firstPrimeInfo, secondPrimeInfo, otherPrimeInfos)); } + static std::unique_ptr<CryptoKeyDataRSAComponents> createPrivateWithAdditionalData(Vector<uint8_t>&& modulus, Vector<uint8_t>&& exponent, Vector<uint8_t>&& privateExponent, PrimeInfo&& firstPrimeInfo, PrimeInfo&& secondPrimeInfo, Vector<PrimeInfo>&& otherPrimeInfos) + { + return std::unique_ptr<CryptoKeyDataRSAComponents>(new CryptoKeyDataRSAComponents(WTFMove(modulus), WTFMove(exponent), WTFMove(privateExponent), WTFMove(firstPrimeInfo), WTFMove(secondPrimeInfo), WTFMove(otherPrimeInfos))); + } virtual ~CryptoKeyDataRSAComponents(); @@ -78,8 +89,13 @@ public: private: CryptoKeyDataRSAComponents(const Vector<uint8_t>& modulus, const Vector<uint8_t>& exponent); + CryptoKeyDataRSAComponents(Vector<uint8_t>&& modulus, Vector<uint8_t>&& exponent); + CryptoKeyDataRSAComponents(const Vector<uint8_t>& modulus, const Vector<uint8_t>& exponent, const Vector<uint8_t>& privateExponent); + CryptoKeyDataRSAComponents(Vector<uint8_t>&& modulus, Vector<uint8_t>&& exponent, Vector<uint8_t>&& privateExponent); + CryptoKeyDataRSAComponents(const Vector<uint8_t>& modulus, const Vector<uint8_t>& exponent, const Vector<uint8_t>& privateExponent, const PrimeInfo& firstPrimeInfo, const PrimeInfo& secondPrimeInfo, const Vector<PrimeInfo>& otherPrimeInfos); + CryptoKeyDataRSAComponents(Vector<uint8_t>&& modulus, Vector<uint8_t>&& exponent, Vector<uint8_t>&& privateExponent, PrimeInfo&& firstPrimeInfo, PrimeInfo&& secondPrimeInfo, Vector<PrimeInfo>&& otherPrimeInfos); Type m_type; @@ -95,14 +111,8 @@ private: Vector<PrimeInfo> m_otherPrimeInfos; // When three or more primes have been used, the number of array elements is be the number of primes used minus two. }; -inline bool isCryptoKeyDataRSAComponents(const CryptoKeyData& data) -{ - return data.format() == CryptoKeyData::Format::RSAComponents; -} - -CRYPTO_KEY_DATA_CASTS(CryptoKeyDataRSAComponents) - } // namespace WebCore +SPECIALIZE_TYPE_TRAITS_CRYPTO_KEY_DATA(CryptoKeyDataRSAComponents, CryptoKeyData::Format::RSAComponents) + #endif // ENABLE(SUBTLE_CRYPTO) -#endif // CryptoKeyDataRSAComponents_h diff --git a/Source/WebCore/crypto/keys/CryptoKeyHMAC.cpp b/Source/WebCore/crypto/keys/CryptoKeyHMAC.cpp index 747e8c200..d57cb6183 100644 --- a/Source/WebCore/crypto/keys/CryptoKeyHMAC.cpp +++ b/Source/WebCore/crypto/keys/CryptoKeyHMAC.cpp @@ -28,60 +28,111 @@ #if ENABLE(SUBTLE_CRYPTO) -#include "CryptoAlgorithmDescriptionBuilder.h" +#include "CryptoAlgorithmHmacKeyParams.h" #include "CryptoAlgorithmRegistry.h" #include "CryptoKeyDataOctetSequence.h" +#include "JsonWebKey.h" +#include <wtf/text/Base64.h> #include <wtf/text/WTFString.h> namespace WebCore { -CryptoKeyHMAC::CryptoKeyHMAC(const Vector<uint8_t>& key, CryptoAlgorithmIdentifier hash, bool extractable, CryptoKeyUsage usage) +CryptoKeyHMAC::CryptoKeyHMAC(const Vector<uint8_t>& key, CryptoAlgorithmIdentifier hash, bool extractable, CryptoKeyUsageBitmap usage) : CryptoKey(CryptoAlgorithmIdentifier::HMAC, CryptoKeyType::Secret, extractable, usage) , m_hash(hash) , m_key(key) { } +CryptoKeyHMAC::CryptoKeyHMAC(Vector<uint8_t>&& key, CryptoAlgorithmIdentifier hash, bool extractable, CryptoKeyUsageBitmap usage) + : CryptoKey(CryptoAlgorithmIdentifier::HMAC, CryptoKeyType::Secret, extractable, usage) + , m_hash(hash) + , m_key(WTFMove(key)) +{ +} + CryptoKeyHMAC::~CryptoKeyHMAC() { } -PassRefPtr<CryptoKeyHMAC> CryptoKeyHMAC::generate(size_t lengthBytes, CryptoAlgorithmIdentifier hash, bool extractable, CryptoKeyUsage usages) +RefPtr<CryptoKeyHMAC> CryptoKeyHMAC::generate(size_t lengthBits, CryptoAlgorithmIdentifier hash, bool extractable, CryptoKeyUsageBitmap usages) { - if (!lengthBytes) { + if (!lengthBits) { switch (hash) { case CryptoAlgorithmIdentifier::SHA_1: case CryptoAlgorithmIdentifier::SHA_224: case CryptoAlgorithmIdentifier::SHA_256: - lengthBytes = 64; + lengthBits = 512; break; case CryptoAlgorithmIdentifier::SHA_384: case CryptoAlgorithmIdentifier::SHA_512: - lengthBytes = 128; + lengthBits = 1024; break; default: return nullptr; } } + // CommonHMAC only supports key length that is a multiple of 8. Therefore, here we are a little bit different + // from the spec as of 11 December 2014: https://www.w3.org/TR/WebCryptoAPI/#hmac-operations + if (lengthBits % 8) + return nullptr; + + return adoptRef(new CryptoKeyHMAC(randomData(lengthBits / 8), hash, extractable, usages)); +} - return adoptRef(new CryptoKeyHMAC(randomData(lengthBytes), hash, extractable, usages)); +RefPtr<CryptoKeyHMAC> CryptoKeyHMAC::importRaw(size_t lengthBits, CryptoAlgorithmIdentifier hash, Vector<uint8_t>&& keyData, bool extractable, CryptoKeyUsageBitmap usages) +{ + size_t length = keyData.size() * 8; + if (!length) + return nullptr; + // CommonHMAC only supports key length that is a multiple of 8. Therefore, here we are a little bit different + // from the spec as of 11 December 2014: https://www.w3.org/TR/WebCryptoAPI/#hmac-operations + if (lengthBits && lengthBits != length) + return nullptr; + + return adoptRef(new CryptoKeyHMAC(WTFMove(keyData), hash, extractable, usages)); } -void CryptoKeyHMAC::buildAlgorithmDescription(CryptoAlgorithmDescriptionBuilder& builder) const +RefPtr<CryptoKeyHMAC> CryptoKeyHMAC::importJwk(size_t lengthBits, CryptoAlgorithmIdentifier hash, JsonWebKey&& keyData, bool extractable, CryptoKeyUsageBitmap usages, CheckAlgCallback&& callback) { - CryptoKey::buildAlgorithmDescription(builder); + if (keyData.kty != "oct") + return nullptr; + if (keyData.k.isNull()) + return nullptr; + Vector<uint8_t> octetSequence; + if (!base64URLDecode(keyData.k, octetSequence)) + return nullptr; + if (!callback(hash, keyData.alg)) + return nullptr; + if (usages && !keyData.use.isNull() && keyData.use != "sig") + return nullptr; + if (keyData.usages && ((keyData.usages & usages) != usages)) + return nullptr; + if (keyData.ext && !keyData.ext.value() && extractable) + return nullptr; - auto hashDescriptionBuilder = builder.createEmptyClone(); - hashDescriptionBuilder->add("name", CryptoAlgorithmRegistry::shared().nameForIdentifier(m_hash)); - builder.add("hash", *hashDescriptionBuilder); + return CryptoKeyHMAC::importRaw(lengthBits, hash, WTFMove(octetSequence), extractable, usages); +} - builder.add("length", m_key.size()); +JsonWebKey CryptoKeyHMAC::exportJwk() const +{ + JsonWebKey result; + result.kty = "oct"; + result.k = base64URLEncode(m_key); + result.key_ops = usages(); + result.ext = extractable(); + return result; +} + +std::unique_ptr<KeyAlgorithm> CryptoKeyHMAC::buildAlgorithm() const +{ + return std::make_unique<HmacKeyAlgorithm>(CryptoAlgorithmRegistry::singleton().name(algorithmIdentifier()), + CryptoAlgorithmRegistry::singleton().name(m_hash), m_key.size() * 8); } std::unique_ptr<CryptoKeyData> CryptoKeyHMAC::exportData() const { - ASSERT(extractable()); - return CryptoKeyDataOctetSequence::create(m_key); + return std::make_unique<CryptoKeyDataOctetSequence>(m_key); } } // namespace WebCore diff --git a/Source/WebCore/crypto/keys/CryptoKeyHMAC.h b/Source/WebCore/crypto/keys/CryptoKeyHMAC.h index 6e5b359a3..25c24527c 100644 --- a/Source/WebCore/crypto/keys/CryptoKeyHMAC.h +++ b/Source/WebCore/crypto/keys/CryptoKeyHMAC.h @@ -23,51 +23,72 @@ * THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef CryptoKeyHMAC_h -#define CryptoKeyHMAC_h +#pragma once + +#if ENABLE(SUBTLE_CRYPTO) #include "CryptoKey.h" +#include <wtf/Function.h> #include <wtf/Vector.h> -#if ENABLE(SUBTLE_CRYPTO) - namespace WebCore { +struct JsonWebKey; + +class HmacKeyAlgorithm final : public KeyAlgorithm { +public: + HmacKeyAlgorithm(const String& name, const String& hash, size_t length) + : KeyAlgorithm(name) + , m_hash(hash) + , m_length(length) + { + } + + KeyAlgorithmClass keyAlgorithmClass() const final { return KeyAlgorithmClass::HMAC; } + + const String& hash() const { return m_hash; } + size_t length() const { return m_length; } + +private: + String m_hash; + size_t m_length; +}; + class CryptoKeyHMAC final : public CryptoKey { public: - static PassRefPtr<CryptoKeyHMAC> create(const Vector<uint8_t>& key, CryptoAlgorithmIdentifier hash, bool extractable, CryptoKeyUsage usage) + static Ref<CryptoKeyHMAC> create(const Vector<uint8_t>& key, CryptoAlgorithmIdentifier hash, bool extractable, CryptoKeyUsageBitmap usage) { - return adoptRef(new CryptoKeyHMAC(key, hash, extractable, usage)); + return adoptRef(*new CryptoKeyHMAC(key, hash, extractable, usage)); } virtual ~CryptoKeyHMAC(); - // If lengthBytes is 0, a recommended length is used, which is the size of the associated hash function's block size. - static PassRefPtr<CryptoKeyHMAC> generate(size_t lengthBytes, CryptoAlgorithmIdentifier hash, bool extractable, CryptoKeyUsage); + static RefPtr<CryptoKeyHMAC> generate(size_t lengthBits, CryptoAlgorithmIdentifier hash, bool extractable, CryptoKeyUsageBitmap); + static RefPtr<CryptoKeyHMAC> importRaw(size_t lengthBits, CryptoAlgorithmIdentifier hash, Vector<uint8_t>&& keyData, bool extractable, CryptoKeyUsageBitmap); + using CheckAlgCallback = Function<bool(CryptoAlgorithmIdentifier, const String&)>; + static RefPtr<CryptoKeyHMAC> importJwk(size_t lengthBits, CryptoAlgorithmIdentifier hash, JsonWebKey&&, bool extractable, CryptoKeyUsageBitmap, CheckAlgCallback&&); - virtual CryptoKeyClass keyClass() const override { return CryptoKeyClass::HMAC; } + CryptoKeyClass keyClass() const final { return CryptoKeyClass::HMAC; } const Vector<uint8_t>& key() const { return m_key; } + JsonWebKey exportJwk() const; CryptoAlgorithmIdentifier hashAlgorithmIdentifier() const { return m_hash; } private: - CryptoKeyHMAC(const Vector<uint8_t>& key, CryptoAlgorithmIdentifier hash, bool extractable, CryptoKeyUsage); + CryptoKeyHMAC(const Vector<uint8_t>& key, CryptoAlgorithmIdentifier hash, bool extractable, CryptoKeyUsageBitmap); + CryptoKeyHMAC(Vector<uint8_t>&& key, CryptoAlgorithmIdentifier hash, bool extractable, CryptoKeyUsageBitmap); - virtual void buildAlgorithmDescription(CryptoAlgorithmDescriptionBuilder&) const override; - virtual std::unique_ptr<CryptoKeyData> exportData() const override; + std::unique_ptr<KeyAlgorithm> buildAlgorithm() const final; + std::unique_ptr<CryptoKeyData> exportData() const final; CryptoAlgorithmIdentifier m_hash; Vector<uint8_t> m_key; }; -inline bool isCryptoKeyHMAC(const CryptoKey& key) -{ - return key.keyClass() == CryptoKeyClass::HMAC; -} +} // namespace WebCore -CRYPTO_KEY_TYPE_CASTS(CryptoKeyHMAC) +SPECIALIZE_TYPE_TRAITS_CRYPTO_KEY(CryptoKeyHMAC, CryptoKeyClass::HMAC) -} // namespace WebCore +SPECIALIZE_TYPE_TRAITS_KEY_ALGORITHM(HmacKeyAlgorithm, KeyAlgorithmClass::HMAC) #endif // ENABLE(SUBTLE_CRYPTO) -#endif // CryptoKeyHMAC_h diff --git a/Source/WebCore/crypto/keys/CryptoKeyRSA.cpp b/Source/WebCore/crypto/keys/CryptoKeyRSA.cpp new file mode 100644 index 000000000..960be3183 --- /dev/null +++ b/Source/WebCore/crypto/keys/CryptoKeyRSA.cpp @@ -0,0 +1,153 @@ +/* + * Copyright (C) 2016 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "CryptoKeyRSA.h" + +#include "CryptoKeyDataRSAComponents.h" +#include "JsonWebKey.h" +#include <wtf/text/Base64.h> + +#if ENABLE(SUBTLE_CRYPTO) + +namespace WebCore { + +RefPtr<CryptoKeyRSA> CryptoKeyRSA::importJwk(CryptoAlgorithmIdentifier algorithm, std::optional<CryptoAlgorithmIdentifier> hash, JsonWebKey&& keyData, bool extractable, CryptoKeyUsageBitmap usages) +{ + if (keyData.kty != "RSA") + return nullptr; + if (keyData.usages && ((keyData.usages & usages) != usages)) + return nullptr; + if (keyData.ext && !keyData.ext.value() && extractable) + return nullptr; + + if (keyData.n.isNull() || keyData.e.isNull()) + return nullptr; + Vector<uint8_t> modulus; + if (!WTF::base64URLDecode(keyData.n, modulus)) + return nullptr; + // Per RFC 7518 Section 6.3.1.1: https://tools.ietf.org/html/rfc7518#section-6.3.1.1 + if (!modulus.isEmpty() && !modulus[0]) + modulus.remove(0); + Vector<uint8_t> exponent; + if (!WTF::base64URLDecode(keyData.e, exponent)) + return nullptr; + if (keyData.d.isNull()) { + // import public key + auto publicKeyComponents = CryptoKeyDataRSAComponents::createPublic(WTFMove(modulus), WTFMove(exponent)); + // Notice: CryptoAlgorithmIdentifier::SHA_1 is just a placeholder. It should not have any effect if hash is std::nullopt. + return CryptoKeyRSA::create(algorithm, hash.value_or(CryptoAlgorithmIdentifier::SHA_1), !!hash, *publicKeyComponents, extractable, usages); + } + + // import private key + Vector<uint8_t> privateExponent; + if (!WTF::base64URLDecode(keyData.d, privateExponent)) + return nullptr; + if (keyData.p.isNull() && keyData.q.isNull() && keyData.dp.isNull() && keyData.dp.isNull() && keyData.qi.isNull()) { + auto privateKeyComponents = CryptoKeyDataRSAComponents::createPrivate(WTFMove(modulus), WTFMove(exponent), WTFMove(privateExponent)); + // Notice: CryptoAlgorithmIdentifier::SHA_1 is just a placeholder. It should not have any effect if hash is std::nullopt. + return CryptoKeyRSA::create(algorithm, hash.value_or(CryptoAlgorithmIdentifier::SHA_1), !!hash, *privateKeyComponents, extractable, usages); + } + + if (keyData.p.isNull() || keyData.q.isNull() || keyData.dp.isNull() || keyData.dq.isNull() || keyData.qi.isNull()) + return nullptr; + CryptoKeyDataRSAComponents::PrimeInfo firstPrimeInfo; + CryptoKeyDataRSAComponents::PrimeInfo secondPrimeInfo; + if (!WTF::base64URLDecode(keyData.p, firstPrimeInfo.primeFactor)) + return nullptr; + if (!WTF::base64URLDecode(keyData.dp, firstPrimeInfo.factorCRTExponent)) + return nullptr; + if (!WTF::base64URLDecode(keyData.q, secondPrimeInfo.primeFactor)) + return nullptr; + if (!WTF::base64URLDecode(keyData.dq, secondPrimeInfo.factorCRTExponent)) + return nullptr; + if (!WTF::base64URLDecode(keyData.qi, secondPrimeInfo.factorCRTCoefficient)) + return nullptr; + if (!keyData.oth) { + auto privateKeyComponents = CryptoKeyDataRSAComponents::createPrivateWithAdditionalData(WTFMove(modulus), WTFMove(exponent), WTFMove(privateExponent), WTFMove(firstPrimeInfo), WTFMove(secondPrimeInfo), { }); + // Notice: CryptoAlgorithmIdentifier::SHA_1 is just a placeholder. It should not have any effect if hash is std::nullopt. + return CryptoKeyRSA::create(algorithm, hash.value_or(CryptoAlgorithmIdentifier::SHA_1), !!hash, *privateKeyComponents, extractable, usages); + } + + Vector<CryptoKeyDataRSAComponents::PrimeInfo> otherPrimeInfos; + for (auto value : keyData.oth.value()) { + CryptoKeyDataRSAComponents::PrimeInfo info; + if (!WTF::base64URLDecode(value.r, info.primeFactor)) + return nullptr; + if (!WTF::base64URLDecode(value.d, info.factorCRTExponent)) + return nullptr; + if (!WTF::base64URLDecode(value.t, info.factorCRTCoefficient)) + return nullptr; + otherPrimeInfos.append(info); + } + + auto privateKeyComponents = CryptoKeyDataRSAComponents::createPrivateWithAdditionalData(WTFMove(modulus), WTFMove(exponent), WTFMove(privateExponent), WTFMove(firstPrimeInfo), WTFMove(secondPrimeInfo), WTFMove(otherPrimeInfos)); + // Notice: CryptoAlgorithmIdentifier::SHA_1 is just a placeholder. It should not have any effect if hash is std::nullopt. + return CryptoKeyRSA::create(algorithm, hash.value_or(CryptoAlgorithmIdentifier::SHA_1), !!hash, *privateKeyComponents, extractable, usages); +} + +JsonWebKey CryptoKeyRSA::exportJwk() const +{ + JsonWebKey result; + result.kty = "RSA"; + result.key_ops = usages(); + result.ext = extractable(); + + auto keyData = exportData(); + const auto& rsaKeyData = downcast<CryptoKeyDataRSAComponents>(*keyData); + // public key + result.n = base64URLEncode(rsaKeyData.modulus()); + result.e = base64URLEncode(rsaKeyData.exponent()); + if (rsaKeyData.type() == CryptoKeyDataRSAComponents::Type::Public) + return result; + + // private key + result.d = base64URLEncode(rsaKeyData.privateExponent()); + if (!rsaKeyData.hasAdditionalPrivateKeyParameters()) + return result; + + result.p = base64URLEncode(rsaKeyData.firstPrimeInfo().primeFactor); + result.q = base64URLEncode(rsaKeyData.secondPrimeInfo().primeFactor); + result.dp = base64URLEncode(rsaKeyData.firstPrimeInfo().factorCRTExponent); + result.dq = base64URLEncode(rsaKeyData.secondPrimeInfo().factorCRTExponent); + result.qi = base64URLEncode(rsaKeyData.secondPrimeInfo().factorCRTCoefficient); + if (rsaKeyData.otherPrimeInfos().isEmpty()) + return result; + + Vector<RsaOtherPrimesInfo> oth; + for (auto info : rsaKeyData.otherPrimeInfos()) { + RsaOtherPrimesInfo otherInfo; + otherInfo.r = base64URLEncode(info.primeFactor); + otherInfo.d = base64URLEncode(info.factorCRTExponent); + otherInfo.t = base64URLEncode(info.factorCRTCoefficient); + oth.append(WTFMove(otherInfo)); + } + result.oth = WTFMove(oth); + return result; +} + +} // namespace WebCore + +#endif // ENABLE(SUBTLE_CRYPTO) diff --git a/Source/WebCore/crypto/keys/CryptoKeyRSA.h b/Source/WebCore/crypto/keys/CryptoKeyRSA.h index b6c1fab2f..0f8ce7c4f 100644 --- a/Source/WebCore/crypto/keys/CryptoKeyRSA.h +++ b/Source/WebCore/crypto/keys/CryptoKeyRSA.h @@ -23,52 +23,102 @@ * THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef CryptoKeyRSA_h -#define CryptoKeyRSA_h +#pragma once #include "CryptoKey.h" -#include <functional> +#include "ExceptionOr.h" +#include <wtf/Function.h> #if ENABLE(SUBTLE_CRYPTO) -#if PLATFORM(MAC) || PLATFORM(IOS) +#if OS(DARWIN) && !PLATFORM(GTK) typedef struct _CCRSACryptor *CCRSACryptorRef; typedef CCRSACryptorRef PlatformRSAKey; #endif +#if PLATFORM(GTK) +typedef struct _PlatformRSAKeyGnuTLS PlatformRSAKeyGnuTLS; +typedef PlatformRSAKeyGnuTLS *PlatformRSAKey; +#endif + namespace WebCore { class CryptoKeyDataRSAComponents; -class CryptoKeyPair; class PromiseWrapper; +class ScriptExecutionContext; + +struct CryptoKeyPair; +struct JsonWebKey; + +class RsaKeyAlgorithm : public KeyAlgorithm { +public: + RsaKeyAlgorithm(const String& name, size_t modulusLength, Vector<uint8_t>&& publicExponent) + : KeyAlgorithm(name) + , m_modulusLength(modulusLength) + , m_publicExponent(WTFMove(publicExponent)) + { + } + + KeyAlgorithmClass keyAlgorithmClass() const override { return KeyAlgorithmClass::RSA; } + + size_t modulusLength() const { return m_modulusLength; } + const Vector<uint8_t>& publicExponent() const { return m_publicExponent; } + +private: + size_t m_modulusLength; + Vector<uint8_t> m_publicExponent; +}; + +class RsaHashedKeyAlgorithm final : public RsaKeyAlgorithm { +public: + RsaHashedKeyAlgorithm(const String& name, size_t modulusLength, Vector<uint8_t>&& publicExponent, const String& hash) + : RsaKeyAlgorithm(name, modulusLength, WTFMove(publicExponent)) + , m_hash(hash) + { + } + + KeyAlgorithmClass keyAlgorithmClass() const final { return KeyAlgorithmClass::HRSA; } + + const String& hash() const { return m_hash; } + +private: + String m_hash; +}; class CryptoKeyRSA final : public CryptoKey { public: - static PassRefPtr<CryptoKeyRSA> create(CryptoAlgorithmIdentifier identifier, CryptoKeyType type, PlatformRSAKey platformKey, bool extractable, CryptoKeyUsage usage) + static Ref<CryptoKeyRSA> create(CryptoAlgorithmIdentifier identifier, CryptoAlgorithmIdentifier hash, bool hasHash, CryptoKeyType type, PlatformRSAKey platformKey, bool extractable, CryptoKeyUsageBitmap usage) { - return adoptRef(new CryptoKeyRSA(identifier, type, platformKey, extractable, usage)); + return adoptRef(*new CryptoKeyRSA(identifier, hash, hasHash, type, platformKey, extractable, usage)); } - static PassRefPtr<CryptoKeyRSA> create(CryptoAlgorithmIdentifier, const CryptoKeyDataRSAComponents&, bool extractable, CryptoKeyUsage); + static RefPtr<CryptoKeyRSA> create(CryptoAlgorithmIdentifier, CryptoAlgorithmIdentifier hash, bool hasHash, const CryptoKeyDataRSAComponents&, bool extractable, CryptoKeyUsageBitmap); virtual ~CryptoKeyRSA(); - void restrictToHash(CryptoAlgorithmIdentifier); bool isRestrictedToHash(CryptoAlgorithmIdentifier&) const; size_t keySizeInBits() const; - typedef std::function<void(CryptoKeyPair&)> KeyPairCallback; - typedef std::function<void()> VoidCallback; - static void generatePair(CryptoAlgorithmIdentifier, unsigned modulusLength, const Vector<uint8_t>& publicExponent, bool extractable, CryptoKeyUsage, KeyPairCallback, VoidCallback failureCallback); + using KeyPairCallback = WTF::Function<void(CryptoKeyPair&&)>; + using VoidCallback = WTF::Function<void()>; + static void generatePair(CryptoAlgorithmIdentifier, CryptoAlgorithmIdentifier hash, bool hasHash, unsigned modulusLength, const Vector<uint8_t>& publicExponent, bool extractable, CryptoKeyUsageBitmap, KeyPairCallback&&, VoidCallback&& failureCallback, ScriptExecutionContext*); + static RefPtr<CryptoKeyRSA> importJwk(CryptoAlgorithmIdentifier, std::optional<CryptoAlgorithmIdentifier> hash, JsonWebKey&&, bool extractable, CryptoKeyUsageBitmap); + static RefPtr<CryptoKeyRSA> importSpki(CryptoAlgorithmIdentifier, std::optional<CryptoAlgorithmIdentifier> hash, Vector<uint8_t>&&, bool extractable, CryptoKeyUsageBitmap); + static RefPtr<CryptoKeyRSA> importPkcs8(CryptoAlgorithmIdentifier, std::optional<CryptoAlgorithmIdentifier> hash, Vector<uint8_t>&&, bool extractable, CryptoKeyUsageBitmap); PlatformRSAKey platformKey() const { return m_platformKey; } + JsonWebKey exportJwk() const; + ExceptionOr<Vector<uint8_t>> exportSpki() const; + ExceptionOr<Vector<uint8_t>> exportPkcs8() const; + + CryptoAlgorithmIdentifier hashAlgorithmIdentifier() const { return m_hash; } private: - CryptoKeyRSA(CryptoAlgorithmIdentifier, CryptoKeyType, PlatformRSAKey, bool extractable, CryptoKeyUsage); + CryptoKeyRSA(CryptoAlgorithmIdentifier, CryptoAlgorithmIdentifier hash, bool hasHash, CryptoKeyType, PlatformRSAKey, bool extractable, CryptoKeyUsageBitmap); - virtual CryptoKeyClass keyClass() const override { return CryptoKeyClass::RSA; } + CryptoKeyClass keyClass() const final { return CryptoKeyClass::RSA; } - virtual void buildAlgorithmDescription(CryptoAlgorithmDescriptionBuilder&) const override; - virtual std::unique_ptr<CryptoKeyData> exportData() const override; + std::unique_ptr<KeyAlgorithm> buildAlgorithm() const final; + std::unique_ptr<CryptoKeyData> exportData() const final; PlatformRSAKey m_platformKey; @@ -76,14 +126,12 @@ private: CryptoAlgorithmIdentifier m_hash; }; -inline bool isCryptoKeyRSA(const CryptoKey& key) -{ - return key.keyClass() == CryptoKeyClass::RSA; -} +} // namespace WebCore -CRYPTO_KEY_TYPE_CASTS(CryptoKeyRSA) +SPECIALIZE_TYPE_TRAITS_CRYPTO_KEY(CryptoKeyRSA, CryptoKeyClass::RSA) -} // namespace WebCore +SPECIALIZE_TYPE_TRAITS_KEY_ALGORITHM(RsaKeyAlgorithm, KeyAlgorithmClass::RSA) + +SPECIALIZE_TYPE_TRAITS_KEY_ALGORITHM(RsaHashedKeyAlgorithm, KeyAlgorithmClass::HRSA) #endif // ENABLE(SUBTLE_CRYPTO) -#endif // CryptoKeyRSA_h diff --git a/Source/WebCore/crypto/keys/CryptoKeySerializationRaw.cpp b/Source/WebCore/crypto/keys/CryptoKeySerializationRaw.cpp new file mode 100644 index 000000000..765e1ee75 --- /dev/null +++ b/Source/WebCore/crypto/keys/CryptoKeySerializationRaw.cpp @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "CryptoKeySerializationRaw.h" + +#if ENABLE(SUBTLE_CRYPTO) + +#include "CryptoAlgorithm.h" +#include "CryptoAlgorithmParametersDeprecated.h" +#include "CryptoKey.h" +#include "CryptoKeyDataOctetSequence.h" + +namespace WebCore { + +CryptoKeySerializationRaw::CryptoKeySerializationRaw(const CryptoOperationData& data) +{ + m_data.append(data.first, data.second); +} + +CryptoKeySerializationRaw::~CryptoKeySerializationRaw() +{ +} + +std::optional<CryptoAlgorithmPair> CryptoKeySerializationRaw::reconcileAlgorithm(CryptoAlgorithm* algorithm, CryptoAlgorithmParametersDeprecated* parameters) const +{ + return CryptoAlgorithmPair { algorithm, parameters }; +} + +void CryptoKeySerializationRaw::reconcileUsages(CryptoKeyUsageBitmap&) const +{ +} + +void CryptoKeySerializationRaw::reconcileExtractable(bool&) const +{ +} + +std::unique_ptr<CryptoKeyData> CryptoKeySerializationRaw::keyData() const +{ + return std::make_unique<CryptoKeyDataOctetSequence>(m_data); +} + +bool CryptoKeySerializationRaw::serialize(const CryptoKey& key, Vector<uint8_t>& result) +{ + std::unique_ptr<CryptoKeyData> keyData = key.exportData(); + if (!keyData) { + // This generally shouldn't happen as long as all key types implement exportData(), but as underlying libraries return errors, there may be some rare failure conditions. + return false; + } + + if (!is<CryptoKeyDataOctetSequence>(*keyData)) + return false; + + result.appendVector(downcast<CryptoKeyDataOctetSequence>(*keyData).octetSequence()); + return true; +} + + +} // namespace WebCore + +#endif // ENABLE(SUBTLE_CRYPTO) diff --git a/Source/WebCore/crypto/keys/CryptoKeySerializationRaw.h b/Source/WebCore/crypto/keys/CryptoKeySerializationRaw.h new file mode 100644 index 000000000..75dd4e578 --- /dev/null +++ b/Source/WebCore/crypto/keys/CryptoKeySerializationRaw.h @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include "CryptoKeySerialization.h" +#include <wtf/Vector.h> +#include <wtf/text/WTFString.h> + +#if ENABLE(SUBTLE_CRYPTO) + +namespace WebCore { + +class CryptoKey; + +class CryptoKeySerializationRaw final : public CryptoKeySerialization { + WTF_MAKE_NONCOPYABLE(CryptoKeySerializationRaw); +public: + static std::unique_ptr<CryptoKeySerializationRaw> create(const CryptoOperationData& data) + { + return std::unique_ptr<CryptoKeySerializationRaw>(new CryptoKeySerializationRaw(data)); + } + + virtual ~CryptoKeySerializationRaw(); + + static bool serialize(const CryptoKey&, Vector<uint8_t>&); + +private: + CryptoKeySerializationRaw(const CryptoOperationData&); + + std::optional<CryptoAlgorithmPair> reconcileAlgorithm(CryptoAlgorithm*, CryptoAlgorithmParametersDeprecated*) const override; + + void reconcileUsages(CryptoKeyUsageBitmap&) const override; + void reconcileExtractable(bool&) const override; + + std::unique_ptr<CryptoKeyData> keyData() const override; + + Vector<uint8_t> m_data; +}; + +} // namespace WebCore + +#endif // ENABLE(SUBTLE_CRYPTO) |