- Sam Listopad provided a patch in feature-request #1900014
  http://curl.haxx.se/bug/feature.cgi?id=1900014 that makes libcurl (built to
  use OpenSSL) support a full chain of certificates in a given PKCS12
  certificate.
diff --git a/CHANGES b/CHANGES
index 01c742e..4a5e294 100644
--- a/CHANGES
+++ b/CHANGES
@@ -6,6 +6,12 @@
 
                                   Changelog
 
+Daniel S (23 Feb 2008)
+- Sam Listopad provided a patch in feature-request #1900014
+  http://curl.haxx.se/bug/feature.cgi?id=1900014 that makes libcurl (built to
+  use OpenSSL) support a full chain of certificates in a given PKCS12
+  certificate.
+
 Daniel S (22 Feb 2008)
 - Georg Lippitsch made the src/Makefile.vc6 makefile use the same memory model
   options as the lib/Makefile.vc6 already did.
diff --git a/RELEASE-NOTES b/RELEASE-NOTES
index 378f67c..0127a13 100644
--- a/RELEASE-NOTES
+++ b/RELEASE-NOTES
@@ -15,6 +15,7 @@
  o we no longer distribute or install a ca cert bundle
  o SSLv2 is now disabled by default for SSL operations
  o the test509-style setting URL in callback is officially no longer supported
+ o support a full chain of certificates in a given PKCS12 certificate
 
 This release includes the following bugfixes:
 
@@ -48,6 +49,6 @@
 
  Michal Marek, Dmitry Kurochkin, Niklas Angebrand, Günter Knauf, Yang Tse,
  Dan Fandrich, Mike Hommey, Pooyan McSporran, Jerome Muffat-Meridol,
- Kaspar Brand, Gautam Kachroo, Zmey Petroff, Georg Lippitsch
+ Kaspar Brand, Gautam Kachroo, Zmey Petroff, Georg Lippitsch, Sam Listopad
 
         Thanks! (and sorry if I forgot to mention someone)
diff --git a/lib/ssluse.c b/lib/ssluse.c
index ac6b057..889cfc8 100644
--- a/lib/ssluse.c
+++ b/lib/ssluse.c
@@ -364,6 +364,8 @@
       FILE *f;
       PKCS12 *p12;
       EVP_PKEY *pri;
+      STACK_OF(X509) *ca = NULL;
+      int i;
 
       f = fopen(cert_file,"rb");
       if(!f) {
@@ -373,10 +375,15 @@
       p12 = d2i_PKCS12_fp(f, NULL);
       fclose(f);
 
+      if(!p12) {
+        failf(data, "error reading PKCS12 file '%s'", cert_file );
+        return 0;
+      }
+
       PKCS12_PBE_add();
 
       if(!PKCS12_parse(p12, data->set.str[STRING_KEY_PASSWD], &pri, &x509,
-                        NULL)) {
+                        &ca)) {
         failf(data,
               "could not parse PKCS12 file, check password, OpenSSL error %s",
               ERR_error_string(ERR_get_error(), NULL) );
@@ -401,6 +408,32 @@
         return 0;
       }
 
+      if (!SSL_CTX_check_private_key (ctx)) {
+        failf(data, "private key from PKCS12 file '%s' "
+              "does not match certificate in same file", cert_file);
+        EVP_PKEY_free(pri);
+        X509_free(x509);
+        return 0;
+      }
+      /* Set Certificate Verification chain */
+      if (ca && sk_num(ca)) {
+        for (i = 0; i < sk_X509_num(ca); i++) {
+          if (!SSL_CTX_add_extra_chain_cert(ctx,sk_X509_value(ca, i))) {
+            failf(data, "cannot add certificate to certificate chain");
+            EVP_PKEY_free(pri);
+            X509_free(x509);
+            return 0;
+          }
+          if (!SSL_CTX_add_client_CA(ctx, sk_X509_value(ca, i))) {
+            failf(data, "cannot add certificate to client CA list",
+                  cert_file);
+            EVP_PKEY_free(pri);
+            X509_free(x509);
+            return 0;
+          }
+        }
+      }
+
       EVP_PKEY_free(pri);
       X509_free(x509);
       cert_done = 1;