summaryrefslogtreecommitdiffstats
path: root/0006-curl-7.27.0-68d2830e.patch
blob: be8c558dd5590a2126c7cbd1d2f53dde2dd61e0d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
From c011938e10bf3af5896d0f7f5ecffc22150303f3 Mon Sep 17 00:00:00 2001
From: Kamil Dudka <kdudka@redhat.com>
Date: Mon, 3 Dec 2012 13:17:50 +0100
Subject: [PATCH 1/3] nss: prevent NSS from crashing on client auth hook failure

Although it is not explicitly stated in the documentation, NSS uses
*pRetCert and *pRetKey even if the client authentication hook returns
a failure.  Namely, if we destroy *pRetCert without clearing *pRetCert
afterwards, NSS destroys the certificate once again, which causes a
double free.

Reported by: Bob Relyea

[upstream commit 68d2830ee9df50961e481e81c1baaa290c33f03e]
---
 lib/nss.c |   17 +++++++++++------
 1 files changed, 11 insertions(+), 6 deletions(-)

diff --git a/lib/nss.c b/lib/nss.c
index 22b53bf..794eccb 100644
--- a/lib/nss.c
+++ b/lib/nss.c
@@ -757,6 +757,8 @@ static SECStatus SelectClientCert(void *arg, PRFileDesc *sock,
     static const char pem_slotname[] = "PEM Token #1";
     SECItem cert_der = { 0, NULL, 0 };
     void *proto_win = SSL_RevealPinArg(sock);
+    struct CERTCertificateStr *cert;
+    struct SECKEYPrivateKeyStr *key;
 
     PK11SlotInfo *slot = PK11_FindSlotByName(pem_slotname);
     if(NULL == slot) {
@@ -771,24 +773,27 @@ static SECStatus SelectClientCert(void *arg, PRFileDesc *sock,
       return SECFailure;
     }
 
-    *pRetCert = PK11_FindCertFromDERCertItem(slot, &cert_der, proto_win);
+    cert = PK11_FindCertFromDERCertItem(slot, &cert_der, proto_win);
     SECITEM_FreeItem(&cert_der, PR_FALSE);
-    if(NULL == *pRetCert) {
+    if(NULL == cert) {
       failf(data, "NSS: client certificate from file not found");
       PK11_FreeSlot(slot);
       return SECFailure;
     }
 
-    *pRetKey = PK11_FindPrivateKeyFromCert(slot, *pRetCert, NULL);
+    key = PK11_FindPrivateKeyFromCert(slot, cert, NULL);
     PK11_FreeSlot(slot);
-    if(NULL == *pRetKey) {
+    if(NULL == key) {
       failf(data, "NSS: private key from file not found");
-      CERT_DestroyCertificate(*pRetCert);
+      CERT_DestroyCertificate(cert);
       return SECFailure;
     }
 
     infof(data, "NSS: client certificate from file\n");
-    display_cert_info(data, *pRetCert);
+    display_cert_info(data, cert);
+
+    *pRetCert = cert;
+    *pRetKey = key;
     return SECSuccess;
   }
 
-- 
1.7.1