From 46503a99be9c8362c8eb37e19802c2df09413e91 Mon Sep 17 00:00:00 2001 From: gu-gu-gu Date: Tue, 3 Dec 2019 11:21:29 +0800 Subject: [PATCH] pesign: openEuler init --- ...e_integer-it-doesn-t-build-on-i686-a.patch | 72 +++ 0002-Fix-command-line-parsing.patch | 73 +++ ...gcc-don-t-error-on-stuff-in-includes.patch | 26 ++ 0004-Fix-certficate-argument-name.patch | 39 ++ ...ion-of-ascii-armor-option-in-manpage.patch | 26 ++ ...ke-ascii-work-since-we-documented-it.patch | 22 + ...ient-to-also-accept-token-cert-macro.patch | 32 ++ ...fy-with-the-cert-as-an-object-signer.patch | 25 ++ ...sigcheck-make-certfile-actually-work.patch | 47 ++ ...-make-sure-err-is-always-initialized.patch | 27 ++ ...make-pesign-h-tell-you-the-file-name.patch | 26 ++ 0012-Add-coverity-build-scripts.patch | 104 +++++ 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 ++ certs.tar.xz | Bin 0 -> 204800 bytes euleros-certs.tar.bz2 | Bin 0 -> 8768 bytes pesign-0.112.tar.bz2 | Bin 0 -> 90251 bytes pesign.py | 91 ++++ pesign.spec | 136 ++++++ 34 files changed, 2432 insertions(+) create mode 100644 0001-cms-kill-generate_integer-it-doesn-t-build-on-i686-a.patch create mode 100644 0002-Fix-command-line-parsing.patch create mode 100644 0003-gcc-don-t-error-on-stuff-in-includes.patch create mode 100644 0004-Fix-certficate-argument-name.patch create mode 100644 0005-Fix-description-of-ascii-armor-option-in-manpage.patch create mode 100644 0006-Make-ascii-work-since-we-documented-it.patch create mode 100644 0007-Switch-pesign-client-to-also-accept-token-cert-macro.patch create mode 100644 0008-pesigcheck-Verify-with-the-cert-as-an-object-signer.patch create mode 100644 0009-pesigcheck-make-certfile-actually-work.patch create mode 100644 0010-signerInfos-make-sure-err-is-always-initialized.patch create mode 100644 0011-pesign-make-pesign-h-tell-you-the-file-name.patch create mode 100644 0012-Add-coverity-build-scripts.patch create mode 100644 0013-Document-implicit-fallthrough.patch create mode 100644 0014-Actually-setfacl-each-directory-of-our-key-storage.patch create mode 100644 0015-oid-add-SHIM_EKU_MODULE_SIGNING_ONLY-and-fix-our-arr.patch create mode 100644 0016-efikeygen-add-modsign.patch create mode 100644 0017-check_cert_db-try-even-harder-to-pick-a-reasonable-v.patch create mode 100644 0018-show-which-db-we-re-checking.patch create mode 100644 0019-more-about-the-time.patch create mode 100644 0020-try-to-say-why-something-fails.patch create mode 100644 0021-Fix-race-condition-in-SEC_GetPassword.patch create mode 100644 0022-sysvinit-Create-the-socket-directory-at-runtime.patch create mode 100644 0023-Better-authorization-scripts.-Again.patch create mode 100644 0024-Make-the-daemon-also-try-to-give-better-errors-on-EP.patch create mode 100644 0025-certdb-fix-PRTime-printfs-for-i686.patch create mode 100644 0026-Clean-up-gcc-command-lines-a-little.patch create mode 100644 0027-Make-pesign-users-groups-static-in-the-repo.patch create mode 100644 0028-rpm-Make-the-client-signer-use-the-fedora-values-unl.patch create mode 100644 0029-Make-macros.pesign-error-in-kojibuilder-if-we-don-t-.patch create mode 100644 certs.tar.xz create mode 100644 euleros-certs.tar.bz2 create mode 100644 pesign-0.112.tar.bz2 create mode 100644 pesign.py create mode 100644 pesign.spec 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 new file mode 100644 index 0000000..0c82dcf --- /dev/null +++ b/0001-cms-kill-generate_integer-it-doesn-t-build-on-i686-a.patch @@ -0,0 +1,72 @@ +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/0002-Fix-command-line-parsing.patch b/0002-Fix-command-line-parsing.patch new file mode 100644 index 0000000..9c03eeb --- /dev/null +++ b/0002-Fix-command-line-parsing.patch @@ -0,0 +1,73 @@ +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/0003-gcc-don-t-error-on-stuff-in-includes.patch b/0003-gcc-don-t-error-on-stuff-in-includes.patch new file mode 100644 index 0000000..cf4e61d --- /dev/null +++ b/0003-gcc-don-t-error-on-stuff-in-includes.patch @@ -0,0 +1,26 @@ +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 new file mode 100644 index 0000000..08509ff --- /dev/null +++ b/0004-Fix-certficate-argument-name.patch @@ -0,0 +1,39 @@ +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/0005-Fix-description-of-ascii-armor-option-in-manpage.patch b/0005-Fix-description-of-ascii-armor-option-in-manpage.patch new file mode 100644 index 0000000..6a5b02d --- /dev/null +++ b/0005-Fix-description-of-ascii-armor-option-in-manpage.patch @@ -0,0 +1,26 @@ +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 new file mode 100644 index 0000000..d0165f9 --- /dev/null +++ b/0006-Make-ascii-work-since-we-documented-it.patch @@ -0,0 +1,22 @@ +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/0007-Switch-pesign-client-to-also-accept-token-cert-macro.patch b/0007-Switch-pesign-client-to-also-accept-token-cert-macro.patch new file mode 100644 index 0000000..faa78ec --- /dev/null +++ b/0007-Switch-pesign-client-to-also-accept-token-cert-macro.patch @@ -0,0 +1,32 @@ +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/0008-pesigcheck-Verify-with-the-cert-as-an-object-signer.patch b/0008-pesigcheck-Verify-with-the-cert-as-an-object-signer.patch new file mode 100644 index 0000000..2226498 --- /dev/null +++ b/0008-pesigcheck-Verify-with-the-cert-as-an-object-signer.patch @@ -0,0 +1,25 @@ +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 new file mode 100644 index 0000000..8b77417 --- /dev/null +++ b/0009-pesigcheck-make-certfile-actually-work.patch @@ -0,0 +1,47 @@ +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/0010-signerInfos-make-sure-err-is-always-initialized.patch b/0010-signerInfos-make-sure-err-is-always-initialized.patch new file mode 100644 index 0000000..08d1da7 --- /dev/null +++ b/0010-signerInfos-make-sure-err-is-always-initialized.patch @@ -0,0 +1,27 @@ +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-pesign-make-pesign-h-tell-you-the-file-name.patch b/0011-pesign-make-pesign-h-tell-you-the-file-name.patch new file mode 100644 index 0000000..3e15617 --- /dev/null +++ b/0011-pesign-make-pesign-h-tell-you-the-file-name.patch @@ -0,0 +1,26 @@ +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 new file mode 100644 index 0000000..f3f0a89 --- /dev/null +++ b/0012-Add-coverity-build-scripts.patch @@ -0,0 +1,104 @@ +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/0013-Document-implicit-fallthrough.patch b/0013-Document-implicit-fallthrough.patch new file mode 100644 index 0000000..3731a3f --- /dev/null +++ b/0013-Document-implicit-fallthrough.patch @@ -0,0 +1,25 @@ +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 new file mode 100644 index 0000000..4b62cb3 --- /dev/null +++ b/0014-Actually-setfacl-each-directory-of-our-key-storage.patch @@ -0,0 +1,50 @@ +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 new file mode 100644 index 0000000..d5428b5 --- /dev/null +++ b/0015-oid-add-SHIM_EKU_MODULE_SIGNING_ONLY-and-fix-our-arr.patch @@ -0,0 +1,59 @@ +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 new file mode 100644 index 0000000..8324334 --- /dev/null +++ b/0016-efikeygen-add-modsign.patch @@ -0,0 +1,197 @@ +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 new file mode 100644 index 0000000..acebc3a --- /dev/null +++ b/0017-check_cert_db-try-even-harder-to-pick-a-reasonable-v.patch @@ -0,0 +1,121 @@ +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 new file mode 100644 index 0000000..2b92f83 --- /dev/null +++ b/0018-show-which-db-we-re-checking.patch @@ -0,0 +1,137 @@ +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 new file mode 100644 index 0000000..2570bf8 --- /dev/null +++ b/0019-more-about-the-time.patch @@ -0,0 +1,97 @@ +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 new file mode 100644 index 0000000..96bdd60 --- /dev/null +++ b/0020-try-to-say-why-something-fails.patch @@ -0,0 +1,419 @@ +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 new file mode 100644 index 0000000..3088923 --- /dev/null +++ b/0021-Fix-race-condition-in-SEC_GetPassword.patch @@ -0,0 +1,34 @@ +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 new file mode 100644 index 0000000..06980ee --- /dev/null +++ b/0022-sysvinit-Create-the-socket-directory-at-runtime.patch @@ -0,0 +1,27 @@ +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 new file mode 100644 index 0000000..c778c94 --- /dev/null +++ b/0023-Better-authorization-scripts.-Again.patch @@ -0,0 +1,217 @@ +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 new file mode 100644 index 0000000..8f4a380 --- /dev/null +++ b/0024-Make-the-daemon-also-try-to-give-better-errors-on-EP.patch @@ -0,0 +1,95 @@ +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 new file mode 100644 index 0000000..0fc2ad8 --- /dev/null +++ b/0025-certdb-fix-PRTime-printfs-for-i686.patch @@ -0,0 +1,31 @@ +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 new file mode 100644 index 0000000..928d62d --- /dev/null +++ b/0026-Clean-up-gcc-command-lines-a-little.patch @@ -0,0 +1,41 @@ +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 new file mode 100644 index 0000000..4131de3 --- /dev/null +++ b/0027-Make-pesign-users-groups-static-in-the-repo.patch @@ -0,0 +1,54 @@ +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 new file mode 100644 index 0000000..ad9da8d --- /dev/null +++ b/0028-rpm-Make-the-client-signer-use-the-fedora-values-unl.patch @@ -0,0 +1,43 @@ +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:"Fedora Signer (OpenSC Card)"}%{?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 new file mode 100644 index 0000000..753afe8 --- /dev/null +++ b/0029-Make-macros.pesign-error-in-kojibuilder-if-we-don-t-.patch @@ -0,0 +1,39 @@ +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/certs.tar.xz b/certs.tar.xz new file mode 100644 index 0000000000000000000000000000000000000000..e99e5760a92646163cab218884dd5f077103aa46 GIT binary patch literal 204800 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 literal 0 HcmV?d00001 diff --git a/pesign-0.112.tar.bz2 b/pesign-0.112.tar.bz2 new file mode 100644 index 0000000000000000000000000000000000000000..61f3b26fc3bec2cdd8be329d10d00ff373adfa1f GIT binary patch literal 90251 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 &ps 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 GHLSp3`I`{{ literal 0 HcmV?d00001 diff --git a/pesign.py b/pesign.py new file mode 100644 index 0000000..4ee59f8 --- /dev/null +++ b/pesign.py @@ -0,0 +1,91 @@ +#!/usr/bin/python3 +# +# Copyright 2017 Peter Jones +# +# Distributed under terms of the GPLv3 license. + +""" +mock plugin to make sure pesign and mockbuild users have the right uid and +gid. +""" + +from mockbuild.trace_decorator import getLog, traceLog +import mockbuild.util + +requires_api_version = "1.1" + +@traceLog() +def init(plugins, conf, buildroot): + """ hello """ + Pesign(plugins, conf, buildroot) + +def getuid(name): + """ get a uid for a user name """ + output = mockbuild.util.do(["getent", "passwd", "%s" % (name,)], + returnOutput=1, printOutput=True) + output = output.split(':') + return output[2], output[3] + +def getgid(name): + """ get a gid for a group name """ + output = mockbuild.util.do(["getent", "group", "%s" % (name,)], + returnOutput=1, printOutput=True) + return output.split(':')[2] + +def newgroup(name, gid, rootdir): + """ create a group with a gid """ + getLog().info("creating group %s with gid %s" % (name, gid)) + mockbuild.util.do(["groupadd", + "-g", "%s" % (gid,), + "-R", "%s" % (rootdir,), + "%s" % (name,), + ]) + +def newuser(name, uid, gid, rootdir): + """ create a user with a uid """ + getLog().info("creating user %s with uid %s" % (name, uid)) + mockbuild.util.do(["useradd", + "-u", "%s" % (uid,), + "-g", "%s" % (gid,), + "-R", "%s" % (rootdir,), + "%s" % (name,)]) + +class Pesign(object): + """ Creates some stuff in our mock root """ + # pylint: disable=too-few-public-methods + @traceLog() + def __init__(self, plugins, conf, buildroot): + """ Effectively we're doing: + getent group pesign >/dev/null || groupadd -r pesign + getent passwd pesign >/dev/null || \ + useradd -r -g pesign -d /var/run/pesign -s /sbin/nologin \ + -c "Group for the pesign signing daemon" pesign + """ + + self.buildroot = buildroot + self.pesign_opts = conf + self.config = buildroot.config + self.state = buildroot.state + self.users = {} + self.groups = {} + plugins.add_hook("postinit", self._pesignPostInitHook) + + @traceLog() + def _pesignPostInitHook(self): + """ find our uid and gid lists """ + for user in self.pesign_opts['users']: + uid, gid = getuid(user) + self.users[user] = [user, uid, gid] + for group in self.pesign_opts['groups']: + gid = getgid(group) + self.groups[group] = [group, gid] + + # create our users + rootdir = self.buildroot.make_chroot_path() + for name, gid in self.groups.values(): + newgroup(name, gid, rootdir) + for name, uid, gid in self.users.values(): + newuser(name, uid, gid, rootdir) + +# -*- coding: utf-8 -*- +# vim:fenc=utf-8:tw=75 diff --git a/pesign.spec b/pesign.spec new file mode 100644 index 0000000..a8f026c --- /dev/null +++ b/pesign.spec @@ -0,0 +1,136 @@ +%global macrosdir %(d=%{_rpmconfigdir}/macros.d; [ -d $d ] || d=%{_sysconfdir}/rpm; echo $d) +Name: pesign +Summary: Signing utility for UEFI binaries +Version: 0.112 +Release: 28 +License: GPLv2 +URL: https://github.com/vathpela/pesign +Source0: pesign-%{version}.tar.bz2 +Source1: certs.tar.xz +Source2: pesign.py +Source3: euleros-certs.tar.bz2 +Obsoletes: pesign-rh-test-certs <= 0.111-7 +Requires: nspr nss nss-util popt rpm +Requires(pre): shadow-utils +BuildRequires: nspr nss nss-util popt-devel nss-tools nspr-devel >= 4.9.2-1 +BuildRequires: nss-devel >= 3.13.6-1 efivar-devel >= 31-1 libuuid-devel tar xz +BuildRequires: python3-rpm-macros python3 systemd + +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 + +%description +pesign is a command line tool for manipulating signatures and +cryptographic digests of UEFI applications. + +%package help +Summary: This package contains help documents +Requires: %{name} = %{version}-%{release} + +%description help +Files for help with pesign. + +%prep +%autosetup -n %{name}-%{version} -p1 -T -b 0 -D -c -a 1 +tar -jxf %{SOURCE3} + +%build +make PREFIX=%{_prefix} LIBDIR=%{_libdir} + +%install +mkdir -p %{buildroot}/%{_libdir} +make PREFIX=%{_prefix} LIBDIR=%{_libdir} INSTALLROOT=%{buildroot} install +make PREFIX=%{_prefix} LIBDIR=%{_libdir} INSTALLROOT=%{buildroot} install_systemd +install -D etc/pki/pesign/* %{buildroot}%{_sysconfdir}/pki/pesign/ +install -D etc/pki/pesign-rh-test/* %{buildroot}%{_sysconfdir}/pki/pesign-rh-test/ +mv euleros-certs/etc/pki/pesign/euleros-pesign-db %{buildroot}/etc/pki/pesign/ +install -D %{buildroot}%{_sysconfdir}/rpm/macros.pesign %{buildroot}%{macrosdir}/macros.pesign +rm -vf %{buildroot}/usr/share/doc/pesign-%{version}/COPYING +install -d -m 0755 %{buildroot}%{python3_sitelib}/mockbuild/plugins/ +install -m 0755 %{SOURCE2} %{buildroot}%{python3_sitelib}/mockbuild/plugins/ + +%pre +getent group pesign >/dev/null || groupadd -r pesign +getent passwd pesign >/dev/null || \ + useradd -r -g pesign -d /var/run/pesign -s /sbin/nologin \ + -c "Group for the pesign signing daemon" pesign +exit 0 + +%post +%systemd_post pesign.service + +%preun +%systemd_preun pesign.service + +%postun +%systemd_postun_with_restart pesign.service + +%files +%doc COPYING +%{_bindir}/* +%dir %{_libexecdir}/pesign/ +%dir %attr(0770,pesign,pesign) %{_sysconfdir}/pki/pesign/ +%config(noreplace) %attr(0660,pesign,pesign) %{_sysconfdir}/pki/pesign/* +%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 +%config(noreplace)/%{_sysconfdir}/pesign/* +%{_sysconfdir}/popt.d/pesign.popt +%{macrosdir}/macros.pesign +%dir %attr(0770, pesign, pesign) %{_localstatedir}/run/%{name} +%dir %attr(0775,pesign,pesign) /etc/pki/pesign/euleros-pesign-db +%attr(0644,pesign,pesign) /etc/pki/pesign/euleros-pesign-db/* +%ghost %attr(0660, -, -) %{_localstatedir}/run/%{name}/socket +%ghost %attr(0660, -, -) %{_localstatedir}/run/%{name}/pesign.pid +%{_tmpfilesdir}/pesign.conf +%{_unitdir}/pesign.service +%{python3_sitelib}/mockbuild/plugins/*/pesign.* +%{python3_sitelib}/mockbuild/plugins/pesign.* +%exclude /boot +%exclude /usr/include +%exclude %{_libdir}/libdpe* +%exclude %{_sysconfdir}/rpm + +%files help +%doc README TODO +%{_mandir}/man*/* + +%changelog +* Tue Dec 3 2019 gulining - 0.112-28 +- rewrite spec + +* Mon Dec 2 2019 openEuler Buildteam - 0.112.27 +- Type:bugfix +- Id:NA +- SUG:NA +- DESC:roll back to the 0.112-24 + +* Sat Nov 30 2019 gulining - 0.112-2 +- Pakcage init