X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=ssl%2Fstatem%2Fextensions_srvr.c;h=1eeae096d6cda54f01fbd4892a4b94b5e20c7828;hp=370d0b9b02800b44fb2f74d99c7e85d15c3c44cf;hb=d270de322c7bfb9c1e7509fbc24e3bf6fde713e6;hpb=89247375efcf0869449a711fd248f160627de2a2 diff --git a/ssl/statem/extensions_srvr.c b/ssl/statem/extensions_srvr.c index 370d0b9b02..1eeae096d6 100644 --- a/ssl/statem/extensions_srvr.c +++ b/ssl/statem/extensions_srvr.c @@ -14,7 +14,7 @@ /* * Parse the client's renegotiation binding and abort if it's not right */ -int tls_parse_client_renegotiate(SSL *s, PACKET *pkt, int *al) +int tls_parse_ctos_renegotiate(SSL *s, PACKET *pkt, int *al) { unsigned int ilen; const unsigned char *data; @@ -49,35 +49,34 @@ int tls_parse_client_renegotiate(SSL *s, PACKET *pkt, int *al) return 1; } -int tls_parse_client_server_name(SSL *s, PACKET *pkt, int *al) +/*- + * The servername extension is treated as follows: + * + * - Only the hostname type is supported with a maximum length of 255. + * - The servername is rejected if too long or if it contains zeros, + * in which case an fatal alert is generated. + * - The servername field is maintained together with the session cache. + * - When a session is resumed, the servername call back invoked in order + * to allow the application to position itself to the right context. + * - The servername is acknowledged if it is new for a session or when + * it is identical to a previously used for the same session. + * Applications can control the behaviour. They can at any time + * set a 'desirable' servername for a new SSL object. This can be the + * case for example with HTTPS when a Host: header field is received and + * a renegotiation is requested. In this case, a possible servername + * presented in the new client hello is only acknowledged if it matches + * the value of the Host: field. + * - Applications must use SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION + * if they provide for changing an explicit servername context for the + * session, i.e. when the session has been established with a servername + * extension. + * - On session reconnect, the servername extension may be absent. + */ +int tls_parse_ctos_server_name(SSL *s, PACKET *pkt, int *al) { unsigned int servname_type; PACKET sni, hostname; - /*- - * The servername extension is treated as follows: - * - * - Only the hostname type is supported with a maximum length of 255. - * - The servername is rejected if too long or if it contains zeros, - * in which case an fatal alert is generated. - * - The servername field is maintained together with the session cache. - * - When a session is resumed, the servername call back invoked in order - * to allow the application to position itself to the right context. - * - The servername is acknowledged if it is new for a session or when - * it is identical to a previously used for the same session. - * Applications can control the behaviour. They can at any time - * set a 'desirable' servername for a new SSL object. This can be the - * case for example with HTTPS when a Host: header field is received and - * a renegotiation is requested. In this case, a possible servername - * presented in the new client hello is only acknowledged if it matches - * the value of the Host: field. - * - Applications must use SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION - * if they provide for changing an explicit servername context for the - * session, i.e. when the session has been established with a servername - * extension. - * - On session reconnect, the servername extension may be absent. - * - */ if (!PACKET_as_length_prefixed_2(pkt, &sni) /* ServerNameList must be at least 1 byte long. */ || PACKET_remaining(&sni) == 0) { @@ -88,7 +87,7 @@ int tls_parse_client_server_name(SSL *s, PACKET *pkt, int *al) /* * Although the server_name extension was intended to be * extensible to new name types, RFC 4366 defined the - * syntax inextensibility and OpenSSL 1.0.x parses it as + * syntax inextensibly and OpenSSL 1.0.x parses it as * such. * RFC 6066 corrected the mistake but adding new name types * is nevertheless no longer feasible, so act as if no other @@ -135,7 +134,7 @@ int tls_parse_client_server_name(SSL *s, PACKET *pkt, int *al) } #ifndef OPENSSL_NO_SRP -int tls_parse_client_srp(SSL *s, PACKET *pkt, int *al) +int tls_parse_ctos_srp(SSL *s, PACKET *pkt, int *al) { PACKET srp_I; @@ -159,7 +158,7 @@ int tls_parse_client_srp(SSL *s, PACKET *pkt, int *al) #endif #ifndef OPENSSL_NO_EC -int tls_parse_client_ec_pt_formats(SSL *s, PACKET *pkt, int *al) +int tls_parse_ctos_ec_pt_formats(SSL *s, PACKET *pkt, int *al) { PACKET ec_point_format_list; @@ -182,7 +181,7 @@ int tls_parse_client_ec_pt_formats(SSL *s, PACKET *pkt, int *al) } #endif /* OPENSSL_NO_EC */ -int tls_parse_client_session_ticket(SSL *s, PACKET *pkt, int *al) +int tls_parse_ctos_session_ticket(SSL *s, PACKET *pkt, int *al) { if (s->tls_session_ticket_ext_cb && !s->tls_session_ticket_ext_cb(s, PACKET_data(pkt), @@ -195,7 +194,7 @@ int tls_parse_client_session_ticket(SSL *s, PACKET *pkt, int *al) return 1; } -int tls_parse_client_sig_algs(SSL *s, PACKET *pkt, int *al) +int tls_parse_ctos_sig_algs(SSL *s, PACKET *pkt, int *al) { PACKET supported_sig_algs; @@ -216,93 +215,93 @@ int tls_parse_client_sig_algs(SSL *s, PACKET *pkt, int *al) } #ifndef OPENSSL_NO_OCSP -int tls_parse_client_status_request(SSL *s, PACKET *pkt, int *al) +int tls_parse_ctos_status_request(SSL *s, PACKET *pkt, int *al) { + PACKET responder_id_list, exts; + if (!PACKET_get_1(pkt, (unsigned int *)&s->tlsext_status_type)) { *al = SSL_AD_DECODE_ERROR; return 0; } - if (s->tlsext_status_type == TLSEXT_STATUSTYPE_ocsp) { - const unsigned char *ext_data; - PACKET responder_id_list, exts; - if (!PACKET_get_length_prefixed_2 (pkt, &responder_id_list)) { - *al = SSL_AD_DECODE_ERROR; - return 0; - } - + if (s->tlsext_status_type != TLSEXT_STATUSTYPE_ocsp) { /* - * We remove any OCSP_RESPIDs from a previous handshake - * to prevent unbounded memory growth - CVE-2016-6304 + * We don't know what to do with any other type so ignore it. */ - sk_OCSP_RESPID_pop_free(s->tlsext_ocsp_ids, OCSP_RESPID_free); - if (PACKET_remaining(&responder_id_list) > 0) { - s->tlsext_ocsp_ids = sk_OCSP_RESPID_new_null(); - if (s->tlsext_ocsp_ids == NULL) { - *al = SSL_AD_INTERNAL_ERROR; - return 0; - } - } else { - s->tlsext_ocsp_ids = NULL; - } + s->tlsext_status_type = -1; + return 1; + } - while (PACKET_remaining(&responder_id_list) > 0) { - OCSP_RESPID *id; - PACKET responder_id; - const unsigned char *id_data; + if (!PACKET_get_length_prefixed_2 (pkt, &responder_id_list)) { + *al = SSL_AD_DECODE_ERROR; + return 0; + } - if (!PACKET_get_length_prefixed_2(&responder_id_list, - &responder_id) - || PACKET_remaining(&responder_id) == 0) { - *al = SSL_AD_DECODE_ERROR; - return 0; - } + /* + * We remove any OCSP_RESPIDs from a previous handshake + * to prevent unbounded memory growth - CVE-2016-6304 + */ + sk_OCSP_RESPID_pop_free(s->tlsext_ocsp_ids, OCSP_RESPID_free); + if (PACKET_remaining(&responder_id_list) > 0) { + s->tlsext_ocsp_ids = sk_OCSP_RESPID_new_null(); + if (s->tlsext_ocsp_ids == NULL) { + *al = SSL_AD_INTERNAL_ERROR; + return 0; + } + } else { + s->tlsext_ocsp_ids = NULL; + } - id_data = PACKET_data(&responder_id); - /* TODO(size_t): Convert d2i_* to size_t */ - id = d2i_OCSP_RESPID(NULL, &id_data, - (int)PACKET_remaining(&responder_id)); - if (id == NULL) { - *al = SSL_AD_DECODE_ERROR; - return 0; - } + while (PACKET_remaining(&responder_id_list) > 0) { + OCSP_RESPID *id; + PACKET responder_id; + const unsigned char *id_data; - if (id_data != PACKET_end(&responder_id)) { - OCSP_RESPID_free(id); - *al = SSL_AD_DECODE_ERROR; - return 0; - } + if (!PACKET_get_length_prefixed_2(&responder_id_list, &responder_id) + || PACKET_remaining(&responder_id) == 0) { + *al = SSL_AD_DECODE_ERROR; + return 0; + } - if (!sk_OCSP_RESPID_push(s->tlsext_ocsp_ids, id)) { - OCSP_RESPID_free(id); - *al = SSL_AD_INTERNAL_ERROR; - return 0; - } + id_data = PACKET_data(&responder_id); + /* TODO(size_t): Convert d2i_* to size_t */ + id = d2i_OCSP_RESPID(NULL, &id_data, + (int)PACKET_remaining(&responder_id)); + if (id == NULL) { + *al = SSL_AD_DECODE_ERROR; + return 0; } - /* Read in request_extensions */ - if (!PACKET_as_length_prefixed_2(pkt, &exts)) { + if (id_data != PACKET_end(&responder_id)) { + OCSP_RESPID_free(id); *al = SSL_AD_DECODE_ERROR; return 0; } - if (PACKET_remaining(&exts) > 0) { - ext_data = PACKET_data(&exts); - sk_X509_EXTENSION_pop_free(s->tlsext_ocsp_exts, - X509_EXTENSION_free); - s->tlsext_ocsp_exts = - d2i_X509_EXTENSIONS(NULL, &ext_data, - (int)PACKET_remaining(&exts)); - if (s->tlsext_ocsp_exts == NULL || ext_data != PACKET_end(&exts)) { - *al = SSL_AD_DECODE_ERROR; - return 0; - } + if (!sk_OCSP_RESPID_push(s->tlsext_ocsp_ids, id)) { + OCSP_RESPID_free(id); + *al = SSL_AD_INTERNAL_ERROR; + return 0; + } + } + + /* Read in request_extensions */ + if (!PACKET_as_length_prefixed_2(pkt, &exts)) { + *al = SSL_AD_DECODE_ERROR; + return 0; + } + + if (PACKET_remaining(&exts) > 0) { + const unsigned char *ext_data = PACKET_data(&exts); + + sk_X509_EXTENSION_pop_free(s->tlsext_ocsp_exts, + X509_EXTENSION_free); + s->tlsext_ocsp_exts = + d2i_X509_EXTENSIONS(NULL, &ext_data, (int)PACKET_remaining(&exts)); + if (s->tlsext_ocsp_exts == NULL || ext_data != PACKET_end(&exts)) { + *al = SSL_AD_DECODE_ERROR; + return 0; } - } else { - /* - * We don't know what to do with any other type so ignore it. - */ - s->tlsext_status_type = -1; } return 1; @@ -310,40 +309,38 @@ int tls_parse_client_status_request(SSL *s, PACKET *pkt, int *al) #endif #ifndef OPENSSL_NO_NEXTPROTONEG -int tls_parse_client_npn(SSL *s, PACKET *pkt, int *al) +int tls_parse_ctos_npn(SSL *s, PACKET *pkt, int *al) { - if (s->s3->tmp.finish_md_len == 0) { - /*- - * We shouldn't accept this extension on a - * renegotiation. - * - * s->new_session will be set on renegotiation, but we - * probably shouldn't rely that it couldn't be set on - * the initial renegotiation too in certain cases (when - * there's some other reason to disallow resuming an - * earlier session -- the current code won't be doing - * anything like that, but this might change). - * - * A valid sign that there's been a previous handshake - * in this connection is if s->s3->tmp.finish_md_len > - * 0. (We are talking about a check that will happen - * in the Hello protocol round, well before a new - * Finished message could have been computed.) - */ + /* + * We shouldn't accept this extension on a + * renegotiation. + * + * s->new_session will be set on renegotiation, but we + * probably shouldn't rely that it couldn't be set on + * the initial renegotiation too in certain cases (when + * there's some other reason to disallow resuming an + * earlier session -- the current code won't be doing + * anything like that, but this might change). + * + * A valid sign that there's been a previous handshake + * in this connection is if s->s3->tmp.finish_md_len > + * 0. (We are talking about a check that will happen + * in the Hello protocol round, well before a new + * Finished message could have been computed.) + */ + if (s->s3->tmp.finish_md_len == 0) s->s3->next_proto_neg_seen = 1; - } return 1; } #endif /* - * Save the ALPN extension in a ClientHello. - * pkt: the contents of the ALPN extension, not including type and length. - * al: a pointer to the alert value to send in the event of a failure. - * returns: 1 on success, 0 on error. + * Save the ALPN extension in a ClientHello.|pkt| holds the contents of the ALPN + * extension, not including type and length. |al| is a pointer to the alert + * value to send in the event of a failure. Returns: 1 on success, 0 on error. */ -int tls_parse_client_alpn(SSL *s, PACKET *pkt, int *al) +int tls_parse_ctos_alpn(SSL *s, PACKET *pkt, int *al) { PACKET protocol_list, save_protocol_list, protocol; @@ -376,9 +373,8 @@ int tls_parse_client_alpn(SSL *s, PACKET *pkt, int *al) } #ifndef OPENSSL_NO_SRTP -int tls_parse_client_use_srtp(SSL *s, PACKET *pkt, int *al) +int tls_parse_ctos_use_srtp(SSL *s, PACKET *pkt, int *al) { - SRTP_PROTECTION_PROFILE *sprof; STACK_OF(SRTP_PROTECTION_PROFILE) *srvr; unsigned int ct, mki_len, id; int i, srtp_pref; @@ -389,8 +385,8 @@ int tls_parse_client_use_srtp(SSL *s, PACKET *pkt, int *al) return 1; /* Pull off the length of the cipher suite list and check it is even */ - if (!PACKET_get_net_2(pkt, &ct) - || (ct & 1) != 0 || !PACKET_get_sub_packet(pkt, &subpkt, ct)) { + if (!PACKET_get_net_2(pkt, &ct) || (ct & 1) != 0 + || !PACKET_get_sub_packet(pkt, &subpkt, ct)) { SSLerr(SSL_F_TLS_PARSE_CLIENT_USE_SRTP, SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST); *al = SSL_AD_DECODE_ERROR; @@ -417,7 +413,9 @@ int tls_parse_client_use_srtp(SSL *s, PACKET *pkt, int *al) * does nothing. */ for (i = 0; i < srtp_pref; i++) { - sprof = sk_SRTP_PROTECTION_PROFILE_value(srvr, i); + SRTP_PROTECTION_PROFILE *sprof = + sk_SRTP_PROTECTION_PROFILE_value(srvr, i); + if (sprof->id == id) { s->srtp_profile = sprof; srtp_pref = i; @@ -426,9 +424,7 @@ int tls_parse_client_use_srtp(SSL *s, PACKET *pkt, int *al) } } - /* - * Now extract the MKI value as a sanity check, but discard it for now - */ + /* Now extract the MKI value as a sanity check, but discard it for now */ if (!PACKET_get_1(pkt, &mki_len)) { SSLerr(SSL_F_TLS_PARSE_CLIENT_USE_SRTP, SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST); @@ -447,7 +443,7 @@ int tls_parse_client_use_srtp(SSL *s, PACKET *pkt, int *al) } #endif -int tls_parse_client_etm(SSL *s, PACKET *pkt, int *al) +int tls_parse_ctos_etm(SSL *s, PACKET *pkt, int *al) { if (!(s->options & SSL_OP_NO_ENCRYPT_THEN_MAC)) s->s3->flags |= TLS1_FLAGS_ENCRYPT_THEN_MAC; @@ -474,8 +470,8 @@ static int check_in_list(SSL *s, unsigned int group_id, unsigned int share_id = (groups[0] << 8) | (groups[1]); if (group_id == share_id - && (!checkallow || tls_curve_allowed(s, groups, - SSL_SECOP_CURVE_CHECK))) { + && (!checkallow + || tls_curve_allowed(s, groups, SSL_SECOP_CURVE_CHECK))) { break; } } @@ -489,7 +485,7 @@ static int check_in_list(SSL *s, unsigned int group_id, * the raw PACKET data for the extension. Returns 1 on success or 0 on failure. * If a failure occurs then |*al| is set to an appropriate alert value. */ -int tls_parse_client_key_share(SSL *s, PACKET *pkt, int *al) +int tls_parse_ctos_key_share(SSL *s, PACKET *pkt, int *al) { unsigned int group_id; PACKET key_share_list, encoded_pt; @@ -585,6 +581,7 @@ int tls_parse_client_key_share(SSL *s, PACKET *pkt, int *al) } else { /* Set up EVP_PKEY with named curve as parameters */ EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL); + if (pctx == NULL || EVP_PKEY_paramgen_init(pctx) <= 0 || EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx, @@ -615,7 +612,7 @@ int tls_parse_client_key_share(SSL *s, PACKET *pkt, int *al) } #ifndef OPENSSL_NO_EC -int tls_parse_client_supported_groups(SSL *s, PACKET *pkt, int *al) +int tls_parse_ctos_supported_groups(SSL *s, PACKET *pkt, int *al) { PACKET supported_groups_list; @@ -639,7 +636,7 @@ int tls_parse_client_supported_groups(SSL *s, PACKET *pkt, int *al) } #endif -int tls_parse_client_ems(SSL *s, PACKET *pkt, int *al) +int tls_parse_ctos_ems(SSL *s, PACKET *pkt, int *al) { /* The extension must always be empty */ if (PACKET_remaining(pkt) != 0) { @@ -652,8 +649,10 @@ int tls_parse_client_ems(SSL *s, PACKET *pkt, int *al) return 1; } -/* Add the server's renegotiation binding */ -int tls_construct_server_renegotiate(SSL *s, WPACKET *pkt, int *al) +/* + * Add the server's renegotiation binding + */ +int tls_construct_stoc_renegotiate(SSL *s, WPACKET *pkt, int *al) { if (!s->s3->send_connection_binding) return 1; @@ -674,7 +673,7 @@ int tls_construct_server_renegotiate(SSL *s, WPACKET *pkt, int *al) return 1; } -int tls_construct_server_server_name(SSL *s, WPACKET *pkt, int *al) +int tls_construct_stoc_server_name(SSL *s, WPACKET *pkt, int *al) { if (s->hit || s->servername_done != 1 || s->session->tlsext_hostname == NULL) @@ -690,7 +689,7 @@ int tls_construct_server_server_name(SSL *s, WPACKET *pkt, int *al) } #ifndef OPENSSL_NO_EC -int tls_construct_server_ec_pt_formats(SSL *s, WPACKET *pkt, int *al) +int tls_construct_stoc_ec_pt_formats(SSL *s, WPACKET *pkt, int *al) { unsigned long alg_k = s->s3->tmp.new_cipher->algorithm_mkey; unsigned long alg_a = s->s3->tmp.new_cipher->algorithm_auth; @@ -703,7 +702,6 @@ int tls_construct_server_ec_pt_formats(SSL *s, WPACKET *pkt, int *al) return 1; tls1_get_formatlist(s, &plist, &plistlen); - if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_ec_point_formats) || !WPACKET_start_sub_packet_u16(pkt) || !WPACKET_sub_memcpy_u8(pkt, plist, plistlen) @@ -716,7 +714,7 @@ int tls_construct_server_ec_pt_formats(SSL *s, WPACKET *pkt, int *al) } #endif -int tls_construct_server_session_ticket(SSL *s, WPACKET *pkt, int *al) +int tls_construct_stoc_session_ticket(SSL *s, WPACKET *pkt, int *al) { if (!s->tlsext_ticket_expected || !tls_use_ticket(s)) { s->tlsext_ticket_expected = 0; @@ -733,7 +731,7 @@ int tls_construct_server_session_ticket(SSL *s, WPACKET *pkt, int *al) } #ifndef OPENSSL_NO_OCSP -int tls_construct_server_status_request(SSL *s, WPACKET *pkt, int *al) +int tls_construct_stoc_status_request(SSL *s, WPACKET *pkt, int *al) { if (!s->tlsext_status_expected) return 1; @@ -750,7 +748,7 @@ int tls_construct_server_status_request(SSL *s, WPACKET *pkt, int *al) #ifndef OPENSSL_NO_NEXTPROTONEG -int tls_construct_server_next_proto_neg(SSL *s, WPACKET *pkt, int *al) +int tls_construct_stoc_next_proto_neg(SSL *s, WPACKET *pkt, int *al) { const unsigned char *npa; unsigned int npalen; @@ -777,7 +775,7 @@ int tls_construct_server_next_proto_neg(SSL *s, WPACKET *pkt, int *al) } #endif -int tls_construct_server_alpn(SSL *s, WPACKET *pkt, int *al) +int tls_construct_stoc_alpn(SSL *s, WPACKET *pkt, int *al) { if (s->s3->alpn_selected == NULL) return 1; @@ -798,7 +796,7 @@ int tls_construct_server_alpn(SSL *s, WPACKET *pkt, int *al) } #ifndef OPENSSL_NO_SRTP -int tls_construct_server_use_srtp(SSL *s, WPACKET *pkt, int *al) +int tls_construct_stoc_use_srtp(SSL *s, WPACKET *pkt, int *al) { if (s->srtp_profile == NULL) return 1; @@ -817,7 +815,7 @@ int tls_construct_server_use_srtp(SSL *s, WPACKET *pkt, int *al) } #endif -int tls_construct_server_etm(SSL *s, WPACKET *pkt, int *al) +int tls_construct_stoc_etm(SSL *s, WPACKET *pkt, int *al) { if ((s->s3->flags & TLS1_FLAGS_ENCRYPT_THEN_MAC) == 0) return 1; @@ -843,7 +841,7 @@ int tls_construct_server_etm(SSL *s, WPACKET *pkt, int *al) return 1; } -int tls_construct_server_ems(SSL *s, WPACKET *pkt, int *al) +int tls_construct_stoc_ems(SSL *s, WPACKET *pkt, int *al) { if ((s->s3->flags & TLS1_FLAGS_RECEIVED_EXTMS) == 0) return 1; @@ -857,7 +855,7 @@ int tls_construct_server_ems(SSL *s, WPACKET *pkt, int *al) return 1; } -int tls_construct_server_key_share(SSL *s, WPACKET *pkt, int *al) +int tls_construct_stoc_key_share(SSL *s, WPACKET *pkt, int *al) { unsigned char *encodedPoint; size_t encoded_pt_len = 0; @@ -911,7 +909,7 @@ int tls_construct_server_key_share(SSL *s, WPACKET *pkt, int *al) return 1; } -int tls_construct_server_cryptopro_bug(SSL *s, WPACKET *pkt, int *al) +int tls_construct_stoc_cryptopro_bug(SSL *s, WPACKET *pkt, int *al) { const unsigned char cryptopro_ext[36] = { 0xfd, 0xe8, /* 65000 */