source: trunk/third/openssl/apps/crl.c @ 18442

Revision 18442, 10.9 KB checked in by zacheiss, 21 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r18441, which included commits to RCS files with non-trunk default branches.
Line 
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
75static 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" -issuer         - print issuer DN\n",
85" -lastupdate     - lastUpdate field\n",
86" -nextupdate     - nextUpdate field\n",
87" -noout          - no CRL output\n",
88" -CAfile  name   - verify CRL using certificates in file \"name\"\n",
89" -CApath  dir    - verify CRL using certificates in \"dir\"\n",
90" -nameopt arg    - various certificate name options\n",
91NULL
92};
93
94static X509_CRL *load_crl(char *file, int format);
95static BIO *bio_out=NULL;
96
97int MAIN(int, char **);
98
99int MAIN(int argc, char **argv)
100        {
101        unsigned long nmflag = 0;
102        X509_CRL *x=NULL;
103        char *CAfile = NULL, *CApath = NULL;
104        int ret=1,i,num,badops=0;
105        BIO *out=NULL;
106        int informat,outformat;
107        char *infile=NULL,*outfile=NULL;
108        int hash=0,issuer=0,lastupdate=0,nextupdate=0,noout=0,text=0;
109        int fingerprint = 0;
110        char **pp;
111        X509_STORE *store = NULL;
112        X509_STORE_CTX ctx;
113        X509_LOOKUP *lookup = NULL;
114        X509_OBJECT xobj;
115        EVP_PKEY *pkey;
116        int do_ver = 0;
117        const EVP_MD *md_alg,*digest=EVP_md5();
118
119        apps_startup();
120
121        if (bio_err == NULL)
122                if ((bio_err=BIO_new(BIO_s_file())) != NULL)
123                        BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
124
125        if (!load_config(bio_err, NULL))
126                goto end;
127
128        if (bio_out == NULL)
129                if ((bio_out=BIO_new(BIO_s_file())) != NULL)
130                        {
131                        BIO_set_fp(bio_out,stdout,BIO_NOCLOSE);
132#ifdef OPENSSL_SYS_VMS
133                        {
134                        BIO *tmpbio = BIO_new(BIO_f_linebuffer());
135                        bio_out = BIO_push(tmpbio, bio_out);
136                        }
137#endif
138                        }
139
140        informat=FORMAT_PEM;
141        outformat=FORMAT_PEM;
142
143        argc--;
144        argv++;
145        num=0;
146        while (argc >= 1)
147                {
148#ifdef undef
149                if      (strcmp(*argv,"-p") == 0)
150                        {
151                        if (--argc < 1) goto bad;
152                        if (!args_from_file(++argv,Nargc,Nargv)) { goto end; }*/
153                        }
154#endif
155                if      (strcmp(*argv,"-inform") == 0)
156                        {
157                        if (--argc < 1) goto bad;
158                        informat=str2fmt(*(++argv));
159                        }
160                else if (strcmp(*argv,"-outform") == 0)
161                        {
162                        if (--argc < 1) goto bad;
163                        outformat=str2fmt(*(++argv));
164                        }
165                else if (strcmp(*argv,"-in") == 0)
166                        {
167                        if (--argc < 1) goto bad;
168                        infile= *(++argv);
169                        }
170                else if (strcmp(*argv,"-out") == 0)
171                        {
172                        if (--argc < 1) goto bad;
173                        outfile= *(++argv);
174                        }
175                else if (strcmp(*argv,"-CApath") == 0)
176                        {
177                        if (--argc < 1) goto bad;
178                        CApath = *(++argv);
179                        do_ver = 1;
180                        }
181                else if (strcmp(*argv,"-CAfile") == 0)
182                        {
183                        if (--argc < 1) goto bad;
184                        CAfile = *(++argv);
185                        do_ver = 1;
186                        }
187                else if (strcmp(*argv,"-verify") == 0)
188                        do_ver = 1;
189                else if (strcmp(*argv,"-text") == 0)
190                        text = 1;
191                else if (strcmp(*argv,"-hash") == 0)
192                        hash= ++num;
193                else if (strcmp(*argv,"-nameopt") == 0)
194                        {
195                        if (--argc < 1) goto bad;
196                        if (!set_name_ex(&nmflag, *(++argv))) goto bad;
197                        }
198                else if (strcmp(*argv,"-issuer") == 0)
199                        issuer= ++num;
200                else if (strcmp(*argv,"-lastupdate") == 0)
201                        lastupdate= ++num;
202                else if (strcmp(*argv,"-nextupdate") == 0)
203                        nextupdate= ++num;
204                else if (strcmp(*argv,"-noout") == 0)
205                        noout= ++num;
206                else if (strcmp(*argv,"-fingerprint") == 0)
207                        fingerprint= ++num;
208                else if ((md_alg=EVP_get_digestbyname(*argv + 1)))
209                        {
210                        /* ok */
211                        digest=md_alg;
212                        }
213                else
214                        {
215                        BIO_printf(bio_err,"unknown option %s\n",*argv);
216                        badops=1;
217                        break;
218                        }
219                argc--;
220                argv++;
221                }
222
223        if (badops)
224                {
225bad:
226                for (pp=crl_usage; (*pp != NULL); pp++)
227                        BIO_printf(bio_err,"%s",*pp);
228                goto end;
229                }
230
231        ERR_load_crypto_strings();
232        x=load_crl(infile,informat);
233        if (x == NULL) { goto end; }
234
235        if(do_ver) {
236                store = X509_STORE_new();
237                lookup=X509_STORE_add_lookup(store,X509_LOOKUP_file());
238                if (lookup == NULL) goto end;
239                if (!X509_LOOKUP_load_file(lookup,CAfile,X509_FILETYPE_PEM))
240                        X509_LOOKUP_load_file(lookup,NULL,X509_FILETYPE_DEFAULT);
241                       
242                lookup=X509_STORE_add_lookup(store,X509_LOOKUP_hash_dir());
243                if (lookup == NULL) goto end;
244                if (!X509_LOOKUP_add_dir(lookup,CApath,X509_FILETYPE_PEM))
245                        X509_LOOKUP_add_dir(lookup,NULL,X509_FILETYPE_DEFAULT);
246                ERR_clear_error();
247
248                if(!X509_STORE_CTX_init(&ctx, store, NULL, NULL)) {
249                        BIO_printf(bio_err,
250                                "Error initialising X509 store\n");
251                        goto end;
252                }
253
254                i = X509_STORE_get_by_subject(&ctx, X509_LU_X509,
255                                        X509_CRL_get_issuer(x), &xobj);
256                if(i <= 0) {
257                        BIO_printf(bio_err,
258                                "Error getting CRL issuer certificate\n");
259                        goto end;
260                }
261                pkey = X509_get_pubkey(xobj.data.x509);
262                X509_OBJECT_free_contents(&xobj);
263                if(!pkey) {
264                        BIO_printf(bio_err,
265                                "Error getting CRL issuer public key\n");
266                        goto end;
267                }
268                i = X509_CRL_verify(x, pkey);
269                EVP_PKEY_free(pkey);
270                if(i < 0) goto end;
271                if(i == 0) BIO_printf(bio_err, "verify failure\n");
272                else BIO_printf(bio_err, "verify OK\n");
273        }
274
275        if (num)
276                {
277                for (i=1; i<=num; i++)
278                        {
279                        if (issuer == i)
280                                {
281                                print_name(bio_out, "issuer=", X509_CRL_get_issuer(x), nmflag);
282                                }
283
284                        if (hash == i)
285                                {
286                                BIO_printf(bio_out,"%08lx\n",
287                                        X509_NAME_hash(X509_CRL_get_issuer(x)));
288                                }
289                        if (lastupdate == i)
290                                {
291                                BIO_printf(bio_out,"lastUpdate=");
292                                ASN1_TIME_print(bio_out,
293                                                X509_CRL_get_lastUpdate(x));
294                                BIO_printf(bio_out,"\n");
295                                }
296                        if (nextupdate == i)
297                                {
298                                BIO_printf(bio_out,"nextUpdate=");
299                                if (X509_CRL_get_nextUpdate(x))
300                                        ASN1_TIME_print(bio_out,
301                                                X509_CRL_get_nextUpdate(x));
302                                else
303                                        BIO_printf(bio_out,"NONE");
304                                BIO_printf(bio_out,"\n");
305                                }
306                        if (fingerprint == i)
307                                {
308                                int j;
309                                unsigned int n;
310                                unsigned char md[EVP_MAX_MD_SIZE];
311
312                                if (!X509_CRL_digest(x,digest,md,&n))
313                                        {
314                                        BIO_printf(bio_err,"out of memory\n");
315                                        goto end;
316                                        }
317                                BIO_printf(bio_out,"%s Fingerprint=",
318                                                OBJ_nid2sn(EVP_MD_type(digest)));
319                                for (j=0; j<(int)n; j++)
320                                        {
321                                        BIO_printf(bio_out,"%02X%c",md[j],
322                                                (j+1 == (int)n)
323                                                ?'\n':':');
324                                        }
325                                }
326                        }
327                }
328
329        out=BIO_new(BIO_s_file());
330        if (out == NULL)
331                {
332                ERR_print_errors(bio_err);
333                goto end;
334                }
335
336        if (outfile == NULL)
337                {
338                BIO_set_fp(out,stdout,BIO_NOCLOSE);
339#ifdef OPENSSL_SYS_VMS
340                {
341                BIO *tmpbio = BIO_new(BIO_f_linebuffer());
342                out = BIO_push(tmpbio, out);
343                }
344#endif
345                }
346        else
347                {
348                if (BIO_write_filename(out,outfile) <= 0)
349                        {
350                        perror(outfile);
351                        goto end;
352                        }
353                }
354
355        if (text) X509_CRL_print(out, x);
356
357        if (noout) goto end;
358
359        if      (outformat == FORMAT_ASN1)
360                i=(int)i2d_X509_CRL_bio(out,x);
361        else if (outformat == FORMAT_PEM)
362                i=PEM_write_bio_X509_CRL(out,x);
363        else   
364                {
365                BIO_printf(bio_err,"bad output format specified for outfile\n");
366                goto end;
367                }
368        if (!i) { BIO_printf(bio_err,"unable to write CRL\n"); goto end; }
369        ret=0;
370end:
371        BIO_free_all(out);
372        BIO_free_all(bio_out);
373        bio_out=NULL;
374        X509_CRL_free(x);
375        if(store) {
376                X509_STORE_CTX_cleanup(&ctx);
377                X509_STORE_free(store);
378        }
379        apps_shutdown();
380        OPENSSL_EXIT(ret);
381        }
382
383static X509_CRL *load_crl(char *infile, int format)
384        {
385        X509_CRL *x=NULL;
386        BIO *in=NULL;
387
388        in=BIO_new(BIO_s_file());
389        if (in == NULL)
390                {
391                ERR_print_errors(bio_err);
392                goto end;
393                }
394
395        if (infile == NULL)
396                BIO_set_fp(in,stdin,BIO_NOCLOSE);
397        else
398                {
399                if (BIO_read_filename(in,infile) <= 0)
400                        {
401                        perror(infile);
402                        goto end;
403                        }
404                }
405        if      (format == FORMAT_ASN1)
406                x=d2i_X509_CRL_bio(in,NULL);
407        else if (format == FORMAT_PEM)
408                x=PEM_read_bio_X509_CRL(in,NULL,NULL,NULL);
409        else    {
410                BIO_printf(bio_err,"bad input format specified for input crl\n");
411                goto end;
412                }
413        if (x == NULL)
414                {
415                BIO_printf(bio_err,"unable to load CRL\n");
416                ERR_print_errors(bio_err);
417                goto end;
418                }
419       
420end:
421        BIO_free(in);
422        return(x);
423        }
424
Note: See TracBrowser for help on using the repository browser.