Add option to allow in-band CRL loading in verify utility. Add function

load_crls and tidy up load_certs. Remove useless purpose variable from
verify utility: now done with args_verify.
This commit is contained in:
Dr. Stephen Henson 2009-10-31 13:34:19 +00:00
parent 036b3f331b
commit 961092281f
4 changed files with 129 additions and 107 deletions

View File

@ -4,6 +4,10 @@
Changes between 0.9.8k and 1.0 [xx XXX xxxx] Changes between 0.9.8k and 1.0 [xx XXX xxxx]
*) Add load_crls() function to apps tidying load_certs() too. Add option
to verify utility to allow additional CRLs to be included.
[Steve Henson]
*) Update OCSP request code to permit adding custom headers to the request: *) Update OCSP request code to permit adding custom headers to the request:
some responders need this. some responders need this.
[Steve Henson] [Steve Henson]

View File

@ -1095,76 +1095,120 @@ error:
} }
#endif /* ndef OPENSSL_NO_RC4 */ #endif /* ndef OPENSSL_NO_RC4 */
STACK_OF(X509) *load_certs(BIO *err, const char *file, int format, static int load_certs_crls(BIO *err, const char *file, int format,
const char *pass, ENGINE *e, const char *cert_descrip) const char *pass, ENGINE *e, const char *desc,
STACK_OF(X509) **pcerts, STACK_OF(X509_CRL) **pcrls)
{ {
BIO *certs;
int i; int i;
STACK_OF(X509) *othercerts = NULL; BIO *bio;
STACK_OF(X509_INFO) *allcerts = NULL; STACK_OF(X509_INFO) *xis = NULL;
X509_INFO *xi; X509_INFO *xi;
PW_CB_DATA cb_data; PW_CB_DATA cb_data;
int rv = 0;
cb_data.password = pass; cb_data.password = pass;
cb_data.prompt_info = file; cb_data.prompt_info = file;
if((certs = BIO_new(BIO_s_file())) == NULL) if (format != FORMAT_PEM)
{ {
ERR_print_errors(err); BIO_printf(err,"bad input format specified for %s\n", desc);
goto end; return 0;
} }
if (file == NULL) if (file == NULL)
BIO_set_fp(certs,stdin,BIO_NOCLOSE); bio = BIO_new_fp(stdin,BIO_NOCLOSE);
else else
bio = BIO_new_file(file, "r");
if (bio == NULL)
{ {
if (BIO_read_filename(certs,file) <= 0) BIO_printf(err, "Error opening %s %s\n",
{ desc, file ? file : "stdin");
BIO_printf(err, "Error opening %s %s\n", ERR_print_errors(err);
cert_descrip, file); return 0;
ERR_print_errors(err); }
xis = PEM_X509_INFO_read_bio(bio, NULL,
(pem_password_cb *)password_callback, &cb_data);
BIO_free(bio);
if (pcerts)
{
*pcerts = sk_X509_new_null();
if (!*pcerts)
goto end; goto end;
}
if (pcrls)
{
*pcrls = sk_X509_CRL_new_null();
if (!*pcrls)
goto end;
}
for(i = 0; i < sk_X509_INFO_num(xis); i++)
{
xi = sk_X509_INFO_value (xis, i);
if (xi->x509 && pcerts)
{
if (!sk_X509_push(*pcerts, xi->x509))
goto end;
xi->x509 = NULL;
}
if (xi->crl && pcrls)
{
if (!sk_X509_CRL_push(*pcrls, xi->crl))
goto end;
xi->crl = NULL;
} }
} }
if (format == FORMAT_PEM) if (pcerts && sk_X509_num(*pcerts) > 0)
rv = 1;
if (pcrls && sk_X509_CRL_num(*pcrls) > 0)
rv = 1;
end:
if (xis)
sk_X509_INFO_pop_free(xis, X509_INFO_free);
if (rv == 0)
{ {
othercerts = sk_X509_new_null(); if (pcerts)
if(!othercerts)
{ {
sk_X509_free(othercerts); sk_X509_pop_free(*pcerts, X509_free);
othercerts = NULL; *pcerts = NULL;
goto end;
} }
allcerts = PEM_X509_INFO_read_bio(certs, NULL, if (pcrls)
(pem_password_cb *)password_callback, &cb_data);
for(i = 0; i < sk_X509_INFO_num(allcerts); i++)
{ {
xi = sk_X509_INFO_value (allcerts, i); sk_X509_CRL_pop_free(*pcrls, X509_CRL_free);
if (xi->x509) *pcrls = NULL;
{
sk_X509_push(othercerts, xi->x509);
xi->x509 = NULL;
}
} }
goto end; BIO_printf(err,"unable to load %s\n",
} pcerts ? "certificates" : "CRLs");
else {
BIO_printf(err,"bad input format specified for %s\n",
cert_descrip);
goto end;
}
end:
if (othercerts == NULL)
{
BIO_printf(err,"unable to load certificates\n");
ERR_print_errors(err); ERR_print_errors(err);
} }
if (allcerts) sk_X509_INFO_pop_free(allcerts, X509_INFO_free); return rv;
if (certs != NULL) BIO_free(certs);
return(othercerts);
} }
STACK_OF(X509) *load_certs(BIO *err, const char *file, int format,
const char *pass, ENGINE *e, const char *desc)
{
STACK_OF(X509) *certs;
load_certs_crls(err, file, format, pass, e, desc, &certs, NULL);
return certs;
}
STACK_OF(X509_CRL) *load_crls(BIO *err, const char *file, int format,
const char *pass, ENGINE *e, const char *desc)
{
STACK_OF(X509_CRL) *crls;
load_certs_crls(err, file, format, pass, e, desc, NULL, &crls);
return crls;
}
#define X509V3_EXT_UNKNOWN_MASK (0xfL << 16) #define X509V3_EXT_UNKNOWN_MASK (0xfL << 16)
/* Return error for unknown extensions */ /* Return error for unknown extensions */

View File

@ -251,6 +251,8 @@ EVP_PKEY *load_pubkey(BIO *err, const char *file, int format, int maybe_stdin,
const char *pass, ENGINE *e, const char *key_descrip); const char *pass, ENGINE *e, const char *key_descrip);
STACK_OF(X509) *load_certs(BIO *err, const char *file, int format, STACK_OF(X509) *load_certs(BIO *err, const char *file, int format,
const char *pass, ENGINE *e, const char *cert_descrip); const char *pass, ENGINE *e, const char *cert_descrip);
STACK_OF(X509_CRL) *load_crls(BIO *err, const char *file, int format,
const char *pass, ENGINE *e, const char *cert_descrip);
X509_STORE *setup_verify(BIO *bp, char *CAfile, char *CApath); X509_STORE *setup_verify(BIO *bp, char *CAfile, char *CApath);
#ifndef OPENSSL_NO_ENGINE #ifndef OPENSSL_NO_ENGINE
ENGINE *setup_engine(BIO *err, const char *engine, int debug); ENGINE *setup_engine(BIO *err, const char *engine, int debug);

View File

@ -70,8 +70,9 @@
#define PROG verify_main #define PROG verify_main
static int MS_CALLBACK cb(int ok, X509_STORE_CTX *ctx); static int MS_CALLBACK cb(int ok, X509_STORE_CTX *ctx);
static int check(X509_STORE *ctx, char *file, STACK_OF(X509) *uchain, STACK_OF(X509) *tchain, int purpose, ENGINE *e); static int check(X509_STORE *ctx, char *file,
static STACK_OF(X509) *load_untrusted(char *file); STACK_OF(X509) *uchain, STACK_OF(X509) *tchain,
STACK_OF(X509_CRL) *crls, ENGINE *e);
static int v_verbose=0, vflags = 0; static int v_verbose=0, vflags = 0;
int MAIN(int, char **); int MAIN(int, char **);
@ -80,10 +81,10 @@ int MAIN(int argc, char **argv)
{ {
ENGINE *e = NULL; ENGINE *e = NULL;
int i,ret=1, badarg = 0; int i,ret=1, badarg = 0;
int purpose = -1;
char *CApath=NULL,*CAfile=NULL; char *CApath=NULL,*CAfile=NULL;
char *untfile = NULL, *trustfile = NULL; char *untfile = NULL, *trustfile = NULL, *crlfile = NULL;
STACK_OF(X509) *untrusted = NULL, *trusted = NULL; STACK_OF(X509) *untrusted = NULL, *trusted = NULL;
STACK_OF(X509_CRL) *crls = NULL;
X509_STORE *cert_ctx=NULL; X509_STORE *cert_ctx=NULL;
X509_LOOKUP *lookup=NULL; X509_LOOKUP *lookup=NULL;
X509_VERIFY_PARAM *vpm = NULL; X509_VERIFY_PARAM *vpm = NULL;
@ -139,6 +140,11 @@ int MAIN(int argc, char **argv)
if (argc-- < 1) goto end; if (argc-- < 1) goto end;
trustfile= *(++argv); trustfile= *(++argv);
} }
else if (strcmp(*argv,"-CRLfile") == 0)
{
if (argc-- < 1) goto end;
crlfile= *(++argv);
}
#ifndef OPENSSL_NO_ENGINE #ifndef OPENSSL_NO_ENGINE
else if (strcmp(*argv,"-engine") == 0) else if (strcmp(*argv,"-engine") == 0)
{ {
@ -192,26 +198,34 @@ int MAIN(int argc, char **argv)
ERR_clear_error(); ERR_clear_error();
if(untfile) { if(untfile)
if(!(untrusted = load_untrusted(untfile))) { {
BIO_printf(bio_err, "Error loading untrusted file %s\n", untfile); untrusted = load_certs(bio_err, untfile, FORMAT_PEM,
ERR_print_errors(bio_err); NULL, e, "untrusted certificates");
if(!untrusted)
goto end; goto end;
} }
}
if(trustfile) { if(trustfile)
if(!(trusted = load_untrusted(trustfile))) { {
BIO_printf(bio_err, "Error loading untrusted file %s\n", trustfile); trusted = load_certs(bio_err, trustfile, FORMAT_PEM,
ERR_print_errors(bio_err); NULL, e, "trusted certificates");
if(!trusted)
goto end; goto end;
} }
}
if (argc < 1) check(cert_ctx, NULL, untrusted, trusted, purpose, e); if(crlfile)
{
crls = load_crls(bio_err, crlfile, FORMAT_PEM,
NULL, e, "other CRLs");
if(!crls)
goto end;
}
if (argc < 1) check(cert_ctx, NULL, untrusted, trusted, crls, e);
else else
for (i=0; i<argc; i++) for (i=0; i<argc; i++)
check(cert_ctx,argv[i], untrusted, trusted, purpose, e); check(cert_ctx,argv[i], untrusted, trusted, crls, e);
ret=0; ret=0;
end: end:
if (ret == 1) { if (ret == 1) {
@ -232,11 +246,14 @@ end:
if (cert_ctx != NULL) X509_STORE_free(cert_ctx); if (cert_ctx != NULL) X509_STORE_free(cert_ctx);
sk_X509_pop_free(untrusted, X509_free); sk_X509_pop_free(untrusted, X509_free);
sk_X509_pop_free(trusted, X509_free); sk_X509_pop_free(trusted, X509_free);
sk_X509_CRL_pop_free(crls, X509_CRL_free);
apps_shutdown(); apps_shutdown();
OPENSSL_EXIT(ret); OPENSSL_EXIT(ret);
} }
static int check(X509_STORE *ctx, char *file, STACK_OF(X509) *uchain, STACK_OF(X509) *tchain, int purpose, ENGINE *e) static int check(X509_STORE *ctx, char *file,
STACK_OF(X509) *uchain, STACK_OF(X509) *tchain,
STACK_OF(X509_CRL) *crls, ENGINE *e)
{ {
X509 *x=NULL; X509 *x=NULL;
int i=0,ret=0; int i=0,ret=0;
@ -260,7 +277,8 @@ static int check(X509_STORE *ctx, char *file, STACK_OF(X509) *uchain, STACK_OF(X
goto end; goto end;
} }
if(tchain) X509_STORE_CTX_trusted_stack(csc, tchain); if(tchain) X509_STORE_CTX_trusted_stack(csc, tchain);
if(purpose >= 0) X509_STORE_CTX_set_purpose(csc, purpose); if (crls)
X509_STORE_CTX_set0_crls(csc, crls);
i=X509_verify_cert(csc); i=X509_verify_cert(csc);
X509_STORE_CTX_free(csc); X509_STORE_CTX_free(csc);
@ -278,52 +296,6 @@ end:
return(ret); return(ret);
} }
static STACK_OF(X509) *load_untrusted(char *certfile)
{
STACK_OF(X509_INFO) *sk=NULL;
STACK_OF(X509) *stack=NULL, *ret=NULL;
BIO *in=NULL;
X509_INFO *xi;
if(!(stack = sk_X509_new_null())) {
BIO_printf(bio_err,"memory allocation failure\n");
goto end;
}
if(!(in=BIO_new_file(certfile, "r"))) {
BIO_printf(bio_err,"error opening the file, %s\n",certfile);
goto end;
}
/* This loads from a file, a stack of x509/crl/pkey sets */
if(!(sk=PEM_X509_INFO_read_bio(in,NULL,NULL,NULL))) {
BIO_printf(bio_err,"error reading the file, %s\n",certfile);
goto end;
}
/* scan over it and pull out the certs */
while (sk_X509_INFO_num(sk))
{
xi=sk_X509_INFO_shift(sk);
if (xi->x509 != NULL)
{
sk_X509_push(stack,xi->x509);
xi->x509=NULL;
}
X509_INFO_free(xi);
}
if(!sk_X509_num(stack)) {
BIO_printf(bio_err,"no certificates in file, %s\n",certfile);
sk_X509_free(stack);
goto end;
}
ret=stack;
end:
BIO_free(in);
sk_X509_INFO_free(sk);
return(ret);
}
static int MS_CALLBACK cb(int ok, X509_STORE_CTX *ctx) static int MS_CALLBACK cb(int ok, X509_STORE_CTX *ctx)
{ {
int cert_error = X509_STORE_CTX_get_error(ctx); int cert_error = X509_STORE_CTX_get_error(ctx);