On Mon, 9 Mar 2015, bch wrote:
OpenSSL and DarwinSSL w/ suggestions from Steve re: style.
Comments welcome.
Thanks a lot and sorry again for my slowness here. My comments in a somewhat
random order:
1 - Please run 'make checksrc' and fix all nits before you post a patch. There
were several minor formatting quirks. I fixed them.
2 - Please add the necessary section to the curl_easy_getinfo.3 man page
3 - Why make set_ssl_version_long() in openssl.c take a struct connectdata *
parameter? Wouldn't a struct SessionHandle straight away make more sense?
4 - The darwinssl version of set_ssl_version_long() seems to not even compile.
It uses a 'connssl' variable that isn't declared!
Finally, I'm attaching my slightly edited version of your diff as a git
commit. It'll be convenient if you keep it a commit and you just send a full
new patch (as git format-patch outputs) when you have done your ammends to it!
--
/ daniel.haxx.se
From 93ed8fbc9fdf74a67f88487b1b315759f2c68753 Mon Sep 17 00:00:00 2001
From: Brad Harder <[email protected]>
Date: Wed, 25 Mar 2015 23:34:44 +0100
Subject: [PATCH] CURLINFO_SSL_NEGOTIATED_VERSION: added
Returns the negotiated SSL/TLS version. Initial support for OpenSSL and
DarwinSSL added.
---
docs/libcurl/symbols-in-versions | 1 +
include/curl/curl.h | 3 ++-
lib/getinfo.c | 4 ++++
lib/urldata.h | 1 +
lib/vtls/darwinssl.c | 32 ++++++++++++++++++++++++++++++++
lib/vtls/openssl.c | 28 ++++++++++++++++++++++++++++
6 files changed, 68 insertions(+), 1 deletion(-)
diff --git a/docs/libcurl/symbols-in-versions b/docs/libcurl/symbols-in-versions
index 1ed3c21..d7523dd 100644
--- a/docs/libcurl/symbols-in-versions
+++ b/docs/libcurl/symbols-in-versions
@@ -225,10 +225,11 @@ CURLINFO_LASTSOCKET 7.15.2
CURLINFO_LOCAL_IP 7.21.0
CURLINFO_LOCAL_PORT 7.21.0
CURLINFO_LONG 7.4.1
CURLINFO_MASK 7.4.1
CURLINFO_NAMELOOKUP_TIME 7.4.1
+CURLINFO_SSL_NEGOTIATED_VERSION 7.42.0
CURLINFO_NONE 7.4.1
CURLINFO_NUM_CONNECTS 7.12.3
CURLINFO_OS_ERRNO 7.12.2
CURLINFO_PRETRANSFER_TIME 7.4.1
CURLINFO_PRIMARY_IP 7.19.0
diff --git a/include/curl/curl.h b/include/curl/curl.h
index ae1b0e4..60db3c9 100644
--- a/include/curl/curl.h
+++ b/include/curl/curl.h
@@ -2116,13 +2116,14 @@ typedef enum {
CURLINFO_RTSP_CSEQ_RECV = CURLINFO_LONG + 39,
CURLINFO_PRIMARY_PORT = CURLINFO_LONG + 40,
CURLINFO_LOCAL_IP = CURLINFO_STRING + 41,
CURLINFO_LOCAL_PORT = CURLINFO_LONG + 42,
CURLINFO_TLS_SESSION = CURLINFO_SLIST + 43,
+ CURLINFO_SSL_NEGOTIATED_VERSION = CURLINFO_LONG + 44,
/* Fill in new entries below here! */
- CURLINFO_LASTONE = 43
+ CURLINFO_LASTONE = 44
} CURLINFO;
/* CURLINFO_RESPONSE_CODE is the new name for the option previously known as
CURLINFO_HTTP_CODE */
#define CURLINFO_HTTP_CODE CURLINFO_RESPONSE_CODE
diff --git a/lib/getinfo.c b/lib/getinfo.c
index 910f520..156deea 100644
--- a/lib/getinfo.c
+++ b/lib/getinfo.c
@@ -67,10 +67,11 @@ CURLcode Curl_initinfo(struct SessionHandle *data)
info->conn_primary_ip[0] = '\0';
info->conn_local_ip[0] = '\0';
info->conn_primary_port = 0;
info->conn_local_port = 0;
+ info->ssl_negotiated_version = -1L;
return CURLE_OK;
}
static CURLcode getinfo_char(struct SessionHandle *data, CURLINFO info,
@@ -134,10 +135,13 @@ static CURLcode getinfo_long(struct SessionHandle *data, CURLINFO info,
*param_longp = data->info.httpcode;
break;
case CURLINFO_HTTP_CONNECTCODE:
*param_longp = data->info.httpproxycode;
break;
+ case CURLINFO_SSL_NEGOTIATED_VERSION:
+ *param_longp = data->info.ssl_negotiated_version;
+ break;
case CURLINFO_FILETIME:
*param_longp = data->info.filetime;
break;
case CURLINFO_HEADER_SIZE:
*param_longp = data->info.header_size;
diff --git a/lib/urldata.h b/lib/urldata.h
index b1b1a67..8e5c3e6 100644
--- a/lib/urldata.h
+++ b/lib/urldata.h
@@ -1104,10 +1104,11 @@ struct PureInfo {
long conn_local_port;
struct curl_certinfo certs; /* info about the certs, only populated in
OpenSSL builds. Asked for with
CURLOPT_CERTINFO / CURLINFO_CERTINFO */
+ long ssl_negotiated_version; /* the version of ssl/tls that we negotiated */
};
struct Progress {
long lastshow; /* time() of the last displayed progress meter or NULL to
diff --git a/lib/vtls/darwinssl.c b/lib/vtls/darwinssl.c
index 03adcef..f73f0df 100644
--- a/lib/vtls/darwinssl.c
+++ b/lib/vtls/darwinssl.c
@@ -1809,10 +1809,41 @@ static int verify_cert(const char *cafile, struct SessionHandle *data,
trust_eval);
return CURLE_PEER_FAILED_VERIFICATION;
}
}
+static void set_ssl_version_long(SSLContextRef ssl_ctx,
+ struct connectdata *conn)
+{
+ SSLProtocol protocol = 0;
+ long code = -1L;
+ (void)SSLGetNegotiatedProtocolVersion(connssl->ssl_ctx, &protocol);
+ if(ssl_ctx) {
+ (void)SSLGetNegotiatedProtocolVersion(connssl->ssl_ctx, &protocol);
+ switch(protocol) {
+ case kSSLProtocol2:
+ code = CURL_SSLVERSION_SSLv2;
+ break;
+ case kSSLProtocol3:
+ code = CURL_SSLVERSION_SSLv3;
+ break;
+ case kTLSProtocol1:
+ code = CURL_SSLVERSION_TLSv1;
+ break;
+#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
+ case kTLSProtocol11:
+ code = CURL_SSLVERSION_TLSv1_1;
+ break;
+ case kTLSProtocol12:
+ code = CURL_SSLVERSION_TLSv1_2;
+ break;
+#endif
+ }
+ }
+ conn->data->info.ssl_negotiated_version = code;
+}
+
static CURLcode
darwinssl_connect_step2(struct connectdata *conn, int sockindex)
{
struct SessionHandle *data = conn->data;
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
@@ -1913,10 +1944,11 @@ darwinssl_connect_step2(struct connectdata *conn, int sockindex)
}
else {
/* we have been connected fine, we're not waiting for anything else. */
connssl->connecting_state = ssl_connect_3;
+ set_ssl_version_long(connssl->ssl_ctx, conn);
/* Informational message */
(void)SSLGetNegotiatedCipher(connssl->ssl_ctx, &cipher);
(void)SSLGetNegotiatedProtocolVersion(connssl->ssl_ctx, &protocol);
switch (protocol) {
case kSSLProtocol2:
diff --git a/lib/vtls/openssl.c b/lib/vtls/openssl.c
index 7a5a7dc..26e6ff7 100644
--- a/lib/vtls/openssl.c
+++ b/lib/vtls/openssl.c
@@ -1666,10 +1666,37 @@ select_next_proto_cb(SSL *ssl,
return SSL_TLSEXT_ERR_OK;
}
#endif /* HAS_NPN */
+static void set_ssl_version_long(SSL *ssl, struct connectdata *conn)
+{
+ long code = -1L;
+ if(ssl) {
+ switch(SSL_version(ssl)) {
+#if OPENSSL_VERSION_NUMBER >= 0x1000100FL
+ case TLS1_2_VERSION:
+ code = CURL_SSLVERSION_TLSv1_2;
+ break;
+ case TLS1_1_VERSION:
+ code = CURL_SSLVERSION_TLSv1_1;
+ break;
+#endif
+ case TLS1_VERSION:
+ code = CURL_SSLVERSION_TLSv1;
+ break;
+ case SSL3_VERSION:
+ code = CURL_SSLVERSION_SSLv3;
+ break;
+ case SSL2_VERSION:
+ code = CURL_SSLVERSION_SSLv2;
+ break;
+ }
+ }
+ conn->data->info.ssl_negotiated_version = code;
+}
+
static const char *
get_ssl_version_txt(SSL *ssl)
{
if(!ssl)
return "";
@@ -2207,10 +2234,11 @@ static CURLcode ossl_connect_step2(struct connectdata *conn, int sockindex)
}
else {
/* we have been connected fine, we're not waiting for anything else. */
connssl->connecting_state = ssl_connect_3;
+ set_ssl_version_long(connssl->handle, conn);
/* Informational message */
infof(data, "SSL connection using %s / %s\n",
get_ssl_version_txt(connssl->handle),
SSL_get_cipher(connssl->handle));
--
2.1.4
-------------------------------------------------------------------
List admin: http://cool.haxx.se/list/listinfo/curl-library
Etiquette: http://curl.haxx.se/mail/etiquette.html