mirror of
https://github.com/mtrojnar/osslsigncode.git
synced 2025-05-20 18:34:29 -05:00
Merge remote-tracking branch 'elmarco/master'
This commit is contained in:
commit
2d8764f8f9
@ -8,9 +8,9 @@ MAINTAINERCLEANFILES = \
|
|||||||
$(srcdir)/config.guess $(srcdir)/config.sub
|
$(srcdir)/config.guess $(srcdir)/config.sub
|
||||||
EXTRA_DIST = .gitignore
|
EXTRA_DIST = .gitignore
|
||||||
|
|
||||||
AM_CFLAGS = $(OPENSSL_CFLAGS) $(OPTIONAL_LIBCURL_CFLAGS)
|
AM_CFLAGS = $(GSF_CFLAGS) $(OPENSSL_CFLAGS) $(OPTIONAL_LIBCURL_CFLAGS)
|
||||||
|
|
||||||
bin_PROGRAMS = osslsigncode
|
bin_PROGRAMS = osslsigncode
|
||||||
|
|
||||||
osslsigncode_SOURCES = osslsigncode.c
|
osslsigncode_SOURCES = osslsigncode.c
|
||||||
osslsigncode_LDADD = $(OPENSSL_LIBS) $(OPTIONAL_LIBCURL_LIBS)
|
osslsigncode_LDADD = $(GSF_LIBS) $(OPENSSL_LIBS) $(OPTIONAL_LIBCURL_LIBS)
|
||||||
|
102
config.h.in
102
config.h.in
@ -1,102 +0,0 @@
|
|||||||
/* config.h.in. Generated from configure.ac by autoheader. */
|
|
||||||
|
|
||||||
/* libcurl is enabled */
|
|
||||||
#undef ENABLE_CURL
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
|
||||||
#undef HAVE_INTTYPES_H
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <memory.h> header file. */
|
|
||||||
#undef HAVE_MEMORY_H
|
|
||||||
|
|
||||||
/* Define to 1 if you have mmap */
|
|
||||||
#undef HAVE_MMAP
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <stdint.h> header file. */
|
|
||||||
#undef HAVE_STDINT_H
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <stdlib.h> header file. */
|
|
||||||
#undef HAVE_STDLIB_H
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <strings.h> header file. */
|
|
||||||
#undef HAVE_STRINGS_H
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <string.h> header file. */
|
|
||||||
#undef HAVE_STRING_H
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <sys/mman.h> header file. */
|
|
||||||
#undef HAVE_SYS_MMAN_H
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <sys/stat.h> header file. */
|
|
||||||
#undef HAVE_SYS_STAT_H
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
|
||||||
#undef HAVE_SYS_TYPES_H
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <unistd.h> header file. */
|
|
||||||
#undef HAVE_UNISTD_H
|
|
||||||
|
|
||||||
/* Name of package */
|
|
||||||
#undef PACKAGE
|
|
||||||
|
|
||||||
/* Define to the address where bug reports for this package should be sent. */
|
|
||||||
#undef PACKAGE_BUGREPORT
|
|
||||||
|
|
||||||
/* Define to the full name of this package. */
|
|
||||||
#undef PACKAGE_NAME
|
|
||||||
|
|
||||||
/* Define to the full name and version of this package. */
|
|
||||||
#undef PACKAGE_STRING
|
|
||||||
|
|
||||||
/* Define to the one symbol short name of this package. */
|
|
||||||
#undef PACKAGE_TARNAME
|
|
||||||
|
|
||||||
/* Define to the home page for this package. */
|
|
||||||
#undef PACKAGE_URL
|
|
||||||
|
|
||||||
/* Define to the version of this package. */
|
|
||||||
#undef PACKAGE_VERSION
|
|
||||||
|
|
||||||
/* Define to 1 if you have the ANSI C header files. */
|
|
||||||
#undef STDC_HEADERS
|
|
||||||
|
|
||||||
/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
|
|
||||||
#undef TIME_WITH_SYS_TIME
|
|
||||||
|
|
||||||
/* Enable extensions on AIX 3, Interix. */
|
|
||||||
#ifndef _ALL_SOURCE
|
|
||||||
# undef _ALL_SOURCE
|
|
||||||
#endif
|
|
||||||
/* Enable GNU extensions on systems that have them. */
|
|
||||||
#ifndef _GNU_SOURCE
|
|
||||||
# undef _GNU_SOURCE
|
|
||||||
#endif
|
|
||||||
/* Enable threading extensions on Solaris. */
|
|
||||||
#ifndef _POSIX_PTHREAD_SEMANTICS
|
|
||||||
# undef _POSIX_PTHREAD_SEMANTICS
|
|
||||||
#endif
|
|
||||||
/* Enable extensions on HP NonStop. */
|
|
||||||
#ifndef _TANDEM_SOURCE
|
|
||||||
# undef _TANDEM_SOURCE
|
|
||||||
#endif
|
|
||||||
/* Enable general extensions on Solaris. */
|
|
||||||
#ifndef __EXTENSIONS__
|
|
||||||
# undef __EXTENSIONS__
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* Version number of package */
|
|
||||||
#undef VERSION
|
|
||||||
|
|
||||||
/* Define to 1 if on MINIX. */
|
|
||||||
#undef _MINIX
|
|
||||||
|
|
||||||
/* Define to 2 if the system does not provide POSIX.1 features except with
|
|
||||||
this defined. */
|
|
||||||
#undef _POSIX_1_SOURCE
|
|
||||||
|
|
||||||
/* Define to 1 if you need to in order for `stat' and other things to work. */
|
|
||||||
#undef _POSIX_SOURCE
|
|
||||||
|
|
||||||
/* Define to empty if `const' does not conform to ANSI C. */
|
|
||||||
#undef const
|
|
14
configure.ac
14
configure.ac
@ -68,6 +68,20 @@ AC_CHECK_LIB(
|
|||||||
[DL_LIBS="-ldl"]
|
[DL_LIBS="-ldl"]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
AC_ARG_WITH([gsf],
|
||||||
|
AS_HELP_STRING([--without-gsf], [Ignore presence of libgsf and disable it])
|
||||||
|
)
|
||||||
|
AS_IF([test "x$with_gsf" != "xno"],
|
||||||
|
[PKG_CHECK_MODULES([GSF], [libgsf-1], [have_gsf=yes], [have_gsf=no])],
|
||||||
|
[have_gsf=no]
|
||||||
|
)
|
||||||
|
AS_IF([test "x$have_gsf" = "xyes"],
|
||||||
|
[AC_DEFINE([WITH_GSF], 1, [Have libgsf?])],
|
||||||
|
[AS_IF([test "x$with_gsf" = "xyes"],
|
||||||
|
[AC_MSG_ERROR([libgsf requested but not found])])]
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
PKG_CHECK_MODULES(
|
PKG_CHECK_MODULES(
|
||||||
[OPENSSL],
|
[OPENSSL],
|
||||||
[libcrypto >= 0.9.8],
|
[libcrypto >= 0.9.8],
|
||||||
|
297
osslsigncode.c
297
osslsigncode.c
@ -58,6 +58,16 @@ static const char *rcsid = "$Id: osslsigncode.c,v 1.4 2011/08/12 11:08:12 mfive
|
|||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef WITH_GSF
|
||||||
|
#include <gsf/gsf-infile-msole.h>
|
||||||
|
#include <gsf/gsf-infile.h>
|
||||||
|
#include <gsf/gsf-input-stdio.h>
|
||||||
|
#include <gsf/gsf-outfile-msole.h>
|
||||||
|
#include <gsf/gsf-outfile.h>
|
||||||
|
#include <gsf/gsf-output-stdio.h>
|
||||||
|
#include <gsf/gsf-utils.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <openssl/err.h>
|
#include <openssl/err.h>
|
||||||
#include <openssl/objects.h>
|
#include <openssl/objects.h>
|
||||||
#include <openssl/evp.h>
|
#include <openssl/evp.h>
|
||||||
@ -81,7 +91,7 @@ static const char *rcsid = "$Id: osslsigncode.c,v 1.4 2011/08/12 11:08:12 mfive
|
|||||||
#define SPC_PE_IMAGE_DATA_OBJID "1.3.6.1.4.1.311.2.1.15"
|
#define SPC_PE_IMAGE_DATA_OBJID "1.3.6.1.4.1.311.2.1.15"
|
||||||
#define SPC_CAB_DATA_OBJID "1.3.6.1.4.1.311.2.1.25"
|
#define SPC_CAB_DATA_OBJID "1.3.6.1.4.1.311.2.1.25"
|
||||||
#define SPC_TIME_STAMP_REQUEST_OBJID "1.3.6.1.4.1.311.3.2.1"
|
#define SPC_TIME_STAMP_REQUEST_OBJID "1.3.6.1.4.1.311.3.2.1"
|
||||||
|
#define SPC_SIPINFO_OBJID "1.3.6.1.4.1.311.2.1.30"
|
||||||
/* 1.3.6.1.4.1.311.4... MS Crypto 2.0 stuff... */
|
/* 1.3.6.1.4.1.311.4... MS Crypto 2.0 stuff... */
|
||||||
|
|
||||||
|
|
||||||
@ -212,6 +222,28 @@ ASN1_SEQUENCE(SpcPeImageData) = {
|
|||||||
|
|
||||||
IMPLEMENT_ASN1_FUNCTIONS(SpcPeImageData)
|
IMPLEMENT_ASN1_FUNCTIONS(SpcPeImageData)
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
ASN1_INTEGER *a;
|
||||||
|
ASN1_OCTET_STRING *string;
|
||||||
|
ASN1_INTEGER *b;
|
||||||
|
ASN1_INTEGER *c;
|
||||||
|
ASN1_INTEGER *d;
|
||||||
|
ASN1_INTEGER *e;
|
||||||
|
ASN1_INTEGER *f;
|
||||||
|
} SpcSipinfo;
|
||||||
|
|
||||||
|
ASN1_SEQUENCE(SpcSipinfo) = {
|
||||||
|
ASN1_SIMPLE(SpcSipinfo, a, ASN1_INTEGER),
|
||||||
|
ASN1_SIMPLE(SpcSipinfo, string, ASN1_OCTET_STRING),
|
||||||
|
ASN1_SIMPLE(SpcSipinfo, b, ASN1_INTEGER),
|
||||||
|
ASN1_SIMPLE(SpcSipinfo, c, ASN1_INTEGER),
|
||||||
|
ASN1_SIMPLE(SpcSipinfo, d, ASN1_INTEGER),
|
||||||
|
ASN1_SIMPLE(SpcSipinfo, e, ASN1_INTEGER),
|
||||||
|
ASN1_SIMPLE(SpcSipinfo, f, ASN1_INTEGER),
|
||||||
|
} ASN1_SEQUENCE_END(SpcSipinfo)
|
||||||
|
|
||||||
|
IMPLEMENT_ASN1_FUNCTIONS(SpcSipinfo)
|
||||||
|
|
||||||
#ifdef ENABLE_CURL
|
#ifdef ENABLE_CURL
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@ -472,14 +504,23 @@ ASN1_TYPE *PKCS7_get_signed_attribute(PKCS7_SIGNER_INFO *si, int nid)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
enum {
|
||||||
|
FILE_TYPE_CAB,
|
||||||
|
FILE_TYPE_PE,
|
||||||
|
FILE_TYPE_MSI,
|
||||||
|
};
|
||||||
|
|
||||||
static void get_indirect_data_blob(u_char **blob, int *len, const EVP_MD *md, int isjava)
|
static void get_indirect_data_blob(u_char **blob, int *len, const EVP_MD *md, int type)
|
||||||
{
|
{
|
||||||
static const unsigned char obsolete[] = {
|
static const unsigned char obsolete[] = {
|
||||||
0x00, 0x3c, 0x00, 0x3c, 0x00, 0x3c, 0x00, 0x4f, 0x00, 0x62,
|
0x00, 0x3c, 0x00, 0x3c, 0x00, 0x3c, 0x00, 0x4f, 0x00, 0x62,
|
||||||
0x00, 0x73, 0x00, 0x6f, 0x00, 0x6c, 0x00, 0x65, 0x00, 0x74,
|
0x00, 0x73, 0x00, 0x6f, 0x00, 0x6c, 0x00, 0x65, 0x00, 0x74,
|
||||||
0x00, 0x65, 0x00, 0x3e, 0x00, 0x3e, 0x00, 0x3e
|
0x00, 0x65, 0x00, 0x3e, 0x00, 0x3e, 0x00, 0x3e
|
||||||
};
|
};
|
||||||
|
static const unsigned char msistr[] = {
|
||||||
|
0xf1, 0x10, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46
|
||||||
|
};
|
||||||
|
|
||||||
u_char *p;
|
u_char *p;
|
||||||
int hashlen, l;
|
int hashlen, l;
|
||||||
@ -487,7 +528,6 @@ static void get_indirect_data_blob(u_char **blob, int *len, const EVP_MD *md, in
|
|||||||
SpcLink *link;
|
SpcLink *link;
|
||||||
SpcIndirectDataContent *idc = SpcIndirectDataContent_new();
|
SpcIndirectDataContent *idc = SpcIndirectDataContent_new();
|
||||||
idc->data = SpcAttributeTypeAndOptionalValue_new();
|
idc->data = SpcAttributeTypeAndOptionalValue_new();
|
||||||
idc->data->type = OBJ_txt2obj(isjava ? SPC_CAB_DATA_OBJID : SPC_PE_IMAGE_DATA_OBJID, 1);
|
|
||||||
|
|
||||||
link = SpcLink_new();
|
link = SpcLink_new();
|
||||||
link->type = 2;
|
link->type = 2;
|
||||||
@ -499,12 +539,12 @@ static void get_indirect_data_blob(u_char **blob, int *len, const EVP_MD *md, in
|
|||||||
idc->data->value = ASN1_TYPE_new();
|
idc->data->value = ASN1_TYPE_new();
|
||||||
idc->data->value->type = V_ASN1_SEQUENCE;
|
idc->data->value->type = V_ASN1_SEQUENCE;
|
||||||
idc->data->value->value.sequence = ASN1_STRING_new();
|
idc->data->value->value.sequence = ASN1_STRING_new();
|
||||||
if (isjava) {
|
if (type == FILE_TYPE_CAB) {
|
||||||
l = i2d_SpcLink(link, NULL);
|
l = i2d_SpcLink(link, NULL);
|
||||||
p = OPENSSL_malloc(l);
|
p = OPENSSL_malloc(l);
|
||||||
i2d_SpcLink(link, &p);
|
i2d_SpcLink(link, &p);
|
||||||
p -= l;
|
p -= l;
|
||||||
} else {
|
} else if (type == FILE_TYPE_PE) {
|
||||||
SpcPeImageData *pid = SpcPeImageData_new();
|
SpcPeImageData *pid = SpcPeImageData_new();
|
||||||
pid->flags = ASN1_BIT_STRING_new();
|
pid->flags = ASN1_BIT_STRING_new();
|
||||||
ASN1_BIT_STRING_set(pid->flags, (unsigned char*)"0", 0);
|
ASN1_BIT_STRING_set(pid->flags, (unsigned char*)"0", 0);
|
||||||
@ -513,7 +553,28 @@ static void get_indirect_data_blob(u_char **blob, int *len, const EVP_MD *md, in
|
|||||||
p = OPENSSL_malloc(l);
|
p = OPENSSL_malloc(l);
|
||||||
i2d_SpcPeImageData(pid, &p);
|
i2d_SpcPeImageData(pid, &p);
|
||||||
p -= l;
|
p -= l;
|
||||||
|
idc->data->type = OBJ_txt2obj(SPC_PE_IMAGE_DATA_OBJID, 1);
|
||||||
|
} else if (type == FILE_TYPE_MSI) {
|
||||||
|
SpcSipinfo *si = SpcSipinfo_new();
|
||||||
|
|
||||||
|
si->a = ASN1_INTEGER_new();
|
||||||
|
ASN1_INTEGER_set(si->a, 1);
|
||||||
|
si->string = M_ASN1_OCTET_STRING_new();
|
||||||
|
M_ASN1_OCTET_STRING_set(si->string, msistr, sizeof(msistr));
|
||||||
|
si->b = ASN1_INTEGER_new();
|
||||||
|
si->c = ASN1_INTEGER_new();
|
||||||
|
si->d = ASN1_INTEGER_new();
|
||||||
|
si->e = ASN1_INTEGER_new();
|
||||||
|
si->f = ASN1_INTEGER_new();
|
||||||
|
l = i2d_SpcSipinfo(si, NULL);
|
||||||
|
p = OPENSSL_malloc(l);
|
||||||
|
i2d_SpcSipinfo(si, &p);
|
||||||
|
p -= l;
|
||||||
|
idc->data->type = OBJ_txt2obj(SPC_SIPINFO_OBJID, 1);
|
||||||
|
} else {
|
||||||
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
idc->data->value->value.sequence->data = p;
|
idc->data->value->value.sequence->data = p;
|
||||||
idc->data->value->value.sequence->length = l;
|
idc->data->value->value.sequence->length = l;
|
||||||
idc->messageDigest = DigestInfo_new();
|
idc->messageDigest = DigestInfo_new();
|
||||||
@ -560,6 +621,77 @@ static void recalc_pe_checksum(BIO *outdata, unsigned int peheader)
|
|||||||
BIO_write(outdata, &checkSum, 4);
|
BIO_write(outdata, &checkSum, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef WITH_GSF
|
||||||
|
static gint msi_base64_decode(gint x)
|
||||||
|
{
|
||||||
|
if (x < 10)
|
||||||
|
return x + '0';
|
||||||
|
if (x < (10 + 26))
|
||||||
|
return x - 10 + 'A';
|
||||||
|
if (x < (10 + 26 + 26))
|
||||||
|
return x - 10 - 26 + 'a';
|
||||||
|
if (x == (10 + 26 + 26))
|
||||||
|
return '.';
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void msi_decode(const guint8 *in, gchar *out)
|
||||||
|
{
|
||||||
|
guint count = 0;
|
||||||
|
guint8 *q = (guint8 *)out;
|
||||||
|
|
||||||
|
/* utf-8 encoding of 0x4840 */
|
||||||
|
if (in[0] == 0xe4 && in[1] == 0xa1 && in[2] == 0x80)
|
||||||
|
in += 3;
|
||||||
|
|
||||||
|
while (*in) {
|
||||||
|
guint8 ch = *in;
|
||||||
|
if ((ch == 0xe3 && in[1] >= 0xa0) || (ch == 0xe4 && in[1] < 0xa0)) {
|
||||||
|
*q++ = msi_base64_decode(in[2] & 0x7f);
|
||||||
|
*q++ = msi_base64_decode(in[1] ^ 0xa0);
|
||||||
|
in += 3;
|
||||||
|
count += 2;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (ch == 0xe4 && in[1] == 0xa0) {
|
||||||
|
*q++ = msi_base64_decode(in[2] & 0x7f);
|
||||||
|
in += 3;
|
||||||
|
count++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
*q++ = *in++;
|
||||||
|
if (ch >= 0xc1)
|
||||||
|
*q++ = *in++;
|
||||||
|
if (ch >= 0xe0)
|
||||||
|
*q++ = *in++;
|
||||||
|
if (ch >= 0xf0)
|
||||||
|
*q++ = *in++;
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
*q = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Sorry if this code looks a bit silly, but that seems
|
||||||
|
* to be the best solution so far...
|
||||||
|
*/
|
||||||
|
static gint msi_cmp(gpointer a, gpointer b)
|
||||||
|
{
|
||||||
|
gchar *pa = (gchar*)g_utf8_to_utf16(a, -1, NULL, NULL, NULL);
|
||||||
|
gchar *pb = (gchar*)g_utf8_to_utf16(b, -1, NULL, NULL, NULL);
|
||||||
|
gint diff;
|
||||||
|
|
||||||
|
diff = memcmp(pa, pb, MIN(strlen(pa), strlen(pb)));
|
||||||
|
/* apparently the longer wins */
|
||||||
|
if (diff == 0)
|
||||||
|
return strlen(pa) > strlen(pb) ? 1 : -1;
|
||||||
|
g_free(pa);
|
||||||
|
g_free(pb);
|
||||||
|
|
||||||
|
return diff;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
BIO *btmp, *sigdata, *hash, *outdata;
|
BIO *btmp, *sigdata, *hash, *outdata;
|
||||||
@ -581,10 +713,16 @@ int main(int argc, char **argv)
|
|||||||
char *turl = NULL, *proxy = NULL;
|
char *turl = NULL, *proxy = NULL;
|
||||||
#endif
|
#endif
|
||||||
u_char *p;
|
u_char *p;
|
||||||
int i, len = 0, is_cabinet = 0, jp = -1, fd = -1, pe32plus = 0, comm = 0;
|
int i, len = 0, type = 0, jp = -1, fd = -1, pe32plus = 0, comm = 0;
|
||||||
unsigned int tmp, peheader = 0, padlen;
|
unsigned int tmp, peheader = 0, padlen;
|
||||||
struct stat st;
|
struct stat st;
|
||||||
|
|
||||||
|
#ifdef WITH_GSF
|
||||||
|
GsfOutfile *outole;
|
||||||
|
GsfOutput *sink;
|
||||||
|
gsf_init();
|
||||||
|
#endif
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
static u_char spcIndirectDataContext_blob_cab[] = {
|
static u_char spcIndirectDataContext_blob_cab[] = {
|
||||||
0x30, 0x50,
|
0x30, 0x50,
|
||||||
@ -630,6 +768,9 @@ int main(int argc, char **argv)
|
|||||||
0x30, 0x0c,
|
0x30, 0x0c,
|
||||||
0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x02, 0x01, 0x16
|
0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x02, 0x01, 0x16
|
||||||
};
|
};
|
||||||
|
static u_char msi_signature[] = {
|
||||||
|
0xd0, 0xcf, 0x11, 0xe0, 0xa1, 0xb1, 0x1a, 0xe1
|
||||||
|
};
|
||||||
|
|
||||||
spcfile = keyfile = pkcs12file = infile = outfile = desc = url = NULL;
|
spcfile = keyfile = pkcs12file = infile = outfile = desc = url = NULL;
|
||||||
hash = outdata = NULL;
|
hash = outdata = NULL;
|
||||||
@ -682,16 +823,28 @@ int main(int argc, char **argv)
|
|||||||
proxy = *(++argv);
|
proxy = *(++argv);
|
||||||
#endif
|
#endif
|
||||||
} else if (!strcmp(*argv, "-v") || !strcmp(*argv, "--version")) {
|
} else if (!strcmp(*argv, "-v") || !strcmp(*argv, "--version")) {
|
||||||
printf(PACKAGE_STRING ", using:\n\t%s\n\t%s\n\nPlease send bug-reports to "
|
printf(PACKAGE_STRING ", using:\n\t%s\n\t%s\n",
|
||||||
PACKAGE_BUGREPORT
|
|
||||||
"\n\n",
|
|
||||||
SSLeay_version(SSLEAY_VERSION),
|
SSLeay_version(SSLEAY_VERSION),
|
||||||
#ifdef ENABLE_CURL
|
#ifdef ENABLE_CURL
|
||||||
curl_version()
|
curl_version()
|
||||||
#else
|
#else
|
||||||
"no libcurl available"
|
"no libcurl available"
|
||||||
|
#endif
|
||||||
|
);
|
||||||
|
printf(
|
||||||
|
#ifdef WITH_GSF
|
||||||
|
"\tlibgsf %d.%d.%d\n",
|
||||||
|
libgsf_major_version,
|
||||||
|
libgsf_minor_version,
|
||||||
|
libgsf_micro_version
|
||||||
|
#else
|
||||||
|
"\tno libgsf available\n"
|
||||||
#endif
|
#endif
|
||||||
);
|
);
|
||||||
|
printf("\nPlease send bug-reports to "
|
||||||
|
PACKAGE_BUGREPORT
|
||||||
|
"\n\n");
|
||||||
|
|
||||||
} else if (!strcmp(*argv, "-jp")) {
|
} else if (!strcmp(*argv, "-jp")) {
|
||||||
char *ap;
|
char *ap;
|
||||||
if (--argc < 1) usage(argv0);
|
if (--argc < 1) usage(argv0);
|
||||||
@ -757,16 +910,23 @@ int main(int argc, char **argv)
|
|||||||
DO_EXIT_1("Failed to open file: %s\n", infile);
|
DO_EXIT_1("Failed to open file: %s\n", infile);
|
||||||
|
|
||||||
if (!memcmp(indata, "MSCF", 4))
|
if (!memcmp(indata, "MSCF", 4))
|
||||||
is_cabinet = 1;
|
type = FILE_TYPE_CAB;
|
||||||
else if (memcmp(indata, "MZ", 2))
|
else if (!memcmp(indata, "MZ", 2))
|
||||||
|
type = FILE_TYPE_PE;
|
||||||
|
else if (!memcmp(indata, msi_signature, sizeof(msi_signature)))
|
||||||
|
type = FILE_TYPE_MSI;
|
||||||
|
else
|
||||||
DO_EXIT_1("Unrecognized file type: %s\n", infile);
|
DO_EXIT_1("Unrecognized file type: %s\n", infile);
|
||||||
|
|
||||||
if (is_cabinet) {
|
hash = BIO_new(BIO_f_md());
|
||||||
|
BIO_set_md(hash, md);
|
||||||
|
|
||||||
|
if (type == FILE_TYPE_CAB) {
|
||||||
if (st.st_size < 44)
|
if (st.st_size < 44)
|
||||||
DO_EXIT_1("Corrupt cab file - too short: %s\n", infile);
|
DO_EXIT_1("Corrupt cab file - too short: %s\n", infile);
|
||||||
if (indata[0x1e] != 0x00 || indata[0x1f] != 0x00)
|
if (indata[0x1e] != 0x00 || indata[0x1f] != 0x00)
|
||||||
DO_EXIT_0("Cannot sign cab files with flag bits set!\n"); /* XXX */
|
DO_EXIT_0("Cannot sign cab files with flag bits set!\n"); /* XXX */
|
||||||
} else {
|
} else if (type == FILE_TYPE_PE) {
|
||||||
if (st.st_size < 64)
|
if (st.st_size < 64)
|
||||||
DO_EXIT_1("Corrupt DOS file - too short: %s\n", infile);
|
DO_EXIT_1("Corrupt DOS file - too short: %s\n", infile);
|
||||||
peheader = GET_UINT32_LE(indata+60);
|
peheader = GET_UINT32_LE(indata+60);
|
||||||
@ -774,18 +934,83 @@ int main(int argc, char **argv)
|
|||||||
DO_EXIT_1("Corrupt PE file - too short: %s\n", infile);
|
DO_EXIT_1("Corrupt PE file - too short: %s\n", infile);
|
||||||
if (memcmp(indata+peheader, "PE\0\0", 4))
|
if (memcmp(indata+peheader, "PE\0\0", 4))
|
||||||
DO_EXIT_1("Unrecognized DOS file type: %s\n", infile);
|
DO_EXIT_1("Unrecognized DOS file type: %s\n", infile);
|
||||||
|
} else if (type == FILE_TYPE_MSI) {
|
||||||
|
#ifdef WITH_GSF
|
||||||
|
GsfInput *src;
|
||||||
|
GsfInfile *ole;
|
||||||
|
GSList *sorted = NULL;
|
||||||
|
guint8 classid[16];
|
||||||
|
gchar decoded[0x40];
|
||||||
|
|
||||||
|
BIO_push(hash, BIO_new(BIO_s_null()));
|
||||||
|
|
||||||
|
src = gsf_input_stdio_new(infile, NULL);
|
||||||
|
if (!src)
|
||||||
|
DO_EXIT_1("Error opening file %s", infile);
|
||||||
|
|
||||||
|
sink = gsf_output_stdio_new(outfile, NULL);
|
||||||
|
if (!sink)
|
||||||
|
DO_EXIT_1("Error opening output file %s", outfile);
|
||||||
|
|
||||||
|
ole = gsf_infile_msole_new(src, NULL);
|
||||||
|
gsf_infile_msole_get_class_id(GSF_INFILE_MSOLE(ole), classid);
|
||||||
|
|
||||||
|
outole = gsf_outfile_msole_new(sink);
|
||||||
|
gsf_outfile_msole_set_class_id(GSF_OUTFILE_MSOLE(outole), classid);
|
||||||
|
|
||||||
|
for (i = 0; i < gsf_infile_num_children(ole); i++) {
|
||||||
|
GsfInput *child = gsf_infile_child_by_index(ole, i);
|
||||||
|
const guint8 *name = gsf_input_name(child);
|
||||||
|
msi_decode(name, decoded);
|
||||||
|
if (!g_strcmp0(decoded, "\05DigitalSignature"))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
sorted = g_slist_insert_sorted(sorted, (gpointer)name, (GCompareFunc)msi_cmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (; sorted; sorted = sorted->next) {
|
||||||
|
GsfInput *child = gsf_infile_child_by_name(ole, (gchar*)sorted->data);
|
||||||
|
msi_decode(sorted->data, decoded);
|
||||||
|
if (child == NULL)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
GsfOutput *outchild = gsf_outfile_new_child(outole, (gchar*)sorted->data, FALSE);
|
||||||
|
while (gsf_input_remaining(child) > 0) {
|
||||||
|
gsf_off_t size = MIN(gsf_input_remaining(child), 4096);
|
||||||
|
guint8 const *data = gsf_input_read(child, size, NULL);
|
||||||
|
BIO_write(hash, data, size);
|
||||||
|
if (!gsf_output_write(outchild, size, data))
|
||||||
|
DO_EXIT_1("Error writing %s", outfile);
|
||||||
|
}
|
||||||
|
g_object_unref(child);
|
||||||
|
gsf_output_close(outchild);
|
||||||
|
g_object_unref(outchild);
|
||||||
|
}
|
||||||
|
|
||||||
|
BIO_write(hash, classid, sizeof(classid));
|
||||||
|
g_slist_free(sorted);
|
||||||
|
#else
|
||||||
|
DO_EXIT_1("libgsf is not available, msi support is disabled: %s\n", infile);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
<<<<<<< HEAD
|
||||||
/* Create outdata file */
|
/* Create outdata file */
|
||||||
outdata = BIO_new_file(outfile, "w+b");
|
outdata = BIO_new_file(outfile, "w+b");
|
||||||
if (outdata == NULL)
|
if (outdata == NULL)
|
||||||
DO_EXIT_1("Failed to create file: %s\n", outfile);
|
DO_EXIT_1("Failed to create file: %s\n", outfile);
|
||||||
|
=======
|
||||||
|
if (type == FILE_TYPE_CAB || type == FILE_TYPE_PE) {
|
||||||
|
/* Create outdata file */
|
||||||
|
outdata = BIO_new_file(outfile, "wb");
|
||||||
|
if (outdata == NULL)
|
||||||
|
DO_EXIT_1("Failed to create file: %s\n", outfile);
|
||||||
|
>>>>>>> elmarco/master
|
||||||
|
|
||||||
hash = BIO_new(BIO_f_md());
|
BIO_push(hash, outdata);
|
||||||
BIO_set_md(hash, md);
|
}
|
||||||
BIO_push(hash, outdata);
|
|
||||||
|
|
||||||
if (is_cabinet) {
|
if (type == FILE_TYPE_CAB) {
|
||||||
unsigned short nfolders;
|
unsigned short nfolders;
|
||||||
|
|
||||||
u_char cabsigned[] = {
|
u_char cabsigned[] = {
|
||||||
@ -829,7 +1054,7 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
/* Write what's left */
|
/* Write what's left */
|
||||||
BIO_write(hash, indata+i, st.st_size-i);
|
BIO_write(hash, indata+i, st.st_size-i);
|
||||||
} else {
|
} else if (type == FILE_TYPE_PE) {
|
||||||
if (jp >= 0)
|
if (jp >= 0)
|
||||||
fprintf(stderr, "Warning: -jp option is only valid "
|
fprintf(stderr, "Warning: -jp option is only valid "
|
||||||
"for CAB files.\n");
|
"for CAB files.\n");
|
||||||
@ -891,7 +1116,7 @@ int main(int argc, char **argv)
|
|||||||
(si, NID_pkcs9_contentType,
|
(si, NID_pkcs9_contentType,
|
||||||
V_ASN1_OBJECT, OBJ_txt2obj(SPC_INDIRECT_DATA_OBJID, 1));
|
V_ASN1_OBJECT, OBJ_txt2obj(SPC_INDIRECT_DATA_OBJID, 1));
|
||||||
|
|
||||||
if (is_cabinet && jp >= 0) {
|
if (type == FILE_TYPE_CAB && jp >= 0) {
|
||||||
const u_char *attrs = NULL;
|
const u_char *attrs = NULL;
|
||||||
static const u_char java_attrs_low[] = {
|
static const u_char java_attrs_low[] = {
|
||||||
0x30, 0x06, 0x03, 0x02, 0x00, 0x01, 0x30, 0x00
|
0x30, 0x06, 0x03, 0x02, 0x00, 0x01, 0x30, 0x00
|
||||||
@ -957,7 +1182,7 @@ int main(int argc, char **argv)
|
|||||||
if ((sigdata = PKCS7_dataInit(sig, NULL)) == NULL)
|
if ((sigdata = PKCS7_dataInit(sig, NULL)) == NULL)
|
||||||
DO_EXIT_0("Signing failed(PKCS7_dataInit)\n");
|
DO_EXIT_0("Signing failed(PKCS7_dataInit)\n");
|
||||||
|
|
||||||
get_indirect_data_blob(&p, &len, md, is_cabinet);
|
get_indirect_data_blob(&p, &len, md, type);
|
||||||
len -= EVP_MD_size(md);
|
len -= EVP_MD_size(md);
|
||||||
memcpy(buf, p, len);
|
memcpy(buf, p, len);
|
||||||
i = BIO_gets(hash, buf + len, EVP_MAX_MD_SIZE);
|
i = BIO_gets(hash, buf + len, EVP_MAX_MD_SIZE);
|
||||||
@ -994,7 +1219,7 @@ int main(int argc, char **argv)
|
|||||||
p -= len;
|
p -= len;
|
||||||
padlen = (8 - len%8) % 8;
|
padlen = (8 - len%8) % 8;
|
||||||
|
|
||||||
if (!is_cabinet) {
|
if (type == FILE_TYPE_PE) {
|
||||||
static const char magic[] = {
|
static const char magic[] = {
|
||||||
0x00, 0x02, 0x02, 0x00
|
0x00, 0x02, 0x02, 0x00
|
||||||
};
|
};
|
||||||
@ -1003,22 +1228,40 @@ int main(int argc, char **argv)
|
|||||||
BIO_write(outdata, magic, sizeof(magic));
|
BIO_write(outdata, magic, sizeof(magic));
|
||||||
}
|
}
|
||||||
|
|
||||||
BIO_write(outdata, p, len);
|
if (type == FILE_TYPE_PE || type == FILE_TYPE_CAB) {
|
||||||
|
BIO_write(outdata, p, len);
|
||||||
|
|
||||||
/* pad (with 0's) asn1 blob to 8 byte boundary */
|
/* pad (with 0's) asn1 blob to 8 byte boundary */
|
||||||
if (padlen > 0) {
|
if (padlen > 0) {
|
||||||
memset(p, 0, padlen);
|
memset(p, 0, padlen);
|
||||||
BIO_write(outdata, p, padlen);
|
BIO_write(outdata, p, padlen);
|
||||||
|
}
|
||||||
|
#ifdef WITH_GSF
|
||||||
|
} else if (type == FILE_TYPE_MSI) {
|
||||||
|
GsfOutput *child;
|
||||||
|
GError *error = NULL;
|
||||||
|
|
||||||
|
child = gsf_outfile_new_child(outole, "\05DigitalSignature", FALSE);
|
||||||
|
if (!gsf_output_write(child, len, p))
|
||||||
|
DO_EXIT_1("Failed to write MSI signature to %s", infile);
|
||||||
|
gsf_output_close(child);
|
||||||
|
gsf_output_close(GSF_OUTPUT(outole));
|
||||||
|
g_object_unref(sink);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!is_cabinet) {
|
if (type == FILE_TYPE_PE) {
|
||||||
(void)BIO_seek(outdata, peheader+152+pe32plus*16);
|
(void)BIO_seek(outdata, peheader+152+pe32plus*16);
|
||||||
PUT_UINT32_LE(st.st_size, buf);
|
PUT_UINT32_LE(st.st_size, buf);
|
||||||
BIO_write(outdata, buf, 4);
|
BIO_write(outdata, buf, 4);
|
||||||
PUT_UINT32_LE(len+8+padlen, buf);
|
PUT_UINT32_LE(len+8+padlen, buf);
|
||||||
BIO_write(outdata, buf, 4);
|
BIO_write(outdata, buf, 4);
|
||||||
|
<<<<<<< HEAD
|
||||||
recalc_pe_checksum(outdata, peheader);
|
recalc_pe_checksum(outdata, peheader);
|
||||||
} else {
|
} else {
|
||||||
|
=======
|
||||||
|
} else if (type == FILE_TYPE_CAB) {
|
||||||
|
>>>>>>> elmarco/master
|
||||||
(void)BIO_seek(outdata, 0x30);
|
(void)BIO_seek(outdata, 0x30);
|
||||||
PUT_UINT32_LE(len+padlen, buf);
|
PUT_UINT32_LE(len+padlen, buf);
|
||||||
BIO_write(outdata, buf, 4);
|
BIO_write(outdata, buf, 4);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user