1This patch is adding support for TLS hello extensions and externally 2generated pre-shared key material to OpenSSL 0.9.8. This is 3based on the patch from Alexey Kobozev <akobozev@cisco.com> 4(sent to openssl-dev mailing list on Tue, 07 Jun 2005 15:40:58 +0300). 5 6 7 8diff -uprN openssl-0.9.8.orig/include/openssl/ssl.h openssl-0.9.8/include/openssl/ssl.h 9--- openssl-0.9.8.orig/include/openssl/ssl.h 2005-06-10 12:51:16.000000000 -0700 10+++ openssl-0.9.8/include/openssl/ssl.h 2005-07-19 20:02:15.000000000 -0700 11@@ -340,6 +340,7 @@ extern "C" { 12 * 'struct ssl_st *' function parameters used to prototype callbacks 13 * in SSL_CTX. */ 14 typedef struct ssl_st *ssl_crock_st; 15+typedef struct tls_extension_st TLS_EXTENSION; 16 17 /* used to hold info on the particular ciphers used */ 18 typedef struct ssl_cipher_st 19@@ -361,6 +362,8 @@ DECLARE_STACK_OF(SSL_CIPHER) 20 typedef struct ssl_st SSL; 21 typedef struct ssl_ctx_st SSL_CTX; 22 23+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); 24+ 25 /* Used to hold functions for SSLv2 or SSLv3/TLSv1 functions */ 26 typedef struct ssl_method_st 27 { 28@@ -968,6 +971,15 @@ struct ssl_st 29 int first_packet; 30 int client_version; /* what was passed, used for 31 * SSLv3/TLS rollback check */ 32+ 33+ /* TLS externsions */ 34+ TLS_EXTENSION *tls_extension; 35+ int (*tls_extension_cb)(SSL *s, TLS_EXTENSION *tls_ext, void *arg); 36+ void *tls_extension_cb_arg; 37+ 38+ /* TLS pre-shared secret session resumption */ 39+ tls_session_secret_cb_fn tls_session_secret_cb; 40+ void *tls_session_secret_cb_arg; 41 }; 42 43 #ifdef __cplusplus 44@@ -1533,6 +1545,13 @@ void *SSL_COMP_get_compression_methods(v 45 int SSL_COMP_add_compression_method(int id,void *cm); 46 #endif 47 48+/* TLS extensions functions */ 49+int SSL_set_hello_extension(SSL *s, int ext_type, void *ext_data, int ext_len); 50+int SSL_set_hello_extension_cb(SSL *s, int (*cb)(SSL *, TLS_EXTENSION *, void *), void *arg); 51+ 52+/* Pre-shared secret session resumption functions */ 53+int SSL_set_session_secret_cb(SSL *s, tls_session_secret_cb_fn tls_session_secret_cb, void *arg); 54+ 55 /* BEGIN ERROR CODES */ 56 /* The following lines are auto generated by the script mkerr.pl. Any changes 57 * made after this point may be overwritten when the script is next run. 58@@ -1714,6 +1733,7 @@ void ERR_load_SSL_strings(void); 59 #define SSL_F_TLS1_ENC 210 60 #define SSL_F_TLS1_SETUP_KEY_BLOCK 211 61 #define SSL_F_WRITE_PENDING 212 62+#define SSL_F_SSL_SET_HELLO_EXTENSION 213 63 64 /* Reason codes. */ 65 #define SSL_R_APP_DATA_IN_HANDSHAKE 100 66diff -uprN openssl-0.9.8.orig/include/openssl/tls1.h openssl-0.9.8/include/openssl/tls1.h 67--- openssl-0.9.8.orig/include/openssl/tls1.h 2003-07-22 05:34:21.000000000 -0700 68+++ openssl-0.9.8/include/openssl/tls1.h 2005-07-19 20:02:15.000000000 -0700 69@@ -282,6 +282,14 @@ extern "C" { 70 #define TLS_MD_MASTER_SECRET_CONST "\x6d\x61\x73\x74\x65\x72\x20\x73\x65\x63\x72\x65\x74" /*master secret*/ 71 #endif 72 73+/* TLS extension struct */ 74+struct tls_extension_st 75+{ 76+ unsigned short type; 77+ unsigned short length; 78+ void *data; 79+}; 80+ 81 #ifdef __cplusplus 82 } 83 #endif 84diff -uprN openssl-0.9.8.orig/ssl/Makefile openssl-0.9.8/ssl/Makefile 85--- openssl-0.9.8.orig/ssl/Makefile 2005-05-30 16:20:30.000000000 -0700 86+++ openssl-0.9.8/ssl/Makefile 2005-07-19 20:02:15.000000000 -0700 87@@ -24,7 +24,7 @@ LIBSRC= \ 88 s2_meth.c s2_srvr.c s2_clnt.c s2_lib.c s2_enc.c s2_pkt.c \ 89 s3_meth.c s3_srvr.c s3_clnt.c s3_lib.c s3_enc.c s3_pkt.c s3_both.c \ 90 s23_meth.c s23_srvr.c s23_clnt.c s23_lib.c s23_pkt.c \ 91- t1_meth.c t1_srvr.c t1_clnt.c t1_lib.c t1_enc.c \ 92+ t1_meth.c t1_srvr.c t1_clnt.c t1_lib.c t1_enc.c t1_ext.c \ 93 d1_meth.c d1_srvr.c d1_clnt.c d1_lib.c d1_pkt.c \ 94 d1_both.c d1_enc.c \ 95 ssl_lib.c ssl_err2.c ssl_cert.c ssl_sess.c \ 96@@ -35,7 +35,7 @@ LIBOBJ= \ 97 s2_meth.o s2_srvr.o s2_clnt.o s2_lib.o s2_enc.o s2_pkt.o \ 98 s3_meth.o s3_srvr.o s3_clnt.o s3_lib.o s3_enc.o s3_pkt.o s3_both.o \ 99 s23_meth.o s23_srvr.o s23_clnt.o s23_lib.o s23_pkt.o \ 100- t1_meth.o t1_srvr.o t1_clnt.o t1_lib.o t1_enc.o \ 101+ t1_meth.o t1_srvr.o t1_clnt.o t1_lib.o t1_enc.o t1_ext.o \ 102 d1_meth.o d1_srvr.o d1_clnt.o d1_lib.o d1_pkt.o \ 103 d1_both.o d1_enc.o \ 104 ssl_lib.o ssl_err2.o ssl_cert.o ssl_sess.o \ 105@@ -968,3 +968,4 @@ t1_srvr.o: ../include/openssl/ssl23.h .. 106 t1_srvr.o: ../include/openssl/stack.h ../include/openssl/symhacks.h 107 t1_srvr.o: ../include/openssl/tls1.h ../include/openssl/x509.h 108 t1_srvr.o: ../include/openssl/x509_vfy.h ssl_locl.h t1_srvr.c 109+t1_ext.o: t1_ext.c ssl_locl.h 110diff -uprN openssl-0.9.8.orig/ssl/s3_clnt.c openssl-0.9.8/ssl/s3_clnt.c 111--- openssl-0.9.8.orig/ssl/s3_clnt.c 2005-05-16 03:11:03.000000000 -0700 112+++ openssl-0.9.8/ssl/s3_clnt.c 2005-07-19 20:02:15.000000000 -0700 113@@ -606,6 +606,20 @@ int ssl3_client_hello(SSL *s) 114 } 115 *(p++)=0; /* Add the NULL method */ 116 117+ /* send client hello extensions if any */ 118+ if (s->version >= TLS1_VERSION && s->tls_extension) 119+ { 120+ // set the total extensions length 121+ s2n(s->tls_extension->length + 4, p); 122+ 123+ // put the extensions with type and length 124+ s2n(s->tls_extension->type, p); 125+ s2n(s->tls_extension->length, p); 126+ 127+ memcpy(p, s->tls_extension->data, s->tls_extension->length); 128+ p+=s->tls_extension->length; 129+ } 130+ 131 l=(p-d); 132 d=buf; 133 *(d++)=SSL3_MT_CLIENT_HELLO; 134@@ -628,7 +642,7 @@ int ssl3_get_server_hello(SSL *s) 135 STACK_OF(SSL_CIPHER) *sk; 136 SSL_CIPHER *c; 137 unsigned char *p,*d; 138- int i,al,ok; 139+ int i,al,ok,pre_shared; 140 unsigned int j; 141 long n; 142 SSL_COMP *comp; 143@@ -693,7 +707,24 @@ int ssl3_get_server_hello(SSL *s) 144 goto f_err; 145 } 146 147- if (j != 0 && j == s->session->session_id_length 148+ /* check if we want to resume the session based on external pre-shared secret */ 149+ pre_shared = 0; 150+ if (s->version >= TLS1_VERSION && s->tls_session_secret_cb) 151+ { 152+ SSL_CIPHER *pref_cipher=NULL; 153+ s->session->master_key_length=sizeof(s->session->master_key); 154+ if (s->tls_session_secret_cb(s, s->session->master_key, &s->session->master_key_length, 155+ NULL, &pref_cipher, s->tls_session_secret_cb_arg)) 156+ { 157+ s->hit=1; 158+ s->session->cipher=pref_cipher ? pref_cipher : ssl_get_cipher_by_char(s,p+j); 159+ s->session->session_id_length = j; 160+ memcpy(s->session->session_id, p, j); 161+ pre_shared = 1; 162+ } 163+ } 164+ 165+ if ((pre_shared || j != 0) && j == s->session->session_id_length 166 && memcmp(p,s->session->session_id,j) == 0) 167 { 168 if(s->sid_ctx_length != s->session->sid_ctx_length 169diff -uprN openssl-0.9.8.orig/ssl/s3_srvr.c openssl-0.9.8/ssl/s3_srvr.c 170--- openssl-0.9.8.orig/ssl/s3_srvr.c 2005-05-22 17:32:55.000000000 -0700 171+++ openssl-0.9.8/ssl/s3_srvr.c 2005-07-19 20:02:15.000000000 -0700 172@@ -955,6 +955,75 @@ int ssl3_get_client_hello(SSL *s) 173 } 174 #endif 175 176+ /* Check for TLS client hello extension here */ 177+ if (p < (d+n) && s->version >= TLS1_VERSION) 178+ { 179+ if (s->tls_extension_cb) 180+ { 181+ TLS_EXTENSION tls_ext; 182+ unsigned short ext_total_len; 183+ 184+ n2s(p, ext_total_len); 185+ n2s(p, tls_ext.type); 186+ n2s(p, tls_ext.length); 187+ 188+ // sanity check in TLS extension len 189+ if (tls_ext.length > (d+n) - p) 190+ { 191+ // just cut the lenth to packet border 192+ tls_ext.length = (d+n) - p; 193+ } 194+ 195+ tls_ext.data = p; 196+ 197+ // returns an alert code or 0 198+ al = s->tls_extension_cb(s, &tls_ext, s->tls_extension_cb_arg); 199+ if (al != 0) 200+ { 201+ SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_PEER_ERROR); 202+ goto f_err; 203+ } 204+ } 205+ } 206+ 207+ /* Check if we want to use external pre-shared secret for this handshake */ 208+ /* for not reused session only */ 209+ if (!s->hit && s->version >= TLS1_VERSION && s->tls_session_secret_cb) 210+ { 211+ SSL_CIPHER *pref_cipher=NULL; 212+ 213+ s->session->master_key_length=sizeof(s->session->master_key); 214+ if(s->tls_session_secret_cb(s, s->session->master_key, &s->session->master_key_length, 215+ ciphers, &pref_cipher, s->tls_session_secret_cb_arg)) 216+ { 217+ s->hit=1; 218+ s->session->ciphers=ciphers; 219+ s->session->verify_result=X509_V_OK; 220+ 221+ ciphers=NULL; 222+ 223+ /* check if some cipher was preferred by call back */ 224+ pref_cipher=pref_cipher ? pref_cipher : ssl3_choose_cipher(s, s->session->ciphers, SSL_get_ciphers(s)); 225+ if (pref_cipher == NULL) 226+ { 227+ al=SSL_AD_HANDSHAKE_FAILURE; 228+ SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_NO_SHARED_CIPHER); 229+ goto f_err; 230+ } 231+ 232+ s->session->cipher=pref_cipher; 233+ 234+ if (s->cipher_list) 235+ sk_SSL_CIPHER_free(s->cipher_list); 236+ 237+ if (s->cipher_list_by_id) 238+ sk_SSL_CIPHER_free(s->cipher_list_by_id); 239+ 240+ s->cipher_list = sk_SSL_CIPHER_dup(s->session->ciphers); 241+ s->cipher_list_by_id = sk_SSL_CIPHER_dup(s->session->ciphers); 242+ } 243+ } 244+ 245 /* Given s->session->ciphers and SSL_get_ciphers, we must 246 * pick a cipher */ 247 248diff -uprN openssl-0.9.8.orig/ssl/ssl_err.c openssl-0.9.8/ssl/ssl_err.c 249--- openssl-0.9.8.orig/ssl/ssl_err.c 2005-06-10 12:51:16.000000000 -0700 250+++ openssl-0.9.8/ssl/ssl_err.c 2005-07-19 20:02:15.000000000 -0700 251@@ -242,6 +242,7 @@ static ERR_STRING_DATA SSL_str_functs[]= 252 {ERR_FUNC(SSL_F_TLS1_ENC), "TLS1_ENC"}, 253 {ERR_FUNC(SSL_F_TLS1_SETUP_KEY_BLOCK), "TLS1_SETUP_KEY_BLOCK"}, 254 {ERR_FUNC(SSL_F_WRITE_PENDING), "WRITE_PENDING"}, 255+{ERR_FUNC(SSL_F_SSL_SET_HELLO_EXTENSION), "SSL_set_hello_extension"}, 256 {0,NULL} 257 }; 258 259diff -uprN openssl-0.9.8.orig/ssl/ssl.h openssl-0.9.8/ssl/ssl.h 260--- openssl-0.9.8.orig/ssl/ssl.h 2005-06-10 12:51:16.000000000 -0700 261+++ openssl-0.9.8/ssl/ssl.h 2005-07-19 20:02:15.000000000 -0700 262@@ -340,6 +340,7 @@ extern "C" { 263 * 'struct ssl_st *' function parameters used to prototype callbacks 264 * in SSL_CTX. */ 265 typedef struct ssl_st *ssl_crock_st; 266+typedef struct tls_extension_st TLS_EXTENSION; 267 268 /* used to hold info on the particular ciphers used */ 269 typedef struct ssl_cipher_st 270@@ -361,6 +362,8 @@ DECLARE_STACK_OF(SSL_CIPHER) 271 typedef struct ssl_st SSL; 272 typedef struct ssl_ctx_st SSL_CTX; 273 274+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); 275+ 276 /* Used to hold functions for SSLv2 or SSLv3/TLSv1 functions */ 277 typedef struct ssl_method_st 278 { 279@@ -968,6 +971,15 @@ struct ssl_st 280 int first_packet; 281 int client_version; /* what was passed, used for 282 * SSLv3/TLS rollback check */ 283+ 284+ /* TLS externsions */ 285+ TLS_EXTENSION *tls_extension; 286+ int (*tls_extension_cb)(SSL *s, TLS_EXTENSION *tls_ext, void *arg); 287+ void *tls_extension_cb_arg; 288+ 289+ /* TLS pre-shared secret session resumption */ 290+ tls_session_secret_cb_fn tls_session_secret_cb; 291+ void *tls_session_secret_cb_arg; 292 }; 293 294 #ifdef __cplusplus 295@@ -1533,6 +1545,13 @@ void *SSL_COMP_get_compression_methods(v 296 int SSL_COMP_add_compression_method(int id,void *cm); 297 #endif 298 299+/* TLS extensions functions */ 300+int SSL_set_hello_extension(SSL *s, int ext_type, void *ext_data, int ext_len); 301+int SSL_set_hello_extension_cb(SSL *s, int (*cb)(SSL *, TLS_EXTENSION *, void *), void *arg); 302+ 303+/* Pre-shared secret session resumption functions */ 304+int SSL_set_session_secret_cb(SSL *s, tls_session_secret_cb_fn tls_session_secret_cb, void *arg); 305+ 306 /* BEGIN ERROR CODES */ 307 /* The following lines are auto generated by the script mkerr.pl. Any changes 308 * made after this point may be overwritten when the script is next run. 309@@ -1714,6 +1733,7 @@ void ERR_load_SSL_strings(void); 310 #define SSL_F_TLS1_ENC 210 311 #define SSL_F_TLS1_SETUP_KEY_BLOCK 211 312 #define SSL_F_WRITE_PENDING 212 313+#define SSL_F_SSL_SET_HELLO_EXTENSION 213 314 315 /* Reason codes. */ 316 #define SSL_R_APP_DATA_IN_HANDSHAKE 100 317diff -uprN openssl-0.9.8.orig/ssl/ssl_sess.c openssl-0.9.8/ssl/ssl_sess.c 318--- openssl-0.9.8.orig/ssl/ssl_sess.c 2005-04-29 13:10:06.000000000 -0700 319+++ openssl-0.9.8/ssl/ssl_sess.c 2005-07-19 20:02:15.000000000 -0700 320@@ -656,6 +656,15 @@ long SSL_CTX_get_timeout(const SSL_CTX * 321 return(s->session_timeout); 322 } 323 324+int SSL_set_session_secret_cb(SSL *s, int (*tls_session_secret_cb)(SSL *s, void *secret, int *secret_len, 325+ STACK_OF(SSL_CIPHER) *peer_ciphers, SSL_CIPHER **cipher, void *arg), void *arg) 326+{ 327+ if (s == NULL) return(0); 328+ s->tls_session_secret_cb = tls_session_secret_cb; 329+ s->tls_session_secret_cb_arg = arg; 330+ return(1); 331+} 332+ 333 typedef struct timeout_param_st 334 { 335 SSL_CTX *ctx; 336diff -uprN openssl-0.9.8.orig/ssl/t1_ext.c openssl-0.9.8/ssl/t1_ext.c 337--- openssl-0.9.8.orig/ssl/t1_ext.c 1969-12-31 16:00:00.000000000 -0800 338+++ openssl-0.9.8/ssl/t1_ext.c 2005-07-19 20:03:29.000000000 -0700 339@@ -0,0 +1,48 @@ 340+ 341+#include <stdio.h> 342+#include "ssl_locl.h" 343+ 344+ 345+int SSL_set_hello_extension(SSL *s, int ext_type, void *ext_data, int ext_len) 346+{ 347+ if(s->version >= TLS1_VERSION) 348+ { 349+ if(s->tls_extension) 350+ { 351+ OPENSSL_free(s->tls_extension); 352+ s->tls_extension = NULL; 353+ } 354+ 355+ if(ext_data) 356+ { 357+ s->tls_extension = OPENSSL_malloc(sizeof(TLS_EXTENSION) + ext_len); 358+ if(!s->tls_extension) 359+ { 360+ SSLerr(SSL_F_SSL_SET_HELLO_EXTENSION, ERR_R_MALLOC_FAILURE); 361+ return 0; 362+ } 363+ 364+ s->tls_extension->type = ext_type; 365+ s->tls_extension->length = ext_len; 366+ s->tls_extension->data = s->tls_extension + 1; 367+ memcpy(s->tls_extension->data, ext_data, ext_len); 368+ } 369+ 370+ return 1; 371+ } 372+ 373+ return 0; 374+} 375+ 376+int SSL_set_hello_extension_cb(SSL *s, int (*cb)(SSL *, TLS_EXTENSION *, void *), void *arg) 377+{ 378+ if(s->version >= TLS1_VERSION) 379+ { 380+ s->tls_extension_cb = cb; 381+ s->tls_extension_cb_arg = arg; 382+ 383+ return 1; 384+ } 385+ 386+ return 0; 387+} 388diff -uprN openssl-0.9.8.orig/ssl/t1_lib.c openssl-0.9.8/ssl/t1_lib.c 389--- openssl-0.9.8.orig/ssl/t1_lib.c 2005-04-26 09:02:40.000000000 -0700 390+++ openssl-0.9.8/ssl/t1_lib.c 2005-07-19 20:02:15.000000000 -0700 391@@ -131,6 +131,10 @@ int tls1_new(SSL *s) 392 393 void tls1_free(SSL *s) 394 { 395+ if(s->tls_extension) 396+ { 397+ OPENSSL_free(s->tls_extension); 398+ } 399 ssl3_free(s); 400 } 401 402diff -uprN openssl-0.9.8.orig/ssl/tls1.h openssl-0.9.8/ssl/tls1.h 403--- openssl-0.9.8.orig/ssl/tls1.h 2003-07-22 05:34:21.000000000 -0700 404+++ openssl-0.9.8/ssl/tls1.h 2005-07-19 20:02:15.000000000 -0700 405@@ -282,6 +282,14 @@ extern "C" { 406 #define TLS_MD_MASTER_SECRET_CONST "\x6d\x61\x73\x74\x65\x72\x20\x73\x65\x63\x72\x65\x74" /*master secret*/ 407 #endif 408 409+/* TLS extension struct */ 410+struct tls_extension_st 411+{ 412+ unsigned short type; 413+ unsigned short length; 414+ void *data; 415+}; 416+ 417 #ifdef __cplusplus 418 } 419 #endif 420diff -uprN openssl-0.9.8.orig/util/ssleay.num openssl-0.9.8/util/ssleay.num 421--- openssl-0.9.8.orig/util/ssleay.num 2005-05-08 17:22:02.000000000 -0700 422+++ openssl-0.9.8/util/ssleay.num 2005-07-19 20:02:15.000000000 -0700 423@@ -226,3 +226,6 @@ DTLSv1_server_method 424 SSL_COMP_get_compression_methods 276 EXIST:!VMS:FUNCTION:COMP 425 SSL_COMP_get_compress_methods 276 EXIST:VMS:FUNCTION:COMP 426 SSL_SESSION_get_id 277 EXIST::FUNCTION: 427+SSL_set_hello_extension 278 EXIST::FUNCTION: 428+SSL_set_hello_extension_cb 279 EXIST::FUNCTION: 429+SSL_set_session_secret_cb 280 EXIST::FUNCTION: 430