"Fossies" - the Fresh Open Source Software Archive

Member "openssl-1.1.1g/apps/dsa.c" (21 Apr 2020, 7713 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 "dsa.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 1995-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 <time.h>
   15 #include "apps.h"
   16 #include "progs.h"
   17 #include <openssl/bio.h>
   18 #include <openssl/err.h>
   19 #include <openssl/dsa.h>
   20 #include <openssl/evp.h>
   21 #include <openssl/x509.h>
   22 #include <openssl/pem.h>
   23 #include <openssl/bn.h>
   24 
   25 typedef enum OPTION_choice {
   26     OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
   27     OPT_INFORM, OPT_OUTFORM, OPT_IN, OPT_OUT, OPT_ENGINE,
   28     /* Do not change the order here; see case statements below */
   29     OPT_PVK_NONE, OPT_PVK_WEAK, OPT_PVK_STRONG,
   30     OPT_NOOUT, OPT_TEXT, OPT_MODULUS, OPT_PUBIN,
   31     OPT_PUBOUT, OPT_CIPHER, OPT_PASSIN, OPT_PASSOUT
   32 } OPTION_CHOICE;
   33 
   34 const OPTIONS dsa_options[] = {
   35     {"help", OPT_HELP, '-', "Display this summary"},
   36     {"inform", OPT_INFORM, 'f', "Input format, DER PEM PVK"},
   37     {"outform", OPT_OUTFORM, 'f', "Output format, DER PEM PVK"},
   38     {"in", OPT_IN, 's', "Input key"},
   39     {"out", OPT_OUT, '>', "Output file"},
   40     {"noout", OPT_NOOUT, '-', "Don't print key out"},
   41     {"text", OPT_TEXT, '-', "Print the key in text"},
   42     {"modulus", OPT_MODULUS, '-', "Print the DSA public value"},
   43     {"pubin", OPT_PUBIN, '-', "Expect a public key in input file"},
   44     {"pubout", OPT_PUBOUT, '-', "Output public key, not private"},
   45     {"passin", OPT_PASSIN, 's', "Input file pass phrase source"},
   46     {"passout", OPT_PASSOUT, 's', "Output file pass phrase source"},
   47     {"", OPT_CIPHER, '-', "Any supported cipher"},
   48 #ifndef OPENSSL_NO_RC4
   49     {"pvk-strong", OPT_PVK_STRONG, '-', "Enable 'Strong' PVK encoding level (default)"},
   50     {"pvk-weak", OPT_PVK_WEAK, '-', "Enable 'Weak' PVK encoding level"},
   51     {"pvk-none", OPT_PVK_NONE, '-', "Don't enforce PVK encoding"},
   52 #endif
   53 #ifndef OPENSSL_NO_ENGINE
   54     {"engine", OPT_ENGINE, 's', "Use engine e, possibly a hardware device"},
   55 #endif
   56     {NULL}
   57 };
   58 
   59 int dsa_main(int argc, char **argv)
   60 {
   61     BIO *out = NULL;
   62     DSA *dsa = NULL;
   63     ENGINE *e = NULL;
   64     const EVP_CIPHER *enc = NULL;
   65     char *infile = NULL, *outfile = NULL, *prog;
   66     char *passin = NULL, *passout = NULL, *passinarg = NULL, *passoutarg = NULL;
   67     OPTION_CHOICE o;
   68     int informat = FORMAT_PEM, outformat = FORMAT_PEM, text = 0, noout = 0;
   69     int i, modulus = 0, pubin = 0, pubout = 0, ret = 1;
   70 #ifndef OPENSSL_NO_RC4
   71     int pvk_encr = 2;
   72 #endif
   73     int private = 0;
   74 
   75     prog = opt_init(argc, argv, dsa_options);
   76     while ((o = opt_next()) != OPT_EOF) {
   77         switch (o) {
   78         case OPT_EOF:
   79         case OPT_ERR:
   80  opthelp:
   81             ret = 0;
   82             BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
   83             goto end;
   84         case OPT_HELP:
   85             opt_help(dsa_options);
   86             ret = 0;
   87             goto end;
   88         case OPT_INFORM:
   89             if (!opt_format(opt_arg(), OPT_FMT_ANY, &informat))
   90                 goto opthelp;
   91             break;
   92         case OPT_IN:
   93             infile = opt_arg();
   94             break;
   95         case OPT_OUTFORM:
   96             if (!opt_format(opt_arg(), OPT_FMT_ANY, &outformat))
   97                 goto opthelp;
   98             break;
   99         case OPT_OUT:
  100             outfile = opt_arg();
  101             break;
  102         case OPT_ENGINE:
  103             e = setup_engine(opt_arg(), 0);
  104             break;
  105         case OPT_PASSIN:
  106             passinarg = opt_arg();
  107             break;
  108         case OPT_PASSOUT:
  109             passoutarg = opt_arg();
  110             break;
  111         case OPT_PVK_STRONG:    /* pvk_encr:= 2 */
  112         case OPT_PVK_WEAK:      /* pvk_encr:= 1 */
  113         case OPT_PVK_NONE:      /* pvk_encr:= 0 */
  114 #ifndef OPENSSL_NO_RC4
  115             pvk_encr = (o - OPT_PVK_NONE);
  116 #endif
  117             break;
  118         case OPT_NOOUT:
  119             noout = 1;
  120             break;
  121         case OPT_TEXT:
  122             text = 1;
  123             break;
  124         case OPT_MODULUS:
  125             modulus = 1;
  126             break;
  127         case OPT_PUBIN:
  128             pubin = 1;
  129             break;
  130         case OPT_PUBOUT:
  131             pubout = 1;
  132             break;
  133         case OPT_CIPHER:
  134             if (!opt_cipher(opt_unknown(), &enc))
  135                 goto end;
  136             break;
  137         }
  138     }
  139     argc = opt_num_rest();
  140     if (argc != 0)
  141         goto opthelp;
  142 
  143     private = pubin || pubout ? 0 : 1;
  144     if (text && !pubin)
  145         private = 1;
  146 
  147     if (!app_passwd(passinarg, passoutarg, &passin, &passout)) {
  148         BIO_printf(bio_err, "Error getting passwords\n");
  149         goto end;
  150     }
  151 
  152     BIO_printf(bio_err, "read DSA key\n");
  153     {
  154         EVP_PKEY *pkey;
  155 
  156         if (pubin)
  157             pkey = load_pubkey(infile, informat, 1, passin, e, "Public Key");
  158         else
  159             pkey = load_key(infile, informat, 1, passin, e, "Private Key");
  160 
  161         if (pkey != NULL) {
  162             dsa = EVP_PKEY_get1_DSA(pkey);
  163             EVP_PKEY_free(pkey);
  164         }
  165     }
  166     if (dsa == NULL) {
  167         BIO_printf(bio_err, "unable to load Key\n");
  168         ERR_print_errors(bio_err);
  169         goto end;
  170     }
  171 
  172     out = bio_open_owner(outfile, outformat, private);
  173     if (out == NULL)
  174         goto end;
  175 
  176     if (text) {
  177         assert(pubin || private);
  178         if (!DSA_print(out, dsa, 0)) {
  179             perror(outfile);
  180             ERR_print_errors(bio_err);
  181             goto end;
  182         }
  183     }
  184 
  185     if (modulus) {
  186         const BIGNUM *pub_key = NULL;
  187         DSA_get0_key(dsa, &pub_key, NULL);
  188         BIO_printf(out, "Public Key=");
  189         BN_print(out, pub_key);
  190         BIO_printf(out, "\n");
  191     }
  192 
  193     if (noout) {
  194         ret = 0;
  195         goto end;
  196     }
  197     BIO_printf(bio_err, "writing DSA key\n");
  198     if (outformat == FORMAT_ASN1) {
  199         if (pubin || pubout) {
  200             i = i2d_DSA_PUBKEY_bio(out, dsa);
  201         } else {
  202             assert(private);
  203             i = i2d_DSAPrivateKey_bio(out, dsa);
  204         }
  205     } else if (outformat == FORMAT_PEM) {
  206         if (pubin || pubout) {
  207             i = PEM_write_bio_DSA_PUBKEY(out, dsa);
  208         } else {
  209             assert(private);
  210             i = PEM_write_bio_DSAPrivateKey(out, dsa, enc,
  211                                             NULL, 0, NULL, passout);
  212         }
  213 #ifndef OPENSSL_NO_RSA
  214     } else if (outformat == FORMAT_MSBLOB || outformat == FORMAT_PVK) {
  215         EVP_PKEY *pk;
  216         pk = EVP_PKEY_new();
  217         if (pk == NULL)
  218            goto end;
  219 
  220         EVP_PKEY_set1_DSA(pk, dsa);
  221         if (outformat == FORMAT_PVK) {
  222             if (pubin) {
  223                 BIO_printf(bio_err, "PVK form impossible with public key input\n");
  224                 EVP_PKEY_free(pk);
  225                 goto end;
  226             }
  227             assert(private);
  228 # ifdef OPENSSL_NO_RC4
  229             BIO_printf(bio_err, "PVK format not supported\n");
  230             EVP_PKEY_free(pk);
  231             goto end;
  232 # else
  233             i = i2b_PVK_bio(out, pk, pvk_encr, 0, passout);
  234 # endif
  235         } else if (pubin || pubout) {
  236             i = i2b_PublicKey_bio(out, pk);
  237         } else {
  238             assert(private);
  239             i = i2b_PrivateKey_bio(out, pk);
  240         }
  241         EVP_PKEY_free(pk);
  242 #endif
  243     } else {
  244         BIO_printf(bio_err, "bad output format specified for outfile\n");
  245         goto end;
  246     }
  247     if (i <= 0) {
  248         BIO_printf(bio_err, "unable to write private key\n");
  249         ERR_print_errors(bio_err);
  250         goto end;
  251     }
  252     ret = 0;
  253  end:
  254     BIO_free_all(out);
  255     DSA_free(dsa);
  256     release_engine(e);
  257     OPENSSL_free(passin);
  258     OPENSSL_free(passout);
  259     return ret;
  260 }