X-Git-Url: https://git.openssl.org/?p=openssl.git;a=blobdiff_plain;f=apps%2Fcms.c;h=b9eec2432a5f16a03294a5522580fd38f9d5ef9f;hp=e732757b2a7f17980c9da616135650e51bc0c913;hb=efba7787cd0036d667943070265ca8aef59e9d00;hpb=43db7aa2de68e04c5b5894e7af5dba54ee1fa363 diff --git a/apps/cms.c b/apps/cms.c index e732757b2a..b9eec2432a 100644 --- a/apps/cms.c +++ b/apps/cms.c @@ -1,54 +1,10 @@ /* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL - * project. - */ -/* ==================================================================== - * Copyright (c) 2008 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. + * Copyright 2008-2016 The OpenSSL Project Authors. All Rights Reserved. * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html */ /* CMS utility function */ @@ -134,15 +90,15 @@ OPTIONS cms_options[] = { " cert.pem... recipient certs for encryption\n"}, {OPT_HELP_STR, 1, '-', "Valid options are:\n"}, {"help", OPT_HELP, '-', "Display this summary"}, - {"inform", OPT_INFORM, 'F', "Input format SMIME (default), PEM or DER"}, - {"outform", OPT_OUTFORM, 'F', + {"inform", OPT_INFORM, 'c', "Input format SMIME (default), PEM or DER"}, + {"outform", OPT_OUTFORM, 'c', "Output format SMIME (default), PEM or DER"}, {"in", OPT_IN, '<', "Input file"}, {"out", OPT_OUT, '>', "Output file"}, {"encrypt", OPT_ENCRYPT, '-', "Encrypt message"}, {"decrypt", OPT_DECRYPT, '-', "Decrypt encrypted message"}, {"sign", OPT_SIGN, '-', "Sign message"}, - {"sign_receipt", OPT_SIGN_RECEIPT, '-'}, + {"sign_receipt", OPT_SIGN_RECEIPT, '-', "Generate a signed receipt for the message"}, {"resign", OPT_RESIGN, '-'}, {"verify", OPT_VERIFY, '-', "Verify signed message"}, {"verify_retcode", OPT_VERIFY_RETCODE, '-'}, @@ -177,7 +133,7 @@ OPTIONS cms_options[] = { {"noindef", OPT_NOINDEF, '-'}, {"nooldmime", OPT_NOOLDMIME, '-'}, {"crlfeol", OPT_CRLFEOL, '-'}, - {"noout", OPT_NOOUT, '-'}, + {"noout", OPT_NOOUT, '-', "For the -cmsout operation do not output the parsed CMS structure"}, {"receipt_request_print", OPT_RR_PRINT, '-'}, {"receipt_request_all", OPT_RR_ALL, '-'}, {"receipt_request_first", OPT_RR_FIRST, '-'}, @@ -191,7 +147,7 @@ OPTIONS cms_options[] = { "Do not load certificates from the default certificates directory"}, {"content", OPT_CONTENT, '<', "Supply or override content for detached signature"}, - {"print", OPT_PRINT, '-'}, + {"print", OPT_PRINT, '-', "For the -cmsout operation print out all fields of the CMS structure"}, {"secretkey", OPT_SECRETKEY, 's'}, {"secretkeyid", OPT_SECRETKEYID, 's'}, {"pwri_password", OPT_PWRI_PASSWORD, 's'}, @@ -205,7 +161,7 @@ OPTIONS cms_options[] = { {"signer", OPT_SIGNER, 's', "Signer certificate file"}, {"recip", OPT_RECIP, '<', "Recipient cert file for decryption"}, {"certsout", OPT_CERTSOUT, '>', "Certificate output file"}, - {"md", OPT_MD, 's'}, + {"md", OPT_MD, 's', "Digest algorithm to use when signing or resigning"}, {"inkey", OPT_INKEY, 's', "Input private key (if not signer or recipient)"}, {"keyform", OPT_KEYFORM, 'f', "Input private key format (PEM or ENGINE)"}, @@ -214,11 +170,9 @@ OPTIONS cms_options[] = { {"receipt_request_to", OPT_RR_TO, 's'}, {"", OPT_CIPHER, '-', "Any supported cipher"}, OPT_V_OPTIONS, -# ifndef OPENSSL_NO_AES {"aes128-wrap", OPT_AES128_WRAP, '-', "Use AES128 to wrap key"}, {"aes192-wrap", OPT_AES192_WRAP, '-', "Use AES192 to wrap key"}, {"aes256-wrap", OPT_AES256_WRAP, '-', "Use AES256 to wrap key"}, -# endif # ifndef OPENSSL_NO_DES {"des3-wrap", OPT_3DES_WRAP, '-', "Use 3DES-EDE to wrap key"}, # endif @@ -245,7 +199,8 @@ int cms_main(int argc, char **argv) X509_STORE *store = NULL; X509_VERIFY_PARAM *vpm = NULL; char *certfile = NULL, *keyfile = NULL, *contfile = NULL; - char *CAfile = NULL, *CApath = NULL, *certsoutfile = NULL; + const char *CAfile = NULL, *CApath = NULL; + char *certsoutfile = NULL; int noCAfile = 0, noCApath = 0; char *infile = NULL, *outfile = NULL, *rctfile = NULL, *inrand = NULL; char *passinarg = NULL, *passin = NULL, *signerfile = NULL, *recipfile = @@ -262,6 +217,7 @@ int cms_main(int argc, char **argv) unsigned char *pwri_pass = NULL, *pwri_tmp = NULL; unsigned char *secret_key = NULL, *secret_keyid = NULL; long ltmp; + const char *mime_eol = "\n"; OPTION_CHOICE o; if ((vpm = X509_VERIFY_PARAM_new()) == NULL) @@ -280,11 +236,11 @@ int cms_main(int argc, char **argv) ret = 0; goto end; case OPT_INFORM: - if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &informat)) + if (!opt_format(opt_arg(), OPT_FMT_PDS, &informat)) goto opthelp; break; case OPT_OUTFORM: - if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &outformat)) + if (!opt_format(opt_arg(), OPT_FMT_PDS, &outformat)) goto opthelp; break; case OPT_OUT: @@ -394,6 +350,7 @@ int cms_main(int argc, char **argv) flags |= CMS_NOOLDMIMETYPE; break; case OPT_CRLFEOL: + mime_eol = "\r\n"; flags |= CMS_CRLFEOL; break; case OPT_NOOUT: @@ -455,7 +412,12 @@ int cms_main(int argc, char **argv) noout = print = 1; break; case OPT_SECRETKEY: - secret_key = string_to_hex(opt_arg(), <mp); + if (secret_key != NULL) { + BIO_printf(bio_err, "Invalid key (supplied twice) %s\n", + opt_arg()); + goto opthelp; + } + secret_key = OPENSSL_hexstr2buf(opt_arg(), <mp); if (secret_key == NULL) { BIO_printf(bio_err, "Invalid key %s\n", opt_arg()); goto end; @@ -463,7 +425,12 @@ int cms_main(int argc, char **argv) secret_keylen = (size_t)ltmp; break; case OPT_SECRETKEYID: - secret_keyid = string_to_hex(opt_arg(), <mp); + if (secret_keyid != NULL) { + BIO_printf(bio_err, "Invalid id (supplied twice) %s\n", + opt_arg()); + goto opthelp; + } + secret_keyid = OPENSSL_hexstr2buf(opt_arg(), <mp); if (secret_keyid == NULL) { BIO_printf(bio_err, "Invalid id %s\n", opt_arg()); goto opthelp; @@ -474,6 +441,11 @@ int cms_main(int argc, char **argv) pwri_pass = (unsigned char *)opt_arg(); break; case OPT_ECONTENT_TYPE: + if (econtent_type != NULL) { + BIO_printf(bio_err, "Invalid OID (supplied twice) %s\n", + opt_arg()); + goto opthelp; + } econtent_type = OBJ_txt2obj(opt_arg(), 0); if (econtent_type == NULL) { BIO_printf(bio_err, "Invalid OID %s\n", opt_arg()); @@ -524,7 +496,7 @@ int cms_main(int argc, char **argv) signerfile = opt_arg(); break; case OPT_INKEY: - /* If previous -inkey arument add signer to list */ + /* If previous -inkey argument add signer to list */ if (keyfile) { if (signerfile == NULL) { BIO_puts(bio_err, "Illegal -inkey without -signer\n"); @@ -550,7 +522,7 @@ int cms_main(int argc, char **argv) if (operation == SMIME_ENCRYPT) { if (encerts == NULL && (encerts = sk_X509_new_null()) == NULL) goto end; - cert = load_cert(opt_arg(), FORMAT_PEM, NULL, e, + cert = load_cert(opt_arg(), FORMAT_PEM, "recipient certificate file"); if (cert == NULL) goto end; @@ -603,7 +575,6 @@ int cms_main(int argc, char **argv) wrap_cipher = EVP_des_ede3_wrap(); # endif break; -# ifndef OPENSSL_NO_AES case OPT_AES128_WRAP: wrap_cipher = EVP_aes_128_wrap(); break; @@ -613,12 +584,6 @@ int cms_main(int argc, char **argv) case OPT_AES256_WRAP: wrap_cipher = EVP_aes_256_wrap(); break; -# else - case OPT_AES128_WRAP: - case OPT_AES192_WRAP: - case OPT_AES256_WRAP: - break; -# endif } } argc = opt_num_rest(); @@ -725,7 +690,7 @@ int cms_main(int argc, char **argv) if ((encerts = sk_X509_new_null()) == NULL) goto end; while (*argv) { - if ((cert = load_cert(*argv, FORMAT_PEM, NULL, e, + if ((cert = load_cert(*argv, FORMAT_PEM, "recipient certificate file")) == NULL) goto end; sk_X509_push(encerts, cert); @@ -735,7 +700,7 @@ int cms_main(int argc, char **argv) } if (certfile) { - if (!load_certs(certfile, &other, FORMAT_PEM, NULL, e, + if (!load_certs(certfile, &other, FORMAT_PEM, NULL, "certificate file")) { ERR_print_errors(bio_err); goto end; @@ -743,7 +708,7 @@ int cms_main(int argc, char **argv) } if (recipfile && (operation == SMIME_DECRYPT)) { - if ((recip = load_cert(recipfile, FORMAT_PEM, NULL, e, + if ((recip = load_cert(recipfile, FORMAT_PEM, "recipient certificate file")) == NULL) { ERR_print_errors(bio_err); goto end; @@ -751,7 +716,7 @@ int cms_main(int argc, char **argv) } if (operation == SMIME_SIGN_RECEIPT) { - if ((signer = load_cert(signerfile, FORMAT_PEM, NULL, e, + if ((signer = load_cert(signerfile, FORMAT_PEM, "receipt signer certificate file")) == NULL) { ERR_print_errors(bio_err); goto end; @@ -968,8 +933,7 @@ int cms_main(int argc, char **argv) signerfile = sk_OPENSSL_STRING_value(sksigners, i); keyfile = sk_OPENSSL_STRING_value(skkeys, i); - signer = load_cert(signerfile, FORMAT_PEM, NULL, - e, "signer certificate"); + signer = load_cert(signerfile, FORMAT_PEM, "signer certificate"); if (!signer) goto end; key = load_key(keyfile, keyform, 0, passin, e, "signing key file"); @@ -1094,11 +1058,11 @@ int cms_main(int argc, char **argv) CMS_ContentInfo_print_ctx(out, cms, 0, NULL); } else if (outformat == FORMAT_SMIME) { if (to) - BIO_printf(out, "To: %s\n", to); + BIO_printf(out, "To: %s%s", to, mime_eol); if (from) - BIO_printf(out, "From: %s\n", from); + BIO_printf(out, "From: %s%s", from, mime_eol); if (subject) - BIO_printf(out, "Subject: %s\n", subject); + BIO_printf(out, "Subject: %s%s", subject, mime_eol); if (operation == SMIME_RESIGN) ret = SMIME_write_CMS(out, cms, indata, flags); else @@ -1229,13 +1193,13 @@ static void receipt_request_print(CMS_ContentInfo *cms) BIO_puts(bio_err, " Receipt Request Parse Error\n"); ERR_print_errors(bio_err); } else { - char *id; + const char *id; int idlen; CMS_ReceiptRequest_get0_values(rr, &scid, &allorfirst, &rlist, &rto); BIO_puts(bio_err, " Signed Content ID:\n"); idlen = ASN1_STRING_length(scid); - id = (char *)ASN1_STRING_data(scid); + id = (const char *)ASN1_STRING_get0_data(scid); BIO_dump_indent(bio_err, id, idlen, 4); BIO_puts(bio_err, " Receipts From"); if (rlist) { @@ -1292,7 +1256,7 @@ static CMS_ReceiptRequest *make_receipt_request(STACK_OF(OPENSSL_STRING) *rr_to, int rr_allorfirst, STACK_OF(OPENSSL_STRING) *rr_from) { - STACK_OF(GENERAL_NAMES) *rct_to, *rct_from; + STACK_OF(GENERAL_NAMES) *rct_to = NULL, *rct_from = NULL; CMS_ReceiptRequest *rr; rct_to = make_names_stack(rr_to); if (!rct_to) @@ -1307,6 +1271,7 @@ static CMS_ReceiptRequest *make_receipt_request(STACK_OF(OPENSSL_STRING) rct_to); return rr; err: + sk_GENERAL_NAMES_pop_free(rct_to, GENERAL_NAMES_free); return NULL; }