t1_lib.c 12.5 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
/* ssl/t1_lib.c */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
 * All rights reserved.
 *
 * This package is an SSL implementation written
 * by Eric Young (eay@cryptsoft.com).
 * The implementation was written so as to conform with Netscapes SSL.
 * 
 * This library is free for commercial and non-commercial use as long as
 * the following conditions are aheared to.  The following conditions
 * apply to all code found in this distribution, be it the RC4, RSA,
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
 * included with this distribution is covered by the same copyright terms
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
 * 
 * Copyright remains Eric Young's, and as such any Copyright notices in
 * the code are not to be removed.
 * If this package is used in a product, Eric Young should be given attribution
 * as the author of the parts of the library used.
 * This can be in the form of a textual message at program startup or
 * in documentation (online or textual) provided with the package.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *    "This product includes cryptographic software written by
 *     Eric Young (eay@cryptsoft.com)"
 *    The word 'cryptographic' can be left out if the rouines from the library
 *    being used are not cryptographic related :-).
 * 4. If you include any Windows specific code (or a derivative thereof) from 
 *    the apps directory (application code) you must include an acknowledgement:
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
 * 
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * 
 * The licence and distribution terms for any publically available version or
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
 * copied and put under another distribution licence
 * [including the GNU Public Licence.]
 */
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
/* ====================================================================
 * Copyright (c) 1998-2006 The OpenSSL Project.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer. 
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. All advertising materials mentioning features or use of this
 *    software must display the following acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
 *
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
 *    endorse or promote products derived from this software without
 *    prior written permission. For written permission, please contact
 *    openssl-core@openssl.org.
 *
 * 5. Products derived from this software may not be called "OpenSSL"
 *    nor may "OpenSSL" appear in their names without prior written
 *    permission of the OpenSSL Project.
 *
 * 6. Redistributions of any form whatsoever must retain the following
 *    acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
 *
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 * ====================================================================
 *
 * This product includes cryptographic software written by Eric Young
 * (eay@cryptsoft.com).  This product includes software written by Tim
 * Hudson (tjh@cryptsoft.com).
 *
 */
111 112

#include <stdio.h>
113
#include <openssl/objects.h>
114 115
#include "ssl_locl.h"

116
const char *tls1_version_str="TLSv1" OPENSSL_VERSION_PTEXT;
117

118
SSL3_ENC_METHOD TLSv1_enc_data={
119 120 121 122 123 124 125 126 127 128 129 130 131
	tls1_enc,
	tls1_mac,
	tls1_setup_key_block,
	tls1_generate_master_secret,
	tls1_change_cipher_state,
	tls1_final_finish_mac,
	TLS1_FINISH_MAC_LENGTH,
	tls1_cert_verify_mac,
	TLS_MD_CLIENT_FINISH_CONST,TLS_MD_CLIENT_FINISH_CONST_SIZE,
	TLS_MD_SERVER_FINISH_CONST,TLS_MD_SERVER_FINISH_CONST_SIZE,
	tls1_alert_code,
	};

132
long tls1_default_timeout(void)
133 134 135 136 137 138
	{
	/* 2 hours, the 24 hours mentioned in the TLSv1 spec
	 * is way too long for http, the cache would over fill */
	return(60*60*2);
	}

U
Ulf Möller 已提交
139
int tls1_new(SSL *s)
140 141 142 143 144 145
	{
	if (!ssl3_new(s)) return(0);
	s->method->ssl_clear(s);
	return(1);
	}

U
Ulf Möller 已提交
146
void tls1_free(SSL *s)
147 148 149 150
	{
	ssl3_free(s);
	}

U
Ulf Möller 已提交
151
void tls1_clear(SSL *s)
152 153 154 155 156
	{
	ssl3_clear(s);
	s->version=TLS1_VERSION;
	}

157

158
#ifndef OPENSSL_NO_TLSEXT
159 160
unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned char *limit)
	{
161 162 163 164 165 166
	int extdatalen=0;
	unsigned char *ret = p;

	ret+=2;

	if (ret>=limit) return NULL; /* this really never occurs, but ... */
167 168
 	if (s->servername_done == 0 && s->tlsext_hostname != NULL)
		{ 
169 170 171 172 173 174
		/* Add TLS extension servername to the Client Hello message */
		unsigned long size_str;
		long lenmax; 

		if ((lenmax = limit - p - 7) < 0) return NULL; 
		if ((size_str = strlen(s->tlsext_hostname)) > (unsigned long)lenmax) return NULL;
175
		
176 177
		s2n(TLSEXT_TYPE_server_name,ret);
		s2n(size_str+3,ret);
178
		*(ret++) = (unsigned char) TLSEXT_NAMETYPE_host_name;
179 180 181 182
		s2n(size_str,ret);
	
		memcpy(ret, s->tlsext_hostname, size_str);
		ret+=size_str;
183
		}
184

185 186 187 188 189 190 191
	if ((extdatalen = ret-p-2)== 0) 
		return p;

	s2n(extdatalen,p);
	return ret;
}

192 193
unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned char *limit)
	{
194 195 196
	int extdatalen=0;
	unsigned char *ret = p;

B
Bodo Möller 已提交
197
	ret+=2;
198 199
	if (ret>=limit) return NULL; /* this really never occurs, but ... */

B
Bodo Möller 已提交
200
	if (!s->hit && s->servername_done == 1 && s->session->tlsext_hostname != NULL)
201
		{ 
202 203 204 205
		if (limit - p - 4 < 0) return NULL; 

		s2n(TLSEXT_TYPE_server_name,ret);
		s2n(0,ret);
206
		}
207 208 209 210 211 212 213 214
	
	if ((extdatalen = ret-p-2)== 0) 
		return p;

	s2n(extdatalen,p);
	return ret;
}

215 216
int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, int n, int *al)
	{
217 218 219
	unsigned short type;
	unsigned short size;
	unsigned short len;
220
	unsigned char *data = *p;
B
Bodo Möller 已提交
221 222 223 224
#if 0
	fprintf(stderr,"ssl_parse_clienthello_tlsext %s\n",s->session->tlsext_hostname?s->session->tlsext_hostname:"NULL");
#endif
	s->servername_done = 0;
225 226

	if (data >= (d+n-2))
227
		return 1;
228 229 230
	n2s(data,len);

        if (data > (d+n-len)) 
231
		return 1;
232

233 234
	while (data <= (d+n-4))
		{
235 236 237 238
		n2s(data,type);
		n2s(data,size);

		if (data+size > (d+n))
239 240
	   		return 1;
		
B
Bodo Möller 已提交
241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263
/* The servername extension is treated as follows:

   - Only the hostname type is supported with a maximum length of 255.
   - The servername is rejected if too long or if it contains zeros,
     in which case an fatal alert is generated.
   - The servername field is maintained together with the session cache.
   - When a session is resumed, the servername call back invoked in order
     to allow the application to position itself to the right context. 
   - The servername is acknowledged if it is new for a session or when 
     it is identical to a previously used for the same session. 
     Applications can control the behaviour.  They can at any time
     set a 'desirable' servername for a new SSL object. This can be the
     case for example with HTTPS when a Host: header field is received and
     a renegotiation is requested. In this case, a possible servername
     presented in the new client hello is only acknowledged if it matches
     the value of the Host: field. 
   - Applications must  use SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION
     if they provide for changing an explicit servername context for the session,
     i.e. when the session has been established with a servername extension. 
   - On session reconnect, the servername extension may be absent. 

*/      

264 265
		if (type == TLSEXT_TYPE_server_name)
			{
266 267 268 269
			unsigned char *sdata = data;
			int servname_type;
			int dsize = size-3 ;
                        
270 271
			if (dsize > 0 )
				{
272 273 274
 				servname_type = *(sdata++); 
				n2s(sdata,len);
				if (len != dsize) 
275 276 277 278
					{
					*al = SSL_AD_DECODE_ERROR;
					return 0;
					}
279

280 281 282 283 284
				switch (servname_type)
					{
				case TLSEXT_NAMETYPE_host_name:
                                        if (s->session->tlsext_hostname == NULL)
						{
B
Bodo Möller 已提交
285
						if (len > TLSEXT_MAXLEN_host_name || 
286
							((s->session->tlsext_hostname = OPENSSL_malloc(len+1)) == NULL))
287 288 289 290
							{
							*al = TLS1_AD_UNRECOGNIZED_NAME;
							return 0;
							}
291
						memcpy(s->session->tlsext_hostname, sdata, len);
B
Bodo Möller 已提交
292 293 294 295 296
						s->session->tlsext_hostname[len]='\0';
						if (strlen(s->session->tlsext_hostname) != len) {
							OPENSSL_free(s->session->tlsext_hostname);
							*al = TLS1_AD_UNRECOGNIZED_NAME;
							return 0;
297
						}
B
Bodo Möller 已提交
298 299 300 301 302 303 304 305 306 307
						s->servername_done = 1; 

#if 0
						fprintf(stderr,"ssl_parse_clienthello_tlsext s->session->tlsext_hostname %s\n",s->session->tlsext_hostname);
#endif
						}
					else 
						s->servername_done = strlen(s->session->tlsext_hostname) == len 
							&& strncmp(s->session->tlsext_hostname,sdata, len) == 0;
					
308
					break;
309

310 311
				default:
					break;
312
					}
313
                                 
314
				}
315 316 317
			}

		data+=size;		
318
		}
319

320 321
	*p = data;
	return 1;
322
}
323 324 325

int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char *d, int n, int *al)
	{
326 327 328 329 330 331 332 333
	unsigned short type;
	unsigned short size;
	unsigned short len;  
	unsigned char *data = *p;

	int tlsext_servername = 0;

	if (data >= (d+n-2))
334
		return 1;
335 336 337

	n2s(data,len);

338 339
	while(data <= (d+n-4))
		{
340 341 342 343
		n2s(data,type);
		n2s(data,size);

		if (data+size > (d+n))
344 345 346 347 348 349 350 351 352
	   		return 1;

		if (type == TLSEXT_TYPE_server_name)
			{
			if (s->tlsext_hostname == NULL || size > 0)
				{
				*al = TLS1_AD_UNRECOGNIZED_NAME;
				return 0;
				}
353
			tlsext_servername = 1;   
354
			}
355 356

		data+=size;		
357
		}
358 359

	if (data != d+n)
360 361 362 363
		{
		*al = SSL_AD_DECODE_ERROR;
		return 0;
		}
364

365 366 367 368 369 370
	if (!s->hit && tlsext_servername == 1)
		{
 		if (s->tlsext_hostname)
			{
			if (s->session->tlsext_hostname == NULL)
				{
371 372
				s->session->tlsext_hostname = BUF_strdup(s->tlsext_hostname);	
				if (!s->session->tlsext_hostname)
373 374 375 376 377 378 379 380 381 382
					{
					*al = SSL_AD_UNRECOGNIZED_NAME;
					return 0;
					}
				}
			else 
				{
				*al = SSL_AD_DECODE_ERROR;
				return 0;
				}
383
			}
384
		}
385

386 387
	*p = data;
	return 1;
388 389
}

390 391
int ssl_check_tlsext(SSL *s,int *al)
	{
392
	int ret=SSL_TLSEXT_ERR_NOACK;
393 394

	*al = SSL_AD_UNRECOGNIZED_NAME;
395 396

	if (s->ctx != NULL && s->ctx->tlsext_servername_callback != 0) 
397
		ret = s->ctx->tlsext_servername_callback(s, al, s->ctx->tlsext_servername_arg);
398
	else if (s->initial_ctx != NULL && s->initial_ctx->tlsext_servername_callback != 0) 		
B
Bodo Möller 已提交
399
		ret = s->initial_ctx->tlsext_servername_callback(s, al, s->initial_ctx->tlsext_servername_arg);
400 401 402 403

	if (ret == SSL_TLSEXT_ERR_NOACK) 
		s->servername_done=0;
	return ret;
404
	}
405
#endif