req.c revision 312826
1/* apps/req.c */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved.
4 *
5 * This package is an SSL implementation written
6 * by Eric Young (eay@cryptsoft.com).
7 * The implementation was written so as to conform with Netscapes SSL.
8 *
9 * This library is free for commercial and non-commercial use as long as
10 * the following conditions are aheared to.  The following conditions
11 * apply to all code found in this distribution, be it the RC4, RSA,
12 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
13 * included with this distribution is covered by the same copyright terms
14 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 *
16 * Copyright remains Eric Young's, and as such any Copyright notices in
17 * the code are not to be removed.
18 * If this package is used in a product, Eric Young should be given attribution
19 * as the author of the parts of the library used.
20 * This can be in the form of a textual message at program startup or
21 * in documentation (online or textual) provided with the package.
22 *
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
25 * are met:
26 * 1. Redistributions of source code must retain the copyright
27 *    notice, this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright
29 *    notice, this list of conditions and the following disclaimer in the
30 *    documentation and/or other materials provided with the distribution.
31 * 3. All advertising materials mentioning features or use of this software
32 *    must display the following acknowledgement:
33 *    "This product includes cryptographic software written by
34 *     Eric Young (eay@cryptsoft.com)"
35 *    The word 'cryptographic' can be left out if the rouines from the library
36 *    being used are not cryptographic related :-).
37 * 4. If you include any Windows specific code (or a derivative thereof) from
38 *    the apps directory (application code) you must include an acknowledgement:
39 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 *
41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 * SUCH DAMAGE.
52 *
53 * The licence and distribution terms for any publically available version or
54 * derivative of this code cannot be changed.  i.e. this code cannot simply be
55 * copied and put under another distribution licence
56 * [including the GNU Public Licence.]
57 */
58
59/*
60 * Until the key-gen callbacks are modified to use newer prototypes, we allow
61 * deprecated functions for openssl-internal code
62 */
63#ifdef OPENSSL_NO_DEPRECATED
64# undef OPENSSL_NO_DEPRECATED
65#endif
66
67#include <stdio.h>
68#include <stdlib.h>
69#include <time.h>
70#include <string.h>
71#ifdef OPENSSL_NO_STDIO
72# define APPS_WIN16
73#endif
74#include "apps.h"
75#include <openssl/bio.h>
76#include <openssl/evp.h>
77#include <openssl/conf.h>
78#include <openssl/err.h>
79#include <openssl/asn1.h>
80#include <openssl/x509.h>
81#include <openssl/x509v3.h>
82#include <openssl/objects.h>
83#include <openssl/pem.h>
84#include <openssl/bn.h>
85#ifndef OPENSSL_NO_RSA
86# include <openssl/rsa.h>
87#endif
88#ifndef OPENSSL_NO_DSA
89# include <openssl/dsa.h>
90#endif
91
92#define SECTION         "req"
93
94#define BITS            "default_bits"
95#define KEYFILE         "default_keyfile"
96#define PROMPT          "prompt"
97#define DISTINGUISHED_NAME      "distinguished_name"
98#define ATTRIBUTES      "attributes"
99#define V3_EXTENSIONS   "x509_extensions"
100#define REQ_EXTENSIONS  "req_extensions"
101#define STRING_MASK     "string_mask"
102#define UTF8_IN         "utf8"
103
104#define DEFAULT_KEY_LENGTH      2048
105#define MIN_KEY_LENGTH          512
106
107#undef PROG
108#define PROG    req_main
109
110/*-
111 * -inform arg  - input format - default PEM (DER or PEM)
112 * -outform arg - output format - default PEM
113 * -in arg      - input file - default stdin
114 * -out arg     - output file - default stdout
115 * -verify      - check request signature
116 * -noout       - don't print stuff out.
117 * -text        - print out human readable text.
118 * -nodes       - no des encryption
119 * -config file - Load configuration file.
120 * -key file    - make a request using key in file (or use it for verification).
121 * -keyform arg - key file format.
122 * -rand file(s) - load the file(s) into the PRNG.
123 * -newkey      - make a key and a request.
124 * -modulus     - print RSA modulus.
125 * -pubkey      - output Public Key.
126 * -x509        - output a self signed X509 structure instead.
127 * -asn1-kludge - output new certificate request in a format that some CA's
128 *                require.  This format is wrong
129 */
130
131static int make_REQ(X509_REQ *req, EVP_PKEY *pkey, char *dn, int mutlirdn,
132                    int attribs, unsigned long chtype);
133static int build_subject(X509_REQ *req, char *subj, unsigned long chtype,
134                         int multirdn);
135static int prompt_info(X509_REQ *req,
136                       STACK_OF(CONF_VALUE) *dn_sk, char *dn_sect,
137                       STACK_OF(CONF_VALUE) *attr_sk, char *attr_sect,
138                       int attribs, unsigned long chtype);
139static int auto_info(X509_REQ *req, STACK_OF(CONF_VALUE) *sk,
140                     STACK_OF(CONF_VALUE) *attr, int attribs,
141                     unsigned long chtype);
142static int add_attribute_object(X509_REQ *req, char *text, const char *def,
143                                char *value, int nid, int n_min, int n_max,
144                                unsigned long chtype);
145static int add_DN_object(X509_NAME *n, char *text, const char *def,
146                         char *value, int nid, int n_min, int n_max,
147                         unsigned long chtype, int mval);
148static int genpkey_cb(EVP_PKEY_CTX *ctx);
149static int req_check_len(int len, int n_min, int n_max);
150static int check_end(const char *str, const char *end);
151static EVP_PKEY_CTX *set_keygen_ctx(BIO *err, const char *gstr,
152                                    int *pkey_type, long *pkeylen,
153                                    char **palgnam, ENGINE *keygen_engine);
154#ifndef MONOLITH
155static char *default_config_file = NULL;
156#endif
157static CONF *req_conf = NULL;
158static int batch = 0;
159
160int MAIN(int, char **);
161
162int MAIN(int argc, char **argv)
163{
164    ENGINE *e = NULL, *gen_eng = NULL;
165    unsigned long nmflag = 0, reqflag = 0;
166    int ex = 1, x509 = 0, days = 30;
167    X509 *x509ss = NULL;
168    X509_REQ *req = NULL;
169    EVP_PKEY_CTX *genctx = NULL;
170    const char *keyalg = NULL;
171    char *keyalgstr = NULL;
172    STACK_OF(OPENSSL_STRING) *pkeyopts = NULL, *sigopts = NULL;
173    EVP_PKEY *pkey = NULL;
174    int i = 0, badops = 0, newreq = 0, verbose = 0, pkey_type = -1;
175    long newkey = -1;
176    BIO *in = NULL, *out = NULL;
177    int informat, outformat, verify = 0, noout = 0, text = 0, keyform =
178        FORMAT_PEM;
179    int nodes = 0, kludge = 0, newhdr = 0, subject = 0, pubkey = 0;
180    char *infile, *outfile, *prog, *keyfile = NULL, *template =
181        NULL, *keyout = NULL;
182    char *engine = NULL;
183    char *extensions = NULL;
184    char *req_exts = NULL;
185    const EVP_CIPHER *cipher = NULL;
186    ASN1_INTEGER *serial = NULL;
187    int modulus = 0;
188    char *inrand = NULL;
189    char *passargin = NULL, *passargout = NULL;
190    char *passin = NULL, *passout = NULL;
191    char *p;
192    char *subj = NULL;
193    int multirdn = 0;
194    const EVP_MD *md_alg = NULL, *digest = NULL;
195    unsigned long chtype = MBSTRING_ASC;
196#ifndef MONOLITH
197    char *to_free;
198    long errline;
199#endif
200
201    req_conf = NULL;
202#ifndef OPENSSL_NO_DES
203    cipher = EVP_des_ede3_cbc();
204#endif
205    apps_startup();
206
207    if (bio_err == NULL)
208        if ((bio_err = BIO_new(BIO_s_file())) != NULL)
209            BIO_set_fp(bio_err, stderr, BIO_NOCLOSE | BIO_FP_TEXT);
210
211    infile = NULL;
212    outfile = NULL;
213    informat = FORMAT_PEM;
214    outformat = FORMAT_PEM;
215
216    prog = argv[0];
217    argc--;
218    argv++;
219    while (argc >= 1) {
220        if (strcmp(*argv, "-inform") == 0) {
221            if (--argc < 1)
222                goto bad;
223            informat = str2fmt(*(++argv));
224        } else if (strcmp(*argv, "-outform") == 0) {
225            if (--argc < 1)
226                goto bad;
227            outformat = str2fmt(*(++argv));
228        }
229#ifndef OPENSSL_NO_ENGINE
230        else if (strcmp(*argv, "-engine") == 0) {
231            if (--argc < 1)
232                goto bad;
233            engine = *(++argv);
234        } else if (strcmp(*argv, "-keygen_engine") == 0) {
235            if (--argc < 1)
236                goto bad;
237            gen_eng = ENGINE_by_id(*(++argv));
238            if (gen_eng == NULL) {
239                BIO_printf(bio_err, "Can't find keygen engine %s\n", *argv);
240                goto end;
241            }
242        }
243#endif
244        else if (strcmp(*argv, "-key") == 0) {
245            if (--argc < 1)
246                goto bad;
247            keyfile = *(++argv);
248        } else if (strcmp(*argv, "-pubkey") == 0) {
249            pubkey = 1;
250        } else if (strcmp(*argv, "-new") == 0) {
251            newreq = 1;
252        } else if (strcmp(*argv, "-config") == 0) {
253            if (--argc < 1)
254                goto bad;
255            template = *(++argv);
256        } else if (strcmp(*argv, "-keyform") == 0) {
257            if (--argc < 1)
258                goto bad;
259            keyform = str2fmt(*(++argv));
260        } else if (strcmp(*argv, "-in") == 0) {
261            if (--argc < 1)
262                goto bad;
263            infile = *(++argv);
264        } else if (strcmp(*argv, "-out") == 0) {
265            if (--argc < 1)
266                goto bad;
267            outfile = *(++argv);
268        } else if (strcmp(*argv, "-keyout") == 0) {
269            if (--argc < 1)
270                goto bad;
271            keyout = *(++argv);
272        } else if (strcmp(*argv, "-passin") == 0) {
273            if (--argc < 1)
274                goto bad;
275            passargin = *(++argv);
276        } else if (strcmp(*argv, "-passout") == 0) {
277            if (--argc < 1)
278                goto bad;
279            passargout = *(++argv);
280        } else if (strcmp(*argv, "-rand") == 0) {
281            if (--argc < 1)
282                goto bad;
283            inrand = *(++argv);
284        } else if (strcmp(*argv, "-newkey") == 0) {
285            if (--argc < 1)
286                goto bad;
287            keyalg = *(++argv);
288            newreq = 1;
289        } else if (strcmp(*argv, "-pkeyopt") == 0) {
290            if (--argc < 1)
291                goto bad;
292            if (!pkeyopts)
293                pkeyopts = sk_OPENSSL_STRING_new_null();
294            if (!pkeyopts || !sk_OPENSSL_STRING_push(pkeyopts, *(++argv)))
295                goto bad;
296        } else if (strcmp(*argv, "-sigopt") == 0) {
297            if (--argc < 1)
298                goto bad;
299            if (!sigopts)
300                sigopts = sk_OPENSSL_STRING_new_null();
301            if (!sigopts || !sk_OPENSSL_STRING_push(sigopts, *(++argv)))
302                goto bad;
303        } else if (strcmp(*argv, "-batch") == 0)
304            batch = 1;
305        else if (strcmp(*argv, "-newhdr") == 0)
306            newhdr = 1;
307        else if (strcmp(*argv, "-modulus") == 0)
308            modulus = 1;
309        else if (strcmp(*argv, "-verify") == 0)
310            verify = 1;
311        else if (strcmp(*argv, "-nodes") == 0)
312            nodes = 1;
313        else if (strcmp(*argv, "-noout") == 0)
314            noout = 1;
315        else if (strcmp(*argv, "-verbose") == 0)
316            verbose = 1;
317        else if (strcmp(*argv, "-utf8") == 0)
318            chtype = MBSTRING_UTF8;
319        else if (strcmp(*argv, "-nameopt") == 0) {
320            if (--argc < 1)
321                goto bad;
322            if (!set_name_ex(&nmflag, *(++argv)))
323                goto bad;
324        } else if (strcmp(*argv, "-reqopt") == 0) {
325            if (--argc < 1)
326                goto bad;
327            if (!set_cert_ex(&reqflag, *(++argv)))
328                goto bad;
329        } else if (strcmp(*argv, "-subject") == 0)
330            subject = 1;
331        else if (strcmp(*argv, "-text") == 0)
332            text = 1;
333        else if (strcmp(*argv, "-x509") == 0) {
334            newreq = 1;
335            x509 = 1;
336        } else if (strcmp(*argv, "-asn1-kludge") == 0)
337            kludge = 1;
338        else if (strcmp(*argv, "-no-asn1-kludge") == 0)
339            kludge = 0;
340        else if (strcmp(*argv, "-subj") == 0) {
341            if (--argc < 1)
342                goto bad;
343            subj = *(++argv);
344        } else if (strcmp(*argv, "-multivalue-rdn") == 0)
345            multirdn = 1;
346        else if (strcmp(*argv, "-days") == 0) {
347            if (--argc < 1)
348                goto bad;
349            days = atoi(*(++argv));
350            if (days == 0)
351                days = 30;
352        } else if (strcmp(*argv, "-set_serial") == 0) {
353            if (--argc < 1)
354                goto bad;
355            serial = s2i_ASN1_INTEGER(NULL, *(++argv));
356            if (!serial)
357                goto bad;
358        } else if (strcmp(*argv, "-extensions") == 0) {
359            if (--argc < 1)
360                goto bad;
361            extensions = *(++argv);
362        } else if (strcmp(*argv, "-reqexts") == 0) {
363            if (--argc < 1)
364                goto bad;
365            req_exts = *(++argv);
366        } else if ((md_alg = EVP_get_digestbyname(&((*argv)[1]))) != NULL) {
367            /* ok */
368            digest = md_alg;
369        } else {
370            BIO_printf(bio_err, "unknown option %s\n", *argv);
371            badops = 1;
372            break;
373        }
374        argc--;
375        argv++;
376    }
377
378    if (badops) {
379 bad:
380        BIO_printf(bio_err, "%s [options] <infile >outfile\n", prog);
381        BIO_printf(bio_err, "where options  are\n");
382        BIO_printf(bio_err, " -inform arg    input format - DER or PEM\n");
383        BIO_printf(bio_err, " -outform arg   output format - DER or PEM\n");
384        BIO_printf(bio_err, " -in arg        input file\n");
385        BIO_printf(bio_err, " -out arg       output file\n");
386        BIO_printf(bio_err, " -text          text form of request\n");
387        BIO_printf(bio_err, " -pubkey        output public key\n");
388        BIO_printf(bio_err, " -noout         do not output REQ\n");
389        BIO_printf(bio_err, " -verify        verify signature on REQ\n");
390        BIO_printf(bio_err, " -modulus       RSA modulus\n");
391        BIO_printf(bio_err, " -nodes         don't encrypt the output key\n");
392#ifndef OPENSSL_NO_ENGINE
393        BIO_printf(bio_err,
394                   " -engine e      use engine e, possibly a hardware device\n");
395#endif
396        BIO_printf(bio_err, " -subject       output the request's subject\n");
397        BIO_printf(bio_err, " -passin        private key password source\n");
398        BIO_printf(bio_err,
399                   " -key file      use the private key contained in file\n");
400        BIO_printf(bio_err, " -keyform arg   key file format\n");
401        BIO_printf(bio_err, " -keyout arg    file to send the key to\n");
402        BIO_printf(bio_err, " -rand file%cfile%c...\n", LIST_SEPARATOR_CHAR,
403                   LIST_SEPARATOR_CHAR);
404        BIO_printf(bio_err,
405                   "                load the file (or the files in the directory) into\n");
406        BIO_printf(bio_err, "                the random number generator\n");
407        BIO_printf(bio_err,
408                   " -newkey rsa:bits generate a new RSA key of 'bits' in size\n");
409        BIO_printf(bio_err,
410                   " -newkey dsa:file generate a new DSA key, parameters taken from CA in 'file'\n");
411#ifndef OPENSSL_NO_ECDSA
412        BIO_printf(bio_err,
413                   " -newkey ec:file generate a new EC key, parameters taken from CA in 'file'\n");
414#endif
415        BIO_printf(bio_err,
416                   " -[digest]      Digest to sign with (md5, sha1, md2, mdc2, md4)\n");
417        BIO_printf(bio_err, " -config file   request template file.\n");
418        BIO_printf(bio_err,
419                   " -subj arg      set or modify request subject\n");
420        BIO_printf(bio_err,
421                   " -multivalue-rdn enable support for multivalued RDNs\n");
422        BIO_printf(bio_err, " -new           new request.\n");
423        BIO_printf(bio_err,
424                   " -batch         do not ask anything during request generation\n");
425        BIO_printf(bio_err,
426                   " -x509          output a x509 structure instead of a cert. req.\n");
427        BIO_printf(bio_err,
428                   " -days          number of days a certificate generated by -x509 is valid for.\n");
429        BIO_printf(bio_err,
430                   " -set_serial    serial number to use for a certificate generated by -x509.\n");
431        BIO_printf(bio_err,
432                   " -newhdr        output \"NEW\" in the header lines\n");
433        BIO_printf(bio_err,
434                   " -asn1-kludge   Output the 'request' in a format that is wrong but some CA's\n");
435        BIO_printf(bio_err,
436                   "                have been reported as requiring\n");
437        BIO_printf(bio_err,
438                   " -extensions .. specify certificate extension section (override value in config file)\n");
439        BIO_printf(bio_err,
440                   " -reqexts ..    specify request extension section (override value in config file)\n");
441        BIO_printf(bio_err,
442                   " -utf8          input characters are UTF8 (default ASCII)\n");
443        BIO_printf(bio_err,
444                   " -nameopt arg    - various certificate name options\n");
445        BIO_printf(bio_err,
446                   " -reqopt arg    - various request text options\n\n");
447        goto end;
448    }
449
450    ERR_load_crypto_strings();
451    if (!app_passwd(bio_err, passargin, passargout, &passin, &passout)) {
452        BIO_printf(bio_err, "Error getting passwords\n");
453        goto end;
454    }
455#ifndef MONOLITH                /* else this has happened in openssl.c
456                                 * (global `config') */
457    /* Lets load up our environment a little */
458    p = getenv("OPENSSL_CONF");
459    if (p == NULL)
460        p = getenv("SSLEAY_CONF");
461    if (p == NULL)
462        p = to_free = make_config_name();
463    default_config_file = p;
464    config = NCONF_new(NULL);
465    i = NCONF_load(config, p, &errline);
466#endif
467
468    if (template != NULL) {
469        long errline = -1;
470
471        if (verbose)
472            BIO_printf(bio_err, "Using configuration from %s\n", template);
473        req_conf = NCONF_new(NULL);
474        i = NCONF_load(req_conf, template, &errline);
475        if (i == 0) {
476            BIO_printf(bio_err, "error on line %ld of %s\n", errline,
477                       template);
478            goto end;
479        }
480    } else {
481        req_conf = config;
482
483        if (req_conf == NULL) {
484            BIO_printf(bio_err, "Unable to load config info from %s\n",
485                       default_config_file);
486            if (newreq)
487                goto end;
488        } else if (verbose)
489            BIO_printf(bio_err, "Using configuration from %s\n",
490                       default_config_file);
491    }
492
493    if (req_conf != NULL) {
494        if (!load_config(bio_err, req_conf))
495            goto end;
496        p = NCONF_get_string(req_conf, NULL, "oid_file");
497        if (p == NULL)
498            ERR_clear_error();
499        if (p != NULL) {
500            BIO *oid_bio;
501
502            oid_bio = BIO_new_file(p, "r");
503            if (oid_bio == NULL) {
504                /*-
505                BIO_printf(bio_err,"problems opening %s for extra oid's\n",p);
506                ERR_print_errors(bio_err);
507                */
508            } else {
509                OBJ_create_objects(oid_bio);
510                BIO_free(oid_bio);
511            }
512        }
513    }
514    if (!add_oid_section(bio_err, req_conf))
515        goto end;
516
517    if (md_alg == NULL) {
518        p = NCONF_get_string(req_conf, SECTION, "default_md");
519        if (p == NULL)
520            ERR_clear_error();
521        if (p != NULL) {
522            if ((md_alg = EVP_get_digestbyname(p)) != NULL)
523                digest = md_alg;
524        }
525    }
526
527    if (!extensions) {
528        extensions = NCONF_get_string(req_conf, SECTION, V3_EXTENSIONS);
529        if (!extensions)
530            ERR_clear_error();
531    }
532    if (extensions) {
533        /* Check syntax of file */
534        X509V3_CTX ctx;
535        X509V3_set_ctx_test(&ctx);
536        X509V3_set_nconf(&ctx, req_conf);
537        if (!X509V3_EXT_add_nconf(req_conf, &ctx, extensions, NULL)) {
538            BIO_printf(bio_err,
539                       "Error Loading extension section %s\n", extensions);
540            goto end;
541        }
542    }
543
544    if (!passin) {
545        passin = NCONF_get_string(req_conf, SECTION, "input_password");
546        if (!passin)
547            ERR_clear_error();
548    }
549
550    if (!passout) {
551        passout = NCONF_get_string(req_conf, SECTION, "output_password");
552        if (!passout)
553            ERR_clear_error();
554    }
555
556    p = NCONF_get_string(req_conf, SECTION, STRING_MASK);
557    if (!p)
558        ERR_clear_error();
559
560    if (p && !ASN1_STRING_set_default_mask_asc(p)) {
561        BIO_printf(bio_err, "Invalid global string mask setting %s\n", p);
562        goto end;
563    }
564
565    if (chtype != MBSTRING_UTF8) {
566        p = NCONF_get_string(req_conf, SECTION, UTF8_IN);
567        if (!p)
568            ERR_clear_error();
569        else if (!strcmp(p, "yes"))
570            chtype = MBSTRING_UTF8;
571    }
572
573    if (!req_exts) {
574        req_exts = NCONF_get_string(req_conf, SECTION, REQ_EXTENSIONS);
575        if (!req_exts)
576            ERR_clear_error();
577    }
578    if (req_exts) {
579        /* Check syntax of file */
580        X509V3_CTX ctx;
581        X509V3_set_ctx_test(&ctx);
582        X509V3_set_nconf(&ctx, req_conf);
583        if (!X509V3_EXT_add_nconf(req_conf, &ctx, req_exts, NULL)) {
584            BIO_printf(bio_err,
585                       "Error Loading request extension section %s\n",
586                       req_exts);
587            goto end;
588        }
589    }
590
591    in = BIO_new(BIO_s_file());
592    out = BIO_new(BIO_s_file());
593    if ((in == NULL) || (out == NULL))
594        goto end;
595
596    e = setup_engine(bio_err, engine, 0);
597
598    if (keyfile != NULL) {
599        pkey = load_key(bio_err, keyfile, keyform, 0, passin, e,
600                        "Private Key");
601        if (!pkey) {
602            /*
603             * load_key() has already printed an appropriate message
604             */
605            goto end;
606        } else {
607            char *randfile = NCONF_get_string(req_conf, SECTION, "RANDFILE");
608            if (randfile == NULL)
609                ERR_clear_error();
610            app_RAND_load_file(randfile, bio_err, 0);
611        }
612    }
613
614    if (newreq && (pkey == NULL)) {
615        char *randfile = NCONF_get_string(req_conf, SECTION, "RANDFILE");
616        if (randfile == NULL)
617            ERR_clear_error();
618        app_RAND_load_file(randfile, bio_err, 0);
619        if (inrand)
620            app_RAND_load_files(inrand);
621
622        if (!NCONF_get_number(req_conf, SECTION, BITS, &newkey)) {
623            newkey = DEFAULT_KEY_LENGTH;
624        }
625
626        if (keyalg) {
627            genctx = set_keygen_ctx(bio_err, keyalg, &pkey_type, &newkey,
628                                    &keyalgstr, gen_eng);
629            if (!genctx)
630                goto end;
631        }
632
633        if (newkey < MIN_KEY_LENGTH
634            && (pkey_type == EVP_PKEY_RSA || pkey_type == EVP_PKEY_DSA)) {
635            BIO_printf(bio_err, "private key length is too short,\n");
636            BIO_printf(bio_err, "it needs to be at least %d bits, not %ld\n",
637                       MIN_KEY_LENGTH, newkey);
638            goto end;
639        }
640
641        if (!genctx) {
642            genctx = set_keygen_ctx(bio_err, NULL, &pkey_type, &newkey,
643                                    &keyalgstr, gen_eng);
644            if (!genctx)
645                goto end;
646        }
647
648        if (pkeyopts) {
649            char *genopt;
650            for (i = 0; i < sk_OPENSSL_STRING_num(pkeyopts); i++) {
651                genopt = sk_OPENSSL_STRING_value(pkeyopts, i);
652                if (pkey_ctrl_string(genctx, genopt) <= 0) {
653                    BIO_printf(bio_err, "parameter error \"%s\"\n", genopt);
654                    ERR_print_errors(bio_err);
655                    goto end;
656                }
657            }
658        }
659
660        BIO_printf(bio_err, "Generating a %ld bit %s private key\n",
661                   newkey, keyalgstr);
662
663        EVP_PKEY_CTX_set_cb(genctx, genpkey_cb);
664        EVP_PKEY_CTX_set_app_data(genctx, bio_err);
665
666        if (EVP_PKEY_keygen(genctx, &pkey) <= 0) {
667            BIO_puts(bio_err, "Error Generating Key\n");
668            goto end;
669        }
670
671        EVP_PKEY_CTX_free(genctx);
672        genctx = NULL;
673
674        app_RAND_write_file(randfile, bio_err);
675
676        if (keyout == NULL) {
677            keyout = NCONF_get_string(req_conf, SECTION, KEYFILE);
678            if (keyout == NULL)
679                ERR_clear_error();
680        }
681
682        if (keyout == NULL) {
683            BIO_printf(bio_err, "writing new private key to stdout\n");
684            BIO_set_fp(out, stdout, BIO_NOCLOSE);
685#ifdef OPENSSL_SYS_VMS
686            {
687                BIO *tmpbio = BIO_new(BIO_f_linebuffer());
688                out = BIO_push(tmpbio, out);
689            }
690#endif
691        } else {
692            BIO_printf(bio_err, "writing new private key to '%s'\n", keyout);
693            if (BIO_write_filename(out, keyout) <= 0) {
694                perror(keyout);
695                goto end;
696            }
697        }
698
699        p = NCONF_get_string(req_conf, SECTION, "encrypt_rsa_key");
700        if (p == NULL) {
701            ERR_clear_error();
702            p = NCONF_get_string(req_conf, SECTION, "encrypt_key");
703            if (p == NULL)
704                ERR_clear_error();
705        }
706        if ((p != NULL) && (strcmp(p, "no") == 0))
707            cipher = NULL;
708        if (nodes)
709            cipher = NULL;
710
711        i = 0;
712 loop:
713        if (!PEM_write_bio_PrivateKey(out, pkey, cipher,
714                                      NULL, 0, NULL, passout)) {
715            if ((ERR_GET_REASON(ERR_peek_error()) ==
716                 PEM_R_PROBLEMS_GETTING_PASSWORD) && (i < 3)) {
717                ERR_clear_error();
718                i++;
719                goto loop;
720            }
721            goto end;
722        }
723        BIO_printf(bio_err, "-----\n");
724    }
725
726    if (!newreq) {
727        /*
728         * Since we are using a pre-existing certificate request, the kludge
729         * 'format' info should not be changed.
730         */
731        kludge = -1;
732        if (infile == NULL)
733            BIO_set_fp(in, stdin, BIO_NOCLOSE);
734        else {
735            if (BIO_read_filename(in, infile) <= 0) {
736                perror(infile);
737                goto end;
738            }
739        }
740
741        if (informat == FORMAT_ASN1)
742            req = d2i_X509_REQ_bio(in, NULL);
743        else if (informat == FORMAT_PEM)
744            req = PEM_read_bio_X509_REQ(in, NULL, NULL, NULL);
745        else {
746            BIO_printf(bio_err,
747                       "bad input format specified for X509 request\n");
748            goto end;
749        }
750        if (req == NULL) {
751            BIO_printf(bio_err, "unable to load X509 request\n");
752            goto end;
753        }
754    }
755
756    if (newreq) {
757        if (pkey == NULL) {
758            BIO_printf(bio_err, "you need to specify a private key\n");
759            goto end;
760        }
761
762        if (req == NULL) {
763            req = X509_REQ_new();
764            if (req == NULL) {
765                goto end;
766            }
767
768            i = make_REQ(req, pkey, subj, multirdn, !x509, chtype);
769            subj = NULL;        /* done processing '-subj' option */
770            if ((kludge > 0)
771                && !sk_X509_ATTRIBUTE_num(req->req_info->attributes)) {
772                sk_X509_ATTRIBUTE_free(req->req_info->attributes);
773                req->req_info->attributes = NULL;
774            }
775            if (!i) {
776                BIO_printf(bio_err, "problems making Certificate Request\n");
777                goto end;
778            }
779        }
780        if (x509) {
781            EVP_PKEY *tmppkey;
782            X509V3_CTX ext_ctx;
783            if ((x509ss = X509_new()) == NULL)
784                goto end;
785
786            /* Set version to V3 */
787            if (extensions && !X509_set_version(x509ss, 2))
788                goto end;
789            if (serial) {
790                if (!X509_set_serialNumber(x509ss, serial))
791                    goto end;
792            } else {
793                if (!rand_serial(NULL, X509_get_serialNumber(x509ss)))
794                    goto end;
795            }
796
797            if (!X509_set_issuer_name(x509ss, X509_REQ_get_subject_name(req)))
798                goto end;
799            if (!X509_gmtime_adj(X509_get_notBefore(x509ss), 0))
800                goto end;
801            if (!X509_time_adj_ex(X509_get_notAfter(x509ss), days, 0, NULL))
802                goto end;
803            if (!X509_set_subject_name
804                (x509ss, X509_REQ_get_subject_name(req)))
805                goto end;
806            tmppkey = X509_REQ_get_pubkey(req);
807            if (!tmppkey || !X509_set_pubkey(x509ss, tmppkey))
808                goto end;
809            EVP_PKEY_free(tmppkey);
810
811            /* Set up V3 context struct */
812
813            X509V3_set_ctx(&ext_ctx, x509ss, x509ss, NULL, NULL, 0);
814            X509V3_set_nconf(&ext_ctx, req_conf);
815
816            /* Add extensions */
817            if (extensions && !X509V3_EXT_add_nconf(req_conf,
818                                                    &ext_ctx, extensions,
819                                                    x509ss)) {
820                BIO_printf(bio_err, "Error Loading extension section %s\n",
821                           extensions);
822                goto end;
823            }
824
825            i = do_X509_sign(bio_err, x509ss, pkey, digest, sigopts);
826            if (!i) {
827                ERR_print_errors(bio_err);
828                goto end;
829            }
830        } else {
831            X509V3_CTX ext_ctx;
832
833            /* Set up V3 context struct */
834
835            X509V3_set_ctx(&ext_ctx, NULL, NULL, req, NULL, 0);
836            X509V3_set_nconf(&ext_ctx, req_conf);
837
838            /* Add extensions */
839            if (req_exts && !X509V3_EXT_REQ_add_nconf(req_conf,
840                                                      &ext_ctx, req_exts,
841                                                      req)) {
842                BIO_printf(bio_err, "Error Loading extension section %s\n",
843                           req_exts);
844                goto end;
845            }
846            i = do_X509_REQ_sign(bio_err, req, pkey, digest, sigopts);
847            if (!i) {
848                ERR_print_errors(bio_err);
849                goto end;
850            }
851        }
852    }
853
854    if (subj && x509) {
855        BIO_printf(bio_err, "Cannot modifiy certificate subject\n");
856        goto end;
857    }
858
859    if (subj && !x509) {
860        if (verbose) {
861            BIO_printf(bio_err, "Modifying Request's Subject\n");
862            print_name(bio_err, "old subject=",
863                       X509_REQ_get_subject_name(req), nmflag);
864        }
865
866        if (build_subject(req, subj, chtype, multirdn) == 0) {
867            BIO_printf(bio_err, "ERROR: cannot modify subject\n");
868            ex = 1;
869            goto end;
870        }
871
872        req->req_info->enc.modified = 1;
873
874        if (verbose) {
875            print_name(bio_err, "new subject=",
876                       X509_REQ_get_subject_name(req), nmflag);
877        }
878    }
879
880    if (verify && !x509) {
881        int tmp = 0;
882
883        if (pkey == NULL) {
884            pkey = X509_REQ_get_pubkey(req);
885            tmp = 1;
886            if (pkey == NULL)
887                goto end;
888        }
889
890        i = X509_REQ_verify(req, pkey);
891        if (tmp) {
892            EVP_PKEY_free(pkey);
893            pkey = NULL;
894        }
895
896        if (i < 0) {
897            goto end;
898        } else if (i == 0) {
899            BIO_printf(bio_err, "verify failure\n");
900            ERR_print_errors(bio_err);
901        } else                  /* if (i > 0) */
902            BIO_printf(bio_err, "verify OK\n");
903    }
904
905    if (noout && !text && !modulus && !subject && !pubkey) {
906        ex = 0;
907        goto end;
908    }
909
910    if (outfile == NULL) {
911        BIO_set_fp(out, stdout, BIO_NOCLOSE);
912#ifdef OPENSSL_SYS_VMS
913        {
914            BIO *tmpbio = BIO_new(BIO_f_linebuffer());
915            out = BIO_push(tmpbio, out);
916        }
917#endif
918    } else {
919        if ((keyout != NULL) && (strcmp(outfile, keyout) == 0))
920            i = (int)BIO_append_filename(out, outfile);
921        else
922            i = (int)BIO_write_filename(out, outfile);
923        if (!i) {
924            perror(outfile);
925            goto end;
926        }
927    }
928
929    if (pubkey) {
930        EVP_PKEY *tpubkey;
931        tpubkey = X509_REQ_get_pubkey(req);
932        if (tpubkey == NULL) {
933            BIO_printf(bio_err, "Error getting public key\n");
934            ERR_print_errors(bio_err);
935            goto end;
936        }
937        PEM_write_bio_PUBKEY(out, tpubkey);
938        EVP_PKEY_free(tpubkey);
939    }
940
941    if (text) {
942        if (x509)
943            X509_print_ex(out, x509ss, nmflag, reqflag);
944        else
945            X509_REQ_print_ex(out, req, nmflag, reqflag);
946    }
947
948    if (subject) {
949        if (x509)
950            print_name(out, "subject=", X509_get_subject_name(x509ss),
951                       nmflag);
952        else
953            print_name(out, "subject=", X509_REQ_get_subject_name(req),
954                       nmflag);
955    }
956
957    if (modulus) {
958        EVP_PKEY *tpubkey;
959
960        if (x509)
961            tpubkey = X509_get_pubkey(x509ss);
962        else
963            tpubkey = X509_REQ_get_pubkey(req);
964        if (tpubkey == NULL) {
965            fprintf(stdout, "Modulus=unavailable\n");
966            goto end;
967        }
968        fprintf(stdout, "Modulus=");
969#ifndef OPENSSL_NO_RSA
970        if (EVP_PKEY_base_id(tpubkey) == EVP_PKEY_RSA)
971            BN_print(out, tpubkey->pkey.rsa->n);
972        else
973#endif
974            fprintf(stdout, "Wrong Algorithm type");
975        EVP_PKEY_free(tpubkey);
976        fprintf(stdout, "\n");
977    }
978
979    if (!noout && !x509) {
980        if (outformat == FORMAT_ASN1)
981            i = i2d_X509_REQ_bio(out, req);
982        else if (outformat == FORMAT_PEM) {
983            if (newhdr)
984                i = PEM_write_bio_X509_REQ_NEW(out, req);
985            else
986                i = PEM_write_bio_X509_REQ(out, req);
987        } else {
988            BIO_printf(bio_err, "bad output format specified for outfile\n");
989            goto end;
990        }
991        if (!i) {
992            BIO_printf(bio_err, "unable to write X509 request\n");
993            goto end;
994        }
995    }
996    if (!noout && x509 && (x509ss != NULL)) {
997        if (outformat == FORMAT_ASN1)
998            i = i2d_X509_bio(out, x509ss);
999        else if (outformat == FORMAT_PEM)
1000            i = PEM_write_bio_X509(out, x509ss);
1001        else {
1002            BIO_printf(bio_err, "bad output format specified for outfile\n");
1003            goto end;
1004        }
1005        if (!i) {
1006            BIO_printf(bio_err, "unable to write X509 certificate\n");
1007            goto end;
1008        }
1009    }
1010    ex = 0;
1011 end:
1012#ifndef MONOLITH
1013    if (to_free)
1014        OPENSSL_free(to_free);
1015#endif
1016    if (ex) {
1017        ERR_print_errors(bio_err);
1018    }
1019    if ((req_conf != NULL) && (req_conf != config))
1020        NCONF_free(req_conf);
1021    BIO_free(in);
1022    BIO_free_all(out);
1023    EVP_PKEY_free(pkey);
1024    if (genctx)
1025        EVP_PKEY_CTX_free(genctx);
1026    if (pkeyopts)
1027        sk_OPENSSL_STRING_free(pkeyopts);
1028    if (sigopts)
1029        sk_OPENSSL_STRING_free(sigopts);
1030#ifndef OPENSSL_NO_ENGINE
1031    if (gen_eng)
1032        ENGINE_free(gen_eng);
1033#endif
1034    if (keyalgstr)
1035        OPENSSL_free(keyalgstr);
1036    X509_REQ_free(req);
1037    X509_free(x509ss);
1038    ASN1_INTEGER_free(serial);
1039    release_engine(e);
1040    if (passargin && passin)
1041        OPENSSL_free(passin);
1042    if (passargout && passout)
1043        OPENSSL_free(passout);
1044    OBJ_cleanup();
1045    apps_shutdown();
1046    OPENSSL_EXIT(ex);
1047}
1048
1049static int make_REQ(X509_REQ *req, EVP_PKEY *pkey, char *subj, int multirdn,
1050                    int attribs, unsigned long chtype)
1051{
1052    int ret = 0, i;
1053    char no_prompt = 0;
1054    STACK_OF(CONF_VALUE) *dn_sk, *attr_sk = NULL;
1055    char *tmp, *dn_sect, *attr_sect;
1056
1057    tmp = NCONF_get_string(req_conf, SECTION, PROMPT);
1058    if (tmp == NULL)
1059        ERR_clear_error();
1060    if ((tmp != NULL) && !strcmp(tmp, "no"))
1061        no_prompt = 1;
1062
1063    dn_sect = NCONF_get_string(req_conf, SECTION, DISTINGUISHED_NAME);
1064    if (dn_sect == NULL) {
1065        BIO_printf(bio_err, "unable to find '%s' in config\n",
1066                   DISTINGUISHED_NAME);
1067        goto err;
1068    }
1069    dn_sk = NCONF_get_section(req_conf, dn_sect);
1070    if (dn_sk == NULL) {
1071        BIO_printf(bio_err, "unable to get '%s' section\n", dn_sect);
1072        goto err;
1073    }
1074
1075    attr_sect = NCONF_get_string(req_conf, SECTION, ATTRIBUTES);
1076    if (attr_sect == NULL) {
1077        ERR_clear_error();
1078        attr_sk = NULL;
1079    } else {
1080        attr_sk = NCONF_get_section(req_conf, attr_sect);
1081        if (attr_sk == NULL) {
1082            BIO_printf(bio_err, "unable to get '%s' section\n", attr_sect);
1083            goto err;
1084        }
1085    }
1086
1087    /* setup version number */
1088    if (!X509_REQ_set_version(req, 0L))
1089        goto err;               /* version 1 */
1090
1091    if (no_prompt)
1092        i = auto_info(req, dn_sk, attr_sk, attribs, chtype);
1093    else {
1094        if (subj)
1095            i = build_subject(req, subj, chtype, multirdn);
1096        else
1097            i = prompt_info(req, dn_sk, dn_sect, attr_sk, attr_sect, attribs,
1098                            chtype);
1099    }
1100    if (!i)
1101        goto err;
1102
1103    if (!X509_REQ_set_pubkey(req, pkey))
1104        goto err;
1105
1106    ret = 1;
1107 err:
1108    return (ret);
1109}
1110
1111/*
1112 * subject is expected to be in the format /type0=value0/type1=value1/type2=...
1113 * where characters may be escaped by \
1114 */
1115static int build_subject(X509_REQ *req, char *subject, unsigned long chtype,
1116                         int multirdn)
1117{
1118    X509_NAME *n;
1119
1120    if (!(n = parse_name(subject, chtype, multirdn)))
1121        return 0;
1122
1123    if (!X509_REQ_set_subject_name(req, n)) {
1124        X509_NAME_free(n);
1125        return 0;
1126    }
1127    X509_NAME_free(n);
1128    return 1;
1129}
1130
1131static int prompt_info(X509_REQ *req,
1132                       STACK_OF(CONF_VALUE) *dn_sk, char *dn_sect,
1133                       STACK_OF(CONF_VALUE) *attr_sk, char *attr_sect,
1134                       int attribs, unsigned long chtype)
1135{
1136    int i;
1137    char *p, *q;
1138    char buf[100];
1139    int nid, mval;
1140    long n_min, n_max;
1141    char *type, *value;
1142    const char *def;
1143    CONF_VALUE *v;
1144    X509_NAME *subj;
1145    subj = X509_REQ_get_subject_name(req);
1146
1147    if (!batch) {
1148        BIO_printf(bio_err,
1149                   "You are about to be asked to enter information that will be incorporated\n");
1150        BIO_printf(bio_err, "into your certificate request.\n");
1151        BIO_printf(bio_err,
1152                   "What you are about to enter is what is called a Distinguished Name or a DN.\n");
1153        BIO_printf(bio_err,
1154                   "There are quite a few fields but you can leave some blank\n");
1155        BIO_printf(bio_err,
1156                   "For some fields there will be a default value,\n");
1157        BIO_printf(bio_err,
1158                   "If you enter '.', the field will be left blank.\n");
1159        BIO_printf(bio_err, "-----\n");
1160    }
1161
1162    if (sk_CONF_VALUE_num(dn_sk)) {
1163        i = -1;
1164 start:for (;;) {
1165            i++;
1166            if (sk_CONF_VALUE_num(dn_sk) <= i)
1167                break;
1168
1169            v = sk_CONF_VALUE_value(dn_sk, i);
1170            p = q = NULL;
1171            type = v->name;
1172            if (!check_end(type, "_min") || !check_end(type, "_max") ||
1173                !check_end(type, "_default") || !check_end(type, "_value"))
1174                continue;
1175            /*
1176             * Skip past any leading X. X: X, etc to allow for multiple
1177             * instances
1178             */
1179            for (p = v->name; *p; p++)
1180                if ((*p == ':') || (*p == ',') || (*p == '.')) {
1181                    p++;
1182                    if (*p)
1183                        type = p;
1184                    break;
1185                }
1186            if (*type == '+') {
1187                mval = -1;
1188                type++;
1189            } else
1190                mval = 0;
1191            /* If OBJ not recognised ignore it */
1192            if ((nid = OBJ_txt2nid(type)) == NID_undef)
1193                goto start;
1194            if (BIO_snprintf(buf, sizeof buf, "%s_default", v->name)
1195                >= (int)sizeof(buf)) {
1196                BIO_printf(bio_err, "Name '%s' too long\n", v->name);
1197                return 0;
1198            }
1199
1200            if ((def = NCONF_get_string(req_conf, dn_sect, buf)) == NULL) {
1201                ERR_clear_error();
1202                def = "";
1203            }
1204
1205            BIO_snprintf(buf, sizeof buf, "%s_value", v->name);
1206            if ((value = NCONF_get_string(req_conf, dn_sect, buf)) == NULL) {
1207                ERR_clear_error();
1208                value = NULL;
1209            }
1210
1211            BIO_snprintf(buf, sizeof buf, "%s_min", v->name);
1212            if (!NCONF_get_number(req_conf, dn_sect, buf, &n_min)) {
1213                ERR_clear_error();
1214                n_min = -1;
1215            }
1216
1217            BIO_snprintf(buf, sizeof buf, "%s_max", v->name);
1218            if (!NCONF_get_number(req_conf, dn_sect, buf, &n_max)) {
1219                ERR_clear_error();
1220                n_max = -1;
1221            }
1222
1223            if (!add_DN_object(subj, v->value, def, value, nid,
1224                               n_min, n_max, chtype, mval))
1225                return 0;
1226        }
1227        if (X509_NAME_entry_count(subj) == 0) {
1228            BIO_printf(bio_err,
1229                       "error, no objects specified in config file\n");
1230            return 0;
1231        }
1232
1233        if (attribs) {
1234            if ((attr_sk != NULL) && (sk_CONF_VALUE_num(attr_sk) > 0)
1235                && (!batch)) {
1236                BIO_printf(bio_err,
1237                           "\nPlease enter the following 'extra' attributes\n");
1238                BIO_printf(bio_err,
1239                           "to be sent with your certificate request\n");
1240            }
1241
1242            i = -1;
1243 start2:   for (;;) {
1244                i++;
1245                if ((attr_sk == NULL) || (sk_CONF_VALUE_num(attr_sk) <= i))
1246                    break;
1247
1248                v = sk_CONF_VALUE_value(attr_sk, i);
1249                type = v->name;
1250                if ((nid = OBJ_txt2nid(type)) == NID_undef)
1251                    goto start2;
1252
1253                if (BIO_snprintf(buf, sizeof buf, "%s_default", type)
1254                    >= (int)sizeof(buf)) {
1255                    BIO_printf(bio_err, "Name '%s' too long\n", v->name);
1256                    return 0;
1257                }
1258
1259                if ((def = NCONF_get_string(req_conf, attr_sect, buf))
1260                    == NULL) {
1261                    ERR_clear_error();
1262                    def = "";
1263                }
1264
1265                BIO_snprintf(buf, sizeof buf, "%s_value", type);
1266                if ((value = NCONF_get_string(req_conf, attr_sect, buf))
1267                    == NULL) {
1268                    ERR_clear_error();
1269                    value = NULL;
1270                }
1271
1272                BIO_snprintf(buf, sizeof buf, "%s_min", type);
1273                if (!NCONF_get_number(req_conf, attr_sect, buf, &n_min)) {
1274                    ERR_clear_error();
1275                    n_min = -1;
1276                }
1277
1278                BIO_snprintf(buf, sizeof buf, "%s_max", type);
1279                if (!NCONF_get_number(req_conf, attr_sect, buf, &n_max)) {
1280                    ERR_clear_error();
1281                    n_max = -1;
1282                }
1283
1284                if (!add_attribute_object(req,
1285                                          v->value, def, value, nid, n_min,
1286                                          n_max, chtype))
1287                    return 0;
1288            }
1289        }
1290    } else {
1291        BIO_printf(bio_err, "No template, please set one up.\n");
1292        return 0;
1293    }
1294
1295    return 1;
1296
1297}
1298
1299static int auto_info(X509_REQ *req, STACK_OF(CONF_VALUE) *dn_sk,
1300                     STACK_OF(CONF_VALUE) *attr_sk, int attribs,
1301                     unsigned long chtype)
1302{
1303    int i;
1304    char *p, *q;
1305    char *type;
1306    CONF_VALUE *v;
1307    X509_NAME *subj;
1308
1309    subj = X509_REQ_get_subject_name(req);
1310
1311    for (i = 0; i < sk_CONF_VALUE_num(dn_sk); i++) {
1312        int mval;
1313        v = sk_CONF_VALUE_value(dn_sk, i);
1314        p = q = NULL;
1315        type = v->name;
1316        /*
1317         * Skip past any leading X. X: X, etc to allow for multiple instances
1318         */
1319        for (p = v->name; *p; p++)
1320#ifndef CHARSET_EBCDIC
1321            if ((*p == ':') || (*p == ',') || (*p == '.')) {
1322#else
1323            if ((*p == os_toascii[':']) || (*p == os_toascii[','])
1324                || (*p == os_toascii['.'])) {
1325#endif
1326                p++;
1327                if (*p)
1328                    type = p;
1329                break;
1330            }
1331#ifndef CHARSET_EBCDIC
1332        if (*type == '+') {
1333#else
1334        if (*type == os_toascii['+']) {
1335#endif
1336            type++;
1337            mval = -1;
1338        } else
1339            mval = 0;
1340        if (!X509_NAME_add_entry_by_txt(subj, type, chtype,
1341                                        (unsigned char *)v->value, -1, -1,
1342                                        mval))
1343            return 0;
1344
1345    }
1346
1347    if (!X509_NAME_entry_count(subj)) {
1348        BIO_printf(bio_err, "error, no objects specified in config file\n");
1349        return 0;
1350    }
1351    if (attribs) {
1352        for (i = 0; i < sk_CONF_VALUE_num(attr_sk); i++) {
1353            v = sk_CONF_VALUE_value(attr_sk, i);
1354            if (!X509_REQ_add1_attr_by_txt(req, v->name, chtype,
1355                                           (unsigned char *)v->value, -1))
1356                return 0;
1357        }
1358    }
1359    return 1;
1360}
1361
1362static int add_DN_object(X509_NAME *n, char *text, const char *def,
1363                         char *value, int nid, int n_min, int n_max,
1364                         unsigned long chtype, int mval)
1365{
1366    int i, ret = 0;
1367    MS_STATIC char buf[1024];
1368 start:
1369    if (!batch)
1370        BIO_printf(bio_err, "%s [%s]:", text, def);
1371    (void)BIO_flush(bio_err);
1372    if (value != NULL) {
1373        BUF_strlcpy(buf, value, sizeof buf);
1374        BUF_strlcat(buf, "\n", sizeof buf);
1375        BIO_printf(bio_err, "%s\n", value);
1376    } else {
1377        buf[0] = '\0';
1378        if (!batch) {
1379            if (!fgets(buf, sizeof buf, stdin))
1380                return 0;
1381        } else {
1382            buf[0] = '\n';
1383            buf[1] = '\0';
1384        }
1385    }
1386
1387    if (buf[0] == '\0')
1388        return (0);
1389    else if (buf[0] == '\n') {
1390        if ((def == NULL) || (def[0] == '\0'))
1391            return (1);
1392        BUF_strlcpy(buf, def, sizeof buf);
1393        BUF_strlcat(buf, "\n", sizeof buf);
1394    } else if ((buf[0] == '.') && (buf[1] == '\n'))
1395        return (1);
1396
1397    i = strlen(buf);
1398    if (buf[i - 1] != '\n') {
1399        BIO_printf(bio_err, "weird input :-(\n");
1400        return (0);
1401    }
1402    buf[--i] = '\0';
1403#ifdef CHARSET_EBCDIC
1404    ebcdic2ascii(buf, buf, i);
1405#endif
1406    if (!req_check_len(i, n_min, n_max)) {
1407        if (batch || value)
1408            return 0;
1409        goto start;
1410    }
1411
1412    if (!X509_NAME_add_entry_by_NID(n, nid, chtype,
1413                                    (unsigned char *)buf, -1, -1, mval))
1414        goto err;
1415    ret = 1;
1416 err:
1417    return (ret);
1418}
1419
1420static int add_attribute_object(X509_REQ *req, char *text, const char *def,
1421                                char *value, int nid, int n_min,
1422                                int n_max, unsigned long chtype)
1423{
1424    int i;
1425    static char buf[1024];
1426
1427 start:
1428    if (!batch)
1429        BIO_printf(bio_err, "%s [%s]:", text, def);
1430    (void)BIO_flush(bio_err);
1431    if (value != NULL) {
1432        BUF_strlcpy(buf, value, sizeof buf);
1433        BUF_strlcat(buf, "\n", sizeof buf);
1434        BIO_printf(bio_err, "%s\n", value);
1435    } else {
1436        buf[0] = '\0';
1437        if (!batch) {
1438            if (!fgets(buf, sizeof buf, stdin))
1439                return 0;
1440        } else {
1441            buf[0] = '\n';
1442            buf[1] = '\0';
1443        }
1444    }
1445
1446    if (buf[0] == '\0')
1447        return (0);
1448    else if (buf[0] == '\n') {
1449        if ((def == NULL) || (def[0] == '\0'))
1450            return (1);
1451        BUF_strlcpy(buf, def, sizeof buf);
1452        BUF_strlcat(buf, "\n", sizeof buf);
1453    } else if ((buf[0] == '.') && (buf[1] == '\n'))
1454        return (1);
1455
1456    i = strlen(buf);
1457    if (buf[i - 1] != '\n') {
1458        BIO_printf(bio_err, "weird input :-(\n");
1459        return (0);
1460    }
1461    buf[--i] = '\0';
1462#ifdef CHARSET_EBCDIC
1463    ebcdic2ascii(buf, buf, i);
1464#endif
1465    if (!req_check_len(i, n_min, n_max)) {
1466        if (batch || value)
1467            return 0;
1468        goto start;
1469    }
1470
1471    if (!X509_REQ_add1_attr_by_NID(req, nid, chtype,
1472                                   (unsigned char *)buf, -1)) {
1473        BIO_printf(bio_err, "Error adding attribute\n");
1474        ERR_print_errors(bio_err);
1475        goto err;
1476    }
1477
1478    return (1);
1479 err:
1480    return (0);
1481}
1482
1483static int req_check_len(int len, int n_min, int n_max)
1484{
1485    if ((n_min > 0) && (len < n_min)) {
1486        BIO_printf(bio_err,
1487                   "string is too short, it needs to be at least %d bytes long\n",
1488                   n_min);
1489        return (0);
1490    }
1491    if ((n_max >= 0) && (len > n_max)) {
1492        BIO_printf(bio_err,
1493                   "string is too long, it needs to be less than  %d bytes long\n",
1494                   n_max);
1495        return (0);
1496    }
1497    return (1);
1498}
1499
1500/* Check if the end of a string matches 'end' */
1501static int check_end(const char *str, const char *end)
1502{
1503    int elen, slen;
1504    const char *tmp;
1505    elen = strlen(end);
1506    slen = strlen(str);
1507    if (elen > slen)
1508        return 1;
1509    tmp = str + slen - elen;
1510    return strcmp(tmp, end);
1511}
1512
1513static EVP_PKEY_CTX *set_keygen_ctx(BIO *err, const char *gstr,
1514                                    int *pkey_type, long *pkeylen,
1515                                    char **palgnam, ENGINE *keygen_engine)
1516{
1517    EVP_PKEY_CTX *gctx = NULL;
1518    EVP_PKEY *param = NULL;
1519    long keylen = -1;
1520    BIO *pbio = NULL;
1521    const char *paramfile = NULL;
1522
1523    if (gstr == NULL) {
1524        *pkey_type = EVP_PKEY_RSA;
1525        keylen = *pkeylen;
1526    } else if (gstr[0] >= '0' && gstr[0] <= '9') {
1527        *pkey_type = EVP_PKEY_RSA;
1528        keylen = atol(gstr);
1529        *pkeylen = keylen;
1530    } else if (!strncmp(gstr, "param:", 6))
1531        paramfile = gstr + 6;
1532    else {
1533        const char *p = strchr(gstr, ':');
1534        int len;
1535        ENGINE *tmpeng;
1536        const EVP_PKEY_ASN1_METHOD *ameth;
1537
1538        if (p)
1539            len = p - gstr;
1540        else
1541            len = strlen(gstr);
1542        /*
1543         * The lookup of a the string will cover all engines so keep a note
1544         * of the implementation.
1545         */
1546
1547        ameth = EVP_PKEY_asn1_find_str(&tmpeng, gstr, len);
1548
1549        if (!ameth) {
1550            BIO_printf(err, "Unknown algorithm %.*s\n", len, gstr);
1551            return NULL;
1552        }
1553
1554        EVP_PKEY_asn1_get0_info(NULL, pkey_type, NULL, NULL, NULL, ameth);
1555#ifndef OPENSSL_NO_ENGINE
1556        if (tmpeng)
1557            ENGINE_finish(tmpeng);
1558#endif
1559        if (*pkey_type == EVP_PKEY_RSA) {
1560            if (p) {
1561                keylen = atol(p + 1);
1562                *pkeylen = keylen;
1563            } else
1564                keylen = *pkeylen;
1565        } else if (p)
1566            paramfile = p + 1;
1567    }
1568
1569    if (paramfile) {
1570        pbio = BIO_new_file(paramfile, "r");
1571        if (!pbio) {
1572            BIO_printf(err, "Can't open parameter file %s\n", paramfile);
1573            return NULL;
1574        }
1575        param = PEM_read_bio_Parameters(pbio, NULL);
1576
1577        if (!param) {
1578            X509 *x;
1579            (void)BIO_reset(pbio);
1580            x = PEM_read_bio_X509(pbio, NULL, NULL, NULL);
1581            if (x) {
1582                param = X509_get_pubkey(x);
1583                X509_free(x);
1584            }
1585        }
1586
1587        BIO_free(pbio);
1588
1589        if (!param) {
1590            BIO_printf(err, "Error reading parameter file %s\n", paramfile);
1591            return NULL;
1592        }
1593        if (*pkey_type == -1)
1594            *pkey_type = EVP_PKEY_id(param);
1595        else if (*pkey_type != EVP_PKEY_base_id(param)) {
1596            BIO_printf(err, "Key Type does not match parameters\n");
1597            EVP_PKEY_free(param);
1598            return NULL;
1599        }
1600    }
1601
1602    if (palgnam) {
1603        const EVP_PKEY_ASN1_METHOD *ameth;
1604        ENGINE *tmpeng;
1605        const char *anam;
1606        ameth = EVP_PKEY_asn1_find(&tmpeng, *pkey_type);
1607        if (!ameth) {
1608            BIO_puts(err, "Internal error: can't find key algorithm\n");
1609            return NULL;
1610        }
1611        EVP_PKEY_asn1_get0_info(NULL, NULL, NULL, NULL, &anam, ameth);
1612        *palgnam = BUF_strdup(anam);
1613#ifndef OPENSSL_NO_ENGINE
1614        if (tmpeng)
1615            ENGINE_finish(tmpeng);
1616#endif
1617    }
1618
1619    if (param) {
1620        gctx = EVP_PKEY_CTX_new(param, keygen_engine);
1621        *pkeylen = EVP_PKEY_bits(param);
1622        EVP_PKEY_free(param);
1623    } else
1624        gctx = EVP_PKEY_CTX_new_id(*pkey_type, keygen_engine);
1625
1626    if (!gctx) {
1627        BIO_puts(err, "Error allocating keygen context\n");
1628        ERR_print_errors(err);
1629        return NULL;
1630    }
1631
1632    if (EVP_PKEY_keygen_init(gctx) <= 0) {
1633        BIO_puts(err, "Error initializing keygen context\n");
1634        ERR_print_errors(err);
1635        return NULL;
1636    }
1637#ifndef OPENSSL_NO_RSA
1638    if ((*pkey_type == EVP_PKEY_RSA) && (keylen != -1)) {
1639        if (EVP_PKEY_CTX_set_rsa_keygen_bits(gctx, keylen) <= 0) {
1640            BIO_puts(err, "Error setting RSA keysize\n");
1641            ERR_print_errors(err);
1642            EVP_PKEY_CTX_free(gctx);
1643            return NULL;
1644        }
1645    }
1646#endif
1647
1648    return gctx;
1649}
1650
1651static int genpkey_cb(EVP_PKEY_CTX *ctx)
1652{
1653    char c = '*';
1654    BIO *b = EVP_PKEY_CTX_get_app_data(ctx);
1655    int p;
1656    p = EVP_PKEY_CTX_get_keygen_info(ctx, 0);
1657    if (p == 0)
1658        c = '.';
1659    if (p == 1)
1660        c = '+';
1661    if (p == 2)
1662        c = '*';
1663    if (p == 3)
1664        c = '\n';
1665    BIO_write(b, &c, 1);
1666    (void)BIO_flush(b);
1667#ifdef LINT
1668    p = n;
1669#endif
1670    return 1;
1671}
1672
1673static int do_sign_init(BIO *err, EVP_MD_CTX *ctx, EVP_PKEY *pkey,
1674                        const EVP_MD *md, STACK_OF(OPENSSL_STRING) *sigopts)
1675{
1676    EVP_PKEY_CTX *pkctx = NULL;
1677    int i;
1678    EVP_MD_CTX_init(ctx);
1679    if (!EVP_DigestSignInit(ctx, &pkctx, md, NULL, pkey))
1680        return 0;
1681    for (i = 0; i < sk_OPENSSL_STRING_num(sigopts); i++) {
1682        char *sigopt = sk_OPENSSL_STRING_value(sigopts, i);
1683        if (pkey_ctrl_string(pkctx, sigopt) <= 0) {
1684            BIO_printf(err, "parameter error \"%s\"\n", sigopt);
1685            ERR_print_errors(bio_err);
1686            return 0;
1687        }
1688    }
1689    return 1;
1690}
1691
1692int do_X509_sign(BIO *err, X509 *x, EVP_PKEY *pkey, const EVP_MD *md,
1693                 STACK_OF(OPENSSL_STRING) *sigopts)
1694{
1695    int rv;
1696    EVP_MD_CTX mctx;
1697    EVP_MD_CTX_init(&mctx);
1698    rv = do_sign_init(err, &mctx, pkey, md, sigopts);
1699    if (rv > 0)
1700        rv = X509_sign_ctx(x, &mctx);
1701    EVP_MD_CTX_cleanup(&mctx);
1702    return rv > 0 ? 1 : 0;
1703}
1704
1705int do_X509_REQ_sign(BIO *err, X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md,
1706                     STACK_OF(OPENSSL_STRING) *sigopts)
1707{
1708    int rv;
1709    EVP_MD_CTX mctx;
1710    EVP_MD_CTX_init(&mctx);
1711    rv = do_sign_init(err, &mctx, pkey, md, sigopts);
1712    if (rv > 0)
1713        rv = X509_REQ_sign_ctx(x, &mctx);
1714    EVP_MD_CTX_cleanup(&mctx);
1715    return rv > 0 ? 1 : 0;
1716}
1717
1718int do_X509_CRL_sign(BIO *err, X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md,
1719                     STACK_OF(OPENSSL_STRING) *sigopts)
1720{
1721    int rv;
1722    EVP_MD_CTX mctx;
1723    EVP_MD_CTX_init(&mctx);
1724    rv = do_sign_init(err, &mctx, pkey, md, sigopts);
1725    if (rv > 0)
1726        rv = X509_CRL_sign_ctx(x, &mctx);
1727    EVP_MD_CTX_cleanup(&mctx);
1728    return rv > 0 ? 1 : 0;
1729}
1730