Annotation of src/usr.bin/openssl/crl2p7.c, Revision 1.2
1.2 ! jsing 1: /* $OpenBSD: crl2p7.c,v 1.1 2014/08/26 17:47:24 jsing Exp $ */
1.1 jsing 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: /* This was written by Gordon Chaffee <chaffee@plateau.cs.berkeley.edu>
60: * and donated 'to the cause' along with lots and lots of other fixes to
61: * the library. */
62:
63: #include <sys/types.h>
64:
65: #include <stdio.h>
66: #include <string.h>
67:
68: #include "apps.h"
69:
70: #include <openssl/err.h>
71: #include <openssl/evp.h>
72: #include <openssl/objects.h>
73: #include <openssl/pem.h>
74: #include <openssl/pkcs7.h>
75: #include <openssl/x509.h>
76:
77: static int add_certs_from_file(STACK_OF(X509) * stack, char *certfile);
78:
79: /* -inform arg - input format - default PEM (DER or PEM)
80: * -outform arg - output format - default PEM
81: * -in arg - input file - default stdin
82: * -out arg - output file - default stdout
83: */
84:
85: int crl2pkcs7_main(int, char **);
86:
87: int
88: crl2pkcs7_main(int argc, char **argv)
89: {
90: int i, badops = 0;
91: BIO *in = NULL, *out = NULL;
92: int informat, outformat;
93: char *infile, *outfile, *prog, *certfile;
94: PKCS7 *p7 = NULL;
95: PKCS7_SIGNED *p7s = NULL;
96: X509_CRL *crl = NULL;
97: STACK_OF(OPENSSL_STRING) * certflst = NULL;
98: STACK_OF(X509_CRL) * crl_stack = NULL;
99: STACK_OF(X509) * cert_stack = NULL;
100: int ret = 1, nocrl = 0;
101:
102: infile = NULL;
103: outfile = NULL;
104: informat = FORMAT_PEM;
105: outformat = FORMAT_PEM;
106:
107: prog = argv[0];
108: argc--;
109: argv++;
110: while (argc >= 1) {
111: if (strcmp(*argv, "-inform") == 0) {
112: if (--argc < 1)
113: goto bad;
114: informat = str2fmt(*(++argv));
115: } else if (strcmp(*argv, "-outform") == 0) {
116: if (--argc < 1)
117: goto bad;
118: outformat = str2fmt(*(++argv));
119: } else if (strcmp(*argv, "-in") == 0) {
120: if (--argc < 1)
121: goto bad;
122: infile = *(++argv);
123: } else if (strcmp(*argv, "-nocrl") == 0) {
124: nocrl = 1;
125: } else if (strcmp(*argv, "-out") == 0) {
126: if (--argc < 1)
127: goto bad;
128: outfile = *(++argv);
129: } else if (strcmp(*argv, "-certfile") == 0) {
130: if (--argc < 1)
131: goto bad;
132: if (!certflst)
133: certflst = sk_OPENSSL_STRING_new_null();
134: sk_OPENSSL_STRING_push(certflst, *(++argv));
135: } else {
136: BIO_printf(bio_err, "unknown option %s\n", *argv);
137: badops = 1;
138: break;
139: }
140: argc--;
141: argv++;
142: }
143:
144: if (badops) {
145: bad:
146: BIO_printf(bio_err, "%s [options] <infile >outfile\n", prog);
147: BIO_printf(bio_err, "where options are\n");
148: BIO_printf(bio_err, " -inform arg input format - DER or PEM\n");
149: BIO_printf(bio_err, " -outform arg output format - DER or PEM\n");
150: BIO_printf(bio_err, " -in arg input file\n");
151: BIO_printf(bio_err, " -out arg output file\n");
152: BIO_printf(bio_err, " -certfile arg certificates file of chain to a trusted CA\n");
153: BIO_printf(bio_err, " (can be used more than once)\n");
154: BIO_printf(bio_err, " -nocrl no crl to load, just certs from '-certfile'\n");
155: ret = 1;
156: goto end;
157: }
158:
159: in = BIO_new(BIO_s_file());
160: out = BIO_new(BIO_s_file());
161: if ((in == NULL) || (out == NULL)) {
162: ERR_print_errors(bio_err);
163: goto end;
164: }
165: if (!nocrl) {
166: if (infile == NULL)
167: BIO_set_fp(in, stdin, BIO_NOCLOSE);
168: else {
169: if (BIO_read_filename(in, infile) <= 0) {
170: perror(infile);
171: goto end;
172: }
173: }
174:
175: if (informat == FORMAT_ASN1)
176: crl = d2i_X509_CRL_bio(in, NULL);
177: else if (informat == FORMAT_PEM)
178: crl = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL);
179: else {
180: BIO_printf(bio_err,
181: "bad input format specified for input crl\n");
182: goto end;
183: }
184: if (crl == NULL) {
185: BIO_printf(bio_err, "unable to load CRL\n");
186: ERR_print_errors(bio_err);
187: goto end;
188: }
189: }
190: if ((p7 = PKCS7_new()) == NULL)
191: goto end;
192: if ((p7s = PKCS7_SIGNED_new()) == NULL)
193: goto end;
194: p7->type = OBJ_nid2obj(NID_pkcs7_signed);
195: p7->d.sign = p7s;
196: p7s->contents->type = OBJ_nid2obj(NID_pkcs7_data);
197:
198: if (!ASN1_INTEGER_set(p7s->version, 1))
199: goto end;
200: if ((crl_stack = sk_X509_CRL_new_null()) == NULL)
201: goto end;
202: p7s->crl = crl_stack;
203: if (crl != NULL) {
204: sk_X509_CRL_push(crl_stack, crl);
205: crl = NULL; /* now part of p7 for freeing */
206: }
207: if ((cert_stack = sk_X509_new_null()) == NULL)
208: goto end;
209: p7s->cert = cert_stack;
210:
211: if (certflst)
212: for (i = 0; i < sk_OPENSSL_STRING_num(certflst); i++) {
213: certfile = sk_OPENSSL_STRING_value(certflst, i);
214: if (add_certs_from_file(cert_stack, certfile) < 0) {
215: BIO_printf(bio_err,
216: "error loading certificates\n");
217: ERR_print_errors(bio_err);
218: goto end;
219: }
220: }
221:
222: sk_OPENSSL_STRING_free(certflst);
223:
224: if (outfile == NULL) {
225: BIO_set_fp(out, stdout, BIO_NOCLOSE);
226: } else {
227: if (BIO_write_filename(out, outfile) <= 0) {
228: perror(outfile);
229: goto end;
230: }
231: }
232:
233: if (outformat == FORMAT_ASN1)
234: i = i2d_PKCS7_bio(out, p7);
235: else if (outformat == FORMAT_PEM)
236: i = PEM_write_bio_PKCS7(out, p7);
237: else {
238: BIO_printf(bio_err,
239: "bad output format specified for outfile\n");
240: goto end;
241: }
242: if (!i) {
243: BIO_printf(bio_err, "unable to write pkcs7 object\n");
244: ERR_print_errors(bio_err);
245: goto end;
246: }
247: ret = 0;
248:
249: end:
250: if (in != NULL)
251: BIO_free(in);
252: if (out != NULL)
253: BIO_free_all(out);
254: if (p7 != NULL)
255: PKCS7_free(p7);
256: if (crl != NULL)
257: X509_CRL_free(crl);
258:
259:
260: return (ret);
261: }
262:
263: /*
264: *----------------------------------------------------------------------
265: * int add_certs_from_file
266: *
267: * Read a list of certificates to be checked from a file.
268: *
269: * Results:
270: * number of certs added if successful, -1 if not.
271: *----------------------------------------------------------------------
272: */
273: static int
274: add_certs_from_file(STACK_OF(X509) * stack, char *certfile)
275: {
276: BIO *in = NULL;
277: int count = 0;
278: int ret = -1;
279: STACK_OF(X509_INFO) * sk = NULL;
280: X509_INFO *xi;
281:
282: in = BIO_new(BIO_s_file());
283: if ((in == NULL) || (BIO_read_filename(in, certfile) <= 0)) {
284: BIO_printf(bio_err, "error opening the file, %s\n", certfile);
285: goto end;
286: }
287: /* This loads from a file, a stack of x509/crl/pkey sets */
288: sk = PEM_X509_INFO_read_bio(in, NULL, NULL, NULL);
289: if (sk == NULL) {
290: BIO_printf(bio_err, "error reading the file, %s\n", certfile);
291: goto end;
292: }
293: /* scan over it and pull out the CRL's */
294: while (sk_X509_INFO_num(sk)) {
295: xi = sk_X509_INFO_shift(sk);
296: if (xi->x509 != NULL) {
297: sk_X509_push(stack, xi->x509);
298: xi->x509 = NULL;
299: count++;
300: }
301: X509_INFO_free(xi);
302: }
303:
304: ret = count;
305:
306: end:
307: /* never need to free x */
308: if (in != NULL)
309: BIO_free(in);
310: if (sk != NULL)
311: sk_X509_INFO_free(sk);
312: return (ret);
313: }