pkcs7.c revision 296341
1194206Ssimon/* apps/pkcs7.c */ 2160814Ssimon/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 3160814Ssimon * All rights reserved. 4194206Ssimon * 5194206Ssimon * This package is an SSL implementation written 6194206Ssimon * by Eric Young (eay@cryptsoft.com). 7194206Ssimon * The implementation was written so as to conform with Netscapes SSL. 8194206Ssimon * 9194206Ssimon * This library is free for commercial and non-commercial use as long as 10194206Ssimon * the following conditions are aheared to. The following conditions 11194206Ssimon * apply to all code found in this distribution, be it the RC4, RSA, 12194206Ssimon * lhash, DES, etc., code; not just the SSL code. The SSL documentation 13194206Ssimon * included with this distribution is covered by the same copyright terms 14194206Ssimon * except that the holder is Tim Hudson (tjh@cryptsoft.com). 15194206Ssimon * 16194206Ssimon * Copyright remains Eric Young's, and as such any Copyright notices in 17194206Ssimon * the code are not to be removed. 18194206Ssimon * If this package is used in a product, Eric Young should be given attribution 19194206Ssimon * as the author of the parts of the library used. 20194206Ssimon * This can be in the form of a textual message at program startup or 21194206Ssimon * in documentation (online or textual) provided with the package. 22194206Ssimon * 23194206Ssimon * Redistribution and use in source and binary forms, with or without 24194206Ssimon * modification, are permitted provided that the following conditions 25194206Ssimon * are met: 26194206Ssimon * 1. Redistributions of source code must retain the copyright 27194206Ssimon * notice, this list of conditions and the following disclaimer. 28194206Ssimon * 2. Redistributions in binary form must reproduce the above copyright 29194206Ssimon * notice, this list of conditions and the following disclaimer in the 30194206Ssimon * documentation and/or other materials provided with the distribution. 31194206Ssimon * 3. All advertising materials mentioning features or use of this software 32194206Ssimon * must display the following acknowledgement: 33194206Ssimon * "This product includes cryptographic software written by 34194206Ssimon * Eric Young (eay@cryptsoft.com)" 35194206Ssimon * The word 'cryptographic' can be left out if the rouines from the library 36194206Ssimon * being used are not cryptographic related :-). 37194206Ssimon * 4. If you include any Windows specific code (or a derivative thereof) from 38194206Ssimon * the apps directory (application code) you must include an acknowledgement: 39194206Ssimon * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 40194206Ssimon * 41194206Ssimon * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 42194206Ssimon * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 43194206Ssimon * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 44194206Ssimon * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 45160814Ssimon * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 46194206Ssimon * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 47160814Ssimon * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 48160814Ssimon * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 49160814Ssimon * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 50160814Ssimon * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 51160814Ssimon * SUCH DAMAGE. 52194206Ssimon * 53160814Ssimon * The licence and distribution terms for any publically available version or 54160814Ssimon * derivative of this code cannot be changed. i.e. this code cannot simply be 55160814Ssimon * copied and put under another distribution licence 56160814Ssimon * [including the GNU Public Licence.] 57160814Ssimon */ 58194206Ssimon 59160814Ssimon#include <stdio.h> 60194206Ssimon#include <stdlib.h> 61194206Ssimon#include <string.h> 62160814Ssimon#include <time.h> 63194206Ssimon#include "apps.h" 64160814Ssimon#include <openssl/err.h> 65194206Ssimon#include <openssl/objects.h> 66194206Ssimon#include <openssl/evp.h> 67194206Ssimon#include <openssl/x509.h> 68194206Ssimon#include <openssl/pkcs7.h> 69194206Ssimon#include <openssl/pem.h> 70160814Ssimon 71160814Ssimon#undef PROG 72160814Ssimon#define PROG pkcs7_main 73160814Ssimon 74160814Ssimon/*- 75160814Ssimon * -inform arg - input format - default PEM (DER or PEM) 76160814Ssimon * -outform arg - output format - default PEM 77160814Ssimon * -in arg - input file - default stdin 78160814Ssimon * -out arg - output file - default stdout 79160814Ssimon * -print_certs 80160814Ssimon */ 81160814Ssimon 82160814Ssimonint MAIN(int, char **); 83160814Ssimon 84194206Ssimonint MAIN(int argc, char **argv) 85194206Ssimon{ 86194206Ssimon PKCS7 *p7 = NULL; 87194206Ssimon int i, badops = 0; 88194206Ssimon BIO *in = NULL, *out = NULL; 89194206Ssimon int informat, outformat; 90194206Ssimon char *infile, *outfile, *prog; 91194206Ssimon int print_certs = 0, text = 0, noout = 0, p7_print = 0; 92194206Ssimon int ret = 1; 93160814Ssimon#ifndef OPENSSL_NO_ENGINE 94160814Ssimon char *engine = NULL; 95160814Ssimon#endif 96194206Ssimon 97194206Ssimon apps_startup(); 98194206Ssimon 99194206Ssimon if (bio_err == NULL) 100194206Ssimon if ((bio_err = BIO_new(BIO_s_file())) != NULL) 101194206Ssimon BIO_set_fp(bio_err, stderr, BIO_NOCLOSE | BIO_FP_TEXT); 102194206Ssimon 103194206Ssimon if (!load_config(bio_err, NULL)) 104194206Ssimon goto end; 105194206Ssimon 106194206Ssimon infile = NULL; 107194206Ssimon outfile = NULL; 108194206Ssimon informat = FORMAT_PEM; 109194206Ssimon outformat = FORMAT_PEM; 110194206Ssimon 111194206Ssimon prog = argv[0]; 112194206Ssimon argc--; 113194206Ssimon argv++; 114194206Ssimon while (argc >= 1) { 115194206Ssimon if (strcmp(*argv, "-inform") == 0) { 116194206Ssimon if (--argc < 1) 117194206Ssimon goto bad; 118194206Ssimon informat = str2fmt(*(++argv)); 119194206Ssimon } else if (strcmp(*argv, "-outform") == 0) { 120194206Ssimon if (--argc < 1) 121194206Ssimon goto bad; 122194206Ssimon outformat = str2fmt(*(++argv)); 123194206Ssimon } else if (strcmp(*argv, "-in") == 0) { 124194206Ssimon if (--argc < 1) 125194206Ssimon goto bad; 126194206Ssimon infile = *(++argv); 127194206Ssimon } else if (strcmp(*argv, "-out") == 0) { 128194206Ssimon if (--argc < 1) 129194206Ssimon goto bad; 130160814Ssimon outfile = *(++argv); 131194206Ssimon } else if (strcmp(*argv, "-noout") == 0) 132194206Ssimon noout = 1; 133160814Ssimon else if (strcmp(*argv, "-text") == 0) 134238405Sjkim text = 1; 135194206Ssimon else if (strcmp(*argv, "-print") == 0) 136194206Ssimon p7_print = 1; 137238405Sjkim else if (strcmp(*argv, "-print_certs") == 0) 138194206Ssimon print_certs = 1; 139194206Ssimon#ifndef OPENSSL_NO_ENGINE 140194206Ssimon else if (strcmp(*argv, "-engine") == 0) { 141238405Sjkim if (--argc < 1) 142194206Ssimon goto bad; 143160814Ssimon engine = *(++argv); 144160814Ssimon } 145160814Ssimon#endif 146194206Ssimon else { 147160814Ssimon BIO_printf(bio_err, "unknown option %s\n", *argv); 148160814Ssimon badops = 1; 149160814Ssimon break; 150160814Ssimon } 151160814Ssimon argc--; 152160814Ssimon argv++; 153160814Ssimon } 154194206Ssimon 155160814Ssimon if (badops) { 156160814Ssimon bad: 157160814Ssimon BIO_printf(bio_err, "%s [options] <infile >outfile\n", prog); 158160814Ssimon BIO_printf(bio_err, "where options are\n"); 159160814Ssimon BIO_printf(bio_err, " -inform arg input format - DER or PEM\n"); 160160814Ssimon BIO_printf(bio_err, " -outform arg output format - DER or PEM\n"); 161194206Ssimon BIO_printf(bio_err, " -in arg input file\n"); 162160814Ssimon BIO_printf(bio_err, " -out arg output file\n"); 163160814Ssimon BIO_printf(bio_err, 164160814Ssimon " -print_certs print any certs or crl in the input\n"); 165160814Ssimon BIO_printf(bio_err, 166160814Ssimon " -text print full details of certificates\n"); 167160814Ssimon BIO_printf(bio_err, " -noout don't output encoded data\n"); 168160814Ssimon#ifndef OPENSSL_NO_ENGINE 169194206Ssimon BIO_printf(bio_err, 170194206Ssimon " -engine e use engine e, possibly a hardware device.\n"); 171194206Ssimon#endif 172194206Ssimon ret = 1; 173194206Ssimon goto end; 174194206Ssimon } 175194206Ssimon 176194206Ssimon ERR_load_crypto_strings(); 177194206Ssimon 178194206Ssimon#ifndef OPENSSL_NO_ENGINE 179194206Ssimon setup_engine(bio_err, engine, 0); 180194206Ssimon#endif 181194206Ssimon 182194206Ssimon in = BIO_new(BIO_s_file()); 183194206Ssimon out = BIO_new(BIO_s_file()); 184160814Ssimon if ((in == NULL) || (out == NULL)) { 185194206Ssimon ERR_print_errors(bio_err); 186194206Ssimon goto end; 187160814Ssimon } 188160814Ssimon 189160814Ssimon if (infile == NULL) 190194206Ssimon BIO_set_fp(in, stdin, BIO_NOCLOSE); 191194206Ssimon else { 192194206Ssimon if (BIO_read_filename(in, infile) <= 0) { 193194206Ssimon BIO_printf(bio_err, "unable to load input file\n"); 194194206Ssimon ERR_print_errors(bio_err); 195194206Ssimon goto end; 196194206Ssimon } 197194206Ssimon } 198194206Ssimon 199194206Ssimon if (informat == FORMAT_ASN1) 200194206Ssimon p7 = d2i_PKCS7_bio(in, NULL); 201194206Ssimon else if (informat == FORMAT_PEM) 202194206Ssimon p7 = PEM_read_bio_PKCS7(in, NULL, NULL, NULL); 203194206Ssimon else { 204194206Ssimon BIO_printf(bio_err, "bad input format specified for pkcs7 object\n"); 205194206Ssimon goto end; 206194206Ssimon } 207194206Ssimon if (p7 == NULL) { 208194206Ssimon BIO_printf(bio_err, "unable to load PKCS7 object\n"); 209194206Ssimon ERR_print_errors(bio_err); 210194206Ssimon goto end; 211194206Ssimon } 212194206Ssimon 213194206Ssimon if (outfile == NULL) { 214194206Ssimon BIO_set_fp(out, stdout, BIO_NOCLOSE); 215276861Sjkim#ifdef OPENSSL_SYS_VMS 216194206Ssimon { 217194206Ssimon BIO *tmpbio = BIO_new(BIO_f_linebuffer()); 218194206Ssimon out = BIO_push(tmpbio, out); 219194206Ssimon } 220194206Ssimon#endif 221194206Ssimon } else { 222160814Ssimon if (BIO_write_filename(out, outfile) <= 0) { 223160814Ssimon perror(outfile); 224194206Ssimon goto end; 225194206Ssimon } 226194206Ssimon } 227160814Ssimon 228160814Ssimon if (p7_print) 229160814Ssimon PKCS7_print_ctx(out, p7, 0, NULL); 230160814Ssimon 231160814Ssimon if (print_certs) { 232160814Ssimon STACK_OF(X509) *certs = NULL; 233194206Ssimon STACK_OF(X509_CRL) *crls = NULL; 234194206Ssimon 235194206Ssimon i = OBJ_obj2nid(p7->type); 236160814Ssimon switch (i) { 237160814Ssimon case NID_pkcs7_signed: 238160814Ssimon certs = p7->d.sign->cert; 239160814Ssimon crls = p7->d.sign->crl; 240194206Ssimon break; 241194206Ssimon case NID_pkcs7_signedAndEnveloped: 242160814Ssimon certs = p7->d.signed_and_enveloped->cert; 243160814Ssimon crls = p7->d.signed_and_enveloped->crl; 244160814Ssimon break; 245160814Ssimon default: 246160814Ssimon break; 247160814Ssimon } 248194206Ssimon 249194206Ssimon if (certs != NULL) { 250194206Ssimon X509 *x; 251194206Ssimon 252160814Ssimon for (i = 0; i < sk_X509_num(certs); i++) { 253160814Ssimon x = sk_X509_value(certs, i); 254160814Ssimon if (text) 255160814Ssimon X509_print(out, x); 256160814Ssimon else 257160814Ssimon dump_cert_text(out, x); 258160814Ssimon 259160814Ssimon if (!noout) 260160814Ssimon PEM_write_bio_X509(out, x); 261160814Ssimon BIO_puts(out, "\n"); 262160814Ssimon } 263160814Ssimon } 264160814Ssimon if (crls != NULL) { 265160814Ssimon X509_CRL *crl; 266160814Ssimon 267160814Ssimon for (i = 0; i < sk_X509_CRL_num(crls); i++) { 268160814Ssimon crl = sk_X509_CRL_value(crls, i); 269160814Ssimon 270160814Ssimon X509_CRL_print(out, crl); 271160814Ssimon 272160814Ssimon if (!noout) 273160814Ssimon PEM_write_bio_X509_CRL(out, crl); 274194206Ssimon BIO_puts(out, "\n"); 275194206Ssimon } 276194206Ssimon } 277194206Ssimon 278194206Ssimon ret = 0; 279194206Ssimon goto end; 280194206Ssimon } 281194206Ssimon 282194206Ssimon if (!noout) { 283194206Ssimon if (outformat == FORMAT_ASN1) 284194206Ssimon i = i2d_PKCS7_bio(out, p7); 285194206Ssimon else if (outformat == FORMAT_PEM) 286160814Ssimon i = PEM_write_bio_PKCS7(out, p7); 287160814Ssimon else { 288160814Ssimon BIO_printf(bio_err, "bad output format specified for outfile\n"); 289160814Ssimon goto end; 290160814Ssimon } 291160814Ssimon 292194206Ssimon if (!i) { 293160814Ssimon BIO_printf(bio_err, "unable to write pkcs7 object\n"); 294160814Ssimon ERR_print_errors(bio_err); 295160814Ssimon goto end; 296160814Ssimon } 297160814Ssimon } 298160814Ssimon ret = 0; 299160814Ssimon end: 300160814Ssimon if (p7 != NULL) 301194206Ssimon PKCS7_free(p7); 302160814Ssimon if (in != NULL) 303160814Ssimon BIO_free(in); 304160814Ssimon if (out != NULL) 305160814Ssimon BIO_free_all(out); 306160814Ssimon apps_shutdown(); 307160814Ssimon OPENSSL_EXIT(ret); 308160814Ssimon} 309194206Ssimon