Document session cache functions.
Also switch to the new variable names (SSL_CTX *ctx, SSL *ssl, SSL_SESSION *session) for all documented functions. Change-Id: I15e15a703b96af1727601108223c7ce3b0691f1d Reviewed-on: https://boringssl-review.googlesource.com/5882 Reviewed-by: Adam Langley <agl@google.com>
This commit is contained in:
parent
14e2b5070b
commit
dafbdd49c7
@ -431,7 +431,7 @@ OPENSSL_EXPORT int SSL_get_error(const SSL *ssl, int ret_code);
|
||||
* lookup callback indicated the session was unavailable. The caller may retry
|
||||
* the operation when lookup has completed.
|
||||
*
|
||||
* See also |SSL_CTX_sess_set_get_cb|. */
|
||||
* See also |SSL_CTX_sess_set_get_cb| and |SSL_magic_pending_session_ptr|. */
|
||||
#define SSL_ERROR_PENDING_SESSION 11
|
||||
|
||||
/* SSL_ERROR_PENDING_CERTIFICATE indicates the operation failed because the
|
||||
@ -505,7 +505,7 @@ OPENSSL_EXPORT void SSL_set_max_version(SSL *ssl, uint16_t version);
|
||||
* |BIO|. Instead, the MTU is configured with |SSL_set_mtu|. */
|
||||
#define SSL_OP_NO_QUERY_MTU 0x00001000L
|
||||
|
||||
/* SSL_OP_NO_TICKET disables session ticket support (RFC 4507). */
|
||||
/* SSL_OP_NO_TICKET disables session ticket support (RFC 5077). */
|
||||
#define SSL_OP_NO_TICKET 0x00004000L
|
||||
|
||||
/* SSL_OP_CIPHER_SERVER_PREFERENCE configures servers to select ciphers and
|
||||
@ -1135,7 +1135,260 @@ OPENSSL_EXPORT int SSL_SESSION_set1_id_context(SSL_SESSION *session,
|
||||
unsigned sid_ctx_len);
|
||||
|
||||
|
||||
/* Session tickets. */
|
||||
/* Session caching.
|
||||
*
|
||||
* Session caching allows clients to reconnect to a server based on saved
|
||||
* parameters from a previous connection.
|
||||
*
|
||||
* For a server, the library implements a built-in internal session cache as an
|
||||
* in-memory hash table. One may also register callbacks to implement a custom
|
||||
* external session cache. An external cache may be used in addition to or
|
||||
* instead of the internal one. Use |SSL_CTX_set_session_cache_mode| to toggle
|
||||
* the internal cache.
|
||||
*
|
||||
* For a client, the only option is an external session cache. Prior to
|
||||
* handshaking, the consumer should look up a session externally (keyed, for
|
||||
* instance, by hostname) and use |SSL_set_session| to configure which session
|
||||
* to offer. The callbacks may be used to determine when new sessions are
|
||||
* available.
|
||||
*
|
||||
* Note that offering or accepting a session short-circuits most parameter
|
||||
* negotiation. Resuming sessions across different configurations may result in
|
||||
* surprising behavor. So, for instance, a client implementing a version
|
||||
* fallback should shard its session cache by maximum protocol version. */
|
||||
|
||||
/* SSL_SESS_CACHE_OFF disables all session caching. */
|
||||
#define SSL_SESS_CACHE_OFF 0x0000
|
||||
|
||||
/* SSL_SESS_CACHE_CLIENT enables session caching for a client.
|
||||
*
|
||||
* TODO(davidben): The internal cache is useless on the client. Always act as if
|
||||
* SSL_SESS_CACHE_NO_INTERNAL is set. https://crbug.com/531194. Also see TODO
|
||||
* attached to |SSL_CTX_sess_set_new_cb|. */
|
||||
#define SSL_SESS_CACHE_CLIENT 0x0001
|
||||
|
||||
/* SSL_SESS_CACHE_SERVER enables session caching for a server. */
|
||||
#define SSL_SESS_CACHE_SERVER 0x0002
|
||||
|
||||
/* SSL_SESS_CACHE_SERVER enables session caching for both client and server. */
|
||||
#define SSL_SESS_CACHE_BOTH (SSL_SESS_CACHE_CLIENT | SSL_SESS_CACHE_SERVER)
|
||||
|
||||
/* SSL_SESS_CACHE_NO_AUTO_CLEAR disables automatically calling
|
||||
* |SSL_CTX_flush_sessions| every 255 connections. */
|
||||
#define SSL_SESS_CACHE_NO_AUTO_CLEAR 0x0080
|
||||
|
||||
/* SSL_SESS_CACHE_NO_INTERNAL_LOOKUP disables looking up a session from the
|
||||
* internal session cache. */
|
||||
#define SSL_SESS_CACHE_NO_INTERNAL_LOOKUP 0x0100
|
||||
|
||||
/* SSL_SESS_CACHE_NO_INTERNAL_STORE disables storing sessions in the internal
|
||||
* session cache. */
|
||||
#define SSL_SESS_CACHE_NO_INTERNAL_STORE 0x0200
|
||||
|
||||
/* SSL_SESS_CACHE_NO_INTERNAL disables the internal session cache. */
|
||||
#define SSL_SESS_CACHE_NO_INTERNAL \
|
||||
(SSL_SESS_CACHE_NO_INTERNAL_LOOKUP | SSL_SESS_CACHE_NO_INTERNAL_STORE)
|
||||
|
||||
/* SSL_CTX_set_session_cache_mode sets the session cache mode bits for |ctx| to
|
||||
* |mode|. It returns the previous value. */
|
||||
OPENSSL_EXPORT int SSL_CTX_set_session_cache_mode(SSL_CTX *ctx, int mode);
|
||||
|
||||
/* SSL_CTX_get_session_cache_mode returns the session cache mode bits for
|
||||
* |ctx| */
|
||||
OPENSSL_EXPORT int SSL_CTX_get_session_cache_mode(const SSL_CTX *ctx);
|
||||
|
||||
/* SSL_set_session, for a client, configures |ssl| to offer to resume |session|
|
||||
* in the initial handshake. */
|
||||
OPENSSL_EXPORT int SSL_set_session(SSL *ssl, SSL_SESSION *session);
|
||||
|
||||
/* SSL_get_session returns a non-owning pointer to |ssl|'s session. Prior to the
|
||||
* initial handshake beginning, this is the session to be offered, set by
|
||||
* |SSL_set_session|. After a handshake has finished, this is the currently
|
||||
* active session. Its behavior is undefined while a handshake is progress. */
|
||||
OPENSSL_EXPORT SSL_SESSION *SSL_get_session(const SSL *ssl);
|
||||
|
||||
/* SSL_get0_session is an alias for |SSL_get_session|. */
|
||||
#define SSL_get0_session SSL_get_session
|
||||
|
||||
/* SSL_get1_session acts like |SSL_get_session| but returns a new reference to
|
||||
* the session. */
|
||||
OPENSSL_EXPORT SSL_SESSION *SSL_get1_session(SSL *ssl);
|
||||
|
||||
/* SSL_CTX_set_timeout sets the lifetime of sessions created in |ctx| to
|
||||
* |timeout|. */
|
||||
OPENSSL_EXPORT long SSL_CTX_set_timeout(SSL_CTX *ctx, long timeout);
|
||||
|
||||
/* SSL_CTX_get_timeout returns the lifetime of sessions created in |ctx|. */
|
||||
OPENSSL_EXPORT long SSL_CTX_get_timeout(const SSL_CTX *ctx);
|
||||
|
||||
/* SSL_CTX_set_session_id_context sets |ctx|'s session ID context to |sid_ctx|.
|
||||
* It returns one on success and zero on error. The session ID context is an
|
||||
* application-defined opaque byte string. A session will not be used in a
|
||||
* connection without a matching session ID context.
|
||||
*
|
||||
* For a server, if |SSL_VERIFY_PEER| is enabled, it is an error to not set a
|
||||
* session ID context.
|
||||
*
|
||||
* TODO(davidben): Is that check needed? That seems a special case of taking
|
||||
* care not to cross-resume across configuration changes, and this is only
|
||||
* relevant if a server requires client auth. */
|
||||
OPENSSL_EXPORT int SSL_CTX_set_session_id_context(SSL_CTX *ctx,
|
||||
const uint8_t *sid_ctx,
|
||||
unsigned sid_ctx_len);
|
||||
|
||||
/* SSL_set_session_id_context sets |ssl|'s session ID context to |sid_ctx|. It
|
||||
* returns one on success and zero on error. See also
|
||||
* |SSL_CTX_set_session_id_context|. */
|
||||
OPENSSL_EXPORT int SSL_set_session_id_context(SSL *ssl, const uint8_t *sid_ctx,
|
||||
unsigned sid_ctx_len);
|
||||
|
||||
/* SSL_CTX_sess_set_cache_size sets the maximum size of |ctx|'s internal session
|
||||
* cache to |size|. It returns the previous value. */
|
||||
OPENSSL_EXPORT unsigned long SSL_CTX_sess_set_cache_size(SSL_CTX *ctx,
|
||||
unsigned long size);
|
||||
|
||||
/* SSL_CTX_sess_get_cache_size returns the maximum size of |ctx|'s internal
|
||||
* session cache. */
|
||||
OPENSSL_EXPORT unsigned long SSL_CTX_sess_get_cache_size(const SSL_CTX *ctx);
|
||||
|
||||
/* SSL_CTX_sessions returns |ctx|'s internal session cache. */
|
||||
OPENSSL_EXPORT LHASH_OF(SSL_SESSION) *SSL_CTX_sessions(SSL_CTX *ctx);
|
||||
|
||||
/* SSL_CTX_sess_number returns the number of sessions in |ctx|'s internal
|
||||
* session cache. */
|
||||
OPENSSL_EXPORT size_t SSL_CTX_sess_number(const SSL_CTX *ctx);
|
||||
|
||||
/* SSL_CTX_add_session inserts |session| into |ctx|'s internal session cache. It
|
||||
* returns one on success and zero on error or if |ctx| already included a
|
||||
* session with that session ID. The caller retains its reference to
|
||||
* |session|. */
|
||||
OPENSSL_EXPORT int SSL_CTX_add_session(SSL_CTX *ctx, SSL_SESSION *session);
|
||||
|
||||
/* SSL_CTX_remove_session removes |session| from |ctx|'s internal session cache.
|
||||
* It returns one on success and zero on error or if no session with a matching
|
||||
* ID was found. */
|
||||
OPENSSL_EXPORT int SSL_CTX_remove_session(SSL_CTX *ctx, SSL_SESSION *session);
|
||||
|
||||
/* SSL_CTX_flush_sessions removes all sessions from |ctx| which have expired as
|
||||
* of time |time|. If |time| is zero, all sessions are removed. */
|
||||
OPENSSL_EXPORT void SSL_CTX_flush_sessions(SSL_CTX *ctx, long time);
|
||||
|
||||
/* SSL_CTX_sess_set_new_cb sets the callback to be called when a new session is
|
||||
* established and ready to be cached. If the session cache is disabled (the
|
||||
* appropriate one of |SSL_SESS_CACHE_CLIENT| or |SSL_SESS_CACHE_SERVER| is
|
||||
* unset), the callback is not called.
|
||||
*
|
||||
* The callback is passed a reference to |session|. It returns one if it takes
|
||||
* ownership and zero otherwise.
|
||||
*
|
||||
* Note: For a client, the callback may be called on abbreviated handshakes if a
|
||||
* ticket is renewed. Further, it may not be called until some time after
|
||||
* |SSL_do_handshake| or |SSL_connect| completes if False Start is enabled. Thus
|
||||
* it's recommended to use this callback over checking |SSL_session_reused| on
|
||||
* handshake completion.
|
||||
*
|
||||
* TODO(davidben): Conditioning callbacks on |SSL_SESS_CACHE_CLIENT| or
|
||||
* |SSL_SESS_CACHE_SERVER| doesn't make any sense when one could just as easily
|
||||
* not supply the callbacks. Removing that condition and the client internal
|
||||
* cache would simplify things. */
|
||||
OPENSSL_EXPORT void SSL_CTX_sess_set_new_cb(
|
||||
SSL_CTX *ctx, int (*new_session_cb)(SSL *ssl, SSL_SESSION *session));
|
||||
|
||||
/* SSL_CTX_sess_get_new_cb returns the callback set by
|
||||
* |SSL_CTX_sess_set_new_cb|. */
|
||||
OPENSSL_EXPORT int (*SSL_CTX_sess_get_new_cb(SSL_CTX *ctx))(
|
||||
SSL *ssl, SSL_SESSION *session);
|
||||
|
||||
/* SSL_CTX_sess_set_remove_cb sets a callback which is called when a session is
|
||||
* removed from the internal session cache.
|
||||
*
|
||||
* TODO(davidben): What is the point of this callback? It seems useless since it
|
||||
* only fires on sessions in the internal cache. */
|
||||
OPENSSL_EXPORT void SSL_CTX_sess_set_remove_cb(
|
||||
SSL_CTX *ctx,
|
||||
void (*remove_session_cb)(SSL_CTX *ctx, SSL_SESSION *session));
|
||||
|
||||
/* SSL_CTX_sess_get_remove_cb returns the callback set by
|
||||
* |SSL_CTX_sess_set_remove_cb|. */
|
||||
OPENSSL_EXPORT void (*SSL_CTX_sess_get_remove_cb(SSL_CTX *ctx))(
|
||||
SSL_CTX *ctx, SSL_SESSION *session);
|
||||
|
||||
/* SSL_CTX_sess_set_get_cb sets a callback to look up a session by ID for a
|
||||
* server. The callback is passed the session ID and should return a matching
|
||||
* |SSL_SESSION| or NULL if not found. It should set |*out_copy| to zero and
|
||||
* return a new reference to the session. This callback is not used for a
|
||||
* client.
|
||||
*
|
||||
* For historical reasons, if |*out_copy| is set to one (default), the SSL
|
||||
* library will take a new reference to the returned |SSL_SESSION|, expecting
|
||||
* the callback to return a non-owning pointer. This is not recommended. If
|
||||
* |ctx| and thus the callback is used on multiple threads, the session may be
|
||||
* removed and invalidated before the SSL library calls |SSL_SESSION_up_ref|,
|
||||
* whereas the callback may synchronize internally.
|
||||
*
|
||||
* To look up a session asynchronously, the callback may return
|
||||
* |SSL_magic_pending_session_ptr|. See the documentation for that function and
|
||||
* |SSL_ERROR_PENDING_SESSION|.
|
||||
*
|
||||
* If the internal session cache is enabled, the callback is only consulted if
|
||||
* the internal cache does not return a match. */
|
||||
OPENSSL_EXPORT void SSL_CTX_sess_set_get_cb(
|
||||
SSL_CTX *ctx,
|
||||
SSL_SESSION *(*get_session_cb)(SSL *ssl, uint8_t *id, int id_len,
|
||||
int *out_copy));
|
||||
|
||||
/* SSL_CTX_sess_get_get_cb returns the callback set by
|
||||
* |SSL_CTX_sess_set_get_cb|. */
|
||||
OPENSSL_EXPORT SSL_SESSION *(*SSL_CTX_sess_get_get_cb(SSL_CTX *ctx))(
|
||||
SSL *ssl, uint8_t *id, int id_len, int *out_copy);
|
||||
|
||||
/* SSL_magic_pending_session_ptr returns a magic |SSL_SESSION|* which indicates
|
||||
* that the session isn't currently unavailable. |SSL_get_error| will then
|
||||
* return |SSL_ERROR_PENDING_SESSION| and the handshake can be retried later
|
||||
* when the lookup has completed. */
|
||||
OPENSSL_EXPORT SSL_SESSION *SSL_magic_pending_session_ptr(void);
|
||||
|
||||
/* GEN_SESSION_CB is a callback to generate session IDs for |ssl|. It returns
|
||||
* one on success and zero on error. On success, the generated ID is written to
|
||||
* |id| and |*id_len| set to the length. On entry, |*id_len| is the maximum
|
||||
* length of the ID, but the callback may shorten it if desired. It is an error
|
||||
* for the callback to set the size to zero.
|
||||
*
|
||||
* Callbacks may use |SSL_has_matching_session_id| to check that the generated
|
||||
* ID is unique. */
|
||||
typedef int (*GEN_SESSION_CB)(const SSL *ssl, uint8_t *id, unsigned *id_len);
|
||||
|
||||
/* SSL_CTX_set_generate_session_id sets the session ID callback of |ctx| to
|
||||
* |cb| and returns one. It will be called on the server when establishing a new
|
||||
* session. */
|
||||
OPENSSL_EXPORT int SSL_CTX_set_generate_session_id(SSL_CTX *ctx,
|
||||
GEN_SESSION_CB cb);
|
||||
|
||||
/* SSL_set_generate_session_id sets the session ID callback of |ssl| to |cb| and
|
||||
* returns one. It will be called on the server when establishing a new
|
||||
* session. */
|
||||
OPENSSL_EXPORT int SSL_set_generate_session_id(SSL *ssl, GEN_SESSION_CB cb);
|
||||
|
||||
/* SSL_has_matching_session_id returns one if |ssl|'s session cache has a
|
||||
* session of value |id| and zero otherwise. */
|
||||
OPENSSL_EXPORT int SSL_has_matching_session_id(const SSL *ssl,
|
||||
const uint8_t *id,
|
||||
unsigned id_len);
|
||||
|
||||
|
||||
/* Session tickets.
|
||||
*
|
||||
* Session tickets, from RFC 5077, allow session resumption without server-side
|
||||
* state. Session tickets are supported in by default but may be disabled with
|
||||
* |SSL_OP_NO_TICKET|.
|
||||
*
|
||||
* On the client, ticket-based sessions use the same APIs as ID-based tickets.
|
||||
* Callers do not need to handle them differently.
|
||||
*
|
||||
* On the server, tickets are encrypted and authenticated with a secret key. By
|
||||
* default, an |SSL_CTX| generates a key on creation. Tickets are minted and
|
||||
* processed transparently. The following functions may be used to configure a
|
||||
* persistent key or implement more custom behavior. */
|
||||
|
||||
/* SSL_CTX_get_tlsext_ticket_keys writes |ctx|'s session ticket key material to
|
||||
* |len| bytes of |out|. It returns one on success and zero if |len| is not
|
||||
@ -1368,22 +1621,6 @@ typedef struct ssl_aead_ctx_st SSL_AEAD_CTX;
|
||||
|
||||
#define SSL_DEFAULT_SESSION_TIMEOUT (2 * 60 * 60)
|
||||
|
||||
/* This callback type is used inside SSL_CTX, SSL, and in the functions that
|
||||
* set them. It is used to override the generation of SSL/TLS session IDs in a
|
||||
* server. Return value should be zero on an error, non-zero to proceed. Also,
|
||||
* callbacks should themselves check if the id they generate is unique
|
||||
* otherwise the SSL handshake will fail with an error - callbacks can do this
|
||||
* using the 'ssl' value they're passed by;
|
||||
* SSL_has_matching_session_id(ssl, id, *id_len)
|
||||
* The length value passed in is set at the maximum size the session ID can be.
|
||||
* In SSLv2 this is 16 bytes, whereas SSLv3/TLSv1 it is 32 bytes. The callback
|
||||
* can alter this length to be less if desired, but under SSLv2 session IDs are
|
||||
* supposed to be fixed at 16 bytes so the id will be padded after the callback
|
||||
* returns in this case. It is also an error for the callback to set the size
|
||||
* to zero. */
|
||||
typedef int (*GEN_SESSION_CB)(const SSL *ssl, uint8_t *id,
|
||||
unsigned int *id_len);
|
||||
|
||||
/* ssl_early_callback_ctx is passed to certain callbacks that are called very
|
||||
* early on during the server handshake. At this point, much of the SSL* hasn't
|
||||
* been filled out and only the ClientHello can be depended on. */
|
||||
@ -1421,32 +1658,6 @@ struct ssl_comp_st {
|
||||
DECLARE_STACK_OF(SSL_COMP)
|
||||
DECLARE_LHASH_OF(SSL_SESSION)
|
||||
|
||||
OPENSSL_EXPORT LHASH_OF(SSL_SESSION) *SSL_CTX_sessions(SSL_CTX *ctx);
|
||||
|
||||
/* SSL_CTX_sess_number returns the number of sessions in |ctx|'s internal
|
||||
* session cache. */
|
||||
OPENSSL_EXPORT size_t SSL_CTX_sess_number(const SSL_CTX *ctx);
|
||||
|
||||
OPENSSL_EXPORT void SSL_CTX_sess_set_new_cb(
|
||||
SSL_CTX *ctx, int (*new_session_cb)(SSL *ssl, SSL_SESSION *sess));
|
||||
OPENSSL_EXPORT int (*SSL_CTX_sess_get_new_cb(SSL_CTX *ctx))(SSL *ssl,
|
||||
SSL_SESSION *sess);
|
||||
OPENSSL_EXPORT void SSL_CTX_sess_set_remove_cb(
|
||||
SSL_CTX *ctx,
|
||||
void (*remove_session_cb)(SSL_CTX *ctx, SSL_SESSION *sess));
|
||||
OPENSSL_EXPORT void (*SSL_CTX_sess_get_remove_cb(SSL_CTX *ctx))(
|
||||
SSL_CTX *ctx, SSL_SESSION *sess);
|
||||
OPENSSL_EXPORT void SSL_CTX_sess_set_get_cb(
|
||||
SSL_CTX *ctx,
|
||||
SSL_SESSION *(*get_session_cb)(SSL *ssl, uint8_t *data, int len,
|
||||
int *copy));
|
||||
OPENSSL_EXPORT SSL_SESSION *(*SSL_CTX_sess_get_get_cb(SSL_CTX *ctx))(
|
||||
SSL *ssl, uint8_t *data, int len, int *copy);
|
||||
/* SSL_magic_pending_session_ptr returns a magic |SSL_SESSION|* which indicates
|
||||
* that the session isn't currently unavailable. |SSL_get_error| will then
|
||||
* return |SSL_ERROR_PENDING_SESSION| and the handshake can be retried later
|
||||
* when the lookup has completed. */
|
||||
OPENSSL_EXPORT SSL_SESSION *SSL_magic_pending_session_ptr(void);
|
||||
OPENSSL_EXPORT void SSL_CTX_set_info_callback(SSL_CTX *ctx,
|
||||
void (*cb)(const SSL *ssl,
|
||||
int type, int val));
|
||||
@ -1840,14 +2051,10 @@ OPENSSL_EXPORT int SSL_set1_curves(SSL *ssl, const int *curves,
|
||||
OPENSSL_EXPORT int SSL_CTX_set_cipher_list(SSL_CTX *, const char *str);
|
||||
OPENSSL_EXPORT int SSL_CTX_set_cipher_list_tls10(SSL_CTX *, const char *str);
|
||||
OPENSSL_EXPORT int SSL_CTX_set_cipher_list_tls11(SSL_CTX *, const char *str);
|
||||
OPENSSL_EXPORT long SSL_CTX_set_timeout(SSL_CTX *ctx, long t);
|
||||
OPENSSL_EXPORT long SSL_CTX_get_timeout(const SSL_CTX *ctx);
|
||||
OPENSSL_EXPORT X509_STORE *SSL_CTX_get_cert_store(const SSL_CTX *);
|
||||
OPENSSL_EXPORT void SSL_CTX_set_cert_store(SSL_CTX *, X509_STORE *);
|
||||
OPENSSL_EXPORT int SSL_want(const SSL *s);
|
||||
|
||||
OPENSSL_EXPORT void SSL_CTX_flush_sessions(SSL_CTX *ctx, long tm);
|
||||
|
||||
/* SSL_get_current_cipher returns the cipher used in the current outgoing
|
||||
* connection state, or NULL if the null cipher is active. */
|
||||
OPENSSL_EXPORT const SSL_CIPHER *SSL_get_current_cipher(const SSL *s);
|
||||
@ -1883,15 +2090,6 @@ OPENSSL_EXPORT const char *SSL_state_string_long(const SSL *s);
|
||||
OPENSSL_EXPORT int SSL_SESSION_print_fp(FILE *fp, const SSL_SESSION *ses);
|
||||
OPENSSL_EXPORT int SSL_SESSION_print(BIO *fp, const SSL_SESSION *ses);
|
||||
|
||||
OPENSSL_EXPORT int SSL_set_session(SSL *to, SSL_SESSION *session);
|
||||
OPENSSL_EXPORT int SSL_CTX_add_session(SSL_CTX *s, SSL_SESSION *c);
|
||||
OPENSSL_EXPORT int SSL_CTX_remove_session(SSL_CTX *, SSL_SESSION *c);
|
||||
OPENSSL_EXPORT int SSL_CTX_set_generate_session_id(SSL_CTX *, GEN_SESSION_CB);
|
||||
OPENSSL_EXPORT int SSL_set_generate_session_id(SSL *, GEN_SESSION_CB);
|
||||
OPENSSL_EXPORT int SSL_has_matching_session_id(const SSL *ssl,
|
||||
const uint8_t *id,
|
||||
unsigned int id_len);
|
||||
|
||||
OPENSSL_EXPORT int SSL_CTX_get_verify_mode(const SSL_CTX *ctx);
|
||||
OPENSSL_EXPORT int SSL_CTX_get_verify_depth(const SSL_CTX *ctx);
|
||||
OPENSSL_EXPORT int (*SSL_CTX_get_verify_callback(const SSL_CTX *ctx))(
|
||||
@ -1907,13 +2105,6 @@ OPENSSL_EXPORT void SSL_CTX_set_default_passwd_cb(SSL_CTX *ctx,
|
||||
OPENSSL_EXPORT void SSL_CTX_set_default_passwd_cb_userdata(SSL_CTX *ctx,
|
||||
void *u);
|
||||
|
||||
OPENSSL_EXPORT int SSL_CTX_set_session_id_context(SSL_CTX *ctx,
|
||||
const uint8_t *sid_ctx,
|
||||
unsigned int sid_ctx_len);
|
||||
|
||||
OPENSSL_EXPORT int SSL_set_session_id_context(SSL *ssl, const uint8_t *sid_ctx,
|
||||
unsigned int sid_ctx_len);
|
||||
|
||||
OPENSSL_EXPORT int SSL_CTX_set_purpose(SSL_CTX *s, int purpose);
|
||||
OPENSSL_EXPORT int SSL_set_purpose(SSL *s, int purpose);
|
||||
OPENSSL_EXPORT int SSL_CTX_set_trust(SSL_CTX *s, int trust);
|
||||
@ -1969,10 +2160,6 @@ OPENSSL_EXPORT int SSL_CTX_set_default_verify_paths(SSL_CTX *ctx);
|
||||
OPENSSL_EXPORT int SSL_CTX_load_verify_locations(SSL_CTX *ctx,
|
||||
const char *CAfile,
|
||||
const char *CApath);
|
||||
#define SSL_get0_session SSL_get_session /* just peek at pointer */
|
||||
OPENSSL_EXPORT SSL_SESSION *SSL_get_session(const SSL *ssl);
|
||||
OPENSSL_EXPORT SSL_SESSION *SSL_get1_session(
|
||||
SSL *ssl); /* obtain a reference count */
|
||||
OPENSSL_EXPORT SSL_CTX *SSL_get_SSL_CTX(const SSL *ssl);
|
||||
OPENSSL_EXPORT SSL_CTX *SSL_set_SSL_CTX(SSL *ssl, SSL_CTX *ctx);
|
||||
OPENSSL_EXPORT void SSL_set_info_callback(SSL *ssl,
|
||||
@ -1987,35 +2174,6 @@ OPENSSL_EXPORT long SSL_get_verify_result(const SSL *ssl);
|
||||
|
||||
OPENSSL_EXPORT int SSL_get_ex_data_X509_STORE_CTX_idx(void);
|
||||
|
||||
/* SSL_CTX_sess_set_cache_size sets the maximum size of |ctx|'s session cache to
|
||||
* |size|. It returns the previous value. */
|
||||
OPENSSL_EXPORT unsigned long SSL_CTX_sess_set_cache_size(SSL_CTX *ctx,
|
||||
unsigned long size);
|
||||
|
||||
/* SSL_CTX_sess_get_cache_size returns the maximum size of |ctx|'s session
|
||||
* cache. */
|
||||
OPENSSL_EXPORT unsigned long SSL_CTX_sess_get_cache_size(const SSL_CTX *ctx);
|
||||
|
||||
/* SSL_SESS_CACHE_* are the possible session cache mode bits.
|
||||
* TODO(davidben): Document. */
|
||||
#define SSL_SESS_CACHE_OFF 0x0000
|
||||
#define SSL_SESS_CACHE_CLIENT 0x0001
|
||||
#define SSL_SESS_CACHE_SERVER 0x0002
|
||||
#define SSL_SESS_CACHE_BOTH (SSL_SESS_CACHE_CLIENT | SSL_SESS_CACHE_SERVER)
|
||||
#define SSL_SESS_CACHE_NO_AUTO_CLEAR 0x0080
|
||||
#define SSL_SESS_CACHE_NO_INTERNAL_LOOKUP 0x0100
|
||||
#define SSL_SESS_CACHE_NO_INTERNAL_STORE 0x0200
|
||||
#define SSL_SESS_CACHE_NO_INTERNAL \
|
||||
(SSL_SESS_CACHE_NO_INTERNAL_LOOKUP | SSL_SESS_CACHE_NO_INTERNAL_STORE)
|
||||
|
||||
/* SSL_CTX_set_session_cache_mode sets the session cache mode bits for |ctx| to
|
||||
* |mode|. It returns the previous value. */
|
||||
OPENSSL_EXPORT int SSL_CTX_set_session_cache_mode(SSL_CTX *ctx, int mode);
|
||||
|
||||
/* SSL_CTX_get_session_cache_mode returns the session cache mode bits for
|
||||
* |ctx| */
|
||||
OPENSSL_EXPORT int SSL_CTX_get_session_cache_mode(const SSL_CTX *ctx);
|
||||
|
||||
/* SSL_CTX_get_max_cert_list returns the maximum length, in bytes, of a peer
|
||||
* certificate chain accepted by |ctx|. */
|
||||
OPENSSL_EXPORT size_t SSL_CTX_get_max_cert_list(const SSL_CTX *ctx);
|
||||
|
@ -918,8 +918,8 @@ err:
|
||||
}
|
||||
|
||||
int SSL_CTX_set_session_id_context(SSL_CTX *ctx, const uint8_t *sid_ctx,
|
||||
unsigned int sid_ctx_len) {
|
||||
if (sid_ctx_len > sizeof ctx->sid_ctx) {
|
||||
unsigned sid_ctx_len) {
|
||||
if (sid_ctx_len > sizeof(ctx->sid_ctx)) {
|
||||
OPENSSL_PUT_ERROR(SSL, SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG);
|
||||
return 0;
|
||||
}
|
||||
@ -930,7 +930,7 @@ int SSL_CTX_set_session_id_context(SSL_CTX *ctx, const uint8_t *sid_ctx,
|
||||
}
|
||||
|
||||
int SSL_set_session_id_context(SSL *ssl, const uint8_t *sid_ctx,
|
||||
unsigned int sid_ctx_len) {
|
||||
unsigned sid_ctx_len) {
|
||||
if (sid_ctx_len > SSL_MAX_SID_CTX_LENGTH) {
|
||||
OPENSSL_PUT_ERROR(SSL, SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG);
|
||||
return 0;
|
||||
@ -952,7 +952,7 @@ int SSL_set_generate_session_id(SSL *ssl, GEN_SESSION_CB cb) {
|
||||
}
|
||||
|
||||
int SSL_has_matching_session_id(const SSL *ssl, const uint8_t *id,
|
||||
unsigned int id_len) {
|
||||
unsigned id_len) {
|
||||
/* A quick examination of SSL_SESSION_hash and SSL_SESSION_cmp shows how we
|
||||
* can "construct" a session to give us the desired check - ie. to find if
|
||||
* there's a session in the hash table that would conflict with any new
|
||||
|
@ -154,9 +154,9 @@ static const char g_pending_session_magic = 0;
|
||||
static CRYPTO_EX_DATA_CLASS g_ex_data_class =
|
||||
CRYPTO_EX_DATA_CLASS_INIT_WITH_APP_DATA;
|
||||
|
||||
static void SSL_SESSION_list_remove(SSL_CTX *ctx, SSL_SESSION *s);
|
||||
static void SSL_SESSION_list_add(SSL_CTX *ctx, SSL_SESSION *s);
|
||||
static int remove_session_lock(SSL_CTX *ctx, SSL_SESSION *c, int lck);
|
||||
static void SSL_SESSION_list_remove(SSL_CTX *ctx, SSL_SESSION *session);
|
||||
static void SSL_SESSION_list_add(SSL_CTX *ctx, SSL_SESSION *session);
|
||||
static int remove_session_lock(SSL_CTX *ctx, SSL_SESSION *session, int lock);
|
||||
|
||||
SSL_SESSION *SSL_SESSION_new(void) {
|
||||
SSL_SESSION *session = (SSL_SESSION *)OPENSSL_malloc(sizeof(SSL_SESSION));
|
||||
@ -301,9 +301,9 @@ void *SSL_SESSION_get_ex_data(const SSL_SESSION *session, int idx) {
|
||||
* server. How you might store that many sessions is perhaps a more interesting
|
||||
* question ... */
|
||||
static int def_generate_session_id(const SSL *ssl, uint8_t *id,
|
||||
unsigned int *id_len) {
|
||||
unsigned *id_len) {
|
||||
static const unsigned kMaxAttempts = 10;
|
||||
unsigned int retry = 0;
|
||||
unsigned retry = 0;
|
||||
do {
|
||||
if (!RAND_bytes(id, *id_len)) {
|
||||
return 0;
|
||||
@ -568,49 +568,49 @@ no_session:
|
||||
return ssl_session_success;
|
||||
}
|
||||
|
||||
int SSL_CTX_add_session(SSL_CTX *ctx, SSL_SESSION *c) {
|
||||
int SSL_CTX_add_session(SSL_CTX *ctx, SSL_SESSION *session) {
|
||||
int ret = 0;
|
||||
SSL_SESSION *s;
|
||||
SSL_SESSION *old_session;
|
||||
|
||||
/* add just 1 reference count for the SSL_CTX's session cache even though it
|
||||
/* Add just 1 reference count for the |SSL_CTX|'s session cache even though it
|
||||
* has two ways of access: each session is in a doubly linked list and an
|
||||
* lhash */
|
||||
SSL_SESSION_up_ref(c);
|
||||
/* if session c is in already in cache, we take back the increment later */
|
||||
* lhash. */
|
||||
SSL_SESSION_up_ref(session);
|
||||
/* If |session| is in already in cache, we take back the increment later. */
|
||||
|
||||
CRYPTO_MUTEX_lock_write(&ctx->lock);
|
||||
if (!lh_SSL_SESSION_insert(ctx->sessions, &s, c)) {
|
||||
if (!lh_SSL_SESSION_insert(ctx->sessions, &old_session, session)) {
|
||||
CRYPTO_MUTEX_unlock(&ctx->lock);
|
||||
SSL_SESSION_free(c);
|
||||
SSL_SESSION_free(session);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* s != NULL iff we already had a session with the given session ID. In this
|
||||
* case, s == c should hold (then we did not really modify ctx->sessions), or
|
||||
* we're in trouble. */
|
||||
if (s != NULL && s != c) {
|
||||
/* |old_session| != NULL iff we already had a session with the given session
|
||||
* ID. In this case, |old_session| == |session| should hold (then we did not
|
||||
* really modify |ctx->sessions|), or we're in trouble. */
|
||||
if (old_session != NULL && old_session != session) {
|
||||
/* We *are* in trouble ... */
|
||||
SSL_SESSION_list_remove(ctx, s);
|
||||
SSL_SESSION_free(s);
|
||||
SSL_SESSION_list_remove(ctx, old_session);
|
||||
SSL_SESSION_free(old_session);
|
||||
/* ... so pretend the other session did not exist in cache (we cannot
|
||||
* handle two SSL_SESSION structures with identical session ID in the same
|
||||
* handle two |SSL_SESSION| structures with identical session ID in the same
|
||||
* cache, which could happen e.g. when two threads concurrently obtain the
|
||||
* same session from an external cache) */
|
||||
s = NULL;
|
||||
* same session from an external cache). */
|
||||
old_session = NULL;
|
||||
}
|
||||
|
||||
/* Put at the head of the queue unless it is already in the cache */
|
||||
if (s == NULL) {
|
||||
SSL_SESSION_list_add(ctx, c);
|
||||
/* Put at the head of the queue unless it is already in the cache. */
|
||||
if (old_session == NULL) {
|
||||
SSL_SESSION_list_add(ctx, session);
|
||||
}
|
||||
|
||||
if (s != NULL) {
|
||||
/* existing cache entry -- decrement previously incremented reference count
|
||||
* because it already takes into account the cache */
|
||||
SSL_SESSION_free(s); /* s == c */
|
||||
if (old_session != NULL) {
|
||||
/* Existing cache entry -- decrement previously incremented reference count
|
||||
* because it already takes into account the cache. */
|
||||
SSL_SESSION_free(old_session); /* |old_session| == |session| */
|
||||
ret = 0;
|
||||
} else {
|
||||
/* new cache entry -- remove old ones if cache has become too large */
|
||||
/* New cache entry -- remove old ones if cache has become too large. */
|
||||
ret = 1;
|
||||
|
||||
if (SSL_CTX_sess_get_cache_size(ctx) > 0) {
|
||||
@ -626,23 +626,23 @@ int SSL_CTX_add_session(SSL_CTX *ctx, SSL_SESSION *c) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SSL_CTX_remove_session(SSL_CTX *ctx, SSL_SESSION *c) {
|
||||
return remove_session_lock(ctx, c, 1);
|
||||
int SSL_CTX_remove_session(SSL_CTX *ctx, SSL_SESSION *session) {
|
||||
return remove_session_lock(ctx, session, 1);
|
||||
}
|
||||
|
||||
static int remove_session_lock(SSL_CTX *ctx, SSL_SESSION *c, int lock) {
|
||||
SSL_SESSION *r;
|
||||
static int remove_session_lock(SSL_CTX *ctx, SSL_SESSION *session, int lock) {
|
||||
int ret = 0;
|
||||
|
||||
if (c != NULL && c->session_id_length != 0) {
|
||||
if (session != NULL && session->session_id_length != 0) {
|
||||
if (lock) {
|
||||
CRYPTO_MUTEX_lock_write(&ctx->lock);
|
||||
}
|
||||
r = lh_SSL_SESSION_retrieve(ctx->sessions, c);
|
||||
if (r == c) {
|
||||
SSL_SESSION *found_session = lh_SSL_SESSION_retrieve(ctx->sessions,
|
||||
session);
|
||||
if (found_session == session) {
|
||||
ret = 1;
|
||||
r = lh_SSL_SESSION_delete(ctx->sessions, c);
|
||||
SSL_SESSION_list_remove(ctx, c);
|
||||
found_session = lh_SSL_SESSION_delete(ctx->sessions, session);
|
||||
SSL_SESSION_list_remove(ctx, session);
|
||||
}
|
||||
|
||||
if (lock) {
|
||||
@ -650,49 +650,48 @@ static int remove_session_lock(SSL_CTX *ctx, SSL_SESSION *c, int lock) {
|
||||
}
|
||||
|
||||
if (ret) {
|
||||
r->not_resumable = 1;
|
||||
found_session->not_resumable = 1;
|
||||
if (ctx->remove_session_cb != NULL) {
|
||||
ctx->remove_session_cb(ctx, r);
|
||||
ctx->remove_session_cb(ctx, found_session);
|
||||
}
|
||||
SSL_SESSION_free(r);
|
||||
SSL_SESSION_free(found_session);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SSL_set_session(SSL *s, SSL_SESSION *session) {
|
||||
if (s->session == session) {
|
||||
int SSL_set_session(SSL *ssl, SSL_SESSION *session) {
|
||||
if (ssl->session == session) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
SSL_SESSION_free(s->session);
|
||||
s->session = session;
|
||||
SSL_SESSION_free(ssl->session);
|
||||
ssl->session = session;
|
||||
if (session != NULL) {
|
||||
SSL_SESSION_up_ref(session);
|
||||
s->verify_result = session->verify_result;
|
||||
ssl->verify_result = session->verify_result;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
long SSL_CTX_set_timeout(SSL_CTX *s, long t) {
|
||||
long l;
|
||||
if (s == NULL) {
|
||||
long SSL_CTX_set_timeout(SSL_CTX *ctx, long timeout) {
|
||||
if (ctx == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
l = s->session_timeout;
|
||||
s->session_timeout = t;
|
||||
return l;
|
||||
long old_timeout = ctx->session_timeout;
|
||||
ctx->session_timeout = timeout;
|
||||
return old_timeout;
|
||||
}
|
||||
|
||||
long SSL_CTX_get_timeout(const SSL_CTX *s) {
|
||||
if (s == NULL) {
|
||||
long SSL_CTX_get_timeout(const SSL_CTX *ctx) {
|
||||
if (ctx == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return s->session_timeout;
|
||||
return ctx->session_timeout;
|
||||
}
|
||||
|
||||
typedef struct timeout_param_st {
|
||||
@ -701,25 +700,25 @@ typedef struct timeout_param_st {
|
||||
LHASH_OF(SSL_SESSION) *cache;
|
||||
} TIMEOUT_PARAM;
|
||||
|
||||
static void timeout_doall_arg(SSL_SESSION *sess, void *void_param) {
|
||||
static void timeout_doall_arg(SSL_SESSION *session, void *void_param) {
|
||||
TIMEOUT_PARAM *param = void_param;
|
||||
|
||||
if (param->time == 0 ||
|
||||
param->time > (sess->time + sess->timeout)) {
|
||||
param->time > (session->time + session->timeout)) {
|
||||
/* timeout */
|
||||
/* The reason we don't call SSL_CTX_remove_session() is to
|
||||
* save on locking overhead */
|
||||
(void) lh_SSL_SESSION_delete(param->cache, sess);
|
||||
SSL_SESSION_list_remove(param->ctx, sess);
|
||||
sess->not_resumable = 1;
|
||||
(void) lh_SSL_SESSION_delete(param->cache, session);
|
||||
SSL_SESSION_list_remove(param->ctx, session);
|
||||
session->not_resumable = 1;
|
||||
if (param->ctx->remove_session_cb != NULL) {
|
||||
param->ctx->remove_session_cb(param->ctx, sess);
|
||||
param->ctx->remove_session_cb(param->ctx, session);
|
||||
}
|
||||
SSL_SESSION_free(sess);
|
||||
SSL_SESSION_free(session);
|
||||
}
|
||||
}
|
||||
|
||||
void SSL_CTX_flush_sessions(SSL_CTX *ctx, long t) {
|
||||
void SSL_CTX_flush_sessions(SSL_CTX *ctx, long time) {
|
||||
TIMEOUT_PARAM tp;
|
||||
|
||||
tp.ctx = ctx;
|
||||
@ -727,7 +726,7 @@ void SSL_CTX_flush_sessions(SSL_CTX *ctx, long t) {
|
||||
if (tp.cache == NULL) {
|
||||
return;
|
||||
}
|
||||
tp.time = t;
|
||||
tp.time = time;
|
||||
CRYPTO_MUTEX_lock_write(&ctx->lock);
|
||||
lh_SSL_SESSION_doall_arg(tp.cache, timeout_doall_arg, &tp);
|
||||
CRYPTO_MUTEX_unlock(&ctx->lock);
|
||||
@ -744,80 +743,80 @@ int ssl_clear_bad_session(SSL *s) {
|
||||
}
|
||||
|
||||
/* locked by SSL_CTX in the calling function */
|
||||
static void SSL_SESSION_list_remove(SSL_CTX *ctx, SSL_SESSION *s) {
|
||||
if (s->next == NULL || s->prev == NULL) {
|
||||
static void SSL_SESSION_list_remove(SSL_CTX *ctx, SSL_SESSION *session) {
|
||||
if (session->next == NULL || session->prev == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (s->next == (SSL_SESSION *)&ctx->session_cache_tail) {
|
||||
if (session->next == (SSL_SESSION *)&ctx->session_cache_tail) {
|
||||
/* last element in list */
|
||||
if (s->prev == (SSL_SESSION *)&ctx->session_cache_head) {
|
||||
if (session->prev == (SSL_SESSION *)&ctx->session_cache_head) {
|
||||
/* only one element in list */
|
||||
ctx->session_cache_head = NULL;
|
||||
ctx->session_cache_tail = NULL;
|
||||
} else {
|
||||
ctx->session_cache_tail = s->prev;
|
||||
s->prev->next = (SSL_SESSION *)&(ctx->session_cache_tail);
|
||||
ctx->session_cache_tail = session->prev;
|
||||
session->prev->next = (SSL_SESSION *)&(ctx->session_cache_tail);
|
||||
}
|
||||
} else {
|
||||
if (s->prev == (SSL_SESSION *)&ctx->session_cache_head) {
|
||||
if (session->prev == (SSL_SESSION *)&ctx->session_cache_head) {
|
||||
/* first element in list */
|
||||
ctx->session_cache_head = s->next;
|
||||
s->next->prev = (SSL_SESSION *)&(ctx->session_cache_head);
|
||||
ctx->session_cache_head = session->next;
|
||||
session->next->prev = (SSL_SESSION *)&(ctx->session_cache_head);
|
||||
} else { /* middle of list */
|
||||
s->next->prev = s->prev;
|
||||
s->prev->next = s->next;
|
||||
session->next->prev = session->prev;
|
||||
session->prev->next = session->next;
|
||||
}
|
||||
}
|
||||
s->prev = s->next = NULL;
|
||||
session->prev = session->next = NULL;
|
||||
}
|
||||
|
||||
static void SSL_SESSION_list_add(SSL_CTX *ctx, SSL_SESSION *s) {
|
||||
if (s->next != NULL && s->prev != NULL) {
|
||||
SSL_SESSION_list_remove(ctx, s);
|
||||
static void SSL_SESSION_list_add(SSL_CTX *ctx, SSL_SESSION *session) {
|
||||
if (session->next != NULL && session->prev != NULL) {
|
||||
SSL_SESSION_list_remove(ctx, session);
|
||||
}
|
||||
|
||||
if (ctx->session_cache_head == NULL) {
|
||||
ctx->session_cache_head = s;
|
||||
ctx->session_cache_tail = s;
|
||||
s->prev = (SSL_SESSION *)&(ctx->session_cache_head);
|
||||
s->next = (SSL_SESSION *)&(ctx->session_cache_tail);
|
||||
ctx->session_cache_head = session;
|
||||
ctx->session_cache_tail = session;
|
||||
session->prev = (SSL_SESSION *)&(ctx->session_cache_head);
|
||||
session->next = (SSL_SESSION *)&(ctx->session_cache_tail);
|
||||
} else {
|
||||
s->next = ctx->session_cache_head;
|
||||
s->next->prev = s;
|
||||
s->prev = (SSL_SESSION *)&(ctx->session_cache_head);
|
||||
ctx->session_cache_head = s;
|
||||
session->next = ctx->session_cache_head;
|
||||
session->next->prev = session;
|
||||
session->prev = (SSL_SESSION *)&(ctx->session_cache_head);
|
||||
ctx->session_cache_head = session;
|
||||
}
|
||||
}
|
||||
|
||||
void SSL_CTX_sess_set_new_cb(SSL_CTX *ctx,
|
||||
int (*cb)(struct ssl_st *ssl, SSL_SESSION *sess)) {
|
||||
int (*cb)(SSL *ssl, SSL_SESSION *session)) {
|
||||
ctx->new_session_cb = cb;
|
||||
}
|
||||
|
||||
int (*SSL_CTX_sess_get_new_cb(SSL_CTX *ctx))(SSL *ssl, SSL_SESSION *sess) {
|
||||
int (*SSL_CTX_sess_get_new_cb(SSL_CTX *ctx))(SSL *ssl, SSL_SESSION *session) {
|
||||
return ctx->new_session_cb;
|
||||
}
|
||||
|
||||
void SSL_CTX_sess_set_remove_cb(SSL_CTX *ctx,
|
||||
void (*cb)(SSL_CTX *ctx, SSL_SESSION *sess)) {
|
||||
void SSL_CTX_sess_set_remove_cb(
|
||||
SSL_CTX *ctx, void (*cb)(SSL_CTX *ctx, SSL_SESSION *session)) {
|
||||
ctx->remove_session_cb = cb;
|
||||
}
|
||||
|
||||
void (*SSL_CTX_sess_get_remove_cb(SSL_CTX *ctx))(SSL_CTX *ctx,
|
||||
SSL_SESSION *sess) {
|
||||
SSL_SESSION *session) {
|
||||
return ctx->remove_session_cb;
|
||||
}
|
||||
|
||||
void SSL_CTX_sess_set_get_cb(SSL_CTX *ctx,
|
||||
SSL_SESSION *(*cb)(struct ssl_st *ssl,
|
||||
uint8_t *data, int len,
|
||||
int *copy)) {
|
||||
SSL_SESSION *(*cb)(SSL *ssl,
|
||||
uint8_t *id, int id_len,
|
||||
int *out_copy)) {
|
||||
ctx->get_session_cb = cb;
|
||||
}
|
||||
|
||||
SSL_SESSION *(*SSL_CTX_sess_get_get_cb(SSL_CTX *ctx))(SSL *ssl, uint8_t *data,
|
||||
int len, int *copy) {
|
||||
SSL_SESSION *(*SSL_CTX_sess_get_get_cb(SSL_CTX *ctx))(
|
||||
SSL *ssl, uint8_t *id, int id_len, int *out_copy) {
|
||||
return ctx->get_session_cb;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user