X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=apps%2Fcrl.c;h=f1c49f3d641787d6c33912188862bab42424d617;hp=1b04f68ecfdb3d4315ecc760822d43a04bf9a639;hb=7ce79a5bfdbcd53ae75f85e94eed665a05b5dea3;hpb=a9be3af5ad4836f7e50f0546311ca90c717b861e diff --git a/apps/crl.c b/apps/crl.c index 1b04f68ecf..f1c49f3d64 100644 --- a/apps/crl.c +++ b/apps/crl.c @@ -72,34 +72,56 @@ #undef POSTFIX #define POSTFIX ".rvk" -static char *crl_usage[]={ +static const char *crl_usage[]={ "usage: crl args\n", "\n", -" -inform arg - input format - default PEM (one of DER, TXT or PEM)\n", +" -inform arg - input format - default PEM (DER or PEM)\n", " -outform arg - output format - default PEM\n", " -text - print out a text format version\n", " -in arg - input file - default stdin\n", " -out arg - output file - default stdout\n", " -hash - print hash value\n", +#ifndef OPENSSL_NO_MD5 +" -hash_old - print old-style (MD5) hash value\n", +#endif +" -fingerprint - print the crl fingerprint\n", " -issuer - print issuer DN\n", " -lastupdate - lastUpdate field\n", " -nextupdate - nextUpdate field\n", +" -crlnumber - print CRL number\n", " -noout - no CRL output\n", +" -CAfile name - verify CRL using certificates in file \"name\"\n", +" -CApath dir - verify CRL using certificates in \"dir\"\n", +" -nameopt arg - various certificate name options\n", NULL }; -static X509_CRL *load_crl(char *file, int format); static BIO *bio_out=NULL; +int MAIN(int, char **); + int MAIN(int argc, char **argv) { + unsigned long nmflag = 0; X509_CRL *x=NULL; - int ret=1,i,num,badops=0; + char *CAfile = NULL, *CApath = NULL; + int ret=1,i,num,badops=0,badsig=0; BIO *out=NULL; - int informat,outformat; - char *infile=NULL,*outfile=NULL; + int informat,outformat, keyformat; + char *infile=NULL,*outfile=NULL, *crldiff = NULL, *keyfile = NULL; int hash=0,issuer=0,lastupdate=0,nextupdate=0,noout=0,text=0; - char **pp,buf[256]; +#ifndef OPENSSL_NO_MD5 + int hash_old=0; +#endif + int fingerprint = 0, crlnumber = 0; + const char **pp; + X509_STORE *store = NULL; + X509_STORE_CTX ctx; + X509_LOOKUP *lookup = NULL; + X509_OBJECT xobj; + EVP_PKEY *pkey; + int do_ver = 0; + const EVP_MD *md_alg,*digest=EVP_sha1(); apps_startup(); @@ -107,12 +129,24 @@ int MAIN(int argc, char **argv) if ((bio_err=BIO_new(BIO_s_file())) != NULL) BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT); + if (!load_config(bio_err, NULL)) + goto end; + if (bio_out == NULL) if ((bio_out=BIO_new(BIO_s_file())) != NULL) + { BIO_set_fp(bio_out,stdout,BIO_NOCLOSE); +#ifdef OPENSSL_SYS_VMS + { + BIO *tmpbio = BIO_new(BIO_f_linebuffer()); + bio_out = BIO_push(tmpbio, bio_out); + } +#endif + } informat=FORMAT_PEM; outformat=FORMAT_PEM; + keyformat=FORMAT_PEM; argc--; argv++; @@ -141,15 +175,53 @@ int MAIN(int argc, char **argv) if (--argc < 1) goto bad; infile= *(++argv); } + else if (strcmp(*argv,"-gendelta") == 0) + { + if (--argc < 1) goto bad; + crldiff= *(++argv); + } + else if (strcmp(*argv,"-key") == 0) + { + if (--argc < 1) goto bad; + keyfile= *(++argv); + } + else if (strcmp(*argv,"-keyform") == 0) + { + if (--argc < 1) goto bad; + keyformat=str2fmt(*(++argv)); + } else if (strcmp(*argv,"-out") == 0) { if (--argc < 1) goto bad; outfile= *(++argv); } + else if (strcmp(*argv,"-CApath") == 0) + { + if (--argc < 1) goto bad; + CApath = *(++argv); + do_ver = 1; + } + else if (strcmp(*argv,"-CAfile") == 0) + { + if (--argc < 1) goto bad; + CAfile = *(++argv); + do_ver = 1; + } + else if (strcmp(*argv,"-verify") == 0) + do_ver = 1; else if (strcmp(*argv,"-text") == 0) text = 1; else if (strcmp(*argv,"-hash") == 0) hash= ++num; +#ifndef OPENSSL_NO_MD5 + else if (strcmp(*argv,"-hash_old") == 0) + hash_old= ++num; +#endif + else if (strcmp(*argv,"-nameopt") == 0) + { + if (--argc < 1) goto bad; + if (!set_name_ex(&nmflag, *(++argv))) goto bad; + } else if (strcmp(*argv,"-issuer") == 0) issuer= ++num; else if (strcmp(*argv,"-lastupdate") == 0) @@ -158,6 +230,17 @@ int MAIN(int argc, char **argv) nextupdate= ++num; else if (strcmp(*argv,"-noout") == 0) noout= ++num; + else if (strcmp(*argv,"-fingerprint") == 0) + fingerprint= ++num; + else if (strcmp(*argv,"-crlnumber") == 0) + crlnumber= ++num; + else if (strcmp(*argv,"-badsig") == 0) + badsig = 1; + else if ((md_alg=EVP_get_digestbyname(*argv + 1))) + { + /* ok */ + digest=md_alg; + } else { BIO_printf(bio_err,"unknown option %s\n",*argv); @@ -172,45 +255,160 @@ int MAIN(int argc, char **argv) { bad: for (pp=crl_usage; (*pp != NULL); pp++) - BIO_printf(bio_err,*pp); + BIO_printf(bio_err,"%s",*pp); goto end; } ERR_load_crypto_strings(); - X509V3_add_standard_extensions(); x=load_crl(infile,informat); if (x == NULL) { goto end; } + if(do_ver) { + store = X509_STORE_new(); + lookup=X509_STORE_add_lookup(store,X509_LOOKUP_file()); + if (lookup == NULL) goto end; + if (!X509_LOOKUP_load_file(lookup,CAfile,X509_FILETYPE_PEM)) + X509_LOOKUP_load_file(lookup,NULL,X509_FILETYPE_DEFAULT); + + lookup=X509_STORE_add_lookup(store,X509_LOOKUP_hash_dir()); + if (lookup == NULL) goto end; + if (!X509_LOOKUP_add_dir(lookup,CApath,X509_FILETYPE_PEM)) + X509_LOOKUP_add_dir(lookup,NULL,X509_FILETYPE_DEFAULT); + ERR_clear_error(); + + if(!X509_STORE_CTX_init(&ctx, store, NULL, NULL)) { + BIO_printf(bio_err, + "Error initialising X509 store\n"); + goto end; + } + + i = X509_STORE_get_by_subject(&ctx, X509_LU_X509, + X509_CRL_get_issuer(x), &xobj); + if(i <= 0) { + BIO_printf(bio_err, + "Error getting CRL issuer certificate\n"); + goto end; + } + pkey = X509_get_pubkey(xobj.data.x509); + X509_OBJECT_free_contents(&xobj); + if(!pkey) { + BIO_printf(bio_err, + "Error getting CRL issuer public key\n"); + goto end; + } + i = X509_CRL_verify(x, pkey); + EVP_PKEY_free(pkey); + if(i < 0) goto end; + if(i == 0) BIO_printf(bio_err, "verify failure\n"); + else BIO_printf(bio_err, "verify OK\n"); + } + + if (crldiff) + { + X509_CRL *newcrl, *delta; + if (!keyfile) + { + BIO_puts(bio_err, "Missing CRL signing key\n"); + goto end; + } + newcrl = load_crl(crldiff,informat); + if (!newcrl) + goto end; + pkey = load_key(bio_err, keyfile, keyformat, 0, NULL, NULL, + "CRL signing key"); + if (!pkey) + { + X509_CRL_free(newcrl); + goto end; + } + delta = X509_CRL_diff(x, newcrl, pkey, digest, 0); + X509_CRL_free(newcrl); + EVP_PKEY_free(pkey); + if (delta) + { + X509_CRL_free(x); + x = delta; + } + else + { + BIO_puts(bio_err, "Error creating delta CRL\n"); + goto end; + } + } + if (num) { for (i=1; i<=num; i++) { if (issuer == i) { - X509_NAME_oneline(x->crl->issuer,buf,256); - BIO_printf(bio_out,"issuer= %s\n",buf); + print_name(bio_out, "issuer=", X509_CRL_get_issuer(x), nmflag); + } + if (crlnumber == i) + { + ASN1_INTEGER *crlnum; + crlnum = X509_CRL_get_ext_d2i(x, NID_crl_number, + NULL, NULL); + BIO_printf(bio_out,"crlNumber="); + if (crlnum) + { + i2a_ASN1_INTEGER(bio_out, crlnum); + ASN1_INTEGER_free(crlnum); + } + else + BIO_puts(bio_out, ""); + BIO_printf(bio_out,"\n"); } - if (hash == i) { BIO_printf(bio_out,"%08lx\n", - X509_NAME_hash(x->crl->issuer)); + X509_NAME_hash(X509_CRL_get_issuer(x))); + } +#ifndef OPENSSL_NO_MD5 + if (hash_old == i) + { + BIO_printf(bio_out,"%08lx\n", + X509_NAME_hash_old( + X509_CRL_get_issuer(x))); } +#endif if (lastupdate == i) { BIO_printf(bio_out,"lastUpdate="); - ASN1_TIME_print(bio_out,x->crl->lastUpdate); + ASN1_TIME_print(bio_out, + X509_CRL_get_lastUpdate(x)); BIO_printf(bio_out,"\n"); } if (nextupdate == i) { BIO_printf(bio_out,"nextUpdate="); - if (x->crl->nextUpdate != NULL) - ASN1_TIME_print(bio_out,x->crl->nextUpdate); + if (X509_CRL_get_nextUpdate(x)) + ASN1_TIME_print(bio_out, + X509_CRL_get_nextUpdate(x)); else BIO_printf(bio_out,"NONE"); BIO_printf(bio_out,"\n"); } + if (fingerprint == i) + { + int j; + unsigned int n; + unsigned char md[EVP_MAX_MD_SIZE]; + + if (!X509_CRL_digest(x,digest,md,&n)) + { + BIO_printf(bio_err,"out of memory\n"); + goto end; + } + BIO_printf(bio_out,"%s Fingerprint=", + OBJ_nid2sn(EVP_MD_type(digest))); + for (j=0; j<(int)n; j++) + { + BIO_printf(bio_out,"%02X%c",md[j], + (j+1 == (int)n) + ?'\n':':'); + } + } } } @@ -222,7 +420,15 @@ bad: } if (outfile == NULL) + { BIO_set_fp(out,stdout,BIO_NOCLOSE); +#ifdef OPENSSL_SYS_VMS + { + BIO *tmpbio = BIO_new(BIO_f_linebuffer()); + out = BIO_push(tmpbio, out); + } +#endif + } else { if (BIO_write_filename(out,outfile) <= 0) @@ -234,7 +440,14 @@ bad: if (text) X509_CRL_print(out, x); - if (noout) goto end; + if (noout) + { + ret = 0; + goto end; + } + + if (badsig) + x->signature->data[x->signature->length - 1] ^= 0x1; if (outformat == FORMAT_ASN1) i=(int)i2d_X509_CRL_bio(out,x); @@ -248,52 +461,16 @@ bad: if (!i) { BIO_printf(bio_err,"unable to write CRL\n"); goto end; } ret=0; end: - BIO_free(out); - BIO_free(bio_out); + if (ret != 0) + ERR_print_errors(bio_err); + BIO_free_all(out); + BIO_free_all(bio_out); + bio_out=NULL; X509_CRL_free(x); - X509V3_EXT_cleanup(); - EXIT(ret); + if(store) { + X509_STORE_CTX_cleanup(&ctx); + X509_STORE_free(store); } - -static X509_CRL *load_crl(char *infile, int format) - { - X509_CRL *x=NULL; - BIO *in=NULL; - - in=BIO_new(BIO_s_file()); - if (in == NULL) - { - ERR_print_errors(bio_err); - goto end; - } - - if (infile == NULL) - BIO_set_fp(in,stdin,BIO_NOCLOSE); - else - { - if (BIO_read_filename(in,infile) <= 0) - { - perror(infile); - goto end; - } - } - if (format == FORMAT_ASN1) - x=d2i_X509_CRL_bio(in,NULL); - else if (format == FORMAT_PEM) - x=PEM_read_bio_X509_CRL(in,NULL,NULL); - else { - BIO_printf(bio_err,"bad input format specified for input crl\n"); - goto end; - } - if (x == NULL) - { - BIO_printf(bio_err,"unable to load CRL\n"); - ERR_print_errors(bio_err); - goto end; - } - -end: - BIO_free(in); - return(x); + apps_shutdown(); + OPENSSL_EXIT(ret); } -