From 289f2b24bf7c2c957305751e35b3b828173daa0a Mon Sep 17 00:00:00 2001 From: devgianlu Date: Sat, 31 May 2025 19:06:51 +0200 Subject: [PATCH] LibCrypto+LibWeb: De-templetize RSA and EC key types There is no need to have `RSAPrivateKey`, `RSAPublicKey`, `ECPrivateKey` and `ECPublicKey` to be templatize to utilize different implementation of numbers. --- Libraries/LibCrypto/Certificate/Certificate.h | 8 +- Libraries/LibCrypto/PK/EC.cpp | 13 +- Libraries/LibCrypto/PK/EC.h | 24 ++-- Libraries/LibCrypto/PK/PK.h | 1 - Libraries/LibCrypto/PK/RSA.cpp | 3 +- Libraries/LibCrypto/PK/RSA.h | 60 +++++---- Libraries/LibWeb/Crypto/CryptoAlgorithms.cpp | 122 +++++++++--------- Libraries/LibWeb/Crypto/CryptoKey.h | 2 +- Tests/LibCrypto/TestRSA.cpp | 2 +- 9 files changed, 113 insertions(+), 122 deletions(-) diff --git a/Libraries/LibCrypto/Certificate/Certificate.h b/Libraries/LibCrypto/Certificate/Certificate.h index 5317775e5b3..a1aec8565e4 100644 --- a/Libraries/LibCrypto/Certificate/Certificate.h +++ b/Libraries/LibCrypto/Certificate/Certificate.h @@ -31,8 +31,8 @@ ErrorOr> parse_ec_parameters(ASN1::Decoder& decoder, Vector rsa; - PK::ECPublicKey<> ec; + PK::RSAPublicKey rsa; + PK::ECPublicKey ec; AlgorithmIdentifier algorithm; ByteBuffer raw_key; @@ -42,8 +42,8 @@ ErrorOr parse_subject_public_key_info(ASN1::Decoder& decoder, // https://www.rfc-editor.org/rfc/rfc5208#section-5 class PrivateKey { public: - PK::RSAPrivateKey<> rsa; - PK::ECPrivateKey<> ec; + PK::RSAPrivateKey rsa; + PK::ECPrivateKey ec; AlgorithmIdentifier algorithm; ByteBuffer raw_key; diff --git a/Libraries/LibCrypto/PK/EC.cpp b/Libraries/LibCrypto/PK/EC.cpp index 16912b3cb36..1a90059fb41 100644 --- a/Libraries/LibCrypto/PK/EC.cpp +++ b/Libraries/LibCrypto/PK/EC.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Altomani Gianluca + * Copyright (c) 2024-2025, Altomani Gianluca * * SPDX-License-Identifier: BSD-2-Clause */ @@ -11,8 +11,7 @@ namespace Crypto::PK { -template<> -ErrorOr ECPrivateKey::export_as_der() const +ErrorOr ECPrivateKey::export_as_der() const { ASN1::Encoder encoder; TRY(encoder.write_constructed(ASN1::Class::Universal, ASN1::Kind::Sequence, [&]() -> ErrorOr { @@ -43,7 +42,7 @@ ErrorOr ECPrivateKey::export_as_der() const return encoder.finish(); } -static ErrorOr> read_ec_public_key(ReadonlyBytes bytes, Vector current_scope) +static ErrorOr read_ec_public_key(ReadonlyBytes bytes, Vector current_scope) { // NOTE: Public keys do not have an ASN1 structure if (bytes.size() < 1) { @@ -56,7 +55,7 @@ static ErrorOr> read_ec_public_key(ReadonlyBytes bytes, Vector { + return ::Crypto::PK::ECPublicKey { UnsignedBigInteger::import_data(bytes.slice(1, half_size)), UnsignedBigInteger::import_data(bytes.slice(1 + half_size, half_size)), half_size, @@ -66,7 +65,7 @@ static ErrorOr> read_ec_public_key(ReadonlyBytes bytes, Vector { + return ::Crypto::PK::ECPublicKey { UnsignedBigInteger::import_data(bytes.slice(0, half_size)), UnsignedBigInteger::import_data(bytes.slice(half_size, half_size)), half_size, @@ -118,7 +117,7 @@ ErrorOr EC::parse_ec_key(ReadonlyBytes der, bool is_private, Ve } } - Optional> public_key; + Optional public_key; if (!decoder.eof()) { auto tag = TRY(decoder.peek()); if (static_cast(tag.kind) == 1) { diff --git a/Libraries/LibCrypto/PK/EC.h b/Libraries/LibCrypto/PK/EC.h index 5ed61147d98..e8dae38a7c2 100644 --- a/Libraries/LibCrypto/PK/EC.h +++ b/Libraries/LibCrypto/PK/EC.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Altomani Gianluca + * Copyright (c) 2024-2025, Altomani Gianluca * * SPDX-License-Identifier: BSD-2-Clause */ @@ -8,16 +8,14 @@ #include #include -#include #include #include namespace Crypto::PK { -template class ECPublicKey { public: - ECPublicKey(Integer x, Integer y, size_t scalar_size) + ECPublicKey(UnsignedBigInteger x, UnsignedBigInteger y, size_t scalar_size) : m_x(move(x)) , m_y(move(y)) , m_scalar_size(scalar_size) @@ -61,16 +59,15 @@ public: } private: - Integer m_x; - Integer m_y; + UnsignedBigInteger m_x; + UnsignedBigInteger m_y; size_t m_scalar_size; }; // https://www.rfc-editor.org/rfc/rfc5915#section-3 -template class ECPrivateKey { public: - ECPrivateKey(Integer d, size_t scalar_size, Optional> parameters, Optional> public_key) + ECPrivateKey(UnsignedBigInteger d, size_t scalar_size, Optional> parameters, Optional public_key) : m_d(move(d)) , m_scalar_size(scalar_size) , m_parameters(parameters) @@ -80,23 +77,23 @@ public: ECPrivateKey() = default; - Integer const& d() const { return m_d; } + UnsignedBigInteger const& d() const { return m_d; } ErrorOr d_bytes() const { return Curves::SECPxxxr1Point::scalar_to_bytes(m_d, m_scalar_size); } Optional const&> parameters() const { return m_parameters; } - Optional const&> public_key() const { return m_public_key; } + Optional public_key() const { return m_public_key; } ErrorOr export_as_der() const; private: - Integer m_d; + UnsignedBigInteger m_d; size_t m_scalar_size; Optional> m_parameters; - Optional> m_public_key; + Optional m_public_key; }; template @@ -105,8 +102,7 @@ struct ECKeyPair { PrivKey private_key; }; -using IntegerType = UnsignedBigInteger; -class EC : public PKSystem, ECPublicKey> { +class EC : public PKSystem { public: using KeyPairType = ECKeyPair; diff --git a/Libraries/LibCrypto/PK/PK.h b/Libraries/LibCrypto/PK/PK.h index 7254ad01172..d3ab0156cdf 100644 --- a/Libraries/LibCrypto/PK/PK.h +++ b/Libraries/LibCrypto/PK/PK.h @@ -217,7 +217,6 @@ requires requires(ExportableKey k) { return encoder.finish(); } -// FIXME: Fixing name up for grabs template class PKSystem { public: diff --git a/Libraries/LibCrypto/PK/RSA.cpp b/Libraries/LibCrypto/PK/RSA.cpp index 6f09834aa94..4ef8fe755a9 100644 --- a/Libraries/LibCrypto/PK/RSA.cpp +++ b/Libraries/LibCrypto/PK/RSA.cpp @@ -14,7 +14,6 @@ #include #include #include -#include #include #include @@ -121,7 +120,7 @@ ErrorOr RSA::parse_rsa_key(ReadonlyBytes der, bool is_private, } } -ErrorOr RSA::generate_key_pair(size_t bits, IntegerType e) +ErrorOr RSA::generate_key_pair(size_t bits, UnsignedBigInteger e) { auto ctx = TRY(OpenSSL_PKEY_CTX::wrap(EVP_PKEY_CTX_new_from_name(nullptr, "RSA", nullptr))); diff --git a/Libraries/LibCrypto/PK/RSA.h b/Libraries/LibCrypto/PK/RSA.h index 7793e0c2cde..05fe95b7000 100644 --- a/Libraries/LibCrypto/PK/RSA.h +++ b/Libraries/LibCrypto/PK/RSA.h @@ -1,6 +1,7 @@ /* * Copyright (c) 2020, Ali Mohammad Pur * Copyright (c) 2022, the SerenityOS developers. + * Copyright (c) 2025, Altomani Gianluca * * SPDX-License-Identifier: BSD-2-Clause */ @@ -15,10 +16,9 @@ namespace Crypto::PK { -template class RSAPublicKey { public: - RSAPublicKey(Integer n, Integer e) + RSAPublicKey(UnsignedBigInteger n, UnsignedBigInteger e) : m_modulus(move(n)) , m_public_exponent(move(e)) , m_length(m_modulus.byte_length()) @@ -31,8 +31,8 @@ public: { } - Integer const& modulus() const { return m_modulus; } - Integer const& public_exponent() const { return m_public_exponent; } + UnsignedBigInteger const& modulus() const { return m_modulus; } + UnsignedBigInteger const& public_exponent() const { return m_public_exponent; } size_t length() const { return m_length; } void set_length(size_t length) { m_length = length; } @@ -48,7 +48,7 @@ public: return encoder.finish(); } - void set(Integer n, Integer e) + void set(UnsignedBigInteger n, UnsignedBigInteger e) { m_modulus = move(n); m_public_exponent = move(e); @@ -56,15 +56,14 @@ public: } private: - Integer m_modulus; - Integer m_public_exponent; + UnsignedBigInteger m_modulus; + UnsignedBigInteger m_public_exponent; size_t m_length { 0 }; }; -template class RSAPrivateKey { public: - RSAPrivateKey(Integer n, Integer d, Integer e) + RSAPrivateKey(UnsignedBigInteger n, UnsignedBigInteger d, UnsignedBigInteger e) : m_modulus(move(n)) , m_private_exponent(move(d)) , m_public_exponent(move(e)) @@ -72,7 +71,7 @@ public: { } - RSAPrivateKey(Integer n, Integer d, Integer e, Integer p, Integer q, Integer dp, Integer dq, Integer qinv) + RSAPrivateKey(UnsignedBigInteger n, UnsignedBigInteger d, UnsignedBigInteger e, UnsignedBigInteger p, UnsignedBigInteger q, UnsignedBigInteger dp, UnsignedBigInteger dq, UnsignedBigInteger qinv) : m_modulus(move(n)) , m_private_exponent(move(d)) , m_public_exponent(move(e)) @@ -87,14 +86,14 @@ public: RSAPrivateKey() = default; - Integer const& modulus() const { return m_modulus; } - Integer const& private_exponent() const { return m_private_exponent; } - Integer const& public_exponent() const { return m_public_exponent; } - Integer const& prime1() const { return m_prime_1; } - Integer const& prime2() const { return m_prime_2; } - Integer const& exponent1() const { return m_exponent_1; } - Integer const& exponent2() const { return m_exponent_2; } - Integer const& coefficient() const { return m_coefficient; } + UnsignedBigInteger const& modulus() const { return m_modulus; } + UnsignedBigInteger const& private_exponent() const { return m_private_exponent; } + UnsignedBigInteger const& public_exponent() const { return m_public_exponent; } + UnsignedBigInteger const& prime1() const { return m_prime_1; } + UnsignedBigInteger const& prime2() const { return m_prime_2; } + UnsignedBigInteger const& exponent1() const { return m_exponent_1; } + UnsignedBigInteger const& exponent2() const { return m_exponent_2; } + UnsignedBigInteger const& coefficient() const { return m_coefficient; } size_t length() const { return m_length; } ErrorOr export_as_der() const @@ -121,14 +120,14 @@ public: } private: - Integer m_modulus; - Integer m_private_exponent; - Integer m_public_exponent; - Integer m_prime_1; - Integer m_prime_2; - Integer m_exponent_1; // d mod (p-1) - Integer m_exponent_2; // d mod (q-1) - Integer m_coefficient; // q^-1 mod p + UnsignedBigInteger m_modulus; + UnsignedBigInteger m_private_exponent; + UnsignedBigInteger m_public_exponent; + UnsignedBigInteger m_prime_1; + UnsignedBigInteger m_prime_2; + UnsignedBigInteger m_exponent_1; // d mod (p-1) + UnsignedBigInteger m_exponent_2; // d mod (q-1) + UnsignedBigInteger m_coefficient; // q^-1 mod p size_t m_length { 0 }; }; @@ -138,21 +137,20 @@ struct RSAKeyPair { PrivKey private_key; }; -using IntegerType = UnsignedBigInteger; -class RSA : public PKSystem, RSAPublicKey> { +class RSA : public PKSystem { public: using KeyPairType = RSAKeyPair; static ErrorOr parse_rsa_key(ReadonlyBytes der, bool is_private, Vector current_scope); - static ErrorOr generate_key_pair(size_t bits, IntegerType e = 65537); + static ErrorOr generate_key_pair(size_t bits, UnsignedBigInteger e = 65537); RSA(KeyPairType const& pair) - : PKSystem, RSAPublicKey>(pair.public_key, pair.private_key) + : PKSystem(pair.public_key, pair.private_key) { } RSA(PublicKeyType const& pubkey, PrivateKeyType const& privkey) - : PKSystem, RSAPublicKey>(pubkey, privkey) + : PKSystem(pubkey, privkey) { } diff --git a/Libraries/LibWeb/Crypto/CryptoAlgorithms.cpp b/Libraries/LibWeb/Crypto/CryptoAlgorithms.cpp index c82d89f8d92..59bf353caab 100644 --- a/Libraries/LibWeb/Crypto/CryptoAlgorithms.cpp +++ b/Libraries/LibWeb/Crypto/CryptoAlgorithms.cpp @@ -233,7 +233,7 @@ static WebIDL::ExceptionOr<::Crypto::Certificate::PrivateKey> parse_a_private_ke return parse_an_ASN1_structure<::Crypto::Certificate::PrivateKey>(realm, bytes, true); } -static WebIDL::ExceptionOr<::Crypto::PK::RSAPrivateKey<>> parse_jwk_rsa_private_key(JS::Realm& realm, Bindings::JsonWebKey const& jwk) +static WebIDL::ExceptionOr<::Crypto::PK::RSAPrivateKey> parse_jwk_rsa_private_key(JS::Realm& realm, Bindings::JsonWebKey const& jwk) { auto n = TRY(base64_url_uint_decode(realm, *jwk.n)); auto d = TRY(base64_url_uint_decode(realm, *jwk.d)); @@ -241,7 +241,7 @@ static WebIDL::ExceptionOr<::Crypto::PK::RSAPrivateKey<>> parse_jwk_rsa_private_ // We know that if any of the extra parameters are provided, all of them must be if (!jwk.p.has_value()) - return ::Crypto::PK::RSAPrivateKey<>(move(n), move(d), move(e)); + return ::Crypto::PK::RSAPrivateKey(move(n), move(d), move(e)); auto p = TRY(base64_url_uint_decode(realm, *jwk.p)); auto q = TRY(base64_url_uint_decode(realm, *jwk.q)); @@ -249,15 +249,15 @@ static WebIDL::ExceptionOr<::Crypto::PK::RSAPrivateKey<>> parse_jwk_rsa_private_ auto dq = TRY(base64_url_uint_decode(realm, *jwk.dq)); auto qi = TRY(base64_url_uint_decode(realm, *jwk.qi)); - return ::Crypto::PK::RSAPrivateKey<>(move(n), move(d), move(e), move(p), move(q), move(dp), move(dq), move(qi)); + return ::Crypto::PK::RSAPrivateKey(move(n), move(d), move(e), move(p), move(q), move(dp), move(dq), move(qi)); } -static WebIDL::ExceptionOr<::Crypto::PK::RSAPublicKey<>> parse_jwk_rsa_public_key(JS::Realm& realm, Bindings::JsonWebKey const& jwk) +static WebIDL::ExceptionOr<::Crypto::PK::RSAPublicKey> parse_jwk_rsa_public_key(JS::Realm& realm, Bindings::JsonWebKey const& jwk) { auto e = TRY(base64_url_uint_decode(realm, *jwk.e)); auto n = TRY(base64_url_uint_decode(realm, *jwk.n)); - return ::Crypto::PK::RSAPublicKey<>(move(n), move(e)); + return ::Crypto::PK::RSAPublicKey(move(n), move(e)); } static WebIDL::ExceptionOr parse_jwk_symmetric_key(JS::Realm& realm, Bindings::JsonWebKey const& jwk) @@ -667,7 +667,7 @@ WebIDL::ExceptionOr> RSAOAEP::encrypt(AlgorithmParams c auto const& label = normalized_algorithm.label; auto const& handle = key->handle(); - auto public_key = handle.get<::Crypto::PK::RSAPublicKey<>>(); + auto public_key = handle.get<::Crypto::PK::RSAPublicKey>(); auto hash = TRY(as(*key->algorithm()).hash().name(vm)); // 3. Perform the encryption operation defined in Section 7.1 of [RFC3447] with the key represented by key as the recipient's RSA public key, @@ -716,7 +716,7 @@ WebIDL::ExceptionOr> RSAOAEP::decrypt(AlgorithmParams c auto const& label = normalized_algorithm.label; auto const& handle = key->handle(); - auto private_key = handle.get<::Crypto::PK::RSAPrivateKey<>>(); + auto private_key = handle.get<::Crypto::PK::RSAPrivateKey>(); auto hash = TRY(as(*key->algorithm()).hash().name(vm)); // 3. Perform the decryption operation defined in Section 7.1 of [RFC3447] with the key represented by key as the recipient's RSA private key, @@ -1055,12 +1055,12 @@ WebIDL::ExceptionOr> RSAOAEP::import_key(Web::Crypto::Algorit // 5. Set the modulusLength attribute of algorithm to the length, in bits, of the RSA public modulus. // 6. Set the publicExponent attribute of algorithm to the BigInteger representation of the RSA public exponent. TRY(key->handle().visit( - [&](::Crypto::PK::RSAPublicKey<> const& public_key) -> WebIDL::ExceptionOr { + [&](::Crypto::PK::RSAPublicKey const& public_key) -> WebIDL::ExceptionOr { algorithm->set_modulus_length(public_key.modulus().byte_length() * 8); TRY(algorithm->set_public_exponent(public_key.public_exponent())); return {}; }, - [&](::Crypto::PK::RSAPrivateKey<> const& private_key) -> WebIDL::ExceptionOr { + [&](::Crypto::PK::RSAPrivateKey const& private_key) -> WebIDL::ExceptionOr { algorithm->set_modulus_length(private_key.modulus().byte_length() * 8); TRY(algorithm->set_public_exponent(private_key.public_exponent())); return {}; @@ -1104,7 +1104,7 @@ WebIDL::ExceptionOr> RSAOAEP::export_key(Bindings::KeyFormat // - 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 auto maybe_data = handle.visit( - [&](::Crypto::PK::RSAPublicKey<> const& public_key) -> ErrorOr { + [&](::Crypto::PK::RSAPublicKey const& public_key) -> ErrorOr { return TRY(::Crypto::PK::wrap_in_subject_public_key_info(public_key, ::Crypto::ASN1::rsa_encryption_oid, nullptr)); }, [](auto) -> ErrorOr { @@ -1131,7 +1131,7 @@ WebIDL::ExceptionOr> RSAOAEP::export_key(Bindings::KeyFormat // - Set the privateKey field to the result of DER-encoding an RSAPrivateKey ASN.1 type, as defined in [RFC3447], Appendix A.1.2, // that represents the RSA private key represented by the [[handle]] internal slot of key auto maybe_data = handle.visit( - [&](::Crypto::PK::RSAPrivateKey<> const& private_key) -> ErrorOr { + [&](::Crypto::PK::RSAPrivateKey const& private_key) -> ErrorOr { return TRY(::Crypto::PK::wrap_in_private_key_info(private_key, ::Crypto::ASN1::rsa_encryption_oid, nullptr)); }, [](auto) -> ErrorOr { @@ -1185,12 +1185,12 @@ WebIDL::ExceptionOr> RSAOAEP::export_key(Bindings::KeyFormat // 10. Set the attributes n and e of jwk according to the corresponding definitions in JSON Web Algorithms [JWA], Section 6.3.1. auto maybe_error = handle.visit( - [&](::Crypto::PK::RSAPublicKey<> const& public_key) -> ErrorOr { + [&](::Crypto::PK::RSAPublicKey const& public_key) -> ErrorOr { jwk.n = TRY(base64_url_uint_encode(public_key.modulus())); jwk.e = TRY(base64_url_uint_encode(public_key.public_exponent())); return {}; }, - [&](::Crypto::PK::RSAPrivateKey<> const& private_key) -> ErrorOr { + [&](::Crypto::PK::RSAPrivateKey const& private_key) -> ErrorOr { jwk.n = TRY(base64_url_uint_encode(private_key.modulus())); jwk.e = TRY(base64_url_uint_encode(private_key.public_exponent())); @@ -1319,7 +1319,7 @@ WebIDL::ExceptionOr> RSAPSS::sign(AlgorithmParams const if (key->type() != Bindings::KeyType::Private) return WebIDL::InvalidAccessError::create(realm, "Key is not a private key"_string); - auto const& private_key = key->handle().get<::Crypto::PK::RSAPrivateKey<>>(); + auto const& private_key = key->handle().get<::Crypto::PK::RSAPrivateKey>(); auto pss_params = static_cast(params); auto hash = TRY(as(*key->algorithm()).hash().name(vm)); @@ -1365,7 +1365,7 @@ WebIDL::ExceptionOr RSAPSS::verify(AlgorithmParams const& params, GC: if (key->type() != Bindings::KeyType::Public) return WebIDL::InvalidAccessError::create(realm, "Key is not a public key"_string); - auto const& public_key = key->handle().get<::Crypto::PK::RSAPublicKey<>>(); + auto const& public_key = key->handle().get<::Crypto::PK::RSAPublicKey>(); auto pss_params = static_cast(params); auto hash = TRY(as(*key->algorithm()).hash().name(vm)); @@ -1633,12 +1633,12 @@ WebIDL::ExceptionOr> RSAPSS::import_key(AlgorithmParams const // 5. Set the modulusLength attribute of algorithm to the length, in bits, of the RSA public modulus. // 6. Set the publicExponent attribute of algorithm to the BigInteger representation of the RSA public exponent. TRY(key->handle().visit( - [&](::Crypto::PK::RSAPublicKey<> const& public_key) -> WebIDL::ExceptionOr { + [&](::Crypto::PK::RSAPublicKey const& public_key) -> WebIDL::ExceptionOr { algorithm->set_modulus_length(public_key.modulus().byte_length() * 8); TRY(algorithm->set_public_exponent(public_key.public_exponent())); return {}; }, - [&](::Crypto::PK::RSAPrivateKey<> const& private_key) -> WebIDL::ExceptionOr { + [&](::Crypto::PK::RSAPrivateKey const& private_key) -> WebIDL::ExceptionOr { algorithm->set_modulus_length(private_key.modulus().byte_length() * 8); TRY(algorithm->set_public_exponent(private_key.public_exponent())); return {}; @@ -1682,7 +1682,7 @@ WebIDL::ExceptionOr> RSAPSS::export_key(Bindings::KeyFormat // - 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 auto maybe_data = handle.visit( - [&](::Crypto::PK::RSAPublicKey<> const& public_key) -> ErrorOr { + [&](::Crypto::PK::RSAPublicKey const& public_key) -> ErrorOr { return TRY(::Crypto::PK::wrap_in_subject_public_key_info(public_key, ::Crypto::ASN1::rsa_encryption_oid, nullptr)); }, [](auto) -> ErrorOr { @@ -1709,7 +1709,7 @@ WebIDL::ExceptionOr> RSAPSS::export_key(Bindings::KeyFormat // - Set the privateKey field to the result of DER-encoding an RSAPrivateKey ASN.1 type, as defined in [RFC3447], Appendix A.1.2, // that represents the RSA private key represented by the [[handle]] internal slot of key auto maybe_data = handle.visit( - [&](::Crypto::PK::RSAPrivateKey<> const& private_key) -> ErrorOr { + [&](::Crypto::PK::RSAPrivateKey const& private_key) -> ErrorOr { return TRY(::Crypto::PK::wrap_in_private_key_info(private_key, ::Crypto::ASN1::rsa_encryption_oid, nullptr)); }, [](auto) -> ErrorOr { @@ -1763,13 +1763,13 @@ WebIDL::ExceptionOr> RSAPSS::export_key(Bindings::KeyFormat // 5. Set the attributes n and e of jwk according to the corresponding definitions in JSON Web Algorithms [JWA], Section 6.3.1. auto maybe_error = handle.visit( - [&](::Crypto::PK::RSAPublicKey<> const& public_key) -> ErrorOr { + [&](::Crypto::PK::RSAPublicKey const& public_key) -> ErrorOr { jwk.n = TRY(base64_url_uint_encode(public_key.modulus())); jwk.e = TRY(base64_url_uint_encode(public_key.public_exponent())); return {}; }, // 6. If the [[type]] internal slot of key is "private": - [&](::Crypto::PK::RSAPrivateKey<> const& private_key) -> ErrorOr { + [&](::Crypto::PK::RSAPrivateKey const& private_key) -> ErrorOr { jwk.n = TRY(base64_url_uint_encode(private_key.modulus())); jwk.e = TRY(base64_url_uint_encode(private_key.public_exponent())); @@ -1898,7 +1898,7 @@ WebIDL::ExceptionOr> RSASSAPKCS1::sign(AlgorithmParams if (key->type() != Bindings::KeyType::Private) return WebIDL::InvalidAccessError::create(realm, "Key is not a private key"_string); - auto const& private_key = key->handle().get<::Crypto::PK::RSAPrivateKey<>>(); + auto const& private_key = key->handle().get<::Crypto::PK::RSAPrivateKey>(); auto hash = TRY(as(*key->algorithm()).hash().name(vm)); // 3. Perform the signature generation operation defined in Section 8.2 of [RFC3447] with the key represented by the [[handle]] internal slot @@ -1941,7 +1941,7 @@ WebIDL::ExceptionOr RSASSAPKCS1::verify(AlgorithmParams const&, GC::R if (key->type() != Bindings::KeyType::Public) return WebIDL::InvalidAccessError::create(realm, "Key is not a public key"_string); - auto const& public_key = key->handle().get<::Crypto::PK::RSAPublicKey<>>(); + auto const& public_key = key->handle().get<::Crypto::PK::RSAPublicKey>(); auto hash = TRY(as(*key->algorithm()).hash().name(vm)); // 2. Perform the signature verification operation defined in Section 8.2 of [RFC3447] with the key represented by the [[handle]] internal slot @@ -2204,12 +2204,12 @@ WebIDL::ExceptionOr> RSASSAPKCS1::import_key(AlgorithmParams // 5. Set the modulusLength attribute of algorithm to the length, in bits, of the RSA public modulus. // 6. Set the publicExponent attribute of algorithm to the BigInteger representation of the RSA public exponent. TRY(key->handle().visit( - [&](::Crypto::PK::RSAPublicKey<> const& public_key) -> WebIDL::ExceptionOr { + [&](::Crypto::PK::RSAPublicKey const& public_key) -> WebIDL::ExceptionOr { algorithm->set_modulus_length(public_key.modulus().byte_length() * 8); TRY(algorithm->set_public_exponent(public_key.public_exponent())); return {}; }, - [&](::Crypto::PK::RSAPrivateKey<> const& private_key) -> WebIDL::ExceptionOr { + [&](::Crypto::PK::RSAPrivateKey const& private_key) -> WebIDL::ExceptionOr { algorithm->set_modulus_length(private_key.modulus().byte_length() * 8); TRY(algorithm->set_public_exponent(private_key.public_exponent())); return {}; @@ -2253,7 +2253,7 @@ WebIDL::ExceptionOr> RSASSAPKCS1::export_key(Bindings::KeyFo // - 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 auto maybe_data = handle.visit( - [&](::Crypto::PK::RSAPublicKey<> const& public_key) -> ErrorOr { + [&](::Crypto::PK::RSAPublicKey const& public_key) -> ErrorOr { return TRY(::Crypto::PK::wrap_in_subject_public_key_info(public_key, ::Crypto::ASN1::rsa_encryption_oid, nullptr)); }, [](auto) -> ErrorOr { @@ -2280,7 +2280,7 @@ WebIDL::ExceptionOr> RSASSAPKCS1::export_key(Bindings::KeyFo // - Set the privateKey field to the result of DER-encoding an RSAPrivateKey ASN.1 type, as defined in [RFC3447], Appendix A.1.2, // that represents the RSA private key represented by the [[handle]] internal slot of key auto maybe_data = handle.visit( - [&](::Crypto::PK::RSAPrivateKey<> const& private_key) -> ErrorOr { + [&](::Crypto::PK::RSAPrivateKey const& private_key) -> ErrorOr { return TRY(::Crypto::PK::wrap_in_private_key_info(private_key, ::Crypto::ASN1::rsa_encryption_oid, nullptr)); }, [](auto) -> ErrorOr { @@ -2334,13 +2334,13 @@ WebIDL::ExceptionOr> RSASSAPKCS1::export_key(Bindings::KeyFo // 5. Set the attributes n and e of jwk according to the corresponding definitions in JSON Web Algorithms [JWA], Section 6.3.1. auto maybe_error = handle.visit( - [&](::Crypto::PK::RSAPublicKey<> const& public_key) -> ErrorOr { + [&](::Crypto::PK::RSAPublicKey const& public_key) -> ErrorOr { jwk.n = TRY(base64_url_uint_encode(public_key.modulus())); jwk.e = TRY(base64_url_uint_encode(public_key.public_exponent())); return {}; }, // 6. If the [[type]] internal slot of key is "private": - [&](::Crypto::PK::RSAPrivateKey<> const& private_key) -> ErrorOr { + [&](::Crypto::PK::RSAPrivateKey const& private_key) -> ErrorOr { jwk.n = TRY(base64_url_uint_encode(private_key.modulus())); jwk.e = TRY(base64_url_uint_encode(private_key.public_exponent())); @@ -3741,7 +3741,7 @@ WebIDL::ExceptionOr, GC::Ref>> ECDSA:: return WebIDL::OperationError::create(m_realm, "Failed to create valid crypto instance"_string); auto public_key_data = maybe_public_key_data.release_value(); - auto ec_public_key = ::Crypto::PK::ECPublicKey<> { public_key_data }; + auto ec_public_key = ::Crypto::PK::ECPublicKey { public_key_data }; // 7. Let algorithm be a new EcKeyAlgorithm object. auto algorithm = EcKeyAlgorithm::create(m_realm); @@ -3768,7 +3768,7 @@ WebIDL::ExceptionOr, GC::Ref>> ECDSA:: public_key->set_usages(usage_intersection(key_usages, { { Bindings::KeyUsage::Verify } })); // 15. Let privateKey be a new CryptoKey representing the private key of the generated key pair. - auto ec_private_key = ::Crypto::PK::ECPrivateKey<> { private_key_data, public_key_data.size, {}, ec_public_key }; + auto ec_private_key = ::Crypto::PK::ECPrivateKey { private_key_data, public_key_data.size, {}, ec_public_key }; auto private_key = CryptoKey::create(m_realm, CryptoKey::InternalKeyData { ec_private_key }); // 16. Set the [[type]] internal slot of privateKey to "private" @@ -3824,7 +3824,7 @@ WebIDL::ExceptionOr> ECDSA::sign(AlgorithmParams const& auto M = TRY_OR_THROW_OOM(vm, ByteBuffer::copy(digest.immutable_data(), hash.digest_size())); // 4. Let d be the ECDSA private key associated with key. - auto d = key->handle().get<::Crypto::PK::ECPrivateKey<>>(); + auto d = key->handle().get<::Crypto::PK::ECPrivateKey>(); // FIXME: 5. Let params be the EC domain parameters associated with key. @@ -3920,7 +3920,7 @@ WebIDL::ExceptionOr ECDSA::verify(AlgorithmParams const& params, GC:: auto M = TRY_OR_THROW_OOM(realm.vm(), ByteBuffer::copy(digest.immutable_data(), hash.digest_size())); // 4. Let Q be the ECDSA public key associated with key. - auto Q = key->handle().get<::Crypto::PK::ECPublicKey<>>(); + auto Q = key->handle().get<::Crypto::PK::ECPublicKey>(); // FIXME: 5. Let params be the EC domain parameters associated with key. @@ -4063,7 +4063,7 @@ WebIDL::ExceptionOr> ECDSA::import_key(AlgorithmParams const& TRY(curve.visit([&](auto& instance) -> WebIDL::ExceptionOr { auto maybe_valid = key->handle().visit( [](auto const&) -> ErrorOr { VERIFY_NOT_REACHED(); }, - [&](::Crypto::PK::ECPublicKey<> const& public_key) { + [&](::Crypto::PK::ECPublicKey const& public_key) { return instance.is_valid_point(public_key.to_secpxxxr1_point()); }); if (maybe_valid.is_error()) @@ -4181,7 +4181,7 @@ WebIDL::ExceptionOr> ECDSA::import_key(AlgorithmParams const& TRY(curve.visit([&](auto& instance) -> WebIDL::ExceptionOr { auto maybe_valid = key->handle().visit( [](auto const&) -> ErrorOr { VERIFY_NOT_REACHED(); }, - [&](::Crypto::PK::ECPrivateKey<> const& private_key) -> ErrorOr { + [&](::Crypto::PK::ECPrivateKey const& private_key) -> ErrorOr { if (!private_key.public_key().has_value()) return true; @@ -4320,7 +4320,7 @@ WebIDL::ExceptionOr> ECDSA::import_key(AlgorithmParams const& if (y_bytes.size() != coord_size) return WebIDL::DataError::create(m_realm, "Invalid key size"_string); - auto public_key = ::Crypto::PK::ECPublicKey<> { + auto public_key = ::Crypto::PK::ECPublicKey { ::Crypto::UnsignedBigInteger::import_data(x_bytes), ::Crypto::UnsignedBigInteger::import_data(y_bytes), coord_size, @@ -4339,7 +4339,7 @@ WebIDL::ExceptionOr> ECDSA::import_key(AlgorithmParams const& // 2. Let key be a new CryptoKey object that represents the Elliptic Curve private key identified // by interpreting jwk according to Section 6.2.2 of JSON Web Algorithms [JWA]. - auto private_key = ::Crypto::PK::ECPrivateKey<> { + auto private_key = ::Crypto::PK::ECPrivateKey { ::Crypto::UnsignedBigInteger::import_data(d_bytes), coord_size, {}, @@ -4381,10 +4381,10 @@ WebIDL::ExceptionOr> ECDSA::import_key(AlgorithmParams const& TRY(curve.visit([&](auto& instance) -> WebIDL::ExceptionOr { auto maybe_valid = key->handle().visit( [](auto const&) -> ErrorOr { VERIFY_NOT_REACHED(); }, - [&](::Crypto::PK::ECPublicKey<> const& public_key) { + [&](::Crypto::PK::ECPublicKey const& public_key) { return instance.is_valid_point(public_key.to_secpxxxr1_point()); }, - [&](::Crypto::PK::ECPrivateKey<> const& private_key) { + [&](::Crypto::PK::ECPrivateKey const& private_key) { return instance.is_valid_point(private_key.public_key()->to_secpxxxr1_point(), private_key.d()); }); if (maybe_valid.is_error()) @@ -4507,7 +4507,7 @@ WebIDL::ExceptionOr> ECDSA::export_key(Bindings::KeyFormat f // Set parameters to the namedCurve choice with value equal to the object identifier secp521r1 defined in [RFC5480] // NOTE: everything above happens in wrap_in_subject_public_key_info auto maybe_data = handle.visit( - [&](::Crypto::PK::ECPublicKey<> const& public_key) -> ErrorOr { + [&](::Crypto::PK::ECPublicKey const& public_key) -> ErrorOr { auto public_key_bytes = TRY(public_key.to_uncompressed()); Span ec_params; @@ -4576,7 +4576,7 @@ WebIDL::ExceptionOr> ECDSA::export_key(Bindings::KeyFormat f // Set parameters to the namedCurve choice with value equal to the object identifier secp521r1 defined in [RFC5480] // NOTE: everything above happens in wrap_in_private_key_info auto maybe_data = handle.visit( - [&](::Crypto::PK::ECPrivateKey<> const& private_key) -> ErrorOr { + [&](::Crypto::PK::ECPrivateKey const& private_key) -> ErrorOr { Span ec_params; if (algorithm.named_curve() == "P-256"sv) ec_params = ::Crypto::ASN1::secp256r1_oid; @@ -4638,7 +4638,7 @@ WebIDL::ExceptionOr> ECDSA::export_key(Bindings::KeyFormat f } auto maybe_error = handle.visit( - [&](::Crypto::PK::ECPublicKey<> const& public_key) -> ErrorOr { + [&](::Crypto::PK::ECPublicKey const& public_key) -> ErrorOr { // 2. Set the x attribute of jwk according to the definition in Section 6.2.1.2 of JSON Web Algorithms [JWA]. auto x_bytes = TRY(public_key.x_bytes()); jwk.x = TRY(encode_base64url(x_bytes, AK::OmitPadding::Yes)); @@ -4649,7 +4649,7 @@ WebIDL::ExceptionOr> ECDSA::export_key(Bindings::KeyFormat f return {}; }, - [&](::Crypto::PK::ECPrivateKey<> const& private_key) -> ErrorOr { + [&](::Crypto::PK::ECPrivateKey const& private_key) -> ErrorOr { Variant curve; if (algorithm.named_curve() == "P-256"sv) curve = ::Crypto::Curves::SECP256r1 {}; @@ -4686,7 +4686,7 @@ WebIDL::ExceptionOr> ECDSA::export_key(Bindings::KeyFormat f // 4. If the [[type]] internal slot of key is "private" if (key->type() == Bindings::KeyType::Private) { auto maybe_error = handle.visit( - [&](::Crypto::PK::ECPrivateKey<> const& private_key) -> ErrorOr { + [&](::Crypto::PK::ECPrivateKey const& private_key) -> ErrorOr { // Set the d attribute of jwk according to the definition in Section 6.2.2.1 of JSON Web Algorithms [JWA]. auto d_bytes = TRY(private_key.d_bytes()); jwk.d = TRY(encode_base64url(d_bytes, AK::OmitPadding::Yes)); @@ -4737,7 +4737,7 @@ WebIDL::ExceptionOr> ECDSA::export_key(Bindings::KeyFormat f // Let data be an octet string representing the Elliptic Curve point Q represented by [[handle]] internal slot // of key according to [SEC1] 2.3.3 using the uncompressed format. auto maybe_data = handle.visit( - [](::Crypto::PK::ECPublicKey<> const& public_key) -> ErrorOr { + [](::Crypto::PK::ECPublicKey const& public_key) -> ErrorOr { return public_key.to_uncompressed(); }, [](auto) -> ErrorOr { @@ -4822,7 +4822,7 @@ WebIDL::ExceptionOr, GC::Ref>> ECDH::g return WebIDL::OperationError::create(m_realm, "Failed to create valid crypto instance"_string); auto public_key_data = maybe_public_key_data.release_value(); - auto ec_public_key = ::Crypto::PK::ECPublicKey<> { public_key_data }; + auto ec_public_key = ::Crypto::PK::ECPublicKey { public_key_data }; // 4. Let algorithm be a new EcKeyAlgorithm object. auto algorithm = EcKeyAlgorithm::create(m_realm); @@ -4849,7 +4849,7 @@ WebIDL::ExceptionOr, GC::Ref>> ECDH::g public_key->set_usages({}); // 12. Let privateKey be a new CryptoKey representing the private key of the generated key pair. - auto ec_private_key = ::Crypto::PK::ECPrivateKey<> { private_key_data, public_key_data.size, {}, ec_public_key }; + auto ec_private_key = ::Crypto::PK::ECPrivateKey { private_key_data, public_key_data.size, {}, ec_public_key }; auto private_key = CryptoKey::create(m_realm, CryptoKey::InternalKeyData { ec_private_key }); // 13. Set the [[type]] internal slot of privateKey to "private" @@ -4911,8 +4911,8 @@ WebIDL::ExceptionOr> ECDH::derive_bits(AlgorithmParams // by the [[handle]] internal slot of publicKey as the EC public key. // 2. Let secret be the result of applying the field element to octet string conversion // defined in Section 6.2 of [RFC6090] to the output of the ECDH primitive. - auto private_key_data = key->handle().get<::Crypto::PK::ECPrivateKey<>>(); - auto public_key_data = public_key->handle().get<::Crypto::PK::ECPublicKey<>>(); + auto private_key_data = key->handle().get<::Crypto::PK::ECPrivateKey>(); + auto public_key_data = public_key->handle().get<::Crypto::PK::ECPublicKey>(); Variant curve; if (internal_algorithm.named_curve() == "P-256"sv) @@ -5066,7 +5066,7 @@ WebIDL::ExceptionOr> ECDH::import_key(AlgorithmParams const& TRY(curve.visit([&](auto& instance) -> WebIDL::ExceptionOr { auto maybe_valid = key->handle().visit( [](auto const&) -> ErrorOr { VERIFY_NOT_REACHED(); }, - [&](::Crypto::PK::ECPublicKey<> const& public_key) { + [&](::Crypto::PK::ECPublicKey const& public_key) { return instance.is_valid_point(public_key.to_secpxxxr1_point()); }); if (maybe_valid.is_error()) @@ -5184,7 +5184,7 @@ WebIDL::ExceptionOr> ECDH::import_key(AlgorithmParams const& TRY(curve.visit([&](auto& instance) -> WebIDL::ExceptionOr { auto maybe_valid = key->handle().visit( [](auto const&) -> ErrorOr { VERIFY_NOT_REACHED(); }, - [&](::Crypto::PK::ECPrivateKey<> const& private_key) -> ErrorOr { + [&](::Crypto::PK::ECPrivateKey const& private_key) -> ErrorOr { if (!private_key.public_key().has_value()) return true; @@ -5292,7 +5292,7 @@ WebIDL::ExceptionOr> ECDH::import_key(AlgorithmParams const& if (y_bytes.size() != coord_size) return WebIDL::DataError::create(m_realm, "Invalid key size"_string); - auto public_key = ::Crypto::PK::ECPublicKey<> { + auto public_key = ::Crypto::PK::ECPublicKey { ::Crypto::UnsignedBigInteger::import_data(x_bytes), ::Crypto::UnsignedBigInteger::import_data(y_bytes), coord_size, @@ -5311,7 +5311,7 @@ WebIDL::ExceptionOr> ECDH::import_key(AlgorithmParams const& // 2. Let key be a new CryptoKey object that represents the Elliptic Curve private key identified // by interpreting jwk according to Section 6.2.2 of JSON Web Algorithms [JWA]. - auto private_key = ::Crypto::PK::ECPrivateKey<> { + auto private_key = ::Crypto::PK::ECPrivateKey { ::Crypto::UnsignedBigInteger::import_data(d_bytes), coord_size, {}, @@ -5353,10 +5353,10 @@ WebIDL::ExceptionOr> ECDH::import_key(AlgorithmParams const& TRY(curve.visit([&](auto& instance) -> WebIDL::ExceptionOr { auto maybe_valid = key->handle().visit( [](auto const&) -> ErrorOr { VERIFY_NOT_REACHED(); }, - [&](::Crypto::PK::ECPublicKey<> const& public_key) { + [&](::Crypto::PK::ECPublicKey const& public_key) { return instance.is_valid_point(public_key.to_secpxxxr1_point()); }, - [&](::Crypto::PK::ECPrivateKey<> const& private_key) { + [&](::Crypto::PK::ECPrivateKey const& private_key) { return instance.is_valid_point(private_key.public_key()->to_secpxxxr1_point(), private_key.d()); }); if (maybe_valid.is_error()) @@ -5470,7 +5470,7 @@ WebIDL::ExceptionOr> ECDH::export_key(Bindings::KeyFormat fo // Set parameters to the namedCurve choice with value equal to the object identifier secp521r1 defined in [RFC5480] // NOTE: everything above happens in wrap_in_subject_public_key_info auto maybe_data = handle.visit( - [&](::Crypto::PK::ECPublicKey<> const& public_key) -> ErrorOr { + [&](::Crypto::PK::ECPublicKey const& public_key) -> ErrorOr { auto public_key_bytes = TRY(public_key.to_uncompressed()); Span ec_params; @@ -5539,7 +5539,7 @@ WebIDL::ExceptionOr> ECDH::export_key(Bindings::KeyFormat fo // Set parameters to the namedCurve choice with value equal to the object identifier secp521r1 defined in [RFC5480] // NOTE: everything above happens in wrap_in_private_key_info auto maybe_data = handle.visit( - [&](::Crypto::PK::ECPrivateKey<> const& private_key) -> ErrorOr { + [&](::Crypto::PK::ECPrivateKey const& private_key) -> ErrorOr { Span ec_params; if (algorithm.named_curve() == "P-256"sv) ec_params = ::Crypto::ASN1::secp256r1_oid; @@ -5601,7 +5601,7 @@ WebIDL::ExceptionOr> ECDH::export_key(Bindings::KeyFormat fo } auto maybe_error = handle.visit( - [&](::Crypto::PK::ECPublicKey<> const& public_key) -> ErrorOr { + [&](::Crypto::PK::ECPublicKey const& public_key) -> ErrorOr { // 2. Set the x attribute of jwk according to the definition in Section 6.2.1.2 of JSON Web Algorithms [JWA]. auto x_bytes = TRY(public_key.x_bytes()); jwk.x = TRY(encode_base64url(x_bytes, AK::OmitPadding::Yes)); @@ -5612,7 +5612,7 @@ WebIDL::ExceptionOr> ECDH::export_key(Bindings::KeyFormat fo return {}; }, - [&](::Crypto::PK::ECPrivateKey<> const& private_key) -> ErrorOr { + [&](::Crypto::PK::ECPrivateKey const& private_key) -> ErrorOr { Variant curve; if (algorithm.named_curve() == "P-256"sv) curve = ::Crypto::Curves::SECP256r1 {}; @@ -5649,7 +5649,7 @@ WebIDL::ExceptionOr> ECDH::export_key(Bindings::KeyFormat fo // 4. If the [[type]] internal slot of key is "private" if (key->type() == Bindings::KeyType::Private) { auto maybe_error = handle.visit( - [&](::Crypto::PK::ECPrivateKey<> const& private_key) -> ErrorOr { + [&](::Crypto::PK::ECPrivateKey const& private_key) -> ErrorOr { // Set the d attribute of jwk according to the definition in Section 6.2.2.1 of JSON Web Algorithms [JWA]. auto d_bytes = TRY(private_key.d_bytes()); jwk.d = TRY(encode_base64url(d_bytes, AK::OmitPadding::Yes)); @@ -5700,7 +5700,7 @@ WebIDL::ExceptionOr> ECDH::export_key(Bindings::KeyFormat fo // Let data be the octet string that represents the Elliptic Curve public key represented by the [[handle]] internal slot // of key according to the encoding rules specified in Section 2.3.3 of [SEC1] and using the uncompressed form. auto maybe_data = handle.visit( - [](::Crypto::PK::ECPublicKey<> const& public_key) -> ErrorOr { + [](::Crypto::PK::ECPublicKey const& public_key) -> ErrorOr { return public_key.to_uncompressed(); }, [](auto) -> ErrorOr { diff --git a/Libraries/LibWeb/Crypto/CryptoKey.h b/Libraries/LibWeb/Crypto/CryptoKey.h index a6fdd1d405a..464a6410219 100644 --- a/Libraries/LibWeb/Crypto/CryptoKey.h +++ b/Libraries/LibWeb/Crypto/CryptoKey.h @@ -25,7 +25,7 @@ class CryptoKey final GC_DECLARE_ALLOCATOR(CryptoKey); public: - using InternalKeyData = Variant, ::Crypto::PK::RSAPrivateKey<>, ::Crypto::PK::ECPublicKey<>, ::Crypto::PK::ECPrivateKey<>>; + using InternalKeyData = Variant; [[nodiscard]] static GC::Ref create(JS::Realm&, InternalKeyData); [[nodiscard]] static GC::Ref create(JS::Realm&); diff --git a/Tests/LibCrypto/TestRSA.cpp b/Tests/LibCrypto/TestRSA.cpp index 7150cc713e8..0d2b1c36b9f 100644 --- a/Tests/LibCrypto/TestRSA.cpp +++ b/Tests/LibCrypto/TestRSA.cpp @@ -22,7 +22,7 @@ TEST_CASE(test_RSA_raw_encrypt) { ByteBuffer data { "hellohellohellohellohellohellohellohellohellohellohellohello123-"_b }; u8 result[] { 0x6f, 0x7b, 0xe2, 0xd3, 0x95, 0xf8, 0x8d, 0x87, 0x6d, 0x10, 0x5e, 0xc3, 0xcd, 0xf7, 0xbb, 0xa6, 0x62, 0x8e, 0x45, 0xa0, 0xf1, 0xe5, 0x0f, 0xdf, 0x69, 0xcb, 0xb6, 0xd5, 0x42, 0x06, 0x7d, 0x72, 0xa9, 0x5e, 0xae, 0xbf, 0xbf, 0x0f, 0xe0, 0xeb, 0x31, 0x31, 0xca, 0x8a, 0x81, 0x1e, 0xb9, 0xec, 0x6d, 0xcc, 0xb8, 0xa4, 0xac, 0xa3, 0x31, 0x05, 0xa9, 0xac, 0xc9, 0xd3, 0xe6, 0x2a, 0x18, 0xfe }; - Crypto::PK::RSA rsa(Crypto::PK::RSAPublicKey<> { + Crypto::PK::RSA rsa(Crypto::PK::RSAPublicKey { "8126832723025844890518845777858816391166654950553329127845898924164623511718747856014227624997335860970996746552094406240834082304784428582653994490504519"_bigint, "65537"_bigint, });