Main Page | Class List | Directories | File List | Class Members | File Members

crl2p7.c

Go to the documentation of this file.
00001 /* apps/crl2p7.c */
00002 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
00003  * All rights reserved.
00004  *
00005  * This package is an SSL implementation written
00006  * by Eric Young (eay@cryptsoft.com).
00007  * The implementation was written so as to conform with Netscapes SSL.
00008  * 
00009  * This library is free for commercial and non-commercial use as long as
00010  * the following conditions are aheared to.  The following conditions
00011  * apply to all code found in this distribution, be it the RC4, RSA,
00012  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
00013  * included with this distribution is covered by the same copyright terms
00014  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
00015  * 
00016  * Copyright remains Eric Young's, and as such any Copyright notices in
00017  * the code are not to be removed.
00018  * If this package is used in a product, Eric Young should be given attribution
00019  * as the author of the parts of the library used.
00020  * This can be in the form of a textual message at program startup or
00021  * in documentation (online or textual) provided with the package.
00022  * 
00023  * Redistribution and use in source and binary forms, with or without
00024  * modification, are permitted provided that the following conditions
00025  * are met:
00026  * 1. Redistributions of source code must retain the copyright
00027  *    notice, this list of conditions and the following disclaimer.
00028  * 2. Redistributions in binary form must reproduce the above copyright
00029  *    notice, this list of conditions and the following disclaimer in the
00030  *    documentation and/or other materials provided with the distribution.
00031  * 3. All advertising materials mentioning features or use of this software
00032  *    must display the following acknowledgement:
00033  *    "This product includes cryptographic software written by
00034  *     Eric Young (eay@cryptsoft.com)"
00035  *    The word 'cryptographic' can be left out if the rouines from the library
00036  *    being used are not cryptographic related :-).
00037  * 4. If you include any Windows specific code (or a derivative thereof) from 
00038  *    the apps directory (application code) you must include an acknowledgement:
00039  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
00040  * 
00041  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
00042  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00043  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00044  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
00045  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00046  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00047  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00048  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00049  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00050  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00051  * SUCH DAMAGE.
00052  * 
00053  * The licence and distribution terms for any publically available version or
00054  * derivative of this code cannot be changed.  i.e. this code cannot simply be
00055  * copied and put under another distribution licence
00056  * [including the GNU Public Licence.]
00057  */
00058 
00059 /* This was written by Gordon Chaffee <chaffee@plateau.cs.berkeley.edu>
00060  * and donated 'to the cause' along with lots and lots of other fixes to
00061  * the library. */
00062 
00063 #include <stdio.h>
00064 #include <string.h>
00065 #include <sys/types.h>
00066 #include <sys/stat.h>
00067 #include "apps.h"
00068 #include <openssl/err.h>
00069 #include <openssl/evp.h>
00070 #include <openssl/x509.h>
00071 #include <openssl/pkcs7.h>
00072 #include <openssl/pem.h>
00073 #include <openssl/objects.h>
00074 
00075 static int add_certs_from_file(STACK_OF(X509) *stack, char *certfile);
00076 #undef PROG
00077 #define PROG    crl2pkcs7_main
00078 
00079 /* -inform arg  - input format - default PEM (DER or PEM)
00080  * -outform arg - output format - default PEM
00081  * -in arg      - input file - default stdin
00082  * -out arg     - output file - default stdout
00083  */
00084 
00085 int MAIN(int, char **);
00086 
00087 int MAIN(int argc, char **argv)
00088         {
00089         int i,badops=0;
00090         BIO *in=NULL,*out=NULL;
00091         int informat,outformat;
00092         char *infile,*outfile,*prog,*certfile;
00093         PKCS7 *p7 = NULL;
00094         PKCS7_SIGNED *p7s = NULL;
00095         X509_CRL *crl=NULL;
00096         STACK *certflst=NULL;
00097         STACK_OF(X509_CRL) *crl_stack=NULL;
00098         STACK_OF(X509) *cert_stack=NULL;
00099         int ret=1,nocrl=0;
00100 
00101         apps_startup();
00102 
00103         if (bio_err == NULL)
00104                 if ((bio_err=BIO_new(BIO_s_file())) != NULL)
00105                         BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
00106 
00107         infile=NULL;
00108         outfile=NULL;
00109         informat=FORMAT_PEM;
00110         outformat=FORMAT_PEM;
00111 
00112         prog=argv[0];
00113         argc--;
00114         argv++;
00115         while (argc >= 1)
00116                 {
00117                 if      (strcmp(*argv,"-inform") == 0)
00118                         {
00119                         if (--argc < 1) goto bad;
00120                         informat=str2fmt(*(++argv));
00121                         }
00122                 else if (strcmp(*argv,"-outform") == 0)
00123                         {
00124                         if (--argc < 1) goto bad;
00125                         outformat=str2fmt(*(++argv));
00126                         }
00127                 else if (strcmp(*argv,"-in") == 0)
00128                         {
00129                         if (--argc < 1) goto bad;
00130                         infile= *(++argv);
00131                         }
00132                 else if (strcmp(*argv,"-nocrl") == 0)
00133                         {
00134                         nocrl=1;
00135                         }
00136                 else if (strcmp(*argv,"-out") == 0)
00137                         {
00138                         if (--argc < 1) goto bad;
00139                         outfile= *(++argv);
00140                         }
00141                 else if (strcmp(*argv,"-certfile") == 0)
00142                         {
00143                         if (--argc < 1) goto bad;
00144                         if(!certflst) certflst = sk_new_null();
00145                         sk_push(certflst,*(++argv));
00146                         }
00147                 else
00148                         {
00149                         BIO_printf(bio_err,"unknown option %s\n",*argv);
00150                         badops=1;
00151                         break;
00152                         }
00153                 argc--;
00154                 argv++;
00155                 }
00156 
00157         if (badops)
00158                 {
00159 bad:
00160                 BIO_printf(bio_err,"%s [options] <infile >outfile\n",prog);
00161                 BIO_printf(bio_err,"where options are\n");
00162                 BIO_printf(bio_err," -inform arg    input format - DER or PEM\n");
00163                 BIO_printf(bio_err," -outform arg   output format - DER or PEM\n");
00164                 BIO_printf(bio_err," -in arg        input file\n");
00165                 BIO_printf(bio_err," -out arg       output file\n");
00166                 BIO_printf(bio_err," -certfile arg  certificates file of chain to a trusted CA\n");
00167                 BIO_printf(bio_err,"                (can be used more than once)\n");
00168                 BIO_printf(bio_err," -nocrl         no crl to load, just certs from '-certfile'\n");
00169                 ret = 1;
00170                 goto end;
00171                 }
00172 
00173         ERR_load_crypto_strings();
00174 
00175         in=BIO_new(BIO_s_file());
00176         out=BIO_new(BIO_s_file());
00177         if ((in == NULL) || (out == NULL))
00178                 {
00179                 ERR_print_errors(bio_err);
00180                 goto end;
00181                 }
00182 
00183         if (!nocrl)
00184                 {
00185                 if (infile == NULL)
00186                         BIO_set_fp(in,stdin,BIO_NOCLOSE);
00187                 else
00188                         {
00189                         if (BIO_read_filename(in,infile) <= 0)
00190                                 {
00191                                 perror(infile);
00192                                 goto end;
00193                                 }
00194                         }
00195 
00196                 if      (informat == FORMAT_ASN1)
00197                         crl=d2i_X509_CRL_bio(in,NULL);
00198                 else if (informat == FORMAT_PEM)
00199                         crl=PEM_read_bio_X509_CRL(in,NULL,NULL,NULL);
00200                 else    {
00201                         BIO_printf(bio_err,"bad input format specified for input crl\n");
00202                         goto end;
00203                         }
00204                 if (crl == NULL)
00205                         {
00206                         BIO_printf(bio_err,"unable to load CRL\n");
00207                         ERR_print_errors(bio_err);
00208                         goto end;
00209                         }
00210                 }
00211         
00212         if ((p7=PKCS7_new()) == NULL) goto end;
00213         if ((p7s=PKCS7_SIGNED_new()) == NULL) goto end;
00214         p7->type=OBJ_nid2obj(NID_pkcs7_signed);
00215         p7->d.sign=p7s;
00216         p7s->contents->type=OBJ_nid2obj(NID_pkcs7_data);
00217 
00218         if (!ASN1_INTEGER_set(p7s->version,1)) goto end;
00219         if ((crl_stack=sk_X509_CRL_new_null()) == NULL) goto end;
00220         p7s->crl=crl_stack;
00221         if (crl != NULL)
00222                 {
00223                 sk_X509_CRL_push(crl_stack,crl);
00224                 crl=NULL; /* now part of p7 for OPENSSL_freeing */
00225                 }
00226 
00227         if ((cert_stack=sk_X509_new_null()) == NULL) goto end;
00228         p7s->cert=cert_stack;
00229 
00230         if(certflst) for(i = 0; i < sk_num(certflst); i++) {
00231                 certfile = sk_value(certflst, i);
00232                 if (add_certs_from_file(cert_stack,certfile) < 0)
00233                         {
00234                         BIO_printf(bio_err, "error loading certificates\n");
00235                         ERR_print_errors(bio_err);
00236                         goto end;
00237                         }
00238         }
00239 
00240         sk_free(certflst);
00241 
00242         if (outfile == NULL)
00243                 {
00244                 BIO_set_fp(out,stdout,BIO_NOCLOSE);
00245 #ifdef OPENSSL_SYS_VMS
00246                 {
00247                 BIO *tmpbio = BIO_new(BIO_f_linebuffer());
00248                 out = BIO_push(tmpbio, out);
00249                 }
00250 #endif
00251                 }
00252         else
00253                 {
00254                 if (BIO_write_filename(out,outfile) <= 0)
00255                         {
00256                         perror(outfile);
00257                         goto end;
00258                         }
00259                 }
00260 
00261         if      (outformat == FORMAT_ASN1)
00262                 i=i2d_PKCS7_bio(out,p7);
00263         else if (outformat == FORMAT_PEM)
00264                 i=PEM_write_bio_PKCS7(out,p7);
00265         else    {
00266                 BIO_printf(bio_err,"bad output format specified for outfile\n");
00267                 goto end;
00268                 }
00269         if (!i)
00270                 {
00271                 BIO_printf(bio_err,"unable to write pkcs7 object\n");
00272                 ERR_print_errors(bio_err);
00273                 goto end;
00274                 }
00275         ret=0;
00276 end:
00277         if (in != NULL) BIO_free(in);
00278         if (out != NULL) BIO_free_all(out);
00279         if (p7 != NULL) PKCS7_free(p7);
00280         if (crl != NULL) X509_CRL_free(crl);
00281 
00282         apps_shutdown();
00283         OPENSSL_EXIT(ret);
00284         }
00285 
00286 /*
00287  *----------------------------------------------------------------------
00288  * int add_certs_from_file
00289  *
00290  *      Read a list of certificates to be checked from a file.
00291  *
00292  * Results:
00293  *      number of certs added if successful, -1 if not.
00294  *----------------------------------------------------------------------
00295  */
00296 static int add_certs_from_file(STACK_OF(X509) *stack, char *certfile)
00297         {
00298         struct stat st;
00299         BIO *in=NULL;
00300         int count=0;
00301         int ret= -1;
00302         STACK_OF(X509_INFO) *sk=NULL;
00303         X509_INFO *xi;
00304 
00305         if ((stat(certfile,&st) != 0))
00306                 {
00307                 BIO_printf(bio_err,"unable to load the file, %s\n",certfile);
00308                 goto end;
00309                 }
00310 
00311         in=BIO_new(BIO_s_file());
00312         if ((in == NULL) || (BIO_read_filename(in,certfile) <= 0))
00313                 {
00314                 BIO_printf(bio_err,"error opening the file, %s\n",certfile);
00315                 goto end;
00316                 }
00317 
00318         /* This loads from a file, a stack of x509/crl/pkey sets */
00319         sk=PEM_X509_INFO_read_bio(in,NULL,NULL,NULL);
00320         if (sk == NULL) {
00321                 BIO_printf(bio_err,"error reading the file, %s\n",certfile);
00322                 goto end;
00323         }
00324 
00325         /* scan over it and pull out the CRL's */
00326         while (sk_X509_INFO_num(sk))
00327                 {
00328                 xi=sk_X509_INFO_shift(sk);
00329                 if (xi->x509 != NULL)
00330                         {
00331                         sk_X509_push(stack,xi->x509);
00332                         xi->x509=NULL;
00333                         count++;
00334                         }
00335                 X509_INFO_free(xi);
00336                 }
00337 
00338         ret=count;
00339 end:
00340         /* never need to OPENSSL_free x */
00341         if (in != NULL) BIO_free(in);
00342         if (sk != NULL) sk_X509_INFO_free(sk);
00343         return(ret);
00344         }
00345 

© sourcejam.com 2005-2008