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:
		
							
								
								
									
										5
									
								
								CHANGES
									
									
									
									
									
								
							
							
						
						
									
										5
									
								
								CHANGES
									
									
									
									
									
								
							@@ -8,15 +8,14 @@
 | 
				
			|||||||
     the updated NID creation version. This should correctly handle UTF8.
 | 
					     the updated NID creation version. This should correctly handle UTF8.
 | 
				
			||||||
     [Steve Henson]
 | 
					     [Steve Henson]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  *) Implement
 | 
					  *) Implement draft-ietf-tls-renegotiation. Re-enable
 | 
				
			||||||
     https://svn.resiprocate.org/rep/ietf-drafts/ekr/draft-rescorla-tls-renegotiate.txt. Re-enable
 | 
					 | 
				
			||||||
     renegotiation but require the extension as needed. Unfortunately,
 | 
					     renegotiation but require the extension as needed. Unfortunately,
 | 
				
			||||||
     SSL3_FLAGS_ALLOW_UNSAFE_LEGACY_RENEGOTIATION turns out to be a
 | 
					     SSL3_FLAGS_ALLOW_UNSAFE_LEGACY_RENEGOTIATION turns out to be a
 | 
				
			||||||
     bad idea. It has been replaced by
 | 
					     bad idea. It has been replaced by
 | 
				
			||||||
     SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION which can be set with
 | 
					     SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION which can be set with
 | 
				
			||||||
     SSL_CTX_set_options(). This is really not recommended unless you
 | 
					     SSL_CTX_set_options(). This is really not recommended unless you
 | 
				
			||||||
     know what you are doing.
 | 
					     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
 | 
					  *) Fixes to stateless session resumption handling. Use initial_ctx when
 | 
				
			||||||
     issuing and attempting to decrypt tickets in case it has changed during
 | 
					     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_A:
 | 
				
			||||||
		case SSL3_ST_CR_CERT_B:
 | 
							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 */
 | 
								/* Check if it is anon DH */
 | 
				
			||||||
			if (!(s->s3->tmp.new_cipher->algorithms & SSL_aNULL))
 | 
								if (!(s->s3->tmp.new_cipher->algorithms & SSL_aNULL))
 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
				ret=ssl3_get_server_certificate(s);
 | 
									ret=ssl3_get_server_certificate(s);
 | 
				
			||||||
				if (ret <= 0) goto end;
 | 
									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
 | 
								else
 | 
				
			||||||
				skip=1;
 | 
									skip=1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			s->state=SSL3_ST_CR_KEY_EXCH_A;
 | 
								s->state=SSL3_ST_CR_KEY_EXCH_A;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
			s->init_num=0;
 | 
								s->init_num=0;
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -434,12 +462,37 @@ int dtls1_connect(SSL *s)
 | 
				
			|||||||
				}
 | 
									}
 | 
				
			||||||
			else
 | 
								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->s3->tmp.next_state=SSL3_ST_CR_FINISHED_A;
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			s->init_num=0;
 | 
								s->init_num=0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			break;
 | 
								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_A:
 | 
				
			||||||
		case SSL3_ST_CR_FINISHED_B:
 | 
							case SSL3_ST_CR_FINISHED_B:
 | 
				
			||||||
			s->d1->change_cipher_spec_ok = 1;
 | 
								s->d1->change_cipher_spec_ok = 1;
 | 
				
			||||||
@@ -552,8 +605,14 @@ int dtls1_client_hello(SSL *s)
 | 
				
			|||||||
	buf=(unsigned char *)s->init_buf->data;
 | 
						buf=(unsigned char *)s->init_buf->data;
 | 
				
			||||||
	if (s->state == SSL3_ST_CW_CLNT_HELLO_A)
 | 
						if (s->state == SSL3_ST_CW_CLNT_HELLO_A)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
 | 
							SSL_SESSION *sess = s->session;
 | 
				
			||||||
		if ((s->session == NULL) ||
 | 
							if ((s->session == NULL) ||
 | 
				
			||||||
			(s->session->ssl_version != s->version) ||
 | 
								(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))
 | 
								(s->session->not_resumable))
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
			if (!ssl_get_new_session(s,0))
 | 
								if (!ssl_get_new_session(s,0))
 | 
				
			||||||
@@ -634,7 +693,7 @@ int dtls1_client_hello(SSL *s)
 | 
				
			|||||||
		*(p++)=0; /* Add the NULL method */
 | 
							*(p++)=0; /* Add the NULL method */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifndef OPENSSL_NO_TLSEXT
 | 
					#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);
 | 
								SSLerr(SSL_F_SSL3_CLIENT_HELLO,ERR_R_INTERNAL_ERROR);
 | 
				
			||||||
			goto err;
 | 
								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);
 | 
						(void) BIO_dgram_get_peer(SSL_get_rbio(s), client);
 | 
				
			||||||
	return 1;
 | 
						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);
 | 
								ret=dtls1_send_server_hello(s);
 | 
				
			||||||
			if (ret <= 0) goto end;
 | 
								if (ret <= 0) goto end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef OPENSSL_NO_TLSEXT
 | 
				
			||||||
			if (s->hit)
 | 
								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
 | 
								else
 | 
				
			||||||
				s->state=SSL3_ST_SW_CERT_A;
 | 
									s->state=SSL3_ST_SW_CERT_A;
 | 
				
			||||||
			s->init_num=0;
 | 
								s->init_num=0;
 | 
				
			||||||
@@ -318,10 +328,24 @@ int dtls1_accept(SSL *s)
 | 
				
			|||||||
				dtls1_start_timer(s);
 | 
									dtls1_start_timer(s);
 | 
				
			||||||
				ret=dtls1_send_server_certificate(s);
 | 
									ret=dtls1_send_server_certificate(s);
 | 
				
			||||||
				if (ret <= 0) goto end;
 | 
									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
 | 
								else
 | 
				
			||||||
				skip=1;
 | 
									skip=1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			s->state=SSL3_ST_SW_KEY_EXCH_A;
 | 
								s->state=SSL3_ST_SW_KEY_EXCH_A;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
			s->init_num=0;
 | 
								s->init_num=0;
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -492,11 +516,34 @@ int dtls1_accept(SSL *s)
 | 
				
			|||||||
			dtls1_stop_timer(s);
 | 
								dtls1_stop_timer(s);
 | 
				
			||||||
			if (s->hit)
 | 
								if (s->hit)
 | 
				
			||||||
				s->state=SSL_ST_OK;
 | 
									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
 | 
								else
 | 
				
			||||||
				s->state=SSL3_ST_SW_CHANGE_A;
 | 
									s->state=SSL3_ST_SW_CHANGE_A;
 | 
				
			||||||
			s->init_num=0;
 | 
								s->init_num=0;
 | 
				
			||||||
			break;
 | 
								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_A:
 | 
				
			||||||
		case SSL3_ST_SW_CHANGE_B:
 | 
							case SSL3_ST_SW_CHANGE_B:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -746,7 +793,7 @@ int dtls1_send_server_hello(SSL *s)
 | 
				
			|||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifndef OPENSSL_NO_TLSEXT
 | 
					#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);
 | 
								SSLerr(SSL_F_SSL3_SEND_SERVER_HELLO,ERR_R_INTERNAL_ERROR);
 | 
				
			||||||
			return -1;
 | 
								return -1;
 | 
				
			||||||
@@ -1172,3 +1219,114 @@ int dtls1_send_server_certificate(SSL *s)
 | 
				
			|||||||
	/* SSL3_ST_SW_CERT_B */
 | 
						/* SSL3_ST_SW_CERT_B */
 | 
				
			||||||
	return(dtls1_do_write(s,SSL3_RT_HANDSHAKE));
 | 
						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 SSL_METHOD *ssl3_get_client_method(int ver);
 | 
				
			||||||
static int ca_dn_cmp(const X509_NAME * const *a,const X509_NAME * const *b);
 | 
					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
 | 
					#ifndef OPENSSL_NO_ECDH
 | 
				
			||||||
static int curve_id2nid(int curve_id);
 | 
					static int curve_id2nid(int curve_id);
 | 
				
			||||||
@@ -861,7 +858,7 @@ int ssl3_get_server_hello(SSL *s)
 | 
				
			|||||||
#endif
 | 
					#endif
 | 
				
			||||||
#ifndef OPENSSL_NO_TLSEXT
 | 
					#ifndef OPENSSL_NO_TLSEXT
 | 
				
			||||||
	/* TLS extensions*/
 | 
						/* 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))
 | 
							if (!ssl_parse_serverhello_tlsext(s,&p,d,n, &al))
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
@@ -875,17 +872,6 @@ int ssl3_get_server_hello(SSL *s)
 | 
				
			|||||||
				goto err;
 | 
									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
 | 
					#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);
 | 
							SSLerr(SSL_F_SSL3_GET_NEW_SESSION_TICKET,SSL_R_LENGTH_MISMATCH);
 | 
				
			||||||
		goto f_err;
 | 
							goto f_err;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	p=d=(unsigned char *)s->init_msg;
 | 
						p=d=(unsigned char *)s->init_msg;
 | 
				
			||||||
	n2l(p, s->session->tlsext_tick_lifetime_hint);
 | 
						n2l(p, s->session->tlsext_tick_lifetime_hint);
 | 
				
			||||||
	n2s(p, ticklen);
 | 
						n2s(p, ticklen);
 | 
				
			||||||
@@ -2735,7 +2722,7 @@ static int curve_id2nid(int curve_id)
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifndef OPENSSL_NO_TLSEXT
 | 
					#ifndef OPENSSL_NO_TLSEXT
 | 
				
			||||||
static int ssl3_check_finished(SSL *s)
 | 
					int ssl3_check_finished(SSL *s)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
	int ok;
 | 
						int ok;
 | 
				
			||||||
	long n;
 | 
						long n;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -957,7 +957,7 @@ int ssl3_get_client_hello(SSL *s)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#ifndef OPENSSL_NO_TLSEXT
 | 
					#ifndef OPENSSL_NO_TLSEXT
 | 
				
			||||||
	/* TLS extensions*/
 | 
						/* 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))
 | 
							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);
 | 
								SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_CLIENTHELLO_TLSEXT);
 | 
				
			||||||
			goto err;
 | 
								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
 | 
					#endif
 | 
				
			||||||
	/* Worst case, we will use the NULL compression, but if we have other
 | 
						/* 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
 | 
						 * options, we will now look for them.  We have i-1 compression
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -129,6 +129,9 @@
 | 
				
			|||||||
extern "C" {
 | 
					extern "C" {
 | 
				
			||||||
#endif
 | 
					#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_MD5			0x03000001
 | 
				
			||||||
#define SSL3_CK_RSA_NULL_SHA			0x03000002
 | 
					#define SSL3_CK_RSA_NULL_SHA			0x03000002
 | 
				
			||||||
#define SSL3_CK_RSA_RC4_40_MD5 			0x03000003
 | 
					#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);
 | 
							j = put_cb ? put_cb(c,p) : ssl_put_cipher_by_char(s,c,p);
 | 
				
			||||||
		p+=j;
 | 
							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);
 | 
						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;
 | 
						STACK_OF(SSL_CIPHER) *sk;
 | 
				
			||||||
	int i,n;
 | 
						int i,n;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						s->s3->send_connection_binding = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	n=ssl_put_cipher_by_char(s,NULL,NULL);
 | 
						n=ssl_put_cipher_by_char(s,NULL,NULL);
 | 
				
			||||||
	if ((num%n) != 0)
 | 
						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)
 | 
						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);
 | 
							c=ssl_get_cipher_by_char(s,p);
 | 
				
			||||||
		p+=n;
 | 
							p+=n;
 | 
				
			||||||
		if (c != NULL)
 | 
							if (c != NULL)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -876,7 +876,7 @@ void dtls1_start_timer(SSL *s);
 | 
				
			|||||||
void dtls1_stop_timer(SSL *s);
 | 
					void dtls1_stop_timer(SSL *s);
 | 
				
			||||||
int dtls1_is_timer_expired(SSL *s);
 | 
					int dtls1_is_timer_expired(SSL *s);
 | 
				
			||||||
void dtls1_double_timeout(SSL *s);
 | 
					void dtls1_double_timeout(SSL *s);
 | 
				
			||||||
 | 
					int dtls1_send_newsession_ticket(SSL *s);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* some client-only functions */
 | 
					/* 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_key_exchange(SSL *s);
 | 
				
			||||||
int ssl3_get_server_certificate(SSL *s);
 | 
					int ssl3_get_server_certificate(SSL *s);
 | 
				
			||||||
int ssl3_check_cert_and_algorithm(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_client_hello(SSL *s);
 | 
				
			||||||
int dtls1_send_client_certificate(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_clienthello_tlsext(SSL *s);
 | 
				
			||||||
int ssl_check_serverhello_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
 | 
					#ifdef OPENSSL_NO_SHA256
 | 
				
			||||||
#define tlsext_tick_md	EVP_sha1
 | 
					#define tlsext_tick_md	EVP_sha1
 | 
				
			||||||
#else
 | 
					#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;
 | 
						int extdatalen=0;
 | 
				
			||||||
	unsigned char *ret = p;
 | 
						unsigned char *ret = p;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* don't add extensions for SSLv3 */
 | 
						/* don't add extensions for SSLv3 unless doing secure renegotiation */
 | 
				
			||||||
	if (s->client_version == SSL3_VERSION)
 | 
						if (s->client_version == SSL3_VERSION
 | 
				
			||||||
 | 
										&& !s->s3->send_connection_binding)
 | 
				
			||||||
		return p;
 | 
							return p;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ret+=2;
 | 
						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;
 | 
							int i;
 | 
				
			||||||
		long extlen, idlen, itmp;
 | 
							long extlen, idlen, itmp;
 | 
				
			||||||
@@ -280,8 +282,8 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned cha
 | 
				
			|||||||
	int extdatalen=0;
 | 
						int extdatalen=0;
 | 
				
			||||||
	unsigned char *ret = p;
 | 
						unsigned char *ret = p;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* don't add extensions for SSLv3 */
 | 
						/* don't add extensions for SSLv3, unless doing secure renegotiation */
 | 
				
			||||||
	if (s->version == SSL3_VERSION)
 | 
						if (s->version == SSL3_VERSION && !s->s3->send_connection_binding)
 | 
				
			||||||
		return p;
 | 
							return p;
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	ret+=2;
 | 
						ret+=2;
 | 
				
			||||||
@@ -295,7 +297,7 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned cha
 | 
				
			|||||||
		s2n(0,ret);
 | 
							s2n(0,ret);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if(s->s3->send_connection_binding)
 | 
						if(s->s3->send_connection_binding)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
          int el;
 | 
					          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->servername_done = 0;
 | 
				
			||||||
	s->tlsext_status_type = -1;
 | 
						s->tlsext_status_type = -1;
 | 
				
			||||||
	s->s3->send_connection_binding = 0;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (data >= (d+n-2))
 | 
						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;
 | 
									return 0;
 | 
				
			||||||
			renegotiate_seen = 1;
 | 
								renegotiate_seen = 1;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		else if (type == TLSEXT_TYPE_status_request
 | 
							else if (type == TLSEXT_TYPE_status_request &&
 | 
				
			||||||
						&& s->ctx->tlsext_status_cb)
 | 
							         s->version != DTLS1_VERSION && s->ctx->tlsext_status_cb)
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
		
 | 
							
 | 
				
			||||||
			if (size < 5) 
 | 
								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;
 | 
								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
 | 
								/* MUST be empty and only sent if we've requested
 | 
				
			||||||
			 * a status request message.
 | 
								 * 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,
 | 
					        memcpy(p, s->s3->previous_client_finished,
 | 
				
			||||||
	       s->s3->previous_client_finished_len);
 | 
						       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;
 | 
					    *len=s->s3->previous_client_finished_len + 1;
 | 
				
			||||||
    
 | 
					
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
    return 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)
 | 
					    if(ilen != s->s3->previous_client_finished_len)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
        SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT,SSL_R_RENEGOTIATION_MISMATCH);
 | 
					        SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT,SSL_R_RENEGOTIATION_MISMATCH);
 | 
				
			||||||
        *al=SSL_AD_ILLEGAL_PARAMETER;
 | 
					        *al=SSL_AD_HANDSHAKE_FAILURE;
 | 
				
			||||||
        return 0;
 | 
					        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))
 | 
						      s->s3->previous_client_finished_len))
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
        SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT,SSL_R_RENEGOTIATION_MISMATCH);
 | 
					        SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT,SSL_R_RENEGOTIATION_MISMATCH);
 | 
				
			||||||
        *al=SSL_AD_ILLEGAL_PARAMETER;
 | 
					        *al=SSL_AD_HANDSHAKE_FAILURE;
 | 
				
			||||||
        return 0;
 | 
					        return 0;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					#ifdef OPENSSL_RI_DEBUG
 | 
				
			||||||
 | 
					    fprintf(stderr, "RI extension received by server\n");
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    s->s3->send_connection_binding=1;
 | 
					    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,
 | 
					        memcpy(p, s->s3->previous_server_finished,
 | 
				
			||||||
	       s->s3->previous_server_finished_len);
 | 
						       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
 | 
					    *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)
 | 
					    if(ilen != expected_len)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
        SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT,SSL_R_RENEGOTIATION_MISMATCH);
 | 
					        SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT,SSL_R_RENEGOTIATION_MISMATCH);
 | 
				
			||||||
        *al=SSL_AD_ILLEGAL_PARAMETER;
 | 
					        *al=SSL_AD_HANDSHAKE_FAILURE;
 | 
				
			||||||
        return 0;
 | 
					        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))
 | 
						      s->s3->previous_client_finished_len))
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
        SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT,SSL_R_RENEGOTIATION_MISMATCH);
 | 
					        SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT,SSL_R_RENEGOTIATION_MISMATCH);
 | 
				
			||||||
        *al=SSL_AD_ILLEGAL_PARAMETER;
 | 
					        *al=SSL_AD_HANDSHAKE_FAILURE;
 | 
				
			||||||
        return 0;
 | 
					        return 0;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    d += s->s3->previous_client_finished_len;
 | 
					    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;
 | 
					        *al=SSL_AD_ILLEGAL_PARAMETER;
 | 
				
			||||||
        return 0;
 | 
					        return 0;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					#ifdef OPENSSL_RI_DEBUG
 | 
				
			||||||
 | 
					    fprintf(stderr, "RI extension received by client\n");
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					    s->s3->send_connection_binding=1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return 1;
 | 
					    return 1;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user