diff options
Diffstat (limited to 'apps')
-rw-r--r-- | apps/apps.c | 270 | ||||
-rw-r--r-- | apps/apps.h | 362 | ||||
-rw-r--r-- | apps/apps_ui.c | 197 | ||||
-rw-r--r-- | apps/apps_ui.h | 28 | ||||
-rw-r--r-- | apps/build.info | 3 | ||||
-rw-r--r-- | apps/fmt.c | 15 | ||||
-rw-r--r-- | apps/fmt.h | 44 | ||||
-rw-r--r-- | apps/opt.c | 190 | ||||
-rw-r--r-- | apps/opt.h | 344 |
9 files changed, 788 insertions, 665 deletions
diff --git a/apps/apps.c b/apps/apps.c index 39535e9e4f..44a90a338c 100644 --- a/apps/apps.c +++ b/apps/apps.c @@ -54,9 +54,6 @@ typedef struct { unsigned long mask; } NAME_EX_TBL; -static UI_METHOD *ui_method = NULL; -static const UI_METHOD *ui_fallback_method = NULL; - 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, @@ -173,179 +170,12 @@ int dump_cert_text(BIO *out, X509 *x) return 0; } -static int ui_open(UI *ui) -{ - int (*opener)(UI *ui) = UI_method_get_opener(ui_fallback_method); - - if (opener) - return opener(ui); - return 1; -} - -static int ui_read(UI *ui, UI_STRING *uis) -{ - int (*reader)(UI *ui, UI_STRING *uis) = NULL; - - 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; - } - } - - reader = UI_method_get_reader(ui_fallback_method); - if (reader) - return reader(ui, uis); - return 1; -} - -static int ui_write(UI *ui, UI_STRING *uis) -{ - int (*writer)(UI *ui, UI_STRING *uis) = NULL; - - 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; - } - } - - writer = UI_method_get_writer(ui_fallback_method); - if (writer) - return writer(ui, uis); - return 1; -} - -static int ui_close(UI *ui) -{ - int (*closer)(UI *ui) = UI_method_get_closer(ui_fallback_method); - - if (closer) - return closer(ui); - return 1; -} - -int setup_ui_method(void) -{ - ui_fallback_method = UI_null(); -#ifndef OPENSSL_NO_UI_CONSOLE - ui_fallback_method = UI_OpenSSL(); -#endif - 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); - return 0; -} - -void destroy_ui_method(void) -{ - if (ui_method) { - UI_destroy_method(ui_method); - ui_method = NULL; - } -} - -const UI_METHOD *get_ui_method(void) -{ - return ui_method; -} - -int password_callback(char *buf, int bufsiz, int verify, PW_CB_DATA *cb_data) -{ - int res = 0; - UI *ui; - int ok = 0; - char *buff = NULL; - int ui_flags = 0; - const char *prompt_info = NULL; - char *prompt; - - if ((ui = UI_new_method(ui_method)) == NULL) - return 0; - - 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 == NULL) { - 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); - - 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); - return res; -} - int wrap_password_callback(char *buf, int bufsiz, int verify, void *userdata) { return password_callback(buf, bufsiz, verify, (PW_CB_DATA *)userdata); } + static char *app_get_pass(const char *arg, int keepbio); int app_passwd(const char *arg1, const char *arg2, char **pass1, char **pass2) @@ -725,7 +555,9 @@ EVP_PKEY *load_key(const char *file, int format, int maybe_stdin, } 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) { @@ -792,7 +624,8 @@ EVP_PKEY *load_pubkey(const char *file, int format, int maybe_stdin, BIO_printf(bio_err, "no engine specified\n"); } 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); @@ -1295,7 +1128,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); @@ -2321,56 +2155,10 @@ int app_access(const char* name, int flag) #endif } -/* app_isdir section */ -#ifdef _WIN32 int app_isdir(const char *name) { - DWORD attr; -# if defined(UNICODE) || defined(_UNICODE) - size_t i, len_0 = strlen(name) + 1; - WCHAR tempname[MAX_PATH]; - - if (len_0 > MAX_PATH) - return -1; - -# if !defined(_WIN32_WCE) || _WIN32_WCE>=101 - if (!MultiByteToWideChar(CP_ACP, 0, name, len_0, tempname, MAX_PATH)) -# endif - for (i = 0; i < len_0; i++) - tempname[i] = (WCHAR)name[i]; - - attr = GetFileAttributes(tempname); -# else - attr = GetFileAttributes(name); -# endif - if (attr == INVALID_FILE_ATTRIBUTES) - return -1; - return ((attr & FILE_ATTRIBUTE_DIRECTORY) != 0); + return opt_isdir(name); } -#else -# include <sys/stat.h> -# 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) @@ -2443,21 +2231,16 @@ 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)); } static BIO_METHOD *prefix_method = NULL; @@ -2465,15 +2248,15 @@ static BIO_METHOD *prefix_method = NULL; 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 (istext(format) && (prefix = getenv("HARNESS_OSSL_PREFIX")) != NULL) { + if (FMT_istext(format) && (prefix = getenv("HARNESS_OSSL_PREFIX")) != NULL) { if (prefix_method == NULL) prefix_method = apps_bf_prefix(); b = BIO_push(BIO_new(prefix_method), b); @@ -2486,9 +2269,9 @@ BIO *dup_bio_out(int format) 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; @@ -2525,11 +2308,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; @@ -2567,7 +2350,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; @@ -2746,3 +2529,14 @@ void make_uppercase(char *string) 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; +} diff --git a/apps/apps.h b/apps/apps.h index 460188df30..da8eae2d87 100644 --- a/apps/apps.h +++ b/apps/apps.h @@ -29,6 +29,9 @@ # include <openssl/engine.h> # include <openssl/ocsp.h> # include <signal.h> +# include "apps_ui.h" +# include "opt.h" +# include "fmt.h" # if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_WINCE) # define openssl_fdset(a,b) FD_SET((unsigned int)a, b) @@ -88,330 +91,6 @@ void corrupt_signature(const ASN1_STRING *signature); int set_cert_times(X509 *x, const char *startdate, const char *enddate, int days); -/* - * Common verification options. - */ -# define OPT_V_ENUM \ - OPT_V__FIRST=2000, \ - OPT_V_POLICY, OPT_V_PURPOSE, OPT_V_VERIFY_NAME, OPT_V_VERIFY_DEPTH, \ - OPT_V_ATTIME, OPT_V_VERIFY_HOSTNAME, OPT_V_VERIFY_EMAIL, \ - OPT_V_VERIFY_IP, OPT_V_IGNORE_CRITICAL, OPT_V_ISSUER_CHECKS, \ - OPT_V_CRL_CHECK, OPT_V_CRL_CHECK_ALL, OPT_V_POLICY_CHECK, \ - OPT_V_EXPLICIT_POLICY, OPT_V_INHIBIT_ANY, OPT_V_INHIBIT_MAP, \ - OPT_V_X509_STRICT, OPT_V_EXTENDED_CRL, OPT_V_USE_DELTAS, \ - OPT_V_POLICY_PRINT, OPT_V_CHECK_SS_SIG, OPT_V_TRUSTED_FIRST, \ - OPT_V_SUITEB_128_ONLY, OPT_V_SUITEB_128, OPT_V_SUITEB_192, \ - OPT_V_PARTIAL_CHAIN, OPT_V_NO_ALT_CHAINS, OPT_V_NO_CHECK_TIME, \ - OPT_V_VERIFY_AUTH_LEVEL, OPT_V_ALLOW_PROXY_CERTS, \ - OPT_V__LAST - -# define OPT_V_OPTIONS \ - { "policy", OPT_V_POLICY, 's', "adds policy to the acceptable policy set"}, \ - { "purpose", OPT_V_PURPOSE, 's', \ - "certificate chain purpose"}, \ - { "verify_name", OPT_V_VERIFY_NAME, 's', "verification policy name"}, \ - { "verify_depth", OPT_V_VERIFY_DEPTH, 'n', \ - "chain depth limit" }, \ - { "auth_level", OPT_V_VERIFY_AUTH_LEVEL, 'n', \ - "chain authentication security level" }, \ - { "attime", OPT_V_ATTIME, 'M', "verification epoch time" }, \ - { "verify_hostname", OPT_V_VERIFY_HOSTNAME, 's', \ - "expected peer hostname" }, \ - { "verify_email", OPT_V_VERIFY_EMAIL, 's', \ - "expected peer email" }, \ - { "verify_ip", OPT_V_VERIFY_IP, 's', \ - "expected peer IP address" }, \ - { "ignore_critical", OPT_V_IGNORE_CRITICAL, '-', \ - "permit unhandled critical extensions"}, \ - { "issuer_checks", OPT_V_ISSUER_CHECKS, '-', "(deprecated)"}, \ - { "crl_check", OPT_V_CRL_CHECK, '-', "check leaf certificate revocation" }, \ - { "crl_check_all", OPT_V_CRL_CHECK_ALL, '-', "check full chain revocation" }, \ - { "policy_check", OPT_V_POLICY_CHECK, '-', "perform rfc5280 policy checks"}, \ - { "explicit_policy", OPT_V_EXPLICIT_POLICY, '-', \ - "set policy variable require-explicit-policy"}, \ - { "inhibit_any", OPT_V_INHIBIT_ANY, '-', \ - "set policy variable inhibit-any-policy"}, \ - { "inhibit_map", OPT_V_INHIBIT_MAP, '-', \ - "set policy variable inhibit-policy-mapping"}, \ - { "x509_strict", OPT_V_X509_STRICT, '-', \ - "disable certificate compatibility work-arounds"}, \ - { "extended_crl", OPT_V_EXTENDED_CRL, '-', \ - "enable extended CRL features"}, \ - { "use_deltas", OPT_V_USE_DELTAS, '-', \ - "use delta CRLs"}, \ - { "policy_print", OPT_V_POLICY_PRINT, '-', \ - "print policy processing diagnostics"}, \ - { "check_ss_sig", OPT_V_CHECK_SS_SIG, '-', \ - "check root CA self-signatures"}, \ - { "trusted_first", OPT_V_TRUSTED_FIRST, '-', \ - "search trust store first (default)" }, \ - { "suiteB_128_only", OPT_V_SUITEB_128_ONLY, '-', "Suite B 128-bit-only mode"}, \ - { "suiteB_128", OPT_V_SUITEB_128, '-', \ - "Suite B 128-bit mode allowing 192-bit algorithms"}, \ - { "suiteB_192", OPT_V_SUITEB_192, '-', "Suite B 192-bit-only mode" }, \ - { "partial_chain", OPT_V_PARTIAL_CHAIN, '-', \ - "accept chains anchored by intermediate trust-store CAs"}, \ - { "no_alt_chains", OPT_V_NO_ALT_CHAINS, '-', "(deprecated)" }, \ - { "no_check_time", OPT_V_NO_CHECK_TIME, '-', "ignore certificate validity time" }, \ - { "allow_proxy_certs", OPT_V_ALLOW_PROXY_CERTS, '-', "allow the use of proxy certificates" } - -# define OPT_V_CASES \ - OPT_V__FIRST: case OPT_V__LAST: break; \ - case OPT_V_POLICY: \ - case OPT_V_PURPOSE: \ - case OPT_V_VERIFY_NAME: \ - case OPT_V_VERIFY_DEPTH: \ - case OPT_V_VERIFY_AUTH_LEVEL: \ - case OPT_V_ATTIME: \ - case OPT_V_VERIFY_HOSTNAME: \ - case OPT_V_VERIFY_EMAIL: \ - case OPT_V_VERIFY_IP: \ - case OPT_V_IGNORE_CRITICAL: \ - case OPT_V_ISSUER_CHECKS: \ - case OPT_V_CRL_CHECK: \ - case OPT_V_CRL_CHECK_ALL: \ - case OPT_V_POLICY_CHECK: \ - case OPT_V_EXPLICIT_POLICY: \ - case OPT_V_INHIBIT_ANY: \ - case OPT_V_INHIBIT_MAP: \ - case OPT_V_X509_STRICT: \ - case OPT_V_EXTENDED_CRL: \ - case OPT_V_USE_DELTAS: \ - case OPT_V_POLICY_PRINT: \ - case OPT_V_CHECK_SS_SIG: \ - case OPT_V_TRUSTED_FIRST: \ - case OPT_V_SUITEB_128_ONLY: \ - case OPT_V_SUITEB_128: \ - case OPT_V_SUITEB_192: \ - case OPT_V_PARTIAL_CHAIN: \ - case OPT_V_NO_ALT_CHAINS: \ - case OPT_V_NO_CHECK_TIME: \ - case OPT_V_ALLOW_PROXY_CERTS - -/* - * Common "extended validation" options. - */ -# define OPT_X_ENUM \ - OPT_X__FIRST=1000, \ - OPT_X_KEY, OPT_X_CERT, OPT_X_CHAIN, OPT_X_CHAIN_BUILD, \ - OPT_X_CERTFORM, OPT_X_KEYFORM, \ - OPT_X__LAST - -# define OPT_X_OPTIONS \ - { "xkey", OPT_X_KEY, '<', "key for Extended certificates"}, \ - { "xcert", OPT_X_CERT, '<', "cert for Extended certificates"}, \ - { "xchain", OPT_X_CHAIN, '<', "chain for Extended certificates"}, \ - { "xchain_build", OPT_X_CHAIN_BUILD, '-', \ - "build certificate chain for the extended certificates"}, \ - { "xcertform", OPT_X_CERTFORM, 'F', \ - "format of Extended certificate (PEM or DER) PEM default " }, \ - { "xkeyform", OPT_X_KEYFORM, 'F', \ - "format of Extended certificate's key (PEM or DER) PEM default"} - -# define OPT_X_CASES \ - OPT_X__FIRST: case OPT_X__LAST: break; \ - case OPT_X_KEY: \ - case OPT_X_CERT: \ - case OPT_X_CHAIN: \ - case OPT_X_CHAIN_BUILD: \ - case OPT_X_CERTFORM: \ - case OPT_X_KEYFORM - -/* - * Common SSL options. - * Any changes here must be coordinated with ../ssl/ssl_conf.c - */ -# define OPT_S_ENUM \ - OPT_S__FIRST=3000, \ - OPT_S_NOSSL3, OPT_S_NOTLS1, OPT_S_NOTLS1_1, OPT_S_NOTLS1_2, \ - OPT_S_NOTLS1_3, OPT_S_BUGS, OPT_S_NO_COMP, OPT_S_NOTICKET, \ - OPT_S_SERVERPREF, OPT_S_LEGACYRENEG, OPT_S_LEGACYCONN, \ - OPT_S_ONRESUMP, OPT_S_NOLEGACYCONN, OPT_S_ALLOW_NO_DHE_KEX, \ - OPT_S_PRIORITIZE_CHACHA, \ - OPT_S_STRICT, OPT_S_SIGALGS, OPT_S_CLIENTSIGALGS, OPT_S_GROUPS, \ - OPT_S_CURVES, OPT_S_NAMEDCURVE, OPT_S_CIPHER, OPT_S_CIPHERSUITES, \ - OPT_S_RECORD_PADDING, OPT_S_DEBUGBROKE, OPT_S_COMP, \ - OPT_S_MINPROTO, OPT_S_MAXPROTO, \ - OPT_S_NO_RENEGOTIATION, OPT_S_NO_MIDDLEBOX, OPT_S__LAST - -# define OPT_S_OPTIONS \ - {"no_ssl3", OPT_S_NOSSL3, '-',"Just disable SSLv3" }, \ - {"no_tls1", OPT_S_NOTLS1, '-', "Just disable TLSv1"}, \ - {"no_tls1_1", OPT_S_NOTLS1_1, '-', "Just disable TLSv1.1" }, \ - {"no_tls1_2", OPT_S_NOTLS1_2, '-', "Just disable TLSv1.2"}, \ - {"no_tls1_3", OPT_S_NOTLS1_3, '-', "Just disable TLSv1.3"}, \ - {"bugs", OPT_S_BUGS, '-', "Turn on SSL bug compatibility"}, \ - {"no_comp", OPT_S_NO_COMP, '-', "Disable SSL/TLS compression (default)" }, \ - {"comp", OPT_S_COMP, '-', "Use SSL/TLS-level compression" }, \ - {"no_ticket", OPT_S_NOTICKET, '-', \ - "Disable use of TLS session tickets"}, \ - {"serverpref", OPT_S_SERVERPREF, '-', "Use server's cipher preferences"}, \ - {"legacy_renegotiation", OPT_S_LEGACYRENEG, '-', \ - "Enable use of legacy renegotiation (dangerous)"}, \ - {"no_renegotiation", OPT_S_NO_RENEGOTIATION, '-', \ - "Disable all renegotiation."}, \ - {"legacy_server_connect", OPT_S_LEGACYCONN, '-', \ - "Allow initial connection to servers that don't support RI"}, \ - {"no_resumption_on_reneg", OPT_S_ONRESUMP, '-', \ - "Disallow session resumption on renegotiation"}, \ - {"no_legacy_server_connect", OPT_S_NOLEGACYCONN, '-', \ - "Disallow initial connection to servers that don't support RI"}, \ - {"allow_no_dhe_kex", OPT_S_ALLOW_NO_DHE_KEX, '-', \ - "In TLSv1.3 allow non-(ec)dhe based key exchange on resumption"}, \ - {"prioritize_chacha", OPT_S_PRIORITIZE_CHACHA, '-', \ - "Prioritize ChaCha ciphers when preferred by clients"}, \ - {"strict", OPT_S_STRICT, '-', \ - "Enforce strict certificate checks as per TLS standard"}, \ - {"sigalgs", OPT_S_SIGALGS, 's', \ - "Signature algorithms to support (colon-separated list)" }, \ - {"client_sigalgs", OPT_S_CLIENTSIGALGS, 's', \ - "Signature algorithms to support for client certificate" \ - " authentication (colon-separated list)" }, \ - {"groups", OPT_S_GROUPS, 's', \ - "Groups to advertise (colon-separated list)" }, \ - {"curves", OPT_S_CURVES, 's', \ - "Groups to advertise (colon-separated list)" }, \ - {"named_curve", OPT_S_NAMEDCURVE, 's', \ - "Elliptic curve used for ECDHE (server-side only)" }, \ - {"cipher", OPT_S_CIPHER, 's', "Specify TLSv1.2 and below cipher list to be used"}, \ - {"ciphersuites", OPT_S_CIPHERSUITES, 's', "Specify TLSv1.3 ciphersuites to be used"}, \ - {"min_protocol", OPT_S_MINPROTO, 's', "Specify the minimum protocol version to be used"}, \ - {"max_protocol", OPT_S_MAXPROTO, 's', "Specify the maximum protocol version to be used"}, \ - {"record_padding", OPT_S_RECORD_PADDING, 's', \ - "Block size to pad TLS 1.3 records to."}, \ - {"debug_broken_protocol", OPT_S_DEBUGBROKE, '-', \ - "Perform all sorts of protocol violations for testing purposes"}, \ - {"no_middlebox", OPT_S_NO_MIDDLEBOX, '-', \ - "Disable TLSv1.3 middlebox compat mode" } - -# define OPT_S_CASES \ - OPT_S__FIRST: case OPT_S__LAST: break; \ - case OPT_S_NOSSL3: \ - case OPT_S_NOTLS1: \ - case OPT_S_NOTLS1_1: \ - case OPT_S_NOTLS1_2: \ - case OPT_S_NOTLS1_3: \ - case OPT_S_BUGS: \ - case OPT_S_NO_COMP: \ - case OPT_S_COMP: \ - case OPT_S_NOTICKET: \ - case OPT_S_SERVERPREF: \ - case OPT_S_LEGACYRENEG: \ - case OPT_S_LEGACYCONN: \ - case OPT_S_ONRESUMP: \ - case OPT_S_NOLEGACYCONN: \ - case OPT_S_ALLOW_NO_DHE_KEX: \ - case OPT_S_PRIORITIZE_CHACHA: \ - case OPT_S_STRICT: \ - case OPT_S_SIGALGS: \ - case OPT_S_CLIENTSIGALGS: \ - case OPT_S_GROUPS: \ - case OPT_S_CURVES: \ - case OPT_S_NAMEDCURVE: \ - case OPT_S_CIPHER: \ - case OPT_S_CIPHERSUITES: \ - case OPT_S_RECORD_PADDING: \ - case OPT_S_NO_RENEGOTIATION: \ - case OPT_S_MINPROTO: \ - case OPT_S_MAXPROTO: \ - case OPT_S_DEBUGBROKE: \ - case OPT_S_NO_MIDDLEBOX - -#define IS_NO_PROT_FLAG(o) \ - (o == OPT_S_NOSSL3 || o == OPT_S_NOTLS1 || o == OPT_S_NOTLS1_1 \ - || o == OPT_S_NOTLS1_2 || o == OPT_S_NOTLS1_3) - -/* - * Random state options. - */ -# define OPT_R_ENUM \ - OPT_R__FIRST=1500, OPT_R_RAND, OPT_R_WRITERAND, OPT_R__LAST - -# define OPT_R_OPTIONS \ - {"rand", OPT_R_RAND, 's', "Load the file(s) into the random number generator"}, \ - {"writerand", OPT_R_WRITERAND, '>', "Write random data to the specified file"} - -# define OPT_R_CASES \ - OPT_R__FIRST: case OPT_R__LAST: break; \ - case OPT_R_RAND: case OPT_R_WRITERAND - -/* - * Option parsing. - */ -extern const char OPT_HELP_STR[]; -extern const char OPT_MORE_STR[]; -typedef struct options_st { - const char *name; - int retval; - /* - * value type: - no value (also the value zero), n number, p positive - * number, u unsigned, l long, s string, < input file, > output file, - * f any format, F der/pem format, E der/pem/engine format identifier. - * l, n and u include zero; p does not. - */ - int valtype; - const char *helpstr; -} OPTIONS; - -/* - * A string/int pairing; widely use for option value lookup, hence the - * name OPT_PAIR. But that name is misleading in s_cb.c, so we also use - * the "generic" name STRINT_PAIR. - */ -typedef struct string_int_pair_st { - const char *name; - int retval; -} OPT_PAIR, STRINT_PAIR; - -/* Flags to pass into opt_format; see FORMAT_xxx, below. */ -# define OPT_FMT_PEMDER (1L << 1) -# define OPT_FMT_PKCS12 (1L << 2) -# define OPT_FMT_SMIME (1L << 3) -# define OPT_FMT_ENGINE (1L << 4) -# define OPT_FMT_MSBLOB (1L << 5) -/* (1L << 6) was OPT_FMT_NETSCAPE, but wasn't used */ -# define OPT_FMT_NSS (1L << 7) -# define OPT_FMT_TEXT (1L << 8) -# define OPT_FMT_HTTP (1L << 9) -# define OPT_FMT_PVK (1L << 10) -# define OPT_FMT_PDE (OPT_FMT_PEMDER | OPT_FMT_ENGINE) -# define OPT_FMT_PDS (OPT_FMT_PEMDER | OPT_FMT_SMIME) -# define OPT_FMT_ANY ( \ - OPT_FMT_PEMDER | OPT_FMT_PKCS12 | OPT_FMT_SMIME | \ - OPT_FMT_ENGINE | OPT_FMT_MSBLOB | OPT_FMT_NSS | \ - OPT_FMT_TEXT | OPT_FMT_HTTP | OPT_FMT_PVK) - -char *opt_progname(const char *argv0); -char *opt_getprog(void); -char *opt_init(int ac, char **av, const OPTIONS * o); -int opt_next(void); -int opt_format(const char *s, unsigned long flags, int *result); -int opt_int(const char *arg, int *result); -int opt_ulong(const char *arg, unsigned long *result); -int opt_long(const char *arg, long *result); -#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L && \ - defined(INTMAX_MAX) && defined(UINTMAX_MAX) -int opt_imax(const char *arg, intmax_t *result); -int opt_umax(const char *arg, uintmax_t *result); -#else -# define opt_imax opt_long -# define opt_umax opt_ulong -# define intmax_t long -# define uintmax_t unsigned long -#endif -int opt_pair(const char *arg, const OPT_PAIR * pairs, int *result); -int opt_cipher(const char *name, const EVP_CIPHER **cipherp); -int opt_md(const char *name, const EVP_MD **mdp); -char *opt_arg(void); -char *opt_flag(void); -char *opt_unknown(void); -char **opt_rest(void); -int opt_num_rest(void); -int opt_verify(int i, X509_VERIFY_PARAM *vpm); -int opt_rand(int i); -void opt_help(const OPTIONS * list); -int opt_format_error(const char *s, unsigned long flags); - typedef struct args_st { int size; int argc; @@ -430,20 +109,8 @@ char **copy_argv(int *argc, char *argv[]); */ void win32_utf8argv(int *argc, char **argv[]); - -# define PW_MIN_LENGTH 4 -typedef struct pw_cb_data { - const void *password; - const char *prompt_info; -} PW_CB_DATA; - /* We need both wrap and the "real" function because libcrypto uses both. */ int wrap_password_callback(char *buf, int bufsiz, int verify, void *cb_data); -int password_callback(char *buf, int bufsiz, int verify, PW_CB_DATA *cb_data); - -int setup_ui_method(void); -void destroy_ui_method(void); -const UI_METHOD *get_ui_method(void); int chopup_args(ARGS *arg, char *buf); # ifdef HEADER_X509_H @@ -573,29 +240,6 @@ void print_cert_checks(BIO *bio, X509 *x, void store_setup_crl_download(X509_STORE *st); -/* See OPT_FMT_xxx, above. */ -/* On some platforms, it's important to distinguish between text and binary - * files. On some, there might even be specific file formats for different - * contents. The FORMAT_xxx macros are meant to express an intent with the - * file being read or created. - */ -# define B_FORMAT_TEXT 0x8000 -# define FORMAT_UNDEF 0 -# define FORMAT_TEXT (1 | B_FORMAT_TEXT) /* Generic text */ -# define FORMAT_BINARY 2 /* Generic binary */ -# define FORMAT_BASE64 (3 | B_FORMAT_TEXT) /* Base64 */ -# define FORMAT_ASN1 4 /* ASN.1/DER */ -# define FORMAT_PEM (5 | B_FORMAT_TEXT) -# define FORMAT_PKCS12 6 -# define FORMAT_SMIME (7 | B_FORMAT_TEXT) -# define FORMAT_ENGINE 8 /* Not really a file format */ -# define FORMAT_PEMRSA (9 | B_FORMAT_TEXT) /* PEM RSAPubicKey format */ -# define FORMAT_ASN1RSA 10 /* DER RSAPubicKey format */ -# define FORMAT_MSBLOB 11 /* MS Key blob format */ -# define FORMAT_PVK 12 /* MS PVK file format */ -# define FORMAT_HTTP 13 /* Download using HTTP */ -# define FORMAT_NSS 14 /* NSS keylog format */ - # define EXT_COPY_NONE 0 # define EXT_COPY_ADD 1 # define EXT_COPY_ALL 2 diff --git a/apps/apps_ui.c b/apps/apps_ui.c new file mode 100644 index 0000000000..bcfe555478 --- /dev/null +++ b/apps/apps_ui.c @@ -0,0 +1,197 @@ +/* + * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (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 + */ + +#include <string.h> +#include <openssl/err.h> +#include <openssl/ui.h> +#include "apps_ui.h" + +static UI_METHOD *ui_method = NULL; +static const UI_METHOD *ui_fallback_method = NULL; + + +static int ui_open(UI *ui) +{ + int (*opener)(UI *ui) = UI_method_get_opener(ui_fallback_method); + + if (opener) + return opener(ui); + return 1; +} + +static int ui_read(UI *ui, UI_STRING *uis) +{ + int (*reader)(UI *ui, UI_STRING *uis) = NULL; + + 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; + } + } + + reader = UI_method_get_reader(ui_fallback_method); + if (reader) + return reader(ui, uis); + return 1; +} + +static int ui_write(UI *ui, UI_STRING *uis) +{ + int (*writer)(UI *ui, UI_STRING *uis) = NULL; + + 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; + } + } + + writer = UI_method_get_writer(ui_fallback_method); + if (writer) + return writer(ui, uis); + return 1; +} + +static int ui_close(UI *ui) +{ + int (*closer)(UI *ui) = UI_method_get_closer(ui_fallback_method); + + if (closer) + return closer(ui); + return 1; +} + +int setup_ui_method(void) +{ + ui_fallback_method = UI_null(); +#ifndef OPENSSL_NO_UI_CONSOLE + ui_fallback_method = UI_OpenSSL(); +#endif + 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); + return 0; +} + +void destroy_ui_method(void) +{ + if (ui_method) { + UI_destroy_method(ui_method); + ui_method = NULL; + } +} + +const UI_METHOD *get_ui_method(void) +{ + return ui_method; +} + +static void *ui_malloc(int sz, const char *what) +{ + void *vp = OPENSSL_malloc(sz); + + if (vp == NULL) { + BIO_printf(bio_err, "Could not allocate %d bytes for %s\n", sz, what); + ERR_print_errors(bio_err); + exit(1); + } + return vp; +} + +int password_callback(char *buf, int bufsiz, int verify, PW_CB_DATA *cb_data) +{ + int res = 0; + UI *ui; + int ok = 0; + char *buff = NULL; + int ui_flags = 0; + const char *prompt_info = NULL; + char *prompt; + + if ((ui = UI_new_method(ui_method)) == NULL) + return 0; + + 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 == NULL) { + 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); + + ok = UI_add_input_string(ui, prompt, ui_flags, buf, + PW_MIN_LENGTH, bufsiz - 1); + + if (ok >= 0 && verify) { + buff = ui_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 && |