Commit f37f20ff authored by Dr. Stephen Henson's avatar Dr. Stephen Henson
Browse files

PR: 2295

Submitted by: Alexei Khlebnikov <alexei.khlebnikov@opera.com>
Reviewed by: steve

OOM checking. Leak in OOM fix. Fall-through comment. Duplicate code
elimination.
parent 101e6e19
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -4,6 +4,9 @@

 Changes between 1.0.1 and 1.1.0  [xx XXX xxxx]

  *) Add TLS v1.2 server support for client authentication. 
     [Steve Henson]

  *) Add support for FIPS mode in ssl library: disable SSLv3, non-FIPS ciphers
     and enable MD5.
     [Steve Henson]
+8 −5
Original line number Diff line number Diff line
@@ -574,7 +574,7 @@ void ssl3_free_digest_list(SSL *s)

void ssl3_finish_mac(SSL *s, const unsigned char *buf, int len)
	{
	if (s->s3->handshake_buffer) 
	if (s->s3->handshake_buffer && !(s->s3->flags & TLS1_FLAGS_KEEP_HANDSHAKE)) 
		{
		BIO_write (s->s3->handshake_buffer,(void *)buf,len);
		} 
@@ -629,9 +629,12 @@ int ssl3_digest_cached_records(SSL *s)
			s->s3->handshake_dgst[i]=NULL;
			}
		}
	if (!(s->s3->flags & TLS1_FLAGS_KEEP_HANDSHAKE))
		{
		/* Free handshake_buffer BIO */
		BIO_free(s->s3->handshake_buffer);
		s->s3->handshake_buffer = NULL;
		}

	return 1;
	}
+111 −2
Original line number Diff line number Diff line
@@ -516,6 +516,9 @@ int ssl3_accept(SSL *s)
				skip=1;
				s->s3->tmp.cert_request=0;
				s->state=SSL3_ST_SW_SRVR_DONE_A;
				if (s->s3->handshake_buffer)
					if (!ssl3_digest_cached_records(s))
						return -1;
				}
			else
				{
@@ -608,6 +611,24 @@ int ssl3_accept(SSL *s)
#endif
				s->init_num = 0;
				}
			else if (s->version >= TLS1_2_VERSION)
				{
				s->state=SSL3_ST_SR_CERT_VRFY_A;
				s->init_num=0;
				if (!s->session->peer)
					break;
				/* For TLS v1.2 freeze the handshake buffer
				 * at this point and digest cached records.
				 */
				if (!s->s3->handshake_buffer)
					{
					SSLerr(SSL_F_SSL3_ACCEPT,ERR_R_INTERNAL_ERROR);
					return -1;
					}
				s->s3->flags |= TLS1_FLAGS_KEEP_HANDSHAKE;
				if (!ssl3_digest_cached_records(s))
					return -1;
				}
			else
				{
				int offset=0;
@@ -1359,8 +1380,11 @@ int ssl3_get_client_hello(SSL *s)
		s->s3->tmp.new_cipher=s->session->cipher;
		}

	if (s->version < TLS1_2_VERSION || !(s->verify_mode & SSL_VERIFY_PEER))
		{
		if (!ssl3_digest_cached_records(s))
			goto f_err;
		}
	
	/* we now have the following setup. 
	 * client_random
@@ -2007,6 +2031,14 @@ int ssl3_send_certificate_request(SSL *s)
		p+=n;
		n++;

		if (s->version >= TLS1_2_VERSION)
			{
			nl = tls12_get_req_sig_algs(s, p + 2);
			s2n(nl, p);
			p += nl + 2;
			n += nl + 2;
			}

		off=n;
		p+=2;
		n+=2;
@@ -2861,6 +2893,9 @@ int ssl3_get_cert_verify(SSL *s)
	long n;
	int type=0,i,j;
	X509 *peer;
	const EVP_MD *md = NULL;
	EVP_MD_CTX mctx;
	EVP_MD_CTX_init(&mctx);

	n=s->method->ssl_get_message(s,
		SSL3_ST_SR_CERT_VRFY_A,
@@ -2929,6 +2964,36 @@ int ssl3_get_cert_verify(SSL *s)
		} 
	else 
		{	
		if (s->version >= TLS1_2_VERSION)
			{
			int sigalg = tls12_get_sigid(pkey);
			/* Should never happen */
			if (sigalg == -1)
				{
				SSLerr(SSL_F_SSL3_GET_CERT_VERIFY,ERR_R_INTERNAL_ERROR);
				al=SSL_AD_INTERNAL_ERROR;
				goto f_err;
				}
			/* Check key type is consistent with signature */
			if (sigalg != (int)p[1])
				{
				SSLerr(SSL_F_SSL3_GET_CERT_VERIFY,SSL_R_WRONG_SIGNATURE_TYPE);
				al=SSL_AD_DECODE_ERROR;
				goto f_err;
				}
			md = tls12_get_hash(p[0]);
			if (md == NULL)
				{
				SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_UNKNOWN_DIGEST);
				al=SSL_AD_DECODE_ERROR;
				goto f_err;
				}
#ifdef SSL_DEBUG
fprintf(stderr, "USING TLSv1.2 HASH %s\n", EVP_MD_name(md));
#endif
			p += 2;
			n -= 2;
			}
		n2s(p,i);
		n-=2;
		if (i > n)
@@ -2946,6 +3011,37 @@ int ssl3_get_cert_verify(SSL *s)
		goto f_err;
		}

	if (s->version >= TLS1_2_VERSION)
		{
		long hdatalen = 0;
		void *hdata;
		hdatalen = BIO_get_mem_data(s->s3->handshake_buffer, &hdata);
		if (hdatalen <= 0)
			{
			SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, ERR_R_INTERNAL_ERROR);
			al=SSL_AD_INTERNAL_ERROR;
			goto f_err;
			}
#ifdef SSL_DEBUG
		fprintf(stderr, "Using TLS 1.2 with client verify alg %s\n",
							EVP_MD_name(md));
#endif
		if (!EVP_VerifyInit_ex(&mctx, md, NULL)
			|| !EVP_VerifyUpdate(&mctx, hdata, hdatalen))
			{
			SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, ERR_R_EVP_LIB);
			al=SSL_AD_INTERNAL_ERROR;
			goto f_err;
			}

		if (EVP_VerifyFinal(&mctx, p , i, pkey) <= 0)
			{
			al=SSL_AD_DECRYPT_ERROR;
			SSLerr(SSL_F_SSL3_GET_CERT_VERIFY,SSL_R_BAD_SIGNATURE);
			goto f_err;
			}
		}
	else
#ifndef OPENSSL_NO_RSA 
	if (pkey->type == EVP_PKEY_RSA)
		{
@@ -3036,6 +3132,13 @@ f_err:
		ssl3_send_alert(s,SSL3_AL_FATAL,al);
		}
end:
	if (s->s3->handshake_buffer)
		{
		BIO_free(s->s3->handshake_buffer);
		s->s3->handshake_buffer = NULL;
		s->s3->flags &= ~TLS1_FLAGS_KEEP_HANDSHAKE;
		}
	EVP_MD_CTX_cleanup(&mctx);
	EVP_PKEY_free(pkey);
	return(ret);
	}
@@ -3148,6 +3251,12 @@ int ssl3_get_client_certificate(SSL *s)
			al=SSL_AD_HANDSHAKE_FAILURE;
			goto f_err;
			}
		/* No client certificate so digest cached records */
		if (s->s3->handshake_buffer && !ssl3_digest_cached_records(s))
			{
			al=SSL_AD_INTERNAL_ERROR;
			goto f_err;
			}
		}
	else
		{
+1 −0
Original line number Diff line number Diff line
@@ -383,6 +383,7 @@ typedef struct ssl3_buffer_st
#define SSL3_FLAGS_POP_BUFFER			0x0004
#define TLS1_FLAGS_TLS_PADDING_BUG		0x0008
#define TLS1_FLAGS_SKIP_CERT_VERIFY		0x0010
#define TLS1_FLAGS_KEEP_HANDSHAKE		0x0020

#ifndef OPENSSL_NO_SSL_INTERN

+1 −0
Original line number Diff line number Diff line
@@ -1096,4 +1096,5 @@ int ssl_parse_clienthello_renegotiate_ext(SSL *s, unsigned char *d, int len,
					  int *al);
long ssl_get_algorithm2(SSL *s);
int tls1_process_sigalgs(SSL *s, const unsigned char *data, int dsize);
int tls12_get_req_sig_algs(SSL *s, unsigned char *p);
#endif
Loading