From 5f46d552b98be7dc9c5669ed02bd02d304526b4e Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Thu, 24 Mar 2022 14:03:47 +0100 Subject: [PATCH] Allow exceptions for expired certificates The browsers allow users to make an exception for expired certificates, so we should probably also. --- common/rfb/CSecurityTLS.cxx | 75 +++++++++++++++++++++++++++---------- 1 file changed, 55 insertions(+), 20 deletions(-) diff --git a/common/rfb/CSecurityTLS.cxx b/common/rfb/CSecurityTLS.cxx index d0af1410..54d995b1 100644 --- a/common/rfb/CSecurityTLS.cxx +++ b/common/rfb/CSecurityTLS.cxx @@ -309,7 +309,8 @@ void CSecurityTLS::checkSession() { const unsigned allowed_errors = GNUTLS_CERT_INVALID | GNUTLS_CERT_SIGNER_NOT_FOUND | - GNUTLS_CERT_SIGNER_NOT_CA; + GNUTLS_CERT_SIGNER_NOT_CA | + GNUTLS_CERT_EXPIRED; unsigned int status; const gnutls_datum_t *cert_list; unsigned int cert_list_size = 0; @@ -381,6 +382,8 @@ void CSecurityTLS::checkSession() vlog.debug("server cert signer not found"); if (status & GNUTLS_CERT_SIGNER_NOT_CA) vlog.debug("server cert signer not CA"); + if (status & GNUTLS_CERT_EXPIRED) + vlog.debug("server certificate has expired"); if (status & GNUTLS_CERT_INSECURE_ALGORITHM) throw AuthFailureException("The server certificate uses an insecure algorithm"); @@ -435,33 +438,65 @@ void CSecurityTLS::checkSession() vlog.debug("Server host not previously known"); vlog.debug("%s", info.data); - text.format("This certificate has been signed by an unknown " - "authority:\n\n%s\n\nSomeone could be trying to " - "impersonate the site and you should not " - "continue.\n\nDo you want to make an exception " - "for this server?", info.data); + if (status & (GNUTLS_CERT_SIGNER_NOT_FOUND | + GNUTLS_CERT_SIGNER_NOT_CA)) { + text.format("This certificate has been signed by an unknown " + "authority:\n\n%s\n\nSomeone could be trying to " + "impersonate the site and you should not " + "continue.\n\nDo you want to make an exception " + "for this server?", info.data); + + if (!msg->showMsgBox(UserMsgBox::M_YESNO, + "Unknown certificate issuer", + text.buf)) + throw AuthFailureException("Unknown certificate issuer"); + } + + if (status & GNUTLS_CERT_EXPIRED) { + text.format("This certificate has expired:\n\n%s\n\nSomeone " + "could be trying to impersonate the site and you " + "should not continue.\n\nDo you want to make an " + "exception for this server?", info.data); - if (!msg->showMsgBox(UserMsgBox::M_YESNO, - "Unknown certificate issuer", - text.buf)) - throw AuthFailureException("Unknown certificate issuer"); + if (!msg->showMsgBox(UserMsgBox::M_YESNO, + "Expired certificate", + text.buf)) + throw AuthFailureException("Expired certificate"); + } } else if (err == GNUTLS_E_CERTIFICATE_KEY_MISMATCH) { CharArray text; vlog.debug("Server host key mismatch"); vlog.debug("%s", info.data); - text.format("This host is previously known with a different " - "certificate, and the new certificate has been " - "signed by an unknown authority:\n\n%s\n\nSomeone " - "could be trying to impersonate the site and you " - "should not continue.\n\nDo you want to make an " - "exception for this server?", info.data); + if (status & (GNUTLS_CERT_SIGNER_NOT_FOUND | + GNUTLS_CERT_SIGNER_NOT_CA)) { + text.format("This host is previously known with a different " + "certificate, and the new certificate has been " + "signed by an unknown authority:\n\n%s\n\nSomeone " + "could be trying to impersonate the site and you " + "should not continue.\n\nDo you want to make an " + "exception for this server?", info.data); + + if (!msg->showMsgBox(UserMsgBox::M_YESNO, + "Unexpected server certificate", + text.buf)) + throw AuthFailureException("Unexpected server certificate"); + } - if (!msg->showMsgBox(UserMsgBox::M_YESNO, - "Unexpected server certificate", - text.buf)) - throw AuthFailureException("Unexpected server certificate"); + if (status & GNUTLS_CERT_EXPIRED) { + text.format("This host is previously known with a different " + "certificate, and the new certificate has expired:" + "\n\n%s\n\nSomeone could be trying to impersonate " + "the site and you should not continue.\n\nDo you " + "want to make an exception for this server?", + info.data); + + if (!msg->showMsgBox(UserMsgBox::M_YESNO, + "Unexpected server certificate", + text.buf)) + throw AuthFailureException("Unexpected server certificate"); + } } if (gnutls_store_pubkey(dbPath.buf, NULL, client->getServerName(), -- 2.39.5