From bdee69f7186e1d0b94baa5179d068fc9c611faf5 Mon Sep 17 00:00:00 2001 From: "Dr. Stephen Henson" Date: Wed, 9 May 2001 00:30:39 +0000 Subject: [PATCH] Allow various X509_STORE_CTX properties to be inherited from X509_STORE. Add CRL checking options to other applications. --- CHANGES | 17 ++++++- apps/s_client.c | 9 +++- apps/s_server.c | 12 +++++ apps/smime.c | 10 +++- apps/verify.c | 2 +- crypto/x509/x509_lu.c | 23 ++++++++- crypto/x509/x509_vfy.c | 104 +++++++++++++++++++++++++---------------- crypto/x509/x509_vfy.h | 18 +++++++ 8 files changed, 148 insertions(+), 47 deletions(-) diff --git a/CHANGES b/CHANGES index 556aa5f342..e0b2838c29 100644 --- a/CHANGES +++ b/CHANGES @@ -11,6 +11,21 @@ *) applies to 0.9.6a (/0.9.6b) and 0.9.7 +) applies to 0.9.7 only + +) Add copies of X509_STORE_CTX fields and callbacks to X509_STORE + structure. These are inherited by X509_STORE_CTX when it is + initialised. This allows various defaults to be set in the + X509_STORE structure (such as flags for CRL checking and custom + purpose or trust settings) for functions which only use X509_STORE_CTX + internally such as S/MIME. + + Modify X509_STORE_CTX_purpose_inherit() so it only sets purposes and + trust settings if they are not set in X509_STORE. This allows X509_STORE + purposes and trust (in S/MIME for example) to override any set by default. + + Add command line options for CRL checking to smime, s_client and s_server + applications. + [Steve Henson] + +) Initial CRL based revocation checking. If the CRL checking flag(s) are set then the CRL is looked up in the X509_STORE structure and its validity and signature checked, then if the certificate is found @@ -3381,7 +3396,7 @@ copied!) [Bodo Moeller] - *) Bugfix: SSL_set_options ignored its parameter, only SSL_CTX_set_options + *) Bugfix: SSL_set_mode ignored its parameter, only SSL_CTX_set_mode worked. *) Fix problems with no-hmac etc. diff --git a/apps/s_client.c b/apps/s_client.c index 7c1f1338e4..bad59f6468 100644 --- a/apps/s_client.c +++ b/apps/s_client.c @@ -166,6 +166,7 @@ int MAIN(int argc, char **argv) { int off=0; SSL *con=NULL,*con2=NULL; + X509_STORE *store = NULL; int s,k,width,state=0; char *cbuf=NULL,*sbuf=NULL; int cbuf_len,cbuf_off; @@ -181,7 +182,7 @@ int MAIN(int argc, char **argv) int write_tty,read_tty,write_ssl,read_ssl,tty_on,ssl_pending; SSL_CTX *ctx=NULL; int ret=1,in_init=1,i,nbio_test=0; - int prexit = 0; + int prexit = 0, vflags = 0; SSL_METHOD *meth=NULL; BIO *sbio; char *inrand=NULL; @@ -255,6 +256,10 @@ int MAIN(int argc, char **argv) if (--argc < 1) goto bad; cert_file= *(++argv); } + else if (strcmp(*argv,"-crl_check") == 0) + vflags |= X509_V_FLAG_CRL_CHECK; + else if (strcmp(*argv,"-crl_check_all") == 0) + vflags |= X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL; else if (strcmp(*argv,"-prexit") == 0) prexit=1; else if (strcmp(*argv,"-crlf") == 0) @@ -436,6 +441,8 @@ bad: /* goto end; */ } + store = SSL_CTX_get_cert_store(ctx); + X509_STORE_set_flags(store, vflags); con=SSL_new(ctx); #ifndef OPENSSL_NO_KRB5 diff --git a/apps/s_server.c b/apps/s_server.c index cd1aa17b26..8d76c8f3fa 100644 --- a/apps/s_server.c +++ b/apps/s_server.c @@ -414,6 +414,8 @@ int MAIN(int, char **); int MAIN(int argc, char *argv[]) { + X509_STORE *store = NULL; + int vflags = 0; short port=PORT; char *CApath=NULL,*CAfile=NULL; char *context = NULL; @@ -518,6 +520,14 @@ int MAIN(int argc, char *argv[]) if (--argc < 1) goto bad; CApath= *(++argv); } + else if (strcmp(*argv,"-crl_check") == 0) + { + vflags |= X509_V_FLAG_CRL_CHECK; + } + else if (strcmp(*argv,"-crl_check") == 0) + { + vflags |= X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL; + } else if (strcmp(*argv,"-serverpref") == 0) { off|=SSL_OP_CIPHER_SERVER_PREFERENCE; } else if (strcmp(*argv,"-cipher") == 0) @@ -721,6 +731,8 @@ bad: ERR_print_errors(bio_err); /* goto end; */ } + store = SSL_CTX_get_cert_store(ctx); + X509_STORE_set_flags(store, vflags); #ifndef OPENSSL_NO_DH if (!no_dhe) diff --git a/apps/smime.c b/apps/smime.c index edc854e53b..ede9531c55 100644 --- a/apps/smime.c +++ b/apps/smime.c @@ -97,7 +97,7 @@ int MAIN(int argc, char **argv) STACK_OF(X509) *encerts = NULL, *other = NULL; BIO *in = NULL, *out = NULL, *indata = NULL; int badarg = 0; - int flags = PKCS7_DETACHED; + int flags = PKCS7_DETACHED, store_flags = 0; char *to = NULL, *from = NULL, *subject = NULL; char *CAfile = NULL, *CApath = NULL; char *passargin = NULL, *passin = NULL; @@ -150,6 +150,10 @@ int MAIN(int argc, char **argv) flags |= PKCS7_BINARY; else if (!strcmp (*args, "-nosigs")) flags |= PKCS7_NOSIGS; + else if (!strcmp (*args, "-crl_check")) + store_flags |= X509_V_FLAG_CRL_CHECK; + else if (!strcmp (*args, "-crl_check_all")) + store_flags |= X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL; else if (!strcmp(*args,"-rand")) { if (args[1]) { args++; @@ -304,6 +308,8 @@ int MAIN(int argc, char **argv) BIO_printf (bio_err, "-text include or delete text MIME headers\n"); BIO_printf (bio_err, "-CApath dir trusted certificates directory\n"); BIO_printf (bio_err, "-CAfile file trusted certificates file\n"); + BIO_printf (bio_err, "-crl_check check revocation status of signer's certificate using CRLs\n"); + BIO_printf (bio_err, "-crl_check_all check revocation status of signer's certificate chain using CRLs\n"); BIO_printf (bio_err, "-engine e use engine e, possibly a hardware device.\n"); BIO_printf (bio_err, "-passin arg input file pass phrase source\n"); BIO_printf(bio_err, "-rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR); @@ -447,8 +453,10 @@ int MAIN(int argc, char **argv) if(operation == SMIME_VERIFY) { if(!(store = setup_verify(bio_err, CAfile, CApath))) goto end; + X509_STORE_set_flags(store, store_flags); } + ret = 3; if(operation == SMIME_ENCRYPT) { diff --git a/apps/verify.c b/apps/verify.c index 08027288dc..5b9d719d9f 100644 --- a/apps/verify.c +++ b/apps/verify.c @@ -287,10 +287,10 @@ static int check(X509_STORE *ctx, char *file, STACK_OF(X509) *uchain, STACK_OF(X ERR_print_errors(bio_err); goto end; } + X509_STORE_set_flags(ctx, vflags); X509_STORE_CTX_init(csc,ctx,x,uchain); if(tchain) X509_STORE_CTX_trusted_stack(csc, tchain); if(purpose >= 0) X509_STORE_CTX_set_purpose(csc, purpose); - X509_STORE_CTX_set_flags(csc, vflags); i=X509_verify_cert(csc); X509_STORE_CTX_free(csc); diff --git a/crypto/x509/x509_lu.c b/crypto/x509/x509_lu.c index 863c738cad..fe9fbca315 100644 --- a/crypto/x509/x509_lu.c +++ b/crypto/x509/x509_lu.c @@ -185,8 +185,22 @@ X509_STORE *X509_STORE_new(void) ret->objs = sk_X509_OBJECT_new(x509_object_cmp); ret->cache=1; ret->get_cert_methods=sk_X509_LOOKUP_new_null(); - ret->verify=NULL; - ret->verify_cb=NULL; + ret->verify=0; + ret->verify_cb=0; + + ret->purpose = 0; + ret->trust = 0; + + ret->flags = 0; + + ret->get_issuer = 0; + ret->check_issued = 0; + ret->check_revocation = 0; + ret->get_crl = 0; + ret->check_crl = 0; + ret->cert_crl = 0; + ret->cleanup = 0; + memset(&ret->ex_data,0,sizeof(CRYPTO_EX_DATA)); ret->references=1; ret->depth=0; @@ -525,5 +539,10 @@ int X509_STORE_CTX_get1_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x) return 0; } +void X509_STORE_set_flags(X509_STORE *ctx, long flags) + { + ctx->flags |= flags; + } + IMPLEMENT_STACK_OF(X509_LOOKUP) IMPLEMENT_STACK_OF(X509_OBJECT) diff --git a/crypto/x509/x509_vfy.c b/crypto/x509/x509_vfy.c index c8fa53dbec..0a5dcbe2ab 100644 --- a/crypto/x509/x509_vfy.c +++ b/crypto/x509/x509_vfy.c @@ -112,7 +112,6 @@ int X509_verify_cert(X509_STORE_CTX *ctx) } cb=ctx->verify_cb; - if (cb == NULL) cb=null_callback; /* first we make sure the chain we are going to build is * present and that the first entry is in place */ @@ -352,8 +351,7 @@ static int check_issued(X509_STORE_CTX *ctx, X509 *x, X509 *issuer) ctx->error = ret; ctx->current_cert = x; ctx->current_issuer = issuer; - if (ctx->verify_cb) - return ctx->verify_cb(0, ctx); + return ctx->verify_cb(0, ctx); return 0; } @@ -385,7 +383,6 @@ static int check_chain_purpose(X509_STORE_CTX *ctx) X509 *x; int (*cb)(); cb=ctx->verify_cb; - if (cb == NULL) cb=null_callback; /* Check all untrusted certificates */ for (i = 0; i < ctx->last_untrusted; i++) { @@ -427,7 +424,6 @@ static int check_trust(X509_STORE_CTX *ctx) X509 *x; int (*cb)(); cb=ctx->verify_cb; - if (cb == NULL) cb=null_callback; /* For now just check the last certificate in the chain */ i = sk_X509_num(ctx->chain) - 1; x = sk_X509_value(ctx->chain, i); @@ -479,8 +475,7 @@ static int check_cert(X509_STORE_CTX *ctx) if(!ok) { ctx->error = X509_V_ERR_UNABLE_TO_GET_CRL; - if (ctx->verify_cb) - ok = ctx->verify_cb(0, ctx); + ok = ctx->verify_cb(0, ctx); goto err; } ctx->current_crl = crl; @@ -529,8 +524,7 @@ static int check_crl(X509_STORE_CTX *ctx, X509_CRL *crl) if(!ctx->check_issued(ctx, issuer, issuer)) { ctx->error = X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER; - if(ctx->verify_cb) - ok = ctx->verify_cb(0, ctx); + ok = ctx->verify_cb(0, ctx); if(!ok) goto err; } } @@ -544,8 +538,7 @@ static int check_crl(X509_STORE_CTX *ctx, X509_CRL *crl) if(!ikey) { ctx->error=X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY; - if(ctx->verify_cb) - ok = ctx->verify_cb(0, ctx); + ok = ctx->verify_cb(0, ctx); if (!ok) goto err; } else @@ -554,8 +547,7 @@ static int check_crl(X509_STORE_CTX *ctx, X509_CRL *crl) if(X509_CRL_verify(crl, ikey) <= 0) { ctx->error=X509_V_ERR_CRL_SIGNATURE_FAILURE; - if(ctx->verify_cb) - ok = ctx->verify_cb(0, ctx); + ok = ctx->verify_cb(0, ctx); if (!ok) goto err; } } @@ -571,18 +563,14 @@ static int check_crl(X509_STORE_CTX *ctx, X509_CRL *crl) if (i == 0) { ctx->error=X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD; - ok= 0; - if(ctx->verify_cb) - ok = ctx->verify_cb(0, ctx); + ok = ctx->verify_cb(0, ctx); if (!ok) goto err; } if (i > 0) { ctx->error=X509_V_ERR_CRL_NOT_YET_VALID; - ok= 0; - if(ctx->verify_cb) - ok = ctx->verify_cb(0, ctx); + ok = ctx->verify_cb(0, ctx); if (!ok) goto err; } @@ -593,18 +581,14 @@ static int check_crl(X509_STORE_CTX *ctx, X509_CRL *crl) if (i == 0) { ctx->error=X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD; - ok= 0; - if(ctx->verify_cb) - ok = ctx->verify_cb(0, ctx); + ok = ctx->verify_cb(0, ctx); if (!ok) goto err; } if (i < 0) { ctx->error=X509_V_ERR_CRL_HAS_EXPIRED; - ok= 0; - if(ctx->verify_cb) - ok = ctx->verify_cb(0, ctx); + ok = ctx->verify_cb(0, ctx); if (!ok) goto err; } } @@ -630,8 +614,7 @@ static int cert_crl(X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x) * this to handle entry extensions in V2 CRLs. */ ctx->error = X509_V_ERR_CERT_REVOKED; - if (ctx->verify_cb) - ok = ctx->verify_cb(0, ctx); + ok = ctx->verify_cb(0, ctx); return ok; } @@ -644,7 +627,6 @@ static int internal_verify(X509_STORE_CTX *ctx) int (*cb)(); cb=ctx->verify_cb; - if (cb == NULL) cb=null_callback; n=sk_X509_num(ctx->chain); ctx->error_depth=n-1; @@ -1041,8 +1023,8 @@ int X509_STORE_CTX_purpose_inherit(X509_STORE_CTX *ctx, int def_purpose, } } - if (purpose) ctx->purpose = purpose; - if (trust) ctx->trust = trust; + if (purpose && !ctx->purpose) ctx->purpose = purpose; + if (trust && !ctx->trust) ctx->trust = trust; return 1; } @@ -1068,8 +1050,8 @@ void X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, X509 *x509, ctx->cert=x509; ctx->untrusted=chain; ctx->last_untrusted=0; - ctx->purpose=0; - ctx->trust=0; + ctx->purpose=store->purpose; + ctx->trust=store->trust; ctx->check_time=0; ctx->flags=0; ctx->other_ctx=NULL; @@ -1080,15 +1062,55 @@ void X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, X509 *x509, ctx->error_depth=0; ctx->current_cert=NULL; ctx->current_issuer=NULL; - ctx->check_issued = check_issued; - ctx->get_issuer = X509_STORE_CTX_get1_issuer; - ctx->verify_cb = store->verify_cb; - ctx->verify = store->verify; - ctx->check_revocation = check_revocation; - ctx->get_crl = get_crl; - ctx->check_crl = check_crl; - ctx->cert_crl = cert_crl; - ctx->cleanup = 0; + + /* Inherit callbacks and flags from X509_STORE if not set + * use defaults. + */ + + ctx->flags = store->flags; + + if (store->check_issued) + ctx->check_issued = store->check_issued; + else + ctx->check_issued = check_issued; + + if (store->get_issuer) + ctx->get_issuer = store->get_issuer; + else + ctx->get_issuer = X509_STORE_CTX_get1_issuer; + + if (store->verify_cb) + ctx->verify_cb = store->verify_cb; + else + ctx->verify_cb = null_callback; + + if (store->verify) + ctx->verify = store->verify; + else + ctx->verify = internal_verify; + + if (store->check_revocation) + ctx->check_revocation = store->check_revocation; + else + ctx->check_revocation = check_revocation; + + if (store->get_crl) + ctx->get_crl = store->get_crl; + else + ctx->get_crl = get_crl; + + if (store->check_crl) + ctx->check_crl = store->check_crl; + else + ctx->check_crl = check_crl; + + if (store->cert_crl) + ctx->cert_crl = store->cert_crl; + else + ctx->cert_crl = cert_crl; + + ctx->cleanup = store->cleanup; + memset(&(ctx->ex_data),0,sizeof(CRYPTO_EX_DATA)); } diff --git a/crypto/x509/x509_vfy.h b/crypto/x509/x509_vfy.h index 22b6c952ba..c308d26ab8 100644 --- a/crypto/x509/x509_vfy.h +++ b/crypto/x509/x509_vfy.h @@ -168,8 +168,24 @@ typedef struct x509_store_st /* These are external lookup methods */ STACK_OF(X509_LOOKUP) *get_cert_methods; + + /* The following fields are not used by X509_STORE but are + * inherited by X509_STORE_CTX when it is initialised. + */ + + unsigned long flags; /* Various verify flags */ + int purpose; + int trust; + /* Callbacks for various operations */ int (*verify)(X509_STORE_CTX *ctx); /* called to verify a certificate */ int (*verify_cb)(int ok,X509_STORE_CTX *ctx); /* error callback */ + int (*get_issuer)(X509 **issuer, X509_STORE_CTX *ctx, X509 *x); /* get issuers cert from ctx */ + int (*check_issued)(X509_STORE_CTX *ctx, X509 *x, X509 *issuer); /* check issued */ + int (*check_revocation)(X509_STORE_CTX *ctx); /* Check revocation status of chain */ + int (*get_crl)(X509_STORE_CTX *ctx, X509_CRL **crl, X509 *x); /* retrieve CRL */ + int (*check_crl)(X509_STORE_CTX *ctx, X509_CRL *crl); /* Check CRL validity */ + int (*cert_crl)(X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x); /* Check certificate against CRL */ + int (*cleanup)(X509_STORE_CTX *ctx); CRYPTO_EX_DATA ex_data; int references; @@ -309,6 +325,8 @@ void X509_OBJECT_free_contents(X509_OBJECT *a); X509_STORE *X509_STORE_new(void ); void X509_STORE_free(X509_STORE *v); +void X509_STORE_set_flags(X509_STORE *ctx, long flags); + X509_STORE_CTX *X509_STORE_CTX_new(void); int X509_STORE_CTX_get1_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x); -- 2.34.1