1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-27 02:17:35 +00:00

LibTLS: Change Certificate parsing to use ErrorOr

Loads of changes that are tightly connected... :/
* Change lambdas to static functions
* Add spec docs to those functions
* Keep the current scope around as a parameter
* Add wrapping classes for some Certificate members
* Parse ec and ecdsa data from certificates
This commit is contained in:
stelar7 2023-04-03 19:05:01 +02:00 committed by Ali Mohammad Pur
parent b1d80b35af
commit d527edf0ab
8 changed files with 1044 additions and 553 deletions

View file

@ -102,13 +102,13 @@ bool Certificate::is_valid() const
{
auto now = Core::DateTime::now();
if (now < not_before) {
dbgln("certificate expired (not yet valid, signed for {})", not_before.to_deprecated_string());
if (now < validity.not_before) {
dbgln("certificate expired (not yet valid, signed for {})", validity.not_before.to_deprecated_string());
return false;
}
if (not_after < now) {
dbgln("certificate expired (expiry date {})", not_after.to_deprecated_string());
if (validity.not_after < now) {
dbgln("certificate expired (expiry date {})", validity.not_after.to_deprecated_string());
return false;
}
@ -201,11 +201,12 @@ void TLSv12::set_root_certificates(Vector<Certificate> certificates)
}
for (auto& cert : certificates) {
if (!cert.is_valid())
dbgln("Certificate for {} by {} is invalid, things may or may not work!", cert.subject.subject, cert.issuer.subject);
if (!cert.is_valid()) {
dbgln("Certificate for {} by {} is invalid, things may or may not work!", cert.subject.common_name(), cert.issuer.common_name());
}
// FIXME: Figure out what we should do when our root certs are invalid.
m_context.root_certificates.set(cert.subject_identifier_string(), cert);
m_context.root_certificates.set(MUST(cert.subject.to_string()).to_deprecated_string(), cert);
}
dbgln_if(TLS_DEBUG, "{}: Set {} root certificates", this, m_context.root_certificates.size());
}
@ -228,7 +229,7 @@ static bool wildcard_matches(StringView host, StringView subject)
static bool certificate_subject_matches_host(Certificate& cert, StringView host)
{
if (wildcard_matches(host, cert.subject.subject))
if (wildcard_matches(host, cert.subject.common_name()))
return true;
for (auto& san : cert.SAN) {
@ -279,15 +280,15 @@ bool Context::verify_chain(StringView host) const
for (size_t cert_index = 0; cert_index < local_chain->size(); ++cert_index) {
auto cert = local_chain->at(cert_index);
auto subject_string = cert.subject_identifier_string();
auto issuer_string = cert.issuer_identifier_string();
auto subject_string = MUST(cert.subject.to_string());
auto issuer_string = MUST(cert.issuer.to_string());
if (!cert.is_valid()) {
dbgln("verify_chain: Certificate is not valid {}", subject_string);
return false;
}
auto maybe_root_certificate = root_certificates.get(issuer_string);
auto maybe_root_certificate = root_certificates.get(issuer_string.to_deprecated_string());
if (maybe_root_certificate.has_value()) {
auto& root_certificate = *maybe_root_certificate;
auto verification_correct = verify_certificate_pair(cert, root_certificate);
@ -312,7 +313,7 @@ bool Context::verify_chain(StringView host) const
}
auto parent_certificate = local_chain->at(cert_index + 1);
if (issuer_string != parent_certificate.subject_identifier_string()) {
if (issuer_string != MUST(parent_certificate.subject.to_string())) {
dbgln("verify_chain: Next certificate in the chain is not the issuer of this certificate");
return false;
}
@ -359,7 +360,7 @@ bool Context::verify_certificate_pair(Certificate const& subject, Certificate co
}
Crypto::PK::RSAPrivateKey dummy_private_key;
Crypto::PK::RSAPublicKey public_key_copy { issuer.public_key };
Crypto::PK::RSAPublicKey public_key_copy { issuer.public_key.rsa };
auto rsa = Crypto::PK::RSA(public_key_copy, dummy_private_key);
auto verification_buffer_result = ByteBuffer::create_uninitialized(subject.signature_value.size());
if (verification_buffer_result.is_error()) {
@ -471,8 +472,8 @@ Vector<Certificate> TLSv12::parse_pem_certificate(ReadonlyBytes certificate_pem_
return {};
}
auto maybe_certificate = Certificate::parse_asn1(decoded_certificate);
if (!maybe_certificate.has_value()) {
auto maybe_certificate = Certificate::parse_certificate(decoded_certificate);
if (!maybe_certificate.is_error()) {
dbgln("Invalid certificate");
return {};
}
@ -516,19 +517,20 @@ ErrorOr<Vector<Certificate>> DefaultRootCACertificates::reload_certificates(Byte
auto certs = TRY(Crypto::decode_pems(data));
for (auto& cert : certs) {
auto certificate_result = Certificate::parse_asn1(cert.bytes());
auto certificate_result = Certificate::parse_certificate(cert.bytes());
// If the certificate does not parse it is likely using elliptic curve keys/signatures, which are not
// supported right now. It might make sense to cleanup cacert.pem before adding it to the system.
if (!certificate_result.has_value()) {
if (certificate_result.is_error()) {
// FIXME: It would be nice to have more informations about the certificate we failed to parse.
// Like: Issuer, Algorithm, CN, etc
dbgln("Failed to load certificate: {}", certificate_result.error());
continue;
}
auto certificate = certificate_result.release_value();
if (certificate.is_certificate_authority && certificate.is_self_signed()) {
TRY(certificates.try_append(move(certificate)));
} else {
dbgln("Skipped '{}' because it is not a valid root CA", certificate.subject_identifier_string());
dbgln("Skipped '{}' because it is not a valid root CA", MUST(certificate.subject.to_string()));
}
}