mirror of
https://github.com/mtrojnar/osslsigncode.git
synced 2025-07-04 12:12:46 -05:00
fix MSI memory leaks
This commit is contained in:

committed by
Michał Trojnara

parent
36708d0ee5
commit
ddb2dc7b15
216
osslsigncode.c
216
osslsigncode.c
@ -2587,7 +2587,7 @@ static gint msi_cmp(gpointer a, gpointer b)
|
|||||||
* of the children of the given infile. The children are
|
* of the children of the given infile. The children are
|
||||||
* sorted according to the msi_cmp.
|
* sorted according to the msi_cmp.
|
||||||
*
|
*
|
||||||
* The returned list must be freed with g_slist_free.
|
* The returned list must be freed with g_slist_free_full.
|
||||||
*/
|
*/
|
||||||
static GSList *msi_sorted_infile_children(GsfInfile *infile)
|
static GSList *msi_sorted_infile_children(GsfInfile *infile)
|
||||||
{
|
{
|
||||||
@ -2597,14 +2597,14 @@ static GSList *msi_sorted_infile_children(GsfInfile *infile)
|
|||||||
|
|
||||||
for (i = 0; i < gsf_infile_num_children(infile); i++) {
|
for (i = 0; i < gsf_infile_num_children(infile); i++) {
|
||||||
GsfInput *child = gsf_infile_child_by_index(infile, i);
|
GsfInput *child = gsf_infile_child_by_index(infile, i);
|
||||||
const guint8 *name = (const guint8*)gsf_input_name(child);
|
const gchar *name = gsf_input_name(child);
|
||||||
msi_decode(name, decoded);
|
msi_decode((const guint8*)name, decoded);
|
||||||
|
|
||||||
if (!g_strcmp0(decoded, "\05DigitalSignature"))
|
if (g_strcmp0(decoded, "\05DigitalSignature") &&
|
||||||
continue;
|
g_strcmp0(decoded, "\05MsiDigitalSignatureEx"))
|
||||||
if (!g_strcmp0(decoded, "\05MsiDigitalSignatureEx"))
|
sorted = g_slist_insert_sorted(sorted, (gpointer)g_strdup(name), (GCompareFunc)msi_cmp);
|
||||||
continue;
|
|
||||||
sorted = g_slist_insert_sorted(sorted, (gpointer)name, (GCompareFunc)msi_cmp);
|
g_object_unref(child);
|
||||||
}
|
}
|
||||||
return sorted;
|
return sorted;
|
||||||
}
|
}
|
||||||
@ -2621,7 +2621,7 @@ static gboolean msi_prehash_utf16_name(gchar *name, BIO *hash)
|
|||||||
|
|
||||||
gchar *u16name = (gchar*)g_utf8_to_utf16(name, -1, NULL, &chars_written, NULL);
|
gchar *u16name = (gchar*)g_utf8_to_utf16(name, -1, NULL, &chars_written, NULL);
|
||||||
if (u16name == NULL) {
|
if (u16name == NULL) {
|
||||||
return FALSE;
|
return FALSE; /* FAILED */
|
||||||
}
|
}
|
||||||
BIO_write(hash, u16name, 2*chars_written);
|
BIO_write(hash, u16name, 2*chars_written);
|
||||||
g_free(u16name);
|
g_free(u16name);
|
||||||
@ -2638,20 +2638,19 @@ static gboolean msi_prehash_utf16_name(gchar *name, BIO *hash)
|
|||||||
*/
|
*/
|
||||||
static gboolean msi_prehash(GsfInfile *infile, gchar *dirname, BIO *hash)
|
static gboolean msi_prehash(GsfInfile *infile, gchar *dirname, BIO *hash)
|
||||||
{
|
{
|
||||||
GSList *sorted = NULL;
|
GSList *sorted, *current;
|
||||||
guint8 classid[16], zeroes[8];
|
guint8 classid[16], zeroes[8];
|
||||||
gchar *name;
|
|
||||||
GsfInput *child;
|
|
||||||
gboolean is_dir;
|
gboolean is_dir;
|
||||||
gsf_off_t size;
|
gsf_off_t size;
|
||||||
guint32 sizebuf;
|
guint32 sizebuf;
|
||||||
|
bool ret = FALSE;
|
||||||
|
|
||||||
memset(&zeroes, 0, sizeof(zeroes));
|
memset(&zeroes, 0, sizeof(zeroes));
|
||||||
gsf_infile_msole_get_class_id(GSF_INFILE_MSOLE(infile), classid);
|
gsf_infile_msole_get_class_id(GSF_INFILE_MSOLE(infile), classid);
|
||||||
|
|
||||||
if (dirname != NULL) {
|
if (dirname != NULL) {
|
||||||
if (!msi_prehash_utf16_name(dirname, hash))
|
if (!msi_prehash_utf16_name(dirname, hash))
|
||||||
return FALSE;
|
return ret; /* FAILED */
|
||||||
}
|
}
|
||||||
BIO_write(hash, classid, sizeof(classid));
|
BIO_write(hash, classid, sizeof(classid));
|
||||||
BIO_write(hash, zeroes, 4);
|
BIO_write(hash, zeroes, 4);
|
||||||
@ -2665,18 +2664,22 @@ static gboolean msi_prehash(GsfInfile *infile, gchar *dirname, BIO *hash)
|
|||||||
BIO_write(hash, zeroes, 8); /* mtime as Windows FILETIME */
|
BIO_write(hash, zeroes, 8); /* mtime as Windows FILETIME */
|
||||||
}
|
}
|
||||||
sorted = msi_sorted_infile_children(infile);
|
sorted = msi_sorted_infile_children(infile);
|
||||||
for (; sorted; sorted = sorted->next) {
|
for (current = sorted; current; current = g_slist_next(current)) {
|
||||||
name = (gchar*)sorted->data;
|
gchar *name = current->data;
|
||||||
child = gsf_infile_child_by_name(infile, name);
|
GsfInput *child = gsf_infile_child_by_name(infile, name);
|
||||||
if (child == NULL)
|
if (child == NULL)
|
||||||
continue;
|
continue;
|
||||||
is_dir = GSF_IS_INFILE(child) && gsf_infile_num_children(GSF_INFILE(child)) > 0;
|
is_dir = GSF_IS_INFILE(child) && gsf_infile_num_children(GSF_INFILE(child)) > 0;
|
||||||
if (is_dir) {
|
if (is_dir) {
|
||||||
if (!msi_prehash(GSF_INFILE(child), name, hash))
|
if (!msi_prehash(GSF_INFILE(child), name, hash)) {
|
||||||
return FALSE;
|
g_object_unref(child);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!msi_prehash_utf16_name(name, hash))
|
if (!msi_prehash_utf16_name(name, hash)) {
|
||||||
return FALSE;
|
g_object_unref(child);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
* File size.
|
* File size.
|
||||||
*/
|
*/
|
||||||
@ -2697,9 +2700,12 @@ static gboolean msi_prehash(GsfInfile *infile, gchar *dirname, BIO *hash)
|
|||||||
BIO_write(hash, zeroes, 8); /* ctime as Windows FILETIME */
|
BIO_write(hash, zeroes, 8); /* ctime as Windows FILETIME */
|
||||||
BIO_write(hash, zeroes, 8); /* mtime as Windows FILETIME */
|
BIO_write(hash, zeroes, 8); /* mtime as Windows FILETIME */
|
||||||
}
|
}
|
||||||
|
g_object_unref(child);
|
||||||
}
|
}
|
||||||
g_slist_free(sorted);
|
ret = TRUE;
|
||||||
return TRUE;
|
out:
|
||||||
|
g_slist_free_full(sorted, g_free);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -2714,22 +2720,21 @@ static gboolean msi_prehash(GsfInfile *infile, gchar *dirname, BIO *hash)
|
|||||||
static gboolean msi_handle_dir(GsfInfile *infile, GsfOutfile *outole, BIO *hash)
|
static gboolean msi_handle_dir(GsfInfile *infile, GsfOutfile *outole, BIO *hash)
|
||||||
{
|
{
|
||||||
guint8 classid[16];
|
guint8 classid[16];
|
||||||
GSList *sorted = NULL;
|
GSList *sorted, *current;
|
||||||
gchar *name;
|
|
||||||
GsfInput *child;
|
|
||||||
GsfOutput *outchild = NULL;
|
GsfOutput *outchild = NULL;
|
||||||
gboolean is_dir;
|
gboolean is_dir;
|
||||||
gsf_off_t size;
|
gsf_off_t size;
|
||||||
guint8 const *data;
|
guint8 const *data;
|
||||||
|
bool ret = FALSE;
|
||||||
|
|
||||||
gsf_infile_msole_get_class_id(GSF_INFILE_MSOLE(infile), classid);
|
gsf_infile_msole_get_class_id(GSF_INFILE_MSOLE(infile), classid);
|
||||||
if (outole != NULL)
|
if (outole != NULL)
|
||||||
gsf_outfile_msole_set_class_id(GSF_OUTFILE_MSOLE(outole), classid);
|
gsf_outfile_msole_set_class_id(GSF_OUTFILE_MSOLE(outole), classid);
|
||||||
|
|
||||||
sorted = msi_sorted_infile_children(infile);
|
sorted = msi_sorted_infile_children(infile);
|
||||||
for (; sorted; sorted = sorted->next) {
|
for (current = sorted; current; current = g_slist_next(current)) {
|
||||||
name = (gchar*)sorted->data;
|
gchar *name = current->data;
|
||||||
child = gsf_infile_child_by_name(infile, name);
|
GsfInput *child = gsf_infile_child_by_name(infile, name);
|
||||||
if (child == NULL)
|
if (child == NULL)
|
||||||
continue;
|
continue;
|
||||||
is_dir = GSF_IS_INFILE(child) && gsf_infile_num_children(GSF_INFILE(child)) > 0;
|
is_dir = GSF_IS_INFILE(child) && gsf_infile_num_children(GSF_INFILE(child)) > 0;
|
||||||
@ -2737,7 +2742,10 @@ static gboolean msi_handle_dir(GsfInfile *infile, GsfOutfile *outole, BIO *hash)
|
|||||||
outchild = gsf_outfile_new_child(outole, name, is_dir);
|
outchild = gsf_outfile_new_child(outole, name, is_dir);
|
||||||
if (is_dir) {
|
if (is_dir) {
|
||||||
if (!msi_handle_dir(GSF_INFILE(child), GSF_OUTFILE(outchild), hash)) {
|
if (!msi_handle_dir(GSF_INFILE(child), GSF_OUTFILE(outchild), hash)) {
|
||||||
return FALSE;
|
gsf_output_close(outchild);
|
||||||
|
g_object_unref(outchild);
|
||||||
|
g_object_unref(child);
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
while (gsf_input_remaining(child) > 0) {
|
while (gsf_input_remaining(child) > 0) {
|
||||||
@ -2745,7 +2753,10 @@ static gboolean msi_handle_dir(GsfInfile *infile, GsfOutfile *outole, BIO *hash)
|
|||||||
data = gsf_input_read(child, size, NULL);
|
data = gsf_input_read(child, size, NULL);
|
||||||
BIO_write(hash, data, size);
|
BIO_write(hash, data, size);
|
||||||
if (outchild != NULL && !gsf_output_write(outchild, size, data)) {
|
if (outchild != NULL && !gsf_output_write(outchild, size, data)) {
|
||||||
return FALSE;
|
gsf_output_close(outchild);
|
||||||
|
g_object_unref(outchild);
|
||||||
|
g_object_unref(child);
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2753,10 +2764,13 @@ static gboolean msi_handle_dir(GsfInfile *infile, GsfOutfile *outole, BIO *hash)
|
|||||||
gsf_output_close(outchild);
|
gsf_output_close(outchild);
|
||||||
g_object_unref(outchild);
|
g_object_unref(outchild);
|
||||||
}
|
}
|
||||||
|
g_object_unref(child);
|
||||||
}
|
}
|
||||||
BIO_write(hash, classid, sizeof(classid));
|
BIO_write(hash, classid, sizeof(classid));
|
||||||
g_slist_free(sorted);
|
ret = TRUE;
|
||||||
return TRUE;
|
out:
|
||||||
|
g_slist_free_full(sorted, g_free);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -2868,49 +2882,65 @@ out:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* msi_get_child returns the first child that its value name matches the pattern.
|
||||||
|
* The returned input stream must be unrefed.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static GsfInput *msi_get_child(GsfInfile *infile, const char *pattern)
|
||||||
|
{
|
||||||
|
gchar decoded[0x40];
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < gsf_infile_num_children(infile); i++) {
|
||||||
|
GsfInput *child = gsf_infile_child_by_index(infile, i);
|
||||||
|
const guint8 *name = (const guint8*)gsf_input_name(child);
|
||||||
|
msi_decode(name, decoded);
|
||||||
|
if (!g_strcmp0(decoded, pattern))
|
||||||
|
return child;
|
||||||
|
else
|
||||||
|
g_object_unref(child);
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* msi_verify_file checks whether or not the signature of infile is valid.
|
* msi_verify_file checks whether or not the signature of infile is valid.
|
||||||
*/
|
*/
|
||||||
static int msi_verify_file(GsfInfile *infile, GLOBAL_OPTIONS *options)
|
static int msi_verify_file(GsfInfile *infile, GLOBAL_OPTIONS *options)
|
||||||
{
|
{
|
||||||
GsfInput *child, *sig = NULL, *exsig = NULL;
|
GsfInput *sig, *exsig;
|
||||||
unsigned char *exdata = NULL;
|
unsigned char *exdata = NULL;
|
||||||
unsigned char *indata = NULL;
|
unsigned char *indata = NULL;
|
||||||
gchar decoded[0x40];
|
|
||||||
int i, ret = 1;
|
int i, ret = 1;
|
||||||
PKCS7 *p7 = NULL;
|
PKCS7 *p7 = NULL;
|
||||||
const guint8 *name;
|
|
||||||
unsigned long inlen, exlen = 0;
|
unsigned long inlen, exlen = 0;
|
||||||
const unsigned char *blob;
|
const unsigned char *blob;
|
||||||
STACK_OF(SIGNATURE) *signatures;
|
STACK_OF(SIGNATURE) *signatures;
|
||||||
SIGNATURE *signature = NULL;
|
SIGNATURE *signature = NULL;
|
||||||
|
|
||||||
signatures = sk_SIGNATURE_new_null();
|
sig = msi_get_child(infile, "\05DigitalSignature");
|
||||||
|
|
||||||
for (i = 0; i < gsf_infile_num_children(infile); i++) {
|
|
||||||
child = gsf_infile_child_by_index(infile, i);
|
|
||||||
name = (const guint8*)gsf_input_name(child);
|
|
||||||
msi_decode(name, decoded);
|
|
||||||
if (!g_strcmp0(decoded, "\05DigitalSignature"))
|
|
||||||
sig = child;
|
|
||||||
if (!g_strcmp0(decoded, "\05MsiDigitalSignatureEx"))
|
|
||||||
exsig = child;
|
|
||||||
}
|
|
||||||
if (sig == NULL) {
|
if (sig == NULL) {
|
||||||
printf("MSI file has no signature\n\n");
|
printf("MSI file has no signature\n\n");
|
||||||
goto out;
|
return 1; /* FAILED */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
signatures = sk_SIGNATURE_new_null();
|
||||||
|
|
||||||
inlen = (unsigned long) gsf_input_remaining(sig);
|
inlen = (unsigned long) gsf_input_remaining(sig);
|
||||||
indata = OPENSSL_malloc(inlen);
|
indata = OPENSSL_malloc(inlen);
|
||||||
if (gsf_input_read(sig, inlen, indata) == NULL) {
|
if (gsf_input_read(sig, inlen, indata) == NULL) {
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
exsig = msi_get_child(infile, "\05MsiDigitalSignatureEx");
|
||||||
if (exsig != NULL) {
|
if (exsig != NULL) {
|
||||||
exlen = (unsigned long) gsf_input_remaining(exsig);
|
exlen = (unsigned long) gsf_input_remaining(exsig);
|
||||||
exdata = OPENSSL_malloc(exlen);
|
exdata = OPENSSL_malloc(exlen);
|
||||||
if (gsf_input_read(exsig, exlen, exdata) == NULL) {
|
if (gsf_input_read(exsig, exlen, exdata) == NULL) {
|
||||||
|
g_object_unref(exsig);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
g_object_unref(exsig);
|
||||||
}
|
}
|
||||||
blob = (unsigned char *)indata;
|
blob = (unsigned char *)indata;
|
||||||
p7 = d2i_PKCS7(NULL, &blob, inlen);
|
p7 = d2i_PKCS7(NULL, &blob, inlen);
|
||||||
@ -2937,6 +2967,7 @@ static int msi_verify_file(GsfInfile *infile, GLOBAL_OPTIONS *options)
|
|||||||
}
|
}
|
||||||
printf("Number of verified signatures: %d\n", i);
|
printf("Number of verified signatures: %d\n", i);
|
||||||
out:
|
out:
|
||||||
|
g_object_unref(sig);
|
||||||
sk_SIGNATURE_free(signatures);
|
sk_SIGNATURE_free(signatures);
|
||||||
OPENSSL_free(indata);
|
OPENSSL_free(indata);
|
||||||
OPENSSL_free(exdata);
|
OPENSSL_free(exdata);
|
||||||
@ -2946,21 +2977,13 @@ out:
|
|||||||
static int msi_extract_dse(GsfInfile *infile, unsigned char **dsebuf,
|
static int msi_extract_dse(GsfInfile *infile, unsigned char **dsebuf,
|
||||||
unsigned long *dselen, int *has_dse)
|
unsigned long *dselen, int *has_dse)
|
||||||
{
|
{
|
||||||
GsfInput *exsig = NULL;
|
GsfInput *exsig;
|
||||||
gchar decoded[0x40];
|
|
||||||
unsigned char *buf = NULL;
|
unsigned char *buf = NULL;
|
||||||
gsf_off_t size = 0;
|
gsf_off_t size = 0;
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < gsf_infile_num_children(infile); i++) {
|
exsig = msi_get_child(infile, "\05MsiDigitalSignatureEx");
|
||||||
GsfInput *child = gsf_infile_child_by_index(infile, i);
|
|
||||||
const guint8 *name = (const guint8*)gsf_input_name(child);
|
|
||||||
msi_decode(name, decoded);
|
|
||||||
if (!g_strcmp0(decoded, "\05MsiDigitalSignatureEx"))
|
|
||||||
exsig = child;
|
|
||||||
}
|
|
||||||
if (exsig == NULL)
|
if (exsig == NULL)
|
||||||
return 1; /* FAILED */
|
return FALSE; /* FAILED */
|
||||||
if (has_dse != NULL) {
|
if (has_dse != NULL) {
|
||||||
*has_dse = 1;
|
*has_dse = 1;
|
||||||
}
|
}
|
||||||
@ -2970,11 +2993,14 @@ static int msi_extract_dse(GsfInfile *infile, unsigned char **dsebuf,
|
|||||||
}
|
}
|
||||||
if (dsebuf != NULL) {
|
if (dsebuf != NULL) {
|
||||||
buf = OPENSSL_malloc(size);
|
buf = OPENSSL_malloc(size);
|
||||||
if (gsf_input_read(exsig, size, buf) == NULL)
|
if (gsf_input_read(exsig, size, buf) == NULL) {
|
||||||
return 1; /* FAILED */
|
g_object_unref(exsig);
|
||||||
|
return FALSE; /* FAILED */
|
||||||
|
}
|
||||||
*dsebuf = buf;
|
*dsebuf = buf;
|
||||||
}
|
}
|
||||||
return 0; /* OK */
|
g_object_unref(exsig);
|
||||||
|
return TRUE; /* OK */
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -2984,26 +3010,16 @@ static int msi_extract_dse(GsfInfile *infile, unsigned char **dsebuf,
|
|||||||
static int msi_extract_signature_to_file(GsfInfile *infile, GLOBAL_OPTIONS *options)
|
static int msi_extract_signature_to_file(GsfInfile *infile, GLOBAL_OPTIONS *options)
|
||||||
{
|
{
|
||||||
char hexbuf[EVP_MAX_MD_SIZE*2+1];
|
char hexbuf[EVP_MAX_MD_SIZE*2+1];
|
||||||
GsfInput *sig = NULL;
|
GsfInput *sig, *exsig;
|
||||||
GsfInput *exsig = NULL;
|
|
||||||
unsigned char *exdata = NULL;
|
unsigned char *exdata = NULL;
|
||||||
unsigned long exlen = 0;
|
unsigned long exlen = 0;
|
||||||
BIO *outdata = NULL;
|
BIO *outdata;
|
||||||
gchar decoded[0x40];
|
int ret = 1;
|
||||||
int i, ret = 1;
|
|
||||||
|
|
||||||
for (i = 0; i < gsf_infile_num_children(infile); i++) {
|
sig = msi_get_child(infile, "\05DigitalSignature");
|
||||||
GsfInput *child = gsf_infile_child_by_index(infile, i);
|
|
||||||
const guint8 *name = (const guint8*)gsf_input_name(child);
|
|
||||||
msi_decode(name, decoded);
|
|
||||||
if (!g_strcmp0(decoded, "\05DigitalSignature"))
|
|
||||||
sig = child;
|
|
||||||
if (!g_strcmp0(decoded, "\05MsiDigitalSignatureEx"))
|
|
||||||
exsig = child;
|
|
||||||
}
|
|
||||||
if (sig == NULL) {
|
if (sig == NULL) {
|
||||||
printf("MSI file has no signature\n\n");
|
printf("MSI file has no signature\n\n");
|
||||||
goto out;
|
return 1; /* FAILED */
|
||||||
}
|
}
|
||||||
/* Create outdata DER file */
|
/* Create outdata DER file */
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
@ -3023,25 +3039,32 @@ static int msi_extract_signature_to_file(GsfInfile *infile, GLOBAL_OPTIONS *opti
|
|||||||
guint8 const *data = gsf_input_read(sig, size, NULL);
|
guint8 const *data = gsf_input_read(sig, size, NULL);
|
||||||
BIO_write(outdata, data, size);
|
BIO_write(outdata, data, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
exsig = msi_get_child(infile, "\05MsiDigitalSignatureEx");
|
||||||
if (exsig != NULL) {
|
if (exsig != NULL) {
|
||||||
exlen = (unsigned long) gsf_input_remaining(exsig);
|
exlen = (unsigned long) gsf_input_remaining(exsig);
|
||||||
if (exlen > EVP_MAX_MD_SIZE) {
|
if (exlen > EVP_MAX_MD_SIZE) {
|
||||||
printf("MsiDigitalSignatureEx is larger than EVP_MAX_MD_SIZE\n");
|
printf("MsiDigitalSignatureEx is larger than EVP_MAX_MD_SIZE\n");
|
||||||
|
g_object_unref(exsig);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
exdata = OPENSSL_malloc(exlen);
|
exdata = OPENSSL_malloc(exlen);
|
||||||
if (gsf_input_read(exsig, exlen, exdata) == NULL) {
|
if (gsf_input_read(exsig, exlen, exdata) == NULL) {
|
||||||
printf("Unable to read MsiDigitalSignatureEx\n");
|
printf("Unable to read MsiDigitalSignatureEx\n");
|
||||||
|
OPENSSL_free(exdata);
|
||||||
|
g_object_unref(exsig);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
tohex(exdata, hexbuf, exlen);
|
tohex(exdata, hexbuf, exlen);
|
||||||
printf("Note: MSI includes a MsiDigitalSignatureEx section\n");
|
printf("Note: MSI includes a MsiDigitalSignatureEx section\n");
|
||||||
printf("MsiDigitalSignatureEx pre-hash: %s\n", hexbuf);
|
printf("MsiDigitalSignatureEx pre-hash: %s\n", hexbuf);
|
||||||
|
OPENSSL_free(exdata);
|
||||||
|
g_object_unref(exsig);
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = 0; /* OK */
|
ret = 0; /* OK */
|
||||||
out:
|
out:
|
||||||
OPENSSL_free(exdata);
|
g_object_unref(sig);
|
||||||
if (outdata)
|
if (outdata)
|
||||||
BIO_free_all(outdata);
|
BIO_free_all(outdata);
|
||||||
return ret;
|
return ret;
|
||||||
@ -3049,25 +3072,16 @@ out:
|
|||||||
|
|
||||||
static PKCS7 *msi_extract_signature_to_pkcs7(GsfInfile *infile)
|
static PKCS7 *msi_extract_signature_to_pkcs7(GsfInfile *infile)
|
||||||
{
|
{
|
||||||
GsfInput *sig = NULL, *child;
|
GsfInput *sig;
|
||||||
const guint8 *name;
|
|
||||||
gchar decoded[0x40];
|
|
||||||
PKCS7 *p7 = NULL;
|
PKCS7 *p7 = NULL;
|
||||||
u_char *buf = NULL;
|
u_char *buf = NULL;
|
||||||
gsf_off_t size = 0;
|
gsf_off_t size = 0;
|
||||||
int i = 0;
|
|
||||||
const unsigned char *p7buf;
|
const unsigned char *p7buf;
|
||||||
|
|
||||||
for (i = 0; i < gsf_infile_num_children(infile); i++) {
|
sig = msi_get_child(infile, "\05DigitalSignature");
|
||||||
child = gsf_infile_child_by_index(infile, i);
|
|
||||||
name = (const guint8*)gsf_input_name(child);
|
|
||||||
msi_decode(name, decoded);
|
|
||||||
if (!g_strcmp0(decoded, "\05DigitalSignature"))
|
|
||||||
sig = child;
|
|
||||||
}
|
|
||||||
if (sig == NULL) {
|
if (sig == NULL) {
|
||||||
printf("MSI file has no signature\n\n");
|
printf("MSI file has no signature\n\n");
|
||||||
goto out;
|
return NULL; /* FAILED */
|
||||||
}
|
}
|
||||||
size = gsf_input_remaining(sig);
|
size = gsf_input_remaining(sig);
|
||||||
buf = OPENSSL_malloc(size);
|
buf = OPENSSL_malloc(size);
|
||||||
@ -3077,6 +3091,7 @@ static PKCS7 *msi_extract_signature_to_pkcs7(GsfInfile *infile)
|
|||||||
p7 = d2i_PKCS7(NULL, &p7buf, size);
|
p7 = d2i_PKCS7(NULL, &p7buf, size);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
|
g_object_unref(sig);
|
||||||
OPENSSL_free(buf);
|
OPENSSL_free(buf);
|
||||||
return p7;
|
return p7;
|
||||||
}
|
}
|
||||||
@ -3128,7 +3143,7 @@ static int msi_check_MsiDigitalSignatureEx(GsfInfile *ole, const EVP_MD *md)
|
|||||||
unsigned long dselen = 0;
|
unsigned long dselen = 0;
|
||||||
int mdlen, has_dse = 0;
|
int mdlen, has_dse = 0;
|
||||||
|
|
||||||
if (msi_extract_dse(ole, NULL, &dselen, &has_dse) != 0 && has_dse) {
|
if (!msi_extract_dse(ole, NULL, &dselen, &has_dse) != 0 && has_dse) {
|
||||||
printf("Unable to extract MsiDigitalSignatureEx section\n\n");
|
printf("Unable to extract MsiDigitalSignatureEx section\n\n");
|
||||||
return 0; /* FAILED */
|
return 0; /* FAILED */
|
||||||
}
|
}
|
||||||
@ -3215,6 +3230,7 @@ static int msi_add_DigitalSignature(GsfOutfile *outole, u_char *p, int len)
|
|||||||
if (!gsf_output_write(child, len, p))
|
if (!gsf_output_write(child, len, p))
|
||||||
ret = 0;
|
ret = 0;
|
||||||
gsf_output_close(child);
|
gsf_output_close(child);
|
||||||
|
g_object_unref(child);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3227,6 +3243,7 @@ static int msi_add_MsiDigitalSignatureEx(GsfOutfile *outole, GSF_PARAMS *gsfpara
|
|||||||
if (!gsf_output_write(child, gsfparams->len_msiex, gsfparams->p_msiex))
|
if (!gsf_output_write(child, gsfparams->len_msiex, gsfparams->p_msiex))
|
||||||
ret = 0;
|
ret = 0;
|
||||||
gsf_output_close(child);
|
gsf_output_close(child);
|
||||||
|
g_object_unref(child);
|
||||||
OPENSSL_free(gsfparams->p_msiex);
|
OPENSSL_free(gsfparams->p_msiex);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -4503,6 +4520,7 @@ static int check_attached_data(file_type_t type, FILE_HEADER *header, GLOBAL_OPT
|
|||||||
}
|
}
|
||||||
ole = gsf_infile_msole_new(src, NULL);
|
ole = gsf_infile_msole_new(src, NULL);
|
||||||
g_object_unref(src);
|
g_object_unref(src);
|
||||||
|
|
||||||
ret = msi_verify_file(ole, options);
|
ret = msi_verify_file(ole, options);
|
||||||
g_object_unref(ole);
|
g_object_unref(ole);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
@ -5346,21 +5364,30 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
if (cmd == CMD_EXTRACT) {
|
if (cmd == CMD_EXTRACT) {
|
||||||
ret = msi_extract_file(ole, &options);
|
ret = msi_extract_file(ole, &options);
|
||||||
|
g_object_unref(ole);
|
||||||
goto skip_signing;
|
goto skip_signing;
|
||||||
} else if (cmd == CMD_VERIFY) {
|
} else if (cmd == CMD_VERIFY) {
|
||||||
ret = msi_verify_file(ole, &options);
|
ret = msi_verify_file(ole, &options);
|
||||||
|
g_object_unref(ole);
|
||||||
goto skip_signing;
|
goto skip_signing;
|
||||||
} else {
|
} else {
|
||||||
sig = msi_presign_file(type, cmd, &header, &options, &cparams, indata,
|
sig = msi_presign_file(type, cmd, &header, &options, &cparams, indata,
|
||||||
hash, ole, &gsfparams, &cursig);
|
hash, ole, &gsfparams, &cursig);
|
||||||
if (cmd == CMD_REMOVE) {
|
if (cmd == CMD_REMOVE) {
|
||||||
gsf_output_close(GSF_OUTPUT(gsfparams.outole));
|
g_object_unref(ole);
|
||||||
g_object_unref(gsfparams.sink);
|
if (gsfparams.outole) {
|
||||||
ret = 0;
|
gsf_output_close(GSF_OUTPUT(gsfparams.outole));
|
||||||
goto skip_signing;
|
g_object_unref(gsfparams.outole);
|
||||||
|
g_object_unref(gsfparams.sink);
|
||||||
|
ret = 0;
|
||||||
|
goto skip_signing;
|
||||||
|
} else
|
||||||
|
/* Failed to create output file */
|
||||||
|
goto err_cleanup;
|
||||||
} else if (!sig) {
|
} else if (!sig) {
|
||||||
PKCS7_free(cursig);
|
PKCS7_free(cursig);
|
||||||
OPENSSL_free(gsfparams.p_msiex);
|
OPENSSL_free(gsfparams.p_msiex);
|
||||||
|
g_object_unref(ole);
|
||||||
goto err_cleanup;
|
goto err_cleanup;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -5441,6 +5468,7 @@ int main(int argc, char **argv)
|
|||||||
outdata, &gsfparams);
|
outdata, &gsfparams);
|
||||||
if (type == FILE_TYPE_MSI) {
|
if (type == FILE_TYPE_MSI) {
|
||||||
gsf_output_close(GSF_OUTPUT(gsfparams.outole));
|
gsf_output_close(GSF_OUTPUT(gsfparams.outole));
|
||||||
|
g_object_unref(gsfparams.outole);
|
||||||
g_object_unref(gsfparams.sink);
|
g_object_unref(gsfparams.sink);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
Reference in New Issue
Block a user