LibWeb: Support the importing of ml-kem keys in spki format

This commit is contained in:
Tete17
2025-11-28 22:06:58 +01:00
committed by Shannon Booth
parent 6350b063ab
commit a414819dd6
Notes: github-actions[bot] 2025-12-30 13:18:01 +00:00
3 changed files with 90 additions and 0 deletions

View File

@@ -9009,6 +9009,94 @@ WebIDL::ExceptionOr<Variant<GC::Ref<CryptoKey>, GC::Ref<CryptoKeyPair>>> MLKEM::
return WebIDL::ExceptionOr<Variant<GC::Ref<CryptoKey>, GC::Ref<CryptoKeyPair>>>(result);
}
// https://wicg.github.io/webcrypto-modern-algos/#ml-kem-operations-import-key
WebIDL::ExceptionOr<GC::Ref<CryptoKey>> MLKEM::import_key(AlgorithmParams const& params, Bindings::KeyFormat key_format, CryptoKey::InternalKeyData key_data, bool extractable, Vector<Bindings::KeyUsage> const& usages)
{
GC::Ptr<CryptoKey> key = nullptr;
// 1. Let keyData be the key data to be imported.
// 2. -> If format is "spki":
if (key_format == Bindings::KeyFormat::Spki) {
// 1. If usages contains a value which is not "encapsulateKey" or "encapsulateBits" then throw
// a SyntaxError.
for (auto const usage : usages) {
if (usage != Bindings::KeyUsage::Encapsulatekey && usage != Bindings::KeyUsage::Encapsulatebits)
return WebIDL::SyntaxError::create(m_realm, Utf16String::formatted("Invalid key usage '{}'", idl_enum_to_string(usage)));
}
// 2. Let spki be the result of running the parse a subjectPublicKeyInfo algorithm over keyData.
// 3. If an error occurred while parsing, then throw a DataError.
auto const spki = TRY(parse_a_subject_public_key_info(m_realm, key_data.get<ByteBuffer>()));
Array<int, 9> expected_oid;
// 4. If the name member of normalizedAlgorithm is "ML-KEM-512":
if (params.name == "ML-KEM-512") {
// Let expectedOid be id-alg-ml-kem-512 (2.16.840.1.101.3.4.4.1).
expected_oid = ::Crypto::ASN1::ml_kem_512_oid;
}
// If the name member of normalizedAlgorithm is "ML-KEM-768":
else if (params.name == "ML-KEM-768") {
// Let expectedOid be id-alg-ml-kem-768 (2.16.840.1.101.3.4.4.2).
expected_oid = ::Crypto::ASN1::ml_kem_768_oid;
}
// If the name member of normalizedAlgorithm is "ML-KEM-1024":
else if (params.name == "ML-KEM-1024") {
// Let expectedOid be id-alg-ml-kem-1024 (2.16.840.1.101.3.4.4.3).
expected_oid = ::Crypto::ASN1::ml_kem_1024_oid;
}
// Otherwise:
else {
// throw a NotSupportedError.
return WebIDL::NotSupportedError::create(m_realm, "Invalid key format"_utf16);
}
// 5. If the algorithm object identifier field of the algorithm AlgorithmIdentifier field of spki is not equal
// to expectedOid, then throw a DataError.
if (spki.algorithm.identifier != expected_oid)
return WebIDL::DataError::create(m_realm, "Invalid algorithm"_utf16);
// 6. If the parameters field of the algorithm AlgorithmIdentifier field of spki is present, then throw a DataError.
if (spki.algorithm.ec_parameters.has_value())
return WebIDL::DataError::create(m_realm, "Invalid algorithm parameters"_utf16);
// 7. Let publicKey be the ML-KEM public key identified by the subjectPublicKey field of spki.
auto const public_key = spki.raw_key;
// 8. Let key be a new CryptoKey that represents publicKey.
key = CryptoKey::create(m_realm, ::Crypto::PK::MLKEMPublicKey(public_key));
// 9. Set the [[type]] internal slot of key to "public"
key->set_type(Bindings::KeyType::Public);
// 10. Let algorithm be a new KeyAlgorithm.
auto const algorithm = KeyAlgorithm::create(m_realm);
// 11. Set the name attribute of algorithm to the name attribute of normalizedAlgorithm.
algorithm->set_name(params.name);
// 12. Set the [[algorithm]] internal slot of key to algorithm.
key->set_algorithm(algorithm);
// 13. Set the [[extractable]] internal slot of key to extractable.
key->set_extractable(extractable);
// 14. Set the [[usages]] internal slot of key to usages.
key->set_usages(usages);
}
// FIXME: -> If format is "pkcs8":
// FIXME: -> If format is "raw-public":
// FIXME: -> If format is "raw-seed":
// FIXME: -> If format is "jwk":
// -> Otherwise:
else {
// throw a NotSupportedError.
return WebIDL::NotSupportedError::create(m_realm, "Invalid key format"_utf16);
}
// 3. Return key
return GC::Ref { *key };
}
// https://wicg.github.io/webcrypto-modern-algos/#ml-kem-operations-encapsulate
WebIDL::ExceptionOr<EncapsulatedBits> MLKEM::encapsulate(AlgorithmParams const& params, GC::Ref<CryptoKey> key)
{