summaryrefslogtreecommitdiff
path: root/Libraries/LibTLS
diff options
context:
space:
mode:
authorAnotherTest <ali.mpfard@gmail.com>2020-12-13 22:25:09 +0330
committerAndreas Kling <kling@serenityos.org>2020-12-13 20:24:58 +0100
commitdbfce38c90b2aa6851c1c83460c9bb9ab87ca774 (patch)
tree317320390671a20954ae9b69d33749d48a5717c6 /Libraries/LibTLS
parent48589db3aab2085ec4e5729fcf8f1a4a8a66067f (diff)
downloadserenity-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.h3
-rw-r--r--Libraries/LibTLS/TLSv12.cpp32
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 {};