diff --git a/0001-openssl-decode-private-exponent-when-converting-jwk-.patch b/0001-openssl-decode-private-exponent-when-converting-jwk-.patch new file mode 100644 index 0000000..b09fff0 --- /dev/null +++ b/0001-openssl-decode-private-exponent-when-converting-jwk-.patch @@ -0,0 +1,187 @@ +From 70cebe8c2f14ad9e7b8359ed53188bbd8ac3cce5 Mon Sep 17 00:00:00 2001 +From: Sergio Correia +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 +--- + 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 ++#include ++#include ++#include ++#include ++ ++#include ++#include ++ ++/* ++ * 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 + diff --git a/0002-Fix-potential-DoS-issue-with-p2c-header.patch b/0002-Fix-potential-DoS-issue-with-p2c-header.patch new file mode 100644 index 0000000..249c9df --- /dev/null +++ b/0002-Fix-potential-DoS-issue-with-p2c-header.patch @@ -0,0 +1,112 @@ +From 6825e070ef5cdcaf815bbd99089a3a6ef8b785d7 Mon Sep 17 00:00:00 2001 +From: Sergio Correia +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 +--- + 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 + + #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 + diff --git a/jose.spec b/jose.spec index dfb13ed..9bf3fb9 100644 --- a/jose.spec +++ b/jose.spec @@ -1,16 +1,20 @@ Name: jose Version: 10 -Release: 2%{?dist} +Release: 2%{?dist}.1 Summary: Tools for JSON Object Signing and Encryption (JOSE) License: ASL 2.0 URL: https://github.com/latchset/%{name} 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 + BuildRequires: pkgconfig BuildRequires: jansson-devel >= 2.10 BuildRequires: openssl-devel BuildRequires: zlib-devel +BuildRequires: autoconf automake libtool Requires: lib%{name}%{?_isa} = %{version}-%{release} %description @@ -43,7 +47,8 @@ Obsoletes: lib%{name}-zlib-devel < %{version}-%{release} This package contains development files for lib%{name}. %prep -%setup -q +%autosetup -p1 +autoreconf -fv --install %build %if 0%{?rhel} @@ -79,6 +84,9 @@ make %{?_smp_mflags} check %{_mandir}/man3/jose*.3* %changelog +* Sun Jun 30 2024 Sergio Correia - 10-2.1 +- Fixes CVE-2023-50967 + * Wed Feb 07 2018 Fedora Release Engineering - 10-2 - Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild