Adding code to send session as PSK Identity.
BUG=75
Change-Id: Ied864cfccbc0e68d71c55c5ab563da27b7253463
Reviewed-on: https://boringssl-review.googlesource.com/9043
Reviewed-by: David Benjamin <davidben@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
diff --git a/ssl/ssl_session.c b/ssl/ssl_session.c
index 1d634d8..e26866b 100644
--- a/ssl/ssl_session.c
+++ b/ssl/ssl_session.c
@@ -175,22 +175,23 @@
return session;
}
-SSL_SESSION *SSL_SESSION_dup(SSL_SESSION *session, int include_ticket) {
+SSL_SESSION *SSL_SESSION_dup(SSL_SESSION *session, int dup_flags) {
SSL_SESSION *new_session = SSL_SESSION_new();
if (new_session == NULL) {
goto err;
}
new_session->ssl_version = session->ssl_version;
- new_session->key_exchange_info = session->key_exchange_info;
+ new_session->sid_ctx_length = session->sid_ctx_length;
+ memcpy(new_session->sid_ctx, session->sid_ctx, session->sid_ctx_length);
+
+ /* Copy the key material. */
new_session->master_key_length = session->master_key_length;
memcpy(new_session->master_key, session->master_key,
session->master_key_length);
- new_session->session_id_length = session->session_id_length;
- memcpy(new_session->session_id, session->session_id,
- session->session_id_length);
- new_session->sid_ctx_length = session->sid_ctx_length;
- memcpy(new_session->sid_ctx, session->sid_ctx, session->sid_ctx_length);
+ new_session->cipher = session->cipher;
+
+ /* Copy authentication state. */
if (session->psk_identity != NULL) {
new_session->psk_identity = BUF_strdup(session->psk_identity);
if (new_session->psk_identity == NULL) {
@@ -208,26 +209,15 @@
}
}
new_session->verify_result = session->verify_result;
- new_session->timeout = session->timeout;
- new_session->time = session->time;
- new_session->cipher = session->cipher;
- /* The new_session does not get a copy of the ex_data. */
- if (session->tlsext_hostname != NULL) {
- new_session->tlsext_hostname = BUF_strdup(session->tlsext_hostname);
- if (new_session->tlsext_hostname == NULL) {
+
+ new_session->ocsp_response_length = session->ocsp_response_length;
+ if (session->ocsp_response != NULL) {
+ new_session->ocsp_response = BUF_memdup(session->ocsp_response,
+ session->ocsp_response_length);
+ if (new_session->ocsp_response == NULL) {
goto err;
}
}
- if (include_ticket) {
- if (session->tlsext_tick != NULL) {
- new_session->tlsext_tick =
- BUF_memdup(session->tlsext_tick, session->tlsext_ticklen);
- if (new_session->tlsext_tick == NULL) {
- goto err;
- }
- }
- new_session->tlsext_ticklen = session->tlsext_ticklen;
- }
new_session->tlsext_signed_cert_timestamp_list_length =
session->tlsext_signed_cert_timestamp_list_length;
@@ -239,25 +229,52 @@
goto err;
}
}
- new_session->ocsp_response_length = session->ocsp_response_length;
- if (session->ocsp_response != NULL) {
- new_session->ocsp_response = BUF_memdup(session->ocsp_response,
- session->ocsp_response_length);
- if (new_session->ocsp_response == NULL) {
- goto err;
- }
- }
+
memcpy(new_session->peer_sha256, session->peer_sha256, SHA256_DIGEST_LENGTH);
- memcpy(new_session->original_handshake_hash,
- session->original_handshake_hash,
- session->original_handshake_hash_len);
- new_session->original_handshake_hash_len =
- session->original_handshake_hash_len;
- new_session->tlsext_tick_lifetime_hint = session->tlsext_tick_lifetime_hint;
- new_session->ticket_flags = session->ticket_flags;
- new_session->ticket_age_add = session->ticket_age_add;
- new_session->extended_master_secret = session->extended_master_secret;
new_session->peer_sha256_valid = session->peer_sha256_valid;
+
+ /* Copy non-authentication connection properties. */
+ if (dup_flags & SSL_SESSION_INCLUDE_NONAUTH) {
+ new_session->session_id_length = session->session_id_length;
+ memcpy(new_session->session_id, session->session_id,
+ session->session_id_length);
+
+ new_session->key_exchange_info = session->key_exchange_info;
+ new_session->timeout = session->timeout;
+ new_session->time = session->time;
+
+ if (session->tlsext_hostname != NULL) {
+ new_session->tlsext_hostname = BUF_strdup(session->tlsext_hostname);
+ if (new_session->tlsext_hostname == NULL) {
+ goto err;
+ }
+ }
+
+ memcpy(new_session->original_handshake_hash,
+ session->original_handshake_hash,
+ session->original_handshake_hash_len);
+ new_session->original_handshake_hash_len =
+ session->original_handshake_hash_len;
+ new_session->tlsext_tick_lifetime_hint = session->tlsext_tick_lifetime_hint;
+ new_session->ticket_flags = session->ticket_flags;
+ new_session->ticket_age_add = session->ticket_age_add;
+ new_session->extended_master_secret = session->extended_master_secret;
+ }
+
+ /* Copy the ticket. */
+ if (dup_flags & SSL_SESSION_INCLUDE_TICKET) {
+ if (session->tlsext_tick != NULL) {
+ new_session->tlsext_tick =
+ BUF_memdup(session->tlsext_tick, session->tlsext_ticklen);
+ if (new_session->tlsext_tick == NULL) {
+ goto err;
+ }
+ }
+ new_session->tlsext_ticklen = session->tlsext_ticklen;
+ }
+
+ /* The new_session does not get a copy of the ex_data. */
+
new_session->not_resumable = 1;
return new_session;
@@ -564,6 +581,25 @@
return ret;
}
+int ssl_session_is_context_valid(const SSL *ssl, const SSL_SESSION *session) {
+ if (session == NULL) {
+ return 0;
+ }
+
+ return session->sid_ctx_length == ssl->sid_ctx_length &&
+ memcmp(session->sid_ctx, ssl->sid_ctx, ssl->sid_ctx_length) == 0;
+}
+
+int ssl_session_is_time_valid(const SSL *ssl, const SSL_SESSION *session) {
+ if (session == NULL) {
+ return 0;
+ }
+
+ struct timeval now;
+ ssl_get_current_time(ssl, &now);
+ return session->timeout >= (long)now.tv_sec - session->time;
+}
+
/* ssl_lookup_session looks up |session_id| in the session cache and sets
* |*out_session| to an |SSL_SESSION| object if found. The caller takes
* ownership of the result. */
@@ -576,7 +612,7 @@
return ssl_session_success;
}
- SSL_SESSION *session;
+ SSL_SESSION *session = NULL;
/* Try the internal cache, if it exists. */
if (!(ssl->initial_ctx->session_cache_mode &
SSL_SESS_CACHE_NO_INTERNAL_LOOKUP)) {
@@ -592,39 +628,48 @@
}
/* TODO(davidben): This should probably move it to the front of the list. */
CRYPTO_MUTEX_unlock_read(&ssl->initial_ctx->lock);
-
- if (session != NULL) {
- *out_session = session;
- return ssl_session_success;
- }
}
/* Fall back to the external cache, if it exists. */
- if (ssl->initial_ctx->get_session_cb == NULL) {
- return ssl_session_success;
+ if (session == NULL &&
+ ssl->initial_ctx->get_session_cb != NULL) {
+ int copy = 1;
+ session = ssl->initial_ctx->get_session_cb(ssl, (uint8_t *)session_id,
+ session_id_len, ©);
+
+ if (session == SSL_magic_pending_session_ptr()) {
+ return ssl_session_retry;
+ }
+
+ /* 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(session);
+ }
+
+ /* Add the externally cached session to the internal cache if necessary. */
+ if (session != NULL &&
+ !(ssl->initial_ctx->session_cache_mode &
+ SSL_SESS_CACHE_NO_INTERNAL_STORE)) {
+ SSL_CTX_add_session(ssl->initial_ctx, session);
+ }
}
- int copy = 1;
- session = ssl->initial_ctx->get_session_cb(ssl, (uint8_t *)session_id,
- session_id_len, ©);
+
if (session == NULL) {
return ssl_session_success;
}
- if (session == SSL_magic_pending_session_ptr()) {
- return ssl_session_retry;
- }
- /* 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(session);
- }
-
- /* Add the externally cached session to the internal cache if necessary. */
- if (!(ssl->initial_ctx->session_cache_mode &
- SSL_SESS_CACHE_NO_INTERNAL_STORE)) {
- SSL_CTX_add_session(ssl->initial_ctx, session);
+ if (!ssl_session_is_context_valid(ssl, session)) {
+ /* The client did not offer a suitable ticket or session ID. */
+ SSL_SESSION_free(session);
+ session = NULL;
+ } else if (!ssl_session_is_time_valid(ssl, session)) {
+ /* The session was from the cache, so remove it. */
+ SSL_CTX_remove_session(ssl->initial_ctx, session);
+ SSL_SESSION_free(session);
+ session = NULL;
}
*out_session = session;
@@ -647,7 +692,6 @@
ssl->version > SSL3_VERSION &&
SSL_early_callback_ctx_extension_get(ctx, TLSEXT_TYPE_session_ticket,
&ticket, &ticket_len);
- int from_cache = 0;
if (tickets_supported && ticket_len > 0) {
if (!tls_process_ticket(ssl, &session, &renew_ticket, ticket, ticket_len,
ctx->session_id, ctx->session_id_len)) {
@@ -660,35 +704,14 @@
if (lookup_ret != ssl_session_success) {
return lookup_ret;
}
- from_cache = 1;
- }
-
- if (session == NULL ||
- session->sid_ctx_length != ssl->sid_ctx_length ||
- memcmp(session->sid_ctx, ssl->sid_ctx, ssl->sid_ctx_length) != 0) {
- /* The client did not offer a suitable ticket or session ID. If supported,
- * the new session should use a ticket. */
- goto no_session;
- }
-
- struct timeval now;
- ssl_get_current_time(ssl, &now);
- if (session->timeout < (long)now.tv_sec - session->time) {
- if (from_cache) {
- /* The session was from the cache, so remove it. */
- SSL_CTX_remove_session(ssl->initial_ctx, session);
- }
- goto no_session;
}
*out_session = session;
- *out_send_ticket = renew_ticket;
- return ssl_session_success;
-
-no_session:
- *out_session = NULL;
- *out_send_ticket = tickets_supported;
- SSL_SESSION_free(session);
+ if (session != NULL) {
+ *out_send_ticket = renew_ticket;
+ } else {
+ *out_send_ticket = tickets_supported;
+ }
return ssl_session_success;
}