req.c revision 296465
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      512
105#define MIN_KEY_LENGTH          384
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);
148#ifndef OPENSSL_NO_RSA
149static int MS_CALLBACK req_cb(int p, int n, BN_GENCB *cb);
150#endif
151static int req_check_len(int len, int n_min, int n_max);
152static int check_end(const char *str, const char *end);
153#ifndef MONOLITH
154static char *default_config_file = NULL;
155#endif
156static CONF *req_conf = NULL;
157static int batch = 0;
158
159#define TYPE_RSA        1
160#define TYPE_DSA        2
161#define TYPE_DH         3
162#define TYPE_EC         4
163
164int MAIN(int, char **);
165
166int MAIN(int argc, char **argv)
167{
168    ENGINE *e = NULL;
169#ifndef OPENSSL_NO_DSA
170    DSA *dsa_params = NULL;
171#endif
172#ifndef OPENSSL_NO_ECDSA
173    EC_KEY *ec_params = NULL;
174#endif
175    unsigned long nmflag = 0, reqflag = 0;
176    int ex = 1, x509 = 0, days = 30;
177    X509 *x509ss = NULL;
178    X509_REQ *req = NULL;
179    EVP_PKEY *pkey = NULL;
180    int i = 0, badops = 0, newreq = 0, verbose = 0, pkey_type = TYPE_RSA;
181    long newkey = -1;
182    BIO *in = NULL, *out = NULL;
183    int informat, outformat, verify = 0, noout = 0, text = 0, keyform =
184        FORMAT_PEM;
185    int nodes = 0, kludge = 0, newhdr = 0, subject = 0, pubkey = 0;
186    char *infile, *outfile, *prog, *keyfile = NULL, *template =
187        NULL, *keyout = NULL;
188#ifndef OPENSSL_NO_ENGINE
189    char *engine = NULL;
190#endif
191    char *extensions = NULL;
192    char *req_exts = NULL;
193    const EVP_CIPHER *cipher = NULL;
194    ASN1_INTEGER *serial = NULL;
195    int modulus = 0;
196    char *inrand = NULL;
197    char *passargin = NULL, *passargout = NULL;
198    char *passin = NULL, *passout = NULL;
199    char *p;
200    char *subj = NULL;
201    int multirdn = 0;
202    const EVP_MD *md_alg = NULL, *digest = EVP_sha1();
203    unsigned long chtype = MBSTRING_ASC;
204#ifndef MONOLITH
205    char *to_free;
206    long errline;
207#endif
208
209    req_conf = NULL;
210#ifndef OPENSSL_NO_DES
211    cipher = EVP_des_ede3_cbc();
212#endif
213    apps_startup();
214
215    if (bio_err == NULL)
216        if ((bio_err = BIO_new(BIO_s_file())) != NULL)
217            BIO_set_fp(bio_err, stderr, BIO_NOCLOSE | BIO_FP_TEXT);
218
219    infile = NULL;
220    outfile = NULL;
221    informat = FORMAT_PEM;
222    outformat = FORMAT_PEM;
223
224    prog = argv[0];
225    argc--;
226    argv++;
227    while (argc >= 1) {
228        if (strcmp(*argv, "-inform") == 0) {
229            if (--argc < 1)
230                goto bad;
231            informat = str2fmt(*(++argv));
232        } else if (strcmp(*argv, "-outform") == 0) {
233            if (--argc < 1)
234                goto bad;
235            outformat = str2fmt(*(++argv));
236        }
237#ifndef OPENSSL_NO_ENGINE
238        else if (strcmp(*argv, "-engine") == 0) {
239            if (--argc < 1)
240                goto bad;
241            engine = *(++argv);
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            int is_numeric;
286
287            if (--argc < 1)
288                goto bad;
289            p = *(++argv);
290            is_numeric = p[0] >= '0' && p[0] <= '9';
291            if (strncmp("rsa:", p, 4) == 0 || is_numeric) {
292                pkey_type = TYPE_RSA;
293                if (!is_numeric)
294                    p += 4;
295                newkey = atoi(p);
296            } else
297#ifndef OPENSSL_NO_DSA
298            if (strncmp("dsa:", p, 4) == 0) {
299                X509 *xtmp = NULL;
300                EVP_PKEY *dtmp;
301
302                pkey_type = TYPE_DSA;
303                p += 4;
304                if ((in = BIO_new_file(p, "r")) == NULL) {
305                    perror(p);
306                    goto end;
307                }
308                if ((dsa_params =
309                     PEM_read_bio_DSAparams(in, NULL, NULL, NULL)) == NULL) {
310                    ERR_clear_error();
311                    (void)BIO_reset(in);
312                    if ((xtmp =
313                         PEM_read_bio_X509(in, NULL, NULL, NULL)) == NULL) {
314                        BIO_printf(bio_err,
315                                   "unable to load DSA parameters from file\n");
316                        goto end;
317                    }
318
319                    if ((dtmp = X509_get_pubkey(xtmp)) == NULL)
320                        goto end;
321                    if (dtmp->type == EVP_PKEY_DSA)
322                        dsa_params = DSAparams_dup(dtmp->pkey.dsa);
323                    EVP_PKEY_free(dtmp);
324                    X509_free(xtmp);
325                    if (dsa_params == NULL) {
326                        BIO_printf(bio_err,
327                                   "Certificate does not contain DSA parameters\n");
328                        goto end;
329                    }
330                }
331                BIO_free(in);
332                in = NULL;
333                newkey = BN_num_bits(dsa_params->p);
334            } else
335#endif
336#ifndef OPENSSL_NO_ECDSA
337            if (strncmp("ec:", p, 3) == 0) {
338                X509 *xtmp = NULL;
339                EVP_PKEY *dtmp;
340                EC_GROUP *group;
341
342                pkey_type = TYPE_EC;
343                p += 3;
344                if ((in = BIO_new_file(p, "r")) == NULL) {
345                    perror(p);
346                    goto end;
347                }
348                if ((ec_params = EC_KEY_new()) == NULL)
349                    goto end;
350                group = PEM_read_bio_ECPKParameters(in, NULL, NULL, NULL);
351                if (group == NULL) {
352                    EC_KEY_free(ec_params);
353                    ERR_clear_error();
354                    (void)BIO_reset(in);
355                    if ((xtmp =
356                         PEM_read_bio_X509(in, NULL, NULL, NULL)) == NULL) {
357                        BIO_printf(bio_err,
358                                   "unable to load EC parameters from file\n");
359                        goto end;
360                    }
361
362                    if ((dtmp = X509_get_pubkey(xtmp)) == NULL)
363                        goto end;
364                    if (dtmp->type == EVP_PKEY_EC)
365                        ec_params = EC_KEY_dup(dtmp->pkey.ec);
366                    EVP_PKEY_free(dtmp);
367                    X509_free(xtmp);
368                    if (ec_params == NULL) {
369                        BIO_printf(bio_err,
370                                   "Certificate does not contain EC parameters\n");
371                        goto end;
372                    }
373                } else {
374                    if (EC_KEY_set_group(ec_params, group) == 0)
375                        goto end;
376                    EC_GROUP_free(group);
377                }
378
379                BIO_free(in);
380                in = NULL;
381                newkey = EC_GROUP_get_degree(EC_KEY_get0_group(ec_params));
382            } else
383#endif
384#ifndef OPENSSL_NO_DH
385            if (strncmp("dh:", p, 4) == 0) {
386                pkey_type = TYPE_DH;
387                p += 3;
388            } else
389#endif
390            {
391                goto bad;
392            }
393
394            newreq = 1;
395        } else if (strcmp(*argv, "-batch") == 0)
396            batch = 1;
397        else if (strcmp(*argv, "-newhdr") == 0)
398            newhdr = 1;
399        else if (strcmp(*argv, "-modulus") == 0)
400            modulus = 1;
401        else if (strcmp(*argv, "-verify") == 0)
402            verify = 1;
403        else if (strcmp(*argv, "-nodes") == 0)
404            nodes = 1;
405        else if (strcmp(*argv, "-noout") == 0)
406            noout = 1;
407        else if (strcmp(*argv, "-verbose") == 0)
408            verbose = 1;
409        else if (strcmp(*argv, "-utf8") == 0)
410            chtype = MBSTRING_UTF8;
411        else if (strcmp(*argv, "-nameopt") == 0) {
412            if (--argc < 1)
413                goto bad;
414            if (!set_name_ex(&nmflag, *(++argv)))
415                goto bad;
416        } else if (strcmp(*argv, "-reqopt") == 0) {
417            if (--argc < 1)
418                goto bad;
419            if (!set_cert_ex(&reqflag, *(++argv)))
420                goto bad;
421        } else if (strcmp(*argv, "-subject") == 0)
422            subject = 1;
423        else if (strcmp(*argv, "-text") == 0)
424            text = 1;
425        else if (strcmp(*argv, "-x509") == 0)
426            x509 = 1;
427        else if (strcmp(*argv, "-asn1-kludge") == 0)
428            kludge = 1;
429        else if (strcmp(*argv, "-no-asn1-kludge") == 0)
430            kludge = 0;
431        else if (strcmp(*argv, "-subj") == 0) {
432            if (--argc < 1)
433                goto bad;
434            subj = *(++argv);
435        } else if (strcmp(*argv, "-multivalue-rdn") == 0)
436            multirdn = 1;
437        else if (strcmp(*argv, "-days") == 0) {
438            if (--argc < 1)
439                goto bad;
440            days = atoi(*(++argv));
441            if (days == 0)
442                days = 30;
443        } else if (strcmp(*argv, "-set_serial") == 0) {
444            if (--argc < 1)
445                goto bad;
446            serial = s2i_ASN1_INTEGER(NULL, *(++argv));
447            if (!serial)
448                goto bad;
449        } else if ((md_alg = EVP_get_digestbyname(&((*argv)[1]))) != NULL) {
450            /* ok */
451            digest = md_alg;
452        } else if (strcmp(*argv, "-extensions") == 0) {
453            if (--argc < 1)
454                goto bad;
455            extensions = *(++argv);
456        } else if (strcmp(*argv, "-reqexts") == 0) {
457            if (--argc < 1)
458                goto bad;
459            req_exts = *(++argv);
460        } else {
461            BIO_printf(bio_err, "unknown option %s\n", *argv);
462            badops = 1;
463            break;
464        }
465        argc--;
466        argv++;
467    }
468
469    if (badops) {
470 bad:
471        BIO_printf(bio_err, "%s [options] <infile >outfile\n", prog);
472        BIO_printf(bio_err, "where options  are\n");
473        BIO_printf(bio_err, " -inform arg    input format - DER or PEM\n");
474        BIO_printf(bio_err, " -outform arg   output format - DER or PEM\n");
475        BIO_printf(bio_err, " -in arg        input file\n");
476        BIO_printf(bio_err, " -out arg       output file\n");
477        BIO_printf(bio_err, " -text          text form of request\n");
478        BIO_printf(bio_err, " -pubkey        output public key\n");
479        BIO_printf(bio_err, " -noout         do not output REQ\n");
480        BIO_printf(bio_err, " -verify        verify signature on REQ\n");
481        BIO_printf(bio_err, " -modulus       RSA modulus\n");
482        BIO_printf(bio_err, " -nodes         don't encrypt the output key\n");
483#ifndef OPENSSL_NO_ENGINE
484        BIO_printf(bio_err,
485                   " -engine e      use engine e, possibly a hardware device\n");
486#endif
487        BIO_printf(bio_err, " -subject       output the request's subject\n");
488        BIO_printf(bio_err, " -passin        private key password source\n");
489        BIO_printf(bio_err,
490                   " -key file      use the private key contained in file\n");
491        BIO_printf(bio_err, " -keyform arg   key file format\n");
492        BIO_printf(bio_err, " -keyout arg    file to send the key to\n");
493        BIO_printf(bio_err, " -rand file%cfile%c...\n", LIST_SEPARATOR_CHAR,
494                   LIST_SEPARATOR_CHAR);
495        BIO_printf(bio_err,
496                   "                load the file (or the files in the directory) into\n");
497        BIO_printf(bio_err, "                the random number generator\n");
498        BIO_printf(bio_err,
499                   " -newkey rsa:bits generate a new RSA key of 'bits' in size\n");
500        BIO_printf(bio_err,
501                   " -newkey dsa:file generate a new DSA key, parameters taken from CA in 'file'\n");
502#ifndef OPENSSL_NO_ECDSA
503        BIO_printf(bio_err,
504                   " -newkey ec:file generate a new EC key, parameters taken from CA in 'file'\n");
505#endif
506        BIO_printf(bio_err,
507                   " -[digest]      Digest to sign with (md5, sha1, md2, mdc2, md4)\n");
508        BIO_printf(bio_err, " -config file   request template file.\n");
509        BIO_printf(bio_err,
510                   " -subj arg      set or modify request subject\n");
511        BIO_printf(bio_err,
512                   " -multivalue-rdn enable support for multivalued RDNs\n");
513        BIO_printf(bio_err, " -new           new request.\n");
514        BIO_printf(bio_err,
515                   " -batch         do not ask anything during request generation\n");
516        BIO_printf(bio_err,
517                   " -x509          output a x509 structure instead of a cert. req.\n");
518        BIO_printf(bio_err,
519                   " -days          number of days a certificate generated by -x509 is valid for.\n");
520        BIO_printf(bio_err,
521                   " -set_serial    serial number to use for a certificate generated by -x509.\n");
522        BIO_printf(bio_err,
523                   " -newhdr        output \"NEW\" in the header lines\n");
524        BIO_printf(bio_err,
525                   " -asn1-kludge   Output the 'request' in a format that is wrong but some CA's\n");
526        BIO_printf(bio_err,
527                   "                have been reported as requiring\n");
528        BIO_printf(bio_err,
529                   " -extensions .. specify certificate extension section (override value in config file)\n");
530        BIO_printf(bio_err,
531                   " -reqexts ..    specify request extension section (override value in config file)\n");
532        BIO_printf(bio_err,
533                   " -utf8          input characters are UTF8 (default ASCII)\n");
534        BIO_printf(bio_err,
535                   " -nameopt arg    - various certificate name options\n");
536        BIO_printf(bio_err,
537                   " -reqopt arg    - various request text options\n\n");
538        goto end;
539    }
540
541    ERR_load_crypto_strings();
542    if (!app_passwd(bio_err, passargin, passargout, &passin, &passout)) {
543        BIO_printf(bio_err, "Error getting passwords\n");
544        goto end;
545    }
546#ifndef MONOLITH                /* else this has happened in openssl.c
547                                 * (global `config') */
548    /* Lets load up our environment a little */
549    p = getenv("OPENSSL_CONF");
550    if (p == NULL)
551        p = getenv("SSLEAY_CONF");
552    if (p == NULL)
553        p = to_free = make_config_name();
554    default_config_file = p;
555    config = NCONF_new(NULL);
556    i = NCONF_load(config, p, &errline);
557#endif
558
559    if (template != NULL) {
560        long errline = -1;
561
562        if (verbose)
563            BIO_printf(bio_err, "Using configuration from %s\n", template);
564        req_conf = NCONF_new(NULL);
565        i = NCONF_load(req_conf, template, &errline);
566        if (i == 0) {
567            BIO_printf(bio_err, "error on line %ld of %s\n", errline,
568                       template);
569            goto end;
570        }
571    } else {
572        req_conf = config;
573
574        if (req_conf == NULL) {
575            BIO_printf(bio_err, "Unable to load config info from %s\n",
576                       default_config_file);
577            if (newreq)
578                goto end;
579        } else if (verbose)
580            BIO_printf(bio_err, "Using configuration from %s\n",
581                       default_config_file);
582    }
583
584    if (req_conf != NULL) {
585        if (!load_config(bio_err, req_conf))
586            goto end;
587        p = NCONF_get_string(req_conf, NULL, "oid_file");
588        if (p == NULL)
589            ERR_clear_error();
590        if (p != NULL) {
591            BIO *oid_bio;
592
593            oid_bio = BIO_new_file(p, "r");
594            if (oid_bio == NULL) {
595                /*-
596                BIO_printf(bio_err,"problems opening %s for extra oid's\n",p);
597                ERR_print_errors(bio_err);
598                */
599            } else {
600                OBJ_create_objects(oid_bio);
601                BIO_free(oid_bio);
602            }
603        }
604    }
605    if (!add_oid_section(bio_err, req_conf))
606        goto end;
607
608    if (md_alg == NULL) {
609        p = NCONF_get_string(req_conf, SECTION, "default_md");
610        if (p == NULL)
611            ERR_clear_error();
612        if (p != NULL) {
613            if ((md_alg = EVP_get_digestbyname(p)) != NULL)
614                digest = md_alg;
615        }
616    }
617
618    if (!extensions) {
619        extensions = NCONF_get_string(req_conf, SECTION, V3_EXTENSIONS);
620        if (!extensions)
621            ERR_clear_error();
622    }
623    if (extensions) {
624        /* Check syntax of file */
625        X509V3_CTX ctx;
626        X509V3_set_ctx_test(&ctx);
627        X509V3_set_nconf(&ctx, req_conf);
628        if (!X509V3_EXT_add_nconf(req_conf, &ctx, extensions, NULL)) {
629            BIO_printf(bio_err,
630                       "Error Loading extension section %s\n", extensions);
631            goto end;
632        }
633    }
634
635    if (!passin) {
636        passin = NCONF_get_string(req_conf, SECTION, "input_password");
637        if (!passin)
638            ERR_clear_error();
639    }
640
641    if (!passout) {
642        passout = NCONF_get_string(req_conf, SECTION, "output_password");
643        if (!passout)
644            ERR_clear_error();
645    }
646
647    p = NCONF_get_string(req_conf, SECTION, STRING_MASK);
648    if (!p)
649        ERR_clear_error();
650
651    if (p && !ASN1_STRING_set_default_mask_asc(p)) {
652        BIO_printf(bio_err, "Invalid global string mask setting %s\n", p);
653        goto end;
654    }
655
656    if (chtype != MBSTRING_UTF8) {
657        p = NCONF_get_string(req_conf, SECTION, UTF8_IN);
658        if (!p)
659            ERR_clear_error();
660        else if (!strcmp(p, "yes"))
661            chtype = MBSTRING_UTF8;
662    }
663
664    if (!req_exts) {
665        req_exts = NCONF_get_string(req_conf, SECTION, REQ_EXTENSIONS);
666        if (!req_exts)
667            ERR_clear_error();
668    }
669    if (req_exts) {
670        /* Check syntax of file */
671        X509V3_CTX ctx;
672        X509V3_set_ctx_test(&ctx);
673        X509V3_set_nconf(&ctx, req_conf);
674        if (!X509V3_EXT_add_nconf(req_conf, &ctx, req_exts, NULL)) {
675            BIO_printf(bio_err,
676                       "Error Loading request extension section %s\n",
677                       req_exts);
678            goto end;
679        }
680    }
681
682    in = BIO_new(BIO_s_file());
683    out = BIO_new(BIO_s_file());
684    if ((in == NULL) || (out == NULL))
685        goto end;
686
687#ifndef OPENSSL_NO_ENGINE
688    e = setup_engine(bio_err, engine, 0);
689#endif
690
691    if (keyfile != NULL) {
692        pkey = load_key(bio_err, keyfile, keyform, 0, passin, e,
693                        "Private Key");
694        if (!pkey) {
695            /*
696             * load_key() has already printed an appropriate message
697             */
698            goto end;
699        } else {
700            char *randfile = NCONF_get_string(req_conf, SECTION, "RANDFILE");
701            if (randfile == NULL)
702                ERR_clear_error();
703            app_RAND_load_file(randfile, bio_err, 0);
704        }
705    }
706
707    if (newreq && (pkey == NULL)) {
708#ifndef OPENSSL_NO_RSA
709        BN_GENCB cb;
710#endif
711        char *randfile = NCONF_get_string(req_conf, SECTION, "RANDFILE");
712        if (randfile == NULL)
713            ERR_clear_error();
714        app_RAND_load_file(randfile, bio_err, 0);
715        if (inrand)
716            app_RAND_load_files(inrand);
717
718        if (newkey <= 0) {
719            if (!NCONF_get_number(req_conf, SECTION, BITS, &newkey))
720                newkey = DEFAULT_KEY_LENGTH;
721        }
722
723        if (newkey < MIN_KEY_LENGTH
724            && (pkey_type == TYPE_RSA || pkey_type == TYPE_DSA)) {
725            BIO_printf(bio_err, "private key length is too short,\n");
726            BIO_printf(bio_err, "it needs to be at least %d bits, not %ld\n",
727                       MIN_KEY_LENGTH, newkey);
728            goto end;
729        }
730        BIO_printf(bio_err, "Generating a %ld bit %s private key\n",
731                   newkey, (pkey_type == TYPE_RSA) ? "RSA" :
732                   (pkey_type == TYPE_DSA) ? "DSA" : "EC");
733
734        if ((pkey = EVP_PKEY_new()) == NULL)
735            goto end;
736
737#ifndef OPENSSL_NO_RSA
738        BN_GENCB_set(&cb, req_cb, bio_err);
739        if (pkey_type == TYPE_RSA) {
740            RSA *rsa = RSA_new();
741            BIGNUM *bn = BN_new();
742            if (!bn || !rsa || !BN_set_word(bn, 0x10001) ||
743                !RSA_generate_key_ex(rsa, newkey, bn, &cb) ||
744                !EVP_PKEY_assign_RSA(pkey, rsa)) {
745                if (bn)
746                    BN_free(bn);
747                if (rsa)
748                    RSA_free(rsa);
749                goto end;
750            }
751            BN_free(bn);
752        } else
753#endif
754#ifndef OPENSSL_NO_DSA
755        if (pkey_type == TYPE_DSA) {
756            if (!DSA_generate_key(dsa_params))
757                goto end;
758            if (!EVP_PKEY_assign_DSA(pkey, dsa_params))
759                goto end;
760            dsa_params = NULL;
761        }
762#endif
763#ifndef OPENSSL_NO_ECDSA
764        if (pkey_type == TYPE_EC) {
765            if (!EC_KEY_generate_key(ec_params))
766                goto end;
767            if (!EVP_PKEY_assign_EC_KEY(pkey, ec_params))
768                goto end;
769            ec_params = NULL;
770        }
771#endif
772
773        app_RAND_write_file(randfile, bio_err);
774
775        if (pkey == NULL)
776            goto end;
777
778        if (keyout == NULL) {
779            keyout = NCONF_get_string(req_conf, SECTION, KEYFILE);
780            if (keyout == NULL)
781                ERR_clear_error();
782        }
783
784        if (keyout == NULL) {
785            BIO_printf(bio_err, "writing new private key to stdout\n");
786            BIO_set_fp(out, stdout, BIO_NOCLOSE);
787#ifdef OPENSSL_SYS_VMS
788            {
789                BIO *tmpbio = BIO_new(BIO_f_linebuffer());
790                out = BIO_push(tmpbio, out);
791            }
792#endif
793        } else {
794            BIO_printf(bio_err, "writing new private key to '%s'\n", keyout);
795            if (BIO_write_filename(out, keyout) <= 0) {
796                perror(keyout);
797                goto end;
798            }
799        }
800
801        p = NCONF_get_string(req_conf, SECTION, "encrypt_rsa_key");
802        if (p == NULL) {
803            ERR_clear_error();
804            p = NCONF_get_string(req_conf, SECTION, "encrypt_key");
805            if (p == NULL)
806                ERR_clear_error();
807        }
808        if ((p != NULL) && (strcmp(p, "no") == 0))
809            cipher = NULL;
810        if (nodes)
811            cipher = NULL;
812
813        i = 0;
814 loop:
815        if (!PEM_write_bio_PrivateKey(out, pkey, cipher,
816                                      NULL, 0, NULL, passout)) {
817            if ((ERR_GET_REASON(ERR_peek_error()) ==
818                 PEM_R_PROBLEMS_GETTING_PASSWORD) && (i < 3)) {
819                ERR_clear_error();
820                i++;
821                goto loop;
822            }
823            goto end;
824        }
825        BIO_printf(bio_err, "-----\n");
826    }
827
828    if (!newreq) {
829        /*
830         * Since we are using a pre-existing certificate request, the kludge
831         * 'format' info should not be changed.
832         */
833        kludge = -1;
834        if (infile == NULL)
835            BIO_set_fp(in, stdin, BIO_NOCLOSE);
836        else {
837            if (BIO_read_filename(in, infile) <= 0) {
838                perror(infile);
839                goto end;
840            }
841        }
842
843        if (informat == FORMAT_ASN1)
844            req = d2i_X509_REQ_bio(in, NULL);
845        else if (informat == FORMAT_PEM)
846            req = PEM_read_bio_X509_REQ(in, NULL, NULL, NULL);
847        else {
848            BIO_printf(bio_err,
849                       "bad input format specified for X509 request\n");
850            goto end;
851        }
852        if (req == NULL) {
853            BIO_printf(bio_err, "unable to load X509 request\n");
854            goto end;
855        }
856    }
857
858    if (newreq || x509) {
859        if (pkey == NULL) {
860            BIO_printf(bio_err, "you need to specify a private key\n");
861            goto end;
862        }
863#ifndef OPENSSL_NO_DSA
864        if (pkey->type == EVP_PKEY_DSA)
865            digest = EVP_dss1();
866#endif
867#ifndef OPENSSL_NO_ECDSA
868        if (pkey->type == EVP_PKEY_EC)
869            digest = EVP_ecdsa();
870#endif
871        if (req == NULL) {
872            req = X509_REQ_new();
873            if (req == NULL) {
874                goto end;
875            }
876
877            i = make_REQ(req, pkey, subj, multirdn, !x509, chtype);
878            subj = NULL;        /* done processing '-subj' option */
879            if ((kludge > 0)
880                && !sk_X509_ATTRIBUTE_num(req->req_info->attributes)) {
881                sk_X509_ATTRIBUTE_free(req->req_info->attributes);
882                req->req_info->attributes = NULL;
883            }
884            if (!i) {
885                BIO_printf(bio_err, "problems making Certificate Request\n");
886                goto end;
887            }
888        }
889        if (x509) {
890            EVP_PKEY *tmppkey;
891            X509V3_CTX ext_ctx;
892            if ((x509ss = X509_new()) == NULL)
893                goto end;
894
895            /* Set version to V3 */
896            if (extensions && !X509_set_version(x509ss, 2))
897                goto end;
898            if (serial) {
899                if (!X509_set_serialNumber(x509ss, serial))
900                    goto end;
901            } else {
902                if (!rand_serial(NULL, X509_get_serialNumber(x509ss)))
903                    goto end;
904            }
905
906            if (!X509_set_issuer_name(x509ss, X509_REQ_get_subject_name(req)))
907                goto end;
908            if (!X509_gmtime_adj(X509_get_notBefore(x509ss), 0))
909                goto end;
910            if (!X509_gmtime_adj
911                (X509_get_notAfter(x509ss), (long)60 * 60 * 24 * days))
912                goto end;
913            if (!X509_set_subject_name
914                (x509ss, X509_REQ_get_subject_name(req)))
915                goto end;
916            tmppkey = X509_REQ_get_pubkey(req);
917            if (!tmppkey || !X509_set_pubkey(x509ss, tmppkey))
918                goto end;
919            EVP_PKEY_free(tmppkey);
920
921            /* Set up V3 context struct */
922
923            X509V3_set_ctx(&ext_ctx, x509ss, x509ss, NULL, NULL, 0);
924            X509V3_set_nconf(&ext_ctx, req_conf);
925
926            /* Add extensions */
927            if (extensions && !X509V3_EXT_add_nconf(req_conf,
928                                                    &ext_ctx, extensions,
929                                                    x509ss)) {
930                BIO_printf(bio_err, "Error Loading extension section %s\n",
931                           extensions);
932                goto end;
933            }
934
935            if (!(i = X509_sign(x509ss, pkey, digest)))
936                goto end;
937        } else {
938            X509V3_CTX ext_ctx;
939
940            /* Set up V3 context struct */
941
942            X509V3_set_ctx(&ext_ctx, NULL, NULL, req, NULL, 0);
943            X509V3_set_nconf(&ext_ctx, req_conf);
944
945            /* Add extensions */
946            if (req_exts && !X509V3_EXT_REQ_add_nconf(req_conf,
947                                                      &ext_ctx, req_exts,
948                                                      req)) {
949                BIO_printf(bio_err, "Error Loading extension section %s\n",
950                           req_exts);
951                goto end;
952            }
953            if (!(i = X509_REQ_sign(req, pkey, digest)))
954                goto end;
955        }
956    }
957
958    if (subj && x509) {
959        BIO_printf(bio_err, "Cannot modifiy certificate subject\n");
960        goto end;
961    }
962
963    if (subj && !x509) {
964        if (verbose) {
965            BIO_printf(bio_err, "Modifying Request's Subject\n");
966            print_name(bio_err, "old subject=",
967                       X509_REQ_get_subject_name(req), nmflag);
968        }
969
970        if (build_subject(req, subj, chtype, multirdn) == 0) {
971            BIO_printf(bio_err, "ERROR: cannot modify subject\n");
972            ex = 1;
973            goto end;
974        }
975
976        req->req_info->enc.modified = 1;
977
978        if (verbose) {
979            print_name(bio_err, "new subject=",
980                       X509_REQ_get_subject_name(req), nmflag);
981        }
982    }
983
984    if (verify && !x509) {
985        int tmp = 0;
986
987        if (pkey == NULL) {
988            pkey = X509_REQ_get_pubkey(req);
989            tmp = 1;
990            if (pkey == NULL)
991                goto end;
992        }
993
994        i = X509_REQ_verify(req, pkey);
995        if (tmp) {
996            EVP_PKEY_free(pkey);
997            pkey = NULL;
998        }
999
1000        if (i < 0) {
1001            goto end;
1002        } else if (i == 0) {
1003            BIO_printf(bio_err, "verify failure\n");
1004            ERR_print_errors(bio_err);
1005        } else                  /* if (i > 0) */
1006            BIO_printf(bio_err, "verify OK\n");
1007    }
1008
1009    if (noout && !text && !modulus && !subject && !pubkey) {
1010        ex = 0;
1011        goto end;
1012    }
1013
1014    if (outfile == NULL) {
1015        BIO_set_fp(out, stdout, BIO_NOCLOSE);
1016#ifdef OPENSSL_SYS_VMS
1017        {
1018            BIO *tmpbio = BIO_new(BIO_f_linebuffer());
1019            out = BIO_push(tmpbio, out);
1020        }
1021#endif
1022    } else {
1023        if ((keyout != NULL) && (strcmp(outfile, keyout) == 0))
1024            i = (int)BIO_append_filename(out, outfile);
1025        else
1026            i = (int)BIO_write_filename(out, outfile);
1027        if (!i) {
1028            perror(outfile);
1029            goto end;
1030        }
1031    }
1032
1033    if (pubkey) {
1034        EVP_PKEY *tpubkey;
1035        tpubkey = X509_REQ_get_pubkey(req);
1036        if (tpubkey == NULL) {
1037            BIO_printf(bio_err, "Error getting public key\n");
1038            ERR_print_errors(bio_err);
1039            goto end;
1040        }
1041        PEM_write_bio_PUBKEY(out, tpubkey);
1042        EVP_PKEY_free(tpubkey);
1043    }
1044
1045    if (text) {
1046        if (x509)
1047            X509_print_ex(out, x509ss, nmflag, reqflag);
1048        else
1049            X509_REQ_print_ex(out, req, nmflag, reqflag);
1050    }
1051
1052    if (subject) {
1053        if (x509)
1054            print_name(out, "subject=", X509_get_subject_name(x509ss),
1055                       nmflag);
1056        else
1057            print_name(out, "subject=", X509_REQ_get_subject_name(req),
1058                       nmflag);
1059    }
1060
1061    if (modulus) {
1062        EVP_PKEY *tpubkey;
1063
1064        if (x509)
1065            tpubkey = X509_get_pubkey(x509ss);
1066        else
1067            tpubkey = X509_REQ_get_pubkey(req);
1068        if (tpubkey == NULL) {
1069            fprintf(stdout, "Modulus=unavailable\n");
1070            goto end;
1071        }
1072        fprintf(stdout, "Modulus=");
1073#ifndef OPENSSL_NO_RSA
1074        if (tpubkey->type == EVP_PKEY_RSA)
1075            BN_print(out, tpubkey->pkey.rsa->n);
1076        else
1077#endif
1078            fprintf(stdout, "Wrong Algorithm type");
1079        EVP_PKEY_free(tpubkey);
1080        fprintf(stdout, "\n");
1081    }
1082
1083    if (!noout && !x509) {
1084        if (outformat == FORMAT_ASN1)
1085            i = i2d_X509_REQ_bio(out, req);
1086        else if (outformat == FORMAT_PEM) {
1087            if (newhdr)
1088                i = PEM_write_bio_X509_REQ_NEW(out, req);
1089            else
1090                i = PEM_write_bio_X509_REQ(out, req);
1091        } else {
1092            BIO_printf(bio_err, "bad output format specified for outfile\n");
1093            goto end;
1094        }
1095        if (!i) {
1096            BIO_printf(bio_err, "unable to write X509 request\n");
1097            goto end;
1098        }
1099    }
1100    if (!noout && x509 && (x509ss != NULL)) {
1101        if (outformat == FORMAT_ASN1)
1102            i = i2d_X509_bio(out, x509ss);
1103        else if (outformat == FORMAT_PEM)
1104            i = PEM_write_bio_X509(out, x509ss);
1105        else {
1106            BIO_printf(bio_err, "bad output format specified for outfile\n");
1107            goto end;
1108        }
1109        if (!i) {
1110            BIO_printf(bio_err, "unable to write X509 certificate\n");
1111            goto end;
1112        }
1113    }
1114    ex = 0;
1115 end:
1116#ifndef MONOLITH
1117    if (to_free)
1118        OPENSSL_free(to_free);
1119#endif
1120    if (ex) {
1121        ERR_print_errors(bio_err);
1122    }
1123    if ((req_conf != NULL) && (req_conf != config))
1124        NCONF_free(req_conf);
1125    BIO_free(in);
1126    BIO_free_all(out);
1127    EVP_PKEY_free(pkey);
1128    X509_REQ_free(req);
1129    X509_free(x509ss);
1130    ASN1_INTEGER_free(serial);
1131    if (passargin && passin)
1132        OPENSSL_free(passin);
1133    if (passargout && passout)
1134        OPENSSL_free(passout);
1135    OBJ_cleanup();
1136#ifndef OPENSSL_NO_DSA
1137    if (dsa_params != NULL)
1138        DSA_free(dsa_params);
1139#endif
1140#ifndef OPENSSL_NO_ECDSA
1141    if (ec_params != NULL)
1142        EC_KEY_free(ec_params);
1143#endif
1144    apps_shutdown();
1145    OPENSSL_EXIT(ex);
1146}
1147
1148static int make_REQ(X509_REQ *req, EVP_PKEY *pkey, char *subj, int multirdn,
1149                    int attribs, unsigned long chtype)
1150{
1151    int ret = 0, i;
1152    char no_prompt = 0;
1153    STACK_OF(CONF_VALUE) *dn_sk, *attr_sk = NULL;
1154    char *tmp, *dn_sect, *attr_sect;
1155
1156    tmp = NCONF_get_string(req_conf, SECTION, PROMPT);
1157    if (tmp == NULL)
1158        ERR_clear_error();
1159    if ((tmp != NULL) && !strcmp(tmp, "no"))
1160        no_prompt = 1;
1161
1162    dn_sect = NCONF_get_string(req_conf, SECTION, DISTINGUISHED_NAME);
1163    if (dn_sect == NULL) {
1164        BIO_printf(bio_err, "unable to find '%s' in config\n",
1165                   DISTINGUISHED_NAME);
1166        goto err;
1167    }
1168    dn_sk = NCONF_get_section(req_conf, dn_sect);
1169    if (dn_sk == NULL) {
1170        BIO_printf(bio_err, "unable to get '%s' section\n", dn_sect);
1171        goto err;
1172    }
1173
1174    attr_sect = NCONF_get_string(req_conf, SECTION, ATTRIBUTES);
1175    if (attr_sect == NULL) {
1176        ERR_clear_error();
1177        attr_sk = NULL;
1178    } else {
1179        attr_sk = NCONF_get_section(req_conf, attr_sect);
1180        if (attr_sk == NULL) {
1181            BIO_printf(bio_err, "unable to get '%s' section\n", attr_sect);
1182            goto err;
1183        }
1184    }
1185
1186    /* setup version number */
1187    if (!X509_REQ_set_version(req, 0L))
1188        goto err;               /* version 1 */
1189
1190    if (no_prompt)
1191        i = auto_info(req, dn_sk, attr_sk, attribs, chtype);
1192    else {
1193        if (subj)
1194            i = build_subject(req, subj, chtype, multirdn);
1195        else
1196            i = prompt_info(req, dn_sk, dn_sect, attr_sk, attr_sect, attribs,
1197                            chtype);
1198    }
1199    if (!i)
1200        goto err;
1201
1202    if (!X509_REQ_set_pubkey(req, pkey))
1203        goto err;
1204
1205    ret = 1;
1206 err:
1207    return (ret);
1208}
1209
1210/*
1211 * subject is expected to be in the format /type0=value0/type1=value1/type2=...
1212 * where characters may be escaped by \
1213 */
1214static int build_subject(X509_REQ *req, char *subject, unsigned long chtype,
1215                         int multirdn)
1216{
1217    X509_NAME *n;
1218
1219    if (!(n = parse_name(subject, chtype, multirdn)))
1220        return 0;
1221
1222    if (!X509_REQ_set_subject_name(req, n)) {
1223        X509_NAME_free(n);
1224        return 0;
1225    }
1226    X509_NAME_free(n);
1227    return 1;
1228}
1229
1230static int prompt_info(X509_REQ *req,
1231                       STACK_OF(CONF_VALUE) *dn_sk, char *dn_sect,
1232                       STACK_OF(CONF_VALUE) *attr_sk, char *attr_sect,
1233                       int attribs, unsigned long chtype)
1234{
1235    int i;
1236    char *p, *q;
1237    char buf[100];
1238    int nid, mval;
1239    long n_min, n_max;
1240    char *type, *value;
1241    const char *def;
1242    CONF_VALUE *v;
1243    X509_NAME *subj;
1244    subj = X509_REQ_get_subject_name(req);
1245
1246    if (!batch) {
1247        BIO_printf(bio_err,
1248                   "You are about to be asked to enter information that will be incorporated\n");
1249        BIO_printf(bio_err, "into your certificate request.\n");
1250        BIO_printf(bio_err,
1251                   "What you are about to enter is what is called a Distinguished Name or a DN.\n");
1252        BIO_printf(bio_err,
1253                   "There are quite a few fields but you can leave some blank\n");
1254        BIO_printf(bio_err,
1255                   "For some fields there will be a default value,\n");
1256        BIO_printf(bio_err,
1257                   "If you enter '.', the field will be left blank.\n");
1258        BIO_printf(bio_err, "-----\n");
1259    }
1260
1261    if (sk_CONF_VALUE_num(dn_sk)) {
1262        i = -1;
1263 start:for (;;) {
1264            i++;
1265            if (sk_CONF_VALUE_num(dn_sk) <= i)
1266                break;
1267
1268            v = sk_CONF_VALUE_value(dn_sk, i);
1269            p = q = NULL;
1270            type = v->name;
1271            if (!check_end(type, "_min") || !check_end(type, "_max") ||
1272                !check_end(type, "_default") || !check_end(type, "_value"))
1273                continue;
1274            /*
1275             * Skip past any leading X. X: X, etc to allow for multiple
1276             * instances
1277             */
1278            for (p = v->name; *p; p++)
1279                if ((*p == ':') || (*p == ',') || (*p == '.')) {
1280                    p++;
1281                    if (*p)
1282                        type = p;
1283                    break;
1284                }
1285            if (*type == '+') {
1286                mval = -1;
1287                type++;
1288            } else
1289                mval = 0;
1290            /* If OBJ not recognised ignore it */
1291            if ((nid = OBJ_txt2nid(type)) == NID_undef)
1292                goto start;
1293            if (BIO_snprintf(buf, sizeof buf, "%s_default", v->name)
1294                >= (int)sizeof(buf)) {
1295                BIO_printf(bio_err, "Name '%s' too long\n", v->name);
1296                return 0;
1297            }
1298
1299            if ((def = NCONF_get_string(req_conf, dn_sect, buf)) == NULL) {
1300                ERR_clear_error();
1301                def = "";
1302            }
1303
1304            BIO_snprintf(buf, sizeof buf, "%s_value", v->name);
1305            if ((value = NCONF_get_string(req_conf, dn_sect, buf)) == NULL) {
1306                ERR_clear_error();
1307                value = NULL;
1308            }
1309
1310            BIO_snprintf(buf, sizeof buf, "%s_min", v->name);
1311            if (!NCONF_get_number(req_conf, dn_sect, buf, &n_min)) {
1312                ERR_clear_error();
1313                n_min = -1;
1314            }
1315
1316            BIO_snprintf(buf, sizeof buf, "%s_max", v->name);
1317            if (!NCONF_get_number(req_conf, dn_sect, buf, &n_max)) {
1318                ERR_clear_error();
1319                n_max = -1;
1320            }
1321
1322            if (!add_DN_object(subj, v->value, def, value, nid,
1323                               n_min, n_max, chtype, mval))
1324                return 0;
1325        }
1326        if (X509_NAME_entry_count(subj) == 0) {
1327            BIO_printf(bio_err,
1328                       "error, no objects specified in config file\n");
1329            return 0;
1330        }
1331
1332        if (attribs) {
1333            if ((attr_sk != NULL) && (sk_CONF_VALUE_num(attr_sk) > 0)
1334                && (!batch)) {
1335                BIO_printf(bio_err,
1336                           "\nPlease enter the following 'extra' attributes\n");
1337                BIO_printf(bio_err,
1338                           "to be sent with your certificate request\n");
1339            }
1340
1341            i = -1;
1342 start2:   for (;;) {
1343                i++;
1344                if ((attr_sk == NULL) || (sk_CONF_VALUE_num(attr_sk) <= i))
1345                    break;
1346
1347                v = sk_CONF_VALUE_value(attr_sk, i);
1348                type = v->name;
1349                if ((nid = OBJ_txt2nid(type)) == NID_undef)
1350                    goto start2;
1351
1352                if (BIO_snprintf(buf, sizeof buf, "%s_default", type)
1353                    >= (int)sizeof(buf)) {
1354                    BIO_printf(bio_err, "Name '%s' too long\n", v->name);
1355                    return 0;
1356                }
1357
1358                if ((def = NCONF_get_string(req_conf, attr_sect, buf))
1359                    == NULL) {
1360                    ERR_clear_error();
1361                    def = "";
1362                }
1363
1364                BIO_snprintf(buf, sizeof buf, "%s_value", type);
1365                if ((value = NCONF_get_string(req_conf, attr_sect, buf))
1366                    == NULL) {
1367                    ERR_clear_error();
1368                    value = NULL;
1369                }
1370
1371                BIO_snprintf(buf, sizeof buf, "%s_min", type);
1372                if (!NCONF_get_number(req_conf, attr_sect, buf, &n_min)) {
1373                    ERR_clear_error();
1374                    n_min = -1;
1375                }
1376
1377                BIO_snprintf(buf, sizeof buf, "%s_max", type);
1378                if (!NCONF_get_number(req_conf, attr_sect, buf, &n_max)) {
1379                    ERR_clear_error();
1380                    n_max = -1;
1381                }
1382
1383                if (!add_attribute_object(req,
1384                                          v->value, def, value, nid, n_min,
1385                                          n_max, chtype))
1386                    return 0;
1387            }
1388        }
1389    } else {
1390        BIO_printf(bio_err, "No template, please set one up.\n");
1391        return 0;
1392    }
1393
1394    return 1;
1395
1396}
1397
1398static int auto_info(X509_REQ *req, STACK_OF(CONF_VALUE) *dn_sk,
1399                     STACK_OF(CONF_VALUE) *attr_sk, int attribs,
1400                     unsigned long chtype)
1401{
1402    int i;
1403    char *p, *q;
1404    char *type;
1405    CONF_VALUE *v;
1406    X509_NAME *subj;
1407
1408    subj = X509_REQ_get_subject_name(req);
1409
1410    for (i = 0; i < sk_CONF_VALUE_num(dn_sk); i++) {
1411        int mval;
1412        v = sk_CONF_VALUE_value(dn_sk, i);
1413        p = q = NULL;
1414        type = v->name;
1415        /*
1416         * Skip past any leading X. X: X, etc to allow for multiple instances
1417         */
1418        for (p = v->name; *p; p++)
1419#ifndef CHARSET_EBCDIC
1420            if ((*p == ':') || (*p == ',') || (*p == '.')) {
1421#else
1422            if ((*p == os_toascii[':']) || (*p == os_toascii[','])
1423                || (*p == os_toascii['.'])) {
1424#endif
1425                p++;
1426                if (*p)
1427                    type = p;
1428                break;
1429            }
1430#ifndef CHARSET_EBCDIC
1431        if (*p == '+')
1432#else
1433        if (*p == os_toascii['+'])
1434#endif
1435        {
1436            p++;
1437            mval = -1;
1438        } else
1439            mval = 0;
1440        if (!X509_NAME_add_entry_by_txt(subj, type, chtype,
1441                                        (unsigned char *)v->value, -1, -1,
1442                                        mval))
1443            return 0;
1444
1445    }
1446
1447    if (!X509_NAME_entry_count(subj)) {
1448        BIO_printf(bio_err, "error, no objects specified in config file\n");
1449        return 0;
1450    }
1451    if (attribs) {
1452        for (i = 0; i < sk_CONF_VALUE_num(attr_sk); i++) {
1453            v = sk_CONF_VALUE_value(attr_sk, i);
1454            if (!X509_REQ_add1_attr_by_txt(req, v->name, chtype,
1455                                           (unsigned char *)v->value, -1))
1456                return 0;
1457        }
1458    }
1459    return 1;
1460}
1461
1462static int add_DN_object(X509_NAME *n, char *text, const char *def,
1463                         char *value, int nid, int n_min, int n_max,
1464                         unsigned long chtype, int mval)
1465{
1466    int i, ret = 0;
1467    MS_STATIC char buf[1024];
1468 start:
1469    if (!batch)
1470        BIO_printf(bio_err, "%s [%s]:", text, def);
1471    (void)BIO_flush(bio_err);
1472    if (value != NULL) {
1473        BUF_strlcpy(buf, value, sizeof buf);
1474        BUF_strlcat(buf, "\n", sizeof buf);
1475        BIO_printf(bio_err, "%s\n", value);
1476    } else {
1477        buf[0] = '\0';
1478        if (!batch) {
1479            if (!fgets(buf, sizeof buf, stdin))
1480                return 0;
1481        } else {
1482            buf[0] = '\n';
1483            buf[1] = '\0';
1484        }
1485    }
1486
1487    if (buf[0] == '\0')
1488        return (0);
1489    else if (buf[0] == '\n') {
1490        if ((def == NULL) || (def[0] == '\0'))
1491            return (1);
1492        BUF_strlcpy(buf, def, sizeof buf);
1493        BUF_strlcat(buf, "\n", sizeof buf);
1494    } else if ((buf[0] == '.') && (buf[1] == '\n'))
1495        return (1);
1496
1497    i = strlen(buf);
1498    if (buf[i - 1] != '\n') {
1499        BIO_printf(bio_err, "weird input :-(\n");
1500        return (0);
1501    }
1502    buf[--i] = '\0';
1503#ifdef CHARSET_EBCDIC
1504    ebcdic2ascii(buf, buf, i);
1505#endif
1506    if (!req_check_len(i, n_min, n_max)) {
1507        if (batch || value)
1508            return 0;
1509        goto start;
1510    }
1511
1512    if (!X509_NAME_add_entry_by_NID(n, nid, chtype,
1513                                    (unsigned char *)buf, -1, -1, mval))
1514        goto err;
1515    ret = 1;
1516 err:
1517    return (ret);
1518}
1519
1520static int add_attribute_object(X509_REQ *req, char *text, const char *def,
1521                                char *value, int nid, int n_min,
1522                                int n_max, unsigned long chtype)
1523{
1524    int i;
1525    static char buf[1024];
1526
1527 start:
1528    if (!batch)
1529        BIO_printf(bio_err, "%s [%s]:", text, def);
1530    (void)BIO_flush(bio_err);
1531    if (value != NULL) {
1532        BUF_strlcpy(buf, value, sizeof buf);
1533        BUF_strlcat(buf, "\n", sizeof buf);
1534        BIO_printf(bio_err, "%s\n", value);
1535    } else {
1536        buf[0] = '\0';
1537        if (!batch) {
1538            if (!fgets(buf, sizeof buf, stdin))
1539                return 0;
1540        } else {
1541            buf[0] = '\n';
1542            buf[1] = '\0';
1543        }
1544    }
1545
1546    if (buf[0] == '\0')
1547        return (0);
1548    else if (buf[0] == '\n') {
1549        if ((def == NULL) || (def[0] == '\0'))
1550            return (1);
1551        BUF_strlcpy(buf, def, sizeof buf);
1552        BUF_strlcat(buf, "\n", sizeof buf);
1553    } else if ((buf[0] == '.') && (buf[1] == '\n'))
1554        return (1);
1555
1556    i = strlen(buf);
1557    if (buf[i - 1] != '\n') {
1558        BIO_printf(bio_err, "weird input :-(\n");
1559        return (0);
1560    }
1561    buf[--i] = '\0';
1562#ifdef CHARSET_EBCDIC
1563    ebcdic2ascii(buf, buf, i);
1564#endif
1565    if (!req_check_len(i, n_min, n_max)) {
1566        if (batch || value)
1567            return 0;
1568        goto start;
1569    }
1570
1571    if (!X509_REQ_add1_attr_by_NID(req, nid, chtype,
1572                                   (unsigned char *)buf, -1)) {
1573        BIO_printf(bio_err, "Error adding attribute\n");
1574        ERR_print_errors(bio_err);
1575        goto err;
1576    }
1577
1578    return (1);
1579 err:
1580    return (0);
1581}
1582
1583#ifndef OPENSSL_NO_RSA
1584static int MS_CALLBACK req_cb(int p, int n, BN_GENCB *cb)
1585{
1586    char c = '*';
1587
1588    if (p == 0)
1589        c = '.';
1590    if (p == 1)
1591        c = '+';
1592    if (p == 2)
1593        c = '*';
1594    if (p == 3)
1595        c = '\n';
1596    BIO_write(cb->arg, &c, 1);
1597    (void)BIO_flush(cb->arg);
1598# ifdef LINT
1599    p = n;
1600# endif
1601    return 1;
1602}
1603#endif
1604
1605static int req_check_len(int len, int n_min, int n_max)
1606{
1607    if ((n_min > 0) && (len < n_min)) {
1608        BIO_printf(bio_err,
1609                   "string is too short, it needs to be at least %d bytes long\n",
1610                   n_min);
1611        return (0);
1612    }
1613    if ((n_max >= 0) && (len > n_max)) {
1614        BIO_printf(bio_err,
1615                   "string is too long, it needs to be less than  %d bytes long\n",
1616                   n_max);
1617        return (0);
1618    }
1619    return (1);
1620}
1621
1622/* Check if the end of a string matches 'end' */
1623static int check_end(const char *str, const char *end)
1624{
1625    int elen, slen;
1626    const char *tmp;
1627    elen = strlen(end);
1628    slen = strlen(str);
1629    if (elen > slen)
1630        return 1;
1631    tmp = str + slen - elen;
1632    return strcmp(tmp, end);
1633}
1634