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
0x48426C7E.asc
Description: application/pgp-keys
signature.asc
Description: OpenPGP digital signature
------------------------------------------------------------------- List admin: http://cool.haxx.se/list/listinfo/curl-library Etiquette: http://curl.haxx.se/mail/etiquette.html
