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