X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=apps%2Fapps.c;h=8921c18cbc945f59b555051753ddfea2cbb230d0;hp=d911c0f9785d24330b8e21d0584197ec3ca00313;hb=b6a07f676071b2b9fdc0e625896ebd57563028cd;hpb=57c0f378b8fdbdc55dba783e9b744b8ed2132819 diff --git a/apps/apps.c b/apps/apps.c index d911c0f978..8921c18cbc 100644 --- a/apps/apps.c +++ b/apps/apps.c @@ -1,7 +1,7 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy * in the file LICENSE in the source distribution or at * https://www.openssl.org/source/license.html @@ -18,9 +18,7 @@ #include #include #include -#ifndef NO_SYS_TYPES_H -# include -#endif +#include #ifndef OPENSSL_NO_POSIX_IO # include # include @@ -50,16 +48,14 @@ static int WIN32_rename(const char *from, const char *to); # define rename(from,to) WIN32_rename((from),(to)) #endif +#define PASS_SOURCE_SIZE_MAX 4 + typedef struct { const char *name; unsigned long flag; unsigned long mask; } NAME_EX_TBL; -#if !defined(OPENSSL_NO_UI) || !defined(OPENSSL_NO_ENGINE) -static UI_METHOD *ui_method = NULL; -#endif - static int set_table_opts(unsigned long *flags, const char *arg, const NAME_EX_TBL * in_tbl); static int set_multi_opts(unsigned long *flags, const char *arg, @@ -112,13 +108,13 @@ int chopup_args(ARGS *arg, char *buf) } } arg->argv[arg->argc] = NULL; - return (1); + return 1; } #ifndef APP_INIT int app_init(long mesgwin) { - return (1); + return 1; } #endif @@ -140,232 +136,92 @@ int ctx_set_verify_locations(SSL_CTX *ctx, const char *CAfile, int ctx_set_ctlog_list_file(SSL_CTX *ctx, const char *path) { - if (path == NULL) { + if (path == NULL) return SSL_CTX_set_default_ctlog_list_file(ctx); - } return SSL_CTX_set_ctlog_list_file(ctx, path); } #endif -int dump_cert_text(BIO *out, X509 *x) -{ - char *p; - - p = X509_NAME_oneline(X509_get_subject_name(x), NULL, 0); - BIO_puts(out, "subject="); - BIO_puts(out, p); - OPENSSL_free(p); - - p = X509_NAME_oneline(X509_get_issuer_name(x), NULL, 0); - BIO_puts(out, "\nissuer="); - BIO_puts(out, p); - BIO_puts(out, "\n"); - OPENSSL_free(p); +static unsigned long nmflag = 0; +static char nmflag_set = 0; - return 0; -} - -#ifndef OPENSSL_NO_UI -static int ui_open(UI *ui) +int set_nameopt(const char *arg) { - return UI_method_get_opener(UI_OpenSSL())(ui); -} + int ret = set_name_ex(&nmflag, arg); -static int ui_read(UI *ui, UI_STRING *uis) -{ - if (UI_get_input_flags(uis) & UI_INPUT_FLAG_DEFAULT_PWD - && UI_get0_user_data(ui)) { - switch (UI_get_string_type(uis)) { - case UIT_PROMPT: - case UIT_VERIFY: - { - const char *password = - ((PW_CB_DATA *)UI_get0_user_data(ui))->password; - if (password && password[0] != '\0') { - UI_set_result(ui, uis, password); - return 1; - } - } - break; - case UIT_NONE: - case UIT_BOOLEAN: - case UIT_INFO: - case UIT_ERROR: - break; - } - } - return UI_method_get_reader(UI_OpenSSL())(ui, uis); -} + if (ret) + nmflag_set = 1; -static int ui_write(UI *ui, UI_STRING *uis) -{ - if (UI_get_input_flags(uis) & UI_INPUT_FLAG_DEFAULT_PWD - && UI_get0_user_data(ui)) { - switch (UI_get_string_type(uis)) { - case UIT_PROMPT: - case UIT_VERIFY: - { - const char *password = - ((PW_CB_DATA *)UI_get0_user_data(ui))->password; - if (password && password[0] != '\0') - return 1; - } - break; - case UIT_NONE: - case UIT_BOOLEAN: - case UIT_INFO: - case UIT_ERROR: - break; - } - } - return UI_method_get_writer(UI_OpenSSL())(ui, uis); + return ret; } -static int ui_close(UI *ui) +unsigned long get_nameopt(void) { - return UI_method_get_closer(UI_OpenSSL())(ui); + return (nmflag_set) ? nmflag : XN_FLAG_ONELINE; } -int setup_ui_method(void) +int dump_cert_text(BIO *out, X509 *x) { - ui_method = UI_create_method("OpenSSL application user interface"); - UI_method_set_opener(ui_method, ui_open); - UI_method_set_reader(ui_method, ui_read); - UI_method_set_writer(ui_method, ui_write); - UI_method_set_closer(ui_method, ui_close); + print_name(out, "subject=", X509_get_subject_name(x), get_nameopt()); + BIO_puts(out, "\n"); + print_name(out, "issuer=", X509_get_issuer_name(x), get_nameopt()); + BIO_puts(out, "\n"); + return 0; } -void destroy_ui_method(void) +int wrap_password_callback(char *buf, int bufsiz, int verify, void *userdata) { - if (ui_method) { - UI_destroy_method(ui_method); - ui_method = NULL; - } + return password_callback(buf, bufsiz, verify, (PW_CB_DATA *)userdata); } -#endif - -int password_callback(char *buf, int bufsiz, int verify, PW_CB_DATA *cb_tmp) -{ - int res = 0; -#ifndef OPENSSL_NO_UI - UI *ui = NULL; -#endif - PW_CB_DATA *cb_data = (PW_CB_DATA *)cb_tmp; - -#ifdef OPENSSL_NO_UI - if (cb_data != NULL && cb_data->password != NULL) { - res = strlen(cb_data->password); - if (res > bufsiz) - res = bufsiz; - memcpy(buf, cb_data->password, res); - } -#else - ui = UI_new_method(ui_method); - if (ui) { - int ok = 0; - char *buff = NULL; - int ui_flags = 0; - const char *prompt_info = NULL; - char *prompt; - - if (cb_data != NULL && cb_data->prompt_info != NULL) - prompt_info = cb_data->prompt_info; - prompt = UI_construct_prompt(ui, "pass phrase", prompt_info); - if (!prompt) { - BIO_printf(bio_err, "Out of memory\n"); - UI_free(ui); - return 0; - } - - ui_flags |= UI_INPUT_FLAG_DEFAULT_PWD; - UI_ctrl(ui, UI_CTRL_PRINT_ERRORS, 1, 0, 0); - - /* We know that there is no previous user data to return to us */ - (void)UI_add_user_data(ui, cb_data); - - if (ok >= 0) - ok = UI_add_input_string(ui, prompt, ui_flags, buf, - PW_MIN_LENGTH, bufsiz - 1); - if (ok >= 0 && verify) { - buff = app_malloc(bufsiz, "password buffer"); - ok = UI_add_verify_string(ui, prompt, ui_flags, buff, - PW_MIN_LENGTH, bufsiz - 1, buf); - } - if (ok >= 0) - do { - ok = UI_process(ui); - } - while (ok < 0 && UI_ctrl(ui, UI_CTRL_IS_REDOABLE, 0, 0, 0)); - OPENSSL_clear_free(buff, (unsigned int)bufsiz); - - if (ok >= 0) - res = strlen(buf); - if (ok == -1) { - BIO_printf(bio_err, "User interface error\n"); - ERR_print_errors(bio_err); - OPENSSL_cleanse(buf, (unsigned int)bufsiz); - res = 0; - } - if (ok == -2) { - BIO_printf(bio_err, "aborted!\n"); - OPENSSL_cleanse(buf, (unsigned int)bufsiz); - res = 0; - } - UI_free(ui); - OPENSSL_free(prompt); - } -#endif - return res; -} static char *app_get_pass(const char *arg, int keepbio); int app_passwd(const char *arg1, const char *arg2, char **pass1, char **pass2) { - int same; - if (!arg2 || !arg1 || strcmp(arg1, arg2)) - same = 0; - else - same = 1; - if (arg1) { + int same = arg1 != NULL && arg2 != NULL && strcmp(arg1, arg2) == 0; + + if (arg1 != NULL) { *pass1 = app_get_pass(arg1, same); - if (!*pass1) + if (*pass1 == NULL) return 0; - } else if (pass1) + } else if (pass1 != NULL) { *pass1 = NULL; - if (arg2) { + } + if (arg2 != NULL) { *pass2 = app_get_pass(arg2, same ? 2 : 0); - if (!*pass2) + if (*pass2 == NULL) return 0; - } else if (pass2) + } else if (pass2 != NULL) { *pass2 = NULL; + } return 1; } static char *app_get_pass(const char *arg, int keepbio) { - char *tmp, tpass[APP_PASS_LEN]; static BIO *pwdbio = NULL; + char *tmp, tpass[APP_PASS_LEN]; int i; + /* PASS_SOURCE_SIZE_MAX = max number of chars before ':' in below strings */ if (strncmp(arg, "pass:", 5) == 0) return OPENSSL_strdup(arg + 5); if (strncmp(arg, "env:", 4) == 0) { tmp = getenv(arg + 4); - if (!tmp) { - BIO_printf(bio_err, "Can't read environment variable %s\n", arg + 4); + if (tmp == NULL) { + BIO_printf(bio_err, "No environment variable %s\n", arg + 4); return NULL; } return OPENSSL_strdup(tmp); } - if (!keepbio || !pwdbio) { + if (!keepbio || pwdbio == NULL) { if (strncmp(arg, "file:", 5) == 0) { pwdbio = BIO_new_file(arg + 5, "r"); - if (!pwdbio) { + if (pwdbio == NULL) { BIO_printf(bio_err, "Can't open file %s\n", arg + 5); return NULL; } @@ -400,7 +256,16 @@ static char *app_get_pass(const char *arg, int keepbio) return NULL; } } else { - BIO_printf(bio_err, "Invalid password argument \"%s\"\n", arg); + /* argument syntax error; do not reveal too much about arg */ + tmp = strchr(arg, ':'); + if (tmp == NULL || tmp - arg > PASS_SOURCE_SIZE_MAX) + BIO_printf(bio_err, + "Invalid password argument, missing ':' within the first %d chars\n", + PASS_SOURCE_SIZE_MAX + 1); + else + BIO_printf(bio_err, + "Invalid password argument, starting with \"%.*s\"\n", + (int)(tmp - arg + 1), arg); return NULL; } } @@ -414,12 +279,12 @@ static char *app_get_pass(const char *arg, int keepbio) return NULL; } tmp = strchr(tpass, '\n'); - if (tmp) + if (tmp != NULL) *tmp = 0; return OPENSSL_strdup(tpass); } -static CONF *app_load_config_(BIO *in, const char *filename) +CONF *app_load_config_bio(BIO *in, const char *filename) { long errorline = -1; CONF *conf; @@ -430,15 +295,21 @@ static CONF *app_load_config_(BIO *in, const char *filename) if (i > 0) return conf; - if (errorline <= 0) - BIO_printf(bio_err, "%s: Can't load config file \"%s\"\n", - opt_getprog(), filename); + if (errorline <= 0) { + BIO_printf(bio_err, "%s: Can't load ", opt_getprog()); + } else { + BIO_printf(bio_err, "%s: Error on line %ld of ", opt_getprog(), + errorline); + } + if (filename != NULL) + BIO_printf(bio_err, "config file \"%s\"\n", filename); else - BIO_printf(bio_err, "%s: Error on line %ld of config file \"%s\"\n", - opt_getprog(), errorline, filename); + BIO_printf(bio_err, "config input"); + NCONF_free(conf); return NULL; } + CONF *app_load_config(const char *filename) { BIO *in; @@ -448,10 +319,11 @@ CONF *app_load_config(const char *filename) if (in == NULL) return NULL; - conf = app_load_config_(in, filename); + conf = app_load_config_bio(in, filename); BIO_free(in); return conf; } + CONF *app_load_config_quiet(const char *filename) { BIO *in; @@ -461,7 +333,7 @@ CONF *app_load_config_quiet(const char *filename) if (in == NULL) return NULL; - conf = app_load_config_(in, filename); + conf = app_load_config_bio(in, filename); BIO_free(in); return conf; } @@ -512,7 +384,7 @@ int add_oid_section(CONF *conf) } static int load_pkcs12(BIO *in, const char *desc, - pem_password_cb *pem_cb, void *cb_data, + pem_password_cb *pem_cb, PW_CB_DATA *cb_data, EVP_PKEY **pkey, X509 **cert, STACK_OF(X509) **ca) { const char *pass; @@ -525,9 +397,9 @@ static int load_pkcs12(BIO *in, const char *desc, goto die; } /* See if an empty password will do */ - if (PKCS12_verify_mac(p12, "", 0) || PKCS12_verify_mac(p12, NULL, 0)) + if (PKCS12_verify_mac(p12, "", 0) || PKCS12_verify_mac(p12, NULL, 0)) { pass = ""; - else { + } else { if (!pem_cb) pem_cb = (pem_password_cb *)password_callback; len = pem_cb(tpass, PEM_BUFSIZE, 0, cb_data); @@ -588,8 +460,7 @@ static int load_cert_crl_http(const char *url, X509 **pcert, X509_CRL **pcrl) OPENSSL_free(host); OPENSSL_free(path); OPENSSL_free(port); - if (bio) - BIO_free_all(bio); + BIO_free_all(bio); OCSP_REQ_CTX_free(rctx); if (rv != 1) { BIO_printf(bio_err, "Error loading %s from %s\n", @@ -615,17 +486,18 @@ X509 *load_cert(const char *file, int format, const char *cert_descrip) if (file == NULL) { unbuffer(stdin); cert = dup_bio_in(format); - } else + } else { cert = bio_open_default(file, 'r', format); + } if (cert == NULL) goto end; - if (format == FORMAT_ASN1) + if (format == FORMAT_ASN1) { x = d2i_X509_bio(cert, NULL); - else if (format == FORMAT_PEM) + } else if (format == FORMAT_PEM) { x = PEM_read_bio_X509_AUX(cert, NULL, (pem_password_cb *)password_callback, NULL); - else if (format == FORMAT_PKCS12) { + } else if (format == FORMAT_PKCS12) { if (!load_pkcs12(cert, cert_descrip, NULL, NULL, NULL, &x, NULL)) goto end; } else { @@ -638,7 +510,7 @@ X509 *load_cert(const char *file, int format, const char *cert_descrip) ERR_print_errors(bio_err); } BIO_free(cert); - return (x); + return x; } X509_CRL *load_crl(const char *infile, int format) @@ -656,11 +528,11 @@ X509_CRL *load_crl(const char *infile, int format) in = bio_open_default(infile, 'r', format); if (in == NULL) goto end; - if (format == FORMAT_ASN1) + if (format == FORMAT_ASN1) { x = d2i_X509_CRL_bio(in, NULL); - else if (format == FORMAT_PEM) + } else if (format == FORMAT_PEM) { x = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL); - else { + } else { BIO_printf(bio_err, "bad input format specified for input crl\n"); goto end; } @@ -672,7 +544,7 @@ X509_CRL *load_crl(const char *infile, int format) end: BIO_free(in); - return (x); + return x; } EVP_PKEY *load_key(const char *file, int format, int maybe_stdin, @@ -690,12 +562,14 @@ EVP_PKEY *load_key(const char *file, int format, int maybe_stdin, goto end; } if (format == FORMAT_ENGINE) { - if (e == NULL) + if (e == NULL) { BIO_printf(bio_err, "no engine specified\n"); - else { + } else { #ifndef OPENSSL_NO_ENGINE if (ENGINE_init(e)) { - pkey = ENGINE_load_private_key(e, file, ui_method, &cb_data); + pkey = ENGINE_load_private_key(e, file, + (UI_METHOD *)get_ui_method(), + &cb_data); ENGINE_finish(e); } if (pkey == NULL) { @@ -711,31 +585,26 @@ EVP_PKEY *load_key(const char *file, int format, int maybe_stdin, if (file == NULL && maybe_stdin) { unbuffer(stdin); key = dup_bio_in(format); - } else + } else { key = bio_open_default(file, 'r', format); + } if (key == NULL) goto end; if (format == FORMAT_ASN1) { pkey = d2i_PrivateKey_bio(key, NULL); } else if (format == FORMAT_PEM) { - pkey = PEM_read_bio_PrivateKey(key, NULL, - (pem_password_cb *)password_callback, - &cb_data); - } - else if (format == FORMAT_PKCS12) { - if (!load_pkcs12(key, key_descrip, - (pem_password_cb *)password_callback, &cb_data, + pkey = PEM_read_bio_PrivateKey(key, NULL, wrap_password_callback, &cb_data); + } else if (format == FORMAT_PKCS12) { + if (!load_pkcs12(key, key_descrip, wrap_password_callback, &cb_data, &pkey, NULL, NULL)) goto end; - } #if !defined(OPENSSL_NO_RSA) && !defined(OPENSSL_NO_DSA) && !defined (OPENSSL_NO_RC4) - else if (format == FORMAT_MSBLOB) + } else if (format == FORMAT_MSBLOB) { pkey = b2i_PrivateKey_bio(key); - else if (format == FORMAT_PVK) - pkey = b2i_PVK_bio(key, (pem_password_cb *)password_callback, - &cb_data); + } else if (format == FORMAT_PVK) { + pkey = b2i_PVK_bio(key, wrap_password_callback, &cb_data); #endif - else { + } else { BIO_printf(bio_err, "bad input format specified for key file\n"); goto end; } @@ -745,7 +614,7 @@ EVP_PKEY *load_key(const char *file, int format, int maybe_stdin, BIO_printf(bio_err, "unable to load %s\n", key_descrip); ERR_print_errors(bio_err); } - return (pkey); + return pkey; } EVP_PKEY *load_pubkey(const char *file, int format, int maybe_stdin, @@ -763,11 +632,12 @@ EVP_PKEY *load_pubkey(const char *file, int format, int maybe_stdin, goto end; } if (format == FORMAT_ENGINE) { - if (e == NULL) + if (e == NULL) { BIO_printf(bio_err, "no engine specified\n"); - else { + } else { #ifndef OPENSSL_NO_ENGINE - pkey = ENGINE_load_public_key(e, file, ui_method, &cb_data); + pkey = ENGINE_load_public_key(e, file, (UI_METHOD *)get_ui_method(), + &cb_data); if (pkey == NULL) { BIO_printf(bio_err, "cannot load %s from engine\n", key_descrip); ERR_print_errors(bio_err); @@ -781,14 +651,14 @@ EVP_PKEY *load_pubkey(const char *file, int format, int maybe_stdin, if (file == NULL && maybe_stdin) { unbuffer(stdin); key = dup_bio_in(format); - } else + } else { key = bio_open_default(file, 'r', format); + } if (key == NULL) goto end; if (format == FORMAT_ASN1) { pkey = d2i_PUBKEY_bio(key, NULL); - } - else if (format == FORMAT_ASN1RSA) { + } else if (format == FORMAT_ASN1RSA) { #ifndef OPENSSL_NO_RSA RSA *rsa; rsa = d2i_RSAPublicKey_bio(key, NULL); @@ -818,21 +688,20 @@ EVP_PKEY *load_pubkey(const char *file, int format, int maybe_stdin, BIO_printf(bio_err, "RSA keys not supported\n"); #endif pkey = NULL; - } - else if (format == FORMAT_PEM) { + } else if (format == FORMAT_PEM) { pkey = PEM_read_bio_PUBKEY(key, NULL, (pem_password_cb *)password_callback, &cb_data); - } #if !defined(OPENSSL_NO_RSA) && !defined(OPENSSL_NO_DSA) - else if (format == FORMAT_MSBLOB) + } else if (format == FORMAT_MSBLOB) { pkey = b2i_PublicKey_bio(key); #endif + } end: BIO_free(key); if (pkey == NULL) BIO_printf(bio_err, "unable to load %s\n", key_descrip); - return (pkey); + return pkey; } static int load_certs_crls(const char *file, int format, @@ -865,36 +734,36 @@ static int load_certs_crls(const char *file, int format, BIO_free(bio); - if (pcerts && *pcerts == NULL) { + if (pcerts != NULL && *pcerts == NULL) { *pcerts = sk_X509_new_null(); - if (!*pcerts) + if (*pcerts == NULL) goto end; } - if (pcrls && *pcrls == NULL) { + if (pcrls != NULL && *pcrls == NULL) { *pcrls = sk_X509_CRL_new_null(); - if (!*pcrls) + if (*pcrls == NULL) goto end; } for (i = 0; i < sk_X509_INFO_num(xis); i++) { xi = sk_X509_INFO_value(xis, i); - if (xi->x509 && pcerts) { + if (xi->x509 != NULL && pcerts != NULL) { if (!sk_X509_push(*pcerts, xi->x509)) goto end; xi->x509 = NULL; } - if (xi->crl && pcrls) { + if (xi->crl != NULL && pcrls != NULL) { if (!sk_X509_CRL_push(*pcrls, xi->crl)) goto end; xi->crl = NULL; } } - if (pcerts && sk_X509_num(*pcerts) > 0) + if (pcerts != NULL && sk_X509_num(*pcerts) > 0) rv = 1; - if (pcrls && sk_X509_CRL_num(*pcrls) > 0) + if (pcrls != NULL && sk_X509_CRL_num(*pcrls) > 0) rv = 1; end: @@ -902,11 +771,11 @@ static int load_certs_crls(const char *file, int format, sk_X509_INFO_pop_free(xis, X509_INFO_free); if (rv == 0) { - if (pcerts) { + if (pcerts != NULL) { sk_X509_pop_free(*pcerts, X509_free); *pcerts = NULL; } - if (pcrls) { + if (pcrls != NULL) { sk_X509_CRL_pop_free(*pcrls, X509_CRL_free); *pcrls = NULL; } @@ -1022,7 +891,8 @@ int set_name_ex(unsigned long *flags, const char *arg) }; if (set_multi_opts(flags, arg, ex_tbl) == 0) return 0; - if ((*flags & XN_FLAG_SEP_MASK) == 0) + if (*flags != XN_FLAG_COMPAT + && (*flags & XN_FLAG_SEP_MASK) == 0) *flags |= XN_FLAG_SEP_CPLUS_SPC; return 1; } @@ -1111,8 +981,9 @@ static int set_table_opts(unsigned long *flags, const char *arg, } else if (c == '+') { c = 1; arg++; - } else + } else { c = 1; + } for (ptbl = in_tbl; ptbl->name; ptbl++) { if (strcasecmp(arg, ptbl->name) == 0) { @@ -1157,23 +1028,23 @@ void print_bignum_var(BIO *out, const BIGNUM *in, const char *var, int len, unsigned char *buffer) { BIO_printf(out, " static unsigned char %s_%d[] = {", var, len); - if (BN_is_zero(in)) - BIO_printf(out, "\n\t0x00"); - else { + if (BN_is_zero(in)) { + BIO_printf(out, "\n 0x00"); + } else { int i, l; l = BN_bn2bin(in, buffer); for (i = 0; i < l; i++) { - if ((i % 10) == 0) - BIO_printf(out, "\n\t"); + BIO_printf(out, (i % 10) == 0 ? "\n " : " "); if (i < l - 1) - BIO_printf(out, "0x%02X, ", buffer[i]); + BIO_printf(out, "0x%02X,", buffer[i]); else BIO_printf(out, "0x%02X", buffer[i]); } } BIO_printf(out, "\n };\n"); } + void print_array(BIO *out, const char* title, int len, const unsigned char* d) { int i; @@ -1207,8 +1078,9 @@ X509_STORE *setup_verify(const char *CAfile, const char *CApath, int noCAfile, i BIO_printf(bio_err, "Error loading file %s\n", CAfile); goto end; } - } else + } else { X509_LOOKUP_load_file(lookup, NULL, X509_FILETYPE_DEFAULT); + } } if (CApath != NULL || !noCApath) { @@ -1220,8 +1092,9 @@ X509_STORE *setup_verify(const char *CAfile, const char *CApath, int noCAfile, i BIO_printf(bio_err, "Error loading directory %s\n", CApath); goto end; } - } else + } else { X509_LOOKUP_add_dir(lookup, NULL, X509_FILETYPE_DEFAULT); + } } ERR_clear_error(); @@ -1252,7 +1125,7 @@ ENGINE *setup_engine(const char *engine, int debug) ENGINE *e = NULL; #ifndef OPENSSL_NO_ENGINE - if (engine) { + if (engine != NULL) { if (strcmp(engine, "auto") == 0) { BIO_printf(bio_err, "enabling auto ENGINE support\n"); ENGINE_register_all_complete(); @@ -1267,7 +1140,8 @@ ENGINE *setup_engine(const char *engine, int debug) if (debug) { ENGINE_ctrl(e, ENGINE_CTRL_SET_LOGSTREAM, 0, bio_err, 0); } - ENGINE_ctrl_cmd(e, "SET_USER_INTERFACE", 0, ui_method, 0, 1); + ENGINE_ctrl_cmd(e, "SET_USER_INTERFACE", 0, (void *)get_ui_method(), + 0, 1); if (!ENGINE_set_default(e, ENGINE_METHOD_ALL)) { BIO_printf(bio_err, "can't use that engine\n"); ERR_print_errors(bio_err); @@ -1307,7 +1181,7 @@ static int index_serial_cmp(const OPENSSL_CSTRING *a, for (aa = a[DB_serial]; *aa == '0'; aa++) ; for (bb = b[DB_serial]; *bb == '0'; bb++) ; - return (strcmp(aa, bb)); + return strcmp(aa, bb); } static int index_name_qual(char **a) @@ -1322,7 +1196,7 @@ static unsigned long index_name_hash(const OPENSSL_CSTRING *a) int index_name_cmp(const OPENSSL_CSTRING *a, const OPENSSL_CSTRING *b) { - return (strcmp(a[DB_name], b[DB_name])); + return strcmp(a[DB_name], b[DB_name]); } static IMPLEMENT_LHASH_HASH_FN(index_serial, OPENSSL_CSTRING) @@ -1373,7 +1247,7 @@ BIGNUM *load_serial(const char *serialfile, int create, ASN1_INTEGER **retai) err: BIO_free(in); ASN1_INTEGER_free(ai); - return (ret); + return ret; } int save_serial(const char *serialfile, const char *suffix, const BIGNUM *serial, @@ -1398,9 +1272,9 @@ int save_serial(const char *serialfile, const char *suffix, const BIGNUM *serial OPENSSL_strlcpy(buf[0], serialfile, BSIZE); else { #ifndef OPENSSL_SYS_VMS - j = BIO_snprintf(buf[0], sizeof buf[0], "%s.%s", serialfile, suffix); + j = BIO_snprintf(buf[0], sizeof(buf[0]), "%s.%s", serialfile, suffix); #else - j = BIO_snprintf(buf[0], sizeof buf[0], "%s-%s", serialfile, suffix); + j = BIO_snprintf(buf[0], sizeof(buf[0]), "%s-%s", serialfile, suffix); #endif } out = BIO_new_file(buf[0], "w"); @@ -1423,7 +1297,7 @@ int save_serial(const char *serialfile, const char *suffix, const BIGNUM *serial err: BIO_free_all(out); ASN1_INTEGER_free(ai); - return (ret); + return ret; } int rotate_serial(const char *serialfile, const char *new_suffix, @@ -1441,11 +1315,11 @@ int rotate_serial(const char *serialfile, const char *new_suffix, goto err; } #ifndef OPENSSL_SYS_VMS - j = BIO_snprintf(buf[0], sizeof buf[0], "%s.%s", serialfile, new_suffix); - j = BIO_snprintf(buf[1], sizeof buf[1], "%s.%s", serialfile, old_suffix); + j = BIO_snprintf(buf[0], sizeof(buf[0]), "%s.%s", serialfile, new_suffix); + j = BIO_snprintf(buf[1], sizeof(buf[1]), "%s.%s", serialfile, old_suffix); #else - j = BIO_snprintf(buf[0], sizeof buf[0], "%s-%s", serialfile, new_suffix); - j = BIO_snprintf(buf[1], sizeof buf[1], "%s-%s", serialfile, old_suffix); + j = BIO_snprintf(buf[0], sizeof(buf[0]), "%s-%s", serialfile, new_suffix); + j = BIO_snprintf(buf[1], sizeof(buf[1]), "%s-%s", serialfile, old_suffix); #endif if (rename(serialfile, buf[1]) < 0 && errno != ENOENT #ifdef ENOTDIR @@ -1474,15 +1348,11 @@ int rand_serial(BIGNUM *b, ASN1_INTEGER *ai) BIGNUM *btmp; int ret = 0; - if (b) - btmp = b; - else - btmp = BN_new(); - + btmp = b == NULL ? BN_new() : b; if (btmp == NULL) return 0; - if (!BN_pseudo_rand(btmp, SERIAL_RAND_BITS, 0, 0)) + if (!BN_rand(btmp, SERIAL_RAND_BITS, BN_RAND_TOP_ANY, BN_RAND_BOTTOM_ANY)) goto error; if (ai && !BN_to_ASN1_INTEGER(btmp, ai)) goto error; @@ -1504,21 +1374,36 @@ CA_DB *load_index(const char *dbfile, DB_ATTR *db_attr) BIO *in; CONF *dbattr_conf = NULL; char buf[BSIZE]; +#ifndef OPENSSL_NO_POSIX_IO + FILE *dbfp; + struct stat dbst; +#endif in = BIO_new_file(dbfile, "r"); if (in == NULL) { ERR_print_errors(bio_err); goto err; } + +#ifndef OPENSSL_NO_POSIX_IO + BIO_get_fp(in, &dbfp); + if (fstat(fileno(dbfp), &dbst) == -1) { + SYSerr(SYS_F_FSTAT, errno); + ERR_add_error_data(3, "fstat('", dbfile, "')"); + ERR_print_errors(bio_err); + goto err; + } +#endif + if ((tmpdb = TXT_DB_read(in, DB_NUMBER)) == NULL) goto err; #ifndef OPENSSL_SYS_VMS - BIO_snprintf(buf, sizeof buf, "%s.attr", dbfile); + BIO_snprintf(buf, sizeof(buf), "%s.attr", dbfile); #else - BIO_snprintf(buf, sizeof buf, "%s-attr", dbfile); + BIO_snprintf(buf, sizeof(buf), "%s-attr", dbfile); #endif - dbattr_conf = app_load_config(buf); + dbattr_conf = app_load_config_quiet(buf); retdb = app_malloc(sizeof(*retdb), "new DB"); retdb->db = tmpdb; @@ -1536,6 +1421,11 @@ CA_DB *load_index(const char *dbfile, DB_ATTR *db_attr) } } + retdb->dbfname = OPENSSL_strdup(dbfile); +#ifndef OPENSSL_NO_POSIX_IO + retdb->dbst = dbst; +#endif + err: NCONF_free(dbattr_conf); TXT_DB_free(tmpdb); @@ -1543,6 +1433,9 @@ CA_DB *load_index(const char *dbfile, DB_ATTR *db_attr) return retdb; } +/* + * Returns > 0 on success, <= 0 on error + */ int index_index(CA_DB *db) { if (!TXT_DB_create_index(db->db, DB_serial, NULL, @@ -1577,13 +1470,13 @@ int save_index(const char *dbfile, const char *suffix, CA_DB *db) goto err; } #ifndef OPENSSL_SYS_VMS - j = BIO_snprintf(buf[2], sizeof buf[2], "%s.attr", dbfile); - j = BIO_snprintf(buf[1], sizeof buf[1], "%s.attr.%s", dbfile, suffix); - j = BIO_snprintf(buf[0], sizeof buf[0], "%s.%s", dbfile, suffix); + j = BIO_snprintf(buf[2], sizeof(buf[2]), "%s.attr", dbfile); + j = BIO_snprintf(buf[1], sizeof(buf[1]), "%s.attr.%s", dbfile, suffix); + j = BIO_snprintf(buf[0], sizeof(buf[0]), "%s.%s", dbfile, suffix); #else - j = BIO_snprintf(buf[2], sizeof buf[2], "%s-attr", dbfile); - j = BIO_snprintf(buf[1], sizeof buf[1], "%s-attr-%s", dbfile, suffix); - j = BIO_snprintf(buf[0], sizeof buf[0], "%s-%s", dbfile, suffix); + j = BIO_snprintf(buf[2], sizeof(buf[2]), "%s-attr", dbfile); + j = BIO_snprintf(buf[1], sizeof(buf[1]), "%s-attr-%s", dbfile, suffix); + j = BIO_snprintf(buf[0], sizeof(buf[0]), "%s-%s", dbfile, suffix); #endif out = BIO_new_file(buf[0], "w"); if (out == NULL) { @@ -1626,17 +1519,17 @@ int rotate_index(const char *dbfile, const char *new_suffix, goto err; } #ifndef OPENSSL_SYS_VMS - j = BIO_snprintf(buf[4], sizeof buf[4], "%s.attr", dbfile); - j = BIO_snprintf(buf[3], sizeof buf[3], "%s.attr.%s", dbfile, old_suffix); - j = BIO_snprintf(buf[2], sizeof buf[2], "%s.attr.%s", dbfile, new_suffix); - j = BIO_snprintf(buf[1], sizeof buf[1], "%s.%s", dbfile, old_suffix); - j = BIO_snprintf(buf[0], sizeof buf[0], "%s.%s", dbfile, new_suffix); + j = BIO_snprintf(buf[4], sizeof(buf[4]), "%s.attr", dbfile); + j = BIO_snprintf(buf[3], sizeof(buf[3]), "%s.attr.%s", dbfile, old_suffix); + j = BIO_snprintf(buf[2], sizeof(buf[2]), "%s.attr.%s", dbfile, new_suffix); + j = BIO_snprintf(buf[1], sizeof(buf[1]), "%s.%s", dbfile, old_suffix); + j = BIO_snprintf(buf[0], sizeof(buf[0]), "%s.%s", dbfile, new_suffix); #else - j = BIO_snprintf(buf[4], sizeof buf[4], "%s-attr", dbfile); - j = BIO_snprintf(buf[3], sizeof buf[3], "%s-attr-%s", dbfile, old_suffix); - j = BIO_snprintf(buf[2], sizeof buf[2], "%s-attr-%s", dbfile, new_suffix); - j = BIO_snprintf(buf[1], sizeof buf[1], "%s-%s", dbfile, old_suffix); - j = BIO_snprintf(buf[0], sizeof buf[0], "%s-%s", dbfile, new_suffix); + j = BIO_snprintf(buf[4], sizeof(buf[4]), "%s-attr", dbfile); + j = BIO_snprintf(buf[3], sizeof(buf[3]), "%s-attr-%s", dbfile, old_suffix); + j = BIO_snprintf(buf[2], sizeof(buf[2]), "%s-attr-%s", dbfile, new_suffix); + j = BIO_snprintf(buf[1], sizeof(buf[1]), "%s-%s", dbfile, old_suffix); + j = BIO_snprintf(buf[0], sizeof(buf[0]), "%s-%s", dbfile, new_suffix); #endif if (rename(dbfile, buf[1]) < 0 && errno != ENOENT #ifdef ENOTDIR @@ -1681,6 +1574,7 @@ void free_index(CA_DB *db) { if (db) { TXT_DB_free(db->db); + OPENSSL_free(db->dbfname); OPENSSL_free(db); } } @@ -1716,15 +1610,23 @@ X509_NAME *parse_name(const char *cp, long chtype, int canmulti) char *work; X509_NAME *n; - if (*cp++ != '/') + if (*cp++ != '/') { + BIO_printf(bio_err, + "name is expected to be in the format " + "/type0=value0/type1=value1/type2=... where characters may " + "be escaped by \\. This name is not in that format: '%s'\n", + --cp); return NULL; + } n = X509_NAME_new(); if (n == NULL) return NULL; work = OPENSSL_strdup(cp); - if (work == NULL) + if (work == NULL) { + BIO_printf(bio_err, "%s: Error copying name input\n", opt_getprog()); goto err; + } while (*cp) { char *bp = work; @@ -1739,7 +1641,7 @@ X509_NAME *parse_name(const char *cp, long chtype, int canmulti) *bp++ = *cp++; if (*cp == '\0') { BIO_printf(bio_err, - "%s: Hit end of string before finding the equals.\n", + "%s: Hit end of string before finding the '='\n", opt_getprog()); goto err; } @@ -1755,8 +1657,8 @@ X509_NAME *parse_name(const char *cp, long chtype, int canmulti) } if (*cp == '\\' && *++cp == '\0') { BIO_printf(bio_err, - "%s: escape character at end of string\n", - opt_getprog()); + "%s: escape character at end of string\n", + opt_getprog()); goto err; } } @@ -1770,13 +1672,22 @@ X509_NAME *parse_name(const char *cp, long chtype, int canmulti) nid = OBJ_txt2nid(typestr); if (nid == NID_undef) { BIO_printf(bio_err, "%s: Skipping unknown attribute \"%s\"\n", - opt_getprog(), typestr); + opt_getprog(), typestr); + continue; + } + if (*valstr == '\0') { + BIO_printf(bio_err, + "%s: No value provided for Subject Attribute %s, skipped\n", + opt_getprog(), typestr); continue; } if (!X509_NAME_add_entry_by_NID(n, nid, chtype, valstr, strlen((char *)valstr), - -1, ismulti ? -1 : 0)) + -1, ismulti ? -1 : 0)) { + BIO_printf(bio_err, "%s: Error adding name attribute \"/%s=%s\"\n", + opt_getprog(), typestr ,valstr); goto err; + } } OPENSSL_free(work); @@ -1858,8 +1769,9 @@ static void nodes_print(const char *name, STACK_OF(X509_POLICY_NODE) *nodes) node = sk_X509_POLICY_NODE_value(nodes, i); X509_POLICY_NODE_print(bio_err, node, 2); } - } else + } else { BIO_puts(bio_err, " \n"); + } } void policies_print(X509_STORE_CTX *ctx) @@ -1902,10 +1814,11 @@ unsigned char *next_protos_parse(size_t *outlen, const char *in) OPENSSL_free(out); return NULL; } - out[start] = i - start; + out[start] = (unsigned char)(i - start); start = i + 1; - } else + } else { out[i + 1] = in[i]; + } } *outlen = len + 1; @@ -2128,9 +2041,9 @@ double app_tminterval(int stop, int usertime) ret = (__int64)(tmstop.QuadPart - tmstart.QuadPart) * 1e-7; } - return (ret); + return ret; } -#elif defined(OPENSSL_SYSTEM_VXWORKS) +#elif defined(OPENSSL_SYS_VXWORKS) # include double app_tminterval(int stop, int usertime) @@ -2164,7 +2077,7 @@ double app_tminterval(int stop, int usertime) else ret = (now - tmstart) / (double)sysClkRateGet(); # endif - return (ret); + return ret; } #elif defined(OPENSSL_SYSTEM_VMS) @@ -2198,7 +2111,7 @@ double app_tminterval(int stop, int usertime) else ret = (now - tmstart) / (double)(CLK_TCK); - return (ret); + return ret; } #elif defined(_SC_CLK_TCK) /* by means of unistd.h */ @@ -2214,14 +2127,14 @@ double app_tminterval(int stop, int usertime) if (usertime) now = rus.tms_utime; - if (stop == TM_START) + if (stop == TM_START) { tmstart = now; - else { + } else { long int tck = sysconf(_SC_CLK_TCK); ret = (now - tmstart) / (double)tck; } - return (ret); + return ret; } #else @@ -2259,58 +2172,10 @@ int app_access(const char* name, int flag) #endif } -/* app_isdir section */ -#ifdef _WIN32 int app_isdir(const char *name) { - HANDLE hList; - WIN32_FIND_DATA FileData; -# if defined(UNICODE) || defined(_UNICODE) - size_t i, len_0 = strlen(name) + 1; - - if (len_0 > OSSL_NELEM(FileData.cFileName)) - return -1; - -# if !defined(_WIN32_WCE) || _WIN32_WCE>=101 - if (!MultiByteToWideChar - (CP_ACP, 0, name, len_0, FileData.cFileName, len_0)) -# endif - for (i = 0; i < len_0; i++) - FileData.cFileName[i] = (WCHAR)name[i]; - - hList = FindFirstFile(FileData.cFileName, &FileData); -# else - hList = FindFirstFile(name, &FileData); -# endif - if (hList == INVALID_HANDLE_VALUE) - return -1; - FindClose(hList); - return ((FileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0); + return opt_isdir(name); } -#else -# include -# ifndef S_ISDIR -# if defined(_S_IFMT) && defined(_S_IFDIR) -# define S_ISDIR(a) (((a) & _S_IFMT) == _S_IFDIR) -# else -# define S_ISDIR(a) (((a) & S_IFMT) == S_IFDIR) -# endif -# endif - -int app_isdir(const char *name) -{ -# if defined(S_ISDIR) - struct stat st; - - if (stat(name, &st) == 0) - return S_ISDIR(st.st_mode); - else - return -1; -# else - return -1; -# endif -} -#endif /* raw_read|write section */ #if defined(__VMS) @@ -2348,12 +2213,12 @@ int raw_read_stdin(void *buf, int siz) { DWORD n; if (ReadFile(GetStdHandle(STD_INPUT_HANDLE), buf, siz, &n, NULL)) - return (n); + return n; else - return (-1); + return -1; } #elif defined(__VMS) -#include +# include int raw_read_stdin(void *buf, int siz) { @@ -2371,9 +2236,9 @@ int raw_write_stdout(const void *buf, int siz) { DWORD n; if (WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), buf, siz, &n, NULL)) - return (n); + return n; else - return (-1); + return -1; } #else int raw_write_stdout(const void *buf, int siz) @@ -2383,45 +2248,60 @@ int raw_write_stdout(const void *buf, int siz) #endif /* - * Centralized handling if input and output files with format specification + * Centralized handling of input and output files with format specification * The format is meant to show what the input and output is supposed to be, * and is therefore a show of intent more than anything else. However, it - * does impact behavior on some platform, such as differentiating between + * does impact behavior on some platforms, such as differentiating between * text and binary input/output on non-Unix platforms */ -static int istext(int format) -{ - return (format & B_FORMAT_TEXT) == B_FORMAT_TEXT; -} - BIO *dup_bio_in(int format) { return BIO_new_fp(stdin, - BIO_NOCLOSE | (istext(format) ? BIO_FP_TEXT : 0)); + BIO_NOCLOSE | (FMT_istext(format) ? BIO_FP_TEXT : 0)); } BIO *dup_bio_out(int format) { BIO *b = BIO_new_fp(stdout, - BIO_NOCLOSE | (istext(format) ? BIO_FP_TEXT : 0)); + BIO_NOCLOSE | (FMT_istext(format) ? BIO_FP_TEXT : 0)); + void *prefix = NULL; + #ifdef OPENSSL_SYS_VMS - if (istext(format)) + if (FMT_istext(format)) b = BIO_push(BIO_new(BIO_f_linebuffer()), b); #endif + + if (FMT_istext(format) + && (prefix = getenv("HARNESS_OSSL_PREFIX")) != NULL) { + b = BIO_push(BIO_new(apps_bf_prefix()), b); + BIO_ctrl(b, PREFIX_CTRL_SET_PREFIX, 0, prefix); + } + return b; } BIO *dup_bio_err(int format) { BIO *b = BIO_new_fp(stderr, - BIO_NOCLOSE | (istext(format) ? BIO_FP_TEXT : 0)); + BIO_NOCLOSE | (FMT_istext(format) ? BIO_FP_TEXT : 0)); #ifdef OPENSSL_SYS_VMS - if (istext(format)) + if (FMT_istext(format)) b = BIO_push(BIO_new(BIO_f_linebuffer()), b); #endif return b; } +/* + * Because the prefix method is created dynamically, we must also be able + * to destroy it. + */ +void destroy_prefix_method(void) +{ + BIO_METHOD *prefix_method = apps_bf_prefix(); + BIO_meth_free(prefix_method); + prefix_method = NULL; +} + void unbuffer(FILE *fp) { /* @@ -2447,11 +2327,11 @@ static const char *modestr(char mode, int format) switch (mode) { case 'a': - return istext(format) ? "a" : "ab"; + return FMT_istext(format) ? "a" : "ab"; case 'r': - return istext(format) ? "r" : "rb"; + return FMT_istext(format) ? "r" : "rb"; case 'w': - return istext(format) ? "w" : "wb"; + return FMT_istext(format) ? "w" : "wb"; } /* The assert above should make sure we never reach this point */ return NULL; @@ -2489,7 +2369,7 @@ BIO *bio_open_owner(const char *filename, int format, int private) #ifdef O_TRUNC mode |= O_TRUNC; #endif - textmode = istext(format); + textmode = FMT_istext(format); if (!textmode) { #ifdef O_BINARY mode |= O_BINARY; @@ -2583,6 +2463,7 @@ void wait_for_async(SSL *s) fd_set asyncfds; OSSL_ASYNC_FD *fds; size_t numfds; + size_t i; if (!SSL_get_all_async_fds(s, NULL, &numfds)) return; @@ -2591,17 +2472,17 @@ void wait_for_async(SSL *s) fds = app_malloc(sizeof(OSSL_ASYNC_FD) * numfds, "allocate async fds"); if (!SSL_get_all_async_fds(s, fds, &numfds)) { OPENSSL_free(fds); + return; } FD_ZERO(&asyncfds); - while (numfds > 0) { - if (width <= (int)*fds) - width = (int)*fds + 1; - openssl_fdset((int)*fds, &asyncfds); - numfds--; - fds++; + for (i = 0; i < numfds; i++) { + if (width <= (int)fds[i]) + width = (int)fds[i] + 1; + openssl_fdset((int)fds[i], &asyncfds); } select(width, (void *)&asyncfds, NULL, NULL, NULL); + OPENSSL_free(fds); #endif } @@ -2647,15 +2528,34 @@ int set_cert_times(X509 *x, const char *startdate, const char *enddate, if (X509_gmtime_adj(X509_getm_notBefore(x), 0) == NULL) return 0; } else { - if (!ASN1_TIME_set_string(X509_getm_notBefore(x), startdate)) + if (!ASN1_TIME_set_string_X509(X509_getm_notBefore(x), startdate)) return 0; } if (enddate == NULL) { if (X509_time_adj_ex(X509_getm_notAfter(x), days, 0, NULL) == NULL) return 0; - } else if (!ASN1_TIME_set_string(X509_getm_notAfter(x), enddate)) { + } else if (!ASN1_TIME_set_string_X509(X509_getm_notAfter(x), enddate)) { return 0; } return 1; } + +void make_uppercase(char *string) +{ + int i; + + for (i = 0; string[i] != '\0'; i++) + string[i] = toupper((unsigned char)string[i]); +} + +int opt_printf_stderr(const char *fmt, ...) +{ + va_list ap; + int ret; + + va_start(ap, fmt); + ret = BIO_vprintf(bio_err, fmt, ap); + va_end(ap); + return ret; +}