xref: /freebsd/crypto/openssl/apps/req.c (revision 6cf8931a2f9fa26b2d9bdba6f1915f655e6bf25f)
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) {
334aeb5019cSJung-uk Kim             newreq = 1;
33574664626SKris Kennaway             x509 = 1;
336aeb5019cSJung-uk Kim         } else if (strcmp(*argv, "-asn1-kludge") == 0)
33774664626SKris Kennaway             kludge = 1;
33874664626SKris Kennaway         else if (strcmp(*argv, "-no-asn1-kludge") == 0)
33974664626SKris Kennaway             kludge = 0;
3406f9291ceSJung-uk Kim         else if (strcmp(*argv, "-subj") == 0) {
3416f9291ceSJung-uk Kim             if (--argc < 1)
3426f9291ceSJung-uk Kim                 goto bad;
3435c87c606SMark Murray             subj = *(++argv);
3446f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-multivalue-rdn") == 0)
3453b4e3dcbSSimon L. B. Nielsen             multirdn = 1;
3466f9291ceSJung-uk Kim         else if (strcmp(*argv, "-days") == 0) {
3476f9291ceSJung-uk Kim             if (--argc < 1)
3486f9291ceSJung-uk Kim                 goto bad;
34974664626SKris Kennaway             days = atoi(*(++argv));
3506f9291ceSJung-uk Kim             if (days == 0)
3516f9291ceSJung-uk Kim                 days = 30;
3526f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-set_serial") == 0) {
3536f9291ceSJung-uk Kim             if (--argc < 1)
3546f9291ceSJung-uk Kim                 goto bad;
3555c87c606SMark Murray             serial = s2i_ASN1_INTEGER(NULL, *(++argv));
3566f9291ceSJung-uk Kim             if (!serial)
3576f9291ceSJung-uk Kim                 goto bad;
3586f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-extensions") == 0) {
3596f9291ceSJung-uk Kim             if (--argc < 1)
3606f9291ceSJung-uk Kim                 goto bad;
361f579bf8eSKris Kennaway             extensions = *(++argv);
3626f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-reqexts") == 0) {
3636f9291ceSJung-uk Kim             if (--argc < 1)
3646f9291ceSJung-uk Kim                 goto bad;
365f579bf8eSKris Kennaway             req_exts = *(++argv);
3666f9291ceSJung-uk Kim         } else if ((md_alg = EVP_get_digestbyname(&((*argv)[1]))) != NULL) {
3671f13597dSJung-uk Kim             /* ok */
3681f13597dSJung-uk Kim             digest = md_alg;
3696f9291ceSJung-uk Kim         } else {
37074664626SKris Kennaway             BIO_printf(bio_err, "unknown option %s\n", *argv);
37174664626SKris Kennaway             badops = 1;
37274664626SKris Kennaway             break;
37374664626SKris Kennaway         }
37474664626SKris Kennaway         argc--;
37574664626SKris Kennaway         argv++;
37674664626SKris Kennaway     }
37774664626SKris Kennaway 
3786f9291ceSJung-uk Kim     if (badops) {
37974664626SKris Kennaway  bad:
38074664626SKris Kennaway         BIO_printf(bio_err, "%s [options] <infile >outfile\n", prog);
38174664626SKris Kennaway         BIO_printf(bio_err, "where options  are\n");
382f579bf8eSKris Kennaway         BIO_printf(bio_err, " -inform arg    input format - DER or PEM\n");
383f579bf8eSKris Kennaway         BIO_printf(bio_err, " -outform arg   output format - DER or PEM\n");
38474664626SKris Kennaway         BIO_printf(bio_err, " -in arg        input file\n");
38574664626SKris Kennaway         BIO_printf(bio_err, " -out arg       output file\n");
38674664626SKris Kennaway         BIO_printf(bio_err, " -text          text form of request\n");
3875c87c606SMark Murray         BIO_printf(bio_err, " -pubkey        output public key\n");
38874664626SKris Kennaway         BIO_printf(bio_err, " -noout         do not output REQ\n");
38974664626SKris Kennaway         BIO_printf(bio_err, " -verify        verify signature on REQ\n");
39074664626SKris Kennaway         BIO_printf(bio_err, " -modulus       RSA modulus\n");
39174664626SKris Kennaway         BIO_printf(bio_err, " -nodes         don't encrypt the output key\n");
392fceca8a3SJacques Vidrine #ifndef OPENSSL_NO_ENGINE
3936f9291ceSJung-uk Kim         BIO_printf(bio_err,
3946f9291ceSJung-uk Kim                    " -engine e      use engine e, possibly a hardware device\n");
395fceca8a3SJacques Vidrine #endif
3965c87c606SMark Murray         BIO_printf(bio_err, " -subject       output the request's subject\n");
3975c87c606SMark Murray         BIO_printf(bio_err, " -passin        private key password source\n");
3986f9291ceSJung-uk Kim         BIO_printf(bio_err,
3996f9291ceSJung-uk Kim                    " -key file      use the private key contained in file\n");
40074664626SKris Kennaway         BIO_printf(bio_err, " -keyform arg   key file format\n");
40174664626SKris Kennaway         BIO_printf(bio_err, " -keyout arg    file to send the key to\n");
4026f9291ceSJung-uk Kim         BIO_printf(bio_err, " -rand file%cfile%c...\n", LIST_SEPARATOR_CHAR,
4036f9291ceSJung-uk Kim                    LIST_SEPARATOR_CHAR);
4046f9291ceSJung-uk Kim         BIO_printf(bio_err,
4056f9291ceSJung-uk Kim                    "                load the file (or the files in the directory) into\n");
406ddd58736SKris Kennaway         BIO_printf(bio_err, "                the random number generator\n");
4076f9291ceSJung-uk Kim         BIO_printf(bio_err,
4086f9291ceSJung-uk Kim                    " -newkey rsa:bits generate a new RSA key of 'bits' in size\n");
4096f9291ceSJung-uk Kim         BIO_printf(bio_err,
4106f9291ceSJung-uk Kim                    " -newkey dsa:file generate a new DSA key, parameters taken from CA in 'file'\n");
4113b4e3dcbSSimon L. B. Nielsen #ifndef OPENSSL_NO_ECDSA
4126f9291ceSJung-uk Kim         BIO_printf(bio_err,
4136f9291ceSJung-uk Kim                    " -newkey ec:file generate a new EC key, parameters taken from CA in 'file'\n");
4143b4e3dcbSSimon L. B. Nielsen #endif
4156f9291ceSJung-uk Kim         BIO_printf(bio_err,
4166f9291ceSJung-uk Kim                    " -[digest]      Digest to sign with (md5, sha1, md2, mdc2, md4)\n");
41774664626SKris Kennaway         BIO_printf(bio_err, " -config file   request template file.\n");
4186f9291ceSJung-uk Kim         BIO_printf(bio_err,
4196f9291ceSJung-uk Kim                    " -subj arg      set or modify request subject\n");
4206f9291ceSJung-uk Kim         BIO_printf(bio_err,
4216f9291ceSJung-uk Kim                    " -multivalue-rdn enable support for multivalued RDNs\n");
42274664626SKris Kennaway         BIO_printf(bio_err, " -new           new request.\n");
4236f9291ceSJung-uk Kim         BIO_printf(bio_err,
4246f9291ceSJung-uk Kim                    " -batch         do not ask anything during request generation\n");
4256f9291ceSJung-uk Kim         BIO_printf(bio_err,
4266f9291ceSJung-uk Kim                    " -x509          output a x509 structure instead of a cert. req.\n");
4276f9291ceSJung-uk Kim         BIO_printf(bio_err,
4286f9291ceSJung-uk Kim                    " -days          number of days a certificate generated by -x509 is valid for.\n");
4296f9291ceSJung-uk Kim         BIO_printf(bio_err,
4306f9291ceSJung-uk Kim                    " -set_serial    serial number to use for a certificate generated by -x509.\n");
4316f9291ceSJung-uk Kim         BIO_printf(bio_err,
4326f9291ceSJung-uk Kim                    " -newhdr        output \"NEW\" in the header lines\n");
4336f9291ceSJung-uk Kim         BIO_printf(bio_err,
4346f9291ceSJung-uk Kim                    " -asn1-kludge   Output the 'request' in a format that is wrong but some CA's\n");
4356f9291ceSJung-uk Kim         BIO_printf(bio_err,
4366f9291ceSJung-uk Kim                    "                have been reported as requiring\n");
4376f9291ceSJung-uk Kim         BIO_printf(bio_err,
4386f9291ceSJung-uk Kim                    " -extensions .. specify certificate extension section (override value in config file)\n");
4396f9291ceSJung-uk Kim         BIO_printf(bio_err,
4406f9291ceSJung-uk Kim                    " -reqexts ..    specify request extension section (override value in config file)\n");
4416f9291ceSJung-uk Kim         BIO_printf(bio_err,
4426f9291ceSJung-uk Kim                    " -utf8          input characters are UTF8 (default ASCII)\n");
4436f9291ceSJung-uk Kim         BIO_printf(bio_err,
4446f9291ceSJung-uk Kim                    " -nameopt arg    - various certificate name options\n");
4456f9291ceSJung-uk Kim         BIO_printf(bio_err,
4466f9291ceSJung-uk Kim                    " -reqopt arg    - various request text options\n\n");
44774664626SKris Kennaway         goto end;
44874664626SKris Kennaway     }
44974664626SKris Kennaway 
45074664626SKris Kennaway     ERR_load_crypto_strings();
451f579bf8eSKris Kennaway     if (!app_passwd(bio_err, passargin, passargout, &passin, &passout)) {
452f579bf8eSKris Kennaway         BIO_printf(bio_err, "Error getting passwords\n");
453f579bf8eSKris Kennaway         goto end;
454f579bf8eSKris Kennaway     }
4556f9291ceSJung-uk Kim #ifndef MONOLITH                /* else this has happened in openssl.c
4566f9291ceSJung-uk Kim                                  * (global `config') */
45774664626SKris Kennaway     /* Lets load up our environment a little */
45874664626SKris Kennaway     p = getenv("OPENSSL_CONF");
45974664626SKris Kennaway     if (p == NULL)
46074664626SKris Kennaway         p = getenv("SSLEAY_CONF");
46174664626SKris Kennaway     if (p == NULL)
4625c87c606SMark Murray         p = to_free = make_config_name();
46374664626SKris Kennaway     default_config_file = p;
4645c87c606SMark Murray     config = NCONF_new(NULL);
4655c87c606SMark Murray     i = NCONF_load(config, p, &errline);
46674664626SKris Kennaway #endif
46774664626SKris Kennaway 
4686f9291ceSJung-uk Kim     if (template != NULL) {
4695c87c606SMark Murray         long errline = -1;
47074664626SKris Kennaway 
4715c87c606SMark Murray         if (verbose)
47274664626SKris Kennaway             BIO_printf(bio_err, "Using configuration from %s\n", template);
4735c87c606SMark Murray         req_conf = NCONF_new(NULL);
4745c87c606SMark Murray         i = NCONF_load(req_conf, template, &errline);
4756f9291ceSJung-uk Kim         if (i == 0) {
4766f9291ceSJung-uk Kim             BIO_printf(bio_err, "error on line %ld of %s\n", errline,
4776f9291ceSJung-uk Kim                        template);
47874664626SKris Kennaway             goto end;
47974664626SKris Kennaway         }
4806f9291ceSJung-uk Kim     } else {
48174664626SKris Kennaway         req_conf = config;
4823b4e3dcbSSimon L. B. Nielsen 
4836f9291ceSJung-uk Kim         if (req_conf == NULL) {
4846f9291ceSJung-uk Kim             BIO_printf(bio_err, "Unable to load config info from %s\n",
4856f9291ceSJung-uk Kim                        default_config_file);
4863b4e3dcbSSimon L. B. Nielsen             if (newreq)
4873b4e3dcbSSimon L. B. Nielsen                 goto end;
4886f9291ceSJung-uk Kim         } else if (verbose)
4893b4e3dcbSSimon L. B. Nielsen             BIO_printf(bio_err, "Using configuration from %s\n",
4903b4e3dcbSSimon L. B. Nielsen                        default_config_file);
49174664626SKris Kennaway     }
49274664626SKris Kennaway 
4936f9291ceSJung-uk Kim     if (req_conf != NULL) {
4945c87c606SMark Murray         if (!load_config(bio_err, req_conf))
4955c87c606SMark Murray             goto end;
4965c87c606SMark Murray         p = NCONF_get_string(req_conf, NULL, "oid_file");
4975c87c606SMark Murray         if (p == NULL)
4985c87c606SMark Murray             ERR_clear_error();
4996f9291ceSJung-uk Kim         if (p != NULL) {
50074664626SKris Kennaway             BIO *oid_bio;
50174664626SKris Kennaway 
50274664626SKris Kennaway             oid_bio = BIO_new_file(p, "r");
5036f9291ceSJung-uk Kim             if (oid_bio == NULL) {
5046f9291ceSJung-uk Kim                 /*-
50574664626SKris Kennaway                 BIO_printf(bio_err,"problems opening %s for extra oid's\n",p);
50674664626SKris Kennaway                 ERR_print_errors(bio_err);
50774664626SKris Kennaway                 */
5086f9291ceSJung-uk Kim             } else {
50974664626SKris Kennaway                 OBJ_create_objects(oid_bio);
51074664626SKris Kennaway                 BIO_free(oid_bio);
51174664626SKris Kennaway             }
51274664626SKris Kennaway         }
51374664626SKris Kennaway     }
5146f9291ceSJung-uk Kim     if (!add_oid_section(bio_err, req_conf))
5156f9291ceSJung-uk Kim         goto end;
51674664626SKris Kennaway 
5176f9291ceSJung-uk Kim     if (md_alg == NULL) {
5185c87c606SMark Murray         p = NCONF_get_string(req_conf, SECTION, "default_md");
5195c87c606SMark Murray         if (p == NULL)
5205c87c606SMark Murray             ERR_clear_error();
5216f9291ceSJung-uk Kim         if (p != NULL) {
52274664626SKris Kennaway             if ((md_alg = EVP_get_digestbyname(p)) != NULL)
52374664626SKris Kennaway                 digest = md_alg;
52474664626SKris Kennaway         }
5255c87c606SMark Murray     }
52674664626SKris Kennaway 
5276f9291ceSJung-uk Kim     if (!extensions) {
5285c87c606SMark Murray         extensions = NCONF_get_string(req_conf, SECTION, V3_EXTENSIONS);
5295c87c606SMark Murray         if (!extensions)
5305c87c606SMark Murray             ERR_clear_error();
5315c87c606SMark Murray     }
53274664626SKris Kennaway     if (extensions) {
53374664626SKris Kennaway         /* Check syntax of file */
53474664626SKris Kennaway         X509V3_CTX ctx;
53574664626SKris Kennaway         X509V3_set_ctx_test(&ctx);
5365c87c606SMark Murray         X509V3_set_nconf(&ctx, req_conf);
5375c87c606SMark Murray         if (!X509V3_EXT_add_nconf(req_conf, &ctx, extensions, NULL)) {
53874664626SKris Kennaway             BIO_printf(bio_err,
53974664626SKris Kennaway                        "Error Loading extension section %s\n", extensions);
54074664626SKris Kennaway             goto end;
54174664626SKris Kennaway         }
54274664626SKris Kennaway     }
54374664626SKris Kennaway 
5446f9291ceSJung-uk Kim     if (!passin) {
5455c87c606SMark Murray         passin = NCONF_get_string(req_conf, SECTION, "input_password");
5465c87c606SMark Murray         if (!passin)
5475c87c606SMark Murray             ERR_clear_error();
5485c87c606SMark Murray     }
549f579bf8eSKris Kennaway 
5506f9291ceSJung-uk Kim     if (!passout) {
5515c87c606SMark Murray         passout = NCONF_get_string(req_conf, SECTION, "output_password");
5525c87c606SMark Murray         if (!passout)
5535c87c606SMark Murray             ERR_clear_error();
5545c87c606SMark Murray     }
555f579bf8eSKris Kennaway 
5565c87c606SMark Murray     p = NCONF_get_string(req_conf, SECTION, STRING_MASK);
5575c87c606SMark Murray     if (!p)
5585c87c606SMark Murray         ERR_clear_error();
559f579bf8eSKris Kennaway 
560f579bf8eSKris Kennaway     if (p && !ASN1_STRING_set_default_mask_asc(p)) {
561f579bf8eSKris Kennaway         BIO_printf(bio_err, "Invalid global string mask setting %s\n", p);
562f579bf8eSKris Kennaway         goto end;
563f579bf8eSKris Kennaway     }
564f579bf8eSKris Kennaway 
5656f9291ceSJung-uk Kim     if (chtype != MBSTRING_UTF8) {
5665c87c606SMark Murray         p = NCONF_get_string(req_conf, SECTION, UTF8_IN);
5675c87c606SMark Murray         if (!p)
5685c87c606SMark Murray             ERR_clear_error();
5695c87c606SMark Murray         else if (!strcmp(p, "yes"))
5705c87c606SMark Murray             chtype = MBSTRING_UTF8;
5715c87c606SMark Murray     }
5725c87c606SMark Murray 
5736f9291ceSJung-uk Kim     if (!req_exts) {
5745c87c606SMark Murray         req_exts = NCONF_get_string(req_conf, SECTION, REQ_EXTENSIONS);
5755c87c606SMark Murray         if (!req_exts)
5765c87c606SMark Murray             ERR_clear_error();
5775c87c606SMark Murray     }
578f579bf8eSKris Kennaway     if (req_exts) {
579f579bf8eSKris Kennaway         /* Check syntax of file */
580f579bf8eSKris Kennaway         X509V3_CTX ctx;
581f579bf8eSKris Kennaway         X509V3_set_ctx_test(&ctx);
5825c87c606SMark Murray         X509V3_set_nconf(&ctx, req_conf);
5835c87c606SMark Murray         if (!X509V3_EXT_add_nconf(req_conf, &ctx, req_exts, NULL)) {
584f579bf8eSKris Kennaway             BIO_printf(bio_err,
585f579bf8eSKris Kennaway                        "Error Loading request extension section %s\n",
586f579bf8eSKris Kennaway                        req_exts);
587f579bf8eSKris Kennaway             goto end;
588f579bf8eSKris Kennaway         }
589f579bf8eSKris Kennaway     }
590f579bf8eSKris Kennaway 
59174664626SKris Kennaway     in = BIO_new(BIO_s_file());
59274664626SKris Kennaway     out = BIO_new(BIO_s_file());
59374664626SKris Kennaway     if ((in == NULL) || (out == NULL))
59474664626SKris Kennaway         goto end;
59574664626SKris Kennaway 
5965c87c606SMark Murray     e = setup_engine(bio_err, engine, 0);
5975c87c606SMark Murray 
5986f9291ceSJung-uk Kim     if (keyfile != NULL) {
5995c87c606SMark Murray         pkey = load_key(bio_err, keyfile, keyform, 0, passin, e,
6005c87c606SMark Murray                         "Private Key");
6016f9291ceSJung-uk Kim         if (!pkey) {
6026f9291ceSJung-uk Kim             /*
6036f9291ceSJung-uk Kim              * load_key() has already printed an appropriate message
6046f9291ceSJung-uk Kim              */
60574664626SKris Kennaway             goto end;
6066f9291ceSJung-uk Kim         } else {
6075c87c606SMark Murray             char *randfile = NCONF_get_string(req_conf, SECTION, "RANDFILE");
6085c87c606SMark Murray             if (randfile == NULL)
6095c87c606SMark Murray                 ERR_clear_error();
610ddd58736SKris Kennaway             app_RAND_load_file(randfile, bio_err, 0);
611ddd58736SKris Kennaway         }
61274664626SKris Kennaway     }
61374664626SKris Kennaway 
6146f9291ceSJung-uk Kim     if (newreq && (pkey == NULL)) {
6155c87c606SMark Murray         char *randfile = NCONF_get_string(req_conf, SECTION, "RANDFILE");
6165c87c606SMark Murray         if (randfile == NULL)
6175c87c606SMark Murray             ERR_clear_error();
618f579bf8eSKris Kennaway         app_RAND_load_file(randfile, bio_err, 0);
619ddd58736SKris Kennaway         if (inrand)
620ddd58736SKris Kennaway             app_RAND_load_files(inrand);
62174664626SKris Kennaway 
6226f9291ceSJung-uk Kim         if (!NCONF_get_number(req_conf, SECTION, BITS, &newkey)) {
623560ede85SJung-uk Kim             newkey = DEFAULT_KEY_LENGTH;
624560ede85SJung-uk Kim         }
625560ede85SJung-uk Kim 
6266f9291ceSJung-uk Kim         if (keyalg) {
6271f13597dSJung-uk Kim             genctx = set_keygen_ctx(bio_err, keyalg, &pkey_type, &newkey,
6281f13597dSJung-uk Kim                                     &keyalgstr, gen_eng);
6291f13597dSJung-uk Kim             if (!genctx)
6301f13597dSJung-uk Kim                 goto end;
6311f13597dSJung-uk Kim         }
6321f13597dSJung-uk Kim 
6336f9291ceSJung-uk Kim         if (newkey < MIN_KEY_LENGTH
6346f9291ceSJung-uk Kim             && (pkey_type == EVP_PKEY_RSA || pkey_type == EVP_PKEY_DSA)) {
63574664626SKris Kennaway             BIO_printf(bio_err, "private key length is too short,\n");
6366f9291ceSJung-uk Kim             BIO_printf(bio_err, "it needs to be at least %d bits, not %ld\n",
6376f9291ceSJung-uk Kim                        MIN_KEY_LENGTH, newkey);
63874664626SKris Kennaway             goto end;
63974664626SKris Kennaway         }
6401f13597dSJung-uk Kim 
6416f9291ceSJung-uk Kim         if (!genctx) {
6421f13597dSJung-uk Kim             genctx = set_keygen_ctx(bio_err, NULL, &pkey_type, &newkey,
6431f13597dSJung-uk Kim                                     &keyalgstr, gen_eng);
6441f13597dSJung-uk Kim             if (!genctx)
6451f13597dSJung-uk Kim                 goto end;
6461f13597dSJung-uk Kim         }
6471f13597dSJung-uk Kim 
6486f9291ceSJung-uk Kim         if (pkeyopts) {
6491f13597dSJung-uk Kim             char *genopt;
6506f9291ceSJung-uk Kim             for (i = 0; i < sk_OPENSSL_STRING_num(pkeyopts); i++) {
6511f13597dSJung-uk Kim                 genopt = sk_OPENSSL_STRING_value(pkeyopts, i);
6526f9291ceSJung-uk Kim                 if (pkey_ctrl_string(genctx, genopt) <= 0) {
6536f9291ceSJung-uk Kim                     BIO_printf(bio_err, "parameter error \"%s\"\n", genopt);
6541f13597dSJung-uk Kim                     ERR_print_errors(bio_err);
6551f13597dSJung-uk Kim                     goto end;
6561f13597dSJung-uk Kim                 }
6571f13597dSJung-uk Kim             }
6581f13597dSJung-uk Kim         }
6591f13597dSJung-uk Kim 
6603b4e3dcbSSimon L. B. Nielsen         BIO_printf(bio_err, "Generating a %ld bit %s private key\n",
6611f13597dSJung-uk Kim                    newkey, keyalgstr);
66274664626SKris Kennaway 
6631f13597dSJung-uk Kim         EVP_PKEY_CTX_set_cb(genctx, genpkey_cb);
6641f13597dSJung-uk Kim         EVP_PKEY_CTX_set_app_data(genctx, bio_err);
66574664626SKris Kennaway 
6666f9291ceSJung-uk Kim         if (EVP_PKEY_keygen(genctx, &pkey) <= 0) {
6671f13597dSJung-uk Kim             BIO_puts(bio_err, "Error Generating Key\n");
66874664626SKris Kennaway             goto end;
66974664626SKris Kennaway         }
6701f13597dSJung-uk Kim 
6711f13597dSJung-uk Kim         EVP_PKEY_CTX_free(genctx);
6721f13597dSJung-uk Kim         genctx = NULL;
67374664626SKris Kennaway 
674f579bf8eSKris Kennaway         app_RAND_write_file(randfile, bio_err);
67574664626SKris Kennaway 
6766f9291ceSJung-uk Kim         if (keyout == NULL) {
6775c87c606SMark Murray             keyout = NCONF_get_string(req_conf, SECTION, KEYFILE);
6785c87c606SMark Murray             if (keyout == NULL)
6795c87c606SMark Murray                 ERR_clear_error();
6805c87c606SMark Murray         }
68174664626SKris Kennaway 
6826f9291ceSJung-uk Kim         if (keyout == NULL) {
68374664626SKris Kennaway             BIO_printf(bio_err, "writing new private key to stdout\n");
68474664626SKris Kennaway             BIO_set_fp(out, stdout, BIO_NOCLOSE);
6855c87c606SMark Murray #ifdef OPENSSL_SYS_VMS
686ddd58736SKris Kennaway             {
687ddd58736SKris Kennaway                 BIO *tmpbio = BIO_new(BIO_f_linebuffer());
688ddd58736SKris Kennaway                 out = BIO_push(tmpbio, out);
689ddd58736SKris Kennaway             }
690ddd58736SKris Kennaway #endif
6916f9291ceSJung-uk Kim         } else {
69274664626SKris Kennaway             BIO_printf(bio_err, "writing new private key to '%s'\n", keyout);
6936f9291ceSJung-uk Kim             if (BIO_write_filename(out, keyout) <= 0) {
69474664626SKris Kennaway                 perror(keyout);
69574664626SKris Kennaway                 goto end;
69674664626SKris Kennaway             }
69774664626SKris Kennaway         }
69874664626SKris Kennaway 
6995c87c606SMark Murray         p = NCONF_get_string(req_conf, SECTION, "encrypt_rsa_key");
7006f9291ceSJung-uk Kim         if (p == NULL) {
7015c87c606SMark Murray             ERR_clear_error();
7025c87c606SMark Murray             p = NCONF_get_string(req_conf, SECTION, "encrypt_key");
7035c87c606SMark Murray             if (p == NULL)
7045c87c606SMark Murray                 ERR_clear_error();
7055c87c606SMark Murray         }
70674664626SKris Kennaway         if ((p != NULL) && (strcmp(p, "no") == 0))
70774664626SKris Kennaway             cipher = NULL;
7086f9291ceSJung-uk Kim         if (nodes)
7096f9291ceSJung-uk Kim             cipher = NULL;
71074664626SKris Kennaway 
71174664626SKris Kennaway         i = 0;
71274664626SKris Kennaway  loop:
71374664626SKris Kennaway         if (!PEM_write_bio_PrivateKey(out, pkey, cipher,
7146f9291ceSJung-uk Kim                                       NULL, 0, NULL, passout)) {
71574664626SKris Kennaway             if ((ERR_GET_REASON(ERR_peek_error()) ==
7166f9291ceSJung-uk Kim                  PEM_R_PROBLEMS_GETTING_PASSWORD) && (i < 3)) {
71774664626SKris Kennaway                 ERR_clear_error();
71874664626SKris Kennaway                 i++;
71974664626SKris Kennaway                 goto loop;
72074664626SKris Kennaway             }
72174664626SKris Kennaway             goto end;
72274664626SKris Kennaway         }
72374664626SKris Kennaway         BIO_printf(bio_err, "-----\n");
72474664626SKris Kennaway     }
72574664626SKris Kennaway 
7266f9291ceSJung-uk Kim     if (!newreq) {
7276f9291ceSJung-uk Kim         /*
7286f9291ceSJung-uk Kim          * Since we are using a pre-existing certificate request, the kludge
7296f9291ceSJung-uk Kim          * 'format' info should not be changed.
7306f9291ceSJung-uk Kim          */
73174664626SKris Kennaway         kludge = -1;
73274664626SKris Kennaway         if (infile == NULL)
73374664626SKris Kennaway             BIO_set_fp(in, stdin, BIO_NOCLOSE);
7346f9291ceSJung-uk Kim         else {
7356f9291ceSJung-uk Kim             if (BIO_read_filename(in, infile) <= 0) {
73674664626SKris Kennaway                 perror(infile);
73774664626SKris Kennaway                 goto end;
73874664626SKris Kennaway             }
73974664626SKris Kennaway         }
74074664626SKris Kennaway 
74174664626SKris Kennaway         if (informat == FORMAT_ASN1)
74274664626SKris Kennaway             req = d2i_X509_REQ_bio(in, NULL);
74374664626SKris Kennaway         else if (informat == FORMAT_PEM)
74474664626SKris Kennaway             req = PEM_read_bio_X509_REQ(in, NULL, NULL, NULL);
7456f9291ceSJung-uk Kim         else {
7466f9291ceSJung-uk Kim             BIO_printf(bio_err,
7476f9291ceSJung-uk Kim                        "bad input format specified for X509 request\n");
74874664626SKris Kennaway             goto end;
74974664626SKris Kennaway         }
7506f9291ceSJung-uk Kim         if (req == NULL) {
75174664626SKris Kennaway             BIO_printf(bio_err, "unable to load X509 request\n");
75274664626SKris Kennaway             goto end;
75374664626SKris Kennaway         }
75474664626SKris Kennaway     }
75574664626SKris Kennaway 
756aeb5019cSJung-uk Kim     if (newreq) {
7576f9291ceSJung-uk Kim         if (pkey == NULL) {
75874664626SKris Kennaway             BIO_printf(bio_err, "you need to specify a private key\n");
75974664626SKris Kennaway             goto end;
76074664626SKris Kennaway         }
7611f13597dSJung-uk Kim 
7626f9291ceSJung-uk Kim         if (req == NULL) {
76374664626SKris Kennaway             req = X509_REQ_new();
7646f9291ceSJung-uk Kim             if (req == NULL) {
76574664626SKris Kennaway                 goto end;
76674664626SKris Kennaway             }
76774664626SKris Kennaway 
7683b4e3dcbSSimon L. B. Nielsen             i = make_REQ(req, pkey, subj, multirdn, !x509, chtype);
7695c87c606SMark Murray             subj = NULL;        /* done processing '-subj' option */
7706f9291ceSJung-uk Kim             if ((kludge > 0)
7716f9291ceSJung-uk Kim                 && !sk_X509_ATTRIBUTE_num(req->req_info->attributes)) {
7725c87c606SMark Murray                 sk_X509_ATTRIBUTE_free(req->req_info->attributes);
7735c87c606SMark Murray                 req->req_info->attributes = NULL;
7745c87c606SMark Murray             }
7756f9291ceSJung-uk Kim             if (!i) {
77674664626SKris Kennaway                 BIO_printf(bio_err, "problems making Certificate Request\n");
77774664626SKris Kennaway                 goto end;
77874664626SKris Kennaway             }
77974664626SKris Kennaway         }
7806f9291ceSJung-uk Kim         if (x509) {
78174664626SKris Kennaway             EVP_PKEY *tmppkey;
78274664626SKris Kennaway             X509V3_CTX ext_ctx;
7836f9291ceSJung-uk Kim             if ((x509ss = X509_new()) == NULL)
7846f9291ceSJung-uk Kim                 goto end;
78574664626SKris Kennaway 
78674664626SKris Kennaway             /* Set version to V3 */
7876f9291ceSJung-uk Kim             if (extensions && !X509_set_version(x509ss, 2))
7886f9291ceSJung-uk Kim                 goto end;
7896f9291ceSJung-uk Kim             if (serial) {
7906f9291ceSJung-uk Kim                 if (!X509_set_serialNumber(x509ss, serial))
7916f9291ceSJung-uk Kim                     goto end;
7926f9291ceSJung-uk Kim             } else {
7936f9291ceSJung-uk Kim                 if (!rand_serial(NULL, X509_get_serialNumber(x509ss)))
7946be8ae07SJacques Vidrine                     goto end;
7955c87c606SMark Murray             }
79674664626SKris Kennaway 
7976f9291ceSJung-uk Kim             if (!X509_set_issuer_name(x509ss, X509_REQ_get_subject_name(req)))
7986f9291ceSJung-uk Kim                 goto end;
7996f9291ceSJung-uk Kim             if (!X509_gmtime_adj(X509_get_notBefore(x509ss), 0))
8006f9291ceSJung-uk Kim                 goto end;
8016f9291ceSJung-uk Kim             if (!X509_time_adj_ex(X509_get_notAfter(x509ss), days, 0, NULL))
8026f9291ceSJung-uk Kim                 goto end;
8036f9291ceSJung-uk Kim             if (!X509_set_subject_name
8046f9291ceSJung-uk Kim                 (x509ss, X509_REQ_get_subject_name(req)))
8056f9291ceSJung-uk Kim                 goto end;
80674664626SKris Kennaway             tmppkey = X509_REQ_get_pubkey(req);
8076f9291ceSJung-uk Kim             if (!tmppkey || !X509_set_pubkey(x509ss, tmppkey))
8086f9291ceSJung-uk Kim                 goto end;
80974664626SKris Kennaway             EVP_PKEY_free(tmppkey);
81074664626SKris Kennaway 
81174664626SKris Kennaway             /* Set up V3 context struct */
81274664626SKris Kennaway 
81374664626SKris Kennaway             X509V3_set_ctx(&ext_ctx, x509ss, x509ss, NULL, NULL, 0);
8145c87c606SMark Murray             X509V3_set_nconf(&ext_ctx, req_conf);
81574664626SKris Kennaway 
81674664626SKris Kennaway             /* Add extensions */
8175c87c606SMark Murray             if (extensions && !X509V3_EXT_add_nconf(req_conf,
8186f9291ceSJung-uk Kim                                                     &ext_ctx, extensions,
8196f9291ceSJung-uk Kim                                                     x509ss)) {
8206f9291ceSJung-uk Kim                 BIO_printf(bio_err, "Error Loading extension section %s\n",
82174664626SKris Kennaway                            extensions);
82274664626SKris Kennaway                 goto end;
82374664626SKris Kennaway             }
82474664626SKris Kennaway 
8251f13597dSJung-uk Kim             i = do_X509_sign(bio_err, x509ss, pkey, digest, sigopts);
8266f9291ceSJung-uk Kim             if (!i) {
8271f13597dSJung-uk Kim                 ERR_print_errors(bio_err);
82874664626SKris Kennaway                 goto end;
82974664626SKris Kennaway             }
8306f9291ceSJung-uk Kim         } else {
831f579bf8eSKris Kennaway             X509V3_CTX ext_ctx;
832f579bf8eSKris Kennaway 
833f579bf8eSKris Kennaway             /* Set up V3 context struct */
834f579bf8eSKris Kennaway 
835f579bf8eSKris Kennaway             X509V3_set_ctx(&ext_ctx, NULL, NULL, req, NULL, 0);
8365c87c606SMark Murray             X509V3_set_nconf(&ext_ctx, req_conf);
837f579bf8eSKris Kennaway 
838f579bf8eSKris Kennaway             /* Add extensions */
8395c87c606SMark Murray             if (req_exts && !X509V3_EXT_REQ_add_nconf(req_conf,
8406f9291ceSJung-uk Kim                                                       &ext_ctx, req_exts,
8416f9291ceSJung-uk Kim                                                       req)) {
8426f9291ceSJung-uk Kim                 BIO_printf(bio_err, "Error Loading extension section %s\n",
843f579bf8eSKris Kennaway                            req_exts);
844f579bf8eSKris Kennaway                 goto end;
845f579bf8eSKris Kennaway             }
8461f13597dSJung-uk Kim             i = do_X509_REQ_sign(bio_err, req, pkey, digest, sigopts);
8476f9291ceSJung-uk Kim             if (!i) {
8481f13597dSJung-uk Kim                 ERR_print_errors(bio_err);
84974664626SKris Kennaway                 goto end;
85074664626SKris Kennaway             }
85174664626SKris Kennaway         }
8521f13597dSJung-uk Kim     }
85374664626SKris Kennaway 
8546f9291ceSJung-uk Kim     if (subj && x509) {
8555c87c606SMark Murray         BIO_printf(bio_err, "Cannot modifiy certificate subject\n");
8565c87c606SMark Murray         goto end;
8575c87c606SMark Murray     }
8585c87c606SMark Murray 
8596f9291ceSJung-uk Kim     if (subj && !x509) {
8606f9291ceSJung-uk Kim         if (verbose) {
8615c87c606SMark Murray             BIO_printf(bio_err, "Modifying Request's Subject\n");
8626f9291ceSJung-uk Kim             print_name(bio_err, "old subject=",
8636f9291ceSJung-uk Kim                        X509_REQ_get_subject_name(req), nmflag);
8645c87c606SMark Murray         }
8655c87c606SMark Murray 
8666f9291ceSJung-uk Kim         if (build_subject(req, subj, chtype, multirdn) == 0) {
8675c87c606SMark Murray             BIO_printf(bio_err, "ERROR: cannot modify subject\n");
8685c87c606SMark Murray             ex = 1;
8695c87c606SMark Murray             goto end;
8705c87c606SMark Murray         }
8715c87c606SMark Murray 
8725c87c606SMark Murray         req->req_info->enc.modified = 1;
8735c87c606SMark Murray 
8746f9291ceSJung-uk Kim         if (verbose) {
8756f9291ceSJung-uk Kim             print_name(bio_err, "new subject=",
8766f9291ceSJung-uk Kim                        X509_REQ_get_subject_name(req), nmflag);
8775c87c606SMark Murray         }
8785c87c606SMark Murray     }
8795c87c606SMark Murray 
8806f9291ceSJung-uk Kim     if (verify && !x509) {
88174664626SKris Kennaway         int tmp = 0;
88274664626SKris Kennaway 
8836f9291ceSJung-uk Kim         if (pkey == NULL) {
88474664626SKris Kennaway             pkey = X509_REQ_get_pubkey(req);
88574664626SKris Kennaway             tmp = 1;
8866f9291ceSJung-uk Kim             if (pkey == NULL)
8876f9291ceSJung-uk Kim                 goto end;
88874664626SKris Kennaway         }
88974664626SKris Kennaway 
89074664626SKris Kennaway         i = X509_REQ_verify(req, pkey);
89174664626SKris Kennaway         if (tmp) {
89274664626SKris Kennaway             EVP_PKEY_free(pkey);
89374664626SKris Kennaway             pkey = NULL;
89474664626SKris Kennaway         }
89574664626SKris Kennaway 
8966f9291ceSJung-uk Kim         if (i < 0) {
89774664626SKris Kennaway             goto end;
8986f9291ceSJung-uk Kim         } else if (i == 0) {
89974664626SKris Kennaway             BIO_printf(bio_err, "verify failure\n");
9005c87c606SMark Murray             ERR_print_errors(bio_err);
9016f9291ceSJung-uk Kim         } else                  /* if (i > 0) */
90274664626SKris Kennaway             BIO_printf(bio_err, "verify OK\n");
90374664626SKris Kennaway     }
90474664626SKris Kennaway 
9056f9291ceSJung-uk Kim     if (noout && !text && !modulus && !subject && !pubkey) {
90674664626SKris Kennaway         ex = 0;
90774664626SKris Kennaway         goto end;
90874664626SKris Kennaway     }
90974664626SKris Kennaway 
9106f9291ceSJung-uk Kim     if (outfile == NULL) {
91174664626SKris Kennaway         BIO_set_fp(out, stdout, BIO_NOCLOSE);
9125c87c606SMark Murray #ifdef OPENSSL_SYS_VMS
913ddd58736SKris Kennaway         {
914ddd58736SKris Kennaway             BIO *tmpbio = BIO_new(BIO_f_linebuffer());
915ddd58736SKris Kennaway             out = BIO_push(tmpbio, out);
916ddd58736SKris Kennaway         }
917ddd58736SKris Kennaway #endif
9186f9291ceSJung-uk Kim     } else {
91974664626SKris Kennaway         if ((keyout != NULL) && (strcmp(outfile, keyout) == 0))
92074664626SKris Kennaway             i = (int)BIO_append_filename(out, outfile);
92174664626SKris Kennaway         else
92274664626SKris Kennaway             i = (int)BIO_write_filename(out, outfile);
9236f9291ceSJung-uk Kim         if (!i) {
92474664626SKris Kennaway             perror(outfile);
92574664626SKris Kennaway             goto end;
92674664626SKris Kennaway         }
92774664626SKris Kennaway     }
92874664626SKris Kennaway 
9296f9291ceSJung-uk Kim     if (pubkey) {
9305c87c606SMark Murray         EVP_PKEY *tpubkey;
9315c87c606SMark Murray         tpubkey = X509_REQ_get_pubkey(req);
9326f9291ceSJung-uk Kim         if (tpubkey == NULL) {
9335c87c606SMark Murray             BIO_printf(bio_err, "Error getting public key\n");
9345c87c606SMark Murray             ERR_print_errors(bio_err);
9355c87c606SMark Murray             goto end;
9365c87c606SMark Murray         }
9375c87c606SMark Murray         PEM_write_bio_PUBKEY(out, tpubkey);
9385c87c606SMark Murray         EVP_PKEY_free(tpubkey);
9395c87c606SMark Murray     }
9405c87c606SMark Murray 
9416f9291ceSJung-uk Kim     if (text) {
94274664626SKris Kennaway         if (x509)
9435c87c606SMark Murray             X509_print_ex(out, x509ss, nmflag, reqflag);
94474664626SKris Kennaway         else
9455c87c606SMark Murray             X509_REQ_print_ex(out, req, nmflag, reqflag);
9465c87c606SMark Murray     }
9475c87c606SMark Murray 
9486f9291ceSJung-uk Kim     if (subject) {
9495c87c606SMark Murray         if (x509)
9506f9291ceSJung-uk Kim             print_name(out, "subject=", X509_get_subject_name(x509ss),
9516f9291ceSJung-uk Kim                        nmflag);
9525c87c606SMark Murray         else
9536f9291ceSJung-uk Kim             print_name(out, "subject=", X509_REQ_get_subject_name(req),
9546f9291ceSJung-uk Kim                        nmflag);
95574664626SKris Kennaway     }
95674664626SKris Kennaway 
9576f9291ceSJung-uk Kim     if (modulus) {
9585c87c606SMark Murray         EVP_PKEY *tpubkey;
95974664626SKris Kennaway 
96074664626SKris Kennaway         if (x509)
9615c87c606SMark Murray             tpubkey = X509_get_pubkey(x509ss);
96274664626SKris Kennaway         else
9635c87c606SMark Murray             tpubkey = X509_REQ_get_pubkey(req);
9646f9291ceSJung-uk Kim         if (tpubkey == NULL) {
96574664626SKris Kennaway             fprintf(stdout, "Modulus=unavailable\n");
96674664626SKris Kennaway             goto end;
96774664626SKris Kennaway         }
96874664626SKris Kennaway         fprintf(stdout, "Modulus=");
9695c87c606SMark Murray #ifndef OPENSSL_NO_RSA
9701f13597dSJung-uk Kim         if (EVP_PKEY_base_id(tpubkey) == EVP_PKEY_RSA)
9715c87c606SMark Murray             BN_print(out, tpubkey->pkey.rsa->n);
97274664626SKris Kennaway         else
97374664626SKris Kennaway #endif
97474664626SKris Kennaway             fprintf(stdout, "Wrong Algorithm type");
9755c87c606SMark Murray         EVP_PKEY_free(tpubkey);
97674664626SKris Kennaway         fprintf(stdout, "\n");
97774664626SKris Kennaway     }
97874664626SKris Kennaway 
9796f9291ceSJung-uk Kim     if (!noout && !x509) {
98074664626SKris Kennaway         if (outformat == FORMAT_ASN1)
98174664626SKris Kennaway             i = i2d_X509_REQ_bio(out, req);
982f579bf8eSKris Kennaway         else if (outformat == FORMAT_PEM) {
9836f9291ceSJung-uk Kim             if (newhdr)
9846f9291ceSJung-uk Kim                 i = PEM_write_bio_X509_REQ_NEW(out, req);
9856f9291ceSJung-uk Kim             else
9866f9291ceSJung-uk Kim                 i = PEM_write_bio_X509_REQ(out, req);
987f579bf8eSKris Kennaway         } else {
98874664626SKris Kennaway             BIO_printf(bio_err, "bad output format specified for outfile\n");
98974664626SKris Kennaway             goto end;
99074664626SKris Kennaway         }
9916f9291ceSJung-uk Kim         if (!i) {
99274664626SKris Kennaway             BIO_printf(bio_err, "unable to write X509 request\n");
99374664626SKris Kennaway             goto end;
99474664626SKris Kennaway         }
99574664626SKris Kennaway     }
9966f9291ceSJung-uk Kim     if (!noout && x509 && (x509ss != NULL)) {
99774664626SKris Kennaway         if (outformat == FORMAT_ASN1)
99874664626SKris Kennaway             i = i2d_X509_bio(out, x509ss);
99974664626SKris Kennaway         else if (outformat == FORMAT_PEM)
100074664626SKris Kennaway             i = PEM_write_bio_X509(out, x509ss);
100174664626SKris Kennaway         else {
100274664626SKris Kennaway             BIO_printf(bio_err, "bad output format specified for outfile\n");
100374664626SKris Kennaway             goto end;
100474664626SKris Kennaway         }
10056f9291ceSJung-uk Kim         if (!i) {
100674664626SKris Kennaway             BIO_printf(bio_err, "unable to write X509 certificate\n");
100774664626SKris Kennaway             goto end;
100874664626SKris Kennaway         }
100974664626SKris Kennaway     }
101074664626SKris Kennaway     ex = 0;
101174664626SKris Kennaway  end:
10125c87c606SMark Murray #ifndef MONOLITH
10135c87c606SMark Murray     if (to_free)
10145c87c606SMark Murray         OPENSSL_free(to_free);
10155c87c606SMark Murray #endif
10166f9291ceSJung-uk Kim     if (ex) {
101774664626SKris Kennaway         ERR_print_errors(bio_err);
101874664626SKris Kennaway     }
10196f9291ceSJung-uk Kim     if ((req_conf != NULL) && (req_conf != config))
10206f9291ceSJung-uk Kim         NCONF_free(req_conf);
102174664626SKris Kennaway     BIO_free(in);
1022ddd58736SKris Kennaway     BIO_free_all(out);
102374664626SKris Kennaway     EVP_PKEY_free(pkey);
10241f13597dSJung-uk Kim     if (genctx)
10251f13597dSJung-uk Kim         EVP_PKEY_CTX_free(genctx);
10261f13597dSJung-uk Kim     if (pkeyopts)
10271f13597dSJung-uk Kim         sk_OPENSSL_STRING_free(pkeyopts);
10281f13597dSJung-uk Kim     if (sigopts)
10291f13597dSJung-uk Kim         sk_OPENSSL_STRING_free(sigopts);
10301f13597dSJung-uk Kim #ifndef OPENSSL_NO_ENGINE
10311f13597dSJung-uk Kim     if (gen_eng)
10321f13597dSJung-uk Kim         ENGINE_free(gen_eng);
10331f13597dSJung-uk Kim #endif
10341f13597dSJung-uk Kim     if (keyalgstr)
10351f13597dSJung-uk Kim         OPENSSL_free(keyalgstr);
103674664626SKris Kennaway     X509_REQ_free(req);
103774664626SKris Kennaway     X509_free(x509ss);
10385c87c606SMark Murray     ASN1_INTEGER_free(serial);
1039*6cf8931aSJung-uk Kim     release_engine(e);
10406f9291ceSJung-uk Kim     if (passargin && passin)
10416f9291ceSJung-uk Kim         OPENSSL_free(passin);
10426f9291ceSJung-uk Kim     if (passargout && passout)
10436f9291ceSJung-uk Kim         OPENSSL_free(passout);
104474664626SKris Kennaway     OBJ_cleanup();
10455c87c606SMark Murray     apps_shutdown();
10465c87c606SMark Murray     OPENSSL_EXIT(ex);
104774664626SKris Kennaway }
104874664626SKris Kennaway 
10493b4e3dcbSSimon L. B. Nielsen static int make_REQ(X509_REQ *req, EVP_PKEY *pkey, char *subj, int multirdn,
10503b4e3dcbSSimon L. B. Nielsen                     int attribs, unsigned long chtype)
105174664626SKris Kennaway {
105274664626SKris Kennaway     int ret = 0, i;
1053f579bf8eSKris Kennaway     char no_prompt = 0;
1054f579bf8eSKris Kennaway     STACK_OF(CONF_VALUE) *dn_sk, *attr_sk = NULL;
1055f579bf8eSKris Kennaway     char *tmp, *dn_sect, *attr_sect;
105674664626SKris Kennaway 
10575c87c606SMark Murray     tmp = NCONF_get_string(req_conf, SECTION, PROMPT);
10585c87c606SMark Murray     if (tmp == NULL)
10595c87c606SMark Murray         ERR_clear_error();
10606f9291ceSJung-uk Kim     if ((tmp != NULL) && !strcmp(tmp, "no"))
10616f9291ceSJung-uk Kim         no_prompt = 1;
1062f579bf8eSKris Kennaway 
10635c87c606SMark Murray     dn_sect = NCONF_get_string(req_conf, SECTION, DISTINGUISHED_NAME);
10646f9291ceSJung-uk Kim     if (dn_sect == NULL) {
106574664626SKris Kennaway         BIO_printf(bio_err, "unable to find '%s' in config\n",
106674664626SKris Kennaway                    DISTINGUISHED_NAME);
106774664626SKris Kennaway         goto err;
106874664626SKris Kennaway     }
10695c87c606SMark Murray     dn_sk = NCONF_get_section(req_conf, dn_sect);
10706f9291ceSJung-uk Kim     if (dn_sk == NULL) {
1071f579bf8eSKris Kennaway         BIO_printf(bio_err, "unable to get '%s' section\n", dn_sect);
107274664626SKris Kennaway         goto err;
107374664626SKris Kennaway     }
107474664626SKris Kennaway 
10755c87c606SMark Murray     attr_sect = NCONF_get_string(req_conf, SECTION, ATTRIBUTES);
10766f9291ceSJung-uk Kim     if (attr_sect == NULL) {
10775c87c606SMark Murray         ERR_clear_error();
1078f579bf8eSKris Kennaway         attr_sk = NULL;
10796f9291ceSJung-uk Kim     } else {
10805c87c606SMark Murray         attr_sk = NCONF_get_section(req_conf, attr_sect);
10816f9291ceSJung-uk Kim         if (attr_sk == NULL) {
1082f579bf8eSKris Kennaway             BIO_printf(bio_err, "unable to get '%s' section\n", attr_sect);
108374664626SKris Kennaway             goto err;
108474664626SKris Kennaway         }
108574664626SKris Kennaway     }
108674664626SKris Kennaway 
1087f579bf8eSKris Kennaway     /* setup version number */
10886f9291ceSJung-uk Kim     if (!X509_REQ_set_version(req, 0L))
10896f9291ceSJung-uk Kim         goto err;               /* version 1 */
109074664626SKris Kennaway 
10915c87c606SMark Murray     if (no_prompt)
10925c87c606SMark Murray         i = auto_info(req, dn_sk, attr_sk, attribs, chtype);
10936f9291ceSJung-uk Kim     else {
10945c87c606SMark Murray         if (subj)
10953b4e3dcbSSimon L. B. Nielsen             i = build_subject(req, subj, chtype, multirdn);
10965c87c606SMark Murray         else
10976f9291ceSJung-uk Kim             i = prompt_info(req, dn_sk, dn_sect, attr_sk, attr_sect, attribs,
10986f9291ceSJung-uk Kim                             chtype);
10995c87c606SMark Murray     }
11006f9291ceSJung-uk Kim     if (!i)
11016f9291ceSJung-uk Kim         goto err;
1102f579bf8eSKris Kennaway 
11036f9291ceSJung-uk Kim     if (!X509_REQ_set_pubkey(req, pkey))
11046f9291ceSJung-uk Kim         goto err;
1105f579bf8eSKris Kennaway 
1106f579bf8eSKris Kennaway     ret = 1;
1107f579bf8eSKris Kennaway  err:
1108f579bf8eSKris Kennaway     return (ret);
1109f579bf8eSKris Kennaway }
1110f579bf8eSKris Kennaway 
11115c87c606SMark Murray /*
11125c87c606SMark Murray  * subject is expected to be in the format /type0=value0/type1=value1/type2=...
11135c87c606SMark Murray  * where characters may be escaped by \
11145c87c606SMark Murray  */
11156f9291ceSJung-uk Kim static int build_subject(X509_REQ *req, char *subject, unsigned long chtype,
11166f9291ceSJung-uk Kim                          int multirdn)
11175c87c606SMark Murray {
11185c87c606SMark Murray     X509_NAME *n;
11195c87c606SMark Murray 
11203b4e3dcbSSimon L. B. Nielsen     if (!(n = parse_name(subject, chtype, multirdn)))
11215c87c606SMark Murray         return 0;
11225c87c606SMark Murray 
11236f9291ceSJung-uk Kim     if (!X509_REQ_set_subject_name(req, n)) {
11245c87c606SMark Murray         X509_NAME_free(n);
11255c87c606SMark Murray         return 0;
11265c87c606SMark Murray     }
11275c87c606SMark Murray     X509_NAME_free(n);
11285c87c606SMark Murray     return 1;
11295c87c606SMark Murray }
11305c87c606SMark Murray 
1131f579bf8eSKris Kennaway static int prompt_info(X509_REQ *req,
1132f579bf8eSKris Kennaway                        STACK_OF(CONF_VALUE) *dn_sk, char *dn_sect,
11336f9291ceSJung-uk Kim                        STACK_OF(CONF_VALUE) *attr_sk, char *attr_sect,
11346f9291ceSJung-uk Kim                        int attribs, unsigned long chtype)
1135f579bf8eSKris Kennaway {
1136f579bf8eSKris Kennaway     int i;
1137f579bf8eSKris Kennaway     char *p, *q;
1138f579bf8eSKris Kennaway     char buf[100];
11393b4e3dcbSSimon L. B. Nielsen     int nid, mval;
11405c87c606SMark Murray     long n_min, n_max;
11413b4e3dcbSSimon L. B. Nielsen     char *type, *value;
11423b4e3dcbSSimon L. B. Nielsen     const char *def;
1143f579bf8eSKris Kennaway     CONF_VALUE *v;
1144f579bf8eSKris Kennaway     X509_NAME *subj;
1145f579bf8eSKris Kennaway     subj = X509_REQ_get_subject_name(req);
11465c87c606SMark Murray 
11476f9291ceSJung-uk Kim     if (!batch) {
11486f9291ceSJung-uk Kim         BIO_printf(bio_err,
11496f9291ceSJung-uk Kim                    "You are about to be asked to enter information that will be incorporated\n");
115074664626SKris Kennaway         BIO_printf(bio_err, "into your certificate request.\n");
11516f9291ceSJung-uk Kim         BIO_printf(bio_err,
11526f9291ceSJung-uk Kim                    "What you are about to enter is what is called a Distinguished Name or a DN.\n");
11536f9291ceSJung-uk Kim         BIO_printf(bio_err,
11546f9291ceSJung-uk Kim                    "There are quite a few fields but you can leave some blank\n");
11556f9291ceSJung-uk Kim         BIO_printf(bio_err,
11566f9291ceSJung-uk Kim                    "For some fields there will be a default value,\n");
11576f9291ceSJung-uk Kim         BIO_printf(bio_err,
11586f9291ceSJung-uk Kim                    "If you enter '.', the field will be left blank.\n");
115974664626SKris Kennaway         BIO_printf(bio_err, "-----\n");
11605c87c606SMark Murray     }
116174664626SKris Kennaway 
11626f9291ceSJung-uk Kim     if (sk_CONF_VALUE_num(dn_sk)) {
116374664626SKris Kennaway         i = -1;
11646f9291ceSJung-uk Kim  start:for (;;) {
116574664626SKris Kennaway             i++;
11666f9291ceSJung-uk Kim             if (sk_CONF_VALUE_num(dn_sk) <= i)
11676f9291ceSJung-uk Kim                 break;
116874664626SKris Kennaway 
1169f579bf8eSKris Kennaway             v = sk_CONF_VALUE_value(dn_sk, i);
117074664626SKris Kennaway             p = q = NULL;
117174664626SKris Kennaway             type = v->name;
117274664626SKris Kennaway             if (!check_end(type, "_min") || !check_end(type, "_max") ||
11736f9291ceSJung-uk Kim                 !check_end(type, "_default") || !check_end(type, "_value"))
11746f9291ceSJung-uk Kim                 continue;
11756f9291ceSJung-uk Kim             /*
11766f9291ceSJung-uk Kim              * Skip past any leading X. X: X, etc to allow for multiple
11776f9291ceSJung-uk Kim              * instances
117874664626SKris Kennaway              */
117974664626SKris Kennaway             for (p = v->name; *p; p++)
11806f9291ceSJung-uk Kim                 if ((*p == ':') || (*p == ',') || (*p == '.')) {
118174664626SKris Kennaway                     p++;
11826f9291ceSJung-uk Kim                     if (*p)
11836f9291ceSJung-uk Kim                         type = p;
118474664626SKris Kennaway                     break;
118574664626SKris Kennaway                 }
11866f9291ceSJung-uk Kim             if (*type == '+') {
11873b4e3dcbSSimon L. B. Nielsen                 mval = -1;
11883b4e3dcbSSimon L. B. Nielsen                 type++;
11896f9291ceSJung-uk Kim             } else
11903b4e3dcbSSimon L. B. Nielsen                 mval = 0;
119174664626SKris Kennaway             /* If OBJ not recognised ignore it */
11926f9291ceSJung-uk Kim             if ((nid = OBJ_txt2nid(type)) == NID_undef)
11936f9291ceSJung-uk Kim                 goto start;
1194ced566fdSJacques Vidrine             if (BIO_snprintf(buf, sizeof buf, "%s_default", v->name)
11956f9291ceSJung-uk Kim                 >= (int)sizeof(buf)) {
11965c87c606SMark Murray                 BIO_printf(bio_err, "Name '%s' too long\n", v->name);
11975c87c606SMark Murray                 return 0;
11985c87c606SMark Murray             }
11995c87c606SMark Murray 
12006f9291ceSJung-uk Kim             if ((def = NCONF_get_string(req_conf, dn_sect, buf)) == NULL) {
12015c87c606SMark Murray                 ERR_clear_error();
12025c87c606SMark Murray                 def = "";
12035c87c606SMark Murray             }
1204ced566fdSJacques Vidrine 
1205ced566fdSJacques Vidrine             BIO_snprintf(buf, sizeof buf, "%s_value", v->name);
12066f9291ceSJung-uk Kim             if ((value = NCONF_get_string(req_conf, dn_sect, buf)) == NULL) {
12075c87c606SMark Murray                 ERR_clear_error();
120874664626SKris Kennaway                 value = NULL;
12095c87c606SMark Murray             }
121074664626SKris Kennaway 
1211ced566fdSJacques Vidrine             BIO_snprintf(buf, sizeof buf, "%s_min", v->name);
12126f9291ceSJung-uk Kim             if (!NCONF_get_number(req_conf, dn_sect, buf, &n_min)) {
1213fceca8a3SJacques Vidrine                 ERR_clear_error();
12145c87c606SMark Murray                 n_min = -1;
1215fceca8a3SJacques Vidrine             }
121674664626SKris Kennaway 
1217ced566fdSJacques Vidrine             BIO_snprintf(buf, sizeof buf, "%s_max", v->name);
12186f9291ceSJung-uk Kim             if (!NCONF_get_number(req_conf, dn_sect, buf, &n_max)) {
1219fceca8a3SJacques Vidrine                 ERR_clear_error();
12205c87c606SMark Murray                 n_max = -1;
1221fceca8a3SJacques Vidrine             }
122274664626SKris Kennaway 
1223f579bf8eSKris Kennaway             if (!add_DN_object(subj, v->value, def, value, nid,
12243b4e3dcbSSimon L. B. Nielsen                                n_min, n_max, chtype, mval))
1225f579bf8eSKris Kennaway                 return 0;
122674664626SKris Kennaway         }
12276f9291ceSJung-uk Kim         if (X509_NAME_entry_count(subj) == 0) {
12286f9291ceSJung-uk Kim             BIO_printf(bio_err,
12296f9291ceSJung-uk Kim                        "error, no objects specified in config file\n");
1230f579bf8eSKris Kennaway             return 0;
123174664626SKris Kennaway         }
123274664626SKris Kennaway 
12336f9291ceSJung-uk Kim         if (attribs) {
12346f9291ceSJung-uk Kim             if ((attr_sk != NULL) && (sk_CONF_VALUE_num(attr_sk) > 0)
12356f9291ceSJung-uk Kim                 && (!batch)) {
12366f9291ceSJung-uk Kim                 BIO_printf(bio_err,
12376f9291ceSJung-uk Kim                            "\nPlease enter the following 'extra' attributes\n");
12386f9291ceSJung-uk Kim                 BIO_printf(bio_err,
12396f9291ceSJung-uk Kim                            "to be sent with your certificate request\n");
124074664626SKris Kennaway             }
124174664626SKris Kennaway 
124274664626SKris Kennaway             i = -1;
12436f9291ceSJung-uk Kim  start2:   for (;;) {
124474664626SKris Kennaway                 i++;
12456f9291ceSJung-uk Kim                 if ((attr_sk == NULL) || (sk_CONF_VALUE_num(attr_sk) <= i))
124674664626SKris Kennaway                     break;
124774664626SKris Kennaway 
1248f579bf8eSKris Kennaway                 v = sk_CONF_VALUE_value(attr_sk, i);
124974664626SKris Kennaway                 type = v->name;
125074664626SKris Kennaway                 if ((nid = OBJ_txt2nid(type)) == NID_undef)
125174664626SKris Kennaway                     goto start2;
125274664626SKris Kennaway 
1253ced566fdSJacques Vidrine                 if (BIO_snprintf(buf, sizeof buf, "%s_default", type)
12546f9291ceSJung-uk Kim                     >= (int)sizeof(buf)) {
12555c87c606SMark Murray                     BIO_printf(bio_err, "Name '%s' too long\n", v->name);
12565c87c606SMark Murray                     return 0;
12575c87c606SMark Murray                 }
12585c87c606SMark Murray 
12595c87c606SMark Murray                 if ((def = NCONF_get_string(req_conf, attr_sect, buf))
12606f9291ceSJung-uk Kim                     == NULL) {
12615c87c606SMark Murray                     ERR_clear_error();
126274664626SKris Kennaway                     def = "";
12635c87c606SMark Murray                 }
12645c87c606SMark Murray 
1265ced566fdSJacques Vidrine                 BIO_snprintf(buf, sizeof buf, "%s_value", type);
12665c87c606SMark Murray                 if ((value = NCONF_get_string(req_conf, attr_sect, buf))
12676f9291ceSJung-uk Kim                     == NULL) {
12685c87c606SMark Murray                     ERR_clear_error();
126974664626SKris Kennaway                     value = NULL;
12705c87c606SMark Murray                 }
127174664626SKris Kennaway 
1272ced566fdSJacques Vidrine                 BIO_snprintf(buf, sizeof buf, "%s_min", type);
12736f9291ceSJung-uk Kim                 if (!NCONF_get_number(req_conf, attr_sect, buf, &n_min)) {
1274ab8565e2SSimon L. B. Nielsen                     ERR_clear_error();
12755c87c606SMark Murray                     n_min = -1;
1276ab8565e2SSimon L. B. Nielsen                 }
127774664626SKris Kennaway 
1278ced566fdSJacques Vidrine                 BIO_snprintf(buf, sizeof buf, "%s_max", type);
12796f9291ceSJung-uk Kim                 if (!NCONF_get_number(req_conf, attr_sect, buf, &n_max)) {
1280ab8565e2SSimon L. B. Nielsen                     ERR_clear_error();
12815c87c606SMark Murray                     n_max = -1;
1282ab8565e2SSimon L. B. Nielsen                 }
128374664626SKris Kennaway 
1284f579bf8eSKris Kennaway                 if (!add_attribute_object(req,
12856f9291ceSJung-uk Kim                                           v->value, def, value, nid, n_min,
12866f9291ceSJung-uk Kim                                           n_max, chtype))
1287f579bf8eSKris Kennaway                     return 0;
128874664626SKris Kennaway             }
128974664626SKris Kennaway         }
12906f9291ceSJung-uk Kim     } else {
129174664626SKris Kennaway         BIO_printf(bio_err, "No template, please set one up.\n");
1292f579bf8eSKris Kennaway         return 0;
129374664626SKris Kennaway     }
129474664626SKris Kennaway 
1295f579bf8eSKris Kennaway     return 1;
129674664626SKris Kennaway 
129774664626SKris Kennaway }
129874664626SKris Kennaway 
1299f579bf8eSKris Kennaway static int auto_info(X509_REQ *req, STACK_OF(CONF_VALUE) *dn_sk,
13006f9291ceSJung-uk Kim                      STACK_OF(CONF_VALUE) *attr_sk, int attribs,
13016f9291ceSJung-uk Kim                      unsigned long chtype)
1302f579bf8eSKris Kennaway {
1303f579bf8eSKris Kennaway     int i;
1304f579bf8eSKris Kennaway     char *p, *q;
1305f579bf8eSKris Kennaway     char *type;
1306f579bf8eSKris Kennaway     CONF_VALUE *v;
1307f579bf8eSKris Kennaway     X509_NAME *subj;
1308f579bf8eSKris Kennaway 
1309f579bf8eSKris Kennaway     subj = X509_REQ_get_subject_name(req);
1310f579bf8eSKris Kennaway 
13116f9291ceSJung-uk Kim     for (i = 0; i < sk_CONF_VALUE_num(dn_sk); i++) {
13123b4e3dcbSSimon L. B. Nielsen         int mval;
1313f579bf8eSKris Kennaway         v = sk_CONF_VALUE_value(dn_sk, i);
1314f579bf8eSKris Kennaway         p = q = NULL;
1315f579bf8eSKris Kennaway         type = v->name;
13166f9291ceSJung-uk Kim         /*
13176f9291ceSJung-uk Kim          * Skip past any leading X. X: X, etc to allow for multiple instances
1318f579bf8eSKris Kennaway          */
1319f579bf8eSKris Kennaway         for (p = v->name; *p; p++)
1320ddd58736SKris Kennaway #ifndef CHARSET_EBCDIC
1321f579bf8eSKris Kennaway             if ((*p == ':') || (*p == ',') || (*p == '.')) {
1322ddd58736SKris Kennaway #else
13236f9291ceSJung-uk Kim             if ((*p == os_toascii[':']) || (*p == os_toascii[','])
13246f9291ceSJung-uk Kim                 || (*p == os_toascii['.'])) {
1325ddd58736SKris Kennaway #endif
1326f579bf8eSKris Kennaway                 p++;
13276f9291ceSJung-uk Kim                 if (*p)
13286f9291ceSJung-uk Kim                     type = p;
1329f579bf8eSKris Kennaway                 break;
1330f579bf8eSKris Kennaway             }
13313b4e3dcbSSimon L. B. Nielsen #ifndef CHARSET_EBCDIC
1332aeb5019cSJung-uk Kim         if (*type == '+') {
13333b4e3dcbSSimon L. B. Nielsen #else
1334aeb5019cSJung-uk Kim         if (*type == os_toascii['+']) {
13353b4e3dcbSSimon L. B. Nielsen #endif
1336aeb5019cSJung-uk Kim             type++;
13373b4e3dcbSSimon L. B. Nielsen             mval = -1;
13386f9291ceSJung-uk Kim         } else
13393b4e3dcbSSimon L. B. Nielsen             mval = 0;
13405c87c606SMark Murray         if (!X509_NAME_add_entry_by_txt(subj, type, chtype,
13416f9291ceSJung-uk Kim                                         (unsigned char *)v->value, -1, -1,
13426f9291ceSJung-uk Kim                                         mval))
13436f9291ceSJung-uk Kim             return 0;
1344f579bf8eSKris Kennaway 
1345f579bf8eSKris Kennaway     }
1346f579bf8eSKris Kennaway 
13476f9291ceSJung-uk Kim     if (!X509_NAME_entry_count(subj)) {
1348f579bf8eSKris Kennaway         BIO_printf(bio_err, "error, no objects specified in config file\n");
1349f579bf8eSKris Kennaway         return 0;
1350f579bf8eSKris Kennaway     }
13516f9291ceSJung-uk Kim     if (attribs) {
13526f9291ceSJung-uk Kim         for (i = 0; i < sk_CONF_VALUE_num(attr_sk); i++) {
1353f579bf8eSKris Kennaway             v = sk_CONF_VALUE_value(attr_sk, i);
13545c87c606SMark Murray             if (!X509_REQ_add1_attr_by_txt(req, v->name, chtype,
13556f9291ceSJung-uk Kim                                            (unsigned char *)v->value, -1))
13566f9291ceSJung-uk Kim                 return 0;
1357f579bf8eSKris Kennaway         }
1358f579bf8eSKris Kennaway     }
1359f579bf8eSKris Kennaway     return 1;
1360f579bf8eSKris Kennaway }
1361f579bf8eSKris Kennaway 
13626f9291ceSJung-uk Kim static int add_DN_object(X509_NAME *n, char *text, const char *def,
13636f9291ceSJung-uk Kim                          char *value, int nid, int n_min, int n_max,
13646f9291ceSJung-uk Kim                          unsigned long chtype, int mval)
136574664626SKris Kennaway {
1366f579bf8eSKris Kennaway     int i, ret = 0;
136774664626SKris Kennaway     MS_STATIC char buf[1024];
136874664626SKris Kennaway  start:
13696f9291ceSJung-uk Kim     if (!batch)
13706f9291ceSJung-uk Kim         BIO_printf(bio_err, "%s [%s]:", text, def);
137174664626SKris Kennaway     (void)BIO_flush(bio_err);
13726f9291ceSJung-uk Kim     if (value != NULL) {
1373ced566fdSJacques Vidrine         BUF_strlcpy(buf, value, sizeof buf);
1374ced566fdSJacques Vidrine         BUF_strlcat(buf, "\n", sizeof buf);
137574664626SKris Kennaway         BIO_printf(bio_err, "%s\n", value);
13766f9291ceSJung-uk Kim     } else {
137774664626SKris Kennaway         buf[0] = '\0';
13786f9291ceSJung-uk Kim         if (!batch) {
13796a599222SSimon L. B. Nielsen             if (!fgets(buf, sizeof buf, stdin))
13806a599222SSimon L. B. Nielsen                 return 0;
13816f9291ceSJung-uk Kim         } else {
13825c87c606SMark Murray             buf[0] = '\n';
13835c87c606SMark Murray             buf[1] = '\0';
13845c87c606SMark Murray         }
138574664626SKris Kennaway     }
138674664626SKris Kennaway 
13876f9291ceSJung-uk Kim     if (buf[0] == '\0')
13886f9291ceSJung-uk Kim         return (0);
13896f9291ceSJung-uk Kim     else if (buf[0] == '\n') {
139074664626SKris Kennaway         if ((def == NULL) || (def[0] == '\0'))
139174664626SKris Kennaway             return (1);
1392ced566fdSJacques Vidrine         BUF_strlcpy(buf, def, sizeof buf);
1393ced566fdSJacques Vidrine         BUF_strlcat(buf, "\n", sizeof buf);
13946f9291ceSJung-uk Kim     } else if ((buf[0] == '.') && (buf[1] == '\n'))
13956f9291ceSJung-uk Kim         return (1);
139674664626SKris Kennaway 
139774664626SKris Kennaway     i = strlen(buf);
13986f9291ceSJung-uk Kim     if (buf[i - 1] != '\n') {
139974664626SKris Kennaway         BIO_printf(bio_err, "weird input :-(\n");
140074664626SKris Kennaway         return (0);
140174664626SKris Kennaway     }
140274664626SKris Kennaway     buf[--i] = '\0';
1403f579bf8eSKris Kennaway #ifdef CHARSET_EBCDIC
1404f579bf8eSKris Kennaway     ebcdic2ascii(buf, buf, i);
1405f579bf8eSKris Kennaway #endif
14066f9291ceSJung-uk Kim     if (!req_check_len(i, n_min, n_max)) {
140794ad176cSJung-uk Kim         if (batch || value)
140894ad176cSJung-uk Kim             return 0;
140994ad176cSJung-uk Kim         goto start;
141094ad176cSJung-uk Kim     }
141194ad176cSJung-uk Kim 
14125c87c606SMark Murray     if (!X509_NAME_add_entry_by_NID(n, nid, chtype,
14136f9291ceSJung-uk Kim                                     (unsigned char *)buf, -1, -1, mval))
14146f9291ceSJung-uk Kim         goto err;
1415f579bf8eSKris Kennaway     ret = 1;
1416f579bf8eSKris Kennaway  err:
1417f579bf8eSKris Kennaway     return (ret);
141874664626SKris Kennaway }
141974664626SKris Kennaway 
14203b4e3dcbSSimon L. B. Nielsen static int add_attribute_object(X509_REQ *req, char *text, const char *def,
14213b4e3dcbSSimon L. B. Nielsen                                 char *value, int nid, int n_min,
14225c87c606SMark Murray                                 int n_max, unsigned long chtype)
1423f579bf8eSKris Kennaway {
1424f579bf8eSKris Kennaway     int i;
1425f579bf8eSKris Kennaway     static char buf[1024];
142674664626SKris Kennaway 
1427f579bf8eSKris Kennaway  start:
14286f9291ceSJung-uk Kim     if (!batch)
14296f9291ceSJung-uk Kim         BIO_printf(bio_err, "%s [%s]:", text, def);
1430f579bf8eSKris Kennaway     (void)BIO_flush(bio_err);
14316f9291ceSJung-uk Kim     if (value != NULL) {
1432ced566fdSJacques Vidrine         BUF_strlcpy(buf, value, sizeof buf);
1433ced566fdSJacques Vidrine         BUF_strlcat(buf, "\n", sizeof buf);
1434f579bf8eSKris Kennaway         BIO_printf(bio_err, "%s\n", value);
14356f9291ceSJung-uk Kim     } else {
1436f579bf8eSKris Kennaway         buf[0] = '\0';
14376f9291ceSJung-uk Kim         if (!batch) {
14386a599222SSimon L. B. Nielsen             if (!fgets(buf, sizeof buf, stdin))
14396a599222SSimon L. B. Nielsen                 return 0;
14406f9291ceSJung-uk Kim         } else {
14415c87c606SMark Murray             buf[0] = '\n';
14425c87c606SMark Murray             buf[1] = '\0';
14435c87c606SMark Murray         }
1444f579bf8eSKris Kennaway     }
144574664626SKris Kennaway 
14466f9291ceSJung-uk Kim     if (buf[0] == '\0')
14476f9291ceSJung-uk Kim         return (0);
14486f9291ceSJung-uk Kim     else if (buf[0] == '\n') {
1449f579bf8eSKris Kennaway         if ((def == NULL) || (def[0] == '\0'))
1450f579bf8eSKris Kennaway             return (1);
1451ced566fdSJacques Vidrine         BUF_strlcpy(buf, def, sizeof buf);
1452ced566fdSJacques Vidrine         BUF_strlcat(buf, "\n", sizeof buf);
14536f9291ceSJung-uk Kim     } else if ((buf[0] == '.') && (buf[1] == '\n'))
14546f9291ceSJung-uk Kim         return (1);
145574664626SKris Kennaway 
1456f579bf8eSKris Kennaway     i = strlen(buf);
14576f9291ceSJung-uk Kim     if (buf[i - 1] != '\n') {
1458f579bf8eSKris Kennaway         BIO_printf(bio_err, "weird input :-(\n");
1459f579bf8eSKris Kennaway         return (0);
1460f579bf8eSKris Kennaway     }
1461f579bf8eSKris Kennaway     buf[--i] = '\0';
1462ddd58736SKris Kennaway #ifdef CHARSET_EBCDIC
1463ddd58736SKris Kennaway     ebcdic2ascii(buf, buf, i);
1464ddd58736SKris Kennaway #endif
14656f9291ceSJung-uk Kim     if (!req_check_len(i, n_min, n_max)) {
146694ad176cSJung-uk Kim         if (batch || value)
146794ad176cSJung-uk Kim             return 0;
146894ad176cSJung-uk Kim         goto start;
146994ad176cSJung-uk Kim     }
1470f579bf8eSKris Kennaway 
14715c87c606SMark Murray     if (!X509_REQ_add1_attr_by_NID(req, nid, chtype,
1472f579bf8eSKris Kennaway                                    (unsigned char *)buf, -1)) {
1473f579bf8eSKris Kennaway         BIO_printf(bio_err, "Error adding attribute\n");
1474f579bf8eSKris Kennaway         ERR_print_errors(bio_err);
1475f579bf8eSKris Kennaway         goto err;
1476f579bf8eSKris Kennaway     }
1477f579bf8eSKris Kennaway 
147874664626SKris Kennaway     return (1);
147974664626SKris Kennaway  err:
148074664626SKris Kennaway     return (0);
148174664626SKris Kennaway }
148274664626SKris Kennaway 
14835c87c606SMark Murray static int req_check_len(int len, int n_min, int n_max)
148474664626SKris Kennaway {
14856f9291ceSJung-uk Kim     if ((n_min > 0) && (len < n_min)) {
14866f9291ceSJung-uk Kim         BIO_printf(bio_err,
14876f9291ceSJung-uk Kim                    "string is too short, it needs to be at least %d bytes long\n",
14886f9291ceSJung-uk Kim                    n_min);
148974664626SKris Kennaway         return (0);
149074664626SKris Kennaway     }
14916f9291ceSJung-uk Kim     if ((n_max >= 0) && (len > n_max)) {
14926f9291ceSJung-uk Kim         BIO_printf(bio_err,
14936f9291ceSJung-uk Kim                    "string is too long, it needs to be less than  %d bytes long\n",
14946f9291ceSJung-uk Kim                    n_max);
149574664626SKris Kennaway         return (0);
149674664626SKris Kennaway     }
149774664626SKris Kennaway     return (1);
149874664626SKris Kennaway }
149974664626SKris Kennaway 
150074664626SKris Kennaway /* Check if the end of a string matches 'end' */
15013b4e3dcbSSimon L. B. Nielsen static int check_end(const char *str, const char *end)
150274664626SKris Kennaway {
150374664626SKris Kennaway     int elen, slen;
15043b4e3dcbSSimon L. B. Nielsen     const char *tmp;
150574664626SKris Kennaway     elen = strlen(end);
150674664626SKris Kennaway     slen = strlen(str);
15076f9291ceSJung-uk Kim     if (elen > slen)
15086f9291ceSJung-uk Kim         return 1;
150974664626SKris Kennaway     tmp = str + slen - elen;
151074664626SKris Kennaway     return strcmp(tmp, end);
151174664626SKris Kennaway }
15121f13597dSJung-uk Kim 
15136f9291ceSJung-uk Kim static EVP_PKEY_CTX *set_keygen_ctx(BIO *err, const char *gstr,
15146f9291ceSJung-uk Kim                                     int *pkey_type, long *pkeylen,
15156f9291ceSJung-uk Kim                                     char **palgnam, ENGINE *keygen_engine)
15161f13597dSJung-uk Kim {
15171f13597dSJung-uk Kim     EVP_PKEY_CTX *gctx = NULL;
15181f13597dSJung-uk Kim     EVP_PKEY *param = NULL;
15191f13597dSJung-uk Kim     long keylen = -1;
15201f13597dSJung-uk Kim     BIO *pbio = NULL;
15211f13597dSJung-uk Kim     const char *paramfile = NULL;
15221f13597dSJung-uk Kim 
15236f9291ceSJung-uk Kim     if (gstr == NULL) {
15241f13597dSJung-uk Kim         *pkey_type = EVP_PKEY_RSA;
15251f13597dSJung-uk Kim         keylen = *pkeylen;
15266f9291ceSJung-uk Kim     } else if (gstr[0] >= '0' && gstr[0] <= '9') {
15271f13597dSJung-uk Kim         *pkey_type = EVP_PKEY_RSA;
15281f13597dSJung-uk Kim         keylen = atol(gstr);
15291f13597dSJung-uk Kim         *pkeylen = keylen;
15306f9291ceSJung-uk Kim     } else if (!strncmp(gstr, "param:", 6))
15311f13597dSJung-uk Kim         paramfile = gstr + 6;
15326f9291ceSJung-uk Kim     else {
15331f13597dSJung-uk Kim         const char *p = strchr(gstr, ':');
15341f13597dSJung-uk Kim         int len;
15351f13597dSJung-uk Kim         ENGINE *tmpeng;
15361f13597dSJung-uk Kim         const EVP_PKEY_ASN1_METHOD *ameth;
15371f13597dSJung-uk Kim 
15381f13597dSJung-uk Kim         if (p)
15391f13597dSJung-uk Kim             len = p - gstr;
15401f13597dSJung-uk Kim         else
15411f13597dSJung-uk Kim             len = strlen(gstr);
15426f9291ceSJung-uk Kim         /*
15436f9291ceSJung-uk Kim          * The lookup of a the string will cover all engines so keep a note
15446f9291ceSJung-uk Kim          * of the implementation.
15451f13597dSJung-uk Kim          */
15461f13597dSJung-uk Kim 
15471f13597dSJung-uk Kim         ameth = EVP_PKEY_asn1_find_str(&tmpeng, gstr, len);
15481f13597dSJung-uk Kim 
15496f9291ceSJung-uk Kim         if (!ameth) {
15501f13597dSJung-uk Kim             BIO_printf(err, "Unknown algorithm %.*s\n", len, gstr);
15511f13597dSJung-uk Kim             return NULL;
15521f13597dSJung-uk Kim         }
15531f13597dSJung-uk Kim 
15546f9291ceSJung-uk Kim         EVP_PKEY_asn1_get0_info(NULL, pkey_type, NULL, NULL, NULL, ameth);
15551f13597dSJung-uk Kim #ifndef OPENSSL_NO_ENGINE
15561f13597dSJung-uk Kim         if (tmpeng)
15571f13597dSJung-uk Kim             ENGINE_finish(tmpeng);
15581f13597dSJung-uk Kim #endif
15596f9291ceSJung-uk Kim         if (*pkey_type == EVP_PKEY_RSA) {
15606f9291ceSJung-uk Kim             if (p) {
15611f13597dSJung-uk Kim                 keylen = atol(p + 1);
15621f13597dSJung-uk Kim                 *pkeylen = keylen;
15636f9291ceSJung-uk Kim             } else
1564560ede85SJung-uk Kim                 keylen = *pkeylen;
15656f9291ceSJung-uk Kim         } else if (p)
15661f13597dSJung-uk Kim             paramfile = p + 1;
15671f13597dSJung-uk Kim     }
15681f13597dSJung-uk Kim 
15696f9291ceSJung-uk Kim     if (paramfile) {
15701f13597dSJung-uk Kim         pbio = BIO_new_file(paramfile, "r");
15716f9291ceSJung-uk Kim         if (!pbio) {
15726f9291ceSJung-uk Kim             BIO_printf(err, "Can't open parameter file %s\n", paramfile);
15731f13597dSJung-uk Kim             return NULL;
15741f13597dSJung-uk Kim         }
15751f13597dSJung-uk Kim         param = PEM_read_bio_Parameters(pbio, NULL);
15761f13597dSJung-uk Kim 
15776f9291ceSJung-uk Kim         if (!param) {
15781f13597dSJung-uk Kim             X509 *x;
15791f13597dSJung-uk Kim             (void)BIO_reset(pbio);
15801f13597dSJung-uk Kim             x = PEM_read_bio_X509(pbio, NULL, NULL, NULL);
15816f9291ceSJung-uk Kim             if (x) {
15821f13597dSJung-uk Kim                 param = X509_get_pubkey(x);
15831f13597dSJung-uk Kim                 X509_free(x);
15841f13597dSJung-uk Kim             }
15851f13597dSJung-uk Kim         }
15861f13597dSJung-uk Kim 
15871f13597dSJung-uk Kim         BIO_free(pbio);
15881f13597dSJung-uk Kim 
15896f9291ceSJung-uk Kim         if (!param) {
15906f9291ceSJung-uk Kim             BIO_printf(err, "Error reading parameter file %s\n", paramfile);
15911f13597dSJung-uk Kim             return NULL;
15921f13597dSJung-uk Kim         }
15931f13597dSJung-uk Kim         if (*pkey_type == -1)
15941f13597dSJung-uk Kim             *pkey_type = EVP_PKEY_id(param);
15956f9291ceSJung-uk Kim         else if (*pkey_type != EVP_PKEY_base_id(param)) {
15961f13597dSJung-uk Kim             BIO_printf(err, "Key Type does not match parameters\n");
15971f13597dSJung-uk Kim             EVP_PKEY_free(param);
15981f13597dSJung-uk Kim             return NULL;
15991f13597dSJung-uk Kim         }
16001f13597dSJung-uk Kim     }
16011f13597dSJung-uk Kim 
16026f9291ceSJung-uk Kim     if (palgnam) {
16031f13597dSJung-uk Kim         const EVP_PKEY_ASN1_METHOD *ameth;
16041f13597dSJung-uk Kim         ENGINE *tmpeng;
16051f13597dSJung-uk Kim         const char *anam;
16061f13597dSJung-uk Kim         ameth = EVP_PKEY_asn1_find(&tmpeng, *pkey_type);
16076f9291ceSJung-uk Kim         if (!ameth) {
16081f13597dSJung-uk Kim             BIO_puts(err, "Internal error: can't find key algorithm\n");
16091f13597dSJung-uk Kim             return NULL;
16101f13597dSJung-uk Kim         }
16111f13597dSJung-uk Kim         EVP_PKEY_asn1_get0_info(NULL, NULL, NULL, NULL, &anam, ameth);
16121f13597dSJung-uk Kim         *palgnam = BUF_strdup(anam);
16131f13597dSJung-uk Kim #ifndef OPENSSL_NO_ENGINE
16141f13597dSJung-uk Kim         if (tmpeng)
16151f13597dSJung-uk Kim             ENGINE_finish(tmpeng);
16161f13597dSJung-uk Kim #endif
16171f13597dSJung-uk Kim     }
16181f13597dSJung-uk Kim 
16196f9291ceSJung-uk Kim     if (param) {
16201f13597dSJung-uk Kim         gctx = EVP_PKEY_CTX_new(param, keygen_engine);
16211f13597dSJung-uk Kim         *pkeylen = EVP_PKEY_bits(param);
16221f13597dSJung-uk Kim         EVP_PKEY_free(param);
16236f9291ceSJung-uk Kim     } else
16241f13597dSJung-uk Kim         gctx = EVP_PKEY_CTX_new_id(*pkey_type, keygen_engine);
16251f13597dSJung-uk Kim 
16266f9291ceSJung-uk Kim     if (!gctx) {
16271f13597dSJung-uk Kim         BIO_puts(err, "Error allocating keygen context\n");
16281f13597dSJung-uk Kim         ERR_print_errors(err);
16291f13597dSJung-uk Kim         return NULL;
16301f13597dSJung-uk Kim     }
16311f13597dSJung-uk Kim 
16326f9291ceSJung-uk Kim     if (EVP_PKEY_keygen_init(gctx) <= 0) {
16331f13597dSJung-uk Kim         BIO_puts(err, "Error initializing keygen context\n");
16341f13597dSJung-uk Kim         ERR_print_errors(err);
16351f13597dSJung-uk Kim         return NULL;
16361f13597dSJung-uk Kim     }
16371f13597dSJung-uk Kim #ifndef OPENSSL_NO_RSA
16386f9291ceSJung-uk Kim     if ((*pkey_type == EVP_PKEY_RSA) && (keylen != -1)) {
16396f9291ceSJung-uk Kim         if (EVP_PKEY_CTX_set_rsa_keygen_bits(gctx, keylen) <= 0) {
16401f13597dSJung-uk Kim             BIO_puts(err, "Error setting RSA keysize\n");
16411f13597dSJung-uk Kim             ERR_print_errors(err);
16421f13597dSJung-uk Kim             EVP_PKEY_CTX_free(gctx);
16431f13597dSJung-uk Kim             return NULL;
16441f13597dSJung-uk Kim         }
16451f13597dSJung-uk Kim     }
16461f13597dSJung-uk Kim #endif
16471f13597dSJung-uk Kim 
16481f13597dSJung-uk Kim     return gctx;
16491f13597dSJung-uk Kim }
16501f13597dSJung-uk Kim 
16511f13597dSJung-uk Kim static int genpkey_cb(EVP_PKEY_CTX *ctx)
16521f13597dSJung-uk Kim {
16531f13597dSJung-uk Kim     char c = '*';
16541f13597dSJung-uk Kim     BIO *b = EVP_PKEY_CTX_get_app_data(ctx);
16551f13597dSJung-uk Kim     int p;
16561f13597dSJung-uk Kim     p = EVP_PKEY_CTX_get_keygen_info(ctx, 0);
16576f9291ceSJung-uk Kim     if (p == 0)
16586f9291ceSJung-uk Kim         c = '.';
16596f9291ceSJung-uk Kim     if (p == 1)
16606f9291ceSJung-uk Kim         c = '+';
16616f9291ceSJung-uk Kim     if (p == 2)
16626f9291ceSJung-uk Kim         c = '*';
16636f9291ceSJung-uk Kim     if (p == 3)
16646f9291ceSJung-uk Kim         c = '\n';
16651f13597dSJung-uk Kim     BIO_write(b, &c, 1);
16661f13597dSJung-uk Kim     (void)BIO_flush(b);
16671f13597dSJung-uk Kim #ifdef LINT
16681f13597dSJung-uk Kim     p = n;
16691f13597dSJung-uk Kim #endif
16701f13597dSJung-uk Kim     return 1;
16711f13597dSJung-uk Kim }
16721f13597dSJung-uk Kim 
16731f13597dSJung-uk Kim static int do_sign_init(BIO *err, EVP_MD_CTX *ctx, EVP_PKEY *pkey,
16741f13597dSJung-uk Kim                         const EVP_MD *md, STACK_OF(OPENSSL_STRING) *sigopts)
16751f13597dSJung-uk Kim {
16761f13597dSJung-uk Kim     EVP_PKEY_CTX *pkctx = NULL;
16771f13597dSJung-uk Kim     int i;
16781f13597dSJung-uk Kim     EVP_MD_CTX_init(ctx);
16791f13597dSJung-uk Kim     if (!EVP_DigestSignInit(ctx, &pkctx, md, NULL, pkey))
16801f13597dSJung-uk Kim         return 0;
16816f9291ceSJung-uk Kim     for (i = 0; i < sk_OPENSSL_STRING_num(sigopts); i++) {
16821f13597dSJung-uk Kim         char *sigopt = sk_OPENSSL_STRING_value(sigopts, i);
16836f9291ceSJung-uk Kim         if (pkey_ctrl_string(pkctx, sigopt) <= 0) {
16841f13597dSJung-uk Kim             BIO_printf(err, "parameter error \"%s\"\n", sigopt);
16851f13597dSJung-uk Kim             ERR_print_errors(bio_err);
16861f13597dSJung-uk Kim             return 0;
16871f13597dSJung-uk Kim         }
16881f13597dSJung-uk Kim     }
16891f13597dSJung-uk Kim     return 1;
16901f13597dSJung-uk Kim }
16911f13597dSJung-uk Kim 
16921f13597dSJung-uk Kim int do_X509_sign(BIO *err, X509 *x, EVP_PKEY *pkey, const EVP_MD *md,
16931f13597dSJung-uk Kim                  STACK_OF(OPENSSL_STRING) *sigopts)
16941f13597dSJung-uk Kim {
16951f13597dSJung-uk Kim     int rv;
16961f13597dSJung-uk Kim     EVP_MD_CTX mctx;
16971f13597dSJung-uk Kim     EVP_MD_CTX_init(&mctx);
16981f13597dSJung-uk Kim     rv = do_sign_init(err, &mctx, pkey, md, sigopts);
16991f13597dSJung-uk Kim     if (rv > 0)
17001f13597dSJung-uk Kim         rv = X509_sign_ctx(x, &mctx);
17011f13597dSJung-uk Kim     EVP_MD_CTX_cleanup(&mctx);
17021f13597dSJung-uk Kim     return rv > 0 ? 1 : 0;
17031f13597dSJung-uk Kim }
17041f13597dSJung-uk Kim 
17051f13597dSJung-uk Kim int do_X509_REQ_sign(BIO *err, X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md,
17061f13597dSJung-uk Kim                      STACK_OF(OPENSSL_STRING) *sigopts)
17071f13597dSJung-uk Kim {
17081f13597dSJung-uk Kim     int rv;
17091f13597dSJung-uk Kim     EVP_MD_CTX mctx;
17101f13597dSJung-uk Kim     EVP_MD_CTX_init(&mctx);
17111f13597dSJung-uk Kim     rv = do_sign_init(err, &mctx, pkey, md, sigopts);
17121f13597dSJung-uk Kim     if (rv > 0)
17131f13597dSJung-uk Kim         rv = X509_REQ_sign_ctx(x, &mctx);
17141f13597dSJung-uk Kim     EVP_MD_CTX_cleanup(&mctx);
17151f13597dSJung-uk Kim     return rv > 0 ? 1 : 0;
17161f13597dSJung-uk Kim }
17171f13597dSJung-uk Kim 
17181f13597dSJung-uk Kim int do_X509_CRL_sign(BIO *err, X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md,
17191f13597dSJung-uk Kim                      STACK_OF(OPENSSL_STRING) *sigopts)
17201f13597dSJung-uk Kim {
17211f13597dSJung-uk Kim     int rv;
17221f13597dSJung-uk Kim     EVP_MD_CTX mctx;
17231f13597dSJung-uk Kim     EVP_MD_CTX_init(&mctx);
17241f13597dSJung-uk Kim     rv = do_sign_init(err, &mctx, pkey, md, sigopts);
17251f13597dSJung-uk Kim     if (rv > 0)
17261f13597dSJung-uk Kim         rv = X509_CRL_sign_ctx(x, &mctx);
17271f13597dSJung-uk Kim     EVP_MD_CTX_cleanup(&mctx);
17281f13597dSJung-uk Kim     return rv > 0 ? 1 : 0;
17291f13597dSJung-uk Kim }
1730