mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-06-11 18:20:43 +09:00
LibWeb: Implement ED25519 sign for SubtleCrypto
This commit is contained in:
parent
ec015034bd
commit
9ad10566b2
Notes:
sideshowbarker
2024-07-17 12:02:22 +09:00
Author: https://github.com/stelar7
Commit: 9ad10566b2
Pull-request: https://github.com/SerenityOS/serenity/pull/23737
Reviewed-by: https://github.com/ADKaster ✅
Reviewed-by: https://github.com/trflynn89
5 changed files with 46 additions and 14 deletions
|
@ -1 +1 @@
|
||||||
Signed OK ... [13 bytes total] (Hello friends)
|
Signed OK
|
||||||
|
|
|
@ -3,29 +3,25 @@
|
||||||
asyncTest(async done => {
|
asyncTest(async done => {
|
||||||
const encoder = new TextEncoder();
|
const encoder = new TextEncoder();
|
||||||
const message = "Hello friends";
|
const message = "Hello friends";
|
||||||
const encoded_message = encoder.encode(message);
|
const encodedMessage = encoder.encode(message);
|
||||||
|
|
||||||
const key_algorithm = {
|
const keyAlgorithm = {
|
||||||
name: "ECDSA",
|
name: "Ed25519",
|
||||||
namedCurve: "P-384",
|
|
||||||
};
|
};
|
||||||
const extractable = true;
|
const extractable = true;
|
||||||
const usages = ["sign", "verify"];
|
const usages = ["sign", "verify"];
|
||||||
const key = await window.crypto.subtle.generateKey(key_algorithm, extractable, usages);
|
const key = await window.crypto.subtle.generateKey(keyAlgorithm, extractable, usages);
|
||||||
|
|
||||||
const signature_algorithm = {
|
const signatureAlgorithm = {
|
||||||
name: "ECDSA",
|
name: "Ed25519",
|
||||||
hash: { name: "SHA-384" },
|
|
||||||
};
|
};
|
||||||
const signature = await window.crypto.subtle.sign(
|
const signature = await window.crypto.subtle.sign(
|
||||||
signature_algorithm,
|
signatureAlgorithm,
|
||||||
key.privateKey,
|
key.privateKey,
|
||||||
encoded_message
|
encodedMessage
|
||||||
);
|
);
|
||||||
|
|
||||||
const data_view = String.fromCharCode.apply(null, new Uint8Array(signature));
|
println(`Signed OK`);
|
||||||
|
|
||||||
println(`Signed OK ... [${signature.byteLength} bytes total] (${data_view})`);
|
|
||||||
|
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
|
|
@ -1278,4 +1278,38 @@ WebIDL::ExceptionOr<Variant<JS::NonnullGCPtr<CryptoKey>, JS::NonnullGCPtr<Crypto
|
||||||
return Variant<JS::NonnullGCPtr<CryptoKey>, JS::NonnullGCPtr<CryptoKeyPair>> { CryptoKeyPair::create(m_realm, public_key, private_key) };
|
return Variant<JS::NonnullGCPtr<CryptoKey>, JS::NonnullGCPtr<CryptoKeyPair>> { CryptoKeyPair::create(m_realm, public_key, private_key) };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WebIDL::ExceptionOr<JS::NonnullGCPtr<JS::ArrayBuffer>> ED25519::sign([[maybe_unused]] AlgorithmParams const& params, JS::NonnullGCPtr<CryptoKey> key, ByteBuffer const& message)
|
||||||
|
{
|
||||||
|
auto& realm = m_realm;
|
||||||
|
auto& vm = realm.vm();
|
||||||
|
|
||||||
|
// 1. If the [[type]] internal slot of key is not "private", then throw an InvalidAccessError.
|
||||||
|
if (key->type() != Bindings::KeyType::Private)
|
||||||
|
return WebIDL::InvalidAccessError::create(realm, "Key is not a private key"_fly_string);
|
||||||
|
|
||||||
|
// 2. Perform the Ed25519 signing process, as specified in [RFC8032], Section 5.1.6,
|
||||||
|
// with message as M, using the Ed25519 private key associated with key.
|
||||||
|
auto private_key = key->handle().visit(
|
||||||
|
[](ByteBuffer data) -> ByteBuffer {
|
||||||
|
return data;
|
||||||
|
},
|
||||||
|
[](auto) -> ByteBuffer { VERIFY_NOT_REACHED(); });
|
||||||
|
|
||||||
|
::Crypto::Curves::Ed25519 curve;
|
||||||
|
auto maybe_public_key = curve.generate_public_key(private_key);
|
||||||
|
if (maybe_public_key.is_error())
|
||||||
|
return WebIDL::OperationError::create(realm, "Failed to generate public key"_fly_string);
|
||||||
|
auto public_key = maybe_public_key.release_value();
|
||||||
|
|
||||||
|
auto maybe_signature = curve.sign(public_key, private_key, message);
|
||||||
|
if (maybe_signature.is_error())
|
||||||
|
return WebIDL::OperationError::create(realm, "Failed to sign message"_fly_string);
|
||||||
|
auto signature = maybe_signature.release_value();
|
||||||
|
|
||||||
|
// 3. Return a new ArrayBuffer associated with the relevant global object of this [HTML],
|
||||||
|
// and containing the bytes of the signature resulting from performing the Ed25519 signing process.
|
||||||
|
auto result = TRY_OR_THROW_OOM(vm, ByteBuffer::copy(signature));
|
||||||
|
return JS::ArrayBuffer::create(realm, move(result));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -266,6 +266,7 @@ private:
|
||||||
|
|
||||||
class ED25519 : public AlgorithmMethods {
|
class ED25519 : public AlgorithmMethods {
|
||||||
public:
|
public:
|
||||||
|
virtual WebIDL::ExceptionOr<JS::NonnullGCPtr<JS::ArrayBuffer>> sign(AlgorithmParams const&, JS::NonnullGCPtr<CryptoKey>, ByteBuffer const&) override;
|
||||||
virtual WebIDL::ExceptionOr<Variant<JS::NonnullGCPtr<CryptoKey>, JS::NonnullGCPtr<CryptoKeyPair>>> generate_key(AlgorithmParams const&, bool, Vector<Bindings::KeyUsage> const&) override;
|
virtual WebIDL::ExceptionOr<Variant<JS::NonnullGCPtr<CryptoKey>, JS::NonnullGCPtr<CryptoKeyPair>>> generate_key(AlgorithmParams const&, bool, Vector<Bindings::KeyUsage> const&) override;
|
||||||
|
|
||||||
static NonnullOwnPtr<AlgorithmMethods> create(JS::Realm& realm) { return adopt_own(*new ED25519(realm)); }
|
static NonnullOwnPtr<AlgorithmMethods> create(JS::Realm& realm) { return adopt_own(*new ED25519(realm)); }
|
||||||
|
|
|
@ -645,6 +645,7 @@ SupportedAlgorithmsMap supported_algorithms()
|
||||||
define_an_algorithm<ECDSA, EcKeyGenParams>("generateKey"_string, "ECDSA"_string);
|
define_an_algorithm<ECDSA, EcKeyGenParams>("generateKey"_string, "ECDSA"_string);
|
||||||
|
|
||||||
// https://wicg.github.io/webcrypto-secure-curves/#ed25519
|
// https://wicg.github.io/webcrypto-secure-curves/#ed25519
|
||||||
|
define_an_algorithm<ED25519>("sign"_string, "Ed25519"_string);
|
||||||
define_an_algorithm<ED25519>("generateKey"_string, "Ed25519"_string);
|
define_an_algorithm<ED25519>("generateKey"_string, "Ed25519"_string);
|
||||||
|
|
||||||
return internal_object;
|
return internal_object;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue