mirror of https://github.com/openssl/openssl.git
Compare commits
10 Commits
37fa547937
...
39cfdcb1ee
| Author | SHA1 | Date |
|---|---|---|
|
|
39cfdcb1ee | |
|
|
296f1f6dd8 | |
|
|
fd7fc90346 | |
|
|
fcb5e20ac7 | |
|
|
b9ff440dd6 | |
|
|
f77fafd16e | |
|
|
f12f8cc035 | |
|
|
4cc70c2732 | |
|
|
5623de77bb | |
|
|
8cca50ce54 |
|
|
@ -93,7 +93,6 @@ EOF
|
|||
|
||||
my %cmd_disabler = (
|
||||
ciphers => "sock",
|
||||
genrsa => "rsa",
|
||||
gendsa => "dsa",
|
||||
dsaparam => "dsa",
|
||||
gendh => "dh",
|
||||
|
|
@ -107,7 +106,7 @@ EOF
|
|||
# [2] = preprocessor conditional for excluding irrespective of deprecation
|
||||
# rsa => [ "pkey", "3_0", "rsa" ],
|
||||
# genrsa => [ "genpkey", "3_0", "rsa" ],
|
||||
rsautl => [ "pkeyutl", "3_0", "rsa" ],
|
||||
rsautl => [ "pkeyutl", "3_0", "" ],
|
||||
# dhparam => [ "pkeyparam", "3_0", "dh" ],
|
||||
# dsaparam => [ "pkeyparam", "3_0", "dsa" ],
|
||||
# dsa => [ "pkey", "3_0", "dsa" ],
|
||||
|
|
|
|||
|
|
@ -1355,6 +1355,7 @@ SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT:272:\
|
|||
attempt to reuse session in different context
|
||||
SSL_R_AT_LEAST_TLS_1_2_NEEDED_IN_SUITEB_MODE:158:\
|
||||
at least (D)TLS 1.2 needed in Suite B mode
|
||||
SSL_R_BAD_CACHE_MODE:424:bad cache mode
|
||||
SSL_R_BAD_CERTIFICATE:348:bad certificate
|
||||
SSL_R_BAD_CHANGE_CIPHER_SPEC:103:bad change cipher spec
|
||||
SSL_R_BAD_CIPHER:186:bad cipher
|
||||
|
|
@ -1526,6 +1527,7 @@ SSL_R_NOT_ON_RECORD_BOUNDARY:182:not on record boundary
|
|||
SSL_R_NOT_REPLACING_CERTIFICATE:289:not replacing certificate
|
||||
SSL_R_NOT_SERVER:284:not server
|
||||
SSL_R_NO_APPLICATION_PROTOCOL:235:no application protocol
|
||||
SSL_R_NO_CACHE_ID_ON_SERVER:425:no cache id on server
|
||||
SSL_R_NO_CERTIFICATES_RETURNED:176:no certificates returned
|
||||
SSL_R_NO_CERTIFICATE_ASSIGNED:177:no certificate assigned
|
||||
SSL_R_NO_CERTIFICATE_SET:179:no certificate set
|
||||
|
|
@ -1599,6 +1601,8 @@ SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING:345:scsv received when renegotiating
|
|||
SSL_R_SCT_VERIFICATION_FAILED:208:sct verification failed
|
||||
SSL_R_SEQUENCE_CTR_WRAPPED:327:sequence ctr wrapped
|
||||
SSL_R_SERVERHELLO_TLSEXT:275:serverhello tlsext
|
||||
SSL_R_SESSION_ALREADY_IN_CACHE:426:session already in cache
|
||||
SSL_R_SESSION_ALREADY_SET:427:session already set
|
||||
SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED:277:session id context uninitialized
|
||||
SSL_R_SHUTDOWN_WHILE_IN_INIT:407:shutdown while in init
|
||||
SSL_R_SIGNATURE_ALGORITHMS_ERROR:360:signature algorithms error
|
||||
|
|
|
|||
|
|
@ -261,10 +261,12 @@ int EVP_PKEY_encrypt(EVP_PKEY_CTX *ctx,
|
|||
|
||||
cipher = ctx->op.ciph.cipher;
|
||||
desc = cipher->description != NULL ? cipher->description : "";
|
||||
ERR_set_mark();
|
||||
ret = cipher->encrypt(ctx->op.ciph.algctx, out, outlen, (out == NULL ? 0 : *outlen), in, inlen);
|
||||
if (ret <= 0)
|
||||
if (ret <= 0 && ERR_count_to_mark() == 0)
|
||||
ERR_raise_data(ERR_LIB_EVP, EVP_R_PROVIDER_ASYM_CIPHER_FAILURE,
|
||||
"%s encrypt:%s", cipher->type_name, desc);
|
||||
ERR_clear_last_mark();
|
||||
return ret;
|
||||
|
||||
legacy:
|
||||
|
|
@ -309,10 +311,12 @@ int EVP_PKEY_decrypt(EVP_PKEY_CTX *ctx,
|
|||
|
||||
cipher = ctx->op.ciph.cipher;
|
||||
desc = cipher->description != NULL ? cipher->description : "";
|
||||
ERR_set_mark();
|
||||
ret = cipher->decrypt(ctx->op.ciph.algctx, out, outlen, (out == NULL ? 0 : *outlen), in, inlen);
|
||||
if (ret <= 0)
|
||||
if (ret <= 0 && ERR_count_to_mark() == 0)
|
||||
ERR_raise_data(ERR_LIB_EVP, EVP_R_PROVIDER_ASYM_CIPHER_FAILURE,
|
||||
"%s decrypt:%s", cipher->type_name, desc);
|
||||
ERR_clear_last_mark();
|
||||
|
||||
return ret;
|
||||
|
||||
|
|
|
|||
|
|
@ -460,10 +460,12 @@ void *evp_keymgmt_gen(const EVP_KEYMGMT *keymgmt, void *genctx,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
ERR_set_mark();
|
||||
ret = keymgmt->gen(genctx, cb, cbarg);
|
||||
if (ret == NULL)
|
||||
if (ret == NULL && ERR_count_to_mark() == 0)
|
||||
ERR_raise_data(ERR_LIB_EVP, EVP_R_PROVIDER_KEYMGMT_FAILURE,
|
||||
"%s key generation:%s", keymgmt->type_name, desc);
|
||||
ERR_clear_last_mark();
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -426,10 +426,12 @@ int EVP_DigestSignUpdate(EVP_MD_CTX *ctx, const void *data, size_t dsize)
|
|||
return 0;
|
||||
}
|
||||
|
||||
ERR_set_mark();
|
||||
ret = signature->digest_sign_update(pctx->op.sig.algctx, data, dsize);
|
||||
if (ret <= 0)
|
||||
if (ret <= 0 && ERR_count_to_mark() == 0)
|
||||
ERR_raise_data(ERR_LIB_EVP, EVP_R_PROVIDER_SIGNATURE_FAILURE,
|
||||
"%s digest_sign_update:%s", signature->type_name, desc);
|
||||
ERR_clear_last_mark();
|
||||
return ret;
|
||||
|
||||
legacy:
|
||||
|
|
@ -474,10 +476,12 @@ int EVP_DigestVerifyUpdate(EVP_MD_CTX *ctx, const void *data, size_t dsize)
|
|||
return 0;
|
||||
}
|
||||
|
||||
ERR_set_mark();
|
||||
ret = signature->digest_verify_update(pctx->op.sig.algctx, data, dsize);
|
||||
if (ret <= 0)
|
||||
if (ret <= 0 && ERR_count_to_mark() == 0)
|
||||
ERR_raise_data(ERR_LIB_EVP, EVP_R_PROVIDER_SIGNATURE_FAILURE,
|
||||
"%s digest_verify_update:%s", signature->type_name, desc);
|
||||
ERR_clear_last_mark();
|
||||
return ret;
|
||||
|
||||
legacy:
|
||||
|
|
@ -527,11 +531,13 @@ int EVP_DigestSignFinal(EVP_MD_CTX *ctx, unsigned char *sigret,
|
|||
pctx = dctx;
|
||||
}
|
||||
|
||||
ERR_set_mark();
|
||||
r = signature->digest_sign_final(pctx->op.sig.algctx, sigret, siglen,
|
||||
sigret == NULL ? 0 : *siglen);
|
||||
if (!r)
|
||||
if (!r && ERR_count_to_mark() == 0)
|
||||
ERR_raise_data(ERR_LIB_EVP, EVP_R_PROVIDER_SIGNATURE_FAILURE,
|
||||
"%s digest_sign_final:%s", signature->type_name, desc);
|
||||
ERR_clear_last_mark();
|
||||
if (dctx == NULL && sigret != NULL)
|
||||
ctx->flags |= EVP_MD_CTX_FLAG_FINALISED;
|
||||
else
|
||||
|
|
@ -638,11 +644,13 @@ int EVP_DigestSign(EVP_MD_CTX *ctx, unsigned char *sigret, size_t *siglen,
|
|||
|
||||
if (sigret != NULL)
|
||||
ctx->flags |= EVP_MD_CTX_FLAG_FINALISED;
|
||||
ERR_set_mark();
|
||||
ret = signature->digest_sign(pctx->op.sig.algctx, sigret, siglen,
|
||||
sigret == NULL ? 0 : *siglen, tbs, tbslen);
|
||||
if (ret <= 0)
|
||||
if (ret <= 0 && ERR_count_to_mark() == 0)
|
||||
ERR_raise_data(ERR_LIB_EVP, EVP_R_PROVIDER_SIGNATURE_FAILURE,
|
||||
"%s digest_sign:%s", signature->type_name, desc);
|
||||
ERR_clear_last_mark();
|
||||
return ret;
|
||||
}
|
||||
} else {
|
||||
|
|
@ -693,10 +701,12 @@ int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sig,
|
|||
pctx = dctx;
|
||||
}
|
||||
|
||||
ERR_set_mark();
|
||||
r = signature->digest_verify_final(pctx->op.sig.algctx, sig, siglen);
|
||||
if (!r)
|
||||
if (!r && ERR_count_to_mark() == 0)
|
||||
ERR_raise_data(ERR_LIB_EVP, EVP_R_PROVIDER_SIGNATURE_FAILURE,
|
||||
"%s digest_verify_final:%s", signature->type_name, desc);
|
||||
ERR_clear_last_mark();
|
||||
if (dctx == NULL)
|
||||
ctx->flags |= EVP_MD_CTX_FLAG_FINALISED;
|
||||
else
|
||||
|
|
@ -769,10 +779,12 @@ int EVP_DigestVerify(EVP_MD_CTX *ctx, const unsigned char *sigret,
|
|||
int ret;
|
||||
|
||||
ctx->flags |= EVP_MD_CTX_FLAG_FINALISED;
|
||||
ERR_set_mark();
|
||||
ret = signature->digest_verify(pctx->op.sig.algctx, sigret, siglen, tbs, tbslen);
|
||||
if (ret <= 0)
|
||||
if (ret <= 0 && ERR_count_to_mark() == 0)
|
||||
ERR_raise_data(ERR_LIB_EVP, EVP_R_PROVIDER_SIGNATURE_FAILURE,
|
||||
"%s digest_verify:%s", signature->type_name, desc);
|
||||
ERR_clear_last_mark();
|
||||
return ret;
|
||||
}
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -2419,6 +2419,11 @@ static int core_pop_error_to_mark(const OSSL_CORE_HANDLE *handle)
|
|||
return ERR_pop_to_mark();
|
||||
}
|
||||
|
||||
static int core_count_to_mark(const OSSL_CORE_HANDLE *handle)
|
||||
{
|
||||
return ERR_count_to_mark();
|
||||
}
|
||||
|
||||
static void core_indicator_get_callback(OPENSSL_CORE_CTX *libctx,
|
||||
OSSL_INDICATOR_CALLBACK **cb)
|
||||
{
|
||||
|
|
@ -2600,6 +2605,7 @@ static const OSSL_DISPATCH core_dispatch_[] = {
|
|||
{ OSSL_FUNC_CORE_CLEAR_LAST_ERROR_MARK,
|
||||
(void (*)(void))core_clear_last_error_mark },
|
||||
{ OSSL_FUNC_CORE_POP_ERROR_TO_MARK, (void (*)(void))core_pop_error_to_mark },
|
||||
{ OSSL_FUNC_CORE_COUNT_TO_MARK, (void (*)(void))core_count_to_mark },
|
||||
{ OSSL_FUNC_BIO_NEW_FILE, (void (*)(void))ossl_core_bio_new_file },
|
||||
{ OSSL_FUNC_BIO_NEW_MEMBUF, (void (*)(void))ossl_core_bio_new_mem_buf },
|
||||
{ OSSL_FUNC_BIO_READ_EX, (void (*)(void))ossl_core_bio_read_ex },
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ static const ERR_STRING_DATA SSL_str_reasons[] = {
|
|||
"attempt to reuse session in different context"},
|
||||
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_AT_LEAST_TLS_1_2_NEEDED_IN_SUITEB_MODE),
|
||||
"at least (D)TLS 1.2 needed in Suite B mode"},
|
||||
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_BAD_CACHE_MODE), "bad cache mode"},
|
||||
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_BAD_CERTIFICATE), "bad certificate"},
|
||||
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_BAD_CHANGE_CIPHER_SPEC),
|
||||
"bad change cipher spec"},
|
||||
|
|
@ -292,6 +293,8 @@ static const ERR_STRING_DATA SSL_str_reasons[] = {
|
|||
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_NOT_SERVER), "not server"},
|
||||
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_NO_APPLICATION_PROTOCOL),
|
||||
"no application protocol"},
|
||||
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_NO_CACHE_ID_ON_SERVER),
|
||||
"no cache id on server"},
|
||||
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_NO_CERTIFICATES_RETURNED),
|
||||
"no certificates returned"},
|
||||
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_NO_CERTIFICATE_ASSIGNED),
|
||||
|
|
@ -407,6 +410,10 @@ static const ERR_STRING_DATA SSL_str_reasons[] = {
|
|||
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_SEQUENCE_CTR_WRAPPED),
|
||||
"sequence ctr wrapped"},
|
||||
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_SERVERHELLO_TLSEXT), "serverhello tlsext"},
|
||||
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_SESSION_ALREADY_IN_CACHE),
|
||||
"session already in cache"},
|
||||
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_SESSION_ALREADY_SET),
|
||||
"session already set"},
|
||||
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED),
|
||||
"session id context uninitialized"},
|
||||
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_SHUTDOWN_WHILE_IN_INIT),
|
||||
|
|
|
|||
|
|
@ -2783,6 +2783,10 @@ DEPEND[html/man3/SSL_session_reused.html]=man3/SSL_session_reused.pod
|
|||
GENERATE[html/man3/SSL_session_reused.html]=man3/SSL_session_reused.pod
|
||||
DEPEND[man/man3/SSL_session_reused.3]=man3/SSL_session_reused.pod
|
||||
GENERATE[man/man3/SSL_session_reused.3]=man3/SSL_session_reused.pod
|
||||
DEPEND[html/man3/SSL_set1_cache_id.html]=man3/SSL_set1_cache_id.pod
|
||||
GENERATE[html/man3/SSL_set1_cache_id.html]=man3/SSL_set1_cache_id.pod
|
||||
DEPEND[man/man3/SSL_set1_cache_id.3]=man3/SSL_set1_cache_id.pod
|
||||
GENERATE[man/man3/SSL_set1_cache_id.3]=man3/SSL_set1_cache_id.pod
|
||||
DEPEND[html/man3/SSL_set1_host.html]=man3/SSL_set1_host.pod
|
||||
GENERATE[html/man3/SSL_set1_host.html]=man3/SSL_set1_host.pod
|
||||
DEPEND[man/man3/SSL_set1_host.3]=man3/SSL_set1_host.pod
|
||||
|
|
@ -3747,6 +3751,7 @@ html/man3/SSL_read.html \
|
|||
html/man3/SSL_read_early_data.html \
|
||||
html/man3/SSL_rstate_string.html \
|
||||
html/man3/SSL_session_reused.html \
|
||||
html/man3/SSL_set1_cache_id.html \
|
||||
html/man3/SSL_set1_host.html \
|
||||
html/man3/SSL_set1_initial_peer_addr.html \
|
||||
html/man3/SSL_set1_server_cert_type.html \
|
||||
|
|
@ -4419,6 +4424,7 @@ man/man3/SSL_read.3 \
|
|||
man/man3/SSL_read_early_data.3 \
|
||||
man/man3/SSL_rstate_string.3 \
|
||||
man/man3/SSL_session_reused.3 \
|
||||
man/man3/SSL_set1_cache_id.3 \
|
||||
man/man3/SSL_set1_host.3 \
|
||||
man/man3/SSL_set1_initial_peer_addr.3 \
|
||||
man/man3/SSL_set1_server_cert_type.3 \
|
||||
|
|
|
|||
|
|
@ -14,9 +14,9 @@ SSL_CTX_sess_set_new_cb, SSL_CTX_sess_set_remove_cb, SSL_CTX_sess_set_get_cb, SS
|
|||
void (*remove_session_cb)(SSL_CTX *ctx,
|
||||
SSL_SESSION *));
|
||||
void SSL_CTX_sess_set_get_cb(SSL_CTX *ctx,
|
||||
SSL_SESSION (*get_session_cb)(SSL *,
|
||||
const unsigned char *,
|
||||
int, int *));
|
||||
SSL_SESSION (*get_session_cb)(SSL *ssl,
|
||||
const unsigned char *data,
|
||||
int len, int *copy));
|
||||
|
||||
int (*SSL_CTX_sess_get_new_cb(SSL_CTX *ctx))(struct ssl_st *ssl,
|
||||
SSL_SESSION *sess);
|
||||
|
|
@ -86,7 +86,7 @@ for all sessions in the internal session cache when
|
|||
L<SSL_CTX_free(3)> is called. The remove_session_cb() is passed
|
||||
the B<ctx> and the ssl session B<sess>. It does not provide any feedback.
|
||||
|
||||
The get_session_cb() is only called on SSL/TLS servers, and is given
|
||||
The get_session_cb() is called on SSL/TLS servers, and is given
|
||||
the session id
|
||||
proposed by the client. The get_session_cb() is always called, even when
|
||||
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
|
|||
is incremented and the session must be explicitly freed with
|
||||
L<SSL_SESSION_free(3)>.
|
||||
|
||||
The get_session_cb() is called on SSL/TLS clients with the application-defined
|
||||
cache identifier set by the client. The get_session_cb() is always called when
|
||||
session caching is disabled. The get_session_cb() is passed the
|
||||
B<ssl> connection, the cache identifier of length B<length> at the memory location
|
||||
B<data>. With the parameter B<copy> the callback can require the
|
||||
library to increment the reference count of the SSL_SESSION object,
|
||||
Normally the reference count is not incremented and therefore the
|
||||
session must not be explicitly freed with
|
||||
L<SSL_SESSION_free(3)>.
|
||||
|
||||
=head1 RETURN VALUES
|
||||
|
||||
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)>,
|
|||
L<SSL_CTX_set_session_cache_mode(3)>,
|
||||
L<SSL_CTX_flush_sessions(3)>,
|
||||
L<SSL_SESSION_free(3)>,
|
||||
L<SSL_CTX_free(3)>
|
||||
L<SSL_CTX_free(3)>,
|
||||
L<SSL_get1_previous_client_session(3)>,
|
||||
L<SSL_set1_cache_id(3)>
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
Copyright 2001-2020 The OpenSSL Project Authors. All Rights Reserved.
|
||||
Copyright 2001-2025 The OpenSSL Project Authors. All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
this file except in compliance with the License. You can obtain a copy
|
||||
|
|
|
|||
|
|
@ -49,12 +49,16 @@ No session caching for client or server takes place.
|
|||
|
||||
=item SSL_SESS_CACHE_CLIENT
|
||||
|
||||
Client sessions are added to the session cache. As there is no reliable way
|
||||
for the OpenSSL library to know whether a session should be reused or which
|
||||
session to choose (due to the abstract BIO layer the SSL engine does not
|
||||
have details about the connection), the application must select the session
|
||||
to be reused by using the L<SSL_set_session(3)>
|
||||
function. This option is not activated by default.
|
||||
Client sessions are added to the session cache. Sessions are identified by their
|
||||
cache identifier set via L<SSL_set1_cache_id(3)> when they are created by an SSL.
|
||||
This cache identifier must be set before calling L<SSL_connect(3)>.
|
||||
|
||||
The application then can retrieve prior sessions via L<SSL_get1_previous_client_session(3)>.
|
||||
After the session has been retrieved, it may be examined to determine whether
|
||||
it can (or should) be used. The session must then be applied to the SSL object via the
|
||||
L<SSL_set_session(3)> before it can be used during L<SSL_connect(3)>.
|
||||
|
||||
This option is not activated by default.
|
||||
|
||||
=item SSL_SESS_CACHE_SERVER
|
||||
|
||||
|
|
@ -64,10 +68,19 @@ the internal session cache (unless SSL_SESS_CACHE_NO_INTERNAL_LOOKUP is set),
|
|||
then (second) in the external cache if available. If the session is found, the
|
||||
server will try to reuse the session. This is the default.
|
||||
|
||||
Servers must not use L<SSL_set1_cache_id(3)>, otherwise, the session will not be
|
||||
found in the cache.
|
||||
|
||||
=item SSL_SESS_CACHE_BOTH
|
||||
|
||||
Enable both SSL_SESS_CACHE_CLIENT and SSL_SESS_CACHE_SERVER at the same time.
|
||||
|
||||
Servers must not use L<SSL_set1_cache_id(3)>, otherwise, the session will not be
|
||||
found in the cache.
|
||||
|
||||
Clients must use L<SSL_set1_cache_id(3)> in order for sessions to be found in the cache
|
||||
via L<SSL_get1_previous_client_session(3)>.
|
||||
|
||||
=item SSL_SESS_CACHE_NO_AUTO_CLEAR
|
||||
|
||||
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.
|
|||
|
||||
SSL_CTX_get_session_cache_mode() returns the currently set cache mode.
|
||||
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
L<ssl(7)>, L<SSL_set_session(3)>,
|
||||
L<SSL_session_reused(3)>,
|
||||
L<SSL_get0_cache_id(3)>,
|
||||
L<SSL_set1_cache_id(3)>,
|
||||
L<SSL_get1_previous_client_session(3)>,
|
||||
L<SSL_CTX_add_session(3)>,
|
||||
L<SSL_CTX_sess_number(3)>,
|
||||
L<SSL_CTX_sess_set_cache_size(3)>,
|
||||
L<SSL_CTX_sess_set_get_cb(3)>,
|
||||
L<SSL_CTX_set_session_id_context(3)>,
|
||||
L<SSL_CTX_set_timeout(3)>,
|
||||
L<SSL_CTX_flush_sessions(3)>
|
||||
L<SSL_CTX_flush_sessions(3)>,
|
||||
L<SSL_connect(3)>
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
Copyright 2001-2021 The OpenSSL Project Authors. All Rights Reserved.
|
||||
Copyright 2001-2025 The OpenSSL Project Authors. All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
this file except in compliance with the License. You can obtain a copy
|
||||
|
|
|
|||
|
|
@ -2,7 +2,8 @@
|
|||
|
||||
=head1 NAME
|
||||
|
||||
SSL_CTX_set_session_id_context, SSL_set_session_id_context - set context within which session can be reused (server side only)
|
||||
SSL_CTX_set_session_id_context, SSL_set_session_id_context
|
||||
- set context within which session can be reused (server side only)
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
|
|
@ -82,7 +83,7 @@ L<ssl(7)>
|
|||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
Copyright 2001-2020 The OpenSSL Project Authors. All Rights Reserved.
|
||||
Copyright 2001-2025 The OpenSSL Project Authors. All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
this file except in compliance with the License. You can obtain a copy
|
||||
|
|
|
|||
|
|
@ -0,0 +1,117 @@
|
|||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
SSL_set1_cache_id,
|
||||
SSL_get1_cache_id,
|
||||
SSL_SESSION_set1_cache_id,
|
||||
SSL_SESSION_get1_cache_id,
|
||||
SSL_get1_previous_client_session - use application-defined cache identifier for session caching
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
#include <openssl/ssl.h>
|
||||
|
||||
int SSL_set1_cache_id(SSL *s, const unsigned char *data, size_t len);
|
||||
int SSL_get1_cache_id(const SSL *s, const unsigned char **data, size_t *len);
|
||||
|
||||
int SSL_SESSION_set1_cache_id(SSL_SESSION *ss, const unsigned char *data, size_t len);
|
||||
int SSL_SESSION_get1_cache_id(const SSL_SESSION *ss, const unsigned char **data, size_t *len);
|
||||
|
||||
int SSL_get1_previous_client_session(SSL *s, int flags);
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
SSL_set1_cache_id() sets the cache identifier specified by B<data> and B<len>
|
||||
into B<s>. This cache identifier is application-defined, and can be a domain
|
||||
name, IP address, port or other identifier.
|
||||
|
||||
SSL_get1_cache_id() returns the cache identifier of B<s> into the B<data> and
|
||||
B<len> variables. The cache identifier is application-defined.
|
||||
|
||||
SSL_SESSION_set1_cache_id() sets the cache identifier specified by B<data> and B<len>
|
||||
into B<ss>. This cache identifier is application-defined.
|
||||
|
||||
SSL_SESSION_get1_cache_id() returns the cache identifier of B<ss> into the B<data> and
|
||||
B<len> variables. The cache identifier is application-defined.
|
||||
|
||||
SSL_get1_previous_client_session() is used to search for and return a
|
||||
SSL_SESSION in the session cache. A cache identifier must first be set
|
||||
via SSL_set1_cache_id().
|
||||
|
||||
=head1 NOTES
|
||||
|
||||
The OpenSSL library can store/retrieve SSL/TLS sessions for later reuse.
|
||||
The sessions can be held in memory for each B<ctx>; if more than one
|
||||
SSL_CTX object is being maintained, the sessions are unique for each SSL_CTX
|
||||
object. The cache mode must be set to SSL_SESS_CACHE_CLIENT via
|
||||
L<SSL_CTX_set_session_cache_mode(3)> in order to use application-defined
|
||||
cache identifiers. When the cache mode is set to SSL_SESSION_CACHE_SERVER or
|
||||
SSL_SESSION_CACHE_BOTH, session IDs are used as the cache identifier.
|
||||
|
||||
To reuse a client session, use the SSL_set1_cache_id() function to specify the
|
||||
cache identifier of the server that the client is attempting to connect to. Set the
|
||||
optional session ID context via L<SSL_CTX_set_session_id_context(3)> or
|
||||
L<SSL_set_session_id_context(3)> before calling SSL_get1_previous_client_session().
|
||||
|
||||
After the session has been retrieved, it may be examined to determine whether
|
||||
it can (or should) be used. The session must then be applied to the SSL object via the
|
||||
L<SSL_set_session(3)> before it can be used during L<SSL_connect(3)>.
|
||||
|
||||
The session cache that is searched is specified by the SSL_CTX used in
|
||||
L<SSL_new(3)>. The SSL_CTX set via L<SSL_set_SSL_CTX(3)> is not used
|
||||
for the session cache.
|
||||
|
||||
SSL_SESSION_set1_cache_id() will fail if the B<ss> is already in a cache. This
|
||||
function can only be used on non-cached SSL_SESSIONs.
|
||||
|
||||
SSL_set1_cache_id() and SSL_SESSION_set1_cache_id() should not be used by servers,
|
||||
the functions will fail.
|
||||
|
||||
The memory returned by SSL_get1_cache_id() and SSL_SESSION_get1_cache_id() must be freed.
|
||||
|
||||
=head1 RETURN VALUES
|
||||
|
||||
The SSL_set1_cache_id(), SSL_get1_cache_id(), SSL_SESSION_set1_cache_id() and
|
||||
SSL_SESSION_get1_cache_id() functions return 1 on success, 0 on failure.
|
||||
|
||||
The SSL_get1_cache_id() function fills in the B<data> and B<len> parameters
|
||||
with the data from the B<s>.
|
||||
|
||||
The SSL_get_previous_client_session() returns an SSL_SESSION on success, or NULL on
|
||||
failure. The error stack should be checked on error.
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
L<SSL_set_session(3)>
|
||||
L<SSL_session_reused(3)>
|
||||
L<SSL_CTX_add_session(3)>
|
||||
L<SSL_CTX_sess_number(3)>
|
||||
L<SSL_CTX_sess_set_cache_size(3)>
|
||||
L<SSL_CTX_sess_set_get_cb(3)>
|
||||
L<SSL_CTX_set_session_id_context(3)>
|
||||
L<SSL_CTX_set_timeout(3)>
|
||||
L<SSL_CTX_flush_sessions(3)>
|
||||
L<SSL_CTX_set_session_cache_mode(3)>,
|
||||
L<SSL_connect(3)>,
|
||||
L<SSL_new(3)>,
|
||||
L<SSL_set_SSL_CTX(3)>,
|
||||
|
||||
=head1 HISTORY
|
||||
|
||||
The SSL_set1_cache_id(),
|
||||
SSL_get1_cache_id(),
|
||||
SSL_SESSION_set1_cache_id(),
|
||||
SSL_SESSION_get1_cache_id(), and
|
||||
SSL_get1_previous_client_session() functions were added in OpenSSL 3.5.
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
Copyright 2000-2025 The OpenSSL Project Authors. All Rights Reserved.
|
||||
|
||||
Licensed under the OpenSSL license (the "License"). You may not use
|
||||
this file except in compliance with the License. You can obtain a copy
|
||||
in the file LICENSE in the source distribution or at
|
||||
L<https://www.openssl.org/source/license.html>.
|
||||
|
||||
=cut
|
||||
|
|
@ -154,6 +154,10 @@ provider):
|
|||
core_new_error OSSL_FUNC_CORE_NEW_ERROR
|
||||
core_set_error_debug OSSL_FUNC_CORE_SET_ERROR_DEBUG
|
||||
core_vset_error OSSL_FUNC_CORE_VSET_ERROR
|
||||
core_set_error_mark OSSL_FUNC_CORE_SET_ERROR_MARK
|
||||
core_clear_last_error_mark OSSL_FUNC_CORE_CLEAR_LAST_ERROR_MARK
|
||||
core_pop_error_to_mark OSSL_FUNC_CORE_POP_ERROR_TO_MARK
|
||||
core_count_to_mark OSSL_FUNC_CORE_COUNT_TO_MARK
|
||||
core_obj_add_sigid OSSL_FUNC_CORE_OBJ_ADD_SIGID
|
||||
core_obj_create OSSL_FUNC_CORE_OBJ_CREATE
|
||||
CRYPTO_malloc OSSL_FUNC_CRYPTO_MALLOC
|
||||
|
|
@ -270,6 +274,33 @@ error occurred or was reported.
|
|||
|
||||
This corresponds to the OpenSSL function L<ERR_vset_error(3)>.
|
||||
|
||||
=item core_set_error_mark()
|
||||
|
||||
sets a mark on the current topmost error record if there is one.
|
||||
|
||||
This corresponds to the OpenSSL function L<ERR_set_mark(3)>.
|
||||
|
||||
=item core_clear_last_error_mark()
|
||||
|
||||
removes the last mark added if there is one.
|
||||
|
||||
This corresponds to the OpenSSL function L<ERR_clear_last_mark(3)>.
|
||||
|
||||
=item core_pop_error_to_mark()
|
||||
|
||||
pops the top of the error stack until a mark is found. The mark is then removed.
|
||||
If there is no mark, the whole stack is removed.
|
||||
|
||||
This corresponds to the OpenSSL function L<ERR_pop_to_mark(3)>.
|
||||
|
||||
=item core_count_to_mark()
|
||||
|
||||
returns the number of entries on the error stack above the most recently
|
||||
marked entry, not including that entry. If there is no mark in the error stack,
|
||||
the number of entries in the error stack is returned.
|
||||
|
||||
This corresponds to the OpenSSL function L<ERR_count_to_mark(3)>.
|
||||
|
||||
=back
|
||||
|
||||
The core_obj_create() function registers a new OID and associated short name
|
||||
|
|
|
|||
|
|
@ -590,10 +590,7 @@ int FuzzerTestOneInput(const uint8_t *buf, size_t len)
|
|||
SSL *server;
|
||||
BIO *in;
|
||||
BIO *out;
|
||||
#if !defined(OPENSSL_NO_EC) \
|
||||
|| (!defined(OPENSSL_NO_DSA) && !defined(OPENSSL_NO_DEPRECATED_3_0))
|
||||
BIO *bio_buf;
|
||||
#endif
|
||||
SSL_CTX *ctx;
|
||||
int ret;
|
||||
#ifndef OPENSSL_NO_DEPRECATED_3_0
|
||||
|
|
|
|||
|
|
@ -253,6 +253,10 @@ OSSL_CORE_MAKE_FUNC(int, provider_up_ref,
|
|||
OSSL_CORE_MAKE_FUNC(int, provider_free,
|
||||
(const OSSL_CORE_HANDLE *prov, int deactivate))
|
||||
|
||||
/* Additional error functions provided by the core */
|
||||
# define OSSL_FUNC_CORE_COUNT_TO_MARK 120
|
||||
OSSL_CORE_MAKE_FUNC(int, core_count_to_mark, (const OSSL_CORE_HANDLE *prov))
|
||||
|
||||
/* Functions provided by the provider to the Core, reserved numbers 1024-1535 */
|
||||
# define OSSL_FUNC_PROVIDER_TEARDOWN 1024
|
||||
OSSL_CORE_MAKE_FUNC(void, provider_teardown, (void *provctx))
|
||||
|
|
|
|||
|
|
@ -1828,6 +1828,7 @@ int SSL_up_ref(SSL *s);
|
|||
int SSL_is_dtls(const SSL *s);
|
||||
int SSL_is_tls(const SSL *s);
|
||||
int SSL_is_quic(const SSL *s);
|
||||
|
||||
__owur int SSL_set_session_id_context(SSL *ssl, const unsigned char *sid_ctx,
|
||||
unsigned int sid_ctx_len);
|
||||
|
||||
|
|
@ -2829,7 +2830,6 @@ typedef unsigned int (*DTLS_timer_cb)(SSL *s, unsigned int timer_us);
|
|||
|
||||
void DTLS_set_timer_cb(SSL *s, DTLS_timer_cb cb);
|
||||
|
||||
|
||||
typedef int (*SSL_allow_early_data_cb_fn)(SSL *s, void *arg);
|
||||
void SSL_CTX_set_allow_early_data_cb(SSL_CTX *ctx,
|
||||
SSL_allow_early_data_cb_fn cb,
|
||||
|
|
@ -2887,6 +2887,14 @@ int SSL_set_quic_tls_transport_params(SSL *s,
|
|||
|
||||
int SSL_set_quic_tls_early_data_enabled(SSL *s, int enabled);
|
||||
|
||||
/* Client cache implementation */
|
||||
__owur SSL_SESSION *SSL_get1_previous_client_session(SSL *s);
|
||||
__owur int SSL_set1_cache_id(SSL *s, const unsigned char *data, size_t len);
|
||||
__owur int SSL_get1_cache_id(const SSL *s, unsigned char **data, size_t *len);
|
||||
__owur int SSL_SESSION_set1_cache_id(SSL_SESSION *ss, const unsigned char *data, size_t len);
|
||||
__owur int SSL_SESSION_get1_cache_id(const SSL_SESSION *ss, unsigned char **data,
|
||||
size_t *len);
|
||||
|
||||
# ifdef __cplusplus
|
||||
}
|
||||
# endif
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@
|
|||
# define SSL_R_APP_DATA_IN_HANDSHAKE 100
|
||||
# define SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT 272
|
||||
# define SSL_R_AT_LEAST_TLS_1_2_NEEDED_IN_SUITEB_MODE 158
|
||||
# define SSL_R_BAD_CACHE_MODE 424
|
||||
# define SSL_R_BAD_CERTIFICATE 348
|
||||
# define SSL_R_BAD_CHANGE_CIPHER_SPEC 103
|
||||
# define SSL_R_BAD_CIPHER 186
|
||||
|
|
@ -190,6 +191,7 @@
|
|||
# define SSL_R_NOT_REPLACING_CERTIFICATE 289
|
||||
# define SSL_R_NOT_SERVER 284
|
||||
# define SSL_R_NO_APPLICATION_PROTOCOL 235
|
||||
# define SSL_R_NO_CACHE_ID_ON_SERVER 425
|
||||
# define SSL_R_NO_CERTIFICATES_RETURNED 176
|
||||
# define SSL_R_NO_CERTIFICATE_ASSIGNED 177
|
||||
# define SSL_R_NO_CERTIFICATE_SET 179
|
||||
|
|
@ -260,6 +262,8 @@
|
|||
# define SSL_R_SCT_VERIFICATION_FAILED 208
|
||||
# define SSL_R_SEQUENCE_CTR_WRAPPED 327
|
||||
# define SSL_R_SERVERHELLO_TLSEXT 275
|
||||
# define SSL_R_SESSION_ALREADY_IN_CACHE 426
|
||||
# define SSL_R_SESSION_ALREADY_SET 427
|
||||
# define SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED 277
|
||||
# define SSL_R_SHUTDOWN_WHILE_IN_INIT 407
|
||||
# define SSL_R_SIGNATURE_ALGORITHMS_ERROR 360
|
||||
|
|
|
|||
|
|
@ -65,6 +65,7 @@ static OSSL_FUNC_core_vset_error_fn *c_vset_error;
|
|||
static OSSL_FUNC_core_set_error_mark_fn *c_set_error_mark;
|
||||
static OSSL_FUNC_core_clear_last_error_mark_fn *c_clear_last_error_mark;
|
||||
static OSSL_FUNC_core_pop_error_to_mark_fn *c_pop_error_to_mark;
|
||||
static OSSL_FUNC_core_count_to_mark_fn *c_count_to_mark;
|
||||
static OSSL_FUNC_CRYPTO_malloc_fn *c_CRYPTO_malloc;
|
||||
static OSSL_FUNC_CRYPTO_zalloc_fn *c_CRYPTO_zalloc;
|
||||
static OSSL_FUNC_CRYPTO_free_fn *c_CRYPTO_free;
|
||||
|
|
@ -834,6 +835,9 @@ int OSSL_provider_init_int(const OSSL_CORE_HANDLE *handle,
|
|||
case OSSL_FUNC_CORE_POP_ERROR_TO_MARK:
|
||||
set_func(c_pop_error_to_mark, OSSL_FUNC_core_pop_error_to_mark(in));
|
||||
break;
|
||||
case OSSL_FUNC_CORE_COUNT_TO_MARK:
|
||||
set_func(c_count_to_mark, OSSL_FUNC_core_count_to_mark(in));
|
||||
break;
|
||||
case OSSL_FUNC_CRYPTO_MALLOC:
|
||||
set_func(c_CRYPTO_malloc, OSSL_FUNC_CRYPTO_malloc(in));
|
||||
break;
|
||||
|
|
@ -1072,6 +1076,11 @@ int ERR_pop_to_mark(void)
|
|||
return c_pop_error_to_mark(NULL);
|
||||
}
|
||||
|
||||
int ERR_count_to_mark(void)
|
||||
{
|
||||
return c_count_to_mark != NULL ? c_count_to_mark(NULL) : 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* This must take a library context, since it's called from the depths
|
||||
* of crypto/initthread.c code, where it's (correctly) assumed that the
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@ static OSSL_FUNC_core_vset_error_fn *c_vset_error;
|
|||
static OSSL_FUNC_core_set_error_mark_fn *c_set_error_mark;
|
||||
static OSSL_FUNC_core_clear_last_error_mark_fn *c_clear_last_error_mark;
|
||||
static OSSL_FUNC_core_pop_error_to_mark_fn *c_pop_error_to_mark;
|
||||
static OSSL_FUNC_core_count_to_mark_fn *c_count_to_mark;
|
||||
#endif
|
||||
|
||||
/* Parameters we provide to the core */
|
||||
|
|
@ -234,6 +235,9 @@ int OSSL_provider_init(const OSSL_CORE_HANDLE *handle,
|
|||
case OSSL_FUNC_CORE_POP_ERROR_TO_MARK:
|
||||
set_func(c_pop_error_to_mark, OSSL_FUNC_core_pop_error_to_mark(tmp));
|
||||
break;
|
||||
case OSSL_FUNC_CORE_COUNT_TO_MARK:
|
||||
set_func(c_count_to_mark, OSSL_FUNC_core_count_to_mark(in));
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
@ -301,4 +305,9 @@ int ERR_pop_to_mark(void)
|
|||
{
|
||||
return c_pop_error_to_mark(NULL);
|
||||
}
|
||||
|
||||
int ERR_count_to_mark(void)
|
||||
{
|
||||
return c_count_to_mark != NULL ? c_count_to_mark(NULL) : 0;
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1102,6 +1102,7 @@ int SSL_has_matching_session_id(const SSL *ssl, const unsigned char *id,
|
|||
if (sc == NULL || id_len > sizeof(r.session_id))
|
||||
return 0;
|
||||
|
||||
r.cache_id = NULL;
|
||||
r.ssl_version = sc->version;
|
||||
r.session_id_length = id_len;
|
||||
memcpy(r.session_id, id, id_len);
|
||||
|
|
@ -1518,6 +1519,7 @@ void ossl_ssl_connection_free(SSL *ssl)
|
|||
OPENSSL_free(s->clienthello->pre_proc_exts);
|
||||
OPENSSL_free(s->clienthello);
|
||||
OPENSSL_free(s->pha_context);
|
||||
OPENSSL_free(s->cache_id);
|
||||
EVP_MD_CTX_free(s->pha_dgst);
|
||||
|
||||
sk_X509_NAME_pop_free(s->ca_names, X509_NAME_free);
|
||||
|
|
@ -2233,6 +2235,8 @@ int SSL_accept(SSL *s)
|
|||
int SSL_connect(SSL *s)
|
||||
{
|
||||
SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);
|
||||
SSL_SESSION *sess;
|
||||
int ret;
|
||||
|
||||
#ifndef OPENSSL_NO_QUIC
|
||||
if (IS_QUIC(s))
|
||||
|
|
@ -2247,6 +2251,24 @@ int SSL_connect(SSL *s)
|
|||
SSL_set_connect_state(s);
|
||||
}
|
||||
|
||||
/*
|
||||
* If a client session has not been set, and there's a previous session
|
||||
* that matches the cache_id, use it.
|
||||
* If the cache is not set to client mode, an error will be raised, so
|
||||
* pop off as necessary.
|
||||
*/
|
||||
if (sc->session == NULL && sc->cache_id != NULL) {
|
||||
ERR_set_mark();
|
||||
sess = SSL_get1_previous_client_session(s);
|
||||
ERR_pop_to_mark();
|
||||
if (sess != NULL) {
|
||||
ret = SSL_set_session(s, sess);
|
||||
SSL_SESSION_free(sess);
|
||||
if (!ret)
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return SSL_do_handshake(s);
|
||||
}
|
||||
|
||||
|
|
@ -3886,9 +3908,24 @@ int SSL_export_keying_material_early(SSL *s, unsigned char *out, size_t olen,
|
|||
static unsigned long ssl_session_hash(const SSL_SESSION *a)
|
||||
{
|
||||
const unsigned char *session_id = a->session_id;
|
||||
unsigned long l;
|
||||
unsigned long l = 0;
|
||||
unsigned char tmp_storage[4];
|
||||
size_t i;
|
||||
|
||||
/* if cache_id set, use that (assume client-side cache) */
|
||||
if (a->cache_id != NULL) {
|
||||
/* Hash the session id context */
|
||||
for (i = 0; i < a->sid_ctx_length; i++)
|
||||
l ^= (long)a->sid_ctx[i] << ((i & (sizeof(l)-1)) * 8);
|
||||
|
||||
/* hash the cache id */
|
||||
for (i = 0; i < a->cache_id_len; i++)
|
||||
l ^= (long)a->cache_id[i] << ((i & (sizeof(l)-1)) * 8);
|
||||
|
||||
return l;
|
||||
}
|
||||
|
||||
/* hash session id (assume server-side cache) */
|
||||
if (a->session_id_length < sizeof(tmp_storage)) {
|
||||
memset(tmp_storage, 0, sizeof(tmp_storage));
|
||||
memcpy(tmp_storage, a->session_id, a->session_id_length);
|
||||
|
|
@ -3906,12 +3943,29 @@ static unsigned long ssl_session_hash(const SSL_SESSION *a)
|
|||
/*
|
||||
* NB: If this function (or indeed the hash function which uses a sort of
|
||||
* coarser function than this one) is changed, ensure
|
||||
* SSL_CTX_has_matching_session_id() is checked accordingly. It relies on
|
||||
* SSL_has_matching_session_id() is checked accordingly. It relies on
|
||||
* being able to construct an SSL_SESSION that will collide with any existing
|
||||
* session with a matching session ID.
|
||||
*/
|
||||
static int ssl_session_cmp(const SSL_SESSION *a, const SSL_SESSION *b)
|
||||
{
|
||||
/* if both have cache_id set, use that (assume client-side cache) */
|
||||
if (a->cache_id != NULL && b->cache_id != NULL) {
|
||||
if (a->cache_id_len != b->cache_id_len
|
||||
|| memcmp(a->cache_id, b->cache_id, a->cache_id_len) != 0)
|
||||
return 1;
|
||||
if (a->sid_ctx_length != b->sid_ctx_length)
|
||||
return 1;
|
||||
if (a->sid_ctx_length > 0
|
||||
&& memcmp(a->sid_ctx, b->sid_ctx, a->sid_ctx_length) != 0)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
/* if only one has a cache_id, it's not a match */
|
||||
if (a->cache_id != NULL || b->cache_id != NULL)
|
||||
return 1;
|
||||
|
||||
/* compare session id (assume server-side cache) */
|
||||
if (a->ssl_version != b->ssl_version)
|
||||
return 1;
|
||||
if (a->session_id_length != b->session_id_length)
|
||||
|
|
@ -5031,6 +5085,10 @@ void SSL_set_accept_state(SSL *s)
|
|||
#endif
|
||||
|
||||
sc->server = 1;
|
||||
/* Don't use cache_id with servers */
|
||||
OPENSSL_free(sc->cache_id);
|
||||
sc->cache_id = NULL;
|
||||
sc->cache_id_len = 0;
|
||||
sc->shutdown = 0;
|
||||
ossl_statem_clear(sc);
|
||||
sc->handshake_func = s->method->ssl_accept;
|
||||
|
|
@ -5268,6 +5326,10 @@ SSL *SSL_dup(SSL *s)
|
|||
|| !dup_ca_names(&retsc->client_ca_names, sc->client_ca_names))
|
||||
goto err;
|
||||
|
||||
if (sc->cache_id != NULL)
|
||||
if ((retsc->cache_id = OPENSSL_memdup(sc->cache_id, sc->cache_id_len)) == NULL)
|
||||
goto err;
|
||||
|
||||
return ret;
|
||||
|
||||
err:
|
||||
|
|
|
|||
|
|
@ -551,6 +551,8 @@ struct ssl_session_st {
|
|||
# ifndef OPENSSL_NO_SRP
|
||||
char *srp_username;
|
||||
# endif
|
||||
unsigned char *cache_id;
|
||||
size_t cache_id_len;
|
||||
unsigned char *ticket_appdata;
|
||||
size_t ticket_appdata_len;
|
||||
uint32_t flags;
|
||||
|
|
@ -1845,6 +1847,9 @@ struct ssl_connection_st {
|
|||
SSL_async_callback_fn async_cb;
|
||||
void *async_cb_arg;
|
||||
|
||||
/* Client cache data */
|
||||
unsigned char *cache_id;
|
||||
size_t cache_id_len;
|
||||
/*
|
||||
* Signature algorithms shared by client and server: cached because these
|
||||
* are used most often.
|
||||
|
|
|
|||
173
ssl/ssl_sess.c
173
ssl/ssl_sess.c
|
|
@ -165,6 +165,7 @@ static SSL_SESSION *ssl_session_dup_intern(const SSL_SESSION *src, int ticket)
|
|||
dest->peer = NULL;
|
||||
dest->peer_rpk = NULL;
|
||||
dest->ticket_appdata = NULL;
|
||||
dest->cache_id = NULL;
|
||||
memset(&dest->ex_data, 0, sizeof(dest->ex_data));
|
||||
|
||||
/* As the copy is not in the cache, we remove the associated pointers */
|
||||
|
|
@ -261,6 +262,13 @@ static SSL_SESSION *ssl_session_dup_intern(const SSL_SESSION *src, int ticket)
|
|||
goto err;
|
||||
}
|
||||
|
||||
if (src->cache_id != NULL) {
|
||||
dest->cache_id =
|
||||
OPENSSL_memdup(src->cache_id, src->cache_id_len);
|
||||
if (dest->cache_id == NULL)
|
||||
goto err;
|
||||
}
|
||||
|
||||
return dest;
|
||||
err:
|
||||
SSL_SESSION_free(dest);
|
||||
|
|
@ -480,6 +488,10 @@ int ssl_get_new_session(SSL_CONNECTION *s, int session)
|
|||
}
|
||||
memcpy(ss->sid_ctx, s->sid_ctx, s->sid_ctx_length);
|
||||
ss->sid_ctx_length = s->sid_ctx_length;
|
||||
if (s->cache_id != NULL && s->cache_id_len > 0) {
|
||||
ss->cache_id = OPENSSL_memdup(s->cache_id, s->cache_id_len);
|
||||
ss->cache_id_len = s->cache_id_len;
|
||||
}
|
||||
s->session = ss;
|
||||
ss->ssl_version = s->version;
|
||||
ss->verify_result = X509_V_OK;
|
||||
|
|
@ -501,6 +513,7 @@ SSL_SESSION *lookup_sess_in_cache(SSL_CONNECTION *s,
|
|||
& SSL_SESS_CACHE_NO_INTERNAL_LOOKUP) == 0) {
|
||||
SSL_SESSION data;
|
||||
|
||||
data.cache_id = NULL;
|
||||
data.ssl_version = s->version;
|
||||
if (!ossl_assert(sess_id_len <= SSL_MAX_SSL_SESSION_ID_LENGTH))
|
||||
return NULL;
|
||||
|
|
@ -875,6 +888,7 @@ void SSL_SESSION_free(SSL_SESSION *ss)
|
|||
#endif
|
||||
OPENSSL_free(ss->ext.alpn_selected);
|
||||
OPENSSL_free(ss->ticket_appdata);
|
||||
OPENSSL_free(ss->cache_id);
|
||||
CRYPTO_FREE_REF(&ss->references);
|
||||
OPENSSL_clear_free(ss, sizeof(*ss));
|
||||
}
|
||||
|
|
@ -1469,4 +1483,163 @@ void SSL_CTX_set_stateless_cookie_verify_cb(
|
|||
ctx->verify_stateless_cookie_cb = cb;
|
||||
}
|
||||
|
||||
SSL_SESSION *SSL_get1_previous_client_session(SSL *s)
|
||||
{
|
||||
SSL_SESSION *ret = NULL;
|
||||
SSL_SESSION data;
|
||||
uint32_t mode;
|
||||
SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);
|
||||
|
||||
if (sc == NULL)
|
||||
return 0;
|
||||
|
||||
mode = sc->session_ctx->session_cache_mode;
|
||||
|
||||
/* Must have client mode enabled. */
|
||||
if ((mode & SSL_SESS_CACHE_CLIENT) != SSL_SESS_CACHE_CLIENT) {
|
||||
ERR_raise(ERR_LIB_SSL, SSL_R_BAD_CACHE_MODE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((mode & SSL_SESS_CACHE_NO_INTERNAL_LOOKUP) == 0) {
|
||||
/* Set up the search parameters */
|
||||
memset(&data, 0, sizeof(data));
|
||||
data.cache_id = sc->cache_id;
|
||||
data.cache_id_len = sc->cache_id_len;
|
||||
data.sid_ctx_length = sc->sid_ctx_length;
|
||||
if (sc->sid_ctx_length > 0)
|
||||
memcpy(data.sid_ctx, sc->sid_ctx, sc->sid_ctx_length);
|
||||
|
||||
/* search */
|
||||
if (!CRYPTO_THREAD_read_lock(sc->session_ctx->lock))
|
||||
return NULL;
|
||||
ret = lh_SSL_SESSION_retrieve(sc->session_ctx->sessions, &data);
|
||||
if (ret != NULL)
|
||||
SSL_SESSION_up_ref(ret);
|
||||
CRYPTO_THREAD_unlock(sc->session_ctx->lock);
|
||||
|
||||
if (ret == NULL) {
|
||||
ssl_tsan_counter(sc->session_ctx, &sc->session_ctx->stats.sess_miss);
|
||||
} else if (sess_timedout(ossl_time_now(), ret)) {
|
||||
ssl_tsan_counter(sc->session_ctx, &sc->session_ctx->stats.sess_timeout);
|
||||
SSL_CTX_remove_session(sc->session_ctx, ret);
|
||||
SSL_SESSION_free(ret);
|
||||
ret = NULL;
|
||||
} else {
|
||||
ssl_tsan_counter(sc->session_ctx, &sc->session_ctx->stats.sess_hit);
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == NULL && sc->session_ctx->get_session_cb != NULL) {
|
||||
int copy = 1;
|
||||
|
||||
ret = sc->session_ctx->get_session_cb(s, sc->cache_id,
|
||||
sc->cache_id_len,
|
||||
©);
|
||||
|
||||
if (ret != NULL) {
|
||||
ssl_tsan_counter(sc->session_ctx, &sc->session_ctx->stats.sess_hit);
|
||||
|
||||
/*
|
||||
* Increment reference count now if the session callback asks us
|
||||
* to do so (note that if the session structures returned by the
|
||||
* callback are shared between threads, it must handle the
|
||||
* reference count itself [i.e. copy == 0], or things won't be
|
||||
* thread-safe).
|
||||
*/
|
||||
if (copy)
|
||||
SSL_SESSION_up_ref(ret);
|
||||
|
||||
/*
|
||||
* Add the externally cached session to the internal cache as
|
||||
* well if and only if we are supposed to.
|
||||
*/
|
||||
if ((mode & SSL_SESS_CACHE_NO_INTERNAL_STORE) == 0) {
|
||||
/*
|
||||
* Either return value of SSL_CTX_add_session should not
|
||||
* interrupt the session resumption process. The return
|
||||
* value is intentionally ignored.
|
||||
*/
|
||||
SSL_CTX_add_session(sc->session_ctx, ret);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SSL_set1_cache_id(SSL *s, const unsigned char *data, size_t len)
|
||||
{
|
||||
SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);
|
||||
|
||||
if (sc == NULL)
|
||||
return 0;
|
||||
|
||||
if (sc->session != NULL) {
|
||||
ERR_raise(ERR_LIB_SSL, SSL_R_SESSION_ALREADY_SET);
|
||||
return 0;
|
||||
}
|
||||
if (sc->server) {
|
||||
ERR_raise(ERR_LIB_SSL, SSL_R_NO_CACHE_ID_ON_SERVER);
|
||||
return 0;
|
||||
}
|
||||
OPENSSL_free(sc->cache_id);
|
||||
sc->cache_id_len = 0;
|
||||
if (data == NULL) {
|
||||
sc->cache_id = NULL;
|
||||
} else {
|
||||
sc->cache_id = OPENSSL_memdup(data, len);
|
||||
if (sc->cache_id == NULL) {
|
||||
ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
sc->cache_id_len = len;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int SSL_get1_cache_id(const SSL *s, unsigned char **data, size_t *len)
|
||||
{
|
||||
SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);
|
||||
|
||||
if (sc == NULL || sc->server || sc->cache_id == NULL)
|
||||
return 0;
|
||||
if ((*data = OPENSSL_memdup(sc->cache_id, sc->cache_id_len)) == NULL)
|
||||
return 0;
|
||||
*len = sc->cache_id_len;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int SSL_SESSION_set1_cache_id(SSL_SESSION *ss, const unsigned char *data, size_t len)
|
||||
{
|
||||
if (ss->next != NULL || ss->prev != NULL) {
|
||||
ERR_raise(ERR_LIB_SSL, SSL_R_SESSION_ALREADY_IN_CACHE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
OPENSSL_free(ss->cache_id);
|
||||
ss->cache_id_len = 0;
|
||||
if (data == NULL) {
|
||||
ss->cache_id = NULL;
|
||||
} else {
|
||||
ss->cache_id = OPENSSL_memdup(data, len);
|
||||
if (ss->cache_id == NULL) {
|
||||
ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
ss->cache_id_len = len;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int SSL_SESSION_get1_cache_id(const SSL_SESSION *ss, unsigned char **data, size_t *len)
|
||||
{
|
||||
if (ss == NULL || ss->cache_id == NULL)
|
||||
return 0;
|
||||
if ((*data = OPENSSL_memdup(ss->cache_id, ss->cache_id_len)) == NULL)
|
||||
return 0;
|
||||
*len = ss->cache_id_len;
|
||||
return 1;
|
||||
}
|
||||
|
||||
IMPLEMENT_PEM_rw(SSL_SESSION, SSL_SESSION, PEM_STRING_SSL_SESSION, SSL_SESSION)
|
||||
|
|
|
|||
|
|
@ -877,7 +877,8 @@ EXT_RETURN tls_construct_ctos_early_data(SSL_CONNECTION *s, WPACKET *pkt,
|
|||
if (psksess == NULL
|
||||
|| !SSL_SESSION_set1_master_key(psksess, psk, psklen)
|
||||
|| !SSL_SESSION_set_cipher(psksess, cipher)
|
||||
|| !SSL_SESSION_set_protocol_version(psksess, TLS1_3_VERSION)) {
|
||||
|| !SSL_SESSION_set_protocol_version(psksess, TLS1_3_VERSION)
|
||||
|| !SSL_SESSION_set1_cache_id(psksess, s->cache_id, s->cache_id_len)) {
|
||||
SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
|
||||
OPENSSL_cleanse(psk, psklen);
|
||||
return EXT_RETURN_FAIL;
|
||||
|
|
|
|||
|
|
@ -69,7 +69,8 @@ IF[{- !$disabled{tests} -}]
|
|||
ca_internals_test bio_tfo_test membio_test bio_dgram_test list_test \
|
||||
fips_version_test x509_test hpke_test pairwise_fail_test \
|
||||
nodefltctxtest evp_xof_test x509_load_cert_file_test bio_meth_test \
|
||||
x509_acert_test x509_req_test strtoultest bio_pw_callback_test
|
||||
x509_acert_test x509_req_test strtoultest bio_pw_callback_test \
|
||||
client_cache_test
|
||||
|
||||
IF[{- !$disabled{'rpk'} -}]
|
||||
PROGRAMS{noinst}=rpktest
|
||||
|
|
@ -590,6 +591,10 @@ IF[{- !$disabled{tests} -}]
|
|||
INCLUDE[rpktest]=../include ../apps/include ..
|
||||
DEPEND[rpktest]=../libcrypto ../libssl libtestutil.a
|
||||
|
||||
SOURCE[client_cache_test]=client_cache_test.c helpers/ssltestlib.c
|
||||
INCLUDE[client_cache_test]=../include ../apps/include ..
|
||||
DEPEND[client_cache_test]=../libcrypto ../libssl libtestutil.a
|
||||
|
||||
SOURCE[defltfips_test]=defltfips_test.c
|
||||
INCLUDE[defltfips_test]=../include ../apps/include
|
||||
DEPEND[defltfips_test]=../libcrypto libtestutil.a
|
||||
|
|
|
|||
|
|
@ -0,0 +1,244 @@
|
|||
/*
|
||||
* Copyright 2023-2025 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
#include <openssl/ssl.h>
|
||||
|
||||
#include "helpers/ssltestlib.h"
|
||||
#include "internal/dane.h"
|
||||
#include "testutil.h"
|
||||
|
||||
static char *certsdir = NULL;
|
||||
static char *cert = NULL;
|
||||
static char *privkey = NULL;
|
||||
static OSSL_LIB_CTX *libctx = NULL;
|
||||
|
||||
static const unsigned char sid_ctx[] = "sid";
|
||||
static const unsigned char cache_id[] = "this is a test";
|
||||
static const unsigned char cache_id2[] = "different";
|
||||
|
||||
static SSL_SESSION *external_cache = NULL;
|
||||
static SSL_SESSION *session_get_cb(SSL *ssl, const unsigned char *data, int len, int *copy)
|
||||
{
|
||||
unsigned char *cid;
|
||||
size_t cid_len;
|
||||
|
||||
if (!SSL_SESSION_get1_cache_id(external_cache, &cid, &cid_len))
|
||||
return NULL;
|
||||
|
||||
if (len != (int)cid_len || memcmp(cid, data, len) != 0) {
|
||||
OPENSSL_free(cid);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
OPENSSL_free(cid);
|
||||
*copy = 1;
|
||||
return external_cache;
|
||||
}
|
||||
|
||||
static int test_client_cache_external(void)
|
||||
{
|
||||
int ret = 0;
|
||||
SSL_CTX *cctx = NULL, *sctx = NULL;
|
||||
SSL *cssl = NULL, *sssl = NULL;
|
||||
uint32_t mode;
|
||||
SSL_SESSION *sess1 = NULL;
|
||||
|
||||
if (!TEST_true(create_ssl_ctx_pair(libctx, TLS_server_method(),
|
||||
TLS_client_method(), TLS1_VERSION, TLS1_2_VERSION,
|
||||
&sctx, &cctx, cert, privkey)))
|
||||
return 0;
|
||||
|
||||
mode = SSL_SESS_CACHE_CLIENT | SSL_SESS_CACHE_NO_INTERNAL_LOOKUP;
|
||||
if (!TEST_true(SSL_CTX_set_session_cache_mode(cctx, mode))
|
||||
|| !TEST_true(SSL_CTX_set_session_id_context(sctx, sid_ctx, sizeof(sid_ctx)))
|
||||
|| !TEST_true(SSL_CTX_set_session_id_context(cctx, sid_ctx, sizeof(sid_ctx))))
|
||||
goto end;
|
||||
|
||||
SSL_CTX_sess_set_get_cb(cctx, session_get_cb);
|
||||
|
||||
/* Initial connection - establishes external_cache */
|
||||
if (!TEST_true(create_ssl_objects(sctx, cctx, &sssl, &cssl, NULL, NULL))
|
||||
|| !TEST_true(SSL_set1_cache_id(cssl, cache_id, sizeof(cache_id)))
|
||||
|| !TEST_true(create_ssl_connection(sssl, cssl, SSL_ERROR_NONE))
|
||||
|| !TEST_ptr(external_cache = SSL_get1_session(cssl)))
|
||||
goto end;
|
||||
|
||||
shutdown_ssl_connection(sssl, cssl);
|
||||
sssl = cssl = NULL;
|
||||
|
||||
/* Test automatic assignment of session when client has cache_id set */
|
||||
if (!TEST_true(create_ssl_objects(sctx, cctx, &sssl, &cssl, NULL, NULL))
|
||||
|| !TEST_true(SSL_set1_cache_id(cssl, cache_id, sizeof(cache_id)))
|
||||
|| !TEST_true(create_ssl_connection(sssl, cssl, SSL_ERROR_NONE))
|
||||
|| !TEST_true(SSL_session_reused(cssl))
|
||||
|| !TEST_ptr(sess1 = SSL_get1_session(cssl)))
|
||||
goto end;
|
||||
|
||||
shutdown_ssl_connection(sssl, cssl);
|
||||
sssl = cssl = NULL;
|
||||
|
||||
/* Ensure client is resumed when no cache_id is set, but session is assigned */
|
||||
if (!TEST_true(create_ssl_objects(sctx, cctx, &sssl, &cssl, NULL, NULL))
|
||||
|| !TEST_true(SSL_set_session(cssl, sess1))
|
||||
|| !TEST_true(create_ssl_connection(sssl, cssl, SSL_ERROR_NONE))
|
||||
|| !TEST_true(SSL_session_reused(cssl)))
|
||||
goto end;
|
||||
|
||||
shutdown_ssl_connection(sssl, cssl);
|
||||
sssl = cssl = NULL;
|
||||
|
||||
/* Ensure client is not resumed when no cache_id is set */
|
||||
if (!TEST_true(create_ssl_objects(sctx, cctx, &sssl, &cssl, NULL, NULL))
|
||||
|| !TEST_true(create_ssl_connection(sssl, cssl, SSL_ERROR_NONE))
|
||||
|| !TEST_false(SSL_session_reused(cssl)))
|
||||
goto end;
|
||||
|
||||
shutdown_ssl_connection(sssl, cssl);
|
||||
sssl = cssl = NULL;
|
||||
|
||||
/* Ensure client is not resumed when a different cache_id is set */
|
||||
if (!TEST_true(create_ssl_objects(sctx, cctx, &sssl, &cssl, NULL, NULL))
|
||||
|| !TEST_true(SSL_set1_cache_id(cssl, cache_id2, sizeof(cache_id2)))
|
||||
|| !TEST_true(create_ssl_connection(sssl, cssl, SSL_ERROR_NONE))
|
||||
|| !TEST_false(SSL_session_reused(cssl)))
|
||||
goto end;
|
||||
|
||||
shutdown_ssl_connection(sssl, cssl);
|
||||
sssl = cssl = NULL;
|
||||
|
||||
ret = 1;
|
||||
end:
|
||||
SSL_free(sssl);
|
||||
SSL_free(cssl);
|
||||
SSL_SESSION_free(external_cache);
|
||||
external_cache = NULL;
|
||||
SSL_SESSION_free(sess1);
|
||||
SSL_CTX_free(sctx);
|
||||
SSL_CTX_free(cctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int test_client_cache(void)
|
||||
{
|
||||
int ret = 0;
|
||||
SSL_CTX *cctx = NULL, *sctx = NULL;
|
||||
SSL *cssl = NULL, *sssl = NULL;
|
||||
SSL_SESSION *sess1 = NULL, *sess2 = NULL, *sess3 = NULL;
|
||||
|
||||
if (!TEST_true(create_ssl_ctx_pair(libctx, TLS_server_method(),
|
||||
TLS_client_method(), TLS1_VERSION, TLS1_2_VERSION,
|
||||
&sctx, &cctx, cert, privkey)))
|
||||
return 0;
|
||||
|
||||
if (!TEST_true(SSL_CTX_set_session_cache_mode(cctx, SSL_SESS_CACHE_CLIENT))
|
||||
|| !TEST_true(SSL_CTX_set_session_id_context(sctx, sid_ctx, sizeof(sid_ctx)))
|
||||
|| !TEST_true(SSL_CTX_set_session_id_context(cctx, sid_ctx, sizeof(sid_ctx))))
|
||||
goto end;
|
||||
|
||||
/* Initial connection */
|
||||
if (!TEST_true(create_ssl_objects(sctx, cctx, &sssl, &cssl, NULL, NULL))
|
||||
|| !TEST_true(SSL_set1_cache_id(cssl, cache_id, sizeof(cache_id)))
|
||||
|| !TEST_true(create_ssl_connection(sssl, cssl, SSL_ERROR_NONE))
|
||||
|| !TEST_ptr(sess1 = SSL_get1_session(cssl)))
|
||||
goto end;
|
||||
|
||||
shutdown_ssl_connection(sssl, cssl);
|
||||
sssl = cssl = NULL;
|
||||
|
||||
/* Test automatic assignment of session when client has cache_id set */
|
||||
if (!TEST_true(create_ssl_objects(sctx, cctx, &sssl, &cssl, NULL, NULL))
|
||||
|| !TEST_true(SSL_set1_cache_id(cssl, cache_id, sizeof(cache_id)))
|
||||
|| !TEST_ptr(sess2 = SSL_get1_previous_client_session(cssl))
|
||||
|| !TEST_ptr_eq(sess1, sess2)
|
||||
|| !TEST_true(create_ssl_connection(sssl, cssl, SSL_ERROR_NONE))
|
||||
|| !TEST_true(SSL_session_reused(cssl))
|
||||
|| !TEST_ptr(sess3 = SSL_get1_session(cssl))
|
||||
|| !TEST_ptr_eq(sess2, sess3))
|
||||
goto end;
|
||||
|
||||
shutdown_ssl_connection(sssl, cssl);
|
||||
sssl = cssl = NULL;
|
||||
|
||||
/* Ensure client is resumed when no cache_id is set, but session is assigned */
|
||||
if (!TEST_true(create_ssl_objects(sctx, cctx, &sssl, &cssl, NULL, NULL))
|
||||
|| !TEST_true(SSL_set_session(cssl, sess3))
|
||||
|| !TEST_true(create_ssl_connection(sssl, cssl, SSL_ERROR_NONE))
|
||||
|| !TEST_true(SSL_session_reused(cssl)))
|
||||
goto end;
|
||||
|
||||
shutdown_ssl_connection(sssl, cssl);
|
||||
sssl = cssl = NULL;
|
||||
|
||||
/* Ensure client is not resumed when no cache_id is set */
|
||||
if (!TEST_true(create_ssl_objects(sctx, cctx, &sssl, &cssl, NULL, NULL))
|
||||
|| !TEST_true(create_ssl_connection(sssl, cssl, SSL_ERROR_NONE))
|
||||
|| !TEST_false(SSL_session_reused(cssl)))
|
||||
goto end;
|
||||
|
||||
shutdown_ssl_connection(sssl, cssl);
|
||||
sssl = cssl = NULL;
|
||||
|
||||
/* Ensure client is not resumed when a different cache_id is set */
|
||||
if (!TEST_true(create_ssl_objects(sctx, cctx, &sssl, &cssl, NULL, NULL))
|
||||
|| !TEST_true(SSL_set1_cache_id(cssl, cache_id2, sizeof(cache_id2)))
|
||||
|| !TEST_true(create_ssl_connection(sssl, cssl, SSL_ERROR_NONE))
|
||||
|| !TEST_false(SSL_session_reused(cssl)))
|
||||
goto end;
|
||||
|
||||
shutdown_ssl_connection(sssl, cssl);
|
||||
sssl = cssl = NULL;
|
||||
|
||||
ret = 1;
|
||||
end:
|
||||
SSL_free(sssl);
|
||||
SSL_free(cssl);
|
||||
SSL_SESSION_free(sess1);
|
||||
SSL_SESSION_free(sess2);
|
||||
SSL_SESSION_free(sess3);
|
||||
SSL_CTX_free(sctx);
|
||||
SSL_CTX_free(cctx);
|
||||
return ret;
|
||||
}
|
||||
OPT_TEST_DECLARE_USAGE("certdir\n")
|
||||
|
||||
int setup_tests(void)
|
||||
{
|
||||
if (!test_skip_common_options()) {
|
||||
TEST_error("Error parsing test options\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!TEST_ptr(certsdir = test_get_argument(0)))
|
||||
return 0;
|
||||
|
||||
cert = test_mk_file_path(certsdir, "servercert.pem");
|
||||
if (cert == NULL)
|
||||
goto err;
|
||||
|
||||
privkey = test_mk_file_path(certsdir, "serverkey.pem");
|
||||
if (privkey == NULL)
|
||||
goto err;
|
||||
|
||||
libctx = OSSL_LIB_CTX_new();
|
||||
if (libctx == NULL)
|
||||
goto err;
|
||||
|
||||
ADD_TEST(test_client_cache);
|
||||
ADD_TEST(test_client_cache_external);
|
||||
return 1;
|
||||
|
||||
err:
|
||||
return 0;
|
||||
}
|
||||
|
||||
void cleanup_tests(void)
|
||||
{
|
||||
OPENSSL_free(cert);
|
||||
OPENSSL_free(privkey);
|
||||
OSSL_LIB_CTX_free(libctx);
|
||||
}
|
||||
|
|
@ -23,9 +23,19 @@ print <<"_____";
|
|||
#ifndef OPENSSL_NO_STDIO
|
||||
# include <stdio.h>
|
||||
#endif
|
||||
_____
|
||||
|
||||
if (${name_uc} eq "RSA") {
|
||||
print("#include <openssl/rsa.h>");
|
||||
}
|
||||
else {
|
||||
print <<"_____";
|
||||
#ifndef OPENSSL_NO_${name_uc}
|
||||
# include <openssl/$name.h>
|
||||
#endif
|
||||
_____
|
||||
}
|
||||
print <<"_____";
|
||||
|
||||
int main(void)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -0,0 +1,23 @@
|
|||
#! /usr/bin/env perl
|
||||
# Copyright 2016-2025 The OpenSSL Project Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
# this file except in compliance with the License. You can obtain a copy
|
||||
# in the file LICENSE in the source distribution or at
|
||||
# https://www.openssl.org/source/license.html
|
||||
|
||||
use OpenSSL::Test::Utils;
|
||||
use OpenSSL::Test qw/:DEFAULT srctop_dir bldtop_dir/;
|
||||
|
||||
BEGIN {
|
||||
setup("test_client_cache");
|
||||
}
|
||||
|
||||
use lib srctop_dir('Configurations');
|
||||
use lib bldtop_dir('.');
|
||||
|
||||
plan skip_all => "TLS is disabled in this OpenSSL build" if disabled("tls1") && disabled("tls1_1") && disabled("tls1_2");
|
||||
|
||||
plan tests => 1;
|
||||
|
||||
ok(run(test(["client_cache_test", srctop_dir("test", "certs")])), "running client_cache_test");
|
||||
|
|
@ -24,6 +24,6 @@ test -d "$QUICHE_TARGET_PATH" || exit 1
|
|||
|
||||
"$QUICHE_TARGET_PATH/debug/quiche-server" --cert "$SRCTOP/test/certs/servercert.pem" \
|
||||
--key "$SRCTOP/test/certs/serverkey.pem" --disable-gso \
|
||||
--http-version HTTP/0.9 --root "$SRCTOP" --no-grease --disable-hystart &
|
||||
--http-version HTTP/0.9 --root "$SRCTOP" --no-grease --disable-hystart > quiche_server_log 2>&1 &
|
||||
|
||||
echo $! >server.pid
|
||||
|
|
|
|||
|
|
@ -1984,7 +1984,7 @@ static int test_tlsext_status_type(void)
|
|||
if (!create_ssl_ctx_pair(libctx, TLS_server_method(), TLS_client_method(),
|
||||
TLS1_VERSION, 0,
|
||||
&sctx, &cctx, leaf, skey))
|
||||
return 0;
|
||||
goto end;
|
||||
if (SSL_CTX_use_certificate_chain_file(sctx, leaf_chain) <= 0)
|
||||
goto end;
|
||||
if (SSL_CTX_get_tlsext_status_type(cctx) != -1)
|
||||
|
|
@ -2481,8 +2481,12 @@ static int execute_test_session(int maxprot, int use_int_cache,
|
|||
# ifndef OPENSSL_NO_TLS1_1
|
||||
SSL *serverssl3 = NULL, *clientssl3 = NULL;
|
||||
# endif
|
||||
SSL_SESSION *sess1 = NULL, *sess2 = NULL;
|
||||
SSL_SESSION *sess1 = NULL, *sess2 = NULL, *sess3 = NULL;
|
||||
int testresult = 0, numnewsesstick = 1;
|
||||
const unsigned char cache_id[] = "this is a test";
|
||||
size_t cache_id_len = sizeof("this is a test");
|
||||
unsigned char *new_cache_id = NULL;
|
||||
size_t new_cache_id_len;
|
||||
|
||||
new_called = remove_called = 0;
|
||||
|
||||
|
|
@ -2522,11 +2526,29 @@ static int execute_test_session(int maxprot, int use_int_cache,
|
|||
|
||||
if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl1, &clientssl1,
|
||||
NULL, NULL))
|
||||
|| !TEST_true(create_ssl_connection(serverssl1, clientssl1,
|
||||
SSL_ERROR_NONE))
|
||||
|| !TEST_true(SSL_set1_cache_id(clientssl1, cache_id, cache_id_len))
|
||||
|| !TEST_true(SSL_get1_cache_id(clientssl1, &new_cache_id, &new_cache_id_len))
|
||||
|| !TEST_mem_eq(cache_id, cache_id_len, new_cache_id, new_cache_id_len)
|
||||
|| !TEST_true(create_ssl_connection(serverssl1, clientssl1, SSL_ERROR_NONE))
|
||||
|| !TEST_false(SSL_set1_cache_id(clientssl1, cache_id, cache_id_len))
|
||||
|| !TEST_ptr(sess1 = SSL_get1_session(clientssl1)))
|
||||
goto end;
|
||||
|
||||
OPENSSL_free(new_cache_id);
|
||||
new_cache_id = NULL;
|
||||
|
||||
if (use_int_cache
|
||||
&& (!TEST_true(SSL_SESSION_get1_cache_id(sess1, &new_cache_id, &new_cache_id_len))
|
||||
|| !TEST_mem_eq(cache_id, cache_id_len, new_cache_id, new_cache_id_len)
|
||||
|| !TEST_ptr(sess3 = SSL_get1_previous_client_session(clientssl1))
|
||||
|| !TEST_ptr_eq(sess1, sess3)
|
||||
|| !TEST_false(SSL_SESSION_set1_cache_id(sess1, cache_id, cache_id_len))))
|
||||
goto end;
|
||||
|
||||
/* no longer used */
|
||||
SSL_SESSION_free(sess3);
|
||||
sess3 = NULL;
|
||||
|
||||
/* Should fail because it should already be in the cache */
|
||||
if (use_int_cache && !TEST_false(SSL_CTX_add_session(cctx, sess1)))
|
||||
goto end;
|
||||
|
|
@ -2782,8 +2804,10 @@ static int execute_test_session(int maxprot, int use_int_cache,
|
|||
# endif
|
||||
SSL_SESSION_free(sess1);
|
||||
SSL_SESSION_free(sess2);
|
||||
SSL_SESSION_free(sess3);
|
||||
SSL_CTX_free(sctx);
|
||||
SSL_CTX_free(cctx);
|
||||
OPENSSL_free(new_cache_id);
|
||||
|
||||
return testresult;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -606,3 +606,8 @@ SSL_CTX_set_domain_flags ? 3_5_0 EXIST::FUNCTION:
|
|||
SSL_CTX_get_domain_flags ? 3_5_0 EXIST::FUNCTION:
|
||||
SSL_get_domain_flags ? 3_5_0 EXIST::FUNCTION:
|
||||
SSL_CTX_set_new_pending_conn_cb ? 3_5_0 EXIST::FUNCTION:
|
||||
SSL_get1_previous_client_session ? 3_5_0 EXIST::FUNCTION:
|
||||
SSL_set1_cache_id ? 3_5_0 EXIST::FUNCTION:
|
||||
SSL_get1_cache_id ? 3_5_0 EXIST::FUNCTION:
|
||||
SSL_SESSION_set1_cache_id ? 3_5_0 EXIST::FUNCTION:
|
||||
SSL_SESSION_get1_cache_id ? 3_5_0 EXIST::FUNCTION:
|
||||
|
|
|
|||
Loading…
Reference in New Issue