From dafbdd49c70184cda18e0c4d87f4b0bd58c94855 Mon Sep 17 00:00:00 2001 From: David Benjamin Date: Mon, 14 Sep 2015 01:40:10 -0400 Subject: [PATCH] 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 --- include/openssl/ssl.h | 354 ++++++++++++++++++++++++++++++------------ ssl/ssl_lib.c | 8 +- ssl/ssl_session.c | 195 ++++++++++++----------- 3 files changed, 357 insertions(+), 200 deletions(-) diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h index da394b82..cf2cf549 100644 --- a/include/openssl/ssl.h +++ b/include/openssl/ssl.h @@ -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); diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c index a70d55a4..a1f72436 100644 --- a/ssl/ssl_lib.c +++ b/ssl/ssl_lib.c @@ -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 diff --git a/ssl/ssl_session.c b/ssl/ssl_session.c index f4d8b34a..96daec0a 100644 --- a/ssl/ssl_session.c +++ b/ssl/ssl_session.c @@ -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; }