From: TimH Subject: Re: Trying to install Apache 2.4 with OpenSSL 1.1 instead of LibreSSL To: ports@openbsd.org Date: Tue, 30 Jan 2024 15:28:20 -0800 On Tue, 30 Jan 2024 13:30:32 +0100 Theo Buehler 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