1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-14 11:14:58 +00:00

LibTLS: Streamline certificate loading

Some refactoring of our root ca loading process:

- Remove duplicate code
- Remove duplicate calls to `parse_root_ca`
- Load user imported certificates in Browser/RequestServer
This commit is contained in:
Fabian Dellwing 2023-04-10 07:06:17 +02:00 committed by Ali Mohammad Pur
parent e4481baef9
commit 93232d4e6d
5 changed files with 28 additions and 33 deletions

View file

@ -42,7 +42,7 @@ ErrorOr<Vector<Certificate>> load_certificates()
{ {
auto cacert_file = TRY(Core::File::open(locate_ca_certs_file(), Core::File::OpenMode::Read)); auto cacert_file = TRY(Core::File::open(locate_ca_certs_file(), Core::File::OpenMode::Read));
auto data = TRY(cacert_file->read_until_eof()); auto data = TRY(cacert_file->read_until_eof());
return TRY(DefaultRootCACertificates::the().reload_certificates(data)); return TRY(DefaultRootCACertificates::parse_pem_root_certificate_authorities(data));
} }
TEST_CASE(test_TLS_hello_handshake) TEST_CASE(test_TLS_hello_handshake)

View file

@ -29,16 +29,7 @@ void CertificateStoreProxyModel::sort(int column, GUI::SortOrder sort_order)
ErrorOr<void> CertificateStoreModel::load() ErrorOr<void> CertificateStoreModel::load()
{ {
auto cacert_file = TRY(Core::File::open("/etc/cacert.pem"sv, Core::File::OpenMode::Read)); m_certificates = TRY(DefaultRootCACertificates::load_certificates());
auto data = TRY(cacert_file->read_until_eof());
auto user_cert_path = TRY(String::formatted("{}/.config/certs.pem", Core::StandardPaths::home_directory()));
if (FileSystem::exists(user_cert_path)) {
auto user_cert_file = TRY(Core::File::open(user_cert_path, Core::File::OpenMode::Read));
TRY(data.try_append(TRY(user_cert_file->read_until_eof())));
}
m_certificates = TRY(DefaultRootCACertificates::the().reload_certificates(data));
return {}; return {};
} }
@ -111,7 +102,7 @@ ErrorOr<void> CertificateStoreWidget::import_pem()
return Error::from_string_view("File is not a .pem or .crt file."sv); return Error::from_string_view("File is not a .pem or .crt file."sv);
auto data = TRY(fsac_file.release_stream()->read_until_eof()); auto data = TRY(fsac_file.release_stream()->read_until_eof());
auto count = TRY(m_root_ca_model->add(TRY(DefaultRootCACertificates::the().reload_certificates(data)))); auto count = TRY(m_root_ca_model->add(TRY(DefaultRootCACertificates::parse_pem_root_certificate_authorities(data))));
if (count == 0) { if (count == 0) {
return Error::from_string_view("No valid CA found to import."sv); return Error::from_string_view("No valid CA found to import."sv);

View file

@ -12,6 +12,6 @@ set(SOURCES
) )
serenity_lib(LibTLS tls) serenity_lib(LibTLS tls)
target_link_libraries(LibTLS PRIVATE LibCore LibCrypto) target_link_libraries(LibTLS PRIVATE LibCore LibCrypto LibFileSystem)
include(ca_certificates_data) include(ca_certificates_data)

View file

@ -260,7 +260,8 @@ public:
Vector<Certificate> const& certificates() const { return m_ca_certificates; } Vector<Certificate> const& certificates() const { return m_ca_certificates; }
ErrorOr<Vector<Certificate>> reload_certificates(ByteBuffer&); static ErrorOr<Vector<Certificate>> parse_pem_root_certificate_authorities(ByteBuffer&);
static ErrorOr<Vector<Certificate>> load_certificates();
static DefaultRootCACertificates& the() { return s_the; } static DefaultRootCACertificates& the() { return s_the; }

View file

@ -10,11 +10,13 @@
#include <LibCore/ConfigFile.h> #include <LibCore/ConfigFile.h>
#include <LibCore/DateTime.h> #include <LibCore/DateTime.h>
#include <LibCore/File.h> #include <LibCore/File.h>
#include <LibCore/StandardPaths.h>
#include <LibCore/Timer.h> #include <LibCore/Timer.h>
#include <LibCrypto/ASN1/ASN1.h> #include <LibCrypto/ASN1/ASN1.h>
#include <LibCrypto/ASN1/PEM.h> #include <LibCrypto/ASN1/PEM.h>
#include <LibCrypto/PK/Code/EMSA_PKCS1_V1_5.h> #include <LibCrypto/PK/Code/EMSA_PKCS1_V1_5.h>
#include <LibCrypto/PK/Code/EMSA_PSS.h> #include <LibCrypto/PK/Code/EMSA_PSS.h>
#include <LibFileSystem/FileSystem.h>
#include <LibTLS/Certificate.h> #include <LibTLS/Certificate.h>
#include <LibTLS/TLSv12.h> #include <LibTLS/TLSv12.h>
#include <errno.h> #include <errno.h>
@ -488,29 +490,30 @@ Vector<Certificate> TLSv12::parse_pem_certificate(ReadonlyBytes certificate_pem_
Singleton<DefaultRootCACertificates> DefaultRootCACertificates::s_the; Singleton<DefaultRootCACertificates> DefaultRootCACertificates::s_the;
DefaultRootCACertificates::DefaultRootCACertificates() DefaultRootCACertificates::DefaultRootCACertificates()
{ {
auto cacert_result = Core::File::open("/etc/cacert.pem"sv, Core::File::OpenMode::Read); auto load_result = load_certificates();
if (cacert_result.is_error()) { if (load_result.is_error()) {
dbgln("Failed to load CA Certificates: {}", cacert_result.error()); dbgln("Failed to load CA Certificates: {}", load_result.error());
return;
}
auto cacert_file = cacert_result.release_value();
auto data_result = cacert_file->read_until_eof();
if (data_result.is_error()) {
dbgln("Failed to load CA Certificates: {}", data_result.error());
return;
}
auto data = data_result.release_value();
auto reload_result = reload_certificates(data);
if (reload_result.is_error()) {
dbgln("Failed to load CA Certificates: {}", reload_result.error());
return; return;
} }
m_ca_certificates = reload_result.release_value(); m_ca_certificates = load_result.release_value();
} }
ErrorOr<Vector<Certificate>> DefaultRootCACertificates::reload_certificates(ByteBuffer& data) ErrorOr<Vector<Certificate>> DefaultRootCACertificates::load_certificates()
{
auto cacert_file = TRY(Core::File::open("/etc/cacert.pem"sv, Core::File::OpenMode::Read));
auto data = TRY(cacert_file->read_until_eof());
auto user_cert_path = TRY(String::formatted("{}/.config/certs.pem", Core::StandardPaths::home_directory()));
if (FileSystem::exists(user_cert_path)) {
auto user_cert_file = TRY(Core::File::open(user_cert_path, Core::File::OpenMode::Read));
TRY(data.try_append(TRY(user_cert_file->read_until_eof())));
}
return TRY(parse_pem_root_certificate_authorities(data));
}
ErrorOr<Vector<Certificate>> DefaultRootCACertificates::parse_pem_root_certificate_authorities(ByteBuffer& data)
{ {
Vector<Certificate> certificates; Vector<Certificate> certificates;
@ -530,7 +533,7 @@ ErrorOr<Vector<Certificate>> DefaultRootCACertificates::reload_certificates(Byte
if (certificate.is_certificate_authority && certificate.is_self_signed()) { if (certificate.is_certificate_authority && certificate.is_self_signed()) {
TRY(certificates.try_append(move(certificate))); TRY(certificates.try_append(move(certificate)));
} else { } else {
dbgln("Skipped '{}' because it is not a valid root CA", MUST(certificate.subject.to_string())); dbgln("Skipped '{}' because it is not a valid root CA", TRY(certificate.subject.to_string()));
} }
} }