mirror of
https://github.com/ossrs/srs.git
synced 2025-03-09 15:49:59 +00:00
AppleM1: Update openssl to v1.1.1l
This commit is contained in:
parent
1fe12b8e8c
commit
b787656eea
990 changed files with 13406 additions and 18710 deletions
455
trunk/3rdparty/openssl-1.1-fit/ssl/t1_lib.c
vendored
455
trunk/3rdparty/openssl-1.1-fit/ssl/t1_lib.c
vendored
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
|
@ -18,9 +18,12 @@
|
|||
#include <openssl/dh.h>
|
||||
#include <openssl/bn.h>
|
||||
#include "internal/nelem.h"
|
||||
#include "ssl_locl.h"
|
||||
#include "ssl_local.h"
|
||||
#include <openssl/ct.h>
|
||||
|
||||
static const SIGALG_LOOKUP *find_sig_alg(SSL *s, X509 *x, EVP_PKEY *pkey);
|
||||
static int tls12_sigalg_allowed(const SSL *s, int op, const SIGALG_LOOKUP *lu);
|
||||
|
||||
SSL3_ENC_METHOD const TLSv1_enc_data = {
|
||||
tls1_enc,
|
||||
tls1_mac,
|
||||
|
@ -465,11 +468,11 @@ static int tls1_check_pkey_comp(SSL *s, EVP_PKEY *pkey)
|
|||
* If point formats extension present check it, otherwise everything is
|
||||
* supported (see RFC4492).
|
||||
*/
|
||||
if (s->session->ext.ecpointformats == NULL)
|
||||
if (s->ext.peer_ecpointformats == NULL)
|
||||
return 1;
|
||||
|
||||
for (i = 0; i < s->session->ext.ecpointformats_len; i++) {
|
||||
if (s->session->ext.ecpointformats[i] == comp_id)
|
||||
for (i = 0; i < s->ext.peer_ecpointformats_len; i++) {
|
||||
if (s->ext.peer_ecpointformats[i] == comp_id)
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
|
@ -578,7 +581,6 @@ static int tls1_check_cert_param(SSL *s, X509 *x, int check_ee_md)
|
|||
if (check_ee_md && tls1_suiteb(s)) {
|
||||
int check_md;
|
||||
size_t i;
|
||||
CERT *c = s->cert;
|
||||
|
||||
/* Check to see we have necessary signing algorithm */
|
||||
if (group_id == TLSEXT_curve_P_256)
|
||||
|
@ -587,8 +589,8 @@ static int tls1_check_cert_param(SSL *s, X509 *x, int check_ee_md)
|
|||
check_md = NID_ecdsa_with_SHA384;
|
||||
else
|
||||
return 0; /* Should never happen */
|
||||
for (i = 0; i < c->shared_sigalgslen; i++) {
|
||||
if (check_md == c->shared_sigalgs[i]->sigandhash)
|
||||
for (i = 0; i < s->shared_sigalgslen; i++) {
|
||||
if (check_md == s->shared_sigalgs[i]->sigandhash)
|
||||
return 1;;
|
||||
}
|
||||
return 0;
|
||||
|
@ -848,8 +850,11 @@ static int rsa_pss_check_min_key_size(const RSA *rsa, const SIGALG_LOOKUP *lu)
|
|||
}
|
||||
|
||||
/*
|
||||
* Return a signature algorithm for TLS < 1.2 where the signature type
|
||||
* is fixed by the certificate type.
|
||||
* Returns a signature algorithm when the peer did not send a list of supported
|
||||
* signature algorithms. The signature algorithm is fixed for the certificate
|
||||
* type. |idx| is a certificate type index (SSL_PKEY_*). When |idx| is -1 the
|
||||
* certificate type from |s| will be used.
|
||||
* Returns the signature algorithm to use, or NULL on error.
|
||||
*/
|
||||
static const SIGALG_LOOKUP *tls1_get_legacy_sigalg(const SSL *s, int idx)
|
||||
{
|
||||
|
@ -892,8 +897,12 @@ static const SIGALG_LOOKUP *tls1_get_legacy_sigalg(const SSL *s, int idx)
|
|||
|
||||
if (!tls1_lookup_md(lu, NULL))
|
||||
return NULL;
|
||||
if (!tls12_sigalg_allowed(s, SSL_SECOP_SIGALG_SUPPORTED, lu))
|
||||
return NULL;
|
||||
return lu;
|
||||
}
|
||||
if (!tls12_sigalg_allowed(s, SSL_SECOP_SIGALG_SUPPORTED, &legacy_rsa_sigalg))
|
||||
return NULL;
|
||||
return &legacy_rsa_sigalg;
|
||||
}
|
||||
/* Set peer sigalg based key type */
|
||||
|
@ -982,6 +991,31 @@ int tls_check_sigalg_curve(const SSL *s, int curve)
|
|||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Return the number of security bits for the signature algorithm, or 0 on
|
||||
* error.
|
||||
*/
|
||||
static int sigalg_security_bits(const SIGALG_LOOKUP *lu)
|
||||
{
|
||||
const EVP_MD *md = NULL;
|
||||
int secbits = 0;
|
||||
|
||||
if (!tls1_lookup_md(lu, &md))
|
||||
return 0;
|
||||
if (md != NULL)
|
||||
{
|
||||
/* Security bits: half digest bits */
|
||||
secbits = EVP_MD_size(md) * 4;
|
||||
} else {
|
||||
/* Values from https://tools.ietf.org/html/rfc8032#section-8.5 */
|
||||
if (lu->sigalg == TLSEXT_SIGALG_ed25519)
|
||||
secbits = 128;
|
||||
else if (lu->sigalg == TLSEXT_SIGALG_ed448)
|
||||
secbits = 224;
|
||||
}
|
||||
return secbits;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check signature algorithm is consistent with sent supported signature
|
||||
* algorithms and if so set relevant digest and signature scheme in
|
||||
|
@ -995,6 +1029,7 @@ int tls12_check_peer_sigalg(SSL *s, uint16_t sig, EVP_PKEY *pkey)
|
|||
size_t sent_sigslen, i, cidx;
|
||||
int pkeyid = EVP_PKEY_id(pkey);
|
||||
const SIGALG_LOOKUP *lu;
|
||||
int secbits = 0;
|
||||
|
||||
/* Should never happen */
|
||||
if (pkeyid == -1)
|
||||
|
@ -1096,20 +1131,20 @@ int tls12_check_peer_sigalg(SSL *s, uint16_t sig, EVP_PKEY *pkey)
|
|||
SSL_R_UNKNOWN_DIGEST);
|
||||
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)) {
|
||||
SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_F_TLS12_CHECK_PEER_SIGALG,
|
||||
SSL_R_WRONG_SIGNATURE_TYPE);
|
||||
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;
|
||||
secbits = sigalg_security_bits(lu);
|
||||
if (secbits == 0 ||
|
||||
!ssl_security(s, SSL_SECOP_SIGALG_CHECK, secbits,
|
||||
md != NULL ? EVP_MD_type(md) : NID_undef,
|
||||
(void *)sigalgstr)) {
|
||||
SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, 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;
|
||||
|
@ -1175,7 +1210,7 @@ int ssl_set_client_disabled(SSL *s)
|
|||
*
|
||||
* Returns 1 when it's disabled, 0 when enabled.
|
||||
*/
|
||||
int ssl_cipher_disabled(SSL *s, const SSL_CIPHER *c, int op, int ecdhe)
|
||||
int ssl_cipher_disabled(const SSL *s, const SSL_CIPHER *c, int op, int ecdhe)
|
||||
{
|
||||
if (c->algorithm_mkey & s->s3->tmp.mask_k
|
||||
|| c->algorithm_auth & s->s3->tmp.mask_a)
|
||||
|
@ -1215,9 +1250,9 @@ int tls1_set_server_sigalgs(SSL *s)
|
|||
size_t i;
|
||||
|
||||
/* Clear any shared signature algorithms */
|
||||
OPENSSL_free(s->cert->shared_sigalgs);
|
||||
s->cert->shared_sigalgs = NULL;
|
||||
s->cert->shared_sigalgslen = 0;
|
||||
OPENSSL_free(s->shared_sigalgs);
|
||||
s->shared_sigalgs = NULL;
|
||||
s->shared_sigalgslen = 0;
|
||||
/* Clear certificate validity flags */
|
||||
for (i = 0; i < SSL_PKEY_NUM; i++)
|
||||
s->s3->tmp.valid_flags[i] = 0;
|
||||
|
@ -1252,7 +1287,7 @@ int tls1_set_server_sigalgs(SSL *s)
|
|||
SSL_F_TLS1_SET_SERVER_SIGALGS, ERR_R_INTERNAL_ERROR);
|
||||
return 0;
|
||||
}
|
||||
if (s->cert->shared_sigalgs != NULL)
|
||||
if (s->shared_sigalgs != NULL)
|
||||
return 1;
|
||||
|
||||
/* Fatal error if no shared signature algorithms */
|
||||
|
@ -1555,7 +1590,7 @@ SSL_TICKET_STATUS tls_decrypt_ticket(SSL *s, const unsigned char *etick,
|
|||
}
|
||||
|
||||
/* Check to see if a signature algorithm is allowed */
|
||||
static int tls12_sigalg_allowed(SSL *s, int op, const SIGALG_LOOKUP *lu)
|
||||
static int tls12_sigalg_allowed(const SSL *s, int op, const SIGALG_LOOKUP *lu)
|
||||
{
|
||||
unsigned char sigalgstr[2];
|
||||
int secbits;
|
||||
|
@ -1616,11 +1651,8 @@ static int tls12_sigalg_allowed(SSL *s, int op, const SIGALG_LOOKUP *lu)
|
|||
}
|
||||
}
|
||||
|
||||
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 */
|
||||
secbits = sigalg_security_bits(lu);
|
||||
sigalgstr[0] = (lu->sigalg >> 8) & 0xff;
|
||||
sigalgstr[1] = lu->sigalg & 0xff;
|
||||
return ssl_security(s, op, secbits, lu->hash, (void *)sigalgstr);
|
||||
|
@ -1724,9 +1756,9 @@ static int tls1_set_shared_sigalgs(SSL *s)
|
|||
CERT *c = s->cert;
|
||||
unsigned int is_suiteb = tls1_suiteb(s);
|
||||
|
||||
OPENSSL_free(c->shared_sigalgs);
|
||||
c->shared_sigalgs = NULL;
|
||||
c->shared_sigalgslen = 0;
|
||||
OPENSSL_free(s->shared_sigalgs);
|
||||
s->shared_sigalgs = NULL;
|
||||
s->shared_sigalgslen = 0;
|
||||
/* If client use client signature algorithms if not NULL */
|
||||
if (!s->server && c->client_sigalgs && !is_suiteb) {
|
||||
conf = c->client_sigalgs;
|
||||
|
@ -1757,8 +1789,8 @@ static int tls1_set_shared_sigalgs(SSL *s)
|
|||
} else {
|
||||
salgs = NULL;
|
||||
}
|
||||
c->shared_sigalgs = salgs;
|
||||
c->shared_sigalgslen = nmatch;
|
||||
s->shared_sigalgs = salgs;
|
||||
s->shared_sigalgslen = nmatch;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -1819,7 +1851,6 @@ int tls1_process_sigalgs(SSL *s)
|
|||
{
|
||||
size_t i;
|
||||
uint32_t *pvalid = s->s3->tmp.valid_flags;
|
||||
CERT *c = s->cert;
|
||||
|
||||
if (!tls1_set_shared_sigalgs(s))
|
||||
return 0;
|
||||
|
@ -1827,8 +1858,8 @@ int tls1_process_sigalgs(SSL *s)
|
|||
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];
|
||||
for (i = 0; i < s->shared_sigalgslen; i++) {
|
||||
const SIGALG_LOOKUP *sigptr = s->shared_sigalgs[i];
|
||||
int idx = sigptr->sig_idx;
|
||||
|
||||
/* Ignore PKCS1 based sig algs in TLSv1.3 */
|
||||
|
@ -1875,12 +1906,12 @@ int SSL_get_shared_sigalgs(SSL *s, int idx,
|
|||
unsigned char *rsig, unsigned char *rhash)
|
||||
{
|
||||
const SIGALG_LOOKUP *shsigalgs;
|
||||
if (s->cert->shared_sigalgs == NULL
|
||||
if (s->shared_sigalgs == NULL
|
||||
|| idx < 0
|
||||
|| idx >= (int)s->cert->shared_sigalgslen
|
||||
|| s->cert->shared_sigalgslen > INT_MAX)
|
||||
|| idx >= (int)s->shared_sigalgslen
|
||||
|| s->shared_sigalgslen > INT_MAX)
|
||||
return 0;
|
||||
shsigalgs = s->cert->shared_sigalgs[idx];
|
||||
shsigalgs = s->shared_sigalgs[idx];
|
||||
if (phash != NULL)
|
||||
*phash = shsigalgs->hash;
|
||||
if (psign != NULL)
|
||||
|
@ -1891,7 +1922,7 @@ int SSL_get_shared_sigalgs(SSL *s, int idx,
|
|||
*rsig = (unsigned char)(shsigalgs->sigalg & 0xff);
|
||||
if (rhash != NULL)
|
||||
*rhash = (unsigned char)((shsigalgs->sigalg >> 8) & 0xff);
|
||||
return (int)s->cert->shared_sigalgslen;
|
||||
return (int)s->shared_sigalgslen;
|
||||
}
|
||||
|
||||
/* Maximum possible number of unique entries in sigalgs array */
|
||||
|
@ -2072,18 +2103,36 @@ int tls1_set_sigalgs(CERT *c, const int *psig_nids, size_t salglen, int client)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int tls1_check_sig_alg(CERT *c, X509 *x, int default_nid)
|
||||
static int tls1_check_sig_alg(SSL *s, X509 *x, int default_nid)
|
||||
{
|
||||
int sig_nid;
|
||||
int sig_nid, use_pc_sigalgs = 0;
|
||||
size_t i;
|
||||
const SIGALG_LOOKUP *sigalg;
|
||||
size_t sigalgslen;
|
||||
if (default_nid == -1)
|
||||
return 1;
|
||||
sig_nid = X509_get_signature_nid(x);
|
||||
if (default_nid)
|
||||
return sig_nid == default_nid ? 1 : 0;
|
||||
for (i = 0; i < c->shared_sigalgslen; i++)
|
||||
if (sig_nid == c->shared_sigalgs[i]->sigandhash)
|
||||
|
||||
if (SSL_IS_TLS13(s) && s->s3->tmp.peer_cert_sigalgs != NULL) {
|
||||
/*
|
||||
* If we're in TLSv1.3 then we only get here if we're checking the
|
||||
* chain. If the peer has specified peer_cert_sigalgs then we use them
|
||||
* otherwise we default to normal sigalgs.
|
||||
*/
|
||||
sigalgslen = s->s3->tmp.peer_cert_sigalgslen;
|
||||
use_pc_sigalgs = 1;
|
||||
} else {
|
||||
sigalgslen = s->shared_sigalgslen;
|
||||
}
|
||||
for (i = 0; i < sigalgslen; i++) {
|
||||
sigalg = use_pc_sigalgs
|
||||
? tls1_lookup_sigalg(s->s3->tmp.peer_cert_sigalgs[i])
|
||||
: s->shared_sigalgs[i];
|
||||
if (sigalg != NULL && sig_nid == sigalg->sigandhash)
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -2240,14 +2289,21 @@ int tls1_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain,
|
|||
}
|
||||
}
|
||||
/* Check signature algorithm of each cert in chain */
|
||||
if (!tls1_check_sig_alg(c, x, default_nid)) {
|
||||
if (SSL_IS_TLS13(s)) {
|
||||
/*
|
||||
* We only get here if the application has called SSL_check_chain(),
|
||||
* so check_flags is always set.
|
||||
*/
|
||||
if (find_sig_alg(s, x, pk) != NULL)
|
||||
rv |= CERT_PKEY_EE_SIGNATURE;
|
||||
} else if (!tls1_check_sig_alg(s, x, default_nid)) {
|
||||
if (!check_flags)
|
||||
goto end;
|
||||
} else
|
||||
rv |= CERT_PKEY_EE_SIGNATURE;
|
||||
rv |= CERT_PKEY_CA_SIGNATURE;
|
||||
for (i = 0; i < sk_X509_num(chain); i++) {
|
||||
if (!tls1_check_sig_alg(c, sk_X509_value(chain, i), default_nid)) {
|
||||
if (!tls1_check_sig_alg(s, sk_X509_value(chain, i), default_nid)) {
|
||||
if (check_flags) {
|
||||
rv &= ~CERT_PKEY_CA_SIGNATURE;
|
||||
break;
|
||||
|
@ -2383,46 +2439,55 @@ int SSL_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain)
|
|||
#ifndef OPENSSL_NO_DH
|
||||
DH *ssl_get_auto_dh(SSL *s)
|
||||
{
|
||||
int dh_secbits = 80;
|
||||
if (s->cert->dh_tmp_auto == 2)
|
||||
return DH_get_1024_160();
|
||||
if (s->s3->tmp.new_cipher->algorithm_auth & (SSL_aNULL | SSL_aPSK)) {
|
||||
if (s->s3->tmp.new_cipher->strength_bits == 256)
|
||||
dh_secbits = 128;
|
||||
else
|
||||
dh_secbits = 80;
|
||||
} else {
|
||||
if (s->s3->tmp.cert == NULL)
|
||||
return NULL;
|
||||
dh_secbits = EVP_PKEY_security_bits(s->s3->tmp.cert->privatekey);
|
||||
DH *dhp = NULL;
|
||||
BIGNUM *p = NULL, *g = NULL;
|
||||
int dh_secbits = 80, sec_level_bits;
|
||||
|
||||
if (s->cert->dh_tmp_auto != 2) {
|
||||
if (s->s3->tmp.new_cipher->algorithm_auth & (SSL_aNULL | SSL_aPSK)) {
|
||||
if (s->s3->tmp.new_cipher->strength_bits == 256)
|
||||
dh_secbits = 128;
|
||||
else
|
||||
dh_secbits = 80;
|
||||
} else {
|
||||
if (s->s3->tmp.cert == NULL)
|
||||
return NULL;
|
||||
dh_secbits = EVP_PKEY_security_bits(s->s3->tmp.cert->privatekey);
|
||||
}
|
||||
}
|
||||
|
||||
if (dh_secbits >= 128) {
|
||||
DH *dhp = DH_new();
|
||||
BIGNUM *p, *g;
|
||||
if (dhp == NULL)
|
||||
return NULL;
|
||||
g = BN_new();
|
||||
if (g == NULL || !BN_set_word(g, 2)) {
|
||||
DH_free(dhp);
|
||||
BN_free(g);
|
||||
return NULL;
|
||||
}
|
||||
if (dh_secbits >= 192)
|
||||
p = BN_get_rfc3526_prime_8192(NULL);
|
||||
else
|
||||
p = BN_get_rfc3526_prime_3072(NULL);
|
||||
if (p == NULL || !DH_set0_pqg(dhp, p, NULL, g)) {
|
||||
DH_free(dhp);
|
||||
BN_free(p);
|
||||
BN_free(g);
|
||||
return NULL;
|
||||
}
|
||||
return dhp;
|
||||
dhp = DH_new();
|
||||
if (dhp == NULL)
|
||||
return NULL;
|
||||
g = BN_new();
|
||||
if (g == NULL || !BN_set_word(g, 2)) {
|
||||
DH_free(dhp);
|
||||
BN_free(g);
|
||||
return NULL;
|
||||
}
|
||||
if (dh_secbits >= 112)
|
||||
return DH_get_2048_224();
|
||||
return DH_get_1024_160();
|
||||
|
||||
/* Do not pick a prime that is too weak for the current security level */
|
||||
sec_level_bits = ssl_get_security_level_bits(s, NULL, NULL);
|
||||
if (dh_secbits < sec_level_bits)
|
||||
dh_secbits = sec_level_bits;
|
||||
|
||||
if (dh_secbits >= 192)
|
||||
p = BN_get_rfc3526_prime_8192(NULL);
|
||||
else if (dh_secbits >= 152)
|
||||
p = BN_get_rfc3526_prime_4096(NULL);
|
||||
else if (dh_secbits >= 128)
|
||||
p = BN_get_rfc3526_prime_3072(NULL);
|
||||
else if (dh_secbits >= 112)
|
||||
p = BN_get_rfc3526_prime_2048(NULL);
|
||||
else
|
||||
p = BN_get_rfc2409_prime_1024(NULL);
|
||||
if (p == NULL || !DH_set0_pqg(dhp, p, NULL, g)) {
|
||||
DH_free(dhp);
|
||||
BN_free(p);
|
||||
BN_free(g);
|
||||
return NULL;
|
||||
}
|
||||
return dhp;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -2528,44 +2593,33 @@ static int tls12_get_cert_sigalg_idx(const SSL *s, const SIGALG_LOOKUP *lu)
|
|||
}
|
||||
|
||||
/*
|
||||
* Returns true if |s| has a usable certificate configured for use
|
||||
* with signature scheme |sig|.
|
||||
* "Usable" includes a check for presence as well as applying
|
||||
* the signature_algorithm_cert restrictions sent by the peer (if any).
|
||||
* Returns false if no usable certificate is found.
|
||||
* Checks the given cert against signature_algorithm_cert restrictions sent by
|
||||
* the peer (if any) as well as whether the hash from the sigalg is usable with
|
||||
* the key.
|
||||
* Returns true if the cert is usable and false otherwise.
|
||||
*/
|
||||
static int has_usable_cert(SSL *s, const SIGALG_LOOKUP *sig, int idx)
|
||||
static int check_cert_usable(SSL *s, const SIGALG_LOOKUP *sig, X509 *x,
|
||||
EVP_PKEY *pkey)
|
||||
{
|
||||
const SIGALG_LOOKUP *lu;
|
||||
int mdnid, pknid, default_mdnid;
|
||||
int mandatory_md = 0;
|
||||
size_t i;
|
||||
|
||||
/* TLS 1.2 callers can override lu->sig_idx, but not TLS 1.3 callers. */
|
||||
if (idx == -1)
|
||||
idx = sig->sig_idx;
|
||||
if (!ssl_has_cert(s, idx))
|
||||
return 0;
|
||||
/* If the EVP_PKEY reports a mandatory digest, allow nothing else. */
|
||||
ERR_set_mark();
|
||||
switch (EVP_PKEY_get_default_digest_nid(s->cert->pkeys[idx].privatekey,
|
||||
&default_mdnid)) {
|
||||
case 2:
|
||||
mandatory_md = 1;
|
||||
break;
|
||||
case 1:
|
||||
break;
|
||||
default: /* If it didn't report a mandatory NID, for whatever reasons,
|
||||
* just clear the error and allow all hashes to be used. */
|
||||
ERR_pop_to_mark();
|
||||
}
|
||||
if (EVP_PKEY_get_default_digest_nid(pkey, &default_mdnid) == 2 &&
|
||||
sig->hash != default_mdnid)
|
||||
return 0;
|
||||
|
||||
/* If it didn't report a mandatory NID, for whatever reasons,
|
||||
* just clear the error and allow all hashes to be used. */
|
||||
ERR_pop_to_mark();
|
||||
|
||||
if (s->s3->tmp.peer_cert_sigalgs != NULL) {
|
||||
for (i = 0; i < s->s3->tmp.peer_cert_sigalgslen; i++) {
|
||||
lu = tls1_lookup_sigalg(s->s3->tmp.peer_cert_sigalgs[i]);
|
||||
if (lu == NULL
|
||||
|| !X509_get_signature_info(s->cert->pkeys[idx].x509, &mdnid,
|
||||
&pknid, NULL, NULL)
|
||||
|| (mandatory_md && mdnid != default_mdnid))
|
||||
|| !X509_get_signature_info(x, &mdnid, &pknid, NULL, NULL))
|
||||
continue;
|
||||
/*
|
||||
* TODO this does not differentiate between the
|
||||
|
@ -2578,7 +2632,104 @@ static int has_usable_cert(SSL *s, const SIGALG_LOOKUP *sig, int idx)
|
|||
}
|
||||
return 0;
|
||||
}
|
||||
return !mandatory_md || sig->hash == default_mdnid;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns true if |s| has a usable certificate configured for use
|
||||
* with signature scheme |sig|.
|
||||
* "Usable" includes a check for presence as well as applying
|
||||
* the signature_algorithm_cert restrictions sent by the peer (if any).
|
||||
* Returns false if no usable certificate is found.
|
||||
*/
|
||||
static int has_usable_cert(SSL *s, const SIGALG_LOOKUP *sig, int idx)
|
||||
{
|
||||
/* TLS 1.2 callers can override sig->sig_idx, but not TLS 1.3 callers. */
|
||||
if (idx == -1)
|
||||
idx = sig->sig_idx;
|
||||
if (!ssl_has_cert(s, idx))
|
||||
return 0;
|
||||
|
||||
return check_cert_usable(s, sig, s->cert->pkeys[idx].x509,
|
||||
s->cert->pkeys[idx].privatekey);
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns true if the supplied cert |x| and key |pkey| is usable with the
|
||||
* specified signature scheme |sig|, or false otherwise.
|
||||
*/
|
||||
static int is_cert_usable(SSL *s, const SIGALG_LOOKUP *sig, X509 *x,
|
||||
EVP_PKEY *pkey)
|
||||
{
|
||||
size_t idx;
|
||||
|
||||
if (ssl_cert_lookup_by_pkey(pkey, &idx) == NULL)
|
||||
return 0;
|
||||
|
||||
/* Check the key is consistent with the sig alg */
|
||||
if ((int)idx != sig->sig_idx)
|
||||
return 0;
|
||||
|
||||
return check_cert_usable(s, sig, x, pkey);
|
||||
}
|
||||
|
||||
/*
|
||||
* Find a signature scheme that works with the supplied certificate |x| and key
|
||||
* |pkey|. |x| and |pkey| may be NULL in which case we additionally look at our
|
||||
* available certs/keys to find one that works.
|
||||
*/
|
||||
static const SIGALG_LOOKUP *find_sig_alg(SSL *s, X509 *x, EVP_PKEY *pkey)
|
||||
{
|
||||
const SIGALG_LOOKUP *lu = NULL;
|
||||
size_t i;
|
||||
#ifndef OPENSSL_NO_EC
|
||||
int curve = -1;
|
||||
#endif
|
||||
EVP_PKEY *tmppkey;
|
||||
|
||||
/* Look for a shared sigalgs matching possible certificates */
|
||||
for (i = 0; i < s->shared_sigalgslen; i++) {
|
||||
lu = s->shared_sigalgs[i];
|
||||
|
||||
/* Skip SHA1, SHA224, DSA and RSA if not PSS */
|
||||
if (lu->hash == NID_sha1
|
||||
|| lu->hash == NID_sha224
|
||||
|| lu->sig == EVP_PKEY_DSA
|
||||
|| lu->sig == EVP_PKEY_RSA)
|
||||
continue;
|
||||
/* Check that we have a cert, and signature_algorithms_cert */
|
||||
if (!tls1_lookup_md(lu, NULL))
|
||||
continue;
|
||||
if ((pkey == NULL && !has_usable_cert(s, lu, -1))
|
||||
|| (pkey != NULL && !is_cert_usable(s, lu, x, pkey)))
|
||||
continue;
|
||||
|
||||
tmppkey = (pkey != NULL) ? pkey
|
||||
: s->cert->pkeys[lu->sig_idx].privatekey;
|
||||
|
||||
if (lu->sig == EVP_PKEY_EC) {
|
||||
#ifndef OPENSSL_NO_EC
|
||||
if (curve == -1) {
|
||||
EC_KEY *ec = EVP_PKEY_get0_EC_KEY(tmppkey);
|
||||
curve = EC_GROUP_get_curve_name(EC_KEY_get0_group(ec));
|
||||
}
|
||||
if (lu->curve != NID_undef && curve != lu->curve)
|
||||
continue;
|
||||
#else
|
||||
continue;
|
||||
#endif
|
||||
} else if (lu->sig == EVP_PKEY_RSA_PSS) {
|
||||
/* validate that key is large enough for the signature algorithm */
|
||||
if (!rsa_pss_check_min_key_size(EVP_PKEY_get0(tmppkey), lu))
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == s->shared_sigalgslen)
|
||||
return NULL;
|
||||
|
||||
return lu;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -2601,48 +2752,8 @@ int tls_choose_sigalg(SSL *s, int fatalerrs)
|
|||
s->s3->tmp.sigalg = NULL;
|
||||
|
||||
if (SSL_IS_TLS13(s)) {
|
||||
size_t i;
|
||||
#ifndef OPENSSL_NO_EC
|
||||
int curve = -1;
|
||||
#endif
|
||||
|
||||
/* Look for a certificate matching shared sigalgs */
|
||||
for (i = 0; i < s->cert->shared_sigalgslen; i++) {
|
||||
lu = s->cert->shared_sigalgs[i];
|
||||
sig_idx = -1;
|
||||
|
||||
/* Skip SHA1, SHA224, DSA and RSA if not PSS */
|
||||
if (lu->hash == NID_sha1
|
||||
|| lu->hash == NID_sha224
|
||||
|| lu->sig == EVP_PKEY_DSA
|
||||
|| lu->sig == EVP_PKEY_RSA)
|
||||
continue;
|
||||
/* Check that we have a cert, and signature_algorithms_cert */
|
||||
if (!tls1_lookup_md(lu, NULL) || !has_usable_cert(s, lu, -1))
|
||||
continue;
|
||||
if (lu->sig == EVP_PKEY_EC) {
|
||||
#ifndef OPENSSL_NO_EC
|
||||
if (curve == -1) {
|
||||
EC_KEY *ec = EVP_PKEY_get0_EC_KEY(s->cert->pkeys[SSL_PKEY_ECC].privatekey);
|
||||
|
||||
curve = EC_GROUP_get_curve_name(EC_KEY_get0_group(ec));
|
||||
}
|
||||
if (lu->curve != NID_undef && curve != lu->curve)
|
||||
continue;
|
||||
#else
|
||||
continue;
|
||||
#endif
|
||||
} else if (lu->sig == EVP_PKEY_RSA_PSS) {
|
||||
/* validate that key is large enough for the signature algorithm */
|
||||
EVP_PKEY *pkey;
|
||||
|
||||
pkey = s->cert->pkeys[lu->sig_idx].privatekey;
|
||||
if (!rsa_pss_check_min_key_size(EVP_PKEY_get0(pkey), lu))
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (i == s->cert->shared_sigalgslen) {
|
||||
lu = find_sig_alg(s, NULL, NULL);
|
||||
if (lu == NULL) {
|
||||
if (!fatalerrs)
|
||||
return 1;
|
||||
SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_F_TLS_CHOOSE_SIGALG,
|
||||
|
@ -2675,8 +2786,8 @@ int tls_choose_sigalg(SSL *s, int fatalerrs)
|
|||
* Find highest preference signature algorithm matching
|
||||
* cert type
|
||||
*/
|
||||
for (i = 0; i < s->cert->shared_sigalgslen; i++) {
|
||||
lu = s->cert->shared_sigalgs[i];
|
||||
for (i = 0; i < s->shared_sigalgslen; i++) {
|
||||
lu = s->shared_sigalgs[i];
|
||||
|
||||
if (s->server) {
|
||||
if ((sig_idx = tls12_get_cert_sigalg_idx(s, lu)) == -1)
|
||||
|
@ -2703,7 +2814,27 @@ int tls_choose_sigalg(SSL *s, int fatalerrs)
|
|||
#endif
|
||||
break;
|
||||
}
|
||||
if (i == s->cert->shared_sigalgslen) {
|
||||
#ifndef OPENSSL_NO_GOST
|
||||
/*
|
||||
* Some Windows-based implementations do not send GOST algorithms indication
|
||||
* in supported_algorithms extension, so when we have GOST-based ciphersuite,
|
||||
* we have to assume GOST support.
|
||||
*/
|
||||
if (i == s->shared_sigalgslen && s->s3->tmp.new_cipher->algorithm_auth & (SSL_aGOST01 | SSL_aGOST12)) {
|
||||
if ((lu = tls1_get_legacy_sigalg(s, -1)) == NULL) {
|
||||
if (!fatalerrs)
|
||||
return 1;
|
||||
SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE,
|
||||
SSL_F_TLS_CHOOSE_SIGALG,
|
||||
SSL_R_NO_SUITABLE_SIGNATURE_ALGORITHM);
|
||||
return 0;
|
||||
} else {
|
||||
i = 0;
|
||||
sig_idx = lu->sig_idx;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (i == s->shared_sigalgslen) {
|
||||
if (!fatalerrs)
|
||||
return 1;
|
||||
SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue