From 6ea7acf5a96786f7514be4fbce174cdc8bedfdd1 Mon Sep 17 00:00:00 2001
From: Johannes Bauer <Jb.Imm@gmx.de>
Date: Wed, 18 Jan 2012 13:39:12 +0100
Subject: [PATCH] OpenSSL: fix PKCS#12 certificate parsing related memory leak

Leak triggered when CURLOPT_SSLCERTTYPE and CURLOPT_SSLKEYTYPE set to P12
and both CURLOPT_SSLCERT and CURLOPT_SSLKEY point to the same PKCS#12 file.
---
 lib/ssluse.c |    6 ++++++
 1 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/lib/ssluse.c b/lib/ssluse.c
index b09ba6d..ec1a149 100644
--- a/lib/ssluse.c
+++ b/lib/ssluse.c
@@ -466,6 +466,7 @@ int cert_stuff(struct connectdata *conn,
         failf(data, SSL_CLIENT_CERT_ERR);
         EVP_PKEY_free(pri);
         X509_free(x509);
+        sk_X509_pop_free(ca, X509_free);
         return 0;
       }
 
@@ -474,6 +475,7 @@ int cert_stuff(struct connectdata *conn,
               cert_file);
         EVP_PKEY_free(pri);
         X509_free(x509);
+        sk_X509_pop_free(ca, X509_free);
         return 0;
       }
 
@@ -482,6 +484,7 @@ int cert_stuff(struct connectdata *conn,
               "does not match certificate in same file", cert_file);
         EVP_PKEY_free(pri);
         X509_free(x509);
+        sk_X509_pop_free(ca, X509_free);
         return 0;
       }
       /* Set Certificate Verification chain */
@@ -491,12 +494,14 @@ int cert_stuff(struct connectdata *conn,
             failf(data, "cannot add certificate to certificate chain");
             EVP_PKEY_free(pri);
             X509_free(x509);
+            sk_X509_pop_free(ca, X509_free);
             return 0;
           }
           if(!SSL_CTX_add_client_CA(ctx, sk_X509_value(ca, i))) {
             failf(data, "cannot add certificate to client CA list");
             EVP_PKEY_free(pri);
             X509_free(x509);
+            sk_X509_pop_free(ca, X509_free);
             return 0;
           }
         }
@@ -504,6 +509,7 @@ int cert_stuff(struct connectdata *conn,
 
       EVP_PKEY_free(pri);
       X509_free(x509);
+      sk_X509_pop_free(ca, X509_free);
       cert_done = 1;
       break;
 #else
-- 
1.6.1.2

