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