diff --git a/0002-make-handle-some-gcc-Wanalyzer-flags-better.patch b/0002-make-handle-some-gcc-Wanalyzer-flags-better.patch new file mode 100644 index 0000000..5bee588 --- /dev/null +++ b/0002-make-handle-some-gcc-Wanalyzer-flags-better.patch @@ -0,0 +1,40 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Peter Jones +Date: Fri, 11 Mar 2022 12:45:28 -0500 +Subject: [PATCH] make: handle some gcc -Wanalyzer flags better + +This makes it so we won't use the -Wanalyzer / -fanalyzer flags by +default, because they're still pretty overzealous. + +Signed-off-by: Peter Jones +--- + Make.defaults | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/Make.defaults b/Make.defaults +index 130c1ee..1c18904 100644 +--- a/Make.defaults ++++ b/Make.defaults +@@ -32,11 +32,11 @@ CCLD := $(if $(filter undefined,$(origin CCLD)),$(CC),$(CCLD)) + CFLAGS ?= -O2 -g3 -pipe -fPIE -fstack-protector-all \ + -fstack-clash-protection \ + $(if $(filter x86_64 ia32,$(ARCH)),-fcf-protection=full,) +-DIAGFLAGS ?= -fmessage-length=0 \ ++DIAGFLAGS ?= $(call enabled,ENABLE_GCC_ANALYZER,-fmessage-length=0 \ + -fdiagnostics-color=always \ + -fdiagnostics-format=text \ + -fdiagnostics-show-cwe \ +- -fanalyzer \ ++ -fanalyzer) \ + $(call enabled,ENABLE_LEAK_CHECKER,-Wno-analyzer-malloc-leak,) + AS ?= $(CROSS_COMPILE)as + AR ?= $(CROSS_COMPILE)$(if $(filter $(CC),clang),llvm-ar,$(notdir $(CC))-ar) +@@ -59,7 +59,7 @@ endif + cflags = $(CFLAGS) $(ARCH3264) \ + -Wall -Wextra -Wsign-compare -Wno-unused-result \ + -Wno-unused-function -Wno-missing-field-initializers \ +- -Wno-analyzer-malloc-leak \ ++ $(call enabled,ENABLE_LEAK_CHECKER,-Wno-analyzer-malloc-leak,) \ + -Werror -Wno-error=cpp -Wno-free-nonheap-object \ + -std=gnu11 -fshort-wchar -fPIC -fno-strict-aliasing \ + -D_GNU_SOURCE -DCONFIG_$(ARCH) -I${TOPDIR}/include \ diff --git a/0003-Rename-dprintf-to-dbgprintf.patch b/0003-Rename-dprintf-to-dbgprintf.patch new file mode 100644 index 0000000..dac8401 --- /dev/null +++ b/0003-Rename-dprintf-to-dbgprintf.patch @@ -0,0 +1,664 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Peter Jones +Date: Fri, 11 Mar 2022 12:46:16 -0500 +Subject: [PATCH] Rename "dprintf' to "dbgprintf" + +stdio defines a dprintf() macro now, so using dprintf() for our debug +printer gets obnoxious warnings. This renames it to dbgprintf(). + +Signed-off-by: Peter Jones +--- + src/cms_common.c | 73 +++++++++++++++++++++++++++++------------------------ + src/cms_pe_common.c | 20 +++++++-------- + src/efikeygen.c | 16 ++++++------ + src/file_pe.c | 6 +++-- + src/password.c | 68 ++++++++++++++++++++++++------------------------- + src/pesign.c | 10 ++++---- + src/util.h | 26 +++++++++---------- + 7 files changed, 114 insertions(+), 105 deletions(-) + +diff --git a/src/cms_common.c b/src/cms_common.c +index ca37e6a..86341ca 100644 +--- a/src/cms_common.c ++++ b/src/cms_common.c +@@ -333,13 +333,13 @@ void cms_set_pw_data(cms_context *cms, secuPWData *pwdata) + + if (!pwdata) { + cms->pwdata.source = PW_SOURCE_INVALID; +- dprintf("pwdata:NULL"); ++ dbgprintf("pwdata:NULL"); + } else { + 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)"); ++ dbgprintf("pwdata:%p", pwdata); ++ dbgprintf("pwdata->source:%d", pwdata->source); ++ dbgprintf("pwdata->data:%p (\"%s\")", pwdata->data, ++ pwdata->data ? pwdata->data : "(null)"); + } + + egress(); +@@ -382,7 +382,7 @@ is_valid_cert(CERTCertificate *cert, void *data) + + errnum = PORT_GetError(); + if (errnum == SEC_ERROR_EXTENSION_NOT_FOUND) { +- dprintf("Got SEC_ERROR_EXTENSION_NOT_FOUND; clearing"); ++ dbgprintf("Got SEC_ERROR_EXTENSION_NOT_FOUND; clearing"); + PORT_SetError(0); + errnum = 0; + } +@@ -415,7 +415,7 @@ is_valid_cert_without_private_key(CERTCertificate *cert, void *data) + + errnum = PORT_GetError(); + if (errnum == SEC_ERROR_EXTENSION_NOT_FOUND) { +- dprintf("Got SEC_ERROR_EXTENSION_NOT_FOUND; clearing"); ++ dbgprintf("Got SEC_ERROR_EXTENSION_NOT_FOUND; clearing"); + PORT_SetError(0); + errnum = 0; + } +@@ -467,23 +467,23 @@ unescape_html_in_place(char *s) + size_t pos = 0; + char *s1; + +- dprintf("unescaping pos:%zd sz:%zd \"%s\"", pos, sz, s); ++ dbgprintf("unescaping pos:%zd sz:%zd \"%s\"", pos, sz, s); + do { + s1 = strchrnul(&s[pos], '%'); + if (s1[0] == '\0') + break; +- dprintf("s1 is \"%s\"", s1); ++ dbgprintf("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); ++ dbgprintf("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); ++ dbgprintf("new pos:%zd sz:%zd s:\"%s\"", pos, sz, s); + } + } while (pos < sz); + } +@@ -499,7 +499,7 @@ resolve_pkcs11_token_in_place(char *tokenname) + char c = *cp; + *cp = '\0'; + +- dprintf("ntn:\"%s\"", ntn); ++ dbgprintf("ntn:\"%s\"", ntn); + if (!strncmp(&ntn[pos], "token=", 6)) { + ntn += 6; + memmove(tokenname, ntn, cp - ntn + 1); +@@ -510,13 +510,13 @@ resolve_pkcs11_token_in_place(char *tokenname) + ntn = cp + (c ? 1 : 0); + } + unescape_html_in_place(tokenname); +- dprintf("token name is \"%s\"", tokenname); ++ dbgprintf("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"); \ ++ dbgprintf("provided token name is pkcs11 uri; parsing");\ + s_ = strdupa(tn+7); \ + resolve_pkcs11_token_in_place(s_); \ + } \ +@@ -528,7 +528,8 @@ 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"); ++ dbgprintf("setting password function to %s", ++ cms->func ? "cms->func" : "SECU_GetModulePassword"); + PK11_SetPasswordFunc(cms->func ? cms->func : SECU_GetModulePassword); + + PK11SlotList *slots = NULL; +@@ -592,7 +593,8 @@ find_certificate(cms_context *cms, int needs_private_key) + return -1; + } + +- dprintf("setting password function to %s", cms->func ? "cms->func" : "SECU_GetModulePassword"); ++ dbgprintf("setting password function to %s", ++ cms->func ? "cms->func" : "SECU_GetModulePassword"); + PK11_SetPasswordFunc(cms->func ? cms->func : SECU_GetModulePassword); + + PK11SlotList *slots = NULL; +@@ -610,10 +612,10 @@ find_certificate(cms_context *cms, int needs_private_key) + } + + while (psle) { +- dprintf("looking for token \"%s\", got \"%s\"", +- tokenname, PK11_GetTokenName(psle->slot)); ++ dbgprintf("looking for token \"%s\", got \"%s\"", ++ tokenname, PK11_GetTokenName(psle->slot)); + if (!strcmp(tokenname, PK11_GetTokenName(psle->slot))) { +- dprintf("found token \"%s\"", tokenname); ++ dbgprintf("found token \"%s\"", tokenname); + break; + } + +@@ -673,8 +675,9 @@ find_certificate(cms_context *cms, int needs_private_key) + psle->slot, is_valid_cert, &cbd); + errnum = PORT_GetError(); + if (errnum) +- dprintf("PK11_TraverseCertsForNicknameInSlot():%s:%s", +- PORT_ErrorToName(errnum), PORT_ErrorToString(errnum)); ++ dbgprintf("PK11_TraverseCertsForNicknameInSlot():%s:%s", ++ PORT_ErrorToName(errnum), ++ PORT_ErrorToString(errnum)); + } else { + status = PK11_TraverseCertsForNicknameInSlot(&nickname, + psle->slot, +@@ -682,28 +685,30 @@ find_certificate(cms_context *cms, int needs_private_key) + &cbd); + errnum = PORT_GetError(); + if (errnum) +- dprintf("PK11_TraverseCertsForNicknameInSlot():%s:%s", +- PORT_ErrorToName(errnum), PORT_ErrorToString(errnum)); ++ dbgprintf("PK11_TraverseCertsForNicknameInSlot():%s:%s", ++ PORT_ErrorToName(errnum), ++ PORT_ErrorToString(errnum)); + } +- dprintf("status:%d cbd.cert:%p", status, cbd.cert); ++ dbgprintf("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)); ++ dbgprintf("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"); ++ dbgprintf("Destroying cert list"); + CERT_DestroyCertList(certlist); +- dprintf("Destroying slot list element"); ++ dbgprintf("Destroying slot list element"); + PK11_DestroySlotListElement(slots, &psle); +- dprintf("Destroying slot list"); ++ dbgprintf("Destroying slot list"); + PK11_FreeSlotList(slots); + cms->psle = NULL; + } +@@ -723,7 +728,8 @@ find_slot_for_token(cms_context *cms, PK11SlotInfo **slot) + + char *tokenname = resolve_token_name(cms->tokenname); + +- dprintf("setting password function to %s", cms->func ? "cms->func" : "SECU_GetModulePassword"); ++ dbgprintf("setting password function to %s", ++ cms->func ? "cms->func" : "SECU_GetModulePassword"); + PK11_SetPasswordFunc(cms->func ? cms->func : SECU_GetModulePassword); + + PK11SlotList *slots = NULL; +@@ -792,7 +798,8 @@ find_certificate_by_callback(cms_context *cms, + return -1; + } + +- dprintf("setting password function to %s", cms->func ? "cms->func" : "SECU_GetModulePassword"); ++ dbgprintf("setting password function to %s", ++ cms->func ? "cms->func" : "SECU_GetModulePassword"); + PK11_SetPasswordFunc(cms->func ? cms->func : SECU_GetModulePassword); + + PK11SlotList *slots = NULL; +diff --git a/src/cms_pe_common.c b/src/cms_pe_common.c +index 3a3921b..fb90ecb 100644 +--- a/src/cms_pe_common.c ++++ b/src/cms_pe_common.c +@@ -188,8 +188,8 @@ generate_digest(cms_context *cms, Pe *pe, int padded) + } + if (!check_pointer_and_size(cms, pe, hash_base, hash_size)) + cmsgotoerr(error, cms, "PE header is invalid"); +- dprintf("beginning of hash"); +- dprintf("digesting %tx + %zx", hash_base - map, hash_size); ++ dbgprintf("beginning of hash"); ++ dbgprintf("digesting %tx + %zx", hash_base - map, hash_size); + generate_digest_step(cms, hash_base, hash_size); + + /* 5. Skip over the image checksum +@@ -209,7 +209,7 @@ generate_digest(cms_context *cms, Pe *pe, int padded) + cmsgotoerr(error, cms, "PE data directory is invalid"); + + generate_digest_step(cms, hash_base, hash_size); +- dprintf("digesting %tx + %zx", hash_base - map, hash_size); ++ dbgprintf("digesting %tx + %zx", hash_base - map, hash_size); + + /* 8. Skip over the crt dir + * 9. Hash everything up to the end of the image header. */ +@@ -222,7 +222,7 @@ generate_digest(cms_context *cms, Pe *pe, int padded) + cmsgotoerr(error, cms, "PE relocations table is invalid"); + + generate_digest_step(cms, hash_base, hash_size); +- dprintf("digesting %tx + %zx", hash_base - map, hash_size); ++ dbgprintf("digesting %tx + %zx", hash_base - map, hash_size); + + /* 10. Set SUM_OF_BYTES_HASHED to the size of the header. */ + hashed_bytes = pe32opthdr ? pe32opthdr->header_size +@@ -256,16 +256,16 @@ generate_digest(cms_context *cms, Pe *pe, int padded) + char *name = shdrs[i].name; + if (name && name[0] == '/') + name = get_str(cms, pe, name + 1); +- dprintf("section:\"%s\"", name ? name : "(null)"); ++ dbgprintf("section:\"%s\"", name ? name : "(null)"); + if (name && !strcmp(name, ".vendor_cert")) { +- dprintf("skipping .vendor_cert section"); ++ dbgprintf("skipping .vendor_cert section"); + hashed_bytes += hash_size; + continue; + } + } + + generate_digest_step(cms, hash_base, hash_size); +- dprintf("digesting %tx + %zx", hash_base - map, hash_size); ++ dbgprintf("digesting %tx + %zx", hash_base - map, hash_size); + + hashed_bytes += hash_size; + } +@@ -285,15 +285,15 @@ 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 %tx + %zx", (ptrdiff_t)tmp_array, ++ dbgprintf("digesting %tx + %zx", (ptrdiff_t)tmp_array, + tmp_size); + } else { + generate_digest_step(cms, hash_base, hash_size); +- dprintf("digesting %tx + %zx", hash_base - map, ++ dbgprintf("digesting %tx + %zx", hash_base - map, + hash_size); + } + } +- dprintf("end of hash"); ++ dbgprintf("end of hash"); + + rc = generate_digest_finish(cms); + if (rc < 0) +diff --git a/src/efikeygen.c b/src/efikeygen.c +index 940fdf5..dd40502 100644 +--- a/src/efikeygen.c ++++ b/src/efikeygen.c +@@ -1067,9 +1067,9 @@ int main(int argc, char *argv[]) + + errno = 0; + timeul = strtoul(not_valid_before, &endptr, 0); +- dprintf("not_valid_before:%lu", timeul); ++ dbgprintf("not_valid_before:%lu", timeul); + if (errno == 0 && endptr && *endptr == 0) { +- dprintf("not_valid_before:%lu", timeul); ++ dbgprintf("not_valid_before:%lu", timeul); + not_before = (PRTime)timeul * PR_USEC_PER_SEC; + } else { + prstatus = PR_ParseTimeString(not_valid_before, +@@ -1078,7 +1078,7 @@ int main(int argc, char *argv[]) + "could not parse date \"%s\"", + not_valid_before); + } +- dprintf("not_before:%"PRId64, not_before); ++ dbgprintf("not_before:%"PRId64, not_before); + } + + if (not_valid_after) { +@@ -1086,11 +1086,11 @@ int main(int argc, char *argv[]) + char *endptr; + + errno = 0; +- dprintf("not_valid_after:%s", not_valid_after); ++ dbgprintf("not_valid_after:%s", not_valid_after); + timeul = strtoul(not_valid_after, &endptr, 0); +- dprintf("not_valid_after:%lu", timeul); ++ dbgprintf("not_valid_after:%lu", timeul); + if (errno == 0 && endptr && *endptr == 0) { +- dprintf("not_valid_after:%lu", timeul); ++ dbgprintf("not_valid_after:%lu", timeul); + not_after = (PRTime)timeul * PR_USEC_PER_SEC; + } else { + prstatus = PR_ParseTimeString(not_valid_after, PR_TRUE, +@@ -1102,10 +1102,10 @@ int main(int argc, char *argv[]) + } else { + // Mon Jan 19 03:14:07 GMT 2037, aka 0x7fffffff minus 1 year. + time_t time = 0x7ffffffful - 60ul * 60 * 24 * 365; +- dprintf("not_valid_after:%lu", time); ++ dbgprintf("not_valid_after:%lu", time); + not_after = (PRTime)time * PR_USEC_PER_SEC; + } +- dprintf("not_after:%"PRId64, not_after); ++ dbgprintf("not_after:%"PRId64, not_after); + + CERTValidity *validity = NULL; + validity = CERT_CreateValidity(not_before, not_after); +diff --git a/src/file_pe.c b/src/file_pe.c +index fa97b89..fed6edb 100644 +--- a/src/file_pe.c ++++ b/src/file_pe.c +@@ -264,7 +264,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: + perr = PORT_GetError(); +- dprintf("PORT_GetError():%s:%s", PORT_ErrorToName(perr), PORT_ErrorToString(perr)); ++ dbgprintf("PORT_GetError():%s:%s", ++ PORT_ErrorToName(perr), PORT_ErrorToString(perr)); + PORT_SetError(0); + rc = find_certificate(ctxp->cms_ctx, 1); + conderrx(rc < 0, 1, "Could not find certificate %s", +@@ -281,7 +282,8 @@ pe_handle_action(pesign_context *ctxp, int action, int padding) + case IMPORT_SIGNATURE|GENERATE_SIGNATURE: + check_inputs(ctxp); + perr = PORT_GetError(); +- dprintf("PORT_GetError():%s:%s", PORT_ErrorToName(perr), PORT_ErrorToString(perr)); ++ dbgprintf("PORT_GetError():%s:%s", ++ PORT_ErrorToName(perr), PORT_ErrorToString(perr)); + 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 05add9a..18c32ed 100644 +--- a/src/password.c ++++ b/src/password.c +@@ -167,7 +167,7 @@ SECU_GetPasswordString(void *arg UNUSED, char *prompt) + char *ret; + ingress(); + ret = get_password(stdin, stdout, prompt, NULL); +- dprintf("password:\"%s\"", ret ? ret : "(null)"); ++ dbgprintf("password:\"%s\"", ret ? ret : "(null)"); + egress(); + return ret; + } +@@ -194,7 +194,7 @@ parse_pwfile_line(char *start, struct token_pass *tp) + size_t offset = 0; + + span = strspn(line, whitespace_and_eol_chars); +- dprintf("whitespace span is %zd", span); ++ dbgprintf("whitespace span is %zd", span); + if (span == 0 && line[span] == '\0') + return -1; + line += span; +@@ -210,17 +210,17 @@ parse_pwfile_line(char *start, struct token_pass *tp) + offset += escspan + 2; + } while(escspan < span); + span += offset; +- dprintf("non-whitespace span is %zd", span); ++ dbgprintf("non-whitespace span is %zd", span); + + if (line[span] == '\0') { +- dprintf("returning %td", (line + span) - start); ++ dbgprintf("returning %td", (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); ++ dbgprintf("whitespace span is %zd", span); + line += span; + tp->token = tp->pass; + tp->pass = line; +@@ -233,15 +233,15 @@ parse_pwfile_line(char *start, struct token_pass *tp) + offset += escspan + 2; + } while(escspan < span); + span += offset; +- dprintf("non-whitespace span is %zd", span); ++ dbgprintf("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 %td", (line + span) - start); ++ dbgprintf("Setting token pass %p to { %p, %p }", tp, tp->token, tp->pass); ++ dbgprintf("token:\"%s\"", tp->token); ++ dbgprintf("pass:\"%s\"", tp->pass); ++ dbgprintf("returning %td", (line + span) - start); + return (line + span) - start; + } + +@@ -260,7 +260,7 @@ SECU_FilePasswd(PK11SlotInfo *slot, PRBool retry, void *arg) + char *path; + + ingress(); +- dprintf("token_name: %s", token_name); ++ dbgprintf("token_name: %s", token_name); + if (cms->pwdata.source != PW_FROMFILEDB) { + cms->log(cms, LOG_ERR, + "Got to %s() but no file is specified.\n", +@@ -289,8 +289,8 @@ SECU_FilePasswd(PK11SlotInfo *slot, PRBool retry, void *arg) + if (rc < 0 || file_len < 1) + goto err_file; + file[file_len-1] = '\0'; +- dprintf("file_len:%zd", file_len); +- dprintf("file:\"%s\"", file); ++ dbgprintf("file_len:%zd", file_len); ++ dbgprintf("file:\"%s\"", file); + + unbreak_line_continuations(file, file_len); + } +@@ -314,23 +314,23 @@ SECU_FilePasswd(PK11SlotInfo *slot, PRBool retry, void *arg) + #pragma GCC diagnostic pop + + span = strspn(start, whitespace_and_eol_chars); +- dprintf("whitespace span is %zd", span); ++ dbgprintf("whitespace span is %zd", span); + start += span; + span = strcspn(start, eol_chars); +- dprintf("non-whitespace span is %zd", span); ++ dbgprintf("non-whitespace span is %zd", span); + + c = start[span]; + start[span] = '\0'; +- dprintf("file:\"%s\"", file); ++ dbgprintf("file:\"%s\"", file); + rc = parse_pwfile_line(start, &phrases[nphrases++]); +- dprintf("parse_pwfile_line returned %d", rc); ++ dbgprintf("parse_pwfile_line returned %d", rc); + if (rc < 0) + goto err_phrases; + + if (c != '\0') + span++; + start += span; +- dprintf("start is file[%td] == '\\x%02hhx'", start - file, ++ dbgprintf("start is file[%td] == '\\x%02hhx'", start - file, + start[0]); + } + +@@ -359,7 +359,7 @@ err_file: + err_phrases: + xfree(phrases); + err: +- dprintf("ret:\"%s\"", ret ? ret : "(null)"); ++ dbgprintf("ret:\"%s\"", ret ? ret : "(null)"); + egress(); + return ret; + } +@@ -412,10 +412,10 @@ SECU_GetModulePassword(PK11SlotInfo *slot, PRBool retry, void *arg) + ingress(); + + if (PK11_ProtectedAuthenticationPath(slot)) { +- dprintf("prompting for PW_DEVICE data"); ++ dbgprintf("prompting for PW_DEVICE data"); + pwdata = &pwxtrn; + } else { +- dprintf("using pwdata from cms"); ++ dbgprintf("using pwdata from cms"); + pwdata = &cms->pwdata; + } + +@@ -423,17 +423,17 @@ SECU_GetModulePassword(PK11SlotInfo *slot, PRBool retry, void *arg) + pwdata->source >= PW_SOURCE_MAX || + pwdata->orig_source <= PW_SOURCE_INVALID || + pwdata->orig_source >= PW_SOURCE_MAX) { +- dprintf("pwdata is invalid"); ++ dbgprintf("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)"); +- dprintf("pwdata->intdata:%ld", pwdata->intdata); ++ dbgprintf("pwdata:%p retry:%d", pwdata, retry); ++ dbgprintf("pwdata->source:%s (%d) orig:%s (%d)", ++ pw_source_names[pwdata->source], pwdata->source, ++ pw_source_names[pwdata->orig_source], pwdata->orig_source); ++ dbgprintf("pwdata->data:%p (\"%s\")", pwdata->data, ++ pwdata->data ? pwdata->data : "(null)"); ++ dbgprintf("pwdata->intdata:%ld", pwdata->intdata); + + if (retry) { + warnx("Incorrect password/PIN entered."); +@@ -470,7 +470,7 @@ SECU_GetModulePassword(PK11SlotInfo *slot, PRBool retry, void *arg) + + case PW_FROMFILEDB: + case PW_DATABASE: +- dprintf("pwdata->source:%s", pw_source_names[pwdata->source]); ++ dbgprintf("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). + */ +@@ -480,17 +480,17 @@ SECU_GetModulePassword(PK11SlotInfo *slot, PRBool retry, void *arg) + return pw; + + case PW_FROMENV: +- dprintf("pwdata->source:PW_FROMENV"); ++ dbgprintf("pwdata->source:PW_FROMENV"); + if (!pwdata || !pwdata->data) + break; + pw = get_env(pwdata->data); +- dprintf("env:%s pw:%s", pwdata->data, pw ? pw : "(null)"); ++ dbgprintf("env:%s pw:%s", pwdata->data, pw ? pw : "(null)"); + pwdata->data = pw; + pwdata->source = PW_PLAINTEXT; + goto PW_PLAINTEXT; + + case PW_FROMFILE: +- dprintf("pwdata->source:PW_FROMFILE"); ++ dbgprintf("pwdata->source:PW_FROMFILE"); + in = fopen(pwdata->data, "r"); + if (!in) + return NULL; +@@ -501,7 +501,7 @@ SECU_GetModulePassword(PK11SlotInfo *slot, PRBool retry, void *arg) + goto PW_PLAINTEXT; + + case PW_FROMFD: +- dprintf("pwdata->source:PW_FROMFD"); ++ dbgprintf("pwdata->source:PW_FROMFD"); + rc = pwdata->intdata; + in = fdopen(pwdata->intdata, "r"); + if (!in) +diff --git a/src/pesign.c b/src/pesign.c +index c2ff35f..f548d81 100644 +--- a/src/pesign.c ++++ b/src/pesign.c +@@ -333,7 +333,7 @@ main(int argc, char *argv[]) + while ((rc = poptGetNextOpt(optCon)) > 0) { + switch (rc) { + case POPT_RET_PWDB: +- dprintf("POPT_RET_PWDB:\"%s\"", pwdata.data ? pwdata.data : "(null)"); ++ dbgprintf("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) +@@ -346,7 +346,7 @@ main(int argc, char *argv[]) + continue; + + case POPT_RET_ENV: +- dprintf("POPT_RET_ENV:\"%s\"", pwdata.data ? pwdata.data : "(null)"); ++ dbgprintf("POPT_RET_ENV:\"%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) +@@ -359,7 +359,7 @@ main(int argc, char *argv[]) + continue; + + case POPT_RET_PINFD: +- dprintf("POPT_RET_PINFD:\"%s\"", pwdata.data ? pwdata.data : "(null)"); ++ dbgprintf("POPT_RET_PINFD:\"%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) +@@ -373,7 +373,7 @@ main(int argc, char *argv[]) + continue; + + case POPT_RET_PINFILE: +- dprintf("POPT_RET_PINFILE:\"%s\"", pwdata.data ? pwdata.data : "(null)"); ++ dbgprintf("POPT_RET_PINFILE:\"%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) +@@ -387,7 +387,7 @@ main(int argc, char *argv[]) + } + } + +- dprintf("pwdata.source:%d %schecking for PESIGN_TOKEN_PIN", ++ dbgprintf("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")) { +diff --git a/src/util.h b/src/util.h +index ba8c621..6616011 100644 +--- a/src/util.h ++++ b/src/util.h +@@ -269,28 +269,28 @@ 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 dbgprintf_(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__ - 2, fmt, ##args) ++#define dbgprintf(fmt, args...) \ ++ dbgprintf_(CAT(CAT(CAT(tv_,__COUNTER__),__LINE__),_), \ ++ __FILE__, __func__, __LINE__ - 2, fmt, ##args) + #else +-#define dprintf(fmt, args...) ({ \ ++#define dbgprintf(fmt, args...) ({ \ + if (verbosity() > 1) \ +- dprintf_(CAT(CAT(CAT(tv_,__COUNTER__),__LINE__),_), \ ++ dbgprintf_(CAT(CAT(CAT(tv_,__COUNTER__),__LINE__),_), \ + __FILE__, __func__, __LINE__ - 3, \ + fmt, ##args); \ + 0; \ + }) + #endif +-#define ingress() dprintf("ingress"); +-#define egress() dprintf("egress"); ++#define ingress() dbgprintf("ingress"); ++#define egress() dbgprintf("egress"); + + #endif /* PESIGN_UTIL_H */ + // vim:fenc=utf-8:tw=75:noet diff --git a/0004-.gitignore-add-compile_commands.json-and-.cache.patch b/0004-.gitignore-add-compile_commands.json-and-.cache.patch new file mode 100644 index 0000000..fb7e7a4 --- /dev/null +++ b/0004-.gitignore-add-compile_commands.json-and-.cache.patch @@ -0,0 +1,30 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Peter Jones +Date: Fri, 11 Mar 2022 12:47:20 -0500 +Subject: [PATCH] .gitignore: add compile_commands.json and .cache/ + +These are used by bear/cnc/clangd/etc, but there's no reason to trip +over them all the time. + +Signed-off-by: Peter Jones +--- + .gitignore | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/.gitignore b/.gitignore +index bf0617b..7425432 100644 +--- a/.gitignore ++++ b/.gitignore +@@ -1,3 +1,4 @@ ++.cache/ + .*.d + .*.P + .*.sw? +@@ -26,6 +27,7 @@ + /*.rpm + *-8be4df61-93ca-11d2-aa0d-00e098032b8c + *-d719b2cb-3d3a-4596-a3bc-dad00e67656f ++compile_commands.json + core.* + cov-int/ + pwfile diff --git a/0005-pesign-print-digests-before-filenames-like-sha256sum.patch b/0005-pesign-print-digests-before-filenames-like-sha256sum.patch new file mode 100644 index 0000000..dbce340 --- /dev/null +++ b/0005-pesign-print-digests-before-filenames-like-sha256sum.patch @@ -0,0 +1,31 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Peter Jones +Date: Fri, 11 Mar 2022 12:44:46 -0500 +Subject: [PATCH] pesign: print digests before filenames like sha256sum does + +Most digest tools print the digest before the filename, there's no +reason pesign needs to be different. + +Signed-off-by: Peter Jones +--- + src/file_pe.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/src/file_pe.c b/src/file_pe.c +index fed6edb..805e614 100644 +--- a/src/file_pe.c ++++ b/src/file_pe.c +@@ -121,12 +121,11 @@ print_digest(pesign_context *pctx) + if (!ctx) + return; + +- printf("%s ", pctx->infile); + int j = ctx->selected_digest; + for (unsigned int i = 0; i < ctx->digests[j].pe_digest->len; i++) + printf("%02x", + (unsigned char)ctx->digests[j].pe_digest->data[i]); +- printf("\n"); ++ printf(" %s\n", pctx->infile); + } + + void diff --git a/0006-Add-pesum-an-authenticode-digest-generator.patch b/0006-Add-pesum-an-authenticode-digest-generator.patch new file mode 100644 index 0000000..10d6fb4 --- /dev/null +++ b/0006-Add-pesum-an-authenticode-digest-generator.patch @@ -0,0 +1,318 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Peter Jones +Date: Fri, 11 Mar 2022 12:54:39 -0500 +Subject: [PATCH] Add 'pesum', an authenticode digest generator. + +Signed-off-by: Peter Jones +--- + src/pesum.c | 195 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ + src/.gitignore | 1 + + src/Makefile | 12 +++- + src/pesum.1.mdoc | 38 +++++++++++ + 4 files changed, 244 insertions(+), 2 deletions(-) + create mode 100644 src/pesum.c + create mode 100644 src/pesum.1.mdoc + +diff --git a/src/pesum.c b/src/pesum.c +new file mode 100644 +index 0000000..e4ddaf8 +--- /dev/null ++++ b/src/pesum.c +@@ -0,0 +1,195 @@ ++// SPDX-License-Identifier: GPLv2 ++/* ++ * pesum.c - pesum command line tool ++ * Copyright Peter Jones ++ */ ++ ++#include "fix_coverity.h" ++ ++#include ++#include ++ ++#include ++#include ++ ++#include "pesign.h" ++#include "pesign_standalone.h" ++ ++static struct { ++ int flag; ++ const char *name; ++} flag_names[] = { ++ {DAEMONIZE, "daemonize"}, ++ {GENERATE_DIGEST, "hash"}, ++ {GENERATE_SIGNATURE, "sign"}, ++ {IMPORT_RAW_SIGNATURE, "import-raw-sig"}, ++ {IMPORT_SIGNATURE, "import-sig"}, ++ {IMPORT_SATTRS, "import-sattrs" }, ++ {EXPORT_SATTRS, "export-sattrs" }, ++ {EXPORT_SIGNATURE, "export-sig"}, ++ {EXPORT_PUBKEY, "export-pubkey"}, ++ {EXPORT_CERT, "export-cert"}, ++ {REMOVE_SIGNATURE, "remove"}, ++ {LIST_SIGNATURES, "list"}, ++ {FLAG_LIST_END, NULL}, ++}; ++ ++void ++print_flag_name(FILE *f, int flag) ++{ ++ for (int i = 0; flag_names[i].flag != FLAG_LIST_END; i++) { ++ if (flag_names[i].flag == flag) ++ fprintf(f, "%s ", flag_names[i].name); ++ } ++} ++ ++static long *verbose; ++ ++long ++verbosity(void) ++{ ++ if (!verbose) ++ return 0; ++ return *verbose; ++} ++ ++int ++main(int argc, char *argv[]) ++{ ++ int rc; ++ SECStatus status; ++ ++ char *digest_name = "sha256"; ++ char *orig_digest_name = digest_name; ++ int padding = 1; ++ long verbose_cmd_line = 0; ++ const char *infile; ++ ++ int action = GENERATE_DIGEST|PRINT_DIGEST; ++ file_format fmt = FORMAT_PE_BINARY; ++ ++ setenv("NSS_DEFAULT_DB_TYPE", "sql", 0); ++ ++ verbose = &verbose_cmd_line; ++ ++ poptContext optCon; ++ struct poptOption options[] = { ++ {.argInfo = POPT_ARG_INTL_DOMAIN, ++ .arg = "pesum" }, ++ {.longName = "verbose", ++ .shortName = 'v', ++ .argInfo = POPT_ARG_VAL|POPT_ARG_LONG|POPT_ARGFLAG_OPTIONAL, ++ .arg = &verbose_cmd_line, ++ .val = 1, ++ .descrip = "be more verbose" }, ++ {.longName = "debug", ++ .shortName = '\0', ++ .argInfo = POPT_ARG_VAL|POPT_ARG_LONG|POPT_ARGFLAG_OPTIONAL, ++ .arg = &verbose_cmd_line, ++ .val = 2, ++ .descrip = "be very verbose" }, ++ {.longName = "digest-type", ++ .shortName = 'd', ++ .argInfo = POPT_ARG_STRING|POPT_ARGFLAG_SHOW_DEFAULT, ++ .arg = &digest_name, ++ .descrip = "digest type to use for pe hash" }, ++ {.longName = "digest_type", ++ .shortName = '\0', ++ .argInfo = POPT_ARG_STRING|POPT_ARGFLAG_DOC_HIDDEN, ++ .arg = &digest_name, ++ .descrip = "digest type to use for pe hash" }, ++ {.longName = "padding", ++ .shortName = 'P', ++ .argInfo = POPT_ARG_VAL, ++ .arg = &padding, ++ .val = 1, ++ .descrip = "pad data section (default)" }, ++ {.longName = "nopadding", ++ .shortName = 'p', ++ .argInfo = POPT_ARG_VAL, ++ .arg = &padding, ++ .val = 0, ++ .descrip = "do not pad the data section" }, ++ POPT_AUTOALIAS ++ POPT_AUTOHELP ++ POPT_TABLEEND ++ }; ++ ++ optCon = poptGetContext("pesum", argc, (const char **)argv, options,0); ++ ++ rc = poptReadDefaultConfig(optCon, 0); ++ if (rc < 0 && !(rc == POPT_ERROR_ERRNO && errno == ENOENT)) ++ errx(1, "poptReadDefaultConfig failed: %s", poptStrerror(rc)); ++ ++ while ((rc = poptGetNextOpt(optCon)) > 0) { ++ ; ++ } ++ ++ if (rc < -1) ++ errx(1, "Invalid argument: %s: %s", ++ poptBadOption(optCon, 0), poptStrerror(rc)); ++ ++ if (!poptPeekArg(optCon)) ++ errx(1, "nothing to do"); ++ ++ status = NSS_NoDB_Init(NULL); ++ if (status != SECSuccess) ++ errx(1, "Could not initialize nss.\n" ++ "NSS says \"%s\" errno says \"%m\"\n", ++ PORT_ErrorToString(PORT_GetError())); ++ ++ while ((infile = poptGetArg(optCon)) != NULL) { ++ pesign_context *ctxp = NULL; ++ ++ char *ext = strrchr(infile, '.'); ++ if (ext && strcmp(ext, ".ko") == 0) ++ fmt = FORMAT_KERNEL_MODULE; ++ ++ rc = pesign_context_new(&ctxp); ++ if (rc < 0) ++ err(1, "Could not initialize context"); ++ ++ ctxp->verbose = verbose_cmd_line; ++ ++ ctxp->hash = 1; ++ ctxp->infile = strdup(infile); ++ if (!ctxp->infile) ++ err(1, "Could not allocate memory"); ++ ++ rc = set_digest_parameters(ctxp->cms_ctx, digest_name); ++ int is_help = strcmp(digest_name, "help") ? 0 : 1; ++ if (rc < 0) { ++ if (!is_help) { ++ fprintf(stderr, "Digest \"%s\" not found.\n", ++ digest_name); ++ } ++ exit(!is_help); ++ } ++ ++ errno = 0; ++ switch (fmt) { ++ case FORMAT_PE_BINARY: ++ pe_handle_action(ctxp, action, padding); ++ break; ++ case FORMAT_KERNEL_MODULE: ++ kmod_handle_action(ctxp, action); ++ break; ++ } ++ ++ pesign_context_free(ctxp); ++ } ++ ++ poptFreeContext(optCon); ++ ++ if (digest_name && digest_name != orig_digest_name) ++ free(digest_name); ++ ++ status = NSS_Shutdown(); ++ if (status != SECSuccess) ++ errx(1, "could not shut down NSS: %s", ++ PORT_ErrorToString(PORT_GetError())); ++ ++ return 0; ++} ++ ++// vim:fenc=utf-8:tw=75:noet +diff --git a/src/.gitignore b/src/.gitignore +index 64ce217..f8f6d66 100644 +--- a/src/.gitignore ++++ b/src/.gitignore +@@ -5,6 +5,7 @@ client + efikeygen + efidbtool + pesigcheck ++pesum + peverify + pesign.service + pesign.sysvinit +diff --git a/src/Makefile b/src/Makefile +index 7010514..79cf09e 100644 +--- a/src/Makefile ++++ b/src/Makefile +@@ -6,7 +6,7 @@ include $(TOPDIR)/Make.rules + include $(TOPDIR)/Make.defaults + + BINTARGETS=authvar client efikeygen pesigcheck pesign \ +- pesign-rpmbuild-helper pesign-authorize ++ pesign-rpmbuild-helper pesign-authorize pesum + CFGTARGETS=tmpfiles.conf + SVCTARGETS=pesign.sysvinit pesign.service + MAN1TARGETS=authvar.1 efikeygen.1 pesigcheck.1 pesign-client.1 pesign.1 +@@ -29,9 +29,12 @@ EFIKEYGEN_SOURCES = efikeygen.c + PESIGCHECK_SOURCES = pesigcheck.c pesigcheck_context.c certdb.c + PESIGN_SOURCES = pesign.c pesign_context.c actions.c daemon.c \ + file_pe.c file_kmod.c pesign_kmod.c ++PESUM_SOURCES = pesum.c pesign_context.c actions.c \ ++ file_pe.c file_kmod.c pesign_kmod.c + + ALL_SOURCES=$(COMMON_SOURCES) $(AUTHVAR_SORUCES) $(CLIENT_SOURCES) \ +- $(EFIKEYGEN_SOURCES) $(PESIGCHECK_SOURCES) $(PESIGN_SOURCES) ++ $(EFIKEYGEN_SOURCES) $(PESIGCHECK_SOURCES) $(PESIGN_SOURCES) \ ++ $(PESUM_SOURCES) + -include $(call deps-of,$(ALL_SOURCES)) + + authvar : $(call objects-of,$(AUTHVAR_SOURCES) $(COMMON_SOURCES)) +@@ -53,6 +56,10 @@ pesign : $(call objects-of,$(PESIGN_SOURCES) $(COMMON_SOURCES) $(COMMON_PE_SOURC + pesign : LDLIBS+=$(TOPDIR)/libdpe/libdpe.a + pesign : PKGS=efivar nss nspr popt + ++pesum : $(call objects-of,$(PESUM_SOURCES) $(COMMON_SOURCES) $(COMMON_PE_SOURCES)) ++pesum : LDLIBS+=$(TOPDIR)/libdpe/libdpe.a ++pesum : PKGS=efivar nss nspr popt ++ + deps : PKGS=efivar nss nspr popt uuid + deps : $(ALL_SOURCES) + $(MAKE) -f $(TOPDIR)/Make.deps \ +@@ -81,6 +88,7 @@ install : + $(INSTALL) -d -m 755 $(INSTALLROOT)$(bindir) + $(INSTALL) -m 755 authvar $(INSTALLROOT)$(bindir) + $(INSTALL) -m 755 pesign $(INSTALLROOT)$(bindir) ++ $(INSTALL) -m 755 pesum $(INSTALLROOT)$(bindir) + $(INSTALL) -m 755 client $(INSTALLROOT)$(bindir)pesign-client + $(INSTALL) -m 755 efikeygen $(INSTALLROOT)$(bindir) + $(INSTALL) -m 755 pesigcheck $(INSTALLROOT)$(bindir) +diff --git a/src/pesum.1.mdoc b/src/pesum.1.mdoc +new file mode 100644 +index 0000000..edd08ce +--- /dev/null ++++ b/src/pesum.1.mdoc +@@ -0,0 +1,38 @@ ++.Dd $Mdocdate: Mar 11 2022$ ++.Dt PESUM 1 ++.Os Linux ++.Sh NAME ++.Nm pesum ++.Nd tool for generating Authenticode digests ++.Sh SYNOPSIS ++.Nm ++.Bk -words ++.Ar file0.efi ++.Op Ar file1.efi ... ++.Sh DESCRIPTION ++.Nm ++is a command line tool to generate Authenticode digests of PE binaries. ++.Sh EXAMPLES ++.Ss Getting the Authenticode digest of some files ++host:$ \fBpesum shimx64.efi grubx64.efi\fR ++8c5806e66bb5b052ebf860e1722474269cff3dde588610df21dbe8cf12c08390\ shimx64.efi ++546a71319c22da1d81879383c4c74be06d1c374bdecfafc9fcc80bd541802bfc\ grubx64.efi ++.Sh STANDARDS ++.Rs ++.%B Portable Executable ++.%I Microsoft ++.%D August 26, 2019 ++.%U https://docs.microsoft.com/en-us/windows/win32/debug/pe-format\ \& ++.Re ++ ++.Rs ++.%B Windows Authenticode Portable Executable Signature Format ++.%I Microsoft ++.%D March 21, 2008 ++.%U https://web.archive.org/web/20130518222430/http://download.microsoft.com/download/9/c/5/9c5b2167-8017-4bae-9fde-d599bac8184a/Authenticode_PE.docx\ \& ++.Re ++.Sh SEE ALSO ++.Xr pesign 1 ++.LP ++.Sh AUTHORS ++.An Peter Jones diff --git a/0002-Fix-building-signed-kernels-on-setups-other-than-koj.patch b/0007-Fix-building-signed-kernels-on-setups-other-than-koj.patch similarity index 97% rename from 0002-Fix-building-signed-kernels-on-setups-other-than-koj.patch rename to 0007-Fix-building-signed-kernels-on-setups-other-than-koj.patch index 920eb6a..b342876 100644 --- a/0002-Fix-building-signed-kernels-on-setups-other-than-koj.patch +++ b/0007-Fix-building-signed-kernels-on-setups-other-than-koj.patch @@ -8,7 +8,6 @@ https://bugzilla.redhat.com/show_bug.cgi?id=1880858 Signed-off-by: Julian Sikorski Suggested-by: Will Springer -(cherry picked from commit 9969b1757a1941c9f57081b308026d687f6c0943) --- src/pesign-rpmbuild-helper.in | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/0003-Add-D_GLIBCXX_ASSERTIONS-to-CPPFLAGS.patch b/0008-Add-D_GLIBCXX_ASSERTIONS-to-CPPFLAGS.patch similarity index 96% rename from 0003-Add-D_GLIBCXX_ASSERTIONS-to-CPPFLAGS.patch rename to 0008-Add-D_GLIBCXX_ASSERTIONS-to-CPPFLAGS.patch index 0dca694..187a623 100644 --- a/0003-Add-D_GLIBCXX_ASSERTIONS-to-CPPFLAGS.patch +++ b/0008-Add-D_GLIBCXX_ASSERTIONS-to-CPPFLAGS.patch @@ -9,7 +9,7 @@ Signed-off-by: Robbie Harwood 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Make.defaults b/Make.defaults -index 130c1ee..4b0e77c 100644 +index 1c18904..05aadd0 100644 --- a/Make.defaults +++ b/Make.defaults @@ -79,7 +79,7 @@ ccldflags = $(cflags) $(CCLDFLAGS) $(LDFLAGS) \ diff --git a/0004-macros.pesign-handle-centos-like-rhel-with-rhelver.patch b/0009-macros.pesign-handle-centos-like-rhel-with-rhelver.patch similarity index 93% rename from 0004-macros.pesign-handle-centos-like-rhel-with-rhelver.patch rename to 0009-macros.pesign-handle-centos-like-rhel-with-rhelver.patch index 62d1936..68cbe5f 100644 --- a/0004-macros.pesign-handle-centos-like-rhel-with-rhelver.patch +++ b/0009-macros.pesign-handle-centos-like-rhel-with-rhelver.patch @@ -4,7 +4,6 @@ Date: Tue, 10 Aug 2021 12:39:08 -0400 Subject: [PATCH] macros.pesign: handle centos like rhel with --rhelver Signed-off-by: Peter Jones -(cherry picked from commit a1bc65c8b0fc20dbe9c9714ee3a31937184ba7f6) --- src/macros.pesign | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/0005-Detect-the-presence-of-rpm-sign-when-checking-for-rh.patch b/0010-Detect-the-presence-of-rpm-sign-when-checking-for-rh.patch similarity index 93% rename from 0005-Detect-the-presence-of-rpm-sign-when-checking-for-rh.patch rename to 0010-Detect-the-presence-of-rpm-sign-when-checking-for-rh.patch index 0baddd6..bb4bef2 100644 --- a/0005-Detect-the-presence-of-rpm-sign-when-checking-for-rh.patch +++ b/0010-Detect-the-presence-of-rpm-sign-when-checking-for-rh.patch @@ -6,7 +6,6 @@ Subject: [PATCH] Detect the presence of rpm-sign when checking for "rhel"-ness Signed-off-by: Peter Jones [rharwood: manually reapply to main] Signed-off-by: Robbie Harwood -(cherry picked from commit 17e5878cb087e0a766722d3c487f87c41b318f9a) --- src/pesign-rpmbuild-helper.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/0011-Rename-README-README.md.patch b/0011-Rename-README-README.md.patch new file mode 100644 index 0000000..ff10b8d --- /dev/null +++ b/0011-Rename-README-README.md.patch @@ -0,0 +1,17 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Robbie Harwood +Date: Fri, 13 May 2022 15:53:05 -0400 +Subject: [PATCH] Rename README -> README.md + +Rich text will let me compact links. + +Signed-off-by: Robbie Harwood +--- + README => README.md | 0 + 1 file changed, 0 insertions(+), 0 deletions(-) + rename README => README.md (100%) + +diff --git a/README b/README.md +similarity index 100% +rename from README +rename to README.md diff --git a/0012-README.md-show-off-a-bit-more.patch b/0012-README.md-show-off-a-bit-more.patch new file mode 100644 index 0000000..9d624f2 --- /dev/null +++ b/0012-README.md-show-off-a-bit-more.patch @@ -0,0 +1,56 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Robbie Harwood +Date: Fri, 13 May 2022 16:09:12 -0400 +Subject: [PATCH] README.md: show off a bit more + +Prominently mention efikeygen and add examples of usage for it and +pesign proper. + +Signed-off-by: Robbie Harwood +--- + README.md | 36 ++++++++++++++++++++++++++++++++---- + 1 file changed, 32 insertions(+), 4 deletions(-) + +diff --git a/README.md b/README.md +index d70bc53..e9f0cb7 100644 +--- a/README.md ++++ b/README.md +@@ -1,6 +1,34 @@ +-Signing tool for PE-COFF binaries, hopefully at least vaguely compliant with +-the PE and Authenticode specifications. ++# pesign + efikeygen + +-This is vaguely analogous to the tool described by +-http://msdn.microsoft.com/en-us/library/8s9b9yaz%28v=vs.80%29.aspx ++Signing tools for PE-COFF binaries. Compliant with the PE and Authenticode ++specifications. + ++(These serve a similar purpose to Microsoft's ++[SignTool.exe](http://msdn.microsoft.com/en-us/library/8s9b9yaz%28v=vs.80%29.aspx), ++except for Linux.) ++ ++## Examples ++ ++Generate a key for use with pesign, stored on disk: ++ ++``` ++efikeyen -d /etc/pki/pesign -S -TYPE -c 'CN=Your Name Key' -n 'Custom Secureboot' ++``` ++ ++For more complex and secure use cases (e.g., hardware tokens), see ++efikeygen man page (`man efikeygen`). ++ ++Sign a UEFI application using that key: ++ ++``` ++pesign -i grubx64.efi -o grubx64.efi.signed -c 'Custom Secureboot' -s ++``` ++ ++Show signatures on a UEFI application: ++ ++``` ++pesign -i grubx64.efi.signed -S ++``` ++ ++For more signing/verification operations, see the pesign man page (`man ++pesign`). diff --git a/0013-Fix-missing-line-in-README.md.patch b/0013-Fix-missing-line-in-README.md.patch new file mode 100644 index 0000000..185bcc3 --- /dev/null +++ b/0013-Fix-missing-line-in-README.md.patch @@ -0,0 +1,23 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Robbie Harwood +Date: Mon, 16 May 2022 15:31:25 -0400 +Subject: [PATCH] Fix missing line in README.md + +Signed-off-by: Robbie Harwood +--- + README.md | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/README.md b/README.md +index e9f0cb7..7bbd6dd 100644 +--- a/README.md ++++ b/README.md +@@ -15,6 +15,8 @@ Generate a key for use with pesign, stored on disk: + efikeyen -d /etc/pki/pesign -S -TYPE -c 'CN=Your Name Key' -n 'Custom Secureboot' + ``` + ++(where TYPE is m if you're only signing kernel modules, and k otherwise). ++ + For more complex and secure use cases (e.g., hardware tokens), see + efikeygen man page (`man efikeygen`). + diff --git a/0014-Fix-typo-in-efikeygen-command.patch b/0014-Fix-typo-in-efikeygen-command.patch new file mode 100644 index 0000000..82d228d --- /dev/null +++ b/0014-Fix-typo-in-efikeygen-command.patch @@ -0,0 +1,23 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Matt Bernhard +Date: Fri, 27 May 2022 14:40:49 -0400 +Subject: [PATCH] Fix typo in efikeygen command + +Signed-off-by: Matt Bernhard +--- + README.md | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/README.md b/README.md +index 7bbd6dd..b6949a2 100644 +--- a/README.md ++++ b/README.md +@@ -12,7 +12,7 @@ except for Linux.) + Generate a key for use with pesign, stored on disk: + + ``` +-efikeyen -d /etc/pki/pesign -S -TYPE -c 'CN=Your Name Key' -n 'Custom Secureboot' ++efikeygen -d /etc/pki/pesign -S -TYPE -c 'CN=Your Name Key' -n 'Custom Secureboot' + ``` + + (where TYPE is m if you're only signing kernel modules, and k otherwise). diff --git a/0015-pesigcheck-Fix-crash-on-digest-match.patch b/0015-pesigcheck-Fix-crash-on-digest-match.patch new file mode 100644 index 0000000..c948558 --- /dev/null +++ b/0015-pesigcheck-Fix-crash-on-digest-match.patch @@ -0,0 +1,53 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Visa Hankala +Date: Fri, 10 Jun 2022 13:25:13 +0000 +Subject: [PATCH] pesigcheck: Fix crash on digest match + +Set selected_digest when the digest is found in db or dbx. +This fixes the following crash of pesigcheck: + + Program received signal SIGSEGV, Segmentation fault. + 0x00005555555597fa in memcpy (__len=24, __src=0x31, + __dest=0x55555558d908) + at /usr/include/x86_64-linux-gnu/bits/string_fortified.h:34 + 34 return __builtin___memcpy_chk (__dest, __src, __len, __bos0 (__dest)); + (gdb) bt + #0 0x00005555555597fa in memcpy (__len=24, __src=0x31, + __dest=0x55555558d908) + at /usr/include/x86_64-linux-gnu/bits/string_fortified.h:34 + #1 get_digest (digest=digest@entry=0x55555558d908, + ctx=, ctx=) at pesigcheck.c:226 + #2 0x00005555555592fd in check_signature ( + reasons=, nreasons=, + ctx=0x7fffffffded0) at pesigcheck.c:262 + #3 main (argc=, argv=) + at pesigcheck.c:512 + +Signed-off-by: Visa Hankala +--- + src/certdb.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +diff --git a/src/certdb.c b/src/certdb.c +index e013b9d..69d5daf 100644 +--- a/src/certdb.c ++++ b/src/certdb.c +@@ -267,12 +267,16 @@ check_hash(pesigcheck_context *ctx, SECItem *sig, efi_guid_t *sigtype, + + if (memcmp(sigtype, &efi_sha256, sizeof(efi_guid_t)) == 0) { + digest = ctx->cms_ctx->digests[0].pe_digest->data; +- if (memcmp (digest, sig->data, 32) == 0) ++ if (memcmp (digest, sig->data, 32) == 0) { ++ ctx->cms_ctx->selected_digest = 0; + return FOUND; ++ } + } else if (memcmp(sigtype, &efi_sha1, sizeof(efi_guid_t)) == 0) { + digest = ctx->cms_ctx->digests[1].pe_digest->data; +- if (memcmp (digest, sig->data, 20) == 0) ++ if (memcmp (digest, sig->data, 20) == 0) { ++ ctx->cms_ctx->selected_digest = 1; + return FOUND; ++ } + } + + return NOT_FOUND; diff --git a/0016-cms-store-digest-as-pointer-instead-of-index.patch b/0016-cms-store-digest-as-pointer-instead-of-index.patch new file mode 100644 index 0000000..a7fc4dd --- /dev/null +++ b/0016-cms-store-digest-as-pointer-instead-of-index.patch @@ -0,0 +1,272 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Robbie Harwood +Date: Fri, 10 Jun 2022 14:40:33 -0400 +Subject: [PATCH] cms: store digest as pointer instead of index + +Storage as an index is problematic because the sentinel value -1 was +used, but accesses were unchecked, leading to crashes like that in +3b1031a6b779cb80c11b34eec84c5a0cc215efed ("pesigcheck: Fix crash on +digest match"). By storing a pointer, we get an explicit NULL +dereference: still a crash, but preferred since it's clearer. + +Since the index was previously also used for retrieving digest +parameters, include a pointer to the relevant struct digest_param in the +struct digest. + +Signed-off-by: Robbie Harwood +--- + src/certdb.c | 15 ++++++++------- + src/cms_common.c | 34 ++++++++++------------------------ + src/content_info.c | 4 ++-- + src/file_kmod.c | 2 +- + src/file_pe.c | 9 +++++---- + src/pesigcheck.c | 4 +--- + src/cms_common.h | 13 ++++++++++++- + 7 files changed, 39 insertions(+), 42 deletions(-) + +diff --git a/src/certdb.c b/src/certdb.c +index 69d5daf..f512824 100644 +--- a/src/certdb.c ++++ b/src/certdb.c +@@ -263,18 +263,19 @@ check_hash(pesigcheck_context *ctx, SECItem *sig, efi_guid_t *sigtype, + { + efi_guid_t efi_sha256 = efi_guid_sha256; + efi_guid_t efi_sha1 = efi_guid_sha1; +- void *digest; ++ void *digest_data; ++ struct digest *digests = ctx->cms_ctx->digests; + + if (memcmp(sigtype, &efi_sha256, sizeof(efi_guid_t)) == 0) { +- digest = ctx->cms_ctx->digests[0].pe_digest->data; +- if (memcmp (digest, sig->data, 32) == 0) { +- ctx->cms_ctx->selected_digest = 0; ++ digest_data = digests[0].pe_digest->data; ++ if (memcmp (digest_data, sig->data, 32) == 0) { ++ ctx->cms_ctx->selected_digest = &digests[0]; + return FOUND; + } + } else if (memcmp(sigtype, &efi_sha1, sizeof(efi_guid_t)) == 0) { +- digest = ctx->cms_ctx->digests[1].pe_digest->data; +- if (memcmp (digest, sig->data, 20) == 0) { +- ctx->cms_ctx->selected_digest = 1; ++ digest_data = digests[1].pe_digest->data; ++ if (memcmp (digest_data, sig->data, 20) == 0) { ++ ctx->cms_ctx->selected_digest = &digests[1]; + return FOUND; + } + } +diff --git a/src/cms_common.c b/src/cms_common.c +index 86341ca..2275f67 100644 +--- a/src/cms_common.c ++++ b/src/cms_common.c +@@ -33,15 +33,6 @@ + + #include "hex.h" + +-struct digest_param { +- char *name; +- SECOidTag digest_tag; +- SECOidTag signature_tag; +- SECOidTag digest_encryption_tag; +- const efi_guid_t *efi_guid; +- int size; +-}; +- + static struct digest_param digest_params[] = { + {.name = "sha256", + .digest_tag = SEC_OID_SHA256, +@@ -65,29 +56,25 @@ static int n_digest_params = sizeof (digest_params) / sizeof (digest_params[0]); + SECOidTag + digest_get_digest_oid(cms_context *cms) + { +- int i = cms->selected_digest; +- return digest_params[i].digest_tag; ++ return cms->selected_digest->digest_params->digest_tag; + } + + SECOidTag + digest_get_encryption_oid(cms_context *cms) + { +- int i = cms->selected_digest; +- return digest_params[i].digest_encryption_tag; ++ return cms->selected_digest->digest_params->digest_encryption_tag; + } + + SECOidTag + digest_get_signature_oid(cms_context *cms) + { +- int i = cms->selected_digest; +- return digest_params[i].signature_tag; ++ return cms->selected_digest->digest_params->signature_tag; + } + + int + digest_get_digest_size(cms_context *cms) + { +- int i = cms->selected_digest; +- return digest_params[i].size; ++ return cms->selected_digest->digest_params->size; + } + + void +@@ -142,8 +129,6 @@ cms_context_init(cms_context *cms) + if (!cms->arena) + cnreterr(-1, cms, "could not create cryptographic arena"); + +- cms->selected_digest = -1; +- + INIT_LIST_HEAD(&cms->pk12_ins); + cms->pk12_out.fd = -1; + cms->db_out = cms->dbx_out = cms->dbt_out = -1; +@@ -226,7 +211,7 @@ cms_context_fini(cms_context *cms) + memset(&cms->newsig, '\0', sizeof (cms->newsig)); + } + +- cms->selected_digest = -1; ++ cms->selected_digest = NULL; + + if (cms->ci_digest) { + free_poison(cms->ci_digest->data, cms->ci_digest->len); +@@ -351,7 +336,7 @@ set_digest_parameters(cms_context *cms, char *name) + if (strcmp(name, "help")) { + for (int i = 0; i < n_digest_params; i++) { + if (!strcmp(name, digest_params[i].name)) { +- cms->selected_digest = i; ++ cms->selected_digest = &cms->digests[i]; + return 0; + } + } +@@ -1279,6 +1264,7 @@ generate_digest_begin(cms_context *cms) + cngotoerr(err, cms, "could not create digest context"); + + PK11_DigestBegin(digests[i].pk11ctx); ++ digests[i].digest_params = &digest_params[i]; + } + + cms->digests = digests; +@@ -1351,11 +1337,11 @@ generate_signature(cms_context *cms) + { + int rc = 0; + +- if (cms->digests[cms->selected_digest].pe_digest == NULL) ++ if (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)) ++ if (content_is_empty(cms->selected_digest->pe_digest->data, ++ cms->selected_digest->pe_digest->len)) + cnreterr(-1, cms, "PE binary has not been digested"); + + SECItem sd_der; +diff --git a/src/content_info.c b/src/content_info.c +index 9684850..777aa28 100644 +--- a/src/content_info.c ++++ b/src/content_info.c +@@ -181,8 +181,8 @@ generate_spc_digest_info(cms_context *cms, SECItem *dip) + if (generate_algorithm_id(cms, &di.digestAlgorithm, + digest_get_digest_oid(cms)) < 0) + return -1; +- int i = cms->selected_digest; +- memcpy(&di.digest, cms->digests[i].pe_digest, sizeof (di.digest)); ++ memcpy(&di.digest, cms->selected_digest->pe_digest, ++ sizeof(di.digest)); + + if (content_is_empty(di.digest.data, di.digest.len)) { + cms->log(cms, LOG_ERR, "got empty digest"); +diff --git a/src/file_kmod.c b/src/file_kmod.c +index 6880cda..c8875fc 100644 +--- a/src/file_kmod.c ++++ b/src/file_kmod.c +@@ -60,7 +60,7 @@ ssize_t + kmod_write_signature(cms_context *cms, int outfd) + { + SEC_PKCS7ContentInfo *cinfo; +- SECItem *digest = cms->digests[cms->selected_digest].pe_digest; ++ SECItem *digest = cms->selected_digest->pe_digest; + SECStatus rv; + struct write_sig_info info = { + .outfd = outfd, +diff --git a/src/file_pe.c b/src/file_pe.c +index 805e614..c22b2af 100644 +--- a/src/file_pe.c ++++ b/src/file_pe.c +@@ -114,6 +114,8 @@ check_inputs(pesign_context *ctx) + static void + print_digest(pesign_context *pctx) + { ++ unsigned int i; ++ + if (!pctx) + return; + +@@ -121,10 +123,9 @@ print_digest(pesign_context *pctx) + if (!ctx) + return; + +- int j = ctx->selected_digest; +- for (unsigned int i = 0; i < ctx->digests[j].pe_digest->len; i++) +- printf("%02x", +- (unsigned char)ctx->digests[j].pe_digest->data[i]); ++ unsigned char *ddata = ctx->selected_digest->pe_digest->data; ++ for (i = 0; i < ctx->selected_digest->pe_digest->len; i++) ++ printf("%02x", ddata[i]); + printf(" %s\n", pctx->infile); + } + +diff --git a/src/pesigcheck.c b/src/pesigcheck.c +index 6dc67f7..ebb404d 100644 +--- a/src/pesigcheck.c ++++ b/src/pesigcheck.c +@@ -221,9 +221,7 @@ 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)); ++ memcpy(digest, cms->selected_digest->pe_digest, sizeof(*digest)); + } + + static int +diff --git a/src/cms_common.h b/src/cms_common.h +index c7acbcf..c7d4f69 100644 +--- a/src/cms_common.h ++++ b/src/cms_common.h +@@ -12,6 +12,7 @@ + #include + + #include ++#include + #include + #include + #include +@@ -57,9 +58,19 @@ + goto errlabel; \ + }) + ++struct digest_param { ++ char *name; ++ SECOidTag digest_tag; ++ SECOidTag signature_tag; ++ SECOidTag digest_encryption_tag; ++ const efi_guid_t *efi_guid; ++ int size; ++}; ++ + struct digest { + PK11Context *pk11ctx; + SECItem *pe_digest; ++ struct digest_param *digest_params; + }; + + typedef struct pk12_file { +@@ -133,7 +144,7 @@ typedef struct cms_context { + int db_out, dbx_out, dbt_out; + + struct digest *digests; +- int selected_digest; ++ struct digest *selected_digest; + int omit_vendor_cert; + + SECItem newsig; diff --git a/0006-Fix-mandoc-invocation-to-not-produce-garbage.patch b/0017-Fix-mandoc-invocation-to-not-produce-garbage.patch similarity index 93% rename from 0006-Fix-mandoc-invocation-to-not-produce-garbage.patch rename to 0017-Fix-mandoc-invocation-to-not-produce-garbage.patch index fb105df..648055e 100644 --- a/0006-Fix-mandoc-invocation-to-not-produce-garbage.patch +++ b/0017-Fix-mandoc-invocation-to-not-produce-garbage.patch @@ -12,7 +12,6 @@ feed this into man(1). Tell mandoc explicitly to produce man pages. Signed-off-by: Robbie Harwood -(cherry picked from commit 102c3d1d81c090750abb3815481d5cfd3e596677) --- Make.rules | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/0018-Work-around-GCC-being-obnoxiously-incompatible-with-.patch b/0018-Work-around-GCC-being-obnoxiously-incompatible-with-.patch new file mode 100644 index 0000000..3d0fd63 --- /dev/null +++ b/0018-Work-around-GCC-being-obnoxiously-incompatible-with-.patch @@ -0,0 +1,41 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Peter Jones +Date: Mon, 29 Aug 2022 15:31:52 -0400 +Subject: [PATCH] Work around GCC being obnoxiously incompatible with GCC + +GCC added and then later removed the diagnostic flag +"-Wanalyzer-use-of-uninitialized-value", and so this doesn't work with +newer versions of GCC. + +This patch removes the previous workaround for when it didn't work well. +I really wish any of our compilers had any sense of rigor with this +stuff at all. + +Signed-off-by: Peter Jones +--- + src/daemon.c | 5 ----- + 1 file changed, 5 deletions(-) + +diff --git a/src/daemon.c b/src/daemon.c +index ff88210..d66dd50 100644 +--- a/src/daemon.c ++++ b/src/daemon.c +@@ -917,10 +917,6 @@ do_shutdown(context *ctx, int nsockets, struct pollfd *pollfds) + free(pollfds); + } + +-/* GCC -fanalyzer has trouble with realloc +- * https://bugzilla.redhat.com/show_bug.cgi?id=2047926 */ +-#pragma GCC diagnostic push +-#pragma GCC diagnostic ignored "-Wanalyzer-use-of-uninitialized-value" + static int + handle_events(context *ctx) + { +@@ -999,7 +995,6 @@ shutdown: + } + return 0; + } +-#pragma GCC diagnostic pop + + static int + get_uid_and_gid(context *ctx, char **homedir) diff --git a/0019-get_password_passthrough-handle-the-callback-context.patch b/0019-get_password_passthrough-handle-the-callback-context.patch new file mode 100644 index 0000000..3240a32 --- /dev/null +++ b/0019-get_password_passthrough-handle-the-callback-context.patch @@ -0,0 +1,51 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Peter Jones +Date: Mon, 29 Aug 2022 14:21:44 -0400 +Subject: [PATCH] get_password_passthrough(): handle the callback context right + +Right now, we have a few callback functions for PK11_Authenticate(), and +they take different arguments. This is incorrect; none of the callers +ever pass anything through except our CMS context. + +This fixes get_password_passthrough() to correctly accept the CMS +context and get the passthrough data from cms->pwdata instead of trying +to treat the CMS context as the pwdata. + +Related: rhbz#2122777 + +Signed-off-by: Peter Jones +--- + src/password.c | 16 +++++++++++++--- + 1 file changed, 13 insertions(+), 3 deletions(-) + +diff --git a/src/password.c b/src/password.c +index 18c32ed..8eb1c33 100644 +--- a/src/password.c ++++ b/src/password.c +@@ -365,13 +365,23 @@ err: + } + + char * +-get_password_passthrough(PK11SlotInfo *slot UNUSED, +- PRBool retry, void *arg) ++get_password_passthrough(PK11SlotInfo *slot UNUSED, PRBool retry, void *arg) + { ++ cms_context *cms; ++ secuPWData *pwdata; ++ ++ dbgprintf("ctx:%p", arg); ++ + if (retry || !arg) + return NULL; + +- char *ret = strdup(arg); ++ cms = (cms_context *)arg; ++ pwdata = &cms->pwdata; ++ ++ if (pwdata->source != PW_PLAINTEXT) ++ return NULL; ++ ++ char *ret = strdup(pwdata->data); + if (!ret) + err(1, "Could not allocate memory"); + diff --git a/0020-read_password-only-prune-CR-NL-from-the-end-of-the-f.patch b/0020-read_password-only-prune-CR-NL-from-the-end-of-the-f.patch new file mode 100644 index 0000000..b69d5ff --- /dev/null +++ b/0020-read_password-only-prune-CR-NL-from-the-end-of-the-f.patch @@ -0,0 +1,47 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Peter Jones +Date: Mon, 29 Aug 2022 15:22:10 -0400 +Subject: [PATCH] read_password(): only prune CR/NL from the end of the file + +Right now, when we read the password/PIN from a file, we're pruning the +end of the string from the file we read indiscriminately. If you don't +have a newline, that means we're cutting off the final digits of the +text. + +This changes it to prune only common special characters from the +pinfile, but also to prune /all/ of them. + +Related: rhbz#2122777 +Signed-off-by: Peter Jones +--- + src/password.c | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +diff --git a/src/password.c b/src/password.c +index 8eb1c33..ac1866e 100644 +--- a/src/password.c ++++ b/src/password.c +@@ -79,6 +79,7 @@ read_password(FILE *in, FILE *out, char *buf, size_t bufsz) + int infd = fileno(in); + struct termios tio; + char *ret; ++ int len; + + ingress(); + ret = fgets(buf, bufsz, in); +@@ -96,7 +97,14 @@ read_password(FILE *in, FILE *out, char *buf, size_t bufsz) + if (ret == NULL) + return -1; + +- buf[strlen(buf)-1] = '\0'; ++ len = strlen(buf); ++ while (len > 0 && (buf[len-1] == '\r' || buf[len-1] == '\n')) { ++ buf[len-1] = '\0'; ++ len--; ++ } ++ if (len == 0) ++ return -1; ++ + egress(); + return 0; + } diff --git a/0021-Revert-cms-store-digest-as-pointer-instead-of-index.patch b/0021-Revert-cms-store-digest-as-pointer-instead-of-index.patch new file mode 100644 index 0000000..ac9bdfd --- /dev/null +++ b/0021-Revert-cms-store-digest-as-pointer-instead-of-index.patch @@ -0,0 +1,276 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Peter Jones +Date: Mon, 29 Aug 2022 16:22:18 -0400 +Subject: [PATCH] Revert "cms: store digest as pointer instead of index" + +In 926782c216532a83f9ff864dee39d2349d61fd23, we switched +cms->selected_digest to be a pointer to the member of the digests array +rather than an index. Unfortunately this is just as bad, because the +bugs that come up wind up setting pointers to NULL+(selected*offset), +i.e. 0x10, and that doesn't get us any closer to actually finding any +problem. + +For now, the new approach is going to be to make it an index again, but +to default it to 0 (sha256) rather than -1, so if it isn't set at the +correct part of the lifecycle it'll just default to the (nearly always) +correct choice. + +This reverts commit 926782c216532a83f9ff864dee39d2349d61fd23. + +Signed-off-by: Peter Jones +--- + src/certdb.c | 15 +++++++-------- + src/cms_common.c | 34 ++++++++++++++++++++++++---------- + src/content_info.c | 4 ++-- + src/file_kmod.c | 2 +- + src/file_pe.c | 9 ++++----- + src/pesigcheck.c | 4 +++- + src/cms_common.h | 13 +------------ + 7 files changed, 42 insertions(+), 39 deletions(-) + +diff --git a/src/certdb.c b/src/certdb.c +index f512824..69d5daf 100644 +--- a/src/certdb.c ++++ b/src/certdb.c +@@ -263,19 +263,18 @@ check_hash(pesigcheck_context *ctx, SECItem *sig, efi_guid_t *sigtype, + { + efi_guid_t efi_sha256 = efi_guid_sha256; + efi_guid_t efi_sha1 = efi_guid_sha1; +- void *digest_data; +- struct digest *digests = ctx->cms_ctx->digests; ++ void *digest; + + if (memcmp(sigtype, &efi_sha256, sizeof(efi_guid_t)) == 0) { +- digest_data = digests[0].pe_digest->data; +- if (memcmp (digest_data, sig->data, 32) == 0) { +- ctx->cms_ctx->selected_digest = &digests[0]; ++ digest = ctx->cms_ctx->digests[0].pe_digest->data; ++ if (memcmp (digest, sig->data, 32) == 0) { ++ ctx->cms_ctx->selected_digest = 0; + return FOUND; + } + } else if (memcmp(sigtype, &efi_sha1, sizeof(efi_guid_t)) == 0) { +- digest_data = digests[1].pe_digest->data; +- if (memcmp (digest_data, sig->data, 20) == 0) { +- ctx->cms_ctx->selected_digest = &digests[1]; ++ digest = ctx->cms_ctx->digests[1].pe_digest->data; ++ if (memcmp (digest, sig->data, 20) == 0) { ++ ctx->cms_ctx->selected_digest = 1; + return FOUND; + } + } +diff --git a/src/cms_common.c b/src/cms_common.c +index 2275f67..86341ca 100644 +--- a/src/cms_common.c ++++ b/src/cms_common.c +@@ -33,6 +33,15 @@ + + #include "hex.h" + ++struct digest_param { ++ char *name; ++ SECOidTag digest_tag; ++ SECOidTag signature_tag; ++ SECOidTag digest_encryption_tag; ++ const efi_guid_t *efi_guid; ++ int size; ++}; ++ + static struct digest_param digest_params[] = { + {.name = "sha256", + .digest_tag = SEC_OID_SHA256, +@@ -56,25 +65,29 @@ static int n_digest_params = sizeof (digest_params) / sizeof (digest_params[0]); + SECOidTag + digest_get_digest_oid(cms_context *cms) + { +- return cms->selected_digest->digest_params->digest_tag; ++ int i = cms->selected_digest; ++ return digest_params[i].digest_tag; + } + + SECOidTag + digest_get_encryption_oid(cms_context *cms) + { +- return cms->selected_digest->digest_params->digest_encryption_tag; ++ int i = cms->selected_digest; ++ return digest_params[i].digest_encryption_tag; + } + + SECOidTag + digest_get_signature_oid(cms_context *cms) + { +- return cms->selected_digest->digest_params->signature_tag; ++ int i = cms->selected_digest; ++ return digest_params[i].signature_tag; + } + + int + digest_get_digest_size(cms_context *cms) + { +- return cms->selected_digest->digest_params->size; ++ int i = cms->selected_digest; ++ return digest_params[i].size; + } + + void +@@ -129,6 +142,8 @@ cms_context_init(cms_context *cms) + if (!cms->arena) + cnreterr(-1, cms, "could not create cryptographic arena"); + ++ cms->selected_digest = -1; ++ + INIT_LIST_HEAD(&cms->pk12_ins); + cms->pk12_out.fd = -1; + cms->db_out = cms->dbx_out = cms->dbt_out = -1; +@@ -211,7 +226,7 @@ cms_context_fini(cms_context *cms) + memset(&cms->newsig, '\0', sizeof (cms->newsig)); + } + +- cms->selected_digest = NULL; ++ cms->selected_digest = -1; + + if (cms->ci_digest) { + free_poison(cms->ci_digest->data, cms->ci_digest->len); +@@ -336,7 +351,7 @@ set_digest_parameters(cms_context *cms, char *name) + if (strcmp(name, "help")) { + for (int i = 0; i < n_digest_params; i++) { + if (!strcmp(name, digest_params[i].name)) { +- cms->selected_digest = &cms->digests[i]; ++ cms->selected_digest = i; + return 0; + } + } +@@ -1264,7 +1279,6 @@ generate_digest_begin(cms_context *cms) + cngotoerr(err, cms, "could not create digest context"); + + PK11_DigestBegin(digests[i].pk11ctx); +- digests[i].digest_params = &digest_params[i]; + } + + cms->digests = digests; +@@ -1337,11 +1351,11 @@ generate_signature(cms_context *cms) + { + int rc = 0; + +- if (cms->selected_digest->pe_digest == NULL) ++ if (cms->digests[cms->selected_digest].pe_digest == NULL) + cnreterr(-1, cms, "PE digest has not been allocated"); + +- if (content_is_empty(cms->selected_digest->pe_digest->data, +- cms->selected_digest->pe_digest->len)) ++ if (content_is_empty(cms->digests[cms->selected_digest].pe_digest->data, ++ cms->digests[cms->selected_digest].pe_digest->len)) + cnreterr(-1, cms, "PE binary has not been digested"); + + SECItem sd_der; +diff --git a/src/content_info.c b/src/content_info.c +index 777aa28..9684850 100644 +--- a/src/content_info.c ++++ b/src/content_info.c +@@ -181,8 +181,8 @@ generate_spc_digest_info(cms_context *cms, SECItem *dip) + if (generate_algorithm_id(cms, &di.digestAlgorithm, + digest_get_digest_oid(cms)) < 0) + return -1; +- memcpy(&di.digest, cms->selected_digest->pe_digest, +- sizeof(di.digest)); ++ int i = cms->selected_digest; ++ memcpy(&di.digest, cms->digests[i].pe_digest, sizeof (di.digest)); + + if (content_is_empty(di.digest.data, di.digest.len)) { + cms->log(cms, LOG_ERR, "got empty digest"); +diff --git a/src/file_kmod.c b/src/file_kmod.c +index c8875fc..6880cda 100644 +--- a/src/file_kmod.c ++++ b/src/file_kmod.c +@@ -60,7 +60,7 @@ ssize_t + kmod_write_signature(cms_context *cms, int outfd) + { + SEC_PKCS7ContentInfo *cinfo; +- SECItem *digest = cms->selected_digest->pe_digest; ++ SECItem *digest = cms->digests[cms->selected_digest].pe_digest; + SECStatus rv; + struct write_sig_info info = { + .outfd = outfd, +diff --git a/src/file_pe.c b/src/file_pe.c +index c22b2af..805e614 100644 +--- a/src/file_pe.c ++++ b/src/file_pe.c +@@ -114,8 +114,6 @@ check_inputs(pesign_context *ctx) + static void + print_digest(pesign_context *pctx) + { +- unsigned int i; +- + if (!pctx) + return; + +@@ -123,9 +121,10 @@ print_digest(pesign_context *pctx) + if (!ctx) + return; + +- unsigned char *ddata = ctx->selected_digest->pe_digest->data; +- for (i = 0; i < ctx->selected_digest->pe_digest->len; i++) +- printf("%02x", ddata[i]); ++ int j = ctx->selected_digest; ++ for (unsigned int i = 0; i < ctx->digests[j].pe_digest->len; i++) ++ printf("%02x", ++ (unsigned char)ctx->digests[j].pe_digest->data[i]); + printf(" %s\n", pctx->infile); + } + +diff --git a/src/pesigcheck.c b/src/pesigcheck.c +index ebb404d..6dc67f7 100644 +--- a/src/pesigcheck.c ++++ b/src/pesigcheck.c +@@ -221,7 +221,9 @@ static void + get_digest(pesigcheck_context *ctx, SECItem *digest) + { + struct cms_context *cms = ctx->cms_ctx; +- memcpy(digest, cms->selected_digest->pe_digest, sizeof(*digest)); ++ struct digest *cms_digest = &cms->digests[cms->selected_digest]; ++ ++ memcpy(digest, cms_digest->pe_digest, sizeof (*digest)); + } + + static int +diff --git a/src/cms_common.h b/src/cms_common.h +index c7d4f69..c7acbcf 100644 +--- a/src/cms_common.h ++++ b/src/cms_common.h +@@ -12,7 +12,6 @@ + #include + + #include +-#include + #include + #include + #include +@@ -58,19 +57,9 @@ + goto errlabel; \ + }) + +-struct digest_param { +- char *name; +- SECOidTag digest_tag; +- SECOidTag signature_tag; +- SECOidTag digest_encryption_tag; +- const efi_guid_t *efi_guid; +- int size; +-}; +- + struct digest { + PK11Context *pk11ctx; + SECItem *pe_digest; +- struct digest_param *digest_params; + }; + + typedef struct pk12_file { +@@ -144,7 +133,7 @@ typedef struct cms_context { + int db_out, dbx_out, dbt_out; + + struct digest *digests; +- struct digest *selected_digest; ++ int selected_digest; + int omit_vendor_cert; + + SECItem newsig; diff --git a/0022-CMS-add-some-minor-cleanups.patch b/0022-CMS-add-some-minor-cleanups.patch new file mode 100644 index 0000000..dfff3f5 --- /dev/null +++ b/0022-CMS-add-some-minor-cleanups.patch @@ -0,0 +1,149 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Peter Jones +Date: Mon, 29 Aug 2022 17:02:46 -0400 +Subject: [PATCH] CMS: add some minor cleanups + +We reverted 926782c216532a83f9ff864dee39d2349d61fd23 so that a future +patch can try a different approach, but that commit also had a few +cleanups that are worthwhile on their own. + +This patch re-introduces the cleanup to move "struct digest_param" to a +more reasonable place and the cleanup to check_hash(), and takes it just +a bit farther. + +Signed-off-by: Peter Jones +--- + src/certdb.c | 26 +++++++++++++++----------- + src/cms_common.c | 39 ++++++++++++++++----------------------- + src/cms_common.h | 16 ++++++++++++++++ + 3 files changed, 47 insertions(+), 34 deletions(-) + +diff --git a/src/certdb.c b/src/certdb.c +index 69d5daf..eb5221f 100644 +--- a/src/certdb.c ++++ b/src/certdb.c +@@ -263,20 +263,24 @@ check_hash(pesigcheck_context *ctx, SECItem *sig, efi_guid_t *sigtype, + { + efi_guid_t efi_sha256 = efi_guid_sha256; + efi_guid_t efi_sha1 = efi_guid_sha1; +- void *digest; ++ void *digest_data; ++ struct digest *digests = ctx->cms_ctx->digests; ++ int selected_digest = -1; ++ size_t size; + + if (memcmp(sigtype, &efi_sha256, sizeof(efi_guid_t)) == 0) { +- digest = ctx->cms_ctx->digests[0].pe_digest->data; +- if (memcmp (digest, sig->data, 32) == 0) { +- ctx->cms_ctx->selected_digest = 0; +- return FOUND; +- } ++ selected_digest = DIGEST_PARAM_SHA256; + } else if (memcmp(sigtype, &efi_sha1, sizeof(efi_guid_t)) == 0) { +- digest = ctx->cms_ctx->digests[1].pe_digest->data; +- if (memcmp (digest, sig->data, 20) == 0) { +- ctx->cms_ctx->selected_digest = 1; +- return FOUND; +- } ++ selected_digest = DIGEST_PARAM_SHA1; ++ } else { ++ return NOT_FOUND; ++ } ++ ++ digest_data = digests[selected_digest].pe_digest->data; ++ size = digest_params[selected_digest].size; ++ if (memcmp (digest_data, sig->data, size) == 0) { ++ ctx->cms_ctx->selected_digest = selected_digest; ++ return FOUND; + } + + return NOT_FOUND; +diff --git a/src/cms_common.c b/src/cms_common.c +index 86341ca..7bddedf 100644 +--- a/src/cms_common.c ++++ b/src/cms_common.c +@@ -33,34 +33,27 @@ + + #include "hex.h" + +-struct digest_param { +- char *name; +- SECOidTag digest_tag; +- SECOidTag signature_tag; +- SECOidTag digest_encryption_tag; +- const efi_guid_t *efi_guid; +- int size; +-}; +- +-static struct digest_param digest_params[] = { +- {.name = "sha256", +- .digest_tag = SEC_OID_SHA256, +- .signature_tag = SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION, +- .digest_encryption_tag = SEC_OID_PKCS1_RSA_ENCRYPTION, +- .efi_guid = &efi_guid_sha256, +- .size = 32 ++const struct digest_param digest_params[] = { ++ [DIGEST_PARAM_SHA256] = { ++ .name = "sha256", ++ .digest_tag = SEC_OID_SHA256, ++ .signature_tag = SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION, ++ .digest_encryption_tag = SEC_OID_PKCS1_RSA_ENCRYPTION, ++ .efi_guid = &efi_guid_sha256, ++ .size = 32 + }, + #if 1 +- {.name = "sha1", +- .digest_tag = SEC_OID_SHA1, +- .signature_tag = SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION, +- .digest_encryption_tag = SEC_OID_PKCS1_RSA_ENCRYPTION, +- .efi_guid = &efi_guid_sha1, +- .size = 20 ++ [DIGEST_PARAM_SHA1] = { ++ .name = "sha1", ++ .digest_tag = SEC_OID_SHA1, ++ .signature_tag = SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION, ++ .digest_encryption_tag = SEC_OID_PKCS1_RSA_ENCRYPTION, ++ .efi_guid = &efi_guid_sha1, ++ .size = 20 + }, + #endif + }; +-static int n_digest_params = sizeof (digest_params) / sizeof (digest_params[0]); ++const int n_digest_params = sizeof (digest_params) / sizeof (digest_params[0]); + + SECOidTag + digest_get_digest_oid(cms_context *cms) +diff --git a/src/cms_common.h b/src/cms_common.h +index c7acbcf..e45402c 100644 +--- a/src/cms_common.h ++++ b/src/cms_common.h +@@ -12,6 +12,7 @@ + #include + + #include ++#include + #include + #include + #include +@@ -62,6 +63,21 @@ struct digest { + SECItem *pe_digest; + }; + ++#define DIGEST_PARAM_SHA256 0 ++#define DIGEST_PARAM_SHA1 1 ++ ++struct digest_param { ++ char *name; ++ SECOidTag digest_tag; ++ SECOidTag signature_tag; ++ SECOidTag digest_encryption_tag; ++ const efi_guid_t *efi_guid; ++ int size; ++}; ++ ++extern const struct digest_param digest_params[2]; ++extern const int n_digest_params; ++ + typedef struct pk12_file { + char *path; + int fd; diff --git a/0023-CMS-make-cms-selected_digest-an-index-again.patch b/0023-CMS-make-cms-selected_digest-an-index-again.patch new file mode 100644 index 0000000..6e19cd1 --- /dev/null +++ b/0023-CMS-make-cms-selected_digest-an-index-again.patch @@ -0,0 +1,291 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Peter Jones +Date: Tue, 30 Aug 2022 15:42:15 -0400 +Subject: [PATCH] CMS: make cms->selected_digest an index (again) + +In 926782c216532a83f9ff864dee39d2349d61fd23, we switched +cms->selected_digest to be a pointer to the entry in cms->digests. + +Because cms->digests is lazily allocated, setting the selected_digest +pointer has to be done at the right part of the CMS context life cycle, +and in some cases it clearly is not: + +==334217== Command: ./src/pesign -n tmp -s --pinfile tmp/pinfile -t OpenSC\ Card\ (testcard) -c kernel-signer -i tmp/unsigned.efi -o tmp/signed.efi --force +==334217== +==334217== Invalid read of size 8 +==334217== at 0x115E7D: digest_get_digest_oid (cms_common.c:59) +==334217== by 0x11CF41: generate_algorithm_id_list (signed_data.c:33) +==334217== by 0x11D348: generate_spc_signed_data (signed_data.c:279) +==334217== by 0x11EDFD: calculate_signature_space (wincert.c:297) +==334217== by 0x11467D: pe_handle_action (file_pe.c:298) +==334217== by 0x10F962: main (pesign.c:585) +==334217== Address 0x10 is not stack'd, malloc'd or (recently) free'd +==334217== +==334217== +==334217== Process terminating with default action of signal 11 (SIGSEGV): dumping core +==334217== Access not within mapped region at address 0x10 +==334217== at 0x115E7D: digest_get_digest_oid (cms_common.c:59) +==334217== by 0x11CF41: generate_algorithm_id_list (signed_data.c:33) +==334217== by 0x11D348: generate_spc_signed_data (signed_data.c:279) +==334217== by 0x11EDFD: calculate_signature_space (wincert.c:297) +==334217== by 0x11467D: pe_handle_action (file_pe.c:298) +==334217== by 0x10F962: main (pesign.c:585) +==334217== If you believe this happened as a result of a stack +==334217== overflow in your program's main thread (unlikely but +==334217== possible), you can try to increase the size of the +==334217== main thread stack using the --main-stacksize= flag. +==334217== The main thread stack size used in this run was 8388608. +==334217== +==334217== HEAP SUMMARY: +==334217== in use at exit: 588,544 bytes in 4,388 blocks +==334217== total heap usage: 8,568 allocs, 4,180 frees, 2,077,115 bytes allocated +==334217== +==334217== LEAK SUMMARY: +==334217== definitely lost: 25 bytes in 1 blocks +==334217== indirectly lost: 0 bytes in 0 blocks +==334217== possibly lost: 51,378 bytes in 166 blocks +==334217== still reachable: 537,141 bytes in 4,221 blocks +==334217== of which reachable via heuristic: +==334217== length64 : 321,312 bytes in 590 blocks +==334217== suppressed: 0 bytes in 0 blocks +==334217== Rerun with --leak-check=full to see details of leaked memory +==334217== +==334217== For lists of detected and suppressed errors, rerun with: -s +==334217== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0) +Segmentation fault (core dumped) + +There is also a similar issue in the daemon code, and how to fix it +there is not immediately clear to me. + +Currently, we realistically only support using sha256 digests, so for +now I've chosen to paper over the issue by switching back to +cms->selected_digest be an index into both ctx->digests and +digest_params, but switching the default value from -1 to 0, aka +DIGEST_PARAM_SHA256. We can revisit this issue later whenever we add +sha384 support (or whichever other digest). + +Signed-off-by: Peter Jones +--- + src/certdb.c | 2 +- + src/cms_common.c | 41 +++++++++++++++++++++++------------------ + src/content_info.c | 2 +- + src/cms_common.h | 5 +++-- + 4 files changed, 28 insertions(+), 22 deletions(-) + +diff --git a/src/certdb.c b/src/certdb.c +index eb5221f..467a01d 100644 +--- a/src/certdb.c ++++ b/src/certdb.c +@@ -265,7 +265,7 @@ check_hash(pesigcheck_context *ctx, SECItem *sig, efi_guid_t *sigtype, + efi_guid_t efi_sha1 = efi_guid_sha1; + void *digest_data; + struct digest *digests = ctx->cms_ctx->digests; +- int selected_digest = -1; ++ unsigned int selected_digest; + size_t size; + + if (memcmp(sigtype, &efi_sha256, sizeof(efi_guid_t)) == 0) { +diff --git a/src/cms_common.c b/src/cms_common.c +index 7bddedf..1c54c90 100644 +--- a/src/cms_common.c ++++ b/src/cms_common.c +@@ -33,6 +33,10 @@ + + #include "hex.h" + ++/* ++ * Note that cms->selected_digest defaults to 0, which means the first ++ * entry of this array is the default digest. ++ */ + const struct digest_param digest_params[] = { + [DIGEST_PARAM_SHA256] = { + .name = "sha256", +@@ -53,33 +57,33 @@ const struct digest_param digest_params[] = { + }, + #endif + }; +-const int n_digest_params = sizeof (digest_params) / sizeof (digest_params[0]); ++const unsigned int n_digest_params = sizeof (digest_params) / sizeof (digest_params[0]); + + SECOidTag + digest_get_digest_oid(cms_context *cms) + { +- int i = cms->selected_digest; ++ unsigned int i = cms->selected_digest; + return digest_params[i].digest_tag; + } + + SECOidTag + digest_get_encryption_oid(cms_context *cms) + { +- int i = cms->selected_digest; ++ unsigned int i = cms->selected_digest; + return digest_params[i].digest_encryption_tag; + } + + SECOidTag + digest_get_signature_oid(cms_context *cms) + { +- int i = cms->selected_digest; ++ unsigned int i = cms->selected_digest; + return digest_params[i].signature_tag; + } + + int + digest_get_digest_size(cms_context *cms) + { +- int i = cms->selected_digest; ++ unsigned int i = cms->selected_digest; + return digest_params[i].size; + } + +@@ -91,7 +95,7 @@ teardown_digests(cms_context *ctx) + if (!digests) + return; + +- for (int i = 0; i < n_digest_params; i++) { ++ for (unsigned int i = 0; i < n_digest_params; i++) { + if (digests[i].pk11ctx) { + PK11_Finalize(digests[i].pk11ctx); + PK11_DestroyContext(digests[i].pk11ctx, PR_TRUE); +@@ -135,7 +139,7 @@ cms_context_init(cms_context *cms) + if (!cms->arena) + cnreterr(-1, cms, "could not create cryptographic arena"); + +- cms->selected_digest = -1; ++ cms->selected_digest = DEFAULT_DIGEST_PARAM; + + INIT_LIST_HEAD(&cms->pk12_ins); + cms->pk12_out.fd = -1; +@@ -219,7 +223,7 @@ cms_context_fini(cms_context *cms) + memset(&cms->newsig, '\0', sizeof (cms->newsig)); + } + +- cms->selected_digest = -1; ++ cms->selected_digest = DEFAULT_DIGEST_PARAM; + + if (cms->ci_digest) { + free_poison(cms->ci_digest->data, cms->ci_digest->len); +@@ -342,7 +346,7 @@ int + set_digest_parameters(cms_context *cms, char *name) + { + if (strcmp(name, "help")) { +- for (int i = 0; i < n_digest_params; i++) { ++ for (unsigned int i = 0; i < n_digest_params; i++) { + if (!strcmp(name, digest_params[i].name)) { + cms->selected_digest = i; + return 0; +@@ -350,7 +354,7 @@ set_digest_parameters(cms_context *cms, char *name) + } + } else { + printf("Supported digests: "); +- for (int i = 0; digest_params[i].name != NULL; i++) { ++ for (unsigned int i = 0; digest_params[i].name != NULL; i++) { + printf("%s ", digest_params[i].name); + } + printf("\n"); +@@ -1265,7 +1269,7 @@ generate_digest_begin(cms_context *cms) + cnreterr(-1, cms, "could not allocate digest context"); + } + +- for (int i = 0; i < n_digest_params; i++) { ++ for (unsigned int i = 0; i < n_digest_params; i++) { + digests[i].pk11ctx = PK11_CreateDigestContext( + digest_params[i].digest_tag); + if (!digests[i].pk11ctx) +@@ -1278,7 +1282,7 @@ generate_digest_begin(cms_context *cms) + return 0; + + err: +- for (int i = 0; i < n_digest_params; i++) { ++ for (unsigned int i = 0; i < n_digest_params; i++) { + if (digests[i].pk11ctx) + PK11_DestroyContext(digests[i].pk11ctx, PR_TRUE); + } +@@ -1290,7 +1294,7 @@ err: + void + generate_digest_step(cms_context *cms, void *data, size_t len) + { +- for (int i = 0; i < n_digest_params; i++) ++ for (unsigned int i = 0; i < n_digest_params; i++) + PK11_DigestOp(cms->digests[i].pk11ctx, data, len); + } + +@@ -1299,7 +1303,7 @@ generate_digest_finish(cms_context *cms) + { + void *mark = PORT_ArenaMark(cms->arena); + +- for (int i = 0; i < n_digest_params; i++) { ++ for (unsigned int i = 0; i < n_digest_params; i++) { + SECItem *digest = PORT_ArenaZAlloc(cms->arena,sizeof (SECItem)); + if (digest == NULL) + cngotoerr(err, cms, "could not allocate memory"); +@@ -1326,7 +1330,7 @@ generate_digest_finish(cms_context *cms) + PORT_ArenaUnmark(cms->arena, mark); + return 0; + err: +- for (int i = 0; i < n_digest_params; i++) { ++ for (unsigned int i = 0; i < n_digest_params; i++) { + if (cms->digests[i].pk11ctx) + PK11_DestroyContext(cms->digests[i].pk11ctx, PR_TRUE); + } +@@ -1343,12 +1347,13 @@ int + generate_signature(cms_context *cms) + { + int rc = 0; ++ int i = cms->selected_digest; + +- if (cms->digests[cms->selected_digest].pe_digest == NULL) ++ if (cms->digests[i].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)) ++ if (content_is_empty(cms->digests[i].pe_digest->data, ++ cms->digests[i].pe_digest->len)) + cnreterr(-1, cms, "PE binary has not been digested"); + + SECItem sd_der; +diff --git a/src/content_info.c b/src/content_info.c +index 9684850..900974c 100644 +--- a/src/content_info.c ++++ b/src/content_info.c +@@ -181,7 +181,7 @@ generate_spc_digest_info(cms_context *cms, SECItem *dip) + if (generate_algorithm_id(cms, &di.digestAlgorithm, + digest_get_digest_oid(cms)) < 0) + return -1; +- int i = cms->selected_digest; ++ unsigned int i = cms->selected_digest; + memcpy(&di.digest, cms->digests[i].pe_digest, sizeof (di.digest)); + + if (content_is_empty(di.digest.data, di.digest.len)) { +diff --git a/src/cms_common.h b/src/cms_common.h +index e45402c..35a128a 100644 +--- a/src/cms_common.h ++++ b/src/cms_common.h +@@ -65,6 +65,7 @@ struct digest { + + #define DIGEST_PARAM_SHA256 0 + #define DIGEST_PARAM_SHA1 1 ++#define DEFAULT_DIGEST_PARAM DIGEST_PARAM_SHA256 + + struct digest_param { + char *name; +@@ -76,7 +77,7 @@ struct digest_param { + }; + + extern const struct digest_param digest_params[2]; +-extern const int n_digest_params; ++extern const unsigned int n_digest_params; + + typedef struct pk12_file { + char *path; +@@ -149,7 +150,7 @@ typedef struct cms_context { + int db_out, dbx_out, dbt_out; + + struct digest *digests; +- int selected_digest; ++ unsigned int selected_digest; + int omit_vendor_cert; + + SECItem newsig; diff --git a/pesign.patches b/pesign.patches index 9b257c3..0b756e9 100644 --- a/pesign.patches +++ b/pesign.patches @@ -1,6 +1,23 @@ Patch0001: 0001-daemon-remove-always-true-comparison.patch -Patch0002: 0002-Fix-building-signed-kernels-on-setups-other-than-koj.patch -Patch0003: 0003-Add-D_GLIBCXX_ASSERTIONS-to-CPPFLAGS.patch -Patch0004: 0004-macros.pesign-handle-centos-like-rhel-with-rhelver.patch -Patch0005: 0005-Detect-the-presence-of-rpm-sign-when-checking-for-rh.patch -Patch0006: 0006-Fix-mandoc-invocation-to-not-produce-garbage.patch +Patch0002: 0002-make-handle-some-gcc-Wanalyzer-flags-better.patch +Patch0003: 0003-Rename-dprintf-to-dbgprintf.patch +Patch0004: 0004-.gitignore-add-compile_commands.json-and-.cache.patch +Patch0005: 0005-pesign-print-digests-before-filenames-like-sha256sum.patch +Patch0006: 0006-Add-pesum-an-authenticode-digest-generator.patch +Patch0007: 0007-Fix-building-signed-kernels-on-setups-other-than-koj.patch +Patch0008: 0008-Add-D_GLIBCXX_ASSERTIONS-to-CPPFLAGS.patch +Patch0009: 0009-macros.pesign-handle-centos-like-rhel-with-rhelver.patch +Patch0010: 0010-Detect-the-presence-of-rpm-sign-when-checking-for-rh.patch +Patch0011: 0011-Rename-README-README.md.patch +Patch0012: 0012-README.md-show-off-a-bit-more.patch +Patch0013: 0013-Fix-missing-line-in-README.md.patch +Patch0014: 0014-Fix-typo-in-efikeygen-command.patch +Patch0015: 0015-pesigcheck-Fix-crash-on-digest-match.patch +Patch0016: 0016-cms-store-digest-as-pointer-instead-of-index.patch +Patch0017: 0017-Fix-mandoc-invocation-to-not-produce-garbage.patch +Patch0018: 0018-Work-around-GCC-being-obnoxiously-incompatible-with-.patch +Patch0019: 0019-get_password_passthrough-handle-the-callback-context.patch +Patch0020: 0020-read_password-only-prune-CR-NL-from-the-end-of-the-f.patch +Patch0021: 0021-Revert-cms-store-digest-as-pointer-instead-of-index.patch +Patch0022: 0022-CMS-add-some-minor-cleanups.patch +Patch0023: 0023-CMS-make-cms-selected_digest-an-index-again.patch diff --git a/pesign.spec b/pesign.spec index 118b151..4c835d0 100644 --- a/pesign.spec +++ b/pesign.spec @@ -6,7 +6,7 @@ Name: pesign Summary: Signing utility for UEFI binaries Version: 115 -Release: 8%{?dist} +Release: 9%{?dist} License: GPL-2.0-only URL: https://github.com/rhboot/pesign @@ -132,12 +132,13 @@ certutil -d %{_sysconfdir}/pki/pesign/ -X -L > /dev/null %files %{!?_licensedir:%global license %%doc} %license COPYING -%doc README TODO +%doc README.md TODO %{_bindir}/authvar %{_bindir}/efikeygen %{_bindir}/pesigcheck %{_bindir}/pesign %{_bindir}/pesign-client +%{_bindir}/pesum %dir %{_libexecdir}/pesign/ %dir %attr(0770,pesign,pesign) %{_sysconfdir}/pki/pesign/ %config(noreplace) %attr(0660,pesign,pesign) %{_sysconfdir}/pki/pesign/* @@ -161,6 +162,9 @@ certutil -d %{_sysconfdir}/pki/pesign/ -X -L > /dev/null %{python3_sitelib}/mockbuild/plugins/pesign.* %changelog +* Wed Aug 31 2022 Robbie Harwood - 115-9 +- Roll up to pjones's smartcard/cms fixes + * Tue Aug 02 2022 Robbie Harwood - 115-8 - Rebuild for python bytecode change - See-also: #2107826