Branch data Line data Source code
1 : : /* apps/crl.c */
2 : : /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 : : * All rights reserved.
4 : : *
5 : : * This package is an SSL implementation written
6 : : * by Eric Young (eay@cryptsoft.com).
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 (tjh@cryptsoft.com).
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 (eay@cryptsoft.com)"
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 (tjh@cryptsoft.com)"
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 : : #ifndef OPENSSL_NO_MD5
85 : : " -hash_old - print old-style (MD5) hash value\n",
86 : : #endif
87 : : " -fingerprint - print the crl fingerprint\n",
88 : : " -issuer - print issuer DN\n",
89 : : " -lastupdate - lastUpdate field\n",
90 : : " -nextupdate - nextUpdate field\n",
91 : : " -crlnumber - print CRL number\n",
92 : : " -noout - no CRL output\n",
93 : : " -CAfile name - verify CRL using certificates in file \"name\"\n",
94 : : " -CApath dir - verify CRL using certificates in \"dir\"\n",
95 : : " -nameopt arg - various certificate name options\n",
96 : : NULL
97 : : };
98 : :
99 : : static BIO *bio_out=NULL;
100 : :
101 : : int MAIN(int, char **);
102 : :
103 : 6 : int MAIN(int argc, char **argv)
104 : : {
105 : 6 : unsigned long nmflag = 0;
106 : 6 : X509_CRL *x=NULL;
107 : 6 : char *CAfile = NULL, *CApath = NULL;
108 : 6 : int ret=1,i,num,badops=0,badsig=0;
109 : 6 : BIO *out=NULL;
110 : : int informat,outformat, keyformat;
111 : 6 : char *infile=NULL,*outfile=NULL, *crldiff = NULL, *keyfile = NULL;
112 : 6 : int hash=0,issuer=0,lastupdate=0,nextupdate=0,noout=0,text=0;
113 : : #ifndef OPENSSL_NO_MD5
114 : 6 : int hash_old=0;
115 : : #endif
116 : 6 : int fingerprint = 0, crlnumber = 0;
117 : : const char **pp;
118 : 6 : X509_STORE *store = NULL;
119 : : X509_STORE_CTX ctx;
120 : 6 : X509_LOOKUP *lookup = NULL;
121 : : X509_OBJECT xobj;
122 : : EVP_PKEY *pkey;
123 : 6 : int do_ver = 0;
124 : 6 : const EVP_MD *md_alg,*digest=EVP_sha1();
125 : :
126 : 6 : apps_startup();
127 : :
128 [ - + ]: 6 : if (bio_err == NULL)
129 [ # # ]: 0 : if ((bio_err=BIO_new(BIO_s_file())) != NULL)
130 : 0 : BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
131 : :
132 [ + - ]: 6 : if (!load_config(bio_err, NULL))
133 : : goto end;
134 : :
135 [ + - ]: 6 : if (bio_out == NULL)
136 [ + - ]: 6 : if ((bio_out=BIO_new(BIO_s_file())) != NULL)
137 : : {
138 : 6 : BIO_set_fp(bio_out,stdout,BIO_NOCLOSE);
139 : : #ifdef OPENSSL_SYS_VMS
140 : : {
141 : : BIO *tmpbio = BIO_new(BIO_f_linebuffer());
142 : : bio_out = BIO_push(tmpbio, bio_out);
143 : : }
144 : : #endif
145 : : }
146 : :
147 : 6 : informat=FORMAT_PEM;
148 : 6 : outformat=FORMAT_PEM;
149 : 6 : keyformat=FORMAT_PEM;
150 : :
151 : 6 : argc--;
152 : 6 : argv++;
153 : 6 : num=0;
154 [ + + ]: 24 : while (argc >= 1)
155 : : {
156 : : #ifdef undef
157 : : if (strcmp(*argv,"-p") == 0)
158 : : {
159 : : if (--argc < 1) goto bad;
160 : : if (!args_from_file(++argv,Nargc,Nargv)) { goto end; }*/
161 : : }
162 : : #endif
163 [ + + ]: 18 : if (strcmp(*argv,"-inform") == 0)
164 : : {
165 [ + - ]: 6 : if (--argc < 1) goto bad;
166 : 6 : informat=str2fmt(*(++argv));
167 : : }
168 [ + + ]: 12 : else if (strcmp(*argv,"-outform") == 0)
169 : : {
170 [ - + ]: 6 : if (--argc < 1) goto bad;
171 : 6 : outformat=str2fmt(*(++argv));
172 : : }
173 [ + - ]: 6 : else if (strcmp(*argv,"-in") == 0)
174 : : {
175 [ - + ]: 6 : if (--argc < 1) goto bad;
176 : 6 : infile= *(++argv);
177 : : }
178 [ # # ]: 0 : else if (strcmp(*argv,"-gendelta") == 0)
179 : : {
180 [ # # ]: 0 : if (--argc < 1) goto bad;
181 : 0 : crldiff= *(++argv);
182 : : }
183 [ # # ]: 0 : else if (strcmp(*argv,"-key") == 0)
184 : : {
185 [ # # ]: 0 : if (--argc < 1) goto bad;
186 : 0 : keyfile= *(++argv);
187 : : }
188 [ # # ]: 0 : else if (strcmp(*argv,"-keyform") == 0)
189 : : {
190 [ # # ]: 0 : if (--argc < 1) goto bad;
191 : 0 : keyformat=str2fmt(*(++argv));
192 : : }
193 [ # # ]: 0 : else if (strcmp(*argv,"-out") == 0)
194 : : {
195 [ # # ]: 0 : if (--argc < 1) goto bad;
196 : 0 : outfile= *(++argv);
197 : : }
198 [ # # ]: 0 : else if (strcmp(*argv,"-CApath") == 0)
199 : : {
200 [ # # ]: 0 : if (--argc < 1) goto bad;
201 : 0 : CApath = *(++argv);
202 : 0 : do_ver = 1;
203 : : }
204 [ # # ]: 0 : else if (strcmp(*argv,"-CAfile") == 0)
205 : : {
206 [ # # ]: 0 : if (--argc < 1) goto bad;
207 : 0 : CAfile = *(++argv);
208 : 0 : do_ver = 1;
209 : : }
210 [ # # ]: 0 : else if (strcmp(*argv,"-verify") == 0)
211 : : do_ver = 1;
212 [ # # ]: 0 : else if (strcmp(*argv,"-text") == 0)
213 : : text = 1;
214 [ # # ]: 0 : else if (strcmp(*argv,"-hash") == 0)
215 : 0 : hash= ++num;
216 : : #ifndef OPENSSL_NO_MD5
217 [ # # ]: 0 : else if (strcmp(*argv,"-hash_old") == 0)
218 : 0 : hash_old= ++num;
219 : : #endif
220 [ # # ]: 0 : else if (strcmp(*argv,"-nameopt") == 0)
221 : : {
222 [ # # ]: 0 : if (--argc < 1) goto bad;
223 [ # # ]: 0 : if (!set_name_ex(&nmflag, *(++argv))) goto bad;
224 : : }
225 [ # # ]: 0 : else if (strcmp(*argv,"-issuer") == 0)
226 : 0 : issuer= ++num;
227 [ # # ]: 0 : else if (strcmp(*argv,"-lastupdate") == 0)
228 : 0 : lastupdate= ++num;
229 [ # # ]: 0 : else if (strcmp(*argv,"-nextupdate") == 0)
230 : 0 : nextupdate= ++num;
231 [ # # ]: 0 : else if (strcmp(*argv,"-noout") == 0)
232 : 0 : noout= ++num;
233 [ # # ]: 0 : else if (strcmp(*argv,"-fingerprint") == 0)
234 : 0 : fingerprint= ++num;
235 [ # # ]: 0 : else if (strcmp(*argv,"-crlnumber") == 0)
236 : 0 : crlnumber= ++num;
237 [ # # ]: 0 : else if (strcmp(*argv,"-badsig") == 0)
238 : : badsig = 1;
239 [ # # ]: 0 : else if ((md_alg=EVP_get_digestbyname(*argv + 1)))
240 : : {
241 : : /* ok */
242 : : digest=md_alg;
243 : : }
244 : : else
245 : : {
246 : 0 : BIO_printf(bio_err,"unknown option %s\n",*argv);
247 : 0 : badops=1;
248 : 0 : break;
249 : : }
250 : 18 : argc--;
251 : 18 : argv++;
252 : : }
253 : :
254 [ - + ]: 6 : if (badops)
255 : : {
256 : : bad:
257 [ # # ]: 0 : for (pp=crl_usage; (*pp != NULL); pp++)
258 : 0 : BIO_printf(bio_err,"%s",*pp);
259 : : goto end;
260 : : }
261 : :
262 : 6 : ERR_load_crypto_strings();
263 : 6 : x=load_crl(infile,informat);
264 [ + - ]: 6 : if (x == NULL) { goto end; }
265 : :
266 [ - + ]: 6 : if(do_ver) {
267 : 0 : store = X509_STORE_new();
268 : 0 : lookup=X509_STORE_add_lookup(store,X509_LOOKUP_file());
269 [ # # ]: 0 : if (lookup == NULL) goto end;
270 [ # # ]: 0 : if (!X509_LOOKUP_load_file(lookup,CAfile,X509_FILETYPE_PEM))
271 : 0 : X509_LOOKUP_load_file(lookup,NULL,X509_FILETYPE_DEFAULT);
272 : :
273 : 0 : lookup=X509_STORE_add_lookup(store,X509_LOOKUP_hash_dir());
274 [ # # ]: 0 : if (lookup == NULL) goto end;
275 [ # # ]: 0 : if (!X509_LOOKUP_add_dir(lookup,CApath,X509_FILETYPE_PEM))
276 : 0 : X509_LOOKUP_add_dir(lookup,NULL,X509_FILETYPE_DEFAULT);
277 : 0 : ERR_clear_error();
278 : :
279 [ # # ]: 0 : if(!X509_STORE_CTX_init(&ctx, store, NULL, NULL)) {
280 : 0 : BIO_printf(bio_err,
281 : : "Error initialising X509 store\n");
282 : 0 : goto end;
283 : : }
284 : :
285 : 0 : i = X509_STORE_get_by_subject(&ctx, X509_LU_X509,
286 : 0 : X509_CRL_get_issuer(x), &xobj);
287 [ # # ]: 0 : if(i <= 0) {
288 : 0 : BIO_printf(bio_err,
289 : : "Error getting CRL issuer certificate\n");
290 : 0 : goto end;
291 : : }
292 : 0 : pkey = X509_get_pubkey(xobj.data.x509);
293 : 0 : X509_OBJECT_free_contents(&xobj);
294 [ # # ]: 0 : if(!pkey) {
295 : 0 : BIO_printf(bio_err,
296 : : "Error getting CRL issuer public key\n");
297 : 0 : goto end;
298 : : }
299 : 0 : i = X509_CRL_verify(x, pkey);
300 : 0 : EVP_PKEY_free(pkey);
301 [ # # ]: 0 : if(i < 0) goto end;
302 [ # # ]: 0 : if(i == 0) BIO_printf(bio_err, "verify failure\n");
303 : 0 : else BIO_printf(bio_err, "verify OK\n");
304 : : }
305 : :
306 [ - + ]: 6 : if (crldiff)
307 : : {
308 : : X509_CRL *newcrl, *delta;
309 [ # # ]: 0 : if (!keyfile)
310 : : {
311 : 0 : BIO_puts(bio_err, "Missing CRL signing key\n");
312 : 0 : goto end;
313 : : }
314 : 0 : newcrl = load_crl(crldiff,informat);
315 [ # # ]: 0 : if (!newcrl)
316 : : goto end;
317 : 0 : pkey = load_key(bio_err, keyfile, keyformat, 0, NULL, NULL,
318 : : "CRL signing key");
319 [ # # ]: 0 : if (!pkey)
320 : : {
321 : 0 : X509_CRL_free(newcrl);
322 : 0 : goto end;
323 : : }
324 : 0 : delta = X509_CRL_diff(x, newcrl, pkey, digest, 0);
325 : 0 : X509_CRL_free(newcrl);
326 : 0 : EVP_PKEY_free(pkey);
327 [ # # ]: 0 : if (delta)
328 : : {
329 : 0 : X509_CRL_free(x);
330 : 0 : x = delta;
331 : : }
332 : : else
333 : : {
334 : 0 : BIO_puts(bio_err, "Error creating delta CRL\n");
335 : 0 : goto end;
336 : : }
337 : : }
338 : :
339 [ - + ]: 6 : if (num)
340 : : {
341 [ # # ]: 0 : for (i=1; i<=num; i++)
342 : : {
343 [ # # ]: 0 : if (issuer == i)
344 : : {
345 : 0 : print_name(bio_out, "issuer=", X509_CRL_get_issuer(x), nmflag);
346 : : }
347 [ # # ]: 0 : if (crlnumber == i)
348 : : {
349 : : ASN1_INTEGER *crlnum;
350 : 0 : crlnum = X509_CRL_get_ext_d2i(x, NID_crl_number,
351 : : NULL, NULL);
352 : 0 : BIO_printf(bio_out,"crlNumber=");
353 [ # # ]: 0 : if (crlnum)
354 : : {
355 : 0 : i2a_ASN1_INTEGER(bio_out, crlnum);
356 : 0 : ASN1_INTEGER_free(crlnum);
357 : : }
358 : : else
359 : 0 : BIO_puts(bio_out, "<NONE>");
360 : 0 : BIO_printf(bio_out,"\n");
361 : : }
362 [ # # ]: 0 : if (hash == i)
363 : : {
364 : 0 : BIO_printf(bio_out,"%08lx\n",
365 : 0 : X509_NAME_hash(X509_CRL_get_issuer(x)));
366 : : }
367 : : #ifndef OPENSSL_NO_MD5
368 [ # # ]: 0 : if (hash_old == i)
369 : : {
370 : 0 : BIO_printf(bio_out,"%08lx\n",
371 : : X509_NAME_hash_old(
372 : 0 : X509_CRL_get_issuer(x)));
373 : : }
374 : : #endif
375 [ # # ]: 0 : if (lastupdate == i)
376 : : {
377 : 0 : BIO_printf(bio_out,"lastUpdate=");
378 : 0 : ASN1_TIME_print(bio_out,
379 : 0 : X509_CRL_get_lastUpdate(x));
380 : 0 : BIO_printf(bio_out,"\n");
381 : : }
382 [ # # ]: 0 : if (nextupdate == i)
383 : : {
384 : 0 : BIO_printf(bio_out,"nextUpdate=");
385 [ # # ]: 0 : if (X509_CRL_get_nextUpdate(x))
386 : 0 : ASN1_TIME_print(bio_out,
387 : : X509_CRL_get_nextUpdate(x));
388 : : else
389 : 0 : BIO_printf(bio_out,"NONE");
390 : 0 : BIO_printf(bio_out,"\n");
391 : : }
392 [ # # ]: 0 : if (fingerprint == i)
393 : : {
394 : : int j;
395 : : unsigned int n;
396 : : unsigned char md[EVP_MAX_MD_SIZE];
397 : :
398 [ # # ]: 0 : if (!X509_CRL_digest(x,digest,md,&n))
399 : : {
400 : 0 : BIO_printf(bio_err,"out of memory\n");
401 : 0 : goto end;
402 : : }
403 : 0 : BIO_printf(bio_out,"%s Fingerprint=",
404 : : OBJ_nid2sn(EVP_MD_type(digest)));
405 [ # # ]: 0 : for (j=0; j<(int)n; j++)
406 : : {
407 [ # # ]: 0 : BIO_printf(bio_out,"%02X%c",md[j],
408 : 0 : (j+1 == (int)n)
409 : : ?'\n':':');
410 : : }
411 : : }
412 : : }
413 : : }
414 : :
415 : 6 : out=BIO_new(BIO_s_file());
416 [ - + ]: 6 : if (out == NULL)
417 : : {
418 : 0 : ERR_print_errors(bio_err);
419 : 0 : goto end;
420 : : }
421 : :
422 [ + - ]: 6 : if (outfile == NULL)
423 : : {
424 : 6 : BIO_set_fp(out,stdout,BIO_NOCLOSE);
425 : : #ifdef OPENSSL_SYS_VMS
426 : : {
427 : : BIO *tmpbio = BIO_new(BIO_f_linebuffer());
428 : : out = BIO_push(tmpbio, out);
429 : : }
430 : : #endif
431 : : }
432 : : else
433 : : {
434 [ # # ]: 0 : if (BIO_write_filename(out,outfile) <= 0)
435 : : {
436 : 0 : perror(outfile);
437 : 0 : goto end;
438 : : }
439 : : }
440 : :
441 [ - + ]: 6 : if (text) X509_CRL_print(out, x);
442 : :
443 [ + - ]: 6 : if (noout)
444 : : {
445 : : ret = 0;
446 : : goto end;
447 : : }
448 : :
449 [ - + ]: 6 : if (badsig)
450 : 0 : x->signature->data[x->signature->length - 1] ^= 0x1;
451 : :
452 [ + + ]: 6 : if (outformat == FORMAT_ASN1)
453 : 3 : i=(int)i2d_X509_CRL_bio(out,x);
454 [ + - ]: 3 : else if (outformat == FORMAT_PEM)
455 : 3 : i=PEM_write_bio_X509_CRL(out,x);
456 : : else
457 : : {
458 : 0 : BIO_printf(bio_err,"bad output format specified for outfile\n");
459 : 0 : goto end;
460 : : }
461 [ - + ]: 6 : if (!i) { BIO_printf(bio_err,"unable to write CRL\n"); goto end; }
462 : : ret=0;
463 : : end:
464 [ - + ]: 6 : if (ret != 0)
465 : 0 : ERR_print_errors(bio_err);
466 : 6 : BIO_free_all(out);
467 : 6 : BIO_free_all(bio_out);
468 : 6 : bio_out=NULL;
469 : 6 : X509_CRL_free(x);
470 [ - + ]: 6 : if(store) {
471 : 0 : X509_STORE_CTX_cleanup(&ctx);
472 : 0 : X509_STORE_free(store);
473 : : }
474 : : apps_shutdown();
475 : 6 : OPENSSL_EXIT(ret);
476 : : }
|