Path: blob/main/crypto/openssl/apps/lib/apps_ui.c
103954 views
/*1* Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.2*3* Licensed under the Apache License 2.0 (the "License"). You may not use4* this file except in compliance with the License. You can obtain a copy5* in the file LICENSE in the source distribution or at6* https://www.openssl.org/source/license.html7*/89#include <string.h>10#include <openssl/err.h>11#include <openssl/ui.h>12#include "apps_ui.h"1314static UI_METHOD *ui_method = NULL;15static const UI_METHOD *ui_base_method = NULL;1617static int ui_open(UI *ui)18{19int (*opener)(UI *ui) = UI_method_get_opener(ui_base_method);2021if (opener != NULL)22return opener(ui);23return 1;24}2526static int ui_read(UI *ui, UI_STRING *uis)27{28int (*reader)(UI *ui, UI_STRING *uis) = NULL;2930if (UI_get_input_flags(uis) & UI_INPUT_FLAG_DEFAULT_PWD31&& UI_get0_user_data(ui)) {32switch (UI_get_string_type(uis)) {33case UIT_PROMPT:34case UIT_VERIFY: {35const char *password = ((PW_CB_DATA *)UI_get0_user_data(ui))->password;3637if (password != NULL) {38UI_set_result(ui, uis, password);39return 1;40}41} break;42case UIT_NONE:43case UIT_BOOLEAN:44case UIT_INFO:45case UIT_ERROR:46break;47}48}4950reader = UI_method_get_reader(ui_base_method);51if (reader != NULL)52return reader(ui, uis);53/* Default to the empty password if we've got nothing better */54UI_set_result(ui, uis, "");55return 1;56}5758static int ui_write(UI *ui, UI_STRING *uis)59{60int (*writer)(UI *ui, UI_STRING *uis) = NULL;6162if (UI_get_input_flags(uis) & UI_INPUT_FLAG_DEFAULT_PWD63&& UI_get0_user_data(ui)) {64switch (UI_get_string_type(uis)) {65case UIT_PROMPT:66case UIT_VERIFY: {67const char *password = ((PW_CB_DATA *)UI_get0_user_data(ui))->password;6869if (password != NULL)70return 1;71} break;72case UIT_NONE:73case UIT_BOOLEAN:74case UIT_INFO:75case UIT_ERROR:76break;77}78}7980writer = UI_method_get_writer(ui_base_method);81if (writer != NULL)82return writer(ui, uis);83return 1;84}8586static int ui_close(UI *ui)87{88int (*closer)(UI *ui) = UI_method_get_closer(ui_base_method);8990if (closer != NULL)91return closer(ui);92return 1;93}9495/* object_name defaults to prompt_info from ui user data if present */96static char *ui_prompt_construct(UI *ui, const char *phrase_desc,97const char *object_name)98{99PW_CB_DATA *cb_data = (PW_CB_DATA *)UI_get0_user_data(ui);100101if (phrase_desc == NULL)102phrase_desc = "pass phrase";103if (object_name == NULL && cb_data != NULL)104object_name = cb_data->prompt_info;105return UI_construct_prompt(NULL, phrase_desc, object_name);106}107108int set_base_ui_method(const UI_METHOD *ui_meth)109{110if (ui_meth == NULL)111ui_meth = UI_null();112ui_base_method = ui_meth;113return 1;114}115116int setup_ui_method(void)117{118ui_base_method = UI_null();119#ifndef OPENSSL_NO_UI_CONSOLE120ui_base_method = UI_OpenSSL();121#endif122ui_method = UI_create_method("OpenSSL application user interface");123return ui_method != NULL124&& 0 == UI_method_set_opener(ui_method, ui_open)125&& 0 == UI_method_set_reader(ui_method, ui_read)126&& 0 == UI_method_set_writer(ui_method, ui_write)127&& 0 == UI_method_set_closer(ui_method, ui_close)128&& 0 == UI_method_set_prompt_constructor(ui_method, ui_prompt_construct);129}130131void destroy_ui_method(void)132{133if (ui_method != NULL) {134UI_destroy_method(ui_method);135ui_method = NULL;136}137}138139const UI_METHOD *get_ui_method(void)140{141return ui_method;142}143144static void *ui_malloc(int sz, const char *what)145{146void *vp = OPENSSL_malloc(sz);147148if (vp == NULL) {149BIO_printf(bio_err, "Could not allocate %d bytes for %s\n", sz, what);150ERR_print_errors(bio_err);151exit(1);152}153return vp;154}155156int password_callback(char *buf, int bufsiz, int verify, PW_CB_DATA *cb_data)157{158int res = 0;159UI *ui;160int ok = 0;161char *buff = NULL;162int ui_flags = 0;163const char *prompt_info = NULL;164char *prompt;165166if ((ui = UI_new_method(ui_method)) == NULL)167return 0;168169if (cb_data != NULL && cb_data->prompt_info != NULL)170prompt_info = cb_data->prompt_info;171prompt = UI_construct_prompt(ui, "pass phrase", prompt_info);172if (prompt == NULL) {173BIO_printf(bio_err, "Out of memory\n");174UI_free(ui);175return 0;176}177178ui_flags |= UI_INPUT_FLAG_DEFAULT_PWD;179UI_ctrl(ui, UI_CTRL_PRINT_ERRORS, 1, 0, 0);180181/* We know that there is no previous user data to return to us */182(void)UI_add_user_data(ui, cb_data);183184ok = UI_add_input_string(ui, prompt, ui_flags, buf,185PW_MIN_LENGTH, bufsiz - 1);186187if (ok >= 0 && verify) {188buff = ui_malloc(bufsiz, "password buffer");189ok = UI_add_verify_string(ui, prompt, ui_flags, buff,190PW_MIN_LENGTH, bufsiz - 1, buf);191}192if (ok >= 0)193do {194ok = UI_process(ui);195} while (ok < 0 && UI_ctrl(ui, UI_CTRL_IS_REDOABLE, 0, 0, 0));196197OPENSSL_clear_free(buff, (unsigned int)bufsiz);198199if (ok >= 0)200res = strlen(buf);201if (ok == -1) {202BIO_printf(bio_err, "User interface error\n");203ERR_print_errors(bio_err);204OPENSSL_cleanse(buf, (unsigned int)bufsiz);205res = 0;206}207if (ok == -2) {208BIO_printf(bio_err, "aborted!\n");209OPENSSL_cleanse(buf, (unsigned int)bufsiz);210res = 0;211}212UI_free(ui);213OPENSSL_free(prompt);214return res;215}216217218