X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=ssl%2Ft1_lib.c;h=511223eb94c78acb334a4801304854151b4395f0;hp=115aab5596246a818e37e6d673a471fcc65bb231;hb=b79d24101e3b5904b3770d60e32bdd6edc558337;hpb=2747d73c1466c487daf64a1234b6fe2e8a62ac75 diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c index 115aab5596..511223eb94 100644 --- a/ssl/t1_lib.c +++ b/ssl/t1_lib.c @@ -706,6 +706,16 @@ static int tls1_check_ec_key(SSL *s, for (j = 0; j <= 1; j++) { if (!tls1_get_curvelist(s, j, &pcurves, &num_curves)) return 0; + if (j == 1 && num_curves == 0) { + /* + * If we've not received any curves then skip this check. + * RFC 4492 does not require the supported elliptic curves extension + * so if it is not sent we can just choose any curve. + * It is invalid to send an empty list in the elliptic curves + * extension, so num_curves == 0 always means no extension. + */ + break; + } for (i = 0; i < num_curves; i++, pcurves += 2) { if (pcurves[0] == curve_id[0] && pcurves[1] == curve_id[1]) break; @@ -798,7 +808,7 @@ static int tls1_check_cert_param(SSL *s, X509 *x, int set_ee_md) return rv; } -# ifndef OPENSSL_NO_ECDH +# ifndef OPENSSL_NO_EC /* Check EC temporary key is compatible with client extensions */ int tls1_check_ec_tmp_key(SSL *s, unsigned long cid) { @@ -863,7 +873,7 @@ int tls1_check_ec_tmp_key(SSL *s, unsigned long cid) return tls1_check_ec_key(s, curve_id, NULL); # endif } -# endif /* OPENSSL_NO_ECDH */ +# endif /* OPENSSL_NO_EC */ #else @@ -893,9 +903,8 @@ static int tls1_check_cert_param(SSL *s, X509 *x, int set_ee_md) # define tlsext_sigalg_dsa(md) md, TLSEXT_signature_dsa, # endif -# ifdef OPENSSL_NO_ECDSA -# define tlsext_sigalg_ecdsa(md) - /* */ +# ifdef OPENSSL_NO_EC +# define tlsext_sigalg_ecdsa(md) /* */ # else # define tlsext_sigalg_ecdsa(md) md, TLSEXT_signature_ecdsa, # endif @@ -906,20 +915,14 @@ static int tls1_check_cert_param(SSL *s, X509 *x, int set_ee_md) tlsext_sigalg_ecdsa(md) static const unsigned char tls12_sigalgs[] = { -# ifndef OPENSSL_NO_SHA512 tlsext_sigalg(TLSEXT_hash_sha512) tlsext_sigalg(TLSEXT_hash_sha384) -# endif -# ifndef OPENSSL_NO_SHA256 tlsext_sigalg(TLSEXT_hash_sha256) tlsext_sigalg(TLSEXT_hash_sha224) -# endif -# ifndef OPENSSL_NO_SHA tlsext_sigalg(TLSEXT_hash_sha1) -# endif }; -# ifndef OPENSSL_NO_ECDSA +# ifndef OPENSSL_NO_EC static const unsigned char suiteb_sigalgs[] = { tlsext_sigalg_ecdsa(TLSEXT_hash_sha256) tlsext_sigalg_ecdsa(TLSEXT_hash_sha384) @@ -1341,22 +1344,6 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf, s2n(salglen, etmp); ret += salglen; } -# ifdef TLSEXT_TYPE_opaque_prf_input - if (s->s3->client_opaque_prf_input != NULL) { - size_t col = s->s3->client_opaque_prf_input_len; - - if ((long)(limit - ret - 6 - col) < 0) - return NULL; - if (col > 0xFFFD) /* can't happen */ - return NULL; - - s2n(TLSEXT_TYPE_opaque_prf_input, ret); - s2n(col + 2, ret); - s2n(col, ret); - memcpy(ret, s->s3->client_opaque_prf_input, col); - ret += col; - } -# endif if (s->tlsext_status_type == TLSEXT_STATUSTYPE_ocsp) { int i; @@ -1467,6 +1454,8 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf, s2n(TLSEXT_TYPE_encrypt_then_mac, ret); s2n(0, ret); # endif + s2n(TLSEXT_TYPE_extended_master_secret, ret); + s2n(0, ret); /* * Add padding to workaround bugs in F5 terminators. See @@ -1607,22 +1596,6 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf, s2n(TLSEXT_TYPE_status_request, ret); s2n(0, ret); } -# ifdef TLSEXT_TYPE_opaque_prf_input - if (s->s3->server_opaque_prf_input != NULL) { - size_t sol = s->s3->server_opaque_prf_input_len; - - if ((long)(limit - ret - 6 - sol) < 0) - return NULL; - if (sol > 0xFFFD) /* can't happen */ - return NULL; - - s2n(TLSEXT_TYPE_opaque_prf_input, ret); - s2n(sol + 2, ret); - s2n(sol, ret); - memcpy(ret, s->s3->server_opaque_prf_input, sol); - ret += sol; - } -# endif # ifndef OPENSSL_NO_SRTP if (SSL_IS_DTLS(s) && s->srtp_profile) { @@ -1720,6 +1693,10 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf, } } # endif + if (!s->hit && s->session->flags & SSL_SESS_FLAG_EXTMS) { + s2n(TLSEXT_TYPE_extended_master_secret, ret); + s2n(0, ret); + } if (s->s3->alpn_selected) { const unsigned char *selected = s->s3->alpn_selected; @@ -1955,9 +1932,6 @@ static int ssl_scan_clienthello_tlsext(SSL *s, unsigned char **p, if (data + size > (d + n)) goto ri_check; -# if 0 - fprintf(stderr, "Received extension type %d size %d\n", type, size); -# endif if (s->tlsext_debug_cb) s->tlsext_debug_cb(s, 0, type, data, size, s->tlsext_debug_arg); if (type == TLSEXT_TYPE_renegotiate) { @@ -2112,15 +2086,6 @@ static int ssl_scan_clienthello_tlsext(SSL *s, unsigned char **p, memcpy(s->session->tlsext_ecpointformatlist, sdata, ecpointformatlist_length); } -# if 0 - fprintf(stderr, - "ssl_parse_clienthello_tlsext s->session->tlsext_ecpointformatlist (length=%i) ", - s->session->tlsext_ecpointformatlist_length); - sdata = s->session->tlsext_ecpointformatlist; - for (i = 0; i < s->session->tlsext_ecpointformatlist_length; i++) - fprintf(stderr, "%i ", *(sdata++)); - fprintf(stderr, "\n"); -# endif } else if (type == TLSEXT_TYPE_elliptic_curves) { unsigned char *sdata = data; int ellipticcurvelist_length = (*(sdata++) << 8); @@ -2149,48 +2114,8 @@ static int ssl_scan_clienthello_tlsext(SSL *s, unsigned char **p, memcpy(s->session->tlsext_ellipticcurvelist, sdata, ellipticcurvelist_length); } -# if 0 - fprintf(stderr, - "ssl_parse_clienthello_tlsext s->session->tlsext_ellipticcurvelist (length=%i) ", - s->session->tlsext_ellipticcurvelist_length); - sdata = s->session->tlsext_ellipticcurvelist; - for (i = 0; i < s->session->tlsext_ellipticcurvelist_length; i++) - fprintf(stderr, "%i ", *(sdata++)); - fprintf(stderr, "\n"); -# endif } # endif /* OPENSSL_NO_EC */ -# ifdef TLSEXT_TYPE_opaque_prf_input - else if (type == TLSEXT_TYPE_opaque_prf_input) { - unsigned char *sdata = data; - - if (size < 2) { - *al = SSL_AD_DECODE_ERROR; - return 0; - } - n2s(sdata, s->s3->client_opaque_prf_input_len); - if (s->s3->client_opaque_prf_input_len != size - 2) { - *al = SSL_AD_DECODE_ERROR; - return 0; - } - - if (s->s3->client_opaque_prf_input != NULL) { - /* shouldn't really happen */ - OPENSSL_free(s->s3->client_opaque_prf_input); - } - - /* dummy byte just to get non-NULL */ - if (s->s3->client_opaque_prf_input_len == 0) - s->s3->client_opaque_prf_input = OPENSSL_malloc(1); - else - s->s3->client_opaque_prf_input = - BUF_memdup(sdata, s->s3->client_opaque_prf_input_len); - if (s->s3->client_opaque_prf_input == NULL) { - *al = TLS1_AD_INTERNAL_ERROR; - return 0; - } - } -# endif else if (type == TLSEXT_TYPE_session_ticket) { if (s->tls_session_ticket_ext_cb && !s->tls_session_ticket_ext_cb(s, data, size, @@ -2369,6 +2294,10 @@ static int ssl_scan_clienthello_tlsext(SSL *s, unsigned char **p, else if (type == TLSEXT_TYPE_encrypt_then_mac) s->s3->flags |= TLS1_FLAGS_ENCRYPT_THEN_MAC; # endif + else if (type == TLSEXT_TYPE_extended_master_secret) { + if (!s->hit) + s->session->flags |= SSL_SESS_FLAG_EXTMS; + } /* * If this ClientHello extension was unhandled and this is a * nonresumed connection, check whether the extension is a custom @@ -2521,14 +2450,6 @@ static int ssl_scan_serverhello_tlsext(SSL *s, unsigned char **p, memcpy(s->session->tlsext_ecpointformatlist, sdata, ecpointformatlist_length); } -# if 0 - fprintf(stderr, - "ssl_parse_serverhello_tlsext s->session->tlsext_ecpointformatlist "); - sdata = s->session->tlsext_ecpointformatlist; - for (i = 0; i < s->session->tlsext_ecpointformatlist_length; i++) - fprintf(stderr, "%i ", *(sdata++)); - fprintf(stderr, "\n"); -# endif } # endif /* OPENSSL_NO_EC */ @@ -2546,38 +2467,6 @@ static int ssl_scan_serverhello_tlsext(SSL *s, unsigned char **p, } s->tlsext_ticket_expected = 1; } -# ifdef TLSEXT_TYPE_opaque_prf_input - else if (type == TLSEXT_TYPE_opaque_prf_input) { - unsigned char *sdata = data; - - if (size < 2) { - *al = SSL_AD_DECODE_ERROR; - return 0; - } - n2s(sdata, s->s3->server_opaque_prf_input_len); - if (s->s3->server_opaque_prf_input_len != size - 2) { - *al = SSL_AD_DECODE_ERROR; - return 0; - } - - if (s->s3->server_opaque_prf_input != NULL) { - /* shouldn't really happen */ - OPENSSL_free(s->s3->server_opaque_prf_input); - } - if (s->s3->server_opaque_prf_input_len == 0) { - /* dummy byte just to get non-NULL */ - s->s3->server_opaque_prf_input = OPENSSL_malloc(1); - } else { - s->s3->server_opaque_prf_input = - BUF_memdup(sdata, s->s3->server_opaque_prf_input_len); - } - - if (s->s3->server_opaque_prf_input == NULL) { - *al = TLS1_AD_INTERNAL_ERROR; - return 0; - } - } -# endif else if (type == TLSEXT_TYPE_status_request) { /* * MUST be empty and only sent if we've requested a status @@ -2695,6 +2584,10 @@ static int ssl_scan_serverhello_tlsext(SSL *s, unsigned char **p, s->s3->flags |= TLS1_FLAGS_ENCRYPT_THEN_MAC; } # endif + else if (type == TLSEXT_TYPE_extended_master_secret) { + if (!s->hit) + s->session->flags |= SSL_SESS_FLAG_EXTMS; + } /* * If this extension type was not otherwise handled, but matches a * custom_cli_ext_record, then send it to the c callback @@ -2751,51 +2644,6 @@ static int ssl_scan_serverhello_tlsext(SSL *s, unsigned char **p, int ssl_prepare_clienthello_tlsext(SSL *s) { -# ifdef TLSEXT_TYPE_opaque_prf_input - { - int r = 1; - - if (s->ctx->tlsext_opaque_prf_input_callback != 0) { - r = s->ctx->tlsext_opaque_prf_input_callback(s, NULL, 0, - s-> - ctx->tlsext_opaque_prf_input_callback_arg); - if (!r) - return -1; - } - - if (s->tlsext_opaque_prf_input != NULL) { - if (s->s3->client_opaque_prf_input != NULL) { - /* shouldn't really happen */ - OPENSSL_free(s->s3->client_opaque_prf_input); - } - - if (s->tlsext_opaque_prf_input_len == 0) { - /* dummy byte just to get non-NULL */ - s->s3->client_opaque_prf_input = OPENSSL_malloc(1); - } else { - s->s3->client_opaque_prf_input = - BUF_memdup(s->tlsext_opaque_prf_input, - s->tlsext_opaque_prf_input_len); - } - if (s->s3->client_opaque_prf_input == NULL) { - SSLerr(SSL_F_SSL_PREPARE_CLIENTHELLO_TLSEXT, - ERR_R_MALLOC_FAILURE); - return -1; - } - s->s3->client_opaque_prf_input_len = - s->tlsext_opaque_prf_input_len; - } - - if (r == 2) - /* - * at callback's request, insist on receiving an appropriate - * server opaque PRF input - */ - s->s3->server_opaque_prf_input_len = - s->tlsext_opaque_prf_input_len; - } -# endif - return 1; } @@ -2831,73 +2679,6 @@ static int ssl_check_clienthello_tlsext_early(SSL *s) s-> initial_ctx->tlsext_servername_arg); -# ifdef TLSEXT_TYPE_opaque_prf_input - { - /* - * This sort of belongs into ssl_prepare_serverhello_tlsext(), but we - * might be sending an alert in response to the client hello, so this - * has to happen here in ssl_check_clienthello_tlsext_early(). - */ - - int r = 1; - - if (s->ctx->tlsext_opaque_prf_input_callback != 0) { - r = s->ctx->tlsext_opaque_prf_input_callback(s, NULL, 0, - s-> - ctx->tlsext_opaque_prf_input_callback_arg); - if (!r) { - ret = SSL_TLSEXT_ERR_ALERT_FATAL; - al = SSL_AD_INTERNAL_ERROR; - goto err; - } - } - - if (s->s3->server_opaque_prf_input != NULL) { - /* shouldn't really happen */ - OPENSSL_free(s->s3->server_opaque_prf_input); - } - s->s3->server_opaque_prf_input = NULL; - - if (s->tlsext_opaque_prf_input != NULL) { - if (s->s3->client_opaque_prf_input != NULL && - s->s3->client_opaque_prf_input_len == - s->tlsext_opaque_prf_input_len) { - /* - * can only use this extension if we have a server opaque PRF - * input of the same length as the client opaque PRF input! - */ - - if (s->tlsext_opaque_prf_input_len == 0) { - /* dummy byte just to get non-NULL */ - s->s3->server_opaque_prf_input = OPENSSL_malloc(1); - } else { - s->s3->server_opaque_prf_input = - BUF_memdup(s->tlsext_opaque_prf_input, - s->tlsext_opaque_prf_input_len); - } - if (s->s3->server_opaque_prf_input == NULL) { - ret = SSL_TLSEXT_ERR_ALERT_FATAL; - al = SSL_AD_INTERNAL_ERROR; - goto err; - } - s->s3->server_opaque_prf_input_len = - s->tlsext_opaque_prf_input_len; - } - } - - if (r == 2 && s->s3->server_opaque_prf_input == NULL) { - /* - * The callback wants to enforce use of the extension, but we - * can't do that with the client opaque PRF input; abort the - * handshake. - */ - ret = SSL_TLSEXT_ERR_ALERT_FATAL; - al = SSL_AD_HANDSHAKE_FAILURE; - } - } - - err: -# endif switch (ret) { case SSL_TLSEXT_ERR_ALERT_FATAL: ssl3_send_alert(s, SSL3_AL_FATAL, al); @@ -2922,6 +2703,7 @@ int tls1_set_server_sigalgs(SSL *s) if (s->cert->shared_sigalgs) { OPENSSL_free(s->cert->shared_sigalgs); s->cert->shared_sigalgs = NULL; + s->cert->shared_sigalgslen = 0; } /* Clear certificate digests and validity flags */ for (i = 0; i < SSL_PKEY_NUM; i++) { @@ -3063,32 +2845,6 @@ int ssl_check_serverhello_tlsext(SSL *s) s-> initial_ctx->tlsext_servername_arg); -# ifdef TLSEXT_TYPE_opaque_prf_input - if (s->s3->server_opaque_prf_input_len > 0) { - /* - * This case may indicate that we, as a client, want to insist on - * using opaque PRF inputs. So first verify that we really have a - * value from the server too. - */ - - if (s->s3->server_opaque_prf_input == NULL) { - ret = SSL_TLSEXT_ERR_ALERT_FATAL; - al = SSL_AD_HANDSHAKE_FAILURE; - } - - /* - * Anytime the server *has* sent an opaque PRF input, we need to - * check that we have a client opaque PRF input of the same size. - */ - if (s->s3->client_opaque_prf_input == NULL || - s->s3->client_opaque_prf_input_len != - s->s3->server_opaque_prf_input_len) { - ret = SSL_TLSEXT_ERR_ALERT_FATAL; - al = SSL_AD_ILLEGAL_PARAMETER; - } - } -# endif - /* * If we've requested certificate status and we wont get one tell the * callback @@ -3318,7 +3074,7 @@ static int tls_decrypt_ticket(SSL *s, const unsigned char *etick, if (memcmp(etick, tctx->tlsext_tick_key_name, 16)) return 2; HMAC_Init_ex(&hctx, tctx->tlsext_tick_hmac_key, 16, - tlsext_tick_md(), NULL); + EVP_sha256(), NULL); EVP_DecryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL, tctx->tlsext_tick_aes_key, etick + 16); } @@ -3462,25 +3218,11 @@ static const tls12_hash_info tls12_md_info[] = { # else {NID_md5, 64, EVP_md5}, # endif -# ifdef OPENSSL_NO_SHA - {NID_sha1, 80, 0}, -# else {NID_sha1, 80, EVP_sha1}, -# endif -# ifdef OPENSSL_NO_SHA256 - {NID_sha224, 112, 0}, - {NID_sha256, 128, 0}, -# else {NID_sha224, 112, EVP_sha224}, {NID_sha256, 128, EVP_sha256}, -# endif -# ifdef OPENSSL_NO_SHA512 - {NID_sha384, 192, 0}, - {NID_sha512, 256, 0} -# else {NID_sha384, 192, EVP_sha384}, {NID_sha512, 256, EVP_sha512} -# endif }; static const tls12_hash_info *tls12_get_hash_info(unsigned char hash_alg) @@ -3514,7 +3256,7 @@ static int tls12_get_pkey_idx(unsigned char sig_alg) case TLSEXT_signature_dsa: return SSL_PKEY_DSA_SIGN; # endif -# ifndef OPENSSL_NO_ECDSA +# ifndef OPENSSL_NO_EC case TLSEXT_signature_ecdsa: return SSL_PKEY_ECC; # endif @@ -3594,7 +3336,7 @@ void ssl_set_sig_mask(unsigned long *pmask_a, SSL *s, int op) have_dsa = 1; break; # endif -# ifndef OPENSSL_NO_ECDSA +# ifndef OPENSSL_NO_EC case TLSEXT_signature_ecdsa: if (!have_ecdsa && tls12_sigalg_allowed(s, op, sigalgs)) have_ecdsa = 1; @@ -3665,6 +3407,7 @@ static int tls1_set_shared_sigalgs(SSL *s) if (c->shared_sigalgs) { OPENSSL_free(c->shared_sigalgs); c->shared_sigalgs = NULL; + c->shared_sigalgslen = 0; } /* If client use client signature algorithms if not NULL */ if (!s->server && c->client_sigalgs && !is_suiteb) { @@ -3687,12 +3430,14 @@ static int tls1_set_shared_sigalgs(SSL *s) preflen = c->peer_sigalgslen; } nmatch = tls12_shared_sigalgs(s, NULL, pref, preflen, allow, allowlen); - if (!nmatch) - return 1; - salgs = OPENSSL_malloc(nmatch * sizeof(TLS_SIGALGS)); - if (!salgs) - return 0; - nmatch = tls12_shared_sigalgs(s, salgs, pref, preflen, allow, allowlen); + if (nmatch) { + salgs = OPENSSL_malloc(nmatch * sizeof(TLS_SIGALGS)); + if (!salgs) + return 0; + nmatch = tls12_shared_sigalgs(s, salgs, pref, preflen, allow, allowlen); + } else { + salgs = NULL; + } c->shared_sigalgs = salgs; c->shared_sigalgslen = nmatch; return 1; @@ -3789,7 +3534,7 @@ int tls1_process_sigalgs(SSL *s) c->pkeys[SSL_PKEY_RSA_ENC].digest = EVP_sha1(); } # endif -# ifndef OPENSSL_NO_ECDSA +# ifndef OPENSSL_NO_EC if (!c->pkeys[SSL_PKEY_ECC].digest) c->pkeys[SSL_PKEY_ECC].digest = EVP_sha1(); # endif @@ -4179,10 +3924,10 @@ int tls1_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain, # endif } else { if (!x || !pk) - goto end; + return 0; idx = ssl_cert_type(x, pk); if (idx == -1) - goto end; + return 0; cpk = c->pkeys + idx; if (c->cert_flags & SSL_CERT_FLAGS_CHECK_TLS_STRICT) check_flags = CERT_PKEY_STRICT_FLAGS;