diff options
author | AnotherTest <ali.mpfard@gmail.com> | 2020-12-13 22:25:09 +0330 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-12-13 20:24:58 +0100 |
commit | dbfce38c90b2aa6851c1c83460c9bb9ab87ca774 (patch) | |
tree | 317320390671a20954ae9b69d33749d48a5717c6 /Libraries/LibTLS | |
parent | 48589db3aab2085ec4e5729fcf8f1a4a8a66067f (diff) | |
download | serenity-dbfce38c90b2aa6851c1c83460c9bb9ab87ca774.zip |
LibTLS: Read subjectAltName from certificates and use it
As quite a few certificates use this extension, reading and using it to
find matching certificates is fairly useful :^)
Diffstat (limited to 'Libraries/LibTLS')
-rw-r--r-- | Libraries/LibTLS/Certificate.h | 3 | ||||
-rw-r--r-- | Libraries/LibTLS/TLSv12.cpp | 32 |
2 files changed, 31 insertions, 4 deletions
diff --git a/Libraries/LibTLS/Certificate.h b/Libraries/LibTLS/Certificate.h index 2f2de40d87..22953092d4 100644 --- a/Libraries/LibTLS/Certificate.h +++ b/Libraries/LibTLS/Certificate.h @@ -66,8 +66,7 @@ struct Certificate { String entity; String subject; String unit; - u8** SAN; - u16 SAN_length; + Vector<String> SAN; u8* ocsp; Crypto::UnsignedBigInteger serial_number; ByteBuffer sign_key; diff --git a/Libraries/LibTLS/TLSv12.cpp b/Libraries/LibTLS/TLSv12.cpp index cf823f58c8..634f3c7b7f 100644 --- a/Libraries/LibTLS/TLSv12.cpp +++ b/Libraries/LibTLS/TLSv12.cpp @@ -41,7 +41,7 @@ namespace { struct OIDChain { - void* root { nullptr }; + OIDChain* root { nullptr }; u8* oid { nullptr }; }; } @@ -73,6 +73,25 @@ static bool _asn1_is_oid(const u8* oid, const u8* compare, size_t length = 3) return true; } +static bool _asn1_is_oid_in_chain(OIDChain* reference_chain, const u8* lookup, size_t lookup_length = 3) +{ + auto is_oid = [](const u8* oid, size_t oid_length, const u8* compare, size_t compare_length) { + if (oid_length < compare_length) + compare_length = oid_length; + for (size_t i = 0; i < compare_length; i++) { + if (oid[i] != compare[i]) + return false; + } + return true; + }; + for (; reference_chain; reference_chain = reference_chain->root) { + if (reference_chain->oid) + if (is_oid(reference_chain->oid, 16, lookup, lookup_length)) + return true; + } + return false; +} + static bool _set_algorithm(CertificateKeyAlgorithm& algorithm, const u8* value, size_t length) { if (length == 7) { @@ -267,6 +286,12 @@ static ssize_t _parse_asn1(const Context& context, Certificate& cert, const u8* if (length == 1) cert.version = buffer[position]; } + if (chain && length > 2) { + if (_asn1_is_oid_in_chain(chain, Constants::san_oid)) { + StringView alt_name { &buffer[position], length }; + cert.SAN.append(alt_name); + } + } // print_buffer(ByteBuffer::wrap(const_cast<u8*>(buffer) + position, length)); break; case 0x03: @@ -788,9 +813,12 @@ Optional<size_t> TLSv12::verify_chain_and_get_matching_certificate(const StringV for (size_t i = 0; i < m_context.certificates.size(); ++i) { auto& cert = m_context.certificates[i]; - // FIXME: Also check against SAN (oid 2.5.29.17). if (wildcard_matches(host, cert.subject)) return i; + for (auto& san : cert.SAN) { + if (wildcard_matches(host, san)) + return i; + } } return {}; |