Blame apps/ca.c

Packit Service 084de1
/*
Packit Service 084de1
 * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
Packit Service 084de1
 *
Packit Service 084de1
 * Licensed under the OpenSSL license (the "License").  You may not use
Packit Service 084de1
 * this file except in compliance with the License.  You can obtain a copy
Packit Service 084de1
 * in the file LICENSE in the source distribution or at
Packit Service 084de1
 * https://www.openssl.org/source/license.html
Packit Service 084de1
 */
Packit Service 084de1
#include <stdio.h>
Packit Service 084de1
#include <stdlib.h>
Packit Service 084de1
#include <string.h>
Packit Service 084de1
#include <ctype.h>
Packit Service 084de1
#include <sys/types.h>
Packit Service 084de1
#include <openssl/conf.h>
Packit Service 084de1
#include <openssl/bio.h>
Packit Service 084de1
#include <openssl/err.h>
Packit Service 084de1
#include <openssl/bn.h>
Packit Service 084de1
#include <openssl/txt_db.h>
Packit Service 084de1
#include <openssl/evp.h>
Packit Service 084de1
#include <openssl/x509.h>
Packit Service 084de1
#include <openssl/x509v3.h>
Packit Service 084de1
#include <openssl/objects.h>
Packit Service 084de1
#include <openssl/ocsp.h>
Packit Service 084de1
#include <openssl/pem.h>
Packit Service 084de1
Packit Service 084de1
#ifndef W_OK
Packit Service 084de1
# ifdef OPENSSL_SYS_VMS
Packit Service 084de1
#  include <unistd.h>
Packit Service 084de1
# elif !defined(OPENSSL_SYS_VXWORKS) && !defined(OPENSSL_SYS_WINDOWS)
Packit Service 084de1
#  include <sys/file.h>
Packit Service 084de1
# endif
Packit Service 084de1
#endif
Packit Service 084de1
Packit Service 084de1
#include "apps.h"
Packit Service 084de1
#include "progs.h"
Packit Service 084de1
Packit Service 084de1
#ifndef W_OK
Packit Service 084de1
# define F_OK 0
Packit Service 084de1
# define W_OK 2
Packit Service 084de1
# define R_OK 4
Packit Service 084de1
#endif
Packit Service 084de1
Packit Service 084de1
#ifndef PATH_MAX
Packit Service 084de1
# define PATH_MAX 4096
Packit Service 084de1
#endif
Packit Service 084de1
Packit Service 084de1
#define BASE_SECTION            "ca"
Packit Service 084de1
Packit Service 084de1
#define ENV_DEFAULT_CA          "default_ca"
Packit Service 084de1
Packit Service 084de1
#define STRING_MASK             "string_mask"
Packit Service 084de1
#define UTF8_IN                 "utf8"
Packit Service 084de1
Packit Service 084de1
#define ENV_NEW_CERTS_DIR       "new_certs_dir"
Packit Service 084de1
#define ENV_CERTIFICATE         "certificate"
Packit Service 084de1
#define ENV_SERIAL              "serial"
Packit Service 084de1
#define ENV_RAND_SERIAL         "rand_serial"
Packit Service 084de1
#define ENV_CRLNUMBER           "crlnumber"
Packit Service 084de1
#define ENV_PRIVATE_KEY         "private_key"
Packit Service 084de1
#define ENV_DEFAULT_DAYS        "default_days"
Packit Service 084de1
#define ENV_DEFAULT_STARTDATE   "default_startdate"
Packit Service 084de1
#define ENV_DEFAULT_ENDDATE     "default_enddate"
Packit Service 084de1
#define ENV_DEFAULT_CRL_DAYS    "default_crl_days"
Packit Service 084de1
#define ENV_DEFAULT_CRL_HOURS   "default_crl_hours"
Packit Service 084de1
#define ENV_DEFAULT_MD          "default_md"
Packit Service 084de1
#define ENV_DEFAULT_EMAIL_DN    "email_in_dn"
Packit Service 084de1
#define ENV_PRESERVE            "preserve"
Packit Service 084de1
#define ENV_POLICY              "policy"
Packit Service 084de1
#define ENV_EXTENSIONS          "x509_extensions"
Packit Service 084de1
#define ENV_CRLEXT              "crl_extensions"
Packit Service 084de1
#define ENV_MSIE_HACK           "msie_hack"
Packit Service 084de1
#define ENV_NAMEOPT             "name_opt"
Packit Service 084de1
#define ENV_CERTOPT             "cert_opt"
Packit Service 084de1
#define ENV_EXTCOPY             "copy_extensions"
Packit Service 084de1
#define ENV_UNIQUE_SUBJECT      "unique_subject"
Packit Service 084de1
Packit Service 084de1
#define ENV_DATABASE            "database"
Packit Service 084de1
Packit Service 084de1
/* Additional revocation information types */
Packit Service 084de1
typedef enum {
Packit Service 084de1
    REV_VALID             = -1, /* Valid (not-revoked) status */
Packit Service 084de1
    REV_NONE              = 0, /* No additional information */
Packit Service 084de1
    REV_CRL_REASON        = 1, /* Value is CRL reason code */
Packit Service 084de1
    REV_HOLD              = 2, /* Value is hold instruction */
Packit Service 084de1
    REV_KEY_COMPROMISE    = 3, /* Value is cert key compromise time */
Packit Service 084de1
    REV_CA_COMPROMISE     = 4  /* Value is CA key compromise time */
Packit Service 084de1
} REVINFO_TYPE;
Packit Service 084de1
Packit Service 084de1
static char *lookup_conf(const CONF *conf, const char *group, const char *tag);
Packit Service 084de1
Packit Service 084de1
static int certify(X509 **xret, const char *infile, EVP_PKEY *pkey, X509 *x509,
Packit Service 084de1
                   const EVP_MD *dgst, STACK_OF(OPENSSL_STRING) *sigopts,
Packit Service 084de1
                   STACK_OF(CONF_VALUE) *policy, CA_DB *db,
Packit Service 084de1
                   BIGNUM *serial, const char *subj, unsigned long chtype,
Packit Service 084de1
                   int multirdn, int email_dn, const char *startdate,
Packit Service 084de1
                   const char *enddate,
Packit Service 084de1
                   long days, int batch, const char *ext_sect, CONF *conf,
Packit Service 084de1
                   int verbose, unsigned long certopt, unsigned long nameopt,
Packit Service 084de1
                   int default_op, int ext_copy, int selfsign);
Packit Service 084de1
static int certify_cert(X509 **xret, const char *infile, EVP_PKEY *pkey, X509 *x509,
Packit Service 084de1
                        const EVP_MD *dgst, STACK_OF(OPENSSL_STRING) *sigopts,
Packit Service 084de1
                        STACK_OF(CONF_VALUE) *policy, CA_DB *db,
Packit Service 084de1
                        BIGNUM *serial, const char *subj, unsigned long chtype,
Packit Service 084de1
                        int multirdn, int email_dn, const char *startdate,
Packit Service 084de1
                        const char *enddate, long days, int batch, const char *ext_sect,
Packit Service 084de1
                        CONF *conf, int verbose, unsigned long certopt,
Packit Service 084de1
                        unsigned long nameopt, int default_op, int ext_copy);
Packit Service 084de1
static int certify_spkac(X509 **xret, const char *infile, EVP_PKEY *pkey,
Packit Service 084de1
                         X509 *x509, const EVP_MD *dgst,
Packit Service 084de1
                         STACK_OF(OPENSSL_STRING) *sigopts,
Packit Service 084de1
                         STACK_OF(CONF_VALUE) *policy, CA_DB *db,
Packit Service 084de1
                         BIGNUM *serial, const char *subj, unsigned long chtype,
Packit Service 084de1
                         int multirdn, int email_dn, const char *startdate,
Packit Service 084de1
                         const char *enddate, long days, const char *ext_sect, CONF *conf,
Packit Service 084de1
                         int verbose, unsigned long certopt,
Packit Service 084de1
                         unsigned long nameopt, int default_op, int ext_copy);
Packit Service 084de1
static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509,
Packit Service 084de1
                   const EVP_MD *dgst, STACK_OF(OPENSSL_STRING) *sigopts,
Packit Service 084de1
                   STACK_OF(CONF_VALUE) *policy, CA_DB *db, BIGNUM *serial,
Packit Service 084de1
                   const char *subj, unsigned long chtype, int multirdn,
Packit Service 084de1
                   int email_dn, const char *startdate, const char *enddate, long days,
Packit Service 084de1
                   int batch, int verbose, X509_REQ *req, const char *ext_sect,
Packit Service 084de1
                   CONF *conf, unsigned long certopt, unsigned long nameopt,
Packit Service 084de1
                   int default_op, int ext_copy, int selfsign);
Packit Service 084de1
static int get_certificate_status(const char *ser_status, CA_DB *db);
Packit Service 084de1
static int do_updatedb(CA_DB *db);
Packit Service 084de1
static int check_time_format(const char *str);
Packit Service 084de1
static int do_revoke(X509 *x509, CA_DB *db, REVINFO_TYPE rev_type,
Packit Service 084de1
                     const char *extval);
Packit Service 084de1
static char *make_revocation_str(REVINFO_TYPE rev_type, const char *rev_arg);
Packit Service 084de1
static int make_revoked(X509_REVOKED *rev, const char *str);
Packit Service 084de1
static int old_entry_print(const ASN1_OBJECT *obj, const ASN1_STRING *str);
Packit Service 084de1
static void write_new_certificate(BIO *bp, X509 *x, int output_der, int notext);
Packit Service 084de1
Packit Service 084de1
static CONF *extconf = NULL;
Packit Service 084de1
static int preserve = 0;
Packit Service 084de1
static int msie_hack = 0;
Packit Service 084de1
Packit Service 084de1
typedef enum OPTION_choice {
Packit Service 084de1
    OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
Packit Service 084de1
    OPT_ENGINE, OPT_VERBOSE, OPT_CONFIG, OPT_NAME, OPT_SUBJ, OPT_UTF8,
Packit Service 084de1
    OPT_CREATE_SERIAL, OPT_MULTIVALUE_RDN, OPT_STARTDATE, OPT_ENDDATE,
Packit Service 084de1
    OPT_DAYS, OPT_MD, OPT_POLICY, OPT_KEYFILE, OPT_KEYFORM, OPT_PASSIN,
Packit Service 084de1
    OPT_KEY, OPT_CERT, OPT_SELFSIGN, OPT_IN, OPT_OUT, OPT_OUTDIR,
Packit Service 084de1
    OPT_SIGOPT, OPT_NOTEXT, OPT_BATCH, OPT_PRESERVEDN, OPT_NOEMAILDN,
Packit Service 084de1
    OPT_GENCRL, OPT_MSIE_HACK, OPT_CRLDAYS, OPT_CRLHOURS, OPT_CRLSEC,
Packit Service 084de1
    OPT_INFILES, OPT_SS_CERT, OPT_SPKAC, OPT_REVOKE, OPT_VALID,
Packit Service 084de1
    OPT_EXTENSIONS, OPT_EXTFILE, OPT_STATUS, OPT_UPDATEDB, OPT_CRLEXTS,
Packit Service 084de1
    OPT_RAND_SERIAL,
Packit Service 084de1
    OPT_R_ENUM,
Packit Service 084de1
    /* Do not change the order here; see related case statements below */
Packit Service 084de1
    OPT_CRL_REASON, OPT_CRL_HOLD, OPT_CRL_COMPROMISE, OPT_CRL_CA_COMPROMISE
Packit Service 084de1
} OPTION_CHOICE;
Packit Service 084de1
Packit Service 084de1
const OPTIONS ca_options[] = {
Packit Service 084de1
    {"help", OPT_HELP, '-', "Display this summary"},
Packit Service 084de1
    {"verbose", OPT_VERBOSE, '-', "Verbose output during processing"},
Packit Service 084de1
    {"config", OPT_CONFIG, 's', "A config file"},
Packit Service 084de1
    {"name", OPT_NAME, 's', "The particular CA definition to use"},
Packit Service 084de1
    {"subj", OPT_SUBJ, 's', "Use arg instead of request's subject"},
Packit Service 084de1
    {"utf8", OPT_UTF8, '-', "Input characters are UTF8 (default ASCII)"},
Packit Service 084de1
    {"create_serial", OPT_CREATE_SERIAL, '-',
Packit Service 084de1
     "If reading serial fails, create a new random serial"},
Packit Service 084de1
    {"rand_serial", OPT_RAND_SERIAL, '-',
Packit Service 084de1
     "Always create a random serial; do not store it"},
Packit Service 084de1
    {"multivalue-rdn", OPT_MULTIVALUE_RDN, '-',
Packit Service 084de1
     "Enable support for multivalued RDNs"},
Packit Service 084de1
    {"startdate", OPT_STARTDATE, 's', "Cert notBefore, YYMMDDHHMMSSZ"},
Packit Service 084de1
    {"enddate", OPT_ENDDATE, 's',
Packit Service 084de1
     "YYMMDDHHMMSSZ cert notAfter (overrides -days)"},
Packit Service 084de1
    {"days", OPT_DAYS, 'p', "Number of days to certify the cert for"},
Packit Service 084de1
    {"md", OPT_MD, 's', "md to use; see openssl help for list"},
Packit Service 084de1
    {"policy", OPT_POLICY, 's', "The CA 'policy' to support"},
Packit Service 084de1
    {"keyfile", OPT_KEYFILE, 's', "Private key"},
Packit Service 084de1
    {"keyform", OPT_KEYFORM, 'f', "Private key file format (PEM or ENGINE)"},
Packit Service 084de1
    {"passin", OPT_PASSIN, 's', "Input file pass phrase source"},
Packit Service 084de1
    {"key", OPT_KEY, 's', "Key to decode the private key if it is encrypted"},
Packit Service 084de1
    {"cert", OPT_CERT, '<', "The CA cert"},
Packit Service 084de1
    {"selfsign", OPT_SELFSIGN, '-',
Packit Service 084de1
     "Sign a cert with the key associated with it"},
Packit Service 084de1
    {"in", OPT_IN, '<', "The input PEM encoded cert request(s)"},
Packit Service 084de1
    {"out", OPT_OUT, '>', "Where to put the output file(s)"},
Packit Service 084de1
    {"outdir", OPT_OUTDIR, '/', "Where to put output cert"},
Packit Service 084de1
    {"sigopt", OPT_SIGOPT, 's', "Signature parameter in n:v form"},
Packit Service 084de1
    {"notext", OPT_NOTEXT, '-', "Do not print the generated certificate"},
Packit Service 084de1
    {"batch", OPT_BATCH, '-', "Don't ask questions"},
Packit Service 084de1
    {"preserveDN", OPT_PRESERVEDN, '-', "Don't re-order the DN"},
Packit Service 084de1
    {"noemailDN", OPT_NOEMAILDN, '-', "Don't add the EMAIL field to the DN"},
Packit Service 084de1
    {"gencrl", OPT_GENCRL, '-', "Generate a new CRL"},
Packit Service 084de1
    {"msie_hack", OPT_MSIE_HACK, '-',
Packit Service 084de1
     "msie modifications to handle all those universal strings"},
Packit Service 084de1
    {"crldays", OPT_CRLDAYS, 'p', "Days until the next CRL is due"},
Packit Service 084de1
    {"crlhours", OPT_CRLHOURS, 'p', "Hours until the next CRL is due"},
Packit Service 084de1
    {"crlsec", OPT_CRLSEC, 'p', "Seconds until the next CRL is due"},
Packit Service 084de1
    {"infiles", OPT_INFILES, '-', "The last argument, requests to process"},
Packit Service 084de1
    {"ss_cert", OPT_SS_CERT, '<', "File contains a self signed cert to sign"},
Packit Service 084de1
    {"spkac", OPT_SPKAC, '<',
Packit Service 084de1
     "File contains DN and signed public key and challenge"},
Packit Service 084de1
    {"revoke", OPT_REVOKE, '<', "Revoke a cert (given in file)"},
Packit Service 084de1
    {"valid", OPT_VALID, 's',
Packit Service 084de1
     "Add a Valid(not-revoked) DB entry about a cert (given in file)"},
Packit Service 084de1
    {"extensions", OPT_EXTENSIONS, 's',
Packit Service 084de1
     "Extension section (override value in config file)"},
Packit Service 084de1
    {"extfile", OPT_EXTFILE, '<',
Packit Service 084de1
     "Configuration file with X509v3 extensions to add"},
Packit Service 084de1
    {"status", OPT_STATUS, 's', "Shows cert status given the serial number"},
Packit Service 084de1
    {"updatedb", OPT_UPDATEDB, '-', "Updates db for expired cert"},
Packit Service 084de1
    {"crlexts", OPT_CRLEXTS, 's',
Packit Service 084de1
     "CRL extension section (override value in config file)"},
Packit Service 084de1
    {"crl_reason", OPT_CRL_REASON, 's', "revocation reason"},
Packit Service 084de1
    {"crl_hold", OPT_CRL_HOLD, 's',
Packit Service 084de1
     "the hold instruction, an OID. Sets revocation reason to certificateHold"},
Packit Service 084de1
    {"crl_compromise", OPT_CRL_COMPROMISE, 's',
Packit Service 084de1
     "sets compromise time to val and the revocation reason to keyCompromise"},
Packit Service 084de1
    {"crl_CA_compromise", OPT_CRL_CA_COMPROMISE, 's',
Packit Service 084de1
     "sets compromise time to val and the revocation reason to CACompromise"},
Packit Service 084de1
    OPT_R_OPTIONS,
Packit Service 084de1
#ifndef OPENSSL_NO_ENGINE
Packit Service 084de1
    {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"},
Packit Service 084de1
#endif
Packit Service 084de1
    {NULL}
Packit Service 084de1
};
Packit Service 084de1
Packit Service 084de1
int ca_main(int argc, char **argv)
Packit Service 084de1
{
Packit Service 084de1
    CONF *conf = NULL;
Packit Service 084de1
    ENGINE *e = NULL;
Packit Service 084de1
    BIGNUM *crlnumber = NULL, *serial = NULL;
Packit Service 084de1
    EVP_PKEY *pkey = NULL;
Packit Service 084de1
    BIO *in = NULL, *out = NULL, *Sout = NULL;
Packit Service 084de1
    ASN1_INTEGER *tmpser;
Packit Service 084de1
    ASN1_TIME *tmptm;
Packit Service 084de1
    CA_DB *db = NULL;
Packit Service 084de1
    DB_ATTR db_attr;
Packit Service 084de1
    STACK_OF(CONF_VALUE) *attribs = NULL;
Packit Service 084de1
    STACK_OF(OPENSSL_STRING) *sigopts = NULL;
Packit Service 084de1
    STACK_OF(X509) *cert_sk = NULL;
Packit Service 084de1
    X509_CRL *crl = NULL;
Packit Service 084de1
    const EVP_MD *dgst = NULL;
Packit Service 084de1
    char *configfile = default_config_file, *section = NULL;
Packit Service 084de1
    char *md = NULL, *policy = NULL, *keyfile = NULL;
Packit Service 084de1
    char *certfile = NULL, *crl_ext = NULL, *crlnumberfile = NULL, *key = NULL;
Packit Service 084de1
    const char *infile = NULL, *spkac_file = NULL, *ss_cert_file = NULL;
Packit Service 084de1
    const char *extensions = NULL, *extfile = NULL, *passinarg = NULL;
Packit Service 084de1
    char *outdir = NULL, *outfile = NULL, *rev_arg = NULL, *ser_status = NULL;
Packit Service 084de1
    const char *serialfile = NULL, *subj = NULL;
Packit Service 084de1
    char *prog, *startdate = NULL, *enddate = NULL;
Packit Service 084de1
    char *dbfile = NULL, *f;
Packit Service 084de1
    char new_cert[PATH_MAX];
Packit Service 084de1
    char tmp[10 + 1] = "\0";
Packit Service 084de1
    char *const *pp;
Packit Service 084de1
    const char *p;
Packit Service 084de1
    size_t outdirlen = 0;
Packit Service 084de1
    int create_ser = 0, free_key = 0, total = 0, total_done = 0;
Packit Service 084de1
    int batch = 0, default_op = 1, doupdatedb = 0, ext_copy = EXT_COPY_NONE;
Packit Service 084de1
    int keyformat = FORMAT_PEM, multirdn = 0, notext = 0, output_der = 0;
Packit Service 084de1
    int ret = 1, email_dn = 1, req = 0, verbose = 0, gencrl = 0, dorevoke = 0;
Packit Service 084de1
    int rand_ser = 0, i, j, selfsign = 0, def_nid, def_ret;
Packit Service 084de1
    long crldays = 0, crlhours = 0, crlsec = 0, days = 0;
Packit Service 084de1
    unsigned long chtype = MBSTRING_ASC, certopt = 0;
Packit Service 084de1
    X509 *x509 = NULL, *x509p = NULL, *x = NULL;
Packit Service 084de1
    REVINFO_TYPE rev_type = REV_NONE;
Packit Service 084de1
    X509_REVOKED *r = NULL;
Packit Service 084de1
    OPTION_CHOICE o;
Packit Service 084de1
Packit Service 084de1
    prog = opt_init(argc, argv, ca_options);
Packit Service 084de1
    while ((o = opt_next()) != OPT_EOF) {
Packit Service 084de1
        switch (o) {
Packit Service 084de1
        case OPT_EOF:
Packit Service 084de1
        case OPT_ERR:
Packit Service 084de1
opthelp:
Packit Service 084de1
            BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
Packit Service 084de1
            goto end;
Packit Service 084de1
        case OPT_HELP:
Packit Service 084de1
            opt_help(ca_options);
Packit Service 084de1
            ret = 0;
Packit Service 084de1
            goto end;
Packit Service 084de1
        case OPT_IN:
Packit Service 084de1
            req = 1;
Packit Service 084de1
            infile = opt_arg();
Packit Service 084de1
            break;
Packit Service 084de1
        case OPT_OUT:
Packit Service 084de1
            outfile = opt_arg();
Packit Service 084de1
            break;
Packit Service 084de1
        case OPT_VERBOSE:
Packit Service 084de1
            verbose = 1;
Packit Service 084de1
            break;
Packit Service 084de1
        case OPT_CONFIG:
Packit Service 084de1
            configfile = opt_arg();
Packit Service 084de1
            break;
Packit Service 084de1
        case OPT_NAME:
Packit Service 084de1
            section = opt_arg();
Packit Service 084de1
            break;
Packit Service 084de1
        case OPT_SUBJ:
Packit Service 084de1
            subj = opt_arg();
Packit Service 084de1
            /* preserve=1; */
Packit Service 084de1
            break;
Packit Service 084de1
        case OPT_UTF8:
Packit Service 084de1
            chtype = MBSTRING_UTF8;
Packit Service 084de1
            break;
Packit Service 084de1
        case OPT_RAND_SERIAL:
Packit Service 084de1
            rand_ser = 1;
Packit Service 084de1
            break;
Packit Service 084de1
        case OPT_CREATE_SERIAL:
Packit Service 084de1
            create_ser = 1;
Packit Service 084de1
            break;
Packit Service 084de1
        case OPT_MULTIVALUE_RDN:
Packit Service 084de1
            multirdn = 1;
Packit Service 084de1
            break;
Packit Service 084de1
        case OPT_STARTDATE:
Packit Service 084de1
            startdate = opt_arg();
Packit Service 084de1
            break;
Packit Service 084de1
        case OPT_ENDDATE:
Packit Service 084de1
            enddate = opt_arg();
Packit Service 084de1
            break;
Packit Service 084de1
        case OPT_DAYS:
Packit Service 084de1
            days = atoi(opt_arg());
Packit Service 084de1
            break;
Packit Service 084de1
        case OPT_MD:
Packit Service 084de1
            md = opt_arg();
Packit Service 084de1
            break;
Packit Service 084de1
        case OPT_POLICY:
Packit Service 084de1
            policy = opt_arg();
Packit Service 084de1
            break;
Packit Service 084de1
        case OPT_KEYFILE:
Packit Service 084de1
            keyfile = opt_arg();
Packit Service 084de1
            break;
Packit Service 084de1
        case OPT_KEYFORM:
Packit Service 084de1
            if (!opt_format(opt_arg(), OPT_FMT_ANY, &keyformat))
Packit Service 084de1
                goto opthelp;
Packit Service 084de1
            break;
Packit Service 084de1
        case OPT_PASSIN:
Packit Service 084de1
            passinarg = opt_arg();
Packit Service 084de1
            break;
Packit Service 084de1
        case OPT_R_CASES:
Packit Service 084de1
            if (!opt_rand(o))
Packit Service 084de1
                goto end;
Packit Service 084de1
            break;
Packit Service 084de1
        case OPT_KEY:
Packit Service 084de1
            key = opt_arg();
Packit Service 084de1
            break;
Packit Service 084de1
        case OPT_CERT:
Packit Service 084de1
            certfile = opt_arg();
Packit Service 084de1
            break;
Packit Service 084de1
        case OPT_SELFSIGN:
Packit Service 084de1
            selfsign = 1;
Packit Service 084de1
            break;
Packit Service 084de1
        case OPT_OUTDIR:
Packit Service 084de1
            outdir = opt_arg();
Packit Service 084de1
            break;
Packit Service 084de1
        case OPT_SIGOPT:
Packit Service 084de1
            if (sigopts == NULL)
Packit Service 084de1
                sigopts = sk_OPENSSL_STRING_new_null();
Packit Service 084de1
            if (sigopts == NULL || !sk_OPENSSL_STRING_push(sigopts, opt_arg()))
Packit Service 084de1
                goto end;
Packit Service 084de1
            break;
Packit Service 084de1
        case OPT_NOTEXT:
Packit Service 084de1
            notext = 1;
Packit Service 084de1
            break;
Packit Service 084de1
        case OPT_BATCH:
Packit Service 084de1
            batch = 1;
Packit Service 084de1
            break;
Packit Service 084de1
        case OPT_PRESERVEDN:
Packit Service 084de1
            preserve = 1;
Packit Service 084de1
            break;
Packit Service 084de1
        case OPT_NOEMAILDN:
Packit Service 084de1
            email_dn = 0;
Packit Service 084de1
            break;
Packit Service 084de1
        case OPT_GENCRL:
Packit Service 084de1
            gencrl = 1;
Packit Service 084de1
            break;
Packit Service 084de1
        case OPT_MSIE_HACK:
Packit Service 084de1
            msie_hack = 1;
Packit Service 084de1
            break;
Packit Service 084de1
        case OPT_CRLDAYS:
Packit Service 084de1
            crldays = atol(opt_arg());
Packit Service 084de1
            break;
Packit Service 084de1
        case OPT_CRLHOURS:
Packit Service 084de1
            crlhours = atol(opt_arg());
Packit Service 084de1
            break;
Packit Service 084de1
        case OPT_CRLSEC:
Packit Service 084de1
            crlsec = atol(opt_arg());
Packit Service 084de1
            break;
Packit Service 084de1
        case OPT_INFILES:
Packit Service 084de1
            req = 1;
Packit Service 084de1
            goto end_of_options;
Packit Service 084de1
        case OPT_SS_CERT:
Packit Service 084de1
            ss_cert_file = opt_arg();
Packit Service 084de1
            req = 1;
Packit Service 084de1
            break;
Packit Service 084de1
        case OPT_SPKAC:
Packit Service 084de1
            spkac_file = opt_arg();
Packit Service 084de1
            req = 1;
Packit Service 084de1
            break;
Packit Service 084de1
        case OPT_REVOKE:
Packit Service 084de1
            infile = opt_arg();
Packit Service 084de1
            dorevoke = 1;
Packit Service 084de1
            break;
Packit Service 084de1
        case OPT_VALID:
Packit Service 084de1
            infile = opt_arg();
Packit Service 084de1
            dorevoke = 2;
Packit Service 084de1
            break;
Packit Service 084de1
        case OPT_EXTENSIONS:
Packit Service 084de1
            extensions = opt_arg();
Packit Service 084de1
            break;
Packit Service 084de1
        case OPT_EXTFILE:
Packit Service 084de1
            extfile = opt_arg();
Packit Service 084de1
            break;
Packit Service 084de1
        case OPT_STATUS:
Packit Service 084de1
            ser_status = opt_arg();
Packit Service 084de1
            break;
Packit Service 084de1
        case OPT_UPDATEDB:
Packit Service 084de1
            doupdatedb = 1;
Packit Service 084de1
            break;
Packit Service 084de1
        case OPT_CRLEXTS:
Packit Service 084de1
            crl_ext = opt_arg();
Packit Service 084de1
            break;
Packit Service 084de1
        case OPT_CRL_REASON:   /* := REV_CRL_REASON */
Packit Service 084de1
        case OPT_CRL_HOLD:
Packit Service 084de1
        case OPT_CRL_COMPROMISE:
Packit Service 084de1
        case OPT_CRL_CA_COMPROMISE:
Packit Service 084de1
            rev_arg = opt_arg();
Packit Service 084de1
            rev_type = (o - OPT_CRL_REASON) + REV_CRL_REASON;
Packit Service 084de1
            break;
Packit Service 084de1
        case OPT_ENGINE:
Packit Service 084de1
            e = setup_engine(opt_arg(), 0);
Packit Service 084de1
            break;
Packit Service 084de1
        }
Packit Service 084de1
    }
Packit Service 084de1
end_of_options:
Packit Service 084de1
    argc = opt_num_rest();
Packit Service 084de1
    argv = opt_rest();
Packit Service 084de1
Packit Service 084de1
    BIO_printf(bio_err, "Using configuration from %s\n", configfile);
Packit Service 084de1
Packit Service 084de1
    if ((conf = app_load_config(configfile)) == NULL)
Packit Service 084de1
        goto end;
Packit Service 084de1
    if (configfile != default_config_file && !app_load_modules(conf))
Packit Service 084de1
        goto end;
Packit Service 084de1
Packit Service 084de1
    /* Lets get the config section we are using */
Packit Service 084de1
    if (section == NULL
Packit Service 084de1
        && (section = lookup_conf(conf, BASE_SECTION, ENV_DEFAULT_CA)) == NULL)
Packit Service 084de1
        goto end;
Packit Service 084de1
Packit Service 084de1
    p = NCONF_get_string(conf, NULL, "oid_file");
Packit Service 084de1
    if (p == NULL)
Packit Service 084de1
        ERR_clear_error();
Packit Service 084de1
    if (p != NULL) {
Packit Service 084de1
        BIO *oid_bio = BIO_new_file(p, "r");
Packit Service 084de1
Packit Service 084de1
        if (oid_bio == NULL) {
Packit Service 084de1
            ERR_clear_error();
Packit Service 084de1
        } else {
Packit Service 084de1
            OBJ_create_objects(oid_bio);
Packit Service 084de1
            BIO_free(oid_bio);
Packit Service 084de1
        }
Packit Service 084de1
    }
Packit Service 084de1
    if (!add_oid_section(conf)) {
Packit Service 084de1
        ERR_print_errors(bio_err);
Packit Service 084de1
        goto end;
Packit Service 084de1
    }
Packit Service 084de1
Packit Service 084de1
    app_RAND_load_conf(conf, BASE_SECTION);
Packit Service 084de1
Packit Service 084de1
    f = NCONF_get_string(conf, section, STRING_MASK);
Packit Service 084de1
    if (f == NULL)
Packit Service 084de1
        ERR_clear_error();
Packit Service 084de1
Packit Service 084de1
    if (f != NULL && !ASN1_STRING_set_default_mask_asc(f)) {
Packit Service 084de1
        BIO_printf(bio_err, "Invalid global string mask setting %s\n", f);
Packit Service 084de1
        goto end;
Packit Service 084de1
    }
Packit Service 084de1
Packit Service 084de1
    if (chtype != MBSTRING_UTF8) {
Packit Service 084de1
        f = NCONF_get_string(conf, section, UTF8_IN);
Packit Service 084de1
        if (f == NULL)
Packit Service 084de1
            ERR_clear_error();
Packit Service 084de1
        else if (strcmp(f, "yes") == 0)
Packit Service 084de1
            chtype = MBSTRING_UTF8;
Packit Service 084de1
    }
Packit Service 084de1
Packit Service 084de1
    db_attr.unique_subject = 1;
Packit Service 084de1
    p = NCONF_get_string(conf, section, ENV_UNIQUE_SUBJECT);
Packit Service 084de1
    if (p != NULL)
Packit Service 084de1
        db_attr.unique_subject = parse_yesno(p, 1);
Packit Service 084de1
    else
Packit Service 084de1
        ERR_clear_error();
Packit Service 084de1
Packit Service 084de1
    /*****************************************************************/
Packit Service 084de1
    /* report status of cert with serial number given on command line */
Packit Service 084de1
    if (ser_status) {
Packit Service 084de1
        dbfile = lookup_conf(conf, section, ENV_DATABASE);
Packit Service 084de1
        if (dbfile == NULL)
Packit Service 084de1
            goto end;
Packit Service 084de1
Packit Service 084de1
        db = load_index(dbfile, &db_attr);
Packit Service 084de1
        if (db == NULL)
Packit Service 084de1
            goto end;
Packit Service 084de1
Packit Service 084de1
        if (index_index(db) <= 0)
Packit Service 084de1
            goto end;
Packit Service 084de1
Packit Service 084de1
        if (get_certificate_status(ser_status, db) != 1)
Packit Service 084de1
            BIO_printf(bio_err, "Error verifying serial %s!\n", ser_status);
Packit Service 084de1
        goto end;
Packit Service 084de1
    }
Packit Service 084de1
Packit Service 084de1
    /*****************************************************************/
Packit Service 084de1
    /* we definitely need a private key, so let's get it */
Packit Service 084de1
Packit Service 084de1
    if (keyfile == NULL
Packit Service 084de1
        && (keyfile = lookup_conf(conf, section, ENV_PRIVATE_KEY)) == NULL)
Packit Service 084de1
        goto end;
Packit Service 084de1
Packit Service 084de1
    if (key == NULL) {
Packit Service 084de1
        free_key = 1;
Packit Service 084de1
        if (!app_passwd(passinarg, NULL, &key, NULL)) {
Packit Service 084de1
            BIO_printf(bio_err, "Error getting password\n");
Packit Service 084de1
            goto end;
Packit Service 084de1
        }
Packit Service 084de1
    }
Packit Service 084de1
    pkey = load_key(keyfile, keyformat, 0, key, e, "CA private key");
Packit Service 084de1
    if (key != NULL)
Packit Service 084de1
        OPENSSL_cleanse(key, strlen(key));
Packit Service 084de1
    if (pkey == NULL)
Packit Service 084de1
        /* load_key() has already printed an appropriate message */
Packit Service 084de1
        goto end;
Packit Service 084de1
Packit Service 084de1
    /*****************************************************************/
Packit Service 084de1
    /* we need a certificate */
Packit Service 084de1
    if (!selfsign || spkac_file || ss_cert_file || gencrl) {
Packit Service 084de1
        if (certfile == NULL
Packit Service 084de1
            && (certfile = lookup_conf(conf, section, ENV_CERTIFICATE)) == NULL)
Packit Service 084de1
            goto end;
Packit Service 084de1
Packit Service 084de1
        x509 = load_cert(certfile, FORMAT_PEM, "CA certificate");
Packit Service 084de1
        if (x509 == NULL)
Packit Service 084de1
            goto end;
Packit Service 084de1
Packit Service 084de1
        if (!X509_check_private_key(x509, pkey)) {
Packit Service 084de1
            BIO_printf(bio_err,
Packit Service 084de1
                       "CA certificate and CA private key do not match\n");
Packit Service 084de1
            goto end;
Packit Service 084de1
        }
Packit Service 084de1
    }
Packit Service 084de1
    if (!selfsign)
Packit Service 084de1
        x509p = x509;
Packit Service 084de1
Packit Service 084de1
    f = NCONF_get_string(conf, BASE_SECTION, ENV_PRESERVE);
Packit Service 084de1
    if (f == NULL)
Packit Service 084de1
        ERR_clear_error();
Packit Service 084de1
    if ((f != NULL) && ((*f == 'y') || (*f == 'Y')))
Packit Service 084de1
        preserve = 1;
Packit Service 084de1
    f = NCONF_get_string(conf, BASE_SECTION, ENV_MSIE_HACK);
Packit Service 084de1
    if (f == NULL)
Packit Service 084de1
        ERR_clear_error();
Packit Service 084de1
    if ((f != NULL) && ((*f == 'y') || (*f == 'Y')))
Packit Service 084de1
        msie_hack = 1;
Packit Service 084de1
Packit Service 084de1
    f = NCONF_get_string(conf, section, ENV_NAMEOPT);
Packit Service 084de1
Packit Service 084de1
    if (f != NULL) {
Packit Service 084de1
        if (!set_nameopt(f)) {
Packit Service 084de1
            BIO_printf(bio_err, "Invalid name options: \"%s\"\n", f);
Packit Service 084de1
            goto end;
Packit Service 084de1
        }
Packit Service 084de1
        default_op = 0;
Packit Service 084de1
    }
Packit Service 084de1
Packit Service 084de1
    f = NCONF_get_string(conf, section, ENV_CERTOPT);
Packit Service 084de1
Packit Service 084de1
    if (f != NULL) {
Packit Service 084de1
        if (!set_cert_ex(&certopt, f)) {
Packit Service 084de1
            BIO_printf(bio_err, "Invalid certificate options: \"%s\"\n", f);
Packit Service 084de1
            goto end;
Packit Service 084de1
        }
Packit Service 084de1
        default_op = 0;
Packit Service 084de1
    } else {
Packit Service 084de1
        ERR_clear_error();
Packit Service 084de1
    }
Packit Service 084de1
Packit Service 084de1
    f = NCONF_get_string(conf, section, ENV_EXTCOPY);
Packit Service 084de1
Packit Service 084de1
    if (f != NULL) {
Packit Service 084de1
        if (!set_ext_copy(&ext_copy, f)) {
Packit Service 084de1
            BIO_printf(bio_err, "Invalid extension copy option: \"%s\"\n", f);
Packit Service 084de1
            goto end;
Packit Service 084de1
        }
Packit Service 084de1
    } else {
Packit Service 084de1
        ERR_clear_error();
Packit Service 084de1
    }
Packit Service 084de1
Packit Service 084de1
    /*****************************************************************/
Packit Service 084de1
    /* lookup where to write new certificates */
Packit Service 084de1
    if ((outdir == NULL) && (req)) {
Packit Service 084de1
Packit Service 084de1
        outdir = NCONF_get_string(conf, section, ENV_NEW_CERTS_DIR);
Packit Service 084de1
        if (outdir == NULL) {
Packit Service 084de1
            BIO_printf(bio_err,
Packit Service 084de1
                       "there needs to be defined a directory for new certificate to be placed in\n");
Packit Service 084de1
            goto end;
Packit Service 084de1
        }
Packit Service 084de1
#ifndef OPENSSL_SYS_VMS
Packit Service 084de1
        /*
Packit Service 084de1
         * outdir is a directory spec, but access() for VMS demands a
Packit Service 084de1
         * filename.  We could use the DEC C routine to convert the
Packit Service 084de1
         * directory syntax to Unix, and give that to app_isdir,
Packit Service 084de1
         * but for now the fopen will catch the error if it's not a
Packit Service 084de1
         * directory
Packit Service 084de1
         */
Packit Service 084de1
        if (app_isdir(outdir) <= 0) {
Packit Service 084de1
            BIO_printf(bio_err, "%s: %s is not a directory\n", prog, outdir);
Packit Service 084de1
            perror(outdir);
Packit Service 084de1
            goto end;
Packit Service 084de1
        }
Packit Service 084de1
#endif
Packit Service 084de1
    }
Packit Service 084de1
Packit Service 084de1
    /*****************************************************************/
Packit Service 084de1
    /* we need to load the database file */
Packit Service 084de1
    dbfile = lookup_conf(conf, section, ENV_DATABASE);
Packit Service 084de1
    if (dbfile == NULL)
Packit Service 084de1
        goto end;
Packit Service 084de1
Packit Service 084de1
    db = load_index(dbfile, &db_attr);
Packit Service 084de1
    if (db == NULL)
Packit Service 084de1
        goto end;
Packit Service 084de1
Packit Service 084de1
    /* Lets check some fields */
Packit Service 084de1
    for (i = 0; i < sk_OPENSSL_PSTRING_num(db->db->data); i++) {
Packit Service 084de1
        pp = sk_OPENSSL_PSTRING_value(db->db->data, i);
Packit Service 084de1
        if ((pp[DB_type][0] != DB_TYPE_REV) && (pp[DB_rev_date][0] != '\0')) {
Packit Service 084de1
            BIO_printf(bio_err,
Packit Service 084de1
                       "entry %d: not revoked yet, but has a revocation date\n",
Packit Service 084de1
                       i + 1);
Packit Service 084de1
            goto end;
Packit Service 084de1
        }
Packit Service 084de1
        if ((pp[DB_type][0] == DB_TYPE_REV) &&
Packit Service 084de1
            !make_revoked(NULL, pp[DB_rev_date])) {
Packit Service 084de1
            BIO_printf(bio_err, " in entry %d\n", i + 1);
Packit Service 084de1
            goto end;
Packit Service 084de1
        }
Packit Service 084de1
        if (!check_time_format((char *)pp[DB_exp_date])) {
Packit Service 084de1
            BIO_printf(bio_err, "entry %d: invalid expiry date\n", i + 1);
Packit Service 084de1
            goto end;
Packit Service 084de1
        }
Packit Service 084de1
        p = pp[DB_serial];
Packit Service 084de1
        j = strlen(p);
Packit Service 084de1
        if (*p == '-') {
Packit Service 084de1
            p++;
Packit Service 084de1
            j--;
Packit Service 084de1
        }
Packit Service 084de1
        if ((j & 1) || (j < 2)) {
Packit Service 084de1
            BIO_printf(bio_err, "entry %d: bad serial number length (%d)\n",
Packit Service 084de1
                       i + 1, j);
Packit Service 084de1
            goto end;
Packit Service 084de1
        }
Packit Service 084de1
        for ( ; *p; p++) {
Packit Service 084de1
            if (!isxdigit(_UC(*p))) {
Packit Service 084de1
                BIO_printf(bio_err,
Packit Service 084de1
                           "entry %d: bad char 0%o '%c' in serial number\n",
Packit Service 084de1
                           i + 1, *p, *p);
Packit Service 084de1
                goto end;
Packit Service 084de1
            }
Packit Service 084de1
        }
Packit Service 084de1
    }
Packit Service 084de1
    if (verbose) {
Packit Service 084de1
        TXT_DB_write(bio_out, db->db);
Packit Service 084de1
        BIO_printf(bio_err, "%d entries loaded from the database\n",
Packit Service 084de1
                   sk_OPENSSL_PSTRING_num(db->db->data));
Packit Service 084de1
        BIO_printf(bio_err, "generating index\n");
Packit Service 084de1
    }
Packit Service 084de1
Packit Service 084de1
    if (index_index(db) <= 0)
Packit Service 084de1
        goto end;
Packit Service 084de1
Packit Service 084de1
    /*****************************************************************/
Packit Service 084de1
    /* Update the db file for expired certificates */
Packit Service 084de1
    if (doupdatedb) {
Packit Service 084de1
        if (verbose)
Packit Service 084de1
            BIO_printf(bio_err, "Updating %s ...\n", dbfile);
Packit Service 084de1
Packit Service 084de1
        i = do_updatedb(db);
Packit Service 084de1
        if (i == -1) {
Packit Service 084de1
            BIO_printf(bio_err, "Malloc failure\n");
Packit Service 084de1
            goto end;
Packit Service 084de1
        } else if (i == 0) {
Packit Service 084de1
            if (verbose)
Packit Service 084de1
                BIO_printf(bio_err, "No entries found to mark expired\n");
Packit Service 084de1
        } else {
Packit Service 084de1
            if (!save_index(dbfile, "new", db))
Packit Service 084de1
                goto end;
Packit Service 084de1
Packit Service 084de1
            if (!rotate_index(dbfile, "new", "old"))
Packit Service 084de1
                goto end;
Packit Service 084de1
Packit Service 084de1
            if (verbose)
Packit Service 084de1
                BIO_printf(bio_err, "Done. %d entries marked as expired\n", i);
Packit Service 084de1
        }
Packit Service 084de1
    }
Packit Service 084de1
Packit Service 084de1
    /*****************************************************************/
Packit Service 084de1
    /* Read extensions config file                                   */
Packit Service 084de1
    if (extfile) {
Packit Service 084de1
        if ((extconf = app_load_config(extfile)) == NULL) {
Packit Service 084de1
            ret = 1;
Packit Service 084de1
            goto end;
Packit Service 084de1
        }
Packit Service 084de1
Packit Service 084de1
        if (verbose)
Packit Service 084de1
            BIO_printf(bio_err, "Successfully loaded extensions file %s\n",
Packit Service 084de1
                       extfile);
Packit Service 084de1
Packit Service 084de1
        /* We can have sections in the ext file */
Packit Service 084de1
        if (extensions == NULL) {
Packit Service 084de1
            extensions = NCONF_get_string(extconf, "default", "extensions");
Packit Service 084de1
            if (extensions == NULL)
Packit Service 084de1
                extensions = "default";
Packit Service 084de1
        }
Packit Service 084de1
    }
Packit Service 084de1
Packit Service 084de1
    /*****************************************************************/
Packit Service 084de1
    if (req || gencrl) {
Packit Service 084de1
        if (spkac_file != NULL && outfile != NULL) {
Packit Service 084de1
            output_der = 1;
Packit Service 084de1
            batch = 1;
Packit Service 084de1
        }
Packit Service 084de1
    }
Packit Service 084de1
Packit Service 084de1
    def_ret = EVP_PKEY_get_default_digest_nid(pkey, &def_nid);
Packit Service 084de1
    /*
Packit Service 084de1
     * EVP_PKEY_get_default_digest_nid() returns 2 if the digest is
Packit Service 084de1
     * mandatory for this algorithm.
Packit Service 084de1
     */
Packit Service 084de1
    if (def_ret == 2 && def_nid == NID_undef) {
Packit Service 084de1
        /* The signing algorithm requires there to be no digest */
Packit Service 084de1
        dgst = EVP_md_null();
Packit Service 084de1
    } else if (md == NULL
Packit Service 084de1
               && (md = lookup_conf(conf, section, ENV_DEFAULT_MD)) == NULL) {
Packit Service 084de1
        goto end;
Packit Service 084de1
    } else {
Packit Service 084de1
        if (strcmp(md, "default") == 0) {
Packit Service 084de1
            if (def_ret <= 0) {
Packit Service 084de1
                BIO_puts(bio_err, "no default digest\n");
Packit Service 084de1
                goto end;
Packit Service 084de1
            }
Packit Service 084de1
            md = (char *)OBJ_nid2sn(def_nid);
Packit Service 084de1
        }
Packit Service 084de1
Packit Service 084de1
        if (!opt_md(md, &dgst))
Packit Service 084de1
            goto end;
Packit Service 084de1
    }
Packit Service 084de1
Packit Service 084de1
    if (req) {
Packit Service 084de1
        if (email_dn == 1) {
Packit Service 084de1
            char *tmp_email_dn = NULL;
Packit Service 084de1
Packit Service 084de1
            tmp_email_dn = NCONF_get_string(conf, section, ENV_DEFAULT_EMAIL_DN);
Packit Service 084de1
            if (tmp_email_dn != NULL && strcmp(tmp_email_dn, "no") == 0)
Packit Service 084de1
                email_dn = 0;
Packit Service 084de1
        }
Packit Service 084de1
        if (verbose)
Packit Service 084de1
            BIO_printf(bio_err, "message digest is %s\n",
Packit Service 084de1
                       OBJ_nid2ln(EVP_MD_type(dgst)));
Packit Service 084de1
        if (policy == NULL
Packit Service 084de1
            && (policy = lookup_conf(conf, section, ENV_POLICY)) == NULL)
Packit Service 084de1
            goto end;
Packit Service 084de1
Packit Service 084de1
        if (verbose)
Packit Service 084de1
            BIO_printf(bio_err, "policy is %s\n", policy);
Packit Service 084de1
Packit Service 084de1
        if (NCONF_get_string(conf, section, ENV_RAND_SERIAL) != NULL) {
Packit Service 084de1
            rand_ser = 1;
Packit Service 084de1
        } else {
Packit Service 084de1
            serialfile = lookup_conf(conf, section, ENV_SERIAL);
Packit Service 084de1
            if (serialfile == NULL)
Packit Service 084de1
                goto end;
Packit Service 084de1
        }
Packit Service 084de1
Packit Service 084de1
        if (extconf == NULL) {
Packit Service 084de1
            /*
Packit Service 084de1
             * no '-extfile' option, so we look for extensions in the main
Packit Service 084de1
             * configuration file
Packit Service 084de1
             */
Packit Service 084de1
            if (extensions == NULL) {
Packit Service 084de1
                extensions = NCONF_get_string(conf, section, ENV_EXTENSIONS);
Packit Service 084de1
                if (extensions == NULL)
Packit Service 084de1
                    ERR_clear_error();
Packit Service 084de1
            }
Packit Service 084de1
            if (extensions != NULL) {
Packit Service 084de1
                /* Check syntax of file */
Packit Service 084de1
                X509V3_CTX ctx;
Packit Service 084de1
                X509V3_set_ctx_test(&ctx;;
Packit Service 084de1
                X509V3_set_nconf(&ctx, conf);
Packit Service 084de1
                if (!X509V3_EXT_add_nconf(conf, &ctx, extensions, NULL)) {
Packit Service 084de1
                    BIO_printf(bio_err,
Packit Service 084de1
                               "Error Loading extension section %s\n",
Packit Service 084de1
                               extensions);
Packit Service 084de1
                    ret = 1;
Packit Service 084de1
                    goto end;
Packit Service 084de1
                }
Packit Service 084de1
            }
Packit Service 084de1
        }
Packit Service 084de1
Packit Service 084de1
        if (startdate == NULL) {
Packit Service 084de1
            startdate = NCONF_get_string(conf, section, ENV_DEFAULT_STARTDATE);
Packit Service 084de1
            if (startdate == NULL)
Packit Service 084de1
                ERR_clear_error();
Packit Service 084de1
        }
Packit Service 084de1
        if (startdate != NULL && !ASN1_TIME_set_string_X509(NULL, startdate)) {
Packit Service 084de1
            BIO_printf(bio_err,
Packit Service 084de1
                       "start date is invalid, it should be YYMMDDHHMMSSZ or YYYYMMDDHHMMSSZ\n");
Packit Service 084de1
            goto end;
Packit Service 084de1
        }
Packit Service 084de1
        if (startdate == NULL)
Packit Service 084de1
            startdate = "today";
Packit Service 084de1
Packit Service 084de1
        if (enddate == NULL) {
Packit Service 084de1
            enddate = NCONF_get_string(conf, section, ENV_DEFAULT_ENDDATE);
Packit Service 084de1
            if (enddate == NULL)
Packit Service 084de1
                ERR_clear_error();
Packit Service 084de1
        }
Packit Service 084de1
        if (enddate != NULL && !ASN1_TIME_set_string_X509(NULL, enddate)) {
Packit Service 084de1
            BIO_printf(bio_err,
Packit Service 084de1
                       "end date is invalid, it should be YYMMDDHHMMSSZ or YYYYMMDDHHMMSSZ\n");
Packit Service 084de1
            goto end;
Packit Service 084de1
        }
Packit Service 084de1
Packit Service 084de1
        if (days == 0) {
Packit Service 084de1
            if (!NCONF_get_number(conf, section, ENV_DEFAULT_DAYS, &days))
Packit Service 084de1
                days = 0;
Packit Service 084de1
        }
Packit Service 084de1
        if (enddate == NULL && days == 0) {
Packit Service 084de1
            BIO_printf(bio_err, "cannot lookup how many days to certify for\n");
Packit Service 084de1
            goto end;
Packit Service 084de1
        }
Packit Service 084de1
Packit Service 084de1
        if (rand_ser) {
Packit Service 084de1
            if ((serial = BN_new()) == NULL || !rand_serial(serial, NULL)) {
Packit Service 084de1
                BIO_printf(bio_err, "error generating serial number\n");
Packit Service 084de1
                goto end;
Packit Service 084de1
            }
Packit Service 084de1
        } else {
Packit Service 084de1
            if ((serial = load_serial(serialfile, create_ser, NULL)) == NULL) {
Packit Service 084de1
                BIO_printf(bio_err, "error while loading serial number\n");
Packit Service 084de1
                goto end;
Packit Service 084de1
            }
Packit Service 084de1
            if (verbose) {
Packit Service 084de1
                if (BN_is_zero(serial)) {
Packit Service 084de1
                    BIO_printf(bio_err, "next serial number is 00\n");
Packit Service 084de1
                } else {
Packit Service 084de1
                    if ((f = BN_bn2hex(serial)) == NULL)
Packit Service 084de1
                        goto end;
Packit Service 084de1
                    BIO_printf(bio_err, "next serial number is %s\n", f);
Packit Service 084de1
                    OPENSSL_free(f);
Packit Service 084de1
                }
Packit Service 084de1
            }
Packit Service 084de1
        }
Packit Service 084de1
Packit Service 084de1
        if ((attribs = NCONF_get_section(conf, policy)) == NULL) {
Packit Service 084de1
            BIO_printf(bio_err, "unable to find 'section' for %s\n", policy);
Packit Service 084de1
            goto end;
Packit Service 084de1
        }
Packit Service 084de1
Packit Service 084de1
        if ((cert_sk = sk_X509_new_null()) == NULL) {
Packit Service 084de1
            BIO_printf(bio_err, "Memory allocation failure\n");
Packit Service 084de1
            goto end;
Packit Service 084de1
        }
Packit Service 084de1
        if (spkac_file != NULL) {
Packit Service 084de1
            total++;
Packit Service 084de1
            j = certify_spkac(&x, spkac_file, pkey, x509, dgst, sigopts,
Packit Service 084de1
                              attribs, db, serial, subj, chtype, multirdn,
Packit Service 084de1
                              email_dn, startdate, enddate, days, extensions,
Packit Service 084de1
                              conf, verbose, certopt, get_nameopt(), default_op,
Packit Service 084de1
                              ext_copy);
Packit Service 084de1
            if (j < 0)
Packit Service 084de1
                goto end;
Packit Service 084de1
            if (j > 0) {
Packit Service 084de1
                total_done++;
Packit Service 084de1
                BIO_printf(bio_err, "\n");
Packit Service 084de1
                if (!BN_add_word(serial, 1))
Packit Service 084de1
                    goto end;
Packit Service 084de1
                if (!sk_X509_push(cert_sk, x)) {
Packit Service 084de1
                    BIO_printf(bio_err, "Memory allocation failure\n");
Packit Service 084de1
                    goto end;
Packit Service 084de1
                }
Packit Service 084de1
            }
Packit Service 084de1
        }
Packit Service 084de1
        if (ss_cert_file != NULL) {
Packit Service 084de1
            total++;
Packit Service 084de1
            j = certify_cert(&x, ss_cert_file, pkey, x509, dgst, sigopts,
Packit Service 084de1
                             attribs,
Packit Service 084de1
                             db, serial, subj, chtype, multirdn, email_dn,
Packit Service 084de1
                             startdate, enddate, days, batch, extensions,
Packit Service 084de1
                             conf, verbose, certopt, get_nameopt(), default_op,
Packit Service 084de1
                             ext_copy);
Packit Service 084de1
            if (j < 0)
Packit Service 084de1
                goto end;
Packit Service 084de1
            if (j > 0) {
Packit Service 084de1
                total_done++;
Packit Service 084de1
                BIO_printf(bio_err, "\n");
Packit Service 084de1
                if (!BN_add_word(serial, 1))
Packit Service 084de1
                    goto end;
Packit Service 084de1
                if (!sk_X509_push(cert_sk, x)) {
Packit Service 084de1
                    BIO_printf(bio_err, "Memory allocation failure\n");
Packit Service 084de1
                    goto end;
Packit Service 084de1
                }
Packit Service 084de1
            }
Packit Service 084de1
        }
Packit Service 084de1
        if (infile != NULL) {
Packit Service 084de1
            total++;
Packit Service 084de1
            j = certify(&x, infile, pkey, x509p, dgst, sigopts, attribs, db,
Packit Service 084de1
                        serial, subj, chtype, multirdn, email_dn, startdate,
Packit Service 084de1
                        enddate, days, batch, extensions, conf, verbose,
Packit Service 084de1
                        certopt, get_nameopt(), default_op, ext_copy, selfsign);
Packit Service 084de1
            if (j < 0)
Packit Service 084de1
                goto end;
Packit Service 084de1
            if (j > 0) {
Packit Service 084de1
                total_done++;
Packit Service 084de1
                BIO_printf(bio_err, "\n");
Packit Service 084de1
                if (!BN_add_word(serial, 1))
Packit Service 084de1
                    goto end;
Packit Service 084de1
                if (!sk_X509_push(cert_sk, x)) {
Packit Service 084de1
                    BIO_printf(bio_err, "Memory allocation failure\n");
Packit Service 084de1
                    goto end;
Packit Service 084de1
                }
Packit Service 084de1
            }
Packit Service 084de1
        }
Packit Service 084de1
        for (i = 0; i < argc; i++) {
Packit Service 084de1
            total++;
Packit Service 084de1
            j = certify(&x, argv[i], pkey, x509p, dgst, sigopts, attribs, db,
Packit Service 084de1
                        serial, subj, chtype, multirdn, email_dn, startdate,
Packit Service 084de1
                        enddate, days, batch, extensions, conf, verbose,
Packit Service 084de1
                        certopt, get_nameopt(), default_op, ext_copy, selfsign);
Packit Service 084de1
            if (j < 0)
Packit Service 084de1
                goto end;
Packit Service 084de1
            if (j > 0) {
Packit Service 084de1
                total_done++;
Packit Service 084de1
                BIO_printf(bio_err, "\n");
Packit Service 084de1
                if (!BN_add_word(serial, 1)) {
Packit Service 084de1
                    X509_free(x);
Packit Service 084de1
                    goto end;
Packit Service 084de1
                }
Packit Service 084de1
                if (!sk_X509_push(cert_sk, x)) {
Packit Service 084de1
                    BIO_printf(bio_err, "Memory allocation failure\n");
Packit Service 084de1
                    X509_free(x);
Packit Service 084de1
                    goto end;
Packit Service 084de1
                }
Packit Service 084de1
            }
Packit Service 084de1
        }
Packit Service 084de1
        /*
Packit Service 084de1
         * we have a stack of newly certified certificates and a data base
Packit Service 084de1
         * and serial number that need updating
Packit Service 084de1
         */
Packit Service 084de1
Packit Service 084de1
        if (sk_X509_num(cert_sk) > 0) {
Packit Service 084de1
            if (!batch) {
Packit Service 084de1
                BIO_printf(bio_err,
Packit Service 084de1
                           "\n%d out of %d certificate requests certified, commit? [y/n]",
Packit Service 084de1
                           total_done, total);
Packit Service 084de1
                (void)BIO_flush(bio_err);
Packit Service 084de1
                tmp[0] = '\0';
Packit Service 084de1
                if (fgets(tmp, sizeof(tmp), stdin) == NULL) {
Packit Service 084de1
                    BIO_printf(bio_err, "CERTIFICATION CANCELED: I/O error\n");
Packit Service 084de1
                    ret = 0;
Packit Service 084de1
                    goto end;
Packit Service 084de1
                }
Packit Service 084de1
                if (tmp[0] != 'y' && tmp[0] != 'Y') {
Packit Service 084de1
                    BIO_printf(bio_err, "CERTIFICATION CANCELED\n");
Packit Service 084de1
                    ret = 0;
Packit Service 084de1
                    goto end;
Packit Service 084de1
                }
Packit Service 084de1
            }
Packit Service 084de1
Packit Service 084de1
            BIO_printf(bio_err, "Write out database with %d new entries\n",
Packit Service 084de1
                       sk_X509_num(cert_sk));
Packit Service 084de1
Packit Service 084de1
            if (serialfile != NULL
Packit Service 084de1
                    && !save_serial(serialfile, "new", serial, NULL))
Packit Service 084de1
                goto end;
Packit Service 084de1
Packit Service 084de1
            if (!save_index(dbfile, "new", db))
Packit Service 084de1
                goto end;
Packit Service 084de1
        }
Packit Service 084de1
Packit Service 084de1
        outdirlen = OPENSSL_strlcpy(new_cert, outdir, sizeof(new_cert));
Packit Service 084de1
#ifndef OPENSSL_SYS_VMS
Packit Service 084de1
        outdirlen = OPENSSL_strlcat(new_cert, "/", sizeof(new_cert));
Packit Service 084de1
#endif
Packit Service 084de1
Packit Service 084de1
        if (verbose)
Packit Service 084de1
            BIO_printf(bio_err, "writing new certificates\n");
Packit Service 084de1
Packit Service 084de1
        for (i = 0; i < sk_X509_num(cert_sk); i++) {
Packit Service 084de1
            BIO *Cout = NULL;
Packit Service 084de1
            X509 *xi = sk_X509_value(cert_sk, i);
Packit Service 084de1
            ASN1_INTEGER *serialNumber = X509_get_serialNumber(xi);
Packit Service 084de1
            const unsigned char *psn = ASN1_STRING_get0_data(serialNumber);
Packit Service 084de1
            const int snl = ASN1_STRING_length(serialNumber);
Packit Service 084de1
            const int filen_len = 2 * (snl > 0 ? snl : 1) + sizeof(".pem");
Packit Service 084de1
            char *n = new_cert + outdirlen;
Packit Service 084de1
Packit Service 084de1
            if (outdirlen + filen_len > PATH_MAX) {
Packit Service 084de1
                BIO_printf(bio_err, "certificate file name too long\n");
Packit Service 084de1
                goto end;
Packit Service 084de1
            }
Packit Service 084de1
Packit Service 084de1
            if (snl > 0) {
Packit Service 084de1
                static const char HEX_DIGITS[] = "0123456789ABCDEF";
Packit Service 084de1
Packit Service 084de1
                for (j = 0; j < snl; j++, psn++) {
Packit Service 084de1
                    *n++ = HEX_DIGITS[*psn >> 4];
Packit Service 084de1
                    *n++ = HEX_DIGITS[*psn & 0x0F];
Packit Service 084de1
                }
Packit Service 084de1
            } else {
Packit Service 084de1
                *(n++) = '0';
Packit Service 084de1
                *(n++) = '0';
Packit Service 084de1
            }
Packit Service 084de1
            *(n++) = '.';
Packit Service 084de1
            *(n++) = 'p';
Packit Service 084de1
            *(n++) = 'e';
Packit Service 084de1
            *(n++) = 'm';
Packit Service 084de1
            *n = '\0';          /* closing new_cert */
Packit Service 084de1
            if (verbose)
Packit Service 084de1
                BIO_printf(bio_err, "writing %s\n", new_cert);
Packit Service 084de1
Packit Service 084de1
            Sout = bio_open_default(outfile, 'w',
Packit Service 084de1
                                    output_der ? FORMAT_ASN1 : FORMAT_TEXT);
Packit Service 084de1
            if (Sout == NULL)
Packit Service 084de1
                goto end;
Packit Service 084de1
Packit Service 084de1
            Cout = BIO_new_file(new_cert, "w");
Packit Service 084de1
            if (Cout == NULL) {
Packit Service 084de1
                perror(new_cert);
Packit Service 084de1
                goto end;
Packit Service 084de1
            }
Packit Service 084de1
            write_new_certificate(Cout, xi, 0, notext);
Packit Service 084de1
            write_new_certificate(Sout, xi, output_der, notext);
Packit Service 084de1
            BIO_free_all(Cout);
Packit Service 084de1
            BIO_free_all(Sout);
Packit Service 084de1
            Sout = NULL;
Packit Service 084de1
        }
Packit Service 084de1
Packit Service 084de1
        if (sk_X509_num(cert_sk)) {
Packit Service 084de1
            /* Rename the database and the serial file */
Packit Service 084de1
            if (serialfile != NULL
Packit Service 084de1
                    && !rotate_serial(serialfile, "new", "old"))
Packit Service 084de1
                goto end;
Packit Service 084de1
Packit Service 084de1
            if (!rotate_index(dbfile, "new", "old"))
Packit Service 084de1
                goto end;
Packit Service 084de1
Packit Service 084de1
            BIO_printf(bio_err, "Data Base Updated\n");
Packit Service 084de1
        }
Packit Service 084de1
    }
Packit Service 084de1
Packit Service 084de1
    /*****************************************************************/
Packit Service 084de1
    if (gencrl) {
Packit Service 084de1
        int crl_v2 = 0;
Packit Service 084de1
        if (crl_ext == NULL) {
Packit Service 084de1
            crl_ext = NCONF_get_string(conf, section, ENV_CRLEXT);
Packit Service 084de1
            if (crl_ext == NULL)
Packit Service 084de1
                ERR_clear_error();
Packit Service 084de1
        }
Packit Service 084de1
        if (crl_ext != NULL) {
Packit Service 084de1
            /* Check syntax of file */
Packit Service 084de1
            X509V3_CTX ctx;
Packit Service 084de1
            X509V3_set_ctx_test(&ctx;;
Packit Service 084de1
            X509V3_set_nconf(&ctx, conf);
Packit Service 084de1
            if (!X509V3_EXT_add_nconf(conf, &ctx, crl_ext, NULL)) {
Packit Service 084de1
                BIO_printf(bio_err,
Packit Service 084de1
                           "Error Loading CRL extension section %s\n", crl_ext);
Packit Service 084de1
                ret = 1;
Packit Service 084de1
                goto end;
Packit Service 084de1
            }
Packit Service 084de1
        }
Packit Service 084de1
Packit Service 084de1
        if ((crlnumberfile = NCONF_get_string(conf, section, ENV_CRLNUMBER))
Packit Service 084de1
            != NULL)
Packit Service 084de1
            if ((crlnumber = load_serial(crlnumberfile, 0, NULL)) == NULL) {
Packit Service 084de1
                BIO_printf(bio_err, "error while loading CRL number\n");
Packit Service 084de1
                goto end;
Packit Service 084de1
            }
Packit Service 084de1
Packit Service 084de1
        if (!crldays && !crlhours && !crlsec) {
Packit Service 084de1
            if (!NCONF_get_number(conf, section,
Packit Service 084de1
                                  ENV_DEFAULT_CRL_DAYS, &crldays))
Packit Service 084de1
                crldays = 0;
Packit Service 084de1
            if (!NCONF_get_number(conf, section,
Packit Service 084de1
                                  ENV_DEFAULT_CRL_HOURS, &crlhours))
Packit Service 084de1
                crlhours = 0;
Packit Service 084de1
            ERR_clear_error();
Packit Service 084de1
        }
Packit Service 084de1
        if ((crldays == 0) && (crlhours == 0) && (crlsec == 0)) {
Packit Service 084de1
            BIO_printf(bio_err,
Packit Service 084de1
                       "cannot lookup how long until the next CRL is issued\n");
Packit Service 084de1
            goto end;
Packit Service 084de1
        }
Packit Service 084de1
Packit Service 084de1
        if (verbose)
Packit Service 084de1
            BIO_printf(bio_err, "making CRL\n");
Packit Service 084de1
        if ((crl = X509_CRL_new()) == NULL)
Packit Service 084de1
            goto end;
Packit Service 084de1
        if (!X509_CRL_set_issuer_name(crl, X509_get_subject_name(x509)))
Packit Service 084de1
            goto end;
Packit Service 084de1
Packit Service 084de1
        tmptm = ASN1_TIME_new();
Packit Service 084de1
        if (tmptm == NULL
Packit Service 084de1
                || X509_gmtime_adj(tmptm, 0) == NULL
Packit Service 084de1
                || !X509_CRL_set1_lastUpdate(crl, tmptm)
Packit Service 084de1
                || X509_time_adj_ex(tmptm, crldays, crlhours * 60 * 60 + crlsec,
Packit Service 084de1
                                    NULL) == NULL) {
Packit Service 084de1
            BIO_puts(bio_err, "error setting CRL nextUpdate\n");
Packit Service 084de1
            ASN1_TIME_free(tmptm);
Packit Service 084de1
            goto end;
Packit Service 084de1
        }
Packit Service 084de1
        X509_CRL_set1_nextUpdate(crl, tmptm);
Packit Service 084de1
Packit Service 084de1
        ASN1_TIME_free(tmptm);
Packit Service 084de1
Packit Service 084de1
        for (i = 0; i < sk_OPENSSL_PSTRING_num(db->db->data); i++) {
Packit Service 084de1
            pp = sk_OPENSSL_PSTRING_value(db->db->data, i);
Packit Service 084de1
            if (pp[DB_type][0] == DB_TYPE_REV) {
Packit Service 084de1
                if ((r = X509_REVOKED_new()) == NULL)
Packit Service 084de1
                    goto end;
Packit Service 084de1
                j = make_revoked(r, pp[DB_rev_date]);
Packit Service 084de1
                if (!j)
Packit Service 084de1
                    goto end;
Packit Service 084de1
                if (j == 2)
Packit Service 084de1
                    crl_v2 = 1;
Packit Service 084de1
                if (!BN_hex2bn(&serial, pp[DB_serial]))
Packit Service 084de1
                    goto end;
Packit Service 084de1
                tmpser = BN_to_ASN1_INTEGER(serial, NULL);
Packit Service 084de1
                BN_free(serial);
Packit Service 084de1
                serial = NULL;
Packit Service 084de1
                if (!tmpser)
Packit Service 084de1
                    goto end;
Packit Service 084de1
                X509_REVOKED_set_serialNumber(r, tmpser);
Packit Service 084de1
                ASN1_INTEGER_free(tmpser);
Packit Service 084de1
                X509_CRL_add0_revoked(crl, r);
Packit Service 084de1
            }
Packit Service 084de1
        }
Packit Service 084de1
Packit Service 084de1
        /*
Packit Service 084de1
         * sort the data so it will be written in serial number order
Packit Service 084de1
         */
Packit Service 084de1
        X509_CRL_sort(crl);
Packit Service 084de1
Packit Service 084de1
        /* we now have a CRL */
Packit Service 084de1
        if (verbose)
Packit Service 084de1
            BIO_printf(bio_err, "signing CRL\n");
Packit Service 084de1
Packit Service 084de1
        /* Add any extensions asked for */
Packit Service 084de1
Packit Service 084de1
        if (crl_ext != NULL || crlnumberfile != NULL) {
Packit Service 084de1
            X509V3_CTX crlctx;
Packit Service 084de1
            X509V3_set_ctx(&crlctx, x509, NULL, NULL, crl, 0);
Packit Service 084de1
            X509V3_set_nconf(&crlctx, conf);
Packit Service 084de1
Packit Service 084de1
            if (crl_ext != NULL)
Packit Service 084de1
                if (!X509V3_EXT_CRL_add_nconf(conf, &crlctx, crl_ext, crl))
Packit Service 084de1
                    goto end;
Packit Service 084de1
            if (crlnumberfile != NULL) {
Packit Service 084de1
                tmpser = BN_to_ASN1_INTEGER(crlnumber, NULL);
Packit Service 084de1
                if (!tmpser)
Packit Service 084de1
                    goto end;
Packit Service 084de1
                X509_CRL_add1_ext_i2d(crl, NID_crl_number, tmpser, 0, 0);
Packit Service 084de1
                ASN1_INTEGER_free(tmpser);
Packit Service 084de1
                crl_v2 = 1;
Packit Service 084de1
                if (!BN_add_word(crlnumber, 1))
Packit Service 084de1
                    goto end;
Packit Service 084de1
            }
Packit Service 084de1
        }
Packit Service 084de1
        if (crl_ext != NULL || crl_v2) {
Packit Service 084de1
            if (!X509_CRL_set_version(crl, 1))
Packit Service 084de1
                goto end;       /* version 2 CRL */
Packit Service 084de1
        }
Packit Service 084de1
Packit Service 084de1
        /* we have a CRL number that need updating */
Packit Service 084de1
        if (crlnumberfile != NULL
Packit Service 084de1
                && !save_serial(crlnumberfile, "new", crlnumber, NULL))
Packit Service 084de1
            goto end;
Packit Service 084de1
Packit Service 084de1
        BN_free(crlnumber);
Packit Service 084de1
        crlnumber = NULL;
Packit Service 084de1
Packit Service 084de1
        if (!do_X509_CRL_sign(crl, pkey, dgst, sigopts))
Packit Service 084de1
            goto end;
Packit Service 084de1
Packit Service 084de1
        Sout = bio_open_default(outfile, 'w',
Packit Service 084de1
                                output_der ? FORMAT_ASN1 : FORMAT_TEXT);
Packit Service 084de1
        if (Sout == NULL)
Packit Service 084de1
            goto end;
Packit Service 084de1
Packit Service 084de1
        PEM_write_bio_X509_CRL(Sout, crl);
Packit Service 084de1
Packit Service 084de1
        /* Rename the crlnumber file */
Packit Service 084de1
        if (crlnumberfile != NULL
Packit Service 084de1
                && !rotate_serial(crlnumberfile, "new", "old"))
Packit Service 084de1
            goto end;
Packit Service 084de1
Packit Service 084de1
    }
Packit Service 084de1
    /*****************************************************************/
Packit Service 084de1
    if (dorevoke) {
Packit Service 084de1
        if (infile == NULL) {
Packit Service 084de1
            BIO_printf(bio_err, "no input files\n");
Packit Service 084de1
            goto end;
Packit Service 084de1
        } else {
Packit Service 084de1
            X509 *revcert;
Packit Service 084de1
            revcert = load_cert(infile, FORMAT_PEM, infile);
Packit Service 084de1
            if (revcert == NULL)
Packit Service 084de1
                goto end;
Packit Service 084de1
            if (dorevoke == 2)
Packit Service 084de1
                rev_type = REV_VALID;
Packit Service 084de1
            j = do_revoke(revcert, db, rev_type, rev_arg);
Packit Service 084de1
            if (j <= 0)
Packit Service 084de1
                goto end;
Packit Service 084de1
            X509_free(revcert);
Packit Service 084de1
Packit Service 084de1
            if (!save_index(dbfile, "new", db))
Packit Service 084de1
                goto end;
Packit Service 084de1
Packit Service 084de1
            if (!rotate_index(dbfile, "new", "old"))
Packit Service 084de1
                goto end;
Packit Service 084de1
Packit Service 084de1
            BIO_printf(bio_err, "Data Base Updated\n");
Packit Service 084de1
        }
Packit Service 084de1
    }
Packit Service 084de1
    ret = 0;
Packit Service 084de1
Packit Service 084de1
 end:
Packit Service 084de1
    if (ret)
Packit Service 084de1
        ERR_print_errors(bio_err);
Packit Service 084de1
    BIO_free_all(Sout);
Packit Service 084de1
    BIO_free_all(out);
Packit Service 084de1
    BIO_free_all(in);
Packit Service 084de1
    sk_X509_pop_free(cert_sk, X509_free);
Packit Service 084de1
Packit Service 084de1
    if (free_key)
Packit Service 084de1
        OPENSSL_free(key);
Packit Service 084de1
    BN_free(serial);
Packit Service 084de1
    BN_free(crlnumber);
Packit Service 084de1
    free_index(db);
Packit Service 084de1
    sk_OPENSSL_STRING_free(sigopts);
Packit Service 084de1
    EVP_PKEY_free(pkey);
Packit Service 084de1
    X509_free(x509);
Packit Service 084de1
    X509_CRL_free(crl);
Packit Service 084de1
    NCONF_free(conf);
Packit Service 084de1
    NCONF_free(extconf);
Packit Service 084de1
    release_engine(e);
Packit Service 084de1
    return ret;
Packit Service 084de1
}
Packit Service 084de1
Packit Service 084de1
static char *lookup_conf(const CONF *conf, const char *section, const char *tag)
Packit Service 084de1
{
Packit Service 084de1
    char *entry = NCONF_get_string(conf, section, tag);
Packit Service 084de1
    if (entry == NULL)
Packit Service 084de1
        BIO_printf(bio_err, "variable lookup failed for %s::%s\n", section, tag);
Packit Service 084de1
    return entry;
Packit Service 084de1
}
Packit Service 084de1
Packit Service 084de1
static int certify(X509 **xret, const char *infile, EVP_PKEY *pkey, X509 *x509,
Packit Service 084de1
                   const EVP_MD *dgst, STACK_OF(OPENSSL_STRING) *sigopts,
Packit Service 084de1
                   STACK_OF(CONF_VALUE) *policy, CA_DB *db,
Packit Service 084de1
                   BIGNUM *serial, const char *subj, unsigned long chtype,
Packit Service 084de1
                   int multirdn, int email_dn, const char *startdate,
Packit Service 084de1
                   const char *enddate,
Packit Service 084de1
                   long days, int batch, const char *ext_sect, CONF *lconf,
Packit Service 084de1
                   int verbose, unsigned long certopt, unsigned long nameopt,
Packit Service 084de1
                   int default_op, int ext_copy, int selfsign)
Packit Service 084de1
{
Packit Service 084de1
    X509_REQ *req = NULL;
Packit Service 084de1
    BIO *in = NULL;
Packit Service 084de1
    EVP_PKEY *pktmp = NULL;
Packit Service 084de1
    int ok = -1, i;
Packit Service 084de1
Packit Service 084de1
    in = BIO_new_file(infile, "r");
Packit Service 084de1
    if (in == NULL) {
Packit Service 084de1
        ERR_print_errors(bio_err);
Packit Service 084de1
        goto end;
Packit Service 084de1
    }
Packit Service 084de1
    if ((req = PEM_read_bio_X509_REQ(in, NULL, NULL, NULL)) == NULL) {
Packit Service 084de1
        BIO_printf(bio_err, "Error reading certificate request in %s\n",
Packit Service 084de1
                   infile);
Packit Service 084de1
        goto end;
Packit Service 084de1
    }
Packit Service 084de1
    if (verbose)
Packit Service 084de1
        X509_REQ_print_ex(bio_err, req, nameopt, X509_FLAG_COMPAT);
Packit Service 084de1
Packit Service 084de1
    BIO_printf(bio_err, "Check that the request matches the signature\n");
Packit Service 084de1
Packit Service 084de1
    if (selfsign && !X509_REQ_check_private_key(req, pkey)) {
Packit Service 084de1
        BIO_printf(bio_err,
Packit Service 084de1
                   "Certificate request and CA private key do not match\n");
Packit Service 084de1
        ok = 0;
Packit Service 084de1
        goto end;
Packit Service 084de1
    }
Packit Service 084de1
    if ((pktmp = X509_REQ_get0_pubkey(req)) == NULL) {
Packit Service 084de1
        BIO_printf(bio_err, "error unpacking public key\n");
Packit Service 084de1
        goto end;
Packit Service 084de1
    }
Packit Service 084de1
    i = X509_REQ_verify(req, pktmp);
Packit Service 084de1
    pktmp = NULL;
Packit Service 084de1
    if (i < 0) {
Packit Service 084de1
        ok = 0;
Packit Service 084de1
        BIO_printf(bio_err, "Signature verification problems....\n");
Packit Service 084de1
        ERR_print_errors(bio_err);
Packit Service 084de1
        goto end;
Packit Service 084de1
    }
Packit Service 084de1
    if (i == 0) {
Packit Service 084de1
        ok = 0;
Packit Service 084de1
        BIO_printf(bio_err,
Packit Service 084de1
                   "Signature did not match the certificate request\n");
Packit Service 084de1
        ERR_print_errors(bio_err);
Packit Service 084de1
        goto end;
Packit Service 084de1
    } else {
Packit Service 084de1
        BIO_printf(bio_err, "Signature ok\n");
Packit Service 084de1
    }
Packit Service 084de1
Packit Service 084de1
    ok = do_body(xret, pkey, x509, dgst, sigopts, policy, db, serial, subj,
Packit Service 084de1
                 chtype, multirdn, email_dn, startdate, enddate, days, batch,
Packit Service 084de1
                 verbose, req, ext_sect, lconf, certopt, nameopt, default_op,
Packit Service 084de1
                 ext_copy, selfsign);
Packit Service 084de1
Packit Service 084de1
 end:
Packit Service 084de1
    X509_REQ_free(req);
Packit Service 084de1
    BIO_free(in);
Packit Service 084de1
    return ok;
Packit Service 084de1
}
Packit Service 084de1
Packit Service 084de1
static int certify_cert(X509 **xret, const char *infile, EVP_PKEY *pkey, X509 *x509,
Packit Service 084de1
                        const EVP_MD *dgst, STACK_OF(OPENSSL_STRING) *sigopts,
Packit Service 084de1
                        STACK_OF(CONF_VALUE) *policy, CA_DB *db,
Packit Service 084de1
                        BIGNUM *serial, const char *subj, unsigned long chtype,
Packit Service 084de1
                        int multirdn, int email_dn, const char *startdate,
Packit Service 084de1
                        const char *enddate, long days, int batch, const char *ext_sect,
Packit Service 084de1
                        CONF *lconf, int verbose, unsigned long certopt,
Packit Service 084de1
                        unsigned long nameopt, int default_op, int ext_copy)
Packit Service 084de1
{
Packit Service 084de1
    X509 *req = NULL;
Packit Service 084de1
    X509_REQ *rreq = NULL;
Packit Service 084de1
    EVP_PKEY *pktmp = NULL;
Packit Service 084de1
    int ok = -1, i;
Packit Service 084de1
Packit Service 084de1
    if ((req = load_cert(infile, FORMAT_PEM, infile)) == NULL)
Packit Service 084de1
        goto end;
Packit Service 084de1
    if (verbose)
Packit Service 084de1
        X509_print(bio_err, req);
Packit Service 084de1
Packit Service 084de1
    BIO_printf(bio_err, "Check that the request matches the signature\n");
Packit Service 084de1
Packit Service 084de1
    if ((pktmp = X509_get0_pubkey(req)) == NULL) {
Packit Service 084de1
        BIO_printf(bio_err, "error unpacking public key\n");
Packit Service 084de1
        goto end;
Packit Service 084de1
    }
Packit Service 084de1
    i = X509_verify(req, pktmp);
Packit Service 084de1
    if (i < 0) {
Packit Service 084de1
        ok = 0;
Packit Service 084de1
        BIO_printf(bio_err, "Signature verification problems....\n");
Packit Service 084de1
        goto end;
Packit Service 084de1
    }
Packit Service 084de1
    if (i == 0) {
Packit Service 084de1
        ok = 0;
Packit Service 084de1
        BIO_printf(bio_err, "Signature did not match the certificate\n");
Packit Service 084de1
        goto end;
Packit Service 084de1
    } else {
Packit Service 084de1
        BIO_printf(bio_err, "Signature ok\n");
Packit Service 084de1
    }
Packit Service 084de1
Packit Service 084de1
    if ((rreq = X509_to_X509_REQ(req, NULL, NULL)) == NULL)
Packit Service 084de1
        goto end;
Packit Service 084de1
Packit Service 084de1
    ok = do_body(xret, pkey, x509, dgst, sigopts, policy, db, serial, subj,
Packit Service 084de1
                 chtype, multirdn, email_dn, startdate, enddate, days, batch,
Packit Service 084de1
                 verbose, rreq, ext_sect, lconf, certopt, nameopt, default_op,
Packit Service 084de1
                 ext_copy, 0);
Packit Service 084de1
Packit Service 084de1
 end:
Packit Service 084de1
    X509_REQ_free(rreq);
Packit Service 084de1
    X509_free(req);
Packit Service 084de1
    return ok;
Packit Service 084de1
}
Packit Service 084de1
Packit Service 084de1
static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509,
Packit Service 084de1
                   const EVP_MD *dgst, STACK_OF(OPENSSL_STRING) *sigopts,
Packit Service 084de1
                   STACK_OF(CONF_VALUE) *policy, CA_DB *db, BIGNUM *serial,
Packit Service 084de1
                   const char *subj, unsigned long chtype, int multirdn,
Packit Service 084de1
                   int email_dn, const char *startdate, const char *enddate, long days,
Packit Service 084de1
                   int batch, int verbose, X509_REQ *req, const char *ext_sect,
Packit Service 084de1
                   CONF *lconf, unsigned long certopt, unsigned long nameopt,
Packit Service 084de1
                   int default_op, int ext_copy, int selfsign)
Packit Service 084de1
{
Packit Service 084de1
    X509_NAME *name = NULL, *CAname = NULL, *subject = NULL;
Packit Service 084de1
    const ASN1_TIME *tm;
Packit Service 084de1
    ASN1_STRING *str, *str2;
Packit Service 084de1
    ASN1_OBJECT *obj;
Packit Service 084de1
    X509 *ret = NULL;
Packit Service 084de1
    X509_NAME_ENTRY *ne, *tne;
Packit Service 084de1
    EVP_PKEY *pktmp;
Packit Service 084de1
    int ok = -1, i, j, last, nid;
Packit Service 084de1
    const char *p;
Packit Service 084de1
    CONF_VALUE *cv;
Packit Service 084de1
    OPENSSL_STRING row[DB_NUMBER];
Packit Service 084de1
    OPENSSL_STRING *irow = NULL;
Packit Service 084de1
    OPENSSL_STRING *rrow = NULL;
Packit Service 084de1
    char buf[25];
Packit Service 084de1
Packit Service 084de1
    for (i = 0; i < DB_NUMBER; i++)
Packit Service 084de1
        row[i] = NULL;
Packit Service 084de1
Packit Service 084de1
    if (subj) {
Packit Service 084de1
        X509_NAME *n = parse_name(subj, chtype, multirdn);
Packit Service 084de1
Packit Service 084de1
        if (!n) {
Packit Service 084de1
            ERR_print_errors(bio_err);
Packit Service 084de1
            goto end;
Packit Service 084de1
        }
Packit Service 084de1
        X509_REQ_set_subject_name(req, n);
Packit Service 084de1
        X509_NAME_free(n);
Packit Service 084de1
    }
Packit Service 084de1
Packit Service 084de1
    if (default_op)
Packit Service 084de1
        BIO_printf(bio_err, "The Subject's Distinguished Name is as follows\n");
Packit Service 084de1
Packit Service 084de1
    name = X509_REQ_get_subject_name(req);
Packit Service 084de1
    for (i = 0; i < X509_NAME_entry_count(name); i++) {
Packit Service 084de1
        ne = X509_NAME_get_entry(name, i);
Packit Service 084de1
        str = X509_NAME_ENTRY_get_data(ne);
Packit Service 084de1
        obj = X509_NAME_ENTRY_get_object(ne);
Packit Service 084de1
        nid = OBJ_obj2nid(obj);
Packit Service 084de1
Packit Service 084de1
        if (msie_hack) {
Packit Service 084de1
            /* assume all type should be strings */
Packit Service 084de1
Packit Service 084de1
            if (str->type == V_ASN1_UNIVERSALSTRING)
Packit Service 084de1
                ASN1_UNIVERSALSTRING_to_string(str);
Packit Service 084de1
Packit Service 084de1
            if (str->type == V_ASN1_IA5STRING && nid != NID_pkcs9_emailAddress)
Packit Service 084de1
                str->type = V_ASN1_T61STRING;
Packit Service 084de1
Packit Service 084de1
            if (nid == NID_pkcs9_emailAddress
Packit Service 084de1
                && str->type == V_ASN1_PRINTABLESTRING)
Packit Service 084de1
                str->type = V_ASN1_IA5STRING;
Packit Service 084de1
        }
Packit Service 084de1
Packit Service 084de1
        /* If no EMAIL is wanted in the subject */
Packit Service 084de1
        if (nid == NID_pkcs9_emailAddress && !email_dn)
Packit Service 084de1
            continue;
Packit Service 084de1
Packit Service 084de1
        /* check some things */
Packit Service 084de1
        if (nid == NID_pkcs9_emailAddress && str->type != V_ASN1_IA5STRING) {
Packit Service 084de1
            BIO_printf(bio_err,
Packit Service 084de1
                       "\nemailAddress type needs to be of type IA5STRING\n");
Packit Service 084de1
            goto end;
Packit Service 084de1
        }
Packit Service 084de1
        if (str->type != V_ASN1_BMPSTRING && str->type != V_ASN1_UTF8STRING) {
Packit Service 084de1
            j = ASN1_PRINTABLE_type(str->data, str->length);
Packit Service 084de1
            if ((j == V_ASN1_T61STRING && str->type != V_ASN1_T61STRING) ||
Packit Service 084de1
                (j == V_ASN1_IA5STRING && str->type == V_ASN1_PRINTABLESTRING))
Packit Service 084de1
            {
Packit Service 084de1
                BIO_printf(bio_err,
Packit Service 084de1
                           "\nThe string contains characters that are illegal for the ASN.1 type\n");
Packit Service 084de1
                goto end;
Packit Service 084de1
            }
Packit Service 084de1
        }
Packit Service 084de1
Packit Service 084de1
        if (default_op)
Packit Service 084de1
            old_entry_print(obj, str);
Packit Service 084de1
    }
Packit Service 084de1
Packit Service 084de1
    /* Ok, now we check the 'policy' stuff. */
Packit Service 084de1
    if ((subject = X509_NAME_new()) == NULL) {
Packit Service 084de1
        BIO_printf(bio_err, "Memory allocation failure\n");
Packit Service 084de1
        goto end;
Packit Service 084de1
    }
Packit Service 084de1
Packit Service 084de1
    /* take a copy of the issuer name before we mess with it. */
Packit Service 084de1
    if (selfsign)
Packit Service 084de1
        CAname = X509_NAME_dup(name);
Packit Service 084de1
    else
Packit Service 084de1
        CAname = X509_NAME_dup(X509_get_subject_name(x509));
Packit Service 084de1
    if (CAname == NULL)
Packit Service 084de1
        goto end;
Packit Service 084de1
    str = str2 = NULL;
Packit Service 084de1
Packit Service 084de1
    for (i = 0; i < sk_CONF_VALUE_num(policy); i++) {
Packit Service 084de1
        cv = sk_CONF_VALUE_value(policy, i); /* get the object id */
Packit Service 084de1
        if ((j = OBJ_txt2nid(cv->name)) == NID_undef) {
Packit Service 084de1
            BIO_printf(bio_err,
Packit Service 084de1
                       "%s:unknown object type in 'policy' configuration\n",
Packit Service 084de1
                       cv->name);
Packit Service 084de1
            goto end;
Packit Service 084de1
        }
Packit Service 084de1
        obj = OBJ_nid2obj(j);
Packit Service 084de1
Packit Service 084de1
        last = -1;
Packit Service 084de1
        for (;;) {
Packit Service 084de1
            X509_NAME_ENTRY *push = NULL;
Packit Service 084de1
Packit Service 084de1
            /* lookup the object in the supplied name list */
Packit Service 084de1
            j = X509_NAME_get_index_by_OBJ(name, obj, last);
Packit Service 084de1
            if (j < 0) {
Packit Service 084de1
                if (last != -1)
Packit Service 084de1
                    break;
Packit Service 084de1
                tne = NULL;
Packit Service 084de1
            } else {
Packit Service 084de1
                tne = X509_NAME_get_entry(name, j);
Packit Service 084de1
            }
Packit Service 084de1
            last = j;
Packit Service 084de1
Packit Service 084de1
            /* depending on the 'policy', decide what to do. */
Packit Service 084de1
            if (strcmp(cv->value, "optional") == 0) {
Packit Service 084de1
                if (tne != NULL)
Packit Service 084de1
                    push = tne;
Packit Service 084de1
            } else if (strcmp(cv->value, "supplied") == 0) {
Packit Service 084de1
                if (tne == NULL) {
Packit Service 084de1
                    BIO_printf(bio_err,
Packit Service 084de1
                               "The %s field needed to be supplied and was missing\n",
Packit Service 084de1
                               cv->name);
Packit Service 084de1
                    goto end;
Packit Service 084de1
                } else {
Packit Service 084de1
                    push = tne;
Packit Service 084de1
                }
Packit Service 084de1
            } else if (strcmp(cv->value, "match") == 0) {
Packit Service 084de1
                int last2;
Packit Service 084de1
Packit Service 084de1
                if (tne == NULL) {
Packit Service 084de1
                    BIO_printf(bio_err,
Packit Service 084de1
                               "The mandatory %s field was missing\n",
Packit Service 084de1
                               cv->name);
Packit Service 084de1
                    goto end;
Packit Service 084de1
                }
Packit Service 084de1
Packit Service 084de1
                last2 = -1;
Packit Service 084de1
Packit Service 084de1
 again2:
Packit Service 084de1
                j = X509_NAME_get_index_by_OBJ(CAname, obj, last2);
Packit Service 084de1
                if ((j < 0) && (last2 == -1)) {
Packit Service 084de1
                    BIO_printf(bio_err,
Packit Service 084de1
                               "The %s field does not exist in the CA certificate,\n"
Packit Service 084de1
                               "the 'policy' is misconfigured\n", cv->name);
Packit Service 084de1
                    goto end;
Packit Service 084de1
                }
Packit Service 084de1
                if (j >= 0) {
Packit Service 084de1
                    push = X509_NAME_get_entry(CAname, j);
Packit Service 084de1
                    str = X509_NAME_ENTRY_get_data(tne);
Packit Service 084de1
                    str2 = X509_NAME_ENTRY_get_data(push);
Packit Service 084de1
                    last2 = j;
Packit Service 084de1
                    if (ASN1_STRING_cmp(str, str2) != 0)
Packit Service 084de1
                        goto again2;
Packit Service 084de1
                }
Packit Service 084de1
                if (j < 0) {
Packit Service 084de1
                    BIO_printf(bio_err,
Packit Service 084de1
                               "The %s field is different between\n"
Packit Service 084de1
                               "CA certificate (%s) and the request (%s)\n",
Packit Service 084de1
                               cv->name,
Packit Service 084de1
                               ((str2 == NULL) ? "NULL" : (char *)str2->data),
Packit Service 084de1
                               ((str == NULL) ? "NULL" : (char *)str->data));
Packit Service 084de1
                    goto end;
Packit Service 084de1
                }
Packit Service 084de1
            } else {
Packit Service 084de1
                BIO_printf(bio_err,
Packit Service 084de1
                           "%s:invalid type in 'policy' configuration\n",
Packit Service 084de1
                           cv->value);
Packit Service 084de1
                goto end;
Packit Service 084de1
            }
Packit Service 084de1
Packit Service 084de1
            if (push != NULL) {
Packit Service 084de1
                if (!X509_NAME_add_entry(subject, push, -1, 0)) {
Packit Service 084de1
                    BIO_printf(bio_err, "Memory allocation failure\n");
Packit Service 084de1
                    goto end;
Packit Service 084de1
                }
Packit Service 084de1
            }
Packit Service 084de1
            if (j < 0)
Packit Service 084de1
                break;
Packit Service 084de1
        }
Packit Service 084de1
    }
Packit Service 084de1
Packit Service 084de1
    if (preserve) {
Packit Service 084de1
        X509_NAME_free(subject);
Packit Service 084de1
        /* subject=X509_NAME_dup(X509_REQ_get_subject_name(req)); */
Packit Service 084de1
        subject = X509_NAME_dup(name);
Packit Service 084de1
        if (subject == NULL)
Packit Service 084de1
            goto end;
Packit Service 084de1
    }
Packit Service 084de1
Packit Service 084de1
    /* We are now totally happy, lets make and sign the certificate */
Packit Service 084de1
    if (verbose)
Packit Service 084de1
        BIO_printf(bio_err,
Packit Service 084de1
                   "Everything appears to be ok, creating and signing the certificate\n");
Packit Service 084de1
Packit Service 084de1
    if ((ret = X509_new()) == NULL)
Packit Service 084de1
        goto end;
Packit Service 084de1
Packit Service 084de1
#ifdef X509_V3
Packit Service 084de1
    /* Make it an X509 v3 certificate. */
Packit Service 084de1
    if (!X509_set_version(ret, 2))
Packit Service 084de1
        goto end;
Packit Service 084de1
#endif
Packit Service 084de1
Packit Service 084de1
    if (BN_to_ASN1_INTEGER(serial, X509_get_serialNumber(ret)) == NULL)
Packit Service 084de1
        goto end;
Packit Service 084de1
    if (selfsign) {
Packit Service 084de1
        if (!X509_set_issuer_name(ret, subject))
Packit Service 084de1
            goto end;
Packit Service 084de1
    } else {
Packit Service 084de1
        if (!X509_set_issuer_name(ret, X509_get_subject_name(x509)))
Packit Service 084de1
            goto end;
Packit Service 084de1
    }
Packit Service 084de1
Packit Service 084de1
    if (!set_cert_times(ret, startdate, enddate, days))
Packit Service 084de1
        goto end;
Packit Service 084de1
Packit Service 084de1
    if (enddate != NULL) {
Packit Service 084de1
        int tdays;
Packit Service 084de1
Packit Service 084de1
        if (!ASN1_TIME_diff(&tdays, NULL, NULL, X509_get0_notAfter(ret)))
Packit Service 084de1
            goto end;
Packit Service 084de1
        days = tdays;
Packit Service 084de1
    }
Packit Service 084de1
Packit Service 084de1
    if (!X509_set_subject_name(ret, subject))
Packit Service 084de1
        goto end;
Packit Service 084de1
Packit Service 084de1
    pktmp = X509_REQ_get0_pubkey(req);
Packit Service 084de1
    i = X509_set_pubkey(ret, pktmp);
Packit Service 084de1
    if (!i)
Packit Service 084de1
        goto end;
Packit Service 084de1
Packit Service 084de1
    /* Lets add the extensions, if there are any */
Packit Service 084de1
    if (ext_sect) {
Packit Service 084de1
        X509V3_CTX ctx;
Packit Service 084de1
Packit Service 084de1
        /* Initialize the context structure */
Packit Service 084de1
        if (selfsign)
Packit Service 084de1
            X509V3_set_ctx(&ctx, ret, ret, req, NULL, 0);
Packit Service 084de1
        else
Packit Service 084de1
            X509V3_set_ctx(&ctx, x509, ret, req, NULL, 0);
Packit Service 084de1
Packit Service 084de1
        if (extconf != NULL) {
Packit Service 084de1
            if (verbose)
Packit Service 084de1
                BIO_printf(bio_err, "Extra configuration file found\n");
Packit Service 084de1
Packit Service 084de1
            /* Use the extconf configuration db LHASH */
Packit Service 084de1
            X509V3_set_nconf(&ctx, extconf);
Packit Service 084de1
Packit Service 084de1
            /* Test the structure (needed?) */
Packit Service 084de1
            /* X509V3_set_ctx_test(&ctx;; */
Packit Service 084de1
Packit Service 084de1
            /* Adds exts contained in the configuration file */
Packit Service 084de1
            if (!X509V3_EXT_add_nconf(extconf, &ctx, ext_sect, ret)) {
Packit Service 084de1
                BIO_printf(bio_err,
Packit Service 084de1
                           "ERROR: adding extensions in section %s\n",
Packit Service 084de1
                           ext_sect);
Packit Service 084de1
                ERR_print_errors(bio_err);
Packit Service 084de1
                goto end;
Packit Service 084de1
            }
Packit Service 084de1
            if (verbose)
Packit Service 084de1
                BIO_printf(bio_err,
Packit Service 084de1
                           "Successfully added extensions from file.\n");
Packit Service 084de1
        } else if (ext_sect) {
Packit Service 084de1
            /* We found extensions to be set from config file */
Packit Service 084de1
            X509V3_set_nconf(&ctx, lconf);
Packit Service 084de1
Packit Service 084de1
            if (!X509V3_EXT_add_nconf(lconf, &ctx, ext_sect, ret)) {
Packit Service 084de1
                BIO_printf(bio_err,
Packit Service 084de1
                           "ERROR: adding extensions in section %s\n",
Packit Service 084de1
                           ext_sect);
Packit Service 084de1
                ERR_print_errors(bio_err);
Packit Service 084de1
                goto end;
Packit Service 084de1
            }
Packit Service 084de1
Packit Service 084de1
            if (verbose)
Packit Service 084de1
                BIO_printf(bio_err,
Packit Service 084de1
                           "Successfully added extensions from config\n");
Packit Service 084de1
        }
Packit Service 084de1
    }
Packit Service 084de1
Packit Service 084de1
    /* Copy extensions from request (if any) */
Packit Service 084de1
Packit Service 084de1
    if (!copy_extensions(ret, req, ext_copy)) {
Packit Service 084de1
        BIO_printf(bio_err, "ERROR: adding extensions from request\n");
Packit Service 084de1
        ERR_print_errors(bio_err);
Packit Service 084de1
        goto end;
Packit Service 084de1
    }
Packit Service 084de1
Packit Service 084de1
    {
Packit Service 084de1
        const STACK_OF(X509_EXTENSION) *exts = X509_get0_extensions(ret);
Packit Service 084de1
Packit Service 084de1
        if (exts != NULL && sk_X509_EXTENSION_num(exts) > 0)
Packit Service 084de1
            /* Make it an X509 v3 certificate. */
Packit Service 084de1
            if (!X509_set_version(ret, 2))
Packit Service 084de1
                goto end;
Packit Service 084de1
    }
Packit Service 084de1
Packit Service 084de1
    if (verbose)
Packit Service 084de1
        BIO_printf(bio_err,
Packit Service 084de1
                   "The subject name appears to be ok, checking data base for clashes\n");
Packit Service 084de1
Packit Service 084de1
    /* Build the correct Subject if no e-mail is wanted in the subject. */
Packit Service 084de1
    if (!email_dn) {
Packit Service 084de1
        X509_NAME_ENTRY *tmpne;
Packit Service 084de1
        X509_NAME *dn_subject;
Packit Service 084de1
Packit Service 084de1
        /*
Packit Service 084de1
         * Its best to dup the subject DN and then delete any email addresses
Packit Service 084de1
         * because this retains its structure.
Packit Service 084de1
         */
Packit Service 084de1
        if ((dn_subject = X509_NAME_dup(subject)) == NULL) {
Packit Service 084de1
            BIO_printf(bio_err, "Memory allocation failure\n");
Packit Service 084de1
            goto end;
Packit Service 084de1
        }
Packit Service 084de1
        i = -1;
Packit Service 084de1
        while ((i = X509_NAME_get_index_by_NID(dn_subject,
Packit Service 084de1
                                               NID_pkcs9_emailAddress,
Packit Service 084de1
                                               i)) >= 0) {
Packit Service 084de1
            tmpne = X509_NAME_delete_entry(dn_subject, i--);
Packit Service 084de1
            X509_NAME_ENTRY_free(tmpne);
Packit Service 084de1
        }
Packit Service 084de1
Packit Service 084de1
        if (!X509_set_subject_name(ret, dn_subject)) {
Packit Service 084de1
            X509_NAME_free(dn_subject);
Packit Service 084de1
            goto end;
Packit Service 084de1
        }
Packit Service 084de1
        X509_NAME_free(dn_subject);
Packit Service 084de1
    }
Packit Service 084de1
Packit Service 084de1
    row[DB_name] = X509_NAME_oneline(X509_get_subject_name(ret), NULL, 0);
Packit Service 084de1
    if (row[DB_name] == NULL) {
Packit Service 084de1
        BIO_printf(bio_err, "Memory allocation failure\n");
Packit Service 084de1
        goto end;
Packit Service 084de1
    }
Packit Service 084de1
Packit Service 084de1
    if (BN_is_zero(serial))
Packit Service 084de1
        row[DB_serial] = OPENSSL_strdup("00");
Packit Service 084de1
    else
Packit Service 084de1
        row[DB_serial] = BN_bn2hex(serial);
Packit Service 084de1
    if (row[DB_serial] == NULL) {
Packit Service 084de1
        BIO_printf(bio_err, "Memory allocation failure\n");
Packit Service 084de1
        goto end;
Packit Service 084de1
    }
Packit Service 084de1
Packit Service 084de1
    if (row[DB_name][0] == '\0') {
Packit Service 084de1
        /*
Packit Service 084de1
         * An empty subject! We'll use the serial number instead. If
Packit Service 084de1
         * unique_subject is in use then we don't want different entries with
Packit Service 084de1
         * empty subjects matching each other.
Packit Service 084de1
         */
Packit Service 084de1
        OPENSSL_free(row[DB_name]);
Packit Service 084de1
        row[DB_name] = OPENSSL_strdup(row[DB_serial]);
Packit Service 084de1
        if (row[DB_name] == NULL) {
Packit Service 084de1
            BIO_printf(bio_err, "Memory allocation failure\n");
Packit Service 084de1
            goto end;
Packit Service 084de1
        }
Packit Service 084de1
    }
Packit Service 084de1
Packit Service 084de1
    if (db->attributes.unique_subject) {
Packit Service 084de1
        OPENSSL_STRING *crow = row;
Packit Service 084de1
Packit Service 084de1
        rrow = TXT_DB_get_by_index(db->db, DB_name, crow);
Packit Service 084de1
        if (rrow != NULL) {
Packit Service 084de1
            BIO_printf(bio_err,
Packit Service 084de1
                       "ERROR:There is already a certificate for %s\n",
Packit Service 084de1
                       row[DB_name]);
Packit Service 084de1
        }
Packit Service 084de1
    }
Packit Service 084de1
    if (rrow == NULL) {
Packit Service 084de1
        rrow = TXT_DB_get_by_index(db->db, DB_serial, row);
Packit Service 084de1
        if (rrow != NULL) {
Packit Service 084de1
            BIO_printf(bio_err,
Packit Service 084de1
                       "ERROR:Serial number %s has already been issued,\n",
Packit Service 084de1
                       row[DB_serial]);
Packit Service 084de1
            BIO_printf(bio_err,
Packit Service 084de1
                       "      check the database/serial_file for corruption\n");
Packit Service 084de1
        }
Packit Service 084de1
    }
Packit Service 084de1
Packit Service 084de1
    if (rrow != NULL) {
Packit Service 084de1
        BIO_printf(bio_err, "The matching entry has the following details\n");
Packit Service 084de1
        if (rrow[DB_type][0] == DB_TYPE_EXP)
Packit Service 084de1
            p = "Expired";
Packit Service 084de1
        else if (rrow[DB_type][0] == DB_TYPE_REV)
Packit Service 084de1
            p = "Revoked";
Packit Service 084de1
        else if (rrow[DB_type][0] == DB_TYPE_VAL)
Packit Service 084de1
            p = "Valid";
Packit Service 084de1
        else
Packit Service 084de1
            p = "\ninvalid type, Data base error\n";
Packit Service 084de1
        BIO_printf(bio_err, "Type          :%s\n", p);;
Packit Service 084de1
        if (rrow[DB_type][0] == DB_TYPE_REV) {
Packit Service 084de1
            p = rrow[DB_exp_date];
Packit Service 084de1
            if (p == NULL)
Packit Service 084de1
                p = "undef";
Packit Service 084de1
            BIO_printf(bio_err, "Was revoked on:%s\n", p);
Packit Service 084de1
        }
Packit Service 084de1
        p = rrow[DB_exp_date];
Packit Service 084de1
        if (p == NULL)
Packit Service 084de1
            p = "undef";
Packit Service 084de1
        BIO_printf(bio_err, "Expires on    :%s\n", p);
Packit Service 084de1
        p = rrow[DB_serial];
Packit Service 084de1
        if (p == NULL)
Packit Service 084de1
            p = "undef";
Packit Service 084de1
        BIO_printf(bio_err, "Serial Number :%s\n", p);
Packit Service 084de1
        p = rrow[DB_file];
Packit Service 084de1
        if (p == NULL)
Packit Service 084de1
            p = "undef";
Packit Service 084de1
        BIO_printf(bio_err, "File name     :%s\n", p);
Packit Service 084de1
        p = rrow[DB_name];
Packit Service 084de1
        if (p == NULL)
Packit Service 084de1
            p = "undef";
Packit Service 084de1
        BIO_printf(bio_err, "Subject Name  :%s\n", p);
Packit Service 084de1
        ok = -1;                /* This is now a 'bad' error. */
Packit Service 084de1
        goto end;
Packit Service 084de1
    }
Packit Service 084de1
Packit Service 084de1
    if (!default_op) {
Packit Service 084de1
        BIO_printf(bio_err, "Certificate Details:\n");
Packit Service 084de1
        /*
Packit Service 084de1
         * Never print signature details because signature not present
Packit Service 084de1
         */
Packit Service 084de1
        certopt |= X509_FLAG_NO_SIGDUMP | X509_FLAG_NO_SIGNAME;
Packit Service 084de1
        X509_print_ex(bio_err, ret, nameopt, certopt);
Packit Service 084de1
    }
Packit Service 084de1
Packit Service 084de1
    BIO_printf(bio_err, "Certificate is to be certified until ");
Packit Service 084de1
    ASN1_TIME_print(bio_err, X509_get0_notAfter(ret));
Packit Service 084de1
    if (days)
Packit Service 084de1
        BIO_printf(bio_err, " (%ld days)", days);
Packit Service 084de1
    BIO_printf(bio_err, "\n");
Packit Service 084de1
Packit Service 084de1
    if (!batch) {
Packit Service 084de1
Packit Service 084de1
        BIO_printf(bio_err, "Sign the certificate? [y/n]:");
Packit Service 084de1
        (void)BIO_flush(bio_err);
Packit Service 084de1
        buf[0] = '\0';
Packit Service 084de1
        if (fgets(buf, sizeof(buf), stdin) == NULL) {
Packit Service 084de1
            BIO_printf(bio_err,
Packit Service 084de1
                       "CERTIFICATE WILL NOT BE CERTIFIED: I/O error\n");
Packit Service 084de1
            ok = 0;
Packit Service 084de1
            goto end;
Packit Service 084de1
        }
Packit Service 084de1
        if (!(buf[0] == 'y' || buf[0] == 'Y')) {
Packit Service 084de1
            BIO_printf(bio_err, "CERTIFICATE WILL NOT BE CERTIFIED\n");
Packit Service 084de1
            ok = 0;
Packit Service 084de1
            goto end;
Packit Service 084de1
        }
Packit Service 084de1
    }
Packit Service 084de1
Packit Service 084de1
    pktmp = X509_get0_pubkey(ret);
Packit Service 084de1
    if (EVP_PKEY_missing_parameters(pktmp) &&
Packit Service 084de1
        !EVP_PKEY_missing_parameters(pkey))
Packit Service 084de1
        EVP_PKEY_copy_parameters(pktmp, pkey);
Packit Service 084de1
Packit Service 084de1
    if (!do_X509_sign(ret, pkey, dgst, sigopts))
Packit Service 084de1
        goto end;
Packit Service 084de1
Packit Service 084de1
    /* We now just add it to the database as DB_TYPE_VAL('V') */
Packit Service 084de1
    row[DB_type] = OPENSSL_strdup("V");
Packit Service 084de1
    tm = X509_get0_notAfter(ret);
Packit Service 084de1
    row[DB_exp_date] = app_malloc(tm->length + 1, "row expdate");
Packit Service 084de1
    memcpy(row[DB_exp_date], tm->data, tm->length);
Packit Service 084de1
    row[DB_exp_date][tm->length] = '\0';
Packit Service 084de1
    row[DB_rev_date] = NULL;
Packit Service 084de1
    row[DB_file] = OPENSSL_strdup("unknown");
Packit Service 084de1
    if ((row[DB_type] == NULL) || (row[DB_exp_date] == NULL) ||
Packit Service 084de1
        (row[DB_file] == NULL) || (row[DB_name] == NULL)) {
Packit Service 084de1
        BIO_printf(bio_err, "Memory allocation failure\n");
Packit Service 084de1
        goto end;
Packit Service 084de1
    }
Packit Service 084de1
Packit Service 084de1
    irow = app_malloc(sizeof(*irow) * (DB_NUMBER + 1), "row space");
Packit Service 084de1
    for (i = 0; i < DB_NUMBER; i++)
Packit Service 084de1
        irow[i] = row[i];
Packit Service 084de1
    irow[DB_NUMBER] = NULL;
Packit Service 084de1
Packit Service 084de1
    if (!TXT_DB_insert(db->db, irow)) {
Packit Service 084de1
        BIO_printf(bio_err, "failed to update database\n");
Packit Service 084de1
        BIO_printf(bio_err, "TXT_DB error number %ld\n", db->db->error);
Packit Service 084de1
        goto end;
Packit Service 084de1
    }
Packit Service 084de1
    irow = NULL;
Packit Service 084de1
    ok = 1;
Packit Service 084de1
 end:
Packit Service 084de1
    if (ok != 1) {
Packit Service 084de1
        for (i = 0; i < DB_NUMBER; i++)
Packit Service 084de1
            OPENSSL_free(row[i]);
Packit Service 084de1
    }
Packit Service 084de1
    OPENSSL_free(irow);
Packit Service 084de1
Packit Service 084de1
    X509_NAME_free(CAname);
Packit Service 084de1
    X509_NAME_free(subject);
Packit Service 084de1
    if (ok <= 0)
Packit Service 084de1
        X509_free(ret);
Packit Service 084de1
    else
Packit Service 084de1
        *xret = ret;
Packit Service 084de1
    return ok;
Packit Service 084de1
}
Packit Service 084de1
Packit Service 084de1
static void write_new_certificate(BIO *bp, X509 *x, int output_der, int notext)
Packit Service 084de1
{
Packit Service 084de1
Packit Service 084de1
    if (output_der) {
Packit Service 084de1
        (void)i2d_X509_bio(bp, x);
Packit Service 084de1
        return;
Packit Service 084de1
    }
Packit Service 084de1
    if (!notext)
Packit Service 084de1
        X509_print(bp, x);
Packit Service 084de1
    PEM_write_bio_X509(bp, x);
Packit Service 084de1
}
Packit Service 084de1
Packit Service 084de1
static int certify_spkac(X509 **xret, const char *infile, EVP_PKEY *pkey,
Packit Service 084de1
                         X509 *x509, const EVP_MD *dgst,
Packit Service 084de1
                         STACK_OF(OPENSSL_STRING) *sigopts,
Packit Service 084de1
                         STACK_OF(CONF_VALUE) *policy, CA_DB *db,
Packit Service 084de1
                         BIGNUM *serial, const char *subj, unsigned long chtype,
Packit Service 084de1
                         int multirdn, int email_dn, const char *startdate,
Packit Service 084de1
                         const char *enddate, long days, const char *ext_sect,
Packit Service 084de1
                         CONF *lconf, int verbose, unsigned long certopt,
Packit Service 084de1
                         unsigned long nameopt, int default_op, int ext_copy)
Packit Service 084de1
{
Packit Service 084de1
    STACK_OF(CONF_VALUE) *sk = NULL;
Packit Service 084de1
    LHASH_OF(CONF_VALUE) *parms = NULL;
Packit Service 084de1
    X509_REQ *req = NULL;
Packit Service 084de1
    CONF_VALUE *cv = NULL;
Packit Service 084de1
    NETSCAPE_SPKI *spki = NULL;
Packit Service 084de1
    char *type, *buf;
Packit Service 084de1
    EVP_PKEY *pktmp = NULL;
Packit Service 084de1
    X509_NAME *n = NULL;
Packit Service 084de1
    X509_NAME_ENTRY *ne = NULL;
Packit Service 084de1
    int ok = -1, i, j;
Packit Service 084de1
    long errline;
Packit Service 084de1
    int nid;
Packit Service 084de1
Packit Service 084de1
    /*
Packit Service 084de1
     * Load input file into a hash table.  (This is just an easy
Packit Service 084de1
     * way to read and parse the file, then put it into a convenient
Packit Service 084de1
     * STACK format).
Packit Service 084de1
     */
Packit Service 084de1
    parms = CONF_load(NULL, infile, &errline);
Packit Service 084de1
    if (parms == NULL) {
Packit Service 084de1
        BIO_printf(bio_err, "error on line %ld of %s\n", errline, infile);
Packit Service 084de1
        ERR_print_errors(bio_err);
Packit Service 084de1
        goto end;
Packit Service 084de1
    }
Packit Service 084de1
Packit Service 084de1
    sk = CONF_get_section(parms, "default");
Packit Service 084de1
    if (sk_CONF_VALUE_num(sk) == 0) {
Packit Service 084de1
        BIO_printf(bio_err, "no name/value pairs found in %s\n", infile);
Packit Service 084de1
        goto end;
Packit Service 084de1
    }
Packit Service 084de1
Packit Service 084de1
    /*
Packit Service 084de1
     * Now create a dummy X509 request structure.  We don't actually
Packit Service 084de1
     * have an X509 request, but we have many of the components
Packit Service 084de1
     * (a public key, various DN components).  The idea is that we
Packit Service 084de1
     * put these components into the right X509 request structure
Packit Service 084de1
     * and we can use the same code as if you had a real X509 request.
Packit Service 084de1
     */
Packit Service 084de1
    req = X509_REQ_new();
Packit Service 084de1
    if (req == NULL) {
Packit Service 084de1
        ERR_print_errors(bio_err);
Packit Service 084de1
        goto end;
Packit Service 084de1
    }
Packit Service 084de1
Packit Service 084de1
    /*
Packit Service 084de1
     * Build up the subject name set.
Packit Service 084de1
     */
Packit Service 084de1
    n = X509_REQ_get_subject_name(req);
Packit Service 084de1
Packit Service 084de1
    for (i = 0;; i++) {
Packit Service 084de1
        if (sk_CONF_VALUE_num(sk) <= i)
Packit Service 084de1
            break;
Packit Service 084de1
Packit Service 084de1
        cv = sk_CONF_VALUE_value(sk, i);
Packit Service 084de1
        type = cv->name;
Packit Service 084de1
        /*
Packit Service 084de1
         * Skip past any leading X. X: X, etc to allow for multiple instances
Packit Service 084de1
         */
Packit Service 084de1
        for (buf = cv->name; *buf; buf++)
Packit Service 084de1
            if ((*buf == ':') || (*buf == ',') || (*buf == '.')) {
Packit Service 084de1
                buf++;
Packit Service 084de1
                if (*buf)
Packit Service 084de1
                    type = buf;
Packit Service 084de1
                break;
Packit Service 084de1
            }
Packit Service 084de1
Packit Service 084de1
        buf = cv->value;
Packit Service 084de1
        if ((nid = OBJ_txt2nid(type)) == NID_undef) {
Packit Service 084de1
            if (strcmp(type, "SPKAC") == 0) {
Packit Service 084de1
                spki = NETSCAPE_SPKI_b64_decode(cv->value, -1);
Packit Service 084de1
                if (spki == NULL) {
Packit Service 084de1
                    BIO_printf(bio_err,
Packit Service 084de1
                               "unable to load Netscape SPKAC structure\n");
Packit Service 084de1
                    ERR_print_errors(bio_err);
Packit Service 084de1
                    goto end;
Packit Service 084de1
                }
Packit Service 084de1
            }
Packit Service 084de1
            continue;
Packit Service 084de1
        }
Packit Service 084de1
Packit Service 084de1
        if (!X509_NAME_add_entry_by_NID(n, nid, chtype,
Packit Service 084de1
                                        (unsigned char *)buf, -1, -1, 0))
Packit Service 084de1
            goto end;
Packit Service 084de1
    }
Packit Service 084de1
    if (spki == NULL) {
Packit Service 084de1
        BIO_printf(bio_err, "Netscape SPKAC structure not found in %s\n",
Packit Service 084de1
                   infile);
Packit Service 084de1
        goto end;
Packit Service 084de1
    }
Packit Service 084de1
Packit Service 084de1
    /*
Packit Service 084de1
     * Now extract the key from the SPKI structure.
Packit Service 084de1
     */
Packit Service 084de1
Packit Service 084de1
    BIO_printf(bio_err, "Check that the SPKAC request matches the signature\n");
Packit Service 084de1
Packit Service 084de1
    if ((pktmp = NETSCAPE_SPKI_get_pubkey(spki)) == NULL) {
Packit Service 084de1
        BIO_printf(bio_err, "error unpacking SPKAC public key\n");
Packit Service 084de1
        goto end;
Packit Service 084de1
    }
Packit Service 084de1
Packit Service 084de1
    j = NETSCAPE_SPKI_verify(spki, pktmp);
Packit Service 084de1
    if (j <= 0) {
Packit Service 084de1
        EVP_PKEY_free(pktmp);
Packit Service 084de1
        BIO_printf(bio_err,
Packit Service 084de1
                   "signature verification failed on SPKAC public key\n");
Packit Service 084de1
        goto end;
Packit Service 084de1
    }
Packit Service 084de1
    BIO_printf(bio_err, "Signature ok\n");
Packit Service 084de1
Packit Service 084de1
    X509_REQ_set_pubkey(req, pktmp);
Packit Service 084de1
    EVP_PKEY_free(pktmp);
Packit Service 084de1
    ok = do_body(xret, pkey, x509, dgst, sigopts, policy, db, serial, subj,
Packit Service 084de1
                 chtype, multirdn, email_dn, startdate, enddate, days, 1,
Packit Service 084de1
                 verbose, req, ext_sect, lconf, certopt, nameopt, default_op,
Packit Service 084de1
                 ext_copy, 0);
Packit Service 084de1
 end:
Packit Service 084de1
    X509_REQ_free(req);
Packit Service 084de1
    CONF_free(parms);
Packit Service 084de1
    NETSCAPE_SPKI_free(spki);
Packit Service 084de1
    X509_NAME_ENTRY_free(ne);
Packit Service 084de1
Packit Service 084de1
    return ok;
Packit Service 084de1
}
Packit Service 084de1
Packit Service 084de1
static int check_time_format(const char *str)
Packit Service 084de1
{
Packit Service 084de1
    return ASN1_TIME_set_string(NULL, str);
Packit Service 084de1
}
Packit Service 084de1
Packit Service 084de1
static int do_revoke(X509 *x509, CA_DB *db, REVINFO_TYPE rev_type,
Packit Service 084de1
                     const char *value)
Packit Service 084de1
{
Packit Service 084de1
    const ASN1_TIME *tm = NULL;
Packit Service 084de1
    char *row[DB_NUMBER], **rrow, **irow;
Packit Service 084de1
    char *rev_str = NULL;
Packit Service 084de1
    BIGNUM *bn = NULL;
Packit Service 084de1
    int ok = -1, i;
Packit Service 084de1
Packit Service 084de1
    for (i = 0; i < DB_NUMBER; i++)
Packit Service 084de1
        row[i] = NULL;
Packit Service 084de1
    row[DB_name] = X509_NAME_oneline(X509_get_subject_name(x509), NULL, 0);
Packit Service 084de1
    bn = ASN1_INTEGER_to_BN(X509_get_serialNumber(x509), NULL);
Packit Service 084de1
    if (!bn)
Packit Service 084de1
        goto end;
Packit Service 084de1
    if (BN_is_zero(bn))
Packit Service 084de1
        row[DB_serial] = OPENSSL_strdup("00");
Packit Service 084de1
    else
Packit Service 084de1
        row[DB_serial] = BN_bn2hex(bn);
Packit Service 084de1
    BN_free(bn);
Packit Service 084de1
    if (row[DB_name] != NULL && row[DB_name][0] == '\0') {
Packit Service 084de1
        /* Entries with empty Subjects actually use the serial number instead */
Packit Service 084de1
        OPENSSL_free(row[DB_name]);
Packit Service 084de1
        row[DB_name] = OPENSSL_strdup(row[DB_serial]);
Packit Service 084de1
    }
Packit Service 084de1
    if ((row[DB_name] == NULL) || (row[DB_serial] == NULL)) {
Packit Service 084de1
        BIO_printf(bio_err, "Memory allocation failure\n");
Packit Service 084de1
        goto end;
Packit Service 084de1
    }
Packit Service 084de1
    /*
Packit Service 084de1
     * We have to lookup by serial number because name lookup skips revoked
Packit Service 084de1
     * certs
Packit Service 084de1
     */
Packit Service 084de1
    rrow = TXT_DB_get_by_index(db->db, DB_serial, row);
Packit Service 084de1
    if (rrow == NULL) {
Packit Service 084de1
        BIO_printf(bio_err,
Packit Service 084de1
                   "Adding Entry with serial number %s to DB for %s\n",
Packit Service 084de1
                   row[DB_serial], row[DB_name]);
Packit Service 084de1
Packit Service 084de1
        /* We now just add it to the database as DB_TYPE_REV('V') */
Packit Service 084de1
        row[DB_type] = OPENSSL_strdup("V");
Packit Service 084de1
        tm = X509_get0_notAfter(x509);
Packit Service 084de1
        row[DB_exp_date] = app_malloc(tm->length + 1, "row exp_data");
Packit Service 084de1
        memcpy(row[DB_exp_date], tm->data, tm->length);
Packit Service 084de1
        row[DB_exp_date][tm->length] = '\0';
Packit Service 084de1
        row[DB_rev_date] = NULL;
Packit Service 084de1
        row[DB_file] = OPENSSL_strdup("unknown");
Packit Service 084de1
Packit Service 084de1
        if (row[DB_type] == NULL || row[DB_file] == NULL) {
Packit Service 084de1
            BIO_printf(bio_err, "Memory allocation failure\n");
Packit Service 084de1
            goto end;
Packit Service 084de1
        }
Packit Service 084de1
Packit Service 084de1
        irow = app_malloc(sizeof(*irow) * (DB_NUMBER + 1), "row ptr");
Packit Service 084de1
        for (i = 0; i < DB_NUMBER; i++)
Packit Service 084de1
            irow[i] = row[i];
Packit Service 084de1
        irow[DB_NUMBER] = NULL;
Packit Service 084de1
Packit Service 084de1
        if (!TXT_DB_insert(db->db, irow)) {
Packit Service 084de1
            BIO_printf(bio_err, "failed to update database\n");
Packit Service 084de1
            BIO_printf(bio_err, "TXT_DB error number %ld\n", db->db->error);
Packit Service 084de1
            OPENSSL_free(irow);
Packit Service 084de1
            goto end;
Packit Service 084de1
        }
Packit Service 084de1
Packit Service 084de1
        for (i = 0; i < DB_NUMBER; i++)
Packit Service 084de1
            row[i] = NULL;
Packit Service 084de1
Packit Service 084de1
        /* Revoke Certificate */
Packit Service 084de1
        if (rev_type == REV_VALID)
Packit Service 084de1
            ok = 1;
Packit Service 084de1
        else
Packit Service 084de1
            /* Retry revocation after DB insertion */
Packit Service 084de1
            ok = do_revoke(x509, db, rev_type, value);
Packit Service 084de1
Packit Service 084de1
        goto end;
Packit Service 084de1
Packit Service 084de1
    } else if (index_name_cmp_noconst(row, rrow)) {
Packit Service 084de1
        BIO_printf(bio_err, "ERROR:name does not match %s\n", row[DB_name]);
Packit Service 084de1
        goto end;
Packit Service 084de1
    } else if (rev_type == REV_VALID) {
Packit Service 084de1
        BIO_printf(bio_err, "ERROR:Already present, serial number %s\n",
Packit Service 084de1
                   row[DB_serial]);
Packit Service 084de1
        goto end;
Packit Service 084de1
    } else if (rrow[DB_type][0] == DB_TYPE_REV) {
Packit Service 084de1
        BIO_printf(bio_err, "ERROR:Already revoked, serial number %s\n",
Packit Service 084de1
                   row[DB_serial]);
Packit Service 084de1
        goto end;
Packit Service 084de1
    } else {
Packit Service 084de1
        BIO_printf(bio_err, "Revoking Certificate %s.\n", rrow[DB_serial]);
Packit Service 084de1
        rev_str = make_revocation_str(rev_type, value);
Packit Service 084de1
        if (!rev_str) {
Packit Service 084de1
            BIO_printf(bio_err, "Error in revocation arguments\n");
Packit Service 084de1
            goto end;
Packit Service 084de1
        }
Packit Service 084de1
        rrow[DB_type][0] = DB_TYPE_REV;
Packit Service 084de1
        rrow[DB_type][1] = '\0';
Packit Service 084de1
        rrow[DB_rev_date] = rev_str;
Packit Service 084de1
    }
Packit Service 084de1
    ok = 1;
Packit Service 084de1
 end:
Packit Service 084de1
    for (i = 0; i < DB_NUMBER; i++)
Packit Service 084de1
        OPENSSL_free(row[i]);
Packit Service 084de1
    return ok;
Packit Service 084de1
}
Packit Service 084de1
Packit Service 084de1
static int get_certificate_status(const char *serial, CA_DB *db)
Packit Service 084de1
{
Packit Service 084de1
    char *row[DB_NUMBER], **rrow;
Packit Service 084de1
    int ok = -1, i;
Packit Service 084de1
    size_t serial_len = strlen(serial);
Packit Service 084de1
Packit Service 084de1
    /* Free Resources */
Packit Service 084de1
    for (i = 0; i < DB_NUMBER; i++)
Packit Service 084de1
        row[i] = NULL;
Packit Service 084de1
Packit Service 084de1
    /* Malloc needed char spaces */
Packit Service 084de1
    row[DB_serial] = app_malloc(serial_len + 2, "row serial#");
Packit Service 084de1
Packit Service 084de1
    if (serial_len % 2) {
Packit Service 084de1
        /*
Packit Service 084de1
         * Set the first char to 0
Packit Service 084de1
         */
Packit Service 084de1
        row[DB_serial][0] = '0';
Packit Service 084de1
Packit Service 084de1
        /* Copy String from serial to row[DB_serial] */
Packit Service 084de1
        memcpy(row[DB_serial] + 1, serial, serial_len);
Packit Service 084de1
        row[DB_serial][serial_len + 1] = '\0';
Packit Service 084de1
    } else {
Packit Service 084de1
        /* Copy String from serial to row[DB_serial] */
Packit Service 084de1
        memcpy(row[DB_serial], serial, serial_len);
Packit Service 084de1
        row[DB_serial][serial_len] = '\0';
Packit Service 084de1
    }
Packit Service 084de1
Packit Service 084de1
    /* Make it Upper Case */
Packit Service 084de1
    make_uppercase(row[DB_serial]);
Packit Service 084de1
Packit Service 084de1
    ok = 1;
Packit Service 084de1
Packit Service 084de1
    /* Search for the certificate */
Packit Service 084de1
    rrow = TXT_DB_get_by_index(db->db, DB_serial, row);
Packit Service 084de1
    if (rrow == NULL) {
Packit Service 084de1
        BIO_printf(bio_err, "Serial %s not present in db.\n", row[DB_serial]);
Packit Service 084de1
        ok = -1;
Packit Service 084de1
        goto end;
Packit Service 084de1
    } else if (rrow[DB_type][0] == DB_TYPE_VAL) {
Packit Service 084de1
        BIO_printf(bio_err, "%s=Valid (%c)\n",
Packit Service 084de1
                   row[DB_serial], rrow[DB_type][0]);
Packit Service 084de1
        goto end;
Packit Service 084de1
    } else if (rrow[DB_type][0] == DB_TYPE_REV) {
Packit Service 084de1
        BIO_printf(bio_err, "%s=Revoked (%c)\n",
Packit Service 084de1
                   row[DB_serial], rrow[DB_type][0]);
Packit Service 084de1
        goto end;
Packit Service 084de1
    } else if (rrow[DB_type][0] == DB_TYPE_EXP) {
Packit Service 084de1
        BIO_printf(bio_err, "%s=Expired (%c)\n",
Packit Service 084de1
                   row[DB_serial], rrow[DB_type][0]);
Packit Service 084de1
        goto end;
Packit Service 084de1
    } else if (rrow[DB_type][0] == DB_TYPE_SUSP) {
Packit Service 084de1
        BIO_printf(bio_err, "%s=Suspended (%c)\n",
Packit Service 084de1
                   row[DB_serial], rrow[DB_type][0]);
Packit Service 084de1
        goto end;
Packit Service 084de1
    } else {
Packit Service 084de1
        BIO_printf(bio_err, "%s=Unknown (%c).\n",
Packit Service 084de1
                   row[DB_serial], rrow[DB_type][0]);
Packit Service 084de1
        ok = -1;
Packit Service 084de1
    }
Packit Service 084de1
 end:
Packit Service 084de1
    for (i = 0; i < DB_NUMBER; i++) {
Packit Service 084de1
        OPENSSL_free(row[i]);
Packit Service 084de1
    }
Packit Service 084de1
    return ok;
Packit Service 084de1
}
Packit Service 084de1
Packit Service 084de1
static int do_updatedb(CA_DB *db)
Packit Service 084de1
{
Packit Service 084de1
    ASN1_UTCTIME *a_tm = NULL;
Packit Service 084de1
    int i, cnt = 0;
Packit Service 084de1
    int db_y2k, a_y2k;          /* flags = 1 if y >= 2000 */
Packit Service 084de1
    char **rrow, *a_tm_s;
Packit Service 084de1
Packit Service 084de1
    a_tm = ASN1_UTCTIME_new();
Packit Service 084de1
    if (a_tm == NULL)
Packit Service 084de1
        return -1;
Packit Service 084de1
Packit Service 084de1
    /* get actual time and make a string */
Packit Service 084de1
    if (X509_gmtime_adj(a_tm, 0) == NULL) {
Packit Service 084de1
        ASN1_UTCTIME_free(a_tm);
Packit Service 084de1
        return -1;
Packit Service 084de1
    }
Packit Service 084de1
    a_tm_s = app_malloc(a_tm->length + 1, "time string");
Packit Service 084de1
Packit Service 084de1
    memcpy(a_tm_s, a_tm->data, a_tm->length);
Packit Service 084de1
    a_tm_s[a_tm->length] = '\0';
Packit Service 084de1
Packit Service 084de1
    if (strncmp(a_tm_s, "49", 2) <= 0)
Packit Service 084de1
        a_y2k = 1;
Packit Service 084de1
    else
Packit Service 084de1
        a_y2k = 0;
Packit Service 084de1
Packit Service 084de1
    for (i = 0; i < sk_OPENSSL_PSTRING_num(db->db->data); i++) {
Packit Service 084de1
        rrow = sk_OPENSSL_PSTRING_value(db->db->data, i);
Packit Service 084de1
Packit Service 084de1
        if (rrow[DB_type][0] == DB_TYPE_VAL) {
Packit Service 084de1
            /* ignore entries that are not valid */
Packit Service 084de1
            if (strncmp(rrow[DB_exp_date], "49", 2) <= 0)
Packit Service 084de1
                db_y2k = 1;
Packit Service 084de1
            else
Packit Service 084de1
                db_y2k = 0;
Packit Service 084de1
Packit Service 084de1
            if (db_y2k == a_y2k) {
Packit Service 084de1
                /* all on the same y2k side */
Packit Service 084de1
                if (strcmp(rrow[DB_exp_date], a_tm_s) <= 0) {
Packit Service 084de1
                    rrow[DB_type][0] = DB_TYPE_EXP;
Packit Service 084de1
                    rrow[DB_type][1] = '\0';
Packit Service 084de1
                    cnt++;
Packit Service 084de1
Packit Service 084de1
                    BIO_printf(bio_err, "%s=Expired\n", rrow[DB_serial]);
Packit Service 084de1
                }
Packit Service 084de1
            } else if (db_y2k < a_y2k) {
Packit Service 084de1
                rrow[DB_type][0] = DB_TYPE_EXP;
Packit Service 084de1
                rrow[DB_type][1] = '\0';
Packit Service 084de1
                cnt++;
Packit Service 084de1
Packit Service 084de1
                BIO_printf(bio_err, "%s=Expired\n", rrow[DB_serial]);
Packit Service 084de1
            }
Packit Service 084de1
Packit Service 084de1
        }
Packit Service 084de1
    }
Packit Service 084de1
Packit Service 084de1
    ASN1_UTCTIME_free(a_tm);
Packit Service 084de1
    OPENSSL_free(a_tm_s);
Packit Service 084de1
    return cnt;
Packit Service 084de1
}
Packit Service 084de1
Packit Service 084de1
static const char *crl_reasons[] = {
Packit Service 084de1
    /* CRL reason strings */
Packit Service 084de1
    "unspecified",
Packit Service 084de1
    "keyCompromise",
Packit Service 084de1
    "CACompromise",
Packit Service 084de1
    "affiliationChanged",
Packit Service 084de1
    "superseded",
Packit Service 084de1
    "cessationOfOperation",
Packit Service 084de1
    "certificateHold",
Packit Service 084de1
    "removeFromCRL",
Packit Service 084de1
    /* Additional pseudo reasons */
Packit Service 084de1
    "holdInstruction",
Packit Service 084de1
    "keyTime",
Packit Service 084de1
    "CAkeyTime"
Packit Service 084de1
};
Packit Service 084de1
Packit Service 084de1
#define NUM_REASONS OSSL_NELEM(crl_reasons)
Packit Service 084de1
Packit Service 084de1
/*
Packit Service 084de1
 * Given revocation information convert to a DB string. The format of the
Packit Service 084de1
 * string is: revtime[,reason,extra]. Where 'revtime' is the revocation time
Packit Service 084de1
 * (the current time). 'reason' is the optional CRL reason and 'extra' is any
Packit Service 084de1
 * additional argument
Packit Service 084de1
 */
Packit Service 084de1
Packit Service 084de1
static char *make_revocation_str(REVINFO_TYPE rev_type, const char *rev_arg)
Packit Service 084de1
{
Packit Service 084de1
    char *str;
Packit Service 084de1
    const char *reason = NULL, *other = NULL;
Packit Service 084de1
    ASN1_OBJECT *otmp;
Packit Service 084de1
    ASN1_UTCTIME *revtm = NULL;
Packit Service 084de1
    int i;
Packit Service 084de1
Packit Service 084de1
    switch (rev_type) {
Packit Service 084de1
    case REV_NONE:
Packit Service 084de1
    case REV_VALID:
Packit Service 084de1
        break;
Packit Service 084de1
Packit Service 084de1
    case REV_CRL_REASON:
Packit Service 084de1
        for (i = 0; i < 8; i++) {
Packit Service 084de1
            if (strcasecmp(rev_arg, crl_reasons[i]) == 0) {
Packit Service 084de1
                reason = crl_reasons[i];
Packit Service 084de1
                break;
Packit Service 084de1
            }
Packit Service 084de1
        }
Packit Service 084de1
        if (reason == NULL) {
Packit Service 084de1
            BIO_printf(bio_err, "Unknown CRL reason %s\n", rev_arg);
Packit Service 084de1
            return NULL;
Packit Service 084de1
        }
Packit Service 084de1
        break;
Packit Service 084de1
Packit Service 084de1
    case REV_HOLD:
Packit Service 084de1
        /* Argument is an OID */
Packit Service 084de1
        otmp = OBJ_txt2obj(rev_arg, 0);
Packit Service 084de1
        ASN1_OBJECT_free(otmp);
Packit Service 084de1
Packit Service 084de1
        if (otmp == NULL) {
Packit Service 084de1
            BIO_printf(bio_err, "Invalid object identifier %s\n", rev_arg);
Packit Service 084de1
            return NULL;
Packit Service 084de1
        }
Packit Service 084de1
Packit Service 084de1
        reason = "holdInstruction";
Packit Service 084de1
        other = rev_arg;
Packit Service 084de1
        break;
Packit Service 084de1
Packit Service 084de1
    case REV_KEY_COMPROMISE:
Packit Service 084de1
    case REV_CA_COMPROMISE:
Packit Service 084de1
        /* Argument is the key compromise time  */
Packit Service 084de1
        if (!ASN1_GENERALIZEDTIME_set_string(NULL, rev_arg)) {
Packit Service 084de1
            BIO_printf(bio_err,
Packit Service 084de1
                       "Invalid time format %s. Need YYYYMMDDHHMMSSZ\n",
Packit Service 084de1
                       rev_arg);
Packit Service 084de1
            return NULL;
Packit Service 084de1
        }
Packit Service 084de1
        other = rev_arg;
Packit Service 084de1
        if (rev_type == REV_KEY_COMPROMISE)
Packit Service 084de1
            reason = "keyTime";
Packit Service 084de1
        else
Packit Service 084de1
            reason = "CAkeyTime";
Packit Service 084de1
Packit Service 084de1
        break;
Packit Service 084de1
    }
Packit Service 084de1
Packit Service 084de1
    revtm = X509_gmtime_adj(NULL, 0);
Packit Service 084de1
Packit Service 084de1
    if (!revtm)
Packit Service 084de1
        return NULL;
Packit Service 084de1
Packit Service 084de1
    i = revtm->length + 1;
Packit Service 084de1
Packit Service 084de1
    if (reason)
Packit Service 084de1
        i += strlen(reason) + 1;
Packit Service 084de1
    if (other)
Packit Service 084de1
        i += strlen(other) + 1;
Packit Service 084de1
Packit Service 084de1
    str = app_malloc(i, "revocation reason");
Packit Service 084de1
    OPENSSL_strlcpy(str, (char *)revtm->data, i);
Packit Service 084de1
    if (reason) {
Packit Service 084de1
        OPENSSL_strlcat(str, ",", i);
Packit Service 084de1
        OPENSSL_strlcat(str, reason, i);
Packit Service 084de1
    }
Packit Service 084de1
    if (other) {
Packit Service 084de1
        OPENSSL_strlcat(str, ",", i);
Packit Service 084de1
        OPENSSL_strlcat(str, other, i);
Packit Service 084de1
    }
Packit Service 084de1
    ASN1_UTCTIME_free(revtm);
Packit Service 084de1
    return str;
Packit Service 084de1
}
Packit Service 084de1
Packit Service 084de1
/*-
Packit Service 084de1
 * Convert revocation field to X509_REVOKED entry
Packit Service 084de1
 * return code:
Packit Service 084de1
 * 0 error
Packit Service 084de1
 * 1 OK
Packit Service 084de1
 * 2 OK and some extensions added (i.e. V2 CRL)
Packit Service 084de1
 */
Packit Service 084de1
Packit Service 084de1
static int make_revoked(X509_REVOKED *rev, const char *str)
Packit Service 084de1
{
Packit Service 084de1
    char *tmp = NULL;
Packit Service 084de1
    int reason_code = -1;
Packit Service 084de1
    int i, ret = 0;
Packit Service 084de1
    ASN1_OBJECT *hold = NULL;
Packit Service 084de1
    ASN1_GENERALIZEDTIME *comp_time = NULL;
Packit Service 084de1
    ASN1_ENUMERATED *rtmp = NULL;
Packit Service 084de1
Packit Service 084de1
    ASN1_TIME *revDate = NULL;
Packit Service 084de1
Packit Service 084de1
    i = unpack_revinfo(&revDate, &reason_code, &hold, &comp_time, str);
Packit Service 084de1
Packit Service 084de1
    if (i == 0)
Packit Service 084de1
        goto end;
Packit Service 084de1
Packit Service 084de1
    if (rev && !X509_REVOKED_set_revocationDate(rev, revDate))
Packit Service 084de1
        goto end;
Packit Service 084de1
Packit Service 084de1
    if (rev && (reason_code != OCSP_REVOKED_STATUS_NOSTATUS)) {
Packit Service 084de1
        rtmp = ASN1_ENUMERATED_new();
Packit Service 084de1
        if (rtmp == NULL || !ASN1_ENUMERATED_set(rtmp, reason_code))
Packit Service 084de1
            goto end;
Packit Service 084de1
        if (!X509_REVOKED_add1_ext_i2d(rev, NID_crl_reason, rtmp, 0, 0))
Packit Service 084de1
            goto end;
Packit Service 084de1
    }
Packit Service 084de1
Packit Service 084de1
    if (rev && comp_time) {
Packit Service 084de1
        if (!X509_REVOKED_add1_ext_i2d
Packit Service 084de1
            (rev, NID_invalidity_date, comp_time, 0, 0))
Packit Service 084de1
            goto end;
Packit Service 084de1
    }
Packit Service 084de1
    if (rev && hold) {
Packit Service 084de1
        if (!X509_REVOKED_add1_ext_i2d
Packit Service 084de1
            (rev, NID_hold_instruction_code, hold, 0, 0))
Packit Service 084de1
            goto end;
Packit Service 084de1
    }
Packit Service 084de1
Packit Service 084de1
    if (reason_code != OCSP_REVOKED_STATUS_NOSTATUS)
Packit Service 084de1
        ret = 2;
Packit Service 084de1
    else
Packit Service 084de1
        ret = 1;
Packit Service 084de1
Packit Service 084de1
 end:
Packit Service 084de1
Packit Service 084de1
    OPENSSL_free(tmp);
Packit Service 084de1
    ASN1_OBJECT_free(hold);
Packit Service 084de1
    ASN1_GENERALIZEDTIME_free(comp_time);
Packit Service 084de1
    ASN1_ENUMERATED_free(rtmp);
Packit Service 084de1
    ASN1_TIME_free(revDate);
Packit Service 084de1
Packit Service 084de1
    return ret;
Packit Service 084de1
}
Packit Service 084de1
Packit Service 084de1
static int old_entry_print(const ASN1_OBJECT *obj, const ASN1_STRING *str)
Packit Service 084de1
{
Packit Service 084de1
    char buf[25], *pbuf;
Packit Service 084de1
    const char *p;
Packit Service 084de1
    int j;
Packit Service 084de1
Packit Service 084de1
    j = i2a_ASN1_OBJECT(bio_err, obj);
Packit Service 084de1
    pbuf = buf;
Packit Service 084de1
    for (j = 22 - j; j > 0; j--)
Packit Service 084de1
        *(pbuf++) = ' ';
Packit Service 084de1
    *(pbuf++) = ':';
Packit Service 084de1
    *(pbuf++) = '\0';
Packit Service 084de1
    BIO_puts(bio_err, buf);
Packit Service 084de1
Packit Service 084de1
    if (str->type == V_ASN1_PRINTABLESTRING)
Packit Service 084de1
        BIO_printf(bio_err, "PRINTABLE:'");
Packit Service 084de1
    else if (str->type == V_ASN1_T61STRING)
Packit Service 084de1
        BIO_printf(bio_err, "T61STRING:'");
Packit Service 084de1
    else if (str->type == V_ASN1_IA5STRING)
Packit Service 084de1
        BIO_printf(bio_err, "IA5STRING:'");
Packit Service 084de1
    else if (str->type == V_ASN1_UNIVERSALSTRING)
Packit Service 084de1
        BIO_printf(bio_err, "UNIVERSALSTRING:'");
Packit Service 084de1
    else
Packit Service 084de1
        BIO_printf(bio_err, "ASN.1 %2d:'", str->type);
Packit Service 084de1
Packit Service 084de1
    p = (const char *)str->data;
Packit Service 084de1
    for (j = str->length; j > 0; j--) {
Packit Service 084de1
        if ((*p >= ' ') && (*p <= '~'))
Packit Service 084de1
            BIO_printf(bio_err, "%c", *p);
Packit Service 084de1
        else if (*p & 0x80)
Packit Service 084de1
            BIO_printf(bio_err, "\\0x%02X", *p);
Packit Service 084de1
        else if ((unsigned char)*p == 0xf7)
Packit Service 084de1
            BIO_printf(bio_err, "^?");
Packit Service 084de1
        else
Packit Service 084de1
            BIO_printf(bio_err, "^%c", *p + '@');
Packit Service 084de1
        p++;
Packit Service 084de1
    }
Packit Service 084de1
    BIO_printf(bio_err, "'\n");
Packit Service 084de1
    return 1;
Packit Service 084de1
}
Packit Service 084de1
Packit Service 084de1
int unpack_revinfo(ASN1_TIME **prevtm, int *preason, ASN1_OBJECT **phold,
Packit Service 084de1
                   ASN1_GENERALIZEDTIME **pinvtm, const char *str)
Packit Service 084de1
{
Packit Service 084de1
    char *tmp;
Packit Service 084de1
    char *rtime_str, *reason_str = NULL, *arg_str = NULL, *p;
Packit Service 084de1
    int reason_code = -1;
Packit Service 084de1
    int ret = 0;
Packit Service 084de1
    unsigned int i;
Packit Service 084de1
    ASN1_OBJECT *hold = NULL;
Packit Service 084de1
    ASN1_GENERALIZEDTIME *comp_time = NULL;
Packit Service 084de1
Packit Service 084de1
    tmp = OPENSSL_strdup(str);
Packit Service 084de1
    if (!tmp) {
Packit Service 084de1
        BIO_printf(bio_err, "memory allocation failure\n");
Packit Service 084de1
        goto end;
Packit Service 084de1
    }
Packit Service 084de1
Packit Service 084de1
    p = strchr(tmp, ',');
Packit Service 084de1
Packit Service 084de1
    rtime_str = tmp;
Packit Service 084de1
Packit Service 084de1
    if (p) {
Packit Service 084de1
        *p = '\0';
Packit Service 084de1
        p++;
Packit Service 084de1
        reason_str = p;
Packit Service 084de1
        p = strchr(p, ',');
Packit Service 084de1
        if (p) {
Packit Service 084de1
            *p = '\0';
Packit Service 084de1
            arg_str = p + 1;
Packit Service 084de1
        }
Packit Service 084de1
    }
Packit Service 084de1
Packit Service 084de1
    if (prevtm) {
Packit Service 084de1
        *prevtm = ASN1_UTCTIME_new();
Packit Service 084de1
        if (*prevtm == NULL) {
Packit Service 084de1
            BIO_printf(bio_err, "memory allocation failure\n");
Packit Service 084de1
            goto end;
Packit Service 084de1
        }
Packit Service 084de1
        if (!ASN1_UTCTIME_set_string(*prevtm, rtime_str)) {
Packit Service 084de1
            BIO_printf(bio_err, "invalid revocation date %s\n", rtime_str);
Packit Service 084de1
            goto end;
Packit Service 084de1
        }
Packit Service 084de1
    }
Packit Service 084de1
    if (reason_str) {
Packit Service 084de1
        for (i = 0; i < NUM_REASONS; i++) {
Packit Service 084de1
            if (strcasecmp(reason_str, crl_reasons[i]) == 0) {
Packit Service 084de1
                reason_code = i;
Packit Service 084de1
                break;
Packit Service 084de1
            }
Packit Service 084de1
        }
Packit Service 084de1
        if (reason_code == OCSP_REVOKED_STATUS_NOSTATUS) {
Packit Service 084de1
            BIO_printf(bio_err, "invalid reason code %s\n", reason_str);
Packit Service 084de1
            goto end;
Packit Service 084de1
        }
Packit Service 084de1
Packit Service 084de1
        if (reason_code == 7) {
Packit Service 084de1
            reason_code = OCSP_REVOKED_STATUS_REMOVEFROMCRL;
Packit Service 084de1
        } else if (reason_code == 8) { /* Hold instruction */
Packit Service 084de1
            if (!arg_str) {
Packit Service 084de1
                BIO_printf(bio_err, "missing hold instruction\n");
Packit Service 084de1
                goto end;
Packit Service 084de1
            }
Packit Service 084de1
            reason_code = OCSP_REVOKED_STATUS_CERTIFICATEHOLD;
Packit Service 084de1
            hold = OBJ_txt2obj(arg_str, 0);
Packit Service 084de1
Packit Service 084de1
            if (!hold) {
Packit Service 084de1
                BIO_printf(bio_err, "invalid object identifier %s\n", arg_str);
Packit Service 084de1
                goto end;
Packit Service 084de1
            }
Packit Service 084de1
            if (phold)
Packit Service 084de1
                *phold = hold;
Packit Service 084de1
            else
Packit Service 084de1
                ASN1_OBJECT_free(hold);
Packit Service 084de1
        } else if ((reason_code == 9) || (reason_code == 10)) {
Packit Service 084de1
            if (!arg_str) {
Packit Service 084de1
                BIO_printf(bio_err, "missing compromised time\n");
Packit Service 084de1
                goto end;
Packit Service 084de1
            }
Packit Service 084de1
            comp_time = ASN1_GENERALIZEDTIME_new();
Packit Service 084de1
            if (comp_time == NULL) {
Packit Service 084de1
                BIO_printf(bio_err, "memory allocation failure\n");
Packit Service 084de1
                goto end;
Packit Service 084de1
            }
Packit Service 084de1
            if (!ASN1_GENERALIZEDTIME_set_string(comp_time, arg_str)) {
Packit Service 084de1
                BIO_printf(bio_err, "invalid compromised time %s\n", arg_str);
Packit Service 084de1
                goto end;
Packit Service 084de1
            }
Packit Service 084de1
            if (reason_code == 9)
Packit Service 084de1
                reason_code = OCSP_REVOKED_STATUS_KEYCOMPROMISE;
Packit Service 084de1
            else
Packit Service 084de1
                reason_code = OCSP_REVOKED_STATUS_CACOMPROMISE;
Packit Service 084de1
        }
Packit Service 084de1
    }
Packit Service 084de1
Packit Service 084de1
    if (preason)
Packit Service 084de1
        *preason = reason_code;
Packit Service 084de1
    if (pinvtm) {
Packit Service 084de1
        *pinvtm = comp_time;
Packit Service 084de1
        comp_time = NULL;
Packit Service 084de1
    }
Packit Service 084de1
Packit Service 084de1
    ret = 1;
Packit Service 084de1
Packit Service 084de1
 end:
Packit Service 084de1
Packit Service 084de1
    OPENSSL_free(tmp);
Packit Service 084de1
    ASN1_GENERALIZEDTIME_free(comp_time);
Packit Service 084de1
Packit Service 084de1
    return ret;
Packit Service 084de1
}