From 6c258856c5f2992128d1f17b59ba920e74e5b4a5 Mon Sep 17 00:00:00 2001 From: Peter Jones Date: Tue, 18 Feb 2020 17:27:22 -0500 Subject: [PATCH 1/9] Rebuild to match OpenSC's token name mangling change. Signed-off-by: Peter Jones --- pesign.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/pesign.spec b/pesign.spec index 134921a..c29c84f 100644 --- a/pesign.spec +++ b/pesign.spec @@ -3,7 +3,7 @@ Name: pesign Summary: Signing utility for UEFI binaries Version: 0.112 -Release: 28%{?dist} +Release: 29%{?dist} License: GPLv2 URL: https://github.com/vathpela/pesign @@ -178,6 +178,9 @@ exit 0 %{python3_sitelib}/mockbuild/plugins/pesign.* %changelog +* Tue Feb 18 2020 Peter Jones - 0.112-29 +- Rebuild to match OpenSC's token name mangling change. + * Thu Jan 30 2020 Fedora Release Engineering - 0.112-28 - Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild From d804a043d72e69825eb5881f4b5ebe7cdcbf580a Mon Sep 17 00:00:00 2001 From: Peter Jones Date: Tue, 18 Feb 2020 17:33:22 -0500 Subject: [PATCH 2/9] Backport a minor fix. Signed-off-by: Peter Jones --- 0031-pesigcheck-Fix-a-wrong-assignment.patch | 49 ++++++++++++++++++++ pesign.spec | 1 + 2 files changed, 50 insertions(+) create mode 100644 0031-pesigcheck-Fix-a-wrong-assignment.patch diff --git a/0031-pesigcheck-Fix-a-wrong-assignment.patch b/0031-pesigcheck-Fix-a-wrong-assignment.patch new file mode 100644 index 0000000..7df5f0b --- /dev/null +++ b/0031-pesigcheck-Fix-a-wrong-assignment.patch @@ -0,0 +1,49 @@ +From c555fd74c009242c3864576bd5f17a1f8f4fdffd Mon Sep 17 00:00:00 2001 +From: Peter Jones +Date: Tue, 18 Feb 2020 16:28:56 -0500 +Subject: [PATCH] pesigcheck: Fix a wrong assignment + +gcc says: + + pesigcheck.c: In function 'check_signature': + pesigcheck.c:321:17: error: implicit conversion from 'enum ' to 'enum ' [-Werror=enum-conversion] + 321 | reason->type = siBuffer; + | ^ + pesigcheck.c:333:17: error: implicit conversion from 'enum ' to 'enum ' [-Werror=enum-conversion] + 333 | reason->type = siBuffer; + | ^ + cc1: all warnings being treated as errors + +And indeed, that line of code makes no sense at all - it was supposed to +be reason->sig.type. + +Signed-off-by: Peter Jones +--- + src/pesigcheck.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/pesigcheck.c b/src/pesigcheck.c +index 524cce307bf..8fa0f1ad03d 100644 +--- a/src/pesigcheck.c ++++ b/src/pesigcheck.c +@@ -318,7 +318,7 @@ check_signature(pesigcheck_context *ctx, int *nreasons, + reason->type = SIGNATURE; + reason->sig.data = data; + reason->sig.len = datalen; +- reason->type = siBuffer; ++ reason->sig.type = siBuffer; + nreason += 1; + is_invalid = true; + } +@@ -330,7 +330,7 @@ check_signature(pesigcheck_context *ctx, int *nreasons, + reason->type = SIGNATURE; + reason->sig.data = data; + reason->sig.len = datalen; +- reason->type = siBuffer; ++ reason->sig.type = siBuffer; + nreason += 1; + has_valid_cert = true; + } +-- +2.24.1 + diff --git a/pesign.spec b/pesign.spec index c29c84f..4a74aa2 100644 --- a/pesign.spec +++ b/pesign.spec @@ -71,6 +71,7 @@ Patch0027: 0027-Make-pesign-users-groups-static-in-the-repo.patch Patch0028: 0028-rpm-Make-the-client-signer-use-the-fedora-values-unl.patch Patch0029: 0029-Make-macros.pesign-error-in-kojibuilder-if-we-don-t-.patch Patch0030: 0030-efikeygen-Fix-the-build-with-nss-3.44.patch +Patch0031: 0031-pesigcheck-Fix-a-wrong-assignment.patch %description This package contains the pesign utility for signing UEFI binaries as From f5005c0628ac783bdeb162c0692dadfda293801f Mon Sep 17 00:00:00 2001 From: Jeremy Cline Date: Tue, 18 Feb 2020 16:37:53 -0500 Subject: [PATCH 3/9] pesign: Apparently opensc got updated and the token name changed All the kernel builds started failing yesterday because the signing token could not be found. Update the token name in the macro shipped by pesign. --- 0028-rpm-Make-the-client-signer-use-the-fedora-values-unl.patch | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/0028-rpm-Make-the-client-signer-use-the-fedora-values-unl.patch b/0028-rpm-Make-the-client-signer-use-the-fedora-values-unl.patch index 3f0b2e1..793fe6c 100644 --- a/0028-rpm-Make-the-client-signer-use-the-fedora-values-unl.patch +++ b/0028-rpm-Make-the-client-signer-use-the-fedora-values-unl.patch @@ -17,7 +17,7 @@ index 69280e9..22a3ee6 100644 %__pesign_token %{nil}%{?pe_signing_token:-t "%{pe_signing_token}"} %__pesign_cert %{!?pe_signing_cert:"Red Hat Test Certificate"}%{?pe_signing_cert:"%{pe_signing_cert}"} -+%__pesign_client_token %{!?pe_signing_token:"Fedora Signer (OpenSC Card)"}%{?pe_signing_token:"%{pe_signing_token}"} ++%__pesign_client_token %{!?pe_signing_token:"OpenSC Card (Fedora Signer)"}%{?pe_signing_token:"%{pe_signing_token}"} +%__pesign_client_cert %{!?pe_signing_cert:"/CN=Fedora Secure Boot Signer"}%{?pe_signing_cert:"%{pe_signing_cert}"} + %_pesign /usr/bin/pesign From 5d1affcd0094a9b2d51a7f2279e07fbeec388b59 Mon Sep 17 00:00:00 2001 From: Peter Jones Date: Mon, 24 Feb 2020 12:48:21 -0500 Subject: [PATCH 4/9] Make sure the patch for -29 is actually in the build in f32, and synchronize with master. Signed-off-by: Peter Jones --- pesign.spec | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/pesign.spec b/pesign.spec index 4a74aa2..f75e1ef 100644 --- a/pesign.spec +++ b/pesign.spec @@ -3,7 +3,7 @@ Name: pesign Summary: Signing utility for UEFI binaries Version: 0.112 -Release: 29%{?dist} +Release: 30%{?dist} License: GPLv2 URL: https://github.com/vathpela/pesign @@ -179,6 +179,10 @@ exit 0 %{python3_sitelib}/mockbuild/plugins/pesign.* %changelog +* Mon Feb 24 2020 Peter Jones - 0.112-30 +- Make sure the patch for -29 is actually in the build in f32, and + synchronize with master. + * Tue Feb 18 2020 Peter Jones - 0.112-29 - Rebuild to match OpenSC's token name mangling change. From bbe011b4163297b08386dde10e9896442248d288 Mon Sep 17 00:00:00 2001 From: Peter Jones Date: Thu, 16 Jul 2020 16:29:13 -0400 Subject: [PATCH 5/9] Synchronize with master Signed-off-by: Peter Jones --- ...e_integer-it-doesn-t-build-on-i686-a.patch | 72 --- ...fikeygen-Fix-the-build-with-nss-3.44.patch | 0 0002-Fix-command-line-parsing.patch | 73 --- ...02-pesigcheck-Fix-a-wrong-assignment.patch | 0 ...t-and-server-work-with-the-113-proto.patch | 317 +++++++++++++ ...gcc-don-t-error-on-stuff-in-includes.patch | 26 -- 0004-Fix-certficate-argument-name.patch | 39 -- 0004-Rename-var-run-to-run.patch | 46 ++ ...c-got-updated-and-the-token-name-cha.patch | 30 ++ ...ion-of-ascii-armor-option-in-manpage.patch | 26 -- ...ke-ascii-work-since-we-documented-it.patch | 22 - ...-run-and-var-run-for-the-socket-path.patch | 86 ++++ ...ient-to-also-accept-token-cert-macro.patch | 32 -- 0007-client-remove-an-extra-debug-print.patch | 25 ++ ...ros.pesign-to-pesign-rpmbuild-helper.patch | 383 ++++++++++++++++ ...fy-with-the-cert-as-an-object-signer.patch | 25 -- ...sigcheck-make-certfile-actually-work.patch | 47 -- 0009-pesign-authorize-shellcheck.patch | 60 +++ ...ize-don-t-setfacl-etc-pki-pesign-foo.patch | 26 ++ ...-make-sure-err-is-always-initialized.patch | 27 -- 0011-kernel-building-hack.patch | 41 ++ ...make-pesign-h-tell-you-the-file-name.patch | 26 -- 0012-Add-coverity-build-scripts.patch | 104 ----- 0012-Use-run-not-var-run.patch | 105 +++++ 0013-Document-implicit-fallthrough.patch | 25 -- ...cl-each-directory-of-our-key-storage.patch | 50 --- ..._MODULE_SIGNING_ONLY-and-fix-our-arr.patch | 59 --- 0016-efikeygen-add-modsign.patch | 197 -------- ...y-even-harder-to-pick-a-reasonable-v.patch | 121 ----- 0018-show-which-db-we-re-checking.patch | 137 ------ 0019-more-about-the-time.patch | 97 ---- 0020-try-to-say-why-something-fails.patch | 419 ------------------ ...ix-race-condition-in-SEC_GetPassword.patch | 34 -- ...eate-the-socket-directory-at-runtime.patch | 27 -- ...-Better-authorization-scripts.-Again.patch | 217 --------- ...also-try-to-give-better-errors-on-EP.patch | 95 ---- 0025-certdb-fix-PRTime-printfs-for-i686.patch | 31 -- ...-Clean-up-gcc-command-lines-a-little.patch | 41 -- ...sign-users-groups-static-in-the-repo.patch | 54 --- ...ent-signer-use-the-fedora-values-unl.patch | 43 -- ...gn-error-in-kojibuilder-if-we-don-t-.patch | 39 -- pesign.spec | 72 ++- sources | 4 +- 43 files changed, 1152 insertions(+), 2248 deletions(-) delete mode 100644 0001-cms-kill-generate_integer-it-doesn-t-build-on-i686-a.patch rename 0030-efikeygen-Fix-the-build-with-nss-3.44.patch => 0001-efikeygen-Fix-the-build-with-nss-3.44.patch (100%) delete mode 100644 0002-Fix-command-line-parsing.patch rename 0031-pesigcheck-Fix-a-wrong-assignment.patch => 0002-pesigcheck-Fix-a-wrong-assignment.patch (100%) create mode 100644 0003-Make-0.112-client-and-server-work-with-the-113-proto.patch delete mode 100644 0003-gcc-don-t-error-on-stuff-in-includes.patch delete mode 100644 0004-Fix-certficate-argument-name.patch create mode 100644 0004-Rename-var-run-to-run.patch create mode 100644 0005-Apparently-opensc-got-updated-and-the-token-name-cha.patch delete mode 100644 0005-Fix-description-of-ascii-armor-option-in-manpage.patch delete mode 100644 0006-Make-ascii-work-since-we-documented-it.patch create mode 100644 0006-client-try-run-and-var-run-for-the-socket-path.patch delete mode 100644 0007-Switch-pesign-client-to-also-accept-token-cert-macro.patch create mode 100644 0007-client-remove-an-extra-debug-print.patch create mode 100644 0008-Move-most-of-macros.pesign-to-pesign-rpmbuild-helper.patch delete mode 100644 0008-pesigcheck-Verify-with-the-cert-as-an-object-signer.patch delete mode 100644 0009-pesigcheck-make-certfile-actually-work.patch create mode 100644 0009-pesign-authorize-shellcheck.patch create mode 100644 0010-pesign-authorize-don-t-setfacl-etc-pki-pesign-foo.patch delete mode 100644 0010-signerInfos-make-sure-err-is-always-initialized.patch create mode 100644 0011-kernel-building-hack.patch delete mode 100644 0011-pesign-make-pesign-h-tell-you-the-file-name.patch delete mode 100644 0012-Add-coverity-build-scripts.patch create mode 100644 0012-Use-run-not-var-run.patch delete mode 100644 0013-Document-implicit-fallthrough.patch delete mode 100644 0014-Actually-setfacl-each-directory-of-our-key-storage.patch delete mode 100644 0015-oid-add-SHIM_EKU_MODULE_SIGNING_ONLY-and-fix-our-arr.patch delete mode 100644 0016-efikeygen-add-modsign.patch delete mode 100644 0017-check_cert_db-try-even-harder-to-pick-a-reasonable-v.patch delete mode 100644 0018-show-which-db-we-re-checking.patch delete mode 100644 0019-more-about-the-time.patch delete mode 100644 0020-try-to-say-why-something-fails.patch delete mode 100644 0021-Fix-race-condition-in-SEC_GetPassword.patch delete mode 100644 0022-sysvinit-Create-the-socket-directory-at-runtime.patch delete mode 100644 0023-Better-authorization-scripts.-Again.patch delete mode 100644 0024-Make-the-daemon-also-try-to-give-better-errors-on-EP.patch delete mode 100644 0025-certdb-fix-PRTime-printfs-for-i686.patch delete mode 100644 0026-Clean-up-gcc-command-lines-a-little.patch delete mode 100644 0027-Make-pesign-users-groups-static-in-the-repo.patch delete mode 100644 0028-rpm-Make-the-client-signer-use-the-fedora-values-unl.patch delete mode 100644 0029-Make-macros.pesign-error-in-kojibuilder-if-we-don-t-.patch diff --git a/0001-cms-kill-generate_integer-it-doesn-t-build-on-i686-a.patch b/0001-cms-kill-generate_integer-it-doesn-t-build-on-i686-a.patch deleted file mode 100644 index 0c82dcf..0000000 --- a/0001-cms-kill-generate_integer-it-doesn-t-build-on-i686-a.patch +++ /dev/null @@ -1,72 +0,0 @@ -From 33bcca8303cad962606df3bfc6a031a9b0626375 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Thu, 21 Apr 2016 10:47:34 -0400 -Subject: [PATCH 01/29] cms: kill generate_integer(), it doesn't build on i686 - and it's unused. - -Signed-off-by: Peter Jones ---- - src/cms_common.c | 34 ---------------------------------- - src/cms_common.h | 1 - - 2 files changed, 35 deletions(-) - -diff --git a/src/cms_common.c b/src/cms_common.c -index b19bc62..6a4e6a7 100644 ---- a/src/cms_common.c -+++ b/src/cms_common.c -@@ -641,40 +641,6 @@ generate_string(cms_context *cms, SECItem *der, char *str) - return 0; - } - --static SEC_ASN1Template IntegerTemplate[] = { -- {.kind = SEC_ASN1_INTEGER, -- .offset = 0, -- .sub = NULL, -- .size = sizeof(long), -- }, -- { 0 }, --}; -- --int --generate_integer(cms_context *cms, SECItem *der, unsigned long integer) --{ -- void *ret; -- -- uint32_t u32; -- -- SECItem input = { -- .data = (void *)&integer, -- .len = sizeof(integer), -- .type = siUnsignedInteger, -- }; -- -- if (integer < 0x100000000) { -- u32 = integer & 0xffffffffUL; -- input.data = (void *)&u32; -- input.len = sizeof(u32); -- } -- -- ret = SEC_ASN1EncodeItem(cms->arena, der, &input, IntegerTemplate); -- if (ret == NULL) -- cmsreterr(-1, cms, "could not encode data"); -- return 0; --} -- - int - generate_time(cms_context *cms, SECItem *encoded, time_t when) - { -diff --git a/src/cms_common.h b/src/cms_common.h -index 7d77faf..c7d7268 100644 ---- a/src/cms_common.h -+++ b/src/cms_common.h -@@ -117,7 +117,6 @@ extern int generate_object_id(cms_context *ctx, SECItem *encoded, - SECOidTag tag); - extern int generate_empty_sequence(cms_context *ctx, SECItem *encoded); - extern int generate_time(cms_context *ctx, SECItem *encoded, time_t when); --extern int generate_integer(cms_context *cms, SECItem *der, unsigned long integer); - extern int generate_string(cms_context *cms, SECItem *der, char *str); - extern int wrap_in_set(cms_context *cms, SECItem *der, SECItem **items); - extern int wrap_in_seq(cms_context *cms, SECItem *der, --- -2.13.4 - diff --git a/0030-efikeygen-Fix-the-build-with-nss-3.44.patch b/0001-efikeygen-Fix-the-build-with-nss-3.44.patch similarity index 100% rename from 0030-efikeygen-Fix-the-build-with-nss-3.44.patch rename to 0001-efikeygen-Fix-the-build-with-nss-3.44.patch diff --git a/0002-Fix-command-line-parsing.patch b/0002-Fix-command-line-parsing.patch deleted file mode 100644 index 9c03eeb..0000000 --- a/0002-Fix-command-line-parsing.patch +++ /dev/null @@ -1,73 +0,0 @@ -From 5be0515dee24308fd7e270bf2e0fb5e5a7a78f32 Mon Sep 17 00:00:00 2001 -From: Julien Cristau -Date: Thu, 9 Jun 2016 14:30:37 +0200 -Subject: [PATCH 02/29] Fix command line parsing - -The gettext translation domain should be passed as .arg, not .descrip, -otherwise popt won't process any of the command line options (it stops -looping over the struct poptOption array when an entry has unset -longName, shortName and arg). - -Signed-off-by: Julien Cristau ---- - src/client.c | 2 +- - src/efikeygen.c | 2 +- - src/efisiglist.c | 2 +- - src/pesigcheck.c | 2 +- - 4 files changed, 4 insertions(+), 4 deletions(-) - -diff --git a/src/client.c b/src/client.c -index 028419f..575c873 100644 ---- a/src/client.c -+++ b/src/client.c -@@ -555,7 +555,7 @@ main(int argc, char *argv[]) - - struct poptOption options[] = { - {.argInfo = POPT_ARG_INTL_DOMAIN, -- .descrip = "pesign" }, -+ .arg = "pesign" }, - {.longName = "token", - .shortName = 't', - .argInfo = POPT_ARG_STRING|POPT_ARGFLAG_SHOW_DEFAULT, -diff --git a/src/efikeygen.c b/src/efikeygen.c -index 6278849..8a515a5 100644 ---- a/src/efikeygen.c -+++ b/src/efikeygen.c -@@ -486,7 +486,7 @@ int main(int argc, char *argv[]) - poptContext optCon; - struct poptOption options[] = { - {.argInfo = POPT_ARG_INTL_DOMAIN, -- .descrip = "pesign" }, -+ .arg = "pesign" }, - /* global nss-ish things */ - {.longName = "dbdir", - .shortName = 'd', -diff --git a/src/efisiglist.c b/src/efisiglist.c -index cd3f1ae..40d6a93 100644 ---- a/src/efisiglist.c -+++ b/src/efisiglist.c -@@ -126,7 +126,7 @@ main(int argc, char *argv[]) - - struct poptOption options[] = { - {.argInfo = POPT_ARG_INTL_DOMAIN, -- .descrip = "pesign" }, -+ .arg = "pesign" }, - {.longName = "infile", - .shortName = 'i', - .argInfo = POPT_ARG_STRING, -diff --git a/src/pesigcheck.c b/src/pesigcheck.c -index 1328fe9..0d49c1a 100644 ---- a/src/pesigcheck.c -+++ b/src/pesigcheck.c -@@ -214,7 +214,7 @@ main(int argc, char *argv[]) - poptContext optCon; - struct poptOption options[] = { - {.argInfo = POPT_ARG_INTL_DOMAIN, -- .descrip = "pesign" }, -+ .arg = "pesign" }, - {.longName = "dbfile", - .shortName = 'D', - .argInfo = POPT_ARG_CALLBACK|POPT_CBFLAG_POST, --- -2.13.4 - diff --git a/0031-pesigcheck-Fix-a-wrong-assignment.patch b/0002-pesigcheck-Fix-a-wrong-assignment.patch similarity index 100% rename from 0031-pesigcheck-Fix-a-wrong-assignment.patch rename to 0002-pesigcheck-Fix-a-wrong-assignment.patch diff --git a/0003-Make-0.112-client-and-server-work-with-the-113-proto.patch b/0003-Make-0.112-client-and-server-work-with-the-113-proto.patch new file mode 100644 index 0000000..e639675 --- /dev/null +++ b/0003-Make-0.112-client-and-server-work-with-the-113-proto.patch @@ -0,0 +1,317 @@ +From 84547e6b7173e4b10a1931fd25f329ea9a8f68b0 Mon Sep 17 00:00:00 2001 +From: Peter Jones +Date: Thu, 11 Jun 2020 16:23:14 -0400 +Subject: [PATCH] Make 0.112 client and server work with the 113 protocol and + vise versa + +This makes the version of the sign API that takes a file type optional, +and makes the client attempt to negotiate which version it's getting. +It also leaves the server able to still handle the version from before +the file type was added. + +Signed-off-by: Peter Jones +--- + src/client.c | 74 +++++++++++++++++++++++++++++++++++++--------------- + src/daemon.c | 63 +++++++++++++++++++++++++++++--------------- + src/daemon.h | 2 ++ + 3 files changed, 97 insertions(+), 42 deletions(-) + +diff --git a/src/client.c b/src/client.c +index aa373abd981..57bcc09cbe8 100644 +--- a/src/client.c ++++ b/src/client.c +@@ -11,6 +11,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -84,8 +85,8 @@ connect_to_server(void) + static int32_t + check_response(int sd, char **srvmsg); + +-static void +-check_cmd_version(int sd, uint32_t command, char *name, int32_t version) ++static int ++check_cmd_version(int sd, uint32_t command, char *name, int32_t version, bool do_exit) + { + struct msghdr msg; + struct iovec iov[1]; +@@ -104,7 +105,7 @@ check_cmd_version(int sd, uint32_t command, char *name, int32_t version) + ssize_t n; + n = sendmsg(sd, &msg, 0); + if (n < 0) { +- fprintf(stderr, "check-cmd-version: kill daemon failed: %m\n"); ++ fprintf(stderr, "check-cmd-version: sendmsg failed: %m\n"); + exit(1); + } + +@@ -120,11 +121,17 @@ check_cmd_version(int sd, uint32_t command, char *name, int32_t version) + + char *srvmsg = NULL; + int32_t rc = check_response(sd, &srvmsg); +- if (rc < 0) ++ ++ if (do_exit && rc < 0) + errx(1, "command \"%s\" not known by server", name); +- if (rc != version) ++ ++ if (do_exit && rc != version) + errx(1, "command \"%s\": client version %d, server version %d", + name, version, rc); ++ ++ if (rc < 0) ++ return rc; ++ return rc == version; + } + + static void +@@ -134,7 +141,7 @@ send_kill_daemon(int sd) + struct iovec iov; + pesignd_msghdr pm; + +- check_cmd_version(sd, CMD_KILL_DAEMON, "kill-daemon", 0); ++ check_cmd_version(sd, CMD_KILL_DAEMON, "kill-daemon", 0, true); + + pm.version = PESIGND_VERSION; + pm.command = CMD_KILL_DAEMON; +@@ -276,7 +283,7 @@ unlock_token(int sd, char *tokenname, char *pin) + + uint32_t size1 = pesignd_string_size(pin); + +- check_cmd_version(sd, CMD_UNLOCK_TOKEN, "unlock-token", 0); ++ check_cmd_version(sd, CMD_UNLOCK_TOKEN, "unlock-token", 0, true); + + pm.version = PESIGND_VERSION; + pm.command = CMD_UNLOCK_TOKEN; +@@ -353,7 +360,7 @@ is_token_unlocked(int sd, char *tokenname) + + uint32_t size0 = pesignd_string_size(tokenname); + +- check_cmd_version(sd, CMD_IS_TOKEN_UNLOCKED, "is-token-unlocked", 0); ++ check_cmd_version(sd, CMD_IS_TOKEN_UNLOCKED, "is-token-unlocked", 0, true); + + pm.version = PESIGND_VERSION; + pm.command = CMD_IS_TOKEN_UNLOCKED; +@@ -452,6 +459,9 @@ static void + sign(int sd, char *infile, char *outfile, char *tokenname, char *certname, + int attached, uint32_t format) + { ++ int rc; ++ bool add_file_type; ++ + int infd = open(infile, O_RDONLY); + if (infd < 0) { + fprintf(stderr, "pesign-client: could not open input file " +@@ -481,12 +491,28 @@ oom: + exit(1); + } + +- check_cmd_version(sd, attached ? CMD_SIGN_ATTACHED : CMD_SIGN_DETACHED, +- attached ? "sign-attached" : "sign-detached", 0); ++ rc = check_cmd_version(sd, ++ attached ? CMD_SIGN_ATTACHED_WITH_FILE_TYPE ++ : CMD_SIGN_DETACHED_WITH_FILE_TYPE, ++ attached ? "sign-attached" : "sign-detached", ++ 0, format == FORMAT_KERNEL_MODULE); ++ if (rc >= 0) { ++ add_file_type = true; ++ } else { ++ add_file_type = false; ++ check_cmd_version(sd, attached ? CMD_SIGN_ATTACHED ++ : CMD_SIGN_DETACHED, ++ attached ? "sign-attached" : "sign-detached", ++ 0, true); ++ } + ++ printf("add_file_type:%d\n", add_file_type); + pm->version = PESIGND_VERSION; +- pm->command = attached ? CMD_SIGN_ATTACHED : CMD_SIGN_DETACHED; +- pm->size = size0 + size1 + sizeof(format); ++ pm->command = attached ? (add_file_type ? CMD_SIGN_ATTACHED_WITH_FILE_TYPE ++ : CMD_SIGN_ATTACHED) ++ : (add_file_type ? CMD_SIGN_DETACHED_WITH_FILE_TYPE ++ : CMD_SIGN_DETACHED); ++ pm->size = size0 + size1 + (add_file_type ? sizeof(format) : 0); + iov[0].iov_base = pm; + iov[0].iov_len = sizeof (*pm); + +@@ -503,25 +529,31 @@ oom: + } + + char *buffer; +- buffer = malloc(size0 + size1); ++ buffer = malloc(pm->size); + if (!buffer) + goto oom; + +- iov[0].iov_base = &format; +- iov[0].iov_len = sizeof(format); ++ int pos = 0; ++ ++ if (add_file_type) { ++ iov[pos].iov_base = &format; ++ iov[pos].iov_len = sizeof(format); ++ pos++; ++ } + + pesignd_string *tn = (pesignd_string *)buffer; + pesignd_string_set(tn, tokenname); +- iov[1].iov_base = tn; +- iov[1].iov_len = size0; ++ iov[pos].iov_base = tn; ++ iov[pos].iov_len = size0; ++ pos++; + + pesignd_string *cn = pesignd_string_next(tn); + pesignd_string_set(cn, certname); +- iov[2].iov_base = cn; +- iov[2].iov_len = size1; ++ iov[pos].iov_base = cn; ++ iov[pos].iov_len = size1; + + msg.msg_iov = iov; +- msg.msg_iovlen = 3; ++ msg.msg_iovlen = add_file_type ? 3 : 2; + + n = sendmsg(sd, &msg, 0); + if (n < 0) { +@@ -535,7 +567,7 @@ oom: + send_fd(sd, outfd); + + char *srvmsg = NULL; +- int rc = check_response(sd, &srvmsg); ++ rc = check_response(sd, &srvmsg); + if (rc < 0) { + fprintf(stderr, "pesign-client: signing failed: \"%s\"\n", + srvmsg); +diff --git a/src/daemon.c b/src/daemon.c +index 9374d59be30..494beb9af72 100644 +--- a/src/daemon.c ++++ b/src/daemon.c +@@ -12,6 +12,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -561,7 +562,7 @@ out: + + static void + handle_signing(context *ctx, struct pollfd *pollfd, socklen_t size, +- int attached) ++ int attached, bool with_file_type) + { + struct msghdr msg; + struct iovec iov; +@@ -585,8 +586,12 @@ oom: + + n = recvmsg(pollfd->fd, &msg, MSG_WAITALL); + +- file_format = *((uint32_t *) buffer); +- n -= sizeof(uint32_t); ++ if (with_file_type) { ++ file_format = *((uint32_t *) buffer); ++ n -= sizeof(uint32_t); ++ } else { ++ file_format = FORMAT_PE_BINARY; ++ } + + pesignd_string *tn = (pesignd_string *)(buffer + sizeof(uint32_t)); + if (n < (long long)sizeof(tn->size)) { +@@ -666,34 +671,44 @@ finish: + teardown_digests(ctx->cms); + } + ++static inline void ++handle_sign_helper(context *ctx, struct pollfd *pollfd, socklen_t size, ++ int attached, bool with_file_type) ++{ ++ int rc = cms_context_alloc(&ctx->cms); ++ if (rc < 0) ++ return; ++ ++ steal_from_cms(ctx->backup_cms, ctx->cms); ++ ++ handle_signing(ctx, pollfd, size, attached, with_file_type); ++ ++ hide_stolen_goods_from_cms(ctx->cms, ctx->backup_cms); ++ cms_context_fini(ctx->cms); ++} ++ + static void + handle_sign_attached(context *ctx, struct pollfd *pollfd, socklen_t size) + { +- int rc = cms_context_alloc(&ctx->cms); +- if (rc < 0) +- return; ++ handle_sign_helper(ctx, pollfd, size, 1, false); ++} + +- steal_from_cms(ctx->backup_cms, ctx->cms); +- +- handle_signing(ctx, pollfd, size, 1); +- +- hide_stolen_goods_from_cms(ctx->cms, ctx->backup_cms); +- cms_context_fini(ctx->cms); ++static void ++handle_sign_attached_with_file_type(context *ctx, struct pollfd *pollfd, socklen_t size) ++{ ++ handle_sign_helper(ctx, pollfd, size, 1, true); + } + + static void + handle_sign_detached(context *ctx, struct pollfd *pollfd, socklen_t size) + { +- int rc = cms_context_alloc(&ctx->cms); +- if (rc < 0) +- return; ++ handle_sign_helper(ctx, pollfd, size, 0, false); ++} + +- steal_from_cms(ctx->backup_cms, ctx->cms); +- +- handle_signing(ctx, pollfd, size, 0); +- +- hide_stolen_goods_from_cms(ctx->cms, ctx->backup_cms); +- cms_context_fini(ctx->cms); ++static void ++handle_sign_detached_with_file_type(context *ctx, struct pollfd *pollfd, socklen_t size) ++{ ++ handle_sign_helper(ctx, pollfd, size, 0, true); + } + + static void +@@ -725,6 +740,12 @@ cmd_table_t cmd_table[] = { + { CMD_UNLOCK_TOKEN, handle_unlock_token, "unlock-token", 0 }, + { CMD_SIGN_ATTACHED, handle_sign_attached, "sign-attached", 0 }, + { CMD_SIGN_DETACHED, handle_sign_detached, "sign-detached", 0 }, ++ { CMD_SIGN_ATTACHED_WITH_FILE_TYPE, ++ handle_sign_attached_with_file_type, ++ "sign-attached-with-file-type", 0 }, ++ { CMD_SIGN_DETACHED_WITH_FILE_TYPE, ++ handle_sign_detached_with_file_type, ++ "sign-detached-with-file-type", 0 }, + { CMD_RESPONSE, NULL, "response", 0 }, + { CMD_IS_TOKEN_UNLOCKED, handle_is_token_unlocked, + "is-token-unlocked", 0 }, +diff --git a/src/daemon.h b/src/daemon.h +index dd430512f1a..834d62c72d0 100644 +--- a/src/daemon.h ++++ b/src/daemon.h +@@ -33,6 +33,8 @@ typedef enum { + CMD_RESPONSE, + CMD_IS_TOKEN_UNLOCKED, + CMD_GET_CMD_VERSION, ++ CMD_SIGN_ATTACHED_WITH_FILE_TYPE, ++ CMD_SIGN_DETACHED_WITH_FILE_TYPE, + CMD_LIST_END + } pesignd_cmd; + +-- +2.26.2 + diff --git a/0003-gcc-don-t-error-on-stuff-in-includes.patch b/0003-gcc-don-t-error-on-stuff-in-includes.patch deleted file mode 100644 index cf4e61d..0000000 --- a/0003-gcc-don-t-error-on-stuff-in-includes.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 6de291458cbab99bcc317e282c16e1523d6de9b8 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Wed, 10 Aug 2016 17:12:39 -0400 -Subject: [PATCH 03/29] gcc: don't error on stuff in includes. - -Signed-off-by: Peter Jones ---- - Make.defaults | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/Make.defaults b/Make.defaults -index c97b452..3511080 100644 ---- a/Make.defaults -+++ b/Make.defaults -@@ -19,7 +19,7 @@ PKG_CONFIG = $(CROSS_COMPILE)pkg-config - CC := $(if $(filter default,$(origin CC)),$(CROSS_COMPILE)gcc,$(CC)) - CCLD := $(if $(filter undefined,$(origin CCLD)),$(CC),$(CCLD)) - CFLAGS ?= -O0 -g3 -fvar-tracking -fvar-tracking-assignments \ -- -Wall -Werror -Wextra -+ -Wall -Werror -Wextra -Wno-error=cpp - AS := $(CROSS_COMPILE)as - AR := $(CROSS_COMPILE)gcc-ar - RANLIB := $(CROSS_COMPILE)gcc-ranlib --- -2.13.4 - diff --git a/0004-Fix-certficate-argument-name.patch b/0004-Fix-certficate-argument-name.patch deleted file mode 100644 index 08509ff..0000000 --- a/0004-Fix-certficate-argument-name.patch +++ /dev/null @@ -1,39 +0,0 @@ -From b20fc54c08e8afe1365e56cacade3ec39984da8d Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Tue, 18 Apr 2017 19:00:34 -0400 -Subject: [PATCH 04/29] Fix "certficate" argument name. - -This fixes our typoed argument name by making the incorrectly spelled -version be a popt alias, and fixing the real implementation to be -spelled right in pesign.c . - -Signed-off-by: Peter Jones ---- - src/pesign.c | 2 +- - src/pesign.popt | 1 + - 2 files changed, 2 insertions(+), 1 deletion(-) - -diff --git a/src/pesign.c b/src/pesign.c -index af374b6..279a17a 100644 ---- a/src/pesign.c -+++ b/src/pesign.c -@@ -438,7 +438,7 @@ main(int argc, char *argv[]) - .arg = &ctxp->outfile, - .descrip = "specify output file", - .argDescrip = "" }, -- {.longName = "certficate", -+ {.longName = "certificate", - .shortName = 'c', - .argInfo = POPT_ARG_STRING, - .arg = &certname, -diff --git a/src/pesign.popt b/src/pesign.popt -index 7b3385d..5a97748 100644 ---- a/src/pesign.popt -+++ b/src/pesign.popt -@@ -1,2 +1,3 @@ - pesign alias --cert --certificate -+pesign alias --certficate --certificate - pesign alias --daemon --daemonize --- -2.13.4 - diff --git a/0004-Rename-var-run-to-run.patch b/0004-Rename-var-run-to-run.patch new file mode 100644 index 0000000..593761b --- /dev/null +++ b/0004-Rename-var-run-to-run.patch @@ -0,0 +1,46 @@ +From f886b7088dfea224e28c03b097c85c9bc20f5441 Mon Sep 17 00:00:00 2001 +From: Peter Jones +Date: Fri, 12 Jun 2020 11:49:44 -0400 +Subject: [PATCH] Rename /var/run/ to /run/ + +Signed-off-by: Peter Jones +--- + src/macros.pesign | 12 ++++++------ + src/tmpfiles.conf | 2 +- + 2 files changed, 7 insertions(+), 7 deletions(-) + +diff --git a/src/macros.pesign b/src/macros.pesign +index 56f75cafbc4..5a6da1c6809 100644 +--- a/src/macros.pesign ++++ b/src/macros.pesign +@@ -45,14 +45,14 @@ + rm -rf ${sattrs} ${sattrs}.sig ${nss} \ + elif [ "$(id -un)" == "kojibuilder" -a \\\ + grep -q ID=fedora /etc/os-release -a \\\ +- ! -S /var/run/pesign/socket ]; then \ ++ ! -S /run/pesign/socket ]; then \ + echo "No socket even though this is kojibuilder" 1>&2 \ +- ls -ld /var/run/pesign 1>&2 \ +- ls -l /var/run/pesign/socket 1>&2 \ +- getfacl /var/run/pesign 1>&2 \ +- getfacl /var/run/pesign/socket 1>&2 \ ++ ls -ld /run/pesign 1>&2 \ ++ ls -l /run/pesign/socket 1>&2 \ ++ getfacl /run/pesign 1>&2 \ ++ getfacl /run/pesign/socket 1>&2 \ + exit 1 \ +- elif [ -S /var/run/pesign/socket ]; then \ ++ elif [ -S /run/pesign/socket ]; then \ + %{_pesign_client} -t %{__pesign_client_token} \\\ + -c %{__pesign_client_cert} \\\ + %{-i} %{-o} %{-e} %{-s} %{-C} \ +diff --git a/src/tmpfiles.conf b/src/tmpfiles.conf +index c1cf35597d8..3375ad52a44 100644 +--- a/src/tmpfiles.conf ++++ b/src/tmpfiles.conf +@@ -1 +1 @@ +-D /var/run/pesign 0770 pesign pesign - ++D /run/pesign 0770 pesign pesign - +-- +2.26.2 + diff --git a/0005-Apparently-opensc-got-updated-and-the-token-name-cha.patch b/0005-Apparently-opensc-got-updated-and-the-token-name-cha.patch new file mode 100644 index 0000000..2b47880 --- /dev/null +++ b/0005-Apparently-opensc-got-updated-and-the-token-name-cha.patch @@ -0,0 +1,30 @@ +From 56eaa15e986d808c670381ca375216eb3abd1588 Mon Sep 17 00:00:00 2001 +From: Jeremy Cline +Date: Tue, 18 Feb 2020 16:37:53 -0500 +Subject: [PATCH] Apparently opensc got updated and the token name changed + +All the kernel builds started failing yesterday because the signing +token could not be found. Update the token name in the macro shipped by +pesign. + +Signed-off-by: Peter Jones +--- + src/macros.pesign | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/macros.pesign b/src/macros.pesign +index 7c5cba170e9..56f75cafbc4 100644 +--- a/src/macros.pesign ++++ b/src/macros.pesign +@@ -9,7 +9,7 @@ + %__pesign_token %{nil}%{?pe_signing_token:-t "%{pe_signing_token}"} + %__pesign_cert %{!?pe_signing_cert:"Red Hat Test Certificate"}%{?pe_signing_cert:"%{pe_signing_cert}"} + +-%__pesign_client_token %{!?pe_signing_token:"Fedora Signer (OpenSC Card)"}%{?pe_signing_token:"%{pe_signing_token}"} ++%__pesign_client_token %{!?pe_signing_token:"OpenSC Card (Fedora Signer)"}%{?pe_signing_token:"%{pe_signing_token}"} + %__pesign_client_cert %{!?pe_signing_cert:"/CN=Fedora Secure Boot Signer"}%{?pe_signing_cert:"%{pe_signing_cert}"} + + %_pesign /usr/bin/pesign +-- +2.26.2 + diff --git a/0005-Fix-description-of-ascii-armor-option-in-manpage.patch b/0005-Fix-description-of-ascii-armor-option-in-manpage.patch deleted file mode 100644 index 6a5b02d..0000000 --- a/0005-Fix-description-of-ascii-armor-option-in-manpage.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 7bc8e8b04c74be5c4e0ebf211affc37cf9f5db37 Mon Sep 17 00:00:00 2001 -From: Julien Cristau -Date: Mon, 27 Jun 2016 15:38:38 +0200 -Subject: [PATCH 05/29] Fix description of --ascii-armor option in manpage - -The --ascii option does not exist. ---- - src/pesign.1 | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/pesign.1 b/src/pesign.1 -index 47d1aec..29ae060 100644 ---- a/src/pesign.1 -+++ b/src/pesign.1 -@@ -81,7 +81,7 @@ Export the public key specified by \-\-certificate to \fIoutkey\fR - Export the certificate specified by \-\-certificate to \fIoutcert\fR - - .TP --\fB-\-ascii\fR -+\fB-\-ascii\-armor\fR - Use ascii armoring on exported certificates. - - .TP --- -2.13.4 - diff --git a/0006-Make-ascii-work-since-we-documented-it.patch b/0006-Make-ascii-work-since-we-documented-it.patch deleted file mode 100644 index d0165f9..0000000 --- a/0006-Make-ascii-work-since-we-documented-it.patch +++ /dev/null @@ -1,22 +0,0 @@ -From 9f411f4e797e983d2e8cb51dc5b9ab8db250c2e3 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Tue, 18 Apr 2017 19:05:40 -0400 -Subject: [PATCH 06/29] Make --ascii work, since we documented it. - -Signed-off-by: Peter Jones ---- - src/pesign.popt | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/src/pesign.popt b/src/pesign.popt -index 5a97748..5ae0c5c 100644 ---- a/src/pesign.popt -+++ b/src/pesign.popt -@@ -1,3 +1,4 @@ - pesign alias --cert --certificate - pesign alias --certficate --certificate - pesign alias --daemon --daemonize -+pesign alias --ascii --ascii-armor --- -2.13.4 - diff --git a/0006-client-try-run-and-var-run-for-the-socket-path.patch b/0006-client-try-run-and-var-run-for-the-socket-path.patch new file mode 100644 index 0000000..337faab --- /dev/null +++ b/0006-client-try-run-and-var-run-for-the-socket-path.patch @@ -0,0 +1,86 @@ +From c662ad097eaa0d8c3691a22254f5d0e9622b26b7 Mon Sep 17 00:00:00 2001 +From: Peter Jones +Date: Mon, 6 Jul 2020 16:13:09 -0400 +Subject: [PATCH 6/7] client: try /run and /var/run for the socket path. + +Signed-off-by: Peter Jones +--- + src/client.c | 40 +++++++++++++++++++++++++++++----------- + 1 file changed, 29 insertions(+), 11 deletions(-) + +diff --git a/src/client.c b/src/client.c +index 2119ef33bf8..a38383415d5 100644 +--- a/src/client.c ++++ b/src/client.c +@@ -49,24 +49,24 @@ print_flag_name(FILE *f, int flag) + } + + static int +-connect_to_server(void) ++connect_to_server_helper(const char * const sockpath) + { +- int rc = access(SOCKPATH, R_OK); ++ int rc = access(sockpath, R_OK); + if (rc != 0) { +- fprintf(stderr, "pesign-client: could not connect to server: " +- "%m\n"); +- exit(1); ++ warn("could not access socket \"%s\"", sockpath); ++ return rc; + } + + struct sockaddr_un addr_un = { + .sun_family = AF_UNIX, +- .sun_path = SOCKPATH, + }; ++ strncpy(addr_un.sun_path, sockpath, sizeof(addr_un.sun_path)); ++ addr_un.sun_path[sizeof(addr_un.sun_path)-1] = '\0'; + + int sd = socket(AF_UNIX, SOCK_STREAM, 0); + if (sd < 0) { +- fprintf(stderr, "pesign-client: could not open socket: %m\n"); +- exit(1); ++ warn("could not open socket \"%s\"", sockpath); ++ return sd; + } + + socklen_t len = strlen(addr_un.sun_path) + +@@ -74,14 +74,32 @@ connect_to_server(void) + + rc = connect(sd, (struct sockaddr *)&addr_un, len); + if (rc < 0) { +- fprintf(stderr, "pesign-client: could not connect to daemon: " +- "%m\n"); +- exit(1); ++ warn("could not connect to daemon"); ++ return sd; + } + + return sd; + } + ++static int ++connect_to_server(void) ++{ ++ int rc, i; ++ const char * const sockets[] = { ++ "/run/pesign/socket", ++ "/var/run/pesign/socket", ++ NULL ++ }; ++ ++ for (i = 0; sockets[i] != NULL; i++) { ++ rc = connect_to_server_helper(sockets[i]); ++ if (rc >= 0) ++ return rc; ++ } ++ ++ exit(1); ++} ++ + static int32_t + check_response(int sd, char **srvmsg); + +-- +2.26.2 + diff --git a/0007-Switch-pesign-client-to-also-accept-token-cert-macro.patch b/0007-Switch-pesign-client-to-also-accept-token-cert-macro.patch deleted file mode 100644 index faa78ec..0000000 --- a/0007-Switch-pesign-client-to-also-accept-token-cert-macro.patch +++ /dev/null @@ -1,32 +0,0 @@ -From d618de733865eab359890b4e677c368a133dad99 Mon Sep 17 00:00:00 2001 -From: Pat Riehecky -Date: Mon, 7 Nov 2016 11:37:08 -0600 -Subject: [PATCH 07/29] Switch pesign client to also accept token/cert macros - rather than use hard coded values - ---- - src/macros.pesign | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/src/macros.pesign b/src/macros.pesign -index 18e5b5e..69280e9 100644 ---- a/src/macros.pesign -+++ b/src/macros.pesign -@@ -41,11 +41,11 @@ - --certdir ${nss} -c signer %{-o} \ - rm -rf ${sattrs} ${sattrs}.sig ${nss} \ - elif [ -S /var/run/pesign/socket ]; then \ -- %{_pesign_client} -t "OpenSC Card (Fedora Signer)" \\\ -- -c "/CN=Fedora Secure Boot Signer" \\\ -+ %{_pesign_client} -t %{__pesign_token} \\\ -+ -c %{__pesign_cert} \\\ - %{-i} %{-o} %{-e} %{-s} %{-C} \ - else \ -- %{_pesign} %{__pesign_token} -c %{__pesign_cert} \\\ -+ %{_pesign} -t %{__pesign_token} -c %{__pesign_cert} \\\ - --certdir ${_pesign_nssdir} \\\ - %{-i} %{-o} %{-e} %{-s} %{-C} \ - fi \ --- -2.13.4 - diff --git a/0007-client-remove-an-extra-debug-print.patch b/0007-client-remove-an-extra-debug-print.patch new file mode 100644 index 0000000..b094ea5 --- /dev/null +++ b/0007-client-remove-an-extra-debug-print.patch @@ -0,0 +1,25 @@ +From ea81cec14d31cd0b0dbde5b42414bfae9daec9b8 Mon Sep 17 00:00:00 2001 +From: Peter Jones +Date: Tue, 14 Jul 2020 16:44:09 -0400 +Subject: [PATCH 07/11] client: remove an extra debug print + +Signed-off-by: Peter Jones +--- + src/client.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/src/client.c b/src/client.c +index 0082be1f597..c9966295e5f 100644 +--- a/src/client.c ++++ b/src/client.c +@@ -536,7 +536,6 @@ oom: + 0, true); + } + +- printf("add_file_type:%d\n", add_file_type); + pm->version = PESIGND_VERSION; + pm->command = attached ? (add_file_type ? CMD_SIGN_ATTACHED_WITH_FILE_TYPE + : CMD_SIGN_ATTACHED) +-- +2.26.2 + diff --git a/0008-Move-most-of-macros.pesign-to-pesign-rpmbuild-helper.patch b/0008-Move-most-of-macros.pesign-to-pesign-rpmbuild-helper.patch new file mode 100644 index 0000000..0a96bdb --- /dev/null +++ b/0008-Move-most-of-macros.pesign-to-pesign-rpmbuild-helper.patch @@ -0,0 +1,383 @@ +From e05840efa8dc9d0a9ff3104b9fa6e5736e0ec549 Mon Sep 17 00:00:00 2001 +From: Peter Jones +Date: Mon, 6 Jul 2020 13:54:35 -0400 +Subject: [PATCH 08/11] Move most of macros.pesign to pesign-rpmbuild-helper + +Signed-off-by: Peter Jones +--- + Make.defaults | 1 + + src/Makefile | 8 +- + src/macros.pesign | 76 ++++-------- + src/pesign-rpmbuild-helper.in | 222 ++++++++++++++++++++++++++++++++++ + 4 files changed, 253 insertions(+), 54 deletions(-) + create mode 100644 src/pesign-rpmbuild-helper.in + +diff --git a/Make.defaults b/Make.defaults +index 0bacafe0d01..d4cd626c11e 100644 +--- a/Make.defaults ++++ b/Make.defaults +@@ -16,6 +16,7 @@ INSTALLROOT = $(DESTDIR) + + INSTALL ?= install + CROSS_COMPILE ?= ++EFI_ARCHES ?= aa64 ia32 x64 + + PKG_CONFIG = $(CROSS_COMPILE)pkg-config + CC := $(if $(filter default,$(origin CC)),$(CROSS_COMPILE)gcc,$(CC)) +diff --git a/src/Makefile b/src/Makefile +index 74327ba13f3..a7ca89159c6 100644 +--- a/src/Makefile ++++ b/src/Makefile +@@ -5,7 +5,7 @@ include $(TOPDIR)/Make.version + include $(TOPDIR)/Make.rules + include $(TOPDIR)/Make.defaults + +-BINTARGETS=authvar client efikeygen efisiglist pesigcheck pesign ++BINTARGETS=authvar client efikeygen efisiglist pesigcheck pesign pesign-rpmbuild-helper + SVCTARGETS=pesign.sysvinit pesign.service + TARGETS=$(BINTARGETS) $(SVCTARGETS) + +@@ -49,6 +49,11 @@ pesign : $(call objects-of,$(PESIGN_SOURCES) $(COMMON_SOURCES) $(COMMON_PE_SOURC + pesign : LDLIBS+=$(TOPDIR)/libdpe/libdpe.a + pesign : PKGS=efivar nss nspr popt + ++pesign-rpmbuild-helper: pesign-rpmbuild-helper.in ++ sed \ ++ -e "s/@@EFI_ARCHES@@/$(EFI_ARCHES)/g" \ ++ $^ > $@ ++ + deps : PKGS=efivar nss nspr popt uuid + deps : $(ALL_SOURCES) + $(MAKE) -f $(TOPDIR)/Make.deps \ +@@ -94,6 +99,7 @@ install : + $(INSTALL) -m 644 macros.pesign $(INSTALLROOT)/etc/rpm/ + $(INSTALL) -d -m 755 $(INSTALLROOT)$(libexecdir)/pesign/ + $(INSTALL) -m 750 pesign-authorize $(INSTALLROOT)$(libexecdir)/pesign/ ++ $(INSTALL) -m 755 pesign-rpmbuild-helper $(INSTALLROOT)$(libexecdir)/pesign/ + $(INSTALL) -d -m 700 $(INSTALLROOT)/etc/pesign + $(INSTALL) -m 600 pesign-users $(INSTALLROOT)/etc/pesign/users + $(INSTALL) -m 600 pesign-groups $(INSTALLROOT)/etc/pesign/groups +diff --git a/src/macros.pesign b/src/macros.pesign +index 5a6da1c6809..cb066b35f4a 100644 +--- a/src/macros.pesign ++++ b/src/macros.pesign +@@ -6,11 +6,11 @@ + # %pesign -s -i shim.orig -o shim.efi + # And magically get the right thing. + +-%__pesign_token %{nil}%{?pe_signing_token:-t "%{pe_signing_token}"} ++%__pesign_token %{nil}%{?pe_signing_token:--token "%{pe_signing_token}"} + %__pesign_cert %{!?pe_signing_cert:"Red Hat Test Certificate"}%{?pe_signing_cert:"%{pe_signing_cert}"} + + %__pesign_client_token %{!?pe_signing_token:"OpenSC Card (Fedora Signer)"}%{?pe_signing_token:"%{pe_signing_token}"} + %__pesign_client_cert %{!?pe_signing_cert:"/CN=Fedora Secure Boot Signer"}%{?pe_signing_cert:"%{pe_signing_cert}"} + + %_pesign /usr/bin/pesign + %_pesign_client /usr/bin/pesign-client +@@ -24,54 +24,24 @@ + # -a # rhel only + # -s # perform signing + %pesign(i:o:C:e:c:n:a:s) \ +- _pesign_nssdir=/etc/pki/pesign \ +- if [ %{__pesign_cert} = "Red Hat Test Certificate" ]; then \ +- _pesign_nssdir=/etc/pki/pesign-rh-test \ +- fi \ +- if [ -x %{_pesign} ] && \\\ +- [ "%{_target_cpu}" == "x86_64" -o \\\ +- "%{_target_cpu}" == "aarch64" ]; then \ +- if [ "0%{?rhel}" -ge "7" -a -f /usr/bin/rpm-sign ]; then \ +- nss=$(mktemp -p $PWD -d) \ +- echo > ${nss}/pwfile \ +- certutil -N -d ${nss} -f ${nss}/pwfile \ +- certutil -A -n "ca" -t "CT,C," -i %{-a*} -d ${nss} \ +- certutil -A -n "signer" -t ",c," -i %{-c*} -d ${nss} \ +- sattrs=$(mktemp -p $PWD --suffix=.der) \ +- %{_pesign} %{-i} -E ${sattrs} --certdir ${nss} --force \ +- rpm-sign --key "%{-n*}" --rsadgstsign ${sattrs} \ +- %{_pesign} -R ${sattrs}.sig -I ${sattrs} %{-i} \\\ +- --certdir ${nss} -c signer %{-o} \ +- rm -rf ${sattrs} ${sattrs}.sig ${nss} \ +- elif [ "$(id -un)" == "kojibuilder" -a \\\ +- grep -q ID=fedora /etc/os-release -a \\\ +- ! -S /run/pesign/socket ]; then \ +- echo "No socket even though this is kojibuilder" 1>&2 \ +- ls -ld /run/pesign 1>&2 \ +- ls -l /run/pesign/socket 1>&2 \ +- getfacl /run/pesign 1>&2 \ +- getfacl /run/pesign/socket 1>&2 \ +- exit 1 \ +- elif [ -S /run/pesign/socket ]; then \ +- %{_pesign_client} -t %{__pesign_client_token} \\\ +- -c %{__pesign_client_cert} \\\ +- %{-i} %{-o} %{-e} %{-s} %{-C} \ +- else \ +- %{_pesign} %{__pesign_token} -c %{__pesign_cert} \\\ +- --certdir ${_pesign_nssdir} \\\ +- %{-i} %{-o} %{-e} %{-s} %{-C} \ +- fi \ +- else \ +- if [ -n "%{-i*}" -a -n "%{-o*}" ]; then \ +- mv %{-i*} %{-o*} \ +- elif [ -n "%{-i*}" -a -n "%{-e*}" ]; then \ +- touch %{-e*} \ +- fi \ +- fi \ +- if [ ! -s %{-o} ]; then \ +- if [ -e "%{-o*}" ]; then \ +- rm -f %{-o*} \ +- fi \ +- exit 1 \ +- fi ; +- ++ %{_libexecdir}/pesign/pesign-rpmbuild-helper \\\ ++ "%{_target_cpu}" \\\ ++ "%{_pesign}" \\\ ++ "%{_pesign_client}" \\\ ++ %{?__pesign_client_token:--client-token %{__pesign_client_token}} \\\ ++ %{?__pesign_client_cert:--client-cert %{__pesign_client_cert}} \\\ ++ %{?__pesign_token:%{__pesign_token}} \\\ ++ %{?__pesign_cert:--cert %{__pesign_cert}} \\\ ++ %{?_buildhost:--hostname "%{_buildhost}"} \\\ ++ %{?vendor:--vendor "%{vendor}"} \\\ ++ %{?_rhel:--rhelver "%{_rhel}"} \\\ ++ %{?-n:--rhelcert "%{-n*}"}%{?!-n:--rhelcert "%{__pesign_cert}"} \\\ ++ %{?-a:--rhelcafile "%{-a*}"} \\\ ++ %{?-c:--rhelcertfile "%{-c*}"} \\\ ++ %{?-C:--certout "%{-C*}"} \\\ ++ %{?-e:--sattrout "%{-e*}"} \\\ ++ %{?-i:--in "%{-i*}"} \\\ ++ %{?-o:--out "%{-o*}"} \\\ ++ %{?-s:--sign} \\\ ++ ; \ ++%{nil} +diff --git a/src/pesign-rpmbuild-helper.in b/src/pesign-rpmbuild-helper.in +new file mode 100644 +index 00000000000..c5287c27e0c +--- /dev/null ++++ b/src/pesign-rpmbuild-helper.in +@@ -0,0 +1,222 @@ ++#!/bin/bash ++# shellcheck shell=bash ++ ++set -eu ++set -x ++ ++usage() { ++ local status="${1}" && shift ++ local out ++ if [[ "${status}" -eq 0 ]] ; then ++ out=/dev/stdout ++ else ++ out=/dev/stderr ++ fi ++ ++ if [[ $# -gt 0 ]] ; then ++ echo "${0}: error: $*" >>"${out}" ++ fi ++ echo "usage: ${0} TARGET_CPU PESIGN_BINARY PESIGN_CLIENT_BINARY [OPTIONS]" >>"${out}" ++ exit "${status}" ++} ++ ++is_efi_arch() { ++ local arch="${1}" ++ local arches=(@@EFI_ARCHES@@) ++ local x ++ for x in "${arches[@]}" ; do ++ if [[ "${arch}" = "${x}" ]] ; then ++ return 0 ++ fi ++ done ++ return 1 ++} ++ ++error_on_empty() { ++ local f="${1}" ++ if [[ ! -s "${f}" ]] ; then ++ if [[ -e "${f}" ]] ; then ++ rm -f "${f}" ++ fi ++ echo "${0}: error: empty result file \"${f}\"">>/dev/stderr ++ exit 1 ++ fi ++} ++ ++main() { ++ if [[ $# -lt 3 ]] ; then ++ usage 1 not enough arguments ++ fi ++ local target_cpu="${1}" && shift ++ local bin="${1}" && shift ++ local client="${1}" && shift ++ ++ local rhelcafile="" || : ++ local rhelcertfile="" || : ++ ++ local certout=() || : ++ local sattrout=() || : ++ local input=() || : ++ local output=() || : ++ local client_token=() || : ++ local client_cert=() || : ++ local token=() || : ++ local cert=() || : ++ local rhelcert=() || : ++ local rhelver=0 || : ++ local sign="" || : ++ local arch="" || : ++ local vendor="" || : ++ local HOSTNAME="" || : ++ ++ while [[ $# -ge 2 ]] ; do ++ case " ${1} " in ++ " --rhelcafile ") ++ rhelcafile="${2}" ++ ;; ++ " --rhelcertfile ") ++ rhelcertfile="${2}" ++ ;; ++ " --hostname ") ++ HOSTNAME="${2}" ++ ;; ++ " --certout ") ++ certout[0]=-C ++ certout[1]="${2}" ++ ;; ++ " --sattrout ") ++ sattrout[0]=-e ++ sattrout[1]="${2}" ++ ;; ++ " --client-token ") ++ client_token[0]=-t ++ client_token[1]="${2}" ++ ;; ++ " --client-cert ") ++ client_cert[0]=-c ++ client_cert[1]="${2}" ++ ;; ++ " --token ") ++ token[0]=-t ++ token[1]="${2}" ++ ;; ++ " --cert ") ++ cert[0]=-c ++ cert[1]="${2}" ++ ;; ++ " --rhelcert ") ++ rhelcert[0]=-c ++ rhelcert[1]="${2}" ++ ;; ++ " --in ") ++ input[0]=-i ++ input[1]="${2}" ++ ;; ++ " --out ") ++ output[0]=-o ++ output[1]="${2}" ++ ;; ++ " --rhelver ") ++ rhelver="${2}" ++ ;; ++ " --vendor ") ++ vendor="${2}" ++ ;; ++ *) ++ break ++ ;; ++ esac ++ shift ++ shift ++ done ++ if [[ $# -ge 1 ]] && [[ "${1}" = --sign ]] ; then ++ sign=-s ++ shift ++ fi ++ ++ if [[ -z "${target_cpu}" ]] ; then ++ target_cpu="$(uname -m)" ++ fi ++ ++ target_cpu="${target_cpu/i?86/ia32}" ++ target_cpu="${target_cpu/x86_64/x64}" ++ target_cpu="${target_cpu/aarch64/aa64}" ++ target_cpu="${target_cpu/arm*/arm/}" ++ ++ local nssdir=/etc/pki/pesign ++ if [[ "${#cert[@]}" -eq 2 ]] && ++ [[ "${cert[1]}" == "Red Hat Test Certificate" ]] ; then ++ nssdir=/etc/pki/pesign-rh-test ++ fi ++ ++ # is_efi_arch is ultimately returning "is pesign configured to sign these ++ # using the rpm macro", so if it isn't, we're just copying the input to ++ # the output ++ if [[ -x "${bin}" ]] && ! is_efi_arch "${target_cpu}" ; then ++ if [[ -n "${input[*]}" ]] && [[ -n "${output[*]}" ]] ; then ++ cp -v "${input[1]}" "${output[1]}" ++ elif [[ -n "${input[*]}" ]] && [[ -n "${sattrout[*]}" ]] ; then ++ touch "${sattrout[1]}" ++ fi ++ ++ # if there's a 0-sized output file, delete it and error out ++ error_on_empty "${output[1]}" ++ return 0 ++ fi ++ ++ USERNAME="${USERNAME:-$(id -un)}" ++ ++ local socket="" || : ++ if grep -q ID=fedora /etc/os-release \ ++ && [[ "${rhelver}" -lt 7 ]] \ ++ && [[ "${USERNAME}" = "mockbuild" ]] \ ++ && [[ "${vendor}" = "Fedora Project" ]] \ ++ && [[ "${HOSTNAME}" =~ bkernel.* ]] ++ then ++ if [[ -S /run/pesign/socket ]] ; then ++ socket=/run/pesign/socket ++ elif [[ -S /var/run/pesign/socket ]]; then ++ socket=/var/run/pesign/socket ++ else ++ echo "Warning: no pesign socket even though user is ${USERNAME}" 1>&2 ++ echo "Warning: if this is a non-scratch koji build, this is wrong" 1>&2 ++ ls -ld /run/pesign /var/run/pesign 1>&2 ||: ++ ls -l /run/pesign/socket /var/run/pesign/socket 1>&2 ||: ++ getfacl /run/pesign /run/pesign/socket /var/run/pesign /var/run/pesign/socket 1>&2 ||: ++ getfacl -n /run/pesign /run/pesign/socket /var/run/pesign /var/run/pesign/socket 1>&2 ||: ++ fi ++ fi ++ ++ if [[ "${rhelver}" -ge 7 ]] ; then ++ nssdir="$(mktemp -p "${PWD}" -d)" ++ echo > "${nssdir}/pwfile" ++ certutil -N -d "${nssdir}" -f "${nssdir}/pwfile" ++ certutil -A -n "ca" -t "CTu,CTu,CTu" -i "${rhelcafile}" -d "${nssdir}" ++ certutil -A -n "signer" -t "CTu,CTu,CTu" -i "${rhelcertfile}" -d "${nssdir}" ++ sattrs="$(mktemp -p "${PWD}" --suffix=.der)" ++ "${bin}" -E "${sattrs}" --certdir "${nssdir}" \ ++ "${input[@]}" --force ++ rpm-sign --key "${rhelcert[1]}" --rsadgstsign "${sattrs}" ++ "${bin}" -R "${sattrs}.sig" -I "${sattrs}" \ ++ --certdir "${nssdir}" -c signer \ ++ "${input[@]}" "${output[@]}" ++ rm -rf "${sattrs}" "${sattrs}.sig" "${nssdir}" ++ elif [[ -n "${socket}" ]] ; then ++ "${client}" "${client_token[@]}" "${client_cert[@]}" \ ++ "${sattrout[@]}" "${certout[@]}" \ ++ ${sign} "${input[@]}" "${output[@]}" ++ else ++ "${bin}" --certdir "${nssdir}" "${token[@]}" \ ++ "${cert[@]}" ${sign} "${sattrout[@]}" \ ++ "${certout[@]}" "${input[@]}" "${output[@]}" ++ fi ++ ++ # if there's a 0-sized output file, delete it and error out ++ if [[ "${#output[@]}" -eq 2 ]] ; then ++ error_on_empty "${output[1]}" ++ fi ++} ++ ++main "${@}" ++ ++# vim:filetype=sh:fenc=utf-8:tw=78:sts=4:sw=4 +-- +2.26.2 + diff --git a/0008-pesigcheck-Verify-with-the-cert-as-an-object-signer.patch b/0008-pesigcheck-Verify-with-the-cert-as-an-object-signer.patch deleted file mode 100644 index 2226498..0000000 --- a/0008-pesigcheck-Verify-with-the-cert-as-an-object-signer.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 2cd211bcc612ad8cb99c778461ca02a9f3e5e44b Mon Sep 17 00:00:00 2001 -From: David Michael -Date: Thu, 16 Feb 2017 15:08:30 -0800 -Subject: [PATCH 08/29] pesigcheck: Verify with the cert as an object signer - ---- - src/certdb.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/certdb.c b/src/certdb.c -index 2a08042..b7c99bb 100644 ---- a/src/certdb.c -+++ b/src/certdb.c -@@ -339,7 +339,7 @@ check_cert(pesigcheck_context *ctx, SECItem *sig, efi_guid_t *sigtype, - } - /* Verify the signature */ - result = SEC_PKCS7VerifyDetachedSignatureAtTime(cinfo, -- certUsageSSLServer, -+ certUsageObjectSigner, - digest, HASH_AlgSHA256, - PR_FALSE, atTime); - if (!result) { --- -2.13.4 - diff --git a/0009-pesigcheck-make-certfile-actually-work.patch b/0009-pesigcheck-make-certfile-actually-work.patch deleted file mode 100644 index 8b77417..0000000 --- a/0009-pesigcheck-make-certfile-actually-work.patch +++ /dev/null @@ -1,47 +0,0 @@ -From e0238e2363f9668aee07b2e44a8f358e694551c0 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Mon, 24 Apr 2017 15:18:10 -0400 -Subject: [PATCH 09/29] pesigcheck: make --certfile actually work - -Signed-off-by: Peter Jones ---- - src/pesigcheck.c | 9 +++++++-- - 1 file changed, 7 insertions(+), 2 deletions(-) - -diff --git a/src/pesigcheck.c b/src/pesigcheck.c -index 0d49c1a..d7be542 100644 ---- a/src/pesigcheck.c -+++ b/src/pesigcheck.c -@@ -130,7 +130,7 @@ check_signature(pesigcheck_context *ctx) - cert_iter iter; - - generate_digest(ctx->cms_ctx, ctx->inpe, 1); -- -+ - if (check_db_hash(DBX, ctx) == FOUND) - return -1; - -@@ -225,6 +225,11 @@ main(int argc, char *argv[]) - .argInfo = POPT_ARG_CALLBACK|POPT_CBFLAG_POST, - .arg = (void *)callback, - .descrip = (void *)ctxp }, -+ {.longName = "certfile", -+ .shortName = 'c', -+ .argInfo = POPT_ARG_CALLBACK|POPT_CBFLAG_POST, -+ .arg = (void *)callback, -+ .descrip = (void *)ctxp }, - {.longName = "in", - .shortName = 'i', - .argInfo = POPT_ARG_STRING, -@@ -258,7 +263,7 @@ main(int argc, char *argv[]) - .shortName = 'c', - .argInfo = POPT_ARG_STRING, - .arg = &certfile, -- .descrip = "the certificate (in DER form) for verification ", -+ .descrip = "import certfile (in DER encoding) for allowed certificate", - .argDescrip = "" }, - POPT_AUTOALIAS - POPT_AUTOHELP --- -2.13.4 - diff --git a/0009-pesign-authorize-shellcheck.patch b/0009-pesign-authorize-shellcheck.patch new file mode 100644 index 0000000..3597f5f --- /dev/null +++ b/0009-pesign-authorize-shellcheck.patch @@ -0,0 +1,60 @@ +From 3107894285164a3d25ca215a76593ebb6d4bc84c Mon Sep 17 00:00:00 2001 +From: Peter Jones +Date: Tue, 14 Jul 2020 15:07:32 -0400 +Subject: [PATCH 09/11] pesign-authorize: shellcheck + +Signed-off-by: Peter Jones +--- + src/pesign-authorize | 16 ++++++++-------- + 1 file changed, 8 insertions(+), 8 deletions(-) + +diff --git a/src/pesign-authorize b/src/pesign-authorize +index a496f601ab4..55cd5c4e55b 100755 +--- a/src/pesign-authorize ++++ b/src/pesign-authorize +@@ -12,21 +12,21 @@ set -u + # License: GPLv2 + declare -a fileusers=() + declare -a dirusers=() +-for user in $(cat /etc/pesign/users); do ++while read -r user ; do + dirusers[${#dirusers[@]}]=-m + dirusers[${#dirusers[@]}]="u:$user:rwx" + fileusers[${#fileusers[@]}]=-m + fileusers[${#fileusers[@]}]="u:$user:rw" +-done ++done +Date: Tue, 14 Jul 2020 15:08:15 -0400 +Subject: [PATCH 10/11] pesign-authorize: don't setfacl /etc/pki/pesign-foo/ + +Signed-off-by: Peter Jones +--- + src/pesign-authorize | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/pesign-authorize b/src/pesign-authorize +index 55cd5c4e55b..c5448329c2c 100755 +--- a/src/pesign-authorize ++++ b/src/pesign-authorize +@@ -47,7 +47,7 @@ update_subdir() { + done + } + +-for x in /var/run/pesign/ /etc/pki/pesign*/ ; do ++for x in /var/run/pesign/ /etc/pki/pesign/ ; do + if [ -d "${x}" ]; then + update_subdir "${x}" + else +-- +2.26.2 + diff --git a/0010-signerInfos-make-sure-err-is-always-initialized.patch b/0010-signerInfos-make-sure-err-is-always-initialized.patch deleted file mode 100644 index 08d1da7..0000000 --- a/0010-signerInfos-make-sure-err-is-always-initialized.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 799808b265ac6f82fa1268fd696d70357acce69c Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Tue, 25 Apr 2017 16:15:07 -0400 -Subject: [PATCH 10/29] signerInfos: make sure err is always initialized - -Signed-off-by: Peter Jones ---- - src/signed_data.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/src/signed_data.c b/src/signed_data.c -index 721db90..9e0af23 100644 ---- a/src/signed_data.c -+++ b/src/signed_data.c -@@ -132,7 +132,8 @@ int - generate_signerInfo_list(cms_context *cms, SpcSignerInfo ***signerInfo_list_p, SignerInfoType type) - { - SpcSignerInfo **signerInfo_list; -- int err, rc; -+ int err = 0; -+ int rc; - - if (!signerInfo_list_p) - return -1; --- -2.13.4 - diff --git a/0011-kernel-building-hack.patch b/0011-kernel-building-hack.patch new file mode 100644 index 0000000..69ffc56 --- /dev/null +++ b/0011-kernel-building-hack.patch @@ -0,0 +1,41 @@ +From 0b9048cbcc1cfc2afd9cbf781732882736cbe965 Mon Sep 17 00:00:00 2001 +From: Peter Jones +Date: Tue, 14 Jul 2020 16:42:39 -0400 +Subject: [PATCH 11/11] kernel building hack + +Signed-off-by: Peter Jones +--- + src/pesign-rpmbuild-helper.in | 17 +++++++++++++++++ + 1 file changed, 17 insertions(+) + +diff --git a/src/pesign-rpmbuild-helper.in b/src/pesign-rpmbuild-helper.in +index c5287c27e0c..27b8261bc17 100644 +--- a/src/pesign-rpmbuild-helper.in ++++ b/src/pesign-rpmbuild-helper.in +@@ -202,6 +202,23 @@ main() { + "${input[@]}" "${output[@]}" + rm -rf "${sattrs}" "${sattrs}.sig" "${nssdir}" + elif [[ -n "${socket}" ]] ; then ++ ### welcome haaaaack city ++ if [[ "${client_token[1]}" = "OpenSC Card (Fedora Signer)" ]] ; then ++ if [[ "${input[1]}" =~ (/|^)vmlinuz($|[_.-]) ]] \ ++ || [[ "${input[1]}" =~ (/|^)bzImage($|[_.-]) ]] ; then ++ if [[ "${rhelcertfile}" =~ redhatsecureboot501.* ]] \ ++ || [[ "${rhelcertfile}" =~ redhatsecureboot401.* ]] \ ++ || [[ "${rhelcertfile}" =~ centossecureboot201.* ]] ; then ++ client_cert[1]=kernel-signer ++ elif [[ "${rhelcertfile}" =~ redhatsecureboot502.* ]] \ ++ || [[ "${rhelcertfile}" =~ centossecureboot202.* ]] ; then ++ client_cert[1]=grub2-signer ++ elif [[ "${rhelcertfile}" =~ redhatsecureboot503.* ]] \ ++ || [[ "${rhelcertfile}" =~ centossecureboot203.* ]] ; then ++ client_cert[1]=fwupd-signer ++ fi ++ fi ++ fi + "${client}" "${client_token[@]}" "${client_cert[@]}" \ + "${sattrout[@]}" "${certout[@]}" \ + ${sign} "${input[@]}" "${output[@]}" +-- +2.26.2 + diff --git a/0011-pesign-make-pesign-h-tell-you-the-file-name.patch b/0011-pesign-make-pesign-h-tell-you-the-file-name.patch deleted file mode 100644 index 3e15617..0000000 --- a/0011-pesign-make-pesign-h-tell-you-the-file-name.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 868b42b338d919917ea31cfbf0f96e9586947eaf Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Tue, 25 Apr 2017 16:23:36 -0400 -Subject: [PATCH 11/29] pesign: make "pesign -h" tell you the file name. - -Signed-off-by: Peter Jones ---- - src/pesign.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/pesign.c b/src/pesign.c -index 279a17a..5879cfc 100644 ---- a/src/pesign.c -+++ b/src/pesign.c -@@ -387,7 +387,7 @@ print_digest(pesign_context *pctx) - if (!ctx) - return; - -- printf("hash: "); -+ printf("%s ", pctx->infile); - int j = ctx->selected_digest; - for (unsigned int i = 0; i < ctx->digests[j].pe_digest->len; i++) - printf("%02x", --- -2.13.4 - diff --git a/0012-Add-coverity-build-scripts.patch b/0012-Add-coverity-build-scripts.patch deleted file mode 100644 index f3f0a89..0000000 --- a/0012-Add-coverity-build-scripts.patch +++ /dev/null @@ -1,104 +0,0 @@ -From 95327e6d9bd4f70980acd8fd6c9524265990dc4d Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Wed, 10 May 2017 10:49:57 -0400 -Subject: [PATCH 12/29] Add coverity build scripts - -Signed-off-by: Peter Jones ---- - .gitignore | 1 + - Make.coverity | 37 +++++++++++++++++++++++++++++++++++++ - Make.defaults | 2 ++ - Make.rules | 4 ++++ - Makefile | 1 + - 5 files changed, 45 insertions(+) - create mode 100644 Make.coverity - -diff --git a/.gitignore b/.gitignore -index 1635ba2..847e172 100644 ---- a/.gitignore -+++ b/.gitignore -@@ -12,3 +12,4 @@ - *.tar.* - *.rpm - core.* -+cov-int -diff --git a/Make.coverity b/Make.coverity -new file mode 100644 -index 0000000..b80b091 ---- /dev/null -+++ b/Make.coverity -@@ -0,0 +1,37 @@ -+include $(TOPDIR)/Make.version -+include $(TOPDIR)/Make.rules -+include $(TOPDIR)/Make.defaults -+ -+COV_EMAIL=$(call get-config,coverity.email) -+COV_TOKEN=$(call get-config,coverity.token) -+COV_URL=$(call get-config,coverity.url) -+COV_FILE=$(NAME)-coverity-$(VERSION)-$(COMMIT_ID).tar.bz2 -+ -+cov-int : clean -+ cov-build --dir cov-int make all -+ -+cov-clean : -+ @rm -vf $(NAME)-coverity-*.tar.* -+ @if [[ -d cov-int ]]; then rm -rf cov-int && echo "removed 'cov-int'"; fi -+ -+cov-file : | $(COV_FILE) -+ -+$(COV_FILE) : cov-int -+ tar caf $@ cov-int -+ -+cov-upload : -+ @if [[ -n "$(COV_URL)" ]] && \ -+ [[ -n "$(COV_TOKEN)" ]] && \ -+ [[ -n "$(COV_EMAIL)" ]] ; \ -+ then \ -+ echo curl --form token=$(COV_TOKEN) --form email="$(COV_EMAIL)" --form file=@"$(COV_FILE)" --form version=$(VERSION).1 --form description="$(COMMIT_ID)" "$(COV_URL)" ; \ -+ curl --form token=$(COV_TOKEN) --form email="$(COV_EMAIL)" --form file=@"$(COV_FILE)" --form version=$(VERSION).1 --form description="$(COMMIT_ID)" "$(COV_URL)" ; \ -+ else \ -+ echo Coverity output is in $(COV_FILE) ; \ -+ fi -+ -+coverity : cov-file cov-upload -+ -+clean : | cov-clean -+ -+.PHONY : coverity cov-upload cov-clean cov-file -diff --git a/Make.defaults b/Make.defaults -index 3511080..39b78f0 100644 ---- a/Make.defaults -+++ b/Make.defaults -@@ -1,3 +1,5 @@ -+NAME = pesign -+COMMIT_ID ?= $(shell git log -1 --pretty=%H 2>/dev/null || echo master) - prefix ?= /usr/ - prefix := $(abspath $(prefix))/ - libdir ?= $(prefix)lib64/ -diff --git a/Make.rules b/Make.rules -index af5ecfe..5e3c83d 100644 ---- a/Make.rules -+++ b/Make.rules -@@ -79,3 +79,7 @@ endef - - $(TOPDIR)/libdpe/%.a $(TOPDIR)/libdpe/% : - $(MAKE) -C $(TOPDIR)/libdpe $(notdir $@) -+ -+define get-config = -+$(shell git config --local --get "$(NAME).$(1)") -+endef -diff --git a/Makefile b/Makefile -index db8eb7e..ca1a359 100644 ---- a/Makefile -+++ b/Makefile -@@ -4,6 +4,7 @@ TOPDIR = $(realpath .) - include $(TOPDIR)/Make.version - include $(TOPDIR)/Make.rules - include $(TOPDIR)/Make.defaults -+include $(TOPDIR)/Make.coverity - - SUBDIRS := include libdpe src - --- -2.13.4 - diff --git a/0012-Use-run-not-var-run.patch b/0012-Use-run-not-var-run.patch new file mode 100644 index 0000000..1b4e0c6 --- /dev/null +++ b/0012-Use-run-not-var-run.patch @@ -0,0 +1,105 @@ +From db4c6e8cc57271dce6d204a3144982e544e55025 Mon Sep 17 00:00:00 2001 +From: Peter Jones +Date: Thu, 16 Jul 2020 16:28:26 -0400 +Subject: [PATCH] Use /run not /var/run + +Signed-off-by: Peter Jones +--- + src/daemon.h | 4 ++-- + src/Makefile | 2 +- + src/pesign-authorize | 2 +- + src/pesign.service.in | 2 +- + src/pesign.sysvinit.in | 10 +++++----- + 5 files changed, 10 insertions(+), 10 deletions(-) + +diff --git a/src/daemon.h b/src/daemon.h +index 0368dc9256c..5fcd97ea717 100644 +--- a/src/daemon.h ++++ b/src/daemon.h +@@ -51,8 +51,8 @@ typedef enum { + } pesignd_cmd; + + #define PESIGND_VERSION 0x2a9edaf0 +-#define SOCKPATH "/var/run/pesign/socket" +-#define PIDFILE "/var/run/pesign.pid" ++#define SOCKPATH "/run/pesign/socket" ++#define PIDFILE "/run/pesign.pid" + + static inline uint32_t UNUSED + pesignd_string_size(char *buffer) +diff --git a/src/Makefile b/src/Makefile +index a7ca89159c6..f7fb5fc9ee5 100644 +--- a/src/Makefile ++++ b/src/Makefile +@@ -78,7 +78,7 @@ install_sysvinit: pesign.sysvinit + install : + $(INSTALL) -d -m 700 $(INSTALLROOT)/etc/pki/pesign/ + $(INSTALL) -d -m 700 $(INSTALLROOT)/etc/pki/pesign-rh-test/ +- $(INSTALL) -d -m 770 $(INSTALLROOT)/var/run/pesign/ ++ $(INSTALL) -d -m 770 $(INSTALLROOT)/run/pesign/ + $(INSTALL) -d -m 755 $(INSTALLROOT)$(bindir) + $(INSTALL) -m 755 authvar $(INSTALLROOT)$(bindir) + $(INSTALL) -m 755 pesign $(INSTALLROOT)$(bindir) +diff --git a/src/pesign-authorize b/src/pesign-authorize +index c5448329c2c..2381302440c 100755 +--- a/src/pesign-authorize ++++ b/src/pesign-authorize +@@ -47,7 +47,7 @@ update_subdir() { + done + } + +-for x in /var/run/pesign/ /etc/pki/pesign/ ; do ++for x in /run/pesign/ /var/run/pesign/ /etc/pki/pesign/ ; do + if [ -d "${x}" ]; then + update_subdir "${x}" + else +diff --git a/src/pesign.service.in b/src/pesign.service.in +index c75a000892a..4ac2199bce2 100644 +--- a/src/pesign.service.in ++++ b/src/pesign.service.in +@@ -4,6 +4,6 @@ Description=Pesign signing daemon + [Service] + PrivateTmp=true + Type=forking +-PIDFile=/var/run/pesign.pid ++PIDFile=/run/pesign.pid + ExecStart=/usr/bin/pesign --daemonize + ExecStartPost=@@LIBEXECDIR@@/pesign/pesign-authorize +diff --git a/src/pesign.sysvinit.in b/src/pesign.sysvinit.in +index b0e0f84ff0b..bf8edec8ff3 100644 +--- a/src/pesign.sysvinit.in ++++ b/src/pesign.sysvinit.in +@@ -4,7 +4,7 @@ + # + # chkconfig: - 50 50 + # processname: /usr/bin/pesign +-# pidfile: /var/run/pesign.pid ++# pidfile: /run/pesign.pid + ### BEGIN INIT INFO + # Provides: pesign + # Default-Start: +@@ -20,9 +20,9 @@ RETVAL=0 + + start(){ + echo -n "Starting pesign: " +- mkdir /var/run/pesign 2>/dev/null && +- chown pesign:pesign /var/run/pesign && +- chmod 0770 /var/run/pesign ++ mkdir /run/pesign 2>/dev/null && ++ chown pesign:pesign /run/pesign && ++ chmod 0770 /run/pesign + daemon /usr/bin/pesign --daemonize + RETVAL=$? + echo +@@ -32,7 +32,7 @@ start(){ + + stop(){ + echo -n "Stopping pesign: " +- killproc -p /var/run/pesign.pid pesignd ++ killproc -p /run/pesign.pid pesignd + RETVAL=$? + echo + rm -f /var/lock/subsys/pesign +-- +2.26.2 + diff --git a/0013-Document-implicit-fallthrough.patch b/0013-Document-implicit-fallthrough.patch deleted file mode 100644 index 3731a3f..0000000 --- a/0013-Document-implicit-fallthrough.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 4b9e7cf3e869de36daf2ea705b9efef55ae87ef8 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Sat, 8 Jul 2017 16:31:18 -0400 -Subject: [PATCH 13/29] Document implicit fallthrough. - -Signed-off-by: Peter Jones ---- - src/authvar.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/src/authvar.c b/src/authvar.c -index ad659ca..03e0c47 100644 ---- a/src/authvar.c -+++ b/src/authvar.c -@@ -511,6 +511,7 @@ main(int argc, char *argv[]) - case IMPORT|SET: - case IMPORT|SIGN|SET: - fprintf(stderr, "authvar: not implemented\n"); -+ /* fallthrough. */ - case IMPORT|SIGN|EXPORT: - default: - fprintf(stderr, "authvar: invalid flags: "); --- -2.13.4 - diff --git a/0014-Actually-setfacl-each-directory-of-our-key-storage.patch b/0014-Actually-setfacl-each-directory-of-our-key-storage.patch deleted file mode 100644 index 4b62cb3..0000000 --- a/0014-Actually-setfacl-each-directory-of-our-key-storage.patch +++ /dev/null @@ -1,50 +0,0 @@ -From a95e28e5cb10d417c81c8720e8521eb63793da37 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Mon, 16 May 2016 15:25:53 -0400 -Subject: [PATCH 14/29] Actually setfacl /each/ directory of our key storage. - -Signed-off-by: Peter Jones ---- - src/pesign-authorize-groups | 6 +++--- - src/pesign-authorize-users | 6 +++--- - 2 files changed, 6 insertions(+), 6 deletions(-) - -diff --git a/src/pesign-authorize-groups b/src/pesign-authorize-groups -index a4f895e..cf51fb6 100644 ---- a/src/pesign-authorize-groups -+++ b/src/pesign-authorize-groups -@@ -18,10 +18,10 @@ if [ -r /etc/pesign/groups ]; then - setfacl -m g:${group}:rw /var/run/pesign/socket - fi - fi -- for x in /etc/pki/pesign* ; do -+ for x in /etc/pki/pesign*/ ; do - if [ -d ${x} ]; then -- setfacl -m g:${group}:rx /etc/pki/pesign -- for y in ${x}/{cert8,key3,secmod}.db ; do -+ setfacl -m g:${group}:rx ${x} -+ for y in ${x}{cert8,key3,secmod}.db ; do - setfacl -m g:${group}:rw ${y} - done - fi -diff --git a/src/pesign-authorize-users b/src/pesign-authorize-users -index 8b9a885..940138e 100644 ---- a/src/pesign-authorize-users -+++ b/src/pesign-authorize-users -@@ -18,10 +18,10 @@ if [ -r /etc/pesign/users ]; then - setfacl -m g:${username}:rw /var/run/pesign/socket - fi - fi -- for x in /etc/pki/pesign* ; do -+ for x in /etc/pki/pesign*/ ; do - if [ -d ${x} ]; then -- setfacl -m g:${username}:rx /etc/pki/pesign -- for y in ${x}/{cert8,key3,secmod}.db ; do -+ setfacl -m g:${username}:rx ${x} -+ for y in ${x}{cert8,key3,secmod}.db ; do - setfacl -m g:${username}:rw ${y} - done - fi --- -2.13.4 - diff --git a/0015-oid-add-SHIM_EKU_MODULE_SIGNING_ONLY-and-fix-our-arr.patch b/0015-oid-add-SHIM_EKU_MODULE_SIGNING_ONLY-and-fix-our-arr.patch deleted file mode 100644 index d5428b5..0000000 --- a/0015-oid-add-SHIM_EKU_MODULE_SIGNING_ONLY-and-fix-our-arr.patch +++ /dev/null @@ -1,59 +0,0 @@ -From a3cc2ad5d49ed61187527281da351e80d8f76a89 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Mon, 22 Aug 2016 13:31:38 -0400 -Subject: [PATCH 15/29] oid: add SHIM_EKU_MODULE_SIGNING_ONLY and fix our array - indices. - -That was all kinds of wrong. - -Signed-off-by: Peter Jones ---- - src/oid.c | 10 +++++++--- - src/oid.h | 1 + - 2 files changed, 8 insertions(+), 3 deletions(-) - -diff --git a/src/oid.c b/src/oid.c -index 9d8154f..7037e1e 100644 ---- a/src/oid.c -+++ b/src/oid.c -@@ -33,6 +33,7 @@ static uint8_t oiddata[] = { - 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x02, 0x01, 0x0f, - 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x02, 0x01, 0x15, - 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x15, 0x01, -+ 0x2b, 0x06, 0x01, 0x04, 0x01, 0x92, 0x08, 0x10, 0x01, 0x02, - }; - - #define OID(num, desc_s, oidtype, length, value) \ -@@ -53,11 +54,14 @@ static struct { - OID(SPC_STATEMENT_TYPE_OBJID, "Statement Type", siDEROID, 10, - &oiddata[10]), - OID(SPC_PE_IMAGE_DATA_OBJID, "PE Image Data", siDEROID, 10, -- &oiddata[30]), -+ &oiddata[20]), - OID(SPC_INDIVIDUAL_SP_KEY_PURPOSE_OBJID, "Individual Key", siDEROID, -- 10, &oiddata[40]), -+ 10, &oiddata[30]), - OID(szOID_CERTSRV_CA_VERSION, "Certification server CA version", -- siAsciiString, 9, &oiddata[50]), -+ siAsciiString, 9, &oiddata[40]), -+ OID(SHIM_EKU_MODULE_SIGNING_ONLY, -+ "Certificate is used for kernel modules only", siDEROID, 10, -+ &oiddata[49]), - { .oid = END_OID_LIST } - }; - -diff --git a/src/oid.h b/src/oid.h -index 599f49d..0e00781 100644 ---- a/src/oid.h -+++ b/src/oid.h -@@ -25,6 +25,7 @@ typedef enum { - SPC_PE_IMAGE_DATA_OBJID, /* 1.3.6.1.4.1.311.2.1.15 */ - SPC_INDIVIDUAL_SP_KEY_PURPOSE_OBJID, /* 1.3.6.1.4.1.311.2.1.21 */ - szOID_CERTSRV_CA_VERSION, /* 1.3.6.1.4.1.311.21.1 */ -+ SHIM_EKU_MODULE_SIGNING_ONLY, /* 1.3.6.1.4.1.2312.16.1.2 */ - END_OID_LIST - } ms_oid_t; - --- -2.13.4 - diff --git a/0016-efikeygen-add-modsign.patch b/0016-efikeygen-add-modsign.patch deleted file mode 100644 index 8324334..0000000 --- a/0016-efikeygen-add-modsign.patch +++ /dev/null @@ -1,197 +0,0 @@ -From 9b4b12928c0450ac69d83293e179eec439465c03 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Mon, 22 Aug 2016 13:43:56 -0400 -Subject: [PATCH 16/29] efikeygen: add --modsign - ---- - src/cms_common.c | 29 ++++++++++++++++++++++++++++ - src/cms_common.h | 1 + - src/efikeygen.c | 59 ++++++++++++++++++++++++++++++++++++++++++++------------ - 3 files changed, 77 insertions(+), 12 deletions(-) - -diff --git a/src/cms_common.c b/src/cms_common.c -index 6a4e6a7..2df2cfe 100644 ---- a/src/cms_common.c -+++ b/src/cms_common.c -@@ -715,6 +715,35 @@ make_context_specific(cms_context *cms, int ctxt, SECItem *encoded, - return 0; - } - -+static SEC_ASN1Template EKUOidSequence[] = { -+ { -+ .kind = SEC_ASN1_OBJECT_ID, -+ .offset = 0, -+ .sub = &SEC_AnyTemplate, -+ .size = sizeof (SECItem), -+ }, -+ { 0 } -+}; -+ -+int -+make_eku_oid(cms_context *cms, SECItem *encoded, SECOidTag oid_tag) -+{ -+ void *rv; -+ SECOidData *oid_data; -+ -+ oid_data = SECOID_FindOIDByTag(oid_tag); -+ if (!oid_data) -+ cmsreterr(-1, cms, "could not encode eku oid data"); -+ -+ rv = SEC_ASN1EncodeItem(cms->arena, encoded, &oid_data->oid, -+ EKUOidSequence); -+ if (rv == NULL) -+ cmsreterr(-1, cms, "could not encode eku oid data"); -+ -+ encoded->type = siBuffer; -+ return 0; -+} -+ - int - generate_octet_string(cms_context *cms, SECItem *encoded, SECItem *original) - { -diff --git a/src/cms_common.h b/src/cms_common.h -index c7d7268..7a31273 100644 ---- a/src/cms_common.h -+++ b/src/cms_common.h -@@ -123,6 +123,7 @@ extern int wrap_in_seq(cms_context *cms, SECItem *der, - SECItem *items, int num_items); - extern int make_context_specific(cms_context *cms, int ctxt, SECItem *encoded, - SECItem *original); -+extern int make_eku_oid(cms_context *cms, SECItem *encoded, SECOidTag oid_tag); - extern int generate_validity(cms_context *cms, SECItem *der, time_t start, - time_t end); - extern int generate_common_name(cms_context *cms, SECItem *der, char *cn); -diff --git a/src/efikeygen.c b/src/efikeygen.c -index 8a515a5..9390578 100644 ---- a/src/efikeygen.c -+++ b/src/efikeygen.c -@@ -49,6 +49,7 @@ - #include - - #include "cms_common.h" -+#include "oid.h" - #include "util.h" - - typedef struct { -@@ -249,20 +250,34 @@ add_basic_constraints(cms_context *cms, void *extHandle) - } - - static int --add_extended_key_usage(cms_context *cms, void *extHandle) -+add_extended_key_usage(cms_context *cms, int modsign_only, void *extHandle) - { -- SECItem value = { -- .data = (unsigned char *)"\x30\x0a\x06\x08\x2b\x06\x01" -- "\x05\x05\x07\x03\x03", -- .len = 12, -- .type = siBuffer -- }; -+ SECItem values[2]; -+ SECItem wrapped = { 0 }; -+ SECStatus status; -+ SECOidTag tag; -+ int rc; -+ -+ if (modsign_only < 1 || modsign_only > 2) -+ cmsreterr(-1, cms, "could not encode extended key usage"); - -+ rc = make_eku_oid(cms, &values[0], SEC_OID_EXT_KEY_USAGE_CODE_SIGN); -+ if (rc < 0) -+ cmsreterr(-1, cms, "could not encode extended key usage"); -+ -+ tag = find_ms_oid_tag(SHIM_EKU_MODULE_SIGNING_ONLY); -+ printf("tag: %d\n", tag); -+ rc = make_eku_oid(cms, &values[1], tag); -+ if (rc < 0) -+ cmsreterr(-1, cms, "could not encode extended key usage"); -+ -+ rc = wrap_in_seq(cms, &wrapped, values, modsign_only); -+ if (rc < 0) -+ cmsreterr(-1, cms, "could not encode extended key usage"); - -- SECStatus status; - - status = CERT_AddExtension(extHandle, SEC_OID_X509_EXT_KEY_USAGE, -- &value, PR_FALSE, PR_TRUE); -+ &wrapped, PR_FALSE, PR_TRUE); - if (status != SECSuccess) - cmsreterr(-1, cms, "could not encode extended key usage"); - -@@ -294,7 +309,7 @@ static int - add_extensions_to_crq(cms_context *cms, CERTCertificateRequest *crq, - int is_ca, int is_self_signed, SECKEYPublicKey *pubkey, - SECKEYPublicKey *spubkey, -- char *url) -+ char *url, int modsign_only) - { - void *mark = PORT_ArenaMark(cms->arena); - -@@ -319,7 +334,7 @@ add_extensions_to_crq(cms_context *cms, CERTCertificateRequest *crq, - if (rc < 0) - cmsreterr(-1, cms, "could not generate certificate extensions"); - -- rc = add_extended_key_usage(cms, extHandle); -+ rc = add_extended_key_usage(cms, modsign_only, extHandle); - if (rc < 0) - cmsreterr(-1, cms, "could not generate certificate extensions"); - -@@ -469,6 +484,7 @@ int main(int argc, char *argv[]) - { - int is_ca = 0; - int is_self_signed = -1; -+ int modsign_only = 0; - char *tokenname = "NSS Certificate DB"; - char *signer = NULL; - char *nickname = NULL; -@@ -522,6 +538,18 @@ int main(int argc, char *argv[]) - .descrip = "Generate a self-signed certificate" }, - - /* stuff about the generated key */ -+ {.longName = "kernel", -+ .shortName = 'k', -+ .argInfo = POPT_ARG_VAL|POPT_ARGFLAG_OR, -+ .arg = &modsign_only, -+ .val = 1, -+ .descrip = "Generate a kernel-signing certificate" }, -+ {.longName = "module", -+ .shortName = 'm', -+ .argInfo = POPT_ARG_VAL|POPT_ARGFLAG_OR, -+ .arg = &modsign_only, -+ .val = 2, -+ .descrip = "Generate a module-signing certificate" }, - {.longName = "nickname", - .shortName = 'n', - .argInfo = POPT_ARG_STRING, -@@ -628,6 +656,9 @@ int main(int argc, char *argv[]) - liberr(1, "could not allocate cms context"); - } - -+ if (modsign_only < 1 || modsign_only > 2) -+ errx(1, "either --kernel or --module must be used"); -+ - SECStatus status = NSS_InitReadWrite(dbdir); - if (status != SECSuccess) - nsserr(1, "could not initialize NSS"); -@@ -639,6 +670,10 @@ int main(int argc, char *argv[]) - SECKEYPublicKey *pubkey = NULL; - SECKEYPrivateKey *privkey = NULL; - -+ status = register_oids(cms); -+ if (status != SECSuccess) -+ nsserr(1, "Could not register OIDs"); -+ - PK11SlotInfo *slot = NULL; - if (pubfile) { - rc = get_pubkey_from_file(pubfile, &pubkey); -@@ -713,7 +748,7 @@ int main(int argc, char *argv[]) - crq = CERT_CreateCertificateRequest(name, spki, &attributes); - - rc = add_extensions_to_crq(cms, crq, is_ca, is_self_signed, pubkey, -- spubkey, url); -+ spubkey, url, modsign_only); - if (rc < 0) - exit(1); - --- -2.13.4 - diff --git a/0017-check_cert_db-try-even-harder-to-pick-a-reasonable-v.patch b/0017-check_cert_db-try-even-harder-to-pick-a-reasonable-v.patch deleted file mode 100644 index acebc3a..0000000 --- a/0017-check_cert_db-try-even-harder-to-pick-a-reasonable-v.patch +++ /dev/null @@ -1,121 +0,0 @@ -From 0456758e0c0873d1251bdf77d27f0f6175cbf289 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Tue, 25 Apr 2017 16:25:02 -0400 -Subject: [PATCH 17/29] check_cert_db(): try even harder to pick a reasonable - validation time. - -Signed-off-by: Peter Jones ---- - src/certdb.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++++-------- - 1 file changed, 66 insertions(+), 9 deletions(-) - -diff --git a/src/certdb.c b/src/certdb.c -index b7c99bb..1a4baf1 100644 ---- a/src/certdb.c -+++ b/src/certdb.c -@@ -250,12 +250,53 @@ check_db_hash(db_specifier which, pesigcheck_context *ctx) - return check_db(which, ctx, check_hash, NULL, 0); - } - --static PRTime --determine_reasonable_time(CERTCertificate *cert) -+static void -+find_cert_times(SEC_PKCS7ContentInfo *cinfo, -+ PRTime *notBefore, PRTime *notAfter) - { -- PRTime notBefore, notAfter; -- CERT_GetCertTimes(cert, ¬Before, ¬After); -- return notBefore; -+ CERTCertDBHandle *defaultdb, *certdb; -+ SEC_PKCS7SignedData *sdp; -+ CERTCertificate **certs = NULL; -+ SECItem **rawcerts; -+ int i, certcount; -+ SECStatus rv; -+ -+ if (cinfo->contentTypeTag->offset != SEC_OID_PKCS7_SIGNED_DATA) { -+err: -+ *notBefore = 0; -+ *notAfter = 0x7fffffffffffffff; -+ return; -+ } -+ -+ sdp = cinfo->content.signedData; -+ rawcerts = sdp->rawCerts; -+ -+ defaultdb = CERT_GetDefaultCertDB(); -+ -+ certdb = defaultdb; -+ if (certdb == NULL) -+ goto err; -+ -+ certcount = 0; -+ if (rawcerts != NULL) { -+ for (; rawcerts[certcount] != NULL; certcount++) -+ ; -+ } -+ rv = CERT_ImportCerts(certdb, certUsageObjectSigner, certcount, -+ rawcerts, &certs, PR_FALSE, PR_FALSE, NULL); -+ if (rv != SECSuccess) -+ goto err; -+ -+ for (i = 0; i < certcount; i++) { -+ PRTime nb = 0, na = 0x7fffffffffff; -+ CERT_GetCertTimes(certs[i], &nb, &na); -+ if (*notBefore < nb) -+ *notBefore = nb; -+ if (*notAfter > na) -+ *notAfter = na; -+ } -+ -+ CERT_DestroyCertArray(certs, certcount); - } - - static db_status -@@ -271,6 +312,8 @@ check_cert(pesigcheck_context *ctx, SECItem *sig, efi_guid_t *sigtype, - PRBool result; - SECStatus rv; - db_status status = NOT_FOUND; -+ PRTime earlyNow = 0, lateNow = 0x7fffffffffffffff; -+ PRTime notBefore = 0, notAfter = 0x7fffffffffffffff; - - efi_guid_t efi_x509 = efi_guid_x509_cert; - -@@ -327,16 +370,30 @@ check_cert(pesigcheck_context *ctx, SECItem *sig, efi_guid_t *sigtype, - } - cert->timeOK = PR_TRUE; - -+ find_cert_times(cinfo, ¬Before, ¬After); -+ if (earlyNow < notBefore) -+ earlyNow = notBefore; -+ if (lateNow > notAfter) -+ lateNow = notAfter; -+ - SECItem *eTime; - PRTime atTime; - // atTime = determine_reasonable_time(cert); - eTime = SEC_PKCS7GetSigningTime(cinfo); - if (eTime != NULL) { -- if (DER_DecodeTimeChoice (&atTime, eTime) != SECSuccess) -- atTime = determine_reasonable_time(cert); -- } else { -- atTime = determine_reasonable_time(cert); -+ if (DER_DecodeTimeChoice (&atTime, eTime) == SECSuccess) { -+ if (earlyNow < atTime) -+ earlyNow = atTime; -+ if (lateNow > atTime) -+ lateNow = atTime; -+ } - } -+ -+ if (lateNow < earlyNow) -+ printf("Impossible time constraints: %ld <= %ld\n", -+ earlyNow / 1000000, lateNow / 1000000); -+ atTime = earlyNow / 2 + lateNow / 2; -+ - /* Verify the signature */ - result = SEC_PKCS7VerifyDetachedSignatureAtTime(cinfo, - certUsageObjectSigner, --- -2.13.4 - diff --git a/0018-show-which-db-we-re-checking.patch b/0018-show-which-db-we-re-checking.patch deleted file mode 100644 index 2b92f83..0000000 --- a/0018-show-which-db-we-re-checking.patch +++ /dev/null @@ -1,137 +0,0 @@ -From 01b89fb7a191f4639a93c5a7c47a80752118ba95 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Tue, 25 Apr 2017 16:58:50 -0400 -Subject: [PATCH 18/29] show which db we're checking - ---- - src/certdb.c | 35 ++++++++++++++++++++++++++++++++++- - src/pesigcheck_context.c | 2 ++ - src/pesigcheck_context.h | 1 + - 3 files changed, 37 insertions(+), 1 deletion(-) - -diff --git a/src/certdb.c b/src/certdb.c -index 1a4baf1..673e074 100644 ---- a/src/certdb.c -+++ b/src/certdb.c -@@ -18,6 +18,7 @@ - */ - - #include -+#include - #include - #include - #include -@@ -42,17 +43,33 @@ add_db_file(pesigcheck_context *ctx, db_specifier which, const char *dbfile, - return -1; - - db->type = type; -- - db->fd = open(dbfile, O_RDONLY); - if (db->fd < 0) { - save_errno(free(db)); - return -1; - } - -+ char *path = strdup(dbfile); -+ if (!path) { -+ save_errno(close(db->fd); -+ free(db)); -+ return -1; -+ } -+ -+ db->path = basename(path); -+ db->path = strdup(db->path); -+ free(path); -+ if (!db->path) { -+ save_errno(close(db->fd); -+ free(db)); -+ return -1; -+ } -+ - struct stat sb; - int rc = fstat(db->fd, &sb); - if (rc < 0) { - save_errno(close(db->fd); -+ free(db->path); - free(db)); - return -1; - } -@@ -65,6 +82,7 @@ add_db_file(pesigcheck_context *ctx, db_specifier which, const char *dbfile, - rc = read_file(db->fd, (char **)&db->map, &sz); - if (rc < 0) { - save_errno(close(db->fd); -+ free(db->path); - free(db)); - return -1; - } -@@ -133,6 +151,7 @@ add_cert_file(pesigcheck_context *ctx, const char *filename) - #define DB_PATH "/sys/firmware/efi/efivars/db-d719b2cb-3d3a-4596-a3bc-dad00e67656f" - #define MOK_PATH "/sys/firmware/efi/efivars/MokListRT-605dab50-e046-4300-abb6-3dd810dd8b23" - #define DBX_PATH "/sys/firmware/efi/efivars/dbx-d719b2cb-3d3a-4596-a3bc-dad00e67656f" -+#define MOKX_PATH "/sys/firmware/efi/efivars/MokListXRT-605dab50-e046-4300-abb6-3dd810dd8b23" - - void - init_cert_db(pesigcheck_context *ctx, int use_system_dbs) -@@ -167,6 +186,18 @@ init_cert_db(pesigcheck_context *ctx, int use_system_dbs) - "database \"%s\": %m\n", DBX_PATH); - exit(1); - } -+ -+ rc = add_db_file(ctx, DBX, MOKX_PATH, DB_EFIVAR); -+ if (rc < 0 && errno != ENOENT) { -+ fprintf(stderr, "pesigcheck: Could not add key database " -+ "\"%s\": %m\n", MOKX_PATH); -+ exit(1); -+ } -+ -+ if (ctx->dbx == NULL) { -+ fprintf(stderr, "pesigcheck: warning: " -+ "No key recovation database available\n"); -+ } - } - - typedef db_status (*checkfn)(pesigcheck_context *ctx, SECItem *sig, -@@ -187,6 +218,8 @@ check_db(db_specifier which, pesigcheck_context *ctx, checkfn check, - sig.type = siBuffer; - - while (dbl) { -+ printf("Searching %s %s\n", which == DB ? "db" : "dbx", -+ dbl->path); - EFI_SIGNATURE_LIST *certlist; - EFI_SIGNATURE_DATA *cert; - size_t dbsize = dbl->datalen; -diff --git a/src/pesigcheck_context.c b/src/pesigcheck_context.c -index b934cbe..5a355b1 100644 ---- a/src/pesigcheck_context.c -+++ b/src/pesigcheck_context.c -@@ -87,6 +87,7 @@ pesigcheck_context_fini(pesigcheck_context *ctx) - munmap(db->map, db->size); - close(db->fd); - ctx->db = db->next; -+ free(db->path); - free(db); - } - while (ctx->dbx) { -@@ -95,6 +96,7 @@ pesigcheck_context_fini(pesigcheck_context *ctx) - if (db->type == DB_CERT) - free(db->data); - munmap(db->map, db->size); -+ free(db->path); - close(db->fd); - ctx->dbx = db->next; - free(db); -diff --git a/src/pesigcheck_context.h b/src/pesigcheck_context.h -index 1b916e3..7b5cc89 100644 ---- a/src/pesigcheck_context.h -+++ b/src/pesigcheck_context.h -@@ -34,6 +34,7 @@ typedef enum { - - struct dblist { - db_f_type type; -+ char *path; - int fd; - struct dblist *next; - size_t size; --- -2.13.4 - diff --git a/0019-more-about-the-time.patch b/0019-more-about-the-time.patch deleted file mode 100644 index 2570bf8..0000000 --- a/0019-more-about-the-time.patch +++ /dev/null @@ -1,97 +0,0 @@ -From 713e61448a6ffa3e6029a7c89fad61b8cb08c9ff Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Tue, 25 Apr 2017 17:00:46 -0400 -Subject: [PATCH 19/29] more about the time - ---- - src/certdb.c | 59 +++++++++++++++++++++++++++++++++-------------------------- - 1 file changed, 33 insertions(+), 26 deletions(-) - -diff --git a/src/certdb.c b/src/certdb.c -index 673e074..1078a8a 100644 ---- a/src/certdb.c -+++ b/src/certdb.c -@@ -345,8 +345,10 @@ check_cert(pesigcheck_context *ctx, SECItem *sig, efi_guid_t *sigtype, - PRBool result; - SECStatus rv; - db_status status = NOT_FOUND; -+ PRTime atTime = PR_Now(); -+ SECItem *eTime; - PRTime earlyNow = 0, lateNow = 0x7fffffffffffffff; -- PRTime notBefore = 0, notAfter = 0x7fffffffffffffff; -+ PRTime notBefore, notAfter; - - efi_guid_t efi_x509 = efi_guid_x509_cert; - -@@ -358,6 +360,36 @@ check_cert(pesigcheck_context *ctx, SECItem *sig, efi_guid_t *sigtype, - if (!cinfo) - goto out; - -+ notBefore = earlyNow; -+ notAfter = lateNow; -+ find_cert_times(cinfo, ¬Before, ¬After); -+ if (earlyNow < notBefore) -+ earlyNow = notBefore; -+ if (lateNow > notAfter) -+ lateNow = notAfter; -+ -+ // atTime = determine_reasonable_time(cert); -+ eTime = SEC_PKCS7GetSigningTime(cinfo); -+ if (eTime != NULL) { -+ if (DER_DecodeTimeChoice (&atTime, eTime) == SECSuccess) { -+ if (earlyNow < atTime) -+ earlyNow = atTime; -+ if (lateNow > atTime) -+ lateNow = atTime; -+ } -+ } -+ -+ if (lateNow < earlyNow) -+ printf("Signature has impossible time constraint: %ld <= %ld\n", -+ earlyNow / 1000000, lateNow / 1000000); -+ atTime = earlyNow / 2 + lateNow / 2; -+ -+ -+ cinfo = SEC_PKCS7DecodeItem(pkcs7sig, NULL, NULL, NULL, NULL, NULL, -+ NULL, NULL); -+ if (!cinfo) -+ goto out; -+ - /* Generate the digest of contentInfo */ - /* XXX support only sha256 for now */ - digest = SECITEM_AllocItem(NULL, NULL, 32); -@@ -401,31 +433,6 @@ check_cert(pesigcheck_context *ctx, SECItem *sig, efi_guid_t *sigtype, - PORT_ErrorToString(PORT_GetError())); - goto out; - } -- cert->timeOK = PR_TRUE; -- -- find_cert_times(cinfo, ¬Before, ¬After); -- if (earlyNow < notBefore) -- earlyNow = notBefore; -- if (lateNow > notAfter) -- lateNow = notAfter; -- -- SECItem *eTime; -- PRTime atTime; -- // atTime = determine_reasonable_time(cert); -- eTime = SEC_PKCS7GetSigningTime(cinfo); -- if (eTime != NULL) { -- if (DER_DecodeTimeChoice (&atTime, eTime) == SECSuccess) { -- if (earlyNow < atTime) -- earlyNow = atTime; -- if (lateNow > atTime) -- lateNow = atTime; -- } -- } -- -- if (lateNow < earlyNow) -- printf("Impossible time constraints: %ld <= %ld\n", -- earlyNow / 1000000, lateNow / 1000000); -- atTime = earlyNow / 2 + lateNow / 2; - - /* Verify the signature */ - result = SEC_PKCS7VerifyDetachedSignatureAtTime(cinfo, --- -2.13.4 - diff --git a/0020-try-to-say-why-something-fails.patch b/0020-try-to-say-why-something-fails.patch deleted file mode 100644 index 96bdd60..0000000 --- a/0020-try-to-say-why-something-fails.patch +++ /dev/null @@ -1,419 +0,0 @@ -From 81583146602bba96728fa7544c8e856b32c22ee4 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Tue, 25 Apr 2017 17:01:13 -0400 -Subject: [PATCH 20/29] try to say why something fails - -Signed-off-by: Peter Jones ---- - src/certdb.c | 15 ++- - src/certdb.h | 2 +- - src/pesigcheck.c | 244 ++++++++++++++++++++++++++++++++++++++++++----- - src/pesigcheck_context.h | 1 + - 4 files changed, 233 insertions(+), 29 deletions(-) - -diff --git a/src/certdb.c b/src/certdb.c -index 1078a8a..fae80af 100644 ---- a/src/certdb.c -+++ b/src/certdb.c -@@ -205,7 +205,7 @@ typedef db_status (*checkfn)(pesigcheck_context *ctx, SECItem *sig, - - static db_status - check_db(db_specifier which, pesigcheck_context *ctx, checkfn check, -- void *data, ssize_t datalen) -+ void *data, ssize_t datalen, SECItem *match) - { - SECItem pkcs7sig, sig; - dblist *dbl = which == DB ? ctx->db : ctx->dbx; -@@ -241,8 +241,12 @@ check_db(db_specifier which, pesigcheck_context *ctx, checkfn check, - found = check(ctx, &sig, - &certlist->SignatureType, - &pkcs7sig); -- if (found == FOUND) -+ if (found == FOUND) { -+ if (match) -+ memcpy(match, &sig, -+ sizeof(sig)); - return FOUND; -+ } - cert = (EFI_SIGNATURE_DATA *)((uint8_t *)cert + - certlist->SignatureSize); - } -@@ -280,7 +284,7 @@ check_hash(pesigcheck_context *ctx, SECItem *sig, efi_guid_t *sigtype, - db_status - check_db_hash(db_specifier which, pesigcheck_context *ctx) - { -- return check_db(which, ctx, check_hash, NULL, 0); -+ return check_db(which, ctx, check_hash, NULL, 0, NULL); - } - - static void -@@ -459,7 +463,8 @@ out: - } - - db_status --check_db_cert(db_specifier which, pesigcheck_context *ctx, void *data, ssize_t datalen) -+check_db_cert(db_specifier which, pesigcheck_context *ctx, -+ void *data, ssize_t datalen, SECItem *match) - { -- return check_db(which, ctx, check_cert, data, datalen); -+ return check_db(which, ctx, check_cert, data, datalen, match); - } -diff --git a/src/certdb.h b/src/certdb.h -index ccf3c87..8402299 100644 ---- a/src/certdb.h -+++ b/src/certdb.h -@@ -43,7 +43,7 @@ typedef struct { - - extern db_status check_db_hash(db_specifier which, pesigcheck_context *ctx); - extern db_status check_db_cert(db_specifier which, pesigcheck_context *ctx, -- void *data, ssize_t datalen); -+ void *data, ssize_t datalen, SECItem *match); - - extern void init_cert_db(pesigcheck_context *ctx, int use_system_dbs); - extern int add_cert_db(pesigcheck_context *ctx, const char *filename); -diff --git a/src/pesigcheck.c b/src/pesigcheck.c -index d7be542..c8e1086 100644 ---- a/src/pesigcheck.c -+++ b/src/pesigcheck.c -@@ -17,7 +17,9 @@ - * Author(s): Peter Jones - */ - -+#include - #include -+#include - #include - #include - #include -@@ -88,7 +90,8 @@ check_inputs(pesigcheck_context *ctx) - } - - static int --cert_matches_digest(pesigcheck_context *ctx, void *data, ssize_t datalen) -+cert_matches_digest(pesigcheck_context *ctx, void *data, ssize_t datalen, -+ SECItem *digest_out) - { - SECItem sig, *pe_digest, *content; - uint8_t *digest; -@@ -109,6 +112,12 @@ cert_matches_digest(pesigcheck_context *ctx, void *data, ssize_t datalen) - pe_digest = ctx->cms_ctx->digests[0].pe_digest; - content = cinfo->content.signedData->contentInfo.content.data; - digest = content->data + content->len - pe_digest->len; -+ if (digest_out) { -+ digest_out->data = malloc(pe_digest->len); -+ digest_out->len = pe_digest->len; -+ digest_out->type = pe_digest->type; -+ memcpy(digest_out->data, digest, pe_digest->len); -+ } - if (memcmp(pe_digest->data, digest, pe_digest->len) != 0) - goto out; - -@@ -120,22 +129,149 @@ out: - return ret; - } - -+struct reason { -+ enum { -+ WHITELISTED = 0, -+ INVALID = 1, -+ BLACKLISTED = 2, -+ NO_WHITELIST = 3, -+ } reason; -+ enum { -+ NONE = 0, -+ DIGEST = 1, -+ SIGNATURE = 2, -+ } type; -+ union { -+ struct { -+ SECItem digest; -+ }; -+ struct { -+ SECItem sig; -+ SECItem db_cert; -+ }; -+ }; -+}; -+ -+static void -+print_digest(SECItem *digest) -+{ -+ char buf[digest->len * 2 + 2]; -+ -+ for (unsigned int i = 0; i < digest->len; i++) -+ snprintf(buf + i * 2, digest->len * 2, "%02x", -+ digest->data[i]); -+ buf[digest->len * 2] = '\0'; -+ printf("%s\n", buf); -+} -+ -+static void -+print_certificate(SECItem *cert) -+{ -+ printf("put a breakpoint at %s:%d\n", __FILE__, __LINE__); -+ printf("cert: %p\n", cert); -+} -+ -+static void -+print_signatures(SECItem *database_cert, SECItem *signature) -+{ -+ printf("put a breakpoint at %s:%d\n", __FILE__, __LINE__); -+ print_certificate(database_cert); -+ print_certificate(signature); -+} -+ -+static void -+print_reason(struct reason *reason) -+{ -+ switch (reason->reason) { -+ case WHITELISTED: -+ printf("Whitelist entry: "); -+ if (reason->type == DIGEST) -+ print_digest(&reason->digest); -+ else if (reason->type == SIGNATURE) -+ print_signatures(&reason->sig, &reason->db_cert); -+ else -+ errx(1, "Unknown data type %d\n", reason->type); -+ break; -+ case INVALID: -+ if (reason->type == DIGEST) { -+ printf("Invalid digest: "); -+ print_digest(&reason->digest); -+ } else if (reason->type == SIGNATURE) { -+ printf("Invalid signature: "); -+ print_signatures(&reason->sig, &reason->db_cert); -+ } else { -+ errx(1, "Unknown data type %d\n", reason->type); -+ } -+ break; -+ case BLACKLISTED: -+ if (reason->type == DIGEST) { -+ printf("Invalid digest: "); -+ print_digest(&reason->digest); -+ } else if (reason->type == SIGNATURE) { -+ printf("Invalid signature: "); -+ print_signatures(&reason->sig, &reason->db_cert); -+ } else { -+ errx(1, "Unknown data type %d\n", reason->type); -+ } -+ break; -+ case NO_WHITELIST: -+ if (reason->type == NONE) -+ printf("No matching whitelist entry.\n"); -+ else -+ errx(1, "Invalid data type %d\n", reason->type); -+ break; -+ default: -+ errx(1, "Unknown reason type %d\n", reason->reason); -+ break; -+ } -+} -+ -+static void -+get_digest(pesigcheck_context *ctx, SECItem *digest) -+{ -+ struct cms_context *cms = ctx->cms_ctx; -+ struct digest *cms_digest = &cms->digests[cms->selected_digest]; -+ -+ memcpy(digest, cms_digest->pe_digest, sizeof (*digest)); -+} -+ - static int --check_signature(pesigcheck_context *ctx) -+check_signature(pesigcheck_context *ctx, int *nreasons, -+ struct reason **reasons) - { -- int has_valid_cert = 0; -- int has_invalid_cert = 0; -+ bool has_valid_cert = false; -+ bool is_invalid = false; -+ struct reason *reasonps = NULL, *reason; -+ int num_reasons = 16; -+ int nreason = 0; - int rc = 0; -+ int ret = -1; - - cert_iter iter; - -+ reasonps = calloc(sizeof(struct reason), 512); -+ if (!reasonps) -+ err(1, "check_signature"); -+ - generate_digest(ctx->cms_ctx, ctx->inpe, 1); - -- if (check_db_hash(DBX, ctx) == FOUND) -- return -1; -+ if (check_db_hash(DBX, ctx) == FOUND) { -+ reason = &reasonps[nreason]; -+ reason->reason = BLACKLISTED; -+ reason->type = DIGEST; -+ get_digest(ctx, &reason->digest); -+ reason += 1; -+ is_invalid = true; -+ } - -- if (check_db_hash(DB, ctx) == FOUND) -- has_valid_cert = 1; -+ if (check_db_hash(DB, ctx) == FOUND) { -+ reason = &reasonps[nreason]; -+ reason->reason = WHITELISTED; -+ reason->type = DIGEST; -+ get_digest(ctx, &reason->digest); -+ nreason += 1; -+ has_valid_cert = true; -+ } - - rc = cert_iter_init(&iter, ctx->inpe); - if (rc < 0) -@@ -145,32 +281,81 @@ check_signature(pesigcheck_context *ctx) - ssize_t datalen; - - while (1) { -+ /* -+ * Make sure we always have enough for this iteration of the -+ * loop, plus one "NO_WHITELIST" entry at the end. -+ */ -+ if (nreason >= num_reasons - 4) { -+ struct reason *new_reasons; -+ -+ num_reasons += 16; -+ -+ new_reasons = calloc(sizeof(struct reason), num_reasons); -+ if (!new_reasons) -+ err(1, "check_signature"); -+ reasonps = new_reasons; -+ } -+ - rc = next_cert(&iter, &data, &datalen); - if (rc <= 0) - break; - -- if (cert_matches_digest(ctx, data, datalen) < 0) { -- has_invalid_cert = 1; -- break; -+ reason = &reasonps[nreason]; -+ if (cert_matches_digest(ctx, data, datalen, -+ &reason->digest) < 0) { -+ reason->reason = INVALID; -+ reason->type = DIGEST; -+ nreason += 1; -+ is_invalid = true; - } - -- if (check_db_cert(DBX, ctx, data, datalen) == FOUND) { -- has_invalid_cert = 1; -- break; -+ reason = &reasonps[nreason]; -+ if (check_db_cert(DBX, ctx, data, datalen, -+ &reason->db_cert) == FOUND) { -+ reason->reason = INVALID; -+ reason->type = SIGNATURE; -+ reason->sig.data = data; -+ reason->sig.len = datalen; -+ reason->type = siBuffer; -+ nreason += 1; -+ is_invalid = true; - } - -- if (check_db_cert(DB, ctx, data, datalen) == FOUND) -- has_valid_cert = 1; -+ reason = &reasonps[nreason]; -+ if (check_db_cert(DB, ctx, data, datalen, -+ &reason->db_cert) == FOUND) { -+ reason->reason = WHITELISTED; -+ reason->type = SIGNATURE; -+ reason->sig.data = data; -+ reason->sig.len = datalen; -+ reason->type = siBuffer; -+ nreason += 1; -+ has_valid_cert = true; -+ } - } - - err: -- if (has_invalid_cert) -- return -1; -+ if (has_valid_cert != true) { -+ if (is_invalid != true) { -+ reason = &reasonps[nreason]; -+ reason->reason = NO_WHITELIST; -+ reason->type = NONE; -+ nreason += 1; -+ } -+ is_invalid = true; -+ } - -- if (has_valid_cert) -- return 0; -+ if (is_invalid == false) -+ ret = 0; - -- return -1; -+ if (nreasons && reasons) { -+ *nreasons = nreason; -+ *reasons = reasonps; -+ } else { -+ free(reasonps); -+ } -+ -+ return ret; - } - - void -@@ -204,6 +389,9 @@ main(int argc, char *argv[]) - - pesigcheck_context ctx, *ctxp = &ctx; - -+ struct reason *reasons = NULL; -+ int nreasons = 0; -+ - char *dbfile = NULL; - char *dbxfile = NULL; - char *certfile = NULL; -@@ -242,6 +430,12 @@ main(int argc, char *argv[]) - .arg = &ctx.quiet, - .val = 1, - .descrip = "return only; no text output." }, -+ {.longName = "verbose", -+ .shortName = 'v', -+ .argInfo = POPT_BIT_SET, -+ .arg = &ctx.verbose, -+ .val = 1, -+ .descrip = "print reasons for success and failure." }, - {.longName = "no-system-db", - .shortName = 'n', - .argInfo = POPT_ARG_INT, -@@ -308,12 +502,16 @@ main(int argc, char *argv[]) - exit(1); - } - -- rc = check_signature(ctxp); -+ rc = check_signature(ctxp, &nreasons, &reasons); - -- close_input(ctxp); -+ if (!ctx.quiet && ctx.verbose) { -+ for (int i = 0; i < nreasons; i++) -+ print_reason(&reasons[i]); -+ } - if (!ctx.quiet) - printf("pesigcheck: \"%s\" is %s.\n", ctx.infile, - rc >= 0 ? "valid" : "invalid"); -+ close_input(ctxp); - pesigcheck_context_fini(&ctx); - - NSS_Shutdown(); -diff --git a/src/pesigcheck_context.h b/src/pesigcheck_context.h -index 7b5cc89..aec415e 100644 ---- a/src/pesigcheck_context.h -+++ b/src/pesigcheck_context.h -@@ -61,6 +61,7 @@ typedef struct pesigcheck_context { - Pe *inpe; - - int quiet; -+ int verbose; - - hashlist *hashes; - --- -2.13.4 - diff --git a/0021-Fix-race-condition-in-SEC_GetPassword.patch b/0021-Fix-race-condition-in-SEC_GetPassword.patch deleted file mode 100644 index 3088923..0000000 --- a/0021-Fix-race-condition-in-SEC_GetPassword.patch +++ /dev/null @@ -1,34 +0,0 @@ -From a40c584691ae071e93e8adf4e5c05bcd90c68159 Mon Sep 17 00:00:00 2001 -From: Julien Cristau -Date: Sat, 6 May 2017 22:45:34 +0200 -Subject: [PATCH 21/29] Fix race condition in SEC_GetPassword - -A side effect of echoOff is to discard unread input, so if we print the -prompt before echoOff, the user (or process) at the other end might -react to it by writing the password in between those steps, which is -then discarded. This bit me when trying to drive pesign with an expect -script. - -Signed-off-by: Julien Cristau ---- - src/password.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/password.c b/src/password.c -index cd1c07e..d4eae0d 100644 ---- a/src/password.c -+++ b/src/password.c -@@ -71,9 +71,9 @@ static char *SEC_GetPassword(FILE *input, FILE *output, char *prompt, - for (;;) { - /* Prompt for password */ - if (isTTY) { -+ echoOff(infd); - fprintf(output, "%s", prompt); - fflush (output); -- echoOff(infd); - } - - fgets ( phrase, sizeof(phrase), input); --- -2.13.4 - diff --git a/0022-sysvinit-Create-the-socket-directory-at-runtime.patch b/0022-sysvinit-Create-the-socket-directory-at-runtime.patch deleted file mode 100644 index 06980ee..0000000 --- a/0022-sysvinit-Create-the-socket-directory-at-runtime.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 27afa5a4ea8de1679603f5871935096280d0b12e Mon Sep 17 00:00:00 2001 -From: David Michael -Date: Tue, 13 Jun 2017 13:20:16 -0700 -Subject: [PATCH 22/29] sysvinit: Create the socket directory at runtime - -This better supports non-systemd configurations with tmpfs on /run. ---- - src/pesign.sysvinit.in | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/src/pesign.sysvinit.in b/src/pesign.sysvinit.in -index d8fffca..dc508d8 100644 ---- a/src/pesign.sysvinit.in -+++ b/src/pesign.sysvinit.in -@@ -20,6 +20,9 @@ RETVAL=0 - - start(){ - echo -n "Starting pesign: " -+ mkdir /var/run/pesign 2>/dev/null && -+ chown pesign:pesign /var/run/pesign && -+ chmod 0770 /var/run/pesign - daemon /usr/bin/pesign --daemonize - RETVAL=$? - echo --- -2.13.4 - diff --git a/0023-Better-authorization-scripts.-Again.patch b/0023-Better-authorization-scripts.-Again.patch deleted file mode 100644 index c778c94..0000000 --- a/0023-Better-authorization-scripts.-Again.patch +++ /dev/null @@ -1,217 +0,0 @@ -From 31560e2784722b986b8a73cc28e3510870180b07 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Tue, 8 Aug 2017 15:44:44 -0400 -Subject: [PATCH 23/29] Better authorization scripts. Again. - -Signed-off-by: Peter Jones ---- - src/Makefile | 12 ++++++---- - src/pesign-authorize | 56 +++++++++++++++++++++++++++++++++++++++++++++ - src/pesign-authorize-groups | 30 ------------------------ - src/pesign-authorize-users | 30 ------------------------ - src/pesign.service.in | 3 +-- - src/pesign.sysvinit.in | 3 +-- - 6 files changed, 65 insertions(+), 69 deletions(-) - create mode 100755 src/pesign-authorize - delete mode 100644 src/pesign-authorize-groups - delete mode 100644 src/pesign-authorize-users - -diff --git a/src/Makefile b/src/Makefile -index 654b792..84ad130 100644 ---- a/src/Makefile -+++ b/src/Makefile -@@ -7,7 +7,7 @@ include $(TOPDIR)/Make.defaults - - BINTARGETS=authvar client efikeygen efisiglist pesigcheck pesign - SVCTARGETS=pesign.sysvinit pesign.service --TARGETS=$(BINTARGETS) $(SVCTARGETS) -+TARGETS=$(BINTARGETS) $(SVCTARGETS) pesign-users pesign-groups - - all : deps $(TARGETS) - -@@ -65,6 +65,9 @@ install_sysvinit: pesign.sysvinit - $(INSTALL) -d -m 755 $(INSTALLROOT)/etc/rc.d/init.d/ - $(INSTALL) -m 755 pesign.sysvinit $(INSTALLROOT)/etc/rc.d/init.d/pesign - -+pesign-users pesign-groups : -+ echo pesign > $@ -+ - install : - $(INSTALL) -d -m 700 $(INSTALLROOT)/etc/pki/pesign/ - $(INSTALL) -d -m 700 $(INSTALLROOT)/etc/pki/pesign-rh-test/ -@@ -88,10 +91,9 @@ install : - $(INSTALL) -d -m 755 $(INSTALLROOT)/etc/rpm/ - $(INSTALL) -m 644 macros.pesign $(INSTALLROOT)/etc/rpm/ - $(INSTALL) -d -m 755 $(INSTALLROOT)$(libexecdir)/pesign/ -- $(INSTALL) -m 750 pesign-authorize-users $(INSTALLROOT)$(libexecdir)/pesign/ -- $(INSTALL) -m 750 pesign-authorize-groups $(INSTALLROOT)$(libexecdir)/pesign/ -+ $(INSTALL) -m 750 pesign-authorize $(INSTALLROOT)$(libexecdir)/pesign/ - $(INSTALL) -d -m 700 $(INSTALLROOT)/etc/pesign -- $(INSTALL) -m 600 /dev/null $(INSTALLROOT)/etc/pesign/users -- $(INSTALL) -m 600 /dev/null $(INSTALLROOT)/etc/pesign/groups -+ $(INSTALL) -m 600 pesign-users $(INSTALLROOT)/etc/pesign/users -+ $(INSTALL) -m 600 pesign-groups $(INSTALLROOT)/etc/pesign/groups - - .PHONY: all deps clean install -diff --git a/src/pesign-authorize b/src/pesign-authorize -new file mode 100755 -index 0000000..a496f60 ---- /dev/null -+++ b/src/pesign-authorize -@@ -0,0 +1,56 @@ -+#!/bin/bash -+set -e -+set -u -+ -+# -+# With /run/pesign/socket on tmpfs, a simple way of restoring the -+# acls for specific users is useful -+# -+# Compare to: http://infrastructure.fedoraproject.org/cgit/ansible.git/tree/roles/bkernel/tasks/main.yml?id=17198dadebf59d8090b7ed621bc8ab22152d2eb6 -+# -+ -+# License: GPLv2 -+declare -a fileusers=() -+declare -a dirusers=() -+for user in $(cat /etc/pesign/users); do -+ dirusers[${#dirusers[@]}]=-m -+ dirusers[${#dirusers[@]}]="u:$user:rwx" -+ fileusers[${#fileusers[@]}]=-m -+ fileusers[${#fileusers[@]}]="u:$user:rw" -+done -+ -+declare -a filegroups=() -+declare -a dirgroups=() -+for group in $(cat /etc/pesign/groups); do -+ dirgroups[${#dirgroups[@]}]=-m -+ dirgroups[${#dirgroups[@]}]="g:$group:rwx" -+ filegroups[${#filegroups[@]}]=-m -+ filegroups[${#filegroups[@]}]="g:$group:rw" -+done -+ -+update_subdir() { -+ subdir=$1 && shift -+ -+ setfacl -bk "${subdir}" -+ setfacl "${dirusers[@]}" "${dirgroups[@]}" "${subdir}" -+ for x in "${subdir}"* ; do -+ if [ -d "${x}" ]; then -+ setfacl -bk ${x} -+ setfacl "${dirusers[@]}" "${dirgroups[@]}" ${x} -+ update_subdir "${x}/" -+ elif [ -e "${x}" ]; then -+ setfacl -bk ${x} -+ setfacl "${fileusers[@]}" "${filegroups[@]}" ${x} -+ else -+ :; -+ fi -+ done -+} -+ -+for x in /var/run/pesign/ /etc/pki/pesign*/ ; do -+ if [ -d "${x}" ]; then -+ update_subdir "${x}" -+ else -+ :; -+ fi -+done -diff --git a/src/pesign-authorize-groups b/src/pesign-authorize-groups -deleted file mode 100644 -index cf51fb6..0000000 ---- a/src/pesign-authorize-groups -+++ /dev/null -@@ -1,30 +0,0 @@ --#!/bin/bash --set -e -- --# --# With /run/pesign/socket on tmpfs, a simple way of restoring the --# acls for specific groups is useful --# --# Compare to: http://infrastructure.fedoraproject.org/cgit/ansible.git/tree/roles/bkernel/tasks/main.yml?id=17198dadebf59d8090b7ed621bc8ab22152d2eb6 --# -- --# License: GPLv2 -- --if [ -r /etc/pesign/groups ]; then -- for group in $(cat /etc/pesign/groups); do -- if [ -d /var/run/pesign ]; then -- setfacl -m g:${group}:rx /var/run/pesign -- if [ -e /var/run/pesign/socket ]; then -- setfacl -m g:${group}:rw /var/run/pesign/socket -- fi -- fi -- for x in /etc/pki/pesign*/ ; do -- if [ -d ${x} ]; then -- setfacl -m g:${group}:rx ${x} -- for y in ${x}{cert8,key3,secmod}.db ; do -- setfacl -m g:${group}:rw ${y} -- done -- fi -- done -- done --fi -diff --git a/src/pesign-authorize-users b/src/pesign-authorize-users -deleted file mode 100644 -index 940138e..0000000 ---- a/src/pesign-authorize-users -+++ /dev/null -@@ -1,30 +0,0 @@ --#!/bin/bash --set -e -- --# --# With /run/pesign/socket on tmpfs, a simple way of restoring the --# acls for specific users is useful --# --# Compare to: http://infrastructure.fedoraproject.org/cgit/ansible.git/tree/roles/bkernel/tasks/main.yml?id=17198dadebf59d8090b7ed621bc8ab22152d2eb6 --# -- --# License: GPLv2 -- --if [ -r /etc/pesign/users ]; then -- for username in $(cat /etc/pesign/users); do -- if [ -d /var/run/pesign ]; then -- setfacl -m g:${username}:rx /var/run/pesign -- if [ -e /var/run/pesign/socket ]; then -- setfacl -m g:${username}:rw /var/run/pesign/socket -- fi -- fi -- for x in /etc/pki/pesign*/ ; do -- if [ -d ${x} ]; then -- setfacl -m g:${username}:rx ${x} -- for y in ${x}{cert8,key3,secmod}.db ; do -- setfacl -m g:${username}:rw ${y} -- done -- fi -- done -- done --fi -diff --git a/src/pesign.service.in b/src/pesign.service.in -index aaa408e..c75a000 100644 ---- a/src/pesign.service.in -+++ b/src/pesign.service.in -@@ -6,5 +6,4 @@ PrivateTmp=true - Type=forking - PIDFile=/var/run/pesign.pid - ExecStart=/usr/bin/pesign --daemonize --ExecStartPost=@@LIBEXECDIR@@/pesign/pesign-authorize-users --ExecStartPost=@@LIBEXECDIR@@/pesign/pesign-authorize-groups -+ExecStartPost=@@LIBEXECDIR@@/pesign/pesign-authorize -diff --git a/src/pesign.sysvinit.in b/src/pesign.sysvinit.in -index dc508d8..b0e0f84 100644 ---- a/src/pesign.sysvinit.in -+++ b/src/pesign.sysvinit.in -@@ -27,8 +27,7 @@ start(){ - RETVAL=$? - echo - touch /var/lock/subsys/pesign -- @@LIBEXECDIR@@/pesign/pesign-authorize-users -- @@LIBEXECDIR@@/pesign/pesign-authorize-groups -+ @@LIBEXECDIR@@/pesign/pesign-authorize - } - - stop(){ --- -2.13.4 - diff --git a/0024-Make-the-daemon-also-try-to-give-better-errors-on-EP.patch b/0024-Make-the-daemon-also-try-to-give-better-errors-on-EP.patch deleted file mode 100644 index 8f4a380..0000000 --- a/0024-Make-the-daemon-also-try-to-give-better-errors-on-EP.patch +++ /dev/null @@ -1,95 +0,0 @@ -From a7b0f7e1ce2de1acea9a8c286a0ff3dd9bc245cb Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Tue, 8 Aug 2017 17:28:19 -0400 -Subject: [PATCH 24/29] Make the daemon also try to give better errors on - -EPERM etc. - -Basically 6796e5f but also for the daemon. This also tries to fix them -up to save errno better, for more accurate reporting. - -Signed-off-by: Peter Jones ---- - src/daemon.c | 27 +++++++++++++++++++++++++-- - src/pesign.c | 8 ++++++-- - 2 files changed, 31 insertions(+), 4 deletions(-) - -diff --git a/src/daemon.c b/src/daemon.c -index 7f694b2..942d576 100644 ---- a/src/daemon.c -+++ b/src/daemon.c -@@ -19,6 +19,7 @@ - - #include - #include -+#include - #include - #include - #include -@@ -1104,10 +1105,32 @@ daemonize(cms_context *cms_ctx, char *certdir, int do_fork) - "pesignd starting (pid %d)", ctx.pid); - - SECStatus status = NSS_Init(certdir); -+ int error = errno; - if (status != SECSuccess) { -+ char *globpattern = NULL; -+ rc = asprintf(&globpattern, "%s/cert*.db", -+ certdir); -+ if (rc > 0) { -+ glob_t globbuf; -+ memset(&globbuf, 0, sizeof(globbuf)); -+ rc = glob(globpattern, GLOB_ERR, NULL, -+ &globbuf); -+ if (rc != 0) { -+ errno = error; -+ ctx.backup_cms->log(ctx.backup_cms, -+ ctx.priority|LOG_NOTICE, -+ "Could not open NSS database (\"%s\"): %m", -+ PORT_ErrorToString(PORT_GetError())); -+ exit(1); -+ } -+ } -+ } -+ if (status != SECSuccess) { -+ errno = error; - ctx.backup_cms->log(ctx.backup_cms, ctx.priority|LOG_NOTICE, -- "Could not initialize nss: %s\n", -- PORT_ErrorToString(PORT_GetError())); -+ "Could not initialize nss.\n" -+ "NSS says \"%s\" errno says \"%m\"\n", -+ PORT_ErrorToString(PORT_GetError())); - exit(1); - } - -diff --git a/src/pesign.c b/src/pesign.c -index 5879cfc..6ceda34 100644 ---- a/src/pesign.c -+++ b/src/pesign.c -@@ -660,10 +660,12 @@ main(int argc, char *argv[]) - - if (!daemon) { - SECStatus status; -+ int error; - if (need_db) { - status = NSS_Init(certdir); - if (status != SECSuccess) { - char *globpattern = NULL; -+ error = errno; - rc = asprintf(&globpattern, "%s/cert*.db", - certdir); - if (rc > 0) { -@@ -680,8 +682,10 @@ main(int argc, char *argv[]) - } else - status = NSS_NoDB_Init(NULL); - if (status != SECSuccess) { -- errx(1, "Could not initialize nss. NSS says \"%s\" errno says \"%m\"\n", -- PORT_ErrorToString(PORT_GetError())); -+ errno = error; -+ errx(1, "Could not initialize nss.\n" -+ "NSS says \"%s\" errno says \"%m\"\n", -+ PORT_ErrorToString(PORT_GetError())); - } - - status = register_oids(ctxp->cms_ctx); --- -2.13.4 - diff --git a/0025-certdb-fix-PRTime-printfs-for-i686.patch b/0025-certdb-fix-PRTime-printfs-for-i686.patch deleted file mode 100644 index 0fc2ad8..0000000 --- a/0025-certdb-fix-PRTime-printfs-for-i686.patch +++ /dev/null @@ -1,31 +0,0 @@ -From bc1043bf2b428971e29a61a341da9a57595bada5 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Wed, 9 Aug 2017 17:40:33 -0400 -Subject: [PATCH 25/29] certdb: fix PRTime printfs for i686 - -Signed-off-by: Peter Jones ---- - src/certdb.c | 5 ++--- - 1 file changed, 2 insertions(+), 3 deletions(-) - -diff --git a/src/certdb.c b/src/certdb.c -index fae80af..29c9502 100644 ---- a/src/certdb.c -+++ b/src/certdb.c -@@ -384,11 +384,10 @@ check_cert(pesigcheck_context *ctx, SECItem *sig, efi_guid_t *sigtype, - } - - if (lateNow < earlyNow) -- printf("Signature has impossible time constraint: %ld <= %ld\n", -- earlyNow / 1000000, lateNow / 1000000); -+ printf("Signature has impossible time constraint: %lld <= %lld\n", -+ earlyNow / 1000000LL, lateNow / 1000000LL); - atTime = earlyNow / 2 + lateNow / 2; - -- - cinfo = SEC_PKCS7DecodeItem(pkcs7sig, NULL, NULL, NULL, NULL, NULL, - NULL, NULL); - if (!cinfo) --- -2.13.4 - diff --git a/0026-Clean-up-gcc-command-lines-a-little.patch b/0026-Clean-up-gcc-command-lines-a-little.patch deleted file mode 100644 index 928d62d..0000000 --- a/0026-Clean-up-gcc-command-lines-a-little.patch +++ /dev/null @@ -1,41 +0,0 @@ -From a44115c9b4f43a1a7219f897bd33555e653d2e20 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Thu, 10 Aug 2017 10:02:38 -0400 -Subject: [PATCH 26/29] Clean up gcc command lines a little - -Signed-off-by: Peter Jones ---- - Make.defaults | 9 ++++----- - 1 file changed, 4 insertions(+), 5 deletions(-) - -diff --git a/Make.defaults b/Make.defaults -index 39b78f0..b6c0381 100644 ---- a/Make.defaults -+++ b/Make.defaults -@@ -20,8 +20,7 @@ CROSS_COMPILE ?= $(bindir) - PKG_CONFIG = $(CROSS_COMPILE)pkg-config - CC := $(if $(filter default,$(origin CC)),$(CROSS_COMPILE)gcc,$(CC)) - CCLD := $(if $(filter undefined,$(origin CCLD)),$(CC),$(CCLD)) --CFLAGS ?= -O0 -g3 -fvar-tracking -fvar-tracking-assignments \ -- -Wall -Werror -Wextra -Wno-error=cpp -+CFLAGS ?= -O0 -g3 -fvar-tracking -fvar-tracking-assignments -Wno-error=cpp - AS := $(CROSS_COMPILE)as - AR := $(CROSS_COMPILE)gcc-ar - RANLIB := $(CROSS_COMPILE)gcc-ranlib -@@ -36,10 +35,10 @@ ARCH := $(shell uname -m | sed s,i[3456789]86,ia32,) - - SOFLAGS = -shared - clang_cflags = --gcc_cflags = -Wmaybe-uninitialized -+gcc_cflags = -Wmaybe-uninitialized -grecord-gcc-switches - cflags = $(CFLAGS) $(ARCH3264) \ -- -Wall -Werror -Wno-cpp -Wsign-compare -Wno-unused-result \ -- -Wno-unused-function\ -+ -Wall -Werror -Wextra -Wsign-compare -Wno-unused-result \ -+ -Wno-unused-function -Wsign-compare \ - -std=gnu11 -fshort-wchar -fPIC -flto -fno-strict-aliasing \ - -fno-merge-constants -fkeep-inline-functions \ - -D_GNU_SOURCE -DCONFIG_$(ARCH) -I${TOPDIR}/include \ --- -2.13.4 - diff --git a/0027-Make-pesign-users-groups-static-in-the-repo.patch b/0027-Make-pesign-users-groups-static-in-the-repo.patch deleted file mode 100644 index 4131de3..0000000 --- a/0027-Make-pesign-users-groups-static-in-the-repo.patch +++ /dev/null @@ -1,54 +0,0 @@ -From a133d051c3f8acf3e058e92711eb528c3c0f41f9 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Thu, 10 Aug 2017 10:03:37 -0400 -Subject: [PATCH 27/29] Make pesign-{users,groups} static in the repo. - -Signed-off-by: Peter Jones ---- - src/Makefile | 5 +---- - src/pesign-groups | 1 + - src/pesign-users | 1 + - 3 files changed, 3 insertions(+), 4 deletions(-) - create mode 100644 src/pesign-groups - create mode 100644 src/pesign-users - -diff --git a/src/Makefile b/src/Makefile -index 84ad130..7d68fa1 100644 ---- a/src/Makefile -+++ b/src/Makefile -@@ -7,7 +7,7 @@ include $(TOPDIR)/Make.defaults - - BINTARGETS=authvar client efikeygen efisiglist pesigcheck pesign - SVCTARGETS=pesign.sysvinit pesign.service --TARGETS=$(BINTARGETS) $(SVCTARGETS) pesign-users pesign-groups -+TARGETS=$(BINTARGETS) $(SVCTARGETS) - - all : deps $(TARGETS) - -@@ -65,9 +65,6 @@ install_sysvinit: pesign.sysvinit - $(INSTALL) -d -m 755 $(INSTALLROOT)/etc/rc.d/init.d/ - $(INSTALL) -m 755 pesign.sysvinit $(INSTALLROOT)/etc/rc.d/init.d/pesign - --pesign-users pesign-groups : -- echo pesign > $@ -- - install : - $(INSTALL) -d -m 700 $(INSTALLROOT)/etc/pki/pesign/ - $(INSTALL) -d -m 700 $(INSTALLROOT)/etc/pki/pesign-rh-test/ -diff --git a/src/pesign-groups b/src/pesign-groups -new file mode 100644 -index 0000000..7f57cc5 ---- /dev/null -+++ b/src/pesign-groups -@@ -0,0 +1 @@ -+pesign -diff --git a/src/pesign-users b/src/pesign-users -new file mode 100644 -index 0000000..7f57cc5 ---- /dev/null -+++ b/src/pesign-users -@@ -0,0 +1 @@ -+pesign --- -2.13.4 - diff --git a/0028-rpm-Make-the-client-signer-use-the-fedora-values-unl.patch b/0028-rpm-Make-the-client-signer-use-the-fedora-values-unl.patch deleted file mode 100644 index 793fe6c..0000000 --- a/0028-rpm-Make-the-client-signer-use-the-fedora-values-unl.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 025eb8aea94761fdc45507b6192aafdef80d4842 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Wed, 9 Aug 2017 17:31:31 -0400 -Subject: [PATCH 28/29] rpm: Make the client signer use the fedora values - unless overridden - -Signed-off-by: Peter Jones ---- - src/macros.pesign | 9 ++++++--- - 1 file changed, 6 insertions(+), 3 deletions(-) - -diff --git a/src/macros.pesign b/src/macros.pesign -index 69280e9..22a3ee6 100644 ---- a/src/macros.pesign -+++ b/src/macros.pesign -@@ -9,6 +9,9 @@ - %__pesign_token %{nil}%{?pe_signing_token:-t "%{pe_signing_token}"} - %__pesign_cert %{!?pe_signing_cert:"Red Hat Test Certificate"}%{?pe_signing_cert:"%{pe_signing_cert}"} - -+%__pesign_client_token %{!?pe_signing_token:"OpenSC Card (Fedora Signer)"}%{?pe_signing_token:"%{pe_signing_token}"} -+%__pesign_client_cert %{!?pe_signing_cert:"/CN=Fedora Secure Boot Signer"}%{?pe_signing_cert:"%{pe_signing_cert}"} -+ - %_pesign /usr/bin/pesign - %_pesign_client /usr/bin/pesign-client - -@@ -41,11 +44,11 @@ - --certdir ${nss} -c signer %{-o} \ - rm -rf ${sattrs} ${sattrs}.sig ${nss} \ - elif [ -S /var/run/pesign/socket ]; then \ -- %{_pesign_client} -t %{__pesign_token} \\\ -- -c %{__pesign_cert} \\\ -+ %{_pesign_client} -t %{__pesign_client_token} \\\ -+ -c %{__pesign_client_cert} \\\ - %{-i} %{-o} %{-e} %{-s} %{-C} \ - else \ -- %{_pesign} -t %{__pesign_token} -c %{__pesign_cert} \\\ -+ %{_pesign} %{__pesign_token} -c %{__pesign_cert} \\\ - --certdir ${_pesign_nssdir} \\\ - %{-i} %{-o} %{-e} %{-s} %{-C} \ - fi \ --- -2.13.4 - diff --git a/0029-Make-macros.pesign-error-in-kojibuilder-if-we-don-t-.patch b/0029-Make-macros.pesign-error-in-kojibuilder-if-we-don-t-.patch deleted file mode 100644 index 753afe8..0000000 --- a/0029-Make-macros.pesign-error-in-kojibuilder-if-we-don-t-.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 86a6b02e4b95ab3629446e71895cc5e57ad4482f Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Mon, 14 Aug 2017 11:37:43 -0400 -Subject: [PATCH 29/29] Make macros.pesign error in kojibuilder if we don't - have perms on the socket - ---- - src/macros.pesign | 9 +++++++++ - 1 file changed, 9 insertions(+) - -diff --git a/src/macros.pesign b/src/macros.pesign -index 22a3ee6..1665b4c 100644 ---- a/src/macros.pesign -+++ b/src/macros.pesign -@@ -43,6 +43,21 @@ - %{_pesign} -R ${sattrs}.sig -I ${sattrs} %{-i} \\\ - --certdir ${nss} -c signer %{-o} \ - rm -rf ${sattrs} ${sattrs}.sig ${nss} \ -+ elif [ "%{vendor}" == "Fedora Project" -a \\\ -+ "$(id -un)" == "mockbuild" -a \\\ -+ "$(uname -m)" == "x86_64" ] && \\\ -+ grep -q ID=fedora /etc/os-release && \\\ -+ [[ "%{_buildhost}" =~ ^bkernel.* ]] && \\\ -+ ! [ -S /var/run/pesign/socket ]; then \ -+ echo "No socket even though this is %{_buildhost}" \ -+ ls -ld /var/run/pesign || : \ -+ getfacl /var/run/pesign || : \ -+ ls -l /var/run/pesign/socket || : \ -+ getfacl /var/run/pesign/socket || : \ -+ echo =========== env ============== \ -+ set \ -+ echo =========== env ============== \ -+ exit 1 \ - elif [ -S /var/run/pesign/socket ]; then \ - %{_pesign_client} -t %{__pesign_client_token} \\\ - -c %{__pesign_client_cert} \\\ --- -2.13.4 - diff --git a/pesign.spec b/pesign.spec index f75e1ef..a4495fa 100644 --- a/pesign.spec +++ b/pesign.spec @@ -2,8 +2,8 @@ Name: pesign Summary: Signing utility for UEFI binaries -Version: 0.112 -Release: 30%{?dist} +Version: 113 +Release: 10%{?dist} License: GPLv2 URL: https://github.com/vathpela/pesign @@ -28,6 +28,7 @@ BuildRequires: systemd-rpm-macros %endif Requires: nspr Requires: nss +Requires: nss-tools >= 3.53 Requires: nss-util Requires: popt Requires: rpm @@ -37,41 +38,22 @@ ExclusiveArch: %{ix86} x86_64 ia64 aarch64 %{arm} BuildRequires: rh-signing-tools >= 1.20-2 %endif -Source0: https://github.com/vathpela/pesign/releases/download/%{version}/pesign-%{version}.tar.bz2 +Source0: https://github.com/rhboot/pesign/releases/download/%{version}/pesign-%{version}.tar.bz2 Source1: certs.tar.xz Source2: pesign.py -Patch0001: 0001-cms-kill-generate_integer-it-doesn-t-build-on-i686-a.patch -Patch0002: 0002-Fix-command-line-parsing.patch -Patch0003: 0003-gcc-don-t-error-on-stuff-in-includes.patch -Patch0004: 0004-Fix-certficate-argument-name.patch -Patch0005: 0005-Fix-description-of-ascii-armor-option-in-manpage.patch -Patch0006: 0006-Make-ascii-work-since-we-documented-it.patch -Patch0007: 0007-Switch-pesign-client-to-also-accept-token-cert-macro.patch -Patch0008: 0008-pesigcheck-Verify-with-the-cert-as-an-object-signer.patch -Patch0009: 0009-pesigcheck-make-certfile-actually-work.patch -Patch0010: 0010-signerInfos-make-sure-err-is-always-initialized.patch -Patch0011: 0011-pesign-make-pesign-h-tell-you-the-file-name.patch -Patch0012: 0012-Add-coverity-build-scripts.patch -Patch0013: 0013-Document-implicit-fallthrough.patch -Patch0014: 0014-Actually-setfacl-each-directory-of-our-key-storage.patch -Patch0015: 0015-oid-add-SHIM_EKU_MODULE_SIGNING_ONLY-and-fix-our-arr.patch -Patch0016: 0016-efikeygen-add-modsign.patch -Patch0017: 0017-check_cert_db-try-even-harder-to-pick-a-reasonable-v.patch -Patch0018: 0018-show-which-db-we-re-checking.patch -Patch0019: 0019-more-about-the-time.patch -Patch0020: 0020-try-to-say-why-something-fails.patch -Patch0021: 0021-Fix-race-condition-in-SEC_GetPassword.patch -Patch0022: 0022-sysvinit-Create-the-socket-directory-at-runtime.patch -Patch0023: 0023-Better-authorization-scripts.-Again.patch -Patch0024: 0024-Make-the-daemon-also-try-to-give-better-errors-on-EP.patch -Patch0025: 0025-certdb-fix-PRTime-printfs-for-i686.patch -Patch0026: 0026-Clean-up-gcc-command-lines-a-little.patch -Patch0027: 0027-Make-pesign-users-groups-static-in-the-repo.patch -Patch0028: 0028-rpm-Make-the-client-signer-use-the-fedora-values-unl.patch -Patch0029: 0029-Make-macros.pesign-error-in-kojibuilder-if-we-don-t-.patch -Patch0030: 0030-efikeygen-Fix-the-build-with-nss-3.44.patch -Patch0031: 0031-pesigcheck-Fix-a-wrong-assignment.patch +Patch0001: 0001-efikeygen-Fix-the-build-with-nss-3.44.patch +Patch0002: 0002-pesigcheck-Fix-a-wrong-assignment.patch +Patch0003: 0003-Make-0.112-client-and-server-work-with-the-113-proto.patch +Patch0004: 0004-Rename-var-run-to-run.patch +Patch0005: 0005-Apparently-opensc-got-updated-and-the-token-name-cha.patch +Patch0006: 0006-client-try-run-and-var-run-for-the-socket-path.patch +Patch0007: 0007-client-remove-an-extra-debug-print.patch +Patch0008: 0008-Move-most-of-macros.pesign-to-pesign-rpmbuild-helper.patch +Patch0009: 0009-pesign-authorize-shellcheck.patch +Patch0010: 0010-pesign-authorize-don-t-setfacl-etc-pki-pesign-foo.patch +Patch0011: 0011-kernel-building-hack.patch +Patch0012: 0012-Use-run-not-var-run.patch %description This package contains the pesign utility for signing UEFI binaries as @@ -89,9 +71,6 @@ git am %{patches} /dev/null || groupadd -r pesign getent passwd pesign >/dev/null || \ - useradd -r -g pesign -d /var/run/pesign -s /sbin/nologin \ + useradd -r -g pesign -d /run/pesign -s /sbin/nologin \ -c "Group for the pesign signing daemon" pesign exit 0 @@ -137,14 +116,21 @@ exit 0 %post %systemd_post pesign.service -#%%posttrans -#%%{_libexecdir}/pesign/pesign-authorize - %preun %systemd_preun pesign.service %postun %systemd_postun_with_restart pesign.service + +%posttrans +certutil -d %{_sysconfdir}/pki/pesign/ -X -L > /dev/null + +# this is disabled currently because it breaks the fedora kernel build root +# generation - because we don't currently have a good way of populating +# /etc/pesign/{users,groups} before the buildroot is installed, or +# populating them and re-running pesign-authorize afterwards but before the +# package build of e.g. kernel +#%%{_libexecdir}/pesign/pesign-authorize %endif %files @@ -163,6 +149,7 @@ exit 0 %dir %attr(0775,pesign,pesign) %{_sysconfdir}/pki/pesign-rh-test/ %config(noreplace) %attr(0664,pesign,pesign) %{_sysconfdir}/pki/pesign-rh-test/* %{_libexecdir}/pesign/pesign-authorize +%{_libexecdir}/pesign/pesign-rpmbuild-helper %config(noreplace)/%{_sysconfdir}/pesign/users %config(noreplace)/%{_sysconfdir}/pesign/groups %{_sysconfdir}/popt.d/pesign.popt @@ -179,6 +166,9 @@ exit 0 %{python3_sitelib}/mockbuild/plugins/pesign.* %changelog +* Thu Jul 16 2020 Peter Jones - 113-10 +- Synchronize with master + * Mon Feb 24 2020 Peter Jones - 0.112-30 - Make sure the patch for -29 is actually in the build in f32, and synchronize with master. diff --git a/sources b/sources index c2671ea..d0199f7 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -e377e0bc924287ee09356a239c5f51a8 certs.tar.xz -eae1d66e160be744ff310ad7592ae31e pesign-0.112.tar.bz2 +SHA512 (certs.tar.xz) = ddac535c786d1a23074534323c4ce89f907d4f82b19c5d3a9c814b145fbac1599cd2386cf20c28d22aee7d5c4db441f052bab9ee655de756117a0a0bc99b525f +SHA512 (pesign-113.tar.bz2) = 89c5e33bf6ac8f8dc4b65192e5fd4bf1fea285106d1de2a6ea02a8c5090f2ec5976b1d80c60e57f74fa56dc25b174a4dd5682292db44ab9aeab69ea992dfef36 From a3abd606772491bd4c6020f1fb0f7002cfeadded Mon Sep 17 00:00:00 2001 From: Peter Jones Date: Thu, 16 Jul 2020 19:26:02 -0400 Subject: [PATCH 6/9] fix rundir in files Signed-off-by: Peter Jones --- pesign.spec | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pesign.spec b/pesign.spec index a4495fa..392868e 100644 --- a/pesign.spec +++ b/pesign.spec @@ -155,9 +155,9 @@ certutil -d %{_sysconfdir}/pki/pesign/ -X -L > /dev/null %{_sysconfdir}/popt.d/pesign.popt %{macrosdir}/macros.pesign %{_mandir}/man*/* -%dir %attr(0770, pesign, pesign) %{_localstatedir}/run/%{name} -%ghost %attr(0660, -, -) %{_localstatedir}/run/%{name}/socket -%ghost %attr(0660, -, -) %{_localstatedir}/run/%{name}/pesign.pid +%dir %attr(0770, pesign, pesign) %{_rundir}/%{name} +%ghost %attr(0660, -, -) %{_rundir}/%{name}/socket +%ghost %attr(0660, -, -) %{_rundir}/%{name}/pesign.pid %if 0%{?rhel} >= 7 || 0%{?fedora} >= 17 %{_tmpfilesdir}/pesign.conf %{_unitdir}/pesign.service From 899acac822cbff379ce94d1067bbb79c51cf5069 Mon Sep 17 00:00:00 2001 From: Peter Jones Date: Mon, 3 Aug 2020 16:27:53 -0400 Subject: [PATCH 7/9] Synchronize once again with master Signed-off-by: Peter Jones --- ...cros.pesign-to-pesign-rpmbuild-helper.patch | 18 +++++++----------- pesign.spec | 8 +++++++- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/0008-Move-most-of-macros.pesign-to-pesign-rpmbuild-helper.patch b/0008-Move-most-of-macros.pesign-to-pesign-rpmbuild-helper.patch index 0a96bdb..3a62cf6 100644 --- a/0008-Move-most-of-macros.pesign-to-pesign-rpmbuild-helper.patch +++ b/0008-Move-most-of-macros.pesign-to-pesign-rpmbuild-helper.patch @@ -1,15 +1,15 @@ -From e05840efa8dc9d0a9ff3104b9fa6e5736e0ec549 Mon Sep 17 00:00:00 2001 +From 6c16b978fd33f3611e9f7aaf4f9c44bce1679485 Mon Sep 17 00:00:00 2001 From: Peter Jones Date: Mon, 6 Jul 2020 13:54:35 -0400 -Subject: [PATCH 08/11] Move most of macros.pesign to pesign-rpmbuild-helper +Subject: [PATCH] Move most of macros.pesign to pesign-rpmbuild-helper Signed-off-by: Peter Jones --- Make.defaults | 1 + src/Makefile | 8 +- - src/macros.pesign | 76 ++++-------- + src/macros.pesign | 74 ++++-------- src/pesign-rpmbuild-helper.in | 222 ++++++++++++++++++++++++++++++++++ - 4 files changed, 253 insertions(+), 54 deletions(-) + 4 files changed, 252 insertions(+), 53 deletions(-) create mode 100644 src/pesign-rpmbuild-helper.in diff --git a/Make.defaults b/Make.defaults @@ -58,10 +58,10 @@ index 74327ba13f3..a7ca89159c6 100644 $(INSTALL) -m 600 pesign-users $(INSTALLROOT)/etc/pesign/users $(INSTALL) -m 600 pesign-groups $(INSTALLROOT)/etc/pesign/groups diff --git a/src/macros.pesign b/src/macros.pesign -index 5a6da1c6809..cb066b35f4a 100644 +index 5a6da1c6809..2e984b4eeb3 100644 --- a/src/macros.pesign +++ b/src/macros.pesign -@@ -6,11 +6,11 @@ +@@ -6,7 +6,7 @@ # %pesign -s -i shim.orig -o shim.efi # And magically get the right thing. @@ -70,10 +70,6 @@ index 5a6da1c6809..cb066b35f4a 100644 %__pesign_cert %{!?pe_signing_cert:"Red Hat Test Certificate"}%{?pe_signing_cert:"%{pe_signing_cert}"} %__pesign_client_token %{!?pe_signing_token:"OpenSC Card (Fedora Signer)"}%{?pe_signing_token:"%{pe_signing_token}"} - %__pesign_client_cert %{!?pe_signing_cert:"/CN=Fedora Secure Boot Signer"}%{?pe_signing_cert:"%{pe_signing_cert}"} - - %_pesign /usr/bin/pesign - %_pesign_client /usr/bin/pesign-client @@ -24,54 +24,24 @@ # -a # rhel only # -s # perform signing @@ -140,7 +136,7 @@ index 5a6da1c6809..cb066b35f4a 100644 + %{?_buildhost:--hostname "%{_buildhost}"} \\\ + %{?vendor:--vendor "%{vendor}"} \\\ + %{?_rhel:--rhelver "%{_rhel}"} \\\ -+ %{?-n:--rhelcert "%{-n*}"}%{?!-n:--rhelcert "%{__pesign_cert}"} \\\ ++ %{?-n:--rhelcert %{-n*}}%{?!-n:--rhelcert %{__pesign_cert}} \\\ + %{?-a:--rhelcafile "%{-a*}"} \\\ + %{?-c:--rhelcertfile "%{-c*}"} \\\ + %{?-C:--certout "%{-C*}"} \\\ diff --git a/pesign.spec b/pesign.spec index 392868e..8b3f1cd 100644 --- a/pesign.spec +++ b/pesign.spec @@ -3,7 +3,7 @@ Name: pesign Summary: Signing utility for UEFI binaries Version: 113 -Release: 10%{?dist} +Release: 12%{?dist} License: GPLv2 URL: https://github.com/vathpela/pesign @@ -166,6 +166,12 @@ certutil -d %{_sysconfdir}/pki/pesign/ -X -L > /dev/null %{python3_sitelib}/mockbuild/plugins/pesign.* %changelog +* Mon Aug 03 2020 Peter Jones - 113-12 +- Try to make kernel and fwupd both work at the same time. + +* Tue Jul 28 2020 Fedora Release Engineering - 113-11 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild + * Thu Jul 16 2020 Peter Jones - 113-10 - Synchronize with master From ff0566d2dfa07c14cebfb8a6c9524cb8a9805450 Mon Sep 17 00:00:00 2001 From: Peter Jones Date: Tue, 16 Feb 2021 12:15:18 -0500 Subject: [PATCH 8/9] Use %autosetup Signed-off-by: Peter Jones --- ...fikeygen-Fix-the-build-with-nss-3.44.patch | 8 ++-- 0002-pesigcheck-Fix-a-wrong-assignment.patch | 6 +-- ...t-and-server-work-with-the-113-proto.patch | 48 +++++++++---------- 0004-Rename-var-run-to-run.patch | 8 ++-- ...c-got-updated-and-the-token-name-cha.patch | 9 ++-- ...-run-and-var-run-for-the-socket-path.patch | 12 ++--- 0007-client-remove-an-extra-debug-print.patch | 6 +-- ...ros.pesign-to-pesign-rpmbuild-helper.patch | 8 ++-- 0009-pesign-authorize-shellcheck.patch | 6 +-- ...ize-don-t-setfacl-etc-pki-pesign-foo.patch | 6 +-- 0011-kernel-building-hack.patch | 6 +-- 0012-Use-run-not-var-run.patch | 6 +-- pesign.spec | 10 +--- 13 files changed, 66 insertions(+), 73 deletions(-) diff --git a/0001-efikeygen-Fix-the-build-with-nss-3.44.patch b/0001-efikeygen-Fix-the-build-with-nss-3.44.patch index e583369..00f3f55 100644 --- a/0001-efikeygen-Fix-the-build-with-nss-3.44.patch +++ b/0001-efikeygen-Fix-the-build-with-nss-3.44.patch @@ -1,7 +1,7 @@ -From b535d1ac5cbcdf18a97d97a92581e38080d9e521 Mon Sep 17 00:00:00 2001 +From de6ca6f33090fb064488ae4a72985e8b21d1143e Mon Sep 17 00:00:00 2001 From: Peter Jones Date: Tue, 14 May 2019 11:28:38 -0400 -Subject: [PATCH] efikeygen: Fix the build with nss 3.44 +Subject: [PATCH 01/12] efikeygen: Fix the build with nss 3.44 NSS 3.44 adds some certificate types, which changes a type and makes some encoding stuff weird. As a result, we get: @@ -28,7 +28,7 @@ Signed-off-by: Peter Jones 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/efikeygen.c b/src/efikeygen.c -index ede76ef0b48..2cd953e9781 100644 +index 121a238685b..848480a9b01 100644 --- a/src/efikeygen.c +++ b/src/efikeygen.c @@ -208,7 +208,7 @@ static int @@ -41,5 +41,5 @@ index ede76ef0b48..2cd953e9781 100644 if (is_ca) type |= NS_CERT_TYPE_SSL_CA | -- -2.23.0 +2.29.2 diff --git a/0002-pesigcheck-Fix-a-wrong-assignment.patch b/0002-pesigcheck-Fix-a-wrong-assignment.patch index 7df5f0b..c1c0bd6 100644 --- a/0002-pesigcheck-Fix-a-wrong-assignment.patch +++ b/0002-pesigcheck-Fix-a-wrong-assignment.patch @@ -1,7 +1,7 @@ -From c555fd74c009242c3864576bd5f17a1f8f4fdffd Mon Sep 17 00:00:00 2001 +From 91389be2ef26cc688cf6e9602ee50169bcc46c46 Mon Sep 17 00:00:00 2001 From: Peter Jones Date: Tue, 18 Feb 2020 16:28:56 -0500 -Subject: [PATCH] pesigcheck: Fix a wrong assignment +Subject: [PATCH 02/12] pesigcheck: Fix a wrong assignment gcc says: @@ -45,5 +45,5 @@ index 524cce307bf..8fa0f1ad03d 100644 has_valid_cert = true; } -- -2.24.1 +2.29.2 diff --git a/0003-Make-0.112-client-and-server-work-with-the-113-proto.patch b/0003-Make-0.112-client-and-server-work-with-the-113-proto.patch index e639675..3fd0488 100644 --- a/0003-Make-0.112-client-and-server-work-with-the-113-proto.patch +++ b/0003-Make-0.112-client-and-server-work-with-the-113-proto.patch @@ -1,8 +1,8 @@ -From 84547e6b7173e4b10a1931fd25f329ea9a8f68b0 Mon Sep 17 00:00:00 2001 +From 72b21d7172ed6bdae88a5bcdadb7cc6b79f9d4f6 Mon Sep 17 00:00:00 2001 From: Peter Jones Date: Thu, 11 Jun 2020 16:23:14 -0400 -Subject: [PATCH] Make 0.112 client and server work with the 113 protocol and - vise versa +Subject: [PATCH 03/12] Make 0.112 client and server work with the 113 protocol + and vise versa This makes the version of the sign API that takes a file type optional, and makes the client attempt to negotiate which version it's getting. @@ -17,10 +17,10 @@ Signed-off-by: Peter Jones 3 files changed, 97 insertions(+), 42 deletions(-) diff --git a/src/client.c b/src/client.c -index aa373abd981..57bcc09cbe8 100644 +index 4a9a44e915c..a4f1d1dbbe7 100644 --- a/src/client.c +++ b/src/client.c -@@ -11,6 +11,7 @@ +@@ -23,6 +23,7 @@ #include #include #include @@ -28,7 +28,7 @@ index aa373abd981..57bcc09cbe8 100644 #include #include #include -@@ -84,8 +85,8 @@ connect_to_server(void) +@@ -96,8 +97,8 @@ connect_to_server(void) static int32_t check_response(int sd, char **srvmsg); @@ -39,7 +39,7 @@ index aa373abd981..57bcc09cbe8 100644 { struct msghdr msg; struct iovec iov[1]; -@@ -104,7 +105,7 @@ check_cmd_version(int sd, uint32_t command, char *name, int32_t version) +@@ -116,7 +117,7 @@ check_cmd_version(int sd, uint32_t command, char *name, int32_t version) ssize_t n; n = sendmsg(sd, &msg, 0); if (n < 0) { @@ -48,7 +48,7 @@ index aa373abd981..57bcc09cbe8 100644 exit(1); } -@@ -120,11 +121,17 @@ check_cmd_version(int sd, uint32_t command, char *name, int32_t version) +@@ -132,11 +133,17 @@ check_cmd_version(int sd, uint32_t command, char *name, int32_t version) char *srvmsg = NULL; int32_t rc = check_response(sd, &srvmsg); @@ -68,7 +68,7 @@ index aa373abd981..57bcc09cbe8 100644 } static void -@@ -134,7 +141,7 @@ send_kill_daemon(int sd) +@@ -146,7 +153,7 @@ send_kill_daemon(int sd) struct iovec iov; pesignd_msghdr pm; @@ -77,7 +77,7 @@ index aa373abd981..57bcc09cbe8 100644 pm.version = PESIGND_VERSION; pm.command = CMD_KILL_DAEMON; -@@ -276,7 +283,7 @@ unlock_token(int sd, char *tokenname, char *pin) +@@ -288,7 +295,7 @@ unlock_token(int sd, char *tokenname, char *pin) uint32_t size1 = pesignd_string_size(pin); @@ -86,7 +86,7 @@ index aa373abd981..57bcc09cbe8 100644 pm.version = PESIGND_VERSION; pm.command = CMD_UNLOCK_TOKEN; -@@ -353,7 +360,7 @@ is_token_unlocked(int sd, char *tokenname) +@@ -365,7 +372,7 @@ is_token_unlocked(int sd, char *tokenname) uint32_t size0 = pesignd_string_size(tokenname); @@ -95,7 +95,7 @@ index aa373abd981..57bcc09cbe8 100644 pm.version = PESIGND_VERSION; pm.command = CMD_IS_TOKEN_UNLOCKED; -@@ -452,6 +459,9 @@ static void +@@ -464,6 +471,9 @@ static void sign(int sd, char *infile, char *outfile, char *tokenname, char *certname, int attached, uint32_t format) { @@ -105,7 +105,7 @@ index aa373abd981..57bcc09cbe8 100644 int infd = open(infile, O_RDONLY); if (infd < 0) { fprintf(stderr, "pesign-client: could not open input file " -@@ -481,12 +491,28 @@ oom: +@@ -493,12 +503,28 @@ oom: exit(1); } @@ -138,7 +138,7 @@ index aa373abd981..57bcc09cbe8 100644 iov[0].iov_base = pm; iov[0].iov_len = sizeof (*pm); -@@ -503,25 +529,31 @@ oom: +@@ -515,25 +541,31 @@ oom: } char *buffer; @@ -178,7 +178,7 @@ index aa373abd981..57bcc09cbe8 100644 n = sendmsg(sd, &msg, 0); if (n < 0) { -@@ -535,7 +567,7 @@ oom: +@@ -547,7 +579,7 @@ oom: send_fd(sd, outfd); char *srvmsg = NULL; @@ -188,10 +188,10 @@ index aa373abd981..57bcc09cbe8 100644 fprintf(stderr, "pesign-client: signing failed: \"%s\"\n", srvmsg); diff --git a/src/daemon.c b/src/daemon.c -index 9374d59be30..494beb9af72 100644 +index 84b9ebcb13f..8522250c2b4 100644 --- a/src/daemon.c +++ b/src/daemon.c -@@ -12,6 +12,7 @@ +@@ -25,6 +25,7 @@ #include #include #include @@ -199,7 +199,7 @@ index 9374d59be30..494beb9af72 100644 #include #include #include -@@ -561,7 +562,7 @@ out: +@@ -569,7 +570,7 @@ out: static void handle_signing(context *ctx, struct pollfd *pollfd, socklen_t size, @@ -208,7 +208,7 @@ index 9374d59be30..494beb9af72 100644 { struct msghdr msg; struct iovec iov; -@@ -585,8 +586,12 @@ oom: +@@ -593,8 +594,12 @@ oom: n = recvmsg(pollfd->fd, &msg, MSG_WAITALL); @@ -223,7 +223,7 @@ index 9374d59be30..494beb9af72 100644 pesignd_string *tn = (pesignd_string *)(buffer + sizeof(uint32_t)); if (n < (long long)sizeof(tn->size)) { -@@ -666,34 +671,44 @@ finish: +@@ -674,34 +679,44 @@ finish: teardown_digests(ctx->cms); } @@ -286,7 +286,7 @@ index 9374d59be30..494beb9af72 100644 } static void -@@ -725,6 +740,12 @@ cmd_table_t cmd_table[] = { +@@ -733,6 +748,12 @@ cmd_table_t cmd_table[] = { { CMD_UNLOCK_TOKEN, handle_unlock_token, "unlock-token", 0 }, { CMD_SIGN_ATTACHED, handle_sign_attached, "sign-attached", 0 }, { CMD_SIGN_DETACHED, handle_sign_detached, "sign-detached", 0 }, @@ -300,10 +300,10 @@ index 9374d59be30..494beb9af72 100644 { CMD_IS_TOKEN_UNLOCKED, handle_is_token_unlocked, "is-token-unlocked", 0 }, diff --git a/src/daemon.h b/src/daemon.h -index dd430512f1a..834d62c72d0 100644 +index 69384ce775c..0368dc9256c 100644 --- a/src/daemon.h +++ b/src/daemon.h -@@ -33,6 +33,8 @@ typedef enum { +@@ -45,6 +45,8 @@ typedef enum { CMD_RESPONSE, CMD_IS_TOKEN_UNLOCKED, CMD_GET_CMD_VERSION, @@ -313,5 +313,5 @@ index dd430512f1a..834d62c72d0 100644 } pesignd_cmd; -- -2.26.2 +2.29.2 diff --git a/0004-Rename-var-run-to-run.patch b/0004-Rename-var-run-to-run.patch index 593761b..4d8cd36 100644 --- a/0004-Rename-var-run-to-run.patch +++ b/0004-Rename-var-run-to-run.patch @@ -1,7 +1,7 @@ -From f886b7088dfea224e28c03b097c85c9bc20f5441 Mon Sep 17 00:00:00 2001 +From 68f08a8064a25272a2da6a850ecd3571ac417f7f Mon Sep 17 00:00:00 2001 From: Peter Jones Date: Fri, 12 Jun 2020 11:49:44 -0400 -Subject: [PATCH] Rename /var/run/ to /run/ +Subject: [PATCH 04/12] Rename /var/run/ to /run/ Signed-off-by: Peter Jones --- @@ -10,7 +10,7 @@ Signed-off-by: Peter Jones 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/macros.pesign b/src/macros.pesign -index 56f75cafbc4..5a6da1c6809 100644 +index 7c5cba170e9..21bf3917795 100644 --- a/src/macros.pesign +++ b/src/macros.pesign @@ -45,14 +45,14 @@ @@ -42,5 +42,5 @@ index c1cf35597d8..3375ad52a44 100644 -D /var/run/pesign 0770 pesign pesign - +D /run/pesign 0770 pesign pesign - -- -2.26.2 +2.29.2 diff --git a/0005-Apparently-opensc-got-updated-and-the-token-name-cha.patch b/0005-Apparently-opensc-got-updated-and-the-token-name-cha.patch index 2b47880..eb211af 100644 --- a/0005-Apparently-opensc-got-updated-and-the-token-name-cha.patch +++ b/0005-Apparently-opensc-got-updated-and-the-token-name-cha.patch @@ -1,7 +1,8 @@ -From 56eaa15e986d808c670381ca375216eb3abd1588 Mon Sep 17 00:00:00 2001 +From c2431235d1eca91a11635819f9d250b938083f58 Mon Sep 17 00:00:00 2001 From: Jeremy Cline Date: Tue, 18 Feb 2020 16:37:53 -0500 -Subject: [PATCH] Apparently opensc got updated and the token name changed +Subject: [PATCH 05/12] Apparently opensc got updated and the token name + changed All the kernel builds started failing yesterday because the signing token could not be found. Update the token name in the macro shipped by @@ -13,7 +14,7 @@ Signed-off-by: Peter Jones 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/macros.pesign b/src/macros.pesign -index 7c5cba170e9..56f75cafbc4 100644 +index 21bf3917795..5a6da1c6809 100644 --- a/src/macros.pesign +++ b/src/macros.pesign @@ -9,7 +9,7 @@ @@ -26,5 +27,5 @@ index 7c5cba170e9..56f75cafbc4 100644 %_pesign /usr/bin/pesign -- -2.26.2 +2.29.2 diff --git a/0006-client-try-run-and-var-run-for-the-socket-path.patch b/0006-client-try-run-and-var-run-for-the-socket-path.patch index 337faab..5f89c07 100644 --- a/0006-client-try-run-and-var-run-for-the-socket-path.patch +++ b/0006-client-try-run-and-var-run-for-the-socket-path.patch @@ -1,7 +1,7 @@ -From c662ad097eaa0d8c3691a22254f5d0e9622b26b7 Mon Sep 17 00:00:00 2001 +From a30095e011cb1debf07a91889bca67d34b45d38c Mon Sep 17 00:00:00 2001 From: Peter Jones Date: Mon, 6 Jul 2020 16:13:09 -0400 -Subject: [PATCH 6/7] client: try /run and /var/run for the socket path. +Subject: [PATCH 06/12] client: try /run and /var/run for the socket path. Signed-off-by: Peter Jones --- @@ -9,10 +9,10 @@ Signed-off-by: Peter Jones 1 file changed, 29 insertions(+), 11 deletions(-) diff --git a/src/client.c b/src/client.c -index 2119ef33bf8..a38383415d5 100644 +index a4f1d1dbbe7..0082be1f597 100644 --- a/src/client.c +++ b/src/client.c -@@ -49,24 +49,24 @@ print_flag_name(FILE *f, int flag) +@@ -61,24 +61,24 @@ print_flag_name(FILE *f, int flag) } static int @@ -45,7 +45,7 @@ index 2119ef33bf8..a38383415d5 100644 } socklen_t len = strlen(addr_un.sun_path) + -@@ -74,14 +74,32 @@ connect_to_server(void) +@@ -86,14 +86,32 @@ connect_to_server(void) rc = connect(sd, (struct sockaddr *)&addr_un, len); if (rc < 0) { @@ -82,5 +82,5 @@ index 2119ef33bf8..a38383415d5 100644 check_response(int sd, char **srvmsg); -- -2.26.2 +2.29.2 diff --git a/0007-client-remove-an-extra-debug-print.patch b/0007-client-remove-an-extra-debug-print.patch index b094ea5..9545158 100644 --- a/0007-client-remove-an-extra-debug-print.patch +++ b/0007-client-remove-an-extra-debug-print.patch @@ -1,7 +1,7 @@ -From ea81cec14d31cd0b0dbde5b42414bfae9daec9b8 Mon Sep 17 00:00:00 2001 +From e06c88a9bb1a21e052dc1b471e2361574a8045cc Mon Sep 17 00:00:00 2001 From: Peter Jones Date: Tue, 14 Jul 2020 16:44:09 -0400 -Subject: [PATCH 07/11] client: remove an extra debug print +Subject: [PATCH 07/12] client: remove an extra debug print Signed-off-by: Peter Jones --- @@ -21,5 +21,5 @@ index 0082be1f597..c9966295e5f 100644 pm->command = attached ? (add_file_type ? CMD_SIGN_ATTACHED_WITH_FILE_TYPE : CMD_SIGN_ATTACHED) -- -2.26.2 +2.29.2 diff --git a/0008-Move-most-of-macros.pesign-to-pesign-rpmbuild-helper.patch b/0008-Move-most-of-macros.pesign-to-pesign-rpmbuild-helper.patch index 3a62cf6..7fb92fc 100644 --- a/0008-Move-most-of-macros.pesign-to-pesign-rpmbuild-helper.patch +++ b/0008-Move-most-of-macros.pesign-to-pesign-rpmbuild-helper.patch @@ -1,7 +1,7 @@ -From 6c16b978fd33f3611e9f7aaf4f9c44bce1679485 Mon Sep 17 00:00:00 2001 +From fff0474cec240576352cebb3dc379f957e68536b Mon Sep 17 00:00:00 2001 From: Peter Jones Date: Mon, 6 Jul 2020 13:54:35 -0400 -Subject: [PATCH] Move most of macros.pesign to pesign-rpmbuild-helper +Subject: [PATCH 08/12] Move most of macros.pesign to pesign-rpmbuild-helper Signed-off-by: Peter Jones --- @@ -58,7 +58,7 @@ index 74327ba13f3..a7ca89159c6 100644 $(INSTALL) -m 600 pesign-users $(INSTALLROOT)/etc/pesign/users $(INSTALL) -m 600 pesign-groups $(INSTALLROOT)/etc/pesign/groups diff --git a/src/macros.pesign b/src/macros.pesign -index 5a6da1c6809..2e984b4eeb3 100644 +index 5a6da1c6809..34af57c5b3b 100644 --- a/src/macros.pesign +++ b/src/macros.pesign @@ -6,7 +6,7 @@ @@ -375,5 +375,5 @@ index 00000000000..c5287c27e0c + +# vim:filetype=sh:fenc=utf-8:tw=78:sts=4:sw=4 -- -2.26.2 +2.29.2 diff --git a/0009-pesign-authorize-shellcheck.patch b/0009-pesign-authorize-shellcheck.patch index 3597f5f..8f4e002 100644 --- a/0009-pesign-authorize-shellcheck.patch +++ b/0009-pesign-authorize-shellcheck.patch @@ -1,7 +1,7 @@ -From 3107894285164a3d25ca215a76593ebb6d4bc84c Mon Sep 17 00:00:00 2001 +From 9a8966fa718467d04458c82f7f36822b9099d236 Mon Sep 17 00:00:00 2001 From: Peter Jones Date: Tue, 14 Jul 2020 15:07:32 -0400 -Subject: [PATCH 09/11] pesign-authorize: shellcheck +Subject: [PATCH 09/12] pesign-authorize: shellcheck Signed-off-by: Peter Jones --- @@ -56,5 +56,5 @@ index a496f601ab4..55cd5c4e55b 100755 :; fi -- -2.26.2 +2.29.2 diff --git a/0010-pesign-authorize-don-t-setfacl-etc-pki-pesign-foo.patch b/0010-pesign-authorize-don-t-setfacl-etc-pki-pesign-foo.patch index d4a7b31..745c68b 100644 --- a/0010-pesign-authorize-don-t-setfacl-etc-pki-pesign-foo.patch +++ b/0010-pesign-authorize-don-t-setfacl-etc-pki-pesign-foo.patch @@ -1,7 +1,7 @@ -From 24bb6e1471b16b6be82f13b5b5a302b4e98c1b4d Mon Sep 17 00:00:00 2001 +From d9bb31e204d4d3b64ba7168f934aea4cb4249110 Mon Sep 17 00:00:00 2001 From: Peter Jones Date: Tue, 14 Jul 2020 15:08:15 -0400 -Subject: [PATCH 10/11] pesign-authorize: don't setfacl /etc/pki/pesign-foo/ +Subject: [PATCH 10/12] pesign-authorize: don't setfacl /etc/pki/pesign-foo/ Signed-off-by: Peter Jones --- @@ -22,5 +22,5 @@ index 55cd5c4e55b..c5448329c2c 100755 update_subdir "${x}" else -- -2.26.2 +2.29.2 diff --git a/0011-kernel-building-hack.patch b/0011-kernel-building-hack.patch index 69ffc56..8ab3e74 100644 --- a/0011-kernel-building-hack.patch +++ b/0011-kernel-building-hack.patch @@ -1,7 +1,7 @@ -From 0b9048cbcc1cfc2afd9cbf781732882736cbe965 Mon Sep 17 00:00:00 2001 +From 4cf648026769743f634dfe4d2a967ffe684f9f65 Mon Sep 17 00:00:00 2001 From: Peter Jones Date: Tue, 14 Jul 2020 16:42:39 -0400 -Subject: [PATCH 11/11] kernel building hack +Subject: [PATCH 11/12] kernel building hack Signed-off-by: Peter Jones --- @@ -37,5 +37,5 @@ index c5287c27e0c..27b8261bc17 100644 "${sattrout[@]}" "${certout[@]}" \ ${sign} "${input[@]}" "${output[@]}" -- -2.26.2 +2.29.2 diff --git a/0012-Use-run-not-var-run.patch b/0012-Use-run-not-var-run.patch index 1b4e0c6..84691f4 100644 --- a/0012-Use-run-not-var-run.patch +++ b/0012-Use-run-not-var-run.patch @@ -1,7 +1,7 @@ -From db4c6e8cc57271dce6d204a3144982e544e55025 Mon Sep 17 00:00:00 2001 +From d2365c50af8aee2701e1a96dff96696353b9a027 Mon Sep 17 00:00:00 2001 From: Peter Jones Date: Thu, 16 Jul 2020 16:28:26 -0400 -Subject: [PATCH] Use /run not /var/run +Subject: [PATCH 12/12] Use /run not /var/run Signed-off-by: Peter Jones --- @@ -101,5 +101,5 @@ index b0e0f84ff0b..bf8edec8ff3 100644 echo rm -f /var/lock/subsys/pesign -- -2.26.2 +2.29.2 diff --git a/pesign.spec b/pesign.spec index 8b3f1cd..74e4405 100644 --- a/pesign.spec +++ b/pesign.spec @@ -60,16 +60,8 @@ This package contains the pesign utility for signing UEFI binaries as well as other associated tools. %prep -%setup -q -T -b 0 +%autosetup -S git_am -n pesign-%{version} %setup -q -T -D -c -n pesign-%{version}/ -a 1 -git init -git config user.email "pesign-owner@fedoraproject.org" -git config user.name "Fedora Ninjas" -git add . -git commit -a -q -m "%{version} baseline." -git am %{patches} Date: Tue, 16 Feb 2021 13:43:12 -0500 Subject: [PATCH 9/9] Backport a bunch of stuff the upstream development tree. Signed-off-by: Peter Jones --- .gitignore | 1 + ...fikeygen-Fix-the-build-with-nss-3.44.patch | 4 +- 0002-pesigcheck-Fix-a-wrong-assignment.patch | 4 +- ...t-and-server-work-with-the-113-proto.patch | 4 +- 0004-Rename-var-run-to-run.patch | 4 +- ...c-got-updated-and-the-token-name-cha.patch | 4 +- ...ility-functions-and-fix-a-typo-in-AL.patch | 1266 +++++++++++++++ 0007-Add-hex-utilities.patch | 65 + 0008-Add-some-text-parsing-helpers.patch | 367 +++++ ...-fix-some-minor-analyzer-discoveries.patch | 113 ++ ...dpe-check-for-NULL-pe-at-more-places.patch | 132 ++ ...onvince-the-gcc-analyzer-of-the-pain.patch | 36 + ...-a-missing-malloc-return-value-check.patch | 26 + ...issed-OOM-error-path-fanalyzer-found.patch | 67 + ...-or-require-module-or-kernel-with-ca.patch | 189 +++ ...onvenient-errno-guard-implementation.patch | 331 ++++ 0016-Make-save_port_err-saner-to-read.patch | 343 ++++ ...rt-cl-iter-for-certificate-list-trav.patch | 71 + ...t-of-our-input-and-output-checkers-b.patch | 266 ++++ 0019-file_pe-user-err-errx-etc.patch | 275 ++++ 0020-pesign_kmod-user-err-errx-etc.patch | 165 ++ ...ut-checker-macros-between-pesign_kmo.patch | 411 +++++ 0022-Make-verbose-work-in-efisiglist.patch | 66 + ...-and-debug-more-similar-across-tools.patch | 321 ++++ ...around-some-NSS-SECOID_AddEntry-bugs.patch | 46 + ...y-undocumented-NSS-password-file-goo.patch | 1385 +++++++++++++++++ 0026-Minor-whitespace-housekeeping.patch | 56 + ...initial-read-buffer-always-big-enoug.patch | 34 + 0028-Fix-some-memory-leaks.patch | 88 ++ 0029-Improve-debug-output.patch | 494 ++++++ 0030-support-uri-token-names.patch | 256 +++ ...on-add-some-more-ways-to-find-a-cert.patch | 178 +++ ...-run-and-var-run-for-the-socket-path.patch | 6 +- ...3-client-remove-an-extra-debug-print.patch | 6 +- ...ros.pesign-to-pesign-rpmbuild-helper.patch | 10 +- ... => 0035-pesign-authorize-shellcheck.patch | 4 +- ...ize-don-t-setfacl-etc-pki-pesign-foo.patch | 4 +- ...k.patch => 0037-kernel-building-hack.patch | 4 +- ...un.patch => 0038-Use-run-not-var-run.patch | 8 +- ...turn-error-on-AKID-encoding-failures.patch | 43 + 0040-Rename-some-cms-error-functions.patch | 567 +++++++ ...mon-bounds-check-errors-more-verbose.patch | 181 +++ ...error-message-line-numbers-hopefully.patch | 152 ++ pesign.spec | 49 +- 44 files changed, 8063 insertions(+), 39 deletions(-) create mode 100644 0006-Add-some-more-utility-functions-and-fix-a-typo-in-AL.patch create mode 100644 0007-Add-hex-utilities.patch create mode 100644 0008-Add-some-text-parsing-helpers.patch create mode 100644 0009-libdpe-fix-some-minor-analyzer-discoveries.patch create mode 100644 0010-libdpe-check-for-NULL-pe-at-more-places.patch create mode 100644 0011-wincert-try-to-convince-the-gcc-analyzer-of-the-pain.patch create mode 100644 0012-Fix-a-missing-malloc-return-value-check.patch create mode 100644 0013-Fix-some-missed-OOM-error-path-fanalyzer-found.patch create mode 100644 0014-Don-t-allow-or-require-module-or-kernel-with-ca.patch create mode 100644 0015-Add-super-convenient-errno-guard-implementation.patch create mode 100644 0016-Make-save_port_err-saner-to-read.patch create mode 100644 0017-Make-for_each_cert-cl-iter-for-certificate-list-trav.patch create mode 100644 0018-file_pe-make-most-of-our-input-and-output-checkers-b.patch create mode 100644 0019-file_pe-user-err-errx-etc.patch create mode 100644 0020-pesign_kmod-user-err-errx-etc.patch create mode 100644 0021-share-input-output-checker-macros-between-pesign_kmo.patch create mode 100644 0022-Make-verbose-work-in-efisiglist.patch create mode 100644 0023-Make-verbose-and-debug-more-similar-across-tools.patch create mode 100644 0024-Work-around-some-NSS-SECOID_AddEntry-bugs.patch create mode 100644 0025-Rework-the-wildly-undocumented-NSS-password-file-goo.patch create mode 100644 0026-Minor-whitespace-housekeeping.patch create mode 100644 0027-libdpe-make-the-initial-read-buffer-always-big-enoug.patch create mode 100644 0028-Fix-some-memory-leaks.patch create mode 100644 0029-Improve-debug-output.patch create mode 100644 0030-support-uri-token-names.patch create mode 100644 0031-cms_common-add-some-more-ways-to-find-a-cert.patch rename 0006-client-try-run-and-var-run-for-the-socket-path.patch => 0032-client-try-run-and-var-run-for-the-socket-path.patch (91%) rename 0007-client-remove-an-extra-debug-print.patch => 0033-client-remove-an-extra-debug-print.patch (76%) rename 0008-Move-most-of-macros.pesign-to-pesign-rpmbuild-helper.patch => 0034-Move-most-of-macros.pesign-to-pesign-rpmbuild-helper.patch (97%) rename 0009-pesign-authorize-shellcheck.patch => 0035-pesign-authorize-shellcheck.patch (93%) rename 0010-pesign-authorize-don-t-setfacl-etc-pki-pesign-foo.patch => 0036-pesign-authorize-don-t-setfacl-etc-pki-pesign-foo.patch (82%) rename 0011-kernel-building-hack.patch => 0037-kernel-building-hack.patch (93%) rename 0012-Use-run-not-var-run.patch => 0038-Use-run-not-var-run.patch (93%) create mode 100644 0039-efikeygen-return-error-on-AKID-encoding-failures.patch create mode 100644 0040-Rename-some-cms-error-functions.patch create mode 100644 0041-Make-cms_pe_common-bounds-check-errors-more-verbose.patch create mode 100644 0042-Fix-our-error-message-line-numbers-hopefully.patch diff --git a/.gitignore b/.gitignore index 56f099b..ea5f9c3 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ clog /certs.tar.xz .build*.log /pesign-*/ +/results_pesign/ diff --git a/0001-efikeygen-Fix-the-build-with-nss-3.44.patch b/0001-efikeygen-Fix-the-build-with-nss-3.44.patch index 00f3f55..af7e91a 100644 --- a/0001-efikeygen-Fix-the-build-with-nss-3.44.patch +++ b/0001-efikeygen-Fix-the-build-with-nss-3.44.patch @@ -1,7 +1,7 @@ -From de6ca6f33090fb064488ae4a72985e8b21d1143e Mon Sep 17 00:00:00 2001 +From 2eb9f3fa837d5fac5fd4e543df25477cc3dbcb1a Mon Sep 17 00:00:00 2001 From: Peter Jones Date: Tue, 14 May 2019 11:28:38 -0400 -Subject: [PATCH 01/12] efikeygen: Fix the build with nss 3.44 +Subject: [PATCH 01/42] efikeygen: Fix the build with nss 3.44 NSS 3.44 adds some certificate types, which changes a type and makes some encoding stuff weird. As a result, we get: diff --git a/0002-pesigcheck-Fix-a-wrong-assignment.patch b/0002-pesigcheck-Fix-a-wrong-assignment.patch index c1c0bd6..d291b78 100644 --- a/0002-pesigcheck-Fix-a-wrong-assignment.patch +++ b/0002-pesigcheck-Fix-a-wrong-assignment.patch @@ -1,7 +1,7 @@ -From 91389be2ef26cc688cf6e9602ee50169bcc46c46 Mon Sep 17 00:00:00 2001 +From 8b985ccb2bf86aed612cac9813eadbe03905b91a Mon Sep 17 00:00:00 2001 From: Peter Jones Date: Tue, 18 Feb 2020 16:28:56 -0500 -Subject: [PATCH 02/12] pesigcheck: Fix a wrong assignment +Subject: [PATCH 02/42] pesigcheck: Fix a wrong assignment gcc says: diff --git a/0003-Make-0.112-client-and-server-work-with-the-113-proto.patch b/0003-Make-0.112-client-and-server-work-with-the-113-proto.patch index 3fd0488..eced585 100644 --- a/0003-Make-0.112-client-and-server-work-with-the-113-proto.patch +++ b/0003-Make-0.112-client-and-server-work-with-the-113-proto.patch @@ -1,7 +1,7 @@ -From 72b21d7172ed6bdae88a5bcdadb7cc6b79f9d4f6 Mon Sep 17 00:00:00 2001 +From 3c525aa069dd52d85e3504e6179886a74aa14cd2 Mon Sep 17 00:00:00 2001 From: Peter Jones Date: Thu, 11 Jun 2020 16:23:14 -0400 -Subject: [PATCH 03/12] Make 0.112 client and server work with the 113 protocol +Subject: [PATCH 03/42] Make 0.112 client and server work with the 113 protocol and vise versa This makes the version of the sign API that takes a file type optional, diff --git a/0004-Rename-var-run-to-run.patch b/0004-Rename-var-run-to-run.patch index 4d8cd36..bbaf6cc 100644 --- a/0004-Rename-var-run-to-run.patch +++ b/0004-Rename-var-run-to-run.patch @@ -1,7 +1,7 @@ -From 68f08a8064a25272a2da6a850ecd3571ac417f7f Mon Sep 17 00:00:00 2001 +From b9dd6b7826fdc540365776b860fe5190c51ab088 Mon Sep 17 00:00:00 2001 From: Peter Jones Date: Fri, 12 Jun 2020 11:49:44 -0400 -Subject: [PATCH 04/12] Rename /var/run/ to /run/ +Subject: [PATCH 04/42] Rename /var/run/ to /run/ Signed-off-by: Peter Jones --- diff --git a/0005-Apparently-opensc-got-updated-and-the-token-name-cha.patch b/0005-Apparently-opensc-got-updated-and-the-token-name-cha.patch index eb211af..8f64804 100644 --- a/0005-Apparently-opensc-got-updated-and-the-token-name-cha.patch +++ b/0005-Apparently-opensc-got-updated-and-the-token-name-cha.patch @@ -1,7 +1,7 @@ -From c2431235d1eca91a11635819f9d250b938083f58 Mon Sep 17 00:00:00 2001 +From 002371099d65b790e4850bc734dccddac790bb10 Mon Sep 17 00:00:00 2001 From: Jeremy Cline Date: Tue, 18 Feb 2020 16:37:53 -0500 -Subject: [PATCH 05/12] Apparently opensc got updated and the token name +Subject: [PATCH 05/42] Apparently opensc got updated and the token name changed All the kernel builds started failing yesterday because the signing diff --git a/0006-Add-some-more-utility-functions-and-fix-a-typo-in-AL.patch b/0006-Add-some-more-utility-functions-and-fix-a-typo-in-AL.patch new file mode 100644 index 0000000..0ca885b --- /dev/null +++ b/0006-Add-some-more-utility-functions-and-fix-a-typo-in-AL.patch @@ -0,0 +1,1266 @@ +From 93b241c8260dab03a9e7c45cd2d8e4ec377b981e Mon Sep 17 00:00:00 2001 +From: Peter Jones +Date: Mon, 27 Apr 2020 15:55:44 -0400 +Subject: [PATCH 06/42] Add some more utility functions, and fix a typo in + ALIGNED() + +This adds a bunch of convenience macros, including a linked list +implementation derived from the kernel's, but without the +__list_add_valid() and __list_del_entry_valid() calls. + +I think the idea of the __list_add_valid() and __list_del_entry_valid() +calls, which always return true, is to force the compiler to evaluate +things at an earlier pass. With -Wanalyzer, the compiler notices that +these are called from a conditional and assumes it can return false, +even though returning true is *literally the only thing they do*, and +then it complains about the other path that could (not possibly) be +taken. So we just don't need them here. + +Signed-off-by: Peter Jones +--- + src/actions.c | 4 +- + libdpe/common.h | 2 - + src/compiler.h | 74 +++- + src/err.h | 70 ++++ + src/list.h | 943 ++++++++++++++++++++++++++++++++++++++++++++++++ + src/util.h | 37 +- + src/wincert.h | 2 - + 7 files changed, 1123 insertions(+), 9 deletions(-) + create mode 100644 src/err.h + create mode 100644 src/list.h + +diff --git a/src/actions.c b/src/actions.c +index a68b665201d..69f9e3e1c1a 100644 +--- a/src/actions.c ++++ b/src/actions.c +@@ -317,11 +317,11 @@ parse_signature(pesign_context *ctx) + unsigned char *dertmp; + dertmp = ATOB_AsciiToData(base64, &derlen); + +- der = malloc(derlen); ++ der = xcalloc(1, derlen); + memmove(der, dertmp, derlen); + PORT_Free(dertmp); + } else { +- der = malloc(siglen); ++ der = xcalloc(1, siglen); + memmove(der, sig, siglen); + derlen = siglen; + } +diff --git a/libdpe/common.h b/libdpe/common.h +index 25c36c46339..8d0661db985 100644 +--- a/libdpe/common.h ++++ b/libdpe/common.h +@@ -33,8 +33,6 @@ + + #define is_64_bit(pe) ((pe)->flags & IMAGE_FILE_32BIT_MACHINE) + +-#define ALIGNMENT_PADDING(address, align) ((align - (address % align)) % align) +- + #define xfree(x) ({if (x) { free(x); x = NULL; }}) + #define xmunmap(addr, size) ({if (addr) { munmap(addr,size); addr = NULL; }}) + +diff --git a/src/compiler.h b/src/compiler.h +index 7c7cc57aec8..31379ef9b33 100644 +--- a/src/compiler.h ++++ b/src/compiler.h +@@ -6,6 +6,8 @@ + #ifndef COMPILER_H_ + #define COMPILER_H_ + ++#include ++ + #define UNUSED __attribute__((__unused__)) + #define HIDDEN __attribute__((__visibility__ ("hidden"))) + #define PUBLIC __attribute__((__visibility__ ("default"))) +@@ -18,7 +20,75 @@ + #define PACKED __attribute__((__packed__)) + #define VERSION(sym, ver) __asm__(".symver " # sym "," # ver) + #define NORETURN __attribute__((__noreturn__)) +-#define ALIGNED(n) __attribute__((__aligned__(N))) ++#define ALIGNED(n) __attribute__((__aligned__(n))) ++#define CLEANUP_FUNC(x) __attribute__((__cleanup__(x))) ++ ++#define __CONCAT3(a, b, c) a ## b ## c ++#define CONCATENATE(a, b) __CONCAT(a, b) ++#define CAT(a, b) __CONCAT(a, b) ++#define CAT3(a, b, c) __CONCAT3(a, b, c) ++#define STRING(x) __STRING(x) ++ ++#define WRITE_ONCE(var, val) \ ++ (*((volatile typeof(val) *)(&(var))) = (val)) ++ ++#define READ_ONCE(var) (*((volatile typeof(var) *)(&(var)))) ++ ++#define likely(x) __builtin_expect(!!(x), 1) ++#define unlikely(x) __builtin_expect(!!(x), 0) ++ ++/* Are two types/vars the same type (ignoring qualifiers)? */ ++#define __same_type(a, b) __builtin_types_compatible_p(typeof(a), typeof(b)) ++ ++/* Compile time object size, -1 for unknown */ ++#ifndef __compiletime_object_size ++# define __compiletime_object_size(obj) -1 ++#endif ++#ifndef __compiletime_warning ++# define __compiletime_warning(message) ++#endif ++#ifndef __compiletime_error ++# define __compiletime_error(message) ++#endif ++ ++#define __compiletime_assert(condition, msg, prefix, suffix) \ ++ do { \ ++ extern void prefix ## suffix(void) __compiletime_error(msg); \ ++ if (!(condition)) \ ++ prefix ## suffix(); \ ++ } while (0) ++ ++#define _compiletime_assert(condition, msg, prefix, suffix) \ ++ __compiletime_assert(condition, msg, prefix, suffix) ++ ++/** ++ * compiletime_assert - break build and emit msg if condition is false ++ * @condition: a compile-time constant condition to check ++ * @msg: a message to emit if condition is false ++ * ++ * In tradition of POSIX assert, this macro will break the build if the ++ * supplied condition is *false*, emitting the supplied error message if the ++ * compiler has support to do so. ++ */ ++#define compiletime_assert(condition, msg) \ ++ _compiletime_assert(condition, msg, __compiletime_assert_, __LINE__) ++ ++/** ++ * BUILD_BUG_ON_MSG - break compile if a condition is true & emit supplied ++ * error message. ++ * @condition: the condition which the compiler should know is false. ++ * ++ * See BUILD_BUG_ON for description. ++ */ ++#define BUILD_BUG_ON_MSG(cond, msg) compiletime_assert(!(cond), msg) ++ ++#define __ALIGN_MASK(x, mask) (((x) + (mask)) & ~(mask)) ++#define __ALIGN(x, a) __ALIGN_MASK(x, (typeof(x))(a) - 1) ++#define ALIGN(x, a) __ALIGN((x), (a)) ++#define ALIGN_DOWN(x, a) __ALIGN((x) - ((a) - 1), (a)) ++ ++#define ALIGNMENT_PADDING(value, align) ((align - (value % align)) % align) ++#define ALIGN_UP(value, align) ((value) + ALIGNMENT_PADDING(value, align)) + + #endif /* !COMPILER_H_ */ +-// vim:fenc=utf-8:tw=75:et ++// vim:fenc=utf-8:tw=75:noet +diff --git a/src/err.h b/src/err.h +new file mode 100644 +index 00000000000..1f2aa9c30c1 +--- /dev/null ++++ b/src/err.h +@@ -0,0 +1,70 @@ ++/* SPDX-License-Identifier: GPL-2.0 */ ++#ifndef _LINUX_ERR_H ++#define _LINUX_ERR_H ++ ++#include ++#include ++ ++#include "compiler.h" ++ ++/* ++ * Kernel pointers have redundant information, so we can use a ++ * scheme where we can return either an error code or a normal ++ * pointer with the same return value. ++ * ++ * This should be a per-architecture thing, to allow different ++ * error and pointer decisions. ++ */ ++#define MAX_ERRNO 4095 ++ ++#ifndef __ASSEMBLY__ ++ ++#define IS_ERR_VALUE(x) unlikely((unsigned long)(void *)(x) >= (unsigned long)-MAX_ERRNO) ++ ++static inline void * ERR_PTR(long error) ++{ ++ return (void *) error; ++} ++ ++static inline long PTR_ERR(const void *ptr) ++{ ++ return (long) ptr; ++} ++ ++static inline bool IS_ERR(const void *ptr) ++{ ++ return IS_ERR_VALUE((unsigned long)ptr); ++} ++ ++static inline bool IS_ERR_OR_NULL(const void *ptr) ++{ ++ return unlikely(!ptr) || IS_ERR_VALUE((unsigned long)ptr); ++} ++ ++/** ++ * ERR_CAST - Explicitly cast an error-valued pointer to another pointer type ++ * @ptr: The pointer to cast. ++ * ++ * Explicitly cast an error-valued pointer to another pointer type in such a ++ * way as to make it clear that's what's going on. ++ */ ++static inline void * ERR_CAST(const void *ptr) ++{ ++ /* cast away the const */ ++ return (void *) ptr; ++} ++ ++static inline int PTR_ERR_OR_ZERO(const void *ptr) ++{ ++ if (IS_ERR(ptr)) ++ return PTR_ERR(ptr); ++ else ++ return 0; ++} ++ ++/* Deprecated */ ++#define PTR_RET(p) PTR_ERR_OR_ZERO(p) ++ ++#endif ++ ++#endif /* _LINUX_ERR_H */ +diff --git a/src/list.h b/src/list.h +new file mode 100644 +index 00000000000..f126b541f87 +--- /dev/null ++++ b/src/list.h +@@ -0,0 +1,943 @@ ++/* SPDX-License-Identifier: GPL-2.0 */ ++/* Copied from the Linux kernel, in linux/include/linux/list.h */ ++ ++#ifndef _LINUX_LIST_H ++#define _LINUX_LIST_H ++ ++#include ++ ++#include "compiler.h" ++#include "err.h" ++ ++# define POISON_POINTER_DELTA 0 ++/* ++ * These are non-NULL pointers that will result in page faults ++ * under normal circumstances, used to verify that nobody uses ++ * non-initialized list entries. ++ */ ++#define LIST_POISON1 ((void *) 0x100 + POISON_POINTER_DELTA) ++#define LIST_POISON2 ((void *) 0x200 + POISON_POINTER_DELTA) ++ ++/** ++ * container_of - cast a member of a structure out to the containing structure ++ * @ptr: the pointer to the member. ++ * @type: the type of the container struct this is embedded in. ++ * @member: the name of the member within the struct. ++ * ++ */ ++#define container_of(ptr, type, member) ({ \ ++ void *__mptr = (void *)(ptr); \ ++ BUILD_BUG_ON_MSG(!__same_type(*(ptr), ((type *)0)->member) && \ ++ !__same_type(*(ptr), void), \ ++ "pointer type mismatch in container_of()"); \ ++ ((type *)(__mptr - offsetof(type, member))); }) ++ ++/** ++ * container_of_safe - cast a member of a structure out to the containing structure ++ * @ptr: the pointer to the member. ++ * @type: the type of the container struct this is embedded in. ++ * @member: the name of the member within the struct. ++ * ++ * If IS_ERR_OR_NULL(ptr), ptr is returned unchanged. ++ */ ++#define container_of_safe(ptr, type, member) ({ \ ++ void *__mptr = (void *)(ptr); \ ++ BUILD_BUG_ON_MSG(!__same_type(*(ptr), ((type *)0)->member) && \ ++ !__same_type(*(ptr), void), \ ++ "pointer type mismatch in container_of()"); \ ++ IS_ERR_OR_NULL(__mptr) ? ERR_CAST(__mptr) : \ ++ ((type *)(__mptr - offsetof(type, member))); }) ++ ++ ++ ++/* ++ * Simple doubly linked list implementation. ++ * ++ * Some of the internal functions ("__xxx") are useful when ++ * manipulating whole lists rather than single entries, as ++ * sometimes we already know the next/prev entries and we can ++ * generate better code by using them directly rather than ++ * using the generic single-entry routines. ++ */ ++ ++struct list_head { ++ struct list_head *next, *prev; ++}; ++ ++struct hlist_head { ++ struct hlist_node *first; ++}; ++ ++struct hlist_node { ++ struct hlist_node *next, **pprev; ++}; ++ ++typedef struct list_head list_t; ++ ++#define LIST_HEAD_INIT(name) { &(name), &(name) } ++ ++#define LIST_HEAD(name) \ ++ struct list_head name = LIST_HEAD_INIT(name) ++ ++#define INIT_LIST_HEAD(ptr) ({ (ptr)->next = (ptr); (ptr)->prev = (ptr); }) ++ ++/* ++ * Insert a new entry between two known consecutive entries. ++ * ++ * This is only for internal list manipulation where we know ++ * the prev/next entries already! ++ */ ++static inline void __list_add(struct list_head * new, ++ struct list_head * prev, ++ struct list_head * next) ++{ ++ next->prev = new; ++ new->next = next; ++ new->prev = prev; ++ WRITE_ONCE(prev->next, new); ++} ++ ++/** ++ * list_add - add a new entry ++ * @new: new entry to be added ++ * @head: list head to add it after ++ * ++ * Insert a new entry after the specified head. ++ * This is good for implementing stacks. ++ */ ++static inline void list_add(struct list_head *new, struct list_head *head) ++{ ++ __list_add(new, head, head->next); ++} ++ ++ ++/** ++ * list_add_tail - add a new entry ++ * @new: new entry to be added ++ * @head: list head to add it before ++ * ++ * Insert a new entry before the specified head. ++ * This is useful for implementing queues. ++ */ ++static inline void list_add_tail(struct list_head *new, struct list_head *head) ++{ ++ __list_add(new, head->prev, head); ++} ++ ++/* ++ * Delete a list entry by making the prev/next entries ++ * point to each other. ++ * ++ * This is only for internal list manipulation where we know ++ * the prev/next entries already! ++ */ ++static inline void __list_del(struct list_head * prev, struct list_head * next) ++{ ++ next->prev = prev; ++ WRITE_ONCE(prev->next, next); ++} ++ ++/** ++ * list_del - deletes entry from list. ++ * @entry: the element to delete from the list. ++ * Note: list_empty() on entry does not return true after this, the entry is ++ * in an undefined state. ++ */ ++static inline void __list_del_entry(struct list_head *entry) ++{ ++ __list_del(entry->prev, entry->next); ++} ++ ++static inline void list_del(struct list_head *entry) ++{ ++ __list_del_entry(entry); ++ entry->next = LIST_POISON1; ++ entry->prev = LIST_POISON2; ++} ++ ++/** ++ * list_replace - replace old entry by new one ++ * @old : the element to be replaced ++ * @new : the new element to insert ++ * ++ * If @old was empty, it will be overwritten. ++ */ ++static inline void list_replace(struct list_head *old, ++ struct list_head *new) ++{ ++ new->next = old->next; ++ new->next->prev = new; ++ new->prev = old->prev; ++ new->prev->next = new; ++} ++ ++static inline void list_replace_init(struct list_head *old, ++ struct list_head *new) ++{ ++ list_replace(old, new); ++ INIT_LIST_HEAD(old); ++} ++ ++/** ++ * list_del_init - deletes entry from list and reinitialize it. ++ * @entry: the element to delete from the list. ++ */ ++static inline void list_del_init(struct list_head *entry) ++{ ++ __list_del_entry(entry); ++ INIT_LIST_HEAD(entry); ++} ++ ++/** ++ * list_move - delete from one list and add as another's head ++ * @list: the entry to move ++ * @head: the head that will precede our entry ++ */ ++static inline void list_move(struct list_head *list, struct list_head *head) ++{ ++ __list_del_entry(list); ++ list_add(list, head); ++} ++ ++/** ++ * list_move_tail - delete from one list and add as another's tail ++ * @list: the entry to move ++ * @head: the head that will follow our entry ++ */ ++static inline void list_move_tail(struct list_head *list, ++ struct list_head *head) ++{ ++ __list_del_entry(list); ++ list_add_tail(list, head); ++} ++ ++/** ++ * list_bulk_move_tail - move a subsection of a list to its tail ++ * @head: the head that will follow our entry ++ * @first: first entry to move ++ * @last: last entry to move, can be the same as first ++ * ++ * Move all entries between @first and including @last before @head. ++ * All three entries must belong to the same linked list. ++ */ ++static inline void list_bulk_move_tail(struct list_head *head, ++ struct list_head *first, ++ struct list_head *last) ++{ ++ first->prev->next = last->next; ++ last->next->prev = first->prev; ++ ++ head->prev->next = first; ++ first->prev = head->prev; ++ ++ last->next = head; ++ head->prev = last; ++} ++ ++/** ++ * list_is_first -- tests whether @ list is the first entry in list @head ++ * @list: the entry to test ++ * @head: the head of the list ++ */ ++static inline int list_is_first(const struct list_head *list, ++ const struct list_head *head) ++{ ++ return list->prev == head; ++} ++ ++/** ++ * list_is_last - tests whether @list is the last entry in list @head ++ * @list: the entry to test ++ * @head: the head of the list ++ */ ++static inline int list_is_last(const struct list_head *list, ++ const struct list_head *head) ++{ ++ return list->next == head; ++} ++ ++/** ++ * list_empty - tests whether a list is empty ++ * @head: the list to test. ++ */ ++static inline int list_empty(const struct list_head *head) ++{ ++ return READ_ONCE(head->next) == head; ++} ++ ++/** ++ * list_empty_careful - tests whether a list is empty and not being modified ++ * @head: the list to test ++ * ++ * Description: ++ * tests whether a list is empty _and_ checks that no other CPU might be ++ * in the process of modifying either member (next or prev) ++ * ++ * NOTE: using list_empty_careful() without synchronization ++ * can only be safe if the only activity that can happen ++ * to the list entry is list_del_init(). Eg. it cannot be used ++ * if another CPU could re-list_add() it. ++ */ ++static inline int list_empty_careful(const struct list_head *head) ++{ ++ struct list_head *next = head->next; ++ return (next == head) && (next == head->prev); ++} ++ ++/** ++ * list_rotate_left - rotate the list to the left ++ * @head: the head of the list ++ */ ++static inline void list_rotate_left(struct list_head *head) ++{ ++ struct list_head *first; ++ ++ if (!list_empty(head)) { ++ first = head->next; ++ list_move_tail(first, head); ++ } ++} ++ ++/** ++ * list_is_singular - tests whether a list has just one entry. ++ * @head: the list to test. ++ */ ++static inline int list_is_singular(const struct list_head *head) ++{ ++ return !list_empty(head) && (head->next == head->prev); ++} ++ ++static inline void __list_cut_position(struct list_head *list, ++ struct list_head *head, struct list_head *entry) ++{ ++ struct list_head *new_first = entry->next; ++ list->next = head->next; ++ list->next->prev = list; ++ list->prev = entry; ++ entry->next = list; ++ head->next = new_first; ++ new_first->prev = head; ++} ++ ++/** ++ * list_cut_position - cut a list into two ++ * @list: a new list to add all removed entries ++ * @head: a list with entries ++ * @entry: an entry within head, could be the head itself ++ * and if so we won't cut the list ++ * ++ * This helper moves the initial part of @head, up to and ++ * including @entry, from @head to @list. You should ++ * pass on @entry an element you know is on @head. @list ++ * should be an empty list or a list you do not care about ++ * losing its data. ++ * ++ */ ++static inline void list_cut_position(struct list_head *list, ++ struct list_head *head, struct list_head *entry) ++{ ++ if (list_empty(head)) ++ return; ++ if (list_is_singular(head) && ++ (head->next != entry && head != entry)) ++ return; ++ if (entry == head) ++ INIT_LIST_HEAD(list); ++ else ++ __list_cut_position(list, head, entry); ++} ++ ++/** ++ * list_cut_before - cut a list into two, before given entry ++ * @list: a new list to add all removed entries ++ * @head: a list with entries ++ * @entry: an entry within head, could be the head itself ++ * ++ * This helper moves the initial part of @head, up to but ++ * excluding @entry, from @head to @list. You should pass ++ * in @entry an element you know is on @head. @list should ++ * be an empty list or a list you do not care about losing ++ * its data. ++ * If @entry == @head, all entries on @head are moved to ++ * @list. ++ */ ++static inline void list_cut_before(struct list_head *list, ++ struct list_head *head, ++ struct list_head *entry) ++{ ++ if (head->next == entry) { ++ INIT_LIST_HEAD(list); ++ return; ++ } ++ list->next = head->next; ++ list->next->prev = list; ++ list->prev = entry->prev; ++ list->prev->next = list; ++ head->next = entry; ++ entry->prev = head; ++} ++ ++static inline void __list_splice(const struct list_head *list, ++ struct list_head *prev, ++ struct list_head *next) ++{ ++ struct list_head *first = list->next; ++ struct list_head *last = list->prev; ++ ++ first->prev = prev; ++ prev->next = first; ++ ++ last->next = next; ++ next->prev = last; ++} ++ ++/** ++ * list_splice - join two lists, this is designed for stacks ++ * @list: the new list to add. ++ * @head: the place to add it in the first list. ++ */ ++static inline void list_splice(const struct list_head *list, ++ struct list_head *head) ++{ ++ if (!list_empty(list)) ++ __list_splice(list, head, head->next); ++} ++ ++/** ++ * list_splice_tail - join two lists, each list being a queue ++ * @list: the new list to add. ++ * @head: the place to add it in the first list. ++ */ ++static inline void list_splice_tail(struct list_head *list, ++ struct list_head *head) ++{ ++ if (!list_empty(list)) ++ __list_splice(list, head->prev, head); ++} ++ ++/** ++ * list_splice_init - join two lists and reinitialise the emptied list. ++ * @list: the new list to add. ++ * @head: the place to add it in the first list. ++ * ++ * The list at @list is reinitialised ++ */ ++static inline void list_splice_init(struct list_head *list, ++ struct list_head *head) ++{ ++ if (!list_empty(list)) { ++ __list_splice(list, head, head->next); ++ INIT_LIST_HEAD(list); ++ } ++} ++ ++/** ++ * list_splice_tail_init - join two lists and reinitialise the emptied list ++ * @list: the new list to add. ++ * @head: the place to add it in the first list. ++ * ++ * Each of the lists is a queue. ++ * The list at @list is reinitialised ++ */ ++static inline void list_splice_tail_init(struct list_head *list, ++ struct list_head *head) ++{ ++ if (!list_empty(list)) { ++ __list_splice(list, head->prev, head); ++ INIT_LIST_HEAD(list); ++ } ++} ++ ++/** ++ * list_entry - get the struct for this entry ++ * @ptr: the &struct list_head pointer. ++ * @type: the type of the struct this is embedded in. ++ * @member: the name of the list_head within the struct. ++ */ ++#define list_entry(ptr, type, member) \ ++ container_of(ptr, type, member) ++ ++/** ++ * list_first_entry - get the first element from a list ++ * @ptr: the list head to take the element from. ++ * @type: the type of the struct this is embedded in. ++ * @member: the name of the list_head within the struct. ++ * ++ * Note, that list is expected to be not empty. ++ */ ++#define list_first_entry(ptr, type, member) \ ++ list_entry((ptr)->next, type, member) ++ ++/** ++ * list_last_entry - get the last element from a list ++ * @ptr: the list head to take the element from. ++ * @type: the type of the struct this is embedded in. ++ * @member: the name of the list_head within the struct. ++ * ++ * Note, that list is expected to be not empty. ++ */ ++#define list_last_entry(ptr, type, member) \ ++ list_entry((ptr)->prev, type, member) ++ ++/** ++ * list_first_entry_or_null - get the first element from a list ++ * @ptr: the list head to take the element from. ++ * @type: the type of the struct this is embedded in. ++ * @member: the name of the list_head within the struct. ++ * ++ * Note that if the list is empty, it returns NULL. ++ */ ++#define list_first_entry_or_null(ptr, type, member) ({ \ ++ struct list_head *head__ = (ptr); \ ++ struct list_head *pos__ = READ_ONCE(head__->next); \ ++ pos__ != head__ ? list_entry(pos__, type, member) : NULL; \ ++}) ++ ++/** ++ * list_next_entry - get the next element in list ++ * @pos: the type * to cursor ++ * @member: the name of the list_head within the struct. ++ */ ++#define list_next_entry(pos, member) \ ++ list_entry((pos)->member.next, typeof(*(pos)), member) ++ ++/** ++ * list_prev_entry - get the prev element in list ++ * @pos: the type * to cursor ++ * @member: the name of the list_head within the struct. ++ */ ++#define list_prev_entry(pos, member) \ ++ list_entry((pos)->member.prev, typeof(*(pos)), member) ++ ++/** ++ * list_for_each - iterate over a list ++ * @pos: the &struct list_head to use as a loop cursor. ++ * @head: the head for your list. ++ */ ++#define list_for_each(pos, head) \ ++ for (pos = (head)->next; pos != (head); pos = pos->next) ++ ++/** ++ * list_for_each_prev - iterate over a list backwards ++ * @pos: the &struct list_head to use as a loop cursor. ++ * @head: the head for your list. ++ */ ++#define list_for_each_prev(pos, head) \ ++ for (pos = (head)->prev; pos != (head); pos = pos->prev) ++ ++/** ++ * list_for_each_safe - iterate over a list safe against removal of list entry ++ * @pos: the &struct list_head to use as a loop cursor. ++ * @n: another &struct list_head to use as temporary storage ++ * @head: the head for your list. ++ */ ++#define list_for_each_safe(pos, n, head) \ ++ for (pos = (head)->next, n = pos->next; pos != (head); \ ++ pos = n, n = pos->next) ++ ++/** ++ * list_for_each_prev_safe - iterate over a list backwards safe against removal of list entry ++ * @pos: the &struct list_head to use as a loop cursor. ++ * @n: another &struct list_head to use as temporary storage ++ * @head: the head for your list. ++ */ ++#define list_for_each_prev_safe(pos, n, head) \ ++ for (pos = (head)->prev, n = pos->prev; \ ++ pos != (head); \ ++ pos = n, n = pos->prev) ++ ++/** ++ * list_for_each_entry - iterate over list of given type ++ * @pos: the type * to use as a loop cursor. ++ * @head: the head for your list. ++ * @member: the name of the list_head within the struct. ++ */ ++#define list_for_each_entry(pos, head, member) \ ++ for (pos = list_first_entry(head, typeof(*pos), member); \ ++ &pos->member != (head); \ ++ pos = list_next_entry(pos, member)) ++ ++/** ++ * list_for_each_entry_reverse - iterate backwards over list of given type. ++ * @pos: the type * to use as a loop cursor. ++ * @head: the head for your list. ++ * @member: the name of the list_head within the struct. ++ */ ++#define list_for_each_entry_reverse(pos, head, member) \ ++ for (pos = list_last_entry(head, typeof(*pos), member); \ ++ &pos->member != (head); \ ++ pos = list_prev_entry(pos, member)) ++ ++/** ++ * list_prepare_entry - prepare a pos entry for use in list_for_each_entry_continue() ++ * @pos: the type * to use as a start point ++ * @head: the head of the list ++ * @member: the name of the list_head within the struct. ++ * ++ * Prepares a pos entry for use as a start point in list_for_each_entry_continue(). ++ */ ++#define list_prepare_entry(pos, head, member) \ ++ ((pos) ? : list_entry(head, typeof(*pos), member)) ++ ++/** ++ * list_for_each_entry_continue - continue iteration over list of given type ++ * @pos: the type * to use as a loop cursor. ++ * @head: the head for your list. ++ * @member: the name of the list_head within the struct. ++ * ++ * Continue to iterate over list of given type, continuing after ++ * the current position. ++ */ ++#define list_for_each_entry_continue(pos, head, member) \ ++ for (pos = list_next_entry(pos, member); \ ++ &pos->member != (head); \ ++ pos = list_next_entry(pos, member)) ++ ++/** ++ * list_for_each_entry_continue_reverse - iterate backwards from the given point ++ * @pos: the type * to use as a loop cursor. ++ * @head: the head for your list. ++ * @member: the name of the list_head within the struct. ++ * ++ * Start to iterate over list of given type backwards, continuing after ++ * the current position. ++ */ ++#define list_for_each_entry_continue_reverse(pos, head, member) \ ++ for (pos = list_prev_entry(pos, member); \ ++ &pos->member != (head); \ ++ pos = list_prev_entry(pos, member)) ++ ++/** ++ * list_for_each_entry_from - iterate over list of given type from the current point ++ * @pos: the type * to use as a loop cursor. ++ * @head: the head for your list. ++ * @member: the name of the list_head within the struct. ++ * ++ * Iterate over list of given type, continuing from current position. ++ */ ++#define list_for_each_entry_from(pos, head, member) \ ++ for (; &pos->member != (head); \ ++ pos = list_next_entry(pos, member)) ++ ++/** ++ * list_for_each_entry_from_reverse - iterate backwards over list of given type ++ * from the current point ++ * @pos: the type * to use as a loop cursor. ++ * @head: the head for your list. ++ * @member: the name of the list_head within the struct. ++ * ++ * Iterate backwards over list of given type, continuing from current position. ++ */ ++#define list_for_each_entry_from_reverse(pos, head, member) \ ++ for (; &pos->member != (head); \ ++ pos = list_prev_entry(pos, member)) ++ ++/** ++ * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry ++ * @pos: the type * to use as a loop cursor. ++ * @n: another type * to use as temporary storage ++ * @head: the head for your list. ++ * @member: the name of the list_head within the struct. ++ */ ++#define list_for_each_entry_safe(pos, n, head, member) \ ++ for (pos = list_first_entry(head, typeof(*pos), member), \ ++ n = list_next_entry(pos, member); \ ++ &pos->member != (head); \ ++ pos = n, n = list_next_entry(n, member)) ++ ++/** ++ * list_for_each_entry_safe_continue - continue list iteration safe against removal ++ * @pos: the type * to use as a loop cursor. ++ * @n: another type * to use as temporary storage ++ * @head: the head for your list. ++ * @member: the name of the list_head within the struct. ++ * ++ * Iterate over list of given type, continuing after current point, ++ * safe against removal of list entry. ++ */ ++#define list_for_each_entry_safe_continue(pos, n, head, member) \ ++ for (pos = list_next_entry(pos, member), \ ++ n = list_next_entry(pos, member); \ ++ &pos->member != (head); \ ++ pos = n, n = list_next_entry(n, member)) ++ ++/** ++ * list_for_each_entry_safe_from - iterate over list from current point safe against removal ++ * @pos: the type * to use as a loop cursor. ++ * @n: another type * to use as temporary storage ++ * @head: the head for your list. ++ * @member: the name of the list_head within the struct. ++ * ++ * Iterate over list of given type from current point, safe against ++ * removal of list entry. ++ */ ++#define list_for_each_entry_safe_from(pos, n, head, member) \ ++ for (n = list_next_entry(pos, member); \ ++ &pos->member != (head); \ ++ pos = n, n = list_next_entry(n, member)) ++ ++/** ++ * list_for_each_entry_safe_reverse - iterate backwards over list safe against removal ++ * @pos: the type * to use as a loop cursor. ++ * @n: another type * to use as temporary storage ++ * @head: the head for your list. ++ * @member: the name of the list_head within the struct. ++ * ++ * Iterate backwards over list of given type, safe against removal ++ * of list entry. ++ */ ++#define list_for_each_entry_safe_reverse(pos, n, head, member) \ ++ for (pos = list_last_entry(head, typeof(*pos), member), \ ++ n = list_prev_entry(pos, member); \ ++ &pos->member != (head); \ ++ pos = n, n = list_prev_entry(n, member)) ++ ++/** ++ * list_safe_reset_next - reset a stale list_for_each_entry_safe loop ++ * @pos: the loop cursor used in the list_for_each_entry_safe loop ++ * @n: temporary storage used in list_for_each_entry_safe ++ * @member: the name of the list_head within the struct. ++ * ++ * list_safe_reset_next is not safe to use in general if the list may be ++ * modified concurrently (eg. the lock is dropped in the loop body). An ++ * exception to this is if the cursor element (pos) is pinned in the list, ++ * and list_safe_reset_next is called after re-taking the lock and before ++ * completing the current iteration of the loop body. ++ */ ++#define list_safe_reset_next(pos, n, member) \ ++ n = list_next_entry(pos, member) ++ ++/* ++ * Count the number of items in a list ++ */ ++static inline int list_count_entries(struct list_head *head) ++{ ++ struct list_head *pos; ++ int n = 0; ++ list_for_each(pos, head) ++ n++; ++ return n; ++} ++ ++/* ++ * Sort a list with cmp() ++ * creates a temporary array on the heap ++ */ ++static inline int ++list_sort(struct list_head *head, ++ int (*cmp)(const void *a, const void *b, void *state), ++ void *state) ++{ ++ struct list_head **array = NULL, *pos; ++ unsigned int nmemb = 0; ++ ++ /* ++ * This always allocates in page-sized units to avoid realloc actually ++ * doing anything most of the time. On 64-bit machines we'll do an ++ * allocation for every 512 entries. ++ */ ++ const size_t pgcnt = 4096 / sizeof(void *); ++ ++ array = calloc(ALIGN_UP(1, pgcnt), sizeof(void *)); ++ if (!array) ++ return -1; ++ ++ list_for_each(pos, head) { ++ struct list_head **new_array; ++ size_t newmemb = ALIGN_UP(nmemb + 1, pgcnt); ++ ++ new_array = reallocarray(array, newmemb, sizeof(*new_array)); ++ if (!new_array) { ++ if (array) ++ free(array); ++ return -1; ++ } ++ array = new_array; ++ array[nmemb++] = pos; ++ } ++ ++ qsort_r(array, nmemb, sizeof(*array), cmp, state); ++ ++ INIT_LIST_HEAD(head); ++ for (unsigned int i = 0; i < nmemb; i++) { ++ INIT_LIST_HEAD(array[i]); ++ list_add(array[i], head); ++ } ++ free(array); ++ ++ return 0; ++} ++ ++/* ++ * Double linked lists with a single pointer list head. ++ * Mostly useful for hash tables where the two pointer list head is ++ * too wasteful. ++ * You lose the ability to access the tail in O(1). ++ */ ++ ++#define HLIST_HEAD_INIT { .first = NULL } ++#define HLIST_HEAD(name) struct hlist_head name = { .first = NULL } ++#define INIT_HLIST_HEAD(ptr) ((ptr)->first = NULL) ++static inline void INIT_HLIST_NODE(struct hlist_node *h) ++{ ++ h->next = NULL; ++ h->pprev = NULL; ++} ++ ++static inline int hlist_unhashed(const struct hlist_node *h) ++{ ++ return !h->pprev; ++} ++ ++static inline int hlist_empty(const struct hlist_head *h) ++{ ++ return !READ_ONCE(h->first); ++} ++ ++static inline void __hlist_del(struct hlist_node *n) ++{ ++ struct hlist_node *next = n->next; ++ struct hlist_node **pprev = n->pprev; ++ ++ WRITE_ONCE(*pprev, next); ++ if (next) ++ next->pprev = pprev; ++} ++ ++static inline void hlist_del(struct hlist_node *n) ++{ ++ __hlist_del(n); ++ n->next = LIST_POISON1; ++ n->pprev = LIST_POISON2; ++} ++ ++static inline void hlist_del_init(struct hlist_node *n) ++{ ++ if (!hlist_unhashed(n)) { ++ __hlist_del(n); ++ INIT_HLIST_NODE(n); ++ } ++} ++ ++static inline void hlist_add_head(struct hlist_node *n, struct hlist_head *h) ++{ ++ struct hlist_node *first = h->first; ++ n->next = first; ++ if (first) ++ first->pprev = &n->next; ++ WRITE_ONCE(h->first, n); ++ n->pprev = &h->first; ++} ++ ++/* next must be != NULL */ ++static inline void hlist_add_before(struct hlist_node *n, ++ struct hlist_node *next) ++{ ++ n->pprev = next->pprev; ++ n->next = next; ++ next->pprev = &n->next; ++ WRITE_ONCE(*(n->pprev), n); ++} ++ ++static inline void hlist_add_behind(struct hlist_node *n, ++ struct hlist_node *prev) ++{ ++ n->next = prev->next; ++ WRITE_ONCE(prev->next, n); ++ n->pprev = &prev->next; ++ ++ if (n->next) ++ n->next->pprev = &n->next; ++} ++ ++/* after that we'll appear to be on some hlist and hlist_del will work */ ++static inline void hlist_add_fake(struct hlist_node *n) ++{ ++ n->pprev = &n->next; ++} ++ ++static inline bool hlist_fake(struct hlist_node *h) ++{ ++ return h->pprev == &h->next; ++} ++ ++/* ++ * Check whether the node is the only node of the head without ++ * accessing head: ++ */ ++static inline bool ++hlist_is_singular_node(struct hlist_node *n, struct hlist_head *h) ++{ ++ return !n->next && n->pprev == &h->first; ++} ++ ++/* ++ * Move a list from one list head to another. Fixup the pprev ++ * reference of the first entry if it exists. ++ */ ++static inline void hlist_move_list(struct hlist_head *old, ++ struct hlist_head *new) ++{ ++ new->first = old->first; ++ if (new->first) ++ new->first->pprev = &new->first; ++ old->first = NULL; ++} ++ ++#define hlist_entry(ptr, type, member) container_of(ptr,type,member) ++ ++#define hlist_for_each(pos, head) \ ++ for (pos = (head)->first; pos ; pos = pos->next) ++ ++#define hlist_for_each_safe(pos, n, head) \ ++ for (pos = (head)->first; pos && ({ n = pos->next; 1; }); \ ++ pos = n) ++ ++#define hlist_entry_safe(ptr, type, member) \ ++ ({ typeof(ptr) ____ptr = (ptr); \ ++ ____ptr ? hlist_entry(____ptr, type, member) : NULL; \ ++ }) ++ ++/** ++ * hlist_for_each_entry - iterate over list of given type ++ * @pos: the type * to use as a loop cursor. ++ * @head: the head for your list. ++ * @member: the name of the hlist_node within the struct. ++ */ ++#define hlist_for_each_entry(pos, head, member) \ ++ for (pos = hlist_entry_safe((head)->first, typeof(*(pos)), member);\ ++ pos; \ ++ pos = hlist_entry_safe((pos)->member.next, typeof(*(pos)), member)) ++ ++/** ++ * hlist_for_each_entry_continue - iterate over a hlist continuing after current point ++ * @pos: the type * to use as a loop cursor. ++ * @member: the name of the hlist_node within the struct. ++ */ ++#define hlist_for_each_entry_continue(pos, member) \ ++ for (pos = hlist_entry_safe((pos)->member.next, typeof(*(pos)), member);\ ++ pos; \ ++ pos = hlist_entry_safe((pos)->member.next, typeof(*(pos)), member)) ++ ++/** ++ * hlist_for_each_entry_from - iterate over a hlist continuing from current point ++ * @pos: the type * to use as a loop cursor. ++ * @member: the name of the hlist_node within the struct. ++ */ ++#define hlist_for_each_entry_from(pos, member) \ ++ for (; pos; \ ++ pos = hlist_entry_safe((pos)->member.next, typeof(*(pos)), member)) ++ ++/** ++ * hlist_for_each_entry_safe - iterate over list of given type safe against removal of list entry ++ * @pos: the type * to use as a loop cursor. ++ * @n: another &struct hlist_node to use as temporary storage ++ * @head: the head for your list. ++ * @member: the name of the hlist_node within the struct. ++ */ ++#define hlist_for_each_entry_safe(pos, n, head, member) \ ++ for (pos = hlist_entry_safe((head)->first, typeof(*pos), member);\ ++ pos && ({ n = pos->member.next; 1; }); \ ++ pos = hlist_entry_safe(n, typeof(*pos), member)) ++ ++#endif +diff --git a/src/util.h b/src/util.h +index 917a7d2d73f..362c3559293 100644 +--- a/src/util.h ++++ b/src/util.h +@@ -19,6 +19,8 @@ + #ifndef PESIGN_UTIL_H + #define PESIGN_UTIL_H 1 + ++#include ++#include + #include + #include + #include +@@ -28,8 +30,15 @@ + #include + + #include "compiler.h" ++#include "list.h" + +-#define xfree(x) ({if (x) { free(x); x = NULL; }}) ++#define xfree(x) ({ if (x) { free(x); x = NULL; } }) ++#define xclose(fd) ({ if ((fd) >= 0) { close(fd); (fd) = -1; } }) ++#define xopen(path, flags, args...) ({ int fd_ = open(path, flags, ## args); if (fd_ < 0) liberr(1, "Could not open file \"%s\"", arg); fd_; }) ++#define xrealloc(o, s) ({ void *o_ = realloc(o, s); if (!o_) liberr(1, "Could not allocate %zd bytes", (size_t)s); o_; }) ++#define xcalloc(n, s) ({ void *p_ = calloc(n, s); if (!p_) liberr(1, "Could not allocate %lu entries of %lu bytes", (unsigned long)n, (unsigned long)s); p_; }) ++#define xstrdup(s) ({ void *p_ = strdup(s); if (!p_) liberr(1, "Could not allocate memory"); p_; }) ++#define xpfstat(path, fd, sb) ({ int rc_ = fstat(fd, sb); if (rc_ < 0) liberr(1, "Could not stat \"%s\"", path); }) + + #define save_errno(x) \ + ({ \ +@@ -44,17 +53,43 @@ + __libpe_seterrno(__saved_errno); \ + }) + ++#define conderr(cond, val, fmt, args...) ({ \ ++ if (cond) \ ++ err(val, fmt, ## args); \ ++ }) ++#define conderrx(cond, val, fmt, args...) ({ \ ++ if (cond) \ ++ errx(val, fmt, ## args); \ ++ }) ++ ++#define condwarn(cond, fmt, args...) ({ \ ++ if (cond) \ ++ warn(fmt, ## args); \ ++ }) ++#define condwarnx(cond, fmt, args...) ({ \ ++ if (cond) \ ++ warnx(fmt, ## args); \ ++ }) ++ + #define nsserr(rv, fmt, args...) ({ \ + errx((rv), "%s:%s:%d: " fmt ": %s", \ + __FILE__, __func__, __LINE__, ##args, \ + PORT_ErrorToString(PORT_GetError())); \ + }) ++#define condnsserr(cond, rv, fmt, args...) ({ \ ++ if ((cond)) \ ++ nsserr(rv, fmt, ## args); \ ++ }) + #define nssreterr(rv, fmt, args...) ({ \ + fprintf(stderr, "%s:%s:%d: " fmt ": %s\n", \ + __FILE__, __func__, __LINE__, ##args, \ + PORT_ErrorToString(PORT_GetError())); \ + return rv; \ + }) ++#define condnssreterr(cond, rv, fmt, args...) ({ \ ++ if ((cond)) \ ++ nssreterr(rv, fmt, ## args); \ ++ }) + #define liberr(rv, fmt, args...) ({ \ + err((rv), "%s:%s:%d: " fmt, \ + __FILE__, __func__, __LINE__, ##args); \ +diff --git a/src/wincert.h b/src/wincert.h +index fc8dc7d9e7c..d0d2b3fe6bf 100644 +--- a/src/wincert.h ++++ b/src/wincert.h +@@ -61,6 +61,4 @@ extern int finalize_signatures(SECItem **sigs, int num_sigs, Pe *pe); + extern size_t get_reserved_sig_space(cms_context *cms, Pe *pe); + extern ssize_t get_sigspace_extend_amount(cms_context *cms, Pe *pe, SECItem *sig); + +-#define ALIGNMENT_PADDING(address, align) ((align - (address % align)) % align) +- + #endif /* PESIGN_WINCERT_H */ +-- +2.29.2 + diff --git a/0007-Add-hex-utilities.patch b/0007-Add-hex-utilities.patch new file mode 100644 index 0000000..b9bfc0e --- /dev/null +++ b/0007-Add-hex-utilities.patch @@ -0,0 +1,65 @@ +From 2fd010b0edc814e46955c85a7ec2cfa8c12a7862 Mon Sep 17 00:00:00 2001 +From: Peter Jones +Date: Mon, 3 Feb 2020 15:42:52 -0500 +Subject: [PATCH 07/42] Add hex utilities. + +Signed-off-by: Peter Jones +--- + src/hex.h | 45 +++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 45 insertions(+) + create mode 100644 src/hex.h + +diff --git a/src/hex.h b/src/hex.h +new file mode 100644 +index 00000000000..24014eb3056 +--- /dev/null ++++ b/src/hex.h +@@ -0,0 +1,45 @@ ++// SPDX-License-Identifier: GPLv2 ++/* ++ * hex.h - hexidecimal conversion helpers ++ * Copyright Peter Jones ++ */ ++#ifndef HEX_H_ ++#define HEX_H_ ++ ++static inline uint8_t hexchar_to_bin(char hex) ++{ ++ if (hex >= '0' && hex <= '9') ++ return hex - '0'; ++ if (hex >= 'A' && hex <= 'F') ++ return hex - 'A' + 10; ++ if (hex >= 'a' && hex <= 'f') ++ return hex - 'a' + 10; ++ return -1; ++} ++ ++static inline int ++hex_to_bin(const char *hex, uint8_t *out, size_t size) ++{ ++ for (size_t i = 0, j = 0; j < size; i+= 2, j++) { ++ uint8_t val; ++ ++ val = hexchar_to_bin(hex[i]); ++ if (val > 15) ++ goto out_of_range; ++ out[j] = (val & 0xf) << 4; ++ ++ val = hexchar_to_bin(hex[i+1]); ++ if (val > 15) ++ goto out_of_range; ++ out[j] |= val & 0xf; ++ } ++ ++ errno = 0; ++ return 0; ++out_of_range: ++ errno = ERANGE; ++ return -1; ++} ++ ++#endif /* !HEX_H_ */ ++// vim:fenc=utf-8:tw=75:noet +-- +2.29.2 + diff --git a/0008-Add-some-text-parsing-helpers.patch b/0008-Add-some-text-parsing-helpers.patch new file mode 100644 index 0000000..1489a93 --- /dev/null +++ b/0008-Add-some-text-parsing-helpers.patch @@ -0,0 +1,367 @@ +From 2cd818c0ef885276cc66ff39bcbe01a90d385db8 Mon Sep 17 00:00:00 2001 +From: Peter Jones +Date: Mon, 22 Jun 2020 10:35:22 -0400 +Subject: [PATCH 08/42] Add some text parsing helpers + +Signed-off-by: Peter Jones +--- + src/text.c | 259 +++++++++++++++++++++++++++++++++++++++++++++++++++ + src/pesign.h | 1 + + src/text.h | 53 +++++++++++ + src/Makefile | 2 +- + 4 files changed, 314 insertions(+), 1 deletion(-) + create mode 100644 src/text.c + create mode 100644 src/text.h + +diff --git a/src/text.c b/src/text.c +new file mode 100644 +index 00000000000..e463e8d05eb +--- /dev/null ++++ b/src/text.c +@@ -0,0 +1,259 @@ ++// SPDX-License-Identifier: GPLv2 ++/* ++ * text.c - helpers for text strings ++ * Copyright Peter Jones ++ */ ++#include "compiler.h" ++#include "text.h" ++ ++#include ++#include ++#include ++#include ++ ++const char * const eol_chars = "\f\r\v\n"; ++// static const char * const whitespace_chars = "\t "; ++const char * const whitespace_and_eol_chars = "\t \f\r\v\n"; ++ ++// static const char * const binary_digits = "01"; ++static const char * const octal_digits = "01234567"; ++// static const char * const decimal_digits = "0123456789"; ++static const char * const hex_digits = "0123456789abcdefABCDEF"; ++ ++static const char * const cnt_nl = "\\\n"; ++static const char * const cnt_lfnl = "\\\r\n"; ++static const char * const cnt_lf = "\\\r"; ++static const char * const cnt_ff = "\\\f"; ++static const char * const cnt_vt = "\\\v"; ++ ++static const char * const line_continuation_strs[] = { ++ cnt_nl, ++ cnt_lfnl, ++ cnt_lf, ++ cnt_ff, ++ cnt_vt, ++ NULL ++}; ++ ++/* ++ * unbreak_line_coninutations: remove all line continuations ++ * @buf: the buffer to operate on ++ * @bufsz: the size of the buffer ++ */ ++void ++unbreak_line_continuations(char *buf, size_t bufsz) ++{ ++ char *to = buf; ++ bool found = true; ++ ++ while (found) { ++ found = false; ++ ++ for (unsigned int i = 0; line_continuation_strs[i]; i++) { ++ size_t cntsz = strlen(line_continuation_strs[i]); ++ char *needle = strstr(to, line_continuation_strs[i]); ++ char *from; ++ size_t sz; ++ ++ if (!needle) ++ continue; ++ ++ found = true; ++ from = needle + cntsz; ++ sz = bufsz - (from - buf); ++ ++ to = needle; ++ memmove(to, from, sz); ++ } ++ } ++} ++ ++/* ++ * stresccspn: calculate the number of bytes which do not contain escape ++ * sequences. ++ * @buf: the buffer to search ++ * ++ * Returns the size of the initial segment of buf which does not contain ++ * any escape sequences. If no escape sequence is found, buf[return] will ++ * point to the NUL terminator. ++ */ ++size_t stresccspn(const char * const buf) ++{ ++ size_t span = strcspn(buf, "\\"); ++ ++ return span; ++} ++ ++/* ++ * escape_func: parse the value for one single escape character ++ * @delimiter: the delimiter as to which kind of escape sequence this is ++ * (i.e. 'x' for \x1abc) ++ * @buf: the buffer being parsed ++ * @val: the parsed value is placed in val ++ * @valsz: how many bytes of val are meaningful ++ * ++ * Returns the number of bytes of buf to advance to skip the escape ++ * sequence, including the delimiter character but not the initial escape ++ * character. If the initial segment of buf is not an escape sequence, ++ * *valsz and the return value will both be 0. ++ */ ++typedef size_t (*escape_func)(uint32_t delimiter, const char * const buf, ++ char val[9], size_t *valsz); ++ ++static size_t ++simple_escape_sequence(uint32_t delimiter, const char * const buf UNUSED, ++ char val[9], size_t *valsz) ++{ ++ val[0] = delimiter & 0xffu; ++ *valsz = 1; ++ ++ return 1; ++} ++ ++static size_t ++digits_escape_sequence(uint32_t delimiter, const char * const buf, ++ char val[2], size_t *valsz) ++{ ++ size_t span; ++ unsigned long long ul; ++ char tmpbuf[4] = { 0, }; ++ int base; ++ ++ if (delimiter == 'x') { ++ span = strspn(buf, hex_digits); ++ base = 16; ++ if (span > 2) ++ span = 2; ++ strncpy(tmpbuf, buf, span); ++ } else { ++ span = strspn(buf, octal_digits); ++ base = 8; ++ if (span > 2) ++ span = 2; ++ tmpbuf[0] = delimiter & 0xffu; ++ strncpy(&tmpbuf[1], buf, span); ++ span += 1; ++ } ++ if (span == 0) { ++ val[0] = delimiter & 0xffu; ++ *valsz = 1; ++ return 1; ++ } ++ ++ tmpbuf[span+1] = '\0'; ++ ul = strtoul(tmpbuf, NULL, base); ++ ++ val[0] = ul & 0xffu; ++ *valsz = 1; ++ ++ return span; ++} ++ ++struct escape_handler { ++ const char * const escapes; ++ escape_func func; ++}; ++static struct escape_handler escape_handlers[] = { ++ {.escapes = " \"\'\?\a\b\f\n\r\t\v\\", ++ .func = simple_escape_sequence }, ++ {.escapes = "x01234567", ++ .func = digits_escape_sequence }, ++ {.escapes = 0, ++ .func = NULL } ++}; ++ ++/* ++ * parse_escape: parses one escape string ++ * @buf: the buffer being parsed ++ * @val: the parsed value is placed in val ++ * @valsz: how many bytes of val are meaningful ++ * ++ * Returns the number of bytes of buf to advance to skip the escape ++ * sequence. If the initial segment of buf is not an escape sequence, ++ * *valsz and the return value will both be 0. ++ */ ++static size_t ++parse_escape(const char * const buf, char val[9], size_t *valsz) ++{ ++ struct escape_handler *eh = NULL; ++ ++ if (buf[0] != '\\') ++ return 0; ++ ++ for(size_t i = 0; escape_handlers[i].escapes != 0; i++) { ++ char *match; ++ eh = &escape_handlers[i]; ++ ++ match = strchrnul(eh->escapes, buf[1]); ++ if (match[0] != buf[1]) ++ continue; ++ } ++ if (eh && eh->func) ++ return eh->func(buf[1], &buf[2], val, valsz); ++ return 0; ++} ++ ++/* ++ * strescspn: calculate the size of an escape sequence. ++ * @buf: a NUL-terminated utf-8 buffer. ++ * ++ * returns the number of bytes which are part of a single escape sequence. ++ * If no escape sequnce can be parsed, returns 0. ++ */ ++size_t strescspn(const char * const buf) ++{ ++ size_t advance = 0, valsz = 0; ++ char val[9] = { 0, }; ++ ++ if (!buf[0] || buf[0] != '\\') ++ return 0; ++ ++ advance = parse_escape(&buf[1], val, &valsz); ++ if (advance == 0) { ++ /* ++ * If we come to illegal escape values like "\\xzz" then ++ * we just use the delimiter character (in this case 'x'), ++ * so the span here is 2. ++ */ ++ return 2; ++ } ++ return valsz + 1; ++} ++ ++/* ++ * resolve_escapes: parse all instances of escape sequences in buf ++ * @buf: the buffer to operate on ++ * ++ * Returns the size of buf once escape sequnces have been replaced. ++ */ ++size_t ++resolve_escapes(char *buf) ++{ ++ size_t to = 0; ++ for (size_t from = 0; buf[from]; from++) { ++ size_t advance, valsz = 0; ++ char val[9]; ++ if (buf[from] != '\\') { ++ buf[to++] = buf[from]; ++ continue; ++ } ++ ++ advance = parse_escape(&buf[from], val, &valsz); ++ if (advance == 0) { ++ /* ++ * If we come to illegal escape values like "\\xzz" ++ * then just move the '\\' out of the way... ++ */ ++ buf[to++] = buf[++from]; ++ continue; ++ } ++ ++ for (size_t j = 0; j < valsz; j++) ++ buf[to+j] = val[j]; ++ to += advance + 1; ++ } ++ buf[to++] = '\0'; ++ return to; ++} ++ ++// vim:fenc=utf-8:tw=75:noet +diff --git a/src/pesign.h b/src/pesign.h +index 9f80a9ad108..1b404223d31 100644 +--- a/src/pesign.h ++++ b/src/pesign.h +@@ -25,6 +25,7 @@ + #include + + #include "util.h" ++#include "text.h" + #include "cms_common.h" + #include "pesign_context.h" + +diff --git a/src/text.h b/src/text.h +new file mode 100644 +index 00000000000..e5722c7aee1 +--- /dev/null ++++ b/src/text.h +@@ -0,0 +1,53 @@ ++// SPDX-License-Identifier: GPLv2 ++/* ++ * text.c - helpers for text strings ++ * Copyright Peter Jones ++ */ ++#ifndef TEXT_H_ ++#define TEXT_H_ ++ ++#include ++ ++/* ++ * Characters that can be considered whitespace or end-of-line markers. ++ */ ++extern const char * const eol_chars; ++extern const char * const whitespace_and_eol_chars; ++ ++/* ++ * unbreak_line_coninutations: remove all line continuations ++ * @buf: the buffer to operate on ++ * @bufsz: the size of the buffer ++ */ ++extern void unbreak_line_continuations(char *buf, size_t bufsz); ++ ++/* ++ * strescspn: calculate the size of an escape sequence. ++ * @buf: a NUL-terminated utf-8 buffer. ++ * ++ * returns the number of bytes which are part of a single escape sequence. ++ * If no escape sequnce can be parsed, returns 0. ++ */ ++extern size_t strescspn(const char * const buf); ++ ++/* ++ * stresccspn: calculate the number of bytes which do not contain escape ++ * sequences. ++ * @buf: the buffer to search ++ * ++ * Returns the size of the initial segment of buf which does not contain ++ * any escape sequences. If no escape sequence is found, buf[return] will ++ * point to the NUL terminator. ++ */ ++extern size_t stresccspn(const char * const buf); ++ ++/* ++ * resolve_escapes: parse all instances of escape sequences in buf ++ * @buf: the buffer to operate on ++ * ++ * Returns the size of buf once escape sequnces have been replaced. ++ */ ++extern size_t resolve_escapes(char *buf); ++ ++#endif /* !TEXT_H_ */ ++// vim:fenc=utf-8:tw=75:noet +diff --git a/src/Makefile b/src/Makefile +index 74327ba13f3..dfdc7c5e4c5 100644 +--- a/src/Makefile ++++ b/src/Makefile +@@ -12,7 +12,7 @@ TARGETS=$(BINTARGETS) $(SVCTARGETS) + all : deps $(TARGETS) + + COMMON_SOURCES = cms_common.c content_info.c oid.c password.c \ +- signed_data.c signer_info.c ucs2.c ++ signed_data.c signer_info.c text.c ucs2.c + COMMON_PE_SOURCES = wincert.c cms_pe_common.c + AUTHVAR_SOURCES = authvar.c authvar_context.c + CLIENT_SOURCES = pesign_context.c actions.c client.c +-- +2.29.2 + diff --git a/0009-libdpe-fix-some-minor-analyzer-discoveries.patch b/0009-libdpe-fix-some-minor-analyzer-discoveries.patch new file mode 100644 index 0000000..0174d86 --- /dev/null +++ b/0009-libdpe-fix-some-minor-analyzer-discoveries.patch @@ -0,0 +1,113 @@ +From d6787fbed0a1f993af6418c758c781361d553219 Mon Sep 17 00:00:00 2001 +From: Peter Jones +Date: Wed, 29 Apr 2020 18:23:30 -0400 +Subject: [PATCH 09/42] libdpe: fix some minor analyzer discoveries. + +I don't think we can meaningfully hit any of these in any use that +actually matters, but may as well fix them. + +Signed-off-by: Peter Jones +--- + libdpe/pe_begin.c | 3 +++ + libdpe/pe_getdatadir.c | 2 +- + libdpe/pe_opthdr.c | 12 ++++++------ + include/libdpe/libdpe.h | 4 ++-- + 4 files changed, 12 insertions(+), 9 deletions(-) + +diff --git a/libdpe/pe_begin.c b/libdpe/pe_begin.c +index 51189f8069c..3bcc2c70c61 100644 +--- a/libdpe/pe_begin.c ++++ b/libdpe/pe_begin.c +@@ -156,6 +156,9 @@ __libpe_read_mmapped_file(int fildes, void *map_address, size_t maxsize, + case PE_K_PE_EXE: + return file_read_pe_exe(fildes, map_address, p_ident, + maxsize, cmd, parent); ++ case PE_K_MZ: ++ errno = ENOSYS; ++ return NULL; + default: + break; + } +diff --git a/libdpe/pe_getdatadir.c b/libdpe/pe_getdatadir.c +index 08f46787304..f080f3a9998 100644 +--- a/libdpe/pe_getdatadir.c ++++ b/libdpe/pe_getdatadir.c +@@ -24,7 +24,7 @@ pe_getdatadir(Pe *pe, data_directory **dd) + { + int rc = -1; + +- if (!dd) { ++ if (!pe || !dd) { + __libpe_seterrno(PE_E_INVALID_INDEX); + return rc; + } +diff --git a/libdpe/pe_opthdr.c b/libdpe/pe_opthdr.c +index 02075e5cd49..ae74a897500 100644 +--- a/libdpe/pe_opthdr.c ++++ b/libdpe/pe_opthdr.c +@@ -32,7 +32,7 @@ pe_getopthdr(Pe *pe) + } + } + +-uint32_t ++int32_t + pe_get_file_alignment(Pe *pe) + { + struct pe32_opt_hdr *pe32opthdr = NULL; +@@ -42,12 +42,12 @@ pe_get_file_alignment(Pe *pe) + case PE_K_PE_EXE: { + void *opthdr = pe_getopthdr(pe); + pe32opthdr = opthdr; +- return pe32opthdr->file_align; ++ return pe32opthdr ? (int32_t)pe32opthdr->file_align : -1; + } + case PE_K_PE64_EXE: { + void *opthdr = pe_getopthdr(pe); + pe64opthdr = opthdr; +- return pe64opthdr->file_align; ++ return pe64opthdr ? (int32_t)pe64opthdr->file_align : -1; + break; + } + default: +@@ -56,7 +56,7 @@ pe_get_file_alignment(Pe *pe) + return -1; + } + +-uint32_t ++int32_t + pe_get_scn_alignment(Pe *pe) + { + struct pe32_opt_hdr *pe32opthdr = NULL; +@@ -66,12 +66,12 @@ pe_get_scn_alignment(Pe *pe) + case PE_K_PE_EXE: { + void *opthdr = pe_getopthdr(pe); + pe32opthdr = opthdr; +- return pe32opthdr->section_align; ++ return pe32opthdr ? (int32_t)pe32opthdr->section_align : -1; + } + case PE_K_PE64_EXE: { + void *opthdr = pe_getopthdr(pe); + pe64opthdr = opthdr; +- return pe64opthdr->section_align; ++ return pe64opthdr ? (int32_t)pe64opthdr->section_align : -1; + break; + } + default: +diff --git a/include/libdpe/libdpe.h b/include/libdpe/libdpe.h +index 09f56a2a05e..895a208fe7d 100644 +--- a/include/libdpe/libdpe.h ++++ b/include/libdpe/libdpe.h +@@ -87,8 +87,8 @@ extern struct pe_hdr *pe_getpehdr(Pe *pe, struct pe_hdr *pehdr); + extern char *pe_rawfile(Pe *pe, size_t *ptr); + extern int pe_getdatadir(Pe *pe, data_directory **dd); + extern void *pe_getopthdr(Pe *pe); +-extern uint32_t pe_get_file_alignment(Pe *pe); +-extern uint32_t pe_get_scn_alignment(Pe *pe); ++extern int32_t pe_get_file_alignment(Pe *pe); ++extern int32_t pe_get_scn_alignment(Pe *pe); + extern int pe_set_image_size(Pe *pe); + + extern int pe_extend_file(Pe *pe, size_t size, uint32_t *new_space, int align); +-- +2.29.2 + diff --git a/0010-libdpe-check-for-NULL-pe-at-more-places.patch b/0010-libdpe-check-for-NULL-pe-at-more-places.patch new file mode 100644 index 0000000..f0e32fd --- /dev/null +++ b/0010-libdpe-check-for-NULL-pe-at-more-places.patch @@ -0,0 +1,132 @@ +From 8677eea21fc9b634b6b97e132a8c4295f2a9aa15 Mon Sep 17 00:00:00 2001 +From: Peter Jones +Date: Thu, 21 May 2020 14:27:01 -0400 +Subject: [PATCH 10/42] libdpe: check for NULL pe at more places. + +This isn't so much to fix a bug as to make "gcc -Wanalyze-..." output +smaller where these things are called. + +Signed-off-by: Peter Jones +--- + libdpe/pe_addcert.c | 17 +++++++++++++++++ + libdpe/pe_allocspace.c | 19 +++++++++++++++++++ + libdpe/libdpe_priv.h | 2 ++ + 3 files changed, 38 insertions(+) + +diff --git a/libdpe/pe_addcert.c b/libdpe/pe_addcert.c +index 803ed61f7f0..b1251992ade 100644 +--- a/libdpe/pe_addcert.c ++++ b/libdpe/pe_addcert.c +@@ -17,6 +17,7 @@ + * Author(s): Peter Jones + */ + #include ++ + #include "libdpe_priv.h" + + int +@@ -25,6 +26,11 @@ pe_clearcert(Pe *pe) + int rc; + data_directory *dd = NULL; + ++ if (!pe) { ++ errno = EINVAL; ++ return -1; ++ } ++ + rc = pe_getdatadir(pe, &dd); + if (rc < 0) + return rc; +@@ -43,6 +49,11 @@ pe_alloccert(Pe *pe, size_t size) + int rc; + data_directory *dd = NULL; + ++ if (!pe) { ++ errno = EINVAL; ++ return -1; ++ } ++ + pe_clearcert(pe); + + uint32_t new_space = 0; +@@ -69,6 +80,12 @@ pe_populatecert(Pe *pe, void *cert, size_t size) + { + int rc; + data_directory *dd = NULL; ++ ++ if (!pe) { ++ errno = EINVAL; ++ return -1; ++ } ++ + rc = pe_getdatadir(pe, &dd); + if (rc < 0) + return rc; +diff --git a/libdpe/pe_allocspace.c b/libdpe/pe_allocspace.c +index a2898f6d446..be704c52cf8 100644 +--- a/libdpe/pe_allocspace.c ++++ b/libdpe/pe_allocspace.c +@@ -56,6 +56,11 @@ pe_fix_addresses(Pe *pe, int64_t offset) + int + pe_set_image_size(Pe *pe) + { ++ if (!pe) { ++ errno = EINVAL; ++ return -1; ++ } ++ + uint32_t image_size = 0; + struct pe_hdr *pehdr = pe->state.pe.pehdr; + struct pe32plus_opt_hdr *opthdr = pe->state.pe32plus_exe.opthdr; +@@ -86,6 +91,11 @@ pe_set_image_size(Pe *pe) + int + pe_extend_file(Pe *pe, size_t size, uint32_t *new_space, int align) + { ++ if (!pe) { ++ errno = EINVAL; ++ return -1; ++ } ++ + void *new = NULL; + + if (align) +@@ -120,6 +130,10 @@ pe_shorten_file(Pe *pe, size_t size) + { + void *new = NULL; + ++ if (!pe) { ++ errno = EINVAL; ++ return -1; ++ } + new = mremap(pe->map_address, pe->maximum_size, + pe->maximum_size - size, 0); + if (new == MAP_FAILED) { +@@ -138,6 +152,11 @@ pe_shorten_file(Pe *pe, size_t size) + int + pe_freespace(Pe *pe, uint32_t offset, size_t size) + { ++ if (!pe) { ++ errno = EINVAL; ++ return -1; ++ } ++ + void *addr = compute_mem_addr(pe, offset); + memset(addr, '\0', size); + +diff --git a/libdpe/libdpe_priv.h b/libdpe/libdpe_priv.h +index 26e50498c1d..e207772097a 100644 +--- a/libdpe/libdpe_priv.h ++++ b/libdpe/libdpe_priv.h +@@ -19,7 +19,9 @@ + #ifndef LIBDPE_PRIV_H + #define LIBDPE_PRIV_H 1 + ++#include + #include ++ + #include "compiler.h" + #include "endian.h" + +-- +2.29.2 + diff --git a/0011-wincert-try-to-convince-the-gcc-analyzer-of-the-pain.patch b/0011-wincert-try-to-convince-the-gcc-analyzer-of-the-pain.patch new file mode 100644 index 0000000..f946508 --- /dev/null +++ b/0011-wincert-try-to-convince-the-gcc-analyzer-of-the-pain.patch @@ -0,0 +1,36 @@ +From b4de3e4891be5f4de2c9a19740fc48c3bc28c68f Mon Sep 17 00:00:00 2001 +From: Peter Jones +Date: Thu, 21 May 2020 15:23:11 -0400 +Subject: [PATCH 11/42] wincert: try to convince the gcc analyzer of the + painfully obvious. + +Signed-off-by: Peter Jones +--- + src/wincert.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +diff --git a/src/wincert.c b/src/wincert.c +index 4ccf528efad..7c802d22025 100644 +--- a/src/wincert.c ++++ b/src/wincert.c +@@ -364,9 +364,16 @@ err: + if (signatures) { + for (i = 0; i < nsigs; i++) { + if (signatures[i]) { +- if (signatures[i]->data) ++ if (signatures[i]->data) /* <-- see below */ + free(signatures[i]->data); + free(signatures[i]); ++ /* ++ * in gcc-10.1.1-1.fc32 , -fanalyzer believes the test ++ * above is a use-after free. I really don't see how, ++ * but this somehow convinces it there's nothing wrong ++ * there. ++ */ ++ signatures[i] = NULL; + } + } + free(signatures); +-- +2.29.2 + diff --git a/0012-Fix-a-missing-malloc-return-value-check.patch b/0012-Fix-a-missing-malloc-return-value-check.patch new file mode 100644 index 0000000..a380aef --- /dev/null +++ b/0012-Fix-a-missing-malloc-return-value-check.patch @@ -0,0 +1,26 @@ +From 998e825efd44d3f5098022537f7967c24d208841 Mon Sep 17 00:00:00 2001 +From: Peter Jones +Date: Fri, 5 Jun 2020 10:20:30 -0400 +Subject: [PATCH 12/42] Fix a missing malloc() return value check. + +Signed-off-by: Peter Jones +--- + src/pesigcheck.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/src/pesigcheck.c b/src/pesigcheck.c +index 8fa0f1ad03d..961a32a6ad7 100644 +--- a/src/pesigcheck.c ++++ b/src/pesigcheck.c +@@ -116,6 +116,8 @@ cert_matches_digest(pesigcheck_context *ctx, void *data, ssize_t datalen, + digest = content->data + content->len - pe_digest->len; + if (digest_out) { + digest_out->data = malloc(pe_digest->len); ++ if (!digest_out->data) ++ goto out; + digest_out->len = pe_digest->len; + digest_out->type = pe_digest->type; + memcpy(digest_out->data, digest, pe_digest->len); +-- +2.29.2 + diff --git a/0013-Fix-some-missed-OOM-error-path-fanalyzer-found.patch b/0013-Fix-some-missed-OOM-error-path-fanalyzer-found.patch new file mode 100644 index 0000000..2451c9c --- /dev/null +++ b/0013-Fix-some-missed-OOM-error-path-fanalyzer-found.patch @@ -0,0 +1,67 @@ +From 1f81f3ec196365d6bdf490d05776ba7a4e0257b0 Mon Sep 17 00:00:00 2001 +From: Peter Jones +Date: Thu, 21 May 2020 15:23:54 -0400 +Subject: [PATCH 13/42] Fix some missed OOM error path -fanalyzer found. + +Amazingly, it seems to find more *real* problems (surprisingly) *and* +present them more readably (not surprisingly at all) without -flto. + +Signed-off-by: Peter Jones +--- + src/actions.c | 19 +++++++++---------- + 1 file changed, 9 insertions(+), 10 deletions(-) + +diff --git a/src/actions.c b/src/actions.c +index 69f9e3e1c1a..d0f538e81d4 100644 +--- a/src/actions.c ++++ b/src/actions.c +@@ -68,8 +68,8 @@ insert_signature(cms_context *cms, int signum) + sizeof (SECItem *) * (cms->num_signatures + 1)); + if (!signatures) { + err: +- cms->log(cms, LOG_ERR, "insert signature: could not allocate " +- "memory: %m"); ++ cms->log(cms, LOG_ERR, ++ "insert signature: could not allocate memory: %m"); + exit(1); + } + cms->signatures = signatures; +@@ -80,6 +80,9 @@ err: + } + + SECItem *newsig = malloc(sizeof (*newsig)); ++ if (!newsig) ++ goto err; ++ + memcpy(newsig, sig, sizeof (*newsig)); + newsig->data = malloc(sig->len); + if (!newsig->data) +@@ -293,10 +296,8 @@ parse_signature(pesign_context *ctx) + size_t siglen; + + rc = read_file(ctx->insigfd, &sig, &siglen); +- if (rc < 0) { +- fprintf(stderr, "pesign: could not read signature.\n"); +- exit(1); +- } ++ if (rc < 0) ++ liberr(1, "pesign: could not read signature"); + + unsigned char *der; + unsigned int derlen; +@@ -306,10 +307,8 @@ parse_signature(pesign_context *ctx) + if (base64) { + base64 += strlen(sig_begin_marker); + char *end = strstr(base64, sig_end_marker); +- if (!end) { +- fprintf(stderr, "pesign: Invalid signature.\n"); +- exit(1); +- } ++ if (!end) ++ liberr(1, "pesign: Invalid signature"); + + derlen = end - base64; + base64[derlen] = '\0'; +-- +2.29.2 + diff --git a/0014-Don-t-allow-or-require-module-or-kernel-with-ca.patch b/0014-Don-t-allow-or-require-module-or-kernel-with-ca.patch new file mode 100644 index 0000000..cb7e17f --- /dev/null +++ b/0014-Don-t-allow-or-require-module-or-kernel-with-ca.patch @@ -0,0 +1,189 @@ +From d14dce18a8fa31e2097d99a717d87b23539b9098 Mon Sep 17 00:00:00 2001 +From: Peter Jones +Date: Wed, 15 May 2019 15:55:17 -0400 +Subject: [PATCH 14/42] Don't allow (or require) --module or --kernel with + --ca. + +If you're doing a CA/signer split setup, the CA shouldn't be allowed to +sign things other than other certificates. + +Signed-off-by: Peter Jones +--- + src/efikeygen.c | 55 ++++++++++++++++++++++++++++++++----------------- + src/efikeygen.1 | 6 ++++-- + 2 files changed, 40 insertions(+), 21 deletions(-) + +diff --git a/src/efikeygen.c b/src/efikeygen.c +index 848480a9b01..b8b0c961739 100644 +--- a/src/efikeygen.c ++++ b/src/efikeygen.c +@@ -54,6 +54,13 @@ + #include "cms_common.h" + #include "oid.h" + ++enum { ++ MODSIGN_EKU_NONE, ++ MODSIGN_EKU_KERNEL, ++ MODSIGN_EKU_MODULE, ++ MODSIGN_EKU_CA ++}; ++ + typedef struct { + SECItem data; + SECAlgorithmID keytype; +@@ -183,8 +190,7 @@ add_key_usage(cms_context *cms, void *extHandle, int is_ca) + + if (is_ca) { + usage = KU_KEY_CERT_SIGN | +- KU_CRL_SIGN | +- KU_DIGITAL_SIGNATURE; ++ KU_CRL_SIGN; + } else { + usage = KU_KEY_ENCIPHERMENT | + KU_DATA_ENCIPHERMENT | +@@ -252,7 +258,7 @@ add_basic_constraints(cms_context *cms, void *extHandle) + } + + static int +-add_extended_key_usage(cms_context *cms, int modsign_only, void *extHandle) ++add_extended_key_usage(cms_context *cms, int modsign_eku, void *extHandle) + { + SECItem values[2]; + SECItem wrapped = { 0 }; +@@ -260,7 +266,11 @@ add_extended_key_usage(cms_context *cms, int modsign_only, void *extHandle) + SECOidTag tag; + int rc; + +- if (modsign_only < 1 || modsign_only > 2) ++ if (modsign_eku == MODSIGN_EKU_CA) ++ return 0; ++ ++ if (modsign_eku != MODSIGN_EKU_KERNEL ++ && modsign_eku != MODSIGN_EKU_MODULE) + cmsreterr(-1, cms, "could not encode extended key usage"); + + rc = make_eku_oid(cms, &values[0], SEC_OID_EXT_KEY_USAGE_CODE_SIGN); +@@ -273,11 +283,10 @@ add_extended_key_usage(cms_context *cms, int modsign_only, void *extHandle) + if (rc < 0) + cmsreterr(-1, cms, "could not encode extended key usage"); + +- rc = wrap_in_seq(cms, &wrapped, values, modsign_only); ++ rc = wrap_in_seq(cms, &wrapped, values, modsign_eku); + if (rc < 0) + cmsreterr(-1, cms, "could not encode extended key usage"); + +- + status = CERT_AddExtension(extHandle, SEC_OID_X509_EXT_KEY_USAGE, + &wrapped, PR_FALSE, PR_TRUE); + if (status != SECSuccess) +@@ -311,7 +320,7 @@ static int + add_extensions_to_crq(cms_context *cms, CERTCertificateRequest *crq, + int is_ca, int is_self_signed, SECKEYPublicKey *pubkey, + SECKEYPublicKey *spubkey, +- char *url, int modsign_only) ++ char *url, int modsign_eku) + { + void *mark = PORT_ArenaMark(cms->arena); + +@@ -336,7 +345,7 @@ add_extensions_to_crq(cms_context *cms, CERTCertificateRequest *crq, + if (rc < 0) + cmsreterr(-1, cms, "could not generate certificate extensions"); + +- rc = add_extended_key_usage(cms, modsign_only, extHandle); ++ rc = add_extended_key_usage(cms, modsign_eku, extHandle); + if (rc < 0) + cmsreterr(-1, cms, "could not generate certificate extensions"); + +@@ -486,7 +495,7 @@ int main(int argc, char *argv[]) + { + int is_ca = 0; + int is_self_signed = -1; +- int modsign_only = 0; ++ int modsign_eku = MODSIGN_EKU_NONE; + char *tokenname = "NSS Certificate DB"; + char *signer = NULL; + char *nickname = NULL; +@@ -543,14 +552,14 @@ int main(int argc, char *argv[]) + {.longName = "kernel", + .shortName = 'k', + .argInfo = POPT_ARG_VAL|POPT_ARGFLAG_OR, +- .arg = &modsign_only, +- .val = 1, ++ .arg = &modsign_eku, ++ .val = MODSIGN_EKU_KERNEL, + .descrip = "Generate a kernel-signing certificate" }, + {.longName = "module", + .shortName = 'm', + .argInfo = POPT_ARG_VAL|POPT_ARGFLAG_OR, +- .arg = &modsign_only, +- .val = 2, ++ .arg = &modsign_eku, ++ .val = MODSIGN_EKU_MODULE, + .descrip = "Generate a module-signing certificate" }, + {.longName = "nickname", + .shortName = 'n', +@@ -622,10 +631,12 @@ int main(int argc, char *argv[]) + /* + * Scenarios that are okay (x == valid combination) + * +- * is_ca is_self_signed pubkey +- * i_c x x x +- * i_s_s x x o +- * pubkey x o o ++ * is_ca is_self_signed pubkey modules kernel ++ * i_c x x x o o ++ * i_s_s x x o o o ++ * pubkey x o x x x ++ * modules o x x x x ++ * kernel o x x x x + */ + + if (is_self_signed == -1) +@@ -660,8 +671,14 @@ int main(int argc, char *argv[]) + liberr(1, "could not allocate cms context"); + } + +- if (modsign_only < 1 || modsign_only > 2) ++ if (is_ca) { ++ if (modsign_eku != MODSIGN_EKU_NONE) ++ errx(1, "CA certificates cannot have kernel or module signing credentials."); ++ modsign_eku = MODSIGN_EKU_CA; ++ } else if (modsign_eku != MODSIGN_EKU_KERNEL ++ && modsign_eku != MODSIGN_EKU_MODULE) { + errx(1, "either --kernel or --module must be used"); ++ } + + SECStatus status = NSS_InitReadWrite(dbdir); + if (status != SECSuccess) +@@ -752,7 +769,7 @@ int main(int argc, char *argv[]) + crq = CERT_CreateCertificateRequest(name, spki, &attributes); + + rc = add_extensions_to_crq(cms, crq, is_ca, is_self_signed, pubkey, +- spubkey, url, modsign_only); ++ spubkey, url, modsign_eku); + if (rc < 0) + exit(1); + +diff --git a/src/efikeygen.1 b/src/efikeygen.1 +index 255fadc3979..88ee7c2f7c0 100644 +--- a/src/efikeygen.1 ++++ b/src/efikeygen.1 +@@ -33,11 +33,13 @@ Nickname of certificate to be used to sign the generated certificate. + + .TP + \fB-\-kernel\fR +-The generated certificate is to be used to sign kernels. ++The generated certificate is to be used to sign kernels. Not to be used for CA ++certificates. + + .TP + \fB-\-module\fR +-The generated certificate is to be used to sign kernel modules. ++The generated certificate is to be used to sign kernel modules. Not to be used ++for CA certificates. + + .TP + \fB-\-token\fR=\fItoken\fR +-- +2.29.2 + diff --git a/0015-Add-super-convenient-errno-guard-implementation.patch b/0015-Add-super-convenient-errno-guard-implementation.patch new file mode 100644 index 0000000..7e43d2b --- /dev/null +++ b/0015-Add-super-convenient-errno-guard-implementation.patch @@ -0,0 +1,331 @@ +From af3e0b8857825d68dde9661b74c382279e90c512 Mon Sep 17 00:00:00 2001 +From: Peter Jones +Date: Fri, 17 May 2019 13:47:14 -0400 +Subject: [PATCH 15/42] Add super convenient errno-guard implementation. + +This confuses the gcc analyzer either less or far more than +save_errno()'s fire-once loop. + +Signed-off-by: Peter Jones +--- + src/certdb.c | 32 ++++++++++++++--------- + src/cms_common.c | 4 ++- + src/efikeygen.c | 1 + + src/errno-guard.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++ + src/errno-guard.h | 26 +++++++++++++++++++ + src/pesigcheck.h | 1 + + src/pesign.h | 2 ++ + src/util.h | 19 ++++---------- + src/Makefile | 9 +++++-- + 9 files changed, 131 insertions(+), 29 deletions(-) + create mode 100644 src/errno-guard.c + create mode 100644 src/errno-guard.h + +diff --git a/src/certdb.c b/src/certdb.c +index 9a4aae45f1d..f1eee3bf490 100644 +--- a/src/certdb.c ++++ b/src/certdb.c +@@ -40,21 +40,23 @@ add_db_file(pesigcheck_context *ctx, db_specifier which, const char *dbfile, + db_f_type type) + { + dblist *db = calloc(1, sizeof (dblist)); ++ int errno_guard; + + if (!db) + return -1; + + db->type = type; + db->fd = open(dbfile, O_RDONLY); ++ set_errno_guard_with_override(&errno_guard); + if (db->fd < 0) { +- save_errno(free(db)); ++ free(db); + return -1; + } + + char *path = strdup(dbfile); + if (!path) { +- save_errno(close(db->fd); +- free(db)); ++ override_errno_guard(&errno_guard, errno); ++ free(db); + return -1; + } + +@@ -62,17 +64,19 @@ add_db_file(pesigcheck_context *ctx, db_specifier which, const char *dbfile, + db->path = strdup(db->path); + free(path); + if (!db->path) { +- save_errno(close(db->fd); +- free(db)); ++ override_errno_guard(&errno_guard, errno); ++ close(db->fd); ++ free(db); + return -1; + } + + struct stat sb; + int rc = fstat(db->fd, &sb); + if (rc < 0) { +- save_errno(close(db->fd); +- free(db->path); +- free(db)); ++ override_errno_guard(&errno_guard, errno); ++ close(db->fd); ++ free(db->path); ++ free(db); + return -1; + } + db->size = sb.st_size; +@@ -83,9 +87,10 @@ add_db_file(pesigcheck_context *ctx, db_specifier which, const char *dbfile, + size_t sz = 0; + rc = read_file(db->fd, (char **)&db->map, &sz); + if (rc < 0) { +- save_errno(close(db->fd); +- free(db->path); +- free(db)); ++ override_errno_guard(&errno_guard, errno); ++ close(db->fd); ++ free(db->path); ++ free(db); + return -1; + } + } +@@ -108,8 +113,10 @@ add_db_file(pesigcheck_context *ctx, db_specifier which, const char *dbfile, + db->datalen = db->size + sizeof(EFI_SIGNATURE_LIST) + + sizeof(efi_guid_t); + db->data = calloc(1, db->datalen); +- if (!db->data) ++ if (!db->data) { ++ override_errno_guard(&errno_guard, errno); + return -1; ++ } + + certlist = (EFI_SIGNATURE_LIST *)db->data; + memcpy((void *)&certlist->SignatureType, &efi_x509, sizeof(efi_guid_t)); +@@ -129,6 +136,7 @@ add_db_file(pesigcheck_context *ctx, db_specifier which, const char *dbfile, + db->next = *tmp; + *tmp = db; + ++ override_errno_guard(&errno_guard, 0); + return 0; + } + +diff --git a/src/cms_common.c b/src/cms_common.c +index d13b2cb0f33..17f7bf252c7 100644 +--- a/src/cms_common.c ++++ b/src/cms_common.c +@@ -241,7 +241,9 @@ cms_context_alloc(cms_context **cmsp) + + int rc = cms_context_init(cms); + if (rc < 0) { +- save_errno(free(cms)); ++ set_errno_guard(); ++ xfree(cms); ++ cms = NULL; + return -1; + } + *cmsp = cms; +diff --git a/src/efikeygen.c b/src/efikeygen.c +index b8b0c961739..ac2ce45a420 100644 +--- a/src/efikeygen.c ++++ b/src/efikeygen.c +@@ -52,6 +52,7 @@ + + #include "util.h" + #include "cms_common.h" ++#include "errno-guard.h" + #include "oid.h" + + enum { +diff --git a/src/errno-guard.c b/src/errno-guard.c +new file mode 100644 +index 00000000000..331692d8d70 +--- /dev/null ++++ b/src/errno-guard.c +@@ -0,0 +1,66 @@ ++/* ++ * errno-guard.c ++ * Copyright 2019 Peter Jones ++ * ++ */ ++#ifndef _GNU_SOURCE ++#define _GNU_SOURCE ++#endif ++ ++#include ++#include ++ ++#include "compiler.h" ++#include "errno-guard.h" ++ ++__thread int errno_guards_[ERRNO_GUARD_ENTRIES_]; ++__thread int errno_guard_no_ = -1; ++ ++void ++clean_up_errno_guard_(int *handle) ++{ ++ if (*handle < 0 ++ || *handle >= ERRNO_GUARD_ENTRIES_ ++ || *handle > errno_guard_no_) ++ return; ++ ++ if (errno_guards_[*handle] >= 0) { ++ errno = errno_guards_[*handle]; ++ errno_guard_no_ = *handle - 1; ++ } ++ *handle = -1; ++} ++ ++int ++set_up_errno_guard_(int *handle) ++{ ++ int guard_var = ++errno_guard_no_; ++ ++ if (guard_var < ERRNO_GUARD_ENTRIES_) ++ errno_guards_[guard_var] = errno; ++ ++ if (handle) ++ *handle = guard_var; ++ return guard_var; ++} ++ ++int ++override_errno_guard(int *handle, int error) ++{ ++ if (handle == NULL ++ || *handle < 0 ++ || *handle >= ERRNO_GUARD_ENTRIES_) ++ return -1; ++ ++ if (*handle > errno_guard_no_) { ++ *handle = -1; ++ return -1; ++ } ++ ++ errno = error; ++ errno_guard_no_ = *handle; ++ ++ return *handle; ++} ++ ++// vim:fenc=utf-8:tw=75:noet +diff --git a/src/errno-guard.h b/src/errno-guard.h +new file mode 100644 +index 00000000000..e413cec95a4 +--- /dev/null ++++ b/src/errno-guard.h +@@ -0,0 +1,26 @@ ++/* ++ * errno-guard.h ++ * Copyright 2019 Peter Jones ++ */ ++ ++#ifndef ERRNO_GUARD_H_ ++#define ERRNO_GUARD_H_ ++ ++#define ERRNO_GUARD_ENTRIES_ ((int)(4096 / sizeof(int))) ++ ++extern __thread int errno_guards_[ERRNO_GUARD_ENTRIES_]; ++extern __thread int errno_guard_no_; ++ ++extern void clean_up_errno_guard_(int *handle); ++extern int set_up_errno_guard_(int *handle); ++ ++#define guard_errno_(handle, guard_var) \ ++ CLEANUP_FUNC(clean_up_errno_guard_) UNUSED int guard_var = set_up_errno_guard_(handle) ++#define errno_guard_var_ CAT(CAT(CAT(CAT(errno_guard_,__LINE__),_),__COUNTER__),_) ++ ++extern int override_errno_guard(int *handle, int error); ++#define set_errno_guard() guard_errno_(NULL, errno_guard_var_) ++#define set_errno_guard_with_override(handle) guard_errno_(handle, errno_guard_var_) ++ ++#endif /* !ERRNO_GUARD_H_ */ ++// vim:fenc=utf-8:tw=75:noet +diff --git a/src/pesigcheck.h b/src/pesigcheck.h +index 20e8040cc06..e4dbe54c59a 100644 +--- a/src/pesigcheck.h ++++ b/src/pesigcheck.h +@@ -29,6 +29,7 @@ + #include "certdb.h" + + #include "endian.h" ++#include "errno-guard.h" + #include "oid.h" + #include "wincert.h" + #include "content_info.h" +diff --git a/src/pesign.h b/src/pesign.h +index 1b404223d31..91d30b57c02 100644 +--- a/src/pesign.h ++++ b/src/pesign.h +@@ -32,7 +32,9 @@ + #include "daemon.h" + #include "efitypes.h" + #include "actions.h" ++#include "errno-guard.h" + #include "endian.h" ++#include "errno-guard.h" + #include "oid.h" + #include "wincert.h" + #include "content_info.h" +diff --git a/src/util.h b/src/util.h +index 362c3559293..1b115a993f6 100644 +--- a/src/util.h ++++ b/src/util.h +@@ -23,9 +23,8 @@ + #include + #include + #include +-#include + #include +-#include ++#include + + #include + +@@ -40,18 +39,10 @@ + #define xstrdup(s) ({ void *p_ = strdup(s); if (!p_) liberr(1, "Could not allocate memory"); p_; }) + #define xpfstat(path, fd, sb) ({ int rc_ = fstat(fd, sb); if (rc_ < 0) liberr(1, "Could not stat \"%s\"", path); }) + +-#define save_errno(x) \ +- ({ \ +- typeof (errno) __saved_errno = errno; \ +- x; \ +- errno = __saved_errno; \ +- }) +-#define save_pe_errno(x) \ +- ({ \ +- typeof (errno) __saved_errno = pe_errno(); \ +- x; \ +- __libpe_seterrno(__saved_errno); \ +- }) ++#define saved_errno_0_ CONCATENATE(CONCATENATE(error_,__LINE__),_0_) ++#define saved_errno_1_ CONCATENATE(CONCATENATE(error_,__LINE__),_1_) ++#define save_pe_errno() \ ++ for (int saved_errno_0_ = 0, saved_errno_1_ = pe_errno(); saved_errno_0_ < 1; saved_errno_0_++, __libdpe_seterrno(saved_errno_1_)) + + #define conderr(cond, val, fmt, args...) ({ \ + if (cond) \ +diff --git a/src/Makefile b/src/Makefile +index dfdc7c5e4c5..bc3e5931456 100644 +--- a/src/Makefile ++++ b/src/Makefile +@@ -11,8 +11,13 @@ TARGETS=$(BINTARGETS) $(SVCTARGETS) + + all : deps $(TARGETS) + +-COMMON_SOURCES = cms_common.c content_info.c oid.c password.c \ +- signed_data.c signer_info.c text.c ucs2.c ++COMMON_SOURCES = cms_common.c content_info.c \ ++ errno-guard.c \ ++ oid.c \ ++ password.c \ ++ signed_data.c signer_info.c \ ++ text.c \ ++ ucs2.c + COMMON_PE_SOURCES = wincert.c cms_pe_common.c + AUTHVAR_SOURCES = authvar.c authvar_context.c + CLIENT_SOURCES = pesign_context.c actions.c client.c +-- +2.29.2 + diff --git a/0016-Make-save_port_err-saner-to-read.patch b/0016-Make-save_port_err-saner-to-read.patch new file mode 100644 index 0000000..713cbc2 --- /dev/null +++ b/0016-Make-save_port_err-saner-to-read.patch @@ -0,0 +1,343 @@ +From d2b39d942ab696d8aaf11280f4b037142ebc3643 Mon Sep 17 00:00:00 2001 +From: Peter Jones +Date: Fri, 17 May 2019 14:04:48 -0400 +Subject: [PATCH 16/42] Make save_port_err() { } saner to read. + +Signed-off-by: Peter Jones +--- + src/cms_common.c | 65 ++++++++++++++++++++++++++++++++++------------- + src/signed_data.c | 39 ++++++++++++++++++++-------- + src/cms_common.h | 14 +++++----- + 3 files changed, 83 insertions(+), 35 deletions(-) + +diff --git a/src/cms_common.c b/src/cms_common.c +index 17f7bf252c7..9218f69ef9e 100644 +--- a/src/cms_common.c ++++ b/src/cms_common.c +@@ -350,7 +350,9 @@ unlock_nss_token(cms_context *cms) + PK11SlotListElement *psle = NULL; + psle = PK11_GetFirstSafe(slots); + if (!psle) { +- save_port_err(PK11_FreeSlotList(slots)); ++ save_port_err() { ++ PK11_FreeSlotList(slots); ++ } + cmsreterr(-1, cms, "could not get pk11 safe"); + } + +@@ -362,7 +364,9 @@ unlock_nss_token(cms_context *cms) + } + + if (!psle) { +- save_port_err(PK11_FreeSlotList(slots)); ++ save_port_err() { ++ PK11_FreeSlotList(slots); ++ } + cms->log(cms, LOG_ERR, "could not find token \"%s\"", + cms->tokenname); + return -1; +@@ -406,7 +410,9 @@ find_certificate(cms_context *cms, int needs_private_key) + PK11SlotListElement *psle = NULL; + psle = PK11_GetFirstSafe(slots); + if (!psle) { +- save_port_err(PK11_FreeSlotList(slots)); ++ save_port_err() { ++ PK11_FreeSlotList(slots); ++ } + cmsreterr(-1, cms, "could not get pk11 safe"); + } + +@@ -418,7 +424,9 @@ find_certificate(cms_context *cms, int needs_private_key) + } + + if (!psle) { +- save_port_err(PK11_FreeSlotList(slots)); ++ save_port_err() { ++ PK11_FreeSlotList(slots); ++ } + cms->log(cms, LOG_ERR, "could not find token \"%s\"", + cms->tokenname); + return -1; +@@ -439,9 +447,10 @@ find_certificate(cms_context *cms, int needs_private_key) + CERTCertList *certlist = NULL; + certlist = PK11_ListCertsInSlot(psle->slot); + if (!certlist) { +- save_port_err( ++ save_port_err() { + PK11_DestroySlotListElement(slots, &psle); +- PK11_FreeSlotList(slots)); ++ PK11_FreeSlotList(slots); ++ } + cmsreterr(-1, cms, "could not get certificate list"); + } + +@@ -466,10 +475,11 @@ find_certificate(cms_context *cms, int needs_private_key) + &cbdata); + } + if (status != SECSuccess || cbdata.cert == NULL) { +- save_port_err( ++ save_port_err() { + CERT_DestroyCertList(certlist); + PK11_DestroySlotListElement(slots, &psle); +- PK11_FreeSlotList(slots)); ++ PK11_FreeSlotList(slots); ++ } + cmsreterr(-1, cms, "could not find certificate in list"); + } + +@@ -502,7 +512,9 @@ find_slot_for_token(cms_context *cms, PK11SlotInfo **slot) + PK11SlotListElement *psle = NULL; + psle = PK11_GetFirstSafe(slots); + if (!psle) { +- save_port_err(PK11_FreeSlotList(slots)); ++ save_port_err() { ++ PK11_FreeSlotList(slots); ++ } + cmsreterr(-1, cms, "could not get pk11 safe"); + } + +@@ -514,7 +526,9 @@ find_slot_for_token(cms_context *cms, PK11SlotInfo **slot) + } + + if (!psle) { +- save_port_err(PK11_FreeSlotList(slots)); ++ save_port_err() { ++ PK11_FreeSlotList(slots); ++ } + cms->log(cms, LOG_ERR, "could not find token \"%s\"", + cms->tokenname); + return -1; +@@ -555,7 +569,9 @@ find_named_certificate(cms_context *cms, char *name, CERTCertificate **cert) + PK11SlotListElement *psle = NULL; + psle = PK11_GetFirstSafe(slots); + if (!psle) { +- save_port_err(PK11_FreeSlotList(slots)); ++ save_port_err() { ++ PK11_FreeSlotList(slots); ++ } + cmsreterr(-1, cms, "could not get pk11 safe"); + } + +@@ -567,7 +583,9 @@ find_named_certificate(cms_context *cms, char *name, CERTCertificate **cert) + } + + if (!psle) { +- save_port_err(PK11_FreeSlotList(slots)); ++ save_port_err() { ++ PK11_FreeSlotList(slots); ++ } + cms->log(cms, LOG_ERR, "could not find token \"%s\"", + cms->tokenname); + return -1; +@@ -588,9 +606,10 @@ find_named_certificate(cms_context *cms, char *name, CERTCertificate **cert) + CERTCertList *certlist = NULL; + certlist = PK11_ListCertsInSlot(psle->slot); + if (!certlist) { +- save_port_err( ++ save_port_err() { + PK11_DestroySlotListElement(slots, &psle); +- PK11_FreeSlotList(slots)); ++ PK11_FreeSlotList(slots); ++ } + cmsreterr(-1, cms, "could not get certificate list"); + } + +@@ -1158,7 +1177,9 @@ wrap_in_seq(cms_context *cms, SECItem *der, SECItem *items, int num_items) + int rc = 0; + ret = SEC_ASN1EncodeItem(cms->arena, der, items, tmpl); + if (ret == NULL) { +- save_port_err(PORT_ArenaRelease(cms->arena, mark)); ++ save_port_err() { ++ PORT_ArenaRelease(cms->arena, mark); ++ } + cmsreterr(-1, cms, "could not encode set"); + } + PORT_ArenaUnmark(cms->arena, mark); +@@ -1261,7 +1282,9 @@ generate_ava(cms_context *cms, SECItem *der, CERTAVA *certava) + + oid = SECOID_FindOID(&certava->type); + if (!oid) { +- save_port_err(PORT_FreeArena(arena, PR_TRUE)); ++ save_port_err() { ++ PORT_FreeArena(arena, PR_TRUE); ++ } + cms->arena = real_arena; + cmsreterr(-1, cms, "could not find OID"); + } +@@ -1279,7 +1302,9 @@ generate_ava(cms_context *cms, SECItem *der, CERTAVA *certava) + SECItem tmp; + ret = SEC_ASN1EncodeItem(arena, &tmp, &ava, AVATemplate); + if (ret == NULL) { +- save_port_err(PORT_FreeArena(arena, PR_TRUE)); ++ save_port_err() { ++ PORT_FreeArena(arena, PR_TRUE); ++ } + cms->arena = real_arena; + cmsreterr(-1, cms, "could not encode AVA"); + } +@@ -1288,7 +1313,9 @@ generate_ava(cms_context *cms, SECItem *der, CERTAVA *certava) + der->len = tmp.len; + der->data = PORT_ArenaAlloc(real_arena, tmp.len); + if (!der->data) { +- save_port_err(PORT_FreeArena(arena, PR_TRUE)); ++ save_port_err() { ++ PORT_FreeArena(arena, PR_TRUE); ++ } + cms->arena = real_arena; + cmsreterr(-1, cms, "could not allocate AVA"); + } +@@ -1479,3 +1506,5 @@ generate_keys(cms_context *cms, PK11SlotInfo *slot, + cmsreterr(-1, cms, "could not generate RSA keypair"); + return 0; + } ++ ++// vim:fenc=utf-8:tw=75:noet +diff --git a/src/signed_data.c b/src/signed_data.c +index af3a84ff4ab..c6dff5481bb 100644 +--- a/src/signed_data.c ++++ b/src/signed_data.c +@@ -81,14 +81,18 @@ generate_certificate_list(cms_context *cms, SECItem ***certificate_list_p) + + certificates = PORT_ArenaZAlloc(cms->arena, sizeof (SECItem *) * 3); + if (!certificates) { +- save_port_err(PORT_ArenaRelease(cms->arena, mark)); ++ save_port_err() { ++ PORT_ArenaRelease(cms->arena, mark); ++ } + cmsreterr(-1, cms, "could not allocate certificate list"); + } + int i = 0; + + certificates[i] = PORT_ArenaZAlloc(cms->arena, sizeof (SECItem)); + if (!certificates[i]) { +- save_port_err(PORT_ArenaRelease(cms->arena, mark)); ++ save_port_err() { ++ PORT_ArenaRelease(cms->arena, mark); ++ } + cmsreterr(-1, cms, "could not allocate certificate entry"); + } + SECITEM_CopyItem(cms->arena, certificates[i++], &cms->cert->derCert); +@@ -106,8 +110,9 @@ generate_certificate_list(cms_context *cms, SECItem ***certificate_list_p) + certificates[i] = PORT_ArenaZAlloc(cms->arena, + sizeof (SECItem)); + if (!certificates[i]) { +- save_port_err( +- PORT_ArenaRelease(cms->arena, mark)); ++ save_port_err() { ++ PORT_ArenaRelease(cms->arena, mark); ++ } + cmsreterr(-1, cms,"could not allocate " + "certificate entry"); + } +@@ -275,7 +280,9 @@ generate_spc_signed_data(cms_context *cms, SECItem *sdp) + void *mark = PORT_ArenaMark(cms->arena); + + if (SEC_ASN1EncodeInteger(cms->arena, &sd.version, 1) == NULL) { +- save_port_err(PORT_ArenaRelease(cms->arena, mark)); ++ save_port_err() { ++ PORT_ArenaRelease(cms->arena, mark); ++ } + cms->ci_digest = NULL; + cmsreterr(-1, cms, "could not encode integer"); + } +@@ -309,7 +316,9 @@ generate_spc_signed_data(cms_context *cms, SECItem *sdp) + SECItem encoded = { 0, }; + if (SEC_ASN1EncodeItem(cms->arena, &encoded, &sd, SignedDataTemplate) + == NULL) { +- save_port_err(PORT_ArenaRelease(cms->arena, mark)); ++ save_port_err() { ++ PORT_ArenaRelease(cms->arena, mark); ++ } + cms->ci_digest = NULL; + cmsreterr(-1, cms, "could not encode SignedData"); + } +@@ -325,7 +334,9 @@ generate_spc_signed_data(cms_context *cms, SECItem *sdp) + SECItem wrapper = { 0, }; + if (SEC_ASN1EncodeItem(cms->arena, &wrapper, &sdw, + ContentInfoTemplate) == NULL) { +- save_port_err(PORT_ArenaRelease(cms->arena, mark)); ++ save_port_err() { ++ PORT_ArenaRelease(cms->arena, mark); ++ } + cms->ci_digest = NULL; + cmsreterr(-1, cms, "could not encode SignedData"); + } +@@ -347,7 +358,9 @@ generate_authvar_signed_data(cms_context *cms, SECItem *sdp) + void *mark = PORT_ArenaMark(cms->arena); + + if (SEC_ASN1EncodeInteger(cms->arena, &sd.version, 1) == NULL) { +- save_port_err(PORT_ArenaRelease(cms->arena, mark)); ++ save_port_err() { ++ PORT_ArenaRelease(cms->arena, mark); ++ } + cmsreterr(-1, cms, "could not encode integer"); + } + +@@ -376,7 +389,9 @@ generate_authvar_signed_data(cms_context *cms, SECItem *sdp) + SECItem encoded = { 0, }; + if (SEC_ASN1EncodeItem(cms->arena, &encoded, &sd, SignedDataTemplate) + == NULL) { +- save_port_err(PORT_ArenaRelease(cms->arena, mark)); ++ save_port_err() { ++ PORT_ArenaRelease(cms->arena, mark); ++ } + cmsreterr(-1, cms, "could not encode SignedData"); + } + +@@ -391,7 +406,9 @@ generate_authvar_signed_data(cms_context *cms, SECItem *sdp) + SECItem wrapper = { 0, }; + if (SEC_ASN1EncodeItem(cms->arena, &wrapper, &sdw, + ContentInfoTemplate) == NULL) { +- save_port_err(PORT_ArenaRelease(cms->arena, mark)); ++ save_port_err() { ++ PORT_ArenaRelease(cms->arena, mark); ++ } + cmsreterr(-1, cms, "could not encode SignedData"); + } + +@@ -399,3 +416,5 @@ generate_authvar_signed_data(cms_context *cms, SECItem *sdp) + PORT_ArenaUnmark(cms->arena, mark); + return 0; + } ++ ++// vim:fenc=utf-8:tw=75:noet +diff --git a/src/cms_common.h b/src/cms_common.h +index c2b5981ba66..266fa224be0 100644 +--- a/src/cms_common.h ++++ b/src/cms_common.h +@@ -19,21 +19,20 @@ + #ifndef CMS_COMMON_H + #define CMS_COMMON_H 1 + +-#include + #include + #include ++ ++#include + #include + #include + #include + #include + #include + +-#define save_port_err(x) \ +- ({ \ +- int __saved_errno = PORT_GetError(); \ +- x; \ +- PORT_SetError(__saved_errno); \ +- }) ++#include "util.h" ++ ++#define save_port_err() \ ++ for (error_t saved_errno_0_ = 0, saved_errno_1_ = PORT_GetError(); saved_errno_0_ < 1; saved_errno_0_++, PORT_SetError(saved_errno_1_)) + + #define cmserr(rv, cms, fmt, args...) ({ \ + (cms)->log((cms), LOG_ERR, "%s:%s:%d: " fmt ": %s", \ +@@ -173,3 +172,4 @@ typedef struct { + } secuPWData; + + #endif /* CMS_COMMON_H */ ++// vim:fenc=utf-8:tw=75:noet +-- +2.29.2 + diff --git a/0017-Make-for_each_cert-cl-iter-for-certificate-list-trav.patch b/0017-Make-for_each_cert-cl-iter-for-certificate-list-trav.patch new file mode 100644 index 0000000..3464e8f --- /dev/null +++ b/0017-Make-for_each_cert-cl-iter-for-certificate-list-trav.patch @@ -0,0 +1,71 @@ +From 03e2f49111fb846254f73ba9a2cce29ea13d3a99 Mon Sep 17 00:00:00 2001 +From: Peter Jones +Date: Fri, 17 May 2019 14:06:04 -0400 +Subject: [PATCH 17/42] Make for_each_cert(cl, iter) for certificate list + traversal. + +Signed-off-by: Peter Jones +--- + src/cms_common.c | 18 ++++++++---------- + src/cms_common.h | 3 +++ + 2 files changed, 11 insertions(+), 10 deletions(-) + +diff --git a/src/cms_common.c b/src/cms_common.c +index 9218f69ef9e..75a95f053a2 100644 +--- a/src/cms_common.c ++++ b/src/cms_common.c +@@ -614,20 +614,20 @@ find_named_certificate(cms_context *cms, char *name, CERTCertificate **cert) + } + + CERTCertListNode *node = NULL; +- for (node = CERT_LIST_HEAD(certlist); !CERT_LIST_END(node,certlist); +- node = CERT_LIST_NEXT(node)) { +- if (!strcmp(node->cert->subjectName, name)) ++ for_each_cert(certlist, tmpnode) { ++ if (!strcmp(tmpnode->cert->subjectName, name)) { ++ node = tmpnode; + break; ++ } + } + /* If we're looking up the issuer of some cert, and the issuer isn't + * in the database, we'll get back what is essentially a template + * that's in NSS's cache waiting to be filled out. We can't use that, + * it'll just cause CERT_DupCertificate() to segfault. */ +- if (CERT_LIST_END(node, certlist) +- || !node->cert || !node->cert->derCert.data +- || !node->cert->derCert.len +- || !node->cert->derIssuer.data +- || !node->cert->derIssuer.len) { ++ if (!node || !node->cert || !node->cert->derCert.data ++ || !node->cert->derCert.len ++ || !node->cert->derIssuer.data ++ || !node->cert->derIssuer.len) { + PK11_DestroySlotListElement(slots, &psle); + PK11_FreeSlotList(slots); + CERT_DestroyCertList(certlist); +@@ -635,8 +635,6 @@ find_named_certificate(cms_context *cms, char *name, CERTCertificate **cert) + return -1; + } + +- +- + *cert = CERT_DupCertificate(node->cert); + + PK11_DestroySlotListElement(slots, &psle); +diff --git a/src/cms_common.h b/src/cms_common.h +index 266fa224be0..b0dc12fc3ab 100644 +--- a/src/cms_common.h ++++ b/src/cms_common.h +@@ -34,6 +34,9 @@ + #define save_port_err() \ + for (error_t saved_errno_0_ = 0, saved_errno_1_ = PORT_GetError(); saved_errno_0_ < 1; saved_errno_0_++, PORT_SetError(saved_errno_1_)) + ++#define for_each_cert(cl, node) \ ++ for (CERTCertListNode *node = CERT_LIST_HEAD(cl); !CERT_LIST_END(node, cl); node = CERT_LIST_NEXT(node)) ++ + #define cmserr(rv, cms, fmt, args...) ({ \ + (cms)->log((cms), LOG_ERR, "%s:%s:%d: " fmt ": %s", \ + __FILE__, __func__, __LINE__, ## args, \ +-- +2.29.2 + diff --git a/0018-file_pe-make-most-of-our-input-and-output-checkers-b.patch b/0018-file_pe-make-most-of-our-input-and-output-checkers-b.patch new file mode 100644 index 0000000..2b4d811 --- /dev/null +++ b/0018-file_pe-make-most-of-our-input-and-output-checkers-b.patch @@ -0,0 +1,266 @@ +From fc554b55d45a552982ba9949645e407231f06748 Mon Sep 17 00:00:00 2001 +From: Peter Jones +Date: Tue, 21 May 2019 13:54:37 -0400 +Subject: [PATCH 18/42] file_pe: make most of our input and output checkers be + generated + +Signed-off-by: Peter Jones +--- + src/file_pe.c | 237 ++++++++++++-------------------------------------- + 1 file changed, 57 insertions(+), 180 deletions(-) + +diff --git a/src/file_pe.c b/src/file_pe.c +index 0555c28ebff..fcac6292d94 100644 +--- a/src/file_pe.c ++++ b/src/file_pe.c +@@ -118,190 +118,67 @@ open_output(pesign_context *ctx) + + Pe_Cmd cmd = ctx->outfd == STDOUT_FILENO ? PE_C_RDWR : PE_C_RDWR_MMAP; + ctx->outpe = pe_begin(ctx->outfd, cmd, NULL); +- if (!ctx->outpe) { +- fprintf(stderr, "pesign: could not load output file: %s\n", +- pe_errmsg(pe_errno())); +- exit(1); +- } ++ conderrx(!ctx->outpe, 1, "could not load output file \"%s\": %s", ++ ctx->outfile, pe_errmsg(pe_errno())); + + pe_clearcert(ctx->outpe); + } + +-static void +-open_rawsig_input(pesign_context *ctx) +-{ +- if (!ctx->rawsig) { +- fprintf(stderr, "pesign: No input file specified.\n"); +- exit(1); +- } +- +- ctx->rawsigfd = open(ctx->rawsig, O_RDONLY|O_CLOEXEC); +- if (ctx->rawsigfd < 0) { +- fprintf(stderr, "pesign: Error opening raw signature for input:" +- " %m\n"); +- exit(1); +- } +-} +- +-static void +-close_rawsig_input(pesign_context *ctx) +-{ +- close(ctx->rawsigfd); +- ctx->rawsigfd = -1; +-} +- +-static void +-open_sattr_input(pesign_context *ctx) +-{ +- if (!ctx->insattrs) { +- fprintf(stderr, "pesign: No input file specified.\n"); +- exit(1); +- } +- +- ctx->insattrsfd = open(ctx->insattrs, O_RDONLY|O_CLOEXEC); +- if (ctx->insattrsfd < 0) { +- fprintf(stderr, "pesign: Error opening signed attributes " +- "for input: %m\n"); +- exit(1); +- } +-} +- +-static void +-close_sattr_input(pesign_context *ctx) +-{ +- close(ctx->insattrsfd); +- ctx->insattrsfd = -1; +-} +- +-static void +-open_sattr_output(pesign_context *ctx) +-{ +- if (!ctx->outsattrs) { +- fprintf(stderr, "pesign: No output file specified.\n"); +- exit(1); +- } +- +- if (access(ctx->outsattrs, F_OK) == 0 && ctx->force == 0) { +- fprintf(stderr, "pesign: \"%s\" exists and --force " +- "was not given.\n", ctx->outsattrs); +- exit(1); +- } +- +- ctx->outsattrsfd = open(ctx->outsattrs, +- O_RDWR|O_CREAT|O_TRUNC|O_CLOEXEC, +- ctx->outmode); +- if (ctx->outsattrsfd < 0) { +- fprintf(stderr, "pesign: Error opening signed attributes " +- "for output: %m\n"); +- exit(1); +- } +-} +- +-static void +-close_sattr_output(pesign_context *ctx) +-{ +- close(ctx->outsattrsfd); +- ctx->outsattrsfd = -1; +-} +- +-static void +-open_sig_input(pesign_context *ctx) +-{ +- if (!ctx->insig) { +- fprintf(stderr, "pesign: No input file specified.\n"); +- exit(1); +- } +- +- ctx->insigfd = open(ctx->insig, O_RDONLY|O_CLOEXEC); +- if (ctx->insigfd < 0) { +- fprintf(stderr, "pesign: Error opening signature for input: " +- "%m\n"); +- exit(1); +- } +-} +- +-static void +-close_sig_input(pesign_context *ctx) +-{ +- close(ctx->insigfd); +- ctx->insigfd = -1; +-} +- +-static void +-open_sig_output(pesign_context *ctx) +-{ +- if (!ctx->outsig) { +- fprintf(stderr, "pesign: No output file specified.\n"); +- exit(1); +- } +- +- if (access(ctx->outsig, F_OK) == 0 && ctx->force == 0) { +- fprintf(stderr, "pesign: \"%s\" exists and --force " +- "was not given.\n", ctx->outsig); +- exit(1); +- } +- +- ctx->outsigfd = open(ctx->outsig, O_RDWR|O_CREAT|O_TRUNC|O_CLOEXEC, +- ctx->outmode); +- if (ctx->outsigfd < 0) { +- fprintf(stderr, "pesign: Error opening signature for output: " +- "%m\n"); +- exit(1); +- } +-} +- +-static void +-close_sig_output(pesign_context *ctx) +-{ +- close(ctx->outsigfd); +- ctx->outsigfd = -1; +-} +- +-static void +-open_pubkey_output(pesign_context *ctx) +-{ +- if (!ctx->outkey) { +- fprintf(stderr, "pesign: No output file specified.\n"); +- exit(1); +- } +- +- if (access(ctx->outkey, F_OK) == 0 && ctx->force == 0) { +- fprintf(stderr, "pesign: \"%s\" exists and --force " +- "was not given.\n", ctx->outkey); +- exit(1); +- } +- +- ctx->outkeyfd = open(ctx->outkey, O_RDWR|O_CREAT|O_TRUNC|O_CLOEXEC, +- ctx->outmode); +- if (ctx->outkeyfd < 0) { +- fprintf(stderr, "pesign: Error opening pubkey for output: " +- "%m\n"); +- exit(1); +- } +-} +- +-static void +-open_cert_output(pesign_context *ctx) +-{ +- if (!ctx->outcert) { +- fprintf(stderr, "pesign: No output file specified.\n"); +- exit(1); +- } +- +- if (access(ctx->outcert, F_OK) == 0 && ctx->force == 0) { +- fprintf(stderr, "pesign: \"%s\" exists and --force " +- "was not given.\n", ctx->outcert); +- exit(1); +- } +- +- ctx->outcertfd = open(ctx->outcert, O_RDWR|O_CREAT|O_TRUNC|O_CLOEXEC, +- ctx->outmode); +- if (ctx->outcertfd < 0) { +- fprintf(stderr, "pesign: Error opening certificate for output: " +- "%m\n"); +- exit(1); +- } +-} ++#define define_input_file(fname, name, descr) \ ++ static void \ ++ CAT3(open_, fname, _input)(pesign_context *ctx) \ ++ { \ ++ conderrx(!ctx->name, 1, \ ++ "No input file specified for %s", \ ++ descr); \ ++ ctx->CAT(name, fd) = \ ++ open(ctx->name, O_RDONLY|O_CLOEXEC); \ ++ conderr(ctx->CAT(name, fd) < 0, 1, \ ++ "Error opening %s file \"%s\" for input", \ ++ descr, ctx->name); \ ++ } \ ++ static void \ ++ CAT3(close_, fname, _input)(pesign_context *ctx) \ ++ { \ ++ close(ctx->CAT(name, fd)); \ ++ ctx->CAT(name, fd) = -1; \ ++ } ++ ++#define define_output_file(fname, name, descr) \ ++ static void \ ++ CAT3(open_, fname, _output)(pesign_context *ctx) \ ++ { \ ++ conderrx(!ctx->name, 1, \ ++ "No output file specified for %s.", \ ++ descr); \ ++ \ ++ if (access(ctx->name, F_OK) == 0 && ctx->force == 0) \ ++ errx(1, \ ++ "\"%s\" exists and --force was not given.",\ ++ ctx->name); \ ++ \ ++ ctx->CAT(name, fd) = \ ++ open(ctx->name, \ ++ O_RDWR|O_CREAT|O_TRUNC|O_CLOEXEC, \ ++ ctx->outmode); \ ++ conderr(ctx->CAT(name, fd) < 0, 1, \ ++ "Error opening %s file \"%s\" for output", \ ++ descr, ctx->name); \ ++ } \ ++ static void \ ++ CAT3(close_, fname, _output)(pesign_context *ctx) \ ++ { \ ++ close(ctx->CAT(name,fd)); \ ++ ctx->CAT(name,fd) = -1; \ ++ } ++ ++define_input_file(rawsig, rawsig, "raw signature"); ++define_input_file(sattr, insattrs, "signed attributes"); ++define_output_file(sattr, outsattrs, "signed attributes"); ++define_input_file(sig, insig, "signature"); ++define_output_file(sig, outsig, "signature"); ++define_output_file(pubkey, outkey, "pubkey"); ++define_output_file(cert, outcert, "certificate"); + + static void + check_inputs(pesign_context *ctx) +-- +2.29.2 + diff --git a/0019-file_pe-user-err-errx-etc.patch b/0019-file_pe-user-err-errx-etc.patch new file mode 100644 index 0000000..bc4af1a --- /dev/null +++ b/0019-file_pe-user-err-errx-etc.patch @@ -0,0 +1,275 @@ +From 61bdc2689de3ab4f3960bee9a1ac7c63386cf727 Mon Sep 17 00:00:00 2001 +From: Peter Jones +Date: Tue, 21 May 2019 14:04:30 -0400 +Subject: [PATCH 19/42] file_pe: user err() errx() etc. + +Signed-off-by: Peter Jones +--- + src/file_pe.c | 146 +++++++++++++++----------------------------------- + 1 file changed, 44 insertions(+), 102 deletions(-) + +diff --git a/src/file_pe.c b/src/file_pe.c +index fcac6292d94..ad076eba961 100644 +--- a/src/file_pe.c ++++ b/src/file_pe.c +@@ -29,36 +29,23 @@ + static void + open_input(pesign_context *ctx) + { +- if (!ctx->infile) { +- fprintf(stderr, "pesign: No input file specified.\n"); +- exit(1); +- } ++ conderrx(!ctx->infile, 1, "No input file specified."); + + struct stat statbuf; + ctx->infd = open(ctx->infile, O_RDONLY|O_CLOEXEC); + stat(ctx->infile, &statbuf); + ctx->outmode = statbuf.st_mode; + +- if (ctx->infd < 0) { +- fprintf(stderr, "pesign: Error opening input: %m\n"); +- exit(1); +- } ++ conderr(ctx->infd < 0, 1, "Error opening input"); + + Pe_Cmd cmd = ctx->infd == STDIN_FILENO ? PE_C_READ : PE_C_READ_MMAP; + ctx->inpe = pe_begin(ctx->infd, cmd, NULL); +- if (!ctx->inpe) { +- fprintf(stderr, "pesign: could not load input file: %s\n", +- pe_errmsg(pe_errno())); +- exit(1); +- } ++ conderrx(!ctx->inpe, 1, "could not load input file \"%s\": %s", ++ ctx->infile, pe_errmsg(pe_errno())); + + int rc = parse_signatures(&ctx->cms_ctx->signatures, + &ctx->cms_ctx->num_signatures, ctx->inpe); +- if (rc < 0) { +- fprintf(stderr, "pesign: could not parse signature list in " +- "EFI binary\n"); +- exit(1); +- } ++ conderrx(rc < 0, 1, "could not parse signature list in EFI binary"); + } + + static void +@@ -89,23 +76,16 @@ close_output(pesign_context *ctx) + static void + open_output(pesign_context *ctx) + { +- if (!ctx->outfile) { +- fprintf(stderr, "pesign: No output file specified.\n"); +- exit(1); +- } ++ conderrx(!ctx->outfile, 1, "No output file specified."); + +- if (access(ctx->outfile, F_OK) == 0 && ctx->force == 0) { +- fprintf(stderr, "pesign: \"%s\" exists and --force was " +- "not given.\n", ctx->outfile); +- exit(1); +- } ++ if (access(ctx->outfile, F_OK) == 0 && ctx->force == 0) ++ errx(1, "\"%s\" exists and --force was not given.", ++ ctx->outfile); + + ctx->outfd = open(ctx->outfile, O_RDWR|O_CREAT|O_TRUNC|O_CLOEXEC, + ctx->outmode); +- if (ctx->outfd < 0) { +- fprintf(stderr, "pesign: Error opening output: %m\n"); +- exit(1); +- } ++ conderr(ctx->outfd < 0, 1, "Error opening \"%s\" for output", ++ ctx->outfile); + + size_t size; + char *addr; +@@ -119,7 +99,7 @@ open_output(pesign_context *ctx) + Pe_Cmd cmd = ctx->outfd == STDOUT_FILENO ? PE_C_RDWR : PE_C_RDWR_MMAP; + ctx->outpe = pe_begin(ctx->outfd, cmd, NULL); + conderrx(!ctx->outpe, 1, "could not load output file \"%s\": %s", +- ctx->outfile, pe_errmsg(pe_errno())); ++ ctx->outfile, pe_errmsg(pe_errno())); + + pe_clearcert(ctx->outpe); + } +@@ -183,21 +163,11 @@ define_output_file(cert, outcert, "certificate"); + static void + check_inputs(pesign_context *ctx) + { +- if (!ctx->infile) { +- fprintf(stderr, "pesign: No input file specified.\n"); +- exit(1); +- } ++ conderrx(!ctx->infile, 1, "No input file specified."); ++ conderrx(!ctx->outfile, 1, "No output file specified."); + +- if (!ctx->outfile) { +- fprintf(stderr, "pesign: No output file specified.\n"); +- exit(1); +- } +- +- if (!strcmp(ctx->infile, ctx->outfile)) { +- fprintf(stderr, "pesign: in-place file editing " +- "is not yet supported\n"); +- exit(1); +- } ++ conderrx(!strcmp(ctx->infile, ctx->outfile), 1, ++ "in-place file editing is not yet supported."); + } + + static void +@@ -232,12 +202,8 @@ pe_handle_action(pesign_context *ctxp, int action, int padding) + case IMPORT_RAW_SIGNATURE|IMPORT_SATTRS: + check_inputs(ctxp); + rc = find_certificate(ctxp->cms_ctx, 0); +- if (rc < 0) { +- fprintf(stderr, "pesign: Could not find " +- "certificate %s\n", +- ctxp->cms_ctx->certname); +- exit(1); +- } ++ conderrx(rc < 0, 1, "Could not find certificate %s\n", ++ ctxp->cms_ctx->certname); + open_rawsig_input(ctxp); + open_sattr_input(ctxp); + import_raw_signature(ctxp); +@@ -266,10 +232,8 @@ pe_handle_action(pesign_context *ctxp, int action, int padding) + /* add a signature from a file */ + case IMPORT_SIGNATURE: + check_inputs(ctxp); +- if (ctxp->signum > ctxp->cms_ctx->num_signatures + 1) { +- fprintf(stderr, "Invalid signature number.\n"); +- exit(1); +- } ++ conderrx(ctxp->signum > ctxp->cms_ctx->num_signatures + 1, ++ 1, "Invalid signature number."); + open_input(ctxp); + open_output(ctxp); + close_input(ctxp); +@@ -285,23 +249,15 @@ pe_handle_action(pesign_context *ctxp, int action, int padding) + break; + case EXPORT_PUBKEY: + rc = find_certificate(ctxp->cms_ctx, 1); +- if (rc < 0) { +- fprintf(stderr, "pesign: Could not find " +- "certificate %s\n", +- ctxp->cms_ctx->certname); +- exit(1); +- } ++ conderrx(rc < 0, 1, "Could not find certificate %s", ++ ctxp->cms_ctx->certname); + open_pubkey_output(ctxp); + export_pubkey(ctxp); + break; + case EXPORT_CERT: + rc = find_certificate(ctxp->cms_ctx, 0); +- if (rc < 0) { +- fprintf(stderr, "pesign: Could not find " +- "certificate %s\n", +- ctxp->cms_ctx->certname); +- exit(1); +- } ++ conderrx(rc < 0, 1, "Could not find certificate %s", ++ ctxp->cms_ctx->certname); + open_cert_output(ctxp); + export_cert(ctxp); + break; +@@ -309,17 +265,12 @@ pe_handle_action(pesign_context *ctxp, int action, int padding) + case EXPORT_SIGNATURE: + open_input(ctxp); + open_sig_output(ctxp); +- if (ctxp->signum > ctxp->cms_ctx->num_signatures) { +- fprintf(stderr, "Invalid signature number.\n"); +- exit(1); +- } ++ conderrx(ctxp->signum > ctxp->cms_ctx->num_signatures, ++ 1, "Invalid signature number."); + if (ctxp->signum < 0) + ctxp->signum = 0; +- if (ctxp->signum >= ctxp->cms_ctx->num_signatures) { +- fprintf(stderr, "No valid signature #%d.\n", +- ctxp->signum); +- exit(1); +- } ++ conderrx(ctxp->signum >= ctxp->cms_ctx->num_signatures, ++ 1, "No valid signature #%d.", ctxp->signum); + memcpy(&ctxp->cms_ctx->newsig, + ctxp->cms_ctx->signatures[ctxp->signum], + sizeof (ctxp->cms_ctx->newsig)); +@@ -335,14 +286,12 @@ pe_handle_action(pesign_context *ctxp, int action, int padding) + open_input(ctxp); + open_output(ctxp); + close_input(ctxp); +- if (ctxp->signum < 0 || +- ctxp->signum >= +- ctxp->cms_ctx->num_signatures) { +- fprintf(stderr, "Invalid signature number %d. " +- "Must be between 0 and %d.\n", +- ctxp->signum, +- ctxp->cms_ctx->num_signatures - 1); +- exit(1); ++ if(ctxp->signum < 0 || ++ ctxp->signum >= ctxp->cms_ctx->num_signatures) { ++ warnx("Invalid signature number %d.", ++ ctxp->signum); ++ errx(1, "Must be between 0 and %d.", ++ ctxp->cms_ctx->num_signatures - 1); + } + remove_signature(ctxp); + close_output(ctxp); +@@ -365,12 +314,8 @@ pe_handle_action(pesign_context *ctxp, int action, int padding) + /* generate a signature and save it in a separate file */ + case EXPORT_SIGNATURE|GENERATE_SIGNATURE: + rc = find_certificate(ctxp->cms_ctx, 1); +- if (rc < 0) { +- fprintf(stderr, "pesign: Could not find " +- "certificate %s\n", +- ctxp->cms_ctx->certname); +- exit(1); +- } ++ conderrx(rc < 0, 1, "Could not find certificate %s", ++ ctxp->cms_ctx->certname); + open_input(ctxp); + open_sig_output(ctxp); + generate_digest(ctxp->cms_ctx, ctxp->inpe, 1); +@@ -381,16 +326,10 @@ pe_handle_action(pesign_context *ctxp, int action, int padding) + case IMPORT_SIGNATURE|GENERATE_SIGNATURE: + check_inputs(ctxp); + rc = find_certificate(ctxp->cms_ctx, 1); +- if (rc < 0) { +- fprintf(stderr, "pesign: Could not find " +- "certificate %s\n", +- ctxp->cms_ctx->certname); +- exit(1); +- } +- if (ctxp->signum > ctxp->cms_ctx->num_signatures + 1) { +- fprintf(stderr, "Invalid signature number.\n"); +- exit(1); +- } ++ conderrx(rc < 0, 1, "Could not find certificate %s", ++ ctxp->cms_ctx->certname); ++ conderrx(ctxp->signum > ctxp->cms_ctx->num_signatures + 1, ++ 1, "Invalid signature number."); + open_input(ctxp); + open_output(ctxp); + close_input(ctxp); +@@ -404,7 +343,8 @@ pe_handle_action(pesign_context *ctxp, int action, int padding) + close_output(ctxp); + break; + default: +- fprintf(stderr, "Incompatible flags (0x%08x): ", action); ++ fprintf(stderr, "%s: Incompatible flags (0x%08x): ", ++ program_invocation_short_name, action); + for (int i = 1; i < FLAG_LIST_END; i <<= 1) { + if (action & i) + print_flag_name(stderr, i); +@@ -413,3 +353,5 @@ pe_handle_action(pesign_context *ctxp, int action, int padding) + exit(1); + } + } ++ ++// vim:fenc=utf-8:tw=75:noet +-- +2.29.2 + diff --git a/0020-pesign_kmod-user-err-errx-etc.patch b/0020-pesign_kmod-user-err-errx-etc.patch new file mode 100644 index 0000000..91e9159 --- /dev/null +++ b/0020-pesign_kmod-user-err-errx-etc.patch @@ -0,0 +1,165 @@ +From 43d7021bc1a4d78cfaa8ad8a31c73058005e26ef Mon Sep 17 00:00:00 2001 +From: Peter Jones +Date: Tue, 21 May 2019 14:45:24 -0400 +Subject: [PATCH 20/42] pesign_kmod: user err() errx() etc. + +Signed-off-by: Peter Jones +--- + src/pesign_kmod.c | 80 +++++++++++++++-------------------------------- + 1 file changed, 26 insertions(+), 54 deletions(-) + +diff --git a/src/pesign_kmod.c b/src/pesign_kmod.c +index 5d78131a69b..916ae52ebe2 100644 +--- a/src/pesign_kmod.c ++++ b/src/pesign_kmod.c +@@ -122,6 +122,7 @@ import_sig_input(pesign_context *ctx) + { + unsigned char *map; + struct stat statbuf; ++ int rc; + + if (!ctx->insig) { + fprintf(stderr, "pesign: No input file specified.\n"); +@@ -135,23 +136,17 @@ import_sig_input(pesign_context *ctx) + exit(1); + } + +- if (fstat(ctx->insigfd, &statbuf)) { +- fprintf(stderr, "pesign: Error on stat signature: %m\n"); +- exit(1); +- } ++ rc = fstat(ctx->insigfd, &statbuf); ++ conderr(rc < 0, 1, "Could not fstat signature file \"%s\"", ++ ctx->insig); + + /* Copy original module data */ + + map = mmap(NULL, ctx->inlength, PROT_READ, MAP_PRIVATE, ctx->infd, 0); +- if (map == MAP_FAILED) { +- fprintf(stderr, "pesign: Error mapping input: %m\n"); +- exit(1); +- } ++ conderr(map == MAP_FAILED, 1, "Could not map kmod input"); + +- if (write_file(ctx->outfd, map, ctx->inlength) < 0) { +- fprintf(stderr, "pesign: failed to write module data: %m\n"); +- exit(1); +- } ++ rc = write_file(ctx->outfd, map, ctx->inlength); ++ conderr(rc < 0, 1, "Failed to write module data"); + + munmap(map, ctx->inlength); + +@@ -159,15 +154,11 @@ import_sig_input(pesign_context *ctx) + + map = mmap(NULL, statbuf.st_size, PROT_READ, MAP_PRIVATE, ctx->insigfd, + 0); +- if (map == MAP_FAILED) { +- fprintf(stderr, "pesign: failed to map signature: %m\n"); +- exit(1); +- } ++ conderr(map == MAP_FAILED, 1, "Could not map signature input \"%s\"", ++ ctx->insig); + +- if (write_file(ctx->outfd, map, statbuf.st_size) < 0) { +- fprintf(stderr, "pesign: Error writing output: %m\n"); +- exit(1); +- } ++ rc = write_file(ctx->outfd, map, statbuf.st_size); ++ conderr(rc < 0, 1, "Error writing output"); + + munmap(map, statbuf.st_size); + } +@@ -180,20 +171,15 @@ handle_signing(pesign_context *ctx, int outfd, int attached) + ssize_t sig_len; + + inmap = mmap(NULL, ctx->inlength, PROT_READ, MAP_PRIVATE, ctx->infd, 0); +- if (inmap == MAP_FAILED) { +- fprintf(stderr, "pesign: Error mapping input: %m\n"); +- exit(1); +- } ++ conderrx(inmap == MAP_FAILED, 1, "Error mapping input kmod"); + + rc = kmod_generate_digest(ctx->cms_ctx, inmap, ctx->inlength); + if (rc < 0) + exit(1); + + if (attached) { +- if (write_file(outfd, inmap, ctx->inlength) < 0) { +- fprintf(stderr, "pesign: failed to write module data: %m\n"); +- exit(1); +- } ++ rc = write_file(outfd, inmap, ctx->inlength); ++ conderr(rc < 0, 1, "Failed to write module data"); + } + munmap(inmap, ctx->inlength); + +@@ -214,16 +200,10 @@ kmod_handle_action(pesign_context *ctxp, int action) + /* generate a signature and embed it in the module */ + case IMPORT_SIGNATURE|GENERATE_SIGNATURE: + rc = find_certificate(ctxp->cms_ctx, 1); +- if (rc < 0) { +- fprintf(stderr, "pesign: Could not find " +- "certificate %s\n", +- ctxp->cms_ctx->certname); +- exit(1); +- } +- if (ctxp->signum > ctxp->cms_ctx->num_signatures + 1) { +- fprintf(stderr, "Invalid signature number.\n"); +- exit(1); +- } ++ conderrx(rc < 0, 1, "Could not find certificate \"%s\"", ++ ctxp->cms_ctx->certname); ++ conderrx(ctxp->signum > ctxp->cms_ctx->num_signatures + 1, ++ 1, "Invalid signature number."); + + open_input(ctxp); + open_output(ctxp); +@@ -235,16 +215,10 @@ kmod_handle_action(pesign_context *ctxp, int action) + /* generate a signature and save it in a separate file */ + case EXPORT_SIGNATURE|GENERATE_SIGNATURE: + rc = find_certificate(ctxp->cms_ctx, 1); +- if (rc < 0) { +- fprintf(stderr, "pesign: Could not find " +- "certificate %s\n", +- ctxp->cms_ctx->certname); +- exit(1); +- } +- if (ctxp->signum > ctxp->cms_ctx->num_signatures + 1) { +- fprintf(stderr, "Invalid signature number.\n"); +- exit(1); +- } ++ conderrx(rc < 0, 1, "Could not find certificate \"%s\"", ++ ctxp->cms_ctx->certname); ++ conderrx(ctxp->signum > ctxp->cms_ctx->num_signatures + 1, ++ 1, "Invalid signature number."); + + open_input(ctxp); + open_sig_output(ctxp); +@@ -255,10 +229,8 @@ kmod_handle_action(pesign_context *ctxp, int action) + + /* add a signature from a file */ + case IMPORT_SIGNATURE: +- if (ctxp->signum > ctxp->cms_ctx->num_signatures + 1) { +- fprintf(stderr, "Invalid signature number.\n"); +- exit(1); +- } ++ conderrx(ctxp->signum > ctxp->cms_ctx->num_signatures + 1, ++ 1, "Invalid signature number."); + open_input(ctxp); + open_output(ctxp); + import_sig_input(ctxp); +@@ -267,8 +239,8 @@ kmod_handle_action(pesign_context *ctxp, int action) + break; + + default: +- fprintf(stderr, "Incompatible flags (0x%08x): ", +- action); ++ fprintf(stderr, "%s: Incompatible flags (0x%08x): ", ++ program_invocation_short_name, action); + for (int i = 1; i < FLAG_LIST_END; i <<= 1) { + if (action & i) + print_flag_name(stderr, i); +-- +2.29.2 + diff --git a/0021-share-input-output-checker-macros-between-pesign_kmo.patch b/0021-share-input-output-checker-macros-between-pesign_kmo.patch new file mode 100644 index 0000000..bde7edc --- /dev/null +++ b/0021-share-input-output-checker-macros-between-pesign_kmo.patch @@ -0,0 +1,411 @@ +From 9209c1e45ca7fa0c821f0da57dd6e1ff746de267 Mon Sep 17 00:00:00 2001 +From: Peter Jones +Date: Tue, 21 May 2019 14:29:24 -0400 +Subject: [PATCH 21/42] share input/output checker macros between pesign_kmod + and file_pe + +Signed-off-by: Peter Jones +--- + src/file_pe.c | 48 --------------- + src/pesign.c | 2 + + src/pesign_kmod.c | 142 ++++++++----------------------------------- + src/pesign_context.h | 20 ++++-- + src/util.h | 65 ++++++++++++++++++++ + 5 files changed, 110 insertions(+), 167 deletions(-) + +diff --git a/src/file_pe.c b/src/file_pe.c +index ad076eba961..31672c68f79 100644 +--- a/src/file_pe.c ++++ b/src/file_pe.c +@@ -104,54 +104,6 @@ open_output(pesign_context *ctx) + pe_clearcert(ctx->outpe); + } + +-#define define_input_file(fname, name, descr) \ +- static void \ +- CAT3(open_, fname, _input)(pesign_context *ctx) \ +- { \ +- conderrx(!ctx->name, 1, \ +- "No input file specified for %s", \ +- descr); \ +- ctx->CAT(name, fd) = \ +- open(ctx->name, O_RDONLY|O_CLOEXEC); \ +- conderr(ctx->CAT(name, fd) < 0, 1, \ +- "Error opening %s file \"%s\" for input", \ +- descr, ctx->name); \ +- } \ +- static void \ +- CAT3(close_, fname, _input)(pesign_context *ctx) \ +- { \ +- close(ctx->CAT(name, fd)); \ +- ctx->CAT(name, fd) = -1; \ +- } +- +-#define define_output_file(fname, name, descr) \ +- static void \ +- CAT3(open_, fname, _output)(pesign_context *ctx) \ +- { \ +- conderrx(!ctx->name, 1, \ +- "No output file specified for %s.", \ +- descr); \ +- \ +- if (access(ctx->name, F_OK) == 0 && ctx->force == 0) \ +- errx(1, \ +- "\"%s\" exists and --force was not given.",\ +- ctx->name); \ +- \ +- ctx->CAT(name, fd) = \ +- open(ctx->name, \ +- O_RDWR|O_CREAT|O_TRUNC|O_CLOEXEC, \ +- ctx->outmode); \ +- conderr(ctx->CAT(name, fd) < 0, 1, \ +- "Error opening %s file \"%s\" for output", \ +- descr, ctx->name); \ +- } \ +- static void \ +- CAT3(close_, fname, _output)(pesign_context *ctx) \ +- { \ +- close(ctx->CAT(name,fd)); \ +- ctx->CAT(name,fd) = -1; \ +- } +- + define_input_file(rawsig, rawsig, "raw signature"); + define_input_file(sattr, insattrs, "signed attributes"); + define_output_file(sattr, outsattrs, "signed attributes"); +diff --git a/src/pesign.c b/src/pesign.c +index 95a832df9e4..d2f3f221df0 100644 +--- a/src/pesign.c ++++ b/src/pesign.c +@@ -462,3 +462,5 @@ main(int argc, char *argv[]) + + return (rc < 0); + } ++ ++// vim:fenc=utf-8:tw=75:noet +diff --git a/src/pesign_kmod.c b/src/pesign_kmod.c +index 916ae52ebe2..a9799b83fa8 100644 +--- a/src/pesign_kmod.c ++++ b/src/pesign_kmod.c +@@ -26,96 +26,10 @@ + #include "pesign_standalone.h" + #include "file_kmod.h" + +-static void +-open_input(pesign_context *ctx) +-{ +- struct stat statbuf; +- +- if (!ctx->infile) { +- fprintf(stderr, "pesign: No input file specified.\n"); +- exit(1); +- } +- +- ctx->infd = open(ctx->infile, O_RDONLY|O_CLOEXEC); +- if (ctx->infd < 0) { +- fprintf(stderr, "pesign: Error opening input: %m\n"); +- exit(1); +- } +- +- if (fstat(ctx->infd, &statbuf)) { +- fprintf(stderr, "pesign: Error on stat input: %m\n"); +- exit(1); +- } +- +- ctx->outmode = statbuf.st_mode; +- ctx->inlength = statbuf.st_size; +-} +- +-static void +-close_input(pesign_context *ctx) +-{ +- close(ctx->infd); +- ctx->infd = -1; +-} +- +-static void +-open_output(pesign_context *ctx) +-{ +- if (!ctx->outfile) { +- fprintf(stderr, "pesign: No output file specified.\n"); +- exit(1); +- } +- +- if (access(ctx->outfile, F_OK) == 0 && ctx->force == 0) { +- fprintf(stderr, "pesign: \"%s\" exists and --force was " +- "not given.\n", ctx->outfile); +- exit(1); +- } +- +- ctx->outfd = open(ctx->outfile, O_RDWR|O_CREAT|O_TRUNC|O_CLOEXEC, +- ctx->outmode); +- if (ctx->outfd < 0) { +- fprintf(stderr, "pesign: Error opening output: %m\n"); +- exit(1); +- } +-} +- +-static void +-close_output(pesign_context *ctx) +-{ +- close(ctx->outfd); +- ctx->outfd = -1; +-} +- +-static void +-open_sig_output(pesign_context *ctx) +-{ +- if (!ctx->outsig) { +- fprintf(stderr, "pesign: No output file specified.\n"); +- exit(1); +- } +- +- if (access(ctx->outsig, F_OK) == 0 && ctx->force == 0) { +- fprintf(stderr, "pesign: \"%s\" exists and --force " +- "was not given.\n", ctx->outsig); +- exit(1); +- } +- +- ctx->outsigfd = open(ctx->outsig, O_RDWR|O_CREAT|O_TRUNC|O_CLOEXEC, +- ctx->outmode); +- if (ctx->outsigfd < 0) { +- fprintf(stderr, "pesign: Error opening signature for output: " +- "%m\n"); +- exit(1); +- } +-} +- +-static void +-close_sig_output(pesign_context *ctx) +-{ +- close(ctx->outsigfd); +- ctx->outsigfd = -1; +-} ++define_input_file(kmod, inkmod, "kmod"); ++define_output_file(kmod, outkmod, "kmod"); ++define_output_file(sig, outsig, "signature"); ++define_input_file(sig, insig, "signature"); + + static void + import_sig_input(pesign_context *ctx) +@@ -124,17 +38,7 @@ import_sig_input(pesign_context *ctx) + struct stat statbuf; + int rc; + +- if (!ctx->insig) { +- fprintf(stderr, "pesign: No input file specified.\n"); +- exit(1); +- } +- +- ctx->insigfd = open(ctx->insig, O_RDONLY|O_CLOEXEC); +- if (ctx->insigfd < 0) { +- fprintf(stderr, "pesign: Error opening signature for input: " +- "%m\n"); +- exit(1); +- } ++ open_sig_input(ctx); + + rc = fstat(ctx->insigfd, &statbuf); + conderr(rc < 0, 1, "Could not fstat signature file \"%s\"", +@@ -143,10 +47,10 @@ import_sig_input(pesign_context *ctx) + /* Copy original module data */ + + map = mmap(NULL, ctx->inlength, PROT_READ, MAP_PRIVATE, ctx->infd, 0); +- conderr(map == MAP_FAILED, 1, "Could not map kmod input"); ++ conderr(map == MAP_FAILED, 1, "Could not map kmod input file \"%s\"", ctx->inkmod); + + rc = write_file(ctx->outfd, map, ctx->inlength); +- conderr(rc < 0, 1, "Failed to write module data"); ++ conderr(rc < 0, 1, "Failed to write module data to \"%s\"", ctx->outkmod); + + munmap(map, ctx->inlength); + +@@ -171,7 +75,7 @@ handle_signing(pesign_context *ctx, int outfd, int attached) + ssize_t sig_len; + + inmap = mmap(NULL, ctx->inlength, PROT_READ, MAP_PRIVATE, ctx->infd, 0); +- conderrx(inmap == MAP_FAILED, 1, "Error mapping input kmod"); ++ conderr(inmap == MAP_FAILED, 1, "Could not map input kmod file \"%s\"", ctx->inkmod); + + rc = kmod_generate_digest(ctx->cms_ctx, inmap, ctx->inlength); + if (rc < 0) +@@ -179,7 +83,7 @@ handle_signing(pesign_context *ctx, int outfd, int attached) + + if (attached) { + rc = write_file(outfd, inmap, ctx->inlength); +- conderr(rc < 0, 1, "Failed to write module data"); ++ conderr(rc < 0, 1, "Failed to write module data to \"%s\"", ctx->outkmod); + } + munmap(inmap, ctx->inlength); + +@@ -205,11 +109,13 @@ kmod_handle_action(pesign_context *ctxp, int action) + conderrx(ctxp->signum > ctxp->cms_ctx->num_signatures + 1, + 1, "Invalid signature number."); + +- open_input(ctxp); +- open_output(ctxp); ++ open_kmod_input(ctxp); ++ proxy_fd_mode(ctxp->inkmodfd, ctxp->inkmod, ++ &ctxp->outmode, &ctxp->inlength); ++ open_kmod_output(ctxp); + handle_signing(ctxp, ctxp->outfd, 1); +- close_output(ctxp); +- close_input(ctxp); ++ close_kmod_output(ctxp); ++ close_kmod_input(ctxp); + break; + + /* generate a signature and save it in a separate file */ +@@ -220,22 +126,26 @@ kmod_handle_action(pesign_context *ctxp, int action) + conderrx(ctxp->signum > ctxp->cms_ctx->num_signatures + 1, + 1, "Invalid signature number."); + +- open_input(ctxp); ++ open_kmod_input(ctxp); ++ proxy_fd_mode(ctxp->inkmodfd, ctxp->inkmod, ++ &ctxp->outmode, &ctxp->inlength); + open_sig_output(ctxp); + handle_signing(ctxp, ctxp->outsigfd, 0); + close_sig_output(ctxp); +- close_input(ctxp); ++ close_kmod_input(ctxp); + break; + + /* add a signature from a file */ + case IMPORT_SIGNATURE: + conderrx(ctxp->signum > ctxp->cms_ctx->num_signatures + 1, + 1, "Invalid signature number."); +- open_input(ctxp); +- open_output(ctxp); ++ open_kmod_input(ctxp); ++ proxy_fd_mode(ctxp->inkmodfd, ctxp->inkmod, ++ &ctxp->outmode, &ctxp->inlength); ++ open_kmod_output(ctxp); + import_sig_input(ctxp); +- close_input(ctxp); +- close_output(ctxp); ++ close_kmod_input(ctxp); ++ close_kmod_output(ctxp); + break; + + default: +@@ -249,3 +159,5 @@ kmod_handle_action(pesign_context *ctxp, int action) + exit(1); + } + } ++ ++// vim:fenc=utf-8:tw=75:noet +diff --git a/src/pesign_context.h b/src/pesign_context.h +index 8d8dfbd294e..45d6831aa7f 100644 +--- a/src/pesign_context.h ++++ b/src/pesign_context.h +@@ -32,10 +32,22 @@ typedef enum { + } file_format; + + typedef struct { +- int infd; +- int outfd; +- char *infile; +- char *outfile; ++ union { ++ int infd; ++ int inkmodfd; ++ }; ++ union { ++ int outfd; ++ int outkmodfd; ++ }; ++ union { ++ char *infile; ++ char *inkmod; ++ }; ++ union { ++ char *outfile; ++ char *outkmod; ++ }; + size_t inlength; + mode_t outmode; + +diff --git a/src/util.h b/src/util.h +index 1b115a993f6..9b34f7b8886 100644 +--- a/src/util.h ++++ b/src/util.h +@@ -24,6 +24,8 @@ + #include + #include + #include ++#include ++#include + #include + + #include +@@ -207,4 +209,67 @@ content_is_empty(uint8_t *data, ssize_t len) + return 1; + } + ++#define define_input_file(fname, name, descr) \ ++ static void \ ++ CAT3(open_, fname, _input)(pesign_context *ctx) \ ++ { \ ++ conderrx(!ctx->name, 1, \ ++ "No input file specified for %s", \ ++ descr); \ ++ ctx->CAT(name, fd) = \ ++ open(ctx->name, O_RDONLY|O_CLOEXEC); \ ++ conderr(ctx->CAT(name, fd) < 0, 1, \ ++ "Error opening %s file \"%s\" for input", \ ++ descr, ctx->name); \ ++ } \ ++ static void \ ++ CAT3(close_, fname, _input)(pesign_context *ctx) \ ++ { \ ++ close(ctx->CAT(name, fd)); \ ++ ctx->CAT(name, fd) = -1; \ ++ } ++ ++#define define_output_file(fname, name, descr) \ ++ static void \ ++ CAT3(open_, fname, _output)(pesign_context *ctx) \ ++ { \ ++ conderrx(!ctx->name, 1, \ ++ "No output file specified for %s.", \ ++ descr); \ ++ \ ++ if (access(ctx->name, F_OK) == 0 && ctx->force == 0) \ ++ errx(1, \ ++ "\"%s\" exists and --force was not given.",\ ++ ctx->name); \ ++ \ ++ ctx->CAT(name, fd) = \ ++ open(ctx->name, \ ++ O_RDWR|O_CREAT|O_TRUNC|O_CLOEXEC, \ ++ ctx->outmode); \ ++ conderr(ctx->CAT(name, fd) < 0, 1, \ ++ "Error opening %s file \"%s\" for output", \ ++ descr, ctx->name); \ ++ } \ ++ static void \ ++ CAT3(close_, fname, _output)(pesign_context *ctx) \ ++ { \ ++ close(ctx->CAT(name,fd)); \ ++ ctx->CAT(name,fd) = -1; \ ++ } ++ ++static inline void ++proxy_fd_mode(int fd, char *infile, mode_t *outmode, size_t *inlength) ++{ ++ struct stat statbuf; ++ int rc; ++ ++ rc = fstat(fd, &statbuf); ++ conderr(rc < 0, 1, "Could not fstat \"%s\"", infile); ++ if (outmode) ++ *outmode = statbuf.st_mode; ++ if (inlength) ++ *inlength = statbuf.st_size; ++} ++ + #endif /* PESIGN_UTIL_H */ ++// vim:fenc=utf-8:tw=75:noet +-- +2.29.2 + diff --git a/0022-Make-verbose-work-in-efisiglist.patch b/0022-Make-verbose-work-in-efisiglist.patch new file mode 100644 index 0000000..a91e38a --- /dev/null +++ b/0022-Make-verbose-work-in-efisiglist.patch @@ -0,0 +1,66 @@ +From 1ec1a523216aa9b63120fa36c3732de3c4cbf546 Mon Sep 17 00:00:00 2001 +From: Peter Jones +Date: Tue, 16 Feb 2021 13:24:54 -0500 +Subject: [PATCH 22/42] Make verbose work in efisiglist + +Signed-off-by: Peter Jones +--- + src/efisiglist.c | 25 +++++++++++++++++++++++++ + 1 file changed, 25 insertions(+) + +diff --git a/src/efisiglist.c b/src/efisiglist.c +index b91e15bfb7b..48ff89c5661 100644 +--- a/src/efisiglist.c ++++ b/src/efisiglist.c +@@ -114,6 +114,15 @@ out_of_range: + return ret; + } + ++static long *verbose; ++ ++long verbosity(void) ++{ ++ if (!verbose) ++ return 0; ++ return *verbose; ++} ++ + int + main(int argc, char *argv[]) + { +@@ -128,9 +137,12 @@ main(int argc, char *argv[]) + int certfd = -1; + void *cert_data = NULL; + size_t cert_size = 0; ++ long esl_verbose = 0; + + int add = 1; + ++ verbose = &esl_verbose; ++ + struct poptOption options[] = { + {.argInfo = POPT_ARG_INTL_DOMAIN, + .arg = "pesign" }, +@@ -175,6 +187,19 @@ main(int argc, char *argv[]) + .arg = &certfile, + .descrip = "certificate to add", + .argDescrip = "" }, ++ {.longName = "verbose", ++ .shortName = 'v', ++ .argInfo = POPT_ARG_VAL|POPT_ARG_LONG|POPT_ARGFLAG_OPTIONAL, ++ .arg = &esl_verbose, ++ .val = 1, ++ .descrip = "be more verbose" }, ++ {.longName = "debug", ++ .shortName = '\0', ++ .argInfo = POPT_ARG_VAL|POPT_ARG_LONG|POPT_ARGFLAG_OPTIONAL, ++ .arg = &esl_verbose, ++ .val = 2, ++ .descrip = "be very verbose" }, ++ + POPT_AUTOALIAS + POPT_AUTOHELP + POPT_TABLEEND +-- +2.29.2 + diff --git a/0023-Make-verbose-and-debug-more-similar-across-tools.patch b/0023-Make-verbose-and-debug-more-similar-across-tools.patch new file mode 100644 index 0000000..45d8526 --- /dev/null +++ b/0023-Make-verbose-and-debug-more-similar-across-tools.patch @@ -0,0 +1,321 @@ +From 8fc539b9712c0e736abfdd3b493d97f7107e91ec Mon Sep 17 00:00:00 2001 +From: Peter Jones +Date: Tue, 28 Apr 2020 10:08:03 -0400 +Subject: [PATCH 23/42] Make --verbose and --debug more similar across tools + +Signed-off-by: Peter Jones +--- + src/authvar.c | 21 +++++++++++++++++++++ + src/client.c | 18 ++++++++++++++++++ + src/cms_pe_common.c | 6 ------ + src/efikeygen.c | 21 +++++++++++++++++++++ + src/pesigcheck.c | 18 +++++++++++++++++- + src/pesign.c | 19 ++++++++++++++++++- + src/authvar_context.h | 2 ++ + src/pesigcheck_context.h | 2 +- + src/pesign_context.h | 2 +- + src/util.h | 14 +++++++++++++- + 10 files changed, 112 insertions(+), 11 deletions(-) + +diff --git a/src/authvar.c b/src/authvar.c +index f9a7dcef9f7..a6c3970e4dc 100644 +--- a/src/authvar.c ++++ b/src/authvar.c +@@ -260,6 +260,15 @@ show_signature_support(void) + return 0; + } + ++static long *verbose; ++ ++long verbosity(void) ++{ ++ if (!verbose) ++ return 0; ++ return *verbose; ++} ++ + int + main(int argc, char *argv[]) + { +@@ -370,6 +379,18 @@ main(int argc, char *argv[]) + .arg = &ctx.cms_ctx->certname, + .descrip = "sign variable with certificate ", + .argDescrip = "" }, ++ {.longName = "verbose", ++ .shortName = 'v', ++ .argInfo = POPT_ARG_VAL|POPT_ARG_LONG|POPT_ARGFLAG_OPTIONAL, ++ .arg = &ctxp->verbose, ++ .val = 1, ++ .descrip = "be more verbose" }, ++ {.longName = "debug", ++ .shortName = '\0', ++ .argInfo = POPT_ARG_VAL|POPT_ARG_LONG|POPT_ARGFLAG_OPTIONAL, ++ .arg = &ctxp->verbose, ++ .val = 2, ++ .descrip = "be very verbose" }, + POPT_AUTOALIAS + POPT_AUTOHELP + POPT_TABLEEND +diff --git a/src/client.c b/src/client.c +index a4f1d1dbbe7..a00b20f5dde 100644 +--- a/src/client.c ++++ b/src/client.c +@@ -600,6 +600,12 @@ oom: + return; + } + ++static long verbose; ++long verbosity(void) ++{ ++ return verbose; ++} ++ + int + main(int argc, char *argv[]) + { +@@ -687,6 +693,18 @@ main(int argc, char *argv[]) + .arg = &pinfile, + .descrip = "read named file for pin information", + .argDescrip = "" }, ++ {.longName = "verbose", ++ .shortName = 'v', ++ .argInfo = POPT_ARG_VAL, ++ .arg = &verbose, ++ .val = 1, ++ .descrip = "be more verbose" }, ++ {.longName = "debug", ++ .shortName = '\0', ++ .argInfo = POPT_ARG_VAL|POPT_ARG_LONG|POPT_ARGFLAG_OPTIONAL, ++ .arg = &verbose, ++ .val = 2, ++ .descrip = "be very verbose" }, + POPT_AUTOALIAS + POPT_AUTOHELP + POPT_TABLEEND +diff --git a/src/cms_pe_common.c b/src/cms_pe_common.c +index 05f72e4431a..00061804a78 100644 +--- a/src/cms_pe_common.c ++++ b/src/cms_pe_common.c +@@ -42,12 +42,6 @@ + #include + #include + +-#if 1 +-#define dprintf(fmt, ...) +-#else +-#define dprintf(fmt, args...) printf(fmt, ## args) +-#endif +- + static int + check_pointer_and_size(Pe *pe, void *ptr, size_t size) + { +diff --git a/src/efikeygen.c b/src/efikeygen.c +index ac2ce45a420..b1cac4705e8 100644 +--- a/src/efikeygen.c ++++ b/src/efikeygen.c +@@ -492,6 +492,13 @@ SEC_ASN1EncodeLongLong(PRArenaPool *poolp, SECItem *dest, + return dest; + } + ++static long verbose = 0; ++ ++long verbosity(void) ++{ ++ return verbose; ++} ++ + int main(int argc, char *argv[]) + { + int is_ca = 0; +@@ -586,6 +593,18 @@ int main(int argc, char *argv[]) + .arg = &serial_str, + .descrip = "Serial number (default: random)", + .argDescrip = "" }, ++ {.longName = "verbose", ++ .shortName = 'v', ++ .argInfo = POPT_ARG_VAL, ++ .arg = &verbose, ++ .val = 1, ++ .descrip = "Be more verbose" }, ++ {.longName = "debug", ++ .shortName = '\0', ++ .argInfo = POPT_ARG_VAL|POPT_ARG_LONG|POPT_ARGFLAG_OPTIONAL, ++ .arg = &verbose, ++ .val = 2, ++ .descrip = "Be very verbose" }, + + /* hidden things */ + {.longName = "pubkey", +@@ -870,3 +889,5 @@ int main(int argc, char *argv[]) + NSS_Shutdown(); + return 0; + } ++ ++// vim:fenc=utf-8:tw=75:noet +diff --git a/src/pesigcheck.c b/src/pesigcheck.c +index 961a32a6ad7..87d4960a9a9 100644 +--- a/src/pesigcheck.c ++++ b/src/pesigcheck.c +@@ -386,6 +386,15 @@ callback(poptContext con UNUSED, + } + } + ++static long *verbose; ++ ++long verbosity(void) ++{ ++ if (!verbose) ++ return 0; ++ return *verbose; ++} ++ + int + main(int argc, char *argv[]) + { +@@ -436,10 +445,16 @@ main(int argc, char *argv[]) + .descrip = "return only; no text output." }, + {.longName = "verbose", + .shortName = 'v', +- .argInfo = POPT_BIT_SET, ++ .argInfo = POPT_ARG_VAL|POPT_ARG_LONG|POPT_ARGFLAG_OPTIONAL, + .arg = &ctx.verbose, + .val = 1, + .descrip = "print reasons for success and failure." }, ++ {.longName = "debug", ++ .shortName = '\0', ++ .argInfo = POPT_ARG_VAL|POPT_ARG_LONG|POPT_ARGFLAG_OPTIONAL, ++ .arg = &ctxp->verbose, ++ .val = 2, ++ .descrip = "be very verbose" }, + {.longName = "no-system-db", + .shortName = 'n', + .argInfo = POPT_ARG_INT, +@@ -475,6 +490,7 @@ main(int argc, char *argv[]) + fprintf(stderr, "pesigcheck: Could not initialize context: %m\n"); + exit(1); + } ++ verbose = &ctxp->verbose; + + optCon = poptGetContext("pesigcheck", argc, (const char **)argv, + options,0); +diff --git a/src/pesign.c b/src/pesign.c +index d2f3f221df0..854120c15c5 100644 +--- a/src/pesign.c ++++ b/src/pesign.c +@@ -64,6 +64,15 @@ print_flag_name(FILE *f, int flag) + } + } + ++static long *verbose; ++ ++long verbosity(void) ++{ ++ if (!verbose) ++ return 0; ++ return *verbose; ++} ++ + int + main(int argc, char *argv[]) + { +@@ -94,6 +103,7 @@ main(int argc, char *argv[]) + fprintf(stderr, "Could not initialize context: %m\n"); + exit(1); + } ++ verbose = &ctxp->verbose; + + poptContext optCon; + struct poptOption options[] = { +@@ -234,10 +244,17 @@ main(int argc, char *argv[]) + .descrip = "don't fork when daemonizing" }, + {.longName = "verbose", + .shortName = 'v', +- .argInfo = POPT_ARG_VAL, ++ .argInfo = POPT_ARG_VAL|POPT_ARG_LONG|POPT_ARGFLAG_OPTIONAL, + .arg = &ctxp->verbose, + .val = 1, ++ .descrip = "be more verbose" }, ++ {.longName = "debug", ++ .shortName = '\0', ++ .argInfo = POPT_ARG_VAL|POPT_ARG_LONG|POPT_ARGFLAG_OPTIONAL, ++ .arg = &ctxp->verbose, ++ .val = 2, + .descrip = "be very verbose" }, ++ + {.longName = "padding", + .shortName = 'P', + .argInfo = POPT_ARG_VAL, +diff --git a/src/authvar_context.h b/src/authvar_context.h +index e9250dd250f..13c18a988f4 100644 +--- a/src/authvar_context.h ++++ b/src/authvar_context.h +@@ -20,6 +20,8 @@ + #define AUTHVAR_CONTEXT_H 1 + + typedef struct { ++ long verbose; ++ + char *namespace; + efi_guid_t guid; + char *name; +diff --git a/src/pesigcheck_context.h b/src/pesigcheck_context.h +index aec415e0cbe..fa72439c875 100644 +--- a/src/pesigcheck_context.h ++++ b/src/pesigcheck_context.h +@@ -61,7 +61,7 @@ typedef struct pesigcheck_context { + Pe *inpe; + + int quiet; +- int verbose; ++ long verbose; + + hashlist *hashes; + +diff --git a/src/pesign_context.h b/src/pesign_context.h +index 45d6831aa7f..0af044d92b4 100644 +--- a/src/pesign_context.h ++++ b/src/pesign_context.h +@@ -52,7 +52,7 @@ typedef struct { + mode_t outmode; + + int force; +- int verbose; ++ long verbose; + + char *rawsig; + int rawsigfd; +diff --git a/src/util.h b/src/util.h +index 9b34f7b8886..21a846c10ee 100644 +--- a/src/util.h ++++ b/src/util.h +@@ -24,8 +24,9 @@ + #include + #include + #include +-#include + #include ++#include ++#include + #include + + #include +@@ -271,5 +272,16 @@ proxy_fd_mode(int fd, char *infile, mode_t *outmode, size_t *inlength) + *inlength = statbuf.st_size; + } + ++extern long verbosity(void); ++ ++#define dprintf_(tv, file, func, line, fmt, args...) ({struct timeval tv; gettimeofday(&tv, NULL); warnx("%ld.%lu %s:%s():%d: " fmt, tv.tv_sec, tv.tv_usec, file, func, line, ##args); }) ++#if defined(PESIGN_DEBUG) ++#define dprintf(fmt, args...) dprintf_(CAT(CAT(CAT(tv_,__COUNTER__),__LINE__),_), __FILE__, __func__, __LINE__, fmt, ##args) ++#else ++#define dprintf(fmt, args...) ({ if (verbosity() > 1) dprintf_(CAT(CAT(CAT(tv_,__COUNTER__),__LINE__),_), __FILE__, __func__, __LINE__, fmt, ##args); 0; }) ++#endif ++#define ingress() dprintf("ingress"); ++#define egress() dprintf("egress"); ++ + #endif /* PESIGN_UTIL_H */ + // vim:fenc=utf-8:tw=75:noet +-- +2.29.2 + diff --git a/0024-Work-around-some-NSS-SECOID_AddEntry-bugs.patch b/0024-Work-around-some-NSS-SECOID_AddEntry-bugs.patch new file mode 100644 index 0000000..102e5e4 --- /dev/null +++ b/0024-Work-around-some-NSS-SECOID_AddEntry-bugs.patch @@ -0,0 +1,46 @@ +From fe2c0facc37f01bdcca8362cc4db7dbd701b6959 Mon Sep 17 00:00:00 2001 +From: Peter Jones +Date: Tue, 28 Apr 2020 10:18:08 -0400 +Subject: [PATCH 24/42] Work around some NSS SECOID_AddEntry() bugs + +Signed-off-by: Peter Jones +--- + src/oid.c | 14 +++++++++++--- + 1 file changed, 11 insertions(+), 3 deletions(-) + +diff --git a/src/oid.c b/src/oid.c +index 4d95ede4046..a2e63093c00 100644 +--- a/src/oid.c ++++ b/src/oid.c +@@ -72,17 +72,25 @@ static struct { + SECStatus + register_oids(cms_context *cms) + { ++ int err = PORT_GetError(); ++ PORT_SetError(0); + for (int i = 0; oids[i].oid != END_OID_LIST; i++) { + SECOidTag rc; + rc = SECOID_AddEntry(&oids[i].sod); + oids[i].sod.offset = rc; + if (rc == SEC_OID_UNKNOWN) { +- cms->log(cms, LOG_ERR, "SECOid_AddEntry() failed: %s", +- PORT_ErrorToString(PORT_GetError())); +- return SECFailure; ++ cmsreterr(SECFailure, cms, ++ "SECOid_AddEntry() failed: %s", ++ PORT_ErrorToString(PORT_GetError())); ++ } else { + } + } + ++ /* ++ * SECOID_AddEntry() leaves the error status that it ++ * used to look it up set. This is very annoying. ++ */ ++ PORT_SetError(err); + return SECSuccess; + } + +-- +2.29.2 + diff --git a/0025-Rework-the-wildly-undocumented-NSS-password-file-goo.patch b/0025-Rework-the-wildly-undocumented-NSS-password-file-goo.patch new file mode 100644 index 0000000..9a0be72 --- /dev/null +++ b/0025-Rework-the-wildly-undocumented-NSS-password-file-goo.patch @@ -0,0 +1,1385 @@ +From db4e0e71d71d794b4d95bfc90145ea243f7d064b Mon Sep 17 00:00:00 2001 +From: Peter Jones +Date: Tue, 28 Apr 2020 10:21:52 -0400 +Subject: [PATCH 25/42] Rework the wildly undocumented NSS password file goo. + +This probably doesn't work yet. +--- + src/cms_common.c | 223 ++++++++++------ + src/cms_pe_common.c | 2 +- + src/daemon.c | 8 +- + src/password.c | 614 +++++++++++++++++++++++++++++--------------- + src/pesign.c | 45 +++- + src/signer_info.c | 9 +- + src/cms_common.h | 57 +++- + 7 files changed, 646 insertions(+), 312 deletions(-) + +diff --git a/src/cms_common.c b/src/cms_common.c +index 75a95f053a2..c2f34e515a2 100644 +--- a/src/cms_common.c ++++ b/src/cms_common.c +@@ -164,11 +164,31 @@ cms_context_fini(cms_context *cms) + cms->cert = NULL; + } + ++ switch (cms->pwdata.source) { ++ case PW_SOURCE_INVALID: ++ case PW_PROMPT: ++ case PW_DEVICE: ++ case PW_FROMFILEDB: ++ case PW_FROMENV: ++ case PW_SOURCE_MAX: ++ break; ++ case PW_DATABASE: ++ xfree(cms->pwdata.data); ++ break; ++ case PW_PLAINTEXT: ++ memset(cms->pwdata.data, 0, strlen(cms->pwdata.data)); ++ xfree(cms->pwdata.data); ++ break; ++ } ++ cms->pwdata.source = PW_SOURCE_INVALID; ++ cms->pwdata.orig_source = PW_SOURCE_INVALID; ++ + if (cms->privkey) { + free(cms->privkey); + cms->privkey = NULL; + } + ++ + /* These were freed when the arena was destroyed */ + if (cms->tokenname) + cms->tokenname = NULL; +@@ -255,9 +275,35 @@ void cms_set_pw_callback(cms_context *cms, PK11PasswordFunc func) + cms->func = func; + } + +-void cms_set_pw_data(cms_context *cms, void *pwdata) ++void cms_set_pw_data(cms_context *cms, secuPWData *pwdata) + { +- cms->pwdata = pwdata; ++ ingress(); ++ ++ switch (cms->pwdata.source) { ++ case PW_SOURCE_INVALID: ++ case PW_PROMPT: ++ case PW_DEVICE: ++ case PW_SOURCE_MAX: ++ break; ++ ++ case PW_FROMENV: ++ case PW_FROMFILEDB: ++ case PW_PLAINTEXT: ++ memset(cms->pwdata.data, 0, strlen(cms->pwdata.data)); ++ xfree(cms->pwdata.data); ++ break; ++ ++ case PW_DATABASE: ++ xfree(cms->pwdata.data); ++ break; ++ } ++ memmove(&cms->pwdata, pwdata, sizeof(*pwdata)); ++ ++ dprintf("pwdata:%p", pwdata); ++ dprintf("pwdata->source:%d", pwdata->source); ++ dprintf("pwdata->data:%p (\"%s\")", pwdata->data, ++ pwdata->data ? pwdata->data : "(null)"); ++ egress(); + } + + int +@@ -280,24 +326,26 @@ set_digest_parameters(cms_context *cms, char *name) + return -1; + } + +-struct cbdata { +- CERTCertificate *cert; ++struct validity_cbdata { ++ cms_context *cms; + PK11SlotListElement *psle; +- secuPWData *pwdata; ++ PK11SlotInfo *slot; ++ CERTCertificate *cert; + }; + + static SECStatus + is_valid_cert(CERTCertificate *cert, void *data) + { +- struct cbdata *cbdata = (struct cbdata *)data; +- +- PK11SlotInfo *slot = cbdata->psle->slot; +- void *pwdata = cbdata->pwdata; +- ++ struct validity_cbdata *cbd = (struct validity_cbdata *)data; ++ PK11SlotInfo *slot = cbd->slot; + SECKEYPrivateKey *privkey = NULL; +- privkey = PK11_FindPrivateKeyFromCert(slot, cert, pwdata); ++ ++ if (cert == NULL) ++ return SECFailure; ++ ++ privkey = PK11_FindPrivateKeyFromCert(slot, cert, cbd->cms); + if (privkey != NULL) { +- cbdata->cert = cert; ++ cbd->cert = CERT_DupCertificate(cert); + SECKEY_DestroyPrivateKey(privkey); + return SECSuccess; + } +@@ -307,9 +355,15 @@ is_valid_cert(CERTCertificate *cert, void *data) + static SECStatus + is_valid_cert_without_private_key(CERTCertificate *cert, void *data) + { +- struct cbdata *cbdata = (struct cbdata *)data; +- if (cert) { +- cbdata->cert = cert; ++ struct validity_cbdata *cbd = (struct validity_cbdata *)data; ++ PK11SlotInfo *slot = cbd->slot; ++ SECKEYPrivateKey *privkey = NULL; ++ ++ if (cert == NULL) ++ return SECFailure; ++ privkey = PK11_FindPrivateKeyFromCert(slot, cert, cbd->cms); ++ if (privkey == NULL) { ++ cbd->cert = CERT_DupCertificate(cert); + return SECSuccess; + } + return SECFailure; +@@ -338,12 +392,10 @@ PK11_DestroySlotListElement(PK11SlotList *slots, PK11SlotListElement **psle) + int + unlock_nss_token(cms_context *cms) + { +- secuPWData pwdata_val = { 0, 0 }; +- void *pwdata = cms->pwdata ? cms->pwdata : &pwdata_val; + PK11_SetPasswordFunc(cms->func ? cms->func : SECU_GetModulePassword); + + PK11SlotList *slots = NULL; +- slots = PK11_GetAllTokens(CKM_RSA_PKCS, PR_FALSE, PR_TRUE, pwdata); ++ slots = PK11_GetAllTokens(CKM_RSA_PKCS, PR_FALSE, PR_TRUE, cms); + if (!slots) + cmsreterr(-1, cms, "could not get pk11 token list"); + +@@ -367,20 +419,21 @@ unlock_nss_token(cms_context *cms) + save_port_err() { + PK11_FreeSlotList(slots); + } +- cms->log(cms, LOG_ERR, "could not find token \"%s\"", +- cms->tokenname); +- return -1; ++ nssreterr(-1, "Could not find token \"%s\"", cms->tokenname); + } + + SECStatus status; + if (PK11_NeedLogin(psle->slot) && +- !PK11_IsLoggedIn(psle->slot, pwdata)) { +- status = PK11_Authenticate(psle->slot, PR_TRUE, pwdata); ++ !PK11_IsLoggedIn(psle->slot, cms)) { ++ status = PK11_Authenticate(psle->slot, PR_TRUE, cms); + if (status != SECSuccess) { +- PK11_DestroySlotListElement(slots, &psle); +- PK11_FreeSlotList(slots); +- cms->log(cms, LOG_ERR, "authentication failed for " +- "token \"%s\"", cms->tokenname); ++ save_port_err() { ++ PK11_DestroySlotListElement(slots, &psle); ++ PK11_FreeSlotList(slots); ++ cms->log(cms, LOG_ERR, ++ "authentication failed for token \"%s\"", ++ cms->tokenname); ++ } + return -1; + } + } +@@ -393,17 +446,16 @@ unlock_nss_token(cms_context *cms) + int + find_certificate(cms_context *cms, int needs_private_key) + { ++ struct validity_cbdata cbd; + if (!cms->certname || !*cms->certname) { + cms->log(cms, LOG_ERR, "no certificate name specified"); + return -1; + } + +- secuPWData pwdata_val = { 0, 0 }; +- void *pwdata = cms->pwdata ? cms->pwdata : &pwdata_val; + PK11_SetPasswordFunc(cms->func ? cms->func : SECU_GetModulePassword); + + PK11SlotList *slots = NULL; +- slots = PK11_GetAllTokens(CKM_RSA_PKCS, PR_FALSE, PR_TRUE, pwdata); ++ slots = PK11_GetAllTokens(CKM_RSA_PKCS, PR_FALSE, PR_TRUE, cms); + if (!slots) + cmsreterr(-1, cms, "could not get pk11 token list"); + +@@ -427,19 +479,20 @@ find_certificate(cms_context *cms, int needs_private_key) + save_port_err() { + PK11_FreeSlotList(slots); + } +- cms->log(cms, LOG_ERR, "could not find token \"%s\"", +- cms->tokenname); +- return -1; ++ nssreterr(-1, "Could not find token \"%s\"", cms->tokenname); + } + + SECStatus status; +- if (PK11_NeedLogin(psle->slot) && !PK11_IsLoggedIn(psle->slot, pwdata)) { +- status = PK11_Authenticate(psle->slot, PR_TRUE, pwdata); ++ if (PK11_NeedLogin(psle->slot) && !PK11_IsLoggedIn(psle->slot, cms)) { ++ status = PK11_Authenticate(psle->slot, PR_TRUE, cms); + if (status != SECSuccess) { +- PK11_DestroySlotListElement(slots, &psle); +- PK11_FreeSlotList(slots); +- cms->log(cms, LOG_ERR, "authentication failed for " +- "token \"%s\"", cms->tokenname); ++ save_port_err() { ++ PK11_DestroySlotListElement(slots, &psle); ++ PK11_FreeSlotList(slots); ++ cms->log(cms, LOG_ERR, ++ "authentication failed for token \"%s\"", ++ cms->tokenname); ++ } + return -1; + } + } +@@ -459,35 +512,37 @@ find_certificate(cms_context *cms, int needs_private_key) + .len = strlen(cms->certname) + 1, + .type = siUTF8String, + }; +- struct cbdata cbdata = { +- .cert = NULL, +- .psle = psle, +- .pwdata = pwdata, +- }; ++ ++ cms->psle = psle; ++ ++ cbd.cms = cms; ++ cbd.psle = psle; ++ cbd.slot = psle->slot; ++ cbd.cert = NULL; + + if (needs_private_key) { + status = PK11_TraverseCertsForNicknameInSlot(&nickname, +- psle->slot, is_valid_cert, &cbdata); ++ psle->slot, is_valid_cert, &cbd); + } else { + status = PK11_TraverseCertsForNicknameInSlot(&nickname, + psle->slot, + is_valid_cert_without_private_key, +- &cbdata); ++ &cbd); + } +- if (status != SECSuccess || cbdata.cert == NULL) { +- save_port_err() { +- CERT_DestroyCertList(certlist); +- PK11_DestroySlotListElement(slots, &psle); +- PK11_FreeSlotList(slots); +- } ++ if (status == SECSuccess && cbd.cert != NULL) { ++ if (cms->cert) ++ CERT_DestroyCertificate(cms->cert); ++ cms->cert = CERT_DupCertificate(cbd.cert); ++ } ++ ++ save_port_err() { ++ CERT_DestroyCertList(certlist); ++ PK11_DestroySlotListElement(slots, &psle); ++ PK11_FreeSlotList(slots); ++ cms->psle = NULL; ++ } ++ if (status != SECSuccess || cms->cert == NULL) + cmsreterr(-1, cms, "could not find certificate in list"); +- } +- +- cms->cert = CERT_DupCertificate(cbdata.cert); +- +- PK11_DestroySlotListElement(slots, &psle); +- PK11_FreeSlotList(slots); +- CERT_DestroyCertList(certlist); + + return 0; + } +@@ -500,12 +555,10 @@ find_slot_for_token(cms_context *cms, PK11SlotInfo **slot) + return -1; + } + +- secuPWData pwdata_val = { 0, 0 }; +- void *pwdata = cms->pwdata ? cms->pwdata : &pwdata_val; + PK11_SetPasswordFunc(cms->func ? cms->func : SECU_GetModulePassword); + + PK11SlotList *slots = NULL; +- slots = PK11_GetAllTokens(CKM_RSA_PKCS, PR_FALSE, PR_TRUE, pwdata); ++ slots = PK11_GetAllTokens(CKM_RSA_PKCS, PR_FALSE, PR_TRUE, cms); + if (!slots) + cmsreterr(-1, cms, "could not get pk11 token list"); + +@@ -529,19 +582,20 @@ find_slot_for_token(cms_context *cms, PK11SlotInfo **slot) + save_port_err() { + PK11_FreeSlotList(slots); + } +- cms->log(cms, LOG_ERR, "could not find token \"%s\"", +- cms->tokenname); +- return -1; ++ nssreterr(-1, "Could not find token \"%s\"", cms->tokenname); + } + + SECStatus status; +- if (PK11_NeedLogin(psle->slot) && !PK11_IsLoggedIn(psle->slot, pwdata)) { +- status = PK11_Authenticate(psle->slot, PR_TRUE, pwdata); ++ if (PK11_NeedLogin(psle->slot) && !PK11_IsLoggedIn(psle->slot, cms)) { ++ status = PK11_Authenticate(psle->slot, PR_TRUE, cms); + if (status != SECSuccess) { +- PK11_DestroySlotListElement(slots, &psle); +- PK11_FreeSlotList(slots); +- cms->log(cms, LOG_ERR, "authentication failed for " +- "token \"%s\"", cms->tokenname); ++ save_port_err() { ++ PK11_DestroySlotListElement(slots, &psle); ++ PK11_FreeSlotList(slots); ++ cms->log(cms, LOG_ERR, ++ "authentication failed for token \"%s\"", ++ cms->tokenname); ++ } + return -1; + } + } +@@ -557,12 +611,10 @@ find_named_certificate(cms_context *cms, char *name, CERTCertificate **cert) + return -1; + } + +- secuPWData pwdata_val = { 0, 0 }; +- void *pwdata = cms->pwdata ? cms->pwdata : &pwdata_val; + PK11_SetPasswordFunc(cms->func ? cms->func : SECU_GetModulePassword); + + PK11SlotList *slots = NULL; +- slots = PK11_GetAllTokens(CKM_RSA_PKCS, PR_FALSE, PR_TRUE, pwdata); ++ slots = PK11_GetAllTokens(CKM_RSA_PKCS, PR_FALSE, PR_TRUE, cms); + if (!slots) + cmsreterr(-1, cms, "could not get pk11 token list"); + +@@ -585,20 +637,23 @@ find_named_certificate(cms_context *cms, char *name, CERTCertificate **cert) + if (!psle) { + save_port_err() { + PK11_FreeSlotList(slots); ++ cms->log(cms, LOG_ERR, "could not find token \"%s\"", ++ cms->tokenname); + } +- cms->log(cms, LOG_ERR, "could not find token \"%s\"", +- cms->tokenname); + return -1; + } + + SECStatus status; +- if (PK11_NeedLogin(psle->slot) && !PK11_IsLoggedIn(psle->slot, pwdata)) { +- status = PK11_Authenticate(psle->slot, PR_TRUE, pwdata); ++ if (PK11_NeedLogin(psle->slot) && !PK11_IsLoggedIn(psle->slot, cms)) { ++ status = PK11_Authenticate(psle->slot, PR_TRUE, cms); + if (status != SECSuccess) { +- PK11_DestroySlotListElement(slots, &psle); +- PK11_FreeSlotList(slots); +- cms->log(cms, LOG_ERR, "authentication failed for " +- "token \"%s\"", cms->tokenname); ++ save_port_err() { ++ PK11_DestroySlotListElement(slots, &psle); ++ PK11_FreeSlotList(slots); ++ cms->log(cms, LOG_ERR, ++ "authentication failed for token \"%s\"", ++ cms->tokenname); ++ } + return -1; + } + } +@@ -1492,14 +1547,14 @@ generate_keys(cms_context *cms, PK11SlotInfo *slot, + }; + + SECStatus rv; +- rv = PK11_Authenticate(slot, PR_TRUE, cms->pwdata); ++ rv = PK11_Authenticate(slot, PR_TRUE, cms); + if (rv != SECSuccess) + cmsreterr(-1, cms, "could not authenticate with pk11 service"); + + void *params = &rsaparams; + *privkey = PK11_GenerateKeyPair(slot, CKM_RSA_PKCS_KEY_PAIR_GEN, + params, pubkey, PR_TRUE, PR_TRUE, +- cms->pwdata); ++ cms); + if (!*privkey) + cmsreterr(-1, cms, "could not generate RSA keypair"); + return 0; +diff --git a/src/cms_pe_common.c b/src/cms_pe_common.c +index 00061804a78..bd96fe91d69 100644 +--- a/src/cms_pe_common.c ++++ b/src/cms_pe_common.c +@@ -275,7 +275,7 @@ generate_digest(cms_context *cms, Pe *pe, int padded) + char *name = shdrs[i].name; + if (name && name[0] == '/') + name = get_str(pe, name + 1); +- dprintf("section:\"%s\"\n", name); ++ dprintf("section:\"%s\"\n", name ? name : "(null)"); + if (name && !strcmp(name, ".vendor_cert")) { + dprintf("skipping .vendor_cert section\n"); + hashed_bytes += hash_size; +diff --git a/src/daemon.c b/src/daemon.c +index 8522250c2b4..9a804b37e64 100644 +--- a/src/daemon.c ++++ b/src/daemon.c +@@ -237,8 +237,14 @@ malformed: + if (!pin) + goto oom; + ++ secuPWData pwdata; ++ ++ memset(&pwdata, 0, sizeof(pwdata)); ++ pwdata.source = pwdata.orig_source = PW_PLAINTEXT; ++ pwdata.data = pin; ++ + cms_set_pw_callback(ctx->cms, get_password_passthrough); +- cms_set_pw_data(ctx->cms, pin); ++ cms_set_pw_data(ctx->cms, &pwdata); + + rc = unlock_nss_token(ctx->cms); + +diff --git a/src/password.c b/src/password.c +index 0da880a659d..0a4ef411ff7 100644 +--- a/src/password.c ++++ b/src/password.c +@@ -19,14 +19,17 @@ + + #include "fix_coverity.h" + ++#include + #include + #include ++#include + #include + #include + + #include "pesign.h" + + #include ++#include + #include + #include + #include +@@ -35,207 +38,324 @@ + #include + #include + +-static void echoOff(int fd) ++#include "list.h" ++ ++static const char * const pw_source_names[] = { ++ [PW_SOURCE_INVALID] = "PW_SOURCE_INVALID", ++ [PW_PROMPT] = "PW_PROMPT", ++ [PW_DEVICE] = "PW_DEVICE", ++ [PW_PLAINTEXT] = "PW_PLAINTEXT", ++ [PW_FROMFILEDB] = "PW_FROMFILEDB", ++ [PW_DATABASE] = "PW_DATABASE", ++ [PW_FROMENV] = "PW_FROMENV", ++ ++ [PW_SOURCE_MAX] = "PW_SOURCE_MAX" ++}; ++ ++static void ++print_prompt(FILE *in, FILE *out, char *prompt) + { +- if (isatty(fd)) { ++ int infd = fileno(in); + struct termios tio; +- tcgetattr(fd, &tio); ++ ++ if (!isatty(infd)) ++ return; ++ ++ fprintf(out, "%s", prompt); ++ fflush(out); ++ ++ tcgetattr(infd, &tio); + tio.c_lflag &= ~ECHO; +- tcsetattr(fd, TCSAFLUSH, &tio); +- } ++ tcsetattr(infd, TCSAFLUSH, &tio); + } + +-static void echoOn(int fd) ++static inline char * ++get_env(const char *name) + { +- if (isatty(fd)) { ++ char *value; ++ ++ value = secure_getenv(name); ++ if (value) ++ value = strdup(value); ++ return value; ++} ++ ++static int ++read_password(FILE *in, FILE *out, char *buf, size_t bufsz) ++{ ++ int infd = fileno(in); + struct termios tio; +- tcgetattr(fd, &tio); +- tio.c_lflag |= ECHO; +- tcsetattr(fd, TCSAFLUSH, &tio); +- } ++ char *ret; ++ ++ ret = fgets(buf, bufsz, in); ++ ++ if (isatty(infd)) { ++ fprintf(out, "\n"); ++ fflush(out); ++ ++ tcgetattr(infd, &tio); ++ tio.c_lflag |= ECHO; ++ tcsetattr(infd, TCSAFLUSH, &tio); ++ } ++ if (ret == NULL) ++ return -1; ++ ++ buf[strlen(buf)-1] = '\0'; ++ return 0; + } + +-static PRBool SEC_BlindCheckPassword(char *cp) ++static PRBool ++check_password(char *cp) + { +- if (cp != NULL) { ++ unsigned int i; ++ ++ if (cp == NULL) ++ return PR_FALSE; ++ ++ for (i = 0; cp[i] != 0; i++) { ++ if (!isprint(cp[i])) ++ return PR_FALSE; ++ } ++ if (i == 0) ++ return PR_FALSE; + return PR_TRUE; +- } +- return PR_FALSE; + } + +-static char *SEC_GetPassword(FILE *input, FILE *output, char *prompt, +- PRBool (*ok)(char *)) ++static char * ++get_password(FILE *input, FILE *output, char *prompt, PRBool (*ok)(char *)) + { +- int infd = fileno(input); +- int isTTY = isatty(infd); +- char phrase[200] = {'\0'}; /* ensure EOF doesn't return junk */ +- +- for (;;) { +- /* Prompt for password */ +- if (isTTY) { +- echoOff(infd); +- fprintf(output, "%s", prompt); +- fflush (output); +- } ++ int infd = fileno(input); ++ char phrase[200]; ++ size_t size = sizeof(phrase); + +- fgets ( phrase, sizeof(phrase), input); ++ ingress(); ++ memset(phrase, 0, size); + +- if (isTTY) { +- fprintf(output, "\n"); +- echoOn(infd); +- } ++ while(true) { ++ int rc; + +- /* stomp on newline */ +- phrase[PORT_Strlen(phrase)-1] = 0; ++ print_prompt(input, output, prompt); ++ rc = read_password(input, output, phrase, size); ++ if (rc < 0) ++ return NULL; + +- /* Validate password */ +- if (!(*ok)(phrase)) { +- /* Not weird enough */ +- if (!isTTY) return 0; +- fprintf(output, "Password must be at least 8 characters long with one or more\n"); +- fprintf(output, "non-alphabetic characters\n"); +- continue; ++ if (!ok) ++ break; ++ ++ if ((*ok)(phrase)) ++ break; ++ ++ if (!isatty(infd)) ++ return NULL; ++ fprintf(output, "Password does not meet requirements.\n"); ++ fflush(output); + } +- return (char*) PORT_Strdup(phrase); +- } +-} + +-static char consoleName[] = { "/dev/tty" }; ++ egress(); ++ return (char *)PORT_Strdup(phrase); ++} + + static char * +-SECU_GetPasswordString(void *arg UNUSED, +- char *prompt UNUSED) ++SECU_GetPasswordString(void *arg UNUSED, char *prompt) ++{ ++ char *ret; ++ ingress(); ++ ret = get_password(stdin, stdout, prompt, check_password); ++ egress(); ++ return ret; ++} ++ ++static int token_pass_cmp(const void *tp0p, const void *tp1p) ++{ ++ const struct token_pass * const tp0 = (const struct token_pass * const)tp0p; ++ const struct token_pass * const tp1 = (const struct token_pass * const)tp1p; ++ int rc; ++ ++ if (!tp1->token || !tp0->token) ++ return tp1->token - tp0->token; ++ rc = strcmp(tp0->token, tp1->token); ++ if (rc == 0) ++ rc = strcmp(tp0->pass, tp1->pass); ++ return rc; ++} ++ ++static int ++parse_pwfile_line(char *start, struct token_pass *tp) + { +- char *p = NULL; +- FILE *input, *output; +- +- /* open terminal */ +- input = fopen(consoleName, "r"); +- if (input == NULL) { +- fprintf(stderr, "Error opening input terminal %s for read\n", +- consoleName); +- return NULL; +- } +- +- output = fopen(consoleName, "w"); +- if (output == NULL) { +- fclose(input); +- fprintf(stderr, "Error opening output terminal %s for write\n", +- consoleName); +- return NULL; +- } +- +- p = SEC_GetPassword (input, output, prompt, SEC_BlindCheckPassword); +- +- fclose(input); +- fclose(output); +- +- return p; ++ size_t span, escspan; ++ char *line = start; ++ size_t offset = 0; ++ ++ span = strspn(line, whitespace_and_eol_chars); ++ dprintf("whitespace span is %zd", span); ++ if (span == 0 && line[span] == '\0') ++ return -1; ++ line += span; ++ ++ tp->token = NULL; ++ tp->pass = line; ++ ++ offset = 0; ++ do { ++ span = strcspn(line + offset, whitespace_and_eol_chars); ++ escspan = strescspn(line + offset); ++ if (escspan < span) ++ offset += escspan + 2; ++ } while(escspan < span); ++ span += offset; ++ dprintf("non-whitespace span is %zd", span); ++ ++ if (line[span] == '\0') { ++ dprintf("returning %ld", (line + span) - start); ++ return (line + span) - start; ++ } ++ line[span] = '\0'; ++ ++ line += span + 1; ++ span = strspn(line, whitespace_and_eol_chars); ++ dprintf("whitespace span is %zd", span); ++ line += span; ++ tp->token = tp->pass; ++ tp->pass = line; ++ ++ offset = 0; ++ do { ++ span = strcspn(line + offset, whitespace_and_eol_chars); ++ escspan = strescspn(line + offset); ++ if (escspan < span) ++ offset += escspan + 2; ++ } while(escspan < span); ++ span += offset; ++ dprintf("non-whitespace span is %zd", span); ++ if (line[span] != '\0') ++ line[span++] = '\0'; ++ ++ resolve_escapes(tp->token); ++ dprintf("Setting token pass %p to { %p, %p }", tp, tp->token, tp->pass); ++ dprintf("token:\"%s\"", tp->token); ++ dprintf("pass:\"%s\"", tp->pass); ++ dprintf("returning %ld", (line + span) - start); ++ return (line + span) - start; + } + +-/* +- * p a s s w o r d _ h a r d c o d e +- * +- * A function to use the password passed in the -f(pwfile) argument +- * of the command line. +- * After use once, null it out otherwise PKCS11 calls us forever.? +- * +- */ + static char * + SECU_FilePasswd(PK11SlotInfo *slot, PRBool retry, void *arg) + { +- char* phrases, *phrase; +- PRFileDesc *fd; +- PRInt32 nb; +- char *pwFile = arg; +- int i; +- const long maxPwdFileSize = 4096; +- char* tokenName = NULL; +- int tokenLen = 0; ++ cms_context *cms = (cms_context *)arg; ++ int fd; ++ char *file = NULL; ++ char *token_name = slot ? PK11_GetTokenName(slot) : NULL; ++ struct token_pass *phrases = NULL; ++ size_t nphrases = 0; ++ char *phrase = NULL; ++ char *start; ++ char *ret = NULL; ++ char *path; + +- if (!pwFile) +- return 0; ++ ingress(); ++ dprintf("token_name: %s", token_name); ++ path = cms->pwdata.data; + +- if (retry) { +- return 0; /* no good retrying - the files contents will be the same */ +- } ++ if (!path || retry) ++ goto err; + +- phrases = PORT_ZAlloc(maxPwdFileSize); ++ phrases = calloc(1, sizeof(struct token_pass)); ++ if (!phrases) ++ goto err; + +- if (!phrases) { +- return 0; /* out of memory */ +- } +- +- fd = PR_Open(pwFile, PR_RDONLY, 0); +- if (!fd) { +- fprintf(stderr, "No password file \"%s\" exists.\n", pwFile); +- PORT_Free(phrases); +- return NULL; +- } ++ fd = open(path, O_RDONLY|O_CLOEXEC); ++ if (fd < 0) { ++ goto err_phrases; ++ } else { ++ size_t file_len = 0; ++ int rc; ++ rc = read_file(fd, &file, &file_len); ++ set_errno_guard(); ++ close(fd); + +- nb = PR_Read(fd, phrases, maxPwdFileSize); +- +- PR_Close(fd); ++ if (rc < 0 || file_len < 1) ++ goto err_file; ++ file[file_len-1] = '\0'; ++ dprintf("file_len:%zd", file_len); ++ dprintf("file:\"%s\"", file); + +- if (nb == 0) { +- fprintf(stderr,"password file contains no data\n"); +- PORT_Free(phrases); +- return NULL; +- } ++ unbreak_line_continuations(file, file_len); ++ } + +- if (slot) { +- tokenName = PK11_GetTokenName(slot); +- if (tokenName) { +- tokenLen = PORT_Strlen(tokenName); +- } +- } +- i = 0; +- do +- { +- int startphrase = i; +- int phraseLen; ++ start = file; ++ while (start && start[0]) { ++ size_t span; ++ struct token_pass *new_phrases; ++ int rc; ++ char c; + +- /* handle the Windows EOL case */ +- while (phrases[i] != '\r' && phrases[i] != '\n' && i < nb) i++; +- /* terminate passphrase */ +- phrases[i++] = '\0'; +- /* clean up any EOL before the start of the next passphrase */ +- while ( (ipwdata.source = PW_DATABASE; ++ xfree(cms->pwdata.data); ++ cms->pwdata.pwdb.phrases = phrases; ++ cms->pwdata.pwdb.nphrases = nphrases; ++ ++ for (size_t i = 0; i < nphrases; i++) { ++ if (phrases[i].token == NULL || phrases[i].token[0] == '\0' ++ || (token_name && !strcmp(token_name, phrases[i].token))) { ++ phrase = phrases[i].pass; ++ break; ++ } ++ } ++ ++ if (phrase) { ++ ret = PORT_Strdup(phrase); ++ if (!ret) ++ errno = ENOMEM; ++ } ++ ++err_file: ++ xfree(file); ++err_phrases: ++ xfree(phrases); ++err: ++ dprintf("ret:\"%s\"", ret ? ret : "(null)"); ++ egress(); ++ return ret; + } + + char * + get_password_passthrough(PK11SlotInfo *slot UNUSED, + PRBool retry, void *arg) + { +- if (retry) ++ if (retry || !arg) + return NULL; + +- if (!arg) +- return arg; +- + char *ret = strdup(arg); +- if (!ret) { +- fprintf(stderr, "Failed to allocate memory\n"); +- exit(1); +- } ++ if (!ret) ++ err(1, "Could not allocate memory"); ++ + return ret; + } + +@@ -247,54 +367,126 @@ get_password_fail(PK11SlotInfo *slot UNUSED, + return NULL; + } + ++static bool ++can_prompt_again(secuPWData *pwdata) ++{ ++ if (pwdata->orig_source == PW_PROMPT) ++ return true; ++ ++ if (pwdata->source == PW_DEVICE) ++ return true; ++ ++ return false; ++} ++ + char * + SECU_GetModulePassword(PK11SlotInfo *slot, PRBool retry, void *arg) + { +- char prompt[255]; +- secuPWData *pwdata = (secuPWData *)arg; +- secuPWData pwnull = { PW_NONE, 0 }; +- secuPWData pwxtrn = { PW_EXTERNAL, "external" }; +- char *pw; +- +- if (pwdata == NULL) +- pwdata = &pwnull; +- +- if (PK11_ProtectedAuthenticationPath(slot)) { +- pwdata = &pwxtrn; +- } +- if (retry && pwdata->source != PW_NONE) { +- PR_fprintf(PR_STDERR, "Incorrect password/PIN entered.\n"); ++ char *prompt = NULL; ++ cms_context *cms = (cms_context *)arg; ++ secuPWData *pwdata; ++ secuPWData pwxtrn = { .source = PW_DEVICE, .orig_source = PW_DEVICE, .data = NULL }; ++ char *pw; ++ int rc; ++ ++ ingress(); ++ ++ if (PK11_ProtectedAuthenticationPath(slot)) { ++ dprintf("prompting for PW_DEVICE data"); ++ pwdata = &pwxtrn; ++ } else { ++ dprintf("using pwdata from cms"); ++ pwdata = &cms->pwdata; ++ } ++ ++ if (pwdata->source <= PW_SOURCE_INVALID || ++ pwdata->source >= PW_SOURCE_MAX || ++ pwdata->orig_source <= PW_SOURCE_INVALID || ++ pwdata->orig_source >= PW_SOURCE_MAX) { ++ dprintf("pwdata is invalid"); ++ return NULL; ++ } ++ ++ dprintf("pwdata:%p retry:%d", pwdata, retry); ++ dprintf("pwdata->source:%s (%d) orig:%s (%d)", ++ pw_source_names[pwdata->source], pwdata->source, ++ pw_source_names[pwdata->orig_source], pwdata->orig_source); ++ dprintf("pwdata->data:%p (\"%s\")", pwdata->data, ++ pwdata->data ? pwdata->data : "(null)"); ++ ++ if (retry) { ++ warnx("Incorrect password/PIN entered."); ++ if (!can_prompt_again(pwdata)) { ++ egress(); ++ return NULL; ++ } ++ } ++ ++ switch (pwdata->source) { ++ case PW_PROMPT: ++ rc = asprintf(&prompt, "Enter Password or Pin for \"%s\":", ++ PK11_GetTokenName(slot)); ++ if (rc < 0) ++ return NULL; ++ pw = SECU_GetPasswordString(NULL, prompt); ++ if (!pw) ++ return NULL; ++ free(prompt); ++ ++ pwdata->source = PW_PLAINTEXT; ++ egress(); ++ return pw; ++ ++ case PW_DEVICE: ++ dprintf("pwdata->source:PW_DEVICE"); ++ rc = asprintf(&prompt, ++ "Press Enter, then enter PIN for \"%s\" on external device.\n", ++ PK11_GetTokenName(slot)); ++ if (rc < 0) ++ return NULL; ++ pw = SECU_GetPasswordString(NULL, prompt); ++ free(prompt); ++ return pw; ++ ++ case PW_FROMFILEDB: ++ case PW_DATABASE: ++ dprintf("pwdata->source:%s", pw_source_names[pwdata->source]); ++ /* Instead of opening and closing the file every time, get the pw ++ * once, then keep it in memory (duh). ++ */ ++ pw = SECU_FilePasswd(slot, retry, cms); ++ if (pw != NULL) { ++ pwdata->source = PW_PLAINTEXT; ++ pwdata->data = strdup(pw); ++ } ++ /* it's already been dup'ed */ ++ egress(); ++ return pw; ++ ++ case PW_FROMENV: ++ dprintf("pwdata->source:PW_FROMENV"); ++ if (!pwdata || !pwdata->data) ++ break; ++ pw = get_env(pwdata->data); ++ dprintf("env:%s pw:%s", pwdata->data, pw ? pw : "(null)"); ++ pwdata->data = pw; ++ pwdata->source = PW_PLAINTEXT; ++ goto PW_PLAINTEXT; ++ ++ PW_PLAINTEXT: ++ case PW_PLAINTEXT: ++ egress(); ++ if (pwdata && pwdata->data) ++ return strdup(pwdata->data); ++ return NULL; ++ ++ default: ++ break; ++ } ++ ++ warnx("Password check failed: No password found."); ++ egress(); + return NULL; +- } +- +- switch (pwdata->source) { +- case PW_NONE: +- sprintf(prompt, "Enter Password or Pin for \"%s\":", +- PK11_GetTokenName(slot)); +- return SECU_GetPasswordString(NULL, prompt); +- case PW_FROMFILE: +- /* Instead of opening and closing the file every time, get the pw +- * once, then keep it in memory (duh). +- */ +- pw = SECU_FilePasswd(slot, retry, pwdata->data); +- pwdata->source = PW_PLAINTEXT; +- pwdata->data = PL_strdup(pw); +- /* it's already been dup'ed */ +- return pw; +- case PW_EXTERNAL: +- sprintf(prompt, +- "Press Enter, then enter PIN for \"%s\" on external device.\n", +- PK11_GetTokenName(slot)); +- (void) SECU_GetPasswordString(NULL, prompt); +- /* Fall Through */ +- case PW_PLAINTEXT: +- return PL_strdup(pwdata->data); +- default: +- break; +- } +- +- PR_fprintf(PR_STDERR, "Password check failed: No password found.\n"); +- return NULL; + } + + #if 0 +@@ -307,28 +499,31 @@ readpw(PK11SlotInfo *slot UNUSED, + { + struct termios sio, tio; + char line[LINE_MAX], *p; ++ char *ret; + ++ ingress(); + memset(line, '\0', sizeof (line)); + + if (tcgetattr(fileno(stdin), &sio) < 0) { +- fprintf(stderr, "Could not read password from standard input.\n"); ++ warnx("Could not read password from standard input."); + return NULL; + } + tio = sio; + tio.c_lflag &= ~ECHO; + if (tcsetattr(fileno(stdin), 0, &tio) < 0) { +- fprintf(stderr, "Could not read password from standard input.\n"); ++ warnx("Could not read password from standard input."); + return NULL; + } + + fprintf(stdout, "Enter passphrase for private key: "); +- if (fgets(line, sizeof(line), stdin) == NULL) { +- fprintf(stdout, "\n"); +- tcsetattr(fileno(stdin), 0, &sio); +- return NULL; +- } +- fprintf(stdout, "\n"); ++ fflush(stdout); ++ ret = fgets(line, sizeof(line), stdin); ++ set_errno_guard(); + tcsetattr(fileno(stdin), 0, &sio); ++ fprintf(stdout, "\n"); ++ fflush(stdout); ++ if (ret == NULL) ++ return NULL; + + p = line + strcspn(line, "\r\n"); + if (p == NULL) +@@ -336,11 +531,14 @@ readpw(PK11SlotInfo *slot UNUSED, + if (p != NULL) + *p = '\0'; + +- char *ret = strdup(line); ++ ret = strdup(line); + memset(line, '\0', sizeof (line)); + if (!ret) { +- fprintf(stderr, "Could not read passphrase.\n"); ++ warnx("Could not read passphrase."); + return NULL; + } ++ egress(); + return ret; + } ++ ++// vim:fenc=utf-8:tw=75:noet +diff --git a/src/pesign.c b/src/pesign.c +index 854120c15c5..e68a141b935 100644 +--- a/src/pesign.c ++++ b/src/pesign.c +@@ -73,6 +73,10 @@ long verbosity(void) + return *verbose; + } + ++enum { ++ POPT_RET_PWDB = 0x40000001 ++}; ++ + int + main(int argc, char *argv[]) + { +@@ -96,6 +100,10 @@ main(int argc, char *argv[]) + char *certdir = "/etc/pki/pesign"; + char *signum = NULL; + ++ secuPWData pwdata; ++ ++ memset(&pwdata, 0, sizeof(pwdata)); ++ + setenv("NSS_DEFAULT_DB_TYPE", "sql", 0); + + rc = pesign_context_new(&ctxp); +@@ -273,6 +281,12 @@ main(int argc, char *argv[]) + .arg = &check_vendor_cert, + .val = 0, + .descrip = "do not hash the .vendor_cert section." }, ++ {.longName = "pwfile", ++ .shortName = '\0', ++ .argInfo = POPT_ARG_STRING|POPT_ARGFLAG_DOC_HIDDEN, ++ .arg = &pwdata.data, ++ .descrip = "file to read passwords from.", ++ .argDescrip = "" }, + POPT_AUTOALIAS + POPT_AUTOHELP + POPT_TABLEEND +@@ -287,8 +301,32 @@ main(int argc, char *argv[]) + exit(1); + } + +- while ((rc = poptGetNextOpt(optCon)) > 0) +- ; ++ while ((rc = poptGetNextOpt(optCon)) > 0) { ++ switch (rc) { ++ case POPT_RET_PWDB: ++ dprintf("POPT_RET_PWDB:\"%s\"", pwdata.data ? pwdata.data : "(null)"); ++ if (pwdata.source != PW_SOURCE_INVALID) ++ errx(1, "only one password/pin method can be used at a time"); ++ if (pwdata.data == NULL) ++ errx(1, "--pwfile requires a file name as an argument"); ++ pwdata.source = PW_FROMFILEDB; ++ pwdata.data = strdup(pwdata.data); ++ if (!pwdata.data) ++ err(1, "could not allocate memory"); ++ continue; ++ } ++ } ++ ++ dprintf("pwdata.source:%d %schecking for PESIGN_TOKEN_PIN", ++ pwdata.source, ++ pwdata.source == PW_SOURCE_INVALID ? "" : "not "); ++ if (pwdata.source == PW_SOURCE_INVALID && secure_getenv("PESIGN_TOKEN_PIN")) { ++ pwdata.source = PW_FROMENV; ++ pwdata.data = strdup(secure_getenv("PESIGN_TOKEN_PIN")); ++ if (!pwdata.data) ++ err(1, "could not allocate memory"); ++ } ++ pwdata.orig_source = pwdata.source; + + if (rc < -1) { + fprintf(stderr, "pesign: Invalid argument: %s: %s\n", +@@ -411,6 +449,9 @@ main(int argc, char *argv[]) + exit(!is_help); + } + ++ if (pwdata.source != PW_DEVICE) ++ cms_set_pw_data(ctxp->cms_ctx, &pwdata); ++ + ctxp->cms_ctx->omit_vendor_cert = !check_vendor_cert; + + ctxp->cms_ctx->tokenname = tokenname ? +diff --git a/src/signer_info.c b/src/signer_info.c +index afa00e2c52e..6b73bce45d7 100644 +--- a/src/signer_info.c ++++ b/src/signer_info.c +@@ -173,15 +173,14 @@ sign_blob(cms_context *cms, SECItem *sigitem, SECItem *sign_content) + if (!oid) + goto err; + +- PK11_SetPasswordFunc(cms->func ? cms->func : readpw); +- SECKEYPrivateKey *privkey = PK11_FindKeyByAnyCert(cms->cert, +- cms->pwdata ? cms->pwdata : NULL); ++ PK11_SetPasswordFunc(cms->func ? cms->func : SECU_GetModulePassword); ++ SECKEYPrivateKey *privkey = PK11_FindKeyByAnyCert(cms->cert, cms); + if (!privkey) { + cms->log(cms, LOG_ERR, "could not get private key: %s", + PORT_ErrorToString(PORT_GetError())); + goto err; + } +- ++ + SECItem *signature, tmp; + memset (&tmp, '\0', sizeof (tmp)); + +@@ -446,3 +445,5 @@ generate_authvar_signer_info(cms_context *cms, SpcSignerInfo *sip) + err: + return -1; + } ++ ++// vim:fenc=utf-8:tw=75:noet +diff --git a/src/cms_common.h b/src/cms_common.h +index b0dc12fc3ab..34ab6551ddd 100644 +--- a/src/cms_common.h ++++ b/src/cms_common.h +@@ -25,11 +25,15 @@ + #include + #include + #include ++#include ++#include ++#include + #include + #include + #include + + #include "util.h" ++#include "password.h" + + #define save_port_err() \ + for (error_t saved_errno_0_ = 0, saved_errno_1_ = PORT_GetError(); saved_errno_0_ < 1; saved_errno_0_++, PORT_SetError(saved_errno_1_)) +@@ -56,6 +60,44 @@ struct digest { + SECItem *pe_digest; + }; + ++struct token_pass { ++ char *token; ++ char *pass; ++}; ++ ++struct pw_database { ++ struct token_pass *phrases; ++ size_t nphrases; ++}; ++ ++typedef enum { ++ // used only for bounds checking ++ PW_SOURCE_INVALID = 0, ++ // prompt the user (pwdata->data is NULL) ++ PW_PROMPT = 1, ++ // prompt the user to use a device (pwdata->data is NULL) ++ PW_DEVICE = 2, ++ // pwdata->data is plain text ++ PW_PLAINTEXT = 3, ++ // pwdata->data is a filename for a database ++ PW_FROMFILEDB = 4, ++ // pwdata->data is the database data ++ PW_DATABASE = 5, ++ // pwdata->data is the name of an environment variable ++ PW_FROMENV = 6, ++ ++ // used only for bounds checking ++ PW_SOURCE_MAX ++} pw_source_t; ++ ++typedef struct { ++ pw_source_t source; ++ pw_source_t orig_source; ++ ++ struct pw_database pwdb; ++ char *data; ++} secuPWData; ++ + struct cms_context; + + typedef int (*cms_common_logger)(struct cms_context *, int priority, +@@ -68,8 +110,9 @@ typedef struct cms_context { + char *tokenname; + char *certname; + CERTCertificate *cert; ++ PK11SlotListElement *psle; + PK11PasswordFunc func; +- void *pwdata; ++ secuPWData pwdata; + + struct digest *digests; + int selected_digest; +@@ -156,7 +199,7 @@ extern SECOidTag digest_get_encryption_oid(cms_context *cms); + extern SECOidTag digest_get_signature_oid(cms_context *cms); + extern int digest_get_digest_size(cms_context *cms); + extern void cms_set_pw_callback(cms_context *cms, PK11PasswordFunc func); +-extern void cms_set_pw_data(cms_context *cms, void *pwdata); ++extern void cms_set_pw_data(cms_context *cms, secuPWData *pwdata); + + extern int set_digest_parameters(cms_context *ctx, char *name); + +@@ -164,15 +207,5 @@ extern int generate_digest_begin(cms_context *cms); + extern void generate_digest_step(cms_context *cms, void *data, size_t len); + extern int generate_digest_finish(cms_context *cms); + +-typedef struct { +- enum { +- PW_NONE = 0, +- PW_FROMFILE = 1, +- PW_PLAINTEXT = 2, +- PW_EXTERNAL = 3 +- } source; +- char *data; +-} secuPWData; +- + #endif /* CMS_COMMON_H */ + // vim:fenc=utf-8:tw=75:noet +-- +2.29.2 + diff --git a/0026-Minor-whitespace-housekeeping.patch b/0026-Minor-whitespace-housekeeping.patch new file mode 100644 index 0000000..20536f5 --- /dev/null +++ b/0026-Minor-whitespace-housekeeping.patch @@ -0,0 +1,56 @@ +From e89e23ff5970e9a2194bcb393fa579c123e37bd1 Mon Sep 17 00:00:00 2001 +From: Peter Jones +Date: Tue, 28 Apr 2020 10:34:31 -0400 +Subject: [PATCH 26/42] Minor whitespace housekeeping + +Signed-off-by: Peter Jones +--- + src/cms_pe_common.c | 2 +- + src/pesigcheck.c | 2 ++ + src/cms_common.h | 3 +-- + 3 files changed, 4 insertions(+), 3 deletions(-) + +diff --git a/src/cms_pe_common.c b/src/cms_pe_common.c +index bd96fe91d69..b5ef2b73058 100644 +--- a/src/cms_pe_common.c ++++ b/src/cms_pe_common.c +@@ -331,4 +331,4 @@ error: + return -1; + } + +-/* vim:fenc=utf-8:sw=8:sts=8:noet */ ++// vim:fenc=utf-8:tw=75:noet +diff --git a/src/pesigcheck.c b/src/pesigcheck.c +index 87d4960a9a9..ada042e2f7e 100644 +--- a/src/pesigcheck.c ++++ b/src/pesigcheck.c +@@ -544,3 +544,5 @@ main(int argc, char *argv[]) + + return (rc < 0); + } ++ ++// vim:fenc=utf-8:tw=75:noet +diff --git a/src/cms_common.h b/src/cms_common.h +index 34ab6551ddd..a8c66cd3f9f 100644 +--- a/src/cms_common.h ++++ b/src/cms_common.h +@@ -41,7 +41,7 @@ + #define for_each_cert(cl, node) \ + for (CERTCertListNode *node = CERT_LIST_HEAD(cl); !CERT_LIST_END(node, cl); node = CERT_LIST_NEXT(node)) + +-#define cmserr(rv, cms, fmt, args...) ({ \ ++#define cmserr(rv, cms, fmt, args...) ({ \ + (cms)->log((cms), LOG_ERR, "%s:%s:%d: " fmt ": %s", \ + __FILE__, __func__, __LINE__, ## args, \ + PORT_ErrorToString(PORT_GetError())); \ +@@ -54,7 +54,6 @@ + return rv; \ + }) + +- + struct digest { + PK11Context *pk11ctx; + SECItem *pe_digest; +-- +2.29.2 + diff --git a/0027-libdpe-make-the-initial-read-buffer-always-big-enoug.patch b/0027-libdpe-make-the-initial-read-buffer-always-big-enoug.patch new file mode 100644 index 0000000..1e89c05 --- /dev/null +++ b/0027-libdpe-make-the-initial-read-buffer-always-big-enoug.patch @@ -0,0 +1,34 @@ +From 5c6ef128d03bad6fc3e4335935c8f5b20a4b4d51 Mon Sep 17 00:00:00 2001 +From: Peter Jones +Date: Fri, 5 Jun 2020 14:00:10 -0400 +Subject: [PATCH 27/42] libdpe: make the initial read buffer always big enough + for the opt header + +Signed-off-by: Peter Jones +--- + libdpe/pe_begin.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/libdpe/pe_begin.c b/libdpe/pe_begin.c +index 3bcc2c70c61..c6a22ab8c43 100644 +--- a/libdpe/pe_begin.c ++++ b/libdpe/pe_begin.c +@@ -174,8 +174,14 @@ read_unmmapped_file(int fildes, size_t maxsize, Pe_Cmd cmd, Pe *parent) + struct { + struct mz_hdr mz; + struct pe_hdr pe; ++ union { ++ struct pe32_opt_hdr opt_hdr_32; ++ struct pe32plus_opt_hdr opt_hdr_64; ++ }; + }; +- unsigned char raw[1]; ++ unsigned char raw[sizeof(struct mz_hdr) ++ + sizeof(struct pe_hdr) ++ + sizeof(struct pe32plus_opt_hdr)]; + } mem; + + ssize_t nread = pread_retry (fildes, &mem.mz, sizeof(mem.mz), 0); +-- +2.29.2 + diff --git a/0028-Fix-some-memory-leaks.patch b/0028-Fix-some-memory-leaks.patch new file mode 100644 index 0000000..0e88f37 --- /dev/null +++ b/0028-Fix-some-memory-leaks.patch @@ -0,0 +1,88 @@ +From df954024f6e89d4b5947f1016f2e4e95505b45b1 Mon Sep 17 00:00:00 2001 +From: Peter Jones +Date: Tue, 16 Jun 2020 10:34:19 -0400 +Subject: [PATCH 28/42] Fix some memory leaks + +Signed-off-by: Peter Jones +--- + src/cms_common.c | 10 ++++++++++ + src/pesign.c | 7 +++++++ + 2 files changed, 17 insertions(+) + +diff --git a/src/cms_common.c b/src/cms_common.c +index c2f34e515a2..7cd98bc994f 100644 +--- a/src/cms_common.c ++++ b/src/cms_common.c +@@ -345,7 +345,10 @@ is_valid_cert(CERTCertificate *cert, void *data) + + privkey = PK11_FindPrivateKeyFromCert(slot, cert, cbd->cms); + if (privkey != NULL) { ++ if (cbd->cert) ++ CERT_DestroyCertificate(cbd->cert); + cbd->cert = CERT_DupCertificate(cert); ++ CERT_DestroyCertificate(cert); + SECKEY_DestroyPrivateKey(privkey); + return SECSuccess; + } +@@ -363,8 +366,15 @@ is_valid_cert_without_private_key(CERTCertificate *cert, void *data) + return SECFailure; + privkey = PK11_FindPrivateKeyFromCert(slot, cert, cbd->cms); + if (privkey == NULL) { ++ if (cbd->cert) ++ CERT_DestroyCertificate(cbd->cert); ++ PORT_SetError(0); + cbd->cert = CERT_DupCertificate(cert); ++ CERT_DestroyCertificate(cert); + return SECSuccess; ++ } else { ++ SECKEY_DestroyPrivateKey(privkey); ++ CERT_DestroyCertificate(cert); + } + return SECFailure; + } +diff --git a/src/pesign.c b/src/pesign.c +index e68a141b935..0e7ce3d0a4e 100644 +--- a/src/pesign.c ++++ b/src/pesign.c +@@ -94,10 +94,12 @@ main(int argc, char *argv[]) + int check_vendor_cert = 1; + + char *digest_name = "sha256"; ++ char *orig_digest_name = digest_name; + char *tokenname = "NSS Certificate DB"; + char *origtoken = tokenname; + char *certname = NULL; + char *certdir = "/etc/pki/pesign"; ++ char *orig_certdir = certdir; + char *signum = NULL; + + secuPWData pwdata; +@@ -349,6 +351,7 @@ main(int argc, char *argv[]) + fprintf(stderr, "invalid signature number: %m\n"); + exit(1); + } ++ free(signum); + } + + int action = 0; +@@ -473,6 +476,8 @@ main(int argc, char *argv[]) + } + if (certname) + free(certname); ++ if (digest_name && digest_name != orig_digest_name) ++ free(digest_name); + + + if (ctxp->sign) { +@@ -507,6 +512,8 @@ main(int argc, char *argv[]) + break; + } + } ++ if (certdir && certdir != orig_certdir) ++ free(certdir); + pesign_context_free(ctxp); + + if (!daemon) { +-- +2.29.2 + diff --git a/0029-Improve-debug-output.patch b/0029-Improve-debug-output.patch new file mode 100644 index 0000000..eb2e9b2 --- /dev/null +++ b/0029-Improve-debug-output.patch @@ -0,0 +1,494 @@ +From 5347765052981b323622c9a5684577778fc7cbab Mon Sep 17 00:00:00 2001 +From: Peter Jones +Date: Tue, 16 Jun 2020 10:43:32 -0400 +Subject: [PATCH 29/42] Improve debug output + +--- + src/cms_common.c | 78 ++++++++++++++++++++++++++++++++++++++------- + src/cms_pe_common.c | 20 ++++++------ + src/file_kmod.c | 5 +-- + src/file_pe.c | 7 ++++ + src/password.c | 36 +++++++++++++++------ + src/pesign.c | 10 ++++++ + src/cms_common.h | 3 +- + 7 files changed, 125 insertions(+), 34 deletions(-) + +diff --git a/src/cms_common.c b/src/cms_common.c +index 7cd98bc994f..e2ca5c097d4 100644 +--- a/src/cms_common.c ++++ b/src/cms_common.c +@@ -339,9 +339,19 @@ is_valid_cert(CERTCertificate *cert, void *data) + struct validity_cbdata *cbd = (struct validity_cbdata *)data; + PK11SlotInfo *slot = cbd->slot; + SECKEYPrivateKey *privkey = NULL; ++ int errnum; + +- if (cert == NULL) ++ errnum = PORT_GetError(); ++ if (errnum == SEC_ERROR_EXTENSION_NOT_FOUND) { ++ dprintf("Got SEC_ERROR_EXTENSION_NOT_FOUND; clearing"); ++ PORT_SetError(0); ++ errnum = 0; ++ } ++ if (cert == NULL) { ++ if (!errnum) ++ PORT_SetError(SEC_ERROR_UNKNOWN_CERT); + return SECFailure; ++ } + + privkey = PK11_FindPrivateKeyFromCert(slot, cert, cbd->cms); + if (privkey != NULL) { +@@ -350,6 +360,7 @@ is_valid_cert(CERTCertificate *cert, void *data) + cbd->cert = CERT_DupCertificate(cert); + CERT_DestroyCertificate(cert); + SECKEY_DestroyPrivateKey(privkey); ++ PORT_SetError(0); + return SECSuccess; + } + return SECFailure; +@@ -361,9 +372,20 @@ is_valid_cert_without_private_key(CERTCertificate *cert, void *data) + struct validity_cbdata *cbd = (struct validity_cbdata *)data; + PK11SlotInfo *slot = cbd->slot; + SECKEYPrivateKey *privkey = NULL; ++ int errnum; + +- if (cert == NULL) ++ errnum = PORT_GetError(); ++ if (errnum == SEC_ERROR_EXTENSION_NOT_FOUND) { ++ dprintf("Got SEC_ERROR_EXTENSION_NOT_FOUND; clearing"); ++ PORT_SetError(0); ++ errnum = 0; ++ } ++ if (cert == NULL) { ++ if (!errnum) ++ PORT_SetError(SEC_ERROR_UNKNOWN_CERT); + return SECFailure; ++ } ++ + privkey = PK11_FindPrivateKeyFromCert(slot, cert, cbd->cms); + if (privkey == NULL) { + if (cbd->cert) +@@ -402,6 +424,7 @@ PK11_DestroySlotListElement(PK11SlotList *slots, PK11SlotListElement **psle) + int + unlock_nss_token(cms_context *cms) + { ++ dprintf("setting password function to %s", cms->func ? "cms->func" : "SECU_GetModulePassword"); + PK11_SetPasswordFunc(cms->func ? cms->func : SECU_GetModulePassword); + + PK11SlotList *slots = NULL; +@@ -438,11 +461,12 @@ unlock_nss_token(cms_context *cms) + status = PK11_Authenticate(psle->slot, PR_TRUE, cms); + if (status != SECSuccess) { + save_port_err() { ++ int err = PORT_GetError(); + PK11_DestroySlotListElement(slots, &psle); + PK11_FreeSlotList(slots); + cms->log(cms, LOG_ERR, +- "authentication failed for token \"%s\"", +- cms->tokenname); ++ "authentication failed for token \"%s\": %s", ++ cms->tokenname, PORT_ErrorToString(err)); + } + return -1; + } +@@ -462,6 +486,7 @@ find_certificate(cms_context *cms, int needs_private_key) + return -1; + } + ++ dprintf("setting password function to %s", cms->func ? "cms->func" : "SECU_GetModulePassword"); + PK11_SetPasswordFunc(cms->func ? cms->func : SECU_GetModulePassword); + + PK11SlotList *slots = NULL; +@@ -479,8 +504,12 @@ find_certificate(cms_context *cms, int needs_private_key) + } + + while (psle) { +- if (!strcmp(cms->tokenname, PK11_GetTokenName(psle->slot))) ++ dprintf("looking for token \"%s\", got \"%s\"", ++ cms->tokenname, PK11_GetTokenName(psle->slot)); ++ if (!strcmp(cms->tokenname, PK11_GetTokenName(psle->slot))) { ++ dprintf("found token \"%s\"", cms->tokenname); + break; ++ } + + psle = PK11_GetNextSafe(slots, psle, PR_FALSE); + } +@@ -492,16 +521,18 @@ find_certificate(cms_context *cms, int needs_private_key) + nssreterr(-1, "Could not find token \"%s\"", cms->tokenname); + } + ++ int errnum; + SECStatus status; + if (PK11_NeedLogin(psle->slot) && !PK11_IsLoggedIn(psle->slot, cms)) { + status = PK11_Authenticate(psle->slot, PR_TRUE, cms); + if (status != SECSuccess) { + save_port_err() { ++ errnum = PORT_GetError(); + PK11_DestroySlotListElement(slots, &psle); + PK11_FreeSlotList(slots); + cms->log(cms, LOG_ERR, +- "authentication failed for token \"%s\"", +- cms->tokenname); ++ "authentication failed for token \"%s\": %s", ++ cms->tokenname, PORT_ErrorToString(errnum)); + } + return -1; + } +@@ -530,29 +561,48 @@ find_certificate(cms_context *cms, int needs_private_key) + cbd.slot = psle->slot; + cbd.cert = NULL; + ++ PORT_SetError(SEC_ERROR_UNKNOWN_CERT); + if (needs_private_key) { + status = PK11_TraverseCertsForNicknameInSlot(&nickname, + psle->slot, is_valid_cert, &cbd); ++ errnum = PORT_GetError(); ++ if (errnum) ++ dprintf("PK11_TraverseCertsForNicknameInSlot():%s:%s", ++ PORT_ErrorToName(errnum), PORT_ErrorToString(errnum)); + } else { + status = PK11_TraverseCertsForNicknameInSlot(&nickname, + psle->slot, + is_valid_cert_without_private_key, + &cbd); ++ errnum = PORT_GetError(); ++ if (errnum) ++ dprintf("PK11_TraverseCertsForNicknameInSlot():%s:%s", ++ PORT_ErrorToName(errnum), PORT_ErrorToString(errnum)); + } ++ dprintf("status:%d cbd.cert:%p", status, cbd.cert); + if (status == SECSuccess && cbd.cert != NULL) { + if (cms->cert) + CERT_DestroyCertificate(cms->cert); + cms->cert = CERT_DupCertificate(cbd.cert); ++ } else { ++ errnum = PORT_GetError(); ++ dprintf("token traversal %s; cert %sfound:%s:%s", ++ status == SECSuccess ? "succeeded" : "failed", ++ cbd.cert == NULL ? "not" : "", ++ PORT_ErrorToName(errnum), PORT_ErrorToString(errnum)); + } + + save_port_err() { ++ dprintf("Destroying cert list"); + CERT_DestroyCertList(certlist); ++ dprintf("Destroying slot list element"); + PK11_DestroySlotListElement(slots, &psle); ++ dprintf("Destroying slot list"); + PK11_FreeSlotList(slots); + cms->psle = NULL; + } + if (status != SECSuccess || cms->cert == NULL) +- cmsreterr(-1, cms, "could not find certificate in list"); ++ cmsreterr(-1, cms, "could not find certificate"); + + return 0; + } +@@ -565,6 +615,7 @@ find_slot_for_token(cms_context *cms, PK11SlotInfo **slot) + return -1; + } + ++ dprintf("setting password function to %s", cms->func ? "cms->func" : "SECU_GetModulePassword"); + PK11_SetPasswordFunc(cms->func ? cms->func : SECU_GetModulePassword); + + PK11SlotList *slots = NULL; +@@ -600,11 +651,12 @@ find_slot_for_token(cms_context *cms, PK11SlotInfo **slot) + status = PK11_Authenticate(psle->slot, PR_TRUE, cms); + if (status != SECSuccess) { + save_port_err() { ++ int err = PORT_GetError(); + PK11_DestroySlotListElement(slots, &psle); + PK11_FreeSlotList(slots); + cms->log(cms, LOG_ERR, +- "authentication failed for token \"%s\"", +- cms->tokenname); ++ "authentication failed for token \"%s\": %s", ++ cms->tokenname, PORT_ErrorToString(err)); + } + return -1; + } +@@ -621,6 +673,7 @@ find_named_certificate(cms_context *cms, char *name, CERTCertificate **cert) + return -1; + } + ++ dprintf("setting password function to %s", cms->func ? "cms->func" : "SECU_GetModulePassword"); + PK11_SetPasswordFunc(cms->func ? cms->func : SECU_GetModulePassword); + + PK11SlotList *slots = NULL; +@@ -658,11 +711,12 @@ find_named_certificate(cms_context *cms, char *name, CERTCertificate **cert) + status = PK11_Authenticate(psle->slot, PR_TRUE, cms); + if (status != SECSuccess) { + save_port_err() { ++ int err = PORT_GetError(); + PK11_DestroySlotListElement(slots, &psle); + PK11_FreeSlotList(slots); + cms->log(cms, LOG_ERR, +- "authentication failed for token \"%s\"", +- cms->tokenname); ++ "authentication failed for token \"%s\": %s", ++ cms->tokenname, PORT_ErrorToString(err)); + } + return -1; + } +diff --git a/src/cms_pe_common.c b/src/cms_pe_common.c +index b5ef2b73058..e5a33eb6fe1 100644 +--- a/src/cms_pe_common.c ++++ b/src/cms_pe_common.c +@@ -198,8 +198,8 @@ generate_digest(cms_context *cms, Pe *pe, int padded) + __FILE__, __func__, __LINE__); + goto error; + } +- dprintf("beginning of hash\n"); +- dprintf("digesting %lx + %lx\n", hash_base - map, hash_size); ++ dprintf("beginning of hash"); ++ dprintf("digesting %lx + %lx", hash_base - map, hash_size); + generate_digest_step(cms, hash_base, hash_size); + + /* 5. Skip over the image checksum +@@ -224,7 +224,7 @@ generate_digest(cms_context *cms, Pe *pe, int padded) + goto error; + } + generate_digest_step(cms, hash_base, hash_size); +- dprintf("digesting %lx + %lx\n", hash_base - map, hash_size); ++ dprintf("digesting %lx + %lx", hash_base - map, hash_size); + + /* 8. Skip over the crt dir + * 9. Hash everything up to the end of the image header. */ +@@ -239,7 +239,7 @@ generate_digest(cms_context *cms, Pe *pe, int padded) + goto error; + } + generate_digest_step(cms, hash_base, hash_size); +- dprintf("digesting %lx + %lx\n", hash_base - map, hash_size); ++ dprintf("digesting %lx + %lx", hash_base - map, hash_size); + + /* 10. Set SUM_OF_BYTES_HASHED to the size of the header. */ + hashed_bytes = pe32opthdr ? pe32opthdr->header_size +@@ -275,16 +275,16 @@ generate_digest(cms_context *cms, Pe *pe, int padded) + char *name = shdrs[i].name; + if (name && name[0] == '/') + name = get_str(pe, name + 1); +- dprintf("section:\"%s\"\n", name ? name : "(null)"); ++ dprintf("section:\"%s\"", name ? name : "(null)"); + if (name && !strcmp(name, ".vendor_cert")) { +- dprintf("skipping .vendor_cert section\n"); ++ dprintf("skipping .vendor_cert section"); + hashed_bytes += hash_size; + continue; + } + } + + generate_digest_step(cms, hash_base, hash_size); +- dprintf("digesting %lx + %lx\n", hash_base - map, hash_size); ++ dprintf("digesting %lx + %lx", hash_base - map, hash_size); + + hashed_bytes += hash_size; + } +@@ -305,13 +305,13 @@ generate_digest(cms_context *cms, Pe *pe, int padded) + memset(tmp_array, '\0', tmp_size); + memcpy(tmp_array, hash_base, hash_size); + generate_digest_step(cms, tmp_array, tmp_size); +- dprintf("digesting %lx + %lx\n", (unsigned long)tmp_array, tmp_size); ++ dprintf("digesting %lx + %lx", (unsigned long)tmp_array, tmp_size); + } else { + generate_digest_step(cms, hash_base, hash_size); +- dprintf("digesting %lx + %lx\n", hash_base - map, hash_size); ++ dprintf("digesting %lx + %lx", hash_base - map, hash_size); + } + } +- dprintf("end of hash\n"); ++ dprintf("end of hash"); + + rc = generate_digest_finish(cms); + if (rc < 0) +diff --git a/src/file_kmod.c b/src/file_kmod.c +index 077f0579e77..994e5639e71 100644 +--- a/src/file_kmod.c ++++ b/src/file_kmod.c +@@ -84,8 +84,9 @@ kmod_write_signature(cms_context *cms, int outfd) + digest_get_digest_oid(cms), + digest, NULL, NULL); + if (!cinfo) { +- cms->log(cms, LOG_ERR, "failed to create signed data: %s", +- PORT_ErrorToString(PORT_GetError())); ++ cms->log(cms, LOG_ERR, "failed to create signed data: %s (%s)", ++ PORT_ErrorToString(PORT_GetError()), ++ PORT_ErrorToName(PORT_GetError())); + return -1; + } + +diff --git a/src/file_pe.c b/src/file_pe.c +index 31672c68f79..5b6ac21763a 100644 +--- a/src/file_pe.c ++++ b/src/file_pe.c +@@ -22,6 +22,7 @@ + #include + #include + #include ++#include + + #include "pesign.h" + #include "pesign_standalone.h" +@@ -144,6 +145,7 @@ void + pe_handle_action(pesign_context *ctxp, int action, int padding) + { + ssize_t sigspace = 0; ++ int err; + int rc; + + switch (action) { +@@ -265,6 +267,9 @@ pe_handle_action(pesign_context *ctxp, int action, int padding) + break; + /* generate a signature and save it in a separate file */ + case EXPORT_SIGNATURE|GENERATE_SIGNATURE: ++ err = PORT_GetError(); ++ dprintf("PORT_GetError():%s:%s", PORT_ErrorToName(err), PORT_ErrorToString(err)); ++ PORT_SetError(0); + rc = find_certificate(ctxp->cms_ctx, 1); + conderrx(rc < 0, 1, "Could not find certificate %s", + ctxp->cms_ctx->certname); +@@ -277,6 +282,8 @@ pe_handle_action(pesign_context *ctxp, int action, int padding) + /* generate a signature and embed it in the binary */ + case IMPORT_SIGNATURE|GENERATE_SIGNATURE: + check_inputs(ctxp); ++ err = PORT_GetError(); ++ dprintf("PORT_GetError():%s:%s", PORT_ErrorToName(err), PORT_ErrorToString(err)); + rc = find_certificate(ctxp->cms_ctx, 1); + conderrx(rc < 0, 1, "Could not find certificate %s", + ctxp->cms_ctx->certname); +diff --git a/src/password.c b/src/password.c +index 0a4ef411ff7..13bd9b12320 100644 +--- a/src/password.c ++++ b/src/password.c +@@ -58,15 +58,19 @@ print_prompt(FILE *in, FILE *out, char *prompt) + int infd = fileno(in); + struct termios tio; + ++ ingress(); + if (!isatty(infd)) + return; + +- fprintf(out, "%s", prompt); +- fflush(out); ++ if (out) { ++ fprintf(out, "%s", prompt); ++ fflush(out); ++ } + + tcgetattr(infd, &tio); + tio.c_lflag &= ~ECHO; + tcsetattr(infd, TCSAFLUSH, &tio); ++ egress(); + } + + static inline char * +@@ -87,11 +91,14 @@ read_password(FILE *in, FILE *out, char *buf, size_t bufsz) + struct termios tio; + char *ret; + ++ ingress(); + ret = fgets(buf, bufsz, in); + + if (isatty(infd)) { +- fprintf(out, "\n"); +- fflush(out); ++ if (out) { ++ fprintf(out, "\n"); ++ fflush(out); ++ } + + tcgetattr(infd, &tio); + tio.c_lflag |= ECHO; +@@ -101,6 +108,7 @@ read_password(FILE *in, FILE *out, char *buf, size_t bufsz) + return -1; + + buf[strlen(buf)-1] = '\0'; ++ egress(); + return 0; + } + +@@ -109,15 +117,23 @@ check_password(char *cp) + { + unsigned int i; + +- if (cp == NULL) ++ ingress(); ++ if (cp == NULL) { ++ egress(); + return PR_FALSE; ++ } + + for (i = 0; cp[i] != 0; i++) { +- if (!isprint(cp[i])) ++ if (!isprint(cp[i])) { ++ egress(); + return PR_FALSE; ++ } + } +- if (i == 0) ++ if (i == 0) { ++ egress(); + return PR_FALSE; ++ } ++ egress(); + return PR_TRUE; + } + +@@ -134,7 +150,8 @@ get_password(FILE *input, FILE *output, char *prompt, PRBool (*ok)(char *)) + while(true) { + int rc; + +- print_prompt(input, output, prompt); ++ if (prompt) ++ print_prompt(input, output, prompt); + rc = read_password(input, output, phrase, size); + if (rc < 0) + return NULL; +@@ -160,7 +177,8 @@ SECU_GetPasswordString(void *arg UNUSED, char *prompt) + { + char *ret; + ingress(); +- ret = get_password(stdin, stdout, prompt, check_password); ++ ret = get_password(stdin, stdout, prompt, NULL); ++ dprintf("password:\"%s\"", ret ? ret : "(null)"); + egress(); + return ret; + } +diff --git a/src/pesign.c b/src/pesign.c +index 0e7ce3d0a4e..b5c9823e1d4 100644 +--- a/src/pesign.c ++++ b/src/pesign.c +@@ -434,6 +434,16 @@ main(int argc, char *argv[]) + "NSS says \"%s\" errno says \"%m\"\n", + PORT_ErrorToString(PORT_GetError())); + } ++ /* ++ * At this point there is *often* an error set, but we ++ * should not get here if it was really an error; one ++ * example is PR_LOAD_LIBRARY_ERROR is often set by PKCS11 ++ * modules that aren't present or whose physical token ++ * devices aren't available. ++ * ++ * Clear it. ++ */ ++ PORT_SetError(0); + + status = register_oids(ctxp->cms_ctx); + if (status != SECSuccess) { +diff --git a/src/cms_common.h b/src/cms_common.h +index a8c66cd3f9f..ee06f812a77 100644 +--- a/src/cms_common.h ++++ b/src/cms_common.h +@@ -48,8 +48,9 @@ + exit(rv); \ + }) + #define cmsreterr(rv, cms, fmt, args...) ({ \ +- (cms)->log((cms), LOG_ERR, "%s:%s:%d: " fmt ": %s", \ ++ (cms)->log((cms), LOG_ERR, "%s:%s:%d: " fmt ":%s:%s", \ + __FILE__, __func__, __LINE__, ## args, \ ++ PORT_ErrorToName(PORT_GetError()), \ + PORT_ErrorToString(PORT_GetError())); \ + return rv; \ + }) +-- +2.29.2 + diff --git a/0030-support-uri-token-names.patch b/0030-support-uri-token-names.patch new file mode 100644 index 0000000..81b1be1 --- /dev/null +++ b/0030-support-uri-token-names.patch @@ -0,0 +1,256 @@ +From 1465c77dc36a9d5464f42e2477758e250b797fac Mon Sep 17 00:00:00 2001 +From: Peter Jones +Date: Sat, 20 Jun 2020 17:13:17 -0400 +Subject: [PATCH 30/42] support uri token names + +Signed-off-by: Peter Jones +--- + src/cms_common.c | 103 ++++++++++++++++++++++++++++++++++++++++------- + 1 file changed, 89 insertions(+), 14 deletions(-) + +diff --git a/src/cms_common.c b/src/cms_common.c +index e2ca5c097d4..e9c2d08f94c 100644 +--- a/src/cms_common.c ++++ b/src/cms_common.c +@@ -25,6 +25,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -42,6 +43,8 @@ + #include + #include + ++#include "hex.h" ++ + struct digest_param { + char *name; + SECOidTag digest_tag; +@@ -421,9 +424,74 @@ PK11_DestroySlotListElement(PK11SlotList *slots, PK11SlotListElement **psle) + *psle = PK11_GetNextSafe(slots, *psle, PR_FALSE); + } + ++static inline void ++unescape_html_in_place(char *s) ++{ ++ size_t sz = strlen(s) + 1; ++ size_t pos = 0; ++ char *s1; ++ ++ dprintf("unescaping pos:%zd sz:%zd \"%s\"", pos, sz, s); ++ do { ++ s1 = strchrnul(&s[pos], '%'); ++ if (s1[0] == '\0') ++ break; ++ dprintf("s1 is \"%s\"", s1); ++ if ((size_t)(s1 - s) < (size_t)(sz - 3)) { ++ int c; ++ ++ c = (hexchar_to_bin(s1[1]) << 4) ++ | (hexchar_to_bin(s1[2]) & 0xf); ++ dprintf("replacing %%%c%c with 0x%02hhx", s1[1], s1[2], (char)c); ++ s1[0] = c; ++ memmove(&s1[1], &s1[3], sz - (&s1[3] - s)); ++ sz -= 2; ++ pos = &s1[1] - s; ++ dprintf("new pos:%zd sz:%zd s:\"%s\"", pos, sz, s); ++ } ++ } while (pos < sz); ++} ++ ++static inline void ++resolve_pkcs11_token_in_place(char *tokenname) ++{ ++ char *ntn = tokenname; ++ size_t pos = 0; ++ ++ while (*ntn) { ++ char *cp = strchrnul(ntn, ';'); ++ char c = *cp; ++ *cp = '\0'; ++ ++ dprintf("ntn:\"%s\"", ntn); ++ if (!strncmp(&ntn[pos], "token=", 6)) { ++ ntn += 6; ++ memmove(tokenname, ntn, cp - ntn + 1); ++ break; ++ } ++ ++ *cp = c; ++ ntn = cp + (c ? 1 : 0); ++ } ++ unescape_html_in_place(tokenname); ++ dprintf("token name is \"%s\"", tokenname); ++} ++ ++#define resolve_token_name(tn) ({ \ ++ char *s_ = tn; \ ++ if (!strncmp(tn, "pkcs11:", 7)) { \ ++ dprintf("provided token name is pkcs11 uri; parsing"); \ ++ s_ = strdupa(tn+7); \ ++ resolve_pkcs11_token_in_place(s_); \ ++ } \ ++ s_; \ ++}) ++ + int + unlock_nss_token(cms_context *cms) + { ++ char *tokenname = resolve_token_name(cms->tokenname); ++ + dprintf("setting password function to %s", cms->func ? "cms->func" : "SECU_GetModulePassword"); + PK11_SetPasswordFunc(cms->func ? cms->func : SECU_GetModulePassword); + +@@ -432,6 +500,7 @@ unlock_nss_token(cms_context *cms) + if (!slots) + cmsreterr(-1, cms, "could not get pk11 token list"); + ++ + PK11SlotListElement *psle = NULL; + psle = PK11_GetFirstSafe(slots); + if (!psle) { +@@ -442,7 +511,7 @@ unlock_nss_token(cms_context *cms) + } + + while (psle) { +- if (!strcmp(cms->tokenname, PK11_GetTokenName(psle->slot))) ++ if (!strcmp(tokenname, PK11_GetTokenName(psle->slot))) + break; + + psle = PK11_GetNextSafe(slots, psle, PR_FALSE); +@@ -452,7 +521,7 @@ unlock_nss_token(cms_context *cms) + save_port_err() { + PK11_FreeSlotList(slots); + } +- nssreterr(-1, "Could not find token \"%s\"", cms->tokenname); ++ nssreterr(-1, "Could not find token \"%s\"", tokenname); + } + + SECStatus status; +@@ -466,7 +535,7 @@ unlock_nss_token(cms_context *cms) + PK11_FreeSlotList(slots); + cms->log(cms, LOG_ERR, + "authentication failed for token \"%s\": %s", +- cms->tokenname, PORT_ErrorToString(err)); ++ tokenname, PORT_ErrorToString(err)); + } + return -1; + } +@@ -480,6 +549,8 @@ unlock_nss_token(cms_context *cms) + int + find_certificate(cms_context *cms, int needs_private_key) + { ++ char *tokenname = resolve_token_name(cms->tokenname); ++ + struct validity_cbdata cbd; + if (!cms->certname || !*cms->certname) { + cms->log(cms, LOG_ERR, "no certificate name specified"); +@@ -505,9 +576,9 @@ find_certificate(cms_context *cms, int needs_private_key) + + while (psle) { + dprintf("looking for token \"%s\", got \"%s\"", +- cms->tokenname, PK11_GetTokenName(psle->slot)); +- if (!strcmp(cms->tokenname, PK11_GetTokenName(psle->slot))) { +- dprintf("found token \"%s\"", cms->tokenname); ++ tokenname, PK11_GetTokenName(psle->slot)); ++ if (!strcmp(tokenname, PK11_GetTokenName(psle->slot))) { ++ dprintf("found token \"%s\"", tokenname); + break; + } + +@@ -518,7 +589,7 @@ find_certificate(cms_context *cms, int needs_private_key) + save_port_err() { + PK11_FreeSlotList(slots); + } +- nssreterr(-1, "Could not find token \"%s\"", cms->tokenname); ++ nssreterr(-1, "Could not find token \"%s\"", tokenname); + } + + int errnum; +@@ -532,7 +603,7 @@ find_certificate(cms_context *cms, int needs_private_key) + PK11_FreeSlotList(slots); + cms->log(cms, LOG_ERR, + "authentication failed for token \"%s\": %s", +- cms->tokenname, PORT_ErrorToString(errnum)); ++ tokenname, PORT_ErrorToString(errnum)); + } + return -1; + } +@@ -615,6 +686,8 @@ find_slot_for_token(cms_context *cms, PK11SlotInfo **slot) + return -1; + } + ++ char *tokenname = resolve_token_name(cms->tokenname); ++ + dprintf("setting password function to %s", cms->func ? "cms->func" : "SECU_GetModulePassword"); + PK11_SetPasswordFunc(cms->func ? cms->func : SECU_GetModulePassword); + +@@ -633,7 +706,7 @@ find_slot_for_token(cms_context *cms, PK11SlotInfo **slot) + } + + while (psle) { +- if (!strcmp(cms->tokenname, PK11_GetTokenName(psle->slot))) ++ if (!strcmp(tokenname, PK11_GetTokenName(psle->slot))) + break; + + psle = PK11_GetNextSafe(slots, psle, PR_FALSE); +@@ -643,7 +716,7 @@ find_slot_for_token(cms_context *cms, PK11SlotInfo **slot) + save_port_err() { + PK11_FreeSlotList(slots); + } +- nssreterr(-1, "Could not find token \"%s\"", cms->tokenname); ++ nssreterr(-1, "Could not find token \"%s\"", tokenname); + } + + SECStatus status; +@@ -656,7 +729,7 @@ find_slot_for_token(cms_context *cms, PK11SlotInfo **slot) + PK11_FreeSlotList(slots); + cms->log(cms, LOG_ERR, + "authentication failed for token \"%s\": %s", +- cms->tokenname, PORT_ErrorToString(err)); ++ tokenname, PORT_ErrorToString(err)); + } + return -1; + } +@@ -668,6 +741,8 @@ find_slot_for_token(cms_context *cms, PK11SlotInfo **slot) + int + find_named_certificate(cms_context *cms, char *name, CERTCertificate **cert) + { ++ char *tokenname = resolve_token_name(cms->tokenname); ++ + if (!name) { + cms->log(cms, LOG_ERR, "no certificate name specified"); + return -1; +@@ -691,7 +766,7 @@ find_named_certificate(cms_context *cms, char *name, CERTCertificate **cert) + } + + while (psle) { +- if (!strcmp(cms->tokenname, PK11_GetTokenName(psle->slot))) ++ if (!strcmp(tokenname, PK11_GetTokenName(psle->slot))) + break; + + psle = PK11_GetNextSafe(slots, psle, PR_FALSE); +@@ -701,7 +776,7 @@ find_named_certificate(cms_context *cms, char *name, CERTCertificate **cert) + save_port_err() { + PK11_FreeSlotList(slots); + cms->log(cms, LOG_ERR, "could not find token \"%s\"", +- cms->tokenname); ++ tokenname); + } + return -1; + } +@@ -716,7 +791,7 @@ find_named_certificate(cms_context *cms, char *name, CERTCertificate **cert) + PK11_FreeSlotList(slots); + cms->log(cms, LOG_ERR, + "authentication failed for token \"%s\": %s", +- cms->tokenname, PORT_ErrorToString(err)); ++ tokenname, PORT_ErrorToString(err)); + } + return -1; + } +-- +2.29.2 + diff --git a/0031-cms_common-add-some-more-ways-to-find-a-cert.patch b/0031-cms_common-add-some-more-ways-to-find-a-cert.patch new file mode 100644 index 0000000..20a9852 --- /dev/null +++ b/0031-cms_common-add-some-more-ways-to-find-a-cert.patch @@ -0,0 +1,178 @@ +From 1b3f668daa34372308d94cf322b1f809e83fe4aa Mon Sep 17 00:00:00 2001 +From: Peter Jones +Date: Mon, 22 Jun 2020 13:54:10 -0400 +Subject: [PATCH 31/42] cms_common: add some more ways to find a cert + +Signed-off-by: Peter Jones +--- + src/cms_common.c | 109 +++++++++++++++++++++++++++++++++++++++-------- + src/cms_common.h | 9 ++++ + 2 files changed, 101 insertions(+), 17 deletions(-) + +diff --git a/src/cms_common.c b/src/cms_common.c +index e9c2d08f94c..e274a8a50da 100644 +--- a/src/cms_common.c ++++ b/src/cms_common.c +@@ -739,12 +739,18 @@ find_slot_for_token(cms_context *cms, PK11SlotInfo **slot) + } + + int +-find_named_certificate(cms_context *cms, char *name, CERTCertificate **cert) ++find_certificate_by_callback(cms_context *cms, ++ find_cert_match_t *match, void *cbdata, ++ CERTCertificate **cert) + { + char *tokenname = resolve_token_name(cms->tokenname); + +- if (!name) { +- cms->log(cms, LOG_ERR, "no certificate name specified"); ++ if (!match) { ++ cms->log(cms, LOG_ERR, "no certificate match callback not specified"); ++ return -1; ++ } ++ if (!cbdata) { ++ cms->log(cms, LOG_ERR, "no certificate callback data not specified"); + return -1; + } + +@@ -809,25 +815,29 @@ find_named_certificate(cms_context *cms, char *name, CERTCertificate **cert) + + CERTCertListNode *node = NULL; + for_each_cert(certlist, tmpnode) { +- if (!strcmp(tmpnode->cert->subjectName, name)) { ++ /* If we're looking up the issuer of some cert, and the ++ * issuer isn't in the database, we'll get back what is ++ * essentially a template that's in NSS's cache waiting to ++ * be filled out. We can't use that, it'll just cause ++ * CERT_DupCertificate() to segfault. */ ++ if (!tmpnode || !tmpnode->cert ++ || !tmpnode->cert->derCert.data ++ || !tmpnode->cert->derCert.len ++ || !tmpnode->cert->derIssuer.data ++ || !tmpnode->cert->derIssuer.len ++ || !tmpnode->cert->serialNumber.data ++ || !tmpnode->cert->serialNumber.len) ++ continue; ++ ++ int rc = match(tmpnode->cert, cbdata); ++ if (rc == 0) { + node = tmpnode; + break; + } + } +- /* If we're looking up the issuer of some cert, and the issuer isn't +- * in the database, we'll get back what is essentially a template +- * that's in NSS's cache waiting to be filled out. We can't use that, +- * it'll just cause CERT_DupCertificate() to segfault. */ +- if (!node || !node->cert || !node->cert->derCert.data +- || !node->cert->derCert.len +- || !node->cert->derIssuer.data +- || !node->cert->derIssuer.len) { +- PK11_DestroySlotListElement(slots, &psle); +- PK11_FreeSlotList(slots); +- CERT_DestroyCertList(certlist); + +- return -1; +- } ++ if (!node) ++ cmsreterr(-1, cms, "Could not find certificate"); + + *cert = CERT_DupCertificate(node->cert); + +@@ -836,6 +846,71 @@ find_named_certificate(cms_context *cms, char *name, CERTCertificate **cert) + CERT_DestroyCertList(certlist); + + return 0; ++ ++} ++ ++static int ++match_subject(CERTCertificate *cert, void *cbdatap) ++{ ++ if (!cert->subjectName) ++ return 0; ++ ++ if (!strcmp(cert->subjectName, (char *)cbdatap)) ++ return 1; ++ ++ return 0; ++} ++ ++int ++find_named_certificate(cms_context *cms, char *name, CERTCertificate **cert) ++{ ++ if (!name) ++ cmsreterr(-1, cms, "no subject name specified"); ++ ++ return find_certificate_by_callback(cms, match_subject, name, cert); ++} ++ ++static int ++match_issuer_and_serial(CERTCertificate *cert, void *cbdatap) ++{ ++ CERTIssuerAndSN *ias = cbdatap; ++ bool found = false; ++ ++ if (ias->derIssuer.len == cert->derIssuer.len && ++ ias->derIssuer.len != 0) { ++ if (memcmp(ias->derIssuer.data, cert->derIssuer.data, ++ ias->derIssuer.len)) ++ return 0; ++ found = true; ++ } ++ ++ if (!found) { ++ SECComparison seccomp; ++ ++ seccomp = CERT_CompareName(&ias->issuer, &cert->issuer); ++ if (seccomp != SECEqual) ++ return 0; ++ } ++ ++ if (ias->serialNumber.len != cert->serialNumber.len) ++ return 0; ++ ++ if (memcmp(ias->serialNumber.data, cert->serialNumber.data, ++ ias->serialNumber.len)) ++ return 0; ++ ++ return 1; ++} ++ ++int ++find_certificate_by_issuer_and_sn(cms_context *cms, ++ CERTIssuerAndSN *ias, ++ CERTCertificate **cert) ++{ ++ if (!ias) ++ cmsreterr(-1, cms, "invalid issuer and serial number"); ++ ++ return find_certificate_by_callback(cms, match_issuer_and_serial, &ias, cert); + } + + int +diff --git a/src/cms_common.h b/src/cms_common.h +index ee06f812a77..04974035f0c 100644 +--- a/src/cms_common.h ++++ b/src/cms_common.h +@@ -190,8 +190,17 @@ extern int generate_keys(cms_context *cms, PK11SlotInfo *slot, + SECKEYPrivateKey **privkey, SECKEYPublicKey **pubkey); + extern int is_issuer_of(CERTCertificate *c0, CERTCertificate *c1); + ++typedef int (find_cert_match_t)(CERTCertificate *cert, void *cbdata); ++extern int find_certificate_by_callback(cms_context *cms, ++ find_cert_match_t *match, void *cbdata, ++ CERTCertificate **cert); ++ + extern int find_named_certificate(cms_context *cms, char *name, + CERTCertificate **cert); ++extern int find_certificate_by_issuer_and_sn(cms_context *cms, ++ CERTIssuerAndSN *ias, ++ CERTCertificate **cert); ++ + extern int find_slot_for_token(cms_context *cms, PK11SlotInfo **slot); + + extern SECOidTag digest_get_digest_oid(cms_context *cms); +-- +2.29.2 + diff --git a/0006-client-try-run-and-var-run-for-the-socket-path.patch b/0032-client-try-run-and-var-run-for-the-socket-path.patch similarity index 91% rename from 0006-client-try-run-and-var-run-for-the-socket-path.patch rename to 0032-client-try-run-and-var-run-for-the-socket-path.patch index 5f89c07..8a3544b 100644 --- a/0006-client-try-run-and-var-run-for-the-socket-path.patch +++ b/0032-client-try-run-and-var-run-for-the-socket-path.patch @@ -1,7 +1,7 @@ -From a30095e011cb1debf07a91889bca67d34b45d38c Mon Sep 17 00:00:00 2001 +From 2dd5d6653ff965e2afc14a2abfba308f26934a65 Mon Sep 17 00:00:00 2001 From: Peter Jones Date: Mon, 6 Jul 2020 16:13:09 -0400 -Subject: [PATCH 06/12] client: try /run and /var/run for the socket path. +Subject: [PATCH 32/42] client: try /run and /var/run for the socket path. Signed-off-by: Peter Jones --- @@ -9,7 +9,7 @@ Signed-off-by: Peter Jones 1 file changed, 29 insertions(+), 11 deletions(-) diff --git a/src/client.c b/src/client.c -index a4f1d1dbbe7..0082be1f597 100644 +index a00b20f5dde..914f2c8bd55 100644 --- a/src/client.c +++ b/src/client.c @@ -61,24 +61,24 @@ print_flag_name(FILE *f, int flag) diff --git a/0007-client-remove-an-extra-debug-print.patch b/0033-client-remove-an-extra-debug-print.patch similarity index 76% rename from 0007-client-remove-an-extra-debug-print.patch rename to 0033-client-remove-an-extra-debug-print.patch index 9545158..0e2051f 100644 --- a/0007-client-remove-an-extra-debug-print.patch +++ b/0033-client-remove-an-extra-debug-print.patch @@ -1,7 +1,7 @@ -From e06c88a9bb1a21e052dc1b471e2361574a8045cc Mon Sep 17 00:00:00 2001 +From 8ce83e63dd221beb775378981090deacd17e2166 Mon Sep 17 00:00:00 2001 From: Peter Jones Date: Tue, 14 Jul 2020 16:44:09 -0400 -Subject: [PATCH 07/12] client: remove an extra debug print +Subject: [PATCH 33/42] client: remove an extra debug print Signed-off-by: Peter Jones --- @@ -9,7 +9,7 @@ Signed-off-by: Peter Jones 1 file changed, 1 deletion(-) diff --git a/src/client.c b/src/client.c -index 0082be1f597..c9966295e5f 100644 +index 914f2c8bd55..48fdeaba6a4 100644 --- a/src/client.c +++ b/src/client.c @@ -536,7 +536,6 @@ oom: diff --git a/0008-Move-most-of-macros.pesign-to-pesign-rpmbuild-helper.patch b/0034-Move-most-of-macros.pesign-to-pesign-rpmbuild-helper.patch similarity index 97% rename from 0008-Move-most-of-macros.pesign-to-pesign-rpmbuild-helper.patch rename to 0034-Move-most-of-macros.pesign-to-pesign-rpmbuild-helper.patch index 7fb92fc..ebb3d8c 100644 --- a/0008-Move-most-of-macros.pesign-to-pesign-rpmbuild-helper.patch +++ b/0034-Move-most-of-macros.pesign-to-pesign-rpmbuild-helper.patch @@ -1,7 +1,7 @@ -From fff0474cec240576352cebb3dc379f957e68536b Mon Sep 17 00:00:00 2001 +From 8fd6066496fc148945570371863597769b8ffe1d Mon Sep 17 00:00:00 2001 From: Peter Jones Date: Mon, 6 Jul 2020 13:54:35 -0400 -Subject: [PATCH 08/12] Move most of macros.pesign to pesign-rpmbuild-helper +Subject: [PATCH 34/42] Move most of macros.pesign to pesign-rpmbuild-helper Signed-off-by: Peter Jones --- @@ -25,7 +25,7 @@ index 0bacafe0d01..d4cd626c11e 100644 PKG_CONFIG = $(CROSS_COMPILE)pkg-config CC := $(if $(filter default,$(origin CC)),$(CROSS_COMPILE)gcc,$(CC)) diff --git a/src/Makefile b/src/Makefile -index 74327ba13f3..a7ca89159c6 100644 +index bc3e5931456..82c2dfdec3f 100644 --- a/src/Makefile +++ b/src/Makefile @@ -5,7 +5,7 @@ include $(TOPDIR)/Make.version @@ -37,7 +37,7 @@ index 74327ba13f3..a7ca89159c6 100644 SVCTARGETS=pesign.sysvinit pesign.service TARGETS=$(BINTARGETS) $(SVCTARGETS) -@@ -49,6 +49,11 @@ pesign : $(call objects-of,$(PESIGN_SOURCES) $(COMMON_SOURCES) $(COMMON_PE_SOURC +@@ -54,6 +54,11 @@ pesign : $(call objects-of,$(PESIGN_SOURCES) $(COMMON_SOURCES) $(COMMON_PE_SOURC pesign : LDLIBS+=$(TOPDIR)/libdpe/libdpe.a pesign : PKGS=efivar nss nspr popt @@ -49,7 +49,7 @@ index 74327ba13f3..a7ca89159c6 100644 deps : PKGS=efivar nss nspr popt uuid deps : $(ALL_SOURCES) $(MAKE) -f $(TOPDIR)/Make.deps \ -@@ -94,6 +99,7 @@ install : +@@ -99,6 +104,7 @@ install : $(INSTALL) -m 644 macros.pesign $(INSTALLROOT)/etc/rpm/ $(INSTALL) -d -m 755 $(INSTALLROOT)$(libexecdir)/pesign/ $(INSTALL) -m 750 pesign-authorize $(INSTALLROOT)$(libexecdir)/pesign/ diff --git a/0009-pesign-authorize-shellcheck.patch b/0035-pesign-authorize-shellcheck.patch similarity index 93% rename from 0009-pesign-authorize-shellcheck.patch rename to 0035-pesign-authorize-shellcheck.patch index 8f4e002..0066657 100644 --- a/0009-pesign-authorize-shellcheck.patch +++ b/0035-pesign-authorize-shellcheck.patch @@ -1,7 +1,7 @@ -From 9a8966fa718467d04458c82f7f36822b9099d236 Mon Sep 17 00:00:00 2001 +From 556e51ec7cdd4225de5e1764fc7fac114bd926d1 Mon Sep 17 00:00:00 2001 From: Peter Jones Date: Tue, 14 Jul 2020 15:07:32 -0400 -Subject: [PATCH 09/12] pesign-authorize: shellcheck +Subject: [PATCH 35/42] pesign-authorize: shellcheck Signed-off-by: Peter Jones --- diff --git a/0010-pesign-authorize-don-t-setfacl-etc-pki-pesign-foo.patch b/0036-pesign-authorize-don-t-setfacl-etc-pki-pesign-foo.patch similarity index 82% rename from 0010-pesign-authorize-don-t-setfacl-etc-pki-pesign-foo.patch rename to 0036-pesign-authorize-don-t-setfacl-etc-pki-pesign-foo.patch index 745c68b..7d7c14e 100644 --- a/0010-pesign-authorize-don-t-setfacl-etc-pki-pesign-foo.patch +++ b/0036-pesign-authorize-don-t-setfacl-etc-pki-pesign-foo.patch @@ -1,7 +1,7 @@ -From d9bb31e204d4d3b64ba7168f934aea4cb4249110 Mon Sep 17 00:00:00 2001 +From 16b80efae3c932d2b966b0ee0095de367aa31c3a Mon Sep 17 00:00:00 2001 From: Peter Jones Date: Tue, 14 Jul 2020 15:08:15 -0400 -Subject: [PATCH 10/12] pesign-authorize: don't setfacl /etc/pki/pesign-foo/ +Subject: [PATCH 36/42] pesign-authorize: don't setfacl /etc/pki/pesign-foo/ Signed-off-by: Peter Jones --- diff --git a/0011-kernel-building-hack.patch b/0037-kernel-building-hack.patch similarity index 93% rename from 0011-kernel-building-hack.patch rename to 0037-kernel-building-hack.patch index 8ab3e74..89b4741 100644 --- a/0011-kernel-building-hack.patch +++ b/0037-kernel-building-hack.patch @@ -1,7 +1,7 @@ -From 4cf648026769743f634dfe4d2a967ffe684f9f65 Mon Sep 17 00:00:00 2001 +From 59e539c55f22e838b7781efb3357da0d8f4de7db Mon Sep 17 00:00:00 2001 From: Peter Jones Date: Tue, 14 Jul 2020 16:42:39 -0400 -Subject: [PATCH 11/12] kernel building hack +Subject: [PATCH 37/42] kernel building hack Signed-off-by: Peter Jones --- diff --git a/0012-Use-run-not-var-run.patch b/0038-Use-run-not-var-run.patch similarity index 93% rename from 0012-Use-run-not-var-run.patch rename to 0038-Use-run-not-var-run.patch index 84691f4..fbc9786 100644 --- a/0012-Use-run-not-var-run.patch +++ b/0038-Use-run-not-var-run.patch @@ -1,7 +1,7 @@ -From d2365c50af8aee2701e1a96dff96696353b9a027 Mon Sep 17 00:00:00 2001 +From 36a87a0471f79346dc245ba62bdaaddf1e9c908e Mon Sep 17 00:00:00 2001 From: Peter Jones Date: Thu, 16 Jul 2020 16:28:26 -0400 -Subject: [PATCH 12/12] Use /run not /var/run +Subject: [PATCH 38/42] Use /run not /var/run Signed-off-by: Peter Jones --- @@ -28,10 +28,10 @@ index 0368dc9256c..5fcd97ea717 100644 static inline uint32_t UNUSED pesignd_string_size(char *buffer) diff --git a/src/Makefile b/src/Makefile -index a7ca89159c6..f7fb5fc9ee5 100644 +index 82c2dfdec3f..e24bd600af0 100644 --- a/src/Makefile +++ b/src/Makefile -@@ -78,7 +78,7 @@ install_sysvinit: pesign.sysvinit +@@ -83,7 +83,7 @@ install_sysvinit: pesign.sysvinit install : $(INSTALL) -d -m 700 $(INSTALLROOT)/etc/pki/pesign/ $(INSTALL) -d -m 700 $(INSTALLROOT)/etc/pki/pesign-rh-test/ diff --git a/0039-efikeygen-return-error-on-AKID-encoding-failures.patch b/0039-efikeygen-return-error-on-AKID-encoding-failures.patch new file mode 100644 index 0000000..b8a739d --- /dev/null +++ b/0039-efikeygen-return-error-on-AKID-encoding-failures.patch @@ -0,0 +1,43 @@ +From 854b9ea4fe5b743f643f8622e5a1ec26dd1eb2dc Mon Sep 17 00:00:00 2001 +From: Peter Jones +Date: Tue, 16 Feb 2021 11:38:27 -0500 +Subject: [PATCH 39/42] efikeygen: return error on AKID encoding failures + +Clearly some of these exiting with nonsense error codes and some of them +returning error values is not how it's supposed to be. + +Signed-off-by: Peter Jones +--- + src/efikeygen.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/src/efikeygen.c b/src/efikeygen.c +index b1cac4705e8..8bf67c2ec20 100644 +--- a/src/efikeygen.c ++++ b/src/efikeygen.c +@@ -156,11 +156,11 @@ add_auth_key_id(cms_context *cms, void *extHandle, SECKEYPublicKey *pubkey) + { + SECItem *pubkey_der = PK11_DEREncodePublicKey(pubkey); + if (!pubkey_der) +- cmserr(-1, cms, "could not encode CA Key ID extension"); ++ cmsreterr(-1, cms, "could not encode CA Key ID extension"); + + SECItem *encoded = PK11_MakeIDFromPubKey(pubkey_der); + if (!encoded) +- cmserr(-1, cms, "could not encode CA Key ID extension"); ++ cmsreterr(-1, cms, "could not encode CA Key ID extension"); + + SECItem cspecific = { 0 }; + int rc = make_context_specific(cms, 0, &cspecific, encoded); +@@ -178,7 +178,7 @@ add_auth_key_id(cms_context *cms, void *extHandle, SECKEYPublicKey *pubkey) + status = CERT_AddExtension(extHandle, SEC_OID_X509_AUTH_KEY_ID, + &wrapped, PR_FALSE, PR_TRUE); + if (status != SECSuccess) +- cmserr(-1, cms, "could not encode CA Key ID extension"); ++ cmsreterr(-1, cms, "could not encode CA Key ID extension"); + return 0; + } + +-- +2.29.2 + diff --git a/0040-Rename-some-cms-error-functions.patch b/0040-Rename-some-cms-error-functions.patch new file mode 100644 index 0000000..a3b2c86 --- /dev/null +++ b/0040-Rename-some-cms-error-functions.patch @@ -0,0 +1,567 @@ +From eaf8471d14e54aa17802ce4d131db2d2440a69f9 Mon Sep 17 00:00:00 2001 +From: Peter Jones +Date: Tue, 16 Feb 2021 12:00:50 -0500 +Subject: [PATCH 40/42] Rename some cms error functions + +Some of these were really not clear, and efikeygen was misusing them. +This adds a couple more and disambiguates some of their names a bit. + +Signed-off-by: Peter Jones +--- + src/cms_common.c | 141 +++++++++++++++++++------------------------- + src/cms_pe_common.c | 8 +-- + src/cms_common.h | 23 ++++++-- + 3 files changed, 80 insertions(+), 92 deletions(-) + +diff --git a/src/cms_common.c b/src/cms_common.c +index e274a8a50da..4bbd5f5cfa9 100644 +--- a/src/cms_common.c ++++ b/src/cms_common.c +@@ -152,7 +152,7 @@ cms_context_init(cms_context *cms) + + cms->arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); + if (!cms->arena) +- cmsreterr(-1, cms, "could not create cryptographic arena"); ++ cnreterr(-1, cms, "could not create cryptographic arena"); + + cms->selected_digest = -1; + +@@ -498,7 +498,7 @@ unlock_nss_token(cms_context *cms) + PK11SlotList *slots = NULL; + slots = PK11_GetAllTokens(CKM_RSA_PKCS, PR_FALSE, PR_TRUE, cms); + if (!slots) +- cmsreterr(-1, cms, "could not get pk11 token list"); ++ cnreterr(-1, cms, "could not get pk11 token list"); + + + PK11SlotListElement *psle = NULL; +@@ -507,7 +507,7 @@ unlock_nss_token(cms_context *cms) + save_port_err() { + PK11_FreeSlotList(slots); + } +- cmsreterr(-1, cms, "could not get pk11 safe"); ++ cnreterr(-1, cms, "could not get pk11 safe"); + } + + while (psle) { +@@ -563,7 +563,7 @@ find_certificate(cms_context *cms, int needs_private_key) + PK11SlotList *slots = NULL; + slots = PK11_GetAllTokens(CKM_RSA_PKCS, PR_FALSE, PR_TRUE, cms); + if (!slots) +- cmsreterr(-1, cms, "could not get pk11 token list"); ++ cnreterr(-1, cms, "could not get pk11 token list"); + + PK11SlotListElement *psle = NULL; + psle = PK11_GetFirstSafe(slots); +@@ -571,7 +571,7 @@ find_certificate(cms_context *cms, int needs_private_key) + save_port_err() { + PK11_FreeSlotList(slots); + } +- cmsreterr(-1, cms, "could not get pk11 safe"); ++ cnreterr(-1, cms, "could not get pk11 safe"); + } + + while (psle) { +@@ -616,7 +616,7 @@ find_certificate(cms_context *cms, int needs_private_key) + PK11_DestroySlotListElement(slots, &psle); + PK11_FreeSlotList(slots); + } +- cmsreterr(-1, cms, "could not get certificate list"); ++ cnreterr(-1, cms, "could not get certificate list"); + } + + SECItem nickname = { +@@ -673,7 +673,7 @@ find_certificate(cms_context *cms, int needs_private_key) + cms->psle = NULL; + } + if (status != SECSuccess || cms->cert == NULL) +- cmsreterr(-1, cms, "could not find certificate"); ++ cnreterr(-1, cms, "could not find certificate"); + + return 0; + } +@@ -694,7 +694,7 @@ find_slot_for_token(cms_context *cms, PK11SlotInfo **slot) + PK11SlotList *slots = NULL; + slots = PK11_GetAllTokens(CKM_RSA_PKCS, PR_FALSE, PR_TRUE, cms); + if (!slots) +- cmsreterr(-1, cms, "could not get pk11 token list"); ++ cnreterr(-1, cms, "could not get pk11 token list"); + + PK11SlotListElement *psle = NULL; + psle = PK11_GetFirstSafe(slots); +@@ -702,7 +702,7 @@ find_slot_for_token(cms_context *cms, PK11SlotInfo **slot) + save_port_err() { + PK11_FreeSlotList(slots); + } +- cmsreterr(-1, cms, "could not get pk11 safe"); ++ cnreterr(-1, cms, "could not get pk11 safe"); + } + + while (psle) { +@@ -760,7 +760,7 @@ find_certificate_by_callback(cms_context *cms, + PK11SlotList *slots = NULL; + slots = PK11_GetAllTokens(CKM_RSA_PKCS, PR_FALSE, PR_TRUE, cms); + if (!slots) +- cmsreterr(-1, cms, "could not get pk11 token list"); ++ cnreterr(-1, cms, "could not get pk11 token list"); + + PK11SlotListElement *psle = NULL; + psle = PK11_GetFirstSafe(slots); +@@ -768,7 +768,7 @@ find_certificate_by_callback(cms_context *cms, + save_port_err() { + PK11_FreeSlotList(slots); + } +- cmsreterr(-1, cms, "could not get pk11 safe"); ++ cnreterr(-1, cms, "could not get pk11 safe"); + } + + while (psle) { +@@ -810,7 +810,7 @@ find_certificate_by_callback(cms_context *cms, + PK11_DestroySlotListElement(slots, &psle); + PK11_FreeSlotList(slots); + } +- cmsreterr(-1, cms, "could not get certificate list"); ++ cnreterr(-1, cms, "could not get certificate list"); + } + + CERTCertListNode *node = NULL; +@@ -837,7 +837,7 @@ find_certificate_by_callback(cms_context *cms, + } + + if (!node) +- cmsreterr(-1, cms, "Could not find certificate"); ++ cnreterr(-1, cms, "Could not find certificate"); + + *cert = CERT_DupCertificate(node->cert); + +@@ -865,7 +865,7 @@ int + find_named_certificate(cms_context *cms, char *name, CERTCertificate **cert) + { + if (!name) +- cmsreterr(-1, cms, "no subject name specified"); ++ cnreterr(-1, cms, "no subject name specified"); + + return find_certificate_by_callback(cms, match_subject, name, cert); + } +@@ -908,7 +908,7 @@ find_certificate_by_issuer_and_sn(cms_context *cms, + CERTCertificate **cert) + { + if (!ias) +- cmsreterr(-1, cms, "invalid issuer and serial number"); ++ cnreterr(-1, cms, "invalid issuer and serial number"); + + return find_certificate_by_callback(cms, match_issuer_and_serial, &ias, cert); + } +@@ -926,7 +926,7 @@ generate_string(cms_context *cms, SECItem *der, char *str) + ret = SEC_ASN1EncodeItem(cms->arena, der, &input, + SEC_PrintableStringTemplate); + if (ret == NULL) +- cmsreterr(-1, cms, "could not encode string"); ++ cnreterr(-1, cms, "could not encode string"); + return 0; + } + +@@ -946,11 +946,11 @@ generate_time(cms_context *cms, SECItem *encoded, time_t when) + tm->tm_year % 100, tm->tm_mon + 1, tm->tm_mday, + tm->tm_hour, tm->tm_min, tm->tm_sec); + if (whenitem.len == 32) +- cmsreterr(-1, cms, "could not encode timestamp"); ++ cnreterr(-1, cms, "could not encode timestamp"); + + if (SEC_ASN1EncodeItem(cms->arena, encoded, &whenitem, + SEC_UTCTimeTemplate) == NULL) +- cmsreterr(-1, cms, "could not encode timestamp"); ++ cnreterr(-1, cms, "could not encode timestamp"); + return 0; + } + +@@ -975,7 +975,7 @@ generate_empty_sequence(cms_context *cms, SECItem *encoded) + ret = SEC_ASN1EncodeItem(cms->arena, encoded, &empty, + EmptySequenceTemplate); + if (ret == NULL) +- cmsreterr(-1, cms, "could not encode empty sequence"); ++ cnreterr(-1, cms, "could not encode empty sequence"); + return 0; + } + +@@ -1000,7 +1000,7 @@ make_context_specific(cms_context *cms, int ctxt, SECItem *encoded, + rv = SEC_ASN1EncodeItem(cms->arena, encoded, original, + ContextSpecificSequence); + if (rv == NULL) +- cmsreterr(-1, cms, "could not encode context specific data"); ++ cnreterr(-1, cms, "could not encode context specific data"); + return 0; + } + +@@ -1022,12 +1022,12 @@ make_eku_oid(cms_context *cms, SECItem *encoded, SECOidTag oid_tag) + + oid_data = SECOID_FindOIDByTag(oid_tag); + if (!oid_data) +- cmsreterr(-1, cms, "could not encode eku oid data"); ++ cnreterr(-1, cms, "could not encode eku oid data"); + + rv = SEC_ASN1EncodeItem(cms->arena, encoded, &oid_data->oid, + EKUOidSequence); + if (rv == NULL) +- cmsreterr(-1, cms, "could not encode eku oid data"); ++ cnreterr(-1, cms, "could not encode eku oid data"); + + encoded->type = siBuffer; + return 0; +@@ -1042,7 +1042,7 @@ generate_octet_string(cms_context *cms, SECItem *encoded, SECItem *original) + } + if (SEC_ASN1EncodeItem(cms->arena, encoded, original, + SEC_OctetStringTemplate) == NULL) +- cmsreterr(-1, cms, "could not encode octet string"); ++ cnreterr(-1, cms, "could not encode octet string"); + + return 0; + } +@@ -1054,13 +1054,13 @@ generate_object_id(cms_context *cms, SECItem *der, SECOidTag tag) + + oid = SECOID_FindOIDByTag(tag); + if (!oid) +- cmsreterr(-1, cms, "could not find OID"); ++ cnreterr(-1, cms, "could not find OID"); + + void *ret; + ret = SEC_ASN1EncodeItem(cms->arena, der, &oid->oid, + SEC_ObjectIDTemplate); + if (ret == NULL) +- cmsreterr(-1, cms, "could not encode ODI"); ++ cnreterr(-1, cms, "could not encode ODI"); + return 0; + } + +@@ -1109,7 +1109,7 @@ encode_algorithm_id(cms_context *cms, SECItem *der, SECOidTag tag) + ret = SEC_ASN1EncodeItem(cms->arena, der, &id, + SECOID_AlgorithmIDTemplate); + if (ret == NULL) +- cmsreterr(-1, cms, "could not encode Algorithm ID"); ++ cnreterr(-1, cms, "could not encode Algorithm ID"); + + return 0; + } +@@ -1144,14 +1144,14 @@ generate_spc_string(cms_context *cms, SECItem *ssp, char *str, int len) + SECITEM_AllocItem(cms->arena, &ss.unicode, len); + if (len != 0) { + if (!ss.unicode.data) +- cmsreterr(-1, cms, "could not allocate memory"); ++ cnreterr(-1, cms, "could not allocate memory"); + + memcpy(ss.unicode.data, str, len); + } + ss.unicode.type = siBMPString; + + if (SEC_ASN1EncodeItem(cms->arena, ssp, &ss, SpcStringTemplate) == NULL) +- cmsreterr(-1, cms, "could not encode SpcString"); ++ cnreterr(-1, cms, "could not encode SpcString"); + + return 0; + } +@@ -1224,19 +1224,14 @@ generate_digest_begin(cms_context *cms) + } else { + digests = PORT_ZAlloc(n_digest_params * sizeof (*digests)); + if (digests == NULL) +- cmsreterr(-1, cms, "could not allocate digest context"); ++ cnreterr(-1, cms, "could not allocate digest context"); + } + + for (int i = 0; i < n_digest_params; i++) { + digests[i].pk11ctx = PK11_CreateDigestContext( + digest_params[i].digest_tag); +- if (!digests[i].pk11ctx) { +- cms->log(cms, LOG_ERR, "%s:%s:%d could not create " +- "digest context: %s", +- __FILE__, __func__, __LINE__, +- PORT_ErrorToString(PORT_GetError())); +- goto err; +- } ++ if (!digests[i].pk11ctx) ++ cngotoerr(err, cms, "could not create digest context"); + + PK11_DigestBegin(digests[i].pk11ctx); + } +@@ -1268,22 +1263,14 @@ generate_digest_finish(cms_context *cms) + + for (int i = 0; i < n_digest_params; i++) { + SECItem *digest = PORT_ArenaZAlloc(cms->arena,sizeof (SECItem)); +- if (digest == NULL) { +- cms->log(cms, LOG_ERR, "%s:%s:%d could not allocate " +- "memory: %s", __FILE__, __func__, __LINE__, +- PORT_ErrorToString(PORT_GetError())); +- goto err; +- } ++ if (digest == NULL) ++ cngotoerr(err, cms, "could not allocate memory"); + + digest->type = siBuffer; + digest->len = digest_params[i].size; + digest->data = PORT_ArenaZAlloc(cms->arena, digest_params[i].size); +- if (digest->data == NULL) { +- cms->log(cms, LOG_ERR, "%s:%s:%d could not allocate " +- "memory: %s", __FILE__, __func__, __LINE__, +- PORT_ErrorToString(PORT_GetError())); +- goto err; +- } ++ if (digest->data == NULL) ++ cngotoerr(err, cms, "could not allocate memory"); + + PK11_DigestFinal(cms->digests[i].pk11ctx, + digest->data, &digest->len, digest_params[i].size); +@@ -1319,29 +1306,23 @@ generate_signature(cms_context *cms) + { + int rc = 0; + +- if (cms->digests[cms->selected_digest].pe_digest == NULL) { +- cms->log(cms, LOG_ERR, "%s:%s:%d PE digest has not been " +- "allocated", __FILE__, __func__, __LINE__); +- return -1; +- } ++ if (cms->digests[cms->selected_digest].pe_digest == NULL) ++ cnreterr(-1, cms, "PE digest has not been allocated"); + + if (content_is_empty(cms->digests[cms->selected_digest].pe_digest->data, +- cms->digests[cms->selected_digest].pe_digest->len)) { +- cms->log(cms, LOG_ERR, "%s:%s:%d PE binary has not been " +- "digested", __FILE__, __func__, __LINE__); +- return -1; +- } ++ cms->digests[cms->selected_digest].pe_digest->len)) ++ cnreterr(-1, cms, "PE binary has not been digested"); + + SECItem sd_der; + memset(&sd_der, '\0', sizeof(sd_der)); + rc = generate_spc_signed_data(cms, &sd_der); + if (rc < 0) +- cmsreterr(-1, cms, "could not create signed data"); ++ cnreterr(-1, cms, "could not create signed data"); + + memcpy(&cms->newsig, &sd_der, sizeof (cms->newsig)); + cms->newsig.data = malloc(sd_der.len); + if (!cms->newsig.data) +- cmsreterr(-1, cms, "could not allocate signed data"); ++ cnreterr(-1, cms, "could not allocate signed data"); + memcpy(cms->newsig.data, sd_der.data, sd_der.len); + return 0; + } +@@ -1387,7 +1368,7 @@ generate_validity(cms_context *cms, SECItem *der, time_t start, time_t end) + void *ret; + ret = SEC_ASN1EncodeItem(cms->arena, der, &validity, ValidityTemplate); + if (ret == NULL) +- cmsreterr(-1, cms, "could not encode validity"); ++ cnreterr(-1, cms, "could not encode validity"); + return 0; + } + +@@ -1405,7 +1386,7 @@ wrap_in_set(cms_context *cms, SECItem *der, SECItem **items) + + ret = SEC_ASN1EncodeItem(cms->arena, der, &items, &SetTemplate); + if (ret == NULL) +- cmsreterr(-1, cms, "could not encode set"); ++ cnreterr(-1, cms, "could not encode set"); + return 0; + } + +@@ -1447,7 +1428,7 @@ wrap_in_seq(cms_context *cms, SECItem *der, SECItem *items, int num_items) + save_port_err() { + PORT_ArenaRelease(cms->arena, mark); + } +- cmsreterr(-1, cms, "could not encode set"); ++ cnreterr(-1, cms, "could not encode set"); + } + PORT_ArenaUnmark(cms->arena, mark); + return rc; +@@ -1494,7 +1475,7 @@ generate_common_name(cms_context *cms, SECItem *der, char *cn_str) + void *ret; + ret = SEC_ASN1EncodeItem(cms->arena, &cn_item, &cn, CommonNameTemplate); + if (ret == NULL) +- cmsreterr(-1, cms, "could not encode common name"); ++ cnreterr(-1, cms, "could not encode common name"); + + SECItem cn_set; + SECItem *items[2] = {&cn_item, NULL}; +@@ -1542,7 +1523,7 @@ generate_ava(cms_context *cms, SECItem *der, CERTAVA *certava) + + void *arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); + if (arena == NULL) +- cmsreterr(-1, cms, "could not create arena"); ++ cnreterr(-1, cms, "could not create arena"); + + void *real_arena = cms->arena; + cms->arena = arena; +@@ -1553,7 +1534,7 @@ generate_ava(cms_context *cms, SECItem *der, CERTAVA *certava) + PORT_FreeArena(arena, PR_TRUE); + } + cms->arena = real_arena; +- cmsreterr(-1, cms, "could not find OID"); ++ cnreterr(-1, cms, "could not find OID"); + } + + int rc = generate_object_id(cms, &ava.type, oid->offset); +@@ -1573,7 +1554,7 @@ generate_ava(cms_context *cms, SECItem *der, CERTAVA *certava) + PORT_FreeArena(arena, PR_TRUE); + } + cms->arena = real_arena; +- cmsreterr(-1, cms, "could not encode AVA"); ++ cnreterr(-1, cms, "could not encode AVA"); + } + + der->type = tmp.type; +@@ -1584,7 +1565,7 @@ generate_ava(cms_context *cms, SECItem *der, CERTAVA *certava) + PORT_FreeArena(arena, PR_TRUE); + } + cms->arena = real_arena; +- cmsreterr(-1, cms, "could not allocate AVA"); ++ cnreterr(-1, cms, "could not allocate AVA"); + } + memcpy(der->data, tmp.data, tmp.len); + PORT_FreeArena(arena, PR_TRUE); +@@ -1612,7 +1593,7 @@ generate_name(cms_context *cms, SECItem *der, CERTName *certname) + + if (num_items == 0) { + PORT_ArenaRelease(cms->arena, marka); +- cmsreterr(-1, cms, "No name items to encode"); ++ cnreterr(-1, cms, "No name items to encode"); + } + + SECItem items[num_items]; +@@ -1698,7 +1679,7 @@ generate_auth_info(cms_context *cms, SECItem *der, char *url) + + SECOidData *oid = SECOID_FindOIDByTag(SEC_OID_PKIX_CA_ISSUERS); + if (!oid) +- cmsreterr(-1, cms, "could not get CA issuers OID"); ++ cnreterr(-1, cms, "could not get CA issuers OID"); + + memcpy(&ai.oid, &oid->oid, sizeof (ai.oid)); + +@@ -1715,7 +1696,7 @@ generate_auth_info(cms_context *cms, SECItem *der, char *url) + SECItem unwrapped; + ret = SEC_ASN1EncodeItem(cms->arena, &unwrapped, &ai, AuthInfoTemplate); + if (ret == NULL) +- cmsreterr(-1, cms, "could not encode CA Issuers"); ++ cnreterr(-1, cms, "could not encode CA Issuers"); + + rc = wrap_in_seq(cms, der, &unwrapped, 1); + if (rc < 0) +@@ -1725,19 +1706,17 @@ generate_auth_info(cms_context *cms, SECItem *der, char *url) + /* I've no idea how to get SEC_ASN1EncodeItem to spit out the thing + * we actually want here. So once again, just force the data to + * look correct :( */ +- if (unwrapped.len < 12) { +- cms->log(cms, LOG_ERR, "%s:%s:%d generated CA Issuers Info " +- "cannot possibly be valid", +- __FILE__, __func__, __LINE__); +- return -1; +- } ++ if (unwrapped.len < 12) ++ cnreterr(-1, cms, ++ "generated CA Issuers Info cannot possibly be valid"); ++ + unwrapped.data[12] = 0x86; + unwrapped.type = siBuffer; + + AuthInfo wrapper; + oid = SECOID_FindOIDByTag(SEC_OID_X509_AUTH_INFO_ACCESS); + if (!oid) +- cmsreterr(-1, cms, "could not find Auth Info Access OID"); ++ cnreterr(-1, cms, "could not find Auth Info Access OID"); + + memcpy(&wrapper.oid, &oid->oid, sizeof (ai.oid)); + +@@ -1746,7 +1725,7 @@ generate_auth_info(cms_context *cms, SECItem *der, char *url) + ret = SEC_ASN1EncodeItem(cms->arena, der, &wrapper, + AuthInfoWrapperTemplate); + if (ret == NULL) +- cmsreterr(-1, cms, "could not encode CA Issuers OID"); ++ cnreterr(-1, cms, "could not encode CA Issuers OID"); + + return 0; + } +@@ -1763,14 +1742,14 @@ generate_keys(cms_context *cms, PK11SlotInfo *slot, + SECStatus rv; + rv = PK11_Authenticate(slot, PR_TRUE, cms); + if (rv != SECSuccess) +- cmsreterr(-1, cms, "could not authenticate with pk11 service"); ++ cnreterr(-1, cms, "could not authenticate with pk11 service"); + + void *params = &rsaparams; + *privkey = PK11_GenerateKeyPair(slot, CKM_RSA_PKCS_KEY_PAIR_GEN, + params, pubkey, PR_TRUE, PR_TRUE, + cms); + if (!*privkey) +- cmsreterr(-1, cms, "could not generate RSA keypair"); ++ cnreterr(-1, cms, "could not generate RSA keypair"); + return 0; + } + +diff --git a/src/cms_pe_common.c b/src/cms_pe_common.c +index e5a33eb6fe1..f6c5cffc6a9 100644 +--- a/src/cms_pe_common.c ++++ b/src/cms_pe_common.c +@@ -165,7 +165,7 @@ generate_digest(cms_context *cms, Pe *pe, int padded) + * 2. Initialize SHA hash context. */ + map = pe_rawfile(pe, &map_size); + if (!map) +- pereterr(-1, "could not get raw output file address"); ++ cmsreterr(-1, cms, "could not get raw output file address"); + + /* 3. Calculate the distance from the base of the image header to the + * image checksum. +@@ -174,10 +174,8 @@ generate_digest(cms_context *cms, Pe *pe, int padded) + hash_base = map; + + opthdr = pe_getopthdr(pe); +- if (opthdr == NULL) { +- cms->log(cms, LOG_ERR, "%s:%s:%d PE header is invalid", __FILE__, __func__, __LINE__); +- goto error; +- } ++ if (opthdr == NULL) ++ cmsgotoerr(error, cms, "PE header is invalid"); + + switch (pe_kind(pe)) { + case PE_K_PE_EXE: { +diff --git a/src/cms_common.h b/src/cms_common.h +index 04974035f0c..1bffdcd034b 100644 +--- a/src/cms_common.h ++++ b/src/cms_common.h +@@ -41,19 +41,30 @@ + #define for_each_cert(cl, node) \ + for (CERTCertListNode *node = CERT_LIST_HEAD(cl); !CERT_LIST_END(node, cl); node = CERT_LIST_NEXT(node)) + +-#define cmserr(rv, cms, fmt, args...) ({ \ +- (cms)->log((cms), LOG_ERR, "%s:%s:%d: " fmt ": %s", \ +- __FILE__, __func__, __LINE__, ## args, \ +- PORT_ErrorToString(PORT_GetError())); \ +- exit(rv); \ ++#define cmsreterr(rv, cms, fmt, args...) ({ \ ++ (cms)->log((cms), LOG_ERR, "%s:%s:%d: " fmt, \ ++ __FILE__, __func__, __LINE__, ## args); \ ++ return rv; \ + }) +-#define cmsreterr(rv, cms, fmt, args...) ({ \ ++#define cmsgotoerr(errlabel, cms, fmt, args...) ({ \ ++ (cms)->log((cms), LOG_ERR, "%s:%s:%d: " fmt, \ ++ __FILE__, __func__, __LINE__, ## args); \ ++ goto errlabel; \ ++ }) ++#define cnreterr(rv, cms, fmt, args...) ({ \ + (cms)->log((cms), LOG_ERR, "%s:%s:%d: " fmt ":%s:%s", \ + __FILE__, __func__, __LINE__, ## args, \ + PORT_ErrorToName(PORT_GetError()), \ + PORT_ErrorToString(PORT_GetError())); \ + return rv; \ + }) ++#define cngotoerr(errlabel, cms, fmt, args...) ({ \ ++ (cms)->log((cms), LOG_ERR, "%s:%s:%d: " fmt ":%s:%s", \ ++ __FILE__, __func__, __LINE__, ## args, \ ++ PORT_ErrorToName(PORT_GetError()), \ ++ PORT_ErrorToString(PORT_GetError())); \ ++ goto errlabel; \ ++ }) + + struct digest { + PK11Context *pk11ctx; +-- +2.29.2 + diff --git a/0041-Make-cms_pe_common-bounds-check-errors-more-verbose.patch b/0041-Make-cms_pe_common-bounds-check-errors-more-verbose.patch new file mode 100644 index 0000000..46d45a3 --- /dev/null +++ b/0041-Make-cms_pe_common-bounds-check-errors-more-verbose.patch @@ -0,0 +1,181 @@ +From 2802ad709872f8291786ce31400a3496bbe23b14 Mon Sep 17 00:00:00 2001 +From: Peter Jones +Date: Tue, 16 Feb 2021 11:19:30 -0500 +Subject: [PATCH 41/42] Make cms_pe_common bounds check errors more verbose + +One of these is failing for hughsie, and that's weird, so I want to know +why. + +Signed-off-by: Peter Jones +--- + src/cms_pe_common.c | 76 +++++++++++++++++++-------------------------- + 1 file changed, 32 insertions(+), 44 deletions(-) + +diff --git a/src/cms_pe_common.c b/src/cms_pe_common.c +index f6c5cffc6a9..bdcfaff99f8 100644 +--- a/src/cms_pe_common.c ++++ b/src/cms_pe_common.c +@@ -43,29 +43,30 @@ + #include + + static int +-check_pointer_and_size(Pe *pe, void *ptr, size_t size) ++check_pointer_and_size(cms_context *cms, Pe *pe, void *ptr, size_t size) + { + void *map = NULL; + size_t map_size = 0; + + map = pe_rawfile(pe, &map_size); + if (!map || map_size < 1) +- return 0; ++ cmsreterr(0, cms, "mmap is %p mmap size is %zd end is %p", ++ map, map_size, (void *)((uintptr_t)map + map_size)); + + if ((uintptr_t)ptr < (uintptr_t)map) +- return 0; ++ cmsreterr(0, cms, "pointer %p is below mmap at %p", ptr, map); + + if ((uintptr_t)ptr + size > (uintptr_t)map + map_size) +- return 0; +- +- if (ptr <= map && size >= map_size) +- return 0; ++ cmsreterr(0, cms, ++ "pointer region end %p is above mmap end at %p", ++ (void *)((uintptr_t)ptr + size), ++ (void *)((uintptr_t)map + map_size)); + + return 1; + } + + static void * +-get_strtab(Pe *pe) ++get_strtab(cms_context *cms, Pe *pe) + { + static void *ret = NULL; + uint32_t *ptr; +@@ -91,17 +92,17 @@ get_strtab(Pe *pe) + intret += pehdr.symbols * sizeof(struct pe_symtab_entry); + + ptr = (uint32_t *)((intptr_t)map + intret); +- if (!check_pointer_and_size(pe, ptr, 4)) ++ if (!check_pointer_and_size(cms, pe, ptr, 4)) + pereterr(NULL, "invalid string table start"); + +- if (!check_pointer_and_size(pe, ptr, *ptr)) ++ if (!check_pointer_and_size(cms, pe, ptr, *ptr)) + pereterr(NULL, "invalid string table size"); + ret = ptr; + return ret; + } + + static char * +-get_str(Pe *pe, char *strnum) ++get_str(cms_context *cms, Pe *pe, char *strnum) + { + size_t sz; + unsigned long num; +@@ -120,7 +121,7 @@ get_str(Pe *pe, char *strnum) + if (errno != 0) + return NULL; + +- strtab = get_strtab(pe); ++ strtab = get_strtab(cms, pe); + if (!strtab) + return NULL; + +@@ -191,11 +192,8 @@ generate_digest(cms_context *cms, Pe *pe, int padded) + default: + goto error; + } +- if (!check_pointer_and_size(pe, hash_base, hash_size)) { +- cms->log(cms, LOG_ERR, "%s:%s:%d PE header is invalid", +- __FILE__, __func__, __LINE__); +- goto error; +- } ++ if (!check_pointer_and_size(cms, pe, hash_base, hash_size)) ++ cmsgotoerr(error, cms, "PE header is invalid"); + dprintf("beginning of hash"); + dprintf("digesting %lx + %lx", hash_base - map, hash_size); + generate_digest_step(cms, hash_base, hash_size); +@@ -209,18 +207,13 @@ generate_digest(cms_context *cms, Pe *pe, int padded) + data_directory *dd; + + rc = pe_getdatadir(pe, &dd); +- if (rc < 0 || !dd || !check_pointer_and_size(pe, dd, sizeof(*dd))) { +- cms->log(cms, LOG_ERR, "%s:%s:%d PE data directory is invalid", +- __FILE__, __func__, __LINE__); +- goto error; +- } ++ if (rc < 0 || !dd || !check_pointer_and_size(cms, pe, dd, sizeof(*dd))) ++ cmsgotoerr(error, cms, "PE data directory is invalid"); + + hash_size = (uintptr_t)&dd->certs - (uintptr_t)hash_base; +- if (!check_pointer_and_size(pe, hash_base, hash_size)) { +- cms->log(cms, LOG_ERR, "%s:%s:%d PE data directory is invalid", +- __FILE__, __func__, __LINE__); +- goto error; +- } ++ if (!check_pointer_and_size(cms, pe, hash_base, hash_size)) ++ cmsgotoerr(error, cms, "PE data directory is invalid"); ++ + generate_digest_step(cms, hash_base, hash_size); + dprintf("digesting %lx + %lx", hash_base - map, hash_size); + +@@ -231,11 +224,9 @@ generate_digest(cms_context *cms, Pe *pe, int padded) + : pe64opthdr->header_size) - + ((uintptr_t)&dd->base_relocations - (uintptr_t)map); + +- if (!check_pointer_and_size(pe, hash_base, hash_size)) { +- cms->log(cms, LOG_ERR, "%s:%s:%d PE relocations table is " +- "invalid", __FILE__, __func__, __LINE__); +- goto error; +- } ++ if (!check_pointer_and_size(cms, pe, hash_base, hash_size)) ++ cmsgotoerr(error, cms, "PE relocations table is invalid"); ++ + generate_digest_step(cms, hash_base, hash_size); + dprintf("digesting %lx + %lx", hash_base - map, hash_size); + +@@ -262,17 +253,15 @@ generate_digest(cms_context *cms, Pe *pe, int padded) + hash_base = (void *)((uintptr_t)map + shdrs[i].data_addr); + hash_size = shdrs[i].raw_data_size; + +- if (!check_pointer_and_size(pe, hash_base, hash_size)) { +- cms->log(cms, LOG_ERR, "%s:%s:%d PE section \"%s\" " +- "has invalid address", +- __FILE__, __func__, __LINE__, shdrs[i].name); +- goto error_shdrs; +- } ++ if (!check_pointer_and_size(cms, pe, hash_base, hash_size)) ++ cmsgotoerr(error_shdrs, cms, ++ "PE section \"%s\" has invalid address", ++ shdrs[i].name); + + if (cms->omit_vendor_cert) { + char *name = shdrs[i].name; + if (name && name[0] == '/') +- name = get_str(pe, name + 1); ++ name = get_str(cms, pe, name + 1); + dprintf("section:\"%s\"", name ? name : "(null)"); + if (name && !strcmp(name, ".vendor_cert")) { + dprintf("skipping .vendor_cert section"); +@@ -291,11 +280,10 @@ generate_digest(cms_context *cms, Pe *pe, int padded) + hash_base = (void *)((uintptr_t)map + hashed_bytes); + hash_size = map_size - dd->certs.size - hashed_bytes; + +- if (!check_pointer_and_size(pe, hash_base, hash_size)) { +- cms->log(cms, LOG_ERR, "%s:%s:%d PE has invalid " +- "trailing data", __FILE__, __func__, __LINE__); +- goto error_shdrs; +- } ++ if (!check_pointer_and_size(cms, pe, hash_base, hash_size)) ++ cmsgotoerr(error_shdrs, cms, ++ "PE has invalid trailing data"); ++ + if (hash_size % 8 != 0 && padded) { + size_t tmp_size = hash_size + + ALIGNMENT_PADDING(hash_size, 8); +-- +2.29.2 + diff --git a/0042-Fix-our-error-message-line-numbers-hopefully.patch b/0042-Fix-our-error-message-line-numbers-hopefully.patch new file mode 100644 index 0000000..fd78c8a --- /dev/null +++ b/0042-Fix-our-error-message-line-numbers-hopefully.patch @@ -0,0 +1,152 @@ +From 25bc2f4ce9215cd39fb448ada642824a5d20205f Mon Sep 17 00:00:00 2001 +From: Peter Jones +Date: Tue, 16 Feb 2021 11:47:00 -0500 +Subject: [PATCH 42/42] Fix our error message line numbers, hopefully. + +Most of these seem to be off by a line or two; it's pretty obvious why. + +Signed-off-by: Peter Jones +--- + src/cms_common.h | 10 ++++++---- + src/compiler.h | 5 ++++- + src/util.h | 32 +++++++++++++++++++++++--------- + 3 files changed, 33 insertions(+), 14 deletions(-) + +diff --git a/src/cms_common.h b/src/cms_common.h +index 1bffdcd034b..6cc31d5c6f0 100644 +--- a/src/cms_common.h ++++ b/src/cms_common.h +@@ -43,24 +43,26 @@ + + #define cmsreterr(rv, cms, fmt, args...) ({ \ + (cms)->log((cms), LOG_ERR, "%s:%s:%d: " fmt, \ +- __FILE__, __func__, __LINE__, ## args); \ ++ __FILE__, __func__, __LINE__ - 2, \ ++ ## args); \ + return rv; \ + }) + #define cmsgotoerr(errlabel, cms, fmt, args...) ({ \ + (cms)->log((cms), LOG_ERR, "%s:%s:%d: " fmt, \ +- __FILE__, __func__, __LINE__, ## args); \ ++ __FILE__, __func__, __LINE__ - 2, \ ++ ## args); \ + goto errlabel; \ + }) + #define cnreterr(rv, cms, fmt, args...) ({ \ + (cms)->log((cms), LOG_ERR, "%s:%s:%d: " fmt ":%s:%s", \ +- __FILE__, __func__, __LINE__, ## args, \ ++ __FILE__, __func__, __LINE__ - 2, ## args, \ + PORT_ErrorToName(PORT_GetError()), \ + PORT_ErrorToString(PORT_GetError())); \ + return rv; \ + }) + #define cngotoerr(errlabel, cms, fmt, args...) ({ \ + (cms)->log((cms), LOG_ERR, "%s:%s:%d: " fmt ":%s:%s", \ +- __FILE__, __func__, __LINE__, ## args, \ ++ __FILE__, __func__, __LINE__ - 2, ## args, \ + PORT_ErrorToName(PORT_GetError()), \ + PORT_ErrorToString(PORT_GetError())); \ + goto errlabel; \ +diff --git a/src/compiler.h b/src/compiler.h +index 31379ef9b33..5d979c9d977 100644 +--- a/src/compiler.h ++++ b/src/compiler.h +@@ -23,6 +23,9 @@ + #define ALIGNED(n) __attribute__((__aligned__(n))) + #define CLEANUP_FUNC(x) __attribute__((__cleanup__(x))) + ++#ifndef __CONCAT ++#define __CONCAT(a, b) a ## b ++#endif + #define __CONCAT3(a, b, c) a ## b ## c + #define CONCATENATE(a, b) __CONCAT(a, b) + #define CAT(a, b) __CONCAT(a, b) +@@ -71,7 +74,7 @@ + * compiler has support to do so. + */ + #define compiletime_assert(condition, msg) \ +- _compiletime_assert(condition, msg, __compiletime_assert_, __LINE__) ++ _compiletime_assert(condition, msg, __compiletime_assert_, __LINE__ - 1) + + /** + * BUILD_BUG_ON_MSG - break compile if a condition is true & emit supplied +diff --git a/src/util.h b/src/util.h +index 21a846c10ee..e2893b71c39 100644 +--- a/src/util.h ++++ b/src/util.h +@@ -67,7 +67,7 @@ + + #define nsserr(rv, fmt, args...) ({ \ + errx((rv), "%s:%s:%d: " fmt ": %s", \ +- __FILE__, __func__, __LINE__, ##args, \ ++ __FILE__, __func__, __LINE__ - 2, ##args, \ + PORT_ErrorToString(PORT_GetError())); \ + }) + #define condnsserr(cond, rv, fmt, args...) ({ \ +@@ -76,7 +76,7 @@ + }) + #define nssreterr(rv, fmt, args...) ({ \ + fprintf(stderr, "%s:%s:%d: " fmt ": %s\n", \ +- __FILE__, __func__, __LINE__, ##args, \ ++ __FILE__, __func__, __LINE__ - 2, ##args, \ + PORT_ErrorToString(PORT_GetError())); \ + return rv; \ + }) +@@ -86,21 +86,21 @@ + }) + #define liberr(rv, fmt, args...) ({ \ + err((rv), "%s:%s:%d: " fmt, \ +- __FILE__, __func__, __LINE__, ##args); \ ++ __FILE__, __func__, __LINE__ - 2, ##args); \ + }) + #define libreterr(rv, fmt, args...) ({ \ + fprintf(stderr, "%s:%s:%d: " fmt ": %m\n", \ +- __FILE__, __func__, __LINE__, ##args); \ ++ __FILE__, __func__, __LINE__ - 2, ##args); \ + return rv; \ + }) + #define peerr(rv, fmt, args...) ({ \ + errx((rv), "%s:%s:%d: " fmt ": %s", \ +- __FILE__, __func__, __LINE__, ##args, \ ++ __FILE__, __func__, __LINE__ - 2, ##args, \ + pe_errmsg(pe_errno())); \ + }) + #define pereterr(rv, fmt, args...) ({ \ + fprintf(stderr, "%s:%s:%d: " fmt ": %s\n", \ +- __FILE__, __func__, __LINE__, ##args, \ ++ __FILE__, __func__, __LINE__ - 2, ##args, \ + pe_errmsg(pe_errno())); \ + return rv; \ + }) +@@ -274,11 +274,25 @@ proxy_fd_mode(int fd, char *infile, mode_t *outmode, size_t *inlength) + + extern long verbosity(void); + +-#define dprintf_(tv, file, func, line, fmt, args...) ({struct timeval tv; gettimeofday(&tv, NULL); warnx("%ld.%lu %s:%s():%d: " fmt, tv.tv_sec, tv.tv_usec, file, func, line, ##args); }) ++#define dprintf_(tv, file, func, line, fmt, args...) ({ \ ++ struct timeval tv; \ ++ gettimeofday(&tv, NULL); \ ++ warnx("%ld.%lu %s:%s():%d: " fmt, \ ++ tv.tv_sec, tv.tv_usec, \ ++ file, func, line, ##args); \ ++ }) + #if defined(PESIGN_DEBUG) +-#define dprintf(fmt, args...) dprintf_(CAT(CAT(CAT(tv_,__COUNTER__),__LINE__),_), __FILE__, __func__, __LINE__, fmt, ##args) ++#define dprintf(fmt, args...) \ ++ dprintf_(CAT(CAT(CAT(tv_,__COUNTER__),__LINE__),_), \ ++ __FILE__, __func__, __LINE__ - 2, fmt, ##args) + #else +-#define dprintf(fmt, args...) ({ if (verbosity() > 1) dprintf_(CAT(CAT(CAT(tv_,__COUNTER__),__LINE__),_), __FILE__, __func__, __LINE__, fmt, ##args); 0; }) ++#define dprintf(fmt, args...) ({ \ ++ if (verbosity() > 1) \ ++ dprintf_(CAT(CAT(CAT(tv_,__COUNTER__),__LINE__),_), \ ++ __FILE__, __func__, __LINE__ - 3, \ ++ fmt, ##args); \ ++ 0; \ ++ }) + #endif + #define ingress() dprintf("ingress"); + #define egress() dprintf("egress"); +-- +2.29.2 + diff --git a/pesign.spec b/pesign.spec index 74e4405..c52f883 100644 --- a/pesign.spec +++ b/pesign.spec @@ -3,7 +3,7 @@ Name: pesign Summary: Signing utility for UEFI binaries Version: 113 -Release: 12%{?dist} +Release: 13%{?dist} License: GPLv2 URL: https://github.com/vathpela/pesign @@ -47,13 +47,43 @@ Patch0002: 0002-pesigcheck-Fix-a-wrong-assignment.patch Patch0003: 0003-Make-0.112-client-and-server-work-with-the-113-proto.patch Patch0004: 0004-Rename-var-run-to-run.patch Patch0005: 0005-Apparently-opensc-got-updated-and-the-token-name-cha.patch -Patch0006: 0006-client-try-run-and-var-run-for-the-socket-path.patch -Patch0007: 0007-client-remove-an-extra-debug-print.patch -Patch0008: 0008-Move-most-of-macros.pesign-to-pesign-rpmbuild-helper.patch -Patch0009: 0009-pesign-authorize-shellcheck.patch -Patch0010: 0010-pesign-authorize-don-t-setfacl-etc-pki-pesign-foo.patch -Patch0011: 0011-kernel-building-hack.patch -Patch0012: 0012-Use-run-not-var-run.patch +Patch0006: 0006-Add-some-more-utility-functions-and-fix-a-typo-in-AL.patch +Patch0007: 0007-Add-hex-utilities.patch +Patch0008: 0008-Add-some-text-parsing-helpers.patch +Patch0009: 0009-libdpe-fix-some-minor-analyzer-discoveries.patch +Patch0010: 0010-libdpe-check-for-NULL-pe-at-more-places.patch +Patch0011: 0011-wincert-try-to-convince-the-gcc-analyzer-of-the-pain.patch +Patch0012: 0012-Fix-a-missing-malloc-return-value-check.patch +Patch0013: 0013-Fix-some-missed-OOM-error-path-fanalyzer-found.patch +Patch0014: 0014-Don-t-allow-or-require-module-or-kernel-with-ca.patch +Patch0015: 0015-Add-super-convenient-errno-guard-implementation.patch +Patch0016: 0016-Make-save_port_err-saner-to-read.patch +Patch0017: 0017-Make-for_each_cert-cl-iter-for-certificate-list-trav.patch +Patch0018: 0018-file_pe-make-most-of-our-input-and-output-checkers-b.patch +Patch0019: 0019-file_pe-user-err-errx-etc.patch +Patch0020: 0020-pesign_kmod-user-err-errx-etc.patch +Patch0021: 0021-share-input-output-checker-macros-between-pesign_kmo.patch +Patch0022: 0022-Make-verbose-work-in-efisiglist.patch +Patch0023: 0023-Make-verbose-and-debug-more-similar-across-tools.patch +Patch0024: 0024-Work-around-some-NSS-SECOID_AddEntry-bugs.patch +Patch0025: 0025-Rework-the-wildly-undocumented-NSS-password-file-goo.patch +Patch0026: 0026-Minor-whitespace-housekeeping.patch +Patch0027: 0027-libdpe-make-the-initial-read-buffer-always-big-enoug.patch +Patch0028: 0028-Fix-some-memory-leaks.patch +Patch0029: 0029-Improve-debug-output.patch +Patch0030: 0030-support-uri-token-names.patch +Patch0031: 0031-cms_common-add-some-more-ways-to-find-a-cert.patch +Patch0032: 0032-client-try-run-and-var-run-for-the-socket-path.patch +Patch0033: 0033-client-remove-an-extra-debug-print.patch +Patch0034: 0034-Move-most-of-macros.pesign-to-pesign-rpmbuild-helper.patch +Patch0035: 0035-pesign-authorize-shellcheck.patch +Patch0036: 0036-pesign-authorize-don-t-setfacl-etc-pki-pesign-foo.patch +Patch0037: 0037-kernel-building-hack.patch +Patch0038: 0038-Use-run-not-var-run.patch +Patch0039: 0039-efikeygen-return-error-on-AKID-encoding-failures.patch +Patch0040: 0040-Rename-some-cms-error-functions.patch +Patch0041: 0041-Make-cms_pe_common-bounds-check-errors-more-verbose.patch +Patch0042: 0042-Fix-our-error-message-line-numbers-hopefully.patch %description This package contains the pesign utility for signing UEFI binaries as @@ -158,6 +188,9 @@ certutil -d %{_sysconfdir}/pki/pesign/ -X -L > /dev/null %{python3_sitelib}/mockbuild/plugins/pesign.* %changelog +* Thu Feb 18 2021 Peter Jones - 113-13 +- Backport a bunch of stuff the upstream development tree. + * Mon Aug 03 2020 Peter Jones - 113-12 - Try to make kernel and fwupd both work at the same time.