openssl-0.9.9-session-ticket.patch revision 214501
1214501SrpauloThis patch adds support for TLS SessionTicket extension (RFC 5077) for 2214501Srpaulothe parts used by EAP-FAST (RFC 4851). 3214501Srpaulo 4214501SrpauloThis is based on the patch from Alexey Kobozev <akobozev@cisco.com> 5214501Srpaulo(sent to openssl-dev mailing list on Tue, 07 Jun 2005 15:40:58 +0300). 6214501Srpaulo 7214501SrpauloNOTE: This patch (without SSL_set_hello_extension() wrapper) was 8214501Srpaulomerged into the upstream OpenSSL 0.9.9 tree and as such, an external 9214501Srpaulopatch for EAP-FAST support is not needed anymore. 10214501Srpaulo 11214501Srpaulo 12214501Srpaulo 13214501SrpauloIndex: openssl-SNAP-20081111/ssl/s3_clnt.c 14214501Srpaulo=================================================================== 15214501Srpaulo--- openssl-SNAP-20081111.orig/ssl/s3_clnt.c 16214501Srpaulo+++ openssl-SNAP-20081111/ssl/s3_clnt.c 17214501Srpaulo@@ -788,6 +788,23 @@ int ssl3_get_server_hello(SSL *s) 18214501Srpaulo goto f_err; 19214501Srpaulo } 20214501Srpaulo 21214501Srpaulo+#ifndef OPENSSL_NO_TLSEXT 22214501Srpaulo+ /* check if we want to resume the session based on external pre-shared secret */ 23214501Srpaulo+ if (s->version >= TLS1_VERSION && s->tls_session_secret_cb) 24214501Srpaulo+ { 25214501Srpaulo+ SSL_CIPHER *pref_cipher=NULL; 26214501Srpaulo+ s->session->master_key_length=sizeof(s->session->master_key); 27214501Srpaulo+ if (s->tls_session_secret_cb(s, s->session->master_key, 28214501Srpaulo+ &s->session->master_key_length, 29214501Srpaulo+ NULL, &pref_cipher, 30214501Srpaulo+ s->tls_session_secret_cb_arg)) 31214501Srpaulo+ { 32214501Srpaulo+ s->session->cipher = pref_cipher ? 33214501Srpaulo+ pref_cipher : ssl_get_cipher_by_char(s, p+j); 34214501Srpaulo+ } 35214501Srpaulo+ } 36214501Srpaulo+#endif /* OPENSSL_NO_TLSEXT */ 37214501Srpaulo+ 38214501Srpaulo if (j != 0 && j == s->session->session_id_length 39214501Srpaulo && memcmp(p,s->session->session_id,j) == 0) 40214501Srpaulo { 41214501Srpaulo@@ -2927,11 +2944,8 @@ static int ssl3_check_finished(SSL *s) 42214501Srpaulo { 43214501Srpaulo int ok; 44214501Srpaulo long n; 45214501Srpaulo- /* If we have no ticket or session ID is non-zero length (a match of 46214501Srpaulo- * a non-zero session length would never reach here) it cannot be a 47214501Srpaulo- * resumed session. 48214501Srpaulo- */ 49214501Srpaulo- if (!s->session->tlsext_tick || s->session->session_id_length) 50214501Srpaulo+ /* If we have no ticket it cannot be a resumed session. */ 51214501Srpaulo+ if (!s->session->tlsext_tick) 52214501Srpaulo return 1; 53214501Srpaulo /* this function is called when we really expect a Certificate 54214501Srpaulo * message, so permit appropriate message length */ 55214501SrpauloIndex: openssl-SNAP-20081111/ssl/s3_srvr.c 56214501Srpaulo=================================================================== 57214501Srpaulo--- openssl-SNAP-20081111.orig/ssl/s3_srvr.c 58214501Srpaulo+++ openssl-SNAP-20081111/ssl/s3_srvr.c 59214501Srpaulo@@ -1010,6 +1010,59 @@ int ssl3_get_client_hello(SSL *s) 60214501Srpaulo SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_CLIENTHELLO_TLSEXT); 61214501Srpaulo goto err; 62214501Srpaulo } 63214501Srpaulo+ 64214501Srpaulo+ /* Check if we want to use external pre-shared secret for this 65214501Srpaulo+ * handshake for not reused session only. We need to generate 66214501Srpaulo+ * server_random before calling tls_session_secret_cb in order to allow 67214501Srpaulo+ * SessionTicket processing to use it in key derivation. */ 68214501Srpaulo+ { 69214501Srpaulo+ unsigned long Time; 70214501Srpaulo+ unsigned char *pos; 71214501Srpaulo+ Time=(unsigned long)time(NULL); /* Time */ 72214501Srpaulo+ pos=s->s3->server_random; 73214501Srpaulo+ l2n(Time,pos); 74214501Srpaulo+ if (RAND_pseudo_bytes(pos,SSL3_RANDOM_SIZE-4) <= 0) 75214501Srpaulo+ { 76214501Srpaulo+ al=SSL_AD_INTERNAL_ERROR; 77214501Srpaulo+ goto f_err; 78214501Srpaulo+ } 79214501Srpaulo+ } 80214501Srpaulo+ 81214501Srpaulo+ if (!s->hit && s->version >= TLS1_VERSION && s->tls_session_secret_cb) 82214501Srpaulo+ { 83214501Srpaulo+ SSL_CIPHER *pref_cipher=NULL; 84214501Srpaulo+ 85214501Srpaulo+ s->session->master_key_length=sizeof(s->session->master_key); 86214501Srpaulo+ if(s->tls_session_secret_cb(s, s->session->master_key, &s->session->master_key_length, 87214501Srpaulo+ ciphers, &pref_cipher, s->tls_session_secret_cb_arg)) 88214501Srpaulo+ { 89214501Srpaulo+ s->hit=1; 90214501Srpaulo+ s->session->ciphers=ciphers; 91214501Srpaulo+ s->session->verify_result=X509_V_OK; 92214501Srpaulo+ 93214501Srpaulo+ ciphers=NULL; 94214501Srpaulo+ 95214501Srpaulo+ /* check if some cipher was preferred by call back */ 96214501Srpaulo+ pref_cipher=pref_cipher ? pref_cipher : ssl3_choose_cipher(s, s->session->ciphers, SSL_get_ciphers(s)); 97214501Srpaulo+ if (pref_cipher == NULL) 98214501Srpaulo+ { 99214501Srpaulo+ al=SSL_AD_HANDSHAKE_FAILURE; 100214501Srpaulo+ SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_NO_SHARED_CIPHER); 101214501Srpaulo+ goto f_err; 102214501Srpaulo+ } 103214501Srpaulo+ 104214501Srpaulo+ s->session->cipher=pref_cipher; 105214501Srpaulo+ 106214501Srpaulo+ if (s->cipher_list) 107214501Srpaulo+ sk_SSL_CIPHER_free(s->cipher_list); 108214501Srpaulo+ 109214501Srpaulo+ if (s->cipher_list_by_id) 110214501Srpaulo+ sk_SSL_CIPHER_free(s->cipher_list_by_id); 111214501Srpaulo+ 112214501Srpaulo+ s->cipher_list = sk_SSL_CIPHER_dup(s->session->ciphers); 113214501Srpaulo+ s->cipher_list_by_id = sk_SSL_CIPHER_dup(s->session->ciphers); 114214501Srpaulo+ } 115214501Srpaulo+ } 116214501Srpaulo #endif 117214501Srpaulo 118214501Srpaulo /* Worst case, we will use the NULL compression, but if we have other 119214501Srpaulo@@ -1134,16 +1187,22 @@ int ssl3_send_server_hello(SSL *s) 120214501Srpaulo unsigned char *buf; 121214501Srpaulo unsigned char *p,*d; 122214501Srpaulo int i,sl; 123214501Srpaulo- unsigned long l,Time; 124214501Srpaulo+ unsigned long l; 125214501Srpaulo+#ifdef OPENSSL_NO_TLSEXT 126214501Srpaulo+ unsigned long Time; 127214501Srpaulo+#endif 128214501Srpaulo 129214501Srpaulo if (s->state == SSL3_ST_SW_SRVR_HELLO_A) 130214501Srpaulo { 131214501Srpaulo buf=(unsigned char *)s->init_buf->data; 132214501Srpaulo+#ifdef OPENSSL_NO_TLSEXT 133214501Srpaulo p=s->s3->server_random; 134214501Srpaulo+ /* Generate server_random if it was not needed previously */ 135214501Srpaulo Time=(unsigned long)time(NULL); /* Time */ 136214501Srpaulo l2n(Time,p); 137214501Srpaulo if (RAND_pseudo_bytes(p,SSL3_RANDOM_SIZE-4) <= 0) 138214501Srpaulo return -1; 139214501Srpaulo+#endif 140214501Srpaulo /* Do the message type and length last */ 141214501Srpaulo d=p= &(buf[4]); 142214501Srpaulo 143214501SrpauloIndex: openssl-SNAP-20081111/ssl/ssl_err.c 144214501Srpaulo=================================================================== 145214501Srpaulo--- openssl-SNAP-20081111.orig/ssl/ssl_err.c 146214501Srpaulo+++ openssl-SNAP-20081111/ssl/ssl_err.c 147214501Srpaulo@@ -263,6 +263,7 @@ static ERR_STRING_DATA SSL_str_functs[]= 148214501Srpaulo {ERR_FUNC(SSL_F_TLS1_PRF), "tls1_prf"}, 149214501Srpaulo {ERR_FUNC(SSL_F_TLS1_SETUP_KEY_BLOCK), "TLS1_SETUP_KEY_BLOCK"}, 150214501Srpaulo {ERR_FUNC(SSL_F_WRITE_PENDING), "WRITE_PENDING"}, 151214501Srpaulo+{ERR_FUNC(SSL_F_SSL_SET_SESSION_TICKET_EXT), "SSL_set_session_ticket_ext"}, 152214501Srpaulo {0,NULL} 153214501Srpaulo }; 154214501Srpaulo 155214501SrpauloIndex: openssl-SNAP-20081111/ssl/ssl.h 156214501Srpaulo=================================================================== 157214501Srpaulo--- openssl-SNAP-20081111.orig/ssl/ssl.h 158214501Srpaulo+++ openssl-SNAP-20081111/ssl/ssl.h 159214501Srpaulo@@ -355,6 +355,7 @@ extern "C" { 160214501Srpaulo * 'struct ssl_st *' function parameters used to prototype callbacks 161214501Srpaulo * in SSL_CTX. */ 162214501Srpaulo typedef struct ssl_st *ssl_crock_st; 163214501Srpaulo+typedef struct tls_session_ticket_ext_st TLS_SESSION_TICKET_EXT; 164214501Srpaulo 165214501Srpaulo /* used to hold info on the particular ciphers used */ 166214501Srpaulo typedef struct ssl_cipher_st 167214501Srpaulo@@ -378,6 +379,8 @@ typedef struct ssl_cipher_st 168214501Srpaulo 169214501Srpaulo DECLARE_STACK_OF(SSL_CIPHER) 170214501Srpaulo 171214501Srpaulo+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); 172214501Srpaulo+ 173214501Srpaulo /* Used to hold functions for SSLv2 or SSLv3/TLSv1 functions */ 174214501Srpaulo typedef struct ssl_method_st 175214501Srpaulo { 176214501Srpaulo@@ -1145,6 +1148,13 @@ struct ssl_st 177214501Srpaulo void *tlsext_opaque_prf_input; 178214501Srpaulo size_t tlsext_opaque_prf_input_len; 179214501Srpaulo 180214501Srpaulo+ /* TLS Session Ticket extension override */ 181214501Srpaulo+ TLS_SESSION_TICKET_EXT *tlsext_session_ticket; 182214501Srpaulo+ 183214501Srpaulo+ /* TLS pre-shared secret session resumption */ 184214501Srpaulo+ tls_session_secret_cb_fn tls_session_secret_cb; 185214501Srpaulo+ void *tls_session_secret_cb_arg; 186214501Srpaulo+ 187214501Srpaulo SSL_CTX * initial_ctx; /* initial ctx, used to store sessions */ 188214501Srpaulo #define session_ctx initial_ctx 189214501Srpaulo #else 190214501Srpaulo@@ -1746,6 +1756,16 @@ void *SSL_COMP_get_compression_methods(v 191214501Srpaulo int SSL_COMP_add_compression_method(int id,void *cm); 192214501Srpaulo #endif 193214501Srpaulo 194214501Srpaulo+/* NOTE: This function will be removed; it is only here for backwards 195214501Srpaulo+ * compatibility for the API during testing. */ 196214501Srpaulo+int SSL_set_hello_extension(SSL *s, int ext_type, void *ext_data, int ext_len); 197214501Srpaulo+ 198214501Srpaulo+/* TLS extensions functions */ 199214501Srpaulo+int SSL_set_session_ticket_ext(SSL *s, void *ext_data, int ext_len); 200214501Srpaulo+ 201214501Srpaulo+/* Pre-shared secret session resumption functions */ 202214501Srpaulo+int SSL_set_session_secret_cb(SSL *s, tls_session_secret_cb_fn tls_session_secret_cb, void *arg); 203214501Srpaulo+ 204214501Srpaulo /* BEGIN ERROR CODES */ 205214501Srpaulo /* The following lines are auto generated by the script mkerr.pl. Any changes 206214501Srpaulo * made after this point may be overwritten when the script is next run. 207214501Srpaulo@@ -1948,6 +1968,7 @@ void ERR_load_SSL_strings(void); 208214501Srpaulo #define SSL_F_TLS1_PRF 284 209214501Srpaulo #define SSL_F_TLS1_SETUP_KEY_BLOCK 211 210214501Srpaulo #define SSL_F_WRITE_PENDING 212 211214501Srpaulo+#define SSL_F_SSL_SET_SESSION_TICKET_EXT 213 212214501Srpaulo 213214501Srpaulo /* Reason codes. */ 214214501Srpaulo #define SSL_R_APP_DATA_IN_HANDSHAKE 100 215214501SrpauloIndex: openssl-SNAP-20081111/ssl/ssl_sess.c 216214501Srpaulo=================================================================== 217214501Srpaulo--- openssl-SNAP-20081111.orig/ssl/ssl_sess.c 218214501Srpaulo+++ openssl-SNAP-20081111/ssl/ssl_sess.c 219214501Srpaulo@@ -834,6 +834,62 @@ long SSL_CTX_get_timeout(const SSL_CTX * 220214501Srpaulo return(s->session_timeout); 221214501Srpaulo } 222214501Srpaulo 223214501Srpaulo+#ifndef OPENSSL_NO_TLSEXT 224214501Srpaulo+int SSL_set_session_secret_cb(SSL *s, int (*tls_session_secret_cb)(SSL *s, void *secret, int *secret_len, 225214501Srpaulo+ STACK_OF(SSL_CIPHER) *peer_ciphers, SSL_CIPHER **cipher, void *arg), void *arg) 226214501Srpaulo+ { 227214501Srpaulo+ if (s == NULL) return(0); 228214501Srpaulo+ s->tls_session_secret_cb = tls_session_secret_cb; 229214501Srpaulo+ s->tls_session_secret_cb_arg = arg; 230214501Srpaulo+ return(1); 231214501Srpaulo+ } 232214501Srpaulo+ 233214501Srpaulo+int SSL_set_session_ticket_ext(SSL *s, void *ext_data, int ext_len) 234214501Srpaulo+ { 235214501Srpaulo+ if (s->version >= TLS1_VERSION) 236214501Srpaulo+ { 237214501Srpaulo+ if (s->tlsext_session_ticket) 238214501Srpaulo+ { 239214501Srpaulo+ OPENSSL_free(s->tlsext_session_ticket); 240214501Srpaulo+ s->tlsext_session_ticket = NULL; 241214501Srpaulo+ } 242214501Srpaulo+ 243214501Srpaulo+ s->tlsext_session_ticket = OPENSSL_malloc(sizeof(TLS_SESSION_TICKET_EXT) + ext_len); 244214501Srpaulo+ if (!s->tlsext_session_ticket) 245214501Srpaulo+ { 246214501Srpaulo+ SSLerr(SSL_F_SSL_SET_SESSION_TICKET_EXT, ERR_R_MALLOC_FAILURE); 247214501Srpaulo+ return 0; 248214501Srpaulo+ } 249214501Srpaulo+ 250214501Srpaulo+ if (ext_data) 251214501Srpaulo+ { 252214501Srpaulo+ s->tlsext_session_ticket->length = ext_len; 253214501Srpaulo+ s->tlsext_session_ticket->data = s->tlsext_session_ticket + 1; 254214501Srpaulo+ memcpy(s->tlsext_session_ticket->data, ext_data, ext_len); 255214501Srpaulo+ } 256214501Srpaulo+ else 257214501Srpaulo+ { 258214501Srpaulo+ s->tlsext_session_ticket->length = 0; 259214501Srpaulo+ s->tlsext_session_ticket->data = NULL; 260214501Srpaulo+ } 261214501Srpaulo+ 262214501Srpaulo+ return 1; 263214501Srpaulo+ } 264214501Srpaulo+ 265214501Srpaulo+ return 0; 266214501Srpaulo+ } 267214501Srpaulo+ 268214501Srpaulo+/* NOTE: This function will be removed; it is only here for backwards 269214501Srpaulo+ * compatibility for the API during testing. */ 270214501Srpaulo+int SSL_set_hello_extension(SSL *s, int ext_type, void *ext_data, int ext_len) 271214501Srpaulo+ { 272214501Srpaulo+ if (ext_type != TLSEXT_TYPE_session_ticket) 273214501Srpaulo+ return 0; 274214501Srpaulo+ 275214501Srpaulo+ return SSL_set_session_ticket_ext(s, ext_data, ext_len); 276214501Srpaulo+ } 277214501Srpaulo+#endif /* OPENSSL_NO_TLSEXT */ 278214501Srpaulo+ 279214501Srpaulo typedef struct timeout_param_st 280214501Srpaulo { 281214501Srpaulo SSL_CTX *ctx; 282214501SrpauloIndex: openssl-SNAP-20081111/ssl/t1_lib.c 283214501Srpaulo=================================================================== 284214501Srpaulo--- openssl-SNAP-20081111.orig/ssl/t1_lib.c 285214501Srpaulo+++ openssl-SNAP-20081111/ssl/t1_lib.c 286214501Srpaulo@@ -154,6 +154,12 @@ int tls1_new(SSL *s) 287214501Srpaulo 288214501Srpaulo void tls1_free(SSL *s) 289214501Srpaulo { 290214501Srpaulo+#ifndef OPENSSL_NO_TLSEXT 291214501Srpaulo+ if (s->tlsext_session_ticket) 292214501Srpaulo+ { 293214501Srpaulo+ OPENSSL_free(s->tlsext_session_ticket); 294214501Srpaulo+ } 295214501Srpaulo+#endif /* OPENSSL_NO_TLSEXT */ 296214501Srpaulo ssl3_free(s); 297214501Srpaulo } 298214501Srpaulo 299214501Srpaulo@@ -357,8 +363,23 @@ unsigned char *ssl_add_clienthello_tlsex 300214501Srpaulo int ticklen; 301214501Srpaulo if (s->session && s->session->tlsext_tick) 302214501Srpaulo ticklen = s->session->tlsext_ticklen; 303214501Srpaulo+ else if (s->session && s->tlsext_session_ticket && 304214501Srpaulo+ s->tlsext_session_ticket->data) 305214501Srpaulo+ { 306214501Srpaulo+ ticklen = s->tlsext_session_ticket->length; 307214501Srpaulo+ s->session->tlsext_tick = OPENSSL_malloc(ticklen); 308214501Srpaulo+ if (!s->session->tlsext_tick) 309214501Srpaulo+ return NULL; 310214501Srpaulo+ memcpy(s->session->tlsext_tick, 311214501Srpaulo+ s->tlsext_session_ticket->data, 312214501Srpaulo+ ticklen); 313214501Srpaulo+ s->session->tlsext_ticklen = ticklen; 314214501Srpaulo+ } 315214501Srpaulo else 316214501Srpaulo ticklen = 0; 317214501Srpaulo+ if (ticklen == 0 && s->tlsext_session_ticket && 318214501Srpaulo+ s->tlsext_session_ticket->data == NULL) 319214501Srpaulo+ goto skip_ext; 320214501Srpaulo /* Check for enough room 2 for extension type, 2 for len 321214501Srpaulo * rest for ticket 322214501Srpaulo */ 323214501Srpaulo@@ -371,6 +392,7 @@ unsigned char *ssl_add_clienthello_tlsex 324214501Srpaulo ret += ticklen; 325214501Srpaulo } 326214501Srpaulo } 327214501Srpaulo+ skip_ext: 328214501Srpaulo 329214501Srpaulo #ifdef TLSEXT_TYPE_opaque_prf_input 330214501Srpaulo if (s->s3->client_opaque_prf_input != NULL) 331214501Srpaulo@@ -1435,6 +1457,15 @@ int tls1_process_ticket(SSL *s, unsigned 332214501Srpaulo s->tlsext_ticket_expected = 1; 333214501Srpaulo return 0; /* Cache miss */ 334214501Srpaulo } 335214501Srpaulo+ if (s->tls_session_secret_cb) 336214501Srpaulo+ { 337214501Srpaulo+ /* Indicate cache miss here and instead of 338214501Srpaulo+ * generating the session from ticket now, 339214501Srpaulo+ * trigger abbreviated handshake based on 340214501Srpaulo+ * external mechanism to calculate the master 341214501Srpaulo+ * secret later. */ 342214501Srpaulo+ return 0; 343214501Srpaulo+ } 344214501Srpaulo return tls_decrypt_ticket(s, p, size, session_id, len, 345214501Srpaulo ret); 346214501Srpaulo } 347214501SrpauloIndex: openssl-SNAP-20081111/ssl/tls1.h 348214501Srpaulo=================================================================== 349214501Srpaulo--- openssl-SNAP-20081111.orig/ssl/tls1.h 350214501Srpaulo+++ openssl-SNAP-20081111/ssl/tls1.h 351214501Srpaulo@@ -512,6 +512,13 @@ SSL_CTX_callback_ctrl(ssl,SSL_CTRL_SET_T 352214501Srpaulo #define TLS_MD_MASTER_SECRET_CONST "\x6d\x61\x73\x74\x65\x72\x20\x73\x65\x63\x72\x65\x74" /*master secret*/ 353214501Srpaulo #endif 354214501Srpaulo 355214501Srpaulo+/* TLS Session Ticket extension struct */ 356214501Srpaulo+struct tls_session_ticket_ext_st 357214501Srpaulo+ { 358214501Srpaulo+ unsigned short length; 359214501Srpaulo+ void *data; 360214501Srpaulo+ }; 361214501Srpaulo+ 362214501Srpaulo #ifdef __cplusplus 363214501Srpaulo } 364214501Srpaulo #endif 365214501SrpauloIndex: openssl-SNAP-20081111/util/ssleay.num 366214501Srpaulo=================================================================== 367214501Srpaulo--- openssl-SNAP-20081111.orig/util/ssleay.num 368214501Srpaulo+++ openssl-SNAP-20081111/util/ssleay.num 369214501Srpaulo@@ -254,3 +254,5 @@ PEM_read_bio_SSL_SESSION 370214501Srpaulo SSL_CTX_set_psk_server_callback 303 EXIST::FUNCTION:PSK 371214501Srpaulo SSL_get_psk_identity 304 EXIST::FUNCTION:PSK 372214501Srpaulo PEM_write_SSL_SESSION 305 EXIST:!WIN16:FUNCTION: 373214501Srpaulo+SSL_set_session_ticket_ext 306 EXIST::FUNCTION:TLSEXT 374214501Srpaulo+SSL_set_session_secret_cb 307 EXIST::FUNCTION:TLSEXT 375