From 062b0d57e535b210c60bdc9d2c60948904b55ac1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dan=20Hor=C3=A1k?= Date: Wed, 10 Apr 2024 14:20:49 +0200 Subject: [PATCH] - SE-tooling: New IBM host-key subject locality (RHEL-30398) - dbginfo.sh: missing data of new ROCE cards (RHEL-24110) - Resolves: RHEL-30398 RHEL-24110 --- s390utils-2.29.0-rhel.patch | 1028 ++++++++++++++++++++++++++++++++++- s390utils.spec | 7 +- 2 files changed, 1008 insertions(+), 27 deletions(-) diff --git a/s390utils-2.29.0-rhel.patch b/s390utils-2.29.0-rhel.patch index cee3cc7..9bc7f2c 100644 --- a/s390utils-2.29.0-rhel.patch +++ b/s390utils-2.29.0-rhel.patch @@ -1,7 +1,7 @@ From a32824922cb273703bacd44e6a29cbc33ae48cf5 Mon Sep 17 00:00:00 2001 From: Ingo Franzki Date: Fri, 21 Jul 2023 14:06:18 +0200 -Subject: [PATCH 01/13] zkey: Support EP11 AES keys with prepended header to +Subject: [PATCH 01/18] zkey: Support EP11 AES keys with prepended header to retain EP11 session (RHEL-11440) The pkey kernel module supports two key blob formats for EP11 AES keys. @@ -730,13 +730,13 @@ index 3000290..843e554 100644 "secure AES key"); } -- -2.43.0 +2.44.0 From df0819ca69dbef1f99321f51cd9c4d33c6374992 Mon Sep 17 00:00:00 2001 From: Steffen Eiden Date: Mon, 7 Aug 2023 16:56:54 +0200 -Subject: [PATCH 02/13] rust/Makefile: Fix use of Cargoflags for 'make clean' +Subject: [PATCH 02/18] rust/Makefile: Fix use of Cargoflags for 'make clean' MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -763,13 +763,13 @@ index cf2fda7..420bafd 100644 rust-test: .check-cargo .no-cross-compile -- -2.43.0 +2.44.0 From b6ce8c7fc10c225c0b1d59af32edd323f5817ab7 Mon Sep 17 00:00:00 2001 From: Steffen Eiden Date: Mon, 7 Aug 2023 16:56:55 +0200 -Subject: [PATCH 03/13] rust/README.md: Fix some typos +Subject: [PATCH 03/18] rust/README.md: Fix some typos MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -833,13 +833,13 @@ index 2622bba..61b0af8 100644 } ``` -- -2.43.0 +2.44.0 From 883d28afea6ea18b1001ebf9e3d921d86be9c593 Mon Sep 17 00:00:00 2001 From: Marc Hartmayer Date: Mon, 4 Sep 2023 14:18:50 +0200 -Subject: [PATCH 04/13] rust/**/*.rs: fix `cargo clippy` findings +Subject: [PATCH 04/18] rust/**/*.rs: fix `cargo clippy` findings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -1205,13 +1205,13 @@ index 2b3e861..bf491c6 100644 let exp = get_test_asset!("exp/asrcb/null_none_default_cuid_seven"); -- -2.43.0 +2.44.0 From 4c8072cebe9add441c42e62663d4089d14d32389 Mon Sep 17 00:00:00 2001 From: Steffen Eiden Date: Wed, 25 Oct 2023 15:26:14 +0200 -Subject: [PATCH 05/13] rust/pv: fix Invalid write of size 1 +Subject: [PATCH 05/18] rust/pv: fix Invalid write of size 1 Fix a valgrind finding. Fix an invalid read/write of one byte after the actual struct to clear. Not fixing this may result in a illegal write or @@ -1240,13 +1240,13 @@ index cdef9ef..88287c8 100644 } std::sync::atomic::compiler_fence(std::sync::atomic::Ordering::SeqCst); -- -2.43.0 +2.44.0 From 49eabe2d13ea3909f4c522fefaf8db998c7ab888 Mon Sep 17 00:00:00 2001 From: Steffen Eiden Date: Wed, 4 Oct 2023 10:59:34 +0200 -Subject: [PATCH 06/13] rust: Create workspace +Subject: [PATCH 06/18] rust: Create workspace A workspaces simplifies the build and packaging process significantly. All build artifacts and binaries are now built in a single location @@ -1492,13 +1492,13 @@ index 30bbbc8..215381b 100644 +edition.workspace = true +license.workspace = true -- -2.43.0 +2.44.0 From be47ce72f4ee7dc7ed2dafb9b89079b0c2b154fa Mon Sep 17 00:00:00 2001 From: Steffen Eiden Date: Wed, 4 Oct 2023 11:08:20 +0200 -Subject: [PATCH 07/13] rust: Update dependency files +Subject: [PATCH 07/18] rust: Update dependency files With the last patch introducing the rust workspace the location of Cargo.lock has changed. Therefore, remove all crate level lock-files and @@ -1912,13 +1912,13 @@ index 1db32c2..f7d1cf0 100644 name = "winapi" version = "0.3.9" -- -2.43.0 +2.44.0 From c25115c0d605c9c79efd8e17d4917a35603c0766 Mon Sep 17 00:00:00 2001 From: Steffen Eiden Date: Tue, 21 Nov 2023 13:27:21 +0100 -Subject: [PATCH 08/13] rust: Sanitize minimal dependencies +Subject: [PATCH 08/18] rust: Sanitize minimal dependencies The crate dependencies were a bit to slack. Due to the rust dependency resolver's strategy of always selecting the latest version this never @@ -2009,13 +2009,13 @@ index d1e75b1..e236c00 100644 pv = { path = "../pv", features = ["uvsecret", "request"] } -- -2.43.0 +2.44.0 From b6009c80b112ad85ca2aa649126b913af5af253c Mon Sep 17 00:00:00 2001 From: Steffen Eiden Date: Wed, 29 Nov 2023 17:06:50 +0100 -Subject: [PATCH 09/13] rust: Use default panic behaviour +Subject: [PATCH 09/18] rust: Use default panic behaviour Reviewed-by: Marc Hartmayer Signed-off-by: Steffen Eiden @@ -2034,13 +2034,13 @@ index 65a70a9..7ba1faa 100644 lto = true -panic = "abort" -- -2.43.0 +2.44.0 From c4e48d060b7d92d7c6cd150728ecb55b301afa62 Mon Sep 17 00:00:00 2001 From: Steffen Eiden Date: Thu, 30 Nov 2023 16:02:16 +0100 -Subject: [PATCH 10/13] rust/pv: Update mockito to version 1 +Subject: [PATCH 10/18] rust/pv: Update mockito to version 1 Signed-off-by: Steffen Eiden (cherry picked from commit 21662d38e68b58bad033cdb1fca99987dd07cf78) @@ -2732,13 +2732,13 @@ index 1c0d2b5..5ca2e71 100644 .with_body_from_file(res_path) .create() -- -2.43.0 +2.44.0 From 66783f1901dcaca6f567ad13b05acc7dbe412ff0 Mon Sep 17 00:00:00 2001 From: Steffen Eiden Date: Wed, 20 Dec 2023 13:31:18 +0100 -Subject: [PATCH 11/13] rust/Makefile: Fix CC/AR variables for TEST_TARGETS +Subject: [PATCH 11/18] rust/Makefile: Fix CC/AR variables for TEST_TARGETS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -2766,13 +2766,13 @@ index e4e9885..fa3cf04 100644 $(PV_TARGETS): .check-dep-pvtools $(PV_TARGETS) $(CARGO_TARGETS): .check-cargo .no-cross-compile -- -2.43.0 +2.44.0 From d54a8aa4d7b77338fd5511d895eadbb074b6024a Mon Sep 17 00:00:00 2001 From: Steffen Eiden Date: Fri, 15 Dec 2023 11:30:14 +0100 -Subject: [PATCH 12/13] rust/pv: Provide access for SecretList members +Subject: [PATCH 12/18] rust/pv: Provide access for SecretList members MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -3044,13 +3044,13 @@ index 6943bd3..72a05b2 100644 fn dump_secret_entry() { const EXP: &[u8] = &[ -- -2.43.0 +2.44.0 From e75bbd754e5912d34c0aedfe35ccedd54ca850be Mon Sep 17 00:00:00 2001 From: Harald Freudenberger Date: Fri, 1 Dec 2023 12:10:20 +0100 -Subject: [PATCH 13/13] rust/pvapconfig: Introduce new tool pvapconfig +Subject: [PATCH 13/18] rust/pvapconfig: Introduce new tool pvapconfig MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -5715,5 +5715,981 @@ index 0000000..2f98bd5 + } +} -- -2.43.0 +2.44.0 + + +From 6b69de3c519971a88c5953075586b322e1efdc3e Mon Sep 17 00:00:00 2001 +From: Joern Siglen +Date: Wed, 25 Oct 2023 15:01:11 +0200 +Subject: [PATCH 14/18] dbginfo.sh: enhance ethtool collection for ROCE + (RHEL-24110) +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +collect module-info for new ROCE cards via ethtool + +Suggested-by: Niklas Schnelle +Reviewed-by: Niklas Schnelle +Signed-off-by: Joern Siglen +Signed-off-by: Jan Höppner +(cherry picked from commit d9034b01f1ddc69850a554d0077db34573560569) +--- + scripts/dbginfo.sh | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/scripts/dbginfo.sh b/scripts/dbginfo.sh +index 9226a8b..f70cf6e 100755 +--- a/scripts/dbginfo.sh ++++ b/scripts/dbginfo.sh +@@ -954,6 +954,8 @@ collect_ethtool() { + "${OUTPUT_FILE_ETHTOOL}" + call_run_command "ethtool -T ${network_device}" \ + "${OUTPUT_FILE_ETHTOOL}" ++ call_run_command "ethtool --module-info ${network_device}" \ ++ "${OUTPUT_FILE_ETHTOOL}" + done + else + pr_skip "ethtool: no devices" +-- +2.44.0 + + +From 90943f11e0feef6bc6cde3bf0b80ad0a21c55d72 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Dan=20Hor=C3=A1k?= +Date: Wed, 10 Apr 2024 11:27:58 +0200 +Subject: [PATCH 15/18] rust/pv: Support `Armonk` in IBM signing key subject + (RHEL-30398) + +New IBM signing keys will have Armonk as locality in the subject. +Ensure that CRLs with Poughkeepsie as issuer locality are still +discovered if they are signed with the signing keys private key. +Also, drop the check for issuer/subject comparison and only rely on +validity period and cryptographic signatures. + +Reviewed-by: Christoph Schlameuss +Reviewed-by: Marc Hartmayer +Signed-off-by: Steffen Eiden + +(backported from commit 1a3d0b74f7819f5e087e6ecbf3ec879a05a88bbc) +--- + rust/pv/src/verify.rs | 58 ++++++++++++++++++++++------ + rust/pv/src/verify/helper.rs | 74 +++++++++++++----------------------- + rust/pv/src/verify/test.rs | 12 ------ + 3 files changed, 73 insertions(+), 71 deletions(-) + +diff --git a/rust/pv/src/verify.rs b/rust/pv/src/verify.rs +index 54fe435..3482f8c 100644 +--- a/rust/pv/src/verify.rs ++++ b/rust/pv/src/verify.rs +@@ -3,10 +3,11 @@ + // Copyright IBM Corp. 2023 + + use core::slice; +-use log::debug; ++use log::{debug, trace}; ++use openssl::error::ErrorStack; + use openssl::stack::Stack; + use openssl::x509::store::X509Store; +-use openssl::x509::{CrlStatus, X509Ref, X509StoreContext, X509}; ++use openssl::x509::{CrlStatus, X509NameRef, X509Ref, X509StoreContext, X509StoreContextRef, X509}; + use openssl_extensions::crl::StackableX509Crl; + use openssl_extensions::crl::X509StoreContextExtension; + +@@ -76,8 +77,8 @@ impl HkdVerifier for CertVerifier { + if verified_crls.is_empty() { + bail_hkd_verify!(NoCrl); + } +- for crl in &verified_crls { +- match crl.get_by_cert(&hkd.to_owned()) { ++ for crl in verified_crls { ++ match crl.get_by_serial(hkd.serial_number()) { + CrlStatus::NotRevoked => (), + _ => bail_hkd_verify!(HdkRevoked), + } +@@ -88,21 +89,54 @@ impl HkdVerifier for CertVerifier { + } + + impl CertVerifier { ++ fn quirk_crls( ++ ctx: &mut X509StoreContextRef, ++ subject: &X509NameRef, ++ ) -> Result, ErrorStack> { ++ match ctx.crls(subject) { ++ Ok(ret) if !ret.is_empty() => return Ok(ret), ++ _ => (), ++ } ++ ++ // Armonk/Poughkeepsie fixup ++ trace!("quirk_crls: Try Locality"); ++ if let Some(locality_subject) = helper::armonk_locality_fixup(subject) { ++ match ctx.crls(&locality_subject) { ++ Ok(ret) if !ret.is_empty() => return Ok(ret), ++ _ => (), ++ } ++ ++ // reorder ++ trace!("quirk_crls: Try Locality+Reorder"); ++ if let Ok(locality_ordered_subject) = helper::reorder_x509_names(&locality_subject) { ++ match ctx.crls(&locality_ordered_subject) { ++ Ok(ret) if !ret.is_empty() => return Ok(ret), ++ _ => (), ++ } ++ } ++ } ++ ++ // reorder unchanged loaciliy subject ++ trace!("quirk_crls: Try Reorder"); ++ if let Ok(ordered_subject) = helper::reorder_x509_names(subject) { ++ match ctx.crls(&ordered_subject) { ++ Ok(ret) if !ret.is_empty() => return Ok(ret), ++ _ => (), ++ } ++ } ++ // nothing found, return empty stack ++ Stack::new() ++ } ++ + ///Download the CLRs that a HKD refers to. + pub fn hkd_crls(&self, hkd: &X509Ref) -> Result> { + let mut ctx = X509StoreContext::new()?; + // Unfortunately we cannot use a dedicated function here and have to use a closure (E0434) + // Otherwise, we cannot refer to self ++ // Search for local CRLs + let mut crls = ctx.init_opt(&self.store, None, None, |ctx| { + let subject = self.ibm_z_sign_key.subject_name(); +- match ctx.crls(subject) { +- Ok(crls) => Ok(crls), +- _ => { +- // reorder the name and try again +- let broken_subj = helper::reorder_x509_names(subject)?; +- ctx.crls(&broken_subj).or_else(helper::stack_err_hlp) +- } +- } ++ Self::quirk_crls(ctx, subject) + })?; + + if !self.offline { +diff --git a/rust/pv/src/verify/helper.rs b/rust/pv/src/verify/helper.rs +index a2f313b..732baef 100644 +--- a/rust/pv/src/verify/helper.rs ++++ b/rust/pv/src/verify/helper.rs +@@ -14,7 +14,7 @@ use openssl::{ + error::ErrorStack, + nid::Nid, + ssl::SslFiletype, +- stack::{Stack, Stackable}, ++ stack::Stack, + x509::{ + store::{File, X509Lookup, X509StoreBuilder, X509StoreBuilderRef, X509StoreRef}, + verify::{X509VerifyFlags, X509VerifyParam}, +@@ -27,6 +27,7 @@ use openssl_extensions::{ + crl::X509StoreExtension, + }; + use std::cmp::Ordering; ++use std::str::from_utf8; + use std::time::Duration; + use std::usize; + +@@ -42,7 +43,6 @@ const SECURITY_CHAIN_MAX_LEN: c_int = 2; + /// verifies that the HKD + /// * has enough security bits + /// * is inside its validity period +-/// * issuer name is the subject name of the [`sign_key`] + /// * the Authority Key ID matches the Signing Key ID of the [`sign_key`] + pub fn verify_hkd_options(hkd: &X509Ref, sign_key: &X509Ref) -> Result<()> { + let hk_pkey = hkd.public_key()?; +@@ -56,9 +56,6 @@ pub fn verify_hkd_options(hkd: &X509Ref, sign_key: &X509Ref) -> Result<()> { + // verify that the hkd is still valid + check_validity_period(hkd.not_before(), hkd.not_after())?; + +- // check if hkd.issuer_name == issuer.subject +- check_x509_name_equal(sign_key.subject_name(), hkd.issuer_name())?; +- + // verify that the AKID of the hkd matches the SKID of the issuer + if let Some(akid) = hkd.akid() { + if akid.check(sign_key) != AkidCheckResult::OK { +@@ -78,9 +75,6 @@ pub fn verify_crl(crl: &X509CrlRef, issuer: &X509Ref) -> Option<()> { + return None; + } + } +- +- check_x509_name_equal(crl.issuer_name(), issuer.subject_name()).ok()?; +- + match crl.verify(issuer.public_key().ok()?.as_ref()).ok()? { + true => Some(()), + false => None, +@@ -210,7 +204,8 @@ pub fn download_crls_into_store(store: &mut X509StoreBuilderRef, crts: &[X509]) + //Asn1StringRef::as_slice aka ASN1_STRING_get0_data gives a string without \0 delimiter + const IBM_Z_COMMON_NAME: &[u8; 43usize] = b"International Business Machines Corporation"; + const IBM_Z_COUNTRY_NAME: &[u8; 2usize] = b"US"; +-const IBM_Z_LOCALITY_NAME: &[u8; 12usize] = b"Poughkeepsie"; ++const IBM_Z_LOCALITY_NAME_POUGHKEEPSIE: &[u8; 12usize] = b"Poughkeepsie"; ++const IBM_Z_LOCALITY_NAME_ARMONK: &[u8; 6usize] = b"Armonk"; + const IBM_Z_ORGANIZATIONAL_UNIT_NAME_SUFFIX: &str = "Key Signing Service"; + const IBM_Z_ORGANIZATION_NAME: &[u8; 43usize] = b"International Business Machines Corporation"; + const IBM_Z_STATE: &[u8; 8usize] = b"New York"; +@@ -229,7 +224,8 @@ fn is_ibm_signing_cert(cert: &X509) -> bool { + if subj.entries().count() != IMB_Z_ENTRY_COUNT + || !name_data_eq(subj, Nid::COUNTRYNAME, IBM_Z_COUNTRY_NAME) + || !name_data_eq(subj, Nid::STATEORPROVINCENAME, IBM_Z_STATE) +- || !name_data_eq(subj, Nid::LOCALITYNAME, IBM_Z_LOCALITY_NAME) ++ || !(name_data_eq(subj, Nid::LOCALITYNAME, IBM_Z_LOCALITY_NAME_POUGHKEEPSIE) ++ || name_data_eq(subj, Nid::LOCALITYNAME, IBM_Z_LOCALITY_NAME_ARMONK)) + || !name_data_eq(subj, Nid::ORGANIZATIONNAME, IBM_Z_ORGANIZATION_NAME) + || !name_data_eq(subj, Nid::COMMONNAME, IBM_Z_COMMON_NAME) + { +@@ -370,23 +366,6 @@ fn check_validity_period(not_before: &Asn1TimeRef, not_after: &Asn1TimeRef) -> R + } + } + +-fn check_x509_name_equal(lhs: &X509NameRef, rhs: &X509NameRef) -> Result<()> { +- if lhs.entries().count() != rhs.entries().count() { +- bail_hkd_verify!(IssuerMismatch); +- } +- +- for l in lhs.entries() { +- let ldata = l.data().as_slice(); +- +- // search for the matching value in the rhs names +- // found none? -> names are not equal +- if !rhs.entries().any(|r| memeq(ldata, r.data().as_slice())) { +- bail_hkd_verify!(IssuerMismatch); +- } +- } +- Ok(()) +-} +- + const NIDS_CORRECT_ORDER: [Nid; 6] = [ + Nid::COUNTRYNAME, + Nid::ORGANIZATIONNAME, +@@ -409,13 +388,28 @@ pub fn reorder_x509_names(subject: &X509NameRef) -> std::result::Result( +- e: ErrorStack, +-) -> std::result::Result, openssl::error::ErrorStack> { +- match e.errors().len() { +- 0 => Stack::::new(), +- _ => Err(e), ++/** ++* Workaround for potential locality mismatches between CRLs and Certs ++* # Return ++* fixed subject or none if locality was not Armonk or any OpenSSL error ++*/ ++pub fn armonk_locality_fixup(subject: &X509NameRef) -> Option { ++ if !name_data_eq(subject, Nid::LOCALITYNAME, IBM_Z_LOCALITY_NAME_ARMONK) { ++ return None; + } ++ ++ let mut ret = X509Name::builder().ok()?; ++ for entry in subject.entries() { ++ match entry.object().nid() { ++ nid @ Nid::LOCALITYNAME => ret ++ .append_entry_by_nid(nid, from_utf8(IBM_Z_LOCALITY_NAME_POUGHKEEPSIE).ok()?) ++ .ok()?, ++ _ => { ++ ret.append_entry(entry).ok()?; ++ } ++ } ++ } ++ Some(ret.build()) + } + + #[cfg(test)] +@@ -453,20 +447,6 @@ mod test { + )); + } + +- #[test] +- fn x509_name_equal() { +- let sign_crt = load_gen_cert("ibm.crt"); +- let hkd = load_gen_cert("host.crt"); +- let other = load_gen_cert("inter_ca.crt"); +- +- assert!(super::check_x509_name_equal(sign_crt.subject_name(), hkd.issuer_name()).is_ok(),); +- +- assert!(matches!( +- super::check_x509_name_equal(other.subject_name(), hkd.subject_name()), +- Err(Error::HkdVerify(IssuerMismatch)) +- )); +- } +- + #[test] + fn is_ibm_z_sign_key() { + let ibm_crt = load_gen_cert("ibm.crt"); +diff --git a/rust/pv/src/verify/test.rs b/rust/pv/src/verify/test.rs +index 5ca2e71..e4c60c5 100644 +--- a/rust/pv/src/verify/test.rs ++++ b/rust/pv/src/verify/test.rs +@@ -99,7 +99,6 @@ fn verify_online() { + let inter_crt = get_cert_asset_path_string("inter_ca.crt"); + let ibm_crt = get_cert_asset_path_string("ibm.crt"); + let hkd_revoked = load_gen_cert("host_rev.crt"); +- let hkd_inv = load_gen_cert("host_invalid_signing_key.crt"); + let hkd_exp = load_gen_cert("host_crt_expired.crt"); + let hkd = load_gen_cert("host.crt"); + +@@ -126,11 +125,6 @@ fn verify_online() { + Err(Error::HkdVerify(HdkRevoked)) + )); + +- assert!(matches!( +- verifier.verify(&hkd_inv), +- Err(Error::HkdVerify(IssuerMismatch)) +- )); +- + assert!(matches!( + verifier.verify(&hkd_exp), + Err(Error::HkdVerify(AfterValidity)) +@@ -145,7 +139,6 @@ fn verify_offline() { + let ibm_crt = get_cert_asset_path_string("ibm.crt"); + let ibm_crl = get_cert_asset_path_string("ibm.crl"); + let hkd_revoked = load_gen_cert("host_rev.crt"); +- let hkd_inv = load_gen_cert("host_invalid_signing_key.crt"); + let hkd_exp = load_gen_cert("host_crt_expired.crt"); + let hkd = load_gen_cert("host.crt"); + +@@ -163,11 +156,6 @@ fn verify_offline() { + Err(Error::HkdVerify(HdkRevoked)) + )); + +- assert!(matches!( +- verifier.verify(&hkd_inv), +- Err(Error::HkdVerify(IssuerMismatch)) +- )); +- + assert!(matches!( + verifier.verify(&hkd_exp), + Err(Error::HkdVerify(AfterValidity)) +-- +2.44.0 + + +From e1423607a66ee37f8ae581fbf5fa013f5ab80ae8 Mon Sep 17 00:00:00 2001 +From: Marc Hartmayer +Date: Thu, 14 Mar 2024 16:05:09 +0000 +Subject: [PATCH 16/18] genprotimg: support `Armonk` in IBM signing key subject + (RHEL-30398) + +New IBM signing certificates will have 'Armonk' as locality in the +subject. Make sure that certificate revocations lists (CRL) with +'Poughkeepsie' as issuer locality are still considered as valid as long +as they are signed with the IBM signing keys private key. In addition, +drop the check for 'issuer(HKD) == subject(HKSK)' as it doesn't improve +security. While at it, remove now unused functions and fix a memory leak +of @akid in `check_crl_issuer`. + +Reviewed-by: Christoph Schlameuss +Signed-off-by: Marc Hartmayer +Signed-off-by: Steffen Eiden +(cherry picked from commit d14e7593cc6380911ca42b09e11c53477ae13d5c) +--- + genprotimg/src/include/pv_crypto_def.h | 3 +- + genprotimg/src/utils/crypto.c | 210 ++++++++++++------------- + genprotimg/src/utils/crypto.h | 1 + + 3 files changed, 104 insertions(+), 110 deletions(-) + +diff --git a/genprotimg/src/include/pv_crypto_def.h b/genprotimg/src/include/pv_crypto_def.h +index 3635433..49710dc 100644 +--- a/genprotimg/src/include/pv_crypto_def.h ++++ b/genprotimg/src/include/pv_crypto_def.h +@@ -17,7 +17,8 @@ + /* IBM signing key subject */ + #define PV_IBM_Z_SUBJECT_COMMON_NAME "International Business Machines Corporation" + #define PV_IBM_Z_SUBJECT_COUNTRY_NAME "US" +-#define PV_IBM_Z_SUBJECT_LOCALITY_NAME "Poughkeepsie" ++#define PV_IBM_Z_SUBJECT_LOCALITY_NAME_POUGHKEEPSIE "Poughkeepsie" ++#define PV_IBM_Z_SUBJECT_LOCALITY_NAME_ARMONK "Armonk" + #define PV_IBM_Z_SUBJECT_ORGANIZATIONONAL_UNIT_NAME_SUFFIX "Key Signing Service" + #define PV_IBM_Z_SUBJECT_ORGANIZATION_NAME "International Business Machines Corporation" + #define PV_IBM_Z_SUBJECT_STATE "New York" +diff --git a/genprotimg/src/utils/crypto.c b/genprotimg/src/utils/crypto.c +index e3bbf1b..86565b9 100644 +--- a/genprotimg/src/utils/crypto.c ++++ b/genprotimg/src/utils/crypto.c +@@ -664,62 +664,9 @@ static gboolean x509_name_data_by_nid_equal(X509_NAME *name, gint nid, + return memcmp(data, y, data_len) == 0; + } + +-static gboolean own_X509_NAME_ENTRY_equal(const X509_NAME_ENTRY *x, +- const X509_NAME_ENTRY *y) +-{ +- const ASN1_OBJECT *x_obj = X509_NAME_ENTRY_get_object(x); +- const ASN1_STRING *x_data = X509_NAME_ENTRY_get_data(x); +- const ASN1_OBJECT *y_obj = X509_NAME_ENTRY_get_object(y); +- const ASN1_STRING *y_data = X509_NAME_ENTRY_get_data(y); +- gint x_len = ASN1_STRING_length(x_data); +- gint y_len = ASN1_STRING_length(y_data); +- +- if (x_len < 0 || x_len != y_len) +- return FALSE; +- +- /* ASN1_STRING_cmp(x_data, y_data) == 0 doesn't work because it also +- * compares the type, which is sometimes different. +- */ +- return OBJ_cmp(x_obj, y_obj) == 0 && +- memcmp(ASN1_STRING_get0_data(x_data), +- ASN1_STRING_get0_data(y_data), +- (unsigned long)x_len) == 0; +-} +- +-static gboolean own_X509_NAME_equal(const X509_NAME *x, const X509_NAME *y) +-{ +- gint x_count = X509_NAME_entry_count(x); +- gint y_count = X509_NAME_entry_count(y); +- +- if (x != y && (!x || !y)) +- return FALSE; +- +- if (x_count != y_count) +- return FALSE; +- +- for (gint i = 0; i < x_count; i++) { +- const X509_NAME_ENTRY *entry_i = X509_NAME_get_entry(x, i); +- gboolean entry_found = FALSE; +- +- for (gint j = 0; j < y_count; j++) { +- const X509_NAME_ENTRY *entry_j = +- X509_NAME_get_entry(y, j); +- +- if (own_X509_NAME_ENTRY_equal(entry_i, entry_j)) { +- entry_found = TRUE; +- break; +- } +- } +- +- if (!entry_found) +- return FALSE; +- } +- return TRUE; +-} +- + /* Checks whether the subject of @cert is a IBM signing key subject. For this we + * must check that the subject is equal to: 'C = US, ST = New York, L = +- * Poughkeepsie, O = International Business Machines Corporation, CN = ++ * Poughkeepsie or Armonk, O = International Business Machines Corporation, CN = + * International Business Machines Corporation' and the organization unit (OUT) + * must end with the suffix ' Key Signing Service'. + */ +@@ -743,8 +690,10 @@ static gboolean has_ibm_signing_subject(X509 *cert) + PV_IBM_Z_SUBJECT_STATE)) + return FALSE; + +- if (!x509_name_data_by_nid_equal(subject, NID_localityName, +- PV_IBM_Z_SUBJECT_LOCALITY_NAME)) ++ if (!(x509_name_data_by_nid_equal(subject, NID_localityName, ++ PV_IBM_Z_SUBJECT_LOCALITY_NAME_POUGHKEEPSIE) || ++ x509_name_data_by_nid_equal(subject, NID_localityName, ++ PV_IBM_Z_SUBJECT_LOCALITY_NAME_ARMONK))) + return FALSE; + + if (!x509_name_data_by_nid_equal(subject, NID_organizationName, +@@ -806,6 +755,39 @@ static X509_NAME *x509_name_reorder_attributes(const X509_NAME *name, const gint + return g_steal_pointer(&ret); + } + ++/** Replace locality 'Armonk' with 'Pougkeepsie'. If Armonk was not set return ++ * `NULL`. ++ */ ++static X509_NAME *x509_armonk_locality_fixup(const X509_NAME *name) ++{ ++ g_autoptr(X509_NAME) ret = NULL; ++ int pos; ++ ++ /* Check if ``L=Armonk`` */ ++ if (!x509_name_data_by_nid_equal((X509_NAME *)name, NID_localityName, ++ PV_IBM_Z_SUBJECT_LOCALITY_NAME_ARMONK)) ++ return NULL; ++ ++ ret = X509_NAME_dup(name); ++ if (!ret) ++ g_abort(); ++ ++ pos = X509_NAME_get_index_by_NID(ret, NID_localityName, -1); ++ if (pos == -1) ++ return NULL; ++ ++ X509_NAME_ENTRY_free(X509_NAME_delete_entry(ret, pos)); ++ ++ /* Create a new name entry at the same position as before */ ++ if (X509_NAME_add_entry_by_NID( ++ ret, NID_localityName, MBSTRING_UTF8, ++ (const unsigned char *)&PV_IBM_Z_SUBJECT_LOCALITY_NAME_POUGHKEEPSIE, ++ sizeof(PV_IBM_Z_SUBJECT_LOCALITY_NAME_POUGHKEEPSIE) - 1, pos, 0) != 1) ++ return NULL; ++ ++ return g_steal_pointer(&ret); ++} ++ + /* In RFC 5280 the attributes of a (subject/issuer) name is not mandatory + * ordered. The problem is that our certificates are not consistent in the order + * (see https://tools.ietf.org/html/rfc5280#section-4.1.2.4 for details). +@@ -828,24 +810,10 @@ X509_NAME *c2b_name(const X509_NAME *name) + return X509_NAME_dup((X509_NAME *)name); + } + +-/* Verify that: subject(issuer) == issuer(crl) and SKID(issuer) == AKID(crl) */ ++/* Verify that SKID(issuer) == AKID(crl) if available */ + static gint check_crl_issuer(X509_CRL *crl, X509 *issuer, GError **err) + { +- const X509_NAME *crl_issuer = X509_CRL_get_issuer(crl); +- const X509_NAME *issuer_subject = X509_get_subject_name(issuer); +- AUTHORITY_KEYID *akid = NULL; +- +- if (!own_X509_NAME_equal(issuer_subject, crl_issuer)) { +- g_autofree char *issuer_subject_str = X509_NAME_oneline(issuer_subject, +- NULL, 0); +- g_autofree char *crl_issuer_str = X509_NAME_oneline(crl_issuer, NULL, 0); +- +- g_set_error(err, PV_CRYPTO_ERROR, +- PV_CRYPTO_ERROR_CRL_SUBJECT_ISSUER_MISMATCH, +- _("issuer mismatch:\n%s\n%s"), +- issuer_subject_str, crl_issuer_str); +- return -1; +- } ++ g_autoptr(AUTHORITY_KEYID) akid = NULL; + + /* If AKID(@crl) is specified it must match with SKID(@issuer) */ + akid = X509_CRL_get_ext_d2i(crl, NID_authority_key_identifier, NULL, NULL); +@@ -881,7 +849,6 @@ gint check_crl_valid_for_cert(X509_CRL *crl, X509 *cert, + return -1; + } + +- /* check that the @crl issuer matches with the subject name of @cert*/ + if (check_crl_issuer(crl, cert, err) < 0) + return -1; + +@@ -910,6 +877,60 @@ gint check_crl_valid_for_cert(X509_CRL *crl, X509 *cert, + return 0; + } + ++/* This function contains work-arounds for some known subject(CRT)<->issuer(CRL) ++ * issues. ++ */ ++static STACK_OF_X509_CRL *quirk_X509_STORE_ctx_get1_crls(X509_STORE_CTX *ctx, ++ const X509_NAME *subject, GError **err) ++{ ++ g_autoptr(X509_NAME) fixed_subject = NULL; ++ g_autoptr(STACK_OF_X509_CRL) ret = NULL; ++ ++ ret = Pv_X509_STORE_CTX_get1_crls(ctx, subject); ++ if (ret && sk_X509_CRL_num(ret) > 0) ++ return g_steal_pointer(&ret); ++ ++ /* Workaround to fix the mismatch between issuer name of the * IBM ++ * signing CRLs and the IBM signing key subject name. Locality name has ++ * changed from Poughkeepsie to Armonk. ++ */ ++ fixed_subject = x509_armonk_locality_fixup(subject); ++ /* Was the locality replaced? */ ++ if (fixed_subject) { ++ X509_NAME *tmp; ++ ++ sk_X509_CRL_free(ret); ++ ret = Pv_X509_STORE_CTX_get1_crls(ctx, fixed_subject); ++ if (ret && sk_X509_CRL_num(ret) > 0) ++ return g_steal_pointer(&ret); ++ ++ /* Workaround to fix the ordering mismatch between issuer name ++ * of the IBM signing CRLs and the IBM signing key subject name. ++ */ ++ tmp = fixed_subject; ++ fixed_subject = c2b_name(fixed_subject); ++ X509_NAME_free(tmp); ++ sk_X509_CRL_free(ret); ++ ret = Pv_X509_STORE_CTX_get1_crls(ctx, fixed_subject); ++ if (ret && sk_X509_CRL_num(ret) > 0) ++ return g_steal_pointer(&ret); ++ X509_NAME_free(fixed_subject); ++ fixed_subject = NULL; ++ } ++ ++ /* Workaround to fix the ordering mismatch between issuer name of the ++ * IBM signing CRLs and the IBM signing key subject name. ++ */ ++ fixed_subject = c2b_name(subject); ++ sk_X509_CRL_free(ret); ++ ret = Pv_X509_STORE_CTX_get1_crls(ctx, fixed_subject); ++ if (ret && sk_X509_CRL_num(ret) > 0) ++ return g_steal_pointer(&ret); ++ ++ g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_NO_CRL, _("no CRL found")); ++ return NULL; ++} ++ + /* Given a certificate @cert try to find valid revocation lists in @ctx. If no + * valid CRL was found NULL is returned. + */ +@@ -927,20 +948,9 @@ STACK_OF_X509_CRL *store_ctx_find_valid_crls(X509_STORE_CTX *ctx, X509 *cert, + return NULL; + } + +- ret = X509_STORE_CTX_get1_crls(ctx, subject); +- if (!ret) { +- /* Workaround to fix the mismatch between issuer name of the +- * IBM Z signing CRLs and the IBM Z signing key subject name. +- */ +- g_autoptr(X509_NAME) broken_subject = c2b_name(subject); +- +- ret = X509_STORE_CTX_get1_crls(ctx, broken_subject); +- if (!ret) { +- g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_NO_CRL, +- _("no CRL found")); +- return NULL; +- } +- } ++ ret = quirk_X509_STORE_ctx_get1_crls(ctx, subject, err); ++ if (!ret) ++ return NULL; + + /* Filter out non-valid CRLs for @cert */ + for (gint i = 0; i < sk_X509_CRL_num(ret); i++) { +@@ -1328,32 +1338,14 @@ gint check_chain_parameters(const STACK_OF_X509 *chain, + + /* It's almost the same as X509_check_issed from OpenSSL does except that we + * don't check the key usage of the potential issuer. This means we check: +- * 1. issuer_name(cert) == subject_name(issuer) +- * 2. Check whether the akid(cert) (if available) matches the issuer skid +- * 3. Check that the cert algrithm matches the subject algorithm +- * 4. Verify the signature of certificate @cert is using the public key of ++ * 1. Check whether the akid(cert) (if available) matches the issuer skid ++ * 2. Check that the cert algrithm matches the subject algorithm ++ * 3. Verify the signature of certificate @cert is using the public key of + * @issuer. + */ + static gint check_host_key_issued(X509 *cert, X509 *issuer, GError **err) + { +- const X509_NAME *issuer_subject = X509_get_subject_name(issuer); +- const X509_NAME *cert_issuer = X509_get_issuer_name(cert); +- AUTHORITY_KEYID *akid = NULL; +- +- /* We cannot use X509_NAME_cmp() because it considers the order of the +- * X509_NAME_Entries. +- */ +- if (!own_X509_NAME_equal(issuer_subject, cert_issuer)) { +- g_autofree char *issuer_subject_str = +- X509_NAME_oneline(issuer_subject, NULL, 0); +- g_autofree char *cert_issuer_str = +- X509_NAME_oneline(cert_issuer, NULL, 0); +- g_set_error(err, PV_CRYPTO_ERROR, +- PV_CRYPTO_ERROR_CERT_SUBJECT_ISSUER_MISMATCH, +- _("Subject issuer mismatch:\n'%s'\n'%s'"), +- issuer_subject_str, cert_issuer_str); +- return -1; +- } ++ g_autoptr(AUTHORITY_KEYID) akid = NULL; + + akid = X509_get_ext_d2i(cert, NID_authority_key_identifier, NULL, NULL); + if (akid && X509_check_akid(issuer, akid) != X509_V_OK) { +diff --git a/genprotimg/src/utils/crypto.h b/genprotimg/src/utils/crypto.h +index fdf66de..e45e57d 100644 +--- a/genprotimg/src/utils/crypto.h ++++ b/genprotimg/src/utils/crypto.h +@@ -75,6 +75,7 @@ void x509_pair_free(x509_pair *pair); + /* Register auto cleanup functions */ + WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(ASN1_INTEGER, ASN1_INTEGER_free) + WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(ASN1_OCTET_STRING, ASN1_OCTET_STRING_free) ++WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(AUTHORITY_KEYID, AUTHORITY_KEYID_free) + WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(BIGNUM, BN_free) + WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(BIO, BIO_free_all) + WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(BN_CTX, BN_CTX_free) +-- +2.44.0 + + +From 1605e9c0033e245f8a6690e2ce95a27e383722df Mon Sep 17 00:00:00 2001 +From: Steffen Eiden +Date: Tue, 12 Mar 2024 10:14:43 +0100 +Subject: [PATCH 17/18] libpv: Support `Armonk` in IBM signing key subject + (RHEL-30398) + +New IBM signing keys will have Armonk as locality in the subject. +Ensure that CRLs with Poughkeepsie as issuer locality are still +discovered if they are signed with the signing keys private key. +Also, drop the check for issuer/subject comparison and only rely on +validity period and cryptographic signatures. + +Reviewed-by: Marc Hartmayer +Reviewed-by: Christoph Schlameuss +Signed-off-by: Steffen Eiden +(cherry picked from commit d7c95265cdb6217b0203efa5893c3a27838af63c) +--- + include/libpv/cert.h | 3 +- + libpv/cert.c | 148 +++++++++++++++++++++++++++++-------------- + 2 files changed, 102 insertions(+), 49 deletions(-) + +diff --git a/include/libpv/cert.h b/include/libpv/cert.h +index bceb3c6..aebe33b 100644 +--- a/include/libpv/cert.h ++++ b/include/libpv/cert.h +@@ -16,7 +16,8 @@ + + #define PV_IBM_Z_SUBJECT_COMMON_NAME "International Business Machines Corporation" + #define PV_IBM_Z_SUBJECT_COUNTRY_NAME "US" +-#define PV_IBM_Z_SUBJECT_LOCALITY_NAME "Poughkeepsie" ++#define PV_IBM_Z_SUBJECT_LOCALITY_NAME_POUGHKEEPSIE "Poughkeepsie" ++#define PV_IBM_Z_SUBJECT_LOCALITY_NAME_ARMONK "Armonk" + #define PV_IBM_Z_SUBJECT_ORGANIZATIONAL_UNIT_NAME_SUFFIX "Key Signing Service" + #define PV_IBM_Z_SUBJECT_ORGANIZATION_NAME "International Business Machines Corporation" + #define PV_IBM_Z_SUBJECT_STATE "New York" +diff --git a/libpv/cert.c b/libpv/cert.c +index c8bb8cc..f4774fc 100644 +--- a/libpv/cert.c ++++ b/libpv/cert.c +@@ -857,7 +857,7 @@ static gboolean x509_name_data_by_nid_equal(X509_NAME *name, int nid, const char + + /* Checks whether the subject of @cert is a IBM signing key subject. For this we + * must check that the subject is equal to: 'C = US, ST = New York, L = +- * Poughkeepsie, O = International Business Machines Corporation, CN = ++ * Poughkeepsie or Armonk, O = International Business Machines Corporation, CN = + * International Business Machines Corporation' and the organization unit (OUT) + * must end with the suffix ' Key Signing Service'. + */ +@@ -879,7 +879,10 @@ static gboolean has_ibm_signing_subject(X509 *cert) + if (!x509_name_data_by_nid_equal(subject, NID_stateOrProvinceName, PV_IBM_Z_SUBJECT_STATE)) + return FALSE; + +- if (!x509_name_data_by_nid_equal(subject, NID_localityName, PV_IBM_Z_SUBJECT_LOCALITY_NAME)) ++ if (!(x509_name_data_by_nid_equal(subject, NID_localityName, ++ PV_IBM_Z_SUBJECT_LOCALITY_NAME_POUGHKEEPSIE) || ++ x509_name_data_by_nid_equal(subject, NID_localityName, ++ PV_IBM_Z_SUBJECT_LOCALITY_NAME_ARMONK))) + return FALSE; + + if (!x509_name_data_by_nid_equal(subject, NID_organizationName, +@@ -1085,10 +1088,9 @@ static int check_signature_algo_match(const EVP_PKEY *pkey, const X509 *subject, + + /* It's almost the same as X509_check_issed from OpenSSL does except that we + * don't check the key usage of the potential issuer. This means we check: +- * 1. issuer_name(cert) == subject_name(issuer) +- * 2. Check whether the akid(cert) (if available) matches the issuer skid +- * 3. Check that the cert algrithm matches the subject algorithm +- * 4. Verify the signature of certificate @cert is using the public key of ++ * 1. Check whether the akid(cert) (if available) matches the issuer skid ++ * 2. Check that the cert algrithm matches the subject algorithm ++ * 3. Verify the signature of certificate @cert is using the public key of + * @issuer. + */ + static int check_host_key_issued(X509 *cert, X509 *issuer, GError **error) +@@ -1097,19 +1099,6 @@ static int check_host_key_issued(X509 *cert, X509 *issuer, GError **error) + const X509_NAME *cert_issuer = X509_get_issuer_name(cert); + g_autoptr(AUTHORITY_KEYID) akid = NULL; + +- /* We cannot use X509_NAME_cmp() because it considers the order of the +- * X509_NAME_Entries. +- */ +- if (!own_X509_NAME_equal(issuer_subject, cert_issuer)) { +- g_autofree char *issuer_subject_str = pv_X509_NAME_oneline(issuer_subject); +- g_autofree char *cert_issuer_str = pv_X509_NAME_oneline(cert_issuer); +- +- g_set_error(error, PV_CERT_ERROR, PV_CERT_ERROR_CERT_SUBJECT_ISSUER_MISMATCH, +- _("Subject issuer mismatch:\n'%s'\n'%s'"), issuer_subject_str, +- cert_issuer_str); +- return -1; +- } +- + akid = X509_get_ext_d2i(cert, NID_authority_key_identifier, NULL, NULL); + if (akid && X509_check_akid(issuer, akid) != X509_V_OK) { + g_set_error(error, PV_CERT_ERROR, PV_CERT_ERROR_SKID_AKID_MISMATCH, +@@ -1286,21 +1275,10 @@ int pv_verify_cert(X509_STORE_CTX *ctx, X509 *cert, GError **error) + return 0; + } + +-/* Verify that: subject(issuer) == issuer(crl) and SKID(issuer) == AKID(crl) */ ++/* Verify that SKID(issuer) == AKID(crl) */ + static int check_crl_issuer(X509_CRL *crl, X509 *issuer, GError **error) + { +- const X509_NAME *crl_issuer = X509_CRL_get_issuer(crl); +- const X509_NAME *issuer_subject = X509_get_subject_name(issuer); +- AUTHORITY_KEYID *akid = NULL; +- +- if (!own_X509_NAME_equal(issuer_subject, crl_issuer)) { +- g_autofree char *issuer_subject_str = pv_X509_NAME_oneline(issuer_subject); +- g_autofree char *crl_issuer_str = pv_X509_NAME_oneline(crl_issuer); +- +- g_set_error(error, PV_CERT_ERROR, PV_CERT_ERROR_CRL_SUBJECT_ISSUER_MISMATCH, +- _("issuer mismatch:\n%s\n%s"), issuer_subject_str, crl_issuer_str); +- return -1; +- } ++ g_autoptr(AUTHORITY_KEYID) akid = NULL; + + /* If AKID(@crl) is specified it must match with SKID(@issuer) */ + akid = X509_CRL_get_ext_d2i(crl, NID_authority_key_identifier, NULL, NULL); +@@ -1325,7 +1303,6 @@ int pv_verify_crl(X509_CRL *crl, X509 *cert, int verify_flags, GError **error) + return -1; + } + +- /* check that the @crl issuer matches with the subject name of @cert*/ + if (check_crl_issuer(crl, cert, error) < 0) + return -1; + +@@ -1393,6 +1370,93 @@ int pv_check_chain_parameters(const STACK_OF_X509 *chain, GError **error) + return 0; + } + ++/** Replace locality 'Armonk' with 'Pougkeepsie'. If Armonk was not set return ++ * `NULL`. ++ */ ++static X509_NAME *x509_armonk_locality_fixup(const X509_NAME *name) ++{ ++ g_autoptr(X509_NAME) ret = NULL; ++ int pos; ++ ++ /* Check if ``L=Armonk`` */ ++ if (!x509_name_data_by_nid_equal((X509_NAME *)name, NID_localityName, ++ PV_IBM_Z_SUBJECT_LOCALITY_NAME_ARMONK)) ++ return NULL; ++ ++ ret = X509_NAME_dup(name); ++ if (!ret) ++ g_abort(); ++ ++ pos = X509_NAME_get_index_by_NID(ret, NID_localityName, -1); ++ if (pos == -1) ++ return NULL; ++ ++ X509_NAME_ENTRY_free(X509_NAME_delete_entry(ret, pos)); ++ ++ /* Create a new name entry at the same position as before */ ++ if (X509_NAME_add_entry_by_NID( ++ ret, NID_localityName, MBSTRING_UTF8, ++ (const unsigned char *)&PV_IBM_Z_SUBJECT_LOCALITY_NAME_POUGHKEEPSIE, ++ sizeof(PV_IBM_Z_SUBJECT_LOCALITY_NAME_POUGHKEEPSIE) - 1, pos, 0) != 1) ++ return NULL; ++ ++ return g_steal_pointer(&ret); ++} ++ ++/* This function contains work-arounds for some known subject(CRT)<->issuer(CRL) ++ * issues. ++ */ ++static STACK_OF_X509_CRL *quirk_X509_STORE_ctx_get1_crls(X509_STORE_CTX *ctx, ++ const X509_NAME *subject, GError **err) ++{ ++ g_autoptr(X509_NAME) fixed_subject = NULL; ++ g_autoptr(STACK_OF_X509_CRL) ret = NULL; ++ ++ ret = pv_X509_STORE_CTX_get1_crls(ctx, subject); ++ if (ret && sk_X509_CRL_num(ret) > 0) ++ return g_steal_pointer(&ret); ++ ++ /* Workaround to fix the mismatch between issuer name of the * IBM ++ * signing CRLs and the IBM signing key subject name. Locality name has ++ * changed from Poughkeepsie to Armonk. ++ */ ++ fixed_subject = x509_armonk_locality_fixup(subject); ++ /* Was the locality replaced? */ ++ if (fixed_subject) { ++ X509_NAME *tmp; ++ ++ sk_X509_CRL_free(ret); ++ ret = pv_X509_STORE_CTX_get1_crls(ctx, fixed_subject); ++ if (ret && sk_X509_CRL_num(ret) > 0) ++ return g_steal_pointer(&ret); ++ ++ /* Workaround to fix the ordering mismatch between issuer name ++ * of the IBM signing CRLs and the IBM signing key subject name. ++ */ ++ tmp = fixed_subject; ++ fixed_subject = pv_c2b_name(fixed_subject); ++ X509_NAME_free(tmp); ++ sk_X509_CRL_free(ret); ++ ret = pv_X509_STORE_CTX_get1_crls(ctx, fixed_subject); ++ if (ret && sk_X509_CRL_num(ret) > 0) ++ return g_steal_pointer(&ret); ++ X509_NAME_free(fixed_subject); ++ fixed_subject = NULL; ++ } ++ ++ /* Workaround to fix the ordering mismatch between issuer name of the ++ * IBM signing CRLs and the IBM signing key subject name. ++ */ ++ fixed_subject = pv_c2b_name(subject); ++ sk_X509_CRL_free(ret); ++ ret = pv_X509_STORE_CTX_get1_crls(ctx, fixed_subject); ++ if (ret && sk_X509_CRL_num(ret) > 0) ++ return g_steal_pointer(&ret); ++ ++ g_set_error(err, PV_CERT_ERROR, PV_CERT_ERROR_NO_CRL, _("no CRL found")); ++ return NULL; ++} ++ + /* Given a certificate @cert try to find valid revocation lists in @ctx. If no + * valid CRL was found NULL is returned. + */ +@@ -1412,21 +1476,9 @@ STACK_OF_X509_CRL *pv_store_ctx_find_valid_crls(X509_STORE_CTX *ctx, X509 *cert, + return NULL; + } + +- ret = pv_X509_STORE_CTX_get1_crls(ctx, subject); +- if (!ret) { +- /* Workaround to fix the mismatch between issuer name of the +- * IBM Z signing CRLs and the IBM Z signing key subject name. +- */ +- g_autoptr(X509_NAME) broken_subject = pv_c2b_name(subject); +- +- ret = pv_X509_STORE_CTX_get1_crls(ctx, broken_subject); +- if (!ret) { +- g_set_error(error, PV_CERT_ERROR, PV_CERT_ERROR_NO_CRL, _("no CRL found")); +- g_info("ERROR: %s", (*error)->message); +- return NULL; +- } +- } +- ++ ret = quirk_X509_STORE_ctx_get1_crls(ctx, subject, error); ++ if (!ret) ++ return NULL; + /* Filter out non-valid CRLs for @cert */ + for (int i = 0; i < sk_X509_CRL_num(ret); i++) { + X509_CRL *crl = sk_X509_CRL_value(ret, i); +-- +2.44.0 + + +From 3bd5cce64692d4b630b313cf465a55595971bed4 Mon Sep 17 00:00:00 2001 +From: Steffen Eiden +Date: Wed, 20 Mar 2024 15:36:52 +0100 +Subject: [PATCH 18/18] pvattest: Fix root-ca parsing (RHEL-30398) + +The parser setup falsely set the argument type as filename array, but +code expected a single filename. Fixed by setting up the parser +correctly to expect a single file name. + +Fixes: 3ab06d77fb1b ("pvattest: Create, perform, and verify attestation measurements") +Reviewed-by: Marc Hartmayer +Signed-off-by: Steffen Eiden +(cherry picked from commit 2b5e7b049123aff094c7de79ba57a5df09471b2e) +--- + pvattest/src/argparse.c | 14 +++++++------- + 1 file changed, 7 insertions(+), 7 deletions(-) + +diff --git a/pvattest/src/argparse.c b/pvattest/src/argparse.c +index fe5662f..5924ddc 100644 +--- a/pvattest/src/argparse.c ++++ b/pvattest/src/argparse.c +@@ -192,13 +192,13 @@ static gboolean hex_str_toull(const char *nptr, uint64_t *dst, GError **error) + } + + /* NOTE REQUIRED */ +-#define _entry_root_ca(__arg_data, __indent) \ +- { \ +- .long_name = "root-ca", .short_name = 0, .flags = G_OPTION_FLAG_NONE, \ +- .arg = G_OPTION_ARG_FILENAME_ARRAY, .arg_data = __arg_data, \ +- .description = "Use FILE as the trusted root CA instead the\n" __indent \ +- "root CAs that are installed on the system (optional).\n", \ +- .arg_description = "FILE", \ ++#define _entry_root_ca(__arg_data, __indent) \ ++ { \ ++ .long_name = "root-ca", .short_name = 0, .flags = G_OPTION_FLAG_NONE, \ ++ .arg = G_OPTION_ARG_FILENAME, .arg_data = __arg_data, \ ++ .description = "Use FILE as the trusted root CA instead the\n" __indent \ ++ "root CAs that are installed on the system (optional).\n", \ ++ .arg_description = "FILE", \ + } + + /* NOTE REQUIRED */ +-- +2.44.0 diff --git a/s390utils.spec b/s390utils.spec index 83ecd0a..87e13e2 100644 --- a/s390utils.spec +++ b/s390utils.spec @@ -18,7 +18,7 @@ Name: s390utils Summary: Utilities and daemons for IBM z Systems Version: 2.29.0 -Release: 3%{?dist} +Release: 3%{?dist}.1 Epoch: 2 License: MIT #URL: http://www.ibm.com/developerworks/linux/linux390/s390-tools.html @@ -1171,6 +1171,11 @@ User-space development files for the s390/s390x architecture. %changelog +* Wed Apr 10 2024 Dan Horák - 2:2.29.0-3.1 +- SE-tooling: New IBM host-key subject locality (RHEL-30398) +- dbginfo.sh: missing data of new ROCE cards (RHEL-24110) +- Resolves: RHEL-30398 RHEL-24110 + * Mon Jan 29 2024 Dan Horák - 2:2.29.0-3 - add s390utils-se-data as a noarch subpackage with Secure Execution data files - Resolves: RHEL-10568