mirror of
https://github.com/mtrojnar/osslsigncode.git
synced 2025-04-19 06:08:05 -05:00
PKCS9_SEQUENCE_NUMBER authenticated attribute support
This commit is contained in:
parent
0985c47990
commit
44ca1f38e6
1
NEWS.md
1
NEWS.md
@ -10,6 +10,7 @@
|
|||||||
- added CAT file verification and listing each member of the CAT file
|
- added CAT file verification and listing each member of the CAT file
|
||||||
by using the "-verbose" option
|
by using the "-verbose" option
|
||||||
- added new command "extract-data" to extract a PKCS#7 data content to be signed
|
- added new command "extract-data" to extract a PKCS#7 data content to be signed
|
||||||
|
- PKCS9_SEQUENCE_NUMBER authenticated attribute support
|
||||||
|
|
||||||
### 2.7 (2023.09.19)
|
### 2.7 (2023.09.19)
|
||||||
|
|
||||||
|
6
cab.c
6
cab.c
@ -506,6 +506,12 @@ static PKCS7 *cab_pkcs7_prepare(FILE_FORMAT_CTX *ctx, BIO *hash, BIO *outdata)
|
|||||||
printf("Unable to extract existing signature\n");
|
printf("Unable to extract existing signature\n");
|
||||||
return NULL; /* FAILED */
|
return NULL; /* FAILED */
|
||||||
}
|
}
|
||||||
|
ctx->options->nested_number = nested_signatures_number_get(cursig);
|
||||||
|
if (ctx->options->nested_number < 0) {
|
||||||
|
printf("Unable to get number of nested signatures\n");
|
||||||
|
PKCS7_free(cursig);
|
||||||
|
return NULL; /* FAILED */
|
||||||
|
}
|
||||||
if (ctx->options->cmd == CMD_ADD)
|
if (ctx->options->cmd == CMD_ADD)
|
||||||
p7 = cursig;
|
p7 = cursig;
|
||||||
}
|
}
|
||||||
|
55
helpers.c
55
helpers.c
@ -14,6 +14,7 @@ static int spc_indirect_data_content_create(u_char **blob, int *len, FILE_FORMAT
|
|||||||
static int pkcs7_signer_info_add_spc_sp_opus_info(PKCS7_SIGNER_INFO *si, FILE_FORMAT_CTX *ctx);
|
static int pkcs7_signer_info_add_spc_sp_opus_info(PKCS7_SIGNER_INFO *si, FILE_FORMAT_CTX *ctx);
|
||||||
static int pkcs7_signer_info_add_signing_time(PKCS7_SIGNER_INFO *si, FILE_FORMAT_CTX *ctx);
|
static int pkcs7_signer_info_add_signing_time(PKCS7_SIGNER_INFO *si, FILE_FORMAT_CTX *ctx);
|
||||||
static int pkcs7_signer_info_add_purpose(PKCS7_SIGNER_INFO *si, FILE_FORMAT_CTX *ctx);
|
static int pkcs7_signer_info_add_purpose(PKCS7_SIGNER_INFO *si, FILE_FORMAT_CTX *ctx);
|
||||||
|
static int pkcs7_signer_info_add_sequence_number(PKCS7_SIGNER_INFO *si, FILE_FORMAT_CTX *ctx);
|
||||||
static STACK_OF(X509) *X509_chain_get_sorted(FILE_FORMAT_CTX *ctx, int signer);
|
static STACK_OF(X509) *X509_chain_get_sorted(FILE_FORMAT_CTX *ctx, int signer);
|
||||||
static int X509_compare(const X509 *const *a, const X509 *const *b);
|
static int X509_compare(const X509 *const *a, const X509 *const *b);
|
||||||
|
|
||||||
@ -237,6 +238,10 @@ PKCS7 *pkcs7_create(FILE_FORMAT_CTX *ctx)
|
|||||||
printf("Couldn't allocate memory for opus info\n");
|
printf("Couldn't allocate memory for opus info\n");
|
||||||
return NULL; /* FAILED */
|
return NULL; /* FAILED */
|
||||||
}
|
}
|
||||||
|
if ((ctx->options->nested_number >= 0) &&
|
||||||
|
!pkcs7_signer_info_add_sequence_number(si, ctx)) {
|
||||||
|
return NULL; /* FAILED */
|
||||||
|
}
|
||||||
/* 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) {
|
||||||
@ -719,6 +724,25 @@ static int pkcs7_signer_info_add_purpose(PKCS7_SIGNER_INFO *si, FILE_FORMAT_CTX
|
|||||||
V_ASN1_SEQUENCE, purpose);
|
V_ASN1_SEQUENCE, purpose);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* [in, out] si: PKCS7_SIGNER_INFO structure
|
||||||
|
* [in] ctx: structure holds input and output data
|
||||||
|
* [returns] 0 on error or 1 on success
|
||||||
|
*/
|
||||||
|
static int pkcs7_signer_info_add_sequence_number(PKCS7_SIGNER_INFO *si, FILE_FORMAT_CTX *ctx)
|
||||||
|
{
|
||||||
|
ASN1_INTEGER *number = ASN1_INTEGER_new();
|
||||||
|
|
||||||
|
if (!number)
|
||||||
|
return 0; /* FAILED */
|
||||||
|
if (!ASN1_INTEGER_set(number, ctx->options->nested_number + 1)) {
|
||||||
|
ASN1_INTEGER_free(number);
|
||||||
|
return 0; /* FAILED */
|
||||||
|
}
|
||||||
|
return PKCS7_add_signed_attribute(si, OBJ_txt2nid(PKCS9_SEQUENCE_NUMBER),
|
||||||
|
V_ASN1_INTEGER, number);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Create certificate chain sorted in ascending order by their DER encoding.
|
* Create certificate chain sorted in ascending order by their DER encoding.
|
||||||
* [in] ctx: structure holds input and output data
|
* [in] ctx: structure holds input and output data
|
||||||
@ -794,6 +818,37 @@ static int X509_compare(const X509 *const *a, const X509 *const *b)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return the number of objects in SPC_NESTED_SIGNATURE_OBJID attribute
|
||||||
|
* [in] p7: existing PKCS#7 signature (Primary Signature)
|
||||||
|
* [returns] -1 on error or the number of nested signatures
|
||||||
|
*/
|
||||||
|
int nested_signatures_number_get(PKCS7 *p7)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
STACK_OF(X509_ATTRIBUTE) *unauth_attr;
|
||||||
|
PKCS7_SIGNER_INFO *si;
|
||||||
|
STACK_OF(PKCS7_SIGNER_INFO) *signer_info = PKCS7_get_signer_info(p7);
|
||||||
|
|
||||||
|
if (!signer_info)
|
||||||
|
return -1; /* FAILED */
|
||||||
|
si = sk_PKCS7_SIGNER_INFO_value(signer_info, 0);
|
||||||
|
if (!si)
|
||||||
|
return -1; /* FAILED */
|
||||||
|
unauth_attr = PKCS7_get_attributes(si); /* cont[1] */
|
||||||
|
if (!unauth_attr)
|
||||||
|
return 0; /* OK, no unauthenticated attributes */
|
||||||
|
for (i=0; i<X509at_get_attr_count(unauth_attr); i++) {
|
||||||
|
int nid = OBJ_txt2nid(SPC_NESTED_SIGNATURE_OBJID);
|
||||||
|
X509_ATTRIBUTE *attr = X509at_get_attr(unauth_attr, i);
|
||||||
|
if (OBJ_obj2nid(X509_ATTRIBUTE_get0_object(attr)) == nid) {
|
||||||
|
/* Nested Signature - Policy OID: 1.3.6.1.4.1.311.2.4.1 */
|
||||||
|
return X509_ATTRIBUTE_count(attr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0; /* OK, no SPC_NESTED_SIGNATURE_OBJID attribute */
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Local Variables:
|
Local Variables:
|
||||||
c-basic-offset: 4
|
c-basic-offset: 4
|
||||||
|
@ -26,6 +26,7 @@ MsCtlContent *ms_ctl_content_get(PKCS7 *p7);
|
|||||||
ASN1_TYPE *catalog_content_get(CatalogAuthAttr *attribute);
|
ASN1_TYPE *catalog_content_get(CatalogAuthAttr *attribute);
|
||||||
SpcLink *spc_link_obsolete_get(void);
|
SpcLink *spc_link_obsolete_get(void);
|
||||||
int compare_digests(u_char *mdbuf, u_char *cmdbuf, int mdtype);
|
int compare_digests(u_char *mdbuf, u_char *cmdbuf, int mdtype);
|
||||||
|
int nested_signatures_number_get(PKCS7 *p7);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Local Variables:
|
Local Variables:
|
||||||
|
6
msi.c
6
msi.c
@ -676,6 +676,12 @@ static PKCS7 *msi_pkcs7_prepare(FILE_FORMAT_CTX *ctx, BIO *hash, BIO *outdata)
|
|||||||
PKCS7_free(cursig);
|
PKCS7_free(cursig);
|
||||||
return NULL; /* FAILED */
|
return NULL; /* FAILED */
|
||||||
}
|
}
|
||||||
|
ctx->options->nested_number = nested_signatures_number_get(cursig);
|
||||||
|
if (ctx->options->nested_number < 0) {
|
||||||
|
printf("Unable to get number of nested signatures\n");
|
||||||
|
PKCS7_free(cursig);
|
||||||
|
return NULL; /* FAILED */
|
||||||
|
}
|
||||||
if (ctx->options->cmd == CMD_ADD)
|
if (ctx->options->cmd == CMD_ADD)
|
||||||
p7 = cursig;
|
p7 = cursig;
|
||||||
}
|
}
|
||||||
|
@ -2037,8 +2037,10 @@ static time_t time_t_timestamp_get_attributes(CMS_ContentInfo **timestamp, PKCS7
|
|||||||
md_nid = OBJ_obj2nid(si->digest_alg->algorithm);
|
md_nid = OBJ_obj2nid(si->digest_alg->algorithm);
|
||||||
printf("Message digest algorithm: %s\n",
|
printf("Message digest algorithm: %s\n",
|
||||||
(md_nid == NID_undef) ? "UNKNOWN" : OBJ_nid2sn(md_nid));
|
(md_nid == NID_undef) ? "UNKNOWN" : OBJ_nid2sn(md_nid));
|
||||||
printf("\nAuthenticated attributes:\n");
|
|
||||||
|
/* Unauthenticated attributes */
|
||||||
auth_attr = PKCS7_get_signed_attributes(si); /* cont[0] */
|
auth_attr = PKCS7_get_signed_attributes(si); /* cont[0] */
|
||||||
|
printf("\nAuthenticated attributes:\n");
|
||||||
for (i=0; i<X509at_get_attr_count(auth_attr); i++) {
|
for (i=0; i<X509at_get_attr_count(auth_attr); i++) {
|
||||||
attr = X509at_get_attr(auth_attr, i);
|
attr = X509at_get_attr(auth_attr, i);
|
||||||
object = X509_ATTRIBUTE_get0_object(attr);
|
object = X509_ATTRIBUTE_get0_object(attr);
|
||||||
@ -2121,6 +2123,12 @@ static time_t time_t_timestamp_get_attributes(CMS_ContentInfo **timestamp, PKCS7
|
|||||||
printf("\tLow level of permissions in Microsoft Internet Explorer 4.x for CAB files\n");
|
printf("\tLow level of permissions in Microsoft Internet Explorer 4.x for CAB files\n");
|
||||||
else
|
else
|
||||||
printf("\tUnrecognized level of permissions in Microsoft Internet Explorer 4.x for CAB files\n");
|
printf("\tUnrecognized level of permissions in Microsoft Internet Explorer 4.x for CAB files\n");
|
||||||
|
} else if (!strcmp(object_txt, PKCS9_SEQUENCE_NUMBER)) {
|
||||||
|
/* PKCS#9 sequence number - Policy OID: 1.2.840.113549.1.9.25.4 */
|
||||||
|
ASN1_INTEGER *number = X509_ATTRIBUTE_get0_data(attr, 0, V_ASN1_INTEGER, NULL);
|
||||||
|
if (number == NULL)
|
||||||
|
continue;
|
||||||
|
printf("\tSequence number: %ld\n", ASN1_INTEGER_get(number));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2247,15 +2255,13 @@ static time_t time_t_get_si_time(PKCS7_SIGNER_INFO *si)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get signing time from authenticated attributes
|
* Get signing time from authenticated attributes cont[0]
|
||||||
* [in] si: PKCS7_SIGNER_INFO structure
|
* [in] si: PKCS7_SIGNER_INFO structure
|
||||||
* [returns] NULL on error or ASN1_UTCTIME on success
|
* [returns] NULL on error or ASN1_UTCTIME on success
|
||||||
*/
|
*/
|
||||||
static ASN1_UTCTIME *asn1_time_get_si_time(PKCS7_SIGNER_INFO *si)
|
static ASN1_UTCTIME *asn1_time_get_si_time(PKCS7_SIGNER_INFO *si)
|
||||||
{
|
{
|
||||||
STACK_OF(X509_ATTRIBUTE) *auth_attr;
|
STACK_OF(X509_ATTRIBUTE) *auth_attr = PKCS7_get_signed_attributes(si);
|
||||||
|
|
||||||
auth_attr = PKCS7_get_signed_attributes(si); /* cont[0] */
|
|
||||||
if (auth_attr) {
|
if (auth_attr) {
|
||||||
int i;
|
int i;
|
||||||
for (i=0; i<X509at_get_attr_count(auth_attr); i++) {
|
for (i=0; i<X509at_get_attr_count(auth_attr); i++) {
|
||||||
@ -2270,6 +2276,28 @@ static ASN1_UTCTIME *asn1_time_get_si_time(PKCS7_SIGNER_INFO *si)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get sequence number from authenticated attributes cont[0]
|
||||||
|
* [in] si: PKCS7_SIGNER_INFO structure
|
||||||
|
* [returns] NULL on error or ASN1_UTCTIME on success
|
||||||
|
*/
|
||||||
|
static long get_sequence_number(PKCS7_SIGNER_INFO *si)
|
||||||
|
{
|
||||||
|
STACK_OF(X509_ATTRIBUTE) *auth_attr = PKCS7_get_signed_attributes(si);
|
||||||
|
if (auth_attr) {
|
||||||
|
int i;
|
||||||
|
for (i=0; i<X509at_get_attr_count(auth_attr); i++) {
|
||||||
|
int nid = OBJ_txt2nid(PKCS9_SEQUENCE_NUMBER);
|
||||||
|
X509_ATTRIBUTE *attr = X509at_get_attr(auth_attr, i);
|
||||||
|
if (OBJ_obj2nid(X509_ATTRIBUTE_get0_object(attr)) == nid) {
|
||||||
|
/* PKCS#9 sequence number - Policy OID:1.2.840.113549.1.9.25.4 */
|
||||||
|
return ASN1_INTEGER_get(X509_ATTRIBUTE_get0_data(attr, 0, V_ASN1_INTEGER, NULL));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get timestamping time from embedded content in a CMS_ContentInfo structure
|
* Get timestamping time from embedded content in a CMS_ContentInfo structure
|
||||||
* [in] si: CMS_ContentInfo structure
|
* [in] si: CMS_ContentInfo structure
|
||||||
@ -2701,6 +2729,7 @@ static int PKCS7_compare(const PKCS7 *const *a, const PKCS7 *const *b)
|
|||||||
STACK_OF(PKCS7_SIGNER_INFO) *signer_info;
|
STACK_OF(PKCS7_SIGNER_INFO) *signer_info;
|
||||||
PKCS7_SIGNER_INFO *si;
|
PKCS7_SIGNER_INFO *si;
|
||||||
const ASN1_TIME *time_a, *time_b;
|
const ASN1_TIME *time_a, *time_b;
|
||||||
|
long index_a, index_b;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
p7_a = PKCS7_dup(*a);
|
p7_a = PKCS7_dup(*a);
|
||||||
@ -2713,6 +2742,7 @@ static int PKCS7_compare(const PKCS7 *const *a, const PKCS7 *const *b)
|
|||||||
if (!si)
|
if (!si)
|
||||||
goto out;
|
goto out;
|
||||||
time_a = asn1_time_get_si_time(si);
|
time_a = asn1_time_get_si_time(si);
|
||||||
|
index_a = get_sequence_number(si);
|
||||||
|
|
||||||
p7_b = PKCS7_dup(*b);
|
p7_b = PKCS7_dup(*b);
|
||||||
if (!p7_b)
|
if (!p7_b)
|
||||||
@ -2724,7 +2754,12 @@ static int PKCS7_compare(const PKCS7 *const *a, const PKCS7 *const *b)
|
|||||||
if (!si)
|
if (!si)
|
||||||
goto out;
|
goto out;
|
||||||
time_b = asn1_time_get_si_time(si);
|
time_b = asn1_time_get_si_time(si);
|
||||||
ret = ASN1_TIME_compare(time_b, time_a);
|
index_b = get_sequence_number(si);
|
||||||
|
|
||||||
|
if (index_a == index_b)
|
||||||
|
ret = ASN1_TIME_compare(time_a, time_b);
|
||||||
|
else
|
||||||
|
ret = (index_a == 0 || index_a < index_b) ? 1 : -1;
|
||||||
|
|
||||||
out:
|
out:
|
||||||
PKCS7_free(p7_a);
|
PKCS7_free(p7_a);
|
||||||
@ -3811,6 +3846,7 @@ static int main_configure(int argc, char **argv, GLOBAL_OPTIONS *options)
|
|||||||
options->time = INVALID_TIME;
|
options->time = INVALID_TIME;
|
||||||
options->jp = -1;
|
options->jp = -1;
|
||||||
options->index = -1;
|
options->index = -1;
|
||||||
|
options->nested_number = -1;
|
||||||
#if OPENSSL_VERSION_NUMBER>=0x30000000L
|
#if OPENSSL_VERSION_NUMBER>=0x30000000L
|
||||||
/* Use legacy PKCS#12 container with RC2-40-CBC private key and certificate encryption algorithm */
|
/* Use legacy PKCS#12 container with RC2-40-CBC private key and certificate encryption algorithm */
|
||||||
options->legacy = 1;
|
options->legacy = 1;
|
||||||
@ -4194,7 +4230,8 @@ int main(int argc, char **argv)
|
|||||||
|| !OBJ_create(SPC_SP_OPUS_INFO_OBJID, NULL, NULL)
|
|| !OBJ_create(SPC_SP_OPUS_INFO_OBJID, NULL, NULL)
|
||||||
|| !OBJ_create(SPC_NESTED_SIGNATURE_OBJID, NULL, NULL)
|
|| !OBJ_create(SPC_NESTED_SIGNATURE_OBJID, NULL, NULL)
|
||||||
|| !OBJ_create(SPC_UNAUTHENTICATED_DATA_BLOB_OBJID, NULL, NULL)
|
|| !OBJ_create(SPC_UNAUTHENTICATED_DATA_BLOB_OBJID, NULL, NULL)
|
||||||
|| !OBJ_create(SPC_RFC3161_OBJID, NULL, NULL))
|
|| !OBJ_create(SPC_RFC3161_OBJID, NULL, NULL)
|
||||||
|
|| !OBJ_create(PKCS9_SEQUENCE_NUMBER, NULL, NULL))
|
||||||
DO_EXIT_0("Failed to create objects\n");
|
DO_EXIT_0("Failed to create objects\n");
|
||||||
|
|
||||||
/* commands and options initialization */
|
/* commands and options initialization */
|
||||||
|
@ -187,6 +187,7 @@
|
|||||||
#define PKCS9_MESSAGE_DIGEST "1.2.840.113549.1.9.4"
|
#define PKCS9_MESSAGE_DIGEST "1.2.840.113549.1.9.4"
|
||||||
#define PKCS9_SIGNING_TIME "1.2.840.113549.1.9.5"
|
#define PKCS9_SIGNING_TIME "1.2.840.113549.1.9.5"
|
||||||
#define PKCS9_COUNTER_SIGNATURE "1.2.840.113549.1.9.6"
|
#define PKCS9_COUNTER_SIGNATURE "1.2.840.113549.1.9.6"
|
||||||
|
#define PKCS9_SEQUENCE_NUMBER "1.2.840.113549.1.9.25.4"
|
||||||
|
|
||||||
/* WIN_CERTIFICATE structure declared in Wintrust.h */
|
/* WIN_CERTIFICATE structure declared in Wintrust.h */
|
||||||
#define WIN_CERT_REVISION_2_0 0x0200
|
#define WIN_CERT_REVISION_2_0 0x0200
|
||||||
@ -291,6 +292,7 @@ typedef struct {
|
|||||||
char *tsa_certfile;
|
char *tsa_certfile;
|
||||||
char *tsa_keyfile;
|
char *tsa_keyfile;
|
||||||
time_t tsa_time;
|
time_t tsa_time;
|
||||||
|
int nested_number;
|
||||||
} GLOBAL_OPTIONS;
|
} GLOBAL_OPTIONS;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
6
pe.c
6
pe.c
@ -423,6 +423,12 @@ static PKCS7 *pe_pkcs7_prepare(FILE_FORMAT_CTX *ctx, BIO *hash, BIO *outdata)
|
|||||||
printf("Unable to extract existing signature\n");
|
printf("Unable to extract existing signature\n");
|
||||||
return NULL; /* FAILED */
|
return NULL; /* FAILED */
|
||||||
}
|
}
|
||||||
|
ctx->options->nested_number = nested_signatures_number_get(cursig);
|
||||||
|
if (ctx->options->nested_number < 0) {
|
||||||
|
printf("Unable to get number of nested signatures\n");
|
||||||
|
PKCS7_free(cursig);
|
||||||
|
return NULL; /* FAILED */
|
||||||
|
}
|
||||||
if (ctx->options->cmd == CMD_ADD)
|
if (ctx->options->cmd == CMD_ADD)
|
||||||
p7 = cursig;
|
p7 = cursig;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user