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