From 6cf89e46c9d09bcdc1cacbd5f7556c7c5c7083cc Mon Sep 17 00:00:00 2001 From: devgianlu Date: Tue, 26 Nov 2024 18:15:39 +0100 Subject: [PATCH] LibCrypto: Parse EC private key when parsing an ASN.1 `PrivateKeyInfo` Parse and store the `ECPrivateKey` extracted from the `privateKeyAlgorithm` field of the ASN.1 `PrivateKeyInfo` sequence when the algorithm identifier is `ec_public_key_encryption`. The parsing function returns `ErrorOr` instead of an "empty" key, like `parse_rsa_key` does. To me, this seemed better in terms of reliability. As mentioned in the previous commit, there is room for improvement. --- Libraries/LibCrypto/Certificate/Certificate.cpp | 12 ++++++++++++ Libraries/LibCrypto/Certificate/Certificate.h | 2 ++ 2 files changed, 14 insertions(+) diff --git a/Libraries/LibCrypto/Certificate/Certificate.cpp b/Libraries/LibCrypto/Certificate/Certificate.cpp index 537f99e8b24..e43302f61dd 100644 --- a/Libraries/LibCrypto/Certificate/Certificate.cpp +++ b/Libraries/LibCrypto/Certificate/Certificate.cpp @@ -12,6 +12,7 @@ #include #include #include +#include namespace { static String s_error_string; @@ -436,6 +437,17 @@ ErrorOr parse_private_key_info(Crypto::ASN1::Decoder& decoder, Vecto EXIT_SCOPE(); return private_key; } + if (private_key.algorithm.identifier.span() == ec_public_key_encryption_oid.span()) { + auto maybe_key = Crypto::PK::EC::parse_ec_key(value.bytes()); + if (maybe_key.is_error()) { + ERROR_WITH_SCOPE(TRY(String::formatted("Invalid EC key at {}: {}", current_scope, maybe_key.release_error()))); + } + + private_key.ec = move(maybe_key.release_value().private_key); + + EXIT_SCOPE(); + return private_key; + } // https://datatracker.ietf.org/doc/html/rfc8410#section-9 // For all of the OIDs, the parameters MUST be absent. diff --git a/Libraries/LibCrypto/Certificate/Certificate.h b/Libraries/LibCrypto/Certificate/Certificate.h index baefb4e831b..7a07f567eaf 100644 --- a/Libraries/LibCrypto/Certificate/Certificate.h +++ b/Libraries/LibCrypto/Certificate/Certificate.h @@ -14,6 +14,7 @@ #include #include #include +#include #include namespace Crypto::Certificate { @@ -262,6 +263,7 @@ ErrorOr parse_subject_public_key_info(Crypto::ASN1::Decoder& d class PrivateKey { public: Crypto::PK::RSAPrivateKey rsa; + Crypto::PK::ECPrivateKey ec; AlgorithmIdentifier algorithm; ByteBuffer raw_key;