Home | History | Annotate | Line # | Download | only in lib
apps.c revision 1.2
      1 /*
      2  * Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved.
      3  *
      4  * Licensed under the Apache License 2.0 (the "License").  You may not use
      5  * this file except in compliance with the License.  You can obtain a copy
      6  * in the file LICENSE in the source distribution or at
      7  * https://www.openssl.org/source/license.html
      8  */
      9 
     10 #if !defined(_POSIX_C_SOURCE) && defined(OPENSSL_SYS_VMS)
     11 /*
     12  * On VMS, you need to define this to get the declaration of fileno().  The
     13  * value 2 is to make sure no function defined in POSIX-2 is left undefined.
     14  */
     15 # define _POSIX_C_SOURCE 2
     16 #endif
     17 
     18 #ifndef OPENSSL_NO_ENGINE
     19 /* We need to use some deprecated APIs */
     20 # define OPENSSL_SUPPRESS_DEPRECATED
     21 # include <openssl/engine.h>
     22 #endif
     23 
     24 #include <stdio.h>
     25 #include <stdlib.h>
     26 #include <string.h>
     27 #include <sys/types.h>
     28 #ifndef OPENSSL_NO_POSIX_IO
     29 # include <sys/stat.h>
     30 # include <fcntl.h>
     31 #endif
     32 #include <ctype.h>
     33 #include <errno.h>
     34 #include <openssl/err.h>
     35 #include <openssl/x509.h>
     36 #include <openssl/x509v3.h>
     37 #include <openssl/http.h>
     38 #include <openssl/pem.h>
     39 #include <openssl/store.h>
     40 #include <openssl/pkcs12.h>
     41 #include <openssl/ui.h>
     42 #include <openssl/safestack.h>
     43 #include <openssl/rsa.h>
     44 #include <openssl/rand.h>
     45 #include <openssl/bn.h>
     46 #include <openssl/ssl.h>
     47 #include <openssl/core_names.h>
     48 #include "s_apps.h"
     49 #include "apps.h"
     50 
     51 #include "internal/sockets.h" /* for openssl_fdset() */
     52 #include "internal/e_os.h"
     53 
     54 #ifdef _WIN32
     55 static int WIN32_rename(const char *from, const char *to);
     56 # define rename(from, to) WIN32_rename((from), (to))
     57 #endif
     58 
     59 #if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS)
     60 # include <conio.h>
     61 #endif
     62 
     63 #if defined(OPENSSL_SYS_MSDOS) && !defined(_WIN32) || defined(__BORLANDC__)
     64 # define _kbhit kbhit
     65 #endif
     66 
     67 static BIO *bio_open_default_(const char *filename, char mode, int format,
     68                               int quiet);
     69 
     70 #define PASS_SOURCE_SIZE_MAX 4
     71 
     72 DEFINE_STACK_OF(CONF)
     73 
     74 typedef struct {
     75     const char *name;
     76     unsigned long flag;
     77     unsigned long mask;
     78 } NAME_EX_TBL;
     79 
     80 static int set_table_opts(unsigned long *flags, const char *arg,
     81                           const NAME_EX_TBL *in_tbl);
     82 static int set_multi_opts(unsigned long *flags, const char *arg,
     83                           const NAME_EX_TBL *in_tbl);
     84 int app_init(long mesgwin);
     85 
     86 int chopup_args(ARGS *arg, char *buf)
     87 {
     88     int quoted;
     89     char c = '\0', *p = NULL;
     90 
     91     arg->argc = 0;
     92     if (arg->size == 0) {
     93         arg->size = 20;
     94         arg->argv = app_malloc(sizeof(*arg->argv) * arg->size, "argv space");
     95     }
     96 
     97     for (p = buf;;) {
     98         /* Skip whitespace. */
     99         while (*p && isspace(_UC(*p)))
    100             p++;
    101         if (*p == '\0')
    102             break;
    103 
    104         /* The start of something good :-) */
    105         if (arg->argc >= arg->size) {
    106             char **tmp;
    107 
    108             arg->size += 20;
    109             tmp = OPENSSL_realloc(arg->argv, sizeof(*arg->argv) * arg->size);
    110             if (tmp == NULL)
    111                 return 0;
    112             arg->argv = tmp;
    113         }
    114         quoted = *p == '\'' || *p == '"';
    115         if (quoted)
    116             c = *p++;
    117         arg->argv[arg->argc++] = p;
    118 
    119         /* now look for the end of this */
    120         if (quoted) {
    121             while (*p && *p != c)
    122                 p++;
    123             *p++ = '\0';
    124         } else {
    125             while (*p && !isspace(_UC(*p)))
    126                 p++;
    127             if (*p)
    128                 *p++ = '\0';
    129         }
    130     }
    131     arg->argv[arg->argc] = NULL;
    132     return 1;
    133 }
    134 
    135 #ifndef APP_INIT
    136 int app_init(long mesgwin)
    137 {
    138     return 1;
    139 }
    140 #endif
    141 
    142 int ctx_set_verify_locations(SSL_CTX *ctx,
    143                              const char *CAfile, int noCAfile,
    144                              const char *CApath, int noCApath,
    145                              const char *CAstore, int noCAstore)
    146 {
    147     if (CAfile == NULL && CApath == NULL && CAstore == NULL) {
    148         if (!noCAfile && SSL_CTX_set_default_verify_file(ctx) <= 0)
    149             return 0;
    150         if (!noCApath && SSL_CTX_set_default_verify_dir(ctx) <= 0)
    151             return 0;
    152         if (!noCAstore && SSL_CTX_set_default_verify_store(ctx) <= 0)
    153             return 0;
    154 
    155         return 1;
    156     }
    157 
    158     if (CAfile != NULL && !SSL_CTX_load_verify_file(ctx, CAfile))
    159         return 0;
    160     if (CApath != NULL && !SSL_CTX_load_verify_dir(ctx, CApath))
    161         return 0;
    162     if (CAstore != NULL && !SSL_CTX_load_verify_store(ctx, CAstore))
    163         return 0;
    164     return 1;
    165 }
    166 
    167 #ifndef OPENSSL_NO_CT
    168 
    169 int ctx_set_ctlog_list_file(SSL_CTX *ctx, const char *path)
    170 {
    171     if (path == NULL)
    172         return SSL_CTX_set_default_ctlog_list_file(ctx);
    173 
    174     return SSL_CTX_set_ctlog_list_file(ctx, path);
    175 }
    176 
    177 #endif
    178 
    179 static unsigned long nmflag = 0;
    180 static char nmflag_set = 0;
    181 
    182 int set_nameopt(const char *arg)
    183 {
    184     int ret = set_name_ex(&nmflag, arg);
    185 
    186     if (ret)
    187         nmflag_set = 1;
    188 
    189     return ret;
    190 }
    191 
    192 unsigned long get_nameopt(void)
    193 {
    194     return
    195         nmflag_set ? nmflag : XN_FLAG_SEP_CPLUS_SPC | XN_FLAG_FN_SN
    196                               | ASN1_STRFLGS_ESC_CTRL
    197                               | ASN1_STRFLGS_UTF8_CONVERT
    198                               | ASN1_STRFLGS_DUMP_UNKNOWN
    199                               | ASN1_STRFLGS_DUMP_DER;
    200 }
    201 
    202 void dump_cert_text(BIO *out, X509 *x)
    203 {
    204     print_name(out, "subject=", X509_get_subject_name(x));
    205     print_name(out, "issuer=", X509_get_issuer_name(x));
    206 }
    207 
    208 int wrap_password_callback(char *buf, int bufsiz, int verify, void *userdata)
    209 {
    210     return password_callback(buf, bufsiz, verify, (PW_CB_DATA *)userdata);
    211 }
    212 
    213 static char *app_get_pass(const char *arg, int keepbio);
    214 
    215 char *get_passwd(const char *pass, const char *desc)
    216 {
    217     char *result = NULL;
    218 
    219     if (desc == NULL)
    220         desc = "<unknown>";
    221     if (!app_passwd(pass, NULL, &result, NULL))
    222         BIO_printf(bio_err, "Error getting password for %s\n", desc);
    223     if (pass != NULL && result == NULL) {
    224         BIO_printf(bio_err,
    225                    "Trying plain input string (better precede with 'pass:')\n");
    226         result = OPENSSL_strdup(pass);
    227         if (result == NULL)
    228             BIO_printf(bio_err,
    229                        "Out of memory getting password for %s\n", desc);
    230     }
    231     return result;
    232 }
    233 
    234 int app_passwd(const char *arg1, const char *arg2, char **pass1, char **pass2)
    235 {
    236     int same = arg1 != NULL && arg2 != NULL && strcmp(arg1, arg2) == 0;
    237 
    238     if (arg1 != NULL) {
    239         *pass1 = app_get_pass(arg1, same);
    240         if (*pass1 == NULL)
    241             return 0;
    242     } else if (pass1 != NULL) {
    243         *pass1 = NULL;
    244     }
    245     if (arg2 != NULL) {
    246         *pass2 = app_get_pass(arg2, same ? 2 : 0);
    247         if (*pass2 == NULL)
    248             return 0;
    249     } else if (pass2 != NULL) {
    250         *pass2 = NULL;
    251     }
    252     return 1;
    253 }
    254 
    255 static char *app_get_pass(const char *arg, int keepbio)
    256 {
    257     static BIO *pwdbio = NULL;
    258     char *tmp, tpass[APP_PASS_LEN];
    259     int i;
    260 
    261     /* PASS_SOURCE_SIZE_MAX = max number of chars before ':' in below strings */
    262     if (CHECK_AND_SKIP_PREFIX(arg, "pass:"))
    263         return OPENSSL_strdup(arg);
    264     if (CHECK_AND_SKIP_PREFIX(arg, "env:")) {
    265         tmp = getenv(arg);
    266         if (tmp == NULL) {
    267             BIO_printf(bio_err, "No environment variable %s\n", arg);
    268             return NULL;
    269         }
    270         return OPENSSL_strdup(tmp);
    271     }
    272     if (!keepbio || pwdbio == NULL) {
    273         if (CHECK_AND_SKIP_PREFIX(arg, "file:")) {
    274             pwdbio = BIO_new_file(arg, "r");
    275             if (pwdbio == NULL) {
    276                 BIO_printf(bio_err, "Can't open file %s\n", arg);
    277                 return NULL;
    278             }
    279 #if !defined(_WIN32)
    280             /*
    281              * Under _WIN32, which covers even Win64 and CE, file
    282              * descriptors referenced by BIO_s_fd are not inherited
    283              * by child process and therefore below is not an option.
    284              * It could have been an option if bss_fd.c was operating
    285              * on real Windows descriptors, such as those obtained
    286              * with CreateFile.
    287              */
    288         } else if (CHECK_AND_SKIP_PREFIX(arg, "fd:")) {
    289             BIO *btmp;
    290 
    291             i = atoi(arg);
    292             if (i >= 0)
    293                 pwdbio = BIO_new_fd(i, BIO_NOCLOSE);
    294             if ((i < 0) || pwdbio == NULL) {
    295                 BIO_printf(bio_err, "Can't access file descriptor %s\n", arg);
    296                 return NULL;
    297             }
    298             /*
    299              * Can't do BIO_gets on an fd BIO so add a buffering BIO
    300              */
    301             btmp = BIO_new(BIO_f_buffer());
    302             if (btmp == NULL) {
    303                 BIO_free_all(pwdbio);
    304                 pwdbio = NULL;
    305                 BIO_printf(bio_err, "Out of memory\n");
    306                 return NULL;
    307             }
    308             pwdbio = BIO_push(btmp, pwdbio);
    309 #endif
    310         } else if (strcmp(arg, "stdin") == 0) {
    311             unbuffer(stdin);
    312             pwdbio = dup_bio_in(FORMAT_TEXT);
    313             if (pwdbio == NULL) {
    314                 BIO_printf(bio_err, "Can't open BIO for stdin\n");
    315                 return NULL;
    316             }
    317         } else {
    318             /* argument syntax error; do not reveal too much about arg */
    319             tmp = strchr(arg, ':');
    320             if (tmp == NULL || tmp - arg > PASS_SOURCE_SIZE_MAX)
    321                 BIO_printf(bio_err,
    322                            "Invalid password argument, missing ':' within the first %d chars\n",
    323                            PASS_SOURCE_SIZE_MAX + 1);
    324             else
    325                 BIO_printf(bio_err,
    326                            "Invalid password argument, starting with \"%.*s\"\n",
    327                            (int)(tmp - arg + 1), arg);
    328             return NULL;
    329         }
    330     }
    331     i = BIO_gets(pwdbio, tpass, APP_PASS_LEN);
    332     if (keepbio != 1) {
    333         BIO_free_all(pwdbio);
    334         pwdbio = NULL;
    335     }
    336     if (i <= 0) {
    337         BIO_printf(bio_err, "Error reading password from BIO\n");
    338         return NULL;
    339     }
    340     tmp = strchr(tpass, '\n');
    341     if (tmp != NULL)
    342         *tmp = 0;
    343     return OPENSSL_strdup(tpass);
    344 }
    345 
    346 char *app_conf_try_string(const CONF *conf, const char *group, const char *name)
    347 {
    348     char *res;
    349 
    350     ERR_set_mark();
    351     res = NCONF_get_string(conf, group, name);
    352     if (res == NULL)
    353         ERR_pop_to_mark();
    354     else
    355         ERR_clear_last_mark();
    356     return res;
    357 }
    358 
    359 int app_conf_try_number(const CONF *conf, const char *group, const char *name,
    360                         long *result)
    361 {
    362     int ok;
    363 
    364     ERR_set_mark();
    365     ok = NCONF_get_number(conf, group, name, result);
    366     if (!ok)
    367         ERR_pop_to_mark();
    368     else
    369         ERR_clear_last_mark();
    370     return ok;
    371 }
    372 
    373 CONF *app_load_config_bio(BIO *in, const char *filename)
    374 {
    375     long errorline = -1;
    376     CONF *conf;
    377     int i;
    378 
    379     conf = NCONF_new_ex(app_get0_libctx(), NULL);
    380     i = NCONF_load_bio(conf, in, &errorline);
    381     if (i > 0)
    382         return conf;
    383 
    384     if (errorline <= 0) {
    385         BIO_printf(bio_err, "%s: Can't load ", opt_getprog());
    386     } else {
    387         BIO_printf(bio_err, "%s: Error on line %ld of ", opt_getprog(),
    388                    errorline);
    389     }
    390     if (filename != NULL)
    391         BIO_printf(bio_err, "config file \"%s\"\n", filename);
    392     else
    393         BIO_printf(bio_err, "config input");
    394 
    395     NCONF_free(conf);
    396     return NULL;
    397 }
    398 
    399 CONF *app_load_config_verbose(const char *filename, int verbose)
    400 {
    401     if (verbose) {
    402         if (*filename == '\0')
    403             BIO_printf(bio_err, "No configuration used\n");
    404         else
    405             BIO_printf(bio_err, "Using configuration from %s\n", filename);
    406     }
    407     return app_load_config_internal(filename, 0);
    408 }
    409 
    410 CONF *app_load_config_internal(const char *filename, int quiet)
    411 {
    412     BIO *in;
    413     CONF *conf;
    414 
    415     if (filename == NULL || *filename != '\0') {
    416         if ((in = bio_open_default_(filename, 'r', FORMAT_TEXT, quiet)) == NULL)
    417             return NULL;
    418         conf = app_load_config_bio(in, filename);
    419         BIO_free(in);
    420     } else {
    421         /* Return empty config if filename is empty string. */
    422         conf = NCONF_new_ex(app_get0_libctx(), NULL);
    423     }
    424     return conf;
    425 }
    426 
    427 int app_load_modules(const CONF *config)
    428 {
    429     CONF *to_free = NULL;
    430 
    431     if (config == NULL)
    432         config = to_free = app_load_config_quiet(default_config_file);
    433     if (config == NULL)
    434         return 1;
    435 
    436     if (CONF_modules_load(config, NULL, 0) <= 0) {
    437         BIO_printf(bio_err, "Error configuring OpenSSL modules\n");
    438         ERR_print_errors(bio_err);
    439         NCONF_free(to_free);
    440         return 0;
    441     }
    442     NCONF_free(to_free);
    443     return 1;
    444 }
    445 
    446 int add_oid_section(CONF *conf)
    447 {
    448     char *p;
    449     STACK_OF(CONF_VALUE) *sktmp;
    450     CONF_VALUE *cnf;
    451     int i;
    452 
    453     if ((p = app_conf_try_string(conf, NULL, "oid_section")) == NULL)
    454         return 1;
    455     if ((sktmp = NCONF_get_section(conf, p)) == NULL) {
    456         BIO_printf(bio_err, "problem loading oid section %s\n", p);
    457         return 0;
    458     }
    459     for (i = 0; i < sk_CONF_VALUE_num(sktmp); i++) {
    460         cnf = sk_CONF_VALUE_value(sktmp, i);
    461         if (OBJ_create(cnf->value, cnf->name, cnf->name) == NID_undef) {
    462             BIO_printf(bio_err, "problem creating object %s=%s\n",
    463                        cnf->name, cnf->value);
    464             return 0;
    465         }
    466     }
    467     return 1;
    468 }
    469 
    470 CONF *app_load_config_modules(const char *configfile)
    471 {
    472     CONF *conf = NULL;
    473 
    474     if (configfile != NULL) {
    475         if ((conf = app_load_config_verbose(configfile, 1)) == NULL)
    476             return NULL;
    477         if (configfile != default_config_file && !app_load_modules(conf)) {
    478             NCONF_free(conf);
    479             conf = NULL;
    480         }
    481     }
    482     return conf;
    483 }
    484 
    485 #define IS_HTTP(uri) ((uri) != NULL  && HAS_PREFIX(uri, OSSL_HTTP_PREFIX))
    486 #define IS_HTTPS(uri) ((uri) != NULL && HAS_PREFIX(uri, OSSL_HTTPS_PREFIX))
    487 
    488 X509 *load_cert_pass(const char *uri, int format, int maybe_stdin,
    489                      const char *pass, const char *desc)
    490 {
    491     X509 *cert = NULL;
    492 
    493     if (desc == NULL)
    494         desc = "certificate";
    495     if (IS_HTTPS(uri)) {
    496         BIO_printf(bio_err, "Loading %s over HTTPS is unsupported\n", desc);
    497     } else if (IS_HTTP(uri)) {
    498         cert = X509_load_http(uri, NULL, NULL, 0 /* timeout */);
    499         if (cert == NULL) {
    500             ERR_print_errors(bio_err);
    501             BIO_printf(bio_err, "Unable to load %s from %s\n", desc, uri);
    502         }
    503     } else {
    504         (void)load_key_certs_crls(uri, format, maybe_stdin, pass, desc, 0,
    505                                   NULL, NULL, NULL, &cert, NULL, NULL, NULL);
    506     }
    507     return cert;
    508 }
    509 
    510 X509_CRL *load_crl(const char *uri, int format, int maybe_stdin,
    511                    const char *desc)
    512 {
    513     X509_CRL *crl = NULL;
    514 
    515     if (desc == NULL)
    516         desc = "CRL";
    517     if (IS_HTTPS(uri)) {
    518         BIO_printf(bio_err, "Loading %s over HTTPS is unsupported\n", desc);
    519     } else if (IS_HTTP(uri)) {
    520         crl = X509_CRL_load_http(uri, NULL, NULL, 0 /* timeout */);
    521         if (crl == NULL) {
    522             ERR_print_errors(bio_err);
    523             BIO_printf(bio_err, "Unable to load %s from %s\n", desc, uri);
    524         }
    525     } else {
    526         (void)load_key_certs_crls(uri, format, maybe_stdin, NULL, desc, 0,
    527                                   NULL, NULL,  NULL, NULL, NULL, &crl, NULL);
    528     }
    529     return crl;
    530 }
    531 
    532 /* Could be simplified if OSSL_STORE supported CSRs, see FR #15725 */
    533 X509_REQ *load_csr(const char *file, int format, const char *desc)
    534 {
    535     X509_REQ *req = NULL;
    536     BIO *in;
    537 
    538     if (format == FORMAT_UNDEF)
    539         format = FORMAT_PEM;
    540     in = bio_open_default(file, 'r', format);
    541     if (in == NULL)
    542         goto end;
    543 
    544     if (format == FORMAT_ASN1)
    545         req = d2i_X509_REQ_bio(in, NULL);
    546     else if (format == FORMAT_PEM)
    547         req = PEM_read_bio_X509_REQ(in, NULL, NULL, NULL);
    548     else
    549         print_format_error(format, OPT_FMT_PEMDER);
    550 
    551  end:
    552     if (req == NULL) {
    553         ERR_print_errors(bio_err);
    554         if (desc != NULL)
    555             BIO_printf(bio_err, "Unable to load %s\n", desc);
    556     }
    557     BIO_free(in);
    558     return req;
    559 }
    560 
    561 /* Better extend OSSL_STORE to support CSRs, see FR #15725 */
    562 X509_REQ *load_csr_autofmt(const char *infile, int format,
    563                            STACK_OF(OPENSSL_STRING) *vfyopts, const char *desc)
    564 {
    565     X509_REQ *csr;
    566 
    567     if (format != FORMAT_UNDEF) {
    568         csr = load_csr(infile, format, desc);
    569     } else { /* try PEM, then DER */
    570         BIO *bio_bak = bio_err;
    571 
    572         bio_err = NULL; /* do not show errors on more than one try */
    573         csr = load_csr(infile, FORMAT_PEM, NULL /* desc */);
    574         bio_err = bio_bak;
    575         if (csr == NULL) {
    576             ERR_clear_error();
    577             csr = load_csr(infile, FORMAT_ASN1, NULL /* desc */);
    578         }
    579         if (csr == NULL) {
    580             BIO_printf(bio_err, "error: unable to load %s from file '%s'\n",
    581                        desc, infile);
    582         }
    583     }
    584     if (csr != NULL) {
    585         EVP_PKEY *pkey = X509_REQ_get0_pubkey(csr);
    586         int ret = do_X509_REQ_verify(csr, pkey, vfyopts);
    587 
    588         if (pkey == NULL || ret < 0)
    589             BIO_puts(bio_err, "Warning: error while verifying CSR self-signature\n");
    590         else if (ret == 0)
    591             BIO_puts(bio_err, "Warning: CSR self-signature does not match the contents\n");
    592         return csr;
    593     }
    594     return csr;
    595 }
    596 
    597 void cleanse(char *str)
    598 {
    599     if (str != NULL)
    600         OPENSSL_cleanse(str, strlen(str));
    601 }
    602 
    603 void clear_free(char *str)
    604 {
    605     if (str != NULL)
    606         OPENSSL_clear_free(str, strlen(str));
    607 }
    608 
    609 EVP_PKEY *load_key(const char *uri, int format, int may_stdin,
    610                    const char *pass, ENGINE *e, const char *desc)
    611 {
    612     EVP_PKEY *pkey = NULL;
    613     char *allocated_uri = NULL;
    614 
    615     if (desc == NULL)
    616         desc = "private key";
    617 
    618     if (format == FORMAT_ENGINE)
    619         uri = allocated_uri = make_engine_uri(e, uri, desc);
    620     (void)load_key_certs_crls(uri, format, may_stdin, pass, desc, 0,
    621                               &pkey, NULL, NULL, NULL, NULL, NULL, NULL);
    622 
    623     OPENSSL_free(allocated_uri);
    624     return pkey;
    625 }
    626 
    627 /* first try reading public key, on failure resort to loading private key */
    628 EVP_PKEY *load_pubkey(const char *uri, int format, int maybe_stdin,
    629                       const char *pass, ENGINE *e, const char *desc)
    630 {
    631     EVP_PKEY *pkey = NULL;
    632     char *allocated_uri = NULL;
    633 
    634     if (desc == NULL)
    635         desc = "public key";
    636 
    637     if (format == FORMAT_ENGINE)
    638         uri = allocated_uri = make_engine_uri(e, uri, desc);
    639     (void)load_key_certs_crls(uri, format, maybe_stdin, pass, desc, 1,
    640                               NULL, &pkey, NULL, NULL, NULL, NULL, NULL);
    641     if (pkey == NULL)
    642         (void)load_key_certs_crls(uri, format, maybe_stdin, pass, desc, 0,
    643                                   &pkey, NULL, NULL, NULL, NULL, NULL, NULL);
    644     OPENSSL_free(allocated_uri);
    645     return pkey;
    646 }
    647 
    648 EVP_PKEY *load_keyparams_suppress(const char *uri, int format, int maybe_stdin,
    649                                   const char *keytype, const char *desc,
    650                                   int suppress_decode_errors)
    651 {
    652     EVP_PKEY *params = NULL;
    653 
    654     if (desc == NULL)
    655         desc = "key parameters";
    656     (void)load_key_certs_crls(uri, format, maybe_stdin, NULL, desc,
    657                               suppress_decode_errors,
    658                               NULL, NULL, &params, NULL, NULL, NULL, NULL);
    659     if (params != NULL && keytype != NULL && !EVP_PKEY_is_a(params, keytype)) {
    660         ERR_print_errors(bio_err);
    661         BIO_printf(bio_err,
    662                    "Unable to load %s from %s (unexpected parameters type)\n",
    663                    desc, uri);
    664         EVP_PKEY_free(params);
    665         params = NULL;
    666     }
    667     return params;
    668 }
    669 
    670 EVP_PKEY *load_keyparams(const char *uri, int format, int maybe_stdin,
    671                          const char *keytype, const char *desc)
    672 {
    673     return load_keyparams_suppress(uri, format, maybe_stdin, keytype, desc, 0);
    674 }
    675 
    676 void app_bail_out(const char *fmt, ...)
    677 {
    678     va_list args;
    679 
    680     va_start(args, fmt);
    681     BIO_vprintf(bio_err, fmt, args);
    682     va_end(args);
    683     ERR_print_errors(bio_err);
    684     exit(EXIT_FAILURE);
    685 }
    686 
    687 void *app_malloc(size_t sz, const char *what)
    688 {
    689     void *vp = OPENSSL_malloc(sz);
    690 
    691     if (vp == NULL)
    692         app_bail_out("%s: Could not allocate %zu bytes for %s\n",
    693                      opt_getprog(), sz, what);
    694     return vp;
    695 }
    696 
    697 char *next_item(char *opt) /* in list separated by comma and/or space */
    698 {
    699     /* advance to separator (comma or whitespace), if any */
    700     while (*opt != ',' && !isspace(_UC(*opt)) && *opt != '\0')
    701         opt++;
    702     if (*opt != '\0') {
    703         /* terminate current item */
    704         *opt++ = '\0';
    705         /* skip over any whitespace after separator */
    706         while (isspace(_UC(*opt)))
    707             opt++;
    708     }
    709     return *opt == '\0' ? NULL : opt; /* NULL indicates end of input */
    710 }
    711 
    712 static void warn_cert_msg(const char *uri, X509 *cert, const char *msg)
    713 {
    714     char *subj = X509_NAME_oneline(X509_get_subject_name(cert), NULL, 0);
    715 
    716     BIO_printf(bio_err, "Warning: certificate from '%s' with subject '%s' %s\n",
    717                uri, subj, msg);
    718     OPENSSL_free(subj);
    719 }
    720 
    721 static void warn_cert(const char *uri, X509 *cert, int warn_EE,
    722                       X509_VERIFY_PARAM *vpm)
    723 {
    724     uint32_t ex_flags = X509_get_extension_flags(cert);
    725     int res = X509_cmp_timeframe(vpm, X509_get0_notBefore(cert),
    726                                  X509_get0_notAfter(cert));
    727 
    728     if (res != 0)
    729         warn_cert_msg(uri, cert, res > 0 ? "has expired" : "not yet valid");
    730     if (warn_EE && (ex_flags & EXFLAG_V1) == 0 && (ex_flags & EXFLAG_CA) == 0)
    731         warn_cert_msg(uri, cert, "is not a CA cert");
    732 }
    733 
    734 static void warn_certs(const char *uri, STACK_OF(X509) *certs, int warn_EE,
    735                        X509_VERIFY_PARAM *vpm)
    736 {
    737     int i;
    738 
    739     for (i = 0; i < sk_X509_num(certs); i++)
    740         warn_cert(uri, sk_X509_value(certs, i), warn_EE, vpm);
    741 }
    742 
    743 int load_cert_certs(const char *uri,
    744                     X509 **pcert, STACK_OF(X509) **pcerts,
    745                     int exclude_http, const char *pass, const char *desc,
    746                     X509_VERIFY_PARAM *vpm)
    747 {
    748     int ret = 0;
    749     char *pass_string;
    750 
    751     if (desc == NULL)
    752         desc = pcerts == NULL ? "certificate" : "certificates";
    753     if (exclude_http && (HAS_CASE_PREFIX(uri, "http://")
    754                          || HAS_CASE_PREFIX(uri, "https://"))) {
    755         BIO_printf(bio_err, "error: HTTP retrieval not allowed for %s\n", desc);
    756         return ret;
    757     }
    758     pass_string = get_passwd(pass, desc);
    759     ret = load_key_certs_crls(uri, FORMAT_UNDEF, 0, pass_string, desc, 0,
    760                               NULL, NULL, NULL, pcert, pcerts, NULL, NULL);
    761     clear_free(pass_string);
    762 
    763     if (ret) {
    764         if (pcert != NULL)
    765             warn_cert(uri, *pcert, 0, vpm);
    766         if (pcerts != NULL)
    767             warn_certs(uri, *pcerts, 1, vpm);
    768     } else {
    769         if (pcerts != NULL) {
    770             OSSL_STACK_OF_X509_free(*pcerts);
    771             *pcerts = NULL;
    772         }
    773     }
    774     return ret;
    775 }
    776 
    777 STACK_OF(X509) *load_certs_multifile(char *files, const char *pass,
    778                                      const char *desc, X509_VERIFY_PARAM *vpm)
    779 {
    780     STACK_OF(X509) *certs = NULL;
    781     STACK_OF(X509) *result = sk_X509_new_null();
    782 
    783     if (files == NULL)
    784         goto err;
    785     if (result == NULL)
    786         goto oom;
    787 
    788     while (files != NULL) {
    789         char *next = next_item(files);
    790 
    791         if (!load_cert_certs(files, NULL, &certs, 0, pass, desc, vpm))
    792             goto err;
    793         if (!X509_add_certs(result, certs,
    794                             X509_ADD_FLAG_UP_REF | X509_ADD_FLAG_NO_DUP))
    795             goto oom;
    796         OSSL_STACK_OF_X509_free(certs);
    797         certs = NULL;
    798         files = next;
    799     }
    800     return result;
    801 
    802  oom:
    803     BIO_printf(bio_err, "out of memory\n");
    804  err:
    805     OSSL_STACK_OF_X509_free(certs);
    806     OSSL_STACK_OF_X509_free(result);
    807     return NULL;
    808 }
    809 
    810 static X509_STORE *sk_X509_to_store(X509_STORE *store /* may be NULL */,
    811                                     const STACK_OF(X509) *certs /* may NULL */)
    812 {
    813     int i;
    814 
    815     if (store == NULL)
    816         store = X509_STORE_new();
    817     if (store == NULL)
    818         return NULL;
    819     for (i = 0; i < sk_X509_num(certs); i++) {
    820         if (!X509_STORE_add_cert(store, sk_X509_value(certs, i))) {
    821             X509_STORE_free(store);
    822             return NULL;
    823         }
    824     }
    825     return store;
    826 }
    827 
    828 /*
    829  * Create cert store structure with certificates read from given file(s).
    830  * Returns pointer to created X509_STORE on success, NULL on error.
    831  */
    832 X509_STORE *load_certstore(char *input, const char *pass, const char *desc,
    833                            X509_VERIFY_PARAM *vpm)
    834 {
    835     X509_STORE *store = NULL;
    836     STACK_OF(X509) *certs = NULL;
    837 
    838     while (input != NULL) {
    839         char *next = next_item(input);
    840         int ok;
    841 
    842         if (!load_cert_certs(input, NULL, &certs, 1, pass, desc, vpm)) {
    843             X509_STORE_free(store);
    844             return NULL;
    845         }
    846         ok = (store = sk_X509_to_store(store, certs)) != NULL;
    847         OSSL_STACK_OF_X509_free(certs);
    848         certs = NULL;
    849         if (!ok)
    850             return NULL;
    851         input = next;
    852     }
    853     return store;
    854 }
    855 
    856 /*
    857  * Initialize or extend, if *certs != NULL, a certificate stack.
    858  * The caller is responsible for freeing *certs if its value is left not NULL.
    859  */
    860 int load_certs(const char *uri, int maybe_stdin, STACK_OF(X509) **certs,
    861                const char *pass, const char *desc)
    862 {
    863     int ret, was_NULL = *certs == NULL;
    864 
    865     if (desc == NULL)
    866         desc = "certificates";
    867     ret = load_key_certs_crls(uri, FORMAT_UNDEF, maybe_stdin, pass, desc, 0,
    868                               NULL, NULL, NULL, NULL, certs, NULL, NULL);
    869 
    870     if (!ret && was_NULL) {
    871         OSSL_STACK_OF_X509_free(*certs);
    872         *certs = NULL;
    873     }
    874     return ret;
    875 }
    876 
    877 /*
    878  * Initialize or extend, if *crls != NULL, a certificate stack.
    879  * The caller is responsible for freeing *crls if its value is left not NULL.
    880  */
    881 int load_crls(const char *uri, STACK_OF(X509_CRL) **crls,
    882               const char *pass, const char *desc)
    883 {
    884     int ret, was_NULL = *crls == NULL;
    885 
    886     if (desc == NULL)
    887         desc = "CRLs";
    888     ret = load_key_certs_crls(uri, FORMAT_UNDEF, 0, pass, desc, 0,
    889                               NULL, NULL, NULL, NULL, NULL, NULL, crls);
    890 
    891     if (!ret && was_NULL) {
    892         sk_X509_CRL_pop_free(*crls, X509_CRL_free);
    893         *crls = NULL;
    894     }
    895     return ret;
    896 }
    897 
    898 static const char *format2string(int format)
    899 {
    900     switch (format) {
    901     case FORMAT_PEM:
    902         return "PEM";
    903     case FORMAT_ASN1:
    904         return "DER";
    905     case FORMAT_PVK:
    906         return "PVK";
    907     case FORMAT_MSBLOB:
    908         return "MSBLOB";
    909     }
    910     return NULL;
    911 }
    912 
    913 /* Set type expectation, but set to 0 if objects of multiple types expected. */
    914 #define SET_EXPECT(val) \
    915     (expect = expect < 0 ? (val) : (expect == (val) ? (val) : 0))
    916 #define SET_EXPECT1(pvar, val) \
    917     if ((pvar) != NULL) { \
    918         *(pvar) = NULL; \
    919         SET_EXPECT(val); \
    920     }
    921 /* Provide (error msg) text for some of the credential types to be loaded. */
    922 #define FAIL_NAME \
    923     (ppkey != NULL ? "private key" : ppubkey != NULL ? "public key" :  \
    924      pparams != NULL ? "key parameters" :                              \
    925      pcert != NULL ? "certificate" : pcerts != NULL ? "certificates" : \
    926      pcrl != NULL ? "CRL" : pcrls != NULL ? "CRLs" : NULL)
    927 /*
    928  * Load those types of credentials for which the result pointer is not NULL.
    929  * Reads from stdin if 'uri' is NULL and 'maybe_stdin' is nonzero.
    930  * 'format' parameter may be FORMAT_PEM, FORMAT_ASN1, or 0 for no hint.
    931  * desc may contain more detail on the credential(s) to be loaded for error msg
    932  * For non-NULL ppkey, pcert, and pcrl the first suitable value found is loaded.
    933  * If pcerts is non-NULL and *pcerts == NULL then a new cert list is allocated.
    934  * If pcerts is non-NULL then all available certificates are appended to *pcerts
    935  * except any certificate assigned to *pcert.
    936  * If pcrls is non-NULL and *pcrls == NULL then a new list of CRLs is allocated.
    937  * If pcrls is non-NULL then all available CRLs are appended to *pcerts
    938  * except any CRL assigned to *pcrl.
    939  * In any case (also on error) the caller is responsible for freeing all members
    940  * of *pcerts and *pcrls (as far as they are not NULL).
    941  */
    942 int load_key_certs_crls(const char *uri, int format, int maybe_stdin,
    943                         const char *pass, const char *desc, int quiet,
    944                         EVP_PKEY **ppkey, EVP_PKEY **ppubkey,
    945                         EVP_PKEY **pparams,
    946                         X509 **pcert, STACK_OF(X509) **pcerts,
    947                         X509_CRL **pcrl, STACK_OF(X509_CRL) **pcrls)
    948 {
    949     PW_CB_DATA uidata;
    950     OSSL_STORE_CTX *ctx = NULL;
    951     OSSL_LIB_CTX *libctx = app_get0_libctx();
    952     const char *propq = app_get0_propq();
    953     int ncerts = 0, ncrls = 0, expect = -1;
    954     const char *failed = FAIL_NAME;
    955     const char *input_type;
    956     OSSL_PARAM itp[2];
    957     const OSSL_PARAM *params = NULL;
    958 
    959     /* 'failed' describes type of credential to load for potential error msg */
    960     if (failed == NULL) {
    961         if (!quiet)
    962             BIO_printf(bio_err, "Internal error: nothing was requested to load from %s\n",
    963                        uri != NULL ? uri : "<stdin>");
    964         return 0;
    965     }
    966     /* suppress any extraneous errors left over from failed parse attempts */
    967     ERR_set_mark();
    968 
    969     SET_EXPECT1(ppkey, OSSL_STORE_INFO_PKEY);
    970     SET_EXPECT1(ppubkey, OSSL_STORE_INFO_PUBKEY);
    971     SET_EXPECT1(pparams, OSSL_STORE_INFO_PARAMS);
    972     SET_EXPECT1(pcert, OSSL_STORE_INFO_CERT);
    973     /*
    974      * Up to here, the follwing holds.
    975      * If just one of the ppkey, ppubkey, pparams, and pcert function parameters
    976      * is nonzero, expect > 0 indicates which type of credential is expected.
    977      * If expect == 0, more than one of them is nonzero (multiple types expected).
    978      */
    979 
    980     if (pcerts != NULL) {
    981         if (*pcerts == NULL && (*pcerts = sk_X509_new_null()) == NULL) {
    982             if (!quiet)
    983                 BIO_printf(bio_err, "Out of memory loading");
    984             goto end;
    985         }
    986         /*
    987          * Adapt the 'expect' variable:
    988          * set to OSSL_STORE_INFO_CERT if no other type is expected so far,
    989          * otherwise set to 0 (indicating that multiple types are expected).
    990          */
    991         SET_EXPECT(OSSL_STORE_INFO_CERT);
    992     }
    993     SET_EXPECT1(pcrl, OSSL_STORE_INFO_CRL);
    994     if (pcrls != NULL) {
    995         if (*pcrls == NULL && (*pcrls = sk_X509_CRL_new_null()) == NULL) {
    996             if (!quiet)
    997                 BIO_printf(bio_err, "Out of memory loading");
    998             goto end;
    999         }
   1000         /*
   1001          * Adapt the 'expect' variable:
   1002          * set to OSSL_STORE_INFO_CRL if no other type is expected so far,
   1003          * otherwise set to 0 (indicating that multiple types are expected).
   1004          */
   1005         SET_EXPECT(OSSL_STORE_INFO_CRL);
   1006     }
   1007 
   1008     uidata.password = pass;
   1009     uidata.prompt_info = uri;
   1010 
   1011     if ((input_type = format2string(format)) != NULL) {
   1012         itp[0] = OSSL_PARAM_construct_utf8_string(OSSL_STORE_PARAM_INPUT_TYPE,
   1013                                                   (char *)input_type, 0);
   1014         itp[1] = OSSL_PARAM_construct_end();
   1015         params = itp;
   1016     }
   1017 
   1018     if (uri == NULL) {
   1019         BIO *bio;
   1020 
   1021         if (!maybe_stdin) {
   1022             if (!quiet)
   1023                 BIO_printf(bio_err, "No filename or uri specified for loading\n");
   1024             goto end;
   1025         }
   1026         uri = "<stdin>";
   1027         unbuffer(stdin);
   1028         bio = BIO_new_fp(stdin, 0);
   1029         if (bio != NULL) {
   1030             ctx = OSSL_STORE_attach(bio, "file", libctx, propq,
   1031                                     get_ui_method(), &uidata, params,
   1032                                     NULL, NULL);
   1033             BIO_free(bio);
   1034         }
   1035     } else {
   1036         ctx = OSSL_STORE_open_ex(uri, libctx, propq, get_ui_method(), &uidata,
   1037                                  params, NULL, NULL);
   1038     }
   1039     if (ctx == NULL) {
   1040         if (!quiet)
   1041             BIO_printf(bio_err, "Could not open file or uri for loading");
   1042         goto end;
   1043     }
   1044     /* expect == 0 means here multiple types of credentials are to be loaded */
   1045     if (expect > 0 && !OSSL_STORE_expect(ctx, expect)) {
   1046         if (!quiet)
   1047             BIO_printf(bio_err, "Internal error trying to load");
   1048         goto end;
   1049     }
   1050 
   1051     failed = NULL;
   1052     /* from here, failed != NULL only if actually an error has been detected */
   1053 
   1054     while ((ppkey != NULL || ppubkey != NULL || pparams != NULL
   1055             || pcert != NULL || pcerts != NULL || pcrl != NULL || pcrls != NULL)
   1056            && !OSSL_STORE_eof(ctx)) {
   1057         OSSL_STORE_INFO *info = OSSL_STORE_load(ctx);
   1058         int type, ok = 1;
   1059 
   1060         /*
   1061          * This can happen (for example) if we attempt to load a file with
   1062          * multiple different types of things in it - but the thing we just
   1063          * tried to load wasn't one of the ones we wanted, e.g. if we're trying
   1064          * to load a certificate but the file has both the private key and the
   1065          * certificate in it. We just retry until eof.
   1066          */
   1067         if (info == NULL) {
   1068             continue;
   1069         }
   1070 
   1071         type = OSSL_STORE_INFO_get_type(info);
   1072         switch (type) {
   1073         case OSSL_STORE_INFO_PKEY:
   1074             if (ppkey != NULL) {
   1075                 ok = (*ppkey = OSSL_STORE_INFO_get1_PKEY(info)) != NULL;
   1076                 if (ok)
   1077                     ppkey = NULL;
   1078                 break;
   1079             }
   1080             /*
   1081              * An EVP_PKEY with private parts also holds the public parts,
   1082              * so if the caller asked for a public key, and we got a private
   1083              * key, we can still pass it back.
   1084              */
   1085             /* fall through */
   1086         case OSSL_STORE_INFO_PUBKEY:
   1087             if (ppubkey != NULL) {
   1088                 ok = (*ppubkey = OSSL_STORE_INFO_get1_PUBKEY(info)) != NULL;
   1089                 if (ok)
   1090                     ppubkey = NULL;
   1091             }
   1092             break;
   1093         case OSSL_STORE_INFO_PARAMS:
   1094             if (pparams != NULL) {
   1095                 ok = (*pparams = OSSL_STORE_INFO_get1_PARAMS(info)) != NULL;
   1096                 if (ok)
   1097                     pparams = NULL;
   1098             }
   1099             break;
   1100         case OSSL_STORE_INFO_CERT:
   1101             if (pcert != NULL) {
   1102                 ok = (*pcert = OSSL_STORE_INFO_get1_CERT(info)) != NULL;
   1103                 if (ok)
   1104                     pcert = NULL;
   1105             } else if (pcerts != NULL) {
   1106                 ok = X509_add_cert(*pcerts,
   1107                                    OSSL_STORE_INFO_get1_CERT(info),
   1108                                    X509_ADD_FLAG_DEFAULT);
   1109             }
   1110             ncerts += ok;
   1111             break;
   1112         case OSSL_STORE_INFO_CRL:
   1113             if (pcrl != NULL) {
   1114                 ok = (*pcrl = OSSL_STORE_INFO_get1_CRL(info)) != NULL;
   1115                 if (ok)
   1116                     pcrl = NULL;
   1117             } else if (pcrls != NULL) {
   1118                 ok = sk_X509_CRL_push(*pcrls, OSSL_STORE_INFO_get1_CRL(info));
   1119             }
   1120             ncrls += ok;
   1121             break;
   1122         default:
   1123             /* skip any other type; ok stays == 1 */
   1124             break;
   1125         }
   1126         OSSL_STORE_INFO_free(info);
   1127         if (!ok) {
   1128             failed = OSSL_STORE_INFO_type_string(type);
   1129             if (!quiet)
   1130                 BIO_printf(bio_err, "Error reading");
   1131             break;
   1132         }
   1133     }
   1134 
   1135  end:
   1136     OSSL_STORE_close(ctx);
   1137 
   1138     /* see if any of the requested types of credentials was not found */
   1139     if (failed == NULL) {
   1140         if (ncerts > 0)
   1141             pcerts = NULL;
   1142         if (ncrls > 0)
   1143             pcrls = NULL;
   1144         failed = FAIL_NAME;
   1145         if (failed != NULL && !quiet)
   1146             BIO_printf(bio_err, "Could not find");
   1147     }
   1148 
   1149     if (failed != NULL && !quiet) {
   1150         unsigned long err = ERR_peek_last_error();
   1151 
   1152         /* continue the error message with the type of credential affected */
   1153         if (desc != NULL && strstr(desc, failed) != NULL) {
   1154             BIO_printf(bio_err, " %s", desc);
   1155         } else {
   1156             BIO_printf(bio_err, " %s", failed);
   1157             if (desc != NULL)
   1158                 BIO_printf(bio_err, " of %s", desc);
   1159         }
   1160         if (uri != NULL)
   1161             BIO_printf(bio_err, " from %s", uri);
   1162         if (ERR_SYSTEM_ERROR(err)) {
   1163             /* provide more readable diagnostic output */
   1164             BIO_printf(bio_err, ": %s", strerror(ERR_GET_REASON(err)));
   1165             ERR_pop_to_mark();
   1166             ERR_set_mark();
   1167         }
   1168         BIO_printf(bio_err, "\n");
   1169         ERR_print_errors(bio_err);
   1170     }
   1171     if (quiet || failed == NULL)
   1172         /* clear any suppressed or spurious errors */
   1173         ERR_pop_to_mark();
   1174     else
   1175         ERR_clear_last_mark();
   1176     return failed == NULL;
   1177 }
   1178 
   1179 #define X509V3_EXT_UNKNOWN_MASK  (0xfL << 16)
   1180 #define X509V3_EXT_DEFAULT       0          /* Return error for unknown exts */
   1181 #define X509V3_EXT_ERROR_UNKNOWN (1L << 16) /* Print error for unknown exts */
   1182 #define X509V3_EXT_PARSE_UNKNOWN (2L << 16) /* ASN1 parse unknown extensions */
   1183 #define X509V3_EXT_DUMP_UNKNOWN  (3L << 16) /* BIO_dump unknown extensions */
   1184 
   1185 #define X509_FLAG_CA (X509_FLAG_NO_ISSUER | X509_FLAG_NO_PUBKEY | \
   1186                       X509_FLAG_NO_HEADER | X509_FLAG_NO_VERSION)
   1187 
   1188 int set_cert_ex(unsigned long *flags, const char *arg)
   1189 {
   1190     static const NAME_EX_TBL cert_tbl[] = {
   1191         {"compatible", X509_FLAG_COMPAT, 0xffffffffl},
   1192         {"ca_default", X509_FLAG_CA, 0xffffffffl},
   1193         {"no_header", X509_FLAG_NO_HEADER, 0},
   1194         {"no_version", X509_FLAG_NO_VERSION, 0},
   1195         {"no_serial", X509_FLAG_NO_SERIAL, 0},
   1196         {"no_signame", X509_FLAG_NO_SIGNAME, 0},
   1197         {"no_validity", X509_FLAG_NO_VALIDITY, 0},
   1198         {"no_subject", X509_FLAG_NO_SUBJECT, 0},
   1199         {"no_issuer", X509_FLAG_NO_ISSUER, 0},
   1200         {"no_pubkey", X509_FLAG_NO_PUBKEY, 0},
   1201         {"no_extensions", X509_FLAG_NO_EXTENSIONS, 0},
   1202         {"no_sigdump", X509_FLAG_NO_SIGDUMP, 0},
   1203         {"no_aux", X509_FLAG_NO_AUX, 0},
   1204         {"no_attributes", X509_FLAG_NO_ATTRIBUTES, 0},
   1205         {"ext_default", X509V3_EXT_DEFAULT, X509V3_EXT_UNKNOWN_MASK},
   1206         {"ext_error", X509V3_EXT_ERROR_UNKNOWN, X509V3_EXT_UNKNOWN_MASK},
   1207         {"ext_parse", X509V3_EXT_PARSE_UNKNOWN, X509V3_EXT_UNKNOWN_MASK},
   1208         {"ext_dump", X509V3_EXT_DUMP_UNKNOWN, X509V3_EXT_UNKNOWN_MASK},
   1209         {NULL, 0, 0}
   1210     };
   1211     return set_multi_opts(flags, arg, cert_tbl);
   1212 }
   1213 
   1214 int set_name_ex(unsigned long *flags, const char *arg)
   1215 {
   1216     static const NAME_EX_TBL ex_tbl[] = {
   1217         {"esc_2253", ASN1_STRFLGS_ESC_2253, 0},
   1218         {"esc_2254", ASN1_STRFLGS_ESC_2254, 0},
   1219         {"esc_ctrl", ASN1_STRFLGS_ESC_CTRL, 0},
   1220         {"esc_msb", ASN1_STRFLGS_ESC_MSB, 0},
   1221         {"use_quote", ASN1_STRFLGS_ESC_QUOTE, 0},
   1222         {"utf8", ASN1_STRFLGS_UTF8_CONVERT, 0},
   1223         {"ignore_type", ASN1_STRFLGS_IGNORE_TYPE, 0},
   1224         {"show_type", ASN1_STRFLGS_SHOW_TYPE, 0},
   1225         {"dump_all", ASN1_STRFLGS_DUMP_ALL, 0},
   1226         {"dump_nostr", ASN1_STRFLGS_DUMP_UNKNOWN, 0},
   1227         {"dump_der", ASN1_STRFLGS_DUMP_DER, 0},
   1228         {"compat", XN_FLAG_COMPAT, 0xffffffffL},
   1229         {"sep_comma_plus", XN_FLAG_SEP_COMMA_PLUS, XN_FLAG_SEP_MASK},
   1230         {"sep_comma_plus_space", XN_FLAG_SEP_CPLUS_SPC, XN_FLAG_SEP_MASK},
   1231         {"sep_semi_plus_space", XN_FLAG_SEP_SPLUS_SPC, XN_FLAG_SEP_MASK},
   1232         {"sep_multiline", XN_FLAG_SEP_MULTILINE, XN_FLAG_SEP_MASK},
   1233         {"dn_rev", XN_FLAG_DN_REV, 0},
   1234         {"nofname", XN_FLAG_FN_NONE, XN_FLAG_FN_MASK},
   1235         {"sname", XN_FLAG_FN_SN, XN_FLAG_FN_MASK},
   1236         {"lname", XN_FLAG_FN_LN, XN_FLAG_FN_MASK},
   1237         {"align", XN_FLAG_FN_ALIGN, 0},
   1238         {"oid", XN_FLAG_FN_OID, XN_FLAG_FN_MASK},
   1239         {"space_eq", XN_FLAG_SPC_EQ, 0},
   1240         {"dump_unknown", XN_FLAG_DUMP_UNKNOWN_FIELDS, 0},
   1241         {"RFC2253", XN_FLAG_RFC2253, 0xffffffffL},
   1242         {"oneline", XN_FLAG_ONELINE, 0xffffffffL},
   1243         {"multiline", XN_FLAG_MULTILINE, 0xffffffffL},
   1244         {"ca_default", XN_FLAG_MULTILINE, 0xffffffffL},
   1245         {NULL, 0, 0}
   1246     };
   1247     if (set_multi_opts(flags, arg, ex_tbl) == 0)
   1248         return 0;
   1249     if (*flags != XN_FLAG_COMPAT
   1250         && (*flags & XN_FLAG_SEP_MASK) == 0)
   1251         *flags |= XN_FLAG_SEP_CPLUS_SPC;
   1252     return 1;
   1253 }
   1254 
   1255 int set_dateopt(unsigned long *dateopt, const char *arg)
   1256 {
   1257     if (OPENSSL_strcasecmp(arg, "rfc_822") == 0)
   1258         *dateopt = ASN1_DTFLGS_RFC822;
   1259     else if (OPENSSL_strcasecmp(arg, "iso_8601") == 0)
   1260         *dateopt = ASN1_DTFLGS_ISO8601;
   1261     else
   1262         return 0;
   1263     return 1;
   1264 }
   1265 
   1266 int set_ext_copy(int *copy_type, const char *arg)
   1267 {
   1268     if (OPENSSL_strcasecmp(arg, "none") == 0)
   1269         *copy_type = EXT_COPY_NONE;
   1270     else if (OPENSSL_strcasecmp(arg, "copy") == 0)
   1271         *copy_type = EXT_COPY_ADD;
   1272     else if (OPENSSL_strcasecmp(arg, "copyall") == 0)
   1273         *copy_type = EXT_COPY_ALL;
   1274     else
   1275         return 0;
   1276     return 1;
   1277 }
   1278 
   1279 int copy_extensions(X509 *x, X509_REQ *req, int copy_type)
   1280 {
   1281     STACK_OF(X509_EXTENSION) *exts;
   1282     int i, ret = 0;
   1283 
   1284     if (x == NULL || req == NULL)
   1285         return 0;
   1286     if (copy_type == EXT_COPY_NONE)
   1287         return 1;
   1288     exts = X509_REQ_get_extensions(req);
   1289 
   1290     for (i = 0; i < sk_X509_EXTENSION_num(exts); i++) {
   1291         X509_EXTENSION *ext = sk_X509_EXTENSION_value(exts, i);
   1292         ASN1_OBJECT *obj = X509_EXTENSION_get_object(ext);
   1293         int idx = X509_get_ext_by_OBJ(x, obj, -1);
   1294 
   1295         /* Does extension exist in target? */
   1296         if (idx != -1) {
   1297             /* If normal copy don't override existing extension */
   1298             if (copy_type == EXT_COPY_ADD)
   1299                 continue;
   1300             /* Delete all extensions of same type */
   1301             do {
   1302                 X509_EXTENSION_free(X509_delete_ext(x, idx));
   1303                 idx = X509_get_ext_by_OBJ(x, obj, -1);
   1304             } while (idx != -1);
   1305         }
   1306         if (!X509_add_ext(x, ext, -1))
   1307             goto end;
   1308     }
   1309     ret = 1;
   1310 
   1311  end:
   1312     sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free);
   1313     return ret;
   1314 }
   1315 
   1316 static int set_multi_opts(unsigned long *flags, const char *arg,
   1317                           const NAME_EX_TBL *in_tbl)
   1318 {
   1319     STACK_OF(CONF_VALUE) *vals;
   1320     CONF_VALUE *val;
   1321     int i, ret = 1;
   1322 
   1323     if (!arg)
   1324         return 0;
   1325     vals = X509V3_parse_list(arg);
   1326     for (i = 0; i < sk_CONF_VALUE_num(vals); i++) {
   1327         val = sk_CONF_VALUE_value(vals, i);
   1328         if (!set_table_opts(flags, val->name, in_tbl))
   1329             ret = 0;
   1330     }
   1331     sk_CONF_VALUE_pop_free(vals, X509V3_conf_free);
   1332     return ret;
   1333 }
   1334 
   1335 static int set_table_opts(unsigned long *flags, const char *arg,
   1336                           const NAME_EX_TBL *in_tbl)
   1337 {
   1338     char c;
   1339     const NAME_EX_TBL *ptbl;
   1340 
   1341     c = arg[0];
   1342     if (c == '-') {
   1343         c = 0;
   1344         arg++;
   1345     } else if (c == '+') {
   1346         c = 1;
   1347         arg++;
   1348     } else {
   1349         c = 1;
   1350     }
   1351 
   1352     for (ptbl = in_tbl; ptbl->name; ptbl++) {
   1353         if (OPENSSL_strcasecmp(arg, ptbl->name) == 0) {
   1354             *flags &= ~ptbl->mask;
   1355             if (c)
   1356                 *flags |= ptbl->flag;
   1357             else
   1358                 *flags &= ~ptbl->flag;
   1359             return 1;
   1360         }
   1361     }
   1362     return 0;
   1363 }
   1364 
   1365 void print_name(BIO *out, const char *title, const X509_NAME *nm)
   1366 {
   1367     char *buf;
   1368     char mline = 0;
   1369     int indent = 0;
   1370     unsigned long lflags = get_nameopt();
   1371 
   1372     if (out == NULL)
   1373         return;
   1374     if (title != NULL)
   1375         BIO_puts(out, title);
   1376     if ((lflags & XN_FLAG_SEP_MASK) == XN_FLAG_SEP_MULTILINE) {
   1377         mline = 1;
   1378         indent = 4;
   1379     }
   1380     if (lflags == XN_FLAG_COMPAT) {
   1381         buf = X509_NAME_oneline(nm, 0, 0);
   1382         BIO_puts(out, buf);
   1383         BIO_puts(out, "\n");
   1384         OPENSSL_free(buf);
   1385     } else {
   1386         if (mline)
   1387             BIO_puts(out, "\n");
   1388         X509_NAME_print_ex(out, nm, indent, lflags);
   1389         BIO_puts(out, "\n");
   1390     }
   1391 }
   1392 
   1393 void print_bignum_var(BIO *out, const BIGNUM *in, const char *var,
   1394                       int len, unsigned char *buffer)
   1395 {
   1396     BIO_printf(out, "    static unsigned char %s_%d[] = {", var, len);
   1397     if (BN_is_zero(in)) {
   1398         BIO_printf(out, "\n        0x00");
   1399     } else {
   1400         int i, l;
   1401 
   1402         l = BN_bn2bin(in, buffer);
   1403         for (i = 0; i < l; i++) {
   1404             BIO_printf(out, (i % 10) == 0 ? "\n        " : " ");
   1405             if (i < l - 1)
   1406                 BIO_printf(out, "0x%02X,", buffer[i]);
   1407             else
   1408                 BIO_printf(out, "0x%02X", buffer[i]);
   1409         }
   1410     }
   1411     BIO_printf(out, "\n    };\n");
   1412 }
   1413 
   1414 void print_array(BIO *out, const char *title, int len, const unsigned char *d)
   1415 {
   1416     int i;
   1417 
   1418     BIO_printf(out, "unsigned char %s[%d] = {", title, len);
   1419     for (i = 0; i < len; i++) {
   1420         if ((i % 10) == 0)
   1421             BIO_printf(out, "\n    ");
   1422         if (i < len - 1)
   1423             BIO_printf(out, "0x%02X, ", d[i]);
   1424         else
   1425             BIO_printf(out, "0x%02X", d[i]);
   1426     }
   1427     BIO_printf(out, "\n};\n");
   1428 }
   1429 
   1430 X509_STORE *setup_verify(const char *CAfile, int noCAfile,
   1431                          const char *CApath, int noCApath,
   1432                          const char *CAstore, int noCAstore)
   1433 {
   1434     X509_STORE *store = X509_STORE_new();
   1435     X509_LOOKUP *lookup;
   1436     OSSL_LIB_CTX *libctx = app_get0_libctx();
   1437     const char *propq = app_get0_propq();
   1438 
   1439     if (store == NULL)
   1440         goto end;
   1441 
   1442     if (CAfile != NULL || !noCAfile) {
   1443         lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file());
   1444         if (lookup == NULL)
   1445             goto end;
   1446         if (CAfile != NULL) {
   1447             if (X509_LOOKUP_load_file_ex(lookup, CAfile, X509_FILETYPE_PEM,
   1448                                          libctx, propq) <= 0) {
   1449                 ERR_clear_error();
   1450                 if (X509_LOOKUP_load_file_ex(lookup, CAfile, X509_FILETYPE_ASN1,
   1451                                              libctx, propq) <= 0) {
   1452                     BIO_printf(bio_err, "Error loading file %s\n", CAfile);
   1453                     goto end;
   1454                 }
   1455             }
   1456         } else {
   1457             X509_LOOKUP_load_file_ex(lookup, NULL, X509_FILETYPE_DEFAULT,
   1458                                      libctx, propq);
   1459         }
   1460     }
   1461 
   1462     if (CApath != NULL || !noCApath) {
   1463         lookup = X509_STORE_add_lookup(store, X509_LOOKUP_hash_dir());
   1464         if (lookup == NULL)
   1465             goto end;
   1466         if (CApath != NULL) {
   1467             if (X509_LOOKUP_add_dir(lookup, CApath, X509_FILETYPE_PEM) <= 0) {
   1468                 BIO_printf(bio_err, "Error loading directory %s\n", CApath);
   1469                 goto end;
   1470             }
   1471         } else {
   1472             X509_LOOKUP_add_dir(lookup, NULL, X509_FILETYPE_DEFAULT);
   1473         }
   1474     }
   1475 
   1476     if (CAstore != NULL || !noCAstore) {
   1477         lookup = X509_STORE_add_lookup(store, X509_LOOKUP_store());
   1478         if (lookup == NULL)
   1479             goto end;
   1480         if (!X509_LOOKUP_add_store_ex(lookup, CAstore, libctx, propq)) {
   1481             if (CAstore != NULL)
   1482                 BIO_printf(bio_err, "Error loading store URI %s\n", CAstore);
   1483             goto end;
   1484         }
   1485     }
   1486 
   1487     ERR_clear_error();
   1488     return store;
   1489  end:
   1490     ERR_print_errors(bio_err);
   1491     X509_STORE_free(store);
   1492     return NULL;
   1493 }
   1494 
   1495 static unsigned long index_serial_hash(const OPENSSL_CSTRING *a)
   1496 {
   1497     const char *n;
   1498 
   1499     n = a[DB_serial];
   1500     while (*n == '0')
   1501         n++;
   1502     return OPENSSL_LH_strhash(n);
   1503 }
   1504 
   1505 static int index_serial_cmp(const OPENSSL_CSTRING *a,
   1506                             const OPENSSL_CSTRING *b)
   1507 {
   1508     const char *aa, *bb;
   1509 
   1510     for (aa = a[DB_serial]; *aa == '0'; aa++) ;
   1511     for (bb = b[DB_serial]; *bb == '0'; bb++) ;
   1512     return strcmp(aa, bb);
   1513 }
   1514 
   1515 static int index_name_qual(char **a)
   1516 {
   1517     return (a[0][0] == 'V');
   1518 }
   1519 
   1520 static unsigned long index_name_hash(const OPENSSL_CSTRING *a)
   1521 {
   1522     return OPENSSL_LH_strhash(a[DB_name]);
   1523 }
   1524 
   1525 int index_name_cmp(const OPENSSL_CSTRING *a, const OPENSSL_CSTRING *b)
   1526 {
   1527     return strcmp(a[DB_name], b[DB_name]);
   1528 }
   1529 
   1530 static IMPLEMENT_LHASH_HASH_FN(index_serial, OPENSSL_CSTRING)
   1531 static IMPLEMENT_LHASH_COMP_FN(index_serial, OPENSSL_CSTRING)
   1532 static IMPLEMENT_LHASH_HASH_FN(index_name, OPENSSL_CSTRING)
   1533 static IMPLEMENT_LHASH_COMP_FN(index_name, OPENSSL_CSTRING)
   1534 #undef BSIZE
   1535 #define BSIZE 256
   1536 BIGNUM *load_serial(const char *serialfile, int *exists, int create,
   1537                     ASN1_INTEGER **retai)
   1538 {
   1539     BIO *in = NULL;
   1540     BIGNUM *ret = NULL;
   1541     char buf[1024];
   1542     ASN1_INTEGER *ai = NULL;
   1543 
   1544     ai = ASN1_INTEGER_new();
   1545     if (ai == NULL)
   1546         goto err;
   1547 
   1548     in = BIO_new_file(serialfile, "r");
   1549     if (exists != NULL)
   1550         *exists = in != NULL;
   1551     if (in == NULL) {
   1552         if (!create) {
   1553             perror(serialfile);
   1554             goto err;
   1555         }
   1556         ERR_clear_error();
   1557         ret = BN_new();
   1558         if (ret == NULL) {
   1559             BIO_printf(bio_err, "Out of memory\n");
   1560         } else if (!rand_serial(ret, ai)) {
   1561             BIO_printf(bio_err, "Error creating random number to store in %s\n",
   1562                        serialfile);
   1563             BN_free(ret);
   1564             ret = NULL;
   1565         }
   1566     } else {
   1567         if (!a2i_ASN1_INTEGER(in, ai, buf, 1024)) {
   1568             BIO_printf(bio_err, "Unable to load number from %s\n",
   1569                        serialfile);
   1570             goto err;
   1571         }
   1572         ret = ASN1_INTEGER_to_BN(ai, NULL);
   1573         if (ret == NULL) {
   1574             BIO_printf(bio_err, "Error converting number from bin to BIGNUM\n");
   1575             goto err;
   1576         }
   1577     }
   1578 
   1579     if (ret != NULL && retai != NULL) {
   1580         *retai = ai;
   1581         ai = NULL;
   1582     }
   1583  err:
   1584     if (ret == NULL)
   1585         ERR_print_errors(bio_err);
   1586     BIO_free(in);
   1587     ASN1_INTEGER_free(ai);
   1588     return ret;
   1589 }
   1590 
   1591 int save_serial(const char *serialfile, const char *suffix,
   1592                 const BIGNUM *serial, ASN1_INTEGER **retai)
   1593 {
   1594     char buf[1][BSIZE];
   1595     BIO *out = NULL;
   1596     int ret = 0;
   1597     ASN1_INTEGER *ai = NULL;
   1598     int j;
   1599 
   1600     if (suffix == NULL)
   1601         j = strlen(serialfile);
   1602     else
   1603         j = strlen(serialfile) + strlen(suffix) + 1;
   1604     if (j >= BSIZE) {
   1605         BIO_printf(bio_err, "File name too long\n");
   1606         goto err;
   1607     }
   1608 
   1609     if (suffix == NULL) {
   1610         OPENSSL_strlcpy(buf[0], serialfile, BSIZE);
   1611     } else {
   1612 #ifndef OPENSSL_SYS_VMS
   1613         BIO_snprintf(buf[0], sizeof(buf[0]), "%s.%s", serialfile, suffix);
   1614 #else
   1615         BIO_snprintf(buf[0], sizeof(buf[0]), "%s-%s", serialfile, suffix);
   1616 #endif
   1617     }
   1618     out = BIO_new_file(buf[0], "w");
   1619     if (out == NULL) {
   1620         goto err;
   1621     }
   1622 
   1623     if ((ai = BN_to_ASN1_INTEGER(serial, NULL)) == NULL) {
   1624         BIO_printf(bio_err, "error converting serial to ASN.1 format\n");
   1625         goto err;
   1626     }
   1627     i2a_ASN1_INTEGER(out, ai);
   1628     BIO_puts(out, "\n");
   1629     ret = 1;
   1630     if (retai) {
   1631         *retai = ai;
   1632         ai = NULL;
   1633     }
   1634  err:
   1635     if (!ret)
   1636         ERR_print_errors(bio_err);
   1637     BIO_free_all(out);
   1638     ASN1_INTEGER_free(ai);
   1639     return ret;
   1640 }
   1641 
   1642 int rotate_serial(const char *serialfile, const char *new_suffix,
   1643                   const char *old_suffix)
   1644 {
   1645     char buf[2][BSIZE];
   1646     int i, j;
   1647 
   1648     i = strlen(serialfile) + strlen(old_suffix);
   1649     j = strlen(serialfile) + strlen(new_suffix);
   1650     if (i > j)
   1651         j = i;
   1652     if (j + 1 >= BSIZE) {
   1653         BIO_printf(bio_err, "File name too long\n");
   1654         goto err;
   1655     }
   1656 #ifndef OPENSSL_SYS_VMS
   1657     BIO_snprintf(buf[0], sizeof(buf[0]), "%s.%s", serialfile, new_suffix);
   1658     BIO_snprintf(buf[1], sizeof(buf[1]), "%s.%s", serialfile, old_suffix);
   1659 #else
   1660     BIO_snprintf(buf[0], sizeof(buf[0]), "%s-%s", serialfile, new_suffix);
   1661     BIO_snprintf(buf[1], sizeof(buf[1]), "%s-%s", serialfile, old_suffix);
   1662 #endif
   1663     if (rename(serialfile, buf[1]) < 0 && errno != ENOENT
   1664 #ifdef ENOTDIR
   1665         && errno != ENOTDIR
   1666 #endif
   1667         ) {
   1668         BIO_printf(bio_err,
   1669                    "Unable to rename %s to %s\n", serialfile, buf[1]);
   1670         perror("reason");
   1671         goto err;
   1672     }
   1673     if (rename(buf[0], serialfile) < 0) {
   1674         BIO_printf(bio_err,
   1675                    "Unable to rename %s to %s\n", buf[0], serialfile);
   1676         perror("reason");
   1677         rename(buf[1], serialfile);
   1678         goto err;
   1679     }
   1680     return 1;
   1681  err:
   1682     ERR_print_errors(bio_err);
   1683     return 0;
   1684 }
   1685 
   1686 int rand_serial(BIGNUM *b, ASN1_INTEGER *ai)
   1687 {
   1688     BIGNUM *btmp;
   1689     int ret = 0;
   1690 
   1691     btmp = b == NULL ? BN_new() : b;
   1692     if (btmp == NULL)
   1693         return 0;
   1694 
   1695     if (!BN_rand(btmp, SERIAL_RAND_BITS, BN_RAND_TOP_ANY, BN_RAND_BOTTOM_ANY))
   1696         goto error;
   1697     if (ai && !BN_to_ASN1_INTEGER(btmp, ai))
   1698         goto error;
   1699 
   1700     ret = 1;
   1701 
   1702  error:
   1703 
   1704     if (btmp != b)
   1705         BN_free(btmp);
   1706 
   1707     return ret;
   1708 }
   1709 
   1710 CA_DB *load_index(const char *dbfile, DB_ATTR *db_attr)
   1711 {
   1712     CA_DB *retdb = NULL;
   1713     TXT_DB *tmpdb = NULL;
   1714     BIO *in;
   1715     CONF *dbattr_conf = NULL;
   1716     char buf[BSIZE];
   1717 #ifndef OPENSSL_NO_POSIX_IO
   1718     FILE *dbfp;
   1719     struct stat dbst;
   1720 #endif
   1721 
   1722     in = BIO_new_file(dbfile, "r");
   1723     if (in == NULL)
   1724         goto err;
   1725 
   1726 #ifndef OPENSSL_NO_POSIX_IO
   1727     BIO_get_fp(in, &dbfp);
   1728     if (fstat(fileno(dbfp), &dbst) == -1) {
   1729         ERR_raise_data(ERR_LIB_SYS, errno,
   1730                        "calling fstat(%s)", dbfile);
   1731         goto err;
   1732     }
   1733 #endif
   1734 
   1735     if ((tmpdb = TXT_DB_read(in, DB_NUMBER)) == NULL)
   1736         goto err;
   1737 
   1738 #ifndef OPENSSL_SYS_VMS
   1739     BIO_snprintf(buf, sizeof(buf), "%s.attr", dbfile);
   1740 #else
   1741     BIO_snprintf(buf, sizeof(buf), "%s-attr", dbfile);
   1742 #endif
   1743     dbattr_conf = app_load_config_quiet(buf);
   1744 
   1745     retdb = app_malloc(sizeof(*retdb), "new DB");
   1746     retdb->db = tmpdb;
   1747     tmpdb = NULL;
   1748     if (db_attr)
   1749         retdb->attributes = *db_attr;
   1750     else
   1751         retdb->attributes.unique_subject = 1;
   1752 
   1753     if (dbattr_conf != NULL) {
   1754         char *p = app_conf_try_string(dbattr_conf, NULL, "unique_subject");
   1755 
   1756         if (p != NULL)
   1757             retdb->attributes.unique_subject = parse_yesno(p, 1);
   1758     }
   1759 
   1760     retdb->dbfname = OPENSSL_strdup(dbfile);
   1761     if (retdb->dbfname == NULL)
   1762         goto err;
   1763 
   1764 #ifndef OPENSSL_NO_POSIX_IO
   1765     retdb->dbst = dbst;
   1766 #endif
   1767 
   1768  err:
   1769     ERR_print_errors(bio_err);
   1770     NCONF_free(dbattr_conf);
   1771     TXT_DB_free(tmpdb);
   1772     BIO_free_all(in);
   1773     return retdb;
   1774 }
   1775 
   1776 /*
   1777  * Returns > 0 on success, <= 0 on error
   1778  */
   1779 int index_index(CA_DB *db)
   1780 {
   1781     if (!TXT_DB_create_index(db->db, DB_serial, NULL,
   1782                              LHASH_HASH_FN(index_serial),
   1783                              LHASH_COMP_FN(index_serial))) {
   1784         BIO_printf(bio_err,
   1785                    "Error creating serial number index:(%ld,%ld,%ld)\n",
   1786                    db->db->error, db->db->arg1, db->db->arg2);
   1787         goto err;
   1788     }
   1789 
   1790     if (db->attributes.unique_subject
   1791         && !TXT_DB_create_index(db->db, DB_name, index_name_qual,
   1792                                 LHASH_HASH_FN(index_name),
   1793                                 LHASH_COMP_FN(index_name))) {
   1794         BIO_printf(bio_err, "Error creating name index:(%ld,%ld,%ld)\n",
   1795                    db->db->error, db->db->arg1, db->db->arg2);
   1796         goto err;
   1797     }
   1798     return 1;
   1799  err:
   1800     ERR_print_errors(bio_err);
   1801     return 0;
   1802 }
   1803 
   1804 int save_index(const char *dbfile, const char *suffix, CA_DB *db)
   1805 {
   1806     char buf[3][BSIZE];
   1807     BIO *out;
   1808     int j;
   1809 
   1810     j = strlen(dbfile) + strlen(suffix);
   1811     if (j + 6 >= BSIZE) {
   1812         BIO_printf(bio_err, "File name too long\n");
   1813         goto err;
   1814     }
   1815 #ifndef OPENSSL_SYS_VMS
   1816     BIO_snprintf(buf[2], sizeof(buf[2]), "%s.attr", dbfile);
   1817     BIO_snprintf(buf[1], sizeof(buf[1]), "%s.attr.%s", dbfile, suffix);
   1818     BIO_snprintf(buf[0], sizeof(buf[0]), "%s.%s", dbfile, suffix);
   1819 #else
   1820     BIO_snprintf(buf[2], sizeof(buf[2]), "%s-attr", dbfile);
   1821     BIO_snprintf(buf[1], sizeof(buf[1]), "%s-attr-%s", dbfile, suffix);
   1822     BIO_snprintf(buf[0], sizeof(buf[0]), "%s-%s", dbfile, suffix);
   1823 #endif
   1824     out = BIO_new_file(buf[0], "w");
   1825     if (out == NULL) {
   1826         perror(dbfile);
   1827         BIO_printf(bio_err, "Unable to open '%s'\n", dbfile);
   1828         goto err;
   1829     }
   1830     j = TXT_DB_write(out, db->db);
   1831     BIO_free(out);
   1832     if (j <= 0)
   1833         goto err;
   1834 
   1835     out = BIO_new_file(buf[1], "w");
   1836     if (out == NULL) {
   1837         perror(buf[2]);
   1838         BIO_printf(bio_err, "Unable to open '%s'\n", buf[2]);
   1839         goto err;
   1840     }
   1841     BIO_printf(out, "unique_subject = %s\n",
   1842                db->attributes.unique_subject ? "yes" : "no");
   1843     BIO_free(out);
   1844 
   1845     return 1;
   1846  err:
   1847     ERR_print_errors(bio_err);
   1848     return 0;
   1849 }
   1850 
   1851 int rotate_index(const char *dbfile, const char *new_suffix,
   1852                  const char *old_suffix)
   1853 {
   1854     char buf[5][BSIZE];
   1855     int i, j;
   1856 
   1857     i = strlen(dbfile) + strlen(old_suffix);
   1858     j = strlen(dbfile) + strlen(new_suffix);
   1859     if (i > j)
   1860         j = i;
   1861     if (j + 6 >= BSIZE) {
   1862         BIO_printf(bio_err, "File name too long\n");
   1863         goto err;
   1864     }
   1865 #ifndef OPENSSL_SYS_VMS
   1866     BIO_snprintf(buf[4], sizeof(buf[4]), "%s.attr", dbfile);
   1867     BIO_snprintf(buf[3], sizeof(buf[3]), "%s.attr.%s", dbfile, old_suffix);
   1868     BIO_snprintf(buf[2], sizeof(buf[2]), "%s.attr.%s", dbfile, new_suffix);
   1869     BIO_snprintf(buf[1], sizeof(buf[1]), "%s.%s", dbfile, old_suffix);
   1870     BIO_snprintf(buf[0], sizeof(buf[0]), "%s.%s", dbfile, new_suffix);
   1871 #else
   1872     BIO_snprintf(buf[4], sizeof(buf[4]), "%s-attr", dbfile);
   1873     BIO_snprintf(buf[3], sizeof(buf[3]), "%s-attr-%s", dbfile, old_suffix);
   1874     BIO_snprintf(buf[2], sizeof(buf[2]), "%s-attr-%s", dbfile, new_suffix);
   1875     BIO_snprintf(buf[1], sizeof(buf[1]), "%s-%s", dbfile, old_suffix);
   1876     BIO_snprintf(buf[0], sizeof(buf[0]), "%s-%s", dbfile, new_suffix);
   1877 #endif
   1878     if (rename(dbfile, buf[1]) < 0 && errno != ENOENT
   1879 #ifdef ENOTDIR
   1880         && errno != ENOTDIR
   1881 #endif
   1882         ) {
   1883         BIO_printf(bio_err, "Unable to rename %s to %s\n", dbfile, buf[1]);
   1884         perror("reason");
   1885         goto err;
   1886     }
   1887     if (rename(buf[0], dbfile) < 0) {
   1888         BIO_printf(bio_err, "Unable to rename %s to %s\n", buf[0], dbfile);
   1889         perror("reason");
   1890         rename(buf[1], dbfile);
   1891         goto err;
   1892     }
   1893     if (rename(buf[4], buf[3]) < 0 && errno != ENOENT
   1894 #ifdef ENOTDIR
   1895         && errno != ENOTDIR
   1896 #endif
   1897         ) {
   1898         BIO_printf(bio_err, "Unable to rename %s to %s\n", buf[4], buf[3]);
   1899         perror("reason");
   1900         rename(dbfile, buf[0]);
   1901         rename(buf[1], dbfile);
   1902         goto err;
   1903     }
   1904     if (rename(buf[2], buf[4]) < 0) {
   1905         BIO_printf(bio_err, "Unable to rename %s to %s\n", buf[2], buf[4]);
   1906         perror("reason");
   1907         rename(buf[3], buf[4]);
   1908         rename(dbfile, buf[0]);
   1909         rename(buf[1], dbfile);
   1910         goto err;
   1911     }
   1912     return 1;
   1913  err:
   1914     ERR_print_errors(bio_err);
   1915     return 0;
   1916 }
   1917 
   1918 void free_index(CA_DB *db)
   1919 {
   1920     if (db) {
   1921         TXT_DB_free(db->db);
   1922         OPENSSL_free(db->dbfname);
   1923         OPENSSL_free(db);
   1924     }
   1925 }
   1926 
   1927 int parse_yesno(const char *str, int def)
   1928 {
   1929     if (str) {
   1930         switch (*str) {
   1931         case 'f':              /* false */
   1932         case 'F':              /* FALSE */
   1933         case 'n':              /* no */
   1934         case 'N':              /* NO */
   1935         case '0':              /* 0 */
   1936             return 0;
   1937         case 't':              /* true */
   1938         case 'T':              /* TRUE */
   1939         case 'y':              /* yes */
   1940         case 'Y':              /* YES */
   1941         case '1':              /* 1 */
   1942             return 1;
   1943         }
   1944     }
   1945     return def;
   1946 }
   1947 
   1948 /*
   1949  * name is expected to be in the format /type0=value0/type1=value1/type2=...
   1950  * where + can be used instead of / to form multi-valued RDNs if canmulti
   1951  * and characters may be escaped by \
   1952  */
   1953 X509_NAME *parse_name(const char *cp, int chtype, int canmulti,
   1954                       const char *desc)
   1955 {
   1956     int nextismulti = 0;
   1957     char *work;
   1958     X509_NAME *n;
   1959 
   1960     if (*cp++ != '/') {
   1961         BIO_printf(bio_err,
   1962                    "%s: %s name is expected to be in the format "
   1963                    "/type0=value0/type1=value1/type2=... where characters may "
   1964                    "be escaped by \\. This name is not in that format: '%s'\n",
   1965                    opt_getprog(), desc, --cp);
   1966         return NULL;
   1967     }
   1968 
   1969     n = X509_NAME_new();
   1970     if (n == NULL) {
   1971         BIO_printf(bio_err, "%s: Out of memory\n", opt_getprog());
   1972         return NULL;
   1973     }
   1974     work = OPENSSL_strdup(cp);
   1975     if (work == NULL) {
   1976         BIO_printf(bio_err, "%s: Error copying %s name input\n",
   1977                    opt_getprog(), desc);
   1978         goto err;
   1979     }
   1980 
   1981     while (*cp != '\0') {
   1982         char *bp = work;
   1983         char *typestr = bp;
   1984         unsigned char *valstr;
   1985         int nid;
   1986         int ismulti = nextismulti;
   1987 
   1988         nextismulti = 0;
   1989 
   1990         /* Collect the type */
   1991         while (*cp != '\0' && *cp != '=')
   1992             *bp++ = *cp++;
   1993         *bp++ = '\0';
   1994         if (*cp == '\0') {
   1995             BIO_printf(bio_err,
   1996                        "%s: Missing '=' after RDN type string '%s' in %s name string\n",
   1997                        opt_getprog(), typestr, desc);
   1998             goto err;
   1999         }
   2000         ++cp;
   2001 
   2002         /* Collect the value. */
   2003         valstr = (unsigned char *)bp;
   2004         for (; *cp != '\0' && *cp != '/'; *bp++ = *cp++) {
   2005             /* unescaped '+' symbol string signals further member of multiRDN */
   2006             if (canmulti && *cp == '+') {
   2007                 nextismulti = 1;
   2008                 break;
   2009             }
   2010             if (*cp == '\\' && *++cp == '\0') {
   2011                 BIO_printf(bio_err,
   2012                            "%s: Escape character at end of %s name string\n",
   2013                            opt_getprog(), desc);
   2014                 goto err;
   2015             }
   2016         }
   2017         *bp++ = '\0';
   2018 
   2019         /* If not at EOS (must be + or /), move forward. */
   2020         if (*cp != '\0')
   2021             ++cp;
   2022 
   2023         /* Parse */
   2024         nid = OBJ_txt2nid(typestr);
   2025         if (nid == NID_undef) {
   2026             BIO_printf(bio_err,
   2027                        "%s warning: Skipping unknown %s name attribute \"%s\"\n",
   2028                        opt_getprog(), desc, typestr);
   2029             if (ismulti)
   2030                 BIO_printf(bio_err,
   2031                            "%s hint: a '+' in a value string needs be escaped using '\\' else a new member of a multi-valued RDN is expected\n",
   2032                            opt_getprog());
   2033             continue;
   2034         }
   2035         if (*valstr == '\0') {
   2036             BIO_printf(bio_err,
   2037                        "%s warning: No value provided for %s name attribute \"%s\", skipped\n",
   2038                        opt_getprog(), desc, typestr);
   2039             continue;
   2040         }
   2041         if (!X509_NAME_add_entry_by_NID(n, nid, chtype,
   2042                                         valstr, strlen((char *)valstr),
   2043                                         -1, ismulti ? -1 : 0)) {
   2044             ERR_print_errors(bio_err);
   2045             BIO_printf(bio_err,
   2046                        "%s: Error adding %s name attribute \"/%s=%s\"\n",
   2047                        opt_getprog(), desc, typestr, valstr);
   2048             goto err;
   2049         }
   2050     }
   2051 
   2052     OPENSSL_free(work);
   2053     return n;
   2054 
   2055  err:
   2056     X509_NAME_free(n);
   2057     OPENSSL_free(work);
   2058     return NULL;
   2059 }
   2060 
   2061 /*
   2062  * Read whole contents of a BIO into an allocated memory buffer and return
   2063  * it.
   2064  */
   2065 
   2066 int bio_to_mem(unsigned char **out, int maxlen, BIO *in)
   2067 {
   2068     BIO *mem;
   2069     int len, ret;
   2070     unsigned char tbuf[1024];
   2071 
   2072     mem = BIO_new(BIO_s_mem());
   2073     if (mem == NULL)
   2074         return -1;
   2075     for (;;) {
   2076         if ((maxlen != -1) && maxlen < 1024)
   2077             len = maxlen;
   2078         else
   2079             len = 1024;
   2080         len = BIO_read(in, tbuf, len);
   2081         if (len < 0) {
   2082             BIO_free(mem);
   2083             return -1;
   2084         }
   2085         if (len == 0)
   2086             break;
   2087         if (BIO_write(mem, tbuf, len) != len) {
   2088             BIO_free(mem);
   2089             return -1;
   2090         }
   2091         if (maxlen != -1)
   2092             maxlen -= len;
   2093 
   2094         if (maxlen == 0)
   2095             break;
   2096     }
   2097     ret = BIO_get_mem_data(mem, (char **)out);
   2098     BIO_set_flags(mem, BIO_FLAGS_MEM_RDONLY);
   2099     BIO_free(mem);
   2100     return ret;
   2101 }
   2102 
   2103 int pkey_ctrl_string(EVP_PKEY_CTX *ctx, const char *value)
   2104 {
   2105     int rv = 0;
   2106     char *stmp, *vtmp = NULL;
   2107 
   2108     stmp = OPENSSL_strdup(value);
   2109     if (stmp == NULL)
   2110         return -1;
   2111     vtmp = strchr(stmp, ':');
   2112     if (vtmp == NULL)
   2113         goto err;
   2114 
   2115     *vtmp = 0;
   2116     vtmp++;
   2117     rv = EVP_PKEY_CTX_ctrl_str(ctx, stmp, vtmp);
   2118 
   2119  err:
   2120     OPENSSL_free(stmp);
   2121     return rv;
   2122 }
   2123 
   2124 static void nodes_print(const char *name, STACK_OF(X509_POLICY_NODE) *nodes)
   2125 {
   2126     X509_POLICY_NODE *node;
   2127     int i;
   2128 
   2129     BIO_printf(bio_err, "%s Policies:", name);
   2130     if (nodes) {
   2131         BIO_puts(bio_err, "\n");
   2132         for (i = 0; i < sk_X509_POLICY_NODE_num(nodes); i++) {
   2133             node = sk_X509_POLICY_NODE_value(nodes, i);
   2134             X509_POLICY_NODE_print(bio_err, node, 2);
   2135         }
   2136     } else {
   2137         BIO_puts(bio_err, " <empty>\n");
   2138     }
   2139 }
   2140 
   2141 void policies_print(X509_STORE_CTX *ctx)
   2142 {
   2143     X509_POLICY_TREE *tree;
   2144     int explicit_policy;
   2145 
   2146     tree = X509_STORE_CTX_get0_policy_tree(ctx);
   2147     explicit_policy = X509_STORE_CTX_get_explicit_policy(ctx);
   2148 
   2149     BIO_printf(bio_err, "Require explicit Policy: %s\n",
   2150                explicit_policy ? "True" : "False");
   2151 
   2152     nodes_print("Authority", X509_policy_tree_get0_policies(tree));
   2153     nodes_print("User", X509_policy_tree_get0_user_policies(tree));
   2154 }
   2155 
   2156 /*-
   2157  * next_protos_parse parses a comma separated list of strings into a string
   2158  * in a format suitable for passing to SSL_CTX_set_next_protos_advertised.
   2159  *   outlen: (output) set to the length of the resulting buffer on success.
   2160  *   err: (maybe NULL) on failure, an error message line is written to this BIO.
   2161  *   in: a NUL terminated string like "abc,def,ghi"
   2162  *
   2163  *   returns: a malloc'd buffer or NULL on failure.
   2164  */
   2165 unsigned char *next_protos_parse(size_t *outlen, const char *in)
   2166 {
   2167     size_t len;
   2168     unsigned char *out;
   2169     size_t i, start = 0;
   2170     size_t skipped = 0;
   2171 
   2172     len = strlen(in);
   2173     if (len == 0 || len >= 65535)
   2174         return NULL;
   2175 
   2176     out = app_malloc(len + 1, "NPN buffer");
   2177     for (i = 0; i <= len; ++i) {
   2178         if (i == len || in[i] == ',') {
   2179             /*
   2180              * Zero-length ALPN elements are invalid on the wire, we could be
   2181              * strict and reject the entire string, but just ignoring extra
   2182              * commas seems harmless and more friendly.
   2183              *
   2184              * Every comma we skip in this way puts the input buffer another
   2185              * byte ahead of the output buffer, so all stores into the output
   2186              * buffer need to be decremented by the number commas skipped.
   2187              */
   2188             if (i == start) {
   2189                 ++start;
   2190                 ++skipped;
   2191                 continue;
   2192             }
   2193             if (i - start > 255) {
   2194                 OPENSSL_free(out);
   2195                 return NULL;
   2196             }
   2197             out[start - skipped] = (unsigned char)(i - start);
   2198             start = i + 1;
   2199         } else {
   2200             out[i + 1 - skipped] = in[i];
   2201         }
   2202     }
   2203 
   2204     if (len <= skipped) {
   2205         OPENSSL_free(out);
   2206         return NULL;
   2207     }
   2208 
   2209     *outlen = len + 1 - skipped;
   2210     return out;
   2211 }
   2212 
   2213 int check_cert_attributes(BIO *bio, X509 *x, const char *checkhost,
   2214                           const char *checkemail, const char *checkip,
   2215                           int print)
   2216 {
   2217     int valid_host = 0;
   2218     int valid_mail = 0;
   2219     int valid_ip = 0;
   2220     int ret = 1;
   2221 
   2222     if (x == NULL)
   2223         return 0;
   2224 
   2225     if (checkhost != NULL) {
   2226         valid_host = X509_check_host(x, checkhost, 0, 0, NULL);
   2227         if (print)
   2228             BIO_printf(bio, "Hostname %s does%s match certificate\n",
   2229                        checkhost, valid_host == 1 ? "" : " NOT");
   2230         ret = ret && valid_host > 0;
   2231     }
   2232 
   2233     if (checkemail != NULL) {
   2234         valid_mail = X509_check_email(x, checkemail, 0, 0);
   2235         if (print)
   2236             BIO_printf(bio, "Email %s does%s match certificate\n",
   2237                        checkemail, valid_mail ? "" : " NOT");
   2238         ret = ret && valid_mail > 0;
   2239     }
   2240 
   2241     if (checkip != NULL) {
   2242         valid_ip = X509_check_ip_asc(x, checkip, 0);
   2243         if (print)
   2244             BIO_printf(bio, "IP %s does%s match certificate\n",
   2245                        checkip, valid_ip ? "" : " NOT");
   2246         ret = ret && valid_ip > 0;
   2247     }
   2248 
   2249     return ret;
   2250 }
   2251 
   2252 static int do_pkey_ctx_init(EVP_PKEY_CTX *pkctx, STACK_OF(OPENSSL_STRING) *opts)
   2253 {
   2254     int i;
   2255 
   2256     if (opts == NULL)
   2257         return 1;
   2258 
   2259     for (i = 0; i < sk_OPENSSL_STRING_num(opts); i++) {
   2260         char *opt = sk_OPENSSL_STRING_value(opts, i);
   2261 
   2262         if (pkey_ctrl_string(pkctx, opt) <= 0) {
   2263             BIO_printf(bio_err, "parameter error \"%s\"\n", opt);
   2264             ERR_print_errors(bio_err);
   2265             return 0;
   2266         }
   2267     }
   2268 
   2269     return 1;
   2270 }
   2271 
   2272 static int do_x509_init(X509 *x, STACK_OF(OPENSSL_STRING) *opts)
   2273 {
   2274     int i;
   2275 
   2276     if (opts == NULL)
   2277         return 1;
   2278 
   2279     for (i = 0; i < sk_OPENSSL_STRING_num(opts); i++) {
   2280         char *opt = sk_OPENSSL_STRING_value(opts, i);
   2281 
   2282         if (x509_ctrl_string(x, opt) <= 0) {
   2283             BIO_printf(bio_err, "parameter error \"%s\"\n", opt);
   2284             ERR_print_errors(bio_err);
   2285             return 0;
   2286         }
   2287     }
   2288 
   2289     return 1;
   2290 }
   2291 
   2292 static int do_x509_req_init(X509_REQ *x, STACK_OF(OPENSSL_STRING) *opts)
   2293 {
   2294     int i;
   2295 
   2296     if (opts == NULL)
   2297         return 1;
   2298 
   2299     for (i = 0; i < sk_OPENSSL_STRING_num(opts); i++) {
   2300         char *opt = sk_OPENSSL_STRING_value(opts, i);
   2301 
   2302         if (x509_req_ctrl_string(x, opt) <= 0) {
   2303             BIO_printf(bio_err, "parameter error \"%s\"\n", opt);
   2304             ERR_print_errors(bio_err);
   2305             return 0;
   2306         }
   2307     }
   2308 
   2309     return 1;
   2310 }
   2311 
   2312 static int do_sign_init(EVP_MD_CTX *ctx, EVP_PKEY *pkey,
   2313                         const char *md, STACK_OF(OPENSSL_STRING) *sigopts)
   2314 {
   2315     EVP_PKEY_CTX *pkctx = NULL;
   2316     char def_md[80];
   2317 
   2318     if (ctx == NULL)
   2319         return 0;
   2320     /*
   2321      * EVP_PKEY_get_default_digest_name() returns 2 if the digest is mandatory
   2322      * for this algorithm.
   2323      */
   2324     if (EVP_PKEY_get_default_digest_name(pkey, def_md, sizeof(def_md)) == 2
   2325             && strcmp(def_md, "UNDEF") == 0) {
   2326         /* The signing algorithm requires there to be no digest */
   2327         md = NULL;
   2328     }
   2329 
   2330     return EVP_DigestSignInit_ex(ctx, &pkctx, md, app_get0_libctx(),
   2331                                  app_get0_propq(), pkey, NULL)
   2332         && do_pkey_ctx_init(pkctx, sigopts);
   2333 }
   2334 
   2335 static int adapt_keyid_ext(X509 *cert, X509V3_CTX *ext_ctx,
   2336                            const char *name, const char *value, int add_default)
   2337 {
   2338     const STACK_OF(X509_EXTENSION) *exts = X509_get0_extensions(cert);
   2339     X509_EXTENSION *new_ext = X509V3_EXT_nconf(NULL, ext_ctx, name, value);
   2340     int idx, rv = 0;
   2341 
   2342     if (new_ext == NULL)
   2343         return rv;
   2344 
   2345     idx = X509v3_get_ext_by_OBJ(exts, X509_EXTENSION_get_object(new_ext), -1);
   2346     if (idx >= 0) {
   2347         X509_EXTENSION *found_ext = X509v3_get_ext(exts, idx);
   2348         ASN1_OCTET_STRING *encoded = X509_EXTENSION_get_data(found_ext);
   2349         int disabled = ASN1_STRING_length(encoded) <= 2; /* indicating "none" */
   2350 
   2351         if (disabled) {
   2352             X509_delete_ext(cert, idx);
   2353             X509_EXTENSION_free(found_ext);
   2354         } /* else keep existing key identifier, which might be outdated */
   2355         rv = 1;
   2356     } else {
   2357         rv = !add_default || X509_add_ext(cert, new_ext, -1);
   2358     }
   2359     X509_EXTENSION_free(new_ext);
   2360     return rv;
   2361 }
   2362 
   2363 int cert_matches_key(const X509 *cert, const EVP_PKEY *pkey)
   2364 {
   2365     int match;
   2366 
   2367     ERR_set_mark();
   2368     match = X509_check_private_key(cert, pkey);
   2369     ERR_pop_to_mark();
   2370     return match;
   2371 }
   2372 
   2373 /* Ensure RFC 5280 compliance, adapt keyIDs as needed, and sign the cert info */
   2374 int do_X509_sign(X509 *cert, int force_v1, EVP_PKEY *pkey, const char *md,
   2375                  STACK_OF(OPENSSL_STRING) *sigopts, X509V3_CTX *ext_ctx)
   2376 {
   2377     EVP_MD_CTX *mctx = EVP_MD_CTX_new();
   2378     int self_sign;
   2379     int rv = 0;
   2380 
   2381     if (!force_v1) {
   2382         if (!X509_set_version(cert, X509_VERSION_3))
   2383             goto end;
   2384 
   2385         /*
   2386          * Add default SKID before AKID such that AKID can make use of it
   2387          * in case the certificate is self-signed
   2388          */
   2389         /* Prevent X509_V_ERR_MISSING_SUBJECT_KEY_IDENTIFIER */
   2390         if (!adapt_keyid_ext(cert, ext_ctx, "subjectKeyIdentifier", "hash", 1))
   2391             goto end;
   2392         /* Prevent X509_V_ERR_MISSING_AUTHORITY_KEY_IDENTIFIER */
   2393         self_sign = cert_matches_key(cert, pkey);
   2394         if (!adapt_keyid_ext(cert, ext_ctx, "authorityKeyIdentifier",
   2395                              "keyid, issuer", !self_sign))
   2396             goto end;
   2397     }
   2398     /* May add further measures for ensuring RFC 5280 compliance, see #19805 */
   2399 
   2400     if (mctx != NULL && do_sign_init(mctx, pkey, md, sigopts) > 0)
   2401         rv = (X509_sign_ctx(cert, mctx) > 0);
   2402  end:
   2403     EVP_MD_CTX_free(mctx);
   2404     return rv;
   2405 }
   2406 
   2407 /* Sign the certificate request info */
   2408 int do_X509_REQ_sign(X509_REQ *x, EVP_PKEY *pkey, const char *md,
   2409                      STACK_OF(OPENSSL_STRING) *sigopts)
   2410 {
   2411     int rv = 0;
   2412     EVP_MD_CTX *mctx = EVP_MD_CTX_new();
   2413 
   2414     if (do_sign_init(mctx, pkey, md, sigopts) > 0)
   2415         rv = (X509_REQ_sign_ctx(x, mctx) > 0);
   2416     EVP_MD_CTX_free(mctx);
   2417     return rv;
   2418 }
   2419 
   2420 /* Sign the CRL info */
   2421 int do_X509_CRL_sign(X509_CRL *x, EVP_PKEY *pkey, const char *md,
   2422                      STACK_OF(OPENSSL_STRING) *sigopts)
   2423 {
   2424     int rv = 0;
   2425     EVP_MD_CTX *mctx = EVP_MD_CTX_new();
   2426 
   2427     if (do_sign_init(mctx, pkey, md, sigopts) > 0)
   2428         rv = (X509_CRL_sign_ctx(x, mctx) > 0);
   2429     EVP_MD_CTX_free(mctx);
   2430     return rv;
   2431 }
   2432 
   2433 /*
   2434  * do_X509_verify returns 1 if the signature is valid,
   2435  * 0 if the signature check fails, or -1 if error occurs.
   2436  */
   2437 int do_X509_verify(X509 *x, EVP_PKEY *pkey, STACK_OF(OPENSSL_STRING) *vfyopts)
   2438 {
   2439     int rv = 0;
   2440 
   2441     if (do_x509_init(x, vfyopts) > 0)
   2442         rv = X509_verify(x, pkey);
   2443     else
   2444         rv = -1;
   2445     return rv;
   2446 }
   2447 
   2448 /*
   2449  * do_X509_REQ_verify returns 1 if the signature is valid,
   2450  * 0 if the signature check fails, or -1 if error occurs.
   2451  */
   2452 int do_X509_REQ_verify(X509_REQ *x, EVP_PKEY *pkey,
   2453                        STACK_OF(OPENSSL_STRING) *vfyopts)
   2454 {
   2455     int rv = 0;
   2456 
   2457     if (do_x509_req_init(x, vfyopts) > 0)
   2458         rv = X509_REQ_verify_ex(x, pkey, app_get0_libctx(), app_get0_propq());
   2459     else
   2460         rv = -1;
   2461     return rv;
   2462 }
   2463 
   2464 /* Get first http URL from a DIST_POINT structure */
   2465 
   2466 static const char *get_dp_url(DIST_POINT *dp)
   2467 {
   2468     GENERAL_NAMES *gens;
   2469     GENERAL_NAME *gen;
   2470     int i, gtype;
   2471     ASN1_STRING *uri;
   2472 
   2473     if (!dp->distpoint || dp->distpoint->type != 0)
   2474         return NULL;
   2475     gens = dp->distpoint->name.fullname;
   2476     for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) {
   2477         gen = sk_GENERAL_NAME_value(gens, i);
   2478         uri = GENERAL_NAME_get0_value(gen, &gtype);
   2479         if (gtype == GEN_URI && ASN1_STRING_length(uri) > 6) {
   2480             const char *uptr = (const char *)ASN1_STRING_get0_data(uri);
   2481 
   2482             if (IS_HTTP(uptr)) /* can/should not use HTTPS here */
   2483                 return uptr;
   2484         }
   2485     }
   2486     return NULL;
   2487 }
   2488 
   2489 /*
   2490  * Look through a CRLDP structure and attempt to find an http URL to
   2491  * downloads a CRL from.
   2492  */
   2493 
   2494 static X509_CRL *load_crl_crldp(STACK_OF(DIST_POINT) *crldp)
   2495 {
   2496     int i;
   2497     const char *urlptr = NULL;
   2498 
   2499     for (i = 0; i < sk_DIST_POINT_num(crldp); i++) {
   2500         DIST_POINT *dp = sk_DIST_POINT_value(crldp, i);
   2501 
   2502         urlptr = get_dp_url(dp);
   2503         if (urlptr != NULL)
   2504             return load_crl(urlptr, FORMAT_UNDEF, 0, "CRL via CDP");
   2505     }
   2506     return NULL;
   2507 }
   2508 
   2509 /*
   2510  * Example of downloading CRLs from CRLDP:
   2511  * not usable for real world as it always downloads and doesn't cache anything.
   2512  */
   2513 
   2514 static STACK_OF(X509_CRL) *crls_http_cb(const X509_STORE_CTX *ctx,
   2515                                         const X509_NAME *nm)
   2516 {
   2517     X509 *x;
   2518     STACK_OF(X509_CRL) *crls = NULL;
   2519     X509_CRL *crl;
   2520     STACK_OF(DIST_POINT) *crldp;
   2521 
   2522     crls = sk_X509_CRL_new_null();
   2523     if (!crls)
   2524         return NULL;
   2525     x = X509_STORE_CTX_get_current_cert(ctx);
   2526     crldp = X509_get_ext_d2i(x, NID_crl_distribution_points, NULL, NULL);
   2527     crl = load_crl_crldp(crldp);
   2528     sk_DIST_POINT_pop_free(crldp, DIST_POINT_free);
   2529 
   2530     if (crl == NULL || !sk_X509_CRL_push(crls, crl))
   2531         goto error;
   2532 
   2533     /* Try to download delta CRL */
   2534     crldp = X509_get_ext_d2i(x, NID_freshest_crl, NULL, NULL);
   2535     crl = load_crl_crldp(crldp);
   2536     sk_DIST_POINT_pop_free(crldp, DIST_POINT_free);
   2537 
   2538     if (crl != NULL && !sk_X509_CRL_push(crls, crl))
   2539         goto error;
   2540 
   2541     return crls;
   2542 
   2543 error:
   2544     X509_CRL_free(crl);
   2545     sk_X509_CRL_free(crls);
   2546     return NULL;
   2547 }
   2548 
   2549 void store_setup_crl_download(X509_STORE *st)
   2550 {
   2551     X509_STORE_set_lookup_crls_cb(st, crls_http_cb);
   2552 }
   2553 
   2554 #if !defined(OPENSSL_NO_SOCK) && !defined(OPENSSL_NO_HTTP)
   2555 static const char *tls_error_hint(void)
   2556 {
   2557     unsigned long err = ERR_peek_error();
   2558 
   2559     if (ERR_GET_LIB(err) != ERR_LIB_SSL)
   2560         err = ERR_peek_last_error();
   2561     if (ERR_GET_LIB(err) != ERR_LIB_SSL)
   2562         return NULL; /* likely no TLS error */
   2563 
   2564     switch (ERR_GET_REASON(err)) {
   2565     case SSL_R_WRONG_VERSION_NUMBER:
   2566         return "The server does not support (a suitable version of) TLS";
   2567     case SSL_R_UNKNOWN_PROTOCOL:
   2568         return "The server does not support HTTPS";
   2569     case SSL_R_CERTIFICATE_VERIFY_FAILED:
   2570         return "Cannot authenticate server via its TLS certificate, likely due to mismatch with our trusted TLS certs or missing revocation status";
   2571     case SSL_AD_REASON_OFFSET + TLS1_AD_UNKNOWN_CA:
   2572         return "Server did not accept our TLS certificate, likely due to mismatch with server's trust anchor or missing revocation status";
   2573     case SSL_AD_REASON_OFFSET + SSL3_AD_HANDSHAKE_FAILURE:
   2574         return "TLS handshake failure. Possibly the server requires our TLS certificate but did not receive it";
   2575     default:
   2576         return NULL; /* no hint available for TLS error */
   2577     }
   2578 }
   2579 
   2580 static BIO *http_tls_shutdown(BIO *bio)
   2581 {
   2582     if (bio != NULL) {
   2583         BIO *cbio;
   2584         const char *hint = tls_error_hint();
   2585 
   2586         if (hint != NULL)
   2587             BIO_printf(bio_err, "%s\n", hint);
   2588         (void)ERR_set_mark();
   2589         BIO_ssl_shutdown(bio);
   2590         cbio = BIO_pop(bio); /* connect+HTTP BIO */
   2591         BIO_free(bio); /* SSL BIO */
   2592         (void)ERR_pop_to_mark(); /* hide SSL_R_READ_BIO_NOT_SET etc. */
   2593         bio = cbio;
   2594     }
   2595     return bio;
   2596 }
   2597 
   2598 /* HTTP callback function that supports TLS connection also via HTTPS proxy */
   2599 BIO *app_http_tls_cb(BIO *bio, void *arg, int connect, int detail)
   2600 {
   2601     APP_HTTP_TLS_INFO *info = (APP_HTTP_TLS_INFO *)arg;
   2602     SSL_CTX *ssl_ctx = info->ssl_ctx;
   2603 
   2604     if (ssl_ctx == NULL) /* not using TLS */
   2605         return bio;
   2606     if (connect) {
   2607         SSL *ssl;
   2608         BIO *sbio = NULL;
   2609         X509_STORE *ts = SSL_CTX_get_cert_store(ssl_ctx);
   2610         X509_VERIFY_PARAM *vpm = X509_STORE_get0_param(ts);
   2611         const char *host = vpm == NULL ? NULL :
   2612             X509_VERIFY_PARAM_get0_host(vpm, 0 /* first hostname */);
   2613 
   2614         /* adapt after fixing callback design flaw, see #17088 */
   2615         if ((info->use_proxy
   2616              && !OSSL_HTTP_proxy_connect(bio, info->server, info->port,
   2617                                          NULL, NULL, /* no proxy credentials */
   2618                                          info->timeout, bio_err, opt_getprog()))
   2619                 || (sbio = BIO_new(BIO_f_ssl())) == NULL) {
   2620             return NULL;
   2621         }
   2622         if ((ssl = SSL_new(ssl_ctx)) == NULL) {
   2623             BIO_free(sbio);
   2624             return NULL;
   2625         }
   2626 
   2627         if (vpm != NULL)
   2628             SSL_set_tlsext_host_name(ssl, host /* may be NULL */);
   2629 
   2630         SSL_set_connect_state(ssl);
   2631         BIO_set_ssl(sbio, ssl, BIO_CLOSE);
   2632 
   2633         bio = BIO_push(sbio, bio);
   2634     } else { /* disconnect from TLS */
   2635         bio = http_tls_shutdown(bio);
   2636     }
   2637     return bio;
   2638 }
   2639 
   2640 void APP_HTTP_TLS_INFO_free(APP_HTTP_TLS_INFO *info)
   2641 {
   2642     if (info != NULL) {
   2643         SSL_CTX_free(info->ssl_ctx);
   2644         OPENSSL_free(info);
   2645     }
   2646 }
   2647 
   2648 ASN1_VALUE *app_http_get_asn1(const char *url, const char *proxy,
   2649                               const char *no_proxy, SSL_CTX *ssl_ctx,
   2650                               const STACK_OF(CONF_VALUE) *headers,
   2651                               long timeout, const char *expected_content_type,
   2652                               const ASN1_ITEM *it)
   2653 {
   2654     APP_HTTP_TLS_INFO info;
   2655     char *server;
   2656     char *port;
   2657     int use_ssl;
   2658     BIO *mem;
   2659     ASN1_VALUE *resp = NULL;
   2660 
   2661     if (url == NULL || it == NULL) {
   2662         ERR_raise(ERR_LIB_HTTP, ERR_R_PASSED_NULL_PARAMETER);
   2663         return NULL;
   2664     }
   2665 
   2666     if (!OSSL_HTTP_parse_url(url, &use_ssl, NULL /* userinfo */, &server, &port,
   2667                              NULL /* port_num, */, NULL, NULL, NULL))
   2668         return NULL;
   2669     if (use_ssl && ssl_ctx == NULL) {
   2670         ERR_raise_data(ERR_LIB_HTTP, ERR_R_PASSED_NULL_PARAMETER,
   2671                        "missing SSL_CTX");
   2672         goto end;
   2673     }
   2674     if (!use_ssl && ssl_ctx != NULL) {
   2675         ERR_raise_data(ERR_LIB_HTTP, ERR_R_PASSED_INVALID_ARGUMENT,
   2676                        "SSL_CTX given but use_ssl == 0");
   2677         goto end;
   2678     }
   2679 
   2680     info.server = server;
   2681     info.port = port;
   2682     info.use_proxy = /* workaround for callback design flaw, see #17088 */
   2683         OSSL_HTTP_adapt_proxy(proxy, no_proxy, server, use_ssl) != NULL;
   2684     info.timeout = timeout;
   2685     info.ssl_ctx = ssl_ctx;
   2686     mem = OSSL_HTTP_get(url, proxy, no_proxy, NULL /* bio */, NULL /* rbio */,
   2687                         app_http_tls_cb, &info, 0 /* buf_size */, headers,
   2688                         expected_content_type, 1 /* expect_asn1 */,
   2689                         OSSL_HTTP_DEFAULT_MAX_RESP_LEN, timeout);
   2690     resp = ASN1_item_d2i_bio(it, mem, NULL);
   2691     BIO_free(mem);
   2692 
   2693  end:
   2694     OPENSSL_free(server);
   2695     OPENSSL_free(port);
   2696     return resp;
   2697 
   2698 }
   2699 
   2700 ASN1_VALUE *app_http_post_asn1(const char *host, const char *port,
   2701                                const char *path, const char *proxy,
   2702                                const char *no_proxy, SSL_CTX *ssl_ctx,
   2703                                const STACK_OF(CONF_VALUE) *headers,
   2704                                const char *content_type,
   2705                                ASN1_VALUE *req, const ASN1_ITEM *req_it,
   2706                                const char *expected_content_type,
   2707                                long timeout, const ASN1_ITEM *rsp_it)
   2708 {
   2709     int use_ssl = ssl_ctx != NULL;
   2710     APP_HTTP_TLS_INFO info;
   2711     BIO *rsp, *req_mem = ASN1_item_i2d_mem_bio(req_it, req);
   2712     ASN1_VALUE *res;
   2713 
   2714     if (req_mem == NULL)
   2715         return NULL;
   2716 
   2717     info.server = host;
   2718     info.port = port;
   2719     info.use_proxy = /* workaround for callback design flaw, see #17088 */
   2720         OSSL_HTTP_adapt_proxy(proxy, no_proxy, host, use_ssl) != NULL;
   2721     info.timeout = timeout;
   2722     info.ssl_ctx = ssl_ctx;
   2723     rsp = OSSL_HTTP_transfer(NULL, host, port, path, use_ssl,
   2724                              proxy, no_proxy, NULL /* bio */, NULL /* rbio */,
   2725                              app_http_tls_cb, &info,
   2726                              0 /* buf_size */, headers, content_type, req_mem,
   2727                              expected_content_type, 1 /* expect_asn1 */,
   2728                              OSSL_HTTP_DEFAULT_MAX_RESP_LEN, timeout,
   2729                              0 /* keep_alive */);
   2730     BIO_free(req_mem);
   2731     res = ASN1_item_d2i_bio(rsp_it, rsp, NULL);
   2732     BIO_free(rsp);
   2733     return res;
   2734 }
   2735 
   2736 #endif
   2737 
   2738 /*
   2739  * Platform-specific sections
   2740  */
   2741 #if defined(_WIN32)
   2742 # ifdef fileno
   2743 #  undef fileno
   2744 #  define fileno(a) (int)_fileno(a)
   2745 # endif
   2746 
   2747 # include <windows.h>
   2748 # include <tchar.h>
   2749 
   2750 static int WIN32_rename(const char *from, const char *to)
   2751 {
   2752     TCHAR *tfrom = NULL, *tto;
   2753     DWORD err;
   2754     int ret = 0;
   2755 
   2756     if (sizeof(TCHAR) == 1) {
   2757         tfrom = (TCHAR *)from;
   2758         tto = (TCHAR *)to;
   2759     } else {                    /* UNICODE path */
   2760         size_t i, flen = strlen(from) + 1, tlen = strlen(to) + 1;
   2761 
   2762         tfrom = malloc(sizeof(*tfrom) * (flen + tlen));
   2763         if (tfrom == NULL)
   2764             goto err;
   2765         tto = tfrom + flen;
   2766 # if !defined(_WIN32_WCE) || _WIN32_WCE >= 101
   2767         if (!MultiByteToWideChar(CP_ACP, 0, from, flen, (WCHAR *)tfrom, flen))
   2768 # endif
   2769             for (i = 0; i < flen; i++)
   2770                 tfrom[i] = (TCHAR)from[i];
   2771 # if !defined(_WIN32_WCE) || _WIN32_WCE >= 101
   2772         if (!MultiByteToWideChar(CP_ACP, 0, to, tlen, (WCHAR *)tto, tlen))
   2773 # endif
   2774             for (i = 0; i < tlen; i++)
   2775                 tto[i] = (TCHAR)to[i];
   2776     }
   2777 
   2778     if (MoveFile(tfrom, tto))
   2779         goto ok;
   2780     err = GetLastError();
   2781     if (err == ERROR_ALREADY_EXISTS || err == ERROR_FILE_EXISTS) {
   2782         if (DeleteFile(tto) && MoveFile(tfrom, tto))
   2783             goto ok;
   2784         err = GetLastError();
   2785     }
   2786     if (err == ERROR_FILE_NOT_FOUND || err == ERROR_PATH_NOT_FOUND)
   2787         errno = ENOENT;
   2788     else if (err == ERROR_ACCESS_DENIED)
   2789         errno = EACCES;
   2790     else
   2791         errno = EINVAL;         /* we could map more codes... */
   2792  err:
   2793     ret = -1;
   2794  ok:
   2795     if (tfrom != NULL && tfrom != (TCHAR *)from)
   2796         free(tfrom);
   2797     return ret;
   2798 }
   2799 #endif
   2800 
   2801 /* app_tminterval section */
   2802 #if defined(_WIN32)
   2803 double app_tminterval(int stop, int usertime)
   2804 {
   2805     FILETIME now;
   2806     double ret = 0;
   2807     static ULARGE_INTEGER tmstart;
   2808     static int warning = 1;
   2809     int use_GetSystemTime = 1;
   2810 # ifdef _WIN32_WINNT
   2811     static HANDLE proc = NULL;
   2812 
   2813     if (proc == NULL) {
   2814         if (check_winnt())
   2815             proc = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE,
   2816                                GetCurrentProcessId());
   2817         if (proc == NULL)
   2818             proc = (HANDLE) - 1;
   2819     }
   2820 
   2821     if (usertime && proc != (HANDLE) - 1) {
   2822         FILETIME junk;
   2823 
   2824         GetProcessTimes(proc, &junk, &junk, &junk, &now);
   2825         use_GetSystemTime = 0;
   2826     }
   2827 # endif
   2828     if (use_GetSystemTime) {
   2829         SYSTEMTIME systime;
   2830 
   2831         if (usertime && warning) {
   2832             BIO_printf(bio_err, "To get meaningful results, run "
   2833                        "this program on idle system.\n");
   2834             warning = 0;
   2835         }
   2836         GetSystemTime(&systime);
   2837         SystemTimeToFileTime(&systime, &now);
   2838     }
   2839 
   2840     if (stop == TM_START) {
   2841         tmstart.u.LowPart = now.dwLowDateTime;
   2842         tmstart.u.HighPart = now.dwHighDateTime;
   2843     } else {
   2844         ULARGE_INTEGER tmstop;
   2845 
   2846         tmstop.u.LowPart = now.dwLowDateTime;
   2847         tmstop.u.HighPart = now.dwHighDateTime;
   2848 
   2849         ret = (__int64)(tmstop.QuadPart - tmstart.QuadPart) * 1e-7;
   2850     }
   2851 
   2852     return ret;
   2853 }
   2854 #elif defined(OPENSSL_SYS_VXWORKS)
   2855 # include <time.h>
   2856 
   2857 double app_tminterval(int stop, int usertime)
   2858 {
   2859     double ret = 0;
   2860 # ifdef CLOCK_REALTIME
   2861     static struct timespec tmstart;
   2862     struct timespec now;
   2863 # else
   2864     static unsigned long tmstart;
   2865     unsigned long now;
   2866 # endif
   2867     static int warning = 1;
   2868 
   2869     if (usertime && warning) {
   2870         BIO_printf(bio_err, "To get meaningful results, run "
   2871                    "this program on idle system.\n");
   2872         warning = 0;
   2873     }
   2874 # ifdef CLOCK_REALTIME
   2875     clock_gettime(CLOCK_REALTIME, &now);
   2876     if (stop == TM_START)
   2877         tmstart = now;
   2878     else
   2879         ret = ((now.tv_sec + now.tv_nsec * 1e-9)
   2880                - (tmstart.tv_sec + tmstart.tv_nsec * 1e-9));
   2881 # else
   2882     now = tickGet();
   2883     if (stop == TM_START)
   2884         tmstart = now;
   2885     else
   2886         ret = (now - tmstart) / (double)sysClkRateGet();
   2887 # endif
   2888     return ret;
   2889 }
   2890 
   2891 #elif defined(_SC_CLK_TCK)      /* by means of unistd.h */
   2892 # include <sys/times.h>
   2893 
   2894 double app_tminterval(int stop, int usertime)
   2895 {
   2896     double ret = 0;
   2897     struct tms rus;
   2898     clock_t now = times(&rus);
   2899     static clock_t tmstart;
   2900 
   2901     if (usertime)
   2902         now = rus.tms_utime;
   2903 
   2904     if (stop == TM_START) {
   2905         tmstart = now;
   2906     } else {
   2907         long int tck = sysconf(_SC_CLK_TCK);
   2908 
   2909         ret = (now - tmstart) / (double)tck;
   2910     }
   2911 
   2912     return ret;
   2913 }
   2914 
   2915 #else
   2916 # include <sys/time.h>
   2917 # include <sys/resource.h>
   2918 
   2919 double app_tminterval(int stop, int usertime)
   2920 {
   2921     double ret = 0;
   2922     struct rusage rus;
   2923     struct timeval now;
   2924     static struct timeval tmstart;
   2925 
   2926     if (usertime)
   2927         getrusage(RUSAGE_SELF, &rus), now = rus.ru_utime;
   2928     else
   2929         gettimeofday(&now, NULL);
   2930 
   2931     if (stop == TM_START)
   2932         tmstart = now;
   2933     else
   2934         ret = ((now.tv_sec + now.tv_usec * 1e-6)
   2935                - (tmstart.tv_sec + tmstart.tv_usec * 1e-6));
   2936 
   2937     return ret;
   2938 }
   2939 #endif
   2940 
   2941 int app_access(const char *name, int flag)
   2942 {
   2943 #ifdef _WIN32
   2944     return _access(name, flag);
   2945 #else
   2946     return access(name, flag);
   2947 #endif
   2948 }
   2949 
   2950 int app_isdir(const char *name)
   2951 {
   2952     return opt_isdir(name);
   2953 }
   2954 
   2955 /* raw_read|write section */
   2956 #if defined(__VMS)
   2957 # include "vms_term_sock.h"
   2958 static int stdin_sock = -1;
   2959 
   2960 static void close_stdin_sock(void)
   2961 {
   2962     TerminalSocket(TERM_SOCK_DELETE, &stdin_sock);
   2963 }
   2964 
   2965 int fileno_stdin(void)
   2966 {
   2967     if (stdin_sock == -1) {
   2968         TerminalSocket(TERM_SOCK_CREATE, &stdin_sock);
   2969         atexit(close_stdin_sock);
   2970     }
   2971 
   2972     return stdin_sock;
   2973 }
   2974 #else
   2975 int fileno_stdin(void)
   2976 {
   2977     return fileno(stdin);
   2978 }
   2979 #endif
   2980 
   2981 int fileno_stdout(void)
   2982 {
   2983     return fileno(stdout);
   2984 }
   2985 
   2986 #if defined(_WIN32) && defined(STD_INPUT_HANDLE)
   2987 int raw_read_stdin(void *buf, int siz)
   2988 {
   2989     DWORD n;
   2990 
   2991     if (ReadFile(GetStdHandle(STD_INPUT_HANDLE), buf, siz, &n, NULL))
   2992         return n;
   2993     else
   2994         return -1;
   2995 }
   2996 #elif defined(__VMS)
   2997 # include <sys/socket.h>
   2998 
   2999 int raw_read_stdin(void *buf, int siz)
   3000 {
   3001     return recv(fileno_stdin(), buf, siz, 0);
   3002 }
   3003 #else
   3004 int raw_read_stdin(void *buf, int siz)
   3005 {
   3006     return read(fileno_stdin(), buf, siz);
   3007 }
   3008 #endif
   3009 
   3010 #if defined(_WIN32) && defined(STD_OUTPUT_HANDLE)
   3011 int raw_write_stdout(const void *buf, int siz)
   3012 {
   3013     DWORD n;
   3014 
   3015     if (WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), buf, siz, &n, NULL))
   3016         return n;
   3017     else
   3018         return -1;
   3019 }
   3020 #elif defined(OPENSSL_SYS_TANDEM) && defined(OPENSSL_THREADS) \
   3021     && defined(_SPT_MODEL_)
   3022 int raw_write_stdout(const void *buf, int siz)
   3023 {
   3024     return write(fileno(stdout), (void *)buf, siz);
   3025 }
   3026 #else
   3027 int raw_write_stdout(const void *buf, int siz)
   3028 {
   3029     return write(fileno_stdout(), buf, siz);
   3030 }
   3031 #endif
   3032 
   3033 /*
   3034  * Centralized handling of input and output files with format specification
   3035  * The format is meant to show what the input and output is supposed to be,
   3036  * and is therefore a show of intent more than anything else.  However, it
   3037  * does impact behavior on some platforms, such as differentiating between
   3038  * text and binary input/output on non-Unix platforms
   3039  */
   3040 BIO *dup_bio_in(int format)
   3041 {
   3042     return BIO_new_fp(stdin,
   3043                       BIO_NOCLOSE | (FMT_istext(format) ? BIO_FP_TEXT : 0));
   3044 }
   3045 
   3046 BIO *dup_bio_out(int format)
   3047 {
   3048     BIO *b = BIO_new_fp(stdout,
   3049                         BIO_NOCLOSE | (FMT_istext(format) ? BIO_FP_TEXT : 0));
   3050     void *prefix = NULL;
   3051 
   3052     if (b == NULL)
   3053         return NULL;
   3054 
   3055 #ifdef OPENSSL_SYS_VMS
   3056     if (FMT_istext(format))
   3057         b = BIO_push(BIO_new(BIO_f_linebuffer()), b);
   3058 #endif
   3059 
   3060     if (FMT_istext(format)
   3061         && (prefix = getenv("HARNESS_OSSL_PREFIX")) != NULL) {
   3062         b = BIO_push(BIO_new(BIO_f_prefix()), b);
   3063         BIO_set_prefix(b, prefix);
   3064     }
   3065 
   3066     return b;
   3067 }
   3068 
   3069 BIO *dup_bio_err(int format)
   3070 {
   3071     BIO *b = BIO_new_fp(stderr,
   3072                         BIO_NOCLOSE | (FMT_istext(format) ? BIO_FP_TEXT : 0));
   3073 
   3074 #ifdef OPENSSL_SYS_VMS
   3075     if (b != NULL && FMT_istext(format))
   3076         b = BIO_push(BIO_new(BIO_f_linebuffer()), b);
   3077 #endif
   3078     return b;
   3079 }
   3080 
   3081 void unbuffer(FILE *fp)
   3082 {
   3083 /*
   3084  * On VMS, setbuf() will only take 32-bit pointers, and a compilation
   3085  * with /POINTER_SIZE=64 will give off a MAYLOSEDATA2 warning here.
   3086  * However, we trust that the C RTL will never give us a FILE pointer
   3087  * above the first 4 GB of memory, so we simply turn off the warning
   3088  * temporarily.
   3089  */
   3090 #if defined(OPENSSL_SYS_VMS) && defined(__DECC)
   3091 # pragma environment save
   3092 # pragma message disable maylosedata2
   3093 #endif
   3094     setbuf(fp, NULL);
   3095 #if defined(OPENSSL_SYS_VMS) && defined(__DECC)
   3096 # pragma environment restore
   3097 #endif
   3098 }
   3099 
   3100 static const char *modestr(char mode, int format)
   3101 {
   3102     OPENSSL_assert(mode == 'a' || mode == 'r' || mode == 'w');
   3103 
   3104     switch (mode) {
   3105     case 'a':
   3106         return FMT_istext(format) ? "a" : "ab";
   3107     case 'r':
   3108         return FMT_istext(format) ? "r" : "rb";
   3109     case 'w':
   3110         return FMT_istext(format) ? "w" : "wb";
   3111     }
   3112     /* The assert above should make sure we never reach this point */
   3113     return NULL;
   3114 }
   3115 
   3116 static const char *modeverb(char mode)
   3117 {
   3118     switch (mode) {
   3119     case 'a':
   3120         return "appending";
   3121     case 'r':
   3122         return "reading";
   3123     case 'w':
   3124         return "writing";
   3125     }
   3126     return "(doing something)";
   3127 }
   3128 
   3129 /*
   3130  * Open a file for writing, owner-read-only.
   3131  */
   3132 BIO *bio_open_owner(const char *filename, int format, int private)
   3133 {
   3134     FILE *fp = NULL;
   3135     BIO *b = NULL;
   3136     int textmode, bflags;
   3137 #ifndef OPENSSL_NO_POSIX_IO
   3138     int fd = -1, mode;
   3139 #endif
   3140 
   3141     if (!private || filename == NULL || strcmp(filename, "-") == 0)
   3142         return bio_open_default(filename, 'w', format);
   3143 
   3144     textmode = FMT_istext(format);
   3145 #ifndef OPENSSL_NO_POSIX_IO
   3146     mode = O_WRONLY;
   3147 # ifdef O_CREAT
   3148     mode |= O_CREAT;
   3149 # endif
   3150 # ifdef O_TRUNC
   3151     mode |= O_TRUNC;
   3152 # endif
   3153     if (!textmode) {
   3154 # ifdef O_BINARY
   3155         mode |= O_BINARY;
   3156 # elif defined(_O_BINARY)
   3157         mode |= _O_BINARY;
   3158 # endif
   3159     }
   3160 
   3161 # ifdef OPENSSL_SYS_VMS
   3162     /*
   3163      * VMS doesn't have O_BINARY, it just doesn't make sense.  But,
   3164      * it still needs to know that we're going binary, or fdopen()
   3165      * will fail with "invalid argument"...  so we tell VMS what the
   3166      * context is.
   3167      */
   3168     if (!textmode)
   3169         fd = open(filename, mode, 0600, "ctx=bin");
   3170     else
   3171 # endif
   3172         fd = open(filename, mode, 0600);
   3173     if (fd < 0)
   3174         goto err;
   3175     fp = fdopen(fd, modestr('w', format));
   3176 #else   /* OPENSSL_NO_POSIX_IO */
   3177     /* Have stdio but not Posix IO, do the best we can */
   3178     fp = fopen(filename, modestr('w', format));
   3179 #endif  /* OPENSSL_NO_POSIX_IO */
   3180     if (fp == NULL)
   3181         goto err;
   3182     bflags = BIO_CLOSE;
   3183     if (textmode)
   3184         bflags |= BIO_FP_TEXT;
   3185     b = BIO_new_fp(fp, bflags);
   3186     if (b != NULL)
   3187         return b;
   3188 
   3189  err:
   3190     BIO_printf(bio_err, "%s: Can't open \"%s\" for writing, %s\n",
   3191                opt_getprog(), filename, strerror(errno));
   3192     ERR_print_errors(bio_err);
   3193     /* If we have fp, then fdopen took over fd, so don't close both. */
   3194     if (fp != NULL)
   3195         fclose(fp);
   3196 #ifndef OPENSSL_NO_POSIX_IO
   3197     else if (fd >= 0)
   3198         close(fd);
   3199 #endif
   3200     return NULL;
   3201 }
   3202 
   3203 static BIO *bio_open_default_(const char *filename, char mode, int format,
   3204                               int quiet)
   3205 {
   3206     BIO *ret;
   3207 
   3208     if (filename == NULL || strcmp(filename, "-") == 0) {
   3209         ret = mode == 'r' ? dup_bio_in(format) : dup_bio_out(format);
   3210         if (quiet) {
   3211             ERR_clear_error();
   3212             return ret;
   3213         }
   3214         if (ret != NULL)
   3215             return ret;
   3216         BIO_printf(bio_err,
   3217                    "Can't open %s, %s\n",
   3218                    mode == 'r' ? "stdin" : "stdout", strerror(errno));
   3219     } else {
   3220         ret = BIO_new_file(filename, modestr(mode, format));
   3221         if (quiet) {
   3222             ERR_clear_error();
   3223             return ret;
   3224         }
   3225         if (ret != NULL)
   3226             return ret;
   3227         BIO_printf(bio_err,
   3228                    "Can't open \"%s\" for %s, %s\n",
   3229                    filename, modeverb(mode), strerror(errno));
   3230     }
   3231     ERR_print_errors(bio_err);
   3232     return NULL;
   3233 }
   3234 
   3235 BIO *bio_open_default(const char *filename, char mode, int format)
   3236 {
   3237     return bio_open_default_(filename, mode, format, 0);
   3238 }
   3239 
   3240 BIO *bio_open_default_quiet(const char *filename, char mode, int format)
   3241 {
   3242     return bio_open_default_(filename, mode, format, 1);
   3243 }
   3244 
   3245 int mem_bio_to_file(BIO *in, const char *filename, int format, int private)
   3246 {
   3247     int rv = 0, ret = 0;
   3248     BIO *out = NULL;
   3249     BUF_MEM *mem_buffer = NULL;
   3250 
   3251     rv = BIO_get_mem_ptr(in, &mem_buffer);
   3252     if (rv <= 0) {
   3253         BIO_puts(bio_err, "Error reading mem buffer\n");
   3254         goto end;
   3255     }
   3256     out = bio_open_owner(filename, format, private);
   3257     if (out == NULL)
   3258         goto end;
   3259     rv = BIO_write(out, mem_buffer->data, mem_buffer->length);
   3260     if (rv < 0 || (size_t)rv != mem_buffer->length)
   3261         BIO_printf(bio_err, "Error writing to output file: '%s'\n", filename);
   3262     else
   3263         ret = 1;
   3264 end:
   3265     if (!ret)
   3266         ERR_print_errors(bio_err);
   3267     BIO_free_all(out);
   3268     return ret;
   3269 }
   3270 
   3271 void wait_for_async(SSL *s)
   3272 {
   3273     /* On Windows select only works for sockets, so we simply don't wait  */
   3274 #ifndef OPENSSL_SYS_WINDOWS
   3275     int width = 0;
   3276     fd_set asyncfds;
   3277     OSSL_ASYNC_FD *fds;
   3278     size_t numfds;
   3279     size_t i;
   3280 
   3281     if (!SSL_get_all_async_fds(s, NULL, &numfds))
   3282         return;
   3283     if (numfds == 0)
   3284         return;
   3285     fds = app_malloc(sizeof(OSSL_ASYNC_FD) * numfds, "allocate async fds");
   3286     if (!SSL_get_all_async_fds(s, fds, &numfds)) {
   3287         OPENSSL_free(fds);
   3288         return;
   3289     }
   3290 
   3291     FD_ZERO(&asyncfds);
   3292     for (i = 0; i < numfds; i++) {
   3293         if (width <= (int)fds[i])
   3294             width = (int)fds[i] + 1;
   3295         openssl_fdset((int)fds[i], &asyncfds);
   3296     }
   3297     select(width, (void *)&asyncfds, NULL, NULL, NULL);
   3298     OPENSSL_free(fds);
   3299 #endif
   3300 }
   3301 
   3302 /* if OPENSSL_SYS_WINDOWS is defined then so is OPENSSL_SYS_MSDOS */
   3303 #if defined(OPENSSL_SYS_MSDOS)
   3304 int has_stdin_waiting(void)
   3305 {
   3306 # if defined(OPENSSL_SYS_WINDOWS)
   3307     HANDLE inhand = GetStdHandle(STD_INPUT_HANDLE);
   3308     DWORD events = 0;
   3309     INPUT_RECORD inputrec;
   3310     DWORD insize = 1;
   3311     BOOL peeked;
   3312 
   3313     if (inhand == INVALID_HANDLE_VALUE) {
   3314         return 0;
   3315     }
   3316 
   3317     peeked = PeekConsoleInput(inhand, &inputrec, insize, &events);
   3318     if (!peeked) {
   3319         /* Probably redirected input? _kbhit() does not work in this case */
   3320         if (!feof(stdin)) {
   3321             return 1;
   3322         }
   3323         return 0;
   3324     }
   3325 # endif
   3326     return _kbhit();
   3327 }
   3328 #endif
   3329 
   3330 /* Corrupt a signature by modifying final byte */
   3331 void corrupt_signature(const ASN1_STRING *signature)
   3332 {
   3333     unsigned char *s = signature->data;
   3334 
   3335     s[signature->length - 1] ^= 0x1;
   3336 }
   3337 
   3338 int check_cert_time_string(const char *time, const char *desc)
   3339 {
   3340     if (time == NULL || strcmp(time, "today") == 0
   3341             || ASN1_TIME_set_string_X509(NULL, time))
   3342         return 1;
   3343     BIO_printf(bio_err,
   3344                "%s is invalid, it should be \"today\" or have format [CC]YYMMDDHHMMSSZ\n",
   3345                desc);
   3346     return 0;
   3347 }
   3348 
   3349 int set_cert_times(X509 *x, const char *startdate, const char *enddate,
   3350                    int days, int strict_compare_times)
   3351 {
   3352     if (!check_cert_time_string(startdate, "start date"))
   3353         return 0;
   3354     if (!check_cert_time_string(enddate, "end date"))
   3355         return 0;
   3356     if (startdate == NULL || strcmp(startdate, "today") == 0) {
   3357         if (X509_gmtime_adj(X509_getm_notBefore(x), 0) == NULL) {
   3358             BIO_printf(bio_err, "Error setting notBefore certificate field\n");
   3359             return 0;
   3360         }
   3361     } else {
   3362         if (!ASN1_TIME_set_string_X509(X509_getm_notBefore(x), startdate)) {
   3363             BIO_printf(bio_err, "Error setting notBefore certificate field\n");
   3364             return 0;
   3365         }
   3366     }
   3367     if (enddate != NULL && strcmp(enddate, "today") == 0) {
   3368         enddate = NULL;
   3369         days = 0;
   3370     }
   3371     if (enddate == NULL) {
   3372         if (X509_time_adj_ex(X509_getm_notAfter(x), days, 0, NULL) == NULL) {
   3373             BIO_printf(bio_err, "Error setting notAfter certificate field\n");
   3374             return 0;
   3375         }
   3376     } else if (!ASN1_TIME_set_string_X509(X509_getm_notAfter(x), enddate)) {
   3377         BIO_printf(bio_err, "Error setting notAfter certificate field\n");
   3378         return 0;
   3379     }
   3380     if (ASN1_TIME_compare(X509_get0_notAfter(x), X509_get0_notBefore(x)) < 0) {
   3381         BIO_printf(bio_err, "%s: end date before start date\n",
   3382                    strict_compare_times ? "Error" : "Warning");
   3383         if (strict_compare_times)
   3384             return 0;
   3385     }
   3386     return 1;
   3387 }
   3388 
   3389 int set_crl_lastupdate(X509_CRL *crl, const char *lastupdate)
   3390 {
   3391     int ret = 0;
   3392     ASN1_TIME *tm = ASN1_TIME_new();
   3393 
   3394     if (tm == NULL)
   3395         goto end;
   3396 
   3397     if (lastupdate == NULL) {
   3398         if (X509_gmtime_adj(tm, 0) == NULL)
   3399             goto end;
   3400     } else {
   3401         if (!ASN1_TIME_set_string_X509(tm, lastupdate))
   3402             goto end;
   3403     }
   3404 
   3405     if (!X509_CRL_set1_lastUpdate(crl, tm))
   3406         goto end;
   3407 
   3408     ret = 1;
   3409 end:
   3410     ASN1_TIME_free(tm);
   3411     return ret;
   3412 }
   3413 
   3414 int set_crl_nextupdate(X509_CRL *crl, const char *nextupdate,
   3415                        long days, long hours, long secs)
   3416 {
   3417     int ret = 0;
   3418     ASN1_TIME *tm = ASN1_TIME_new();
   3419 
   3420     if (tm == NULL)
   3421         goto end;
   3422 
   3423     if (nextupdate == NULL) {
   3424         if (X509_time_adj_ex(tm, days, hours * 60 * 60 + secs, NULL) == NULL)
   3425             goto end;
   3426     } else {
   3427         if (!ASN1_TIME_set_string_X509(tm, nextupdate))
   3428             goto end;
   3429     }
   3430 
   3431     if (!X509_CRL_set1_nextUpdate(crl, tm))
   3432         goto end;
   3433 
   3434     ret = 1;
   3435 end:
   3436     ASN1_TIME_free(tm);
   3437     return ret;
   3438 }
   3439 
   3440 void make_uppercase(char *string)
   3441 {
   3442     int i;
   3443 
   3444     for (i = 0; string[i] != '\0'; i++)
   3445         string[i] = toupper((unsigned char)string[i]);
   3446 }
   3447 
   3448 OSSL_PARAM *app_params_new_from_opts(STACK_OF(OPENSSL_STRING) *opts,
   3449                                      const OSSL_PARAM *paramdefs)
   3450 {
   3451     OSSL_PARAM *params = NULL;
   3452     size_t sz = (size_t)sk_OPENSSL_STRING_num(opts);
   3453     size_t params_n;
   3454     char *opt = "", *stmp, *vtmp = NULL;
   3455     int found = 1;
   3456 
   3457     if (opts == NULL)
   3458         return NULL;
   3459 
   3460     params = OPENSSL_zalloc(sizeof(OSSL_PARAM) * (sz + 1));
   3461     if (params == NULL)
   3462         return NULL;
   3463 
   3464     for (params_n = 0; params_n < sz; params_n++) {
   3465         opt = sk_OPENSSL_STRING_value(opts, (int)params_n);
   3466         if ((stmp = OPENSSL_strdup(opt)) == NULL
   3467             || (vtmp = strchr(stmp, ':')) == NULL)
   3468             goto err;
   3469         /* Replace ':' with 0 to terminate the string pointed to by stmp */
   3470         *vtmp = 0;
   3471         /* Skip over the separator so that vmtp points to the value */
   3472         vtmp++;
   3473         if (!OSSL_PARAM_allocate_from_text(&params[params_n], paramdefs,
   3474                                            stmp, vtmp, strlen(vtmp), &found))
   3475             goto err;
   3476         OPENSSL_free(stmp);
   3477     }
   3478     params[params_n] = OSSL_PARAM_construct_end();
   3479     return params;
   3480 err:
   3481     OPENSSL_free(stmp);
   3482     BIO_printf(bio_err, "Parameter %s '%s'\n", found ? "error" : "unknown",
   3483                opt);
   3484     ERR_print_errors(bio_err);
   3485     app_params_free(params);
   3486     return NULL;
   3487 }
   3488 
   3489 void app_params_free(OSSL_PARAM *params)
   3490 {
   3491     int i;
   3492 
   3493     if (params != NULL) {
   3494         for (i = 0; params[i].key != NULL; ++i)
   3495             OPENSSL_free(params[i].data);
   3496         OPENSSL_free(params);
   3497     }
   3498 }
   3499 
   3500 EVP_PKEY *app_keygen(EVP_PKEY_CTX *ctx, const char *alg, int bits, int verbose)
   3501 {
   3502     EVP_PKEY *res = NULL;
   3503 
   3504     if (verbose && alg != NULL) {
   3505         BIO_printf(bio_err, "Generating %s key", alg);
   3506         if (bits > 0)
   3507             BIO_printf(bio_err, " with %d bits\n", bits);
   3508         else
   3509             BIO_printf(bio_err, "\n");
   3510     }
   3511     if (!RAND_status())
   3512         BIO_printf(bio_err, "Warning: generating random key material may take a long time\n"
   3513                    "if the system has a poor entropy source\n");
   3514     if (EVP_PKEY_keygen(ctx, &res) <= 0)
   3515         BIO_printf(bio_err, "%s: Error generating %s key\n", opt_getprog(),
   3516                    alg != NULL ? alg : "asymmetric");
   3517     return res;
   3518 }
   3519 
   3520 EVP_PKEY *app_paramgen(EVP_PKEY_CTX *ctx, const char *alg)
   3521 {
   3522     EVP_PKEY *res = NULL;
   3523 
   3524     if (!RAND_status())
   3525         BIO_printf(bio_err, "Warning: generating random key parameters may take a long time\n"
   3526                    "if the system has a poor entropy source\n");
   3527     if (EVP_PKEY_paramgen(ctx, &res) <= 0)
   3528         BIO_printf(bio_err, "%s: Generating %s key parameters failed\n",
   3529                    opt_getprog(), alg != NULL ? alg : "asymmetric");
   3530     return res;
   3531 }
   3532 
   3533 /*
   3534  * Return non-zero if the legacy path is still an option.
   3535  * This decision is based on the global command line operations and the
   3536  * behaviour thus far.
   3537  */
   3538 int opt_legacy_okay(void)
   3539 {
   3540     int provider_options = opt_provider_option_given();
   3541     int libctx = app_get0_libctx() != NULL || app_get0_propq() != NULL;
   3542 
   3543     /*
   3544      * Having a provider option specified or a custom library context or
   3545      * property query, is a sure sign we're not using legacy.
   3546      */
   3547     if (provider_options || libctx)
   3548         return 0;
   3549     return 1;
   3550 }
   3551