X-Git-Url: https://git.openssl.org/?p=openssl.git;a=blobdiff_plain;f=ssl%2Ft1_lib.c;h=ddafa0c623dab82f18e738609f8dd344bd3c8353;hp=156497988a622e3484fbca499fe307dbbcf9f2ec;hb=de4dc598024fd0a9c2b7a466fd5323755d369522;hpb=b8fef8ee929a8775262cb4371f62c35f7058dbed diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c index 156497988a..ddafa0c623 100644 --- a/ssl/t1_lib.c +++ b/ssl/t1_lib.c @@ -343,6 +343,10 @@ int tls1_set_groups(uint16_t **pext, size_t *pextlen, */ unsigned long dup_list = 0; + if (ngroups == 0) { + SSLerr(SSL_F_TLS1_SET_GROUPS, SSL_R_BAD_LENGTH); + return 0; + } if ((glist = OPENSSL_malloc(ngroups * sizeof(*glist))) == NULL) { SSLerr(SSL_F_TLS1_SET_GROUPS, ERR_R_MALLOC_FAILURE); return 0; @@ -945,6 +949,37 @@ size_t tls12_get_psigalgs(SSL *s, int sent, const uint16_t **psigs) } } +/* + * Called by servers only. Checks that we have a sig alg that supports the + * specified EC curve. + */ +int tls_check_sigalg_curve(const SSL *s, int curve) +{ + const uint16_t *sigs; + size_t siglen, i; + + if (s->cert->conf_sigalgs) { + sigs = s->cert->conf_sigalgs; + siglen = s->cert->conf_sigalgslen; + } else { + sigs = tls12_sigalgs; + siglen = OSSL_NELEM(tls12_sigalgs); + } + + for (i = 0; i < siglen; i++) { + const SIGALG_LOOKUP *lu = tls1_lookup_sigalg(sigs[i]); + + if (lu == NULL) + continue; + if (lu->sig == EVP_PKEY_EC + && lu->curve != NID_undef + && curve == lu->curve) + return 1; + } + + return 0; +} + /* * Check signature algorithm is consistent with sent supported signature * algorithms and if so set relevant digest and signature scheme in @@ -2492,7 +2527,7 @@ 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; + int mdnid, pknid, supported; size_t i; /* TLS 1.2 callers can override lu->sig_idx, but not TLS 1.3 callers. */ @@ -2505,19 +2540,39 @@ static int has_usable_cert(SSL *s, const SIGALG_LOOKUP *sig, int idx) 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)) + &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; - /* - * 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; + + 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 1; } return 0; } + 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; }