untrusted comment: signature from openbsd 5.6 base private key
RWR0EANmo9nqhpxHVrEZWmf2qAA9zblsetB0gpcMFrkMumxjVXGdcaRNHc7TS+IkdiYNDncAU2qjYSaM8bDI+nQp9HUayjp3RQQ=

OpenBSD 5.6 errata 17, Mar 13, 2015:

Don't permit TLS client connections to be downgraded to weak keys.

Apply by doing:
    cd /usr/src
    signify -Vep /etc/signify/openbsd-56-base.pub -x 017_openssl.patch.sig -m - | \
        patch -p0

And then rebuild and install libssl:
    cd lib/libssl/ssl
    make obj
    make depend
    make
    make install


Index: lib/libssl/src/ssl/d1_clnt.c
===================================================================
RCS file: /cvs/src/lib/libssl/src/ssl/d1_clnt.c,v
retrieving revision 1.33
diff -u -p -r1.33 d1_clnt.c
--- lib/libssl/src/ssl/d1_clnt.c	7 Aug 2014 20:02:23 -0000	1.33
+++ lib/libssl/src/ssl/d1_clnt.c	10 Mar 2015 17:11:46 -0000
@@ -939,20 +939,16 @@ dtls1_send_client_key_exchange(SSL *s)
 			RSA *rsa;
 			unsigned char tmp_buf[SSL_MAX_MASTER_KEY_LENGTH];
 
-			if (s->session->sess_cert->peer_rsa_tmp != NULL)
-				rsa = s->session->sess_cert->peer_rsa_tmp;
-			else {
-				pkey = X509_get_pubkey(s->session->sess_cert->peer_pkeys[SSL_PKEY_RSA_ENC].x509);
-				if ((pkey == NULL) ||
-				    (pkey->type != EVP_PKEY_RSA) ||
-				    (pkey->pkey.rsa == NULL)) {
-					SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,
-					    ERR_R_INTERNAL_ERROR);
-					goto err;
-				}
-				rsa = pkey->pkey.rsa;
-				EVP_PKEY_free(pkey);
+			pkey = X509_get_pubkey(s->session->sess_cert->peer_pkeys[SSL_PKEY_RSA_ENC].x509);
+			if ((pkey == NULL) ||
+			    (pkey->type != EVP_PKEY_RSA) ||
+			    (pkey->pkey.rsa == NULL)) {
+				SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,
+				    ERR_R_INTERNAL_ERROR);
+				goto err;
 			}
+			rsa = pkey->pkey.rsa;
+			EVP_PKEY_free(pkey);
 
 			tmp_buf[0] = s->client_version >> 8;
 			tmp_buf[1] = s->client_version&0xff;
Index: lib/libssl/src/ssl/s3_clnt.c
===================================================================
RCS file: /cvs/src/lib/libssl/src/ssl/s3_clnt.c,v
retrieving revision 1.85
diff -u -p -r1.85 s3_clnt.c
--- lib/libssl/src/ssl/s3_clnt.c	7 Aug 2014 01:24:10 -0000	1.85
+++ lib/libssl/src/ssl/s3_clnt.c	10 Mar 2015 17:11:59 -0000
@@ -1162,6 +1162,9 @@ ssl3_get_key_exchange(SSL *s)
 	int		 curve_nid = 0;
 	int		 encoded_pt_len = 0;
 
+	alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
+	alg_a = s->s3->tmp.new_cipher->algorithm_auth;
+
 	/*
 	 * Use same message size as in ssl3_get_certificate_request()
 	 * as ServerKeyExchange message may be skipped.
@@ -1170,17 +1173,27 @@ ssl3_get_key_exchange(SSL *s)
 	    SSL3_ST_CR_KEY_EXCH_B, -1, s->max_cert_list, &ok);
 	if (!ok)
 		return ((int)n);
+	
+	EVP_MD_CTX_init(&md_ctx);
 
 	if (s->s3->tmp.message_type != SSL3_MT_SERVER_KEY_EXCHANGE) {
+		/*
+		 * Do not skip server key exchange if this cipher suite uses
+		 * ephemeral keys.
+		 */
+		if (alg_k & (SSL_kDHE|SSL_kECDHE)) {
+			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,
+			    SSL_R_UNEXPECTED_MESSAGE);
+			al = SSL_AD_UNEXPECTED_MESSAGE;
+			goto f_err;
+		}
+
 		s->s3->tmp.reuse_message = 1;
+		EVP_MD_CTX_cleanup(&md_ctx);
 		return (1);
 	}
 
-	param = p = (unsigned char *)s->init_msg;
 	if (s->session->sess_cert != NULL) {
-		RSA_free(s->session->sess_cert->peer_rsa_tmp);
-		s->session->sess_cert->peer_rsa_tmp = NULL;
-
 		DH_free(s->session->sess_cert->peer_dh_tmp);
 		s->session->sess_cert->peer_dh_tmp = NULL;
 
@@ -1192,68 +1205,10 @@ ssl3_get_key_exchange(SSL *s)
 			goto err; 
 	}
 
+	param = p = (unsigned char *)s->init_msg;
 	param_len = 0;
-	alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
-	alg_a = s->s3->tmp.new_cipher->algorithm_auth;
-	EVP_MD_CTX_init(&md_ctx);
-
-	if (alg_k & SSL_kRSA) {
-		if ((rsa = RSA_new()) == NULL) {
-			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,
-			    ERR_R_MALLOC_FAILURE);
-			goto err;
-		}
-		if (2 > n)
-			goto truncated;
-		n2s(p, i);
-		param_len = i + 2;
-		if (param_len > n) {
-			al = SSL_AD_DECODE_ERROR;
-			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,
-			    SSL_R_BAD_RSA_MODULUS_LENGTH);
-			goto f_err;
-		}
-		if (!(rsa->n = BN_bin2bn(p, i, rsa->n))) {
-			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,
-			    ERR_R_BN_LIB);
-			goto err;
-		}
-		p += i;
 
-		if (param_len + 2 > n)
-			goto truncated;
-		n2s(p, i);
-		param_len += i + 2;
-		if (param_len > n) {
-			al = SSL_AD_DECODE_ERROR;
-			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,
-			    SSL_R_BAD_RSA_E_LENGTH);
-			goto f_err;
-		}
-		if (!(rsa->e = BN_bin2bn(p, i, rsa->e))) {
-			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,
-			    ERR_R_BN_LIB);
-			goto err;
-		}
-		p += i;
-		n -= param_len;
-
-		/*
-		 * This should be because we are using an
-		 * export cipher
-		 */
-		if (alg_a & SSL_aRSA)
-			pkey = X509_get_pubkey(
-			    s->session->sess_cert->peer_pkeys[
-			    SSL_PKEY_RSA_ENC].x509);
-		else {
-			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,
-			    ERR_R_INTERNAL_ERROR);
-			goto err;
-		}
-		s->session->sess_cert->peer_rsa_tmp = rsa;
-		rsa = NULL;
-	} else if (alg_k & SSL_kDHE) {
+	if (alg_k & SSL_kDHE) {
 		if ((dh = DH_new()) == NULL) {
 			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,
 			    ERR_R_DH_LIB);
@@ -1311,6 +1266,17 @@ ssl3_get_key_exchange(SSL *s)
 		p += i;
 		n -= param_len;
 
+		/*
+		 * Check the strength of the DH key just constructed.
+		 * Discard keys weaker than 1024 bits.
+		 */
+
+		if (DH_size(dh) < 1024 / 8) {
+			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,
+			    SSL_R_BAD_DH_P_LENGTH);
+			goto err;
+		}
+
 		if (alg_a & SSL_aRSA)
 			pkey = X509_get_pubkey(
 			    s->session->sess_cert->peer_pkeys[
@@ -1953,23 +1919,19 @@ ssl3_send_client_key_exchange(SSL *s)
 				goto err;
 			}
 
-			if (s->session->sess_cert->peer_rsa_tmp != NULL)
-				rsa = s->session->sess_cert->peer_rsa_tmp;
-			else {
-				pkey = X509_get_pubkey(
-				    s->session->sess_cert->peer_pkeys[
-				    SSL_PKEY_RSA_ENC].x509);
-				if ((pkey == NULL) ||
-				    (pkey->type != EVP_PKEY_RSA) ||
-				    (pkey->pkey.rsa == NULL)) {
-					SSLerr(
-					    SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,
-					    ERR_R_INTERNAL_ERROR);
-					goto err;
-				}
-				rsa = pkey->pkey.rsa;
+			pkey = X509_get_pubkey(
+			    s->session->sess_cert->peer_pkeys[
+			    SSL_PKEY_RSA_ENC].x509);
+			if ((pkey == NULL) ||
+			    (pkey->type != EVP_PKEY_RSA) ||
+			    (pkey->pkey.rsa == NULL)) {
+				SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,
+				    ERR_R_INTERNAL_ERROR);
 				EVP_PKEY_free(pkey);
+				goto err;
 			}
+			rsa = pkey->pkey.rsa;
+			EVP_PKEY_free(pkey);
 
 			tmp_buf[0] = s->client_version >> 8;
 			tmp_buf[1] = s->client_version & 0xff;
@@ -2598,7 +2560,6 @@ ssl3_check_cert_and_algorithm(SSL *s)
 	long		 alg_k, alg_a;
 	EVP_PKEY	*pkey = NULL;
 	SESS_CERT	*sc;
-	RSA		*rsa;
 	DH		*dh;
 
 	alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
@@ -2614,8 +2575,6 @@ ssl3_check_cert_and_algorithm(SSL *s)
 		    ERR_R_INTERNAL_ERROR);
 		goto err;
 	}
-
-	rsa = s->session->sess_cert->peer_rsa_tmp;
 	dh = s->session->sess_cert->peer_dh_tmp;
 
 	/* This is the passed certificate. */
@@ -2648,7 +2607,7 @@ ssl3_check_cert_and_algorithm(SSL *s)
 		goto f_err;
 	}
 	if ((alg_k & SSL_kRSA) &&
-	    !(has_bits(i, EVP_PK_RSA|EVP_PKT_ENC) || (rsa != NULL))) {
+	    !has_bits(i, EVP_PK_RSA|EVP_PKT_ENC)) {
 		SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,
 		    SSL_R_MISSING_RSA_ENCRYPTING_CERT);
 		goto f_err;
Index: lib/libssl/src/ssl/ssl_cert.c
===================================================================
RCS file: /cvs/src/lib/libssl/src/ssl/ssl_cert.c,v
retrieving revision 1.41
diff -u -p -r1.41 ssl_cert.c
--- lib/libssl/src/ssl/ssl_cert.c	10 Jul 2014 08:25:00 -0000	1.41
+++ lib/libssl/src/ssl/ssl_cert.c	10 Mar 2015 17:11:46 -0000
@@ -407,7 +407,6 @@ ssl_sess_cert_free(SESS_CERT *sc)
 			X509_free(sc->peer_pkeys[i].x509);
 	}
 
-	RSA_free(sc->peer_rsa_tmp);
 	DH_free(sc->peer_dh_tmp);
 	EC_KEY_free(sc->peer_ecdh_tmp);
 
Index: lib/libssl/src/ssl/ssl_locl.h
===================================================================
RCS file: /cvs/src/lib/libssl/src/ssl/ssl_locl.h,v
retrieving revision 1.63
diff -u -p -r1.63 ssl_locl.h
--- lib/libssl/src/ssl/ssl_locl.h	28 Jul 2014 04:23:12 -0000	1.63
+++ lib/libssl/src/ssl/ssl_locl.h	10 Mar 2015 17:11:46 -0000
@@ -464,7 +464,7 @@ typedef struct sess_cert_st {
 	/* Obviously we don't have the private keys of these,
 	 * so maybe we shouldn't even use the CERT_PKEY type here. */
 
-	RSA *peer_rsa_tmp;
+	RSA *__peer_rsa_tmp;
 	DH *peer_dh_tmp;
 	EC_KEY *peer_ecdh_tmp;