1*cca6fc52SDaniel Fojt /* $OpenBSD: crl.c,v 1.13 2019/07/14 03:30:45 guenther Exp $ */ 2f5b1c8a1SJohn Marino /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 3f5b1c8a1SJohn Marino * All rights reserved. 4f5b1c8a1SJohn Marino * 5f5b1c8a1SJohn Marino * This package is an SSL implementation written 6f5b1c8a1SJohn Marino * by Eric Young (eay@cryptsoft.com). 7f5b1c8a1SJohn Marino * The implementation was written so as to conform with Netscapes SSL. 8f5b1c8a1SJohn Marino * 9f5b1c8a1SJohn Marino * This library is free for commercial and non-commercial use as long as 10f5b1c8a1SJohn Marino * the following conditions are aheared to. The following conditions 11f5b1c8a1SJohn Marino * apply to all code found in this distribution, be it the RC4, RSA, 12f5b1c8a1SJohn Marino * lhash, DES, etc., code; not just the SSL code. The SSL documentation 13f5b1c8a1SJohn Marino * included with this distribution is covered by the same copyright terms 14f5b1c8a1SJohn Marino * except that the holder is Tim Hudson (tjh@cryptsoft.com). 15f5b1c8a1SJohn Marino * 16f5b1c8a1SJohn Marino * Copyright remains Eric Young's, and as such any Copyright notices in 17f5b1c8a1SJohn Marino * the code are not to be removed. 18f5b1c8a1SJohn Marino * If this package is used in a product, Eric Young should be given attribution 19f5b1c8a1SJohn Marino * as the author of the parts of the library used. 20f5b1c8a1SJohn Marino * This can be in the form of a textual message at program startup or 21f5b1c8a1SJohn Marino * in documentation (online or textual) provided with the package. 22f5b1c8a1SJohn Marino * 23f5b1c8a1SJohn Marino * Redistribution and use in source and binary forms, with or without 24f5b1c8a1SJohn Marino * modification, are permitted provided that the following conditions 25f5b1c8a1SJohn Marino * are met: 26f5b1c8a1SJohn Marino * 1. Redistributions of source code must retain the copyright 27f5b1c8a1SJohn Marino * notice, this list of conditions and the following disclaimer. 28f5b1c8a1SJohn Marino * 2. Redistributions in binary form must reproduce the above copyright 29f5b1c8a1SJohn Marino * notice, this list of conditions and the following disclaimer in the 30f5b1c8a1SJohn Marino * documentation and/or other materials provided with the distribution. 31f5b1c8a1SJohn Marino * 3. All advertising materials mentioning features or use of this software 32f5b1c8a1SJohn Marino * must display the following acknowledgement: 33f5b1c8a1SJohn Marino * "This product includes cryptographic software written by 34f5b1c8a1SJohn Marino * Eric Young (eay@cryptsoft.com)" 35f5b1c8a1SJohn Marino * The word 'cryptographic' can be left out if the rouines from the library 36f5b1c8a1SJohn Marino * being used are not cryptographic related :-). 37f5b1c8a1SJohn Marino * 4. If you include any Windows specific code (or a derivative thereof) from 38f5b1c8a1SJohn Marino * the apps directory (application code) you must include an acknowledgement: 39f5b1c8a1SJohn Marino * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 40f5b1c8a1SJohn Marino * 41f5b1c8a1SJohn Marino * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 42f5b1c8a1SJohn Marino * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 43f5b1c8a1SJohn Marino * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 44f5b1c8a1SJohn Marino * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 45f5b1c8a1SJohn Marino * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 46f5b1c8a1SJohn Marino * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 47f5b1c8a1SJohn Marino * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 48f5b1c8a1SJohn Marino * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 49f5b1c8a1SJohn Marino * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 50f5b1c8a1SJohn Marino * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 51f5b1c8a1SJohn Marino * SUCH DAMAGE. 52f5b1c8a1SJohn Marino * 53f5b1c8a1SJohn Marino * The licence and distribution terms for any publically available version or 54f5b1c8a1SJohn Marino * derivative of this code cannot be changed. i.e. this code cannot simply be 55f5b1c8a1SJohn Marino * copied and put under another distribution licence 56f5b1c8a1SJohn Marino * [including the GNU Public Licence.] 57f5b1c8a1SJohn Marino */ 58f5b1c8a1SJohn Marino 59f5b1c8a1SJohn Marino #include <stdio.h> 60f5b1c8a1SJohn Marino #include <stdlib.h> 61f5b1c8a1SJohn Marino #include <string.h> 62f5b1c8a1SJohn Marino 63f5b1c8a1SJohn Marino #include "apps.h" 64f5b1c8a1SJohn Marino 65f5b1c8a1SJohn Marino #include <openssl/bio.h> 66f5b1c8a1SJohn Marino #include <openssl/err.h> 67f5b1c8a1SJohn Marino #include <openssl/pem.h> 68f5b1c8a1SJohn Marino #include <openssl/x509.h> 69f5b1c8a1SJohn Marino #include <openssl/x509v3.h> 70f5b1c8a1SJohn Marino 71f5b1c8a1SJohn Marino static struct { 72f5b1c8a1SJohn Marino char *cafile; 73f5b1c8a1SJohn Marino char *capath; 74f5b1c8a1SJohn Marino int crlnumber; 75f5b1c8a1SJohn Marino int fingerprint; 76f5b1c8a1SJohn Marino int hash; 77f5b1c8a1SJohn Marino int hash_old; 78f5b1c8a1SJohn Marino char *infile; 79f5b1c8a1SJohn Marino int informat; 80f5b1c8a1SJohn Marino int issuer; 81f5b1c8a1SJohn Marino int lastupdate; 82f5b1c8a1SJohn Marino char *nameopt; 83f5b1c8a1SJohn Marino int nextupdate; 84f5b1c8a1SJohn Marino int noout; 85f5b1c8a1SJohn Marino char *outfile; 86f5b1c8a1SJohn Marino int outformat; 87f5b1c8a1SJohn Marino int text; 88f5b1c8a1SJohn Marino int verify; 89f5b1c8a1SJohn Marino } crl_config; 90f5b1c8a1SJohn Marino 91*cca6fc52SDaniel Fojt static const struct option crl_options[] = { 92f5b1c8a1SJohn Marino { 93f5b1c8a1SJohn Marino .name = "CAfile", 94f5b1c8a1SJohn Marino .argname = "file", 95f5b1c8a1SJohn Marino .desc = "Verify the CRL using certificates in the given file", 96f5b1c8a1SJohn Marino .type = OPTION_ARG, 97f5b1c8a1SJohn Marino .opt.arg = &crl_config.cafile, 98f5b1c8a1SJohn Marino }, 99f5b1c8a1SJohn Marino { 100f5b1c8a1SJohn Marino .name = "CApath", 101f5b1c8a1SJohn Marino .argname = "path", 102f5b1c8a1SJohn Marino .desc = "Verify the CRL using certificates in the given path", 103f5b1c8a1SJohn Marino .type = OPTION_ARG, 104f5b1c8a1SJohn Marino .opt.arg = &crl_config.capath, 105f5b1c8a1SJohn Marino }, 106f5b1c8a1SJohn Marino { 107f5b1c8a1SJohn Marino .name = "crlnumber", 108f5b1c8a1SJohn Marino .desc = "Print the CRL number", 109f5b1c8a1SJohn Marino .type = OPTION_FLAG_ORD, 110f5b1c8a1SJohn Marino .opt.flag = &crl_config.crlnumber, 111f5b1c8a1SJohn Marino }, 112f5b1c8a1SJohn Marino { 113f5b1c8a1SJohn Marino .name = "fingerprint", 114f5b1c8a1SJohn Marino .desc = "Print the CRL fingerprint", 115f5b1c8a1SJohn Marino .type = OPTION_FLAG_ORD, 116f5b1c8a1SJohn Marino .opt.flag = &crl_config.fingerprint, 117f5b1c8a1SJohn Marino }, 118f5b1c8a1SJohn Marino { 119f5b1c8a1SJohn Marino .name = "hash", 120f5b1c8a1SJohn Marino .desc = "Print the hash of the issuer name", 121f5b1c8a1SJohn Marino .type = OPTION_FLAG_ORD, 122f5b1c8a1SJohn Marino .opt.flag = &crl_config.hash, 123f5b1c8a1SJohn Marino }, 124f5b1c8a1SJohn Marino { 125f5b1c8a1SJohn Marino .name = "hash_old", 126f5b1c8a1SJohn Marino .desc = "Print an old-style (MD5) hash of the issuer name", 127f5b1c8a1SJohn Marino .type = OPTION_FLAG_ORD, 128f5b1c8a1SJohn Marino .opt.flag = &crl_config.hash_old, 129f5b1c8a1SJohn Marino }, 130f5b1c8a1SJohn Marino { 131f5b1c8a1SJohn Marino .name = "in", 132f5b1c8a1SJohn Marino .argname = "file", 133f5b1c8a1SJohn Marino .desc = "Input file to read from (stdin if unspecified)", 134f5b1c8a1SJohn Marino .type = OPTION_ARG, 135f5b1c8a1SJohn Marino .opt.arg = &crl_config.infile, 136f5b1c8a1SJohn Marino }, 137f5b1c8a1SJohn Marino { 138f5b1c8a1SJohn Marino .name = "inform", 139f5b1c8a1SJohn Marino .argname = "format", 140f5b1c8a1SJohn Marino .desc = "Input format (DER or PEM)", 141f5b1c8a1SJohn Marino .type = OPTION_ARG_FORMAT, 142f5b1c8a1SJohn Marino .opt.value = &crl_config.informat, 143f5b1c8a1SJohn Marino }, 144f5b1c8a1SJohn Marino { 145f5b1c8a1SJohn Marino .name = "issuer", 146f5b1c8a1SJohn Marino .desc = "Print the issuer name", 147f5b1c8a1SJohn Marino .type = OPTION_FLAG_ORD, 148f5b1c8a1SJohn Marino .opt.flag = &crl_config.issuer, 149f5b1c8a1SJohn Marino }, 150f5b1c8a1SJohn Marino { 151f5b1c8a1SJohn Marino .name = "lastupdate", 152f5b1c8a1SJohn Marino .desc = "Print the lastUpdate field", 153f5b1c8a1SJohn Marino .type = OPTION_FLAG_ORD, 154f5b1c8a1SJohn Marino .opt.flag = &crl_config.lastupdate, 155f5b1c8a1SJohn Marino }, 156f5b1c8a1SJohn Marino { 157f5b1c8a1SJohn Marino .name = "nameopt", 158f5b1c8a1SJohn Marino .argname = "options", 159f5b1c8a1SJohn Marino .desc = "Specify certificate name options", 160f5b1c8a1SJohn Marino .type = OPTION_ARG, 161f5b1c8a1SJohn Marino .opt.arg = &crl_config.nameopt, 162f5b1c8a1SJohn Marino }, 163f5b1c8a1SJohn Marino { 164f5b1c8a1SJohn Marino .name = "nextupdate", 165f5b1c8a1SJohn Marino .desc = "Print the nextUpdate field", 166f5b1c8a1SJohn Marino .type = OPTION_FLAG_ORD, 167f5b1c8a1SJohn Marino .opt.flag = &crl_config.nextupdate, 168f5b1c8a1SJohn Marino }, 169f5b1c8a1SJohn Marino { 170f5b1c8a1SJohn Marino .name = "noout", 171f5b1c8a1SJohn Marino .desc = "Do not output the encoded version of the CRL", 172f5b1c8a1SJohn Marino .type = OPTION_FLAG, 173f5b1c8a1SJohn Marino .opt.flag = &crl_config.noout, 174f5b1c8a1SJohn Marino }, 175f5b1c8a1SJohn Marino { 176f5b1c8a1SJohn Marino .name = "out", 177f5b1c8a1SJohn Marino .argname = "file", 178f5b1c8a1SJohn Marino .desc = "Output file to write to (stdout if unspecified)", 179f5b1c8a1SJohn Marino .type = OPTION_ARG, 180f5b1c8a1SJohn Marino .opt.arg = &crl_config.outfile, 181f5b1c8a1SJohn Marino }, 182f5b1c8a1SJohn Marino { 183f5b1c8a1SJohn Marino .name = "outform", 184f5b1c8a1SJohn Marino .argname = "format", 185f5b1c8a1SJohn Marino .desc = "Output format (DER or PEM)", 186f5b1c8a1SJohn Marino .type = OPTION_ARG_FORMAT, 187f5b1c8a1SJohn Marino .opt.value = &crl_config.outformat, 188f5b1c8a1SJohn Marino }, 189f5b1c8a1SJohn Marino { 190f5b1c8a1SJohn Marino .name = "text", 191f5b1c8a1SJohn Marino .desc = "Print out the CRL in text form", 192f5b1c8a1SJohn Marino .type = OPTION_FLAG, 193f5b1c8a1SJohn Marino .opt.flag = &crl_config.text, 194f5b1c8a1SJohn Marino }, 195f5b1c8a1SJohn Marino { 196f5b1c8a1SJohn Marino .name = "verify", 197f5b1c8a1SJohn Marino .desc = "Verify the signature on the CRL", 198f5b1c8a1SJohn Marino .type = OPTION_FLAG, 199f5b1c8a1SJohn Marino .opt.flag = &crl_config.verify, 200f5b1c8a1SJohn Marino }, 201f5b1c8a1SJohn Marino {NULL}, 202f5b1c8a1SJohn Marino }; 203f5b1c8a1SJohn Marino 204f5b1c8a1SJohn Marino static void 205f5b1c8a1SJohn Marino crl_usage(void) 206f5b1c8a1SJohn Marino { 207f5b1c8a1SJohn Marino fprintf(stderr, 208f5b1c8a1SJohn Marino "usage: crl [-CAfile file] [-CApath dir] [-fingerprint] [-hash]\n" 209f5b1c8a1SJohn Marino " [-in file] [-inform DER | PEM] [-issuer] [-lastupdate]\n" 210f5b1c8a1SJohn Marino " [-nextupdate] [-noout] [-out file] [-outform DER | PEM]\n" 211f5b1c8a1SJohn Marino " [-text]\n\n"); 212f5b1c8a1SJohn Marino options_usage(crl_options); 213f5b1c8a1SJohn Marino } 214f5b1c8a1SJohn Marino 215f5b1c8a1SJohn Marino static X509_CRL *load_crl(char *file, int format); 216f5b1c8a1SJohn Marino static BIO *bio_out = NULL; 217f5b1c8a1SJohn Marino 218f5b1c8a1SJohn Marino int 219f5b1c8a1SJohn Marino crl_main(int argc, char **argv) 220f5b1c8a1SJohn Marino { 221f5b1c8a1SJohn Marino unsigned long nmflag = 0; 222f5b1c8a1SJohn Marino X509_CRL *x = NULL; 223f5b1c8a1SJohn Marino int ret = 1, i; 224f5b1c8a1SJohn Marino BIO *out = NULL; 225f5b1c8a1SJohn Marino X509_STORE *store = NULL; 226f5b1c8a1SJohn Marino X509_STORE_CTX ctx; 227f5b1c8a1SJohn Marino X509_LOOKUP *lookup = NULL; 228f5b1c8a1SJohn Marino X509_OBJECT xobj; 229f5b1c8a1SJohn Marino EVP_PKEY *pkey; 230f5b1c8a1SJohn Marino const EVP_MD *digest; 231f5b1c8a1SJohn Marino char *digest_name = NULL; 232f5b1c8a1SJohn Marino 233f5b1c8a1SJohn Marino if (single_execution) { 23472c33676SMaxim Ag if (pledge("stdio cpath wpath rpath", NULL) == -1) { 235f5b1c8a1SJohn Marino perror("pledge"); 236f5b1c8a1SJohn Marino exit(1); 237f5b1c8a1SJohn Marino } 238f5b1c8a1SJohn Marino } 239f5b1c8a1SJohn Marino 240f5b1c8a1SJohn Marino if (bio_out == NULL) { 241f5b1c8a1SJohn Marino if ((bio_out = BIO_new(BIO_s_file())) != NULL) { 242f5b1c8a1SJohn Marino BIO_set_fp(bio_out, stdout, BIO_NOCLOSE); 243f5b1c8a1SJohn Marino } 244f5b1c8a1SJohn Marino } 245f5b1c8a1SJohn Marino 24672c33676SMaxim Ag digest = EVP_sha256(); 247f5b1c8a1SJohn Marino 248f5b1c8a1SJohn Marino memset(&crl_config, 0, sizeof(crl_config)); 249f5b1c8a1SJohn Marino crl_config.informat = FORMAT_PEM; 250f5b1c8a1SJohn Marino crl_config.outformat = FORMAT_PEM; 251f5b1c8a1SJohn Marino 252f5b1c8a1SJohn Marino if (options_parse(argc, argv, crl_options, &digest_name, NULL) != 0) { 253f5b1c8a1SJohn Marino crl_usage(); 254f5b1c8a1SJohn Marino goto end; 255f5b1c8a1SJohn Marino } 256f5b1c8a1SJohn Marino 257f5b1c8a1SJohn Marino if (crl_config.cafile != NULL || crl_config.capath != NULL) 258f5b1c8a1SJohn Marino crl_config.verify = 1; 259f5b1c8a1SJohn Marino 260f5b1c8a1SJohn Marino if (crl_config.nameopt != NULL) { 261f5b1c8a1SJohn Marino if (set_name_ex(&nmflag, crl_config.nameopt) != 1) { 262f5b1c8a1SJohn Marino fprintf(stderr, 263f5b1c8a1SJohn Marino "Invalid -nameopt argument '%s'\n", 264f5b1c8a1SJohn Marino crl_config.nameopt); 265f5b1c8a1SJohn Marino goto end; 266f5b1c8a1SJohn Marino } 267f5b1c8a1SJohn Marino } 268f5b1c8a1SJohn Marino 269f5b1c8a1SJohn Marino if (digest_name != NULL) { 270f5b1c8a1SJohn Marino if ((digest = EVP_get_digestbyname(digest_name)) == NULL) { 271f5b1c8a1SJohn Marino fprintf(stderr, 272f5b1c8a1SJohn Marino "Unknown message digest algorithm '%s'\n", 273f5b1c8a1SJohn Marino digest_name); 274f5b1c8a1SJohn Marino goto end; 275f5b1c8a1SJohn Marino } 276f5b1c8a1SJohn Marino } 277f5b1c8a1SJohn Marino 278f5b1c8a1SJohn Marino x = load_crl(crl_config.infile, crl_config.informat); 279f5b1c8a1SJohn Marino if (x == NULL) 280f5b1c8a1SJohn Marino goto end; 281f5b1c8a1SJohn Marino 282f5b1c8a1SJohn Marino if (crl_config.verify) { 283f5b1c8a1SJohn Marino store = X509_STORE_new(); 284f5b1c8a1SJohn Marino lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file()); 285f5b1c8a1SJohn Marino if (lookup == NULL) 286f5b1c8a1SJohn Marino goto end; 287f5b1c8a1SJohn Marino if (!X509_LOOKUP_load_file(lookup, crl_config.cafile, 288f5b1c8a1SJohn Marino X509_FILETYPE_PEM)) 289f5b1c8a1SJohn Marino X509_LOOKUP_load_file(lookup, NULL, 290f5b1c8a1SJohn Marino X509_FILETYPE_DEFAULT); 291f5b1c8a1SJohn Marino 292f5b1c8a1SJohn Marino lookup = X509_STORE_add_lookup(store, X509_LOOKUP_hash_dir()); 293f5b1c8a1SJohn Marino if (lookup == NULL) 294f5b1c8a1SJohn Marino goto end; 295f5b1c8a1SJohn Marino if (!X509_LOOKUP_add_dir(lookup, crl_config.capath, 296f5b1c8a1SJohn Marino X509_FILETYPE_PEM)) 297f5b1c8a1SJohn Marino X509_LOOKUP_add_dir(lookup, NULL, 298f5b1c8a1SJohn Marino X509_FILETYPE_DEFAULT); 299f5b1c8a1SJohn Marino ERR_clear_error(); 300f5b1c8a1SJohn Marino 301f5b1c8a1SJohn Marino if (!X509_STORE_CTX_init(&ctx, store, NULL, NULL)) { 302f5b1c8a1SJohn Marino BIO_printf(bio_err, 303f5b1c8a1SJohn Marino "Error initialising X509 store\n"); 304f5b1c8a1SJohn Marino goto end; 305f5b1c8a1SJohn Marino } 306f5b1c8a1SJohn Marino i = X509_STORE_get_by_subject(&ctx, X509_LU_X509, 307f5b1c8a1SJohn Marino X509_CRL_get_issuer(x), &xobj); 308f5b1c8a1SJohn Marino if (i <= 0) { 309f5b1c8a1SJohn Marino BIO_printf(bio_err, 310f5b1c8a1SJohn Marino "Error getting CRL issuer certificate\n"); 311f5b1c8a1SJohn Marino goto end; 312f5b1c8a1SJohn Marino } 313f5b1c8a1SJohn Marino pkey = X509_get_pubkey(xobj.data.x509); 314f5b1c8a1SJohn Marino X509_OBJECT_free_contents(&xobj); 315f5b1c8a1SJohn Marino if (!pkey) { 316f5b1c8a1SJohn Marino BIO_printf(bio_err, 317f5b1c8a1SJohn Marino "Error getting CRL issuer public key\n"); 318f5b1c8a1SJohn Marino goto end; 319f5b1c8a1SJohn Marino } 320f5b1c8a1SJohn Marino i = X509_CRL_verify(x, pkey); 321f5b1c8a1SJohn Marino EVP_PKEY_free(pkey); 322f5b1c8a1SJohn Marino if (i < 0) 323f5b1c8a1SJohn Marino goto end; 324f5b1c8a1SJohn Marino if (i == 0) 325f5b1c8a1SJohn Marino BIO_printf(bio_err, "verify failure\n"); 326f5b1c8a1SJohn Marino else 327f5b1c8a1SJohn Marino BIO_printf(bio_err, "verify OK\n"); 328f5b1c8a1SJohn Marino } 329f5b1c8a1SJohn Marino 330f5b1c8a1SJohn Marino /* Print requested information the order that the flags were given. */ 331f5b1c8a1SJohn Marino for (i = 1; i <= argc; i++) { 332f5b1c8a1SJohn Marino if (crl_config.issuer == i) { 333f5b1c8a1SJohn Marino print_name(bio_out, "issuer=", 334f5b1c8a1SJohn Marino X509_CRL_get_issuer(x), nmflag); 335f5b1c8a1SJohn Marino } 336f5b1c8a1SJohn Marino if (crl_config.crlnumber == i) { 337f5b1c8a1SJohn Marino ASN1_INTEGER *crlnum; 338f5b1c8a1SJohn Marino crlnum = X509_CRL_get_ext_d2i(x, 339f5b1c8a1SJohn Marino NID_crl_number, NULL, NULL); 340f5b1c8a1SJohn Marino BIO_printf(bio_out, "crlNumber="); 341f5b1c8a1SJohn Marino if (crlnum) { 342f5b1c8a1SJohn Marino i2a_ASN1_INTEGER(bio_out, crlnum); 343f5b1c8a1SJohn Marino ASN1_INTEGER_free(crlnum); 344f5b1c8a1SJohn Marino } else 345f5b1c8a1SJohn Marino BIO_puts(bio_out, "<NONE>"); 346f5b1c8a1SJohn Marino BIO_printf(bio_out, "\n"); 347f5b1c8a1SJohn Marino } 348f5b1c8a1SJohn Marino if (crl_config.hash == i) { 349f5b1c8a1SJohn Marino BIO_printf(bio_out, "%08lx\n", 350f5b1c8a1SJohn Marino X509_NAME_hash(X509_CRL_get_issuer(x))); 351f5b1c8a1SJohn Marino } 352f5b1c8a1SJohn Marino #ifndef OPENSSL_NO_MD5 353f5b1c8a1SJohn Marino if (crl_config.hash_old == i) { 354f5b1c8a1SJohn Marino BIO_printf(bio_out, "%08lx\n", 355f5b1c8a1SJohn Marino X509_NAME_hash_old(X509_CRL_get_issuer(x))); 356f5b1c8a1SJohn Marino } 357f5b1c8a1SJohn Marino #endif 358f5b1c8a1SJohn Marino if (crl_config.lastupdate == i) { 359f5b1c8a1SJohn Marino BIO_printf(bio_out, "lastUpdate="); 360f5b1c8a1SJohn Marino ASN1_TIME_print(bio_out, 361f5b1c8a1SJohn Marino X509_CRL_get_lastUpdate(x)); 362f5b1c8a1SJohn Marino BIO_printf(bio_out, "\n"); 363f5b1c8a1SJohn Marino } 364f5b1c8a1SJohn Marino if (crl_config.nextupdate == i) { 365f5b1c8a1SJohn Marino BIO_printf(bio_out, "nextUpdate="); 366f5b1c8a1SJohn Marino if (X509_CRL_get_nextUpdate(x)) 367f5b1c8a1SJohn Marino ASN1_TIME_print(bio_out, 368f5b1c8a1SJohn Marino X509_CRL_get_nextUpdate(x)); 369f5b1c8a1SJohn Marino else 370f5b1c8a1SJohn Marino BIO_printf(bio_out, "NONE"); 371f5b1c8a1SJohn Marino BIO_printf(bio_out, "\n"); 372f5b1c8a1SJohn Marino } 373f5b1c8a1SJohn Marino if (crl_config.fingerprint == i) { 374f5b1c8a1SJohn Marino int j; 375f5b1c8a1SJohn Marino unsigned int n; 376f5b1c8a1SJohn Marino unsigned char md[EVP_MAX_MD_SIZE]; 377f5b1c8a1SJohn Marino 378f5b1c8a1SJohn Marino if (!X509_CRL_digest(x, digest, md, &n)) { 379f5b1c8a1SJohn Marino BIO_printf(bio_err, "out of memory\n"); 380f5b1c8a1SJohn Marino goto end; 381f5b1c8a1SJohn Marino } 382f5b1c8a1SJohn Marino BIO_printf(bio_out, "%s Fingerprint=", 383f5b1c8a1SJohn Marino OBJ_nid2sn(EVP_MD_type(digest))); 384f5b1c8a1SJohn Marino for (j = 0; j < (int) n; j++) { 385f5b1c8a1SJohn Marino BIO_printf(bio_out, "%02X%c", md[j], 386f5b1c8a1SJohn Marino (j + 1 == (int)n) ? '\n' : ':'); 387f5b1c8a1SJohn Marino } 388f5b1c8a1SJohn Marino } 389f5b1c8a1SJohn Marino } 390f5b1c8a1SJohn Marino 391f5b1c8a1SJohn Marino out = BIO_new(BIO_s_file()); 392f5b1c8a1SJohn Marino if (out == NULL) { 393f5b1c8a1SJohn Marino ERR_print_errors(bio_err); 394f5b1c8a1SJohn Marino goto end; 395f5b1c8a1SJohn Marino } 396f5b1c8a1SJohn Marino if (crl_config.outfile == NULL) { 397f5b1c8a1SJohn Marino BIO_set_fp(out, stdout, BIO_NOCLOSE); 398f5b1c8a1SJohn Marino } else { 399f5b1c8a1SJohn Marino if (BIO_write_filename(out, crl_config.outfile) <= 0) { 400f5b1c8a1SJohn Marino perror(crl_config.outfile); 401f5b1c8a1SJohn Marino goto end; 402f5b1c8a1SJohn Marino } 403f5b1c8a1SJohn Marino } 404f5b1c8a1SJohn Marino 405f5b1c8a1SJohn Marino if (crl_config.text) 406f5b1c8a1SJohn Marino X509_CRL_print(out, x); 407f5b1c8a1SJohn Marino 408f5b1c8a1SJohn Marino if (crl_config.noout) { 409f5b1c8a1SJohn Marino ret = 0; 410f5b1c8a1SJohn Marino goto end; 411f5b1c8a1SJohn Marino } 412f5b1c8a1SJohn Marino if (crl_config.outformat == FORMAT_ASN1) 413f5b1c8a1SJohn Marino i = (int) i2d_X509_CRL_bio(out, x); 414f5b1c8a1SJohn Marino else if (crl_config.outformat == FORMAT_PEM) 415f5b1c8a1SJohn Marino i = PEM_write_bio_X509_CRL(out, x); 416f5b1c8a1SJohn Marino else { 417f5b1c8a1SJohn Marino BIO_printf(bio_err, 418f5b1c8a1SJohn Marino "bad output format specified for outfile\n"); 419f5b1c8a1SJohn Marino goto end; 420f5b1c8a1SJohn Marino } 421f5b1c8a1SJohn Marino if (!i) { 422f5b1c8a1SJohn Marino BIO_printf(bio_err, "unable to write CRL\n"); 423f5b1c8a1SJohn Marino goto end; 424f5b1c8a1SJohn Marino } 425f5b1c8a1SJohn Marino ret = 0; 426f5b1c8a1SJohn Marino 427f5b1c8a1SJohn Marino end: 428f5b1c8a1SJohn Marino BIO_free_all(out); 429f5b1c8a1SJohn Marino BIO_free_all(bio_out); 430f5b1c8a1SJohn Marino bio_out = NULL; 431f5b1c8a1SJohn Marino X509_CRL_free(x); 432f5b1c8a1SJohn Marino if (store) { 433f5b1c8a1SJohn Marino X509_STORE_CTX_cleanup(&ctx); 434f5b1c8a1SJohn Marino X509_STORE_free(store); 435f5b1c8a1SJohn Marino } 436f5b1c8a1SJohn Marino 437f5b1c8a1SJohn Marino return (ret); 438f5b1c8a1SJohn Marino } 439f5b1c8a1SJohn Marino 440f5b1c8a1SJohn Marino static X509_CRL * 441f5b1c8a1SJohn Marino load_crl(char *infile, int format) 442f5b1c8a1SJohn Marino { 443f5b1c8a1SJohn Marino X509_CRL *x = NULL; 444f5b1c8a1SJohn Marino BIO *in = NULL; 445f5b1c8a1SJohn Marino 446f5b1c8a1SJohn Marino in = BIO_new(BIO_s_file()); 447f5b1c8a1SJohn Marino if (in == NULL) { 448f5b1c8a1SJohn Marino ERR_print_errors(bio_err); 449f5b1c8a1SJohn Marino goto end; 450f5b1c8a1SJohn Marino } 451f5b1c8a1SJohn Marino if (infile == NULL) 452f5b1c8a1SJohn Marino BIO_set_fp(in, stdin, BIO_NOCLOSE); 453f5b1c8a1SJohn Marino else { 454f5b1c8a1SJohn Marino if (BIO_read_filename(in, infile) <= 0) { 455f5b1c8a1SJohn Marino perror(infile); 456f5b1c8a1SJohn Marino goto end; 457f5b1c8a1SJohn Marino } 458f5b1c8a1SJohn Marino } 459f5b1c8a1SJohn Marino if (format == FORMAT_ASN1) 460f5b1c8a1SJohn Marino x = d2i_X509_CRL_bio(in, NULL); 461f5b1c8a1SJohn Marino else if (format == FORMAT_PEM) 462f5b1c8a1SJohn Marino x = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL); 463f5b1c8a1SJohn Marino else { 464f5b1c8a1SJohn Marino BIO_printf(bio_err, 465f5b1c8a1SJohn Marino "bad input format specified for input crl\n"); 466f5b1c8a1SJohn Marino goto end; 467f5b1c8a1SJohn Marino } 468f5b1c8a1SJohn Marino if (x == NULL) { 469f5b1c8a1SJohn Marino BIO_printf(bio_err, "unable to load CRL\n"); 470f5b1c8a1SJohn Marino ERR_print_errors(bio_err); 471f5b1c8a1SJohn Marino goto end; 472f5b1c8a1SJohn Marino } 473f5b1c8a1SJohn Marino 474f5b1c8a1SJohn Marino end: 475f5b1c8a1SJohn Marino BIO_free(in); 476f5b1c8a1SJohn Marino return (x); 477f5b1c8a1SJohn Marino } 478