1--- 2c: Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al. 3SPDX-License-Identifier: curl 4Title: CURLINFO_TLS_SSL_PTR 5Section: 3 6Source: libcurl 7See-also: 8 - CURLINFO_TLS_SESSION (3) 9 - curl_easy_getinfo (3) 10 - curl_easy_setopt (3) 11Protocol: 12 - TLS 13TLS-backend: 14 - BearSSL 15 - GnuTLS 16 - mbedTLS 17 - OpenSSL 18 - Schannel 19 - Secure Transport 20 - wolfSSL 21Added-in: 7.48.0 22--- 23 24# NAME 25 26CURLINFO_TLS_SESSION, CURLINFO_TLS_SSL_PTR - get TLS session info 27 28# SYNOPSIS 29 30~~~c 31#include <curl/curl.h> 32 33CURLcode curl_easy_getinfo(CURL *handle, CURLINFO_TLS_SSL_PTR, 34 struct curl_tlssessioninfo **session); 35 36/* if you need compatibility with libcurl < 7.48.0 use 37 CURLINFO_TLS_SESSION instead: */ 38 39CURLcode curl_easy_getinfo(CURL *handle, CURLINFO_TLS_SESSION, 40 struct curl_tlssessioninfo **session); 41~~~ 42 43# DESCRIPTION 44 45Pass a pointer to a *struct curl_tlssessioninfo **. The pointer is initialized 46to refer to a *struct curl_tlssessioninfo ** that contains an enum indicating 47the SSL library used for the handshake and a pointer to the respective 48internal TLS session structure of this underlying SSL library. 49 50This option may be useful for example to extract certificate information in a 51format convenient for further processing, such as manual validation. Refer to 52the **LIMITATIONS** section. 53 54~~~c 55struct curl_tlssessioninfo { 56 curl_sslbackend backend; 57 void *internals; 58}; 59~~~ 60 61The *backend* struct member is one of the defines in the CURLSSLBACKEND_* 62series: CURLSSLBACKEND_NONE (when built without TLS support), 63CURLSSLBACKEND_WOLFSSL, CURLSSLBACKEND_SECURETRANSPORT, CURLSSLBACKEND_GNUTLS, 64CURLSSLBACKEND_MBEDTLS, CURLSSLBACKEND_NSS, CURLSSLBACKEND_OPENSSL or 65CURLSSLBACKEND_SCHANNEL. (Note that the OpenSSL 66forks are all reported as just OpenSSL here.) 67 68The *internals* struct member points to a TLS library specific pointer for 69the active ("in use") SSL connection, with the following underlying types: 70 71## GnuTLS 72 73**gnutls_session_t** 74 75## OpenSSL 76 77CURLINFO_TLS_SESSION(3): **SSL_CTX *** 78 79CURLINFO_TLS_SSL_PTR(3): **SSL *** 80Since 7.48.0 the *internals* member can point to these other SSL backends 81as well: 82 83## mbedTLS 84 85**mbedTLS_ssl_context *** 86 87## Secure Channel 88 89**CtxtHandle *** 90 91## Secure Transport 92 93**SSLContext *** 94 95## wolfSSL 96 97**SSL *** 98 99## 100 101If the *internals* pointer is NULL then either the SSL backend is not 102supported, an SSL session has not yet been established or the connection is no 103longer associated with the easy handle (e.g. curl_easy_perform(3) has 104returned). 105 106# LIMITATIONS 107 108This option has some limitations that could make it unsafe when it comes to 109the manual verification of certificates. 110 111This option only retrieves the first in-use SSL session pointer for your easy 112handle, however your easy handle may have more than one in-use SSL session if 113using FTP over SSL. That is because the FTP protocol has a control channel and 114a data channel and one or both may be over SSL. Currently there is no way to 115retrieve a second in-use SSL session associated with an easy handle. 116 117This option has not been thoroughly tested with clear text protocols that can 118be upgraded/downgraded to/from SSL: FTP, SMTP, POP3, IMAP when used with 119CURLOPT_USE_SSL(3). Though you can to retrieve the SSL pointer, it is possible 120that before you can do that, data (including auth) may have already been sent 121over a connection after it was upgraded. 122 123Renegotiation. If unsafe renegotiation or renegotiation in a way that the 124certificate is allowed to change is allowed by your SSL library this may occur 125and the certificate may change, and data may continue to be sent or received 126after renegotiation but before you are able to get the (possibly) changed SSL 127pointer, with the (possibly) changed certificate information. 128 129Instead of using this option to poll for certificate changes use 130CURLOPT_SSL_CTX_FUNCTION(3) to set a verification callback, if supported. 131That is safer and does not suffer from any of the problems above. 132 133How are you using this option? Are you affected by any of these limitations? 134Please let us know by making a comment at 135https://github.com/curl/curl/issues/685 136 137# %PROTOCOLS% 138 139# EXAMPLE 140 141~~~c 142#include <curl/curl.h> 143#include <openssl/ssl.h> 144 145CURL *curl; 146static size_t wf(void *ptr, size_t size, size_t nmemb, void *stream) 147{ 148 const struct curl_tlssessioninfo *info = NULL; 149 CURLcode res = curl_easy_getinfo(curl, CURLINFO_TLS_SSL_PTR, &info); 150 if(info && !res) { 151 if(CURLSSLBACKEND_OPENSSL == info->backend) { 152 printf("OpenSSL ver. %s\n", SSL_get_version((SSL*)info->internals)); 153 } 154 } 155 return size * nmemb; 156} 157 158int main(int argc, char **argv) 159{ 160 CURLcode res; 161 curl = curl_easy_init(); 162 if(curl) { 163 curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); 164 curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, wf); 165 res = curl_easy_perform(curl); 166 curl_easy_cleanup(curl); 167 } 168 return res; 169} 170~~~ 171 172# HISTORY 173 174This option supersedes CURLINFO_TLS_SESSION(3) which was added in 7.34.0. 175This option is exactly the same as that option except in the case of OpenSSL. 176 177# %AVAILABILITY% 178 179# RETURN VALUE 180 181Returns CURLE_OK if the option is supported, and CURLE_UNKNOWN_OPTION if not. 182