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