mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-05-23 19:42:53 +00:00
LibWeb: Implement ED25519 generateKey for SubtleCrypto
This commit is contained in:
parent
069295d132
commit
ec015034bd
Notes:
sideshowbarker
2024-07-18 00:34:07 +09:00
Author: https://github.com/stelar7
Commit: ec015034bd
Pull-request: https://github.com/SerenityOS/serenity/pull/23737
Reviewed-by: https://github.com/ADKaster ✅
Reviewed-by: https://github.com/trflynn89
3 changed files with 84 additions and 0 deletions
|
@ -7,6 +7,7 @@
|
|||
#include <AK/Base64.h>
|
||||
#include <AK/QuickSort.h>
|
||||
#include <LibCrypto/ASN1/DER.h>
|
||||
#include <LibCrypto/Curves/Ed25519.h>
|
||||
#include <LibCrypto/Curves/SECPxxxr1.h>
|
||||
#include <LibCrypto/Hash/HashManager.h>
|
||||
#include <LibCrypto/PK/RSA.h>
|
||||
|
@ -1210,4 +1211,71 @@ WebIDL::ExceptionOr<JS::Value> ECDSA::verify(AlgorithmParams const& params, JS::
|
|||
return JS::Value(result);
|
||||
}
|
||||
|
||||
// https://wicg.github.io/webcrypto-secure-curves/#ed25519-operations
|
||||
WebIDL::ExceptionOr<Variant<JS::NonnullGCPtr<CryptoKey>, JS::NonnullGCPtr<CryptoKeyPair>>> ED25519::generate_key([[maybe_unused]] AlgorithmParams const& params, bool extractable, Vector<Bindings::KeyUsage> const& key_usages)
|
||||
{
|
||||
// 1. If usages contains a value which is not one of "sign" or "verify", then throw a SyntaxError.
|
||||
for (auto const& usage : key_usages) {
|
||||
if (usage != Bindings::KeyUsage::Sign && usage != Bindings::KeyUsage::Verify) {
|
||||
return WebIDL::SyntaxError::create(m_realm, MUST(String::formatted("Invalid key usage '{}'", idl_enum_to_string(usage))));
|
||||
}
|
||||
}
|
||||
|
||||
// 2. Generate an Ed25519 key pair, as defined in [RFC8032], section 5.1.5.
|
||||
::Crypto::Curves::Ed25519 curve;
|
||||
auto maybe_private_key = curve.generate_private_key();
|
||||
if (maybe_private_key.is_error())
|
||||
return WebIDL::OperationError::create(m_realm, "Failed to generate private key"_fly_string);
|
||||
auto private_key_data = maybe_private_key.release_value();
|
||||
|
||||
auto maybe_public_key = curve.generate_public_key(private_key_data);
|
||||
if (maybe_public_key.is_error())
|
||||
return WebIDL::OperationError::create(m_realm, "Failed to generate public key"_fly_string);
|
||||
auto public_key_data = maybe_public_key.release_value();
|
||||
|
||||
// 3. Let algorithm be a new KeyAlgorithm object.
|
||||
auto algorithm = KeyAlgorithm::create(m_realm);
|
||||
|
||||
// 4. Set the name attribute of algorithm to "Ed25519".
|
||||
algorithm->set_name("Ed25519"_string);
|
||||
|
||||
// 5. Let publicKey be a new CryptoKey associated with the relevant global object of this [HTML],
|
||||
// and representing the public key of the generated key pair.
|
||||
auto public_key = CryptoKey::create(m_realm, CryptoKey::InternalKeyData { public_key_data });
|
||||
|
||||
// 6. Set the [[type]] internal slot of publicKey to "public"
|
||||
public_key->set_type(Bindings::KeyType::Public);
|
||||
|
||||
// 7. Set the [[algorithm]] internal slot of publicKey to algorithm.
|
||||
public_key->set_algorithm(algorithm);
|
||||
|
||||
// 8. Set the [[extractable]] internal slot of publicKey to true.
|
||||
public_key->set_extractable(true);
|
||||
|
||||
// 9. Set the [[usages]] internal slot of publicKey to be the usage intersection of usages and [ "verify" ].
|
||||
public_key->set_usages(usage_intersection(key_usages, { { Bindings::KeyUsage::Verify } }));
|
||||
|
||||
// 10. Let privateKey be a new CryptoKey associated with the relevant global object of this [HTML],
|
||||
// and representing the private key of the generated key pair.
|
||||
auto private_key = CryptoKey::create(m_realm, CryptoKey::InternalKeyData { private_key_data });
|
||||
|
||||
// 11. Set the [[type]] internal slot of privateKey to "private"
|
||||
private_key->set_type(Bindings::KeyType::Private);
|
||||
|
||||
// 12. Set the [[algorithm]] internal slot of privateKey to algorithm.
|
||||
private_key->set_algorithm(algorithm);
|
||||
|
||||
// 13. Set the [[extractable]] internal slot of privateKey to extractable.
|
||||
private_key->set_extractable(extractable);
|
||||
|
||||
// 14. Set the [[usages]] internal slot of privateKey to be the usage intersection of usages and [ "sign" ].
|
||||
private_key->set_usages(usage_intersection(key_usages, { { Bindings::KeyUsage::Sign } }));
|
||||
|
||||
// 15. Let result be a new CryptoKeyPair dictionary.
|
||||
// 16. Set the publicKey attribute of result to be publicKey.
|
||||
// 17. Set the privateKey attribute of result to be privateKey.
|
||||
// 18. Return the result of converting result to an ECMAScript Object, as defined by [WebIDL].
|
||||
return Variant<JS::NonnullGCPtr<CryptoKey>, JS::NonnullGCPtr<CryptoKeyPair>> { CryptoKeyPair::create(m_realm, public_key, private_key) };
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue