diff options
author | Daniel Atallah <datallah@pidgin.im> | 2014-10-31 18:01:24 -0400 |
---|---|---|
committer | Daniel Atallah <datallah@pidgin.im> | 2014-10-31 18:01:24 -0400 |
commit | 90bda5b9d8b60f8435c747038c9f01b7536fffff (patch) | |
tree | 7cd2e590bc999ff25a2e905d83ab2e4c8eb04d1c | |
parent | 3dbe905ec5ab3c14bb5abd7326fe0df565deb0a5 (diff) | |
download | pidgin-90bda5b9d8b60f8435c747038c9f01b7536fffff.tar.gz |
Fix NSS handling of self-signed certificates. Fixes #16412.
-rw-r--r-- | ChangeLog | 5 | ||||
-rw-r--r-- | libpurple/plugins/ssl/ssl-nss.c | 34 |
2 files changed, 27 insertions, 12 deletions
@@ -1,8 +1,9 @@ Pidgin and Finch: The Pimpin' Penguin IM Clients That're Good for the Soul version 2.10.11 (?/?/?): - Stuff: - * Things. + General: + * Fix handling of Self-Signed SSL/TLS Certificates when using the NSS + plugin (#16412) version 2.10.10 (10/22/14): General: diff --git a/libpurple/plugins/ssl/ssl-nss.c b/libpurple/plugins/ssl/ssl-nss.c index 2757b35094..12cae38676 100644 --- a/libpurple/plugins/ssl/ssl-nss.c +++ b/libpurple/plugins/ssl/ssl-nss.c @@ -1044,9 +1044,10 @@ static void x509_verify_cert(PurpleCertificateVerificationRequest *vrq, PurpleCe CERTCertDBHandle *certdb = CERT_GetDefaultCertDB(); CERTCertificate *crt_dat; PRTime now = PR_Now(); - SECStatus rv; + SECStatus rv; PurpleCertificate *first_cert = vrq->cert_chain->data; CERTVerifyLog log; + gboolean self_signed = FALSE; crt_dat = X509_NSS_DATA(first_cert); @@ -1059,6 +1060,14 @@ static void x509_verify_cert(PurpleCertificateVerificationRequest *vrq, PurpleCe CERTVerifyLogNode *node = NULL; unsigned int depth = (unsigned int)-1; + if (crt_dat->isRoot) { + self_signed = TRUE; + *flags |= PURPLE_CERTIFICATE_SELF_SIGNED; + } + + /* Handling of untrusted, etc. modeled after + * source/security/manager/ssl/src/TransportSecurityInfo.cpp in Firefox + */ for (node = log.head; node; node = node->next) { if (depth != node->depth) { depth = node->depth; @@ -1077,13 +1086,18 @@ static void x509_verify_cert(PurpleCertificateVerificationRequest *vrq, PurpleCe break; case SEC_ERROR_UNKNOWN_ISSUER: case SEC_ERROR_UNTRUSTED_ISSUER: - if (crt_dat->isRoot) { - *flags |= PURPLE_CERTIFICATE_SELF_SIGNED; - } else { + if (!self_signed) { *flags |= PURPLE_CERTIFICATE_CA_UNKNOWN; } break; + case SEC_ERROR_CA_CERT_INVALID: + case SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE: + case SEC_ERROR_UNTRUSTED_CERT: case SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED: + if (!self_signed) { + *flags |= PURPLE_CERTIFICATE_INVALID_CHAIN; + } + break; case SEC_ERROR_BAD_SIGNATURE: default: *flags |= PURPLE_CERTIFICATE_INVALID_CHAIN; @@ -1091,12 +1105,12 @@ static void x509_verify_cert(PurpleCertificateVerificationRequest *vrq, PurpleCe if (node->cert) CERT_DestroyCertificate(node->cert); } - } else { - rv = CERT_VerifyCertName(crt_dat, vrq->subject_name); - if (rv != SECSuccess) { - purple_debug_error("nss", "Cert chain valid, but name not verified\n"); - *flags |= PURPLE_CERTIFICATE_NAME_MISMATCH; - } + } + + rv = CERT_VerifyCertName(crt_dat, vrq->subject_name); + if (rv != SECSuccess) { + purple_debug_error("nss", "subject name not verified\n"); + *flags |= PURPLE_CERTIFICATE_NAME_MISMATCH; } PORT_FreeArena(log.arena, PR_FALSE); |