2 * Copyright 1995-2021 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
{
26 OPT_INFORM
, OPT_OUTFORM
, OPT_IN
, OPT_OUT
, OPT_NOCRL
, OPT_CERTFILE
,
30 const OPTIONS crl2pkcs7_options
[] = {
31 OPT_SECTION("General"),
32 {"help", OPT_HELP
, '-', "Display this summary"},
35 {"in", OPT_IN
, '<', "Input file"},
36 {"inform", OPT_INFORM
, 'F', "Input format - DER or PEM"},
37 {"nocrl", OPT_NOCRL
, '-', "No crl to load, just certs from '-certfile'"},
38 {"certfile", OPT_CERTFILE
, '<',
39 "File of chain of certs to a trusted CA; can be repeated"},
41 OPT_SECTION("Output"),
42 {"out", OPT_OUT
, '>', "Output file"},
43 {"outform", OPT_OUTFORM
, 'F', "Output format - DER or PEM"},
49 int crl2pkcs7_main(int argc
, char **argv
)
51 BIO
*in
= NULL
, *out
= NULL
;
53 PKCS7_SIGNED
*p7s
= NULL
;
54 STACK_OF(OPENSSL_STRING
) *certflst
= NULL
;
55 STACK_OF(X509
) *cert_stack
= NULL
;
56 STACK_OF(X509_CRL
) *crl_stack
= NULL
;
58 char *infile
= NULL
, *outfile
= NULL
, *prog
, *certfile
;
59 int i
= 0, informat
= FORMAT_PEM
, outformat
= FORMAT_PEM
, ret
= 1, nocrl
=
63 prog
= opt_init(argc
, argv
, crl2pkcs7_options
);
64 while ((o
= opt_next()) != OPT_EOF
) {
69 BIO_printf(bio_err
, "%s: Use -help for summary.\n", prog
);
72 opt_help(crl2pkcs7_options
);
76 if (!opt_format(opt_arg(), OPT_FMT_PEMDER
, &informat
))
80 if (!opt_format(opt_arg(), OPT_FMT_PEMDER
, &outformat
))
93 if ((certflst
== NULL
)
94 && (certflst
= sk_OPENSSL_STRING_new_null()) == NULL
)
96 if (!sk_OPENSSL_STRING_push(certflst
, opt_arg()))
100 if (!opt_provider(o
))
106 /* No remaining args. */
107 if (!opt_check_rest_arg(NULL
))
111 in
= bio_open_default(infile
, 'r', informat
);
115 if (informat
== FORMAT_ASN1
)
116 crl
= d2i_X509_CRL_bio(in
, NULL
);
117 else if (informat
== FORMAT_PEM
)
118 crl
= PEM_read_bio_X509_CRL(in
, NULL
, NULL
, NULL
);
120 BIO_printf(bio_err
, "unable to load CRL\n");
121 ERR_print_errors(bio_err
);
126 if ((p7
= PKCS7_new()) == NULL
)
128 if ((p7s
= PKCS7_SIGNED_new()) == NULL
)
130 p7
->type
= OBJ_nid2obj(NID_pkcs7_signed
);
132 p7s
->contents
->type
= OBJ_nid2obj(NID_pkcs7_data
);
134 if (!ASN1_INTEGER_set(p7s
->version
, 1))
138 if ((crl_stack
= sk_X509_CRL_new_null()) == NULL
)
140 p7s
->crl
= crl_stack
;
141 sk_X509_CRL_push(crl_stack
, crl
);
142 crl
= NULL
; /* now part of p7 for OPENSSL_freeing */
145 if (certflst
!= NULL
) {
146 if ((cert_stack
= sk_X509_new_null()) == NULL
)
148 p7s
->cert
= cert_stack
;
150 for (i
= 0; i
< sk_OPENSSL_STRING_num(certflst
); i
++) {
151 certfile
= sk_OPENSSL_STRING_value(certflst
, i
);
152 if (add_certs_from_file(cert_stack
, certfile
) < 0) {
153 BIO_printf(bio_err
, "error loading certificates\n");
154 ERR_print_errors(bio_err
);
160 out
= bio_open_default(outfile
, 'w', outformat
);
164 if (outformat
== FORMAT_ASN1
)
165 i
= i2d_PKCS7_bio(out
, p7
);
166 else if (outformat
== FORMAT_PEM
)
167 i
= PEM_write_bio_PKCS7(out
, p7
);
169 BIO_printf(bio_err
, "unable to write pkcs7 object\n");
170 ERR_print_errors(bio_err
);
175 sk_OPENSSL_STRING_free(certflst
);
185 *----------------------------------------------------------------------
186 * int add_certs_from_file
188 * Read a list of certificates to be checked from a file.
191 * number of certs added if successful, -1 if not.
192 *----------------------------------------------------------------------
194 static int add_certs_from_file(STACK_OF(X509
) *stack
, char *certfile
)
199 STACK_OF(X509_INFO
) *sk
= NULL
;
202 in
= BIO_new_file(certfile
, "r");
204 BIO_printf(bio_err
, "error opening the file, %s\n", certfile
);
208 /* This loads from a file, a stack of x509/crl/pkey sets */
209 sk
= PEM_X509_INFO_read_bio(in
, NULL
, NULL
, NULL
);
211 BIO_printf(bio_err
, "error reading the file, %s\n", certfile
);
215 /* scan over it and pull out the CRL's */
216 while (sk_X509_INFO_num(sk
)) {
217 xi
= sk_X509_INFO_shift(sk
);
218 if (xi
->x509
!= NULL
) {
219 sk_X509_push(stack
, xi
->x509
);
228 /* never need to OPENSSL_free x */
230 sk_X509_INFO_free(sk
);