diff options
Diffstat (limited to 'Source/WebCore/crypto/keys/CryptoKeyHMAC.cpp')
-rw-r--r-- | Source/WebCore/crypto/keys/CryptoKeyHMAC.cpp | 81 |
1 files changed, 66 insertions, 15 deletions
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 |