mirror of
https://github.com/avast/retdec.git
synced 2024-11-26 22:30:35 +00:00
Updated authenticode-parser to the latest version
This commit is contained in:
parent
153690d2d1
commit
094a37393f
@ -106,8 +106,8 @@ typedef struct {
|
||||
char* key_alg; /* Name of the key algorithm */
|
||||
char* sig_alg; /* Name of the signature algorithm */
|
||||
char* sig_alg_oid; /* OID of the signature algorithm */
|
||||
time_t not_before; /* NotBefore validity */
|
||||
time_t not_after; /* NotAfter validity */
|
||||
int64_t not_before; /* NotBefore validity */
|
||||
int64_t not_after; /* NotAfter validity */
|
||||
char* key; /* PEM encoded public key */
|
||||
Attributes issuer_attrs; /* Parsed X509 Attributes of Issuer */
|
||||
Attributes subject_attrs; /* Parsed X509 Attributes of Subject */
|
||||
@ -120,7 +120,7 @@ typedef struct {
|
||||
|
||||
typedef struct {
|
||||
int verify_flags; /* COUNTERISGNATURE_VFY_ flag */
|
||||
time_t sign_time; /* Signing time of the timestamp countersignature */
|
||||
int64_t sign_time; /* Signing time of the timestamp countersignature */
|
||||
char* digest_alg; /* Name of the digest algorithm used */
|
||||
ByteArray digest; /* Stored message digest */
|
||||
CertificateArray* chain; /* Certificate chain of the signer */
|
||||
@ -190,7 +190,7 @@ AuthenticodeArray* parse_authenticode(const uint8_t* pe_data, uint64_t pe_len);
|
||||
* @param len
|
||||
* @return AuthenticodeArray*
|
||||
*/
|
||||
AuthenticodeArray* authenticode_new(const uint8_t* data, long len);
|
||||
AuthenticodeArray* authenticode_new(const uint8_t* data, int32_t len);
|
||||
|
||||
/**
|
||||
* @brief Deallocates AuthenticodeArray and all it's allocated members
|
||||
|
13
deps/authenticode-parser/src/authenticode.c
vendored
13
deps/authenticode-parser/src/authenticode.c
vendored
@ -22,6 +22,7 @@ SOFTWARE.
|
||||
#include <openssl/asn1.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/objects.h>
|
||||
#include <openssl/opensslv.h>
|
||||
#include <openssl/ossl_typ.h>
|
||||
#include <openssl/pkcs7.h>
|
||||
#include <openssl/safestack.h>
|
||||
@ -274,7 +275,8 @@ static bool authenticode_verify(PKCS7* p7, PKCS7_SIGNER_INFO* si, X509* signCert
|
||||
}
|
||||
|
||||
/* Creates all the Authenticode objects so we can parse them with OpenSSL, is not thread-safe, needs
|
||||
* to be called once before any multi-threading environmentt - https://github.com/openssl/openssl/issues/13524 */
|
||||
* to be called once before any multi-threading environmentt -
|
||||
* https://github.com/openssl/openssl/issues/13524 */
|
||||
void initialize_authenticode_parser()
|
||||
{
|
||||
OBJ_create("1.3.6.1.4.1.311.2.1.12", "spcSpOpusInfo", "SPC_SP_OPUS_INFO_OBJID");
|
||||
@ -285,9 +287,9 @@ void initialize_authenticode_parser()
|
||||
|
||||
/* Return array of Authenticode signatures stored in the data, there can be multiple
|
||||
* of signatures as Authenticode signatures are often nested through unauth attributes */
|
||||
AuthenticodeArray* authenticode_new(const uint8_t* data, long len)
|
||||
AuthenticodeArray* authenticode_new(const uint8_t* data, int32_t len)
|
||||
{
|
||||
if (!data || len == 0)
|
||||
if (!data || len <= 0)
|
||||
return NULL;
|
||||
|
||||
AuthenticodeArray* result = (AuthenticodeArray*)calloc(1, sizeof(*result));
|
||||
@ -318,7 +320,7 @@ AuthenticodeArray* authenticode_new(const uint8_t* data, long len)
|
||||
}
|
||||
|
||||
/* We expect SignedData type of PKCS7 */
|
||||
if (!PKCS7_type_is_signed(p7)) {
|
||||
if (!PKCS7_type_is_signed(p7) || !p7->d.sign) {
|
||||
auth->verify_flags = AUTHENTICODE_VFY_WRONG_PKCS7_TYPE;
|
||||
goto end;
|
||||
}
|
||||
@ -567,7 +569,8 @@ AuthenticodeArray* parse_authenticode(const uint8_t* pe_data, uint64_t pe_len)
|
||||
uint32_t dwLength = letoh32(*(uint32_t*)(pe_data + cert_addr));
|
||||
if (pe_len < cert_addr + dwLength)
|
||||
return NULL;
|
||||
/* dwLength = offsetof(WIN_CERTIFICATE, bCertificate) + (size of the variable-length binary array contained within bCertificate) */
|
||||
/* dwLength = offsetof(WIN_CERTIFICATE, bCertificate) + (size of the variable-length binary
|
||||
* array contained within bCertificate) */
|
||||
AuthenticodeArray* auth_array = authenticode_new(pe_data + cert_addr + 0x8, dwLength - 0x8);
|
||||
if (!auth_array)
|
||||
return NULL;
|
||||
|
5
deps/authenticode-parser/src/certificate.c
vendored
5
deps/authenticode-parser/src/certificate.c
vendored
@ -24,6 +24,7 @@ SOFTWARE.
|
||||
#include <openssl/asn1.h>
|
||||
#include <openssl/crypto.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/opensslv.h>
|
||||
#include <openssl/sha.h>
|
||||
#include <openssl/x509.h>
|
||||
#include <string.h>
|
||||
@ -308,8 +309,8 @@ Certificate* certificate_new(X509* x509)
|
||||
|
||||
result->version = X509_get_version(x509);
|
||||
result->serial = integer_to_serial(X509_get_serialNumber(x509));
|
||||
result->not_after = ASN1_TIME_to_time_t(X509_get0_notAfter(x509));
|
||||
result->not_before = ASN1_TIME_to_time_t(X509_get0_notBefore(x509));
|
||||
result->not_after = ASN1_TIME_to_int64_t(X509_get0_notAfter(x509));
|
||||
result->not_before = ASN1_TIME_to_int64_t(X509_get0_notBefore(x509));
|
||||
int sig_nid = X509_get_signature_nid(x509);
|
||||
result->sig_alg = strdup(OBJ_nid2ln(sig_nid));
|
||||
|
||||
|
369
deps/authenticode-parser/src/countersignature.c
vendored
369
deps/authenticode-parser/src/countersignature.c
vendored
@ -21,8 +21,11 @@ SOFTWARE.
|
||||
|
||||
#include "countersignature.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <openssl/cms.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/objects.h>
|
||||
#include <openssl/opensslv.h>
|
||||
#include <openssl/ossl_typ.h>
|
||||
#include <openssl/pkcs7.h>
|
||||
#include <openssl/safestack.h>
|
||||
@ -36,6 +39,73 @@ SOFTWARE.
|
||||
#include "helper.h"
|
||||
#include "structs.h"
|
||||
|
||||
struct CountersignatureImplStruct;
|
||||
|
||||
typedef TS_TST_INFO* get_ts_tst_info_func(struct CountersignatureImplStruct*);
|
||||
typedef STACK_OF(X509) * get_signers_func(struct CountersignatureImplStruct*);
|
||||
typedef STACK_OF(X509) * get_certs_func(struct CountersignatureImplStruct*);
|
||||
typedef int
|
||||
verify_digest_func(struct CountersignatureImplStruct*, uint8_t* digest, size_t digest_size);
|
||||
typedef BIO* verify_signature_init_func(struct CountersignatureImplStruct*);
|
||||
typedef int
|
||||
verify_signature_finish_func(struct CountersignatureImplStruct*, BIO* bio, X509* signer);
|
||||
|
||||
#define IMPL_FUNC_NAME(func, type) ms_countersig_impl_##func##_##type##_
|
||||
|
||||
#define DECLARE_FUNCS(type) \
|
||||
get_ts_tst_info_func IMPL_FUNC_NAME(get_ts_tst_info, type); \
|
||||
get_signers_func IMPL_FUNC_NAME(get_signers, type); \
|
||||
get_certs_func IMPL_FUNC_NAME(get_certs, type); \
|
||||
verify_digest_func IMPL_FUNC_NAME(verify_digest, type); \
|
||||
verify_signature_init_func IMPL_FUNC_NAME(verify_signature_init, type); \
|
||||
verify_signature_finish_func IMPL_FUNC_NAME(verify_signature_finish, type);
|
||||
|
||||
DECLARE_FUNCS(pkcs7)
|
||||
DECLARE_FUNCS(cms)
|
||||
|
||||
typedef struct {
|
||||
get_ts_tst_info_func* get_ts_tst_info;
|
||||
get_signers_func* get_signers;
|
||||
get_certs_func* get_certs;
|
||||
verify_digest_func* verify_digest;
|
||||
verify_signature_init_func* verify_signature_init;
|
||||
verify_signature_finish_func* verify_signature_finish;
|
||||
} CountersignatureImplFuncs;
|
||||
|
||||
#define FUNC_ARRAY_NAME_FOR_IMPL(type) countersig_impl_funcs_##type##_
|
||||
#define FUNC_ARRAY_FOR_IMPL(type) \
|
||||
static const CountersignatureImplFuncs FUNC_ARRAY_NAME_FOR_IMPL(type) = { \
|
||||
&IMPL_FUNC_NAME(get_ts_tst_info, type), \
|
||||
&IMPL_FUNC_NAME(get_signers, type), \
|
||||
&IMPL_FUNC_NAME(get_certs, type), \
|
||||
&IMPL_FUNC_NAME(verify_digest, type), \
|
||||
&IMPL_FUNC_NAME(verify_signature_init, type), \
|
||||
&IMPL_FUNC_NAME(verify_signature_finish, type), \
|
||||
};
|
||||
|
||||
FUNC_ARRAY_FOR_IMPL(pkcs7)
|
||||
FUNC_ARRAY_FOR_IMPL(cms)
|
||||
|
||||
typedef enum {
|
||||
CS_IMPL_PKCS7,
|
||||
CS_IMPL_CMS,
|
||||
} CountersignatureImplType;
|
||||
|
||||
typedef struct CountersignatureImplStruct {
|
||||
CountersignatureImplType type;
|
||||
const CountersignatureImplFuncs* funcs;
|
||||
union {
|
||||
PKCS7* pkcs7;
|
||||
CMS_ContentInfo* cms;
|
||||
};
|
||||
// this is here to serve as a cache for CMS because the only way to obtain
|
||||
// certs from CMS is to use CMS_get1_certs which leaves the deallocation
|
||||
// to the caller but it just complicates things if you need to remember to
|
||||
// deallocate also certs. This makes it easier if CountersignatureImpl itself
|
||||
// is an owner of this thing.
|
||||
STACK_OF(X509) * _certs;
|
||||
} CountersignatureImpl;
|
||||
|
||||
Countersignature* pkcs9_countersig_new(
|
||||
const uint8_t* data, long size, STACK_OF(X509) * certs, ASN1_STRING* enc_digest)
|
||||
{
|
||||
@ -58,7 +128,7 @@ Countersignature* pkcs9_countersig_new(
|
||||
goto end;
|
||||
}
|
||||
|
||||
result->sign_time = ASN1_TIME_to_time_t(sign_time->value.utctime);
|
||||
result->sign_time = ASN1_TIME_to_int64_t(sign_time->value.utctime);
|
||||
|
||||
X509* signCert = X509_find_by_issuer_and_serial(
|
||||
certs, si->issuer_and_serial->issuer, si->issuer_and_serial->serial);
|
||||
@ -133,7 +203,7 @@ Countersignature* pkcs9_countersig_new(
|
||||
|
||||
/* compare the encrypted digest and calculated digest */
|
||||
bool isValid = false;
|
||||
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x3000000fL
|
||||
size_t mdLen = EVP_MD_get_size(md);
|
||||
#else
|
||||
@ -178,22 +248,264 @@ end:
|
||||
return result;
|
||||
}
|
||||
|
||||
TS_TST_INFO* IMPL_FUNC_NAME(get_ts_tst_info, pkcs7)(CountersignatureImpl* impl)
|
||||
{
|
||||
assert(impl->type == CS_IMPL_PKCS7);
|
||||
|
||||
return PKCS7_to_TS_TST_INFO(impl->pkcs7);
|
||||
}
|
||||
|
||||
TS_TST_INFO* IMPL_FUNC_NAME(get_ts_tst_info, cms)(CountersignatureImpl* impl)
|
||||
{
|
||||
assert(impl->type == CS_IMPL_CMS);
|
||||
|
||||
const ASN1_OBJECT* content_type = CMS_get0_eContentType(impl->cms);
|
||||
if (!content_type || OBJ_obj2nid(content_type) != NID_id_smime_ct_TSTInfo) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ASN1_OCTET_STRING** content = CMS_get0_content(impl->cms);
|
||||
if (!content || !*content) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const uint8_t* data = (*content)->data;
|
||||
TS_TST_INFO* ts_tst_info = d2i_TS_TST_INFO(NULL, &data, (*content)->length);
|
||||
if (!ts_tst_info) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return ts_tst_info;
|
||||
}
|
||||
|
||||
STACK_OF(X509) * IMPL_FUNC_NAME(get_signers, pkcs7)(CountersignatureImpl* impl)
|
||||
{
|
||||
assert(impl->type == CS_IMPL_PKCS7);
|
||||
|
||||
return PKCS7_get0_signers(impl->pkcs7, impl->pkcs7->d.sign->cert, 0);
|
||||
}
|
||||
|
||||
STACK_OF(X509) * IMPL_FUNC_NAME(get_signers, cms)(CountersignatureImpl* impl)
|
||||
{
|
||||
assert(impl->type == CS_IMPL_CMS);
|
||||
|
||||
STACK_OF(CMS_SignerInfo)* signer_infos = CMS_get0_SignerInfos(impl->cms);
|
||||
if (!signer_infos) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Use our func points to cache the certs and don't create another copy
|
||||
STACK_OF(X509)* certs = impl->funcs->get_certs(impl);
|
||||
|
||||
int si_count = sk_CMS_SignerInfo_num(signer_infos);
|
||||
int cert_count = certs ? sk_X509_num(certs) : 0;
|
||||
STACK_OF(X509)* result = sk_X509_new_null();
|
||||
|
||||
// PKCS7_get0_signers() lets us specify the certificate array and looks up signer certificate
|
||||
// there With CMS_ContentInfo, we don't have direct access to signer certificate, just all the
|
||||
// certificates The only thing we can do is to go through all signer infos and find those which
|
||||
// match some certificate in all certificates. It essentially simulates what
|
||||
// PKCS7_get0_signers() does.
|
||||
for (int i = 0; i < si_count; ++i) {
|
||||
CMS_SignerInfo* si = sk_CMS_SignerInfo_value(signer_infos, i);
|
||||
if (!si) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (certs) {
|
||||
for (int j = 0; j < cert_count; ++j) {
|
||||
X509* cert = sk_X509_value(certs, j);
|
||||
if (!cert) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (CMS_SignerInfo_cert_cmp(si, cert) == 0) {
|
||||
if (!sk_X509_push(result, cert)) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
STACK_OF(X509) * IMPL_FUNC_NAME(get_certs, pkcs7)(CountersignatureImpl* impl)
|
||||
{
|
||||
assert(impl->type == CS_IMPL_PKCS7);
|
||||
|
||||
return impl->pkcs7->d.sign->cert;
|
||||
}
|
||||
|
||||
STACK_OF(X509) * IMPL_FUNC_NAME(get_certs, cms)(CountersignatureImpl* impl)
|
||||
{
|
||||
assert(impl->type == CS_IMPL_CMS);
|
||||
|
||||
if (impl->_certs) {
|
||||
return impl->_certs;
|
||||
}
|
||||
|
||||
impl->_certs = CMS_get1_certs(impl->cms);
|
||||
return impl->_certs;
|
||||
}
|
||||
|
||||
int IMPL_FUNC_NAME(verify_digest, pkcs7)(
|
||||
CountersignatureImpl* impl, uint8_t* digest, size_t digest_size)
|
||||
{
|
||||
assert(impl->type == CS_IMPL_PKCS7);
|
||||
|
||||
X509_STORE* store = X509_STORE_new();
|
||||
TS_VERIFY_CTX* ctx = TS_VERIFY_CTX_new();
|
||||
TS_VERIFY_CTX_init(ctx);
|
||||
|
||||
TS_VERIFY_CTX_set_flags(ctx, TS_VFY_VERSION | TS_VFY_IMPRINT);
|
||||
TS_VERIFY_CTX_set_store(ctx, store);
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x3000000fL
|
||||
TS_VERIFY_CTX_set_certs(ctx, impl->funcs->get_certs(impl));
|
||||
#else
|
||||
TS_VERIFY_CTS_set_certs(ctx, impl->funcs->get_certs(impl));
|
||||
#endif
|
||||
TS_VERIFY_CTX_set_imprint(ctx, digest, digest_size);
|
||||
|
||||
int result = TS_RESP_verify_token(ctx, impl->pkcs7);
|
||||
|
||||
X509_STORE_free(store);
|
||||
OPENSSL_free(ctx);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int IMPL_FUNC_NAME(verify_digest, cms)(
|
||||
CountersignatureImpl* impl, uint8_t* digest, size_t digest_size)
|
||||
{
|
||||
assert(impl->type == CS_IMPL_CMS);
|
||||
|
||||
// This is essentially just reimplementation of TS_RESP_verify_token() from OpenSSL
|
||||
TS_TST_INFO* ts_tst_info = impl->funcs->get_ts_tst_info(impl);
|
||||
if (!ts_tst_info || TS_TST_INFO_get_version(ts_tst_info) != 1) {
|
||||
if (ts_tst_info)
|
||||
TS_TST_INFO_free(ts_tst_info);
|
||||
return 0;
|
||||
}
|
||||
|
||||
TS_MSG_IMPRINT* ts_imprint = TS_TST_INFO_get_msg_imprint(ts_tst_info);
|
||||
if (!ts_imprint) {
|
||||
TS_TST_INFO_free(ts_tst_info);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ASN1_OCTET_STRING* ts_imprint_digest = TS_MSG_IMPRINT_get_msg(ts_imprint);
|
||||
if (!ts_imprint_digest) {
|
||||
TS_TST_INFO_free(ts_tst_info);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ts_imprint_digest->length != (int)digest_size ||
|
||||
memcmp(ts_imprint_digest->data, digest, digest_size) != 0) {
|
||||
TS_TST_INFO_free(ts_tst_info);
|
||||
return 0;
|
||||
}
|
||||
|
||||
TS_TST_INFO_free(ts_tst_info);
|
||||
return 1;
|
||||
}
|
||||
|
||||
BIO* IMPL_FUNC_NAME(verify_signature_init, pkcs7)(CountersignatureImpl* impl)
|
||||
{
|
||||
assert(impl->type == CS_IMPL_PKCS7);
|
||||
|
||||
return PKCS7_dataInit(impl->pkcs7, NULL);
|
||||
}
|
||||
|
||||
BIO* IMPL_FUNC_NAME(verify_signature_init, cms)(CountersignatureImpl* impl)
|
||||
{
|
||||
assert(impl->type == CS_IMPL_CMS);
|
||||
|
||||
return CMS_dataInit(impl->cms, NULL);
|
||||
}
|
||||
|
||||
int IMPL_FUNC_NAME(verify_signature_finish, pkcs7)(
|
||||
CountersignatureImpl* impl, BIO* bio, X509* signer)
|
||||
{
|
||||
assert(impl->type == CS_IMPL_PKCS7);
|
||||
|
||||
/* Verify signature with PKCS7_signatureVerify
|
||||
because TS_RESP_verify_token would try to verify
|
||||
chain and without trust anchors it always fails */
|
||||
PKCS7_SIGNER_INFO* si = sk_PKCS7_SIGNER_INFO_value(PKCS7_get_signer_info(impl->pkcs7), 0);
|
||||
return PKCS7_signatureVerify(bio, impl->pkcs7, si, signer);
|
||||
}
|
||||
|
||||
int IMPL_FUNC_NAME(verify_signature_finish, cms)(CountersignatureImpl* impl, BIO* bio, X509* signer)
|
||||
{
|
||||
assert(impl->type == CS_IMPL_CMS);
|
||||
|
||||
(void)signer;
|
||||
CMS_SignerInfo* si = sk_CMS_SignerInfo_value(CMS_get0_SignerInfos(impl->cms), 0);
|
||||
return CMS_SignerInfo_verify_content(si, bio);
|
||||
}
|
||||
|
||||
CountersignatureImpl* ms_countersig_impl_new(const uint8_t* data, long size)
|
||||
{
|
||||
const uint8_t* d = data;
|
||||
PKCS7* p7 = d2i_PKCS7(NULL, &d, size);
|
||||
if (p7 && PKCS7_type_is_signed(p7) && p7->d.sign) {
|
||||
CountersignatureImpl* result =
|
||||
(CountersignatureImpl*)calloc(1, sizeof(CountersignatureImpl));
|
||||
result->type = CS_IMPL_PKCS7;
|
||||
result->funcs = &FUNC_ARRAY_NAME_FOR_IMPL(pkcs7);
|
||||
result->pkcs7 = p7;
|
||||
return result;
|
||||
}
|
||||
|
||||
d = data;
|
||||
CMS_ContentInfo* cms = d2i_CMS_ContentInfo(NULL, &d, size);
|
||||
if (cms) {
|
||||
CountersignatureImpl* result =
|
||||
(CountersignatureImpl*)calloc(1, sizeof(CountersignatureImpl));
|
||||
result->type = CS_IMPL_CMS;
|
||||
result->funcs = &FUNC_ARRAY_NAME_FOR_IMPL(cms);
|
||||
result->cms = cms;
|
||||
return result;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void ms_countersig_impl_free(CountersignatureImpl* impl)
|
||||
{
|
||||
switch (impl->type) {
|
||||
case CS_IMPL_PKCS7:
|
||||
PKCS7_free(impl->pkcs7);
|
||||
break;
|
||||
case CS_IMPL_CMS:
|
||||
if (impl->_certs) {
|
||||
sk_X509_pop_free(impl->_certs, X509_free);
|
||||
}
|
||||
CMS_ContentInfo_free(impl->cms);
|
||||
break;
|
||||
}
|
||||
|
||||
free(impl);
|
||||
}
|
||||
|
||||
Countersignature* ms_countersig_new(const uint8_t* data, long size, ASN1_STRING* enc_digest)
|
||||
{
|
||||
Countersignature* result = (Countersignature*)calloc(1, sizeof(*result));
|
||||
if (!result)
|
||||
return NULL;
|
||||
|
||||
PKCS7* p7 = d2i_PKCS7(NULL, &data, size);
|
||||
if (!p7) {
|
||||
CountersignatureImpl* impl = ms_countersig_impl_new(data, size);
|
||||
if (!impl) {
|
||||
result->verify_flags = COUNTERSIGNATURE_VFY_CANT_PARSE;
|
||||
return result;
|
||||
}
|
||||
|
||||
TS_TST_INFO* ts = PKCS7_to_TS_TST_INFO(p7);
|
||||
TS_TST_INFO* ts = impl->funcs->get_ts_tst_info(impl);
|
||||
if (!ts) {
|
||||
result->verify_flags = COUNTERSIGNATURE_VFY_CANT_PARSE;
|
||||
PKCS7_free(p7);
|
||||
ms_countersig_impl_free(impl);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -201,20 +513,21 @@ Countersignature* ms_countersig_new(const uint8_t* data, long size, ASN1_STRING*
|
||||
if (!rawTime) {
|
||||
result->verify_flags = COUNTERSIGNATURE_VFY_TIME_MISSING;
|
||||
TS_TST_INFO_free(ts);
|
||||
PKCS7_free(p7);
|
||||
ms_countersig_impl_free(impl);
|
||||
return result;
|
||||
}
|
||||
|
||||
result->sign_time = ASN1_TIME_to_time_t(rawTime);
|
||||
result->sign_time = ASN1_TIME_to_int64_t(rawTime);
|
||||
|
||||
STACK_OF(X509)* sigs = PKCS7_get0_signers(p7, p7->d.sign->cert, 0);
|
||||
STACK_OF(X509)* sigs = impl->funcs->get_signers(impl);
|
||||
X509* signCert = sk_X509_value(sigs, 0);
|
||||
if (!signCert) {
|
||||
result->verify_flags = COUNTERSIGNATURE_VFY_NO_SIGNER_CERT;
|
||||
goto end;
|
||||
}
|
||||
|
||||
result->chain = parse_signer_chain(signCert, p7->d.sign->cert);
|
||||
STACK_OF(X509)* certs = impl->funcs->get_certs(impl);
|
||||
result->chain = parse_signer_chain(signCert, certs);
|
||||
|
||||
/* Imprint == digest */
|
||||
TS_MSG_IMPRINT* imprint = TS_TST_INFO_get_msg_imprint(ts);
|
||||
@ -259,52 +572,30 @@ Countersignature* ms_countersig_new(const uint8_t* data, long size, ASN1_STRING*
|
||||
goto end;
|
||||
}
|
||||
|
||||
TS_VERIFY_CTX* ctx = TS_VERIFY_CTX_new();
|
||||
X509_STORE* store = X509_STORE_new();
|
||||
TS_VERIFY_CTX_init(ctx);
|
||||
|
||||
TS_VERIFY_CTX_set_flags(ctx, TS_VFY_VERSION | TS_VFY_IMPRINT);
|
||||
TS_VERIFY_CTX_set_store(ctx, store);
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x3000000fL
|
||||
TS_VERIFY_CTX_set_certs(ctx, p7->d.sign->cert);
|
||||
#else
|
||||
TS_VERIFY_CTS_set_certs(ctx, p7->d.sign->cert);
|
||||
#endif
|
||||
TS_VERIFY_CTX_set_imprint(ctx, calc_digest, mdLen);
|
||||
|
||||
bool isValid = TS_RESP_verify_token(ctx, p7) == 1;
|
||||
|
||||
X509_STORE_free(store);
|
||||
OPENSSL_free(ctx);
|
||||
|
||||
bool isValid = impl->funcs->verify_digest(impl, calc_digest, mdLen) == 1;
|
||||
if (!isValid) {
|
||||
result->verify_flags = COUNTERSIGNATURE_VFY_INVALID;
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* Verify signature with PKCS7_signatureVerify
|
||||
because TS_RESP_verify_token would try to verify
|
||||
chain and without trust anchors it always fails */
|
||||
BIO* p7bio = PKCS7_dataInit(p7, NULL);
|
||||
BIO* bio = impl->funcs->verify_signature_init(impl);
|
||||
|
||||
char buf[4096];
|
||||
/* We now have to 'read' from p7bio to calculate digests etc. */
|
||||
while (BIO_read(p7bio, buf, sizeof(buf)) > 0)
|
||||
/* We now have to 'read' from bio to calculate digests etc. */
|
||||
while (BIO_read(bio, buf, sizeof(buf)) > 0)
|
||||
continue;
|
||||
|
||||
PKCS7_SIGNER_INFO* si = sk_PKCS7_SIGNER_INFO_value(PKCS7_get_signer_info(p7), 0);
|
||||
isValid = impl->funcs->verify_signature_finish(impl, bio, signCert) == 1;
|
||||
|
||||
isValid = PKCS7_signatureVerify(p7bio, p7, si, signCert) == 1;
|
||||
|
||||
BIO_free_all(p7bio);
|
||||
BIO_free_all(bio);
|
||||
|
||||
if (!isValid)
|
||||
result->verify_flags = COUNTERSIGNATURE_VFY_INVALID;
|
||||
|
||||
end:
|
||||
sk_X509_free(sigs);
|
||||
PKCS7_free(p7);
|
||||
TS_TST_INFO_free(ts);
|
||||
ms_countersig_impl_free(impl);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
2
deps/authenticode-parser/src/helper.c
vendored
2
deps/authenticode-parser/src/helper.c
vendored
@ -73,7 +73,7 @@ int byte_array_init(ByteArray* arr, const uint8_t* data, int len)
|
||||
return 0;
|
||||
}
|
||||
|
||||
time_t ASN1_TIME_to_time_t(const ASN1_TIME* time)
|
||||
int64_t ASN1_TIME_to_int64_t(const ASN1_TIME* time)
|
||||
{
|
||||
struct tm t = {0};
|
||||
if (!time)
|
||||
|
2
deps/authenticode-parser/src/helper.h
vendored
2
deps/authenticode-parser/src/helper.h
vendored
@ -59,7 +59,7 @@ int calculate_digest(const EVP_MD* md, const uint8_t* data, size_t len, uint8_t*
|
||||
/* Copies data of length len into already existing arr */
|
||||
int byte_array_init(ByteArray* arr, const uint8_t* data, int len);
|
||||
/* Converts ASN1_TIME string time into a unix timestamp */
|
||||
time_t ASN1_TIME_to_time_t(const ASN1_TIME* time);
|
||||
int64_t ASN1_TIME_to_int64_t(const ASN1_TIME* time);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user