From 2fa79d7c34f8dd1d85fb83b25cf872d5f9ad8677 Mon Sep 17 00:00:00 2001 From: devgianlu Date: Tue, 24 Dec 2024 16:23:49 +0100 Subject: [PATCH] tmp --- Libraries/LibCrypto/PK/Code/Code.h | 35 ----- Libraries/LibCrypto/PK/Code/EMSA_PKCS1_V1_5.h | 136 ------------------ Libraries/LibCrypto/PK/PK.h | 4 +- Libraries/LibCrypto/PK/RSA.cpp | 127 +++++++--------- Libraries/LibCrypto/PK/RSA.h | 92 ++++++++++-- Libraries/LibTLS/HandshakeServer.cpp | 20 +-- Libraries/LibTLS/TLSv12.cpp | 19 +-- Tests/LibCrypto/TestRSA.cpp | 21 +++ 8 files changed, 165 insertions(+), 289 deletions(-) delete mode 100644 Libraries/LibCrypto/PK/Code/Code.h delete mode 100644 Libraries/LibCrypto/PK/Code/EMSA_PKCS1_V1_5.h diff --git a/Libraries/LibCrypto/PK/Code/Code.h b/Libraries/LibCrypto/PK/Code/Code.h deleted file mode 100644 index e720d37b4ebbd..0000000000000 --- a/Libraries/LibCrypto/PK/Code/Code.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2020, Ali Mohammad Pur - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#pragma once - -#include -#include - -namespace Crypto::PK { - -template -class Code { -public: - template - Code(Args... args) - : m_hasher(args...) - { - } - - virtual void encode(ReadonlyBytes in, ByteBuffer& out, size_t em_bits) = 0; - virtual VerificationConsistency verify(ReadonlyBytes msg, ReadonlyBytes emsg, size_t em_bits) = 0; - - HashFunction const& hasher() const { return m_hasher; } - HashFunction& hasher() { return m_hasher; } - -protected: - virtual ~Code() = default; - - HashFunction m_hasher; -}; - -} diff --git a/Libraries/LibCrypto/PK/Code/EMSA_PKCS1_V1_5.h b/Libraries/LibCrypto/PK/Code/EMSA_PKCS1_V1_5.h deleted file mode 100644 index 794652ccf01bf..0000000000000 --- a/Libraries/LibCrypto/PK/Code/EMSA_PKCS1_V1_5.h +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright (c) 2022, Michiel Visser - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#pragma once - -#include -#include -#include -#include -#include - -namespace Crypto::PK { - -template -class EMSA_PKCS1_V1_5 : public Code { -public: - template - EMSA_PKCS1_V1_5(Args... args) - : Code(args...) - { - } - - virtual void encode(ReadonlyBytes in, ByteBuffer& out, size_t em_bits) override - { - auto& hash_fn = this->hasher(); - hash_fn.update(in); - auto message_digest = hash_fn.digest(); - auto message_digest_size = message_digest.bytes().size(); - - auto digest_info = hash_function_digest_info(); - auto encoded_message_length = digest_info.size() + message_digest_size; - - auto em_bytes = (em_bits + 7) / 8; - // RFC8017 section 9.2: 3. If emLen < tLen + 11, output "intended encoded message length too short" and stop. - if (em_bytes < encoded_message_length + 11) { - dbgln("EMSA-PKCS1-V1_5-ENCODE: intended encoded message length too short"); - return; - } - - auto offset = 0; - // Build the padding 0x0001ffff..ff00 - out[offset++] = 0x00; - out[offset++] = 0x01; - for (size_t i = 0; i < em_bytes - encoded_message_length - 3; i++) - out[offset++] = 0xff; - out[offset++] = 0x00; - // Add the digest info and message digest - out.overwrite(offset, digest_info.data(), digest_info.size()); - offset += digest_info.size(); - out.overwrite(offset, message_digest.immutable_data(), message_digest.data_length()); - } - - virtual VerificationConsistency verify(ReadonlyBytes msg, ReadonlyBytes emsg, size_t em_bits) override - { - auto em_bytes = (em_bits + 7) / 8; - auto buffer_result = ByteBuffer::create_uninitialized(em_bytes); - if (buffer_result.is_error()) { - dbgln("EMSA-PKCS1-V1_5-VERIFY: out of memory"); - return VerificationConsistency::Inconsistent; - } - auto buffer = buffer_result.release_value(); - - // Encode the supplied message into the buffer - encode(msg, buffer, em_bits); - - // Check that the expected message matches the encoded original message - if (emsg != buffer) { - return VerificationConsistency::Inconsistent; - } - return VerificationConsistency::Consistent; - } - -private: - inline ReadonlyBytes hash_function_digest_info(); -}; - -template<> -inline ReadonlyBytes EMSA_PKCS1_V1_5::hash_function_digest_info() -{ - // RFC8017 section 9.2 notes 1 - return { "\x30\x20\x30\x0c\x06\x08\x2a\x86\x48\x86\xf7\x0d\x02\x05\x05\x00\x04\x10", 18 }; -} - -template<> -inline ReadonlyBytes EMSA_PKCS1_V1_5::hash_function_digest_info() -{ - // RFC8017 section 9.2 notes 1 - return { "\x30\x21\x30\x09\x06\x05\x2b\x0e\x03\x02\x1a\x05\x00\x04\x14", 15 }; -} - -template<> -inline ReadonlyBytes EMSA_PKCS1_V1_5::hash_function_digest_info() -{ - // RFC8017 section 9.2 notes 1 - return { "\x30\x31\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x01\x05\x00\x04\x20", 19 }; -} - -template<> -inline ReadonlyBytes EMSA_PKCS1_V1_5::hash_function_digest_info() -{ - // RFC8017 section 9.2 notes 1 - return { "\x30\x41\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x02\x05\x00\x04\x30", 19 }; -} - -template<> -inline ReadonlyBytes EMSA_PKCS1_V1_5::hash_function_digest_info() -{ - // RFC8017 section 9.2 notes 1 - return { "\x30\x51\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x03\x05\x00\x04\x40", 19 }; -} - -template<> -inline ReadonlyBytes EMSA_PKCS1_V1_5::hash_function_digest_info() -{ - // RFC8017 section 9.2 notes 1 - switch (hasher().kind()) { - case Hash::HashKind::MD5: - return { "\x30\x20\x30\x0c\x06\x08\x2a\x86\x48\x86\xf7\x0d\x02\x05\x05\x00\x04\x10", 18 }; - case Hash::HashKind::SHA1: - return { "\x30\x21\x30\x09\x06\x05\x2b\x0e\x03\x02\x1a\x05\x00\x04\x14", 15 }; - case Hash::HashKind::SHA256: - return { "\x30\x31\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x01\x05\x00\x04\x20", 19 }; - case Hash::HashKind::SHA384: - return { "\x30\x41\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x02\x05\x00\x04\x30", 19 }; - case Hash::HashKind::SHA512: - return { "\x30\x51\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x03\x05\x00\x04\x40", 19 }; - case Hash::HashKind::None: - default: - VERIFY_NOT_REACHED(); - } -} - -} diff --git a/Libraries/LibCrypto/PK/PK.h b/Libraries/LibCrypto/PK/PK.h index baa4ae81c83a4..9574aa9a81e21 100644 --- a/Libraries/LibCrypto/PK/PK.h +++ b/Libraries/LibCrypto/PK/PK.h @@ -235,8 +235,8 @@ class PKSystem { virtual ErrorOr encrypt(ReadonlyBytes in, Bytes& out) = 0; virtual ErrorOr decrypt(ReadonlyBytes in, Bytes& out) = 0; - virtual ErrorOr verify(ReadonlyBytes in, Bytes& out) = 0; - virtual ErrorOr sign(ReadonlyBytes in, Bytes& out) = 0; + virtual ErrorOr sign(ReadonlyBytes message, Bytes& signature) = 0; + virtual ErrorOr verify(ReadonlyBytes message, ReadonlyBytes signature) = 0; virtual ByteString class_name() const = 0; diff --git a/Libraries/LibCrypto/PK/RSA.cpp b/Libraries/LibCrypto/PK/RSA.cpp index 0f3ea342054cd..3ce4095a1ce5b 100644 --- a/Libraries/LibCrypto/PK/RSA.cpp +++ b/Libraries/LibCrypto/PK/RSA.cpp @@ -220,7 +220,7 @@ ErrorOr RSA::encrypt(ReadonlyBytes in, Bytes& out) auto ctx = TRY(OpenSSL_PKEY_CTX::wrap(EVP_PKEY_CTX_new_from_pkey(nullptr, key.ptr(), nullptr))); OPENSSL_TRY(EVP_PKEY_encrypt_init(ctx.ptr())); - OPENSSL_TRY(EVP_PKEY_CTX_set_rsa_padding(ctx.ptr(), RSA_NO_PADDING)); + TRY(configure(ctx)); size_t out_size = out.size(); OPENSSL_TRY(EVP_PKEY_encrypt(ctx.ptr(), out.data(), &out_size, in.data(), in.size())); @@ -235,7 +235,7 @@ ErrorOr RSA::decrypt(ReadonlyBytes in, Bytes& out) auto ctx = TRY(OpenSSL_PKEY_CTX::wrap(EVP_PKEY_CTX_new_from_pkey(nullptr, key.ptr(), nullptr))); OPENSSL_TRY(EVP_PKEY_decrypt_init(ctx.ptr())); - OPENSSL_TRY(EVP_PKEY_CTX_set_rsa_padding(ctx.ptr(), RSA_NO_PADDING)); + TRY(configure(ctx)); size_t out_size = out.size(); OPENSSL_TRY(EVP_PKEY_decrypt(ctx.ptr(), out.data(), &out_size, in.data(), in.size())); @@ -243,22 +243,37 @@ ErrorOr RSA::decrypt(ReadonlyBytes in, Bytes& out) return {}; } -ErrorOr RSA::sign(ReadonlyBytes in, Bytes& out) +ErrorOr RSA::sign(ReadonlyBytes message, Bytes& signature) { - auto in_integer = UnsignedBigInteger::import_data(in.data(), in.size()); - auto exp = NumberTheory::ModularPower(in_integer, m_private_key.private_exponent(), m_private_key.modulus()); - auto size = exp.export_data(out); - out = out.slice(out.size() - size, size); + auto key = TRY(private_key_to_openssl_pkey(m_private_key)); + + auto ctx = TRY(OpenSSL_PKEY_CTX::wrap(EVP_PKEY_CTX_new_from_pkey(nullptr, key.ptr(), nullptr))); + + OPENSSL_TRY(EVP_PKEY_sign_init(ctx.ptr())); + TRY(configure(ctx)); + + size_t signature_size = signature.size(); + OPENSSL_TRY(EVP_PKEY_sign(ctx.ptr(), signature.data(), &signature_size, message.data(), message.size())); + signature = signature.slice(0, signature_size); return {}; } -ErrorOr RSA::verify(ReadonlyBytes in, Bytes& out) +ErrorOr RSA::verify(ReadonlyBytes message, ReadonlyBytes signature) { - auto in_integer = UnsignedBigInteger::import_data(in.data(), in.size()); - auto exp = NumberTheory::ModularPower(in_integer, m_public_key.public_exponent(), m_public_key.modulus()); - auto size = exp.export_data(out); - out = out.slice(out.size() - size, size); - return {}; + auto key = TRY(public_key_to_openssl_pkey(m_public_key)); + + auto ctx = TRY(OpenSSL_PKEY_CTX::wrap(EVP_PKEY_CTX_new_from_pkey(nullptr, key.ptr(), nullptr))); + + OPENSSL_TRY(EVP_PKEY_verify_init(ctx.ptr())); + TRY(configure(ctx)); + + auto ret = EVP_PKEY_verify(ctx.ptr(), signature.data(), signature.size(), message.data(), message.size()); + if (ret == 1) + return true; + if (ret == 0) + return false; + OPENSSL_TRY(ret); + VERIFY_NOT_REACHED(); } void RSA::import_private_key(ReadonlyBytes bytes, bool pem) @@ -323,79 +338,45 @@ void RSA::import_public_key(ReadonlyBytes bytes, bool pem) m_public_key = maybe_key.release_value().public_key; } -ErrorOr RSA_PKCS1_EME::encrypt(ReadonlyBytes in, Bytes& out) +ErrorOr RSA_PKCS1_EMSA::verify(ReadonlyBytes message, ReadonlyBytes signature) { - auto mod_len = (m_public_key.modulus().trimmed_length() * sizeof(u32) * 8 + 7) / 8; - dbgln_if(CRYPTO_DEBUG, "key size: {}", mod_len); - if (in.size() > mod_len - 11) - return Error::from_string_literal("Message too long"); - - if (out.size() < mod_len) - return Error::from_string_literal("Output buffer too small"); - - auto ps_length = mod_len - in.size() - 3; - Vector ps; - ps.resize(ps_length); - - fill_with_random(ps); - // since fill_with_random can create zeros (shocking!) - // we have to go through and un-zero the zeros - for (size_t i = 0; i < ps_length; ++i) { - while (!ps[i]) - ps[i] = get_random(); - } + auto key = TRY(public_key_to_openssl_pkey(m_public_key)); + auto const* hash_type = TRY(this->hash_type()); - u8 paddings[] { 0x00, 0x02 }; + auto ctx = TRY(OpenSSL_MD_CTX::create()); - out.overwrite(0, paddings, 2); - out.overwrite(2, ps.data(), ps_length); - out.overwrite(2 + ps_length, paddings, 1); - out.overwrite(3 + ps_length, in.data(), in.size()); - out = out.trim(3 + ps_length + in.size()); // should be a single block + auto key_ctx = TRY(OpenSSL_PKEY_CTX::wrap(EVP_PKEY_CTX_new(key.ptr(), nullptr))); + EVP_MD_CTX_set_pkey_ctx(ctx.ptr(), key_ctx.ptr()); - dbgln_if(CRYPTO_DEBUG, "padded output size: {} buffer size: {}", 3 + ps_length + in.size(), out.size()); + OPENSSL_TRY(EVP_DigestVerifyInit(ctx.ptr(), nullptr, hash_type, nullptr, key.ptr())); + TRY(configure(key_ctx)); - TRY(RSA::encrypt(out, out)); - return {}; + auto res = EVP_DigestVerify(ctx.ptr(), signature.data(), signature.size(), message.data(), message.size()); + if (res == 1) + return true; + if (res == 0) + return false; + OPENSSL_TRY(res); + VERIFY_NOT_REACHED(); } -ErrorOr RSA_PKCS1_EME::decrypt(ReadonlyBytes in, Bytes& out) +ErrorOr RSA_PKCS1_EMSA::sign(ReadonlyBytes message, Bytes& signature) { - auto mod_len = (m_public_key.modulus().trimmed_length() * sizeof(u32) * 8 + 7) / 8; - if (in.size() != mod_len) - return Error::from_string_literal("Invalid input size"); - - TRY(RSA::decrypt(in, out)); - - if (out.size() < RSA::output_size()) - return Error::from_string_literal("Not enough data after decryption"); - - if (out[0] != 0x00 || out[1] != 0x02) - return Error::from_string_literal("Invalid padding"); - - size_t offset = 2; - while (offset < out.size() && out[offset]) - ++offset; + auto key = TRY(public_key_to_openssl_pkey(m_public_key)); + auto const* hash_type = TRY(this->hash_type()); - if (offset == out.size()) - return Error::from_string_literal("Garbage data, no zero to split padding"); + auto ctx = TRY(OpenSSL_MD_CTX::create()); - ++offset; + auto key_ctx = TRY(OpenSSL_PKEY_CTX::wrap(EVP_PKEY_CTX_new(key.ptr(), nullptr))); + EVP_MD_CTX_set_pkey_ctx(ctx.ptr(), key_ctx.ptr()); - if (offset - 3 < 8) - return Error::from_string_literal("PS too small"); + OPENSSL_TRY(EVP_DigestSignInit(ctx.ptr(), nullptr, hash_type, nullptr, key.ptr())); + TRY(configure(key_ctx)); - out = out.slice(offset, out.size() - offset); + size_t signature_size = signature.size(); + OPENSSL_TRY(EVP_DigestSign(ctx.ptr(), signature.data(), &signature_size, message.data(), message.size())); + signature = signature.slice(0, signature_size); return {}; } -ErrorOr RSA_PKCS1_EME::sign(ReadonlyBytes, Bytes&) -{ - return Error::from_string_literal("FIXME: RSA_PKCS_EME::sign"); -} - -ErrorOr RSA_PKCS1_EME::verify(ReadonlyBytes, Bytes&) -{ - return Error::from_string_literal("FIXME: RSA_PKCS_EME::verify"); -} } diff --git a/Libraries/LibCrypto/PK/RSA.h b/Libraries/LibCrypto/PK/RSA.h index e12aa46928a02..32fa8c7fe0d03 100644 --- a/Libraries/LibCrypto/PK/RSA.h +++ b/Libraries/LibCrypto/PK/RSA.h @@ -9,9 +9,11 @@ #include #include +#include #include #include #include +#include namespace Crypto::PK { @@ -199,8 +201,8 @@ class RSA : public PKSystem, RSAPublicKey encrypt(ReadonlyBytes in, Bytes& out) override; virtual ErrorOr decrypt(ReadonlyBytes in, Bytes& out) override; - virtual ErrorOr verify(ReadonlyBytes in, Bytes& out) override; - virtual ErrorOr sign(ReadonlyBytes in, Bytes& out) override; + virtual ErrorOr sign(ReadonlyBytes message, Bytes& signature) override; + virtual ErrorOr verify(ReadonlyBytes message, ReadonlyBytes signature) override; virtual ByteString class_name() const override { @@ -222,13 +224,18 @@ class RSA : public PKSystem, RSAPublicKey configure(OpenSSL_PKEY_CTX& ctx) + { + OPENSSL_TRY(EVP_PKEY_CTX_set_rsa_padding(ctx.ptr(), RSA_NO_PADDING)); + return {}; + } + static ErrorOr public_key_to_openssl_pkey(PublicKeyType const& public_key); static ErrorOr private_key_to_openssl_pkey(PrivateKeyType const& private_key); }; class RSA_PKCS1_EME : public RSA { public: - // forward all constructions to RSA template RSA_PKCS1_EME(Args... args) : RSA(args...) @@ -237,20 +244,85 @@ class RSA_PKCS1_EME : public RSA { ~RSA_PKCS1_EME() = default; - virtual ErrorOr encrypt(ReadonlyBytes in, Bytes& out) override; - virtual ErrorOr decrypt(ReadonlyBytes in, Bytes& out) override; - - virtual ErrorOr verify(ReadonlyBytes in, Bytes& out) override; - virtual ErrorOr sign(ReadonlyBytes in, Bytes& out) override; + virtual ErrorOr sign(ReadonlyBytes, Bytes&) override + { + return Error::from_string_literal("Signing is not supported with RSA_PKCS1-EME"); + } + virtual ErrorOr verify(ReadonlyBytes, ReadonlyBytes) override + { + return Error::from_string_literal("Verifying is not supported with RSA_PKCS1-EME"); + } virtual ByteString class_name() const override { return "RSA_PKCS1-EME"; } - virtual size_t output_size() const override +protected: + ErrorOr configure(OpenSSL_PKEY_CTX& ctx) override { - return m_public_key.length(); + OPENSSL_TRY(EVP_PKEY_CTX_set_rsa_padding(ctx.ptr(), RSA_PKCS1_PADDING)); + return {}; } }; + +class RSA_PKCS1_EMSA : public RSA { +public: + template + RSA_PKCS1_EMSA(Hash::HashKind hash_kind, Args... args) + : RSA(args...) + , m_hash_kind(hash_kind) + { + } + + ~RSA_PKCS1_EMSA() = default; + + virtual ErrorOr encrypt(ReadonlyBytes, Bytes&) override + { + return Error::from_string_literal("Encrypting is not supported with RSA_PKCS1-EMSA"); + } + virtual ErrorOr decrypt(ReadonlyBytes, Bytes&) override + { + return Error::from_string_literal("Decrypting is not supported with RSA_PKCS1-EMSA"); + } + + virtual ErrorOr verify(ReadonlyBytes message, ReadonlyBytes signature) override; + virtual ErrorOr sign(ReadonlyBytes message, Bytes& signature) override; + + virtual ByteString class_name() const override + { + return "RSA_PKCS1-EMSA"; + } + +protected: + ErrorOr hash_type() const + { + switch (m_hash_kind) { + case Hash::HashKind::BLAKE2b: + return EVP_blake2b512(); + case Hash::HashKind::MD5: + return EVP_md5(); + case Hash::HashKind::SHA1: + return EVP_sha1(); + case Hash::HashKind::SHA256: + return EVP_sha256(); + case Hash::HashKind::SHA384: + return EVP_sha384(); + case Hash::HashKind::SHA512: + return EVP_sha512(); + default: + return Error::from_string_literal("Unsupported hash kind"); + } + } + + ErrorOr configure(OpenSSL_PKEY_CTX& ctx) override + { + OPENSSL_TRY(EVP_PKEY_CTX_set_rsa_padding(ctx.ptr(), RSA_PKCS1_PADDING)); + return {}; + } + +private: + Hash::HashKind m_hash_kind { Hash::HashKind::Unknown }; +}; + } diff --git a/Libraries/LibTLS/HandshakeServer.cpp b/Libraries/LibTLS/HandshakeServer.cpp index cef2fe0ea1f82..79662378cc0db 100644 --- a/Libraries/LibTLS/HandshakeServer.cpp +++ b/Libraries/LibTLS/HandshakeServer.cpp @@ -16,7 +16,6 @@ #include #include #include -#include #include namespace TLS { @@ -377,18 +376,6 @@ ssize_t TLSv12::verify_rsa_server_key_exchange(ReadonlyBytes server_key_info_buf return (i8)Error::NotSafe; } // RFC5246 section 7.4.2: The sender's certificate MUST come first in the list. - auto certificate_public_key = m_context.certificates.first().public_key; - Crypto::PK::RSAPrivateKey dummy_private_key; - auto rsa = Crypto::PK::RSA(certificate_public_key.rsa, dummy_private_key); - - auto signature_verify_buffer_result = ByteBuffer::create_uninitialized(signature_length); - if (signature_verify_buffer_result.is_error()) { - dbgln("verify_rsa_server_key_exchange failed: Not enough memory"); - return (i8)Error::OutOfMemory; - } - auto signature_verify_buffer = signature_verify_buffer_result.release_value(); - auto signature_verify_bytes = signature_verify_buffer.bytes(); - MUST(rsa.verify(signature, signature_verify_bytes)); auto message_result = ByteBuffer::create_uninitialized(64 + server_key_info_buffer.size()); if (message_result.is_error()) { @@ -419,10 +406,11 @@ ssize_t TLSv12::verify_rsa_server_key_exchange(ReadonlyBytes server_key_info_buf return (i8)Error::NotUnderstood; } - auto pkcs1 = Crypto::PK::EMSA_PKCS1_V1_5(hash_kind); - auto verification = pkcs1.verify(message, signature_verify_bytes, signature_length * 8); + auto certificate_public_key = m_context.certificates.first().public_key; + auto rsa = Crypto::PK::RSA_PKCS1_EMSA(hash_kind, certificate_public_key.rsa); + auto verification = MUST(rsa.verify(message, signature)); - if (verification == Crypto::VerificationConsistency::Inconsistent) { + if (!verification) { dbgln("verify_rsa_server_key_exchange failed: Verification of signature inconsistent"); return (i8)Error::NotSafe; } diff --git a/Libraries/LibTLS/TLSv12.cpp b/Libraries/LibTLS/TLSv12.cpp index 86b196a049e51..86adfd4b6c371 100644 --- a/Libraries/LibTLS/TLSv12.cpp +++ b/Libraries/LibTLS/TLSv12.cpp @@ -18,7 +18,6 @@ #include #include #include -#include #include #include #include @@ -342,22 +341,8 @@ bool Context::verify_certificate_pair(Certificate const& subject, Certificate co } if (is_rsa) { - Crypto::PK::RSAPrivateKey dummy_private_key; - Crypto::PK::RSAPublicKey public_key_copy { issuer.public_key.rsa }; - auto rsa = Crypto::PK::RSA(public_key_copy, dummy_private_key); - auto verification_buffer_result = ByteBuffer::create_uninitialized(subject.signature_value.size()); - if (verification_buffer_result.is_error()) { - dbgln("verify_certificate_pair: Unable to allocate buffer for verification"); - return false; - } - auto verification_buffer = verification_buffer_result.release_value(); - auto verification_buffer_bytes = verification_buffer.bytes(); - MUST(rsa.verify(subject.signature_value, verification_buffer_bytes)); - - ReadonlyBytes message = subject.tbs_asn1.bytes(); - auto pkcs1 = Crypto::PK::EMSA_PKCS1_V1_5(kind); - auto verification = pkcs1.verify(message, verification_buffer_bytes, subject.signature_value.size() * 8); - return verification == Crypto::VerificationConsistency::Consistent; + auto rsa = Crypto::PK::RSA_PKCS1_EMSA(kind, issuer.public_key.rsa); + return MUST(rsa.verify(subject.tbs_asn1, subject.signature_value)); } // ECDSA hash verification: hash, then check signature against the specific curve diff --git a/Tests/LibCrypto/TestRSA.cpp b/Tests/LibCrypto/TestRSA.cpp index fba3c3879614e..916240403abcf 100644 --- a/Tests/LibCrypto/TestRSA.cpp +++ b/Tests/LibCrypto/TestRSA.cpp @@ -176,3 +176,24 @@ TEST_CASE(test_RSA_encrypt_decrypt) EXPECT(memcmp(enc.data(), "WellHelloFriendsWellHelloFriendsWellHelloFriendsWellHelloFriends", 64) == 0); } + +TEST_CASE(test_RSA_sign_verify) +{ + auto keypair = TRY_OR_FAIL(Crypto::PK::RSA::generate_key_pair(1024)); + Crypto::PK::RSA rsa(keypair); + + ByteBuffer msg_buffer = {}; + msg_buffer.resize(rsa.output_size()); + + ByteBuffer sig_buffer = {}; + sig_buffer.resize(rsa.output_size()); + + auto msg = msg_buffer.bytes(); + auto sig = sig_buffer.bytes(); + + msg.overwrite(0, "WellHelloFriendsWellHelloFriendsWellHelloFriendsWellHelloFriends", 64); + + TRY_OR_FAIL(rsa.sign(msg, sig)); + auto ok = TRY_OR_FAIL(rsa.verify(msg, sig)); + EXPECT_EQ(ok, true); +}