00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
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
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