openssl-0.9.8h-tls-extensions.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 7214501SrpauloOpenSSL 0.9.8h does not enable TLS extension support by default, so it 8214501Srpaulowill need to be enabled by adding enable-tlsext to config script 9214501Srpaulocommand line. 10214501Srpaulo 11214501Srpaulo 12214501Srpaulodiff -upr openssl-0.9.8h.orig/ssl/s3_clnt.c openssl-0.9.8h/ssl/s3_clnt.c 13214501Srpaulo--- openssl-0.9.8h.orig/ssl/s3_clnt.c 2008-05-28 10:29:27.000000000 +0300 14214501Srpaulo+++ openssl-0.9.8h/ssl/s3_clnt.c 2008-05-29 10:44:25.000000000 +0300 15214501Srpaulo@@ -752,6 +752,20 @@ int ssl3_get_server_hello(SSL *s) 16214501Srpaulo goto f_err; 17214501Srpaulo } 18214501Srpaulo 19214501Srpaulo+#ifndef OPENSSL_NO_TLSEXT 20214501Srpaulo+ /* check if we want to resume the session based on external pre-shared secret */ 21214501Srpaulo+ if (s->version >= TLS1_VERSION && s->tls_session_secret_cb) 22214501Srpaulo+ { 23214501Srpaulo+ SSL_CIPHER *pref_cipher=NULL; 24214501Srpaulo+ s->session->master_key_length=sizeof(s->session->master_key); 25214501Srpaulo+ if (s->tls_session_secret_cb(s, s->session->master_key, &s->session->master_key_length, 26214501Srpaulo+ NULL, &pref_cipher, s->tls_session_secret_cb_arg)) 27214501Srpaulo+ { 28214501Srpaulo+ s->session->cipher=pref_cipher ? pref_cipher : ssl_get_cipher_by_char(s,p+j); 29214501Srpaulo+ } 30214501Srpaulo+ } 31214501Srpaulo+#endif /* OPENSSL_NO_TLSEXT */ 32214501Srpaulo+ 33214501Srpaulo if (j != 0 && j == s->session->session_id_length 34214501Srpaulo && memcmp(p,s->session->session_id,j) == 0) 35214501Srpaulo { 36214501Srpaulo@@ -2693,11 +2707,8 @@ static int ssl3_check_finished(SSL *s) 37214501Srpaulo { 38214501Srpaulo int ok; 39214501Srpaulo long n; 40214501Srpaulo- /* If we have no ticket or session ID is non-zero length (a match of 41214501Srpaulo- * a non-zero session length would never reach here) it cannot be a 42214501Srpaulo- * resumed session. 43214501Srpaulo- */ 44214501Srpaulo- if (!s->session->tlsext_tick || s->session->session_id_length) 45214501Srpaulo+ /* If we have no ticket it cannot be a resumed session. */ 46214501Srpaulo+ if (!s->session->tlsext_tick) 47214501Srpaulo return 1; 48214501Srpaulo /* this function is called when we really expect a Certificate 49214501Srpaulo * message, so permit appropriate message length */ 50214501Srpaulodiff -upr openssl-0.9.8h.orig/ssl/s3_srvr.c openssl-0.9.8h/ssl/s3_srvr.c 51214501Srpaulo--- openssl-0.9.8h.orig/ssl/s3_srvr.c 2008-04-30 19:11:32.000000000 +0300 52214501Srpaulo+++ openssl-0.9.8h/ssl/s3_srvr.c 2008-05-28 18:49:34.000000000 +0300 53214501Srpaulo@@ -959,6 +959,59 @@ int ssl3_get_client_hello(SSL *s) 54214501Srpaulo SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_CLIENTHELLO_TLSEXT); 55214501Srpaulo goto err; 56214501Srpaulo } 57214501Srpaulo+ 58214501Srpaulo+ /* Check if we want to use external pre-shared secret for this 59214501Srpaulo+ * handshake for not reused session only. We need to generate 60214501Srpaulo+ * server_random before calling tls_session_secret_cb in order to allow 61214501Srpaulo+ * SessionTicket processing to use it in key derivation. */ 62214501Srpaulo+ { 63214501Srpaulo+ unsigned long Time; 64214501Srpaulo+ unsigned char *pos; 65214501Srpaulo+ Time=(unsigned long)time(NULL); /* Time */ 66214501Srpaulo+ pos=s->s3->server_random; 67214501Srpaulo+ l2n(Time,pos); 68214501Srpaulo+ if (RAND_pseudo_bytes(pos,SSL3_RANDOM_SIZE-4) <= 0) 69214501Srpaulo+ { 70214501Srpaulo+ al=SSL_AD_INTERNAL_ERROR; 71214501Srpaulo+ goto f_err; 72214501Srpaulo+ } 73214501Srpaulo+ } 74214501Srpaulo+ 75214501Srpaulo+ if (!s->hit && s->version >= TLS1_VERSION && s->tls_session_secret_cb) 76214501Srpaulo+ { 77214501Srpaulo+ SSL_CIPHER *pref_cipher=NULL; 78214501Srpaulo+ 79214501Srpaulo+ s->session->master_key_length=sizeof(s->session->master_key); 80214501Srpaulo+ if(s->tls_session_secret_cb(s, s->session->master_key, &s->session->master_key_length, 81214501Srpaulo+ ciphers, &pref_cipher, s->tls_session_secret_cb_arg)) 82214501Srpaulo+ { 83214501Srpaulo+ s->hit=1; 84214501Srpaulo+ s->session->ciphers=ciphers; 85214501Srpaulo+ s->session->verify_result=X509_V_OK; 86214501Srpaulo+ 87214501Srpaulo+ ciphers=NULL; 88214501Srpaulo+ 89214501Srpaulo+ /* check if some cipher was preferred by call back */ 90214501Srpaulo+ pref_cipher=pref_cipher ? pref_cipher : ssl3_choose_cipher(s, s->session->ciphers, SSL_get_ciphers(s)); 91214501Srpaulo+ if (pref_cipher == NULL) 92214501Srpaulo+ { 93214501Srpaulo+ al=SSL_AD_HANDSHAKE_FAILURE; 94214501Srpaulo+ SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_NO_SHARED_CIPHER); 95214501Srpaulo+ goto f_err; 96214501Srpaulo+ } 97214501Srpaulo+ 98214501Srpaulo+ s->session->cipher=pref_cipher; 99214501Srpaulo+ 100214501Srpaulo+ if (s->cipher_list) 101214501Srpaulo+ sk_SSL_CIPHER_free(s->cipher_list); 102214501Srpaulo+ 103214501Srpaulo+ if (s->cipher_list_by_id) 104214501Srpaulo+ sk_SSL_CIPHER_free(s->cipher_list_by_id); 105214501Srpaulo+ 106214501Srpaulo+ s->cipher_list = sk_SSL_CIPHER_dup(s->session->ciphers); 107214501Srpaulo+ s->cipher_list_by_id = sk_SSL_CIPHER_dup(s->session->ciphers); 108214501Srpaulo+ } 109214501Srpaulo+ } 110214501Srpaulo #endif 111214501Srpaulo /* Worst case, we will use the NULL compression, but if we have other 112214501Srpaulo * options, we will now look for them. We have i-1 compression 113214501Srpaulo@@ -1097,16 +1150,22 @@ int ssl3_send_server_hello(SSL *s) 114214501Srpaulo unsigned char *buf; 115214501Srpaulo unsigned char *p,*d; 116214501Srpaulo int i,sl; 117214501Srpaulo- unsigned long l,Time; 118214501Srpaulo+ unsigned long l; 119214501Srpaulo+#ifdef OPENSSL_NO_TLSEXT 120214501Srpaulo+ unsigned long Time; 121214501Srpaulo+#endif 122214501Srpaulo 123214501Srpaulo if (s->state == SSL3_ST_SW_SRVR_HELLO_A) 124214501Srpaulo { 125214501Srpaulo buf=(unsigned char *)s->init_buf->data; 126214501Srpaulo+#ifdef OPENSSL_NO_TLSEXT 127214501Srpaulo p=s->s3->server_random; 128214501Srpaulo+ /* Generate server_random if it was not needed previously */ 129214501Srpaulo Time=(unsigned long)time(NULL); /* Time */ 130214501Srpaulo l2n(Time,p); 131214501Srpaulo if (RAND_pseudo_bytes(p,SSL3_RANDOM_SIZE-4) <= 0) 132214501Srpaulo return -1; 133214501Srpaulo+#endif 134214501Srpaulo /* Do the message type and length last */ 135214501Srpaulo d=p= &(buf[4]); 136214501Srpaulo 137214501Srpaulodiff -upr openssl-0.9.8h.orig/ssl/ssl.h openssl-0.9.8h/ssl/ssl.h 138214501Srpaulo--- openssl-0.9.8h.orig/ssl/ssl.h 2008-04-30 19:11:32.000000000 +0300 139214501Srpaulo+++ openssl-0.9.8h/ssl/ssl.h 2008-05-28 18:49:34.000000000 +0300 140214501Srpaulo@@ -343,6 +343,7 @@ extern "C" { 141214501Srpaulo * 'struct ssl_st *' function parameters used to prototype callbacks 142214501Srpaulo * in SSL_CTX. */ 143214501Srpaulo typedef struct ssl_st *ssl_crock_st; 144214501Srpaulo+typedef struct tls_extension_st TLS_EXTENSION; 145214501Srpaulo 146214501Srpaulo /* used to hold info on the particular ciphers used */ 147214501Srpaulo typedef struct ssl_cipher_st 148214501Srpaulo@@ -364,6 +365,8 @@ DECLARE_STACK_OF(SSL_CIPHER) 149214501Srpaulo typedef struct ssl_st SSL; 150214501Srpaulo typedef struct ssl_ctx_st SSL_CTX; 151214501Srpaulo 152214501Srpaulo+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); 153214501Srpaulo+ 154214501Srpaulo /* Used to hold functions for SSLv2 or SSLv3/TLSv1 functions */ 155214501Srpaulo typedef struct ssl_method_st 156214501Srpaulo { 157214501Srpaulo@@ -1027,6 +1030,14 @@ struct ssl_st 158214501Srpaulo 159214501Srpaulo /* RFC4507 session ticket expected to be received or sent */ 160214501Srpaulo int tlsext_ticket_expected; 161214501Srpaulo+ 162214501Srpaulo+ /* TLS extensions */ 163214501Srpaulo+ TLS_EXTENSION *tls_extension; 164214501Srpaulo+ 165214501Srpaulo+ /* TLS pre-shared secret session resumption */ 166214501Srpaulo+ tls_session_secret_cb_fn tls_session_secret_cb; 167214501Srpaulo+ void *tls_session_secret_cb_arg; 168214501Srpaulo+ 169214501Srpaulo SSL_CTX * initial_ctx; /* initial ctx, used to store sessions */ 170214501Srpaulo #define session_ctx initial_ctx 171214501Srpaulo #else 172214501Srpaulo@@ -1625,6 +1636,12 @@ void *SSL_COMP_get_compression_methods(v 173214501Srpaulo int SSL_COMP_add_compression_method(int id,void *cm); 174214501Srpaulo #endif 175214501Srpaulo 176214501Srpaulo+/* TLS extensions functions */ 177214501Srpaulo+int SSL_set_hello_extension(SSL *s, int ext_type, void *ext_data, int ext_len); 178214501Srpaulo+ 179214501Srpaulo+/* Pre-shared secret session resumption functions */ 180214501Srpaulo+int SSL_set_session_secret_cb(SSL *s, tls_session_secret_cb_fn tls_session_secret_cb, void *arg); 181214501Srpaulo+ 182214501Srpaulo /* BEGIN ERROR CODES */ 183214501Srpaulo /* The following lines are auto generated by the script mkerr.pl. Any changes 184214501Srpaulo * made after this point may be overwritten when the script is next run. 185214501Srpaulo@@ -1815,6 +1832,7 @@ void ERR_load_SSL_strings(void); 186214501Srpaulo #define SSL_F_TLS1_ENC 210 187214501Srpaulo #define SSL_F_TLS1_SETUP_KEY_BLOCK 211 188214501Srpaulo #define SSL_F_WRITE_PENDING 212 189214501Srpaulo+#define SSL_F_SSL_SET_HELLO_EXTENSION 213 190214501Srpaulo 191214501Srpaulo /* Reason codes. */ 192214501Srpaulo #define SSL_R_APP_DATA_IN_HANDSHAKE 100 193214501Srpaulodiff -upr openssl-0.9.8h.orig/ssl/ssl_err.c openssl-0.9.8h/ssl/ssl_err.c 194214501Srpaulo--- openssl-0.9.8h.orig/ssl/ssl_err.c 2007-10-12 03:00:30.000000000 +0300 195214501Srpaulo+++ openssl-0.9.8h/ssl/ssl_err.c 2008-05-28 18:49:34.000000000 +0300 196214501Srpaulo@@ -251,6 +251,7 @@ static ERR_STRING_DATA SSL_str_functs[]= 197214501Srpaulo {ERR_FUNC(SSL_F_TLS1_ENC), "TLS1_ENC"}, 198214501Srpaulo {ERR_FUNC(SSL_F_TLS1_SETUP_KEY_BLOCK), "TLS1_SETUP_KEY_BLOCK"}, 199214501Srpaulo {ERR_FUNC(SSL_F_WRITE_PENDING), "WRITE_PENDING"}, 200214501Srpaulo+{ERR_FUNC(SSL_F_SSL_SET_HELLO_EXTENSION), "SSL_set_hello_extension"}, 201214501Srpaulo {0,NULL} 202214501Srpaulo }; 203214501Srpaulo 204214501Srpaulodiff -upr openssl-0.9.8h.orig/ssl/ssl_sess.c openssl-0.9.8h/ssl/ssl_sess.c 205214501Srpaulo--- openssl-0.9.8h.orig/ssl/ssl_sess.c 2007-10-17 20:30:15.000000000 +0300 206214501Srpaulo+++ openssl-0.9.8h/ssl/ssl_sess.c 2008-05-28 18:49:34.000000000 +0300 207214501Srpaulo@@ -704,6 +704,52 @@ long SSL_CTX_get_timeout(const SSL_CTX * 208214501Srpaulo return(s->session_timeout); 209214501Srpaulo } 210214501Srpaulo 211214501Srpaulo+#ifndef OPENSSL_NO_TLSEXT 212214501Srpaulo+int SSL_set_session_secret_cb(SSL *s, int (*tls_session_secret_cb)(SSL *s, void *secret, int *secret_len, 213214501Srpaulo+ STACK_OF(SSL_CIPHER) *peer_ciphers, SSL_CIPHER **cipher, void *arg), void *arg) 214214501Srpaulo+{ 215214501Srpaulo+ if (s == NULL) return(0); 216214501Srpaulo+ s->tls_session_secret_cb = tls_session_secret_cb; 217214501Srpaulo+ s->tls_session_secret_cb_arg = arg; 218214501Srpaulo+ return(1); 219214501Srpaulo+} 220214501Srpaulo+ 221214501Srpaulo+int SSL_set_hello_extension(SSL *s, int ext_type, void *ext_data, int ext_len) 222214501Srpaulo+{ 223214501Srpaulo+ if(s->version >= TLS1_VERSION) 224214501Srpaulo+ { 225214501Srpaulo+ if(s->tls_extension) 226214501Srpaulo+ { 227214501Srpaulo+ OPENSSL_free(s->tls_extension); 228214501Srpaulo+ s->tls_extension = NULL; 229214501Srpaulo+ } 230214501Srpaulo+ 231214501Srpaulo+ s->tls_extension = OPENSSL_malloc(sizeof(TLS_EXTENSION) + ext_len); 232214501Srpaulo+ if(!s->tls_extension) 233214501Srpaulo+ { 234214501Srpaulo+ SSLerr(SSL_F_SSL_SET_HELLO_EXTENSION, ERR_R_MALLOC_FAILURE); 235214501Srpaulo+ return 0; 236214501Srpaulo+ } 237214501Srpaulo+ 238214501Srpaulo+ s->tls_extension->type = ext_type; 239214501Srpaulo+ 240214501Srpaulo+ if(ext_data) 241214501Srpaulo+ { 242214501Srpaulo+ s->tls_extension->length = ext_len; 243214501Srpaulo+ s->tls_extension->data = s->tls_extension + 1; 244214501Srpaulo+ memcpy(s->tls_extension->data, ext_data, ext_len); 245214501Srpaulo+ } else { 246214501Srpaulo+ s->tls_extension->length = 0; 247214501Srpaulo+ s->tls_extension->data = NULL; 248214501Srpaulo+ } 249214501Srpaulo+ 250214501Srpaulo+ return 1; 251214501Srpaulo+ } 252214501Srpaulo+ 253214501Srpaulo+ return 0; 254214501Srpaulo+} 255214501Srpaulo+#endif /* OPENSSL_NO_TLSEXT */ 256214501Srpaulo+ 257214501Srpaulo typedef struct timeout_param_st 258214501Srpaulo { 259214501Srpaulo SSL_CTX *ctx; 260214501Srpaulodiff -upr openssl-0.9.8h.orig/ssl/t1_lib.c openssl-0.9.8h/ssl/t1_lib.c 261214501Srpaulo--- openssl-0.9.8h.orig/ssl/t1_lib.c 2008-05-28 10:26:33.000000000 +0300 262214501Srpaulo+++ openssl-0.9.8h/ssl/t1_lib.c 2008-05-28 18:49:34.000000000 +0300 263214501Srpaulo@@ -106,6 +106,12 @@ int tls1_new(SSL *s) 264214501Srpaulo 265214501Srpaulo void tls1_free(SSL *s) 266214501Srpaulo { 267214501Srpaulo+#ifndef OPENSSL_NO_TLSEXT 268214501Srpaulo+ if(s->tls_extension) 269214501Srpaulo+ { 270214501Srpaulo+ OPENSSL_free(s->tls_extension); 271214501Srpaulo+ } 272214501Srpaulo+#endif 273214501Srpaulo ssl3_free(s); 274214501Srpaulo } 275214501Srpaulo 276214501Srpaulo@@ -175,8 +181,24 @@ unsigned char *ssl_add_clienthello_tlsex 277214501Srpaulo int ticklen; 278214501Srpaulo if (s->session && s->session->tlsext_tick) 279214501Srpaulo ticklen = s->session->tlsext_ticklen; 280214501Srpaulo+ else if (s->session && s->tls_extension && 281214501Srpaulo+ s->tls_extension->type == TLSEXT_TYPE_session_ticket && 282214501Srpaulo+ s->tls_extension->data) 283214501Srpaulo+ { 284214501Srpaulo+ ticklen = s->tls_extension->length; 285214501Srpaulo+ s->session->tlsext_tick = OPENSSL_malloc(ticklen); 286214501Srpaulo+ if (!s->session->tlsext_tick) 287214501Srpaulo+ return NULL; 288214501Srpaulo+ memcpy(s->session->tlsext_tick, s->tls_extension->data, 289214501Srpaulo+ ticklen); 290214501Srpaulo+ s->session->tlsext_ticklen = ticklen; 291214501Srpaulo+ } 292214501Srpaulo else 293214501Srpaulo ticklen = 0; 294214501Srpaulo+ if (ticklen == 0 && s->tls_extension && 295214501Srpaulo+ s->tls_extension->type == TLSEXT_TYPE_session_ticket && 296214501Srpaulo+ s->tls_extension->data == NULL) 297214501Srpaulo+ goto skip_ext; 298214501Srpaulo /* Check for enough room 2 for extension type, 2 for len 299214501Srpaulo * rest for ticket 300214501Srpaulo */ 301214501Srpaulo@@ -190,6 +212,7 @@ unsigned char *ssl_add_clienthello_tlsex 302214501Srpaulo ret += ticklen; 303214501Srpaulo } 304214501Srpaulo } 305214501Srpaulo+ skip_ext: 306214501Srpaulo 307214501Srpaulo if (s->tlsext_status_type == TLSEXT_STATUSTYPE_ocsp) 308214501Srpaulo { 309214501Srpaulo@@ -774,6 +797,8 @@ int tls1_process_ticket(SSL *s, unsigned 310214501Srpaulo s->tlsext_ticket_expected = 1; 311214501Srpaulo return 0; /* Cache miss */ 312214501Srpaulo } 313214501Srpaulo+ if (s->tls_session_secret_cb) 314214501Srpaulo+ return 0; 315214501Srpaulo return tls_decrypt_ticket(s, p, size, session_id, len, 316214501Srpaulo ret); 317214501Srpaulo } 318214501Srpaulodiff -upr openssl-0.9.8h.orig/ssl/tls1.h openssl-0.9.8h/ssl/tls1.h 319214501Srpaulo--- openssl-0.9.8h.orig/ssl/tls1.h 2008-04-30 19:11:33.000000000 +0300 320214501Srpaulo+++ openssl-0.9.8h/ssl/tls1.h 2008-05-28 18:49:34.000000000 +0300 321214501Srpaulo@@ -398,6 +398,14 @@ SSL_CTX_callback_ctrl(ssl,SSL_CTRL_SET_T 322214501Srpaulo #define TLS_MD_MASTER_SECRET_CONST "\x6d\x61\x73\x74\x65\x72\x20\x73\x65\x63\x72\x65\x74" /*master secret*/ 323214501Srpaulo #endif 324214501Srpaulo 325214501Srpaulo+/* TLS extension struct */ 326214501Srpaulo+struct tls_extension_st 327214501Srpaulo+{ 328214501Srpaulo+ unsigned short type; 329214501Srpaulo+ unsigned short length; 330214501Srpaulo+ void *data; 331214501Srpaulo+}; 332214501Srpaulo+ 333214501Srpaulo #ifdef __cplusplus 334214501Srpaulo } 335214501Srpaulo #endif 336214501Srpaulodiff -upr openssl-0.9.8h.orig/util/ssleay.num openssl-0.9.8h/util/ssleay.num 337214501Srpaulo--- openssl-0.9.8h.orig/util/ssleay.num 2007-08-13 01:31:16.000000000 +0300 338214501Srpaulo+++ openssl-0.9.8h/util/ssleay.num 2008-05-28 18:49:34.000000000 +0300 339214501Srpaulo@@ -241,3 +241,5 @@ SSL_CTX_sess_get_remove_cb 340214501Srpaulo SSL_set_SSL_CTX 290 EXIST::FUNCTION: 341214501Srpaulo SSL_get_servername 291 EXIST::FUNCTION:TLSEXT 342214501Srpaulo SSL_get_servername_type 292 EXIST::FUNCTION:TLSEXT 343214501Srpaulo+SSL_set_hello_extension 305 EXIST::FUNCTION:TLSEXT 344214501Srpaulo+SSL_set_session_secret_cb 306 EXIST::FUNCTION:TLSEXT 345