Here's a little patch to get CURLINFO_CERTINFO to do something
meaningful if libcurl was compiled to use GnuTLS instead of OpenSSL.

As described in the log, I'd prefer to get PEM as the returned text to
the client, but the OpenSSL API doesn't allow that either.  Would you
be happy with a patch to add an option CURLINFO_CERTINFO_PEM that would
return the server certificate in PEM format for machine-processing?

Happy hacking!

Christian
From e70671769c65826efc07a9da8a75a694e9619140 Mon Sep 17 00:00:00 2001
From: Christian Grothoff <[email protected]>
Date: Wed, 18 Sep 2013 22:00:55 +0200
Subject: [PATCH] Adding support for CURLINFO_CERTINFO when compiled with
 GnuTLS.

This change exposes the server's x509 certificate chain to
the client via the CURLINFO_CERTINFO mechanism, which
previously was documented to only work for OpenSSL.  However,
the format in which the certificate is returned maybe
slightly different: as implemented, GnuTLS provides more
information in a human-readable fashion.  The OpenSSL
format as generated from the code seemed also rather
ad-hoc, so I'm not sure if this is OK or not.  I would
prefer if both mechanisms were changed to output some
standard format that can be easily processed later (DER
would be best), but for that a new option (like
CURLINFO_CERTINFO_PEM) should probably be introduced;
this change is less invasive and should improve
compatibility between the OpenSSL and GnuTLS-based
variants of libcurl.

Note that I did not update the documentation itself.
---
 lib/gtls.c |   29 +++++++++++++++++++++++++++++
 1 file changed, 29 insertions(+)

diff --git a/lib/gtls.c b/lib/gtls.c
index 700e46a..6f5536b 100644
--- a/lib/gtls.c
+++ b/lib/gtls.c
@@ -51,6 +51,7 @@
 #include "connect.h" /* for the connect timeout */
 #include "select.h"
 #include "rawstr.h"
+#include "slist.h"
 
 #define _MPRINTF_REPLACE /* use our functions only */
 #include <curl/mprintf.h>
@@ -605,6 +606,34 @@ gtls_connect_step3(struct connectdata *conn,
     infof(data, "\t common name: WARNING couldn't obtain\n");
   }
 
+  if(0 == Curl_ssl_init_certinfo (data, cert_list_size)) {
+    unsigned int i;
+
+    for(i=0;i<cert_list_size;i++) {
+      gnutls_x509_crt_t cert;
+      gnutls_datum_t dn;
+
+      if(GNUTLS_E_SUCCESS == gnutls_x509_crt_init (&cert)) {
+        if((GNUTLS_E_SUCCESS ==
+            gnutls_x509_crt_import (cert, &chainp[i],
+                                    GNUTLS_X509_FMT_DER)) &&
+           (GNUTLS_E_SUCCESS ==
+            gnutls_x509_crt_print (cert,
+                                   GNUTLS_CRT_PRINT_FULL,
+                                   &dn))) {
+          char *output;
+          struct curl_certinfo * ci = &data->info.certs;
+
+          output = curl_maprintf ("%.*s", dn.size, dn.data);
+          gnutls_free (dn.data);
+          if(NULL != output)
+            ci->certinfo[i] = Curl_slist_append_nodup (NULL, output);
+        }
+        gnutls_x509_crt_deinit (cert);
+      }
+    }
+  }
+
   if(data->set.ssl.verifypeer) {
     /* This function will try to verify the peer's certificate and return its
        status (trusted, invalid etc.). The value of status should be one or
-- 
1.7.10.4

Attachment: 0x48426C7E.asc
Description: application/pgp-keys

Attachment: signature.asc
Description: OpenPGP digital signature

-------------------------------------------------------------------
List admin: http://cool.haxx.se/list/listinfo/curl-library
Etiquette:  http://curl.haxx.se/mail/etiquette.html

Reply via email to