"Fossies" - the Fresh Open Source Software Archive

Member "openssl-1.1.1g/apps/ec.c" (21 Apr 2020, 8320 Bytes) of package /linux/misc/openssl-1.1.1g.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "ec.c" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 1.1.1f_vs_1.1.1g.

    1 /*
    2  * Copyright 2002-2020 The OpenSSL Project Authors. All Rights Reserved.
    3  *
    4  * Licensed under the OpenSSL license (the "License").  You may not use
    5  * this file except in compliance with the License.  You can obtain a copy
    6  * in the file LICENSE in the source distribution or at
    7  * https://www.openssl.org/source/license.html
    8  */
    9 
   10 #include <openssl/opensslconf.h>
   11 #include <stdio.h>
   12 #include <stdlib.h>
   13 #include <string.h>
   14 #include "apps.h"
   15 #include "progs.h"
   16 #include <openssl/bio.h>
   17 #include <openssl/err.h>
   18 #include <openssl/evp.h>
   19 #include <openssl/pem.h>
   20 
   21 static OPT_PAIR conv_forms[] = {
   22     {"compressed", POINT_CONVERSION_COMPRESSED},
   23     {"uncompressed", POINT_CONVERSION_UNCOMPRESSED},
   24     {"hybrid", POINT_CONVERSION_HYBRID},
   25     {NULL}
   26 };
   27 
   28 static OPT_PAIR param_enc[] = {
   29     {"named_curve", OPENSSL_EC_NAMED_CURVE},
   30     {"explicit", 0},
   31     {NULL}
   32 };
   33 
   34 typedef enum OPTION_choice {
   35     OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
   36     OPT_INFORM, OPT_OUTFORM, OPT_ENGINE, OPT_IN, OPT_OUT,
   37     OPT_NOOUT, OPT_TEXT, OPT_PARAM_OUT, OPT_PUBIN, OPT_PUBOUT,
   38     OPT_PASSIN, OPT_PASSOUT, OPT_PARAM_ENC, OPT_CONV_FORM, OPT_CIPHER,
   39     OPT_NO_PUBLIC, OPT_CHECK
   40 } OPTION_CHOICE;
   41 
   42 const OPTIONS ec_options[] = {
   43     {"help", OPT_HELP, '-', "Display this summary"},
   44     {"in", OPT_IN, 's', "Input file"},
   45     {"inform", OPT_INFORM, 'f', "Input format - DER or PEM"},
   46     {"out", OPT_OUT, '>', "Output file"},
   47     {"outform", OPT_OUTFORM, 'F', "Output format - DER or PEM"},
   48     {"noout", OPT_NOOUT, '-', "Don't print key out"},
   49     {"text", OPT_TEXT, '-', "Print the key"},
   50     {"param_out", OPT_PARAM_OUT, '-', "Print the elliptic curve parameters"},
   51     {"pubin", OPT_PUBIN, '-', "Expect a public key in input file"},
   52     {"pubout", OPT_PUBOUT, '-', "Output public key, not private"},
   53     {"no_public", OPT_NO_PUBLIC, '-', "exclude public key from private key"},
   54     {"check", OPT_CHECK, '-', "check key consistency"},
   55     {"passin", OPT_PASSIN, 's', "Input file pass phrase source"},
   56     {"passout", OPT_PASSOUT, 's', "Output file pass phrase source"},
   57     {"param_enc", OPT_PARAM_ENC, 's',
   58      "Specifies the way the ec parameters are encoded"},
   59     {"conv_form", OPT_CONV_FORM, 's', "Specifies the point conversion form "},
   60     {"", OPT_CIPHER, '-', "Any supported cipher"},
   61 #ifndef OPENSSL_NO_ENGINE
   62     {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"},
   63 #endif
   64     {NULL}
   65 };
   66 
   67 int ec_main(int argc, char **argv)
   68 {
   69     BIO *in = NULL, *out = NULL;
   70     ENGINE *e = NULL;
   71     EC_KEY *eckey = NULL;
   72     const EC_GROUP *group;
   73     const EVP_CIPHER *enc = NULL;
   74     point_conversion_form_t form = POINT_CONVERSION_UNCOMPRESSED;
   75     char *infile = NULL, *outfile = NULL, *prog;
   76     char *passin = NULL, *passout = NULL, *passinarg = NULL, *passoutarg = NULL;
   77     OPTION_CHOICE o;
   78     int asn1_flag = OPENSSL_EC_NAMED_CURVE, new_form = 0, new_asn1_flag = 0;
   79     int informat = FORMAT_PEM, outformat = FORMAT_PEM, text = 0, noout = 0;
   80     int pubin = 0, pubout = 0, param_out = 0, i, ret = 1, private = 0;
   81     int no_public = 0, check = 0;
   82 
   83     prog = opt_init(argc, argv, ec_options);
   84     while ((o = opt_next()) != OPT_EOF) {
   85         switch (o) {
   86         case OPT_EOF:
   87         case OPT_ERR:
   88  opthelp:
   89             BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
   90             goto end;
   91         case OPT_HELP:
   92             opt_help(ec_options);
   93             ret = 0;
   94             goto end;
   95         case OPT_INFORM:
   96             if (!opt_format(opt_arg(), OPT_FMT_ANY, &informat))
   97                 goto opthelp;
   98             break;
   99         case OPT_IN:
  100             infile = opt_arg();
  101             break;
  102         case OPT_OUTFORM:
  103             if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &outformat))
  104                 goto opthelp;
  105             break;
  106         case OPT_OUT:
  107             outfile = opt_arg();
  108             break;
  109         case OPT_NOOUT:
  110             noout = 1;
  111             break;
  112         case OPT_TEXT:
  113             text = 1;
  114             break;
  115         case OPT_PARAM_OUT:
  116             param_out = 1;
  117             break;
  118         case OPT_PUBIN:
  119             pubin = 1;
  120             break;
  121         case OPT_PUBOUT:
  122             pubout = 1;
  123             break;
  124         case OPT_PASSIN:
  125             passinarg = opt_arg();
  126             break;
  127         case OPT_PASSOUT:
  128             passoutarg = opt_arg();
  129             break;
  130         case OPT_ENGINE:
  131             e = setup_engine(opt_arg(), 0);
  132             break;
  133         case OPT_CIPHER:
  134             if (!opt_cipher(opt_unknown(), &enc))
  135                 goto opthelp;
  136             break;
  137         case OPT_CONV_FORM:
  138             if (!opt_pair(opt_arg(), conv_forms, &i))
  139                 goto opthelp;
  140             new_form = 1;
  141             form = i;
  142             break;
  143         case OPT_PARAM_ENC:
  144             if (!opt_pair(opt_arg(), param_enc, &i))
  145                 goto opthelp;
  146             new_asn1_flag = 1;
  147             asn1_flag = i;
  148             break;
  149         case OPT_NO_PUBLIC:
  150             no_public = 1;
  151             break;
  152         case OPT_CHECK:
  153             check = 1;
  154             break;
  155         }
  156     }
  157     argc = opt_num_rest();
  158     if (argc != 0)
  159         goto opthelp;
  160 
  161     private = param_out || pubin || pubout ? 0 : 1;
  162     if (text && !pubin)
  163         private = 1;
  164 
  165     if (!app_passwd(passinarg, passoutarg, &passin, &passout)) {
  166         BIO_printf(bio_err, "Error getting passwords\n");
  167         goto end;
  168     }
  169 
  170     if (informat != FORMAT_ENGINE) {
  171         in = bio_open_default(infile, 'r', informat);
  172         if (in == NULL)
  173             goto end;
  174     }
  175 
  176     BIO_printf(bio_err, "read EC key\n");
  177     if (informat == FORMAT_ASN1) {
  178         if (pubin)
  179             eckey = d2i_EC_PUBKEY_bio(in, NULL);
  180         else
  181             eckey = d2i_ECPrivateKey_bio(in, NULL);
  182     } else if (informat == FORMAT_ENGINE) {
  183         EVP_PKEY *pkey;
  184         if (pubin)
  185             pkey = load_pubkey(infile, informat, 1, passin, e, "Public Key");
  186         else
  187             pkey = load_key(infile, informat, 1, passin, e, "Private Key");
  188         if (pkey != NULL) {
  189             eckey = EVP_PKEY_get1_EC_KEY(pkey);
  190             EVP_PKEY_free(pkey);
  191         }
  192     } else {
  193         if (pubin)
  194             eckey = PEM_read_bio_EC_PUBKEY(in, NULL, NULL, NULL);
  195         else
  196             eckey = PEM_read_bio_ECPrivateKey(in, NULL, NULL, passin);
  197     }
  198     if (eckey == NULL) {
  199         BIO_printf(bio_err, "unable to load Key\n");
  200         ERR_print_errors(bio_err);
  201         goto end;
  202     }
  203 
  204     out = bio_open_owner(outfile, outformat, private);
  205     if (out == NULL)
  206         goto end;
  207 
  208     group = EC_KEY_get0_group(eckey);
  209 
  210     if (new_form)
  211         EC_KEY_set_conv_form(eckey, form);
  212 
  213     if (new_asn1_flag)
  214         EC_KEY_set_asn1_flag(eckey, asn1_flag);
  215 
  216     if (no_public)
  217         EC_KEY_set_enc_flags(eckey, EC_PKEY_NO_PUBKEY);
  218 
  219     if (text) {
  220         assert(pubin || private);
  221         if (!EC_KEY_print(out, eckey, 0)) {
  222             perror(outfile);
  223             ERR_print_errors(bio_err);
  224             goto end;
  225         }
  226     }
  227 
  228     if (check) {
  229         if (EC_KEY_check_key(eckey) == 1) {
  230             BIO_printf(bio_err, "EC Key valid.\n");
  231         } else {
  232             BIO_printf(bio_err, "EC Key Invalid!\n");
  233             ERR_print_errors(bio_err);
  234         }
  235     }
  236 
  237     if (noout) {
  238         ret = 0;
  239         goto end;
  240     }
  241 
  242     BIO_printf(bio_err, "writing EC key\n");
  243     if (outformat == FORMAT_ASN1) {
  244         if (param_out) {
  245             i = i2d_ECPKParameters_bio(out, group);
  246         } else if (pubin || pubout) {
  247             i = i2d_EC_PUBKEY_bio(out, eckey);
  248         } else {
  249             assert(private);
  250             i = i2d_ECPrivateKey_bio(out, eckey);
  251         }
  252     } else {
  253         if (param_out) {
  254             i = PEM_write_bio_ECPKParameters(out, group);
  255         } else if (pubin || pubout) {
  256             i = PEM_write_bio_EC_PUBKEY(out, eckey);
  257         } else {
  258             assert(private);
  259             i = PEM_write_bio_ECPrivateKey(out, eckey, enc,
  260                                            NULL, 0, NULL, passout);
  261         }
  262     }
  263 
  264     if (!i) {
  265         BIO_printf(bio_err, "unable to write private key\n");
  266         ERR_print_errors(bio_err);
  267     } else {
  268         ret = 0;
  269     }
  270  end:
  271     BIO_free(in);
  272     BIO_free_all(out);
  273     EC_KEY_free(eckey);
  274     release_engine(e);
  275     OPENSSL_free(passin);
  276     OPENSSL_free(passout);
  277     return ret;
  278 }