Skip to content

Commit a318c6a

Browse files
committed
Add client-side session caching
Add support for client-side caching. Uses an application defined "cache_id" to identify a connection. This cache_id may be an IP address, DNS name or anything else the client wishes to use.
1 parent 9505105 commit a318c6a

16 files changed

Lines changed: 460 additions & 30 deletions

crypto/err/openssl.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1346,6 +1346,7 @@ SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT:272:\
13461346
attempt to reuse session in different context
13471347
SSL_R_AT_LEAST_TLS_1_2_NEEDED_IN_SUITEB_MODE:158:\
13481348
at least (D)TLS 1.2 needed in Suite B mode
1349+
SSL_R_BAD_CACHE_MODE:424:bad cache mode
13491350
SSL_R_BAD_CERTIFICATE:348:bad certificate
13501351
SSL_R_BAD_CHANGE_CIPHER_SPEC:103:bad change cipher spec
13511352
SSL_R_BAD_CIPHER:186:bad cipher
@@ -1517,6 +1518,7 @@ SSL_R_NOT_ON_RECORD_BOUNDARY:182:not on record boundary
15171518
SSL_R_NOT_REPLACING_CERTIFICATE:289:not replacing certificate
15181519
SSL_R_NOT_SERVER:284:not server
15191520
SSL_R_NO_APPLICATION_PROTOCOL:235:no application protocol
1521+
SSL_R_NO_CACHE_ID_ON_SERVER:425:no cache id on server
15201522
SSL_R_NO_CERTIFICATES_RETURNED:176:no certificates returned
15211523
SSL_R_NO_CERTIFICATE_ASSIGNED:177:no certificate assigned
15221524
SSL_R_NO_CERTIFICATE_SET:179:no certificate set
@@ -1590,6 +1592,8 @@ SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING:345:scsv received when renegotiating
15901592
SSL_R_SCT_VERIFICATION_FAILED:208:sct verification failed
15911593
SSL_R_SEQUENCE_CTR_WRAPPED:327:sequence ctr wrapped
15921594
SSL_R_SERVERHELLO_TLSEXT:275:serverhello tlsext
1595+
SSL_R_SESSION_ALREADY_IN_CACHE:426:session already in cache
1596+
SSL_R_SESSION_ALREADY_SET:427:session already set
15931597
SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED:277:session id context uninitialized
15941598
SSL_R_SHUTDOWN_WHILE_IN_INIT:407:shutdown while in init
15951599
SSL_R_SIGNATURE_ALGORITHMS_ERROR:360:signature algorithms error

crypto/ssl_err.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ static const ERR_STRING_DATA SSL_str_reasons[] = {
2323
"attempt to reuse session in different context"},
2424
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_AT_LEAST_TLS_1_2_NEEDED_IN_SUITEB_MODE),
2525
"at least (D)TLS 1.2 needed in Suite B mode"},
26+
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_BAD_CACHE_MODE), "bad cache mode"},
2627
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_BAD_CERTIFICATE), "bad certificate"},
2728
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_BAD_CHANGE_CIPHER_SPEC),
2829
"bad change cipher spec"},
@@ -292,6 +293,8 @@ static const ERR_STRING_DATA SSL_str_reasons[] = {
292293
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_NOT_SERVER), "not server"},
293294
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_NO_APPLICATION_PROTOCOL),
294295
"no application protocol"},
296+
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_NO_CACHE_ID_ON_SERVER),
297+
"no cache id on server"},
295298
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_NO_CERTIFICATES_RETURNED),
296299
"no certificates returned"},
297300
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_NO_CERTIFICATE_ASSIGNED),
@@ -407,6 +410,10 @@ static const ERR_STRING_DATA SSL_str_reasons[] = {
407410
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_SEQUENCE_CTR_WRAPPED),
408411
"sequence ctr wrapped"},
409412
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_SERVERHELLO_TLSEXT), "serverhello tlsext"},
413+
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_SESSION_ALREADY_IN_CACHE),
414+
"session already in cache"},
415+
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_SESSION_ALREADY_SET),
416+
"session already set"},
410417
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED),
411418
"session id context uninitialized"},
412419
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_SHUTDOWN_WHILE_IN_INIT),

doc/build.info

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2775,6 +2775,10 @@ DEPEND[html/man3/SSL_session_reused.html]=man3/SSL_session_reused.pod
27752775
GENERATE[html/man3/SSL_session_reused.html]=man3/SSL_session_reused.pod
27762776
DEPEND[man/man3/SSL_session_reused.3]=man3/SSL_session_reused.pod
27772777
GENERATE[man/man3/SSL_session_reused.3]=man3/SSL_session_reused.pod
2778+
DEPEND[html/man3/SSL_set1_cache_id.html]=man3/SSL_set1_cache_id.pod
2779+
GENERATE[html/man3/SSL_set1_cache_id.html]=man3/SSL_set1_cache_id.pod
2780+
DEPEND[man/man3/SSL_set1_cache_id.3]=man3/SSL_set1_cache_id.pod
2781+
GENERATE[man/man3/SSL_set1_cache_id.3]=man3/SSL_set1_cache_id.pod
27782782
DEPEND[html/man3/SSL_set1_host.html]=man3/SSL_set1_host.pod
27792783
GENERATE[html/man3/SSL_set1_host.html]=man3/SSL_set1_host.pod
27802784
DEPEND[man/man3/SSL_set1_host.3]=man3/SSL_set1_host.pod
@@ -3739,6 +3743,7 @@ html/man3/SSL_read.html \
37393743
html/man3/SSL_read_early_data.html \
37403744
html/man3/SSL_rstate_string.html \
37413745
html/man3/SSL_session_reused.html \
3746+
html/man3/SSL_set1_cache_id.html \
37423747
html/man3/SSL_set1_host.html \
37433748
html/man3/SSL_set1_initial_peer_addr.html \
37443749
html/man3/SSL_set1_server_cert_type.html \
@@ -4411,6 +4416,7 @@ man/man3/SSL_read.3 \
44114416
man/man3/SSL_read_early_data.3 \
44124417
man/man3/SSL_rstate_string.3 \
44134418
man/man3/SSL_session_reused.3 \
4419+
man/man3/SSL_set1_cache_id.3 \
44144420
man/man3/SSL_set1_host.3 \
44154421
man/man3/SSL_set1_initial_peer_addr.3 \
44164422
man/man3/SSL_set1_server_cert_type.3 \

doc/man3/SSL_CTX_sess_set_get_cb.pod

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@ SSL_CTX_sess_set_new_cb, SSL_CTX_sess_set_remove_cb, SSL_CTX_sess_set_get_cb, SS
1414
void (*remove_session_cb)(SSL_CTX *ctx,
1515
SSL_SESSION *));
1616
void SSL_CTX_sess_set_get_cb(SSL_CTX *ctx,
17-
SSL_SESSION (*get_session_cb)(SSL *,
18-
const unsigned char *,
19-
int, int *));
17+
SSL_SESSION (*get_session_cb)(SSL *ssl,
18+
const unsigned char *data,
19+
int len, int *copy));
2020

2121
int (*SSL_CTX_sess_get_new_cb(SSL_CTX *ctx))(struct ssl_st *ssl,
2222
SSL_SESSION *sess);
@@ -86,7 +86,7 @@ for all sessions in the internal session cache when
8686
L<SSL_CTX_free(3)> is called. The remove_session_cb() is passed
8787
the B<ctx> and the ssl session B<sess>. It does not provide any feedback.
8888

89-
The get_session_cb() is only called on SSL/TLS servers, and is given
89+
The get_session_cb() is called on SSL/TLS servers, and is given
9090
the session id
9191
proposed by the client. The get_session_cb() is always called, even when
9292
session caching was disabled. The get_session_cb() is passed the
@@ -98,6 +98,16 @@ If the get_session_cb() does not write to B<copy>, the reference count
9898
is incremented and the session must be explicitly freed with
9999
L<SSL_SESSION_free(3)>.
100100

101+
The get_session_cb() is called on SSL/TLS clients with the application-defined
102+
cache identifier set by the client. The get_session_cb() is always called when
103+
session caching is disabled. The get_session_cb() is passed the
104+
B<ssl> connection, the cache identifier of length B<length> at the memory location
105+
B<data>. With the parameter B<copy> the callback can require the
106+
library to increment the reference count of the SSL_SESSION object,
107+
Normally the reference count is not incremented and therefore the
108+
session must not be explicitly freed with
109+
L<SSL_SESSION_free(3)>.
110+
101111
=head1 RETURN VALUES
102112

103113
SSL_CTX_sess_get_new_cb(), SSL_CTX_sess_get_remove_cb() and SSL_CTX_sess_get_get_cb()
@@ -109,11 +119,13 @@ L<ssl(7)>, L<d2i_SSL_SESSION(3)>,
109119
L<SSL_CTX_set_session_cache_mode(3)>,
110120
L<SSL_CTX_flush_sessions(3)>,
111121
L<SSL_SESSION_free(3)>,
112-
L<SSL_CTX_free(3)>
122+
L<SSL_CTX_free(3)>,
123+
L<SSL_get1_previous_client_session(3)>,
124+
L<SSL_set1_cache_id(3)>
113125

114126
=head1 COPYRIGHT
115127

116-
Copyright 2001-2020 The OpenSSL Project Authors. All Rights Reserved.
128+
Copyright 2001-2025 The OpenSSL Project Authors. All Rights Reserved.
117129

118130
Licensed under the Apache License 2.0 (the "License"). You may not use
119131
this file except in compliance with the License. You can obtain a copy

doc/man3/SSL_CTX_set_session_cache_mode.pod

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -49,12 +49,16 @@ No session caching for client or server takes place.
4949

5050
=item SSL_SESS_CACHE_CLIENT
5151

52-
Client sessions are added to the session cache. As there is no reliable way
53-
for the OpenSSL library to know whether a session should be reused or which
54-
session to choose (due to the abstract BIO layer the SSL engine does not
55-
have details about the connection), the application must select the session
56-
to be reused by using the L<SSL_set_session(3)>
57-
function. This option is not activated by default.
52+
Client sessions are added to the session cache. Sessions are identified by their
53+
cache identifier set via L<SSL_set1_cache_id(3)> when they are created by an SSL.
54+
This cache identifier must be set before calling L<SSL_connect(3)>.
55+
56+
The application then can retrieve prior sessions via L<SSL_get1_previous_client_session(3)>.
57+
After the session has been retrieved, it may be examined to determine whether
58+
it can (or should) be used. The session must then be applied to the SSL object via the
59+
L<SSL_set_session(3)> before it can be used during L<SSL_connect(3)>.
60+
61+
This option is not activated by default.
5862

5963
=item SSL_SESS_CACHE_SERVER
6064

@@ -64,10 +68,19 @@ the internal session cache (unless SSL_SESS_CACHE_NO_INTERNAL_LOOKUP is set),
6468
then (second) in the external cache if available. If the session is found, the
6569
server will try to reuse the session. This is the default.
6670

71+
Servers must not use L<SSL_set1_cache_id(3)>, otherwise, the session will not be
72+
found in the cache.
73+
6774
=item SSL_SESS_CACHE_BOTH
6875

6976
Enable both SSL_SESS_CACHE_CLIENT and SSL_SESS_CACHE_SERVER at the same time.
7077

78+
Servers must not use L<SSL_set1_cache_id(3)>, otherwise, the session will not be
79+
found in the cache.
80+
81+
Clients must use L<SSL_set1_cache_id(3)> in order for sessions to be found in the cache
82+
via L<SSL_get1_previous_client_session(3)>.
83+
7184
=item SSL_SESS_CACHE_NO_AUTO_CLEAR
7285

7386
Normally the session cache is checked for expired sessions every
@@ -121,22 +134,25 @@ SSL_CTX_set_session_cache_mode() returns the previously set cache mode.
121134

122135
SSL_CTX_get_session_cache_mode() returns the currently set cache mode.
123136

124-
125137
=head1 SEE ALSO
126138

127139
L<ssl(7)>, L<SSL_set_session(3)>,
128140
L<SSL_session_reused(3)>,
141+
L<SSL_get0_cache_id(3)>,
142+
L<SSL_set1_cache_id(3)>,
143+
L<SSL_get1_previous_client_session(3)>,
129144
L<SSL_CTX_add_session(3)>,
130145
L<SSL_CTX_sess_number(3)>,
131146
L<SSL_CTX_sess_set_cache_size(3)>,
132147
L<SSL_CTX_sess_set_get_cb(3)>,
133148
L<SSL_CTX_set_session_id_context(3)>,
134149
L<SSL_CTX_set_timeout(3)>,
135-
L<SSL_CTX_flush_sessions(3)>
150+
L<SSL_CTX_flush_sessions(3)>,
151+
L<SSL_connect(3)>
136152

137153
=head1 COPYRIGHT
138154

139-
Copyright 2001-2021 The OpenSSL Project Authors. All Rights Reserved.
155+
Copyright 2001-2025 The OpenSSL Project Authors. All Rights Reserved.
140156

141157
Licensed under the Apache License 2.0 (the "License"). You may not use
142158
this file except in compliance with the License. You can obtain a copy

doc/man3/SSL_CTX_set_session_id_context.pod

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22

33
=head1 NAME
44

5-
SSL_CTX_set_session_id_context, SSL_set_session_id_context - set context within which session can be reused (server side only)
5+
SSL_CTX_set_session_id_context, SSL_set_session_id_context
6+
- set context within which session can be reused (server side only)
67

78
=head1 SYNOPSIS
89

@@ -82,7 +83,7 @@ L<ssl(7)>
8283

8384
=head1 COPYRIGHT
8485

85-
Copyright 2001-2020 The OpenSSL Project Authors. All Rights Reserved.
86+
Copyright 2001-2025 The OpenSSL Project Authors. All Rights Reserved.
8687

8788
Licensed under the Apache License 2.0 (the "License"). You may not use
8889
this file except in compliance with the License. You can obtain a copy

doc/man3/SSL_get_verify_result.pod

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,25 +2,30 @@
22

33
=head1 NAME
44

5-
SSL_get_verify_result - get result of peer certificate verification
5+
SSL_get_verify_result,
6+
SSL_SESSION_get_verify_result
7+
- get result of peer certificate verification
68

79
=head1 SYNOPSIS
810

911
#include <openssl/ssl.h>
1012

1113
long SSL_get_verify_result(const SSL *ssl);
14+
long SSL_SESSION_get_verify_result(const SSL_SESSION *ss);
1215

1316
=head1 DESCRIPTION
1417

15-
SSL_get_verify_result() returns the result of the verification of the
16-
X509 certificate presented by the peer, if any. I<ssl> B<MUST NOT> be NULL.
18+
SSL_get_verify_result() and SSL_SESSION_get_verify_result() return the
19+
result of the verification of the X509 certificate presented by the peer,
20+
if any. I<ssl> B<MUST NOT> be NULL.
1721

1822
=head1 NOTES
1923

20-
SSL_get_verify_result() can only return one error code while the verification
24+
SSL_get_verify_result() and SSL_SESSION_get_verify_result() can only return
25+
one error code while the verification
2126
of a certificate can fail because of many reasons at the same time. Only
2227
the last verification error that occurred during the processing is available
23-
from SSL_get_verify_result().
28+
from SSL_get_verify_result() or SSL_SESSION_get_verify_result().
2429

2530
Sometimes there can be a sequence of errors leading to the verification
2631
failure as reported by SSL_get_verify_result().
@@ -61,9 +66,13 @@ L<ssl(7)>, L<SSL_set_verify_result(3)>,
6166
L<SSL_get_peer_certificate(3)>,
6267
L<openssl-verify(1)>
6368

69+
=head1 HISTORY
70+
71+
The SSL_SESSION_get_verify_result() function was added in OpenSSL 3.5.
72+
6473
=head1 COPYRIGHT
6574

66-
Copyright 2000-2023 The OpenSSL Project Authors. All Rights Reserved.
75+
Copyright 2000-2025 The OpenSSL Project Authors. All Rights Reserved.
6776

6877
Licensed under the Apache License 2.0 (the "License"). You may not use
6978
this file except in compliance with the License. You can obtain a copy

doc/man3/SSL_set1_cache_id.pod

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
=pod
2+
3+
=head1 NAME
4+
5+
SSL_set1_cache_id,
6+
SSL_get0_cache_id,
7+
SSL_SESSION_set1_cache_id,
8+
SSL_SESSION_get0_cache_id,
9+
SSL_get1_previous_client_session - use application-defined cache identifier for session caching
10+
11+
=head1 SYNOPSIS
12+
13+
#include <openssl/ssl.h>
14+
15+
int SSL_set1_cache_id(SSL *s, const unsigned char *data, size_t len);
16+
int SSL_get0_cache_id(const SSL *s, const unsigned char **data, size_t *len);
17+
18+
int SSL_SESSION_set1_cache_id(SSL_SESSION *ss, const unsigned char *data, size_t len);
19+
int SSL_SESSION_get0_cache_id(const SSL_SESSION *ss, const unsigned char **data, size_t *len);
20+
21+
int SSL_get1_previous_client_session(SSL *s, int flags);
22+
23+
=head1 DESCRIPTION
24+
25+
SSL_set1_cache_id() sets the cache identifier specified by B<data> and B<len>
26+
into B<s>. This cache identifier is application-defined, and can be a domain
27+
name, IP address, port or other identifier.
28+
29+
SSL_get0_cache_id() returns the cache identifier of B<s> into the B<data> and
30+
B<len> variables. The cache identifier is application-defined.
31+
32+
SSL_SESSION_set1_cache_id() sets the cache identifier specified by B<data> and B<len>
33+
into B<ss>. This cache identifier is application-defined.
34+
35+
SSL_SESSION_get0_cache_id() returns the cache identifier of B<ss> into the B<data> and
36+
B<len> variables. The cache identifier is application-defined.
37+
38+
SSL_get1_previous_client_session() is used to search for and return a
39+
SSL_SESSION in the session cache. A cache identifier must first be set
40+
via SSL_set1_cache_id().
41+
42+
=head1 NOTES
43+
44+
The OpenSSL library can store/retrieve SSL/TLS sessions for later reuse.
45+
The sessions can be held in memory for each B<ctx>; if more than one
46+
SSL_CTX object is being maintained, the sessions are unique for each SSL_CTX
47+
object. The cache mode must be set to SSL_SESS_CACHE_CLIENT via
48+
L<SSL_CTX_set_session_cache_mode(3)> in order to use application-defined
49+
cache identifiers. When the cache mode is set to SSL_SESSION_CACHE_SERVER or
50+
SSL_SESSION_CACHE_BOTH, session IDs are used as the cache identifier.
51+
52+
To reuse a client session, use the SSL_set1_cache_id() function to specify the
53+
cache identifier of the server that the client is attempting to connect to. Set the
54+
optional session ID context via L<SSL_CTX_set_session_id_context(3)> or
55+
L<SSL_set_session_id_context(3)> before calling SSL_get1_previous_client_session().
56+
57+
After the session has been retrieved, it may be examined to determine whether
58+
it can (or should) be used. The session must then be applied to the SSL object via the
59+
L<SSL_set_session(3)> before it can be used during L<SSL_connect(3)>.
60+
61+
The session cache that is searched is specified by the SSL_CTX used in
62+
L<SSL_new(3)>. The SSL_CTX set via L<SSL_set_SSL_CTX(3)> is not used
63+
for the session cache.
64+
65+
SSL_SESSION_set1_cache_id() will fail if the B<ss> is already in a cache. This
66+
function can only be used on non-cached SSL_SESSIONs.
67+
68+
SSL_set1_cache_id() and SSL_SESSION_set1_cache_id() should not be used by servers.
69+
70+
=head1 RETURN VALUES
71+
72+
The SSL_set1_cache_id(), SSL_get0_cache_id(), SSL_SESSION_set1_cache_id() and
73+
SSL_SESSION_get0_cache_id() functions return 1 on success, 0 on failure.
74+
75+
The SSL_get0_cache_id() function fills in the B<data> and B<len> parameters
76+
with the data from the B<s>.
77+
78+
The SSL_get_previous_client_session() returns an SSL_SESSION on success, or NULL on
79+
failure. The error stack should be checked on error.
80+
81+
=head1 SEE ALSO
82+
83+
L<SSL_set_session(3)>
84+
L<SSL_session_reused(3)>
85+
L<SSL_CTX_add_session(3)>
86+
L<SSL_CTX_sess_number(3)>
87+
L<SSL_CTX_sess_set_cache_size(3)>
88+
L<SSL_CTX_sess_set_get_cb(3)>
89+
L<SSL_CTX_set_session_id_context(3)>
90+
L<SSL_CTX_set_timeout(3)>
91+
L<SSL_CTX_flush_sessions(3)>
92+
L<SSL_CTX_set_session_cache_mode(3)>,
93+
L<SSL_connect(3)>,
94+
L<SSL_new(3)>,
95+
L<SSL_set_SSL_CTX(3)>,
96+
97+
=head1 HISTORY
98+
99+
The SSL_set1_cache_id(),
100+
SSL_get0_cache_id(),
101+
SSL_SESSION_set1_cache_id(),
102+
SSL_SESSION_get0_cache_id(), and
103+
SSL_get1_previous_client_session() functions were added in OpenSSL 3.5.
104+
105+
=head1 COPYRIGHT
106+
107+
Copyright 2000-2025 The OpenSSL Project Authors. All Rights Reserved.
108+
109+
Licensed under the OpenSSL license (the "License"). You may not use
110+
this file except in compliance with the License. You can obtain a copy
111+
in the file LICENSE in the source distribution or at
112+
L<https://www.openssl.org/source/license.html>.
113+
114+
=cut

0 commit comments

Comments
 (0)