]>
git.ipfire.org Git - thirdparty/openssl.git/blob - apps/crl.c
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
15 #include <openssl/bio.h>
16 #include <openssl/err.h>
17 #include <openssl/x509.h>
18 #include <openssl/x509v3.h>
19 #include <openssl/pem.h>
21 typedef enum OPTION_choice
{
22 OPT_ERR
= -1, OPT_EOF
= 0, OPT_HELP
,
23 OPT_INFORM
, OPT_IN
, OPT_OUTFORM
, OPT_OUT
, OPT_KEYFORM
, OPT_KEY
,
24 OPT_ISSUER
, OPT_LASTUPDATE
, OPT_NEXTUPDATE
, OPT_FINGERPRINT
,
25 OPT_CRLNUMBER
, OPT_BADSIG
, OPT_GENDELTA
, OPT_CAPATH
, OPT_CAFILE
, OPT_CASTORE
,
26 OPT_NOCAPATH
, OPT_NOCAFILE
, OPT_NOCASTORE
, OPT_VERIFY
, OPT_TEXT
, OPT_HASH
,
27 OPT_HASH_OLD
, OPT_NOOUT
, OPT_NAMEOPT
, OPT_MD
, OPT_PROV_ENUM
30 const OPTIONS crl_options
[] = {
31 OPT_SECTION("General"),
32 {"help", OPT_HELP
, '-', "Display this summary"},
33 {"verify", OPT_VERIFY
, '-', "Verify CRL signature"},
36 {"in", OPT_IN
, '<', "Input file - default stdin"},
37 {"inform", OPT_INFORM
, 'F', "Input format; default PEM"},
38 {"key", OPT_KEY
, '<', "CRL signing Private key to use"},
39 {"keyform", OPT_KEYFORM
, 'F', "Private key file format (PEM or ENGINE)"},
41 OPT_SECTION("Output"),
42 {"out", OPT_OUT
, '>', "output file - default stdout"},
43 {"outform", OPT_OUTFORM
, 'F', "Output format - default PEM"},
44 {"text", OPT_TEXT
, '-', "Print out a text format version"},
45 {"hash", OPT_HASH
, '-', "Print hash value"},
46 #ifndef OPENSSL_NO_MD5
47 {"hash_old", OPT_HASH_OLD
, '-', "Print old-style (MD5) hash value"},
49 {"nameopt", OPT_NAMEOPT
, 's', "Various certificate name options"},
50 {"", OPT_MD
, '-', "Any supported digest"},
53 {"issuer", OPT_ISSUER
, '-', "Print issuer DN"},
54 {"lastupdate", OPT_LASTUPDATE
, '-', "Set lastUpdate field"},
55 {"nextupdate", OPT_NEXTUPDATE
, '-', "Set nextUpdate field"},
56 {"noout", OPT_NOOUT
, '-', "No CRL output"},
57 {"fingerprint", OPT_FINGERPRINT
, '-', "Print the crl fingerprint"},
58 {"crlnumber", OPT_CRLNUMBER
, '-', "Print CRL number"},
59 {"badsig", OPT_BADSIG
, '-', "Corrupt last byte of loaded CRL signature (for test)" },
60 {"gendelta", OPT_GENDELTA
, '<', "Other CRL to compare/diff to the Input one"},
62 OPT_SECTION("Certificate"),
63 {"CApath", OPT_CAPATH
, '/', "Verify CRL using certificates in dir"},
64 {"CAfile", OPT_CAFILE
, '<', "Verify CRL using certificates in file name"},
65 {"CAstore", OPT_CASTORE
, ':', "Verify CRL using certificates in store URI"},
66 {"no-CAfile", OPT_NOCAFILE
, '-',
67 "Do not load the default certificates file"},
68 {"no-CApath", OPT_NOCAPATH
, '-',
69 "Do not load certificates from the default certificates directory"},
70 {"no-CAstore", OPT_NOCASTORE
, '-',
71 "Do not load certificates from the default certificates store"},
76 int crl_main(int argc
, char **argv
)
80 X509_STORE
*store
= NULL
;
81 X509_STORE_CTX
*ctx
= NULL
;
82 X509_LOOKUP
*lookup
= NULL
;
83 X509_OBJECT
*xobj
= NULL
;
85 const EVP_MD
*digest
= EVP_sha1();
86 char *infile
= NULL
, *outfile
= NULL
, *crldiff
= NULL
, *keyfile
= NULL
;
87 const char *CAfile
= NULL
, *CApath
= NULL
, *CAstore
= NULL
, *prog
;
89 int hash
= 0, issuer
= 0, lastupdate
= 0, nextupdate
= 0, noout
= 0;
90 int informat
= FORMAT_PEM
, outformat
= FORMAT_PEM
, keyformat
= FORMAT_PEM
;
91 int ret
= 1, num
= 0, badsig
= 0, fingerprint
= 0, crlnumber
= 0;
92 int text
= 0, do_ver
= 0, noCAfile
= 0, noCApath
= 0, noCAstore
= 0;
94 #ifndef OPENSSL_NO_MD5
98 prog
= opt_init(argc
, argv
, crl_options
);
99 while ((o
= opt_next()) != OPT_EOF
) {
104 BIO_printf(bio_err
, "%s: Use -help for summary.\n", prog
);
107 opt_help(crl_options
);
111 if (!opt_format(opt_arg(), OPT_FMT_PEMDER
, &informat
))
118 if (!opt_format(opt_arg(), OPT_FMT_PEMDER
, &outformat
))
125 if (!opt_format(opt_arg(), OPT_FMT_PEMDER
, &keyformat
))
156 #ifndef OPENSSL_NO_MD5
181 case OPT_FINGERPRINT
:
191 if (!set_nameopt(opt_arg()))
195 if (!opt_md(opt_unknown(), &digest
))
199 if (!opt_provider(o
))
204 argc
= opt_num_rest();
208 x
= load_crl(infile
, informat
);
213 if ((store
= setup_verify(CAfile
, noCAfile
, CApath
, noCApath
,
214 CAstore
, noCAstore
)) == NULL
)
216 lookup
= X509_STORE_add_lookup(store
, X509_LOOKUP_file());
219 ctx
= X509_STORE_CTX_new();
220 if (ctx
== NULL
|| !X509_STORE_CTX_init(ctx
, store
, NULL
, NULL
)) {
221 BIO_printf(bio_err
, "Error initialising X509 store\n");
225 xobj
= X509_STORE_CTX_get_obj_by_subject(ctx
, X509_LU_X509
,
226 X509_CRL_get_issuer(x
));
228 BIO_printf(bio_err
, "Error getting CRL issuer certificate\n");
231 pkey
= X509_get_pubkey(X509_OBJECT_get0_X509(xobj
));
232 X509_OBJECT_free(xobj
);
234 BIO_printf(bio_err
, "Error getting CRL issuer public key\n");
237 i
= X509_CRL_verify(x
, pkey
);
242 BIO_printf(bio_err
, "verify failure\n");
244 BIO_printf(bio_err
, "verify OK\n");
248 X509_CRL
*newcrl
, *delta
;
250 BIO_puts(bio_err
, "Missing CRL signing key\n");
253 newcrl
= load_crl(crldiff
, informat
);
256 pkey
= load_key(keyfile
, keyformat
, 0, NULL
, NULL
, "CRL signing key");
258 X509_CRL_free(newcrl
);
261 delta
= X509_CRL_diff(x
, newcrl
, pkey
, digest
, 0);
262 X509_CRL_free(newcrl
);
268 BIO_puts(bio_err
, "Error creating delta CRL\n");
274 const ASN1_BIT_STRING
*sig
;
276 X509_CRL_get0_signature(x
, &sig
, NULL
);
277 corrupt_signature(sig
);
281 for (i
= 1; i
<= num
; i
++) {
283 print_name(bio_out
, "issuer=", X509_CRL_get_issuer(x
),
286 if (crlnumber
== i
) {
287 ASN1_INTEGER
*crlnum
;
288 crlnum
= X509_CRL_get_ext_d2i(x
, NID_crl_number
, NULL
, NULL
);
289 BIO_printf(bio_out
, "crlNumber=");
291 i2a_ASN1_INTEGER(bio_out
, crlnum
);
292 ASN1_INTEGER_free(crlnum
);
294 BIO_puts(bio_out
, "<NONE>");
295 BIO_printf(bio_out
, "\n");
298 BIO_printf(bio_out
, "%08lx\n",
299 X509_NAME_hash(X509_CRL_get_issuer(x
)));
301 #ifndef OPENSSL_NO_MD5
303 BIO_printf(bio_out
, "%08lx\n",
304 X509_NAME_hash_old(X509_CRL_get_issuer(x
)));
307 if (lastupdate
== i
) {
308 BIO_printf(bio_out
, "lastUpdate=");
309 ASN1_TIME_print(bio_out
, X509_CRL_get0_lastUpdate(x
));
310 BIO_printf(bio_out
, "\n");
312 if (nextupdate
== i
) {
313 BIO_printf(bio_out
, "nextUpdate=");
314 if (X509_CRL_get0_nextUpdate(x
))
315 ASN1_TIME_print(bio_out
, X509_CRL_get0_nextUpdate(x
));
317 BIO_printf(bio_out
, "NONE");
318 BIO_printf(bio_out
, "\n");
320 if (fingerprint
== i
) {
323 unsigned char md
[EVP_MAX_MD_SIZE
];
325 if (!X509_CRL_digest(x
, digest
, md
, &n
)) {
326 BIO_printf(bio_err
, "out of memory\n");
329 BIO_printf(bio_out
, "%s Fingerprint=",
330 OBJ_nid2sn(EVP_MD_type(digest
)));
331 for (j
= 0; j
< (int)n
; j
++) {
332 BIO_printf(bio_out
, "%02X%c", md
[j
], (j
+ 1 == (int)n
)
338 out
= bio_open_default(outfile
, 'w', outformat
);
343 X509_CRL_print_ex(out
, x
, get_nameopt());
350 if (outformat
== FORMAT_ASN1
)
351 i
= (int)i2d_X509_CRL_bio(out
, x
);
353 i
= PEM_write_bio_X509_CRL(out
, x
);
355 BIO_printf(bio_err
, "unable to write CRL\n");
362 ERR_print_errors(bio_err
);
365 X509_STORE_CTX_free(ctx
);
366 X509_STORE_free(store
);