Tuesday, January 30, 2024

Re: Trying to install Apache 2.4 with OpenSSL 1.1 instead of LibreSSL

On Tue, 30 Jan 2024 13:30:32 +0100
Theo Buehler <tb@theobuehler.org> wrote:

> This version of a diff from jsing for libssl (it applies with slight
> offsets to 7.4-stable) should fix this issue.
>
> Could you please try this with an unpached apache-httpd?
>
> Index: s3_lib.c
> ===================================================================
> RCS file: /cvs/src/lib/libssl/s3_lib.c,v
> diff -u -p -r1.248 s3_lib.c
> --- s3_lib.c 29 Nov 2023 13:39:34 -0000 1.248
> +++ s3_lib.c 30 Jan 2024 11:34:10 -0000
> @@ -1594,6 +1594,7 @@ ssl3_free(SSL *s)
> tls1_transcript_hash_free(s);
>
> free(s->s3->alpn_selected);
> + free(s->s3->alpn_wire_data);
>
> freezero(s->s3->peer_quic_transport_params,
> s->s3->peer_quic_transport_params_len);
> @@ -1659,6 +1660,9 @@ ssl3_clear(SSL *s)
> free(s->s3->alpn_selected);
> s->s3->alpn_selected = NULL;
> s->s3->alpn_selected_len = 0;
> + free(s->s3->alpn_wire_data);
> + s->s3->alpn_wire_data = NULL;
> + s->s3->alpn_wire_data_len = 0;
>
> freezero(s->s3->peer_quic_transport_params,
> s->s3->peer_quic_transport_params_len);
> Index: ssl_local.h
> ===================================================================
> RCS file: /cvs/src/lib/libssl/ssl_local.h,v
> diff -u -p -r1.12 ssl_local.h
> --- ssl_local.h 29 Dec 2023 12:24:33 -0000 1.12
> +++ ssl_local.h 30 Jan 2024 11:34:10 -0000
> @@ -1209,6 +1209,8 @@ typedef struct ssl3_state_st {
> */
> uint8_t *alpn_selected;
> size_t alpn_selected_len;
> + uint8_t *alpn_wire_data;
> + size_t alpn_wire_data_len;
>
> /* Contains the QUIC transport params received from our peer. */
> uint8_t *peer_quic_transport_params;
> Index: ssl_tlsext.c
> ===================================================================
> RCS file: /cvs/src/lib/libssl/ssl_tlsext.c,v
> diff -u -p -r1.137 ssl_tlsext.c
> --- ssl_tlsext.c 28 Apr 2023 18:14:59 -0000 1.137
> +++ ssl_tlsext.c 30 Jan 2024 11:34:10 -0000
> @@ -86,33 +86,48 @@ tlsext_alpn_check_format(CBS *cbs)
> }
>
> static int
> -tlsext_alpn_server_parse(SSL *s, uint16_t msg_types, CBS *cbs, int *alert)
> +tlsext_alpn_server_parse(SSL *s, uint16_t msg_type, CBS *cbs, int *alert)
> {
> - CBS alpn, selected_cbs;
> - const unsigned char *selected;
> - unsigned char selected_len;
> - int r;
> + CBS alpn;
>
> if (!CBS_get_u16_length_prefixed(cbs, &alpn))
> return 0;
> -
> if (!tlsext_alpn_check_format(&alpn))
> return 0;
> + if (!CBS_stow(&alpn, &s->s3->alpn_wire_data, &s->s3->alpn_wire_data_len))
> + return 0;
> +
> + return 1;
> +}
> +
> +static int
> +tlsext_alpn_server_process(SSL *s, uint16_t msg_type, int *alert)
> +{
> + const unsigned char *selected;
> + unsigned char selected_len;
> + CBS alpn, selected_cbs;
> + int cb_ret;
>
> if (s->ctx->alpn_select_cb == NULL)
> return 1;
>
> + if (s->s3->alpn_wire_data == NULL) {
> + *alert = SSL_AD_INTERNAL_ERROR;
> + return 0;
> + }
> + CBS_init(&alpn, s->s3->alpn_wire_data, s->s3->alpn_wire_data_len);
> +
> /*
> * XXX - A few things should be considered here:
> * 1. Ensure that the same protocol is selected on session resumption.
> * 2. Should the callback be called even if no ALPN extension was sent?
> * 3. TLSv1.2 and earlier: ensure that SNI has already been processed.
> */
> - r = s->ctx->alpn_select_cb(s, &selected, &selected_len,
> + cb_ret = s->ctx->alpn_select_cb(s, &selected, &selected_len,
> CBS_data(&alpn), CBS_len(&alpn),
> s->ctx->alpn_select_cb_arg);
>
> - if (r == SSL_TLSEXT_ERR_OK) {
> + if (cb_ret == SSL_TLSEXT_ERR_OK) {
> CBS_init(&selected_cbs, selected, selected_len);
>
> if (!CBS_stow(&selected_cbs, &s->s3->alpn_selected,
> @@ -125,7 +140,7 @@ tlsext_alpn_server_parse(SSL *s, uint16_
> }
>
> /* On SSL_TLSEXT_ERR_NOACK behave as if no callback was present. */
> - if (r == SSL_TLSEXT_ERR_NOACK)
> + if (cb_ret == SSL_TLSEXT_ERR_NOACK)
> return 1;
>
> *alert = SSL_AD_NO_APPLICATION_PROTOCOL;
> @@ -1972,6 +1987,7 @@ struct tls_extension_funcs {
> int (*needs)(SSL *s, uint16_t msg_type);
> int (*build)(SSL *s, uint16_t msg_type, CBB *cbb);
> int (*parse)(SSL *s, uint16_t msg_type, CBS *cbs, int *alert);
> + int (*process)(SSL *s, uint16_t msg_type, int *alert);
> };
>
> struct tls_extension {
> @@ -2123,6 +2139,7 @@ static const struct tls_extension tls_ex
> .needs = tlsext_alpn_server_needs,
> .build = tlsext_alpn_server_build,
> .parse = tlsext_alpn_server_parse,
> + .process = tlsext_alpn_server_process,
> },
> },
> {
> @@ -2391,6 +2408,14 @@ tlsext_clienthello_hash_extension(SSL *s
> return 1;
> }
>
> +static void
> +tlsext_cleanup(SSL *s)
> +{
> + free(s->s3->alpn_wire_data);
> + s->s3->alpn_wire_data = NULL;
> + s->s3->alpn_wire_data_len = 0;
> +}
> +
> static int
> tlsext_parse(SSL *s, int is_server, uint16_t msg_type, CBS *cbs, int *alert)
> {
> @@ -2466,6 +2491,36 @@ tlsext_parse(SSL *s, int is_server, uint
> return 0;
> }
>
> +static int
> +tlsext_process(SSL *s, int is_server, uint16_t msg_type, int *alert)
> +{
> + const struct tls_extension_funcs *ext;
> + const struct tls_extension *tlsext;
> + int alert_desc;
> + size_t idx;
> +
> + alert_desc = SSL_AD_DECODE_ERROR;
> +
> + /* Run processing for present TLS extensions, in a defined order. */
> + for (idx = 0; idx < N_TLS_EXTENSIONS; idx++) {
> + tlsext = &tls_extensions[idx];
> + if ((s->s3->hs.extensions_seen & (1 << idx)) == 0)
> + continue;
> + ext = tlsext_funcs(tlsext, is_server);
> + if (ext->process == NULL)
> + continue;
> + if (!ext->process(s, msg_type, &alert_desc))
> + goto err;
> + }
> +
> + return 1;
> +
> + err:
> + *alert = alert_desc;
> +
> + return 0;
> +}
> +
> static void
> tlsext_server_reset_state(SSL *s)
> {
> @@ -2486,11 +2541,23 @@ tlsext_server_build(SSL *s, uint16_t msg
> int
> tlsext_server_parse(SSL *s, uint16_t msg_type, CBS *cbs, int *alert)
> {
> + int ret = 0;
> +
> /* XXX - this should be done by the caller... */
> if (msg_type == SSL_TLSEXT_MSG_CH)
> tlsext_server_reset_state(s);
>
> - return tlsext_parse(s, 1, msg_type, cbs, alert);
> + if (!tlsext_parse(s, 1, msg_type, cbs, alert))
> + goto err;
> + if (!tlsext_process(s, 1, msg_type, alert))
> + goto err;
> +
> + ret = 1;
> +
> + err:
> + tlsext_cleanup(s);
> +
> + return ret;
> }
>
> static void

After applying this patch, I was not able to replicate the
error on Chrome after a few minutes of testing on a couple different
clients.

I will leave this version running and report any issues.

--TimH

No comments:

Post a Comment