Hi all,
I use openssl library in a daemon (as ssl client), and there are a lot
of crashes around ssl session management. A crash happens when ssl
sessions are flushed via SSL_CTX_flush_sessions(), because they
could have bad session id.
> openssl version on FreeBSD
OpenSSL 1.0.1m 19 Mar 2015
The client cache is enable with:
SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_CLIENT)
Moreover, I also use:
SSL_CTX_sess_set_new_cb(ctx, new_ssl_session_cb);
SSL_CTX_sess_set_remove_cb(ctx, remove_ssl_session_cb);
So, when server requests new session ticket (SSL3_ST_CR_SESSION_TICKET_[AB]),
the session can have more references than once. But in function
ssl3_get_new_session_ticket(), session_id is changed without checks on
session->references. If session_id is changed then cache access is wrong!
To solve this problem, I used a new ssl session, created with i2d/d2i (and
release one reference from old ssl session).
What do you think?
Olivier
--
Olivier Szika
R&D System Engineer
Stormshield - Stormshield Network Security
--- crypto/openssl/ssl/s3_clnt.c.orig 2015-04-16 11:24:32.860740414 +0200
+++ crypto/openssl/ssl/s3_clnt.c 2015-04-17 09:49:38.646822826 +0200
@@ -2115,6 +2115,59 @@
* elsewhere in OpenSSL. The session ID is set to the SHA256 (or SHA1 is
* SHA256 is disabled) hash of the ticket.
*/
+
+ /*
+ * If references > 1, ssl session id must not be changed, mainly with cache sessions.
+ * To solve this problem, a new ssl session is created from original.
+ */
+ if (s->session->references > 1)
+ {
+ int len;
+ unsigned char *buffer, *p;
+ const unsigned char *cp;
+ SSL_SESSION *sess;
+
+ /* Create new ssl session from current */
+ len = i2d_SSL_SESSION(s->session, NULL);
+ if (len > 0xFF00)
+ {
+ SSLerr(SSL_F_SSL3_GET_NEW_SESSION_TICKET, SSL_R_BAD_LENGTH);
+ goto err;
+ }
+
+ buffer = OPENSSL_malloc(len);
+ if (buffer == NULL)
+ {
+ SSLerr(SSL_F_SSL3_GET_NEW_SESSION_TICKET, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ p = buffer;
+ cp = buffer;
+
+ if (!i2d_SSL_SESSION(s->session, &p))
+ {
+ OPENSSL_free(buffer);
+ SSLerr(SSL_F_SSL3_GET_NEW_SESSION_TICKET, SSL_F_I2D_SSL_SESSION);
+ goto err;
+ }
+
+ sess = d2i_SSL_SESSION(NULL, &cp, len);
+ if (sess == NULL)
+ {
+ OPENSSL_free(buffer);
+ SSLerr(SSL_F_SSL3_GET_NEW_SESSION_TICKET, SSL_F_D2I_SSL_SESSION);
+ goto err;
+ }
+
+ /* Release 1 reference for current session */
+ SSL_SESSION_free(s->session);
+
+ /* use new session */
+ s->session = sess;
+
+ OPENSSL_free(buffer);
+ }
+
EVP_Digest(p, ticklen,
s->session->session_id, &s->session->session_id_length,
# ifndef OPENSSL_NO_SHA256
_______________________________________________
openssl-dev mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-dev