[BACK]Return to req.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / openssl

Annotation of src/usr.bin/openssl/req.c, Revision 1.18

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