os/ossrv/ssl/libcrypto/src/crypto/pkcs7/dec.c
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 /* crypto/pkcs7/verify.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 #include <stdio.h>
    59 #include <stdlib.h>
    60 #include <string.h>
    61 #include <openssl/bio.h>
    62 #include <openssl/x509.h>
    63 #include <openssl/pem.h>
    64 #include <openssl/err.h>
    65 #include <openssl/asn1.h>
    66 
    67 int verify_callback(int ok, X509_STORE_CTX *ctx);
    68 
    69 BIO *bio_err=NULL;
    70 
    71 int main(argc,argv)
    72 int argc;
    73 char *argv[];
    74 	{
    75 	char *keyfile=NULL;
    76 	BIO *in;
    77 	EVP_PKEY *pkey;
    78 	X509 *x509;
    79 	PKCS7 *p7;
    80 	PKCS7_SIGNER_INFO *si;
    81 	X509_STORE_CTX cert_ctx;
    82 	X509_STORE *cert_store=NULL;
    83 	BIO *data,*detached=NULL,*p7bio=NULL;
    84 	char buf[1024*4];
    85 	unsigned char *pp;
    86 	int i,printit=0;
    87 	STACK_OF(PKCS7_SIGNER_INFO) *sk;
    88 
    89 	OpenSSL_add_all_algorithms();
    90 	bio_err=BIO_new_fp(stderr,BIO_NOCLOSE);
    91 
    92 	data=BIO_new(BIO_s_file());
    93 	pp=NULL;
    94 	while (argc > 1)
    95 		{
    96 		argc--;
    97 		argv++;
    98 		if (strcmp(argv[0],"-p") == 0)
    99 			{
   100 			printit=1;
   101 			}
   102 		else if ((strcmp(argv[0],"-k") == 0) && (argc >= 2)) {
   103 			keyfile = argv[1];
   104 			argc-=1;
   105 			argv+=1;
   106 		} else if ((strcmp(argv[0],"-d") == 0) && (argc >= 2))
   107 			{
   108 			detached=BIO_new(BIO_s_file());
   109 			if (!BIO_read_filename(detached,argv[1]))
   110 				goto err;
   111 			argc-=1;
   112 			argv+=1;
   113 			}
   114 		else break;
   115 		}
   116 
   117 	 if (!BIO_read_filename(data,argv[0])) goto err; 
   118 
   119 	if(!keyfile) {
   120 		fprintf(stderr, "No private key file specified\n");
   121 		goto err;
   122 	}
   123 
   124         if ((in=BIO_new_file(keyfile,"r")) == NULL) goto err;
   125         if ((x509=PEM_read_bio_X509(in,NULL,NULL,NULL)) == NULL) goto err;
   126         BIO_reset(in);
   127         if ((pkey=PEM_read_bio_PrivateKey(in,NULL,NULL,NULL)) == NULL)
   128 		goto err;
   129         BIO_free(in);
   130 
   131 	if (pp == NULL)
   132 		BIO_set_fp(data,stdin,BIO_NOCLOSE);
   133 
   134 
   135 	/* Load the PKCS7 object from a file */
   136 	if ((p7=PEM_read_bio_PKCS7(data,NULL,NULL,NULL)) == NULL) goto err;
   137 
   138 
   139 
   140 	/* This stuff is being setup for certificate verification.
   141 	 * When using SSL, it could be replaced with a 
   142 	 * cert_stre=SSL_CTX_get_cert_store(ssl_ctx); */
   143 	cert_store=X509_STORE_new();
   144 	X509_STORE_set_default_paths(cert_store);
   145 	X509_STORE_load_locations(cert_store,NULL,"../../certs");
   146 	X509_STORE_set_verify_cb_func(cert_store,verify_callback);
   147 
   148 	ERR_clear_error();
   149 
   150 	/* We need to process the data */
   151 	/* We cannot support detached encryption */
   152 	p7bio=PKCS7_dataDecode(p7,pkey,detached,x509);
   153 
   154 	if (p7bio == NULL)
   155 		{
   156 		printf("problems decoding\n");
   157 		goto err;
   158 		}
   159 
   160 	/* We now have to 'read' from p7bio to calculate digests etc. */
   161 	for (;;)
   162 		{
   163 		i=BIO_read(p7bio,buf,sizeof(buf));
   164 		/* print it? */
   165 		if (i <= 0) break;
   166 		fwrite(buf,1, i, stdout);
   167 		}
   168 
   169 	/* We can now verify signatures */
   170 	sk=PKCS7_get_signer_info(p7);
   171 	if (sk == NULL)
   172 		{
   173 		fprintf(stderr, "there are no signatures on this data\n");
   174 		}
   175 	else
   176 		{
   177 		/* Ok, first we need to, for each subject entry,
   178 		 * see if we can verify */
   179 		ERR_clear_error();
   180 		for (i=0; i<sk_PKCS7_SIGNER_INFO_num(sk); i++)
   181 			{
   182 			si=sk_PKCS7_SIGNER_INFO_value(sk,i);
   183 			i=PKCS7_dataVerify(cert_store,&cert_ctx,p7bio,p7,si);
   184 			if (i <= 0)
   185 				goto err;
   186 			else
   187 				fprintf(stderr,"Signature verified\n");
   188 			}
   189 		}
   190 	X509_STORE_free(cert_store);
   191 
   192 	exit(0);
   193 err:
   194 	ERR_load_crypto_strings();
   195 	ERR_print_errors_fp(stderr);
   196 	exit(1);
   197 	}
   198 
   199 /* should be X509 * but we can just have them as char *. */
   200 int verify_callback(int ok, X509_STORE_CTX *ctx)
   201 	{
   202 	char buf[256];
   203 	X509 *err_cert;
   204 	int err,depth;
   205 
   206 	err_cert=X509_STORE_CTX_get_current_cert(ctx);
   207 	err=	X509_STORE_CTX_get_error(ctx);
   208 	depth=	X509_STORE_CTX_get_error_depth(ctx);
   209 
   210 	X509_NAME_oneline(X509_get_subject_name(err_cert),buf,256);
   211 	BIO_printf(bio_err,"depth=%d %s\n",depth,buf);
   212 	if (!ok)
   213 		{
   214 		BIO_printf(bio_err,"verify error:num=%d:%s\n",err,
   215 			X509_verify_cert_error_string(err));
   216 		if (depth < 6)
   217 			{
   218 			ok=1;
   219 			X509_STORE_CTX_set_error(ctx,X509_V_OK);
   220 			}
   221 		else
   222 			{
   223 			ok=0;
   224 			X509_STORE_CTX_set_error(ctx,X509_V_ERR_CERT_CHAIN_TOO_LONG);
   225 			}
   226 		}
   227 	switch (ctx->error)
   228 		{
   229 	case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
   230 		X509_NAME_oneline(X509_get_issuer_name(ctx->current_cert),buf,256);
   231 		BIO_printf(bio_err,"issuer= %s\n",buf);
   232 		break;
   233 	case X509_V_ERR_CERT_NOT_YET_VALID:
   234 	case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
   235 		BIO_printf(bio_err,"notBefore=");
   236 		ASN1_UTCTIME_print(bio_err,X509_get_notBefore(ctx->current_cert));
   237 		BIO_printf(bio_err,"\n");
   238 		break;
   239 	case X509_V_ERR_CERT_HAS_EXPIRED:
   240 	case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
   241 		BIO_printf(bio_err,"notAfter=");
   242 		ASN1_UTCTIME_print(bio_err,X509_get_notAfter(ctx->current_cert));
   243 		BIO_printf(bio_err,"\n");
   244 		break;
   245 		}
   246 	BIO_printf(bio_err,"verify return:%d\n",ok);
   247 	return(ok);
   248 	}