X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=ssl%2Ft1_lib.c;h=402047a237b1f9f2b8e4f7f01828374a2f1f97c7;hp=7af9c7e3ddb1c93f5efd9a301bd5810ea9800b37;hb=124037fdc0571b5bd9022412348e9979a1726a31;hpb=b6eb9827a6866981c08cc9613ca8b4a648894fb1 diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c index 7af9c7e3dd..402047a237 100644 --- a/ssl/t1_lib.c +++ b/ssl/t1_lib.c @@ -123,13 +123,11 @@ const char tls1_version_str[] = "TLSv1" OPENSSL_VERSION_PTEXT; -#ifndef OPENSSL_NO_TLSEXT static int tls_decrypt_ticket(SSL *s, const unsigned char *tick, int ticklen, const unsigned char *sess_id, int sesslen, SSL_SESSION **psess); static int ssl_check_clienthello_tlsext_early(SSL *s); int ssl_check_serverhello_tlsext(SSL *s); -#endif SSL3_ENC_METHOD const TLSv1_enc_data = { tls1_enc, @@ -208,9 +206,7 @@ int tls1_new(SSL *s) void tls1_free(SSL *s) { -#ifndef OPENSSL_NO_TLSEXT OPENSSL_free(s->tlsext_session_ticket); -#endif /* OPENSSL_NO_TLSEXT */ ssl3_free(s); } @@ -268,37 +264,65 @@ static const unsigned char ecformats_default[] = { TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2 }; -static const unsigned char eccurves_default[] = { - 0, 14, /* sect571r1 (14) */ - 0, 13, /* sect571k1 (13) */ +/* The client's default curves / the server's 'auto' curves. */ +static const unsigned char eccurves_auto[] = { + /* Prefer P-256 which has the fastest and most secure implementations. */ + 0, 23, /* secp256r1 (23) */ + /* Other >= 256-bit prime curves. */ 0, 25, /* secp521r1 (25) */ 0, 28, /* brainpool512r1 (28) */ - 0, 11, /* sect409k1 (11) */ - 0, 12, /* sect409r1 (12) */ 0, 27, /* brainpoolP384r1 (27) */ 0, 24, /* secp384r1 (24) */ + 0, 26, /* brainpoolP256r1 (26) */ + 0, 22, /* secp256k1 (22) */ + /* >= 256-bit binary curves. */ + 0, 14, /* sect571r1 (14) */ + 0, 13, /* sect571k1 (13) */ + 0, 11, /* sect409k1 (11) */ + 0, 12, /* sect409r1 (12) */ 0, 9, /* sect283k1 (9) */ 0, 10, /* sect283r1 (10) */ +}; + +static const unsigned char eccurves_all[] = { + /* Prefer P-256 which has the fastest and most secure implementations. */ + 0, 23, /* secp256r1 (23) */ + /* Other >= 256-bit prime curves. */ + 0, 25, /* secp521r1 (25) */ + 0, 28, /* brainpool512r1 (28) */ + 0, 27, /* brainpoolP384r1 (27) */ + 0, 24, /* secp384r1 (24) */ 0, 26, /* brainpoolP256r1 (26) */ 0, 22, /* secp256k1 (22) */ - 0, 23, /* secp256r1 (23) */ + /* >= 256-bit binary curves. */ + 0, 14, /* sect571r1 (14) */ + 0, 13, /* sect571k1 (13) */ + 0, 11, /* sect409k1 (11) */ + 0, 12, /* sect409r1 (12) */ + 0, 9, /* sect283k1 (9) */ + 0, 10, /* sect283r1 (10) */ + /* + * Remaining curves disabled by default but still permitted if set + * via an explicit callback or parameters. + */ + 0, 20, /* secp224k1 (20) */ + 0, 21, /* secp224r1 (21) */ + 0, 18, /* secp192k1 (18) */ + 0, 19, /* secp192r1 (19) */ + 0, 15, /* secp160k1 (15) */ + 0, 16, /* secp160r1 (16) */ + 0, 17, /* secp160r2 (17) */ 0, 8, /* sect239k1 (8) */ 0, 6, /* sect233k1 (6) */ 0, 7, /* sect233r1 (7) */ - 0, 20, /* secp224k1 (20) */ - 0, 21, /* secp224r1 (21) */ 0, 4, /* sect193r1 (4) */ 0, 5, /* sect193r2 (5) */ - 0, 18, /* secp192k1 (18) */ - 0, 19, /* secp192r1 (19) */ 0, 1, /* sect163k1 (1) */ 0, 2, /* sect163r1 (2) */ 0, 3, /* sect163r2 (3) */ - 0, 15, /* secp160k1 (15) */ - 0, 16, /* secp160r1 (16) */ - 0, 17, /* secp160r2 (17) */ }; + static const unsigned char suiteb_curves[] = { 0, TLSEXT_curve_P_256, 0, TLSEXT_curve_P_384 @@ -419,8 +443,13 @@ static int tls1_get_curvelist(SSL *s, int sess, pcurveslen = s->tlsext_ellipticcurvelist_length; } if (!*pcurves) { - *pcurves = eccurves_default; - pcurveslen = sizeof(eccurves_default); + if (!s->server || (s->cert && s->cert->ecdh_tmp_auto)) { + *pcurves = eccurves_auto; + pcurveslen = sizeof(eccurves_auto); + } else { + *pcurves = eccurves_all; + pcurveslen = sizeof(eccurves_all); + } } } @@ -526,6 +555,20 @@ int tls1_shared_curve(SSL *s, int nmatch) (s, !(s->options & SSL_OP_CIPHER_SERVER_PREFERENCE), &pref, &num_pref)) return nmatch == -1 ? 0 : NID_undef; + + /* + * If the client didn't send the elliptic_curves extension all of them + * are allowed. + */ + if (num_supp == 0 && (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE) != 0) { + supp = eccurves_all; + num_supp = sizeof(eccurves_all) / 2; + } else if (num_pref == 0 && + (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE) == 0) { + pref = eccurves_all; + num_pref = sizeof(eccurves_all) / 2; + } + k = 0; for (i = 0; i < num_pref; i++, pref += 2) { const unsigned char *tsupp = supp; @@ -795,9 +838,9 @@ static int tls1_check_cert_param(SSL *s, X509 *x, int set_ee_md) return 0; if (set_ee_md == 2) { if (check_md == NID_ecdsa_with_SHA256) - c->pkeys[SSL_PKEY_ECC].digest = EVP_sha256(); + s->s3->tmp.md[SSL_PKEY_ECC] = EVP_sha256(); else - c->pkeys[SSL_PKEY_ECC].digest = EVP_sha384(); + s->s3->tmp.md[SSL_PKEY_ECC] = EVP_sha384(); } } return rv; @@ -879,32 +922,30 @@ static int tls1_check_cert_param(SSL *s, X509 *x, int set_ee_md) #endif /* OPENSSL_NO_EC */ -#ifndef OPENSSL_NO_TLSEXT - /* * List of supported signature algorithms and hashes. Should make this * customisable at some point, for now include everything we support. */ -# ifdef OPENSSL_NO_RSA -# define tlsext_sigalg_rsa(md) /* */ -# else -# define tlsext_sigalg_rsa(md) md, TLSEXT_signature_rsa, -# endif +#ifdef OPENSSL_NO_RSA +# define tlsext_sigalg_rsa(md) /* */ +#else +# define tlsext_sigalg_rsa(md) md, TLSEXT_signature_rsa, +#endif -# ifdef OPENSSL_NO_DSA -# define tlsext_sigalg_dsa(md) /* */ -# else -# define tlsext_sigalg_dsa(md) md, TLSEXT_signature_dsa, -# endif +#ifdef OPENSSL_NO_DSA +# define tlsext_sigalg_dsa(md) /* */ +#else +# define tlsext_sigalg_dsa(md) md, TLSEXT_signature_dsa, +#endif -# ifdef OPENSSL_NO_EC -# define tlsext_sigalg_ecdsa(md) /* */ -# else -# define tlsext_sigalg_ecdsa(md) md, TLSEXT_signature_ecdsa, -# endif +#ifdef OPENSSL_NO_EC +# define tlsext_sigalg_ecdsa(md) /* */ +#else +# define tlsext_sigalg_ecdsa(md) md, TLSEXT_signature_ecdsa, +#endif -# define tlsext_sigalg(md) \ +#define tlsext_sigalg(md) \ tlsext_sigalg_rsa(md) \ tlsext_sigalg_dsa(md) \ tlsext_sigalg_ecdsa(md) @@ -917,19 +958,19 @@ static const unsigned char tls12_sigalgs[] = { tlsext_sigalg(TLSEXT_hash_sha1) }; -# ifndef OPENSSL_NO_EC +#ifndef OPENSSL_NO_EC static const unsigned char suiteb_sigalgs[] = { tlsext_sigalg_ecdsa(TLSEXT_hash_sha256) tlsext_sigalg_ecdsa(TLSEXT_hash_sha384) }; -# endif +#endif size_t tls12_get_psigalgs(SSL *s, const unsigned char **psigs) { /* * If Suite B mode use Suite B sigalgs only, ignore any other * preferences. */ -# ifndef OPENSSL_NO_EC +#ifndef OPENSSL_NO_EC switch (tls1_suiteb(s)) { case SSL_CERT_FLAG_SUITEB_128_LOS: *psigs = suiteb_sigalgs; @@ -943,7 +984,7 @@ size_t tls12_get_psigalgs(SSL *s, const unsigned char **psigs) *psigs = suiteb_sigalgs + 2; return 2; } -# endif +#endif /* If server use client authentication sigalgs if not NULL */ if (s->server && s->cert->client_sigalgs) { *psigs = s->cert->client_sigalgs; @@ -975,7 +1016,7 @@ int tls12_check_peer_sigalg(const EVP_MD **pmd, SSL *s, SSLerr(SSL_F_TLS12_CHECK_PEER_SIGALG, SSL_R_WRONG_SIGNATURE_TYPE); return 0; } -# ifndef OPENSSL_NO_EC +#ifndef OPENSSL_NO_EC if (pkey->type == EVP_PKEY_EC) { unsigned char curve_id[2], comp_id; /* Check compression and curve matches extensions */ @@ -1006,7 +1047,7 @@ int tls12_check_peer_sigalg(const EVP_MD **pmd, SSL *s, } } else if (tls1_suiteb(s)) return 0; -# endif +#endif /* Check signature matches a type we sent */ sent_sigslen = tls12_get_psigalgs(s, &sent_sigs); @@ -1036,8 +1077,7 @@ int tls12_check_peer_sigalg(const EVP_MD **pmd, SSL *s, /* * Store the digest used so applications can retrieve it if they wish. */ - if (s->session && s->session->sess_cert) - s->session->sess_cert->peer_key->digest = *pmd; + s->s3->tmp.peer_md = *pmd; return 1; } @@ -1049,52 +1089,44 @@ int tls12_check_peer_sigalg(const EVP_MD **pmd, SSL *s, */ void ssl_set_client_disabled(SSL *s) { - CERT *c = s->cert; - c->mask_a = 0; - c->mask_k = 0; + s->s3->tmp.mask_a = 0; + s->s3->tmp.mask_k = 0; /* Don't allow TLS 1.2 only ciphers if we don't suppport them */ if (!SSL_CLIENT_USE_TLS1_2_CIPHERS(s)) - c->mask_ssl = SSL_TLSV1_2; + s->s3->tmp.mask_ssl = SSL_TLSV1_2; else - c->mask_ssl = 0; - ssl_set_sig_mask(&c->mask_a, s, SSL_SECOP_SIGALG_MASK); + s->s3->tmp.mask_ssl = 0; + ssl_set_sig_mask(&s->s3->tmp.mask_a, s, SSL_SECOP_SIGALG_MASK); /* * Disable static DH if we don't include any appropriate signature * algorithms. */ - if (c->mask_a & SSL_aRSA) - c->mask_k |= SSL_kDHr | SSL_kECDHr; - if (c->mask_a & SSL_aDSS) - c->mask_k |= SSL_kDHd; - if (c->mask_a & SSL_aECDSA) - c->mask_k |= SSL_kECDHe; -# ifndef OPENSSL_NO_KRB5 - if (!kssl_tgt_is_available(s->kssl_ctx)) { - c->mask_a |= SSL_aKRB5; - c->mask_k |= SSL_kKRB5; - } -# endif + if (s->s3->tmp.mask_a & SSL_aRSA) + s->s3->tmp.mask_k |= SSL_kDHr | SSL_kECDHr; + if (s->s3->tmp.mask_a & SSL_aDSS) + s->s3->tmp.mask_k |= SSL_kDHd; + if (s->s3->tmp.mask_a & SSL_aECDSA) + s->s3->tmp.mask_k |= SSL_kECDHe; # ifndef OPENSSL_NO_PSK /* with PSK there must be client callback set */ if (!s->psk_client_callback) { - c->mask_a |= SSL_aPSK; - c->mask_k |= SSL_kPSK; + s->s3->tmp.mask_a |= SSL_aPSK; + s->s3->tmp.mask_k |= SSL_kPSK; } -# endif /* OPENSSL_NO_PSK */ -# ifndef OPENSSL_NO_SRP +#endif /* OPENSSL_NO_PSK */ +#ifndef OPENSSL_NO_SRP if (!(s->srp_ctx.srp_Mask & SSL_kSRP)) { - c->mask_a |= SSL_aSRP; - c->mask_k |= SSL_kSRP; + s->s3->tmp.mask_a |= SSL_aSRP; + s->s3->tmp.mask_k |= SSL_kSRP; } -# endif - c->valid = 1; +#endif } int ssl_cipher_disabled(SSL *s, const SSL_CIPHER *c, int op) { - CERT *ct = s->cert; - if (c->algorithm_ssl & ct->mask_ssl || c->algorithm_mkey & ct->mask_k - || c->algorithm_auth & ct->mask_a) + if (c->algorithm_ssl & s->s3->tmp.mask_ssl + || c->algorithm_mkey & s->s3->tmp.mask_k + || c->algorithm_auth & s->s3->tmp.mask_a) return 1; return !ssl_security(s, op, c->strength_bits, 0, (void *)c); } @@ -1112,7 +1144,7 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf, int extdatalen = 0; unsigned char *orig = buf; unsigned char *ret = buf; -# ifndef OPENSSL_NO_EC +#ifndef OPENSSL_NO_EC /* See if we support any ECC ciphersuites */ int using_ecc = 0; if (s->version >= TLS1_VERSION || SSL_IS_DTLS(s)) { @@ -1132,7 +1164,7 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf, } } } -# endif +#endif ret += 2; @@ -1197,7 +1229,7 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf, memcpy(ret, s->tlsext_hostname, size_str); ret += size_str; } -# ifndef OPENSSL_NO_SRP +#ifndef OPENSSL_NO_SRP /* Add SRP username if there is one */ if (s->srp_ctx.login != NULL) { /* Add TLS extension SRP username to the * Client Hello message */ @@ -1224,9 +1256,9 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf, memcpy(ret, s->srp_ctx.login, login_len); ret += login_len; } -# endif +#endif -# ifndef OPENSSL_NO_EC +#ifndef OPENSSL_NO_EC if (using_ecc) { /* * Add TLS extension ECPointFormats to the ClientHello message @@ -1287,7 +1319,7 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf, s2n(curves_list_len, ret); ret += curves_list_len; } -# endif /* OPENSSL_NO_EC */ +#endif /* OPENSSL_NO_EC */ if (tls_use_ticket(s)) { int ticklen; @@ -1383,7 +1415,7 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf, if (extlen > 0) i2d_X509_EXTENSIONS(s->tlsext_ocsp_exts, &ret); } -# ifndef OPENSSL_NO_HEARTBEATS +#ifndef OPENSSL_NO_HEARTBEATS /* Add Heartbeat extension */ if ((limit - ret - 4 - 1) < 0) return NULL; @@ -1398,9 +1430,9 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf, *(ret++) = SSL_TLSEXT_HB_DONT_SEND_REQUESTS; else *(ret++) = SSL_TLSEXT_HB_ENABLED; -# endif +#endif -# ifndef OPENSSL_NO_NEXTPROTONEG +#ifndef OPENSSL_NO_NEXTPROTONEG if (s->ctx->next_proto_select_cb && !s->s3->tmp.finish_md_len) { /* * The client advertises an emtpy extension to indicate its support @@ -1411,7 +1443,7 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf, s2n(TLSEXT_TYPE_next_proto_neg, ret); s2n(0, ret); } -# endif +#endif if (s->alpn_client_proto_list && !s->s3->tmp.finish_md_len) { if ((size_t)(limit - ret) < 6 + s->alpn_client_proto_list_len) @@ -1422,7 +1454,7 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf, memcpy(ret, s->alpn_client_proto_list, s->alpn_client_proto_list_len); ret += s->alpn_client_proto_list_len; } -# ifndef OPENSSL_NO_SRTP +#ifndef OPENSSL_NO_SRTP if (SSL_IS_DTLS(s) && SSL_get_srtp_profiles(s)) { int el; @@ -1444,15 +1476,15 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf, } ret += el; } -# endif +#endif custom_ext_init(&s->cert->cli_ext); /* Add custom TLS Extensions to ClientHello */ if (!custom_ext_add(s, 0, &ret, limit, al)) return NULL; -# ifdef TLSEXT_TYPE_encrypt_then_mac +#ifdef TLSEXT_TYPE_encrypt_then_mac s2n(TLSEXT_TYPE_encrypt_then_mac, ret); s2n(0, ret); -# endif +#endif s2n(TLSEXT_TYPE_extended_master_secret, ret); s2n(0, ret); @@ -1464,13 +1496,7 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf, */ if (s->options & SSL_OP_TLSEXT_PADDING) { int hlen = ret - (unsigned char *)s->init_buf->data; - /* - * The code in s23_clnt.c to build ClientHello messages includes the - * 5-byte record header in the buffer, while the code in s3_clnt.c - * does not. - */ - if (s->state == SSL23_ST_CW_CLNT_HELLO_A) - hlen -= 5; + if (hlen > 0xff && hlen < 0x200) { hlen = 0x200 - hlen; if (hlen >= 4) @@ -1500,16 +1526,16 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf, int extdatalen = 0; unsigned char *orig = buf; unsigned char *ret = buf; -# ifndef OPENSSL_NO_NEXTPROTONEG +#ifndef OPENSSL_NO_NEXTPROTONEG int next_proto_neg_seen; -# endif -# ifndef OPENSSL_NO_EC +#endif +#ifndef OPENSSL_NO_EC unsigned long alg_k = s->s3->tmp.new_cipher->algorithm_mkey; unsigned long alg_a = s->s3->tmp.new_cipher->algorithm_auth; int using_ecc = (alg_k & (SSL_kECDHE | SSL_kECDHr | SSL_kECDHe)) || (alg_a & SSL_aECDSA); using_ecc = using_ecc && (s->session->tlsext_ecpointformatlist != NULL); -# endif +#endif ret += 2; if (ret >= limit) @@ -1549,7 +1575,7 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf, s2n(TLSEXT_TYPE_server_name, ret); s2n(0, ret); } -# ifndef OPENSSL_NO_EC +#ifndef OPENSSL_NO_EC if (using_ecc) { const unsigned char *plist; size_t plistlen; @@ -1580,7 +1606,7 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf, * Currently the server should not respond with a SupportedCurves * extension */ -# endif /* OPENSSL_NO_EC */ +#endif /* OPENSSL_NO_EC */ if (s->tlsext_ticket_expected && tls_use_ticket(s)) { if ((long)(limit - ret - 4) < 0) @@ -1596,7 +1622,7 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf, s2n(0, ret); } -# ifndef OPENSSL_NO_SRTP +#ifndef OPENSSL_NO_SRTP if (SSL_IS_DTLS(s) && s->srtp_profile) { int el; @@ -1617,7 +1643,7 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf, } ret += el; } -# endif +#endif if (((s->s3->tmp.new_cipher->id & 0xFFFF) == 0x80 || (s->s3->tmp.new_cipher->id & 0xFFFF) == 0x81) @@ -1636,7 +1662,7 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf, ret += 36; } -# ifndef OPENSSL_NO_HEARTBEATS +#ifndef OPENSSL_NO_HEARTBEATS /* Add Heartbeat extension if we've received one */ if (s->tlsext_heartbeat & SSL_TLSEXT_HB_ENABLED) { if ((limit - ret - 4 - 1) < 0) @@ -1654,9 +1680,9 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf, *(ret++) = SSL_TLSEXT_HB_ENABLED; } -# endif +#endif -# ifndef OPENSSL_NO_NEXTPROTONEG +#ifndef OPENSSL_NO_NEXTPROTONEG next_proto_neg_seen = s->s3->next_proto_neg_seen; s->s3->next_proto_neg_seen = 0; if (next_proto_neg_seen && s->ctx->next_protos_advertised_cb) { @@ -1677,10 +1703,10 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf, s->s3->next_proto_neg_seen = 1; } } -# endif +#endif if (!custom_ext_add(s, 1, &ret, limit, al)) return NULL; -# ifdef TLSEXT_TYPE_encrypt_then_mac +#ifdef TLSEXT_TYPE_encrypt_then_mac if (s->s3->flags & TLS1_FLAGS_ENCRYPT_THEN_MAC) { /* * Don't use encrypt_then_mac if AEAD or RC4 might want to disable @@ -1694,7 +1720,7 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf, s2n(0, ret); } } -# endif +#endif if (!s->hit && s->session->flags & SSL_SESS_FLAG_EXTMS) { s2n(TLSEXT_TYPE_extended_master_secret, ret); s2n(0, ret); @@ -1790,7 +1816,7 @@ static int tls1_alpn_handle_client_hello(SSL *s, const unsigned char *data, return -1; } -# ifndef OPENSSL_NO_EC +#ifndef OPENSSL_NO_EC /*- * ssl_check_for_safari attempts to fingerprint Safari using OS X * SecureTransport using the TLS extension block in |d|, of length |n|. @@ -1871,7 +1897,7 @@ static void ssl_check_for_safari(SSL *s, const unsigned char *data, s->s3->is_probably_safari = 1; } -# endif /* !OPENSSL_NO_EC */ +#endif /* !OPENSSL_NO_EC */ static int ssl_scan_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, int n, int *al) @@ -1884,49 +1910,53 @@ static int ssl_scan_clienthello_tlsext(SSL *s, unsigned char **p, s->servername_done = 0; s->tlsext_status_type = -1; -# ifndef OPENSSL_NO_NEXTPROTONEG +#ifndef OPENSSL_NO_NEXTPROTONEG s->s3->next_proto_neg_seen = 0; -# endif +#endif OPENSSL_free(s->s3->alpn_selected); s->s3->alpn_selected = NULL; -# ifndef OPENSSL_NO_HEARTBEATS +#ifndef OPENSSL_NO_HEARTBEATS s->tlsext_heartbeat &= ~(SSL_TLSEXT_HB_ENABLED | SSL_TLSEXT_HB_DONT_SEND_REQUESTS); -# endif +#endif -# ifndef OPENSSL_NO_EC +#ifndef OPENSSL_NO_EC if (s->options & SSL_OP_SAFARI_ECDHE_ECDSA_BUG) ssl_check_for_safari(s, data, d, n); -# endif /* !OPENSSL_NO_EC */ +#endif /* !OPENSSL_NO_EC */ /* Clear any signature algorithms extension received */ - OPENSSL_free(s->cert->peer_sigalgs); - s->cert->peer_sigalgs = NULL; -# ifdef TLSEXT_TYPE_encrypt_then_mac + OPENSSL_free(s->s3->tmp.peer_sigalgs); + s->s3->tmp.peer_sigalgs = NULL; +#ifdef TLSEXT_TYPE_encrypt_then_mac s->s3->flags &= ~TLS1_FLAGS_ENCRYPT_THEN_MAC; -# endif +#endif -# ifndef OPENSSL_NO_SRP +#ifndef OPENSSL_NO_SRP OPENSSL_free(s->srp_ctx.login); s->srp_ctx.login = NULL; -# endif +#endif s->srtp_profile = NULL; - if (data >= (d + n - 2)) + if (data == d + n) goto ri_check; + + if (data > (d + n - 2)) + goto err; + n2s(data, len); if (data > (d + n - len)) - goto ri_check; + goto err; while (data <= (d + n - 4)) { n2s(data, type); n2s(data, size); if (data + size > (d + n)) - goto ri_check; + goto err; if (s->tlsext_debug_cb) s->tlsext_debug_cb(s, 0, type, data, size, s->tlsext_debug_arg); if (type == TLSEXT_TYPE_renegotiate) { @@ -1965,16 +1995,12 @@ static int ssl_scan_clienthello_tlsext(SSL *s, unsigned char **p, int servname_type; int dsize; - if (size < 2) { - *al = SSL_AD_DECODE_ERROR; - return 0; - } + if (size < 2) + goto err; n2s(data, dsize); size -= 2; - if (dsize > size) { - *al = SSL_AD_DECODE_ERROR; - return 0; - } + if (dsize > size) + goto err; sdata = data; while (dsize > 3) { @@ -1982,18 +2008,16 @@ static int ssl_scan_clienthello_tlsext(SSL *s, unsigned char **p, n2s(sdata, len); dsize -= 3; - if (len > dsize) { - *al = SSL_AD_DECODE_ERROR; - return 0; - } + if (len > dsize) + goto err; + if (s->servername_done == 0) switch (servname_type) { case TLSEXT_NAMETYPE_host_name: if (!s->hit) { - if (s->session->tlsext_hostname) { - *al = SSL_AD_DECODE_ERROR; - return 0; - } + if (s->session->tlsext_hostname) + goto err; + if (len > TLSEXT_MAXLEN_host_name) { *al = TLS1_AD_UNRECOGNIZED_NAME; return 0; @@ -2027,44 +2051,34 @@ static int ssl_scan_clienthello_tlsext(SSL *s, unsigned char **p, dsize -= len; } - if (dsize != 0) { - *al = SSL_AD_DECODE_ERROR; - return 0; - } + if (dsize != 0) + goto err; } -# ifndef OPENSSL_NO_SRP +#ifndef OPENSSL_NO_SRP else if (type == TLSEXT_TYPE_srp) { - if (size <= 0 || ((len = data[0])) != (size - 1)) { - *al = SSL_AD_DECODE_ERROR; - return 0; - } - if (s->srp_ctx.login != NULL) { - *al = SSL_AD_DECODE_ERROR; - return 0; - } + if (size == 0 || ((len = data[0])) != (size - 1)) + goto err; + if (s->srp_ctx.login != NULL) + goto err; if ((s->srp_ctx.login = OPENSSL_malloc(len + 1)) == NULL) return -1; memcpy(s->srp_ctx.login, &data[1], len); s->srp_ctx.login[len] = '\0'; - if (strlen(s->srp_ctx.login) != len) { - *al = SSL_AD_DECODE_ERROR; - return 0; - } + if (strlen(s->srp_ctx.login) != len) + goto err; } -# endif +#endif -# ifndef OPENSSL_NO_EC +#ifndef OPENSSL_NO_EC else if (type == TLSEXT_TYPE_ec_point_formats) { unsigned char *sdata = data; int ecpointformatlist_length = *(sdata++); if (ecpointformatlist_length != size - 1 || - ecpointformatlist_length < 1) { - *al = TLS1_AD_DECODE_ERROR; - return 0; - } + ecpointformatlist_length < 1) + goto err; if (!s->hit) { OPENSSL_free(s->session->tlsext_ecpointformatlist); s->session->tlsext_ecpointformatlist = NULL; @@ -2087,15 +2101,13 @@ static int ssl_scan_clienthello_tlsext(SSL *s, unsigned char **p, if (ellipticcurvelist_length != size - 2 || ellipticcurvelist_length < 1 || /* Each NamedCurve is 2 bytes. */ - ellipticcurvelist_length & 1) { - *al = TLS1_AD_DECODE_ERROR; - return 0; - } + ellipticcurvelist_length & 1) + goto err; + if (!s->hit) { - if (s->session->tlsext_ellipticcurvelist) { - *al = TLS1_AD_DECODE_ERROR; - return 0; - } + if (s->session->tlsext_ellipticcurvelist) + goto err; + s->session->tlsext_ellipticcurvelist_length = 0; if ((s->session->tlsext_ellipticcurvelist = OPENSSL_malloc(ellipticcurvelist_length)) == NULL) { @@ -2108,7 +2120,7 @@ static int ssl_scan_clienthello_tlsext(SSL *s, unsigned char **p, ellipticcurvelist_length); } } -# endif /* OPENSSL_NO_EC */ +#endif /* OPENSSL_NO_EC */ else if (type == TLSEXT_TYPE_session_ticket) { if (s->tls_session_ticket_ext_cb && !s->tls_session_ticket_ext_cb(s, data, size, @@ -2119,26 +2131,18 @@ static int ssl_scan_clienthello_tlsext(SSL *s, unsigned char **p, } } else if (type == TLSEXT_TYPE_signature_algorithms) { int dsize; - if (s->cert->peer_sigalgs || size < 2) { - *al = SSL_AD_DECODE_ERROR; - return 0; - } + if (s->s3->tmp.peer_sigalgs || size < 2) + goto err; n2s(data, dsize); size -= 2; - if (dsize != size || dsize & 1 || !dsize) { - *al = SSL_AD_DECODE_ERROR; - return 0; - } - if (!tls1_save_sigalgs(s, data, dsize)) { - *al = SSL_AD_DECODE_ERROR; - return 0; - } + if (dsize != size || dsize & 1 || !dsize) + goto err; + if (!tls1_save_sigalgs(s, data, dsize)) + goto err; } else if (type == TLSEXT_TYPE_status_request) { - if (size < 5) { - *al = SSL_AD_DECODE_ERROR; - return 0; - } + if (size < 5) + goto err; s->tlsext_status_type = *data++; size--; @@ -2148,35 +2152,26 @@ static int ssl_scan_clienthello_tlsext(SSL *s, unsigned char **p, /* Read in responder_id_list */ n2s(data, dsize); size -= 2; - if (dsize > size) { - *al = SSL_AD_DECODE_ERROR; - return 0; - } + if (dsize > size) + goto err; while (dsize > 0) { OCSP_RESPID *id; int idsize; - if (dsize < 4) { - *al = SSL_AD_DECODE_ERROR; - return 0; - } + if (dsize < 4) + goto err; n2s(data, idsize); dsize -= 2 + idsize; size -= 2 + idsize; - if (dsize < 0) { - *al = SSL_AD_DECODE_ERROR; - return 0; - } + if (dsize < 0) + goto err; sdata = data; data += idsize; id = d2i_OCSP_RESPID(NULL, &sdata, idsize); - if (!id) { - *al = SSL_AD_DECODE_ERROR; - return 0; - } + if (!id) + goto err; if (data != sdata) { OCSP_RESPID_free(id); - *al = SSL_AD_DECODE_ERROR; - return 0; + goto err; } if (!s->tlsext_ocsp_ids && !(s->tlsext_ocsp_ids = @@ -2193,26 +2188,20 @@ static int ssl_scan_clienthello_tlsext(SSL *s, unsigned char **p, } /* Read in request_extensions */ - if (size < 2) { - *al = SSL_AD_DECODE_ERROR; - return 0; - } + if (size < 2) + goto err; n2s(data, dsize); size -= 2; - if (dsize != size) { - *al = SSL_AD_DECODE_ERROR; - return 0; - } + if (dsize != size) + goto err; sdata = data; if (dsize > 0) { sk_X509_EXTENSION_pop_free(s->tlsext_ocsp_exts, X509_EXTENSION_free); s->tlsext_ocsp_exts = d2i_X509_EXTENSIONS(NULL, &sdata, dsize); - if (!s->tlsext_ocsp_exts || (data + dsize != sdata)) { - *al = SSL_AD_DECODE_ERROR; - return 0; - } + if (!s->tlsext_ocsp_exts || (data + dsize != sdata)) + goto err; } } /* @@ -2221,7 +2210,7 @@ static int ssl_scan_clienthello_tlsext(SSL *s, unsigned char **p, else s->tlsext_status_type = -1; } -# ifndef OPENSSL_NO_HEARTBEATS +#ifndef OPENSSL_NO_HEARTBEATS else if (type == TLSEXT_TYPE_heartbeat) { switch (data[0]) { case 0x01: /* Client allows us to send HB requests */ @@ -2236,8 +2225,8 @@ static int ssl_scan_clienthello_tlsext(SSL *s, unsigned char **p, return 0; } } -# endif -# ifndef OPENSSL_NO_NEXTPROTONEG +#endif +#ifndef OPENSSL_NO_NEXTPROTONEG else if (type == TLSEXT_TYPE_next_proto_neg && s->s3->tmp.finish_md_len == 0 && s->s3->alpn_selected == NULL) { @@ -2260,30 +2249,30 @@ static int ssl_scan_clienthello_tlsext(SSL *s, unsigned char **p, */ s->s3->next_proto_neg_seen = 1; } -# endif +#endif else if (type == TLSEXT_TYPE_application_layer_protocol_negotiation && s->ctx->alpn_select_cb && s->s3->tmp.finish_md_len == 0) { if (tls1_alpn_handle_client_hello(s, data, size, al) != 0) return 0; -# ifndef OPENSSL_NO_NEXTPROTONEG +#ifndef OPENSSL_NO_NEXTPROTONEG /* ALPN takes precedence over NPN. */ s->s3->next_proto_neg_seen = 0; -# endif +#endif } /* session ticket processed earlier */ -# ifndef OPENSSL_NO_SRTP +#ifndef OPENSSL_NO_SRTP else if (SSL_IS_DTLS(s) && SSL_get_srtp_profiles(s) && type == TLSEXT_TYPE_use_srtp) { if (ssl_parse_clienthello_use_srtp_ext(s, data, size, al)) return 0; } -# endif -# ifdef TLSEXT_TYPE_encrypt_then_mac +#endif +#ifdef TLSEXT_TYPE_encrypt_then_mac else if (type == TLSEXT_TYPE_encrypt_then_mac) s->s3->flags |= TLS1_FLAGS_ENCRYPT_THEN_MAC; -# endif +#endif else if (type == TLSEXT_TYPE_extended_master_secret) { if (!s->hit) s->session->flags |= SSL_SESS_FLAG_EXTMS; @@ -2303,6 +2292,10 @@ static int ssl_scan_clienthello_tlsext(SSL *s, unsigned char **p, data += size; } + /* Spurious data on the end */ + if (data != d + n) + goto err; + *p = data; ri_check: @@ -2318,6 +2311,9 @@ static int ssl_scan_clienthello_tlsext(SSL *s, unsigned char **p, } return 1; +err: + *al = SSL_AD_DECODE_ERROR; + return 0; } int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, @@ -2337,7 +2333,7 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, return 1; } -# ifndef OPENSSL_NO_NEXTPROTONEG +#ifndef OPENSSL_NO_NEXTPROTONEG /* * ssl_next_proto_validate validates a Next Protocol Negotiation block. No * elements of zero length are allowed and the set of elements must exactly @@ -2356,7 +2352,7 @@ static char ssl_next_proto_validate(unsigned char *d, unsigned len) return off == len; } -# endif +#endif static int ssl_scan_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char *d, int n, int *al) @@ -2368,21 +2364,21 @@ static int ssl_scan_serverhello_tlsext(SSL *s, unsigned char **p, int tlsext_servername = 0; int renegotiate_seen = 0; -# ifndef OPENSSL_NO_NEXTPROTONEG +#ifndef OPENSSL_NO_NEXTPROTONEG s->s3->next_proto_neg_seen = 0; -# endif +#endif s->tlsext_ticket_expected = 0; OPENSSL_free(s->s3->alpn_selected); s->s3->alpn_selected = NULL; -# ifndef OPENSSL_NO_HEARTBEATS +#ifndef OPENSSL_NO_HEARTBEATS s->tlsext_heartbeat &= ~(SSL_TLSEXT_HB_ENABLED | SSL_TLSEXT_HB_DONT_SEND_REQUESTS); -# endif +#endif -# ifdef TLSEXT_TYPE_encrypt_then_mac +#ifdef TLSEXT_TYPE_encrypt_then_mac s->s3->flags &= ~TLS1_FLAGS_ENCRYPT_THEN_MAC; -# endif +#endif if (data >= (d + n - 2)) goto ri_check; @@ -2415,7 +2411,7 @@ static int ssl_scan_serverhello_tlsext(SSL *s, unsigned char **p, } tlsext_servername = 1; } -# ifndef OPENSSL_NO_EC +#ifndef OPENSSL_NO_EC else if (type == TLSEXT_TYPE_ec_point_formats) { unsigned char *sdata = data; int ecpointformatlist_length = *(sdata++); @@ -2438,7 +2434,7 @@ static int ssl_scan_serverhello_tlsext(SSL *s, unsigned char **p, ecpointformatlist_length); } } -# endif /* OPENSSL_NO_EC */ +#endif /* OPENSSL_NO_EC */ else if (type == TLSEXT_TYPE_session_ticket) { if (s->tls_session_ticket_ext_cb && @@ -2466,7 +2462,7 @@ static int ssl_scan_serverhello_tlsext(SSL *s, unsigned char **p, /* Set flag to expect CertificateStatus message */ s->tlsext_status_expected = 1; } -# ifndef OPENSSL_NO_NEXTPROTONEG +#ifndef OPENSSL_NO_NEXTPROTONEG else if (type == TLSEXT_TYPE_next_proto_neg && s->s3->tmp.finish_md_len == 0) { unsigned char *selected; @@ -2499,7 +2495,7 @@ static int ssl_scan_serverhello_tlsext(SSL *s, unsigned char **p, s->next_proto_negotiated_len = selected_len; s->s3->next_proto_neg_seen = 1; } -# endif +#endif else if (type == TLSEXT_TYPE_application_layer_protocol_negotiation) { unsigned len; @@ -2540,7 +2536,7 @@ static int ssl_scan_serverhello_tlsext(SSL *s, unsigned char **p, memcpy(s->s3->alpn_selected, data + 3, len); s->s3->alpn_selected_len = len; } -# ifndef OPENSSL_NO_HEARTBEATS +#ifndef OPENSSL_NO_HEARTBEATS else if (type == TLSEXT_TYPE_heartbeat) { switch (data[0]) { case 0x01: /* Server allows us to send HB requests */ @@ -2555,21 +2551,21 @@ static int ssl_scan_serverhello_tlsext(SSL *s, unsigned char **p, return 0; } } -# endif -# ifndef OPENSSL_NO_SRTP +#endif +#ifndef OPENSSL_NO_SRTP else if (SSL_IS_DTLS(s) && type == TLSEXT_TYPE_use_srtp) { if (ssl_parse_serverhello_use_srtp_ext(s, data, size, al)) return 0; } -# endif -# ifdef TLSEXT_TYPE_encrypt_then_mac +#endif +#ifdef TLSEXT_TYPE_encrypt_then_mac else if (type == TLSEXT_TYPE_encrypt_then_mac) { /* Ignore if inappropriate ciphersuite */ if (s->s3->tmp.new_cipher->algorithm_mac != SSL_AEAD && s->s3->tmp.new_cipher->algorithm_enc != SSL_RC4) s->s3->flags |= TLS1_FLAGS_ENCRYPT_THEN_MAC; } -# endif +#endif else if (type == TLSEXT_TYPE_extended_master_secret) { if (!s->hit) s->session->flags |= SSL_SESS_FLAG_EXTMS; @@ -2643,7 +2639,7 @@ static int ssl_check_clienthello_tlsext_early(SSL *s) int ret = SSL_TLSEXT_ERR_NOACK; int al = SSL_AD_UNRECOGNIZED_NAME; -# ifndef OPENSSL_NO_EC +#ifndef OPENSSL_NO_EC /* * The handling of the ECPointFormats extension is done elsewhere, namely * in ssl3_choose_cipher in s3_lib.c. @@ -2652,7 +2648,7 @@ static int ssl_check_clienthello_tlsext_early(SSL *s) * The handling of the EllipticCurves extension is done elsewhere, namely * in ssl3_choose_cipher in s3_lib.c. */ -# endif +#endif if (s->ctx != NULL && s->ctx->tlsext_servername_callback != 0) ret = @@ -2680,6 +2676,21 @@ static int ssl_check_clienthello_tlsext_early(SSL *s) return 1; } } +/* Initialise digests to default values */ +static void ssl_set_default_md(SSL *s) +{ + const EVP_MD **pmd = s->s3->tmp.md; +#ifndef OPENSSL_NO_DSA + pmd[SSL_PKEY_DSA_SIGN] = EVP_sha1(); +#endif +#ifndef OPENSSL_NO_RSA + pmd[SSL_PKEY_RSA_SIGN] = EVP_sha1(); + pmd[SSL_PKEY_RSA_ENC] = EVP_sha1(); +#endif +#ifndef OPENSSL_NO_EC + pmd[SSL_PKEY_ECC] = EVP_sha1(); +#endif +} int tls1_set_server_sigalgs(SSL *s) { @@ -2691,12 +2702,12 @@ int tls1_set_server_sigalgs(SSL *s) s->cert->shared_sigalgslen = 0; /* Clear certificate digests and validity flags */ for (i = 0; i < SSL_PKEY_NUM; i++) { - s->cert->pkeys[i].digest = NULL; - s->cert->pkeys[i].valid_flags = 0; + s->s3->tmp.md[i] = NULL; + s->s3->tmp.valid_flags[i] = 0; } /* If sigalgs received process it. */ - if (s->cert->peer_sigalgs) { + if (s->s3->tmp.peer_sigalgs) { if (!tls1_process_sigalgs(s)) { SSLerr(SSL_F_TLS1_SET_SERVER_SIGALGS, ERR_R_MALLOC_FAILURE); al = SSL_AD_INTERNAL_ERROR; @@ -2709,8 +2720,9 @@ int tls1_set_server_sigalgs(SSL *s) al = SSL_AD_ILLEGAL_PARAMETER; goto err; } - } else - ssl_cert_set_default_md(s->cert); + } else { + ssl_set_default_md(s); + } return 1; err: ssl3_send_alert(s, SSL3_AL_FATAL, al); @@ -2720,7 +2732,7 @@ int tls1_set_server_sigalgs(SSL *s) int ssl_check_clienthello_tlsext_late(SSL *s) { int ret = SSL_TLSEXT_ERR_OK; - int al; + int al = SSL_AD_INTERNAL_ERROR; /* * If status request then ask callback what to do. Note: this must be @@ -2784,7 +2796,7 @@ int ssl_check_serverhello_tlsext(SSL *s) int ret = SSL_TLSEXT_ERR_NOACK; int al = SSL_AD_UNRECOGNIZED_NAME; -# ifndef OPENSSL_NO_EC +#ifndef OPENSSL_NO_EC /* * If we are client and using an elliptic curve cryptography cipher * suite, then if server returns an EC point formats lists extension it @@ -2816,7 +2828,7 @@ int ssl_check_serverhello_tlsext(SSL *s) } } ret = SSL_TLSEXT_ERR_OK; -# endif /* OPENSSL_NO_EC */ +#endif /* OPENSSL_NO_EC */ if (s->ctx != NULL && s->ctx->tlsext_servername_callback != 0) ret = @@ -3193,11 +3205,11 @@ typedef struct { } tls12_hash_info; static const tls12_hash_info tls12_md_info[] = { -# ifdef OPENSSL_NO_MD5 +#ifdef OPENSSL_NO_MD5 {NID_md5, 64, 0}, -# else +#else {NID_md5, 64, EVP_md5}, -# endif +#endif {NID_sha1, 80, EVP_sha1}, {NID_sha224, 112, EVP_sha224}, {NID_sha256, 128, EVP_sha256}, @@ -3228,18 +3240,18 @@ const EVP_MD *tls12_get_hash(unsigned char hash_alg) static int tls12_get_pkey_idx(unsigned char sig_alg) { switch (sig_alg) { -# ifndef OPENSSL_NO_RSA +#ifndef OPENSSL_NO_RSA case TLSEXT_signature_rsa: return SSL_PKEY_RSA_SIGN; -# endif -# ifndef OPENSSL_NO_DSA +#endif +#ifndef OPENSSL_NO_DSA case TLSEXT_signature_dsa: return SSL_PKEY_DSA_SIGN; -# endif -# ifndef OPENSSL_NO_EC +#endif +#ifndef OPENSSL_NO_EC case TLSEXT_signature_ecdsa: return SSL_PKEY_ECC; -# endif +#endif } return -1; } @@ -3302,24 +3314,24 @@ void ssl_set_sig_mask(unsigned long *pmask_a, SSL *s, int op) sigalgslen = tls12_get_psigalgs(s, &sigalgs); for (i = 0; i < sigalgslen; i += 2, sigalgs += 2) { switch (sigalgs[1]) { -# ifndef OPENSSL_NO_RSA +#ifndef OPENSSL_NO_RSA case TLSEXT_signature_rsa: if (!have_rsa && tls12_sigalg_allowed(s, op, sigalgs)) have_rsa = 1; break; -# endif -# ifndef OPENSSL_NO_DSA +#endif +#ifndef OPENSSL_NO_DSA case TLSEXT_signature_dsa: if (!have_dsa && tls12_sigalg_allowed(s, op, sigalgs)) have_dsa = 1; break; -# endif -# ifndef OPENSSL_NO_EC +#endif +#ifndef OPENSSL_NO_EC case TLSEXT_signature_ecdsa: if (!have_ecdsa && tls12_sigalg_allowed(s, op, sigalgs)) have_ecdsa = 1; break; -# endif +#endif } } if (!have_rsa) @@ -3398,13 +3410,13 @@ static int tls1_set_shared_sigalgs(SSL *s) if (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE || is_suiteb) { pref = conf; preflen = conflen; - allow = c->peer_sigalgs; - allowlen = c->peer_sigalgslen; + allow = s->s3->tmp.peer_sigalgs; + allowlen = s->s3->tmp.peer_sigalgslen; } else { allow = conf; allowlen = conflen; - pref = c->peer_sigalgs; - preflen = c->peer_sigalgslen; + pref = s->s3->tmp.peer_sigalgs; + preflen = s->s3->tmp.peer_sigalgslen; } nmatch = tls12_shared_sigalgs(s, NULL, pref, preflen, allow, allowlen); if (nmatch) { @@ -3432,12 +3444,12 @@ int tls1_save_sigalgs(SSL *s, const unsigned char *data, int dsize) if (!c) return 0; - OPENSSL_free(c->peer_sigalgs); - c->peer_sigalgs = OPENSSL_malloc(dsize); - if (!c->peer_sigalgs) + OPENSSL_free(s->s3->tmp.peer_sigalgs); + s->s3->tmp.peer_sigalgs = OPENSSL_malloc(dsize); + if (s->s3->tmp.peer_sigalgs == NULL) return 0; - c->peer_sigalgslen = dsize; - memcpy(c->peer_sigalgs, data, dsize); + s->s3->tmp.peer_sigalgslen = dsize; + memcpy(s->s3->tmp.peer_sigalgs, data, dsize); return 1; } @@ -3446,12 +3458,14 @@ int tls1_process_sigalgs(SSL *s) int idx; size_t i; const EVP_MD *md; + const EVP_MD **pmd = s->s3->tmp.md; + int *pvalid = s->s3->tmp.valid_flags; CERT *c = s->cert; TLS_SIGALGS *sigptr; if (!tls1_set_shared_sigalgs(s)) return 0; -# ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL +#ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL if (s->cert->cert_flags & SSL_CERT_FLAG_BROKEN_PROTOCOL) { /* * Use first set signature preference to force message digest, @@ -3465,28 +3479,26 @@ int tls1_process_sigalgs(SSL *s) if (sigs) { idx = tls12_get_pkey_idx(sigs[1]); md = tls12_get_hash(sigs[0]); - c->pkeys[idx].digest = md; - c->pkeys[idx].valid_flags = CERT_PKEY_EXPLICIT_SIGN; + pmd[idx] = md; + pvalid[idx] = CERT_PKEY_EXPLICIT_SIGN; if (idx == SSL_PKEY_RSA_SIGN) { - c->pkeys[SSL_PKEY_RSA_ENC].valid_flags = - CERT_PKEY_EXPLICIT_SIGN; - c->pkeys[SSL_PKEY_RSA_ENC].digest = md; + pvalid[SSL_PKEY_RSA_ENC] = CERT_PKEY_EXPLICIT_SIGN; + pmd[SSL_PKEY_RSA_ENC] = md; } } } -# endif +#endif for (i = 0, sigptr = c->shared_sigalgs; i < c->shared_sigalgslen; i++, sigptr++) { idx = tls12_get_pkey_idx(sigptr->rsign); - if (idx > 0 && c->pkeys[idx].digest == NULL) { + if (idx > 0 && pmd[idx] == NULL) { md = tls12_get_hash(sigptr->rhash); - c->pkeys[idx].digest = md; - c->pkeys[idx].valid_flags = CERT_PKEY_EXPLICIT_SIGN; + pmd[idx] = md; + pvalid[idx] = CERT_PKEY_EXPLICIT_SIGN; if (idx == SSL_PKEY_RSA_SIGN) { - c->pkeys[SSL_PKEY_RSA_ENC].valid_flags = - CERT_PKEY_EXPLICIT_SIGN; - c->pkeys[SSL_PKEY_RSA_ENC].digest = md; + pvalid[SSL_PKEY_RSA_ENC] = CERT_PKEY_EXPLICIT_SIGN; + pmd[SSL_PKEY_RSA_ENC] = md; } } @@ -3500,20 +3512,20 @@ int tls1_process_sigalgs(SSL *s) * Set any remaining keys to default values. NOTE: if alg is not * supported it stays as NULL. */ -# ifndef OPENSSL_NO_DSA - if (!c->pkeys[SSL_PKEY_DSA_SIGN].digest) - c->pkeys[SSL_PKEY_DSA_SIGN].digest = EVP_sha1(); -# endif -# ifndef OPENSSL_NO_RSA - if (!c->pkeys[SSL_PKEY_RSA_SIGN].digest) { - c->pkeys[SSL_PKEY_RSA_SIGN].digest = EVP_sha1(); - c->pkeys[SSL_PKEY_RSA_ENC].digest = EVP_sha1(); +#ifndef OPENSSL_NO_DSA + if (pmd[SSL_PKEY_DSA_SIGN] == NULL) + 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(); } -# endif -# ifndef OPENSSL_NO_EC - if (!c->pkeys[SSL_PKEY_ECC].digest) - c->pkeys[SSL_PKEY_ECC].digest = EVP_sha1(); -# endif +#endif +#ifndef OPENSSL_NO_EC + if (pmd[SSL_PKEY_ECC] == NULL) + pmd[SSL_PKEY_ECC] = EVP_sha1(); +#endif } return 1; } @@ -3522,12 +3534,12 @@ int SSL_get_sigalgs(SSL *s, int idx, int *psign, int *phash, int *psignhash, unsigned char *rsig, unsigned char *rhash) { - const unsigned char *psig = s->cert->peer_sigalgs; + const unsigned char *psig = s->s3->tmp.peer_sigalgs; if (psig == NULL) return 0; if (idx >= 0) { idx <<= 1; - if (idx >= (int)s->cert->peer_sigalgslen) + if (idx >= (int)s->s3->tmp.peer_sigalgslen) return 0; psig += idx; if (rhash) @@ -3536,7 +3548,7 @@ int SSL_get_sigalgs(SSL *s, int idx, *rsig = psig[1]; tls1_lookup_sigalg(phash, psign, psignhash, psig); } - return s->cert->peer_sigalgslen / 2; + return s->s3->tmp.peer_sigalgslen / 2; } int SSL_get_shared_sigalgs(SSL *s, int idx, @@ -3560,7 +3572,7 @@ int SSL_get_shared_sigalgs(SSL *s, int idx, return s->cert->shared_sigalgslen; } -# ifndef OPENSSL_NO_HEARTBEATS +#ifndef OPENSSL_NO_HEARTBEATS int tls1_process_heartbeat(SSL *s, unsigned char *p, unsigned int length) { unsigned char *pl; @@ -3718,9 +3730,9 @@ int tls1_heartbeat(SSL *s) OPENSSL_free(buf); return ret; } -# endif +#endif -# define MAX_SIGALGLEN (TLSEXT_hash_num * TLSEXT_signature_num * 2) +#define MAX_SIGALGLEN (TLSEXT_hash_num * TLSEXT_signature_num * 2) typedef struct { size_t sigalgcnt; @@ -3749,11 +3761,11 @@ static int sig_cb(const char *elem, int len, void *arg) if (!*p) return 0; - if (!strcmp(etmp, "RSA")) + if (strcmp(etmp, "RSA") == 0) sig_alg = EVP_PKEY_RSA; - else if (!strcmp(etmp, "DSA")) + else if (strcmp(etmp, "DSA") == 0) sig_alg = EVP_PKEY_DSA; - else if (!strcmp(etmp, "ECDSA")) + else if (strcmp(etmp, "ECDSA") == 0) sig_alg = EVP_PKEY_EC; else return 0; @@ -3863,10 +3875,10 @@ static int ssl_check_ca_name(STACK_OF(X509_NAME) *names, X509 *x) /* Flags which need to be set for a certificate when stict mode not set */ -# define CERT_PKEY_VALID_FLAGS \ +#define CERT_PKEY_VALID_FLAGS \ (CERT_PKEY_EE_SIGNATURE|CERT_PKEY_EE_PARAM) /* Strict mode flags */ -# define CERT_PKEY_STRICT_FLAGS \ +#define CERT_PKEY_STRICT_FLAGS \ (CERT_PKEY_VALID_FLAGS|CERT_PKEY_CA_SIGNATURE|CERT_PKEY_CA_PARAM \ | CERT_PKEY_ISSUER_NAME|CERT_PKEY_CERT_TYPE) @@ -3878,6 +3890,7 @@ int tls1_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain, int check_flags = 0, strict_mode; CERT_PKEY *cpk = NULL; CERT *c = s->cert; + int *pvalid; unsigned int suiteb_flags = tls1_suiteb(s); /* idx == -1 means checking server chains */ if (idx != -1) { @@ -3887,6 +3900,7 @@ int tls1_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain, idx = cpk - c->pkeys; } else cpk = c->pkeys + idx; + pvalid = s->s3->tmp.valid_flags + idx; x = cpk->x509; pk = cpk->privatekey; chain = cpk->chain; @@ -3894,15 +3908,15 @@ int tls1_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain, /* If no cert or key, forget it */ if (!x || !pk) goto end; -# ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL +#ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL /* Allow any certificate to pass test */ if (s->cert->cert_flags & SSL_CERT_FLAG_BROKEN_PROTOCOL) { rv = CERT_PKEY_STRICT_FLAGS | CERT_PKEY_EXPLICIT_SIGN | CERT_PKEY_VALID | CERT_PKEY_SIGN; - cpk->valid_flags = rv; + *pvalid = rv; return rv; } -# endif +#endif } else { if (!x || !pk) return 0; @@ -3910,6 +3924,8 @@ int tls1_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain, if (idx == -1) return 0; cpk = c->pkeys + idx; + pvalid = s->s3->tmp.valid_flags + idx; + if (c->cert_flags & SSL_CERT_FLAGS_CHECK_TLS_STRICT) check_flags = CERT_PKEY_STRICT_FLAGS; else @@ -3935,7 +3951,7 @@ int tls1_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain, if (TLS1_get_version(s) >= TLS1_2_VERSION && strict_mode) { int default_nid; unsigned char rsign = 0; - if (c->peer_sigalgs) + if (s->s3->tmp.peer_sigalgs) default_nid = 0; /* If no sigalgs extension use defaults from RFC5246 */ else { @@ -4096,9 +4112,9 @@ int tls1_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain, end: if (TLS1_get_version(s) >= TLS1_2_VERSION) { - if (cpk->valid_flags & CERT_PKEY_EXPLICIT_SIGN) + if (*pvalid & CERT_PKEY_EXPLICIT_SIGN) rv |= CERT_PKEY_EXPLICIT_SIGN | CERT_PKEY_SIGN; - else if (cpk->digest) + else if (s->s3->tmp.md[idx] != NULL) rv |= CERT_PKEY_SIGN; } else rv |= CERT_PKEY_SIGN | CERT_PKEY_EXPLICIT_SIGN; @@ -4109,10 +4125,10 @@ int tls1_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain, */ if (!check_flags) { if (rv & CERT_PKEY_VALID) - cpk->valid_flags = rv; + *pvalid = rv; else { /* Preserve explicit sign flag, clear rest */ - cpk->valid_flags &= CERT_PKEY_EXPLICIT_SIGN; + *pvalid &= CERT_PKEY_EXPLICIT_SIGN; return 0; } } @@ -4136,7 +4152,6 @@ int SSL_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain) return tls1_check_chain(s, x, pk, chain, -1); } -#endif #ifndef OPENSSL_NO_DH DH *ssl_get_auto_dh(SSL *s)