{NID_brainpoolP256r1, 128, TLS_CURVE_PRIME}, /* brainpoolP256r1 (26) */
{NID_brainpoolP384r1, 192, TLS_CURVE_PRIME}, /* brainpoolP384r1 (27) */
{NID_brainpoolP512r1, 256, TLS_CURVE_PRIME}, /* brainpool512r1 (28) */
- {NID_X25519, 128, TLS_CURVE_CUSTOM}, /* X25519 (29) */
+ {EVP_PKEY_X25519, 128, TLS_CURVE_CUSTOM}, /* X25519 (29) */
};
static const unsigned char ecformats_default[] = {
NID_sha512, SSL_MD_SHA512_IDX, EVP_PKEY_EC, SSL_PKEY_ECC,
NID_ecdsa_with_SHA512, NID_secp521r1},
{"ed25519", TLSEXT_SIGALG_ed25519,
- NID_undef, -1, NID_ED25519, SSL_PKEY_ED25519,
+ NID_undef, -1, EVP_PKEY_ED25519, SSL_PKEY_ED25519,
NID_undef, NID_undef},
{NULL, TLSEXT_SIGALG_ecdsa_sha224,
NID_sha224, SSL_MD_SHA224_IDX, EVP_PKEY_EC, SSL_PKEY_ECC,
}
return NULL;
}
+/* Lookup hash: return 0 if invalid or not enabled */
+int tls1_lookup_md(const SIGALG_LOOKUP *lu, const EVP_MD **pmd)
+{
+ const EVP_MD *md;
+ if (lu == NULL)
+ return 0;
+ /* lu->hash == NID_undef means no associated digest */
+ if (lu->hash == NID_undef) {
+ md = NULL;
+ } else {
+ md = ssl_md(lu->hash_idx);
+ if (md == NULL)
+ return 0;
+ }
+ if (pmd)
+ *pmd = md;
+ return 1;
+}
+
/*
* Return a signature algorithm for TLS < 1.2 where the signature type
* is fixed by the certificate type.
if (SSL_USE_SIGALGS(s) || idx != SSL_PKEY_RSA) {
const SIGALG_LOOKUP *lu = tls1_lookup_sigalg(tls_default_sigalg[idx]);
- if (lu == NULL || ssl_md(lu->hash_idx) == NULL) {
+ if (!tls1_lookup_md(lu, NULL))
return NULL;
- }
return lu;
}
return &legacy_rsa_sigalg;
SSLerr(SSL_F_TLS12_CHECK_PEER_SIGALG, SSL_R_WRONG_SIGNATURE_TYPE);
return 0;
}
- md = ssl_md(lu->hash_idx);
- if (md == NULL) {
- SSLerr(SSL_F_TLS12_CHECK_PEER_SIGALG, SSL_R_UNKNOWN_DIGEST);
- return 0;
+ if (!tls1_lookup_md(lu, &md)) {
+ SSLerr(SSL_F_TLS12_CHECK_PEER_SIGALG, SSL_R_UNKNOWN_DIGEST);
+ return 0;
}
- /*
- * Make sure security callback allows algorithm. For historical reasons we
- * have to pass the sigalg as a two byte char array.
- */
- sigalgstr[0] = (sig >> 8) & 0xff;
- sigalgstr[1] = sig & 0xff;
- if (!ssl_security(s, SSL_SECOP_SIGALG_CHECK,
- EVP_MD_size(md) * 4, EVP_MD_type(md),
- (void *)sigalgstr)) {
- SSLerr(SSL_F_TLS12_CHECK_PEER_SIGALG, SSL_R_WRONG_SIGNATURE_TYPE);
- return 0;
+ if (md != NULL) {
+ /*
+ * Make sure security callback allows algorithm. For historical
+ * reasons we have to pass the sigalg as a two byte char array.
+ */
+ sigalgstr[0] = (sig >> 8) & 0xff;
+ sigalgstr[1] = sig & 0xff;
+ if (!ssl_security(s, SSL_SECOP_SIGALG_CHECK,
+ EVP_MD_size(md) * 4, EVP_MD_type(md),
+ (void *)sigalgstr)) {
+ SSLerr(SSL_F_TLS12_CHECK_PEER_SIGALG, SSL_R_WRONG_SIGNATURE_TYPE);
+ return 0;
+ }
}
/* Store the sigalg the peer uses */
s->s3->tmp.peer_sigalg = lu;
#ifndef OPENSSL_NO_EC
case EVP_PKEY_EC:
return SSL_PKEY_ECC;
- case NID_ED25519:
+ case EVP_PKEY_ED25519:
return SSL_PKEY_ED25519;
#endif
#ifndef OPENSSL_NO_GOST
int secbits;
/* See if sigalgs is recognised and if hash is enabled */
- if (lu == NULL || ssl_md(lu->hash_idx) == NULL)
+ if (!tls1_lookup_md(lu, NULL))
return 0;
/* DSA is not allowed in TLS 1.3 */
if (SSL_IS_TLS13(s) && lu->sig == EVP_PKEY_DSA)
return 0;
+ /* TODO(OpenSSL1.2) fully axe DSA/etc. in ClientHello per TLS 1.3 spec */
+ if (!s->server && !SSL_IS_DTLS(s) && s->s3->tmp.min_ver >= TLS1_3_VERSION
+ && (lu->sig == EVP_PKEY_DSA || lu->hash_idx == SSL_MD_SHA1_IDX
+ || lu->hash_idx == SSL_MD_MD5_IDX
+ || lu->hash_idx == SSL_MD_SHA224_IDX))
+ return 0;
/* See if public key algorithm allowed */
if (tls12_get_pkey_idx(lu->sig) == -1)
return 0;
+ if (lu->hash == NID_undef)
+ return 1;
/* Security bits: half digest bits */
secbits = EVP_MD_size(ssl_md(lu->hash_idx)) * 4;
/* Finally see if security callback allows it */
break;
#endif
#ifndef OPENSSL_NO_EC
+ case EVP_PKEY_ED25519:
case EVP_PKEY_EC:
if (!have_ecdsa && tls12_sigalg_allowed(s, op, lu))
have_ecdsa = 1;
get_sigorhash(&sig_alg, &hash_alg, p);
}
- if (sig_alg == NID_undef || hash_alg == NID_undef)
+ if (sig_alg == NID_undef || (p != NULL && hash_alg == NID_undef))
return 0;
for (i = 0; i < sarg->sigalgcnt; i += 2) {
|| lu->sig == EVP_PKEY_DSA
|| lu->sig == EVP_PKEY_RSA)
continue;
- if (ssl_md(lu->hash_idx) == NULL)
+ if (!tls1_lookup_md(lu, NULL))
continue;
idx = lu->sig_idx;
if (!ssl_has_cert(s, idx))
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 */
if (lu->sig_idx == idx
&& (curve == -1 || lu->curve == curve))
break;
+ if (idx == SSL_PKEY_ECC && lu->sig == EVP_PKEY_ED25519) {
+ idx = SSL_PKEY_ED25519;
+ break;
+ }
#endif
if (idx == SSL_PKEY_RSA && lu->sig == EVP_PKEY_RSA_PSS)
break;