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

Support for fixed DH ciphersuites.

The cipher definitions of these ciphersuites have been around since SSLeay
but were always disabled. Now OpenSSL supports DH certificates they can be
finally enabled.

Various additional changes were needed to make them work properly: many
unused fixed DH sections of code were untested.
parent a985410d
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -4,6 +4,10 @@

 Changes between 1.0.1 and 1.1.0  [xx XXX xxxx]

  *) Support for fixed DH ciphersuites: those requiring DH server
     certificates.
     [Steve Henson]

  *) Transparently support X9.42 DH parameters when calling
     PEM_read_bio_DHparameters. This means existing applications can handle
     the new parameter format automatically.
+12 −0
Original line number Diff line number Diff line
@@ -594,6 +594,18 @@ int ssl_cert_type(X509 *x, EVP_PKEY *pkey)
		{
		ret = SSL_PKEY_GOST01;
		}
	else if (x && i == EVP_PKEY_DH)
		{
		/* For DH two cases: DH certificate signed with RSA and
		 * DH certificate signed with DSA.
		 */
		i = X509_certificate_type(x, pk);
		if (i & EVP_PKS_RSA)
			ret = SSL_PKEY_DH_RSA;
		else if (i & EVP_PKS_DSA)
			ret = SSL_PKEY_DH_DSA;
		}
		
err:
	if(!pkey) EVP_PKEY_free(pk);
	return(ret);
+30 −11
Original line number Diff line number Diff line
@@ -2396,23 +2396,38 @@ int ssl3_send_client_key_exchange(SSL *s)
		else if (alg_k & (SSL_kEDH|SSL_kDHr|SSL_kDHd))
			{
			DH *dh_srvr,*dh_clnt;
			SESS_CERT *scert = s->session->sess_cert;

			if (s->session->sess_cert == NULL) 
			if (scert == NULL) 
				{
				ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_UNEXPECTED_MESSAGE);
				SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,SSL_R_UNEXPECTED_MESSAGE);
				goto err;
				}

			if (s->session->sess_cert->peer_dh_tmp != NULL)
				dh_srvr=s->session->sess_cert->peer_dh_tmp;
			if (scert->peer_dh_tmp != NULL)
				dh_srvr=scert->peer_dh_tmp;
			else
				{
				/* we get them from the cert */
				ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_HANDSHAKE_FAILURE);
				SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,SSL_R_UNABLE_TO_FIND_DH_PARAMETERS);
				int idx = scert->peer_cert_type;
				EVP_PKEY *spkey = NULL;
				dh_srvr = NULL;
				if (idx >= 0)
					spkey = X509_get_pubkey(
						scert->peer_pkeys[idx].x509);
				if (spkey)
					{
					dh_srvr = EVP_PKEY_get1_DH(spkey);
					EVP_PKEY_free(spkey);
					}
				if (dh_srvr == NULL)
					{
					SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,
					    ERR_R_INTERNAL_ERROR);
					goto err;
					}
				}

			/* generate a new random key */
			if ((dh_clnt=DHparams_dup(dh_srvr)) == NULL)
@@ -2431,6 +2446,8 @@ int ssl3_send_client_key_exchange(SSL *s)
			 * make sure to clear it out afterwards */

			n=DH_compute_key(p,dh_srvr->pub_key,dh_clnt);
			if (scert->peer_dh_tmp == NULL)
				DH_free(dh_srvr);

			if (n <= 0)
				{
@@ -3132,7 +3149,7 @@ int ssl3_check_cert_and_algorithm(SSL *s)
	alg_a=s->s3->tmp.new_cipher->algorithm_auth;

	/* we don't have a certificate */
	if ((alg_a & (SSL_aDH|SSL_aNULL|SSL_aKRB5)) || (alg_k & SSL_kPSK))
	if ((alg_a & (SSL_aNULL|SSL_aKRB5)) || (alg_k & SSL_kPSK))
		return(1);

	sc=s->session->sess_cert;
@@ -3200,13 +3217,15 @@ int ssl3_check_cert_and_algorithm(SSL *s)
		SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,SSL_R_MISSING_DH_KEY);
		goto f_err;
		}
	else if ((alg_k & SSL_kDHr) && !has_bits(i,EVP_PK_DH|EVP_PKS_RSA))
	else if ((alg_k & SSL_kDHr) && (TLS1_get_version(s) < TLS1_2_VERSION) &&
		!has_bits(i,EVP_PK_DH|EVP_PKS_RSA))
		{
		SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,SSL_R_MISSING_DH_RSA_CERT);
		goto f_err;
		}
#ifndef OPENSSL_NO_DSA
	else if ((alg_k & SSL_kDHd) && !has_bits(i,EVP_PK_DH|EVP_PKS_DSA))
	else if ((alg_k & SSL_kDHd) && (TLS1_get_version(s) < TLS1_2_VERSION) &&
		!has_bits(i,EVP_PK_DH|EVP_PKS_DSA))
		{
		SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,SSL_R_MISSING_DH_DSA_CERT);
		goto f_err;
+24 −24
Original line number Diff line number Diff line
@@ -335,7 +335,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={
/* The DH ciphers */
/* Cipher 0B */
	{
	0,
	1,
	SSL3_TXT_DH_DSS_DES_40_CBC_SHA,
	SSL3_CK_DH_DSS_DES_40_CBC_SHA,
	SSL_kDHd,
@@ -351,7 +351,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={

/* Cipher 0C */
	{
	0, /* not implemented (non-ephemeral DH) */
	1,
	SSL3_TXT_DH_DSS_DES_64_CBC_SHA,
	SSL3_CK_DH_DSS_DES_64_CBC_SHA,
	SSL_kDHd,
@@ -367,7 +367,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={

/* Cipher 0D */
	{
	0, /* not implemented (non-ephemeral DH) */
	1,
	SSL3_TXT_DH_DSS_DES_192_CBC3_SHA,
	SSL3_CK_DH_DSS_DES_192_CBC3_SHA,
	SSL_kDHd,
@@ -383,7 +383,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={

/* Cipher 0E */
	{
	0, /* not implemented (non-ephemeral DH) */
	1,
	SSL3_TXT_DH_RSA_DES_40_CBC_SHA,
	SSL3_CK_DH_RSA_DES_40_CBC_SHA,
	SSL_kDHr,
@@ -399,7 +399,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={

/* Cipher 0F */
	{
	0, /* not implemented (non-ephemeral DH) */
	1,
	SSL3_TXT_DH_RSA_DES_64_CBC_SHA,
	SSL3_CK_DH_RSA_DES_64_CBC_SHA,
	SSL_kDHr,
@@ -415,7 +415,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={

/* Cipher 10 */
	{
	0, /* not implemented (non-ephemeral DH) */
	1,
	SSL3_TXT_DH_RSA_DES_192_CBC3_SHA,
	SSL3_CK_DH_RSA_DES_192_CBC3_SHA,
	SSL_kDHr,
@@ -902,7 +902,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={
	},
/* Cipher 30 */
	{
	0,
	1,
	TLS1_TXT_DH_DSS_WITH_AES_128_SHA,
	TLS1_CK_DH_DSS_WITH_AES_128_SHA,
	SSL_kDHd,
@@ -917,7 +917,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={
	},
/* Cipher 31 */
	{
	0,
	1,
	TLS1_TXT_DH_RSA_WITH_AES_128_SHA,
	TLS1_CK_DH_RSA_WITH_AES_128_SHA,
	SSL_kDHr,
@@ -993,7 +993,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={
	},
/* Cipher 36 */
	{
	0,
	1,
	TLS1_TXT_DH_DSS_WITH_AES_256_SHA,
	TLS1_CK_DH_DSS_WITH_AES_256_SHA,
	SSL_kDHd,
@@ -1009,7 +1009,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={

/* Cipher 37 */
	{
	0, /* not implemented (non-ephemeral DH) */
	1,
	TLS1_TXT_DH_RSA_WITH_AES_256_SHA,
	TLS1_CK_DH_RSA_WITH_AES_256_SHA,
	SSL_kDHr,
@@ -1122,7 +1122,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={

	/* Cipher 3E */
	{
	0, /* not implemented (non-ephemeral DH) */
	1,
	TLS1_TXT_DH_DSS_WITH_AES_128_SHA256,
	TLS1_CK_DH_DSS_WITH_AES_128_SHA256,
	SSL_kDHr,
@@ -1138,7 +1138,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={

	/* Cipher 3F */
	{
	0, /* not implemented (non-ephemeral DH) */
	1,
	TLS1_TXT_DH_RSA_WITH_AES_128_SHA256,
	TLS1_CK_DH_RSA_WITH_AES_128_SHA256,
	SSL_kDHr,
@@ -1189,7 +1189,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={

	/* Cipher 42 */
	{
	0, /* not implemented (non-ephemeral DH) */
	1,
	TLS1_TXT_DH_DSS_WITH_CAMELLIA_128_CBC_SHA,
	TLS1_CK_DH_DSS_WITH_CAMELLIA_128_CBC_SHA,
	SSL_kDHd,
@@ -1205,7 +1205,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={

	/* Cipher 43 */
	{
	0, /* not implemented (non-ephemeral DH) */
	1,
	TLS1_TXT_DH_RSA_WITH_CAMELLIA_128_CBC_SHA,
	TLS1_CK_DH_RSA_WITH_CAMELLIA_128_CBC_SHA,
	SSL_kDHr,
@@ -1404,7 +1404,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={

	/* Cipher 68 */
	{
	0, /* not implemented (non-ephemeral DH) */
	1,
	TLS1_TXT_DH_DSS_WITH_AES_256_SHA256,
	TLS1_CK_DH_DSS_WITH_AES_256_SHA256,
	SSL_kDHr,
@@ -1420,7 +1420,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={

	/* Cipher 69 */
	{
	0, /* not implemented (non-ephemeral DH) */
	1,
	TLS1_TXT_DH_RSA_WITH_AES_256_SHA256,
	TLS1_CK_DH_RSA_WITH_AES_256_SHA256,
	SSL_kDHr,
@@ -1577,7 +1577,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={
	},
	/* Cipher 85 */
	{
	0, /* not implemented (non-ephemeral DH) */
	1,
	TLS1_TXT_DH_DSS_WITH_CAMELLIA_256_CBC_SHA,
	TLS1_CK_DH_DSS_WITH_CAMELLIA_256_CBC_SHA,
	SSL_kDHd,
@@ -1593,7 +1593,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={

	/* Cipher 86 */
	{
	0, /* not implemented (non-ephemeral DH) */
	1,
	TLS1_TXT_DH_RSA_WITH_CAMELLIA_256_CBC_SHA,
	TLS1_CK_DH_RSA_WITH_CAMELLIA_256_CBC_SHA,
	SSL_kDHr,
@@ -1743,7 +1743,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={

	/* Cipher 97 */
	{
	0, /* not implemented (non-ephemeral DH) */
	1,
	TLS1_TXT_DH_DSS_WITH_SEED_SHA,
	TLS1_CK_DH_DSS_WITH_SEED_SHA,
	SSL_kDHd,
@@ -1759,7 +1759,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={

	/* Cipher 98 */
	{
	0, /* not implemented (non-ephemeral DH) */
	1,
	TLS1_TXT_DH_RSA_WITH_SEED_SHA,
	TLS1_CK_DH_RSA_WITH_SEED_SHA,
	SSL_kDHr,
@@ -1891,7 +1891,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={

	/* Cipher A0 */
	{
	0,
	1,
	TLS1_TXT_DH_RSA_WITH_AES_128_GCM_SHA256,
	TLS1_CK_DH_RSA_WITH_AES_128_GCM_SHA256,
	SSL_kDHr,
@@ -1907,7 +1907,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={

	/* Cipher A1 */
	{
	0,
	1,
	TLS1_TXT_DH_RSA_WITH_AES_256_GCM_SHA384,
	TLS1_CK_DH_RSA_WITH_AES_256_GCM_SHA384,
	SSL_kDHr,
@@ -1955,7 +1955,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={

	/* Cipher A4 */
	{
	0,
	1,
	TLS1_TXT_DH_DSS_WITH_AES_128_GCM_SHA256,
	TLS1_CK_DH_DSS_WITH_AES_128_GCM_SHA256,
	SSL_kDHr,
@@ -1971,7 +1971,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={

	/* Cipher A5 */
	{
	0,
	1,
	TLS1_TXT_DH_DSS_WITH_AES_256_GCM_SHA384,
	TLS1_CK_DH_DSS_WITH_AES_256_GCM_SHA384,
	SSL_kDHr,
+20 −2
Original line number Diff line number Diff line
@@ -478,7 +478,7 @@ int ssl3_accept(SSL *s)
			    /* SRP: send ServerKeyExchange */
			    || (alg_k & SSL_kSRP)
#endif
			    || (alg_k & (SSL_kDHr|SSL_kDHd|SSL_kEDH))
			    || (alg_k & SSL_kEDH)
			    || (alg_k & SSL_kEECDH)
			    || ((alg_k & SSL_kRSA)
				&& (s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey == NULL
@@ -2289,7 +2289,25 @@ int ssl3_get_client_key_exchange(SSL *s)
			}
		else
			{
			if (s->s3->tmp.dh == NULL)
			int idx = -1;
			if (alg_k & SSL_kDHr)
				idx = SSL_PKEY_DH_RSA;
			else if (alg_k & SSL_kDHd)
				idx = SSL_PKEY_DH_DSA;
			if (idx >= 0)
				{
				EVP_PKEY *skey = s->cert->pkeys[idx].privatekey;
				if ((skey == NULL) ||
					(skey->type != EVP_PKEY_DH) ||
					(skey->pkey.dh == NULL))
					{
					al=SSL_AD_HANDSHAKE_FAILURE;
					SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_MISSING_RSA_CERTIFICATE);
					goto f_err;
					}
				dh_srvr = skey->pkey.dh;
				}
			else if (s->s3->tmp.dh == NULL)
				{
				al=SSL_AD_HANDSHAKE_FAILURE;
				SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_MISSING_TMP_DH_KEY);
Loading