Hello OpenSSL team! There is a bug in the session resume (server side, when SSL_OP_NO_TICKET option specified) code.
This is hash function for session id: static unsigned long ssl_session_hash(const SSL_SESSION *a) { unsigned long l; l=(unsigned long) ((unsigned int) a->session_id[0] )| ((unsigned int) a->session_id[1]<< 8L)| ((unsigned long)a->session_id[2]<<16L)| ((unsigned long)a->session_id[3]<<24L); return(l); } But in session finding function int ssl_get_prev_session(SSL *s, unsigned char *session_id, int len, const unsigned char *limit) we have session_id copying. SSL_SESSION data; data.ssl_version=s->version; data.session_id_length=len; if (len == 0) return 0; memcpy(data.session_id,session_id,len); <--- *problem is here* CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX); ret=lh_SSL_SESSION_retrieve(s->session_ctx->sessions,&data); So, for session_id length == 3 (so, any length below 4) ("The length of the session id is 16 bytes for SSLv2 sessions and between 1 and 32 bytes for SSLv3/TLSv1.", http://www.openssl.org/docs/ssl/SSL_CTX_set_generate_session_id.html) we will have *garbage *in the "a->session_id[3]" in ssl_session_hash function. *Solution*: add memset(data.session_id,0,SSL_MAX_SSL_SESSION_ID_LENGTH); // is needed when we have session_id < 4 bytes (Hash sum is calculated from the first 4 bytes!) before memcpy(data.session_id,session_id,len); <--- problem code code line. I have found this bug in 0.9.8m version, but code analyzing show this problem in the "openssl-1.0.1c" version too.
Hello OpenSSL team!
This is hash function for session id:
static unsigned long ssl_session_hash(const SSL_SESSION *a)
{
unsigned long l;
l=(unsigned long)
((unsigned int) a->session_id[0] ? ? )|
((unsigned int) a->session_id[1]<< 8L)|
((unsigned long)a->session_id[2]<<16L)|
((unsigned long)a->session_id[3]<<24L);
return(l);
}
But in session finding function?
int ssl_get_prev_session(SSL *s, unsigned char *session_id, int len,?const unsigned char *limit)
we have session_id copying.
SSL_SESSION data;
data.ssl_version=s->version;
data.session_id_length=len;
if (len == 0)
return 0;
memcpy(data.session_id,session_id,len); ? ?<--- problem is here
CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX);
ret=lh_SSL_SESSION_retrieve(s->session_ctx->sessions,&data);
So, for session_id length == 3 (so, any length below 4)
("The length of the session id is 16 bytes for SSLv2 sessions and between 1 and 32 bytes for SSLv3/TLSv1.",?http://www.openssl.org/docs/ssl/SSL_CTX_set_generate_session_id.html)
we will have garbage in the "a->session_id[3]" in?
ssl_session_hash
function.
Solution: add?
? memset(data.session_id,0,SSL_MAX_SSL_SESSION_ID_LENGTH); // is needed when we have session_id < 4 bytes (Hash sum is calculated from the first 4 bytes!)
before?
memcpy(data.session_id,session_id,len); ? ?<--- problem code
code line.
I have found this bug in 0.9.8m version, but code analyzing show this problem in the "openssl-1.0.1c" ?version too.