summaryrefslogtreecommitdiff
path: root/src/gmcerts.c
diff options
context:
space:
mode:
authorJaakko Keränen <jaakko.keranen@iki.fi>2021-03-26 11:14:57 +0200
committerJaakko Keränen <jaakko.keranen@iki.fi>2021-03-26 11:14:57 +0200
commit1e5dfdc840824723dfa142707aca1f0fca4c0056 (patch)
tree1b2c10b7529381754383e7f0140971f26557263a /src/gmcerts.c
parent2740b24b1ff0c6c5363303fcc35028d471c1ce0e (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/gmcerts.c')
-rw-r--r--src/gmcerts.c31
1 files changed, 30 insertions, 1 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
377static 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
385iBool 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
377iBool checkTrust_GmCerts(iGmCerts *d, iRangecc domain, const iTlsCertificate *cert) { 406iBool 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. */