Marcus Meissner
0b5d673ec8
Modified pesign-bnc805166-fix-signature-list.patch, block out the source code for find/attach Issuer certificate (bnc#805166 comment#13) OBS-URL: https://build.opensuse.org/request/show/156163 OBS-URL: https://build.opensuse.org/package/show/Base:System/pesign?expand=0&rev=11
784 lines
22 KiB
Diff
784 lines
22 KiB
Diff
commit 63c6ad572b3c1a7041dc581072421c2c94ff5d35
|
|
Author: Gary Ching-Pang Lin <chingpang@gmail.com>
|
|
Date: Fri Feb 22 15:13:08 2013 +0800
|
|
|
|
Backport patches to fix signature list
|
|
|
|
Get cms_context out of wincert functions.
|
|
ee357451be9968cedda57ce13b103eb82c590e67
|
|
|
|
Rework siglist to be somewhat more useful.
|
|
a5ec0d2cd06dec0961fc3fed680e7e385dc5bec8
|
|
|
|
Don't allow our signature list iterator to walk off the end of the file.
|
|
18980866e7952100d98510297c0e1cc25fca8fc8
|
|
|
|
Include old signatures in new space calculations.
|
|
77d334d77435d64e88fcc772b5b58440b394584a
|
|
|
|
Make implanting extracted certificates work again.
|
|
5ceddd2f80dfea70d211236190943746c2d2f77b
|
|
|
|
Add error handling macros to make code simpler.
|
|
0bafa814b49a9556550cfbc373e0ea5b9edb929e
|
|
|
|
Add is_issuer_of(cert, cert) helper function.
|
|
7750aaeceb2655807788f8e45417e84cb5404a8e
|
|
|
|
Add "find_named_certificate()" helper function.
|
|
c89c8dbf7929f8f8f36bc1c4045fcc17d5ce7e5c
|
|
|
|
Make generate_certificate_list include the issuing certificate.
|
|
8c3d82ceb5029bedfee1577682fec5ff3669ff3c
|
|
|
|
Fix a casting problem on 32-bit.
|
|
|
|
9eb2814858270af2d7ecfbfa5ca131e7be2f9f53
|
|
|
|
Index: pesign-0.99/libdpe/pe_addcert.c
|
|
===================================================================
|
|
--- pesign-0.99.orig/libdpe/pe_addcert.c
|
|
+++ pesign-0.99/libdpe/pe_addcert.c
|
|
@@ -59,7 +59,7 @@ pe_alloccert(Pe *pe, size_t size)
|
|
memset(addr, '\0', size);
|
|
|
|
dd->certs.virtual_address = compute_file_addr(pe, addr);
|
|
- dd->certs.size = size;
|
|
+ dd->certs.size += size;
|
|
|
|
#if 0
|
|
pe_set_image_size(pe);
|
|
Index: pesign-0.99/libdpe/pe_updatefile.c
|
|
===================================================================
|
|
--- pesign-0.99.orig/libdpe/pe_updatefile.c
|
|
+++ pesign-0.99/libdpe/pe_updatefile.c
|
|
@@ -24,6 +24,7 @@
|
|
#include <sys/mman.h>
|
|
|
|
static struct section_header *
|
|
+__attribute__((unused))
|
|
__get_last_section(Pe *pe)
|
|
{
|
|
Pe_Scn *scn = NULL;
|
|
@@ -79,6 +80,7 @@ compare_sections (const void *a, const v
|
|
}
|
|
|
|
static void
|
|
+__attribute__((unused))
|
|
sort_sections (Pe_Scn **scns, Pe_ScnList *list)
|
|
{
|
|
Pe_Scn **scnp = scns;
|
|
@@ -131,7 +133,16 @@ __pe_updatemmap(Pe *pe, size_t shnum)
|
|
msync(msync_start, msync_end - msync_start, MS_SYNC);
|
|
|
|
#warning this is not done yet.
|
|
- struct section_header *sh = __get_last_section(pe);
|
|
+ //struct section_header *sh = __get_last_section(pe);
|
|
+
|
|
+ size_t dd_size = sizeof (*dd) / sizeof (dd->exports);
|
|
+ data_dirent *dde = &dd->exports;
|
|
+ for (int i = 0; i < dd_size; i++, dde++) {
|
|
+ if (dde->size != 0) {
|
|
+ char *addr = compute_mem_addr(pe, dde->virtual_address);
|
|
+ msync(addr, dde->size, MS_SYNC);
|
|
+ }
|
|
+ }
|
|
|
|
return 0;
|
|
}
|
|
Index: pesign-0.99/src/actions.c
|
|
===================================================================
|
|
--- pesign-0.99.orig/src/actions.c
|
|
+++ pesign-0.99/src/actions.c
|
|
@@ -268,7 +268,7 @@ failure:
|
|
return ret;
|
|
}
|
|
|
|
-static void
|
|
+void
|
|
parse_signature(pesign_context *ctx)
|
|
{
|
|
int rc;
|
|
@@ -396,8 +396,6 @@ generate_sattr_blob(pesign_context *ctx)
|
|
void
|
|
check_signature_space(pesign_context *ctx)
|
|
{
|
|
- parse_signature(ctx);
|
|
-
|
|
ssize_t available = available_cert_space(ctx->outpe);
|
|
|
|
if (available < ctx->cms_ctx->newsig.len) {
|
|
@@ -406,14 +404,6 @@ check_signature_space(pesign_context *ct
|
|
}
|
|
}
|
|
|
|
-int
|
|
-import_signature(pesign_context *ctx)
|
|
-{
|
|
- insert_signature(ctx->cms_ctx, ctx->signum);
|
|
-
|
|
- return finalize_signatures(ctx->cms_ctx, ctx->outpe);
|
|
-}
|
|
-
|
|
void
|
|
allocate_signature_space(Pe *pe, ssize_t sigspace)
|
|
{
|
|
Index: pesign-0.99/src/actions.h
|
|
===================================================================
|
|
--- pesign-0.99.orig/src/actions.h
|
|
+++ pesign-0.99/src/actions.h
|
|
@@ -28,12 +28,12 @@ extern int list_signatures(pesign_contex
|
|
extern void check_signature_space(pesign_context *ctx);
|
|
extern void allocate_signature_space(Pe *pe, ssize_t sigspace);
|
|
extern off_t export_signature(cms_context *cms, int fd, int ascii_armor);
|
|
-extern int import_signature(pesign_context *ctx);
|
|
extern void import_raw_signature(pesign_context *pctx);
|
|
extern void remove_signature(pesign_context *ctx);
|
|
extern void export_pubkey(pesign_context *ctx);
|
|
extern void export_cert(pesign_context *ctx);
|
|
extern int generate_sattr_blob(pesign_context *pctx);
|
|
+extern void parse_signature(pesign_context *ctx);
|
|
extern void insert_signature(cms_context *cms, int signum);
|
|
|
|
#endif /* PESIGN_CRYPTO_H */
|
|
Index: pesign-0.99/src/cms_common.c
|
|
===================================================================
|
|
--- pesign-0.99.orig/src/cms_common.c
|
|
+++ pesign-0.99/src/cms_common.c
|
|
@@ -304,6 +304,17 @@ is_valid_cert(CERTCertificate *cert, voi
|
|
return SECFailure;
|
|
}
|
|
|
|
+int
|
|
+is_issuer_of(CERTCertificate *c0, CERTCertificate *c1)
|
|
+{
|
|
+ if (c0->derSubject.len != c1->derIssuer.len)
|
|
+ return 0;
|
|
+
|
|
+ if (memcmp(c0->derSubject.data, c1->derIssuer.data, c0->derSubject.len))
|
|
+ return 0;
|
|
+ return 1;
|
|
+}
|
|
+
|
|
/* This is the dumbest function ever, but we need it anyway, because nss
|
|
* is garbage. */
|
|
static void
|
|
@@ -443,6 +454,88 @@ err_slots:
|
|
|
|
PK11_DestroySlotListElement(slots, &psle);
|
|
PK11_FreeSlotList(slots);
|
|
+ CERT_DestroyCertList(certlist);
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+int
|
|
+find_named_certificate(cms_context *cms, char *name, CERTCertificate **cert)
|
|
+{
|
|
+ if (!name) {
|
|
+ cms->log(cms, LOG_ERR, "no certificate name specified");
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ secuPWData pwdata_val = { 0, 0 };
|
|
+ void *pwdata = cms->pwdata ? cms->pwdata : &pwdata_val;
|
|
+ PK11_SetPasswordFunc(cms->func ? cms->func : SECU_GetModulePassword);
|
|
+
|
|
+ PK11SlotList *slots = NULL;
|
|
+ slots = PK11_GetAllTokens(CKM_RSA_PKCS, PR_FALSE, PR_TRUE, pwdata);
|
|
+ if (!slots)
|
|
+ cmsreterr(-1, cms, "could not get pk11 token list");
|
|
+
|
|
+ PK11SlotListElement *psle = NULL;
|
|
+ psle = PK11_GetFirstSafe(slots);
|
|
+ if (!psle) {
|
|
+ save_port_err(PK11_FreeSlotList(slots));
|
|
+ cmsreterr(-1, cms, "could not get pk11 safe");
|
|
+ }
|
|
+
|
|
+ while (psle) {
|
|
+ if (!strcmp(cms->tokenname, PK11_GetTokenName(psle->slot)))
|
|
+ break;
|
|
+
|
|
+ psle = PK11_GetNextSafe(slots, psle, PR_FALSE);
|
|
+ }
|
|
+
|
|
+ if (!psle) {
|
|
+ save_port_err(PK11_FreeSlotList(slots));
|
|
+ cms->log(cms, LOG_ERR, "could not find token \"%s\"",
|
|
+ cms->tokenname);
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ SECStatus status;
|
|
+ if (PK11_NeedLogin(psle->slot) && !PK11_IsLoggedIn(psle->slot, pwdata)) {
|
|
+ status = PK11_Authenticate(psle->slot, PR_TRUE, pwdata);
|
|
+ if (status != SECSuccess) {
|
|
+ PK11_DestroySlotListElement(slots, &psle);
|
|
+ PK11_FreeSlotList(slots);
|
|
+ cms->log(cms, LOG_ERR, "authentication failed for "
|
|
+ "token \"%s\"", cms->tokenname);
|
|
+ return -1;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ CERTCertList *certlist = NULL;
|
|
+ certlist = PK11_ListCertsInSlot(psle->slot);
|
|
+ if (!certlist) {
|
|
+ save_port_err(
|
|
+ PK11_DestroySlotListElement(slots, &psle);
|
|
+ PK11_FreeSlotList(slots));
|
|
+ cmsreterr(-1, cms, "could not get certificate list");
|
|
+ }
|
|
+
|
|
+ CERTCertListNode *node = NULL;
|
|
+ for (node = CERT_LIST_HEAD(certlist); !CERT_LIST_END(node,certlist);
|
|
+ node = CERT_LIST_NEXT(node)) {
|
|
+ if (!strcmp(node->cert->subjectName, name))
|
|
+ break;
|
|
+ }
|
|
+ if (!node) {
|
|
+ PK11_DestroySlotListElement(slots, &psle);
|
|
+ PK11_FreeSlotList(slots);
|
|
+ CERT_DestroyCertList(certlist);
|
|
+
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ *cert = CERT_DupCertificate(node->cert);
|
|
+
|
|
+ PK11_DestroySlotListElement(slots, &psle);
|
|
+ PK11_FreeSlotList(slots);
|
|
CERT_DestroyCertList(certlist);
|
|
|
|
return 0;
|
|
Index: pesign-0.99/src/cms_common.h
|
|
===================================================================
|
|
--- pesign-0.99.orig/src/cms_common.h
|
|
+++ pesign-0.99/src/cms_common.h
|
|
@@ -19,9 +19,35 @@
|
|
#ifndef CMS_COMMON_H
|
|
#define CMS_COMMON_H 1
|
|
|
|
-#include <stdarg.h>
|
|
+#include <errno.h>
|
|
#include <nss3/cert.h>
|
|
#include <nss3/secpkcs7.h>
|
|
+#include <signal.h>
|
|
+#include <stdarg.h>
|
|
+#include <syslog.h>
|
|
+#include <time.h>
|
|
+#include <unistd.h>
|
|
+
|
|
+#define save_port_err(x) \
|
|
+ ({ \
|
|
+ int __saved_errno = PORT_GetError(); \
|
|
+ x; \
|
|
+ PORT_SetError(__saved_errno); \
|
|
+ })
|
|
+
|
|
+#define cmserr(rv, cms, fmt, args...) ({ \
|
|
+ (cms)->log((cms), LOG_ERR, "%s:%s:%d: " fmt ": %s", \
|
|
+ __FILE__, __func__, __LINE__, ## args, \
|
|
+ PORT_ErrorToString(PORT_GetError())); \
|
|
+ exit(rv); \
|
|
+ })
|
|
+#define cmsreterr(rv, cms, fmt, args...) ({ \
|
|
+ (cms)->log((cms), LOG_ERR, "%s:%s:%d: " fmt ": %s", \
|
|
+ __FILE__, __func__, __LINE__, ## args, \
|
|
+ PORT_ErrorToString(PORT_GetError())); \
|
|
+ return rv; \
|
|
+ })
|
|
+
|
|
|
|
struct digest {
|
|
PK11Context *pk11ctx;
|
|
@@ -109,6 +135,10 @@ extern int generate_digest(cms_context *
|
|
extern int generate_signature(cms_context *ctx);
|
|
extern int unlock_nss_token(cms_context *ctx);
|
|
extern int find_certificate(cms_context *ctx);
|
|
+extern int is_issuer_of(CERTCertificate *c0, CERTCertificate *c1);
|
|
+
|
|
+extern int find_named_certificate(cms_context *cms, char *name,
|
|
+ CERTCertificate **cert);
|
|
|
|
extern SECOidTag digest_get_digest_oid(cms_context *cms);
|
|
extern SECOidTag digest_get_encryption_oid(cms_context *cms);
|
|
Index: pesign-0.99/src/daemon.c
|
|
===================================================================
|
|
--- pesign-0.99.orig/src/daemon.c
|
|
+++ pesign-0.99/src/daemon.c
|
|
@@ -288,7 +288,8 @@ set_up_inpe(context *ctx, int fd, Pe **p
|
|
return -1;
|
|
}
|
|
|
|
- int rc = parse_signatures(ctx->cms, *pe);
|
|
+ int rc = parse_signatures(&ctx->cms->signatures,
|
|
+ &ctx->cms->num_signatures, *pe);
|
|
if (rc < 0) {
|
|
ctx->cms->log(ctx->cms, ctx->priority|LOG_ERR,
|
|
"pesignd: could not parse signature list");
|
|
@@ -454,7 +455,8 @@ err_attached:
|
|
if (rc < 0)
|
|
goto err_attached;
|
|
insert_signature(ctx->cms, ctx->cms->num_signatures);
|
|
- finalize_signatures(ctx->cms, outpe);
|
|
+ finalize_signatures(ctx->cms->signatures,
|
|
+ ctx->cms->num_signatures, outpe);
|
|
pe_end(outpe);
|
|
} else {
|
|
if (ftruncate(outfd, 0) != 0) {
|
|
Index: pesign-0.99/src/pesign.c
|
|
===================================================================
|
|
--- pesign-0.99.orig/src/pesign.c
|
|
+++ pesign-0.99/src/pesign.c
|
|
@@ -104,7 +104,8 @@ open_input(pesign_context *ctx)
|
|
exit(1);
|
|
}
|
|
|
|
- int rc = parse_signatures(ctx->cms_ctx, ctx->inpe);
|
|
+ int rc = parse_signatures(&ctx->cms_ctx->signatures,
|
|
+ &ctx->cms_ctx->num_signatures, ctx->inpe);
|
|
if (rc < 0) {
|
|
fprintf(stderr, "pesign: could not parse signature data\n");
|
|
exit(1);
|
|
@@ -126,7 +127,8 @@ close_output(pesign_context *ctx)
|
|
{
|
|
Pe_Cmd cmd = ctx->outfd == STDOUT_FILENO ? PE_C_RDWR : PE_C_RDWR_MMAP;
|
|
|
|
- finalize_signatures(ctx->cms_ctx, ctx->outpe);
|
|
+ finalize_signatures(ctx->cms_ctx->signatures,
|
|
+ ctx->cms_ctx->num_signatures, ctx->outpe);
|
|
pe_update(ctx->outpe, cmd);
|
|
pe_end(ctx->outpe);
|
|
ctx->outpe = NULL;
|
|
@@ -673,7 +675,9 @@ main(int argc, char *argv[])
|
|
allocate_signature_space(ctxp->outpe, sigspace);
|
|
generate_signature(ctxp->cms_ctx);
|
|
insert_signature(ctxp->cms_ctx, ctxp->signum);
|
|
- finalize_signatures(ctxp->cms_ctx, ctxp->outpe);
|
|
+ finalize_signatures(ctxp->cms_ctx->signatures,
|
|
+ ctxp->cms_ctx->num_signatures,
|
|
+ ctxp->outpe);
|
|
close_output(ctxp);
|
|
break;
|
|
case EXPORT_SATTRS:
|
|
@@ -687,12 +691,27 @@ main(int argc, char *argv[])
|
|
/* add a signature from a file */
|
|
case IMPORT_SIGNATURE:
|
|
check_inputs(ctxp);
|
|
+ if (ctxp->signum > ctxp->cms_ctx->num_signatures + 1) {
|
|
+ fprintf(stderr, "Invalid signature number.\n");
|
|
+ exit(1);
|
|
+ }
|
|
open_input(ctxp);
|
|
open_output(ctxp);
|
|
close_input(ctxp);
|
|
open_sig_input(ctxp);
|
|
+ parse_signature(ctxp);
|
|
+ sigspace =
|
|
+ calculate_signature_overhead(
|
|
+ ctxp->cms_ctx->newsig.len) +
|
|
+ ctxp->cms_ctx->newsig.len +
|
|
+ get_reserved_sig_space(ctxp->cms_ctx,
|
|
+ ctxp->outpe);
|
|
+ allocate_signature_space(ctxp->outpe, sigspace);
|
|
check_signature_space(ctxp);
|
|
- import_signature(ctxp);
|
|
+ insert_signature(ctxp->cms_ctx, ctxp->signum);
|
|
+ finalize_signatures(ctxp->cms_ctx->signatures,
|
|
+ ctxp->cms_ctx->num_signatures,
|
|
+ ctxp->outpe);
|
|
close_sig_input(ctxp);
|
|
close_output(ctxp);
|
|
break;
|
|
@@ -788,6 +807,10 @@ main(int argc, char *argv[])
|
|
ctxp->cms_ctx->certname);
|
|
exit(1);
|
|
}
|
|
+ if (ctxp->signum > ctxp->cms_ctx->num_signatures + 1) {
|
|
+ fprintf(stderr, "Invalid signature number.\n");
|
|
+ exit(1);
|
|
+ }
|
|
open_input(ctxp);
|
|
open_output(ctxp);
|
|
close_input(ctxp);
|
|
@@ -798,7 +821,9 @@ main(int argc, char *argv[])
|
|
generate_digest(ctxp->cms_ctx, ctxp->outpe);
|
|
generate_signature(ctxp->cms_ctx);
|
|
insert_signature(ctxp->cms_ctx, ctxp->signum);
|
|
- finalize_signatures(ctxp->cms_ctx, ctxp->outpe);
|
|
+ finalize_signatures(ctxp->cms_ctx->signatures,
|
|
+ ctxp->cms_ctx->num_signatures,
|
|
+ ctxp->outpe);
|
|
close_output(ctxp);
|
|
break;
|
|
case DAEMONIZE:
|
|
Index: pesign-0.99/src/peverify.c
|
|
===================================================================
|
|
--- pesign-0.99.orig/src/peverify.c
|
|
+++ pesign-0.99/src/peverify.c
|
|
@@ -55,9 +55,12 @@ open_input(peverify_context *ctx)
|
|
exit(1);
|
|
}
|
|
|
|
- int rc = parse_signatures(&ctx->cms_ctx, ctx->inpe);
|
|
+ int rc = parse_signatures(&ctx->cms_ctx->signatures,
|
|
+ &ctx->cms_ctx->num_signatures,
|
|
+ ctx->inpe);
|
|
if (rc < 0) {
|
|
- fprintf(stderr, "pesign: could not parse signature data\n");
|
|
+ fprintf(stderr, "pesign: could not parse signature list in "
|
|
+ "EFI binary\n");
|
|
exit(1);
|
|
}
|
|
}
|
|
Index: pesign-0.99/src/siglist.c
|
|
===================================================================
|
|
--- pesign-0.99.orig/src/siglist.c
|
|
+++ pesign-0.99/src/siglist.c
|
|
@@ -17,11 +17,15 @@
|
|
* Author(s): Peter Jones <pjones@redhat.com>
|
|
*/
|
|
|
|
+#include <stdlib.h>
|
|
#include <stdint.h>
|
|
+#include <stdio.h>
|
|
+#include <string.h>
|
|
#include <sys/param.h>
|
|
#include <errno.h>
|
|
|
|
-#include "authvar.h"
|
|
+#include "efitypes.h"
|
|
+#include "siglist.h"
|
|
|
|
struct efi_signature_data {
|
|
efi_guid_t SignatureOwner;
|
|
@@ -135,7 +139,10 @@ signature_list_add_sig(signature_list *s
|
|
if (memcmp(&sl->SignatureType, &x509_guid, sizeof (efi_guid_t)) == 0) {
|
|
if (sigsize > sl->SignatureSize)
|
|
resize_entries(sl, sigsize);
|
|
- } else if (sigsize != sl->SignatureSize) {
|
|
+ } else if (sigsize != get_sig_type_size(sl->SignatureType)) {
|
|
+ fprintf(stderr, "sigsize: %d sl->SignatureSize: %d\n",
|
|
+ sigsize, sl->SignatureSize);
|
|
+ errno = EINVAL;
|
|
return -1;
|
|
}
|
|
|
|
@@ -162,11 +169,31 @@ signature_list_add_sig(signature_list *s
|
|
return 0;
|
|
}
|
|
|
|
-void *
|
|
-signature_list_realize(signature_list *sl)
|
|
+#if 0
|
|
+int
|
|
+signature_list_parse(signature_list *sl, uint8_t *data, size_t len)
|
|
+{
|
|
+ if (!sl)
|
|
+ return -1;
|
|
+
|
|
+ if (sl->realized) {
|
|
+ free(sl->realized);
|
|
+ sl->realized = NULL;
|
|
+ }
|
|
+
|
|
+ efi_signature_list *esl = data;
|
|
+ efi_signature_data *esd = NULL;
|
|
+
|
|
+}
|
|
+#endif
|
|
+
|
|
+int
|
|
+signature_list_realize(signature_list *sl, void **out, size_t *outsize)
|
|
{
|
|
- if (sl->realized)
|
|
- return sl->realized;
|
|
+ if (sl->realized) {
|
|
+ free(sl->realized);
|
|
+ sl->realized = NULL;
|
|
+ }
|
|
|
|
struct efi_signature_list *esl = NULL;
|
|
uint32_t size = sizeof (*esl) +
|
|
@@ -174,7 +201,7 @@ signature_list_realize(signature_list *s
|
|
|
|
void *ret = calloc(1, size);
|
|
if (!ret)
|
|
- return NULL;
|
|
+ return -1;
|
|
esl = ret;
|
|
|
|
memcpy(esl, sl, sizeof (*esl));
|
|
@@ -186,7 +213,10 @@ signature_list_realize(signature_list *s
|
|
}
|
|
|
|
sl->realized = ret;
|
|
- return ret;
|
|
+
|
|
+ *out = ret;
|
|
+ *outsize = size;
|
|
+ return 0;
|
|
}
|
|
|
|
void
|
|
Index: pesign-0.99/src/siglist.h
|
|
===================================================================
|
|
--- pesign-0.99.orig/src/siglist.h
|
|
+++ pesign-0.99/src/siglist.h
|
|
@@ -24,7 +24,8 @@ typedef struct signature_list signature_
|
|
extern signature_list *signature_list_new(efi_guid_t SignatureType);
|
|
extern int signature_list_add_sig(signature_list *sl, efi_guid_t owner,
|
|
uint8_t *sig, uint32_t sigsize);
|
|
-extern void *signature_list_realize(signature_list *sl);
|
|
+extern int signature_list_realize(signature_list *sl,
|
|
+ void **out, size_t *outsize);
|
|
extern void signature_list_free(signature_list *sl);
|
|
|
|
#endif /* SIGLIST_H */
|
|
Index: pesign-0.99/src/signed_data.c
|
|
===================================================================
|
|
--- pesign-0.99.orig/src/signed_data.c
|
|
+++ pesign-0.99/src/signed_data.c
|
|
@@ -76,20 +76,53 @@ static int
|
|
generate_certificate_list(cms_context *cms, SECItem ***certificate_list_p)
|
|
{
|
|
SECItem **certificates = NULL;
|
|
+ void *mark = PORT_ArenaMark(cms->arena);
|
|
|
|
- certificates = PORT_ArenaZAlloc(cms->arena, sizeof (SECItem *) * 2);
|
|
- if (!certificates)
|
|
- return -1;
|
|
-
|
|
- certificates[0] = PORT_ArenaZAlloc(cms->arena, sizeof (SECItem));
|
|
- if (!certificates[0]) {
|
|
- int err = PORT_GetError();
|
|
- PORT_ZFree(certificates, sizeof (SECItem) * 2);
|
|
- PORT_SetError(err);
|
|
- return -1;
|
|
+ certificates = PORT_ArenaZAlloc(cms->arena, sizeof (SECItem *) * 3);
|
|
+ if (!certificates) {
|
|
+ save_port_err(PORT_ArenaRelease(cms->arena, mark));
|
|
+ cmsreterr(-1, cms, "could not allocate certificate list");
|
|
}
|
|
+ int i = 0;
|
|
+
|
|
+ certificates[i] = PORT_ArenaZAlloc(cms->arena, sizeof (SECItem));
|
|
+ if (!certificates[i]) {
|
|
+ save_port_err(PORT_ArenaRelease(cms->arena, mark));
|
|
+ cmsreterr(-1, cms, "could not allocate certificate entry");
|
|
+ }
|
|
+ SECITEM_CopyItem(cms->arena, certificates[i++], &cms->cert->derCert);
|
|
+
|
|
+#if 0
|
|
+ if (!is_issuer_of(cms->cert, cms->cert)) {
|
|
+ CERTCertificate *signer = NULL;
|
|
+ int rc = find_named_certificate(cms, cms->cert->issuerName,
|
|
+ &signer);
|
|
+ if (rc < 0) {
|
|
+ PORT_ArenaRelease(cms->arena, mark);
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ if (signer) {
|
|
+ if (signer->derCert.len != cms->cert->derCert.len ||
|
|
+ memcmp(signer->derCert.data,
|
|
+ cms->cert->derCert.data,
|
|
+ signer->derCert.len)) {
|
|
+ certificates[i] = PORT_ArenaZAlloc(cms->arena,
|
|
+ sizeof (SECItem));
|
|
+ if (!certificates[i]) {
|
|
+ save_port_err(
|
|
+ PORT_ArenaRelease(cms->arena, mark));
|
|
+ cmsreterr(-1, cms,"could not allocate "
|
|
+ "certificate entry");
|
|
+ }
|
|
+ SECITEM_CopyItem(cms->arena, certificates[i++],
|
|
+ &signer->derCert);
|
|
+ }
|
|
+ CERT_DestroyCertificate(signer);
|
|
+ }
|
|
+ }
|
|
+#endif
|
|
|
|
- SECITEM_CopyItem(cms->arena, certificates[0], &cms->cert->derCert);
|
|
*certificate_list_p = certificates;
|
|
return 0;
|
|
}
|
|
Index: pesign-0.99/src/wincert.c
|
|
===================================================================
|
|
--- pesign-0.99.orig/src/wincert.c
|
|
+++ pesign-0.99/src/wincert.c
|
|
@@ -25,13 +25,13 @@ struct cert_list_entry {
|
|
};
|
|
|
|
static int
|
|
-generate_cert_list(cms_context *cms, void **cert_list,
|
|
- size_t *cert_list_size)
|
|
+generate_cert_list(SECItem **signatures, int num_signatures,
|
|
+ void **cert_list, size_t *cert_list_size)
|
|
{
|
|
size_t cl_size = 0;
|
|
- for (int i = 0; i < cms->num_signatures; i++) {
|
|
+ for (int i = 0; i < num_signatures; i++) {
|
|
cl_size += sizeof (win_certificate);
|
|
- cl_size += cms->signatures[i]->len;
|
|
+ cl_size += signatures[i]->len;
|
|
}
|
|
|
|
uint8_t *data = malloc(cl_size);
|
|
@@ -41,15 +41,15 @@ generate_cert_list(cms_context *cms, voi
|
|
*cert_list = (void *)data;
|
|
*cert_list_size = cl_size;
|
|
|
|
- for (int i = 0; i < cms->num_signatures; i++) {
|
|
+ for (int i = 0; i < num_signatures; i++) {
|
|
struct cert_list_entry *cle = (struct cert_list_entry *)data;
|
|
- cle->wc.length = cms->signatures[i]->len +
|
|
+ cle->wc.length = signatures[i]->len +
|
|
sizeof (win_certificate);
|
|
cle->wc.revision = WIN_CERT_REVISION_2_0;
|
|
cle->wc.cert_type = WIN_CERT_TYPE_PKCS_SIGNED_DATA;
|
|
- memcpy(&cle->data[0], cms->signatures[i]->data,
|
|
- cms->signatures[i]->len);
|
|
- data += sizeof (win_certificate) + cms->signatures[i]->len;
|
|
+ memcpy(&cle->data[0], signatures[i]->data,
|
|
+ signatures[i]->len);
|
|
+ data += sizeof (win_certificate) + signatures[i]->len;
|
|
}
|
|
|
|
return 0;
|
|
@@ -62,12 +62,13 @@ implant_cert_list(Pe *pe, void *cert_lis
|
|
}
|
|
|
|
int
|
|
-finalize_signatures(cms_context *cms, Pe *pe)
|
|
+finalize_signatures(SECItem **sigs, int num_sigs, Pe *pe)
|
|
{
|
|
void *clist = NULL;
|
|
size_t clist_size = 0;
|
|
|
|
- if (generate_cert_list(cms, &clist, &clist_size) < 0)
|
|
+ if (generate_cert_list(sigs, num_sigs,
|
|
+ &clist, &clist_size) < 0)
|
|
return -1;
|
|
|
|
if (implant_cert_list(pe, clist, clist_size) < 0) {
|
|
@@ -126,6 +127,13 @@ done:
|
|
void *certs = iter->certs;
|
|
size_t size = iter->size;
|
|
|
|
+ void *map = NULL;
|
|
+ size_t map_size = 0;
|
|
+
|
|
+ map = pe_rawfile(iter->pe, &map_size);
|
|
+ if (!map || map_size < 1)
|
|
+ return 0;
|
|
+
|
|
while (1) {
|
|
win_certificate *tmpcert;
|
|
if (n + sizeof (*tmpcert) >= size)
|
|
@@ -133,6 +141,9 @@ done:
|
|
|
|
tmpcert = (win_certificate *)((uint8_t *)certs + n);
|
|
|
|
+ if ((intptr_t)tmpcert > (intptr_t)map + map_size)
|
|
+ return -1;
|
|
+
|
|
/* length _includes_ the size of the structure. */
|
|
uint32_t length = le32_to_cpu(tmpcert->length);
|
|
|
|
@@ -193,7 +204,23 @@ available_cert_space(Pe *pe)
|
|
return totalsize - foundsize;
|
|
}
|
|
|
|
-ssize_t calculate_signature_space(cms_context *cms, Pe *pe)
|
|
+size_t
|
|
+get_reserved_sig_space(cms_context *cms, Pe *pe)
|
|
+{
|
|
+ size_t ret = 0;
|
|
+ for (int i = 0; i < cms->num_signatures; i++)
|
|
+ ret += cms->signatures[i]->len + sizeof (win_certificate);
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+ssize_t
|
|
+calculate_signature_overhead(ssize_t size)
|
|
+{
|
|
+ return sizeof(win_certificate);
|
|
+}
|
|
+
|
|
+ssize_t
|
|
+calculate_signature_space(cms_context *cms, Pe *pe)
|
|
{
|
|
int rc;
|
|
|
|
@@ -209,7 +236,9 @@ err:
|
|
if (rc < 0)
|
|
goto err;
|
|
|
|
- ssize_t ret = sig.len + dd->certs.size + sizeof(win_certificate) -
|
|
+ size_t res = get_reserved_sig_space(cms, pe);
|
|
+
|
|
+ ssize_t ret = res + sig.len + sizeof(win_certificate) -
|
|
available_cert_space(pe);
|
|
|
|
//free(sig.data);
|
|
@@ -218,7 +247,7 @@ err:
|
|
}
|
|
|
|
int
|
|
-parse_signatures(cms_context *cms, Pe *pe)
|
|
+parse_signatures(SECItem ***sigs, int *num_sigs, Pe *pe)
|
|
{
|
|
cert_iter iter;
|
|
int rc = cert_iter_init(&iter, pe);
|
|
@@ -238,8 +267,8 @@ parse_signatures(cms_context *cms, Pe *p
|
|
}
|
|
|
|
if (nsigs == 0) {
|
|
- cms->num_signatures = 0;
|
|
- cms->signatures = NULL;
|
|
+ *num_sigs = 0;
|
|
+ *sigs = NULL;
|
|
return 0;
|
|
}
|
|
|
|
@@ -271,8 +300,8 @@ parse_signatures(cms_context *cms, Pe *p
|
|
i++;
|
|
}
|
|
|
|
- cms->num_signatures = nsigs;
|
|
- cms->signatures = signatures;
|
|
+ *num_sigs = nsigs;
|
|
+ *sigs = signatures;
|
|
|
|
return 0;
|
|
err:
|
|
Index: pesign-0.99/src/wincert.h
|
|
===================================================================
|
|
--- pesign-0.99.orig/src/wincert.h
|
|
+++ pesign-0.99/src/wincert.h
|
|
@@ -32,8 +32,6 @@ typedef struct win_certificate {
|
|
uint16_t cert_type;
|
|
} win_certificate;
|
|
|
|
-extern int finalize_signatures(cms_context *cms, Pe *pe);
|
|
-
|
|
typedef struct cert_iter {
|
|
Pe *pe;
|
|
off_t n;
|
|
@@ -45,6 +43,10 @@ extern int cert_iter_init(cert_iter *ite
|
|
extern int next_cert(cert_iter *iter, void **cert, ssize_t *cert_size);
|
|
extern ssize_t available_cert_space(Pe *pe);
|
|
extern ssize_t calculate_signature_space(cms_context *cms, Pe *pe);
|
|
-extern int parse_signatures(cms_context *cms, Pe *pe);
|
|
+extern int parse_signatures(SECItem ***sigs, int *num_sigs, Pe *pe);
|
|
+extern int finalize_signatures(SECItem **sigs, int num_sigs, Pe *pe);
|
|
+extern size_t get_reserved_sig_space(cms_context *cms, Pe *pe);
|
|
+extern ssize_t calculate_signature_overhead(ssize_t size);
|
|
+
|
|
|
|
#endif /* PESIGN_WINCERT_H */
|