From: Kurt Roeckx Date: Tue, 15 Jul 2025 09:38:21 +0000 (+0200) Subject: Remove support for SSLv2 Client Hello X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=09c2bc5f6c107ce97c396f2b7cc9118646085a0f;p=thirdparty%2Fopenssl.git Remove support for SSLv2 Client Hello Drop support for the SSLv2 Client Hello. We allowed that a client send an SSLv2 compatible Client Hello. Reviewed-by: Dmitry Belyavskiy Reviewed-by: Alicja Kario Reviewed-by: Tomas Mraz Reviewed-by: Matt Caswell (Merged from https://github.com/openssl/openssl/pull/28041) --- diff --git a/CHANGES.md b/CHANGES.md index 067a2b0752b..ff960d0dcc9 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -32,6 +32,15 @@ OpenSSL 4.0 ### Changes between 3.6 and 4.0 [xx XXX xxxx] + * Remove support for an SSLv2 Client Hello. When a client wanted to support + both SSLv2 and higher versions like SSLv3 or even TLSv1, it needed to + send an SSLv2 Client Hello. SSLv2 support itself was removed in version + 1.1.0, but there was still compatibility code for clients sending an SSLv2 + Client Hello. Since we no longer support SSLv2 Client Hello, + SSL_client_hello_isv2() is now deprecated and always returns 0. + + *Kurt Roeckx* + * Added "ML-DSA-MU" digest algorithm support. *Shane Lontis* diff --git a/NEWS.md b/NEWS.md index f966d8cfda5..30542709ce2 100644 --- a/NEWS.md +++ b/NEWS.md @@ -36,6 +36,8 @@ OpenSSL 4.0 * The crypto-mdebug-backtrace configuration option has been entirely removed. + * Support for the SSLv2 Client Hello was removed + OpenSSL 3.6 ----------- diff --git a/doc/man3/SSL_CTX_set_client_hello_cb.pod b/doc/man3/SSL_CTX_set_client_hello_cb.pod index 6367c68a625..41defadf306 100644 --- a/doc/man3/SSL_CTX_set_client_hello_cb.pod +++ b/doc/man3/SSL_CTX_set_client_hello_cb.pod @@ -9,7 +9,6 @@ SSL_CTX_set_client_hello_cb, SSL_client_hello_cb_fn, SSL_client_hello_isv2, SSL_ typedef int (*SSL_client_hello_cb_fn)(SSL *s, int *al, void *arg); void SSL_CTX_set_client_hello_cb(SSL_CTX *c, SSL_client_hello_cb_fn *f, void *arg); - int SSL_client_hello_isv2(SSL *s); unsigned int SSL_client_hello_get0_legacy_version(SSL *s); size_t SSL_client_hello_get0_random(SSL *s, const unsigned char **out); size_t SSL_client_hello_get0_session_id(SSL *s, const unsigned char **out); @@ -23,6 +22,12 @@ SSL_CTX_set_client_hello_cb, SSL_client_hello_cb_fn, SSL_client_hello_isv2, SSL_ int SSL_client_hello_get0_ext(SSL *s, unsigned int type, const unsigned char **out, size_t *outlen); +The following functions have been deprecated since OpenSSL 4.0, and can be +hidden entirely by defining B with a suitable version value, +see L: + + int SSL_client_hello_isv2(SSL *s); + =head1 DESCRIPTION SSL_CTX_set_client_hello_cb() sets the callback function, which is automatically @@ -40,14 +45,9 @@ function, the ClientHello callback will be called again, and, if it returns success, normal handshake processing will continue from that point. SSL_client_hello_isv2() indicates whether the ClientHello was carried in a -SSLv2 record and is in the SSLv2 format. The SSLv2 format has substantial -differences from the normal SSLv3 format, including using three bytes per -cipher suite, and not allowing extensions. Additionally, the SSLv2 format -'challenge' field is exposed via SSL_client_hello_get0_random(), padded to -SSL3_RANDOM_SIZE bytes with zeros if needed. For SSLv2 format ClientHellos, -SSL_client_hello_get0_compression_methods() returns a dummy list that only includes -the null compression method, since the SSLv2 format does not include a -mechanism by which to negotiate compression. +SSLv2 record and is in the SSLv2 format. +Support for the SSLv2 format was removed in 4.0 and this function +will always return 0. SSL_client_hello_get0_random(), SSL_client_hello_get0_session_id(), SSL_client_hello_get0_ciphers(), and @@ -117,7 +117,7 @@ The application's supplied ClientHello callback returns SSL_CLIENT_HELLO_SUCCESS on success, SSL_CLIENT_HELLO_ERROR on failure, and SSL_CLIENT_HELLO_RETRY to suspend processing. -SSL_client_hello_isv2() returns 1 for SSLv2-format ClientHellos and 0 otherwise. +SSL_client_hello_isv2() returns 0. SSL_client_hello_get0_random(), SSL_client_hello_get0_session_id(), SSL_client_hello_get0_ciphers(), and diff --git a/doc/man3/SSL_get_ciphers.pod b/doc/man3/SSL_get_ciphers.pod index add0fc4cd04..307f27e52d9 100644 --- a/doc/man3/SSL_get_ciphers.pod +++ b/doc/man3/SSL_get_ciphers.pod @@ -51,12 +51,13 @@ list received from the client on B. If B is NULL, no ciphers are available, or B is not operating in server mode, NULL is returned. SSL_bytes_to_cipher_list() treats the supplied B octets in B -as a wire-protocol cipher suite specification (in the three-octet-per-cipher -SSLv2 wire format if B is nonzero; otherwise the two-octet -SSLv3/TLS wire format), and parses the cipher suites supported by the library +as a wire-protocol cipher suite specification in the two-octet +SSLv3/TLS wire format, and parses the cipher suites supported by the library into the returned stacks of SSL_CIPHER objects sk and Signalling Cipher-Suite -Values scsvs. Unsupported cipher suites are ignored. Returns 1 on success -and 0 on failure. +Values scsvs. +The B is no longer supported and should always be set to 0. +Unsupported cipher suites are ignored. +Returns 1 on success and 0 on failure. SSL_get_cipher_list() returns a pointer to the name of the SSL_CIPHER listed for B with B. If B is NULL, no ciphers are diff --git a/include/openssl/ssl.h.in b/include/openssl/ssl.h.in index 7882b8bc674..83d72e6fa8c 100644 --- a/include/openssl/ssl.h.in +++ b/include/openssl/ssl.h.in @@ -1922,7 +1922,9 @@ typedef int (*SSL_new_pending_conn_cb_fn)(SSL_CTX *ctx, SSL *new_ssl, void SSL_CTX_set_new_pending_conn_cb(SSL_CTX *c, SSL_new_pending_conn_cb_fn cb, void *arg); -int SSL_client_hello_isv2(SSL *s); +#ifndef OPENSSL_NO_DEPRECATED_4_0 +OSSL_DEPRECATEDIN_4_0 int SSL_client_hello_isv2(SSL *s); +#endif unsigned int SSL_client_hello_get0_legacy_version(SSL *s); size_t SSL_client_hello_get0_random(SSL *s, const unsigned char **out); size_t SSL_client_hello_get0_session_id(SSL *s, const unsigned char **out); diff --git a/ssl/record/rec_layer_s3.c b/ssl/record/rec_layer_s3.c index f4b249bf324..670b03ab0bf 100644 --- a/ssl/record/rec_layer_s3.c +++ b/ssl/record/rec_layer_s3.c @@ -1122,17 +1122,6 @@ start: } } -/* - * Returns true if the current rrec was sent in SSLv2 backwards compatible - * format and false otherwise. - */ -int RECORD_LAYER_is_sslv2_record(RECORD_LAYER *rl) -{ - if (SSL_CONNECTION_IS_DTLS(rl->s)) - return 0; - return rl->tlsrecs[0].version == SSL2_VERSION; -} - static OSSL_FUNC_rlayer_msg_callback_fn rlayer_msg_callback_wrapper; static void rlayer_msg_callback_wrapper(int write_p, int version, int content_type, const void *buf, diff --git a/ssl/record/record.h b/ssl/record/record.h index 8e7b8838452..23c15f3b41b 100644 --- a/ssl/record/record.h +++ b/ssl/record/record.h @@ -140,7 +140,6 @@ int RECORD_LAYER_reset(RECORD_LAYER *rl); int RECORD_LAYER_read_pending(const RECORD_LAYER *rl); int RECORD_LAYER_processed_read_pending(const RECORD_LAYER *rl); int RECORD_LAYER_write_pending(const RECORD_LAYER *rl); -int RECORD_LAYER_is_sslv2_record(RECORD_LAYER *rl); __owur size_t ssl3_pending(const SSL *s); __owur int ssl3_write_bytes(SSL *s, uint8_t type, const void *buf, size_t len, size_t *written); diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c index e82ac8c0406..43ca1e46d73 100644 --- a/ssl/ssl_lib.c +++ b/ssl/ssl_lib.c @@ -6732,17 +6732,12 @@ void SSL_CTX_set_new_pending_conn_cb(SSL_CTX *c, SSL_new_pending_conn_cb_fn cb, c->new_pending_conn_arg = arg; } +#ifndef OPENSSL_NO_DEPRECATED_4_0 int SSL_client_hello_isv2(SSL *s) { - const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); - - if (sc == NULL) - return 0; - - if (sc->clienthello == NULL) - return 0; - return sc->clienthello->isv2; + return 0; } +#endif unsigned int SSL_client_hello_get0_legacy_version(SSL *s) { @@ -7045,20 +7040,14 @@ int ssl_log_secret(SSL_CONNECTION *sc, secret_len); } -#define SSLV2_CIPHER_LEN 3 - -int ssl_cache_cipherlist(SSL_CONNECTION *s, PACKET *cipher_suites, int sslv2format) +int ssl_cache_cipherlist(SSL_CONNECTION *s, PACKET *cipher_suites) { - int n; - - n = sslv2format ? SSLV2_CIPHER_LEN : TLS_CIPHER_LEN; - if (PACKET_remaining(cipher_suites) == 0) { SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_NO_CIPHERS_SPECIFIED); return 0; } - if (PACKET_remaining(cipher_suites) % n != 0) { + if (PACKET_remaining(cipher_suites) % TLS_CIPHER_LEN != 0) { SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST); return 0; } @@ -7067,45 +7056,8 @@ int ssl_cache_cipherlist(SSL_CONNECTION *s, PACKET *cipher_suites, int sslv2form s->s3.tmp.ciphers_raw = NULL; s->s3.tmp.ciphers_rawlen = 0; - if (sslv2format) { - size_t numciphers = PACKET_remaining(cipher_suites) / n; - PACKET sslv2ciphers = *cipher_suites; - unsigned int leadbyte; - unsigned char *raw; - - /* - * We store the raw ciphers list in SSLv3+ format so we need to do some - * preprocessing to convert the list first. If there are any SSLv2 only - * ciphersuites with a non-zero leading byte then we are going to - * slightly over allocate because we won't store those. But that isn't a - * problem. - */ - raw = OPENSSL_malloc_array(numciphers, TLS_CIPHER_LEN); - s->s3.tmp.ciphers_raw = raw; - if (raw == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_CRYPTO_LIB); - return 0; - } - for (s->s3.tmp.ciphers_rawlen = 0; - PACKET_remaining(&sslv2ciphers) > 0; - raw += TLS_CIPHER_LEN) { - if (!PACKET_get_1(&sslv2ciphers, &leadbyte) - || (leadbyte == 0 - && !PACKET_copy_bytes(&sslv2ciphers, raw, - TLS_CIPHER_LEN)) - || (leadbyte != 0 - && !PACKET_forward(&sslv2ciphers, TLS_CIPHER_LEN))) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_PACKET); - OPENSSL_free(s->s3.tmp.ciphers_raw); - s->s3.tmp.ciphers_raw = NULL; - s->s3.tmp.ciphers_rawlen = 0; - return 0; - } - if (leadbyte == 0) - s->s3.tmp.ciphers_rawlen += TLS_CIPHER_LEN; - } - } else if (!PACKET_memdup(cipher_suites, &s->s3.tmp.ciphers_raw, - &s->s3.tmp.ciphers_rawlen)) { + if (!PACKET_memdup(cipher_suites, &s->s3.tmp.ciphers_raw, + &s->s3.tmp.ciphers_rawlen)) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } @@ -7119,27 +7071,24 @@ int SSL_bytes_to_cipher_list(SSL *s, const unsigned char *bytes, size_t len, PACKET pkt; SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); - if (sc == NULL) + if (sc == NULL || isv2format) return 0; if (!PACKET_buf_init(&pkt, bytes, len)) return 0; - return ossl_bytes_to_cipher_list(sc, &pkt, sk, scsvs, isv2format, 0); + return ossl_bytes_to_cipher_list(sc, &pkt, sk, scsvs, 0); } int ossl_bytes_to_cipher_list(SSL_CONNECTION *s, PACKET *cipher_suites, STACK_OF(SSL_CIPHER) **skp, STACK_OF(SSL_CIPHER) **scsvs_out, - int sslv2format, int fatal) + int fatal) { const SSL_CIPHER *c; STACK_OF(SSL_CIPHER) *sk = NULL; STACK_OF(SSL_CIPHER) *scsvs = NULL; - int n; - /* 3 = SSLV2_CIPHER_LEN > TLS_CIPHER_LEN = 2. */ - unsigned char cipher[SSLV2_CIPHER_LEN]; - - n = sslv2format ? SSLV2_CIPHER_LEN : TLS_CIPHER_LEN; + int n = TLS_CIPHER_LEN; + unsigned char cipher[TLS_CIPHER_LEN]; if (PACKET_remaining(cipher_suites) == 0) { if (fatal) @@ -7169,16 +7118,7 @@ int ossl_bytes_to_cipher_list(SSL_CONNECTION *s, PACKET *cipher_suites, } while (PACKET_copy_bytes(cipher_suites, cipher, n)) { - /* - * SSLv3 ciphers wrapped in an SSLv2-compatible ClientHello have the - * first byte set to zero, while true SSLv2 ciphers have a non-zero - * first byte. We don't support any true SSLv2 ciphers, so skip them. - */ - if (sslv2format && cipher[0] != '\0') - continue; - - /* For SSLv2-compat, ignore leading 0-byte. */ - c = ssl_get_cipher_by_char(s, sslv2format ? &cipher[1] : cipher, 1); + c = ssl_get_cipher_by_char(s, cipher, 1); if (c != NULL) { if ((c->valid && !sk_SSL_CIPHER_push(sk, c)) || (!c->valid && !sk_SSL_CIPHER_push(scsvs, c))) { if (fatal) diff --git a/ssl/ssl_local.h b/ssl/ssl_local.h index 994bfb79431..606fded1118 100644 --- a/ssl/ssl_local.h +++ b/ssl/ssl_local.h @@ -639,7 +639,6 @@ typedef struct raw_extension_st { } RAW_EXTENSION; typedef struct { - unsigned int isv2; unsigned int legacy_version; unsigned char random[SSL3_RANDOM_SIZE]; size_t session_id_len; @@ -2506,11 +2505,10 @@ __owur STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(SSL_CTX *ctx, STACK_OF(SSL_CIPHER) **cipher_list_by_id, const char *rule_str, CERT *c); -__owur int ssl_cache_cipherlist(SSL_CONNECTION *s, PACKET *cipher_suites, - int sslv2format); +__owur int ssl_cache_cipherlist(SSL_CONNECTION *s, PACKET *cipher_suites); __owur int ossl_bytes_to_cipher_list(SSL_CONNECTION *s, PACKET *cipher_suites, STACK_OF(SSL_CIPHER) **skp, - STACK_OF(SSL_CIPHER) **scsvs, int sslv2format, + STACK_OF(SSL_CIPHER) **scsvs, int fatal); void ssl_update_cache(SSL_CONNECTION *s, int mode); __owur int ssl_cipher_get_evp_cipher(SSL_CTX *ctx, const SSL_CIPHER *sslc, diff --git a/ssl/statem/statem_lib.c b/ssl/statem/statem_lib.c index 9e0c853c0d2..3e3d00a8bec 100644 --- a/ssl/statem/statem_lib.c +++ b/ssl/statem/statem_lib.c @@ -1595,32 +1595,16 @@ int tls_get_message_header(SSL_CONNECTION *s, int *mt) *mt = *p; s->s3.tmp.message_type = *(p++); - if (RECORD_LAYER_is_sslv2_record(&s->rlayer)) { - /* - * Only happens with SSLv3+ in an SSLv2 backward compatible - * ClientHello - * - * Total message size is the remaining record bytes to read - * plus the SSL3_HM_HEADER_LENGTH bytes that we already read - */ - l = s->rlayer.tlsrecs[0].length + SSL3_HM_HEADER_LENGTH; - s->s3.tmp.message_size = l; - - s->init_msg = s->init_buf->data; - s->init_num = SSL3_HM_HEADER_LENGTH; - } else { - n2l3(p, l); - /* BUF_MEM_grow takes an 'int' parameter */ - if (l > (INT_MAX - SSL3_HM_HEADER_LENGTH)) { - SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, - SSL_R_EXCESSIVE_MESSAGE_SIZE); - return 0; - } - s->s3.tmp.message_size = l; - - s->init_msg = s->init_buf->data + SSL3_HM_HEADER_LENGTH; - s->init_num = 0; + n2l3(p, l); + /* BUF_MEM_grow takes an 'int' parameter */ + if (l > (INT_MAX - SSL3_HM_HEADER_LENGTH)) { + SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_EXCESSIVE_MESSAGE_SIZE); + return 0; } + s->s3.tmp.message_size = l; + + s->init_msg = s->init_buf->data + SSL3_HM_HEADER_LENGTH; + s->init_num = 0; return 1; } @@ -1663,48 +1647,35 @@ int tls_get_message_body(SSL_CONNECTION *s, size_t *len) return 0; } - /* Feed this message into MAC computation. */ - if (RECORD_LAYER_is_sslv2_record(&s->rlayer)) { - if (!ssl3_finish_mac(s, (unsigned char *)s->init_buf->data, - s->init_num)) { - /* SSLfatal() already called */ - *len = 0; - return 0; - } - if (s->msg_callback) - s->msg_callback(0, SSL2_VERSION, 0, s->init_buf->data, - (size_t)s->init_num, ussl, s->msg_callback_arg); - } else { - /* - * We defer feeding in the HRR until later. We'll do it as part of - * processing the message - * The TLsv1.3 handshake transcript stops at the ClientFinished - * message. - */ + /* + * We defer feeding in the HRR until later. We'll do it as part of + * processing the message + * The TLsv1.3 handshake transcript stops at the ClientFinished + * message. + */ #define SERVER_HELLO_RANDOM_OFFSET (SSL3_HM_HEADER_LENGTH + 2) - /* KeyUpdate and NewSessionTicket do not need to be added */ - if (!SSL_CONNECTION_IS_TLS13(s) - || (s->s3.tmp.message_type != SSL3_MT_NEWSESSION_TICKET - && s->s3.tmp.message_type != SSL3_MT_KEY_UPDATE)) { - if (s->s3.tmp.message_type != SSL3_MT_SERVER_HELLO - || s->init_num < SERVER_HELLO_RANDOM_OFFSET + SSL3_RANDOM_SIZE - || memcmp(hrrrandom, - s->init_buf->data + SERVER_HELLO_RANDOM_OFFSET, - SSL3_RANDOM_SIZE) - != 0) { - if (!ssl3_finish_mac(s, (unsigned char *)s->init_buf->data, - s->init_num + SSL3_HM_HEADER_LENGTH)) { - /* SSLfatal() already called */ - *len = 0; - return 0; - } + /* KeyUpdate and NewSessionTicket do not need to be added */ + if (!SSL_CONNECTION_IS_TLS13(s) + || (s->s3.tmp.message_type != SSL3_MT_NEWSESSION_TICKET + && s->s3.tmp.message_type != SSL3_MT_KEY_UPDATE)) { + if (s->s3.tmp.message_type != SSL3_MT_SERVER_HELLO + || s->init_num < SERVER_HELLO_RANDOM_OFFSET + SSL3_RANDOM_SIZE + || memcmp(hrrrandom, + s->init_buf->data + SERVER_HELLO_RANDOM_OFFSET, + SSL3_RANDOM_SIZE) + != 0) { + if (!ssl3_finish_mac(s, (unsigned char *)s->init_buf->data, + s->init_num + SSL3_HM_HEADER_LENGTH)) { + /* SSLfatal() already called */ + *len = 0; + return 0; } } - if (s->msg_callback) - s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, s->init_buf->data, - (size_t)s->init_num + SSL3_HM_HEADER_LENGTH, ussl, - s->msg_callback_arg); } + if (s->msg_callback) + s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, s->init_buf->data, + (size_t)s->init_num + SSL3_HM_HEADER_LENGTH, ussl, + s->msg_callback_arg); *len = s->init_num; return 1; diff --git a/ssl/statem/statem_srvr.c b/ssl/statem/statem_srvr.c index db99d49706e..bdb46716ef6 100644 --- a/ssl/statem/statem_srvr.c +++ b/ssl/statem/statem_srvr.c @@ -1627,7 +1627,6 @@ MSG_PROCESS_RETURN tls_process_client_hello(SSL_CONNECTION *s, PACKET *pkt) { /* |cookie| will only be initialized for DTLS. */ PACKET session_id, compression, extensions, cookie; - static const unsigned char null_compression = 0; CLIENTHELLO_MSG *clienthello = NULL; /* Check if this is actually an unexpected renegotiation ClientHello */ @@ -1657,156 +1656,65 @@ MSG_PROCESS_RETURN tls_process_client_hello(SSL_CONNECTION *s, PACKET *pkt) /* * First, parse the raw ClientHello data into the CLIENTHELLO_MSG structure. */ - clienthello->isv2 = RECORD_LAYER_is_sslv2_record(&s->rlayer); PACKET_null_init(&cookie); - if (clienthello->isv2) { - unsigned int mt; - - if (!SSL_IS_FIRST_HANDSHAKE(s) - || s->hello_retry_request != SSL_HRR_NONE) { - SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_R_UNEXPECTED_MESSAGE); - goto err; - } - - /*- - * An SSLv3/TLSv1 backwards-compatible CLIENT-HELLO in an SSLv2 - * header is sent directly on the wire, not wrapped as a TLS - * record. Our record layer just processes the message length and passes - * the rest right through. Its format is: - * Byte Content - * 0-1 msg_length - decoded by the record layer - * 2 msg_type - s->init_msg points here - * 3-4 version - * 5-6 cipher_spec_length - * 7-8 session_id_length - * 9-10 challenge_length - * ... ... - */ - - if (!PACKET_get_1(pkt, &mt) - || mt != SSL2_MT_CLIENT_HELLO) { - /* - * Should never happen. We should have tested this in the record - * layer in order to have determined that this is an SSLv2 record - * in the first place - */ - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - goto err; - } - } - if (!PACKET_get_net_2(pkt, &clienthello->legacy_version)) { SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_TOO_SHORT); goto err; } - /* Parse the message and load client random. */ - if (clienthello->isv2) { - /* - * Handle an SSLv2 backwards compatible ClientHello - * Note, this is only for SSLv3+ using the backward compatible format. - * Real SSLv2 is not supported, and is rejected below. - */ - unsigned int ciphersuite_len, session_id_len, challenge_len; - PACKET challenge; - - if (!PACKET_get_net_2(pkt, &ciphersuite_len) - || !PACKET_get_net_2(pkt, &session_id_len) - || !PACKET_get_net_2(pkt, &challenge_len)) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_RECORD_LENGTH_MISMATCH); - goto err; - } - - if (session_id_len > SSL_MAX_SSL_SESSION_ID_LENGTH) { - SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_LENGTH_MISMATCH); - goto err; - } + if (!PACKET_copy_bytes(pkt, clienthello->random, SSL3_RANDOM_SIZE) + || !PACKET_get_length_prefixed_1(pkt, &session_id) + || !PACKET_copy_all(&session_id, clienthello->session_id, + SSL_MAX_SSL_SESSION_ID_LENGTH, + &clienthello->session_id_len)) { + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_MISMATCH); + goto err; + } - if (!PACKET_get_sub_packet(pkt, &clienthello->ciphersuites, - ciphersuite_len) - || !PACKET_copy_bytes(pkt, clienthello->session_id, session_id_len) - || !PACKET_get_sub_packet(pkt, &challenge, challenge_len) - /* No extensions. */ - || PACKET_remaining(pkt) != 0) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_RECORD_LENGTH_MISMATCH); + if (SSL_CONNECTION_IS_DTLS(s)) { + if (!PACKET_get_length_prefixed_1(pkt, &cookie)) { + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_MISMATCH); goto err; } - clienthello->session_id_len = session_id_len; - - /* Load the client random and compression list. We use SSL3_RANDOM_SIZE - * here rather than sizeof(clienthello->random) because that is the limit - * for SSLv3 and it is fixed. It won't change even if - * sizeof(clienthello->random) does. - */ - challenge_len = challenge_len > SSL3_RANDOM_SIZE - ? SSL3_RANDOM_SIZE - : challenge_len; - memset(clienthello->random, 0, SSL3_RANDOM_SIZE); - if (!PACKET_copy_bytes(&challenge, - clienthello->random + SSL3_RANDOM_SIZE - challenge_len, challenge_len) - /* Advertise only null compression. */ - || !PACKET_buf_init(&compression, &null_compression, 1)) { + if (!PACKET_copy_all(&cookie, clienthello->dtls_cookie, + DTLS1_COOKIE_LENGTH, + &clienthello->dtls_cookie_len)) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } - - PACKET_null_init(&clienthello->extensions); - } else { - /* Regular ClientHello. */ - if (!PACKET_copy_bytes(pkt, clienthello->random, SSL3_RANDOM_SIZE) - || !PACKET_get_length_prefixed_1(pkt, &session_id) - || !PACKET_copy_all(&session_id, clienthello->session_id, - SSL_MAX_SSL_SESSION_ID_LENGTH, - &clienthello->session_id_len)) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_MISMATCH); - goto err; - } - - if (SSL_CONNECTION_IS_DTLS(s)) { - if (!PACKET_get_length_prefixed_1(pkt, &cookie)) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_MISMATCH); - goto err; - } - if (!PACKET_copy_all(&cookie, clienthello->dtls_cookie, - sizeof(clienthello->dtls_cookie), - &clienthello->dtls_cookie_len)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - goto err; - } - /* - * If we require cookies and this ClientHello doesn't contain one, - * just return since we do not want to allocate any memory yet. - * So check cookie length... - */ - if (SSL_get_options(SSL_CONNECTION_GET_SSL(s)) & SSL_OP_COOKIE_EXCHANGE) { - if (clienthello->dtls_cookie_len == 0) { - OPENSSL_free(clienthello); - return MSG_PROCESS_FINISHED_READING; - } + /* + * If we require cookies and this ClientHello doesn't contain one, + * just return since we do not want to allocate any memory yet. + * So check cookie length... + */ + if (SSL_get_options(SSL_CONNECTION_GET_SSL(s)) & SSL_OP_COOKIE_EXCHANGE) { + if (clienthello->dtls_cookie_len == 0) { + OPENSSL_free(clienthello); + return MSG_PROCESS_FINISHED_READING; } } + } - if (!PACKET_get_length_prefixed_2(pkt, &clienthello->ciphersuites)) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_MISMATCH); - goto err; - } + if (!PACKET_get_length_prefixed_2(pkt, &clienthello->ciphersuites)) { + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_MISMATCH); + goto err; + } - if (!PACKET_get_length_prefixed_1(pkt, &compression)) { + if (!PACKET_get_length_prefixed_1(pkt, &compression)) { + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_MISMATCH); + goto err; + } + + /* Could be empty. */ + if (PACKET_remaining(pkt) == 0) { + PACKET_null_init(&clienthello->extensions); + } else { + if (!PACKET_get_length_prefixed_2(pkt, &clienthello->extensions) + || PACKET_remaining(pkt) != 0) { SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_MISMATCH); goto err; } - - /* Could be empty. */ - if (PACKET_remaining(pkt) == 0) { - PACKET_null_init(&clienthello->extensions); - } else { - if (!PACKET_get_length_prefixed_2(pkt, &clienthello->extensions) - || PACKET_remaining(pkt) != 0) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_MISMATCH); - goto err; - } - } } if (!PACKET_copy_all(&compression, clienthello->compressions, @@ -1874,23 +1782,6 @@ static int tls_early_post_process_client_hello(SSL_CONNECTION *s) /* Set up the client_random */ memcpy(s->s3.client_random, clienthello->random, SSL3_RANDOM_SIZE); - /* Choose the version */ - - if (clienthello->isv2) { - if (clienthello->legacy_version == SSL2_VERSION - || (clienthello->legacy_version & 0xff00) - != (SSL3_VERSION_MAJOR << 8)) { - /* - * This is real SSLv2 or something completely unknown. We don't - * support it. - */ - SSLfatal(s, SSL_AD_PROTOCOL_VERSION, SSL_R_UNKNOWN_PROTOCOL); - goto err; - } - /* SSLv3/TLS */ - s->client_version = clienthello->legacy_version; - } - /* Choose the server SSL/TLS/DTLS version. */ protverr = ssl_choose_server_version(s, clienthello, &dgrd); @@ -1936,10 +1827,8 @@ static int tls_early_post_process_client_hello(SSL_CONNECTION *s) s->hit = 0; - if (!ssl_cache_cipherlist(s, &clienthello->ciphersuites, - clienthello->isv2) - || !ossl_bytes_to_cipher_list(s, &clienthello->ciphersuites, &ciphers, - &scsvs, clienthello->isv2, 1)) { + if (!ssl_cache_cipherlist(s, &clienthello->ciphersuites) + || !ossl_bytes_to_cipher_list(s, &clienthello->ciphersuites, &ciphers, &scsvs, 1)) { /* SSLfatal() already called */ goto err; } @@ -2017,7 +1906,7 @@ static int tls_early_post_process_client_hello(SSL_CONNECTION *s) * SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION setting will be * ignored. */ - if (clienthello->isv2 || (s->new_session && (s->options & SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION))) { + if (s->new_session && (s->options & SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION)) { if (!ssl_get_new_session(s, 1)) { /* SSLfatal() already called */ goto err; diff --git a/test/cipherbytes_test.c b/test/cipherbytes_test.c index 3e73781cfed..981a9cc13bc 100644 --- a/test/cipherbytes_test.c +++ b/test/cipherbytes_test.c @@ -66,38 +66,6 @@ err: return ret; } -static int test_v2(void) -{ - STACK_OF(SSL_CIPHER) *sk, *scsv; - /* ECDHE-ECDSA-AES256GCM, SSL2_RC4_1238_WITH_MD5, - * ECDHE-ECDSA-CHACHA20-POLY1305 */ - const unsigned char bytes[] = { 0x00, 0x00, 0x35, 0x01, 0x00, 0x80, - 0x00, 0x00, 0x33 }; - int ret = 0; - - if (!TEST_true(SSL_bytes_to_cipher_list(s, bytes, sizeof(bytes), 1, - &sk, &scsv)) - || !TEST_ptr(sk) - || !TEST_int_eq(sk_SSL_CIPHER_num(sk), 2) - || !TEST_ptr(scsv) - || !TEST_int_eq(sk_SSL_CIPHER_num(scsv), 0)) - goto err; - if (strcmp(SSL_CIPHER_get_name(sk_SSL_CIPHER_value(sk, 0)), - "AES256-SHA") - != 0 - || strcmp(SSL_CIPHER_get_name(sk_SSL_CIPHER_value(sk, 1)), - "DHE-RSA-AES128-SHA") - != 0) - goto err; - - ret = 1; - -err: - sk_SSL_CIPHER_free(sk); - sk_SSL_CIPHER_free(scsv); - return ret; -} - static int test_v3(void) { STACK_OF(SSL_CIPHER) *sk = NULL, *scsv = NULL; @@ -139,7 +107,6 @@ int setup_tests(void) ADD_TEST(test_empty); ADD_TEST(test_unsupported); - ADD_TEST(test_v2); ADD_TEST(test_v3); return 1; } diff --git a/test/recipes/70-test_sslrecords.t b/test/recipes/70-test_sslrecords.t index fe26564d506..4f909295600 100644 --- a/test/recipes/70-test_sslrecords.t +++ b/test/recipes/70-test_sslrecords.t @@ -33,20 +33,19 @@ my $inject_recs_num = undef; my $content_type = undef; my $boundary_test_type = undef; my $fatal_alert = undef; # set by filters at expected fatal alerts -my $sslv2testtype = undef; my $proxy_start_success = 0; -plan tests => 44; +plan tests => 34; SKIP: { - skip "TLS 1.2 is disabled", 22 if disabled("tls1_2"); + skip "TLS 1.2 is disabled", 17 if disabled("tls1_2"); # Run tests with TLS run_tests(0); } SKIP: { - skip "DTLS 1.2 is disabled", 22 if disabled("dtls1_2"); - skip "DTLSProxy does not work on Windows", 22 if $^O =~ /^(MSWin32)$/; + skip "DTLS 1.2 is disabled", 17 if disabled("dtls1_2"); + skip "DTLSProxy does not work on Windows", 17 if $^O =~ /^(MSWin32)$/; run_tests(1); } @@ -107,7 +106,7 @@ sub run_tests "In context empty records test".($run_test_as_dtls == 1) ? " for DTLS" : " for TLS"); SKIP: { - skip "Record tests not intended for dtls", 7 if $run_test_as_dtls == 1; + skip "Record tests not intended for dtls", 2 if $run_test_as_dtls == 1; #Test 3: Injecting too many in context empty records should fail $fatal_alert = 0; $proxy->clear(); @@ -128,76 +127,10 @@ sub run_tests $proxy->clientflags("-no_tls1_3"); $proxy->start(); ok($fatal_alert, "Fragmented alert records test"); - - #Run some SSLv2 ClientHello tests - - use constant { - TLSV1_2_IN_SSLV2 => 0, - SSLV2_IN_SSLV2 => 1, - FRAGMENTED_IN_TLSV1_2 => 2, - FRAGMENTED_IN_SSLV2 => 3, - ALERT_BEFORE_SSLV2 => 4 - }; - - # The TLSv1.2 in SSLv2 ClientHello need to run at security level 0 - # because in a SSLv2 ClientHello we can't send extensions to indicate - # which signature algorithm we want to use, and the default is SHA1. - - #Test 5: Inject an SSLv2 style record format for a TLSv1.2 ClientHello - $sslv2testtype = TLSV1_2_IN_SSLV2; - $proxy->clear(); - $proxy->filter(\&add_sslv2_filter); - $proxy->serverflags("-tls1_2"); - $proxy->clientflags("-no_tls1_3 -legacy_renegotiation"); - $proxy->ciphers("AES128-SHA:\@SECLEVEL=0"); - $proxy->start(); - ok(TLSProxy::Message->success(), "TLSv1.2 in SSLv2 ClientHello test"); - - #Test 6: Inject an SSLv2 style record format for an SSLv2 ClientHello. We don't - # support this so it should fail. We actually treat it as an unknown - # protocol so we don't even send an alert in this case. - $sslv2testtype = SSLV2_IN_SSLV2; - $proxy->clear(); - $proxy->serverflags("-tls1_2"); - $proxy->clientflags("-no_tls1_3"); - $proxy->ciphers("AES128-SHA:\@SECLEVEL=0"); - $proxy->start(); - ok(TLSProxy::Message->fail(), "SSLv2 in SSLv2 ClientHello test"); - - #Test 7: Sanity check ClientHello fragmentation. This isn't really an SSLv2 test - # at all, but it gives us confidence that Test 8 fails for the right - # reasons - $sslv2testtype = FRAGMENTED_IN_TLSV1_2; - $proxy->clear(); - $proxy->serverflags("-tls1_2"); - $proxy->clientflags("-no_tls1_3"); - $proxy->ciphers("AES128-SHA:\@SECLEVEL=0"); - $proxy->start(); - ok(TLSProxy::Message->success(), "Fragmented ClientHello in TLSv1.2 test"); - - #Test 8: Fragment a TLSv1.2 ClientHello across a TLS1.2 record; an SSLv2 - # record; and another TLS1.2 record. This isn't allowed so should fail - $sslv2testtype = FRAGMENTED_IN_SSLV2; - $proxy->clear(); - $proxy->serverflags("-tls1_2"); - $proxy->clientflags("-no_tls1_3"); - $proxy->ciphers("AES128-SHA:\@SECLEVEL=0"); - $proxy->start(); - ok(TLSProxy::Message->fail(), "Fragmented ClientHello in TLSv1.2/SSLv2 test"); - - #Test 9: Send a TLS warning alert before an SSLv2 ClientHello. This should - # fail because an SSLv2 ClientHello must be the first record. - $sslv2testtype = ALERT_BEFORE_SSLV2; - $proxy->clear(); - $proxy->serverflags("-tls1_2"); - $proxy->clientflags("-no_tls1_3"); - $proxy->ciphers("AES128-SHA:\@SECLEVEL=0"); - $proxy->start(); - ok(TLSProxy::Message->fail(), "Alert before SSLv2 ClientHello test"); } #Unrecognised record type tests - #Test 10: Sending an unrecognised record type in TLS1.2 should fail + #Test 5: Sending an unrecognised record type in TLS1.2 should fail $fatal_alert = 0; $proxy->clear(); if ($run_test_as_dtls == 1) { @@ -220,7 +153,7 @@ sub run_tests skip "TLSv1.1 or DTLSv1 disabled", 1 if ($run_test_as_dtls == 0 && disabled("tls1_1")) || ($run_test_as_dtls == 1 && disabled("dtls1")); - #Test 11: Sending an unrecognised record type in TLS1.1 should fail + #Test 6: Sending an unrecognised record type in TLS1.1 should fail $fatal_alert = 0; $proxy->clear(); if ($run_test_as_dtls == 1) { @@ -239,7 +172,7 @@ sub run_tests SKIP: { skip "Record tests not intended for dtls", 10 if $run_test_as_dtls == 1; - #Test 12: Sending a different record version in TLS1.2 should fail + #Test 7: Sending a different record version in TLS1.2 should fail $fatal_alert = 0; $proxy->clear(); $proxy->clientflags("-tls1_2"); @@ -252,20 +185,20 @@ sub run_tests skip "TLSv1.3 disabled", 9 if disabled("tls1_3") || (disabled("ec") && disabled("dh")); - #Test 13: Sending a different record version in TLS1.3 should fail + #Test 8: Sending a different record version in TLS1.3 should fail $proxy->clear(); $proxy->filter(\&change_version); $proxy->start(); ok(TLSProxy::Message->fail(), "Changed record version in TLS1.3"); - #Test 14: Sending an unrecognised record type in TLS1.3 should fail + #Test 9: Sending an unrecognised record type in TLS1.3 should fail $fatal_alert = 0; $proxy->clear(); $proxy->filter(\&add_unknown_record_type); $proxy->start(); ok($fatal_alert, "Unrecognised record type in TLS1.3"); - #Test 15: Sending an outer record type other than app data once encrypted + #Test 10: Sending an outer record type other than app data once encrypted #should fail $fatal_alert = 0; $proxy->clear(); @@ -281,7 +214,7 @@ sub run_tests NO_DATA_BETWEEN_KEY_UPDATE => 4, }; - #Test 16: Sending a ServerHello which doesn't end on a record boundary + #Test 11: Sending a ServerHello which doesn't end on a record boundary # should fail $fatal_alert = 0; $proxy->clear(); @@ -290,7 +223,7 @@ sub run_tests $proxy->start(); ok($fatal_alert, "Record not on boundary in TLS1.3 (ServerHello)"); - #Test 17: Sending a Finished which doesn't end on a record boundary + #Test 12: Sending a Finished which doesn't end on a record boundary # should fail $fatal_alert = 0; $proxy->clear(); @@ -298,7 +231,7 @@ sub run_tests $proxy->start(); ok($fatal_alert, "Record not on boundary in TLS1.3 (Finished)"); - #Test 18: Sending a KeyUpdate which doesn't end on a record boundary + #Test 13: Sending a KeyUpdate which doesn't end on a record boundary # should fail $fatal_alert = 0; $proxy->clear(); @@ -306,7 +239,7 @@ sub run_tests $proxy->start(); ok($fatal_alert, "Record not on boundary in TLS1.3 (KeyUpdate)"); - #Test 19: Sending application data in the middle of a fragmented KeyUpdate + #Test 14: Sending application data in the middle of a fragmented KeyUpdate # should fail. Strictly speaking this is not a record boundary test # but we use the same filter. $fatal_alert = 0; @@ -315,7 +248,7 @@ sub run_tests $proxy->start(); ok($fatal_alert, "Data between KeyUpdate"); - #Test 20: Fragmented KeyUpdate. This should succeed. Strictly speaking this + #Test 15: Fragmented KeyUpdate. This should succeed. Strictly speaking this # is not a record boundary test but we use the same filter. $proxy->clear(); $boundary_test_type = NO_DATA_BETWEEN_KEY_UPDATE; @@ -325,7 +258,7 @@ sub run_tests SKIP: { skip "EC disabled", 1 if disabled("ec"); - #Test 21: Force an HRR and change the "real" ServerHello to have a protocol + #Test 16: Force an HRR and change the "real" ServerHello to have a protocol # record version of 0x0301 (TLSv1.0). At this point we have already # decided that we are doing TLSv1.3 but are still using plaintext # records. The server should be sending a record version of 0x303 @@ -342,7 +275,7 @@ sub run_tests SKIP: { skip "DTLS only record tests", 1 if $run_test_as_dtls != 1; - #Test 22: We should ignore empty app data records + #Test 17: We should ignore empty app data records $proxy->clear(); $proxy->filter(\&empty_app_data); $proxy->start(); @@ -452,153 +385,6 @@ sub add_frag_alert_filter push @{$records}, $record; } -sub add_sslv2_filter -{ - my $proxy = shift; - my $clienthello; - my $record; - - # We're only interested in the initial ClientHello - if ($proxy->flight != 0) { - return; - } - - # Ditch the real ClientHello - we're going to replace it with our own - shift @{$proxy->record_list}; - - if ($sslv2testtype == ALERT_BEFORE_SSLV2) { - my $alert = pack('CC', TLSProxy::Message::AL_LEVEL_FATAL, - TLSProxy::Message::AL_DESC_NO_RENEGOTIATION); - my $alertlen = length $alert; - $record = TLSProxy::Record->new( - 0, - TLSProxy::Record::RT_ALERT, - TLSProxy::Record::VERS_TLS_1_2, - $alertlen, - 0, - $alertlen, - $alertlen, - $alert, - $alert - ); - - push @{$proxy->record_list}, $record; - } - - if ($sslv2testtype == ALERT_BEFORE_SSLV2 - || $sslv2testtype == TLSV1_2_IN_SSLV2 - || $sslv2testtype == SSLV2_IN_SSLV2) { - # This is an SSLv2 format ClientHello - $clienthello = - pack "C44", - 0x01, # ClientHello - 0x03, 0x03, #TLSv1.2 - 0x00, 0x03, # Ciphersuites len - 0x00, 0x00, # Session id len - 0x00, 0x20, # Challenge len - 0x00, 0x00, 0x2f, #AES128-SHA - 0x01, 0x18, 0x9F, 0x76, 0xEC, 0x57, 0xCE, 0xE5, 0xB3, 0xAB, 0x79, 0x90, - 0xAD, 0xAC, 0x6E, 0xD1, 0x58, 0x35, 0x03, 0x97, 0x16, 0x10, 0x82, 0x56, - 0xD8, 0x55, 0xFF, 0xE1, 0x8A, 0xA3, 0x2E, 0xF6; # Challenge - - if ($sslv2testtype == SSLV2_IN_SSLV2) { - # Set the version to "real" SSLv2 - vec($clienthello, 1, 8) = 0x00; - vec($clienthello, 2, 8) = 0x02; - } - - my $chlen = length $clienthello; - - $record = TLSProxy::Record->new( - 0, - TLSProxy::Record::RT_HANDSHAKE, - TLSProxy::Record::VERS_TLS_1_2, - $chlen, - 1, #SSLv2 - $chlen, - $chlen, - $clienthello, - $clienthello - ); - - push @{$proxy->record_list}, $record; - } else { - # For this test we're using a real TLS ClientHello - $clienthello = - pack "C49", - 0x01, # ClientHello - 0x00, 0x00, 0x2D, # Message length - 0x03, 0x03, # TLSv1.2 - 0x01, 0x18, 0x9F, 0x76, 0xEC, 0x57, 0xCE, 0xE5, 0xB3, 0xAB, 0x79, 0x90, - 0xAD, 0xAC, 0x6E, 0xD1, 0x58, 0x35, 0x03, 0x97, 0x16, 0x10, 0x82, 0x56, - 0xD8, 0x55, 0xFF, 0xE1, 0x8A, 0xA3, 0x2E, 0xF6, # Random - 0x00, # Session id len - 0x00, 0x04, # Ciphersuites len - 0x00, 0x2f, # AES128-SHA - 0x00, 0xff, # Empty reneg info SCSV - 0x01, # Compression methods len - 0x00, # Null compression - 0x00, 0x00; # Extensions len - - # Split this into 3: A TLS record; a SSLv2 record and a TLS record. - # We deliberately split the second record prior to the Challenge/Random - # and set the first byte of the random to 1. This makes the second SSLv2 - # record look like an SSLv2 ClientHello - my $frag1 = substr $clienthello, 0, 6; - my $frag2 = substr $clienthello, 6, 32; - my $frag3 = substr $clienthello, 38; - - my $fraglen = length $frag1; - $record = TLSProxy::Record->new( - 0, - TLSProxy::Record::RT_HANDSHAKE, - TLSProxy::Record::VERS_TLS_1_2, - $fraglen, - 0, - $fraglen, - $fraglen, - $frag1, - $frag1 - ); - push @{$proxy->record_list}, $record; - - $fraglen = length $frag2; - my $recvers; - if ($sslv2testtype == FRAGMENTED_IN_SSLV2) { - $recvers = 1; - } else { - $recvers = 0; - } - $record = TLSProxy::Record->new( - 0, - TLSProxy::Record::RT_HANDSHAKE, - TLSProxy::Record::VERS_TLS_1_2, - $fraglen, - $recvers, - $fraglen, - $fraglen, - $frag2, - $frag2 - ); - push @{$proxy->record_list}, $record; - - $fraglen = length $frag3; - $record = TLSProxy::Record->new( - 0, - TLSProxy::Record::RT_HANDSHAKE, - TLSProxy::Record::VERS_TLS_1_2, - $fraglen, - 0, - $fraglen, - $fraglen, - $frag3, - $frag3 - ); - push @{$proxy->record_list}, $record; - } - -} - sub add_unknown_record_type { my $proxy = shift; diff --git a/util/libssl.num b/util/libssl.num index d43e75f4d50..f8ca36f67df 100644 --- a/util/libssl.num +++ b/util/libssl.num @@ -298,7 +298,7 @@ SSL_get_srp_username ? 4_0_0 EXIST::FUNCTION:DEPRECATEDIN_3_0 SSL_get_srp_userinfo ? 4_0_0 EXIST::FUNCTION:DEPRECATEDIN_3_0,SRP SSL_CTX_set_client_hello_cb ? 4_0_0 EXIST::FUNCTION: SSL_CTX_set_new_pending_conn_cb ? 4_0_0 EXIST::FUNCTION: -SSL_client_hello_isv2 ? 4_0_0 EXIST::FUNCTION: +SSL_client_hello_isv2 ? 4_0_0 EXIST::FUNCTION:DEPRECATEDIN_4_0 SSL_client_hello_get0_legacy_version ? 4_0_0 EXIST::FUNCTION: SSL_client_hello_get0_random ? 4_0_0 EXIST::FUNCTION: SSL_client_hello_get0_session_id ? 4_0_0 EXIST::FUNCTION: