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

Continuing TLS v1.2 support: add support for server parsing of

signature algorithms extension and correct signature format for
server key exchange.

All ciphersuites should now work on the server but no client support and
no client certificate support yet.
parent c1847111
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -4,6 +4,12 @@

 Changes between 1.0.1 and 1.1.0  [xx XXX xxxx]

  *) Add server support for TLS v1.2 signature algorithms extension. Switch
     to new signature format when needed using client digest preference.
     All server ciphersuites should now work correctly in TLS v1.2. No client
     support yet and no support for client certificates.
     [Steve Henson]

  *) Initial TLS v1.2 support. Add new SHA256 digest to ssl code, switch
     to SHA256 for PRF when using TLS v1.2 and later. Add new SHA256 based
     ciphersuites. At present only RSA key exchange ciphersuites work with
+3 −0
Original line number Diff line number Diff line
@@ -1526,6 +1526,9 @@ bad:
	SSL_CTX_set_quiet_shutdown(ctx,1);
	if (bugs) SSL_CTX_set_options(ctx,SSL_OP_ALL);
	if (hack) SSL_CTX_set_options(ctx,SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG);
	/* HACK while TLS v1.2 is disabled by default */
	if (!(off & SSL_OP_NO_TLSv1_2))
		SSL_CTX_clear_options(ctx, SSL_OP_NO_TLSv1_2);
	SSL_CTX_set_options(ctx,off);
	/* DTLS: partial reads end up discarding unread UDP bytes :-( 
	 * Setting read ahead solves this problem.
+1 −1
Original line number Diff line number Diff line
@@ -1139,7 +1139,7 @@ int dtls1_send_server_key_exchange(SSL *s)
		if (!(s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL)
			&& !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK))
			{
			if ((pkey=ssl_get_sign_pkey(s,s->s3->tmp.new_cipher))
			if ((pkey=ssl_get_sign_pkey(s,s->s3->tmp.new_cipher, NULL))
				== NULL)
				{
				al=SSL_AD_DECODE_ERROR;
+20 −25
Original line number Diff line number Diff line
@@ -1530,6 +1530,7 @@ int ssl3_send_server_key_exchange(SSL *s)
	BN_CTX *bn_ctx = NULL; 
#endif
	EVP_PKEY *pkey;
	const EVP_MD *md = NULL;
	unsigned char *p,*d;
	int al,i;
	unsigned long type;
@@ -1810,7 +1811,7 @@ int ssl3_send_server_key_exchange(SSL *s)
		if (!(s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL)
			&& !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK))
			{
			if ((pkey=ssl_get_sign_pkey(s,s->s3->tmp.new_cipher))
			if ((pkey=ssl_get_sign_pkey(s,s->s3->tmp.new_cipher,&md))
				== NULL)
				{
				al=SSL_AD_DECODE_ERROR;
@@ -1888,7 +1889,8 @@ int ssl3_send_server_key_exchange(SSL *s)
			/* n is the length of the params, they start at &(d[4])
			 * and p points to the space at the end. */
#ifndef OPENSSL_NO_RSA
			if (pkey->type == EVP_PKEY_RSA)
			if (pkey->type == EVP_PKEY_RSA
					&& s->version < TLS1_2_VERSION)
				{
				q=md_buf;
				j=0;
@@ -1915,44 +1917,37 @@ int ssl3_send_server_key_exchange(SSL *s)
				}
			else
#endif
#if !defined(OPENSSL_NO_DSA)
				if (pkey->type == EVP_PKEY_DSA)
			if (md)
				{
				/* lets do DSS */
				EVP_SignInit_ex(&md_ctx,EVP_dss1(), NULL);
				EVP_SignUpdate(&md_ctx,&(s->s3->client_random[0]),SSL3_RANDOM_SIZE);
				EVP_SignUpdate(&md_ctx,&(s->s3->server_random[0]),SSL3_RANDOM_SIZE);
				EVP_SignUpdate(&md_ctx,&(d[4]),n);
				if (!EVP_SignFinal(&md_ctx,&(p[2]),
					(unsigned int *)&i,pkey))
				/* For TLS1.2 and later send signature
				 * algorithm */
				if (s->version >= TLS1_2_VERSION)
					{
					SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,ERR_LIB_DSA);
					goto err;
					if (!tls12_get_sigandhash(p, pkey, md))
						{
						/* Should never happen */
						al=SSL_AD_INTERNAL_ERROR;
						SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,ERR_R_INTERNAL_ERROR);
						goto f_err;
						}
				s2n(i,p);
				n+=i+2;
					p+=2;
					}
			else
#endif
#if !defined(OPENSSL_NO_ECDSA)
				if (pkey->type == EVP_PKEY_EC)
				{
				/* let's do ECDSA */
				EVP_SignInit_ex(&md_ctx,EVP_ecdsa(), NULL);
				EVP_SignInit_ex(&md_ctx, md, NULL);
				EVP_SignUpdate(&md_ctx,&(s->s3->client_random[0]),SSL3_RANDOM_SIZE);
				EVP_SignUpdate(&md_ctx,&(s->s3->server_random[0]),SSL3_RANDOM_SIZE);
				EVP_SignUpdate(&md_ctx,&(d[4]),n);
				if (!EVP_SignFinal(&md_ctx,&(p[2]),
					(unsigned int *)&i,pkey))
					{
					SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,ERR_LIB_ECDSA);
					SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,ERR_LIB_EVP);
					goto err;
					}
				s2n(i,p);
				n+=i+2;
				if (s->version >= TLS1_2_VERSION)
					n+= 2;
				}
			else
#endif
				{
				/* Is this error check actually needed? */
				al=SSL_AD_HANDSHAKE_FAILURE;
+20 −1
Original line number Diff line number Diff line
@@ -160,6 +160,21 @@ int SSL_get_ex_data_X509_STORE_CTX_idx(void)
	return ssl_x509_store_ctx_idx;
	}

static void ssl_cert_set_default_md(CERT *cert)
	{
	/* Set digest values to defaults */
#ifndef OPENSSL_NO_DSA
	cert->pkeys[SSL_PKEY_DSA_SIGN].digest = EVP_dss1();
#endif
#ifndef OPENSSL_NO_RSA
	cert->pkeys[SSL_PKEY_RSA_SIGN].digest = EVP_sha1();
	cert->pkeys[SSL_PKEY_RSA_ENC].digest = EVP_sha1();
#endif
#ifndef OPENSSL_NO_ECDSA
	cert->pkeys[SSL_PKEY_ECC].digest = EVP_ecdsa();
#endif
	}

CERT *ssl_cert_new(void)
	{
	CERT *ret;
@@ -174,7 +189,7 @@ CERT *ssl_cert_new(void)

	ret->key= &(ret->pkeys[SSL_PKEY_RSA_ENC]);
	ret->references=1;

	ssl_cert_set_default_md(ret);
	return(ret);
	}

@@ -307,6 +322,10 @@ CERT *ssl_cert_dup(CERT *cert)
	 * chain is held inside SSL_CTX */

	ret->references=1;
	/* Set digests to defaults. NB: we don't copy existing values as they
	 * will be set during handshake.
	 */
	ssl_cert_set_default_md(ret);

	return(ret);
	
Loading