531
547
/* not found a matching name */
551
static int tls_check_preauth (const gnutls_datum_t *certdata,
552
gnutls_certificate_status certstat,
553
const char *hostname, int chainidx, int* certerr,
556
gnutls_x509_crt cert;
558
*certerr = CERTERR_VALID;
561
if (gnutls_x509_crt_init (&cert) < 0)
563
mutt_error (_("Error initialising gnutls certificate data"));
568
if (gnutls_x509_crt_import (cert, certdata, GNUTLS_X509_FMT_DER) < 0)
570
mutt_error (_("Error processing certificate data"));
572
gnutls_x509_crt_deinit (cert);
576
if (option (OPTSSLVERIFYDATES) != M_NO)
578
if (gnutls_x509_crt_get_expiration_time (cert) < time(NULL))
579
*certerr |= CERTERR_EXPIRED;
580
if (gnutls_x509_crt_get_activation_time (cert) > time(NULL))
581
*certerr |= CERTERR_NOTYETVALID;
584
if (chainidx == 0 && option (OPTSSLVERIFYHOST) != M_NO
585
&& !gnutls_x509_crt_check_hostname (cert, hostname)
586
&& !tls_check_stored_hostname (certdata, hostname))
587
*certerr |= CERTERR_HOSTNAME;
589
/* see whether certificate is in our cache (certificates file) */
590
if (tls_compare_certificates (certdata))
594
if (chainidx == 0 && certstat & GNUTLS_CERT_INVALID)
596
/* doesn't matter - have decided is valid because server
597
certificate is in our trusted cache */
598
certstat ^= GNUTLS_CERT_INVALID;
601
if (chainidx == 0 && certstat & GNUTLS_CERT_SIGNER_NOT_FOUND)
603
/* doesn't matter that we haven't found the signer, since
604
certificate is in our trusted cache */
605
certstat ^= GNUTLS_CERT_SIGNER_NOT_FOUND;
608
if (chainidx <= 1 && certstat & GNUTLS_CERT_SIGNER_NOT_CA)
610
/* Hmm. Not really sure how to handle this, but let's say
611
that we don't care if the CA certificate hasn't got the
612
correct X.509 basic constraints if server or first signer
613
certificate is in our cache. */
614
certstat ^= GNUTLS_CERT_SIGNER_NOT_CA;
617
if (chainidx == 0 && certstat & GNUTLS_CERT_INSECURE_ALGORITHM)
619
/* doesn't matter that it was signed using an insecure
620
algorithm, since certificate is in our trusted cache */
621
certstat ^= GNUTLS_CERT_INSECURE_ALGORITHM;
625
if (certstat & GNUTLS_CERT_REVOKED)
627
*certerr |= CERTERR_REVOKED;
628
certstat ^= GNUTLS_CERT_REVOKED;
631
if (certstat & GNUTLS_CERT_INVALID)
633
*certerr |= CERTERR_NOTTRUSTED;
634
certstat ^= GNUTLS_CERT_INVALID;
637
if (certstat & GNUTLS_CERT_SIGNER_NOT_FOUND)
639
/* NB: already cleared if cert in cache */
640
*certerr |= CERTERR_NOTTRUSTED;
641
certstat ^= GNUTLS_CERT_SIGNER_NOT_FOUND;
644
if (certstat & GNUTLS_CERT_SIGNER_NOT_CA)
646
/* NB: already cleared if cert in cache */
647
*certerr |= CERTERR_SIGNERNOTCA;
648
certstat ^= GNUTLS_CERT_SIGNER_NOT_CA;
651
if (certstat & GNUTLS_CERT_INSECURE_ALGORITHM)
653
/* NB: already cleared if cert in cache */
654
*certerr |= CERTERR_INSECUREALG;
655
certstat ^= GNUTLS_CERT_INSECURE_ALGORITHM;
658
gnutls_x509_crt_deinit (cert);
660
/* we've been zeroing the interesting bits in certstat -
661
don't return OK if there are any unhandled bits we don't
663
if (*certerr == CERTERR_VALID && certstat == 0)
535
669
static int tls_check_one_certificate (const gnutls_datum_t *certdata,
536
670
gnutls_certificate_status certstat,
537
671
const char* hostname, int idx, int len)
673
int certerr, savedcert;
539
674
gnutls_x509_crt cert;
540
int certerr_hostname = 0;
541
int certerr_expired = 0;
542
int certerr_notyetvalid = 0;
543
int certerr_nottrusted = 0;
544
int certerr_revoked = 0;
545
int certerr_signernotca = 0;
546
675
char buf[SHORT_STRING];
547
676
char fpbuf[SHORT_STRING];
562
691
gnutls_datum pemdata;
563
692
int i, row, done, ret;
565
if (gnutls_x509_crt_init (&cert) < 0)
567
mutt_error (_("Error initialising gnutls certificate data"));
572
if (gnutls_x509_crt_import (cert, certdata, GNUTLS_X509_FMT_DER) < 0)
574
mutt_error (_("Error processing certificate data"));
576
gnutls_x509_crt_deinit (cert);
580
if (gnutls_x509_crt_get_expiration_time (cert) < time(NULL))
582
if (gnutls_x509_crt_get_activation_time (cert) > time(NULL))
583
certerr_notyetvalid = 1;
587
if (!gnutls_x509_crt_check_hostname (cert, hostname) &&
588
!tls_check_stored_hostname (certdata, hostname))
589
certerr_hostname = 1;
592
/* see whether certificate is in our cache (certificates file) */
593
if (tls_compare_certificates (certdata))
595
if (certstat & GNUTLS_CERT_INVALID)
597
/* doesn't matter - have decided is valid because server
598
certificate is in our trusted cache */
599
certstat ^= GNUTLS_CERT_INVALID;
602
if (certstat & GNUTLS_CERT_SIGNER_NOT_FOUND)
604
/* doesn't matter that we haven't found the signer, since
605
certificate is in our trusted cache */
606
certstat ^= GNUTLS_CERT_SIGNER_NOT_FOUND;
609
if (certstat & GNUTLS_CERT_SIGNER_NOT_CA)
611
/* Hmm. Not really sure how to handle this, but let's say
612
that we don't care if the CA certificate hasn't got the
613
correct X.509 basic constraints if server certificate is
615
certstat ^= GNUTLS_CERT_SIGNER_NOT_CA;
619
if (certstat & GNUTLS_CERT_REVOKED)
622
certstat ^= GNUTLS_CERT_REVOKED;
625
if (certstat & GNUTLS_CERT_INVALID)
627
certerr_nottrusted = 1;
628
certstat ^= GNUTLS_CERT_INVALID;
631
if (certstat & GNUTLS_CERT_SIGNER_NOT_FOUND)
633
/* NB: already cleared if cert in cache */
634
certerr_nottrusted = 1;
635
certstat ^= GNUTLS_CERT_SIGNER_NOT_FOUND;
638
if (certstat & GNUTLS_CERT_SIGNER_NOT_CA)
640
/* NB: already cleared if cert in cache */
641
certerr_signernotca = 1;
642
certstat ^= GNUTLS_CERT_SIGNER_NOT_CA;
645
/* OK if signed by (or is) a trusted certificate */
646
/* we've been zeroing the interesting bits in certstat -
647
don't return OK if there are any unhandled bits we don't
649
if (!(certerr_expired || certerr_notyetvalid ||
650
certerr_hostname || certerr_nottrusted) && certstat == 0)
652
gnutls_x509_crt_deinit (cert);
694
if (!tls_check_preauth (certdata, certstat, hostname, idx, &certerr,
698
/* skip signers if insecure algorithm was used */
699
if (idx && (certerr & CERTERR_INSECUREALG))
703
mutt_error (_("Warning: Server certificate was signed using an insecure algorithm"));
656
709
/* interactive check from user */
710
if (gnutls_x509_crt_init (&cert) < 0)
712
mutt_error (_("Error initialising gnutls certificate data"));
717
if (gnutls_x509_crt_import (cert, certdata, GNUTLS_X509_FMT_DER) < 0)
719
mutt_error (_("Error processing certificate data"));
721
gnutls_x509_crt_deinit (cert);
657
725
menu = mutt_new_menu (-1);
659
727
menu->dialog = (char **) safe_calloc (1, menu->max * sizeof (char *));
660
728
for (i = 0; i < menu->max; i++)
661
729
menu->dialog[i] = (char *) safe_calloc (1, SHORT_STRING * sizeof (char));
664
732
strfcpy (menu->dialog[row], _("This certificate belongs to:"), SHORT_STRING);
667
735
buflen = sizeof (dn_common_name);
668
736
if (gnutls_x509_crt_get_dn_by_oid (cert, GNUTLS_OID_X520_COMMON_NAME, 0, 0,
669
737
dn_common_name, &buflen) != 0)
692
760
if (gnutls_x509_crt_get_dn_by_oid (cert, GNUTLS_OID_X520_COUNTRY_NAME, 0, 0,
693
761
dn_country, &buflen) != 0)
694
762
dn_country[0] = '\0';
696
764
snprintf (menu->dialog[row++], SHORT_STRING, " %s %s", dn_common_name, dn_email);
697
765
snprintf (menu->dialog[row++], SHORT_STRING, " %s", dn_organization);
698
766
snprintf (menu->dialog[row++], SHORT_STRING, " %s", dn_organizational_unit);
699
767
snprintf (menu->dialog[row++], SHORT_STRING, " %s %s %s",
700
768
dn_locality, dn_province, dn_country);
703
771
strfcpy (menu->dialog[row], _("This certificate was issued by:"), SHORT_STRING);
706
774
buflen = sizeof (dn_common_name);
707
775
if (gnutls_x509_crt_get_issuer_dn_by_oid (cert, GNUTLS_OID_X520_COMMON_NAME, 0, 0,
708
776
dn_common_name, &buflen) != 0)
731
799
if (gnutls_x509_crt_get_issuer_dn_by_oid (cert, GNUTLS_OID_X520_COUNTRY_NAME, 0, 0,
732
800
dn_country, &buflen) != 0)
733
801
dn_country[0] = '\0';
735
803
snprintf (menu->dialog[row++], SHORT_STRING, " %s %s", dn_common_name, dn_email);
736
804
snprintf (menu->dialog[row++], SHORT_STRING, " %s", dn_organization);
737
805
snprintf (menu->dialog[row++], SHORT_STRING, " %s", dn_organizational_unit);
738
806
snprintf (menu->dialog[row++], SHORT_STRING, " %s %s %s",
739
807
dn_locality, dn_province, dn_country);
742
810
snprintf (menu->dialog[row++], SHORT_STRING, _("This certificate is valid"));
744
812
t = gnutls_x509_crt_get_activation_time (cert);
745
snprintf (menu->dialog[row++], SHORT_STRING, _(" from %s"),
813
snprintf (menu->dialog[row++], SHORT_STRING, _(" from %s"),
746
814
tls_make_date (t, datestr, 30));
748
816
t = gnutls_x509_crt_get_expiration_time (cert);
749
snprintf (menu->dialog[row++], SHORT_STRING, _(" to %s"),
817
snprintf (menu->dialog[row++], SHORT_STRING, _(" to %s"),
750
818
tls_make_date (t, datestr, 30));
753
821
tls_fingerprint (GNUTLS_DIG_SHA, fpbuf, sizeof (fpbuf), certdata);
754
822
snprintf (menu->dialog[row++], SHORT_STRING, _("SHA1 Fingerprint: %s"), fpbuf);
756
824
tls_fingerprint (GNUTLS_DIG_MD5, fpbuf, sizeof (fpbuf), certdata);
757
825
snprintf (menu->dialog[row++], SHORT_STRING, _("MD5 Fingerprint: %s"), fpbuf);
759
if (certerr_notyetvalid)
827
if (certerr & CERTERR_NOTYETVALID)
762
830
strfcpy (menu->dialog[row], _("WARNING: Server certificate is not yet valid"), SHORT_STRING);
832
if (certerr & CERTERR_EXPIRED)
767
835
strfcpy (menu->dialog[row], _("WARNING: Server certificate has expired"), SHORT_STRING);
837
if (certerr & CERTERR_REVOKED)
772
840
strfcpy (menu->dialog[row], _("WARNING: Server certificate has been revoked"), SHORT_STRING);
774
if (certerr_hostname)
842
if (certerr & CERTERR_HOSTNAME)
777
845
strfcpy (menu->dialog[row], _("WARNING: Server hostname does not match certificate"), SHORT_STRING);
779
if (certerr_signernotca)
847
if (certerr & CERTERR_SIGNERNOTCA)
782
850
strfcpy (menu->dialog[row], _("WARNING: Signer of server certificate is not a CA"), SHORT_STRING);
866
936
return (done == 2);
869
static int tls_check_certificate (CONNECTION* conn)
939
/* sanity-checking wrapper for gnutls_certificate_verify_peers */
940
static gnutls_certificate_status tls_verify_peers (gnutls_session tlsstate)
871
tlssockdata *data = conn->sockdata;
872
gnutls_session state = data->state;
873
const gnutls_datum *cert_list;
874
unsigned int cert_list_size = 0;
875
942
gnutls_certificate_status certstat;
878
if (gnutls_auth_get_type (state) != GNUTLS_CRD_CERTIFICATE)
880
mutt_error (_("Unable to get certificate from peer"));
885
certstat = gnutls_certificate_verify_peers (state);
944
certstat = gnutls_certificate_verify_peers (tlsstate);
887
948
if (certstat == GNUTLS_E_NO_CERTIFICATE_FOUND)
901
962
/* We only support X.509 certificates (not OpenPGP) at the moment */
902
if (gnutls_certificate_type_get (state) != GNUTLS_CRT_X509)
963
if (gnutls_certificate_type_get (tlsstate) != GNUTLS_CRT_X509)
904
965
mutt_error (_("Certificate is not X.509"));
973
static int tls_check_certificate (CONNECTION* conn)
975
tlssockdata *data = conn->sockdata;
976
gnutls_session state = data->state;
977
const gnutls_datum *cert_list;
978
unsigned int cert_list_size = 0;
979
gnutls_certificate_status certstat;
980
int certerr, i, preauthrc, savedcert, rc = 0;
982
if (gnutls_auth_get_type (state) != GNUTLS_CRD_CERTIFICATE)
984
mutt_error (_("Unable to get certificate from peer"));
989
certstat = tls_verify_peers (state);
909
991
cert_list = gnutls_certificate_get_peers (state, &cert_list_size);
999
/* tls_verify_peers doesn't check hostname or expiration, so walk
1000
* from most specific to least checking these. If we see a saved certificate,
1001
* its status short-circuits the remaining checks. */
1003
for (i = 0; i < cert_list_size; i++) {
1004
rc = tls_check_preauth(&cert_list[i], certstat, conn->account.host, i,
1005
&certerr, &savedcert);
1017
/* then check interactively, starting from chain root */
917
1018
for (i = cert_list_size - 1; i >= 0; i--)
919
1020
rc = tls_check_one_certificate (&cert_list[i], certstat, conn->account.host,
920
1021
i, cert_list_size);
1023
/* add signers to trust set, then reverify */
1025
rc = gnutls_certificate_set_x509_trust_mem (data->xcred, &cert_list[i],
1026
GNUTLS_X509_FMT_DER);
1028
dprint (1, (debugfile, "error trusting certificate %d: %d\n", i, rc));
1030
certstat = tls_verify_peers (state);