2 * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
4 * Licensed under the OpenSSL license (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 {"help", OPT_HELP
, '-', "Display this summary"},
31 {"inform", OPT_INFORM
, 'F', "Input format - DER or PEM"},
32 {"outform", OPT_OUTFORM
, 'F', "Output format - DER or PEM"},
33 {"in", OPT_IN
, '<', "Input file"},
34 {"out", OPT_OUT
, '>', "Output file"},
35 {"nocrl", OPT_NOCRL
, '-', "No crl to load, just certs from '-certfile'"},
36 {"certfile", OPT_CERTFILE
, '<',
37 "File of chain of certs to a trusted CA; can be repeated"},
41 int crl2pkcs7_main(int argc
, char **argv
)
43 BIO
*in
= NULL
, *out
= NULL
;
45 PKCS7_SIGNED
*p7s
= NULL
;
46 STACK_OF(OPENSSL_STRING
) *certflst
= NULL
;
47 STACK_OF(X509
) *cert_stack
= NULL
;
48 STACK_OF(X509_CRL
) *crl_stack
= NULL
;
50 char *infile
= NULL
, *outfile
= NULL
, *prog
, *certfile
;
51 int i
= 0, informat
= FORMAT_PEM
, outformat
= FORMAT_PEM
, ret
= 1, nocrl
=
55 prog
= opt_init(argc
, argv
, crl2pkcs7_options
);
56 while ((o
= opt_next()) != OPT_EOF
) {
61 BIO_printf(bio_err
, "%s: Use -help for summary.\n", prog
);
64 opt_help(crl2pkcs7_options
);
68 if (!opt_format(opt_arg(), OPT_FMT_PEMDER
, &informat
))
72 if (!opt_format(opt_arg(), OPT_FMT_PEMDER
, &outformat
))
85 if ((certflst
== NULL
)
86 && (certflst
= sk_OPENSSL_STRING_new_null()) == NULL
)
88 if (!sk_OPENSSL_STRING_push(certflst
, opt_arg()))
93 argc
= opt_num_rest();
98 in
= bio_open_default(infile
, 'r', informat
);
102 if (informat
== FORMAT_ASN1
)
103 crl
= d2i_X509_CRL_bio(in
, NULL
);
104 else if (informat
== FORMAT_PEM
)
105 crl
= PEM_read_bio_X509_CRL(in
, NULL
, NULL
, NULL
);
107 BIO_printf(bio_err
, "unable to load CRL\n");
108 ERR_print_errors(bio_err
);
113 if ((p7
= PKCS7_new()) == NULL
)
115 if ((p7s
= PKCS7_SIGNED_new()) == NULL
)
117 p7
->type
= OBJ_nid2obj(NID_pkcs7_signed
);
119 p7s
->contents
->type
= OBJ_nid2obj(NID_pkcs7_data
);
121 if (!ASN1_INTEGER_set(p7s
->version
, 1))
123 if ((crl_stack
= sk_X509_CRL_new_null()) == NULL
)
125 p7s
->crl
= crl_stack
;
127 sk_X509_CRL_push(crl_stack
, crl
);
128 crl
= NULL
; /* now part of p7 for OPENSSL_freeing */
131 if ((cert_stack
= sk_X509_new_null()) == NULL
)
133 p7s
->cert
= cert_stack
;
135 if (certflst
!= NULL
)
136 for (i
= 0; i
< sk_OPENSSL_STRING_num(certflst
); i
++) {
137 certfile
= sk_OPENSSL_STRING_value(certflst
, i
);
138 if (add_certs_from_file(cert_stack
, certfile
) < 0) {
139 BIO_printf(bio_err
, "error loading certificates\n");
140 ERR_print_errors(bio_err
);
145 out
= bio_open_default(outfile
, 'w', outformat
);
149 if (outformat
== FORMAT_ASN1
)
150 i
= i2d_PKCS7_bio(out
, p7
);
151 else if (outformat
== FORMAT_PEM
)
152 i
= PEM_write_bio_PKCS7(out
, p7
);
154 BIO_printf(bio_err
, "unable to write pkcs7 object\n");
155 ERR_print_errors(bio_err
);
160 sk_OPENSSL_STRING_free(certflst
);
170 *----------------------------------------------------------------------
171 * int add_certs_from_file
173 * Read a list of certificates to be checked from a file.
176 * number of certs added if successful, -1 if not.
177 *----------------------------------------------------------------------
179 static int add_certs_from_file(STACK_OF(X509
) *stack
, char *certfile
)
184 STACK_OF(X509_INFO
) *sk
= NULL
;
187 in
= BIO_new_file(certfile
, "r");
189 BIO_printf(bio_err
, "error opening the file, %s\n", certfile
);
193 /* This loads from a file, a stack of x509/crl/pkey sets */
194 sk
= PEM_X509_INFO_read_bio(in
, NULL
, NULL
, NULL
);
196 BIO_printf(bio_err
, "error reading the file, %s\n", certfile
);
200 /* scan over it and pull out the CRL's */
201 while (sk_X509_INFO_num(sk
)) {
202 xi
= sk_X509_INFO_shift(sk
);
203 if (xi
->x509
!= NULL
) {
204 sk_X509_push(stack
, xi
->x509
);
213 /* never need to OPENSSL_free x */
215 sk_X509_INFO_free(sk
);