cryptlib.c 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282
  1. /*
  2. * Copyright 1998-2023 The OpenSSL Project Authors. All Rights Reserved.
  3. * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
  4. *
  5. * Licensed under the Apache License 2.0 (the "License"). You may not use
  6. * this file except in compliance with the License. You can obtain a copy
  7. * in the file LICENSE in the source distribution or at
  8. * https://www.openssl.org/source/license.html
  9. */
  10. #include "internal/e_os.h"
  11. #include "crypto/cryptlib.h"
  12. #include <openssl/safestack.h>
  13. #if defined(_WIN32) && !defined(OPENSSL_SYS_UEFI)
  14. # include <tchar.h>
  15. # include <signal.h>
  16. # ifdef __WATCOMC__
  17. # if defined(_UNICODE) || defined(__UNICODE__)
  18. # define _vsntprintf _vsnwprintf
  19. # else
  20. # define _vsntprintf _vsnprintf
  21. # endif
  22. # endif
  23. # ifdef _MSC_VER
  24. # define alloca _alloca
  25. # endif
  26. # if defined(_WIN32_WINNT) && _WIN32_WINNT>=0x0333
  27. # ifdef OPENSSL_SYS_WIN_CORE
  28. int OPENSSL_isservice(void)
  29. {
  30. /* OneCore API cannot interact with GUI */
  31. return 1;
  32. }
  33. # else
  34. int OPENSSL_isservice(void)
  35. {
  36. HWINSTA h;
  37. DWORD len;
  38. WCHAR *name;
  39. static union {
  40. void *p;
  41. FARPROC f;
  42. } _OPENSSL_isservice = {
  43. NULL
  44. };
  45. if (_OPENSSL_isservice.p == NULL) {
  46. HANDLE mod = GetModuleHandle(NULL);
  47. FARPROC f = NULL;
  48. if (mod != NULL)
  49. f = GetProcAddress(mod, "_OPENSSL_isservice");
  50. if (f == NULL)
  51. _OPENSSL_isservice.p = (void *)-1;
  52. else
  53. _OPENSSL_isservice.f = f;
  54. }
  55. if (_OPENSSL_isservice.p != (void *)-1)
  56. return (*_OPENSSL_isservice.f) ();
  57. h = GetProcessWindowStation();
  58. if (h == NULL)
  59. return -1;
  60. if (GetUserObjectInformationW(h, UOI_NAME, NULL, 0, &len) ||
  61. GetLastError() != ERROR_INSUFFICIENT_BUFFER)
  62. return -1;
  63. if (len > 512)
  64. return -1; /* paranoia */
  65. len++, len &= ~1; /* paranoia */
  66. name = (WCHAR *)alloca(len + sizeof(WCHAR));
  67. if (!GetUserObjectInformationW(h, UOI_NAME, name, len, &len))
  68. return -1;
  69. len++, len &= ~1; /* paranoia */
  70. name[len / sizeof(WCHAR)] = L'\0'; /* paranoia */
  71. # if 1
  72. /*
  73. * This doesn't cover "interactive" services [working with real
  74. * WinSta0's] nor programs started non-interactively by Task Scheduler
  75. * [those are working with SAWinSta].
  76. */
  77. if (wcsstr(name, L"Service-0x"))
  78. return 1;
  79. # else
  80. /* This covers all non-interactive programs such as services. */
  81. if (!wcsstr(name, L"WinSta0"))
  82. return 1;
  83. # endif
  84. else
  85. return 0;
  86. }
  87. # endif
  88. # else
  89. int OPENSSL_isservice(void)
  90. {
  91. return 0;
  92. }
  93. # endif
  94. void OPENSSL_showfatal(const char *fmta, ...)
  95. {
  96. va_list ap;
  97. TCHAR buf[256];
  98. const TCHAR *fmt;
  99. /*
  100. * First check if it's a console application, in which case the
  101. * error message would be printed to standard error.
  102. * Windows CE does not have a concept of a console application,
  103. * so we need to guard the check.
  104. */
  105. # ifdef STD_ERROR_HANDLE
  106. HANDLE h;
  107. if ((h = GetStdHandle(STD_ERROR_HANDLE)) != NULL &&
  108. GetFileType(h) != FILE_TYPE_UNKNOWN) {
  109. /* must be console application */
  110. int len;
  111. DWORD out;
  112. va_start(ap, fmta);
  113. len = _vsnprintf((char *)buf, sizeof(buf), fmta, ap);
  114. WriteFile(h, buf, len < 0 ? sizeof(buf) : (DWORD) len, &out, NULL);
  115. va_end(ap);
  116. return;
  117. }
  118. # endif
  119. if (sizeof(TCHAR) == sizeof(char))
  120. fmt = (const TCHAR *)fmta;
  121. else
  122. do {
  123. int keepgoing;
  124. size_t len_0 = strlen(fmta) + 1, i;
  125. WCHAR *fmtw;
  126. fmtw = (WCHAR *)alloca(len_0 * sizeof(WCHAR));
  127. if (fmtw == NULL) {
  128. fmt = (const TCHAR *)L"no stack?";
  129. break;
  130. }
  131. if (!MultiByteToWideChar(CP_ACP, 0, fmta, len_0, fmtw, len_0))
  132. for (i = 0; i < len_0; i++)
  133. fmtw[i] = (WCHAR)fmta[i];
  134. for (i = 0; i < len_0; i++) {
  135. if (fmtw[i] == L'%')
  136. do {
  137. keepgoing = 0;
  138. switch (fmtw[i + 1]) {
  139. case L'0':
  140. case L'1':
  141. case L'2':
  142. case L'3':
  143. case L'4':
  144. case L'5':
  145. case L'6':
  146. case L'7':
  147. case L'8':
  148. case L'9':
  149. case L'.':
  150. case L'*':
  151. case L'-':
  152. i++;
  153. keepgoing = 1;
  154. break;
  155. case L's':
  156. fmtw[i + 1] = L'S';
  157. break;
  158. case L'S':
  159. fmtw[i + 1] = L's';
  160. break;
  161. case L'c':
  162. fmtw[i + 1] = L'C';
  163. break;
  164. case L'C':
  165. fmtw[i + 1] = L'c';
  166. break;
  167. }
  168. } while (keepgoing);
  169. }
  170. fmt = (const TCHAR *)fmtw;
  171. } while (0);
  172. va_start(ap, fmta);
  173. _vsntprintf(buf, OSSL_NELEM(buf) - 1, fmt, ap);
  174. buf[OSSL_NELEM(buf) - 1] = _T('\0');
  175. va_end(ap);
  176. # if defined(_WIN32_WINNT) && _WIN32_WINNT>=0x0333
  177. # ifdef OPENSSL_SYS_WIN_CORE
  178. /* ONECORE is always NONGUI and NT >= 0x0601 */
  179. # if !defined(NDEBUG)
  180. /*
  181. * We are in a situation where we tried to report a critical
  182. * error and this failed for some reason. As a last resort,
  183. * in debug builds, send output to the debugger or any other
  184. * tool like DebugView which can monitor the output.
  185. */
  186. OutputDebugString(buf);
  187. # endif
  188. # else
  189. /* this -------------v--- guards NT-specific calls */
  190. if (check_winnt() && OPENSSL_isservice() > 0) {
  191. HANDLE hEventLog = RegisterEventSource(NULL, _T("OpenSSL"));
  192. if (hEventLog != NULL) {
  193. const TCHAR *pmsg = buf;
  194. if (!ReportEvent(hEventLog, EVENTLOG_ERROR_TYPE, 0, 0, NULL,
  195. 1, 0, &pmsg, NULL)) {
  196. # if !defined(NDEBUG)
  197. /*
  198. * We are in a situation where we tried to report a critical
  199. * error and this failed for some reason. As a last resort,
  200. * in debug builds, send output to the debugger or any other
  201. * tool like DebugView which can monitor the output.
  202. */
  203. OutputDebugString(pmsg);
  204. # endif
  205. }
  206. (void)DeregisterEventSource(hEventLog);
  207. }
  208. } else {
  209. MessageBox(NULL, buf, _T("OpenSSL: FATAL"), MB_OK | MB_ICONERROR);
  210. }
  211. # endif
  212. # else
  213. MessageBox(NULL, buf, _T("OpenSSL: FATAL"), MB_OK | MB_ICONERROR);
  214. # endif
  215. }
  216. #else
  217. void OPENSSL_showfatal(const char *fmta, ...)
  218. {
  219. #ifndef OPENSSL_NO_STDIO
  220. va_list ap;
  221. va_start(ap, fmta);
  222. vfprintf(stderr, fmta, ap);
  223. va_end(ap);
  224. #endif
  225. }
  226. int OPENSSL_isservice(void)
  227. {
  228. return 0;
  229. }
  230. #endif
  231. void OPENSSL_die(const char *message, const char *file, int line)
  232. {
  233. OPENSSL_showfatal("%s:%d: OpenSSL internal error: %s\n",
  234. file, line, message);
  235. #if !defined(_WIN32) || defined(OPENSSL_SYS_UEFI)
  236. abort();
  237. #else
  238. /*
  239. * Win32 abort() customarily shows a dialog, but we just did that...
  240. */
  241. # if !defined(_WIN32_WCE)
  242. raise(SIGABRT);
  243. # endif
  244. _exit(3);
  245. #endif
  246. }
  247. #if defined(__TANDEM) && defined(OPENSSL_VPROC)
  248. /*
  249. * Define a VPROC function for HP NonStop build crypto library.
  250. * This is used by platform version identification tools.
  251. * Do not inline this procedure or make it static.
  252. */
  253. # define OPENSSL_VPROC_STRING_(x) x##_CRYPTO
  254. # define OPENSSL_VPROC_STRING(x) OPENSSL_VPROC_STRING_(x)
  255. # define OPENSSL_VPROC_FUNC OPENSSL_VPROC_STRING(OPENSSL_VPROC)
  256. void OPENSSL_VPROC_FUNC(void) {}
  257. #endif /* __TANDEM */