Changed error output to stderr instead of stdout

This commit is contained in:
olszomal 2024-06-05 12:25:20 +02:00 committed by Michał Trojnara
parent bad6e96e0f
commit 2b3228d549
11 changed files with 486 additions and 476 deletions

View File

@ -6,6 +6,7 @@
- used native HTTP client with OpenSSL 3.0 or later, removed libcurl dependency - used native HTTP client with OpenSSL 3.0 or later, removed libcurl dependency
- added the "-ignore-crl" option to disable fetching and verifying - added the "-ignore-crl" option to disable fetching and verifying
CRL Distribution Points CRL Distribution Points
- changed error output to stderr instead of stdout
- improved testing - improved testing
### 2.8 (2024.03.03) ### 2.8 (2024.03.03)

194
appx.c
View File

@ -442,7 +442,7 @@ static PKCS7 *appx_pkcs7_contents_get(FILE_FORMAT_CTX *ctx, BIO *hash, const EVP
/* Create and append a new signature content types entry */ /* Create and append a new signature content types entry */
entry = zipGetCDEntryByName(ctx->appx_ctx->zip, CONTENT_TYPES_FILENAME); entry = zipGetCDEntryByName(ctx->appx_ctx->zip, CONTENT_TYPES_FILENAME);
if (!entry) { if (!entry) {
printf("Not a valid .appx file: content types file missing\n"); fprintf(stderr, "Not a valid .appx file: content types file missing\n");
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
if (!appx_append_ct_signature_entry(ctx->appx_ctx->zip, entry)) { if (!appx_append_ct_signature_entry(ctx->appx_ctx->zip, entry)) {
@ -483,7 +483,7 @@ static int appx_verify_digests(FILE_FORMAT_CTX *ctx, PKCS7 *p7)
if (idc) { if (idc) {
BIO *hashes; BIO *hashes;
if (!appx_extract_hashes(ctx, idc)) { if (!appx_extract_hashes(ctx, idc)) {
printf("Failed to extract hashes from the signature\n"); fprintf(stderr, "Failed to extract hashes from the signature\n");
SpcIndirectDataContent_free(idc); SpcIndirectDataContent_free(idc);
return 0; /* FAILED */ return 0; /* FAILED */
} }
@ -494,7 +494,7 @@ static int appx_verify_digests(FILE_FORMAT_CTX *ctx, PKCS7 *p7)
} }
BIO_free_all(hashes); BIO_free_all(hashes);
if (!appx_compare_hashes(ctx)) { if (!appx_compare_hashes(ctx)) {
printf("Signature hash verification failed\n"); fprintf(stderr, "Signature hash verification failed\n");
SpcIndirectDataContent_free(idc); SpcIndirectDataContent_free(idc);
return 0; /* FAILED */ return 0; /* FAILED */
} }
@ -518,7 +518,7 @@ static PKCS7 *appx_pkcs7_extract(FILE_FORMAT_CTX *ctx)
/* Check if the signature exists */ /* Check if the signature exists */
if (!zipEntryExist(ctx->appx_ctx->zip, APP_SIGNATURE_FILENAME)) { if (!zipEntryExist(ctx->appx_ctx->zip, APP_SIGNATURE_FILENAME)) {
printf("%s does not exist\n", APP_SIGNATURE_FILENAME); fprintf(stderr, "%s does not exist\n", APP_SIGNATURE_FILENAME);
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
dataSize = zipReadFileDataByName(&data, ctx->appx_ctx->zip, APP_SIGNATURE_FILENAME); dataSize = zipReadFileDataByName(&data, ctx->appx_ctx->zip, APP_SIGNATURE_FILENAME);
@ -527,7 +527,7 @@ static PKCS7 *appx_pkcs7_extract(FILE_FORMAT_CTX *ctx)
} }
/* P7X format is just 0x504B4358 (PKCX) followed by PKCS#7 data in the DER format */ /* P7X format is just 0x504B4358 (PKCX) followed by PKCS#7 data in the DER format */
if (memcmp(data, PKCX_SIGNATURE, 4)) { if (memcmp(data, PKCX_SIGNATURE, 4)) {
printf("Invalid PKCX header\n"); fprintf(stderr, "Invalid PKCX header\n");
OPENSSL_free(data); OPENSSL_free(data);
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
@ -556,7 +556,7 @@ static int appx_remove_pkcs7(FILE_FORMAT_CTX *ctx, BIO *hash, BIO *outdata)
(void)hash; (void)hash;
if (!entry) { if (!entry) {
printf("Not a valid .appx file: content types file missing\n"); fprintf(stderr, "Not a valid .appx file: content types file missing\n");
return 1; /* FAILED */ return 1; /* FAILED */
} }
/* read signature data */ /* read signature data */
@ -566,17 +566,17 @@ static int appx_remove_pkcs7(FILE_FORMAT_CTX *ctx, BIO *hash, BIO *outdata)
} }
OPENSSL_free(data); OPENSSL_free(data);
if (!appx_remove_ct_signature_entry(zip, entry)) { if (!appx_remove_ct_signature_entry(zip, entry)) {
printf("Failed to remove signature entry\n"); fprintf(stderr, "Failed to remove signature entry\n");
return 1; /* FAILED */ return 1; /* FAILED */
} }
for (entry = zip->centralDirectoryHead; entry != NULL; entry = entry->next) { for (entry = zip->centralDirectoryHead; entry != NULL; entry = entry->next) {
if (noEntries == zip->centralDirectoryRecordCount) { if (noEntries == zip->centralDirectoryRecordCount) {
printf("Warning: Corrupted central directory structure\n"); fprintf(stderr, "Corrupted central directory structure\n");
return 1; /* FAILED */ return 1; /* FAILED */
} }
noEntries++; noEntries++;
if (!entry->fileName || (entry->fileNameLen == 0)) { if (!entry->fileName || (entry->fileNameLen == 0)) {
printf("Warning: Corrupted file name\n"); fprintf(stderr, "Corrupted file name\n");
return 1; /* FAILED */ return 1; /* FAILED */
} }
if (strcmp(entry->fileName, APP_SIGNATURE_FILENAME)) { if (strcmp(entry->fileName, APP_SIGNATURE_FILENAME)) {
@ -587,11 +587,11 @@ static int appx_remove_pkcs7(FILE_FORMAT_CTX *ctx, BIO *hash, BIO *outdata)
} }
} }
if (!get_current_position(outdata, &cdOffset)) { if (!get_current_position(outdata, &cdOffset)) {
printf("Unable to get offset\n"); fprintf(stderr, "Unable to get offset\n");
return 1; /* FAILED */ return 1; /* FAILED */
} }
if (!appx_write_central_directory(outdata, zip, 1, cdOffset)) { if (!appx_write_central_directory(outdata, zip, 1, cdOffset)) {
printf("Unable to write central directory\n"); fprintf(stderr, "Unable to write central directory\n");
return 1; /* FAILED */ return 1; /* FAILED */
} }
return 0; /* OK */ return 0; /* OK */
@ -615,7 +615,7 @@ static int appx_process_data(FILE_FORMAT_CTX *ctx, BIO *hash, BIO *outdata)
/* Create and append a new signature content types entry */ /* Create and append a new signature content types entry */
entry = zipGetCDEntryByName(ctx->appx_ctx->zip, CONTENT_TYPES_FILENAME); entry = zipGetCDEntryByName(ctx->appx_ctx->zip, CONTENT_TYPES_FILENAME);
if (!entry) { if (!entry) {
printf("Not a valid .appx file: content types file missing\n"); fprintf(stderr, "Not a valid .appx file: content types file missing\n");
return 0; /* FAILED */ return 0; /* FAILED */
} }
if (!appx_append_ct_signature_entry(ctx->appx_ctx->zip, entry)) { if (!appx_append_ct_signature_entry(ctx->appx_ctx->zip, entry)) {
@ -646,12 +646,12 @@ static PKCS7 *appx_pkcs7_signature_new(FILE_FORMAT_CTX *ctx, BIO *hash)
} }
p7 = pkcs7_create(ctx); p7 = pkcs7_create(ctx);
if (!p7) { if (!p7) {
printf("Creating a new signature failed\n"); fprintf(stderr, "Creating a new signature failed\n");
BIO_free_all(hashes); BIO_free_all(hashes);
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
if (!add_indirect_data_object(p7)) { if (!add_indirect_data_object(p7)) {
printf("Adding SPC_INDIRECT_DATA_OBJID failed\n"); fprintf(stderr, "Adding SPC_INDIRECT_DATA_OBJID failed\n");
PKCS7_free(p7); PKCS7_free(p7);
BIO_free_all(hashes); BIO_free_all(hashes);
return NULL; /* FAILED */ return NULL; /* FAILED */
@ -659,12 +659,12 @@ static PKCS7 *appx_pkcs7_signature_new(FILE_FORMAT_CTX *ctx, BIO *hash)
content = spc_indirect_data_content_get(hashes, ctx); content = spc_indirect_data_content_get(hashes, ctx);
BIO_free_all(hashes); BIO_free_all(hashes);
if (!content) { if (!content) {
printf("Failed to get spcIndirectDataContent\n"); fprintf(stderr, "Failed to get spcIndirectDataContent\n");
PKCS7_free(p7); PKCS7_free(p7);
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
if (!sign_spc_indirect_data_content(p7, content)) { if (!sign_spc_indirect_data_content(p7, content)) {
printf("Failed to set signed content\n"); fprintf(stderr, "Failed to set signed content\n");
PKCS7_free(p7); PKCS7_free(p7);
ASN1_OCTET_STRING_free(content); ASN1_OCTET_STRING_free(content);
return NULL; /* FAILED */ return NULL; /* FAILED */
@ -692,13 +692,13 @@ static int appx_append_pkcs7(FILE_FORMAT_CTX *ctx, BIO *outdata, PKCS7 *p7)
for (entry = zip->centralDirectoryHead; entry != NULL;) { for (entry = zip->centralDirectoryHead; entry != NULL;) {
if (noEntries >= zip->centralDirectoryRecordCount) { if (noEntries >= zip->centralDirectoryRecordCount) {
printf("Warning: Corrupted central directory structure\n"); fprintf(stderr, "Corrupted central directory structure\n");
return 1; /* FAILED */ return 1; /* FAILED */
} }
noEntries++; noEntries++;
last = entry; last = entry;
if (!entry->fileName || (entry->fileNameLen == 0)) { if (!entry->fileName || (entry->fileNameLen == 0)) {
printf("Warning: Corrupted file name\n"); fprintf(stderr, "Corrupted file name\n");
return 1; /* FAILED */ return 1; /* FAILED */
} }
if (strcmp(entry->fileName, APP_SIGNATURE_FILENAME)) { if (strcmp(entry->fileName, APP_SIGNATURE_FILENAME)) {
@ -738,17 +738,17 @@ static int appx_append_pkcs7(FILE_FORMAT_CTX *ctx, BIO *outdata, PKCS7 *p7)
len += 4; len += 4;
if (!zipAppendSignatureFile(outdata, zip, blob, (uint64_t)len)) { if (!zipAppendSignatureFile(outdata, zip, blob, (uint64_t)len)) {
OPENSSL_free(blob); OPENSSL_free(blob);
printf("Failed to append zip file\n"); fprintf(stderr, "Failed to append zip file\n");
return 1; /* FAILED */ return 1; /* FAILED */
} }
OPENSSL_free(der); OPENSSL_free(der);
OPENSSL_free(blob); OPENSSL_free(blob);
if (!get_current_position(outdata, &cdOffset)) { if (!get_current_position(outdata, &cdOffset)) {
printf("Unable to get offset\n"); fprintf(stderr, "Unable to get offset\n");
return 1; /* FAILED */ return 1; /* FAILED */
} }
if (!appx_write_central_directory(outdata, zip, 0, cdOffset)) { if (!appx_write_central_directory(outdata, zip, 0, cdOffset)) {
printf("Unable to write central directory\n"); fprintf(stderr, "Unable to write central directory\n");
return 1; /* FAILED */ return 1; /* FAILED */
} }
return 0; /* OK */ return 0; /* OK */
@ -811,11 +811,11 @@ static BIO *appx_calculate_hashes(FILE_FORMAT_CTX *ctx)
if (!ctx->appx_ctx->calculatedBMHash || !ctx->appx_ctx->calculatedCTHash if (!ctx->appx_ctx->calculatedBMHash || !ctx->appx_ctx->calculatedCTHash
|| !ctx->appx_ctx->calculatedCDHash || !ctx->appx_ctx->calculatedDataHash) { || !ctx->appx_ctx->calculatedCDHash || !ctx->appx_ctx->calculatedDataHash) {
printf("One or more hashes calculation failed\n"); fprintf(stderr, "One or more hashes calculation failed\n");
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
if (zipEntryExist(ctx->appx_ctx->zip, CODE_INTEGRITY_FILENAME) && !ctx->appx_ctx->calculatedCIHash) { if (zipEntryExist(ctx->appx_ctx->zip, CODE_INTEGRITY_FILENAME) && !ctx->appx_ctx->calculatedCIHash) {
printf("Code integrity file exists, but CI hash calculation failed\n"); fprintf(stderr, "Code integrity file exists, but CI hash calculation failed\n");
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
return appx_hash_blob_get(ctx); return appx_hash_blob_get(ctx);
@ -879,13 +879,13 @@ static uint8_t *appx_calc_zip_central_directory_hash(ZIP_FILE *zip, const EVP_MD
BIO *bhash = BIO_new(BIO_f_md()); BIO *bhash = BIO_new(BIO_f_md());
if (!BIO_set_md(bhash, md)) { if (!BIO_set_md(bhash, md)) {
printf("Unable to set the message digest of BIO\n"); fprintf(stderr, "Unable to set the message digest of BIO\n");
BIO_free_all(bhash); BIO_free_all(bhash);
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
BIO_push(bhash, BIO_new(BIO_s_null())); BIO_push(bhash, BIO_new(BIO_s_null()));
if (!appx_write_central_directory(bhash, zip, 1, cdOffset)) { if (!appx_write_central_directory(bhash, zip, 1, cdOffset)) {
printf("Unable to write central directory\n"); fprintf(stderr, "Unable to write central directory\n");
BIO_free_all(bhash); BIO_free_all(bhash);
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
@ -913,11 +913,11 @@ static int appx_write_central_directory(BIO *bio, ZIP_FILE *zip, int removeSigna
/* the signature file is considered non existent for hashing purposes */ /* the signature file is considered non existent for hashing purposes */
uint64_t sizeOnDisk = 0; uint64_t sizeOnDisk = 0;
if (noEntries > zip->centralDirectoryRecordCount) { if (noEntries > zip->centralDirectoryRecordCount) {
printf("Warning: Corrupted central directory structure\n"); fprintf(stderr, "Corrupted central directory structure\n");
return 0; /* FAILED */ return 0; /* FAILED */
} }
if (!entry->fileName || (entry->fileNameLen == 0)) { if (!entry->fileName || (entry->fileNameLen == 0)) {
printf("Warning: Corrupted file name\n"); fprintf(stderr, "Corrupted file name\n");
return 0; /* FAILED */ return 0; /* FAILED */
} }
if (removeSignature && !strcmp(entry->fileName, APP_SIGNATURE_FILENAME)) { if (removeSignature && !strcmp(entry->fileName, APP_SIGNATURE_FILENAME)) {
@ -1006,7 +1006,7 @@ static uint8_t *appx_calc_zip_data_hash(uint64_t *cdOffset, ZIP_FILE *zip, const
uint64_t noEntries = 0; uint64_t noEntries = 0;
if (!BIO_set_md(bhash, md)) { if (!BIO_set_md(bhash, md)) {
printf("Unable to set the message digest of BIO\n"); fprintf(stderr, "Unable to set the message digest of BIO\n");
BIO_free_all(bhash); BIO_free_all(bhash);
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
@ -1016,13 +1016,13 @@ static uint8_t *appx_calc_zip_data_hash(uint64_t *cdOffset, ZIP_FILE *zip, const
/* the signature file is considered not existent for hashing purposes */ /* the signature file is considered not existent for hashing purposes */
uint64_t sizeOnDisk = 0; uint64_t sizeOnDisk = 0;
if (noEntries >= zip->centralDirectoryRecordCount) { if (noEntries >= zip->centralDirectoryRecordCount) {
printf("Warning: Corrupted central directory structure\n"); fprintf(stderr, "Corrupted central directory structure\n");
BIO_free_all(bhash); BIO_free_all(bhash);
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
noEntries++; noEntries++;
if (!entry->fileName || (entry->fileNameLen == 0)) { if (!entry->fileName || (entry->fileNameLen == 0)) {
printf("Warning: Corrupted file name\n"); fprintf(stderr, "Corrupted file name\n");
BIO_free_all(bhash); BIO_free_all(bhash);
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
@ -1030,7 +1030,7 @@ static uint8_t *appx_calc_zip_data_hash(uint64_t *cdOffset, ZIP_FILE *zip, const
continue; continue;
} }
if (!zipRewriteData(zip, entry, bhash, &sizeOnDisk)) { if (!zipRewriteData(zip, entry, bhash, &sizeOnDisk)) {
printf("Rewrite data error\n"); fprintf(stderr, "Rewrite data error\n");
BIO_free_all(bhash); BIO_free_all(bhash);
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
@ -1060,7 +1060,7 @@ static int appx_extract_hashes(FILE_FORMAT_CTX *ctx, SpcIndirectDataContent *con
long d = ASN1_INTEGER_get(si->d); long d = ASN1_INTEGER_get(si->d);
long e = ASN1_INTEGER_get(si->e); long e = ASN1_INTEGER_get(si->e);
long f = ASN1_INTEGER_get(si->f); long f = ASN1_INTEGER_get(si->f);
BIO *stdbio = BIO_new_fp(stdout, BIO_NOCLOSE); BIO *stdbio = BIO_new_fp(stderr, BIO_NOCLOSE);
printf("a: 0x%lX b: 0x%lX c: 0x%lX d: 0x%lX e: 0x%lX f: 0x%lX\n", a, b, c, d, e, f); printf("a: 0x%lX b: 0x%lX c: 0x%lX d: 0x%lX e: 0x%lX f: 0x%lX\n", a, b, c, d, e, f);
printf("string: "); printf("string: ");
ASN1_STRING_print_ex(stdbio, si->string, ASN1_STRFLGS_RFC2253); ASN1_STRING_print_ex(stdbio, si->string, ASN1_STRFLGS_RFC2253);
@ -1075,11 +1075,11 @@ static int appx_extract_hashes(FILE_FORMAT_CTX *ctx, SpcIndirectDataContent *con
/* we are expecting at least 4 hashes + 4 byte header */ /* we are expecting at least 4 hashes + 4 byte header */
if (length < 4 * mdlen + 4) { if (length < 4 * mdlen + 4) {
printf("Hash too short\n"); fprintf(stderr, "Hash too short\n");
return 0; /* FAILED */ return 0; /* FAILED */
} }
if (memcmp(data, APPX_SIGNATURE, 4)) { if (memcmp(data, APPX_SIGNATURE, 4)) {
printf("Hash signature does not match\n"); fprintf(stderr, "Hash signature does not match\n");
return 0; /* FAILED */ return 0; /* FAILED */
} }
while (pos + mdlen + 4 <= length) { while (pos + mdlen + 4 <= length) {
@ -1099,29 +1099,29 @@ static int appx_extract_hashes(FILE_FORMAT_CTX *ctx, SpcIndirectDataContent *con
ctx->appx_ctx->existingCIHash = OPENSSL_malloc((size_t)mdlen); ctx->appx_ctx->existingCIHash = OPENSSL_malloc((size_t)mdlen);
memcpy(ctx->appx_ctx->existingCIHash, data + pos + 4, (size_t)mdlen); memcpy(ctx->appx_ctx->existingCIHash, data + pos + 4, (size_t)mdlen);
} else { } else {
printf("Invalid hash signature\n"); fprintf(stderr, "Invalid hash signature\n");
return 0; /* FAILED */ return 0; /* FAILED */
} }
pos += mdlen + 4; pos += mdlen + 4;
} }
if (!ctx->appx_ctx->existingDataHash) { if (!ctx->appx_ctx->existingDataHash) {
printf("File hash missing\n"); fprintf(stderr, "File hash missing\n");
return 0; /* FAILED */ return 0; /* FAILED */
} }
if (!ctx->appx_ctx->existingCDHash) { if (!ctx->appx_ctx->existingCDHash) {
printf("Central directory hash missing\n"); fprintf(stderr, "Central directory hash missing\n");
return 0; /* FAILED */ return 0; /* FAILED */
} }
if (!ctx->appx_ctx->existingBMHash) { if (!ctx->appx_ctx->existingBMHash) {
printf("Block map hash missing\n"); fprintf(stderr, "Block map hash missing\n");
return 0; /* FAILED */ return 0; /* FAILED */
} }
if (!ctx->appx_ctx->existingCTHash) { if (!ctx->appx_ctx->existingCTHash) {
printf("Content types hash missing\n"); fprintf(stderr, "Content types hash missing\n");
return 0; /* FAILED */ return 0; /* FAILED */
} }
if (zipEntryExist(ctx->appx_ctx->zip, CODE_INTEGRITY_FILENAME) && !ctx->appx_ctx->existingCIHash) { if (zipEntryExist(ctx->appx_ctx->zip, CODE_INTEGRITY_FILENAME) && !ctx->appx_ctx->existingCIHash) {
printf("Code integrity hash missing\n"); fprintf(stderr, "Code integrity hash missing\n");
return 0; /* FAILED */ return 0; /* FAILED */
} }
return 1; /* OK */ return 1; /* OK */
@ -1142,7 +1142,7 @@ static int appx_compare_hashes(FILE_FORMAT_CTX *ctx)
return 0; /* FAILED */ return 0; /* FAILED */
} }
} else { } else {
printf("Block map hash missing\n"); fprintf(stderr, "Block map hash missing\n");
return 0; /* FAILED */ return 0; /* FAILED */
} }
if (ctx->appx_ctx->calculatedCTHash && ctx->appx_ctx->existingCTHash) { if (ctx->appx_ctx->calculatedCTHash && ctx->appx_ctx->existingCTHash) {
@ -1151,7 +1151,7 @@ static int appx_compare_hashes(FILE_FORMAT_CTX *ctx)
return 0; /* FAILED */ return 0; /* FAILED */
} }
} else { } else {
printf("Content Types hash missing\n"); fprintf(stderr, "Content Types hash missing\n");
return 0; /* FAILED */ return 0; /* FAILED */
} }
if (ctx->appx_ctx->calculatedDataHash && ctx->appx_ctx->existingDataHash) { if (ctx->appx_ctx->calculatedDataHash && ctx->appx_ctx->existingDataHash) {
@ -1160,7 +1160,7 @@ static int appx_compare_hashes(FILE_FORMAT_CTX *ctx)
return 0; /* FAILED */ return 0; /* FAILED */
} }
} else { } else {
printf("Central Directory hash missing\n"); fprintf(stderr, "Central Directory hash missing\n");
return 0; /* FAILED */ return 0; /* FAILED */
} }
if (ctx->appx_ctx->calculatedCDHash && ctx->appx_ctx->existingCDHash) { if (ctx->appx_ctx->calculatedCDHash && ctx->appx_ctx->existingCDHash) {
@ -1169,7 +1169,7 @@ static int appx_compare_hashes(FILE_FORMAT_CTX *ctx)
return 0; /* FAILED */ return 0; /* FAILED */
} }
} else { } else {
printf("Central Directory hash missing\n"); fprintf(stderr, "Central Directory hash missing\n");
return 0; /* FAILED */ return 0; /* FAILED */
} }
if (ctx->appx_ctx->calculatedCIHash && ctx->appx_ctx->existingCIHash) { if (ctx->appx_ctx->calculatedCIHash && ctx->appx_ctx->existingCIHash) {
@ -1180,7 +1180,7 @@ static int appx_compare_hashes(FILE_FORMAT_CTX *ctx)
} else if (!ctx->appx_ctx->calculatedCIHash && !ctx->appx_ctx->existingCIHash) { } else if (!ctx->appx_ctx->calculatedCIHash && !ctx->appx_ctx->existingCIHash) {
/* this is fine, CI file is optional -> if it is missing we expect both hashes to be non existent */ /* this is fine, CI file is optional -> if it is missing we expect both hashes to be non existent */
} else { } else {
printf("Code Integrity hash missing\n"); fprintf(stderr, "Code Integrity hash missing\n");
return 0; /* FAILED */ return 0; /* FAILED */
} }
return 1; /* OK */ return 1; /* OK */
@ -1205,7 +1205,7 @@ static int appx_remove_ct_signature_entry(ZIP_FILE *zip, ZIP_CENTRAL_DIRECTORY_E
} }
cpos = strstr((const char *)data, SIGNATURE_CONTENT_TYPES_ENTRY); cpos = strstr((const char *)data, SIGNATURE_CONTENT_TYPES_ENTRY);
if (!cpos) { if (!cpos) {
printf("Did not find existing signature entry in %s\n", entry->fileName); printf("Warning: Did not find existing signature entry in %s\n", entry->fileName);
OPENSSL_free(data); OPENSSL_free(data);
return 1; /* do not treat as en error */ return 1; /* do not treat as en error */
} }
@ -1243,7 +1243,7 @@ static int appx_append_ct_signature_entry(ZIP_FILE *zip, ZIP_CENTRAL_DIRECTORY_E
} }
cpos = strstr((const char *)data, SIGNATURE_CONTENT_TYPES_CLOSING_TAG); cpos = strstr((const char *)data, SIGNATURE_CONTENT_TYPES_CLOSING_TAG);
if (!cpos) { if (!cpos) {
printf("%s parsing error\n", entry->fileName); fprintf(stderr, "%s parsing error\n", entry->fileName);
OPENSSL_free(data); OPENSSL_free(data);
return 0; /* FAILED */ return 0; /* FAILED */
} }
@ -1275,24 +1275,24 @@ static const EVP_MD *appx_get_md(ZIP_FILE *zip)
dataSize = zipReadFileDataByName(&data, zip, BLOCK_MAP_FILENAME); dataSize = zipReadFileDataByName(&data, zip, BLOCK_MAP_FILENAME);
if (dataSize <= 0) { if (dataSize <= 0) {
printf("Could not read: %s\n", BLOCK_MAP_FILENAME); fprintf(stderr, "Could not read: %s\n", BLOCK_MAP_FILENAME);
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
start = strstr((const char *)data, HASH_METHOD_TAG); start = strstr((const char *)data, HASH_METHOD_TAG);
if (!start) { if (!start) {
printf("Parse error: tag: %s not found in %s\n", HASH_METHOD_TAG, BLOCK_MAP_FILENAME); fprintf(stderr, "Parse error: tag: %s not found in %s\n", HASH_METHOD_TAG, BLOCK_MAP_FILENAME);
OPENSSL_free(data); OPENSSL_free(data);
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
start += strlen(HASH_METHOD_TAG); start += strlen(HASH_METHOD_TAG);
if ((uint8_t *)start >= data + dataSize) { if ((uint8_t *)start >= data + dataSize) {
printf("Parse error: data too short in %s\n", BLOCK_MAP_FILENAME); fprintf(stderr, "Parse error: data too short in %s\n", BLOCK_MAP_FILENAME);
OPENSSL_free(data); OPENSSL_free(data);
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
end = strstr((const char *)start, ">"); end = strstr((const char *)start, ">");
if (!end) { if (!end) {
printf("Parse error: end of tag not found in %s\n", BLOCK_MAP_FILENAME); fprintf(stderr, "Parse error: end of tag not found in %s\n", BLOCK_MAP_FILENAME);
OPENSSL_free(data); OPENSSL_free(data);
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
@ -1306,7 +1306,7 @@ static const EVP_MD *appx_get_md(ZIP_FILE *zip)
} }
} }
if (!valueStart || !valueEnd || valueEnd <= valueStart) { if (!valueStart || !valueEnd || valueEnd <= valueStart) {
printf("Parse error: value parse error in %s\n", BLOCK_MAP_FILENAME); fprintf(stderr, "Parse error: value parse error in %s\n", BLOCK_MAP_FILENAME);
OPENSSL_free(data); OPENSSL_free(data);
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
@ -1321,7 +1321,7 @@ static const EVP_MD *appx_get_md(ZIP_FILE *zip)
printf("Hash method is SHA512\n"); printf("Hash method is SHA512\n");
md = EVP_sha512(); md = EVP_sha512();
} else { } else {
printf("Unsupported hash method\n"); fprintf(stderr, "Unsupported hash method\n");
OPENSSL_free(data); OPENSSL_free(data);
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
@ -1342,12 +1342,12 @@ static ZIP_CENTRAL_DIRECTORY_ENTRY *zipGetCDEntryByName(ZIP_FILE *zip, const cha
for (entry = zip->centralDirectoryHead; entry != NULL; entry = entry->next) { for (entry = zip->centralDirectoryHead; entry != NULL; entry = entry->next) {
if (noEntries >= zip->centralDirectoryRecordCount) { if (noEntries >= zip->centralDirectoryRecordCount) {
printf("Warning: Corrupted central directory structure\n"); fprintf(stderr, "Corrupted central directory structure\n");
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
noEntries++; noEntries++;
if (!entry->fileName || (entry->fileNameLen == 0)) { if (!entry->fileName || (entry->fileNameLen == 0)) {
printf("Warning: Corrupted file name\n"); fprintf(stderr, "Corrupted file name\n");
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
if (!strcmp(entry->fileName, name)) { if (!strcmp(entry->fileName, name)) {
@ -1454,7 +1454,7 @@ static int zipAppendSignatureFile(BIO *bio, ZIP_FILE *zip, uint8_t *data, uint64
dataToWrite = OPENSSL_malloc(dataSize); dataToWrite = OPENSSL_malloc(dataSize);
ret = zipDeflate(dataToWrite, &size, data, dataSize); ret = zipDeflate(dataToWrite, &size, data, dataSize);
if (ret != Z_OK) { if (ret != Z_OK) {
printf("Zip deflate failed: %d\n", ret); fprintf(stderr, "Zip deflate failed: %d\n", ret);
OPENSSL_free(dataToWrite); OPENSSL_free(dataToWrite);
return 0; /* FAILED */ return 0; /* FAILED */
} }
@ -1492,7 +1492,7 @@ static int zipAppendSignatureFile(BIO *bio, ZIP_FILE *zip, uint8_t *data, uint64
header.extraFieldLen = 0; header.extraFieldLen = 0;
if (!get_current_position(bio, &offset)) { if (!get_current_position(bio, &offset)) {
printf("Unable to get offset\n"); fprintf(stderr, "Unable to get offset\n");
OPENSSL_free(dataToWrite); OPENSSL_free(dataToWrite);
return 0; /* FAILED */ return 0; /* FAILED */
} }
@ -1577,7 +1577,7 @@ static int zipOverrideFileData(ZIP_CENTRAL_DIRECTORY_ENTRY *entry, uint8_t *data
size = dataSize; size = dataSize;
ret = zipDeflate(entry->overrideData->data, &size, data, dataSize); ret = zipDeflate(entry->overrideData->data, &size, data, dataSize);
if (ret != Z_OK) { if (ret != Z_OK) {
printf("Zip deflate failed: %d\n", ret); fprintf(stderr, "Zip deflate failed: %d\n", ret);
return 0; /* FAILED */ return 0; /* FAILED */
} }
entry->overrideData->compressedSize = size; entry->overrideData->compressedSize = size;
@ -1599,7 +1599,7 @@ static int zipRewriteData(ZIP_FILE *zip, ZIP_CENTRAL_DIRECTORY_ENTRY *entry, BIO
memset(&header, 0, sizeof(header)); memset(&header, 0, sizeof(header));
if (entry->offsetOfLocalHeader >= (uint64_t)zip->fileSize) { if (entry->offsetOfLocalHeader >= (uint64_t)zip->fileSize) {
printf("Corrupted relative offset of local header : 0x%08" PRIX64 "\n", entry->offsetOfLocalHeader); fprintf(stderr, "Corrupted relative offset of local header : 0x%08" PRIX64 "\n", entry->offsetOfLocalHeader);
return 0; /* FAILED */ return 0; /* FAILED */
} }
if (fseeko(zip->file, (int64_t)entry->offsetOfLocalHeader, SEEK_SET) < 0) { if (fseeko(zip->file, (int64_t)entry->offsetOfLocalHeader, SEEK_SET) < 0) {
@ -1620,7 +1620,7 @@ static int zipRewriteData(ZIP_FILE *zip, ZIP_CENTRAL_DIRECTORY_ENTRY *entry, BIO
return 0; /* FAILED */ return 0; /* FAILED */
} }
if (entry->compressedSize > (uint64_t)zip->fileSize - entry->offsetOfLocalHeader) { if (entry->compressedSize > (uint64_t)zip->fileSize - entry->offsetOfLocalHeader) {
printf("Corrupted compressedSize : 0x%08" PRIX64 "\n", entry->compressedSize); fprintf(stderr, "Corrupted compressedSize : 0x%08" PRIX64 "\n", entry->compressedSize);
return 0; /* FAILED */ return 0; /* FAILED */
} }
if (fseeko(zip->file, (int64_t)entry->compressedSize, SEEK_CUR) < 0) { if (fseeko(zip->file, (int64_t)entry->compressedSize, SEEK_CUR) < 0) {
@ -1724,12 +1724,12 @@ static int zipEntryExist(ZIP_FILE *zip, const char *name)
for (entry = zip->centralDirectoryHead; entry != NULL; entry = entry->next) { for (entry = zip->centralDirectoryHead; entry != NULL; entry = entry->next) {
if (noEntries >= zip->centralDirectoryRecordCount) { if (noEntries >= zip->centralDirectoryRecordCount) {
printf("Warning: Corrupted central directory structure\n"); fprintf(stderr, "Corrupted central directory structure\n");
return 0; /* FAILED */ return 0; /* FAILED */
} }
noEntries++; noEntries++;
if (!entry->fileName || (entry->fileNameLen == 0)) { if (!entry->fileName || (entry->fileNameLen == 0)) {
printf("Warning: Corrupted file name\n"); fprintf(stderr, "Corrupted file name\n");
return 0; /* FAILED */ return 0; /* FAILED */
} }
if (!strcmp(entry->fileName, name)) { if (!strcmp(entry->fileName, name)) {
@ -1759,7 +1759,7 @@ static u_char *zipCalcDigest(ZIP_FILE *zip, const char *fileName, const EVP_MD *
} }
bhash = BIO_new(BIO_f_md()); bhash = BIO_new(BIO_f_md());
if (!BIO_set_md(bhash, md)) { if (!BIO_set_md(bhash, md)) {
printf("Unable to set the message digest of BIO\n"); fprintf(stderr, "Unable to set the message digest of BIO\n");
OPENSSL_free(data); OPENSSL_free(data);
BIO_free_all(bhash); BIO_free_all(bhash);
return NULL; /* FAILED */ return NULL; /* FAILED */
@ -1792,12 +1792,12 @@ static size_t zipReadFileDataByName(uint8_t **pData, ZIP_FILE *zip, const char *
for (entry = zip->centralDirectoryHead; entry != NULL; entry = entry->next) { for (entry = zip->centralDirectoryHead; entry != NULL; entry = entry->next) {
if (noEntries >= zip->centralDirectoryRecordCount) { if (noEntries >= zip->centralDirectoryRecordCount) {
printf("Warning: Corrupted central directory structure\n"); fprintf(stderr, "Corrupted central directory structure\n");
return 0; /* FAILED */ return 0; /* FAILED */
} }
noEntries++; noEntries++;
if (!entry->fileName || (entry->fileNameLen == 0)) { if (!entry->fileName || (entry->fileNameLen == 0)) {
printf("Warning: Corrupted file name\n"); fprintf(stderr, "Corrupted file name\n");
return 0; /* FAILED */ return 0; /* FAILED */
} }
if (!strcmp(entry->fileName, name)) { if (!strcmp(entry->fileName, name)) {
@ -1823,7 +1823,7 @@ static size_t zipReadFileData(ZIP_FILE *zip, uint8_t **pData, ZIP_CENTRAL_DIRECT
size_t size, dataSize = 0; size_t size, dataSize = 0;
if (entry->offsetOfLocalHeader >= (uint64_t)zip->fileSize) { if (entry->offsetOfLocalHeader >= (uint64_t)zip->fileSize) {
printf("Corrupted relative offset of local header : 0x%08" PRIX64 "\n", entry->offsetOfLocalHeader); fprintf(stderr, "Corrupted relative offset of local header : 0x%08" PRIX64 "\n", entry->offsetOfLocalHeader);
return 0; /* FAILED */ return 0; /* FAILED */
} }
if (fseeko(file, (int64_t)entry->offsetOfLocalHeader, SEEK_SET) < 0) { if (fseeko(file, (int64_t)entry->offsetOfLocalHeader, SEEK_SET) < 0) {
@ -1847,7 +1847,7 @@ static size_t zipReadFileData(ZIP_FILE *zip, uint8_t **pData, ZIP_CENTRAL_DIRECT
|| header.compressedSize != compressedSize || header.compressedSize != compressedSize
|| header.uncompressedSize != uncompressedSize || header.uncompressedSize != uncompressedSize
|| header.compression != entry->compression) { || header.compression != entry->compression) {
printf("Local header does not match central directory entry\n"); fprintf(stderr, "Local header does not match central directory entry\n");
return 0; /* FAILED */ return 0; /* FAILED */
} }
/* we don't really need those */ /* we don't really need those */
@ -1855,7 +1855,7 @@ static size_t zipReadFileData(ZIP_FILE *zip, uint8_t **pData, ZIP_CENTRAL_DIRECT
OPENSSL_free(header.extraField); OPENSSL_free(header.extraField);
if (compressedSize > (uint64_t)zip->fileSize - entry->offsetOfLocalHeader) { if (compressedSize > (uint64_t)zip->fileSize - entry->offsetOfLocalHeader) {
printf("Corrupted compressedSize : 0x%08" PRIX64 "\n", entry->compressedSize); fprintf(stderr, "Corrupted compressedSize : 0x%08" PRIX64 "\n", entry->compressedSize);
return 0; /* FAILED */ return 0; /* FAILED */
} }
compressedData = OPENSSL_zalloc(compressedSize + 1); compressedData = OPENSSL_zalloc(compressedSize + 1);
@ -1883,7 +1883,7 @@ static size_t zipReadFileData(ZIP_FILE *zip, uint8_t **pData, ZIP_CENTRAL_DIRECT
OPENSSL_free(compressedData); OPENSSL_free(compressedData);
if (ret != Z_OK) { if (ret != Z_OK) {
printf("Data decompresssion failed, zlib error: %d\n", ret); fprintf(stderr, "Data decompresssion failed, zlib error: %d\n", ret);
OPENSSL_free(uncompressedData); OPENSSL_free(uncompressedData);
return 0; /* FAILED */ return 0; /* FAILED */
} else { } else {
@ -1895,7 +1895,7 @@ static size_t zipReadFileData(ZIP_FILE *zip, uint8_t **pData, ZIP_CENTRAL_DIRECT
dataSize = destLen; dataSize = destLen;
} }
} else { } else {
printf("Unsupported compression mode: %d\n", entry->compression); fprintf(stderr, "Unsupported compression mode: %d\n", entry->compression);
OPENSSL_free(compressedData); OPENSSL_free(compressedData);
return 0; /* FAILED */ return 0; /* FAILED */
} }
@ -1920,7 +1920,7 @@ static int zipReadLocalHeader(ZIP_LOCAL_HEADER *header, ZIP_FILE *zip, uint64_t
return 0; /* FAILED */ return 0; /* FAILED */
} }
if (memcmp(signature, PKZIP_LH_SIGNATURE, 4)) { if (memcmp(signature, PKZIP_LH_SIGNATURE, 4)) {
printf("The input file is not a valid zip file - local header signature does not match\n"); fprintf(stderr, "The input file is not a valid zip file - local header signature does not match\n");
return 0; /* FAILED */ return 0; /* FAILED */
} }
/* version needed to extract (2 bytes) */ /* version needed to extract (2 bytes) */
@ -1972,7 +1972,7 @@ static int zipReadLocalHeader(ZIP_LOCAL_HEADER *header, ZIP_FILE *zip, uint64_t
return 0; /* FAILED */ return 0; /* FAILED */
} }
if (compressedSize > (uint64_t)(zip->fileSize - offset)) { if (compressedSize > (uint64_t)(zip->fileSize - offset)) {
printf("Corrupted compressedSize : 0x%08" PRIX64 "\n", compressedSize); fprintf(stderr, "Corrupted compressedSize : 0x%08" PRIX64 "\n", compressedSize);
return 0; /* FAILED */ return 0; /* FAILED */
} }
if (fseeko(file, (int64_t)compressedSize, SEEK_CUR) < 0) { if (fseeko(file, (int64_t)compressedSize, SEEK_CUR) < 0) {
@ -1983,7 +1983,7 @@ static int zipReadLocalHeader(ZIP_LOCAL_HEADER *header, ZIP_FILE *zip, uint64_t
return 0; /* FAILED */ return 0; /* FAILED */
} }
if (memcmp(signature, PKZIP_DATA_DESCRIPTOR_SIGNATURE, 4)) { if (memcmp(signature, PKZIP_DATA_DESCRIPTOR_SIGNATURE, 4)) {
printf("The input file is not a valid zip file - flags indicate data descriptor, but data descriptor signature does not match\n"); fprintf(stderr, "The input file is not a valid zip file - flags indicate data descriptor, but data descriptor signature does not match\n");
OPENSSL_free(header->fileName); OPENSSL_free(header->fileName);
OPENSSL_free(header->extraField); OPENSSL_free(header->extraField);
return 0; /* FAILED */ return 0; /* FAILED */
@ -2007,7 +2007,7 @@ static int zipReadLocalHeader(ZIP_LOCAL_HEADER *header, ZIP_FILE *zip, uint64_t
uint16_t op = bufferGetU16(header->extraField, &pos); uint16_t op = bufferGetU16(header->extraField, &pos);
if (op != ZIP64_HEADER) { if (op != ZIP64_HEADER) {
printf("Expected zip64 header in local header extra field, got : 0x%X\n", op); fprintf(stderr, "Expected zip64 header in local header extra field, got : 0x%X\n", op);
OPENSSL_free(header->fileName); OPENSSL_free(header->fileName);
OPENSSL_free(header->extraField); OPENSSL_free(header->extraField);
header->fileName = NULL; header->fileName = NULL;
@ -2020,7 +2020,7 @@ static int zipReadLocalHeader(ZIP_LOCAL_HEADER *header, ZIP_FILE *zip, uint64_t
header->uncompressedSize = bufferGetU64(header->extraField, &pos); header->uncompressedSize = bufferGetU64(header->extraField, &pos);
header->uncompressedSizeInZip64 = 1; header->uncompressedSizeInZip64 = 1;
} else { } else {
printf("Invalid zip64 local header entry\n"); fprintf(stderr, "Invalid zip64 local header entry\n");
OPENSSL_free(header->fileName); OPENSSL_free(header->fileName);
OPENSSL_free(header->extraField); OPENSSL_free(header->extraField);
header->fileName = NULL; header->fileName = NULL;
@ -2033,7 +2033,7 @@ static int zipReadLocalHeader(ZIP_LOCAL_HEADER *header, ZIP_FILE *zip, uint64_t
header->compressedSize = bufferGetU64(header->extraField, &pos); header->compressedSize = bufferGetU64(header->extraField, &pos);
header->compressedSizeInZip64 = 1; header->compressedSizeInZip64 = 1;
} else { } else {
printf("Invalid zip64 local header entry\n"); fprintf(stderr, "Invalid zip64 local header entry\n");
OPENSSL_free(header->fileName); OPENSSL_free(header->fileName);
OPENSSL_free(header->extraField); OPENSSL_free(header->extraField);
header->fileName = NULL; header->fileName = NULL;
@ -2212,7 +2212,7 @@ static ZIP_FILE *openZip(const char *filename)
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
if (zip->locator.eocdOffset >= (uint64_t)zip->fileSize) { if (zip->locator.eocdOffset >= (uint64_t)zip->fileSize) {
printf("Corrupted end of central directory locator offset : 0x%08" PRIX64 "\n", zip->locator.eocdOffset); fprintf(stderr, "Corrupted end of central directory locator offset : 0x%08" PRIX64 "\n", zip->locator.eocdOffset);
freeZip(zip); freeZip(zip);
return 0; /* FAILED */ return 0; /* FAILED */
} }
@ -2241,13 +2241,13 @@ static ZIP_FILE *openZip(const char *filename)
zip->centralDirectorySize = zip->eocdr.centralDirectorySize; zip->centralDirectorySize = zip->eocdr.centralDirectorySize;
zip->centralDirectoryRecordCount = (uint64_t)zip->eocdr.totalEntries; zip->centralDirectoryRecordCount = (uint64_t)zip->eocdr.totalEntries;
if (zip->centralDirectoryRecordCount > UINT16_MAX) { if (zip->centralDirectoryRecordCount > UINT16_MAX) {
printf("Corrupted total number of entries in the central directory : 0x%08" PRIX64 "\n", zip->centralDirectoryRecordCount); fprintf(stderr, "Corrupted total number of entries in the central directory : 0x%08" PRIX64 "\n", zip->centralDirectoryRecordCount);
freeZip(zip); freeZip(zip);
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
} }
if (zip->centralDirectoryOffset >= (uint64_t)zip->fileSize) { if (zip->centralDirectoryOffset >= (uint64_t)zip->fileSize) {
printf("Corrupted central directory offset : 0x%08" PRIX64 "\n", zip->centralDirectoryOffset); fprintf(stderr, "Corrupted central directory offset : 0x%08" PRIX64 "\n", zip->centralDirectoryOffset);
freeZip(zip); freeZip(zip);
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
@ -2308,26 +2308,26 @@ static ZIP_FILE *zipSortCentralDirectory(ZIP_FILE *zip)
for (entry = zip->centralDirectoryHead; entry != NULL; entry = entry->next) { for (entry = zip->centralDirectoryHead; entry != NULL; entry = entry->next) {
if (noEntries >= zip->centralDirectoryRecordCount) { if (noEntries >= zip->centralDirectoryRecordCount) {
printf("Corrupted central directory structure\n"); fprintf(stderr, "Corrupted central directory structure\n");
sk_ZIP_CENTRAL_DIRECTORY_ENTRY_free(chain); sk_ZIP_CENTRAL_DIRECTORY_ENTRY_free(chain);
freeZip(zip); freeZip(zip);
return NULL; return NULL; /* FAILED */
} }
noEntries++; noEntries++;
if (!sk_ZIP_CENTRAL_DIRECTORY_ENTRY_push(chain, entry)) { if (!sk_ZIP_CENTRAL_DIRECTORY_ENTRY_push(chain, entry)) {
printf("Failed to add central directory entry\n"); fprintf(stderr, "Failed to add central directory entry\n");
sk_ZIP_CENTRAL_DIRECTORY_ENTRY_free(chain); sk_ZIP_CENTRAL_DIRECTORY_ENTRY_free(chain);
freeZip(zip); freeZip(zip);
return NULL; return NULL; /* FAILED */
} }
} }
sk_ZIP_CENTRAL_DIRECTORY_ENTRY_sort(chain); sk_ZIP_CENTRAL_DIRECTORY_ENTRY_sort(chain);
zip->centralDirectoryHead = entry = sk_ZIP_CENTRAL_DIRECTORY_ENTRY_value(chain, 0); zip->centralDirectoryHead = entry = sk_ZIP_CENTRAL_DIRECTORY_ENTRY_value(chain, 0);
if (!entry) { if (!entry) {
printf("Failed to get sorted central directory entry\n"); fprintf(stderr, "Failed to get sorted central directory entry\n");
sk_ZIP_CENTRAL_DIRECTORY_ENTRY_free(chain); sk_ZIP_CENTRAL_DIRECTORY_ENTRY_free(chain);
freeZip(zip); freeZip(zip);
return NULL; return NULL; /* FAILED */
} }
for (i=1; i<sk_ZIP_CENTRAL_DIRECTORY_ENTRY_num(chain); i++) { for (i=1; i<sk_ZIP_CENTRAL_DIRECTORY_ENTRY_num(chain); i++) {
entry->next = sk_ZIP_CENTRAL_DIRECTORY_ENTRY_value(chain, i); entry->next = sk_ZIP_CENTRAL_DIRECTORY_ENTRY_value(chain, i);
@ -2384,7 +2384,7 @@ static int zipReadCentralDirectory(ZIP_FILE *zip, FILE *file)
} else if (!zip->centralDirectoryHead) { } else if (!zip->centralDirectoryHead) {
zip->centralDirectoryHead = entry; zip->centralDirectoryHead = entry;
} else { } else {
printf("Corrupted central directory structure\n"); fprintf(stderr, "Corrupted central directory structure\n");
OPENSSL_free(entry); OPENSSL_free(entry);
return 0; /* FAILED */ return 0; /* FAILED */
} }
@ -2408,7 +2408,7 @@ static ZIP_CENTRAL_DIRECTORY_ENTRY *zipReadNextCentralDirectoryEntry(FILE *file)
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
if (memcmp(signature, PKZIP_CD_SIGNATURE, 4)) { if (memcmp(signature, PKZIP_CD_SIGNATURE, 4)) {
printf("The input file is not a valid zip file - could not find Central Directory record\n"); fprintf(stderr, "The input file is not a valid zip file - could not find Central Directory record\n");
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
entry = OPENSSL_zalloc(sizeof(ZIP_CENTRAL_DIRECTORY_ENTRY)); entry = OPENSSL_zalloc(sizeof(ZIP_CENTRAL_DIRECTORY_ENTRY));
@ -2487,7 +2487,7 @@ static ZIP_CENTRAL_DIRECTORY_ENTRY *zipReadNextCentralDirectoryEntry(FILE *file)
uint16_t header = bufferGetU16(entry->extraField, &pos); uint16_t header = bufferGetU16(entry->extraField, &pos);
if (header != ZIP64_HEADER) { if (header != ZIP64_HEADER) {
printf("Expected zip64 header in central directory extra field, got : 0x%X\n", header); fprintf(stderr, "Expected zip64 header in central directory extra field, got : 0x%X\n", header);
freeZipCentralDirectoryEntry(entry); freeZipCentralDirectoryEntry(entry);
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
@ -2497,7 +2497,7 @@ static ZIP_CENTRAL_DIRECTORY_ENTRY *zipReadNextCentralDirectoryEntry(FILE *file)
entry->uncompressedSize = bufferGetU64(entry->extraField, &pos); entry->uncompressedSize = bufferGetU64(entry->extraField, &pos);
entry->uncompressedSizeInZip64 = 1; entry->uncompressedSizeInZip64 = 1;
} else { } else {
printf("Invalid zip64 central directory entry\n"); fprintf(stderr, "Invalid zip64 central directory entry\n");
freeZipCentralDirectoryEntry(entry); freeZipCentralDirectoryEntry(entry);
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
@ -2507,7 +2507,7 @@ static ZIP_CENTRAL_DIRECTORY_ENTRY *zipReadNextCentralDirectoryEntry(FILE *file)
entry->compressedSize = bufferGetU64(entry->extraField, &pos); entry->compressedSize = bufferGetU64(entry->extraField, &pos);
entry->compressedSizeInZip64 = 1; entry->compressedSizeInZip64 = 1;
} else { } else {
printf("Invalid zip64 central directory entry\n"); fprintf(stderr, "Invalid zip64 central directory entry\n");
freeZipCentralDirectoryEntry(entry); freeZipCentralDirectoryEntry(entry);
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
@ -2517,7 +2517,7 @@ static ZIP_CENTRAL_DIRECTORY_ENTRY *zipReadNextCentralDirectoryEntry(FILE *file)
entry->offsetOfLocalHeader = bufferGetU64(entry->extraField, &pos); entry->offsetOfLocalHeader = bufferGetU64(entry->extraField, &pos);
entry->offsetInZip64 = 1; entry->offsetInZip64 = 1;
} else { } else {
printf("Invalid zip64 central directory entry\n"); fprintf(stderr, "Invalid zip64 central directory entry\n");
freeZipCentralDirectoryEntry(entry); freeZipCentralDirectoryEntry(entry);
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
@ -2527,7 +2527,7 @@ static ZIP_CENTRAL_DIRECTORY_ENTRY *zipReadNextCentralDirectoryEntry(FILE *file)
entry->diskNoStart = bufferGetU32(entry->extraField, &pos); entry->diskNoStart = bufferGetU32(entry->extraField, &pos);
entry->diskNoInZip64 = 1; entry->diskNoInZip64 = 1;
} else { } else {
printf("Invalid zip64 central directory entry\n"); fprintf(stderr, "Invalid zip64 central directory entry\n");
freeZipCentralDirectoryEntry(entry); freeZipCentralDirectoryEntry(entry);
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
@ -2604,7 +2604,7 @@ static int readZipEOCDR(ZIP_EOCDR *eocdr, FILE *file)
eocdr->centralDirectoryDiskNumber != eocdr->diskNumber || eocdr->centralDirectoryDiskNumber != eocdr->diskNumber ||
eocdr->diskEntries != eocdr->totalEntries) eocdr->diskEntries != eocdr->totalEntries)
{ {
printf("The input file is a multipart archive - not supported\n"); fprintf(stderr, "The input file is a multipart archive - not supported\n");
return 0; /* FAILED */ return 0; /* FAILED */
} }
#endif #endif
@ -2640,7 +2640,7 @@ static int readZip64EOCDLocator(ZIP64_EOCD_LOCATOR *locator, FILE *file)
return 0; /* FAILED */ return 0; /* FAILED */
} }
if (memcmp(signature, PKZIP64_EOCD_LOCATOR_SIGNATURE, 4)) { if (memcmp(signature, PKZIP64_EOCD_LOCATOR_SIGNATURE, 4)) {
printf("The input file is not a valid zip file - could not find zip64 EOCD locator\n"); fprintf(stderr, "The input file is not a valid zip file - could not find zip64 EOCD locator\n");
return 0; /* FAILED */ return 0; /* FAILED */
} }
locator->diskWithEOCD = fileGetU32(file); locator->diskWithEOCD = fileGetU32(file);
@ -2669,7 +2669,7 @@ static int readZip64EOCDR(ZIP64_EOCDR *eocdr, FILE *file, uint64_t offset)
return 0; /* FAILED */ return 0; /* FAILED */
} }
if (memcmp(signature, PKZIP64_EOCDR_SIGNATURE, 4)) { if (memcmp(signature, PKZIP64_EOCDR_SIGNATURE, 4)) {
printf("The input file is not a valid zip file - could not find zip64 End of Central Directory record\n"); fprintf(stderr, "The input file is not a valid zip file - could not find zip64 End of Central Directory record\n");
return 0; /* FAILED */ return 0; /* FAILED */
} }
/* size of zip64 end of central directory record (8 bytes) */ /* size of zip64 end of central directory record (8 bytes) */
@ -2694,7 +2694,7 @@ static int readZip64EOCDR(ZIP64_EOCDR *eocdr, FILE *file, uint64_t offset)
/* zip64 extensible data sector (comment) */ /* zip64 extensible data sector (comment) */
eocdr->commentLen = eocdr->eocdrSize - 44; eocdr->commentLen = eocdr->eocdrSize - 44;
if (eocdr->commentLen > UINT16_MAX) { if (eocdr->commentLen > UINT16_MAX) {
printf("Corrupted file comment length : 0x%08" PRIX64 "\n", eocdr->commentLen); fprintf(stderr, "Corrupted file comment length : 0x%08" PRIX64 "\n", eocdr->commentLen);
return 0; /* FAILED */ return 0; /* FAILED */
} }
if (eocdr->commentLen > 0) { if (eocdr->commentLen > 0) {
@ -2707,7 +2707,7 @@ static int readZip64EOCDR(ZIP64_EOCDR *eocdr, FILE *file, uint64_t offset)
if (eocdr->diskWithCentralDirectory > 1 || eocdr->diskNumber > 1 || if (eocdr->diskWithCentralDirectory > 1 || eocdr->diskNumber > 1 ||
eocdr->diskWithCentralDirectory != eocdr->diskNumber || eocdr->diskWithCentralDirectory != eocdr->diskNumber ||
eocdr->totalEntries != eocdr->diskEntries) { eocdr->totalEntries != eocdr->diskEntries) {
printf("The input file is a multipart archive - not supported\n"); fprintf(stderr, "The input file is a multipart archive - not supported\n");
return 0; /* FAILED */ return 0; /* FAILED */
} }
return 1; /* OK */ return 1; /* OK */

58
cab.c
View File

@ -206,7 +206,7 @@ static u_char *cab_digest_calc(FILE_FORMAT_CTX *ctx, const EVP_MD *md)
BIO *bhash = BIO_new(BIO_f_md()); BIO *bhash = BIO_new(BIO_f_md());
if (!BIO_set_md(bhash, md)) { if (!BIO_set_md(bhash, md)) {
printf("Unable to set the message digest of BIO\n"); fprintf(stderr, "Unable to set the message digest of BIO\n");
BIO_free_all(bhash); BIO_free_all(bhash);
return 0; /* FAILED */ return 0; /* FAILED */
} }
@ -296,7 +296,7 @@ static u_char *cab_digest_calc(FILE_FORMAT_CTX *ctx, const EVP_MD *md)
nfolders--; nfolders--;
} }
if (idx != coffFiles) { if (idx != coffFiles) {
printf("Corrupt coffFiles value: 0x%08X\n", coffFiles); fprintf(stderr, "Corrupt coffFiles value: 0x%08X\n", coffFiles);
BIO_free_all(bhash); BIO_free_all(bhash);
return 0; /* FAILED */ return 0; /* FAILED */
} }
@ -307,7 +307,7 @@ static u_char *cab_digest_calc(FILE_FORMAT_CTX *ctx, const EVP_MD *md)
} }
/* (variable) ab - the compressed data bytes */ /* (variable) ab - the compressed data bytes */
if (!bio_hash_data(bhash, ctx->options->indata, idx, fileend)) { if (!bio_hash_data(bhash, ctx->options->indata, idx, fileend)) {
printf("Unable to calculate digest\n"); fprintf(stderr, "Unable to calculate digest\n");
BIO_free_all(bhash); BIO_free_all(bhash);
return 0; /* FAILED */ return 0; /* FAILED */
} }
@ -343,17 +343,17 @@ static int cab_verify_digests(FILE_FORMAT_CTX *ctx, PKCS7 *p7)
} }
} }
if (mdtype == -1) { if (mdtype == -1) {
printf("Failed to extract current message digest\n\n"); fprintf(stderr, "Failed to extract current message digest\n\n");
return 0; /* FAILED */ return 0; /* FAILED */
} }
md = EVP_get_digestbynid(mdtype); md = EVP_get_digestbynid(mdtype);
cmdbuf = cab_digest_calc(ctx, md); cmdbuf = cab_digest_calc(ctx, md);
if (!cmdbuf) { if (!cmdbuf) {
printf("Failed to calculate message digest\n\n"); fprintf(stderr, "Failed to calculate message digest\n\n");
return 0; /* FAILED */ return 0; /* FAILED */
} }
if (!compare_digests(mdbuf, cmdbuf, mdtype)) { if (!compare_digests(mdbuf, cmdbuf, mdtype)) {
printf("Signature verification: failed\n\n"); fprintf(stderr, "Signature verification: failed\n\n");
OPENSSL_free(cmdbuf); OPENSSL_free(cmdbuf);
return 0; /* FAILED */ return 0; /* FAILED */
} }
@ -443,7 +443,7 @@ static int cab_remove_pkcs7(FILE_FORMAT_CTX *ctx, BIO *hash, BIO *outdata)
BIO_write(outdata, ctx->options->indata + 32, 4); BIO_write(outdata, ctx->options->indata + 32, 4);
idx = cab_write_optional_names(outdata, ctx->options->indata, 60, flags); idx = cab_write_optional_names(outdata, ctx->options->indata, 60, flags);
if (idx >= ctx->cab_ctx->fileend) { if (idx >= ctx->cab_ctx->fileend) {
printf("Corrupt CAB file - too short\n"); fprintf(stderr, "Corrupt CAB file - too short\n");
OPENSSL_free(buf); OPENSSL_free(buf);
return 0; /* FAILED */ return 0; /* FAILED */
} }
@ -453,7 +453,7 @@ static int cab_remove_pkcs7(FILE_FORMAT_CTX *ctx, BIO *hash, BIO *outdata)
*/ */
nfolders = GET_UINT16_LE(ctx->options->indata + 26); nfolders = GET_UINT16_LE(ctx->options->indata + 26);
if (nfolders * 8 >= ctx->cab_ctx->fileend - idx) { if (nfolders * 8 >= ctx->cab_ctx->fileend - idx) {
printf("Corrupt cFolders value: 0x%08X\n", nfolders); fprintf(stderr, "Corrupt cFolders value: 0x%08X\n", nfolders);
OPENSSL_free(buf); OPENSSL_free(buf);
return 0; /* FAILED */ return 0; /* FAILED */
} }
@ -510,26 +510,26 @@ static PKCS7 *cab_pkcs7_signature_new(FILE_FORMAT_CTX *ctx, BIO *hash)
PKCS7 *p7 = pkcs7_create(ctx); PKCS7 *p7 = pkcs7_create(ctx);
if (!p7) { if (!p7) {
printf("Creating a new signature failed\n"); fprintf(stderr, "Creating a new signature failed\n");
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
if (ctx->options->jp >= 0 && !cab_add_jp_attribute(p7, ctx->options->jp)) { if (ctx->options->jp >= 0 && !cab_add_jp_attribute(p7, ctx->options->jp)) {
printf("Adding jp attribute failed\n"); fprintf(stderr, "Adding jp attribute failed\n");
PKCS7_free(p7); PKCS7_free(p7);
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
if (!add_indirect_data_object(p7)) { if (!add_indirect_data_object(p7)) {
printf("Adding SPC_INDIRECT_DATA_OBJID failed\n"); fprintf(stderr, "Adding SPC_INDIRECT_DATA_OBJID failed\n");
PKCS7_free(p7); PKCS7_free(p7);
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
content = spc_indirect_data_content_get(hash, ctx); content = spc_indirect_data_content_get(hash, ctx);
if (!content) { if (!content) {
printf("Failed to get spcIndirectDataContent\n"); fprintf(stderr, "Failed to get spcIndirectDataContent\n");
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
if (!sign_spc_indirect_data_content(p7, content)) { if (!sign_spc_indirect_data_content(p7, content)) {
printf("Failed to set signed content\n"); fprintf(stderr, "Failed to set signed content\n");
PKCS7_free(p7); PKCS7_free(p7);
ASN1_OCTET_STRING_free(content); ASN1_OCTET_STRING_free(content);
return NULL; /* FAILED */ return NULL; /* FAILED */
@ -556,7 +556,7 @@ static int cab_append_pkcs7(FILE_FORMAT_CTX *ctx, BIO *outdata, PKCS7 *p7)
if (((len = i2d_PKCS7(p7, NULL)) <= 0) if (((len = i2d_PKCS7(p7, NULL)) <= 0)
|| (p = OPENSSL_malloc((size_t)len)) == NULL) { || (p = OPENSSL_malloc((size_t)len)) == NULL) {
printf("i2d_PKCS memory allocation failed: %d\n", len); fprintf(stderr, "i2d_PKCS memory allocation failed: %d\n", len);
return 1; /* FAILED */ return 1; /* FAILED */
} }
i2d_PKCS7(p7, &p); i2d_PKCS7(p7, &p);
@ -653,19 +653,19 @@ static CAB_CTX *cab_ctx_get(char *indata, uint32_t filesize)
uint16_t flags; uint16_t flags;
if (filesize < 44) { if (filesize < 44) {
printf("CAB file is too short\n"); fprintf(stderr, "CAB file is too short\n");
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
reserved = GET_UINT32_LE(indata + 4); reserved = GET_UINT32_LE(indata + 4);
if (reserved) { if (reserved) {
printf("Reserved1: 0x%08X\n", reserved); fprintf(stderr, "Reserved1: 0x%08X\n", reserved);
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
/* flags specify bit-mapped values that indicate the presence of optional data */ /* flags specify bit-mapped values that indicate the presence of optional data */
flags = GET_UINT16_LE(indata + 30); flags = GET_UINT16_LE(indata + 30);
if (flags & FLAG_PREV_CABINET) { if (flags & FLAG_PREV_CABINET) {
/* FLAG_NEXT_CABINET works */ /* FLAG_NEXT_CABINET works */
printf("Multivolume cabinet file is unsupported: flags 0x%04X\n", flags); fprintf(stderr, "Multivolume cabinet file is unsupported: flags 0x%04X\n", flags);
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
if (flags & FLAG_RESERVE_PRESENT) { if (flags & FLAG_RESERVE_PRESENT) {
@ -675,12 +675,12 @@ static CAB_CTX *cab_ctx_get(char *indata, uint32_t filesize)
*/ */
header_size = GET_UINT32_LE(indata + 36); header_size = GET_UINT32_LE(indata + 36);
if (header_size != 20) { if (header_size != 20) {
printf("Additional header size: 0x%08X\n", header_size); fprintf(stderr, "Additional header size: 0x%08X\n", header_size);
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
reserved = GET_UINT32_LE(indata + 40); reserved = GET_UINT32_LE(indata + 40);
if (reserved != 0x00100000) { if (reserved != 0x00100000) {
printf("abReserved: 0x%08X\n", reserved); fprintf(stderr, "abReserved: 0x%08X\n", reserved);
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
/* /*
@ -695,13 +695,13 @@ static CAB_CTX *cab_ctx_get(char *indata, uint32_t filesize)
sigpos = GET_UINT32_LE(indata + 44); sigpos = GET_UINT32_LE(indata + 44);
siglen = GET_UINT32_LE(indata + 48); siglen = GET_UINT32_LE(indata + 48);
if ((sigpos < filesize && sigpos + siglen != filesize) || (sigpos >= filesize)) { if ((sigpos < filesize && sigpos + siglen != filesize) || (sigpos >= filesize)) {
printf("Additional data offset:\t%u bytes\nAdditional data size:\t%u bytes\n", fprintf(stderr, "Additional data offset:\t%u bytes\nAdditional data size:\t%u bytes\n",
sigpos, siglen); sigpos, siglen);
printf("File size:\t\t%u bytes\n", filesize); fprintf(stderr, "File size:\t\t%u bytes\n", filesize);
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
if ((sigpos > 0 && siglen == 0) || (sigpos == 0 && siglen > 0)) { if ((sigpos > 0 && siglen == 0) || (sigpos == 0 && siglen > 0)) {
printf("Corrupt signature\n"); fprintf(stderr, "Corrupt signature\n");
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
} }
@ -852,7 +852,7 @@ static int cab_modify_header(FILE_FORMAT_CTX *ctx, BIO *hash, BIO *outdata)
idx = cab_write_optional_names(outdata, ctx->options->indata, 60, flags); idx = cab_write_optional_names(outdata, ctx->options->indata, 60, flags);
if (idx >= ctx->cab_ctx->fileend) { if (idx >= ctx->cab_ctx->fileend) {
printf("Corrupt CAB file - too short\n"); fprintf(stderr, "Corrupt CAB file - too short\n");
return 0; /* FAILED */ return 0; /* FAILED */
} }
/* /*
@ -861,7 +861,7 @@ static int cab_modify_header(FILE_FORMAT_CTX *ctx, BIO *hash, BIO *outdata)
*/ */
nfolders = GET_UINT16_LE(ctx->options->indata + 26); nfolders = GET_UINT16_LE(ctx->options->indata + 26);
if (nfolders * 8 >= ctx->cab_ctx->fileend - idx) { if (nfolders * 8 >= ctx->cab_ctx->fileend - idx) {
printf("Corrupt cFolders value: 0x%08X\n", nfolders); fprintf(stderr, "Corrupt cFolders value: 0x%08X\n", nfolders);
return 0; /* FAILED */ return 0; /* FAILED */
} }
while (nfolders) { while (nfolders) {
@ -936,7 +936,7 @@ static int cab_add_header(FILE_FORMAT_CTX *ctx, BIO *hash, BIO *outdata)
idx = cab_write_optional_names(outdata, ctx->options->indata, 36, flags); idx = cab_write_optional_names(outdata, ctx->options->indata, 36, flags);
if (idx >= ctx->cab_ctx->fileend) { if (idx >= ctx->cab_ctx->fileend) {
printf("Corrupt CAB file - too short\n"); fprintf(stderr, "Corrupt CAB file - too short\n");
OPENSSL_free(buf); OPENSSL_free(buf);
return 0; /* FAILED */ return 0; /* FAILED */
} }
@ -946,7 +946,7 @@ static int cab_add_header(FILE_FORMAT_CTX *ctx, BIO *hash, BIO *outdata)
*/ */
nfolders = GET_UINT16_LE(ctx->options->indata + 26); nfolders = GET_UINT16_LE(ctx->options->indata + 26);
if (nfolders * 8 >= ctx->cab_ctx->fileend - idx) { if (nfolders * 8 >= ctx->cab_ctx->fileend - idx) {
printf("Corrupt cFolders value: 0x%08X\n", nfolders); fprintf(stderr, "Corrupt cFolders value: 0x%08X\n", nfolders);
OPENSSL_free(buf); OPENSSL_free(buf);
return 0; /* FAILED */ return 0; /* FAILED */
} }
@ -979,16 +979,16 @@ static int cab_add_header(FILE_FORMAT_CTX *ctx, BIO *hash, BIO *outdata)
static int cab_check_file(FILE_FORMAT_CTX *ctx) static int cab_check_file(FILE_FORMAT_CTX *ctx)
{ {
if (!ctx) { if (!ctx) {
printf("Init error\n\n"); fprintf(stderr, "Init error\n");
return 0; /* FAILED */ return 0; /* FAILED */
} }
if (ctx->cab_ctx->header_size != 20) { if (ctx->cab_ctx->header_size != 20) {
printf("No signature found\n\n"); fprintf(stderr, "No signature found\n");
return 0; /* FAILED */ return 0; /* FAILED */
} }
if (ctx->cab_ctx->sigpos == 0 || ctx->cab_ctx->siglen == 0 if (ctx->cab_ctx->sigpos == 0 || ctx->cab_ctx->siglen == 0
|| ctx->cab_ctx->sigpos > ctx->cab_ctx->fileend) { || ctx->cab_ctx->sigpos > ctx->cab_ctx->fileend) {
printf("No signature found\n\n"); fprintf(stderr, "No signature found\n");
return 0; /* FAILED */ return 0; /* FAILED */
} }
return 1; /* OK */ return 1; /* OK */

28
cat.c
View File

@ -82,7 +82,7 @@ static FILE_FORMAT_CTX *cat_ctx_new(GLOBAL_OPTIONS *options, BIO *hash, BIO *out
uint32_t filesize; uint32_t filesize;
if (options->cmd == CMD_REMOVE || options->cmd==CMD_ATTACH || options->cmd == CMD_EXTRACT_DATA) { if (options->cmd == CMD_REMOVE || options->cmd==CMD_ATTACH || options->cmd == CMD_EXTRACT_DATA) {
printf("Unsupported command\n"); fprintf(stderr, "Unsupported command\n");
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
filesize = get_file_size(options->infile); filesize = get_file_size(options->infile);
@ -158,21 +158,21 @@ static PKCS7 *cat_pkcs7_signature_new(FILE_FORMAT_CTX *ctx, BIO *hash)
p7 = pkcs7_create(ctx); p7 = pkcs7_create(ctx);
if (!p7) { if (!p7) {
printf("Creating a new signature failed\n"); fprintf(stderr, "Creating a new signature failed\n");
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
if (!cat_add_ms_ctl_object(p7)) { if (!cat_add_ms_ctl_object(p7)) {
printf("Adding MS_CTL_OBJID failed\n"); fprintf(stderr, "Adding MS_CTL_OBJID failed\n");
PKCS7_free(p7); PKCS7_free(p7);
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
if (!ctx->cat_ctx->p7 || !ctx->cat_ctx->p7->d.sign || !ctx->cat_ctx->p7->d.sign->contents) { if (!ctx->cat_ctx->p7 || !ctx->cat_ctx->p7->d.sign || !ctx->cat_ctx->p7->d.sign->contents) {
printf("Failed to get content\n"); fprintf(stderr, "Failed to get content\n");
PKCS7_free(p7); PKCS7_free(p7);
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
if (!cat_sign_ms_ctl_content(p7, ctx->cat_ctx->p7->d.sign->contents)) { if (!cat_sign_ms_ctl_content(p7, ctx->cat_ctx->p7->d.sign->contents)) {
printf("Failed to set signed content\n"); fprintf(stderr, "Failed to set signed content\n");
PKCS7_free(p7); PKCS7_free(p7);
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
@ -287,7 +287,7 @@ static int cat_sign_ms_ctl_content(PKCS7 *p7, PKCS7 *contents)
if (!contents->d.other || !contents->d.other->value.sequence if (!contents->d.other || !contents->d.other->value.sequence
|| !contents->d.other->value.sequence->data) { || !contents->d.other->value.sequence->data) {
printf("Failed to get content value\n"); fprintf(stderr, "Failed to get content value\n");
return 0; /* FAILED */ return 0; /* FAILED */
} }
seqhdrlen = asn1_simple_hdr_len(contents->d.other->value.sequence->data, seqhdrlen = asn1_simple_hdr_len(contents->d.other->value.sequence->data,
@ -296,11 +296,11 @@ static int cat_sign_ms_ctl_content(PKCS7 *p7, PKCS7 *contents)
content_length = contents->d.other->value.sequence->length - seqhdrlen; content_length = contents->d.other->value.sequence->length - seqhdrlen;
if (!pkcs7_sign_content(p7, content, content_length)) { if (!pkcs7_sign_content(p7, content, content_length)) {
printf("Failed to sign content\n"); fprintf(stderr, "Failed to sign content\n");
return 0; /* FAILED */ return 0; /* FAILED */
} }
if (!PKCS7_set_content(p7, PKCS7_dup(contents))) { if (!PKCS7_set_content(p7, PKCS7_dup(contents))) {
printf("PKCS7_set_content failed\n"); fprintf(stderr, "PKCS7_set_content failed\n");
return 0; /* FAILED */ return 0; /* FAILED */
} }
return 1; /* OK */ return 1; /* OK */
@ -318,7 +318,7 @@ static int cat_list_content(PKCS7 *p7)
ctlc = ms_ctl_content_get(p7); ctlc = ms_ctl_content_get(p7);
if (!ctlc) { if (!ctlc) {
printf("Failed to extract MS_CTL_OBJID data\n"); fprintf(stderr, "Failed to extract MS_CTL_OBJID data\n");
return 1; /* FAILED */ return 1; /* FAILED */
} }
printf("\nCatalog members:\n"); printf("\nCatalog members:\n");
@ -353,7 +353,7 @@ static int cat_list_content(PKCS7 *p7)
printf("\n"); printf("\n");
} }
MsCtlContent_free(ctlc); MsCtlContent_free(ctlc);
ERR_print_errors_fp(stdout); ERR_print_errors_fp(stderr);
return 0; /* OK */ return 0; /* OK */
} }
@ -382,7 +382,7 @@ static int cat_print_content_member_digest(ASN1_TYPE *content)
} }
SpcIndirectDataContent_free(idc); SpcIndirectDataContent_free(idc);
if (mdtype == -1) { if (mdtype == -1) {
printf("Failed to extract current message digest\n\n"); fprintf(stderr, "Failed to extract current message digest\n\n");
return 0; /* FAILED */ return 0; /* FAILED */
} }
printf("\tHash algorithm: %s\n", OBJ_nid2sn(mdtype)); printf("\tHash algorithm: %s\n", OBJ_nid2sn(mdtype));
@ -461,17 +461,17 @@ static int cat_check_file(FILE_FORMAT_CTX *ctx)
PKCS7_SIGNER_INFO *si; PKCS7_SIGNER_INFO *si;
if (!ctx) { if (!ctx) {
printf("Init error\n\n"); fprintf(stderr, "Init error\n");
return 0; /* FAILED */ return 0; /* FAILED */
} }
signer_info = PKCS7_get_signer_info(ctx->cat_ctx->p7); signer_info = PKCS7_get_signer_info(ctx->cat_ctx->p7);
if (!signer_info) { if (!signer_info) {
printf("Failed catalog file\n\n"); fprintf(stderr, "Failed catalog file\n");
return 0; /* FAILED */ return 0; /* FAILED */
} }
si = sk_PKCS7_SIGNER_INFO_value(signer_info, 0); si = sk_PKCS7_SIGNER_INFO_value(signer_info, 0);
if (!si) { if (!si) {
printf("No signature found\n\n"); fprintf(stderr, "No signature found\n");
return 0; /* FAILED */ return 0; /* FAILED */
} }
if (ctx->options->verbose) { if (ctx->options->verbose) {

View File

@ -37,16 +37,16 @@ uint32_t get_file_size(const char *infile)
ret = stat(infile, &st); ret = stat(infile, &st);
#endif #endif
if (ret) { if (ret) {
printf("Failed to open file: %s\n", infile); fprintf(stderr, "Failed to open file: %s\n", infile);
return 0; return 0;
} }
if (st.st_size < 4) { if (st.st_size < 4) {
printf("Unrecognized file type - file is too short: %s\n", infile); fprintf(stderr, "Unrecognized file type - file is too short: %s\n", infile);
return 0; return 0;
} }
if (st.st_size > UINT32_MAX) { if (st.st_size > UINT32_MAX) {
printf("Unsupported file - too large: %s\n", infile); fprintf(stderr, "Unsupported file - too large: %s\n", infile);
return 0; return 0;
} }
return (uint32_t)st.st_size; return (uint32_t)st.st_size;
@ -86,7 +86,7 @@ char *map_file(const char *infile, const size_t size)
} }
close(fd); close(fd);
#else #else
printf("No file mapping function\n"); fprintf(stderr, "No file mapping function\n");
return NULL; return NULL;
#endif /* HAVE_SYS_MMAN_H */ #endif /* HAVE_SYS_MMAN_H */
#endif /* WIN32 */ #endif /* WIN32 */
@ -152,7 +152,7 @@ int data_write_pkcs7(FILE_FORMAT_CTX *ctx, BIO *outdata, PKCS7 *p7)
ret = !i2d_PKCS7_bio(outdata, p7); ret = !i2d_PKCS7_bio(outdata, p7);
} }
if (ret) { if (ret) {
printf("Unable to write pkcs7 object\n"); fprintf(stderr, "Unable to write pkcs7 object\n");
} }
return ret; return ret;
} }
@ -193,9 +193,9 @@ PKCS7 *pkcs7_create(FILE_FORMAT_CTX *ctx)
} }
} }
if (si == NULL) { if (si == NULL) {
printf("Failed to checking the consistency of a private key: %s\n", fprintf(stderr, "Failed to checking the consistency of a private key: %s\n",
ctx->options->keyfile); ctx->options->keyfile);
printf(" with a public key in any X509 certificate: %s\n\n", fprintf(stderr, " with a public key in any X509 certificate: %s\n\n",
ctx->options->certfile); ctx->options->certfile);
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
@ -208,7 +208,7 @@ PKCS7 *pkcs7_create(FILE_FORMAT_CTX *ctx)
} }
if ((ctx->options->desc || ctx->options->url) && if ((ctx->options->desc || ctx->options->url) &&
!pkcs7_signer_info_add_spc_sp_opus_info(si, ctx)) { !pkcs7_signer_info_add_spc_sp_opus_info(si, ctx)) {
printf("Couldn't allocate memory for opus info\n"); fprintf(stderr, "Couldn't allocate memory for opus info\n");
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
if ((ctx->options->nested_number >= 0) && if ((ctx->options->nested_number >= 0) &&
@ -218,7 +218,7 @@ PKCS7 *pkcs7_create(FILE_FORMAT_CTX *ctx)
/* create X509 chain sorted in ascending order by their DER encoding */ /* create X509 chain sorted in ascending order by their DER encoding */
chain = X509_chain_get_sorted(ctx, signer); chain = X509_chain_get_sorted(ctx, signer);
if (chain == NULL) { if (chain == NULL) {
printf("Failed to create a sorted certificate chain\n"); fprintf(stderr, "Failed to create a sorted certificate chain\n");
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
/* add sorted certificate chain */ /* add sorted certificate chain */
@ -278,11 +278,12 @@ int sign_spc_indirect_data_content(PKCS7 *p7, ASN1_OCTET_STRING *content)
inf = ASN1_get_object(&p, &plen, &tag, &class, len); inf = ASN1_get_object(&p, &plen, &tag, &class, len);
if (inf != V_ASN1_CONSTRUCTED || tag != V_ASN1_SEQUENCE if (inf != V_ASN1_CONSTRUCTED || tag != V_ASN1_SEQUENCE
|| !pkcs7_sign_content(p7, p, (int)plen)) { || !pkcs7_sign_content(p7, p, (int)plen)) {
printf("Failed to sign spcIndirectDataContent\n"); fprintf(stderr, "Failed to sign spcIndirectDataContent\n");
return 0; /* FAILED */ return 0; /* FAILED */
} }
td7 = PKCS7_new(); td7 = PKCS7_new();
if (!td7) { if (!td7) {
fprintf(stderr, "PKCS7_new failed\n");
return 0; /* FAILED */ return 0; /* FAILED */
} }
td7->type = OBJ_txt2obj(SPC_INDIRECT_DATA_OBJID, 1); td7->type = OBJ_txt2obj(SPC_INDIRECT_DATA_OBJID, 1);
@ -291,7 +292,7 @@ int sign_spc_indirect_data_content(PKCS7 *p7, ASN1_OCTET_STRING *content)
td7->d.other->value.sequence = ASN1_STRING_new(); td7->d.other->value.sequence = ASN1_STRING_new();
ASN1_STRING_set(td7->d.other->value.sequence, data, len); ASN1_STRING_set(td7->d.other->value.sequence, data, len);
if (!PKCS7_set_content(p7, td7)) { if (!PKCS7_set_content(p7, td7)) {
printf("PKCS7_set_content failed\n"); fprintf(stderr, "PKCS7_set_content failed\n");
PKCS7_free(td7); PKCS7_free(td7);
return 0; /* FAILED */ return 0; /* FAILED */
} }
@ -388,13 +389,13 @@ int pkcs7_sign_content(PKCS7 *p7, const u_char *data, int len)
BIO *p7bio; BIO *p7bio;
if ((p7bio = PKCS7_dataInit(p7, NULL)) == NULL) { if ((p7bio = PKCS7_dataInit(p7, NULL)) == NULL) {
printf("PKCS7_dataInit failed\n"); fprintf(stderr, "PKCS7_dataInit failed\n");
return 0; /* FAILED */ return 0; /* FAILED */
} }
BIO_write(p7bio, data, len); BIO_write(p7bio, data, len);
(void)BIO_flush(p7bio); (void)BIO_flush(p7bio);
if (!PKCS7_dataFinal(p7, p7bio)) { if (!PKCS7_dataFinal(p7, p7bio)) {
printf("PKCS7_dataFinal failed\n"); fprintf(stderr, "PKCS7_dataFinal failed\n");
BIO_free_all(p7bio); BIO_free_all(p7bio);
return 0; /* FAILED */ return 0; /* FAILED */
} }
@ -488,7 +489,7 @@ MsCtlContent *ms_ctl_content_get(PKCS7 *p7)
const u_char *data; const u_char *data;
if (!is_content_type(p7, MS_CTL_OBJID)) { if (!is_content_type(p7, MS_CTL_OBJID)) {
printf("Failed to find MS_CTL_OBJID\n"); fprintf(stderr, "Failed to find MS_CTL_OBJID\n");
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
value = p7->d.sign->contents->d.other->value.sequence; value = p7->d.sign->contents->d.other->value.sequence;

218
msi.c
View File

@ -350,11 +350,11 @@ static PKCS7 *msi_pkcs7_contents_get(FILE_FORMAT_CTX *ctx, BIO *hash, const EVP_
(void)md; (void)md;
if (ctx->options->add_msi_dse && !msi_calc_MsiDigitalSignatureEx(ctx, hash)) { if (ctx->options->add_msi_dse && !msi_calc_MsiDigitalSignatureEx(ctx, hash)) {
printf("Unable to calc MsiDigitalSignatureEx\n"); fprintf(stderr, "Unable to calc MsiDigitalSignatureEx\n");
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
if (!msi_hash_dir(ctx->msi_ctx->msi, ctx->msi_ctx->dirent, hash, 1)) { if (!msi_hash_dir(ctx->msi_ctx->msi, ctx->msi_ctx->dirent, hash, 1)) {
printf("Unable to msi_handle_dir()\n"); fprintf(stderr, "Unable to msi_handle_dir()\n");
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
content = spc_indirect_data_content_get(hash, ctx); content = spc_indirect_data_content_get(hash, ctx);
@ -374,13 +374,13 @@ static u_char *msi_digest_calc(FILE_FORMAT_CTX *ctx, const EVP_MD *md)
BIO *bhash = BIO_new(BIO_f_md()); BIO *bhash = BIO_new(BIO_f_md());
if (!BIO_set_md(bhash, md)) { if (!BIO_set_md(bhash, md)) {
printf("Unable to set the message digest of BIO\n"); fprintf(stderr, "Unable to set the message digest of BIO\n");
BIO_free_all(bhash); BIO_free_all(bhash);
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
BIO_push(bhash, BIO_new(BIO_s_null())); BIO_push(bhash, BIO_new(BIO_s_null()));
if (!bio_hash_data(bhash, ctx->options->indata, 0, ctx->msi_ctx->fileend)) { if (!bio_hash_data(bhash, ctx->options->indata, 0, ctx->msi_ctx->fileend)) {
printf("Unable to calculate digest\n"); fprintf(stderr, "Unable to calculate digest\n");
BIO_free_all(bhash); BIO_free_all(bhash);
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
@ -420,14 +420,14 @@ static int msi_verify_digests(FILE_FORMAT_CTX *ctx, PKCS7 *p7)
} }
} }
if (mdtype == -1) { if (mdtype == -1) {
printf("Failed to extract current message digest\n\n"); fprintf(stderr, "Failed to extract current message digest\n\n");
return 0; /* FAILED */ return 0; /* FAILED */
} }
printf("Message digest algorithm : %s\n", OBJ_nid2sn(mdtype)); printf("Message digest algorithm : %s\n", OBJ_nid2sn(mdtype));
md = EVP_get_digestbynid(mdtype); md = EVP_get_digestbynid(mdtype);
hash = BIO_new(BIO_f_md()); hash = BIO_new(BIO_f_md());
if (!BIO_set_md(hash, md)) { if (!BIO_set_md(hash, md)) {
printf("Unable to set the message digest of BIO\n"); fprintf(stderr, "Unable to set the message digest of BIO\n");
BIO_free_all(hash); BIO_free_all(hash);
return 0; /* FAILED */ return 0; /* FAILED */
} }
@ -435,13 +435,13 @@ static int msi_verify_digests(FILE_FORMAT_CTX *ctx, PKCS7 *p7)
if (ctx->msi_ctx->p_msiex) { if (ctx->msi_ctx->p_msiex) {
BIO *prehash = BIO_new(BIO_f_md()); BIO *prehash = BIO_new(BIO_f_md());
if (EVP_MD_size(md) != (int)ctx->msi_ctx->len_msiex) { if (EVP_MD_size(md) != (int)ctx->msi_ctx->len_msiex) {
printf("Incorrect MsiDigitalSignatureEx stream data length\n\n"); fprintf(stderr, "Incorrect MsiDigitalSignatureEx stream data length\n\n");
BIO_free_all(hash); BIO_free_all(hash);
BIO_free_all(prehash); BIO_free_all(prehash);
return 0; /* FAILED */ return 0; /* FAILED */
} }
if (!BIO_set_md(prehash, md)) { if (!BIO_set_md(prehash, md)) {
printf("Unable to set the message digest of BIO\n"); fprintf(stderr, "Unable to set the message digest of BIO\n");
BIO_free_all(hash); BIO_free_all(hash);
BIO_free_all(prehash); BIO_free_all(prehash);
return 0; /* FAILED */ return 0; /* FAILED */
@ -451,7 +451,7 @@ static int msi_verify_digests(FILE_FORMAT_CTX *ctx, PKCS7 *p7)
print_hash("Current MsiDigitalSignatureEx ", "", (u_char *)ctx->msi_ctx->p_msiex, print_hash("Current MsiDigitalSignatureEx ", "", (u_char *)ctx->msi_ctx->p_msiex,
(int)ctx->msi_ctx->len_msiex); (int)ctx->msi_ctx->len_msiex);
if (!msi_prehash_dir(ctx->msi_ctx->dirent, prehash, 1)) { if (!msi_prehash_dir(ctx->msi_ctx->dirent, prehash, 1)) {
printf("Failed to calculate pre-hash used for MsiDigitalSignatureEx\n\n"); fprintf(stderr, "Failed to calculate pre-hash used for MsiDigitalSignatureEx\n\n");
BIO_free_all(hash); BIO_free_all(hash);
BIO_free_all(prehash); BIO_free_all(prehash);
return 0; /* FAILED */ return 0; /* FAILED */
@ -463,7 +463,7 @@ static int msi_verify_digests(FILE_FORMAT_CTX *ctx, PKCS7 *p7)
} }
if (!msi_hash_dir(ctx->msi_ctx->msi, ctx->msi_ctx->dirent, hash, 1)) { if (!msi_hash_dir(ctx->msi_ctx->msi, ctx->msi_ctx->dirent, hash, 1)) {
printf("Failed to calculate DigitalSignature\n\n"); fprintf(stderr, "Failed to calculate DigitalSignature\n\n");
BIO_free_all(hash); BIO_free_all(hash);
return 0; /* FAILED */ return 0; /* FAILED */
} }
@ -474,12 +474,12 @@ static int msi_verify_digests(FILE_FORMAT_CTX *ctx, PKCS7 *p7)
print_hash("Calculated DigitalSignature ", mdok ? "" : " MISMATCH!!!\n", print_hash("Calculated DigitalSignature ", mdok ? "" : " MISMATCH!!!\n",
cmdbuf, EVP_MD_size(md)); cmdbuf, EVP_MD_size(md));
if (!mdok) { if (!mdok) {
printf("Signature verification: failed\n\n"); fprintf(stderr, "Signature verification: failed\n\n");
return 0; /* FAILED */ return 0; /* FAILED */
} }
cdigest = msi_digest_calc(ctx, md); cdigest = msi_digest_calc(ctx, md);
if (!cdigest) { if (!cdigest) {
printf("Failed to calculate simple message digest\n\n"); fprintf(stderr, "Failed to calculate simple message digest\n\n");
return 0; /* FAILED */ return 0; /* FAILED */
} }
mdlen = EVP_MD_size(EVP_get_digestbynid(mdtype)); mdlen = EVP_MD_size(EVP_get_digestbynid(mdtype));
@ -504,12 +504,12 @@ static PKCS7 *msi_pkcs7_extract(FILE_FORMAT_CTX *ctx)
ds = msi_signatures_get(ctx->msi_ctx->dirent, NULL); ds = msi_signatures_get(ctx->msi_ctx->dirent, NULL);
if (!ds) { if (!ds) {
printf("MSI file has no signature\n"); fprintf(stderr, "MSI file has no signature\n");
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
p7 = msi_pkcs7_get_digital_signature(ctx, ds); p7 = msi_pkcs7_get_digital_signature(ctx, ds);
if (!p7) { if (!p7) {
printf("Unable to extract existing signature\n"); fprintf(stderr, "Unable to extract existing signature\n");
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
return p7; return p7;
@ -531,12 +531,12 @@ static PKCS7 *msi_pkcs7_extract_to_nest(FILE_FORMAT_CTX *ctx)
} }
ds = msi_signatures_get(ctx->msi_ctx->dirent, &dse); ds = msi_signatures_get(ctx->msi_ctx->dirent, &dse);
if (!ds) { if (!ds) {
printf("MSI file has no signature\n"); fprintf(stderr, "MSI file has no signature\n");
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
p7 = msi_pkcs7_get_digital_signature(ctx, ds); p7 = msi_pkcs7_get_digital_signature(ctx, ds);
if (!p7) { if (!p7) {
printf("Unable to extract existing signature\n"); fprintf(stderr, "Unable to extract existing signature\n");
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
/* perform a sanity check for the MsiDigitalSignatureEx section */ /* perform a sanity check for the MsiDigitalSignatureEx section */
@ -575,7 +575,7 @@ static int msi_remove_pkcs7(FILE_FORMAT_CTX *ctx, BIO *hash, BIO *outdata)
} }
if (!msi_file_write(ctx->msi_ctx->msi, ctx->msi_ctx->dirent, if (!msi_file_write(ctx->msi_ctx->msi, ctx->msi_ctx->dirent,
NULL, 0, NULL, 0, outdata)) { NULL, 0, NULL, 0, outdata)) {
printf("Saving the msi file failed\n"); fprintf(stderr, "Saving the msi file failed\n");
return 1; /* FAILED */ return 1; /* FAILED */
} }
return 0; /* OK */ return 0; /* OK */
@ -612,21 +612,21 @@ static PKCS7 *msi_pkcs7_signature_new(FILE_FORMAT_CTX *ctx, BIO *hash)
PKCS7 *p7 = pkcs7_create(ctx); PKCS7 *p7 = pkcs7_create(ctx);
if (!p7) { if (!p7) {
printf("Creating a new signature failed\n"); fprintf(stderr, "Creating a new signature failed\n");
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
if (!add_indirect_data_object(p7)) { if (!add_indirect_data_object(p7)) {
printf("Adding SPC_INDIRECT_DATA_OBJID failed\n"); fprintf(stderr, "Adding SPC_INDIRECT_DATA_OBJID failed\n");
PKCS7_free(p7); PKCS7_free(p7);
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
content = spc_indirect_data_content_get(hash, ctx); content = spc_indirect_data_content_get(hash, ctx);
if (!content) { if (!content) {
printf("Failed to get spcIndirectDataContent\n"); fprintf(stderr, "Failed to get spcIndirectDataContent\n");
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
if (!sign_spc_indirect_data_content(p7, content)) { if (!sign_spc_indirect_data_content(p7, content)) {
printf("Failed to set signed content\n"); fprintf(stderr, "Failed to set signed content\n");
PKCS7_free(p7); PKCS7_free(p7);
ASN1_OCTET_STRING_free(content); ASN1_OCTET_STRING_free(content);
return NULL; /* FAILED */ return NULL; /* FAILED */
@ -649,7 +649,7 @@ static int msi_append_pkcs7(FILE_FORMAT_CTX *ctx, BIO *outdata, PKCS7 *p7)
if (((len = i2d_PKCS7(p7, NULL)) <= 0) if (((len = i2d_PKCS7(p7, NULL)) <= 0)
|| (p = OPENSSL_malloc((size_t)len)) == NULL) { || (p = OPENSSL_malloc((size_t)len)) == NULL) {
printf("i2d_PKCS memory allocation failed: %d\n", len); fprintf(stderr, "i2d_PKCS memory allocation failed: %d\n", len);
return 1; /* FAILED */ return 1; /* FAILED */
} }
i2d_PKCS7(p7, &p); i2d_PKCS7(p7, &p);
@ -657,7 +657,7 @@ static int msi_append_pkcs7(FILE_FORMAT_CTX *ctx, BIO *outdata, PKCS7 *p7)
if (!msi_file_write(ctx->msi_ctx->msi, ctx->msi_ctx->dirent, p, (uint32_t)len, if (!msi_file_write(ctx->msi_ctx->msi, ctx->msi_ctx->dirent, p, (uint32_t)len,
ctx->msi_ctx->p_msiex, ctx->msi_ctx->len_msiex, outdata)) { ctx->msi_ctx->p_msiex, ctx->msi_ctx->len_msiex, outdata)) {
printf("Saving the msi file failed\n"); fprintf(stderr, "Saving the msi file failed\n");
OPENSSL_free(p); OPENSSL_free(p);
return 1; /* FAILED */ return 1; /* FAILED */
} }
@ -719,17 +719,17 @@ static MSI_CTX *msi_ctx_get(char *indata, uint32_t filesize)
msi = msi_file_new(indata, filesize); msi = msi_file_new(indata, filesize);
if (!msi) { if (!msi) {
printf("Failed to parse MSI_FILE struct\n"); fprintf(stderr, "Failed to parse MSI_FILE struct\n");
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
root = msi_root_entry_get(msi); root = msi_root_entry_get(msi);
if (!root) { if (!root) {
printf("Failed to get file entry\n"); fprintf(stderr, "Failed to get file entry\n");
msi_file_free(msi); msi_file_free(msi);
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
if (!msi_dirent_new(msi, root, NULL, &(dirent))) { if (!msi_dirent_new(msi, root, NULL, &(dirent))) {
printf("Failed to parse MSI_DIRENT struct\n"); fprintf(stderr, "Failed to parse MSI_DIRENT struct\n");
msi_file_free(msi); msi_file_free(msi);
if (dirent) if (dirent)
msi_dirent_free(dirent); msi_dirent_free(dirent);
@ -750,12 +750,12 @@ static PKCS7 *msi_pkcs7_get_digital_signature(FILE_FORMAT_CTX *ctx, MSI_ENTRY *d
uint32_t len = GET_UINT32_LE(ds->size); uint32_t len = GET_UINT32_LE(ds->size);
if (len == 0 || len >= MAXREGSECT) { if (len == 0 || len >= MAXREGSECT) {
printf("Corrupted DigitalSignature stream length 0x%08X\n", len); fprintf(stderr, "Corrupted DigitalSignature stream length 0x%08X\n", len);
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
p = OPENSSL_malloc((size_t)len); p = OPENSSL_malloc((size_t)len);
if (!msi_file_read(ctx->msi_ctx->msi, ds, 0, p, len)) { if (!msi_file_read(ctx->msi_ctx->msi, ds, 0, p, len)) {
printf("DigitalSignature stream data error\n"); fprintf(stderr, "DigitalSignature stream data error\n");
OPENSSL_free(p); OPENSSL_free(p);
return NULL; return NULL;
} }
@ -763,7 +763,7 @@ static PKCS7 *msi_pkcs7_get_digital_signature(FILE_FORMAT_CTX *ctx, MSI_ENTRY *d
p7 = d2i_PKCS7(NULL, &blob, len); p7 = d2i_PKCS7(NULL, &blob, len);
OPENSSL_free(p); OPENSSL_free(p);
if (!p7) { if (!p7) {
printf("Failed to extract PKCS7 data\n"); fprintf(stderr, "Failed to extract PKCS7 data\n");
return NULL; return NULL;
} }
return p7; return p7;
@ -774,7 +774,7 @@ static const u_char *sector_offset_to_address(MSI_FILE *msi, uint32_t sector, ui
{ {
if (sector >= MAXREGSECT || offset >= msi->m_sectorSize if (sector >= MAXREGSECT || offset >= msi->m_sectorSize
|| (msi->m_bufferLen - offset) / msi->m_sectorSize <= sector) { || (msi->m_bufferLen - offset) / msi->m_sectorSize <= sector) {
printf("Corrupted file\n"); fprintf(stderr, "Corrupted file\n");
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
return msi->m_buffer + (sector + 1) * msi->m_sectorSize + offset; return msi->m_buffer + (sector + 1) * msi->m_sectorSize + offset;
@ -795,19 +795,19 @@ static uint32_t get_fat_sector_location(MSI_FILE *msi, uint32_t fatSectorNumber)
fatSectorNumber -= entriesPerSector; fatSectorNumber -= entriesPerSector;
address = sector_offset_to_address(msi, difatSectorLocation, msi->m_sectorSize - 4); address = sector_offset_to_address(msi, difatSectorLocation, msi->m_sectorSize - 4);
if (!address) { if (!address) {
printf("Failed to get a next sector address\n"); fprintf(stderr, "Failed to get a next sector address\n");
return NOSTREAM; /* FAILED */ return NOSTREAM; /* FAILED */
} }
difatSectorLocation = GET_UINT32_LE(address); difatSectorLocation = GET_UINT32_LE(address);
} }
address = sector_offset_to_address(msi, difatSectorLocation, fatSectorNumber * 4); address = sector_offset_to_address(msi, difatSectorLocation, fatSectorNumber * 4);
if (!address) { if (!address) {
printf("Failed to get a next sector address\n"); fprintf(stderr, "Failed to get a next sector address\n");
return NOSTREAM; /* FAILED */ return NOSTREAM; /* FAILED */
} }
fatSectorLocation = GET_UINT32_LE(address); fatSectorLocation = GET_UINT32_LE(address);
if (fatSectorLocation == 0 || fatSectorLocation >= FREESECT) { if (fatSectorLocation == 0 || fatSectorLocation >= FREESECT) {
printf("Get corrupted sector location 0x%08X\n", fatSectorLocation); fprintf(stderr, "Get corrupted sector location 0x%08X\n", fatSectorLocation);
return NOSTREAM; /* FAILED */ return NOSTREAM; /* FAILED */
} }
return fatSectorLocation; return fatSectorLocation;
@ -823,17 +823,17 @@ static uint32_t get_next_sector(MSI_FILE *msi, uint32_t sector)
uint32_t fatSectorNumber = sector / entriesPerSector; uint32_t fatSectorNumber = sector / entriesPerSector;
uint32_t fatSectorLocation = get_fat_sector_location(msi, fatSectorNumber); uint32_t fatSectorLocation = get_fat_sector_location(msi, fatSectorNumber);
if (fatSectorLocation == NOSTREAM) { if (fatSectorLocation == NOSTREAM) {
printf("Failed to get a fat sector location\n"); fprintf(stderr, "Failed to get a fat sector location\n");
return NOSTREAM; /* FAILED */ return NOSTREAM; /* FAILED */
} }
address = sector_offset_to_address(msi, fatSectorLocation, sector % entriesPerSector * 4); address = sector_offset_to_address(msi, fatSectorLocation, sector % entriesPerSector * 4);
if (!address) { if (!address) {
printf("Failed to get a next sector address\n"); fprintf(stderr, "Failed to get a next sector address\n");
return NOSTREAM; /* FAILED */ return NOSTREAM; /* FAILED */
} }
nextSectorLocation = GET_UINT32_LE(address); nextSectorLocation = GET_UINT32_LE(address);
if (nextSectorLocation == 0 || nextSectorLocation >= FREESECT) { if (nextSectorLocation == 0 || nextSectorLocation >= FREESECT) {
printf("Get corrupted sector location 0x%08X\n", nextSectorLocation); fprintf(stderr, "Get corrupted sector location 0x%08X\n", nextSectorLocation);
return NOSTREAM; /* FAILED */ return NOSTREAM; /* FAILED */
} }
return nextSectorLocation; return nextSectorLocation;
@ -846,7 +846,7 @@ static int locate_final_sector(MSI_FILE *msi, uint32_t sector, uint32_t offset,
offset -= msi->m_sectorSize; offset -= msi->m_sectorSize;
sector = get_next_sector(msi, sector); sector = get_next_sector(msi, sector);
if (sector == NOSTREAM) { if (sector == NOSTREAM) {
printf("Failed to get a next sector\n"); fprintf(stderr, "Failed to get a next sector\n");
return 0; /* FAILED */ return 0; /* FAILED */
} }
} }
@ -860,11 +860,11 @@ static const u_char *mini_sector_offset_to_address(MSI_FILE *msi, uint32_t secto
{ {
if (sector >= MAXREGSECT || offset >= msi->m_minisectorSize || if (sector >= MAXREGSECT || offset >= msi->m_minisectorSize ||
(msi->m_bufferLen - offset) / msi->m_minisectorSize <= sector) { (msi->m_bufferLen - offset) / msi->m_minisectorSize <= sector) {
printf("Corrupted file\n"); fprintf(stderr, "Corrupted file\n");
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
if (!locate_final_sector(msi, msi->m_miniStreamStartSector, sector * msi->m_minisectorSize + offset, &sector, &offset)) { if (!locate_final_sector(msi, msi->m_miniStreamStartSector, sector * msi->m_minisectorSize + offset, &sector, &offset)) {
printf("Failed to locate a final sector\n"); fprintf(stderr, "Failed to locate a final sector\n");
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
return sector_offset_to_address(msi, sector, offset); return sector_offset_to_address(msi, sector, offset);
@ -877,7 +877,7 @@ static const u_char *mini_sector_offset_to_address(MSI_FILE *msi, uint32_t secto
static int read_stream(MSI_FILE *msi, uint32_t sector, uint32_t offset, char *buffer, uint32_t len) static int read_stream(MSI_FILE *msi, uint32_t sector, uint32_t offset, char *buffer, uint32_t len)
{ {
if (!locate_final_sector(msi, sector, offset, &sector, &offset)) { if (!locate_final_sector(msi, sector, offset, &sector, &offset)) {
printf("Failed to locate a final sector\n"); fprintf(stderr, "Failed to locate a final sector\n");
return 0; /* FAILED */ return 0; /* FAILED */
} }
while (len > 0) { while (len > 0) {
@ -885,12 +885,12 @@ static int read_stream(MSI_FILE *msi, uint32_t sector, uint32_t offset, char *bu
uint32_t copylen; uint32_t copylen;
address = sector_offset_to_address(msi, sector, offset); address = sector_offset_to_address(msi, sector, offset);
if (!address) { if (!address) {
printf("Failed to get a next sector address\n"); fprintf(stderr, "Failed to get a next sector address\n");
return 0; /* FAILED */ return 0; /* FAILED */
} }
copylen = MIN(len, msi->m_sectorSize - offset); copylen = MIN(len, msi->m_sectorSize - offset);
if (msi->m_buffer + msi->m_bufferLen < address + copylen) { if (msi->m_buffer + msi->m_bufferLen < address + copylen) {
printf("Corrupted file\n"); fprintf(stderr, "Corrupted file\n");
return 0; /* FAILED */ return 0; /* FAILED */
} }
memcpy(buffer, address, copylen); memcpy(buffer, address, copylen);
@ -898,7 +898,7 @@ static int read_stream(MSI_FILE *msi, uint32_t sector, uint32_t offset, char *bu
len -= copylen; len -= copylen;
sector = get_next_sector(msi, sector); sector = get_next_sector(msi, sector);
if (sector == 0) { if (sector == 0) {
printf("Failed to get a next sector\n"); fprintf(stderr, "Failed to get a next sector\n");
return 0; /* FAILED */ return 0; /* FAILED */
} }
offset = 0; offset = 0;
@ -913,17 +913,17 @@ static uint32_t get_next_mini_sector(MSI_FILE *msi, uint32_t miniSector)
const u_char *address; const u_char *address;
if (!locate_final_sector(msi, msi->m_hdr->firstMiniFATSectorLocation, miniSector * 4, &sector, &offset)) { if (!locate_final_sector(msi, msi->m_hdr->firstMiniFATSectorLocation, miniSector * 4, &sector, &offset)) {
printf("Failed to locate a final sector\n"); fprintf(stderr, "Failed to locate a final sector\n");
return NOSTREAM; /* FAILED */ return NOSTREAM; /* FAILED */
} }
address = sector_offset_to_address(msi, sector, offset); address = sector_offset_to_address(msi, sector, offset);
if (!address) { if (!address) {
printf("Failed to get a next mini sector address\n"); fprintf(stderr, "Failed to get a next mini sector address\n");
return NOSTREAM; /* FAILED */ return NOSTREAM; /* FAILED */
} }
nextMiniSectorLocation = GET_UINT32_LE(address); nextMiniSectorLocation = GET_UINT32_LE(address);
if (nextMiniSectorLocation == 0 || nextMiniSectorLocation >= FREESECT) { if (nextMiniSectorLocation == 0 || nextMiniSectorLocation >= FREESECT) {
printf("Get corrupted sector location 0x%08X\n", nextMiniSectorLocation); fprintf(stderr, "Get corrupted sector location 0x%08X\n", nextMiniSectorLocation);
return NOSTREAM; /* FAILED */ return NOSTREAM; /* FAILED */
} }
return nextMiniSectorLocation; return nextMiniSectorLocation;
@ -935,7 +935,7 @@ static int locate_final_mini_sector(MSI_FILE *msi, uint32_t sector, uint32_t off
offset -= msi->m_minisectorSize; offset -= msi->m_minisectorSize;
sector = get_next_mini_sector(msi, sector); sector = get_next_mini_sector(msi, sector);
if (sector == NOSTREAM) { if (sector == NOSTREAM) {
printf("Failed to get a next mini sector\n"); fprintf(stderr, "Failed to get a next mini sector\n");
return 0; /* FAILED */ return 0; /* FAILED */
} }
} }
@ -948,7 +948,7 @@ static int locate_final_mini_sector(MSI_FILE *msi, uint32_t sector, uint32_t off
static int read_mini_stream(MSI_FILE *msi, uint32_t sector, uint32_t offset, char *buffer, uint32_t len) static int read_mini_stream(MSI_FILE *msi, uint32_t sector, uint32_t offset, char *buffer, uint32_t len)
{ {
if (!locate_final_mini_sector(msi, sector, offset, &sector, &offset)) { if (!locate_final_mini_sector(msi, sector, offset, &sector, &offset)) {
printf("Failed to locate a final mini sector\n"); fprintf(stderr, "Failed to locate a final mini sector\n");
return 0; /* FAILED */ return 0; /* FAILED */
} }
while (len > 0) { while (len > 0) {
@ -956,12 +956,12 @@ static int read_mini_stream(MSI_FILE *msi, uint32_t sector, uint32_t offset, cha
uint32_t copylen; uint32_t copylen;
address = mini_sector_offset_to_address(msi, sector, offset); address = mini_sector_offset_to_address(msi, sector, offset);
if (!address) { if (!address) {
printf("Failed to get a next mini sector address\n"); fprintf(stderr, "Failed to get a next mini sector address\n");
return 0; /* FAILED */ return 0; /* FAILED */
} }
copylen = MIN(len, msi->m_minisectorSize - offset); copylen = MIN(len, msi->m_minisectorSize - offset);
if (msi->m_buffer + msi->m_bufferLen < address + copylen) { if (msi->m_buffer + msi->m_bufferLen < address + copylen) {
printf("Corrupted file\n"); fprintf(stderr, "Corrupted file\n");
return 0; /* FAILED */ return 0; /* FAILED */
} }
memcpy(buffer, address, copylen); memcpy(buffer, address, copylen);
@ -969,7 +969,7 @@ static int read_mini_stream(MSI_FILE *msi, uint32_t sector, uint32_t offset, cha
len -= copylen; len -= copylen;
sector = get_next_mini_sector(msi, sector); sector = get_next_mini_sector(msi, sector);
if (sector == NOSTREAM) { if (sector == NOSTREAM) {
printf("Failed to get a next mini sector\n"); fprintf(stderr, "Failed to get a next mini sector\n");
return 0; /* FAILED */ return 0; /* FAILED */
} }
offset = 0; offset = 0;
@ -1004,20 +1004,20 @@ static MSI_FILE_HDR *parse_header(char *data)
memcpy(header->signature, data + HEADER_SIGNATURE, sizeof header->signature); memcpy(header->signature, data + HEADER_SIGNATURE, sizeof header->signature);
/* Minor Version field SHOULD be set to 0x003E. */ /* Minor Version field SHOULD be set to 0x003E. */
header->minorVersion = GET_UINT16_LE(data + HEADER_MINOR_VER); header->minorVersion = GET_UINT16_LE(data + HEADER_MINOR_VER);
if (header->minorVersion !=0x003E ) { if (header->minorVersion !=0x003E) {
printf("Warning: Minor Version field SHOULD be 0x003E, but is: 0x%04X\n", header->minorVersion); printf("Warning: Minor Version field SHOULD be 0x003E, but is: 0x%04X\n", header->minorVersion);
} }
/* Major Version field MUST be set to either 0x0003 (version 3) or 0x0004 (version 4). */ /* Major Version field MUST be set to either 0x0003 (version 3) or 0x0004 (version 4). */
header->majorVersion = GET_UINT16_LE(data + HEADER_MAJOR_VER); header->majorVersion = GET_UINT16_LE(data + HEADER_MAJOR_VER);
if (header->majorVersion != 0x0003 && header->majorVersion != 0x0004) { if (header->majorVersion != 0x0003 && header->majorVersion != 0x0004) {
printf("Unknown Major Version: 0x%04X\n", header->majorVersion); fprintf(stderr, "Unknown Major Version: 0x%04X\n", header->majorVersion);
OPENSSL_free(header); OPENSSL_free(header);
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
/* Byte Order field MUST be set to 0xFFFE, specifies little-endian byte order. */ /* Byte Order field MUST be set to 0xFFFE, specifies little-endian byte order. */
header->byteOrder = GET_UINT16_LE(data + HEADER_BYTE_ORDER); header->byteOrder = GET_UINT16_LE(data + HEADER_BYTE_ORDER);
if (header->byteOrder != 0xFFFE) { if (header->byteOrder != 0xFFFE) {
printf("Unknown Byte Order: 0x%04X\n", header->byteOrder); fprintf(stderr, "Unknown Byte Order: 0x%04X\n", header->byteOrder);
OPENSSL_free(header); OPENSSL_free(header);
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
@ -1026,7 +1026,7 @@ static MSI_FILE_HDR *parse_header(char *data)
header->sectorShift = GET_UINT16_LE(data + HEADER_SECTOR_SHIFT); header->sectorShift = GET_UINT16_LE(data + HEADER_SECTOR_SHIFT);
if ((header->majorVersion == 0x0003 && header->sectorShift != 0x0009) || if ((header->majorVersion == 0x0003 && header->sectorShift != 0x0009) ||
(header->majorVersion == 0x0004 && header->sectorShift != 0x000C)) { (header->majorVersion == 0x0004 && header->sectorShift != 0x000C)) {
printf("Unknown Sector Shift: 0x%04X\n", header->sectorShift); fprintf(stderr, "Unknown Sector Shift: 0x%04X\n", header->sectorShift);
OPENSSL_free(header); OPENSSL_free(header);
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
@ -1035,7 +1035,7 @@ static MSI_FILE_HDR *parse_header(char *data)
* The sector size of the Mini Stream MUST be 64 bytes. */ * The sector size of the Mini Stream MUST be 64 bytes. */
header->miniSectorShift = GET_UINT16_LE(data + HEADER_MINI_SECTOR_SHIFT); header->miniSectorShift = GET_UINT16_LE(data + HEADER_MINI_SECTOR_SHIFT);
if (header->miniSectorShift != 0x0006) { if (header->miniSectorShift != 0x0006) {
printf("Unknown Mini Sector Shift: 0x%04X\n", header->miniSectorShift); fprintf(stderr, "Unknown Mini Sector Shift: 0x%04X\n", header->miniSectorShift);
OPENSSL_free(header); OPENSSL_free(header);
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
@ -1045,13 +1045,13 @@ static MSI_FILE_HDR *parse_header(char *data)
* If Major Version is 3, the Number of Directory Sectors MUST be zero. */ * If Major Version is 3, the Number of Directory Sectors MUST be zero. */
header->numDirectorySector = GET_UINT32_LE(data + HEADER_DIR_SECTORS_NUM); header->numDirectorySector = GET_UINT32_LE(data + HEADER_DIR_SECTORS_NUM);
if (header->majorVersion == 0x0003 && header->numDirectorySector != 0x00000000) { if (header->majorVersion == 0x0003 && header->numDirectorySector != 0x00000000) {
printf("Unsupported Number of Directory Sectors: 0x%08X\n", header->numDirectorySector); fprintf(stderr, "Unsupported Number of Directory Sectors: 0x%08X\n", header->numDirectorySector);
OPENSSL_free(header); OPENSSL_free(header);
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
header->numFATSector = GET_UINT32_LE(data + HEADER_FAT_SECTORS_NUM); header->numFATSector = GET_UINT32_LE(data + HEADER_FAT_SECTORS_NUM);
if ((uint64_t)header->numFATSector * sectorSize >= SIZE_16M) { if ((uint64_t)header->numFATSector * sectorSize >= SIZE_16M) {
printf("Unsupported Number of FAT Sectors: 0x%08X\n", header->numFATSector); fprintf(stderr, "Unsupported Number of FAT Sectors: 0x%08X\n", header->numFATSector);
OPENSSL_free(header); OPENSSL_free(header);
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
@ -1064,21 +1064,21 @@ static MSI_FILE_HDR *parse_header(char *data)
* must be allocated as normal sectors from the FAT. */ * must be allocated as normal sectors from the FAT. */
header->miniStreamCutoffSize = GET_UINT32_LE(data + HEADER_MINI_STREAM_CUTOFF); header->miniStreamCutoffSize = GET_UINT32_LE(data + HEADER_MINI_STREAM_CUTOFF);
if (header->miniStreamCutoffSize != 0x00001000) { if (header->miniStreamCutoffSize != 0x00001000) {
printf("Unsupported Mini Stream Cutoff Size: 0x%08X\n", header->miniStreamCutoffSize); fprintf(stderr, "Unsupported Mini Stream Cutoff Size: 0x%08X\n", header->miniStreamCutoffSize);
OPENSSL_free(header); OPENSSL_free(header);
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
header->firstMiniFATSectorLocation = GET_UINT32_LE(data + HEADER_MINI_FAT_SECTOR_LOC); header->firstMiniFATSectorLocation = GET_UINT32_LE(data + HEADER_MINI_FAT_SECTOR_LOC);
header->numMiniFATSector = GET_UINT32_LE(data + HEADER_MINI_FAT_SECTORS_NUM); header->numMiniFATSector = GET_UINT32_LE(data + HEADER_MINI_FAT_SECTORS_NUM);
if ((uint64_t)header->numMiniFATSector * sectorSize >= SIZE_16M) { if ((uint64_t)header->numMiniFATSector * sectorSize >= SIZE_16M) {
printf("Unsupported Number of Mini FAT Sectors: 0x%08X\n", header->numMiniFATSector); fprintf(stderr, "Unsupported Number of Mini FAT Sectors: 0x%08X\n", header->numMiniFATSector);
OPENSSL_free(header); OPENSSL_free(header);
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
header->firstDIFATSectorLocation = GET_UINT32_LE(data + HEADER_DIFAT_SECTOR_LOC); header->firstDIFATSectorLocation = GET_UINT32_LE(data + HEADER_DIFAT_SECTOR_LOC);
header->numDIFATSector = GET_UINT32_LE(data + HEADER_DIFAT_SECTORS_NUM); header->numDIFATSector = GET_UINT32_LE(data + HEADER_DIFAT_SECTORS_NUM);
if ((uint64_t)header->numDIFATSector * sectorSize >= SIZE_16M) { if ((uint64_t)header->numDIFATSector * sectorSize >= SIZE_16M) {
printf("Unsupported Number of DIFAT Sectors: 0x%08X\n", header->numDIFATSector); fprintf(stderr, "Unsupported Number of DIFAT Sectors: 0x%08X\n", header->numDIFATSector);
OPENSSL_free(header); OPENSSL_free(header);
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
@ -1097,7 +1097,7 @@ static MSI_ENTRY *parse_entry(MSI_FILE *msi, const u_char *data, int is_root)
entry->nameLen = GET_UINT16_LE(data + DIRENT_NAME_LEN); entry->nameLen = GET_UINT16_LE(data + DIRENT_NAME_LEN);
/* This length MUST NOT exceed 64, the maximum size of the Directory Entry Name field */ /* This length MUST NOT exceed 64, the maximum size of the Directory Entry Name field */
if (entry->nameLen == 0 || entry->nameLen > 64) { if (entry->nameLen == 0 || entry->nameLen > 64) {
printf("Corrupted Directory Entry Name Length\n"); fprintf(stderr, "Corrupted Directory Entry Name Length\n");
OPENSSL_free(entry); OPENSSL_free(entry);
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
@ -1106,7 +1106,7 @@ static MSI_ENTRY *parse_entry(MSI_FILE *msi, const u_char *data, int is_root)
* string "Root Entry" in Unicode UTF-16. */ * string "Root Entry" in Unicode UTF-16. */
if (is_root && (entry->nameLen != sizeof msi_root_entry if (is_root && (entry->nameLen != sizeof msi_root_entry
|| memcmp(entry->name, msi_root_entry, entry->nameLen))) { || memcmp(entry->name, msi_root_entry, entry->nameLen))) {
printf("Corrupted Root Directory Entry's Name\n"); fprintf(stderr, "Corrupted Root Directory Entry's Name\n");
OPENSSL_free(entry); OPENSSL_free(entry);
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
@ -1121,7 +1121,7 @@ static MSI_ENTRY *parse_entry(MSI_FILE *msi, const u_char *data, int is_root)
/* The Creation Time field in the root storage directory entry MUST be all zeroes /* The Creation Time field in the root storage directory entry MUST be all zeroes
but the Modified Time field in the root storage directory entry MAY be all zeroes */ but the Modified Time field in the root storage directory entry MAY be all zeroes */
if (is_root && memcmp(entry->creationTime, msi_zeroes, 8)) { if (is_root && memcmp(entry->creationTime, msi_zeroes, 8)) {
printf("Corrupted Root Directory Entry's Creation Time\n"); fprintf(stderr, "Corrupted Root Directory Entry's Creation Time\n");
OPENSSL_free(entry); OPENSSL_free(entry);
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
@ -1133,7 +1133,7 @@ static MSI_ENTRY *parse_entry(MSI_FILE *msi, const u_char *data, int is_root)
inlen = GET_UINT32_LE(entry->size); inlen = GET_UINT32_LE(entry->size);
if ((msi->m_sectorSize == 0x0200 && inlen > 0x80000000) if ((msi->m_sectorSize == 0x0200 && inlen > 0x80000000)
|| (msi->m_bufferLen <= inlen)) { || (msi->m_bufferLen <= inlen)) {
printf("Corrupted Stream Size 0x%08X\n", inlen); fprintf(stderr, "Corrupted Stream Size 0x%08X\n", inlen);
OPENSSL_free(entry); OPENSSL_free(entry);
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
@ -1153,27 +1153,27 @@ static MSI_ENTRY *get_entry(MSI_FILE *msi, uint32_t entryID, int is_root)
/* Corrupted file */ /* Corrupted file */
if (!is_root && entryID == 0) { if (!is_root && entryID == 0) {
printf("Corrupted entryID\n"); fprintf(stderr, "Corrupted entryID\n");
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
if (msi->m_bufferLen / sizeof(MSI_ENTRY) <= entryID) { if (msi->m_bufferLen / sizeof(MSI_ENTRY) <= entryID) {
printf("Invalid argument entryID\n"); fprintf(stderr, "Invalid argument entryID\n");
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
/* The first entry in the first sector of the directory chain is known as /* The first entry in the first sector of the directory chain is known as
the root directory entry so it can not contain the directory stream */ the root directory entry so it can not contain the directory stream */
if (msi->m_hdr->firstDirectorySectorLocation == 0 && entryID == 0) { if (msi->m_hdr->firstDirectorySectorLocation == 0 && entryID == 0) {
printf("Corrupted First Directory Sector Location\n"); fprintf(stderr, "Corrupted First Directory Sector Location\n");
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
if (!locate_final_sector(msi, msi->m_hdr->firstDirectorySectorLocation, if (!locate_final_sector(msi, msi->m_hdr->firstDirectorySectorLocation,
entryID * sizeof(MSI_ENTRY), &sector, &offset)) { entryID * sizeof(MSI_ENTRY), &sector, &offset)) {
printf("Failed to locate a final sector\n"); fprintf(stderr, "Failed to locate a final sector\n");
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
address = sector_offset_to_address(msi, sector, offset); address = sector_offset_to_address(msi, sector, offset);
if (!address) { if (!address) {
printf("Failed to get a final address\n"); fprintf(stderr, "Failed to get a final address\n");
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
return parse_entry(msi, address, is_root); return parse_entry(msi, address, is_root);
@ -1200,12 +1200,12 @@ static MSI_FILE *msi_file_new(char *buffer, uint32_t len)
MSI_FILE_HDR *header; MSI_FILE_HDR *header;
if (buffer == NULL || len == 0) { if (buffer == NULL || len == 0) {
printf("Invalid argument\n"); fprintf(stderr, "Invalid argument\n");
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
header = parse_header(buffer); header = parse_header(buffer);
if (!header) { if (!header) {
printf("Failed to parse MSI_FILE_HDR struct\n"); fprintf(stderr, "Failed to parse MSI_FILE_HDR struct\n");
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
msi = (MSI_FILE *)OPENSSL_malloc(sizeof(MSI_FILE)); msi = (MSI_FILE *)OPENSSL_malloc(sizeof(MSI_FILE));
@ -1218,20 +1218,20 @@ static MSI_FILE *msi_file_new(char *buffer, uint32_t len)
if (msi->m_bufferLen < sizeof *(msi->m_hdr) || if (msi->m_bufferLen < sizeof *(msi->m_hdr) ||
memcmp(msi->m_hdr->signature, msi_magic, sizeof msi_magic)) { memcmp(msi->m_hdr->signature, msi_magic, sizeof msi_magic)) {
printf("Wrong file format\n"); fprintf(stderr, "Wrong file format\n");
msi_file_free(msi); msi_file_free(msi);
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
/* The file must contains at least 3 sectors */ /* The file must contains at least 3 sectors */
if (msi->m_bufferLen < msi->m_sectorSize * 3) { if (msi->m_bufferLen < msi->m_sectorSize * 3) {
printf("The file must contains at least 3 sectors\n"); fprintf(stderr, "The file must contains at least 3 sectors\n");
msi_file_free(msi); msi_file_free(msi);
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
root = msi_root_entry_get(msi); root = msi_root_entry_get(msi);
if (!root) { if (!root) {
printf("Failed to get msi root entry\n"); fprintf(stderr, "Failed to get msi root entry\n");
msi_file_free(msi); msi_file_free(msi);
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
@ -1251,13 +1251,13 @@ static int msi_dirent_new(MSI_FILE *msi, MSI_ENTRY *entry, MSI_DIRENT *parent, M
return 1; /* OK */ return 1; /* OK */
} }
if (entry->nameLen == 0 || entry->nameLen > 64) { if (entry->nameLen == 0 || entry->nameLen > 64) {
printf("Corrupted Directory Entry Name Length\n"); fprintf(stderr, "Corrupted Directory Entry Name Length\n");
return 0; /* FAILED */ return 0; /* FAILED */
} }
/* detect cycles in previously visited entries (parents, siblings) */ /* detect cycles in previously visited entries (parents, siblings) */
if (!ret) { /* initialized (non-root entry) */ if (!ret) { /* initialized (non-root entry) */
if (!memcmp(entry, tortoise->entry, sizeof(MSI_ENTRY))) { if (!memcmp(entry, tortoise->entry, sizeof(MSI_ENTRY))) {
printf("MSI_ENTRY cycle detected at level %d\n", cnt); fprintf(stderr, "MSI_ENTRY cycle detected at level %d\n", cnt);
OPENSSL_free(entry); OPENSSL_free(entry);
return 0; /* FAILED */ return 0; /* FAILED */
} }
@ -1284,7 +1284,7 @@ static int msi_dirent_new(MSI_FILE *msi, MSI_ENTRY *entry, MSI_DIRENT *parent, M
} }
if (parent && !sk_MSI_DIRENT_push(parent->children, dirent)) { if (parent && !sk_MSI_DIRENT_push(parent->children, dirent)) {
printf("Failed to insert MSI_DIRENT\n"); fprintf(stderr, "Failed to insert MSI_DIRENT\n");
return 0; /* FAILED */ return 0; /* FAILED */
} }
@ -1294,7 +1294,7 @@ static int msi_dirent_new(MSI_FILE *msi, MSI_ENTRY *entry, MSI_DIRENT *parent, M
if (!recurse_entry(msi, entry->leftSiblingID, parent) if (!recurse_entry(msi, entry->leftSiblingID, parent)
|| !recurse_entry(msi, entry->rightSiblingID, parent) || !recurse_entry(msi, entry->rightSiblingID, parent)
|| !recurse_entry(msi, entry->childID, dirent)) { || !recurse_entry(msi, entry->childID, dirent)) {
printf("Failed to add a sibling or a child to the tree\n"); fprintf(stderr, "Failed to add a sibling or a child to the tree\n");
return 0; /* FAILED */ return 0; /* FAILED */
} }
@ -1313,7 +1313,7 @@ static int recurse_entry(MSI_FILE *msi, uint32_t entryID, MSI_DIRENT *parent)
node = get_entry(msi, entryID, FALSE); node = get_entry(msi, entryID, FALSE);
if (!node) { if (!node) {
printf("Corrupted ID: 0x%08X\n", entryID); fprintf(stderr, "Corrupted ID: 0x%08X\n", entryID);
return 0; /* FAILED */ return 0; /* FAILED */
} }
@ -1478,7 +1478,7 @@ static int msi_hash_dir(MSI_FILE *msi, MSI_DIRENT *dirent, BIO *hash, int is_roo
} }
indata = (char *)OPENSSL_malloc(inlen); indata = (char *)OPENSSL_malloc(inlen);
if (!msi_file_read(msi, child->entry, 0, indata, inlen)) { if (!msi_file_read(msi, child->entry, 0, indata, inlen)) {
printf("Failed to read stream data\n"); fprintf(stderr, "Failed to read stream data\n");
OPENSSL_free(indata); OPENSSL_free(indata);
goto out; goto out;
} }
@ -1487,7 +1487,7 @@ static int msi_hash_dir(MSI_FILE *msi, MSI_DIRENT *dirent, BIO *hash, int is_roo
} }
if (child->type == DIR_STORAGE) { if (child->type == DIR_STORAGE) {
if (!msi_hash_dir(msi, child, hash, 0)) { if (!msi_hash_dir(msi, child, hash, 0)) {
printf("Failed to hash a MSI storage\n"); fprintf(stderr, "Failed to hash a MSI storage\n");
goto out; goto out;
} }
} }
@ -1506,7 +1506,7 @@ static int ministream_append(MSI_OUT *out, char *buf, uint32_t len)
out->ministreamsMemallocCount += needSectors; out->ministreamsMemallocCount += needSectors;
out->ministream = OPENSSL_realloc(out->ministream, (size_t)(out->ministreamsMemallocCount * out->sectorSize)); out->ministream = OPENSSL_realloc(out->ministream, (size_t)(out->ministreamsMemallocCount * out->sectorSize));
if (!out->ministream) { if (!out->ministream) {
printf("Memory allocation failure\n"); fprintf(stderr, "Memory allocation failure\n");
return 0; /* FAILED */ return 0; /* FAILED */
} }
} }
@ -1520,12 +1520,12 @@ static int minifat_append(MSI_OUT *out, char *buf, uint32_t len)
if (out->minifatLen == (uint64_t)out->minifatMemallocCount * out->sectorSize) { if (out->minifatLen == (uint64_t)out->minifatMemallocCount * out->sectorSize) {
out->minifatMemallocCount++; out->minifatMemallocCount++;
if ((uint64_t)out->minifatMemallocCount * out->sectorSize >= SIZE_16M) { if ((uint64_t)out->minifatMemallocCount * out->sectorSize >= SIZE_16M) {
printf("Failed to append MiniFAT sector\n"); fprintf(stderr, "Failed to append MiniFAT sector\n");
return 0; /* FAILED */ return 0; /* FAILED */
} }
out->minifat = OPENSSL_realloc(out->minifat, (size_t)(out->minifatMemallocCount * out->sectorSize)); out->minifat = OPENSSL_realloc(out->minifat, (size_t)(out->minifatMemallocCount * out->sectorSize));
if (!out->minifat) { if (!out->minifat) {
printf("Memory allocation failure\n"); fprintf(stderr, "Memory allocation failure\n");
return 0; /* FAILED */ return 0; /* FAILED */
} }
} }
@ -1539,12 +1539,12 @@ static int fat_append(MSI_OUT *out, char *buf, uint32_t len)
if (out->fatLen == (uint64_t)out->fatMemallocCount * out->sectorSize) { if (out->fatLen == (uint64_t)out->fatMemallocCount * out->sectorSize) {
out->fatMemallocCount++; out->fatMemallocCount++;
if ((uint64_t)out->fatMemallocCount * out->sectorSize >= SIZE_16M) { if ((uint64_t)out->fatMemallocCount * out->sectorSize >= SIZE_16M) {
printf("Failed to append FAT sector\n"); fprintf(stderr, "Failed to append FAT sector\n");
return 0; /* FAILED */ return 0; /* FAILED */
} }
out->fat = OPENSSL_realloc(out->fat, (size_t)(out->fatMemallocCount * out->sectorSize)); out->fat = OPENSSL_realloc(out->fat, (size_t)(out->fatMemallocCount * out->sectorSize));
if (!out->fat) { if (!out->fat) {
printf("Memory allocation failure\n"); fprintf(stderr, "Memory allocation failure\n");
return 0; /* FAILED */ return 0; /* FAILED */
} }
} }
@ -1558,12 +1558,12 @@ static int difat_append(MSI_OUT *out, char *buf, uint32_t len)
if (out->difatLen == (uint64_t)out->difatMemallocCount * out->sectorSize) { if (out->difatLen == (uint64_t)out->difatMemallocCount * out->sectorSize) {
out->difatMemallocCount++; out->difatMemallocCount++;
if ((uint64_t)out->difatMemallocCount * out->sectorSize >= SIZE_16M) { if ((uint64_t)out->difatMemallocCount * out->sectorSize >= SIZE_16M) {
printf("Failed to append DIFAT sector\n"); fprintf(stderr, "Failed to append DIFAT sector\n");
return 0; /* FAILED */ return 0; /* FAILED */
} }
out->difat = OPENSSL_realloc(out->difat, (size_t)(out->difatMemallocCount * out->sectorSize)); out->difat = OPENSSL_realloc(out->difat, (size_t)(out->difatMemallocCount * out->sectorSize));
if (!out->difat) { if (!out->difat) {
printf("Memory allocation failure\n"); fprintf(stderr, "Memory allocation failure\n");
return 0; /* FAILED */ return 0; /* FAILED */
} }
} }
@ -1582,7 +1582,7 @@ static int msi_dirent_delete(MSI_DIRENT *dirent, const u_char *name, uint16_t na
continue; continue;
} }
if (child->type != DIR_STREAM) { if (child->type != DIR_STREAM) {
printf("Can't delete or replace storages\n"); fprintf(stderr, "Can't delete or replace storages\n");
return 0; /* FAILED */ return 0; /* FAILED */
} }
sk_MSI_DIRENT_delete(dirent->children, i); sk_MSI_DIRENT_delete(dirent->children, i);
@ -1680,7 +1680,7 @@ static int stream_handle(MSI_FILE *msi, MSI_DIRENT *dirent, u_char *p_msi, uint3
if (dirent->type == DIR_ROOT) { if (dirent->type == DIR_ROOT) {
if (len_msi > 0 && !signature_insert(dirent, len_msiex)) { if (len_msi > 0 && !signature_insert(dirent, len_msiex)) {
printf("Insert new signature failed\n"); fprintf(stderr, "Insert new signature failed\n");
return 0; /* FAILED */ return 0; /* FAILED */
} }
out->ministreamsMemallocCount = (GET_UINT32_LE(dirent->entry->size) + out->sectorSize - 1)/out->sectorSize; out->ministreamsMemallocCount = (GET_UINT32_LE(dirent->entry->size) + out->sectorSize - 1)/out->sectorSize;
@ -1697,7 +1697,7 @@ static int stream_handle(MSI_FILE *msi, MSI_DIRENT *dirent, u_char *p_msi, uint3
char *indata = NULL; char *indata = NULL;
uint32_t inlen = GET_UINT32_LE(child->entry->size); uint32_t inlen = GET_UINT32_LE(child->entry->size);
if (inlen >= MAXREGSECT) { if (inlen >= MAXREGSECT) {
printf("Corrupted stream length 0x%08X\n", inlen); fprintf(stderr, "Corrupted stream length 0x%08X\n", inlen);
return 0; /* FAILED */ return 0; /* FAILED */
} }
/* DigitalSignature or MsiDigitalSignatureEx: inlen == 0 */ /* DigitalSignature or MsiDigitalSignatureEx: inlen == 0 */
@ -2239,11 +2239,11 @@ out:
static BIO *msi_digest_calc_bio(FILE_FORMAT_CTX *ctx, BIO *hash) static BIO *msi_digest_calc_bio(FILE_FORMAT_CTX *ctx, BIO *hash)
{ {
if (ctx->options->add_msi_dse && !msi_calc_MsiDigitalSignatureEx(ctx, hash)) { if (ctx->options->add_msi_dse && !msi_calc_MsiDigitalSignatureEx(ctx, hash)) {
printf("Unable to calc MsiDigitalSignatureEx\n"); fprintf(stderr, "Unable to calc MsiDigitalSignatureEx\n");
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
if (!msi_hash_dir(ctx->msi_ctx->msi, ctx->msi_ctx->dirent, hash, 1)) { if (!msi_hash_dir(ctx->msi_ctx->msi, ctx->msi_ctx->dirent, hash, 1)) {
printf("Unable to msi_handle_dir()\n"); fprintf(stderr, "Unable to msi_handle_dir()\n");
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
return hash; return hash;
@ -2296,14 +2296,14 @@ static int msi_calc_MsiDigitalSignatureEx(FILE_FORMAT_CTX *ctx, BIO *hash)
BIO *prehash = BIO_new(BIO_f_md()); BIO *prehash = BIO_new(BIO_f_md());
if (!BIO_set_md(prehash, ctx->options->md)) { if (!BIO_set_md(prehash, ctx->options->md)) {
printf("Unable to set the message digest of BIO\n"); fprintf(stderr, "Unable to set the message digest of BIO\n");
BIO_free_all(prehash); BIO_free_all(prehash);
return 0; /* FAILED */ return 0; /* FAILED */
} }
BIO_push(prehash, BIO_new(BIO_s_null())); BIO_push(prehash, BIO_new(BIO_s_null()));
if (!msi_prehash_dir(ctx->msi_ctx->dirent, prehash, 1)) { if (!msi_prehash_dir(ctx->msi_ctx->dirent, prehash, 1)) {
printf("Unable to calculate MSI pre-hash ('metadata') hash\n"); fprintf(stderr, "Unable to calculate MSI pre-hash ('metadata') hash\n");
return 0; /* FAILED */ return 0; /* FAILED */
} }
if (ctx->msi_ctx->p_msiex) { if (ctx->msi_ctx->p_msiex) {
@ -2335,23 +2335,23 @@ static int msi_check_MsiDigitalSignatureEx(FILE_FORMAT_CTX *ctx, MSI_ENTRY *dse,
alg = sk_X509_ALGOR_value(p7->d.sign->md_algs, 0); alg = sk_X509_ALGOR_value(p7->d.sign->md_algs, 0);
X509_ALGOR_get0(&aoid, NULL, NULL, alg); X509_ALGOR_get0(&aoid, NULL, NULL, alg);
printf("Message digest algorithm found : %s\n", OBJ_nid2sn(OBJ_obj2nid(aoid))); fprintf(stderr, "Message digest algorithm found : %s\n", OBJ_nid2sn(OBJ_obj2nid(aoid)));
printf("It is not possible to add a nested signature of a different MD type to the MSI file " fprintf(stderr, "It is not possible to add a nested signature of a different MD type to the MSI file "
"without invalidating the initial signature, as the file contains MsiDigitalSignatureEx.\n" "without invalidating the initial signature, as the file contains MsiDigitalSignatureEx.\n"
"The file should be signed again, rather than adding a nested signature.\n"); "The file should be signed again, rather than adding a nested signature.\n");
return 0; /* FAILED */ return 0; /* FAILED */
} }
if (!dse && ctx->options->add_msi_dse) { if (!dse && ctx->options->add_msi_dse) {
printf("It is not possible to add a nested signature using the -add-msi-dse parameter " fprintf(stderr, "It is not possible to add a nested signature using the -add-msi-dse parameter "
"without invalidating the initial signature, as the file does not contain MsiDigitalSignatureEx.\n" "without invalidating the initial signature, as the file does not contain MsiDigitalSignatureEx.\n"
"The file should be signed again, rather than adding a nested signature.\n"); "The file should be signed again, rather than adding a nested signature.\n");
return 0; /* FAILED */ return 0; /* FAILED */
} }
if (dse && !ctx->options->add_msi_dse) { if (dse && !ctx->options->add_msi_dse) {
printf("It is not possible to add a signature without using the -add-msi-dse parameter, " fprintf(stderr, "It is not possible to add a signature without using the -add-msi-dse parameter, "
"as doing so would invalidate the initial signature due to the presence of MsiDigitalSignatureEx.\n" "as doing so would invalidate the initial signature due to the presence of MsiDigitalSignatureEx.\n"
"In this case, consider using the -add-msi-dse option.\n"); "In this case, consider using the -add-msi-dse option.\n");
return 0; /* FAILED */ return 0; /* FAILED */
} }
return 1; /* OK */ return 1; /* OK */
} }
@ -2378,22 +2378,22 @@ static int msi_check_file(FILE_FORMAT_CTX *ctx)
MSI_ENTRY *ds, *dse = NULL; MSI_ENTRY *ds, *dse = NULL;
if (!ctx) { if (!ctx) {
printf("Init error\n\n"); fprintf(stderr, "Init error\n");
return 0; /* FAILED */ return 0; /* FAILED */
} }
ds = msi_signatures_get(ctx->msi_ctx->dirent, &dse); ds = msi_signatures_get(ctx->msi_ctx->dirent, &dse);
if (!ds) { if (!ds) {
printf("MSI file has no signature\n\n"); fprintf(stderr, "MSI file has no signature\n");
return 0; /* FAILED */ return 0; /* FAILED */
} }
inlen = GET_UINT32_LE(ds->size); inlen = GET_UINT32_LE(ds->size);
if (inlen == 0 || inlen >= MAXREGSECT) { if (inlen == 0 || inlen >= MAXREGSECT) {
printf("Corrupted DigitalSignature stream length 0x%08X\n", inlen); fprintf(stderr, "Corrupted DigitalSignature stream length 0x%08X\n", inlen);
return 0; /* FAILED */ return 0; /* FAILED */
} }
indata = OPENSSL_malloc((size_t)inlen); indata = OPENSSL_malloc((size_t)inlen);
if (!msi_file_read(ctx->msi_ctx->msi, ds, 0, indata, inlen)) { if (!msi_file_read(ctx->msi_ctx->msi, ds, 0, indata, inlen)) {
printf("DigitalSignature stream data error\n\n"); fprintf(stderr, "DigitalSignature stream data error\n\n");
OPENSSL_free(indata); OPENSSL_free(indata);
return 0; /* FAILED */ return 0; /* FAILED */
} }
@ -2402,7 +2402,7 @@ static int msi_check_file(FILE_FORMAT_CTX *ctx)
} else { } else {
ctx->msi_ctx->len_msiex = GET_UINT32_LE(dse->size); ctx->msi_ctx->len_msiex = GET_UINT32_LE(dse->size);
if (ctx->msi_ctx->len_msiex == 0 || ctx->msi_ctx->len_msiex >= MAXREGSECT) { if (ctx->msi_ctx->len_msiex == 0 || ctx->msi_ctx->len_msiex >= MAXREGSECT) {
printf("Corrupted MsiDigitalSignatureEx stream length 0x%08X\n", fprintf(stderr, "Corrupted MsiDigitalSignatureEx stream length 0x%08X\n",
ctx->msi_ctx->len_msiex); ctx->msi_ctx->len_msiex);
OPENSSL_free(indata); OPENSSL_free(indata);
return 0; /* FAILED */ return 0; /* FAILED */
@ -2410,7 +2410,7 @@ static int msi_check_file(FILE_FORMAT_CTX *ctx)
ctx->msi_ctx->p_msiex = OPENSSL_malloc((size_t)ctx->msi_ctx->len_msiex); ctx->msi_ctx->p_msiex = OPENSSL_malloc((size_t)ctx->msi_ctx->len_msiex);
if (!msi_file_read(ctx->msi_ctx->msi, dse, 0, (char *)ctx->msi_ctx->p_msiex, if (!msi_file_read(ctx->msi_ctx->msi, dse, 0, (char *)ctx->msi_ctx->p_msiex,
ctx->msi_ctx->len_msiex)) { ctx->msi_ctx->len_msiex)) {
printf("MsiDigitalSignatureEx stream data error\n\n"); fprintf(stderr, "MsiDigitalSignatureEx stream data error\n\n");
OPENSSL_free(indata); OPENSSL_free(indata);
return 0; /* FAILED */ return 0; /* FAILED */
} }

File diff suppressed because it is too large Load Diff

View File

@ -221,9 +221,9 @@
*/ */
#define FLAG_RESERVE_PRESENT 0x0004 #define FLAG_RESERVE_PRESENT 0x0004
#define DO_EXIT_0(x) { printf(x); goto err_cleanup; } #define DO_EXIT_0(x) { fprintf(stderr, x); goto err_cleanup; }
#define DO_EXIT_1(x, y) { printf(x, y); goto err_cleanup; } #define DO_EXIT_1(x, y) { fprintf(stderr, x, y); goto err_cleanup; }
#define DO_EXIT_2(x, y, z) { printf(x, y, z); goto err_cleanup; } #define DO_EXIT_2(x, y, z) { fprintf(stderr, x, y, z); goto err_cleanup; }
/* Default policy if request did not specify it. */ /* Default policy if request did not specify it. */
#define TSA_POLICY1 "1.2.3.4.1" #define TSA_POLICY1 "1.2.3.4.1"

84
pe.c
View File

@ -251,7 +251,7 @@ static int pe_verify_digests(FILE_FORMAT_CTX *ctx, PKCS7 *p7)
SpcIndirectDataContent *idc = d2i_SpcIndirectDataContent(NULL, &p, content_val->length); SpcIndirectDataContent *idc = d2i_SpcIndirectDataContent(NULL, &p, content_val->length);
if (idc) { if (idc) {
if (!pe_page_hash_get(&ph, &phlen, &phtype, idc->data)) { if (!pe_page_hash_get(&ph, &phlen, &phtype, idc->data)) {
printf("Failed to extract a page hash\n\n"); fprintf(stderr, "Failed to extract a page hash\n\n");
SpcIndirectDataContent_free(idc); SpcIndirectDataContent_free(idc);
return 0; /* FAILED */ return 0; /* FAILED */
} }
@ -263,25 +263,25 @@ static int pe_verify_digests(FILE_FORMAT_CTX *ctx, PKCS7 *p7)
} }
} }
if (mdtype == -1) { if (mdtype == -1) {
printf("Failed to extract current message digest\n\n"); fprintf(stderr, "Failed to extract current message digest\n\n");
OPENSSL_free(ph); OPENSSL_free(ph);
return 0; /* FAILED */ return 0; /* FAILED */
} }
md = EVP_get_digestbynid(mdtype); md = EVP_get_digestbynid(mdtype);
cmdbuf = pe_digest_calc(ctx, md); cmdbuf = pe_digest_calc(ctx, md);
if (!cmdbuf) { if (!cmdbuf) {
printf("Failed to calculate message digest\n\n"); fprintf(stderr, "Failed to calculate message digest\n\n");
OPENSSL_free(ph); OPENSSL_free(ph);
return 0; /* FAILED */ return 0; /* FAILED */
} }
if (!compare_digests(mdbuf, cmdbuf, mdtype)) { if (!compare_digests(mdbuf, cmdbuf, mdtype)) {
printf("Signature verification: failed\n\n"); fprintf(stderr, "Signature verification: failed\n\n");
OPENSSL_free(ph); OPENSSL_free(ph);
OPENSSL_free(cmdbuf); OPENSSL_free(cmdbuf);
return 0; /* FAILED */ return 0; /* FAILED */
} }
if (!pe_verify_page_hash(ctx, ph, phlen, phtype)) { if (!pe_verify_page_hash(ctx, ph, phlen, phtype)) {
printf("Signature verification: failed\n\n"); fprintf(stderr, "Signature verification: failed\n\n");
OPENSSL_free(ph); OPENSSL_free(ph);
OPENSSL_free(cmdbuf); OPENSSL_free(cmdbuf);
return 0; /* FAILED */ return 0; /* FAILED */
@ -303,11 +303,11 @@ static int pe_verify_indirect_data(FILE_FORMAT_CTX *ctx, SpcAttributeTypeAndOpti
u_char *ph = NULL; u_char *ph = NULL;
if (!pe_page_hash_get(&ph, &phlen, &phtype, obj)) { if (!pe_page_hash_get(&ph, &phlen, &phtype, obj)) {
printf("Failed to extract a page hash\n\n"); fprintf(stderr, "Failed to extract a page hash\n\n");
return 0; /* FAILED */ return 0; /* FAILED */
} }
if (!pe_verify_page_hash(ctx, ph, phlen, phtype)) { if (!pe_verify_page_hash(ctx, ph, phlen, phtype)) {
printf("Page hash verification: failed\n\n"); fprintf(stderr, "Page hash verification: failed\n\n");
OPENSSL_free(ph); OPENSSL_free(ph);
return 0; /* FAILED */ return 0; /* FAILED */
} }
@ -353,7 +353,7 @@ static int pe_remove_pkcs7(FILE_FORMAT_CTX *ctx, BIO *hash, BIO *outdata)
/* Strip current signature */ /* Strip current signature */
ctx->pe_ctx->fileend = ctx->pe_ctx->sigpos; ctx->pe_ctx->fileend = ctx->pe_ctx->sigpos;
if (!pe_modify_header(ctx, hash, outdata)) { if (!pe_modify_header(ctx, hash, outdata)) {
printf("Unable to modify file header\n"); fprintf(stderr, "Unable to modify file header\n");
return 1; /* FAILED */ return 1; /* FAILED */
} }
return 0; /* OK */ return 0; /* OK */
@ -373,7 +373,7 @@ static int pe_process_data(FILE_FORMAT_CTX *ctx, BIO *hash, BIO *outdata)
ctx->pe_ctx->fileend = ctx->pe_ctx->sigpos; ctx->pe_ctx->fileend = ctx->pe_ctx->sigpos;
} }
if (!pe_modify_header(ctx, hash, outdata)) { if (!pe_modify_header(ctx, hash, outdata)) {
printf("Unable to modify file header\n"); fprintf(stderr, "Unable to modify file header\n");
return 0; /* FAILED */ return 0; /* FAILED */
} }
return 1; /* OK */ return 1; /* OK */
@ -391,21 +391,21 @@ static PKCS7 *pe_pkcs7_signature_new(FILE_FORMAT_CTX *ctx, BIO *hash)
PKCS7 *p7 = pkcs7_create(ctx); PKCS7 *p7 = pkcs7_create(ctx);
if (!p7) { if (!p7) {
printf("Creating a new signature failed\n"); fprintf(stderr, "Creating a new signature failed\n");
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
if (!add_indirect_data_object(p7)) { if (!add_indirect_data_object(p7)) {
printf("Adding SPC_INDIRECT_DATA_OBJID failed\n"); fprintf(stderr, "Adding SPC_INDIRECT_DATA_OBJID failed\n");
PKCS7_free(p7); PKCS7_free(p7);
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
content = spc_indirect_data_content_get(hash, ctx); content = spc_indirect_data_content_get(hash, ctx);
if (!content) { if (!content) {
printf("Failed to get spcIndirectDataContent\n"); fprintf(stderr, "Failed to get spcIndirectDataContent\n");
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
if (!sign_spc_indirect_data_content(p7, content)) { if (!sign_spc_indirect_data_content(p7, content)) {
printf("Failed to set signed content\n"); fprintf(stderr, "Failed to set signed content\n");
PKCS7_free(p7); PKCS7_free(p7);
ASN1_OCTET_STRING_free(content); ASN1_OCTET_STRING_free(content);
return NULL; /* FAILED */ return NULL; /* FAILED */
@ -435,7 +435,7 @@ static int pe_append_pkcs7(FILE_FORMAT_CTX *ctx, BIO *outdata, PKCS7 *p7)
if (((len = i2d_PKCS7(p7, NULL)) <= 0) if (((len = i2d_PKCS7(p7, NULL)) <= 0)
|| (p = OPENSSL_malloc((size_t)len)) == NULL) { || (p = OPENSSL_malloc((size_t)len)) == NULL) {
printf("i2d_PKCS memory allocation failed: %d\n", len); fprintf(stderr, "i2d_PKCS memory allocation failed: %d\n", len);
return 1; /* FAILED */ return 1; /* FAILED */
} }
i2d_PKCS7(p7, &p); i2d_PKCS7(p7, &p);
@ -540,7 +540,7 @@ static PE_CTX *pe_ctx_get(char *indata, uint32_t filesize)
uint16_t magic; uint16_t magic;
if (filesize < 64) { if (filesize < 64) {
printf("Corrupt DOS file - too short\n"); fprintf(stderr, "Corrupt DOS file - too short\n");
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
/* SizeOfHeaders field specifies the combined size of an MS-DOS stub, PE header, /* SizeOfHeaders field specifies the combined size of an MS-DOS stub, PE header,
@ -549,15 +549,15 @@ static PE_CTX *pe_ctx_get(char *indata, uint32_t filesize)
* because of a bug when checking section names for compatibility purposes */ * because of a bug when checking section names for compatibility purposes */
header_size = GET_UINT32_LE(indata + 60); header_size = GET_UINT32_LE(indata + 60);
if (header_size < 44 || header_size > filesize) { if (header_size < 44 || header_size > filesize) {
printf("Unexpected SizeOfHeaders field: 0x%08X\n", header_size); fprintf(stderr, "Unexpected SizeOfHeaders field: 0x%08X\n", header_size);
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
if (filesize < header_size + 176) { if (filesize < header_size + 176) {
printf("Corrupt PE file - too short\n"); fprintf(stderr, "Corrupt PE file - too short\n");
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
if (memcmp(indata + header_size, "PE\0\0", 4)) { if (memcmp(indata + header_size, "PE\0\0", 4)) {
printf("Unrecognized DOS file type\n"); fprintf(stderr, "Unrecognized DOS file type\n");
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
/* Magic field identifies the state of the image file. The most common number is /* Magic field identifies the state of the image file. The most common number is
@ -570,7 +570,7 @@ static PE_CTX *pe_ctx_get(char *indata, uint32_t filesize)
} else if (magic == 0x10b) { } else if (magic == 0x10b) {
pe32plus = 0; pe32plus = 0;
} else { } else {
printf("Corrupt PE file - found unknown magic %04X\n", magic); fprintf(stderr, "Corrupt PE file - found unknown magic %04X\n", magic);
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
/* The image file checksum */ /* The image file checksum */
@ -579,7 +579,7 @@ static PE_CTX *pe_ctx_get(char *indata, uint32_t filesize)
* in the remainder of the optional header. Each describes a location and size. */ * in the remainder of the optional header. Each describes a location and size. */
nrvas = GET_UINT32_LE(indata + header_size + 116 + pe32plus * 16); nrvas = GET_UINT32_LE(indata + header_size + 116 + pe32plus * 16);
if (nrvas < 5) { if (nrvas < 5) {
printf("Can not handle PE files without certificate table resource\n"); fprintf(stderr, "Can not handle PE files without certificate table resource\n");
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
/* Certificate Table field specifies the attribute certificate table address (4 bytes) and size (4 bytes) */ /* Certificate Table field specifies the attribute certificate table address (4 bytes) and size (4 bytes) */
@ -589,7 +589,7 @@ static PE_CTX *pe_ctx_get(char *indata, uint32_t filesize)
that signature should be last part of file */ that signature should be last part of file */
if ((sigpos != 0 || siglen != 0) && if ((sigpos != 0 || siglen != 0) &&
(sigpos == 0 || siglen == 0 || sigpos >= filesize || sigpos + siglen != filesize)) { (sigpos == 0 || siglen == 0 || sigpos >= filesize || sigpos + siglen != filesize)) {
printf("Ignoring PE signature not at the end of the file\n"); printf("Warning: Ignoring PE signature not at the end of the file\n");
sigpos = 0; sigpos = 0;
siglen = 0; siglen = 0;
} }
@ -617,7 +617,7 @@ static PKCS7 *pe_pkcs7_get_file(char *indata, PE_CTX *pe_ctx)
uint32_t pos = 0; uint32_t pos = 0;
if (pe_ctx->siglen == 0 || pe_ctx->siglen > pe_ctx->fileend) { if (pe_ctx->siglen == 0 || pe_ctx->siglen > pe_ctx->fileend) {
printf("Corrupted signature length: 0x%08X\n", pe_ctx->siglen); fprintf(stderr, "Corrupted signature length: 0x%08X\n", pe_ctx->siglen);
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
while (pos < pe_ctx->siglen) { while (pos < pe_ctx->siglen) {
@ -780,7 +780,7 @@ static BIO *pe_digest_calc_bio(FILE_FORMAT_CTX *ctx, const EVP_MD *md)
BIO *bhash = BIO_new(BIO_f_md()); BIO *bhash = BIO_new(BIO_f_md());
if (!BIO_set_md(bhash, md)) { if (!BIO_set_md(bhash, md)) {
printf("Unable to set the message digest of BIO\n"); fprintf(stderr, "Unable to set the message digest of BIO\n");
BIO_free_all(bhash); BIO_free_all(bhash);
return 0; /* FAILED */ return 0; /* FAILED */
} }
@ -805,7 +805,7 @@ static BIO *pe_digest_calc_bio(FILE_FORMAT_CTX *ctx, const EVP_MD *md)
} }
idx += (uint32_t)written + 8; idx += (uint32_t)written + 8;
if (!bio_hash_data(bhash, ctx->options->indata, idx, fileend)) { if (!bio_hash_data(bhash, ctx->options->indata, idx, fileend)) {
printf("Unable to calculate digest\n"); fprintf(stderr, "Unable to calculate digest\n");
BIO_free_all(bhash); BIO_free_all(bhash);
return 0; /* FAILED */ return 0; /* FAILED */
} }
@ -918,7 +918,7 @@ static u_char *pe_page_hash_calc(int *rphlen, FILE_FORMAT_CTX *ctx, int phtype)
* which immediately follows the headers, can be up to 65535 under Vista and later */ * which immediately follows the headers, can be up to 65535 under Vista and later */
nsections = GET_UINT16_LE(ctx->options->indata + ctx->pe_ctx->header_size + 6); nsections = GET_UINT16_LE(ctx->options->indata + ctx->pe_ctx->header_size + 6);
if (nsections == 0) { if (nsections == 0) {
printf("Corrupted number of sections: 0x%08X\n", nsections); fprintf(stderr, "Corrupted number of sections: 0x%08X\n", nsections);
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
/* FileAlignment is the alignment factor (in bytes) that is used to align /* FileAlignment is the alignment factor (in bytes) that is used to align
@ -926,7 +926,7 @@ static u_char *pe_page_hash_calc(int *rphlen, FILE_FORMAT_CTX *ctx, int phtype)
* of 2 between 512 and 64 K, inclusive. The default is 512. */ * of 2 between 512 and 64 K, inclusive. The default is 512. */
alignment = GET_UINT32_LE(ctx->options->indata + ctx->pe_ctx->header_size + 60); alignment = GET_UINT32_LE(ctx->options->indata + ctx->pe_ctx->header_size + 60);
if (alignment < 512 || alignment > UINT16_MAX) { if (alignment < 512 || alignment > UINT16_MAX) {
printf("Corrupted file alignment factor: 0x%08X\n", alignment); fprintf(stderr, "Corrupted file alignment factor: 0x%08X\n", alignment);
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
/* SectionAlignment is the alignment (in bytes) of sections when they are /* SectionAlignment is the alignment (in bytes) of sections when they are
@ -936,14 +936,14 @@ static u_char *pe_page_hash_calc(int *rphlen, FILE_FORMAT_CTX *ctx, int phtype)
* https://devblogs.microsoft.com/oldnewthing/20210510-00/?p=105200 */ * https://devblogs.microsoft.com/oldnewthing/20210510-00/?p=105200 */
pagesize = GET_UINT32_LE(ctx->options->indata + ctx->pe_ctx->header_size + 56); pagesize = GET_UINT32_LE(ctx->options->indata + ctx->pe_ctx->header_size + 56);
if (pagesize == 0 || pagesize < alignment || pagesize > 4194304) { if (pagesize == 0 || pagesize < alignment || pagesize > 4194304) {
printf("Corrupted page size: 0x%08X\n", pagesize); fprintf(stderr, "Corrupted page size: 0x%08X\n", pagesize);
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
/* SizeOfHeaders is the combined size of an MS-DOS stub, PE header, /* SizeOfHeaders is the combined size of an MS-DOS stub, PE header,
* and section headers rounded up to a multiple of FileAlignment. */ * and section headers rounded up to a multiple of FileAlignment. */
hdrsize = GET_UINT32_LE(ctx->options->indata + ctx->pe_ctx->header_size + 84); hdrsize = GET_UINT32_LE(ctx->options->indata + ctx->pe_ctx->header_size + 84);
if (hdrsize < ctx->pe_ctx->header_size || hdrsize > UINT32_MAX) { if (hdrsize < ctx->pe_ctx->header_size || hdrsize > UINT32_MAX) {
printf("Corrupted headers size: 0x%08X\n", hdrsize); fprintf(stderr, "Corrupted headers size: 0x%08X\n", hdrsize);
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
/* SizeOfOptionalHeader is the size of the optional header, which is /* SizeOfOptionalHeader is the size of the optional header, which is
@ -951,7 +951,7 @@ static u_char *pe_page_hash_calc(int *rphlen, FILE_FORMAT_CTX *ctx, int phtype)
* and can't be bigger than the file */ * and can't be bigger than the file */
opthdr_size = GET_UINT16_LE(ctx->options->indata + ctx->pe_ctx->header_size + 20); opthdr_size = GET_UINT16_LE(ctx->options->indata + ctx->pe_ctx->header_size + 20);
if (opthdr_size == 0 || opthdr_size > ctx->pe_ctx->fileend) { if (opthdr_size == 0 || opthdr_size > ctx->pe_ctx->fileend) {
printf("Corrupted optional header size: 0x%08X\n", opthdr_size); fprintf(stderr, "Corrupted optional header size: 0x%08X\n", opthdr_size);
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
pphlen = 4 + EVP_MD_size(md); pphlen = 4 + EVP_MD_size(md);
@ -959,7 +959,7 @@ static u_char *pe_page_hash_calc(int *rphlen, FILE_FORMAT_CTX *ctx, int phtype)
bhash = BIO_new(BIO_f_md()); bhash = BIO_new(BIO_f_md());
if (!BIO_set_md(bhash, md)) { if (!BIO_set_md(bhash, md)) {
printf("Unable to set the message digest of BIO\n"); fprintf(stderr, "Unable to set the message digest of BIO\n");
BIO_free_all(bhash); BIO_free_all(bhash);
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
@ -1006,7 +1006,7 @@ static u_char *pe_page_hash_calc(int *rphlen, FILE_FORMAT_CTX *ctx, int phtype)
PUT_UINT32_LE(ro + l, res + pi*pphlen); PUT_UINT32_LE(ro + l, res + pi*pphlen);
bhash = BIO_new(BIO_f_md()); bhash = BIO_new(BIO_f_md());
if (!BIO_set_md(bhash, md)) { if (!BIO_set_md(bhash, md)) {
printf("Unable to set the message digest of BIO\n"); fprintf(stderr, "Unable to set the message digest of BIO\n");
BIO_free_all(bhash); BIO_free_all(bhash);
OPENSSL_free(zeroes); OPENSSL_free(zeroes);
OPENSSL_free(res); OPENSSL_free(res);
@ -1099,7 +1099,7 @@ static SpcLink *pe_page_hash_link_get(FILE_FORMAT_CTX *ctx, int phtype)
ph = pe_page_hash_calc(&phlen, ctx, phtype); ph = pe_page_hash_calc(&phlen, ctx, phtype);
if (!ph) { if (!ph) {
printf("Failed to calculate page hash\n"); fprintf(stderr, "Failed to calculate page hash\n");
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
if (ctx->options->verbose) if (ctx->options->verbose)
@ -1170,20 +1170,20 @@ static int pe_check_file(FILE_FORMAT_CTX *ctx)
uint32_t real_pe_checksum, sum = 0; uint32_t real_pe_checksum, sum = 0;
if (!ctx) { if (!ctx) {
printf("Init error\n\n"); fprintf(stderr, "Init error\n");
return 0; /* FAILED */ return 0; /* FAILED */
} }
real_pe_checksum = pe_calc_realchecksum(ctx); real_pe_checksum = pe_calc_realchecksum(ctx);
if (ctx->pe_ctx->pe_checksum == real_pe_checksum) { if (ctx->pe_ctx->pe_checksum == real_pe_checksum) {
printf("PE checksum : %08X\n\n", real_pe_checksum); printf("PE checksum : %08X\n", real_pe_checksum);
} else { } else {
printf("Current PE checksum : %08X\n", ctx->pe_ctx->pe_checksum); printf("Current PE checksum : %08X\n", ctx->pe_ctx->pe_checksum);
printf("Calculated PE checksum: %08X\n", real_pe_checksum); printf("Calculated PE checksum: %08X\n", real_pe_checksum);
printf("Warning: invalid PE checksum\n\n"); printf("Warning: invalid PE checksum\n");
} }
if (ctx->pe_ctx->sigpos == 0 || ctx->pe_ctx->siglen == 0 if (ctx->pe_ctx->sigpos == 0 || ctx->pe_ctx->siglen == 0
|| ctx->pe_ctx->sigpos > ctx->pe_ctx->fileend) { || ctx->pe_ctx->sigpos > ctx->pe_ctx->fileend) {
printf("No signature found\n\n"); fprintf(stderr, "No signature found\n");
return 0; /* FAILED */ return 0; /* FAILED */
} }
/* /*
@ -1193,9 +1193,9 @@ static int pe_check_file(FILE_FORMAT_CTX *ctx)
while (sum < ctx->pe_ctx->siglen) { while (sum < ctx->pe_ctx->siglen) {
uint32_t len = GET_UINT32_LE(ctx->options->indata + ctx->pe_ctx->sigpos + sum); uint32_t len = GET_UINT32_LE(ctx->options->indata + ctx->pe_ctx->sigpos + sum);
if (ctx->pe_ctx->siglen - len > 8) { if (ctx->pe_ctx->siglen - len > 8) {
printf("Corrupted attribute certificate table\n"); fprintf(stderr, "Corrupted attribute certificate table\n");
printf("Attribute certificate table size : %08X\n", ctx->pe_ctx->siglen); fprintf(stderr, "Attribute certificate table size : %08X\n", ctx->pe_ctx->siglen);
printf("Attribute certificate entry length: %08X\n\n", len); fprintf(stderr, "Attribute certificate entry length: %08X\n\n", len);
return 0; /* FAILED */ return 0; /* FAILED */
} }
/* quadword align data */ /* quadword align data */
@ -1203,9 +1203,9 @@ static int pe_check_file(FILE_FORMAT_CTX *ctx)
sum += len; sum += len;
} }
if (sum != ctx->pe_ctx->siglen) { if (sum != ctx->pe_ctx->siglen) {
printf("Corrupted attribute certificate table\n"); fprintf(stderr, "Corrupted attribute certificate table\n");
printf("Attribute certificate table size : %08X\n", ctx->pe_ctx->siglen); fprintf(stderr, "Attribute certificate table size : %08X\n", ctx->pe_ctx->siglen);
printf("Sum of the rounded dwLength values: %08X\n\n", sum); fprintf(stderr, "Sum of the rounded dwLength values: %08X\n\n", sum);
return 0; /* FAILED */ return 0; /* FAILED */
} }
return 1; /* OK */ return 1; /* OK */

View File

@ -243,7 +243,7 @@ static u_char *script_digest_calc(FILE_FORMAT_CTX *ctx, const EVP_MD *md)
BIO *hash = BIO_new(BIO_f_md()); BIO *hash = BIO_new(BIO_f_md());
if (!BIO_set_md(hash, md)) { if (!BIO_set_md(hash, md)) {
printf("Unable to set the message digest of BIO\n"); fprintf(stderr, "Unable to set the message digest of BIO\n");
BIO_free_all(hash); BIO_free_all(hash);
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
@ -286,7 +286,7 @@ static int script_verify_digests(FILE_FORMAT_CTX *ctx, PKCS7 *p7)
} }
} }
if (mdtype == -1) { if (mdtype == -1) {
printf("Failed to extract current message digest\n\n"); fprintf(stderr, "Failed to extract current message digest\n\n");
return 0; /* FAILED */ return 0; /* FAILED */
} }
md = EVP_get_digestbynid(mdtype); md = EVP_get_digestbynid(mdtype);
@ -299,7 +299,7 @@ static int script_verify_digests(FILE_FORMAT_CTX *ctx, PKCS7 *p7)
BIO_free_all(bhash); BIO_free_all(bhash);
if (!compare_digests(mdbuf, cmdbuf, mdtype)) { if (!compare_digests(mdbuf, cmdbuf, mdtype)) {
printf("Signature verification: failed\n\n"); fprintf(stderr, "Signature verification: failed\n\n");
OPENSSL_free(cmdbuf); OPENSSL_free(cmdbuf);
return 0; /* FAILED */ return 0; /* FAILED */
} }
@ -346,7 +346,7 @@ static PKCS7 *script_pkcs7_extract(FILE_FORMAT_CTX *ctx)
/* allocate memory for cleaned Base64 */ /* allocate memory for cleaned Base64 */
clean_base64 = OPENSSL_malloc(base64_len); clean_base64 = OPENSSL_malloc(base64_len);
if (!clean_base64) { if (!clean_base64) {
printf("Malloc failed\n"); fprintf(stderr, "Malloc failed\n");
goto cleanup; goto cleanup;
} }
@ -355,7 +355,7 @@ static PKCS7 *script_pkcs7_extract(FILE_FORMAT_CTX *ctx)
/* find the opening tag */ /* find the opening tag */
for(;;) { for(;;) {
if (ptr + open_tag_len >= base64_data + base64_len) { if (ptr + open_tag_len >= base64_data + base64_len) {
printf("Signature line too long\n"); fprintf(stderr, "Signature line too long\n");
goto cleanup; goto cleanup;
} }
if (!memcmp(ptr, open_tag, (size_t)open_tag_len)) { if (!memcmp(ptr, open_tag, (size_t)open_tag_len)) {
@ -375,7 +375,7 @@ static PKCS7 *script_pkcs7_extract(FILE_FORMAT_CTX *ctx)
/* copy until the closing tag */ /* copy until the closing tag */
for(;;) { for(;;) {
if (ptr + close_tag_len >= base64_data + base64_len) { if (ptr + close_tag_len >= base64_data + base64_len) {
printf("Signature line too long\n"); fprintf(stderr, "Signature line too long\n");
goto cleanup; goto cleanup;
} }
if (close_tag_len) { if (close_tag_len) {
@ -473,21 +473,21 @@ static PKCS7 *script_pkcs7_signature_new(FILE_FORMAT_CTX *ctx, BIO *hash)
PKCS7 *p7 = pkcs7_create(ctx); PKCS7 *p7 = pkcs7_create(ctx);
if (!p7) { if (!p7) {
printf("Creating a new signature failed\n"); fprintf(stderr, "Creating a new signature failed\n");
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
if (!add_indirect_data_object(p7)) { if (!add_indirect_data_object(p7)) {
printf("Adding SPC_INDIRECT_DATA_OBJID failed\n"); fprintf(stderr, "Adding SPC_INDIRECT_DATA_OBJID failed\n");
PKCS7_free(p7); PKCS7_free(p7);
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
content = spc_indirect_data_content_get(hash, ctx); content = spc_indirect_data_content_get(hash, ctx);
if (!content) { if (!content) {
printf("Failed to get spcIndirectDataContent\n"); fprintf(stderr, "Failed to get spcIndirectDataContent\n");
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
if (!sign_spc_indirect_data_content(p7, content)) { if (!sign_spc_indirect_data_content(p7, content)) {
printf("Failed to set signed content\n"); fprintf(stderr, "Failed to set signed content\n");
PKCS7_free(p7); PKCS7_free(p7);
ASN1_OCTET_STRING_free(content); ASN1_OCTET_STRING_free(content);
return NULL; /* FAILED */ return NULL; /* FAILED */
@ -784,13 +784,13 @@ static BIO *script_digest_calc_bio(FILE_FORMAT_CTX *ctx, const EVP_MD *md)
fileend = ctx->script_ctx->fileend; fileend = ctx->script_ctx->fileend;
if (!BIO_set_md(hash, md)) { if (!BIO_set_md(hash, md)) {
printf("Unable to set the message digest of BIO\n"); fprintf(stderr, "Unable to set the message digest of BIO\n");
BIO_free_all(hash); BIO_free_all(hash);
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
BIO_push(hash, BIO_new(BIO_s_null())); BIO_push(hash, BIO_new(BIO_s_null()));
if (!script_digest_convert(hash, ctx, fileend)) { if (!script_digest_convert(hash, ctx, fileend)) {
printf("Unable calc a message digest value\n"); fprintf(stderr, "Unable calc a message digest value\n");
BIO_free_all(hash); BIO_free_all(hash);
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
@ -852,12 +852,12 @@ static int script_write_bio(BIO *bio, char *indata, size_t len)
static int script_check_file(FILE_FORMAT_CTX *ctx) static int script_check_file(FILE_FORMAT_CTX *ctx)
{ {
if (!ctx) { if (!ctx) {
printf("Init error\n\n"); fprintf(stderr, "Init error\n");
return 0; /* FAILED */ return 0; /* FAILED */
} }
if (ctx->script_ctx->sigpos == 0 if (ctx->script_ctx->sigpos == 0
|| ctx->script_ctx->sigpos > ctx->script_ctx->fileend) { || ctx->script_ctx->sigpos > ctx->script_ctx->fileend) {
printf("No signature found\n\n"); fprintf(stderr, "No signature found\n");
return 0; /* FAILED */ return 0; /* FAILED */
} }

View File

@ -2,7 +2,7 @@
"""Implementation of a single ctest script.""" """Implementation of a single ctest script."""
import sys import sys
import subprocess from subprocess import Popen, PIPE
def parse(value): def parse(value):
@ -19,7 +19,11 @@ def main() -> None:
if len(sys.argv) > 1: if len(sys.argv) > 1:
try: try:
params = map(parse, sys.argv[1:]) params = map(parse, sys.argv[1:])
proc = subprocess.run(params, check=True) proc = Popen(params, stdout=PIPE, stderr=PIPE, text=True)
stdout, stderr = proc.communicate()
print(stdout, file=sys.stderr)
if stderr:
print("Error:\n" + "-" * 58 + "\n" + stderr, file=sys.stderr)
sys.exit(proc.returncode) sys.exit(proc.returncode)
except Exception as err: # pylint: disable=broad-except except Exception as err: # pylint: disable=broad-except
# all exceptions are critical # all exceptions are critical