xref: /freebsd/crypto/openssl/crypto/cryptlib.c (revision b077aed33b7b6aefca7b17ddb250cf521f938613)
1e71b7053SJung-uk Kim /*
2*b077aed3SPierre Pronchery  * Copyright 1998-2021 The OpenSSL Project Authors. All Rights Reserved.
3e71b7053SJung-uk Kim  * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
43b4e3dcbSSimon L. B. Nielsen  *
5*b077aed3SPierre Pronchery  * Licensed under the Apache License 2.0 (the "License").  You may not use
6e71b7053SJung-uk Kim  * this file except in compliance with the License.  You can obtain a copy
7e71b7053SJung-uk Kim  * in the file LICENSE in the source distribution or at
8e71b7053SJung-uk Kim  * https://www.openssl.org/source/license.html
93b4e3dcbSSimon L. B. Nielsen  */
1074664626SKris Kennaway 
11e71b7053SJung-uk Kim #include "e_os.h"
1217f01e99SJung-uk Kim #include "crypto/cryptlib.h"
13ddd58736SKris Kennaway #include <openssl/safestack.h>
1474664626SKris Kennaway 
15e71b7053SJung-uk Kim #if defined(_WIN32)
163b4e3dcbSSimon L. B. Nielsen # include <tchar.h>
171f13597dSJung-uk Kim # include <signal.h>
181f13597dSJung-uk Kim # ifdef __WATCOMC__
191f13597dSJung-uk Kim #  if defined(_UNICODE) || defined(__UNICODE__)
201f13597dSJung-uk Kim #   define _vsntprintf _vsnwprintf
211f13597dSJung-uk Kim #  else
221f13597dSJung-uk Kim #   define _vsntprintf _vsnprintf
231f13597dSJung-uk Kim #  endif
241f13597dSJung-uk Kim # endif
251f13597dSJung-uk Kim # ifdef _MSC_VER
261f13597dSJung-uk Kim #  define alloca _alloca
271f13597dSJung-uk Kim # endif
283b4e3dcbSSimon L. B. Nielsen 
293b4e3dcbSSimon L. B. Nielsen # if defined(_WIN32_WINNT) && _WIN32_WINNT>=0x0333
30e71b7053SJung-uk Kim #  ifdef OPENSSL_SYS_WIN_CORE
31e71b7053SJung-uk Kim 
OPENSSL_isservice(void)32e71b7053SJung-uk Kim int OPENSSL_isservice(void)
33e71b7053SJung-uk Kim {
34e71b7053SJung-uk Kim     /* OneCore API cannot interact with GUI */
35e71b7053SJung-uk Kim     return 1;
36e71b7053SJung-uk Kim }
37e71b7053SJung-uk Kim #  else
OPENSSL_isservice(void)383b4e3dcbSSimon L. B. Nielsen int OPENSSL_isservice(void)
396f9291ceSJung-uk Kim {
406f9291ceSJung-uk Kim     HWINSTA h;
413b4e3dcbSSimon L. B. Nielsen     DWORD len;
423b4e3dcbSSimon L. B. Nielsen     WCHAR *name;
436f9291ceSJung-uk Kim     static union {
446f9291ceSJung-uk Kim         void *p;
45e71b7053SJung-uk Kim         FARPROC f;
466f9291ceSJung-uk Kim     } _OPENSSL_isservice = {
476f9291ceSJung-uk Kim         NULL
486f9291ceSJung-uk Kim     };
491f13597dSJung-uk Kim 
501f13597dSJung-uk Kim     if (_OPENSSL_isservice.p == NULL) {
51e71b7053SJung-uk Kim         HANDLE mod = GetModuleHandle(NULL);
52c9cf7b5cSJung-uk Kim         FARPROC f = NULL;
53e71b7053SJung-uk Kim 
54e71b7053SJung-uk Kim         if (mod != NULL)
55e71b7053SJung-uk Kim             f = GetProcAddress(mod, "_OPENSSL_isservice");
56e71b7053SJung-uk Kim         if (f == NULL)
571f13597dSJung-uk Kim             _OPENSSL_isservice.p = (void *)-1;
58e71b7053SJung-uk Kim         else
59e71b7053SJung-uk Kim             _OPENSSL_isservice.f = f;
601f13597dSJung-uk Kim     }
611f13597dSJung-uk Kim 
621f13597dSJung-uk Kim     if (_OPENSSL_isservice.p != (void *)-1)
631f13597dSJung-uk Kim         return (*_OPENSSL_isservice.f) ();
643b4e3dcbSSimon L. B. Nielsen 
653b4e3dcbSSimon L. B. Nielsen     h = GetProcessWindowStation();
666f9291ceSJung-uk Kim     if (h == NULL)
676f9291ceSJung-uk Kim         return -1;
683b4e3dcbSSimon L. B. Nielsen 
693b4e3dcbSSimon L. B. Nielsen     if (GetUserObjectInformationW(h, UOI_NAME, NULL, 0, &len) ||
703b4e3dcbSSimon L. B. Nielsen         GetLastError() != ERROR_INSUFFICIENT_BUFFER)
713b4e3dcbSSimon L. B. Nielsen         return -1;
723b4e3dcbSSimon L. B. Nielsen 
736f9291ceSJung-uk Kim     if (len > 512)
746f9291ceSJung-uk Kim         return -1;              /* paranoia */
753b4e3dcbSSimon L. B. Nielsen     len++, len &= ~1;           /* paranoia */
763b4e3dcbSSimon L. B. Nielsen     name = (WCHAR *)alloca(len + sizeof(WCHAR));
773b4e3dcbSSimon L. B. Nielsen     if (!GetUserObjectInformationW(h, UOI_NAME, name, len, &len))
783b4e3dcbSSimon L. B. Nielsen         return -1;
793b4e3dcbSSimon L. B. Nielsen 
803b4e3dcbSSimon L. B. Nielsen     len++, len &= ~1;           /* paranoia */
813b4e3dcbSSimon L. B. Nielsen     name[len / sizeof(WCHAR)] = L'\0'; /* paranoia */
823b4e3dcbSSimon L. B. Nielsen #   if 1
836f9291ceSJung-uk Kim     /*
846f9291ceSJung-uk Kim      * This doesn't cover "interactive" services [working with real
856f9291ceSJung-uk Kim      * WinSta0's] nor programs started non-interactively by Task Scheduler
866f9291ceSJung-uk Kim      * [those are working with SAWinSta].
876f9291ceSJung-uk Kim      */
886f9291ceSJung-uk Kim     if (wcsstr(name, L"Service-0x"))
896f9291ceSJung-uk Kim         return 1;
903b4e3dcbSSimon L. B. Nielsen #   else
913b4e3dcbSSimon L. B. Nielsen     /* This covers all non-interactive programs such as services. */
926f9291ceSJung-uk Kim     if (!wcsstr(name, L"WinSta0"))
936f9291ceSJung-uk Kim         return 1;
943b4e3dcbSSimon L. B. Nielsen #   endif
956f9291ceSJung-uk Kim     else
966f9291ceSJung-uk Kim         return 0;
973b4e3dcbSSimon L. B. Nielsen }
98e71b7053SJung-uk Kim #  endif
993b4e3dcbSSimon L. B. Nielsen # else
OPENSSL_isservice(void)1006f9291ceSJung-uk Kim int OPENSSL_isservice(void)
1016f9291ceSJung-uk Kim {
1026f9291ceSJung-uk Kim     return 0;
1036f9291ceSJung-uk Kim }
1043b4e3dcbSSimon L. B. Nielsen # endif
1053b4e3dcbSSimon L. B. Nielsen 
OPENSSL_showfatal(const char * fmta,...)1063b4e3dcbSSimon L. B. Nielsen void OPENSSL_showfatal(const char *fmta, ...)
1076f9291ceSJung-uk Kim {
1086f9291ceSJung-uk Kim     va_list ap;
1093b4e3dcbSSimon L. B. Nielsen     TCHAR buf[256];
1103b4e3dcbSSimon L. B. Nielsen     const TCHAR *fmt;
111e71b7053SJung-uk Kim     /*
112e71b7053SJung-uk Kim      * First check if it's a console application, in which case the
113e71b7053SJung-uk Kim      * error message would be printed to standard error.
114e71b7053SJung-uk Kim      * Windows CE does not have a concept of a console application,
115e71b7053SJung-uk Kim      * so we need to guard the check.
116e71b7053SJung-uk Kim      */
117e71b7053SJung-uk Kim # ifdef STD_ERROR_HANDLE
1183b4e3dcbSSimon L. B. Nielsen     HANDLE h;
1193b4e3dcbSSimon L. B. Nielsen 
1203b4e3dcbSSimon L. B. Nielsen     if ((h = GetStdHandle(STD_ERROR_HANDLE)) != NULL &&
1216f9291ceSJung-uk Kim         GetFileType(h) != FILE_TYPE_UNKNOWN) {
1226f9291ceSJung-uk Kim         /* must be console application */
1237bded2dbSJung-uk Kim         int len;
1247bded2dbSJung-uk Kim         DWORD out;
1257bded2dbSJung-uk Kim 
1263b4e3dcbSSimon L. B. Nielsen         va_start(ap, fmta);
1277bded2dbSJung-uk Kim         len = _vsnprintf((char *)buf, sizeof(buf), fmta, ap);
1287bded2dbSJung-uk Kim         WriteFile(h, buf, len < 0 ? sizeof(buf) : (DWORD) len, &out, NULL);
1293b4e3dcbSSimon L. B. Nielsen         va_end(ap);
1303b4e3dcbSSimon L. B. Nielsen         return;
1313b4e3dcbSSimon L. B. Nielsen     }
1323b4e3dcbSSimon L. B. Nielsen # endif
1333b4e3dcbSSimon L. B. Nielsen 
1343b4e3dcbSSimon L. B. Nielsen     if (sizeof(TCHAR) == sizeof(char))
1353b4e3dcbSSimon L. B. Nielsen         fmt = (const TCHAR *)fmta;
1366f9291ceSJung-uk Kim     else
1376f9291ceSJung-uk Kim         do {
1386f9291ceSJung-uk Kim             int keepgoing;
1393b4e3dcbSSimon L. B. Nielsen             size_t len_0 = strlen(fmta) + 1, i;
1403b4e3dcbSSimon L. B. Nielsen             WCHAR *fmtw;
1413b4e3dcbSSimon L. B. Nielsen 
1423b4e3dcbSSimon L. B. Nielsen             fmtw = (WCHAR *)alloca(len_0 * sizeof(WCHAR));
1436f9291ceSJung-uk Kim             if (fmtw == NULL) {
1446f9291ceSJung-uk Kim                 fmt = (const TCHAR *)L"no stack?";
1456f9291ceSJung-uk Kim                 break;
1466f9291ceSJung-uk Kim             }
1473b4e3dcbSSimon L. B. Nielsen             if (!MultiByteToWideChar(CP_ACP, 0, fmta, len_0, fmtw, len_0))
1483b4e3dcbSSimon L. B. Nielsen                 for (i = 0; i < len_0; i++)
1496f9291ceSJung-uk Kim                     fmtw[i] = (WCHAR)fmta[i];
1506f9291ceSJung-uk Kim             for (i = 0; i < len_0; i++) {
1516f9291ceSJung-uk Kim                 if (fmtw[i] == L'%')
1526f9291ceSJung-uk Kim                     do {
1536f9291ceSJung-uk Kim                         keepgoing = 0;
1546f9291ceSJung-uk Kim                         switch (fmtw[i + 1]) {
1556f9291ceSJung-uk Kim                         case L'0':
1566f9291ceSJung-uk Kim                         case L'1':
1576f9291ceSJung-uk Kim                         case L'2':
1586f9291ceSJung-uk Kim                         case L'3':
1596f9291ceSJung-uk Kim                         case L'4':
1606f9291ceSJung-uk Kim                         case L'5':
1616f9291ceSJung-uk Kim                         case L'6':
1626f9291ceSJung-uk Kim                         case L'7':
1636f9291ceSJung-uk Kim                         case L'8':
1646f9291ceSJung-uk Kim                         case L'9':
1656f9291ceSJung-uk Kim                         case L'.':
1666f9291ceSJung-uk Kim                         case L'*':
1676f9291ceSJung-uk Kim                         case L'-':
1686f9291ceSJung-uk Kim                             i++;
1696f9291ceSJung-uk Kim                             keepgoing = 1;
1706f9291ceSJung-uk Kim                             break;
1716f9291ceSJung-uk Kim                         case L's':
1726f9291ceSJung-uk Kim                             fmtw[i + 1] = L'S';
1736f9291ceSJung-uk Kim                             break;
1746f9291ceSJung-uk Kim                         case L'S':
1756f9291ceSJung-uk Kim                             fmtw[i + 1] = L's';
1766f9291ceSJung-uk Kim                             break;
1776f9291ceSJung-uk Kim                         case L'c':
1786f9291ceSJung-uk Kim                             fmtw[i + 1] = L'C';
1796f9291ceSJung-uk Kim                             break;
1806f9291ceSJung-uk Kim                         case L'C':
1816f9291ceSJung-uk Kim                             fmtw[i + 1] = L'c';
1826f9291ceSJung-uk Kim                             break;
1833b4e3dcbSSimon L. B. Nielsen                         }
1843b4e3dcbSSimon L. B. Nielsen                     } while (keepgoing);
1853b4e3dcbSSimon L. B. Nielsen             }
1863b4e3dcbSSimon L. B. Nielsen             fmt = (const TCHAR *)fmtw;
1873b4e3dcbSSimon L. B. Nielsen         } while (0);
1883b4e3dcbSSimon L. B. Nielsen 
1893b4e3dcbSSimon L. B. Nielsen     va_start(ap, fmta);
190e71b7053SJung-uk Kim     _vsntprintf(buf, OSSL_NELEM(buf) - 1, fmt, ap);
191e71b7053SJung-uk Kim     buf[OSSL_NELEM(buf) - 1] = _T('\0');
1923b4e3dcbSSimon L. B. Nielsen     va_end(ap);
1933b4e3dcbSSimon L. B. Nielsen 
1943b4e3dcbSSimon L. B. Nielsen # if defined(_WIN32_WINNT) && _WIN32_WINNT>=0x0333
195e71b7053SJung-uk Kim #  ifdef OPENSSL_SYS_WIN_CORE
196e71b7053SJung-uk Kim     /* ONECORE is always NONGUI and NT >= 0x0601 */
197e71b7053SJung-uk Kim #   if !defined(NDEBUG)
198e71b7053SJung-uk Kim         /*
199e71b7053SJung-uk Kim         * We are in a situation where we tried to report a critical
200e71b7053SJung-uk Kim         * error and this failed for some reason. As a last resort,
201e71b7053SJung-uk Kim         * in debug builds, send output to the debugger or any other
202e71b7053SJung-uk Kim         * tool like DebugView which can monitor the output.
203e71b7053SJung-uk Kim         */
204e71b7053SJung-uk Kim         OutputDebugString(buf);
205e71b7053SJung-uk Kim #   endif
206e71b7053SJung-uk Kim #  else
2073b4e3dcbSSimon L. B. Nielsen     /* this -------------v--- guards NT-specific calls */
2086f9291ceSJung-uk Kim     if (check_winnt() && OPENSSL_isservice() > 0) {
20980815a77SJung-uk Kim         HANDLE hEventLog = RegisterEventSource(NULL, _T("OpenSSL"));
21080815a77SJung-uk Kim 
21180815a77SJung-uk Kim         if (hEventLog != NULL) {
2123b4e3dcbSSimon L. B. Nielsen             const TCHAR *pmsg = buf;
21380815a77SJung-uk Kim 
21480815a77SJung-uk Kim             if (!ReportEvent(hEventLog, EVENTLOG_ERROR_TYPE, 0, 0, NULL,
21580815a77SJung-uk Kim                              1, 0, &pmsg, NULL)) {
216e71b7053SJung-uk Kim #   if !defined(NDEBUG)
21780815a77SJung-uk Kim                 /*
21880815a77SJung-uk Kim                  * We are in a situation where we tried to report a critical
21980815a77SJung-uk Kim                  * error and this failed for some reason. As a last resort,
22080815a77SJung-uk Kim                  * in debug builds, send output to the debugger or any other
22180815a77SJung-uk Kim                  * tool like DebugView which can monitor the output.
22280815a77SJung-uk Kim                  */
22380815a77SJung-uk Kim                 OutputDebugString(pmsg);
22480815a77SJung-uk Kim #   endif
22580815a77SJung-uk Kim             }
22680815a77SJung-uk Kim 
22780815a77SJung-uk Kim             (void)DeregisterEventSource(hEventLog);
22880815a77SJung-uk Kim         }
229e71b7053SJung-uk Kim     } else {
23080815a77SJung-uk Kim         MessageBox(NULL, buf, _T("OpenSSL: FATAL"), MB_OK | MB_ICONERROR);
2313b4e3dcbSSimon L. B. Nielsen     }
232e71b7053SJung-uk Kim #  endif
233e71b7053SJung-uk Kim # else
234e71b7053SJung-uk Kim     MessageBox(NULL, buf, _T("OpenSSL: FATAL"), MB_OK | MB_ICONERROR);
235e71b7053SJung-uk Kim # endif
236e71b7053SJung-uk Kim }
2373b4e3dcbSSimon L. B. Nielsen #else
OPENSSL_showfatal(const char * fmta,...)2383b4e3dcbSSimon L. B. Nielsen void OPENSSL_showfatal(const char *fmta, ...)
2396f9291ceSJung-uk Kim {
240e71b7053SJung-uk Kim #ifndef OPENSSL_NO_STDIO
2416f9291ceSJung-uk Kim     va_list ap;
2423b4e3dcbSSimon L. B. Nielsen 
2433b4e3dcbSSimon L. B. Nielsen     va_start(ap, fmta);
2443b4e3dcbSSimon L. B. Nielsen     vfprintf(stderr, fmta, ap);
2453b4e3dcbSSimon L. B. Nielsen     va_end(ap);
246e71b7053SJung-uk Kim #endif
2473b4e3dcbSSimon L. B. Nielsen }
2486f9291ceSJung-uk Kim 
OPENSSL_isservice(void)2496f9291ceSJung-uk Kim int OPENSSL_isservice(void)
2506f9291ceSJung-uk Kim {
2516f9291ceSJung-uk Kim     return 0;
2526f9291ceSJung-uk Kim }
25374664626SKris Kennaway #endif
2545c87c606SMark Murray 
OPENSSL_die(const char * message,const char * file,int line)255e71b7053SJung-uk Kim void OPENSSL_die(const char *message, const char *file, int line)
2565c87c606SMark Murray {
257e71b7053SJung-uk Kim     OPENSSL_showfatal("%s:%d: OpenSSL internal error: %s\n",
258e71b7053SJung-uk Kim                       file, line, message);
259e71b7053SJung-uk Kim #if !defined(_WIN32)
2605c87c606SMark Murray     abort();
2611f13597dSJung-uk Kim #else
2626f9291ceSJung-uk Kim     /*
2636f9291ceSJung-uk Kim      * Win32 abort() customarily shows a dialog, but we just did that...
2646f9291ceSJung-uk Kim      */
2657bded2dbSJung-uk Kim # if !defined(_WIN32_WCE)
2661f13597dSJung-uk Kim     raise(SIGABRT);
2677bded2dbSJung-uk Kim # endif
2681f13597dSJung-uk Kim     _exit(3);
2691f13597dSJung-uk Kim #endif
2705c87c606SMark Murray }
2716be8ae07SJacques Vidrine 
272*b077aed3SPierre Pronchery #if defined(__TANDEM) && defined(OPENSSL_VPROC)
273e71b7053SJung-uk Kim /*
274*b077aed3SPierre Pronchery  * Define a VPROC function for HP NonStop build crypto library.
275*b077aed3SPierre Pronchery  * This is used by platform version identification tools.
276*b077aed3SPierre Pronchery  * Do not inline this procedure or make it static.
277e71b7053SJung-uk Kim  */
278*b077aed3SPierre Pronchery # define OPENSSL_VPROC_STRING_(x)    x##_CRYPTO
279*b077aed3SPierre Pronchery # define OPENSSL_VPROC_STRING(x)     OPENSSL_VPROC_STRING_(x)
280*b077aed3SPierre Pronchery # define OPENSSL_VPROC_FUNC          OPENSSL_VPROC_STRING(OPENSSL_VPROC)
OPENSSL_VPROC_FUNC(void)281*b077aed3SPierre Pronchery void OPENSSL_VPROC_FUNC(void) {}
282*b077aed3SPierre Pronchery #endif /* __TANDEM */
283