"Fossies" - the Fresh Open Source Software Archive

Member "openssl-1.1.1g/apps/dsaparam.c" (21 Apr 2020, 7986 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 "dsaparam.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 <time.h>
   14 #include <string.h>
   15 #include "apps.h"
   16 #include "progs.h"
   17 #include <openssl/bio.h>
   18 #include <openssl/err.h>
   19 #include <openssl/bn.h>
   20 #include <openssl/dsa.h>
   21 #include <openssl/x509.h>
   22 #include <openssl/pem.h>
   23 
   24 static int dsa_cb(int p, int n, BN_GENCB *cb);
   25 
   26 typedef enum OPTION_choice {
   27     OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
   28     OPT_INFORM, OPT_OUTFORM, OPT_IN, OPT_OUT, OPT_TEXT, OPT_C,
   29     OPT_NOOUT, OPT_GENKEY, OPT_ENGINE, OPT_R_ENUM
   30 } OPTION_CHOICE;
   31 
   32 const OPTIONS dsaparam_options[] = {
   33     {"help", OPT_HELP, '-', "Display this summary"},
   34     {"inform", OPT_INFORM, 'F', "Input format - DER or PEM"},
   35     {"in", OPT_IN, '<', "Input file"},
   36     {"outform", OPT_OUTFORM, 'F', "Output format - DER or PEM"},
   37     {"out", OPT_OUT, '>', "Output file"},
   38     {"text", OPT_TEXT, '-', "Print as text"},
   39     {"C", OPT_C, '-', "Output C code"},
   40     {"noout", OPT_NOOUT, '-', "No output"},
   41     {"genkey", OPT_GENKEY, '-', "Generate a DSA key"},
   42     OPT_R_OPTIONS,
   43 #ifndef OPENSSL_NO_ENGINE
   44     {"engine", OPT_ENGINE, 's', "Use engine e, possibly a hardware device"},
   45 #endif
   46     {NULL}
   47 };
   48 
   49 int dsaparam_main(int argc, char **argv)
   50 {
   51     ENGINE *e = NULL;
   52     DSA *dsa = NULL;
   53     BIO *in = NULL, *out = NULL;
   54     BN_GENCB *cb = NULL;
   55     int numbits = -1, num = 0, genkey = 0;
   56     int informat = FORMAT_PEM, outformat = FORMAT_PEM, noout = 0, C = 0;
   57     int ret = 1, i, text = 0, private = 0;
   58     char *infile = NULL, *outfile = NULL, *prog;
   59     OPTION_CHOICE o;
   60 
   61     prog = opt_init(argc, argv, dsaparam_options);
   62     while ((o = opt_next()) != OPT_EOF) {
   63         switch (o) {
   64         case OPT_EOF:
   65         case OPT_ERR:
   66  opthelp:
   67             BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
   68             goto end;
   69         case OPT_HELP:
   70             opt_help(dsaparam_options);
   71             ret = 0;
   72             goto end;
   73         case OPT_INFORM:
   74             if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &informat))
   75                 goto opthelp;
   76             break;
   77         case OPT_IN:
   78             infile = opt_arg();
   79             break;
   80         case OPT_OUTFORM:
   81             if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &outformat))
   82                 goto opthelp;
   83             break;
   84         case OPT_OUT:
   85             outfile = opt_arg();
   86             break;
   87         case OPT_ENGINE:
   88             e = setup_engine(opt_arg(), 0);
   89             break;
   90         case OPT_TEXT:
   91             text = 1;
   92             break;
   93         case OPT_C:
   94             C = 1;
   95             break;
   96         case OPT_GENKEY:
   97             genkey = 1;
   98             break;
   99         case OPT_R_CASES:
  100             if (!opt_rand(o))
  101                 goto end;
  102             break;
  103         case OPT_NOOUT:
  104             noout = 1;
  105             break;
  106         }
  107     }
  108     argc = opt_num_rest();
  109     argv = opt_rest();
  110 
  111     if (argc == 1) {
  112         if (!opt_int(argv[0], &num) || num < 0)
  113             goto end;
  114         /* generate a key */
  115         numbits = num;
  116     }
  117     private = genkey ? 1 : 0;
  118 
  119     in = bio_open_default(infile, 'r', informat);
  120     if (in == NULL)
  121         goto end;
  122     out = bio_open_owner(outfile, outformat, private);
  123     if (out == NULL)
  124         goto end;
  125 
  126     if (numbits > 0) {
  127         if (numbits > OPENSSL_DSA_MAX_MODULUS_BITS)
  128             BIO_printf(bio_err,
  129                        "Warning: It is not recommended to use more than %d bit for DSA keys.\n"
  130                        "         Your key size is %d! Larger key size may behave not as expected.\n",
  131                        OPENSSL_DSA_MAX_MODULUS_BITS, numbits);
  132 
  133         cb = BN_GENCB_new();
  134         if (cb == NULL) {
  135             BIO_printf(bio_err, "Error allocating BN_GENCB object\n");
  136             goto end;
  137         }
  138         BN_GENCB_set(cb, dsa_cb, bio_err);
  139         dsa = DSA_new();
  140         if (dsa == NULL) {
  141             BIO_printf(bio_err, "Error allocating DSA object\n");
  142             goto end;
  143         }
  144         BIO_printf(bio_err, "Generating DSA parameters, %d bit long prime\n",
  145                    num);
  146         BIO_printf(bio_err, "This could take some time\n");
  147         if (!DSA_generate_parameters_ex(dsa, num, NULL, 0, NULL, NULL, cb)) {
  148             ERR_print_errors(bio_err);
  149             BIO_printf(bio_err, "Error, DSA key generation failed\n");
  150             goto end;
  151         }
  152     } else if (informat == FORMAT_ASN1) {
  153         dsa = d2i_DSAparams_bio(in, NULL);
  154     } else {
  155         dsa = PEM_read_bio_DSAparams(in, NULL, NULL, NULL);
  156     }
  157     if (dsa == NULL) {
  158         BIO_printf(bio_err, "unable to load DSA parameters\n");
  159         ERR_print_errors(bio_err);
  160         goto end;
  161     }
  162 
  163     if (text) {
  164         DSAparams_print(out, dsa);
  165     }
  166 
  167     if (C) {
  168         const BIGNUM *p = NULL, *q = NULL, *g = NULL;
  169         unsigned char *data;
  170         int len, bits_p;
  171 
  172         DSA_get0_pqg(dsa, &p, &q, &g);
  173         len = BN_num_bytes(p);
  174         bits_p = BN_num_bits(p);
  175 
  176         data = app_malloc(len + 20, "BN space");
  177 
  178         BIO_printf(bio_out, "static DSA *get_dsa%d(void)\n{\n", bits_p);
  179         print_bignum_var(bio_out, p, "dsap", bits_p, data);
  180         print_bignum_var(bio_out, q, "dsaq", bits_p, data);
  181         print_bignum_var(bio_out, g, "dsag", bits_p, data);
  182         BIO_printf(bio_out, "    DSA *dsa = DSA_new();\n"
  183                             "    BIGNUM *p, *q, *g;\n"
  184                             "\n");
  185         BIO_printf(bio_out, "    if (dsa == NULL)\n"
  186                             "        return NULL;\n");
  187         BIO_printf(bio_out, "    if (!DSA_set0_pqg(dsa, p = BN_bin2bn(dsap_%d, sizeof(dsap_%d), NULL),\n",
  188                    bits_p, bits_p);
  189         BIO_printf(bio_out, "                           q = BN_bin2bn(dsaq_%d, sizeof(dsaq_%d), NULL),\n",
  190                    bits_p, bits_p);
  191         BIO_printf(bio_out, "                           g = BN_bin2bn(dsag_%d, sizeof(dsag_%d), NULL))) {\n",
  192                    bits_p, bits_p);
  193         BIO_printf(bio_out, "        DSA_free(dsa);\n"
  194                             "        BN_free(p);\n"
  195                             "        BN_free(q);\n"
  196                             "        BN_free(g);\n"
  197                             "        return NULL;\n"
  198                             "    }\n"
  199                             "    return dsa;\n}\n");
  200         OPENSSL_free(data);
  201     }
  202 
  203     if (outformat == FORMAT_ASN1 && genkey)
  204         noout = 1;
  205 
  206     if (!noout) {
  207         if (outformat == FORMAT_ASN1)
  208             i = i2d_DSAparams_bio(out, dsa);
  209         else
  210             i = PEM_write_bio_DSAparams(out, dsa);
  211         if (!i) {
  212             BIO_printf(bio_err, "unable to write DSA parameters\n");
  213             ERR_print_errors(bio_err);
  214             goto end;
  215         }
  216     }
  217     if (genkey) {
  218         DSA *dsakey;
  219 
  220         if ((dsakey = DSAparams_dup(dsa)) == NULL)
  221             goto end;
  222         if (!DSA_generate_key(dsakey)) {
  223             ERR_print_errors(bio_err);
  224             DSA_free(dsakey);
  225             goto end;
  226         }
  227         assert(private);
  228         if (outformat == FORMAT_ASN1)
  229             i = i2d_DSAPrivateKey_bio(out, dsakey);
  230         else
  231             i = PEM_write_bio_DSAPrivateKey(out, dsakey, NULL, NULL, 0, NULL,
  232                                             NULL);
  233         DSA_free(dsakey);
  234     }
  235     ret = 0;
  236  end:
  237     BN_GENCB_free(cb);
  238     BIO_free(in);
  239     BIO_free_all(out);
  240     DSA_free(dsa);
  241     release_engine(e);
  242     return ret;
  243 }
  244 
  245 static int dsa_cb(int p, int n, BN_GENCB *cb)
  246 {
  247     static const char symbols[] = ".+*\n";
  248     char c = (p >= 0 && (size_t)p < sizeof(symbols) - 1) ? symbols[p] : '?';
  249 
  250     BIO_write(BN_GENCB_get_arg(cb), &c, 1);
  251     (void)BIO_flush(BN_GENCB_get_arg(cb));
  252     return 1;
  253 }