Latest update.

This commit is contained in:
2019-09-21 00:43:47 +09:00
parent 2e57f602ae
commit 62515c7d8d
1131 changed files with 47556 additions and 24957 deletions
+173 -87
View File
@@ -21,6 +21,8 @@
#include "ssl_locl.h"
#include <openssl/ct.h>
static const SIGALG_LOOKUP *find_sig_alg(SSL *s, X509 *x, EVP_PKEY *pkey);
SSL3_ENC_METHOD const TLSv1_enc_data = {
tls1_enc,
tls1_mac,
@@ -226,6 +228,13 @@ const TLS_GROUP_INFO *tls1_group_id_lookup(uint16_t group_id)
}
#if !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_EC)
int tls1_group_id2nid(uint16_t group_id)
{
const TLS_GROUP_INFO *ginf = tls1_group_id_lookup(group_id);
return ginf == NULL ? NID_undef : ginf->nid;
}
static uint16_t tls1_nid2group_id(int nid)
{
size_t i;
@@ -1721,8 +1730,8 @@ void ssl_set_sig_mask(uint32_t *pmask_a, SSL *s, int op)
continue;
clu = ssl_cert_lookup_by_idx(lu->sig_idx);
if (clu == NULL)
continue;
if (clu == NULL)
continue;
/* If algorithm is disabled see if we can enable it */
if ((clu->amask & disabled_mask) != 0
@@ -2144,16 +2153,34 @@ int tls1_set_sigalgs(CERT *c, const int *psig_nids, size_t salglen, int client)
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 < s->shared_sigalgslen; i++)
if (sig_nid == s->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 (sig_nid == sigalg->sigandhash)
return 1;
}
return 0;
}
@@ -2310,7 +2337,14 @@ 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(s, 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
@@ -2597,6 +2631,60 @@ static int tls12_get_cert_sigalg_idx(const SSL *s, const SIGALG_LOOKUP *lu)
return s->s3.tmp.valid_flags[sig_idx] & CERT_PKEY_VALID ? sig_idx : -1;
}
/*
* 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 check_cert_usable(SSL *s, const SIGALG_LOOKUP *sig, X509 *x,
EVP_PKEY *pkey)
{
const SIGALG_LOOKUP *lu;
int mdnid, pknid, supported;
size_t i;
/*
* If the given EVP_PKEY cannot supporting signing with this sigalg,
* the answer is simply 'no'.
*/
ERR_set_mark();
supported = EVP_PKEY_supports_digest_nid(pkey, sig->hash);
ERR_pop_to_mark();
if (supported == 0)
return 0;
/*
* The TLS 1.3 signature_algorithms_cert extension places restrictions
* on the sigalg with which the certificate was signed (by its issuer).
*/
if (s->s3.tmp.peer_cert_sigalgs != NULL) {
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]);
if (lu == NULL)
continue;
/*
* TODO this does not differentiate between the
* rsa_pss_pss_* and rsa_pss_rsae_* schemes since we do not
* have a chain here that lets us look at the key OID in the
* signing certificate.
*/
if (mdnid == lu->hash && pknid == lu->sig)
return 1;
}
return 0;
}
/*
* Without signat_algorithms_cert, any certificate for which we have
* a viable public key is permitted.
*/
return 1;
}
/*
* Returns true if |s| has a usable certificate configured for use
* with signature scheme |sig|.
@@ -2606,54 +2694,92 @@ static int tls12_get_cert_sigalg_idx(const SSL *s, const SIGALG_LOOKUP *lu)
*/
static int has_usable_cert(SSL *s, const SIGALG_LOOKUP *sig, int idx)
{
const SIGALG_LOOKUP *lu;
int mdnid, pknid, supported;
size_t i;
/* TLS 1.2 callers can override lu->sig_idx, but not TLS 1.3 callers. */
/* 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;
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)
/*
* TODO this does not differentiate between the
* rsa_pss_pss_* and rsa_pss_rsae_* schemes since we do not
* have a chain here that lets us look at the key OID in the
* signing certificate.
*/
|| mdnid != lu->hash
|| pknid != lu->sig)
continue;
ERR_set_mark();
supported = EVP_PKEY_supports_digest_nid(s->cert->pkeys[idx].privatekey,
mdnid);
if (supported == 0)
continue;
else if (supported < 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();
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));
}
return 1;
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;
}
return 0;
break;
}
supported = EVP_PKEY_supports_digest_nid(s->cert->pkeys[idx].privatekey,
sig->hash);
if (supported == 0)
return 0;
else if (supported < 0)
ERR_clear_error();
return 1;
if (i == s->shared_sigalgslen)
return NULL;
return lu;
}
/*
@@ -2676,48 +2802,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->shared_sigalgslen; i++) {
lu = s->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->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,