X-Git-Url: https://git.openssl.org/?p=openssl.git;a=blobdiff_plain;f=ssl%2Ft1_lib.c;h=384a8c1ecb98e06717dce5d2f2dd77138c350dd9;hp=7685403e3f00e849882897084c8a6a9efb0203d0;hb=f1a5939f177becfaf465f9cf5a834ce6341276c4;hpb=018031faa82a4f1d9ab1d0a048b56ba1f0163ae9 diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c index 7685403e3f..384a8c1ecb 100644 --- a/ssl/t1_lib.c +++ b/ssl/t1_lib.c @@ -607,7 +607,7 @@ static int tls1_check_cert_param(SSL *s, X509 *x, int set_ee_md) else return 0; /* Should never happen */ for (i = 0; i < c->shared_sigalgslen; i++) - if (check_md == c->shared_sigalgs[i].signandhash_nid) + if (check_md == c->shared_sigalgs[i]->sigandhash) break; if (i == c->shared_sigalgslen) return 0; @@ -705,65 +705,91 @@ static const uint16_t suiteb_sigalgs[] = { }; #endif -typedef struct sigalg_lookup_st { - uint16_t sigalg; - int hash; - int sig; -} SIGALG_LOOKUP; - static const SIGALG_LOOKUP sigalg_lookup_tbl[] = { #ifndef OPENSSL_NO_EC - {TLSEXT_SIGALG_ecdsa_secp256r1_sha256, NID_sha256, EVP_PKEY_EC}, - {TLSEXT_SIGALG_ecdsa_secp384r1_sha384, NID_sha384, EVP_PKEY_EC}, - {TLSEXT_SIGALG_ecdsa_secp521r1_sha512, NID_sha512, EVP_PKEY_EC}, - {TLSEXT_SIGALG_ecdsa_sha1, NID_sha1, EVP_PKEY_EC}, + {"ecdsa_secp256r1_sha256", TLSEXT_SIGALG_ecdsa_secp256r1_sha256, + NID_sha256, SSL_MD_SHA256_IDX, EVP_PKEY_EC, SSL_PKEY_ECC, + NID_ecdsa_with_SHA256, NID_X9_62_prime256v1}, + {"ecdsa_secp384r1_sha384", TLSEXT_SIGALG_ecdsa_secp384r1_sha384, + NID_sha384, SSL_MD_SHA384_IDX, EVP_PKEY_EC, SSL_PKEY_ECC, + NID_ecdsa_with_SHA384, NID_secp384r1}, + {"ecdsa_secp521r1_sha512", TLSEXT_SIGALG_ecdsa_secp521r1_sha512, + NID_sha512, SSL_MD_SHA512_IDX, EVP_PKEY_EC, SSL_PKEY_ECC, + NID_ecdsa_with_SHA512, NID_secp521r1}, + {NULL, TLSEXT_SIGALG_ecdsa_sha1, + NID_sha1, SSL_MD_SHA1_IDX, EVP_PKEY_EC, SSL_PKEY_ECC, + NID_ecdsa_with_SHA1, NID_undef}, #endif - {TLSEXT_SIGALG_rsa_pss_sha256, NID_sha256, EVP_PKEY_RSA_PSS}, - {TLSEXT_SIGALG_rsa_pss_sha384, NID_sha384, EVP_PKEY_RSA_PSS}, - {TLSEXT_SIGALG_rsa_pss_sha512, NID_sha512, EVP_PKEY_RSA_PSS}, - {TLSEXT_SIGALG_rsa_pkcs1_sha256, NID_sha256, EVP_PKEY_RSA}, - {TLSEXT_SIGALG_rsa_pkcs1_sha384, NID_sha384, EVP_PKEY_RSA}, - {TLSEXT_SIGALG_rsa_pkcs1_sha512, NID_sha512, EVP_PKEY_RSA}, - {TLSEXT_SIGALG_rsa_pkcs1_sha1, NID_sha1, EVP_PKEY_RSA}, + {"rsa_pss_sha256", TLSEXT_SIGALG_rsa_pss_sha256, + NID_sha256, SSL_MD_SHA256_IDX, EVP_PKEY_RSA_PSS, SSL_PKEY_RSA_PSS_SIGN, + NID_undef, NID_undef}, + {"rsa_pss_sha384", TLSEXT_SIGALG_rsa_pss_sha384, + NID_sha384, SSL_MD_SHA384_IDX, EVP_PKEY_RSA_PSS, SSL_PKEY_RSA_PSS_SIGN, + NID_undef, NID_undef}, + {"rsa_pss_sha512", TLSEXT_SIGALG_rsa_pss_sha512, + 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_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_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_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_sha1WithRSAEncryption, NID_undef}, #ifndef OPENSSL_NO_DSA - {TLSEXT_SIGALG_dsa_sha256, NID_sha256, EVP_PKEY_DSA}, - {TLSEXT_SIGALG_dsa_sha384, NID_sha384, EVP_PKEY_DSA}, - {TLSEXT_SIGALG_dsa_sha512, NID_sha512, EVP_PKEY_DSA}, - {TLSEXT_SIGALG_dsa_sha1, NID_sha1, EVP_PKEY_DSA}, + {NULL, TLSEXT_SIGALG_dsa_sha256, + NID_sha256, SSL_MD_SHA256_IDX, EVP_PKEY_DSA, SSL_PKEY_DSA_SIGN, + NID_dsa_with_SHA256, NID_undef}, + {NULL, TLSEXT_SIGALG_dsa_sha384, + NID_sha384, SSL_MD_SHA384_IDX, EVP_PKEY_DSA, SSL_PKEY_DSA_SIGN, + NID_undef, NID_undef}, + {NULL, TLSEXT_SIGALG_dsa_sha512, + NID_sha512, SSL_MD_SHA512_IDX, EVP_PKEY_DSA, SSL_PKEY_DSA_SIGN, + NID_undef, NID_undef}, + {NULL, TLSEXT_SIGALG_dsa_sha1, + NID_sha1, SSL_MD_SHA1_IDX, EVP_PKEY_DSA, SSL_PKEY_DSA_SIGN, + NID_dsaWithSHA1, NID_undef}, #endif #ifndef OPENSSL_NO_GOST - {TLSEXT_SIGALG_gostr34102012_256_gostr34112012_256, NID_id_GostR3411_2012_256, NID_id_GostR3410_2012_256}, - {TLSEXT_SIGALG_gostr34102012_512_gostr34112012_512, NID_id_GostR3411_2012_512, NID_id_GostR3410_2012_512}, - {TLSEXT_SIGALG_gostr34102001_gostr3411, NID_id_GostR3411_94, NID_id_GostR3410_2001} + {NULL, TLSEXT_SIGALG_gostr34102012_256_gostr34112012_256, + NID_id_GostR3411_2012_256, SSL_MD_GOST12_256_IDX, + NID_id_GostR3410_2012_256, SSL_PKEY_GOST12_256, + NID_undef, NID_undef}, + {NULL, TLSEXT_SIGALG_gostr34102012_512_gostr34112012_512, + NID_id_GostR3411_2012_512, SSL_MD_GOST12_512_IDX, + NID_id_GostR3410_2012_512, SSL_PKEY_GOST12_512, + NID_undef, NID_undef}, + {NULL, TLSEXT_SIGALG_gostr34102001_gostr3411, + NID_id_GostR3411_94, SSL_MD_GOST94_IDX, + NID_id_GostR3410_2001, SSL_PKEY_GOST01, + NID_undef, NID_undef} #endif }; -static int tls_sigalg_get_hash(uint16_t sigalg) +/* Lookup TLS signature algorithm */ +static const SIGALG_LOOKUP *tls1_lookup_sigalg(uint16_t sigalg) { size_t i; - const SIGALG_LOOKUP *curr; + const SIGALG_LOOKUP *s; - for (i = 0, curr = sigalg_lookup_tbl; i < OSSL_NELEM(sigalg_lookup_tbl); - i++, curr++) { - if (curr->sigalg == sigalg) - return curr->hash; + for (i = 0, s = sigalg_lookup_tbl; i < OSSL_NELEM(sigalg_lookup_tbl); + i++, s++) { + if (s->sigalg == sigalg) + return s; } - - return 0; + return NULL; } static int tls_sigalg_get_sig(uint16_t sigalg) { - size_t i; - const SIGALG_LOOKUP *curr; + const SIGALG_LOOKUP *r = tls1_lookup_sigalg(sigalg); - for (i = 0, curr = sigalg_lookup_tbl; i < OSSL_NELEM(sigalg_lookup_tbl); - i++, curr++) { - if (curr->sigalg == sigalg) - return curr->sig; - } - - return 0; + return r != NULL ? r->sig : 0; } size_t tls12_get_psigalgs(SSL *s, int sent, const uint16_t **psigs) @@ -809,56 +835,77 @@ size_t tls12_get_psigalgs(SSL *s, int sent, const uint16_t **psigs) * algorithms and if so set relevant digest and signature scheme in * s. */ -int tls12_check_peer_sigalg(SSL *s, unsigned int sig, EVP_PKEY *pkey) +int tls12_check_peer_sigalg(SSL *s, uint16_t sig, EVP_PKEY *pkey) { const uint16_t *sent_sigs; const EVP_MD *md = NULL; char sigalgstr[2]; size_t sent_sigslen, i; int pkeyid = EVP_PKEY_id(pkey); - int peer_sigtype; + const SIGALG_LOOKUP *lu; + /* Should never happen */ if (pkeyid == -1) return -1; - /* Check key type is consistent with signature */ - peer_sigtype = tls_sigalg_get_sig(sig); - /* RSA keys can be used for RSA-PSS */ - if (pkeyid != peer_sigtype - && (peer_sigtype != EVP_PKEY_RSA_PSS || pkeyid != EVP_PKEY_RSA)) { + /* Only allow PSS for TLS 1.3 */ + if (SSL_IS_TLS13(s) && 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 + */ + if (lu == NULL || (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; } #ifndef OPENSSL_NO_EC if (pkeyid == EVP_PKEY_EC) { - unsigned char curve_id[2], comp_id; - /* Check compression and curve matches extensions */ - if (!tls1_set_ec_id(curve_id, &comp_id, EVP_PKEY_get0_EC_KEY(pkey))) - return 0; - if (!s->server && !tls1_check_ec_key(s, curve_id, &comp_id)) { - 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]) + 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 */ + + if (curve != lu->curve) { + SSLerr(SSL_F_TLS12_CHECK_PEER_SIGALG, SSL_R_WRONG_CURVE); return 0; - if (curve_id[1] == TLSEXT_curve_P_256) { - if (tls_sigalg_get_hash(sig) != NID_sha256) { + } + } 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; + if (!s->server && !tls1_check_ec_key(s, curve_id, &comp_id)) { + SSLerr(SSL_F_TLS12_CHECK_PEER_SIGALG, SSL_R_WRONG_CURVE); + return 0; + } + if (tls1_suiteb(s)) { + /* 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_ILLEGAL_SUITEB_DIGEST); + SSL_R_WRONG_SIGNATURE_TYPE); return 0; } - } else if (curve_id[1] == TLSEXT_curve_P_384) { - if (tls_sigalg_get_hash(sig) != NID_sha384) { + /* + * 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; } - } else - return 0; + } } - } else if (tls1_suiteb(s)) + } else if (tls1_suiteb(s)) { return 0; + } #endif /* Check signature matches a type we sent */ @@ -868,13 +915,12 @@ int tls12_check_peer_sigalg(SSL *s, unsigned int sig, EVP_PKEY *pkey) break; } /* Allow fallback to SHA1 if not strict mode */ - if (i == sent_sigslen - && (tls_sigalg_get_hash(sig) != NID_sha1 - || s->cert->cert_flags & SSL_CERT_FLAGS_CHECK_TLS_STRICT)) { + if (i == sent_sigslen && (lu->hash != NID_sha1 + || s->cert->cert_flags & SSL_CERT_FLAGS_CHECK_TLS_STRICT)) { SSLerr(SSL_F_TLS12_CHECK_PEER_SIGALG, SSL_R_WRONG_SIGNATURE_TYPE); return 0; } - md = tls12_get_hash(tls_sigalg_get_hash(sig)); + md = ssl_md(lu->hash_idx); if (md == NULL) { SSLerr(SSL_F_TLS12_CHECK_PEER_SIGALG, SSL_R_UNKNOWN_DIGEST); return 0; @@ -891,19 +937,16 @@ int tls12_check_peer_sigalg(SSL *s, unsigned int sig, EVP_PKEY *pkey) 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; - s->s3->tmp.peer_sigtype = peer_sigtype; + /* Store the sigalg the peer uses */ + s->s3->tmp.peer_sigalg = lu; return 1; } int SSL_get_peer_signature_type_nid(const SSL *s, int *pnid) { - if (s->s3->tmp.peer_sigtype == NID_undef) + if (s->s3->tmp.peer_sigalg == NULL) return 0; - *pnid = s->s3->tmp.peer_sigtype; + *pnid = s->s3->tmp.peer_sigalg->sig; return 1; } @@ -1143,7 +1186,7 @@ TICKET_RETURN tls_decrypt_ticket(SSL *s, const unsigned char *etick, 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(); @@ -1263,7 +1306,7 @@ int tls12_get_sigandhash(SSL *s, WPACKET *pkt, const EVP_PKEY *pk, { int md_id, sig_id; size_t i; - const TLS_SIGALGS *curr; + const SIGALG_LOOKUP *curr; if (md == NULL) return 0; @@ -1275,66 +1318,41 @@ int tls12_get_sigandhash(SSL *s, WPACKET *pkt, const EVP_PKEY *pk, if (SSL_IS_TLS13(s) && sig_id == EVP_PKEY_RSA) sig_id = EVP_PKEY_RSA_PSS; - for (i = 0, curr = s->cert->shared_sigalgs; i < s->cert->shared_sigalgslen; - i++, curr++) { + 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_nid == md_nid && (curr->sign_nid == sig_id - || (sig_id == EVP_PKEY_RSA && curr->sign_nid == EVP_PKEY_RSA_PSS))){ - if (!WPACKET_put_bytes_u16(pkt, curr->rsigalg)) + 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->sign_nid == EVP_PKEY_RSA_PSS; + *ispss = curr->sig == EVP_PKEY_RSA_PSS; return 1; } } 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) { @@ -1370,47 +1388,25 @@ static int tls12_get_pkey_idx(int sig_nid) return -1; } -/* Convert TLS 1.2 signature algorithm extension values into NIDs */ -static void tls1_lookup_sigalg(int *phash_nid, int *psign_nid, - int *psignhash_nid, uint16_t data) -{ - int sign_nid = NID_undef, hash_nid = NID_undef; - if (!phash_nid && !psign_nid && !psignhash_nid) - return; - if (phash_nid || psignhash_nid) { - hash_nid = tls_sigalg_get_hash(data); - if (phash_nid) - *phash_nid = hash_nid; - } - if (psign_nid || psignhash_nid) { - sign_nid = tls_sigalg_get_sig(data); - if (psign_nid) - *psign_nid = sign_nid; - } - if (psignhash_nid) { - if (sign_nid == NID_undef || hash_nid == NID_undef - || OBJ_find_sigid_by_algs(psignhash_nid, hash_nid, sign_nid) <= 0) - *psignhash_nid = NID_undef; - } -} - /* 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); } /* @@ -1477,7 +1473,7 @@ int tls12_copy_sigalgs(SSL *s, WPACKET *pkt, } /* Given preference and allowed sigalgs set shared sigalgs */ -static size_t tls12_shared_sigalgs(SSL *s, TLS_SIGALGS *shsig, +static size_t tls12_shared_sigalgs(SSL *s, const SIGALG_LOOKUP **shsig, const uint16_t *pref, size_t preflen, const uint16_t *allow, size_t allowlen) { @@ -1491,10 +1487,7 @@ static size_t tls12_shared_sigalgs(SSL *s, TLS_SIGALGS *shsig, if (*ptmp == *atmp) { nmatch++; if (shsig) { - shsig->rsigalg = *ptmp; - tls1_lookup_sigalg(&shsig->hash_nid, - &shsig->sign_nid, - &shsig->signandhash_nid, *ptmp); + *shsig = tls1_lookup_sigalg(*ptmp); shsig++; } break; @@ -1510,7 +1503,7 @@ static int tls1_set_shared_sigalgs(SSL *s) const uint16_t *pref, *allow, *conf; size_t preflen, allowlen, conflen; size_t nmatch; - TLS_SIGALGS *salgs = NULL; + const SIGALG_LOOKUP **salgs = NULL; CERT *c = s->cert; unsigned int is_suiteb = tls1_suiteb(s); @@ -1539,7 +1532,7 @@ static int tls1_set_shared_sigalgs(SSL *s) } nmatch = tls12_shared_sigalgs(s, NULL, pref, preflen, allow, allowlen); if (nmatch) { - salgs = OPENSSL_malloc(nmatch * sizeof(TLS_SIGALGS)); + salgs = OPENSSL_malloc(nmatch * sizeof(*salgs)); if (salgs == NULL) return 0; nmatch = tls12_shared_sigalgs(s, salgs, pref, preflen, allow, allowlen); @@ -1597,18 +1590,19 @@ int tls1_process_sigalgs(SSL *s) const EVP_MD **pmd = s->s3->tmp.md; uint32_t *pvalid = s->s3->tmp.valid_flags; CERT *c = s->cert; - TLS_SIGALGS *sigptr; + if (!tls1_set_shared_sigalgs(s)) return 0; - for (i = 0, sigptr = c->shared_sigalgs; - i < c->shared_sigalgslen; i++, sigptr++) { + for (i = 0; i < c->shared_sigalgslen; i++) { + const SIGALG_LOOKUP *sigptr = c->shared_sigalgs[i]; + /* Ignore PKCS1 based sig algs in TLSv1.3 */ - if (SSL_IS_TLS13(s) && sigptr->sign_nid == EVP_PKEY_RSA) + if (SSL_IS_TLS13(s) && sigptr->sig == EVP_PKEY_RSA) continue; - idx = tls12_get_pkey_idx(sigptr->sign_nid); + idx = tls12_get_pkey_idx(sigptr->sig); if (idx > 0 && pmd[idx] == NULL) { - md = tls12_get_hash(sigptr->hash_nid); + md = ssl_md(sigptr->hash_idx); pmd[idx] = md; pvalid[idx] = CERT_PKEY_EXPLICIT_SIGN; if (idx == SSL_PKEY_RSA_SIGN) { @@ -1616,7 +1610,6 @@ int tls1_process_sigalgs(SSL *s) pmd[SSL_PKEY_RSA_ENC] = md; } } - } /* * In strict mode or TLS1.3 leave unset digests as NULL to indicate we can't @@ -1665,14 +1658,22 @@ int SSL_get_sigalgs(SSL *s, int idx, if (psig == NULL || numsigalgs > INT_MAX) return 0; if (idx >= 0) { + const SIGALG_LOOKUP *lu; + if (idx >= (int)numsigalgs) return 0; psig += idx; - if (rhash) + if (rhash != NULL) *rhash = (unsigned char)((*psig >> 8) & 0xff); - if (rsig) + if (rsig != NULL) *rsig = (unsigned char)(*psig & 0xff); - tls1_lookup_sigalg(phash, psign, psignhash, *psig); + lu = tls1_lookup_sigalg(*psig); + if (psign != NULL) + *psign = lu != NULL ? lu->sig : NID_undef; + if (phash != NULL) + *phash = lu != NULL ? lu->hash : NID_undef; + if (psignhash != NULL) + *psignhash = lu != NULL ? lu->sigandhash : NID_undef; } return (int)numsigalgs; } @@ -1681,29 +1682,31 @@ int SSL_get_shared_sigalgs(SSL *s, int idx, int *psign, int *phash, int *psignhash, unsigned char *rsig, unsigned char *rhash) { - TLS_SIGALGS *shsigalgs = s->cert->shared_sigalgs; - if (!shsigalgs || idx >= (int)s->cert->shared_sigalgslen - || s->cert->shared_sigalgslen > INT_MAX) + const SIGALG_LOOKUP *shsigalgs; + if (s->cert->shared_sigalgs == NULL + || idx >= (int)s->cert->shared_sigalgslen + || s->cert->shared_sigalgslen > INT_MAX) return 0; - shsigalgs += idx; - if (phash) - *phash = shsigalgs->hash_nid; - if (psign) - *psign = shsigalgs->sign_nid; - if (psignhash) - *psignhash = shsigalgs->signandhash_nid; - if (rsig) - *rsig = (unsigned char)(shsigalgs->rsigalg & 0xff); - if (rhash) - *rhash = (unsigned char)((shsigalgs->rsigalg >> 8) & 0xff); + shsigalgs = s->cert->shared_sigalgs[idx]; + if (phash != NULL) + *phash = shsigalgs->hash; + if (psign != NULL) + *psign = shsigalgs->sig; + if (psignhash != NULL) + *psignhash = shsigalgs->sigandhash; + if (rsig != NULL) + *rsig = (unsigned char)(shsigalgs->sigalg & 0xff); + if (rhash != NULL) + *rhash = (unsigned char)((shsigalgs->sigalg >> 8) & 0xff); return (int)s->cert->shared_sigalgslen; } -#define MAX_SIGALGLEN (TLSEXT_hash_num * TLSEXT_signature_num * 2) +/* Maximum possible number of unique entries in sigalgs array */ +#define TLS_MAX_SIGALGCNT (OSSL_NELEM(sigalg_lookup_tbl) * 2) typedef struct { size_t sigalgcnt; - int sigalgs[MAX_SIGALGLEN]; + int sigalgs[TLS_MAX_SIGALGCNT]; } sig_cb_st; static void get_sigorhash(int *psig, int *phash, const char *str) @@ -1722,31 +1725,44 @@ static void get_sigorhash(int *psig, int *phash, const char *str) *phash = OBJ_ln2nid(str); } } +/* Maximum length of a signature algorithm string component */ +#define TLS_MAX_SIGSTRING_LEN 40 static int sig_cb(const char *elem, int len, void *arg) { sig_cb_st *sarg = arg; size_t i; - char etmp[20], *p; + char etmp[TLS_MAX_SIGSTRING_LEN], *p; int sig_alg = NID_undef, hash_alg = NID_undef; if (elem == NULL) return 0; - if (sarg->sigalgcnt == MAX_SIGALGLEN) + if (sarg->sigalgcnt == TLS_MAX_SIGALGCNT) return 0; if (len > (int)(sizeof(etmp) - 1)) return 0; memcpy(etmp, elem, len); etmp[len] = 0; p = strchr(etmp, '+'); - if (!p) - return 0; - *p = 0; - p++; - if (!*p) - return 0; - - get_sigorhash(&sig_alg, &hash_alg, etmp); - get_sigorhash(&sig_alg, &hash_alg, p); + /* See if we have a match for TLS 1.3 names */ + if (p == NULL) { + const SIGALG_LOOKUP *s; + + for (i = 0, s = sigalg_lookup_tbl; i < OSSL_NELEM(sigalg_lookup_tbl); + i++, s++) { + if (s->name != NULL && strcmp(etmp, s->name) == 0) { + sig_alg = s->sig; + hash_alg = s->hash; + break; + } + } + } else { + *p = 0; + p++; + if (*p == 0) + return 0; + get_sigorhash(&sig_alg, &hash_alg, etmp); + get_sigorhash(&sig_alg, &hash_alg, p); + } if (sig_alg == NID_undef || hash_alg == NID_undef) return 0; @@ -1830,7 +1846,7 @@ static int tls1_check_sig_alg(CERT *c, X509 *x, int default_nid) 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].signandhash_nid) + if (sig_nid == c->shared_sigalgs[i]->sigandhash) return 1; return 0; } @@ -1972,8 +1988,9 @@ int tls1_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain, 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) {