Index | Thread | Search

From:
Theo Buehler <tb@theobuehler.org>
Subject:
Re: Trying to install Apache 2.4 with OpenSSL 1.1 instead of LibreSSL
To:
Tim <timh@dirtymonday.net>
Cc:
"ports@openbsd.org" <ports@openbsd.org>, jsing@openbsd.org
Date:
Tue, 30 Jan 2024 13:30:32 +0100

Download raw body.

Thread
  • Theo Buehler:

    Trying to install Apache 2.4 with OpenSSL 1.1 instead of LibreSSL

  • On Fri, Jan 26, 2024 at 02:11:52PM -0800, Tim wrote:
    > I'm trying to troubleshoot an issue where Chrome/Chromium browsers
    > randomly fail to correctly use SSL against my web server.
    
    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
    
    
    
  • Theo Buehler:

    Trying to install Apache 2.4 with OpenSSL 1.1 instead of LibreSSL