Main Page | Class List | Directories | File List | Class Members | File Members

crl.c

Go to the documentation of this file.
00001 /* apps/crl.c */
00002 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
00003  * All rights reserved.
00004  *
00005  * This package is an SSL implementation written
00006  * by Eric Young (eay@cryptsoft.com).
00007  * The implementation was written so as to conform with Netscapes SSL.
00008  * 
00009  * This library is free for commercial and non-commercial use as long as
00010  * the following conditions are aheared to.  The following conditions
00011  * apply to all code found in this distribution, be it the RC4, RSA,
00012  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
00013  * included with this distribution is covered by the same copyright terms
00014  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
00015  * 
00016  * Copyright remains Eric Young's, and as such any Copyright notices in
00017  * the code are not to be removed.
00018  * If this package is used in a product, Eric Young should be given attribution
00019  * as the author of the parts of the library used.
00020  * This can be in the form of a textual message at program startup or
00021  * in documentation (online or textual) provided with the package.
00022  * 
00023  * Redistribution and use in source and binary forms, with or without
00024  * modification, are permitted provided that the following conditions
00025  * are met:
00026  * 1. Redistributions of source code must retain the copyright
00027  *    notice, this list of conditions and the following disclaimer.
00028  * 2. Redistributions in binary form must reproduce the above copyright
00029  *    notice, this list of conditions and the following disclaimer in the
00030  *    documentation and/or other materials provided with the distribution.
00031  * 3. All advertising materials mentioning features or use of this software
00032  *    must display the following acknowledgement:
00033  *    "This product includes cryptographic software written by
00034  *     Eric Young (eay@cryptsoft.com)"
00035  *    The word 'cryptographic' can be left out if the rouines from the library
00036  *    being used are not cryptographic related :-).
00037  * 4. If you include any Windows specific code (or a derivative thereof) from 
00038  *    the apps directory (application code) you must include an acknowledgement:
00039  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
00040  * 
00041  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
00042  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00043  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00044  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
00045  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00046  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00047  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00048  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00049  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00050  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00051  * SUCH DAMAGE.
00052  * 
00053  * The licence and distribution terms for any publically available version or
00054  * derivative of this code cannot be changed.  i.e. this code cannot simply be
00055  * copied and put under another distribution licence
00056  * [including the GNU Public Licence.]
00057  */
00058 
00059 #include <stdio.h>
00060 #include <stdlib.h>
00061 #include <string.h>
00062 #include "apps.h"
00063 #include <openssl/bio.h>
00064 #include <openssl/err.h>
00065 #include <openssl/x509.h>
00066 #include <openssl/x509v3.h>
00067 #include <openssl/pem.h>
00068 
00069 #undef PROG
00070 #define PROG    crl_main
00071 
00072 #undef POSTFIX
00073 #define POSTFIX ".rvk"
00074 
00075 static const char *crl_usage[]={
00076 "usage: crl args\n",
00077 "\n",
00078 " -inform arg     - input format - default PEM (DER or PEM)\n",
00079 " -outform arg    - output format - default PEM\n",
00080 " -text           - print out a text format version\n",
00081 " -in arg         - input file - default stdin\n",
00082 " -out arg        - output file - default stdout\n",
00083 " -hash           - print hash value\n",
00084 " -fingerprint    - print the crl fingerprint\n",
00085 " -issuer         - print issuer DN\n",
00086 " -lastupdate     - lastUpdate field\n",
00087 " -nextupdate     - nextUpdate field\n",
00088 " -noout          - no CRL output\n",
00089 " -CAfile  name   - verify CRL using certificates in file \"name\"\n",
00090 " -CApath  dir    - verify CRL using certificates in \"dir\"\n",
00091 " -nameopt arg    - various certificate name options\n",
00092 NULL
00093 };
00094 
00095 static X509_CRL *load_crl(char *file, int format);
00096 static BIO *bio_out=NULL;
00097 
00098 int MAIN(int, char **);
00099 
00100 int MAIN(int argc, char **argv)
00101         {
00102         unsigned long nmflag = 0;
00103         X509_CRL *x=NULL;
00104         char *CAfile = NULL, *CApath = NULL;
00105         int ret=1,i,num,badops=0;
00106         BIO *out=NULL;
00107         int informat,outformat;
00108         char *infile=NULL,*outfile=NULL;
00109         int hash=0,issuer=0,lastupdate=0,nextupdate=0,noout=0,text=0;
00110         int fingerprint = 0;
00111         const char **pp;
00112         X509_STORE *store = NULL;
00113         X509_STORE_CTX ctx;
00114         X509_LOOKUP *lookup = NULL;
00115         X509_OBJECT xobj;
00116         EVP_PKEY *pkey;
00117         int do_ver = 0;
00118         const EVP_MD *md_alg,*digest=EVP_sha1();
00119 
00120         apps_startup();
00121 
00122         if (bio_err == NULL)
00123                 if ((bio_err=BIO_new(BIO_s_file())) != NULL)
00124                         BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
00125 
00126         if (!load_config(bio_err, NULL))
00127                 goto end;
00128 
00129         if (bio_out == NULL)
00130                 if ((bio_out=BIO_new(BIO_s_file())) != NULL)
00131                         {
00132                         BIO_set_fp(bio_out,stdout,BIO_NOCLOSE);
00133 #ifdef OPENSSL_SYS_VMS
00134                         {
00135                         BIO *tmpbio = BIO_new(BIO_f_linebuffer());
00136                         bio_out = BIO_push(tmpbio, bio_out);
00137                         }
00138 #endif
00139                         }
00140 
00141         informat=FORMAT_PEM;
00142         outformat=FORMAT_PEM;
00143 
00144         argc--;
00145         argv++;
00146         num=0;
00147         while (argc >= 1)
00148                 {
00149 #ifdef undef
00150                 if      (strcmp(*argv,"-p") == 0)
00151                         {
00152                         if (--argc < 1) goto bad;
00153                         if (!args_from_file(++argv,Nargc,Nargv)) { goto end; }*/
00154                         }
00155 #endif
00156                 if      (strcmp(*argv,"-inform") == 0)
00157                         {
00158                         if (--argc < 1) goto bad;
00159                         informat=str2fmt(*(++argv));
00160                         }
00161                 else if (strcmp(*argv,"-outform") == 0)
00162                         {
00163                         if (--argc < 1) goto bad;
00164                         outformat=str2fmt(*(++argv));
00165                         }
00166                 else if (strcmp(*argv,"-in") == 0)
00167                         {
00168                         if (--argc < 1) goto bad;
00169                         infile= *(++argv);
00170                         }
00171                 else if (strcmp(*argv,"-out") == 0)
00172                         {
00173                         if (--argc < 1) goto bad;
00174                         outfile= *(++argv);
00175                         }
00176                 else if (strcmp(*argv,"-CApath") == 0)
00177                         {
00178                         if (--argc < 1) goto bad;
00179                         CApath = *(++argv);
00180                         do_ver = 1;
00181                         }
00182                 else if (strcmp(*argv,"-CAfile") == 0)
00183                         {
00184                         if (--argc < 1) goto bad;
00185                         CAfile = *(++argv);
00186                         do_ver = 1;
00187                         }
00188                 else if (strcmp(*argv,"-verify") == 0)
00189                         do_ver = 1;
00190                 else if (strcmp(*argv,"-text") == 0)
00191                         text = 1;
00192                 else if (strcmp(*argv,"-hash") == 0)
00193                         hash= ++num;
00194                 else if (strcmp(*argv,"-nameopt") == 0)
00195                         {
00196                         if (--argc < 1) goto bad;
00197                         if (!set_name_ex(&nmflag, *(++argv))) goto bad;
00198                         }
00199                 else if (strcmp(*argv,"-issuer") == 0)
00200                         issuer= ++num;
00201                 else if (strcmp(*argv,"-lastupdate") == 0)
00202                         lastupdate= ++num;
00203                 else if (strcmp(*argv,"-nextupdate") == 0)
00204                         nextupdate= ++num;
00205                 else if (strcmp(*argv,"-noout") == 0)
00206                         noout= ++num;
00207                 else if (strcmp(*argv,"-fingerprint") == 0)
00208                         fingerprint= ++num;
00209                 else if ((md_alg=EVP_get_digestbyname(*argv + 1)))
00210                         {
00211                         /* ok */
00212                         digest=md_alg;
00213                         }
00214                 else
00215                         {
00216                         BIO_printf(bio_err,"unknown option %s\n",*argv);
00217                         badops=1;
00218                         break;
00219                         }
00220                 argc--;
00221                 argv++;
00222                 }
00223 
00224         if (badops)
00225                 {
00226 bad:
00227                 for (pp=crl_usage; (*pp != NULL); pp++)
00228                         BIO_printf(bio_err,"%s",*pp);
00229                 goto end;
00230                 }
00231 
00232         ERR_load_crypto_strings();
00233         x=load_crl(infile,informat);
00234         if (x == NULL) { goto end; }
00235 
00236         if(do_ver) {
00237                 store = X509_STORE_new();
00238                 lookup=X509_STORE_add_lookup(store,X509_LOOKUP_file());
00239                 if (lookup == NULL) goto end;
00240                 if (!X509_LOOKUP_load_file(lookup,CAfile,X509_FILETYPE_PEM))
00241                         X509_LOOKUP_load_file(lookup,NULL,X509_FILETYPE_DEFAULT);
00242                         
00243                 lookup=X509_STORE_add_lookup(store,X509_LOOKUP_hash_dir());
00244                 if (lookup == NULL) goto end;
00245                 if (!X509_LOOKUP_add_dir(lookup,CApath,X509_FILETYPE_PEM))
00246                         X509_LOOKUP_add_dir(lookup,NULL,X509_FILETYPE_DEFAULT);
00247                 ERR_clear_error();
00248 
00249                 if(!X509_STORE_CTX_init(&ctx, store, NULL, NULL)) {
00250                         BIO_printf(bio_err,
00251                                 "Error initialising X509 store\n");
00252                         goto end;
00253                 }
00254 
00255                 i = X509_STORE_get_by_subject(&ctx, X509_LU_X509, 
00256                                         X509_CRL_get_issuer(x), &xobj);
00257                 if(i <= 0) {
00258                         BIO_printf(bio_err,
00259                                 "Error getting CRL issuer certificate\n");
00260                         goto end;
00261                 }
00262                 pkey = X509_get_pubkey(xobj.data.x509);
00263                 X509_OBJECT_free_contents(&xobj);
00264                 if(!pkey) {
00265                         BIO_printf(bio_err,
00266                                 "Error getting CRL issuer public key\n");
00267                         goto end;
00268                 }
00269                 i = X509_CRL_verify(x, pkey);
00270                 EVP_PKEY_free(pkey);
00271                 if(i < 0) goto end;
00272                 if(i == 0) BIO_printf(bio_err, "verify failure\n");
00273                 else BIO_printf(bio_err, "verify OK\n");
00274         }
00275 
00276         if (num)
00277                 {
00278                 for (i=1; i<=num; i++)
00279                         {
00280                         if (issuer == i)
00281                                 {
00282                                 print_name(bio_out, "issuer=", X509_CRL_get_issuer(x), nmflag);
00283                                 }
00284 
00285                         if (hash == i)
00286                                 {
00287                                 BIO_printf(bio_out,"%08lx\n",
00288                                         X509_NAME_hash(X509_CRL_get_issuer(x)));
00289                                 }
00290                         if (lastupdate == i)
00291                                 {
00292                                 BIO_printf(bio_out,"lastUpdate=");
00293                                 ASN1_TIME_print(bio_out,
00294                                                 X509_CRL_get_lastUpdate(x));
00295                                 BIO_printf(bio_out,"\n");
00296                                 }
00297                         if (nextupdate == i)
00298                                 {
00299                                 BIO_printf(bio_out,"nextUpdate=");
00300                                 if (X509_CRL_get_nextUpdate(x)) 
00301                                         ASN1_TIME_print(bio_out,
00302                                                 X509_CRL_get_nextUpdate(x));
00303                                 else
00304                                         BIO_printf(bio_out,"NONE");
00305                                 BIO_printf(bio_out,"\n");
00306                                 }
00307                         if (fingerprint == i)
00308                                 {
00309                                 int j;
00310                                 unsigned int n;
00311                                 unsigned char md[EVP_MAX_MD_SIZE];
00312 
00313                                 if (!X509_CRL_digest(x,digest,md,&n))
00314                                         {
00315                                         BIO_printf(bio_err,"out of memory\n");
00316                                         goto end;
00317                                         }
00318                                 BIO_printf(bio_out,"%s Fingerprint=",
00319                                                 OBJ_nid2sn(EVP_MD_type(digest)));
00320                                 for (j=0; j<(int)n; j++)
00321                                         {
00322                                         BIO_printf(bio_out,"%02X%c",md[j],
00323                                                 (j+1 == (int)n)
00324                                                 ?'\n':':');
00325                                         }
00326                                 }
00327                         }
00328                 }
00329 
00330         out=BIO_new(BIO_s_file());
00331         if (out == NULL)
00332                 {
00333                 ERR_print_errors(bio_err);
00334                 goto end;
00335                 }
00336 
00337         if (outfile == NULL)
00338                 {
00339                 BIO_set_fp(out,stdout,BIO_NOCLOSE);
00340 #ifdef OPENSSL_SYS_VMS
00341                 {
00342                 BIO *tmpbio = BIO_new(BIO_f_linebuffer());
00343                 out = BIO_push(tmpbio, out);
00344                 }
00345 #endif
00346                 }
00347         else
00348                 {
00349                 if (BIO_write_filename(out,outfile) <= 0)
00350                         {
00351                         perror(outfile);
00352                         goto end;
00353                         }
00354                 }
00355 
00356         if (text) X509_CRL_print(out, x);
00357 
00358         if (noout) 
00359                 {
00360                 ret = 0;
00361                 goto end;
00362                 }
00363 
00364         if      (outformat == FORMAT_ASN1)
00365                 i=(int)i2d_X509_CRL_bio(out,x);
00366         else if (outformat == FORMAT_PEM)
00367                 i=PEM_write_bio_X509_CRL(out,x);
00368         else    
00369                 {
00370                 BIO_printf(bio_err,"bad output format specified for outfile\n");
00371                 goto end;
00372                 }
00373         if (!i) { BIO_printf(bio_err,"unable to write CRL\n"); goto end; }
00374         ret=0;
00375 end:
00376         BIO_free_all(out);
00377         BIO_free_all(bio_out);
00378         bio_out=NULL;
00379         X509_CRL_free(x);
00380         if(store) {
00381                 X509_STORE_CTX_cleanup(&ctx);
00382                 X509_STORE_free(store);
00383         }
00384         apps_shutdown();
00385         OPENSSL_EXIT(ret);
00386         }
00387 
00388 static X509_CRL *load_crl(char *infile, int format)
00389         {
00390         X509_CRL *x=NULL;
00391         BIO *in=NULL;
00392 
00393         in=BIO_new(BIO_s_file());
00394         if (in == NULL)
00395                 {
00396                 ERR_print_errors(bio_err);
00397                 goto end;
00398                 }
00399 
00400         if (infile == NULL)
00401                 BIO_set_fp(in,stdin,BIO_NOCLOSE);
00402         else
00403                 {
00404                 if (BIO_read_filename(in,infile) <= 0)
00405                         {
00406                         perror(infile);
00407                         goto end;
00408                         }
00409                 }
00410         if      (format == FORMAT_ASN1)
00411                 x=d2i_X509_CRL_bio(in,NULL);
00412         else if (format == FORMAT_PEM)
00413                 x=PEM_read_bio_X509_CRL(in,NULL,NULL,NULL);
00414         else    {
00415                 BIO_printf(bio_err,"bad input format specified for input crl\n");
00416                 goto end;
00417                 }
00418         if (x == NULL)
00419                 {
00420                 BIO_printf(bio_err,"unable to load CRL\n");
00421                 ERR_print_errors(bio_err);
00422                 goto end;
00423                 }
00424         
00425 end:
00426         BIO_free(in);
00427         return(x);
00428         }
00429 

© sourcejam.com 2005-2008