mirror of
https://github.com/mtrojnar/osslsigncode
synced 2026-06-08 16:13:39 +00:00
Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| fac8164622 | |||
| cbee1e723c | |||
| f90327df09 |
@@ -7,7 +7,7 @@ on:
|
||||
env:
|
||||
# Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.)
|
||||
BUILD_TYPE: Release
|
||||
version: osslsigncode-2.11
|
||||
version: osslsigncode-2.12
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
+1
-1
@@ -10,7 +10,7 @@ set(BUILTIN_SOCKET ON CACHE BOOL "") # for static Python
|
||||
|
||||
# configure basic project information
|
||||
project(osslsigncode
|
||||
VERSION 2.11
|
||||
VERSION 2.12
|
||||
DESCRIPTION "OpenSSL based Authenticode signing for PE, CAB, CAT, MSI, APPX and script files"
|
||||
HOMEPAGE_URL "https://github.com/mtrojnar/osslsigncode"
|
||||
LANGUAGES C)
|
||||
|
||||
@@ -1,5 +1,18 @@
|
||||
# osslsigncode change log
|
||||
|
||||
### 2.12 (2026.02.02)
|
||||
|
||||
**CRITICAL SECURITY VULNERABILITY**
|
||||
|
||||
This release fixes a critical memory corruption vulnerability. A malicious
|
||||
attacker could create a signed file, which, when verified with osslsigncode,
|
||||
triggers arbitrary code execution. Any previous version of osslsigncode should
|
||||
be immediately upgraded if the tool is used for verification of untrusted
|
||||
files.
|
||||
|
||||
- fixed a buffer overflow while extracting message digests
|
||||
(reported and fixed by Antoni Klajn, Opera)
|
||||
|
||||
### 2.11 (2026.01.20)
|
||||
- added keyUsage validation for signer certificate
|
||||
(thanks to Hanqing Zhao and Zi-Quan You for reporting the issue)
|
||||
|
||||
@@ -342,9 +342,9 @@ static int cab_verify_digests(FILE_FORMAT_CTX *ctx, PKCS7 *p7)
|
||||
const u_char *p = content_val->data;
|
||||
SpcIndirectDataContent *idc = d2i_SpcIndirectDataContent(NULL, &p, content_val->length);
|
||||
if (idc) {
|
||||
if (idc->messageDigest && idc->messageDigest->digest && idc->messageDigest->digestAlgorithm) {
|
||||
mdtype = OBJ_obj2nid(idc->messageDigest->digestAlgorithm->algorithm);
|
||||
memcpy(mdbuf, idc->messageDigest->digest->data, (size_t)idc->messageDigest->digest->length);
|
||||
if (spc_extract_digest_safe(idc, mdbuf, &mdtype) < 0) {
|
||||
SpcIndirectDataContent_free(idc);
|
||||
return 0; /* FAILED */
|
||||
}
|
||||
SpcIndirectDataContent_free(idc);
|
||||
}
|
||||
|
||||
@@ -390,10 +390,9 @@ static int cat_print_content_member_digest(ASN1_TYPE *content)
|
||||
idc = d2i_SpcIndirectDataContent(NULL, &data, ASN1_STRING_length(value));
|
||||
if (!idc)
|
||||
return 0; /* FAILED */
|
||||
if (idc->messageDigest && idc->messageDigest->digest && idc->messageDigest->digestAlgorithm) {
|
||||
/* get a digest algorithm a message digest of the file from the content */
|
||||
mdtype = OBJ_obj2nid(idc->messageDigest->digestAlgorithm->algorithm);
|
||||
memcpy(mdbuf, idc->messageDigest->digest->data, (size_t)idc->messageDigest->digest->length);
|
||||
if (spc_extract_digest_safe(idc, mdbuf, &mdtype) < 0) {
|
||||
SpcIndirectDataContent_free(idc);
|
||||
return 0; /* FAILED */
|
||||
}
|
||||
SpcIndirectDataContent_free(idc);
|
||||
if (mdtype == -1) {
|
||||
|
||||
@@ -548,6 +548,33 @@ SpcLink *spc_link_obsolete_get(void)
|
||||
return link;
|
||||
}
|
||||
|
||||
/*
|
||||
* Safely extract digest from SpcIndirectDataContent
|
||||
* [in] idc: parsed SpcIndirectDataContent
|
||||
* [out] mdbuf: output buffer (must be EVP_MAX_MD_SIZE bytes)
|
||||
* [out] mdtype: digest algorithm's NID
|
||||
* [returns] -1 on error or digest length on success
|
||||
*/
|
||||
int spc_extract_digest_safe(SpcIndirectDataContent *idc,
|
||||
u_char *mdbuf, int *mdtype)
|
||||
{
|
||||
int digest_len;
|
||||
|
||||
if (!idc || !idc->messageDigest || !idc->messageDigest->digest ||
|
||||
!idc->messageDigest->digestAlgorithm) {
|
||||
fprintf(stderr, "Missing digest data\n");
|
||||
return -1;
|
||||
}
|
||||
digest_len = idc->messageDigest->digest->length;
|
||||
if (digest_len <= 0 || digest_len > EVP_MAX_MD_SIZE) {
|
||||
fprintf(stderr, "Invalid digest length: %d\n", digest_len);
|
||||
return -1;
|
||||
}
|
||||
memcpy(mdbuf, idc->messageDigest->digest->data, (size_t)digest_len);
|
||||
*mdtype = OBJ_obj2nid(idc->messageDigest->digestAlgorithm->algorithm);
|
||||
return digest_len;
|
||||
}
|
||||
|
||||
/*
|
||||
* [in] mdbuf, cmdbuf: message digests
|
||||
* [in] mdtype: message digest algorithm type
|
||||
|
||||
@@ -24,6 +24,8 @@ int is_content_type(PKCS7 *p7, const char *objid);
|
||||
MsCtlContent *ms_ctl_content_get(PKCS7 *p7);
|
||||
ASN1_TYPE *catalog_content_get(CatalogAuthAttr *attribute);
|
||||
SpcLink *spc_link_obsolete_get(void);
|
||||
int spc_extract_digest_safe(SpcIndirectDataContent *idc,
|
||||
u_char *mdbuf, int *mdtype);
|
||||
int compare_digests(u_char *mdbuf, u_char *cmdbuf, int mdtype);
|
||||
|
||||
/*
|
||||
|
||||
@@ -419,9 +419,9 @@ static int msi_verify_digests(FILE_FORMAT_CTX *ctx, PKCS7 *p7)
|
||||
const u_char *p = content_val->data;
|
||||
SpcIndirectDataContent *idc = d2i_SpcIndirectDataContent(NULL, &p, content_val->length);
|
||||
if (idc) {
|
||||
if (idc->messageDigest && idc->messageDigest->digest && idc->messageDigest->digestAlgorithm) {
|
||||
mdtype = OBJ_obj2nid(idc->messageDigest->digestAlgorithm->algorithm);
|
||||
memcpy(mdbuf, idc->messageDigest->digest->data, (size_t)idc->messageDigest->digest->length);
|
||||
if (spc_extract_digest_safe(idc, mdbuf, &mdtype) < 0) {
|
||||
SpcIndirectDataContent_free(idc);
|
||||
return 0; /* FAILED */
|
||||
}
|
||||
SpcIndirectDataContent_free(idc);
|
||||
}
|
||||
|
||||
+3
-4
@@ -3082,10 +3082,9 @@ static int verify_content_member_digest(FILE_FORMAT_CTX *ctx, ASN1_TYPE *content
|
||||
fprintf(stderr, "Failed to extract SpcIndirectDataContent data\n");
|
||||
return 1; /* FAILED */
|
||||
}
|
||||
if (idc->messageDigest && idc->messageDigest->digest && idc->messageDigest->digestAlgorithm) {
|
||||
/* get a digest algorithm a message digest of the file from the content */
|
||||
mdtype = OBJ_obj2nid(idc->messageDigest->digestAlgorithm->algorithm);
|
||||
memcpy(mdbuf, idc->messageDigest->digest->data, (size_t)idc->messageDigest->digest->length);
|
||||
if (spc_extract_digest_safe(idc, mdbuf, &mdtype) < 0) {
|
||||
SpcIndirectDataContent_free(idc);
|
||||
return 1; /* FAILED */
|
||||
}
|
||||
if (mdtype == -1) {
|
||||
fprintf(stderr, "Failed to extract current message digest\n\n");
|
||||
|
||||
@@ -255,9 +255,9 @@ static int pe_verify_digests(FILE_FORMAT_CTX *ctx, PKCS7 *p7)
|
||||
SpcIndirectDataContent_free(idc);
|
||||
return 0; /* FAILED */
|
||||
}
|
||||
if (idc->messageDigest && idc->messageDigest->digest && idc->messageDigest->digestAlgorithm) {
|
||||
mdtype = OBJ_obj2nid(idc->messageDigest->digestAlgorithm->algorithm);
|
||||
memcpy(mdbuf, idc->messageDigest->digest->data, (size_t)idc->messageDigest->digest->length);
|
||||
if (spc_extract_digest_safe(idc, mdbuf, &mdtype) < 0) {
|
||||
SpcIndirectDataContent_free(idc);
|
||||
return 0; /* FAILED */
|
||||
}
|
||||
SpcIndirectDataContent_free(idc);
|
||||
}
|
||||
|
||||
@@ -294,9 +294,9 @@ static int script_verify_digests(FILE_FORMAT_CTX *ctx, PKCS7 *p7)
|
||||
const u_char *p = content_val->data;
|
||||
SpcIndirectDataContent *idc = d2i_SpcIndirectDataContent(NULL, &p, content_val->length);
|
||||
if (idc) {
|
||||
if (idc->messageDigest && idc->messageDigest->digest && idc->messageDigest->digestAlgorithm) {
|
||||
mdtype = OBJ_obj2nid(idc->messageDigest->digestAlgorithm->algorithm);
|
||||
memcpy(mdbuf, idc->messageDigest->digest->data, (size_t)idc->messageDigest->digest->length);
|
||||
if (spc_extract_digest_safe(idc, mdbuf, &mdtype) < 0) {
|
||||
SpcIndirectDataContent_free(idc);
|
||||
return 0; /* FAILED */
|
||||
}
|
||||
SpcIndirectDataContent_free(idc);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user