xref: /freebsd/crypto/openssl/apps/req.c (revision ed7112f094e259f5ad6674b204d52543e831efa2)
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 
596f9291ceSJung-uk Kim /*
606f9291ceSJung-uk Kim  * Until the key-gen callbacks are modified to use newer prototypes, we allow
616f9291ceSJung-uk Kim  * deprecated functions for openssl-internal code
626f9291ceSJung-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 
1044c6a0400SJung-uk Kim #define DEFAULT_KEY_LENGTH      2048
1054c6a0400SJung-uk Kim #define MIN_KEY_LENGTH          512
10674664626SKris Kennaway 
10774664626SKris Kennaway #undef PROG
10874664626SKris Kennaway #define PROG    req_main
10974664626SKris Kennaway 
1106f9291ceSJung-uk Kim /*-
1116f9291ceSJung-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,
1376f9291ceSJung-uk Kim                        STACK_OF(CONF_VALUE) *attr_sk, char *attr_sect,
1386f9291ceSJung-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,
1436f9291ceSJung-uk Kim                                 char *value, int nid, int n_min, int n_max,
1446f9291ceSJung-uk Kim                                 unsigned long chtype);
1456f9291ceSJung-uk Kim static int add_DN_object(X509_NAME *n, char *text, const char *def,
1466f9291ceSJung-uk Kim                          char *value, int nid, int n_min, int n_max,
1476f9291ceSJung-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);
1516f9291ceSJung-uk Kim static EVP_PKEY_CTX *set_keygen_ctx(BIO *err, const char *gstr,
1526f9291ceSJung-uk Kim                                     int *pkey_type, long *pkeylen,
1536f9291ceSJung-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;
1776f9291ceSJung-uk Kim     int informat, outformat, verify = 0, noout = 0, text = 0, keyform =
1786f9291ceSJung-uk Kim         FORMAT_PEM;
1795c87c606SMark Murray     int nodes = 0, kludge = 0, newhdr = 0, subject = 0, pubkey = 0;
1806f9291ceSJung-uk Kim     char *infile, *outfile, *prog, *keyfile = NULL, *template =
1816f9291ceSJung-uk Kim         NULL, *keyout = NULL;
1825c87c606SMark Murray     char *engine = NULL;
18374664626SKris Kennaway     char *extensions = NULL;
184f579bf8eSKris Kennaway     char *req_exts = NULL;
1855c87c606SMark Murray     const EVP_CIPHER *cipher = NULL;
1865c87c606SMark Murray     ASN1_INTEGER *serial = NULL;
18774664626SKris Kennaway     int modulus = 0;
188ddd58736SKris Kennaway     char *inrand = NULL;
189f579bf8eSKris Kennaway     char *passargin = NULL, *passargout = NULL;
190f579bf8eSKris Kennaway     char *passin = NULL, *passout = NULL;
19174664626SKris Kennaway     char *p;
1925c87c606SMark Murray     char *subj = NULL;
1933b4e3dcbSSimon L. B. Nielsen     int multirdn = 0;
1941f13597dSJung-uk Kim     const EVP_MD *md_alg = NULL, *digest = NULL;
1955c87c606SMark Murray     unsigned long chtype = MBSTRING_ASC;
19674664626SKris Kennaway #ifndef MONOLITH
1975c87c606SMark Murray     char *to_free;
1985c87c606SMark Murray     long errline;
19974664626SKris Kennaway #endif
20074664626SKris Kennaway 
201f579bf8eSKris Kennaway     req_conf = NULL;
2025c87c606SMark Murray #ifndef OPENSSL_NO_DES
20374664626SKris Kennaway     cipher = EVP_des_ede3_cbc();
20474664626SKris Kennaway #endif
20574664626SKris Kennaway     apps_startup();
20674664626SKris Kennaway 
20774664626SKris Kennaway     if (bio_err == NULL)
20874664626SKris Kennaway         if ((bio_err = BIO_new(BIO_s_file())) != NULL)
20974664626SKris Kennaway             BIO_set_fp(bio_err, stderr, BIO_NOCLOSE | BIO_FP_TEXT);
21074664626SKris Kennaway 
21174664626SKris Kennaway     infile = NULL;
21274664626SKris Kennaway     outfile = NULL;
21374664626SKris Kennaway     informat = FORMAT_PEM;
21474664626SKris Kennaway     outformat = FORMAT_PEM;
21574664626SKris Kennaway 
21674664626SKris Kennaway     prog = argv[0];
21774664626SKris Kennaway     argc--;
21874664626SKris Kennaway     argv++;
2196f9291ceSJung-uk Kim     while (argc >= 1) {
2206f9291ceSJung-uk Kim         if (strcmp(*argv, "-inform") == 0) {
2216f9291ceSJung-uk Kim             if (--argc < 1)
2226f9291ceSJung-uk Kim                 goto bad;
22374664626SKris Kennaway             informat = str2fmt(*(++argv));
2246f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-outform") == 0) {
2256f9291ceSJung-uk Kim             if (--argc < 1)
2266f9291ceSJung-uk Kim                 goto bad;
22774664626SKris Kennaway             outformat = str2fmt(*(++argv));
22874664626SKris Kennaway         }
229fceca8a3SJacques Vidrine #ifndef OPENSSL_NO_ENGINE
2306f9291ceSJung-uk Kim         else if (strcmp(*argv, "-engine") == 0) {
2316f9291ceSJung-uk Kim             if (--argc < 1)
2326f9291ceSJung-uk Kim                 goto bad;
2335c87c606SMark Murray             engine = *(++argv);
2346f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-keygen_engine") == 0) {
2356f9291ceSJung-uk Kim             if (--argc < 1)
2366f9291ceSJung-uk Kim                 goto bad;
2371f13597dSJung-uk Kim             gen_eng = ENGINE_by_id(*(++argv));
2386f9291ceSJung-uk Kim             if (gen_eng == NULL) {
2391f13597dSJung-uk Kim                 BIO_printf(bio_err, "Can't find keygen engine %s\n", *argv);
2401f13597dSJung-uk Kim                 goto end;
2411f13597dSJung-uk Kim             }
2421f13597dSJung-uk Kim         }
243fceca8a3SJacques Vidrine #endif
2446f9291ceSJung-uk Kim         else if (strcmp(*argv, "-key") == 0) {
2456f9291ceSJung-uk Kim             if (--argc < 1)
2466f9291ceSJung-uk Kim                 goto bad;
24774664626SKris Kennaway             keyfile = *(++argv);
2486f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-pubkey") == 0) {
2495c87c606SMark Murray             pubkey = 1;
2506f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-new") == 0) {
25174664626SKris Kennaway             newreq = 1;
2526f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-config") == 0) {
2536f9291ceSJung-uk Kim             if (--argc < 1)
2546f9291ceSJung-uk Kim                 goto bad;
25574664626SKris Kennaway             template = *(++argv);
2566f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-keyform") == 0) {
2576f9291ceSJung-uk Kim             if (--argc < 1)
2586f9291ceSJung-uk Kim                 goto bad;
25974664626SKris Kennaway             keyform = str2fmt(*(++argv));
2606f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-in") == 0) {
2616f9291ceSJung-uk Kim             if (--argc < 1)
2626f9291ceSJung-uk Kim                 goto bad;
26374664626SKris Kennaway             infile = *(++argv);
2646f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-out") == 0) {
2656f9291ceSJung-uk Kim             if (--argc < 1)
2666f9291ceSJung-uk Kim                 goto bad;
26774664626SKris Kennaway             outfile = *(++argv);
2686f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-keyout") == 0) {
2696f9291ceSJung-uk Kim             if (--argc < 1)
2706f9291ceSJung-uk Kim                 goto bad;
27174664626SKris Kennaway             keyout = *(++argv);
2726f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-passin") == 0) {
2736f9291ceSJung-uk Kim             if (--argc < 1)
2746f9291ceSJung-uk Kim                 goto bad;
275f579bf8eSKris Kennaway             passargin = *(++argv);
2766f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-passout") == 0) {
2776f9291ceSJung-uk Kim             if (--argc < 1)
2786f9291ceSJung-uk Kim                 goto bad;
279f579bf8eSKris Kennaway             passargout = *(++argv);
2806f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-rand") == 0) {
2816f9291ceSJung-uk Kim             if (--argc < 1)
2826f9291ceSJung-uk Kim                 goto bad;
283ddd58736SKris Kennaway             inrand = *(++argv);
2846f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-newkey") == 0) {
2851f13597dSJung-uk Kim             if (--argc < 1)
2861f13597dSJung-uk Kim                 goto bad;
2871f13597dSJung-uk Kim             keyalg = *(++argv);
2881f13597dSJung-uk Kim             newreq = 1;
2896f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-pkeyopt") == 0) {
2901f13597dSJung-uk Kim             if (--argc < 1)
2911f13597dSJung-uk Kim                 goto bad;
2921f13597dSJung-uk Kim             if (!pkeyopts)
2931f13597dSJung-uk Kim                 pkeyopts = sk_OPENSSL_STRING_new_null();
2941f13597dSJung-uk Kim             if (!pkeyopts || !sk_OPENSSL_STRING_push(pkeyopts, *(++argv)))
2953b4e3dcbSSimon L. B. Nielsen                 goto bad;
2966f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-sigopt") == 0) {
2971f13597dSJung-uk Kim             if (--argc < 1)
2981f13597dSJung-uk Kim                 goto bad;
2991f13597dSJung-uk Kim             if (!sigopts)
3001f13597dSJung-uk Kim                 sigopts = sk_OPENSSL_STRING_new_null();
3011f13597dSJung-uk Kim             if (!sigopts || !sk_OPENSSL_STRING_push(sigopts, *(++argv)))
3021f13597dSJung-uk Kim                 goto bad;
3036f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-batch") == 0)
3045c87c606SMark Murray             batch = 1;
305f579bf8eSKris Kennaway         else if (strcmp(*argv, "-newhdr") == 0)
306f579bf8eSKris Kennaway             newhdr = 1;
30774664626SKris Kennaway         else if (strcmp(*argv, "-modulus") == 0)
30874664626SKris Kennaway             modulus = 1;
30974664626SKris Kennaway         else if (strcmp(*argv, "-verify") == 0)
31074664626SKris Kennaway             verify = 1;
31174664626SKris Kennaway         else if (strcmp(*argv, "-nodes") == 0)
31274664626SKris Kennaway             nodes = 1;
31374664626SKris Kennaway         else if (strcmp(*argv, "-noout") == 0)
31474664626SKris Kennaway             noout = 1;
3155c87c606SMark Murray         else if (strcmp(*argv, "-verbose") == 0)
3165c87c606SMark Murray             verbose = 1;
3175c87c606SMark Murray         else if (strcmp(*argv, "-utf8") == 0)
3185c87c606SMark Murray             chtype = MBSTRING_UTF8;
3196f9291ceSJung-uk Kim         else if (strcmp(*argv, "-nameopt") == 0) {
3206f9291ceSJung-uk Kim             if (--argc < 1)
3216f9291ceSJung-uk Kim                 goto bad;
3226f9291ceSJung-uk Kim             if (!set_name_ex(&nmflag, *(++argv)))
3236f9291ceSJung-uk Kim                 goto bad;
3246f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-reqopt") == 0) {
3256f9291ceSJung-uk Kim             if (--argc < 1)
3266f9291ceSJung-uk Kim                 goto bad;
3276f9291ceSJung-uk Kim             if (!set_cert_ex(&reqflag, *(++argv)))
3286f9291ceSJung-uk Kim                 goto bad;
3296f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-subject") == 0)
3305c87c606SMark Murray             subject = 1;
33174664626SKris Kennaway         else if (strcmp(*argv, "-text") == 0)
33274664626SKris Kennaway             text = 1;
333aeb5019cSJung-uk Kim         else if (strcmp(*argv, "-x509") == 0) {
33474664626SKris Kennaway             x509 = 1;
335aeb5019cSJung-uk Kim         } else if (strcmp(*argv, "-asn1-kludge") == 0)
33674664626SKris Kennaway             kludge = 1;
33774664626SKris Kennaway         else if (strcmp(*argv, "-no-asn1-kludge") == 0)
33874664626SKris Kennaway             kludge = 0;
3396f9291ceSJung-uk Kim         else if (strcmp(*argv, "-subj") == 0) {
3406f9291ceSJung-uk Kim             if (--argc < 1)
3416f9291ceSJung-uk Kim                 goto bad;
3425c87c606SMark Murray             subj = *(++argv);
3436f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-multivalue-rdn") == 0)
3443b4e3dcbSSimon L. B. Nielsen             multirdn = 1;
3456f9291ceSJung-uk Kim         else if (strcmp(*argv, "-days") == 0) {
3466f9291ceSJung-uk Kim             if (--argc < 1)
3476f9291ceSJung-uk Kim                 goto bad;
34874664626SKris Kennaway             days = atoi(*(++argv));
3496f9291ceSJung-uk Kim             if (days == 0)
3506f9291ceSJung-uk Kim                 days = 30;
3516f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-set_serial") == 0) {
3526f9291ceSJung-uk Kim             if (--argc < 1)
3536f9291ceSJung-uk Kim                 goto bad;
3545c87c606SMark Murray             serial = s2i_ASN1_INTEGER(NULL, *(++argv));
3556f9291ceSJung-uk Kim             if (!serial)
3566f9291ceSJung-uk Kim                 goto bad;
3576f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-extensions") == 0) {
3586f9291ceSJung-uk Kim             if (--argc < 1)
3596f9291ceSJung-uk Kim                 goto bad;
360f579bf8eSKris Kennaway             extensions = *(++argv);
3616f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-reqexts") == 0) {
3626f9291ceSJung-uk Kim             if (--argc < 1)
3636f9291ceSJung-uk Kim                 goto bad;
364f579bf8eSKris Kennaway             req_exts = *(++argv);
3656f9291ceSJung-uk Kim         } else if ((md_alg = EVP_get_digestbyname(&((*argv)[1]))) != NULL) {
3661f13597dSJung-uk Kim             /* ok */
3671f13597dSJung-uk Kim             digest = md_alg;
3686f9291ceSJung-uk Kim         } else {
36974664626SKris Kennaway             BIO_printf(bio_err, "unknown option %s\n", *argv);
37074664626SKris Kennaway             badops = 1;
37174664626SKris Kennaway             break;
37274664626SKris Kennaway         }
37374664626SKris Kennaway         argc--;
37474664626SKris Kennaway         argv++;
37574664626SKris Kennaway     }
37674664626SKris Kennaway 
3776f9291ceSJung-uk Kim     if (badops) {
37874664626SKris Kennaway  bad:
37974664626SKris Kennaway         BIO_printf(bio_err, "%s [options] <infile >outfile\n", prog);
38074664626SKris Kennaway         BIO_printf(bio_err, "where options  are\n");
381f579bf8eSKris Kennaway         BIO_printf(bio_err, " -inform arg    input format - DER or PEM\n");
382f579bf8eSKris Kennaway         BIO_printf(bio_err, " -outform arg   output format - DER or PEM\n");
38374664626SKris Kennaway         BIO_printf(bio_err, " -in arg        input file\n");
38474664626SKris Kennaway         BIO_printf(bio_err, " -out arg       output file\n");
38574664626SKris Kennaway         BIO_printf(bio_err, " -text          text form of request\n");
3865c87c606SMark Murray         BIO_printf(bio_err, " -pubkey        output public key\n");
38774664626SKris Kennaway         BIO_printf(bio_err, " -noout         do not output REQ\n");
38874664626SKris Kennaway         BIO_printf(bio_err, " -verify        verify signature on REQ\n");
38974664626SKris Kennaway         BIO_printf(bio_err, " -modulus       RSA modulus\n");
39074664626SKris Kennaway         BIO_printf(bio_err, " -nodes         don't encrypt the output key\n");
391fceca8a3SJacques Vidrine #ifndef OPENSSL_NO_ENGINE
3926f9291ceSJung-uk Kim         BIO_printf(bio_err,
3936f9291ceSJung-uk Kim                    " -engine e      use engine e, possibly a hardware device\n");
394fceca8a3SJacques Vidrine #endif
3955c87c606SMark Murray         BIO_printf(bio_err, " -subject       output the request's subject\n");
3965c87c606SMark Murray         BIO_printf(bio_err, " -passin        private key password source\n");
3976f9291ceSJung-uk Kim         BIO_printf(bio_err,
3986f9291ceSJung-uk Kim                    " -key file      use the private key contained in file\n");
39974664626SKris Kennaway         BIO_printf(bio_err, " -keyform arg   key file format\n");
40074664626SKris Kennaway         BIO_printf(bio_err, " -keyout arg    file to send the key to\n");
4016f9291ceSJung-uk Kim         BIO_printf(bio_err, " -rand file%cfile%c...\n", LIST_SEPARATOR_CHAR,
4026f9291ceSJung-uk Kim                    LIST_SEPARATOR_CHAR);
4036f9291ceSJung-uk Kim         BIO_printf(bio_err,
4046f9291ceSJung-uk Kim                    "                load the file (or the files in the directory) into\n");
405ddd58736SKris Kennaway         BIO_printf(bio_err, "                the random number generator\n");
4066f9291ceSJung-uk Kim         BIO_printf(bio_err,
4076f9291ceSJung-uk Kim                    " -newkey rsa:bits generate a new RSA key of 'bits' in size\n");
4086f9291ceSJung-uk Kim         BIO_printf(bio_err,
4096f9291ceSJung-uk Kim                    " -newkey dsa:file generate a new DSA key, parameters taken from CA in 'file'\n");
4103b4e3dcbSSimon L. B. Nielsen #ifndef OPENSSL_NO_ECDSA
4116f9291ceSJung-uk Kim         BIO_printf(bio_err,
4126f9291ceSJung-uk Kim                    " -newkey ec:file generate a new EC key, parameters taken from CA in 'file'\n");
4133b4e3dcbSSimon L. B. Nielsen #endif
4146f9291ceSJung-uk Kim         BIO_printf(bio_err,
4156f9291ceSJung-uk Kim                    " -[digest]      Digest to sign with (md5, sha1, md2, mdc2, md4)\n");
41674664626SKris Kennaway         BIO_printf(bio_err, " -config file   request template file.\n");
4176f9291ceSJung-uk Kim         BIO_printf(bio_err,
4186f9291ceSJung-uk Kim                    " -subj arg      set or modify request subject\n");
4196f9291ceSJung-uk Kim         BIO_printf(bio_err,
4206f9291ceSJung-uk Kim                    " -multivalue-rdn enable support for multivalued RDNs\n");
42174664626SKris Kennaway         BIO_printf(bio_err, " -new           new request.\n");
4226f9291ceSJung-uk Kim         BIO_printf(bio_err,
4236f9291ceSJung-uk Kim                    " -batch         do not ask anything during request generation\n");
4246f9291ceSJung-uk Kim         BIO_printf(bio_err,
4256f9291ceSJung-uk Kim                    " -x509          output a x509 structure instead of a cert. req.\n");
4266f9291ceSJung-uk Kim         BIO_printf(bio_err,
4276f9291ceSJung-uk Kim                    " -days          number of days a certificate generated by -x509 is valid for.\n");
4286f9291ceSJung-uk Kim         BIO_printf(bio_err,
4296f9291ceSJung-uk Kim                    " -set_serial    serial number to use for a certificate generated by -x509.\n");
4306f9291ceSJung-uk Kim         BIO_printf(bio_err,
4316f9291ceSJung-uk Kim                    " -newhdr        output \"NEW\" in the header lines\n");
4326f9291ceSJung-uk Kim         BIO_printf(bio_err,
4336f9291ceSJung-uk Kim                    " -asn1-kludge   Output the 'request' in a format that is wrong but some CA's\n");
4346f9291ceSJung-uk Kim         BIO_printf(bio_err,
4356f9291ceSJung-uk Kim                    "                have been reported as requiring\n");
4366f9291ceSJung-uk Kim         BIO_printf(bio_err,
4376f9291ceSJung-uk Kim                    " -extensions .. specify certificate extension section (override value in config file)\n");
4386f9291ceSJung-uk Kim         BIO_printf(bio_err,
4396f9291ceSJung-uk Kim                    " -reqexts ..    specify request extension section (override value in config file)\n");
4406f9291ceSJung-uk Kim         BIO_printf(bio_err,
4416f9291ceSJung-uk Kim                    " -utf8          input characters are UTF8 (default ASCII)\n");
4426f9291ceSJung-uk Kim         BIO_printf(bio_err,
4436f9291ceSJung-uk Kim                    " -nameopt arg    - various certificate name options\n");
4446f9291ceSJung-uk Kim         BIO_printf(bio_err,
4456f9291ceSJung-uk Kim                    " -reqopt arg    - various request text options\n\n");
44674664626SKris Kennaway         goto end;
44774664626SKris Kennaway     }
44874664626SKris Kennaway 
449*ed7112f0SJung-uk Kim     if (x509 && infile == NULL)
450*ed7112f0SJung-uk Kim         newreq = 1;
451*ed7112f0SJung-uk Kim 
45274664626SKris Kennaway     ERR_load_crypto_strings();
453f579bf8eSKris Kennaway     if (!app_passwd(bio_err, passargin, passargout, &passin, &passout)) {
454f579bf8eSKris Kennaway         BIO_printf(bio_err, "Error getting passwords\n");
455f579bf8eSKris Kennaway         goto end;
456f579bf8eSKris Kennaway     }
4576f9291ceSJung-uk Kim #ifndef MONOLITH                /* else this has happened in openssl.c
4586f9291ceSJung-uk Kim                                  * (global `config') */
45974664626SKris Kennaway     /* Lets load up our environment a little */
46074664626SKris Kennaway     p = getenv("OPENSSL_CONF");
46174664626SKris Kennaway     if (p == NULL)
46274664626SKris Kennaway         p = getenv("SSLEAY_CONF");
46374664626SKris Kennaway     if (p == NULL)
4645c87c606SMark Murray         p = to_free = make_config_name();
46574664626SKris Kennaway     default_config_file = p;
4665c87c606SMark Murray     config = NCONF_new(NULL);
4675c87c606SMark Murray     i = NCONF_load(config, p, &errline);
46874664626SKris Kennaway #endif
46974664626SKris Kennaway 
4706f9291ceSJung-uk Kim     if (template != NULL) {
4715c87c606SMark Murray         long errline = -1;
47274664626SKris Kennaway 
4735c87c606SMark Murray         if (verbose)
47474664626SKris Kennaway             BIO_printf(bio_err, "Using configuration from %s\n", template);
4755c87c606SMark Murray         req_conf = NCONF_new(NULL);
4765c87c606SMark Murray         i = NCONF_load(req_conf, template, &errline);
4776f9291ceSJung-uk Kim         if (i == 0) {
4786f9291ceSJung-uk Kim             BIO_printf(bio_err, "error on line %ld of %s\n", errline,
4796f9291ceSJung-uk Kim                        template);
48074664626SKris Kennaway             goto end;
48174664626SKris Kennaway         }
4826f9291ceSJung-uk Kim     } else {
48374664626SKris Kennaway         req_conf = config;
4843b4e3dcbSSimon L. B. Nielsen 
4856f9291ceSJung-uk Kim         if (req_conf == NULL) {
4866f9291ceSJung-uk Kim             BIO_printf(bio_err, "Unable to load config info from %s\n",
4876f9291ceSJung-uk Kim                        default_config_file);
4883b4e3dcbSSimon L. B. Nielsen             if (newreq)
4893b4e3dcbSSimon L. B. Nielsen                 goto end;
4906f9291ceSJung-uk Kim         } else if (verbose)
4913b4e3dcbSSimon L. B. Nielsen             BIO_printf(bio_err, "Using configuration from %s\n",
4923b4e3dcbSSimon L. B. Nielsen                        default_config_file);
49374664626SKris Kennaway     }
49474664626SKris Kennaway 
4956f9291ceSJung-uk Kim     if (req_conf != NULL) {
4965c87c606SMark Murray         if (!load_config(bio_err, req_conf))
4975c87c606SMark Murray             goto end;
4985c87c606SMark Murray         p = NCONF_get_string(req_conf, NULL, "oid_file");
4995c87c606SMark Murray         if (p == NULL)
5005c87c606SMark Murray             ERR_clear_error();
5016f9291ceSJung-uk Kim         if (p != NULL) {
50274664626SKris Kennaway             BIO *oid_bio;
50374664626SKris Kennaway 
50474664626SKris Kennaway             oid_bio = BIO_new_file(p, "r");
5056f9291ceSJung-uk Kim             if (oid_bio == NULL) {
5066f9291ceSJung-uk Kim                 /*-
50774664626SKris Kennaway                 BIO_printf(bio_err,"problems opening %s for extra oid's\n",p);
50874664626SKris Kennaway                 ERR_print_errors(bio_err);
50974664626SKris Kennaway                 */
5106f9291ceSJung-uk Kim             } else {
51174664626SKris Kennaway                 OBJ_create_objects(oid_bio);
51274664626SKris Kennaway                 BIO_free(oid_bio);
51374664626SKris Kennaway             }
51474664626SKris Kennaway         }
51574664626SKris Kennaway     }
5166f9291ceSJung-uk Kim     if (!add_oid_section(bio_err, req_conf))
5176f9291ceSJung-uk Kim         goto end;
51874664626SKris Kennaway 
5196f9291ceSJung-uk Kim     if (md_alg == NULL) {
5205c87c606SMark Murray         p = NCONF_get_string(req_conf, SECTION, "default_md");
5215c87c606SMark Murray         if (p == NULL)
5225c87c606SMark Murray             ERR_clear_error();
5236f9291ceSJung-uk Kim         if (p != NULL) {
52474664626SKris Kennaway             if ((md_alg = EVP_get_digestbyname(p)) != NULL)
52574664626SKris Kennaway                 digest = md_alg;
52674664626SKris Kennaway         }
5275c87c606SMark Murray     }
52874664626SKris Kennaway 
5296f9291ceSJung-uk Kim     if (!extensions) {
5305c87c606SMark Murray         extensions = NCONF_get_string(req_conf, SECTION, V3_EXTENSIONS);
5315c87c606SMark Murray         if (!extensions)
5325c87c606SMark Murray             ERR_clear_error();
5335c87c606SMark Murray     }
53474664626SKris Kennaway     if (extensions) {
53574664626SKris Kennaway         /* Check syntax of file */
53674664626SKris Kennaway         X509V3_CTX ctx;
53774664626SKris Kennaway         X509V3_set_ctx_test(&ctx);
5385c87c606SMark Murray         X509V3_set_nconf(&ctx, req_conf);
5395c87c606SMark Murray         if (!X509V3_EXT_add_nconf(req_conf, &ctx, extensions, NULL)) {
54074664626SKris Kennaway             BIO_printf(bio_err,
54174664626SKris Kennaway                        "Error Loading extension section %s\n", extensions);
54274664626SKris Kennaway             goto end;
54374664626SKris Kennaway         }
54474664626SKris Kennaway     }
54574664626SKris Kennaway 
5466f9291ceSJung-uk Kim     if (!passin) {
5475c87c606SMark Murray         passin = NCONF_get_string(req_conf, SECTION, "input_password");
5485c87c606SMark Murray         if (!passin)
5495c87c606SMark Murray             ERR_clear_error();
5505c87c606SMark Murray     }
551f579bf8eSKris Kennaway 
5526f9291ceSJung-uk Kim     if (!passout) {
5535c87c606SMark Murray         passout = NCONF_get_string(req_conf, SECTION, "output_password");
5545c87c606SMark Murray         if (!passout)
5555c87c606SMark Murray             ERR_clear_error();
5565c87c606SMark Murray     }
557f579bf8eSKris Kennaway 
5585c87c606SMark Murray     p = NCONF_get_string(req_conf, SECTION, STRING_MASK);
5595c87c606SMark Murray     if (!p)
5605c87c606SMark Murray         ERR_clear_error();
561f579bf8eSKris Kennaway 
562f579bf8eSKris Kennaway     if (p && !ASN1_STRING_set_default_mask_asc(p)) {
563f579bf8eSKris Kennaway         BIO_printf(bio_err, "Invalid global string mask setting %s\n", p);
564f579bf8eSKris Kennaway         goto end;
565f579bf8eSKris Kennaway     }
566f579bf8eSKris Kennaway 
5676f9291ceSJung-uk Kim     if (chtype != MBSTRING_UTF8) {
5685c87c606SMark Murray         p = NCONF_get_string(req_conf, SECTION, UTF8_IN);
5695c87c606SMark Murray         if (!p)
5705c87c606SMark Murray             ERR_clear_error();
5715c87c606SMark Murray         else if (!strcmp(p, "yes"))
5725c87c606SMark Murray             chtype = MBSTRING_UTF8;
5735c87c606SMark Murray     }
5745c87c606SMark Murray 
5756f9291ceSJung-uk Kim     if (!req_exts) {
5765c87c606SMark Murray         req_exts = NCONF_get_string(req_conf, SECTION, REQ_EXTENSIONS);
5775c87c606SMark Murray         if (!req_exts)
5785c87c606SMark Murray             ERR_clear_error();
5795c87c606SMark Murray     }
580f579bf8eSKris Kennaway     if (req_exts) {
581f579bf8eSKris Kennaway         /* Check syntax of file */
582f579bf8eSKris Kennaway         X509V3_CTX ctx;
583f579bf8eSKris Kennaway         X509V3_set_ctx_test(&ctx);
5845c87c606SMark Murray         X509V3_set_nconf(&ctx, req_conf);
5855c87c606SMark Murray         if (!X509V3_EXT_add_nconf(req_conf, &ctx, req_exts, NULL)) {
586f579bf8eSKris Kennaway             BIO_printf(bio_err,
587f579bf8eSKris Kennaway                        "Error Loading request extension section %s\n",
588f579bf8eSKris Kennaway                        req_exts);
589f579bf8eSKris Kennaway             goto end;
590f579bf8eSKris Kennaway         }
591f579bf8eSKris Kennaway     }
592f579bf8eSKris Kennaway 
59374664626SKris Kennaway     in = BIO_new(BIO_s_file());
59474664626SKris Kennaway     out = BIO_new(BIO_s_file());
59574664626SKris Kennaway     if ((in == NULL) || (out == NULL))
59674664626SKris Kennaway         goto end;
59774664626SKris Kennaway 
5985c87c606SMark Murray     e = setup_engine(bio_err, engine, 0);
5995c87c606SMark Murray 
6006f9291ceSJung-uk Kim     if (keyfile != NULL) {
6015c87c606SMark Murray         pkey = load_key(bio_err, keyfile, keyform, 0, passin, e,
6025c87c606SMark Murray                         "Private Key");
6036f9291ceSJung-uk Kim         if (!pkey) {
6046f9291ceSJung-uk Kim             /*
6056f9291ceSJung-uk Kim              * load_key() has already printed an appropriate message
6066f9291ceSJung-uk Kim              */
60774664626SKris Kennaway             goto end;
6086f9291ceSJung-uk Kim         } else {
6095c87c606SMark Murray             char *randfile = NCONF_get_string(req_conf, SECTION, "RANDFILE");
6105c87c606SMark Murray             if (randfile == NULL)
6115c87c606SMark Murray                 ERR_clear_error();
612ddd58736SKris Kennaway             app_RAND_load_file(randfile, bio_err, 0);
613ddd58736SKris Kennaway         }
61474664626SKris Kennaway     }
61574664626SKris Kennaway 
6166f9291ceSJung-uk Kim     if (newreq && (pkey == NULL)) {
6175c87c606SMark Murray         char *randfile = NCONF_get_string(req_conf, SECTION, "RANDFILE");
6185c87c606SMark Murray         if (randfile == NULL)
6195c87c606SMark Murray             ERR_clear_error();
620f579bf8eSKris Kennaway         app_RAND_load_file(randfile, bio_err, 0);
621ddd58736SKris Kennaway         if (inrand)
622ddd58736SKris Kennaway             app_RAND_load_files(inrand);
62374664626SKris Kennaway 
6246f9291ceSJung-uk Kim         if (!NCONF_get_number(req_conf, SECTION, BITS, &newkey)) {
625560ede85SJung-uk Kim             newkey = DEFAULT_KEY_LENGTH;
626560ede85SJung-uk Kim         }
627560ede85SJung-uk Kim 
6286f9291ceSJung-uk Kim         if (keyalg) {
6291f13597dSJung-uk Kim             genctx = set_keygen_ctx(bio_err, keyalg, &pkey_type, &newkey,
6301f13597dSJung-uk Kim                                     &keyalgstr, gen_eng);
6311f13597dSJung-uk Kim             if (!genctx)
6321f13597dSJung-uk Kim                 goto end;
6331f13597dSJung-uk Kim         }
6341f13597dSJung-uk Kim 
6356f9291ceSJung-uk Kim         if (newkey < MIN_KEY_LENGTH
6366f9291ceSJung-uk Kim             && (pkey_type == EVP_PKEY_RSA || pkey_type == EVP_PKEY_DSA)) {
63774664626SKris Kennaway             BIO_printf(bio_err, "private key length is too short,\n");
6386f9291ceSJung-uk Kim             BIO_printf(bio_err, "it needs to be at least %d bits, not %ld\n",
6396f9291ceSJung-uk Kim                        MIN_KEY_LENGTH, newkey);
64074664626SKris Kennaway             goto end;
64174664626SKris Kennaway         }
6421f13597dSJung-uk Kim 
6436f9291ceSJung-uk Kim         if (!genctx) {
6441f13597dSJung-uk Kim             genctx = set_keygen_ctx(bio_err, NULL, &pkey_type, &newkey,
6451f13597dSJung-uk Kim                                     &keyalgstr, gen_eng);
6461f13597dSJung-uk Kim             if (!genctx)
6471f13597dSJung-uk Kim                 goto end;
6481f13597dSJung-uk Kim         }
6491f13597dSJung-uk Kim 
6506f9291ceSJung-uk Kim         if (pkeyopts) {
6511f13597dSJung-uk Kim             char *genopt;
6526f9291ceSJung-uk Kim             for (i = 0; i < sk_OPENSSL_STRING_num(pkeyopts); i++) {
6531f13597dSJung-uk Kim                 genopt = sk_OPENSSL_STRING_value(pkeyopts, i);
6546f9291ceSJung-uk Kim                 if (pkey_ctrl_string(genctx, genopt) <= 0) {
6556f9291ceSJung-uk Kim                     BIO_printf(bio_err, "parameter error \"%s\"\n", genopt);
6561f13597dSJung-uk Kim                     ERR_print_errors(bio_err);
6571f13597dSJung-uk Kim                     goto end;
6581f13597dSJung-uk Kim                 }
6591f13597dSJung-uk Kim             }
6601f13597dSJung-uk Kim         }
6611f13597dSJung-uk Kim 
6623b4e3dcbSSimon L. B. Nielsen         BIO_printf(bio_err, "Generating a %ld bit %s private key\n",
6631f13597dSJung-uk Kim                    newkey, keyalgstr);
66474664626SKris Kennaway 
6651f13597dSJung-uk Kim         EVP_PKEY_CTX_set_cb(genctx, genpkey_cb);
6661f13597dSJung-uk Kim         EVP_PKEY_CTX_set_app_data(genctx, bio_err);
66774664626SKris Kennaway 
6686f9291ceSJung-uk Kim         if (EVP_PKEY_keygen(genctx, &pkey) <= 0) {
6691f13597dSJung-uk Kim             BIO_puts(bio_err, "Error Generating Key\n");
67074664626SKris Kennaway             goto end;
67174664626SKris Kennaway         }
6721f13597dSJung-uk Kim 
6731f13597dSJung-uk Kim         EVP_PKEY_CTX_free(genctx);
6741f13597dSJung-uk Kim         genctx = NULL;
67574664626SKris Kennaway 
676f579bf8eSKris Kennaway         app_RAND_write_file(randfile, bio_err);
67774664626SKris Kennaway 
6786f9291ceSJung-uk Kim         if (keyout == NULL) {
6795c87c606SMark Murray             keyout = NCONF_get_string(req_conf, SECTION, KEYFILE);
6805c87c606SMark Murray             if (keyout == NULL)
6815c87c606SMark Murray                 ERR_clear_error();
6825c87c606SMark Murray         }
68374664626SKris Kennaway 
6846f9291ceSJung-uk Kim         if (keyout == NULL) {
68574664626SKris Kennaway             BIO_printf(bio_err, "writing new private key to stdout\n");
68674664626SKris Kennaway             BIO_set_fp(out, stdout, BIO_NOCLOSE);
6875c87c606SMark Murray #ifdef OPENSSL_SYS_VMS
688ddd58736SKris Kennaway             {
689ddd58736SKris Kennaway                 BIO *tmpbio = BIO_new(BIO_f_linebuffer());
690ddd58736SKris Kennaway                 out = BIO_push(tmpbio, out);
691ddd58736SKris Kennaway             }
692ddd58736SKris Kennaway #endif
6936f9291ceSJung-uk Kim         } else {
69474664626SKris Kennaway             BIO_printf(bio_err, "writing new private key to '%s'\n", keyout);
6956f9291ceSJung-uk Kim             if (BIO_write_filename(out, keyout) <= 0) {
69674664626SKris Kennaway                 perror(keyout);
69774664626SKris Kennaway                 goto end;
69874664626SKris Kennaway             }
69974664626SKris Kennaway         }
70074664626SKris Kennaway 
7015c87c606SMark Murray         p = NCONF_get_string(req_conf, SECTION, "encrypt_rsa_key");
7026f9291ceSJung-uk Kim         if (p == NULL) {
7035c87c606SMark Murray             ERR_clear_error();
7045c87c606SMark Murray             p = NCONF_get_string(req_conf, SECTION, "encrypt_key");
7055c87c606SMark Murray             if (p == NULL)
7065c87c606SMark Murray                 ERR_clear_error();
7075c87c606SMark Murray         }
70874664626SKris Kennaway         if ((p != NULL) && (strcmp(p, "no") == 0))
70974664626SKris Kennaway             cipher = NULL;
7106f9291ceSJung-uk Kim         if (nodes)
7116f9291ceSJung-uk Kim             cipher = NULL;
71274664626SKris Kennaway 
71374664626SKris Kennaway         i = 0;
71474664626SKris Kennaway  loop:
71574664626SKris Kennaway         if (!PEM_write_bio_PrivateKey(out, pkey, cipher,
7166f9291ceSJung-uk Kim                                       NULL, 0, NULL, passout)) {
71774664626SKris Kennaway             if ((ERR_GET_REASON(ERR_peek_error()) ==
7186f9291ceSJung-uk Kim                  PEM_R_PROBLEMS_GETTING_PASSWORD) && (i < 3)) {
71974664626SKris Kennaway                 ERR_clear_error();
72074664626SKris Kennaway                 i++;
72174664626SKris Kennaway                 goto loop;
72274664626SKris Kennaway             }
72374664626SKris Kennaway             goto end;
72474664626SKris Kennaway         }
72574664626SKris Kennaway         BIO_printf(bio_err, "-----\n");
72674664626SKris Kennaway     }
72774664626SKris Kennaway 
7286f9291ceSJung-uk Kim     if (!newreq) {
7296f9291ceSJung-uk Kim         /*
7306f9291ceSJung-uk Kim          * Since we are using a pre-existing certificate request, the kludge
7316f9291ceSJung-uk Kim          * 'format' info should not be changed.
7326f9291ceSJung-uk Kim          */
73374664626SKris Kennaway         kludge = -1;
73474664626SKris Kennaway         if (infile == NULL)
73574664626SKris Kennaway             BIO_set_fp(in, stdin, BIO_NOCLOSE);
7366f9291ceSJung-uk Kim         else {
7376f9291ceSJung-uk Kim             if (BIO_read_filename(in, infile) <= 0) {
73874664626SKris Kennaway                 perror(infile);
73974664626SKris Kennaway                 goto end;
74074664626SKris Kennaway             }
74174664626SKris Kennaway         }
74274664626SKris Kennaway 
74374664626SKris Kennaway         if (informat == FORMAT_ASN1)
74474664626SKris Kennaway             req = d2i_X509_REQ_bio(in, NULL);
74574664626SKris Kennaway         else if (informat == FORMAT_PEM)
74674664626SKris Kennaway             req = PEM_read_bio_X509_REQ(in, NULL, NULL, NULL);
7476f9291ceSJung-uk Kim         else {
7486f9291ceSJung-uk Kim             BIO_printf(bio_err,
7496f9291ceSJung-uk Kim                        "bad input format specified for X509 request\n");
75074664626SKris Kennaway             goto end;
75174664626SKris Kennaway         }
7526f9291ceSJung-uk Kim         if (req == NULL) {
75374664626SKris Kennaway             BIO_printf(bio_err, "unable to load X509 request\n");
75474664626SKris Kennaway             goto end;
75574664626SKris Kennaway         }
75674664626SKris Kennaway     }
75774664626SKris Kennaway 
758*ed7112f0SJung-uk Kim     if (newreq || x509) {
7596f9291ceSJung-uk Kim         if (pkey == NULL) {
76074664626SKris Kennaway             BIO_printf(bio_err, "you need to specify a private key\n");
76174664626SKris Kennaway             goto end;
76274664626SKris Kennaway         }
7631f13597dSJung-uk Kim 
7646f9291ceSJung-uk Kim         if (req == NULL) {
76574664626SKris Kennaway             req = X509_REQ_new();
7666f9291ceSJung-uk Kim             if (req == NULL) {
76774664626SKris Kennaway                 goto end;
76874664626SKris Kennaway             }
76974664626SKris Kennaway 
7703b4e3dcbSSimon L. B. Nielsen             i = make_REQ(req, pkey, subj, multirdn, !x509, chtype);
7715c87c606SMark Murray             subj = NULL;        /* done processing '-subj' option */
7726f9291ceSJung-uk Kim             if ((kludge > 0)
7736f9291ceSJung-uk Kim                 && !sk_X509_ATTRIBUTE_num(req->req_info->attributes)) {
7745c87c606SMark Murray                 sk_X509_ATTRIBUTE_free(req->req_info->attributes);
7755c87c606SMark Murray                 req->req_info->attributes = NULL;
7765c87c606SMark Murray             }
7776f9291ceSJung-uk Kim             if (!i) {
77874664626SKris Kennaway                 BIO_printf(bio_err, "problems making Certificate Request\n");
77974664626SKris Kennaway                 goto end;
78074664626SKris Kennaway             }
78174664626SKris Kennaway         }
7826f9291ceSJung-uk Kim         if (x509) {
78374664626SKris Kennaway             EVP_PKEY *tmppkey;
78474664626SKris Kennaway             X509V3_CTX ext_ctx;
7856f9291ceSJung-uk Kim             if ((x509ss = X509_new()) == NULL)
7866f9291ceSJung-uk Kim                 goto end;
78774664626SKris Kennaway 
78874664626SKris Kennaway             /* Set version to V3 */
7896f9291ceSJung-uk Kim             if (extensions && !X509_set_version(x509ss, 2))
7906f9291ceSJung-uk Kim                 goto end;
7916f9291ceSJung-uk Kim             if (serial) {
7926f9291ceSJung-uk Kim                 if (!X509_set_serialNumber(x509ss, serial))
7936f9291ceSJung-uk Kim                     goto end;
7946f9291ceSJung-uk Kim             } else {
7956f9291ceSJung-uk Kim                 if (!rand_serial(NULL, X509_get_serialNumber(x509ss)))
7966be8ae07SJacques Vidrine                     goto end;
7975c87c606SMark Murray             }
79874664626SKris Kennaway 
7996f9291ceSJung-uk Kim             if (!X509_set_issuer_name(x509ss, X509_REQ_get_subject_name(req)))
8006f9291ceSJung-uk Kim                 goto end;
8016f9291ceSJung-uk Kim             if (!X509_gmtime_adj(X509_get_notBefore(x509ss), 0))
8026f9291ceSJung-uk Kim                 goto end;
8036f9291ceSJung-uk Kim             if (!X509_time_adj_ex(X509_get_notAfter(x509ss), days, 0, NULL))
8046f9291ceSJung-uk Kim                 goto end;
8056f9291ceSJung-uk Kim             if (!X509_set_subject_name
8066f9291ceSJung-uk Kim                 (x509ss, X509_REQ_get_subject_name(req)))
8076f9291ceSJung-uk Kim                 goto end;
80874664626SKris Kennaway             tmppkey = X509_REQ_get_pubkey(req);
8096f9291ceSJung-uk Kim             if (!tmppkey || !X509_set_pubkey(x509ss, tmppkey))
8106f9291ceSJung-uk Kim                 goto end;
81174664626SKris Kennaway             EVP_PKEY_free(tmppkey);
81274664626SKris Kennaway 
81374664626SKris Kennaway             /* Set up V3 context struct */
81474664626SKris Kennaway 
81574664626SKris Kennaway             X509V3_set_ctx(&ext_ctx, x509ss, x509ss, NULL, NULL, 0);
8165c87c606SMark Murray             X509V3_set_nconf(&ext_ctx, req_conf);
81774664626SKris Kennaway 
81874664626SKris Kennaway             /* Add extensions */
8195c87c606SMark Murray             if (extensions && !X509V3_EXT_add_nconf(req_conf,
8206f9291ceSJung-uk Kim                                                     &ext_ctx, extensions,
8216f9291ceSJung-uk Kim                                                     x509ss)) {
8226f9291ceSJung-uk Kim                 BIO_printf(bio_err, "Error Loading extension section %s\n",
82374664626SKris Kennaway                            extensions);
82474664626SKris Kennaway                 goto end;
82574664626SKris Kennaway             }
82674664626SKris Kennaway 
8271f13597dSJung-uk Kim             i = do_X509_sign(bio_err, x509ss, pkey, digest, sigopts);
8286f9291ceSJung-uk Kim             if (!i) {
8291f13597dSJung-uk Kim                 ERR_print_errors(bio_err);
83074664626SKris Kennaway                 goto end;
83174664626SKris Kennaway             }
8326f9291ceSJung-uk Kim         } else {
833f579bf8eSKris Kennaway             X509V3_CTX ext_ctx;
834f579bf8eSKris Kennaway 
835f579bf8eSKris Kennaway             /* Set up V3 context struct */
836f579bf8eSKris Kennaway 
837f579bf8eSKris Kennaway             X509V3_set_ctx(&ext_ctx, NULL, NULL, req, NULL, 0);
8385c87c606SMark Murray             X509V3_set_nconf(&ext_ctx, req_conf);
839f579bf8eSKris Kennaway 
840f579bf8eSKris Kennaway             /* Add extensions */
8415c87c606SMark Murray             if (req_exts && !X509V3_EXT_REQ_add_nconf(req_conf,
8426f9291ceSJung-uk Kim                                                       &ext_ctx, req_exts,
8436f9291ceSJung-uk Kim                                                       req)) {
8446f9291ceSJung-uk Kim                 BIO_printf(bio_err, "Error Loading extension section %s\n",
845f579bf8eSKris Kennaway                            req_exts);
846f579bf8eSKris Kennaway                 goto end;
847f579bf8eSKris Kennaway             }
8481f13597dSJung-uk Kim             i = do_X509_REQ_sign(bio_err, req, pkey, digest, sigopts);
8496f9291ceSJung-uk Kim             if (!i) {
8501f13597dSJung-uk Kim                 ERR_print_errors(bio_err);
85174664626SKris Kennaway                 goto end;
85274664626SKris Kennaway             }
85374664626SKris Kennaway         }
8541f13597dSJung-uk Kim     }
85574664626SKris Kennaway 
8566f9291ceSJung-uk Kim     if (subj && x509) {
8575c87c606SMark Murray         BIO_printf(bio_err, "Cannot modifiy certificate subject\n");
8585c87c606SMark Murray         goto end;
8595c87c606SMark Murray     }
8605c87c606SMark Murray 
8616f9291ceSJung-uk Kim     if (subj && !x509) {
8626f9291ceSJung-uk Kim         if (verbose) {
8635c87c606SMark Murray             BIO_printf(bio_err, "Modifying Request's Subject\n");
8646f9291ceSJung-uk Kim             print_name(bio_err, "old subject=",
8656f9291ceSJung-uk Kim                        X509_REQ_get_subject_name(req), nmflag);
8665c87c606SMark Murray         }
8675c87c606SMark Murray 
8686f9291ceSJung-uk Kim         if (build_subject(req, subj, chtype, multirdn) == 0) {
8695c87c606SMark Murray             BIO_printf(bio_err, "ERROR: cannot modify subject\n");
8705c87c606SMark Murray             ex = 1;
8715c87c606SMark Murray             goto end;
8725c87c606SMark Murray         }
8735c87c606SMark Murray 
8745c87c606SMark Murray         req->req_info->enc.modified = 1;
8755c87c606SMark Murray 
8766f9291ceSJung-uk Kim         if (verbose) {
8776f9291ceSJung-uk Kim             print_name(bio_err, "new subject=",
8786f9291ceSJung-uk Kim                        X509_REQ_get_subject_name(req), nmflag);
8795c87c606SMark Murray         }
8805c87c606SMark Murray     }
8815c87c606SMark Murray 
8826f9291ceSJung-uk Kim     if (verify && !x509) {
88374664626SKris Kennaway         int tmp = 0;
88474664626SKris Kennaway 
8856f9291ceSJung-uk Kim         if (pkey == NULL) {
88674664626SKris Kennaway             pkey = X509_REQ_get_pubkey(req);
88774664626SKris Kennaway             tmp = 1;
8886f9291ceSJung-uk Kim             if (pkey == NULL)
8896f9291ceSJung-uk Kim                 goto end;
89074664626SKris Kennaway         }
89174664626SKris Kennaway 
89274664626SKris Kennaway         i = X509_REQ_verify(req, pkey);
89374664626SKris Kennaway         if (tmp) {
89474664626SKris Kennaway             EVP_PKEY_free(pkey);
89574664626SKris Kennaway             pkey = NULL;
89674664626SKris Kennaway         }
89774664626SKris Kennaway 
8986f9291ceSJung-uk Kim         if (i < 0) {
89974664626SKris Kennaway             goto end;
9006f9291ceSJung-uk Kim         } else if (i == 0) {
90174664626SKris Kennaway             BIO_printf(bio_err, "verify failure\n");
9025c87c606SMark Murray             ERR_print_errors(bio_err);
9036f9291ceSJung-uk Kim         } else                  /* if (i > 0) */
90474664626SKris Kennaway             BIO_printf(bio_err, "verify OK\n");
90574664626SKris Kennaway     }
90674664626SKris Kennaway 
9076f9291ceSJung-uk Kim     if (noout && !text && !modulus && !subject && !pubkey) {
90874664626SKris Kennaway         ex = 0;
90974664626SKris Kennaway         goto end;
91074664626SKris Kennaway     }
91174664626SKris Kennaway 
9126f9291ceSJung-uk Kim     if (outfile == NULL) {
91374664626SKris Kennaway         BIO_set_fp(out, stdout, BIO_NOCLOSE);
9145c87c606SMark Murray #ifdef OPENSSL_SYS_VMS
915ddd58736SKris Kennaway         {
916ddd58736SKris Kennaway             BIO *tmpbio = BIO_new(BIO_f_linebuffer());
917ddd58736SKris Kennaway             out = BIO_push(tmpbio, out);
918ddd58736SKris Kennaway         }
919ddd58736SKris Kennaway #endif
9206f9291ceSJung-uk Kim     } else {
92174664626SKris Kennaway         if ((keyout != NULL) && (strcmp(outfile, keyout) == 0))
92274664626SKris Kennaway             i = (int)BIO_append_filename(out, outfile);
92374664626SKris Kennaway         else
92474664626SKris Kennaway             i = (int)BIO_write_filename(out, outfile);
9256f9291ceSJung-uk Kim         if (!i) {
92674664626SKris Kennaway             perror(outfile);
92774664626SKris Kennaway             goto end;
92874664626SKris Kennaway         }
92974664626SKris Kennaway     }
93074664626SKris Kennaway 
9316f9291ceSJung-uk Kim     if (pubkey) {
9325c87c606SMark Murray         EVP_PKEY *tpubkey;
9335c87c606SMark Murray         tpubkey = X509_REQ_get_pubkey(req);
9346f9291ceSJung-uk Kim         if (tpubkey == NULL) {
9355c87c606SMark Murray             BIO_printf(bio_err, "Error getting public key\n");
9365c87c606SMark Murray             ERR_print_errors(bio_err);
9375c87c606SMark Murray             goto end;
9385c87c606SMark Murray         }
9395c87c606SMark Murray         PEM_write_bio_PUBKEY(out, tpubkey);
9405c87c606SMark Murray         EVP_PKEY_free(tpubkey);
9415c87c606SMark Murray     }
9425c87c606SMark Murray 
9436f9291ceSJung-uk Kim     if (text) {
94474664626SKris Kennaway         if (x509)
9455c87c606SMark Murray             X509_print_ex(out, x509ss, nmflag, reqflag);
94674664626SKris Kennaway         else
9475c87c606SMark Murray             X509_REQ_print_ex(out, req, nmflag, reqflag);
9485c87c606SMark Murray     }
9495c87c606SMark Murray 
9506f9291ceSJung-uk Kim     if (subject) {
9515c87c606SMark Murray         if (x509)
9526f9291ceSJung-uk Kim             print_name(out, "subject=", X509_get_subject_name(x509ss),
9536f9291ceSJung-uk Kim                        nmflag);
9545c87c606SMark Murray         else
9556f9291ceSJung-uk Kim             print_name(out, "subject=", X509_REQ_get_subject_name(req),
9566f9291ceSJung-uk Kim                        nmflag);
95774664626SKris Kennaway     }
95874664626SKris Kennaway 
9596f9291ceSJung-uk Kim     if (modulus) {
9605c87c606SMark Murray         EVP_PKEY *tpubkey;
96174664626SKris Kennaway 
96274664626SKris Kennaway         if (x509)
9635c87c606SMark Murray             tpubkey = X509_get_pubkey(x509ss);
96474664626SKris Kennaway         else
9655c87c606SMark Murray             tpubkey = X509_REQ_get_pubkey(req);
9666f9291ceSJung-uk Kim         if (tpubkey == NULL) {
96774664626SKris Kennaway             fprintf(stdout, "Modulus=unavailable\n");
96874664626SKris Kennaway             goto end;
96974664626SKris Kennaway         }
97074664626SKris Kennaway         fprintf(stdout, "Modulus=");
9715c87c606SMark Murray #ifndef OPENSSL_NO_RSA
9721f13597dSJung-uk Kim         if (EVP_PKEY_base_id(tpubkey) == EVP_PKEY_RSA)
9735c87c606SMark Murray             BN_print(out, tpubkey->pkey.rsa->n);
97474664626SKris Kennaway         else
97574664626SKris Kennaway #endif
97674664626SKris Kennaway             fprintf(stdout, "Wrong Algorithm type");
9775c87c606SMark Murray         EVP_PKEY_free(tpubkey);
97874664626SKris Kennaway         fprintf(stdout, "\n");
97974664626SKris Kennaway     }
98074664626SKris Kennaway 
9816f9291ceSJung-uk Kim     if (!noout && !x509) {
98274664626SKris Kennaway         if (outformat == FORMAT_ASN1)
98374664626SKris Kennaway             i = i2d_X509_REQ_bio(out, req);
984f579bf8eSKris Kennaway         else if (outformat == FORMAT_PEM) {
9856f9291ceSJung-uk Kim             if (newhdr)
9866f9291ceSJung-uk Kim                 i = PEM_write_bio_X509_REQ_NEW(out, req);
9876f9291ceSJung-uk Kim             else
9886f9291ceSJung-uk Kim                 i = PEM_write_bio_X509_REQ(out, req);
989f579bf8eSKris Kennaway         } else {
99074664626SKris Kennaway             BIO_printf(bio_err, "bad output format specified for outfile\n");
99174664626SKris Kennaway             goto end;
99274664626SKris Kennaway         }
9936f9291ceSJung-uk Kim         if (!i) {
99474664626SKris Kennaway             BIO_printf(bio_err, "unable to write X509 request\n");
99574664626SKris Kennaway             goto end;
99674664626SKris Kennaway         }
99774664626SKris Kennaway     }
9986f9291ceSJung-uk Kim     if (!noout && x509 && (x509ss != NULL)) {
99974664626SKris Kennaway         if (outformat == FORMAT_ASN1)
100074664626SKris Kennaway             i = i2d_X509_bio(out, x509ss);
100174664626SKris Kennaway         else if (outformat == FORMAT_PEM)
100274664626SKris Kennaway             i = PEM_write_bio_X509(out, x509ss);
100374664626SKris Kennaway         else {
100474664626SKris Kennaway             BIO_printf(bio_err, "bad output format specified for outfile\n");
100574664626SKris Kennaway             goto end;
100674664626SKris Kennaway         }
10076f9291ceSJung-uk Kim         if (!i) {
100874664626SKris Kennaway             BIO_printf(bio_err, "unable to write X509 certificate\n");
100974664626SKris Kennaway             goto end;
101074664626SKris Kennaway         }
101174664626SKris Kennaway     }
101274664626SKris Kennaway     ex = 0;
101374664626SKris Kennaway  end:
10145c87c606SMark Murray #ifndef MONOLITH
10155c87c606SMark Murray     if (to_free)
10165c87c606SMark Murray         OPENSSL_free(to_free);
10175c87c606SMark Murray #endif
10186f9291ceSJung-uk Kim     if (ex) {
101974664626SKris Kennaway         ERR_print_errors(bio_err);
102074664626SKris Kennaway     }
10216f9291ceSJung-uk Kim     if ((req_conf != NULL) && (req_conf != config))
10226f9291ceSJung-uk Kim         NCONF_free(req_conf);
102374664626SKris Kennaway     BIO_free(in);
1024ddd58736SKris Kennaway     BIO_free_all(out);
102574664626SKris Kennaway     EVP_PKEY_free(pkey);
10261f13597dSJung-uk Kim     if (genctx)
10271f13597dSJung-uk Kim         EVP_PKEY_CTX_free(genctx);
10281f13597dSJung-uk Kim     if (pkeyopts)
10291f13597dSJung-uk Kim         sk_OPENSSL_STRING_free(pkeyopts);
10301f13597dSJung-uk Kim     if (sigopts)
10311f13597dSJung-uk Kim         sk_OPENSSL_STRING_free(sigopts);
10321f13597dSJung-uk Kim #ifndef OPENSSL_NO_ENGINE
10331f13597dSJung-uk Kim     if (gen_eng)
10341f13597dSJung-uk Kim         ENGINE_free(gen_eng);
10351f13597dSJung-uk Kim #endif
10361f13597dSJung-uk Kim     if (keyalgstr)
10371f13597dSJung-uk Kim         OPENSSL_free(keyalgstr);
103874664626SKris Kennaway     X509_REQ_free(req);
103974664626SKris Kennaway     X509_free(x509ss);
10405c87c606SMark Murray     ASN1_INTEGER_free(serial);
10416cf8931aSJung-uk Kim     release_engine(e);
10426f9291ceSJung-uk Kim     if (passargin && passin)
10436f9291ceSJung-uk Kim         OPENSSL_free(passin);
10446f9291ceSJung-uk Kim     if (passargout && passout)
10456f9291ceSJung-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();
10626f9291ceSJung-uk Kim     if ((tmp != NULL) && !strcmp(tmp, "no"))
10636f9291ceSJung-uk Kim         no_prompt = 1;
1064f579bf8eSKris Kennaway 
10655c87c606SMark Murray     dn_sect = NCONF_get_string(req_conf, SECTION, DISTINGUISHED_NAME);
10666f9291ceSJung-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);
10726f9291ceSJung-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);
10786f9291ceSJung-uk Kim     if (attr_sect == NULL) {
10795c87c606SMark Murray         ERR_clear_error();
1080f579bf8eSKris Kennaway         attr_sk = NULL;
10816f9291ceSJung-uk Kim     } else {
10825c87c606SMark Murray         attr_sk = NCONF_get_section(req_conf, attr_sect);
10836f9291ceSJung-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 */
10906f9291ceSJung-uk Kim     if (!X509_REQ_set_version(req, 0L))
10916f9291ceSJung-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);
10956f9291ceSJung-uk Kim     else {
10965c87c606SMark Murray         if (subj)
10973b4e3dcbSSimon L. B. Nielsen             i = build_subject(req, subj, chtype, multirdn);
10985c87c606SMark Murray         else
10996f9291ceSJung-uk Kim             i = prompt_info(req, dn_sk, dn_sect, attr_sk, attr_sect, attribs,
11006f9291ceSJung-uk Kim                             chtype);
11015c87c606SMark Murray     }
11026f9291ceSJung-uk Kim     if (!i)
11036f9291ceSJung-uk Kim         goto err;
1104f579bf8eSKris Kennaway 
11056f9291ceSJung-uk Kim     if (!X509_REQ_set_pubkey(req, pkey))
11066f9291ceSJung-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  */
11176f9291ceSJung-uk Kim static int build_subject(X509_REQ *req, char *subject, unsigned long chtype,
11186f9291ceSJung-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 
11256f9291ceSJung-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,
11356f9291ceSJung-uk Kim                        STACK_OF(CONF_VALUE) *attr_sk, char *attr_sect,
11366f9291ceSJung-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 
11496f9291ceSJung-uk Kim     if (!batch) {
11506f9291ceSJung-uk Kim         BIO_printf(bio_err,
11516f9291ceSJung-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");
11536f9291ceSJung-uk Kim         BIO_printf(bio_err,
11546f9291ceSJung-uk Kim                    "What you are about to enter is what is called a Distinguished Name or a DN.\n");
11556f9291ceSJung-uk Kim         BIO_printf(bio_err,
11566f9291ceSJung-uk Kim                    "There are quite a few fields but you can leave some blank\n");
11576f9291ceSJung-uk Kim         BIO_printf(bio_err,
11586f9291ceSJung-uk Kim                    "For some fields there will be a default value,\n");
11596f9291ceSJung-uk Kim         BIO_printf(bio_err,
11606f9291ceSJung-uk Kim                    "If you enter '.', the field will be left blank.\n");
116174664626SKris Kennaway         BIO_printf(bio_err, "-----\n");
11625c87c606SMark Murray     }
116374664626SKris Kennaway 
11646f9291ceSJung-uk Kim     if (sk_CONF_VALUE_num(dn_sk)) {
116574664626SKris Kennaway         i = -1;
11666f9291ceSJung-uk Kim  start:for (;;) {
116774664626SKris Kennaway             i++;
11686f9291ceSJung-uk Kim             if (sk_CONF_VALUE_num(dn_sk) <= i)
11696f9291ceSJung-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") ||
11756f9291ceSJung-uk Kim                 !check_end(type, "_default") || !check_end(type, "_value"))
11766f9291ceSJung-uk Kim                 continue;
11776f9291ceSJung-uk Kim             /*
11786f9291ceSJung-uk Kim              * Skip past any leading X. X: X, etc to allow for multiple
11796f9291ceSJung-uk Kim              * instances
118074664626SKris Kennaway              */
118174664626SKris Kennaway             for (p = v->name; *p; p++)
11826f9291ceSJung-uk Kim                 if ((*p == ':') || (*p == ',') || (*p == '.')) {
118374664626SKris Kennaway                     p++;
11846f9291ceSJung-uk Kim                     if (*p)
11856f9291ceSJung-uk Kim                         type = p;
118674664626SKris Kennaway                     break;
118774664626SKris Kennaway                 }
11886f9291ceSJung-uk Kim             if (*type == '+') {
11893b4e3dcbSSimon L. B. Nielsen                 mval = -1;
11903b4e3dcbSSimon L. B. Nielsen                 type++;
11916f9291ceSJung-uk Kim             } else
11923b4e3dcbSSimon L. B. Nielsen                 mval = 0;
119374664626SKris Kennaway             /* If OBJ not recognised ignore it */
11946f9291ceSJung-uk Kim             if ((nid = OBJ_txt2nid(type)) == NID_undef)
11956f9291ceSJung-uk Kim                 goto start;
1196ced566fdSJacques Vidrine             if (BIO_snprintf(buf, sizeof buf, "%s_default", v->name)
11976f9291ceSJung-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 
12026f9291ceSJung-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);
12086f9291ceSJung-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);
12146f9291ceSJung-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);
12206f9291ceSJung-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         }
12296f9291ceSJung-uk Kim         if (X509_NAME_entry_count(subj) == 0) {
12306f9291ceSJung-uk Kim             BIO_printf(bio_err,
12316f9291ceSJung-uk Kim                        "error, no objects specified in config file\n");
1232f579bf8eSKris Kennaway             return 0;
123374664626SKris Kennaway         }
123474664626SKris Kennaway 
12356f9291ceSJung-uk Kim         if (attribs) {
12366f9291ceSJung-uk Kim             if ((attr_sk != NULL) && (sk_CONF_VALUE_num(attr_sk) > 0)
12376f9291ceSJung-uk Kim                 && (!batch)) {
12386f9291ceSJung-uk Kim                 BIO_printf(bio_err,
12396f9291ceSJung-uk Kim                            "\nPlease enter the following 'extra' attributes\n");
12406f9291ceSJung-uk Kim                 BIO_printf(bio_err,
12416f9291ceSJung-uk Kim                            "to be sent with your certificate request\n");
124274664626SKris Kennaway             }
124374664626SKris Kennaway 
124474664626SKris Kennaway             i = -1;
12456f9291ceSJung-uk Kim  start2:   for (;;) {
124674664626SKris Kennaway                 i++;
12476f9291ceSJung-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)
12566f9291ceSJung-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))
12626f9291ceSJung-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))
12696f9291ceSJung-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);
12756f9291ceSJung-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);
12816f9291ceSJung-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,
12876f9291ceSJung-uk Kim                                           v->value, def, value, nid, n_min,
12886f9291ceSJung-uk Kim                                           n_max, chtype))
1289f579bf8eSKris Kennaway                     return 0;
129074664626SKris Kennaway             }
129174664626SKris Kennaway         }
12926f9291ceSJung-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,
13026f9291ceSJung-uk Kim                      STACK_OF(CONF_VALUE) *attr_sk, int attribs,
13036f9291ceSJung-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 
13136f9291ceSJung-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;
13186f9291ceSJung-uk Kim         /*
13196f9291ceSJung-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
13256f9291ceSJung-uk Kim             if ((*p == os_toascii[':']) || (*p == os_toascii[','])
13266f9291ceSJung-uk Kim                 || (*p == os_toascii['.'])) {
1327ddd58736SKris Kennaway #endif
1328f579bf8eSKris Kennaway                 p++;
13296f9291ceSJung-uk Kim                 if (*p)
13306f9291ceSJung-uk Kim                     type = p;
1331f579bf8eSKris Kennaway                 break;
1332f579bf8eSKris Kennaway             }
13333b4e3dcbSSimon L. B. Nielsen #ifndef CHARSET_EBCDIC
1334aeb5019cSJung-uk Kim         if (*type == '+') {
13353b4e3dcbSSimon L. B. Nielsen #else
1336aeb5019cSJung-uk Kim         if (*type == os_toascii['+']) {
13373b4e3dcbSSimon L. B. Nielsen #endif
1338aeb5019cSJung-uk Kim             type++;
13393b4e3dcbSSimon L. B. Nielsen             mval = -1;
13406f9291ceSJung-uk Kim         } else
13413b4e3dcbSSimon L. B. Nielsen             mval = 0;
13425c87c606SMark Murray         if (!X509_NAME_add_entry_by_txt(subj, type, chtype,
13436f9291ceSJung-uk Kim                                         (unsigned char *)v->value, -1, -1,
13446f9291ceSJung-uk Kim                                         mval))
13456f9291ceSJung-uk Kim             return 0;
1346f579bf8eSKris Kennaway 
1347f579bf8eSKris Kennaway     }
1348f579bf8eSKris Kennaway 
13496f9291ceSJung-uk Kim     if (!X509_NAME_entry_count(subj)) {
1350f579bf8eSKris Kennaway         BIO_printf(bio_err, "error, no objects specified in config file\n");
1351f579bf8eSKris Kennaway         return 0;
1352f579bf8eSKris Kennaway     }
13536f9291ceSJung-uk Kim     if (attribs) {
13546f9291ceSJung-uk Kim         for (i = 0; i < sk_CONF_VALUE_num(attr_sk); i++) {
1355f579bf8eSKris Kennaway             v = sk_CONF_VALUE_value(attr_sk, i);
13565c87c606SMark Murray             if (!X509_REQ_add1_attr_by_txt(req, v->name, chtype,
13576f9291ceSJung-uk Kim                                            (unsigned char *)v->value, -1))
13586f9291ceSJung-uk Kim                 return 0;
1359f579bf8eSKris Kennaway         }
1360f579bf8eSKris Kennaway     }
1361f579bf8eSKris Kennaway     return 1;
1362f579bf8eSKris Kennaway }
1363f579bf8eSKris Kennaway 
13646f9291ceSJung-uk Kim static int add_DN_object(X509_NAME *n, char *text, const char *def,
13656f9291ceSJung-uk Kim                          char *value, int nid, int n_min, int n_max,
13666f9291ceSJung-uk Kim                          unsigned long chtype, int mval)
136774664626SKris Kennaway {
1368f579bf8eSKris Kennaway     int i, ret = 0;
136974664626SKris Kennaway     MS_STATIC char buf[1024];
137074664626SKris Kennaway  start:
13716f9291ceSJung-uk Kim     if (!batch)
13726f9291ceSJung-uk Kim         BIO_printf(bio_err, "%s [%s]:", text, def);
137374664626SKris Kennaway     (void)BIO_flush(bio_err);
13746f9291ceSJung-uk Kim     if (value != NULL) {
1375ced566fdSJacques Vidrine         BUF_strlcpy(buf, value, sizeof buf);
1376ced566fdSJacques Vidrine         BUF_strlcat(buf, "\n", sizeof buf);
137774664626SKris Kennaway         BIO_printf(bio_err, "%s\n", value);
13786f9291ceSJung-uk Kim     } else {
137974664626SKris Kennaway         buf[0] = '\0';
13806f9291ceSJung-uk Kim         if (!batch) {
13816a599222SSimon L. B. Nielsen             if (!fgets(buf, sizeof buf, stdin))
13826a599222SSimon L. B. Nielsen                 return 0;
13836f9291ceSJung-uk Kim         } else {
13845c87c606SMark Murray             buf[0] = '\n';
13855c87c606SMark Murray             buf[1] = '\0';
13865c87c606SMark Murray         }
138774664626SKris Kennaway     }
138874664626SKris Kennaway 
13896f9291ceSJung-uk Kim     if (buf[0] == '\0')
13906f9291ceSJung-uk Kim         return (0);
13916f9291ceSJung-uk Kim     else if (buf[0] == '\n') {
139274664626SKris Kennaway         if ((def == NULL) || (def[0] == '\0'))
139374664626SKris Kennaway             return (1);
1394ced566fdSJacques Vidrine         BUF_strlcpy(buf, def, sizeof buf);
1395ced566fdSJacques Vidrine         BUF_strlcat(buf, "\n", sizeof buf);
13966f9291ceSJung-uk Kim     } else if ((buf[0] == '.') && (buf[1] == '\n'))
13976f9291ceSJung-uk Kim         return (1);
139874664626SKris Kennaway 
139974664626SKris Kennaway     i = strlen(buf);
14006f9291ceSJung-uk Kim     if (buf[i - 1] != '\n') {
140174664626SKris Kennaway         BIO_printf(bio_err, "weird input :-(\n");
140274664626SKris Kennaway         return (0);
140374664626SKris Kennaway     }
140474664626SKris Kennaway     buf[--i] = '\0';
1405f579bf8eSKris Kennaway #ifdef CHARSET_EBCDIC
1406f579bf8eSKris Kennaway     ebcdic2ascii(buf, buf, i);
1407f579bf8eSKris Kennaway #endif
14086f9291ceSJung-uk Kim     if (!req_check_len(i, n_min, n_max)) {
140994ad176cSJung-uk Kim         if (batch || value)
141094ad176cSJung-uk Kim             return 0;
141194ad176cSJung-uk Kim         goto start;
141294ad176cSJung-uk Kim     }
141394ad176cSJung-uk Kim 
14145c87c606SMark Murray     if (!X509_NAME_add_entry_by_NID(n, nid, chtype,
14156f9291ceSJung-uk Kim                                     (unsigned char *)buf, -1, -1, mval))
14166f9291ceSJung-uk Kim         goto err;
1417f579bf8eSKris Kennaway     ret = 1;
1418f579bf8eSKris Kennaway  err:
1419f579bf8eSKris Kennaway     return (ret);
142074664626SKris Kennaway }
142174664626SKris Kennaway 
14223b4e3dcbSSimon L. B. Nielsen static int add_attribute_object(X509_REQ *req, char *text, const char *def,
14233b4e3dcbSSimon L. B. Nielsen                                 char *value, int nid, int n_min,
14245c87c606SMark Murray                                 int n_max, unsigned long chtype)
1425f579bf8eSKris Kennaway {
1426f579bf8eSKris Kennaway     int i;
1427f579bf8eSKris Kennaway     static char buf[1024];
142874664626SKris Kennaway 
1429f579bf8eSKris Kennaway  start:
14306f9291ceSJung-uk Kim     if (!batch)
14316f9291ceSJung-uk Kim         BIO_printf(bio_err, "%s [%s]:", text, def);
1432f579bf8eSKris Kennaway     (void)BIO_flush(bio_err);
14336f9291ceSJung-uk Kim     if (value != NULL) {
1434ced566fdSJacques Vidrine         BUF_strlcpy(buf, value, sizeof buf);
1435ced566fdSJacques Vidrine         BUF_strlcat(buf, "\n", sizeof buf);
1436f579bf8eSKris Kennaway         BIO_printf(bio_err, "%s\n", value);
14376f9291ceSJung-uk Kim     } else {
1438f579bf8eSKris Kennaway         buf[0] = '\0';
14396f9291ceSJung-uk Kim         if (!batch) {
14406a599222SSimon L. B. Nielsen             if (!fgets(buf, sizeof buf, stdin))
14416a599222SSimon L. B. Nielsen                 return 0;
14426f9291ceSJung-uk Kim         } else {
14435c87c606SMark Murray             buf[0] = '\n';
14445c87c606SMark Murray             buf[1] = '\0';
14455c87c606SMark Murray         }
1446f579bf8eSKris Kennaway     }
144774664626SKris Kennaway 
14486f9291ceSJung-uk Kim     if (buf[0] == '\0')
14496f9291ceSJung-uk Kim         return (0);
14506f9291ceSJung-uk Kim     else if (buf[0] == '\n') {
1451f579bf8eSKris Kennaway         if ((def == NULL) || (def[0] == '\0'))
1452f579bf8eSKris Kennaway             return (1);
1453ced566fdSJacques Vidrine         BUF_strlcpy(buf, def, sizeof buf);
1454ced566fdSJacques Vidrine         BUF_strlcat(buf, "\n", sizeof buf);
14556f9291ceSJung-uk Kim     } else if ((buf[0] == '.') && (buf[1] == '\n'))
14566f9291ceSJung-uk Kim         return (1);
145774664626SKris Kennaway 
1458f579bf8eSKris Kennaway     i = strlen(buf);
14596f9291ceSJung-uk Kim     if (buf[i - 1] != '\n') {
1460f579bf8eSKris Kennaway         BIO_printf(bio_err, "weird input :-(\n");
1461f579bf8eSKris Kennaway         return (0);
1462f579bf8eSKris Kennaway     }
1463f579bf8eSKris Kennaway     buf[--i] = '\0';
1464ddd58736SKris Kennaway #ifdef CHARSET_EBCDIC
1465ddd58736SKris Kennaway     ebcdic2ascii(buf, buf, i);
1466ddd58736SKris Kennaway #endif
14676f9291ceSJung-uk Kim     if (!req_check_len(i, n_min, n_max)) {
146894ad176cSJung-uk Kim         if (batch || value)
146994ad176cSJung-uk Kim             return 0;
147094ad176cSJung-uk Kim         goto start;
147194ad176cSJung-uk Kim     }
1472f579bf8eSKris Kennaway 
14735c87c606SMark Murray     if (!X509_REQ_add1_attr_by_NID(req, nid, chtype,
1474f579bf8eSKris Kennaway                                    (unsigned char *)buf, -1)) {
1475f579bf8eSKris Kennaway         BIO_printf(bio_err, "Error adding attribute\n");
1476f579bf8eSKris Kennaway         ERR_print_errors(bio_err);
1477f579bf8eSKris Kennaway         goto err;
1478f579bf8eSKris Kennaway     }
1479f579bf8eSKris Kennaway 
148074664626SKris Kennaway     return (1);
148174664626SKris Kennaway  err:
148274664626SKris Kennaway     return (0);
148374664626SKris Kennaway }
148474664626SKris Kennaway 
14855c87c606SMark Murray static int req_check_len(int len, int n_min, int n_max)
148674664626SKris Kennaway {
14876f9291ceSJung-uk Kim     if ((n_min > 0) && (len < n_min)) {
14886f9291ceSJung-uk Kim         BIO_printf(bio_err,
14896f9291ceSJung-uk Kim                    "string is too short, it needs to be at least %d bytes long\n",
14906f9291ceSJung-uk Kim                    n_min);
149174664626SKris Kennaway         return (0);
149274664626SKris Kennaway     }
14936f9291ceSJung-uk Kim     if ((n_max >= 0) && (len > n_max)) {
14946f9291ceSJung-uk Kim         BIO_printf(bio_err,
14956f9291ceSJung-uk Kim                    "string is too long, it needs to be less than  %d bytes long\n",
14966f9291ceSJung-uk Kim                    n_max);
149774664626SKris Kennaway         return (0);
149874664626SKris Kennaway     }
149974664626SKris Kennaway     return (1);
150074664626SKris Kennaway }
150174664626SKris Kennaway 
150274664626SKris Kennaway /* Check if the end of a string matches 'end' */
15033b4e3dcbSSimon L. B. Nielsen static int check_end(const char *str, const char *end)
150474664626SKris Kennaway {
150574664626SKris Kennaway     int elen, slen;
15063b4e3dcbSSimon L. B. Nielsen     const char *tmp;
150774664626SKris Kennaway     elen = strlen(end);
150874664626SKris Kennaway     slen = strlen(str);
15096f9291ceSJung-uk Kim     if (elen > slen)
15106f9291ceSJung-uk Kim         return 1;
151174664626SKris Kennaway     tmp = str + slen - elen;
151274664626SKris Kennaway     return strcmp(tmp, end);
151374664626SKris Kennaway }
15141f13597dSJung-uk Kim 
15156f9291ceSJung-uk Kim static EVP_PKEY_CTX *set_keygen_ctx(BIO *err, const char *gstr,
15166f9291ceSJung-uk Kim                                     int *pkey_type, long *pkeylen,
15176f9291ceSJung-uk Kim                                     char **palgnam, ENGINE *keygen_engine)
15181f13597dSJung-uk Kim {
15191f13597dSJung-uk Kim     EVP_PKEY_CTX *gctx = NULL;
15201f13597dSJung-uk Kim     EVP_PKEY *param = NULL;
15211f13597dSJung-uk Kim     long keylen = -1;
15221f13597dSJung-uk Kim     BIO *pbio = NULL;
15231f13597dSJung-uk Kim     const char *paramfile = NULL;
15241f13597dSJung-uk Kim 
15256f9291ceSJung-uk Kim     if (gstr == NULL) {
15261f13597dSJung-uk Kim         *pkey_type = EVP_PKEY_RSA;
15271f13597dSJung-uk Kim         keylen = *pkeylen;
15286f9291ceSJung-uk Kim     } else if (gstr[0] >= '0' && gstr[0] <= '9') {
15291f13597dSJung-uk Kim         *pkey_type = EVP_PKEY_RSA;
15301f13597dSJung-uk Kim         keylen = atol(gstr);
15311f13597dSJung-uk Kim         *pkeylen = keylen;
15326f9291ceSJung-uk Kim     } else if (!strncmp(gstr, "param:", 6))
15331f13597dSJung-uk Kim         paramfile = gstr + 6;
15346f9291ceSJung-uk Kim     else {
15351f13597dSJung-uk Kim         const char *p = strchr(gstr, ':');
15361f13597dSJung-uk Kim         int len;
15371f13597dSJung-uk Kim         ENGINE *tmpeng;
15381f13597dSJung-uk Kim         const EVP_PKEY_ASN1_METHOD *ameth;
15391f13597dSJung-uk Kim 
15401f13597dSJung-uk Kim         if (p)
15411f13597dSJung-uk Kim             len = p - gstr;
15421f13597dSJung-uk Kim         else
15431f13597dSJung-uk Kim             len = strlen(gstr);
15446f9291ceSJung-uk Kim         /*
15456f9291ceSJung-uk Kim          * The lookup of a the string will cover all engines so keep a note
15466f9291ceSJung-uk Kim          * of the implementation.
15471f13597dSJung-uk Kim          */
15481f13597dSJung-uk Kim 
15491f13597dSJung-uk Kim         ameth = EVP_PKEY_asn1_find_str(&tmpeng, gstr, len);
15501f13597dSJung-uk Kim 
15516f9291ceSJung-uk Kim         if (!ameth) {
15521f13597dSJung-uk Kim             BIO_printf(err, "Unknown algorithm %.*s\n", len, gstr);
15531f13597dSJung-uk Kim             return NULL;
15541f13597dSJung-uk Kim         }
15551f13597dSJung-uk Kim 
15566f9291ceSJung-uk Kim         EVP_PKEY_asn1_get0_info(NULL, pkey_type, NULL, NULL, NULL, ameth);
15571f13597dSJung-uk Kim #ifndef OPENSSL_NO_ENGINE
15581f13597dSJung-uk Kim         if (tmpeng)
15591f13597dSJung-uk Kim             ENGINE_finish(tmpeng);
15601f13597dSJung-uk Kim #endif
15616f9291ceSJung-uk Kim         if (*pkey_type == EVP_PKEY_RSA) {
15626f9291ceSJung-uk Kim             if (p) {
15631f13597dSJung-uk Kim                 keylen = atol(p + 1);
15641f13597dSJung-uk Kim                 *pkeylen = keylen;
15656f9291ceSJung-uk Kim             } else
1566560ede85SJung-uk Kim                 keylen = *pkeylen;
15676f9291ceSJung-uk Kim         } else if (p)
15681f13597dSJung-uk Kim             paramfile = p + 1;
15691f13597dSJung-uk Kim     }
15701f13597dSJung-uk Kim 
15716f9291ceSJung-uk Kim     if (paramfile) {
15721f13597dSJung-uk Kim         pbio = BIO_new_file(paramfile, "r");
15736f9291ceSJung-uk Kim         if (!pbio) {
15746f9291ceSJung-uk Kim             BIO_printf(err, "Can't open parameter file %s\n", paramfile);
15751f13597dSJung-uk Kim             return NULL;
15761f13597dSJung-uk Kim         }
15771f13597dSJung-uk Kim         param = PEM_read_bio_Parameters(pbio, NULL);
15781f13597dSJung-uk Kim 
15796f9291ceSJung-uk Kim         if (!param) {
15801f13597dSJung-uk Kim             X509 *x;
15811f13597dSJung-uk Kim             (void)BIO_reset(pbio);
15821f13597dSJung-uk Kim             x = PEM_read_bio_X509(pbio, NULL, NULL, NULL);
15836f9291ceSJung-uk Kim             if (x) {
15841f13597dSJung-uk Kim                 param = X509_get_pubkey(x);
15851f13597dSJung-uk Kim                 X509_free(x);
15861f13597dSJung-uk Kim             }
15871f13597dSJung-uk Kim         }
15881f13597dSJung-uk Kim 
15891f13597dSJung-uk Kim         BIO_free(pbio);
15901f13597dSJung-uk Kim 
15916f9291ceSJung-uk Kim         if (!param) {
15926f9291ceSJung-uk Kim             BIO_printf(err, "Error reading parameter file %s\n", paramfile);
15931f13597dSJung-uk Kim             return NULL;
15941f13597dSJung-uk Kim         }
15951f13597dSJung-uk Kim         if (*pkey_type == -1)
15961f13597dSJung-uk Kim             *pkey_type = EVP_PKEY_id(param);
15976f9291ceSJung-uk Kim         else if (*pkey_type != EVP_PKEY_base_id(param)) {
15981f13597dSJung-uk Kim             BIO_printf(err, "Key Type does not match parameters\n");
15991f13597dSJung-uk Kim             EVP_PKEY_free(param);
16001f13597dSJung-uk Kim             return NULL;
16011f13597dSJung-uk Kim         }
16021f13597dSJung-uk Kim     }
16031f13597dSJung-uk Kim 
16046f9291ceSJung-uk Kim     if (palgnam) {
16051f13597dSJung-uk Kim         const EVP_PKEY_ASN1_METHOD *ameth;
16061f13597dSJung-uk Kim         ENGINE *tmpeng;
16071f13597dSJung-uk Kim         const char *anam;
16081f13597dSJung-uk Kim         ameth = EVP_PKEY_asn1_find(&tmpeng, *pkey_type);
16096f9291ceSJung-uk Kim         if (!ameth) {
16101f13597dSJung-uk Kim             BIO_puts(err, "Internal error: can't find key algorithm\n");
16111f13597dSJung-uk Kim             return NULL;
16121f13597dSJung-uk Kim         }
16131f13597dSJung-uk Kim         EVP_PKEY_asn1_get0_info(NULL, NULL, NULL, NULL, &anam, ameth);
16141f13597dSJung-uk Kim         *palgnam = BUF_strdup(anam);
16151f13597dSJung-uk Kim #ifndef OPENSSL_NO_ENGINE
16161f13597dSJung-uk Kim         if (tmpeng)
16171f13597dSJung-uk Kim             ENGINE_finish(tmpeng);
16181f13597dSJung-uk Kim #endif
16191f13597dSJung-uk Kim     }
16201f13597dSJung-uk Kim 
16216f9291ceSJung-uk Kim     if (param) {
16221f13597dSJung-uk Kim         gctx = EVP_PKEY_CTX_new(param, keygen_engine);
16231f13597dSJung-uk Kim         *pkeylen = EVP_PKEY_bits(param);
16241f13597dSJung-uk Kim         EVP_PKEY_free(param);
16256f9291ceSJung-uk Kim     } else
16261f13597dSJung-uk Kim         gctx = EVP_PKEY_CTX_new_id(*pkey_type, keygen_engine);
16271f13597dSJung-uk Kim 
16286f9291ceSJung-uk Kim     if (!gctx) {
16291f13597dSJung-uk Kim         BIO_puts(err, "Error allocating keygen context\n");
16301f13597dSJung-uk Kim         ERR_print_errors(err);
16311f13597dSJung-uk Kim         return NULL;
16321f13597dSJung-uk Kim     }
16331f13597dSJung-uk Kim 
16346f9291ceSJung-uk Kim     if (EVP_PKEY_keygen_init(gctx) <= 0) {
16351f13597dSJung-uk Kim         BIO_puts(err, "Error initializing keygen context\n");
16361f13597dSJung-uk Kim         ERR_print_errors(err);
16371f13597dSJung-uk Kim         return NULL;
16381f13597dSJung-uk Kim     }
16391f13597dSJung-uk Kim #ifndef OPENSSL_NO_RSA
16406f9291ceSJung-uk Kim     if ((*pkey_type == EVP_PKEY_RSA) && (keylen != -1)) {
16416f9291ceSJung-uk Kim         if (EVP_PKEY_CTX_set_rsa_keygen_bits(gctx, keylen) <= 0) {
16421f13597dSJung-uk Kim             BIO_puts(err, "Error setting RSA keysize\n");
16431f13597dSJung-uk Kim             ERR_print_errors(err);
16441f13597dSJung-uk Kim             EVP_PKEY_CTX_free(gctx);
16451f13597dSJung-uk Kim             return NULL;
16461f13597dSJung-uk Kim         }
16471f13597dSJung-uk Kim     }
16481f13597dSJung-uk Kim #endif
16491f13597dSJung-uk Kim 
16501f13597dSJung-uk Kim     return gctx;
16511f13597dSJung-uk Kim }
16521f13597dSJung-uk Kim 
16531f13597dSJung-uk Kim static int genpkey_cb(EVP_PKEY_CTX *ctx)
16541f13597dSJung-uk Kim {
16551f13597dSJung-uk Kim     char c = '*';
16561f13597dSJung-uk Kim     BIO *b = EVP_PKEY_CTX_get_app_data(ctx);
16571f13597dSJung-uk Kim     int p;
16581f13597dSJung-uk Kim     p = EVP_PKEY_CTX_get_keygen_info(ctx, 0);
16596f9291ceSJung-uk Kim     if (p == 0)
16606f9291ceSJung-uk Kim         c = '.';
16616f9291ceSJung-uk Kim     if (p == 1)
16626f9291ceSJung-uk Kim         c = '+';
16636f9291ceSJung-uk Kim     if (p == 2)
16646f9291ceSJung-uk Kim         c = '*';
16656f9291ceSJung-uk Kim     if (p == 3)
16666f9291ceSJung-uk Kim         c = '\n';
16671f13597dSJung-uk Kim     BIO_write(b, &c, 1);
16681f13597dSJung-uk Kim     (void)BIO_flush(b);
16691f13597dSJung-uk Kim #ifdef LINT
16701f13597dSJung-uk Kim     p = n;
16711f13597dSJung-uk Kim #endif
16721f13597dSJung-uk Kim     return 1;
16731f13597dSJung-uk Kim }
16741f13597dSJung-uk Kim 
16751f13597dSJung-uk Kim static int do_sign_init(BIO *err, EVP_MD_CTX *ctx, EVP_PKEY *pkey,
16761f13597dSJung-uk Kim                         const EVP_MD *md, STACK_OF(OPENSSL_STRING) *sigopts)
16771f13597dSJung-uk Kim {
16781f13597dSJung-uk Kim     EVP_PKEY_CTX *pkctx = NULL;
16791f13597dSJung-uk Kim     int i;
16801f13597dSJung-uk Kim     EVP_MD_CTX_init(ctx);
16811f13597dSJung-uk Kim     if (!EVP_DigestSignInit(ctx, &pkctx, md, NULL, pkey))
16821f13597dSJung-uk Kim         return 0;
16836f9291ceSJung-uk Kim     for (i = 0; i < sk_OPENSSL_STRING_num(sigopts); i++) {
16841f13597dSJung-uk Kim         char *sigopt = sk_OPENSSL_STRING_value(sigopts, i);
16856f9291ceSJung-uk Kim         if (pkey_ctrl_string(pkctx, sigopt) <= 0) {
16861f13597dSJung-uk Kim             BIO_printf(err, "parameter error \"%s\"\n", sigopt);
16871f13597dSJung-uk Kim             ERR_print_errors(bio_err);
16881f13597dSJung-uk Kim             return 0;
16891f13597dSJung-uk Kim         }
16901f13597dSJung-uk Kim     }
16911f13597dSJung-uk Kim     return 1;
16921f13597dSJung-uk Kim }
16931f13597dSJung-uk Kim 
16941f13597dSJung-uk Kim int do_X509_sign(BIO *err, X509 *x, EVP_PKEY *pkey, const EVP_MD *md,
16951f13597dSJung-uk Kim                  STACK_OF(OPENSSL_STRING) *sigopts)
16961f13597dSJung-uk Kim {
16971f13597dSJung-uk Kim     int rv;
16981f13597dSJung-uk Kim     EVP_MD_CTX mctx;
16991f13597dSJung-uk Kim     EVP_MD_CTX_init(&mctx);
17001f13597dSJung-uk Kim     rv = do_sign_init(err, &mctx, pkey, md, sigopts);
17011f13597dSJung-uk Kim     if (rv > 0)
17021f13597dSJung-uk Kim         rv = X509_sign_ctx(x, &mctx);
17031f13597dSJung-uk Kim     EVP_MD_CTX_cleanup(&mctx);
17041f13597dSJung-uk Kim     return rv > 0 ? 1 : 0;
17051f13597dSJung-uk Kim }
17061f13597dSJung-uk Kim 
17071f13597dSJung-uk Kim int do_X509_REQ_sign(BIO *err, X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md,
17081f13597dSJung-uk Kim                      STACK_OF(OPENSSL_STRING) *sigopts)
17091f13597dSJung-uk Kim {
17101f13597dSJung-uk Kim     int rv;
17111f13597dSJung-uk Kim     EVP_MD_CTX mctx;
17121f13597dSJung-uk Kim     EVP_MD_CTX_init(&mctx);
17131f13597dSJung-uk Kim     rv = do_sign_init(err, &mctx, pkey, md, sigopts);
17141f13597dSJung-uk Kim     if (rv > 0)
17151f13597dSJung-uk Kim         rv = X509_REQ_sign_ctx(x, &mctx);
17161f13597dSJung-uk Kim     EVP_MD_CTX_cleanup(&mctx);
17171f13597dSJung-uk Kim     return rv > 0 ? 1 : 0;
17181f13597dSJung-uk Kim }
17191f13597dSJung-uk Kim 
17201f13597dSJung-uk Kim int do_X509_CRL_sign(BIO *err, X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md,
17211f13597dSJung-uk Kim                      STACK_OF(OPENSSL_STRING) *sigopts)
17221f13597dSJung-uk Kim {
17231f13597dSJung-uk Kim     int rv;
17241f13597dSJung-uk Kim     EVP_MD_CTX mctx;
17251f13597dSJung-uk Kim     EVP_MD_CTX_init(&mctx);
17261f13597dSJung-uk Kim     rv = do_sign_init(err, &mctx, pkey, md, sigopts);
17271f13597dSJung-uk Kim     if (rv > 0)
17281f13597dSJung-uk Kim         rv = X509_CRL_sign_ctx(x, &mctx);
17291f13597dSJung-uk Kim     EVP_MD_CTX_cleanup(&mctx);
17301f13597dSJung-uk Kim     return rv > 0 ? 1 : 0;
17311f13597dSJung-uk Kim }
1732