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;