]>
git.ipfire.org Git - thirdparty/openssl.git/blob - apps/crl.c
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
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', "CRL input format (DER or PEM); has no effect"},
38 {"key", OPT_KEY
, '<', "CRL signing Private key to use"},
39 {"keyform", OPT_KEYFORM
, 'F', "Private key file format (DER/PEM/P12); has no effect"},
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', "Certificate subject/issuer name printing 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 char *digestname
= NULL
;
88 const char *CAfile
= NULL
, *CApath
= NULL
, *CAstore
= NULL
, *prog
;
90 int hash
= 0, issuer
= 0, lastupdate
= 0, nextupdate
= 0, noout
= 0;
91 int informat
= FORMAT_PEM
, outformat
= FORMAT_PEM
, keyformat
= FORMAT_PEM
;
92 int ret
= 1, num
= 0, badsig
= 0, fingerprint
= 0, crlnumber
= 0;
93 int text
= 0, do_ver
= 0, noCAfile
= 0, noCApath
= 0, noCAstore
= 0;
95 #ifndef OPENSSL_NO_MD5
99 prog
= opt_init(argc
, argv
, crl_options
);
100 while ((o
= opt_next()) != OPT_EOF
) {
105 BIO_printf(bio_err
, "%s: Use -help for summary.\n", prog
);
108 opt_help(crl_options
);
112 if (!opt_format(opt_arg(), OPT_FMT_PEMDER
, &informat
))
119 if (!opt_format(opt_arg(), OPT_FMT_PEMDER
, &outformat
))
126 if (!opt_format(opt_arg(), OPT_FMT_ANY
, &keyformat
))
157 #ifndef OPENSSL_NO_MD5
182 case OPT_FINGERPRINT
:
192 if (!set_nameopt(opt_arg()))
196 digestname
= opt_unknown();
199 if (!opt_provider(o
))
205 /* No remaining args. */
206 argc
= opt_num_rest();
210 if (digestname
!= NULL
&& !opt_md(digestname
, &digest
))
212 x
= load_crl(infile
, "CRL");
217 if ((store
= setup_verify(CAfile
, noCAfile
, CApath
, noCApath
,
218 CAstore
, noCAstore
)) == NULL
)
220 lookup
= X509_STORE_add_lookup(store
, X509_LOOKUP_file());
223 ctx
= X509_STORE_CTX_new();
224 if (ctx
== NULL
|| !X509_STORE_CTX_init(ctx
, store
, NULL
, NULL
)) {
225 BIO_printf(bio_err
, "Error initialising X509 store\n");
229 xobj
= X509_STORE_CTX_get_obj_by_subject(ctx
, X509_LU_X509
,
230 X509_CRL_get_issuer(x
));
232 BIO_printf(bio_err
, "Error getting CRL issuer certificate\n");
235 pkey
= X509_get_pubkey(X509_OBJECT_get0_X509(xobj
));
236 X509_OBJECT_free(xobj
);
238 BIO_printf(bio_err
, "Error getting CRL issuer public key\n");
241 i
= X509_CRL_verify(x
, pkey
);
246 BIO_printf(bio_err
, "verify failure\n");
248 BIO_printf(bio_err
, "verify OK\n");
252 X509_CRL
*newcrl
, *delta
;
254 BIO_puts(bio_err
, "Missing CRL signing key\n");
257 newcrl
= load_crl(crldiff
, "other CRL");
260 pkey
= load_key(keyfile
, keyformat
, 0, NULL
, NULL
, "CRL signing key");
262 X509_CRL_free(newcrl
);
265 delta
= X509_CRL_diff(x
, newcrl
, pkey
, digest
, 0);
266 X509_CRL_free(newcrl
);
272 BIO_puts(bio_err
, "Error creating delta CRL\n");
278 const ASN1_BIT_STRING
*sig
;
280 X509_CRL_get0_signature(x
, &sig
, NULL
);
281 corrupt_signature(sig
);
285 for (i
= 1; i
<= num
; i
++) {
287 print_name(bio_out
, "issuer=", X509_CRL_get_issuer(x
),
290 if (crlnumber
== i
) {
291 ASN1_INTEGER
*crlnum
;
293 crlnum
= X509_CRL_get_ext_d2i(x
, NID_crl_number
, NULL
, NULL
);
294 BIO_printf(bio_out
, "crlNumber=");
296 BIO_puts(bio_out
, "0x");
297 i2a_ASN1_INTEGER(bio_out
, crlnum
);
298 ASN1_INTEGER_free(crlnum
);
300 BIO_puts(bio_out
, "<NONE>");
302 BIO_printf(bio_out
, "\n");
306 unsigned long hash_value
=
307 X509_NAME_hash_ex(X509_CRL_get_issuer(x
), app_get0_libctx(),
308 app_get0_propq(), &ok
);
310 BIO_printf(bio_out
, "issuer name hash=");
312 BIO_printf(bio_out
, "%08lx\n", hash_value
);
314 BIO_puts(bio_out
, "<ERROR>");
316 #ifndef OPENSSL_NO_MD5
318 BIO_printf(bio_out
, "issuer name old hash=");
319 BIO_printf(bio_out
, "%08lx\n",
320 X509_NAME_hash_old(X509_CRL_get_issuer(x
)));
323 if (lastupdate
== i
) {
324 BIO_printf(bio_out
, "lastUpdate=");
325 ASN1_TIME_print(bio_out
, X509_CRL_get0_lastUpdate(x
));
326 BIO_printf(bio_out
, "\n");
328 if (nextupdate
== i
) {
329 BIO_printf(bio_out
, "nextUpdate=");
330 if (X509_CRL_get0_nextUpdate(x
))
331 ASN1_TIME_print(bio_out
, X509_CRL_get0_nextUpdate(x
));
333 BIO_printf(bio_out
, "NONE");
334 BIO_printf(bio_out
, "\n");
336 if (fingerprint
== i
) {
339 unsigned char md
[EVP_MAX_MD_SIZE
];
341 if (!X509_CRL_digest(x
, digest
, md
, &n
)) {
342 BIO_printf(bio_err
, "out of memory\n");
345 BIO_printf(bio_out
, "%s Fingerprint=",
346 OBJ_nid2sn(EVP_MD_type(digest
)));
347 for (j
= 0; j
< (int)n
; j
++) {
348 BIO_printf(bio_out
, "%02X%c", md
[j
], (j
+ 1 == (int)n
)
354 out
= bio_open_default(outfile
, 'w', outformat
);
359 X509_CRL_print_ex(out
, x
, get_nameopt());
366 if (outformat
== FORMAT_ASN1
)
367 i
= (int)i2d_X509_CRL_bio(out
, x
);
369 i
= PEM_write_bio_X509_CRL(out
, x
);
371 BIO_printf(bio_err
, "unable to write CRL\n");
378 ERR_print_errors(bio_err
);
381 X509_STORE_CTX_free(ctx
);
382 X509_STORE_free(store
);