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

Reply via email to