From 0b7031437905d5e7dac228d2af05cd8a507c7a04 Mon Sep 17 00:00:00 2001 From: stelar7 Date: Wed, 12 Apr 2023 15:05:08 +0200 Subject: LibCrypto: Store the TBS ASN.1 data on the certificate This way we dont need to guess the offsets in LibTLS when using it. --- Userland/Libraries/LibCrypto/ASN1/DER.cpp | 10 ++++++++++ Userland/Libraries/LibCrypto/ASN1/DER.h | 2 ++ Userland/Libraries/LibTLS/Certificate.cpp | 12 ++++++++++++ Userland/Libraries/LibTLS/Certificate.h | 1 + 4 files changed, 25 insertions(+) diff --git a/Userland/Libraries/LibCrypto/ASN1/DER.cpp b/Userland/Libraries/LibCrypto/ASN1/DER.cpp index cbd7167921..262a12454b 100644 --- a/Userland/Libraries/LibCrypto/ASN1/DER.cpp +++ b/Userland/Libraries/LibCrypto/ASN1/DER.cpp @@ -67,6 +67,16 @@ ErrorOr Decoder::read_byte() return byte; } +ErrorOr Decoder::peek_entry_bytes() +{ + if (m_stack.is_empty()) + return Error::from_string_literal("ASN1::Decoder: Reading bytes from an empty stack"); + + auto entry = m_stack.last(); + + return entry; +} + ErrorOr Decoder::read_bytes(size_t length) { if (m_stack.is_empty()) diff --git a/Userland/Libraries/LibCrypto/ASN1/DER.h b/Userland/Libraries/LibCrypto/ASN1/DER.h index 63829c95b2..8138461e38 100644 --- a/Userland/Libraries/LibCrypto/ASN1/DER.h +++ b/Userland/Libraries/LibCrypto/ASN1/DER.h @@ -151,6 +151,8 @@ public: ErrorOr enter(); ErrorOr leave(); + ErrorOr peek_entry_bytes(); + private: template ErrorOr with_type_check(DecodedType&& value) diff --git a/Userland/Libraries/LibTLS/Certificate.cpp b/Userland/Libraries/LibTLS/Certificate.cpp index dbd3f9cf30..3a831b262a 100644 --- a/Userland/Libraries/LibTLS/Certificate.cpp +++ b/Userland/Libraries/LibTLS/Certificate.cpp @@ -680,9 +680,21 @@ static ErrorOr parse_tbs_certificate(Crypto::ASN1::Decoder& decoder // -- If present, version shall be v3]] // } + // Note: Parse out the ASN.1 of this object, since its used for TLS verification. + // To do this, we get the bytes of our parent, the size of ourself, and slice the parent buffer. + auto pre_cert_buffer = TRY(decoder.peek_entry_bytes()); + + // FIXME: Dont assume this value. + // Note: we assume this to be 4. 1 for the tag, and 3 for the length. + auto entry_length_byte_count = 4; + ENTER_TYPED_SCOPE(Sequence, "TBSCertificate"sv); + auto post_cert_buffer = TRY(decoder.peek_entry_bytes()); + auto asn1_data = TRY(ByteBuffer::copy(pre_cert_buffer.slice(0, post_cert_buffer.size() + entry_length_byte_count))); + Certificate certificate; + certificate.tbs_asn1 = asn1_data; certificate.version = TRY(parse_version(decoder, current_scope)).to_u64(); certificate.serial_number = TRY(parse_serial_number(decoder, current_scope)); certificate.algorithm = TRY(parse_algorithm_identifier(decoder, current_scope)); diff --git a/Userland/Libraries/LibTLS/Certificate.h b/Userland/Libraries/LibTLS/Certificate.h index 612c7ca11a..ac372d378f 100644 --- a/Userland/Libraries/LibTLS/Certificate.h +++ b/Userland/Libraries/LibTLS/Certificate.h @@ -271,6 +271,7 @@ public: AlgorithmIdentifier signature_algorithm; ByteBuffer signature_value {}; ByteBuffer original_asn1 {}; + ByteBuffer tbs_asn1 {}; bool is_allowed_to_sign_certificate { false }; bool is_certificate_authority { false }; Optional path_length_constraint {}; -- cgit v1.2.3