From: Kevin McCarthy Date: Wed, 8 Mar 2017 02:26:07 +0000 (-0800) Subject: Don't allow storing duplicate certs for OpenSSL interactive prompt. (closes #3914) X-Git-Tag: mutt-1-9-rel~146 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=2f512db10b44e808ef509e1f35c937b0488711ba;p=mutt Don't allow storing duplicate certs for OpenSSL interactive prompt. (closes #3914) Check to make sure the certificate is not already in the $certificate_file before offering the (a)ccept always option. To allow a cert with a new validity timespan to be added to the file, check the expiration dates when comparing certificates in the certficate file. --- diff --git a/mutt_ssl.c b/mutt_ssl.c index 82a23767..2ca21dda 100644 --- a/mutt_ssl.c +++ b/mutt_ssl.c @@ -795,33 +795,46 @@ static int check_certificate_cache (X509 *peercert) return 0; } -static int check_certificate_by_digest (X509 *peercert) +static int check_certificate_expiration (X509 *peercert, int silent) { - unsigned char peermd[EVP_MAX_MD_SIZE]; - unsigned int peermdlen; - X509 *cert = NULL; - int pass = 0; - FILE *fp; - - /* expiration check */ if (option (OPTSSLVERIFYDATES) != MUTT_NO) { if (X509_cmp_current_time (X509_get_notBefore (peercert)) >= 0) { - dprint (2, (debugfile, "Server certificate is not yet valid\n")); - mutt_error (_("Server certificate is not yet valid")); - mutt_sleep (2); + if (!silent) + { + dprint (2, (debugfile, "Server certificate is not yet valid\n")); + mutt_error (_("Server certificate is not yet valid")); + mutt_sleep (2); + } return 0; } if (X509_cmp_current_time (X509_get_notAfter (peercert)) <= 0) { - dprint (2, (debugfile, "Server certificate has expired\n")); - mutt_error (_("Server certificate has expired")); - mutt_sleep (2); + if (!silent) + { + dprint (2, (debugfile, "Server certificate has expired\n")); + mutt_error (_("Server certificate has expired")); + mutt_sleep (2); + } return 0; } } + return 1; +} + +static int check_certificate_file (X509 *peercert) +{ + unsigned char peermd[EVP_MAX_MD_SIZE]; + unsigned int peermdlen; + X509 *cert = NULL; + int pass = 0; + FILE *fp; + + if (!SslCertFile) + return 0; + if ((fp = fopen (SslCertFile, "rt")) == NULL) return 0; @@ -833,10 +846,12 @@ static int check_certificate_by_digest (X509 *peercert) while (PEM_read_X509 (fp, &cert, NULL, NULL) != NULL) { - pass = compare_certificates (cert, peercert, peermd, peermdlen) ? 0 : 1; - - if (pass) + if ((compare_certificates (cert, peercert, peermd, peermdlen) == 0) && + check_certificate_expiration (cert, 1)) + { + pass = 1; break; + } } /* PEM_read_X509 sets an error on eof */ if (!pass) @@ -847,6 +862,12 @@ static int check_certificate_by_digest (X509 *peercert) return pass; } +static int check_certificate_by_digest (X509 *peercert) +{ + return check_certificate_expiration (peercert, 0) && + check_certificate_file (peercert); +} + /* port to mutt from msmtp's tls.c */ static int hostname_match (const char *hostname, const char *certname) { @@ -1161,10 +1182,9 @@ static int interactive_check_cert (X509 *cert, int idx, int len, SSL *ssl) * an OpenSSL connection. */ menu->keys = _("roas"); - if (SslCertFile - && (option (OPTSSLVERIFYDATES) == MUTT_NO - || (X509_cmp_current_time (X509_get_notAfter (cert)) >= 0 - && X509_cmp_current_time (X509_get_notBefore (cert)) < 0))) + if (SslCertFile && + check_certificate_expiration (cert, 1) && + !check_certificate_file (cert)) { allow_always = 1; if (allow_skip)