LibWeb: Add RSAOAEP.exportKey for the spki format

This commit is contained in:
stelar7 2024-04-05 15:46:42 +02:00 committed by Andreas Kling
parent 1fd6673f87
commit f9dd028119
Notes: sideshowbarker 2024-07-17 07:11:12 +09:00
2 changed files with 43 additions and 5 deletions

View file

@ -7,6 +7,7 @@
#pragma once #pragma once
#include <AK/ByteBuffer.h> #include <AK/ByteBuffer.h>
#include <LibCrypto/ASN1/DER.h>
#ifndef KERNEL #ifndef KERNEL
# include <AK/ByteString.h> # include <AK/ByteString.h>
@ -44,6 +45,35 @@ requires requires(ExportableKey k) {
return encoder.finish(); return encoder.finish();
} }
template<typename ExportableKey>
ErrorOr<ByteBuffer> wrap_in_subject_public_key_info(ExportableKey key, Span<int> algorithm_identifier)
requires requires(ExportableKey k) {
k.export_as_der();
}
{
ASN1::Encoder encoder;
TRY(encoder.write_constructed(ASN1::Class::Universal, ASN1::Kind::Sequence, [&]() -> ErrorOr<void> {
// AlgorithmIdentifier
TRY(encoder.write_constructed(ASN1::Class::Universal, ASN1::Kind::Sequence, [&]() -> ErrorOr<void> {
TRY(encoder.write(algorithm_identifier)); // algorithm
// FIXME: This assumes we have a NULL parameter, this is not always the case
TRY(encoder.write(nullptr)); // parameters
return {};
}));
// subjectPublicKey
auto data = TRY(key.export_as_der());
auto bitstring = ::Crypto::ASN1::BitStringView(data, 0);
TRY(encoder.write(bitstring));
return {};
}));
return encoder.finish();
}
// FIXME: Fixing name up for grabs // FIXME: Fixing name up for grabs
template<typename PrivKeyT, typename PubKeyT> template<typename PrivKeyT, typename PubKeyT>
class PKSystem { class PKSystem {

View file

@ -788,19 +788,27 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<JS::Object>> RSAOAEP::export_key(Bindings::
if (key->type() != Bindings::KeyType::Public) if (key->type() != Bindings::KeyType::Public)
return WebIDL::InvalidAccessError::create(realm, "Key is not public"_fly_string); return WebIDL::InvalidAccessError::create(realm, "Key is not public"_fly_string);
// FIXME: 2. Let data be an instance of the subjectPublicKeyInfo ASN.1 structure defined in [RFC5280] with the following properties: // 2. Let data be an instance of the subjectPublicKeyInfo ASN.1 structure defined in [RFC5280] with the following properties:
// - Set the algorithm field to an AlgorithmIdentifier ASN.1 type with the following properties: // - Set the algorithm field to an AlgorithmIdentifier ASN.1 type with the following properties:
// - Set the algorithm field to the OID rsaEncryption defined in [RFC3447]. // - Set the algorithm field to the OID rsaEncryption defined in [RFC3447].
// - Set the params field to the ASN.1 type NULL. // - Set the params field to the ASN.1 type NULL.
// - Set the subjectPublicKey field to the result of DER-encoding an RSAPublicKey ASN.1 type, as defined in [RFC3447], Appendix A.1.1, // - Set the subjectPublicKey field to the result of DER-encoding an RSAPublicKey ASN.1 type, as defined in [RFC3447], Appendix A.1.1,
// that represents the RSA public key represented by the [[handle]] internal slot of key // that represents the RSA public key represented by the [[handle]] internal slot of key
auto maybe_data = handle.visit(
[&](::Crypto::PK::RSAPublicKey<> const& public_key) -> ErrorOr<ByteBuffer> {
auto rsa_encryption_oid = Array<int, 7> { 1, 2, 840, 113549, 1, 1, 1 };
return TRY(::Crypto::PK::wrap_in_subject_public_key_info(public_key, rsa_encryption_oid));
},
[](auto) -> ErrorOr<ByteBuffer> {
VERIFY_NOT_REACHED();
});
// FIXME: clang-format butchers the visit if we do the TRY inline
auto data = TRY_OR_THROW_OOM(vm, maybe_data);
// FIXME: 3. Let result be the result of creating an ArrayBuffer containing data. // 3. Let result be the result of creating an ArrayBuffer containing data.
result = JS::ArrayBuffer::create(realm, TRY_OR_THROW_OOM(vm, ByteBuffer::copy(("FIXME"sv).bytes()))); result = JS::ArrayBuffer::create(realm, data);
} }
// FIXME: If format is "pkcs8"
// If format is "jwk" // If format is "jwk"
else if (format == Bindings::KeyFormat::Jwk) { else if (format == Bindings::KeyFormat::Jwk) {
// 1. Let jwk be a new JsonWebKey dictionary. // 1. Let jwk be a new JsonWebKey dictionary.