void CryptoAlgorithmRSASSA_PKCS1_v1_5::exportKey(SubtleCrypto::KeyFormat format, Ref<CryptoKey>&& key, KeyDataCallback&& callback, ExceptionCallback&& exceptionCallback) { const auto& rsaKey = downcast<CryptoKeyRSA>(key.get()); if (!rsaKey.keySizeInBits()) { exceptionCallback(OperationError); return; } KeyData result; switch (format) { case SubtleCrypto::KeyFormat::Jwk: { JsonWebKey jwk = rsaKey.exportJwk(); switch (rsaKey.hashAlgorithmIdentifier()) { case CryptoAlgorithmIdentifier::SHA_1: jwk.alg = String(ALG1); break; case CryptoAlgorithmIdentifier::SHA_224: jwk.alg = String(ALG224); break; case CryptoAlgorithmIdentifier::SHA_256: jwk.alg = String(ALG256); break; case CryptoAlgorithmIdentifier::SHA_384: jwk.alg = String(ALG384); break; case CryptoAlgorithmIdentifier::SHA_512: jwk.alg = String(ALG512); break; default: ASSERT_NOT_REACHED(); } result = WTFMove(jwk); break; } case SubtleCrypto::KeyFormat::Spki: { auto spki = rsaKey.exportSpki(); if (spki.hasException()) { exceptionCallback(spki.releaseException().code()); return; } result = spki.releaseReturnValue(); break; } case SubtleCrypto::KeyFormat::Pkcs8: { auto pkcs8 = rsaKey.exportPkcs8(); if (pkcs8.hasException()) { exceptionCallback(pkcs8.releaseException().code()); return; } result = pkcs8.releaseReturnValue(); break; } default: exceptionCallback(NOT_SUPPORTED_ERR); return; } callback(format, WTFMove(result)); }
void CryptoAlgorithmHMAC::importKey(SubtleCrypto::KeyFormat format, KeyData&& data, const std::unique_ptr<CryptoAlgorithmParameters>&& parameters, bool extractable, CryptoKeyUsageBitmap usages, KeyCallback&& callback, ExceptionCallback&& exceptionCallback) { ASSERT(parameters); const auto& hmacParameters = downcast<CryptoAlgorithmHmacKeyParams>(*parameters); if (usagesAreInvalidForCryptoAlgorithmHMAC(usages)) { exceptionCallback(SYNTAX_ERR); return; } RefPtr<CryptoKeyHMAC> result; switch (format) { case SubtleCrypto::KeyFormat::Raw: result = CryptoKeyHMAC::importRaw(hmacParameters.length.valueOr(0), hmacParameters.hashIdentifier, WTFMove(WTF::get<Vector<uint8_t>>(data)), extractable, usages); break; case SubtleCrypto::KeyFormat::Jwk: { auto checkAlgCallback = [](CryptoAlgorithmIdentifier hash, const Optional<String>& alg) -> bool { switch (hash) { case CryptoAlgorithmIdentifier::SHA_1: return !alg || alg.value() == ALG1; case CryptoAlgorithmIdentifier::SHA_224: return !alg || alg.value() == ALG224; case CryptoAlgorithmIdentifier::SHA_256: return !alg || alg.value() == ALG256; case CryptoAlgorithmIdentifier::SHA_384: return !alg || alg.value() == ALG384; case CryptoAlgorithmIdentifier::SHA_512: return !alg || alg.value() == ALG512; default: return false; } return false; }; result = CryptoKeyHMAC::importJwk(hmacParameters.length.valueOr(0), hmacParameters.hashIdentifier, WTFMove(WTF::get<JsonWebKey>(data)), extractable, usages, WTFMove(checkAlgCallback)); break; } default: exceptionCallback(NOT_SUPPORTED_ERR); return; } if (!result) { exceptionCallback(DataError); return; } callback(*result); }
void CryptoAlgorithmRSASSA_PKCS1_v1_5::verify(Ref<CryptoKey>&& key, Vector<uint8_t>&& signature, Vector<uint8_t>&& data, BoolCallback&& callback, ExceptionCallback&& exceptionCallback, ScriptExecutionContext& context, WorkQueue& workQueue) { if (key->type() != CryptoKeyType::Public) { exceptionCallback(INVALID_ACCESS_ERR); return; } platformVerify(WTFMove(key), WTFMove(signature), WTFMove(data), WTFMove(callback), WTFMove(exceptionCallback), context, workQueue); }
void CryptoAlgorithmHMAC::exportKey(SubtleCrypto::KeyFormat format, Ref<CryptoKey>&& key, KeyDataCallback&& callback, ExceptionCallback&& exceptionCallback) { const auto& hmacKey = downcast<CryptoKeyHMAC>(key.get()); if (hmacKey.key().isEmpty()) { exceptionCallback(OperationError); return; } KeyData result; switch (format) { case SubtleCrypto::KeyFormat::Raw: result = Vector<uint8_t>(hmacKey.key()); break; case SubtleCrypto::KeyFormat::Jwk: { JsonWebKey jwk = hmacKey.exportJwk(); switch (hmacKey.hashAlgorithmIdentifier()) { case CryptoAlgorithmIdentifier::SHA_1: jwk.alg = String(ALG1); break; case CryptoAlgorithmIdentifier::SHA_224: jwk.alg = String(ALG224); break; case CryptoAlgorithmIdentifier::SHA_256: jwk.alg = String(ALG256); break; case CryptoAlgorithmIdentifier::SHA_384: jwk.alg = String(ALG384); break; case CryptoAlgorithmIdentifier::SHA_512: jwk.alg = String(ALG512); break; default: ASSERT_NOT_REACHED(); } result = WTFMove(jwk); break; } default: exceptionCallback(NOT_SUPPORTED_ERR); return; } callback(format, WTFMove(result)); }
void CryptoAlgorithmHMAC::generateKey(const std::unique_ptr<CryptoAlgorithmParameters>&& parameters, bool extractable, CryptoKeyUsageBitmap usages, KeyOrKeyPairCallback&& callback, ExceptionCallback&& exceptionCallback, ScriptExecutionContext&) { ASSERT(parameters); const auto& hmacParameters = downcast<CryptoAlgorithmHmacKeyParams>(*parameters); if (usagesAreInvalidForCryptoAlgorithmHMAC(usages)) { exceptionCallback(SYNTAX_ERR); return; } if (hmacParameters.length && !hmacParameters.length.value()) { exceptionCallback(OperationError); return; } auto result = CryptoKeyHMAC::generate(hmacParameters.length.valueOr(0), hmacParameters.hashIdentifier, extractable, usages); if (!result) { exceptionCallback(OperationError); return; } callback(result.get(), nullptr); }
void CryptoAlgorithmSHA1::digest(Vector<uint8_t>&& message, VectorCallback&& callback, ExceptionCallback&& exceptionCallback, ScriptExecutionContext& context, WorkQueue& workQueue) { auto digest = CryptoDigest::create(CryptoDigest::Algorithm::SHA_1); if (!digest) { exceptionCallback(OperationError); return; } context.ref(); workQueue.dispatch([digest = WTFMove(digest), message = WTFMove(message), callback = WTFMove(callback), &context]() mutable { digest->addBytes(message.data(), message.size()); auto result = digest->computeHash(); context.postTask([callback = WTFMove(callback), result = WTFMove(result)](ScriptExecutionContext& context) { callback(result); context.deref(); }); }); }
void CryptoAlgorithmRSASSA_PKCS1_v1_5::generateKey(const CryptoAlgorithmParameters& parameters, bool extractable, CryptoKeyUsageBitmap usages, KeyOrKeyPairCallback&& callback, ExceptionCallback&& exceptionCallback, ScriptExecutionContext& context) { const auto& rsaParameters = downcast<CryptoAlgorithmRsaHashedKeyGenParams>(parameters); if (usages & (CryptoKeyUsageDecrypt | CryptoKeyUsageEncrypt | CryptoKeyUsageDeriveKey | CryptoKeyUsageDeriveBits | CryptoKeyUsageWrapKey | CryptoKeyUsageUnwrapKey)) { exceptionCallback(SYNTAX_ERR); return; } auto keyPairCallback = [capturedCallback = WTFMove(callback)](CryptoKeyPair&& pair) { pair.publicKey->setUsagesBitmap(pair.publicKey->usagesBitmap() & CryptoKeyUsageVerify); pair.privateKey->setUsagesBitmap(pair.privateKey->usagesBitmap() & CryptoKeyUsageSign); capturedCallback(WTFMove(pair)); }; auto failureCallback = [capturedCallback = WTFMove(exceptionCallback)]() { capturedCallback(OperationError); }; CryptoKeyRSA::generatePair(CryptoAlgorithmIdentifier::RSASSA_PKCS1_v1_5, rsaParameters.hashIdentifier, true, rsaParameters.modulusLength, rsaParameters.publicExponentVector(), extractable, usages, WTFMove(keyPairCallback), WTFMove(failureCallback), &context); }
void CryptoAlgorithmRSA_OAEP::platformDecrypt(std::unique_ptr<CryptoAlgorithmParameters>&& parameters, Ref<CryptoKey>&& key, Vector<uint8_t>&& cipherText, VectorCallback&& callback, ExceptionCallback&& exceptionCallback, ScriptExecutionContext& context, WorkQueue& workQueue) { context.ref(); workQueue.dispatch([parameters = WTFMove(parameters), key = WTFMove(key), cipherText = WTFMove(cipherText), callback = WTFMove(callback), exceptionCallback = WTFMove(exceptionCallback), &context]() mutable { auto& rsaParameters = downcast<CryptoAlgorithmRsaOaepParams>(*parameters); auto& rsaKey = downcast<CryptoKeyRSA>(key.get()); auto result = decryptRSA_OAEP(rsaKey.hashAlgorithmIdentifier(), rsaParameters.labelVector(), rsaKey.platformKey(), rsaKey.keySizeInBits(), cipherText.data(), cipherText.size()); if (result.hasException()) { context.postTask([exceptionCallback = WTFMove(exceptionCallback), ec = result.releaseException().code()](ScriptExecutionContext& context) { exceptionCallback(ec); context.deref(); }); return; } context.postTask([callback = WTFMove(callback), result = result.releaseReturnValue()](ScriptExecutionContext& context) { callback(result); context.deref(); }); }); }
void CryptoAlgorithmRSASSA_PKCS1_v1_5::importKey(SubtleCrypto::KeyFormat format, KeyData&& data, const std::unique_ptr<CryptoAlgorithmParameters>&& parameters, bool extractable, CryptoKeyUsageBitmap usages, KeyCallback&& callback, ExceptionCallback&& exceptionCallback) { ASSERT(parameters); const auto& rsaParameters = downcast<CryptoAlgorithmRsaHashedImportParams>(*parameters); RefPtr<CryptoKeyRSA> result; switch (format) { case SubtleCrypto::KeyFormat::Jwk: { JsonWebKey key = WTFMove(WTF::get<JsonWebKey>(data)); if (usages && ((key.d && (usages ^ CryptoKeyUsageSign)) || (!key.d && (usages ^ CryptoKeyUsageVerify)))) { exceptionCallback(SYNTAX_ERR); return; } if (usages && key.use && key.use.value() != "sig") { exceptionCallback(DataError); return; } bool isMatched = false; switch (rsaParameters.hashIdentifier) { case CryptoAlgorithmIdentifier::SHA_1: isMatched = !key.alg || key.alg.value() == ALG1; break; case CryptoAlgorithmIdentifier::SHA_224: isMatched = !key.alg || key.alg.value() == ALG224; break; case CryptoAlgorithmIdentifier::SHA_256: isMatched = !key.alg || key.alg.value() == ALG256; break; case CryptoAlgorithmIdentifier::SHA_384: isMatched = !key.alg || key.alg.value() == ALG384; break; case CryptoAlgorithmIdentifier::SHA_512: isMatched = !key.alg || key.alg.value() == ALG512; break; default: break; } if (!isMatched) { exceptionCallback(DataError); return; } result = CryptoKeyRSA::importJwk(rsaParameters.identifier, rsaParameters.hashIdentifier, WTFMove(key), extractable, usages); break; } case SubtleCrypto::KeyFormat::Spki: { if (usages && (usages ^ CryptoKeyUsageVerify)) { exceptionCallback(SYNTAX_ERR); return; } // FIXME: <webkit.org/b/165436> result = CryptoKeyRSA::importSpki(rsaParameters.identifier, rsaParameters.hashIdentifier, WTFMove(WTF::get<Vector<uint8_t>>(data)), extractable, usages); break; } case SubtleCrypto::KeyFormat::Pkcs8: { if (usages && (usages ^ CryptoKeyUsageSign)) { exceptionCallback(SYNTAX_ERR); return; } // FIXME: <webkit.org/b/165436> result = CryptoKeyRSA::importPkcs8(parameters->identifier, rsaParameters.hashIdentifier, WTFMove(WTF::get<Vector<uint8_t>>(data)), extractable, usages); break; } default: exceptionCallback(NOT_SUPPORTED_ERR); return; } if (!result) { exceptionCallback(DataError); return; } callback(*result); }