Add option to allow in-band CRL loading in verify utility. Add function
authorDr. Stephen Henson <steve@openssl.org>
Sat, 31 Oct 2009 13:33:57 +0000 (13:33 +0000)
committerDr. Stephen Henson <steve@openssl.org>
Sat, 31 Oct 2009 13:33:57 +0000 (13:33 +0000)
load_crls and tidy up load_certs. Remove useless purpose variable from
verify utility: now done with args_verify.

CHANGES
apps/apps.c
apps/apps.h
apps/verify.c

diff --git a/CHANGES b/CHANGES
index 7c0664edb3f1ae9f7d0e0565be8f67a659a82256..fc7c0ad39442f9dba565fd7b6d54d584c787aff7 100644 (file)
--- a/CHANGES
+++ b/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:
      some responders need this.
      [Steve Henson]
   *) Update OCSP request code to permit adding custom headers to the request:
      some responders need this.
      [Steve Henson]
index 09d9df2817a7e669f7b2a92279b9a998b5fcb79b..5dccea70d2be6d43492578fe5db565da71c05d2b 100644 (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,
-       const char *pass, ENGINE *e, const char *cert_descrip)
+static int load_certs_crls(BIO *err, const char *file, int format,
+       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;
-       STACK_OF(X509_INFO) *allcerts = NULL;
+       BIO *bio;
+       STACK_OF(X509_INFO) *xis = NULL;
        X509_INFO *xi;
        PW_CB_DATA cb_data;
        X509_INFO *xi;
        PW_CB_DATA cb_data;
+       int rv = 0;
 
        cb_data.password = pass;
        cb_data.prompt_info = file;
 
 
        cb_data.password = pass;
        cb_data.prompt_info = file;
 
-       if((certs = BIO_new(BIO_s_file())) == NULL)
+       if (format != FORMAT_PEM)
                {
                {
-               ERR_print_errors(err);
-               goto end;
+               BIO_printf(err,"bad input format specified for %s\n", desc);
+               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",
-                               cert_descrip, file);
-                       ERR_print_errors(err);
+               BIO_printf(err, "Error opening %s %s\n",
+                               desc, file ? file : "stdin");
+               ERR_print_errors(err);
+               return 0;
+               }
+
+       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      (format == FORMAT_PEM)
+       if (pcrls)
                {
                {
-               othercerts = sk_X509_new_null();
-               if(!othercerts)
-                       {
-                       sk_X509_free(othercerts);
-                       othercerts = NULL;
+               *pcrls = sk_X509_CRL_new_null();
+               if (!*pcrls)
                        goto end;
                        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;
                        }
                        }
-               allcerts = PEM_X509_INFO_read_bio(certs, NULL,
-                               (pem_password_cb *)password_callback, &cb_data);
-               for(i = 0; i < sk_X509_INFO_num(allcerts); i++)
+               if (xi->crl && pcrls)
                        {
                        {
-                       xi = sk_X509_INFO_value (allcerts, i);
-                       if (xi->x509)
-                               {
-                               sk_X509_push(othercerts, xi->x509);
-                               xi->x509 = NULL;
-                               }
+                       if (!sk_X509_CRL_push(*pcrls, xi->crl))
+                               goto end;
+                       xi->crl = NULL;
                        }
                        }
-               goto end;
                }
                }
-       else    {
-               BIO_printf(err,"bad input format specified for %s\n",
-                       cert_descrip);
-               goto end;
-               }
-end:
-       if (othercerts == NULL)
+
+       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)
                {
                {
-               BIO_printf(err,"unable to load certificates\n");
+               if (pcerts)
+                       {
+                       sk_X509_pop_free(*pcerts, X509_free);
+                       *pcerts = NULL;
+                       }
+               if (pcrls)
+                       {
+                       sk_X509_CRL_pop_free(*pcrls, X509_CRL_free);
+                       *pcrls = NULL;
+                       }
+               BIO_printf(err,"unable to load %s\n",
+                               pcerts ? "certificates" : "CRLs");
                ERR_print_errors(err);
                }
                ERR_print_errors(err);
                }
-       if (allcerts) sk_X509_INFO_pop_free(allcerts, X509_INFO_free);
-       if (certs != NULL) BIO_free(certs);
-       return(othercerts);
+       return rv;
        }
 
        }
 
+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)
 /* Return error for unknown extensions */
 
 #define X509V3_EXT_UNKNOWN_MASK                (0xfL << 16)
 /* Return error for unknown extensions */
index 35a0266414ce14f156f0866ce5b4bcaf249c924d..596a39aceb507cbfa173e8c5b81466ecd98c052e 100644 (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);
 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 *key_descrip);
 STACK_OF(X509) *load_certs(BIO *err, const char *file, int format,
        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);
 #ifndef OPENSSL_NO_ENGINE
 ENGINE *setup_engine(BIO *err, const char *engine, int debug);
 X509_STORE *setup_verify(BIO *bp, char *CAfile, char *CApath);
 #ifndef OPENSSL_NO_ENGINE
 ENGINE *setup_engine(BIO *err, const char *engine, int debug);
index 96fcfb429d4185915f8d06747b8f888243a65f06..c0be253db23329c713307f419bc187e505b19bb3 100644 (file)
@@ -70,8 +70,9 @@
 #define PROG   verify_main
 
 static int MS_CALLBACK cb(int ok, X509_STORE_CTX *ctx);
 #define PROG   verify_main
 
 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 STACK_OF(X509) *load_untrusted(char *file);
+static int check(X509_STORE *ctx, char *file,
+               STACK_OF(X509) *uchain, STACK_OF(X509) *tchain,
+               STACK_OF(X509_CRL) *crls, ENGINE *e);
 static int v_verbose=0, vflags = 0;
 
 int MAIN(int, char **);
 static int v_verbose=0, vflags = 0;
 
 int MAIN(int, char **);
@@ -80,10 +81,10 @@ int MAIN(int argc, char **argv)
        {
        ENGINE *e = NULL;
        int i,ret=1, badarg = 0;
        {
        ENGINE *e = NULL;
        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_LOOKUP *lookup=NULL;
        X509_VERIFY_PARAM *vpm = NULL;
        X509_STORE *cert_ctx=NULL;
        X509_LOOKUP *lookup=NULL;
        X509_VERIFY_PARAM *vpm = NULL;
@@ -139,6 +140,11 @@ int MAIN(int argc, char **argv)
                                if (argc-- < 1) goto end;
                                trustfile= *(++argv);
                                }
                                if (argc-- < 1) goto end;
                                trustfile= *(++argv);
                                }
+                       else if (strcmp(*argv,"-CRLfile") == 0)
+                               {
+                               if (argc-- < 1) goto end;
+                               crlfile= *(++argv);
+                               }
 #ifndef OPENSSL_NO_ENGINE
                        else if (strcmp(*argv,"-engine") == 0)
                                {
 #ifndef OPENSSL_NO_ENGINE
                        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(!(untrusted = load_untrusted(untfile))) {
-                       BIO_printf(bio_err, "Error loading untrusted file %s\n", untfile);
-                       ERR_print_errors(bio_err);
+       if(untfile)
+               {
+               untrusted = load_certs(bio_err, untfile, FORMAT_PEM,
+                                       NULL, e, "untrusted certificates");
+               if(!untrusted)
                        goto end;
                }
                        goto end;
                }
-       }
 
 
-       if(trustfile) {
-               if(!(trusted = load_untrusted(trustfile))) {
-                       BIO_printf(bio_err, "Error loading untrusted file %s\n", trustfile);
-                       ERR_print_errors(bio_err);
+       if(trustfile)
+               {
+               trusted = load_certs(bio_err, trustfile, FORMAT_PEM,
+                                       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
                for (i=0; i<argc; i++)
        else
                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;
 end:
        if (ret == 1) {
        ret=0;
 end:
        if (ret == 1) {
@@ -232,11 +246,14 @@ end:
        if (cert_ctx != NULL) X509_STORE_free(cert_ctx);
        sk_X509_pop_free(untrusted, X509_free);
        sk_X509_pop_free(trusted, X509_free);
        if (cert_ctx != NULL) X509_STORE_free(cert_ctx);
        sk_X509_pop_free(untrusted, X509_free);
        sk_X509_pop_free(trusted, X509_free);
+       sk_X509_CRL_pop_free(crls, X509_CRL_free);
        apps_shutdown();
        OPENSSL_EXIT(ret);
        }
 
        apps_shutdown();
        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;
        int i=0,ret=0;
        {
        X509 *x=NULL;
        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;
                }
        if(tchain) X509_STORE_CTX_trusted_stack(csc, tchain);
                goto end;
                }
        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);
        X509_STORE_CTX_free(csc);
 
        i=X509_verify_cert(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)
        {
        int cert_error = X509_STORE_CTX_get_error(ctx);
 static int MS_CALLBACK cb(int ok, X509_STORE_CTX *ctx)
        {
        int cert_error = X509_STORE_CTX_get_error(ctx);