X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=apps%2Fec.c;h=03abb00683373b8ea0565af9412d1ed332508e40;hp=a30d3f0a40db4a31d518245e79992a93036cc844;hb=df2cb82ae397ac7e1466f674ecd2309ac6de14e7;hpb=bdd58d98467e9f0f6635c1628e1eae304383afb1 diff --git a/apps/ec.c b/apps/ec.c index a30d3f0a40..03abb00683 100644 --- a/apps/ec.c +++ b/apps/ec.c @@ -1,66 +1,22 @@ /* - * Written by Nils Larsch for the OpenSSL project. - */ -/* ==================================================================== - * Copyright (c) 1998-2005 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 - * openssl-core@openssl.org. - * - * 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. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). + * Copyright 2002-2018 The OpenSSL Project Authors. All Rights Reserved. * + * 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 */ #include -#ifndef OPENSSL_NO_EC +#ifdef OPENSSL_NO_EC +NON_EMPTY_TRANSLATION_UNIT +#else + # include # include # include # include "apps.h" +# include "progs.h" # include # include # include @@ -83,20 +39,23 @@ typedef enum OPTION_choice { OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, OPT_INFORM, OPT_OUTFORM, OPT_ENGINE, OPT_IN, OPT_OUT, OPT_NOOUT, OPT_TEXT, OPT_PARAM_OUT, OPT_PUBIN, OPT_PUBOUT, - OPT_PASSIN, OPT_PASSOUT, OPT_PARAM_ENC, OPT_CONV_FORM, OPT_CIPHER + OPT_PASSIN, OPT_PASSOUT, OPT_PARAM_ENC, OPT_CONV_FORM, OPT_CIPHER, + OPT_NO_PUBLIC, OPT_CHECK } OPTION_CHOICE; -OPTIONS ec_options[] = { +const OPTIONS ec_options[] = { {"help", OPT_HELP, '-', "Display this summary"}, - {"in", OPT_IN, '<', "Input file"}, - {"inform", OPT_INFORM, 'F', "Input format - DER or PEM"}, + {"in", OPT_IN, 's', "Input file"}, + {"inform", OPT_INFORM, 'f', "Input format - DER or PEM"}, {"out", OPT_OUT, '>', "Output file"}, {"outform", OPT_OUTFORM, 'F', "Output format - DER or PEM"}, {"noout", OPT_NOOUT, '-', "Don't print key out"}, {"text", OPT_TEXT, '-', "Print the key"}, {"param_out", OPT_PARAM_OUT, '-', "Print the elliptic curve parameters"}, - {"pubin", OPT_PUBIN, '-'}, - {"pubout", OPT_PUBOUT, '-'}, + {"pubin", OPT_PUBIN, '-', "Expect a public key in input file"}, + {"pubout", OPT_PUBOUT, '-', "Output public key, not private"}, + {"no_public", OPT_NO_PUBLIC, '-', "exclude public key from private key"}, + {"check", OPT_CHECK, '-', "check key consistency"}, {"passin", OPT_PASSIN, 's', "Input file pass phrase source"}, {"passout", OPT_PASSOUT, 's', "Output file pass phrase source"}, {"param_enc", OPT_PARAM_ENC, 's', @@ -112,6 +71,7 @@ OPTIONS ec_options[] = { int ec_main(int argc, char **argv) { BIO *in = NULL, *out = NULL; + ENGINE *e = NULL; EC_KEY *eckey = NULL; const EC_GROUP *group; const EVP_CIPHER *enc = NULL; @@ -122,6 +82,7 @@ int ec_main(int argc, char **argv) int asn1_flag = OPENSSL_EC_NAMED_CURVE, new_form = 0, new_asn1_flag = 0; int informat = FORMAT_PEM, outformat = FORMAT_PEM, text = 0, noout = 0; int pubin = 0, pubout = 0, param_out = 0, i, ret = 1, private = 0; + int no_public = 0, check = 0; prog = opt_init(argc, argv, ec_options); while ((o = opt_next()) != OPT_EOF) { @@ -136,7 +97,7 @@ int ec_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_ANY, &informat)) goto opthelp; break; case OPT_IN: @@ -171,7 +132,7 @@ int ec_main(int argc, char **argv) passoutarg = opt_arg(); break; case OPT_ENGINE: - (void)setup_engine(opt_arg(), 0); + e = setup_engine(opt_arg(), 0); break; case OPT_CIPHER: if (!opt_cipher(opt_unknown(), &enc)) @@ -189,12 +150,20 @@ int ec_main(int argc, char **argv) new_asn1_flag = 1; asn1_flag = i; break; + case OPT_NO_PUBLIC: + no_public = 1; + break; + case OPT_CHECK: + check = 1; + break; } } argc = opt_num_rest(); - argv = opt_rest(); + if (argc != 0) + goto opthelp; + private = param_out || pubin || pubout ? 0 : 1; - if (text) + if (text && !pubin) private = 1; if (!app_passwd(passinarg, passoutarg, &passin, &passout)) { @@ -202,12 +171,11 @@ int ec_main(int argc, char **argv) goto end; } - if (!app_load_modules(NULL)) - goto end; - - in = bio_open_default(infile, 'r', informat); - if (in == NULL) - goto end; + if (informat != FORMAT_ENGINE) { + in = bio_open_default(infile, 'r', informat); + if (in == NULL) + goto end; + } BIO_printf(bio_err, "read EC key\n"); if (informat == FORMAT_ASN1) { @@ -215,6 +183,16 @@ int ec_main(int argc, char **argv) eckey = d2i_EC_PUBKEY_bio(in, NULL); else eckey = d2i_ECPrivateKey_bio(in, NULL); + } else if (informat == FORMAT_ENGINE) { + EVP_PKEY *pkey; + if (pubin) + pkey = load_pubkey(infile, informat, 1, passin, e, "Public Key"); + else + pkey = load_key(infile, informat, 1, passin, e, "Private Key"); + if (pkey != NULL) { + eckey = EVP_PKEY_get1_EC_KEY(pkey); + EVP_PKEY_free(pkey); + } } else { if (pubin) eckey = PEM_read_bio_EC_PUBKEY(in, NULL, NULL, NULL); @@ -239,8 +217,11 @@ int ec_main(int argc, char **argv) if (new_asn1_flag) EC_KEY_set_asn1_flag(eckey, asn1_flag); + if (no_public) + EC_KEY_set_enc_flags(eckey, EC_PKEY_NO_PUBKEY); + if (text) { - assert(private); + assert(pubin || private); if (!EC_KEY_print(out, eckey, 0)) { perror(outfile); ERR_print_errors(bio_err); @@ -248,6 +229,15 @@ int ec_main(int argc, char **argv) } } + if (check) { + if (EC_KEY_check_key(eckey) == 1) { + BIO_printf(bio_err, "EC Key valid.\n"); + } else { + BIO_printf(bio_err, "EC Key Invalid!\n"); + ERR_print_errors(bio_err); + } + } + if (noout) { ret = 0; goto end; @@ -255,20 +245,20 @@ int ec_main(int argc, char **argv) BIO_printf(bio_err, "writing EC key\n"); if (outformat == FORMAT_ASN1) { - if (param_out) + if (param_out) { i = i2d_ECPKParameters_bio(out, group); - else if (pubin || pubout) + } else if (pubin || pubout) { i = i2d_EC_PUBKEY_bio(out, eckey); - else { + } else { assert(private); i = i2d_ECPrivateKey_bio(out, eckey); } } else { - if (param_out) + if (param_out) { i = PEM_write_bio_ECPKParameters(out, group); - else if (pubin || pubout) + } else if (pubin || pubout) { i = PEM_write_bio_EC_PUBKEY(out, eckey); - else { + } else { assert(private); i = PEM_write_bio_ECPrivateKey(out, eckey, enc, NULL, 0, NULL, passout); @@ -278,20 +268,16 @@ int ec_main(int argc, char **argv) if (!i) { BIO_printf(bio_err, "unable to write private key\n"); ERR_print_errors(bio_err); - } else + } else { ret = 0; + } end: BIO_free(in); BIO_free_all(out); EC_KEY_free(eckey); + release_engine(e); OPENSSL_free(passin); OPENSSL_free(passout); - return (ret); + return ret; } -#else /* !OPENSSL_NO_EC */ - -# if PEDANTIC -static void *dummy = &dummy; -# endif - #endif