"Fossies" - the Fresh Open Source Software Archive

Member "openssl-1.1.1g/apps/genrsa.c" (21 Apr 2020, 5492 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 "genrsa.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 <string.h>
   13 #include <sys/types.h>
   14 #include <sys/stat.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/rsa.h>
   21 #include <openssl/evp.h>
   22 #include <openssl/x509.h>
   23 #include <openssl/pem.h>
   24 #include <openssl/rand.h>
   25 
   26 #define DEFBITS 2048
   27 #define DEFPRIMES 2
   28 
   29 static int genrsa_cb(int p, int n, BN_GENCB *cb);
   30 
   31 typedef enum OPTION_choice {
   32     OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
   33     OPT_3, OPT_F4, OPT_ENGINE,
   34     OPT_OUT, OPT_PASSOUT, OPT_CIPHER, OPT_PRIMES,
   35     OPT_R_ENUM
   36 } OPTION_CHOICE;
   37 
   38 const OPTIONS genrsa_options[] = {
   39     {"help", OPT_HELP, '-', "Display this summary"},
   40     {"3", OPT_3, '-', "Use 3 for the E value"},
   41     {"F4", OPT_F4, '-', "Use F4 (0x10001) for the E value"},
   42     {"f4", OPT_F4, '-', "Use F4 (0x10001) for the E value"},
   43     {"out", OPT_OUT, '>', "Output the key to specified file"},
   44     OPT_R_OPTIONS,
   45     {"passout", OPT_PASSOUT, 's', "Output file pass phrase source"},
   46     {"", OPT_CIPHER, '-', "Encrypt the output with any supported cipher"},
   47 #ifndef OPENSSL_NO_ENGINE
   48     {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"},
   49 #endif
   50     {"primes", OPT_PRIMES, 'p', "Specify number of primes"},
   51     {NULL}
   52 };
   53 
   54 int genrsa_main(int argc, char **argv)
   55 {
   56     BN_GENCB *cb = BN_GENCB_new();
   57     PW_CB_DATA cb_data;
   58     ENGINE *eng = NULL;
   59     BIGNUM *bn = BN_new();
   60     BIO *out = NULL;
   61     const BIGNUM *e;
   62     RSA *rsa = NULL;
   63     const EVP_CIPHER *enc = NULL;
   64     int ret = 1, num = DEFBITS, private = 0, primes = DEFPRIMES;
   65     unsigned long f4 = RSA_F4;
   66     char *outfile = NULL, *passoutarg = NULL, *passout = NULL;
   67     char *prog, *hexe, *dece;
   68     OPTION_CHOICE o;
   69 
   70     if (bn == NULL || cb == NULL)
   71         goto end;
   72 
   73     BN_GENCB_set(cb, genrsa_cb, bio_err);
   74 
   75     prog = opt_init(argc, argv, genrsa_options);
   76     while ((o = opt_next()) != OPT_EOF) {
   77         switch (o) {
   78         case OPT_EOF:
   79         case OPT_ERR:
   80 opthelp:
   81             BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
   82             goto end;
   83         case OPT_HELP:
   84             ret = 0;
   85             opt_help(genrsa_options);
   86             goto end;
   87         case OPT_3:
   88             f4 = 3;
   89             break;
   90         case OPT_F4:
   91             f4 = RSA_F4;
   92             break;
   93         case OPT_OUT:
   94             outfile = opt_arg();
   95             break;
   96         case OPT_ENGINE:
   97             eng = setup_engine(opt_arg(), 0);
   98             break;
   99         case OPT_R_CASES:
  100             if (!opt_rand(o))
  101                 goto end;
  102             break;
  103         case OPT_PASSOUT:
  104             passoutarg = opt_arg();
  105             break;
  106         case OPT_CIPHER:
  107             if (!opt_cipher(opt_unknown(), &enc))
  108                 goto end;
  109             break;
  110         case OPT_PRIMES:
  111             if (!opt_int(opt_arg(), &primes))
  112                 goto end;
  113             break;
  114         }
  115     }
  116     argc = opt_num_rest();
  117     argv = opt_rest();
  118 
  119     if (argc == 1) {
  120         if (!opt_int(argv[0], &num) || num <= 0)
  121             goto end;
  122         if (num > OPENSSL_RSA_MAX_MODULUS_BITS)
  123             BIO_printf(bio_err,
  124                        "Warning: It is not recommended to use more than %d bit for RSA keys.\n"
  125                        "         Your key size is %d! Larger key size may behave not as expected.\n",
  126                        OPENSSL_RSA_MAX_MODULUS_BITS, num);
  127     } else if (argc > 0) {
  128         BIO_printf(bio_err, "Extra arguments given.\n");
  129         goto opthelp;
  130     }
  131 
  132     private = 1;
  133     if (!app_passwd(NULL, passoutarg, NULL, &passout)) {
  134         BIO_printf(bio_err, "Error getting password\n");
  135         goto end;
  136     }
  137 
  138     out = bio_open_owner(outfile, FORMAT_PEM, private);
  139     if (out == NULL)
  140         goto end;
  141 
  142     BIO_printf(bio_err, "Generating RSA private key, %d bit long modulus (%d primes)\n",
  143                num, primes);
  144     rsa = eng ? RSA_new_method(eng) : RSA_new();
  145     if (rsa == NULL)
  146         goto end;
  147 
  148     if (!BN_set_word(bn, f4)
  149         || !RSA_generate_multi_prime_key(rsa, num, primes, bn, cb))
  150         goto end;
  151 
  152     RSA_get0_key(rsa, NULL, &e, NULL);
  153     hexe = BN_bn2hex(e);
  154     dece = BN_bn2dec(e);
  155     if (hexe && dece) {
  156         BIO_printf(bio_err, "e is %s (0x%s)\n", dece, hexe);
  157     }
  158     OPENSSL_free(hexe);
  159     OPENSSL_free(dece);
  160     cb_data.password = passout;
  161     cb_data.prompt_info = outfile;
  162     assert(private);
  163     if (!PEM_write_bio_RSAPrivateKey(out, rsa, enc, NULL, 0,
  164                                      (pem_password_cb *)password_callback,
  165                                      &cb_data))
  166         goto end;
  167 
  168     ret = 0;
  169  end:
  170     BN_free(bn);
  171     BN_GENCB_free(cb);
  172     RSA_free(rsa);
  173     BIO_free_all(out);
  174     release_engine(eng);
  175     OPENSSL_free(passout);
  176     if (ret != 0)
  177         ERR_print_errors(bio_err);
  178     return ret;
  179 }
  180 
  181 static int genrsa_cb(int p, int n, BN_GENCB *cb)
  182 {
  183     char c = '*';
  184 
  185     if (p == 0)
  186         c = '.';
  187     if (p == 1)
  188         c = '+';
  189     if (p == 2)
  190         c = '*';
  191     if (p == 3)
  192         c = '\n';
  193     BIO_write(BN_GENCB_get_arg(cb), &c, 1);
  194     (void)BIO_flush(BN_GENCB_get_arg(cb));
  195     return 1;
  196 }