mirror of https://github.com/openssl/openssl.git
				
				
				
			Add support for magic cipher suite value (MCSV). Make secure renegotiation
work in SSLv3: initial handshake has no extensions but includes MCSV, if server indicates RI support then renegotiation handshakes include RI. NB: current MCSV value is bogus for testing only, will be updated when we have an official value. Change mismatch alerts to handshake_failure as required by spec. Also have some debugging fprintfs so we can clearly see what is going on if OPENSSL_RI_DEBUG is set.
This commit is contained in:
		
							parent
							
								
									1ff44a99a4
								
							
						
					
					
						commit
						7a014dceb6
					
				
							
								
								
									
										5
									
								
								CHANGES
								
								
								
								
							
							
						
						
									
										5
									
								
								CHANGES
								
								
								
								
							|  | @ -8,15 +8,14 @@ | |||
|      the updated NID creation version. This should correctly handle UTF8. | ||||
|      [Steve Henson] | ||||
| 
 | ||||
|   *) Implement | ||||
|      https://svn.resiprocate.org/rep/ietf-drafts/ekr/draft-rescorla-tls-renegotiate.txt. Re-enable | ||||
|   *) Implement draft-ietf-tls-renegotiation. Re-enable | ||||
|      renegotiation but require the extension as needed. Unfortunately, | ||||
|      SSL3_FLAGS_ALLOW_UNSAFE_LEGACY_RENEGOTIATION turns out to be a | ||||
|      bad idea. It has been replaced by | ||||
|      SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION which can be set with | ||||
|      SSL_CTX_set_options(). This is really not recommended unless you | ||||
|      know what you are doing. | ||||
|      [Eric Rescorla <ekr@networkresonance.com> and Ben Laurie] | ||||
|      [Eric Rescorla <ekr@networkresonance.com>, Ben Laurie, Steve Henson] | ||||
| 
 | ||||
|   *) Fixes to stateless session resumption handling. Use initial_ctx when | ||||
|      issuing and attempting to decrypt tickets in case it has changed during | ||||
|  |  | |||
|  | @ -283,15 +283,43 @@ int dtls1_connect(SSL *s) | |||
| 
 | ||||
| 		case SSL3_ST_CR_CERT_A: | ||||
| 		case SSL3_ST_CR_CERT_B: | ||||
| #ifndef OPENSSL_NO_TLSEXT | ||||
| 			ret=ssl3_check_finished(s); | ||||
| 			if (ret <= 0) goto end; | ||||
| 			if (ret == 2) | ||||
| 				{ | ||||
| 				s->hit = 1; | ||||
| 				if (s->tlsext_ticket_expected) | ||||
| 					s->state=SSL3_ST_CR_SESSION_TICKET_A; | ||||
| 				else | ||||
| 					s->state=SSL3_ST_CR_FINISHED_A; | ||||
| 				s->init_num=0; | ||||
| 				break; | ||||
| 				} | ||||
| #endif | ||||
| 			/* Check if it is anon DH */ | ||||
| 			if (!(s->s3->tmp.new_cipher->algorithms & SSL_aNULL)) | ||||
| 				{ | ||||
| 				ret=ssl3_get_server_certificate(s); | ||||
| 				if (ret <= 0) goto end; | ||||
| #ifndef OPENSSL_NO_TLSEXT | ||||
| 				if (s->tlsext_status_expected) | ||||
| 					s->state=SSL3_ST_CR_CERT_STATUS_A; | ||||
| 				else | ||||
| 					s->state=SSL3_ST_CR_KEY_EXCH_A; | ||||
| 				} | ||||
| 			else | ||||
| 				{ | ||||
| 				skip = 1; | ||||
| 				s->state=SSL3_ST_CR_KEY_EXCH_A; | ||||
| 				} | ||||
| #else | ||||
| 				} | ||||
| 			else | ||||
| 				skip=1; | ||||
| 
 | ||||
| 			s->state=SSL3_ST_CR_KEY_EXCH_A; | ||||
| #endif | ||||
| 			s->init_num=0; | ||||
| 			break; | ||||
| 
 | ||||
|  | @ -434,12 +462,37 @@ int dtls1_connect(SSL *s) | |||
| 				} | ||||
| 			else | ||||
| 				{ | ||||
| #ifndef OPENSSL_NO_TLSEXT | ||||
| 				/* Allow NewSessionTicket if ticket expected */ | ||||
| 				if (s->tlsext_ticket_expected) | ||||
| 					s->s3->tmp.next_state=SSL3_ST_CR_SESSION_TICKET_A; | ||||
| 				else | ||||
| #endif | ||||
| 				 | ||||
| 				s->s3->tmp.next_state=SSL3_ST_CR_FINISHED_A; | ||||
| 				} | ||||
| 			s->init_num=0; | ||||
| 
 | ||||
| 			break; | ||||
| 
 | ||||
| #ifndef OPENSSL_NO_TLSEXT | ||||
| 		case SSL3_ST_CR_SESSION_TICKET_A: | ||||
| 		case SSL3_ST_CR_SESSION_TICKET_B: | ||||
| 			ret=ssl3_get_new_session_ticket(s); | ||||
| 			if (ret <= 0) goto end; | ||||
| 			s->state=SSL3_ST_CR_FINISHED_A; | ||||
| 			s->init_num=0; | ||||
| 		break; | ||||
| 
 | ||||
| 		case SSL3_ST_CR_CERT_STATUS_A: | ||||
| 		case SSL3_ST_CR_CERT_STATUS_B: | ||||
| 			ret=ssl3_get_cert_status(s); | ||||
| 			if (ret <= 0) goto end; | ||||
| 			s->state=SSL3_ST_CR_KEY_EXCH_A; | ||||
| 			s->init_num=0; | ||||
| 		break; | ||||
| #endif | ||||
| 
 | ||||
| 		case SSL3_ST_CR_FINISHED_A: | ||||
| 		case SSL3_ST_CR_FINISHED_B: | ||||
| 			s->d1->change_cipher_spec_ok = 1; | ||||
|  | @ -552,8 +605,14 @@ int dtls1_client_hello(SSL *s) | |||
| 	buf=(unsigned char *)s->init_buf->data; | ||||
| 	if (s->state == SSL3_ST_CW_CLNT_HELLO_A) | ||||
| 		{ | ||||
| 		SSL_SESSION *sess = s->session; | ||||
| 		if ((s->session == NULL) || | ||||
| 			(s->session->ssl_version != s->version) || | ||||
| #ifdef OPENSSL_NO_TLSEXT | ||||
| 			!sess->session_id_length || | ||||
| #else | ||||
| 			(!sess->session_id_length && !sess->tlsext_tick) || | ||||
| #endif | ||||
| 			(s->session->not_resumable)) | ||||
| 			{ | ||||
| 			if (!ssl_get_new_session(s,0)) | ||||
|  | @ -634,7 +693,7 @@ int dtls1_client_hello(SSL *s) | |||
| 		*(p++)=0; /* Add the NULL method */ | ||||
| 
 | ||||
| #ifndef OPENSSL_NO_TLSEXT | ||||
| 		if ((p = ssl_add_clienthello_dtlsext(s, p, buf+SSL3_RT_MAX_PLAIN_LENGTH)) == NULL) | ||||
| 		if ((p = ssl_add_clienthello_tlsext(s, p, buf+SSL3_RT_MAX_PLAIN_LENGTH)) == NULL) | ||||
| 			{ | ||||
| 			SSLerr(SSL_F_SSL3_CLIENT_HELLO,ERR_R_INTERNAL_ERROR); | ||||
| 			goto err; | ||||
|  |  | |||
							
								
								
									
										191
									
								
								ssl/d1_lib.c
								
								
								
								
							
							
						
						
									
										191
									
								
								ssl/d1_lib.c
								
								
								
								
							|  | @ -404,194 +404,3 @@ int dtls1_listen(SSL *s, struct sockaddr *client) | |||
| 	(void) BIO_dgram_get_peer(SSL_get_rbio(s), client); | ||||
| 	return 1; | ||||
| 	} | ||||
| 
 | ||||
| #ifndef OPENSSL_NO_TLSEXT | ||||
| unsigned char *ssl_add_clienthello_dtlsext(SSL *s, unsigned char *p, unsigned char *limit) | ||||
| 	{ | ||||
| 	int extdatalen = 0; | ||||
| 	unsigned char *ret = p; | ||||
| 	int el; | ||||
| 
 | ||||
| 	ret+=2; | ||||
| 	 | ||||
| 	if (ret>=limit) return NULL; /* this really never occurs, but ... */ | ||||
| 
 | ||||
| 	/* Renegotiate extension */ | ||||
| 	if(!ssl_add_clienthello_renegotiate_ext(s, 0, &el, 0)) | ||||
| 		{ | ||||
| 		SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR); | ||||
| 		return NULL; | ||||
| 		} | ||||
| 
 | ||||
| 	if((limit - p - 4 - el) < 0) return NULL; | ||||
| 	   | ||||
| 	s2n(TLSEXT_TYPE_renegotiate,ret); | ||||
| 	s2n(el,ret); | ||||
| 
 | ||||
| 	if(!ssl_add_clienthello_renegotiate_ext(s, ret, &el, el)) | ||||
| 		{ | ||||
| 		SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR); | ||||
| 		return NULL; | ||||
| 		} | ||||
| 
 | ||||
| 	ret += el; | ||||
| 
 | ||||
| 	if ((extdatalen = ret-p-2)== 0)  | ||||
| 		return p; | ||||
| 
 | ||||
| 	s2n(extdatalen,p); | ||||
| 
 | ||||
| 	return ret; | ||||
| 	} | ||||
| 
 | ||||
| int ssl_parse_clienthello_dtlsext(SSL *s, unsigned char **p, unsigned char *d, int n, int *al) | ||||
| 	{ | ||||
| 	unsigned short type; | ||||
| 	unsigned short size; | ||||
| 	unsigned short len; | ||||
| 	unsigned char *data = *p; | ||||
| 	int renegotiate_seen = 0; | ||||
| 
 | ||||
| 	if (data >= (d+n-2)) | ||||
| 		{ | ||||
| 		if (s->new_session | ||||
| 			&& !(s->ctx->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION)) | ||||
| 			{ | ||||
| 			/* We should always see one extension: the renegotiate extension */ | ||||
| 	 		SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_TLSEXT, SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED); | ||||
| 			*al = SSL_AD_ILLEGAL_PARAMETER; /* is this the right alert? */ | ||||
| 			return 0; | ||||
| 			} | ||||
| 		return 1; | ||||
| 		} | ||||
| 	n2s(data,len); | ||||
| 
 | ||||
| 	if (data > (d+n-len))  | ||||
| 		return 1; | ||||
| 
 | ||||
| 	while (data <= (d+n-4)) | ||||
| 		{ | ||||
| 		n2s(data,type); | ||||
| 		n2s(data,size); | ||||
| 		 | ||||
| 		if (data+size > (d+n)) | ||||
| 	   		return 1; | ||||
| 		 | ||||
| 		if (type == TLSEXT_TYPE_renegotiate) | ||||
| 			{ | ||||
| 			if(!ssl_parse_clienthello_renegotiate_ext(s, data, size, al)) | ||||
| 				return 0; | ||||
| 			renegotiate_seen = 1; | ||||
| 			} | ||||
| 		 | ||||
| 		data+=size; | ||||
| 		} | ||||
| 
 | ||||
| 	if (s->new_session && !renegotiate_seen | ||||
| 		&& !(s->ctx->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION)) | ||||
| 		{ | ||||
| 		*al = SSL_AD_ILLEGAL_PARAMETER; /* is this the right alert? */ | ||||
| 	 	SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_TLSEXT, SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED); | ||||
| 		return 0; | ||||
| 		} | ||||
| 
 | ||||
| 	*p = data; | ||||
| 	return 1; | ||||
| 	} | ||||
| 
 | ||||
| unsigned char *ssl_add_serverhello_dtlsext(SSL *s, unsigned char *p, unsigned char *limit) | ||||
| 	{ | ||||
| 	int extdatalen = 0; | ||||
| 	unsigned char *ret = p; | ||||
| 	 | ||||
| 	ret+=2; | ||||
| 	 | ||||
| 	if (ret>=limit) return NULL; /* this really never occurs, but ... */ | ||||
| 	 | ||||
| 	if(s->s3->send_connection_binding) | ||||
| 		{ | ||||
| 		int el; | ||||
| 
 | ||||
| 		if(!ssl_add_serverhello_renegotiate_ext(s, 0, &el, 0)) | ||||
| 			{ | ||||
| 			SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR); | ||||
| 			return NULL; | ||||
| 			} | ||||
| 
 | ||||
| 		if((limit - p - 4 - el) < 0) return NULL; | ||||
|            | ||||
| 		s2n(TLSEXT_TYPE_renegotiate,ret); | ||||
| 		s2n(el,ret); | ||||
| 
 | ||||
| 		if(!ssl_add_serverhello_renegotiate_ext(s, ret, &el, el)) | ||||
| 			{ | ||||
| 			SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR); | ||||
| 			return NULL; | ||||
| 			} | ||||
| 
 | ||||
| 		ret += el; | ||||
| 		} | ||||
| 
 | ||||
| 	if ((extdatalen = ret-p-2)== 0)  | ||||
| 		return p; | ||||
| 
 | ||||
| 	s2n(extdatalen,p); | ||||
| 
 | ||||
| 	return ret; | ||||
| 	} | ||||
| 
 | ||||
| int ssl_parse_serverhello_dtlsext(SSL *s, unsigned char **p, unsigned char *d, int n, int *al) | ||||
| 	{ | ||||
| 	unsigned short type; | ||||
| 	unsigned short size; | ||||
| 	unsigned short len; | ||||
| 	unsigned char *data = *p; | ||||
| 	int renegotiate_seen = 0; | ||||
| 	 | ||||
| 	if (data >= (d+n-2)) | ||||
| 		{ | ||||
| 		if (s->new_session | ||||
| 			&& !(s->ctx->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION)) | ||||
| 			{ | ||||
| 			/* We should always see one extension: the renegotiate extension */ | ||||
| 	 		SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_TLSEXT, SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED); | ||||
| 			*al = SSL_AD_ILLEGAL_PARAMETER; /* is this the right alert? */ | ||||
| 			return 0; | ||||
| 			} | ||||
| 		return 1; | ||||
| 		} | ||||
| 	n2s(data,len); | ||||
| 	 | ||||
| 	if (data > (d+n-len))  | ||||
| 		return 1; | ||||
| 	 | ||||
| 	while (data <= (d+n-4)) | ||||
| 		{ | ||||
| 		n2s(data,type); | ||||
| 		n2s(data,size); | ||||
| 		 | ||||
| 		if (data+size > (d+n)) | ||||
| 	   		return 1; | ||||
| 		 | ||||
| 		if (type == TLSEXT_TYPE_renegotiate) | ||||
| 			{ | ||||
| 			if(!ssl_parse_serverhello_renegotiate_ext(s, data, size, al)) | ||||
| 				return 0; | ||||
| 			renegotiate_seen = 1; | ||||
| 			} | ||||
| 		 | ||||
| 		data+=size; | ||||
| 		} | ||||
| 
 | ||||
| 	if (s->new_session && !renegotiate_seen | ||||
| 		&& !(s->ctx->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION)) | ||||
| 		{ | ||||
| 		*al = SSL_AD_ILLEGAL_PARAMETER; /* is this the right alert? */ | ||||
| 	 	SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_TLSEXT, SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED); | ||||
| 		return 0; | ||||
| 		} | ||||
| 
 | ||||
| 	*p = data; | ||||
| 	return 1; | ||||
| 	} | ||||
| #endif | ||||
|  |  | |||
							
								
								
									
										162
									
								
								ssl/d1_srvr.c
								
								
								
								
							
							
						
						
									
										162
									
								
								ssl/d1_srvr.c
								
								
								
								
							|  | @ -303,8 +303,18 @@ int dtls1_accept(SSL *s) | |||
| 			ret=dtls1_send_server_hello(s); | ||||
| 			if (ret <= 0) goto end; | ||||
| 
 | ||||
| #ifndef OPENSSL_NO_TLSEXT | ||||
| 			if (s->hit) | ||||
| 				s->state=SSL3_ST_SW_CHANGE_A; | ||||
| 				{ | ||||
| 				if (s->tlsext_ticket_expected) | ||||
| 					s->state=SSL3_ST_SW_SESSION_TICKET_A; | ||||
| 				else | ||||
| 					s->state=SSL3_ST_SW_CHANGE_A; | ||||
| 				} | ||||
| #else | ||||
| 			if (s->hit) | ||||
| 					s->state=SSL3_ST_SW_CHANGE_A; | ||||
| #endif | ||||
| 			else | ||||
| 				s->state=SSL3_ST_SW_CERT_A; | ||||
| 			s->init_num=0; | ||||
|  | @ -318,10 +328,24 @@ int dtls1_accept(SSL *s) | |||
| 				dtls1_start_timer(s); | ||||
| 				ret=dtls1_send_server_certificate(s); | ||||
| 				if (ret <= 0) goto end; | ||||
| #ifndef OPENSSL_NO_TLSEXT | ||||
| 				if (s->tlsext_status_expected) | ||||
| 					s->state=SSL3_ST_SW_CERT_STATUS_A; | ||||
| 				else | ||||
| 					s->state=SSL3_ST_SW_KEY_EXCH_A; | ||||
| 				} | ||||
| 			else | ||||
| 				{ | ||||
| 				skip = 1; | ||||
| 				s->state=SSL3_ST_SW_KEY_EXCH_A; | ||||
| 				} | ||||
| #else | ||||
| 				} | ||||
| 			else | ||||
| 				skip=1; | ||||
| 
 | ||||
| 			s->state=SSL3_ST_SW_KEY_EXCH_A; | ||||
| #endif | ||||
| 			s->init_num=0; | ||||
| 			break; | ||||
| 
 | ||||
|  | @ -492,11 +516,34 @@ int dtls1_accept(SSL *s) | |||
| 			dtls1_stop_timer(s); | ||||
| 			if (s->hit) | ||||
| 				s->state=SSL_ST_OK; | ||||
| #ifndef OPENSSL_NO_TLSEXT | ||||
| 			else if (s->tlsext_ticket_expected) | ||||
| 				s->state=SSL3_ST_SW_SESSION_TICKET_A; | ||||
| #endif | ||||
| 			else | ||||
| 				s->state=SSL3_ST_SW_CHANGE_A; | ||||
| 			s->init_num=0; | ||||
| 			break; | ||||
| 
 | ||||
| #ifndef OPENSSL_NO_TLSEXT | ||||
| 		case SSL3_ST_SW_SESSION_TICKET_A: | ||||
| 		case SSL3_ST_SW_SESSION_TICKET_B: | ||||
| 			ret=dtls1_send_newsession_ticket(s); | ||||
| 			if (ret <= 0) goto end; | ||||
| 			s->state=SSL3_ST_SW_CHANGE_A; | ||||
| 			s->init_num=0; | ||||
| 			break; | ||||
| 
 | ||||
| 		case SSL3_ST_SW_CERT_STATUS_A: | ||||
| 		case SSL3_ST_SW_CERT_STATUS_B: | ||||
| 			ret=ssl3_send_cert_status(s); | ||||
| 			if (ret <= 0) goto end; | ||||
| 			s->state=SSL3_ST_SW_KEY_EXCH_A; | ||||
| 			s->init_num=0; | ||||
| 			break; | ||||
| 
 | ||||
| #endif | ||||
| 
 | ||||
| 		case SSL3_ST_SW_CHANGE_A: | ||||
| 		case SSL3_ST_SW_CHANGE_B: | ||||
| 
 | ||||
|  | @ -746,7 +793,7 @@ int dtls1_send_server_hello(SSL *s) | |||
| #endif | ||||
| 
 | ||||
| #ifndef OPENSSL_NO_TLSEXT | ||||
| 		if ((p = ssl_add_serverhello_dtlsext(s, p, buf+SSL3_RT_MAX_PLAIN_LENGTH)) == NULL) | ||||
| 		if ((p = ssl_add_serverhello_tlsext(s, p, buf+SSL3_RT_MAX_PLAIN_LENGTH)) == NULL) | ||||
| 			{ | ||||
| 			SSLerr(SSL_F_SSL3_SEND_SERVER_HELLO,ERR_R_INTERNAL_ERROR); | ||||
| 			return -1; | ||||
|  | @ -1172,3 +1219,114 @@ int dtls1_send_server_certificate(SSL *s) | |||
| 	/* SSL3_ST_SW_CERT_B */ | ||||
| 	return(dtls1_do_write(s,SSL3_RT_HANDSHAKE)); | ||||
| 	} | ||||
| 
 | ||||
| #ifndef OPENSSL_NO_TLSEXT | ||||
| int dtls1_send_newsession_ticket(SSL *s) | ||||
| 	{ | ||||
| 	if (s->state == SSL3_ST_SW_SESSION_TICKET_A) | ||||
| 		{ | ||||
| 		unsigned char *p, *senc, *macstart; | ||||
| 		int len, slen; | ||||
| 		unsigned int hlen, msg_len; | ||||
| 		EVP_CIPHER_CTX ctx; | ||||
| 		HMAC_CTX hctx; | ||||
| 		SSL_CTX *tctx = s->initial_ctx; | ||||
| 		unsigned char iv[EVP_MAX_IV_LENGTH]; | ||||
| 		unsigned char key_name[16]; | ||||
| 
 | ||||
| 		/* get session encoding length */ | ||||
| 		slen = i2d_SSL_SESSION(s->session, NULL); | ||||
| 		/* Some length values are 16 bits, so forget it if session is
 | ||||
|  		 * too long | ||||
|  		 */ | ||||
| 		if (slen > 0xFF00) | ||||
| 			return -1; | ||||
| 		/* Grow buffer if need be: the length calculation is as
 | ||||
|  		 * follows 12 (DTLS handshake message header) + | ||||
|  		 * 4 (ticket lifetime hint) + 2 (ticket length) + | ||||
|  		 * 16 (key name) + max_iv_len (iv length) + | ||||
|  		 * session_length + max_enc_block_size (max encrypted session | ||||
|  		 * length) + max_md_size (HMAC). | ||||
|  		 */ | ||||
| 		if (!BUF_MEM_grow(s->init_buf, | ||||
| 			DTLS1_HM_HEADER_LENGTH + 22 + EVP_MAX_IV_LENGTH + | ||||
| 			EVP_MAX_BLOCK_LENGTH + EVP_MAX_MD_SIZE + slen)) | ||||
| 			return -1; | ||||
| 		senc = OPENSSL_malloc(slen); | ||||
| 		if (!senc) | ||||
| 			return -1; | ||||
| 		p = senc; | ||||
| 		i2d_SSL_SESSION(s->session, &p); | ||||
| 
 | ||||
| 		p=(unsigned char *)&(s->init_buf->data[DTLS1_HM_HEADER_LENGTH]); | ||||
| 		EVP_CIPHER_CTX_init(&ctx); | ||||
| 		HMAC_CTX_init(&hctx); | ||||
| 		/* Initialize HMAC and cipher contexts. If callback present
 | ||||
| 		 * it does all the work otherwise use generated values | ||||
| 		 * from parent ctx. | ||||
| 		 */ | ||||
| 		if (tctx->tlsext_ticket_key_cb) | ||||
| 			{ | ||||
| 			if (tctx->tlsext_ticket_key_cb(s, key_name, iv, &ctx, | ||||
| 							 &hctx, 1) < 0) | ||||
| 				{ | ||||
| 				OPENSSL_free(senc); | ||||
| 				return -1; | ||||
| 				} | ||||
| 			} | ||||
| 		else | ||||
| 			{ | ||||
| 			RAND_pseudo_bytes(iv, 16); | ||||
| 			EVP_EncryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL, | ||||
| 					tctx->tlsext_tick_aes_key, iv); | ||||
| 			HMAC_Init_ex(&hctx, tctx->tlsext_tick_hmac_key, 16, | ||||
| 					tlsext_tick_md(), NULL); | ||||
| 			memcpy(key_name, tctx->tlsext_tick_key_name, 16); | ||||
| 			} | ||||
| 		l2n(s->session->tlsext_tick_lifetime_hint, p); | ||||
| 		/* Skip ticket length for now */ | ||||
| 		p += 2; | ||||
| 		/* Output key name */ | ||||
| 		macstart = p; | ||||
| 		memcpy(p, key_name, 16); | ||||
| 		p += 16; | ||||
| 		/* output IV */ | ||||
| 		memcpy(p, iv, EVP_CIPHER_CTX_iv_length(&ctx)); | ||||
| 		p += EVP_CIPHER_CTX_iv_length(&ctx); | ||||
| 		/* Encrypt session data */ | ||||
| 		EVP_EncryptUpdate(&ctx, p, &len, senc, slen); | ||||
| 		p += len; | ||||
| 		EVP_EncryptFinal(&ctx, p, &len); | ||||
| 		p += len; | ||||
| 		EVP_CIPHER_CTX_cleanup(&ctx); | ||||
| 
 | ||||
| 		HMAC_Update(&hctx, macstart, p - macstart); | ||||
| 		HMAC_Final(&hctx, p, &hlen); | ||||
| 		HMAC_CTX_cleanup(&hctx); | ||||
| 
 | ||||
| 		p += hlen; | ||||
| 		/* Now write out lengths: p points to end of data written */ | ||||
| 		/* Total length */ | ||||
| 		len = p - (unsigned char *)&(s->init_buf->data[DTLS1_HM_HEADER_LENGTH]); | ||||
| 		p=(unsigned char *)&(s->init_buf->data[DTLS1_HM_HEADER_LENGTH]) + 4; | ||||
| 		s2n(len - 18, p);  /* Ticket length */ | ||||
| 
 | ||||
| 		/* number of bytes to write */ | ||||
| 		s->init_num= len; | ||||
| 		s->state=SSL3_ST_SW_SESSION_TICKET_B; | ||||
| 		s->init_off=0; | ||||
| 		OPENSSL_free(senc); | ||||
| 
 | ||||
| 		/* XDTLS:  set message header ? */ | ||||
| 		msg_len = s->init_num - DTLS1_HM_HEADER_LENGTH; | ||||
| 		dtls1_set_message_header(s, (void *)s->init_buf->data, | ||||
| 			SSL3_MT_NEWSESSION_TICKET, msg_len, 0, msg_len); | ||||
| 
 | ||||
| 		/* buffer the message to handle re-xmits */ | ||||
| 		dtls1_buffer_message(s, 0); | ||||
| 		} | ||||
| 
 | ||||
| 	/* SSL3_ST_SW_SESSION_TICKET_B */ | ||||
| 	return(dtls1_do_write(s,SSL3_RT_HANDSHAKE)); | ||||
| 	} | ||||
| #endif | ||||
|  | @ -144,9 +144,6 @@ | |||
| 
 | ||||
| static SSL_METHOD *ssl3_get_client_method(int ver); | ||||
| static int ca_dn_cmp(const X509_NAME * const *a,const X509_NAME * const *b); | ||||
| #ifndef OPENSSL_NO_TLSEXT | ||||
| static int ssl3_check_finished(SSL *s); | ||||
| #endif | ||||
| 
 | ||||
| #ifndef OPENSSL_NO_ECDH | ||||
| static int curve_id2nid(int curve_id); | ||||
|  | @ -861,7 +858,7 @@ int ssl3_get_server_hello(SSL *s) | |||
| #endif | ||||
| #ifndef OPENSSL_NO_TLSEXT | ||||
| 	/* TLS extensions*/ | ||||
| 	if (s->version > SSL3_VERSION && s->version != DTLS1_VERSION && s->version != DTLS1_BAD_VER) | ||||
| 	if (s->version >= SSL3_VERSION) | ||||
| 		{ | ||||
| 		if (!ssl_parse_serverhello_tlsext(s,&p,d,n, &al)) | ||||
| 			{ | ||||
|  | @ -875,17 +872,6 @@ int ssl3_get_server_hello(SSL *s) | |||
| 				goto err; | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 	/* DTLS extensions */ | ||||
| 	if (s->version == DTLS1_VERSION || s->version == DTLS1_BAD_VER) | ||||
| 	{ | ||||
| 		if (!ssl_parse_serverhello_dtlsext(s,&p,d,n, &al)) | ||||
| 		{ | ||||
| 			/* 'al' set by ssl_parse_serverhello_dtlsext */ | ||||
| 			SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_PARSE_TLSEXT); | ||||
| 			goto f_err; | ||||
| 		} | ||||
| 	} | ||||
| #endif | ||||
| 
 | ||||
| 
 | ||||
|  | @ -1732,6 +1718,7 @@ int ssl3_get_new_session_ticket(SSL *s) | |||
| 		SSLerr(SSL_F_SSL3_GET_NEW_SESSION_TICKET,SSL_R_LENGTH_MISMATCH); | ||||
| 		goto f_err; | ||||
| 		} | ||||
| 
 | ||||
| 	p=d=(unsigned char *)s->init_msg; | ||||
| 	n2l(p, s->session->tlsext_tick_lifetime_hint); | ||||
| 	n2s(p, ticklen); | ||||
|  | @ -2735,7 +2722,7 @@ static int curve_id2nid(int curve_id) | |||
|  */ | ||||
| 
 | ||||
| #ifndef OPENSSL_NO_TLSEXT | ||||
| static int ssl3_check_finished(SSL *s) | ||||
| int ssl3_check_finished(SSL *s) | ||||
| 	{ | ||||
| 	int ok; | ||||
| 	long n; | ||||
|  |  | |||
|  | @ -957,7 +957,7 @@ int ssl3_get_client_hello(SSL *s) | |||
| 
 | ||||
| #ifndef OPENSSL_NO_TLSEXT | ||||
| 	/* TLS extensions*/ | ||||
| 	if (s->version > SSL3_VERSION && s->version != DTLS1_VERSION && s->version != DTLS1_BAD_VER) | ||||
| 	if (s->version >= SSL3_VERSION) | ||||
| 		{ | ||||
| 		if (!ssl_parse_clienthello_tlsext(s,&p,d,n, &al)) | ||||
| 			{ | ||||
|  | @ -970,17 +970,6 @@ int ssl3_get_client_hello(SSL *s) | |||
| 			SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_CLIENTHELLO_TLSEXT); | ||||
| 			goto err; | ||||
| 		} | ||||
| 
 | ||||
| 	/* DTLS extensions */ | ||||
| 	if (s->version == DTLS1_VERSION || s->version == DTLS1_BAD_VER) | ||||
| 		{ | ||||
| 		if (!ssl_parse_clienthello_dtlsext(s,&p,d,n, &al)) | ||||
| 			{ | ||||
| 				/* 'al' set by ssl_parse_clienthello_dtlsext */ | ||||
| 				SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_PARSE_TLSEXT); | ||||
| 				goto f_err; | ||||
| 			} | ||||
| 		} | ||||
| #endif | ||||
| 	/* Worst case, we will use the NULL compression, but if we have other
 | ||||
| 	 * options, we will now look for them.  We have i-1 compression | ||||
|  |  | |||
|  | @ -129,6 +129,9 @@ | |||
| extern "C" { | ||||
| #endif | ||||
| 
 | ||||
| /* Magic Cipher Suite Value. NB: bogus value used for testing */ | ||||
| #define SSL3_CK_MCSV				0x03000FEC | ||||
| 
 | ||||
| #define SSL3_CK_RSA_NULL_MD5			0x03000001 | ||||
| #define SSL3_CK_RSA_NULL_SHA			0x03000002 | ||||
| #define SSL3_CK_RSA_RC4_40_MD5 			0x03000003 | ||||
|  |  | |||
|  | @ -1287,6 +1287,22 @@ int ssl_cipher_list_to_bytes(SSL *s,STACK_OF(SSL_CIPHER) *sk,unsigned char *p, | |||
| 		j = put_cb ? put_cb(c,p) : ssl_put_cipher_by_char(s,c,p); | ||||
| 		p+=j; | ||||
| 		} | ||||
| 	/* If p == q, no ciphers and caller indicates an error, otherwise
 | ||||
| 	 * add MCSV | ||||
| 	 */ | ||||
| 	if (p != q) | ||||
| 		{ | ||||
| 		static SSL_CIPHER msvc = | ||||
| 			{ | ||||
| 			0, NULL, SSL3_CK_MCSV, 0, 0, 0, 0, 0, 0, 0, 0, 0 | ||||
| 			}; | ||||
| 		j = put_cb ? put_cb(&msvc,p) : ssl_put_cipher_by_char(s,&msvc,p); | ||||
| 		p+=j; | ||||
| #ifdef OPENSSL_RI_DEBUG | ||||
| 		fprintf(stderr, "MCSV sent by client\n"); | ||||
| #endif | ||||
| 		} | ||||
| 
 | ||||
| 	return(p-q); | ||||
| 	} | ||||
| 
 | ||||
|  | @ -1297,6 +1313,8 @@ STACK_OF(SSL_CIPHER) *ssl_bytes_to_cipher_list(SSL *s,unsigned char *p,int num, | |||
| 	STACK_OF(SSL_CIPHER) *sk; | ||||
| 	int i,n; | ||||
| 
 | ||||
| 	s->s3->send_connection_binding = 0; | ||||
| 
 | ||||
| 	n=ssl_put_cipher_by_char(s,NULL,NULL); | ||||
| 	if ((num%n) != 0) | ||||
| 		{ | ||||
|  | @ -1313,6 +1331,19 @@ STACK_OF(SSL_CIPHER) *ssl_bytes_to_cipher_list(SSL *s,unsigned char *p,int num, | |||
| 
 | ||||
| 	for (i=0; i<num; i+=n) | ||||
| 		{ | ||||
| 		/* Check for MCSV */ | ||||
| 		if ((n != 3 || !p[0]) && | ||||
| 			(p[n-2] == ((SSL3_CK_MCSV >> 8) & 0xff)) && | ||||
| 			(p[n-1] == (SSL3_CK_MCSV & 0xff))) | ||||
| 			{ | ||||
| 			s->s3->send_connection_binding = 1; | ||||
| 			p += n; | ||||
| #ifdef OPENSSL_RI_DEBUG | ||||
| 			fprintf(stderr, "MCSV received by server\n"); | ||||
| #endif | ||||
| 			continue; | ||||
| 			} | ||||
| 
 | ||||
| 		c=ssl_get_cipher_by_char(s,p); | ||||
| 		p+=n; | ||||
| 		if (c != NULL) | ||||
|  |  | |||
|  | @ -876,7 +876,7 @@ void dtls1_start_timer(SSL *s); | |||
| void dtls1_stop_timer(SSL *s); | ||||
| int dtls1_is_timer_expired(SSL *s); | ||||
| void dtls1_double_timeout(SSL *s); | ||||
| 
 | ||||
| int dtls1_send_newsession_ticket(SSL *s); | ||||
| 
 | ||||
| 
 | ||||
| /* some client-only functions */ | ||||
|  | @ -893,6 +893,9 @@ int ssl3_send_client_key_exchange(SSL *s); | |||
| int ssl3_get_key_exchange(SSL *s); | ||||
| int ssl3_get_server_certificate(SSL *s); | ||||
| int ssl3_check_cert_and_algorithm(SSL *s); | ||||
| #ifndef OPENSSL_NO_TLSEXT | ||||
| int ssl3_check_finished(SSL *s); | ||||
| #endif | ||||
| 
 | ||||
| int dtls1_client_hello(SSL *s); | ||||
| int dtls1_send_client_certificate(SSL *s); | ||||
|  | @ -977,11 +980,6 @@ int ssl_prepare_serverhello_tlsext(SSL *s); | |||
| int ssl_check_clienthello_tlsext(SSL *s); | ||||
| int ssl_check_serverhello_tlsext(SSL *s); | ||||
| 
 | ||||
| unsigned char *ssl_add_clienthello_dtlsext(SSL *s, unsigned char *p, unsigned char *limit); | ||||
| unsigned char *ssl_add_serverhello_dtlsext(SSL *s, unsigned char *p, unsigned char *limit); | ||||
| int ssl_parse_clienthello_dtlsext(SSL *s, unsigned char **data, unsigned char *d, int n, int *al); | ||||
| int ssl_parse_serverhello_dtlsext(SSL *s, unsigned char **data, unsigned char *d, int n, int *al); | ||||
| 
 | ||||
| #ifdef OPENSSL_NO_SHA256 | ||||
| #define tlsext_tick_md	EVP_sha1 | ||||
| #else | ||||
|  |  | |||
							
								
								
									
										22
									
								
								ssl/t1_lib.c
								
								
								
								
							
							
						
						
									
										22
									
								
								ssl/t1_lib.c
								
								
								
								
							|  | @ -133,8 +133,9 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned cha | |||
| 	int extdatalen=0; | ||||
| 	unsigned char *ret = p; | ||||
| 
 | ||||
| 	/* don't add extensions for SSLv3 */ | ||||
| 	if (s->client_version == SSL3_VERSION) | ||||
| 	/* don't add extensions for SSLv3 unless doing secure renegotiation */ | ||||
| 	if (s->client_version == SSL3_VERSION | ||||
| 					&& !s->s3->send_connection_binding) | ||||
| 		return p; | ||||
| 
 | ||||
| 	ret+=2; | ||||
|  | @ -220,7 +221,8 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned cha | |||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 	if (s->tlsext_status_type == TLSEXT_STATUSTYPE_ocsp) | ||||
| 	if (s->tlsext_status_type == TLSEXT_STATUSTYPE_ocsp && | ||||
| 	    s->version != DTLS1_VERSION) | ||||
| 		{ | ||||
| 		int i; | ||||
| 		long extlen, idlen, itmp; | ||||
|  | @ -280,8 +282,8 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned cha | |||
| 	int extdatalen=0; | ||||
| 	unsigned char *ret = p; | ||||
| 
 | ||||
| 	/* don't add extensions for SSLv3 */ | ||||
| 	if (s->version == SSL3_VERSION) | ||||
| 	/* don't add extensions for SSLv3, unless doing secure renegotiation */ | ||||
| 	if (s->version == SSL3_VERSION && !s->s3->send_connection_binding) | ||||
| 		return p; | ||||
| 	 | ||||
| 	ret+=2; | ||||
|  | @ -295,7 +297,7 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned cha | |||
| 		s2n(0,ret); | ||||
| 		} | ||||
| 
 | ||||
|         if(s->s3->send_connection_binding) | ||||
| 	if(s->s3->send_connection_binding) | ||||
|         { | ||||
|           int el; | ||||
|            | ||||
|  | @ -351,7 +353,6 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in | |||
| 
 | ||||
| 	s->servername_done = 0; | ||||
| 	s->tlsext_status_type = -1; | ||||
| 	s->s3->send_connection_binding = 0; | ||||
| 
 | ||||
| 	if (data >= (d+n-2)) | ||||
| 		{ | ||||
|  | @ -483,8 +484,8 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in | |||
| 				return 0; | ||||
| 			renegotiate_seen = 1; | ||||
| 			} | ||||
| 		else if (type == TLSEXT_TYPE_status_request | ||||
| 						&& s->ctx->tlsext_status_cb) | ||||
| 		else if (type == TLSEXT_TYPE_status_request && | ||||
| 		         s->version != DTLS1_VERSION && s->ctx->tlsext_status_cb) | ||||
| 			{ | ||||
| 		 | ||||
| 			if (size < 5)  | ||||
|  | @ -658,7 +659,8 @@ int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in | |||
| 				} | ||||
| 			s->tlsext_ticket_expected = 1; | ||||
| 			} | ||||
| 		else if (type == TLSEXT_TYPE_status_request) | ||||
| 		else if (type == TLSEXT_TYPE_status_request && | ||||
| 		         s->version != DTLS1_VERSION) | ||||
| 			{ | ||||
| 			/* MUST be empty and only sent if we've requested
 | ||||
| 			 * a status request message. | ||||
|  |  | |||
|  | @ -130,10 +130,14 @@ int ssl_add_clienthello_renegotiate_ext(SSL *s, unsigned char *p, int *len, | |||
| 
 | ||||
|         memcpy(p, s->s3->previous_client_finished, | ||||
| 	       s->s3->previous_client_finished_len); | ||||
| #ifdef OPENSSL_RI_DEBUG | ||||
|     fprintf(stderr, "RI extension sent by client\n"); | ||||
| #endif | ||||
|         } | ||||
|      | ||||
|     *len=s->s3->previous_client_finished_len + 1; | ||||
|      | ||||
| 
 | ||||
|   | ||||
|     return 1; | ||||
|     } | ||||
| 
 | ||||
|  | @ -166,7 +170,7 @@ int ssl_parse_clienthello_renegotiate_ext(SSL *s, unsigned char *d, int len, | |||
|     if(ilen != s->s3->previous_client_finished_len) | ||||
|         { | ||||
|         SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT,SSL_R_RENEGOTIATION_MISMATCH); | ||||
|         *al=SSL_AD_ILLEGAL_PARAMETER; | ||||
|         *al=SSL_AD_HANDSHAKE_FAILURE; | ||||
|         return 0; | ||||
|         } | ||||
|      | ||||
|  | @ -174,9 +178,12 @@ int ssl_parse_clienthello_renegotiate_ext(SSL *s, unsigned char *d, int len, | |||
| 	      s->s3->previous_client_finished_len)) | ||||
|         { | ||||
|         SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT,SSL_R_RENEGOTIATION_MISMATCH); | ||||
|         *al=SSL_AD_ILLEGAL_PARAMETER; | ||||
|         *al=SSL_AD_HANDSHAKE_FAILURE; | ||||
|         return 0; | ||||
|         } | ||||
| #ifdef OPENSSL_RI_DEBUG | ||||
|     fprintf(stderr, "RI extension received by server\n"); | ||||
| #endif | ||||
| 
 | ||||
|     s->s3->send_connection_binding=1; | ||||
| 
 | ||||
|  | @ -206,6 +213,9 @@ int ssl_add_serverhello_renegotiate_ext(SSL *s, unsigned char *p, int *len, | |||
| 
 | ||||
|         memcpy(p, s->s3->previous_server_finished, | ||||
| 	       s->s3->previous_server_finished_len); | ||||
| #ifdef OPENSSL_RI_DEBUG | ||||
|     fprintf(stderr, "RI extension sent by server\n"); | ||||
| #endif | ||||
|         } | ||||
|      | ||||
|     *len=s->s3->previous_client_finished_len | ||||
|  | @ -249,7 +259,7 @@ int ssl_parse_serverhello_renegotiate_ext(SSL *s, unsigned char *d, int len, | |||
|     if(ilen != expected_len) | ||||
|         { | ||||
|         SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT,SSL_R_RENEGOTIATION_MISMATCH); | ||||
|         *al=SSL_AD_ILLEGAL_PARAMETER; | ||||
|         *al=SSL_AD_HANDSHAKE_FAILURE; | ||||
|         return 0; | ||||
|         } | ||||
| 
 | ||||
|  | @ -257,7 +267,7 @@ int ssl_parse_serverhello_renegotiate_ext(SSL *s, unsigned char *d, int len, | |||
| 	      s->s3->previous_client_finished_len)) | ||||
|         { | ||||
|         SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT,SSL_R_RENEGOTIATION_MISMATCH); | ||||
|         *al=SSL_AD_ILLEGAL_PARAMETER; | ||||
|         *al=SSL_AD_HANDSHAKE_FAILURE; | ||||
|         return 0; | ||||
|         } | ||||
|     d += s->s3->previous_client_finished_len; | ||||
|  | @ -269,6 +279,10 @@ int ssl_parse_serverhello_renegotiate_ext(SSL *s, unsigned char *d, int len, | |||
|         *al=SSL_AD_ILLEGAL_PARAMETER; | ||||
|         return 0; | ||||
|         } | ||||
| #ifdef OPENSSL_RI_DEBUG | ||||
|     fprintf(stderr, "RI extension received by client\n"); | ||||
| #endif | ||||
|     s->s3->send_connection_binding=1; | ||||
| 
 | ||||
|     return 1; | ||||
|     } | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue