X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=ssl%2Ft1_lib.c;h=e310071c23ac89e3944a32c600fa4a23c1a03e47;hp=0b90048637f0f5c021a0aef3323d9f46766da4f8;hb=4a419f60188405d6ecc450526b6aa926638d1db2;hpb=f1adb0068fb04abbadf3ebbb105146bc75094197 diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c index 0b90048637..e310071c23 100644 --- a/ssl/t1_lib.c +++ b/ssl/t1_lib.c @@ -730,16 +730,16 @@ static const SIGALG_LOOKUP sigalg_lookup_tbl[] = { 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_sha256, SSL_MD_SHA256_IDX, EVP_PKEY_RSA, SSL_PKEY_RSA, 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_sha384, SSL_MD_SHA384_IDX, EVP_PKEY_RSA, SSL_PKEY_RSA, 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_sha512, SSL_MD_SHA512_IDX, EVP_PKEY_RSA, SSL_PKEY_RSA, 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_sha1, SSL_MD_SHA1_IDX, EVP_PKEY_RSA, SSL_PKEY_RSA, NID_sha1WithRSAEncryption, NID_undef}, #ifndef OPENSSL_NO_DSA {NULL, TLSEXT_SIGALG_dsa_sha256, @@ -1022,10 +1022,9 @@ void ssl_set_default_md(SSL *s) #endif #ifndef OPENSSL_NO_RSA if (SSL_USE_SIGALGS(s)) - pmd[SSL_PKEY_RSA_SIGN] = ssl_md(SSL_MD_SHA1_IDX); + pmd[SSL_PKEY_RSA] = ssl_md(SSL_MD_SHA1_IDX); else - pmd[SSL_PKEY_RSA_SIGN] = ssl_md(SSL_MD_MD5_SHA1_IDX); - pmd[SSL_PKEY_RSA_ENC] = pmd[SSL_PKEY_RSA_SIGN]; + 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); @@ -1186,7 +1185,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(); @@ -1253,8 +1252,8 @@ TICKET_RETURN tls_decrypt_ticket(SSL *s, const unsigned char *etick, } /* Attempt to decrypt session data */ /* Move p after IV to start of encrypted ticket, update length */ - p = etick + 16 + EVP_CIPHER_CTX_iv_length(ctx); - eticklen -= 16 + EVP_CIPHER_CTX_iv_length(ctx); + p = etick + TLSEXT_KEYNAME_LENGTH + EVP_CIPHER_CTX_iv_length(ctx); + eticklen -= TLSEXT_KEYNAME_LENGTH + EVP_CIPHER_CTX_iv_length(ctx); sdec = OPENSSL_malloc(eticklen); if (sdec == NULL || EVP_DecryptUpdate(ctx, sdec, &slen, p, (int)eticklen) <= 0) { @@ -1358,13 +1357,13 @@ static int tls12_get_pkey_idx(int sig_nid) switch (sig_nid) { #ifndef OPENSSL_NO_RSA case EVP_PKEY_RSA: - return SSL_PKEY_RSA_SIGN; + return SSL_PKEY_RSA; /* * For now return RSA key for PSS. When we support PSS only keys * this will need to be updated. */ case EVP_PKEY_RSA_PSS: - return SSL_PKEY_RSA_SIGN; + return SSL_PKEY_RSA; #endif #ifndef OPENSSL_NO_DSA case EVP_PKEY_DSA: @@ -1601,14 +1600,10 @@ int tls1_process_sigalgs(SSL *s) if (SSL_IS_TLS13(s) && sigptr->sig == EVP_PKEY_RSA) continue; idx = tls12_get_pkey_idx(sigptr->sig); - if (idx > 0 && pmd[idx] == NULL) { + if (idx >= 0 && pmd[idx] == NULL) { md = ssl_md(sigptr->hash_idx); pmd[idx] = md; pvalid[idx] = CERT_PKEY_EXPLICIT_SIGN; - if (idx == SSL_PKEY_RSA_SIGN) { - pvalid[SSL_PKEY_RSA_ENC] = CERT_PKEY_EXPLICIT_SIGN; - pmd[SSL_PKEY_RSA_ENC] = md; - } } } /* @@ -1626,9 +1621,8 @@ int tls1_process_sigalgs(SSL *s) pmd[SSL_PKEY_DSA_SIGN] = EVP_sha1(); #endif #ifndef OPENSSL_NO_RSA - if (pmd[SSL_PKEY_RSA_SIGN] == NULL) { - pmd[SSL_PKEY_RSA_SIGN] = EVP_sha1(); - pmd[SSL_PKEY_RSA_ENC] = EVP_sha1(); + if (pmd[SSL_PKEY_RSA] == NULL) { + pmd[SSL_PKEY_RSA] = EVP_sha1(); } #endif #ifndef OPENSSL_NO_EC @@ -1684,6 +1678,7 @@ int SSL_get_shared_sigalgs(SSL *s, int idx, { const SIGALG_LOOKUP *shsigalgs; if (s->cert->shared_sigalgs == NULL + || idx < 0 || idx >= (int)s->cert->shared_sigalgslen || s->cert->shared_sigalgslen > INT_MAX) return 0; @@ -1944,8 +1939,7 @@ int tls1_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain, /* If no sigalgs extension use defaults from RFC5246 */ else { switch (idx) { - case SSL_PKEY_RSA_ENC: - case SSL_PKEY_RSA_SIGN: + case SSL_PKEY_RSA: rsign = EVP_PKEY_RSA; default_nid = NID_sha1WithRSAEncryption; break; @@ -2132,8 +2126,7 @@ int tls1_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain, /* Set validity of certificates in an SSL structure */ void tls1_set_cert_validity(SSL *s) { - tls1_check_chain(s, NULL, NULL, NULL, SSL_PKEY_RSA_ENC); - tls1_check_chain(s, NULL, NULL, NULL, SSL_PKEY_RSA_SIGN); + tls1_check_chain(s, NULL, NULL, NULL, SSL_PKEY_RSA); tls1_check_chain(s, NULL, NULL, NULL, SSL_PKEY_DSA_SIGN); tls1_check_chain(s, NULL, NULL, NULL, SSL_PKEY_ECC); tls1_check_chain(s, NULL, NULL, NULL, SSL_PKEY_GOST01); @@ -2270,3 +2263,62 @@ int ssl_security_cert_chain(SSL *s, STACK_OF(X509) *sk, X509 *x, int vfy) } return 1; } + +/* + * Choose an appropriate signature algorithm based on available certificates + * Set current certificate and digest to match chosen algorithm. + */ +int tls_choose_sigalg(SSL *s, int *al) +{ + if (SSL_IS_TLS13(s)) { + size_t i; +#ifndef OPENSSL_NO_EC + int curve = -1; +#endif + + /* Look for a certificate matching shared sigaglgs */ + for (i = 0; i < s->cert->shared_sigalgslen; i++) { + const SIGALG_LOOKUP *lu = s->cert->shared_sigalgs[i]; + int idx; + const EVP_MD *md; + CERT_PKEY *c; + + /* Skip RSA if not PSS */ + if (lu->sig == EVP_PKEY_RSA) + continue; + md = ssl_md(lu->hash_idx); + if (md == NULL) + continue; + idx = lu->sig_idx; + c = &s->cert->pkeys[idx]; + if (c->x509 == NULL || c->privatekey == NULL) + continue; + if (lu->sig == EVP_PKEY_EC) { +#ifndef OPENSSL_NO_EC + if (curve == -1) { + EC_KEY *ec = EVP_PKEY_get0_EC_KEY(c->privatekey); + + curve = EC_GROUP_get_curve_name(EC_KEY_get0_group(ec)); + } + if (curve != lu->curve) + continue; +#else + continue; +#endif + } + s->s3->tmp.sigalg = lu; + s->s3->tmp.cert_idx = idx; + s->s3->tmp.md[idx] = md; + s->cert->key = s->cert->pkeys + idx; + return 1; + } + *al = SSL_AD_HANDSHAKE_FAILURE; + SSLerr(SSL_F_TLS_CHOOSE_SIGALG, SSL_R_NO_SUITABLE_SIGNATURE_ALGORITHM); + return 0; + } + /* + * FIXME: could handle previous TLS versions in an appropriate way + * and tidy up certificate and signature algorithm handling. + */ + return 1; +}