openssl-0.9.8g-tls-extensions.patch revision 214734
1193323SedThis patch adds support for TLS SessionTicket extension (RFC 5077) for
2193323Sedthe parts used by EAP-FAST (RFC 4851).
3193323Sed
4193323SedThis is based on the patch from Alexey Kobozev <akobozev@cisco.com>
5193323Sed(sent to openssl-dev mailing list on Tue, 07 Jun 2005 15:40:58 +0300).
6193323Sed
7193323SedOpenSSL 0.9.8g does not enable TLS extension support by default, so it
8193323Sedwill need to be enabled by adding enable-tlsext to config script
9193323Sedcommand line.
10193323Sed
11193323Sed
12193323Seddiff -upr openssl-0.9.8g.orig/ssl/s3_clnt.c openssl-0.9.8g/ssl/s3_clnt.c
13193323Sed--- openssl-0.9.8g.orig/ssl/s3_clnt.c	2007-08-31 03:28:51.000000000 +0300
14193323Sed+++ openssl-0.9.8g/ssl/s3_clnt.c	2008-04-15 17:11:46.000000000 +0300
15193323Sed@@ -727,6 +727,20 @@ int ssl3_get_server_hello(SSL *s)
16193323Sed 		goto f_err;
17193323Sed 		}
18193323Sed 
19205407Srdivacky+#ifndef OPENSSL_NO_TLSEXT
20205407Srdivacky+	/* check if we want to resume the session based on external pre-shared secret */
21193323Sed+	if (s->version >= TLS1_VERSION && s->tls_session_secret_cb)
22193323Sed+	{
23193323Sed+		SSL_CIPHER *pref_cipher=NULL;
24193323Sed+		s->session->master_key_length=sizeof(s->session->master_key);
25193323Sed+		if (s->tls_session_secret_cb(s, s->session->master_key, &s->session->master_key_length,
26193323Sed+			NULL, &pref_cipher, s->tls_session_secret_cb_arg))
27193323Sed+		{
28193323Sed+			s->session->cipher=pref_cipher ? pref_cipher : ssl_get_cipher_by_char(s,p+j);
29193323Sed+		}
30193323Sed+	}
31193323Sed+#endif /* OPENSSL_NO_TLSEXT */
32193323Sed+
33193323Sed 	if (j != 0 && j == s->session->session_id_length
34193323Sed 	    && memcmp(p,s->session->session_id,j) == 0)
35193323Sed 	    {
36193323Seddiff -upr openssl-0.9.8g.orig/ssl/s3_srvr.c openssl-0.9.8g/ssl/s3_srvr.c
37193323Sed--- openssl-0.9.8g.orig/ssl/s3_srvr.c	2007-09-30 21:55:59.000000000 +0300
38193323Sed+++ openssl-0.9.8g/ssl/s3_srvr.c	2008-04-15 17:10:37.000000000 +0300
39193323Sed@@ -928,6 +928,59 @@ int ssl3_get_client_hello(SSL *s)
40193323Sed 			SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_CLIENTHELLO_TLSEXT);
41193323Sed 			goto err;
42193323Sed 		}
43193323Sed+
44193323Sed+	/* Check if we want to use external pre-shared secret for this
45193323Sed+	 * handshake for not reused session only. We need to generate
46193323Sed+	 * server_random before calling tls_session_secret_cb in order to allow
47193323Sed+	 * SessionTicket processing to use it in key derivation. */
48193323Sed+	{
49193323Sed+		unsigned long Time;
50193323Sed+		unsigned char *pos;
51193323Sed+		Time=(unsigned long)time(NULL);			/* Time */
52193323Sed+		pos=s->s3->server_random;
53193323Sed+		l2n(Time,pos);
54193323Sed+		if (RAND_pseudo_bytes(pos,SSL3_RANDOM_SIZE-4) <= 0)
55193323Sed+		{
56193323Sed+			al=SSL_AD_INTERNAL_ERROR;
57193323Sed+			goto f_err;
58193323Sed+		}
59193323Sed+	}
60193323Sed+
61193323Sed+	if (!s->hit && s->version >= TLS1_VERSION && s->tls_session_secret_cb)
62193323Sed+	{
63193323Sed+		SSL_CIPHER *pref_cipher=NULL;
64193323Sed+
65193323Sed+		s->session->master_key_length=sizeof(s->session->master_key);
66193323Sed+		if(s->tls_session_secret_cb(s, s->session->master_key, &s->session->master_key_length, 
67193323Sed+			ciphers, &pref_cipher, s->tls_session_secret_cb_arg))
68193323Sed+		{
69193323Sed+			s->hit=1;
70199511Srdivacky+			s->session->ciphers=ciphers;
71199511Srdivacky+			s->session->verify_result=X509_V_OK;
72199511Srdivacky+			
73199511Srdivacky+			ciphers=NULL;
74199511Srdivacky+			
75193323Sed+			/* check if some cipher was preferred by call back */
76193323Sed+			pref_cipher=pref_cipher ? pref_cipher : ssl3_choose_cipher(s, s->session->ciphers, SSL_get_ciphers(s));
77193323Sed+			if (pref_cipher == NULL)
78193323Sed+				{
79193323Sed+				al=SSL_AD_HANDSHAKE_FAILURE;
80193323Sed+				SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_NO_SHARED_CIPHER);
81193323Sed+				goto f_err;
82193323Sed+				}
83193323Sed+
84193323Sed+			s->session->cipher=pref_cipher;
85193323Sed+
86193323Sed+			if (s->cipher_list)
87193323Sed+				sk_SSL_CIPHER_free(s->cipher_list);
88193323Sed+
89193323Sed+			if (s->cipher_list_by_id)
90193323Sed+				sk_SSL_CIPHER_free(s->cipher_list_by_id);
91193323Sed+
92193323Sed+			s->cipher_list = sk_SSL_CIPHER_dup(s->session->ciphers);
93193323Sed+			s->cipher_list_by_id = sk_SSL_CIPHER_dup(s->session->ciphers);
94193323Sed+		}
95193323Sed+	}
96193323Sed #endif
97193323Sed 	/* Worst case, we will use the NULL compression, but if we have other
98193323Sed 	 * options, we will now look for them.  We have i-1 compression
99193323Sed@@ -1066,16 +1119,22 @@ int ssl3_send_server_hello(SSL *s)
100193323Sed 	unsigned char *buf;
101193323Sed 	unsigned char *p,*d;
102193323Sed 	int i,sl;
103193323Sed-	unsigned long l,Time;
104193323Sed+	unsigned long l;
105193323Sed+#ifdef OPENSSL_NO_TLSEXT
106193323Sed+	unsigned long Time;
107193323Sed+#endif
108193323Sed 
109193323Sed 	if (s->state == SSL3_ST_SW_SRVR_HELLO_A)
110193323Sed 		{
111193323Sed 		buf=(unsigned char *)s->init_buf->data;
112193323Sed+#ifdef OPENSSL_NO_TLSEXT
113193323Sed 		p=s->s3->server_random;
114193323Sed+		/* Generate server_random if it was not needed previously */
115193323Sed 		Time=(unsigned long)time(NULL);			/* Time */
116193323Sed 		l2n(Time,p);
117202375Srdivacky 		if (RAND_pseudo_bytes(p,SSL3_RANDOM_SIZE-4) <= 0)
118193323Sed 			return -1;
119193323Sed+#endif
120193323Sed 		/* Do the message type and length last */
121193323Sed 		d=p= &(buf[4]);
122193323Sed 
123193323Seddiff -upr openssl-0.9.8g.orig/ssl/ssl.h openssl-0.9.8g/ssl/ssl.h
124204642Srdivacky--- openssl-0.9.8g.orig/ssl/ssl.h	2007-10-19 10:42:38.000000000 +0300
125204642Srdivacky+++ openssl-0.9.8g/ssl/ssl.h	2008-04-15 17:10:37.000000000 +0300
126204642Srdivacky@@ -342,6 +342,7 @@ extern "C" {
127204642Srdivacky  * 'struct ssl_st *' function parameters used to prototype callbacks
128193323Sed  * in SSL_CTX. */
129198090Srdivacky typedef struct ssl_st *ssl_crock_st;
130208599Srdivacky+typedef struct tls_extension_st TLS_EXTENSION;
131198090Srdivacky 
132193323Sed /* used to hold info on the particular ciphers used */
133193323Sed typedef struct ssl_cipher_st
134198090Srdivacky@@ -363,6 +364,8 @@ DECLARE_STACK_OF(SSL_CIPHER)
135208599Srdivacky typedef struct ssl_st SSL;
136198090Srdivacky typedef struct ssl_ctx_st SSL_CTX;
137193323Sed 
138193323Sed+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);
139204642Srdivacky+
140204642Srdivacky /* Used to hold functions for SSLv2 or SSLv3/TLSv1 functions */
141204642Srdivacky typedef struct ssl_method_st
142204642Srdivacky 	{
143204642Srdivacky@@ -1004,6 +1007,14 @@ struct ssl_st
144204642Srdivacky 	                       */
145204642Srdivacky 	/* RFC4507 session ticket expected to be received or sent */
146204642Srdivacky 	int tlsext_ticket_expected;
147204642Srdivacky+
148204642Srdivacky+	/* TLS extensions */
149204642Srdivacky+	TLS_EXTENSION *tls_extension;
150204642Srdivacky+
151204642Srdivacky+	/* TLS pre-shared secret session resumption */
152204642Srdivacky+	tls_session_secret_cb_fn tls_session_secret_cb;
153204642Srdivacky+	void *tls_session_secret_cb_arg;
154204642Srdivacky+
155204642Srdivacky 	SSL_CTX * initial_ctx; /* initial ctx, used to store sessions */
156204642Srdivacky #define session_ctx initial_ctx
157204642Srdivacky #else
158204642Srdivacky@@ -1589,6 +1600,12 @@ void *SSL_COMP_get_compression_methods(v
159204642Srdivacky int SSL_COMP_add_compression_method(int id,void *cm);
160204642Srdivacky #endif
161204642Srdivacky 
162204642Srdivacky+/* TLS extensions functions */
163204642Srdivacky+int SSL_set_hello_extension(SSL *s, int ext_type, void *ext_data, int ext_len);
164204642Srdivacky+
165204642Srdivacky+/* Pre-shared secret session resumption functions */
166204642Srdivacky+int SSL_set_session_secret_cb(SSL *s, tls_session_secret_cb_fn tls_session_secret_cb, void *arg);
167204642Srdivacky+
168204642Srdivacky /* BEGIN ERROR CODES */
169204642Srdivacky /* The following lines are auto generated by the script mkerr.pl. Any changes
170204642Srdivacky  * made after this point may be overwritten when the script is next run.
171204642Srdivacky@@ -1778,6 +1795,7 @@ void ERR_load_SSL_strings(void);
172204642Srdivacky #define SSL_F_TLS1_ENC					 210
173204642Srdivacky #define SSL_F_TLS1_SETUP_KEY_BLOCK			 211
174204642Srdivacky #define SSL_F_WRITE_PENDING				 212
175204642Srdivacky+#define SSL_F_SSL_SET_HELLO_EXTENSION			 213
176204642Srdivacky 
177204642Srdivacky /* Reason codes. */
178204642Srdivacky #define SSL_R_APP_DATA_IN_HANDSHAKE			 100
179204642Srdivackydiff -upr openssl-0.9.8g.orig/ssl/ssl_err.c openssl-0.9.8g/ssl/ssl_err.c
180204642Srdivacky--- openssl-0.9.8g.orig/ssl/ssl_err.c	2007-10-11 17:36:59.000000000 +0300
181204642Srdivacky+++ openssl-0.9.8g/ssl/ssl_err.c	2008-04-15 17:10:37.000000000 +0300
182204642Srdivacky@@ -250,6 +250,7 @@ static ERR_STRING_DATA SSL_str_functs[]=
183204642Srdivacky {ERR_FUNC(SSL_F_TLS1_ENC),	"TLS1_ENC"},
184204642Srdivacky {ERR_FUNC(SSL_F_TLS1_SETUP_KEY_BLOCK),	"TLS1_SETUP_KEY_BLOCK"},
185204642Srdivacky {ERR_FUNC(SSL_F_WRITE_PENDING),	"WRITE_PENDING"},
186204642Srdivacky+{ERR_FUNC(SSL_F_SSL_SET_HELLO_EXTENSION), "SSL_set_hello_extension"},
187204642Srdivacky {0,NULL}
188203954Srdivacky 	};
189203954Srdivacky 
190203954Srdivackydiff -upr openssl-0.9.8g.orig/ssl/ssl_sess.c openssl-0.9.8g/ssl/ssl_sess.c
191203954Srdivacky--- openssl-0.9.8g.orig/ssl/ssl_sess.c	2007-10-19 10:36:34.000000000 +0300
192203954Srdivacky+++ openssl-0.9.8g/ssl/ssl_sess.c	2008-04-15 17:10:37.000000000 +0300
193203954Srdivacky@@ -704,6 +704,52 @@ long SSL_CTX_get_timeout(const SSL_CTX *
194203954Srdivacky 	return(s->session_timeout);
195203954Srdivacky 	}
196204642Srdivacky 
197204642Srdivacky+#ifndef OPENSSL_NO_TLSEXT
198204642Srdivacky+int SSL_set_session_secret_cb(SSL *s, int (*tls_session_secret_cb)(SSL *s, void *secret, int *secret_len, 
199204642Srdivacky+	STACK_OF(SSL_CIPHER) *peer_ciphers, SSL_CIPHER **cipher, void *arg), void *arg)
200204642Srdivacky+{
201204642Srdivacky+	if (s == NULL) return(0);
202204642Srdivacky+	s->tls_session_secret_cb = tls_session_secret_cb;
203204642Srdivacky+	s->tls_session_secret_cb_arg = arg;
204204642Srdivacky+	return(1);
205205218Srdivacky+}
206204642Srdivacky+
207204642Srdivacky+int SSL_set_hello_extension(SSL *s, int ext_type, void *ext_data, int ext_len)
208204642Srdivacky+{
209198090Srdivacky+	if(s->version >= TLS1_VERSION)
210193323Sed+	{
211198090Srdivacky+		if(s->tls_extension)
212198892Srdivacky+		{
213201360Srdivacky+			OPENSSL_free(s->tls_extension);
214201360Srdivacky+			s->tls_extension = NULL;
215201360Srdivacky+		}
216201360Srdivacky+
217193323Sed+		s->tls_extension = OPENSSL_malloc(sizeof(TLS_EXTENSION) + ext_len);
218195098Sed+		if(!s->tls_extension)
219199511Srdivacky+		{
220201360Srdivacky+			SSLerr(SSL_F_SSL_SET_HELLO_EXTENSION, ERR_R_MALLOC_FAILURE);
221201360Srdivacky+			return 0;
222195098Sed+		}
223195098Sed+
224212904Sdim+		s->tls_extension->type = ext_type;
225212904Sdim+
226212904Sdim+		if(ext_data)
227199511Srdivacky+		{
228201360Srdivacky+			s->tls_extension->length = ext_len;
229201360Srdivacky+			s->tls_extension->data = s->tls_extension + 1;
230212904Sdim+			memcpy(s->tls_extension->data, ext_data, ext_len);
231195098Sed+		} else {
232195098Sed+			s->tls_extension->length = 0;
233199511Srdivacky+			s->tls_extension->data = NULL;
234201360Srdivacky+		}
235201360Srdivacky+
236195098Sed+		return 1;
237198090Srdivacky+	}
238199511Srdivacky+
239201360Srdivacky+	return 0;
240201360Srdivacky+}
241198090Srdivacky+#endif /* OPENSSL_NO_TLSEXT */
242198090Srdivacky+
243198090Srdivacky typedef struct timeout_param_st
244201360Srdivacky 	{
245201360Srdivacky 	SSL_CTX *ctx;
246201360Srdivackydiff -upr openssl-0.9.8g.orig/ssl/t1_lib.c openssl-0.9.8g/ssl/t1_lib.c
247201360Srdivacky--- openssl-0.9.8g.orig/ssl/t1_lib.c	2007-10-19 10:44:10.000000000 +0300
248198090Srdivacky+++ openssl-0.9.8g/ssl/t1_lib.c	2008-04-15 17:10:37.000000000 +0300
249195098Sed@@ -105,6 +105,12 @@ int tls1_new(SSL *s)
250198090Srdivacky 
251201360Srdivacky void tls1_free(SSL *s)
252201360Srdivacky 	{
253201360Srdivacky+#ifndef OPENSSL_NO_TLSEXT
254201360Srdivacky+	if(s->tls_extension)
255201360Srdivacky+	{
256201360Srdivacky+		OPENSSL_free(s->tls_extension);
257195098Sed+	}
258193323Sed+#endif
259193323Sed 	ssl3_free(s);
260193323Sed 	}
261193323Sed 
262198090Srdivacky@@ -174,8 +180,24 @@ unsigned char *ssl_add_clienthello_tlsex
263201360Srdivacky 		int ticklen;
264201360Srdivacky 		if (s->session && s->session->tlsext_tick)
265201360Srdivacky 			ticklen = s->session->tlsext_ticklen;
266201360Srdivacky+		else if (s->session && s->tls_extension &&
267193323Sed+			s->tls_extension->type == TLSEXT_TYPE_session_ticket &&
268204642Srdivacky+			s->tls_extension->data)
269201360Srdivacky+		{
270193323Sed+			ticklen = s->tls_extension->length;
271193323Sed+			s->session->tlsext_tick = OPENSSL_malloc(ticklen);
272198892Srdivacky+			if (!s->session->tlsext_tick)
273198892Srdivacky+				return NULL;
274198892Srdivacky+			memcpy(s->session->tlsext_tick, s->tls_extension->data,
275201360Srdivacky+			       ticklen);
276202878Srdivacky+			s->session->tlsext_ticklen = ticklen;
277202375Srdivacky+		}
278201360Srdivacky 		else
279201360Srdivacky 			ticklen = 0;
280198892Srdivacky+		if (ticklen == 0 && s->tls_extension &&
281198892Srdivacky+		    s->tls_extension->type == TLSEXT_TYPE_session_ticket &&
282193323Sed+		    s->tls_extension->data == NULL)
283198090Srdivacky+			goto skip_ext;
284198090Srdivacky 		/* Check for enough room 2 for extension type, 2 for len
285205218Srdivacky  		 * rest for ticket
286205218Srdivacky   		 */
287201360Srdivacky@@ -189,6 +211,7 @@ unsigned char *ssl_add_clienthello_tlsex
288193323Sed 			ret += ticklen;
289193323Sed 			}
290198090Srdivacky 		}
291198090Srdivacky+		skip_ext:
292198090Srdivacky 
293198090Srdivacky 	if ((extdatalen = ret-p-2)== 0) 
294198090Srdivacky 		return p;
295201360Srdivacky@@ -543,6 +566,8 @@ int tls1_process_ticket(SSL *s, unsigned
296204642Srdivacky 				s->tlsext_ticket_expected = 1;
297201360Srdivacky 				return 0;	/* Cache miss */
298201360Srdivacky 				}
299198090Srdivacky+			if (s->tls_session_secret_cb)
300198090Srdivacky+				return 0;
301198090Srdivacky 			return tls_decrypt_ticket(s, p, size, session_id, len,
302201360Srdivacky 									ret);
303204642Srdivacky 			}
304201360Srdivackydiff -upr openssl-0.9.8g.orig/ssl/tls1.h openssl-0.9.8g/ssl/tls1.h
305201360Srdivacky--- openssl-0.9.8g.orig/ssl/tls1.h	2007-08-28 04:12:44.000000000 +0300
306198090Srdivacky+++ openssl-0.9.8g/ssl/tls1.h	2008-04-15 17:10:37.000000000 +0300
307198090Srdivacky@@ -365,6 +365,14 @@ SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TLSEXT_SER
308198090Srdivacky #define TLS_MD_MASTER_SECRET_CONST    "\x6d\x61\x73\x74\x65\x72\x20\x73\x65\x63\x72\x65\x74"  /*master secret*/
309204642Srdivacky #endif
310198892Srdivacky 
311198090Srdivacky+/* TLS extension struct */
312201360Srdivacky+struct tls_extension_st
313201360Srdivacky+{
314198090Srdivacky+	unsigned short type;
315193323Sed+	unsigned short length;
316201360Srdivacky+	void *data;
317204642Srdivacky+};
318198892Srdivacky+
319198090Srdivacky #ifdef  __cplusplus
320198090Srdivacky }
321193323Sed #endif
322193323Seddiff -upr openssl-0.9.8g.orig/util/ssleay.num openssl-0.9.8g/util/ssleay.num
323198090Srdivacky--- openssl-0.9.8g.orig/util/ssleay.num	2007-08-13 01:31:16.000000000 +0300
324198090Srdivacky+++ openssl-0.9.8g/util/ssleay.num	2008-04-15 17:10:37.000000000 +0300
325198090Srdivacky@@ -241,3 +241,5 @@ SSL_CTX_sess_get_remove_cb              
326198090Srdivacky SSL_set_SSL_CTX                         290	EXIST::FUNCTION:
327198090Srdivacky SSL_get_servername                      291	EXIST::FUNCTION:TLSEXT
328198090Srdivacky SSL_get_servername_type                 292	EXIST::FUNCTION:TLSEXT
329198090Srdivacky+SSL_set_hello_extension			305	EXIST::FUNCTION:TLSEXT
330201360Srdivacky+SSL_set_session_secret_cb		306	EXIST::FUNCTION:TLSEXT
331204642Srdivacky