aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/libcurl/curl_easy_getinfo.312
-rw-r--r--include/curl/curl.h28
-rw-r--r--lib/getinfo.c46
-rw-r--r--lib/urldata.h2
4 files changed, 85 insertions, 3 deletions
diff --git a/docs/libcurl/curl_easy_getinfo.3 b/docs/libcurl/curl_easy_getinfo.3
index db0f4d62a..8d000c053 100644
--- a/docs/libcurl/curl_easy_getinfo.3
+++ b/docs/libcurl/curl_easy_getinfo.3
@@ -221,6 +221,18 @@ provided in a series of data in the format "name:content" where the content is
for the specific named data. See also the certinfo.c example. NOTE: this
option is only available in libcurl built with OpenSSL, NSS, GSKit or QsoSSL
support. (Added in 7.19.1)
+.IP CURLINFO_TLS_SESSION
+Pass a pointer to a 'struct curl_tlsinfo *'. The pointer will be initialized
+to refer to a 'struct curl_tlsinfo *' that will contain an enum indicating the
+SSL library used for the handshake and the respective internal TLS session
+structure of this underlying SSL library.
+
+This may then be used to extract certificate information in a format
+convenient for further processing, such as manual validation. NOTE: this
+option may not be available for all SSL backends; unsupported SSL backends
+will return 'CURLSSLBACKEND_NONE' to indicate that they are not supported;
+this does not mean that no SSL backend was used. (Added in 7.34.0)
+
.IP CURLINFO_CONDITION_UNMET
Pass a pointer to a long to receive the number 1 if the condition provided in
the previous request didn't match (see \fICURLOPT_TIMECONDITION\fP). Alas, if
diff --git a/include/curl/curl.h b/include/curl/curl.h
index 14ff7c756..b58939b00 100644
--- a/include/curl/curl.h
+++ b/include/curl/curl.h
@@ -1388,8 +1388,7 @@ typedef enum {
CINIT(ADDRESS_SCOPE, LONG, 171),
/* Collect certificate chain info and allow it to get retrievable with
- CURLINFO_CERTINFO after the transfer is complete. (Unfortunately) only
- working with OpenSSL-powered builds. */
+ CURLINFO_CERTINFO after the transfer is complete. */
CINIT(CERTINFO, LONG, 172),
/* "name" and "pwd" to use when fetching. */
@@ -1986,6 +1985,28 @@ struct curl_certinfo {
format "name: value" */
};
+/* enum for the different supported SSL backends */
+typedef enum {
+ CURLSSLBACKEND_NONE = 0,
+ CURLSSLBACKEND_OPENSSL = 1,
+ CURLSSLBACKEND_GNUTLS = 2,
+ CURLSSLBACKEND_NSS = 3,
+ CURLSSLBACKEND_QSOSSL = 4,
+ CURLSSLBACKEND_GSKIT = 5,
+ CURLSSLBACKEND_POLARSSL = 6,
+ CURLSSLBACKEND_CYASSL = 7,
+ CURLSSLBACKEND_SCHANNEL = 8,
+ CURLSSLBACKEND_DARWINSSL = 9
+} curl_ssl_backend;
+
+/* Information about the SSL library used and the respective internal SSL
+ handle, which can be used to obtain further information regarding the
+ connection. Asked for with CURLINFO_TLS_SESSION. */
+struct curl_tlsinfo {
+ curl_ssl_backend ssl_backend;
+ void *internals;
+};
+
#define CURLINFO_STRING 0x100000
#define CURLINFO_LONG 0x200000
#define CURLINFO_DOUBLE 0x300000
@@ -2037,9 +2058,10 @@ typedef enum {
CURLINFO_PRIMARY_PORT = CURLINFO_LONG + 40,
CURLINFO_LOCAL_IP = CURLINFO_STRING + 41,
CURLINFO_LOCAL_PORT = CURLINFO_LONG + 42,
+ CURLINFO_TLS_SESSION = CURLINFO_SLIST + 43,
/* Fill in new entries below here! */
- CURLINFO_LASTONE = 42
+ CURLINFO_LASTONE = 43
} CURLINFO;
/* CURLINFO_RESPONSE_CODE is the new name for the option previously known as
diff --git a/lib/getinfo.c b/lib/getinfo.c
index 3d09dc684..6a4e72e4a 100644
--- a/lib/getinfo.c
+++ b/lib/getinfo.c
@@ -277,7 +277,53 @@ static CURLcode getinfo_slist(struct SessionHandle *data, CURLINFO info,
ptr.to_certinfo = &data->info.certs;
*param_slistp = ptr.to_slist;
break;
+ case CURLINFO_TLS_SESSION:
+ {
+ struct curl_tlsinfo **tlsinfop = (struct curl_tlsinfo **) param_slistp;
+ struct curl_tlsinfo *tlsinfo = &data->tlsinfo;
+ struct connectdata *conn = data->easy_conn;
+ unsigned int sockindex = 0;
+ *tlsinfop = tlsinfo;
+ tlsinfo->ssl_backend = CURLSSLBACKEND_NONE;
+ tlsinfo->internals = NULL;
+
+ /* Find the active ("in use") SSL connection, if any */
+ while((sockindex < sizeof(conn->ssl) / sizeof(conn->ssl[0])) &&
+ (!conn->ssl[sockindex].use))
+ sockindex++;
+
+ if(sockindex == sizeof(conn->ssl) / sizeof(conn->ssl[0]))
+ break; /* no SSL session found */
+
+ /* Return the TLS session information from the relevant backend */
+#ifdef USE_SSLEAY
+ tlsinfo->ssl_backend = CURLSSLBACKEND_OPENSSL;
+ tlsinfo->internals = conn->ssl[sockindex].ctx;
+#endif
+#ifdef USE_GNUTLS
+ tlsinfo->ssl_backend = CURLSSLBACKEND_GNUTLS;
+ tlsinfo->internals = conn->ssl[sockindex].session;
+#endif
+#ifdef USE_NSS
+ tlsinfo->ssl_backend = CURLSSLBACKEND_NSS;
+ tlsinfo->internals = conn->ssl[sockindex].handle;
+#endif
+#ifdef USE_QSOSSL
+ tlsinfo->ssl_backend = CURLSSLBACKEND_QSOSSL;
+ tlsinfo->internals = conn->ssl[sockindex].handle;
+#endif
+#ifdef USE_GSKIT
+ tlsinfo->ssl_backend = CURLSSLBACKEND_GSKIT;
+ tlsinfo->internals = conn->ssl[sockindex].handle;
+#endif
+ /* NOTE: For other SSL backends, it is not immediately clear what data
+ to return from 'struct ssl_connect_data'; thus, for now we keep the
+ backend as CURLSSLBACKEND_NONE in those cases, which should be
+ interpreted as "not supported" */
+ break;
+ }
+ break;
default:
return CURLE_BAD_FUNCTION_ARGUMENT;
}
diff --git a/lib/urldata.h b/lib/urldata.h
index 98686bb33..29cf9603b 100644
--- a/lib/urldata.h
+++ b/lib/urldata.h
@@ -1637,6 +1637,8 @@ struct SessionHandle {
other dynamic purposes */
struct WildcardData wildcard; /* wildcard download state info */
struct PureInfo info; /* stats, reports and info data */
+ struct curl_tlsinfo tlsinfo; /* Information about the TLS session, only
+ valid after a client has asked for it */
#if defined(CURL_DOES_CONVERSIONS) && defined(HAVE_ICONV)
iconv_t outbound_cd; /* for translating to the network encoding */
iconv_t inbound_cd; /* for translating from the network encoding */