summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Atallah <datallah@pidgin.im>2014-10-31 18:01:24 -0400
committerDaniel Atallah <datallah@pidgin.im>2014-10-31 18:01:24 -0400
commit90bda5b9d8b60f8435c747038c9f01b7536fffff (patch)
tree7cd2e590bc999ff25a2e905d83ab2e4c8eb04d1c
parent3dbe905ec5ab3c14bb5abd7326fe0df565deb0a5 (diff)
downloadpidgin-90bda5b9d8b60f8435c747038c9f01b7536fffff.tar.gz
Fix NSS handling of self-signed certificates. Fixes #16412.
-rw-r--r--ChangeLog5
-rw-r--r--libpurple/plugins/ssl/ssl-nss.c34
2 files changed, 27 insertions, 12 deletions
diff --git a/ChangeLog b/ChangeLog
index 217609d8ea..d31fcaf363 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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);