New options to the -verify program which can be used for chain verification.

Extend the X509_PURPOSE structure to include shortnames for purposed and default
trust ids.

Still need some extendable trust checking code and integration with the SSL and
S/MIME code.
This commit is contained in:
Dr. Stephen Henson
1999-11-26 00:27:07 +00:00
parent 1126239111
commit d4cec6a13d
17 changed files with 290 additions and 112 deletions

View File

@@ -727,11 +727,12 @@ spkac.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h apps.h progs.h
verify.o: ../include/openssl/asn1.h ../include/openssl/bio.h
verify.o: ../include/openssl/blowfish.h ../include/openssl/bn.h
verify.o: ../include/openssl/buffer.h ../include/openssl/cast.h
verify.o: ../include/openssl/crypto.h ../include/openssl/des.h
verify.o: ../include/openssl/dh.h ../include/openssl/dsa.h
verify.o: ../include/openssl/e_os.h ../include/openssl/e_os2.h
verify.o: ../include/openssl/err.h ../include/openssl/evp.h
verify.o: ../include/openssl/idea.h ../include/openssl/md2.h
verify.o: ../include/openssl/conf.h ../include/openssl/crypto.h
verify.o: ../include/openssl/des.h ../include/openssl/dh.h
verify.o: ../include/openssl/dsa.h ../include/openssl/e_os.h
verify.o: ../include/openssl/e_os2.h ../include/openssl/err.h
verify.o: ../include/openssl/evp.h ../include/openssl/idea.h
verify.o: ../include/openssl/lhash.h ../include/openssl/md2.h
verify.o: ../include/openssl/md5.h ../include/openssl/mdc2.h
verify.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
verify.o: ../include/openssl/opensslv.h ../include/openssl/pem.h
@@ -740,8 +741,8 @@ verify.o: ../include/openssl/rc2.h ../include/openssl/rc4.h
verify.o: ../include/openssl/rc5.h ../include/openssl/ripemd.h
verify.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
verify.o: ../include/openssl/sha.h ../include/openssl/stack.h
verify.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h apps.h
verify.o: progs.h
verify.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
verify.o: ../include/openssl/x509v3.h apps.h progs.h
version.o: ../include/openssl/asn1.h ../include/openssl/bio.h
version.o: ../include/openssl/blowfish.h ../include/openssl/bn.h
version.o: ../include/openssl/buffer.h ../include/openssl/cast.h

View File

@@ -287,13 +287,14 @@ int MAIN(int argc, char **argv)
PKCS8_PRIV_KEY_INFO *p8;
PKCS7 *authsafe;
X509 *ucert = NULL;
STACK_OF(X509) *certs;
STACK_OF(X509) *certs=NULL;
char *catmp;
int i;
unsigned char keyid[EVP_MAX_MD_SIZE];
unsigned int keyidlen = 0;
key = PEM_read_bio_PrivateKey(inkey ? inkey : in, NULL, NULL, NULL);
if (!inkey) (void) BIO_reset(in);
else BIO_free(inkey);
if (!key) {
BIO_printf (bio_err, "Error loading private key\n");
ERR_print_errors(bio_err);
@@ -364,7 +365,7 @@ int MAIN(int argc, char **argv)
PKCS12_add_friendlyname(bag, catmp, -1);
sk_push(bags, (char *)bag);
}
sk_X509_pop_free(certs, X509_free);
if (canames) sk_free(canames);
if(!noprompt &&

View File

@@ -63,22 +63,29 @@
#include <openssl/bio.h>
#include <openssl/err.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>
#include <openssl/pem.h>
#undef PROG
#define PROG verify_main
static int MS_CALLBACK cb(int ok, X509_STORE_CTX *ctx);
static int check(X509_STORE *ctx,char *file);
static int check(X509_STORE *ctx,char *file, STACK_OF(X509)*other, int purpose);
static STACK_OF(X509) *load_untrusted(char *file);
static int v_verbose=0;
int MAIN(int argc, char **argv)
{
int i,ret=1;
int purpose = -1;
char *CApath=NULL,*CAfile=NULL;
char *untfile = NULL;
STACK_OF(X509) *untrusted = NULL;
X509_STORE *cert_ctx=NULL;
X509_LOOKUP *lookup=NULL;
X509_PURPOSE_add_standard();
X509V3_add_standard_extensions();
cert_ctx=X509_STORE_new();
if (cert_ctx == NULL) goto end;
X509_STORE_set_verify_cb_func(cert_ctx,cb);
@@ -107,6 +114,24 @@ int MAIN(int argc, char **argv)
if (argc-- < 1) goto end;
CAfile= *(++argv);
}
else if (strcmp(*argv,"-purpose") == 0)
{
X509_PURPOSE *xptmp;
if (argc-- < 1) goto end;
i = X509_PURPOSE_get_by_sname(*(++argv));
if(i < 0)
{
BIO_printf(bio_err, "unrecognised purpose\n");
goto end;
}
xptmp = X509_PURPOSE_iget(i);
purpose = X509_PURPOSE_get_id(xptmp);
}
else if (strcmp(*argv,"-untrusted") == 0)
{
if (argc-- < 1) goto end;
untfile= *(++argv);
}
else if (strcmp(*argv,"-help") == 0)
goto end;
else if (strcmp(*argv,"-verbose") == 0)
@@ -144,26 +169,45 @@ int MAIN(int argc, char **argv)
}
} else X509_LOOKUP_add_dir(lookup,NULL,X509_FILETYPE_DEFAULT);
ERR_clear_error();
if (argc < 1) check(cert_ctx,NULL);
if(untfile) {
if(!(untrusted = load_untrusted(untfile))) {
BIO_printf(bio_err, "Error loading untrusted file %s\n", untfile);
ERR_print_errors(bio_err);
goto end;
}
}
if (argc < 1) check(cert_ctx, NULL, untrusted, purpose);
else
for (i=0; i<argc; i++)
check(cert_ctx,argv[i]);
check(cert_ctx,argv[i], untrusted, purpose);
ret=0;
end:
if (ret == 1)
if (ret == 1) {
BIO_printf(bio_err,"usage: verify [-verbose] [-CApath path] [-CAfile file] cert1 cert2 ...\n");
BIO_printf(bio_err,"recognised usages:\n");
for(i = 0; i < X509_PURPOSE_get_count(); i++) {
X509_PURPOSE *ptmp;
ptmp = X509_PURPOSE_iget(i);
BIO_printf(bio_err, "\t%-10s\t%s\n", X509_PURPOSE_iget_sname(ptmp),
X509_PURPOSE_iget_name(ptmp));
}
}
if (cert_ctx != NULL) X509_STORE_free(cert_ctx);
sk_X509_pop_free(untrusted, X509_free);
X509V3_EXT_cleanup();
X509_PURPOSE_cleanup();
EXIT(ret);
}
static int check(X509_STORE *ctx, char *file)
static int check(X509_STORE *ctx, char *file, STACK_OF(X509) *uchain, int purpose)
{
X509 *x=NULL;
BIO *in=NULL;
int i=0,ret=0;
X509_STORE_CTX csc;
X509_STORE_CTX *csc;
in=BIO_new(BIO_s_file());
if (in == NULL)
@@ -193,9 +237,16 @@ static int check(X509_STORE *ctx, char *file)
}
fprintf(stdout,"%s: ",(file == NULL)?"stdin":file);
X509_STORE_CTX_init(&csc,ctx,x,NULL);
i=X509_verify_cert(&csc);
X509_STORE_CTX_cleanup(&csc);
csc = X509_STORE_CTX_new();
if (csc == NULL)
{
ERR_print_errors(bio_err);
goto end;
}
X509_STORE_CTX_init(csc,ctx,x,uchain);
if(purpose >= 0) X509_STORE_CTX_chain_purpose(csc, purpose);
i=X509_verify_cert(csc);
X509_STORE_CTX_free(csc);
ret=0;
end:
@@ -212,6 +263,52 @@ end:
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)
{
char buf[256];
@@ -230,6 +327,11 @@ static int MS_CALLBACK cb(int ok, X509_STORE_CTX *ctx)
* the user.
*/
if (ctx->error == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT) ok=1;
/* Continue after extension errors too */
if (ctx->error == X509_V_ERR_INVALID_CA) ok=1;
if (ctx->error == X509_V_ERR_PATH_LENGTH_EXCEEDED) ok=1;
if (ctx->error == X509_V_ERR_INVALID_PURPOSE) ok=1;
if (ctx->error == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT) ok=1;
}
if (!v_verbose)
ERR_clear_error();

View File

@@ -136,14 +136,9 @@ static int sign (X509 *x, EVP_PKEY *pkey,int days,const EVP_MD *digest,
static int x509_certify (X509_STORE *ctx,char *CAfile,const EVP_MD *digest,
X509 *x,X509 *xca,EVP_PKEY *pkey,char *serial,
int create,int days, LHASH *conf, char *section);
static int efunc(X509_PURPOSE *pt, void *arg);
static int purpose_print(BIO *bio, X509 *cert, X509_PURPOSE *pt);
static int reqfile=0;
typedef struct {
BIO *bio;
X509 *cert;
} X509_PPRINT;
int MAIN(int argc, char **argv)
{
int ret=1;
@@ -609,11 +604,14 @@ bad:
}
else if (pprint == i)
{
X509_PPRINT ptmp;
ptmp.bio = STDout;
ptmp.cert = x;
X509_PURPOSE *ptmp;
int j;
BIO_printf(STDout, "Certificate purposes:\n");
X509_PURPOSE_enum(efunc, &ptmp);
for(j = 0; j < X509_PURPOSE_get_count(); j++)
{
ptmp = X509_PURPOSE_iget(j);
purpose_print(STDout, x, ptmp);
}
}
else
if (modulus == i)
@@ -1227,20 +1225,18 @@ err:
return(0);
}
static int efunc(X509_PURPOSE *pt, void *arg)
static int purpose_print(BIO *bio, X509 *cert, X509_PURPOSE *pt)
{
X509_PPRINT *ptmp;
int id, i, idret;
char *pname;
ptmp = arg;
id = X509_PURPOSE_get_id(pt);
pname = X509_PURPOSE_get_name(pt);
pname = X509_PURPOSE_iget_name(pt);
for(i = 0; i < 2; i++) {
idret = X509_check_purpose(ptmp->cert, id, i);
BIO_printf(ptmp->bio, "%s%s : ", pname, i ? " CA" : "");
if(idret == 1) BIO_printf(ptmp->bio, "Yes\n");
else if (idret == 0) BIO_printf(ptmp->bio, "No\n");
else BIO_printf(ptmp->bio, "Yes (WARNING code=%d)\n", idret);
idret = X509_check_purpose(cert, id, i);
BIO_printf(bio, "%s%s : ", pname, i ? " CA" : "");
if(idret == 1) BIO_printf(bio, "Yes\n");
else if (idret == 0) BIO_printf(bio, "No\n");
else BIO_printf(bio, "Yes (WARNING code=%d)\n", idret);
}
return 1;
}