cURL / Mailing Lists / curl-library / Single Mail

curl-library

CURL patch (fwd)

From: Daniel Stenberg <daniel-curl_at_haxx.se>
Date: Fri, 5 Mar 2004 14:15:58 +0100 (CET)

This is the issue 10 patch mention in the TODO-RELEASE document.

Any comments on this good people?

-- 
    Daniel Stenberg -- http://curl.haxx.se/ -- http://daniel.haxx.se/
   [[ Do not send mails to this email address. They won't reach me. ]]
---------- Forwarded message ----------
Date: Thu, 20 Nov 2003 01:10:42 +0600
From: Anton Fedorov <datacompboy_at_mail.ru>
To: daniel_at_haxx.se
Subject: CURL patch
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
                        Hello, Daniel!
        First is pach, also posted (but looks like broken) into your forum, this
fix for transfer.c if some callback changed URL:
********
diff -urNw curl-7.10.8/lib/transfer.c curl-7.10.8.new/lib/transfer.c
- --- curl-7.10.8/lib/transfer.c  Sat Oct 25 04:54:34 2003
+++ curl-7.10.8.new/lib/transfer.c  Wed Nov 19 21:43:58 2003
@@ -1854,13 +1854,12 @@
          to the new URL */
       urlchanged = data->change.url_changed;
       if ((CURLE_OK == res) && urlchanged) {
- -        char *gotourl;
         res = Curl_done(conn);
         if(CURLE_OK == res) {
           newurl = strdup(data->change.url);
- -          res = Curl_follow(data, gotourl);
+          res = Curl_follow(data, newurl);
           if(res)
- -            free(gotourl);
+            free(newurl);
         }
       }
     } while (urlchanged && res == CURLE_OK) ;
********
        I'm have played with libcurl & commandline curl, looked on google,
and  found  that  this  fix  could  be useful: I have added allow to save server
certificate  to  FILE*, this help to work with self-signed SSL servers: you just
opened your bundle for append, request first time server, request fail (can't be
verified  host). All next times you access to this host it already "trusted" and
verify finish well.
        Here  is  my patch, it for command line curl, libcurl, and documentaion,
apply  it  with  -w option {editor that I use changed whitespaces}.
********
diff -urNw curl-7.10.8/CHANGES curl-7.10.8.new/CHANGES
- --- curl-7.10.8/CHANGES Sat Nov  1 17:22:12 2003
+++ curl-7.10.8.new/CHANGES Wed Nov 19 22:14:02 2003
@@ -6,6 +6,9 @@
                                   Changelog
+DataCompBoy (19 November)
+- Added option CURLOPT_SSL_KEY_EXPORT for exporting content of server
+  certificate to file. (curl command line option --scdump)
 Version 7.10.8 (1 November 2003)
diff -urNw curl-7.10.8/docs/curl.1 curl-7.10.8.new/docs/curl.1
- --- curl-7.10.8/docs/curl.1 Sat Nov  1 03:18:02 2003
+++ curl-7.10.8.new/docs/curl.1 Wed Nov 19 22:13:24 2003
@@ -262,6 +262,8 @@
 certificate concatenated!
 If this option is used several times, the last one will be used.
+.IP "--scdump <file for dump server certificate>"
+(HTTPS) stores dump of server certificate to given file.
 .IP "--cacert <CA certificate>"
 (HTTPS) Tells curl to use the specified certificate file to verify the
 peer. The file may contain multiple CA certificates. The certificate(s) must
diff -urNw curl-7.10.8/docs/libcurl/curl_easy_setopt.3 curl-7.10.8.new/docs/libcurl/curl_easy_setopt.3
- --- curl-7.10.8/docs/libcurl/curl_easy_setopt.3 Sat Oct 18 18:54:20 2003
+++ curl-7.10.8.new/docs/libcurl/curl_easy_setopt.3 Wed Nov 19 22:04:06 2003
@@ -815,6 +815,9 @@
 Pass a pointer to a zero terminated string as parameter. The string should be
 the format of your certificate. Supported formats are "PEM" and "DER".  (Added
 in 7.9.3)
+.TP
+.B CURLOPT_SSL_KEY_EXPORT
+Pass a FILE* for get dump of server certificate
 .TP
 .B CURLOPT_SSLCERTPASSWD
 Pass a pointer to a zero terminated string as parameter. It will be used as
diff -urNw curl-7.10.8/include/curl/curl.h curl-7.10.8.new/include/curl/curl.h
- --- curl-7.10.8/include/curl/curl.h Sat Nov  1 17:25:52 2003
+++ curl-7.10.8.new/include/curl/curl.h Wed Nov 19 21:54:06 2003
@@ -694,6 +694,9 @@
      an HTTP or FTP server. */
   CINIT(MAXFILESIZE, LONG, 114),
+  /* SSL Key Export */
+  CINIT(SSL_KEY_EXPORT, OBJECTPOINT, 115),
+
   CURLOPT_LASTENTRY /* the last unused */
 } CURLoption;
diff -urNw curl-7.10.8/lib/ssluse.c curl-7.10.8.new/lib/ssluse.c
- --- curl-7.10.8/lib/ssluse.c    Sat Oct 25 03:03:12 2003
+++ curl-7.10.8.new/lib/ssluse.c    Thu Nov 20 01:06:18 2003
@@ -375,15 +375,55 @@
   return(1);
 }
+static int SSL_Curl_Data_index = 0;
+#define NETSCAPE_CERT_HDR   "certificate"
+
+// Code based on code from SSL_CTX_set_verify(3) and from apps/x509.c of OpenSSL
 static
 int cert_verify_callback(int ok, X509_STORE_CTX *ctx)
 {
- -  X509 *err_cert;
   char buf[256];
+    X509   *err_cert;
+    int     err, depth;
+    SSL    *ssl;
+    struct SessionHandle * data;
   err_cert=X509_STORE_CTX_get_current_cert(ctx);
+    err = X509_STORE_CTX_get_error(ctx);
+    depth = X509_STORE_CTX_get_error_depth(ctx);
+
+    ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
+    data = SSL_get_ex_data(ssl, SSL_Curl_Data_index);
+
   X509_NAME_oneline(X509_get_subject_name(err_cert),buf,256);
+    if (!ok) {
+        infof(data, "verify error:num=%d:%s:depth=%d:%s\n", err,
+              X509_verify_cert_error_string(err), depth, buf);
+    }
+    else if (data->set.key_export)
+    {
+        fprintf(data->set.key_export, "depth=%d:%s\n", depth, buf);
+    }
+
+    /* Dump cert to file if user want it */
+    if (data->set.key_export)
+    {
+      int j;
+      unsigned int n;
+      unsigned char md[16];
+      BIO * bio = BIO_new_fp(data->set.key_export, BIO_NOCLOSE || BIO_FP_TEXT);
+      BIO_printf(bio,"## Dump of cert created by curl\n");
+      X509_digest(ctx->cert,EVP_md5(),md,&n);
+      BIO_printf(bio,"%s Fingerprint=", OBJ_nid2sn(EVP_MD_type(EVP_md5())));
+      for (j=0; j<(int)n; j++)
+          { BIO_printf(bio,"%02X%c",md[j], (j+1 == (int)n) ?'\n':':'); }
+      BIO_printf(bio,"PEM Data:\n");
+      PEM_write_bio_X509(bio,ctx->cert);
+      X509_print_ex(bio, ctx->cert, 0, 0);
+      BIO_free(bio);
+    }
+
   return ok;
 }
@@ -392,6 +432,7 @@
 #ifdef USE_SSLEAY
 /* "global" init done? */
 static int init_ssl=0;
+/*static int SSL_Curl_Data_index = 0;  <<-- Defined before cert_verify_callback */
 /* we have the "SSL is seeded" boolean global for the application to
    prevent multiple time-consuming seedings in vain */
@@ -417,6 +458,8 @@
   /* Setup all the global SSL stuff */
   SSLeay_add_ssl_algorithms();
+
+  SSL_Curl_Data_index = SSL_get_ex_new_index(0, "CURL Data Index", NULL, NULL, NULL);
 #else
   /* SSL disabled, do nothing */
 #endif
@@ -1032,6 +1075,10 @@
   conn->ssl.server_cert = 0x0;
+  /* Set up user configuration into context, so cert-checker know is
+     user want to get dump of key or not, also for DEBUG all this errors */
+  SSL_set_ex_data(conn->ssl.handle, SSL_Curl_Data_index, data);
+
   if(!conn->bits.reuse) {
     /* We're not re-using a connection, check if there's a cached ID we
        can/should use here! */
diff -urNw curl-7.10.8/lib/url.c curl-7.10.8.new/lib/url.c
- --- curl-7.10.8/lib/url.c   Sat Nov  1 03:18:02 2003
+++ curl-7.10.8.new/lib/url.c   Wed Nov 19 22:19:44 2003
@@ -1010,6 +1010,12 @@
      */
     data->set.cert_type = va_arg(param, char *);
     break;
+  case CURLOPT_SSL_KEY_EXPORT:
+    /*
+     * FILE* to where server certificate will dumped
+     */
+    data->set.key_export = va_arg(param, FILE *);
+    break;
   case CURLOPT_SSLKEY:
     /*
      * String that holds file name of the SSL certificate to use
diff -urNw curl-7.10.8/lib/urldata.h curl-7.10.8.new/lib/urldata.h
- --- curl-7.10.8/lib/urldata.h   Sun Oct 19 03:14:34 2003
+++ curl-7.10.8.new/lib/urldata.h   Wed Nov 19 23:12:14 2003
@@ -866,6 +866,8 @@
   bool no_signal;        /* do not use any signal/alarm handler */
   bool global_dns_cache;
+
+  FILE * key_export; /* added at last line to be */
 };
 /*
diff -urNw curl-7.10.8/src/main.c curl-7.10.8.new/src/main.c
- --- curl-7.10.8/src/main.c  Sat Nov  1 03:18:02 2003
+++ curl-7.10.8.new/src/main.c  Wed Nov 19 23:37:52 2003
@@ -532,6 +532,8 @@
   char *cipher_list;
   char *cert;
   char *cert_type;
+  FILE *key_export;
+  bool  key_export_open;
   char *cacert;
   char *capath;
   char *key;
@@ -1186,6 +1188,7 @@
     {"Ee","pass",        TRUE},
     {"Ef","engine",      TRUE},
     {"Eg","capath ",     TRUE},
+    {"Eh","scdump ",     TRUE},
     {"f", "fail",        FALSE},
     {"F", "form",        TRUE},
     {"g", "globoff",     FALSE},
@@ -1618,6 +1621,10 @@
         /* CA cert directory */
         GetStr(&config->capath, nextarg);
         break;
+      case 'h': /* Cert export */
+        config->key_export = fopen(nextarg, "w");
+        config->key_export_open = TRUE;
+        break;
       default: /* certificate file */
         {
           char *ptr = strchr(nextarg, ':');
@@ -3180,6 +3187,7 @@
         curl_easy_setopt(curl, CURLOPT_HTTPPOST, config->httppost);
         curl_easy_setopt(curl, CURLOPT_SSLCERT, config->cert);
         curl_easy_setopt(curl, CURLOPT_SSLCERTTYPE, config->cert_type);
+        curl_easy_setopt(curl, CURLOPT_SSL_KEY_EXPORT, config->key_export);
         curl_easy_setopt(curl, CURLOPT_SSLKEY, config->key);
         curl_easy_setopt(curl, CURLOPT_SSLKEYTYPE, config->key_type);
         curl_easy_setopt(curl, CURLOPT_SSLKEYPASSWD, config->key_passwd);
@@ -3414,6 +3422,9 @@
   if(config->trace_fopened)
     fclose(config->trace_stream);
+  if(config->key_export_open)
+    fclose(config->key_export);
+
   if(allocuseragent)
     free(config->useragent);
********
                                                              WBR, DataCompBoy
                                                           datacompboy_at_mail.ru
-----BEGIN PGP SIGNATURE-----
Version: PGP 6.5i
iQA/AwUBP7tr24izXXEb1WF5EQLBmwCcCGndjcEwGTsp6636WCQQWDR3J1QAoPo6
HpNkM+UVbTA6ps50Dws+3K98
=4m3Y
-----END PGP SIGNATURE-----
Received on 2004-03-05