diff options
| -rw-r--r-- | docs/libcurl/curl_easy_getinfo.3 | 12 | ||||
| -rw-r--r-- | include/curl/curl.h | 28 | ||||
| -rw-r--r-- | lib/getinfo.c | 46 | ||||
| -rw-r--r-- | lib/urldata.h | 2 | 
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 */ | 
