diff options
author | Jaakko Keränen <jaakko.keranen@iki.fi> | 2021-03-26 11:14:57 +0200 |
---|---|---|
committer | Jaakko Keränen <jaakko.keranen@iki.fi> | 2021-03-26 11:14:57 +0200 |
commit | 1e5dfdc840824723dfa142707aca1f0fca4c0056 (patch) | |
tree | 1b2c10b7529381754383e7f0140971f26557263a /src | |
parent | 2740b24b1ff0c6c5363303fcc35028d471c1ce0e (diff) |
GmCerts: Relaxed domain verification
Allow a certificate for a higher-level domain to be verified against any subdomains, i.e., implicitly assume every certificate uses wildcards.
CA verification is still done separately, and OpenSSL does that strictly as before.
Diffstat (limited to 'src')
-rw-r--r-- | src/gmcerts.c | 31 | ||||
-rw-r--r-- | src/gmcerts.h | 2 | ||||
-rw-r--r-- | src/gmrequest.c | 2 |
3 files changed, 33 insertions, 2 deletions
diff --git a/src/gmcerts.c b/src/gmcerts.c index 6a1ba98c..2cc10a3d 100644 --- a/src/gmcerts.c +++ b/src/gmcerts.c | |||
@@ -374,6 +374,35 @@ void deinit_GmCerts(iGmCerts *d) { | |||
374 | delete_Mutex(d->mtx); | 374 | delete_Mutex(d->mtx); |
375 | } | 375 | } |
376 | 376 | ||
377 | static iRangecc stripFirstDomainLabel_(iRangecc domain) { | ||
378 | iRangecc label = iNullRange; | ||
379 | if (nextSplit_Rangecc(domain, ".", &label) && nextSplit_Rangecc(domain, ".", &label)) { | ||
380 | return (iRangecc){ label.start, domain.end }; | ||
381 | } | ||
382 | return iNullRange; | ||
383 | } | ||
384 | |||
385 | iBool verifyDomain_GmCerts(const iTlsCertificate *cert, iRangecc domain) { | ||
386 | if (verifyDomain_TlsCertificate(cert, domain)) { | ||
387 | return iTrue; | ||
388 | } | ||
389 | /* Allow for an implicit wildcard in the domain name. Self-signed TOFU is really only | ||
390 | about the public/private key pair; any other details should be considered | ||
391 | complementary. */ | ||
392 | for (iRangecc higherDomain = stripFirstDomainLabel_(domain); | ||
393 | !isEmpty_Range(&higherDomain); | ||
394 | higherDomain = stripFirstDomainLabel_(higherDomain)) { | ||
395 | if (!iStrStrN(higherDomain.start, ".", size_Range(&higherDomain))) { | ||
396 | /* Must have two labels at least. */ | ||
397 | break; | ||
398 | } | ||
399 | if (verifyDomain_TlsCertificate(cert, higherDomain)) { | ||
400 | return iTrue; | ||
401 | } | ||
402 | } | ||
403 | return iFalse; | ||
404 | } | ||
405 | |||
377 | iBool checkTrust_GmCerts(iGmCerts *d, iRangecc domain, const iTlsCertificate *cert) { | 406 | iBool checkTrust_GmCerts(iGmCerts *d, iRangecc domain, const iTlsCertificate *cert) { |
378 | if (!cert) { | 407 | if (!cert) { |
379 | return iFalse; | 408 | return iFalse; |
@@ -383,7 +412,7 @@ iBool checkTrust_GmCerts(iGmCerts *d, iRangecc domain, const iTlsCertificate *ce | |||
383 | } | 412 | } |
384 | /* We trust CA verification implicitly. */ | 413 | /* We trust CA verification implicitly. */ |
385 | const iBool isAuth = verify_TlsCertificate(cert) == authority_TlsCertificateVerifyStatus; | 414 | const iBool isAuth = verify_TlsCertificate(cert) == authority_TlsCertificateVerifyStatus; |
386 | if (!isAuth && !verifyDomain_TlsCertificate(cert, domain)) { | 415 | if (!isAuth && !verifyDomain_GmCerts(cert, domain)) { |
387 | return iFalse; | 416 | return iFalse; |
388 | } | 417 | } |
389 | /* TODO: Could call setTrusted_GmCerts() instead of duplicating the trust-setting. */ | 418 | /* TODO: Could call setTrusted_GmCerts() instead of duplicating the trust-setting. */ |
diff --git a/src/gmcerts.h b/src/gmcerts.h index a28c050e..a9859845 100644 --- a/src/gmcerts.h +++ b/src/gmcerts.h | |||
@@ -95,3 +95,5 @@ const iPtrArray * listIdentities_GmCerts (const iGmCerts *, iGmCertsIdentityF | |||
95 | 95 | ||
96 | void signIn_GmCerts (iGmCerts *, iGmIdentity *identity, const iString *url); | 96 | void signIn_GmCerts (iGmCerts *, iGmIdentity *identity, const iString *url); |
97 | void signOut_GmCerts (iGmCerts *, const iString *url); | 97 | void signOut_GmCerts (iGmCerts *, const iString *url); |
98 | |||
99 | iBool verifyDomain_GmCerts (const iTlsCertificate *cert, iRangecc domain); | ||
diff --git a/src/gmrequest.c b/src/gmrequest.c index f065f935..c968990c 100644 --- a/src/gmrequest.c +++ b/src/gmrequest.c | |||
@@ -157,7 +157,7 @@ static void checkServerCertificate_GmRequest_(iGmRequest *d) { | |||
157 | if (!isExpired_TlsCertificate(cert)) { | 157 | if (!isExpired_TlsCertificate(cert)) { |
158 | resp->certFlags |= timeVerified_GmCertFlag; | 158 | resp->certFlags |= timeVerified_GmCertFlag; |
159 | } | 159 | } |
160 | if (verifyDomain_TlsCertificate(cert, domain)) { | 160 | if (verifyDomain_GmCerts(cert, domain)) { |
161 | resp->certFlags |= domainVerified_GmCertFlag; | 161 | resp->certFlags |= domainVerified_GmCertFlag; |
162 | } | 162 | } |
163 | if (checkTrust_GmCerts(d->certs, domain, cert)) { | 163 | if (checkTrust_GmCerts(d->certs, domain, cert)) { |