summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/gmcerts.c31
-rw-r--r--src/gmcerts.h2
-rw-r--r--src/gmrequest.c2
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
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. */
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
96void signIn_GmCerts (iGmCerts *, iGmIdentity *identity, const iString *url); 96void signIn_GmCerts (iGmCerts *, iGmIdentity *identity, const iString *url);
97void signOut_GmCerts (iGmCerts *, const iString *url); 97void signOut_GmCerts (iGmCerts *, const iString *url);
98
99iBool 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)) {