cURL / Mailing Lists / curl-library / Single Mail

curl-library

PKCS 12 Support patch

From: Samuel Listopad <samuel.listopad_at_authentify.com>
Date: Fri, 17 Dec 2004 11:25:55 -0600

I don't know if this will be accepted as I don't know if there was a
concious decision not to include PKCS12 support, but this will add it.
If it doesn't get in that's fine, just thought I would put it out
there.

I also realize some of this may not be the best way to go about some
things. The main one being figuring out PKCS12 support, I just go by
the fact that 0.9.3 and later of openssl have PKCS12 support. It should
probably be put into some automagic something or other, but I am not
well versed in that stuff.

Sam Listopad

pkcs12Support.patch
------------------------------------------------------------------------
----------
--- lib/ssluse.c Fri Dec 17 08:51:45 2004
+++ lib-new/ssluse.c Wed Dec 15 16:50:24 2004
@@ -90,6 +91,16 @@
 #undef HAVE_ENGINE_LOAD_FOUR_ARGS
 #endif
 
+#if OPENSSL_VERSION_NUMBER >= 0x00903001L
+/* OpenSSL has PKCS 12 support */
+#define HAVE_PKCS12_SUPPORT
+#include <openssl/pkcs12.h>
+#else
+/* OpenSSL/SSLEay does not have PKCS12 support */
+#undef HAVE_PKCS12_SUPPORT
+#endif
+
+
 #if OPENSSL_VERSION_NUMBER >= 0x00906001L
 #define HAVE_ERR_ERROR_STRING_N 1
 #endif
@@ -234,6 +245,9 @@
 #ifndef SSL_FILETYPE_ENGINE
 #define SSL_FILETYPE_ENGINE 42
 #endif
+#ifndef SSL_FILETYPE_PKCS12
+#define SSL_FILETYPE_PKCS12 43
+#endif
 static int do_file_type(const char *type)
 {
   if(!type || !type[0])
@@ -244,6 +258,8 @@
     return SSL_FILETYPE_ASN1;
   if(curl_strequal(type, "ENG"))
     return SSL_FILETYPE_ENGINE;
+ if(curl_strequal(type, "P12"))
+ return SSL_FILETYPE_PKCS12;
   return -1;
 }
 
@@ -261,6 +277,7 @@
   if(cert_file != NULL) {
     SSL *ssl;
     X509 *x509;
+ int cert_done = 0;
 
     if(data->set.key_passwd) {
 #ifndef HAVE_USERDATA_IN_PWD_CALLBACK
@@ -312,6 +329,58 @@
       failf(data, "file type ENG for certificate not implemented");
       return 0;
 
+ case SSL_FILETYPE_PKCS12:
+ {
+#ifdef HAVE_PKCS12_SUPPORT
+ FILE *f;
+ PKCS12 *p12;
+
+ if ((f = fopen(cert_file,"rb")) == NULL ){
+ failf(data, "could not open PKCS12 file '%s'", cert_file);
+ return 0;
+ }
+ p12 = d2i_PKCS12_fp(f, NULL);
+ fclose(f);
+
+ PKCS12_PBE_add();
+
+ EVP_PKEY *pri;
+
+ if (!PKCS12_parse(p12, data->set.key_passwd, &pri, &x509, NULL)){
+ failf(data,
+ "could not parse PKCS12 file, check password, OpenSSL
error %s",
+ ERR_error_string(ERR_get_error(), NULL)
+ );
+ return 0;
+ }
+
+ PKCS12_free(p12);
+
+ if(SSL_CTX_use_certificate(ctx,
+ x509) != 1) {
+ failf(data, SSL_CLIENT_CERT_ERR);
+ EVP_PKEY_free(pri);
+ X509_free(x509);
+ return 0;
+ }
+
+ if(SSL_CTX_use_PrivateKey(ctx,
+ pri) != 1) {
+ failf(data, "unable to use private key from PKCS12 file '%s'",
cert_file);
+ EVP_PKEY_free(pri);
+ X509_free(x509);
+ return 0;
+ }
+
+ EVP_PKEY_free(pri);
+ X509_free(x509);
+ cert_done = 1;
+ break;
+#else
+ failf(data, "file type P12 for certificate not supported");
+ return 0;
+#endif
+ }
     default:
       failf(data, "not supported file type '%s' for certificate",
cert_type);
       return 0;
@@ -321,6 +390,8 @@
 
     switch(file_type) {
     case SSL_FILETYPE_PEM:
+ if(cert_done)
+ break;
       if(key_file == NULL)
         /* cert & key can only be in PEM case in the same file */
         key_file=cert_file;
@@ -371,6 +442,16 @@
       failf(data, "file type ENG for private key not supported\n");
       return 0;
 #endif
+ case SSL_FILETYPE_PKCS12:
+ if( cert_done ){
+ break;
+ }
+ else
+ {
+ failf(data, "file type P12 for private key not supported\n");
+ return 0;
+ }
+
     default:
       failf(data, "not supported file type for private key\n");
       return 0;
Received on 2004-12-17