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;