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