From 1df1badd32d4664c6258bd5f370a72f9792362a817d077f735ae3714072a2797 Mon Sep 17 00:00:00 2001 From: Mark Post Date: Sat, 13 Nov 2021 20:06:12 +0000 Subject: [PATCH 1/2] Accepting request 931282 from home:markkp:branches:Base:System - Upgraded to version 2.19.0 (jsc#SLE-18324) * v2.19.0 (2021-11-10)__ Add new tools / libraries: - chreipl-fcp-mpath: New toolset that uses multipath information to change the configured FCP re-IPL path on detecting issues with the current path Changes of existing tools: - dbginfo.sh: Add retry timeout and remove possible blocking "blockdev --report" - dbginfo.sh: Collect config- and debug-data for chreipl-fcp-mpath - hsci: Add support for multiple MAC addresses Bug Fixes: - lshwc: Fix compile error for gcc <8.1 - zdump: Various clean-ups and fixes - ziomon: Correct throughput calculation in ziorep_printers - zipl: Fix segmentation fault when setting stage3_parms * v2.18.0 (2021-10-01)__ Add new tools: - scripts: Add tool for parsing sclp s390dbf logs - zdev: Add udev rule helper tool - zipl-editenv: Add tool to operate with zIPL environment installed in the boot record Changes of existing tools: - Makefile: Fix order of build of libraries for parallel builds - dbginfo.sh: Add collection in area of timedate, coredump and --check option - dbginfo.sh: Add exception on dump2tar for /sys/kernel/mm/page_idle/bitmap - dbginfo.sh: Cleanup of outdated sections and general code rework - dbginfo.sh: Collect zipl boot menu entries from boot loader specification - lszcrypt: Add support for vfio-ap status field - lszcrypt: Improved output for deconfig cards and queues - lszfcp: Add linkdown case to host marker of extended output - zdev: Add auto-config for PCI and crypto devices - zdump: Introduce multi-level message logging - zipl: Add support for environment block interpretation - zkey-cryptsetup: Support LUKS2 volumes with integrity support enabled Bug Fixes: - hsavmcore: Avoid recompilation of overlay during install step - libkmipclient: Fix parsing of hex values for XML and JSON encoding - vmur/vmur.cpp: Fix error handling on transfer failure - zdump: Lots of smaller fixes across the board * v2.17.0 (2021-07-07)__ Add new tools / libraries: - hsavmcore: New utility to make the dump process with kdump more efficient - libkmipclient: Add KMIP client shared library - libseckey: Add a secure key library - lshwc: New tool to extract and list complete counter sets Changes of existing tools: - genprotimg: Add '--(enable|disable)-pckmo' options - genprotimg: Add OpenSSL 3.0 support - genprotimg: Change plaintext control flags defaults so PCKMO functions are allowed - libutil: Introduce multi-level message logging (util_log) - libutil: Introduce util_arch module - udev/dasd: Change DASD udev-rule to set none scheduler - zdsfs: Add transparent codepage conversion - zkey: Add support for KMIP-based key management systems Bug Fixes: - ttyrun-getty: Avoid conflicts with serial-getty@ - dbginfo: add /proc/kallsyms - refresh zVM, lscpu - fix WORKARCHIVE handling - dbginfo: add KVM data collection for server and guest - fix lszdev - genprotimg: Add missing return values in error paths - zkey: Fix conversion of CCA DATA keys to CCA CIPHER keys - znetconf: avoid conflict with "chzdev -e" * v2.16.0 (2021-02-19)__ Add new tool: - hsci: New tool to manage HSCI (HiperSockets Converged Interfaces) Changes of existing tools: - genprotimg: Add host-key document verification support - genprotimg: boot: Make boot loader -march=z900 compatible - libekmfweb: Make install directory for shared libraries configurable - lsdasd: Add FC Endpoint Security information - make: Add address sanitizer support - netboot: Add version information to scripts - netboot: Bump busybox version in pxelinux.0 build - zdev: Add FC Endpoint Security information for DASD devices - zdev: Add build option to update initial RAM-disk by default - zkey-ekmfweb: Avoid sequence number clash when generating keys - zkey/zkey-ekmfweb: Install KMS plugins into configurable location - zkey: Add support to store LUKS2 dummy passphrase in key repository Bug Fixes: - dasdfmt: Fix segfault when an incorrect option is specified - genprotimg: Fix several build issues - genprotimg: Require argument for 'ramdisk' and 'parmfile' options - zcryptstats: Fix handling of partial results with many domains - zfcpdbf: Deal with crash 7.2.9 change in caller name formatting - zipl/boot: Fix memory use after free in stage2 - zipl/boot: Fix potential heap overflow in stage2 - zipl: Fix reading 4k disk's geometry - Removed the following obsolete patches * s390-tools-sles15sp3-dasdfmt-Fix-segfault-when-an-incorrect-option-is-spe.patch * s390-tools-sles15sp3-libutil-Compare-proc-entries-to-vfstype.patch * s390-tools-sles15sp3-01-zdev-Add-FC-Endpoint-Security-information-for-DASD-d.patch * s390-tools-sles15sp3-02-lsdasd-Add-FC-Endpoint-Security-information.patch * s390-tools-sles15sp3-hsci-Add-new-tool-to-control-HiperSockets-Converged-.patch * s390-tools-sles15sp3-zcryptstats-Fix-handling-of-partial-results-with-man.patch * s390-tools-sles15sp3-01-genprotimg-abort-if-one-of-the-recursive-targets-is-.patch * s390-tools-sles15sp3-02-genprotimg-fix-two-memory-leaks.patch * s390-tools-sles15sp3-03-genprotimg-require-argument-for-ramdisk-and-parmfile.patch * s390-tools-sles15sp3-04-genprotimg-add-host-key-document-verification-suppor.patch * s390-tools-sles15sp3-zkey-Fix-APQN-property-names.patch * s390-tools-sles15sp3-zipl-fix-4k-scsi-ipl.patch * s390-tools-sles15sp3-dasd-change-DASD-udev-rule-to-set-none-scheduler.patch * s390-tools-sles15sp3-check-return-code-from-util_file_read_l.patch - Removed an obsolete "export ROOT_BUILD_DIR" statement from the spec file. - Removed unnecessary defattr statements in the files section. - Updated the spec file to correspond to the changes made to the location and name of the kernel image in the kernel-zfcpdump package (bsc#1189841) - Did some spec file cleanup based on the recommendations from spec-cleaner. OBS-URL: https://build.opensuse.org/request/show/931282 OBS-URL: https://build.opensuse.org/package/show/Base:System/s390-tools?expand=0&rev=124 --- s390-tools-2.15.1.tar.gz | 3 - s390-tools-2.19.0.tar.gz | 3 + ...-partition-check-and-BLKRRPART-ioctl.patch | 2 +- s390-tools-sles12-zipl_boot_msg.patch | 2 +- ...-if-one-of-the-recursive-targets-is-.patch | 38 - ...oint-Security-information-for-DASD-d.patch | 47 - ...3-02-genprotimg-fix-two-memory-leaks.patch | 56 - ...Add-FC-Endpoint-Security-information.patch | 58 - ...re-argument-for-ramdisk-and-parmfile.patch | 49 - ...ost-key-document-verification-suppor.patch | 2410 ----------------- ...sles15sp3-Format-devices-in-parallel.patch | 25 +- ...ools-sles15sp3-Implement-Y-yast_mode.patch | 91 +- ...mplement-f-for-backwards-compability.patch | 2 +- ...ck-return-code-from-util_file_read_l.patch | 12 - ...DASD-udev-rule-to-set-none-scheduler.patch | 52 - ...ault-when-an-incorrect-option-is-spe.patch | 34 - ...-retry-BIODASDINFO-if-device-is-busy.patch | 4 +- ...l-to-control-HiperSockets-Converged-.patch | 633 ----- ...es15sp3-remove-no-pie-link-arguments.patch | 2 +- ...handling-of-partial-results-with-man.patch | 73 - ...tools-sles15sp3-zipl-fix-4k-scsi-ipl.patch | 64 - ...es15sp3-zkey-Fix-APQN-property-names.patch | 49 - s390-tools.changes | 125 + s390-tools.spec | 127 +- 24 files changed, 325 insertions(+), 3636 deletions(-) delete mode 100644 s390-tools-2.15.1.tar.gz create mode 100644 s390-tools-2.19.0.tar.gz delete mode 100644 s390-tools-sles15sp3-01-genprotimg-abort-if-one-of-the-recursive-targets-is-.patch delete mode 100644 s390-tools-sles15sp3-01-zdev-Add-FC-Endpoint-Security-information-for-DASD-d.patch delete mode 100644 s390-tools-sles15sp3-02-genprotimg-fix-two-memory-leaks.patch delete mode 100644 s390-tools-sles15sp3-02-lsdasd-Add-FC-Endpoint-Security-information.patch delete mode 100644 s390-tools-sles15sp3-03-genprotimg-require-argument-for-ramdisk-and-parmfile.patch delete mode 100644 s390-tools-sles15sp3-04-genprotimg-add-host-key-document-verification-suppor.patch delete mode 100644 s390-tools-sles15sp3-check-return-code-from-util_file_read_l.patch delete mode 100644 s390-tools-sles15sp3-dasd-change-DASD-udev-rule-to-set-none-scheduler.patch delete mode 100644 s390-tools-sles15sp3-dasdfmt-Fix-segfault-when-an-incorrect-option-is-spe.patch delete mode 100644 s390-tools-sles15sp3-hsci-Add-new-tool-to-control-HiperSockets-Converged-.patch delete mode 100644 s390-tools-sles15sp3-zcryptstats-Fix-handling-of-partial-results-with-man.patch delete mode 100644 s390-tools-sles15sp3-zipl-fix-4k-scsi-ipl.patch delete mode 100644 s390-tools-sles15sp3-zkey-Fix-APQN-property-names.patch diff --git a/s390-tools-2.15.1.tar.gz b/s390-tools-2.15.1.tar.gz deleted file mode 100644 index 1150a71..0000000 --- a/s390-tools-2.15.1.tar.gz +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:8dc1180031018756ccd5acf6c26c4175bcac79e512e8a2ea8569fdf5d3f9bd6c -size 1390556 diff --git a/s390-tools-2.19.0.tar.gz b/s390-tools-2.19.0.tar.gz new file mode 100644 index 0000000..135797f --- /dev/null +++ b/s390-tools-2.19.0.tar.gz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:17dc163e6a1e940f895c64955c130058600e1df834e1ab134410be7266ef724a +size 1681093 diff --git a/s390-tools-sles12-fdasd-skip-partition-check-and-BLKRRPART-ioctl.patch b/s390-tools-sles12-fdasd-skip-partition-check-and-BLKRRPART-ioctl.patch index efc8d40..c152918 100644 --- a/s390-tools-sles12-fdasd-skip-partition-check-and-BLKRRPART-ioctl.patch +++ b/s390-tools-sles12-fdasd-skip-partition-check-and-BLKRRPART-ioctl.patch @@ -27,7 +27,7 @@ index 4503d3e..f04dc3d 100644 if (!anc->silent) printf("rereading partition table...\n"); -- if (dasd_reread_partition_table(options.device, 1) != 0) { +- if (dasd_reread_partition_table(options.device, 5) != 0) { + rc = dasd_reread_partition_table(options.device, 1); + if (rc == EINVAL && !anc->force_virtual) { fdasd_error(anc, unable_to_ioctl, "Error while rereading " diff --git a/s390-tools-sles12-zipl_boot_msg.patch b/s390-tools-sles12-zipl_boot_msg.patch index 1a84cb2..e89405a 100644 --- a/s390-tools-sles12-zipl_boot_msg.patch +++ b/s390-tools-sles12-zipl_boot_msg.patch @@ -1,6 +1,6 @@ --- s390-tools-1.24.1/zipl/boot/menu.c 2013-12-18 11:11:45.000000000 -0500 +++ s390-tools-1.24.1/zipl/boot/menu.c 2013-12-18 11:59:18.000000000 -0500 -@@ -167,8 +167,11 @@ +@@ -168,8 +168,11 @@ /* print config list */ menu_list(); diff --git a/s390-tools-sles15sp3-01-genprotimg-abort-if-one-of-the-recursive-targets-is-.patch b/s390-tools-sles15sp3-01-genprotimg-abort-if-one-of-the-recursive-targets-is-.patch deleted file mode 100644 index 0f690cb..0000000 --- a/s390-tools-sles15sp3-01-genprotimg-abort-if-one-of-the-recursive-targets-is-.patch +++ /dev/null @@ -1,38 +0,0 @@ -Subject: [PATCH] [FEAT VS2010] genprotimg: abort if one of the recursive targets is failing -From: Marc Hartmayer - -Summary: genprotimg: add host-key document verification -Description: Add host-key document verification support to genprotimg. This - ensures that a host-key document is genuine and provided by - IBM. For this the user must provide the IBM Z signing key, the - intermediate CA certificate (signed by the root CA used) so a - chain of trust starting from the host-key document and ending in - the root CA can be established. -Upstream-ID: 6db7fbe0187042f44a63a5c7dbeb9f116909d02e -Problem-ID: VS2010 - -Upstream-Description: - - genprotimg: abort if one of the recursive targets is failing - - Abort compilation as soon as one of the recursive targets is failing. - - Fixes: 65b9fc442c1a ("genprotimg: introduce new tool for the creation of PV images") - Signed-off-by: Marc Hartmayer - Signed-off-by: Jan Hoeppner - - -Signed-off-by: Marc Hartmayer -Index: s390-tools-service/genprotimg/Makefile -=================================================================== ---- s390-tools-service.orig/genprotimg/Makefile -+++ s390-tools-service/genprotimg/Makefile -@@ -21,7 +21,7 @@ clean: clean-recursive - $(RECURSIVE_TARGETS): - @target=`echo $@ |sed s/-recursive//`; \ - for d in $(SUBDIRS); do \ -- $(MAKE) -C $$d $$target; \ -+ $(MAKE) -C $$d $$target || exit 1; \ - done - - .PHONY: all install clean $(RECURSIVE_TARGETS) diff --git a/s390-tools-sles15sp3-01-zdev-Add-FC-Endpoint-Security-information-for-DASD-d.patch b/s390-tools-sles15sp3-01-zdev-Add-FC-Endpoint-Security-information-for-DASD-d.patch deleted file mode 100644 index 4f57c10..0000000 --- a/s390-tools-sles15sp3-01-zdev-Add-FC-Endpoint-Security-information-for-DASD-d.patch +++ /dev/null @@ -1,47 +0,0 @@ -Subject: [PATCH] [FEAT IO1812] zdev/lsdasd: Add FC Endpoint Security information -From: Jan Hoeppner - -Summary: zdev/lsdasd: Add FC Endpoint Security information -Description: Provide the status of the FC Endpoint Security information via the - long output of lsdasd for online Base and Alias devices. -Upstream-ID: - -Problem-ID: IO1812 - -Signed-off-by: Jan Hoeppner ---- - zdev/src/dasd.c | 17 +++++++++++++++++ - 1 file changed, 17 insertions(+) - ---- a/zdev/src/dasd.c -+++ b/zdev/src/dasd.c -@@ -313,6 +313,22 @@ static struct attrib dasd_attr_safe_offl - .writeonly = 1, - }; - -+static struct attrib dasd_attr_fc_security = { -+ .name = "fc_security", -+ .title = "Show FC Endpoint Security state of DASD device", -+ .desc = -+ "This read-only attribute shows the Fibre Channel Endpoint Security\n" -+ "status of the connection to the DASD device:\n" -+ " Unsupported : The DASD device does not support Fibre Channel\n" -+ " Endpoint Security\n" -+ " Inconsistent : The operational channel paths of the DASD device\n" -+ " report inconsistent Fibre Channel Endpoint\n" -+ " Security status\n" -+ " Authentication: The connection has been authenticated\n" -+ " Encryption : The connection is encrypted\n", -+ .readonly = 1, -+}; -+ - /* - * DASD subtype methods. - */ -@@ -617,6 +633,7 @@ struct subtype dasd_subtype_eckd = { - &dasd_attr_reservation_policy, - &dasd_attr_last_known_reservation_state, - &dasd_attr_safe_offline, -+ &dasd_attr_fc_security, - &internal_attr_early, - ), - .unknown_dev_attribs = 1, diff --git a/s390-tools-sles15sp3-02-genprotimg-fix-two-memory-leaks.patch b/s390-tools-sles15sp3-02-genprotimg-fix-two-memory-leaks.patch deleted file mode 100644 index 170b42b..0000000 --- a/s390-tools-sles15sp3-02-genprotimg-fix-two-memory-leaks.patch +++ /dev/null @@ -1,56 +0,0 @@ -Subject: [PATCH] [FEAT VS2010] genprotimg: fix two memory leaks -From: Marc Hartmayer - -Summary: genprotimg: add host-key document verification -Description: Add host-key document verification support to genprotimg. This - ensures that a host-key document is genuine and provided by - IBM. For this the user must provide the IBM Z signing key, the - intermediate CA certificate (signed by the root CA used) so a - chain of trust starting from the host-key document and ending in - the root CA can be established. -Upstream-ID: db6f272607842a6279fee589fb101f3a1f6148f3 -Problem-ID: VS2010 - -Upstream-Description: - - genprotimg: fix two memory leaks - - ==1005844== HEAP SUMMARY: - ==1005844== in use at exit: 18,907 bytes in 14 blocks - ==1005844== total heap usage: 82 allocs, 68 frees, 32,529 bytes allocated - ==1005844== - ==1005844== 136 (104 direct, 32 indirect) bytes in 1 blocks are definitely lost in loss record 12 of 14 - ==1005844== at 0x483885A: calloc (vg_replace_malloc.c:760) - ==1005844== by 0x48C950D: g_malloc0 (gmem.c:132) - ==1005844== by 0x100EC41: pv_args_new (pv_args.c:364) - ==1005844== by 0x100587F: main (genprotimg.c:122) - ==1005844== - ==1005844== LEAK SUMMARY: - ==1005844== definitely lost: 104 bytes in 1 blocks - ==1005844== indirectly lost: 32 bytes in 1 blocks - ==1005844== possibly lost: 0 bytes in 0 blocks - ==1005844== still reachable: 18,771 bytes in 12 blocks - ==1005844== suppressed: 0 bytes in 0 blocks - ==1005844== Reachable blocks (those to which a pointer was found) are not shown. - ==1005844== To see them, rerun with: --leak-check=full --show-leak-kinds=all - ==1005844== - ==1005844== For lists of detected and suppressed errors, rerun with: -s - ==1005844== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0) - - Signed-off-by: Marc Hartmayer - Signed-off-by: Jan Hoeppner - - -Signed-off-by: Marc Hartmayer -Index: s390-tools-service/genprotimg/src/genprotimg.c -=================================================================== ---- s390-tools-service.orig/genprotimg/src/genprotimg.c -+++ s390-tools-service/genprotimg/src/genprotimg.c -@@ -177,5 +177,7 @@ error: - rmdir_recursive(tmp_dir, NULL); - remove_signal_handler(signals, G_N_ELEMENTS(signals)); - g_free(tmp_dir); -+ g_clear_pointer(&img, pv_img_free); -+ g_clear_pointer(&args, pv_args_free); - exit(ret); - } diff --git a/s390-tools-sles15sp3-02-lsdasd-Add-FC-Endpoint-Security-information.patch b/s390-tools-sles15sp3-02-lsdasd-Add-FC-Endpoint-Security-information.patch deleted file mode 100644 index 573c66f..0000000 --- a/s390-tools-sles15sp3-02-lsdasd-Add-FC-Endpoint-Security-information.patch +++ /dev/null @@ -1,58 +0,0 @@ -Subject: [PATCH] [FEAT IO1812] zdev/lsdasd: Add FC Endpoint Security information -From: Jan Hoeppner - -Summary: zdev/lsdasd: Add FC Endpoint Security information -Description: Provide the status of the FC Endpoint Security information via the - long output of lsdasd for online Base and Alias devices. -Upstream-ID: - -Problem-ID: IO1812 - -Signed-off-by: Jan Hoeppner ---- - zconf/lsdasd | 7 +++++-- - 1 file changed, 5 insertions(+), 2 deletions(-) - ---- a/zconf/lsdasd -+++ b/zconf/lsdasd -@@ -387,6 +387,7 @@ function extended() - read EXTSZ 2> /dev/null < $DEVPATH/extent_pool/extent_size - read CAPACITY 2> /dev/null < $DEVPATH/capacity/logical_capacity - read ALLOCATED 2> /dev/null < $DEVPATH/capacity/space_allocated -+ read FC_SEC 2> /dev/null < $DEVPATH/fc_security - - # convert to hexadecimal values - PIM=0x$PIM -@@ -521,7 +522,7 @@ function extended() - elif [[ "$ALIAS" == 1 ]]; then - if [[ "$BASEONLY" == "false" ]]; then - ACTIVE="alias" -- printf "%s:%s:%s# status:\t\t\t\t%s# type: \t\t\t\t%s# use_diag:\t\t\t\t%s# readonly:\t\t\t\t%s# eer_enabled:\t\t\t\t%s# erplog:\t\t\t\t%s# hpf:\t\t\t\t\t%s # uid: \t\t\t\t%s# paths_installed: \t\t\t%s %s %s %s %s %s %s %s# paths_in_use: \t\t\t%s %s %s %s %s %s %s %s# paths_non_preferred: \t\t\t%s %s %s %s %s %s %s %s# paths_invalid_cabling: \t\t%s %s %s %s %s %s %s %s# paths_cuir_quiesced: \t\t\t%s %s %s %s %s %s %s %s# paths_invalid_hpf_characteristics: \t%s %s %s %s %s %s %s %s# paths_error_threshold_exceeded: \t%s %s %s %s %s %s %s %s#\n" \ -+ printf "%s:%s:%s# status:\t\t\t\t%s# type: \t\t\t\t%s# use_diag:\t\t\t\t%s# readonly:\t\t\t\t%s# eer_enabled:\t\t\t\t%s# erplog:\t\t\t\t%s# hpf:\t\t\t\t\t%s # uid: \t\t\t\t%s# fc_security: \t\t\t\t%s# paths_installed: \t\t\t%s %s %s %s %s %s %s %s# paths_in_use: \t\t\t%s %s %s %s %s %s %s %s# paths_non_preferred: \t\t\t%s %s %s %s %s %s %s %s# paths_invalid_cabling: \t\t%s %s %s %s %s %s %s %s# paths_cuir_quiesced: \t\t\t%s %s %s %s %s %s %s %s# paths_invalid_hpf_characteristics: \t%s %s %s %s %s %s %s %s# paths_error_threshold_exceeded: \t%s %s %s %s %s %s %s %s#\n" \ - "$SORTKEYLEN" "$SORTKEY" \ - "$BUSID" \ - "$ACTIVE" \ -@@ -532,6 +533,7 @@ function extended() - "$ERP" \ - "$HPF" \ - "$DEV_UID" \ -+ "$FC_SEC" \ - "${INSTALLED_PATHS[@]}" \ - "${USED_PATHS[@]}" \ - "${NP_PATHS[@]}" \ -@@ -563,7 +565,7 @@ function extended() - DISCIPLINE="${DISCIPLINE} (ESE)" - fi - -- printf "%s:%s:%s/%s/%s%s%s# status:\t\t\t\t%s# type: \t\t\t\t%s# blksz:\t\t\t\t%s# size: \t\t\t\t%s# blocks:\t\t\t\t%s# extent_size:\t\t\t\t%s# logical_capacity:\t\t\t%s# space_allocated:\t\t\t%s# use_diag:\t\t\t\t%s# readonly:\t\t\t\t%s# eer_enabled:\t\t\t\t%s# erplog:\t\t\t\t%s# hpf:\t\t\t\t\t%s# uid: \t\t\t\t%s# paths_installed: \t\t\t%s %s %s %s %s %s %s %s# paths_in_use: \t\t\t%s %s %s %s %s %s %s %s# paths_non_preferred: \t\t\t%s %s %s %s %s %s %s %s# paths_invalid_cabling: \t\t%s %s %s %s %s %s %s %s# paths_cuir_quiesced: \t\t\t%s %s %s %s %s %s %s %s# paths_invalid_hpf_characteristics: \t%s %s %s %s %s %s %s %s# paths_error_threshold_exceeded: \t%s %s %s %s %s %s %s %s#\n" \ -+ printf "%s:%s:%s/%s/%s%s%s# status:\t\t\t\t%s# type: \t\t\t\t%s# blksz:\t\t\t\t%s# size: \t\t\t\t%s# blocks:\t\t\t\t%s# extent_size:\t\t\t\t%s# logical_capacity:\t\t\t%s# space_allocated:\t\t\t%s# use_diag:\t\t\t\t%s# readonly:\t\t\t\t%s# eer_enabled:\t\t\t\t%s# erplog:\t\t\t\t%s# hpf:\t\t\t\t\t%s# uid: \t\t\t\t%s# fc_security: \t\t\t\t%s# paths_installed: \t\t\t%s %s %s %s %s %s %s %s# paths_in_use: \t\t\t%s %s %s %s %s %s %s %s# paths_non_preferred: \t\t\t%s %s %s %s %s %s %s %s# paths_invalid_cabling: \t\t%s %s %s %s %s %s %s %s# paths_cuir_quiesced: \t\t\t%s %s %s %s %s %s %s %s# paths_invalid_hpf_characteristics: \t%s %s %s %s %s %s %s %s# paths_error_threshold_exceeded: \t%s %s %s %s %s %s %s %s#\n" \ - "$SORTKEYLEN" "$SORTKEY" \ - "$BUSID" \ - "$BLOCKNAME" \ -@@ -584,6 +586,7 @@ function extended() - "$ERP" \ - "$HPF" \ - "$DEV_UID" \ -+ "$FC_SEC" \ - "${INSTALLED_PATHS[@]}" \ - "${USED_PATHS[@]}" \ - "${NP_PATHS[@]}" \ diff --git a/s390-tools-sles15sp3-03-genprotimg-require-argument-for-ramdisk-and-parmfile.patch b/s390-tools-sles15sp3-03-genprotimg-require-argument-for-ramdisk-and-parmfile.patch deleted file mode 100644 index e8d4cf7..0000000 --- a/s390-tools-sles15sp3-03-genprotimg-require-argument-for-ramdisk-and-parmfile.patch +++ /dev/null @@ -1,49 +0,0 @@ -Subject: [PATCH] [FEAT VS2010] genprotimg: require argument for 'ramdisk' and 'parmfile' options -From: Marc Hartmayer - -Summary: genprotimg: add host-key document verification -Description: Add host-key document verification support to genprotimg. This - ensures that a host-key document is genuine and provided by - IBM. For this the user must provide the IBM Z signing key, the - intermediate CA certificate (signed by the root CA used) so a - chain of trust starting from the host-key document and ending in - the root CA can be established. -Upstream-ID: 895a88b2f8d775e45ab1251f0b4bb275efd44a64 -Problem-ID: VS2010 - -Upstream-Description: - - genprotimg: require argument for 'ramdisk' and 'parmfile' options - - A argument is required for the optional options 'ramdisk' and - 'parmfile'. - - Fixes: 65b9fc442c1a ("genprotimg: introduce new tool for the creation of PV images") - Reviewed-by: Bjoern Walk - Signed-off-by: Marc Hartmayer - Signed-off-by: Jan Hoeppner - - -Signed-off-by: Marc Hartmayer -Index: s390-tools-service/genprotimg/src/pv/pv_args.c -=================================================================== ---- s390-tools-service.orig/genprotimg/src/pv/pv_args.c -+++ s390-tools-service/genprotimg/src/pv/pv_args.c -@@ -227,7 +227,7 @@ gint pv_args_parse_options(PvArgs *args, - .arg_description = _("IMAGE") }, - { .long_name = "ramdisk", - .short_name = 'r', -- .flags = G_OPTION_FLAG_OPTIONAL_ARG | G_OPTION_FLAG_FILENAME, -+ .flags = G_OPTION_FLAG_FILENAME, - .arg = G_OPTION_ARG_CALLBACK, - .arg_data = cb_add_component, - .description = _("Use RAMDISK as the initial RAM disk\n" INDENT -@@ -235,7 +235,7 @@ gint pv_args_parse_options(PvArgs *args, - .arg_description = _("RAMDISK") }, - { .long_name = "parmfile", - .short_name = 'p', -- .flags = G_OPTION_FLAG_OPTIONAL_ARG | G_OPTION_FLAG_FILENAME, -+ .flags = G_OPTION_FLAG_FILENAME, - .arg = G_OPTION_ARG_CALLBACK, - .arg_data = cb_add_component, - .description = _("Use the kernel parameters stored in PARMFILE\n" INDENT diff --git a/s390-tools-sles15sp3-04-genprotimg-add-host-key-document-verification-suppor.patch b/s390-tools-sles15sp3-04-genprotimg-add-host-key-document-verification-suppor.patch deleted file mode 100644 index 214ec21..0000000 --- a/s390-tools-sles15sp3-04-genprotimg-add-host-key-document-verification-suppor.patch +++ /dev/null @@ -1,2410 +0,0 @@ -Subject: [PATCH] [FEAT VS2010] genprotimg: add host-key document verification support -From: Marc Hartmayer - -Summary: genprotimg: add host-key document verification -Description: Add host-key document verification support to genprotimg. This - ensures that a host-key document is genuine and provided by - IBM. For this the user must provide the IBM Z signing key, the - intermediate CA certificate (signed by the root CA used) so a - chain of trust starting from the host-key document and ending in - the root CA can be established. -Upstream-ID: 074de1e14ed785c18f55ecf9762ac3f5de3465b4 -Problem-ID: VS2010 - -Upstream-Description: - - genprotimg: add host-key document verification support - - Add host-key document verification support to genprotimg. This ensures - that a host-key document is genuine and provided by IBM. For this the - user must provide the IBM Z signing key, the intermediate CA - certificate (signed by the root CA used) so a chain of trust starting - from the host-key document and ending in the root CA can be - established. - - By default, genprotimg tries to download all revocation lists needed - by looking up in the corresponding certificate on how CRL information - can be obtained (see https://tools.ietf.org/html/rfc5280#section-4.2.1.13 - for details). - - Acked-by: Patrick Steuer - Signed-off-by: Marc Hartmayer - Signed-off-by: Jan Hoeppner - - -Signed-off-by: Marc Hartmayer -Index: s390-tools-service/genprotimg/man/genprotimg.8 -=================================================================== ---- s390-tools-service.orig/genprotimg/man/genprotimg.8 -+++ s390-tools-service/genprotimg/man/genprotimg.8 -@@ -2,7 +2,7 @@ - .\" s390-tools is free software; you can redistribute it and/or modify - .\" it under the terms of the MIT license. See LICENSE for details. - .\" --.TH GENPROTIMG 8 "March 2020" "s390-tools" -+.TH GENPROTIMG 8 "November 2020" "s390-tools" - .SH NAME - genprotimg \- Create a protected virtualization image - -@@ -10,6 +10,7 @@ genprotimg \- Create a protected virtual - .SY - .B genprotimg - \fB\-k\fR \fIHOST_KEY_DOCUMENT\fR... -+\fB\-C\fR \fICERTIFICATE\fR... - \fB\-i\fR \fIVMLINUZ\fR - [\fB\-r\fR \fIRAMDISK\fR] - [\fB\-p\fR \fIPARMFILE\fR] -@@ -21,15 +22,19 @@ genprotimg \- Create a protected virtual - .PP - Use \fBgenprotimg\fR to generate a single bootable image file with - encrypted and integrity-protected parts. The command requires a kernel --image, a host-key document, and an output file name. Optionally, --specify an initial RAM filesystem, and a file containing the kernel --parameters. Should special circumstances require it, you can -+image, a host-key document, certificates for the host-key document -+verification, and an output file name. Optionally, specify an initial -+RAM filesystem, and a file containing the kernel parameters. If the -+command should be run offline, use the \fB\-\-offline\fR option and -+specify the certificate revocation lists (CRLs) by using the -+\fB\-\-crl\fR option. Should special circumstances require it, you can - optionally specify your own keys for the encryption by using the --experimental options. In the resulting image file, a plain text boot --loader, the encrypted components for kernel, initial RAM disk, kernel --parameters, and the encrypted and integrity-protected header are --concatenated. The header contains metadata necessary for running the --guest in protected mode. -+experimental options. For all certificates, CRLs, and host-key -+documents, both the PEM and DER input formats are supported. In the -+resulting image file, a plain text boot loader, the encrypted -+components for kernel, initial RAM disk, kernel parameters, and the -+encrypted and integrity-protected header are concatenated. The header -+contains metadata necessary for running the guest in protected mode. - .PP - Use this image file as a kernel image for zipl or for a direct kernel - boot using QEMU. -@@ -53,6 +58,12 @@ Specifies a host-key document. At least - option multiple times to enable the image to run on more than one - host. - .TP -+\fB\-C\fR, \fB\-\-cert\fR=\fI\,FILE\/\fR -+Specifies the certificate that is used to establish a chain of trust -+for the verification of the host-key documents. Specify this option -+twice to specify the IBM Z signing key and the intermediate CA -+certificate (signed by the root CA). Required. -+.TP - \fB\-o\fR, \fB\-\-output\fR=\fI\,OUTPUT_FILE\/\fR - Specifies the output file. Required. - .TP -@@ -65,6 +76,20 @@ Specifies the RAM disk image. Optional. - \fB\-p\fR, \fB\-\-parmfile\fR=\fI\,PARMFILE\/\fR - Specifies the kernel command line stored in \fI\,PARMFILE\/\fR. Optional. - .TP -+\fB\-\-crl\fR=\fI\,FILE\/\fR -+Specifies the revocation list that is used to check whether a -+certificate of the chain of trust is revoked. Specify this option -+multiple times to use multiple CRLs. Optional. -+.TP -+\fB\-\-offline\fR -+Specifies offline mode, in which no attempt is made to download -+CRLs. Optional. -+.TP -+\fB\-\-root\-ca\fR=\fI\,FILE\/\fR -+Specifies the root CA certificate for the verification. If omitted, -+the DigiCert root CA certificate installed on the system is used. Use -+this only if you trust the specified certificate. Optional. -+.TP - \fB\-\-no-verify\fR - Do not require the host-key documents to be valid. For testing - purposes, do not use for a production image. Optional. -@@ -77,11 +102,13 @@ Prints version information, then exits. - Generate a protected virtualization image in - \fI\,/boot/vmlinuz.pv\/\fR, using the kernel file \fI\,vmlinuz\/\fR, - the initrd in \fI\,initramfs\/\fR, the kernel parameters contained in --\fI\,parmfile\/\fR, and the host-key document in \fI\,host_key.crt\/\fR: -+\fI\,parmfile\/\fR, the intermediate CA in \fI\,DigiCertCA.crt\/\fR, -+the IBM Z signing key in \fI\,ibm-z-host-key-signing.crt\/\fR, and the -+host-key document in \fI\,host_key.crt\/\fR: - .PP - .Vb 1 - .EX --\& genprotimg \-i \fI\,vmlinuz\/\fR \-r \fI\,initramfs\/\fR \-p \fI\,parmfile\/\fR \-k \fI\,host_key.crt\/\fR \-o \fI\,/boot/vmlinuz.pv\/\fR -+\& genprotimg \-i \fI\,vmlinuz\/\fR \-r \fI\,initramfs\/\fR \-p \fI\,parmfile\/\fR \-k \fI\,host_key.crt\/\fR \-C \fI\,ibm-z-host-key-signing.crt\/\fR \-C \fI\,DigiCertCA.crt \-o \fI\,/boot/vmlinuz.pv\/\fR - .EE - .Ve - .PP -Index: s390-tools-service/genprotimg/src/Makefile -=================================================================== ---- s390-tools-service.orig/genprotimg/src/Makefile -+++ s390-tools-service/genprotimg/src/Makefile -@@ -23,16 +23,16 @@ WARNINGS := -Wall -Wextra -Wshadow \ - $(bin_PROGRAM)_SRCS := $(bin_PROGRAM).c pv/pv_stage3.c pv/pv_image.c \ - pv/pv_comp.c pv/pv_hdr.c pv/pv_ipib.c utils/crypto.c utils/file_utils.c \ - pv/pv_args.c utils/buffer.c pv/pv_comps.c pv/pv_error.c \ -- pv/pv_opt_item.c \ -+ pv/pv_opt_item.c utils/curl.c \ - $(NULL) - $(bin_PROGRAM)_OBJS := $($(bin_PROGRAM)_SRCS:.c=.o) - - ALL_CFLAGS += -std=gnu11 -DPKGDATADIR=$(PKGDATADIR) \ -- $(GLIB2_CFLAGS) $(LIBCRYPTO_CFLAGS) \ -+ $(GLIB2_CFLAGS) $(LIBCRYPTO_CFLAGS) $(LIBCURL_CFLAGS) \ - $(WARNINGS) \ - $(NULL) - ALL_CPPFLAGS += $(INCLUDE_PARMS) --LDLIBS += $(GLIB2_LIBS) $(LIBCRYPTO_LIBS) -+LDLIBS += $(GLIB2_LIBS) $(LIBCRYPTO_LIBS) $(LIBCURL_LIBS) - - - ifneq ($(shell sh -c 'command -v pkg-config'),) -@@ -40,21 +40,27 @@ GLIB2_CFLAGS := $(shell pkg-config --sil - GLIB2_LIBS := $(shell pkg-config --silence-errors --libs glib-2.0) - LIBCRYPTO_CFLAGS := $(shell pkg-config --silence-errors --cflags libcrypto) - LIBCRYPTO_LIBS := $(shell pkg-config --silence-errors --libs libcrypto) -+LIBCURL_CFLAGS := $(shell pkg-config --silence-errors --cflags libcurl) -+LIBCURL_LIBS := $(shell pkg-config --silence-errors --libs libcurl) - else - GLIB2_CFLAGS := -I/usr/include/glib-2.0 -I/usr/lib64/glib-2.0/include - GLIB2_LIBS := -lglib-2.0 - LIBCRYPTO_CFLAGS := - LIBCRYPTO_LIBS := -lcrypto -+LIBCURL_CFLAGS := -+LIBCURL_LIBS := -lcurl - endif - - BUILD_TARGETS := skip-$(bin_PROGRAM) - INSTALL_TARGETS := skip-$(bin_PROGRAM) - ifneq (${HAVE_OPENSSL},0) - ifneq (${HAVE_GLIB2},0) -+ifneq (${HAVE_LIBCURL},0) - BUILD_TARGETS := $(bin_PROGRAM) - INSTALL_TARGETS := install-$(bin_PROGRAM) - endif - endif -+endif - - all: $(BUILD_TARGETS) - -@@ -98,4 +104,9 @@ $($(bin_PROGRAM)_OBJS): .check-dep-$(bin - "openssl-devel / libssl-dev version >= 1.1.0", \ - "HAVE_OPENSSL=0", \ - "-I.") -+ $(call check_dep, \ -+ "$(bin_PROGRAM)", \ -+ "curl/curl.h", \ -+ "libcurl-devel", \ -+ "HAVE_LIBCURL=0") - touch $@ -Index: s390-tools-service/genprotimg/src/genprotimg.c -=================================================================== ---- s390-tools-service.orig/genprotimg/src/genprotimg.c -+++ s390-tools-service/genprotimg/src/genprotimg.c -@@ -18,6 +18,8 @@ - #include "common.h" - #include "pv/pv_args.h" - #include "pv/pv_image.h" -+#include "utils/crypto.h" -+#include "utils/curl.h" - - enum { - LOG_LEVEL_CRITICAL = 0, -@@ -117,6 +119,8 @@ static void remove_signal_handler(const - signal(signals[i], SIG_DFL); - } - -+static void __attribute__((constructor)) __init(void); -+static void __attribute__((destructor)) __cleanup(void); - gint main(gint argc, gchar *argv[]) - { - g_autoptr(PvArgs) args = pv_args_new(); -@@ -181,3 +185,16 @@ error: - g_clear_pointer(&args, pv_args_free); - exit(ret); - } -+ -+static void __init(void) -+{ -+ pv_crypto_init(); -+ if (curl_init() != 0) -+ g_abort(); -+} -+ -+static void __cleanup(void) -+{ -+ curl_cleanup(); -+ pv_crypto_cleanup(); -+} -Index: s390-tools-service/genprotimg/src/include/pv_crypto_def.h -=================================================================== ---- s390-tools-service.orig/genprotimg/src/include/pv_crypto_def.h -+++ s390-tools-service/genprotimg/src/include/pv_crypto_def.h -@@ -14,6 +14,24 @@ - - #include "lib/zt_common.h" - -+/* 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_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" -+#define PV_IMB_Z_SUBJECT_ENTRY_COUNT 6 -+ -+/* Minimum security level for the keys/certificates used to establish a chain of -+ * trust (see https://www.openssl.org/docs/man1.1.1/man3/X509_VERIFY_PARAM_set_auth_level.html -+ * for details). -+ */ -+#define PV_CERTS_SECURITY_LEVEL 2 -+ -+/* SKID for DigiCert Assured ID Root CA */ -+#define DIGICERT_ASSURED_ID_ROOT_CA_SKID "45EBA2AFF492CB82312D518BA7A7219DF36DC80F" -+ - union ecdh_pub_key { - struct { - uint8_t x[80]; -Index: s390-tools-service/genprotimg/src/pv/pv_args.c -=================================================================== ---- s390-tools-service.orig/genprotimg/src/pv/pv_args.c -+++ s390-tools-service/genprotimg/src/pv/pv_args.c -@@ -18,7 +18,9 @@ - - static gchar summary[] = - "Use genprotimg to create a protected virtualization kernel image file,\n" -- "which can be loaded using zipl or QEMU."; -+ "which can be loaded using zipl or QEMU. For all certificates, revocation\n" -+ "lists, and host-key documents, both the PEM and DER input formats are\n" -+ "supported."; - - static gint pv_arg_compare(gconstpointer arg_1, gconstpointer arg_2) - { -@@ -97,9 +99,14 @@ static gint pv_args_validate_options(PvA - return -1; - } - -- if (!args->no_verify) { -- g_set_error(err, PV_PARSE_ERROR, PR_PARSE_ERROR_MISSING_ARGUMENT, -- _("Use the option '--no-verify' as the verification support is not available yet.")); -+ if (!args->no_verify && -+ (!args->untrusted_cert_paths || -+ g_strv_length(args->untrusted_cert_paths) == 0)) { -+ g_set_error( -+ err, PV_PARSE_ERROR, PR_PARSE_ERROR_MISSING_ARGUMENT, -+ _("Either specify the IBM Z signing key and (DigiCert) intermediate CA certificate\n" -+ "by using the '--cert' option, or use the '--no-verify' flag to disable the\n" -+ "host-key document verification completely (at your own risk).")); - return -1; - } - -@@ -141,6 +148,8 @@ static gboolean cb_set_string_option(con - { - gchar **args_option = NULL; - -+ if (g_str_equal(option, "--root-ca")) -+ args_option = &args->root_ca_path; - if (g_str_equal(option, "-o") || g_str_equal(option, "--output")) - args_option = &args->output_path; - if (g_str_equal(option, "--x-comp-key")) -@@ -211,6 +220,18 @@ gint pv_args_parse_options(PvArgs *args, - _("FILE specifies a host-key document. At least\n" INDENT - "one is required."), - .arg_description = _("FILE") }, -+ { .long_name = "cert", -+ .short_name = 'C', -+ .flags = G_OPTION_FLAG_NONE, -+ .arg = G_OPTION_ARG_FILENAME_ARRAY, -+ .arg_data = &args->untrusted_cert_paths, -+ .description = _( -+ "FILE contains a certificate that is used to\n" INDENT -+ "establish a chain of trust for the verification\n" INDENT -+ "of the host-key documents. The IBM Z signing\n" INDENT -+ "key and intermediate CA certificate (signed\n" INDENT -+ "by the root CA) are required."), -+ .arg_description = _("FILE") }, - { .long_name = "output", - .short_name = 'o', - .flags = G_OPTION_FLAG_FILENAME, -@@ -241,6 +262,31 @@ gint pv_args_parse_options(PvArgs *args, - .description = _("Use the kernel parameters stored in PARMFILE\n" INDENT - "(optional)."), - .arg_description = _("PARMFILE") }, -+ { .long_name = "crl", -+ .short_name = 0, -+ .flags = G_OPTION_FLAG_NONE, -+ .arg = G_OPTION_ARG_FILENAME_ARRAY, -+ .arg_data = &args->crl_paths, -+ .description = _( -+ "FILE contains a certificate revocation list\n" INDENT -+ "(optional)."), -+ .arg_description = _("FILE") }, -+ { .long_name = "offline", -+ .short_name = 0, -+ .flags = G_OPTION_FLAG_NONE, -+ .arg = G_OPTION_ARG_NONE, -+ .arg_data = &args->offline, -+ .description = _("Don't download CRLs (optional)."), -+ .arg_description = NULL }, -+ { .long_name = "root-ca", -+ .short_name = 0, -+ .flags = G_OPTION_FLAG_FILENAME, -+ .arg = G_OPTION_ARG_CALLBACK, -+ .arg_data = cb_set_string_option, -+ .description = _( -+ "Set FILE as the trusted root CA and don't use the\n" INDENT -+ "root CAs that are installed on the system (optional)."), -+ .arg_description = _("FILE") }, - { .long_name = "no-verify", - .short_name = 0, - .flags = G_OPTION_FLAG_NONE, -@@ -378,6 +424,9 @@ void pv_args_free(PvArgs *args) - g_free(args->cust_root_key_path); - g_free(args->cust_comm_key_path); - g_free(args->gcm_iv_path); -+ g_free(args->root_ca_path); -+ g_strfreev(args->crl_paths); -+ g_strfreev(args->untrusted_cert_paths); - g_strfreev(args->host_keys); - g_free(args->xts_key_path); - g_slist_free_full(args->comps, (GDestroyNotify)pv_arg_free); -Index: s390-tools-service/genprotimg/src/pv/pv_args.h -=================================================================== ---- s390-tools-service.orig/genprotimg/src/pv/pv_args.h -+++ s390-tools-service/genprotimg/src/pv/pv_args.h -@@ -25,6 +25,7 @@ void pv_arg_free(PvArg *arg); - typedef struct { - gint log_level; - gint no_verify; -+ gboolean offline; - gchar *pcf; - gchar *scf; - gchar *psw_addr; /* PSW address which will be used for the start of -@@ -34,6 +35,11 @@ typedef struct { - gchar *cust_comm_key_path; - gchar *gcm_iv_path; - gchar **host_keys; -+ gchar *root_ca_path; /* Trusted root CA used for the verification of the -+ * chain of trust (if specified). -+ */ -+ gchar **untrusted_cert_paths; -+ gchar **crl_paths; - gchar *xts_key_path; - GSList *comps; - gchar *output_path; -Index: s390-tools-service/genprotimg/src/pv/pv_error.h -=================================================================== ---- s390-tools-service.orig/genprotimg/src/pv/pv_error.h -+++ s390-tools-service/genprotimg/src/pv/pv_error.h -@@ -28,6 +28,8 @@ typedef enum { - PV_ERROR_IPIB_SIZE, - PV_ERROR_PV_HDR_SIZE, - PV_ERROR_INTERNAL, -+ PV_ERROR_CURL_INIT_FAILED, -+ PV_ERROR_DOWNLOAD_FAILED, - } PvErrors; - - typedef enum { -@@ -57,6 +59,31 @@ typedef enum { - PV_CRYPTO_ERROR_RANDOMIZATION, - PV_CRYPTO_ERROR_INVALID_PARM, - PV_CRYPTO_ERROR_INVALID_KEY_SIZE, -+ PV_CRYPTO_ERROR_INVALID_VALIDITY_PERIOD, -+ PV_CRYPTO_ERROR_EXPIRED, -+ PV_CRYPTO_ERROR_NOT_VALID_YET, -+ PV_CRYPTO_ERROR_LOAD_CRL, -+ PV_CRYPTO_ERROR_NO_PUBLIC_KEY, -+ PV_CRYPTO_ERROR_INVALID_SIGNATURE_ALGORITHM, -+ PV_CRYPTO_ERROR_SIGNATURE_ALGORITHM_MISMATCH, -+ PV_CRYPTO_ERROR_INVALID_URI, -+ PV_CRYPTO_ERROR_CRL_DOWNLOAD_FAILED, -+ PV_CRYPTO_ERROR_CERT_SIGNATURE_INVALID, -+ PV_CRYPTO_ERROR_CRL_SIGNATURE_INVALID, -+ PV_CRYPTO_ERROR_CERT_SUBJECT_ISSUER_MISMATCH, -+ PV_CRYPTO_ERROR_CRL_SUBJECT_ISSUER_MISMATCH, -+ PV_CRYPTO_ERROR_NO_IBM_Z_SIGNING_KEY, -+ PV_CRYPTO_ERROR_MALFORMED_CERTIFICATE, -+ PV_CRYPTO_ERROR_NO_CRL, -+ PV_CRYPTO_ERROR_LOAD_ROOT_CA, -+ PV_CRYPTO_ERROR_LOAD_DEFAULT_CA, -+ PV_CRYPTO_ERROR_MALFORMED_ROOT_CA, -+ PV_CRYPTO_ERROR_WRONG_CA_USED, -+ PV_CRYPTO_ERROR_SKID_AKID_MISMATCH, -+ PV_CRYPTO_ERROR_NO_ISSUER_IBM_Z_FOUND, -+ PV_CRYPTO_ERROR_FAILED_DOWNLOAD_CRL, -+ PV_CRYPTO_ERROR_NO_CRLDP, -+ PV_CRYPTO_ERROR_CERT_REVOKED, - } PvCryptoErrors; - - #endif -Index: s390-tools-service/genprotimg/src/pv/pv_image.c -=================================================================== ---- s390-tools-service.orig/genprotimg/src/pv/pv_image.c -+++ s390-tools-service/genprotimg/src/pv/pv_image.c -@@ -10,6 +10,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -138,22 +139,18 @@ static EVP_PKEY *pv_img_get_cust_pub_pri - return generate_ec_key(nid, err); - } - --static HostKeyList *pv_img_get_host_keys(gchar **host_cert_paths, -- X509_STORE *store, gint nid, -+static HostKeyList *pv_img_get_host_keys(GSList *host_keys_with_path, gint nid, - GError **err) - { - g_autoslist(EVP_PKEY) ret = NULL; - -- g_assert(host_cert_paths); -- -- for (gchar **iterator = host_cert_paths; iterator != NULL && *iterator != NULL; -- iterator++) { -+ for (GSList *iterator = host_keys_with_path; iterator; -+ iterator = iterator->next) { -+ x509_with_path *cert_with_path = iterator->data; - g_autoptr(EVP_PKEY) host_key = NULL; -- const gchar *path = *iterator; -- -- g_assert(path); -+ X509 *cert = cert_with_path->cert; - -- host_key = read_ec_pubkey_cert(store, nid, path, err); -+ host_key = read_ec_pubkey_cert(cert, nid, err); - if (!host_key) - return NULL; - -@@ -253,10 +250,172 @@ static gint pv_img_set_control_flags(PvI - return 0; - } - -+static gint pv_img_hostkey_verify(GSList *host_key_certs, -+ const gchar *root_ca_path, -+ const gchar *const *crl_paths, -+ const gchar *const *untrusted_cert_paths, -+ gboolean offline, GError **err) -+{ -+ g_autoslist(x509_with_path) untrusted_certs_with_path = NULL; -+ g_autoptr(STACK_OF_X509) ibm_signing_certs = NULL; -+ g_autoptr(STACK_OF_X509) untrusted_certs = NULL; -+ g_autoslist(x509_pair) ibm_z_pairs = NULL; -+ g_autoptr(X509_STORE) trusted = NULL; -+ gint ibm_signing_certs_count; -+ -+ /* Load trusted root CAs of the system if and only if @root_ca_path is -+ * NULL, otherwise use the root CA specified by @root_ca_path. -+ */ -+ trusted = store_setup(root_ca_path, crl_paths, err); -+ if (!trusted) -+ goto error; -+ -+ if (!offline) { -+ g_autoptr(STACK_OF_X509_CRL) downloaded_ibm_signing_crls = NULL; -+ -+ /* Set up the download routine for the lookup of CRLs. */ -+ store_setup_crl_download(trusted); -+ -+ /* Try to download the CRLs of the IBM Z signing certificates -+ * specified in the host-key documents. Ignore download errors -+ * as it's still possible that a CRL is specified via command -+ * line. -+ */ -+ downloaded_ibm_signing_crls = try_load_crls_by_certs(host_key_certs); -+ -+ /* Add the downloaded CRLs to the store so they can be used for -+ * the verification later. -+ */ -+ for (int i = 0; i < sk_X509_CRL_num(downloaded_ibm_signing_crls); i++) { -+ X509_CRL *crl = sk_X509_CRL_value(downloaded_ibm_signing_crls, i); -+ -+ if (X509_STORE_add_crl(trusted, crl) != 1) { -+ g_set_error(err, PV_CRYPTO_ERROR, -+ PV_CRYPTO_ERROR_INTERNAL, -+ _("failed to load CRL")); -+ goto error; -+ } -+ } -+ } -+ -+ /* Load all untrusted certificates (e.g. IBM Z signing key and -+ * DigiCert intermediate CA) that are required to establish a chain of -+ * trust starting from the host-key document up to the root CA (if not -+ * otherwise specified that's the DigiCert Assured ID Root CA). -+ */ -+ untrusted_certs_with_path = load_certificates(untrusted_cert_paths, err); -+ if (!untrusted_certs_with_path) -+ goto error; -+ -+ /* Convert to STACK_OF(X509) */ -+ untrusted_certs = get_x509_stack(untrusted_certs_with_path); -+ -+ /* Find all IBM Z signing keys and remove them from the chain as we -+ * have to verify that they're valid. The last step of the chain of -+ * trust verification must be done manually, as the IBM Z signing keys -+ * are not marked as (intermediate) CA and therefore the standard -+ * `X509_verify_cert` function of OpenSSL cannot be used to verify the -+ * actual host-key documents. -+ */ -+ ibm_signing_certs = delete_ibm_signing_certs(untrusted_certs); -+ ibm_signing_certs_count = sk_X509_num(ibm_signing_certs); -+ if (ibm_signing_certs_count < 1) { -+ g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_NO_IBM_Z_SIGNING_KEY, -+ _("please specify at least one IBM Z signing key")); -+ goto error; -+ } else if (ibm_signing_certs_count > 1) { -+ g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_NO_IBM_Z_SIGNING_KEY, -+ _("please specify only one IBM Z signing key")); -+ goto error; -+ } -+ -+ if (store_set_verify_param(trusted, err) < 0) -+ goto error; -+ -+ /* Verify that the IBM Z signing keys are trustable. -+ * For this we must check: -+ * -+ * 1. Can a chain of trust be established ending in a root CA -+ * 2. Is the correct root CA ued? It has either to be the -+ * 'DigiCert Assured ID Root CA' or the root CA specified via -+ * command line. -+ */ -+ for (gint i = 0; i < sk_X509_num(ibm_signing_certs); ++i) { -+ X509 *ibm_signing_cert = sk_X509_value(ibm_signing_certs, i); -+ g_autoptr(STACK_OF_X509_CRL) ibm_signing_crls = NULL; -+ g_autoptr(X509_STORE_CTX) ctx = NULL; -+ x509_pair *pair = NULL; -+ -+ g_assert(ibm_signing_cert); -+ -+ /* Create the verification context and set the trusted -+ * and chain parameters. -+ */ -+ ctx = create_store_ctx(trusted, untrusted_certs, err); -+ if (!ctx) -+ goto error; -+ -+ /* Verify the IBM Z signing key */ -+ if (verify_cert(ibm_signing_cert, ctx, err) < 0) -+ goto error; -+ -+ /* Verify the build chain of trust chain. If the user passes a -+ * trusted root CA on the command line then the check for the -+ * Subject Key Identifier (SKID) is skipped, otherwise let's -+ * check if the SKID meets our expectation. -+ */ -+ if (!root_ca_path && -+ check_chain_parameters(X509_STORE_CTX_get0_chain(ctx), -+ get_digicert_assured_id_root_ca_skid(), -+ err) < 0) { -+ goto error; -+ } -+ -+ ibm_signing_crls = store_ctx_find_valid_crls(ctx, ibm_signing_cert, err); -+ if (!ibm_signing_crls) { -+ g_prefix_error(err, _("IBM Z signing key: ")); -+ goto error; -+ } -+ -+ /* Increment reference counter of @ibm_signing_cert as the -+ * certificate will now also be owned by @ibm_z_pairs. -+ */ -+ if (X509_up_ref(ibm_signing_cert) != 1) -+ g_abort(); -+ -+ pair = x509_pair_new(&ibm_signing_cert, &ibm_signing_crls); -+ ibm_z_pairs = g_slist_append(ibm_z_pairs, pair); -+ g_assert(!ibm_signing_cert); -+ g_assert(!ibm_signing_crls); -+ } -+ -+ /* Verify host-key documents by using the IBM Z signing -+ * certificates and the corresponding certificate revocation -+ * lists. -+ */ -+ for (GSList *iterator = host_key_certs; iterator; iterator = iterator->next) { -+ x509_with_path *host_key_with_path = iterator->data; -+ const gchar *host_key_path = host_key_with_path->path; -+ X509 *host_key = host_key_with_path->cert; -+ gint flags = X509_V_FLAG_CRL_CHECK; -+ -+ if (verify_host_key(host_key, ibm_z_pairs, flags, -+ PV_CERTS_SECURITY_LEVEL, err) < 0) { -+ g_prefix_error(err, "'%s': ", host_key_path); -+ goto error; -+ } -+ } -+ -+ return 0; -+error: -+ g_prefix_error(err, _("Failed to verify host-key document: ")); -+ return -1; -+} -+ - /* read in the keys or auto-generate them */ - static gint pv_img_set_keys(PvImage *img, const PvArgs *args, GError **err) - { -- g_autoptr(X509_STORE) store = NULL; -+ g_autoslist(x509_with_path) host_key_certs = NULL; - - g_assert(img->xts_cipher); - g_assert(img->cust_comm_cipher); -@@ -285,8 +444,25 @@ static gint pv_img_set_keys(PvImage *img - if (!img->cust_pub_priv_key) - return -1; - -+ /* Load all host-key documents specified on the command line */ -+ host_key_certs = load_certificates((const gchar **)args->host_keys, -+ err); -+ if (!host_key_certs) -+ return -1; -+ -+ if (!args->no_verify && -+ pv_img_hostkey_verify(host_key_certs, args->root_ca_path, -+ (const gchar * const *)args->crl_paths, -+ (const gchar * const *)args->untrusted_cert_paths, -+ args->offline, err) < 0) { -+ return -1; -+ } -+ -+ /* Loads the public keys stored in the host-key documents and verify -+ * that the correct elliptic curve is used. -+ */ - img->host_pub_keys = -- pv_img_get_host_keys(args->host_keys, store, img->nid, err); -+ pv_img_get_host_keys(host_key_certs, img->nid, err); - if (!img->host_pub_keys) - return -1; - -@@ -406,6 +582,9 @@ PvImage *pv_img_new(PvArgs *args, const - if (args->no_verify) - g_warning(_("host-key document verification is disabled. Your workload is not secured.")); - -+ if (args->root_ca_path) -+ g_warning(_("A different root CA than the default DigiCert root CA is selected. Ensure that this root CA is trusted.")); -+ - ret->comps = pv_img_comps_new(EVP_sha512(), EVP_sha512(), EVP_sha512(), err); - if (!ret->comps) - return NULL; -Index: s390-tools-service/genprotimg/src/utils/crypto.c -=================================================================== ---- s390-tools-service.orig/genprotimg/src/utils/crypto.c -+++ s390-tools-service/genprotimg/src/utils/crypto.c -@@ -16,6 +16,11 @@ - #include - #include - #include -+#include -+#include -+#include -+#include -+#include - #include - #include - -@@ -25,8 +30,49 @@ - #include "pv/pv_error.h" - - #include "buffer.h" -+#include "curl.h" - #include "crypto.h" - -+#define DEFINE_GSLIST_MAP(t2, t1) \ -+ typedef t1 *(*g_slist_map_func_##t2##_##t1)(const t2 *x, \ -+ GError **err); \ -+ G_GNUC_UNUSED static GSList *g_slist_map_##t2##_##t1(const GSList *list, \ -+ g_slist_map_func_##t2##_##t1 func, \ -+ GError **err) \ -+ { \ -+ g_autoslist(t1) ret = NULL; \ -+ for (const GSList *iterator = list; iterator; \ -+ iterator = iterator->next) { \ -+ const t2 *value = iterator->data; \ -+ t1 *new_value = NULL; \ -+ g_assert(value); \ -+ new_value = func(value, err); \ -+ if (!new_value) \ -+ return NULL; \ -+ ret = g_slist_append(ret, g_steal_pointer(&new_value)); \ -+ } \ -+ return g_steal_pointer(&ret); \ -+ } -+ -+#define DEFINE_GSLIST_TO_STACK(t1) \ -+ G_GNUC_UNUSED static STACK_OF(t1) *g_slist_to_stack_of_##t1(GSList **list) \ -+ { \ -+ g_assert(list); \ -+ g_autoptr(STACK_OF_##t1) ret = sk_##t1##_new_null(); \ -+ if (!ret) \ -+ g_abort(); \ -+ for (GSList *iterator = *list; iterator; \ -+ iterator = iterator->next) { \ -+ if (sk_##t1##_push(ret, g_steal_pointer(&iterator->data)) == 0) \ -+ g_abort(); \ -+ } \ -+ g_clear_pointer(list, g_slist_free); \ -+ return g_steal_pointer(&ret); \ -+ } -+ -+DEFINE_GSLIST_MAP(x509_with_path, X509) -+DEFINE_GSLIST_TO_STACK(X509) -+ - EVP_MD_CTX *digest_ctx_new(const EVP_MD *md, GError **err) - { - g_autoptr(EVP_MD_CTX) ctx = EVP_MD_CTX_new(); -@@ -359,79 +405,1340 @@ static gboolean certificate_uses_correct - return TRUE; - } - --static gboolean verify_certificate(X509_STORE *store, X509 *cert, GError **err) -+/* Verify that the used public key algorithm matches the subject signature -+ * algorithm -+ */ -+static int check_signature_algo_match(const EVP_PKEY *pkey, const X509 *subject, -+ GError **err) - { -- g_autoptr(X509_STORE_CTX) csc = X509_STORE_CTX_new(); -- if (!csc) -+ gint pkey_nid; -+ -+ if (!pkey) { -+ g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_NO_PUBLIC_KEY, -+ _("no public key")); -+ return -1; -+ } -+ -+ if (OBJ_find_sigid_algs(X509_get_signature_nid(subject), NULL, -+ &pkey_nid) != 1) { -+ g_set_error(err, PV_CRYPTO_ERROR, -+ PV_CRYPTO_ERROR_INVALID_SIGNATURE_ALGORITHM, -+ _("unsupported signature algorithm")); -+ return -1; -+ } -+ -+ if (EVP_PKEY_type(pkey_nid) != EVP_PKEY_base_id(pkey)) { -+ g_set_error(err, PV_CRYPTO_ERROR, -+ PV_CRYPTO_ERROR_SIGNATURE_ALGORITHM_MISMATCH, -+ _("signature algorithm mismatch")); -+ return -1; -+ } -+ -+ return 0; -+} -+ -+static X509_CRL *load_crl_from_bio(BIO *bio) -+{ -+ g_autoptr(X509_CRL) crl = PEM_read_bio_X509_CRL(bio, NULL, 0, NULL); -+ if (crl) -+ return g_steal_pointer(&crl); -+ ERR_clear_error(); -+ BIO_reset(bio); -+ -+ /* maybe the CRL is stored in DER format */ -+ crl = d2i_X509_CRL_bio(bio, NULL); -+ if (crl) -+ return g_steal_pointer(&crl); -+ return NULL; -+} -+ -+static X509_CRL *GByteArray_to_X509_CRL(const GByteArray *data) -+{ -+ g_autoptr(X509_CRL) ret = NULL; -+ g_autoptr(BIO) bio = NULL; -+ -+ g_assert(data); -+ -+ if (data->len > INT_MAX) -+ return NULL; -+ -+ bio = BIO_new_mem_buf(data->data, (int)data->len); -+ if (!bio) - g_abort(); - -- if (X509_STORE_CTX_init(csc, store, cert, NULL) != 1) { -- g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_INIT, -- _("Failed to initialize X.509 store")); -- return FALSE; -+ ret = load_crl_from_bio(bio); -+ if (!ret) -+ return NULL; -+ -+ return g_steal_pointer(&ret); -+} -+ -+static gint load_crl_from_web(const gchar *url, X509_CRL **crl, GError **err) -+{ -+ g_autoptr(X509_CRL) tmp_crl = NULL; -+ g_autoptr(GByteArray) data = NULL; -+ g_assert(crl); -+ -+ data = curl_download(url, CRL_DOWNLOAD_TIMEOUT_MS, -+ CRL_DOWNLOAD_MAX_SIZE, err); -+ if (!data) { -+ g_prefix_error(err, _("unable to download CRL: ")); -+ return -1; - } -+ tmp_crl = GByteArray_to_X509_CRL(data); -+ if (!tmp_crl) { -+ g_set_error(err, PV_CRYPTO_ERROR, -+ PV_CRYPTO_ERROR_CRL_DOWNLOAD_FAILED, -+ _("unable to load CRL from '%s'"), url); -+ return -1; -+ } -+ *crl = g_steal_pointer(&tmp_crl); -+ return 0; -+} - -- if (X509_verify_cert(csc) != 1) { -- g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_VERIFICATION, -- _("Failed to verify host-key document")); -+static BIO *bio_read_from_file(const char *path) -+{ -+ g_autoptr(BIO) bio = BIO_new_file(path, "r"); -+ -+ if (!bio) -+ return NULL; -+ -+ return g_steal_pointer(&bio); -+} -+ -+/* This function reads in only the first certificate and ignores all other. This -+ * is only relevant for the PEM file format. For the host-key document and the -+ * root CA this behavior is expected. -+ */ -+X509 *load_cert_from_file(const char *path, GError **err) -+{ -+ g_autoptr(BIO) bio = bio_read_from_file(path); -+ g_autoptr(X509) cert = NULL; -+ -+ if (!bio) { -+ g_set_error(err, PV_CRYPTO_ERROR, -+ PV_CRYPTO_ERROR_READ_CERTIFICATE, -+ _("unable to read certificate: '%s'"), path); -+ return NULL; -+ } -+ -+ cert = PEM_read_bio_X509(bio, NULL, NULL, NULL); -+ if (cert) -+ return g_steal_pointer(&cert); -+ ERR_clear_error(); -+ BIO_reset(bio); -+ -+ /* maybe the certificate is stored in DER format */ -+ cert = d2i_X509_bio(bio, NULL); -+ if (cert) -+ return g_steal_pointer(&cert); -+ -+ g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_READ_CERTIFICATE, -+ _("unable to load certificate: '%s'"), path); -+ return NULL; -+} -+ -+/* @crl_paths is allowed to be NULL */ -+static int load_crls_to_store(X509_STORE *store, const gchar *const *crl_paths, -+ gboolean err_out_empty_crls, GError **err) -+{ -+ for (const gchar *const *iterator = crl_paths; -+ iterator != NULL && *iterator != NULL; iterator++) { -+ const gchar *crl_path = *iterator; -+ X509_LOOKUP *lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file()); -+ int count; -+ -+ g_assert(crl_path); -+ -+ if (!lookup) { -+ g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_INTERNAL, -+ _("X509 store initialization failed")); -+ return -1; -+ } -+ -+ /* support *.pem files containing multiple CRLs */ -+ count = X509_load_crl_file(lookup, crl_path, X509_FILETYPE_PEM); -+ if (count > 0) -+ continue; -+ -+ count = X509_load_crl_file(lookup, crl_path, X509_FILETYPE_ASN1); -+ if (count == 1) -+ continue; -+ -+ if (err_out_empty_crls) { -+ g_set_error(err, PV_CRYPTO_ERROR, -+ PV_CRYPTO_ERROR_LOAD_CRL, -+ _("unable to load CRL from: '%s'"), crl_path); -+ return -1; -+ } -+ } -+ -+ return 0; -+} -+ -+/* returns -+ * 0 when the certificate is valid, -+ * -1 when not yet valid, -+ * 1 when expired -+ */ -+static int check_validity_period(const ASN1_TIME *not_before, const ASN1_TIME *not_after) -+{ -+ if (X509_cmp_current_time(not_before) != -1) -+ return -1; -+ -+ if (X509_cmp_current_time(not_after) != 1) -+ return 1; -+ -+ return 0; -+} -+ -+static gint x509_name_entry_get_data0(X509_NAME_ENTRY *entry, const guchar **data, -+ gsize *data_len) -+{ -+ const ASN1_STRING *asn1_str; -+ gint tmp_data_len; -+ -+ g_assert(data); -+ g_assert(data_len); -+ -+ asn1_str = X509_NAME_ENTRY_get_data(entry); -+ if (!asn1_str) -+ return -1; -+ -+ tmp_data_len = ASN1_STRING_length(asn1_str); -+ if (tmp_data_len < 0) -+ return -1; -+ -+ *data = ASN1_STRING_get0_data(asn1_str); -+ *data_len = (gsize)tmp_data_len; -+ return 0; -+} -+ -+/* The caller must not free *data! */ -+static gint x509_name_get_data0_by_NID(X509_NAME *name, gint nid, -+ const guchar **data, gsize *data_len) -+{ -+ -+ X509_NAME_ENTRY *entry = NULL; -+ gint lastpos = -1; -+ -+ lastpos = X509_NAME_get_index_by_NID(name, nid, lastpos); -+ if (lastpos == -1) -+ return -1; -+ -+ entry = X509_NAME_get_entry(name, lastpos); -+ if (!entry) -+ return -1; -+ -+ if (x509_name_entry_get_data0(entry, data, data_len) < 0) -+ return -1; -+ -+ return 0; -+} -+ -+/* @y must be a NULL-terminated string */ -+static gboolean x509_name_data_by_nid_equal(X509_NAME *name, gint nid, -+ const gchar *y) -+{ -+ const guchar *data = NULL; -+ gsize y_len = strlen(y); -+ gsize data_len; -+ -+ if (x509_name_get_data0_by_NID(name, nid, &data, &data_len) < 0) -+ return FALSE; -+ -+ if (data_len != y_len) -+ return FALSE; -+ -+ 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 = -+ * International Business Machines Corporation' and the organization unit (OUT) -+ * must end with the suffix ' Key Signing Service'. -+ */ -+static gboolean has_ibm_signing_subject(X509 *cert) -+{ -+ X509_NAME *subject = X509_get_subject_name(cert); -+ /* X509_NAME_entry_count is safe to be used with NULL */ -+ gint entry_count = X509_NAME_entry_count(subject); -+ g_autofree gchar *data_str = NULL; -+ const guchar *data; -+ gsize data_len; -+ -+ if (entry_count != PV_IMB_Z_SUBJECT_ENTRY_COUNT) -+ return FALSE; -+ -+ if (!x509_name_data_by_nid_equal(subject, NID_countryName, -+ PV_IBM_Z_SUBJECT_COUNTRY_NAME)) -+ return FALSE; -+ -+ 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)) -+ return FALSE; -+ -+ if (!x509_name_data_by_nid_equal(subject, NID_organizationName, -+ PV_IBM_Z_SUBJECT_ORGANIZATION_NAME)) -+ return FALSE; -+ -+ if (!x509_name_data_by_nid_equal(subject, NID_commonName, -+ PV_IBM_Z_SUBJECT_COMMON_NAME)) -+ return FALSE; -+ -+ if (x509_name_get_data0_by_NID(subject, NID_organizationalUnitName, -+ &data, &data_len) < 0) -+ return FALSE; -+ -+ /* Make sure that data_str is null-terminated as in general it cannot be -+ * assumed that @data is null-terminated. -+ */ -+ data_str = g_strndup((const gchar *)data, data_len); -+ if (!g_str_has_suffix(data_str, -+ PV_IBM_Z_SUBJECT_ORGANIZATIONONAL_UNIT_NAME_SUFFIX)) -+ return FALSE; - - return TRUE; - } - --static X509 *load_certificate(const gchar *path, GError **err) -+static X509_NAME *x509_name_reorder_attributes(const X509_NAME *name, const gint nids[], -+ gsize nids_len) - { -- g_autoptr(X509) ret = NULL; -- g_autoptr(BIO) bio = BIO_new_file(path, "rb"); -+ gint entry_count = X509_NAME_entry_count(name); -+ g_autoptr(X509_NAME) ret = NULL; -+ -+ if (entry_count < 0) -+ return NULL; -+ -+ if (nids_len != (gsize) entry_count) -+ return NULL; -+ -+ ret = X509_NAME_new(); -+ if (!ret) -+ g_abort(); -+ -+ for (gsize i = 0; i < nids_len; i++) { -+ const X509_NAME_ENTRY *entry = NULL; -+ gint nid = nids[i]; -+ gint lastpos = -1; -+ -+ lastpos = X509_NAME_get_index_by_NID((X509_NAME *)name, nid, lastpos); -+ if (lastpos == -1) -+ return NULL; -+ -+ entry = X509_NAME_get_entry(name, lastpos); -+ if (!entry) -+ return NULL; -+ -+ if (X509_NAME_add_entry(ret, entry, -1, 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). -+ * -+ * This function converts a correct X509_NAME into the broken one. The caller is -+ * responsible to free the returned value. -+ */ -+X509_NAME *c2b_name(const X509_NAME *name) -+{ -+ gint nids[] = { NID_countryName, NID_organizationName, NID_organizationalUnitName, -+ NID_localityName, NID_stateOrProvinceName, NID_commonName }; -+ g_autoptr(X509_NAME) broken_name = NULL; -+ -+ g_assert(name); -+ -+ /* Try to reorder the attributes */ -+ broken_name = x509_name_reorder_attributes(name, nids, G_N_ELEMENTS(nids)); -+ if (broken_name) -+ return g_steal_pointer(&broken_name); -+ return X509_NAME_dup((X509_NAME *)name); -+} -+ -+/* Verify that: subject(issuer) == issuer(crl) and SKID(issuer) == AKID(crl) */ -+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); - -- if (!bio) { - g_set_error(err, PV_CRYPTO_ERROR, -- PV_CRYPTO_ERROR_READ_CERTIFICATE, -- _("Failed to read host-key document: '%s'"), path); -+ PV_CRYPTO_ERROR_CRL_SUBJECT_ISSUER_MISMATCH, -+ _("issuer mismatch:\n%s\n%s"), -+ issuer_subject_str, crl_issuer_str); -+ return -1; -+ } -+ -+ /* If AKID(@crl) is specified it must match with SKID(@issuer) */ -+ akid = X509_CRL_get_ext_d2i(crl, NID_authority_key_identifier, NULL, NULL); -+ if (akid && X509_check_akid(issuer, akid) != X509_V_OK) { -+ g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_SKID_AKID_MISMATCH, -+ _("AKID mismatch")); -+ return -1; -+ } -+ -+ return 0; -+} -+ -+/* Verify whether a revocation list @crl is valid and is issued by @cert. For -+ * this multiple steps must be done: -+ * -+ * 1. verify issuer of the CRL matches with the suject name of @cert -+ * 2. verify the validity period of the CRL -+ * 3. verify the signature of the CRL -+ * -+ * Important: This function doesn't verify whether @cert is allowed to issue a -+ * CRL. Returns 0 if @crl is valid and issued by @cert, otherwise -1. -+ */ -+gint check_crl_valid_for_cert(X509_CRL *crl, X509 *cert, -+ gint verify_flags, GError **err) -+{ -+ EVP_PKEY *pkey = X509_get0_pubkey(cert); -+ -+ g_assert(crl); -+ -+ if (!pkey) { -+ g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_INTERNAL, -+ _("failed to retrieve public key from the certificate")); -+ return -1; -+ } -+ -+ /* check that the @crl issuer matches with the subject name of @cert*/ -+ if (check_crl_issuer(crl, cert, err) < 0) -+ return -1; -+ -+ /* verify the validity period of the CRL */ -+ if (!(verify_flags & X509_V_FLAG_NO_CHECK_TIME)) { -+ const ASN1_TIME *last = X509_CRL_get0_lastUpdate(crl); -+ const ASN1_TIME *next = X509_CRL_get0_nextUpdate(crl); -+ -+ if (!last || !next || check_validity_period(last, next)) { -+ g_set_error(err, PV_CRYPTO_ERROR, -+ PV_CRYPTO_ERROR_INVALID_VALIDITY_PERIOD, -+ _("validity period is not valid")); -+ return -1; -+ } -+ } else { -+ verify_flags &= ~X509_V_FLAG_NO_CHECK_TIME; -+ } -+ -+ /* verify the signature */ -+ if (X509_CRL_verify(crl, pkey) != 1) { -+ g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_CRL_SIGNATURE_INVALID, -+ _("signature is not valid")); -+ return -1; -+ } -+ g_assert(verify_flags == 0); -+ return 0; -+} -+ -+/* Given a certificate @cert try to find valid revocation lists in @ctx. If no -+ * valid CRL was found NULL is returned. -+ */ -+STACK_OF_X509_CRL *store_ctx_find_valid_crls(X509_STORE_CTX *ctx, X509 *cert, -+ GError **err) -+{ -+ g_autoptr(STACK_OF_X509_CRL) ret = NULL; -+ const gint verify_flags = 0; -+ X509_NAME *subject = NULL; -+ -+ subject = X509_get_subject_name(cert); -+ if (!subject) { -+ g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_MALFORMED_CERTIFICATE, -+ _("certificate is malformed")); - return NULL; - } - -- ret = PEM_read_bio_X509(bio, NULL, 0, NULL); -+ ret = X509_STORE_CTX_get1_crls(ctx, subject); - if (!ret) { -- g_set_error(err, PV_CRYPTO_ERROR, -- PV_CRYPTO_ERROR_READ_CERTIFICATE, -- _("Failed to load host-key document: '%s'"), path); -+ /* 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; -+ } -+ } -+ -+ /* Filter out non-valid CRLs for @cert */ -+ for (gint i = 0; i < sk_X509_CRL_num(ret); i++) { -+ X509_CRL *crl = sk_X509_CRL_value(ret, i); -+ -+ g_assert(crl); -+ -+ /* If @crl is not valid remove it from the array and log a -+ * warning. -+ */ -+ if (check_crl_valid_for_cert(crl, cert, verify_flags, err) < 0) { -+ g_assert(err); -+ g_warning(_("CRL is not valid: %s"), (*err)->message); -+ g_clear_error(err); -+ -+ /* Remove this certificate from the list and change i-- as the -+ * array has changed - this is not beautfiul, but right now the -+ * easiest solution I came up with -+ */ -+ if (sk_X509_CRL_delete(ret, i--) != crl) -+ g_abort(); -+ -+ g_clear_pointer(&crl, X509_CRL_free); -+ } -+ } -+ -+ if (sk_X509_CRL_num(ret) < 1) { -+ g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_NO_CRL, -+ _("no valid CRL found")); - return NULL; - } -+ return g_steal_pointer(&ret); -+} -+ -+/* Return a list of all IBM Z signing key certificates in @certs and remove them -+ * from the chain. Return empty stack if no IBM Z signing key is found. -+ */ -+STACK_OF_X509 *delete_ibm_signing_certs(STACK_OF_X509 *certs) -+{ -+ g_autoptr(STACK_OF_X509) ret = sk_X509_new_null(); -+ -+ for (gint i = 0; i < sk_X509_num(certs); i++) { -+ X509 *cert = sk_X509_value(certs, i); -+ -+ g_assert(cert); -+ -+ if (!has_ibm_signing_subject(cert)) -+ continue; -+ -+ /* Remove this certificate from the list and change i-- as the -+ * array has changed - this is not beautfiul, but right now the -+ * easiest solution I came up with. -+ */ -+ if (sk_X509_delete(certs, i--) != cert) -+ g_abort(); -+ -+ if (sk_X509_push(ret, g_steal_pointer(&cert)) == 0) -+ g_abort(); -+ } - - return g_steal_pointer(&ret); - } - --EVP_PKEY *read_ec_pubkey_cert(X509_STORE *store, gint nid, const gchar *path, -- GError **err) -+X509_STORE *store_setup(const gchar *root_ca_path, const gchar * const *crl_paths, -+ GError **err) -+{ -+ g_autoptr(X509_STORE) store = X509_STORE_new(); -+ -+ g_assert(store); -+ -+ /* if @root_ca_path != NULL use the specified root CA only, otherwise use the -+ * default root CAs found on the system -+ */ -+ if (root_ca_path) { -+ X509_LOOKUP *lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file()); -+ int count; -+ -+ if (!lookup) { -+ g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_INTERNAL, -+ _("X509 store initialization failed")); -+ return NULL; -+ } -+ -+ count = X509_load_cert_file(lookup, root_ca_path, X509_FILETYPE_PEM); -+ if (count > 1) { -+ g_set_error(err, PV_CRYPTO_ERROR, -+ PV_CRYPTO_ERROR_LOAD_ROOT_CA, -+ _("multiple certificates in one PEM file is not supported: '%s'"), -+ root_ca_path); -+ return NULL; -+ } else if (count < 1) { -+ count = X509_load_cert_file(lookup, root_ca_path, -+ X509_FILETYPE_ASN1); -+ if (count != 1) { -+ g_set_error(err, PV_CRYPTO_ERROR, -+ PV_CRYPTO_ERROR_LOAD_ROOT_CA, -+ _("failed to load root certificate from '%s'"), -+ root_ca_path); -+ return NULL; -+ } -+ } -+ } else { -+ /* Load certificates into @store from the hardcoded OpenSSL -+ * default paths -+ */ -+ if (X509_STORE_set_default_paths(store) != 1) { -+ g_set_error(err, PV_CRYPTO_ERROR, -+ PV_CRYPTO_ERROR_LOAD_DEFAULT_CA, -+ _("failed to load system root certificates")); -+ return NULL; -+ } -+ } -+ -+ /* Error out if a CRL file was provided that has not at least one CRL*/ -+ if (load_crls_to_store(store, crl_paths, TRUE, err) < 0) -+ return NULL; -+ -+ return g_steal_pointer(&store); -+} -+ -+int store_set_verify_param(X509_STORE *store, GError **err) -+{ -+ g_autoptr(X509_VERIFY_PARAM) param = NULL; -+ unsigned long flags = X509_V_FLAG_CRL_CHECK | -+ X509_V_FLAG_CRL_CHECK_ALL | -+ X509_V_FLAG_TRUSTED_FIRST | -+ X509_V_FLAG_CHECK_SS_SIGNATURE | -+ X509_V_FLAG_X509_STRICT | -+ X509_V_FLAG_POLICY_CHECK; -+ -+ /* Create a X509_VERIFY_PARAM structure, which specifies which checks -+ * should be done by the certificate verification operation -+ */ -+ param = X509_VERIFY_PARAM_new(); -+ if (!param) -+ g_abort(); -+ -+ /* The maximum depth level of the chain of trust for the verification of -+ * the IBM Z signing key is 2, i.e. IBM Z signing key -> (DigiCert) -+ * intermediate CA -> (DigiCert) root CA -+ */ -+ X509_VERIFY_PARAM_set_depth(param, 2); -+ -+ /* Set minimum allowed security level to at least 112 bits. */ -+ X509_VERIFY_PARAM_set_auth_level(param, PV_CERTS_SECURITY_LEVEL); -+ -+ /* Set verification purpose to 'Any Purpose' and specify that the -+ * associated trust setting of the default purpose should be used. -+ */ -+ if (X509_VERIFY_PARAM_set_purpose(param, -+ X509_PURPOSE_ANY | X509_TRUST_DEFAULT) != 1) -+ goto error; -+ -+ /* Each certificate from the chain of trust must be checked against a -+ * CRL to see if it has been revoked. In addition, use trusted -+ * certificates first mode, check signature of the last certificate, -+ * strict mode, and verify the policies. -+ */ -+ if (X509_VERIFY_PARAM_set_flags(param, flags) != 1) -+ goto error; -+ -+ if (X509_STORE_set1_param(store, param) != 1) -+ goto error; -+ -+ return 0; -+ -+error: -+ g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_INTERNAL, -+ _("X509 store initialization failed")); -+ return -1; -+} -+ -+/* @cert_paths must contain at least one element, otherwise an error is -+ * reported. -+ */ -+GSList *load_certificates(const gchar *const *cert_paths, GError **err) -+{ -+ g_autoslist(x509_with_path) ret = NULL; -+ -+ for (const gchar *const *iterator = cert_paths; -+ iterator != NULL && *iterator != NULL; iterator++) { -+ const gchar *cert_path = *iterator; -+ g_autoptr(X509) cert = NULL; -+ -+ g_assert(cert_path); -+ -+ cert = load_cert_from_file(cert_path, err); -+ if (!cert) -+ return NULL; -+ -+ ret = g_slist_append(ret, x509_with_path_new(cert, cert_path)); -+ } -+ if (!ret) { -+ g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_READ_CERTIFICATE, -+ _("no certificates specified")); -+ return NULL; -+ } -+ -+ return g_steal_pointer(&ret); -+} -+ -+static X509 *get_cert(const x509_with_path *cert_with_path, G_GNUC_UNUSED GError **err) - { -- g_autoptr(EVP_PKEY) ret = NULL; - g_autoptr(X509) cert = NULL; - -- cert = load_certificate(path, err); -+ g_assert(cert_with_path && cert_with_path->cert); -+ -+ cert = cert_with_path->cert; -+ if (X509_up_ref(cert) != 1) -+ g_abort(); -+ return g_steal_pointer(&cert); -+} -+ -+STACK_OF_X509 *get_x509_stack(const GSList *x509_with_path_list) -+{ -+ g_autoslist(X509) certs = NULL; -+ g_autoptr(GError) err = NULL; -+ -+ certs = g_slist_map_x509_with_path_X509(x509_with_path_list, -+ get_cert, &err); -+ g_assert_null(err); -+ return g_slist_to_stack_of_X509(&certs); -+} -+ -+x509_with_path *x509_with_path_new(X509 *cert, const gchar *path) -+{ -+ g_autoptr(x509_with_path) ret = g_new(x509_with_path, 1); -+ -+ g_assert(cert && path); -+ -+ if (X509_up_ref(cert) != 1) -+ g_abort(); -+ ret->cert = cert; -+ ret->path = g_strdup(path); -+ return g_steal_pointer(&ret); -+} -+ -+void x509_with_path_free(x509_with_path *cert) -+{ - if (!cert) -+ return; -+ -+ X509_free(cert->cert); -+ g_free((gchar *)cert->path); -+ g_free(cert); -+} -+ -+x509_pair *x509_pair_new(X509 **cert, STACK_OF_X509_CRL **crls) -+{ -+ g_autoptr(x509_pair) ret = g_new0(x509_pair, 1); -+ -+ g_assert(cert); -+ g_assert(crls); -+ -+ ret->cert = g_steal_pointer(cert); -+ ret->crls = g_steal_pointer(crls); -+ return g_steal_pointer(&ret); -+} -+ -+void x509_pair_free(x509_pair *pair) -+{ -+ if (!pair) -+ return; -+ -+ sk_X509_CRL_pop_free(pair->crls, X509_CRL_free); -+ X509_free(pair->cert); -+ g_free(pair); -+} -+ -+X509_STORE_CTX *create_store_ctx(X509_STORE *trusted, STACK_OF_X509 *chain, -+ GError **err) -+{ -+ g_autoptr(X509_STORE_CTX) ctx = X509_STORE_CTX_new(); -+ -+ if (!ctx || !X509_STORE_CTX_init(ctx, trusted, NULL, chain)) { -+ g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_INTERNAL, -+ _("X509 store initialization failed: %s"), -+ X509_verify_cert_error_string(X509_STORE_CTX_get_error(ctx))); - return NULL; -+ } - -- if (store && !verify_certificate(store, cert, err)) { -- g_prefix_error(err, -- _("Failed to load host-key document: '%s': "), -- path); -+ return g_steal_pointer(&ctx); -+} -+ -+gint verify_cert(X509 *cert, X509_STORE_CTX *ctx, GError **err) -+{ -+ gint rc; -+ -+ X509_STORE_CTX_set_cert(ctx, cert); -+ rc = X509_verify_cert(ctx); -+ if (rc != 1) { -+ X509 *tmp_cert = NULL; -+ -+ tmp_cert = X509_STORE_CTX_get_current_cert(ctx); -+ if (tmp_cert) { -+ g_autofree char *subj_name = X509_NAME_oneline( -+ X509_get_subject_name(tmp_cert), NULL, 0); -+ g_set_error(err, PV_CRYPTO_ERROR, -+ PV_CRYPTO_ERROR_INTERNAL, -+ _("failed to verify certificate '%s': %s"), -+ subj_name, -+ X509_verify_cert_error_string( -+ X509_STORE_CTX_get_error(ctx))); -+ } else { -+ g_set_error(err, PV_CRYPTO_ERROR, -+ PV_CRYPTO_ERROR_INTERNAL, -+ _("failed to verify certificate: %s"), -+ X509_verify_cert_error_string( -+ X509_STORE_CTX_get_error(ctx))); -+ } -+ -+ return -1; -+ } -+ -+ return 0; -+} -+ -+static int security_level_to_bits(int level) -+{ -+ static int security_bits[] = { 0, 80, 112, 128, 192, 256 }; -+ -+ g_assert(level > 0 && level < (int)G_N_ELEMENTS(security_bits)); -+ -+ return security_bits[level]; -+} -+ -+static ASN1_OCTET_STRING *digicert_assured_id_root_ca; -+ -+const ASN1_OCTET_STRING *get_digicert_assured_id_root_ca_skid(void) -+{ -+ pv_crypto_init(); -+ return digicert_assured_id_root_ca; -+} -+ -+/* Used for the caching of the downloaded CRLs */ -+static GHashTable *cached_crls; -+ -+void pv_crypto_init(void) -+{ -+ if (digicert_assured_id_root_ca) -+ return; -+ -+ cached_crls = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, -+ (GDestroyNotify)X509_CRL_free); -+ digicert_assured_id_root_ca = s2i_ASN1_OCTET_STRING( -+ NULL, NULL, DIGICERT_ASSURED_ID_ROOT_CA_SKID); -+} -+ -+void pv_crypto_cleanup(void) -+{ -+ if (!digicert_assured_id_root_ca) -+ return; -+ g_clear_pointer(&cached_crls, g_hash_table_destroy); -+ g_clear_pointer(&digicert_assured_id_root_ca, ASN1_OCTET_STRING_free); -+} -+ -+gint check_chain_parameters(const STACK_OF_X509 *chain, -+ const ASN1_OCTET_STRING *skid, GError **err) -+{ -+ const ASN1_OCTET_STRING *ca_skid = NULL; -+ gint len = sk_X509_num(chain); -+ X509 *ca = NULL; -+ -+ g_assert(skid); -+ /* at least one root and one leaf certificate must be defined */ -+ g_assert(len >= 2); -+ -+ /* get the root certificate of the chain of trust */ -+ ca = sk_X509_value(chain, len - 1); -+ if (!ca) { -+ g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_INTERNAL, -+ _("no root certificate found")); -+ return -1; -+ } -+ -+ ca_skid = X509_get0_subject_key_id(ca); -+ if (!ca_skid) { -+ g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_MALFORMED_ROOT_CA, -+ _("malformed root certificate")); -+ return -1; -+ } -+ -+ if (ASN1_STRING_cmp(ca_skid, skid) != 0) { -+ g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_WRONG_CA_USED, -+ _("expecting DigiCert root CA to be used")); -+ return -1; -+ } -+ -+ return 0; -+} -+ -+/* 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 -+ * @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; -+ } -+ -+ 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(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_SKID_AKID_MISMATCH, -+ _("AKID mismatch")); -+ return -1; -+ } -+ -+ if (check_signature_algo_match(X509_get0_pubkey(issuer), cert, err) < 0) -+ return -1; -+ -+ if (X509_verify(cert, X509_get0_pubkey(issuer)) != 1) { -+ g_set_error(err, PV_CRYPTO_ERROR, -+ PV_CRYPTO_ERROR_CERT_SIGNATURE_INVALID, -+ _("Signature verification failed")); -+ return -1; -+ } -+ -+ return 0; -+} -+ -+static gboolean is_cert_revoked(X509 *cert, X509_CRL *crl) -+{ -+ X509_REVOKED *revoked = NULL; -+ gint rc; -+ -+ if (!cert || !crl) -+ g_abort(); -+ -+ rc = X509_CRL_get0_by_serial(crl, &revoked, -+ (ASN1_INTEGER *)X509_get0_serialNumber(cert)); -+ if (rc == 0) -+ return FALSE; -+ -+ if (revoked) -+ return TRUE; -+ -+ return FALSE; -+} -+ -+/* Get the first http[s] URL from a DIST_POINT */ -+static const char *get_first_dp_url(DIST_POINT *dp) -+{ -+ GENERAL_NAMES *general_names; -+ -+ g_assert(dp); -+ -+ if (!dp->distpoint || dp->distpoint->type != 0) -+ return NULL; -+ -+ general_names = dp->distpoint->name.fullname; -+ for (gint i = 0; i < sk_GENERAL_NAME_num(general_names); i++) { -+ GENERAL_NAME *name = sk_GENERAL_NAME_value(general_names, i); -+ g_autofree const gchar *uri_str = NULL; -+ ASN1_STRING *uri_asn1; -+ const gchar *uri_data; -+ gint uri_data_len; -+ gint type; -+ -+ uri_asn1 = GENERAL_NAME_get0_value(name, &type); -+ if (type != GEN_URI) -+ continue; -+ uri_data_len = ASN1_STRING_length(uri_asn1); -+ if (uri_data_len < 0) -+ continue; -+ uri_data = (const gchar *)ASN1_STRING_get0_data(uri_asn1); -+ /* Make sure that uri_str is null-terminated as in general it -+ * cannot be assumed that @uri_data is null-terminated. -+ */ -+ uri_str = g_strndup(uri_data, -+ (gsize)uri_data_len); -+ if (g_str_has_prefix(uri_str, "http://")) -+ return uri_data; -+ if (g_str_has_prefix(uri_str, "https://")) -+ return uri_data; -+ } -+ return NULL; -+} -+ -+static gboolean insert_crl(X509_NAME *name, X509_CRL *crl) -+{ -+ g_autofree gchar *key = NULL; -+ -+ g_assert(name); -+ -+ key = X509_NAME_oneline(name, NULL, 0); -+ if (!key) -+ g_abort(); -+ if (X509_CRL_up_ref(crl) != 1) -+ g_abort(); -+ return g_hash_table_insert(cached_crls, g_steal_pointer(&key), crl); -+} -+ -+/* Caller is responsible for free'ing */ -+static X509_CRL *lookup_crl(X509_NAME *name) -+{ -+ g_autoptr(X509_CRL) crl = NULL; -+ g_autofree gchar *key = NULL; -+ -+ g_assert(name); -+ -+ key = X509_NAME_oneline(name, NULL, 0); -+ if (!key) -+ g_abort(); -+ crl = g_hash_table_lookup(cached_crls, key); -+ if (crl) { -+ if (X509_CRL_up_ref(crl) != 1) -+ g_abort(); -+ return g_steal_pointer(&crl); -+ } -+ return NULL; -+} -+ -+/* Returns empty stack if no CRL downloaded. */ -+static STACK_OF_X509_CRL *crls_download_cb(X509_STORE_CTX *ctx, X509_NAME *nm) -+{ -+ g_autoptr(STACK_OF_X509_CRL) crls = NULL; -+ g_autoptr(X509_CRL) crl = NULL; -+ /* must not be free'd */ -+ X509 *cert = NULL; -+ -+ crls = sk_X509_CRL_new_null(); -+ if (!crls) -+ g_abort(); -+ cert = X509_STORE_CTX_get_current_cert(ctx); -+ if (!cert) -+ g_steal_pointer(&crls); -+ g_assert(X509_NAME_cmp(X509_get_issuer_name(cert), nm) == 0); -+ crl = lookup_crl(nm); -+ if (!crl) { -+ /* ignore error */ -+ crl = load_crl_by_cert(cert, NULL); -+ if (!crl) -+ return g_steal_pointer(&crls); -+ g_assert_true(insert_crl(nm, crl)); -+ } -+ if (sk_X509_CRL_push(crls, g_steal_pointer(&crl)) == 0) -+ g_abort(); -+ return g_steal_pointer(&crls); -+} -+ -+void STACK_OF_DIST_POINT_free(STACK_OF_DIST_POINT *stack) -+{ -+ if (!stack) -+ return; -+ -+ sk_DIST_POINT_pop_free(stack, DIST_POINT_free); -+} -+ -+void STACK_OF_X509_free(STACK_OF_X509 *stack) -+{ -+ if (!stack) -+ return; -+ -+ sk_X509_pop_free(stack, X509_free); -+} -+ -+void STACK_OF_X509_CRL_free(STACK_OF_X509_CRL *stack) -+{ -+ if (!stack) -+ return; -+ -+ sk_X509_CRL_pop_free(stack, X509_CRL_free); -+} -+ -+/* Downloaded CRLs have a higher precedence than the CRLs specified on the -+ * command line. -+ */ -+static STACK_OF_X509_CRL *crls_cb(X509_STORE_CTX *ctx, X509_NAME *nm) -+{ -+ g_autoptr(STACK_OF_X509_CRL) crls = crls_download_cb(ctx, nm); -+ -+ if (sk_X509_CRL_num(crls) > 0) -+ return g_steal_pointer(&crls); -+ return X509_STORE_CTX_get1_crls(ctx, nm); -+} -+ -+/* Set up CRL lookup with download support */ -+void store_setup_crl_download(X509_STORE *st) -+{ -+ X509_STORE_set_lookup_crls(st, crls_cb); -+} -+ -+/* Download a CRL using the URI specified in the distribution @crldp */ -+static X509_CRL *load_crl_by_dist_point(DIST_POINT *crldp, GError **err) -+{ -+ const gchar *uri = get_first_dp_url(crldp); -+ g_autoptr(X509_CRL) crl = NULL; -+ -+ if (!uri) { -+ g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_INTERNAL, -+ _("no valid URL specified in distribution point")); - return NULL; - } - -+ if (load_crl_from_web(uri, &crl, err) < 0) -+ return NULL; -+ -+ return g_steal_pointer(&crl); -+} -+ -+/* This function returns the first X509_CRL found from the CRL distribution -+ * points specified in @cert. This function could be optimized by filtering -+ * duplicate certificates and/or filtering duplicated URIs. -+ */ -+X509_CRL *load_crl_by_cert(X509 *cert, GError **err) -+{ -+ g_autoptr(STACK_OF_DIST_POINT) crldps = NULL; -+ g_autoptr(X509_CRL) ret = NULL; -+ -+ g_assert(cert); -+ -+ crldps = X509_get_ext_d2i(cert, NID_crl_distribution_points, NULL, NULL); -+ if (!crldps || sk_DIST_POINT_num(crldps) == 0) { -+ g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_NO_CRLDP, -+ _("no distribution point found")); -+ return NULL; -+ } -+ -+ for (int i = 0; i < sk_DIST_POINT_num(crldps); i++) { -+ DIST_POINT *crldp = sk_DIST_POINT_value(crldps, i); -+ -+ g_assert(crldp); -+ -+ /* ignore error */ -+ ret = load_crl_by_dist_point(crldp, NULL); -+ if (ret) -+ return g_steal_pointer(&ret); -+ } -+ -+ g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_FAILED_DOWNLOAD_CRL, -+ _("failed to download CRL")); -+ return NULL; -+} -+ -+STACK_OF_X509_CRL *try_load_crls_by_certs(GSList *certs_with_path) -+{ -+ g_autoptr(STACK_OF_X509_CRL) ret = sk_X509_CRL_new_null(); -+ if (!ret) -+ g_abort(); -+ -+ for (GSList *iterator = certs_with_path; iterator; -+ iterator = iterator->next) { -+ x509_with_path *cert_with_path = iterator->data; -+ X509 *cert = cert_with_path->cert; -+ g_autoptr(X509_CRL) crl = NULL; -+ -+ g_assert(cert); -+ -+ /* ignore error */ -+ crl = load_crl_by_cert(cert, NULL); -+ if (!crl) -+ continue; -+ -+ if (sk_X509_CRL_push(ret, g_steal_pointer(&crl)) == 0) -+ g_abort(); -+ } -+ -+ return g_steal_pointer(&ret); -+} -+ -+/* Assumptions are that the issuer_crt and issuer_crl is a trusted IBM Z -+ * signing certificate/revocation list. This function verifies a host-key -+ * document. To do so multiple steps are required: -+ * -+ * 1. issuer(host_key) == subject(issuer_crt) -+ * 2. Signature verification -+ * 3. @host_key must not be expired -+ * 4. @host_key must not be revoked -+ */ -+gint verify_host_key(X509 *host_key, GSList *issuer_pairs, -+ gint verify_flags, int level, GError **err) -+{ -+ g_assert(host_key); -+ -+ const gint exp_security_bits = security_level_to_bits(level); -+ EVP_PKEY *pkey = X509_get0_pubkey(host_key); -+ gboolean successfully_checked = FALSE; -+ gint pkey_security_bits; -+ -+ if (!pkey) { -+ g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_INTERNAL, -+ _("failed to retrieve public key")); -+ return -1; -+ } -+ -+ /* check key level, if necessary */ -+ pkey_security_bits = EVP_PKEY_security_bits(pkey); -+ if (exp_security_bits > 0 && pkey_security_bits < exp_security_bits) { -+ g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_VERIFICATION, -+ _("not enough bits of security (%d, %d expected)"), -+ pkey_security_bits, exp_security_bits); -+ return -1; -+ } -+ -+ if (!(verify_flags & X509_V_FLAG_NO_CHECK_TIME)) { -+ const ASN1_TIME *last = X509_get_notBefore(host_key); -+ const ASN1_TIME *next = X509_get_notAfter(host_key); -+ -+ if (!last || !next || check_validity_period(last, next)) { -+ g_set_error(err, PV_CRYPTO_ERROR, -+ PV_CRYPTO_ERROR_INVALID_VALIDITY_PERIOD, -+ _("validity period is not valid")); -+ return -1; -+ } -+ } else { -+ verify_flags &= ~X509_V_FLAG_NO_CHECK_TIME; -+ } -+ -+ /* Verify that the host_key was issued by a certificate and that it -+ * wasn't revoked. -+ */ -+ for (GSList *iterator = issuer_pairs; iterator; -+ iterator = iterator->next) { -+ const x509_pair *pair = iterator->data; -+ STACK_OF_X509_CRL *issuer_crls = NULL; -+ X509 *issuer_cert = NULL; -+ -+ g_assert(pair); -+ -+ issuer_cert = pair->cert; -+ issuer_crls = pair->crls; -+ -+ g_assert(issuer_cert); -+ -+ /* Verify that the issuer(host_key) == subject(issuer_cert) and -+ * that the signature is valid -+ */ -+ if (check_host_key_issued(host_key, issuer_cert, NULL) < 0) -+ continue; -+ -+ /* Check against CRL */ -+ if (verify_flags & X509_V_FLAG_CRL_CHECK) { -+ gboolean crl_checked = FALSE; -+ -+ verify_flags &= ~X509_V_FLAG_CRL_CHECK; -+ for (gint i = 0; i < sk_X509_CRL_num(issuer_crls); i++) { -+ X509_CRL *issuer_crl = -+ sk_X509_CRL_value(issuer_crls, i); -+ -+ g_assert(issuer_crl); -+ -+ if (is_cert_revoked(host_key, issuer_crl)) { -+ g_set_error(err, PV_CRYPTO_ERROR, -+ PV_CRYPTO_ERROR_CERT_REVOKED, -+ _("certificate revoked")); -+ return -1; -+ } -+ -+ crl_checked = TRUE; -+ } -+ -+ if (!crl_checked) { -+ g_set_error(err, PV_CRYPTO_ERROR, -+ PV_CRYPTO_ERROR_INTERNAL, -+ _("no valid CRL found")); -+ return -1; -+ } -+ successfully_checked = TRUE; -+ break; -+ } -+ } -+ -+ if (!successfully_checked) { -+ g_set_error(err, PV_CRYPTO_ERROR, -+ PV_CRYPTO_ERROR_NO_ISSUER_IBM_Z_FOUND, -+ _("no IBM Z signing key that issued this host-key document found")); -+ return -1; -+ } -+ -+ /* were some unsupported flags specified? */ -+ g_assert(verify_flags == 0); -+ return 0; -+} -+ -+EVP_PKEY *read_ec_pubkey_cert(X509 *cert, gint nid, -+ GError **err) -+{ -+ g_autoptr(EVP_PKEY) ret = NULL; -+ - ret = X509_get_pubkey(cert); - if (!ret) { - g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_INVALID_PARM, -- _("Failed to get public key from host-key document: '%s'"), -- path); -+ _("Failed to get public key from host-key document")); - return NULL; - } - - if (!certificate_uses_correct_curve(ret, nid, err)) { - g_prefix_error(err, -- _("Failed to load host-key document: '%s': "), -- path); -+ _("Host-key document doesn\'t use correct EC curve")); - return NULL; - } - -Index: s390-tools-service/genprotimg/src/utils/crypto.h -=================================================================== ---- s390-tools-service.orig/genprotimg/src/utils/crypto.h -+++ s390-tools-service/genprotimg/src/utils/crypto.h -@@ -11,14 +11,18 @@ - #define PV_UTILS_CRYPTO_H - - #include -+#include - #include - #include - #include - #include - #include -+#include - #include -+#include - #include - #include -+#include - #include - - #include "common.h" -@@ -33,6 +37,9 @@ - #define AES_256_XTS_TWEAK_SIZE 16 - #define AES_256_XTS_KEY_SIZE 64 - -+#define CRL_DOWNLOAD_TIMEOUT_MS 3000 -+#define CRL_DOWNLOAD_MAX_SIZE (1024 * 1024) /* in bytes */ -+ - enum PvCryptoMode { - PV_ENCRYPT, - PV_DECRYPT, -@@ -40,7 +47,34 @@ enum PvCryptoMode { - - typedef GSList HostKeyList; - -+/* play nice with g_autoptr */ -+typedef STACK_OF(DIST_POINT) STACK_OF_DIST_POINT; -+typedef STACK_OF(X509) STACK_OF_X509; -+typedef STACK_OF(X509_CRL) STACK_OF_X509_CRL; -+ -+void STACK_OF_DIST_POINT_free(STACK_OF_DIST_POINT *stack); -+void STACK_OF_X509_free(STACK_OF_X509 *stack); -+void STACK_OF_X509_CRL_free(STACK_OF_X509_CRL *stack); -+ -+typedef struct { -+ X509 *cert; -+ const gchar *path; -+} x509_with_path; -+ -+x509_with_path *x509_with_path_new(X509 *cert, const gchar *path); -+void x509_with_path_free(x509_with_path *cert); -+ -+typedef struct { -+ X509 *cert; -+ STACK_OF_X509_CRL *crls; -+} x509_pair; -+ -+x509_pair *x509_pair_new(X509 **cert, STACK_OF_X509_CRL **crls); -+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(BIGNUM, BN_free) - WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(BIO, BIO_free_all) - WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(BN_CTX, BN_CTX_free) -@@ -51,10 +85,18 @@ WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(EV - WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(EVP_MD_CTX, EVP_MD_CTX_free) - WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(EVP_PKEY, EVP_PKEY_free) - WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(EVP_PKEY_CTX, EVP_PKEY_CTX_free) -+WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(STACK_OF_DIST_POINT, STACK_OF_DIST_POINT_free); -+WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(STACK_OF_X509, STACK_OF_X509_free); -+WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(STACK_OF_X509_CRL, STACK_OF_X509_CRL_free); - WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(X509, X509_free) -+WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(X509_CRL, X509_CRL_free) - WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(X509_LOOKUP, X509_LOOKUP_free) -+WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(X509_NAME, X509_NAME_free) -+WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(x509_pair, x509_pair_free) - WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(X509_STORE, X509_STORE_free) - WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(X509_STORE_CTX, X509_STORE_CTX_free) -+WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(X509_VERIFY_PARAM, X509_VERIFY_PARAM_free) -+WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(x509_with_path, x509_with_path_free) - - union cmp_index { - struct { -@@ -79,8 +121,37 @@ struct cipher_parms { - const Buffer *iv_or_tweak; - }; - --EVP_PKEY *read_ec_pubkey_cert(X509_STORE *store, gint nid, const gchar *path, -- GError **err); -+int check_crl_valid_for_cert(X509_CRL *crl, X509 *cert, -+ gint verify_flags, GError **err); -+void pv_crypto_init(void); -+void pv_crypto_cleanup(void); -+const ASN1_OCTET_STRING *get_digicert_assured_id_root_ca_skid(void); -+gint verify_host_key(X509 *host_key, GSList *issuer_pairs, -+ gint verify_flags, int level, GError **err); -+X509 *load_cert_from_file(const char *path, GError **err); -+X509_CRL *load_crl_from_file(const gchar *path, GError **err); -+GSList *load_certificates(const gchar *const *cert_paths, GError **err); -+STACK_OF_X509 *get_x509_stack(const GSList *x509_with_path_list); -+X509_STORE *store_setup(const gchar *root_ca_path, -+ const gchar * const *crl_paths, -+ GError **err); -+int store_set_verify_param(X509_STORE *store, GError **err); -+X509_CRL *load_crl_by_cert(X509 *cert, GError **err); -+STACK_OF_X509_CRL *try_load_crls_by_certs(GSList *certs_with_path); -+gint check_chain_parameters(const STACK_OF_X509 *chain, -+ const ASN1_OCTET_STRING *skid, GError **err); -+X509_NAME *c2b_name(const X509_NAME *name); -+ -+STACK_OF_X509 *delete_ibm_signing_certs(STACK_OF_X509 *certs); -+STACK_OF_X509_CRL *store_ctx_find_valid_crls(X509_STORE_CTX *ctx, X509 *cert, -+ GError **err); -+X509_STORE_CTX *create_store_ctx(X509_STORE *trusted, STACK_OF_X509 *chain, -+ GError **err); -+gint verify_cert(X509 *cert, X509_STORE_CTX *ctx, GError **err); -+X509_CRL *get_first_valid_crl(X509_STORE_CTX *ctx, X509 *cert, GError **err); -+void store_setup_crl_download(X509_STORE *st); -+EVP_PKEY *read_ec_pubkey_cert(X509 *cert, gint nid, GError **err); -+ - Buffer *compute_exchange_key(EVP_PKEY *cust, EVP_PKEY *host, GError **err); - Buffer *generate_aes_key(guint size, GError **err); - Buffer *generate_aes_iv(guint size, GError **err); -Index: s390-tools-service/genprotimg/src/utils/curl.c -=================================================================== ---- /dev/null -+++ s390-tools-service/genprotimg/src/utils/curl.c -@@ -0,0 +1,121 @@ -+/* -+ * Libcurl utils -+ * -+ * Copyright IBM Corp. 2020 -+ * -+ * s390-tools is free software; you can redistribute it and/or modify -+ * it under the terms of the MIT license. See LICENSE for details. -+ */ -+ -+#include -+#include -+#include -+#include -+ -+#include "lib/zt_common.h" -+#include "pv/pv_error.h" -+ -+#include "curl.h" -+ -+struct UserData { -+ GByteArray *buffer; -+ guint max_size; -+}; -+ -+static size_t write_callback(char *ptr, size_t size, size_t nmemb, void *userdata) -+{ -+ g_assert(userdata); -+ struct UserData *data = (struct UserData *)userdata; -+ GByteArray *buffer = data->buffer; -+ guint64 actual_size; -+ size_t err; -+ -+ g_assert(buffer); -+ -+ if (!g_uint64_checked_mul(&actual_size, size, nmemb)) -+ g_abort(); -+ -+ /* Signal an error condition by returning a amount that differs -+ * from the amount passed to the callback. This results in a -+ * CURLE_WRITE_ERROR. -+ */ -+ err = actual_size + 1; -+ -+ if (actual_size > G_MAXUINT) -+ return err; -+ -+ data->buffer = g_byte_array_append(buffer, (guchar *)ptr, (guint)actual_size); -+ if (data->buffer->len > data->max_size) -+ return err; -+ -+ return actual_size; -+} -+ -+gint curl_init(void) -+{ -+ if (curl_global_init(CURL_GLOBAL_ALL) != 0) -+ return -1; -+ return 0; -+} -+ -+void curl_cleanup(void) -+{ -+ curl_global_cleanup(); -+} -+ -+GByteArray *curl_download(const gchar *url, long timeout_ms, guint max_size, -+ GError **err) -+{ -+ g_autoptr(GByteArray) ret = NULL; -+ g_autoptr(CURL) handle = NULL; -+ g_autofree gchar *agent = NULL; -+ struct UserData userdata; -+ CURLcode rc; -+ -+ /* set up curl session */ -+ handle = curl_easy_init(); -+ if (!handle) -+ g_abort(); -+ -+ /* follow redirection */ -+ rc = curl_easy_setopt(handle, CURLOPT_FOLLOWLOCATION, 1l); -+ if (rc != CURLE_OK) -+ goto curl_err; -+ rc = curl_easy_setopt(handle, CURLOPT_TIMEOUT_MS, timeout_ms); -+ if (rc != CURLE_OK) -+ goto curl_err; -+ rc = curl_easy_setopt(handle, CURLOPT_NOSIGNAL, 1l); -+ if (rc != CURLE_OK) -+ goto curl_err; -+ agent = g_strdup_printf("%s/%s", tool_name, RELEASE_STRING); -+ rc = curl_easy_setopt(handle, CURLOPT_USERAGENT, agent); -+ if (rc != CURLE_OK) -+ goto curl_err; -+ rc = curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, write_callback); -+ if (rc != CURLE_OK) -+ goto curl_err; -+ ret = g_byte_array_new(); -+ userdata.buffer = ret; -+ userdata.max_size = max_size; -+ rc = curl_easy_setopt(handle, CURLOPT_WRITEDATA, (void *)&userdata); -+ if (rc != CURLE_OK) -+ goto curl_err; -+ rc = curl_easy_setopt(handle, CURLOPT_URL, url); -+ if (rc != CURLE_OK) -+ goto curl_err; -+ -+ rc = curl_easy_perform(handle); -+ if (rc != CURLE_OK) { -+ g_set_error(err, PV_ERROR, PV_ERROR_DOWNLOAD_FAILED, -+ _("download failed: %s"), curl_easy_strerror(rc)); -+ return NULL; -+ } -+ -+ return g_steal_pointer(&ret); -+curl_err: -+ g_set_error(err, PV_ERROR, -+ PV_ERROR_CURL_INIT_FAILED, -+ _("cURL initialization failed: %s"), -+ curl_easy_strerror(rc)); -+ return NULL; -+} -Index: s390-tools-service/genprotimg/src/utils/curl.h -=================================================================== ---- /dev/null -+++ s390-tools-service/genprotimg/src/utils/curl.h -@@ -0,0 +1,25 @@ -+/* -+ * Libcurl utils -+ * -+ * Copyright IBM Corp. 2020 -+ * -+ * s390-tools is free software; you can redistribute it and/or modify -+ * it under the terms of the MIT license. See LICENSE for details. -+ */ -+ -+#ifndef PV_UTILS_LIBCURL_H -+#define PV_UTILS_LIBCURL_H -+ -+#include -+#include -+ -+#include "common.h" -+ -+WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(CURL, curl_easy_cleanup) -+ -+GByteArray *curl_download(const gchar *url, long timeout_ms, guint max_size, -+ GError **err); -+gint curl_init(void); -+void curl_cleanup(void); -+ -+#endif /* PV_UTILS_LIBCURL_H */ diff --git a/s390-tools-sles15sp3-Format-devices-in-parallel.patch b/s390-tools-sles15sp3-Format-devices-in-parallel.patch index bd7dbc5..94dea3f 100644 --- a/s390-tools-sles15sp3-Format-devices-in-parallel.patch +++ b/s390-tools-sles15sp3-Format-devices-in-parallel.patch @@ -63,7 +63,7 @@ index e7fc501..07c674b 100644 #include "lib/dasd_base.h" #include "lib/dasd_sys.h" -@@ -81,6 +82,7 @@ +@@ -81,6 +82,7 @@ static struct dasdfmt_globals { int mode_specified; int ese; int no_discard; @@ -71,7 +71,7 @@ index e7fc501..07c674b 100644 } g = { .dasd_info = { 0 }, }; -@@ -105,6 +107,11 @@ +@@ -105,6 +107,11 @@ static struct util_opt opt_vec[] = { .desc = "Perform complete format check on device", .flags = UTIL_OPT_FLAG_NOSHORT, }, @@ -83,7 +83,7 @@ index e7fc501..07c674b 100644 UTIL_OPT_SECTION("FORMAT OPTIONS"), { .option = { "blocksize", required_argument, NULL, 'b' }, -@@ -162,7 +170,7 @@ +@@ -162,7 +169,7 @@ static struct util_opt opt_vec[] = { .desc = "Show a progressbar", }, { @@ -92,16 +92,7 @@ index e7fc501..07c674b 100644 .desc = "Show progress in percent", }, UTIL_OPT_SECTION("MISC"), -@@ -297,7 +305,7 @@ - p_old = p_new; - barlength = cyl * 33 / cylinders; - for (i = 1; i <= barlength; i++) -- printf("#"); -+ printf("%d|", g.procnum); - for (i = barlength + 1; i <= 33; i++) - printf("-"); - printf("|%3d%%", p_new); -@@ -311,7 +318,7 @@ +@@ -311,7 +318,7 @@ static void draw_progress(int cyl, unsig } if (g.print_hashmarks && (cyl / g.hashstep - hashcount) != 0) { @@ -110,7 +101,7 @@ index e7fc501..07c674b 100644 fflush(stdout); hashcount++; } -@@ -1560,7 +1568,11 @@ +@@ -1560,7 +1567,11 @@ int main(int argc, char *argv[]) char *reqsize_param_str = NULL; char *hashstep_str = NULL; @@ -123,7 +114,7 @@ index e7fc501..07c674b 100644 /* Establish a handler for interrupt signals. */ signal(SIGTERM, program_interrupt_signal); -@@ -1623,7 +1635,7 @@ +@@ -1623,7 +1634,7 @@ int main(int argc, char *argv[]) g.print_hashmarks = 1; } break; @@ -132,7 +123,7 @@ index e7fc501..07c674b 100644 if (!(g.print_hashmarks || g.print_progressbar)) g.print_percentage = 1; break; -@@ -1682,6 +1694,9 @@ +@@ -1682,6 +1693,9 @@ int main(int argc, char *argv[]) case OPT_NODISCARD: g.no_discard = 1; break; @@ -142,7 +133,7 @@ index e7fc501..07c674b 100644 case OPT_CHECK: g.check = 1; break; -@@ -1733,15 +1748,35 @@ +@@ -1733,15 +1747,35 @@ int main(int argc, char *argv[]) if (numdev > 1 && g.labelspec) error("Specifying a volser to be written doesn't make sense when formatting multiple DASD volumes."); diff --git a/s390-tools-sles15sp3-Implement-Y-yast_mode.patch b/s390-tools-sles15sp3-Implement-Y-yast_mode.patch index 34afb87..7e43b31 100644 --- a/s390-tools-sles15sp3-Implement-Y-yast_mode.patch +++ b/s390-tools-sles15sp3-Implement-Y-yast_mode.patch @@ -60,7 +60,18 @@ index 6dd28fa..5b6023a 100644 UTIL_OPT_SECTION("MISC"), { .option = { "check_host_count", no_argument, NULL, 'C' }, -@@ -392,7 +397,7 @@ static void evaluate_format_error(format +@@ -318,7 +323,9 @@ static void draw_progress(int cyl, unsig + } + + if (g.print_hashmarks && (cyl / g.hashstep - hashcount) != 0) { +- printf("%d|", g.procnum); ++ if (g.yast_mode) ++ printf("%d|", g.procnum); ++ else printf("#"); + fflush(stdout); + hashcount++; + } +@@ -392,7 +399,7 @@ static void evaluate_format_error(format unsigned int kl = 0; int blksize = cdata->expect.blksize; @@ -69,7 +80,7 @@ index 6dd28fa..5b6023a 100644 printf("\n"); /* -@@ -780,8 +785,9 @@ static void check_hashmarks(void) +@@ -780,8 +787,9 @@ static void check_hashmarks(void) g.hashstep = 10; } @@ -81,7 +92,7 @@ index 6dd28fa..5b6023a 100644 } } -@@ -1462,17 +1468,19 @@ static void do_format_dasd(volume_label_ +@@ -1462,17 +1470,19 @@ static void do_format_dasd(volume_label_ break; } @@ -104,18 +115,45 @@ index 6dd28fa..5b6023a 100644 printf("ok\n"); } } -@@ -1548,6 +1556,10 @@ +@@ -1548,6 +1558,7 @@ void process_dasd(volume_label_t *orig_v error("%s", str); set_geo(&cylinders, &heads); -+ if (g.yast_mode) { -+ printf("%d\n", cylinders); -+ fflush(stdout); -+ } ++ set_label(&vlabel, &format_params, cylinders); if (g.check) -@@ -1693,6 +1703,10 @@ int main(int argc, char *argv[]) +@@ -1557,6 +1568,29 @@ void process_dasd(volume_label_t *orig_v + + } + ++static void yast_print_cylinfo(const char *dev_filename) ++{ ++ unsigned int cylinders = -1u; ++ int fd; ++ dasd_information2_t dasd_info; ++ struct dasd_eckd_characteristics *characteristics; ++ ++ fd = open(dev_filename, O_RDONLY); ++ if ((fd != -1) && ( ! ioctl(fd, BIODASDINFO2, &dasd_info))) { ++ ++ characteristics = (struct dasd_eckd_characteristics *) &dasd_info.characteristics; ++ if (characteristics->no_cyl == LV_COMPAT_CYL && characteristics->long_no_cyl) ++ cylinders = characteristics->long_no_cyl; ++ else ++ cylinders = characteristics->no_cyl; ++ } ++ ++ if (fd != -1) ++ close(fd); ++ printf("%u\n", cylinders); ++ fflush(stdout); ++} ++ + int main(int argc, char *argv[]) + { + volume_label_t vlabel; +@@ -1693,6 +1727,10 @@ int main(int argc, char *argv[]) case OPT_NODISCARD: g.no_discard = 1; break; @@ -126,6 +164,41 @@ index 6dd28fa..5b6023a 100644 case 'P': max_parallel = atoi(optarg); break; +@@ -1728,6 +1766,21 @@ int main(int argc, char *argv[]) + reqsize = DEFAULT_REQUESTSIZE; + } + ++/* If -Y (YaST mode) was specified by the caller, then we need to suppress ++ * most of all the other output that might be generated. But, we _do_ want ++ * hashmarks printed so that YaST can track what's going on. If it wasn't ++ * specified on the command line, set it to a default of 10 cylinders. ++ */ ++ if (g.yast_mode) { ++ g.verbosity = 0; ++ g.print_progressbar = 0; ++ g.print_percentage = 0; ++ if (! g.print_hashmarks) { ++ g.print_hashmarks = 1; ++ hashstep_str = "10"; ++ } ++ } ++ + if (g.print_hashmarks) + PARSE_PARAM_INTO(g.hashstep, hashstep_str, 10, "hashstep"); + +@@ -1747,6 +1800,12 @@ int main(int argc, char *argv[]) + if (numdev > 1 && g.labelspec) + error("Specifying a volser to be written doesn't make sense when formatting multiple DASD volumes."); + ++ if (g.yast_mode) { ++ for (numproc = 0; numproc < numdev; numproc++) ++ yast_print_cylinfo(g.dev_path_array[numproc]); ++ ++ } ++ + for (numproc = 0; numproc < numdev; numproc++) { + chpid = fork(); + if (chpid == -1 ) -- 1.7.12.4 diff --git a/s390-tools-sles15sp3-Implement-f-for-backwards-compability.patch b/s390-tools-sles15sp3-Implement-f-for-backwards-compability.patch index fae53fe..3a813e3 100644 --- a/s390-tools-sles15sp3-Implement-f-for-backwards-compability.patch +++ b/s390-tools-sles15sp3-Implement-f-for-backwards-compability.patch @@ -52,7 +52,7 @@ index 5b6023a..cdd80df 100644 UTIL_OPT_SECTION("FORMAT OPTIONS"), { .option = { "blocksize", required_argument, NULL, 'b' }, -@@ -1627,6 +1631,12 @@ +@@ -1649,6 +1653,12 @@ } g.layout_specified = 1; break; diff --git a/s390-tools-sles15sp3-check-return-code-from-util_file_read_l.patch b/s390-tools-sles15sp3-check-return-code-from-util_file_read_l.patch deleted file mode 100644 index 9e00edd..0000000 --- a/s390-tools-sles15sp3-check-return-code-from-util_file_read_l.patch +++ /dev/null @@ -1,12 +0,0 @@ ---- a/libdasd/dasd_sys.c 2020-10-28 10:31:59.000000000 -0400 -+++ b/libdasd/dasd_sys.c 2021-02-27 17:41:04.937023501 -0500 -@@ -218,7 +218,8 @@ - return 0; - - path = util_path_sysfs("bus/ccw/devices/%s/host_access_count", busid); -- util_file_read_l(&value, 10, path); -+ if (util_file_read_l(&value, 10, path) == -1) -+ value=0; - free(path); - - return value; diff --git a/s390-tools-sles15sp3-dasd-change-DASD-udev-rule-to-set-none-scheduler.patch b/s390-tools-sles15sp3-dasd-change-DASD-udev-rule-to-set-none-scheduler.patch deleted file mode 100644 index 41475c8..0000000 --- a/s390-tools-sles15sp3-dasd-change-DASD-udev-rule-to-set-none-scheduler.patch +++ /dev/null @@ -1,52 +0,0 @@ -Subject: [PATCH] [BZ 192049] udev/dasd: change DASD udev-rule to set none scheduler -From: Stefan Haberland - -Description: dasd: change default scheduler to reduce CPU consumption -Symptom: CPU consumption up to 20% higher for mq-deadline - compared to none scheduler for DASD devices with no - difference in throughput. -Problem: Performance analysis showed that with recent DASD - device drivers using multi-queue block queuing the - throughput of mq-deadline and none scheduler is nearly - identical but the CPU consumption of mq-deadline - scheduler due to its optimizations is up to 20% higher - compared to none scheduler. -Solution: Set none scheduler as default in the DASD udev rule. -Reproduction: Use DASD devices with mq-deadline scheduler. -Upstream-ID: a65bc51cf4e5c1fe628bb182cc1a02ee83eb102d -Problem-ID: 192049 - -Upstream-Description: - - udev/dasd: change DASD udev-rule to set none scheduler - - Performance evaluation showed that using the mq-deadline scheduler for DASD - devices leads to a significantly higher CPU consumption compared to using - none scheduler while having the same amount of throughput. - Setting none scheduler as default in the dasd udev rule. - - Signed-off-by: Stefan Haberland - Reviewed-by: Jan Hoeppner - Signed-off-by: Jan Hoeppner - - -Signed-off-by: Stefan Haberland ---- - etc/udev/rules.d/59-dasd.rules | 8 ++++++++ - 1 file changed, 8 insertions(+) - ---- a/etc/udev/rules.d/59-dasd.rules -+++ b/etc/udev/rules.d/59-dasd.rules -@@ -26,10 +26,10 @@ - - LABEL="dasd_symlinks_end" - --# on device add set request queue scheduler to deadline -+# on device add set request queue scheduler to none - SUBSYSTEM!="block", GOTO="sched_end" - - ACTION!="change", GOTO="sched_end" --KERNEL=="dasd*[!0-9]", TEST=="queue/scheduler", ATTR{queue/scheduler}="deadline" -+KERNEL=="dasd*[!0-9]", TEST=="queue/scheduler", ATTR{queue/scheduler}="none" - - LABEL="sched_end" diff --git a/s390-tools-sles15sp3-dasdfmt-Fix-segfault-when-an-incorrect-option-is-spe.patch b/s390-tools-sles15sp3-dasdfmt-Fix-segfault-when-an-incorrect-option-is-spe.patch deleted file mode 100644 index 9566601..0000000 --- a/s390-tools-sles15sp3-dasdfmt-Fix-segfault-when-an-incorrect-option-is-spe.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 148d3f9b64da599adf453baf65e7a8596e2e7d97 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Jan=20H=C3=B6ppner?= -Date: Mon, 2 Nov 2020 09:09:51 +0100 -Subject: [PATCH] dasdfmt: Fix segfault when an incorrect option is specified -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -When specifying an incorrect program option, dasdfmt segfaults as the -format string for the corresponding error message has no parameter. -Add the missing parameter to fix this. - -Fixes: 732b3dddab84 ("dasdfmt: Replace ERRMSG_EXIT macro with an error handling function") -Signed-off-by: Jan Höppner ---- - dasdfmt/dasdfmt.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/dasdfmt/dasdfmt.c b/dasdfmt/dasdfmt.c -index a424f3c..5665f64 100644 ---- a/dasdfmt/dasdfmt.c -+++ b/dasdfmt/dasdfmt.c -@@ -1637,7 +1637,7 @@ int main(int argc, char *argv[]) - /* End of options string - start of devices list */ - break; - default: -- error("Try '%s --help' for more information."); -+ error("Try '%s --help' for more information.", prog_name); - } - - if (rc == -1) --- -2.26.2 - diff --git a/s390-tools-sles15sp3-dasdfmt-retry-BIODASDINFO-if-device-is-busy.patch b/s390-tools-sles15sp3-dasdfmt-retry-BIODASDINFO-if-device-is-busy.patch index d0cd974..b231c30 100644 --- a/s390-tools-sles15sp3-dasdfmt-retry-BIODASDINFO-if-device-is-busy.patch +++ b/s390-tools-sles15sp3-dasdfmt-retry-BIODASDINFO-if-device-is-busy.patch @@ -23,7 +23,7 @@ diff --git a/dasdfmt/dasdfmt.c b/dasdfmt/dasdfmt.c index e1877ac..f03cbad 100644 --- a/dasdfmt/dasdfmt.c +++ b/dasdfmt/dasdfmt.c -@@ -619,7 +619,7 @@ +@@ -621,7 +621,7 @@ */ static void check_disk(void) { @@ -32,7 +32,7 @@ index e1877ac..f03cbad 100644 bool ro; err = dasd_is_ro(g.dev_node, &ro); -@@ -629,6 +629,23 @@ +@@ -631,6 +631,23 @@ if (ro) error("Disk %s is read only!", g.dev_path); if (!g.force) { diff --git a/s390-tools-sles15sp3-hsci-Add-new-tool-to-control-HiperSockets-Converged-.patch b/s390-tools-sles15sp3-hsci-Add-new-tool-to-control-HiperSockets-Converged-.patch deleted file mode 100644 index eff7b6d..0000000 --- a/s390-tools-sles15sp3-hsci-Add-new-tool-to-control-HiperSockets-Converged-.patch +++ /dev/null @@ -1,633 +0,0 @@ -From ef090dda8333a778cb2d9e7f65ca8021e2ae9e67 Mon Sep 17 00:00:00 2001 -From: Karsten Graul -Date: Tue, 10 Nov 2020 12:07:03 +0100 -Subject: [PATCH] hsci: Add new tool to control HiperSockets Converged - Interfaces -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -hsci is used to control and show HSCI (HiperSockets Converged Interfaces) -settings. A HiperSockets interface and an external network interface are -converged to an HSCI interface. - -Signed-off-by: Alexandra Winter -Signed-off-by: Wenjia Zhang -Reviewed-by: Jan Hoeppner -Signed-off-by: Jan Hoeppner ---- - Makefile | 2 +- - README.md | 3 + - hsci/Makefile | 16 ++ - hsci/hsci | 441 ++++++++++++++++++++++++++++++++++++++++++++++++++ - hsci/hsci.8 | 100 ++++++++++++ - 5 files changed, 561 insertions(+), 1 deletion(-) - create mode 100644 hsci/Makefile - create mode 100755 hsci/hsci - create mode 100644 hsci/hsci.8 - -diff --git a/Makefile b/Makefile -index cc277b8e..cfbbd950 100644 ---- a/Makefile -+++ b/Makefile -@@ -9,7 +9,7 @@ TOOL_DIRS = zipl zdump fdasd dasdfmt dasdview tunedasd \ - vmconvert vmcp man mon_tools dasdinfo vmur cpuplugd ipl_tools \ - ziomon iucvterm hyptop cmsfs-fuse qethqoat zfcpdump zdsfs cpumf \ - systemd hmcdrvfs cpacfstats zdev dump2tar zkey netboot etc zpcictl \ -- genprotimg lsstp -+ genprotimg lsstp hsci - - SUB_DIRS = $(LIB_DIRS) $(TOOL_DIRS) - -diff --git a/README.md b/README.md -index aa2188a5..581353fd 100644 ---- a/README.md -+++ b/README.md -@@ -249,6 +249,9 @@ Package contents - Management Foundation - Web Edition, and is used to manage keys in an - enterprise. - -+ * hsci: -+ Manage HiperSockets Converged Interfaces (HSCI). -+ - For more information refer to the following publications: - - * "Device Drivers, Features, and Commands" chapter "Useful Linux commands" -diff --git a/hsci/Makefile b/hsci/Makefile -new file mode 100644 -index 00000000..6f7474c5 ---- /dev/null -+++ b/hsci/Makefile -@@ -0,0 +1,16 @@ -+include ../common.mak -+ -+all: -+ -+install: hsci -+ $(SED) -e 's/%S390_TOOLS_VERSION%/$(S390_TOOLS_RELEASE)/' \ -+ < hsci >$(DESTDIR)$(BINDIR)/hsci; \ -+ chown $(OWNER).$(GROUP) $(DESTDIR)$(BINDIR)/hsci; \ -+ chmod 755 $(DESTDIR)$(BINDIR)/hsci; \ -+ $(INSTALL) -d -m 755 $(DESTDIR)$(BINDIR) $(DESTDIR)$(MANDIR)/man8 -+ $(INSTALL) -g $(GROUP) -o $(OWNER) -m 644 hsci.8 \ -+ $(DESTDIR)$(MANDIR)/man8 -+ -+clean: -+ -+.PHONY: all install clean -diff --git a/hsci/hsci b/hsci/hsci -new file mode 100755 -index 00000000..9a56aa0d ---- /dev/null -+++ b/hsci/hsci -@@ -0,0 +1,441 @@ -+#!/bin/bash -+# -+# hsci - Tool to manage HiperSockets Converged Interfaces (HSCI) -+# -+# Copyright IBM Corp. 2020 -+# -+# s390-tools is free software; you can redistribute it and/or modify -+# it under the terms of the MIT license. See LICENSE for details. -+# -+ -+hsdev="" -+ndev="" -+hsci="" -+hsdev_mac="" -+hsif_pnetid="" -+netif_pnetid="" -+hsci_pnetid="" -+ -+function usage { -+cat <<-EOD -+Usage: hsci COMMAND [OPTION] -+ -+This tool is designed to control and show HSCI (HiperSockets Converged -+Interfaces) settings. A HiperSockets interface and an external network -+ -+COMMANDS -+ add HIPERSOCKETS_DEV NET_DEV Adds an HSCI interface -+ del HSCI_NAME Deletes an HSCI interface -+ show Lists the configured HSCI interfaces -+ -+OPTIONS: -+ -v, --version Prints the version number of the hsci tool and exits -+ -h, --help Displays the help information for the command -+EOD -+} -+ -+function prereqs_check { -+ if ! [ -x "$(command -v ip)" ]; then -+ echo "Error: No iproute2 installed on this system" >&2 -+ return 1 -+ fi -+} -+ -+function check_pnetids { -+ # get PNETID of the HS -+ local hsif_pnetids="" -+ local netif_pnetids="" -+ -+ if [ -e /sys/class/net/$hsdev/device/util_string ]; then -+ hsif_pnetids="$(cat /sys/class/net/$hsdev/device/util_string | tr -d '\000' | iconv -f IBM-1047 -t ASCII)" -+ else -+ if [ -e /sys/class/net/$hsdev/device/chpid ]; then -+ chpid="$(cat /sys/class/net/$hsdev/device/chpid | tr [:upper:] [:lower:])" -+ hsif_pnetids="$(cat /sys/devices/css0/chp0.$chpid/util_string | tr -d '\000' | iconv -f IBM-1047 -t ASCII)" -+ fi -+ fi -+ if [ "$hsif_pnetids" != "" ]; then -+ port_hsif="$(cat /sys/class/net/$hsdev/dev_port)" -+ (( idx=16*$port_hsif+1 )) -+ (( end=$idx+15 )) -+ hsif_pnetid="$(echo "$hsif_pnetids" | cut -c $idx-$end | tr -d ' ')" -+ fi -+ -+ # get PNETID of the NET_DEV -+ if [ -e /sys/class/net/$ndev/device/util_string ]; then -+ netif_pnetids="$(cat /sys/class/net/$ndev/device/util_string | tr -d '\000' | iconv -f IBM-1047 -t ASCII)" -+ else -+ if [ -e /sys/class/net/$ndev/device/chpid ]; then -+ chpid="$(cat /sys/class/net/$ndev/device/chpid | tr [:upper:] [:lower:])" -+ netif_pnetids="$(cat /sys/devices/css0/chp0.$chpid/util_string | tr -d '\000' | iconv -f IBM-1047 -t ASCII)" -+ fi -+ fi -+ if [ "$netif_pnetids" != "" ]; then -+ port_netif="$(cat /sys/class/net/$ndev/dev_port)" -+ (( idx=16*$port_netif+1 )) -+ (( end=$idx+15 )) -+ netif_pnetid="$(echo "$netif_pnetids" | cut -c $idx-$end | tr -d ' ')" -+ fi -+ -+ #Check PNETIDs -+ if [ "$hsif_pnetid" != "" ] && [ "$netif_pnetid" != "" ] && [ "$netif_pnetid" != "$hsif_pnetid" ]; then -+ echo "Error: $hsdev and $ndev have different PNETIDs! They are $hsif_pnetid and $netif_pnetid respectively" >&2 -+ return 1 -+ fi -+ -+ if [ "$hsif_pnetid" != "" ] && [ "$netif_pnetid" != "" ] && [ "$netif_pnetid" == "$hsif_pnetid" ]; then -+ hsci_pnetid=$hsif_pnetid -+ fi -+} -+ -+function verify_precon { -+ echo "Verifying net dev $ndev and HiperSockets dev $hsdev" -+ -+ if [ ! -e /sys/class/net/$hsdev ]; then -+ echo "Error: $hsdev does not exist" >&2 -+ return 1 -+ fi -+ if [ "$(cat /sys/class/net/$hsdev/device/card_type)" != "HiperSockets" ]; then -+ echo "Error: $hsdev is not a HiperSockets device" >&2 -+ return 1 -+ fi -+ if [ "$(cat /sys/class/net/$hsdev/device/layer2)" != "1" ]; then -+ echo "Error: $hsdev is not in layer 2 mode" >&2 -+ return 1 -+ fi -+ if [ ! -e /sys/class/net/$hsdev/device/vnicc/bridge_invisible ]; then -+ echo "Error: Missing vnic-characteristics support" >&2 -+ return 1 -+ fi -+ if [ "$(cat /sys/class/net/$hsdev/device/vnicc/bridge_invisible)" == "n/a" ]; then -+ echo "Error: $hsdev does not support vnicc" >&2 -+ return 1 -+ fi -+ if [ $(ip link show $hsdev | grep UP | wc -l) -eq 0 ]; then -+ echo "Error: $hsdev is not in state UP" >&2 -+ return 1 -+ fi -+ if [ $(bridge -d link show dev $hsdev self | grep learning_sync | wc -l) -eq 0 ]; then -+ echo "Error: $hsdev does not support attribute learning_sync" >&2 -+ return 1 -+ fi -+ if [ $(ip link show $hsdev | grep master | wc -l) -ne 0 ]; then -+ echo "Error: $hsdev is already a bridge port" >&2 -+ return 1 -+ fi -+ -+ #Pre-verify net_dev -+ if [ ! -e /sys/class/net/$ndev ]; then -+ echo "Error: $ndev does not exist" >&2 -+ return 1 -+ fi -+ if [ "$(cat /sys/class/net/$ndev/device/card_type)" == "HiperSockets" ]; then -+ echo "Error: $ndev is also a HiperSockets device" >&2 -+ return 1 -+ fi -+ if [ $(ip link show $ndev | grep UP | wc -l) -eq 0 ]; then -+ echo "Error: $ndev is not in state UP" >&2 -+ return 1 -+ fi -+ if [ $(ip link show $ndev | grep master | wc -l) -ne 0 ]; then -+ echo "Error: $ndev is already a bridge port" >&2 -+ return 1 -+ fi -+ -+ #Check PNETIDs -+ check_pnetids -+ if [ $? -ne 0 ]; then -+ return $? -+ fi -+ -+ return 0 -+} -+ -+function clean_up { -+ bridge link set dev $hsdev learning_sync off self >/dev/null 2>&1 -+ echo 0 > /sys/class/net/$hsdev/device/vnicc/bridge_invisible >/dev/null 2>&1 -+ bridge fdb del $hsdev_mac dev $ndev >/dev/null 2>&1 -+ ip link del $hsci >/dev/null 2>&1 -+} -+ -+############################################################################## -+## add a new HSCI interface -+############################################################################## -+function add_hsci { -+ -+ if [ $# != 2 ]; then -+ echo "hsci: Invalid parameters" >&2 -+ echo "Use 'hsci --help' for more information" >&2 -+ return 1 -+ fi -+ hsdev=$1 -+ ndev=$2 -+ -+ #### Verify preconditions -+ verify_precon -+ if [ $? -ne 0 ]; then -+ return $? -+ fi -+ -+ hsci_postfix="$(readlink /sys/class/net/$hsdev/device/cdev0 | tail -c5)" -+ hsci=hsci$hsci_postfix -+ -+ echo "Adding $hsci with a HiperSockets dev $hsdev and an external dev $ndev" -+ -+ #### Create bridge -+ ip link add name $hsci type bridge stp_state 0 >/dev/null 2>&1 -+ if [ $? -ne 0 ]; then -+ echo "Error: Could not create a bridge" >&2 -+ return 1 -+ fi -+ -+ #### Prepare hsdev -+ # Set VNICC of hsdev to invisible -+ #(mandatory for co-existence with HS-OSA bridges!) -+ echo 1 > /sys/class/net/$hsdev/device/vnicc/bridge_invisible -+ -+ #### Create bridge ports -+ ip link set dev $ndev master $hsci >/dev/null 2>&1 -+ if [ $? -ne 0 ]; then -+ echo "Error: Could not set master for $ndev" >&2 -+ clean_up -+ return 1 -+ fi -+ ip link set dev $hsdev master $hsci >/dev/null 2>&1 -+ if [ $? -ne 0 ]; then -+ echo "Error: Could not set master for $hsdev" >&2 -+ clean_up -+ return 1 -+ fi -+ -+ # no forwarding between ndev and hsdev -> isolated on -+ # ndev is default for outgoing unknown targets -> flood on -+ # no need to learn external LAN targets into fdb -> learning off -+ bridge link set dev $ndev isolated on learning off flood on mcast_flood on >/dev/null 2>&1 -+ if [ $? -ne 0 ]; then -+ echo "Error: Failed to set bridge attributes on $ndev" >&2 -+ clean_up -+ return 1 -+ fi -+ -+ # no forwarding between ndev and hsdev -> isolated on -+ # fdb will be populated by dev-to-bridge-notification, no need to learn -+ # -> learning off -+ # only send to hsdev, if listed in fdb -> flood off -+ # don't send MC/BC on hsdev -> mcast_flood off -+ bridge link set dev $hsdev isolated on learning off flood off mcast_flood off >/dev/null 2>&1 -+ if [ $? -ne 0 ]; then -+ echo "Error: Failed to set bridge attributes on $hsdev" >&2 -+ clean_up -+ return 1 -+ fi -+ -+ # NOTE: Although not required, BCs will be sent out on hsdev. -+ # NOTE: We need to receive BCs on hsdev, as z/OS HSCI does ARP requests on HS. -+ -+ hsdev_mac="$(cat /sys/class/net/$hsdev/address)" -+ echo "Set $hsdev MAC $hsdev_mac on $ndev and $hsci" -+ -+ # set HS MAC on OSA as secondary MAC -+ bridge fdb add $hsdev_mac dev $ndev >/dev/null 2>&1 -+ if [ $? -ne 0 ]; then -+ echo "Error: Failed to set HS MAC on OSA as secondary MAC" >&2 -+ clean_up -+ return 1 -+ fi -+ -+ # set HS MAC (common MAC) on HSCI as primary MAC -+ ip link set address $hsdev_mac dev $hsci >/dev/null 2>&1 -+ if [ $? -ne 0 ]; then -+ echo "Error: Failed to set HiperSockets MAC (common MAC) on HSCI as primary MAC" >&2 -+ clean_up -+ return 1 -+ fi -+ -+ # use hsdev MTU -+ if [ -e /sys/class/net/$hsdev/mtu ]; then -+ hs_mtu="$(cat /sys/class/net/$hsdev/mtu)" -+ ip link set dev $hsci mtu $hs_mtu >/dev/null 2>&1 -+ if [ $? -ne 0 ]; then -+ echo "Error: Failed to set MTU for $hsci " >&2 -+ clean_up -+ return 1 -+ fi -+ fi -+ ip link set dev $hsci up >/dev/null 2>&1 -+ if [ $? -ne 0 ]; then -+ echo "Error: Failed to set $hsci up" >&2 -+ clean_up -+ return 1 -+ fi -+ -+ # Turn on device for bridge notification -+ bridge link set dev $hsdev learning_sync on self >/dev/null 2>&1 -+ if [ $? -ne 0 ]; then -+ echo "Error: Failed to turn on device for bridge notification" >&2 -+ clean_up -+ return 1 -+ fi -+ echo "Successfully added HSCI interface $hsci" -+ return 0 -+} -+ -+############################################################################## -+## Delete HSCI -+############################################################################## -+ -+function del_hsci { -+ if [ $# != 1 ]; then -+ echo "hsci: invalid parameters" >&2 -+ echo "Use 'hsci --help' for more information" >&2 -+ return 1 -+ fi -+ hsci=$1 -+ if [ $(ip link show dev $hsci | wc -l) -eq 0 ]; then -+ echo "Error: $hsci does not exit" >&2 -+ return 1 -+ fi -+ if [ $(ip link show | grep "master $hsci" | wc -l) -eq 0 ]; then -+ echo "Error: $hsci is not an active HSCI interface" >&2 -+ return 1 -+ fi -+ -+ bports="$(ip link show | grep "master $hsci" | awk '{print $2}')" -+ for bport in $bports; do -+ if [ $(bridge -d link show dev $bport | grep "learning_sync on" | wc -l) -ne 0 ]; then -+ hsdev=${bport%:} -+ else -+ ndev=${bport%:} -+ fi -+ done -+ if [ "$hsdev" == "" ]; then -+ echo "Error: $hsci has no active HiperSockets port" >&2 -+ return 1 -+ fi -+ echo "Deleting HSCI interface $hsci with the HiperSockets $hsdev and the external $ndev" -+ -+ bridge link set dev $hsdev learning_sync off self >/dev/null 2>&1 -+ if [ $? -ne 0 ]; then -+ echo "Error: Failed to turn off learning_sync on $hsdev" >&2 -+ return 1 -+ fi -+ echo 0 > /sys/class/net/$hsdev/device/vnicc/bridge_invisible -+ -+ hsdev_mac="$(cat /sys/class/net/$hsdev/address)" -+ echo "Deleting $hsev MAC $hsdev_mac on $ndev" -+ bridge fdb del $hsdev_mac dev $ndev >/dev/null 2>&1 -+ if [ $? -ne 0 ]; then -+ echo "Error: Failed to delete $hsev MAC $hsdev_mac on $ndev" >&2 -+ return 1 -+ fi -+ -+ ip link del $hsci >/dev/null 2>&1 -+ if [ $? -ne 0 ]; then -+ echo "Error: Failed to delete $hsci" >&2 -+ return 1 -+ fi -+ echo "Successfully deleted device $hsci" -+ -+ return 0 -+} -+ -+############################################################################## -+## Show HSCI -+############################################################################## -+ -+function list_active { -+ hsdev=$1 -+ local ext="" -+ -+ hsci="$(ip link show dev $hsdev | awk '{for(x=1;x&2 -+ echo "Use 'hsci --help' for more information" >&2 -+ return 1 -+ fi -+ header=0 -+ -+ for hs_net_dev in $(ls -1 /sys/class/net/); do -+ list_one $hs_net_dev -+ done -+ -+ return 0 -+} -+ -+#============================================================================== -+ -+function print_version() -+{ -+ echo "hsci utility: version %S390_TOOLS_VERSION%" -+ echo "Copyright IBM Corp. 2020" -+} -+ -+############################################################################## -+##### Main -+############################################################################## -+prereqs_check -+ -+args="$(getopt -u -o hv -l help,version -- $*)" -+[ $? -ne 0 ] && exit 2 -+set -- $args -+while true; do -+ case $1 in -+ -v | --version) -+ print_version -+ exit 0 -+ ;; -+ -h | --help) -+ usage -+ exit 0 -+ ;; -+ --) -+ ;; -+ add) shift -+ add_hsci "$@" -+ exit $? -+ ;; -+ del) shift -+ del_hsci "$@" -+ exit $? -+ ;; -+ show) shift -+ show_hsci "$@" -+ exit $? -+ ;; -+ *) echo "hsci: Please specify a valid command or option" >&2 -+ echo "Use 'hsci --help' for more information" >&2 -+ exit 1 -+ esac -+ shift -+done -+ -diff --git a/hsci/hsci.8 b/hsci/hsci.8 -new file mode 100644 -index 00000000..fc170532 ---- /dev/null -+++ b/hsci/hsci.8 -@@ -0,0 +1,100 @@ -+.\" Copyright IBM Corp. 2020 -+ -+.TH HSCI 8 "November 2020" "s390-tools" "Linux Programmer's Manual" -+ -+ -+.SH NAME -+.B hsci -+\- control and show HSCI settings. -+ -+ -+.SH SYNOPSIS -+.B hsci add -+.I HSDEV -+.I NETDEV -+.br -+.B hsci del -+.I HSCINAME -+.br -+.B hsci show -+.br -+.B hsci [\-hv] -+ -+.SH DESCRIPTION -+.BI hsci -+is used to control and show HSCI (HiperSockets Converged Interfaces) settings. A HiperSockets interface and an external network interface are converged into an HSCI interface. -+ -+.SH COMMANDS -+.TP -+.B add \fIHSDEV\fR \fINETDEV\fR -+.RS .4i -+.PP -+Adds an HSCI interface -+.PP -+.I HSDEV -+is the interface name of the HiperSockets device to be converged into the HSCI interface. -+.PP -+.I NETDEV -+is the interface name of the external network device to be converged into the HSCI interface. -+.RE -+ -+.TP -+.B del \fIHSCINAME\fR -+.RS .4i -+.PP -+Deletes an HSCI interface -+.PP -+.I HSCINAME -+is the name of the HSCI interface for the HiperSockets device and the external network device. -+.RE -+ -+.TP -+.B show -+.RS .4i -+.PP -+Lists the configured HSCI interfaces. -+.RE -+ -+.SH OPTIONS -+.TP -+.BR \-v ", " \-\-version -+Prints the version number of hsci and exits. -+.TP -+.BR \-h ", " \-\-help -+Displays the help information for the command. -+ -+.SH EXIT CODES -+.TP -+.BR "0" -+The hsci command ran successfully. -+ -+.TP -+.BR "1" -+An error occurred. -+ -+.SH EXAMPLE -+.BR "hsci show" -+.TP -+.RB -+Lists the configured HSCI interfaces: -+.RS 1.2i -+ -+HSCI PNET_ID HiperSockets External -+.br -+----------------------------------------- -+.br -+hsci8410 NET1 enc8410 encb040 -+ -+.RE -+ -+.SH SEE ALSO -+.nf -+ip(8), bridge(8) -+.fi -+ -+.SH AUTHOR -+.nf -+Written by Alexandra Winter -+ Wenjia Zhang -+.fi -+ --- -2.17.1 - diff --git a/s390-tools-sles15sp3-remove-no-pie-link-arguments.patch b/s390-tools-sles15sp3-remove-no-pie-link-arguments.patch index 5eaf4b8..5050ce2 100644 --- a/s390-tools-sles15sp3-remove-no-pie-link-arguments.patch +++ b/s390-tools-sles15sp3-remove-no-pie-link-arguments.patch @@ -1,6 +1,6 @@ --- s390-tools-2.15.1/common.mak 2020-10-28 10:31:59.000000000 -0400 +++ s390-tools-2.15.1/common.mak 2021-03-01 11:16:20.285597140 -0500 -@@ -224,8 +224,8 @@ +@@ -252,8 +252,8 @@ ifneq ($(shell $(CC_SILENT) -dumpspecs 2>/dev/null | grep -e '[^f]no-pie'),) NO_PIE_CFLAGS := -fno-pie diff --git a/s390-tools-sles15sp3-zcryptstats-Fix-handling-of-partial-results-with-man.patch b/s390-tools-sles15sp3-zcryptstats-Fix-handling-of-partial-results-with-man.patch deleted file mode 100644 index 95703e3..0000000 --- a/s390-tools-sles15sp3-zcryptstats-Fix-handling-of-partial-results-with-man.patch +++ /dev/null @@ -1,73 +0,0 @@ -Subject: [PATCH] [BZ 189239] zcryptstats: Fix handling of partial results with many domains -From: Ingo Franzki - -Description: zcryptstats: Fix handling of partial results with many domains -Symptom: Running zcryptstats when many domains are available per cryto - card does not produce any output, and is hanging in a loop. -Problem: When many domains per card are available, then the results of - the SCDMD CHSC call may not fit into the output area, and a - partial result is returned. The further results must be - retrieved with another CHSC call. Fix the code to pass the - correct next-domain to the subsequent CHSC call of a partial - response. Otherwise the same set of domains 1 to n are retrieved - again, resulting in an infinite loop, because this will always - produce a partial result. -Solution: Fix the code to pass the correct next-domain to the subsequent - CHSC call of a partial response. -Reproduction: Run zcryptstats on a system with many domains per card. -Upstream-ID: cf2311f1f1de17435b49ba8c8697be91705ba031 -Problem-ID: 189239 - -Upstream-Description: - - zcryptstats: Fix handling of partial results with many domains - - When many domains per card are available, then the results of the SCDMD - CHSC call may not fit into the output area, and a partial result is - returned. The further results must be retrieved with another CHSC call. - - Fix the code to pass the correct next-domain to the subsequent CHSC call - of a partial response. Otherwise the same set of domains 1 to n are - retrieved again, resulting in an infinite loop, because this will always - produce a partial result. - - Signed-off-by: Ingo Franzki - Reviewed-by: Harald Freudenberger - Signed-off-by: Jan Hoeppner - - -Signed-off-by: Ingo Franzki ---- - zconf/zcrypt/zcryptstats.c | 14 ++++++++------ - 1 file changed, 8 insertions(+), 6 deletions(-) - ---- a/zconf/zcrypt/zcryptstats.c -+++ b/zconf/zcrypt/zcryptstats.c -@@ -1178,8 +1178,14 @@ static int get_apqn_measurement_data(uin - scdmd_area.request.header.code = 0x102d; - scdmd_area.request.header.length = - sizeof(struct chsc_scdmd_request); -- scdmd_area.request.first_drid.ap_index = card; -- scdmd_area.request.first_drid.domain_index = g.min_domain; -+ if (scdmd_area.response.p) { -+ scdmd_area.request.first_drid = -+ scdmd_area.response.crid; -+ } else { -+ scdmd_area.request.first_drid.ap_index = card; -+ scdmd_area.request.first_drid.domain_index = -+ g.min_domain; -+ } - scdmd_area.request.last_drid.ap_index = card; - scdmd_area.request.last_drid.domain_index = g.max_domain; - scdmd_area.request.s = 1; -@@ -1217,10 +1223,6 @@ static int get_apqn_measurement_data(uin - rc = process_apqn_measurement_data(&scdmd_area); - if (rc != 0) - break; -- -- if (scdmd_area.response.p) -- scdmd_area.request.first_drid = -- scdmd_area.response.crid; - } while (scdmd_area.response.p); - - return rc; diff --git a/s390-tools-sles15sp3-zipl-fix-4k-scsi-ipl.patch b/s390-tools-sles15sp3-zipl-fix-4k-scsi-ipl.patch deleted file mode 100644 index 4e09f35..0000000 --- a/s390-tools-sles15sp3-zipl-fix-4k-scsi-ipl.patch +++ /dev/null @@ -1,64 +0,0 @@ -Subject: [PATCH] [BZ 191696] zipl: fix reading 4k disk's geometry -From: Stefan Haberland - -Description: zipl: fix IPL on 4K SCSI disks -Symptom: IPL is not working when bootloader is installed - on a SCSI disk with 4k physical blocksize without using - a devicemapper target. -Problem: The getgeo ioctl that is used reports the partition - start in multiple of 512 byte sectors but the blocksize - that is used is the physical blocksize of 4k and - therefore the calculated partition start does not - match. For device mapper targets the zipl-helper script - is used that adjusts the partition start correctly to - the physical blocksize. -Solution: Adjust the partition start depending on the physical - blocksize. -Reproduction: Use zipl to install a bootloader on a SCSI disk with 4k - physical blocksize and without usage of a device mapper - target. -Upstream-ID: 4a3957fab5696cc410c5b495956859a424e3552a -Problem-ID: 191696 - -Upstream-Description: - - zipl: fix reading 4k disk's geometry - - On 4k SCSI disks zipl stores wrong values to 'scsi_mbr.program_table_pointer', - which makes system unbootable. - This happens in 'zipl/src/disk.c:656': - - ``` - /* Convert file system block to physical */ - *physical = mapped * phy_per_fs + subblock; - /* Add partition start */ - *physical += info->geo.start; - - ``` - - So 'hd_geometry.start' should be adjusted before being used. - - Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1918723 - Closes: https://github.com/ibm-s390-linux/s390-tools/pull/107 - Signed-off-by: Nikita Dubrovskii - Reviewed-by: Stefan Haberland - Signed-off-by: Jan Hoeppner - - -Signed-off-by: Stefan Haberland ---- - zipl/src/disk.c | 3 +++ - 1 file changed, 3 insertions(+) - ---- a/zipl/src/disk.c -+++ b/zipl/src/disk.c -@@ -444,6 +444,9 @@ type_determined: - } - /* Convert device size to size in physical blocks */ - data->phy_blocks = devsize / (data->phy_block_size / 512); -+ /* Adjust start on SCSI according to block_size. device-mapper devices are skipped */ -+ if (data->type == disk_type_scsi && target->targetbase == NULL) -+ data->geo.start = data->geo.start / (data->phy_block_size / 512); - if (data->partnum != 0) - data->partition = stats.st_rdev; - /* Try to get device name */ diff --git a/s390-tools-sles15sp3-zkey-Fix-APQN-property-names.patch b/s390-tools-sles15sp3-zkey-Fix-APQN-property-names.patch deleted file mode 100644 index b2c523a..0000000 --- a/s390-tools-sles15sp3-zkey-Fix-APQN-property-names.patch +++ /dev/null @@ -1,49 +0,0 @@ -Subject: [PATCH] [BZ 189965] zkey: Fix APQN property names -From: Ingo Franzki - -Description: zkey: Fix KMS plugin configuration to store APQNs correctly. -Symptom: When a KMS plugin is configured with APQNs, the set of - APQNs is stored per card type, i.e. the set of CCA APQNs and - the set of EP11 APQNs is stored separately in the KMS - plugin configuration file. Unfortunately, the names of the - configuration properties are swapped, so that CCA APQNs are - stored as EP11 APQNs, and vice versa. - This does not cause any malfunction as of today, however - if this is fixed later, while a KMS plugin configuration - already exists, then the KMS plugin will fail to work once - the fix is applied. A KMS plugin reconfiguration would then - be needed to make the plugin work again. -Problem: The KMS configuration property names to store the CCA and - EP11 APQNs are incorrect, i.e. swapped. -Solution: Correct the KMS configuration property names. -Reproduction: Configure a KMS plugin with APQNs and check the KMS config - file. -Upstream-ID: 07d181e29b484108bce5ea07c1561ffb62a1b56e -Problem-ID: 189965 - -Upstream-Description: - - zkey: Fix APQN property names - - Signed-off-by: Ingo Franzki - Signed-off-by: Jan Hoeppner - - -Signed-off-by: Ingo Franzki ---- - zkey/kms.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/zkey/kms.c -+++ b/zkey/kms.c -@@ -46,8 +46,8 @@ - #define KMS_CONFIG_PROP_KMS "kms" - #define KMS_CONFIG_PROP_KMS_CONFIG "config" - #define KMS_CONFIG_PROP_APQNS "apqns" --#define KMS_CONFIG_PROP_CCA_APQNS "ep11_apqns" --#define KMS_CONFIG_PROP_EP11_APQNS "cca_apqns" -+#define KMS_CONFIG_PROP_CCA_APQNS "cca_apqns" -+#define KMS_CONFIG_PROP_EP11_APQNS "ep11_apqns" - #define KMS_CONFIG_LOCAL "local" - - #define KMS_KEY_PROP_NAME "zkey-name" diff --git a/s390-tools.changes b/s390-tools.changes index 99f06d5..544ec85 100644 --- a/s390-tools.changes +++ b/s390-tools.changes @@ -1,3 +1,108 @@ +------------------------------------------------------------------- +Mon Nov 8 20:08:54 UTC 2021 - Mark Post + +- Upgraded to version 2.19.0 (jsc#SLE-18324) + * v2.19.0 (2021-11-10)__ + Add new tools / libraries: + - chreipl-fcp-mpath: New toolset that uses multipath information to change + the configured FCP re-IPL path on detecting issues with the current path + Changes of existing tools: + - dbginfo.sh: Add retry timeout and remove possible blocking "blockdev --report" + - dbginfo.sh: Collect config- and debug-data for chreipl-fcp-mpath + - hsci: Add support for multiple MAC addresses + Bug Fixes: + - lshwc: Fix compile error for gcc <8.1 + - zdump: Various clean-ups and fixes + - ziomon: Correct throughput calculation in ziorep_printers + - zipl: Fix segmentation fault when setting stage3_parms + * v2.18.0 (2021-10-01)__ + Add new tools: + - scripts: Add tool for parsing sclp s390dbf logs + - zdev: Add udev rule helper tool + - zipl-editenv: Add tool to operate with zIPL environment installed in the boot record + Changes of existing tools: + - Makefile: Fix order of build of libraries for parallel builds + - dbginfo.sh: Add collection in area of timedate, coredump and --check option + - dbginfo.sh: Add exception on dump2tar for /sys/kernel/mm/page_idle/bitmap + - dbginfo.sh: Cleanup of outdated sections and general code rework + - dbginfo.sh: Collect zipl boot menu entries from boot loader specification + - lszcrypt: Add support for vfio-ap status field + - lszcrypt: Improved output for deconfig cards and queues + - lszfcp: Add linkdown case to host marker of extended output + - zdev: Add auto-config for PCI and crypto devices + - zdump: Introduce multi-level message logging + - zipl: Add support for environment block interpretation + - zkey-cryptsetup: Support LUKS2 volumes with integrity support enabled + Bug Fixes: + - hsavmcore: Avoid recompilation of overlay during install step + - libkmipclient: Fix parsing of hex values for XML and JSON encoding + - vmur/vmur.cpp: Fix error handling on transfer failure + - zdump: Lots of smaller fixes across the board + * v2.17.0 (2021-07-07)__ + Add new tools / libraries: + - hsavmcore: New utility to make the dump process with kdump more efficient + - libkmipclient: Add KMIP client shared library + - libseckey: Add a secure key library + - lshwc: New tool to extract and list complete counter sets + Changes of existing tools: + - genprotimg: Add '--(enable|disable)-pckmo' options + - genprotimg: Add OpenSSL 3.0 support + - genprotimg: Change plaintext control flags defaults so PCKMO functions are allowed + - libutil: Introduce multi-level message logging (util_log) + - libutil: Introduce util_arch module + - udev/dasd: Change DASD udev-rule to set none scheduler + - zdsfs: Add transparent codepage conversion + - zkey: Add support for KMIP-based key management systems + Bug Fixes: + - ttyrun-getty: Avoid conflicts with serial-getty@ + - dbginfo: add /proc/kallsyms - refresh zVM, lscpu - fix WORKARCHIVE handling + - dbginfo: add KVM data collection for server and guest - fix lszdev + - genprotimg: Add missing return values in error paths + - zkey: Fix conversion of CCA DATA keys to CCA CIPHER keys + - znetconf: avoid conflict with "chzdev -e" + * v2.16.0 (2021-02-19)__ + Add new tool: + - hsci: New tool to manage HSCI (HiperSockets Converged Interfaces) + Changes of existing tools: + - genprotimg: Add host-key document verification support + - genprotimg: boot: Make boot loader -march=z900 compatible + - libekmfweb: Make install directory for shared libraries configurable + - lsdasd: Add FC Endpoint Security information + - make: Add address sanitizer support + - netboot: Add version information to scripts + - netboot: Bump busybox version in pxelinux.0 build + - zdev: Add FC Endpoint Security information for DASD devices + - zdev: Add build option to update initial RAM-disk by default + - zkey-ekmfweb: Avoid sequence number clash when generating keys + - zkey/zkey-ekmfweb: Install KMS plugins into configurable location + - zkey: Add support to store LUKS2 dummy passphrase in key repository + Bug Fixes: + - dasdfmt: Fix segfault when an incorrect option is specified + - genprotimg: Fix several build issues + - genprotimg: Require argument for 'ramdisk' and 'parmfile' options + - zcryptstats: Fix handling of partial results with many domains + - zfcpdbf: Deal with crash 7.2.9 change in caller name formatting + - zipl/boot: Fix memory use after free in stage2 + - zipl/boot: Fix potential heap overflow in stage2 + - zipl: Fix reading 4k disk's geometry +- Removed the following obsolete patches + * s390-tools-sles15sp3-dasdfmt-Fix-segfault-when-an-incorrect-option-is-spe.patch + * s390-tools-sles15sp3-libutil-Compare-proc-entries-to-vfstype.patch + * s390-tools-sles15sp3-01-zdev-Add-FC-Endpoint-Security-information-for-DASD-d.patch + * s390-tools-sles15sp3-02-lsdasd-Add-FC-Endpoint-Security-information.patch + * s390-tools-sles15sp3-hsci-Add-new-tool-to-control-HiperSockets-Converged-.patch + * s390-tools-sles15sp3-zcryptstats-Fix-handling-of-partial-results-with-man.patch + * s390-tools-sles15sp3-01-genprotimg-abort-if-one-of-the-recursive-targets-is-.patch + * s390-tools-sles15sp3-02-genprotimg-fix-two-memory-leaks.patch + * s390-tools-sles15sp3-03-genprotimg-require-argument-for-ramdisk-and-parmfile.patch + * s390-tools-sles15sp3-04-genprotimg-add-host-key-document-verification-suppor.patch + * s390-tools-sles15sp3-zkey-Fix-APQN-property-names.patch + * s390-tools-sles15sp3-zipl-fix-4k-scsi-ipl.patch + * s390-tools-sles15sp3-dasd-change-DASD-udev-rule-to-set-none-scheduler.patch + * s390-tools-sles15sp3-check-return-code-from-util_file_read_l.patch +- Removed an obsolete "export ROOT_BUILD_DIR" statement from the spec file. +- Removed unnecessary defattr statements in the files section. + ------------------------------------------------------------------- Mon Oct 18 17:51:04 UTC 2021 - Mark Post @@ -7,6 +112,26 @@ Mon Oct 18 17:51:04 UTC 2021 - Mark Post - Did some spec file cleanup based on the recommendations from spec-cleaner. +------------------------------------------------------------------- +Fri Jun 18 20:55:06 UTC 2021 - Mark Post + +- Reworked s390-tools-sles15sp2-Implement-Y-yast_mode.patch (yet + again). If more DASD volumes are to be formatted than are allowed + by the "maximum number to do in parallel" parameter, dasdfmt + waits until one of the child processes ends before starting another. + For YaST to be able to figure out how many cylinders a particular + DASD volume has, that information has to be output for _all_ of the + volumes, before any of the child processes are spawned. + (bsc#1187012) + +------------------------------------------------------------------- +Wed May 26 21:13:23 UTC 2021 - Mark Post + +- Modified the following patches to correct the output from the + dasdfmt command when *not* using "YaST mode." (bsc#1182816, bsc#1182820) + * s390-tools-sles15sp3-Format-devices-in-parallel.patch + * s390-tools-sles15sp3-Implement-Y-yast_mode.patch + ------------------------------------------------------------------- Thu May 6 13:59:15 UTC 2021 - Mark Post diff --git a/s390-tools.spec b/s390-tools.spec index be287f8..2effb61 100644 --- a/s390-tools.spec +++ b/s390-tools.spec @@ -23,7 +23,7 @@ %endif Name: s390-tools -Version: 2.15.1 +Version: 2.19.0 Release: 0 Summary: S/390 tools like zipl and dasdfmt License: MIT @@ -87,20 +87,6 @@ Source98: zfcp_disk_configure.8 Source99: zfcp_host_configure.8 ### -Patch1: s390-tools-sles15sp3-dasdfmt-Fix-segfault-when-an-incorrect-option-is-spe.patch -Patch2: s390-tools-sles15sp3-libutil-Compare-proc-entries-to-vfstype.patch -Patch3: s390-tools-sles15sp3-01-zdev-Add-FC-Endpoint-Security-information-for-DASD-d.patch -Patch4: s390-tools-sles15sp3-02-lsdasd-Add-FC-Endpoint-Security-information.patch -Patch5: s390-tools-sles15sp3-hsci-Add-new-tool-to-control-HiperSockets-Converged-.patch -Patch6: s390-tools-sles15sp3-zcryptstats-Fix-handling-of-partial-results-with-man.patch -Patch7: s390-tools-sles15sp3-01-genprotimg-abort-if-one-of-the-recursive-targets-is-.patch -Patch8: s390-tools-sles15sp3-02-genprotimg-fix-two-memory-leaks.patch -Patch9: s390-tools-sles15sp3-03-genprotimg-require-argument-for-ramdisk-and-parmfile.patch -Patch10: s390-tools-sles15sp3-04-genprotimg-add-host-key-document-verification-suppor.patch -Patch11: s390-tools-sles15sp3-zkey-Fix-APQN-property-names.patch -Patch12: s390-tools-sles15sp3-zipl-fix-4k-scsi-ipl.patch -Patch13: s390-tools-sles15sp3-dasd-change-DASD-udev-rule-to-set-none-scheduler.patch - # SUSE patches Patch900: s390-tools-sles12-zipl_boot_msg.patch Patch901: s390-tools-sles15-sysconfig-compatible-dumpconf.patch @@ -113,8 +99,7 @@ Patch907: s390-tools-sles15sp3-Implement-f-for-backwards-compability.patch Patch908: s390-tools-sles15sp3-dasdfmt-retry-BIODASDINFO-if-device-is-busy.patch Patch909: s390-tools-sles12-fdasd-skip-partition-check-and-BLKRRPART-ioctl.patch Patch910: s390-tools-sles15sp1-11-zdev-Do-not-call-zipl-on-initrd-update.patch -Patch911: s390-tools-sles15sp3-check-return-code-from-util_file_read_l.patch -Patch912: s390-tools-sles15sp3-remove-no-pie-link-arguments.patch +Patch911: s390-tools-sles15sp3-remove-no-pie-link-arguments.patch BuildRequires: curl-devel BuildRequires: dracut @@ -127,8 +112,10 @@ BuildRequires: kernel-zfcpdump BuildRequires: libcryptsetup-devel > 2.0.3 BuildRequires: libjson-c-devel BuildRequires: libpfm-devel +BuildRequires: libxml2-devel BuildRequires: ncurses-devel BuildRequires: net-snmp-devel +BuildRequires: openssl-devel >= 1.1.1l BuildRequires: pesign-obs-integration BuildRequires: qclib-devel-static BuildRequires: tcpd-devel @@ -211,7 +198,7 @@ on IBM Z servers. Summary: IBM Enterprise Key Management Foundation - Web Edition client library License: MIT Group: Development/Libraries/C and C++ -Requires: libekmfweb1 +Requires: libekmfweb1 = %{version} %description -n libekmfweb1-devel libekmfweb1 is a client library that provides access to IBM' Enterprise Key @@ -219,6 +206,54 @@ Management Foundation – Web Edition.0 EKMF Web provides efficient and security-rich centralized key management for IBM z/OS data set encryption on IBM Z servers. +%package -n libkmipclient1 +Summary: IBM Key Management Interoperability Protocol (KMIP) client library +License: MIT +Group: System/Libraries + +%description -n libkmipclient1 +Key Management Interoperability Protocol (KMIP) is a client/server +communication protocol for the storage and maintenance of key, +certificate, and secret objects. This client library enables secure +creation and storage of cryptographic objects on the IBM Security Key +Lifecycle Manager server. You must configure client devices to connect +to the server for key management operations. + +%package -n libkmipclient1-devel +Summary: Header files for the IBM Z KMIP client library +License: MIT +Group: Development/Libraries/C and C++ +Requires: libkmipclient1 = %{version} + +%description -n libkmipclient1-devel +This package provides the header files and symbolic link to the +shared library for the IBM Z KMIP client library. + +%package chreipl-fcp-mpath +Summary: Use multipath information for re-IPL path failover +License: MIT +Group: System/Boot +BuildRequires: bash +BuildRequires: coreutils +## Required for build+install with ENABLE_DOC=1 +#BuildRequires: pandoc +BuildRequires: sed +#BuildRequires: gawk +#BuildRequires: gzip +Requires: bash +# Required for use with HAVE_DRACUT=1 +Requires: dracut +Requires: multipath-tools +Requires: udev +Requires(post): udev + +%description chreipl-fcp-mpath +The chreipl-fcp-mpath toolset monitors udev events about paths to the +re-IPL volume. If the currently configured FCP re-IPL path becomes +unavailable, the toolset checks for operational paths to the same +volume. If available, it reconfigures the FCP re-IPL settings to use an +operational path. + %prep %autosetup -p1 @@ -234,7 +269,9 @@ export OPT_FLAGS="%{optflags}" export KERNELIMAGE_MAKEFLAGS="%%{?_smp_mflags}" %make_build \ ZFCPDUMP_DIR=%{_prefix}/lib/s390-tools/zfcpdump \ - DISTRELEASE=%{release} + DISTRELEASE=%{release} \ + UDEVRUNDIR=/run/udev \ + HAVE_DRACUT=1 gcc -static -o read_values ${OPT_FLAGS} %{SOURCE86} -lqc %install @@ -244,6 +281,7 @@ mkdir -p %{buildroot}%{_sysconfdir}/zkey/repository ZFCPDUMP_DIR=%{_prefix}/lib/s390-tools/zfcpdump \ DISTRELEASE=%{release} \ SYSTEMDSYSTEMUNITDIR=%{_unitdir} \ + UDEVRUNDIR=/run/udev \ HAVE_DRACUT=1 # The make install command puts things in /etc/sysconfig and not the @@ -258,8 +296,13 @@ popd install -m 755 read_values %{buildroot}/%{_bindir}/ install -m644 -t %{buildroot}/%{_mandir}/man8 %{SOURCE87} -export ROOT_BUILD_DIR="%{_builddir}/%{name}-%{version}/zfcpdump/kernel" +# The "usrmerge" has happened in openSUSE:Factory, but not yet in SLES. +# Make sure we look for the zfcpdump kernel image in the right place. +%if 0%{?usrmerged} install -D -m600 %{_prefix}/lib/modules/*-zfcpdump/image %{buildroot}%{_prefix}/lib/s390-tools/zfcpdump/zfcpdump-image +%else +install -D -m600 /boot/image-*-zfcpdump %{buildroot}%{_prefix}/lib/s390-tools/zfcpdump/zfcpdump-image +%endif install -D -m644 etc/cpuplugd.conf %{buildroot}%{_sysconfdir}/cpuplugd.conf install -D -m644 etc/udev/rules.d/40-z90crypt.rules %{buildroot}%{_prefix}/lib/udev/rules.d/40-z90crypt.rules @@ -343,7 +386,7 @@ rm -fv %{buildroot}/%{_sbindir}/chmem find . ! -type d | sed 's/^.//;\-/man/-s/^.*$/%doc &.gz/' > %{_builddir}/%{name}-filelist -grep -v -E 'osasnmp|*\.conf$|ekmfweb.so|ekmfweb.h' %{_builddir}/%{name}-filelist >%{_builddir}/%{name}.list +grep -v -E 'osasnmp|*\.conf$|ekmfweb.so|ekmfweb.h|kmipclient|kmip/profiles/*\.profile|chreipl-fcp-mpath' %{_builddir}/%{name}-filelist >%{_builddir}/%{name}.list grep osasnmp[^-] %{_builddir}/%{name}-filelist >%{_builddir}/%{name}.osasnmp touch boot/zipl/active_devices.txt @@ -435,6 +478,12 @@ grep -q '^%{_bindir}/ts-shell$' %{_sysconfdir}/shells \ %post -n libekmfweb1 ldconfig +%post -n libkmipclient1 +ldconfig + +%post chreipl-fcp-mpath +%udev_rules_update + %preun %service_del_preun appldata.service %service_del_preun cio_ignore.service @@ -466,6 +515,9 @@ ldconfig %postun -n libekmfweb1 ldconfig +%postun -n libkmipclient1 +ldconfig + # Even though SLES15+ is systemd based, the build service doesn't # run it, so we have to make sure we can safely issue the # systemctl command. @@ -496,7 +548,7 @@ fi %{stop_on_removal osasnmpd} %files -f %{_builddir}/%{name}.list -%defattr(-,root,root) + %doc README.md %doc README.SUSE @@ -509,7 +561,10 @@ fi %config %attr(0640,root,ts-shell) %{_sysconfdir}/iucvterm/ts-shell.conf %config %attr(0640,root,ts-shell) %{_sysconfdir}/iucvterm/unrestricted.conf %dir %attr(0770,root,zkeyadm) %{_sysconfdir}/zkey +%dir %attr(0770,root,zkeyadm) %{_sysconfdir}/zkey/kmip +%dir %attr(0770,root,zkeyadm) %{_sysconfdir}/zkey/kmip/profiles %dir %attr(0770,root,zkeyadm) %{_sysconfdir}/zkey/repository +%config %{_sysconfdir}/zkey/kmip/profiles/* %config %{_sysconfdir}/modprobe.d/90-s390-tools.conf %config %{_sysconfdir}/cpuplugd.conf %config %{_sysconfdir}/zkey/kms-plugins.conf @@ -540,24 +595,20 @@ fi %exclude %{_mandir}/man8/lshmc.8.gz %files -n osasnmpd -f %{_builddir}/%{name}.osasnmp -%defattr(-,root,root) %{_libexecdir}/net-snmp/agents/osasnmpd %files zdsfs -%defattr(-,root,root) %doc CAUTION %{_bindir}/zdsfs %{_mandir}/man1/zdsfs.1%{?ext_man} %files hmcdrvfs -%defattr(-,root,root) %{_bindir}/hmcdrvfs %{_sbindir}/lshmc %{_mandir}/man1/hmcdrvfs.1%{?ext_man} %{_mandir}/man8/lshmc.8%{?ext_man} %files -n libekmfweb1 -%defattr(-,root,root) %{_libdir}/libekmfweb.so.* %files -n libekmfweb1-devel @@ -565,4 +616,28 @@ fi %dir %attr(755,root,root) %{_includedir}/ekmfweb %attr(644,root,root) %{_includedir}/ekmfweb/ekmfweb.h +%files -n libkmipclient1 +%{_libdir}/libkmipclient.so.* + +%files -n libkmipclient1-devel +%{_libdir}/libkmipclient.so +%dir %attr(755,root,root) %{_includedir}/kmipclient +%attr(644,root,root) %{_includedir}/kmipclient/kmipclient.h + +%files chreipl-fcp-mpath +%doc chreipl-fcp-mpath/README.md +## Requires build+install with ENABLE_DOC=1 +#doc chreipl-fcp-mpath/README.html +%dir %{_prefix}/lib/chreipl-fcp-mpath/ +%{_prefix}/lib/chreipl-fcp-mpath/* +%{_prefix}/lib/dracut/dracut.conf.d/70-chreipl-fcp-mpath.conf +%{_prefix}/lib/udev/chreipl-fcp-mpath-is-ipl-tgt +%{_prefix}/lib/udev/chreipl-fcp-mpath-is-ipl-vol +%{_prefix}/lib/udev/chreipl-fcp-mpath-is-reipl-zfcp +%{_prefix}/lib/udev/chreipl-fcp-mpath-record-volume-identifier +%{_prefix}/lib/udev/chreipl-fcp-mpath-try-change-ipl-path +%{_udevrulesdir}/70-chreipl-fcp-mpath.rules +## Requires build+install with ENABLE_DOC=1 +#{_mandir}/man7/chreipl-fcp-mpath.7.gz + %changelog From cfd1a1864ba5da62f8d0f17e41bf8ce8e6b79f95e1a839a09a834fdd21250ac5 Mon Sep 17 00:00:00 2001 From: Mark Post Date: Sat, 13 Nov 2021 20:15:37 +0000 Subject: [PATCH 2/2] OBS-URL: https://build.opensuse.org/package/show/Base:System/s390-tools?expand=0&rev=125 --- ...util-Compare-proc-entries-to-vfstype.patch | 41 ------------------- 1 file changed, 41 deletions(-) delete mode 100644 s390-tools-sles15sp3-libutil-Compare-proc-entries-to-vfstype.patch diff --git a/s390-tools-sles15sp3-libutil-Compare-proc-entries-to-vfstype.patch b/s390-tools-sles15sp3-libutil-Compare-proc-entries-to-vfstype.patch deleted file mode 100644 index e79af9f..0000000 --- a/s390-tools-sles15sp3-libutil-Compare-proc-entries-to-vfstype.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 8ec47052397a868c0764900db69fda4a892bd512 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Jan=20H=C3=B6ppner?= -Date: Fri, 6 Nov 2020 18:47:07 +0100 -Subject: [PATCH] libutil: Compare proc entries to vfstype -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Modern systems have systemd manage system mount points like sysfs which -specify 'sysfs' as a keyword for the device as there is no device -associated with this special filesystem. However, any arbitrary string -could be specified here and the determination of the sysfs mount point -would fail in such a case. -To make sure that the mount point of the sysfs is still found when -mounted with a device keyword specified other than 'sysfs', check for -the filesystem type instead, which is more specific. - -Fixes: https://github.com/ibm-s390-tools/s390-tools/issues/91 -Suggested-by: Mark Post -Reviewed-by: Stefan Haberland -Signed-off-by: Jan Höppner ---- - libutil/util_proc.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/libutil/util_proc.c b/libutil/util_proc.c -index 080f831..9ac4381 100644 ---- a/libutil/util_proc.c -+++ b/libutil/util_proc.c -@@ -460,7 +460,7 @@ int util_proc_mnt_get_entry(const char *file_name, const char *spec, - rc = scan_mnt_entry(&file, entry); - if (rc) - goto out_free; -- if (!strcmp(entry->spec, spec)) { -+ if (!strcmp(entry->vfstype, spec)) { - rc = 0; - goto out_free; - } --- -2.26.2 -