1*e7718adaStb /* $OpenBSD: crl.c,v 1.17 2023/03/06 14:32:05 tb Exp $ */
2dab3f910Sjsing /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3dab3f910Sjsing * All rights reserved.
4dab3f910Sjsing *
5dab3f910Sjsing * This package is an SSL implementation written
6dab3f910Sjsing * by Eric Young (eay@cryptsoft.com).
7dab3f910Sjsing * The implementation was written so as to conform with Netscapes SSL.
8dab3f910Sjsing *
9dab3f910Sjsing * This library is free for commercial and non-commercial use as long as
10dab3f910Sjsing * the following conditions are aheared to. The following conditions
11dab3f910Sjsing * apply to all code found in this distribution, be it the RC4, RSA,
12dab3f910Sjsing * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13dab3f910Sjsing * included with this distribution is covered by the same copyright terms
14dab3f910Sjsing * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15dab3f910Sjsing *
16dab3f910Sjsing * Copyright remains Eric Young's, and as such any Copyright notices in
17dab3f910Sjsing * the code are not to be removed.
18dab3f910Sjsing * If this package is used in a product, Eric Young should be given attribution
19dab3f910Sjsing * as the author of the parts of the library used.
20dab3f910Sjsing * This can be in the form of a textual message at program startup or
21dab3f910Sjsing * in documentation (online or textual) provided with the package.
22dab3f910Sjsing *
23dab3f910Sjsing * Redistribution and use in source and binary forms, with or without
24dab3f910Sjsing * modification, are permitted provided that the following conditions
25dab3f910Sjsing * are met:
26dab3f910Sjsing * 1. Redistributions of source code must retain the copyright
27dab3f910Sjsing * notice, this list of conditions and the following disclaimer.
28dab3f910Sjsing * 2. Redistributions in binary form must reproduce the above copyright
29dab3f910Sjsing * notice, this list of conditions and the following disclaimer in the
30dab3f910Sjsing * documentation and/or other materials provided with the distribution.
31dab3f910Sjsing * 3. All advertising materials mentioning features or use of this software
32dab3f910Sjsing * must display the following acknowledgement:
33dab3f910Sjsing * "This product includes cryptographic software written by
34dab3f910Sjsing * Eric Young (eay@cryptsoft.com)"
35dab3f910Sjsing * The word 'cryptographic' can be left out if the rouines from the library
36dab3f910Sjsing * being used are not cryptographic related :-).
37dab3f910Sjsing * 4. If you include any Windows specific code (or a derivative thereof) from
38dab3f910Sjsing * the apps directory (application code) you must include an acknowledgement:
39dab3f910Sjsing * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40dab3f910Sjsing *
41dab3f910Sjsing * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42dab3f910Sjsing * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43dab3f910Sjsing * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44dab3f910Sjsing * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45dab3f910Sjsing * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46dab3f910Sjsing * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47dab3f910Sjsing * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48dab3f910Sjsing * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49dab3f910Sjsing * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50dab3f910Sjsing * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51dab3f910Sjsing * SUCH DAMAGE.
52dab3f910Sjsing *
53dab3f910Sjsing * The licence and distribution terms for any publically available version or
54dab3f910Sjsing * derivative of this code cannot be changed. i.e. this code cannot simply be
55dab3f910Sjsing * copied and put under another distribution licence
56dab3f910Sjsing * [including the GNU Public Licence.]
57dab3f910Sjsing */
58dab3f910Sjsing
59dab3f910Sjsing #include <stdio.h>
60dab3f910Sjsing #include <stdlib.h>
61dab3f910Sjsing #include <string.h>
62dab3f910Sjsing
63dab3f910Sjsing #include "apps.h"
64dab3f910Sjsing
65dab3f910Sjsing #include <openssl/bio.h>
66dab3f910Sjsing #include <openssl/err.h>
67dab3f910Sjsing #include <openssl/pem.h>
68dab3f910Sjsing #include <openssl/x509.h>
69dab3f910Sjsing #include <openssl/x509v3.h>
70dab3f910Sjsing
71017236d2Sjsing static struct {
72017236d2Sjsing char *cafile;
73017236d2Sjsing char *capath;
74017236d2Sjsing int crlnumber;
75017236d2Sjsing int fingerprint;
76017236d2Sjsing int hash;
77017236d2Sjsing int hash_old;
78017236d2Sjsing char *infile;
79017236d2Sjsing int informat;
80017236d2Sjsing int issuer;
81017236d2Sjsing int lastupdate;
82017236d2Sjsing char *nameopt;
83017236d2Sjsing int nextupdate;
84017236d2Sjsing int noout;
85017236d2Sjsing char *outfile;
86017236d2Sjsing int outformat;
87017236d2Sjsing int text;
88017236d2Sjsing int verify;
89*e7718adaStb } cfg;
90017236d2Sjsing
91ea149709Sguenther static const struct option crl_options[] = {
92017236d2Sjsing {
93017236d2Sjsing .name = "CAfile",
94017236d2Sjsing .argname = "file",
95017236d2Sjsing .desc = "Verify the CRL using certificates in the given file",
96017236d2Sjsing .type = OPTION_ARG,
97*e7718adaStb .opt.arg = &cfg.cafile,
98017236d2Sjsing },
99017236d2Sjsing {
100017236d2Sjsing .name = "CApath",
101017236d2Sjsing .argname = "path",
102017236d2Sjsing .desc = "Verify the CRL using certificates in the given path",
103017236d2Sjsing .type = OPTION_ARG,
104*e7718adaStb .opt.arg = &cfg.capath,
105017236d2Sjsing },
106017236d2Sjsing {
107017236d2Sjsing .name = "crlnumber",
108017236d2Sjsing .desc = "Print the CRL number",
109017236d2Sjsing .type = OPTION_FLAG_ORD,
110*e7718adaStb .opt.flag = &cfg.crlnumber,
111017236d2Sjsing },
112017236d2Sjsing {
113017236d2Sjsing .name = "fingerprint",
114017236d2Sjsing .desc = "Print the CRL fingerprint",
115017236d2Sjsing .type = OPTION_FLAG_ORD,
116*e7718adaStb .opt.flag = &cfg.fingerprint,
117017236d2Sjsing },
118017236d2Sjsing {
119017236d2Sjsing .name = "hash",
120017236d2Sjsing .desc = "Print the hash of the issuer name",
121017236d2Sjsing .type = OPTION_FLAG_ORD,
122*e7718adaStb .opt.flag = &cfg.hash,
123017236d2Sjsing },
124017236d2Sjsing {
125017236d2Sjsing .name = "hash_old",
126017236d2Sjsing .desc = "Print an old-style (MD5) hash of the issuer name",
127017236d2Sjsing .type = OPTION_FLAG_ORD,
128*e7718adaStb .opt.flag = &cfg.hash_old,
129017236d2Sjsing },
130017236d2Sjsing {
131017236d2Sjsing .name = "in",
132017236d2Sjsing .argname = "file",
133017236d2Sjsing .desc = "Input file to read from (stdin if unspecified)",
134017236d2Sjsing .type = OPTION_ARG,
135*e7718adaStb .opt.arg = &cfg.infile,
136017236d2Sjsing },
137017236d2Sjsing {
138017236d2Sjsing .name = "inform",
139017236d2Sjsing .argname = "format",
140017236d2Sjsing .desc = "Input format (DER or PEM)",
141017236d2Sjsing .type = OPTION_ARG_FORMAT,
142*e7718adaStb .opt.value = &cfg.informat,
143017236d2Sjsing },
144017236d2Sjsing {
145017236d2Sjsing .name = "issuer",
146017236d2Sjsing .desc = "Print the issuer name",
147017236d2Sjsing .type = OPTION_FLAG_ORD,
148*e7718adaStb .opt.flag = &cfg.issuer,
149017236d2Sjsing },
150017236d2Sjsing {
151017236d2Sjsing .name = "lastupdate",
152017236d2Sjsing .desc = "Print the lastUpdate field",
153017236d2Sjsing .type = OPTION_FLAG_ORD,
154*e7718adaStb .opt.flag = &cfg.lastupdate,
155017236d2Sjsing },
156017236d2Sjsing {
157017236d2Sjsing .name = "nameopt",
158017236d2Sjsing .argname = "options",
159017236d2Sjsing .desc = "Specify certificate name options",
160017236d2Sjsing .type = OPTION_ARG,
161*e7718adaStb .opt.arg = &cfg.nameopt,
162017236d2Sjsing },
163017236d2Sjsing {
164017236d2Sjsing .name = "nextupdate",
165017236d2Sjsing .desc = "Print the nextUpdate field",
166017236d2Sjsing .type = OPTION_FLAG_ORD,
167*e7718adaStb .opt.flag = &cfg.nextupdate,
168017236d2Sjsing },
169017236d2Sjsing {
170017236d2Sjsing .name = "noout",
171017236d2Sjsing .desc = "Do not output the encoded version of the CRL",
172017236d2Sjsing .type = OPTION_FLAG,
173*e7718adaStb .opt.flag = &cfg.noout,
174017236d2Sjsing },
175017236d2Sjsing {
176017236d2Sjsing .name = "out",
177017236d2Sjsing .argname = "file",
178017236d2Sjsing .desc = "Output file to write to (stdout if unspecified)",
179017236d2Sjsing .type = OPTION_ARG,
180*e7718adaStb .opt.arg = &cfg.outfile,
181017236d2Sjsing },
182017236d2Sjsing {
183017236d2Sjsing .name = "outform",
184017236d2Sjsing .argname = "format",
185017236d2Sjsing .desc = "Output format (DER or PEM)",
186017236d2Sjsing .type = OPTION_ARG_FORMAT,
187*e7718adaStb .opt.value = &cfg.outformat,
188017236d2Sjsing },
189017236d2Sjsing {
190017236d2Sjsing .name = "text",
191017236d2Sjsing .desc = "Print out the CRL in text form",
192017236d2Sjsing .type = OPTION_FLAG,
193*e7718adaStb .opt.flag = &cfg.text,
194017236d2Sjsing },
195017236d2Sjsing {
196017236d2Sjsing .name = "verify",
197017236d2Sjsing .desc = "Verify the signature on the CRL",
198017236d2Sjsing .type = OPTION_FLAG,
199*e7718adaStb .opt.flag = &cfg.verify,
200017236d2Sjsing },
201d220e929Sbcook {NULL},
202dab3f910Sjsing };
203dab3f910Sjsing
204017236d2Sjsing static void
crl_usage(void)205017236d2Sjsing crl_usage(void)
206017236d2Sjsing {
207017236d2Sjsing fprintf(stderr,
208017236d2Sjsing "usage: crl [-CAfile file] [-CApath dir] [-fingerprint] [-hash]\n"
209017236d2Sjsing " [-in file] [-inform DER | PEM] [-issuer] [-lastupdate]\n"
210017236d2Sjsing " [-nextupdate] [-noout] [-out file] [-outform DER | PEM]\n"
211017236d2Sjsing " [-text]\n\n");
212017236d2Sjsing options_usage(crl_options);
213017236d2Sjsing }
214017236d2Sjsing
215dab3f910Sjsing static X509_CRL *load_crl(char *file, int format);
216dab3f910Sjsing static BIO *bio_out = NULL;
217dab3f910Sjsing
218dab3f910Sjsing int
crl_main(int argc,char ** argv)219dab3f910Sjsing crl_main(int argc, char **argv)
220dab3f910Sjsing {
221dab3f910Sjsing unsigned long nmflag = 0;
222dab3f910Sjsing X509_CRL *x = NULL;
223017236d2Sjsing int ret = 1, i;
224dab3f910Sjsing BIO *out = NULL;
225dab3f910Sjsing X509_STORE *store = NULL;
22673e19d3eStb X509_STORE_CTX *ctx = NULL;
227dab3f910Sjsing X509_LOOKUP *lookup = NULL;
2283d522683Stb X509_OBJECT *xobj = NULL;
229dab3f910Sjsing EVP_PKEY *pkey;
230017236d2Sjsing const EVP_MD *digest;
231017236d2Sjsing char *digest_name = NULL;
232dab3f910Sjsing
23351811eadSderaadt if (pledge("stdio cpath wpath rpath", NULL) == -1) {
2349bc487adSdoug perror("pledge");
235e370f0eeSdoug exit(1);
236e370f0eeSdoug }
2379bc487adSdoug
238017236d2Sjsing if (bio_out == NULL) {
239dab3f910Sjsing if ((bio_out = BIO_new(BIO_s_file())) != NULL) {
240dab3f910Sjsing BIO_set_fp(bio_out, stdout, BIO_NOCLOSE);
241dab3f910Sjsing }
242017236d2Sjsing }
243dab3f910Sjsing
244020b59f8Sjsg digest = EVP_sha256();
245017236d2Sjsing
246*e7718adaStb memset(&cfg, 0, sizeof(cfg));
247*e7718adaStb cfg.informat = FORMAT_PEM;
248*e7718adaStb cfg.outformat = FORMAT_PEM;
249017236d2Sjsing
250beba0da1Sjsing if (options_parse(argc, argv, crl_options, &digest_name, NULL) != 0) {
251017236d2Sjsing crl_usage();
252017236d2Sjsing goto end;
253017236d2Sjsing }
254017236d2Sjsing
255*e7718adaStb if (cfg.cafile != NULL || cfg.capath != NULL)
256*e7718adaStb cfg.verify = 1;
257017236d2Sjsing
258*e7718adaStb if (cfg.nameopt != NULL) {
259*e7718adaStb if (set_name_ex(&nmflag, cfg.nameopt) != 1) {
260017236d2Sjsing fprintf(stderr,
261017236d2Sjsing "Invalid -nameopt argument '%s'\n",
262*e7718adaStb cfg.nameopt);
263dab3f910Sjsing goto end;
264dab3f910Sjsing }
265dab3f910Sjsing }
266dab3f910Sjsing
267017236d2Sjsing if (digest_name != NULL) {
268017236d2Sjsing if ((digest = EVP_get_digestbyname(digest_name)) == NULL) {
269017236d2Sjsing fprintf(stderr,
270017236d2Sjsing "Unknown message digest algorithm '%s'\n",
271017236d2Sjsing digest_name);
272dab3f910Sjsing goto end;
273dab3f910Sjsing }
274017236d2Sjsing }
275017236d2Sjsing
276*e7718adaStb x = load_crl(cfg.infile, cfg.informat);
277017236d2Sjsing if (x == NULL)
278dab3f910Sjsing goto end;
279017236d2Sjsing
280*e7718adaStb if (cfg.verify) {
281dab3f910Sjsing store = X509_STORE_new();
28273e19d3eStb if (store == NULL)
28373e19d3eStb goto end;
284dab3f910Sjsing lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file());
285dab3f910Sjsing if (lookup == NULL)
286dab3f910Sjsing goto end;
287*e7718adaStb if (!X509_LOOKUP_load_file(lookup, cfg.cafile,
288017236d2Sjsing X509_FILETYPE_PEM))
289dab3f910Sjsing X509_LOOKUP_load_file(lookup, NULL,
290dab3f910Sjsing X509_FILETYPE_DEFAULT);
291dab3f910Sjsing
292dab3f910Sjsing lookup = X509_STORE_add_lookup(store, X509_LOOKUP_hash_dir());
293dab3f910Sjsing if (lookup == NULL)
294dab3f910Sjsing goto end;
295*e7718adaStb if (!X509_LOOKUP_add_dir(lookup, cfg.capath,
296017236d2Sjsing X509_FILETYPE_PEM))
297dab3f910Sjsing X509_LOOKUP_add_dir(lookup, NULL,
298dab3f910Sjsing X509_FILETYPE_DEFAULT);
299dab3f910Sjsing ERR_clear_error();
300dab3f910Sjsing
30173e19d3eStb if ((ctx = X509_STORE_CTX_new()) == NULL)
30273e19d3eStb goto end;
3033d522683Stb if ((xobj = X509_OBJECT_new()) == NULL)
3043d522683Stb goto end;
30573e19d3eStb
30673e19d3eStb if (!X509_STORE_CTX_init(ctx, store, NULL, NULL)) {
307dab3f910Sjsing BIO_printf(bio_err,
308dab3f910Sjsing "Error initialising X509 store\n");
309dab3f910Sjsing goto end;
310dab3f910Sjsing }
31173e19d3eStb i = X509_STORE_get_by_subject(ctx, X509_LU_X509,
3123d522683Stb X509_CRL_get_issuer(x), xobj);
313dab3f910Sjsing if (i <= 0) {
314dab3f910Sjsing BIO_printf(bio_err,
315dab3f910Sjsing "Error getting CRL issuer certificate\n");
316dab3f910Sjsing goto end;
317dab3f910Sjsing }
3183d522683Stb pkey = X509_get_pubkey(X509_OBJECT_get0_X509(xobj));
3193d522683Stb X509_OBJECT_free(xobj);
3203d522683Stb xobj = NULL;
321dab3f910Sjsing if (!pkey) {
322dab3f910Sjsing BIO_printf(bio_err,
323dab3f910Sjsing "Error getting CRL issuer public key\n");
324dab3f910Sjsing goto end;
325dab3f910Sjsing }
326dab3f910Sjsing i = X509_CRL_verify(x, pkey);
327dab3f910Sjsing EVP_PKEY_free(pkey);
328dab3f910Sjsing if (i < 0)
329dab3f910Sjsing goto end;
330dab3f910Sjsing if (i == 0)
331dab3f910Sjsing BIO_printf(bio_err, "verify failure\n");
332dab3f910Sjsing else
333dab3f910Sjsing BIO_printf(bio_err, "verify OK\n");
334dab3f910Sjsing }
335017236d2Sjsing
336017236d2Sjsing /* Print requested information the order that the flags were given. */
337017236d2Sjsing for (i = 1; i <= argc; i++) {
338*e7718adaStb if (cfg.issuer == i) {
339dab3f910Sjsing print_name(bio_out, "issuer=",
340dab3f910Sjsing X509_CRL_get_issuer(x), nmflag);
341dab3f910Sjsing }
342*e7718adaStb if (cfg.crlnumber == i) {
343dab3f910Sjsing ASN1_INTEGER *crlnum;
344dab3f910Sjsing crlnum = X509_CRL_get_ext_d2i(x,
345dab3f910Sjsing NID_crl_number, NULL, NULL);
346dab3f910Sjsing BIO_printf(bio_out, "crlNumber=");
347dab3f910Sjsing if (crlnum) {
348dab3f910Sjsing i2a_ASN1_INTEGER(bio_out, crlnum);
349dab3f910Sjsing ASN1_INTEGER_free(crlnum);
350dab3f910Sjsing } else
351dab3f910Sjsing BIO_puts(bio_out, "<NONE>");
352dab3f910Sjsing BIO_printf(bio_out, "\n");
353dab3f910Sjsing }
354*e7718adaStb if (cfg.hash == i) {
355dab3f910Sjsing BIO_printf(bio_out, "%08lx\n",
356dab3f910Sjsing X509_NAME_hash(X509_CRL_get_issuer(x)));
357dab3f910Sjsing }
358dab3f910Sjsing #ifndef OPENSSL_NO_MD5
359*e7718adaStb if (cfg.hash_old == i) {
360dab3f910Sjsing BIO_printf(bio_out, "%08lx\n",
361dab3f910Sjsing X509_NAME_hash_old(X509_CRL_get_issuer(x)));
362dab3f910Sjsing }
363dab3f910Sjsing #endif
364*e7718adaStb if (cfg.lastupdate == i) {
365dab3f910Sjsing BIO_printf(bio_out, "lastUpdate=");
366dab3f910Sjsing ASN1_TIME_print(bio_out,
367dab3f910Sjsing X509_CRL_get_lastUpdate(x));
368dab3f910Sjsing BIO_printf(bio_out, "\n");
369dab3f910Sjsing }
370*e7718adaStb if (cfg.nextupdate == i) {
371dab3f910Sjsing BIO_printf(bio_out, "nextUpdate=");
372dab3f910Sjsing if (X509_CRL_get_nextUpdate(x))
373dab3f910Sjsing ASN1_TIME_print(bio_out,
374dab3f910Sjsing X509_CRL_get_nextUpdate(x));
375dab3f910Sjsing else
376dab3f910Sjsing BIO_printf(bio_out, "NONE");
377dab3f910Sjsing BIO_printf(bio_out, "\n");
378dab3f910Sjsing }
379*e7718adaStb if (cfg.fingerprint == i) {
380dab3f910Sjsing int j;
381dab3f910Sjsing unsigned int n;
382dab3f910Sjsing unsigned char md[EVP_MAX_MD_SIZE];
383dab3f910Sjsing
384dab3f910Sjsing if (!X509_CRL_digest(x, digest, md, &n)) {
385dab3f910Sjsing BIO_printf(bio_err, "out of memory\n");
386dab3f910Sjsing goto end;
387dab3f910Sjsing }
388dab3f910Sjsing BIO_printf(bio_out, "%s Fingerprint=",
389dab3f910Sjsing OBJ_nid2sn(EVP_MD_type(digest)));
390dab3f910Sjsing for (j = 0; j < (int) n; j++) {
391dab3f910Sjsing BIO_printf(bio_out, "%02X%c", md[j],
392dab3f910Sjsing (j + 1 == (int)n) ? '\n' : ':');
393dab3f910Sjsing }
394dab3f910Sjsing }
395dab3f910Sjsing }
396017236d2Sjsing
397dab3f910Sjsing out = BIO_new(BIO_s_file());
398dab3f910Sjsing if (out == NULL) {
399dab3f910Sjsing ERR_print_errors(bio_err);
400dab3f910Sjsing goto end;
401dab3f910Sjsing }
402*e7718adaStb if (cfg.outfile == NULL) {
403dab3f910Sjsing BIO_set_fp(out, stdout, BIO_NOCLOSE);
404dab3f910Sjsing } else {
405*e7718adaStb if (BIO_write_filename(out, cfg.outfile) <= 0) {
406*e7718adaStb perror(cfg.outfile);
407dab3f910Sjsing goto end;
408dab3f910Sjsing }
409dab3f910Sjsing }
410dab3f910Sjsing
411*e7718adaStb if (cfg.text)
412dab3f910Sjsing X509_CRL_print(out, x);
413dab3f910Sjsing
414*e7718adaStb if (cfg.noout) {
415dab3f910Sjsing ret = 0;
416dab3f910Sjsing goto end;
417dab3f910Sjsing }
418*e7718adaStb if (cfg.outformat == FORMAT_ASN1)
419dab3f910Sjsing i = (int) i2d_X509_CRL_bio(out, x);
420*e7718adaStb else if (cfg.outformat == FORMAT_PEM)
421dab3f910Sjsing i = PEM_write_bio_X509_CRL(out, x);
422dab3f910Sjsing else {
423dab3f910Sjsing BIO_printf(bio_err,
424dab3f910Sjsing "bad output format specified for outfile\n");
425dab3f910Sjsing goto end;
426dab3f910Sjsing }
427dab3f910Sjsing if (!i) {
428dab3f910Sjsing BIO_printf(bio_err, "unable to write CRL\n");
429dab3f910Sjsing goto end;
430dab3f910Sjsing }
431dab3f910Sjsing ret = 0;
432dab3f910Sjsing
433dab3f910Sjsing end:
434dab3f910Sjsing BIO_free_all(out);
435dab3f910Sjsing BIO_free_all(bio_out);
436dab3f910Sjsing bio_out = NULL;
437dab3f910Sjsing X509_CRL_free(x);
43873e19d3eStb X509_STORE_CTX_free(ctx);
439dab3f910Sjsing X509_STORE_free(store);
4403d522683Stb X509_OBJECT_free(xobj);
441dab3f910Sjsing
442dab3f910Sjsing return (ret);
443dab3f910Sjsing }
444dab3f910Sjsing
445dab3f910Sjsing static X509_CRL *
load_crl(char * infile,int format)446dab3f910Sjsing load_crl(char *infile, int format)
447dab3f910Sjsing {
448dab3f910Sjsing X509_CRL *x = NULL;
449dab3f910Sjsing BIO *in = NULL;
450dab3f910Sjsing
451dab3f910Sjsing in = BIO_new(BIO_s_file());
452dab3f910Sjsing if (in == NULL) {
453dab3f910Sjsing ERR_print_errors(bio_err);
454dab3f910Sjsing goto end;
455dab3f910Sjsing }
456dab3f910Sjsing if (infile == NULL)
457dab3f910Sjsing BIO_set_fp(in, stdin, BIO_NOCLOSE);
458dab3f910Sjsing else {
459dab3f910Sjsing if (BIO_read_filename(in, infile) <= 0) {
460dab3f910Sjsing perror(infile);
461dab3f910Sjsing goto end;
462dab3f910Sjsing }
463dab3f910Sjsing }
464dab3f910Sjsing if (format == FORMAT_ASN1)
465dab3f910Sjsing x = d2i_X509_CRL_bio(in, NULL);
466dab3f910Sjsing else if (format == FORMAT_PEM)
467dab3f910Sjsing x = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL);
468dab3f910Sjsing else {
469dab3f910Sjsing BIO_printf(bio_err,
470dab3f910Sjsing "bad input format specified for input crl\n");
471dab3f910Sjsing goto end;
472dab3f910Sjsing }
473dab3f910Sjsing if (x == NULL) {
474dab3f910Sjsing BIO_printf(bio_err, "unable to load CRL\n");
475dab3f910Sjsing ERR_print_errors(bio_err);
476dab3f910Sjsing goto end;
477dab3f910Sjsing }
478dab3f910Sjsing
479dab3f910Sjsing end:
480dab3f910Sjsing BIO_free(in);
481dab3f910Sjsing return (x);
482dab3f910Sjsing }
483