t1_lib.c revision 194206
1/* ssl/t1_lib.c */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved.
4 *
5 * This package is an SSL implementation written
6 * by Eric Young (eay@cryptsoft.com).
7 * The implementation was written so as to conform with Netscapes SSL.
8 *
9 * This library is free for commercial and non-commercial use as long as
10 * the following conditions are aheared to.  The following conditions
11 * apply to all code found in this distribution, be it the RC4, RSA,
12 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
13 * included with this distribution is covered by the same copyright terms
14 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 *
16 * Copyright remains Eric Young's, and as such any Copyright notices in
17 * the code are not to be removed.
18 * If this package is used in a product, Eric Young should be given attribution
19 * as the author of the parts of the library used.
20 * This can be in the form of a textual message at program startup or
21 * in documentation (online or textual) provided with the package.
22 *
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
25 * are met:
26 * 1. Redistributions of source code must retain the copyright
27 *    notice, this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright
29 *    notice, this list of conditions and the following disclaimer in the
30 *    documentation and/or other materials provided with the distribution.
31 * 3. All advertising materials mentioning features or use of this software
32 *    must display the following acknowledgement:
33 *    "This product includes cryptographic software written by
34 *     Eric Young (eay@cryptsoft.com)"
35 *    The word 'cryptographic' can be left out if the rouines from the library
36 *    being used are not cryptographic related :-).
37 * 4. If you include any Windows specific code (or a derivative thereof) from
38 *    the apps directory (application code) you must include an acknowledgement:
39 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 *
41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 * SUCH DAMAGE.
52 *
53 * The licence and distribution terms for any publically available version or
54 * derivative of this code cannot be changed.  i.e. this code cannot simply be
55 * copied and put under another distribution licence
56 * [including the GNU Public Licence.]
57 */
58
59#include <stdio.h>
60#include <openssl/objects.h>
61#include <openssl/evp.h>
62#include <openssl/hmac.h>
63#include <openssl/ocsp.h>
64#include "ssl_locl.h"
65
66const char tls1_version_str[]="TLSv1" OPENSSL_VERSION_PTEXT;
67
68#ifndef OPENSSL_NO_TLSEXT
69static int tls_decrypt_ticket(SSL *s, const unsigned char *tick, int ticklen,
70				const unsigned char *sess_id, int sesslen,
71				SSL_SESSION **psess);
72#endif
73
74SSL3_ENC_METHOD TLSv1_enc_data={
75	tls1_enc,
76	tls1_mac,
77	tls1_setup_key_block,
78	tls1_generate_master_secret,
79	tls1_change_cipher_state,
80	tls1_final_finish_mac,
81	TLS1_FINISH_MAC_LENGTH,
82	tls1_cert_verify_mac,
83	TLS_MD_CLIENT_FINISH_CONST,TLS_MD_CLIENT_FINISH_CONST_SIZE,
84	TLS_MD_SERVER_FINISH_CONST,TLS_MD_SERVER_FINISH_CONST_SIZE,
85	tls1_alert_code,
86	};
87
88long tls1_default_timeout(void)
89	{
90	/* 2 hours, the 24 hours mentioned in the TLSv1 spec
91	 * is way too long for http, the cache would over fill */
92	return(60*60*2);
93	}
94
95IMPLEMENT_tls1_meth_func(tlsv1_base_method,
96			ssl_undefined_function,
97			ssl_undefined_function,
98			ssl_bad_method)
99
100int tls1_new(SSL *s)
101	{
102	if (!ssl3_new(s)) return(0);
103	s->method->ssl_clear(s);
104	return(1);
105	}
106
107void tls1_free(SSL *s)
108	{
109	ssl3_free(s);
110	}
111
112void tls1_clear(SSL *s)
113	{
114	ssl3_clear(s);
115	s->version=TLS1_VERSION;
116	}
117
118#if 0
119long tls1_ctrl(SSL *s, int cmd, long larg, char *parg)
120	{
121	return(0);
122	}
123
124long tls1_callback_ctrl(SSL *s, int cmd, void *(*fp)())
125	{
126	return(0);
127	}
128#endif
129
130#ifndef OPENSSL_NO_TLSEXT
131unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned char *limit)
132	{
133	int extdatalen=0;
134	unsigned char *ret = p;
135
136	ret+=2;
137
138	if (ret>=limit) return NULL; /* this really never occurs, but ... */
139
140 	if (s->tlsext_hostname != NULL)
141		{
142		/* Add TLS extension servername to the Client Hello message */
143		unsigned long size_str;
144		long lenmax;
145
146		/* check for enough space.
147		   4 for the servername type and entension length
148		   2 for servernamelist length
149		   1 for the hostname type
150		   2 for hostname length
151		   + hostname length
152		*/
153
154		if ((lenmax = limit - ret - 9) < 0
155		|| (size_str = strlen(s->tlsext_hostname)) > (unsigned long)lenmax)
156			return NULL;
157
158		/* extension type and length */
159		s2n(TLSEXT_TYPE_server_name,ret);
160		s2n(size_str+5,ret);
161
162		/* length of servername list */
163		s2n(size_str+3,ret);
164
165		/* hostname type, length and hostname */
166		*(ret++) = (unsigned char) TLSEXT_NAMETYPE_host_name;
167		s2n(size_str,ret);
168		memcpy(ret, s->tlsext_hostname, size_str);
169		ret+=size_str;
170
171		}
172
173	if (!(SSL_get_options(s) & SSL_OP_NO_TICKET))
174		{
175		int ticklen;
176		if (s->session && s->session->tlsext_tick)
177			ticklen = s->session->tlsext_ticklen;
178		else
179			ticklen = 0;
180		/* Check for enough room 2 for extension type, 2 for len
181 		 * rest for ticket
182  		 */
183		if (limit - ret - 4 - ticklen < 0)
184			return NULL;
185		s2n(TLSEXT_TYPE_session_ticket,ret);
186		s2n(ticklen,ret);
187		if (ticklen)
188			{
189			memcpy(ret, s->session->tlsext_tick, ticklen);
190			ret += ticklen;
191			}
192		}
193
194	if (s->tlsext_status_type == TLSEXT_STATUSTYPE_ocsp)
195		{
196		int i;
197		long extlen, idlen, itmp;
198		OCSP_RESPID *id;
199
200		idlen = 0;
201		for (i = 0; i < sk_OCSP_RESPID_num(s->tlsext_ocsp_ids); i++)
202			{
203			id = sk_OCSP_RESPID_value(s->tlsext_ocsp_ids, i);
204			itmp = i2d_OCSP_RESPID(id, NULL);
205			if (itmp <= 0)
206				return NULL;
207			idlen += itmp + 2;
208			}
209
210		if (s->tlsext_ocsp_exts)
211			{
212			extlen = i2d_X509_EXTENSIONS(s->tlsext_ocsp_exts, NULL);
213			if (extlen < 0)
214				return NULL;
215			}
216		else
217			extlen = 0;
218
219		if ((long)(limit - ret - 7 - extlen - idlen) < 0) return NULL;
220		s2n(TLSEXT_TYPE_status_request, ret);
221		if (extlen + idlen > 0xFFF0)
222			return NULL;
223		s2n(extlen + idlen + 5, ret);
224		*(ret++) = TLSEXT_STATUSTYPE_ocsp;
225		s2n(idlen, ret);
226		for (i = 0; i < sk_OCSP_RESPID_num(s->tlsext_ocsp_ids); i++)
227			{
228			/* save position of id len */
229			unsigned char *q = ret;
230			id = sk_OCSP_RESPID_value(s->tlsext_ocsp_ids, i);
231			/* skip over id len */
232			ret += 2;
233			itmp = i2d_OCSP_RESPID(id, &ret);
234			/* write id len */
235			s2n(itmp, q);
236			}
237		s2n(extlen, ret);
238		if (extlen > 0)
239			i2d_X509_EXTENSIONS(s->tlsext_ocsp_exts, &ret);
240		}
241
242	if ((extdatalen = ret-p-2)== 0)
243		return p;
244
245	s2n(extdatalen,p);
246	return ret;
247	}
248
249unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned char *limit)
250	{
251	int extdatalen=0;
252	unsigned char *ret = p;
253
254	ret+=2;
255	if (ret>=limit) return NULL; /* this really never occurs, but ... */
256
257	if (!s->hit && s->servername_done == 1 && s->session->tlsext_hostname != NULL)
258		{
259		if (limit - ret - 4 < 0) return NULL;
260
261		s2n(TLSEXT_TYPE_server_name,ret);
262		s2n(0,ret);
263		}
264
265	if (s->tlsext_ticket_expected
266		&& !(SSL_get_options(s) & SSL_OP_NO_TICKET))
267		{
268		if (limit - ret - 4 < 0) return NULL;
269		s2n(TLSEXT_TYPE_session_ticket,ret);
270		s2n(0,ret);
271		}
272
273	if (s->tlsext_status_expected)
274		{
275		if ((long)(limit - ret - 4) < 0) return NULL;
276		s2n(TLSEXT_TYPE_status_request,ret);
277		s2n(0,ret);
278		}
279
280	if ((extdatalen = ret-p-2)== 0)
281		return p;
282
283	s2n(extdatalen,p);
284	return ret;
285	}
286
287int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, int n, int *al)
288	{
289	unsigned short type;
290	unsigned short size;
291	unsigned short len;
292	unsigned char *data = *p;
293	s->servername_done = 0;
294	s->tlsext_status_type = -1;
295
296	if (data >= (d+n-2))
297		return 1;
298	n2s(data,len);
299
300	if (data > (d+n-len))
301		return 1;
302
303	while (data <= (d+n-4))
304		{
305		n2s(data,type);
306		n2s(data,size);
307
308		if (data+size > (d+n))
309	   		return 1;
310
311		if (s->tlsext_debug_cb)
312			s->tlsext_debug_cb(s, 0, type, data, size,
313						s->tlsext_debug_arg);
314/* The servername extension is treated as follows:
315
316   - Only the hostname type is supported with a maximum length of 255.
317   - The servername is rejected if too long or if it contains zeros,
318     in which case an fatal alert is generated.
319   - The servername field is maintained together with the session cache.
320   - When a session is resumed, the servername call back invoked in order
321     to allow the application to position itself to the right context.
322   - The servername is acknowledged if it is new for a session or when
323     it is identical to a previously used for the same session.
324     Applications can control the behaviour.  They can at any time
325     set a 'desirable' servername for a new SSL object. This can be the
326     case for example with HTTPS when a Host: header field is received and
327     a renegotiation is requested. In this case, a possible servername
328     presented in the new client hello is only acknowledged if it matches
329     the value of the Host: field.
330   - Applications must  use SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION
331     if they provide for changing an explicit servername context for the session,
332     i.e. when the session has been established with a servername extension.
333   - On session reconnect, the servername extension may be absent.
334
335*/
336
337		if (type == TLSEXT_TYPE_server_name)
338			{
339			unsigned char *sdata;
340			int servname_type;
341			int dsize;
342
343			if (size < 2)
344				{
345				*al = SSL_AD_DECODE_ERROR;
346				return 0;
347				}
348			n2s(data,dsize);
349			size -= 2;
350			if (dsize > size  )
351				{
352				*al = SSL_AD_DECODE_ERROR;
353				return 0;
354				}
355
356			sdata = data;
357			while (dsize > 3)
358				{
359	 			servname_type = *(sdata++);
360				n2s(sdata,len);
361				dsize -= 3;
362
363				if (len > dsize)
364					{
365					*al = SSL_AD_DECODE_ERROR;
366					return 0;
367					}
368				if (s->servername_done == 0)
369				switch (servname_type)
370					{
371				case TLSEXT_NAMETYPE_host_name:
372					if (s->session->tlsext_hostname == NULL)
373						{
374						if (len > TLSEXT_MAXLEN_host_name ||
375							((s->session->tlsext_hostname = OPENSSL_malloc(len+1)) == NULL))
376							{
377							*al = TLS1_AD_UNRECOGNIZED_NAME;
378							return 0;
379							}
380						memcpy(s->session->tlsext_hostname, sdata, len);
381						s->session->tlsext_hostname[len]='\0';
382						if (strlen(s->session->tlsext_hostname) != len) {
383							OPENSSL_free(s->session->tlsext_hostname);
384							s->session->tlsext_hostname = NULL;
385							*al = TLS1_AD_UNRECOGNIZED_NAME;
386							return 0;
387						}
388						s->servername_done = 1;
389
390						}
391					else
392						s->servername_done = strlen(s->session->tlsext_hostname) == len
393							&& strncmp(s->session->tlsext_hostname, (char *)sdata, len) == 0;
394
395					break;
396
397				default:
398					break;
399					}
400
401				dsize -= len;
402				}
403			if (dsize != 0)
404				{
405				*al = SSL_AD_DECODE_ERROR;
406				return 0;
407				}
408
409			}
410		else if (type == TLSEXT_TYPE_status_request
411						&& s->ctx->tlsext_status_cb)
412			{
413
414			if (size < 5)
415				{
416				*al = SSL_AD_DECODE_ERROR;
417				return 0;
418				}
419
420			s->tlsext_status_type = *data++;
421			size--;
422			if (s->tlsext_status_type == TLSEXT_STATUSTYPE_ocsp)
423				{
424				const unsigned char *sdata;
425				int dsize;
426				/* Read in responder_id_list */
427				n2s(data,dsize);
428				size -= 2;
429				if (dsize > size  )
430					{
431					*al = SSL_AD_DECODE_ERROR;
432					return 0;
433					}
434				while (dsize > 0)
435					{
436					OCSP_RESPID *id;
437					int idsize;
438					if (dsize < 4)
439						{
440						*al = SSL_AD_DECODE_ERROR;
441						return 0;
442						}
443					n2s(data, idsize);
444					dsize -= 2 + idsize;
445					if (dsize < 0)
446						{
447						*al = SSL_AD_DECODE_ERROR;
448						return 0;
449						}
450					sdata = data;
451					data += idsize;
452					id = d2i_OCSP_RESPID(NULL,
453								&sdata, idsize);
454					if (!id)
455						{
456						*al = SSL_AD_DECODE_ERROR;
457						return 0;
458						}
459					if (data != sdata)
460						{
461						OCSP_RESPID_free(id);
462						*al = SSL_AD_DECODE_ERROR;
463						return 0;
464						}
465					if (!s->tlsext_ocsp_ids
466						&& !(s->tlsext_ocsp_ids =
467						sk_OCSP_RESPID_new_null()))
468						{
469						OCSP_RESPID_free(id);
470						*al = SSL_AD_INTERNAL_ERROR;
471						return 0;
472						}
473					if (!sk_OCSP_RESPID_push(
474							s->tlsext_ocsp_ids, id))
475						{
476						OCSP_RESPID_free(id);
477						*al = SSL_AD_INTERNAL_ERROR;
478						return 0;
479						}
480					}
481
482				/* Read in request_extensions */
483				n2s(data,dsize);
484				size -= 2;
485				if (dsize > size)
486					{
487					*al = SSL_AD_DECODE_ERROR;
488					return 0;
489					}
490				sdata = data;
491				if (dsize > 0)
492					{
493					s->tlsext_ocsp_exts =
494						d2i_X509_EXTENSIONS(NULL,
495							&sdata, dsize);
496					if (!s->tlsext_ocsp_exts
497						|| (data + dsize != sdata))
498						{
499						*al = SSL_AD_DECODE_ERROR;
500						return 0;
501						}
502					}
503				}
504				/* We don't know what to do with any other type
505 			 	* so ignore it.
506 			 	*/
507				else
508					s->tlsext_status_type = -1;
509			}
510		/* session ticket processed earlier */
511
512		data+=size;
513		}
514
515	*p = data;
516	return 1;
517	}
518
519int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char *d, int n, int *al)
520	{
521	unsigned short type;
522	unsigned short size;
523	unsigned short len;
524	unsigned char *data = *p;
525
526	int tlsext_servername = 0;
527
528	if (data >= (d+n-2))
529		return 1;
530
531	n2s(data,len);
532
533	while(data <= (d+n-4))
534		{
535		n2s(data,type);
536		n2s(data,size);
537
538		if (data+size > (d+n))
539	   		return 1;
540
541		if (s->tlsext_debug_cb)
542			s->tlsext_debug_cb(s, 1, type, data, size,
543						s->tlsext_debug_arg);
544
545		if (type == TLSEXT_TYPE_server_name)
546			{
547			if (s->tlsext_hostname == NULL || size > 0)
548				{
549				*al = TLS1_AD_UNRECOGNIZED_NAME;
550				return 0;
551				}
552			tlsext_servername = 1;
553			}
554		else if (type == TLSEXT_TYPE_session_ticket)
555			{
556			if ((SSL_get_options(s) & SSL_OP_NO_TICKET)
557				|| (size > 0))
558				{
559				*al = TLS1_AD_UNSUPPORTED_EXTENSION;
560				return 0;
561				}
562			s->tlsext_ticket_expected = 1;
563			}
564		else if (type == TLSEXT_TYPE_status_request)
565			{
566			/* MUST be empty and only sent if we've requested
567			 * a status request message.
568			 */
569			if ((s->tlsext_status_type == -1) || (size > 0))
570				{
571				*al = TLS1_AD_UNSUPPORTED_EXTENSION;
572				return 0;
573				}
574			/* Set flag to expect CertificateStatus message */
575			s->tlsext_status_expected = 1;
576			}
577
578		data+=size;
579		}
580
581	if (data != d+n)
582		{
583		*al = SSL_AD_DECODE_ERROR;
584		return 0;
585		}
586
587	if (!s->hit && tlsext_servername == 1)
588		{
589 		if (s->tlsext_hostname)
590			{
591			if (s->session->tlsext_hostname == NULL)
592				{
593				s->session->tlsext_hostname = BUF_strdup(s->tlsext_hostname);
594				if (!s->session->tlsext_hostname)
595					{
596					*al = SSL_AD_UNRECOGNIZED_NAME;
597					return 0;
598					}
599				}
600			else
601				{
602				*al = SSL_AD_DECODE_ERROR;
603				return 0;
604				}
605			}
606		}
607
608	*p = data;
609	return 1;
610	}
611
612int ssl_check_clienthello_tlsext(SSL *s)
613	{
614	int ret=SSL_TLSEXT_ERR_NOACK;
615	int al = SSL_AD_UNRECOGNIZED_NAME;
616
617	if (s->ctx != NULL && s->ctx->tlsext_servername_callback != 0)
618		ret = s->ctx->tlsext_servername_callback(s, &al, s->ctx->tlsext_servername_arg);
619	else if (s->initial_ctx != NULL && s->initial_ctx->tlsext_servername_callback != 0)
620		ret = s->initial_ctx->tlsext_servername_callback(s, &al, s->initial_ctx->tlsext_servername_arg);
621
622	/* If status request then ask callback what to do.
623 	 * Note: this must be called after servername callbacks in case
624 	 * the certificate has changed.
625 	 */
626	if ((s->tlsext_status_type != -1) && s->ctx->tlsext_status_cb)
627		{
628		int r;
629		r = s->ctx->tlsext_status_cb(s, s->ctx->tlsext_status_arg);
630		switch (r)
631			{
632			/* We don't want to send a status request response */
633			case SSL_TLSEXT_ERR_NOACK:
634				s->tlsext_status_expected = 0;
635				break;
636			/* status request response should be sent */
637			case SSL_TLSEXT_ERR_OK:
638				if (s->tlsext_ocsp_resp)
639					s->tlsext_status_expected = 1;
640				else
641					s->tlsext_status_expected = 0;
642				break;
643			/* something bad happened */
644			case SSL_TLSEXT_ERR_ALERT_FATAL:
645				ret = SSL_TLSEXT_ERR_ALERT_FATAL;
646				al = SSL_AD_INTERNAL_ERROR;
647				goto err;
648			}
649		}
650	else
651		s->tlsext_status_expected = 0;
652	err:
653	switch (ret)
654		{
655		case SSL_TLSEXT_ERR_ALERT_FATAL:
656			ssl3_send_alert(s,SSL3_AL_FATAL,al);
657			return -1;
658
659		case SSL_TLSEXT_ERR_ALERT_WARNING:
660			ssl3_send_alert(s,SSL3_AL_WARNING,al);
661			return 1;
662
663		case SSL_TLSEXT_ERR_NOACK:
664			s->servername_done=0;
665			default:
666		return 1;
667		}
668	}
669
670int ssl_check_serverhello_tlsext(SSL *s)
671	{
672	int ret=SSL_TLSEXT_ERR_NOACK;
673	int al = SSL_AD_UNRECOGNIZED_NAME;
674
675	if (s->ctx != NULL && s->ctx->tlsext_servername_callback != 0)
676		ret = s->ctx->tlsext_servername_callback(s, &al, s->ctx->tlsext_servername_arg);
677	else if (s->initial_ctx != NULL && s->initial_ctx->tlsext_servername_callback != 0)
678		ret = s->initial_ctx->tlsext_servername_callback(s, &al, s->initial_ctx->tlsext_servername_arg);
679
680	/* If we've requested certificate status and we wont get one
681 	 * tell the callback
682 	 */
683	if ((s->tlsext_status_type != -1) && !(s->tlsext_status_expected)
684			&& s->ctx->tlsext_status_cb)
685		{
686		int r;
687		/* Set resp to NULL, resplen to -1 so callback knows
688 		 * there is no response.
689 		 */
690		if (s->tlsext_ocsp_resp)
691			{
692			OPENSSL_free(s->tlsext_ocsp_resp);
693			s->tlsext_ocsp_resp = NULL;
694			}
695		s->tlsext_ocsp_resplen = -1;
696		r = s->ctx->tlsext_status_cb(s, s->ctx->tlsext_status_arg);
697		if (r == 0)
698			{
699			al = SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE;
700			ret = SSL_TLSEXT_ERR_ALERT_FATAL;
701			}
702		if (r < 0)
703			{
704			al = SSL_AD_INTERNAL_ERROR;
705			ret = SSL_TLSEXT_ERR_ALERT_FATAL;
706			}
707		}
708
709	switch (ret)
710		{
711		case SSL_TLSEXT_ERR_ALERT_FATAL:
712			ssl3_send_alert(s,SSL3_AL_FATAL,al);
713			return -1;
714
715		case SSL_TLSEXT_ERR_ALERT_WARNING:
716			ssl3_send_alert(s,SSL3_AL_WARNING,al);
717			return 1;
718
719		case SSL_TLSEXT_ERR_NOACK:
720			s->servername_done=0;
721			default:
722		return 1;
723		}
724	}
725
726/* Since the server cache lookup is done early on in the processing of client
727 * hello and other operations depend on the result we need to handle any TLS
728 * session ticket extension at the same time.
729 */
730
731int tls1_process_ticket(SSL *s, unsigned char *session_id, int len,
732				const unsigned char *limit, SSL_SESSION **ret)
733	{
734	/* Point after session ID in client hello */
735	const unsigned char *p = session_id + len;
736	unsigned short i;
737
738	/* If tickets disabled behave as if no ticket present
739 	 * to permit stateful resumption.
740 	 */
741	if (SSL_get_options(s) & SSL_OP_NO_TICKET)
742		return 1;
743
744	if ((s->version <= SSL3_VERSION) || !limit)
745		return 1;
746	if (p >= limit)
747		return -1;
748	/* Skip past cipher list */
749	n2s(p, i);
750	p+= i;
751	if (p >= limit)
752		return -1;
753	/* Skip past compression algorithm list */
754	i = *(p++);
755	p += i;
756	if (p > limit)
757		return -1;
758	/* Now at start of extensions */
759	if ((p + 2) >= limit)
760		return 1;
761	n2s(p, i);
762	while ((p + 4) <= limit)
763		{
764		unsigned short type, size;
765		n2s(p, type);
766		n2s(p, size);
767		if (p + size > limit)
768			return 1;
769		if (type == TLSEXT_TYPE_session_ticket)
770			{
771			/* If zero length note client will accept a ticket
772 			 * and indicate cache miss to trigger full handshake
773 			 */
774			if (size == 0)
775				{
776				s->tlsext_ticket_expected = 1;
777				return 0;	/* Cache miss */
778				}
779			return tls_decrypt_ticket(s, p, size, session_id, len,
780									ret);
781			}
782		p += size;
783		}
784	return 1;
785	}
786
787static int tls_decrypt_ticket(SSL *s, const unsigned char *etick, int eticklen,
788				const unsigned char *sess_id, int sesslen,
789				SSL_SESSION **psess)
790	{
791	SSL_SESSION *sess;
792	unsigned char *sdec;
793	const unsigned char *p;
794	int slen, mlen, renew_ticket = 0;
795	unsigned char tick_hmac[EVP_MAX_MD_SIZE];
796	HMAC_CTX hctx;
797	EVP_CIPHER_CTX ctx;
798	/* Need at least keyname + iv + some encrypted data */
799	if (eticklen < 48)
800		goto tickerr;
801	/* Initialize session ticket encryption and HMAC contexts */
802	HMAC_CTX_init(&hctx);
803	EVP_CIPHER_CTX_init(&ctx);
804	if (s->ctx->tlsext_ticket_key_cb)
805		{
806		unsigned char *nctick = (unsigned char *)etick;
807		int rv = s->ctx->tlsext_ticket_key_cb(s, nctick, nctick + 16,
808							&ctx, &hctx, 0);
809		if (rv < 0)
810			return -1;
811		if (rv == 0)
812			goto tickerr;
813		if (rv == 2)
814			renew_ticket = 1;
815		}
816	else
817		{
818		/* Check key name matches */
819		if (memcmp(etick, s->ctx->tlsext_tick_key_name, 16))
820			goto tickerr;
821		HMAC_Init_ex(&hctx, s->ctx->tlsext_tick_hmac_key, 16,
822					tlsext_tick_md(), NULL);
823		EVP_DecryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL,
824				s->ctx->tlsext_tick_aes_key, etick + 16);
825		}
826	/* Attempt to process session ticket, first conduct sanity and
827 	 * integrity checks on ticket.
828 	 */
829	mlen = HMAC_size(&hctx);
830	eticklen -= mlen;
831	/* Check HMAC of encrypted ticket */
832	HMAC_Update(&hctx, etick, eticklen);
833	HMAC_Final(&hctx, tick_hmac, NULL);
834	HMAC_CTX_cleanup(&hctx);
835	if (memcmp(tick_hmac, etick + eticklen, mlen))
836		goto tickerr;
837	/* Attempt to decrypt session data */
838	/* Move p after IV to start of encrypted ticket, update length */
839	p = etick + 16 + EVP_CIPHER_CTX_iv_length(&ctx);
840	eticklen -= 16 + EVP_CIPHER_CTX_iv_length(&ctx);
841	sdec = OPENSSL_malloc(eticklen);
842	if (!sdec)
843		{
844		EVP_CIPHER_CTX_cleanup(&ctx);
845		return -1;
846		}
847	EVP_DecryptUpdate(&ctx, sdec, &slen, p, eticklen);
848	if (EVP_DecryptFinal(&ctx, sdec + slen, &mlen) <= 0)
849		goto tickerr;
850	slen += mlen;
851	EVP_CIPHER_CTX_cleanup(&ctx);
852	p = sdec;
853
854	sess = d2i_SSL_SESSION(NULL, &p, slen);
855	OPENSSL_free(sdec);
856	if (sess)
857		{
858		/* The session ID if non-empty is used by some clients to
859 		 * detect that the ticket has been accepted. So we copy it to
860 		 * the session structure. If it is empty set length to zero
861 		 * as required by standard.
862 		 */
863		if (sesslen)
864			memcpy(sess->session_id, sess_id, sesslen);
865		sess->session_id_length = sesslen;
866		*psess = sess;
867		s->tlsext_ticket_expected = renew_ticket;
868		return 1;
869		}
870	/* If session decrypt failure indicate a cache miss and set state to
871 	 * send a new ticket
872 	 */
873	tickerr:
874	s->tlsext_ticket_expected = 1;
875	return 0;
876	}
877
878#endif
879