openssl-0.9.9-session-ticket.patch revision 285830
11573SrgrimesThis patch adds support for TLS SessionTicket extension (RFC 5077) for 21573Srgrimesthe parts used by EAP-FAST (RFC 4851). 31573Srgrimes 41573SrgrimesThis is based on the patch from Alexey Kobozev <akobozev@cisco.com> 51573Srgrimes(sent to openssl-dev mailing list on Tue, 07 Jun 2005 15:40:58 +0300). 61573Srgrimes 71573SrgrimesNOTE: This patch (without SSL_set_hello_extension() wrapper) was 81573Srgrimesmerged into the upstream OpenSSL 0.9.9 tree and as such, an external 91573Srgrimespatch for EAP-FAST support is not needed anymore. 101573Srgrimes 111573Srgrimes 121573Srgrimes 131573SrgrimesIndex: openssl-SNAP-20081111/ssl/s3_clnt.c 141573Srgrimes=================================================================== 151573Srgrimes--- openssl-SNAP-20081111.orig/ssl/s3_clnt.c 161573Srgrimes+++ openssl-SNAP-20081111/ssl/s3_clnt.c 171573Srgrimes@@ -788,6 +788,23 @@ int ssl3_get_server_hello(SSL *s) 181573Srgrimes goto f_err; 191573Srgrimes } 201573Srgrimes 211573Srgrimes+#ifndef OPENSSL_NO_TLSEXT 221573Srgrimes+ /* check if we want to resume the session based on external pre-shared secret */ 231573Srgrimes+ if (s->version >= TLS1_VERSION && s->tls_session_secret_cb) 241573Srgrimes+ { 251573Srgrimes+ SSL_CIPHER *pref_cipher=NULL; 261573Srgrimes+ s->session->master_key_length=sizeof(s->session->master_key); 271573Srgrimes+ if (s->tls_session_secret_cb(s, s->session->master_key, 281573Srgrimes+ &s->session->master_key_length, 291573Srgrimes+ NULL, &pref_cipher, 301573Srgrimes+ s->tls_session_secret_cb_arg)) 311573Srgrimes+ { 321573Srgrimes+ s->session->cipher = pref_cipher ? 3350476Speter+ pref_cipher : ssl_get_cipher_by_char(s, p+j); 341573Srgrimes+ } 35187817Strhodes+ } 361573Srgrimes+#endif /* OPENSSL_NO_TLSEXT */ 371573Srgrimes+ 381573Srgrimes if (j != 0 && j == s->session->session_id_length 391573Srgrimes && memcmp(p,s->session->session_id,j) == 0) 40109050Stjr { 411573Srgrimes@@ -2927,11 +2944,8 @@ static int ssl3_check_finished(SSL *s) 42109050Stjr { 431573Srgrimes int ok; 44109050Stjr long n; 45109050Stjr- /* If we have no ticket or session ID is non-zero length (a match of 46109050Stjr- * a non-zero session length would never reach here) it cannot be a 471573Srgrimes- * resumed session. 4859460Sphantom- */ 4959460Sphantom- if (!s->session->tlsext_tick || s->session->session_id_length) 501573Srgrimes+ /* If we have no ticket it cannot be a resumed session. */ 5184306Sru+ if (!s->session->tlsext_tick) 521573Srgrimes return 1; 531573Srgrimes /* this function is called when we really expect a Certificate 54109050Stjr * message, so permit appropriate message length */ 55109050StjrIndex: openssl-SNAP-20081111/ssl/s3_srvr.c 561573Srgrimes=================================================================== 571573Srgrimes--- openssl-SNAP-20081111.orig/ssl/s3_srvr.c 581573Srgrimes+++ openssl-SNAP-20081111/ssl/s3_srvr.c 59109050Stjr@@ -1010,6 +1010,59 @@ int ssl3_get_client_hello(SSL *s) 60109050Stjr SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_CLIENTHELLO_TLSEXT); 611573Srgrimes goto err; 621573Srgrimes } 63109050Stjr+ 64109050Stjr+ /* Check if we want to use external pre-shared secret for this 651573Srgrimes+ * handshake for not reused session only. We need to generate 66109050Stjr+ * server_random before calling tls_session_secret_cb in order to allow 67109050Stjr+ * SessionTicket processing to use it in key derivation. */ 681573Srgrimes+ { 691573Srgrimes+ unsigned long Time; 701573Srgrimes+ unsigned char *pos; 711573Srgrimes+ Time=(unsigned long)time(NULL); /* Time */ 721573Srgrimes+ pos=s->s3->server_random; 731573Srgrimes+ l2n(Time,pos); 741573Srgrimes+ if (RAND_pseudo_bytes(pos,SSL3_RANDOM_SIZE-4) <= 0) 751573Srgrimes+ { 761573Srgrimes+ al=SSL_AD_INTERNAL_ERROR; 771573Srgrimes+ goto f_err; 781573Srgrimes+ } 791573Srgrimes+ } 80187823Strhodes+ 81187823Strhodes+ if (!s->hit && s->version >= TLS1_VERSION && s->tls_session_secret_cb) 82187823Strhodes+ { 83187823Strhodes+ SSL_CIPHER *pref_cipher=NULL; 841573Srgrimes+ 851573Srgrimes+ s->session->master_key_length=sizeof(s->session->master_key); 861573Srgrimes+ if(s->tls_session_secret_cb(s, s->session->master_key, &s->session->master_key_length, 871573Srgrimes+ ciphers, &pref_cipher, s->tls_session_secret_cb_arg)) 881573Srgrimes+ { 891573Srgrimes+ s->hit=1; 901573Srgrimes+ s->session->ciphers=ciphers; 911573Srgrimes+ s->session->verify_result=X509_V_OK; 921573Srgrimes+ 931573Srgrimes+ ciphers=NULL; 941573Srgrimes+ 951573Srgrimes+ /* check if some cipher was preferred by call back */ 96109050Stjr+ pref_cipher=pref_cipher ? pref_cipher : ssl3_choose_cipher(s, s->session->ciphers, SSL_get_ciphers(s)); 97109050Stjr+ if (pref_cipher == NULL) 98109050Stjr+ { 99109050Stjr+ al=SSL_AD_HANDSHAKE_FAILURE; 100109050Stjr+ SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_NO_SHARED_CIPHER); 101109050Stjr+ goto f_err; 102109050Stjr+ } 103109050Stjr+ 104109050Stjr+ s->session->cipher=pref_cipher; 105109050Stjr+ 106109050Stjr+ if (s->cipher_list) 107109050Stjr+ sk_SSL_CIPHER_free(s->cipher_list); 108109050Stjr+ 109109050Stjr+ if (s->cipher_list_by_id) 110109050Stjr+ sk_SSL_CIPHER_free(s->cipher_list_by_id); 111111285Sru+ 112109050Stjr+ s->cipher_list = sk_SSL_CIPHER_dup(s->session->ciphers); 113109050Stjr+ s->cipher_list_by_id = sk_SSL_CIPHER_dup(s->session->ciphers); 114109050Stjr+ } 1151573Srgrimes+ } 1161573Srgrimes #endif 1171573Srgrimes 1181573Srgrimes /* Worst case, we will use the NULL compression, but if we have other 1191573Srgrimes@@ -1134,16 +1187,22 @@ int ssl3_send_server_hello(SSL *s) 1201573Srgrimes unsigned char *buf; 12186352Smurray unsigned char *p,*d; 122109050Stjr int i,sl; 1231573Srgrimes- unsigned long l,Time; 1241573Srgrimes+ unsigned long l; 1251573Srgrimes+#ifdef OPENSSL_NO_TLSEXT 1261573Srgrimes+ unsigned long Time; 1271573Srgrimes+#endif 1281573Srgrimes 1291573Srgrimes if (s->state == SSL3_ST_SW_SRVR_HELLO_A) 1301573Srgrimes { 13173088Sru buf=(unsigned char *)s->init_buf->data; 132+#ifdef OPENSSL_NO_TLSEXT 133 p=s->s3->server_random; 134+ /* Generate server_random if it was not needed previously */ 135 Time=(unsigned long)time(NULL); /* Time */ 136 l2n(Time,p); 137 if (RAND_pseudo_bytes(p,SSL3_RANDOM_SIZE-4) <= 0) 138 return -1; 139+#endif 140 /* Do the message type and length last */ 141 d=p= &(buf[4]); 142 143Index: openssl-SNAP-20081111/ssl/ssl_err.c 144=================================================================== 145--- openssl-SNAP-20081111.orig/ssl/ssl_err.c 146+++ openssl-SNAP-20081111/ssl/ssl_err.c 147@@ -263,6 +263,7 @@ static ERR_STRING_DATA SSL_str_functs[]= 148 {ERR_FUNC(SSL_F_TLS1_PRF), "tls1_prf"}, 149 {ERR_FUNC(SSL_F_TLS1_SETUP_KEY_BLOCK), "TLS1_SETUP_KEY_BLOCK"}, 150 {ERR_FUNC(SSL_F_WRITE_PENDING), "WRITE_PENDING"}, 151+{ERR_FUNC(SSL_F_SSL_SET_SESSION_TICKET_EXT), "SSL_set_session_ticket_ext"}, 152 {0,NULL} 153 }; 154 155Index: openssl-SNAP-20081111/ssl/ssl.h 156=================================================================== 157--- openssl-SNAP-20081111.orig/ssl/ssl.h 158+++ openssl-SNAP-20081111/ssl/ssl.h 159@@ -355,6 +355,7 @@ extern "C" { 160 * 'struct ssl_st *' function parameters used to prototype callbacks 161 * in SSL_CTX. */ 162 typedef struct ssl_st *ssl_crock_st; 163+typedef struct tls_session_ticket_ext_st TLS_SESSION_TICKET_EXT; 164 165 /* used to hold info on the particular ciphers used */ 166 typedef struct ssl_cipher_st 167@@ -378,6 +379,8 @@ typedef struct ssl_cipher_st 168 169 DECLARE_STACK_OF(SSL_CIPHER) 170 171+typedef int (*tls_session_secret_cb_fn)(SSL *s, void *secret, int *secret_len, STACK_OF(SSL_CIPHER) *peer_ciphers, SSL_CIPHER **cipher, void *arg); 172+ 173 /* Used to hold functions for SSLv2 or SSLv3/TLSv1 functions */ 174 typedef struct ssl_method_st 175 { 176@@ -1145,6 +1148,13 @@ struct ssl_st 177 void *tlsext_opaque_prf_input; 178 size_t tlsext_opaque_prf_input_len; 179 180+ /* TLS Session Ticket extension override */ 181+ TLS_SESSION_TICKET_EXT *tlsext_session_ticket; 182+ 183+ /* TLS pre-shared secret session resumption */ 184+ tls_session_secret_cb_fn tls_session_secret_cb; 185+ void *tls_session_secret_cb_arg; 186+ 187 SSL_CTX * initial_ctx; /* initial ctx, used to store sessions */ 188 #define session_ctx initial_ctx 189 #else 190@@ -1746,6 +1756,16 @@ void *SSL_COMP_get_compression_methods(v 191 int SSL_COMP_add_compression_method(int id,void *cm); 192 #endif 193 194+/* NOTE: This function will be removed; it is only here for backwards 195+ * compatibility for the API during testing. */ 196+int SSL_set_hello_extension(SSL *s, int ext_type, void *ext_data, int ext_len); 197+ 198+/* TLS extensions functions */ 199+int SSL_set_session_ticket_ext(SSL *s, void *ext_data, int ext_len); 200+ 201+/* Pre-shared secret session resumption functions */ 202+int SSL_set_session_secret_cb(SSL *s, tls_session_secret_cb_fn tls_session_secret_cb, void *arg); 203+ 204 /* BEGIN ERROR CODES */ 205 /* The following lines are auto generated by the script mkerr.pl. Any changes 206 * made after this point may be overwritten when the script is next run. 207@@ -1948,6 +1968,7 @@ void ERR_load_SSL_strings(void); 208 #define SSL_F_TLS1_PRF 284 209 #define SSL_F_TLS1_SETUP_KEY_BLOCK 211 210 #define SSL_F_WRITE_PENDING 212 211+#define SSL_F_SSL_SET_SESSION_TICKET_EXT 213 212 213 /* Reason codes. */ 214 #define SSL_R_APP_DATA_IN_HANDSHAKE 100 215Index: openssl-SNAP-20081111/ssl/ssl_sess.c 216=================================================================== 217--- openssl-SNAP-20081111.orig/ssl/ssl_sess.c 218+++ openssl-SNAP-20081111/ssl/ssl_sess.c 219@@ -834,6 +834,62 @@ long SSL_CTX_get_timeout(const SSL_CTX * 220 return(s->session_timeout); 221 } 222 223+#ifndef OPENSSL_NO_TLSEXT 224+int SSL_set_session_secret_cb(SSL *s, int (*tls_session_secret_cb)(SSL *s, void *secret, int *secret_len, 225+ STACK_OF(SSL_CIPHER) *peer_ciphers, SSL_CIPHER **cipher, void *arg), void *arg) 226+ { 227+ if (s == NULL) return(0); 228+ s->tls_session_secret_cb = tls_session_secret_cb; 229+ s->tls_session_secret_cb_arg = arg; 230+ return(1); 231+ } 232+ 233+int SSL_set_session_ticket_ext(SSL *s, void *ext_data, int ext_len) 234+ { 235+ if (s->version >= TLS1_VERSION) 236+ { 237+ if (s->tlsext_session_ticket) 238+ { 239+ OPENSSL_free(s->tlsext_session_ticket); 240+ s->tlsext_session_ticket = NULL; 241+ } 242+ 243+ s->tlsext_session_ticket = OPENSSL_malloc(sizeof(TLS_SESSION_TICKET_EXT) + ext_len); 244+ if (!s->tlsext_session_ticket) 245+ { 246+ SSLerr(SSL_F_SSL_SET_SESSION_TICKET_EXT, ERR_R_MALLOC_FAILURE); 247+ return 0; 248+ } 249+ 250+ if (ext_data) 251+ { 252+ s->tlsext_session_ticket->length = ext_len; 253+ s->tlsext_session_ticket->data = s->tlsext_session_ticket + 1; 254+ memcpy(s->tlsext_session_ticket->data, ext_data, ext_len); 255+ } 256+ else 257+ { 258+ s->tlsext_session_ticket->length = 0; 259+ s->tlsext_session_ticket->data = NULL; 260+ } 261+ 262+ return 1; 263+ } 264+ 265+ return 0; 266+ } 267+ 268+/* NOTE: This function will be removed; it is only here for backwards 269+ * compatibility for the API during testing. */ 270+int SSL_set_hello_extension(SSL *s, int ext_type, void *ext_data, int ext_len) 271+ { 272+ if (ext_type != TLSEXT_TYPE_session_ticket) 273+ return 0; 274+ 275+ return SSL_set_session_ticket_ext(s, ext_data, ext_len); 276+ } 277+#endif /* OPENSSL_NO_TLSEXT */ 278+ 279 typedef struct timeout_param_st 280 { 281 SSL_CTX *ctx; 282Index: openssl-SNAP-20081111/ssl/t1_lib.c 283=================================================================== 284--- openssl-SNAP-20081111.orig/ssl/t1_lib.c 285+++ openssl-SNAP-20081111/ssl/t1_lib.c 286@@ -154,6 +154,12 @@ int tls1_new(SSL *s) 287 288 void tls1_free(SSL *s) 289 { 290+#ifndef OPENSSL_NO_TLSEXT 291+ if (s->tlsext_session_ticket) 292+ { 293+ OPENSSL_free(s->tlsext_session_ticket); 294+ } 295+#endif /* OPENSSL_NO_TLSEXT */ 296 ssl3_free(s); 297 } 298 299@@ -357,8 +363,23 @@ unsigned char *ssl_add_clienthello_tlsex 300 int ticklen; 301 if (s->session && s->session->tlsext_tick) 302 ticklen = s->session->tlsext_ticklen; 303+ else if (s->session && s->tlsext_session_ticket && 304+ s->tlsext_session_ticket->data) 305+ { 306+ ticklen = s->tlsext_session_ticket->length; 307+ s->session->tlsext_tick = OPENSSL_malloc(ticklen); 308+ if (!s->session->tlsext_tick) 309+ return NULL; 310+ memcpy(s->session->tlsext_tick, 311+ s->tlsext_session_ticket->data, 312+ ticklen); 313+ s->session->tlsext_ticklen = ticklen; 314+ } 315 else 316 ticklen = 0; 317+ if (ticklen == 0 && s->tlsext_session_ticket && 318+ s->tlsext_session_ticket->data == NULL) 319+ goto skip_ext; 320 /* Check for enough room 2 for extension type, 2 for len 321 * rest for ticket 322 */ 323@@ -371,6 +392,7 @@ unsigned char *ssl_add_clienthello_tlsex 324 ret += ticklen; 325 } 326 } 327+ skip_ext: 328 329 #ifdef TLSEXT_TYPE_opaque_prf_input 330 if (s->s3->client_opaque_prf_input != NULL) 331@@ -1435,6 +1457,15 @@ int tls1_process_ticket(SSL *s, unsigned 332 s->tlsext_ticket_expected = 1; 333 return 0; /* Cache miss */ 334 } 335+ if (s->tls_session_secret_cb) 336+ { 337+ /* Indicate cache miss here and instead of 338+ * generating the session from ticket now, 339+ * trigger abbreviated handshake based on 340+ * external mechanism to calculate the master 341+ * secret later. */ 342+ return 0; 343+ } 344 return tls_decrypt_ticket(s, p, size, session_id, len, 345 ret); 346 } 347Index: openssl-SNAP-20081111/ssl/tls1.h 348=================================================================== 349--- openssl-SNAP-20081111.orig/ssl/tls1.h 350+++ openssl-SNAP-20081111/ssl/tls1.h 351@@ -512,6 +512,13 @@ SSL_CTX_callback_ctrl(ssl,SSL_CTRL_SET_T 352 #define TLS_MD_MASTER_SECRET_CONST "\x6d\x61\x73\x74\x65\x72\x20\x73\x65\x63\x72\x65\x74" /*master secret*/ 353 #endif 354 355+/* TLS Session Ticket extension struct */ 356+struct tls_session_ticket_ext_st 357+ { 358+ unsigned short length; 359+ void *data; 360+ }; 361+ 362 #ifdef __cplusplus 363 } 364 #endif 365Index: openssl-SNAP-20081111/util/ssleay.num 366=================================================================== 367--- openssl-SNAP-20081111.orig/util/ssleay.num 368+++ openssl-SNAP-20081111/util/ssleay.num 369@@ -254,3 +254,5 @@ PEM_read_bio_SSL_SESSION 370 SSL_CTX_set_psk_server_callback 303 EXIST::FUNCTION:PSK 371 SSL_get_psk_identity 304 EXIST::FUNCTION:PSK 372 PEM_write_SSL_SESSION 305 EXIST:!WIN16:FUNCTION: 373+SSL_set_session_ticket_ext 306 EXIST::FUNCTION:TLSEXT 374+SSL_set_session_secret_cb 307 EXIST::FUNCTION:TLSEXT 375