From 142acddaddaf329062f64d7d80418111499d70aa Mon Sep 17 00:00:00 2001
From: Alessandro Ghedini <alessandro@ghedini.me>
Date: Sun, 15 Mar 2015 13:50:30 +0100
Subject: [PATCH] gtls: implement CURLOPT_CERTINFO

---
 docs/libcurl/opts/CURLOPT_CERTINFO.3 | 11 +++++------
 lib/vtls/gtls.c                      | 18 ++++++++++++++++++
 lib/vtls/gtls.h                      |  3 +++
 lib/x509asn1.c                       |  2 +-
 lib/x509asn1.h                       |  2 +-
 5 files changed, 28 insertions(+), 8 deletions(-)

diff --git a/docs/libcurl/opts/CURLOPT_CERTINFO.3 b/docs/libcurl/opts/CURLOPT_CERTINFO.3
index 8c01711..c47e890 100644
--- a/docs/libcurl/opts/CURLOPT_CERTINFO.3
+++ b/docs/libcurl/opts/CURLOPT_CERTINFO.3
@@ -29,11 +29,10 @@ CURLOPT_CERTINFO \- request SSL certificate information
 CURLcode curl_easy_setopt(CURL *handle, CURLOPT_CERTINFO, long certinfo);
 .SH DESCRIPTION
 Pass a long set to 1 to enable libcurl's certificate chain info gatherer. With
-this enabled, libcurl (if built with OpenSSL, NSS or GSKit) will
-extract lots of information and data about the certificates in the certificate
-chain used in the SSL connection. This data may then be retrieved after a
-transfer using \fIcurl_easy_getinfo(3)\fP and its option
-\fICURLINFO_CERTINFO\fP.
+this enabled, libcurl will extract lots of information and data about the
+certificates in the certificate chain used in the SSL connection. This data may
+then be retrieved after a transfer using \fIcurl_easy_getinfo(3)\fP and its
+option \fICURLINFO_CERTINFO\fP.
 .SH DEFAULT
 0
 .SH PROTOCOLS
@@ -41,7 +40,7 @@ All TLS-based
 .SH EXAMPLE
 TODO
 .SH AVAILABILITY
-Added in 7.19.1
+This option is supported by the OpenSSL, GnuTLS, NSS and GSKit backends.
 .SH RETURN VALUE
 Returns CURLE_OK if the option is supported, and CURLE_UNKNOWN_OPTION if not.
 .SH "SEE ALSO"
diff --git a/lib/vtls/gtls.c b/lib/vtls/gtls.c
index 439b6ff..c722e45 100644
--- a/lib/vtls/gtls.c
+++ b/lib/vtls/gtls.c
@@ -53,6 +53,7 @@
 #include "select.h"
 #include "rawstr.h"
 #include "warnless.h"
+#include "x509asn1.h"
 #include "curl_printf.h"
 #include "curl_memory.h"
 /* The last #include file should be: */
@@ -837,6 +838,23 @@ gtls_connect_step3(struct connectdata *conn,
     infof(data, "\t common name: WARNING couldn't obtain\n");
   }
 
+  if(data->set.ssl.certinfo) {
+    unsigned int i;
+
+    result = Curl_ssl_init_certinfo(data, cert_list_size);
+    if(result)
+      return result;
+
+    for(i = 0; i < cert_list_size; i++) {
+      const char *beg = chainp[i].data;
+      const char *end = chainp[i].data + chainp[i].size;
+
+      result = Curl_extract_certinfo(conn, i, beg, end);
+      if(result)
+        return result;
+    }
+  }
+
   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
diff --git a/lib/vtls/gtls.h b/lib/vtls/gtls.h
index af1cb5b..dcae442 100644
--- a/lib/vtls/gtls.h
+++ b/lib/vtls/gtls.h
@@ -57,6 +57,9 @@ bool Curl_gtls_cert_status_request(void);
 /* this backend supports the CAPATH option */
 #define have_curlssl_ca_path 1
 
+/* this backend supports CURLOPT_CERTINFO */
+#define have_curlssl_certinfo 1
+
 /* API setup for GnuTLS */
 #define curlssl_init Curl_gtls_init
 #define curlssl_cleanup Curl_gtls_cleanup
diff --git a/lib/x509asn1.c b/lib/x509asn1.c
index 32f1ea2..75b5144 100644
--- a/lib/x509asn1.c
+++ b/lib/x509asn1.c
@@ -22,7 +22,7 @@
 
 #include "curl_setup.h"
 
-#if defined(USE_GSKIT) || defined(USE_NSS)
+#if defined(USE_GSKIT) || defined(USE_NSS) || defined(USE_GNUTLS)
 
 #include <curl/curl.h>
 #include "urldata.h"
diff --git a/lib/x509asn1.h b/lib/x509asn1.h
index 075c424..0de8932 100644
--- a/lib/x509asn1.h
+++ b/lib/x509asn1.h
@@ -25,7 +25,7 @@
 
 #include "curl_setup.h"
 
-#if defined(USE_GSKIT) || defined(USE_NSS)
+#if defined(USE_GSKIT) || defined(USE_NSS) || defined(USE_GNUTLS)
 
 #include "urldata.h"
 
-- 
2.1.4


