Home | History | Annotate | Line # | Download | only in apps
      1      1.1  christos /*
      2      1.1  christos  * Copyright 1995-2024 The OpenSSL Project Authors. All Rights Reserved.
      3      1.1  christos  *
      4      1.1  christos  * Licensed under the Apache License 2.0 (the "License").  You may not use
      5      1.1  christos  * this file except in compliance with the License.  You can obtain a copy
      6      1.1  christos  * in the file LICENSE in the source distribution or at
      7      1.1  christos  * https://www.openssl.org/source/license.html
      8      1.1  christos  */
      9      1.1  christos #include "internal/e_os.h"
     10      1.1  christos 
     11      1.1  christos #include <stdio.h>
     12      1.1  christos #include <stdlib.h>
     13      1.1  christos #include <string.h>
     14      1.1  christos #include <ctype.h>
     15      1.1  christos #include <sys/types.h>
     16      1.1  christos #include <openssl/conf.h>
     17      1.1  christos #include <openssl/bio.h>
     18      1.1  christos #include <openssl/err.h>
     19      1.1  christos #include <openssl/bn.h>
     20      1.1  christos #include <openssl/txt_db.h>
     21      1.1  christos #include <openssl/evp.h>
     22      1.1  christos #include <openssl/x509.h>
     23      1.1  christos #include <openssl/x509v3.h>
     24      1.1  christos #include <openssl/objects.h>
     25      1.1  christos #include <openssl/ocsp.h>
     26      1.1  christos #include <openssl/pem.h>
     27      1.1  christos 
     28      1.1  christos #ifndef W_OK
     29  1.1.1.2  christos #ifdef OPENSSL_SYS_VMS
     30  1.1.1.2  christos #include <unistd.h>
     31  1.1.1.2  christos #elif !defined(OPENSSL_SYS_VXWORKS) && !defined(OPENSSL_SYS_WINDOWS) && !defined(OPENSSL_SYS_TANDEM)
     32  1.1.1.2  christos #include <sys/file.h>
     33  1.1.1.2  christos #endif
     34      1.1  christos #endif
     35      1.1  christos 
     36      1.1  christos #include "apps.h"
     37      1.1  christos #include "progs.h"
     38      1.1  christos 
     39      1.1  christos #ifndef W_OK
     40  1.1.1.2  christos #define F_OK 0
     41  1.1.1.2  christos #define W_OK 2
     42  1.1.1.2  christos #define R_OK 4
     43      1.1  christos #endif
     44      1.1  christos 
     45      1.1  christos #ifndef PATH_MAX
     46  1.1.1.2  christos #define PATH_MAX 4096
     47      1.1  christos #endif
     48      1.1  christos 
     49  1.1.1.2  christos #define BASE_SECTION "ca"
     50      1.1  christos 
     51  1.1.1.2  christos #define ENV_DEFAULT_CA "default_ca"
     52      1.1  christos 
     53  1.1.1.2  christos #define STRING_MASK "string_mask"
     54  1.1.1.2  christos #define UTF8_IN "utf8"
     55      1.1  christos 
     56  1.1.1.2  christos #define ENV_NEW_CERTS_DIR "new_certs_dir"
     57  1.1.1.2  christos #define ENV_CERTIFICATE "certificate"
     58  1.1.1.2  christos #define ENV_SERIAL "serial"
     59  1.1.1.2  christos #define ENV_RAND_SERIAL "rand_serial"
     60  1.1.1.2  christos #define ENV_CRLNUMBER "crlnumber"
     61  1.1.1.2  christos #define ENV_PRIVATE_KEY "private_key"
     62  1.1.1.2  christos #define ENV_DEFAULT_DAYS "default_days"
     63  1.1.1.2  christos #define ENV_DEFAULT_STARTDATE "default_startdate"
     64  1.1.1.2  christos #define ENV_DEFAULT_ENDDATE "default_enddate"
     65  1.1.1.2  christos #define ENV_DEFAULT_CRL_DAYS "default_crl_days"
     66  1.1.1.2  christos #define ENV_DEFAULT_CRL_HOURS "default_crl_hours"
     67  1.1.1.2  christos #define ENV_DEFAULT_MD "default_md"
     68  1.1.1.2  christos #define ENV_DEFAULT_EMAIL_DN "email_in_dn"
     69  1.1.1.2  christos #define ENV_PRESERVE "preserve"
     70  1.1.1.2  christos #define ENV_POLICY "policy"
     71  1.1.1.2  christos #define ENV_EXTENSIONS "x509_extensions"
     72  1.1.1.2  christos #define ENV_CRLEXT "crl_extensions"
     73  1.1.1.2  christos #define ENV_MSIE_HACK "msie_hack"
     74  1.1.1.2  christos #define ENV_NAMEOPT "name_opt"
     75  1.1.1.2  christos #define ENV_CERTOPT "cert_opt"
     76  1.1.1.2  christos #define ENV_EXTCOPY "copy_extensions"
     77  1.1.1.2  christos #define ENV_UNIQUE_SUBJECT "unique_subject"
     78      1.1  christos 
     79  1.1.1.2  christos #define ENV_DATABASE "database"
     80      1.1  christos 
     81      1.1  christos /* Additional revocation information types */
     82      1.1  christos typedef enum {
     83  1.1.1.2  christos     REV_VALID = -1, /* Valid (not-revoked) status */
     84  1.1.1.2  christos     REV_NONE = 0, /* No additional information */
     85  1.1.1.2  christos     REV_CRL_REASON = 1, /* Value is CRL reason code */
     86  1.1.1.2  christos     REV_HOLD = 2, /* Value is hold instruction */
     87  1.1.1.2  christos     REV_KEY_COMPROMISE = 3, /* Value is cert key compromise time */
     88  1.1.1.2  christos     REV_CA_COMPROMISE = 4 /* Value is CA key compromise time */
     89      1.1  christos } REVINFO_TYPE;
     90      1.1  christos 
     91      1.1  christos static char *lookup_conf(const CONF *conf, const char *group, const char *tag);
     92      1.1  christos 
     93      1.1  christos static int certify(X509 **xret, const char *infile, int informat,
     94  1.1.1.2  christos     EVP_PKEY *pkey, X509 *x509,
     95  1.1.1.2  christos     const char *dgst,
     96  1.1.1.2  christos     STACK_OF(OPENSSL_STRING) *sigopts,
     97  1.1.1.2  christos     STACK_OF(OPENSSL_STRING) *vfyopts,
     98  1.1.1.2  christos     STACK_OF(CONF_VALUE) *policy, CA_DB *db,
     99  1.1.1.2  christos     BIGNUM *serial, const char *subj, unsigned long chtype,
    100  1.1.1.2  christos     int multirdn, int email_dn, const char *startdate,
    101  1.1.1.2  christos     const char *enddate,
    102  1.1.1.2  christos     long days, int batch, const char *ext_sect, CONF *conf,
    103  1.1.1.2  christos     int verbose, unsigned long certopt, unsigned long nameopt,
    104  1.1.1.2  christos     int default_op, int ext_copy, int selfsign, unsigned long dateopt);
    105      1.1  christos static int certify_cert(X509 **xret, const char *infile, int certformat,
    106  1.1.1.2  christos     const char *passin, EVP_PKEY *pkey, X509 *x509,
    107  1.1.1.2  christos     const char *dgst,
    108  1.1.1.2  christos     STACK_OF(OPENSSL_STRING) *sigopts,
    109  1.1.1.2  christos     STACK_OF(OPENSSL_STRING) *vfyopts,
    110  1.1.1.2  christos     STACK_OF(CONF_VALUE) *policy, CA_DB *db,
    111  1.1.1.2  christos     BIGNUM *serial, const char *subj, unsigned long chtype,
    112  1.1.1.2  christos     int multirdn, int email_dn, const char *startdate,
    113  1.1.1.2  christos     const char *enddate, long days, int batch, const char *ext_sect,
    114  1.1.1.2  christos     CONF *conf, int verbose, unsigned long certopt,
    115  1.1.1.2  christos     unsigned long nameopt, int default_op, int ext_copy, unsigned long dateopt);
    116      1.1  christos static int certify_spkac(X509 **xret, const char *infile, EVP_PKEY *pkey,
    117  1.1.1.2  christos     X509 *x509, const char *dgst,
    118  1.1.1.2  christos     STACK_OF(OPENSSL_STRING) *sigopts,
    119  1.1.1.2  christos     STACK_OF(CONF_VALUE) *policy, CA_DB *db,
    120  1.1.1.2  christos     BIGNUM *serial, const char *subj, unsigned long chtype,
    121  1.1.1.2  christos     int multirdn, int email_dn, const char *startdate,
    122  1.1.1.2  christos     const char *enddate, long days, const char *ext_sect, CONF *conf,
    123  1.1.1.2  christos     int verbose, unsigned long certopt,
    124  1.1.1.2  christos     unsigned long nameopt, int default_op, int ext_copy, unsigned long dateopt);
    125      1.1  christos static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509,
    126  1.1.1.2  christos     const char *dgst, STACK_OF(OPENSSL_STRING) *sigopts,
    127  1.1.1.2  christos     STACK_OF(CONF_VALUE) *policy, CA_DB *db, BIGNUM *serial,
    128  1.1.1.2  christos     const char *subj, unsigned long chtype, int multirdn,
    129  1.1.1.2  christos     int email_dn, const char *startdate, const char *enddate, long days,
    130  1.1.1.2  christos     int batch, int verbose, X509_REQ *req, const char *ext_sect,
    131  1.1.1.2  christos     CONF *conf, unsigned long certopt, unsigned long nameopt,
    132  1.1.1.2  christos     int default_op, int ext_copy, int selfsign, unsigned long dateopt);
    133      1.1  christos static int get_certificate_status(const char *ser_status, CA_DB *db);
    134      1.1  christos static int check_time_format(const char *str);
    135      1.1  christos static int do_revoke(X509 *x509, CA_DB *db, REVINFO_TYPE rev_type,
    136  1.1.1.2  christos     const char *extval);
    137      1.1  christos static char *make_revocation_str(REVINFO_TYPE rev_type, const char *rev_arg);
    138      1.1  christos static int make_revoked(X509_REVOKED *rev, const char *str);
    139      1.1  christos static int old_entry_print(const ASN1_OBJECT *obj, const ASN1_STRING *str);
    140      1.1  christos static void write_new_certificate(BIO *bp, X509 *x, int output_der, int notext);
    141      1.1  christos 
    142      1.1  christos static CONF *extfile_conf = NULL;
    143      1.1  christos static int preserve = 0;
    144      1.1  christos static int msie_hack = 0;
    145      1.1  christos 
    146      1.1  christos typedef enum OPTION_choice {
    147      1.1  christos     OPT_COMMON,
    148  1.1.1.2  christos     OPT_ENGINE,
    149  1.1.1.2  christos     OPT_VERBOSE,
    150  1.1.1.2  christos     OPT_CONFIG,
    151  1.1.1.2  christos     OPT_NAME,
    152  1.1.1.2  christos     OPT_SUBJ,
    153  1.1.1.2  christos     OPT_UTF8,
    154  1.1.1.2  christos     OPT_CREATE_SERIAL,
    155  1.1.1.2  christos     OPT_MULTIVALUE_RDN,
    156  1.1.1.2  christos     OPT_STARTDATE,
    157  1.1.1.2  christos     OPT_ENDDATE,
    158  1.1.1.2  christos     OPT_DAYS,
    159  1.1.1.2  christos     OPT_MD,
    160  1.1.1.2  christos     OPT_POLICY,
    161  1.1.1.2  christos     OPT_KEYFILE,
    162  1.1.1.2  christos     OPT_KEYFORM,
    163  1.1.1.2  christos     OPT_PASSIN,
    164  1.1.1.2  christos     OPT_KEY,
    165  1.1.1.2  christos     OPT_CERT,
    166  1.1.1.2  christos     OPT_CERTFORM,
    167  1.1.1.2  christos     OPT_SELFSIGN,
    168  1.1.1.2  christos     OPT_IN,
    169  1.1.1.2  christos     OPT_INFORM,
    170  1.1.1.2  christos     OPT_OUT,
    171  1.1.1.2  christos     OPT_DATEOPT,
    172  1.1.1.2  christos     OPT_OUTDIR,
    173  1.1.1.2  christos     OPT_VFYOPT,
    174  1.1.1.2  christos     OPT_SIGOPT,
    175  1.1.1.2  christos     OPT_NOTEXT,
    176  1.1.1.2  christos     OPT_BATCH,
    177  1.1.1.2  christos     OPT_PRESERVEDN,
    178  1.1.1.2  christos     OPT_NOEMAILDN,
    179  1.1.1.2  christos     OPT_GENCRL,
    180  1.1.1.2  christos     OPT_MSIE_HACK,
    181  1.1.1.2  christos     OPT_CRL_LASTUPDATE,
    182  1.1.1.2  christos     OPT_CRL_NEXTUPDATE,
    183  1.1.1.2  christos     OPT_CRLDAYS,
    184  1.1.1.2  christos     OPT_CRLHOURS,
    185  1.1.1.2  christos     OPT_CRLSEC,
    186  1.1.1.2  christos     OPT_NOT_BEFORE,
    187  1.1.1.2  christos     OPT_NOT_AFTER,
    188  1.1.1.2  christos     OPT_INFILES,
    189  1.1.1.2  christos     OPT_SS_CERT,
    190  1.1.1.2  christos     OPT_SPKAC,
    191  1.1.1.2  christos     OPT_REVOKE,
    192  1.1.1.2  christos     OPT_VALID,
    193  1.1.1.2  christos     OPT_EXTENSIONS,
    194  1.1.1.2  christos     OPT_EXTFILE,
    195  1.1.1.2  christos     OPT_STATUS,
    196  1.1.1.2  christos     OPT_UPDATEDB,
    197  1.1.1.2  christos     OPT_CRLEXTS,
    198  1.1.1.2  christos     OPT_RAND_SERIAL,
    199  1.1.1.2  christos     OPT_QUIET,
    200  1.1.1.2  christos     OPT_R_ENUM,
    201  1.1.1.2  christos     OPT_PROV_ENUM,
    202      1.1  christos     /* Do not change the order here; see related case statements below */
    203  1.1.1.2  christos     OPT_CRL_REASON,
    204  1.1.1.2  christos     OPT_CRL_HOLD,
    205  1.1.1.2  christos     OPT_CRL_COMPROMISE,
    206  1.1.1.2  christos     OPT_CRL_CA_COMPROMISE
    207      1.1  christos } OPTION_CHOICE;
    208      1.1  christos 
    209      1.1  christos const OPTIONS ca_options[] = {
    210  1.1.1.2  christos     { OPT_HELP_STR, 1, '-', "Usage: %s [options] [certreq...]\n" },
    211      1.1  christos 
    212      1.1  christos     OPT_SECTION("General"),
    213  1.1.1.2  christos     { "help", OPT_HELP, '-', "Display this summary" },
    214  1.1.1.2  christos     { "verbose", OPT_VERBOSE, '-', "Verbose output during processing" },
    215  1.1.1.2  christos     { "quiet", OPT_QUIET, '-', "Terse output during processing" },
    216  1.1.1.2  christos     { "outdir", OPT_OUTDIR, '/', "Where to put output cert" },
    217  1.1.1.2  christos     { "in", OPT_IN, '<', "The input cert request(s)" },
    218  1.1.1.2  christos     { "inform", OPT_INFORM, 'F',
    219  1.1.1.2  christos         "CSR input format to use (PEM or DER; by default try PEM first)" },
    220  1.1.1.2  christos     { "infiles", OPT_INFILES, '-', "The last argument, requests to process" },
    221  1.1.1.2  christos     { "out", OPT_OUT, '>', "Where to put the output file(s)" },
    222  1.1.1.2  christos     { "dateopt", OPT_DATEOPT, 's', "Datetime format used for printing. (rfc_822/iso_8601). Default is rfc_822." },
    223  1.1.1.2  christos     { "notext", OPT_NOTEXT, '-', "Do not print the generated certificate" },
    224  1.1.1.2  christos     { "batch", OPT_BATCH, '-', "Don't ask questions" },
    225  1.1.1.2  christos     { "msie_hack", OPT_MSIE_HACK, '-',
    226  1.1.1.2  christos         "msie modifications to handle all Universal Strings" },
    227  1.1.1.2  christos     { "ss_cert", OPT_SS_CERT, '<', "File contains a self signed cert to sign" },
    228  1.1.1.2  christos     { "spkac", OPT_SPKAC, '<',
    229  1.1.1.2  christos         "File contains DN and signed public key and challenge" },
    230      1.1  christos #ifndef OPENSSL_NO_ENGINE
    231  1.1.1.2  christos     { "engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device" },
    232      1.1  christos #endif
    233      1.1  christos 
    234      1.1  christos     OPT_SECTION("Configuration"),
    235  1.1.1.2  christos     { "config", OPT_CONFIG, 's', "A config file" },
    236  1.1.1.2  christos     { "name", OPT_NAME, 's', "The particular CA definition to use" },
    237  1.1.1.2  christos     { "section", OPT_NAME, 's', "An alias for -name" },
    238  1.1.1.2  christos     { "policy", OPT_POLICY, 's', "The CA 'policy' to support" },
    239      1.1  christos 
    240      1.1  christos     OPT_SECTION("Certificate"),
    241  1.1.1.2  christos     { "subj", OPT_SUBJ, 's', "Use arg instead of request's subject" },
    242  1.1.1.2  christos     { "utf8", OPT_UTF8, '-', "Input characters are UTF8; default ASCII" },
    243  1.1.1.2  christos     { "create_serial", OPT_CREATE_SERIAL, '-',
    244  1.1.1.2  christos         "If reading serial fails, create a new random serial" },
    245  1.1.1.2  christos     { "rand_serial", OPT_RAND_SERIAL, '-',
    246  1.1.1.2  christos         "Always create a random serial; do not store it" },
    247  1.1.1.2  christos     { "multivalue-rdn", OPT_MULTIVALUE_RDN, '-',
    248  1.1.1.2  christos         "Deprecated; multi-valued RDNs support is always on." },
    249  1.1.1.2  christos     { "startdate", OPT_STARTDATE, 's',
    250  1.1.1.2  christos         "[CC]YYMMDDHHMMSSZ value for notBefore certificate field" },
    251  1.1.1.2  christos     { "not_before", OPT_NOT_BEFORE, 's', "An alias for -startdate" },
    252  1.1.1.2  christos     { "enddate", OPT_ENDDATE, 's',
    253  1.1.1.2  christos         "[CC]YYMMDDHHMMSSZ value for notAfter certificate field, overrides -days" },
    254  1.1.1.2  christos     { "not_after", OPT_NOT_AFTER, 's', "An alias for -enddate" },
    255  1.1.1.2  christos     { "days", OPT_DAYS, 'p', "Number of days from today to certify the cert for" },
    256  1.1.1.2  christos     { "extensions", OPT_EXTENSIONS, 's',
    257  1.1.1.2  christos         "Extension section (override value in config file)" },
    258  1.1.1.2  christos     { "extfile", OPT_EXTFILE, '<',
    259  1.1.1.2  christos         "Configuration file with X509v3 extensions to add" },
    260  1.1.1.2  christos     { "preserveDN", OPT_PRESERVEDN, '-', "Don't re-order the DN" },
    261  1.1.1.2  christos     { "noemailDN", OPT_NOEMAILDN, '-', "Don't add the EMAIL field to the DN" },
    262      1.1  christos 
    263      1.1  christos     OPT_SECTION("Signing"),
    264  1.1.1.2  christos     { "md", OPT_MD, 's', "Digest to use, such as sha256" },
    265  1.1.1.2  christos     { "keyfile", OPT_KEYFILE, 's', "The CA private key" },
    266  1.1.1.2  christos     { "keyform", OPT_KEYFORM, 'f',
    267  1.1.1.2  christos         "Private key file format (ENGINE, other values ignored)" },
    268  1.1.1.2  christos     { "passin", OPT_PASSIN, 's', "Key and cert input file pass phrase source" },
    269  1.1.1.2  christos     { "key", OPT_KEY, 's',
    270  1.1.1.2  christos         "Key to decrypt the private key or cert files if encrypted. Better use -passin" },
    271  1.1.1.2  christos     { "cert", OPT_CERT, '<', "The CA cert" },
    272  1.1.1.2  christos     { "certform", OPT_CERTFORM, 'F',
    273  1.1.1.2  christos         "Certificate input format (DER/PEM/P12); has no effect" },
    274  1.1.1.2  christos     { "selfsign", OPT_SELFSIGN, '-',
    275  1.1.1.2  christos         "Sign a cert with the key associated with it" },
    276  1.1.1.2  christos     { "sigopt", OPT_SIGOPT, 's', "Signature parameter in n:v form" },
    277  1.1.1.2  christos     { "vfyopt", OPT_VFYOPT, 's', "Verification parameter in n:v form" },
    278      1.1  christos 
    279      1.1  christos     OPT_SECTION("Revocation"),
    280  1.1.1.2  christos     { "gencrl", OPT_GENCRL, '-', "Generate a new CRL" },
    281  1.1.1.2  christos     { "valid", OPT_VALID, 's',
    282  1.1.1.2  christos         "Add a Valid(not-revoked) DB entry about a cert (given in file)" },
    283  1.1.1.2  christos     { "status", OPT_STATUS, 's', "Shows cert status given the serial number" },
    284  1.1.1.2  christos     { "updatedb", OPT_UPDATEDB, '-', "Updates db for expired cert" },
    285  1.1.1.2  christos     { "crlexts", OPT_CRLEXTS, 's',
    286  1.1.1.2  christos         "CRL extension section (override value in config file)" },
    287  1.1.1.2  christos     { "crl_reason", OPT_CRL_REASON, 's', "revocation reason" },
    288  1.1.1.2  christos     { "crl_hold", OPT_CRL_HOLD, 's',
    289  1.1.1.2  christos         "the hold instruction, an OID. Sets revocation reason to certificateHold" },
    290  1.1.1.2  christos     { "crl_compromise", OPT_CRL_COMPROMISE, 's',
    291  1.1.1.2  christos         "sets compromise time to val and the revocation reason to keyCompromise" },
    292  1.1.1.2  christos     { "crl_CA_compromise", OPT_CRL_CA_COMPROMISE, 's',
    293  1.1.1.2  christos         "sets compromise time to val and the revocation reason to CACompromise" },
    294  1.1.1.2  christos     { "crl_lastupdate", OPT_CRL_LASTUPDATE, 's',
    295  1.1.1.2  christos         "Sets the CRL lastUpdate time to val (YYMMDDHHMMSSZ or YYYYMMDDHHMMSSZ)" },
    296  1.1.1.2  christos     { "crl_nextupdate", OPT_CRL_NEXTUPDATE, 's',
    297  1.1.1.2  christos         "Sets the CRL nextUpdate time to val (YYMMDDHHMMSSZ or YYYYMMDDHHMMSSZ)" },
    298  1.1.1.2  christos     { "crldays", OPT_CRLDAYS, 'p', "Days until the next CRL is due" },
    299  1.1.1.2  christos     { "crlhours", OPT_CRLHOURS, 'p', "Hours until the next CRL is due" },
    300  1.1.1.2  christos     { "crlsec", OPT_CRLSEC, 'p', "Seconds until the next CRL is due" },
    301  1.1.1.2  christos     { "revoke", OPT_REVOKE, '<', "Revoke a cert (given in file)" },
    302      1.1  christos 
    303      1.1  christos     OPT_R_OPTIONS,
    304      1.1  christos     OPT_PROV_OPTIONS,
    305      1.1  christos 
    306      1.1  christos     OPT_PARAMETERS(),
    307  1.1.1.2  christos     { "certreq", 0, 0, "Certificate requests to be signed (optional)" },
    308  1.1.1.2  christos     { NULL }
    309      1.1  christos };
    310      1.1  christos 
    311      1.1  christos int ca_main(int argc, char **argv)
    312      1.1  christos {
    313      1.1  christos     CONF *conf = NULL;
    314      1.1  christos     ENGINE *e = NULL;
    315      1.1  christos     BIGNUM *crlnumber = NULL, *serial = NULL;
    316      1.1  christos     EVP_PKEY *pkey = NULL;
    317      1.1  christos     BIO *in = NULL, *out = NULL, *Sout = NULL;
    318      1.1  christos     ASN1_INTEGER *tmpser;
    319      1.1  christos     CA_DB *db = NULL;
    320      1.1  christos     DB_ATTR db_attr;
    321      1.1  christos     STACK_OF(CONF_VALUE) *attribs = NULL;
    322      1.1  christos     STACK_OF(OPENSSL_STRING) *sigopts = NULL, *vfyopts = NULL;
    323      1.1  christos     STACK_OF(X509) *cert_sk = NULL;
    324      1.1  christos     X509_CRL *crl = NULL;
    325      1.1  christos     char *configfile = default_config_file, *section = NULL;
    326      1.1  christos     char def_dgst[80] = "";
    327      1.1  christos     char *dgst = NULL, *policy = NULL, *keyfile = NULL;
    328      1.1  christos     char *certfile = NULL, *crl_ext = NULL, *crlnumberfile = NULL;
    329      1.1  christos     int certformat = FORMAT_UNDEF, informat = FORMAT_UNDEF;
    330      1.1  christos     unsigned long dateopt = ASN1_DTFLGS_RFC822;
    331      1.1  christos     const char *infile = NULL, *spkac_file = NULL, *ss_cert_file = NULL;
    332      1.1  christos     const char *extensions = NULL, *extfile = NULL, *passinarg = NULL;
    333      1.1  christos     char *passin = NULL;
    334      1.1  christos     char *outdir = NULL, *outfile = NULL, *rev_arg = NULL, *ser_status = NULL;
    335      1.1  christos     const char *serialfile = NULL, *subj = NULL;
    336      1.1  christos     char *prog, *startdate = NULL, *enddate = NULL;
    337      1.1  christos     char *dbfile = NULL, *f;
    338      1.1  christos     char new_cert[PATH_MAX];
    339      1.1  christos     char tmp[10 + 1] = "\0";
    340      1.1  christos     char *const *pp;
    341      1.1  christos     const char *p;
    342      1.1  christos     size_t outdirlen = 0;
    343      1.1  christos     int create_ser = 0, free_passin = 0, total = 0, total_done = 0;
    344      1.1  christos     int batch = 0, default_op = 1, doupdatedb = 0, ext_copy = EXT_COPY_NONE;
    345      1.1  christos     int keyformat = FORMAT_UNDEF, multirdn = 1, notext = 0, output_der = 0;
    346      1.1  christos     int ret = 1, email_dn = 1, req = 0, verbose = 0, gencrl = 0, dorevoke = 0;
    347      1.1  christos     int rand_ser = 0, i, j, selfsign = 0, def_ret;
    348      1.1  christos     char *crl_lastupdate = NULL, *crl_nextupdate = NULL;
    349      1.1  christos     long crldays = 0, crlhours = 0, crlsec = 0, days = 0;
    350      1.1  christos     unsigned long chtype = MBSTRING_ASC, certopt = 0;
    351      1.1  christos     X509 *x509 = NULL, *x509p = NULL, *x = NULL;
    352      1.1  christos     REVINFO_TYPE rev_type = REV_NONE;
    353      1.1  christos     X509_REVOKED *r = NULL;
    354      1.1  christos     OPTION_CHOICE o;
    355      1.1  christos 
    356      1.1  christos     prog = opt_init(argc, argv, ca_options);
    357      1.1  christos     while ((o = opt_next()) != OPT_EOF) {
    358      1.1  christos         switch (o) {
    359      1.1  christos         case OPT_EOF:
    360      1.1  christos         case OPT_ERR:
    361  1.1.1.2  christos         opthelp:
    362      1.1  christos             BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
    363      1.1  christos             goto end;
    364      1.1  christos         case OPT_HELP:
    365      1.1  christos             opt_help(ca_options);
    366      1.1  christos             ret = 0;
    367      1.1  christos             goto end;
    368      1.1  christos         case OPT_IN:
    369      1.1  christos             req = 1;
    370      1.1  christos             infile = opt_arg();
    371      1.1  christos             break;
    372      1.1  christos         case OPT_INFORM:
    373      1.1  christos             if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &informat))
    374      1.1  christos                 goto opthelp;
    375      1.1  christos             break;
    376      1.1  christos         case OPT_OUT:
    377      1.1  christos             outfile = opt_arg();
    378      1.1  christos             break;
    379      1.1  christos         case OPT_DATEOPT:
    380      1.1  christos             if (!set_dateopt(&dateopt, opt_arg()))
    381      1.1  christos                 goto opthelp;
    382      1.1  christos             break;
    383      1.1  christos         case OPT_VERBOSE:
    384      1.1  christos             verbose = 1;
    385      1.1  christos             break;
    386      1.1  christos         case OPT_QUIET:
    387      1.1  christos             verbose = 0;
    388      1.1  christos             break;
    389      1.1  christos         case OPT_CONFIG:
    390      1.1  christos             configfile = opt_arg();
    391      1.1  christos             break;
    392      1.1  christos         case OPT_NAME:
    393      1.1  christos             section = opt_arg();
    394      1.1  christos             break;
    395      1.1  christos         case OPT_SUBJ:
    396      1.1  christos             subj = opt_arg();
    397      1.1  christos             /* preserve=1; */
    398      1.1  christos             break;
    399      1.1  christos         case OPT_UTF8:
    400      1.1  christos             chtype = MBSTRING_UTF8;
    401      1.1  christos             break;
    402      1.1  christos         case OPT_RAND_SERIAL:
    403      1.1  christos             rand_ser = 1;
    404      1.1  christos             break;
    405      1.1  christos         case OPT_CREATE_SERIAL:
    406      1.1  christos             create_ser = 1;
    407      1.1  christos             break;
    408      1.1  christos         case OPT_MULTIVALUE_RDN:
    409      1.1  christos             /* obsolete */
    410      1.1  christos             break;
    411      1.1  christos         case OPT_STARTDATE:
    412      1.1  christos         case OPT_NOT_BEFORE:
    413      1.1  christos             startdate = opt_arg();
    414      1.1  christos             break;
    415      1.1  christos         case OPT_ENDDATE:
    416      1.1  christos         case OPT_NOT_AFTER:
    417      1.1  christos             enddate = opt_arg();
    418      1.1  christos             break;
    419      1.1  christos         case OPT_DAYS:
    420      1.1  christos             days = atoi(opt_arg());
    421      1.1  christos             break;
    422      1.1  christos         case OPT_MD:
    423      1.1  christos             dgst = opt_arg();
    424      1.1  christos             break;
    425      1.1  christos         case OPT_POLICY:
    426      1.1  christos             policy = opt_arg();
    427      1.1  christos             break;
    428      1.1  christos         case OPT_KEYFILE:
    429      1.1  christos             keyfile = opt_arg();
    430      1.1  christos             break;
    431      1.1  christos         case OPT_KEYFORM:
    432      1.1  christos             if (!opt_format(opt_arg(), OPT_FMT_ANY, &keyformat))
    433      1.1  christos                 goto opthelp;
    434      1.1  christos             break;
    435      1.1  christos         case OPT_PASSIN:
    436      1.1  christos             passinarg = opt_arg();
    437      1.1  christos             break;
    438      1.1  christos         case OPT_R_CASES:
    439      1.1  christos             if (!opt_rand(o))
    440      1.1  christos                 goto end;
    441      1.1  christos             break;
    442      1.1  christos         case OPT_PROV_CASES:
    443      1.1  christos             if (!opt_provider(o))
    444      1.1  christos                 goto end;
    445      1.1  christos             break;
    446      1.1  christos         case OPT_KEY:
    447      1.1  christos             passin = opt_arg();
    448      1.1  christos             break;
    449      1.1  christos         case OPT_CERT:
    450      1.1  christos             certfile = opt_arg();
    451      1.1  christos             break;
    452      1.1  christos         case OPT_CERTFORM:
    453      1.1  christos             if (!opt_format(opt_arg(), OPT_FMT_ANY, &certformat))
    454      1.1  christos                 goto opthelp;
    455      1.1  christos             break;
    456      1.1  christos         case OPT_SELFSIGN:
    457      1.1  christos             selfsign = 1;
    458      1.1  christos             break;
    459      1.1  christos         case OPT_OUTDIR:
    460      1.1  christos             outdir = opt_arg();
    461      1.1  christos             break;
    462      1.1  christos         case OPT_SIGOPT:
    463      1.1  christos             if (sigopts == NULL)
    464      1.1  christos                 sigopts = sk_OPENSSL_STRING_new_null();
    465      1.1  christos             if (sigopts == NULL || !sk_OPENSSL_STRING_push(sigopts, opt_arg()))
    466      1.1  christos                 goto end;
    467      1.1  christos             break;
    468      1.1  christos         case OPT_VFYOPT:
    469      1.1  christos             if (vfyopts == NULL)
    470      1.1  christos                 vfyopts = sk_OPENSSL_STRING_new_null();
    471      1.1  christos             if (vfyopts == NULL || !sk_OPENSSL_STRING_push(vfyopts, opt_arg()))
    472      1.1  christos                 goto end;
    473      1.1  christos             break;
    474      1.1  christos         case OPT_NOTEXT:
    475      1.1  christos             notext = 1;
    476      1.1  christos             break;
    477      1.1  christos         case OPT_BATCH:
    478      1.1  christos             batch = 1;
    479      1.1  christos             break;
    480      1.1  christos         case OPT_PRESERVEDN:
    481      1.1  christos             preserve = 1;
    482      1.1  christos             break;
    483      1.1  christos         case OPT_NOEMAILDN:
    484      1.1  christos             email_dn = 0;
    485      1.1  christos             break;
    486      1.1  christos         case OPT_GENCRL:
    487      1.1  christos             gencrl = 1;
    488      1.1  christos             break;
    489      1.1  christos         case OPT_MSIE_HACK:
    490      1.1  christos             msie_hack = 1;
    491      1.1  christos             break;
    492      1.1  christos         case OPT_CRL_LASTUPDATE:
    493      1.1  christos             crl_lastupdate = opt_arg();
    494      1.1  christos             break;
    495      1.1  christos         case OPT_CRL_NEXTUPDATE:
    496      1.1  christos             crl_nextupdate = opt_arg();
    497      1.1  christos             break;
    498      1.1  christos         case OPT_CRLDAYS:
    499      1.1  christos             crldays = atol(opt_arg());
    500      1.1  christos             break;
    501      1.1  christos         case OPT_CRLHOURS:
    502      1.1  christos             crlhours = atol(opt_arg());
    503      1.1  christos             break;
    504      1.1  christos         case OPT_CRLSEC:
    505      1.1  christos             crlsec = atol(opt_arg());
    506      1.1  christos             break;
    507      1.1  christos         case OPT_INFILES:
    508      1.1  christos             req = 1;
    509      1.1  christos             goto end_of_options;
    510      1.1  christos         case OPT_SS_CERT:
    511      1.1  christos             ss_cert_file = opt_arg();
    512      1.1  christos             req = 1;
    513      1.1  christos             break;
    514      1.1  christos         case OPT_SPKAC:
    515      1.1  christos             spkac_file = opt_arg();
    516      1.1  christos             req = 1;
    517      1.1  christos             break;
    518      1.1  christos         case OPT_REVOKE:
    519      1.1  christos             infile = opt_arg();
    520      1.1  christos             dorevoke = 1;
    521      1.1  christos             break;
    522      1.1  christos         case OPT_VALID:
    523      1.1  christos             infile = opt_arg();
    524      1.1  christos             dorevoke = 2;
    525      1.1  christos             break;
    526      1.1  christos         case OPT_EXTENSIONS:
    527      1.1  christos             extensions = opt_arg();
    528      1.1  christos             break;
    529      1.1  christos         case OPT_EXTFILE:
    530      1.1  christos             extfile = opt_arg();
    531      1.1  christos             break;
    532      1.1  christos         case OPT_STATUS:
    533      1.1  christos             ser_status = opt_arg();
    534      1.1  christos             break;
    535      1.1  christos         case OPT_UPDATEDB:
    536      1.1  christos             doupdatedb = 1;
    537      1.1  christos             break;
    538      1.1  christos         case OPT_CRLEXTS:
    539      1.1  christos             crl_ext = opt_arg();
    540      1.1  christos             break;
    541  1.1.1.2  christos         case OPT_CRL_REASON: /* := REV_CRL_REASON */
    542      1.1  christos         case OPT_CRL_HOLD:
    543      1.1  christos         case OPT_CRL_COMPROMISE:
    544      1.1  christos         case OPT_CRL_CA_COMPROMISE:
    545      1.1  christos             rev_arg = opt_arg();
    546      1.1  christos             rev_type = (o - OPT_CRL_REASON) + REV_CRL_REASON;
    547      1.1  christos             break;
    548      1.1  christos         case OPT_ENGINE:
    549      1.1  christos             e = setup_engine(opt_arg(), 0);
    550      1.1  christos             break;
    551      1.1  christos         }
    552      1.1  christos     }
    553      1.1  christos 
    554      1.1  christos end_of_options:
    555      1.1  christos     /* Remaining args are files to certify. */
    556      1.1  christos     argc = opt_num_rest();
    557      1.1  christos     argv = opt_rest();
    558      1.1  christos 
    559      1.1  christos     if ((conf = app_load_config_verbose(configfile, 1)) == NULL)
    560      1.1  christos         goto end;
    561      1.1  christos     if (configfile != default_config_file && !app_load_modules(conf))
    562      1.1  christos         goto end;
    563      1.1  christos 
    564      1.1  christos     /* Lets get the config section we are using */
    565      1.1  christos     if (section == NULL
    566      1.1  christos         && (section = lookup_conf(conf, BASE_SECTION, ENV_DEFAULT_CA)) == NULL)
    567      1.1  christos         goto end;
    568      1.1  christos 
    569      1.1  christos     p = app_conf_try_string(conf, NULL, "oid_file");
    570      1.1  christos     if (p != NULL) {
    571      1.1  christos         BIO *oid_bio = BIO_new_file(p, "r");
    572      1.1  christos 
    573      1.1  christos         if (oid_bio == NULL) {
    574      1.1  christos             ERR_clear_error();
    575      1.1  christos         } else {
    576      1.1  christos             OBJ_create_objects(oid_bio);
    577      1.1  christos             BIO_free(oid_bio);
    578      1.1  christos         }
    579      1.1  christos     }
    580      1.1  christos     if (!add_oid_section(conf))
    581      1.1  christos         goto end;
    582      1.1  christos 
    583      1.1  christos     app_RAND_load_conf(conf, BASE_SECTION);
    584      1.1  christos     if (!app_RAND_load())
    585      1.1  christos         goto end;
    586      1.1  christos 
    587      1.1  christos     f = app_conf_try_string(conf, section, STRING_MASK);
    588      1.1  christos     if (f != NULL && !ASN1_STRING_set_default_mask_asc(f)) {
    589      1.1  christos         BIO_printf(bio_err, "Invalid global string mask setting %s\n", f);
    590      1.1  christos         goto end;
    591      1.1  christos     }
    592      1.1  christos 
    593      1.1  christos     if (chtype != MBSTRING_UTF8) {
    594      1.1  christos         f = app_conf_try_string(conf, section, UTF8_IN);
    595      1.1  christos         if (f != NULL && strcmp(f, "yes") == 0)
    596      1.1  christos             chtype = MBSTRING_UTF8;
    597      1.1  christos     }
    598      1.1  christos 
    599      1.1  christos     db_attr.unique_subject = 1;
    600      1.1  christos     p = app_conf_try_string(conf, section, ENV_UNIQUE_SUBJECT);
    601      1.1  christos     if (p != NULL)
    602      1.1  christos         db_attr.unique_subject = parse_yesno(p, 1);
    603      1.1  christos 
    604      1.1  christos     /*****************************************************************/
    605      1.1  christos     /* report status of cert with serial number given on command line */
    606      1.1  christos     if (ser_status) {
    607      1.1  christos         dbfile = lookup_conf(conf, section, ENV_DATABASE);
    608      1.1  christos         if (dbfile == NULL)
    609      1.1  christos             goto end;
    610      1.1  christos 
    611      1.1  christos         db = load_index(dbfile, &db_attr);
    612      1.1  christos         if (db == NULL) {
    613      1.1  christos             BIO_printf(bio_err, "Problem with index file: %s (could not load/parse file)\n", dbfile);
    614      1.1  christos             goto end;
    615      1.1  christos         }
    616      1.1  christos 
    617      1.1  christos         if (index_index(db) <= 0)
    618      1.1  christos             goto end;
    619      1.1  christos 
    620      1.1  christos         if (get_certificate_status(ser_status, db) != 1)
    621      1.1  christos             BIO_printf(bio_err, "Error verifying serial %s!\n", ser_status);
    622      1.1  christos         goto end;
    623      1.1  christos     }
    624      1.1  christos 
    625      1.1  christos     /*****************************************************************/
    626      1.1  christos     /* we definitely need a private key, so let's get it */
    627      1.1  christos 
    628      1.1  christos     if (keyfile == NULL
    629      1.1  christos         && (keyfile = lookup_conf(conf, section, ENV_PRIVATE_KEY)) == NULL)
    630      1.1  christos         goto end;
    631      1.1  christos 
    632      1.1  christos     if (passin == NULL) {
    633      1.1  christos         free_passin = 1;
    634      1.1  christos         if (!app_passwd(passinarg, NULL, &passin, NULL)) {
    635      1.1  christos             BIO_printf(bio_err, "Error getting password\n");
    636      1.1  christos             goto end;
    637      1.1  christos         }
    638      1.1  christos     }
    639      1.1  christos     pkey = load_key(keyfile, keyformat, 0, passin, e, "CA private key");
    640      1.1  christos     cleanse(passin);
    641      1.1  christos     if (pkey == NULL)
    642      1.1  christos         /* load_key() has already printed an appropriate message */
    643      1.1  christos         goto end;
    644      1.1  christos 
    645      1.1  christos     /*****************************************************************/
    646      1.1  christos     /* we need a certificate */
    647      1.1  christos     if (!selfsign || spkac_file || ss_cert_file || gencrl) {
    648      1.1  christos         if (certfile == NULL
    649      1.1  christos             && (certfile = lookup_conf(conf, section, ENV_CERTIFICATE)) == NULL)
    650      1.1  christos             goto end;
    651      1.1  christos 
    652      1.1  christos         x509 = load_cert_pass(certfile, certformat, 1, passin, "CA certificate");
    653      1.1  christos         if (x509 == NULL)
    654      1.1  christos             goto end;
    655      1.1  christos 
    656      1.1  christos         if (!X509_check_private_key(x509, pkey)) {
    657      1.1  christos             BIO_printf(bio_err,
    658  1.1.1.2  christos                 "CA certificate and CA private key do not match\n");
    659      1.1  christos             goto end;
    660      1.1  christos         }
    661      1.1  christos     }
    662      1.1  christos     if (!selfsign)
    663      1.1  christos         x509p = x509;
    664      1.1  christos 
    665      1.1  christos     f = app_conf_try_string(conf, BASE_SECTION, ENV_PRESERVE);
    666      1.1  christos     if (f != NULL && (*f == 'y' || *f == 'Y'))
    667      1.1  christos         preserve = 1;
    668      1.1  christos     f = app_conf_try_string(conf, BASE_SECTION, ENV_MSIE_HACK);
    669      1.1  christos     if (f != NULL && (*f == 'y' || *f == 'Y'))
    670      1.1  christos         msie_hack = 1;
    671      1.1  christos 
    672      1.1  christos     f = app_conf_try_string(conf, section, ENV_NAMEOPT);
    673      1.1  christos     if (f != NULL) {
    674      1.1  christos         if (!set_nameopt(f)) {
    675      1.1  christos             BIO_printf(bio_err, "Invalid name options: \"%s\"\n", f);
    676      1.1  christos             goto end;
    677      1.1  christos         }
    678      1.1  christos         default_op = 0;
    679      1.1  christos     }
    680      1.1  christos 
    681      1.1  christos     f = app_conf_try_string(conf, section, ENV_CERTOPT);
    682      1.1  christos     if (f != NULL) {
    683      1.1  christos         if (!set_cert_ex(&certopt, f)) {
    684      1.1  christos             BIO_printf(bio_err, "Invalid certificate options: \"%s\"\n", f);
    685      1.1  christos             goto end;
    686      1.1  christos         }
    687      1.1  christos         default_op = 0;
    688      1.1  christos     }
    689      1.1  christos 
    690      1.1  christos     f = app_conf_try_string(conf, section, ENV_EXTCOPY);
    691      1.1  christos     if (f != NULL) {
    692      1.1  christos         if (!set_ext_copy(&ext_copy, f)) {
    693      1.1  christos             BIO_printf(bio_err, "Invalid extension copy option: \"%s\"\n", f);
    694      1.1  christos             goto end;
    695      1.1  christos         }
    696      1.1  christos     }
    697      1.1  christos 
    698      1.1  christos     /*****************************************************************/
    699      1.1  christos     /* lookup where to write new certificates */
    700      1.1  christos     if ((outdir == NULL) && (req)) {
    701      1.1  christos 
    702      1.1  christos         outdir = NCONF_get_string(conf, section, ENV_NEW_CERTS_DIR);
    703      1.1  christos         if (outdir == NULL) {
    704      1.1  christos             BIO_printf(bio_err,
    705  1.1.1.2  christos                 "there needs to be defined a directory for new certificate to be placed in\n");
    706      1.1  christos             goto end;
    707      1.1  christos         }
    708      1.1  christos #ifndef OPENSSL_SYS_VMS
    709      1.1  christos         /*
    710      1.1  christos          * outdir is a directory spec, but access() for VMS demands a
    711      1.1  christos          * filename.  We could use the DEC C routine to convert the
    712      1.1  christos          * directory syntax to Unix, and give that to app_isdir,
    713      1.1  christos          * but for now the fopen will catch the error if it's not a
    714      1.1  christos          * directory
    715      1.1  christos          */
    716      1.1  christos         if (app_isdir(outdir) <= 0) {
    717      1.1  christos             BIO_printf(bio_err, "%s: %s is not a directory\n", prog, outdir);
    718      1.1  christos             perror(outdir);
    719      1.1  christos             goto end;
    720      1.1  christos         }
    721      1.1  christos #endif
    722      1.1  christos     }
    723      1.1  christos 
    724      1.1  christos     /*****************************************************************/
    725      1.1  christos     /* we need to load the database file */
    726      1.1  christos     dbfile = lookup_conf(conf, section, ENV_DATABASE);
    727      1.1  christos     if (dbfile == NULL)
    728      1.1  christos         goto end;
    729      1.1  christos 
    730      1.1  christos     db = load_index(dbfile, &db_attr);
    731      1.1  christos     if (db == NULL) {
    732      1.1  christos         BIO_printf(bio_err, "Problem with index file: %s (could not load/parse file)\n", dbfile);
    733      1.1  christos         goto end;
    734      1.1  christos     }
    735      1.1  christos 
    736      1.1  christos     /* Lets check some fields */
    737      1.1  christos     for (i = 0; i < sk_OPENSSL_PSTRING_num(db->db->data); i++) {
    738      1.1  christos         pp = sk_OPENSSL_PSTRING_value(db->db->data, i);
    739      1.1  christos         if ((pp[DB_type][0] != DB_TYPE_REV) && (pp[DB_rev_date][0] != '\0')) {
    740      1.1  christos             BIO_printf(bio_err,
    741  1.1.1.2  christos                 "entry %d: not revoked yet, but has a revocation date\n",
    742  1.1.1.2  christos                 i + 1);
    743      1.1  christos             goto end;
    744      1.1  christos         }
    745  1.1.1.2  christos         if ((pp[DB_type][0] == DB_TYPE_REV) && !make_revoked(NULL, pp[DB_rev_date])) {
    746      1.1  christos             BIO_printf(bio_err, " in entry %d\n", i + 1);
    747      1.1  christos             goto end;
    748      1.1  christos         }
    749      1.1  christos         if (!check_time_format((char *)pp[DB_exp_date])) {
    750      1.1  christos             BIO_printf(bio_err, "entry %d: invalid expiry date\n", i + 1);
    751      1.1  christos             goto end;
    752      1.1  christos         }
    753      1.1  christos         p = pp[DB_serial];
    754      1.1  christos         j = strlen(p);
    755      1.1  christos         if (*p == '-') {
    756      1.1  christos             p++;
    757      1.1  christos             j--;
    758      1.1  christos         }
    759      1.1  christos         if ((j & 1) || (j < 2)) {
    760      1.1  christos             BIO_printf(bio_err, "entry %d: bad serial number length (%d)\n",
    761  1.1.1.2  christos                 i + 1, j);
    762      1.1  christos             goto end;
    763      1.1  christos         }
    764  1.1.1.2  christos         for (; *p; p++) {
    765      1.1  christos             if (!isxdigit(_UC(*p))) {
    766      1.1  christos                 BIO_printf(bio_err,
    767  1.1.1.2  christos                     "entry %d: bad char 0%o '%c' in serial number\n",
    768  1.1.1.2  christos                     i + 1, *p, *p);
    769      1.1  christos                 goto end;
    770      1.1  christos             }
    771      1.1  christos         }
    772      1.1  christos     }
    773      1.1  christos     if (verbose) {
    774      1.1  christos         TXT_DB_write(bio_out, db->db);
    775      1.1  christos         BIO_printf(bio_err, "%d entries loaded from the database\n",
    776  1.1.1.2  christos             sk_OPENSSL_PSTRING_num(db->db->data));
    777      1.1  christos         BIO_printf(bio_err, "generating index\n");
    778      1.1  christos     }
    779      1.1  christos 
    780      1.1  christos     if (index_index(db) <= 0)
    781      1.1  christos         goto end;
    782      1.1  christos 
    783      1.1  christos     /*****************************************************************/
    784      1.1  christos     /* Update the db file for expired certificates */
    785      1.1  christos     if (doupdatedb) {
    786      1.1  christos         if (verbose)
    787      1.1  christos             BIO_printf(bio_err, "Updating %s ...\n", dbfile);
    788      1.1  christos 
    789      1.1  christos         i = do_updatedb(db, NULL);
    790      1.1  christos         if (i == -1) {
    791      1.1  christos             BIO_printf(bio_err, "Malloc failure\n");
    792      1.1  christos             goto end;
    793      1.1  christos         } else if (i == 0) {
    794      1.1  christos             if (verbose)
    795      1.1  christos                 BIO_printf(bio_err, "No entries found to mark expired\n");
    796      1.1  christos         } else {
    797      1.1  christos             if (!save_index(dbfile, "new", db))
    798      1.1  christos                 goto end;
    799      1.1  christos 
    800      1.1  christos             if (!rotate_index(dbfile, "new", "old"))
    801      1.1  christos                 goto end;
    802      1.1  christos 
    803      1.1  christos             if (verbose)
    804      1.1  christos                 BIO_printf(bio_err, "Done. %d entries marked as expired\n", i);
    805      1.1  christos         }
    806      1.1  christos     }
    807      1.1  christos 
    808      1.1  christos     /*****************************************************************/
    809      1.1  christos     /* Read extensions config file                                   */
    810      1.1  christos     if (extfile) {
    811      1.1  christos         if ((extfile_conf = app_load_config(extfile)) == NULL) {
    812      1.1  christos             ret = 1;
    813      1.1  christos             goto end;
    814      1.1  christos         }
    815      1.1  christos 
    816      1.1  christos         if (verbose)
    817      1.1  christos             BIO_printf(bio_err, "Successfully loaded extensions file %s\n",
    818  1.1.1.2  christos                 extfile);
    819      1.1  christos 
    820      1.1  christos         /* We can have sections in the ext file */
    821      1.1  christos         if (extensions == NULL) {
    822  1.1.1.2  christos             extensions = app_conf_try_string(extfile_conf, "default", "extensions");
    823      1.1  christos             if (extensions == NULL)
    824      1.1  christos                 extensions = "default";
    825      1.1  christos         }
    826      1.1  christos     }
    827      1.1  christos 
    828      1.1  christos     /*****************************************************************/
    829      1.1  christos     if (req || gencrl) {
    830      1.1  christos         if (spkac_file != NULL && outfile != NULL) {
    831      1.1  christos             output_der = 1;
    832      1.1  christos             batch = 1;
    833      1.1  christos         }
    834      1.1  christos     }
    835      1.1  christos 
    836      1.1  christos     def_ret = EVP_PKEY_get_default_digest_name(pkey, def_dgst, sizeof(def_dgst));
    837      1.1  christos     /*
    838      1.1  christos      * EVP_PKEY_get_default_digest_name() returns 2 if the digest is
    839      1.1  christos      * mandatory for this algorithm.
    840      1.1  christos      *
    841      1.1  christos      * That call may give back the name "UNDEF", which has these meanings:
    842      1.1  christos      *
    843      1.1  christos      * when def_ret == 2: the user MUST leave the digest unspecified
    844      1.1  christos      * when def_ret == 1: the user MAY leave the digest unspecified
    845      1.1  christos      */
    846      1.1  christos     if (def_ret == 2 && strcmp(def_dgst, "UNDEF") == 0) {
    847      1.1  christos         dgst = NULL;
    848      1.1  christos     } else if (dgst == NULL
    849  1.1.1.2  christos         && (dgst = lookup_conf(conf, section, ENV_DEFAULT_MD)) == NULL
    850  1.1.1.2  christos         && strcmp(def_dgst, "UNDEF") != 0) {
    851      1.1  christos         goto end;
    852      1.1  christos     } else {
    853      1.1  christos         if (strcmp(dgst, "default") == 0 || strcmp(def_dgst, "UNDEF") == 0) {
    854      1.1  christos             if (def_ret <= 0) {
    855      1.1  christos                 BIO_puts(bio_err, "no default digest\n");
    856      1.1  christos                 goto end;
    857      1.1  christos             }
    858      1.1  christos             dgst = def_dgst;
    859      1.1  christos         }
    860      1.1  christos     }
    861      1.1  christos 
    862      1.1  christos     if (req) {
    863      1.1  christos         if (email_dn == 1) {
    864      1.1  christos             char *tmp_email_dn = NULL;
    865      1.1  christos 
    866  1.1.1.2  christos             tmp_email_dn = app_conf_try_string(conf, section, ENV_DEFAULT_EMAIL_DN);
    867      1.1  christos             if (tmp_email_dn != NULL && strcmp(tmp_email_dn, "no") == 0)
    868      1.1  christos                 email_dn = 0;
    869      1.1  christos         }
    870      1.1  christos         if (verbose)
    871      1.1  christos             BIO_printf(bio_err, "message digest is %s\n", dgst);
    872      1.1  christos         if (policy == NULL
    873      1.1  christos             && (policy = lookup_conf(conf, section, ENV_POLICY)) == NULL)
    874      1.1  christos             goto end;
    875      1.1  christos 
    876      1.1  christos         if (verbose)
    877      1.1  christos             BIO_printf(bio_err, "policy is %s\n", policy);
    878      1.1  christos 
    879      1.1  christos         if (app_conf_try_string(conf, section, ENV_RAND_SERIAL) != NULL) {
    880      1.1  christos             rand_ser = 1;
    881      1.1  christos         } else {
    882      1.1  christos             serialfile = lookup_conf(conf, section, ENV_SERIAL);
    883      1.1  christos             if (serialfile == NULL)
    884      1.1  christos                 goto end;
    885      1.1  christos         }
    886      1.1  christos 
    887      1.1  christos         if (extfile_conf != NULL) {
    888      1.1  christos             /* Check syntax of extfile */
    889      1.1  christos             X509V3_CTX ctx;
    890      1.1  christos 
    891      1.1  christos             X509V3_set_ctx_test(&ctx);
    892      1.1  christos             X509V3_set_nconf(&ctx, extfile_conf);
    893      1.1  christos             if (!X509V3_EXT_add_nconf(extfile_conf, &ctx, extensions, NULL)) {
    894      1.1  christos                 BIO_printf(bio_err,
    895  1.1.1.2  christos                     "Error checking certificate extensions from extfile section %s\n",
    896  1.1.1.2  christos                     extensions);
    897      1.1  christos                 ret = 1;
    898      1.1  christos                 goto end;
    899      1.1  christos             }
    900      1.1  christos         } else {
    901      1.1  christos             /*
    902      1.1  christos              * no '-extfile' option, so we look for extensions in the main
    903      1.1  christos              * configuration file
    904      1.1  christos              */
    905      1.1  christos             if (extensions == NULL)
    906      1.1  christos                 extensions = app_conf_try_string(conf, section, ENV_EXTENSIONS);
    907      1.1  christos             if (extensions != NULL) {
    908      1.1  christos                 /* Check syntax of config file section */
    909      1.1  christos                 X509V3_CTX ctx;
    910      1.1  christos 
    911      1.1  christos                 X509V3_set_ctx_test(&ctx);
    912      1.1  christos                 X509V3_set_nconf(&ctx, conf);
    913      1.1  christos                 if (!X509V3_EXT_add_nconf(conf, &ctx, extensions, NULL)) {
    914      1.1  christos                     BIO_printf(bio_err,
    915  1.1.1.2  christos                         "Error checking certificate extension config section %s\n",
    916  1.1.1.2  christos                         extensions);
    917      1.1  christos                     ret = 1;
    918      1.1  christos                     goto end;
    919      1.1  christos                 }
    920      1.1  christos             }
    921      1.1  christos         }
    922      1.1  christos 
    923      1.1  christos         if (startdate == NULL)
    924  1.1.1.2  christos             startdate = app_conf_try_string(conf, section, ENV_DEFAULT_STARTDATE);
    925      1.1  christos         if (enddate == NULL)
    926      1.1  christos             enddate = app_conf_try_string(conf, section, ENV_DEFAULT_ENDDATE);
    927      1.1  christos         if (days == 0) {
    928      1.1  christos             if (!app_conf_try_number(conf, section, ENV_DEFAULT_DAYS, &days))
    929      1.1  christos                 days = 0;
    930      1.1  christos         }
    931      1.1  christos         if (enddate == NULL && days == 0) {
    932      1.1  christos             BIO_printf(bio_err, "cannot lookup how many days to certify for\n");
    933      1.1  christos             goto end;
    934      1.1  christos         }
    935      1.1  christos         if (days != 0 && enddate != NULL)
    936      1.1  christos             BIO_printf(bio_err,
    937  1.1.1.2  christos                 "Warning: -enddate or -not_after option overriding -days option\n");
    938      1.1  christos 
    939      1.1  christos         if (rand_ser) {
    940      1.1  christos             if ((serial = BN_new()) == NULL || !rand_serial(serial, NULL)) {
    941      1.1  christos                 BIO_printf(bio_err, "error generating serial number\n");
    942      1.1  christos                 goto end;
    943      1.1  christos             }
    944      1.1  christos         } else {
    945      1.1  christos             serial = load_serial(serialfile, NULL, create_ser, NULL);
    946      1.1  christos             if (serial == NULL) {
    947      1.1  christos                 BIO_printf(bio_err, "error while loading serial number\n");
    948      1.1  christos                 goto end;
    949      1.1  christos             }
    950      1.1  christos             if (verbose) {
    951      1.1  christos                 if (BN_is_zero(serial)) {
    952      1.1  christos                     BIO_printf(bio_err, "next serial number is 00\n");
    953      1.1  christos                 } else {
    954      1.1  christos                     if ((f = BN_bn2hex(serial)) == NULL)
    955      1.1  christos                         goto end;
    956      1.1  christos                     BIO_printf(bio_err, "next serial number is %s\n", f);
    957      1.1  christos                     OPENSSL_free(f);
    958      1.1  christos                 }
    959      1.1  christos             }
    960      1.1  christos         }
    961      1.1  christos 
    962      1.1  christos         if ((attribs = NCONF_get_section(conf, policy)) == NULL) {
    963      1.1  christos             BIO_printf(bio_err, "unable to find 'section' for %s\n", policy);
    964      1.1  christos             goto end;
    965      1.1  christos         }
    966      1.1  christos 
    967      1.1  christos         if ((cert_sk = sk_X509_new_null()) == NULL) {
    968      1.1  christos             BIO_printf(bio_err, "Memory allocation failure\n");
    969      1.1  christos             goto end;
    970      1.1  christos         }
    971      1.1  christos         if (spkac_file != NULL) {
    972      1.1  christos             total++;
    973      1.1  christos             j = certify_spkac(&x, spkac_file, pkey, x509, dgst, sigopts,
    974  1.1.1.2  christos                 attribs, db, serial, subj, chtype, multirdn,
    975  1.1.1.2  christos                 email_dn, startdate, enddate, days, extensions,
    976  1.1.1.2  christos                 conf, verbose, certopt, get_nameopt(), default_op,
    977  1.1.1.2  christos                 ext_copy, dateopt);
    978      1.1  christos             if (j < 0)
    979      1.1  christos                 goto end;
    980      1.1  christos             if (j > 0) {
    981      1.1  christos                 total_done++;
    982      1.1  christos                 BIO_printf(bio_err, "\n");
    983      1.1  christos                 if (!BN_add_word(serial, 1))
    984      1.1  christos                     goto end;
    985      1.1  christos                 if (!sk_X509_push(cert_sk, x)) {
    986      1.1  christos                     BIO_printf(bio_err, "Memory allocation failure\n");
    987      1.1  christos                     goto end;
    988      1.1  christos                 }
    989      1.1  christos             }
    990      1.1  christos         }
    991      1.1  christos         if (ss_cert_file != NULL) {
    992      1.1  christos             total++;
    993      1.1  christos             j = certify_cert(&x, ss_cert_file, certformat, passin, pkey,
    994  1.1.1.2  christos                 x509, dgst, sigopts, vfyopts, attribs,
    995  1.1.1.2  christos                 db, serial, subj, chtype, multirdn, email_dn,
    996  1.1.1.2  christos                 startdate, enddate, days, batch, extensions,
    997  1.1.1.2  christos                 conf, verbose, certopt, get_nameopt(), default_op,
    998  1.1.1.2  christos                 ext_copy, dateopt);
    999      1.1  christos             if (j < 0)
   1000      1.1  christos                 goto end;
   1001      1.1  christos             if (j > 0) {
   1002      1.1  christos                 total_done++;
   1003      1.1  christos                 BIO_printf(bio_err, "\n");
   1004      1.1  christos                 if (!BN_add_word(serial, 1))
   1005      1.1  christos                     goto end;
   1006      1.1  christos                 if (!sk_X509_push(cert_sk, x)) {
   1007      1.1  christos                     BIO_printf(bio_err, "Memory allocation failure\n");
   1008      1.1  christos                     goto end;
   1009      1.1  christos                 }
   1010      1.1  christos             }
   1011      1.1  christos         }
   1012      1.1  christos         if (infile != NULL) {
   1013      1.1  christos             total++;
   1014      1.1  christos             j = certify(&x, infile, informat, pkey, x509p, dgst,
   1015  1.1.1.2  christos                 sigopts, vfyopts, attribs, db,
   1016  1.1.1.2  christos                 serial, subj, chtype, multirdn, email_dn, startdate,
   1017  1.1.1.2  christos                 enddate, days, batch, extensions, conf, verbose,
   1018  1.1.1.2  christos                 certopt, get_nameopt(), default_op, ext_copy, selfsign, dateopt);
   1019      1.1  christos             if (j < 0)
   1020      1.1  christos                 goto end;
   1021      1.1  christos             if (j > 0) {
   1022      1.1  christos                 total_done++;
   1023      1.1  christos                 BIO_printf(bio_err, "\n");
   1024      1.1  christos                 if (!BN_add_word(serial, 1))
   1025      1.1  christos                     goto end;
   1026      1.1  christos                 if (!sk_X509_push(cert_sk, x)) {
   1027      1.1  christos                     BIO_printf(bio_err, "Memory allocation failure\n");
   1028      1.1  christos                     goto end;
   1029      1.1  christos                 }
   1030      1.1  christos             }
   1031      1.1  christos         }
   1032      1.1  christos         for (i = 0; i < argc; i++) {
   1033      1.1  christos             total++;
   1034      1.1  christos             j = certify(&x, argv[i], informat, pkey, x509p, dgst,
   1035  1.1.1.2  christos                 sigopts, vfyopts,
   1036  1.1.1.2  christos                 attribs, db,
   1037  1.1.1.2  christos                 serial, subj, chtype, multirdn, email_dn, startdate,
   1038  1.1.1.2  christos                 enddate, days, batch, extensions, conf, verbose,
   1039  1.1.1.2  christos                 certopt, get_nameopt(), default_op, ext_copy, selfsign, dateopt);
   1040      1.1  christos             if (j < 0)
   1041      1.1  christos                 goto end;
   1042      1.1  christos             if (j > 0) {
   1043      1.1  christos                 total_done++;
   1044      1.1  christos                 BIO_printf(bio_err, "\n");
   1045      1.1  christos                 if (!BN_add_word(serial, 1)) {
   1046      1.1  christos                     X509_free(x);
   1047      1.1  christos                     goto end;
   1048      1.1  christos                 }
   1049      1.1  christos                 if (!sk_X509_push(cert_sk, x)) {
   1050      1.1  christos                     BIO_printf(bio_err, "Memory allocation failure\n");
   1051      1.1  christos                     X509_free(x);
   1052      1.1  christos                     goto end;
   1053      1.1  christos                 }
   1054      1.1  christos             }
   1055      1.1  christos         }
   1056      1.1  christos         /*
   1057      1.1  christos          * we have a stack of newly certified certificates and a database
   1058      1.1  christos          * and serial number that need updating
   1059      1.1  christos          */
   1060      1.1  christos 
   1061      1.1  christos         if (sk_X509_num(cert_sk) > 0) {
   1062      1.1  christos             if (!batch) {
   1063      1.1  christos                 BIO_printf(bio_err,
   1064  1.1.1.2  christos                     "\n%d out of %d certificate requests certified, commit? [y/n]",
   1065  1.1.1.2  christos                     total_done, total);
   1066      1.1  christos                 (void)BIO_flush(bio_err);
   1067      1.1  christos                 tmp[0] = '\0';
   1068      1.1  christos                 if (fgets(tmp, sizeof(tmp), stdin) == NULL) {
   1069      1.1  christos                     BIO_printf(bio_err, "CERTIFICATION CANCELED: I/O error\n");
   1070      1.1  christos                     ret = 0;
   1071      1.1  christos                     goto end;
   1072      1.1  christos                 }
   1073      1.1  christos                 if (tmp[0] != 'y' && tmp[0] != 'Y') {
   1074      1.1  christos                     BIO_printf(bio_err, "CERTIFICATION CANCELED\n");
   1075      1.1  christos                     ret = 0;
   1076      1.1  christos                     goto end;
   1077      1.1  christos                 }
   1078      1.1  christos             }
   1079      1.1  christos 
   1080      1.1  christos             BIO_printf(bio_err, "Write out database with %d new entries\n",
   1081  1.1.1.2  christos                 sk_X509_num(cert_sk));
   1082      1.1  christos 
   1083      1.1  christos             if (serialfile != NULL
   1084  1.1.1.2  christos                 && !save_serial(serialfile, "new", serial, NULL))
   1085      1.1  christos                 goto end;
   1086      1.1  christos 
   1087      1.1  christos             if (!save_index(dbfile, "new", db))
   1088      1.1  christos                 goto end;
   1089      1.1  christos         }
   1090      1.1  christos 
   1091      1.1  christos         outdirlen = OPENSSL_strlcpy(new_cert, outdir, sizeof(new_cert));
   1092      1.1  christos #ifndef OPENSSL_SYS_VMS
   1093      1.1  christos         outdirlen = OPENSSL_strlcat(new_cert, "/", sizeof(new_cert));
   1094      1.1  christos #endif
   1095      1.1  christos 
   1096      1.1  christos         if (verbose)
   1097      1.1  christos             BIO_printf(bio_err, "writing new certificates\n");
   1098      1.1  christos 
   1099      1.1  christos         for (i = 0; i < sk_X509_num(cert_sk); i++) {
   1100      1.1  christos             BIO *Cout = NULL;
   1101      1.1  christos             X509 *xi = sk_X509_value(cert_sk, i);
   1102      1.1  christos             const ASN1_INTEGER *serialNumber = X509_get0_serialNumber(xi);
   1103      1.1  christos             const unsigned char *psn = ASN1_STRING_get0_data(serialNumber);
   1104      1.1  christos             const int snl = ASN1_STRING_length(serialNumber);
   1105      1.1  christos             const int filen_len = 2 * (snl > 0 ? snl : 1) + sizeof(".pem");
   1106      1.1  christos             char *n = new_cert + outdirlen;
   1107      1.1  christos 
   1108      1.1  christos             if (outdirlen + filen_len > PATH_MAX) {
   1109      1.1  christos                 BIO_printf(bio_err, "certificate file name too long\n");
   1110      1.1  christos                 goto end;
   1111      1.1  christos             }
   1112      1.1  christos 
   1113      1.1  christos             if (snl > 0) {
   1114      1.1  christos                 static const char HEX_DIGITS[] = "0123456789ABCDEF";
   1115      1.1  christos 
   1116      1.1  christos                 for (j = 0; j < snl; j++, psn++) {
   1117      1.1  christos                     *n++ = HEX_DIGITS[*psn >> 4];
   1118      1.1  christos                     *n++ = HEX_DIGITS[*psn & 0x0F];
   1119      1.1  christos                 }
   1120      1.1  christos             } else {
   1121      1.1  christos                 *(n++) = '0';
   1122      1.1  christos                 *(n++) = '0';
   1123      1.1  christos             }
   1124      1.1  christos             *(n++) = '.';
   1125      1.1  christos             *(n++) = 'p';
   1126      1.1  christos             *(n++) = 'e';
   1127      1.1  christos             *(n++) = 'm';
   1128  1.1.1.2  christos             *n = '\0'; /* closing new_cert */
   1129      1.1  christos             if (verbose)
   1130      1.1  christos                 BIO_printf(bio_err, "writing %s\n", new_cert);
   1131      1.1  christos 
   1132      1.1  christos             Sout = bio_open_default(outfile, 'w',
   1133  1.1.1.2  christos                 output_der ? FORMAT_ASN1 : FORMAT_TEXT);
   1134      1.1  christos             if (Sout == NULL)
   1135      1.1  christos                 goto end;
   1136      1.1  christos 
   1137      1.1  christos             Cout = BIO_new_file(new_cert, "w");
   1138      1.1  christos             if (Cout == NULL) {
   1139      1.1  christos                 perror(new_cert);
   1140      1.1  christos                 goto end;
   1141      1.1  christos             }
   1142      1.1  christos             write_new_certificate(Cout, xi, 0, notext);
   1143      1.1  christos             write_new_certificate(Sout, xi, output_der, notext);
   1144      1.1  christos             BIO_free_all(Cout);
   1145      1.1  christos             BIO_free_all(Sout);
   1146      1.1  christos             Sout = NULL;
   1147      1.1  christos         }
   1148      1.1  christos 
   1149      1.1  christos         if (sk_X509_num(cert_sk)) {
   1150      1.1  christos             /* Rename the database and the serial file */
   1151      1.1  christos             if (serialfile != NULL
   1152  1.1.1.2  christos                 && !rotate_serial(serialfile, "new", "old"))
   1153      1.1  christos                 goto end;
   1154      1.1  christos 
   1155      1.1  christos             if (!rotate_index(dbfile, "new", "old"))
   1156      1.1  christos                 goto end;
   1157      1.1  christos 
   1158      1.1  christos             BIO_printf(bio_err, "Database updated\n");
   1159      1.1  christos         }
   1160      1.1  christos     }
   1161      1.1  christos 
   1162      1.1  christos     /*****************************************************************/
   1163      1.1  christos     if (gencrl) {
   1164      1.1  christos         int crl_v2 = 0;
   1165      1.1  christos 
   1166      1.1  christos         if (crl_ext == NULL)
   1167      1.1  christos             crl_ext = app_conf_try_string(conf, section, ENV_CRLEXT);
   1168      1.1  christos         if (crl_ext != NULL) {
   1169      1.1  christos             /* Check syntax of file */
   1170      1.1  christos             X509V3_CTX ctx;
   1171      1.1  christos 
   1172      1.1  christos             X509V3_set_ctx_test(&ctx);
   1173      1.1  christos             X509V3_set_nconf(&ctx, conf);
   1174      1.1  christos             if (!X509V3_EXT_add_nconf(conf, &ctx, crl_ext, NULL)) {
   1175      1.1  christos                 BIO_printf(bio_err,
   1176  1.1.1.2  christos                     "Error checking CRL extension section %s\n", crl_ext);
   1177      1.1  christos                 ret = 1;
   1178      1.1  christos                 goto end;
   1179      1.1  christos             }
   1180      1.1  christos         }
   1181      1.1  christos 
   1182      1.1  christos         crlnumberfile = app_conf_try_string(conf, section, ENV_CRLNUMBER);
   1183      1.1  christos         if (crlnumberfile != NULL) {
   1184      1.1  christos             if ((crlnumber = load_serial(crlnumberfile, NULL, 0, NULL))
   1185      1.1  christos                 == NULL) {
   1186      1.1  christos                 BIO_printf(bio_err, "error while loading CRL number\n");
   1187      1.1  christos                 goto end;
   1188      1.1  christos             }
   1189      1.1  christos         }
   1190      1.1  christos 
   1191      1.1  christos         if (!crldays && !crlhours && !crlsec) {
   1192      1.1  christos             if (!app_conf_try_number(conf, section,
   1193  1.1.1.2  christos                     ENV_DEFAULT_CRL_DAYS, &crldays))
   1194      1.1  christos                 crldays = 0;
   1195      1.1  christos             if (!app_conf_try_number(conf, section,
   1196  1.1.1.2  christos                     ENV_DEFAULT_CRL_HOURS, &crlhours))
   1197      1.1  christos                 crlhours = 0;
   1198      1.1  christos         }
   1199  1.1.1.2  christos         if ((crl_nextupdate == NULL) && (crldays == 0) && (crlhours == 0) && (crlsec == 0)) {
   1200      1.1  christos             BIO_printf(bio_err,
   1201  1.1.1.2  christos                 "cannot lookup how long until the next CRL is issued\n");
   1202      1.1  christos             goto end;
   1203      1.1  christos         }
   1204      1.1  christos 
   1205      1.1  christos         if (verbose)
   1206      1.1  christos             BIO_printf(bio_err, "making CRL\n");
   1207      1.1  christos         if ((crl = X509_CRL_new_ex(app_get0_libctx(), app_get0_propq())) == NULL)
   1208      1.1  christos             goto end;
   1209      1.1  christos         if (!X509_CRL_set_issuer_name(crl, X509_get_subject_name(x509)))
   1210      1.1  christos             goto end;
   1211      1.1  christos 
   1212      1.1  christos         if (!set_crl_lastupdate(crl, crl_lastupdate)) {
   1213      1.1  christos             BIO_puts(bio_err, "error setting CRL lastUpdate\n");
   1214      1.1  christos             ret = 1;
   1215      1.1  christos             goto end;
   1216      1.1  christos         }
   1217      1.1  christos 
   1218      1.1  christos         if (!set_crl_nextupdate(crl, crl_nextupdate,
   1219  1.1.1.2  christos                 crldays, crlhours, crlsec)) {
   1220      1.1  christos             BIO_puts(bio_err, "error setting CRL nextUpdate\n");
   1221      1.1  christos             ret = 1;
   1222      1.1  christos             goto end;
   1223      1.1  christos         }
   1224      1.1  christos 
   1225      1.1  christos         for (i = 0; i < sk_OPENSSL_PSTRING_num(db->db->data); i++) {
   1226      1.1  christos             pp = sk_OPENSSL_PSTRING_value(db->db->data, i);
   1227      1.1  christos             if (pp[DB_type][0] == DB_TYPE_REV) {
   1228      1.1  christos                 if ((r = X509_REVOKED_new()) == NULL)
   1229      1.1  christos                     goto end;
   1230      1.1  christos                 j = make_revoked(r, pp[DB_rev_date]);
   1231      1.1  christos                 if (!j)
   1232      1.1  christos                     goto end;
   1233      1.1  christos                 if (j == 2)
   1234      1.1  christos                     crl_v2 = 1;
   1235      1.1  christos                 if (!BN_hex2bn(&serial, pp[DB_serial]))
   1236      1.1  christos                     goto end;
   1237      1.1  christos                 tmpser = BN_to_ASN1_INTEGER(serial, NULL);
   1238      1.1  christos                 BN_free(serial);
   1239      1.1  christos                 serial = NULL;
   1240      1.1  christos                 if (!tmpser)
   1241      1.1  christos                     goto end;
   1242      1.1  christos                 X509_REVOKED_set_serialNumber(r, tmpser);
   1243      1.1  christos                 ASN1_INTEGER_free(tmpser);
   1244      1.1  christos                 X509_CRL_add0_revoked(crl, r);
   1245      1.1  christos             }
   1246      1.1  christos         }
   1247      1.1  christos 
   1248      1.1  christos         /*
   1249      1.1  christos          * sort the data so it will be written in serial number order
   1250      1.1  christos          */
   1251      1.1  christos         X509_CRL_sort(crl);
   1252      1.1  christos 
   1253      1.1  christos         /* we now have a CRL */
   1254      1.1  christos         if (verbose)
   1255      1.1  christos             BIO_printf(bio_err, "signing CRL\n");
   1256      1.1  christos 
   1257      1.1  christos         /* Add any extensions asked for */
   1258      1.1  christos 
   1259      1.1  christos         if (crl_ext != NULL || crlnumberfile != NULL) {
   1260      1.1  christos             X509V3_CTX crlctx;
   1261      1.1  christos 
   1262      1.1  christos             X509V3_set_ctx(&crlctx, x509, NULL, NULL, crl, 0);
   1263      1.1  christos             X509V3_set_nconf(&crlctx, conf);
   1264      1.1  christos 
   1265      1.1  christos             if (crl_ext != NULL)
   1266      1.1  christos                 if (!X509V3_EXT_CRL_add_nconf(conf, &crlctx, crl_ext, crl)) {
   1267      1.1  christos                     BIO_printf(bio_err,
   1268  1.1.1.2  christos                         "Error adding CRL extensions from section %s\n", crl_ext);
   1269      1.1  christos                     goto end;
   1270      1.1  christos                 }
   1271      1.1  christos             if (crlnumberfile != NULL) {
   1272      1.1  christos                 tmpser = BN_to_ASN1_INTEGER(crlnumber, NULL);
   1273      1.1  christos                 if (!tmpser)
   1274      1.1  christos                     goto end;
   1275      1.1  christos                 X509_CRL_add1_ext_i2d(crl, NID_crl_number, tmpser, 0, 0);
   1276      1.1  christos                 ASN1_INTEGER_free(tmpser);
   1277      1.1  christos                 crl_v2 = 1;
   1278      1.1  christos                 if (!BN_add_word(crlnumber, 1))
   1279      1.1  christos                     goto end;
   1280      1.1  christos             }
   1281      1.1  christos         }
   1282      1.1  christos         if (crl_ext != NULL || crl_v2) {
   1283      1.1  christos             if (!X509_CRL_set_version(crl, X509_CRL_VERSION_2))
   1284      1.1  christos                 goto end;
   1285      1.1  christos         }
   1286      1.1  christos 
   1287      1.1  christos         /* we have a CRL number that need updating */
   1288      1.1  christos         if (crlnumberfile != NULL
   1289  1.1.1.2  christos             && !save_serial(crlnumberfile, "new", crlnumber, NULL))
   1290      1.1  christos             goto end;
   1291      1.1  christos 
   1292      1.1  christos         BN_free(crlnumber);
   1293      1.1  christos         crlnumber = NULL;
   1294      1.1  christos 
   1295      1.1  christos         if (!do_X509_CRL_sign(crl, pkey, dgst, sigopts))
   1296      1.1  christos             goto end;
   1297      1.1  christos 
   1298      1.1  christos         Sout = bio_open_default(outfile, 'w',
   1299  1.1.1.2  christos             output_der ? FORMAT_ASN1 : FORMAT_TEXT);
   1300      1.1  christos         if (Sout == NULL)
   1301      1.1  christos             goto end;
   1302      1.1  christos 
   1303      1.1  christos         PEM_write_bio_X509_CRL(Sout, crl);
   1304      1.1  christos 
   1305      1.1  christos         /* Rename the crlnumber file */
   1306      1.1  christos         if (crlnumberfile != NULL
   1307  1.1.1.2  christos             && !rotate_serial(crlnumberfile, "new", "old"))
   1308      1.1  christos             goto end;
   1309      1.1  christos     }
   1310      1.1  christos     /*****************************************************************/
   1311      1.1  christos     if (dorevoke) {
   1312      1.1  christos         if (infile == NULL) {
   1313      1.1  christos             BIO_printf(bio_err, "no input files\n");
   1314      1.1  christos             goto end;
   1315      1.1  christos         } else {
   1316      1.1  christos             X509 *revcert;
   1317      1.1  christos 
   1318      1.1  christos             revcert = load_cert_pass(infile, informat, 1, passin,
   1319  1.1.1.2  christos                 "certificate to be revoked");
   1320      1.1  christos             if (revcert == NULL)
   1321      1.1  christos                 goto end;
   1322      1.1  christos             if (dorevoke == 2)
   1323      1.1  christos                 rev_type = REV_VALID;
   1324      1.1  christos             j = do_revoke(revcert, db, rev_type, rev_arg);
   1325      1.1  christos             if (j <= 0)
   1326      1.1  christos                 goto end;
   1327      1.1  christos             X509_free(revcert);
   1328      1.1  christos 
   1329      1.1  christos             if (!save_index(dbfile, "new", db))
   1330      1.1  christos                 goto end;
   1331      1.1  christos 
   1332      1.1  christos             if (!rotate_index(dbfile, "new", "old"))
   1333      1.1  christos                 goto end;
   1334      1.1  christos 
   1335      1.1  christos             BIO_printf(bio_err, "Database updated\n");
   1336      1.1  christos         }
   1337      1.1  christos     }
   1338      1.1  christos     ret = 0;
   1339      1.1  christos 
   1340  1.1.1.2  christos end:
   1341      1.1  christos     if (ret)
   1342      1.1  christos         ERR_print_errors(bio_err);
   1343      1.1  christos     BIO_free_all(Sout);
   1344      1.1  christos     BIO_free_all(out);
   1345      1.1  christos     BIO_free_all(in);
   1346      1.1  christos     OSSL_STACK_OF_X509_free(cert_sk);
   1347      1.1  christos 
   1348      1.1  christos     cleanse(passin);
   1349      1.1  christos     if (free_passin)
   1350      1.1  christos         OPENSSL_free(passin);
   1351      1.1  christos     BN_free(serial);
   1352      1.1  christos     BN_free(crlnumber);
   1353      1.1  christos     free_index(db);
   1354      1.1  christos     sk_OPENSSL_STRING_free(sigopts);
   1355      1.1  christos     sk_OPENSSL_STRING_free(vfyopts);
   1356      1.1  christos     EVP_PKEY_free(pkey);
   1357      1.1  christos     X509_free(x509);
   1358      1.1  christos     X509_CRL_free(crl);
   1359      1.1  christos     NCONF_free(conf);
   1360      1.1  christos     NCONF_free(extfile_conf);
   1361      1.1  christos     release_engine(e);
   1362      1.1  christos     return ret;
   1363      1.1  christos }
   1364      1.1  christos 
   1365      1.1  christos static char *lookup_conf(const CONF *conf, const char *section, const char *tag)
   1366      1.1  christos {
   1367      1.1  christos     char *entry = NCONF_get_string(conf, section, tag);
   1368      1.1  christos     if (entry == NULL)
   1369      1.1  christos         BIO_printf(bio_err, "variable lookup failed for %s::%s\n", section, tag);
   1370      1.1  christos     return entry;
   1371      1.1  christos }
   1372      1.1  christos 
   1373      1.1  christos static int certify(X509 **xret, const char *infile, int informat,
   1374  1.1.1.2  christos     EVP_PKEY *pkey, X509 *x509,
   1375  1.1.1.2  christos     const char *dgst,
   1376  1.1.1.2  christos     STACK_OF(OPENSSL_STRING) *sigopts,
   1377  1.1.1.2  christos     STACK_OF(OPENSSL_STRING) *vfyopts,
   1378  1.1.1.2  christos     STACK_OF(CONF_VALUE) *policy, CA_DB *db,
   1379  1.1.1.2  christos     BIGNUM *serial, const char *subj, unsigned long chtype,
   1380  1.1.1.2  christos     int multirdn, int email_dn, const char *startdate,
   1381  1.1.1.2  christos     const char *enddate,
   1382  1.1.1.2  christos     long days, int batch, const char *ext_sect, CONF *lconf,
   1383  1.1.1.2  christos     int verbose, unsigned long certopt, unsigned long nameopt,
   1384  1.1.1.2  christos     int default_op, int ext_copy, int selfsign, unsigned long dateopt)
   1385      1.1  christos {
   1386      1.1  christos     X509_REQ *req = NULL;
   1387      1.1  christos     EVP_PKEY *pktmp = NULL;
   1388      1.1  christos     int ok = -1, i;
   1389      1.1  christos 
   1390      1.1  christos     req = load_csr_autofmt(infile, informat, vfyopts, "certificate request");
   1391      1.1  christos     if (req == NULL)
   1392      1.1  christos         goto end;
   1393      1.1  christos     if ((pktmp = X509_REQ_get0_pubkey(req)) == NULL) {
   1394      1.1  christos         BIO_printf(bio_err, "Error unpacking public key\n");
   1395      1.1  christos         goto end;
   1396      1.1  christos     }
   1397      1.1  christos     if (verbose)
   1398      1.1  christos         X509_REQ_print_ex(bio_err, req, nameopt, X509_FLAG_COMPAT);
   1399      1.1  christos 
   1400      1.1  christos     BIO_printf(bio_err, "Check that the request matches the signature\n");
   1401      1.1  christos     ok = 0;
   1402      1.1  christos 
   1403      1.1  christos     if (selfsign && !X509_REQ_check_private_key(req, pkey)) {
   1404      1.1  christos         BIO_printf(bio_err,
   1405  1.1.1.2  christos             "Certificate request and CA private key do not match\n");
   1406      1.1  christos         goto end;
   1407      1.1  christos     }
   1408      1.1  christos     i = do_X509_REQ_verify(req, pktmp, vfyopts);
   1409      1.1  christos     if (i < 0) {
   1410      1.1  christos         BIO_printf(bio_err, "Signature verification problems...\n");
   1411      1.1  christos         goto end;
   1412      1.1  christos     }
   1413      1.1  christos     if (i == 0) {
   1414      1.1  christos         BIO_printf(bio_err,
   1415  1.1.1.2  christos             "Signature did not match the certificate request\n");
   1416      1.1  christos         goto end;
   1417      1.1  christos     }
   1418      1.1  christos     BIO_printf(bio_err, "Signature ok\n");
   1419      1.1  christos 
   1420      1.1  christos     ok = do_body(xret, pkey, x509, dgst, sigopts, policy, db, serial, subj,
   1421  1.1.1.2  christos         chtype, multirdn, email_dn, startdate, enddate, days, batch,
   1422  1.1.1.2  christos         verbose, req, ext_sect, lconf, certopt, nameopt, default_op,
   1423  1.1.1.2  christos         ext_copy, selfsign, dateopt);
   1424      1.1  christos 
   1425  1.1.1.2  christos end:
   1426      1.1  christos     ERR_print_errors(bio_err);
   1427      1.1  christos     X509_REQ_free(req);
   1428      1.1  christos     return ok;
   1429      1.1  christos }
   1430      1.1  christos 
   1431      1.1  christos static int certify_cert(X509 **xret, const char *infile, int certformat,
   1432  1.1.1.2  christos     const char *passin, EVP_PKEY *pkey, X509 *x509,
   1433  1.1.1.2  christos     const char *dgst,
   1434  1.1.1.2  christos     STACK_OF(OPENSSL_STRING) *sigopts,
   1435  1.1.1.2  christos     STACK_OF(OPENSSL_STRING) *vfyopts,
   1436  1.1.1.2  christos     STACK_OF(CONF_VALUE) *policy, CA_DB *db,
   1437  1.1.1.2  christos     BIGNUM *serial, const char *subj, unsigned long chtype,
   1438  1.1.1.2  christos     int multirdn, int email_dn, const char *startdate,
   1439  1.1.1.2  christos     const char *enddate, long days, int batch, const char *ext_sect,
   1440  1.1.1.2  christos     CONF *lconf, int verbose, unsigned long certopt,
   1441  1.1.1.2  christos     unsigned long nameopt, int default_op, int ext_copy, unsigned long dateopt)
   1442      1.1  christos {
   1443      1.1  christos     X509 *template_cert = NULL;
   1444      1.1  christos     X509_REQ *rreq = NULL;
   1445      1.1  christos     EVP_PKEY *pktmp = NULL;
   1446      1.1  christos     int ok = -1, i;
   1447      1.1  christos 
   1448      1.1  christos     if ((template_cert = load_cert_pass(infile, certformat, 1, passin,
   1449  1.1.1.2  christos              "template certificate"))
   1450  1.1.1.2  christos         == NULL)
   1451      1.1  christos         goto end;
   1452      1.1  christos     if (verbose)
   1453      1.1  christos         X509_print(bio_err, template_cert);
   1454      1.1  christos 
   1455      1.1  christos     BIO_printf(bio_err, "Check that the request matches the signature\n");
   1456      1.1  christos 
   1457      1.1  christos     if ((pktmp = X509_get0_pubkey(template_cert)) == NULL) {
   1458      1.1  christos         BIO_printf(bio_err, "error unpacking public key\n");
   1459      1.1  christos         goto end;
   1460      1.1  christos     }
   1461      1.1  christos     i = do_X509_verify(template_cert, pktmp, vfyopts);
   1462      1.1  christos     if (i < 0) {
   1463      1.1  christos         ok = 0;
   1464      1.1  christos         BIO_printf(bio_err, "Signature verification problems....\n");
   1465      1.1  christos         goto end;
   1466      1.1  christos     }
   1467      1.1  christos     if (i == 0) {
   1468      1.1  christos         ok = 0;
   1469      1.1  christos         BIO_printf(bio_err, "Signature did not match the certificate\n");
   1470      1.1  christos         goto end;
   1471      1.1  christos     } else {
   1472      1.1  christos         BIO_printf(bio_err, "Signature ok\n");
   1473      1.1  christos     }
   1474      1.1  christos 
   1475      1.1  christos     if ((rreq = X509_to_X509_REQ(template_cert, NULL, NULL)) == NULL)
   1476      1.1  christos         goto end;
   1477      1.1  christos 
   1478      1.1  christos     ok = do_body(xret, pkey, x509, dgst, sigopts, policy, db, serial, subj,
   1479  1.1.1.2  christos         chtype, multirdn, email_dn, startdate, enddate, days, batch,
   1480  1.1.1.2  christos         verbose, rreq, ext_sect, lconf, certopt, nameopt, default_op,
   1481  1.1.1.2  christos         ext_copy, 0, dateopt);
   1482      1.1  christos 
   1483  1.1.1.2  christos end:
   1484      1.1  christos     X509_REQ_free(rreq);
   1485      1.1  christos     X509_free(template_cert);
   1486      1.1  christos     return ok;
   1487      1.1  christos }
   1488      1.1  christos 
   1489      1.1  christos static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509,
   1490  1.1.1.2  christos     const char *dgst, STACK_OF(OPENSSL_STRING) *sigopts,
   1491  1.1.1.2  christos     STACK_OF(CONF_VALUE) *policy, CA_DB *db, BIGNUM *serial,
   1492  1.1.1.2  christos     const char *subj, unsigned long chtype, int multirdn,
   1493  1.1.1.2  christos     int email_dn, const char *startdate, const char *enddate, long days,
   1494  1.1.1.2  christos     int batch, int verbose, X509_REQ *req, const char *ext_sect,
   1495  1.1.1.2  christos     CONF *lconf, unsigned long certopt, unsigned long nameopt,
   1496  1.1.1.2  christos     int default_op, int ext_copy, int selfsign, unsigned long dateopt)
   1497      1.1  christos {
   1498      1.1  christos     const X509_NAME *name = NULL;
   1499      1.1  christos     X509_NAME *CAname = NULL, *subject = NULL;
   1500      1.1  christos     const ASN1_TIME *tm;
   1501      1.1  christos     ASN1_STRING *str, *str2;
   1502      1.1  christos     ASN1_OBJECT *obj;
   1503      1.1  christos     X509 *ret = NULL;
   1504      1.1  christos     X509_NAME_ENTRY *ne, *tne;
   1505      1.1  christos     EVP_PKEY *pktmp;
   1506      1.1  christos     int ok = -1, i, j, last, nid;
   1507      1.1  christos     const char *p;
   1508      1.1  christos     CONF_VALUE *cv;
   1509      1.1  christos     OPENSSL_STRING row[DB_NUMBER];
   1510      1.1  christos     OPENSSL_STRING *irow = NULL;
   1511      1.1  christos     OPENSSL_STRING *rrow = NULL;
   1512      1.1  christos     char buf[25];
   1513      1.1  christos     X509V3_CTX ext_ctx;
   1514      1.1  christos 
   1515      1.1  christos     for (i = 0; i < DB_NUMBER; i++)
   1516      1.1  christos         row[i] = NULL;
   1517      1.1  christos 
   1518      1.1  christos     if (subj) {
   1519      1.1  christos         X509_NAME *n = parse_name(subj, chtype, multirdn, "subject");
   1520      1.1  christos 
   1521      1.1  christos         if (!n)
   1522      1.1  christos             goto end;
   1523      1.1  christos         X509_REQ_set_subject_name(req, n);
   1524      1.1  christos         X509_NAME_free(n);
   1525      1.1  christos     }
   1526      1.1  christos 
   1527      1.1  christos     if (default_op)
   1528      1.1  christos         BIO_printf(bio_err, "The Subject's Distinguished Name is as follows\n");
   1529      1.1  christos 
   1530      1.1  christos     name = X509_REQ_get_subject_name(req);
   1531      1.1  christos     for (i = 0; i < X509_NAME_entry_count(name); i++) {
   1532      1.1  christos         ne = X509_NAME_get_entry(name, i);
   1533      1.1  christos         str = X509_NAME_ENTRY_get_data(ne);
   1534      1.1  christos         obj = X509_NAME_ENTRY_get_object(ne);
   1535      1.1  christos         nid = OBJ_obj2nid(obj);
   1536      1.1  christos 
   1537      1.1  christos         if (msie_hack) {
   1538      1.1  christos             /* assume all type should be strings */
   1539      1.1  christos 
   1540      1.1  christos             if (str->type == V_ASN1_UNIVERSALSTRING)
   1541      1.1  christos                 ASN1_UNIVERSALSTRING_to_string(str);
   1542      1.1  christos 
   1543      1.1  christos             if (str->type == V_ASN1_IA5STRING && nid != NID_pkcs9_emailAddress)
   1544      1.1  christos                 str->type = V_ASN1_T61STRING;
   1545      1.1  christos 
   1546      1.1  christos             if (nid == NID_pkcs9_emailAddress
   1547      1.1  christos                 && str->type == V_ASN1_PRINTABLESTRING)
   1548      1.1  christos                 str->type = V_ASN1_IA5STRING;
   1549      1.1  christos         }
   1550      1.1  christos 
   1551      1.1  christos         /* If no EMAIL is wanted in the subject */
   1552      1.1  christos         if (nid == NID_pkcs9_emailAddress && !email_dn)
   1553      1.1  christos             continue;
   1554      1.1  christos 
   1555      1.1  christos         /* check some things */
   1556      1.1  christos         if (nid == NID_pkcs9_emailAddress && str->type != V_ASN1_IA5STRING) {
   1557      1.1  christos             BIO_printf(bio_err,
   1558  1.1.1.2  christos                 "\nemailAddress type needs to be of type IA5STRING\n");
   1559      1.1  christos             goto end;
   1560      1.1  christos         }
   1561      1.1  christos         if (str->type != V_ASN1_BMPSTRING && str->type != V_ASN1_UTF8STRING) {
   1562      1.1  christos             j = ASN1_PRINTABLE_type(str->data, str->length);
   1563  1.1.1.2  christos             if ((j == V_ASN1_T61STRING && str->type != V_ASN1_T61STRING) || (j == V_ASN1_IA5STRING && str->type == V_ASN1_PRINTABLESTRING)) {
   1564      1.1  christos                 BIO_printf(bio_err,
   1565  1.1.1.2  christos                     "\nThe string contains characters that are illegal for the ASN.1 type\n");
   1566      1.1  christos                 goto end;
   1567      1.1  christos             }
   1568      1.1  christos         }
   1569      1.1  christos 
   1570      1.1  christos         if (default_op)
   1571      1.1  christos             old_entry_print(obj, str);
   1572      1.1  christos     }
   1573      1.1  christos 
   1574      1.1  christos     /* Ok, now we check the 'policy' stuff. */
   1575      1.1  christos     if ((subject = X509_NAME_new()) == NULL) {
   1576      1.1  christos         BIO_printf(bio_err, "Memory allocation failure\n");
   1577      1.1  christos         goto end;
   1578      1.1  christos     }
   1579      1.1  christos 
   1580      1.1  christos     /* take a copy of the issuer name before we mess with it. */
   1581      1.1  christos     if (selfsign)
   1582      1.1  christos         CAname = X509_NAME_dup(name);
   1583      1.1  christos     else
   1584      1.1  christos         CAname = X509_NAME_dup(X509_get_subject_name(x509));
   1585      1.1  christos     if (CAname == NULL)
   1586      1.1  christos         goto end;
   1587      1.1  christos     str = str2 = NULL;
   1588      1.1  christos 
   1589      1.1  christos     for (i = 0; i < sk_CONF_VALUE_num(policy); i++) {
   1590      1.1  christos         cv = sk_CONF_VALUE_value(policy, i); /* get the object id */
   1591      1.1  christos         if ((j = OBJ_txt2nid(cv->name)) == NID_undef) {
   1592      1.1  christos             BIO_printf(bio_err,
   1593  1.1.1.2  christos                 "%s:unknown object type in 'policy' configuration\n",
   1594  1.1.1.2  christos                 cv->name);
   1595      1.1  christos             goto end;
   1596      1.1  christos         }
   1597      1.1  christos         obj = OBJ_nid2obj(j);
   1598      1.1  christos 
   1599      1.1  christos         last = -1;
   1600      1.1  christos         for (;;) {
   1601      1.1  christos             X509_NAME_ENTRY *push = NULL;
   1602      1.1  christos 
   1603      1.1  christos             /* lookup the object in the supplied name list */
   1604      1.1  christos             j = X509_NAME_get_index_by_OBJ(name, obj, last);
   1605      1.1  christos             if (j < 0) {
   1606      1.1  christos                 if (last != -1)
   1607      1.1  christos                     break;
   1608      1.1  christos                 tne = NULL;
   1609      1.1  christos             } else {
   1610      1.1  christos                 tne = X509_NAME_get_entry(name, j);
   1611      1.1  christos             }
   1612      1.1  christos             last = j;
   1613      1.1  christos 
   1614      1.1  christos             /* depending on the 'policy', decide what to do. */
   1615      1.1  christos             if (strcmp(cv->value, "optional") == 0) {
   1616      1.1  christos                 if (tne != NULL)
   1617      1.1  christos                     push = tne;
   1618      1.1  christos             } else if (strcmp(cv->value, "supplied") == 0) {
   1619      1.1  christos                 if (tne == NULL) {
   1620      1.1  christos                     BIO_printf(bio_err,
   1621  1.1.1.2  christos                         "The %s field needed to be supplied and was missing\n",
   1622  1.1.1.2  christos                         cv->name);
   1623      1.1  christos                     goto end;
   1624      1.1  christos                 } else {
   1625      1.1  christos                     push = tne;
   1626      1.1  christos                 }
   1627      1.1  christos             } else if (strcmp(cv->value, "match") == 0) {
   1628      1.1  christos                 int last2;
   1629      1.1  christos 
   1630      1.1  christos                 if (tne == NULL) {
   1631      1.1  christos                     BIO_printf(bio_err,
   1632  1.1.1.2  christos                         "The mandatory %s field was missing\n",
   1633  1.1.1.2  christos                         cv->name);
   1634      1.1  christos                     goto end;
   1635      1.1  christos                 }
   1636      1.1  christos 
   1637      1.1  christos                 last2 = -1;
   1638      1.1  christos 
   1639  1.1.1.2  christos             again2:
   1640      1.1  christos                 j = X509_NAME_get_index_by_OBJ(CAname, obj, last2);
   1641      1.1  christos                 if ((j < 0) && (last2 == -1)) {
   1642      1.1  christos                     BIO_printf(bio_err,
   1643  1.1.1.2  christos                         "The %s field does not exist in the CA certificate,\n"
   1644  1.1.1.2  christos                         "the 'policy' is misconfigured\n",
   1645  1.1.1.2  christos                         cv->name);
   1646      1.1  christos                     goto end;
   1647      1.1  christos                 }
   1648      1.1  christos                 if (j >= 0) {
   1649      1.1  christos                     push = X509_NAME_get_entry(CAname, j);
   1650      1.1  christos                     str = X509_NAME_ENTRY_get_data(tne);
   1651      1.1  christos                     str2 = X509_NAME_ENTRY_get_data(push);
   1652      1.1  christos                     last2 = j;
   1653      1.1  christos                     if (ASN1_STRING_cmp(str, str2) != 0)
   1654      1.1  christos                         goto again2;
   1655      1.1  christos                 }
   1656      1.1  christos                 if (j < 0) {
   1657      1.1  christos                     BIO_printf(bio_err,
   1658  1.1.1.2  christos                         "The %s field is different between\n"
   1659  1.1.1.2  christos                         "CA certificate (%s) and the request (%s)\n",
   1660  1.1.1.2  christos                         cv->name,
   1661  1.1.1.2  christos                         ((str2 == NULL) ? "NULL" : (char *)str2->data),
   1662  1.1.1.2  christos                         ((str == NULL) ? "NULL" : (char *)str->data));
   1663      1.1  christos                     goto end;
   1664      1.1  christos                 }
   1665      1.1  christos             } else {
   1666      1.1  christos                 BIO_printf(bio_err,
   1667  1.1.1.2  christos                     "%s:invalid type in 'policy' configuration\n",
   1668  1.1.1.2  christos                     cv->value);
   1669      1.1  christos                 goto end;
   1670      1.1  christos             }
   1671      1.1  christos 
   1672      1.1  christos             if (push != NULL) {
   1673      1.1  christos                 if (!X509_NAME_add_entry(subject, push, -1, 0)) {
   1674      1.1  christos                     BIO_printf(bio_err, "Memory allocation failure\n");
   1675      1.1  christos                     goto end;
   1676      1.1  christos                 }
   1677      1.1  christos             }
   1678      1.1  christos             if (j < 0)
   1679      1.1  christos                 break;
   1680      1.1  christos         }
   1681      1.1  christos     }
   1682      1.1  christos 
   1683      1.1  christos     if (preserve) {
   1684      1.1  christos         X509_NAME_free(subject);
   1685      1.1  christos         /* subject=X509_NAME_dup(X509_REQ_get_subject_name(req)); */
   1686      1.1  christos         subject = X509_NAME_dup(name);
   1687      1.1  christos         if (subject == NULL)
   1688      1.1  christos             goto end;
   1689      1.1  christos     }
   1690      1.1  christos 
   1691      1.1  christos     /* We are now totally happy, lets make and sign the certificate */
   1692      1.1  christos     if (verbose)
   1693      1.1  christos         BIO_printf(bio_err,
   1694  1.1.1.2  christos             "Everything appears to be ok, creating and signing the certificate\n");
   1695      1.1  christos 
   1696      1.1  christos     if ((ret = X509_new_ex(app_get0_libctx(), app_get0_propq())) == NULL)
   1697      1.1  christos         goto end;
   1698      1.1  christos 
   1699      1.1  christos     if (BN_to_ASN1_INTEGER(serial, X509_get_serialNumber(ret)) == NULL)
   1700      1.1  christos         goto end;
   1701      1.1  christos     if (selfsign) {
   1702      1.1  christos         if (!X509_set_issuer_name(ret, subject))
   1703      1.1  christos             goto end;
   1704      1.1  christos     } else {
   1705      1.1  christos         if (!X509_set_issuer_name(ret, X509_get_subject_name(x509)))
   1706      1.1  christos             goto end;
   1707      1.1  christos     }
   1708      1.1  christos 
   1709      1.1  christos     if (!set_cert_times(ret, startdate, enddate, days, 0))
   1710      1.1  christos         goto end;
   1711      1.1  christos 
   1712      1.1  christos     if (enddate != NULL) {
   1713      1.1  christos         int tdays;
   1714      1.1  christos 
   1715      1.1  christos         if (!ASN1_TIME_diff(&tdays, NULL, NULL, X509_get0_notAfter(ret)))
   1716      1.1  christos             goto end;
   1717      1.1  christos         days = tdays;
   1718      1.1  christos     }
   1719      1.1  christos 
   1720      1.1  christos     if (!X509_set_subject_name(ret, subject))
   1721      1.1  christos         goto end;
   1722      1.1  christos 
   1723      1.1  christos     pktmp = X509_REQ_get0_pubkey(req);
   1724      1.1  christos     i = X509_set_pubkey(ret, pktmp);
   1725      1.1  christos     if (!i)
   1726      1.1  christos         goto end;
   1727      1.1  christos 
   1728      1.1  christos     /* Initialize the context structure */
   1729      1.1  christos     X509V3_set_ctx(&ext_ctx, selfsign ? ret : x509,
   1730  1.1.1.2  christos         ret, NULL /* no need to give req, needed info is in ret */,
   1731  1.1.1.2  christos         NULL, X509V3_CTX_REPLACE);
   1732      1.1  christos     /* prepare fallback for AKID, but only if issuer cert equals subject cert */
   1733      1.1  christos     if (selfsign) {
   1734      1.1  christos         if (!X509V3_set_issuer_pkey(&ext_ctx, pkey))
   1735      1.1  christos             goto end;
   1736      1.1  christos         if (!cert_matches_key(ret, pkey))
   1737      1.1  christos             BIO_printf(bio_err,
   1738  1.1.1.2  christos                 "Warning: Signature key and public key of cert do not match\n");
   1739      1.1  christos     }
   1740      1.1  christos 
   1741      1.1  christos     /* Lets add the extensions, if there are any */
   1742      1.1  christos     if (ext_sect) {
   1743      1.1  christos         if (extfile_conf != NULL) {
   1744      1.1  christos             if (verbose)
   1745      1.1  christos                 BIO_printf(bio_err, "Extra configuration file found\n");
   1746      1.1  christos 
   1747      1.1  christos             /* Use the extfile_conf configuration db LHASH */
   1748      1.1  christos             X509V3_set_nconf(&ext_ctx, extfile_conf);
   1749      1.1  christos 
   1750      1.1  christos             /* Adds exts contained in the configuration file */
   1751      1.1  christos             if (!X509V3_EXT_add_nconf(extfile_conf, &ext_ctx, ext_sect, ret)) {
   1752      1.1  christos                 BIO_printf(bio_err,
   1753  1.1.1.2  christos                     "Error adding certificate extensions from extfile section %s\n",
   1754  1.1.1.2  christos                     ext_sect);
   1755      1.1  christos                 goto end;
   1756      1.1  christos             }
   1757      1.1  christos             if (verbose)
   1758      1.1  christos                 BIO_printf(bio_err,
   1759  1.1.1.2  christos                     "Successfully added extensions from file.\n");
   1760      1.1  christos         } else if (ext_sect) {
   1761      1.1  christos             /* We found extensions to be set from config file */
   1762      1.1  christos             X509V3_set_nconf(&ext_ctx, lconf);
   1763      1.1  christos 
   1764      1.1  christos             if (!X509V3_EXT_add_nconf(lconf, &ext_ctx, ext_sect, ret)) {
   1765      1.1  christos                 BIO_printf(bio_err,
   1766  1.1.1.2  christos                     "Error adding certificate extensions from config section %s\n",
   1767  1.1.1.2  christos                     ext_sect);
   1768      1.1  christos                 goto end;
   1769      1.1  christos             }
   1770      1.1  christos 
   1771      1.1  christos             if (verbose)
   1772      1.1  christos                 BIO_printf(bio_err,
   1773  1.1.1.2  christos                     "Successfully added extensions from config\n");
   1774      1.1  christos         }
   1775      1.1  christos     }
   1776      1.1  christos 
   1777      1.1  christos     /* Copy extensions from request (if any) */
   1778      1.1  christos 
   1779      1.1  christos     if (!copy_extensions(ret, req, ext_copy)) {
   1780      1.1  christos         BIO_printf(bio_err, "ERROR: adding extensions from request\n");
   1781      1.1  christos         goto end;
   1782      1.1  christos     }
   1783      1.1  christos 
   1784      1.1  christos     if (verbose)
   1785      1.1  christos         BIO_printf(bio_err,
   1786  1.1.1.2  christos             "The subject name appears to be ok, checking database for clashes\n");
   1787      1.1  christos 
   1788      1.1  christos     /* Build the correct Subject if no e-mail is wanted in the subject. */
   1789      1.1  christos     if (!email_dn) {
   1790      1.1  christos         X509_NAME_ENTRY *tmpne;
   1791      1.1  christos         X509_NAME *dn_subject;
   1792      1.1  christos 
   1793      1.1  christos         /*
   1794      1.1  christos          * Its best to dup the subject DN and then delete any email addresses
   1795      1.1  christos          * because this retains its structure.
   1796      1.1  christos          */
   1797      1.1  christos         if ((dn_subject = X509_NAME_dup(subject)) == NULL) {
   1798      1.1  christos             BIO_printf(bio_err, "Memory allocation failure\n");
   1799      1.1  christos             goto end;
   1800      1.1  christos         }
   1801      1.1  christos         i = -1;
   1802      1.1  christos         while ((i = X509_NAME_get_index_by_NID(dn_subject,
   1803  1.1.1.2  christos                     NID_pkcs9_emailAddress,
   1804  1.1.1.2  christos                     i))
   1805  1.1.1.2  christos             >= 0) {
   1806      1.1  christos             tmpne = X509_NAME_delete_entry(dn_subject, i--);
   1807      1.1  christos             X509_NAME_ENTRY_free(tmpne);
   1808      1.1  christos         }
   1809      1.1  christos 
   1810      1.1  christos         if (!X509_set_subject_name(ret, dn_subject)) {
   1811      1.1  christos             X509_NAME_free(dn_subject);
   1812      1.1  christos             goto end;
   1813      1.1  christos         }
   1814      1.1  christos         X509_NAME_free(dn_subject);
   1815      1.1  christos     }
   1816      1.1  christos 
   1817      1.1  christos     row[DB_name] = X509_NAME_oneline(X509_get_subject_name(ret), NULL, 0);
   1818      1.1  christos     if (row[DB_name] == NULL) {
   1819      1.1  christos         BIO_printf(bio_err, "Memory allocation failure\n");
   1820      1.1  christos         goto end;
   1821      1.1  christos     }
   1822      1.1  christos 
   1823      1.1  christos     if (BN_is_zero(serial))
   1824      1.1  christos         row[DB_serial] = OPENSSL_strdup("00");
   1825      1.1  christos     else
   1826      1.1  christos         row[DB_serial] = BN_bn2hex(serial);
   1827      1.1  christos     if (row[DB_serial] == NULL) {
   1828      1.1  christos         BIO_printf(bio_err, "Memory allocation failure\n");
   1829      1.1  christos         goto end;
   1830      1.1  christos     }
   1831      1.1  christos 
   1832      1.1  christos     if (row[DB_name][0] == '\0') {
   1833      1.1  christos         /*
   1834      1.1  christos          * An empty subject! We'll use the serial number instead. If
   1835      1.1  christos          * unique_subject is in use then we don't want different entries with
   1836      1.1  christos          * empty subjects matching each other.
   1837      1.1  christos          */
   1838      1.1  christos         OPENSSL_free(row[DB_name]);
   1839      1.1  christos         row[DB_name] = OPENSSL_strdup(row[DB_serial]);
   1840      1.1  christos         if (row[DB_name] == NULL) {
   1841      1.1  christos             BIO_printf(bio_err, "Memory allocation failure\n");
   1842      1.1  christos             goto end;
   1843      1.1  christos         }
   1844      1.1  christos     }
   1845      1.1  christos 
   1846      1.1  christos     if (db->attributes.unique_subject) {
   1847      1.1  christos         OPENSSL_STRING *crow = row;
   1848      1.1  christos 
   1849      1.1  christos         rrow = TXT_DB_get_by_index(db->db, DB_name, crow);
   1850      1.1  christos         if (rrow != NULL) {
   1851      1.1  christos             BIO_printf(bio_err,
   1852  1.1.1.2  christos                 "ERROR:There is already a certificate for %s\n",
   1853  1.1.1.2  christos                 row[DB_name]);
   1854      1.1  christos         }
   1855      1.1  christos     }
   1856      1.1  christos     if (rrow == NULL) {
   1857      1.1  christos         rrow = TXT_DB_get_by_index(db->db, DB_serial, row);
   1858      1.1  christos         if (rrow != NULL) {
   1859      1.1  christos             BIO_printf(bio_err,
   1860  1.1.1.2  christos                 "ERROR:Serial number %s has already been issued,\n",
   1861  1.1.1.2  christos                 row[DB_serial]);
   1862      1.1  christos             BIO_printf(bio_err,
   1863  1.1.1.2  christos                 "      check the database/serial_file for corruption\n");
   1864      1.1  christos         }
   1865      1.1  christos     }
   1866      1.1  christos 
   1867      1.1  christos     if (rrow != NULL) {
   1868      1.1  christos         BIO_printf(bio_err, "The matching entry has the following details\n");
   1869      1.1  christos         if (rrow[DB_type][0] == DB_TYPE_EXP)
   1870      1.1  christos             p = "Expired";
   1871      1.1  christos         else if (rrow[DB_type][0] == DB_TYPE_REV)
   1872      1.1  christos             p = "Revoked";
   1873      1.1  christos         else if (rrow[DB_type][0] == DB_TYPE_VAL)
   1874      1.1  christos             p = "Valid";
   1875      1.1  christos         else
   1876      1.1  christos             p = "\ninvalid type, Database error\n";
   1877      1.1  christos         BIO_printf(bio_err, "Type          :%s\n", p);
   1878      1.1  christos         if (rrow[DB_type][0] == DB_TYPE_REV) {
   1879      1.1  christos             p = rrow[DB_exp_date];
   1880      1.1  christos             if (p == NULL)
   1881      1.1  christos                 p = "undef";
   1882      1.1  christos             BIO_printf(bio_err, "Was revoked on:%s\n", p);
   1883      1.1  christos         }
   1884      1.1  christos         p = rrow[DB_exp_date];
   1885      1.1  christos         if (p == NULL)
   1886      1.1  christos             p = "undef";
   1887      1.1  christos         BIO_printf(bio_err, "Expires on    :%s\n", p);
   1888      1.1  christos         p = rrow[DB_serial];
   1889      1.1  christos         if (p == NULL)
   1890      1.1  christos             p = "undef";
   1891      1.1  christos         BIO_printf(bio_err, "Serial Number :%s\n", p);
   1892      1.1  christos         p = rrow[DB_file];
   1893      1.1  christos         if (p == NULL)
   1894      1.1  christos             p = "undef";
   1895      1.1  christos         BIO_printf(bio_err, "File name     :%s\n", p);
   1896      1.1  christos         p = rrow[DB_name];
   1897      1.1  christos         if (p == NULL)
   1898      1.1  christos             p = "undef";
   1899      1.1  christos         BIO_printf(bio_err, "Subject Name  :%s\n", p);
   1900  1.1.1.2  christos         ok = -1; /* This is now a 'bad' error. */
   1901      1.1  christos         goto end;
   1902      1.1  christos     }
   1903      1.1  christos 
   1904      1.1  christos     if (!default_op) {
   1905      1.1  christos         BIO_printf(bio_err, "Certificate Details:\n");
   1906      1.1  christos         /*
   1907      1.1  christos          * Never print signature details because signature not present
   1908      1.1  christos          */
   1909      1.1  christos         certopt |= X509_FLAG_NO_SIGDUMP | X509_FLAG_NO_SIGNAME;
   1910      1.1  christos         X509_print_ex(bio_err, ret, nameopt, certopt);
   1911      1.1  christos     }
   1912      1.1  christos 
   1913      1.1  christos     BIO_printf(bio_err, "Certificate is to be certified until ");
   1914      1.1  christos     ASN1_TIME_print_ex(bio_err, X509_get0_notAfter(ret), dateopt);
   1915      1.1  christos     if (days)
   1916      1.1  christos         BIO_printf(bio_err, " (%ld days)", days);
   1917      1.1  christos     BIO_printf(bio_err, "\n");
   1918      1.1  christos 
   1919      1.1  christos     if (!batch) {
   1920      1.1  christos 
   1921      1.1  christos         BIO_printf(bio_err, "Sign the certificate? [y/n]:");
   1922      1.1  christos         (void)BIO_flush(bio_err);
   1923      1.1  christos         buf[0] = '\0';
   1924      1.1  christos         if (fgets(buf, sizeof(buf), stdin) == NULL) {
   1925      1.1  christos             BIO_printf(bio_err,
   1926  1.1.1.2  christos                 "CERTIFICATE WILL NOT BE CERTIFIED: I/O error\n");
   1927      1.1  christos             ok = 0;
   1928      1.1  christos             goto end;
   1929      1.1  christos         }
   1930      1.1  christos         if (!(buf[0] == 'y' || buf[0] == 'Y')) {
   1931      1.1  christos             BIO_printf(bio_err, "CERTIFICATE WILL NOT BE CERTIFIED\n");
   1932      1.1  christos             ok = 0;
   1933      1.1  christos             goto end;
   1934      1.1  christos         }
   1935      1.1  christos     }
   1936      1.1  christos 
   1937      1.1  christos     pktmp = X509_get0_pubkey(ret);
   1938  1.1.1.2  christos     if (EVP_PKEY_missing_parameters(pktmp) && !EVP_PKEY_missing_parameters(pkey))
   1939      1.1  christos         EVP_PKEY_copy_parameters(pktmp, pkey);
   1940      1.1  christos 
   1941      1.1  christos     if (!do_X509_sign(ret, 0, pkey, dgst, sigopts, &ext_ctx))
   1942      1.1  christos         goto end;
   1943      1.1  christos 
   1944      1.1  christos     /* We now just add it to the database as DB_TYPE_VAL('V') */
   1945      1.1  christos     row[DB_type] = OPENSSL_strdup("V");
   1946      1.1  christos     tm = X509_get0_notAfter(ret);
   1947      1.1  christos     row[DB_exp_date] = app_malloc(tm->length + 1, "row expdate");
   1948      1.1  christos     memcpy(row[DB_exp_date], tm->data, tm->length);
   1949      1.1  christos     row[DB_exp_date][tm->length] = '\0';
   1950      1.1  christos     row[DB_rev_date] = NULL;
   1951      1.1  christos     row[DB_file] = OPENSSL_strdup("unknown");
   1952      1.1  christos     if ((row[DB_type] == NULL) || (row[DB_file] == NULL)
   1953      1.1  christos         || (row[DB_name] == NULL)) {
   1954      1.1  christos         BIO_printf(bio_err, "Memory allocation failure\n");
   1955      1.1  christos         goto end;
   1956      1.1  christos     }
   1957      1.1  christos 
   1958      1.1  christos     irow = app_malloc(sizeof(*irow) * (DB_NUMBER + 1), "row space");
   1959      1.1  christos     for (i = 0; i < DB_NUMBER; i++)
   1960      1.1  christos         irow[i] = row[i];
   1961      1.1  christos     irow[DB_NUMBER] = NULL;
   1962      1.1  christos 
   1963      1.1  christos     if (!TXT_DB_insert(db->db, irow)) {
   1964      1.1  christos         BIO_printf(bio_err, "failed to update database\n");
   1965      1.1  christos         BIO_printf(bio_err, "TXT_DB error number %ld\n", db->db->error);
   1966      1.1  christos         goto end;
   1967      1.1  christos     }
   1968      1.1  christos     irow = NULL;
   1969      1.1  christos     ok = 1;
   1970  1.1.1.2  christos end:
   1971      1.1  christos     if (ok != 1) {
   1972      1.1  christos         for (i = 0; i < DB_NUMBER; i++)
   1973      1.1  christos             OPENSSL_free(row[i]);
   1974      1.1  christos     }
   1975      1.1  christos     OPENSSL_free(irow);
   1976      1.1  christos 
   1977      1.1  christos     X509_NAME_free(CAname);
   1978      1.1  christos     X509_NAME_free(subject);
   1979      1.1  christos     if (ok <= 0)
   1980      1.1  christos         X509_free(ret);
   1981      1.1  christos     else
   1982      1.1  christos         *xret = ret;
   1983      1.1  christos     return ok;
   1984      1.1  christos }
   1985      1.1  christos 
   1986      1.1  christos static void write_new_certificate(BIO *bp, X509 *x, int output_der, int notext)
   1987      1.1  christos {
   1988      1.1  christos 
   1989      1.1  christos     if (output_der) {
   1990      1.1  christos         (void)i2d_X509_bio(bp, x);
   1991      1.1  christos         return;
   1992      1.1  christos     }
   1993      1.1  christos     if (!notext)
   1994      1.1  christos         X509_print(bp, x);
   1995      1.1  christos     PEM_write_bio_X509(bp, x);
   1996      1.1  christos }
   1997      1.1  christos 
   1998      1.1  christos static int certify_spkac(X509 **xret, const char *infile, EVP_PKEY *pkey,
   1999  1.1.1.2  christos     X509 *x509, const char *dgst,
   2000  1.1.1.2  christos     STACK_OF(OPENSSL_STRING) *sigopts,
   2001  1.1.1.2  christos     STACK_OF(CONF_VALUE) *policy, CA_DB *db,
   2002  1.1.1.2  christos     BIGNUM *serial, const char *subj, unsigned long chtype,
   2003  1.1.1.2  christos     int multirdn, int email_dn, const char *startdate,
   2004  1.1.1.2  christos     const char *enddate, long days, const char *ext_sect,
   2005  1.1.1.2  christos     CONF *lconf, int verbose, unsigned long certopt,
   2006  1.1.1.2  christos     unsigned long nameopt, int default_op, int ext_copy, unsigned long dateopt)
   2007      1.1  christos {
   2008      1.1  christos     STACK_OF(CONF_VALUE) *sk = NULL;
   2009      1.1  christos     LHASH_OF(CONF_VALUE) *parms = NULL;
   2010      1.1  christos     X509_REQ *req = NULL;
   2011      1.1  christos     CONF_VALUE *cv = NULL;
   2012      1.1  christos     NETSCAPE_SPKI *spki = NULL;
   2013      1.1  christos     char *type, *buf;
   2014      1.1  christos     EVP_PKEY *pktmp = NULL;
   2015      1.1  christos     X509_NAME *n = NULL;
   2016      1.1  christos     X509_NAME_ENTRY *ne = NULL;
   2017      1.1  christos     int ok = -1, i, j;
   2018      1.1  christos     long errline;
   2019      1.1  christos     int nid;
   2020      1.1  christos 
   2021      1.1  christos     /*
   2022      1.1  christos      * Load input file into a hash table.  (This is just an easy
   2023      1.1  christos      * way to read and parse the file, then put it into a convenient
   2024      1.1  christos      * STACK format).
   2025      1.1  christos      */
   2026      1.1  christos     parms = CONF_load(NULL, infile, &errline);
   2027      1.1  christos     if (parms == NULL) {
   2028      1.1  christos         BIO_printf(bio_err, "error on line %ld of %s\n", errline, infile);
   2029      1.1  christos         goto end;
   2030      1.1  christos     }
   2031      1.1  christos 
   2032      1.1  christos     sk = CONF_get_section(parms, "default");
   2033      1.1  christos     if (sk_CONF_VALUE_num(sk) == 0) {
   2034      1.1  christos         BIO_printf(bio_err, "no name/value pairs found in %s\n", infile);
   2035      1.1  christos         goto end;
   2036      1.1  christos     }
   2037      1.1  christos 
   2038      1.1  christos     /*
   2039      1.1  christos      * Now create a dummy X509 request structure.  We don't actually
   2040      1.1  christos      * have an X509 request, but we have many of the components
   2041      1.1  christos      * (a public key, various DN components).  The idea is that we
   2042      1.1  christos      * put these components into the right X509 request structure
   2043      1.1  christos      * and we can use the same code as if you had a real X509 request.
   2044      1.1  christos      */
   2045      1.1  christos     req = X509_REQ_new();
   2046      1.1  christos     if (req == NULL)
   2047      1.1  christos         goto end;
   2048      1.1  christos 
   2049      1.1  christos     /*
   2050      1.1  christos      * Build up the subject name set.
   2051      1.1  christos      */
   2052      1.1  christos     n = X509_REQ_get_subject_name(req);
   2053      1.1  christos 
   2054      1.1  christos     for (i = 0;; i++) {
   2055      1.1  christos         if (sk_CONF_VALUE_num(sk) <= i)
   2056      1.1  christos             break;
   2057      1.1  christos 
   2058      1.1  christos         cv = sk_CONF_VALUE_value(sk, i);
   2059      1.1  christos         type = cv->name;
   2060      1.1  christos         /*
   2061      1.1  christos          * Skip past any leading X. X: X, etc to allow for multiple instances
   2062      1.1  christos          */
   2063      1.1  christos         for (buf = cv->name; *buf; buf++)
   2064      1.1  christos             if ((*buf == ':') || (*buf == ',') || (*buf == '.')) {
   2065      1.1  christos                 buf++;
   2066      1.1  christos                 if (*buf)
   2067      1.1  christos                     type = buf;
   2068      1.1  christos                 break;
   2069      1.1  christos             }
   2070      1.1  christos 
   2071      1.1  christos         buf = cv->value;
   2072      1.1  christos         if ((nid = OBJ_txt2nid(type)) == NID_undef) {
   2073      1.1  christos             if (strcmp(type, "SPKAC") == 0) {
   2074      1.1  christos                 spki = NETSCAPE_SPKI_b64_decode(cv->value, -1);
   2075      1.1  christos                 if (spki == NULL) {
   2076      1.1  christos                     BIO_printf(bio_err,
   2077  1.1.1.2  christos                         "unable to load Netscape SPKAC structure\n");
   2078      1.1  christos                     goto end;
   2079      1.1  christos                 }
   2080      1.1  christos             }
   2081      1.1  christos             continue;
   2082      1.1  christos         }
   2083      1.1  christos 
   2084      1.1  christos         if (!X509_NAME_add_entry_by_NID(n, nid, chtype,
   2085  1.1.1.2  christos                 (unsigned char *)buf, -1, -1, 0))
   2086      1.1  christos             goto end;
   2087      1.1  christos     }
   2088      1.1  christos     if (spki == NULL) {
   2089      1.1  christos         BIO_printf(bio_err, "Netscape SPKAC structure not found in %s\n",
   2090  1.1.1.2  christos             infile);
   2091      1.1  christos         goto end;
   2092      1.1  christos     }
   2093      1.1  christos 
   2094      1.1  christos     /*
   2095      1.1  christos      * Now extract the key from the SPKI structure.
   2096      1.1  christos      */
   2097      1.1  christos 
   2098      1.1  christos     BIO_printf(bio_err, "Check that the SPKAC request matches the signature\n");
   2099      1.1  christos 
   2100      1.1  christos     if ((pktmp = NETSCAPE_SPKI_get_pubkey(spki)) == NULL) {
   2101      1.1  christos         BIO_printf(bio_err, "error unpacking SPKAC public key\n");
   2102      1.1  christos         goto end;
   2103      1.1  christos     }
   2104      1.1  christos 
   2105      1.1  christos     j = NETSCAPE_SPKI_verify(spki, pktmp);
   2106      1.1  christos     if (j <= 0) {
   2107      1.1  christos         EVP_PKEY_free(pktmp);
   2108      1.1  christos         BIO_printf(bio_err,
   2109  1.1.1.2  christos             "signature verification failed on SPKAC public key\n");
   2110      1.1  christos         goto end;
   2111      1.1  christos     }
   2112      1.1  christos     BIO_printf(bio_err, "Signature ok\n");
   2113      1.1  christos 
   2114      1.1  christos     X509_REQ_set_pubkey(req, pktmp);
   2115      1.1  christos     EVP_PKEY_free(pktmp);
   2116      1.1  christos     ok = do_body(xret, pkey, x509, dgst, sigopts, policy, db, serial, subj,
   2117  1.1.1.2  christos         chtype, multirdn, email_dn, startdate, enddate, days, 1,
   2118  1.1.1.2  christos         verbose, req, ext_sect, lconf, certopt, nameopt, default_op,
   2119  1.1.1.2  christos         ext_copy, 0, dateopt);
   2120  1.1.1.2  christos end:
   2121      1.1  christos     X509_REQ_free(req);
   2122      1.1  christos     CONF_free(parms);
   2123      1.1  christos     NETSCAPE_SPKI_free(spki);
   2124      1.1  christos     X509_NAME_ENTRY_free(ne);
   2125      1.1  christos 
   2126      1.1  christos     return ok;
   2127      1.1  christos }
   2128      1.1  christos 
   2129      1.1  christos static int check_time_format(const char *str)
   2130      1.1  christos {
   2131      1.1  christos     return ASN1_TIME_set_string(NULL, str);
   2132      1.1  christos }
   2133      1.1  christos 
   2134      1.1  christos static int do_revoke(X509 *x509, CA_DB *db, REVINFO_TYPE rev_type,
   2135  1.1.1.2  christos     const char *value)
   2136      1.1  christos {
   2137      1.1  christos     const ASN1_TIME *tm = NULL;
   2138      1.1  christos     char *row[DB_NUMBER], **rrow, **irow;
   2139      1.1  christos     char *rev_str = NULL;
   2140      1.1  christos     BIGNUM *bn = NULL;
   2141      1.1  christos     int ok = -1, i;
   2142      1.1  christos 
   2143      1.1  christos     for (i = 0; i < DB_NUMBER; i++)
   2144      1.1  christos         row[i] = NULL;
   2145      1.1  christos     row[DB_name] = X509_NAME_oneline(X509_get_subject_name(x509), NULL, 0);
   2146      1.1  christos     bn = ASN1_INTEGER_to_BN(X509_get0_serialNumber(x509), NULL);
   2147      1.1  christos     if (!bn)
   2148      1.1  christos         goto end;
   2149      1.1  christos     if (BN_is_zero(bn))
   2150      1.1  christos         row[DB_serial] = OPENSSL_strdup("00");
   2151      1.1  christos     else
   2152      1.1  christos         row[DB_serial] = BN_bn2hex(bn);
   2153      1.1  christos     BN_free(bn);
   2154      1.1  christos     if (row[DB_name] != NULL && row[DB_name][0] == '\0') {
   2155      1.1  christos         /* Entries with empty Subjects actually use the serial number instead */
   2156      1.1  christos         OPENSSL_free(row[DB_name]);
   2157      1.1  christos         row[DB_name] = OPENSSL_strdup(row[DB_serial]);
   2158      1.1  christos     }
   2159      1.1  christos     if ((row[DB_name] == NULL) || (row[DB_serial] == NULL)) {
   2160      1.1  christos         BIO_printf(bio_err, "Memory allocation failure\n");
   2161      1.1  christos         goto end;
   2162      1.1  christos     }
   2163      1.1  christos     /*
   2164      1.1  christos      * We have to lookup by serial number because name lookup skips revoked
   2165      1.1  christos      * certs
   2166      1.1  christos      */
   2167      1.1  christos     rrow = TXT_DB_get_by_index(db->db, DB_serial, row);
   2168      1.1  christos     if (rrow == NULL) {
   2169      1.1  christos         BIO_printf(bio_err,
   2170  1.1.1.2  christos             "Adding Entry with serial number %s to DB for %s\n",
   2171  1.1.1.2  christos             row[DB_serial], row[DB_name]);
   2172      1.1  christos 
   2173      1.1  christos         /* We now just add it to the database as DB_TYPE_REV('V') */
   2174      1.1  christos         row[DB_type] = OPENSSL_strdup("V");
   2175      1.1  christos         tm = X509_get0_notAfter(x509);
   2176      1.1  christos         row[DB_exp_date] = app_malloc(tm->length + 1, "row exp_data");
   2177      1.1  christos         memcpy(row[DB_exp_date], tm->data, tm->length);
   2178      1.1  christos         row[DB_exp_date][tm->length] = '\0';
   2179      1.1  christos         row[DB_rev_date] = NULL;
   2180      1.1  christos         row[DB_file] = OPENSSL_strdup("unknown");
   2181      1.1  christos 
   2182      1.1  christos         if (row[DB_type] == NULL || row[DB_file] == NULL) {
   2183      1.1  christos             BIO_printf(bio_err, "Memory allocation failure\n");
   2184      1.1  christos             goto end;
   2185      1.1  christos         }
   2186      1.1  christos 
   2187      1.1  christos         irow = app_malloc(sizeof(*irow) * (DB_NUMBER + 1), "row ptr");
   2188      1.1  christos         for (i = 0; i < DB_NUMBER; i++)
   2189      1.1  christos             irow[i] = row[i];
   2190      1.1  christos         irow[DB_NUMBER] = NULL;
   2191      1.1  christos 
   2192      1.1  christos         if (!TXT_DB_insert(db->db, irow)) {
   2193      1.1  christos             BIO_printf(bio_err, "failed to update database\n");
   2194      1.1  christos             BIO_printf(bio_err, "TXT_DB error number %ld\n", db->db->error);
   2195      1.1  christos             OPENSSL_free(irow);
   2196      1.1  christos             goto end;
   2197      1.1  christos         }
   2198      1.1  christos 
   2199      1.1  christos         for (i = 0; i < DB_NUMBER; i++)
   2200      1.1  christos             row[i] = NULL;
   2201      1.1  christos 
   2202      1.1  christos         /* Revoke Certificate */
   2203      1.1  christos         if (rev_type == REV_VALID)
   2204      1.1  christos             ok = 1;
   2205      1.1  christos         else
   2206      1.1  christos             /* Retry revocation after DB insertion */
   2207      1.1  christos             ok = do_revoke(x509, db, rev_type, value);
   2208      1.1  christos 
   2209      1.1  christos         goto end;
   2210      1.1  christos 
   2211      1.1  christos     } else if (index_name_cmp_noconst(row, rrow)) {
   2212      1.1  christos         BIO_printf(bio_err, "ERROR:name does not match %s\n", row[DB_name]);
   2213      1.1  christos         goto end;
   2214      1.1  christos     } else if (rev_type == REV_VALID) {
   2215      1.1  christos         BIO_printf(bio_err, "ERROR:Already present, serial number %s\n",
   2216  1.1.1.2  christos             row[DB_serial]);
   2217      1.1  christos         goto end;
   2218      1.1  christos     } else if (rrow[DB_type][0] == DB_TYPE_REV) {
   2219      1.1  christos         BIO_printf(bio_err, "ERROR:Already revoked, serial number %s\n",
   2220  1.1.1.2  christos             row[DB_serial]);
   2221      1.1  christos         goto end;
   2222      1.1  christos     } else {
   2223      1.1  christos         BIO_printf(bio_err, "Revoking Certificate %s.\n", rrow[DB_serial]);
   2224      1.1  christos         rev_str = make_revocation_str(rev_type, value);
   2225      1.1  christos         if (!rev_str) {
   2226      1.1  christos             BIO_printf(bio_err, "Error in revocation arguments\n");
   2227      1.1  christos             goto end;
   2228      1.1  christos         }
   2229      1.1  christos         rrow[DB_type][0] = DB_TYPE_REV;
   2230      1.1  christos         rrow[DB_type][1] = '\0';
   2231      1.1  christos         rrow[DB_rev_date] = rev_str;
   2232      1.1  christos     }
   2233      1.1  christos     ok = 1;
   2234  1.1.1.2  christos end:
   2235      1.1  christos     for (i = 0; i < DB_NUMBER; i++)
   2236      1.1  christos         OPENSSL_free(row[i]);
   2237      1.1  christos     return ok;
   2238      1.1  christos }
   2239      1.1  christos 
   2240      1.1  christos static int get_certificate_status(const char *serial, CA_DB *db)
   2241      1.1  christos {
   2242      1.1  christos     char *row[DB_NUMBER], **rrow;
   2243      1.1  christos     int ok = -1, i;
   2244      1.1  christos     size_t serial_len = strlen(serial);
   2245      1.1  christos 
   2246      1.1  christos     /* Free Resources */
   2247      1.1  christos     for (i = 0; i < DB_NUMBER; i++)
   2248      1.1  christos         row[i] = NULL;
   2249      1.1  christos 
   2250      1.1  christos     /* Malloc needed char spaces */
   2251      1.1  christos     row[DB_serial] = app_malloc(serial_len + 2, "row serial#");
   2252      1.1  christos 
   2253      1.1  christos     if (serial_len % 2) {
   2254      1.1  christos         /*
   2255      1.1  christos          * Set the first char to 0
   2256      1.1  christos          */
   2257      1.1  christos         row[DB_serial][0] = '0';
   2258      1.1  christos 
   2259      1.1  christos         /* Copy String from serial to row[DB_serial] */
   2260      1.1  christos         memcpy(row[DB_serial] + 1, serial, serial_len);
   2261      1.1  christos         row[DB_serial][serial_len + 1] = '\0';
   2262      1.1  christos     } else {
   2263      1.1  christos         /* Copy String from serial to row[DB_serial] */
   2264      1.1  christos         memcpy(row[DB_serial], serial, serial_len);
   2265      1.1  christos         row[DB_serial][serial_len] = '\0';
   2266      1.1  christos     }
   2267      1.1  christos 
   2268      1.1  christos     /* Make it Upper Case */
   2269      1.1  christos     make_uppercase(row[DB_serial]);
   2270      1.1  christos 
   2271      1.1  christos     ok = 1;
   2272      1.1  christos 
   2273      1.1  christos     /* Search for the certificate */
   2274      1.1  christos     rrow = TXT_DB_get_by_index(db->db, DB_serial, row);
   2275      1.1  christos     if (rrow == NULL) {
   2276      1.1  christos         BIO_printf(bio_err, "Serial %s not present in db.\n", row[DB_serial]);
   2277      1.1  christos         ok = -1;
   2278      1.1  christos         goto end;
   2279      1.1  christos     } else if (rrow[DB_type][0] == DB_TYPE_VAL) {
   2280      1.1  christos         BIO_printf(bio_err, "%s=Valid (%c)\n",
   2281  1.1.1.2  christos             row[DB_serial], rrow[DB_type][0]);
   2282      1.1  christos         goto end;
   2283      1.1  christos     } else if (rrow[DB_type][0] == DB_TYPE_REV) {
   2284      1.1  christos         BIO_printf(bio_err, "%s=Revoked (%c)\n",
   2285  1.1.1.2  christos             row[DB_serial], rrow[DB_type][0]);
   2286      1.1  christos         goto end;
   2287      1.1  christos     } else if (rrow[DB_type][0] == DB_TYPE_EXP) {
   2288      1.1  christos         BIO_printf(bio_err, "%s=Expired (%c)\n",
   2289  1.1.1.2  christos             row[DB_serial], rrow[DB_type][0]);
   2290      1.1  christos         goto end;
   2291      1.1  christos     } else if (rrow[DB_type][0] == DB_TYPE_SUSP) {
   2292      1.1  christos         BIO_printf(bio_err, "%s=Suspended (%c)\n",
   2293  1.1.1.2  christos             row[DB_serial], rrow[DB_type][0]);
   2294      1.1  christos         goto end;
   2295      1.1  christos     } else {
   2296      1.1  christos         BIO_printf(bio_err, "%s=Unknown (%c).\n",
   2297  1.1.1.2  christos             row[DB_serial], rrow[DB_type][0]);
   2298      1.1  christos         ok = -1;
   2299      1.1  christos     }
   2300  1.1.1.2  christos end:
   2301      1.1  christos     for (i = 0; i < DB_NUMBER; i++) {
   2302      1.1  christos         OPENSSL_free(row[i]);
   2303      1.1  christos     }
   2304      1.1  christos     return ok;
   2305      1.1  christos }
   2306      1.1  christos 
   2307      1.1  christos int do_updatedb(CA_DB *db, time_t *now)
   2308      1.1  christos {
   2309      1.1  christos     ASN1_TIME *a_tm = NULL;
   2310      1.1  christos     int i, cnt = 0;
   2311      1.1  christos     char **rrow;
   2312      1.1  christos 
   2313      1.1  christos     a_tm = ASN1_TIME_new();
   2314      1.1  christos     if (a_tm == NULL)
   2315      1.1  christos         return -1;
   2316      1.1  christos 
   2317      1.1  christos     /* get actual time */
   2318      1.1  christos     if (X509_time_adj(a_tm, 0, now) == NULL) {
   2319      1.1  christos         ASN1_TIME_free(a_tm);
   2320      1.1  christos         return -1;
   2321      1.1  christos     }
   2322      1.1  christos 
   2323      1.1  christos     for (i = 0; i < sk_OPENSSL_PSTRING_num(db->db->data); i++) {
   2324      1.1  christos         rrow = sk_OPENSSL_PSTRING_value(db->db->data, i);
   2325      1.1  christos 
   2326      1.1  christos         if (rrow[DB_type][0] == DB_TYPE_VAL) {
   2327      1.1  christos             /* ignore entries that are not valid */
   2328      1.1  christos             ASN1_TIME *exp_date = NULL;
   2329      1.1  christos 
   2330      1.1  christos             exp_date = ASN1_TIME_new();
   2331      1.1  christos             if (exp_date == NULL) {
   2332      1.1  christos                 ASN1_TIME_free(a_tm);
   2333      1.1  christos                 return -1;
   2334      1.1  christos             }
   2335      1.1  christos 
   2336      1.1  christos             if (!ASN1_TIME_set_string(exp_date, rrow[DB_exp_date])) {
   2337      1.1  christos                 ASN1_TIME_free(a_tm);
   2338      1.1  christos                 ASN1_TIME_free(exp_date);
   2339      1.1  christos                 return -1;
   2340      1.1  christos             }
   2341      1.1  christos 
   2342      1.1  christos             if (ASN1_TIME_compare(exp_date, a_tm) <= 0) {
   2343      1.1  christos                 rrow[DB_type][0] = DB_TYPE_EXP;
   2344      1.1  christos                 rrow[DB_type][1] = '\0';
   2345      1.1  christos                 cnt++;
   2346      1.1  christos 
   2347      1.1  christos                 BIO_printf(bio_err, "%s=Expired\n", rrow[DB_serial]);
   2348      1.1  christos             }
   2349      1.1  christos             ASN1_TIME_free(exp_date);
   2350      1.1  christos         }
   2351      1.1  christos     }
   2352      1.1  christos 
   2353      1.1  christos     ASN1_TIME_free(a_tm);
   2354      1.1  christos     return cnt;
   2355      1.1  christos }
   2356      1.1  christos 
   2357      1.1  christos static const char *crl_reasons[] = {
   2358      1.1  christos     /* CRL reason strings */
   2359      1.1  christos     "unspecified",
   2360      1.1  christos     "keyCompromise",
   2361      1.1  christos     "CACompromise",
   2362      1.1  christos     "affiliationChanged",
   2363      1.1  christos     "superseded",
   2364      1.1  christos     "cessationOfOperation",
   2365      1.1  christos     "certificateHold",
   2366      1.1  christos     "removeFromCRL",
   2367      1.1  christos     /* Additional pseudo reasons */
   2368      1.1  christos     "holdInstruction",
   2369      1.1  christos     "keyTime",
   2370      1.1  christos     "CAkeyTime"
   2371      1.1  christos };
   2372      1.1  christos 
   2373      1.1  christos #define NUM_REASONS OSSL_NELEM(crl_reasons)
   2374      1.1  christos 
   2375      1.1  christos /*
   2376      1.1  christos  * Given revocation information convert to a DB string. The format of the
   2377      1.1  christos  * string is: revtime[,reason,extra]. Where 'revtime' is the revocation time
   2378      1.1  christos  * (the current time). 'reason' is the optional CRL reason and 'extra' is any
   2379      1.1  christos  * additional argument
   2380      1.1  christos  */
   2381      1.1  christos 
   2382      1.1  christos static char *make_revocation_str(REVINFO_TYPE rev_type, const char *rev_arg)
   2383      1.1  christos {
   2384      1.1  christos     char *str;
   2385      1.1  christos     const char *reason = NULL, *other = NULL;
   2386      1.1  christos     ASN1_OBJECT *otmp;
   2387      1.1  christos     ASN1_UTCTIME *revtm = NULL;
   2388      1.1  christos     int i;
   2389      1.1  christos 
   2390      1.1  christos     switch (rev_type) {
   2391      1.1  christos     case REV_NONE:
   2392      1.1  christos     case REV_VALID:
   2393      1.1  christos         break;
   2394      1.1  christos 
   2395      1.1  christos     case REV_CRL_REASON:
   2396      1.1  christos         for (i = 0; i < 8; i++) {
   2397      1.1  christos             if (OPENSSL_strcasecmp(rev_arg, crl_reasons[i]) == 0) {
   2398      1.1  christos                 reason = crl_reasons[i];
   2399      1.1  christos                 break;
   2400      1.1  christos             }
   2401      1.1  christos         }
   2402      1.1  christos         if (reason == NULL) {
   2403      1.1  christos             BIO_printf(bio_err, "Unknown CRL reason %s\n", rev_arg);
   2404      1.1  christos             return NULL;
   2405      1.1  christos         }
   2406      1.1  christos         break;
   2407      1.1  christos 
   2408      1.1  christos     case REV_HOLD:
   2409      1.1  christos         /* Argument is an OID */
   2410      1.1  christos         otmp = OBJ_txt2obj(rev_arg, 0);
   2411      1.1  christos         ASN1_OBJECT_free(otmp);
   2412      1.1  christos 
   2413      1.1  christos         if (otmp == NULL) {
   2414      1.1  christos             BIO_printf(bio_err, "Invalid object identifier %s\n", rev_arg);
   2415      1.1  christos             return NULL;
   2416      1.1  christos         }
   2417      1.1  christos 
   2418      1.1  christos         reason = "holdInstruction";
   2419      1.1  christos         other = rev_arg;
   2420      1.1  christos         break;
   2421      1.1  christos 
   2422      1.1  christos     case REV_KEY_COMPROMISE:
   2423      1.1  christos     case REV_CA_COMPROMISE:
   2424      1.1  christos         /* Argument is the key compromise time  */
   2425      1.1  christos         if (!ASN1_GENERALIZEDTIME_set_string(NULL, rev_arg)) {
   2426      1.1  christos             BIO_printf(bio_err,
   2427  1.1.1.2  christos                 "Invalid time format %s. Need YYYYMMDDHHMMSSZ\n",
   2428  1.1.1.2  christos                 rev_arg);
   2429      1.1  christos             return NULL;
   2430      1.1  christos         }
   2431      1.1  christos         other = rev_arg;
   2432      1.1  christos         if (rev_type == REV_KEY_COMPROMISE)
   2433      1.1  christos             reason = "keyTime";
   2434      1.1  christos         else
   2435      1.1  christos             reason = "CAkeyTime";
   2436      1.1  christos 
   2437      1.1  christos         break;
   2438      1.1  christos     }
   2439      1.1  christos 
   2440      1.1  christos     revtm = X509_gmtime_adj(NULL, 0);
   2441      1.1  christos 
   2442      1.1  christos     if (!revtm)
   2443      1.1  christos         return NULL;
   2444      1.1  christos 
   2445      1.1  christos     i = revtm->length + 1;
   2446      1.1  christos 
   2447      1.1  christos     if (reason)
   2448      1.1  christos         i += strlen(reason) + 1;
   2449      1.1  christos     if (other)
   2450      1.1  christos         i += strlen(other) + 1;
   2451      1.1  christos 
   2452      1.1  christos     str = app_malloc(i, "revocation reason");
   2453      1.1  christos     OPENSSL_strlcpy(str, (char *)revtm->data, i);
   2454      1.1  christos     if (reason) {
   2455      1.1  christos         OPENSSL_strlcat(str, ",", i);
   2456      1.1  christos         OPENSSL_strlcat(str, reason, i);
   2457      1.1  christos     }
   2458      1.1  christos     if (other) {
   2459      1.1  christos         OPENSSL_strlcat(str, ",", i);
   2460      1.1  christos         OPENSSL_strlcat(str, other, i);
   2461      1.1  christos     }
   2462      1.1  christos     ASN1_UTCTIME_free(revtm);
   2463      1.1  christos     return str;
   2464      1.1  christos }
   2465      1.1  christos 
   2466      1.1  christos /*-
   2467      1.1  christos  * Convert revocation field to X509_REVOKED entry
   2468      1.1  christos  * return code:
   2469      1.1  christos  * 0 error
   2470      1.1  christos  * 1 OK
   2471      1.1  christos  * 2 OK and some extensions added (i.e. V2 CRL)
   2472      1.1  christos  */
   2473      1.1  christos 
   2474      1.1  christos static int make_revoked(X509_REVOKED *rev, const char *str)
   2475      1.1  christos {
   2476      1.1  christos     char *tmp = NULL;
   2477      1.1  christos     int reason_code = -1;
   2478      1.1  christos     int i, ret = 0;
   2479      1.1  christos     ASN1_OBJECT *hold = NULL;
   2480      1.1  christos     ASN1_GENERALIZEDTIME *comp_time = NULL;
   2481      1.1  christos     ASN1_ENUMERATED *rtmp = NULL;
   2482      1.1  christos 
   2483      1.1  christos     ASN1_TIME *revDate = NULL;
   2484      1.1  christos 
   2485      1.1  christos     i = unpack_revinfo(&revDate, &reason_code, &hold, &comp_time, str);
   2486      1.1  christos 
   2487      1.1  christos     if (i == 0)
   2488      1.1  christos         goto end;
   2489      1.1  christos 
   2490      1.1  christos     if (rev && !X509_REVOKED_set_revocationDate(rev, revDate))
   2491      1.1  christos         goto end;
   2492      1.1  christos 
   2493      1.1  christos     if (rev && (reason_code != OCSP_REVOKED_STATUS_NOSTATUS)) {
   2494      1.1  christos         rtmp = ASN1_ENUMERATED_new();
   2495      1.1  christos         if (rtmp == NULL || !ASN1_ENUMERATED_set(rtmp, reason_code))
   2496      1.1  christos             goto end;
   2497      1.1  christos         if (X509_REVOKED_add1_ext_i2d(rev, NID_crl_reason, rtmp, 0, 0) <= 0)
   2498      1.1  christos             goto end;
   2499      1.1  christos     }
   2500      1.1  christos 
   2501      1.1  christos     if (rev && comp_time) {
   2502  1.1.1.2  christos         if (X509_REVOKED_add1_ext_i2d(rev, NID_invalidity_date, comp_time, 0, 0) <= 0)
   2503      1.1  christos             goto end;
   2504      1.1  christos     }
   2505      1.1  christos     if (rev && hold) {
   2506  1.1.1.2  christos         if (X509_REVOKED_add1_ext_i2d(rev, NID_hold_instruction_code, hold, 0, 0) <= 0)
   2507      1.1  christos             goto end;
   2508      1.1  christos     }
   2509      1.1  christos 
   2510      1.1  christos     if (reason_code != OCSP_REVOKED_STATUS_NOSTATUS)
   2511      1.1  christos         ret = 2;
   2512      1.1  christos     else
   2513      1.1  christos         ret = 1;
   2514      1.1  christos 
   2515  1.1.1.2  christos end:
   2516      1.1  christos 
   2517      1.1  christos     OPENSSL_free(tmp);
   2518      1.1  christos     ASN1_OBJECT_free(hold);
   2519      1.1  christos     ASN1_GENERALIZEDTIME_free(comp_time);
   2520      1.1  christos     ASN1_ENUMERATED_free(rtmp);
   2521      1.1  christos     ASN1_TIME_free(revDate);
   2522      1.1  christos 
   2523      1.1  christos     return ret;
   2524      1.1  christos }
   2525      1.1  christos 
   2526      1.1  christos static int old_entry_print(const ASN1_OBJECT *obj, const ASN1_STRING *str)
   2527      1.1  christos {
   2528      1.1  christos     char buf[25], *pbuf;
   2529      1.1  christos     const char *p;
   2530      1.1  christos     int j;
   2531      1.1  christos 
   2532      1.1  christos     j = i2a_ASN1_OBJECT(bio_err, obj);
   2533      1.1  christos     pbuf = buf;
   2534      1.1  christos     for (j = 22 - j; j > 0; j--)
   2535      1.1  christos         *(pbuf++) = ' ';
   2536      1.1  christos     *(pbuf++) = ':';
   2537      1.1  christos     *(pbuf++) = '\0';
   2538      1.1  christos     BIO_puts(bio_err, buf);
   2539      1.1  christos 
   2540      1.1  christos     if (str->type == V_ASN1_PRINTABLESTRING)
   2541      1.1  christos         BIO_printf(bio_err, "PRINTABLE:'");
   2542      1.1  christos     else if (str->type == V_ASN1_T61STRING)
   2543      1.1  christos         BIO_printf(bio_err, "T61STRING:'");
   2544      1.1  christos     else if (str->type == V_ASN1_IA5STRING)
   2545      1.1  christos         BIO_printf(bio_err, "IA5STRING:'");
   2546      1.1  christos     else if (str->type == V_ASN1_UNIVERSALSTRING)
   2547      1.1  christos         BIO_printf(bio_err, "UNIVERSALSTRING:'");
   2548      1.1  christos     else
   2549      1.1  christos         BIO_printf(bio_err, "ASN.1 %2d:'", str->type);
   2550      1.1  christos 
   2551      1.1  christos     p = (const char *)str->data;
   2552      1.1  christos     for (j = str->length; j > 0; j--) {
   2553      1.1  christos         if ((*p >= ' ') && (*p <= '~'))
   2554      1.1  christos             BIO_printf(bio_err, "%c", *p);
   2555      1.1  christos         else if (*p & 0x80)
   2556      1.1  christos             BIO_printf(bio_err, "\\0x%02X", *p);
   2557      1.1  christos         else if ((unsigned char)*p == 0xf7)
   2558      1.1  christos             BIO_printf(bio_err, "^?");
   2559      1.1  christos         else
   2560      1.1  christos             BIO_printf(bio_err, "^%c", *p + '@');
   2561      1.1  christos         p++;
   2562      1.1  christos     }
   2563      1.1  christos     BIO_printf(bio_err, "'\n");
   2564      1.1  christos     return 1;
   2565      1.1  christos }
   2566      1.1  christos 
   2567      1.1  christos int unpack_revinfo(ASN1_TIME **prevtm, int *preason, ASN1_OBJECT **phold,
   2568  1.1.1.2  christos     ASN1_GENERALIZEDTIME **pinvtm, const char *str)
   2569      1.1  christos {
   2570      1.1  christos     char *tmp;
   2571      1.1  christos     char *rtime_str, *reason_str = NULL, *arg_str = NULL, *p;
   2572      1.1  christos     int reason_code = -1;
   2573      1.1  christos     int ret = 0;
   2574      1.1  christos     unsigned int i;
   2575      1.1  christos     ASN1_OBJECT *hold = NULL;
   2576      1.1  christos     ASN1_GENERALIZEDTIME *comp_time = NULL;
   2577      1.1  christos 
   2578      1.1  christos     tmp = OPENSSL_strdup(str);
   2579      1.1  christos     if (!tmp) {
   2580      1.1  christos         BIO_printf(bio_err, "memory allocation failure\n");
   2581      1.1  christos         goto end;
   2582      1.1  christos     }
   2583      1.1  christos 
   2584      1.1  christos     p = strchr(tmp, ',');
   2585      1.1  christos 
   2586      1.1  christos     rtime_str = tmp;
   2587      1.1  christos 
   2588      1.1  christos     if (p) {
   2589      1.1  christos         *p = '\0';
   2590      1.1  christos         p++;
   2591      1.1  christos         reason_str = p;
   2592      1.1  christos         p = strchr(p, ',');
   2593      1.1  christos         if (p) {
   2594      1.1  christos             *p = '\0';
   2595      1.1  christos             arg_str = p + 1;
   2596      1.1  christos         }
   2597      1.1  christos     }
   2598      1.1  christos 
   2599      1.1  christos     if (prevtm) {
   2600      1.1  christos         *prevtm = ASN1_UTCTIME_new();
   2601      1.1  christos         if (*prevtm == NULL) {
   2602      1.1  christos             BIO_printf(bio_err, "memory allocation failure\n");
   2603      1.1  christos             goto end;
   2604      1.1  christos         }
   2605      1.1  christos         if (!ASN1_UTCTIME_set_string(*prevtm, rtime_str)) {
   2606      1.1  christos             BIO_printf(bio_err, "invalid revocation date %s\n", rtime_str);
   2607      1.1  christos             goto end;
   2608      1.1  christos         }
   2609      1.1  christos     }
   2610      1.1  christos     if (reason_str) {
   2611      1.1  christos         for (i = 0; i < NUM_REASONS; i++) {
   2612      1.1  christos             if (OPENSSL_strcasecmp(reason_str, crl_reasons[i]) == 0) {
   2613      1.1  christos                 reason_code = i;
   2614      1.1  christos                 break;
   2615      1.1  christos             }
   2616      1.1  christos         }
   2617      1.1  christos         if (reason_code == OCSP_REVOKED_STATUS_NOSTATUS) {
   2618      1.1  christos             BIO_printf(bio_err, "invalid reason code %s\n", reason_str);
   2619      1.1  christos             goto end;
   2620      1.1  christos         }
   2621      1.1  christos 
   2622      1.1  christos         if (reason_code == 7) {
   2623      1.1  christos             reason_code = OCSP_REVOKED_STATUS_REMOVEFROMCRL;
   2624      1.1  christos         } else if (reason_code == 8) { /* Hold instruction */
   2625      1.1  christos             if (!arg_str) {
   2626      1.1  christos                 BIO_printf(bio_err, "missing hold instruction\n");
   2627      1.1  christos                 goto end;
   2628      1.1  christos             }
   2629      1.1  christos             reason_code = OCSP_REVOKED_STATUS_CERTIFICATEHOLD;
   2630      1.1  christos             hold = OBJ_txt2obj(arg_str, 0);
   2631      1.1  christos 
   2632      1.1  christos             if (!hold) {
   2633      1.1  christos                 BIO_printf(bio_err, "invalid object identifier %s\n", arg_str);
   2634      1.1  christos                 goto end;
   2635      1.1  christos             }
   2636      1.1  christos             if (phold)
   2637      1.1  christos                 *phold = hold;
   2638      1.1  christos             else
   2639      1.1  christos                 ASN1_OBJECT_free(hold);
   2640      1.1  christos         } else if ((reason_code == 9) || (reason_code == 10)) {
   2641      1.1  christos             if (!arg_str) {
   2642      1.1  christos                 BIO_printf(bio_err, "missing compromised time\n");
   2643      1.1  christos                 goto end;
   2644      1.1  christos             }
   2645      1.1  christos             comp_time = ASN1_GENERALIZEDTIME_new();
   2646      1.1  christos             if (comp_time == NULL) {
   2647      1.1  christos                 BIO_printf(bio_err, "memory allocation failure\n");
   2648      1.1  christos                 goto end;
   2649      1.1  christos             }
   2650      1.1  christos             if (!ASN1_GENERALIZEDTIME_set_string(comp_time, arg_str)) {
   2651      1.1  christos                 BIO_printf(bio_err, "invalid compromised time %s\n", arg_str);
   2652      1.1  christos                 goto end;
   2653      1.1  christos             }
   2654      1.1  christos             if (reason_code == 9)
   2655      1.1  christos                 reason_code = OCSP_REVOKED_STATUS_KEYCOMPROMISE;
   2656      1.1  christos             else
   2657      1.1  christos                 reason_code = OCSP_REVOKED_STATUS_CACOMPROMISE;
   2658      1.1  christos         }
   2659      1.1  christos     }
   2660      1.1  christos 
   2661      1.1  christos     if (preason)
   2662      1.1  christos         *preason = reason_code;
   2663      1.1  christos     if (pinvtm) {
   2664      1.1  christos         *pinvtm = comp_time;
   2665      1.1  christos         comp_time = NULL;
   2666      1.1  christos     }
   2667      1.1  christos 
   2668      1.1  christos     ret = 1;
   2669      1.1  christos 
   2670  1.1.1.2  christos end:
   2671      1.1  christos 
   2672      1.1  christos     OPENSSL_free(tmp);
   2673      1.1  christos     ASN1_GENERALIZEDTIME_free(comp_time);
   2674      1.1  christos 
   2675      1.1  christos     return ret;
   2676      1.1  christos }
   2677