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