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:
parent
036b3f331b
commit
961092281f
4
CHANGES
4
CHANGES
@ -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]
|
||||||
|
130
apps/apps.c
130
apps/apps.c
@ -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 */
|
||||||
|
@ -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);
|
||||||
|
100
apps/verify.c
100
apps/verify.c
@ -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);
|
||||||
|
Loading…
Reference in New Issue
Block a user