Mercurial > pidgin
comparison libpurple/plugins/ssl/ssl-gnutls.c @ 30959:43af903bd816
NSS will not return invalid or irrelevant intermediate certificates
that the server presented as part of the certificate chain. GnuTLS,
however, will return them, which breaks our certificate validation
when the server is mis-configured.
This fixes our GnuTLS SSL plugin to discard any certificate (and
subsequent certs) in the chain if it did not sign the previous
certificate. This allows GnuTLS users to connect to
omega.contacts.msn.com while it is still misconfigured.
author | Stu Tomlinson <stu@nosnilmot.com> |
---|---|
date | Tue, 23 Nov 2010 01:50:30 +0000 |
parents | df9de37e0274 |
children | fb0c5aa0fe55 |
comparison
equal
deleted
inserted
replaced
30958:a467e55ec3c7 | 30959:43af903bd816 |
---|---|
518 } | 518 } |
519 | 519 |
520 /* Forward declarations are fun! */ | 520 /* Forward declarations are fun! */ |
521 static PurpleCertificate * | 521 static PurpleCertificate * |
522 x509_import_from_datum(const gnutls_datum dt, gnutls_x509_crt_fmt mode); | 522 x509_import_from_datum(const gnutls_datum dt, gnutls_x509_crt_fmt mode); |
523 /* indeed! */ | |
524 static gboolean | |
525 x509_certificate_signed_by(PurpleCertificate * crt, | |
526 PurpleCertificate * issuer); | |
527 static void | |
528 x509_destroy_certificate(PurpleCertificate * crt); | |
523 | 529 |
524 static GList * | 530 static GList * |
525 ssl_gnutls_get_peer_certificates(PurpleSslConnection * gsc) | 531 ssl_gnutls_get_peer_certificates(PurpleSslConnection * gsc) |
526 { | 532 { |
527 PurpleSslGnutlsData *gnutls_data = PURPLE_SSL_GNUTLS_DATA(gsc); | 533 PurpleSslGnutlsData *gnutls_data = PURPLE_SSL_GNUTLS_DATA(gsc); |
534 PurpleCertificate *prvcrt = NULL; | |
528 | 535 |
529 /* List of Certificate instances to return */ | 536 /* List of Certificate instances to return */ |
530 GList * peer_certs = NULL; | 537 GList * peer_certs = NULL; |
531 | 538 |
532 /* List of raw certificates as given by GnuTLS */ | 539 /* List of raw certificates as given by GnuTLS */ |
548 PurpleCertificate * newcrt = x509_import_from_datum(cert_list[i], | 555 PurpleCertificate * newcrt = x509_import_from_datum(cert_list[i], |
549 GNUTLS_X509_FMT_DER); | 556 GNUTLS_X509_FMT_DER); |
550 /* Append is somewhat inefficient on linked lists, but is easy | 557 /* Append is somewhat inefficient on linked lists, but is easy |
551 to read. If someone complains, I'll change it. | 558 to read. If someone complains, I'll change it. |
552 TODO: Is anyone complaining? (Maybe elb?) */ | 559 TODO: Is anyone complaining? (Maybe elb?) */ |
553 peer_certs = g_list_append(peer_certs, newcrt); | 560 /* only append if previous cert was actually signed by this one. |
561 * Thanks Microsoft. */ | |
562 if ((prvcrt == NULL) || x509_certificate_signed_by(prvcrt, newcrt)) { | |
563 peer_certs = g_list_append(peer_certs, newcrt); | |
564 prvcrt = newcrt; | |
565 } else { | |
566 x509_destroy_certificate(newcrt); | |
567 purple_debug_error("gnutls", "Dropping further peer certificates " | |
568 "because the chain is broken!\n"); | |
569 break; | |
570 } | |
554 } | 571 } |
555 | 572 |
556 /* cert_list doesn't need free()-ing */ | 573 /* cert_list doesn't need free()-ing */ |
557 | 574 |
558 return peer_certs; | 575 return peer_certs; |