OpenSSL  1.0.1c
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Macros
crl.c
Go to the documentation of this file.
1 /* apps/crl.c */
2 /* Copyright (C) 1995-1998 Eric Young ([email protected])
3  * All rights reserved.
4  *
5  * This package is an SSL implementation written
6  * by Eric Young ([email protected]).
7  * The implementation was written so as to conform with Netscapes SSL.
8  *
9  * This library is free for commercial and non-commercial use as long as
10  * the following conditions are aheared to. The following conditions
11  * apply to all code found in this distribution, be it the RC4, RSA,
12  * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13  * included with this distribution is covered by the same copyright terms
14  * except that the holder is Tim Hudson ([email protected]).
15  *
16  * Copyright remains Eric Young's, and as such any Copyright notices in
17  * the code are not to be removed.
18  * If this package is used in a product, Eric Young should be given attribution
19  * as the author of the parts of the library used.
20  * This can be in the form of a textual message at program startup or
21  * in documentation (online or textual) provided with the package.
22  *
23  * Redistribution and use in source and binary forms, with or without
24  * modification, are permitted provided that the following conditions
25  * are met:
26  * 1. Redistributions of source code must retain the copyright
27  * notice, this list of conditions and the following disclaimer.
28  * 2. Redistributions in binary form must reproduce the above copyright
29  * notice, this list of conditions and the following disclaimer in the
30  * documentation and/or other materials provided with the distribution.
31  * 3. All advertising materials mentioning features or use of this software
32  * must display the following acknowledgement:
33  * "This product includes cryptographic software written by
34  * Eric Young ([email protected])"
35  * The word 'cryptographic' can be left out if the rouines from the library
36  * being used are not cryptographic related :-).
37  * 4. If you include any Windows specific code (or a derivative thereof) from
38  * the apps directory (application code) you must include an acknowledgement:
39  * "This product includes software written by Tim Hudson ([email protected])"
40  *
41  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51  * SUCH DAMAGE.
52  *
53  * The licence and distribution terms for any publically available version or
54  * derivative of this code cannot be changed. i.e. this code cannot simply be
55  * copied and put under another distribution licence
56  * [including the GNU Public Licence.]
57  */
58 
59 #include <stdio.h>
60 #include <stdlib.h>
61 #include <string.h>
62 #include "apps.h"
63 #include <openssl/bio.h>
64 #include <openssl/err.h>
65 #include <openssl/x509.h>
66 #include <openssl/x509v3.h>
67 #include <openssl/pem.h>
68 
69 #undef PROG
70 #define PROG crl_main
71 
72 #undef POSTFIX
73 #define POSTFIX ".rvk"
74 
75 static const char *crl_usage[]={
76 "usage: crl args\n",
77 "\n",
78 " -inform arg - input format - default PEM (DER or PEM)\n",
79 " -outform arg - output format - default PEM\n",
80 " -text - print out a text format version\n",
81 " -in arg - input file - default stdin\n",
82 " -out arg - output file - default stdout\n",
83 " -hash - print hash value\n",
84 " -fingerprint - print the crl fingerprint\n",
85 " -issuer - print issuer DN\n",
86 " -lastupdate - lastUpdate field\n",
87 " -nextupdate - nextUpdate field\n",
88 " -crlnumber - print CRL number\n",
89 " -noout - no CRL output\n",
90 " -CAfile name - verify CRL using certificates in file \"name\"\n",
91 " -CApath dir - verify CRL using certificates in \"dir\"\n",
92 " -nameopt arg - various certificate name options\n",
93 NULL
94 };
95 
96 static X509_CRL *load_crl(char *file, int format);
97 static BIO *bio_out=NULL;
98 
99 int MAIN(int, char **);
100 
101 int MAIN(int argc, char **argv)
102  {
103  unsigned long nmflag = 0;
104  X509_CRL *x=NULL;
105  char *CAfile = NULL, *CApath = NULL;
106  int ret=1,i,num,badops=0;
107  BIO *out=NULL;
108  int informat,outformat;
109  char *infile=NULL,*outfile=NULL;
110  int hash=0,issuer=0,lastupdate=0,nextupdate=0,noout=0,text=0;
111  int fingerprint = 0, crlnumber = 0;
112  const char **pp;
113  X509_STORE *store = NULL;
114  X509_STORE_CTX ctx;
115  X509_LOOKUP *lookup = NULL;
116  X509_OBJECT xobj;
117  EVP_PKEY *pkey;
118  int do_ver = 0;
119  const EVP_MD *md_alg,*digest=EVP_sha1();
120 
121  apps_startup();
122 
123  if (bio_err == NULL)
124  if ((bio_err=BIO_new(BIO_s_file())) != NULL)
126 
127  if (!load_config(bio_err, NULL))
128  goto end;
129 
130  if (bio_out == NULL)
131  if ((bio_out=BIO_new(BIO_s_file())) != NULL)
132  {
133  BIO_set_fp(bio_out,stdout,BIO_NOCLOSE);
134 #ifdef OPENSSL_SYS_VMS
135  {
136  BIO *tmpbio = BIO_new(BIO_f_linebuffer());
137  bio_out = BIO_push(tmpbio, bio_out);
138  }
139 #endif
140  }
141 
142  informat=FORMAT_PEM;
143  outformat=FORMAT_PEM;
144 
145  argc--;
146  argv++;
147  num=0;
148  while (argc >= 1)
149  {
150 #ifdef undef
151  if (strcmp(*argv,"-p") == 0)
152  {
153  if (--argc < 1) goto bad;
154  if (!args_from_file(++argv,Nargc,Nargv)) { goto end; }*/
155  }
156 #endif
157  if (strcmp(*argv,"-inform") == 0)
158  {
159  if (--argc < 1) goto bad;
160  informat=str2fmt(*(++argv));
161  }
162  else if (strcmp(*argv,"-outform") == 0)
163  {
164  if (--argc < 1) goto bad;
165  outformat=str2fmt(*(++argv));
166  }
167  else if (strcmp(*argv,"-in") == 0)
168  {
169  if (--argc < 1) goto bad;
170  infile= *(++argv);
171  }
172  else if (strcmp(*argv,"-out") == 0)
173  {
174  if (--argc < 1) goto bad;
175  outfile= *(++argv);
176  }
177  else if (strcmp(*argv,"-CApath") == 0)
178  {
179  if (--argc < 1) goto bad;
180  CApath = *(++argv);
181  do_ver = 1;
182  }
183  else if (strcmp(*argv,"-CAfile") == 0)
184  {
185  if (--argc < 1) goto bad;
186  CAfile = *(++argv);
187  do_ver = 1;
188  }
189  else if (strcmp(*argv,"-verify") == 0)
190  do_ver = 1;
191  else if (strcmp(*argv,"-text") == 0)
192  text = 1;
193  else if (strcmp(*argv,"-hash") == 0)
194  hash= ++num;
195  else if (strcmp(*argv,"-nameopt") == 0)
196  {
197  if (--argc < 1) goto bad;
198  if (!set_name_ex(&nmflag, *(++argv))) goto bad;
199  }
200  else if (strcmp(*argv,"-issuer") == 0)
201  issuer= ++num;
202  else if (strcmp(*argv,"-lastupdate") == 0)
203  lastupdate= ++num;
204  else if (strcmp(*argv,"-nextupdate") == 0)
205  nextupdate= ++num;
206  else if (strcmp(*argv,"-noout") == 0)
207  noout= ++num;
208  else if (strcmp(*argv,"-fingerprint") == 0)
209  fingerprint= ++num;
210  else if (strcmp(*argv,"-crlnumber") == 0)
211  crlnumber= ++num;
212  else if ((md_alg=EVP_get_digestbyname(*argv + 1)))
213  {
214  /* ok */
215  digest=md_alg;
216  }
217  else
218  {
219  BIO_printf(bio_err,"unknown option %s\n",*argv);
220  badops=1;
221  break;
222  }
223  argc--;
224  argv++;
225  }
226 
227  if (badops)
228  {
229 bad:
230  for (pp=crl_usage; (*pp != NULL); pp++)
231  BIO_printf(bio_err,"%s",*pp);
232  goto end;
233  }
234 
236  x=load_crl(infile,informat);
237  if (x == NULL) { goto end; }
238 
239  if(do_ver) {
240  store = X509_STORE_new();
241  lookup=X509_STORE_add_lookup(store,X509_LOOKUP_file());
242  if (lookup == NULL) goto end;
243  if (!X509_LOOKUP_load_file(lookup,CAfile,X509_FILETYPE_PEM))
245 
247  if (lookup == NULL) goto end;
248  if (!X509_LOOKUP_add_dir(lookup,CApath,X509_FILETYPE_PEM))
250  ERR_clear_error();
251 
252  if(!X509_STORE_CTX_init(&ctx, store, NULL, NULL)) {
254  "Error initialising X509 store\n");
255  goto end;
256  }
257 
259  X509_CRL_get_issuer(x), &xobj);
260  if(i <= 0) {
262  "Error getting CRL issuer certificate\n");
263  goto end;
264  }
265  pkey = X509_get_pubkey(xobj.data.x509);
267  if(!pkey) {
269  "Error getting CRL issuer public key\n");
270  goto end;
271  }
272  i = X509_CRL_verify(x, pkey);
273  EVP_PKEY_free(pkey);
274  if(i < 0) goto end;
275  if(i == 0) BIO_printf(bio_err, "verify failure\n");
276  else BIO_printf(bio_err, "verify OK\n");
277  }
278 
279  if (num)
280  {
281  for (i=1; i<=num; i++)
282  {
283  if (issuer == i)
284  {
285  print_name(bio_out, "issuer=", X509_CRL_get_issuer(x), nmflag);
286  }
287  if (crlnumber == i)
288  {
289  ASN1_INTEGER *crlnum;
291  NULL, NULL);
292  BIO_printf(bio_out,"crlNumber=");
293  if (crlnum)
294  {
295  i2a_ASN1_INTEGER(bio_out, crlnum);
296  ASN1_INTEGER_free(crlnum);
297  }
298  else
299  BIO_puts(bio_out, "<NONE>");
300  BIO_printf(bio_out,"\n");
301  }
302  if (hash == i)
303  {
304  BIO_printf(bio_out,"%08lx\n",
306  }
307  if (lastupdate == i)
308  {
309  BIO_printf(bio_out,"lastUpdate=");
310  ASN1_TIME_print(bio_out,
312  BIO_printf(bio_out,"\n");
313  }
314  if (nextupdate == i)
315  {
316  BIO_printf(bio_out,"nextUpdate=");
317  if (X509_CRL_get_nextUpdate(x))
318  ASN1_TIME_print(bio_out,
320  else
321  BIO_printf(bio_out,"NONE");
322  BIO_printf(bio_out,"\n");
323  }
324  if (fingerprint == i)
325  {
326  int j;
327  unsigned int n;
328  unsigned char md[EVP_MAX_MD_SIZE];
329 
330  if (!X509_CRL_digest(x,digest,md,&n))
331  {
332  BIO_printf(bio_err,"out of memory\n");
333  goto end;
334  }
335  BIO_printf(bio_out,"%s Fingerprint=",
336  OBJ_nid2sn(EVP_MD_type(digest)));
337  for (j=0; j<(int)n; j++)
338  {
339  BIO_printf(bio_out,"%02X%c",md[j],
340  (j+1 == (int)n)
341  ?'\n':':');
342  }
343  }
344  }
345  }
346 
347  out=BIO_new(BIO_s_file());
348  if (out == NULL)
349  {
351  goto end;
352  }
353 
354  if (outfile == NULL)
355  {
356  BIO_set_fp(out,stdout,BIO_NOCLOSE);
357 #ifdef OPENSSL_SYS_VMS
358  {
359  BIO *tmpbio = BIO_new(BIO_f_linebuffer());
360  out = BIO_push(tmpbio, out);
361  }
362 #endif
363  }
364  else
365  {
366  if (BIO_write_filename(out,outfile) <= 0)
367  {
368  perror(outfile);
369  goto end;
370  }
371  }
372 
373  if (text) X509_CRL_print(out, x);
374 
375  if (noout)
376  {
377  ret = 0;
378  goto end;
379  }
380 
381  if (outformat == FORMAT_ASN1)
382  i=(int)i2d_X509_CRL_bio(out,x);
383  else if (outformat == FORMAT_PEM)
384  i=PEM_write_bio_X509_CRL(out,x);
385  else
386  {
387  BIO_printf(bio_err,"bad output format specified for outfile\n");
388  goto end;
389  }
390  if (!i) { BIO_printf(bio_err,"unable to write CRL\n"); goto end; }
391  ret=0;
392 end:
393  BIO_free_all(out);
394  BIO_free_all(bio_out);
395  bio_out=NULL;
396  X509_CRL_free(x);
397  if(store) {
399  X509_STORE_free(store);
400  }
401  apps_shutdown();
402  OPENSSL_EXIT(ret);
403  }
404 
405 static X509_CRL *load_crl(char *infile, int format)
406  {
407  X509_CRL *x=NULL;
408  BIO *in=NULL;
409 
410  in=BIO_new(BIO_s_file());
411  if (in == NULL)
412  {
414  goto end;
415  }
416 
417  if (infile == NULL)
418  BIO_set_fp(in,stdin,BIO_NOCLOSE);
419  else
420  {
421  if (BIO_read_filename(in,infile) <= 0)
422  {
423  perror(infile);
424  goto end;
425  }
426  }
427  if (format == FORMAT_ASN1)
428  x=d2i_X509_CRL_bio(in,NULL);
429  else if (format == FORMAT_PEM)
430  x=PEM_read_bio_X509_CRL(in,NULL,NULL,NULL);
431  else {
432  BIO_printf(bio_err,"bad input format specified for input crl\n");
433  goto end;
434  }
435  if (x == NULL)
436  {
437  BIO_printf(bio_err,"unable to load CRL\n");
439  goto end;
440  }
441 
442 end:
443  BIO_free(in);
444  return(x);
445  }
446