source: rtems-libbsd/freebsd/crypto/openssl/apps/genpkey.c @ 0a699e7

5-freebsd-126-freebsd-12
Last change on this file since 0a699e7 was 0a699e7, checked in by Christian Mauderer <christian.mauderer@…>, on 03/28/19 at 06:13:59

bin/openssl: Import from FreeBSD.

  • Property mode set to 100644
File size: 8.6 KB
Line 
1#include <machine/rtems-bsd-user-space.h>
2
3/*
4 * Copyright 2006-2018 The OpenSSL Project Authors. All Rights Reserved.
5 *
6 * Licensed under the OpenSSL license (the "License").  You may not use
7 * this file except in compliance with the License.  You can obtain a copy
8 * in the file LICENSE in the source distribution or at
9 * https://www.openssl.org/source/license.html
10 */
11
12#include <stdio.h>
13#include <string.h>
14#include "apps.h"
15#include "progs.h"
16#include <openssl/pem.h>
17#include <openssl/err.h>
18#include <openssl/evp.h>
19#ifndef OPENSSL_NO_ENGINE
20# include <openssl/engine.h>
21#endif
22
23static int init_keygen_file(EVP_PKEY_CTX **pctx, const char *file, ENGINE *e);
24static int genpkey_cb(EVP_PKEY_CTX *ctx);
25
26typedef enum OPTION_choice {
27    OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
28    OPT_ENGINE, OPT_OUTFORM, OPT_OUT, OPT_PASS, OPT_PARAMFILE,
29    OPT_ALGORITHM, OPT_PKEYOPT, OPT_GENPARAM, OPT_TEXT, OPT_CIPHER
30} OPTION_CHOICE;
31
32const OPTIONS genpkey_options[] = {
33    {"help", OPT_HELP, '-', "Display this summary"},
34    {"out", OPT_OUT, '>', "Output file"},
35    {"outform", OPT_OUTFORM, 'F', "output format (DER or PEM)"},
36    {"pass", OPT_PASS, 's', "Output file pass phrase source"},
37    {"paramfile", OPT_PARAMFILE, '<', "Parameters file"},
38    {"algorithm", OPT_ALGORITHM, 's', "The public key algorithm"},
39    {"pkeyopt", OPT_PKEYOPT, 's',
40     "Set the public key algorithm option as opt:value"},
41    {"genparam", OPT_GENPARAM, '-', "Generate parameters, not key"},
42    {"text", OPT_TEXT, '-', "Print the in text"},
43    {"", OPT_CIPHER, '-', "Cipher to use to encrypt the key"},
44#ifndef OPENSSL_NO_ENGINE
45    {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"},
46#endif
47    /* This is deliberately last. */
48    {OPT_HELP_STR, 1, 1,
49     "Order of options may be important!  See the documentation.\n"},
50    {NULL}
51};
52
53int genpkey_main(int argc, char **argv)
54{
55    BIO *in = NULL, *out = NULL;
56    ENGINE *e = NULL;
57    EVP_PKEY *pkey = NULL;
58    EVP_PKEY_CTX *ctx = NULL;
59    char *outfile = NULL, *passarg = NULL, *pass = NULL, *prog;
60    const EVP_CIPHER *cipher = NULL;
61    OPTION_CHOICE o;
62    int outformat = FORMAT_PEM, text = 0, ret = 1, rv, do_param = 0;
63    int private = 0;
64
65    prog = opt_init(argc, argv, genpkey_options);
66    while ((o = opt_next()) != OPT_EOF) {
67        switch (o) {
68        case OPT_EOF:
69        case OPT_ERR:
70 opthelp:
71            BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
72            goto end;
73        case OPT_HELP:
74            ret = 0;
75            opt_help(genpkey_options);
76            goto end;
77        case OPT_OUTFORM:
78            if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &outformat))
79                goto opthelp;
80            break;
81        case OPT_OUT:
82            outfile = opt_arg();
83            break;
84        case OPT_PASS:
85            passarg = opt_arg();
86            break;
87        case OPT_ENGINE:
88            e = setup_engine(opt_arg(), 0);
89            break;
90        case OPT_PARAMFILE:
91            if (do_param == 1)
92                goto opthelp;
93            if (!init_keygen_file(&ctx, opt_arg(), e))
94                goto end;
95            break;
96        case OPT_ALGORITHM:
97            if (!init_gen_str(&ctx, opt_arg(), e, do_param))
98                goto end;
99            break;
100        case OPT_PKEYOPT:
101            if (ctx == NULL) {
102                BIO_printf(bio_err, "%s: No keytype specified.\n", prog);
103                goto opthelp;
104            }
105            if (pkey_ctrl_string(ctx, opt_arg()) <= 0) {
106                BIO_printf(bio_err,
107                           "%s: Error setting %s parameter:\n",
108                           prog, opt_arg());
109                ERR_print_errors(bio_err);
110                goto end;
111            }
112            break;
113        case OPT_GENPARAM:
114            if (ctx != NULL)
115                goto opthelp;
116            do_param = 1;
117            break;
118        case OPT_TEXT:
119            text = 1;
120            break;
121        case OPT_CIPHER:
122            if (!opt_cipher(opt_unknown(), &cipher)
123                || do_param == 1)
124                goto opthelp;
125            if (EVP_CIPHER_mode(cipher) == EVP_CIPH_GCM_MODE ||
126                EVP_CIPHER_mode(cipher) == EVP_CIPH_CCM_MODE ||
127                EVP_CIPHER_mode(cipher) == EVP_CIPH_XTS_MODE ||
128                EVP_CIPHER_mode(cipher) == EVP_CIPH_OCB_MODE) {
129                BIO_printf(bio_err, "%s: cipher mode not supported\n", prog);
130                goto end;
131            }
132        }
133    }
134    argc = opt_num_rest();
135    if (argc != 0)
136        goto opthelp;
137
138    private = do_param ? 0 : 1;
139
140    if (ctx == NULL)
141        goto opthelp;
142
143    if (!app_passwd(passarg, NULL, &pass, NULL)) {
144        BIO_puts(bio_err, "Error getting password\n");
145        goto end;
146    }
147
148    out = bio_open_owner(outfile, outformat, private);
149    if (out == NULL)
150        goto end;
151
152    EVP_PKEY_CTX_set_cb(ctx, genpkey_cb);
153    EVP_PKEY_CTX_set_app_data(ctx, bio_err);
154
155    if (do_param) {
156        if (EVP_PKEY_paramgen(ctx, &pkey) <= 0) {
157            BIO_puts(bio_err, "Error generating parameters\n");
158            ERR_print_errors(bio_err);
159            goto end;
160        }
161    } else {
162        if (EVP_PKEY_keygen(ctx, &pkey) <= 0) {
163            BIO_puts(bio_err, "Error generating key\n");
164            ERR_print_errors(bio_err);
165            goto end;
166        }
167    }
168
169    if (do_param) {
170        rv = PEM_write_bio_Parameters(out, pkey);
171    } else if (outformat == FORMAT_PEM) {
172        assert(private);
173        rv = PEM_write_bio_PrivateKey(out, pkey, cipher, NULL, 0, NULL, pass);
174    } else if (outformat == FORMAT_ASN1) {
175        assert(private);
176        rv = i2d_PrivateKey_bio(out, pkey);
177    } else {
178        BIO_printf(bio_err, "Bad format specified for key\n");
179        goto end;
180    }
181
182    if (rv <= 0) {
183        BIO_puts(bio_err, "Error writing key\n");
184        ERR_print_errors(bio_err);
185    }
186
187    if (text) {
188        if (do_param)
189            rv = EVP_PKEY_print_params(out, pkey, 0, NULL);
190        else
191            rv = EVP_PKEY_print_private(out, pkey, 0, NULL);
192
193        if (rv <= 0) {
194            BIO_puts(bio_err, "Error printing key\n");
195            ERR_print_errors(bio_err);
196        }
197    }
198
199    ret = 0;
200
201 end:
202    EVP_PKEY_free(pkey);
203    EVP_PKEY_CTX_free(ctx);
204    BIO_free_all(out);
205    BIO_free(in);
206    release_engine(e);
207    OPENSSL_free(pass);
208    return ret;
209}
210
211static int init_keygen_file(EVP_PKEY_CTX **pctx, const char *file, ENGINE *e)
212{
213    BIO *pbio;
214    EVP_PKEY *pkey = NULL;
215    EVP_PKEY_CTX *ctx = NULL;
216    if (*pctx) {
217        BIO_puts(bio_err, "Parameters already set!\n");
218        return 0;
219    }
220
221    pbio = BIO_new_file(file, "r");
222    if (!pbio) {
223        BIO_printf(bio_err, "Can't open parameter file %s\n", file);
224        return 0;
225    }
226
227    pkey = PEM_read_bio_Parameters(pbio, NULL);
228    BIO_free(pbio);
229
230    if (!pkey) {
231        BIO_printf(bio_err, "Error reading parameter file %s\n", file);
232        return 0;
233    }
234
235    ctx = EVP_PKEY_CTX_new(pkey, e);
236    if (ctx == NULL)
237        goto err;
238    if (EVP_PKEY_keygen_init(ctx) <= 0)
239        goto err;
240    EVP_PKEY_free(pkey);
241    *pctx = ctx;
242    return 1;
243
244 err:
245    BIO_puts(bio_err, "Error initializing context\n");
246    ERR_print_errors(bio_err);
247    EVP_PKEY_CTX_free(ctx);
248    EVP_PKEY_free(pkey);
249    return 0;
250
251}
252
253int init_gen_str(EVP_PKEY_CTX **pctx,
254                 const char *algname, ENGINE *e, int do_param)
255{
256    EVP_PKEY_CTX *ctx = NULL;
257    const EVP_PKEY_ASN1_METHOD *ameth;
258    ENGINE *tmpeng = NULL;
259    int pkey_id;
260
261    if (*pctx) {
262        BIO_puts(bio_err, "Algorithm already set!\n");
263        return 0;
264    }
265
266    ameth = EVP_PKEY_asn1_find_str(&tmpeng, algname, -1);
267
268#ifndef OPENSSL_NO_ENGINE
269    if (!ameth && e)
270        ameth = ENGINE_get_pkey_asn1_meth_str(e, algname, -1);
271#endif
272
273    if (!ameth) {
274        BIO_printf(bio_err, "Algorithm %s not found\n", algname);
275        return 0;
276    }
277
278    ERR_clear_error();
279
280    EVP_PKEY_asn1_get0_info(&pkey_id, NULL, NULL, NULL, NULL, ameth);
281#ifndef OPENSSL_NO_ENGINE
282    ENGINE_finish(tmpeng);
283#endif
284    ctx = EVP_PKEY_CTX_new_id(pkey_id, e);
285
286    if (!ctx)
287        goto err;
288    if (do_param) {
289        if (EVP_PKEY_paramgen_init(ctx) <= 0)
290            goto err;
291    } else {
292        if (EVP_PKEY_keygen_init(ctx) <= 0)
293            goto err;
294    }
295
296    *pctx = ctx;
297    return 1;
298
299 err:
300    BIO_printf(bio_err, "Error initializing %s context\n", algname);
301    ERR_print_errors(bio_err);
302    EVP_PKEY_CTX_free(ctx);
303    return 0;
304
305}
306
307static int genpkey_cb(EVP_PKEY_CTX *ctx)
308{
309    char c = '*';
310    BIO *b = EVP_PKEY_CTX_get_app_data(ctx);
311    int p;
312    p = EVP_PKEY_CTX_get_keygen_info(ctx, 0);
313    if (p == 0)
314        c = '.';
315    if (p == 1)
316        c = '+';
317    if (p == 2)
318        c = '*';
319    if (p == 3)
320        c = '\n';
321    BIO_write(b, &c, 1);
322    (void)BIO_flush(b);
323    return 1;
324}
Note: See TracBrowser for help on using the repository browser.