diff --git a/Libraries/LibCrypto/PK/RSA.cpp b/Libraries/LibCrypto/PK/RSA.cpp index f6595f46b3c..4032636b7d4 100644 --- a/Libraries/LibCrypto/PK/RSA.cpp +++ b/Libraries/LibCrypto/PK/RSA.cpp @@ -114,6 +114,28 @@ ErrorOr RSA::parse_rsa_key(ReadonlyBytes der, bool is_private, } } +ErrorOr RSA::generate_key_pair(size_t bits, IntegerType e) +{ + IntegerType p; + IntegerType q; + IntegerType lambda; + + do { + p = NumberTheory::random_big_prime(bits / 2); + q = NumberTheory::random_big_prime(bits / 2); + lambda = NumberTheory::LCM(p.minus(1), q.minus(1)); + } while (!(NumberTheory::GCD(e, lambda) == 1)); + + auto n = p.multiplied_by(q); + + auto d = NumberTheory::ModularInverse(e, lambda); + RSAKeyPair keys { + { n, e }, + { n, d, e, p, q } + }; + return keys; +} + void RSA::encrypt(ReadonlyBytes in, Bytes& out) { dbgln_if(CRYPTO_DEBUG, "in size: {}", in.size()); diff --git a/Libraries/LibCrypto/PK/RSA.h b/Libraries/LibCrypto/PK/RSA.h index c1b2aa1a4a5..81e069225f8 100644 --- a/Libraries/LibCrypto/PK/RSA.h +++ b/Libraries/LibCrypto/PK/RSA.h @@ -160,27 +160,7 @@ public: using KeyPairType = RSAKeyPair; static ErrorOr parse_rsa_key(ReadonlyBytes der, bool is_private, Vector current_scope); - static KeyPairType generate_key_pair(size_t bits = 256, IntegerType e = 65537) - { - IntegerType p; - IntegerType q; - IntegerType lambda; - - do { - p = NumberTheory::random_big_prime(bits / 2); - q = NumberTheory::random_big_prime(bits / 2); - lambda = NumberTheory::LCM(p.minus(1), q.minus(1)); - } while (!(NumberTheory::GCD(e, lambda) == 1)); - - auto n = p.multiplied_by(q); - - auto d = NumberTheory::ModularInverse(e, lambda); - RSAKeyPair keys { - { n, e }, - { n, d, e, p, q } - }; - return keys; - } + static ErrorOr generate_key_pair(size_t bits = 256, IntegerType e = 65537); RSA(KeyPairType const& pair) : PKSystem, RSAPublicKey>(pair.public_key, pair.private_key) diff --git a/Libraries/LibWeb/Crypto/CryptoAlgorithms.cpp b/Libraries/LibWeb/Crypto/CryptoAlgorithms.cpp index 751817463ac..df50b2ca4df 100644 --- a/Libraries/LibWeb/Crypto/CryptoAlgorithms.cpp +++ b/Libraries/LibWeb/Crypto/CryptoAlgorithms.cpp @@ -764,7 +764,11 @@ WebIDL::ExceptionOr, GC::Ref>> RSAOAEP // and RSA public exponent equal to the publicExponent member of normalizedAlgorithm. // 3. If performing the operation results in an error, then throw an OperationError. auto const& normalized_algorithm = static_cast(params); - auto key_pair = ::Crypto::PK::RSA::generate_key_pair(normalized_algorithm.modulus_length, normalized_algorithm.public_exponent); + auto maybe_key_pair = ::Crypto::PK::RSA::generate_key_pair(normalized_algorithm.modulus_length, normalized_algorithm.public_exponent); + if (maybe_key_pair.is_error()) + return WebIDL::OperationError::create(m_realm, "Failed generating RSA key pair"_string); + + auto key_pair = maybe_key_pair.release_value(); // 4. Let algorithm be a new RsaHashedKeyAlgorithm object. auto algorithm = RsaHashedKeyAlgorithm::create(m_realm); diff --git a/Tests/LibCrypto/TestRSA.cpp b/Tests/LibCrypto/TestRSA.cpp index fcae3a1498e..1e06ccb5cde 100644 --- a/Tests/LibCrypto/TestRSA.cpp +++ b/Tests/LibCrypto/TestRSA.cpp @@ -36,7 +36,9 @@ TEST_CASE(test_RSA_raw_encrypt) TEST_CASE(test_RSA_PKCS_1_encrypt) { ByteBuffer data { "hellohellohellohellohellohellohellohellohello123-"_b }; - Crypto::PK::RSA_PKCS1_EME rsa(Crypto::PK::RSA::generate_key_pair(1024)); + + auto keypair = TRY_OR_FAIL(Crypto::PK::RSA::generate_key_pair(1024)); + Crypto::PK::RSA_PKCS1_EME rsa(keypair); ByteBuffer buffer = {}; buffer.resize(rsa.output_size()); auto buf = buffer.bytes(); @@ -155,7 +157,8 @@ c8yGzl89pYST TEST_CASE(test_RSA_encrypt_decrypt) { - Crypto::PK::RSA rsa(Crypto::PK::RSA::generate_key_pair(1024)); + auto keypair = TRY_OR_FAIL(Crypto::PK::RSA::generate_key_pair(1024)); + Crypto::PK::RSA rsa(keypair); ByteBuffer enc_buffer = {}; enc_buffer.resize(rsa.output_size());