From 6982ed4db767d23141c2399be47595d47a45f4fe Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Sat, 23 Feb 2008 12:27:45 +0000 Subject: [PATCH] - 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. --- CHANGES | 6 ++++++ RELEASE-NOTES | 3 ++- lib/ssluse.c | 35 ++++++++++++++++++++++++++++++++++- 3 files changed, 42 insertions(+), 2 deletions(-) diff --git a/CHANGES b/CHANGES index 01c742eeb..4a5e29430 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 378f67c64..0127a1308 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -15,6 +15,7 @@ This release includes the following changes: 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 @@ advice from friends like these: 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 ac6b057cb..889cfc84f 100644 --- a/lib/ssluse.c +++ b/lib/ssluse.c @@ -364,6 +364,8 @@ int cert_stuff(struct connectdata *conn, 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 @@ int cert_stuff(struct connectdata *conn, 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 @@ int cert_stuff(struct connectdata *conn, 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;