NID_sha512, SSL_MD_SHA512_IDX, EVP_PKEY_RSA_PSS, SSL_PKEY_RSA_PSS_SIGN,
NID_undef, NID_undef},
{"rsa_pkcs1_sha256", TLSEXT_SIGALG_rsa_pkcs1_sha256,
- NID_sha256, SSL_MD_SHA256_IDX, EVP_PKEY_RSA, SSL_PKEY_RSA_SIGN,
+ NID_sha256, SSL_MD_SHA256_IDX, EVP_PKEY_RSA, SSL_PKEY_RSA,
NID_sha256WithRSAEncryption, NID_undef},
{"rsa_pkcs1_sha384", TLSEXT_SIGALG_rsa_pkcs1_sha384,
- NID_sha384, SSL_MD_SHA384_IDX, EVP_PKEY_RSA, SSL_PKEY_RSA_SIGN,
+ NID_sha384, SSL_MD_SHA384_IDX, EVP_PKEY_RSA, SSL_PKEY_RSA,
NID_sha384WithRSAEncryption, NID_undef},
{"rsa_pkcs1_sha512", TLSEXT_SIGALG_rsa_pkcs1_sha512,
- NID_sha512, SSL_MD_SHA512_IDX, EVP_PKEY_RSA, SSL_PKEY_RSA_SIGN,
+ NID_sha512, SSL_MD_SHA512_IDX, EVP_PKEY_RSA, SSL_PKEY_RSA,
NID_sha512WithRSAEncryption, NID_undef},
{"rsa_pkcs1_sha1", TLSEXT_SIGALG_rsa_pkcs1_sha1,
- NID_sha1, SSL_MD_SHA1_IDX, EVP_PKEY_RSA, SSL_PKEY_RSA_SIGN,
+ NID_sha1, SSL_MD_SHA1_IDX, EVP_PKEY_RSA, SSL_PKEY_RSA,
NID_sha1WithRSAEncryption, NID_undef},
#ifndef OPENSSL_NO_DSA
{NULL, TLSEXT_SIGALG_dsa_sha256,
return NULL;
}
-static int tls_sigalg_get_hash(uint16_t sigalg)
-{
- const SIGALG_LOOKUP *r = tls1_lookup_sigalg(sigalg);
-
- return r != NULL ? r->hash : 0;
-}
-
static int tls_sigalg_get_sig(uint16_t sigalg)
{
const SIGALG_LOOKUP *r = tls1_lookup_sigalg(sigalg);
#ifndef OPENSSL_NO_EC
if (pkeyid == EVP_PKEY_EC) {
EC_KEY *ec = EVP_PKEY_get0_EC_KEY(pkey);
+ int curve = EC_GROUP_get_curve_name(EC_KEY_get0_group(ec));
+
if (SSL_IS_TLS13(s)) {
/* For TLS 1.3 check curve matches signature algorithm */
- int curve = EC_GROUP_get_curve_name(EC_KEY_get0_group(ec));
+
if (curve != lu->curve) {
SSLerr(SSL_F_TLS12_CHECK_PEER_SIGALG, SSL_R_WRONG_CURVE);
return 0;
}
} else {
unsigned char curve_id[2], comp_id;
+
/* Check compression and curve matches extensions */
if (!tls1_set_ec_id(curve_id, &comp_id, ec))
return 0;
SSLerr(SSL_F_TLS12_CHECK_PEER_SIGALG, SSL_R_WRONG_CURVE);
return 0;
}
- /* If Suite B only P-384+SHA384 or P-256+SHA-256 allowed */
if (tls1_suiteb(s)) {
- if (curve_id[0])
+ /* Check sigalg matches a permissible Suite B value */
+ if (sig != TLSEXT_SIGALG_ecdsa_secp256r1_sha256
+ && sig != TLSEXT_SIGALG_ecdsa_secp384r1_sha384) {
+ SSLerr(SSL_F_TLS12_CHECK_PEER_SIGALG,
+ SSL_R_WRONG_SIGNATURE_TYPE);
return 0;
- if (curve_id[1] == TLSEXT_curve_P_256) {
- if (tls_sigalg_get_hash(sig) != NID_sha256) {
- SSLerr(SSL_F_TLS12_CHECK_PEER_SIGALG,
- SSL_R_ILLEGAL_SUITEB_DIGEST);
- return 0;
- }
- } else if (curve_id[1] == TLSEXT_curve_P_384) {
- if (tls_sigalg_get_hash(sig) != NID_sha384) {
- SSLerr(SSL_F_TLS12_CHECK_PEER_SIGALG,
- SSL_R_ILLEGAL_SUITEB_DIGEST);
- return 0;
- }
- } else {
+ }
+ /*
+ * Suite B also requires P-256+SHA256 and P-384+SHA384:
+ * this matches the TLS 1.3 requirements so we can just
+ * check the curve is the expected TLS 1.3 value.
+ * If this fails an inappropriate digest is being used.
+ */
+ if (curve != lu->curve) {
+ SSLerr(SSL_F_TLS12_CHECK_PEER_SIGALG,
+ SSL_R_ILLEGAL_SUITEB_DIGEST);
return 0;
}
}
SSLerr(SSL_F_TLS12_CHECK_PEER_SIGALG, SSL_R_WRONG_SIGNATURE_TYPE);
return 0;
}
- md = tls12_get_hash(lu->hash);
+ md = ssl_md(lu->hash_idx);
if (md == NULL) {
SSLerr(SSL_F_TLS12_CHECK_PEER_SIGALG, SSL_R_UNKNOWN_DIGEST);
return 0;
SSLerr(SSL_F_TLS12_CHECK_PEER_SIGALG, SSL_R_WRONG_SIGNATURE_TYPE);
return 0;
}
- /*
- * Store the digest used so applications can retrieve it if they wish.
- */
- s->s3->tmp.peer_md = md;
+ /* Store the sigalg the peer uses */
s->s3->tmp.peer_sigalg = lu;
return 1;
}
#endif
#ifndef OPENSSL_NO_RSA
if (SSL_USE_SIGALGS(s))
- pmd[SSL_PKEY_RSA_SIGN] = ssl_md(SSL_MD_SHA1_IDX);
+ pmd[SSL_PKEY_RSA] = ssl_md(SSL_MD_SHA1_IDX);
else
- pmd[SSL_PKEY_RSA_SIGN] = ssl_md(SSL_MD_MD5_SHA1_IDX);
- pmd[SSL_PKEY_RSA_ENC] = pmd[SSL_PKEY_RSA_SIGN];
+ pmd[SSL_PKEY_RSA] = ssl_md(SSL_MD_MD5_SHA1_IDX);
#endif
#ifndef OPENSSL_NO_EC
pmd[SSL_PKEY_ECC] = ssl_md(SSL_MD_SHA1_IDX);
unsigned char tick_hmac[EVP_MAX_MD_SIZE];
HMAC_CTX *hctx = NULL;
EVP_CIPHER_CTX *ctx;
- SSL_CTX *tctx = s->initial_ctx;
+ SSL_CTX *tctx = s->session_ctx;
/* Initialize session ticket encryption and HMAC contexts */
hctx = HMAC_CTX_new();
return 0;
}
-typedef struct {
- int nid;
- int secbits;
- int md_idx;
-} tls12_hash_info;
-
-static const tls12_hash_info tls12_md_info[] = {
- {NID_md5, 64, SSL_MD_MD5_IDX},
- {NID_sha1, 80, SSL_MD_SHA1_IDX},
- {NID_sha224, 112, SSL_MD_SHA224_IDX},
- {NID_sha256, 128, SSL_MD_SHA256_IDX},
- {NID_sha384, 192, SSL_MD_SHA384_IDX},
- {NID_sha512, 256, SSL_MD_SHA512_IDX},
- {NID_id_GostR3411_94, 128, SSL_MD_GOST94_IDX},
- {NID_id_GostR3411_2012_256, 128, SSL_MD_GOST12_256_IDX},
- {NID_id_GostR3411_2012_512, 256, SSL_MD_GOST12_512_IDX},
-};
-
-static const tls12_hash_info *tls12_get_hash_info(int hash_nid)
-{
- unsigned int i;
- if (hash_nid == NID_undef)
- return NULL;
-
- for (i = 0; i < OSSL_NELEM(tls12_md_info); i++) {
- if (tls12_md_info[i].nid == hash_nid)
- return tls12_md_info + i;
- }
-
- return NULL;
-}
-
-const EVP_MD *tls12_get_hash(int hash_nid)
-{
- const tls12_hash_info *inf;
- if (hash_nid == NID_md5 && FIPS_mode())
- return NULL;
- inf = tls12_get_hash_info(hash_nid);
- if (!inf)
- return NULL;
- return ssl_md(inf->md_idx);
-}
-
static int tls12_get_pkey_idx(int sig_nid)
{
switch (sig_nid) {
#ifndef OPENSSL_NO_RSA
case EVP_PKEY_RSA:
- return SSL_PKEY_RSA_SIGN;
+ return SSL_PKEY_RSA;
/*
* For now return RSA key for PSS. When we support PSS only keys
* this will need to be updated.
*/
case EVP_PKEY_RSA_PSS:
- return SSL_PKEY_RSA_SIGN;
+ return SSL_PKEY_RSA;
#endif
#ifndef OPENSSL_NO_DSA
case EVP_PKEY_DSA:
}
/* Check to see if a signature algorithm is allowed */
-static int tls12_sigalg_allowed(SSL *s, int op, unsigned int ptmp)
+static int tls12_sigalg_allowed(SSL *s, int op, uint16_t ptmp)
{
- /* See if we have an entry in the hash table and it is enabled */
- const tls12_hash_info *hinf
- = tls12_get_hash_info(tls_sigalg_get_hash(ptmp));
+ const SIGALG_LOOKUP *lu = tls1_lookup_sigalg(ptmp);
unsigned char sigalgstr[2];
+ int secbits;
- if (hinf == NULL || ssl_md(hinf->md_idx) == NULL)
+ /* See if sigalgs is recognised and if hash is enabled */
+ if (lu == NULL || ssl_md(lu->hash_idx) == NULL)
return 0;
/* See if public key algorithm allowed */
- if (tls12_get_pkey_idx(tls_sigalg_get_sig(ptmp)) == -1)
+ if (tls12_get_pkey_idx(lu->sig) == -1)
return 0;
+ /* Security bits: half digest bits */
+ secbits = EVP_MD_size(ssl_md(lu->hash_idx)) * 4;
/* Finally see if security callback allows it */
sigalgstr[0] = (ptmp >> 8) & 0xff;
sigalgstr[1] = ptmp & 0xff;
- return ssl_security(s, op, hinf->secbits, hinf->nid, (void *)sigalgstr);
+ return ssl_security(s, op, secbits, lu->hash, (void *)sigalgstr);
}
/*
if (SSL_IS_TLS13(s) && sigptr->sig == EVP_PKEY_RSA)
continue;
idx = tls12_get_pkey_idx(sigptr->sig);
- if (idx > 0 && pmd[idx] == NULL) {
- md = tls12_get_hash(sigptr->hash);
+ if (idx >= 0 && pmd[idx] == NULL) {
+ md = ssl_md(sigptr->hash_idx);
pmd[idx] = md;
pvalid[idx] = CERT_PKEY_EXPLICIT_SIGN;
- if (idx == SSL_PKEY_RSA_SIGN) {
- pvalid[SSL_PKEY_RSA_ENC] = CERT_PKEY_EXPLICIT_SIGN;
- pmd[SSL_PKEY_RSA_ENC] = md;
- }
}
-
}
/*
* In strict mode or TLS1.3 leave unset digests as NULL to indicate we can't
pmd[SSL_PKEY_DSA_SIGN] = EVP_sha1();
#endif
#ifndef OPENSSL_NO_RSA
- if (pmd[SSL_PKEY_RSA_SIGN] == NULL) {
- pmd[SSL_PKEY_RSA_SIGN] = EVP_sha1();
- pmd[SSL_PKEY_RSA_ENC] = EVP_sha1();
+ if (pmd[SSL_PKEY_RSA] == NULL) {
+ pmd[SSL_PKEY_RSA] = EVP_sha1();
}
#endif
#ifndef OPENSSL_NO_EC
{
const SIGALG_LOOKUP *shsigalgs;
if (s->cert->shared_sigalgs == NULL
+ || idx < 0
|| idx >= (int)s->cert->shared_sigalgslen
|| s->cert->shared_sigalgslen > INT_MAX)
return 0;
/* If no sigalgs extension use defaults from RFC5246 */
else {
switch (idx) {
- case SSL_PKEY_RSA_ENC:
- case SSL_PKEY_RSA_SIGN:
+ case SSL_PKEY_RSA:
rsign = EVP_PKEY_RSA;
default_nid = NID_sha1WithRSAEncryption;
break;
size_t j;
const uint16_t *p = c->conf_sigalgs;
for (j = 0; j < c->conf_sigalgslen; j++, p++) {
- if (tls_sigalg_get_hash(*p) == NID_sha1
- && tls_sigalg_get_sig(*p) == rsign)
+ const SIGALG_LOOKUP *lu = tls1_lookup_sigalg(*p);
+
+ if (lu != NULL && lu->hash == NID_sha1 && lu->sig == rsign)
break;
}
if (j == c->conf_sigalgslen) {
/* Set validity of certificates in an SSL structure */
void tls1_set_cert_validity(SSL *s)
{
- tls1_check_chain(s, NULL, NULL, NULL, SSL_PKEY_RSA_ENC);
- tls1_check_chain(s, NULL, NULL, NULL, SSL_PKEY_RSA_SIGN);
+ tls1_check_chain(s, NULL, NULL, NULL, SSL_PKEY_RSA);
tls1_check_chain(s, NULL, NULL, NULL, SSL_PKEY_DSA_SIGN);
tls1_check_chain(s, NULL, NULL, NULL, SSL_PKEY_ECC);
tls1_check_chain(s, NULL, NULL, NULL, SSL_PKEY_GOST01);
}
return 1;
}
+
+/*
+ * Choose an appropriate signature algorithm based on available certificates
+ * Set current certificate and digest to match chosen algorithm.
+ */
+int tls_choose_sigalg(SSL *s)
+{
+ if (SSL_IS_TLS13(s)) {
+ size_t i;
+#ifndef OPENSSL_NO_EC
+ int curve = -1;
+#endif
+
+ /* Look for a certificate matching shared sigaglgs */
+ for (i = 0; i < s->cert->shared_sigalgslen; i++) {
+ const SIGALG_LOOKUP *lu = s->cert->shared_sigalgs[i];
+ int idx;
+ const EVP_MD *md;
+ CERT_PKEY *c;
+
+ /* Skip RSA if not PSS */
+ if (lu->sig == EVP_PKEY_RSA)
+ continue;
+ md = ssl_md(lu->hash_idx);
+ if (md == NULL)
+ continue;
+ idx = lu->sig_idx;
+ c = &s->cert->pkeys[idx];
+ if (c->x509 == NULL || c->privatekey == NULL)
+ continue;
+ if (lu->sig == EVP_PKEY_EC) {
+#ifndef OPENSSL_NO_EC
+ if (curve == -1) {
+ EC_KEY *ec = EVP_PKEY_get0_EC_KEY(c->privatekey);
+
+ curve = EC_GROUP_get_curve_name(EC_KEY_get0_group(ec));
+ }
+ if (curve != lu->curve)
+ continue;
+#else
+ continue;
+#endif
+ }
+ s->s3->tmp.sigalg = lu;
+ s->s3->tmp.cert_idx = idx;
+ s->s3->tmp.md[idx] = md;
+ s->cert->key = s->cert->pkeys + idx;
+ return 1;
+ }
+ return 0;
+ }
+ /*
+ * FIXME: could handle previous TLS versions in an appropriate way
+ * and tidy up certificate and signature algorithm handling.
+ */
+ return 1;
+}