additional CRLs (supplied as part of a PKCS#7 structure) support

This commit is contained in:
olszomal 2020-09-30 12:09:25 +02:00 committed by Michał Trojnara
parent 0bb54d9f51
commit fe028d12f4

View File

@ -276,6 +276,7 @@ typedef struct {
X509 *cert; X509 *cert;
STACK_OF(X509) *certs; STACK_OF(X509) *certs;
STACK_OF(X509) *xcerts; STACK_OF(X509) *xcerts;
STACK_OF(X509_CRL) *crls;
} CRYPTO_PARAMS; } CRYPTO_PARAMS;
#ifdef WITH_GSF #ifdef WITH_GSF
@ -1868,7 +1869,7 @@ static int load_crlfile_lookup(X509_STORE *store, char *certs, char *crl)
printf("\nError: no certificate found\n"); printf("\nError: no certificate found\n");
return 0; /* FAILED */ return 0; /* FAILED */
} }
if (!X509_load_crl_file(lookup, crl, X509_FILETYPE_PEM)) { if (crl && !X509_load_crl_file(lookup, crl, X509_FILETYPE_PEM)) {
printf("\nError: no CRL found in %s\n", crl); printf("\nError: no CRL found in %s\n", crl);
return 0; /* FAILED */ return 0; /* FAILED */
} }
@ -2287,7 +2288,8 @@ out:
return url; return url;
} }
static int verify_crl(char *ca_file, char *crl_file, X509 *signer, STACK_OF(X509) *chain) static int verify_crl(char *ca_file, char *crl_file, STACK_OF(X509_CRL) *crls,
X509 *signer, STACK_OF(X509) *chain)
{ {
X509_STORE *store = NULL; X509_STORE *store = NULL;
X509_STORE_CTX *ctx = NULL; X509_STORE_CTX *ctx = NULL;
@ -2306,6 +2308,10 @@ static int verify_crl(char *ca_file, char *crl_file, X509 *signer, STACK_OF(X509
if (!X509_STORE_CTX_init(ctx, store, signer, chain)) if (!X509_STORE_CTX_init(ctx, store, signer, chain))
goto out; goto out;
/* set an additional CRLs */
if (crls)
X509_STORE_CTX_set0_crls(ctx, crls);
if (X509_verify_cert(ctx) <= 0) { if (X509_verify_cert(ctx) <= 0) {
int error = X509_STORE_CTX_get_error(ctx); int error = X509_STORE_CTX_get_error(ctx);
printf("\nX509_verify_cert: certificate verify error: %s\n", printf("\nX509_verify_cert: certificate verify error: %s\n",
@ -2329,6 +2335,7 @@ static int verify_timestamp(SIGNATURE *signature, GLOBAL_OPTIONS *options)
STACK_OF(CMS_SignerInfo) *sinfos; STACK_OF(CMS_SignerInfo) *sinfos;
CMS_SignerInfo *cmssi; CMS_SignerInfo *cmssi;
X509 *signer; X509 *signer;
STACK_OF(X509_CRL) *crls;
char *url; char *url;
PKCS7_SIGNER_INFO *si; PKCS7_SIGNER_INFO *si;
int verok = 0; int verok = 0;
@ -2377,9 +2384,10 @@ static int verify_timestamp(SIGNATURE *signature, GLOBAL_OPTIONS *options)
printf("\n"); printf("\n");
/* verify a Certificate Revocation List */ /* verify a Certificate Revocation List */
if (options->crluntrusted) { crls = signature->p7->d.sign->crl;
if (options->crluntrusted || crls) {
STACK_OF(X509) *chain = CMS_get1_certs(signature->timestamp); STACK_OF(X509) *chain = CMS_get1_certs(signature->timestamp);
int crlok = verify_crl(options->untrusted, options->crluntrusted, signer, chain); int crlok = verify_crl(options->untrusted, options->crluntrusted, crls, signer, chain);
sk_X509_pop_free(chain, X509_free); sk_X509_pop_free(chain, X509_free);
printf("Timestamp Server Signature CRL verification: %s\n", crlok ? "ok" : "failed"); printf("Timestamp Server Signature CRL verification: %s\n", crlok ? "ok" : "failed");
if (!crlok) if (!crlok)
@ -2408,6 +2416,7 @@ out:
static int verify_authenticode(SIGNATURE *signature, GLOBAL_OPTIONS *options, X509 *signer) static int verify_authenticode(SIGNATURE *signature, GLOBAL_OPTIONS *options, X509 *signer)
{ {
X509_STORE *store; X509_STORE *store;
STACK_OF(X509_CRL) *crls;
size_t seqhdrlen; size_t seqhdrlen;
BIO *bio = NULL; BIO *bio = NULL;
int verok = 0; int verok = 0;
@ -2441,9 +2450,10 @@ static int verify_authenticode(SIGNATURE *signature, GLOBAL_OPTIONS *options, X5
BIO_free(bio); BIO_free(bio);
/* verify a Certificate Revocation List */ /* verify a Certificate Revocation List */
if (options->crlfile) { crls = signature->p7->d.sign->crl;
if (options->crlfile || crls) {
STACK_OF(X509) *chain = signature->p7->d.sign->cert; STACK_OF(X509) *chain = signature->p7->d.sign->cert;
int crlok = verify_crl(options->cafile, options->crlfile, signer, chain); int crlok = verify_crl(options->cafile, options->crlfile, crls, signer, chain);
printf("Signature CRL verification: %s\n", crlok ? "ok" : "failed"); printf("Signature CRL verification: %s\n", crlok ? "ok" : "failed");
if (!crlok) if (!crlok)
goto out; goto out;
@ -3147,7 +3157,7 @@ static int msi_check_MsiDigitalSignatureEx(GsfInfile *ole, const EVP_MD *md)
unsigned long dselen = 0; unsigned long dselen = 0;
int mdlen, has_dse = 0; int mdlen, has_dse = 0;
if (!msi_extract_dse(ole, NULL, &dselen, &has_dse) != 0 && has_dse) { if (!msi_extract_dse(ole, NULL, &dselen, &has_dse) && has_dse) {
printf("Unable to extract MsiDigitalSignatureEx section\n\n"); printf("Unable to extract MsiDigitalSignatureEx section\n\n");
return 0; /* FAILED */ return 0; /* FAILED */
} }
@ -4235,6 +4245,12 @@ static PKCS7 *create_new_signature(file_type_t type,
for (i = sk_X509_num(cparams->certs)-1; i>=0; i--) for (i = sk_X509_num(cparams->certs)-1; i>=0; i--)
PKCS7_add_certificate(sig, sk_X509_value(cparams->certs, i)); PKCS7_add_certificate(sig, sk_X509_value(cparams->certs, i));
/* add crls */
if (cparams->crls) {
for (i=0; i<sk_X509_CRL_num(cparams->crls); i++)
PKCS7_add_crl(sig, sk_X509_CRL_value(cparams->crls, i));
}
return sig; /* OK */ return sig; /* OK */
} }
@ -4662,15 +4678,35 @@ out:
return ret; return ret;
} }
/* Obtain a copy of the whole X509_CRL chain */
STACK_OF(X509_CRL) *X509_CRL_chain_up_ref(STACK_OF(X509_CRL) *chain)
{
STACK_OF(X509_CRL) *ret;
int i;
ret = sk_X509_CRL_dup(chain);
if (ret == NULL)
return NULL;
for (i = 0; i < sk_X509_CRL_num(ret); i++) {
X509_CRL *x = sk_X509_CRL_value(ret, i);
if (!X509_CRL_up_ref(x))
goto err;
}
return ret;
err:
while (i-- > 0)
X509_CRL_free(sk_X509_CRL_value(ret, i));
sk_X509_CRL_free(ret);
return NULL;
}
/* /*
* Load certificates from a file. * Load certificates from a file.
* If successful all certificates will be written to cparams->certs. * If successful all certificates will be written to cparams->certs
* and optional CRLs will be written to cparams->crls.
*/ */
static int read_certfile(GLOBAL_OPTIONS *options, CRYPTO_PARAMS *cparams) static int read_certfile(GLOBAL_OPTIONS *options, CRYPTO_PARAMS *cparams)
{ {
BIO *btmp; BIO *btmp;
PKCS7 *p7;
X509 *x = NULL;
int ret = 0; int ret = 0;
btmp = BIO_new_file(options->certfile, "rb"); btmp = BIO_new_file(options->certfile, "rb");
@ -4683,6 +4719,7 @@ static int read_certfile(GLOBAL_OPTIONS *options, CRYPTO_PARAMS *cparams)
/* .der certificate file */ /* .der certificate file */
if (!cparams->certs) { if (!cparams->certs) {
X509 *x = NULL;
(void)BIO_seek(btmp, 0); (void)BIO_seek(btmp, 0);
if (d2i_X509_bio(btmp, &x)) { if (d2i_X509_bio(btmp, &x)) {
cparams->certs = sk_X509_new_null(); cparams->certs = sk_X509_new_null();
@ -4696,11 +4733,15 @@ static int read_certfile(GLOBAL_OPTIONS *options, CRYPTO_PARAMS *cparams)
/* .spc or .p7b certificate file (PKCS#7 structure) */ /* .spc or .p7b certificate file (PKCS#7 structure) */
if (!cparams->certs) { if (!cparams->certs) {
PKCS7 *p7;
(void)BIO_seek(btmp, 0); (void)BIO_seek(btmp, 0);
p7 = d2i_PKCS7_bio(btmp, NULL); p7 = d2i_PKCS7_bio(btmp, NULL);
if (!p7) if (!p7)
goto out; /* FAILED */ goto out; /* FAILED */
cparams->certs = X509_chain_up_ref(p7->d.sign->cert); cparams->certs = X509_chain_up_ref(p7->d.sign->cert);
/* additional CRLs may be supplied as part of a PKCS#7 signed data structure */
cparams->crls = X509_CRL_chain_up_ref(p7->d.sign->crl);
PKCS7_free(p7); PKCS7_free(p7);
} }