diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/gmcerts.c | 26 | ||||
-rw-r--r-- | src/gmrequest.c | 10 | ||||
-rw-r--r-- | src/gmutil.c | 6 | ||||
-rw-r--r-- | src/gmutil.h | 1 | ||||
-rw-r--r-- | src/ui/documentwidget.c | 38 |
5 files changed, 60 insertions, 21 deletions
diff --git a/src/gmcerts.c b/src/gmcerts.c index 32e47b40..d8e77b12 100644 --- a/src/gmcerts.c +++ b/src/gmcerts.c | |||
@@ -456,13 +456,8 @@ iBool checkTrust_GmCerts(iGmCerts *d, iRangecc domain, uint16_t port, const iTls | |||
456 | if (!cert) { | 456 | if (!cert) { |
457 | return iFalse; | 457 | return iFalse; |
458 | } | 458 | } |
459 | if (isExpired_TlsCertificate(cert)) { | ||
460 | return iFalse; | ||
461 | } | ||
462 | /* We trust CA verification implicitly. */ | 459 | /* We trust CA verification implicitly. */ |
463 | //const iBool isAuth = verify_TlsCertificate(cert) == authority_TlsCertificateVerifyStatus; | 460 | if (!verifyDomain_GmCerts(cert, domain)) { |
464 | // const iBool isAuth = iFalse; /* CA verification done during handshake */ | ||
465 | if (/*!isAuth &&*/ !verifyDomain_GmCerts(cert, domain)) { | ||
466 | return iFalse; | 461 | return iFalse; |
467 | } | 462 | } |
468 | /* TODO: Could call setTrusted_GmCerts() instead of duplicating the trust-setting. */ | 463 | /* TODO: Could call setTrusted_GmCerts() instead of duplicating the trust-setting. */ |
@@ -474,11 +469,12 @@ iBool checkTrust_GmCerts(iGmCerts *d, iRangecc domain, uint16_t port, const iTls | |||
474 | init_String(&key); | 469 | init_String(&key); |
475 | makeTrustKey_(domain, port, &key); | 470 | makeTrustKey_(domain, port, &key); |
476 | lock_Mutex(d->mtx); | 471 | lock_Mutex(d->mtx); |
472 | iBool ok = !isExpired_TlsCertificate(cert); | ||
477 | iTrustEntry *trust = value_StringHash(d->trusted, &key); | 473 | iTrustEntry *trust = value_StringHash(d->trusted, &key); |
478 | if (trust) { | 474 | if (trust) { |
479 | /* We already have it, check if it matches the one we trust for this domain (if it's | 475 | /* We already have it, check if it matches the one we trust for this domain (if it's |
480 | still valid. */ | 476 | still valid. */ |
481 | if (/*!isAuth && */elapsedSeconds_Time(&trust->validUntil) < 0) { | 477 | if (elapsedSeconds_Time(&trust->validUntil) < 0) { |
482 | /* Trusted cert is still valid. */ | 478 | /* Trusted cert is still valid. */ |
483 | const iBool isTrusted = cmp_Block(fingerprint, &trust->fingerprint) == 0; | 479 | const iBool isTrusted = cmp_Block(fingerprint, &trust->fingerprint) == 0; |
484 | unlock_Mutex(d->mtx); | 480 | unlock_Mutex(d->mtx); |
@@ -487,17 +483,23 @@ iBool checkTrust_GmCerts(iGmCerts *d, iRangecc domain, uint16_t port, const iTls | |||
487 | return isTrusted; | 483 | return isTrusted; |
488 | } | 484 | } |
489 | /* Update the trusted cert. */ | 485 | /* Update the trusted cert. */ |
490 | init_Time(&trust->validUntil, &until); | 486 | if (ok) { |
491 | set_Block(&trust->fingerprint, fingerprint); | 487 | init_Time(&trust->validUntil, &until); |
488 | set_Block(&trust->fingerprint, fingerprint); | ||
489 | } | ||
492 | } | 490 | } |
493 | else { | 491 | else { |
494 | insert_StringHash(d->trusted, &key, iClob(new_TrustEntry(fingerprint, &until))); | 492 | if (ok) { |
493 | insert_StringHash(d->trusted, &key, iClob(new_TrustEntry(fingerprint, &until))); | ||
494 | } | ||
495 | } | ||
496 | if (ok) { | ||
497 | save_GmCerts_(d); | ||
495 | } | 498 | } |
496 | save_GmCerts_(d); | ||
497 | unlock_Mutex(d->mtx); | 499 | unlock_Mutex(d->mtx); |
498 | delete_Block(fingerprint); | 500 | delete_Block(fingerprint); |
499 | deinit_String(&key); | 501 | deinit_String(&key); |
500 | return iTrue; | 502 | return ok; |
501 | } | 503 | } |
502 | 504 | ||
503 | void setTrusted_GmCerts(iGmCerts *d, iRangecc domain, uint16_t port, const iBlock *fingerprint, | 505 | void setTrusted_GmCerts(iGmCerts *d, iRangecc domain, uint16_t port, const iBlock *fingerprint, |
diff --git a/src/gmrequest.c b/src/gmrequest.c index 9b640cee..44ef063f 100644 --- a/src/gmrequest.c +++ b/src/gmrequest.c | |||
@@ -290,8 +290,14 @@ static void requestFinished_GmRequest_(iGmRequest *d, iTlsRequest *req) { | |||
290 | : finished_GmRequestState); | 290 | : finished_GmRequestState); |
291 | if (d->state == failure_GmRequestState) { | 291 | if (d->state == failure_GmRequestState) { |
292 | if (!isVerified_TlsRequest(req)) { | 292 | if (!isVerified_TlsRequest(req)) { |
293 | d->resp->statusCode = tlsServerCertificateNotVerified_GmStatusCode; | 293 | if (isExpired_TlsCertificate(serverCertificate_TlsRequest(req))) { |
294 | setCStr_String(&d->resp->meta, "Server certificate could not be verified"); | 294 | d->resp->statusCode = tlsServerCertificateExpired_GmStatusCode; |
295 | setCStr_String(&d->resp->meta, "Server certificate has expired"); | ||
296 | } | ||
297 | else { | ||
298 | d->resp->statusCode = tlsServerCertificateNotVerified_GmStatusCode; | ||
299 | setCStr_String(&d->resp->meta, "Server certificate could not be verified"); | ||
300 | } | ||
295 | } | 301 | } |
296 | else { | 302 | else { |
297 | d->resp->statusCode = tlsFailure_GmStatusCode; | 303 | d->resp->statusCode = tlsFailure_GmStatusCode; |
diff --git a/src/gmutil.c b/src/gmutil.c index 0ae0861c..fda8489b 100644 --- a/src/gmutil.c +++ b/src/gmutil.c | |||
@@ -682,8 +682,12 @@ static const struct { | |||
682 | { 0x1f5a7, /* networked computers */ | 682 | { 0x1f5a7, /* networked computers */ |
683 | "${error.tls}", | 683 | "${error.tls}", |
684 | "${error.tls.msg}" } }, | 684 | "${error.tls.msg}" } }, |
685 | { tlsServerCertificateExpired_GmStatusCode, | ||
686 | { 0x1f4C6, /* calendar */ | ||
687 | "${error.certexpired}", | ||
688 | "${error.certexpired.msg}" } }, | ||
685 | { tlsServerCertificateNotVerified_GmStatusCode, | 689 | { tlsServerCertificateNotVerified_GmStatusCode, |
686 | { 0x1f645, | 690 | { 0x1f645, /* no good */ |
687 | "${error.certverify}", | 691 | "${error.certverify}", |
688 | "${error.certverify.msg}" } }, | 692 | "${error.certverify.msg}" } }, |
689 | { temporaryFailure_GmStatusCode, | 693 | { temporaryFailure_GmStatusCode, |
diff --git a/src/gmutil.h b/src/gmutil.h index 1bf41775..f8491781 100644 --- a/src/gmutil.h +++ b/src/gmutil.h | |||
@@ -43,6 +43,7 @@ enum iGmStatusCode { | |||
43 | unknownStatusCode_GmStatusCode, | 43 | unknownStatusCode_GmStatusCode, |
44 | invalidLocalResource_GmStatusCode, | 44 | invalidLocalResource_GmStatusCode, |
45 | tlsFailure_GmStatusCode, | 45 | tlsFailure_GmStatusCode, |
46 | tlsServerCertificateExpired_GmStatusCode, | ||
46 | tlsServerCertificateNotVerified_GmStatusCode, | 47 | tlsServerCertificateNotVerified_GmStatusCode, |
47 | 48 | ||
48 | none_GmStatusCode = 0, | 49 | none_GmStatusCode = 0, |
diff --git a/src/ui/documentwidget.c b/src/ui/documentwidget.c index 4a4101b1..f0ee9823 100644 --- a/src/ui/documentwidget.c +++ b/src/ui/documentwidget.c | |||
@@ -1135,7 +1135,18 @@ static void showErrorPage_DocumentWidget_(iDocumentWidget *d, enum iGmStatusCode | |||
1135 | useBanner = iFalse; /* valid data wasn't received from host */ | 1135 | useBanner = iFalse; /* valid data wasn't received from host */ |
1136 | appendFormat_String(src, "\n\n>%s\n", cstr_String(meta)); | 1136 | appendFormat_String(src, "\n\n>%s\n", cstr_String(meta)); |
1137 | break; | 1137 | break; |
1138 | /* fall through */ | 1138 | case tlsServerCertificateExpired_GmStatusCode: |
1139 | makeFooterButtons_DocumentWidget_( | ||
1140 | d, | ||
1141 | (iMenuItem[]){ { rightArrowhead_Icon " Ignore Expiry and Continue Loading", | ||
1142 | 0, 0, "server.unexpire" | ||
1143 | }, | ||
1144 | { info_Icon " ${menu.pageinfo}", | ||
1145 | SDLK_i, | ||
1146 | KMOD_PRIMARY, | ||
1147 | "document.info" } }, | ||
1148 | 2); | ||
1149 | break; | ||
1139 | case tlsServerCertificateNotVerified_GmStatusCode: | 1150 | case tlsServerCertificateNotVerified_GmStatusCode: |
1140 | makeFooterButtons_DocumentWidget_( | 1151 | makeFooterButtons_DocumentWidget_( |
1141 | d, | 1152 | d, |
@@ -1575,12 +1586,12 @@ static void updateTrust_DocumentWidget_(iDocumentWidget *d, const iGmResponse *r | |||
1575 | ~d->certFlags & trusted_GmCertFlag) { | 1586 | ~d->certFlags & trusted_GmCertFlag) { |
1576 | updateTextCStr_LabelWidget(lock, red_ColorEscape warning_Icon); | 1587 | updateTextCStr_LabelWidget(lock, red_ColorEscape warning_Icon); |
1577 | } | 1588 | } |
1578 | else if (d->certFlags & trusted_GmCertFlag) { | 1589 | else if (~d->certFlags & timeVerified_GmCertFlag) { |
1579 | updateTextCStr_LabelWidget(lock, green_ColorEscape closedLock_Icon); | 1590 | updateTextCStr_LabelWidget(lock, isDarkMode ? orange_ColorEscape warning_Icon |
1591 | : black_ColorEscape warning_Icon); | ||
1580 | } | 1592 | } |
1581 | else { | 1593 | else { |
1582 | updateTextCStr_LabelWidget(lock, isDarkMode ? orange_ColorEscape warning_Icon | 1594 | updateTextCStr_LabelWidget(lock, green_ColorEscape closedLock_Icon); |
1583 | : black_ColorEscape warning_Icon); | ||
1584 | } | 1595 | } |
1585 | setBanner_GmDocument(d->doc, bannerType_DocumentWidget_(d)); | 1596 | setBanner_GmDocument(d->doc, bannerType_DocumentWidget_(d)); |
1586 | } | 1597 | } |
@@ -2631,12 +2642,27 @@ static iBool handleCommand_DocumentWidget_(iDocumentWidget *d, const char *cmd) | |||
2631 | addAction_Widget(dlg, SDLK_SPACE, 0, "message.ok"); | 2642 | addAction_Widget(dlg, SDLK_SPACE, 0, "message.ok"); |
2632 | return iTrue; | 2643 | return iTrue; |
2633 | } | 2644 | } |
2645 | else if (equal_Command(cmd, "server.unexpire") && document_App() == d) { | ||
2646 | const iRangecc host = urlHost_String(d->mod.url); | ||
2647 | const uint16_t port = urlPort_String(d->mod.url); | ||
2648 | if (!isEmpty_Block(d->certFingerprint) && !isEmpty_Range(&host)) { | ||
2649 | iTime expiry; | ||
2650 | initCurrent_Time(&expiry); | ||
2651 | iTime oneHour; /* One hour is long enough for a single visit (?). */ | ||
2652 | initSeconds_Time(&oneHour, 3600); | ||
2653 | add_Time(&expiry, &oneHour); | ||
2654 | iDate expDate; | ||
2655 | init_Date(&expDate, &expiry); | ||
2656 | setTrusted_GmCerts(certs_App(), host, port, d->certFingerprint, &expDate); | ||
2657 | postCommand_Widget(w, "navigate.reload"); | ||
2658 | } | ||
2659 | return iTrue; | ||
2660 | } | ||
2634 | else if (equal_Command(cmd, "server.trustcert") && document_App() == d) { | 2661 | else if (equal_Command(cmd, "server.trustcert") && document_App() == d) { |
2635 | const iRangecc host = urlHost_String(d->mod.url); | 2662 | const iRangecc host = urlHost_String(d->mod.url); |
2636 | const uint16_t port = urlPort_String(d->mod.url); | 2663 | const uint16_t port = urlPort_String(d->mod.url); |
2637 | if (!isEmpty_Block(d->certFingerprint) && !isEmpty_Range(&host)) { | 2664 | if (!isEmpty_Block(d->certFingerprint) && !isEmpty_Range(&host)) { |
2638 | setTrusted_GmCerts(certs_App(), host, port, d->certFingerprint, &d->certExpiry); | 2665 | setTrusted_GmCerts(certs_App(), host, port, d->certFingerprint, &d->certExpiry); |
2639 | d->certFlags |= trusted_GmCertFlag; | ||
2640 | postCommand_Widget(w, "navigate.reload"); | 2666 | postCommand_Widget(w, "navigate.reload"); |
2641 | } | 2667 | } |
2642 | return iTrue; | 2668 | return iTrue; |