Compare commits
No commits in common. "c9" and "c8" have entirely different histories.
2
.gitignore
vendored
2
.gitignore
vendored
@ -1 +1 @@
|
|||||||
SOURCES/jose-11.tar.xz
|
SOURCES/jose-10.tar.bz2
|
||||||
|
@ -1 +1 @@
|
|||||||
4aef660fa140c8897d76039b651cd093207ad456 SOURCES/jose-11.tar.xz
|
def05b305a862e23910c3dfc6cacb511b935ab65 SOURCES/jose-10.tar.bz2
|
||||||
|
@ -0,0 +1,187 @@
|
|||||||
|
From 70cebe8c2f14ad9e7b8359ed53188bbd8ac3cce5 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Sergio Correia <scorreia@redhat.com>
|
||||||
|
Date: Thu, 23 May 2024 12:34:01 -0400
|
||||||
|
Subject: [PATCH] openssl: decode private exponent when converting jwk -> RSA
|
||||||
|
|
||||||
|
We were not decoding the private exponent, and thus always passing
|
||||||
|
NULL to RSA_set0_key() in jose_openssl_jwk_to_RSA().
|
||||||
|
|
||||||
|
Fixes: #75
|
||||||
|
|
||||||
|
This is a backport of https://github.com/latchset/jose/pull/76, with
|
||||||
|
some changes to adapt the test to run during the EL8 build, which
|
||||||
|
still uses autotools instead of meson.
|
||||||
|
|
||||||
|
Signed-off-by: Sergio Correia <scorreia@redhat.com>
|
||||||
|
---
|
||||||
|
configure.ac | 1 +
|
||||||
|
lib/openssl/jwk.c | 1 +
|
||||||
|
tests/Makefile.am | 7 +--
|
||||||
|
tests/issue-75/issue-75.c | 89 +++++++++++++++++++++++++++++++++++++++
|
||||||
|
tests/issue-75/rsa512.pem | 9 ++++
|
||||||
|
5 files changed, 104 insertions(+), 3 deletions(-)
|
||||||
|
create mode 100644 tests/issue-75/issue-75.c
|
||||||
|
create mode 100644 tests/issue-75/rsa512.pem
|
||||||
|
|
||||||
|
diff --git a/configure.ac b/configure.ac
|
||||||
|
index cf8c9a6..fb9c7b7 100644
|
||||||
|
--- a/configure.ac
|
||||||
|
+++ b/configure.ac
|
||||||
|
@@ -14,6 +14,7 @@ PKG_PROG_PKG_CONFIG([0.25])
|
||||||
|
PKG_CHECK_MODULES([zlib], [zlib])
|
||||||
|
PKG_CHECK_MODULES([jansson], [jansson >= 2.10])
|
||||||
|
PKG_CHECK_MODULES([libcrypto], [libcrypto >= 1.0.2])
|
||||||
|
+PKG_CHECK_MODULES([libssl], [libssl >= 1.0.2])
|
||||||
|
|
||||||
|
AC_OPENMP
|
||||||
|
AC_SUBST([OPENMP_CFLAGS])
|
||||||
|
diff --git a/lib/openssl/jwk.c b/lib/openssl/jwk.c
|
||||||
|
index 83be3a5..8fc1dd7 100644
|
||||||
|
--- a/lib/openssl/jwk.c
|
||||||
|
+++ b/lib/openssl/jwk.c
|
||||||
|
@@ -305,6 +305,7 @@ jose_openssl_jwk_to_RSA(jose_cfg_t *cfg, const json_t *jwk)
|
||||||
|
|
||||||
|
N = bn_decode_json(n);
|
||||||
|
E = bn_decode_json(e);
|
||||||
|
+ D = bn_decode_json(d);
|
||||||
|
P = bn_decode_json(p);
|
||||||
|
Q = bn_decode_json(q);
|
||||||
|
DP = bn_decode_json(dp);
|
||||||
|
diff --git a/tests/Makefile.am b/tests/Makefile.am
|
||||||
|
index 282463e..cd330d7 100644
|
||||||
|
--- a/tests/Makefile.am
|
||||||
|
+++ b/tests/Makefile.am
|
||||||
|
@@ -1,8 +1,8 @@
|
||||||
|
AM_CFLAGS = @JOSE_CFLAGS@ @OPENMP_CFLAGS@ @jansson_CFLAGS@ -I$(top_srcdir) -I$(top_builddir)
|
||||||
|
-LDFLAGS += $(top_builddir)/lib/libjose.la @jansson_LIBS@
|
||||||
|
+LDFLAGS += $(top_builddir)/lib/libjose.la @jansson_LIBS@ @libcrypto_LIBS@ @libssl_LIBS@
|
||||||
|
EXTRA_DIST = vectors
|
||||||
|
|
||||||
|
-AM_TESTS_ENVIRONMENT=PATH=$(top_builddir)/cmd:$(PATH) VECTORS=$(top_srcdir)/tests/vectors
|
||||||
|
+AM_TESTS_ENVIRONMENT=PATH=$(top_builddir)/cmd:$(PATH) VECTORS=$(top_srcdir)/tests/vectors ISSUE_75_DATADIR=$(top_srcdir)/tests/issue-75
|
||||||
|
TESTS = $(dist_check_SCRIPTS) $(check_PROGRAMS)
|
||||||
|
|
||||||
|
check_PROGRAMS = \
|
||||||
|
@@ -13,7 +13,8 @@ check_PROGRAMS = \
|
||||||
|
alg_comp \
|
||||||
|
api_b64 \
|
||||||
|
api_jws \
|
||||||
|
- api_jwe
|
||||||
|
+ api_jwe \
|
||||||
|
+ issue-75/issue-75
|
||||||
|
|
||||||
|
dist_check_SCRIPTS = \
|
||||||
|
jose-alg \
|
||||||
|
diff --git a/tests/issue-75/issue-75.c b/tests/issue-75/issue-75.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..6e266df
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/tests/issue-75/issue-75.c
|
||||||
|
@@ -0,0 +1,89 @@
|
||||||
|
+/* vim: set tabstop=8 shiftwidth=4 softtabstop=4 expandtab smarttab colorcolumn=80: */
|
||||||
|
+/*
|
||||||
|
+ * Copyright 2020 Red Hat, Inc.
|
||||||
|
+ *
|
||||||
|
+ * Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
+ * you may not use this file except in compliance with the License.
|
||||||
|
+ * You may obtain a copy of the License at
|
||||||
|
+ *
|
||||||
|
+ * http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
+ *
|
||||||
|
+ * Unless required by applicable law or agreed to in writing, software
|
||||||
|
+ * distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
+ * See the License for the specific language governing permissions and
|
||||||
|
+ * limitations under the License.
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+#include <jose/jose.h>
|
||||||
|
+#include <jose/openssl.h>
|
||||||
|
+#include <assert.h>
|
||||||
|
+#include <string.h>
|
||||||
|
+#include <sys/stat.h>
|
||||||
|
+
|
||||||
|
+#include <openssl/opensslv.h>
|
||||||
|
+#include <openssl/ssl.h>
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * In this test we load a (RSA, 512-bit) PEM file asa n EVP_PKEY*, then
|
||||||
|
+ * convert it to JWK with jose_openssl_jwk_from_EVP_PKEY().
|
||||||
|
+ *
|
||||||
|
+ * Afterwards, we convert this JWK to EVP_PKEY* again, with
|
||||||
|
+ * jose_openssl_jwk_to_EVP_PKEY(), and once more convert the
|
||||||
|
+ * resulting EVP_PKEY* back to JWK with jose_openssl_jwk_from_EVP_PKEY().
|
||||||
|
+ *
|
||||||
|
+ * We then compare the two JWKs, and they should be equal.
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+int
|
||||||
|
+main(int argc, char *argv[])
|
||||||
|
+{
|
||||||
|
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||||
|
+ SSL_library_init();
|
||||||
|
+#else
|
||||||
|
+ OPENSSL_init_ssl(0, NULL);
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+ const char *issue_75_data_dir = getenv("ISSUE_75_DATADIR");
|
||||||
|
+ if (!issue_75_data_dir) {
|
||||||
|
+ fprintf(stderr, "%s: ERROR: please, specify the ISSUE_75_DATADIR env variable, pointing out to the directory where the rsa512.pem used in the issue-75 test is located\n", argv[0]);
|
||||||
|
+ exit(1);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ const char *datafile = "rsa512.pem";
|
||||||
|
+ if (strlen(datafile) + strlen(issue_75_data_dir + 1 /* path separator */) > PATH_MAX) {
|
||||||
|
+ fprintf(stderr, "%s: ERROR: invalid path to issue-75 data file: ISSUE_75_DATADIR is too large\n", argv[0]);
|
||||||
|
+ exit(1);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ char pemfile[PATH_MAX + 1] = {};
|
||||||
|
+ snprintf(pemfile, PATH_MAX, "%s/%s", issue_75_data_dir, datafile);
|
||||||
|
+
|
||||||
|
+ struct stat s_buffer;
|
||||||
|
+ if (stat(pemfile, &s_buffer) != 0) {
|
||||||
|
+ fprintf(stderr, "%s: ERROR: data file '%s' does not seem to exist; please make sure ISSUE_75_DATADIR is correctly set\n", argv[0], pemfile);
|
||||||
|
+ exit(1);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ BIO* pfile = BIO_new_file(pemfile, "r");
|
||||||
|
+ assert(pfile);
|
||||||
|
+
|
||||||
|
+ EVP_PKEY* pkey = PEM_read_bio_PrivateKey(pfile, NULL, 0, NULL);
|
||||||
|
+ assert(pkey);
|
||||||
|
+ BIO_free(pfile);
|
||||||
|
+
|
||||||
|
+ json_auto_t* jwk = jose_openssl_jwk_from_EVP_PKEY(NULL, pkey);
|
||||||
|
+ assert(jwk);
|
||||||
|
+
|
||||||
|
+ EVP_PKEY* from_jwk = jose_openssl_jwk_to_EVP_PKEY(NULL, jwk);
|
||||||
|
+ assert(from_jwk);
|
||||||
|
+
|
||||||
|
+ json_auto_t* converted_jwk = jose_openssl_jwk_from_EVP_PKEY(NULL, from_jwk);
|
||||||
|
+ assert(converted_jwk);
|
||||||
|
+
|
||||||
|
+ EVP_PKEY_free(pkey);
|
||||||
|
+ EVP_PKEY_free(from_jwk);
|
||||||
|
+
|
||||||
|
+ assert(json_equal(jwk, converted_jwk));
|
||||||
|
+ return EXIT_SUCCESS;
|
||||||
|
+}
|
||||||
|
diff --git a/tests/issue-75/rsa512.pem b/tests/issue-75/rsa512.pem
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..961ec32
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/tests/issue-75/rsa512.pem
|
||||||
|
@@ -0,0 +1,9 @@
|
||||||
|
+-----BEGIN RSA PRIVATE KEY-----
|
||||||
|
+MIIBOgIBAAJBAMm/50Zj7HgDGBzTy6tmgeBq4jVVpbWA86ZBFgQpwOmXsRToQpCA
|
||||||
|
+K56DNzDBMOt4SIA7pF2uf9VBF3EQ7rg8H88CAwEAAQJAYK/HdsSMnzdcZvRZt1r5
|
||||||
|
+A0Q2BLl3IPUbz6GBm50nBssB2lYZqxpOL0i5MO5wt7DgPzrbwjugjUvhkSwdy+Wo
|
||||||
|
+gQIhAO1KoRRDaUufWNkzLjx+1XbZFnZRw+xN4Nz2P0JrVRO9AiEA2afqKfzaaxGg
|
||||||
|
+tnZGINhYBx8Iym9cZ2BpXdh5ZGCydHsCIBIcYhLz2jOFY/if6WWAoLZDd21sbDG6
|
||||||
|
+9/ClcsqU+pdZAiEA1zLDPkJnPidOrDjie4UL+/Z+PZC/XuKfKw9mbo2Aw9MCIB2E
|
||||||
|
+LzXkdu8W3g3ORa4jkV3na49Jiyg0VGeaAoauebo5
|
||||||
|
+-----END RSA PRIVATE KEY-----
|
||||||
|
--
|
||||||
|
2.44.0
|
||||||
|
|
112
SOURCES/0002-Fix-potential-DoS-issue-with-p2c-header.patch
Normal file
112
SOURCES/0002-Fix-potential-DoS-issue-with-p2c-header.patch
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
From 6825e070ef5cdcaf815bbd99089a3a6ef8b785d7 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Sergio Correia <scorreia@redhat.com>
|
||||||
|
Date: Thu, 23 May 2024 13:56:43 -0400
|
||||||
|
Subject: [PATCH 2/2] Fix potential DoS issue with p2c header
|
||||||
|
|
||||||
|
Unbounded p2c headers may be used to cause an application that accept
|
||||||
|
PBES algorithms to spend a lot of resources running PBKDF2 with a very
|
||||||
|
high number of iterations.
|
||||||
|
|
||||||
|
Limit the maximum number of iterations to to 32768.
|
||||||
|
|
||||||
|
Fixes: CVE-2023-50967
|
||||||
|
|
||||||
|
This is a backport of https://github.com/latchset/jose/pull/154, with
|
||||||
|
some changes to adapt the test to run during the EL8 build, which
|
||||||
|
still uses autotools instead of meson.
|
||||||
|
|
||||||
|
Signed-off-by: Sergio Correia <scorreia@redhat.com>
|
||||||
|
---
|
||||||
|
lib/openssl/pbes2.c | 9 +++++++--
|
||||||
|
tests/Makefile.am | 2 +-
|
||||||
|
tests/cve-2023-50967/cve-2023-50967.jwe | 1 +
|
||||||
|
tests/cve-2023-50967/cve-2023-50967.jwk | 1 +
|
||||||
|
tests/jose-jwe-dec | 5 +++++
|
||||||
|
5 files changed, 15 insertions(+), 3 deletions(-)
|
||||||
|
create mode 100644 tests/cve-2023-50967/cve-2023-50967.jwe
|
||||||
|
create mode 100644 tests/cve-2023-50967/cve-2023-50967.jwk
|
||||||
|
|
||||||
|
diff --git a/lib/openssl/pbes2.c b/lib/openssl/pbes2.c
|
||||||
|
index 0a2756e..b399c5d 100644
|
||||||
|
--- a/lib/openssl/pbes2.c
|
||||||
|
+++ b/lib/openssl/pbes2.c
|
||||||
|
@@ -25,6 +25,8 @@
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#define NAMES "PBES2-HS256+A128KW", "PBES2-HS384+A192KW", "PBES2-HS512+A256KW"
|
||||||
|
+#define P2C_MIN_ITERATIONS 1000
|
||||||
|
+#define P2C_MAX_ITERATIONS 32768
|
||||||
|
|
||||||
|
static json_t *
|
||||||
|
pbkdf2(const char *alg, jose_cfg_t *cfg, const json_t *jwk, int iter,
|
||||||
|
@@ -170,7 +172,7 @@ alg_wrap_wrp(const jose_hook_alg_t *alg, jose_cfg_t *cfg, json_t *jwe,
|
||||||
|
json_auto_t *hdr = NULL;
|
||||||
|
const char *aes = NULL;
|
||||||
|
json_t *h = NULL;
|
||||||
|
- int p2c = 10000;
|
||||||
|
+ int p2c = P2C_MAX_ITERATIONS;
|
||||||
|
size_t stl = 0;
|
||||||
|
|
||||||
|
if (!json_object_get(cek, "k") && !jose_jwk_gen(cfg, cek))
|
||||||
|
@@ -203,7 +205,7 @@ alg_wrap_wrp(const jose_hook_alg_t *alg, jose_cfg_t *cfg, json_t *jwe,
|
||||||
|
json_object_set_new(h, "p2c", json_integer(p2c)) < 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
- if (p2c < 1000)
|
||||||
|
+ if (p2c < P2C_MIN_ITERATIONS || p2c > P2C_MAX_ITERATIONS)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (json_object_set_new(h, "p2s", jose_b64_enc(st, stl)) == -1)
|
||||||
|
@@ -245,6 +247,9 @@ alg_wrap_unw(const jose_hook_alg_t *alg, jose_cfg_t *cfg, const json_t *jwe,
|
||||||
|
if (json_unpack(hdr, "{s:I}", "p2c", &p2c) == -1)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
+ if (p2c > P2C_MAX_ITERATIONS)
|
||||||
|
+ return false;
|
||||||
|
+
|
||||||
|
stl = jose_b64_dec(json_object_get(hdr, "p2s"), NULL, 0);
|
||||||
|
if (stl < 8 || stl > sizeof(st))
|
||||||
|
return false;
|
||||||
|
diff --git a/tests/Makefile.am b/tests/Makefile.am
|
||||||
|
index cd330d7..4a3651a 100644
|
||||||
|
--- a/tests/Makefile.am
|
||||||
|
+++ b/tests/Makefile.am
|
||||||
|
@@ -2,7 +2,7 @@ AM_CFLAGS = @JOSE_CFLAGS@ @OPENMP_CFLAGS@ @jansson_CFLAGS@ -I$(top_srcdir) -I$(t
|
||||||
|
LDFLAGS += $(top_builddir)/lib/libjose.la @jansson_LIBS@ @libcrypto_LIBS@ @libssl_LIBS@
|
||||||
|
EXTRA_DIST = vectors
|
||||||
|
|
||||||
|
-AM_TESTS_ENVIRONMENT=PATH=$(top_builddir)/cmd:$(PATH) VECTORS=$(top_srcdir)/tests/vectors ISSUE_75_DATADIR=$(top_srcdir)/tests/issue-75
|
||||||
|
+AM_TESTS_ENVIRONMENT=PATH=$(top_builddir)/cmd:$(PATH) VECTORS=$(top_srcdir)/tests/vectors ISSUE_75_DATADIR=$(top_srcdir)/tests/issue-75 CVE_2023_50967=$(top_srcdir)/tests/cve-2023-50967
|
||||||
|
TESTS = $(dist_check_SCRIPTS) $(check_PROGRAMS)
|
||||||
|
|
||||||
|
check_PROGRAMS = \
|
||||||
|
diff --git a/tests/cve-2023-50967/cve-2023-50967.jwe b/tests/cve-2023-50967/cve-2023-50967.jwe
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..70bfc42
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/tests/cve-2023-50967/cve-2023-50967.jwe
|
||||||
|
@@ -0,0 +1 @@
|
||||||
|
+{"ciphertext":"aaPb-JYGACs-loPwJkZewg","encrypted_key":"P1h8q8wLVxqYsZUuw6iEQTzgXVZHCsu8Eik-oqbE4AJGIDto3gb3SA","header":{"alg":"PBES2-HS256+A128KW","p2c":1000000000,"p2s":"qUQQWWkyyIqculSiC93mlg"},"iv":"Clg3JX9oNl_ck3sLSGrlgg","protected":"eyJlbmMiOiJBMTI4Q0JDLUhTMjU2In0","tag":"i7vga9tJkwRswFd7HlyD_A"}
|
||||||
|
diff --git a/tests/cve-2023-50967/cve-2023-50967.jwk b/tests/cve-2023-50967/cve-2023-50967.jwk
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..d7fb1be
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/tests/cve-2023-50967/cve-2023-50967.jwk
|
||||||
|
@@ -0,0 +1 @@
|
||||||
|
+{"alg":"PBES2-HS256+A128KW","k":"VHBLJ4-PmnqELoKbQoXuRA","key_ops":["wrapKey","unwrapKey"],"kty":"oct"}
|
||||||
|
diff --git a/tests/jose-jwe-dec b/tests/jose-jwe-dec
|
||||||
|
index 9b2143c..b5b4995 100755
|
||||||
|
--- a/tests/jose-jwe-dec
|
||||||
|
+++ b/tests/jose-jwe-dec
|
||||||
|
@@ -53,3 +53,8 @@ test "`jose jwe dec -i $prfx.12.jweg -k $prfx.12.jwk`" == "`cat $prfx.12.pt`"
|
||||||
|
test "`jose jwe dec -i $prfx.13.jweg -k $prfx.13.1.jwk`" == "`cat $prfx.13.pt`"
|
||||||
|
test "`jose jwe dec -i $prfx.13.jweg -k $prfx.13.2.jwk`" == "`cat $prfx.13.pt`"
|
||||||
|
test "`jose jwe dec -i $prfx.13.jweg -k $prfx.13.3.jwk`" == "`cat $prfx.13.pt`"
|
||||||
|
+
|
||||||
|
+# CVE-2023-50967 - test originally from https://github.com/P3ngu1nW/CVE_Request/blob/main/latch-jose.md
|
||||||
|
+# This test is expected to fail quickly on patched systems.
|
||||||
|
+prfx="${CVE_2023_50967}/cve-2023-50967"
|
||||||
|
+! test "$(jose jwe dec -i $prfx.jwe -k $prfx.jwk)"
|
||||||
|
--
|
||||||
|
2.43.0
|
||||||
|
|
111
SOURCES/0003-Adapt-alg_comp-test-to-different-zlib-142.patch
Normal file
111
SOURCES/0003-Adapt-alg_comp-test-to-different-zlib-142.patch
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
From 4878253a04be8d5b60a3b33262f60dac76eed3ec Mon Sep 17 00:00:00 2001
|
||||||
|
From: Tulio Magno Quites Machado Filho <tuliom@redhat.com>
|
||||||
|
Date: Wed, 6 Dec 2023 19:12:13 -0300
|
||||||
|
Subject: [PATCH] Adapt alg_comp test to different zlib (#142)
|
||||||
|
|
||||||
|
Different zlib implementations such as zlib-ng, QATzip and libnxz
|
||||||
|
provide API and ABI compatibility with madler's zlib. However, they do
|
||||||
|
not guarantee identical output.
|
||||||
|
This makes it very hard to compare the length or binary output of a
|
||||||
|
compressed stream.
|
||||||
|
|
||||||
|
Instead of doing that, this patch aims to compare the input against the
|
||||||
|
output of a compression and decompression cycle.
|
||||||
|
|
||||||
|
Fixes #142.
|
||||||
|
---
|
||||||
|
tests/alg_comp.c | 55 ++++++++++++++++++++++++++++--------------------
|
||||||
|
1 file changed, 32 insertions(+), 23 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/tests/alg_comp.c b/tests/alg_comp.c
|
||||||
|
index c9bef75..fcd305c 100644
|
||||||
|
--- a/tests/alg_comp.c
|
||||||
|
+++ b/tests/alg_comp.c
|
||||||
|
@@ -41,22 +41,23 @@ const struct {
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
|
-typedef typeof(((jose_hook_alg_t *) NULL)->comp.inf) comp_func_t;
|
||||||
|
-
|
||||||
|
static void
|
||||||
|
-test(const jose_hook_alg_t *a, comp_func_t func, bool iter,
|
||||||
|
- const uint8_t *i, size_t il,
|
||||||
|
- const uint8_t *o, size_t ol)
|
||||||
|
+test(const jose_hook_alg_t *a, bool iter,
|
||||||
|
+ const uint8_t *i, size_t il)
|
||||||
|
{
|
||||||
|
jose_io_auto_t *b = NULL;
|
||||||
|
+ jose_io_auto_t *c = NULL;
|
||||||
|
jose_io_auto_t *z = NULL;
|
||||||
|
- void *buf = NULL;
|
||||||
|
- size_t len = 0;
|
||||||
|
+ void *buf1 = NULL;
|
||||||
|
+ void *buf2 = NULL;
|
||||||
|
+ size_t blen = 0;
|
||||||
|
+ size_t clen = 0;
|
||||||
|
|
||||||
|
- b = jose_io_malloc(NULL, &buf, &len);
|
||||||
|
+ /* Test compression first. */
|
||||||
|
+ b = jose_io_malloc(NULL, &buf1, &blen);
|
||||||
|
assert(b);
|
||||||
|
|
||||||
|
- z = func(a, NULL, b);
|
||||||
|
+ z = a->comp.def(a, NULL, b);
|
||||||
|
assert(z);
|
||||||
|
|
||||||
|
if (iter) {
|
||||||
|
@@ -68,8 +69,26 @@ test(const jose_hook_alg_t *a, comp_func_t func, bool iter,
|
||||||
|
|
||||||
|
assert(z->done(z));
|
||||||
|
|
||||||
|
- assert(len == ol);
|
||||||
|
- assert(memcmp(buf, o, ol) == 0);
|
||||||
|
+ /* Test decompression now. */
|
||||||
|
+ c = jose_io_malloc(NULL, &buf2, &clen);
|
||||||
|
+ assert(b);
|
||||||
|
+
|
||||||
|
+ z = a->comp.inf(a, NULL, c);
|
||||||
|
+ assert(z);
|
||||||
|
+
|
||||||
|
+ if (iter) {
|
||||||
|
+ uint8_t *m = buf1;
|
||||||
|
+ for (size_t j = 0; j < blen; j++)
|
||||||
|
+ assert(z->feed(z, &m[j], 1));
|
||||||
|
+ } else {
|
||||||
|
+ assert(z->feed(z, buf1, blen));
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ assert(z->done(z));
|
||||||
|
+
|
||||||
|
+ /* Compare the final output with the original input. */
|
||||||
|
+ assert(clen == il);
|
||||||
|
+ assert(memcmp(buf2, i, il) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
@@ -93,20 +112,10 @@ main(int argc, char *argv[])
|
||||||
|
assert(jose_b64_dec_buf(tests[i].def, strlen(tests[i].def),
|
||||||
|
tst_def, sizeof(tst_def)) == sizeof(tst_def));
|
||||||
|
|
||||||
|
- test(a, a->comp.def, false,
|
||||||
|
- tst_inf, sizeof(tst_inf),
|
||||||
|
- tst_def, sizeof(tst_def));
|
||||||
|
-
|
||||||
|
- test(a, a->comp.inf, false,
|
||||||
|
- tst_def, sizeof(tst_def),
|
||||||
|
+ test(a, false,
|
||||||
|
tst_inf, sizeof(tst_inf));
|
||||||
|
|
||||||
|
- test(a, a->comp.def, true,
|
||||||
|
- tst_inf, sizeof(tst_inf),
|
||||||
|
- tst_def, sizeof(tst_def));
|
||||||
|
-
|
||||||
|
- test(a, a->comp.inf, true,
|
||||||
|
- tst_def, sizeof(tst_def),
|
||||||
|
+ test(a, true,
|
||||||
|
tst_inf, sizeof(tst_inf));
|
||||||
|
}
|
||||||
|
|
||||||
|
--
|
||||||
|
2.43.0
|
||||||
|
|
@ -0,0 +1,135 @@
|
|||||||
|
From d2917d639717a9eaf401d87844ea2b78d597d917 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Sergio Arroutbi <sarroutb@redhat.com>
|
||||||
|
Date: Mon, 1 Jul 2024 10:28:40 -0400
|
||||||
|
Subject: [PATCH] Avoid potential DoS with high decompression chunks
|
||||||
|
|
||||||
|
Backported from https://github.com/latchset/jose/pull/157
|
||||||
|
|
||||||
|
Signed-off-by: Sergio Arroutbi <sarroutb@redhat.com>
|
||||||
|
---
|
||||||
|
lib/hooks.h | 2 ++
|
||||||
|
lib/zlib/deflate.c | 3 +++
|
||||||
|
tests/alg_comp.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
3 files changed, 72 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/lib/hooks.h b/lib/hooks.h
|
||||||
|
index 9da7b40..e9c78f4 100644
|
||||||
|
--- a/lib/hooks.h
|
||||||
|
+++ b/lib/hooks.h
|
||||||
|
@@ -20,6 +20,8 @@
|
||||||
|
#include <jose/jws.h>
|
||||||
|
#include <jose/jwe.h>
|
||||||
|
|
||||||
|
+#define MAX_COMPRESSED_SIZE (256*1024)
|
||||||
|
+
|
||||||
|
typedef enum {
|
||||||
|
JOSE_HOOK_JWK_KIND_NONE = 0,
|
||||||
|
JOSE_HOOK_JWK_KIND_TYPE,
|
||||||
|
diff --git a/lib/zlib/deflate.c b/lib/zlib/deflate.c
|
||||||
|
index 07eca0c..04ded33 100644
|
||||||
|
--- a/lib/zlib/deflate.c
|
||||||
|
+++ b/lib/zlib/deflate.c
|
||||||
|
@@ -113,6 +113,9 @@ def_free(jose_io_t *io)
|
||||||
|
static bool
|
||||||
|
inf_feed(jose_io_t *io, const void *in, size_t len)
|
||||||
|
{
|
||||||
|
+ if (len > MAX_COMPRESSED_SIZE) {
|
||||||
|
+ return false;
|
||||||
|
+ }
|
||||||
|
return feed(io, in, len, inflate);
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/tests/alg_comp.c b/tests/alg_comp.c
|
||||||
|
index fcd305c..753566b 100644
|
||||||
|
--- a/tests/alg_comp.c
|
||||||
|
+++ b/tests/alg_comp.c
|
||||||
|
@@ -19,6 +19,10 @@
|
||||||
|
#include <jose/jose.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <string.h>
|
||||||
|
+#include <stdlib.h>
|
||||||
|
+
|
||||||
|
+static int g_high_compression_tested = 0;
|
||||||
|
+static int g_low_compression_tested = 0;
|
||||||
|
|
||||||
|
const struct {
|
||||||
|
const char *alg;
|
||||||
|
@@ -41,6 +45,62 @@ const struct {
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
|
+const uint32_t long_string_tests[] = {
|
||||||
|
+ 2000, 200000, 10000000, 0
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static uint8_t* get_random_string(uint32_t length)
|
||||||
|
+{
|
||||||
|
+ assert(length);
|
||||||
|
+ uint8_t* c = (uint8_t*)malloc(length*sizeof(uint8_t));
|
||||||
|
+ for (uint32_t i=0; i<length; i++) {
|
||||||
|
+ c[i] = 'A' + (random() % 26);
|
||||||
|
+ }
|
||||||
|
+ return c;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void
|
||||||
|
+test_long_string(size_t inputlen) {
|
||||||
|
+ jose_io_auto_t *b = NULL;
|
||||||
|
+ jose_io_auto_t *c = NULL;
|
||||||
|
+ jose_io_auto_t *z = NULL;
|
||||||
|
+ void *buf1 = NULL;
|
||||||
|
+ void *buf2 = NULL;
|
||||||
|
+ size_t blen = 0;
|
||||||
|
+ size_t clen = 0;
|
||||||
|
+ const jose_hook_alg_t *a = jose_hook_alg_find(JOSE_HOOK_ALG_KIND_COMP, "DEF");
|
||||||
|
+ uint8_t* str = get_random_string(inputlen);
|
||||||
|
+
|
||||||
|
+ /* Test compression first. */
|
||||||
|
+ b = jose_io_malloc(NULL, &buf1, &blen);
|
||||||
|
+ assert(b);
|
||||||
|
+ z = a->comp.def(a, NULL, b);
|
||||||
|
+ assert(z);
|
||||||
|
+
|
||||||
|
+ assert(z->feed(z, str, inputlen));
|
||||||
|
+ assert(z->done(z));
|
||||||
|
+
|
||||||
|
+ /* Test decompression now */
|
||||||
|
+ c = jose_io_malloc(NULL, &buf2, &clen);
|
||||||
|
+ assert(b);
|
||||||
|
+ z = a->comp.inf(a, NULL, c);
|
||||||
|
+ assert(z);
|
||||||
|
+
|
||||||
|
+ /* If length>MAX_COMPRESSED_SIZE, it must fail due to high decompression size */
|
||||||
|
+ if(blen > MAX_COMPRESSED_SIZE) {
|
||||||
|
+ assert(!z->feed(z, buf1, blen));
|
||||||
|
+ g_high_compression_tested = 1;
|
||||||
|
+ } else {
|
||||||
|
+ assert(z->feed(z, buf1, blen));
|
||||||
|
+ g_low_compression_tested = 1;
|
||||||
|
+ /* Compare the final output with the original input. */
|
||||||
|
+ assert(clen == inputlen);
|
||||||
|
+ assert(memcmp(buf2, str, inputlen) == 0);
|
||||||
|
+ }
|
||||||
|
+ assert(z->done(z));
|
||||||
|
+ free(str);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static void
|
||||||
|
test(const jose_hook_alg_t *a, bool iter,
|
||||||
|
const uint8_t *i, size_t il)
|
||||||
|
@@ -119,5 +179,12 @@ main(int argc, char *argv[])
|
||||||
|
tst_inf, sizeof(tst_inf));
|
||||||
|
}
|
||||||
|
|
||||||
|
+ for (size_t i = 0; long_string_tests[i]; i++) {
|
||||||
|
+ test_long_string(long_string_tests[i]);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ assert(1 == g_high_compression_tested);
|
||||||
|
+ assert(1 == g_low_compression_tested);
|
||||||
|
+
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
|
--
|
||||||
|
2.43.0
|
||||||
|
|
@ -0,0 +1,413 @@
|
|||||||
|
From c2f52c8a063aac43161b030c36f43587985e8cf7 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Sergio Correia <scorreia@redhat.com>
|
||||||
|
Date: Mon, 1 Jul 2024 10:30:39 -0400
|
||||||
|
Subject: [PATCH] jwe: fix the case when we have "zip" in the protected header
|
||||||
|
|
||||||
|
Backport from https://github.com/latchset/jose/pull/161
|
||||||
|
|
||||||
|
When we have "zip" in the protected header, e.g.: "zip": "DEF",
|
||||||
|
we should compress the payload before the encryption.
|
||||||
|
|
||||||
|
However, as it stands, we are doing the compression after the
|
||||||
|
encryption, which results in the jose_jwe_enc* functions
|
||||||
|
producing JWEs that we are unable to decrypt afterwards.
|
||||||
|
|
||||||
|
For the "zip" case, we do the compression now before the
|
||||||
|
encryption, to fix this behavior.
|
||||||
|
|
||||||
|
Also add some tests to exercise these scenarios, both using
|
||||||
|
the jose_jwe_enc*/jose_jwe_dec* functions, as well as the
|
||||||
|
command line utilities jose jwe enc / jose jwe dec.
|
||||||
|
|
||||||
|
Signed-off-by: Sergio Correia <scorreia@redhat.com>
|
||||||
|
---
|
||||||
|
lib/jwe.c | 26 +++---------
|
||||||
|
lib/misc.c | 58 +++++++++++++++++++++++++
|
||||||
|
lib/misc.h | 6 +++
|
||||||
|
lib/openssl/aescbch.c | 9 +++-
|
||||||
|
lib/openssl/aesgcm.c | 10 ++++-
|
||||||
|
tests/alg_comp.c | 1 +
|
||||||
|
tests/api_jwe.c | 99 +++++++++++++++++++++++++++++++++++++++++--
|
||||||
|
tests/jose-jwe-enc | 9 ++++
|
||||||
|
8 files changed, 192 insertions(+), 26 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/lib/jwe.c b/lib/jwe.c
|
||||||
|
index 516245b..55b4333 100644
|
||||||
|
--- a/lib/jwe.c
|
||||||
|
+++ b/lib/jwe.c
|
||||||
|
@@ -275,14 +275,8 @@ jose_jwe_enc_cek_io(jose_cfg_t *cfg, json_t *jwe, const json_t *cek,
|
||||||
|
jose_io_t *next)
|
||||||
|
{
|
||||||
|
const jose_hook_alg_t *alg = NULL;
|
||||||
|
- jose_io_auto_t *zip = NULL;
|
||||||
|
- json_auto_t *prt = NULL;
|
||||||
|
const char *h = NULL;
|
||||||
|
const char *k = NULL;
|
||||||
|
- const char *z = NULL;
|
||||||
|
-
|
||||||
|
- prt = jose_b64_dec_load(json_object_get(jwe, "protected"));
|
||||||
|
- (void) json_unpack(prt, "{s:s}", "zip", &z);
|
||||||
|
|
||||||
|
if (json_unpack(jwe, "{s?{s?s}}", "unprotected", "enc", &h) < 0)
|
||||||
|
return NULL;
|
||||||
|
@@ -336,19 +330,7 @@ jose_jwe_enc_cek_io(jose_cfg_t *cfg, json_t *jwe, const json_t *cek,
|
||||||
|
if (!encode_protected(jwe))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
- if (z) {
|
||||||
|
- const jose_hook_alg_t *a = NULL;
|
||||||
|
-
|
||||||
|
- a = jose_hook_alg_find(JOSE_HOOK_ALG_KIND_COMP, z);
|
||||||
|
- if (!a)
|
||||||
|
- return NULL;
|
||||||
|
-
|
||||||
|
- zip = a->comp.def(a, cfg, next);
|
||||||
|
- if (!zip)
|
||||||
|
- return NULL;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- return alg->encr.enc(alg, cfg, jwe, cek, zip ? zip : next);
|
||||||
|
+ return alg->encr.enc(alg, cfg, jwe, cek, next);
|
||||||
|
}
|
||||||
|
|
||||||
|
void *
|
||||||
|
@@ -463,6 +445,12 @@ jose_jwe_dec_cek(jose_cfg_t *cfg, const json_t *jwe, const json_t *cek,
|
||||||
|
o = jose_io_malloc(cfg, &pt, ptl);
|
||||||
|
d = jose_jwe_dec_cek_io(cfg, jwe, cek, o);
|
||||||
|
i = jose_b64_dec_io(d);
|
||||||
|
+
|
||||||
|
+ /* Here we make sure the ciphertext is not larger than our
|
||||||
|
+ * compression limit. */
|
||||||
|
+ if (zip_in_protected_header((json_t*)jwe) && ctl > MAX_COMPRESSED_SIZE)
|
||||||
|
+ return false;
|
||||||
|
+
|
||||||
|
if (!o || !d || !i || !i->feed(i, ct, ctl) || !i->done(i))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
diff --git a/lib/misc.c b/lib/misc.c
|
||||||
|
index 465cd0d..1015ce4 100644
|
||||||
|
--- a/lib/misc.c
|
||||||
|
+++ b/lib/misc.c
|
||||||
|
@@ -18,6 +18,7 @@
|
||||||
|
#include "misc.h"
|
||||||
|
#include <jose/b64.h>
|
||||||
|
#include <string.h>
|
||||||
|
+#include "hooks.h"
|
||||||
|
|
||||||
|
bool
|
||||||
|
encode_protected(json_t *obj)
|
||||||
|
@@ -42,6 +43,63 @@ zero(void *mem, size_t len)
|
||||||
|
memset(mem, 0, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
+
|
||||||
|
+bool
|
||||||
|
+handle_zip_enc(json_t *json, const void *in, size_t len, void **data, size_t *datalen)
|
||||||
|
+{
|
||||||
|
+ json_t *prt = NULL;
|
||||||
|
+ char *z = NULL;
|
||||||
|
+ const jose_hook_alg_t *a = NULL;
|
||||||
|
+ jose_io_auto_t *zip = NULL;
|
||||||
|
+ jose_io_auto_t *zipdata = NULL;
|
||||||
|
+
|
||||||
|
+ prt = json_object_get(json, "protected");
|
||||||
|
+ if (prt && json_is_string(prt))
|
||||||
|
+ prt = jose_b64_dec_load(prt);
|
||||||
|
+
|
||||||
|
+ /* Check if we have "zip" in the protected header. */
|
||||||
|
+ if (json_unpack(prt, "{s:s}", "zip", &z) == -1) {
|
||||||
|
+ /* No zip. */
|
||||||
|
+ *data = (void*)in;
|
||||||
|
+ *datalen = len;
|
||||||
|
+ return true;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* OK, we have "zip", so we should compress the payload before
|
||||||
|
+ * the encryption takes place. */
|
||||||
|
+ a = jose_hook_alg_find(JOSE_HOOK_ALG_KIND_COMP, z);
|
||||||
|
+ if (!a)
|
||||||
|
+ return false;
|
||||||
|
+
|
||||||
|
+ zipdata = jose_io_malloc(NULL, data, datalen);
|
||||||
|
+ if (!zipdata)
|
||||||
|
+ return false;
|
||||||
|
+
|
||||||
|
+ zip = a->comp.def(a, NULL, zipdata);
|
||||||
|
+ if (!zip || !zip->feed(zip, in, len) || !zip->done(zip))
|
||||||
|
+ return false;
|
||||||
|
+
|
||||||
|
+ return true;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+bool
|
||||||
|
+zip_in_protected_header(json_t *json)
|
||||||
|
+{
|
||||||
|
+ json_t *prt = NULL;
|
||||||
|
+ char *z = NULL;
|
||||||
|
+
|
||||||
|
+ prt = json_object_get(json, "protected");
|
||||||
|
+ if (prt && json_is_string(prt))
|
||||||
|
+ prt = jose_b64_dec_load(prt);
|
||||||
|
+
|
||||||
|
+ /* Check if we have "zip" in the protected header. */
|
||||||
|
+ if (json_unpack(prt, "{s:s}", "zip", &z) == -1)
|
||||||
|
+ return false;
|
||||||
|
+
|
||||||
|
+ /* We have "zip", but let's validate the alg also. */
|
||||||
|
+ return jose_hook_alg_find(JOSE_HOOK_ALG_KIND_COMP, z) != NULL;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static void __attribute__((constructor))
|
||||||
|
constructor(void)
|
||||||
|
{
|
||||||
|
diff --git a/lib/misc.h b/lib/misc.h
|
||||||
|
index d479d53..18e7710 100644
|
||||||
|
--- a/lib/misc.h
|
||||||
|
+++ b/lib/misc.h
|
||||||
|
@@ -30,3 +30,9 @@ encode_protected(json_t *obj);
|
||||||
|
|
||||||
|
void
|
||||||
|
zero(void *mem, size_t len);
|
||||||
|
+
|
||||||
|
+bool
|
||||||
|
+handle_zip_enc(json_t *jwe, const void *in, size_t len, void **data, size_t *data_len);
|
||||||
|
+
|
||||||
|
+bool
|
||||||
|
+zip_in_protected_header(json_t *jwe);
|
||||||
|
diff --git a/lib/openssl/aescbch.c b/lib/openssl/aescbch.c
|
||||||
|
index ce8073d..b0e6419 100644
|
||||||
|
--- a/lib/openssl/aescbch.c
|
||||||
|
+++ b/lib/openssl/aescbch.c
|
||||||
|
@@ -18,6 +18,7 @@
|
||||||
|
#include "misc.h"
|
||||||
|
#include <jose/b64.h>
|
||||||
|
#include "../hooks.h"
|
||||||
|
+#include "../misc.h"
|
||||||
|
|
||||||
|
#include <openssl/rand.h>
|
||||||
|
#include <openssl/sha.h>
|
||||||
|
@@ -132,9 +133,13 @@ enc_feed(jose_io_t *io, const void *in, size_t len)
|
||||||
|
io_t *i = containerof(io, io_t, io);
|
||||||
|
|
||||||
|
uint8_t ct[EVP_CIPHER_CTX_block_size(i->cctx) + 1];
|
||||||
|
- const uint8_t *pt = in;
|
||||||
|
+ uint8_t *pt = NULL;
|
||||||
|
+ size_t ptlen = 0;
|
||||||
|
|
||||||
|
- for (size_t j = 0; j < len; j++) {
|
||||||
|
+ if (!handle_zip_enc(i->json, in, len, (void**)&pt, &ptlen))
|
||||||
|
+ return false;
|
||||||
|
+
|
||||||
|
+ for (size_t j = 0; j < ptlen; j++) {
|
||||||
|
int l = 0;
|
||||||
|
|
||||||
|
if (EVP_EncryptUpdate(i->cctx, ct, &l, &pt[j], 1) <= 0)
|
||||||
|
diff --git a/lib/openssl/aesgcm.c b/lib/openssl/aesgcm.c
|
||||||
|
index 190b469..1a88719 100644
|
||||||
|
--- a/lib/openssl/aesgcm.c
|
||||||
|
+++ b/lib/openssl/aesgcm.c
|
||||||
|
@@ -18,6 +18,7 @@
|
||||||
|
#include "misc.h"
|
||||||
|
#include <jose/b64.h>
|
||||||
|
#include "../hooks.h"
|
||||||
|
+#include "../misc.h"
|
||||||
|
|
||||||
|
#include <openssl/rand.h>
|
||||||
|
|
||||||
|
@@ -103,10 +104,15 @@ static bool
|
||||||
|
enc_feed(jose_io_t *io, const void *in, size_t len)
|
||||||
|
{
|
||||||
|
io_t *i = containerof(io, io_t, io);
|
||||||
|
- const uint8_t *pt = in;
|
||||||
|
int l = 0;
|
||||||
|
|
||||||
|
- for (size_t j = 0; j < len; j++) {
|
||||||
|
+ uint8_t *pt = NULL;
|
||||||
|
+ size_t ptlen = 0;
|
||||||
|
+
|
||||||
|
+ if (!handle_zip_enc(i->json, in, len, (void**)&pt, &ptlen))
|
||||||
|
+ return false;
|
||||||
|
+
|
||||||
|
+ for (size_t j = 0; j < ptlen; j++) {
|
||||||
|
uint8_t ct[EVP_CIPHER_CTX_block_size(i->cctx) + 1];
|
||||||
|
|
||||||
|
if (EVP_EncryptUpdate(i->cctx, ct, &l, &pt[j], 1) <= 0)
|
||||||
|
diff --git a/tests/alg_comp.c b/tests/alg_comp.c
|
||||||
|
index 753566b..33dc32e 100644
|
||||||
|
--- a/tests/alg_comp.c
|
||||||
|
+++ b/tests/alg_comp.c
|
||||||
|
@@ -53,6 +53,7 @@ static uint8_t* get_random_string(uint32_t length)
|
||||||
|
{
|
||||||
|
assert(length);
|
||||||
|
uint8_t* c = (uint8_t*)malloc(length*sizeof(uint8_t));
|
||||||
|
+ assert(c);
|
||||||
|
for (uint32_t i=0; i<length; i++) {
|
||||||
|
c[i] = 'A' + (random() % 26);
|
||||||
|
}
|
||||||
|
diff --git a/tests/api_jwe.c b/tests/api_jwe.c
|
||||||
|
index f1d7a48..5fa4e10 100644
|
||||||
|
--- a/tests/api_jwe.c
|
||||||
|
+++ b/tests/api_jwe.c
|
||||||
|
@@ -19,8 +19,10 @@
|
||||||
|
#include <assert.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
+#include "../lib/hooks.h" /* for MAX_COMPRESSED_SIZE */
|
||||||
|
+
|
||||||
|
static bool
|
||||||
|
-dec(json_t *jwe, json_t *jwk)
|
||||||
|
+dec_cmp(json_t *jwe, json_t *jwk, const char* expected_data, size_t expected_len)
|
||||||
|
{
|
||||||
|
bool ret = false;
|
||||||
|
char *pt = NULL;
|
||||||
|
@@ -30,10 +32,10 @@ dec(json_t *jwe, json_t *jwk)
|
||||||
|
if (!pt)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
- if (ptl != 4)
|
||||||
|
+ if (ptl != expected_len)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
- if (strcmp(pt, "foo") != 0)
|
||||||
|
+ if (strcmp(pt, expected_data) != 0)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
ret = true;
|
||||||
|
@@ -43,12 +45,40 @@ error:
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static bool
|
||||||
|
+dec(json_t *jwe, json_t *jwk)
|
||||||
|
+{
|
||||||
|
+ return dec_cmp(jwe, jwk, "foo", 4);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+struct zip_test_data_t {
|
||||||
|
+ char* data;
|
||||||
|
+ size_t datalen;
|
||||||
|
+ bool expected;
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static char*
|
||||||
|
+make_data(size_t len)
|
||||||
|
+{
|
||||||
|
+ assert(len > 0);
|
||||||
|
+
|
||||||
|
+ char *data = malloc(len);
|
||||||
|
+ assert(data);
|
||||||
|
+
|
||||||
|
+ for (size_t i = 0; i < len; i++) {
|
||||||
|
+ data[i] = 'A' + (random() % 26);
|
||||||
|
+ }
|
||||||
|
+ data[len-1] = '\0';
|
||||||
|
+ return data;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
int
|
||||||
|
main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
json_auto_t *jwke = json_pack("{s:s}", "alg", "ECDH-ES+A128KW");
|
||||||
|
json_auto_t *jwkr = json_pack("{s:s}", "alg", "RSA1_5");
|
||||||
|
json_auto_t *jwko = json_pack("{s:s}", "alg", "A128KW");
|
||||||
|
+ json_auto_t *jwkz = json_pack("{s:s, s:i}", "kty", "oct", "bytes", 16);
|
||||||
|
json_auto_t *set0 = json_pack("{s:[O,O]}", "keys", jwke, jwko);
|
||||||
|
json_auto_t *set1 = json_pack("{s:[O,O]}", "keys", jwkr, jwko);
|
||||||
|
json_auto_t *set2 = json_pack("{s:[O,O]}", "keys", jwke, jwkr);
|
||||||
|
@@ -57,6 +87,7 @@ main(int argc, char *argv[])
|
||||||
|
assert(jose_jwk_gen(NULL, jwke));
|
||||||
|
assert(jose_jwk_gen(NULL, jwkr));
|
||||||
|
assert(jose_jwk_gen(NULL, jwko));
|
||||||
|
+ assert(jose_jwk_gen(NULL, jwkz));
|
||||||
|
|
||||||
|
json_decref(jwe);
|
||||||
|
assert((jwe = json_object()));
|
||||||
|
@@ -98,5 +129,67 @@ main(int argc, char *argv[])
|
||||||
|
assert(dec(jwe, set1));
|
||||||
|
assert(dec(jwe, set2));
|
||||||
|
|
||||||
|
+
|
||||||
|
+ json_decref(jwe);
|
||||||
|
+ assert((jwe = json_pack("{s:{s:s,s:s,s:s,s:s}}", "protected", "alg", "A128KW", "enc", "A128GCM", "typ", "JWE", "zip", "DEF")));
|
||||||
|
+ assert(jose_jwe_enc(NULL, jwe, NULL, jwkz, "foo", 4));
|
||||||
|
+ assert(dec(jwe, jwkz));
|
||||||
|
+ assert(!dec(jwe, jwkr));
|
||||||
|
+ assert(!dec(jwe, jwko));
|
||||||
|
+ assert(!dec(jwe, set0));
|
||||||
|
+ assert(!dec(jwe, set1));
|
||||||
|
+ assert(!dec(jwe, set2));
|
||||||
|
+
|
||||||
|
+ /* Some tests with "zip": "DEF" */
|
||||||
|
+ struct zip_test_data_t zip[] = {
|
||||||
|
+ {
|
||||||
|
+ .data = make_data(5),
|
||||||
|
+ .datalen = 5,
|
||||||
|
+ .expected = true,
|
||||||
|
+ },
|
||||||
|
+ {
|
||||||
|
+ .data = make_data(50),
|
||||||
|
+ .datalen = 50,
|
||||||
|
+ .expected = true,
|
||||||
|
+ },
|
||||||
|
+ {
|
||||||
|
+ .data = make_data(1000),
|
||||||
|
+ .datalen = 1000,
|
||||||
|
+ .expected = true,
|
||||||
|
+ },
|
||||||
|
+ {
|
||||||
|
+ .data = make_data(10000000),
|
||||||
|
+ .datalen = 10000000,
|
||||||
|
+ .expected = false, /* compressed len will be ~8000000+
|
||||||
|
+ * (i.e. > MAX_COMPRESSED_SIZE)
|
||||||
|
+ */
|
||||||
|
+ },
|
||||||
|
+ {
|
||||||
|
+ .data = make_data(50000),
|
||||||
|
+ .datalen = 50000,
|
||||||
|
+ .expected = true
|
||||||
|
+ },
|
||||||
|
+ {
|
||||||
|
+
|
||||||
|
+ .data = NULL
|
||||||
|
+ }
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ for (size_t i = 0; zip[i].data != NULL; i++) {
|
||||||
|
+ json_decref(jwe);
|
||||||
|
+ assert((jwe = json_pack("{s:{s:s,s:s,s:s,s:s}}", "protected", "alg", "A128KW", "enc", "A128GCM", "typ", "JWE", "zip", "DEF")));
|
||||||
|
+ assert(jose_jwe_enc(NULL, jwe, NULL, jwkz, zip[i].data, zip[i].datalen));
|
||||||
|
+
|
||||||
|
+ /* Now let's get the ciphertext compressed len. */
|
||||||
|
+ char *ct = NULL;
|
||||||
|
+ size_t ctl = 0;
|
||||||
|
+ assert(json_unpack(jwe, "{s:s%}", "ciphertext", &ct, &ctl) != -1);
|
||||||
|
+ /* And check our expectation is correct. */
|
||||||
|
+ assert(zip[i].expected == (ctl < MAX_COMPRESSED_SIZE));
|
||||||
|
+
|
||||||
|
+ assert(dec_cmp(jwe, jwkz, zip[i].data, zip[i].datalen) == zip[i].expected);
|
||||||
|
+ free(zip[i].data);
|
||||||
|
+ zip[i].data = NULL;
|
||||||
|
+ }
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
|
diff --git a/tests/jose-jwe-enc b/tests/jose-jwe-enc
|
||||||
|
index 4644aee..0091c4b 100755
|
||||||
|
--- a/tests/jose-jwe-enc
|
||||||
|
+++ b/tests/jose-jwe-enc
|
||||||
|
@@ -75,4 +75,13 @@ for msg in "hi" "this is a longer message that is more than one block"; do
|
||||||
|
echo -n "$msg" | jose jwe enc -I- -k $jwk -o $jwe
|
||||||
|
[ "`jose jwe dec -i $jwe -k $jwk -O-`" == "$msg" ]
|
||||||
|
done
|
||||||
|
+
|
||||||
|
+ # "zip": "DEF"
|
||||||
|
+ tmpl='{"kty":"oct","bytes":32}'
|
||||||
|
+ for enc in A128CBC-HS256 A192CBC-HS384 A256CBC-HS512 A128GCM A192GCM A256GCM; do
|
||||||
|
+ jose jwk gen -i "${tmpl}" -o "${jwk}"
|
||||||
|
+ zip="$(printf '{"alg":"A128KW","enc":"%s","zip":"DEF"}' "${enc}")"
|
||||||
|
+ printf '%s' "${msg}" | jose jwe enc -i "${zip}" -I- -k "${jwk}" -o "${jwe}"
|
||||||
|
+ [ "$(jose jwe dec -i "${jwe}" -k "${jwk}" -O-)" = "${msg}" ]
|
||||||
|
+ done
|
||||||
|
done
|
||||||
|
--
|
||||||
|
2.43.0
|
||||||
|
|
@ -1,21 +1,23 @@
|
|||||||
Name: jose
|
Name: jose
|
||||||
Version: 11
|
Version: 10
|
||||||
Release: 3%{?dist}
|
Release: 2%{?dist}.3
|
||||||
Summary: Tools for JSON Object Signing and Encryption (JOSE)
|
Summary: Tools for JSON Object Signing and Encryption (JOSE)
|
||||||
|
|
||||||
License: ASL 2.0
|
License: ASL 2.0
|
||||||
URL: https://github.com/latchset/%{name}
|
URL: https://github.com/latchset/%{name}
|
||||||
Source0: https://github.com/latchset/%{name}/releases/download/v%{version}/%{name}-%{version}.tar.xz
|
Source0: https://github.com/latchset/%{name}/releases/download/v%{version}/%{name}-%{version}.tar.bz2
|
||||||
|
|
||||||
|
Patch1: 0001-openssl-decode-private-exponent-when-converting-jwk-.patch
|
||||||
|
Patch2: 0002-Fix-potential-DoS-issue-with-p2c-header.patch
|
||||||
|
Patch3: 0003-Adapt-alg_comp-test-to-different-zlib-142.patch
|
||||||
|
Patch4: 0004-Avoid-potential-DoS-with-high-decompression-chunks.patch
|
||||||
|
Patch5: 0005-jwe-fix-the-case-when-we-have-zip-in-the-protected-h.patch
|
||||||
|
|
||||||
BuildRequires: gcc
|
|
||||||
BuildRequires: pkgconfig
|
BuildRequires: pkgconfig
|
||||||
BuildRequires: jansson-devel >= 2.10
|
BuildRequires: jansson-devel >= 2.10
|
||||||
BuildRequires: openssl-devel
|
BuildRequires: openssl-devel
|
||||||
BuildRequires: zlib-devel
|
BuildRequires: zlib-devel
|
||||||
BuildRequires: git-core
|
BuildRequires: autoconf automake libtool
|
||||||
BuildRequires: meson
|
|
||||||
BuildRequires: ninja-build
|
|
||||||
BuildRequires: asciidoc
|
|
||||||
Requires: lib%{name}%{?_isa} = %{version}-%{release}
|
Requires: lib%{name}%{?_isa} = %{version}-%{release}
|
||||||
|
|
||||||
%description
|
%description
|
||||||
@ -48,26 +50,30 @@ Obsoletes: lib%{name}-zlib-devel < %{version}-%{release}
|
|||||||
This package contains development files for lib%{name}.
|
This package contains development files for lib%{name}.
|
||||||
|
|
||||||
%prep
|
%prep
|
||||||
%autosetup -S git
|
%autosetup -p1
|
||||||
|
autoreconf -fv --install
|
||||||
|
|
||||||
%build
|
%build
|
||||||
%meson
|
%if 0%{?rhel}
|
||||||
%meson_build
|
%__sed -i 's|libcrypto >= 1\.0\.2|libcrypto >= 1\.0\.1|' configure
|
||||||
|
%endif
|
||||||
|
%configure --disable-openmp
|
||||||
|
make %{?_smp_mflags}
|
||||||
|
|
||||||
%install
|
%install
|
||||||
rm -rf %{buildroot}
|
rm -rf %{buildroot}
|
||||||
%meson_install
|
%make_install
|
||||||
rm -rf %{buildroot}/%{_libdir}/lib%{name}.la
|
rm -rf %{buildroot}/%{_libdir}/lib%{name}.la
|
||||||
|
|
||||||
%check
|
%check
|
||||||
%meson_test
|
make %{?_smp_mflags} check
|
||||||
|
|
||||||
%ldconfig_scriptlets -n lib%{name}
|
%post -n lib%{name} -p /sbin/ldconfig
|
||||||
|
%postun -n lib%{name} -p /sbin/ldconfig
|
||||||
|
|
||||||
%files
|
%files
|
||||||
%{_bindir}/%{name}
|
%{_bindir}/%{name}
|
||||||
%{_mandir}/man1/jose*.1*
|
%{_mandir}/man1/jose*.1*
|
||||||
%license COPYING
|
|
||||||
|
|
||||||
%files -n lib%{name}
|
%files -n lib%{name}
|
||||||
%license COPYING
|
%license COPYING
|
||||||
@ -81,43 +87,16 @@ rm -rf %{buildroot}/%{_libdir}/lib%{name}.la
|
|||||||
%{_mandir}/man3/jose*.3*
|
%{_mandir}/man3/jose*.3*
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
* Mon Aug 09 2021 Mohan Boddu <mboddu@redhat.com> - 11-3
|
* Mon Jul 01 2024 Sergio Correia <scorreia@redhat.com> - 10-2.3
|
||||||
- Rebuilt for IMA sigs, glibc 2.34, aarch64 flags
|
- Backport fix for CVE-2024-28176
|
||||||
Related: rhbz#1991688
|
Resolves: RHEL-28719
|
||||||
|
|
||||||
* Wed Jun 16 2021 Mohan Boddu <mboddu@redhat.com> - 11-2
|
* Mon Jul 01 2024 Sergio Correia <scorreia@redhat.com> - 10-2.2
|
||||||
- Rebuilt for RHEL 9 BETA for openssl 3.0
|
- Fix tests on s390x
|
||||||
Related: rhbz#1971065
|
Related: RHEL-29857
|
||||||
|
|
||||||
* Fri May 07 2021 Sergio Correia <scorreia@redhat.com> - 11-1
|
* Sun Jun 30 2024 Sergio Correia <scorreia@redhat.com> - 10-2.1
|
||||||
- Update to new jose upstream release, v11.
|
- Fixes CVE-2023-50967
|
||||||
Resolves: rhbz#1935983
|
|
||||||
Resolves: rhbz#1958067
|
|
||||||
|
|
||||||
* Fri Apr 16 2021 Mohan Boddu <mboddu@redhat.com> - 10-10
|
|
||||||
- Rebuilt for RHEL 9 BETA on Apr 15th 2021. Related: rhbz#1947937
|
|
||||||
|
|
||||||
* Tue Jan 26 2021 Fedora Release Engineering <releng@fedoraproject.org> - 10-9
|
|
||||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild
|
|
||||||
|
|
||||||
* Tue Jul 28 2020 Tom Stellard <tstellar@redhat.com> - 10-8
|
|
||||||
- Use make macros
|
|
||||||
- https://fedoraproject.org/wiki/Changes/UseMakeBuildInstallMacro
|
|
||||||
|
|
||||||
* Tue Jul 28 2020 Fedora Release Engineering <releng@fedoraproject.org> - 10-7
|
|
||||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild
|
|
||||||
|
|
||||||
* Wed Jan 29 2020 Fedora Release Engineering <releng@fedoraproject.org> - 10-6
|
|
||||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild
|
|
||||||
|
|
||||||
* Thu Jul 25 2019 Fedora Release Engineering <releng@fedoraproject.org> - 10-5
|
|
||||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild
|
|
||||||
|
|
||||||
* Fri Feb 01 2019 Fedora Release Engineering <releng@fedoraproject.org> - 10-4
|
|
||||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild
|
|
||||||
|
|
||||||
* Fri Jul 13 2018 Fedora Release Engineering <releng@fedoraproject.org> - 10-3
|
|
||||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild
|
|
||||||
|
|
||||||
* Wed Feb 07 2018 Fedora Release Engineering <releng@fedoraproject.org> - 10-2
|
* Wed Feb 07 2018 Fedora Release Engineering <releng@fedoraproject.org> - 10-2
|
||||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild
|
- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild
|
||||||
|
Loading…
Reference in New Issue
Block a user