2 * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
4 * Licensed under the Apache License 2.0 (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
12 #include <sys/types.h>
15 #include <openssl/err.h>
16 #include <openssl/evp.h>
17 #include <openssl/x509.h>
18 #include <openssl/pkcs7.h>
19 #include <openssl/pem.h>
20 #include <openssl/objects.h>
22 static int add_certs_from_file(STACK_OF(X509
) *stack
, char *certfile
);
24 typedef enum OPTION_choice
{
25 OPT_ERR
= -1, OPT_EOF
= 0, OPT_HELP
,
26 OPT_INFORM
, OPT_OUTFORM
, OPT_IN
, OPT_OUT
, OPT_NOCRL
, OPT_CERTFILE
29 const OPTIONS crl2pkcs7_options
[] = {
30 OPT_SECTION("General"),
31 {"help", OPT_HELP
, '-', "Display this summary"},
34 {"in", OPT_IN
, '<', "Input file"},
35 {"inform", OPT_INFORM
, 'F', "Input format - DER or PEM"},
36 {"nocrl", OPT_NOCRL
, '-', "No crl to load, just certs from '-certfile'"},
37 {"certfile", OPT_CERTFILE
, '<',
38 "File of chain of certs to a trusted CA; can be repeated"},
40 OPT_SECTION("Output"),
41 {"out", OPT_OUT
, '>', "Output file"},
42 {"outform", OPT_OUTFORM
, 'F', "Output format - DER or PEM"},
46 int crl2pkcs7_main(int argc
, char **argv
)
48 BIO
*in
= NULL
, *out
= NULL
;
50 PKCS7_SIGNED
*p7s
= NULL
;
51 STACK_OF(OPENSSL_STRING
) *certflst
= NULL
;
52 STACK_OF(X509
) *cert_stack
= NULL
;
53 STACK_OF(X509_CRL
) *crl_stack
= NULL
;
55 char *infile
= NULL
, *outfile
= NULL
, *prog
, *certfile
;
56 int i
= 0, informat
= FORMAT_PEM
, outformat
= FORMAT_PEM
, ret
= 1, nocrl
=
60 prog
= opt_init(argc
, argv
, crl2pkcs7_options
);
61 while ((o
= opt_next()) != OPT_EOF
) {
66 BIO_printf(bio_err
, "%s: Use -help for summary.\n", prog
);
69 opt_help(crl2pkcs7_options
);
73 if (!opt_format(opt_arg(), OPT_FMT_PEMDER
, &informat
))
77 if (!opt_format(opt_arg(), OPT_FMT_PEMDER
, &outformat
))
90 if ((certflst
== NULL
)
91 && (certflst
= sk_OPENSSL_STRING_new_null()) == NULL
)
93 if (!sk_OPENSSL_STRING_push(certflst
, opt_arg()))
98 argc
= opt_num_rest();
103 in
= bio_open_default(infile
, 'r', informat
);
107 if (informat
== FORMAT_ASN1
)
108 crl
= d2i_X509_CRL_bio(in
, NULL
);
109 else if (informat
== FORMAT_PEM
)
110 crl
= PEM_read_bio_X509_CRL(in
, NULL
, NULL
, NULL
);
112 BIO_printf(bio_err
, "unable to load CRL\n");
113 ERR_print_errors(bio_err
);
118 if ((p7
= PKCS7_new()) == NULL
)
120 if ((p7s
= PKCS7_SIGNED_new()) == NULL
)
122 p7
->type
= OBJ_nid2obj(NID_pkcs7_signed
);
124 p7s
->contents
->type
= OBJ_nid2obj(NID_pkcs7_data
);
126 if (!ASN1_INTEGER_set(p7s
->version
, 1))
128 if ((crl_stack
= sk_X509_CRL_new_null()) == NULL
)
130 p7s
->crl
= crl_stack
;
132 sk_X509_CRL_push(crl_stack
, crl
);
133 crl
= NULL
; /* now part of p7 for OPENSSL_freeing */
136 if ((cert_stack
= sk_X509_new_null()) == NULL
)
138 p7s
->cert
= cert_stack
;
140 if (certflst
!= NULL
)
141 for (i
= 0; i
< sk_OPENSSL_STRING_num(certflst
); i
++) {
142 certfile
= sk_OPENSSL_STRING_value(certflst
, i
);
143 if (add_certs_from_file(cert_stack
, certfile
) < 0) {
144 BIO_printf(bio_err
, "error loading certificates\n");
145 ERR_print_errors(bio_err
);
150 out
= bio_open_default(outfile
, 'w', outformat
);
154 if (outformat
== FORMAT_ASN1
)
155 i
= i2d_PKCS7_bio(out
, p7
);
156 else if (outformat
== FORMAT_PEM
)
157 i
= PEM_write_bio_PKCS7(out
, p7
);
159 BIO_printf(bio_err
, "unable to write pkcs7 object\n");
160 ERR_print_errors(bio_err
);
165 sk_OPENSSL_STRING_free(certflst
);
175 *----------------------------------------------------------------------
176 * int add_certs_from_file
178 * Read a list of certificates to be checked from a file.
181 * number of certs added if successful, -1 if not.
182 *----------------------------------------------------------------------
184 static int add_certs_from_file(STACK_OF(X509
) *stack
, char *certfile
)
189 STACK_OF(X509_INFO
) *sk
= NULL
;
192 in
= BIO_new_file(certfile
, "r");
194 BIO_printf(bio_err
, "error opening the file, %s\n", certfile
);
198 /* This loads from a file, a stack of x509/crl/pkey sets */
199 sk
= PEM_X509_INFO_read_bio(in
, NULL
, NULL
, NULL
);
201 BIO_printf(bio_err
, "error reading the file, %s\n", certfile
);
205 /* scan over it and pull out the CRL's */
206 while (sk_X509_INFO_num(sk
)) {
207 xi
= sk_X509_INFO_shift(sk
);
208 if (xi
->x509
!= NULL
) {
209 sk_X509_push(stack
, xi
->x509
);
218 /* never need to OPENSSL_free x */
220 sk_X509_INFO_free(sk
);