#ifndef OPENSSL_NO_EC
{"ecdsa_secp256r1_sha256", TLSEXT_SIGALG_ecdsa_secp256r1_sha256,
NID_sha256, SSL_MD_SHA256_IDX, EVP_PKEY_EC, SSL_PKEY_ECC,
- NID_ecdsa_with_SHA256, NID_X9_62_prime256v1},
+ NID_ecdsa_with_SHA256, NID_X9_62_prime256v1, 1},
{"ecdsa_secp384r1_sha384", TLSEXT_SIGALG_ecdsa_secp384r1_sha384,
NID_sha384, SSL_MD_SHA384_IDX, EVP_PKEY_EC, SSL_PKEY_ECC,
- NID_ecdsa_with_SHA384, NID_secp384r1},
+ NID_ecdsa_with_SHA384, NID_secp384r1, 1},
{"ecdsa_secp521r1_sha512", TLSEXT_SIGALG_ecdsa_secp521r1_sha512,
NID_sha512, SSL_MD_SHA512_IDX, EVP_PKEY_EC, SSL_PKEY_ECC,
- NID_ecdsa_with_SHA512, NID_secp521r1},
+ NID_ecdsa_with_SHA512, NID_secp521r1, 1},
{"ed25519", TLSEXT_SIGALG_ed25519,
NID_undef, -1, EVP_PKEY_ED25519, SSL_PKEY_ED25519,
- NID_undef, NID_undef},
+ NID_undef, NID_undef, 1},
{"ed448", TLSEXT_SIGALG_ed448,
NID_undef, -1, EVP_PKEY_ED448, SSL_PKEY_ED448,
- NID_undef, NID_undef},
+ NID_undef, NID_undef, 1},
{NULL, TLSEXT_SIGALG_ecdsa_sha224,
NID_sha224, SSL_MD_SHA224_IDX, EVP_PKEY_EC, SSL_PKEY_ECC,
- NID_ecdsa_with_SHA224, NID_undef},
+ NID_ecdsa_with_SHA224, NID_undef, 1},
{NULL, TLSEXT_SIGALG_ecdsa_sha1,
NID_sha1, SSL_MD_SHA1_IDX, EVP_PKEY_EC, SSL_PKEY_ECC,
- NID_ecdsa_with_SHA1, NID_undef},
+ NID_ecdsa_with_SHA1, NID_undef, 1},
#endif
{"rsa_pss_rsae_sha256", TLSEXT_SIGALG_rsa_pss_rsae_sha256,
NID_sha256, SSL_MD_SHA256_IDX, EVP_PKEY_RSA_PSS, SSL_PKEY_RSA,
- NID_undef, NID_undef},
+ NID_undef, NID_undef, 1},
{"rsa_pss_rsae_sha384", TLSEXT_SIGALG_rsa_pss_rsae_sha384,
NID_sha384, SSL_MD_SHA384_IDX, EVP_PKEY_RSA_PSS, SSL_PKEY_RSA,
- NID_undef, NID_undef},
+ NID_undef, NID_undef, 1},
{"rsa_pss_rsae_sha512", TLSEXT_SIGALG_rsa_pss_rsae_sha512,
NID_sha512, SSL_MD_SHA512_IDX, EVP_PKEY_RSA_PSS, SSL_PKEY_RSA,
- NID_undef, NID_undef},
+ NID_undef, NID_undef, 1},
{"rsa_pss_pss_sha256", TLSEXT_SIGALG_rsa_pss_pss_sha256,
NID_sha256, SSL_MD_SHA256_IDX, EVP_PKEY_RSA_PSS, SSL_PKEY_RSA_PSS_SIGN,
- NID_undef, NID_undef},
+ NID_undef, NID_undef, 1},
{"rsa_pss_pss_sha384", TLSEXT_SIGALG_rsa_pss_pss_sha384,
NID_sha384, SSL_MD_SHA384_IDX, EVP_PKEY_RSA_PSS, SSL_PKEY_RSA_PSS_SIGN,
- NID_undef, NID_undef},
+ NID_undef, NID_undef, 1},
{"rsa_pss_pss_sha512", TLSEXT_SIGALG_rsa_pss_pss_sha512,
NID_sha512, SSL_MD_SHA512_IDX, EVP_PKEY_RSA_PSS, SSL_PKEY_RSA_PSS_SIGN,
- NID_undef, NID_undef},
+ NID_undef, NID_undef, 1},
{"rsa_pkcs1_sha256", TLSEXT_SIGALG_rsa_pkcs1_sha256,
NID_sha256, SSL_MD_SHA256_IDX, EVP_PKEY_RSA, SSL_PKEY_RSA,
- NID_sha256WithRSAEncryption, NID_undef},
+ NID_sha256WithRSAEncryption, NID_undef, 1},
{"rsa_pkcs1_sha384", TLSEXT_SIGALG_rsa_pkcs1_sha384,
NID_sha384, SSL_MD_SHA384_IDX, EVP_PKEY_RSA, SSL_PKEY_RSA,
- NID_sha384WithRSAEncryption, NID_undef},
+ NID_sha384WithRSAEncryption, NID_undef, 1},
{"rsa_pkcs1_sha512", TLSEXT_SIGALG_rsa_pkcs1_sha512,
NID_sha512, SSL_MD_SHA512_IDX, EVP_PKEY_RSA, SSL_PKEY_RSA,
- NID_sha512WithRSAEncryption, NID_undef},
+ NID_sha512WithRSAEncryption, NID_undef, 1},
{"rsa_pkcs1_sha224", TLSEXT_SIGALG_rsa_pkcs1_sha224,
NID_sha224, SSL_MD_SHA224_IDX, EVP_PKEY_RSA, SSL_PKEY_RSA,
- NID_sha224WithRSAEncryption, NID_undef},
+ NID_sha224WithRSAEncryption, NID_undef, 1},
{"rsa_pkcs1_sha1", TLSEXT_SIGALG_rsa_pkcs1_sha1,
NID_sha1, SSL_MD_SHA1_IDX, EVP_PKEY_RSA, SSL_PKEY_RSA,
- NID_sha1WithRSAEncryption, NID_undef},
+ NID_sha1WithRSAEncryption, NID_undef, 1},
#ifndef OPENSSL_NO_DSA
{NULL, TLSEXT_SIGALG_dsa_sha256,
NID_sha256, SSL_MD_SHA256_IDX, EVP_PKEY_DSA, SSL_PKEY_DSA_SIGN,
- NID_dsa_with_SHA256, NID_undef},
+ NID_dsa_with_SHA256, NID_undef, 1},
{NULL, TLSEXT_SIGALG_dsa_sha384,
NID_sha384, SSL_MD_SHA384_IDX, EVP_PKEY_DSA, SSL_PKEY_DSA_SIGN,
- NID_undef, NID_undef},
+ NID_undef, NID_undef, 1},
{NULL, TLSEXT_SIGALG_dsa_sha512,
NID_sha512, SSL_MD_SHA512_IDX, EVP_PKEY_DSA, SSL_PKEY_DSA_SIGN,
- NID_undef, NID_undef},
+ NID_undef, NID_undef, 1},
{NULL, TLSEXT_SIGALG_dsa_sha224,
NID_sha224, SSL_MD_SHA224_IDX, EVP_PKEY_DSA, SSL_PKEY_DSA_SIGN,
- NID_undef, NID_undef},
+ NID_undef, NID_undef, 1},
{NULL, TLSEXT_SIGALG_dsa_sha1,
NID_sha1, SSL_MD_SHA1_IDX, EVP_PKEY_DSA, SSL_PKEY_DSA_SIGN,
- NID_dsaWithSHA1, NID_undef},
+ NID_dsaWithSHA1, NID_undef, 1},
#endif
#ifndef OPENSSL_NO_GOST
{NULL, TLSEXT_SIGALG_gostr34102012_256_intrinsic,
NID_id_GostR3411_2012_256, SSL_MD_GOST12_256_IDX,
NID_id_GostR3410_2012_256, SSL_PKEY_GOST12_256,
- NID_undef, NID_undef},
+ NID_undef, NID_undef, 1},
{NULL, TLSEXT_SIGALG_gostr34102012_512_intrinsic,
NID_id_GostR3411_2012_512, SSL_MD_GOST12_512_IDX,
NID_id_GostR3410_2012_512, SSL_PKEY_GOST12_512,
- NID_undef, NID_undef},
+ NID_undef, NID_undef, 1},
{NULL, TLSEXT_SIGALG_gostr34102012_256_gostr34112012_256,
NID_id_GostR3411_2012_256, SSL_MD_GOST12_256_IDX,
NID_id_GostR3410_2012_256, SSL_PKEY_GOST12_256,
- NID_undef, NID_undef},
+ NID_undef, NID_undef, 1},
{NULL, TLSEXT_SIGALG_gostr34102012_512_gostr34112012_512,
NID_id_GostR3411_2012_512, SSL_MD_GOST12_512_IDX,
NID_id_GostR3410_2012_512, SSL_PKEY_GOST12_512,
- NID_undef, NID_undef},
+ NID_undef, NID_undef, 1},
{NULL, TLSEXT_SIGALG_gostr34102001_gostr3411,
NID_id_GostR3411_94, SSL_MD_GOST94_IDX,
NID_id_GostR3410_2001, SSL_PKEY_GOST01,
- NID_undef, NID_undef}
+ NID_undef, NID_undef, 1}
#endif
};
/* Legacy sigalgs for TLS < 1.2 RSA TLS signatures */
"rsa_pkcs1_md5_sha1", 0,
NID_md5_sha1, SSL_MD_MD5_SHA1_IDX,
EVP_PKEY_RSA, SSL_PKEY_RSA,
- NID_undef, NID_undef
+ NID_undef, NID_undef, 1
};
/*
0, /* SSL_PKEY_ED448 */
};
+int ssl_setup_sig_algs(SSL_CTX *ctx)
+{
+ size_t i;
+ const SIGALG_LOOKUP *lu;
+ SIGALG_LOOKUP *cache
+ = OPENSSL_malloc(sizeof(*lu) * OSSL_NELEM(sigalg_lookup_tbl));
+ EVP_PKEY *tmpkey = EVP_PKEY_new();
+ int ret = 0;
+
+ if (cache == NULL || tmpkey == NULL)
+ goto err;
+
+ ERR_set_mark();
+ for (i = 0, lu = sigalg_lookup_tbl;
+ i < OSSL_NELEM(sigalg_lookup_tbl); lu++, i++) {
+ EVP_PKEY_CTX *pctx;
+
+ cache[i] = *lu;
+
+ /*
+ * Check hash is available.
+ * TODO(3.0): This test is not perfect. A provider could have support
+ * for a signature scheme, but not a particular hash. However the hash
+ * could be available from some other loaded provider. In that case it
+ * could be that the signature is available, and the hash is available
+ * independently - but not as a combination. We ignore this for now.
+ */
+ if (lu->hash != NID_undef
+ && ctx->ssl_digest_methods[lu->hash_idx] == NULL) {
+ cache[i].enabled = 0;
+ continue;
+ }
+
+ if (!EVP_PKEY_set_type(tmpkey, lu->sig)) {
+ cache[i].enabled = 0;
+ continue;
+ }
+ pctx = EVP_PKEY_CTX_new_from_pkey(ctx->libctx, tmpkey, ctx->propq);
+ /* If unable to create pctx we assume the sig algorithm is unavailable */
+ if (pctx == NULL)
+ cache[i].enabled = 0;
+ EVP_PKEY_CTX_free(pctx);
+ }
+ ERR_pop_to_mark();
+ ctx->sigalg_lookup_cache = cache;
+ cache = NULL;
+
+ ret = 1;
+ err:
+ OPENSSL_free(cache);
+ EVP_PKEY_free(tmpkey);
+ return ret;
+}
+
/* Lookup TLS signature algorithm */
-static const SIGALG_LOOKUP *tls1_lookup_sigalg(uint16_t sigalg)
+static const SIGALG_LOOKUP *tls1_lookup_sigalg(const SSL *s, uint16_t sigalg)
{
size_t i;
- const SIGALG_LOOKUP *s;
+ const SIGALG_LOOKUP *lu;
- for (i = 0, s = sigalg_lookup_tbl; i < OSSL_NELEM(sigalg_lookup_tbl);
- i++, s++) {
- if (s->sigalg == sigalg)
- return s;
+ for (i = 0, lu = s->ctx->sigalg_lookup_cache;
+ /* cache should have the same number of elements as sigalg_lookup_tbl */
+ i < OSSL_NELEM(sigalg_lookup_tbl);
+ lu++, i++) {
+ if (lu->sigalg == sigalg)
+ return lu;
}
return NULL;
}
if (idx < 0 || idx >= (int)OSSL_NELEM(tls_default_sigalg))
return NULL;
if (SSL_USE_SIGALGS(s) || idx != SSL_PKEY_RSA) {
- const SIGALG_LOOKUP *lu = tls1_lookup_sigalg(tls_default_sigalg[idx]);
+ const SIGALG_LOOKUP *lu = tls1_lookup_sigalg(s, tls_default_sigalg[idx]);
if (!tls1_lookup_md(s->ctx, lu, NULL))
return NULL;
}
for (i = 0; i < siglen; i++) {
- const SIGALG_LOOKUP *lu = tls1_lookup_sigalg(sigs[i]);
+ const SIGALG_LOOKUP *lu = tls1_lookup_sigalg(s, sigs[i]);
if (lu == NULL)
continue;
if (pkeyid == EVP_PKEY_RSA)
pkeyid = EVP_PKEY_RSA_PSS;
}
- lu = tls1_lookup_sigalg(sig);
+ lu = tls1_lookup_sigalg(s, sig);
/*
* Check sigalgs is known. Disallow SHA1/SHA224 with TLS 1.3. Check key type
* is consistent with signature: RSA keys can be used for RSA-PSS
unsigned char sigalgstr[2];
int secbits;
- /* See if sigalgs is recognised and if hash is enabled */
- if (!tls1_lookup_md(s->ctx, lu, NULL))
+ if (lu == NULL || !lu->enabled)
return 0;
/* DSA is not allowed in TLS 1.3 */
if (SSL_IS_TLS13(s) && lu->sig == EVP_PKEY_DSA)
*/
sigalgslen = tls12_get_psigalgs(s, 1, &sigalgs);
for (i = 0; i < sigalgslen; i++, sigalgs++) {
- const SIGALG_LOOKUP *lu = tls1_lookup_sigalg(*sigalgs);
+ const SIGALG_LOOKUP *lu = tls1_lookup_sigalg(s, *sigalgs);
const SSL_CERT_LOOKUP *clu;
if (lu == NULL)
int rv = 0;
for (i = 0; i < psiglen; i++, psig++) {
- const SIGALG_LOOKUP *lu = tls1_lookup_sigalg(*psig);
+ const SIGALG_LOOKUP *lu = tls1_lookup_sigalg(s, *psig);
if (!tls12_sigalg_allowed(s, SSL_SECOP_SIGALG_SUPPORTED, lu))
continue;
const uint16_t *ptmp, *atmp;
size_t i, j, nmatch = 0;
for (i = 0, ptmp = pref; i < preflen; i++, ptmp++) {
- const SIGALG_LOOKUP *lu = tls1_lookup_sigalg(*ptmp);
+ const SIGALG_LOOKUP *lu = tls1_lookup_sigalg(s, *ptmp);
/* Skip disabled hashes or signature algorithms */
if (!tls12_sigalg_allowed(s, SSL_SECOP_SIGALG_SHARED, lu))
*rhash = (unsigned char)((*psig >> 8) & 0xff);
if (rsig != NULL)
*rsig = (unsigned char)(*psig & 0xff);
- lu = tls1_lookup_sigalg(*psig);
+ lu = tls1_lookup_sigalg(s, *psig);
if (psign != NULL)
*psign = lu != NULL ? lu->sig : NID_undef;
if (phash != NULL)
}
for (i = 0; i < sigalgslen; i++) {
sigalg = use_pc_sigalgs
- ? tls1_lookup_sigalg(s->s3.tmp.peer_cert_sigalgs[i])
+ ? tls1_lookup_sigalg(s, s->s3.tmp.peer_cert_sigalgs[i])
: s->shared_sigalgs[i];
if (sigalg != NULL && sig_nid == sigalg->sigandhash)
return 1;
size_t j;
const uint16_t *p = c->conf_sigalgs;
for (j = 0; j < c->conf_sigalgslen; j++, p++) {
- const SIGALG_LOOKUP *lu = tls1_lookup_sigalg(*p);
+ const SIGALG_LOOKUP *lu = tls1_lookup_sigalg(s, *p);
if (lu != NULL && lu->hash == NID_sha1 && lu->sig == rsign)
break;
if (!X509_get_signature_info(x, &mdnid, &pknid, NULL, NULL))
return 0;
for (i = 0; i < s->s3.tmp.peer_cert_sigalgslen; i++) {
- lu = tls1_lookup_sigalg(s->s3.tmp.peer_cert_sigalgs[i]);
+ lu = tls1_lookup_sigalg(s, s->s3.tmp.peer_cert_sigalgs[i]);
if (lu == NULL)
continue;