xref: /freebsd/crypto/openssl/apps/req.c (revision 6f9291cea8b06d251243fd47a7234018541832a3)
174664626SKris Kennaway /* apps/req.c */
274664626SKris Kennaway /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
374664626SKris Kennaway  * All rights reserved.
474664626SKris Kennaway  *
574664626SKris Kennaway  * This package is an SSL implementation written
674664626SKris Kennaway  * by Eric Young (eay@cryptsoft.com).
774664626SKris Kennaway  * The implementation was written so as to conform with Netscapes SSL.
874664626SKris Kennaway  *
974664626SKris Kennaway  * This library is free for commercial and non-commercial use as long as
1074664626SKris Kennaway  * the following conditions are aheared to.  The following conditions
1174664626SKris Kennaway  * apply to all code found in this distribution, be it the RC4, RSA,
1274664626SKris Kennaway  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
1374664626SKris Kennaway  * included with this distribution is covered by the same copyright terms
1474664626SKris Kennaway  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
1574664626SKris Kennaway  *
1674664626SKris Kennaway  * Copyright remains Eric Young's, and as such any Copyright notices in
1774664626SKris Kennaway  * the code are not to be removed.
1874664626SKris Kennaway  * If this package is used in a product, Eric Young should be given attribution
1974664626SKris Kennaway  * as the author of the parts of the library used.
2074664626SKris Kennaway  * This can be in the form of a textual message at program startup or
2174664626SKris Kennaway  * in documentation (online or textual) provided with the package.
2274664626SKris Kennaway  *
2374664626SKris Kennaway  * Redistribution and use in source and binary forms, with or without
2474664626SKris Kennaway  * modification, are permitted provided that the following conditions
2574664626SKris Kennaway  * are met:
2674664626SKris Kennaway  * 1. Redistributions of source code must retain the copyright
2774664626SKris Kennaway  *    notice, this list of conditions and the following disclaimer.
2874664626SKris Kennaway  * 2. Redistributions in binary form must reproduce the above copyright
2974664626SKris Kennaway  *    notice, this list of conditions and the following disclaimer in the
3074664626SKris Kennaway  *    documentation and/or other materials provided with the distribution.
3174664626SKris Kennaway  * 3. All advertising materials mentioning features or use of this software
3274664626SKris Kennaway  *    must display the following acknowledgement:
3374664626SKris Kennaway  *    "This product includes cryptographic software written by
3474664626SKris Kennaway  *     Eric Young (eay@cryptsoft.com)"
3574664626SKris Kennaway  *    The word 'cryptographic' can be left out if the rouines from the library
3674664626SKris Kennaway  *    being used are not cryptographic related :-).
3774664626SKris Kennaway  * 4. If you include any Windows specific code (or a derivative thereof) from
3874664626SKris Kennaway  *    the apps directory (application code) you must include an acknowledgement:
3974664626SKris Kennaway  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
4074664626SKris Kennaway  *
4174664626SKris Kennaway  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
4274664626SKris Kennaway  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
4374664626SKris Kennaway  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
4474664626SKris Kennaway  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
4574664626SKris Kennaway  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
4674664626SKris Kennaway  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
4774664626SKris Kennaway  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
4874664626SKris Kennaway  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
4974664626SKris Kennaway  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
5074664626SKris Kennaway  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
5174664626SKris Kennaway  * SUCH DAMAGE.
5274664626SKris Kennaway  *
5374664626SKris Kennaway  * The licence and distribution terms for any publically available version or
5474664626SKris Kennaway  * derivative of this code cannot be changed.  i.e. this code cannot simply be
5574664626SKris Kennaway  * copied and put under another distribution licence
5674664626SKris Kennaway  * [including the GNU Public Licence.]
5774664626SKris Kennaway  */
5874664626SKris Kennaway 
59*6f9291ceSJung-uk Kim /*
60*6f9291ceSJung-uk Kim  * Until the key-gen callbacks are modified to use newer prototypes, we allow
61*6f9291ceSJung-uk Kim  * deprecated functions for openssl-internal code
62*6f9291ceSJung-uk Kim  */
633b4e3dcbSSimon L. B. Nielsen #ifdef OPENSSL_NO_DEPRECATED
643b4e3dcbSSimon L. B. Nielsen # undef OPENSSL_NO_DEPRECATED
653b4e3dcbSSimon L. B. Nielsen #endif
663b4e3dcbSSimon L. B. Nielsen 
6774664626SKris Kennaway #include <stdio.h>
6874664626SKris Kennaway #include <stdlib.h>
6974664626SKris Kennaway #include <time.h>
7074664626SKris Kennaway #include <string.h>
715c87c606SMark Murray #ifdef OPENSSL_NO_STDIO
7274664626SKris Kennaway # define APPS_WIN16
7374664626SKris Kennaway #endif
7474664626SKris Kennaway #include "apps.h"
7574664626SKris Kennaway #include <openssl/bio.h>
7674664626SKris Kennaway #include <openssl/evp.h>
7774664626SKris Kennaway #include <openssl/conf.h>
7874664626SKris Kennaway #include <openssl/err.h>
7974664626SKris Kennaway #include <openssl/asn1.h>
8074664626SKris Kennaway #include <openssl/x509.h>
8174664626SKris Kennaway #include <openssl/x509v3.h>
8274664626SKris Kennaway #include <openssl/objects.h>
8374664626SKris Kennaway #include <openssl/pem.h>
843b4e3dcbSSimon L. B. Nielsen #include <openssl/bn.h>
853b4e3dcbSSimon L. B. Nielsen #ifndef OPENSSL_NO_RSA
863b4e3dcbSSimon L. B. Nielsen # include <openssl/rsa.h>
873b4e3dcbSSimon L. B. Nielsen #endif
883b4e3dcbSSimon L. B. Nielsen #ifndef OPENSSL_NO_DSA
893b4e3dcbSSimon L. B. Nielsen # include <openssl/dsa.h>
903b4e3dcbSSimon L. B. Nielsen #endif
9174664626SKris Kennaway 
9274664626SKris Kennaway #define SECTION         "req"
9374664626SKris Kennaway 
9474664626SKris Kennaway #define BITS            "default_bits"
9574664626SKris Kennaway #define KEYFILE         "default_keyfile"
96f579bf8eSKris Kennaway #define PROMPT          "prompt"
9774664626SKris Kennaway #define DISTINGUISHED_NAME      "distinguished_name"
9874664626SKris Kennaway #define ATTRIBUTES      "attributes"
9974664626SKris Kennaway #define V3_EXTENSIONS   "x509_extensions"
100f579bf8eSKris Kennaway #define REQ_EXTENSIONS  "req_extensions"
101f579bf8eSKris Kennaway #define STRING_MASK     "string_mask"
1025c87c606SMark Murray #define UTF8_IN         "utf8"
10374664626SKris Kennaway 
10474664626SKris Kennaway #define DEFAULT_KEY_LENGTH      512
10574664626SKris Kennaway #define MIN_KEY_LENGTH          384
10674664626SKris Kennaway 
10774664626SKris Kennaway #undef PROG
10874664626SKris Kennaway #define PROG    req_main
10974664626SKris Kennaway 
110*6f9291ceSJung-uk Kim /*-
111*6f9291ceSJung-uk Kim  * -inform arg  - input format - default PEM (DER or PEM)
11274664626SKris Kennaway  * -outform arg - output format - default PEM
11374664626SKris Kennaway  * -in arg      - input file - default stdin
11474664626SKris Kennaway  * -out arg     - output file - default stdout
11574664626SKris Kennaway  * -verify      - check request signature
11674664626SKris Kennaway  * -noout       - don't print stuff out.
11774664626SKris Kennaway  * -text        - print out human readable text.
11874664626SKris Kennaway  * -nodes       - no des encryption
11974664626SKris Kennaway  * -config file - Load configuration file.
12074664626SKris Kennaway  * -key file    - make a request using key in file (or use it for verification).
1215c87c606SMark Murray  * -keyform arg - key file format.
122ddd58736SKris Kennaway  * -rand file(s) - load the file(s) into the PRNG.
12374664626SKris Kennaway  * -newkey      - make a key and a request.
12474664626SKris Kennaway  * -modulus     - print RSA modulus.
1255c87c606SMark Murray  * -pubkey      - output Public Key.
12674664626SKris Kennaway  * -x509        - output a self signed X509 structure instead.
12774664626SKris Kennaway  * -asn1-kludge - output new certificate request in a format that some CA's
12874664626SKris Kennaway  *                require.  This format is wrong
12974664626SKris Kennaway  */
13074664626SKris Kennaway 
1313b4e3dcbSSimon L. B. Nielsen static int make_REQ(X509_REQ *req, EVP_PKEY *pkey, char *dn, int mutlirdn,
1323b4e3dcbSSimon L. B. Nielsen                     int attribs, unsigned long chtype);
1333b4e3dcbSSimon L. B. Nielsen static int build_subject(X509_REQ *req, char *subj, unsigned long chtype,
1343b4e3dcbSSimon L. B. Nielsen                          int multirdn);
135f579bf8eSKris Kennaway static int prompt_info(X509_REQ *req,
136f579bf8eSKris Kennaway                        STACK_OF(CONF_VALUE) *dn_sk, char *dn_sect,
137*6f9291ceSJung-uk Kim                        STACK_OF(CONF_VALUE) *attr_sk, char *attr_sect,
138*6f9291ceSJung-uk Kim                        int attribs, unsigned long chtype);
139f579bf8eSKris Kennaway static int auto_info(X509_REQ *req, STACK_OF(CONF_VALUE) *sk,
1405c87c606SMark Murray                      STACK_OF(CONF_VALUE) *attr, int attribs,
1415c87c606SMark Murray                      unsigned long chtype);
1423b4e3dcbSSimon L. B. Nielsen static int add_attribute_object(X509_REQ *req, char *text, const char *def,
143*6f9291ceSJung-uk Kim                                 char *value, int nid, int n_min, int n_max,
144*6f9291ceSJung-uk Kim                                 unsigned long chtype);
145*6f9291ceSJung-uk Kim static int add_DN_object(X509_NAME *n, char *text, const char *def,
146*6f9291ceSJung-uk Kim                          char *value, int nid, int n_min, int n_max,
147*6f9291ceSJung-uk Kim                          unsigned long chtype, int mval);
1481f13597dSJung-uk Kim static int genpkey_cb(EVP_PKEY_CTX *ctx);
1495c87c606SMark Murray static int req_check_len(int len, int n_min, int n_max);
1503b4e3dcbSSimon L. B. Nielsen static int check_end(const char *str, const char *end);
151*6f9291ceSJung-uk Kim static EVP_PKEY_CTX *set_keygen_ctx(BIO *err, const char *gstr,
152*6f9291ceSJung-uk Kim                                     int *pkey_type, long *pkeylen,
153*6f9291ceSJung-uk Kim                                     char **palgnam, ENGINE *keygen_engine);
15474664626SKris Kennaway #ifndef MONOLITH
15574664626SKris Kennaway static char *default_config_file = NULL;
15674664626SKris Kennaway #endif
1575c87c606SMark Murray static CONF *req_conf = NULL;
1585c87c606SMark Murray static int batch = 0;
15974664626SKris Kennaway 
160f579bf8eSKris Kennaway int MAIN(int, char **);
161f579bf8eSKris Kennaway 
16274664626SKris Kennaway int MAIN(int argc, char **argv)
16374664626SKris Kennaway {
1641f13597dSJung-uk Kim     ENGINE *e = NULL, *gen_eng = NULL;
1655c87c606SMark Murray     unsigned long nmflag = 0, reqflag = 0;
16674664626SKris Kennaway     int ex = 1, x509 = 0, days = 30;
16774664626SKris Kennaway     X509 *x509ss = NULL;
16874664626SKris Kennaway     X509_REQ *req = NULL;
1691f13597dSJung-uk Kim     EVP_PKEY_CTX *genctx = NULL;
1701f13597dSJung-uk Kim     const char *keyalg = NULL;
1711f13597dSJung-uk Kim     char *keyalgstr = NULL;
1721f13597dSJung-uk Kim     STACK_OF(OPENSSL_STRING) *pkeyopts = NULL, *sigopts = NULL;
17374664626SKris Kennaway     EVP_PKEY *pkey = NULL;
1741f13597dSJung-uk Kim     int i = 0, badops = 0, newreq = 0, verbose = 0, pkey_type = -1;
1755c87c606SMark Murray     long newkey = -1;
17674664626SKris Kennaway     BIO *in = NULL, *out = NULL;
177*6f9291ceSJung-uk Kim     int informat, outformat, verify = 0, noout = 0, text = 0, keyform =
178*6f9291ceSJung-uk Kim         FORMAT_PEM;
1795c87c606SMark Murray     int nodes = 0, kludge = 0, newhdr = 0, subject = 0, pubkey = 0;
180*6f9291ceSJung-uk Kim     char *infile, *outfile, *prog, *keyfile = NULL, *template =
181*6f9291ceSJung-uk Kim         NULL, *keyout = NULL;
182fceca8a3SJacques Vidrine #ifndef OPENSSL_NO_ENGINE
1835c87c606SMark Murray     char *engine = NULL;
184fceca8a3SJacques Vidrine #endif
18574664626SKris Kennaway     char *extensions = NULL;
186f579bf8eSKris Kennaway     char *req_exts = NULL;
1875c87c606SMark Murray     const EVP_CIPHER *cipher = NULL;
1885c87c606SMark Murray     ASN1_INTEGER *serial = NULL;
18974664626SKris Kennaway     int modulus = 0;
190ddd58736SKris Kennaway     char *inrand = NULL;
191f579bf8eSKris Kennaway     char *passargin = NULL, *passargout = NULL;
192f579bf8eSKris Kennaway     char *passin = NULL, *passout = NULL;
19374664626SKris Kennaway     char *p;
1945c87c606SMark Murray     char *subj = NULL;
1953b4e3dcbSSimon L. B. Nielsen     int multirdn = 0;
1961f13597dSJung-uk Kim     const EVP_MD *md_alg = NULL, *digest = NULL;
1975c87c606SMark Murray     unsigned long chtype = MBSTRING_ASC;
19874664626SKris Kennaway #ifndef MONOLITH
1995c87c606SMark Murray     char *to_free;
2005c87c606SMark Murray     long errline;
20174664626SKris Kennaway #endif
20274664626SKris Kennaway 
203f579bf8eSKris Kennaway     req_conf = NULL;
2045c87c606SMark Murray #ifndef OPENSSL_NO_DES
20574664626SKris Kennaway     cipher = EVP_des_ede3_cbc();
20674664626SKris Kennaway #endif
20774664626SKris Kennaway     apps_startup();
20874664626SKris Kennaway 
20974664626SKris Kennaway     if (bio_err == NULL)
21074664626SKris Kennaway         if ((bio_err = BIO_new(BIO_s_file())) != NULL)
21174664626SKris Kennaway             BIO_set_fp(bio_err, stderr, BIO_NOCLOSE | BIO_FP_TEXT);
21274664626SKris Kennaway 
21374664626SKris Kennaway     infile = NULL;
21474664626SKris Kennaway     outfile = NULL;
21574664626SKris Kennaway     informat = FORMAT_PEM;
21674664626SKris Kennaway     outformat = FORMAT_PEM;
21774664626SKris Kennaway 
21874664626SKris Kennaway     prog = argv[0];
21974664626SKris Kennaway     argc--;
22074664626SKris Kennaway     argv++;
221*6f9291ceSJung-uk Kim     while (argc >= 1) {
222*6f9291ceSJung-uk Kim         if (strcmp(*argv, "-inform") == 0) {
223*6f9291ceSJung-uk Kim             if (--argc < 1)
224*6f9291ceSJung-uk Kim                 goto bad;
22574664626SKris Kennaway             informat = str2fmt(*(++argv));
226*6f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-outform") == 0) {
227*6f9291ceSJung-uk Kim             if (--argc < 1)
228*6f9291ceSJung-uk Kim                 goto bad;
22974664626SKris Kennaway             outformat = str2fmt(*(++argv));
23074664626SKris Kennaway         }
231fceca8a3SJacques Vidrine #ifndef OPENSSL_NO_ENGINE
232*6f9291ceSJung-uk Kim         else if (strcmp(*argv, "-engine") == 0) {
233*6f9291ceSJung-uk Kim             if (--argc < 1)
234*6f9291ceSJung-uk Kim                 goto bad;
2355c87c606SMark Murray             engine = *(++argv);
236*6f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-keygen_engine") == 0) {
237*6f9291ceSJung-uk Kim             if (--argc < 1)
238*6f9291ceSJung-uk Kim                 goto bad;
2391f13597dSJung-uk Kim             gen_eng = ENGINE_by_id(*(++argv));
240*6f9291ceSJung-uk Kim             if (gen_eng == NULL) {
2411f13597dSJung-uk Kim                 BIO_printf(bio_err, "Can't find keygen engine %s\n", *argv);
2421f13597dSJung-uk Kim                 goto end;
2431f13597dSJung-uk Kim             }
2441f13597dSJung-uk Kim         }
245fceca8a3SJacques Vidrine #endif
246*6f9291ceSJung-uk Kim         else if (strcmp(*argv, "-key") == 0) {
247*6f9291ceSJung-uk Kim             if (--argc < 1)
248*6f9291ceSJung-uk Kim                 goto bad;
24974664626SKris Kennaway             keyfile = *(++argv);
250*6f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-pubkey") == 0) {
2515c87c606SMark Murray             pubkey = 1;
252*6f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-new") == 0) {
25374664626SKris Kennaway             newreq = 1;
254*6f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-config") == 0) {
255*6f9291ceSJung-uk Kim             if (--argc < 1)
256*6f9291ceSJung-uk Kim                 goto bad;
25774664626SKris Kennaway             template = *(++argv);
258*6f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-keyform") == 0) {
259*6f9291ceSJung-uk Kim             if (--argc < 1)
260*6f9291ceSJung-uk Kim                 goto bad;
26174664626SKris Kennaway             keyform = str2fmt(*(++argv));
262*6f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-in") == 0) {
263*6f9291ceSJung-uk Kim             if (--argc < 1)
264*6f9291ceSJung-uk Kim                 goto bad;
26574664626SKris Kennaway             infile = *(++argv);
266*6f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-out") == 0) {
267*6f9291ceSJung-uk Kim             if (--argc < 1)
268*6f9291ceSJung-uk Kim                 goto bad;
26974664626SKris Kennaway             outfile = *(++argv);
270*6f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-keyout") == 0) {
271*6f9291ceSJung-uk Kim             if (--argc < 1)
272*6f9291ceSJung-uk Kim                 goto bad;
27374664626SKris Kennaway             keyout = *(++argv);
274*6f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-passin") == 0) {
275*6f9291ceSJung-uk Kim             if (--argc < 1)
276*6f9291ceSJung-uk Kim                 goto bad;
277f579bf8eSKris Kennaway             passargin = *(++argv);
278*6f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-passout") == 0) {
279*6f9291ceSJung-uk Kim             if (--argc < 1)
280*6f9291ceSJung-uk Kim                 goto bad;
281f579bf8eSKris Kennaway             passargout = *(++argv);
282*6f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-rand") == 0) {
283*6f9291ceSJung-uk Kim             if (--argc < 1)
284*6f9291ceSJung-uk Kim                 goto bad;
285ddd58736SKris Kennaway             inrand = *(++argv);
286*6f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-newkey") == 0) {
2871f13597dSJung-uk Kim             if (--argc < 1)
2881f13597dSJung-uk Kim                 goto bad;
2891f13597dSJung-uk Kim             keyalg = *(++argv);
2901f13597dSJung-uk Kim             newreq = 1;
291*6f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-pkeyopt") == 0) {
2921f13597dSJung-uk Kim             if (--argc < 1)
2931f13597dSJung-uk Kim                 goto bad;
2941f13597dSJung-uk Kim             if (!pkeyopts)
2951f13597dSJung-uk Kim                 pkeyopts = sk_OPENSSL_STRING_new_null();
2961f13597dSJung-uk Kim             if (!pkeyopts || !sk_OPENSSL_STRING_push(pkeyopts, *(++argv)))
2973b4e3dcbSSimon L. B. Nielsen                 goto bad;
298*6f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-sigopt") == 0) {
2991f13597dSJung-uk Kim             if (--argc < 1)
3001f13597dSJung-uk Kim                 goto bad;
3011f13597dSJung-uk Kim             if (!sigopts)
3021f13597dSJung-uk Kim                 sigopts = sk_OPENSSL_STRING_new_null();
3031f13597dSJung-uk Kim             if (!sigopts || !sk_OPENSSL_STRING_push(sigopts, *(++argv)))
3041f13597dSJung-uk Kim                 goto bad;
305*6f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-batch") == 0)
3065c87c606SMark Murray             batch = 1;
307f579bf8eSKris Kennaway         else if (strcmp(*argv, "-newhdr") == 0)
308f579bf8eSKris Kennaway             newhdr = 1;
30974664626SKris Kennaway         else if (strcmp(*argv, "-modulus") == 0)
31074664626SKris Kennaway             modulus = 1;
31174664626SKris Kennaway         else if (strcmp(*argv, "-verify") == 0)
31274664626SKris Kennaway             verify = 1;
31374664626SKris Kennaway         else if (strcmp(*argv, "-nodes") == 0)
31474664626SKris Kennaway             nodes = 1;
31574664626SKris Kennaway         else if (strcmp(*argv, "-noout") == 0)
31674664626SKris Kennaway             noout = 1;
3175c87c606SMark Murray         else if (strcmp(*argv, "-verbose") == 0)
3185c87c606SMark Murray             verbose = 1;
3195c87c606SMark Murray         else if (strcmp(*argv, "-utf8") == 0)
3205c87c606SMark Murray             chtype = MBSTRING_UTF8;
321*6f9291ceSJung-uk Kim         else if (strcmp(*argv, "-nameopt") == 0) {
322*6f9291ceSJung-uk Kim             if (--argc < 1)
323*6f9291ceSJung-uk Kim                 goto bad;
324*6f9291ceSJung-uk Kim             if (!set_name_ex(&nmflag, *(++argv)))
325*6f9291ceSJung-uk Kim                 goto bad;
326*6f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-reqopt") == 0) {
327*6f9291ceSJung-uk Kim             if (--argc < 1)
328*6f9291ceSJung-uk Kim                 goto bad;
329*6f9291ceSJung-uk Kim             if (!set_cert_ex(&reqflag, *(++argv)))
330*6f9291ceSJung-uk Kim                 goto bad;
331*6f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-subject") == 0)
3325c87c606SMark Murray             subject = 1;
33374664626SKris Kennaway         else if (strcmp(*argv, "-text") == 0)
33474664626SKris Kennaway             text = 1;
33574664626SKris Kennaway         else if (strcmp(*argv, "-x509") == 0)
33674664626SKris Kennaway             x509 = 1;
33774664626SKris Kennaway         else if (strcmp(*argv, "-asn1-kludge") == 0)
33874664626SKris Kennaway             kludge = 1;
33974664626SKris Kennaway         else if (strcmp(*argv, "-no-asn1-kludge") == 0)
34074664626SKris Kennaway             kludge = 0;
341*6f9291ceSJung-uk Kim         else if (strcmp(*argv, "-subj") == 0) {
342*6f9291ceSJung-uk Kim             if (--argc < 1)
343*6f9291ceSJung-uk Kim                 goto bad;
3445c87c606SMark Murray             subj = *(++argv);
345*6f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-multivalue-rdn") == 0)
3463b4e3dcbSSimon L. B. Nielsen             multirdn = 1;
347*6f9291ceSJung-uk Kim         else if (strcmp(*argv, "-days") == 0) {
348*6f9291ceSJung-uk Kim             if (--argc < 1)
349*6f9291ceSJung-uk Kim                 goto bad;
35074664626SKris Kennaway             days = atoi(*(++argv));
351*6f9291ceSJung-uk Kim             if (days == 0)
352*6f9291ceSJung-uk Kim                 days = 30;
353*6f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-set_serial") == 0) {
354*6f9291ceSJung-uk Kim             if (--argc < 1)
355*6f9291ceSJung-uk Kim                 goto bad;
3565c87c606SMark Murray             serial = s2i_ASN1_INTEGER(NULL, *(++argv));
357*6f9291ceSJung-uk Kim             if (!serial)
358*6f9291ceSJung-uk Kim                 goto bad;
359*6f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-extensions") == 0) {
360*6f9291ceSJung-uk Kim             if (--argc < 1)
361*6f9291ceSJung-uk Kim                 goto bad;
362f579bf8eSKris Kennaway             extensions = *(++argv);
363*6f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-reqexts") == 0) {
364*6f9291ceSJung-uk Kim             if (--argc < 1)
365*6f9291ceSJung-uk Kim                 goto bad;
366f579bf8eSKris Kennaway             req_exts = *(++argv);
367*6f9291ceSJung-uk Kim         } else if ((md_alg = EVP_get_digestbyname(&((*argv)[1]))) != NULL) {
3681f13597dSJung-uk Kim             /* ok */
3691f13597dSJung-uk Kim             digest = md_alg;
370*6f9291ceSJung-uk Kim         } else {
37174664626SKris Kennaway             BIO_printf(bio_err, "unknown option %s\n", *argv);
37274664626SKris Kennaway             badops = 1;
37374664626SKris Kennaway             break;
37474664626SKris Kennaway         }
37574664626SKris Kennaway         argc--;
37674664626SKris Kennaway         argv++;
37774664626SKris Kennaway     }
37874664626SKris Kennaway 
379*6f9291ceSJung-uk Kim     if (badops) {
38074664626SKris Kennaway  bad:
38174664626SKris Kennaway         BIO_printf(bio_err, "%s [options] <infile >outfile\n", prog);
38274664626SKris Kennaway         BIO_printf(bio_err, "where options  are\n");
383f579bf8eSKris Kennaway         BIO_printf(bio_err, " -inform arg    input format - DER or PEM\n");
384f579bf8eSKris Kennaway         BIO_printf(bio_err, " -outform arg   output format - DER or PEM\n");
38574664626SKris Kennaway         BIO_printf(bio_err, " -in arg        input file\n");
38674664626SKris Kennaway         BIO_printf(bio_err, " -out arg       output file\n");
38774664626SKris Kennaway         BIO_printf(bio_err, " -text          text form of request\n");
3885c87c606SMark Murray         BIO_printf(bio_err, " -pubkey        output public key\n");
38974664626SKris Kennaway         BIO_printf(bio_err, " -noout         do not output REQ\n");
39074664626SKris Kennaway         BIO_printf(bio_err, " -verify        verify signature on REQ\n");
39174664626SKris Kennaway         BIO_printf(bio_err, " -modulus       RSA modulus\n");
39274664626SKris Kennaway         BIO_printf(bio_err, " -nodes         don't encrypt the output key\n");
393fceca8a3SJacques Vidrine #ifndef OPENSSL_NO_ENGINE
394*6f9291ceSJung-uk Kim         BIO_printf(bio_err,
395*6f9291ceSJung-uk Kim                    " -engine e      use engine e, possibly a hardware device\n");
396fceca8a3SJacques Vidrine #endif
3975c87c606SMark Murray         BIO_printf(bio_err, " -subject       output the request's subject\n");
3985c87c606SMark Murray         BIO_printf(bio_err, " -passin        private key password source\n");
399*6f9291ceSJung-uk Kim         BIO_printf(bio_err,
400*6f9291ceSJung-uk Kim                    " -key file      use the private key contained in file\n");
40174664626SKris Kennaway         BIO_printf(bio_err, " -keyform arg   key file format\n");
40274664626SKris Kennaway         BIO_printf(bio_err, " -keyout arg    file to send the key to\n");
403*6f9291ceSJung-uk Kim         BIO_printf(bio_err, " -rand file%cfile%c...\n", LIST_SEPARATOR_CHAR,
404*6f9291ceSJung-uk Kim                    LIST_SEPARATOR_CHAR);
405*6f9291ceSJung-uk Kim         BIO_printf(bio_err,
406*6f9291ceSJung-uk Kim                    "                load the file (or the files in the directory) into\n");
407ddd58736SKris Kennaway         BIO_printf(bio_err, "                the random number generator\n");
408*6f9291ceSJung-uk Kim         BIO_printf(bio_err,
409*6f9291ceSJung-uk Kim                    " -newkey rsa:bits generate a new RSA key of 'bits' in size\n");
410*6f9291ceSJung-uk Kim         BIO_printf(bio_err,
411*6f9291ceSJung-uk Kim                    " -newkey dsa:file generate a new DSA key, parameters taken from CA in 'file'\n");
4123b4e3dcbSSimon L. B. Nielsen #ifndef OPENSSL_NO_ECDSA
413*6f9291ceSJung-uk Kim         BIO_printf(bio_err,
414*6f9291ceSJung-uk Kim                    " -newkey ec:file generate a new EC key, parameters taken from CA in 'file'\n");
4153b4e3dcbSSimon L. B. Nielsen #endif
416*6f9291ceSJung-uk Kim         BIO_printf(bio_err,
417*6f9291ceSJung-uk Kim                    " -[digest]      Digest to sign with (md5, sha1, md2, mdc2, md4)\n");
41874664626SKris Kennaway         BIO_printf(bio_err, " -config file   request template file.\n");
419*6f9291ceSJung-uk Kim         BIO_printf(bio_err,
420*6f9291ceSJung-uk Kim                    " -subj arg      set or modify request subject\n");
421*6f9291ceSJung-uk Kim         BIO_printf(bio_err,
422*6f9291ceSJung-uk Kim                    " -multivalue-rdn enable support for multivalued RDNs\n");
42374664626SKris Kennaway         BIO_printf(bio_err, " -new           new request.\n");
424*6f9291ceSJung-uk Kim         BIO_printf(bio_err,
425*6f9291ceSJung-uk Kim                    " -batch         do not ask anything during request generation\n");
426*6f9291ceSJung-uk Kim         BIO_printf(bio_err,
427*6f9291ceSJung-uk Kim                    " -x509          output a x509 structure instead of a cert. req.\n");
428*6f9291ceSJung-uk Kim         BIO_printf(bio_err,
429*6f9291ceSJung-uk Kim                    " -days          number of days a certificate generated by -x509 is valid for.\n");
430*6f9291ceSJung-uk Kim         BIO_printf(bio_err,
431*6f9291ceSJung-uk Kim                    " -set_serial    serial number to use for a certificate generated by -x509.\n");
432*6f9291ceSJung-uk Kim         BIO_printf(bio_err,
433*6f9291ceSJung-uk Kim                    " -newhdr        output \"NEW\" in the header lines\n");
434*6f9291ceSJung-uk Kim         BIO_printf(bio_err,
435*6f9291ceSJung-uk Kim                    " -asn1-kludge   Output the 'request' in a format that is wrong but some CA's\n");
436*6f9291ceSJung-uk Kim         BIO_printf(bio_err,
437*6f9291ceSJung-uk Kim                    "                have been reported as requiring\n");
438*6f9291ceSJung-uk Kim         BIO_printf(bio_err,
439*6f9291ceSJung-uk Kim                    " -extensions .. specify certificate extension section (override value in config file)\n");
440*6f9291ceSJung-uk Kim         BIO_printf(bio_err,
441*6f9291ceSJung-uk Kim                    " -reqexts ..    specify request extension section (override value in config file)\n");
442*6f9291ceSJung-uk Kim         BIO_printf(bio_err,
443*6f9291ceSJung-uk Kim                    " -utf8          input characters are UTF8 (default ASCII)\n");
444*6f9291ceSJung-uk Kim         BIO_printf(bio_err,
445*6f9291ceSJung-uk Kim                    " -nameopt arg    - various certificate name options\n");
446*6f9291ceSJung-uk Kim         BIO_printf(bio_err,
447*6f9291ceSJung-uk Kim                    " -reqopt arg    - various request text options\n\n");
44874664626SKris Kennaway         goto end;
44974664626SKris Kennaway     }
45074664626SKris Kennaway 
45174664626SKris Kennaway     ERR_load_crypto_strings();
452f579bf8eSKris Kennaway     if (!app_passwd(bio_err, passargin, passargout, &passin, &passout)) {
453f579bf8eSKris Kennaway         BIO_printf(bio_err, "Error getting passwords\n");
454f579bf8eSKris Kennaway         goto end;
455f579bf8eSKris Kennaway     }
456*6f9291ceSJung-uk Kim #ifndef MONOLITH                /* else this has happened in openssl.c
457*6f9291ceSJung-uk Kim                                  * (global `config') */
45874664626SKris Kennaway     /* Lets load up our environment a little */
45974664626SKris Kennaway     p = getenv("OPENSSL_CONF");
46074664626SKris Kennaway     if (p == NULL)
46174664626SKris Kennaway         p = getenv("SSLEAY_CONF");
46274664626SKris Kennaway     if (p == NULL)
4635c87c606SMark Murray         p = to_free = make_config_name();
46474664626SKris Kennaway     default_config_file = p;
4655c87c606SMark Murray     config = NCONF_new(NULL);
4665c87c606SMark Murray     i = NCONF_load(config, p, &errline);
46774664626SKris Kennaway #endif
46874664626SKris Kennaway 
469*6f9291ceSJung-uk Kim     if (template != NULL) {
4705c87c606SMark Murray         long errline = -1;
47174664626SKris Kennaway 
4725c87c606SMark Murray         if (verbose)
47374664626SKris Kennaway             BIO_printf(bio_err, "Using configuration from %s\n", template);
4745c87c606SMark Murray         req_conf = NCONF_new(NULL);
4755c87c606SMark Murray         i = NCONF_load(req_conf, template, &errline);
476*6f9291ceSJung-uk Kim         if (i == 0) {
477*6f9291ceSJung-uk Kim             BIO_printf(bio_err, "error on line %ld of %s\n", errline,
478*6f9291ceSJung-uk Kim                        template);
47974664626SKris Kennaway             goto end;
48074664626SKris Kennaway         }
481*6f9291ceSJung-uk Kim     } else {
48274664626SKris Kennaway         req_conf = config;
4833b4e3dcbSSimon L. B. Nielsen 
484*6f9291ceSJung-uk Kim         if (req_conf == NULL) {
485*6f9291ceSJung-uk Kim             BIO_printf(bio_err, "Unable to load config info from %s\n",
486*6f9291ceSJung-uk Kim                        default_config_file);
4873b4e3dcbSSimon L. B. Nielsen             if (newreq)
4883b4e3dcbSSimon L. B. Nielsen                 goto end;
489*6f9291ceSJung-uk Kim         } else if (verbose)
4903b4e3dcbSSimon L. B. Nielsen             BIO_printf(bio_err, "Using configuration from %s\n",
4913b4e3dcbSSimon L. B. Nielsen                        default_config_file);
49274664626SKris Kennaway     }
49374664626SKris Kennaway 
494*6f9291ceSJung-uk Kim     if (req_conf != NULL) {
4955c87c606SMark Murray         if (!load_config(bio_err, req_conf))
4965c87c606SMark Murray             goto end;
4975c87c606SMark Murray         p = NCONF_get_string(req_conf, NULL, "oid_file");
4985c87c606SMark Murray         if (p == NULL)
4995c87c606SMark Murray             ERR_clear_error();
500*6f9291ceSJung-uk Kim         if (p != NULL) {
50174664626SKris Kennaway             BIO *oid_bio;
50274664626SKris Kennaway 
50374664626SKris Kennaway             oid_bio = BIO_new_file(p, "r");
504*6f9291ceSJung-uk Kim             if (oid_bio == NULL) {
505*6f9291ceSJung-uk Kim                 /*-
50674664626SKris Kennaway                 BIO_printf(bio_err,"problems opening %s for extra oid's\n",p);
50774664626SKris Kennaway                 ERR_print_errors(bio_err);
50874664626SKris Kennaway                 */
509*6f9291ceSJung-uk Kim             } else {
51074664626SKris Kennaway                 OBJ_create_objects(oid_bio);
51174664626SKris Kennaway                 BIO_free(oid_bio);
51274664626SKris Kennaway             }
51374664626SKris Kennaway         }
51474664626SKris Kennaway     }
515*6f9291ceSJung-uk Kim     if (!add_oid_section(bio_err, req_conf))
516*6f9291ceSJung-uk Kim         goto end;
51774664626SKris Kennaway 
518*6f9291ceSJung-uk Kim     if (md_alg == NULL) {
5195c87c606SMark Murray         p = NCONF_get_string(req_conf, SECTION, "default_md");
5205c87c606SMark Murray         if (p == NULL)
5215c87c606SMark Murray             ERR_clear_error();
522*6f9291ceSJung-uk Kim         if (p != NULL) {
52374664626SKris Kennaway             if ((md_alg = EVP_get_digestbyname(p)) != NULL)
52474664626SKris Kennaway                 digest = md_alg;
52574664626SKris Kennaway         }
5265c87c606SMark Murray     }
52774664626SKris Kennaway 
528*6f9291ceSJung-uk Kim     if (!extensions) {
5295c87c606SMark Murray         extensions = NCONF_get_string(req_conf, SECTION, V3_EXTENSIONS);
5305c87c606SMark Murray         if (!extensions)
5315c87c606SMark Murray             ERR_clear_error();
5325c87c606SMark Murray     }
53374664626SKris Kennaway     if (extensions) {
53474664626SKris Kennaway         /* Check syntax of file */
53574664626SKris Kennaway         X509V3_CTX ctx;
53674664626SKris Kennaway         X509V3_set_ctx_test(&ctx);
5375c87c606SMark Murray         X509V3_set_nconf(&ctx, req_conf);
5385c87c606SMark Murray         if (!X509V3_EXT_add_nconf(req_conf, &ctx, extensions, NULL)) {
53974664626SKris Kennaway             BIO_printf(bio_err,
54074664626SKris Kennaway                        "Error Loading extension section %s\n", extensions);
54174664626SKris Kennaway             goto end;
54274664626SKris Kennaway         }
54374664626SKris Kennaway     }
54474664626SKris Kennaway 
545*6f9291ceSJung-uk Kim     if (!passin) {
5465c87c606SMark Murray         passin = NCONF_get_string(req_conf, SECTION, "input_password");
5475c87c606SMark Murray         if (!passin)
5485c87c606SMark Murray             ERR_clear_error();
5495c87c606SMark Murray     }
550f579bf8eSKris Kennaway 
551*6f9291ceSJung-uk Kim     if (!passout) {
5525c87c606SMark Murray         passout = NCONF_get_string(req_conf, SECTION, "output_password");
5535c87c606SMark Murray         if (!passout)
5545c87c606SMark Murray             ERR_clear_error();
5555c87c606SMark Murray     }
556f579bf8eSKris Kennaway 
5575c87c606SMark Murray     p = NCONF_get_string(req_conf, SECTION, STRING_MASK);
5585c87c606SMark Murray     if (!p)
5595c87c606SMark Murray         ERR_clear_error();
560f579bf8eSKris Kennaway 
561f579bf8eSKris Kennaway     if (p && !ASN1_STRING_set_default_mask_asc(p)) {
562f579bf8eSKris Kennaway         BIO_printf(bio_err, "Invalid global string mask setting %s\n", p);
563f579bf8eSKris Kennaway         goto end;
564f579bf8eSKris Kennaway     }
565f579bf8eSKris Kennaway 
566*6f9291ceSJung-uk Kim     if (chtype != MBSTRING_UTF8) {
5675c87c606SMark Murray         p = NCONF_get_string(req_conf, SECTION, UTF8_IN);
5685c87c606SMark Murray         if (!p)
5695c87c606SMark Murray             ERR_clear_error();
5705c87c606SMark Murray         else if (!strcmp(p, "yes"))
5715c87c606SMark Murray             chtype = MBSTRING_UTF8;
5725c87c606SMark Murray     }
5735c87c606SMark Murray 
574*6f9291ceSJung-uk Kim     if (!req_exts) {
5755c87c606SMark Murray         req_exts = NCONF_get_string(req_conf, SECTION, REQ_EXTENSIONS);
5765c87c606SMark Murray         if (!req_exts)
5775c87c606SMark Murray             ERR_clear_error();
5785c87c606SMark Murray     }
579f579bf8eSKris Kennaway     if (req_exts) {
580f579bf8eSKris Kennaway         /* Check syntax of file */
581f579bf8eSKris Kennaway         X509V3_CTX ctx;
582f579bf8eSKris Kennaway         X509V3_set_ctx_test(&ctx);
5835c87c606SMark Murray         X509V3_set_nconf(&ctx, req_conf);
5845c87c606SMark Murray         if (!X509V3_EXT_add_nconf(req_conf, &ctx, req_exts, NULL)) {
585f579bf8eSKris Kennaway             BIO_printf(bio_err,
586f579bf8eSKris Kennaway                        "Error Loading request extension section %s\n",
587f579bf8eSKris Kennaway                        req_exts);
588f579bf8eSKris Kennaway             goto end;
589f579bf8eSKris Kennaway         }
590f579bf8eSKris Kennaway     }
591f579bf8eSKris Kennaway 
59274664626SKris Kennaway     in = BIO_new(BIO_s_file());
59374664626SKris Kennaway     out = BIO_new(BIO_s_file());
59474664626SKris Kennaway     if ((in == NULL) || (out == NULL))
59574664626SKris Kennaway         goto end;
59674664626SKris Kennaway 
597fceca8a3SJacques Vidrine #ifndef OPENSSL_NO_ENGINE
5985c87c606SMark Murray     e = setup_engine(bio_err, engine, 0);
599fceca8a3SJacques Vidrine #endif
6005c87c606SMark Murray 
601*6f9291ceSJung-uk Kim     if (keyfile != NULL) {
6025c87c606SMark Murray         pkey = load_key(bio_err, keyfile, keyform, 0, passin, e,
6035c87c606SMark Murray                         "Private Key");
604*6f9291ceSJung-uk Kim         if (!pkey) {
605*6f9291ceSJung-uk Kim             /*
606*6f9291ceSJung-uk Kim              * load_key() has already printed an appropriate message
607*6f9291ceSJung-uk Kim              */
60874664626SKris Kennaway             goto end;
609*6f9291ceSJung-uk Kim         } else {
6105c87c606SMark Murray             char *randfile = NCONF_get_string(req_conf, SECTION, "RANDFILE");
6115c87c606SMark Murray             if (randfile == NULL)
6125c87c606SMark Murray                 ERR_clear_error();
613ddd58736SKris Kennaway             app_RAND_load_file(randfile, bio_err, 0);
614ddd58736SKris Kennaway         }
61574664626SKris Kennaway     }
61674664626SKris Kennaway 
617*6f9291ceSJung-uk Kim     if (newreq && (pkey == NULL)) {
6185c87c606SMark Murray         char *randfile = NCONF_get_string(req_conf, SECTION, "RANDFILE");
6195c87c606SMark Murray         if (randfile == NULL)
6205c87c606SMark Murray             ERR_clear_error();
621f579bf8eSKris Kennaway         app_RAND_load_file(randfile, bio_err, 0);
622ddd58736SKris Kennaway         if (inrand)
623ddd58736SKris Kennaway             app_RAND_load_files(inrand);
62474664626SKris Kennaway 
625*6f9291ceSJung-uk Kim         if (!NCONF_get_number(req_conf, SECTION, BITS, &newkey)) {
626560ede85SJung-uk Kim             newkey = DEFAULT_KEY_LENGTH;
627560ede85SJung-uk Kim         }
628560ede85SJung-uk Kim 
629*6f9291ceSJung-uk Kim         if (keyalg) {
6301f13597dSJung-uk Kim             genctx = set_keygen_ctx(bio_err, keyalg, &pkey_type, &newkey,
6311f13597dSJung-uk Kim                                     &keyalgstr, gen_eng);
6321f13597dSJung-uk Kim             if (!genctx)
6331f13597dSJung-uk Kim                 goto end;
6341f13597dSJung-uk Kim         }
6351f13597dSJung-uk Kim 
636*6f9291ceSJung-uk Kim         if (newkey < MIN_KEY_LENGTH
637*6f9291ceSJung-uk Kim             && (pkey_type == EVP_PKEY_RSA || pkey_type == EVP_PKEY_DSA)) {
63874664626SKris Kennaway             BIO_printf(bio_err, "private key length is too short,\n");
639*6f9291ceSJung-uk Kim             BIO_printf(bio_err, "it needs to be at least %d bits, not %ld\n",
640*6f9291ceSJung-uk Kim                        MIN_KEY_LENGTH, newkey);
64174664626SKris Kennaway             goto end;
64274664626SKris Kennaway         }
6431f13597dSJung-uk Kim 
644*6f9291ceSJung-uk Kim         if (!genctx) {
6451f13597dSJung-uk Kim             genctx = set_keygen_ctx(bio_err, NULL, &pkey_type, &newkey,
6461f13597dSJung-uk Kim                                     &keyalgstr, gen_eng);
6471f13597dSJung-uk Kim             if (!genctx)
6481f13597dSJung-uk Kim                 goto end;
6491f13597dSJung-uk Kim         }
6501f13597dSJung-uk Kim 
651*6f9291ceSJung-uk Kim         if (pkeyopts) {
6521f13597dSJung-uk Kim             char *genopt;
653*6f9291ceSJung-uk Kim             for (i = 0; i < sk_OPENSSL_STRING_num(pkeyopts); i++) {
6541f13597dSJung-uk Kim                 genopt = sk_OPENSSL_STRING_value(pkeyopts, i);
655*6f9291ceSJung-uk Kim                 if (pkey_ctrl_string(genctx, genopt) <= 0) {
656*6f9291ceSJung-uk Kim                     BIO_printf(bio_err, "parameter error \"%s\"\n", genopt);
6571f13597dSJung-uk Kim                     ERR_print_errors(bio_err);
6581f13597dSJung-uk Kim                     goto end;
6591f13597dSJung-uk Kim                 }
6601f13597dSJung-uk Kim             }
6611f13597dSJung-uk Kim         }
6621f13597dSJung-uk Kim 
6633b4e3dcbSSimon L. B. Nielsen         BIO_printf(bio_err, "Generating a %ld bit %s private key\n",
6641f13597dSJung-uk Kim                    newkey, keyalgstr);
66574664626SKris Kennaway 
6661f13597dSJung-uk Kim         EVP_PKEY_CTX_set_cb(genctx, genpkey_cb);
6671f13597dSJung-uk Kim         EVP_PKEY_CTX_set_app_data(genctx, bio_err);
66874664626SKris Kennaway 
669*6f9291ceSJung-uk Kim         if (EVP_PKEY_keygen(genctx, &pkey) <= 0) {
6701f13597dSJung-uk Kim             BIO_puts(bio_err, "Error Generating Key\n");
67174664626SKris Kennaway             goto end;
67274664626SKris Kennaway         }
6731f13597dSJung-uk Kim 
6741f13597dSJung-uk Kim         EVP_PKEY_CTX_free(genctx);
6751f13597dSJung-uk Kim         genctx = NULL;
67674664626SKris Kennaway 
677f579bf8eSKris Kennaway         app_RAND_write_file(randfile, bio_err);
67874664626SKris Kennaway 
679*6f9291ceSJung-uk Kim         if (keyout == NULL) {
6805c87c606SMark Murray             keyout = NCONF_get_string(req_conf, SECTION, KEYFILE);
6815c87c606SMark Murray             if (keyout == NULL)
6825c87c606SMark Murray                 ERR_clear_error();
6835c87c606SMark Murray         }
68474664626SKris Kennaway 
685*6f9291ceSJung-uk Kim         if (keyout == NULL) {
68674664626SKris Kennaway             BIO_printf(bio_err, "writing new private key to stdout\n");
68774664626SKris Kennaway             BIO_set_fp(out, stdout, BIO_NOCLOSE);
6885c87c606SMark Murray #ifdef OPENSSL_SYS_VMS
689ddd58736SKris Kennaway             {
690ddd58736SKris Kennaway                 BIO *tmpbio = BIO_new(BIO_f_linebuffer());
691ddd58736SKris Kennaway                 out = BIO_push(tmpbio, out);
692ddd58736SKris Kennaway             }
693ddd58736SKris Kennaway #endif
694*6f9291ceSJung-uk Kim         } else {
69574664626SKris Kennaway             BIO_printf(bio_err, "writing new private key to '%s'\n", keyout);
696*6f9291ceSJung-uk Kim             if (BIO_write_filename(out, keyout) <= 0) {
69774664626SKris Kennaway                 perror(keyout);
69874664626SKris Kennaway                 goto end;
69974664626SKris Kennaway             }
70074664626SKris Kennaway         }
70174664626SKris Kennaway 
7025c87c606SMark Murray         p = NCONF_get_string(req_conf, SECTION, "encrypt_rsa_key");
703*6f9291ceSJung-uk Kim         if (p == NULL) {
7045c87c606SMark Murray             ERR_clear_error();
7055c87c606SMark Murray             p = NCONF_get_string(req_conf, SECTION, "encrypt_key");
7065c87c606SMark Murray             if (p == NULL)
7075c87c606SMark Murray                 ERR_clear_error();
7085c87c606SMark Murray         }
70974664626SKris Kennaway         if ((p != NULL) && (strcmp(p, "no") == 0))
71074664626SKris Kennaway             cipher = NULL;
711*6f9291ceSJung-uk Kim         if (nodes)
712*6f9291ceSJung-uk Kim             cipher = NULL;
71374664626SKris Kennaway 
71474664626SKris Kennaway         i = 0;
71574664626SKris Kennaway  loop:
71674664626SKris Kennaway         if (!PEM_write_bio_PrivateKey(out, pkey, cipher,
717*6f9291ceSJung-uk Kim                                       NULL, 0, NULL, passout)) {
71874664626SKris Kennaway             if ((ERR_GET_REASON(ERR_peek_error()) ==
719*6f9291ceSJung-uk Kim                  PEM_R_PROBLEMS_GETTING_PASSWORD) && (i < 3)) {
72074664626SKris Kennaway                 ERR_clear_error();
72174664626SKris Kennaway                 i++;
72274664626SKris Kennaway                 goto loop;
72374664626SKris Kennaway             }
72474664626SKris Kennaway             goto end;
72574664626SKris Kennaway         }
72674664626SKris Kennaway         BIO_printf(bio_err, "-----\n");
72774664626SKris Kennaway     }
72874664626SKris Kennaway 
729*6f9291ceSJung-uk Kim     if (!newreq) {
730*6f9291ceSJung-uk Kim         /*
731*6f9291ceSJung-uk Kim          * Since we are using a pre-existing certificate request, the kludge
732*6f9291ceSJung-uk Kim          * 'format' info should not be changed.
733*6f9291ceSJung-uk Kim          */
73474664626SKris Kennaway         kludge = -1;
73574664626SKris Kennaway         if (infile == NULL)
73674664626SKris Kennaway             BIO_set_fp(in, stdin, BIO_NOCLOSE);
737*6f9291ceSJung-uk Kim         else {
738*6f9291ceSJung-uk Kim             if (BIO_read_filename(in, infile) <= 0) {
73974664626SKris Kennaway                 perror(infile);
74074664626SKris Kennaway                 goto end;
74174664626SKris Kennaway             }
74274664626SKris Kennaway         }
74374664626SKris Kennaway 
74474664626SKris Kennaway         if (informat == FORMAT_ASN1)
74574664626SKris Kennaway             req = d2i_X509_REQ_bio(in, NULL);
74674664626SKris Kennaway         else if (informat == FORMAT_PEM)
74774664626SKris Kennaway             req = PEM_read_bio_X509_REQ(in, NULL, NULL, NULL);
748*6f9291ceSJung-uk Kim         else {
749*6f9291ceSJung-uk Kim             BIO_printf(bio_err,
750*6f9291ceSJung-uk Kim                        "bad input format specified for X509 request\n");
75174664626SKris Kennaway             goto end;
75274664626SKris Kennaway         }
753*6f9291ceSJung-uk Kim         if (req == NULL) {
75474664626SKris Kennaway             BIO_printf(bio_err, "unable to load X509 request\n");
75574664626SKris Kennaway             goto end;
75674664626SKris Kennaway         }
75774664626SKris Kennaway     }
75874664626SKris Kennaway 
759*6f9291ceSJung-uk Kim     if (newreq || x509) {
760*6f9291ceSJung-uk Kim         if (pkey == NULL) {
76174664626SKris Kennaway             BIO_printf(bio_err, "you need to specify a private key\n");
76274664626SKris Kennaway             goto end;
76374664626SKris Kennaway         }
7641f13597dSJung-uk Kim 
765*6f9291ceSJung-uk Kim         if (req == NULL) {
76674664626SKris Kennaway             req = X509_REQ_new();
767*6f9291ceSJung-uk Kim             if (req == NULL) {
76874664626SKris Kennaway                 goto end;
76974664626SKris Kennaway             }
77074664626SKris Kennaway 
7713b4e3dcbSSimon L. B. Nielsen             i = make_REQ(req, pkey, subj, multirdn, !x509, chtype);
7725c87c606SMark Murray             subj = NULL;        /* done processing '-subj' option */
773*6f9291ceSJung-uk Kim             if ((kludge > 0)
774*6f9291ceSJung-uk Kim                 && !sk_X509_ATTRIBUTE_num(req->req_info->attributes)) {
7755c87c606SMark Murray                 sk_X509_ATTRIBUTE_free(req->req_info->attributes);
7765c87c606SMark Murray                 req->req_info->attributes = NULL;
7775c87c606SMark Murray             }
778*6f9291ceSJung-uk Kim             if (!i) {
77974664626SKris Kennaway                 BIO_printf(bio_err, "problems making Certificate Request\n");
78074664626SKris Kennaway                 goto end;
78174664626SKris Kennaway             }
78274664626SKris Kennaway         }
783*6f9291ceSJung-uk Kim         if (x509) {
78474664626SKris Kennaway             EVP_PKEY *tmppkey;
78574664626SKris Kennaway             X509V3_CTX ext_ctx;
786*6f9291ceSJung-uk Kim             if ((x509ss = X509_new()) == NULL)
787*6f9291ceSJung-uk Kim                 goto end;
78874664626SKris Kennaway 
78974664626SKris Kennaway             /* Set version to V3 */
790*6f9291ceSJung-uk Kim             if (extensions && !X509_set_version(x509ss, 2))
791*6f9291ceSJung-uk Kim                 goto end;
792*6f9291ceSJung-uk Kim             if (serial) {
793*6f9291ceSJung-uk Kim                 if (!X509_set_serialNumber(x509ss, serial))
794*6f9291ceSJung-uk Kim                     goto end;
795*6f9291ceSJung-uk Kim             } else {
796*6f9291ceSJung-uk Kim                 if (!rand_serial(NULL, X509_get_serialNumber(x509ss)))
7976be8ae07SJacques Vidrine                     goto end;
7985c87c606SMark Murray             }
79974664626SKris Kennaway 
800*6f9291ceSJung-uk Kim             if (!X509_set_issuer_name(x509ss, X509_REQ_get_subject_name(req)))
801*6f9291ceSJung-uk Kim                 goto end;
802*6f9291ceSJung-uk Kim             if (!X509_gmtime_adj(X509_get_notBefore(x509ss), 0))
803*6f9291ceSJung-uk Kim                 goto end;
804*6f9291ceSJung-uk Kim             if (!X509_time_adj_ex(X509_get_notAfter(x509ss), days, 0, NULL))
805*6f9291ceSJung-uk Kim                 goto end;
806*6f9291ceSJung-uk Kim             if (!X509_set_subject_name
807*6f9291ceSJung-uk Kim                 (x509ss, X509_REQ_get_subject_name(req)))
808*6f9291ceSJung-uk Kim                 goto end;
80974664626SKris Kennaway             tmppkey = X509_REQ_get_pubkey(req);
810*6f9291ceSJung-uk Kim             if (!tmppkey || !X509_set_pubkey(x509ss, tmppkey))
811*6f9291ceSJung-uk Kim                 goto end;
81274664626SKris Kennaway             EVP_PKEY_free(tmppkey);
81374664626SKris Kennaway 
81474664626SKris Kennaway             /* Set up V3 context struct */
81574664626SKris Kennaway 
81674664626SKris Kennaway             X509V3_set_ctx(&ext_ctx, x509ss, x509ss, NULL, NULL, 0);
8175c87c606SMark Murray             X509V3_set_nconf(&ext_ctx, req_conf);
81874664626SKris Kennaway 
81974664626SKris Kennaway             /* Add extensions */
8205c87c606SMark Murray             if (extensions && !X509V3_EXT_add_nconf(req_conf,
821*6f9291ceSJung-uk Kim                                                     &ext_ctx, extensions,
822*6f9291ceSJung-uk Kim                                                     x509ss)) {
823*6f9291ceSJung-uk Kim                 BIO_printf(bio_err, "Error Loading extension section %s\n",
82474664626SKris Kennaway                            extensions);
82574664626SKris Kennaway                 goto end;
82674664626SKris Kennaway             }
82774664626SKris Kennaway 
8281f13597dSJung-uk Kim             i = do_X509_sign(bio_err, x509ss, pkey, digest, sigopts);
829*6f9291ceSJung-uk Kim             if (!i) {
8301f13597dSJung-uk Kim                 ERR_print_errors(bio_err);
83174664626SKris Kennaway                 goto end;
83274664626SKris Kennaway             }
833*6f9291ceSJung-uk Kim         } else {
834f579bf8eSKris Kennaway             X509V3_CTX ext_ctx;
835f579bf8eSKris Kennaway 
836f579bf8eSKris Kennaway             /* Set up V3 context struct */
837f579bf8eSKris Kennaway 
838f579bf8eSKris Kennaway             X509V3_set_ctx(&ext_ctx, NULL, NULL, req, NULL, 0);
8395c87c606SMark Murray             X509V3_set_nconf(&ext_ctx, req_conf);
840f579bf8eSKris Kennaway 
841f579bf8eSKris Kennaway             /* Add extensions */
8425c87c606SMark Murray             if (req_exts && !X509V3_EXT_REQ_add_nconf(req_conf,
843*6f9291ceSJung-uk Kim                                                       &ext_ctx, req_exts,
844*6f9291ceSJung-uk Kim                                                       req)) {
845*6f9291ceSJung-uk Kim                 BIO_printf(bio_err, "Error Loading extension section %s\n",
846f579bf8eSKris Kennaway                            req_exts);
847f579bf8eSKris Kennaway                 goto end;
848f579bf8eSKris Kennaway             }
8491f13597dSJung-uk Kim             i = do_X509_REQ_sign(bio_err, req, pkey, digest, sigopts);
850*6f9291ceSJung-uk Kim             if (!i) {
8511f13597dSJung-uk Kim                 ERR_print_errors(bio_err);
85274664626SKris Kennaway                 goto end;
85374664626SKris Kennaway             }
85474664626SKris Kennaway         }
8551f13597dSJung-uk Kim     }
85674664626SKris Kennaway 
857*6f9291ceSJung-uk Kim     if (subj && x509) {
8585c87c606SMark Murray         BIO_printf(bio_err, "Cannot modifiy certificate subject\n");
8595c87c606SMark Murray         goto end;
8605c87c606SMark Murray     }
8615c87c606SMark Murray 
862*6f9291ceSJung-uk Kim     if (subj && !x509) {
863*6f9291ceSJung-uk Kim         if (verbose) {
8645c87c606SMark Murray             BIO_printf(bio_err, "Modifying Request's Subject\n");
865*6f9291ceSJung-uk Kim             print_name(bio_err, "old subject=",
866*6f9291ceSJung-uk Kim                        X509_REQ_get_subject_name(req), nmflag);
8675c87c606SMark Murray         }
8685c87c606SMark Murray 
869*6f9291ceSJung-uk Kim         if (build_subject(req, subj, chtype, multirdn) == 0) {
8705c87c606SMark Murray             BIO_printf(bio_err, "ERROR: cannot modify subject\n");
8715c87c606SMark Murray             ex = 1;
8725c87c606SMark Murray             goto end;
8735c87c606SMark Murray         }
8745c87c606SMark Murray 
8755c87c606SMark Murray         req->req_info->enc.modified = 1;
8765c87c606SMark Murray 
877*6f9291ceSJung-uk Kim         if (verbose) {
878*6f9291ceSJung-uk Kim             print_name(bio_err, "new subject=",
879*6f9291ceSJung-uk Kim                        X509_REQ_get_subject_name(req), nmflag);
8805c87c606SMark Murray         }
8815c87c606SMark Murray     }
8825c87c606SMark Murray 
883*6f9291ceSJung-uk Kim     if (verify && !x509) {
88474664626SKris Kennaway         int tmp = 0;
88574664626SKris Kennaway 
886*6f9291ceSJung-uk Kim         if (pkey == NULL) {
88774664626SKris Kennaway             pkey = X509_REQ_get_pubkey(req);
88874664626SKris Kennaway             tmp = 1;
889*6f9291ceSJung-uk Kim             if (pkey == NULL)
890*6f9291ceSJung-uk Kim                 goto end;
89174664626SKris Kennaway         }
89274664626SKris Kennaway 
89374664626SKris Kennaway         i = X509_REQ_verify(req, pkey);
89474664626SKris Kennaway         if (tmp) {
89574664626SKris Kennaway             EVP_PKEY_free(pkey);
89674664626SKris Kennaway             pkey = NULL;
89774664626SKris Kennaway         }
89874664626SKris Kennaway 
899*6f9291ceSJung-uk Kim         if (i < 0) {
90074664626SKris Kennaway             goto end;
901*6f9291ceSJung-uk Kim         } else if (i == 0) {
90274664626SKris Kennaway             BIO_printf(bio_err, "verify failure\n");
9035c87c606SMark Murray             ERR_print_errors(bio_err);
904*6f9291ceSJung-uk Kim         } else                  /* if (i > 0) */
90574664626SKris Kennaway             BIO_printf(bio_err, "verify OK\n");
90674664626SKris Kennaway     }
90774664626SKris Kennaway 
908*6f9291ceSJung-uk Kim     if (noout && !text && !modulus && !subject && !pubkey) {
90974664626SKris Kennaway         ex = 0;
91074664626SKris Kennaway         goto end;
91174664626SKris Kennaway     }
91274664626SKris Kennaway 
913*6f9291ceSJung-uk Kim     if (outfile == NULL) {
91474664626SKris Kennaway         BIO_set_fp(out, stdout, BIO_NOCLOSE);
9155c87c606SMark Murray #ifdef OPENSSL_SYS_VMS
916ddd58736SKris Kennaway         {
917ddd58736SKris Kennaway             BIO *tmpbio = BIO_new(BIO_f_linebuffer());
918ddd58736SKris Kennaway             out = BIO_push(tmpbio, out);
919ddd58736SKris Kennaway         }
920ddd58736SKris Kennaway #endif
921*6f9291ceSJung-uk Kim     } else {
92274664626SKris Kennaway         if ((keyout != NULL) && (strcmp(outfile, keyout) == 0))
92374664626SKris Kennaway             i = (int)BIO_append_filename(out, outfile);
92474664626SKris Kennaway         else
92574664626SKris Kennaway             i = (int)BIO_write_filename(out, outfile);
926*6f9291ceSJung-uk Kim         if (!i) {
92774664626SKris Kennaway             perror(outfile);
92874664626SKris Kennaway             goto end;
92974664626SKris Kennaway         }
93074664626SKris Kennaway     }
93174664626SKris Kennaway 
932*6f9291ceSJung-uk Kim     if (pubkey) {
9335c87c606SMark Murray         EVP_PKEY *tpubkey;
9345c87c606SMark Murray         tpubkey = X509_REQ_get_pubkey(req);
935*6f9291ceSJung-uk Kim         if (tpubkey == NULL) {
9365c87c606SMark Murray             BIO_printf(bio_err, "Error getting public key\n");
9375c87c606SMark Murray             ERR_print_errors(bio_err);
9385c87c606SMark Murray             goto end;
9395c87c606SMark Murray         }
9405c87c606SMark Murray         PEM_write_bio_PUBKEY(out, tpubkey);
9415c87c606SMark Murray         EVP_PKEY_free(tpubkey);
9425c87c606SMark Murray     }
9435c87c606SMark Murray 
944*6f9291ceSJung-uk Kim     if (text) {
94574664626SKris Kennaway         if (x509)
9465c87c606SMark Murray             X509_print_ex(out, x509ss, nmflag, reqflag);
94774664626SKris Kennaway         else
9485c87c606SMark Murray             X509_REQ_print_ex(out, req, nmflag, reqflag);
9495c87c606SMark Murray     }
9505c87c606SMark Murray 
951*6f9291ceSJung-uk Kim     if (subject) {
9525c87c606SMark Murray         if (x509)
953*6f9291ceSJung-uk Kim             print_name(out, "subject=", X509_get_subject_name(x509ss),
954*6f9291ceSJung-uk Kim                        nmflag);
9555c87c606SMark Murray         else
956*6f9291ceSJung-uk Kim             print_name(out, "subject=", X509_REQ_get_subject_name(req),
957*6f9291ceSJung-uk Kim                        nmflag);
95874664626SKris Kennaway     }
95974664626SKris Kennaway 
960*6f9291ceSJung-uk Kim     if (modulus) {
9615c87c606SMark Murray         EVP_PKEY *tpubkey;
96274664626SKris Kennaway 
96374664626SKris Kennaway         if (x509)
9645c87c606SMark Murray             tpubkey = X509_get_pubkey(x509ss);
96574664626SKris Kennaway         else
9665c87c606SMark Murray             tpubkey = X509_REQ_get_pubkey(req);
967*6f9291ceSJung-uk Kim         if (tpubkey == NULL) {
96874664626SKris Kennaway             fprintf(stdout, "Modulus=unavailable\n");
96974664626SKris Kennaway             goto end;
97074664626SKris Kennaway         }
97174664626SKris Kennaway         fprintf(stdout, "Modulus=");
9725c87c606SMark Murray #ifndef OPENSSL_NO_RSA
9731f13597dSJung-uk Kim         if (EVP_PKEY_base_id(tpubkey) == EVP_PKEY_RSA)
9745c87c606SMark Murray             BN_print(out, tpubkey->pkey.rsa->n);
97574664626SKris Kennaway         else
97674664626SKris Kennaway #endif
97774664626SKris Kennaway             fprintf(stdout, "Wrong Algorithm type");
9785c87c606SMark Murray         EVP_PKEY_free(tpubkey);
97974664626SKris Kennaway         fprintf(stdout, "\n");
98074664626SKris Kennaway     }
98174664626SKris Kennaway 
982*6f9291ceSJung-uk Kim     if (!noout && !x509) {
98374664626SKris Kennaway         if (outformat == FORMAT_ASN1)
98474664626SKris Kennaway             i = i2d_X509_REQ_bio(out, req);
985f579bf8eSKris Kennaway         else if (outformat == FORMAT_PEM) {
986*6f9291ceSJung-uk Kim             if (newhdr)
987*6f9291ceSJung-uk Kim                 i = PEM_write_bio_X509_REQ_NEW(out, req);
988*6f9291ceSJung-uk Kim             else
989*6f9291ceSJung-uk Kim                 i = PEM_write_bio_X509_REQ(out, req);
990f579bf8eSKris Kennaway         } else {
99174664626SKris Kennaway             BIO_printf(bio_err, "bad output format specified for outfile\n");
99274664626SKris Kennaway             goto end;
99374664626SKris Kennaway         }
994*6f9291ceSJung-uk Kim         if (!i) {
99574664626SKris Kennaway             BIO_printf(bio_err, "unable to write X509 request\n");
99674664626SKris Kennaway             goto end;
99774664626SKris Kennaway         }
99874664626SKris Kennaway     }
999*6f9291ceSJung-uk Kim     if (!noout && x509 && (x509ss != NULL)) {
100074664626SKris Kennaway         if (outformat == FORMAT_ASN1)
100174664626SKris Kennaway             i = i2d_X509_bio(out, x509ss);
100274664626SKris Kennaway         else if (outformat == FORMAT_PEM)
100374664626SKris Kennaway             i = PEM_write_bio_X509(out, x509ss);
100474664626SKris Kennaway         else {
100574664626SKris Kennaway             BIO_printf(bio_err, "bad output format specified for outfile\n");
100674664626SKris Kennaway             goto end;
100774664626SKris Kennaway         }
1008*6f9291ceSJung-uk Kim         if (!i) {
100974664626SKris Kennaway             BIO_printf(bio_err, "unable to write X509 certificate\n");
101074664626SKris Kennaway             goto end;
101174664626SKris Kennaway         }
101274664626SKris Kennaway     }
101374664626SKris Kennaway     ex = 0;
101474664626SKris Kennaway  end:
10155c87c606SMark Murray #ifndef MONOLITH
10165c87c606SMark Murray     if (to_free)
10175c87c606SMark Murray         OPENSSL_free(to_free);
10185c87c606SMark Murray #endif
1019*6f9291ceSJung-uk Kim     if (ex) {
102074664626SKris Kennaway         ERR_print_errors(bio_err);
102174664626SKris Kennaway     }
1022*6f9291ceSJung-uk Kim     if ((req_conf != NULL) && (req_conf != config))
1023*6f9291ceSJung-uk Kim         NCONF_free(req_conf);
102474664626SKris Kennaway     BIO_free(in);
1025ddd58736SKris Kennaway     BIO_free_all(out);
102674664626SKris Kennaway     EVP_PKEY_free(pkey);
10271f13597dSJung-uk Kim     if (genctx)
10281f13597dSJung-uk Kim         EVP_PKEY_CTX_free(genctx);
10291f13597dSJung-uk Kim     if (pkeyopts)
10301f13597dSJung-uk Kim         sk_OPENSSL_STRING_free(pkeyopts);
10311f13597dSJung-uk Kim     if (sigopts)
10321f13597dSJung-uk Kim         sk_OPENSSL_STRING_free(sigopts);
10331f13597dSJung-uk Kim #ifndef OPENSSL_NO_ENGINE
10341f13597dSJung-uk Kim     if (gen_eng)
10351f13597dSJung-uk Kim         ENGINE_free(gen_eng);
10361f13597dSJung-uk Kim #endif
10371f13597dSJung-uk Kim     if (keyalgstr)
10381f13597dSJung-uk Kim         OPENSSL_free(keyalgstr);
103974664626SKris Kennaway     X509_REQ_free(req);
104074664626SKris Kennaway     X509_free(x509ss);
10415c87c606SMark Murray     ASN1_INTEGER_free(serial);
1042*6f9291ceSJung-uk Kim     if (passargin && passin)
1043*6f9291ceSJung-uk Kim         OPENSSL_free(passin);
1044*6f9291ceSJung-uk Kim     if (passargout && passout)
1045*6f9291ceSJung-uk Kim         OPENSSL_free(passout);
104674664626SKris Kennaway     OBJ_cleanup();
10475c87c606SMark Murray     apps_shutdown();
10485c87c606SMark Murray     OPENSSL_EXIT(ex);
104974664626SKris Kennaway }
105074664626SKris Kennaway 
10513b4e3dcbSSimon L. B. Nielsen static int make_REQ(X509_REQ *req, EVP_PKEY *pkey, char *subj, int multirdn,
10523b4e3dcbSSimon L. B. Nielsen                     int attribs, unsigned long chtype)
105374664626SKris Kennaway {
105474664626SKris Kennaway     int ret = 0, i;
1055f579bf8eSKris Kennaway     char no_prompt = 0;
1056f579bf8eSKris Kennaway     STACK_OF(CONF_VALUE) *dn_sk, *attr_sk = NULL;
1057f579bf8eSKris Kennaway     char *tmp, *dn_sect, *attr_sect;
105874664626SKris Kennaway 
10595c87c606SMark Murray     tmp = NCONF_get_string(req_conf, SECTION, PROMPT);
10605c87c606SMark Murray     if (tmp == NULL)
10615c87c606SMark Murray         ERR_clear_error();
1062*6f9291ceSJung-uk Kim     if ((tmp != NULL) && !strcmp(tmp, "no"))
1063*6f9291ceSJung-uk Kim         no_prompt = 1;
1064f579bf8eSKris Kennaway 
10655c87c606SMark Murray     dn_sect = NCONF_get_string(req_conf, SECTION, DISTINGUISHED_NAME);
1066*6f9291ceSJung-uk Kim     if (dn_sect == NULL) {
106774664626SKris Kennaway         BIO_printf(bio_err, "unable to find '%s' in config\n",
106874664626SKris Kennaway                    DISTINGUISHED_NAME);
106974664626SKris Kennaway         goto err;
107074664626SKris Kennaway     }
10715c87c606SMark Murray     dn_sk = NCONF_get_section(req_conf, dn_sect);
1072*6f9291ceSJung-uk Kim     if (dn_sk == NULL) {
1073f579bf8eSKris Kennaway         BIO_printf(bio_err, "unable to get '%s' section\n", dn_sect);
107474664626SKris Kennaway         goto err;
107574664626SKris Kennaway     }
107674664626SKris Kennaway 
10775c87c606SMark Murray     attr_sect = NCONF_get_string(req_conf, SECTION, ATTRIBUTES);
1078*6f9291ceSJung-uk Kim     if (attr_sect == NULL) {
10795c87c606SMark Murray         ERR_clear_error();
1080f579bf8eSKris Kennaway         attr_sk = NULL;
1081*6f9291ceSJung-uk Kim     } else {
10825c87c606SMark Murray         attr_sk = NCONF_get_section(req_conf, attr_sect);
1083*6f9291ceSJung-uk Kim         if (attr_sk == NULL) {
1084f579bf8eSKris Kennaway             BIO_printf(bio_err, "unable to get '%s' section\n", attr_sect);
108574664626SKris Kennaway             goto err;
108674664626SKris Kennaway         }
108774664626SKris Kennaway     }
108874664626SKris Kennaway 
1089f579bf8eSKris Kennaway     /* setup version number */
1090*6f9291ceSJung-uk Kim     if (!X509_REQ_set_version(req, 0L))
1091*6f9291ceSJung-uk Kim         goto err;               /* version 1 */
109274664626SKris Kennaway 
10935c87c606SMark Murray     if (no_prompt)
10945c87c606SMark Murray         i = auto_info(req, dn_sk, attr_sk, attribs, chtype);
1095*6f9291ceSJung-uk Kim     else {
10965c87c606SMark Murray         if (subj)
10973b4e3dcbSSimon L. B. Nielsen             i = build_subject(req, subj, chtype, multirdn);
10985c87c606SMark Murray         else
1099*6f9291ceSJung-uk Kim             i = prompt_info(req, dn_sk, dn_sect, attr_sk, attr_sect, attribs,
1100*6f9291ceSJung-uk Kim                             chtype);
11015c87c606SMark Murray     }
1102*6f9291ceSJung-uk Kim     if (!i)
1103*6f9291ceSJung-uk Kim         goto err;
1104f579bf8eSKris Kennaway 
1105*6f9291ceSJung-uk Kim     if (!X509_REQ_set_pubkey(req, pkey))
1106*6f9291ceSJung-uk Kim         goto err;
1107f579bf8eSKris Kennaway 
1108f579bf8eSKris Kennaway     ret = 1;
1109f579bf8eSKris Kennaway  err:
1110f579bf8eSKris Kennaway     return (ret);
1111f579bf8eSKris Kennaway }
1112f579bf8eSKris Kennaway 
11135c87c606SMark Murray /*
11145c87c606SMark Murray  * subject is expected to be in the format /type0=value0/type1=value1/type2=...
11155c87c606SMark Murray  * where characters may be escaped by \
11165c87c606SMark Murray  */
1117*6f9291ceSJung-uk Kim static int build_subject(X509_REQ *req, char *subject, unsigned long chtype,
1118*6f9291ceSJung-uk Kim                          int multirdn)
11195c87c606SMark Murray {
11205c87c606SMark Murray     X509_NAME *n;
11215c87c606SMark Murray 
11223b4e3dcbSSimon L. B. Nielsen     if (!(n = parse_name(subject, chtype, multirdn)))
11235c87c606SMark Murray         return 0;
11245c87c606SMark Murray 
1125*6f9291ceSJung-uk Kim     if (!X509_REQ_set_subject_name(req, n)) {
11265c87c606SMark Murray         X509_NAME_free(n);
11275c87c606SMark Murray         return 0;
11285c87c606SMark Murray     }
11295c87c606SMark Murray     X509_NAME_free(n);
11305c87c606SMark Murray     return 1;
11315c87c606SMark Murray }
11325c87c606SMark Murray 
1133f579bf8eSKris Kennaway static int prompt_info(X509_REQ *req,
1134f579bf8eSKris Kennaway                        STACK_OF(CONF_VALUE) *dn_sk, char *dn_sect,
1135*6f9291ceSJung-uk Kim                        STACK_OF(CONF_VALUE) *attr_sk, char *attr_sect,
1136*6f9291ceSJung-uk Kim                        int attribs, unsigned long chtype)
1137f579bf8eSKris Kennaway {
1138f579bf8eSKris Kennaway     int i;
1139f579bf8eSKris Kennaway     char *p, *q;
1140f579bf8eSKris Kennaway     char buf[100];
11413b4e3dcbSSimon L. B. Nielsen     int nid, mval;
11425c87c606SMark Murray     long n_min, n_max;
11433b4e3dcbSSimon L. B. Nielsen     char *type, *value;
11443b4e3dcbSSimon L. B. Nielsen     const char *def;
1145f579bf8eSKris Kennaway     CONF_VALUE *v;
1146f579bf8eSKris Kennaway     X509_NAME *subj;
1147f579bf8eSKris Kennaway     subj = X509_REQ_get_subject_name(req);
11485c87c606SMark Murray 
1149*6f9291ceSJung-uk Kim     if (!batch) {
1150*6f9291ceSJung-uk Kim         BIO_printf(bio_err,
1151*6f9291ceSJung-uk Kim                    "You are about to be asked to enter information that will be incorporated\n");
115274664626SKris Kennaway         BIO_printf(bio_err, "into your certificate request.\n");
1153*6f9291ceSJung-uk Kim         BIO_printf(bio_err,
1154*6f9291ceSJung-uk Kim                    "What you are about to enter is what is called a Distinguished Name or a DN.\n");
1155*6f9291ceSJung-uk Kim         BIO_printf(bio_err,
1156*6f9291ceSJung-uk Kim                    "There are quite a few fields but you can leave some blank\n");
1157*6f9291ceSJung-uk Kim         BIO_printf(bio_err,
1158*6f9291ceSJung-uk Kim                    "For some fields there will be a default value,\n");
1159*6f9291ceSJung-uk Kim         BIO_printf(bio_err,
1160*6f9291ceSJung-uk Kim                    "If you enter '.', the field will be left blank.\n");
116174664626SKris Kennaway         BIO_printf(bio_err, "-----\n");
11625c87c606SMark Murray     }
116374664626SKris Kennaway 
1164*6f9291ceSJung-uk Kim     if (sk_CONF_VALUE_num(dn_sk)) {
116574664626SKris Kennaway         i = -1;
1166*6f9291ceSJung-uk Kim  start:for (;;) {
116774664626SKris Kennaway             i++;
1168*6f9291ceSJung-uk Kim             if (sk_CONF_VALUE_num(dn_sk) <= i)
1169*6f9291ceSJung-uk Kim                 break;
117074664626SKris Kennaway 
1171f579bf8eSKris Kennaway             v = sk_CONF_VALUE_value(dn_sk, i);
117274664626SKris Kennaway             p = q = NULL;
117374664626SKris Kennaway             type = v->name;
117474664626SKris Kennaway             if (!check_end(type, "_min") || !check_end(type, "_max") ||
1175*6f9291ceSJung-uk Kim                 !check_end(type, "_default") || !check_end(type, "_value"))
1176*6f9291ceSJung-uk Kim                 continue;
1177*6f9291ceSJung-uk Kim             /*
1178*6f9291ceSJung-uk Kim              * Skip past any leading X. X: X, etc to allow for multiple
1179*6f9291ceSJung-uk Kim              * instances
118074664626SKris Kennaway              */
118174664626SKris Kennaway             for (p = v->name; *p; p++)
1182*6f9291ceSJung-uk Kim                 if ((*p == ':') || (*p == ',') || (*p == '.')) {
118374664626SKris Kennaway                     p++;
1184*6f9291ceSJung-uk Kim                     if (*p)
1185*6f9291ceSJung-uk Kim                         type = p;
118674664626SKris Kennaway                     break;
118774664626SKris Kennaway                 }
1188*6f9291ceSJung-uk Kim             if (*type == '+') {
11893b4e3dcbSSimon L. B. Nielsen                 mval = -1;
11903b4e3dcbSSimon L. B. Nielsen                 type++;
1191*6f9291ceSJung-uk Kim             } else
11923b4e3dcbSSimon L. B. Nielsen                 mval = 0;
119374664626SKris Kennaway             /* If OBJ not recognised ignore it */
1194*6f9291ceSJung-uk Kim             if ((nid = OBJ_txt2nid(type)) == NID_undef)
1195*6f9291ceSJung-uk Kim                 goto start;
1196ced566fdSJacques Vidrine             if (BIO_snprintf(buf, sizeof buf, "%s_default", v->name)
1197*6f9291ceSJung-uk Kim                 >= (int)sizeof(buf)) {
11985c87c606SMark Murray                 BIO_printf(bio_err, "Name '%s' too long\n", v->name);
11995c87c606SMark Murray                 return 0;
12005c87c606SMark Murray             }
12015c87c606SMark Murray 
1202*6f9291ceSJung-uk Kim             if ((def = NCONF_get_string(req_conf, dn_sect, buf)) == NULL) {
12035c87c606SMark Murray                 ERR_clear_error();
12045c87c606SMark Murray                 def = "";
12055c87c606SMark Murray             }
1206ced566fdSJacques Vidrine 
1207ced566fdSJacques Vidrine             BIO_snprintf(buf, sizeof buf, "%s_value", v->name);
1208*6f9291ceSJung-uk Kim             if ((value = NCONF_get_string(req_conf, dn_sect, buf)) == NULL) {
12095c87c606SMark Murray                 ERR_clear_error();
121074664626SKris Kennaway                 value = NULL;
12115c87c606SMark Murray             }
121274664626SKris Kennaway 
1213ced566fdSJacques Vidrine             BIO_snprintf(buf, sizeof buf, "%s_min", v->name);
1214*6f9291ceSJung-uk Kim             if (!NCONF_get_number(req_conf, dn_sect, buf, &n_min)) {
1215fceca8a3SJacques Vidrine                 ERR_clear_error();
12165c87c606SMark Murray                 n_min = -1;
1217fceca8a3SJacques Vidrine             }
121874664626SKris Kennaway 
1219ced566fdSJacques Vidrine             BIO_snprintf(buf, sizeof buf, "%s_max", v->name);
1220*6f9291ceSJung-uk Kim             if (!NCONF_get_number(req_conf, dn_sect, buf, &n_max)) {
1221fceca8a3SJacques Vidrine                 ERR_clear_error();
12225c87c606SMark Murray                 n_max = -1;
1223fceca8a3SJacques Vidrine             }
122474664626SKris Kennaway 
1225f579bf8eSKris Kennaway             if (!add_DN_object(subj, v->value, def, value, nid,
12263b4e3dcbSSimon L. B. Nielsen                                n_min, n_max, chtype, mval))
1227f579bf8eSKris Kennaway                 return 0;
122874664626SKris Kennaway         }
1229*6f9291ceSJung-uk Kim         if (X509_NAME_entry_count(subj) == 0) {
1230*6f9291ceSJung-uk Kim             BIO_printf(bio_err,
1231*6f9291ceSJung-uk Kim                        "error, no objects specified in config file\n");
1232f579bf8eSKris Kennaway             return 0;
123374664626SKris Kennaway         }
123474664626SKris Kennaway 
1235*6f9291ceSJung-uk Kim         if (attribs) {
1236*6f9291ceSJung-uk Kim             if ((attr_sk != NULL) && (sk_CONF_VALUE_num(attr_sk) > 0)
1237*6f9291ceSJung-uk Kim                 && (!batch)) {
1238*6f9291ceSJung-uk Kim                 BIO_printf(bio_err,
1239*6f9291ceSJung-uk Kim                            "\nPlease enter the following 'extra' attributes\n");
1240*6f9291ceSJung-uk Kim                 BIO_printf(bio_err,
1241*6f9291ceSJung-uk Kim                            "to be sent with your certificate request\n");
124274664626SKris Kennaway             }
124374664626SKris Kennaway 
124474664626SKris Kennaway             i = -1;
1245*6f9291ceSJung-uk Kim  start2:   for (;;) {
124674664626SKris Kennaway                 i++;
1247*6f9291ceSJung-uk Kim                 if ((attr_sk == NULL) || (sk_CONF_VALUE_num(attr_sk) <= i))
124874664626SKris Kennaway                     break;
124974664626SKris Kennaway 
1250f579bf8eSKris Kennaway                 v = sk_CONF_VALUE_value(attr_sk, i);
125174664626SKris Kennaway                 type = v->name;
125274664626SKris Kennaway                 if ((nid = OBJ_txt2nid(type)) == NID_undef)
125374664626SKris Kennaway                     goto start2;
125474664626SKris Kennaway 
1255ced566fdSJacques Vidrine                 if (BIO_snprintf(buf, sizeof buf, "%s_default", type)
1256*6f9291ceSJung-uk Kim                     >= (int)sizeof(buf)) {
12575c87c606SMark Murray                     BIO_printf(bio_err, "Name '%s' too long\n", v->name);
12585c87c606SMark Murray                     return 0;
12595c87c606SMark Murray                 }
12605c87c606SMark Murray 
12615c87c606SMark Murray                 if ((def = NCONF_get_string(req_conf, attr_sect, buf))
1262*6f9291ceSJung-uk Kim                     == NULL) {
12635c87c606SMark Murray                     ERR_clear_error();
126474664626SKris Kennaway                     def = "";
12655c87c606SMark Murray                 }
12665c87c606SMark Murray 
1267ced566fdSJacques Vidrine                 BIO_snprintf(buf, sizeof buf, "%s_value", type);
12685c87c606SMark Murray                 if ((value = NCONF_get_string(req_conf, attr_sect, buf))
1269*6f9291ceSJung-uk Kim                     == NULL) {
12705c87c606SMark Murray                     ERR_clear_error();
127174664626SKris Kennaway                     value = NULL;
12725c87c606SMark Murray                 }
127374664626SKris Kennaway 
1274ced566fdSJacques Vidrine                 BIO_snprintf(buf, sizeof buf, "%s_min", type);
1275*6f9291ceSJung-uk Kim                 if (!NCONF_get_number(req_conf, attr_sect, buf, &n_min)) {
1276ab8565e2SSimon L. B. Nielsen                     ERR_clear_error();
12775c87c606SMark Murray                     n_min = -1;
1278ab8565e2SSimon L. B. Nielsen                 }
127974664626SKris Kennaway 
1280ced566fdSJacques Vidrine                 BIO_snprintf(buf, sizeof buf, "%s_max", type);
1281*6f9291ceSJung-uk Kim                 if (!NCONF_get_number(req_conf, attr_sect, buf, &n_max)) {
1282ab8565e2SSimon L. B. Nielsen                     ERR_clear_error();
12835c87c606SMark Murray                     n_max = -1;
1284ab8565e2SSimon L. B. Nielsen                 }
128574664626SKris Kennaway 
1286f579bf8eSKris Kennaway                 if (!add_attribute_object(req,
1287*6f9291ceSJung-uk Kim                                           v->value, def, value, nid, n_min,
1288*6f9291ceSJung-uk Kim                                           n_max, chtype))
1289f579bf8eSKris Kennaway                     return 0;
129074664626SKris Kennaway             }
129174664626SKris Kennaway         }
1292*6f9291ceSJung-uk Kim     } else {
129374664626SKris Kennaway         BIO_printf(bio_err, "No template, please set one up.\n");
1294f579bf8eSKris Kennaway         return 0;
129574664626SKris Kennaway     }
129674664626SKris Kennaway 
1297f579bf8eSKris Kennaway     return 1;
129874664626SKris Kennaway 
129974664626SKris Kennaway }
130074664626SKris Kennaway 
1301f579bf8eSKris Kennaway static int auto_info(X509_REQ *req, STACK_OF(CONF_VALUE) *dn_sk,
1302*6f9291ceSJung-uk Kim                      STACK_OF(CONF_VALUE) *attr_sk, int attribs,
1303*6f9291ceSJung-uk Kim                      unsigned long chtype)
1304f579bf8eSKris Kennaway {
1305f579bf8eSKris Kennaway     int i;
1306f579bf8eSKris Kennaway     char *p, *q;
1307f579bf8eSKris Kennaway     char *type;
1308f579bf8eSKris Kennaway     CONF_VALUE *v;
1309f579bf8eSKris Kennaway     X509_NAME *subj;
1310f579bf8eSKris Kennaway 
1311f579bf8eSKris Kennaway     subj = X509_REQ_get_subject_name(req);
1312f579bf8eSKris Kennaway 
1313*6f9291ceSJung-uk Kim     for (i = 0; i < sk_CONF_VALUE_num(dn_sk); i++) {
13143b4e3dcbSSimon L. B. Nielsen         int mval;
1315f579bf8eSKris Kennaway         v = sk_CONF_VALUE_value(dn_sk, i);
1316f579bf8eSKris Kennaway         p = q = NULL;
1317f579bf8eSKris Kennaway         type = v->name;
1318*6f9291ceSJung-uk Kim         /*
1319*6f9291ceSJung-uk Kim          * Skip past any leading X. X: X, etc to allow for multiple instances
1320f579bf8eSKris Kennaway          */
1321f579bf8eSKris Kennaway         for (p = v->name; *p; p++)
1322ddd58736SKris Kennaway #ifndef CHARSET_EBCDIC
1323f579bf8eSKris Kennaway             if ((*p == ':') || (*p == ',') || (*p == '.')) {
1324ddd58736SKris Kennaway #else
1325*6f9291ceSJung-uk Kim             if ((*p == os_toascii[':']) || (*p == os_toascii[','])
1326*6f9291ceSJung-uk Kim                 || (*p == os_toascii['.'])) {
1327ddd58736SKris Kennaway #endif
1328f579bf8eSKris Kennaway                 p++;
1329*6f9291ceSJung-uk Kim                 if (*p)
1330*6f9291ceSJung-uk Kim                     type = p;
1331f579bf8eSKris Kennaway                 break;
1332f579bf8eSKris Kennaway             }
13333b4e3dcbSSimon L. B. Nielsen #ifndef CHARSET_EBCDIC
13343b4e3dcbSSimon L. B. Nielsen         if (*p == '+')
13353b4e3dcbSSimon L. B. Nielsen #else
13363b4e3dcbSSimon L. B. Nielsen         if (*p == os_toascii['+'])
13373b4e3dcbSSimon L. B. Nielsen #endif
13383b4e3dcbSSimon L. B. Nielsen         {
13393b4e3dcbSSimon L. B. Nielsen             p++;
13403b4e3dcbSSimon L. B. Nielsen             mval = -1;
1341*6f9291ceSJung-uk Kim         } else
13423b4e3dcbSSimon L. B. Nielsen             mval = 0;
13435c87c606SMark Murray         if (!X509_NAME_add_entry_by_txt(subj, type, chtype,
1344*6f9291ceSJung-uk Kim                                         (unsigned char *)v->value, -1, -1,
1345*6f9291ceSJung-uk Kim                                         mval))
1346*6f9291ceSJung-uk Kim             return 0;
1347f579bf8eSKris Kennaway 
1348f579bf8eSKris Kennaway     }
1349f579bf8eSKris Kennaway 
1350*6f9291ceSJung-uk Kim     if (!X509_NAME_entry_count(subj)) {
1351f579bf8eSKris Kennaway         BIO_printf(bio_err, "error, no objects specified in config file\n");
1352f579bf8eSKris Kennaway         return 0;
1353f579bf8eSKris Kennaway     }
1354*6f9291ceSJung-uk Kim     if (attribs) {
1355*6f9291ceSJung-uk Kim         for (i = 0; i < sk_CONF_VALUE_num(attr_sk); i++) {
1356f579bf8eSKris Kennaway             v = sk_CONF_VALUE_value(attr_sk, i);
13575c87c606SMark Murray             if (!X509_REQ_add1_attr_by_txt(req, v->name, chtype,
1358*6f9291ceSJung-uk Kim                                            (unsigned char *)v->value, -1))
1359*6f9291ceSJung-uk Kim                 return 0;
1360f579bf8eSKris Kennaway         }
1361f579bf8eSKris Kennaway     }
1362f579bf8eSKris Kennaway     return 1;
1363f579bf8eSKris Kennaway }
1364f579bf8eSKris Kennaway 
1365*6f9291ceSJung-uk Kim static int add_DN_object(X509_NAME *n, char *text, const char *def,
1366*6f9291ceSJung-uk Kim                          char *value, int nid, int n_min, int n_max,
1367*6f9291ceSJung-uk Kim                          unsigned long chtype, int mval)
136874664626SKris Kennaway {
1369f579bf8eSKris Kennaway     int i, ret = 0;
137074664626SKris Kennaway     MS_STATIC char buf[1024];
137174664626SKris Kennaway  start:
1372*6f9291ceSJung-uk Kim     if (!batch)
1373*6f9291ceSJung-uk Kim         BIO_printf(bio_err, "%s [%s]:", text, def);
137474664626SKris Kennaway     (void)BIO_flush(bio_err);
1375*6f9291ceSJung-uk Kim     if (value != NULL) {
1376ced566fdSJacques Vidrine         BUF_strlcpy(buf, value, sizeof buf);
1377ced566fdSJacques Vidrine         BUF_strlcat(buf, "\n", sizeof buf);
137874664626SKris Kennaway         BIO_printf(bio_err, "%s\n", value);
1379*6f9291ceSJung-uk Kim     } else {
138074664626SKris Kennaway         buf[0] = '\0';
1381*6f9291ceSJung-uk Kim         if (!batch) {
13826a599222SSimon L. B. Nielsen             if (!fgets(buf, sizeof buf, stdin))
13836a599222SSimon L. B. Nielsen                 return 0;
1384*6f9291ceSJung-uk Kim         } else {
13855c87c606SMark Murray             buf[0] = '\n';
13865c87c606SMark Murray             buf[1] = '\0';
13875c87c606SMark Murray         }
138874664626SKris Kennaway     }
138974664626SKris Kennaway 
1390*6f9291ceSJung-uk Kim     if (buf[0] == '\0')
1391*6f9291ceSJung-uk Kim         return (0);
1392*6f9291ceSJung-uk Kim     else if (buf[0] == '\n') {
139374664626SKris Kennaway         if ((def == NULL) || (def[0] == '\0'))
139474664626SKris Kennaway             return (1);
1395ced566fdSJacques Vidrine         BUF_strlcpy(buf, def, sizeof buf);
1396ced566fdSJacques Vidrine         BUF_strlcat(buf, "\n", sizeof buf);
1397*6f9291ceSJung-uk Kim     } else if ((buf[0] == '.') && (buf[1] == '\n'))
1398*6f9291ceSJung-uk Kim         return (1);
139974664626SKris Kennaway 
140074664626SKris Kennaway     i = strlen(buf);
1401*6f9291ceSJung-uk Kim     if (buf[i - 1] != '\n') {
140274664626SKris Kennaway         BIO_printf(bio_err, "weird input :-(\n");
140374664626SKris Kennaway         return (0);
140474664626SKris Kennaway     }
140574664626SKris Kennaway     buf[--i] = '\0';
1406f579bf8eSKris Kennaway #ifdef CHARSET_EBCDIC
1407f579bf8eSKris Kennaway     ebcdic2ascii(buf, buf, i);
1408f579bf8eSKris Kennaway #endif
1409*6f9291ceSJung-uk Kim     if (!req_check_len(i, n_min, n_max)) {
141094ad176cSJung-uk Kim         if (batch || value)
141194ad176cSJung-uk Kim             return 0;
141294ad176cSJung-uk Kim         goto start;
141394ad176cSJung-uk Kim     }
141494ad176cSJung-uk Kim 
14155c87c606SMark Murray     if (!X509_NAME_add_entry_by_NID(n, nid, chtype,
1416*6f9291ceSJung-uk Kim                                     (unsigned char *)buf, -1, -1, mval))
1417*6f9291ceSJung-uk Kim         goto err;
1418f579bf8eSKris Kennaway     ret = 1;
1419f579bf8eSKris Kennaway  err:
1420f579bf8eSKris Kennaway     return (ret);
142174664626SKris Kennaway }
142274664626SKris Kennaway 
14233b4e3dcbSSimon L. B. Nielsen static int add_attribute_object(X509_REQ *req, char *text, const char *def,
14243b4e3dcbSSimon L. B. Nielsen                                 char *value, int nid, int n_min,
14255c87c606SMark Murray                                 int n_max, unsigned long chtype)
1426f579bf8eSKris Kennaway {
1427f579bf8eSKris Kennaway     int i;
1428f579bf8eSKris Kennaway     static char buf[1024];
142974664626SKris Kennaway 
1430f579bf8eSKris Kennaway  start:
1431*6f9291ceSJung-uk Kim     if (!batch)
1432*6f9291ceSJung-uk Kim         BIO_printf(bio_err, "%s [%s]:", text, def);
1433f579bf8eSKris Kennaway     (void)BIO_flush(bio_err);
1434*6f9291ceSJung-uk Kim     if (value != NULL) {
1435ced566fdSJacques Vidrine         BUF_strlcpy(buf, value, sizeof buf);
1436ced566fdSJacques Vidrine         BUF_strlcat(buf, "\n", sizeof buf);
1437f579bf8eSKris Kennaway         BIO_printf(bio_err, "%s\n", value);
1438*6f9291ceSJung-uk Kim     } else {
1439f579bf8eSKris Kennaway         buf[0] = '\0';
1440*6f9291ceSJung-uk Kim         if (!batch) {
14416a599222SSimon L. B. Nielsen             if (!fgets(buf, sizeof buf, stdin))
14426a599222SSimon L. B. Nielsen                 return 0;
1443*6f9291ceSJung-uk Kim         } else {
14445c87c606SMark Murray             buf[0] = '\n';
14455c87c606SMark Murray             buf[1] = '\0';
14465c87c606SMark Murray         }
1447f579bf8eSKris Kennaway     }
144874664626SKris Kennaway 
1449*6f9291ceSJung-uk Kim     if (buf[0] == '\0')
1450*6f9291ceSJung-uk Kim         return (0);
1451*6f9291ceSJung-uk Kim     else if (buf[0] == '\n') {
1452f579bf8eSKris Kennaway         if ((def == NULL) || (def[0] == '\0'))
1453f579bf8eSKris Kennaway             return (1);
1454ced566fdSJacques Vidrine         BUF_strlcpy(buf, def, sizeof buf);
1455ced566fdSJacques Vidrine         BUF_strlcat(buf, "\n", sizeof buf);
1456*6f9291ceSJung-uk Kim     } else if ((buf[0] == '.') && (buf[1] == '\n'))
1457*6f9291ceSJung-uk Kim         return (1);
145874664626SKris Kennaway 
1459f579bf8eSKris Kennaway     i = strlen(buf);
1460*6f9291ceSJung-uk Kim     if (buf[i - 1] != '\n') {
1461f579bf8eSKris Kennaway         BIO_printf(bio_err, "weird input :-(\n");
1462f579bf8eSKris Kennaway         return (0);
1463f579bf8eSKris Kennaway     }
1464f579bf8eSKris Kennaway     buf[--i] = '\0';
1465ddd58736SKris Kennaway #ifdef CHARSET_EBCDIC
1466ddd58736SKris Kennaway     ebcdic2ascii(buf, buf, i);
1467ddd58736SKris Kennaway #endif
1468*6f9291ceSJung-uk Kim     if (!req_check_len(i, n_min, n_max)) {
146994ad176cSJung-uk Kim         if (batch || value)
147094ad176cSJung-uk Kim             return 0;
147194ad176cSJung-uk Kim         goto start;
147294ad176cSJung-uk Kim     }
1473f579bf8eSKris Kennaway 
14745c87c606SMark Murray     if (!X509_REQ_add1_attr_by_NID(req, nid, chtype,
1475f579bf8eSKris Kennaway                                    (unsigned char *)buf, -1)) {
1476f579bf8eSKris Kennaway         BIO_printf(bio_err, "Error adding attribute\n");
1477f579bf8eSKris Kennaway         ERR_print_errors(bio_err);
1478f579bf8eSKris Kennaway         goto err;
1479f579bf8eSKris Kennaway     }
1480f579bf8eSKris Kennaway 
148174664626SKris Kennaway     return (1);
148274664626SKris Kennaway  err:
148374664626SKris Kennaway     return (0);
148474664626SKris Kennaway }
148574664626SKris Kennaway 
14865c87c606SMark Murray static int req_check_len(int len, int n_min, int n_max)
148774664626SKris Kennaway {
1488*6f9291ceSJung-uk Kim     if ((n_min > 0) && (len < n_min)) {
1489*6f9291ceSJung-uk Kim         BIO_printf(bio_err,
1490*6f9291ceSJung-uk Kim                    "string is too short, it needs to be at least %d bytes long\n",
1491*6f9291ceSJung-uk Kim                    n_min);
149274664626SKris Kennaway         return (0);
149374664626SKris Kennaway     }
1494*6f9291ceSJung-uk Kim     if ((n_max >= 0) && (len > n_max)) {
1495*6f9291ceSJung-uk Kim         BIO_printf(bio_err,
1496*6f9291ceSJung-uk Kim                    "string is too long, it needs to be less than  %d bytes long\n",
1497*6f9291ceSJung-uk Kim                    n_max);
149874664626SKris Kennaway         return (0);
149974664626SKris Kennaway     }
150074664626SKris Kennaway     return (1);
150174664626SKris Kennaway }
150274664626SKris Kennaway 
150374664626SKris Kennaway /* Check if the end of a string matches 'end' */
15043b4e3dcbSSimon L. B. Nielsen static int check_end(const char *str, const char *end)
150574664626SKris Kennaway {
150674664626SKris Kennaway     int elen, slen;
15073b4e3dcbSSimon L. B. Nielsen     const char *tmp;
150874664626SKris Kennaway     elen = strlen(end);
150974664626SKris Kennaway     slen = strlen(str);
1510*6f9291ceSJung-uk Kim     if (elen > slen)
1511*6f9291ceSJung-uk Kim         return 1;
151274664626SKris Kennaway     tmp = str + slen - elen;
151374664626SKris Kennaway     return strcmp(tmp, end);
151474664626SKris Kennaway }
15151f13597dSJung-uk Kim 
1516*6f9291ceSJung-uk Kim static EVP_PKEY_CTX *set_keygen_ctx(BIO *err, const char *gstr,
1517*6f9291ceSJung-uk Kim                                     int *pkey_type, long *pkeylen,
1518*6f9291ceSJung-uk Kim                                     char **palgnam, ENGINE *keygen_engine)
15191f13597dSJung-uk Kim {
15201f13597dSJung-uk Kim     EVP_PKEY_CTX *gctx = NULL;
15211f13597dSJung-uk Kim     EVP_PKEY *param = NULL;
15221f13597dSJung-uk Kim     long keylen = -1;
15231f13597dSJung-uk Kim     BIO *pbio = NULL;
15241f13597dSJung-uk Kim     const char *paramfile = NULL;
15251f13597dSJung-uk Kim 
1526*6f9291ceSJung-uk Kim     if (gstr == NULL) {
15271f13597dSJung-uk Kim         *pkey_type = EVP_PKEY_RSA;
15281f13597dSJung-uk Kim         keylen = *pkeylen;
1529*6f9291ceSJung-uk Kim     } else if (gstr[0] >= '0' && gstr[0] <= '9') {
15301f13597dSJung-uk Kim         *pkey_type = EVP_PKEY_RSA;
15311f13597dSJung-uk Kim         keylen = atol(gstr);
15321f13597dSJung-uk Kim         *pkeylen = keylen;
1533*6f9291ceSJung-uk Kim     } else if (!strncmp(gstr, "param:", 6))
15341f13597dSJung-uk Kim         paramfile = gstr + 6;
1535*6f9291ceSJung-uk Kim     else {
15361f13597dSJung-uk Kim         const char *p = strchr(gstr, ':');
15371f13597dSJung-uk Kim         int len;
15381f13597dSJung-uk Kim         ENGINE *tmpeng;
15391f13597dSJung-uk Kim         const EVP_PKEY_ASN1_METHOD *ameth;
15401f13597dSJung-uk Kim 
15411f13597dSJung-uk Kim         if (p)
15421f13597dSJung-uk Kim             len = p - gstr;
15431f13597dSJung-uk Kim         else
15441f13597dSJung-uk Kim             len = strlen(gstr);
1545*6f9291ceSJung-uk Kim         /*
1546*6f9291ceSJung-uk Kim          * The lookup of a the string will cover all engines so keep a note
1547*6f9291ceSJung-uk Kim          * of the implementation.
15481f13597dSJung-uk Kim          */
15491f13597dSJung-uk Kim 
15501f13597dSJung-uk Kim         ameth = EVP_PKEY_asn1_find_str(&tmpeng, gstr, len);
15511f13597dSJung-uk Kim 
1552*6f9291ceSJung-uk Kim         if (!ameth) {
15531f13597dSJung-uk Kim             BIO_printf(err, "Unknown algorithm %.*s\n", len, gstr);
15541f13597dSJung-uk Kim             return NULL;
15551f13597dSJung-uk Kim         }
15561f13597dSJung-uk Kim 
1557*6f9291ceSJung-uk Kim         EVP_PKEY_asn1_get0_info(NULL, pkey_type, NULL, NULL, NULL, ameth);
15581f13597dSJung-uk Kim #ifndef OPENSSL_NO_ENGINE
15591f13597dSJung-uk Kim         if (tmpeng)
15601f13597dSJung-uk Kim             ENGINE_finish(tmpeng);
15611f13597dSJung-uk Kim #endif
1562*6f9291ceSJung-uk Kim         if (*pkey_type == EVP_PKEY_RSA) {
1563*6f9291ceSJung-uk Kim             if (p) {
15641f13597dSJung-uk Kim                 keylen = atol(p + 1);
15651f13597dSJung-uk Kim                 *pkeylen = keylen;
1566*6f9291ceSJung-uk Kim             } else
1567560ede85SJung-uk Kim                 keylen = *pkeylen;
1568*6f9291ceSJung-uk Kim         } else if (p)
15691f13597dSJung-uk Kim             paramfile = p + 1;
15701f13597dSJung-uk Kim     }
15711f13597dSJung-uk Kim 
1572*6f9291ceSJung-uk Kim     if (paramfile) {
15731f13597dSJung-uk Kim         pbio = BIO_new_file(paramfile, "r");
1574*6f9291ceSJung-uk Kim         if (!pbio) {
1575*6f9291ceSJung-uk Kim             BIO_printf(err, "Can't open parameter file %s\n", paramfile);
15761f13597dSJung-uk Kim             return NULL;
15771f13597dSJung-uk Kim         }
15781f13597dSJung-uk Kim         param = PEM_read_bio_Parameters(pbio, NULL);
15791f13597dSJung-uk Kim 
1580*6f9291ceSJung-uk Kim         if (!param) {
15811f13597dSJung-uk Kim             X509 *x;
15821f13597dSJung-uk Kim             (void)BIO_reset(pbio);
15831f13597dSJung-uk Kim             x = PEM_read_bio_X509(pbio, NULL, NULL, NULL);
1584*6f9291ceSJung-uk Kim             if (x) {
15851f13597dSJung-uk Kim                 param = X509_get_pubkey(x);
15861f13597dSJung-uk Kim                 X509_free(x);
15871f13597dSJung-uk Kim             }
15881f13597dSJung-uk Kim         }
15891f13597dSJung-uk Kim 
15901f13597dSJung-uk Kim         BIO_free(pbio);
15911f13597dSJung-uk Kim 
1592*6f9291ceSJung-uk Kim         if (!param) {
1593*6f9291ceSJung-uk Kim             BIO_printf(err, "Error reading parameter file %s\n", paramfile);
15941f13597dSJung-uk Kim             return NULL;
15951f13597dSJung-uk Kim         }
15961f13597dSJung-uk Kim         if (*pkey_type == -1)
15971f13597dSJung-uk Kim             *pkey_type = EVP_PKEY_id(param);
1598*6f9291ceSJung-uk Kim         else if (*pkey_type != EVP_PKEY_base_id(param)) {
15991f13597dSJung-uk Kim             BIO_printf(err, "Key Type does not match parameters\n");
16001f13597dSJung-uk Kim             EVP_PKEY_free(param);
16011f13597dSJung-uk Kim             return NULL;
16021f13597dSJung-uk Kim         }
16031f13597dSJung-uk Kim     }
16041f13597dSJung-uk Kim 
1605*6f9291ceSJung-uk Kim     if (palgnam) {
16061f13597dSJung-uk Kim         const EVP_PKEY_ASN1_METHOD *ameth;
16071f13597dSJung-uk Kim         ENGINE *tmpeng;
16081f13597dSJung-uk Kim         const char *anam;
16091f13597dSJung-uk Kim         ameth = EVP_PKEY_asn1_find(&tmpeng, *pkey_type);
1610*6f9291ceSJung-uk Kim         if (!ameth) {
16111f13597dSJung-uk Kim             BIO_puts(err, "Internal error: can't find key algorithm\n");
16121f13597dSJung-uk Kim             return NULL;
16131f13597dSJung-uk Kim         }
16141f13597dSJung-uk Kim         EVP_PKEY_asn1_get0_info(NULL, NULL, NULL, NULL, &anam, ameth);
16151f13597dSJung-uk Kim         *palgnam = BUF_strdup(anam);
16161f13597dSJung-uk Kim #ifndef OPENSSL_NO_ENGINE
16171f13597dSJung-uk Kim         if (tmpeng)
16181f13597dSJung-uk Kim             ENGINE_finish(tmpeng);
16191f13597dSJung-uk Kim #endif
16201f13597dSJung-uk Kim     }
16211f13597dSJung-uk Kim 
1622*6f9291ceSJung-uk Kim     if (param) {
16231f13597dSJung-uk Kim         gctx = EVP_PKEY_CTX_new(param, keygen_engine);
16241f13597dSJung-uk Kim         *pkeylen = EVP_PKEY_bits(param);
16251f13597dSJung-uk Kim         EVP_PKEY_free(param);
1626*6f9291ceSJung-uk Kim     } else
16271f13597dSJung-uk Kim         gctx = EVP_PKEY_CTX_new_id(*pkey_type, keygen_engine);
16281f13597dSJung-uk Kim 
1629*6f9291ceSJung-uk Kim     if (!gctx) {
16301f13597dSJung-uk Kim         BIO_puts(err, "Error allocating keygen context\n");
16311f13597dSJung-uk Kim         ERR_print_errors(err);
16321f13597dSJung-uk Kim         return NULL;
16331f13597dSJung-uk Kim     }
16341f13597dSJung-uk Kim 
1635*6f9291ceSJung-uk Kim     if (EVP_PKEY_keygen_init(gctx) <= 0) {
16361f13597dSJung-uk Kim         BIO_puts(err, "Error initializing keygen context\n");
16371f13597dSJung-uk Kim         ERR_print_errors(err);
16381f13597dSJung-uk Kim         return NULL;
16391f13597dSJung-uk Kim     }
16401f13597dSJung-uk Kim #ifndef OPENSSL_NO_RSA
1641*6f9291ceSJung-uk Kim     if ((*pkey_type == EVP_PKEY_RSA) && (keylen != -1)) {
1642*6f9291ceSJung-uk Kim         if (EVP_PKEY_CTX_set_rsa_keygen_bits(gctx, keylen) <= 0) {
16431f13597dSJung-uk Kim             BIO_puts(err, "Error setting RSA keysize\n");
16441f13597dSJung-uk Kim             ERR_print_errors(err);
16451f13597dSJung-uk Kim             EVP_PKEY_CTX_free(gctx);
16461f13597dSJung-uk Kim             return NULL;
16471f13597dSJung-uk Kim         }
16481f13597dSJung-uk Kim     }
16491f13597dSJung-uk Kim #endif
16501f13597dSJung-uk Kim 
16511f13597dSJung-uk Kim     return gctx;
16521f13597dSJung-uk Kim }
16531f13597dSJung-uk Kim 
16541f13597dSJung-uk Kim static int genpkey_cb(EVP_PKEY_CTX *ctx)
16551f13597dSJung-uk Kim {
16561f13597dSJung-uk Kim     char c = '*';
16571f13597dSJung-uk Kim     BIO *b = EVP_PKEY_CTX_get_app_data(ctx);
16581f13597dSJung-uk Kim     int p;
16591f13597dSJung-uk Kim     p = EVP_PKEY_CTX_get_keygen_info(ctx, 0);
1660*6f9291ceSJung-uk Kim     if (p == 0)
1661*6f9291ceSJung-uk Kim         c = '.';
1662*6f9291ceSJung-uk Kim     if (p == 1)
1663*6f9291ceSJung-uk Kim         c = '+';
1664*6f9291ceSJung-uk Kim     if (p == 2)
1665*6f9291ceSJung-uk Kim         c = '*';
1666*6f9291ceSJung-uk Kim     if (p == 3)
1667*6f9291ceSJung-uk Kim         c = '\n';
16681f13597dSJung-uk Kim     BIO_write(b, &c, 1);
16691f13597dSJung-uk Kim     (void)BIO_flush(b);
16701f13597dSJung-uk Kim #ifdef LINT
16711f13597dSJung-uk Kim     p = n;
16721f13597dSJung-uk Kim #endif
16731f13597dSJung-uk Kim     return 1;
16741f13597dSJung-uk Kim }
16751f13597dSJung-uk Kim 
16761f13597dSJung-uk Kim static int do_sign_init(BIO *err, EVP_MD_CTX *ctx, EVP_PKEY *pkey,
16771f13597dSJung-uk Kim                         const EVP_MD *md, STACK_OF(OPENSSL_STRING) *sigopts)
16781f13597dSJung-uk Kim {
16791f13597dSJung-uk Kim     EVP_PKEY_CTX *pkctx = NULL;
16801f13597dSJung-uk Kim     int i;
16811f13597dSJung-uk Kim     EVP_MD_CTX_init(ctx);
16821f13597dSJung-uk Kim     if (!EVP_DigestSignInit(ctx, &pkctx, md, NULL, pkey))
16831f13597dSJung-uk Kim         return 0;
1684*6f9291ceSJung-uk Kim     for (i = 0; i < sk_OPENSSL_STRING_num(sigopts); i++) {
16851f13597dSJung-uk Kim         char *sigopt = sk_OPENSSL_STRING_value(sigopts, i);
1686*6f9291ceSJung-uk Kim         if (pkey_ctrl_string(pkctx, sigopt) <= 0) {
16871f13597dSJung-uk Kim             BIO_printf(err, "parameter error \"%s\"\n", sigopt);
16881f13597dSJung-uk Kim             ERR_print_errors(bio_err);
16891f13597dSJung-uk Kim             return 0;
16901f13597dSJung-uk Kim         }
16911f13597dSJung-uk Kim     }
16921f13597dSJung-uk Kim     return 1;
16931f13597dSJung-uk Kim }
16941f13597dSJung-uk Kim 
16951f13597dSJung-uk Kim int do_X509_sign(BIO *err, X509 *x, EVP_PKEY *pkey, const EVP_MD *md,
16961f13597dSJung-uk Kim                  STACK_OF(OPENSSL_STRING) *sigopts)
16971f13597dSJung-uk Kim {
16981f13597dSJung-uk Kim     int rv;
16991f13597dSJung-uk Kim     EVP_MD_CTX mctx;
17001f13597dSJung-uk Kim     EVP_MD_CTX_init(&mctx);
17011f13597dSJung-uk Kim     rv = do_sign_init(err, &mctx, pkey, md, sigopts);
17021f13597dSJung-uk Kim     if (rv > 0)
17031f13597dSJung-uk Kim         rv = X509_sign_ctx(x, &mctx);
17041f13597dSJung-uk Kim     EVP_MD_CTX_cleanup(&mctx);
17051f13597dSJung-uk Kim     return rv > 0 ? 1 : 0;
17061f13597dSJung-uk Kim }
17071f13597dSJung-uk Kim 
17081f13597dSJung-uk Kim int do_X509_REQ_sign(BIO *err, X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md,
17091f13597dSJung-uk Kim                      STACK_OF(OPENSSL_STRING) *sigopts)
17101f13597dSJung-uk Kim {
17111f13597dSJung-uk Kim     int rv;
17121f13597dSJung-uk Kim     EVP_MD_CTX mctx;
17131f13597dSJung-uk Kim     EVP_MD_CTX_init(&mctx);
17141f13597dSJung-uk Kim     rv = do_sign_init(err, &mctx, pkey, md, sigopts);
17151f13597dSJung-uk Kim     if (rv > 0)
17161f13597dSJung-uk Kim         rv = X509_REQ_sign_ctx(x, &mctx);
17171f13597dSJung-uk Kim     EVP_MD_CTX_cleanup(&mctx);
17181f13597dSJung-uk Kim     return rv > 0 ? 1 : 0;
17191f13597dSJung-uk Kim }
17201f13597dSJung-uk Kim 
17211f13597dSJung-uk Kim int do_X509_CRL_sign(BIO *err, X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md,
17221f13597dSJung-uk Kim                      STACK_OF(OPENSSL_STRING) *sigopts)
17231f13597dSJung-uk Kim {
17241f13597dSJung-uk Kim     int rv;
17251f13597dSJung-uk Kim     EVP_MD_CTX mctx;
17261f13597dSJung-uk Kim     EVP_MD_CTX_init(&mctx);
17271f13597dSJung-uk Kim     rv = do_sign_init(err, &mctx, pkey, md, sigopts);
17281f13597dSJung-uk Kim     if (rv > 0)
17291f13597dSJung-uk Kim         rv = X509_CRL_sign_ctx(x, &mctx);
17301f13597dSJung-uk Kim     EVP_MD_CTX_cleanup(&mctx);
17311f13597dSJung-uk Kim     return rv > 0 ? 1 : 0;
17321f13597dSJung-uk Kim }
1733