From 49c388b8917d47483433dd64d61bfac0e6af82e4 Mon Sep 17 00:00:00 2001 From: devgianlu Date: Sun, 24 Nov 2024 21:55:03 +0100 Subject: [PATCH] LibTLS+LibWeb+LibCrypto: Move `Certificate` to LibCrypto By moving `Certificate` to `LibCrypto` it is possible to reuse a bunch of code from in `LibCrypto` itself. It also moves some constants and pieces of code to a more appropriate place than `LibTLS`. This also makes future work on WebCryptoAPI easier. --- Libraries/LibCrypto/CMakeLists.txt | 1 + .../Certificate}/Certificate.cpp | 2 +- .../Certificate}/Certificate.h | 5 +-- Libraries/LibTLS/CMakeLists.txt | 1 - Libraries/LibTLS/TLSv12.cpp | 24 ++++++------- Libraries/LibTLS/TLSv12.h | 4 ++- Libraries/LibWeb/Crypto/CryptoAlgorithms.cpp | 34 +++++++++---------- Meta/Lagom/Fuzzers/FuzzASN1.cpp | 4 +-- Services/RequestServer/main.cpp | 1 - Tests/LibTLS/TestTLSCertificateParser.cpp | 8 ++--- Tests/LibTLS/TestTLSHandshake.cpp | 4 +-- .../src/main/cpp/RequestServerService.cpp | 2 +- 12 files changed, 44 insertions(+), 46 deletions(-) rename Libraries/{LibTLS => LibCrypto/Certificate}/Certificate.cpp (99%) rename Libraries/{LibTLS => LibCrypto/Certificate}/Certificate.h (99%) diff --git a/Libraries/LibCrypto/CMakeLists.txt b/Libraries/LibCrypto/CMakeLists.txt index 6d637cb8eb0..cfade641e6b 100644 --- a/Libraries/LibCrypto/CMakeLists.txt +++ b/Libraries/LibCrypto/CMakeLists.txt @@ -17,6 +17,7 @@ set(SOURCES BigInt/Algorithms/SimpleOperations.cpp BigInt/SignedBigInteger.cpp BigInt/UnsignedBigInteger.cpp + Certificate/Certificate.cpp Checksum/Adler32.cpp Checksum/cksum.cpp Checksum/CRC32.cpp diff --git a/Libraries/LibTLS/Certificate.cpp b/Libraries/LibCrypto/Certificate/Certificate.cpp similarity index 99% rename from Libraries/LibTLS/Certificate.cpp rename to Libraries/LibCrypto/Certificate/Certificate.cpp index d80d8bbfc56..736a288eae9 100644 --- a/Libraries/LibTLS/Certificate.cpp +++ b/Libraries/LibCrypto/Certificate/Certificate.cpp @@ -17,7 +17,7 @@ namespace { static String s_error_string; } -namespace TLS { +namespace Crypto::Certificate { #define ERROR_WITH_SCOPE(error) \ do { \ diff --git a/Libraries/LibTLS/Certificate.h b/Libraries/LibCrypto/Certificate/Certificate.h similarity index 99% rename from Libraries/LibTLS/Certificate.h rename to Libraries/LibCrypto/Certificate/Certificate.h index 88945c6ebfb..c524eb834d9 100644 --- a/Libraries/LibTLS/Certificate.h +++ b/Libraries/LibCrypto/Certificate/Certificate.h @@ -15,9 +15,8 @@ #include #include #include -#include -namespace TLS { +namespace Crypto::Certificate { constexpr static Array rsa_encryption_oid { 1, 2, 840, 113549, 1, 1, 1 }, @@ -301,5 +300,3 @@ private: }; } - -using TLS::Certificate; diff --git a/Libraries/LibTLS/CMakeLists.txt b/Libraries/LibTLS/CMakeLists.txt index 326df1f4cc6..f21dc89a922 100644 --- a/Libraries/LibTLS/CMakeLists.txt +++ b/Libraries/LibTLS/CMakeLists.txt @@ -1,7 +1,6 @@ add_cxx_compile_options(-Wvla) set(SOURCES - Certificate.cpp Handshake.cpp HandshakeCertificate.cpp HandshakeClient.cpp diff --git a/Libraries/LibTLS/TLSv12.cpp b/Libraries/LibTLS/TLSv12.cpp index 2863dd2ad77..584d88ad3ef 100644 --- a/Libraries/LibTLS/TLSv12.cpp +++ b/Libraries/LibTLS/TLSv12.cpp @@ -14,11 +14,11 @@ #include #include #include +#include #include #include #include #include -#include #include #include @@ -316,25 +316,25 @@ bool Context::verify_certificate_pair(Certificate const& subject, Certificate co bool is_rsa = true; - if (identifier == rsa_encryption_oid) { + if (identifier == Crypto::Certificate::rsa_encryption_oid) { kind = Crypto::Hash::HashKind::None; - } else if (identifier == rsa_md5_encryption_oid) { + } else if (identifier == Crypto::Certificate::rsa_md5_encryption_oid) { kind = Crypto::Hash::HashKind::MD5; - } else if (identifier == rsa_sha1_encryption_oid) { + } else if (identifier == Crypto::Certificate::rsa_sha1_encryption_oid) { kind = Crypto::Hash::HashKind::SHA1; - } else if (identifier == rsa_sha256_encryption_oid) { + } else if (identifier == Crypto::Certificate::rsa_sha256_encryption_oid) { kind = Crypto::Hash::HashKind::SHA256; - } else if (identifier == rsa_sha384_encryption_oid) { + } else if (identifier == Crypto::Certificate::rsa_sha384_encryption_oid) { kind = Crypto::Hash::HashKind::SHA384; - } else if (identifier == rsa_sha512_encryption_oid) { + } else if (identifier == Crypto::Certificate::rsa_sha512_encryption_oid) { kind = Crypto::Hash::HashKind::SHA512; - } else if (identifier == ecdsa_with_sha256_encryption_oid) { + } else if (identifier == Crypto::Certificate::ecdsa_with_sha256_encryption_oid) { kind = Crypto::Hash::HashKind::SHA256; is_rsa = false; - } else if (identifier == ecdsa_with_sha384_encryption_oid) { + } else if (identifier == Crypto::Certificate::ecdsa_with_sha384_encryption_oid) { kind = Crypto::Hash::HashKind::SHA384; is_rsa = false; - } else if (identifier == ecdsa_with_sha512_encryption_oid) { + } else if (identifier == Crypto::Certificate::ecdsa_with_sha512_encryption_oid) { kind = Crypto::Hash::HashKind::SHA512; is_rsa = false; } @@ -597,9 +597,9 @@ ErrorOr> DefaultRootCACertificates::parse_pem_root_certifica ErrorOr oid_to_curve(Vector curve) { - if (curve == curve_ansip384r1) + if (curve == Crypto::Certificate::curve_ansip384r1) return SupportedGroup::SECP384R1; - if (curve == curve_prime256) + if (curve == Crypto::Certificate::curve_prime256) return SupportedGroup::SECP256R1; return AK::Error::from_string_literal("Unknown curve oid"); diff --git a/Libraries/LibTLS/TLSv12.h b/Libraries/LibTLS/TLSv12.h index 3330743808c..f6cb127da75 100644 --- a/Libraries/LibTLS/TLSv12.h +++ b/Libraries/LibTLS/TLSv12.h @@ -6,7 +6,6 @@ #pragma once -#include "Certificate.h" #include #include #include @@ -15,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -24,6 +24,8 @@ namespace TLS { +using Crypto::Certificate::Certificate; + inline void print_buffer(ReadonlyBytes buffer) { dbgln("{:hex-dump}", buffer); diff --git a/Libraries/LibWeb/Crypto/CryptoAlgorithms.cpp b/Libraries/LibWeb/Crypto/CryptoAlgorithms.cpp index 8d0963d1edf..b0f392d4d03 100644 --- a/Libraries/LibWeb/Crypto/CryptoAlgorithms.cpp +++ b/Libraries/LibWeb/Crypto/CryptoAlgorithms.cpp @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -28,7 +29,6 @@ #include #include #include -#include #include #include #include @@ -173,13 +173,13 @@ static WebIDL::ExceptionOr parse_an_ASN1_structure(JS::Realm& realm, // 4. Parse data according to the Distinguished Encoding Rules of [X690], using structure as the ASN.1 structure to be decoded. ::Crypto::ASN1::Decoder decoder(data); Structure structure; - if constexpr (IsSame) { - auto maybe_subject_public_key = TLS::parse_subject_public_key_info(decoder); + if constexpr (IsSame) { + auto maybe_subject_public_key = ::Crypto::Certificate::parse_subject_public_key_info(decoder); if (maybe_subject_public_key.is_error()) return WebIDL::DataError::create(realm, MUST(String::formatted("Error parsing subjectPublicKeyInfo: {}", maybe_subject_public_key.release_error()))); structure = maybe_subject_public_key.release_value(); - } else if constexpr (IsSame) { - auto maybe_private_key = TLS::parse_private_key_info(decoder); + } else if constexpr (IsSame) { + auto maybe_private_key = ::Crypto::Certificate::parse_private_key_info(decoder); if (maybe_private_key.is_error()) return WebIDL::DataError::create(realm, MUST(String::formatted("Error parsing privateKeyInfo: {}", maybe_private_key.release_error()))); structure = maybe_private_key.release_value(); @@ -201,21 +201,21 @@ static WebIDL::ExceptionOr parse_an_ASN1_structure(JS::Realm& realm, } // https://w3c.github.io/webcrypto/#concept-parse-a-spki -static WebIDL::ExceptionOr parse_a_subject_public_key_info(JS::Realm& realm, ReadonlyBytes bytes) +static WebIDL::ExceptionOr<::Crypto::Certificate::SubjectPublicKey> parse_a_subject_public_key_info(JS::Realm& realm, ReadonlyBytes bytes) { // When this specification says to parse a subjectPublicKeyInfo, the user agent must parse an ASN.1 structure, // with data set to the sequence of bytes to be parsed, structure as the ASN.1 structure of subjectPublicKeyInfo, // as specified in [RFC5280], and exactData set to true. - return parse_an_ASN1_structure(realm, bytes, true); + return parse_an_ASN1_structure<::Crypto::Certificate::SubjectPublicKey>(realm, bytes, true); } // https://w3c.github.io/webcrypto/#concept-parse-a-privateKeyInfo -static WebIDL::ExceptionOr parse_a_private_key_info(JS::Realm& realm, ReadonlyBytes bytes) +static WebIDL::ExceptionOr<::Crypto::Certificate::PrivateKey> parse_a_private_key_info(JS::Realm& realm, ReadonlyBytes bytes) { // When this specification says to parse a PrivateKeyInfo, the user agent must parse an ASN.1 structure // with data set to the sequence of bytes to be parsed, structure as the ASN.1 structure of PrivateKeyInfo, // as specified in [RFC5208], and exactData set to true. - return parse_an_ASN1_structure(realm, bytes, true); + 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) @@ -852,7 +852,7 @@ WebIDL::ExceptionOr> RSAOAEP::import_key(Web::Crypto::Algorit // 4. If the algorithm object identifier field of the algorithm AlgorithmIdentifier field of spki // is not equal to the rsaEncryption object identifier defined in [RFC3447], then throw a DataError. - if (spki.algorithm.identifier != TLS::rsa_encryption_oid) + if (spki.algorithm.identifier != ::Crypto::Certificate::rsa_encryption_oid) return WebIDL::DataError::create(m_realm, "Algorithm object identifier is not the rsaEncryption object identifier"_string); // 5. Let publicKey be the result of performing the parse an ASN.1 structure algorithm, @@ -889,7 +889,7 @@ WebIDL::ExceptionOr> RSAOAEP::import_key(Web::Crypto::Algorit // 4. If the algorithm object identifier field of the privateKeyAlgorithm PrivateKeyAlgorithm field of privateKeyInfo // is not equal to the rsaEncryption object identifier defined in [RFC3447], then throw a DataError. - if (private_key_info.algorithm.identifier != TLS::rsa_encryption_oid) + if (private_key_info.algorithm.identifier != ::Crypto::Certificate::rsa_encryption_oid) return WebIDL::DataError::create(m_realm, "Algorithm object identifier is not the rsaEncryption object identifier"_string); // 5. Let rsaPrivateKey be the result of performing the parse an ASN.1 structure algorithm, @@ -2720,7 +2720,7 @@ WebIDL::ExceptionOr> ED25519::import_key( // 4. If the algorithm object identifier field of the algorithm AlgorithmIdentifier field of spki // is not equal to the id-Ed25519 object identifier defined in [RFC8410], then throw a DataError. - if (spki.algorithm.identifier != TLS::ed25519_oid) + if (spki.algorithm.identifier != ::Crypto::Certificate::ed25519_oid) return WebIDL::DataError::create(m_realm, "Invalid algorithm identifier"_string); // 5. If the parameters field of the algorithm AlgorithmIdentifier field of spki is present, then throw a DataError. @@ -2762,7 +2762,7 @@ WebIDL::ExceptionOr> ED25519::import_key( // 4. If the algorithm object identifier field of the privateKeyAlgorithm PrivateKeyAlgorithm field // of privateKeyInfo is not equal to the id-Ed25519 object identifier defined in [RFC8410], then throw a DataError. - if (private_key_info.algorithm.identifier != TLS::ed25519_oid) + if (private_key_info.algorithm.identifier != ::Crypto::Certificate::ed25519_oid) return WebIDL::DataError::create(m_realm, "Invalid algorithm identifier"_string); // 5. If the parameters field of the privateKeyAlgorithm PrivateKeyAlgorithmIdentifier field of privateKeyInfo is present, @@ -2970,7 +2970,7 @@ WebIDL::ExceptionOr> ED25519::export_key(Bindings::KeyFormat // * Set the algorithm field to an AlgorithmIdentifier ASN.1 type with the following properties: // * Set the algorithm object identifier to the id-Ed25519 OID defined in [RFC8410]. // * Set the subjectPublicKey field to keyData. - auto ed25519_oid = TLS::ed25519_oid; + auto ed25519_oid = ::Crypto::Certificate::ed25519_oid; auto data = TRY_OR_THROW_OOM(vm, ::Crypto::PK::wrap_in_subject_public_key_info(key_data, ed25519_oid)); // 3. Let result be a new ArrayBuffer associated with the relevant global object of this [HTML], and containing data. @@ -2989,7 +2989,7 @@ WebIDL::ExceptionOr> ED25519::export_key(Bindings::KeyFormat // * Set the algorithm object identifier to the id-Ed25519 OID defined in [RFC8410]. // * Set the privateKey field to the result of DER-encoding a CurvePrivateKey ASN.1 type, as defined in Section 7 of [RFC8410], that represents the Ed25519 private key represented by the [[handle]] internal slot of key - auto ed25519_oid = TLS::ed25519_oid; + auto ed25519_oid = ::Crypto::Certificate::ed25519_oid; auto data = TRY_OR_THROW_OOM(vm, ::Crypto::PK::wrap_in_private_key_info(key_data, ed25519_oid)); // 3. Let result be a new ArrayBuffer associated with the relevant global object of this [HTML], and containing data. @@ -3413,7 +3413,7 @@ WebIDL::ExceptionOr> X25519::import_key([[maybe_unused]] Web: // 4. If the algorithm object identifier field of the algorithm AlgorithmIdentifier field of spki // is not equal to the id-X25519 object identifier defined in [RFC8410], then throw a DataError. - if (spki.algorithm.identifier != TLS::x25519_oid) + if (spki.algorithm.identifier != ::Crypto::Certificate::x25519_oid) return WebIDL::DataError::create(m_realm, "Invalid algorithm"_string); // 5. If the parameters field of the algorithm AlgorithmIdentifier field of spki is present, then throw a DataError. @@ -3454,7 +3454,7 @@ WebIDL::ExceptionOr> X25519::import_key([[maybe_unused]] Web: // 4. If the algorithm object identifier field of the privateKeyAlgorithm PrivateKeyAlgorithm field of privateKeyInfo // is not equal to the id-X25519 object identifier defined in [RFC8410], then throw a DataError. - if (private_key_info.algorithm.identifier != TLS::x25519_oid) + if (private_key_info.algorithm.identifier != ::Crypto::Certificate::x25519_oid) return WebIDL::DataError::create(m_realm, "Invalid algorithm"_string); // 5. If the parameters field of the privateKeyAlgorithm PrivateKeyAlgorithmIdentifier field of privateKeyInfo is present, then throw a DataError. diff --git a/Meta/Lagom/Fuzzers/FuzzASN1.cpp b/Meta/Lagom/Fuzzers/FuzzASN1.cpp index 107b0f2bef1..5c4f34b70e4 100644 --- a/Meta/Lagom/Fuzzers/FuzzASN1.cpp +++ b/Meta/Lagom/Fuzzers/FuzzASN1.cpp @@ -4,14 +4,14 @@ * SPDX-License-Identifier: BSD-2-Clause */ -#include +#include #include #include extern "C" int LLVMFuzzerTestOneInput(uint8_t const* data, size_t size) { AK::set_debug_enabled(false); - (void)TLS::Certificate::parse_certificate({ data, size }); + (void)Crypto::Certificate::Certificate::parse_certificate({ data, size }); return 0; } diff --git a/Services/RequestServer/main.cpp b/Services/RequestServer/main.cpp index 1ada7318e3f..1f7ed6c6896 100644 --- a/Services/RequestServer/main.cpp +++ b/Services/RequestServer/main.cpp @@ -15,7 +15,6 @@ #include #include #include -#include #include #include diff --git a/Tests/LibTLS/TestTLSCertificateParser.cpp b/Tests/LibTLS/TestTLSCertificateParser.cpp index 76ef590b78a..2ad9ea4fc93 100644 --- a/Tests/LibTLS/TestTLSCertificateParser.cpp +++ b/Tests/LibTLS/TestTLSCertificateParser.cpp @@ -5,13 +5,13 @@ */ #include -#include +#include #include TEST_CASE(certificate_with_malformed_tbscertificate_should_fail_gracefully) { Array invalid_certificate_data { 0xB0, 0x02, 0x70, 0x00 }; - auto parse_result = TLS::Certificate::parse_certificate(invalid_certificate_data); + auto parse_result = Crypto::Certificate::Certificate::parse_certificate(invalid_certificate_data); EXPECT(parse_result.is_error()); } @@ -31,9 +31,9 @@ TEST_CASE(test_private_key_info_decode) auto decoded_keyder = TRY_OR_FAIL(decode_base64(keyder)); Crypto::ASN1::Decoder decoder(decoded_keyder); - auto private_key_info = TRY_OR_FAIL(TLS::parse_private_key_info(decoder)); + auto private_key_info = TRY_OR_FAIL(Crypto::Certificate::parse_private_key_info(decoder)); - EXPECT_EQ(private_key_info.algorithm.identifier, TLS::rsa_encryption_oid); + EXPECT_EQ(private_key_info.algorithm.identifier, Crypto::Certificate::rsa_encryption_oid); auto& key = private_key_info.rsa; EXPECT_EQ(key.length() * 8, 512u); diff --git a/Tests/LibTLS/TestTLSHandshake.cpp b/Tests/LibTLS/TestTLSHandshake.cpp index 2f42c29fbb6..d365fe47320 100644 --- a/Tests/LibTLS/TestTLSHandshake.cpp +++ b/Tests/LibTLS/TestTLSHandshake.cpp @@ -23,7 +23,7 @@ static ByteBuffer operator""_b(char const* string, size_t length) return ByteBuffer::copy(string, length).release_value(); } -ErrorOr> load_certificates(); +ErrorOr> load_certificates(); ByteString locate_ca_certs_file(); ByteString locate_ca_certs_file() @@ -38,7 +38,7 @@ ByteString locate_ca_certs_file() return ""; } -ErrorOr> load_certificates() +ErrorOr> load_certificates() { auto cacert_file = TRY(Core::File::open(locate_ca_certs_file(), Core::File::OpenMode::Read)); auto data = TRY(cacert_file->read_until_eof()); diff --git a/UI/Android/src/main/cpp/RequestServerService.cpp b/UI/Android/src/main/cpp/RequestServerService.cpp index 895323ef353..6f91b46b8fc 100644 --- a/UI/Android/src/main/cpp/RequestServerService.cpp +++ b/UI/Android/src/main/cpp/RequestServerService.cpp @@ -14,7 +14,7 @@ #include #include #include -#include +#include #include #include #include