mirror of
https://github.com/curl/curl.git
synced 2026-08-25 08:43:31 +03:00
vtls: feature ssls-export for SSL session im-/export
Adds the experimental feature `ssls-export` to libcurl and curl for importing and exporting SSL sessions from/to a file. * add functions to libcurl API * add command line option `--ssl-sessions <filename>` to curl * add documenation * add support in configure * add support in cmake + add pytest case Closes #15924
This commit is contained in:
parent
8a1ee2b47d
commit
515a21f350
48 changed files with 1662 additions and 125 deletions
|
|
@ -63,3 +63,15 @@ Graduation requirements:
|
|||
|
||||
- it has been given time to mature, so no earlier than April 2025 (twelve
|
||||
months after being added here)
|
||||
|
||||
## SSL session import/export
|
||||
|
||||
Import/Export of SSL sessions tickets in libcurl and curl command line
|
||||
option '--ssl-session <filename>' for faster TLS handshakes and use
|
||||
of TLSv1.3/QUIC Early Data (0-RTT).
|
||||
|
||||
Graduation requirements:
|
||||
|
||||
- the implementation is considered safe
|
||||
|
||||
- feedback from users saying that session export works for their use cases
|
||||
|
|
|
|||
|
|
@ -191,6 +191,7 @@ assumes that CMake generates `Makefile`:
|
|||
- `USE_ECH`: Enable ECH support. Default: `OFF`
|
||||
- `USE_HTTPSRR`: Enable HTTPS RR support. Default: `OFF`
|
||||
- `USE_OPENSSL_QUIC`: Use OpenSSL and nghttp3 libraries for HTTP/3 support. Default: `OFF`
|
||||
- `USE_SSLS_EXPORT`: Enable experimental SSL session import/export. Default: `OFF`
|
||||
|
||||
## Disabling features
|
||||
|
||||
|
|
|
|||
|
|
@ -269,6 +269,7 @@ DPAGES = \
|
|||
ssl-no-revoke.md \
|
||||
ssl-reqd.md \
|
||||
ssl-revoke-best-effort.md \
|
||||
ssl-sessions.md \
|
||||
ssl.md \
|
||||
sslv2.md \
|
||||
sslv3.md \
|
||||
|
|
|
|||
35
docs/cmdline-opts/ssl-sessions.md
Normal file
35
docs/cmdline-opts/ssl-sessions.md
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
---
|
||||
c: Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
SPDX-License-Identifier: curl
|
||||
Long: ssl-sessions
|
||||
Arg: <filename>
|
||||
Protocols: TLS
|
||||
Help: Load/save SSL session tickets from/to this file
|
||||
Added: 8.12.0
|
||||
Category: tls
|
||||
Multi: single
|
||||
See-also:
|
||||
- tls-earlydata
|
||||
Example:
|
||||
- --ssl-sessions sessions.txt $URL
|
||||
---
|
||||
|
||||
# `--ssl-sessions`
|
||||
|
||||
Use the given file to load SSL session tickets into curl's cache before
|
||||
starting any transfers. At the end of a successful curl run, the cached
|
||||
SSL sessions tickets are save to the file, replacing any previous content.
|
||||
|
||||
The file does not have to exist, but curl reports an error if it is
|
||||
unable to create it. Unused loaded tickets are saved again, unless they
|
||||
get replaced or purged from the cache for space reasons.
|
||||
|
||||
Using a session file allows `--tls-earlydata` to send the first request
|
||||
in "0-RTT" mode, should an SSL session with the feature be found. Note that
|
||||
a server may not support early data. Also note that early data does
|
||||
not provide forward secrecy, e.g. is not as secure.
|
||||
|
||||
The SSL session tickets are stored as base64 encoded text, each ticket on
|
||||
its own line. The hostnames are cryptographically salted and hashed. While
|
||||
this prevents someone to easily see the hosts you contacted, they could still
|
||||
check if a specific hostname matches one of the values.
|
||||
|
|
@ -10,6 +10,7 @@ Multi: boolean
|
|||
See-also:
|
||||
- tlsv1.3
|
||||
- tls-max
|
||||
- ssl-sessions
|
||||
Example:
|
||||
- --tls-earlydata $URL
|
||||
---
|
||||
|
|
|
|||
|
|
@ -41,6 +41,8 @@ man_MANS = \
|
|||
curl_easy_reset.3 \
|
||||
curl_easy_send.3 \
|
||||
curl_easy_setopt.3 \
|
||||
curl_easy_ssls_import.3 \
|
||||
curl_easy_ssls_export.3 \
|
||||
curl_easy_strerror.3 \
|
||||
curl_easy_unescape.3 \
|
||||
curl_easy_upkeep.3 \
|
||||
|
|
|
|||
172
docs/libcurl/curl_easy_ssls_export.md
Normal file
172
docs/libcurl/curl_easy_ssls_export.md
Normal file
|
|
@ -0,0 +1,172 @@
|
|||
---
|
||||
c: Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
SPDX-License-Identifier: curl
|
||||
Title: curl_easy_ssls_export
|
||||
Section: 3
|
||||
Source: libcurl
|
||||
See-also:
|
||||
- CURLOPT_SHARE (3)
|
||||
- curl_share_setopt (3)
|
||||
- curl_easy_ssls_import (3)
|
||||
Protocol:
|
||||
- All
|
||||
TLS-backend:
|
||||
- GnuTLS
|
||||
- OpenSSL
|
||||
- BearSSL
|
||||
- wolfSSL
|
||||
- mbedTLS
|
||||
Added-in: 8.12.0
|
||||
---
|
||||
|
||||
# NAME
|
||||
|
||||
curl_easy_ssls_export - export SSL sessions
|
||||
|
||||
# SYNOPSIS
|
||||
|
||||
~~~c
|
||||
#include <curl/curl.h>
|
||||
|
||||
typedef CURLcode curl_ssls_export_function(CURL *handle,
|
||||
void *userptr,
|
||||
const char *session_key,
|
||||
const unsigned char *shmac,
|
||||
size_t shmac_len,
|
||||
const unsigned char *sdata,
|
||||
size_t sdata_len,
|
||||
curl_off_t valid_until,
|
||||
int ietf_tls_id,
|
||||
const char *alpn,
|
||||
size_t earlydata_max);
|
||||
|
||||
CURLcode curl_easy_ssls_export(CURL *handle,
|
||||
curl_ssls_export_function *export_fn,
|
||||
void *userptr);
|
||||
~~~
|
||||
|
||||
# DESCRIPTION
|
||||
|
||||
This function iterates over all SSL session tickets that belong to the
|
||||
easy handle and invokes the **export_fn** callback on each of them, as
|
||||
long as the callback returns **CURLE_OK**.
|
||||
|
||||
The callback may then store this information and use curl_easy_ssls_import(3)
|
||||
in another libcurl instance to add SSL session tickets again. Reuse of
|
||||
SSL session tickets may result in faster handshakes and some connections
|
||||
might be able to send request data in the initial packets (0-RTT).
|
||||
|
||||
From all the parameters passed to the **export_fn** only two need to be
|
||||
persisted: either **session_key** or **shamc** and always **sdata**. All
|
||||
other parameters are informative, e.g. allow the callback to act only
|
||||
on specific session tickets.
|
||||
|
||||
Note that SSL sessions that involve a client certificate or SRP
|
||||
username/password are not exported.
|
||||
|
||||
# Export Function Parameter
|
||||
|
||||
## Session Key
|
||||
|
||||
This is a printable, 0-terminated string that starts with **hostname:port**
|
||||
the session ticket is originating from and also contains all relevant
|
||||
SSL parameters used in the connection. The key also carries the name
|
||||
and version number of the TLS backend used.
|
||||
|
||||
It is recommended to only persist **session_key** when it can be protected
|
||||
from outside access. Since the hostname appears in plain text, it would
|
||||
allow any third party to see how curl has been used for.
|
||||
|
||||
## Salted Hash
|
||||
|
||||
A binary blob of **shmac_len** bytes that contains a random salt and
|
||||
a cryptographic hash of the salt and **session_key**. The salt is generated
|
||||
for every session individually. Storing **shmac** is recommended when
|
||||
placing session tickets in a file, for example.
|
||||
|
||||
A third party may brute-force known hostnames, but cannot just "grep" for
|
||||
them.
|
||||
|
||||
## Session Data
|
||||
|
||||
A binary blob of **sdata_len** bytes, **sdata** contains all relevant
|
||||
SSL session ticket information for a later import - apart from **session_key**
|
||||
and **shmac**.
|
||||
|
||||
## valid_until
|
||||
|
||||
Seconds since EPOCH (1970-01-01) until the session ticket is considered
|
||||
valid.
|
||||
|
||||
## TLS Version
|
||||
|
||||
The IETF assigned number for the TLS version the session ticket originates
|
||||
from. This is **0x0304** for TLSv1.3, **0x0303** for 1.2, etc. Session
|
||||
tickets from version 1.3 have better security properties, so an export
|
||||
might store only those.
|
||||
|
||||
## ALPN
|
||||
|
||||
The ALPN protocol that had been negotiated with the host. This may be
|
||||
**NULL** if negotiation gave no result or had not been attempted.
|
||||
|
||||
## Early Data
|
||||
|
||||
The maximum amount of bytes the server supports to receive in early data
|
||||
(0-RTT). This is 0 unless the server explicitly indicates support.
|
||||
|
||||
# %PROTOCOLS%
|
||||
|
||||
# EXAMPLE
|
||||
|
||||
~~~c
|
||||
CURLcode my_export_cb(CURL *handle,
|
||||
void *userptr,
|
||||
const char *session_key,
|
||||
const unsigned char *shmac,
|
||||
size_t shmac_len,
|
||||
const unsigned char *sdata,
|
||||
size_t sdata_len,
|
||||
curl_off_t valid_until,
|
||||
int ietf_tls_id,
|
||||
const char *alpn,
|
||||
size_t earlydata_max)
|
||||
{
|
||||
/* persist sdata */
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
CURLSHcode sh;
|
||||
CURLSH *share = curl_share_init();
|
||||
CURLcode rc;
|
||||
CURL *curl;
|
||||
|
||||
sh = curl_share_setopt(share, CURLSHOPT_SHARE, CURL_LOCK_DATA_SSL_SESSION);
|
||||
if(sh)
|
||||
printf("Error: %s\n", curl_share_strerror(sh));
|
||||
|
||||
curl = curl_easy_init();
|
||||
if(curl) {
|
||||
curl_easy_setopt(curl, CURLOPT_SHARE, share);
|
||||
|
||||
rc = curl_easy_ssls_export(curl, my_export_cb, NULL);
|
||||
|
||||
/* always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
}
|
||||
curl_share_cleanup(share);
|
||||
}
|
||||
~~~
|
||||
|
||||
# %AVAILABILITY%
|
||||
|
||||
# RETURN VALUE
|
||||
|
||||
This function returns a CURLcode indicating success or error.
|
||||
|
||||
CURLE_OK (0) means everything was OK, non-zero means an error occurred, see
|
||||
libcurl-errors(3). If CURLOPT_ERRORBUFFER(3) was set with curl_easy_setopt(3)
|
||||
there can be an error message stored in the error buffer when non-zero is
|
||||
returned.
|
||||
84
docs/libcurl/curl_easy_ssls_import.md
Normal file
84
docs/libcurl/curl_easy_ssls_import.md
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
---
|
||||
c: Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
SPDX-License-Identifier: curl
|
||||
Title: curl_easy_ssls_import
|
||||
Section: 3
|
||||
Source: libcurl
|
||||
See-also:
|
||||
- CURLOPT_SHARE (3)
|
||||
- curl_share_setopt (3)
|
||||
- curl_easy_ssls_export (3)
|
||||
Protocol:
|
||||
- All
|
||||
Added-in: 8.12.0
|
||||
---
|
||||
|
||||
# NAME
|
||||
|
||||
curl_easy_ssls_export - export SSL sessions
|
||||
|
||||
# SYNOPSIS
|
||||
|
||||
~~~c
|
||||
#include <curl/curl.h>
|
||||
|
||||
CURLcode curl_easy_ssls_import(CURL *handle,
|
||||
const char *session_key,
|
||||
const unsigned char *shmac, size_t shmac_len,
|
||||
const unsigned char *sdata, size_t sdata_len);
|
||||
~~~
|
||||
|
||||
# DESCRIPTION
|
||||
|
||||
This function imports a previously exported SSL session ticket. **sdata** and
|
||||
**sdata_len** must always be provided. If **session_key** is **NULL**, then
|
||||
**shmac** and **shmac_len** must be given as received during the export.
|
||||
See curl_easy_ssls_export(3) for a description of those.
|
||||
|
||||
Import of session tickets from other curl versions may fail due to changes
|
||||
in the handling of **shmac** or **sdata**. A session ticket which has
|
||||
already expired is silently discarded.
|
||||
|
||||
# %PROTOCOLS%
|
||||
|
||||
# EXAMPLE
|
||||
|
||||
~~~c
|
||||
int main(void)
|
||||
{
|
||||
CURLSHcode sh;
|
||||
CURLSH *share = curl_share_init();
|
||||
CURLcode rc;
|
||||
CURL *curl;
|
||||
|
||||
sh = curl_share_setopt(share, CURLSHOPT_SHARE, CURL_LOCK_DATA_SSL_SESSION);
|
||||
if(sh)
|
||||
printf("Error: %s\n", curl_share_strerror(sh));
|
||||
|
||||
curl = curl_easy_init();
|
||||
if(curl) {
|
||||
unsigned char *shmac, *sdata;
|
||||
size_t hlen, slen;
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_SHARE, share);
|
||||
|
||||
/* read shmac and sdata from storage */
|
||||
rc = curl_easy_ssls_import(curl, NULL, shmac, hlen, sdata, slen);
|
||||
|
||||
/* always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
}
|
||||
curl_share_cleanup(share);
|
||||
}
|
||||
~~~
|
||||
|
||||
# %AVAILABILITY%
|
||||
|
||||
# RETURN VALUE
|
||||
|
||||
This function returns a CURLcode indicating success or error.
|
||||
|
||||
CURLE_OK (0) means everything was OK, non-zero means an error occurred, see
|
||||
libcurl-errors(3). If CURLOPT_ERRORBUFFER(3) was set with curl_easy_setopt(3)
|
||||
there can be an error message stored in the error buffer when non-zero is
|
||||
returned.
|
||||
|
|
@ -105,6 +105,10 @@ Tracing of DNS-over-HTTP operations to resolve hostnames.
|
|||
|
||||
Traces reading of upload data from the application in order to send it to the server.
|
||||
|
||||
## `ssls`
|
||||
|
||||
Tracing of SSL Session handling, e.g. caching/import/export.
|
||||
|
||||
## `smtp`
|
||||
|
||||
Tracing of SMTP operations when this protocol is enabled in your build.
|
||||
|
|
|
|||
|
|
@ -300,6 +300,13 @@ GSS-API Negotiation Mechanism, defined in RFC 2478.) (added in 7.10.8)
|
|||
|
||||
supports SSL (HTTPS/FTPS) (Added in 7.10)
|
||||
|
||||
## SSLS-EXPORT
|
||||
|
||||
*features* mask bit: non-existent
|
||||
|
||||
libcurl was built with SSL session import/export support
|
||||
(experimental, added in 8.12.0)
|
||||
|
||||
## SSPI
|
||||
|
||||
*features* mask bit: CURL_VERSION_SSPI
|
||||
|
|
|
|||
|
|
@ -235,6 +235,7 @@
|
|||
--ssl-no-revoke 7.44.0
|
||||
--ssl-reqd 7.20.0
|
||||
--ssl-revoke-best-effort 7.70.0
|
||||
--ssl-sessions 8.12.0
|
||||
--sslv2 (-2) 5.9
|
||||
--sslv3 (-3) 5.9
|
||||
--stderr 6.2
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue