openssl: Upgrade 3.0.14 -> 3.0.15

Updated SRC_URI link and format due to change in openssl website.

CVE's Fixed by upgrade:
CVE-2024-5535: Fixed possible buffer overread in SSL_select_next_proto().
CVE-2024-6119: Fixed possible denial of service in X.509 name checks

- Removed backports of CVE-2024-5535 as it is already fixed.

Detailed Information:
https://github.com/openssl/openssl/blob/openssl-3.0/CHANGES.md#changes-between-3014-and-3015-3-sep-2024

(From OE-Core rev: 299118bf8e50055de28139b23781f2d34eb6eae0)

Signed-off-by: Siddharth Doshi <sdoshi@mvista.com>
Signed-off-by: Steve Sakoman <steve@sakoman.com>
This commit is contained in:
Siddharth Doshi
2024-09-06 14:02:18 +05:30
committed by Steve Sakoman
parent 00fb236b77
commit f5805aec43
10 changed files with 2 additions and 2198 deletions

View File

@@ -1,115 +0,0 @@
From e6190fc977f086428cc7880f95e8bcd5a11ac193 Mon Sep 17 00:00:00 2001
From: Matt Caswell <matt@openssl.org>
Date: Fri, 31 May 2024 11:14:33 +0100
Subject: [PATCH 1/9] Fix SSL_select_next_proto
Ensure that the provided client list is non-NULL and starts with a valid
entry. When called from the ALPN callback the client list should already
have been validated by OpenSSL so this should not cause a problem. When
called from the NPN callback the client list is locally configured and
will not have already been validated. Therefore SSL_select_next_proto
should not assume that it is correctly formatted.
We implement stricter checking of the client protocol list. We also do the
same for the server list while we are about it.
CVE-2024-5535
Reviewed-by: Neil Horman <nhorman@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/24718)
(cherry picked from commit 4ada436a1946cbb24db5ab4ca082b69c1bc10f37)
Upstream-Status: Backport from [https://github.com/openssl/openssl/commit/cf6f91f6121f4db167405db2f0de410a456f260c]
CVE: CVE-2024-5535
Signed-off-by: Siddharth Doshi <sdoshi@mvista.com>
---
ssl/ssl_lib.c | 63 ++++++++++++++++++++++++++++++++-------------------
1 file changed, 40 insertions(+), 23 deletions(-)
diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c
index cb4e006..e628140 100644
--- a/ssl/ssl_lib.c
+++ b/ssl/ssl_lib.c
@@ -2952,37 +2952,54 @@ int SSL_select_next_proto(unsigned char **out, unsigned char *outlen,
unsigned int server_len,
const unsigned char *client, unsigned int client_len)
{
- unsigned int i, j;
- const unsigned char *result;
- int status = OPENSSL_NPN_UNSUPPORTED;
+ PACKET cpkt, csubpkt, spkt, ssubpkt;
+
+ if (!PACKET_buf_init(&cpkt, client, client_len)
+ || !PACKET_get_length_prefixed_1(&cpkt, &csubpkt)
+ || PACKET_remaining(&csubpkt) == 0) {
+ *out = NULL;
+ *outlen = 0;
+ return OPENSSL_NPN_NO_OVERLAP;
+ }
+
+ /*
+ * Set the default opportunistic protocol. Will be overwritten if we find
+ * a match.
+ */
+ *out = (unsigned char *)PACKET_data(&csubpkt);
+ *outlen = (unsigned char)PACKET_remaining(&csubpkt);
/*
* For each protocol in server preference order, see if we support it.
*/
- for (i = 0; i < server_len;) {
- for (j = 0; j < client_len;) {
- if (server[i] == client[j] &&
- memcmp(&server[i + 1], &client[j + 1], server[i]) == 0) {
- /* We found a match */
- result = &server[i];
- status = OPENSSL_NPN_NEGOTIATED;
- goto found;
+ if (PACKET_buf_init(&spkt, server, server_len)) {
+ while (PACKET_get_length_prefixed_1(&spkt, &ssubpkt)) {
+ if (PACKET_remaining(&ssubpkt) == 0)
+ continue; /* Invalid - ignore it */
+ if (PACKET_buf_init(&cpkt, client, client_len)) {
+ while (PACKET_get_length_prefixed_1(&cpkt, &csubpkt)) {
+ if (PACKET_equal(&csubpkt, PACKET_data(&ssubpkt),
+ PACKET_remaining(&ssubpkt))) {
+ /* We found a match */
+ *out = (unsigned char *)PACKET_data(&ssubpkt);
+ *outlen = (unsigned char)PACKET_remaining(&ssubpkt);
+ return OPENSSL_NPN_NEGOTIATED;
+ }
+ }
+ /* Ignore spurious trailing bytes in the client list */
+ } else {
+ /* This should never happen */
+ return OPENSSL_NPN_NO_OVERLAP;
}
- j += client[j];
- j++;
}
- i += server[i];
- i++;
+ /* Ignore spurious trailing bytes in the server list */
}
- /* There's no overlap between our protocols and the server's list. */
- result = client;
- status = OPENSSL_NPN_NO_OVERLAP;
-
- found:
- *out = (unsigned char *)result + 1;
- *outlen = result[0];
- return status;
+ /*
+ * There's no overlap between our protocols and the server's list. We use
+ * the default opportunistic protocol selected earlier
+ */
+ return OPENSSL_NPN_NO_OVERLAP;
}
#ifndef OPENSSL_NO_NEXTPROTONEG
--
2.25.1

View File

@@ -1,44 +0,0 @@
From 4a96c6b7265838b044dab4a2a6150c246297bc89 Mon Sep 17 00:00:00 2001
From: Matt Caswell <matt@openssl.org>
Date: Fri, 31 May 2024 11:18:27 +0100
Subject: [PATCH 2/9] More correctly handle a selected_len of 0 when processing
NPN
In the case where the NPN callback returns with SSL_TLEXT_ERR_OK, but
the selected_len is 0 we should fail. Previously this would fail with an
internal_error alert because calling OPENSSL_malloc(selected_len) will
return NULL when selected_len is 0. We make this error detection more
explicit and return a handshake failure alert.
Follow on from CVE-2024-5535
Reviewed-by: Neil Horman <nhorman@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/24718)
(cherry picked from commit 4279c89a726025c758db3dafb263b17e52211304)
Upstream-Status: Backport from [https://github.com/openssl/openssl/commit/159921152fd4aa91e4c849fd281ad93ac0d0d0ba]
CVE: CVE-2024-5535
Signed-off-by: Siddharth Doshi <sdoshi@mvista.com>
---
ssl/statem/extensions_clnt.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/ssl/statem/extensions_clnt.c b/ssl/statem/extensions_clnt.c
index 842be07..a07dc62 100644
--- a/ssl/statem/extensions_clnt.c
+++ b/ssl/statem/extensions_clnt.c
@@ -1536,7 +1536,8 @@ int tls_parse_stoc_npn(SSL *s, PACKET *pkt, unsigned int context, X509 *x,
PACKET_data(pkt),
PACKET_remaining(pkt),
s->ctx->ext.npn_select_cb_arg) !=
- SSL_TLSEXT_ERR_OK) {
+ SSL_TLSEXT_ERR_OK
+ || selected_len == 0) {
SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_R_BAD_EXTENSION);
return 0;
}
--
2.25.1

View File

@@ -1,84 +0,0 @@
From 6887608f77236d14b0789f4b1c14df53dfe2d618 Mon Sep 17 00:00:00 2001
From: Matt Caswell <matt@openssl.org>
Date: Fri, 31 May 2024 11:46:38 +0100
Subject: [PATCH 3/9] Clarify the SSL_select_next_proto() documentation
We clarify the input preconditions and the expected behaviour in the event
of no overlap.
Follow on from CVE-2024-5535
Reviewed-by: Neil Horman <nhorman@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/24718)
(cherry picked from commit 889ed19ba25abebd2690997acd6d4791cbe5c493)
Upstream-Status: Backport from [https://github.com/openssl/openssl/commit/7a9f521b1de96e79184948e5813e791e608cc94b]
CVE: CVE-2024-5535
Signed-off-by: Siddharth Doshi <sdoshi@mvista.com>
---
doc/man3/SSL_CTX_set_alpn_select_cb.pod | 26 +++++++++++++++++--------
1 file changed, 18 insertions(+), 8 deletions(-)
diff --git a/doc/man3/SSL_CTX_set_alpn_select_cb.pod b/doc/man3/SSL_CTX_set_alpn_select_cb.pod
index 102e657..a29557d 100644
--- a/doc/man3/SSL_CTX_set_alpn_select_cb.pod
+++ b/doc/man3/SSL_CTX_set_alpn_select_cb.pod
@@ -52,7 +52,8 @@ SSL_select_next_proto, SSL_get0_alpn_selected, SSL_get0_next_proto_negotiated
SSL_CTX_set_alpn_protos() and SSL_set_alpn_protos() are used by the client to
set the list of protocols available to be negotiated. The B<protos> must be in
protocol-list format, described below. The length of B<protos> is specified in
-B<protos_len>.
+B<protos_len>. Setting B<protos_len> to 0 clears any existing list of ALPN
+protocols and no ALPN extension will be sent to the server.
SSL_CTX_set_alpn_select_cb() sets the application callback B<cb> used by a
server to select which protocol to use for the incoming connection. When B<cb>
@@ -73,9 +74,16 @@ B<server_len> and B<client>, B<client_len> must be in the protocol-list format
described below. The first item in the B<server>, B<server_len> list that
matches an item in the B<client>, B<client_len> list is selected, and returned
in B<out>, B<outlen>. The B<out> value will point into either B<server> or
-B<client>, so it should be copied immediately. If no match is found, the first
-item in B<client>, B<client_len> is returned in B<out>, B<outlen>. This
-function can also be used in the NPN callback.
+B<client>, so it should be copied immediately. The client list must include at
+least one valid (nonempty) protocol entry in the list.
+
+The SSL_select_next_proto() helper function can be useful from either the ALPN
+callback or the NPN callback (described below). If no match is found, the first
+item in B<client>, B<client_len> is returned in B<out>, B<outlen> and
+B<OPENSSL_NPN_NO_OVERLAP> is returned. This can be useful when implementating
+the NPN callback. In the ALPN case, the value returned in B<out> and B<outlen>
+must be ignored if B<OPENSSL_NPN_NO_OVERLAP> has been returned from
+SSL_select_next_proto().
SSL_CTX_set_next_proto_select_cb() sets a callback B<cb> that is called when a
client needs to select a protocol from the server's provided list, and a
@@ -85,9 +93,10 @@ must be set to point to the selected protocol (which may be within B<in>).
The length of the protocol name must be written into B<outlen>. The
server's advertised protocols are provided in B<in> and B<inlen>. The
callback can assume that B<in> is syntactically valid. The client must
-select a protocol. It is fatal to the connection if this callback returns
-a value other than B<SSL_TLSEXT_ERR_OK>. The B<arg> parameter is the pointer
-set via SSL_CTX_set_next_proto_select_cb().
+select a protocol (although it may be an empty, zero length protocol). It is
+fatal to the connection if this callback returns a value other than
+B<SSL_TLSEXT_ERR_OK> or if the zero length protocol is selected. The B<arg>
+parameter is the pointer set via SSL_CTX_set_next_proto_select_cb().
SSL_CTX_set_next_protos_advertised_cb() sets a callback B<cb> that is called
when a TLS server needs a list of supported protocols for Next Protocol
@@ -149,7 +158,8 @@ A match was found and is returned in B<out>, B<outlen>.
=item OPENSSL_NPN_NO_OVERLAP
No match was found. The first item in B<client>, B<client_len> is returned in
-B<out>, B<outlen>.
+B<out>, B<outlen> (or B<NULL> and 0 in the case where the first entry in
+B<client> is invalid).
=back
--
2.25.1

View File

@@ -1,178 +0,0 @@
From 6f9e71968f1f5e089bf79b0925e703a16f7bfa19 Mon Sep 17 00:00:00 2001
From: Matt Caswell <matt@openssl.org>
Date: Fri, 31 May 2024 16:35:16 +0100
Subject: [PATCH 4/9] Add a test for SSL_select_next_proto
Follow on from CVE-2024-5535
Reviewed-by: Neil Horman <nhorman@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/24718)
(cherry picked from commit ad1318efa2cfdf43ed49d23c4a815f4754604b97)
Upstream-Status: Backport from [https://github.com/openssl/openssl/commit/707c71aa03ba968e09325d72cf1e8dcac70df2df]
CVE: CVE-2024-5535
Signed-off-by: Siddharth Doshi <sdoshi@mvista.com>
---
test/sslapitest.c | 137 ++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 137 insertions(+)
diff --git a/test/sslapitest.c b/test/sslapitest.c
index 2b1c2fd..3922262 100644
--- a/test/sslapitest.c
+++ b/test/sslapitest.c
@@ -10765,6 +10765,142 @@ static int test_multi_resume(int idx)
return testresult;
}
+static struct next_proto_st {
+ int serverlen;
+ unsigned char server[40];
+ int clientlen;
+ unsigned char client[40];
+ int expected_ret;
+ size_t selectedlen;
+ unsigned char selected[40];
+} next_proto_tests[] = {
+ {
+ 4, { 3, 'a', 'b', 'c' },
+ 4, { 3, 'a', 'b', 'c' },
+ OPENSSL_NPN_NEGOTIATED,
+ 3, { 'a', 'b', 'c' }
+ },
+ {
+ 7, { 3, 'a', 'b', 'c', 2, 'a', 'b' },
+ 4, { 3, 'a', 'b', 'c' },
+ OPENSSL_NPN_NEGOTIATED,
+ 3, { 'a', 'b', 'c' }
+ },
+ {
+ 7, { 2, 'a', 'b', 3, 'a', 'b', 'c', },
+ 4, { 3, 'a', 'b', 'c' },
+ OPENSSL_NPN_NEGOTIATED,
+ 3, { 'a', 'b', 'c' }
+ },
+ {
+ 4, { 3, 'a', 'b', 'c' },
+ 7, { 3, 'a', 'b', 'c', 2, 'a', 'b', },
+ OPENSSL_NPN_NEGOTIATED,
+ 3, { 'a', 'b', 'c' }
+ },
+ {
+ 4, { 3, 'a', 'b', 'c' },
+ 7, { 2, 'a', 'b', 3, 'a', 'b', 'c'},
+ OPENSSL_NPN_NEGOTIATED,
+ 3, { 'a', 'b', 'c' }
+ },
+ {
+ 7, { 2, 'b', 'c', 3, 'a', 'b', 'c' },
+ 7, { 2, 'a', 'b', 3, 'a', 'b', 'c'},
+ OPENSSL_NPN_NEGOTIATED,
+ 3, { 'a', 'b', 'c' }
+ },
+ {
+ 10, { 2, 'b', 'c', 3, 'a', 'b', 'c', 2, 'a', 'b' },
+ 7, { 2, 'a', 'b', 3, 'a', 'b', 'c'},
+ OPENSSL_NPN_NEGOTIATED,
+ 3, { 'a', 'b', 'c' }
+ },
+ {
+ 4, { 3, 'b', 'c', 'd' },
+ 4, { 3, 'a', 'b', 'c' },
+ OPENSSL_NPN_NO_OVERLAP,
+ 3, { 'a', 'b', 'c' }
+ },
+ {
+ 0, { 0 },
+ 4, { 3, 'a', 'b', 'c' },
+ OPENSSL_NPN_NO_OVERLAP,
+ 3, { 'a', 'b', 'c' }
+ },
+ {
+ -1, { 0 },
+ 4, { 3, 'a', 'b', 'c' },
+ OPENSSL_NPN_NO_OVERLAP,
+ 3, { 'a', 'b', 'c' }
+ },
+ {
+ 4, { 3, 'a', 'b', 'c' },
+ 0, { 0 },
+ OPENSSL_NPN_NO_OVERLAP,
+ 0, { 0 }
+ },
+ {
+ 4, { 3, 'a', 'b', 'c' },
+ -1, { 0 },
+ OPENSSL_NPN_NO_OVERLAP,
+ 0, { 0 }
+ },
+ {
+ 3, { 3, 'a', 'b', 'c' },
+ 4, { 3, 'a', 'b', 'c' },
+ OPENSSL_NPN_NO_OVERLAP,
+ 3, { 'a', 'b', 'c' }
+ },
+ {
+ 4, { 3, 'a', 'b', 'c' },
+ 3, { 3, 'a', 'b', 'c' },
+ OPENSSL_NPN_NO_OVERLAP,
+ 0, { 0 }
+ }
+};
+
+static int test_select_next_proto(int idx)
+{
+ struct next_proto_st *np = &next_proto_tests[idx];
+ int ret = 0;
+ unsigned char *out, *client, *server;
+ unsigned char outlen;
+ unsigned int clientlen, serverlen;
+
+ if (np->clientlen == -1) {
+ client = NULL;
+ clientlen = 0;
+ } else {
+ client = np->client;
+ clientlen = (unsigned int)np->clientlen;
+ }
+ if (np->serverlen == -1) {
+ server = NULL;
+ serverlen = 0;
+ } else {
+ server = np->server;
+ serverlen = (unsigned int)np->serverlen;
+ }
+
+ if (!TEST_int_eq(SSL_select_next_proto(&out, &outlen, server, serverlen,
+ client, clientlen),
+ np->expected_ret))
+ goto err;
+
+ if (np->selectedlen == 0) {
+ if (!TEST_ptr_null(out) || !TEST_uchar_eq(outlen, 0))
+ goto err;
+ } else {
+ if (!TEST_mem_eq(out, outlen, np->selected, np->selectedlen))
+ goto err;
+ }
+
+ ret = 1;
+ err:
+ return ret;
+}
+
OPT_TEST_DECLARE_USAGE("certfile privkeyfile srpvfile tmpfile provider config dhfile\n")
int setup_tests(void)
@@ -11041,6 +11177,7 @@ int setup_tests(void)
#endif
ADD_ALL_TESTS(test_handshake_retry, 16);
ADD_ALL_TESTS(test_multi_resume, 5);
+ ADD_ALL_TESTS(test_select_next_proto, OSSL_NELEM(next_proto_tests));
return 1;
err:
--
2.25.1

File diff suppressed because it is too large Load Diff

View File

@@ -1,45 +0,0 @@
From a8c0ee154d212284f82680275de63642d914365e Mon Sep 17 00:00:00 2001
From: Matt Caswell <matt@openssl.org>
Date: Fri, 21 Jun 2024 10:41:55 +0100
Subject: [PATCH 6/9] Correct return values for
tls_construct_stoc_next_proto_neg
Return EXT_RETURN_NOT_SENT in the event that we don't send the extension,
rather than EXT_RETURN_SENT. This actually makes no difference at all to
the current control flow since this return value is ignored in this case
anyway. But lets make it correct anyway.
Follow on from CVE-2024-5535
Reviewed-by: Neil Horman <nhorman@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/24718)
(cherry picked from commit 087501b4f572825e27ca8cc2c5874fcf6fd47cf7)
Upstream-Status: Backport from [https://github.com/openssl/openssl/commit/189a7ed3e380e34ea38fe4190a7c9396bace0fb7]
CVE: CVE-2024-5535
Signed-off-by: Siddharth Doshi <sdoshi@mvista.com>
---
ssl/statem/extensions_srvr.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/ssl/statem/extensions_srvr.c b/ssl/statem/extensions_srvr.c
index 1fab5a3..51ea74b 100644
--- a/ssl/statem/extensions_srvr.c
+++ b/ssl/statem/extensions_srvr.c
@@ -1471,9 +1471,10 @@ EXT_RETURN tls_construct_stoc_next_proto_neg(SSL *s, WPACKET *pkt,
return EXT_RETURN_FAIL;
}
s->s3.npn_seen = 1;
+ return EXT_RETURN_SENT;
}
- return EXT_RETURN_SENT;
+ return EXT_RETURN_NOT_SENT;
}
#endif
--
2.25.1

View File

@@ -1,68 +0,0 @@
From fa5cc5eb58a4c9632929397fc9a6c291fff1b99d Mon Sep 17 00:00:00 2001
From: Matt Caswell <matt@openssl.org>
Date: Fri, 21 Jun 2024 11:51:54 +0100
Subject: [PATCH 7/9] Add ALPN validation in the client
The ALPN protocol selected by the server must be one that we originally
advertised. We should verify that it is.
Follow on from CVE-2024-5535
Reviewed-by: Neil Horman <nhorman@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/24718)
(cherry picked from commit 017e54183b95617825fb9316d618c154a34c634e)
Upstream-Status: Backport from [https://github.com/openssl/openssl/commit/4b375b998798dd516d367036773073e1b88e6433]
CVE: CVE-2024-5535
Signed-off-by: Siddharth Doshi <sdoshi@mvista.com>
---
ssl/statem/extensions_clnt.c | 24 ++++++++++++++++++++++++
1 file changed, 24 insertions(+)
diff --git a/ssl/statem/extensions_clnt.c b/ssl/statem/extensions_clnt.c
index a07dc62..b21ccf9 100644
--- a/ssl/statem/extensions_clnt.c
+++ b/ssl/statem/extensions_clnt.c
@@ -1566,6 +1566,8 @@ int tls_parse_stoc_alpn(SSL *s, PACKET *pkt, unsigned int context, X509 *x,
size_t chainidx)
{
size_t len;
+ PACKET confpkt, protpkt;
+ int valid = 0;
/* We must have requested it. */
if (!s->s3.alpn_sent) {
@@ -1584,6 +1586,28 @@ int tls_parse_stoc_alpn(SSL *s, PACKET *pkt, unsigned int context, X509 *x,
SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION);
return 0;
}
+
+ /* It must be a protocol that we sent */
+ if (!PACKET_buf_init(&confpkt, s->ext.alpn, s->ext.alpn_len)) {
+ SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
+ return 0;
+ }
+ while (PACKET_get_length_prefixed_1(&confpkt, &protpkt)) {
+ if (PACKET_remaining(&protpkt) != len)
+ continue;
+ if (memcmp(PACKET_data(pkt), PACKET_data(&protpkt), len) == 0) {
+ /* Valid protocol found */
+ valid = 1;
+ break;
+ }
+ }
+
+ if (!valid) {
+ /* The protocol sent from the server does not match one we advertised */
+ SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION);
+ return 0;
+ }
+
OPENSSL_free(s->s3.alpn_selected);
s->s3.alpn_selected = OPENSSL_malloc(len);
if (s->s3.alpn_selected == NULL) {
--
2.25.1

View File

@@ -1,273 +0,0 @@
From b898db2b91751a52d2af699e674a80a6b218084d Mon Sep 17 00:00:00 2001
From: Matt Caswell <matt@openssl.org>
Date: Fri, 21 Jun 2024 10:09:41 +0100
Subject: [PATCH 8/9] Add explicit testing of ALN and NPN in sslapitest
We already had some tests elsewhere - but this extends that testing with
additional tests.
Follow on from CVE-2024-5535
Reviewed-by: Neil Horman <nhorman@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/24718)
(cherry picked from commit 0453bf5a7ac60ab01c8bb713d8cc2a94324aa88c)
Upstream-Status: Backport from [https://github.com/openssl/openssl/commit/ca176d7291eb780e4ed2781342f5be5a32210a68]
CVE: CVE-2024-5535
Signed-off-by: Siddharth Doshi <sdoshi@mvista.com>
---
test/sslapitest.c | 229 ++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 229 insertions(+)
diff --git a/test/sslapitest.c b/test/sslapitest.c
index 3922262..171298b 100644
--- a/test/sslapitest.c
+++ b/test/sslapitest.c
@@ -10901,6 +10901,231 @@ static int test_select_next_proto(int idx)
return ret;
}
+static const unsigned char fooprot[] = {3, 'f', 'o', 'o' };
+static const unsigned char barprot[] = {3, 'b', 'a', 'r' };
+
+#if !defined(OPENSSL_NO_TLS1_2) && !defined(OPENSSL_NO_NEXTPROTONEG)
+static int npn_advert_cb(SSL *ssl, const unsigned char **out,
+ unsigned int *outlen, void *arg)
+{
+ int *idx = (int *)arg;
+
+ switch (*idx) {
+ default:
+ case 0:
+ *out = fooprot;
+ *outlen = sizeof(fooprot);
+ return SSL_TLSEXT_ERR_OK;
+
+ case 1:
+ *outlen = 0;
+ return SSL_TLSEXT_ERR_OK;
+
+ case 2:
+ return SSL_TLSEXT_ERR_NOACK;
+ }
+}
+
+static int npn_select_cb(SSL *s, unsigned char **out, unsigned char *outlen,
+ const unsigned char *in, unsigned int inlen, void *arg)
+{
+ int *idx = (int *)arg;
+
+ switch (*idx) {
+ case 0:
+ case 1:
+ *out = (unsigned char *)(fooprot + 1);
+ *outlen = *fooprot;
+ return SSL_TLSEXT_ERR_OK;
+
+ case 3:
+ *out = (unsigned char *)(barprot + 1);
+ *outlen = *barprot;
+ return SSL_TLSEXT_ERR_OK;
+
+ case 4:
+ *outlen = 0;
+ return SSL_TLSEXT_ERR_OK;
+
+ default:
+ case 2:
+ return SSL_TLSEXT_ERR_ALERT_FATAL;
+ }
+}
+
+/*
+ * Test the NPN callbacks
+ * Test 0: advert = foo, select = foo
+ * Test 1: advert = <empty>, select = foo
+ * Test 2: no advert
+ * Test 3: advert = foo, select = bar
+ * Test 4: advert = foo, select = <empty> (should fail)
+ */
+static int test_npn(int idx)
+{
+ SSL_CTX *sctx = NULL, *cctx = NULL;
+ SSL *serverssl = NULL, *clientssl = NULL;
+ int testresult = 0;
+
+ if (!TEST_true(create_ssl_ctx_pair(libctx, TLS_server_method(),
+ TLS_client_method(), 0, TLS1_2_VERSION,
+ &sctx, &cctx, cert, privkey)))
+ goto end;
+
+ SSL_CTX_set_next_protos_advertised_cb(sctx, npn_advert_cb, &idx);
+ SSL_CTX_set_next_proto_select_cb(cctx, npn_select_cb, &idx);
+
+ if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl, NULL,
+ NULL)))
+ goto end;
+
+ if (idx == 4) {
+ /* We don't allow empty selection of NPN, so this should fail */
+ if (!TEST_false(create_ssl_connection(serverssl, clientssl,
+ SSL_ERROR_NONE)))
+ goto end;
+ } else {
+ const unsigned char *prot;
+ unsigned int protlen;
+
+ if (!TEST_true(create_ssl_connection(serverssl, clientssl,
+ SSL_ERROR_NONE)))
+ goto end;
+
+ SSL_get0_next_proto_negotiated(serverssl, &prot, &protlen);
+ switch (idx) {
+ case 0:
+ case 1:
+ if (!TEST_mem_eq(prot, protlen, fooprot + 1, *fooprot))
+ goto end;
+ break;
+ case 2:
+ if (!TEST_uint_eq(protlen, 0))
+ goto end;
+ break;
+ case 3:
+ if (!TEST_mem_eq(prot, protlen, barprot + 1, *barprot))
+ goto end;
+ break;
+ default:
+ TEST_error("Should not get here");
+ goto end;
+ }
+ }
+
+ testresult = 1;
+ end:
+ SSL_free(serverssl);
+ SSL_free(clientssl);
+ SSL_CTX_free(sctx);
+ SSL_CTX_free(cctx);
+
+ return testresult;
+}
+#endif /* !defined(OPENSSL_NO_TLS1_2) && !defined(OPENSSL_NO_NEXTPROTONEG) */
+
+static int alpn_select_cb2(SSL *ssl, const unsigned char **out,
+ unsigned char *outlen, const unsigned char *in,
+ unsigned int inlen, void *arg)
+{
+ int *idx = (int *)arg;
+
+ switch (*idx) {
+ case 0:
+ *out = (unsigned char *)(fooprot + 1);
+ *outlen = *fooprot;
+ return SSL_TLSEXT_ERR_OK;
+
+ case 2:
+ *out = (unsigned char *)(barprot + 1);
+ *outlen = *barprot;
+ return SSL_TLSEXT_ERR_OK;
+
+ case 3:
+ *outlen = 0;
+ return SSL_TLSEXT_ERR_OK;
+
+ default:
+ case 1:
+ return SSL_TLSEXT_ERR_ALERT_FATAL;
+ }
+ return 0;
+}
+
+/*
+ * Test the ALPN callbacks
+ * Test 0: client = foo, select = foo
+ * Test 1: client = <empty>, select = none
+ * Test 2: client = foo, select = bar (should fail)
+ * Test 3: client = foo, select = <empty> (should fail)
+ */
+static int test_alpn(int idx)
+{
+ SSL_CTX *sctx = NULL, *cctx = NULL;
+ SSL *serverssl = NULL, *clientssl = NULL;
+ int testresult = 0;
+ const unsigned char *prots = fooprot;
+ unsigned int protslen = sizeof(fooprot);
+
+ if (!TEST_true(create_ssl_ctx_pair(libctx, TLS_server_method(),
+ TLS_client_method(), 0, 0,
+ &sctx, &cctx, cert, privkey)))
+ goto end;
+
+ SSL_CTX_set_alpn_select_cb(sctx, alpn_select_cb2, &idx);
+
+ if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl, NULL,
+ NULL)))
+ goto end;
+
+ if (idx == 1) {
+ prots = NULL;
+ protslen = 0;
+ }
+
+ /* SSL_set_alpn_protos returns 0 for success! */
+ if (!TEST_false(SSL_set_alpn_protos(clientssl, prots, protslen)))
+ goto end;
+
+ if (idx == 2 || idx == 3) {
+ /* We don't allow empty selection of NPN, so this should fail */
+ if (!TEST_false(create_ssl_connection(serverssl, clientssl,
+ SSL_ERROR_NONE)))
+ goto end;
+ } else {
+ const unsigned char *prot;
+ unsigned int protlen;
+
+ if (!TEST_true(create_ssl_connection(serverssl, clientssl,
+ SSL_ERROR_NONE)))
+ goto end;
+
+ SSL_get0_alpn_selected(clientssl, &prot, &protlen);
+ switch (idx) {
+ case 0:
+ if (!TEST_mem_eq(prot, protlen, fooprot + 1, *fooprot))
+ goto end;
+ break;
+ case 1:
+ if (!TEST_uint_eq(protlen, 0))
+ goto end;
+ break;
+ default:
+ TEST_error("Should not get here");
+ goto end;
+ }
+ }
+
+ testresult = 1;
+ end:
+ SSL_free(serverssl);
+ SSL_free(clientssl);
+ SSL_CTX_free(sctx);
+ SSL_CTX_free(cctx);
+
+ return testresult;
+}
+
OPT_TEST_DECLARE_USAGE("certfile privkeyfile srpvfile tmpfile provider config dhfile\n")
int setup_tests(void)
@@ -11178,6 +11403,10 @@ int setup_tests(void)
ADD_ALL_TESTS(test_handshake_retry, 16);
ADD_ALL_TESTS(test_multi_resume, 5);
ADD_ALL_TESTS(test_select_next_proto, OSSL_NELEM(next_proto_tests));
+#if !defined(OPENSSL_NO_TLS1_2) && !defined(OPENSSL_NO_NEXTPROTONEG)
+ ADD_ALL_TESTS(test_npn, 5);
+#endif
+ ADD_ALL_TESTS(test_alpn, 4);
return 1;
err:
--
2.25.1

View File

@@ -1,205 +0,0 @@
From 475480db0f9592f15f00a7cf692d3e04ad8e742f Mon Sep 17 00:00:00 2001
From: Matt Caswell <matt@openssl.org>
Date: Fri, 21 Jun 2024 14:29:26 +0100
Subject: [PATCH 9/9] Add a test for an empty NextProto message
It is valid according to the spec for a NextProto message to have no
protocols listed in it. The OpenSSL implementation however does not allow
us to create such a message. In order to check that we work as expected
when communicating with a client that does generate such messages we have
to use a TLSProxy test.
Follow on from CVE-2024-5535
Reviewed-by: Neil Horman <nhorman@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/24718)
(cherry picked from commit a201030901de9f9a48b34c38f6922fb0b272f26f)
Upstream-Status: Backport from [https://github.com/openssl/openssl/commit/99c2b6b971c302595db1801e26a202247238659d]
CVE: CVE-2024-5535
Signed-off-by: Siddharth Doshi <sdoshi@mvista.com>
---
test/recipes/70-test_npn.t | 73 +++++++++++++++++++++++++++++++++
util/perl/TLSProxy/Message.pm | 9 ++++
util/perl/TLSProxy/NextProto.pm | 54 ++++++++++++++++++++++++
util/perl/TLSProxy/Proxy.pm | 1 +
4 files changed, 137 insertions(+)
create mode 100644 test/recipes/70-test_npn.t
create mode 100644 util/perl/TLSProxy/NextProto.pm
diff --git a/test/recipes/70-test_npn.t b/test/recipes/70-test_npn.t
new file mode 100644
index 0000000..f82e71a
--- /dev/null
+++ b/test/recipes/70-test_npn.t
@@ -0,0 +1,73 @@
+#! /usr/bin/env perl
+# Copyright 2024 The OpenSSL Project Authors. All Rights Reserved.
+#
+# Licensed under the Apache License 2.0 (the "License"). You may not use
+# this file except in compliance with the License. You can obtain a copy
+# in the file LICENSE in the source distribution or at
+# https://www.openssl.org/source/license.html
+
+use strict;
+use OpenSSL::Test qw/:DEFAULT cmdstr srctop_file/;
+use OpenSSL::Test::Utils;
+
+use TLSProxy::Proxy;
+
+my $test_name = "test_npn";
+setup($test_name);
+
+plan skip_all => "TLSProxy isn't usable on $^O"
+ if $^O =~ /^(VMS)$/;
+
+plan skip_all => "$test_name needs the dynamic engine feature enabled"
+ if disabled("engine") || disabled("dynamic-engine");
+
+plan skip_all => "$test_name needs the sock feature enabled"
+ if disabled("sock");
+
+plan skip_all => "$test_name needs NPN enabled"
+ if disabled("nextprotoneg");
+
+plan skip_all => "$test_name needs TLSv1.2 enabled"
+ if disabled("tls1_2");
+
+my $proxy = TLSProxy::Proxy->new(
+ undef,
+ cmdstr(app(["openssl"]), display => 1),
+ srctop_file("apps", "server.pem"),
+ (!$ENV{HARNESS_ACTIVE} || $ENV{HARNESS_VERBOSE})
+);
+
+$proxy->start() or plan skip_all => "Unable to start up Proxy for tests";
+plan tests => 1;
+
+my $npnseen = 0;
+
+# Test 1: Check sending an empty NextProto message from the client works. This is
+# valid as per the spec, but OpenSSL does not allow you to send it.
+# Therefore we must be prepared to receive such a message but we cannot
+# generate it except via TLSProxy
+$proxy->clear();
+$proxy->filter(\&npn_filter);
+$proxy->clientflags("-nextprotoneg foo -no_tls1_3");
+$proxy->serverflags("-nextprotoneg foo");
+$proxy->start();
+ok($npnseen && TLSProxy::Message->success(), "Empty NPN message");
+
+sub npn_filter
+{
+ my $proxy = shift;
+ my $message;
+
+ # The NextProto message always appears in flight 2
+ return if $proxy->flight != 2;
+
+ foreach my $message (@{$proxy->message_list}) {
+ if ($message->mt == TLSProxy::Message::MT_NEXT_PROTO) {
+ # Our TLSproxy NextProto message support doesn't support parsing of
+ # the message. If we repack it just creates an empty NextProto
+ # message - which is exactly the scenario we want to test here.
+ $message->repack();
+ $npnseen = 1;
+ }
+ }
+}
diff --git a/util/perl/TLSProxy/Message.pm b/util/perl/TLSProxy/Message.pm
index 2c1bdb3..eb350de 100644
--- a/util/perl/TLSProxy/Message.pm
+++ b/util/perl/TLSProxy/Message.pm
@@ -379,6 +379,15 @@ sub create_message
[@message_frag_lens]
);
$message->parse();
+ } elsif ($mt == MT_NEXT_PROTO) {
+ $message = TLSProxy::NextProto->new(
+ $server,
+ $data,
+ [@message_rec_list],
+ $startoffset,
+ [@message_frag_lens]
+ );
+ $message->parse();
} else {
#Unknown message type
$message = TLSProxy::Message->new(
diff --git a/util/perl/TLSProxy/NextProto.pm b/util/perl/TLSProxy/NextProto.pm
new file mode 100644
index 0000000..0e18347
--- /dev/null
+++ b/util/perl/TLSProxy/NextProto.pm
@@ -0,0 +1,54 @@
+# Copyright 2024 The OpenSSL Project Authors. All Rights Reserved.
+#
+# Licensed under the Apache License 2.0 (the "License"). You may not use
+# this file except in compliance with the License. You can obtain a copy
+# in the file LICENSE in the source distribution or at
+# https://www.openssl.org/source/license.html
+
+use strict;
+
+package TLSProxy::NextProto;
+
+use vars '@ISA';
+push @ISA, 'TLSProxy::Message';
+
+sub new
+{
+ my $class = shift;
+ my ($server,
+ $data,
+ $records,
+ $startoffset,
+ $message_frag_lens) = @_;
+
+ my $self = $class->SUPER::new(
+ $server,
+ TLSProxy::Message::MT_NEXT_PROTO,
+ $data,
+ $records,
+ $startoffset,
+ $message_frag_lens);
+
+ return $self;
+}
+
+sub parse
+{
+ # We don't support parsing at the moment
+}
+
+# This is supposed to reconstruct the on-the-wire message data following changes.
+# For now though since we don't support parsing we just create an empty NextProto
+# message - this capability is used in test_npn
+sub set_message_contents
+{
+ my $self = shift;
+ my $data;
+
+ $data = pack("C32", 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00);
+ $self->data($data);
+}
+1;
diff --git a/util/perl/TLSProxy/Proxy.pm b/util/perl/TLSProxy/Proxy.pm
index 3de10ec..b707722 100644
--- a/util/perl/TLSProxy/Proxy.pm
+++ b/util/perl/TLSProxy/Proxy.pm
@@ -23,6 +23,7 @@ use TLSProxy::CertificateRequest;
use TLSProxy::CertificateVerify;
use TLSProxy::ServerKeyExchange;
use TLSProxy::NewSessionTicket;
+use TLSProxy::NextProto;
my $have_IPv6;
my $IP_factory;
--
2.25.1

View File

@@ -7,27 +7,18 @@ SECTION = "libs/network"
LICENSE = "Apache-2.0"
LIC_FILES_CHKSUM = "file://LICENSE.txt;md5=c75985e733726beaba57bc5253e96d04"
SRC_URI = "http://www.openssl.org/source/openssl-${PV}.tar.gz \
SRC_URI = "https://github.com/openssl/openssl/releases/download/openssl-${PV}/openssl-${PV}.tar.gz \
file://run-ptest \
file://0001-buildinfo-strip-sysroot-and-debug-prefix-map-from-co.patch \
file://afalg.patch \
file://0001-Configure-do-not-tweak-mips-cflags.patch \
file://CVE-2024-5535_1.patch \
file://CVE-2024-5535_2.patch \
file://CVE-2024-5535_3.patch \
file://CVE-2024-5535_4.patch \
file://CVE-2024-5535_5.patch \
file://CVE-2024-5535_6.patch \
file://CVE-2024-5535_7.patch \
file://CVE-2024-5535_8.patch \
file://CVE-2024-5535_9.patch \
"
SRC_URI:append:class-nativesdk = " \
file://environment.d-openssl.sh \
"
SRC_URI[sha256sum] = "eeca035d4dd4e84fc25846d952da6297484afa0650a6f84c682e39df3a4123ca"
SRC_URI[sha256sum] = "23c666d0edf20f14249b3d8f0368acaee9ab585b09e1de82107c66e1f3ec9533"
inherit lib_package multilib_header multilib_script ptest perlnative
MULTILIB_SCRIPTS = "${PN}-bin:${bindir}/c_rehash"