From: Dr. Stephen Henson Date: Fri, 16 Jun 2017 17:55:28 +0000 (+0100) Subject: Allow Ed25519 in TLS 1.2 X-Git-Tag: OpenSSL_1_1_1-pre1~1261 X-Git-Url: https://git.openssl.org/?p=openssl.git;a=commitdiff_plain;h=b2021556e4b838f451459deab2b2eee9b40c9169 Allow Ed25519 in TLS 1.2 Reviewed-by: Matt Caswell (Merged from https://github.com/openssl/openssl/pull/3585) --- diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c index a535e13373..a46ede1414 100644 --- a/ssl/ssl_lib.c +++ b/ssl/ssl_lib.c @@ -2969,6 +2969,11 @@ void ssl_set_masks(SSL *s) if (ecdsa_ok) mask_a |= SSL_aECDSA; } + /* Allow Ed25519 for TLS 1.2 if peer supports it */ + if (!(mask_a & SSL_aECDSA) && ssl_has_cert(s, SSL_PKEY_ED25519) + && pvalid[SSL_PKEY_ED25519] & CERT_PKEY_EXPLICIT_SIGN + && TLS1_get_version(s) == TLS1_2_VERSION) + mask_a |= SSL_aECDSA; #endif #ifndef OPENSSL_NO_EC diff --git a/ssl/statem/statem_clnt.c b/ssl/statem/statem_clnt.c index 46439359fb..711680e917 100644 --- a/ssl/statem/statem_clnt.c +++ b/ssl/statem/statem_clnt.c @@ -1790,9 +1790,10 @@ MSG_PROCESS_RETURN tls_process_server_certificate(SSL *s, PACKET *pkt) if (!SSL_IS_TLS13(s)) { exp_idx = ssl_cipher_get_cert_index(s->s3->tmp.new_cipher); if (exp_idx >= 0 && i != exp_idx - && (exp_idx != SSL_PKEY_GOST_EC || - (i != SSL_PKEY_GOST12_512 && i != SSL_PKEY_GOST12_256 - && i != SSL_PKEY_GOST01))) { + && (exp_idx != SSL_PKEY_ECC || i != SSL_PKEY_ED25519) + && (exp_idx != SSL_PKEY_GOST_EC || + (i != SSL_PKEY_GOST12_512 && i != SSL_PKEY_GOST12_256 + && i != SSL_PKEY_GOST01))) { x = NULL; al = SSL_AD_ILLEGAL_PARAMETER; SSLerr(SSL_F_TLS_PROCESS_SERVER_CERTIFICATE, @@ -2210,7 +2211,10 @@ MSG_PROCESS_RETURN tls_process_key_exchange(SSL *s, PACKET *pkt) goto err; } - md = ssl_md(s->s3->tmp.peer_sigalg->hash_idx); + if (!tls1_lookup_md(s->s3->tmp.peer_sigalg, &md)) { + al = SSL_AD_INTERNAL_ERROR; + goto err; + } if (!PACKET_get_length_prefixed_2(pkt, &signature) || PACKET_remaining(pkt) != 0) { @@ -3352,7 +3356,7 @@ int ssl3_check_cert_and_algorithm(SSL *s) #ifndef OPENSSL_NO_EC idx = s->session->peer_type; - if (idx == SSL_PKEY_ECC) { + if (idx == SSL_PKEY_ECC || idx == SSL_PKEY_ED25519) { if (ssl_check_srvr_ecc_cert_and_alg(s->session->peer, s) == 0) { /* check failed */ SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, SSL_R_BAD_ECC_CERT); diff --git a/ssl/statem/statem_srvr.c b/ssl/statem/statem_srvr.c index 6168b98ede..05405b0e0d 100644 --- a/ssl/statem/statem_srvr.c +++ b/ssl/statem/statem_srvr.c @@ -2415,7 +2415,7 @@ int tls_construct_server_key_exchange(SSL *s, WPACKET *pkt) size_t siglen, tbslen; int rv; - if (pkey == NULL || md == NULL) { + if (pkey == NULL || !tls1_lookup_md(lu, &md)) { /* Should never happen */ al = SSL_AD_INTERNAL_ERROR; SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE, diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c index cf11921727..0f1d95be31 100644 --- a/ssl/t1_lib.c +++ b/ssl/t1_lib.c @@ -1498,6 +1498,7 @@ void ssl_set_sig_mask(uint32_t *pmask_a, SSL *s, int op) break; #endif #ifndef OPENSSL_NO_EC + case NID_ED25519: case EVP_PKEY_EC: if (!have_ecdsa && tls12_sigalg_allowed(s, op, lu)) have_ecdsa = 1; @@ -2380,11 +2381,16 @@ int tls_choose_sigalg(SSL *s, int *al) return 0; } } else if (!ssl_has_cert(s, idx)) { - if (al == NULL) - return 1; - *al = SSL_AD_INTERNAL_ERROR; - SSLerr(SSL_F_TLS_CHOOSE_SIGALG, ERR_R_INTERNAL_ERROR); - return 0; + /* Allow Ed25519 if no EC certificate */ + if (idx == SSL_PKEY_ECC && ssl_has_cert(s, SSL_PKEY_ED25519)) { + idx = SSL_PKEY_ED25519; + } else { + if (al == NULL) + return 1; + *al = SSL_AD_INTERNAL_ERROR; + SSLerr(SSL_F_TLS_CHOOSE_SIGALG, ERR_R_INTERNAL_ERROR); + return 0; + } } } else { /* Find index for client certificate */ @@ -2421,6 +2427,10 @@ int tls_choose_sigalg(SSL *s, int *al) if (lu->sig_idx == idx && (curve == -1 || lu->curve == curve)) break; + if (idx == SSL_PKEY_ECC && lu->sig == NID_ED25519) { + idx = SSL_PKEY_ED25519; + break; + } #endif if (idx == SSL_PKEY_RSA && lu->sig == EVP_PKEY_RSA_PSS) break;