* Check cert parameters compatible with extensions: currently just checks EC
* certificates have compatible curves and compression.
*/
-static int tls1_check_cert_param(SSL *s, X509 *x, int set_ee_md)
+static int tls1_check_cert_param(SSL *s, X509 *x, int check_ee_md)
{
unsigned char comp_id, curve_id[2];
EVP_PKEY *pkey;
return 0;
/*
* Special case for suite B. We *MUST* sign using SHA256+P-256 or
- * SHA384+P-384, adjust digest if necessary.
+ * SHA384+P-384.
*/
- if (set_ee_md && tls1_suiteb(s)) {
+ if (check_ee_md && tls1_suiteb(s)) {
int check_md;
size_t i;
CERT *c = s->cert;
break;
if (i == c->shared_sigalgslen)
return 0;
- if (set_ee_md == 2) {
- if (check_md == NID_ecdsa_with_SHA256)
- s->s3->tmp.md[SSL_PKEY_ECC] = EVP_sha256();
- else
- s->s3->tmp.md[SSL_PKEY_ECC] = EVP_sha384();
- }
}
return rv;
}
return 1;
}
-static int tls_sigalg_get_sig(uint16_t sigalg)
-{
- const SIGALG_LOOKUP *r = tls1_lookup_sigalg(sigalg);
-
- return r != NULL ? r->sig : 0;
-}
-
size_t tls12_get_psigalgs(SSL *s, int sent, const uint16_t **psigs)
{
/*
/* Should never happen */
if (pkeyid == -1)
return -1;
- /* Only allow PSS for TLS 1.3 */
- if (SSL_IS_TLS13(s) && pkeyid == EVP_PKEY_RSA)
- pkeyid = EVP_PKEY_RSA_PSS;
+ if (SSL_IS_TLS13(s)) {
+ /* Disallow DSA for TLS 1.3 */
+ if (pkeyid == EVP_PKEY_DSA) {
+ SSLerr(SSL_F_TLS12_CHECK_PEER_SIGALG, SSL_R_WRONG_SIGNATURE_TYPE);
+ return 0;
+ }
+ /* Only allow PSS for TLS 1.3 */
+ if (pkeyid == EVP_PKEY_RSA)
+ pkeyid = EVP_PKEY_RSA_PSS;
+ }
lu = tls1_lookup_sigalg(sig);
/*
- * Check sigalgs is known and key type is consistent with signature:
- * RSA keys can be used for RSA-PSS
+ * Check sigalgs is known. Disallow SHA1 with TLS 1.3. Check key type is
+ * consistent with signature: RSA keys can be used for RSA-PSS
*/
- if (lu == NULL || (pkeyid != lu->sig
+ if (lu == NULL || (SSL_IS_TLS13(s) && lu->hash == NID_sha1)
+ || (pkeyid != lu->sig
&& (lu->sig != EVP_PKEY_RSA_PSS || pkeyid != EVP_PKEY_RSA))) {
SSLerr(SSL_F_TLS12_CHECK_PEER_SIGALG, SSL_R_WRONG_SIGNATURE_TYPE);
return 0;
int curve = EC_GROUP_get_curve_name(EC_KEY_get0_group(ec));
if (SSL_IS_TLS13(s)) {
+ if (EC_KEY_get_conv_form(ec) != POINT_CONVERSION_UNCOMPRESSED) {
+ SSLerr(SSL_F_TLS12_CHECK_PEER_SIGALG,
+ SSL_R_ILLEGAL_POINT_COMPRESSION);
+ return 0;
+ }
/* For TLS 1.3 check curve matches signature algorithm */
-
- if (curve != lu->curve) {
+ if (lu->curve != NID_undef && curve != lu->curve) {
SSLerr(SSL_F_TLS12_CHECK_PEER_SIGALG, SSL_R_WRONG_CURVE);
return 0;
}
return ssl_security(s, SSL_SECOP_TICKET, 0, 0, NULL);
}
-/* Initialise digests to default values */
-void ssl_set_default_md(SSL *s)
-{
- const EVP_MD **pmd = s->s3->tmp.md;
-#ifndef OPENSSL_NO_DSA
- pmd[SSL_PKEY_DSA_SIGN] = ssl_md(SSL_MD_SHA1_IDX);
-#endif
-#ifndef OPENSSL_NO_RSA
- if (SSL_USE_SIGALGS(s))
- pmd[SSL_PKEY_RSA] = ssl_md(SSL_MD_SHA1_IDX);
- else
- 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);
-#endif
-#ifndef OPENSSL_NO_GOST
- pmd[SSL_PKEY_GOST01] = ssl_md(SSL_MD_GOST94_IDX);
- pmd[SSL_PKEY_GOST12_256] = ssl_md(SSL_MD_GOST12_256_IDX);
- pmd[SSL_PKEY_GOST12_512] = ssl_md(SSL_MD_GOST12_512_IDX);
-#endif
-}
-
int tls1_set_server_sigalgs(SSL *s)
{
int al;
OPENSSL_free(s->cert->shared_sigalgs);
s->cert->shared_sigalgs = NULL;
s->cert->shared_sigalgslen = 0;
- /* Clear certificate digests and validity flags */
- for (i = 0; i < SSL_PKEY_NUM; i++) {
- s->s3->tmp.md[i] = NULL;
+ /* Clear certificate validity flags */
+ for (i = 0; i < SSL_PKEY_NUM; i++)
s->s3->tmp.valid_flags[i] = 0;
- }
+ /*
+ * If peer sent no signature algorithms check to see if we support
+ * the default algorithm for each certificate type
+ */
+ if (s->s3->tmp.peer_sigalgs == NULL) {
+ const uint16_t *sent_sigs;
+ size_t sent_sigslen = tls12_get_psigalgs(s, 1, &sent_sigs);
- /* If sigalgs received process it. */
- if (s->s3->tmp.peer_sigalgs) {
- if (!tls1_process_sigalgs(s)) {
- SSLerr(SSL_F_TLS1_SET_SERVER_SIGALGS, ERR_R_MALLOC_FAILURE);
- al = SSL_AD_INTERNAL_ERROR;
- goto err;
- }
- /* Fatal error is no shared signature algorithms */
- if (!s->cert->shared_sigalgs) {
- SSLerr(SSL_F_TLS1_SET_SERVER_SIGALGS,
- SSL_R_NO_SHARED_SIGNATURE_ALGORITHMS);
- al = SSL_AD_ILLEGAL_PARAMETER;
- goto err;
+ for (i = 0; i < SSL_PKEY_NUM; i++) {
+ const SIGALG_LOOKUP *lu = tls1_get_legacy_sigalg(s, i);
+ size_t j;
+
+ if (lu == NULL)
+ continue;
+ /* Check default matches a type we sent */
+ for (j = 0; j < sent_sigslen; j++) {
+ if (lu->sigalg == sent_sigs[j]) {
+ s->s3->tmp.valid_flags[i] = CERT_PKEY_SIGN;
+ break;
+ }
+ }
}
- } else {
- ssl_set_default_md(s);
+ return 1;
}
- return 1;
+
+ if (!tls1_process_sigalgs(s)) {
+ SSLerr(SSL_F_TLS1_SET_SERVER_SIGALGS, ERR_R_MALLOC_FAILURE);
+ al = SSL_AD_INTERNAL_ERROR;
+ goto err;
+ }
+ if (s->cert->shared_sigalgs != NULL)
+ return 1;
+ /* Fatal error is no shared signature algorithms */
+ SSLerr(SSL_F_TLS1_SET_SERVER_SIGALGS, SSL_R_NO_SHARED_SIGNATURE_ALGORITHMS);
+ al = SSL_AD_ILLEGAL_PARAMETER;
err:
ssl3_send_alert(s, SSL3_AL_FATAL, al);
return 0;
sess = d2i_SSL_SESSION(NULL, &p, slen);
OPENSSL_free(sdec);
if (sess) {
+ /* Some additional consistency checks */
+ if (p != sdec + slen || sess->session_id_length != 0) {
+ SSL_SESSION_free(sess);
+ return 2;
+ }
/*
* The session ID, if non-empty, is used by some clients to detect
* that the ticket has been accepted. So we copy it to the session
return ret;
}
-int tls12_get_sigandhash(SSL *s, WPACKET *pkt, const EVP_PKEY *pk,
- const EVP_MD *md, int *ispss)
-{
- int md_id, sig_id;
- size_t i;
- const SIGALG_LOOKUP *curr;
-
- if (md == NULL)
- return 0;
- md_id = EVP_MD_type(md);
- sig_id = EVP_PKEY_id(pk);
- if (md_id == NID_undef)
- return 0;
- /* For TLS 1.3 only allow RSA-PSS */
- if (SSL_IS_TLS13(s) && sig_id == EVP_PKEY_RSA)
- sig_id = EVP_PKEY_RSA_PSS;
-
- if (s->s3->tmp.peer_sigalgs == NULL) {
- /* Should never happen: we abort if no sigalgs extension and TLS 1.3 */
- if (SSL_IS_TLS13(s))
- return 0;
- /* For TLS 1.2 and no sigalgs lookup using complete table */
- for (i = 0, curr = sigalg_lookup_tbl; i < OSSL_NELEM(sigalg_lookup_tbl);
- i++, curr++) {
- if (curr->hash == md_id && curr->sig == sig_id) {
- if (!WPACKET_put_bytes_u16(pkt, curr->sigalg))
- return 0;
- *ispss = curr->sig == EVP_PKEY_RSA_PSS;
- return 1;
- }
- }
- return 0;
- }
-
- for (i = 0; i < s->cert->shared_sigalgslen; i++) {
- curr = s->cert->shared_sigalgs[i];
-
- /*
- * Look for matching key and hash. If key type is RSA also match PSS
- * signature type.
- */
- if (curr->hash == md_id && (curr->sig == sig_id
- || (sig_id == EVP_PKEY_RSA && curr->sig == EVP_PKEY_RSA_PSS))){
- if (!WPACKET_put_bytes_u16(pkt, curr->sigalg))
- return 0;
- *ispss = curr->sig == EVP_PKEY_RSA_PSS;
- return 1;
- }
- }
- return 0;
-}
-
static int tls12_get_pkey_idx(int sig_nid)
{
switch (sig_nid) {
}
/* Check to see if a signature algorithm is allowed */
-static int tls12_sigalg_allowed(SSL *s, int op, uint16_t ptmp)
+static int tls12_sigalg_allowed(SSL *s, int op, const SIGALG_LOOKUP *lu)
{
- const SIGALG_LOOKUP *lu = tls1_lookup_sigalg(ptmp);
unsigned char sigalgstr[2];
int secbits;
/* See if sigalgs is recognised and if hash is enabled */
if (lu == NULL || ssl_md(lu->hash_idx) == NULL)
return 0;
+ /* DSA is not allowed in TLS 1.3 */
+ if (SSL_IS_TLS13(s) && lu->sig == EVP_PKEY_DSA)
+ return 0;
/* See if public key algorithm allowed */
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;
+ sigalgstr[0] = (lu->sigalg >> 8) & 0xff;
+ sigalgstr[1] = lu->sigalg & 0xff;
return ssl_security(s, op, secbits, lu->hash, (void *)sigalgstr);
}
*/
sigalgslen = tls12_get_psigalgs(s, 1, &sigalgs);
for (i = 0; i < sigalgslen; i ++, sigalgs++) {
- switch (tls_sigalg_get_sig(*sigalgs)) {
+ const SIGALG_LOOKUP *lu = tls1_lookup_sigalg(*sigalgs);
+
+ if (lu == NULL)
+ continue;
+ switch (lu->sig) {
#ifndef OPENSSL_NO_RSA
/* Any RSA-PSS signature algorithms also mean we allow RSA */
case EVP_PKEY_RSA_PSS:
case EVP_PKEY_RSA:
- if (!have_rsa && tls12_sigalg_allowed(s, op, *sigalgs))
+ if (!have_rsa && tls12_sigalg_allowed(s, op, lu))
have_rsa = 1;
break;
#endif
#ifndef OPENSSL_NO_DSA
case EVP_PKEY_DSA:
- if (!have_dsa && tls12_sigalg_allowed(s, op, *sigalgs))
+ if (!have_dsa && tls12_sigalg_allowed(s, op, lu))
have_dsa = 1;
break;
#endif
#ifndef OPENSSL_NO_EC
case EVP_PKEY_EC:
- if (!have_ecdsa && tls12_sigalg_allowed(s, op, *sigalgs))
+ if (!have_ecdsa && tls12_sigalg_allowed(s, op, lu))
have_ecdsa = 1;
break;
#endif
const uint16_t *psig, size_t psiglen)
{
size_t i;
+ int rv = 0;
for (i = 0; i < psiglen; i++, psig++) {
- if (tls12_sigalg_allowed(s, SSL_SECOP_SIGALG_SUPPORTED, *psig)) {
- if (!WPACKET_put_bytes_u16(pkt, *psig))
- return 0;
- }
+ const SIGALG_LOOKUP *lu = tls1_lookup_sigalg(*psig);
+
+ if (!tls12_sigalg_allowed(s, SSL_SECOP_SIGALG_SUPPORTED, lu))
+ continue;
+ if (!WPACKET_put_bytes_u16(pkt, *psig))
+ return 0;
+ /*
+ * If TLS 1.3 must have at least one valid TLS 1.3 message
+ * signing algorithm: i.e. neither RSA nor SHA1
+ */
+ if (rv == 0 && (!SSL_IS_TLS13(s)
+ || (lu->sig != EVP_PKEY_RSA && lu->hash != NID_sha1)))
+ rv = 1;
}
- return 1;
+ return rv;
}
/* Given preference and allowed sigalgs set shared sigalgs */
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);
+
/* Skip disabled hashes or signature algorithms */
- if (!tls12_sigalg_allowed(s, SSL_SECOP_SIGALG_SHARED, *ptmp))
+ if (!tls12_sigalg_allowed(s, SSL_SECOP_SIGALG_SHARED, lu))
continue;
for (j = 0, atmp = allow; j < allowlen; j++, atmp++) {
if (*ptmp == *atmp) {
nmatch++;
- if (shsig) {
- *shsig = tls1_lookup_sigalg(*ptmp);
- shsig++;
- }
+ if (shsig)
+ *shsig++ = lu;
break;
}
}
size = PACKET_remaining(pkt);
/* Invalid data length */
- if ((size & 1) != 0)
+ if (size == 0 || (size & 1) != 0)
return 0;
size >>= 1;
int tls1_process_sigalgs(SSL *s)
{
- int idx;
size_t i;
- const EVP_MD *md;
- const EVP_MD **pmd = s->s3->tmp.md;
uint32_t *pvalid = s->s3->tmp.valid_flags;
CERT *c = s->cert;
if (!tls1_set_shared_sigalgs(s))
return 0;
+ for (i = 0; i < SSL_PKEY_NUM; i++)
+ pvalid[i] = 0;
+
for (i = 0; i < c->shared_sigalgslen; i++) {
const SIGALG_LOOKUP *sigptr = c->shared_sigalgs[i];
+ int idx = sigptr->sig_idx;
/* Ignore PKCS1 based sig algs in TLSv1.3 */
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 = ssl_md(sigptr->hash_idx);
- pmd[idx] = md;
- pvalid[idx] = CERT_PKEY_EXPLICIT_SIGN;
- }
- }
- /*
- * In strict mode or TLS1.3 leave unset digests as NULL to indicate we can't
- * use the certificate for signing.
- */
- if (!(s->cert->cert_flags & SSL_CERT_FLAGS_CHECK_TLS_STRICT)
- && !SSL_IS_TLS13(s)) {
- /*
- * Set any remaining keys to default values. NOTE: if alg is not
- * supported it stays as NULL.
- */
-#ifndef OPENSSL_NO_DSA
- if (pmd[SSL_PKEY_DSA_SIGN] == NULL)
- pmd[SSL_PKEY_DSA_SIGN] = EVP_sha1();
-#endif
-#ifndef OPENSSL_NO_RSA
- if (pmd[SSL_PKEY_RSA] == NULL) {
- pmd[SSL_PKEY_RSA] = EVP_sha1();
- }
-#endif
-#ifndef OPENSSL_NO_EC
- if (pmd[SSL_PKEY_ECC] == NULL)
- pmd[SSL_PKEY_ECC] = EVP_sha1();
-#endif
-#ifndef OPENSSL_NO_GOST
- if (pmd[SSL_PKEY_GOST01] == NULL)
- pmd[SSL_PKEY_GOST01] = EVP_get_digestbynid(NID_id_GostR3411_94);
- if (pmd[SSL_PKEY_GOST12_256] == NULL)
- pmd[SSL_PKEY_GOST12_256] =
- EVP_get_digestbynid(NID_id_GostR3411_2012_256);
- if (pmd[SSL_PKEY_GOST12_512] == NULL)
- pmd[SSL_PKEY_GOST12_512] =
- EVP_get_digestbynid(NID_id_GostR3411_2012_512);
-#endif
+ /* If not disabled indicate we can explicitly sign */
+ if (pvalid[idx] == 0 && tls12_get_pkey_idx(sigptr->sig) != -1)
+ pvalid[sigptr->sig_idx] = CERT_PKEY_EXPLICIT_SIGN | CERT_PKEY_SIGN;
}
return 1;
}
rv |= CERT_PKEY_EE_SIGNATURE | CERT_PKEY_CA_SIGNATURE;
skip_sigs:
/* Check cert parameters are consistent */
- if (tls1_check_cert_param(s, x, check_flags ? 1 : 2))
+ if (tls1_check_cert_param(s, x, 1))
rv |= CERT_PKEY_EE_PARAM;
else if (!check_flags)
goto end;
break;
}
if (check_type) {
- const unsigned char *ctypes;
- int ctypelen;
- if (c->ctypes) {
- ctypes = c->ctypes;
- ctypelen = (int)c->ctype_num;
- } else {
- ctypes = (unsigned char *)s->s3->tmp.ctype;
- ctypelen = s->s3->tmp.ctype_num;
- }
- for (i = 0; i < ctypelen; i++) {
- if (ctypes[i] == check_type) {
+ const uint8_t *ctypes = s->s3->tmp.ctype;
+ size_t j;
+
+ for (j = 0; j < s->s3->tmp.ctype_len; j++, ctypes++) {
+ if (*ctypes == check_type) {
rv |= CERT_PKEY_CERT_TYPE;
break;
}
}
if (!(rv & CERT_PKEY_CERT_TYPE) && !check_flags)
goto end;
- } else
+ } else {
rv |= CERT_PKEY_CERT_TYPE;
+ }
ca_dn = s->s3->tmp.ca_names;
end:
- if (TLS1_get_version(s) >= TLS1_2_VERSION) {
- if (*pvalid & CERT_PKEY_EXPLICIT_SIGN)
- rv |= CERT_PKEY_EXPLICIT_SIGN | CERT_PKEY_SIGN;
- else if (s->s3->tmp.md[idx] != NULL)
- rv |= CERT_PKEY_SIGN;
- } else
+ if (TLS1_get_version(s) >= TLS1_2_VERSION)
+ rv |= *pvalid & (CERT_PKEY_EXPLICIT_SIGN | CERT_PKEY_SIGN);
+ else
rv |= CERT_PKEY_SIGN | CERT_PKEY_EXPLICIT_SIGN;
/*
* chain is invalid.
*/
if (!check_flags) {
- if (rv & CERT_PKEY_VALID)
+ if (rv & CERT_PKEY_VALID) {
*pvalid = rv;
- else {
- /* Preserve explicit sign flag, clear rest */
- *pvalid &= CERT_PKEY_EXPLICIT_SIGN;
+ } else {
+ /* Preserve sign and explicit sign flag, clear rest */
+ *pvalid &= CERT_PKEY_EXPLICIT_SIGN | CERT_PKEY_SIGN;
return 0;
}
}
else
dh_secbits = 80;
} else {
- CERT_PKEY *cpk = ssl_get_server_send_pkey(s);
- dh_secbits = EVP_PKEY_security_bits(cpk->privatekey);
+ if (s->s3->tmp.cert == NULL)
+ return NULL;
+ dh_secbits = EVP_PKEY_security_bits(s->s3->tmp.cert->privatekey);
}
if (dh_secbits >= 128) {
/*
* Choose an appropriate signature algorithm based on available certificates
- * Set current certificate and digest to match chosen algorithm.
+ * Sets chosen certificate and signature algorithm.
+ *
+ * For servers if we fail to find a required certificate it is a fatal error
+ * and an appropriate error code is set and the TLS alert set in *al.
+ *
+ * For clients al is set to NULL. If a certificate is not suitable it is not
+ * a fatal error: we will either try another certificate or not present one
+ * to the server. In this case no error is set.
*/
int tls_choose_sigalg(SSL *s, int *al)
{
- int idx;
+ int idx = -1;
const SIGALG_LOOKUP *lu = NULL;
+ s->s3->tmp.cert = NULL;
+ s->s3->tmp.sigalg = NULL;
+
if (SSL_IS_TLS13(s)) {
size_t i;
#ifndef OPENSSL_NO_EC
- int curve = -1;
+ int curve = -1, skip_ec = 0;
#endif
/* Look for a certificate matching shared sigaglgs */
for (i = 0; i < s->cert->shared_sigalgslen; i++) {
lu = s->cert->shared_sigalgs[i];
- /* Skip RSA if not PSS */
- if (lu->sig == EVP_PKEY_RSA)
+ /* Skip SHA1, DSA and RSA if not PSS */
+ if (lu->hash == NID_sha1 || lu->sig == EVP_PKEY_DSA
+ || lu->sig == EVP_PKEY_RSA)
continue;
if (ssl_md(lu->hash_idx) == NULL)
continue;
EC_KEY *ec = EVP_PKEY_get0_EC_KEY(s->cert->pkeys[idx].privatekey);
curve = EC_GROUP_get_curve_name(EC_KEY_get0_group(ec));
+ if (EC_KEY_get_conv_form(ec)
+ != POINT_CONVERSION_UNCOMPRESSED)
+ skip_ec = 1;
}
- if (curve != lu->curve)
+ if (skip_ec || (lu->curve != NID_undef && curve != lu->curve))
continue;
#else
continue;
break;
}
if (i == s->cert->shared_sigalgslen) {
+ if (al == NULL)
+ return 1;
*al = SSL_AD_HANDSHAKE_FAILURE;
SSLerr(SSL_F_TLS_CHOOSE_SIGALG,
SSL_R_NO_SUITABLE_SIGNATURE_ALGORITHM);
return 0;
}
} else {
- /* Find index corresponding to ciphersuite */
- idx = ssl_cipher_get_cert_index(s->s3->tmp.new_cipher);
- /* If no certificate for ciphersuite return */
- if (idx == -1) {
- s->s3->tmp.cert_idx = -1;
- s->s3->tmp.sigalg = NULL;
- return 1;
- }
- if (idx == SSL_PKEY_GOST_EC) {
- /* Work out which GOST certificate is avaiable */
- if (ssl_has_cert(s, SSL_PKEY_GOST12_512)) {
- idx = SSL_PKEY_GOST12_512;
- } else if (ssl_has_cert(s, SSL_PKEY_GOST12_256)) {
- idx = SSL_PKEY_GOST12_256;
- } else if (ssl_has_cert(s, SSL_PKEY_GOST01)) {
- idx = SSL_PKEY_GOST01;
- } else {
+ if (s->server) {
+ /* Find index corresponding to ciphersuite */
+ idx = ssl_cipher_get_cert_index(s->s3->tmp.new_cipher);
+ /* If no certificate for ciphersuite return */
+ if (idx == -1)
+ return 1;
+ if (idx == SSL_PKEY_GOST_EC) {
+ /* Work out which GOST certificate is avaiable */
+ if (ssl_has_cert(s, SSL_PKEY_GOST12_512)) {
+ idx = SSL_PKEY_GOST12_512;
+ } else if (ssl_has_cert(s, SSL_PKEY_GOST12_256)) {
+ idx = SSL_PKEY_GOST12_256;
+ } else if (ssl_has_cert(s, SSL_PKEY_GOST01)) {
+ idx = SSL_PKEY_GOST01;
+ } else {
+ if (al == NULL)
+ return 1;
+ *al = SSL_AD_INTERNAL_ERROR;
+ SSLerr(SSL_F_TLS_CHOOSE_SIGALG, ERR_R_INTERNAL_ERROR);
+ 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;
}
- } else if (!ssl_has_cert(s, idx)) {
- *al = SSL_AD_INTERNAL_ERROR;
- SSLerr(SSL_F_TLS_CHOOSE_SIGALG, ERR_R_INTERNAL_ERROR);
- return 0;
+ } else {
+ /* Find index for client certificate */
+ idx = s->cert->key - s->cert->pkeys;
+ if (!ssl_has_cert(s, idx))
+ return 1;
}
if (SSL_USE_SIGALGS(s)) {
if (s->s3->tmp.peer_sigalgs != NULL) {
size_t i;
+#ifndef OPENSSL_NO_EC
+ int curve;
+
+ /* For Suite B need to match signature algorithm to curve */
+ if (tls1_suiteb(s)) {
+ EC_KEY *ec = EVP_PKEY_get0_EC_KEY(s->cert->pkeys[idx].privatekey);
+ curve = EC_GROUP_get_curve_name(EC_KEY_get0_group(ec));
+ } else {
+ curve = -1;
+ }
+#endif
/*
* Find highest preference signature algorithm matching
*/
for (i = 0; i < s->cert->shared_sigalgslen; i++) {
lu = s->cert->shared_sigalgs[i];
+#ifdef OPENSSL_NO_EC
if (lu->sig_idx == idx)
break;
+#else
+ if (lu->sig_idx == idx
+ && (curve == -1 || lu->curve == curve))
+ break;
+#endif
if (idx == SSL_PKEY_RSA && lu->sig == EVP_PKEY_RSA_PSS)
break;
}
if (i == s->cert->shared_sigalgslen) {
+ if (al == NULL)
+ return 1;
*al = SSL_AD_INTERNAL_ERROR;
SSLerr(SSL_F_TLS_CHOOSE_SIGALG, ERR_R_INTERNAL_ERROR);
return 0;
size_t sent_sigslen, i;
if ((lu = tls1_get_legacy_sigalg(s, idx)) == NULL) {
+ if (al == NULL)
+ return 1;
*al = SSL_AD_INTERNAL_ERROR;
SSLerr(SSL_F_TLS_CHOOSE_SIGALG, ERR_R_INTERNAL_ERROR);
return 0;
break;
}
if (i == sent_sigslen) {
+ if (al == NULL)
+ return 1;
SSLerr(SSL_F_TLS_CHOOSE_SIGALG, SSL_R_WRONG_SIGNATURE_TYPE);
*al = SSL_AD_HANDSHAKE_FAILURE;
return 0;
}
} else {
if ((lu = tls1_get_legacy_sigalg(s, idx)) == NULL) {
+ if (al == NULL)
+ return 1;
*al = SSL_AD_INTERNAL_ERROR;
SSLerr(SSL_F_TLS_CHOOSE_SIGALG, ERR_R_INTERNAL_ERROR);
return 0;
}
}
}
- s->s3->tmp.cert_idx = idx;
+ if (idx == -1) {
+ if (al != NULL) {
+ *al = SSL_AD_INTERNAL_ERROR;
+ SSLerr(SSL_F_TLS_CHOOSE_SIGALG, ERR_R_INTERNAL_ERROR);
+ }
+ return 0;
+ }
+ s->s3->tmp.cert = &s->cert->pkeys[idx];
+ s->cert->key = s->s3->tmp.cert;
s->s3->tmp.sigalg = lu;
return 1;
}