apps_ui.c 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. /*
  2. * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
  3. *
  4. * Licensed under the OpenSSL license (the "License"). You may not use
  5. * this file except in compliance with the License. You can obtain a copy
  6. * in the file LICENSE in the source distribution or at
  7. * https://www.openssl.org/source/license.html
  8. */
  9. #include <string.h>
  10. #include <openssl/err.h>
  11. #include <openssl/ui.h>
  12. #include "apps_ui.h"
  13. static UI_METHOD *ui_method = NULL;
  14. static const UI_METHOD *ui_fallback_method = NULL;
  15. static int ui_open(UI *ui)
  16. {
  17. int (*opener)(UI *ui) = UI_method_get_opener(ui_fallback_method);
  18. if (opener)
  19. return opener(ui);
  20. return 1;
  21. }
  22. static int ui_read(UI *ui, UI_STRING *uis)
  23. {
  24. int (*reader)(UI *ui, UI_STRING *uis) = NULL;
  25. if (UI_get_input_flags(uis) & UI_INPUT_FLAG_DEFAULT_PWD
  26. && UI_get0_user_data(ui)) {
  27. switch (UI_get_string_type(uis)) {
  28. case UIT_PROMPT:
  29. case UIT_VERIFY:
  30. {
  31. const char *password =
  32. ((PW_CB_DATA *)UI_get0_user_data(ui))->password;
  33. if (password && password[0] != '\0') {
  34. UI_set_result(ui, uis, password);
  35. return 1;
  36. }
  37. }
  38. break;
  39. case UIT_NONE:
  40. case UIT_BOOLEAN:
  41. case UIT_INFO:
  42. case UIT_ERROR:
  43. break;
  44. }
  45. }
  46. reader = UI_method_get_reader(ui_fallback_method);
  47. if (reader)
  48. return reader(ui, uis);
  49. return 1;
  50. }
  51. static int ui_write(UI *ui, UI_STRING *uis)
  52. {
  53. int (*writer)(UI *ui, UI_STRING *uis) = NULL;
  54. if (UI_get_input_flags(uis) & UI_INPUT_FLAG_DEFAULT_PWD
  55. && UI_get0_user_data(ui)) {
  56. switch (UI_get_string_type(uis)) {
  57. case UIT_PROMPT:
  58. case UIT_VERIFY:
  59. {
  60. const char *password =
  61. ((PW_CB_DATA *)UI_get0_user_data(ui))->password;
  62. if (password && password[0] != '\0')
  63. return 1;
  64. }
  65. break;
  66. case UIT_NONE:
  67. case UIT_BOOLEAN:
  68. case UIT_INFO:
  69. case UIT_ERROR:
  70. break;
  71. }
  72. }
  73. writer = UI_method_get_writer(ui_fallback_method);
  74. if (writer)
  75. return writer(ui, uis);
  76. return 1;
  77. }
  78. static int ui_close(UI *ui)
  79. {
  80. int (*closer)(UI *ui) = UI_method_get_closer(ui_fallback_method);
  81. if (closer)
  82. return closer(ui);
  83. return 1;
  84. }
  85. int setup_ui_method(void)
  86. {
  87. ui_fallback_method = UI_null();
  88. #ifndef OPENSSL_NO_UI_CONSOLE
  89. ui_fallback_method = UI_OpenSSL();
  90. #endif
  91. ui_method = UI_create_method("OpenSSL application user interface");
  92. UI_method_set_opener(ui_method, ui_open);
  93. UI_method_set_reader(ui_method, ui_read);
  94. UI_method_set_writer(ui_method, ui_write);
  95. UI_method_set_closer(ui_method, ui_close);
  96. return 0;
  97. }
  98. void destroy_ui_method(void)
  99. {
  100. if (ui_method) {
  101. UI_destroy_method(ui_method);
  102. ui_method = NULL;
  103. }
  104. }
  105. const UI_METHOD *get_ui_method(void)
  106. {
  107. return ui_method;
  108. }
  109. static void *ui_malloc(int sz, const char *what)
  110. {
  111. void *vp = OPENSSL_malloc(sz);
  112. if (vp == NULL) {
  113. BIO_printf(bio_err, "Could not allocate %d bytes for %s\n", sz, what);
  114. ERR_print_errors(bio_err);
  115. exit(1);
  116. }
  117. return vp;
  118. }
  119. int password_callback(char *buf, int bufsiz, int verify, PW_CB_DATA *cb_data)
  120. {
  121. int res = 0;
  122. UI *ui;
  123. int ok = 0;
  124. char *buff = NULL;
  125. int ui_flags = 0;
  126. const char *prompt_info = NULL;
  127. char *prompt;
  128. if ((ui = UI_new_method(ui_method)) == NULL)
  129. return 0;
  130. if (cb_data != NULL && cb_data->prompt_info != NULL)
  131. prompt_info = cb_data->prompt_info;
  132. prompt = UI_construct_prompt(ui, "pass phrase", prompt_info);
  133. if (prompt == NULL) {
  134. BIO_printf(bio_err, "Out of memory\n");
  135. UI_free(ui);
  136. return 0;
  137. }
  138. ui_flags |= UI_INPUT_FLAG_DEFAULT_PWD;
  139. UI_ctrl(ui, UI_CTRL_PRINT_ERRORS, 1, 0, 0);
  140. /* We know that there is no previous user data to return to us */
  141. (void)UI_add_user_data(ui, cb_data);
  142. ok = UI_add_input_string(ui, prompt, ui_flags, buf,
  143. PW_MIN_LENGTH, bufsiz - 1);
  144. if (ok >= 0 && verify) {
  145. buff = ui_malloc(bufsiz, "password buffer");
  146. ok = UI_add_verify_string(ui, prompt, ui_flags, buff,
  147. PW_MIN_LENGTH, bufsiz - 1, buf);
  148. }
  149. if (ok >= 0)
  150. do {
  151. ok = UI_process(ui);
  152. } while (ok < 0 && UI_ctrl(ui, UI_CTRL_IS_REDOABLE, 0, 0, 0));
  153. OPENSSL_clear_free(buff, (unsigned int)bufsiz);
  154. if (ok >= 0)
  155. res = strlen(buf);
  156. if (ok == -1) {
  157. BIO_printf(bio_err, "User interface error\n");
  158. ERR_print_errors(bio_err);
  159. OPENSSL_cleanse(buf, (unsigned int)bufsiz);
  160. res = 0;
  161. }
  162. if (ok == -2) {
  163. BIO_printf(bio_err, "aborted!\n");
  164. OPENSSL_cleanse(buf, (unsigned int)bufsiz);
  165. res = 0;
  166. }
  167. UI_free(ui);
  168. OPENSSL_free(prompt);
  169. return res;
  170. }