From 03bd53db66ca59eaae1546b53c4f700f569e0458 Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Fri, 16 Jan 2026 16:47:17 +0200 Subject: [PATCH] [CRYPT32] Sync to wine 10.0 - Move CertEnumSystemStoreLocation to reactos/store.c - Add emulation layer for unixlib calls - Implement enumeration of root certificate store in the registry TODO: - Implement remaining unixlib functionality using mbedtls or similar --- dll/win32/crypt32/CMakeLists.txt | 20 +- dll/win32/crypt32/base64.c | 523 ++++++++++--- dll/win32/crypt32/cert.c | 671 ++++++++++------ dll/win32/crypt32/chain.c | 394 ++++++---- dll/win32/crypt32/collectionstore.c | 16 +- dll/win32/crypt32/context.c | 4 +- dll/win32/crypt32/crl.c | 194 +++-- dll/win32/crypt32/crypt32.spec | 2 + dll/win32/crypt32/crypt32_private.h | 188 +++-- dll/win32/crypt32/ctl.c | 24 +- dll/win32/crypt32/decode.c | 1132 ++++++++++++++++++++++----- dll/win32/crypt32/encode.c | 451 ++++++++--- dll/win32/crypt32/filestore.c | 33 +- dll/win32/crypt32/main.c | 53 +- dll/win32/crypt32/message.c | 18 +- dll/win32/crypt32/msg.c | 328 +++++--- dll/win32/crypt32/object.c | 590 +++++++------- dll/win32/crypt32/oid.c | 389 ++++----- dll/win32/crypt32/pfx.c | 242 ++++++ dll/win32/crypt32/precomp.h | 2 - dll/win32/crypt32/proplist.c | 4 +- dll/win32/crypt32/protectdata.c | 21 +- dll/win32/crypt32/provstore.c | 8 +- dll/win32/crypt32/reactos/store.c | 65 ++ dll/win32/crypt32/reactos/unixlib.c | 338 ++++++++ dll/win32/crypt32/regstore.c | 64 +- dll/win32/crypt32/rootstore.c | 650 +++++---------- dll/win32/crypt32/serialize.c | 221 +++++- dll/win32/crypt32/sip.c | 98 +-- dll/win32/crypt32/store.c | 151 ++-- dll/win32/crypt32/str.c | 921 ++++++++-------------- dll/win32/crypt32/unixlib.c | 805 +++++++++++++++++++ dll/win32/crypt32/wine/unixlib.h | 32 + media/doc/WINESYNC.txt | 2 +- 34 files changed, 5726 insertions(+), 2928 deletions(-) create mode 100644 dll/win32/crypt32/pfx.c create mode 100644 dll/win32/crypt32/reactos/store.c create mode 100644 dll/win32/crypt32/reactos/unixlib.c create mode 100644 dll/win32/crypt32/unixlib.c create mode 100644 dll/win32/crypt32/wine/unixlib.h diff --git a/dll/win32/crypt32/CMakeLists.txt b/dll/win32/crypt32/CMakeLists.txt index e5ee97541ed..d000171d110 100644 --- a/dll/win32/crypt32/CMakeLists.txt +++ b/dll/win32/crypt32/CMakeLists.txt @@ -2,11 +2,11 @@ remove_definitions(-D_WIN32_WINNT=0x502 -DWINVER=0x502) add_definitions(-D_WIN32_WINNT=0x600 -DWINVER=0x600) +remove_definitions(-D_CRT_NON_CONFORMING_SWPRINTFS) + add_definitions( - -D__ROS_LONG64__ -D_WINE -D_CRYPT32_ - -Dstrncasecmp=_strnicmp ) spec2def(crypt32.dll crypt32.spec ADD_IMPORTLIB) @@ -27,6 +27,7 @@ list(APPEND SOURCE msg.c object.c oid.c + pfx.c proplist.c protectdata.c provstore.c @@ -35,7 +36,10 @@ list(APPEND SOURCE serialize.c sip.c store.c - str.c) + str.c + reactos/store.c + reactos/unixlib.c +) list(APPEND PCH_SKIP_SOURCE ${CMAKE_CURRENT_BINARY_DIR}/crypt32_stubs.c) @@ -47,15 +51,17 @@ add_library(crypt32 MODULE ${CMAKE_CURRENT_BINARY_DIR}/crypt32.def) if(MSVC) - # Disable warning C4090: 'function': different 'const' qualifiers - # Disable warning C4312: 'type cast': conversion from 'unsigned int' to 'void *' of greater size - target_compile_options(crypt32 PRIVATE /wd4090 /wd4312) + target_compile_options(crypt32 PRIVATE + /wd4090 # warning C4090: 'function': different 'const' qualifiers + /wd4267 # warning C4267: 'function': conversion from 'size_t' to 'ULONG', possible loss of data + /wd4312 # warning C4312: 'type cast': conversion from 'unsigned int' to 'void *' of greater size + ) endif() set_module_type(crypt32 win32dll) target_link_libraries(crypt32 wine ${PSEH_LIB} oldnames) add_delay_importlibs(crypt32 cryptnet) -add_importlibs(crypt32 bcrypt user32 advapi32 advapi32_vista msvcrt kernel32 ntdll) +add_importlibs(crypt32 bcrypt user32 advapi32 advapi32_vista msvcrt kernel32_vista kernel32 ntdll) add_pch(crypt32 precomp.h "${PCH_SKIP_SOURCE}") add_cd_file(TARGET crypt32 DESTINATION reactos/system32 FOR all) set_wine_module_FIXME(crypt32) # CORE-5743: No ARRAY_SIZE macro diff --git a/dll/win32/crypt32/base64.c b/dll/win32/crypt32/base64.c index d158c1aceb7..298756ca541 100644 --- a/dll/win32/crypt32/base64.c +++ b/dll/win32/crypt32/base64.c @@ -25,7 +25,6 @@ #include "winerror.h" #include "wincrypt.h" #include "wine/debug.h" -#include "wine/unicode.h" WINE_DEFAULT_DEBUG_CHANNEL(crypt); @@ -39,30 +38,15 @@ WINE_DEFAULT_DEBUG_CHANNEL(crypt); #define X509_HEADER "-----BEGIN X509 CRL-----" #define X509_TRAILER "-----END X509 CRL-----" -static const WCHAR CERT_HEADER_W[] = { -'-','-','-','-','-','B','E','G','I','N',' ','C','E','R','T','I','F','I','C', -'A','T','E','-','-','-','-','-',0 }; -static const WCHAR CERT_HEADER_START_W[] = { -'-','-','-','-','-','B','E','G','I','N',' ',0 }; -static const WCHAR CERT_DELIMITER_W[] = { -'-','-','-','-','-',0 }; -static const WCHAR CERT_TRAILER_W[] = { -'-','-','-','-','-','E','N','D',' ','C','E','R','T','I','F','I','C','A','T', -'E','-','-','-','-','-',0 }; -static const WCHAR CERT_TRAILER_START_W[] = { -'-','-','-','-','-','E','N','D',' ',0 }; -static const WCHAR CERT_REQUEST_HEADER_W[] = { -'-','-','-','-','-','B','E','G','I','N',' ','N','E','W',' ','C','E','R','T', -'I','F','I','C','A','T','E',' ','R','E','Q','U','E','S','T','-','-','-','-','-',0 }; -static const WCHAR CERT_REQUEST_TRAILER_W[] = { -'-','-','-','-','-','E','N','D',' ','N','E','W',' ','C','E','R','T','I','F', -'I','C','A','T','E',' ','R','E','Q','U','E','S','T','-','-','-','-','-',0 }; -static const WCHAR X509_HEADER_W[] = { -'-','-','-','-','-','B','E','G','I','N',' ','X','5','0','9',' ','C','R','L', -'-','-','-','-','-',0 }; -static const WCHAR X509_TRAILER_W[] = { -'-','-','-','-','-','E','N','D',' ','X','5','0','9',' ','C','R','L','-','-', -'-','-','-',0 }; +static const WCHAR CERT_HEADER_W[] = L"-----BEGIN CERTIFICATE-----"; +static const WCHAR CERT_HEADER_START_W[] = L"-----BEGIN "; +static const WCHAR CERT_DELIMITER_W[] = L"-----"; +static const WCHAR CERT_TRAILER_W[] = L"-----END CERTIFICATE-----"; +static const WCHAR CERT_TRAILER_START_W[] = L"-----END "; +static const WCHAR CERT_REQUEST_HEADER_W[] = L"-----BEGIN NEW CERTIFICATE REQUEST-----"; +static const WCHAR CERT_REQUEST_TRAILER_W[] = L"-----END NEW CERTIFICATE REQUEST-----"; +static const WCHAR X509_HEADER_W[] = L"-----BEGIN X509 CRL-----"; +static const WCHAR X509_TRAILER_W[] = L"-----END X509 CRL-----"; static const char b64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; @@ -93,84 +77,90 @@ static BOOL EncodeBinaryToBinaryA(const BYTE *pbBinary, return ret; } -static LONG encodeBase64A(const BYTE *in_buf, int in_len, LPCSTR sep, +static DWORD stradd(LPSTR ptr, LPCSTR end, LPCSTR s, DWORD slen) +{ + if (ptr + slen > end) + slen = end - ptr; + memcpy(ptr, s, slen); + return slen; +} + +static DWORD encodeBase64A(const BYTE *in_buf, int in_len, LPCSTR sep, char* out_buf, DWORD *out_len) { int div, i; const BYTE *d = in_buf; int bytes = (in_len*8 + 5)/6, pad_bytes = (bytes % 4) ? 4 - (bytes % 4) : 0; - DWORD needed; LPSTR ptr; + LPCSTR end; + char chunk[4]; - TRACE("bytes is %d, pad bytes is %d\n", bytes, pad_bytes); - needed = bytes + pad_bytes; - needed += (needed / 64 + (needed % 64 ? 1 : 0)) * strlen(sep); - needed++; - - if (needed > *out_len) + if (!out_buf) { - *out_len = needed; - return ERROR_INSUFFICIENT_BUFFER; + TRACE("bytes is %d, pad bytes is %d\n", bytes, pad_bytes); + *out_len = bytes + pad_bytes; + *out_len += (*out_len / 64 + (*out_len % 64 ? 1 : 0)) * strlen(sep) + 1; + return 0; } - else - *out_len = needed; /* Three bytes of input give 4 chars of output */ div = in_len / 3; ptr = out_buf; + end = ptr + *out_len; i = 0; - while (div > 0) + while (div > 0 && ptr < end) { - if (i && i % 64 == 0) - { - strcpy(ptr, sep); - ptr += strlen(sep); - } /* first char is the first 6 bits of the first byte*/ - *ptr++ = b64[ ( d[0] >> 2) & 0x3f ]; + chunk[0] = b64[ ( d[0] >> 2) & 0x3f ]; /* second char is the last 2 bits of the first byte and the first 4 * bits of the second byte */ - *ptr++ = b64[ ((d[0] << 4) & 0x30) | (d[1] >> 4 & 0x0f)]; + chunk[1] = b64[ ((d[0] << 4) & 0x30) | (d[1] >> 4 & 0x0f)]; /* third char is the last 4 bits of the second byte and the first 2 * bits of the third byte */ - *ptr++ = b64[ ((d[1] << 2) & 0x3c) | (d[2] >> 6 & 0x03)]; + chunk[2] = b64[ ((d[1] << 2) & 0x3c) | (d[2] >> 6 & 0x03)]; /* fourth char is the remaining 6 bits of the third byte */ - *ptr++ = b64[ d[2] & 0x3f]; + chunk[3] = b64[ d[2] & 0x3f]; + ptr += stradd(ptr, end, chunk, 4); i += 4; d += 3; div--; + + if (i && i % 64 == 0) + ptr += stradd(ptr, end, sep, strlen(sep)); } switch(pad_bytes) { case 1: /* first char is the first 6 bits of the first byte*/ - *ptr++ = b64[ ( d[0] >> 2) & 0x3f ]; + chunk[0] = b64[ ( d[0] >> 2) & 0x3f ]; /* second char is the last 2 bits of the first byte and the first 4 * bits of the second byte */ - *ptr++ = b64[ ((d[0] << 4) & 0x30) | (d[1] >> 4 & 0x0f)]; + chunk[1] = b64[ ((d[0] << 4) & 0x30) | (d[1] >> 4 & 0x0f)]; /* third char is the last 4 bits of the second byte padded with * two zeroes */ - *ptr++ = b64[ ((d[1] << 2) & 0x3c) ]; + chunk[2] = b64[ ((d[1] << 2) & 0x3c) ]; /* fourth char is a = to indicate one byte of padding */ - *ptr++ = '='; + chunk[3] = '='; + ptr += stradd(ptr, end, chunk, 4); break; case 2: /* first char is the first 6 bits of the first byte*/ - *ptr++ = b64[ ( d[0] >> 2) & 0x3f ]; + chunk[0] = b64[ ( d[0] >> 2) & 0x3f ]; /* second char is the last 2 bits of the first byte padded with * four zeroes*/ - *ptr++ = b64[ ((d[0] << 4) & 0x30)]; + chunk[1] = b64[ ((d[0] << 4) & 0x30)]; /* third char is = to indicate padding */ - *ptr++ = '='; + chunk[2] = '='; /* fourth char is = to indicate padding */ - *ptr++ = '='; + chunk[3] = '='; + ptr += stradd(ptr, end, chunk, 4); break; } - strcpy(ptr, sep); + ptr += stradd(ptr, end, sep, strlen(sep)); - return ERROR_SUCCESS; + return ptr - out_buf; } static BOOL BinaryToBase64A(const BYTE *pbBinary, @@ -215,32 +205,34 @@ static BOOL BinaryToBase64A(const BYTE *pbBinary, if (pszString) { + LPSTR ptr = pszString; + DWORD size = *pcchString; + LPSTR end = ptr + size; + + if (header) + { + ptr += stradd(ptr, end, header, strlen(header)); + ptr += stradd(ptr, end, sep, strlen(sep)); + size = end - ptr; + } + ptr += encodeBase64A(pbBinary, cbBinary, sep, ptr, &size); + if (trailer) + { + ptr += stradd(ptr, end, trailer, strlen(trailer)); + ptr += stradd(ptr, end, sep, strlen(sep)); + } + + if (ptr < end) + *ptr = '\0'; + if (charsNeeded <= *pcchString) { - LPSTR ptr = pszString; - DWORD size = charsNeeded; - - if (header) - { - strcpy(ptr, header); - ptr += strlen(ptr); - strcpy(ptr, sep); - ptr += strlen(sep); - } - encodeBase64A(pbBinary, cbBinary, sep, ptr, &size); - ptr += size - 1; - if (trailer) - { - strcpy(ptr, trailer); - ptr += strlen(ptr); - strcpy(ptr, sep); - } *pcchString = charsNeeded - 1; } else { *pcchString = charsNeeded; - SetLastError(ERROR_INSUFFICIENT_BUFFER); + SetLastError(ERROR_MORE_DATA); ret = FALSE; } } @@ -250,12 +242,69 @@ static BOOL BinaryToBase64A(const BYTE *pbBinary, return ret; } +static BOOL BinaryToHexRawA(const BYTE *bin, DWORD nbin, DWORD flags, char *str, DWORD *nstr) +{ + static const char hex[] = "0123456789abcdef"; + DWORD needed; + + if (flags & CRYPT_STRING_NOCRLF) + needed = 0; + else if (flags & CRYPT_STRING_NOCR) + needed = 1; + else + needed = 2; + + needed += nbin * 2 + 1; + + if (!str) + { + *nstr = needed; + return TRUE; + } + + if (needed > *nstr && *nstr < 3) + { + SetLastError(ERROR_MORE_DATA); + return FALSE; + } + + nbin = min(nbin, (*nstr - 1) / 2); + + while (nbin--) + { + *str++ = hex[(*bin >> 4) & 0xf]; + *str++ = hex[*bin & 0xf]; + bin++; + } + + if (needed > *nstr) + { + *str = 0; + SetLastError(ERROR_MORE_DATA); + return FALSE; + } + + if (flags & CRYPT_STRING_NOCR) + { + *str++ = '\n'; + } + else if (!(flags & CRYPT_STRING_NOCRLF)) + { + *str++ = '\r'; + *str++ = '\n'; + } + + *str = 0; + *nstr = needed - 1; + return TRUE; +} + BOOL WINAPI CryptBinaryToStringA(const BYTE *pbBinary, DWORD cbBinary, DWORD dwFlags, LPSTR pszString, DWORD *pcchString) { BinaryToStringAFunc encoder = NULL; - TRACE("(%p, %d, %08x, %p, %p)\n", pbBinary, cbBinary, dwFlags, pszString, + TRACE("(%p, %ld, %08lx, %p, %p)\n", pbBinary, cbBinary, dwFlags, pszString, pcchString); if (!pbBinary) @@ -280,11 +329,14 @@ BOOL WINAPI CryptBinaryToStringA(const BYTE *pbBinary, case CRYPT_STRING_BASE64X509CRLHEADER: encoder = BinaryToBase64A; break; + case CRYPT_STRING_HEXRAW: + encoder = BinaryToHexRawA; + break; case CRYPT_STRING_HEX: case CRYPT_STRING_HEXASCII: case CRYPT_STRING_HEXADDR: case CRYPT_STRING_HEXASCIIADDR: - FIXME("Unimplemented type %d\n", dwFlags & 0x0fffffff); + FIXME("Unimplemented type %ld\n", dwFlags & 0x0fffffff); /* fall through */ default: SetLastError(ERROR_INVALID_PARAMETER); @@ -324,7 +376,7 @@ static LONG encodeBase64W(const BYTE *in_buf, int in_len, LPCWSTR sep, TRACE("bytes is %d, pad bytes is %d\n", bytes, pad_bytes); needed = bytes + pad_bytes; - needed += (needed / 64 + (needed % 64 ? 1 : 0)) * strlenW(sep); + needed += (needed / 64 + (needed % 64 ? 1 : 0)) * lstrlenW(sep); needed++; if (needed > *out_len) @@ -342,11 +394,6 @@ static LONG encodeBase64W(const BYTE *in_buf, int in_len, LPCWSTR sep, i = 0; while (div > 0) { - if (i && i % 64 == 0) - { - strcpyW(ptr, sep); - ptr += strlenW(sep); - } /* first char is the first 6 bits of the first byte*/ *ptr++ = b64[ ( d[0] >> 2) & 0x3f ]; /* second char is the last 2 bits of the first byte and the first 4 @@ -360,6 +407,12 @@ static LONG encodeBase64W(const BYTE *in_buf, int in_len, LPCWSTR sep, i += 4; d += 3; div--; + + if (i && i % 64 == 0) + { + lstrcpyW(ptr, sep); + ptr += lstrlenW(sep); + } } switch(pad_bytes) @@ -388,7 +441,7 @@ static LONG encodeBase64W(const BYTE *in_buf, int in_len, LPCWSTR sep, *ptr++ = '='; break; } - strcpyW(ptr, sep); + lstrcpyW(ptr, sep); return ERROR_SUCCESS; } @@ -396,17 +449,16 @@ static LONG encodeBase64W(const BYTE *in_buf, int in_len, LPCWSTR sep, static BOOL BinaryToBase64W(const BYTE *pbBinary, DWORD cbBinary, DWORD dwFlags, LPWSTR pszString, DWORD *pcchString) { - static const WCHAR crlf[] = { '\r','\n',0 }, lf[] = { '\n',0 }, empty[] = {0}; BOOL ret = TRUE; LPCWSTR header = NULL, trailer = NULL, sep; DWORD charsNeeded; if (dwFlags & CRYPT_STRING_NOCR) - sep = lf; + sep = L"\n"; else if (dwFlags & CRYPT_STRING_NOCRLF) - sep = empty; + sep = L""; else - sep = crlf; + sep = L"\r\n"; switch (dwFlags & 0x0fffffff) { case CRYPT_STRING_BASE64: @@ -429,9 +481,9 @@ static BOOL BinaryToBase64W(const BYTE *pbBinary, charsNeeded = 0; encodeBase64W(pbBinary, cbBinary, sep, NULL, &charsNeeded); if (header) - charsNeeded += strlenW(header) + strlenW(sep); + charsNeeded += lstrlenW(header) + lstrlenW(sep); if (trailer) - charsNeeded += strlenW(trailer) + strlenW(sep); + charsNeeded += lstrlenW(trailer) + lstrlenW(sep); if (pszString) { @@ -442,25 +494,25 @@ static BOOL BinaryToBase64W(const BYTE *pbBinary, if (header) { - strcpyW(ptr, header); - ptr += strlenW(ptr); - strcpyW(ptr, sep); - ptr += strlenW(sep); + lstrcpyW(ptr, header); + ptr += lstrlenW(ptr); + lstrcpyW(ptr, sep); + ptr += lstrlenW(sep); } encodeBase64W(pbBinary, cbBinary, sep, ptr, &size); ptr += size - 1; if (trailer) { - strcpyW(ptr, trailer); - ptr += strlenW(ptr); - strcpyW(ptr, sep); + lstrcpyW(ptr, trailer); + ptr += lstrlenW(ptr); + lstrcpyW(ptr, sep); } *pcchString = charsNeeded - 1; } else { *pcchString = charsNeeded; - SetLastError(ERROR_INSUFFICIENT_BUFFER); + SetLastError(ERROR_MORE_DATA); ret = FALSE; } } @@ -470,12 +522,131 @@ static BOOL BinaryToBase64W(const BYTE *pbBinary, return ret; } +static BOOL BinaryToHexRawW(const BYTE *bin, DWORD nbin, DWORD flags, LPWSTR str, DWORD *nstr) +{ + static const WCHAR hex[] = L"0123456789abcdef"; + DWORD needed; + + if (flags & CRYPT_STRING_NOCRLF) + needed = 0; + else if (flags & CRYPT_STRING_NOCR) + needed = 1; + else + needed = 2; + + needed += nbin * 2 + 1; + + if (!str) + { + *nstr = needed; + return TRUE; + } + + if (needed > *nstr) + { + SetLastError(ERROR_MORE_DATA); + return FALSE; + } + + while (nbin--) + { + *str++ = hex[(*bin >> 4) & 0xf]; + *str++ = hex[*bin & 0xf]; + bin++; + } + + if (flags & CRYPT_STRING_NOCR) + *str++ = '\n'; + else if (!(flags & CRYPT_STRING_NOCRLF)) + { + *str++ = '\r'; + *str++ = '\n'; + } + + *str = 0; + *nstr = needed - 1; + return TRUE; +} + +static BOOL binary_to_hexW(const BYTE *bin, DWORD nbin, DWORD flags, LPWSTR str, DWORD *nstr) +{ + static const WCHAR hex[] = L"0123456789abcdef"; + DWORD needed, i; + + needed = nbin * 3; /* spaces + terminating \0 */ + + if (flags & CRYPT_STRING_NOCR) + { + needed += (nbin + 7) / 16; /* space every 16 characters */ + needed += 1; /* terminating \n */ + } + else if (!(flags & CRYPT_STRING_NOCRLF)) + { + needed += (nbin + 7) / 16; /* space every 16 characters */ + needed += nbin / 16 + 1; /* LF every 16 characters + terminating \r */ + + if (nbin % 16) + needed += 1; /* terminating \n */ + } + + if (!str) + { + *nstr = needed; + return TRUE; + } + + if (needed > *nstr) + { + SetLastError(ERROR_MORE_DATA); + return FALSE; + } + + for (i = 0; i < nbin; i++) + { + *str++ = hex[(bin[i] >> 4) & 0xf]; + *str++ = hex[bin[i] & 0xf]; + + if (i >= nbin - 1) break; + + if (i && !(flags & CRYPT_STRING_NOCRLF)) + { + if (!((i + 1) % 16)) + { + if (flags & CRYPT_STRING_NOCR) + *str++ = '\n'; + else + { + *str++ = '\r'; + *str++ = '\n'; + } + continue; + } + else if (!((i + 1) % 8)) + *str++ = ' '; + } + + *str++ = ' '; + } + + if (flags & CRYPT_STRING_NOCR) + *str++ = '\n'; + else if (!(flags & CRYPT_STRING_NOCRLF)) + { + *str++ = '\r'; + *str++ = '\n'; + } + + *str = 0; + *nstr = needed - 1; + return TRUE; +} + BOOL WINAPI CryptBinaryToStringW(const BYTE *pbBinary, DWORD cbBinary, DWORD dwFlags, LPWSTR pszString, DWORD *pcchString) { BinaryToStringWFunc encoder = NULL; - TRACE("(%p, %d, %08x, %p, %p)\n", pbBinary, cbBinary, dwFlags, pszString, + TRACE("(%p, %ld, %08lx, %p, %p)\n", pbBinary, cbBinary, dwFlags, pszString, pcchString); if (!pbBinary) @@ -500,11 +671,16 @@ BOOL WINAPI CryptBinaryToStringW(const BYTE *pbBinary, case CRYPT_STRING_BASE64X509CRLHEADER: encoder = BinaryToBase64W; break; + case CRYPT_STRING_HEXRAW: + encoder = BinaryToHexRawW; + break; case CRYPT_STRING_HEX: + encoder = binary_to_hexW; + break; case CRYPT_STRING_HEXASCII: case CRYPT_STRING_HEXADDR: case CRYPT_STRING_HEXASCIIADDR: - FIXME("Unimplemented type %d\n", dwFlags & 0x0fffffff); + FIXME("Unimplemented type %ld\n", dwFlags & 0x0fffffff); /* fall through */ default: SetLastError(ERROR_INVALID_PARAMETER); @@ -769,6 +945,120 @@ static LONG DecodeAnyA(LPCSTR pszString, DWORD cchString, return ret; } +static BOOL is_hex_string_special_char(WCHAR c) +{ + switch (c) + { + case '-': + case ',': + case ' ': + case '\t': + case '\r': + case '\n': + return TRUE; + + default: + return FALSE; + } +} + +static WCHAR wchar_from_str(BOOL wide, const void **str, DWORD *len) +{ + WCHAR c; + + if (!*len) + return 0; + + --*len; + if (wide) + c = *(*(const WCHAR **)str)++; + else + c = *(*(const char **)str)++; + + return c ? c : 0xffff; +} + +static BYTE digit_from_char(WCHAR c) +{ + if (c >= '0' && c <= '9') + return c - '0'; + c = towlower(c); + if (c >= 'a' && c <= 'f') + return c - 'a' + 0xa; + return 0xff; +} + +static LONG string_to_hex(const void* str, BOOL wide, DWORD len, BYTE *hex, DWORD *hex_len, + DWORD *skipped, DWORD *ret_flags) +{ + unsigned int byte_idx = 0; + BYTE d1, d2; + WCHAR c; + + if (!str || !hex_len) + return ERROR_INVALID_PARAMETER; + + if (!len) + len = wide ? wcslen(str) : strlen(str); + + if (wide && !len) + return ERROR_INVALID_PARAMETER; + + if (skipped) + *skipped = 0; + if (ret_flags) + *ret_flags = 0; + + while ((c = wchar_from_str(wide, &str, &len)) && is_hex_string_special_char(c)) + ; + + while ((d1 = digit_from_char(c)) != 0xff) + { + if ((d2 = digit_from_char(wchar_from_str(wide, &str, &len))) == 0xff) + { + if (!hex) + *hex_len = 0; + return ERROR_INVALID_DATA; + } + + if (hex && byte_idx < *hex_len) + hex[byte_idx] = (d1 << 4) | d2; + + ++byte_idx; + + do + { + c = wchar_from_str(wide, &str, &len); + } while (c == '-' || c == ','); + } + + while (c) + { + if (!is_hex_string_special_char(c)) + { + if (!hex) + *hex_len = 0; + return ERROR_INVALID_DATA; + } + c = wchar_from_str(wide, &str, &len); + } + + if (hex && byte_idx > *hex_len) + return ERROR_MORE_DATA; + + if (ret_flags) + *ret_flags = CRYPT_STRING_HEX; + + *hex_len = byte_idx; + + return ERROR_SUCCESS; +} + +static LONG string_to_hexA(const char *str, DWORD len, BYTE *hex, DWORD *hex_len, DWORD *skipped, DWORD *ret_flags) +{ + return string_to_hex(str, FALSE, len, hex, hex_len, skipped, ret_flags); +} + BOOL WINAPI CryptStringToBinaryA(LPCSTR pszString, DWORD cchString, DWORD dwFlags, BYTE *pbBinary, DWORD *pcbBinary, DWORD *pdwSkip, DWORD *pdwFlags) @@ -776,7 +1066,7 @@ BOOL WINAPI CryptStringToBinaryA(LPCSTR pszString, StringToBinaryAFunc decoder; LONG ret; - TRACE("(%s, %d, %08x, %p, %p, %p, %p)\n", debugstr_an(pszString, cchString ? cchString : -1), + TRACE("(%s, %ld, %08lx, %p, %p, %p, %p)\n", debugstr_an(pszString, cchString ? cchString : -1), cchString, dwFlags, pbBinary, pcbBinary, pdwSkip, pdwFlags); if (!pszString) @@ -814,10 +1104,12 @@ BOOL WINAPI CryptStringToBinaryA(LPCSTR pszString, decoder = DecodeAnyA; break; case CRYPT_STRING_HEX: + decoder = string_to_hexA; + break; case CRYPT_STRING_HEXASCII: case CRYPT_STRING_HEXADDR: case CRYPT_STRING_HEXASCIIADDR: - FIXME("Unimplemented type %d\n", dwFlags & 0x7fffffff); + FIXME("Unimplemented type %ld\n", dwFlags & 0x7fffffff); /* fall through */ default: SetLastError(ERROR_INVALID_PARAMETER); @@ -856,27 +1148,27 @@ static LONG Base64WithHeaderAndTrailerToBinaryW(LPCWSTR pszString, LPCWSTR trailerBegins; size_t dataLength; - if ((strlenW(header) + strlenW(trailer)) > cchString) + if ((lstrlenW(header) + lstrlenW(trailer)) > cchString) { return ERROR_INVALID_DATA; } - if (!(headerBegins = strstrW(pszString, header))) + if (!(headerBegins = wcsstr(pszString, header))) { TRACE("Can't find %s in %s.\n", debugstr_w(header), debugstr_wn(pszString, cchString)); return ERROR_INVALID_DATA; } - dataBegins = headerBegins + strlenW(header); - if (!(dataBegins = strstrW(dataBegins, CERT_DELIMITER_W))) + dataBegins = headerBegins + lstrlenW(header); + if (!(dataBegins = wcsstr(dataBegins, CERT_DELIMITER_W))) { return ERROR_INVALID_DATA; } - dataBegins += strlenW(CERT_DELIMITER_W); + dataBegins += lstrlenW(CERT_DELIMITER_W); if (*dataBegins == '\r') dataBegins++; if (*dataBegins == '\n') dataBegins++; - if (!(trailerBegins = strstrW(dataBegins, trailer))) + if (!(trailerBegins = wcsstr(dataBegins, trailer))) { return ERROR_INVALID_DATA; } @@ -980,6 +1272,11 @@ static LONG DecodeAnyW(LPCWSTR pszString, DWORD cchString, return ret; } +static LONG string_to_hexW(const WCHAR *str, DWORD len, BYTE *hex, DWORD *hex_len, DWORD *skipped, DWORD *ret_flags) +{ + return string_to_hex(str, TRUE, len, hex, hex_len, skipped, ret_flags); +} + BOOL WINAPI CryptStringToBinaryW(LPCWSTR pszString, DWORD cchString, DWORD dwFlags, BYTE *pbBinary, DWORD *pcbBinary, DWORD *pdwSkip, DWORD *pdwFlags) @@ -987,7 +1284,7 @@ BOOL WINAPI CryptStringToBinaryW(LPCWSTR pszString, StringToBinaryWFunc decoder; LONG ret; - TRACE("(%s, %d, %08x, %p, %p, %p, %p)\n", debugstr_wn(pszString, cchString ? cchString : -1), + TRACE("(%s, %ld, %08lx, %p, %p, %p, %p)\n", debugstr_wn(pszString, cchString ? cchString : -1), cchString, dwFlags, pbBinary, pcbBinary, pdwSkip, pdwFlags); if (!pszString) @@ -1025,17 +1322,19 @@ BOOL WINAPI CryptStringToBinaryW(LPCWSTR pszString, decoder = DecodeAnyW; break; case CRYPT_STRING_HEX: + decoder = string_to_hexW; + break; case CRYPT_STRING_HEXASCII: case CRYPT_STRING_HEXADDR: case CRYPT_STRING_HEXASCIIADDR: - FIXME("Unimplemented type %d\n", dwFlags & 0x7fffffff); + FIXME("Unimplemented type %ld\n", dwFlags & 0x7fffffff); /* fall through */ default: SetLastError(ERROR_INVALID_PARAMETER); return FALSE; } if (!cchString) - cchString = strlenW(pszString); + cchString = lstrlenW(pszString); ret = decoder(pszString, cchString, pbBinary, pcbBinary, pdwSkip, pdwFlags); if (ret) SetLastError(ret); diff --git a/dll/win32/crypt32/cert.c b/dll/win32/crypt32/cert.c index 0065ba69d48..7b1edaa2236 100644 --- a/dll/win32/crypt32/cert.c +++ b/dll/win32/crypt32/cert.c @@ -20,12 +20,11 @@ #include #include -#define NONAMELESSUNION #include "ntstatus.h" #define WIN32_NO_STATUS #include "windef.h" #include "winbase.h" -#include "wine/winternl.h" +#include "winternl.h" #define CRYPT_OID_INFO_HAS_EXTRA_FIELDS #include "wincrypt.h" #include "snmp.h" @@ -33,7 +32,6 @@ #include "winnls.h" #include "rpc.h" #include "wine/debug.h" -#include "wine/unicode.h" #include "crypt32_private.h" WINE_DEFAULT_DEBUG_CHANNEL(crypt); @@ -63,7 +61,7 @@ BOOL WINAPI CertAddEncodedCertificateToStore(HCERTSTORE hCertStore, pbCertEncoded, cbCertEncoded); BOOL ret; - TRACE("(%p, %08x, %p, %d, %08x, %p)\n", hCertStore, dwCertEncodingType, + TRACE("(%p, %08lx, %p, %ld, %08lx, %p)\n", hCertStore, dwCertEncodingType, pbCertEncoded, cbCertEncoded, dwAddDisposition, ppCertContext); if (cert) @@ -83,7 +81,7 @@ BOOL WINAPI CertAddEncodedCertificateToSystemStoreA(LPCSTR pszCertStoreName, HCERTSTORE store; BOOL ret = FALSE; - TRACE("(%s, %p, %d)\n", debugstr_a(pszCertStoreName), pbCertEncoded, + TRACE("(%s, %p, %ld)\n", debugstr_a(pszCertStoreName), pbCertEncoded, cbCertEncoded); store = CertOpenSystemStoreA(0, pszCertStoreName); @@ -102,7 +100,7 @@ BOOL WINAPI CertAddEncodedCertificateToSystemStoreW(LPCWSTR pszCertStoreName, HCERTSTORE store; BOOL ret = FALSE; - TRACE("(%s, %p, %d)\n", debugstr_w(pszCertStoreName), pbCertEncoded, + TRACE("(%s, %p, %ld)\n", debugstr_w(pszCertStoreName), pbCertEncoded, cbCertEncoded); store = CertOpenSystemStoreW(0, pszCertStoreName); @@ -201,7 +199,7 @@ static BOOL add_cert_to_store(WINECRYPT_CERTSTORE *store, const CERT_CONTEXT *ce break; } default: - FIXME("Unimplemented add disposition %d\n", add_disposition); + FIXME("Unimplemented add disposition %ld\n", add_disposition); SetLastError(E_INVALIDARG); return FALSE; } @@ -288,7 +286,7 @@ BOOL WINAPI CertAddCertificateContextToStore(HCERTSTORE hCertStore, PCCERT_CONTE { WINECRYPT_CERTSTORE *store = hCertStore; - TRACE("(%p, %p, %08x, %p)\n", hCertStore, pCertContext, dwAddDisposition, ppStoreContext); + TRACE("(%p, %p, %08lx, %p)\n", hCertStore, pCertContext, dwAddDisposition, ppStoreContext); return add_cert_to_store(store, pCertContext, dwAddDisposition, FALSE, ppStoreContext); } @@ -301,7 +299,7 @@ BOOL WINAPI CertAddCertificateLinkToStore(HCERTSTORE hCertStore, WINECRYPT_CERTSTORE *store = (WINECRYPT_CERTSTORE*)hCertStore; if (!(calls++)) - FIXME("(%p, %p, %08x, %p): semi-stub\n", hCertStore, pCertContext, + FIXME("(%p, %p, %08lx, %p): semi-stub\n", hCertStore, pCertContext, dwAddDisposition, ppCertContext); if (store->dwMagic != WINE_CRYPTCERTSTORE_MAGIC) return FALSE; @@ -322,7 +320,7 @@ PCCERT_CONTEXT WINAPI CertCreateCertificateContext(DWORD dwCertEncodingType, PCERT_INFO certInfo = NULL; DWORD size = 0; - TRACE("(%08x, %p, %d)\n", dwCertEncodingType, pbCertEncoded, + TRACE("(%08lx, %p, %ld)\n", dwCertEncodingType, pbCertEncoded, cbCertEncoded); if ((dwCertEncodingType & CERT_ENCODING_TYPE_MASK) != X509_ASN_ENCODING) @@ -383,7 +381,7 @@ DWORD WINAPI CertEnumCertificateContextProperties(PCCERT_CONTEXT pCertContext, cert_t *cert = cert_from_ptr(pCertContext); DWORD ret; - TRACE("(%p, %d)\n", pCertContext, dwPropId); + TRACE("(%p, %ld)\n", pCertContext, dwPropId); if (cert->base.properties) ret = ContextPropertyList_EnumPropIDs(cert->base.properties, dwPropId); @@ -428,20 +426,114 @@ static BOOL CertContext_CopyParam(void *pvData, DWORD *pcbData, const void *pb, return ret; } +void CRYPT_ConvertKeyContext(const struct store_CERT_KEY_CONTEXT *src, CERT_KEY_CONTEXT *dst) +{ + dst->cbSize = sizeof(*dst); + dst->hCryptProv = src->hCryptProv; + dst->dwKeySpec = src->dwKeySpec; +} + +/* + * Fix offsets in a continuous block of memory of CRYPT_KEY_PROV_INFO with + * its associated data. + */ +static void fix_KeyProvInfoProperty(CRYPT_KEY_PROV_INFO *info) +{ + BYTE *data; + DWORD i; + + data = (BYTE *)(info + 1) + sizeof(CRYPT_KEY_PROV_PARAM) * info->cProvParam; + + if (info->pwszContainerName) + { + info->pwszContainerName = (LPWSTR)data; + data += (lstrlenW(info->pwszContainerName) + 1) * sizeof(WCHAR); + } + + if (info->pwszProvName) + { + info->pwszProvName = (LPWSTR)data; + data += (lstrlenW(info->pwszProvName) + 1) * sizeof(WCHAR); + } + + info->rgProvParam = info->cProvParam ? (CRYPT_KEY_PROV_PARAM *)(info + 1) : NULL; + + for (i = 0; i < info->cProvParam; i++) + { + info->rgProvParam[i].pbData = info->rgProvParam[i].cbData ? data : NULL; + data += info->rgProvParam[i].cbData; + } +} + +/* + * Copy to a continuous block of memory of CRYPT_KEY_PROV_INFO with + * its associated data. + */ +static void copy_KeyProvInfoProperty(const CRYPT_KEY_PROV_INFO *from, CRYPT_KEY_PROV_INFO *to) +{ + BYTE *data; + DWORD i; + + data = (BYTE *)(to + 1) + sizeof(CRYPT_KEY_PROV_PARAM) * from->cProvParam; + + if (from->pwszContainerName) + { + to->pwszContainerName = (LPWSTR)data; + lstrcpyW((LPWSTR)data, from->pwszContainerName); + data += (lstrlenW(from->pwszContainerName) + 1) * sizeof(WCHAR); + } + else + to->pwszContainerName = NULL; + + if (from->pwszProvName) + { + to->pwszProvName = (LPWSTR)data; + lstrcpyW((LPWSTR)data, from->pwszProvName); + data += (lstrlenW(from->pwszProvName) + 1) * sizeof(WCHAR); + } + else + to->pwszProvName = NULL; + + to->dwProvType = from->dwProvType; + to->dwFlags = from->dwFlags; + to->cProvParam = from->cProvParam; + to->rgProvParam = from->cProvParam ? (CRYPT_KEY_PROV_PARAM *)(to + 1) : NULL; + to->dwKeySpec = from->dwKeySpec; + + for (i = 0; i < from->cProvParam; i++) + { + to->rgProvParam[i].dwParam = from->rgProvParam[i].dwParam; + to->rgProvParam[i].dwFlags = from->rgProvParam[i].dwFlags; + to->rgProvParam[i].cbData = from->rgProvParam[i].cbData; + to->rgProvParam[i].pbData = from->rgProvParam[i].cbData ? data : NULL; + memcpy(data, from->rgProvParam[i].pbData, from->rgProvParam[i].cbData); + data += from->rgProvParam[i].cbData; + } +} + static BOOL CertContext_GetProperty(cert_t *cert, DWORD dwPropId, void *pvData, DWORD *pcbData) { BOOL ret; CRYPT_DATA_BLOB blob; - TRACE("(%p, %d, %p, %p)\n", cert, dwPropId, pvData, pcbData); + TRACE("(%p, %ld, %p, %p)\n", cert, dwPropId, pvData, pcbData); if (cert->base.properties) ret = ContextPropertyList_FindProperty(cert->base.properties, dwPropId, &blob); else ret = FALSE; if (ret) + { + CERT_KEY_CONTEXT ctx; + if (dwPropId == CERT_KEY_CONTEXT_PROP_ID) + { + CRYPT_ConvertKeyContext((const struct store_CERT_KEY_CONTEXT *)blob.pbData, &ctx); + blob.pbData = (BYTE *)&ctx; + blob.cbData = ctx.cbSize; + } ret = CertContext_CopyParam(pvData, pcbData, blob.pbData, blob.cbData); + } else { /* Implicit properties */ @@ -520,41 +612,13 @@ static BOOL CertContext_GetProperty(cert_t *cert, DWORD dwPropId, return ret; } -void CRYPT_FixKeyProvInfoPointers(PCRYPT_KEY_PROV_INFO info) -{ - DWORD i, containerLen, provNameLen; - LPBYTE data = (LPBYTE)info + sizeof(CRYPT_KEY_PROV_INFO); - - info->pwszContainerName = (LPWSTR)data; - containerLen = (lstrlenW(info->pwszContainerName) + 1) * sizeof(WCHAR); - data += containerLen; - - info->pwszProvName = (LPWSTR)data; - provNameLen = (lstrlenW(info->pwszProvName) + 1) * sizeof(WCHAR); - data += provNameLen; - - if (info->cProvParam) - { - info->rgProvParam = (PCRYPT_KEY_PROV_PARAM)data; - data += info->cProvParam * sizeof(CRYPT_KEY_PROV_PARAM); - - for (i = 0; i < info->cProvParam; i++) - { - info->rgProvParam[i].pbData = data; - data += info->rgProvParam[i].cbData; - } - } - else - info->rgProvParam = NULL; -} - BOOL WINAPI CertGetCertificateContextProperty(PCCERT_CONTEXT pCertContext, DWORD dwPropId, void *pvData, DWORD *pcbData) { cert_t *cert = cert_from_ptr(pCertContext); BOOL ret; - TRACE("(%p, %d, %p, %p)\n", pCertContext, dwPropId, pvData, pcbData); + TRACE("(%p, %ld, %p, %p)\n", pCertContext, dwPropId, pvData, pcbData); switch (dwPropId) { @@ -581,10 +645,9 @@ BOOL WINAPI CertGetCertificateContextProperty(PCCERT_CONTEXT pCertContext, break; } case CERT_KEY_PROV_INFO_PROP_ID: - ret = CertContext_GetProperty(cert, dwPropId, pvData, - pcbData); + ret = CertContext_GetProperty(cert, dwPropId, pvData, pcbData); if (ret && pvData) - CRYPT_FixKeyProvInfoPointers(pvData); + fix_KeyProvInfoProperty(pvData); break; default: ret = CertContext_GetProperty(cert, dwPropId, pvData, @@ -595,95 +658,74 @@ BOOL WINAPI CertGetCertificateContextProperty(PCCERT_CONTEXT pCertContext, return ret; } -/* Copies key provider info from from into to, where to is assumed to be a - * contiguous buffer of memory large enough for from and all its associated - * data, but whose pointers are uninitialized. - * Upon return, to contains a contiguous copy of from, packed in the following - * order: - * - CRYPT_KEY_PROV_INFO - * - pwszContainerName - * - pwszProvName - * - rgProvParam[0]... +/* + * Create a continuous block of memory for CRYPT_KEY_PROV_INFO with + * its associated data, and add it to the certificate properties. */ -static void CRYPT_CopyKeyProvInfo(PCRYPT_KEY_PROV_INFO to, - const CRYPT_KEY_PROV_INFO *from) -{ - DWORD i; - LPBYTE nextData = (LPBYTE)to + sizeof(CRYPT_KEY_PROV_INFO); - - if (from->pwszContainerName) - { - to->pwszContainerName = (LPWSTR)nextData; - lstrcpyW(to->pwszContainerName, from->pwszContainerName); - nextData += (lstrlenW(from->pwszContainerName) + 1) * sizeof(WCHAR); - } - else - to->pwszContainerName = NULL; - if (from->pwszProvName) - { - to->pwszProvName = (LPWSTR)nextData; - lstrcpyW(to->pwszProvName, from->pwszProvName); - nextData += (lstrlenW(from->pwszProvName) + 1) * sizeof(WCHAR); - } - else - to->pwszProvName = NULL; - to->dwProvType = from->dwProvType; - to->dwFlags = from->dwFlags; - to->cProvParam = from->cProvParam; - to->rgProvParam = (PCRYPT_KEY_PROV_PARAM)nextData; - nextData += to->cProvParam * sizeof(CRYPT_KEY_PROV_PARAM); - to->dwKeySpec = from->dwKeySpec; - for (i = 0; i < to->cProvParam; i++) - { - memcpy(&to->rgProvParam[i], &from->rgProvParam[i], - sizeof(CRYPT_KEY_PROV_PARAM)); - to->rgProvParam[i].pbData = nextData; - memcpy(to->rgProvParam[i].pbData, from->rgProvParam[i].pbData, - from->rgProvParam[i].cbData); - nextData += from->rgProvParam[i].cbData; - } -} - -static BOOL CertContext_SetKeyProvInfoProperty(CONTEXT_PROPERTY_LIST *properties, - const CRYPT_KEY_PROV_INFO *info) +static BOOL CertContext_SetKeyProvInfoProperty(CONTEXT_PROPERTY_LIST *properties, const CRYPT_KEY_PROV_INFO *info) { + CRYPT_KEY_PROV_INFO *prop; + DWORD size = sizeof(CRYPT_KEY_PROV_INFO), i; BOOL ret; - LPBYTE buf = NULL; - DWORD size = sizeof(CRYPT_KEY_PROV_INFO), i, containerSize, provNameSize; if (info->pwszContainerName) - containerSize = (lstrlenW(info->pwszContainerName) + 1) * sizeof(WCHAR); - else - containerSize = 0; + size += (lstrlenW(info->pwszContainerName) + 1) * sizeof(WCHAR); if (info->pwszProvName) - provNameSize = (lstrlenW(info->pwszProvName) + 1) * sizeof(WCHAR); - else - provNameSize = 0; - size += containerSize + provNameSize; + size += (lstrlenW(info->pwszProvName) + 1) * sizeof(WCHAR); + for (i = 0; i < info->cProvParam; i++) size += sizeof(CRYPT_KEY_PROV_PARAM) + info->rgProvParam[i].cbData; - buf = CryptMemAlloc(size); - if (buf) + + prop = CryptMemAlloc(size); + if (!prop) { - CRYPT_CopyKeyProvInfo((PCRYPT_KEY_PROV_INFO)buf, info); - ret = ContextPropertyList_SetProperty(properties, - CERT_KEY_PROV_INFO_PROP_ID, buf, size); - CryptMemFree(buf); + SetLastError(ERROR_OUTOFMEMORY); + return FALSE; } - else - ret = FALSE; + + copy_KeyProvInfoProperty(info, prop); + + ret = ContextPropertyList_SetProperty(properties, CERT_KEY_PROV_INFO_PROP_ID, (const BYTE *)prop, size); + CryptMemFree(prop); + return ret; } +static BOOL CertContext_SetKeyContextProperty(CONTEXT_PROPERTY_LIST *properties, + const CERT_KEY_CONTEXT *keyContext) +{ + struct store_CERT_KEY_CONTEXT ctx; + + ctx.cbSize = sizeof(ctx); + ctx.hCryptProv = keyContext->hCryptProv; + ctx.dwKeySpec = keyContext->dwKeySpec; + + return ContextPropertyList_SetProperty(properties, CERT_KEY_CONTEXT_PROP_ID, + (const BYTE *)&ctx, ctx.cbSize); +} + static BOOL CertContext_SetProperty(cert_t *cert, DWORD dwPropId, DWORD dwFlags, const void *pvData) { BOOL ret; - TRACE("(%p, %d, %08x, %p)\n", cert, dwPropId, dwFlags, pvData); + TRACE("(%p, %ld, %08lx, %p)\n", cert, dwPropId, dwFlags, pvData); if (!cert->base.properties) ret = FALSE; + else if (dwPropId >= CERT_FIRST_USER_PROP_ID && dwPropId <= CERT_LAST_USER_PROP_ID) + { + if (pvData) + { + const CRYPT_DATA_BLOB *blob = pvData; + ret = ContextPropertyList_SetProperty(cert->base.properties, dwPropId, blob->pbData, blob->cbData); + } + else + { + ContextPropertyList_RemoveProperty(cert->base.properties, dwPropId); + ret = TRUE; + } + } else { switch (dwPropId) @@ -733,7 +775,6 @@ static BOOL CertContext_SetProperty(cert_t *cert, DWORD dwPropId, } break; case CERT_KEY_CONTEXT_PROP_ID: - { if (pvData) { const CERT_KEY_CONTEXT *keyContext = pvData; @@ -744,8 +785,7 @@ static BOOL CertContext_SetProperty(cert_t *cert, DWORD dwPropId, ret = FALSE; } else - ret = ContextPropertyList_SetProperty(cert->base.properties, dwPropId, - (const BYTE *)keyContext, keyContext->cbSize); + ret = CertContext_SetKeyContextProperty(cert->base.properties, pvData); } else { @@ -753,7 +793,6 @@ static BOOL CertContext_SetProperty(cert_t *cert, DWORD dwPropId, ret = TRUE; } break; - } case CERT_KEY_PROV_INFO_PROP_ID: if (pvData) ret = CertContext_SetKeyProvInfoProperty(cert->base.properties, pvData); @@ -788,7 +827,7 @@ static BOOL CertContext_SetProperty(cert_t *cert, DWORD dwPropId, break; } default: - FIXME("%d: stub\n", dwPropId); + FIXME("%ld: stub\n", dwPropId); ret = FALSE; } } @@ -801,7 +840,7 @@ BOOL WINAPI CertSetCertificateContextProperty(PCCERT_CONTEXT pCertContext, { BOOL ret; - TRACE("(%p, %d, %08x, %p)\n", pCertContext, dwPropId, dwFlags, pvData); + TRACE("(%p, %ld, %08lx, %p)\n", pCertContext, dwPropId, dwFlags, pvData); /* Handle special cases for "read-only"/invalid prop IDs. Windows just * crashes on most of these, I'll be safer. @@ -826,7 +865,7 @@ BOOL WINAPI CertSetCertificateContextProperty(PCCERT_CONTEXT pCertContext, * the certificate if info is NULL. The acquired provider is returned in * *phCryptProv, and the key spec for the provider is returned in *pdwKeySpec. */ -static BOOL CRYPT_AcquirePrivateKeyFromProvInfo(PCCERT_CONTEXT pCert, +static BOOL CRYPT_AcquirePrivateKeyFromProvInfo(PCCERT_CONTEXT pCert, DWORD dwFlags, PCRYPT_KEY_PROV_INFO info, HCRYPTPROV *phCryptProv, DWORD *pdwKeySpec) { DWORD size = 0; @@ -838,7 +877,7 @@ static BOOL CRYPT_AcquirePrivateKeyFromProvInfo(PCCERT_CONTEXT pCert, CERT_KEY_PROV_INFO_PROP_ID, 0, &size); if (ret) { - info = HeapAlloc(GetProcessHeap(), 0, size); + info = CryptMemAlloc(size); if (info) { ret = CertGetCertificateContextProperty(pCert, @@ -857,7 +896,7 @@ static BOOL CRYPT_AcquirePrivateKeyFromProvInfo(PCCERT_CONTEXT pCert, if (ret) { ret = CryptAcquireContextW(phCryptProv, info->pwszContainerName, - info->pwszProvName, info->dwProvType, 0); + info->pwszProvName, info->dwProvType, (dwFlags & CRYPT_ACQUIRE_SILENT_FLAG) ? CRYPT_SILENT : 0); if (ret) { DWORD i; @@ -874,7 +913,7 @@ static BOOL CRYPT_AcquirePrivateKeyFromProvInfo(PCCERT_CONTEXT pCert, SetLastError(CRYPT_E_NO_KEY_PROPERTY); } if (allocated) - HeapFree(GetProcessHeap(), 0, info); + CryptMemFree(info); return ret; } @@ -886,8 +925,9 @@ BOOL WINAPI CryptAcquireCertificatePrivateKey(PCCERT_CONTEXT pCert, PCRYPT_KEY_PROV_INFO info = NULL; CERT_KEY_CONTEXT keyContext; DWORD size; + PCCERT_CONTEXT cert_in_store = NULL; - TRACE("(%p, %08x, %p, %p, %p, %p)\n", pCert, dwFlags, pvReserved, + TRACE("(%p, %08lx, %p, %p, %p, %p)\n", pCert, dwFlags, pvReserved, phCryptProv, pdwKeySpec, pfCallerFreeProv); if (dwFlags & CRYPT_ACQUIRE_USE_PROV_INFO_FLAG) @@ -896,9 +936,36 @@ BOOL WINAPI CryptAcquireCertificatePrivateKey(PCCERT_CONTEXT pCert, ret = CertGetCertificateContextProperty(pCert, CERT_KEY_PROV_INFO_PROP_ID, 0, &size); + + if (!ret) + { + HCERTSTORE hstore; + + hstore = CertOpenStore(CERT_STORE_PROV_SYSTEM_W, 0, 0, + CERT_SYSTEM_STORE_CURRENT_USER, L"My"); + if (hstore) + { + cert_in_store = CertFindCertificateInStore(hstore, pCert->dwCertEncodingType, 0, + CERT_FIND_EXISTING, pCert, NULL); + if (cert_in_store) + { + ret = CertGetCertificateContextProperty(cert_in_store, CERT_KEY_PROV_INFO_PROP_ID, 0, &size); + if (ret) + pCert = cert_in_store; + else + { + CertFreeCertificateContext(cert_in_store); + cert_in_store = NULL; + } + } + + CertCloseStore(hstore, 0); + } + } + if (ret) { - info = HeapAlloc(GetProcessHeap(), 0, size); + info = CryptMemAlloc(size); ret = CertGetCertificateContextProperty(pCert, CERT_KEY_PROV_INFO_PROP_ID, info, &size); if (ret) @@ -919,12 +986,12 @@ BOOL WINAPI CryptAcquireCertificatePrivateKey(PCCERT_CONTEXT pCert, if (pdwKeySpec) *pdwKeySpec = keyContext.dwKeySpec; if (pfCallerFreeProv) - *pfCallerFreeProv = !cache; + *pfCallerFreeProv = FALSE; } } if (!*phCryptProv) { - ret = CRYPT_AcquirePrivateKeyFromProvInfo(pCert, info, + ret = CRYPT_AcquirePrivateKeyFromProvInfo(pCert, dwFlags, info, &keyContext.hCryptProv, &keyContext.dwKeySpec); if (ret) { @@ -948,7 +1015,10 @@ BOOL WINAPI CryptAcquireCertificatePrivateKey(PCCERT_CONTEXT pCert, } } } - HeapFree(GetProcessHeap(), 0, info); + CryptMemFree(info); + if (cert_in_store) + CertFreeCertificateContext(cert_in_store); + if (ret) SetLastError(0); return ret; } @@ -1009,10 +1079,10 @@ static BOOL container_matches_cert(PCCERT_CONTEXT pCert, LPCSTR container, if (matches) { keyProvInfo->pwszContainerName = - CryptMemAlloc((strlenW(containerW) + 1) * sizeof(WCHAR)); + CryptMemAlloc((lstrlenW(containerW) + 1) * sizeof(WCHAR)); if (keyProvInfo->pwszContainerName) { - strcpyW(keyProvInfo->pwszContainerName, containerW); + lstrcpyW(keyProvInfo->pwszContainerName, containerW); keyProvInfo->dwKeySpec = AT_SIGNATURE; } else @@ -1066,7 +1136,7 @@ static BOOL find_matching_provider(PCCERT_CONTEXT pCert, DWORD dwFlags) DWORD index = 0, cbProvName = 0; CRYPT_KEY_PROV_INFO keyProvInfo; - TRACE("(%p, %08x)\n", pCert, dwFlags); + TRACE("(%p, %08lx)\n", pCert, dwFlags); memset(&keyProvInfo, 0, sizeof(keyProvInfo)); while (ret && !found) @@ -1155,7 +1225,7 @@ BOOL WINAPI CryptFindCertificateKeyProvInfo(PCCERT_CONTEXT pCert, { BOOL matches; - TRACE("(%p, %08x, %p)\n", pCert, dwFlags, pvReserved); + TRACE("(%p, %08lx, %p)\n", pCert, dwFlags, pvReserved); matches = cert_prov_info_matches_cert(pCert); if (!matches) @@ -1168,7 +1238,7 @@ BOOL WINAPI CertCompareCertificate(DWORD dwCertEncodingType, { BOOL ret; - TRACE("(%08x, %p, %p)\n", dwCertEncodingType, pCertId1, pCertId2); + TRACE("(%08lx, %p, %p)\n", dwCertEncodingType, pCertId1, pCertId2); ret = CertCompareCertificateName(dwCertEncodingType, &pCertId1->Issuer, &pCertId2->Issuer) && CertCompareIntegerBlob(&pCertId1->SerialNumber, @@ -1182,7 +1252,7 @@ BOOL WINAPI CertCompareCertificateName(DWORD dwCertEncodingType, { BOOL ret; - TRACE("(%08x, %p, %p)\n", dwCertEncodingType, pCertName1, pCertName2); + TRACE("(%08lx, %p, %p)\n", dwCertEncodingType, pCertName1, pCertName2); if (pCertName1->cbData == pCertName2->cbData) { @@ -1246,7 +1316,7 @@ BOOL WINAPI CertComparePublicKeyInfo(DWORD dwCertEncodingType, { BOOL ret; - TRACE("(%08x, %p, %p)\n", dwCertEncodingType, pPublicKey1, pPublicKey2); + TRACE("(%08lx, %p, %p)\n", dwCertEncodingType, pPublicKey1, pPublicKey2); /* RSA public key data should start with ASN_SEQUENCE, * otherwise it's not a RSA_CSP_PUBLICKEYBLOB. @@ -1270,7 +1340,7 @@ BOOL WINAPI CertComparePublicKeyInfo(DWORD dwCertEncodingType, ret = FALSE; break; default: - WARN("Unknown encoding type %08x\n", dwCertEncodingType); + WARN("Unknown encoding type %08lx\n", dwCertEncodingType); /* FALLTHROUGH */ case X509_ASN_ENCODING: { @@ -1307,7 +1377,7 @@ DWORD WINAPI CertGetPublicKeyLength(DWORD dwCertEncodingType, { DWORD len = 0; - TRACE("(%08x, %p)\n", dwCertEncodingType, pPublicKey); + TRACE("(%08lx, %p)\n", dwCertEncodingType, pPublicKey); if (GET_CERT_ENCODING_TYPE(dwCertEncodingType) != X509_ASN_ENCODING) { @@ -1332,9 +1402,9 @@ DWORD WINAPI CertGetPublicKeyLength(DWORD dwCertEncodingType, { HCRYPTKEY key; - TRACE("public key algid %#x (%s)\n", info->u.Algid, debugstr_a(pPublicKey->Algorithm.pszObjId)); + TRACE("public key algid %#x (%s)\n", info->Algid, debugstr_a(pPublicKey->Algorithm.pszObjId)); - ret = CryptImportPublicKeyInfo(I_CryptGetDefaultCryptProv(info->u.Algid), dwCertEncodingType, pPublicKey, &key); + ret = CryptImportPublicKeyInfo(I_CryptGetDefaultCryptProv(info->Algid), dwCertEncodingType, pPublicKey, &key); if (ret) { size = sizeof(len); @@ -1412,10 +1482,15 @@ static BOOL compare_cert_by_name(PCCERT_CONTEXT pCertContext, DWORD dwType, CERT_NAME_BLOB *blob = (CERT_NAME_BLOB *)pvPara, *toCompare; BOOL ret; - if (dwType & CERT_INFO_SUBJECT_FLAG) + if ((dwType & CERT_COMPARE_MASK) == CERT_INFO_SUBJECT_FLAG) toCompare = &pCertContext->pCertInfo->Subject; - else + else if ((dwType & CERT_COMPARE_MASK) == CERT_INFO_ISSUER_FLAG) toCompare = &pCertContext->pCertInfo->Issuer; + else + { + ERR("dwType %08lx doesn't specify SUBJECT or ISSUER\n", dwType); + return FALSE; + } ret = CertCompareCertificateName(pCertContext->dwCertEncodingType, toCompare, blob); return ret; @@ -1467,14 +1542,14 @@ static BOOL compare_cert_by_cert_id(PCCERT_CONTEXT pCertContext, DWORD dwType, { case CERT_ID_ISSUER_SERIAL_NUMBER: ret = CertCompareCertificateName(pCertContext->dwCertEncodingType, - &pCertContext->pCertInfo->Issuer, &id->u.IssuerSerialNumber.Issuer); + &pCertContext->pCertInfo->Issuer, &id->IssuerSerialNumber.Issuer); if (ret) ret = CertCompareIntegerBlob(&pCertContext->pCertInfo->SerialNumber, - &id->u.IssuerSerialNumber.SerialNumber); + &id->IssuerSerialNumber.SerialNumber); break; case CERT_ID_SHA1_HASH: ret = compare_cert_by_sha1_hash(pCertContext, dwType, dwFlags, - &id->u.HashId); + &id->HashId); break; case CERT_ID_KEY_IDENTIFIER: { @@ -1482,7 +1557,7 @@ static BOOL compare_cert_by_cert_id(PCCERT_CONTEXT pCertContext, DWORD dwType, ret = CertGetCertificateContextProperty(pCertContext, CERT_KEY_IDENTIFIER_PROP_ID, NULL, &size); - if (ret && size == id->u.KeyId.cbData) + if (ret && size == id->KeyId.cbData) { LPBYTE buf = CryptMemAlloc(size); @@ -1490,7 +1565,7 @@ static BOOL compare_cert_by_cert_id(PCCERT_CONTEXT pCertContext, DWORD dwType, { CertGetCertificateContextProperty(pCertContext, CERT_KEY_IDENTIFIER_PROP_ID, buf, &size); - ret = !memcmp(buf, id->u.KeyId.pbData, size); + ret = !memcmp(buf, id->KeyId.pbData, size); CryptMemFree(buf); } else @@ -1592,15 +1667,15 @@ static PCCERT_CONTEXT find_cert_by_issuer(HCERTSTORE store, DWORD dwType, if (info->CertIssuer.cbData && info->CertSerialNumber.cbData) { id.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER; - memcpy(&id.u.IssuerSerialNumber.Issuer, &info->CertIssuer, + memcpy(&id.IssuerSerialNumber.Issuer, &info->CertIssuer, sizeof(CERT_NAME_BLOB)); - memcpy(&id.u.IssuerSerialNumber.SerialNumber, + memcpy(&id.IssuerSerialNumber.SerialNumber, &info->CertSerialNumber, sizeof(CRYPT_INTEGER_BLOB)); } else if (info->KeyId.cbData) { id.dwIdChoice = CERT_ID_KEY_IDENTIFIER; - memcpy(&id.u.KeyId, &info->KeyId, sizeof(CRYPT_HASH_BLOB)); + memcpy(&id.KeyId, &info->KeyId, sizeof(CRYPT_HASH_BLOB)); } else ret = FALSE; @@ -1638,9 +1713,9 @@ static PCCERT_CONTEXT find_cert_by_issuer(HCERTSTORE store, DWORD dwType, if (directoryName) { id.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER; - memcpy(&id.u.IssuerSerialNumber.Issuer, - &directoryName->u.DirectoryName, sizeof(CERT_NAME_BLOB)); - memcpy(&id.u.IssuerSerialNumber.SerialNumber, + memcpy(&id.IssuerSerialNumber.Issuer, + &directoryName->DirectoryName, sizeof(CERT_NAME_BLOB)); + memcpy(&id.IssuerSerialNumber.SerialNumber, &info->AuthorityCertSerialNumber, sizeof(CRYPT_INTEGER_BLOB)); } @@ -1653,7 +1728,7 @@ static PCCERT_CONTEXT find_cert_by_issuer(HCERTSTORE store, DWORD dwType, else if (info->KeyId.cbData) { id.dwIdChoice = CERT_ID_KEY_IDENTIFIER; - memcpy(&id.u.KeyId, &info->KeyId, sizeof(CRYPT_HASH_BLOB)); + memcpy(&id.KeyId, &info->KeyId, sizeof(CRYPT_HASH_BLOB)); } else ret = FALSE; @@ -1665,7 +1740,7 @@ static PCCERT_CONTEXT find_cert_by_issuer(HCERTSTORE store, DWORD dwType, } else found = cert_compare_certs_in_store(store, prev, - compare_cert_by_name, CERT_COMPARE_NAME | CERT_COMPARE_SUBJECT_CERT, + compare_cert_by_name, CERT_FIND_SUBJECT_NAME, dwFlags, &subject->pCertInfo->Issuer); return found; } @@ -1677,7 +1752,7 @@ static BOOL compare_cert_by_name_str(PCCERT_CONTEXT pCertContext, DWORD len; BOOL ret = FALSE; - if (dwType & CERT_INFO_SUBJECT_FLAG) + if ((dwType & CERT_COMPARE_MASK) == CERT_INFO_SUBJECT_FLAG) name = &pCertContext->pCertInfo->Subject; else name = &pCertContext->pCertInfo->Issuer; @@ -1689,13 +1764,10 @@ static BOOL compare_cert_by_name_str(PCCERT_CONTEXT pCertContext, if (str) { - LPWSTR ptr; - CertNameToStrW(pCertContext->dwCertEncodingType, name, CERT_SIMPLE_NAME_STR, str, len); - for (ptr = str; *ptr; ptr++) - *ptr = tolowerW(*ptr); - if (strstrW(str, pvPara)) + wcslwr(str); + if (wcsstr(str, pvPara)) ret = TRUE; CryptMemFree(str); } @@ -1717,11 +1789,8 @@ static PCCERT_CONTEXT find_cert_by_name_str_a(HCERTSTORE store, DWORD dwType, if (str) { - LPWSTR ptr; - MultiByteToWideChar(CP_ACP, 0, pvPara, -1, str, len); - for (ptr = str; *ptr; ptr++) - *ptr = tolowerW(*ptr); + wcslwr(str); found = cert_compare_certs_in_store(store, prev, compare_cert_by_name_str, dwType, dwFlags, str); CryptMemFree(str); @@ -1741,17 +1810,13 @@ static PCCERT_CONTEXT find_cert_by_name_str_w(HCERTSTORE store, DWORD dwType, if (pvPara) { - DWORD len = strlenW(pvPara); + DWORD len = lstrlenW(pvPara); LPWSTR str = CryptMemAlloc((len + 1) * sizeof(WCHAR)); if (str) { - LPCWSTR src; - LPWSTR dst; - - for (src = pvPara, dst = str; *src; src++, dst++) - *dst = tolowerW(*src); - *dst = 0; + wcscpy( str, pvPara ); + wcslwr( str ); found = cert_compare_certs_in_store(store, prev, compare_cert_by_name_str, dwType, dwFlags, str); CryptMemFree(str); @@ -1769,8 +1834,9 @@ PCCERT_CONTEXT WINAPI CertFindCertificateInStore(HCERTSTORE hCertStore, PCCERT_CONTEXT ret; CertFindFunc find = NULL; CertCompareFunc compare = NULL; + CERT_ID cert_id; - TRACE("(%p, %08x, %08x, %08x, %p, %p)\n", hCertStore, dwCertEncodingType, + TRACE("(%p, %08lx, %08lx, %08lx, %p, %p)\n", hCertStore, dwCertEncodingType, dwFlags, dwType, pvPara, pPrevCertContext); switch (dwType >> CERT_COMPARE_SHIFT) @@ -1799,6 +1865,11 @@ PCCERT_CONTEXT WINAPI CertFindCertificateInStore(HCERTSTORE hCertStore, case CERT_COMPARE_SUBJECT_CERT: compare = compare_cert_by_subject_cert; break; + case CERT_COMPARE_KEY_IDENTIFIER: + cert_id.dwIdChoice = CERT_ID_KEY_IDENTIFIER; + cert_id.KeyId = *(const CRYPT_HASH_BLOB *)pvPara; + pvPara = &cert_id; + /* fall through */ case CERT_COMPARE_CERT_ID: compare = compare_cert_by_cert_id; break; @@ -1812,7 +1883,7 @@ PCCERT_CONTEXT WINAPI CertFindCertificateInStore(HCERTSTORE hCertStore, compare = compare_cert_by_signature_hash; break; default: - FIXME("find type %08x unimplemented\n", dwType); + FIXME("find type %08lx unimplemented\n", dwType); } if (find) @@ -1831,7 +1902,7 @@ PCCERT_CONTEXT WINAPI CertFindCertificateInStore(HCERTSTORE hCertStore, PCCERT_CONTEXT WINAPI CertGetSubjectCertificateFromStore(HCERTSTORE hCertStore, DWORD dwCertEncodingType, PCERT_INFO pCertId) { - TRACE("(%p, %08x, %p)\n", hCertStore, dwCertEncodingType, pCertId); + TRACE("(%p, %08lx, %p)\n", hCertStore, dwCertEncodingType, pCertId); if (!pCertId) { @@ -1890,7 +1961,7 @@ PCCERT_CONTEXT WINAPI CertGetIssuerCertificateFromStore(HCERTSTORE hCertStore, { PCCERT_CONTEXT ret; - TRACE("(%p, %p, %p, %08x)\n", hCertStore, pSubjectContext, + TRACE("(%p, %p, %p, %08lx)\n", hCertStore, pSubjectContext, pPrevIssuerContext, *pdwFlags); if (!pSubjectContext) @@ -1937,7 +2008,7 @@ BOOL WINAPI CertVerifyRevocation(DWORD dwEncodingType, DWORD dwRevType, { BOOL ret; - TRACE("(%08x, %d, %d, %p, %08x, %p, %p)\n", dwEncodingType, dwRevType, + TRACE("(%08lx, %ld, %ld, %p, %08lx, %p, %p)\n", dwEncodingType, dwRevType, cContext, rgpvContext, dwFlags, pRevPara, pRevStatus); if (pRevStatus->cbSize != sizeof(OLD_CERT_REVOCATION_STATUS) && @@ -2009,7 +2080,7 @@ PCRYPT_ATTRIBUTE WINAPI CertFindAttribute(LPCSTR pszObjId, DWORD cAttr, PCRYPT_ATTRIBUTE ret = NULL; DWORD i; - TRACE("%s %d %p\n", debugstr_a(pszObjId), cAttr, rgAttr); + TRACE("%s %ld %p\n", debugstr_a(pszObjId), cAttr, rgAttr); if (!cAttr) return NULL; @@ -2031,7 +2102,7 @@ PCERT_EXTENSION WINAPI CertFindExtension(LPCSTR pszObjId, DWORD cExtensions, PCERT_EXTENSION ret = NULL; DWORD i; - TRACE("%s %d %p\n", debugstr_a(pszObjId), cExtensions, rgExtensions); + TRACE("%s %ld %p\n", debugstr_a(pszObjId), cExtensions, rgExtensions); if (!cExtensions) return NULL; @@ -2094,10 +2165,10 @@ static BOOL find_matching_rdn_attr(DWORD dwFlags, const CERT_NAME_INFO *name, name->rgRDN[i].rgRDNAttr[j].Value.cbData) match = FALSE; else if (dwFlags & CERT_CASE_INSENSITIVE_IS_RDN_ATTRS_FLAG) - match = !strncmpiW(nameStr, attrStr, + match = !wcsnicmp(nameStr, attrStr, attr->Value.cbData / sizeof(WCHAR)); else - match = !strncmpW(nameStr, attrStr, + match = !wcsncmp(nameStr, attrStr, attr->Value.cbData / sizeof(WCHAR)); TRACE("%s : %s => %d\n", debugstr_wn(nameStr, attr->Value.cbData / sizeof(WCHAR)), @@ -2114,7 +2185,7 @@ static BOOL find_matching_rdn_attr(DWORD dwFlags, const CERT_NAME_INFO *name, name->rgRDN[i].rgRDNAttr[j].Value.cbData) match = FALSE; else if (dwFlags & CERT_CASE_INSENSITIVE_IS_RDN_ATTRS_FLAG) - match = !strncasecmp(nameStr, attrStr, + match = !_strnicmp(nameStr, attrStr, attr->Value.cbData); else match = !strncmp(nameStr, attrStr, attr->Value.cbData); @@ -2136,7 +2207,7 @@ BOOL WINAPI CertIsRDNAttrsInCertificateName(DWORD dwCertEncodingType, DWORD size; BOOL ret; - TRACE("(%08x, %08x, %p, %p)\n", dwCertEncodingType, dwFlags, pCertName, + TRACE("(%08lx, %08lx, %p, %p)\n", dwCertEncodingType, dwFlags, pCertName, pRDN); type = dwFlags & CERT_UNICODE_IS_RDN_ATTRS_FLAG ? X509_UNICODE_NAME : @@ -2191,11 +2262,11 @@ BOOL WINAPI CryptHashCertificate(HCRYPTPROV_LEGACY hCryptProv, ALG_ID Algid, BOOL ret = TRUE; HCRYPTHASH hHash = 0; - TRACE("(%08lx, %d, %08x, %p, %d, %p, %p)\n", hCryptProv, Algid, dwFlags, + TRACE("(%08Ix, %d, %08lx, %p, %ld, %p, %p)\n", hCryptProv, Algid, dwFlags, pbEncoded, cbEncoded, pbComputedHash, pcbComputedHash); if (!hCryptProv) - hCryptProv = I_CryptGetDefaultCryptProv(0); + hCryptProv = I_CryptGetDefaultCryptProv(Algid); if (!Algid) Algid = CALG_SHA1; if (ret) @@ -2213,6 +2284,59 @@ BOOL WINAPI CryptHashCertificate(HCRYPTPROV_LEGACY hCryptProv, ALG_ID Algid, return ret; } +BOOL WINAPI CryptHashCertificate2(LPCWSTR pwszCNGHashAlgid, DWORD dwFlags, + void *pvReserved, const BYTE *pbEncoded, DWORD cbEncoded, BYTE *pbComputedHash, + DWORD *pcbComputedHash) +{ + BCRYPT_HASH_HANDLE hash = NULL; + BCRYPT_ALG_HANDLE alg = NULL; + NTSTATUS status; + DWORD hash_len; + DWORD hash_len_size; + + TRACE("(%s, %08lx, %p, %p, %ld, %p, %p)\n", debugstr_w(pwszCNGHashAlgid), + dwFlags, pvReserved, pbEncoded, cbEncoded, pbComputedHash, pcbComputedHash); + + if ((status = BCryptOpenAlgorithmProvider(&alg, pwszCNGHashAlgid, NULL, 0))) + { + if (status == STATUS_NOT_IMPLEMENTED) + status = STATUS_NOT_FOUND; + goto done; + } + + if ((status = BCryptCreateHash(alg, &hash, NULL, 0, NULL, 0, 0))) + goto done; + + if ((status = BCryptGetProperty(hash, BCRYPT_HASH_LENGTH, (BYTE *)&hash_len, sizeof(hash_len), &hash_len_size, 0))) + goto done; + + if (!pbComputedHash) + { + *pcbComputedHash = hash_len; + goto done; + } + + if (*pcbComputedHash < hash_len) + { + status = ERROR_MORE_DATA; + goto done; + } + + *pcbComputedHash = hash_len; + + if ((status = BCryptHashData(hash, (BYTE *)pbEncoded, cbEncoded, 0))) + goto done; + + if ((status = BCryptFinishHash(hash, pbComputedHash, hash_len, 0))) + goto done; + +done: + if (hash) BCryptDestroyHash(hash); + if (alg) BCryptCloseAlgorithmProvider(alg, 0); + if (status) SetLastError(status); + return !status; +} + BOOL WINAPI CryptHashPublicKeyInfo(HCRYPTPROV_LEGACY hCryptProv, ALG_ID Algid, DWORD dwFlags, DWORD dwCertEncodingType, PCERT_PUBLIC_KEY_INFO pInfo, BYTE *pbComputedHash, DWORD *pcbComputedHash) @@ -2220,7 +2344,7 @@ BOOL WINAPI CryptHashPublicKeyInfo(HCRYPTPROV_LEGACY hCryptProv, ALG_ID Algid, BOOL ret = TRUE; HCRYPTHASH hHash = 0; - TRACE("(%08lx, %d, %08x, %d, %p, %p, %p)\n", hCryptProv, Algid, dwFlags, + TRACE("(%08Ix, %d, %08lx, %ld, %p, %p, %p)\n", hCryptProv, Algid, dwFlags, dwCertEncodingType, pInfo, pbComputedHash, pcbComputedHash); if (!hCryptProv) @@ -2265,7 +2389,7 @@ BOOL WINAPI CryptHashToBeSigned(HCRYPTPROV_LEGACY hCryptProv, CERT_SIGNED_CONTENT_INFO *info; DWORD size; - TRACE("(%08lx, %08x, %p, %d, %p, %d)\n", hCryptProv, dwCertEncodingType, + TRACE("(%08Ix, %08lx, %p, %ld, %p, %ld)\n", hCryptProv, dwCertEncodingType, pbEncoded, cbEncoded, pbComputedHash, *pcbComputedHash); ret = CryptDecodeObjectEx(dwCertEncodingType, X509_CERT, @@ -2286,7 +2410,7 @@ BOOL WINAPI CryptHashToBeSigned(HCRYPTPROV_LEGACY hCryptProv, } else { - ret = CryptCreateHash(hCryptProv, oidInfo->u.Algid, 0, 0, &hHash); + ret = CryptCreateHash(hCryptProv, oidInfo->Algid, 0, 0, &hHash); if (ret) { ret = CryptHashData(hHash, info->ToBeSigned.pbData, @@ -2311,7 +2435,7 @@ BOOL WINAPI CryptSignCertificate(HCRYPTPROV_OR_NCRYPT_KEY_HANDLE hCryptProv, PCCRYPT_OID_INFO info; HCRYPTHASH hHash; - TRACE("(%08lx, %d, %d, %p, %d, %p, %p, %p, %p)\n", hCryptProv, + TRACE("(%08Ix, %ld, %ld, %p, %ld, %p, %p, %p, %p)\n", hCryptProv, dwKeySpec, dwCertEncodingType, pbEncodedToBeSigned, cbEncodedToBeSigned, pSignatureAlgorithm, pvHashAuxInfo, pbSignature, pcbSignature); @@ -2326,7 +2450,7 @@ BOOL WINAPI CryptSignCertificate(HCRYPTPROV_OR_NCRYPT_KEY_HANDLE hCryptProv, { if (!hCryptProv) hCryptProv = I_CryptGetDefaultCryptProv(0); - ret = CryptCreateHash(hCryptProv, info->u.Algid, 0, 0, &hHash); + ret = CryptCreateHash(hCryptProv, info->Algid, 0, 0, &hHash); if (ret) { ret = CryptHashData(hHash, pbEncodedToBeSigned, @@ -2346,7 +2470,7 @@ BOOL WINAPI CryptSignCertificate(HCRYPTPROV_OR_NCRYPT_KEY_HANDLE hCryptProv, } else { - ret = CryptCreateHash(hCryptProv, info->u.Algid, 0, 0, &hHash); + ret = CryptCreateHash(hCryptProv, info->Algid, 0, 0, &hHash); if (ret) { ret = CryptHashData(hHash, pbEncodedToBeSigned, @@ -2369,7 +2493,7 @@ BOOL WINAPI CryptSignAndEncodeCertificate(HCRYPTPROV_OR_NCRYPT_KEY_HANDLE hCrypt BOOL ret; DWORD encodedSize, hashSize; - TRACE("(%08lx, %d, %d, %s, %p, %p, %p, %p, %p)\n", hCryptProv, dwKeySpec, + TRACE("(%08Ix, %ld, %ld, %s, %p, %p, %p, %p, %p)\n", hCryptProv, dwKeySpec, dwCertEncodingType, debugstr_a(lpszStructType), pvStructInfo, pSignatureAlgorithm, pvHashAuxInfo, pbEncoded, pcbEncoded); @@ -2442,14 +2566,14 @@ static BOOL CRYPT_VerifySignature(HCRYPTPROV_LEGACY hCryptProv, DWORD dwCertEnco HCRYPTKEY key; ALG_ID pubKeyID, hashID; - hashID = info->u.Algid; + hashID = info->Algid; if (info->ExtraInfo.cbData >= sizeof(ALG_ID)) pubKeyID = *(ALG_ID *)info->ExtraInfo.pbData; else pubKeyID = hashID; /* Load the default provider if necessary */ if (!hCryptProv) - hCryptProv = I_CryptGetDefaultCryptProv(0); + hCryptProv = I_CryptGetDefaultCryptProv(hashID); ret = CryptImportPublicKeyInfoEx(hCryptProv, dwCertEncodingType, pubKeyInfo, pubKeyID, 0, NULL, &key); if (ret) @@ -2513,9 +2637,8 @@ done: static BOOL CNG_ImportECCPubKey(CERT_PUBLIC_KEY_INFO *pubKeyInfo, BCRYPT_KEY_HANDLE *key) { DWORD blob_magic, ecckey_len, size; - BCRYPT_ALG_HANDLE alg = NULL; + BCRYPT_ALG_HANDLE alg_handle; BCRYPT_ECCKEY_BLOB *ecckey; - const WCHAR *sign_algo; char **ecc_curve; NTSTATUS status; @@ -2538,56 +2661,120 @@ static BOOL CNG_ImportECCPubKey(CERT_PUBLIC_KEY_INFO *pubKeyInfo, BCRYPT_KEY_HAN if (!strcmp(*ecc_curve, szOID_ECC_CURVE_P256)) { - sign_algo = BCRYPT_ECDSA_P256_ALGORITHM; + alg_handle = BCRYPT_ECDSA_P256_ALG_HANDLE; blob_magic = BCRYPT_ECDSA_PUBLIC_P256_MAGIC; } else if (!strcmp(*ecc_curve, szOID_ECC_CURVE_P384)) { - sign_algo = BCRYPT_ECDSA_P384_ALGORITHM; + alg_handle = BCRYPT_ECDSA_P384_ALG_HANDLE; blob_magic = BCRYPT_ECDSA_PUBLIC_P384_MAGIC; } else { FIXME("Unsupported ecc curve type: %s\n", *ecc_curve); - sign_algo = NULL; + alg_handle = NULL; blob_magic = 0; } LocalFree(ecc_curve); - if (!sign_algo) + if (!alg_handle) { SetLastError(NTE_BAD_ALGID); return FALSE; } - if ((status = BCryptOpenAlgorithmProvider(&alg, sign_algo, NULL, 0))) - goto done; - ecckey_len = sizeof(BCRYPT_ECCKEY_BLOB) + pubKeyInfo->PublicKey.cbData - 1; if (!(ecckey = CryptMemAlloc(ecckey_len))) - { - status = STATUS_NO_MEMORY; - goto done; - } + return STATUS_NO_MEMORY; ecckey->dwMagic = blob_magic; ecckey->cbKey = (pubKeyInfo->PublicKey.cbData - 1) / 2; memcpy(ecckey + 1, pubKeyInfo->PublicKey.pbData + 1, pubKeyInfo->PublicKey.cbData - 1); - status = BCryptImportKeyPair(alg, NULL, BCRYPT_ECCPUBLIC_BLOB, key, (BYTE*)ecckey, ecckey_len, 0); + status = BCryptImportKeyPair(alg_handle, NULL, BCRYPT_ECCPUBLIC_BLOB, key, (BYTE*)ecckey, ecckey_len, 0); CryptMemFree(ecckey); -done: - if (alg) BCryptCloseAlgorithmProvider(alg, 0); if (status) SetLastError(RtlNtStatusToDosError(status)); return !status; } -static BOOL CNG_ImportPubKey(CERT_PUBLIC_KEY_INFO *pubKeyInfo, BCRYPT_KEY_HANDLE *key) +static BOOL CNG_ImportRSAPubKey(CERT_PUBLIC_KEY_INFO *info, BCRYPT_KEY_HANDLE *key) +{ + DWORD size, modulus_len, i; + BLOBHEADER *hdr; + RSAPUBKEY *rsapubkey; + BCRYPT_ALG_HANDLE alg_handle; + BCRYPT_RSAKEY_BLOB *rsakey; + BYTE *s, *d; + NTSTATUS status; + + if (!info->PublicKey.cbData) + { + SetLastError(NTE_BAD_ALGID); + return FALSE; + } + + if (!CryptDecodeObjectEx(X509_ASN_ENCODING, RSA_CSP_PUBLICKEYBLOB, info->PublicKey.pbData, + info->PublicKey.cbData, CRYPT_DECODE_ALLOC_FLAG, NULL, &hdr, &size)) + { + WARN("CryptDecodeObjectEx failed\n"); + return FALSE; + } + + if (hdr->aiKeyAlg == CALG_RSA_KEYX) + alg_handle = BCRYPT_RSA_ALG_HANDLE; + else if (hdr->aiKeyAlg == CALG_RSA_SIGN) + alg_handle = BCRYPT_RSA_SIGN_ALG_HANDLE; + else + { + FIXME("Unsupported RSA algorithm: %#x\n", hdr->aiKeyAlg); + LocalFree(hdr); + SetLastError(NTE_BAD_ALGID); + return FALSE; + } + + rsapubkey = (RSAPUBKEY *)(hdr + 1); + + modulus_len = size - sizeof(*hdr) - sizeof(*rsapubkey); + if (modulus_len != rsapubkey->bitlen / 8) + FIXME("RSA pubkey has wrong modulus_len %lu\n", modulus_len); + + size = sizeof(*rsakey) + sizeof(ULONG) + modulus_len; + if (!(rsakey = CryptMemAlloc(size))) + return STATUS_NO_MEMORY; + + rsakey->Magic = BCRYPT_RSAPUBLIC_MAGIC; + rsakey->BitLength = rsapubkey->bitlen; + rsakey->cbPublicExp = sizeof(ULONG); + rsakey->cbModulus = modulus_len; + rsakey->cbPrime1 = 0; + rsakey->cbPrime2 = 0; + + d = (BYTE *)(rsakey + 1); + /* According to MSDN modulus and pubexp are in LE while + * BCRYPT_RSAKEY_BLOB is supposed to have them in BE format */ + *(ULONG *)d = RtlUlongByteSwap(rsapubkey->pubexp); + d += sizeof(ULONG); + s = (BYTE *)(rsapubkey + 1); + for (i = 0; i < modulus_len; i++) + d[i] = s[modulus_len - i - 1]; + + status = BCryptImportKeyPair(alg_handle, NULL, BCRYPT_RSAPUBLIC_BLOB, key, (BYTE *)rsakey, size, 0); + CryptMemFree(rsakey); + + LocalFree(hdr); + if (status) SetLastError(RtlNtStatusToDosError(status)); + return !status; +} + +BOOL CNG_ImportPubKey(CERT_PUBLIC_KEY_INFO *pubKeyInfo, BCRYPT_KEY_HANDLE *key) { if (!strcmp(pubKeyInfo->Algorithm.pszObjId, szOID_ECC_PUBLIC_KEY)) return CNG_ImportECCPubKey(pubKeyInfo, key); + if (!strcmp(pubKeyInfo->Algorithm.pszObjId, szOID_RSA_RSA)) + return CNG_ImportRSAPubKey(pubKeyInfo, key); + FIXME("Unsupported public key type: %s\n", debugstr_a(pubKeyInfo->Algorithm.pszObjId)); SetLastError(NTE_BAD_ALGID); return FALSE; @@ -2596,38 +2783,54 @@ static BOOL CNG_ImportPubKey(CERT_PUBLIC_KEY_INFO *pubKeyInfo, BCRYPT_KEY_HANDLE static BOOL CNG_PrepareSignatureECC(BYTE *encoded_sig, DWORD encoded_size, BYTE **sig_value, DWORD *sig_len) { CERT_ECC_SIGNATURE *ecc_sig; - DWORD size; + DWORD size, r_size, s_size, r_offset, s_offset; int i; if (!CryptDecodeObjectEx(X509_ASN_ENCODING, X509_ECC_SIGNATURE, encoded_sig, encoded_size, CRYPT_DECODE_ALLOC_FLAG, NULL, &ecc_sig, &size)) return FALSE; - if (!ecc_sig->r.cbData || !ecc_sig->s.cbData) + if (!(r_size = ecc_sig->r.cbData) || !(s_size = ecc_sig->s.cbData)) { LocalFree(ecc_sig); SetLastError(ERROR_INVALID_DATA); return FALSE; } + r_size = s_size = max( r_size, s_size ); - *sig_len = ecc_sig->r.cbData + ecc_sig->s.cbData; + *sig_len = r_size + s_size; if (!(*sig_value = CryptMemAlloc(*sig_len))) { LocalFree(ecc_sig); SetLastError(ERROR_OUTOFMEMORY); return FALSE; } + memset( *sig_value, 0, *sig_len ); + + r_offset = r_size - ecc_sig->r.cbData; + s_offset = s_size - ecc_sig->s.cbData; for (i = 0; i < ecc_sig->r.cbData; i++) - (*sig_value)[i] = ecc_sig->r.pbData[ecc_sig->r.cbData - i - 1]; + (*sig_value)[i + r_offset] = ecc_sig->r.pbData[ecc_sig->r.cbData - i - 1]; for (i = 0; i < ecc_sig->s.cbData; i++) - (*sig_value)[ecc_sig->r.cbData + i] = ecc_sig->s.pbData[ecc_sig->s.cbData - i - 1]; + (*sig_value)[r_size + i + s_offset] = ecc_sig->s.pbData[ecc_sig->s.cbData - i - 1]; LocalFree(ecc_sig); return TRUE; } -static BOOL CNG_PrepareSignature(CERT_PUBLIC_KEY_INFO *pubKeyInfo, const CERT_SIGNED_CONTENT_INFO *signedCert, +BOOL cng_prepare_signature(const char *alg_oid, BYTE *encoded_sig, DWORD encoded_sig_len, + BYTE **sig_value, DWORD *sig_len) +{ + if (!strcmp(alg_oid, szOID_ECC_PUBLIC_KEY)) + return CNG_PrepareSignatureECC(encoded_sig, encoded_sig_len, sig_value, sig_len); + + FIXME("Unsupported public key type: %s\n", debugstr_a(alg_oid)); + SetLastError(NTE_BAD_ALGID); + return FALSE; +} + +static BOOL CNG_PrepareCertSignature(CERT_PUBLIC_KEY_INFO *pubKeyInfo, const CERT_SIGNED_CONTENT_INFO *signedCert, BYTE **sig_value, DWORD *sig_len) { BYTE *encoded_sig; @@ -2649,14 +2852,8 @@ static BOOL CNG_PrepareSignature(CERT_PUBLIC_KEY_INFO *pubKeyInfo, const CERT_SI for (i = 0; i < signedCert->Signature.cbData; i++) encoded_sig[i] = signedCert->Signature.pbData[signedCert->Signature.cbData - i - 1]; - if (!strcmp(pubKeyInfo->Algorithm.pszObjId, szOID_ECC_PUBLIC_KEY)) - ret = CNG_PrepareSignatureECC(encoded_sig, signedCert->Signature.cbData, sig_value, sig_len); - else - { - FIXME("Unsupported public key type: %s\n", debugstr_a(pubKeyInfo->Algorithm.pszObjId)); - SetLastError(NTE_BAD_ALGID); - } - + ret = cng_prepare_signature(pubKeyInfo->Algorithm.pszObjId, encoded_sig, signedCert->Signature.cbData, + sig_value, sig_len); CryptMemFree(encoded_sig); return ret; } @@ -2676,13 +2873,13 @@ static BOOL CNG_VerifySignature(HCRYPTPROV_LEGACY hCryptProv, DWORD dwCertEncodi ret = CNG_CalcHash(info->pwszCNGAlgid, signedCert, &hash_value, &hash_len); if (ret) { - ret = CNG_PrepareSignature(pubKeyInfo, signedCert, &sig_value, &sig_len); + ret = CNG_PrepareCertSignature(pubKeyInfo, signedCert, &sig_value, &sig_len); if (ret) { status = BCryptVerifySignature(key, NULL, hash_value, hash_len, sig_value, sig_len, 0); if (status) { - FIXME("Failed to verify signature: %08x\n", status); + FIXME("Failed to verify signature: %08lx\n", status); SetLastError(RtlNtStatusToDosError(status)); ret = FALSE; } @@ -2708,7 +2905,7 @@ static BOOL CRYPT_VerifyCertSignatureFromPublicKeyInfo(HCRYPTPROV_LEGACY hCryptP return FALSE; } - if (info->u.Algid == CALG_OID_INFO_CNG_ONLY) + if (info->Algid == CALG_OID_INFO_CNG_ONLY) return CNG_VerifySignature(hCryptProv, dwCertEncodingType, pubKeyInfo, signedCert, info); else return CRYPT_VerifySignature(hCryptProv, dwCertEncodingType, pubKeyInfo, signedCert, info); @@ -2721,7 +2918,7 @@ BOOL WINAPI CryptVerifyCertificateSignatureEx(HCRYPTPROV_LEGACY hCryptProv, BOOL ret = TRUE; CRYPT_DATA_BLOB subjectBlob; - TRACE("(%08lx, %d, %d, %p, %d, %p, %08x, %p)\n", hCryptProv, + TRACE("(%08Ix, %ld, %ld, %p, %ld, %p, %08lx, %p)\n", hCryptProv, dwCertEncodingType, dwSubjectType, pvSubject, dwIssuerType, pvIssuer, dwFlags, pvReserved); @@ -2813,7 +3010,7 @@ BOOL WINAPI CertGetIntendedKeyUsage(DWORD dwCertEncodingType, PCERT_EXTENSION ext; BOOL ret = FALSE; - TRACE("(%08x, %p, %p, %d)\n", dwCertEncodingType, pCertInfo, pbKeyUsage, + TRACE("(%08lx, %p, %p, %ld)\n", dwCertEncodingType, pCertInfo, pbKeyUsage, cbKeyUsage); ext = CertFindExtension(szOID_KEY_USAGE, pCertInfo->cExtension, @@ -2857,7 +3054,7 @@ BOOL WINAPI CertGetEnhancedKeyUsage(PCCERT_CONTEXT pCertContext, DWORD dwFlags, return FALSE; } - TRACE("(%p, %08x, %p, %d)\n", pCertContext, dwFlags, pUsage, *pcbUsage); + TRACE("(%p, %08lx, %p, %ld)\n", pCertContext, dwFlags, pUsage, *pcbUsage); if (!(dwFlags & CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG)) { @@ -3164,7 +3361,7 @@ BOOL WINAPI CertGetValidUsages(DWORD cCerts, PCCERT_CONTEXT *rghCerts, BOOL allUsagesValid = TRUE; CERT_ENHKEY_USAGE validUsages = { 0, NULL }; - TRACE("(%d, %p, %d, %p, %d)\n", cCerts, rghCerts, *cNumOIDs, + TRACE("(%ld, %p, %d, %p, %ld)\n", cCerts, rghCerts, *cNumOIDs, rghOIDs, *pcbOIDs); for (i = 0; i < cCerts; i++) @@ -3506,7 +3703,7 @@ typedef RPC_STATUS (RPC_ENTRY *RpcStringFreeFunc)(unsigned char **); static HCRYPTPROV CRYPT_CreateKeyProv(void) { HCRYPTPROV hProv = 0; - HMODULE rpcrt = LoadLibraryA("rpcrt4"); + HMODULE rpcrt = LoadLibraryW(L"rpcrt4"); if (rpcrt) { @@ -3560,7 +3757,7 @@ PCCERT_CONTEXT WINAPI CertCreateSelfSignCertificate(HCRYPTPROV_OR_NCRYPT_KEY_HAN PCERT_PUBLIC_KEY_INFO pubKey = NULL; DWORD pubKeySize = 0, dwKeySpec; - TRACE("(%08lx, %p, %08x, %p, %p, %p, %p, %p)\n", hProv, + TRACE("(%08Ix, %p, %08lx, %p, %p, %p, %p, %p)\n", hProv, pSubjectIssuerBlob, dwFlags, pKeyProvInfo, pSignatureAlgorithm, pStartTime, pExtensions, pExtensions); @@ -3669,7 +3866,7 @@ BOOL WINAPI CertVerifyCTLUsage(DWORD dwEncodingType, DWORD dwSubjectType, PCTL_VERIFY_USAGE_PARA pVerifyUsagePara, PCTL_VERIFY_USAGE_STATUS pVerifyUsageStatus) { - FIXME("(0x%x, %d, %p, %p, 0x%x, %p, %p): stub\n", dwEncodingType, + FIXME("(0x%lx, %ld, %p, %p, 0x%lx, %p, %p): stub\n", dwEncodingType, dwSubjectType, pvSubject, pSubjectUsage, dwFlags, pVerifyUsagePara, pVerifyUsageStatus); SetLastError(ERROR_CALL_NOT_IMPLEMENTED); @@ -3680,12 +3877,12 @@ const void * WINAPI CertCreateContext(DWORD dwContextType, DWORD dwEncodingType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, PCERT_CREATE_CONTEXT_PARA pCreatePara) { - TRACE("(0x%x, 0x%x, %p, %d, 0x%08x, %p)\n", dwContextType, dwEncodingType, + TRACE("(0x%lx, 0x%lx, %p, %ld, 0x%08lx, %p)\n", dwContextType, dwEncodingType, pbEncoded, cbEncoded, dwFlags, pCreatePara); if (dwFlags) { - FIXME("dwFlags 0x%08x not handled\n", dwFlags); + FIXME("dwFlags 0x%08lx not handled\n", dwFlags); return NULL; } if (pCreatePara) @@ -3703,7 +3900,7 @@ const void * WINAPI CertCreateContext(DWORD dwContextType, DWORD dwEncodingType, case CERT_STORE_CTL_CONTEXT: return CertCreateCTLContext(dwEncodingType, pbEncoded, cbEncoded); default: - WARN("unknown context type: 0x%x\n", dwContextType); + WARN("unknown context type: 0x%lx\n", dwContextType); return NULL; } } @@ -3711,7 +3908,7 @@ const void * WINAPI CertCreateContext(DWORD dwContextType, DWORD dwEncodingType, BOOL WINAPI CryptSetKeyIdentifierProperty(const CRYPT_HASH_BLOB *pKeyIdentifier, DWORD dwPropId, DWORD dwFlags, LPCWSTR pwszComputerName, void *pvReserved, const void *pvData) { - FIXME("(%p, 0x%x, 0x%x, %s, %p, %p): stub\n", pKeyIdentifier, dwPropId, dwFlags, + FIXME("(%p, 0x%lx, 0x%lx, %s, %p, %p): stub\n", pKeyIdentifier, dwPropId, dwFlags, debugstr_w(pwszComputerName), pvReserved, pvData); return FALSE; } diff --git a/dll/win32/crypt32/chain.c b/dll/win32/crypt32/chain.c index 41c87b7ae7d..5e4288eda37 100644 --- a/dll/win32/crypt32/chain.c +++ b/dll/win32/crypt32/chain.c @@ -16,16 +16,18 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * */ + #include -#define NONAMELESSUNION +#include + #include "windef.h" #include "winbase.h" +#include "winnls.h" #define CERT_CHAIN_PARA_HAS_EXTRA_FIELDS #define CERT_REVOCATION_PARA_HAS_EXTRA_FIELDS #include "wincrypt.h" #include "wininet.h" #include "wine/debug.h" -#include "wine/unicode.h" #include "crypt32_private.h" WINE_DEFAULT_DEBUG_CHANNEL(crypt); @@ -66,8 +68,6 @@ static inline void CRYPT_CloseStores(DWORD cStores, HCERTSTORE *stores) CertCloseStore(stores[i], 0); } -static const WCHAR rootW[] = { 'R','o','o','t',0 }; - /* Finds cert in store by comparing the cert's hashes. */ static PCCERT_CONTEXT CRYPT_FindCertInStore(HCERTSTORE store, PCCERT_CONTEXT cert) @@ -92,7 +92,7 @@ static BOOL CRYPT_CheckRestrictedRoot(HCERTSTORE store) if (store) { - HCERTSTORE rootStore = CertOpenSystemStoreW(0, rootW); + HCERTSTORE rootStore = CertOpenSystemStoreW(0, L"Root"); PCCERT_CONTEXT cert = NULL, check; do { @@ -117,17 +117,13 @@ HCERTCHAINENGINE CRYPT_CreateChainEngine(HCERTSTORE root, DWORD system_store, co CertificateChainEngine *engine; HCERTSTORE worldStores[4]; - static const WCHAR caW[] = { 'C','A',0 }; - static const WCHAR myW[] = { 'M','y',0 }; - static const WCHAR trustW[] = { 'T','r','u','s','t',0 }; - if(!root) { if(config->cbSize >= sizeof(CERT_CHAIN_ENGINE_CONFIG) && config->hExclusiveRoot) root = CertDuplicateStore(config->hExclusiveRoot); else if (config->hRestrictedRoot) root = CertDuplicateStore(config->hRestrictedRoot); else - root = CertOpenStore(CERT_STORE_PROV_SYSTEM_W, 0, 0, system_store, rootW); + root = CertOpenStore(CERT_STORE_PROV_SYSTEM_W, 0, 0, system_store, L"Root"); if(!root) return NULL; } @@ -142,9 +138,9 @@ HCERTCHAINENGINE CRYPT_CreateChainEngine(HCERTSTORE root, DWORD system_store, co engine->hRoot = root; engine->hWorld = CertOpenStore(CERT_STORE_PROV_COLLECTION, 0, 0, CERT_STORE_CREATE_NEW_FLAG, NULL); worldStores[0] = CertDuplicateStore(engine->hRoot); - worldStores[1] = CertOpenStore(CERT_STORE_PROV_SYSTEM_W, 0, 0, system_store, caW); - worldStores[2] = CertOpenStore(CERT_STORE_PROV_SYSTEM_W, 0, 0, system_store, myW); - worldStores[3] = CertOpenStore(CERT_STORE_PROV_SYSTEM_W, 0, 0, system_store, trustW); + worldStores[1] = CertOpenStore(CERT_STORE_PROV_SYSTEM_W, 0, 0, system_store, L"CA"); + worldStores[2] = CertOpenStore(CERT_STORE_PROV_SYSTEM_W, 0, 0, system_store, L"My"); + worldStores[3] = CertOpenStore(CERT_STORE_PROV_SYSTEM_W, 0, 0, system_store, L"Trust"); CRYPT_AddStoresToCollection(engine->hWorld, ARRAY_SIZE(worldStores), worldStores); CRYPT_AddStoresToCollection(engine->hWorld, config->cAdditionalStore, config->rghAdditionalStore); @@ -296,7 +292,7 @@ DWORD CRYPT_IsCertificateSelfSigned(const CERT_CONTEXT *cert) &info->AuthorityCertIssuer.rgAltEntry[i]; if (directoryName) { - if (CertCompareCertificateName(cert->dwCertEncodingType, &directoryName->u.DirectoryName, &cert->pCertInfo->Issuer) + if (CertCompareCertificateName(cert->dwCertEncodingType, &directoryName->DirectoryName, &cert->pCertInfo->Issuer) && CertCompareIntegerBlob(&info->AuthorityCertSerialNumber, &cert->pCertInfo->SerialNumber)) status = CERT_TRUST_HAS_NAME_MATCH_ISSUER; } @@ -613,7 +609,7 @@ static BOOL CRYPT_CheckBasicConstraintsForCA(CertificateChainEngine *engine, chainConstraints->fCA = constraints.fCA; if (!constraints.fCA) { - TRACE_(chain)("chain element %d can't be a CA\n", remainingCAs + 1); + TRACE_(chain)("chain element %ld can't be a CA\n", remainingCAs + 1); validBasicConstraints = FALSE; } else if (constraints.fPathLenConstraint) @@ -625,7 +621,7 @@ static BOOL CRYPT_CheckBasicConstraintsForCA(CertificateChainEngine *engine, constraints.dwPathLenConstraint < chainConstraints->dwPathLenConstraint) { - TRACE_(chain)("setting path length constraint to %d\n", + TRACE_(chain)("setting path length constraint to %ld\n", chainConstraints->dwPathLenConstraint); chainConstraints->fPathLenConstraint = TRUE; chainConstraints->dwPathLenConstraint = @@ -636,7 +632,7 @@ static BOOL CRYPT_CheckBasicConstraintsForCA(CertificateChainEngine *engine, if (chainConstraints->fPathLenConstraint && remainingCAs > chainConstraints->dwPathLenConstraint) { - TRACE_(chain)("remaining CAs %d exceed max path length %d\n", + TRACE_(chain)("remaining CAs %ld exceed max path length %ld\n", remainingCAs, chainConstraints->dwPathLenConstraint); validBasicConstraints = FALSE; *pathLengthConstraintViolated = TRUE; @@ -704,18 +700,18 @@ static BOOL url_matches(LPCWSTR constraint, LPCWSTR name, * The format for URIs is in RFC 2396. * * First, remove any scheme that's present. */ - colon = strchrW(name, ':'); + colon = wcschr(name, ':'); if (colon && *(colon + 1) == '/' && *(colon + 2) == '/') name = colon + 3; /* Next, find the end of the authority component. (The authority is * generally just the hostname, but it may contain a username or a port. * Those are removed next.) */ - authority_end = strchrW(name, '/'); + authority_end = wcschr(name, '/'); if (!authority_end) - authority_end = strchrW(name, '?'); + authority_end = wcschr(name, '?'); if (!authority_end) - authority_end = name + strlenW(name); + authority_end = name + lstrlenW(name); /* Remove any port number from the authority. The userinfo portion * of an authority may contain a colon, so stop if a userinfo portion * is found (indicated by '@'). @@ -726,7 +722,7 @@ static BOOL url_matches(LPCWSTR constraint, LPCWSTR name, if (*colon == ':') authority_end = colon; /* Remove any username from the authority */ - if ((at = strchrW(name, '@'))) + if ((at = wcschr(name, '@'))) name = at; /* Ignore any path or query portion of the URL. */ if (*authority_end) @@ -760,11 +756,11 @@ static BOOL rfc822_name_matches(LPCWSTR constraint, LPCWSTR name, *trustErrorStatus |= CERT_TRUST_INVALID_NAME_CONSTRAINTS; else if (!name) ; /* no match */ - else if (strchrW(constraint, '@')) + else if (wcschr(constraint, '@')) match = !lstrcmpiW(constraint, name); else { - if ((at = strchrW(name, '@'))) + if ((at = wcschr(name, '@'))) match = domain_name_matches(constraint, at + 1); else match = !lstrcmpiW(constraint, name); @@ -822,7 +818,7 @@ static BOOL ip_address_matches(const CRYPT_DATA_BLOB *constraint, { BOOL match = FALSE; - TRACE("(%d, %p), (%d, %p)\n", constraint->cbData, constraint->pbData, + TRACE("(%ld, %p), (%ld, %p)\n", constraint->cbData, constraint->pbData, name->cbData, name->pbData); /* RFC5280, section 4.2.1.10, iPAddress syntax: either 8 or 32 bytes, for @@ -895,27 +891,27 @@ static BOOL alt_name_matches(const CERT_ALT_NAME_ENTRY *name, switch (constraint->dwAltNameChoice) { case CERT_ALT_NAME_RFC822_NAME: - match = rfc822_name_matches(constraint->u.pwszURL, - name->u.pwszURL, trustErrorStatus); + match = rfc822_name_matches(constraint->pwszURL, + name->pwszURL, trustErrorStatus); break; case CERT_ALT_NAME_DNS_NAME: - match = dns_name_matches(constraint->u.pwszURL, - name->u.pwszURL, trustErrorStatus); + match = dns_name_matches(constraint->pwszURL, + name->pwszURL, trustErrorStatus); break; case CERT_ALT_NAME_URL: - match = url_matches(constraint->u.pwszURL, - name->u.pwszURL, trustErrorStatus); + match = url_matches(constraint->pwszURL, + name->pwszURL, trustErrorStatus); break; case CERT_ALT_NAME_IP_ADDRESS: - match = ip_address_matches(&constraint->u.IPAddress, - &name->u.IPAddress, trustErrorStatus); + match = ip_address_matches(&constraint->IPAddress, + &name->IPAddress, trustErrorStatus); break; case CERT_ALT_NAME_DIRECTORY_NAME: - match = directory_name_matches(&constraint->u.DirectoryName, - &name->u.DirectoryName); + match = directory_name_matches(&constraint->DirectoryName, + &name->DirectoryName); break; default: - ERR("name choice %d unsupported in this context\n", + ERR("name choice %ld unsupported in this context\n", constraint->dwAltNameChoice); *trustErrorStatus |= CERT_TRUST_HAS_NOT_SUPPORTED_NAME_CONSTRAINT; @@ -991,7 +987,7 @@ static void compare_alt_name_with_constraints(const CERT_EXTENSION *altNameExt, &subjectAltName->rgAltEntry[i], nameConstraints, trustErrorStatus)) { - TRACE_(chain)("subject alternate name form %d excluded\n", + TRACE_(chain)("subject alternate name form %ld excluded\n", subjectAltName->rgAltEntry[i].dwAltNameChoice); *trustErrorStatus |= CERT_TRUST_HAS_EXCLUDED_NAME_CONSTRAINT; @@ -1001,7 +997,7 @@ static void compare_alt_name_with_constraints(const CERT_EXTENSION *altNameExt, &subjectAltName->rgAltEntry[i], nameConstraints, trustErrorStatus, &nameFormPresent) && nameFormPresent) { - TRACE_(chain)("subject alternate name form %d not permitted\n", + TRACE_(chain)("subject alternate name form %ld not permitted\n", subjectAltName->rgAltEntry[i].dwAltNameChoice); *trustErrorStatus |= CERT_TRUST_HAS_NOT_PERMITTED_NAME_CONSTRAINT; @@ -1026,7 +1022,7 @@ static BOOL rfc822_attr_matches_excluded_name(const CERT_RDN_ATTR *attr, &nameConstraints->rgExcludedSubtree[i].Base; if (constraint->dwAltNameChoice == CERT_ALT_NAME_RFC822_NAME) - match = rfc822_name_matches(constraint->u.pwszRfc822Name, + match = rfc822_name_matches(constraint->pwszRfc822Name, (LPCWSTR)attr->Value.pbData, trustErrorStatus); } return match; @@ -1047,7 +1043,7 @@ static BOOL rfc822_attr_matches_permitted_name(const CERT_RDN_ATTR *attr, if (constraint->dwAltNameChoice == CERT_ALT_NAME_RFC822_NAME) { *present = TRUE; - match = rfc822_name_matches(constraint->u.pwszRfc822Name, + match = rfc822_name_matches(constraint->pwszRfc822Name, (LPCWSTR)attr->Value.pbData, trustErrorStatus); } } @@ -1156,7 +1152,7 @@ static void compare_subject_with_constraints(const CERT_NAME_BLOB *subjectName, &nameConstraints->rgExcludedSubtree[i].Base; if (constraint->dwAltNameChoice == CERT_ALT_NAME_DIRECTORY_NAME && - directory_name_matches(&constraint->u.DirectoryName, subjectName)) + directory_name_matches(&constraint->DirectoryName, subjectName)) { TRACE_(chain)("subject name is excluded\n"); *trustErrorStatus |= @@ -1181,7 +1177,7 @@ static void compare_subject_with_constraints(const CERT_NAME_BLOB *subjectName, if (constraint->dwAltNameChoice == CERT_ALT_NAME_DIRECTORY_NAME) { hasDirectoryConstraint = TRUE; - match = directory_name_matches(&constraint->u.DirectoryName, + match = directory_name_matches(&constraint->DirectoryName, subjectName); } } @@ -1431,34 +1427,34 @@ static void dump_alt_name_entry(const CERT_ALT_NAME_ENTRY *entry) { case CERT_ALT_NAME_OTHER_NAME: TRACE_(chain)("CERT_ALT_NAME_OTHER_NAME, oid = %s\n", - debugstr_a(entry->u.pOtherName->pszObjId)); + debugstr_a(entry->pOtherName->pszObjId)); break; case CERT_ALT_NAME_RFC822_NAME: TRACE_(chain)("CERT_ALT_NAME_RFC822_NAME: %s\n", - debugstr_w(entry->u.pwszRfc822Name)); + debugstr_w(entry->pwszRfc822Name)); break; case CERT_ALT_NAME_DNS_NAME: TRACE_(chain)("CERT_ALT_NAME_DNS_NAME: %s\n", - debugstr_w(entry->u.pwszDNSName)); + debugstr_w(entry->pwszDNSName)); break; case CERT_ALT_NAME_DIRECTORY_NAME: - str = name_value_to_str(&entry->u.DirectoryName); + str = name_value_to_str(&entry->DirectoryName); TRACE_(chain)("CERT_ALT_NAME_DIRECTORY_NAME: %s\n", debugstr_w(str)); CryptMemFree(str); break; case CERT_ALT_NAME_URL: - TRACE_(chain)("CERT_ALT_NAME_URL: %s\n", debugstr_w(entry->u.pwszURL)); + TRACE_(chain)("CERT_ALT_NAME_URL: %s\n", debugstr_w(entry->pwszURL)); break; case CERT_ALT_NAME_IP_ADDRESS: - TRACE_(chain)("CERT_ALT_NAME_IP_ADDRESS: %d bytes\n", - entry->u.IPAddress.cbData); + TRACE_(chain)("CERT_ALT_NAME_IP_ADDRESS: %ld bytes\n", + entry->IPAddress.cbData); break; case CERT_ALT_NAME_REGISTERED_ID: TRACE_(chain)("CERT_ALT_NAME_REGISTERED_ID: %s\n", - debugstr_a(entry->u.pszRegisteredID)); + debugstr_a(entry->pszRegisteredID)); break; default: - TRACE_(chain)("dwAltNameChoice = %d\n", entry->dwAltNameChoice); + TRACE_(chain)("dwAltNameChoice = %ld\n", entry->dwAltNameChoice); } } @@ -1474,7 +1470,7 @@ static void dump_alt_name(LPCSTR type, const CERT_EXTENSION *ext) { DWORD i; - TRACE_(chain)("%d alt name entries:\n", name->cAltEntry); + TRACE_(chain)("%ld alt name entries:\n", name->cAltEntry); for (i = 0; i < name->cAltEntry; i++) dump_alt_name_entry(&name->rgAltEntry[i]); LocalFree(name); @@ -1493,7 +1489,7 @@ static void dump_basic_constraints(const CERT_EXTENSION *ext) TRACE_(chain)("SubjectType: %02x\n", info->SubjectType.pbData[0]); TRACE_(chain)("%s path length constraint\n", info->fPathLenConstraint ? "has" : "doesn't have"); - TRACE_(chain)("path length=%d\n", info->dwPathLenConstraint); + TRACE_(chain)("path length=%ld\n", info->dwPathLenConstraint); LocalFree(info); } } @@ -1511,7 +1507,7 @@ static void dump_basic_constraints2(const CERT_EXTENSION *ext) TRACE_(chain)("can%s be a CA\n", constraints.fCA ? "" : "not"); TRACE_(chain)("%s path length constraint\n", constraints.fPathLenConstraint ? "has" : "doesn't have"); - TRACE_(chain)("path length=%d\n", constraints.dwPathLenConstraint); + TRACE_(chain)("path length=%ld\n", constraints.dwPathLenConstraint); } } @@ -1545,7 +1541,7 @@ static void dump_key_usage(const CERT_EXTENSION *ext) static void dump_general_subtree(const CERT_GENERAL_SUBTREE *subtree) { dump_alt_name_entry(&subtree->Base); - TRACE_(chain)("dwMinimum = %d, fMaximum = %d, dwMaximum = %d\n", + TRACE_(chain)("dwMinimum = %ld, fMaximum = %d, dwMaximum = %ld\n", subtree->dwMinimum, subtree->fMaximum, subtree->dwMaximum); } @@ -1561,11 +1557,11 @@ static void dump_name_constraints(const CERT_EXTENSION *ext) { DWORD i; - TRACE_(chain)("%d permitted subtrees:\n", + TRACE_(chain)("%ld permitted subtrees:\n", nameConstraints->cPermittedSubtree); for (i = 0; i < nameConstraints->cPermittedSubtree; i++) dump_general_subtree(&nameConstraints->rgPermittedSubtree[i]); - TRACE_(chain)("%d excluded subtrees:\n", + TRACE_(chain)("%ld excluded subtrees:\n", nameConstraints->cExcludedSubtree); for (i = 0; i < nameConstraints->cExcludedSubtree; i++) dump_general_subtree(&nameConstraints->rgExcludedSubtree[i]); @@ -1584,12 +1580,12 @@ static void dump_cert_policies(const CERT_EXTENSION *ext) { DWORD i, j; - TRACE_(chain)("%d policies:\n", policies->cPolicyInfo); + TRACE_(chain)("%ld policies:\n", policies->cPolicyInfo); for (i = 0; i < policies->cPolicyInfo; i++) { TRACE_(chain)("policy identifier: %s\n", debugstr_a(policies->rgPolicyInfo[i].pszPolicyIdentifier)); - TRACE_(chain)("%d policy qualifiers:\n", + TRACE_(chain)("%ld policy qualifiers:\n", policies->rgPolicyInfo[i].cPolicyQualifier); for (j = 0; j < policies->rgPolicyInfo[i].cPolicyQualifier; j++) TRACE_(chain)("%s\n", debugstr_a( @@ -1611,7 +1607,7 @@ static void dump_enhanced_key_usage(const CERT_EXTENSION *ext) { DWORD i; - TRACE_(chain)("%d usages:\n", usage->cUsageIdentifier); + TRACE_(chain)("%ld usages:\n", usage->cUsageIdentifier); for (i = 0; i < usage->cUsageIdentifier; i++) TRACE_(chain)("%s\n", usage->rgpszUsageIdentifier[i]); LocalFree(usage); @@ -1691,7 +1687,7 @@ static void dump_element(PCCERT_CONTEXT cert) LPWSTR name = NULL; DWORD len, i; - TRACE_(chain)("%p: version %d\n", cert, cert->pCertInfo->dwVersion); + TRACE_(chain)("%p: version %ld\n", cert, cert->pCertInfo->dwVersion); len = CertGetNameStringW(cert, CERT_NAME_SIMPLE_DISPLAY_TYPE, CERT_NAME_ISSUER_FLAG, NULL, NULL, 0); name = CryptMemAlloc(len * sizeof(WCHAR)); @@ -1715,7 +1711,7 @@ static void dump_element(PCCERT_CONTEXT cert) TRACE_(chain)("valid from %s to %s\n", filetime_to_str(&cert->pCertInfo->NotBefore), filetime_to_str(&cert->pCertInfo->NotAfter)); - TRACE_(chain)("%d extensions\n", cert->pCertInfo->cExtension); + TRACE_(chain)("%ld extensions\n", cert->pCertInfo->cExtension); for (i = 0; i < cert->pCertInfo->cExtension; i++) dump_extension(&cert->pCertInfo->rgExtension[i]); } @@ -1870,7 +1866,7 @@ static BOOL CRYPT_IsCertVersionValid(PCCERT_CONTEXT cert) /* Do nothing, all fields are allowed for V3 certs */ break; default: - WARN_(chain)("invalid cert version %d\n", cert->pCertInfo->dwVersion); + WARN_(chain)("invalid cert version %ld\n", cert->pCertInfo->dwVersion); ret = FALSE; } return ret; @@ -1885,7 +1881,7 @@ static void CRYPT_CheckSimpleChain(CertificateChainEngine *engine, CERT_BASIC_CONSTRAINTS2_INFO constraints = { FALSE, FALSE, 0 }; DWORD status; - TRACE_(chain)("checking chain with %d elements for time %s\n", + TRACE_(chain)("checking chain with %ld elements for time %s\n", chain->cElement, filetime_to_str(time)); for (i = chain->cElement - 1; i >= 0; i--) { @@ -2011,7 +2007,7 @@ static PCCERT_CONTEXT CRYPT_FindIssuer(const CertificateChainEngine *engine, con if(!res) return NULL; - urls = HeapAlloc(GetProcessHeap(), 0, size); + urls = CryptMemAlloc(size); if(!urls) return NULL; @@ -2031,7 +2027,7 @@ static PCCERT_CONTEXT CRYPT_FindIssuer(const CertificateChainEngine *engine, con 0, (void**)&new_cert, NULL, NULL, NULL, NULL); if(!res) { - TRACE("CryptRetrieveObjectByUrlW failed: %u\n", GetLastError()); + TRACE("CryptRetrieveObjectByUrlW failed: %lu\n", GetLastError()); continue; } @@ -2049,7 +2045,7 @@ static PCCERT_CONTEXT CRYPT_FindIssuer(const CertificateChainEngine *engine, con } } - HeapFree(GetProcessHeap(), 0, urls); + CryptMemFree(urls); return issuer; } @@ -2079,9 +2075,9 @@ static PCCERT_CONTEXT CRYPT_GetIssuer(const CertificateChainEngine *engine, if (info->CertIssuer.cbData && info->CertSerialNumber.cbData) { id.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER; - memcpy(&id.u.IssuerSerialNumber.Issuer, &info->CertIssuer, + memcpy(&id.IssuerSerialNumber.Issuer, &info->CertIssuer, sizeof(CERT_NAME_BLOB)); - memcpy(&id.u.IssuerSerialNumber.SerialNumber, + memcpy(&id.IssuerSerialNumber.SerialNumber, &info->CertSerialNumber, sizeof(CRYPT_INTEGER_BLOB)); issuer = CRYPT_FindIssuer(engine, subject, store, CERT_FIND_CERT_ID, &id, flags, prevIssuer); @@ -2095,7 +2091,7 @@ static PCCERT_CONTEXT CRYPT_GetIssuer(const CertificateChainEngine *engine, { id.dwIdChoice = CERT_ID_KEY_IDENTIFIER; - memcpy(&id.u.KeyId, &info->KeyId, sizeof(CRYPT_HASH_BLOB)); + memcpy(&id.KeyId, &info->KeyId, sizeof(CRYPT_HASH_BLOB)); issuer = CRYPT_FindIssuer(engine, subject, store, CERT_FIND_CERT_ID, &id, flags, prevIssuer); if (issuer) { @@ -2135,9 +2131,9 @@ static PCCERT_CONTEXT CRYPT_GetIssuer(const CertificateChainEngine *engine, if (directoryName) { id.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER; - memcpy(&id.u.IssuerSerialNumber.Issuer, - &directoryName->u.DirectoryName, sizeof(CERT_NAME_BLOB)); - memcpy(&id.u.IssuerSerialNumber.SerialNumber, + memcpy(&id.IssuerSerialNumber.Issuer, + &directoryName->DirectoryName, sizeof(CERT_NAME_BLOB)); + memcpy(&id.IssuerSerialNumber.SerialNumber, &info->AuthorityCertSerialNumber, sizeof(CRYPT_INTEGER_BLOB)); @@ -2154,7 +2150,7 @@ static PCCERT_CONTEXT CRYPT_GetIssuer(const CertificateChainEngine *engine, else if (info->KeyId.cbData) { id.dwIdChoice = CERT_ID_KEY_IDENTIFIER; - memcpy(&id.u.KeyId, &info->KeyId, sizeof(CRYPT_HASH_BLOB)); + memcpy(&id.KeyId, &info->KeyId, sizeof(CRYPT_HASH_BLOB)); issuer = CRYPT_FindIssuer(engine, subject, store, CERT_FIND_CERT_ID, &id, flags, prevIssuer); if (issuer) { @@ -2727,7 +2723,7 @@ static void CRYPT_VerifyChainRevocation(PCERT_CHAIN_CONTEXT chain, error = CERT_TRUST_IS_REVOKED; break; default: - WARN("unmapped error %08x\n", revocationStatus.dwError); + WARN("unmapped error %08lx\n", revocationStatus.dwError); error = 0; } if (element) @@ -2863,16 +2859,16 @@ static void dump_usage_match(LPCSTR name, const CERT_USAGE_MATCH *usageMatch) static void dump_chain_para(const CERT_CHAIN_PARA *pChainPara) { - TRACE_(chain)("%d\n", pChainPara->cbSize); + TRACE_(chain)("%ld\n", pChainPara->cbSize); if (pChainPara->cbSize >= sizeof(CERT_CHAIN_PARA_NO_EXTRA_FIELDS)) dump_usage_match("RequestedUsage", &pChainPara->RequestedUsage); if (pChainPara->cbSize >= sizeof(CERT_CHAIN_PARA)) { dump_usage_match("RequestedIssuancePolicy", &pChainPara->RequestedIssuancePolicy); - TRACE_(chain)("%d\n", pChainPara->dwUrlRetrievalTimeout); + TRACE_(chain)("%ld\n", pChainPara->dwUrlRetrievalTimeout); TRACE_(chain)("%d\n", pChainPara->fCheckRevocationFreshnessTime); - TRACE_(chain)("%d\n", pChainPara->dwRevocationFreshnessTime); + TRACE_(chain)("%ld\n", pChainPara->dwRevocationFreshnessTime); } } @@ -2885,7 +2881,7 @@ BOOL WINAPI CertGetCertificateChain(HCERTCHAINENGINE hChainEngine, BOOL ret; CertificateChain *chain = NULL; - TRACE("(%p, %p, %s, %p, %p, %08x, %p, %p)\n", hChainEngine, pCertContext, + TRACE("(%p, %p, %s, %p, %p, %08lx, %p, %p)\n", hChainEngine, pCertContext, debugstr_filetime(pTime), hAdditionalStore, pChainPara, dwFlags, pvReserved, ppChainContext); @@ -2934,7 +2930,7 @@ BOOL WINAPI CertGetCertificateChain(HCERTCHAINENGINE hChainEngine, CRYPT_VerifyChainRevocation(pChain, pTime, hAdditionalStore, pChainPara, dwFlags); CRYPT_CheckUsages(pChain, pChainPara); - TRACE_(chain)("error status: %08x\n", + TRACE_(chain)("error status: %08lx\n", pChain->TrustStatus.dwErrorStatus); if (ppChainContext) *ppChainContext = pChain; @@ -2974,7 +2970,7 @@ PCCERT_CHAIN_CONTEXT WINAPI CertFindChainInStore(HCERTSTORE store, DWORD certEncodingType, DWORD findFlags, DWORD findType, const void *findPara, PCCERT_CHAIN_CONTEXT prevChainContext) { - FIXME("(%p, %08x, %08x, %d, %p, %p): stub\n", store, certEncodingType, + FIXME("(%p, %08lx, %08lx, %ld, %p, %p): stub\n", store, certEncodingType, findFlags, findType, findPara, prevChainContext); return NULL; } @@ -3031,7 +3027,8 @@ static BOOL WINAPI verify_base_policy(LPCSTR szPolicyOID, &pPolicyStatus->lElementIndex); } if (!pPolicyStatus->dwError && - pChainContext->TrustStatus.dwErrorStatus & CERT_TRUST_IS_NOT_TIME_VALID) + pChainContext->TrustStatus.dwErrorStatus & CERT_TRUST_IS_NOT_TIME_VALID && + !(checks & CERT_CHAIN_POLICY_IGNORE_NOT_TIME_VALID_FLAG)) { pPolicyStatus->dwError = CERT_E_EXPIRED; find_element_with_error(pChainContext, @@ -3079,8 +3076,8 @@ static void dump_authenticode_extra_chain_policy_para( { if (extraPara) { - TRACE_(chain)("cbSize = %d\n", extraPara->cbSize); - TRACE_(chain)("dwRegPolicySettings = %08x\n", + TRACE_(chain)("cbSize = %ld\n", extraPara->cbSize); + TRACE_(chain)("dwRegPolicySettings = %08lx\n", extraPara->dwRegPolicySettings); TRACE_(chain)("pSignerInfo = %p\n", extraPara->pSignerInfo); } @@ -3178,8 +3175,8 @@ static BOOL match_dns_to_subject_alt_name(const CERT_EXTENSION *ext, CERT_ALT_NAME_DNS_NAME) { TRACE_(chain)("dNSName: %s\n", debugstr_w( - subjectName->rgAltEntry[i].u.pwszDNSName)); - if (subjectName->rgAltEntry[i].u.pwszDNSName[0] == '*') + subjectName->rgAltEntry[i].pwszDNSName)); + if (subjectName->rgAltEntry[i].pwszDNSName[0] == '*') { LPCWSTR server_name_dot; @@ -3195,16 +3192,16 @@ static BOOL match_dns_to_subject_alt_name(const CERT_EXTENSION *ext, * label, then requires an exact match of the remaining * string. */ - server_name_dot = strchrW(server_name, '.'); + server_name_dot = wcschr(server_name, '.'); if (server_name_dot) { - if (!strcmpiW(server_name_dot, - subjectName->rgAltEntry[i].u.pwszDNSName + 1)) + if (!wcsicmp(server_name_dot, + subjectName->rgAltEntry[i].pwszDNSName + 1)) matches = TRUE; } } - else if (!strcmpiW(server_name, - subjectName->rgAltEntry[i].u.pwszDNSName)) + else if (!wcsicmp(server_name, + subjectName->rgAltEntry[i].pwszDNSName)) matches = TRUE; } } @@ -3214,12 +3211,11 @@ static BOOL match_dns_to_subject_alt_name(const CERT_EXTENSION *ext, } static BOOL find_matching_domain_component(const CERT_NAME_INFO *name, - LPCWSTR component) + const WCHAR *component, size_t len) { - BOOL matches = FALSE; DWORD i, j; - for (i = 0; !matches && i < name->cRDN; i++) + for (i = 0; i < name->cRDN; i++) for (j = 0; j < name->rgRDN[i].cRDNAttr; j++) if (!strcmp(szOID_DOMAIN_COMPONENT, name->rgRDN[i].rgRDNAttr[j].pszObjId)) @@ -3227,15 +3223,16 @@ static BOOL find_matching_domain_component(const CERT_NAME_INFO *name, const CERT_RDN_ATTR *attr; attr = &name->rgRDN[i].rgRDNAttr[j]; - /* Compare with memicmpW rather than strcmpiW in order to avoid + /* Compare with wcsnicmp rather than wcsicmp in order to avoid * a match with a string with an embedded NULL. The component * must match one domain component attribute's entire string * value with a case-insensitive match. */ - matches = !memicmpW(component, (LPCWSTR)attr->Value.pbData, - attr->Value.cbData / sizeof(WCHAR)); + if ((len == attr->Value.cbData / sizeof(WCHAR)) && + !wcsnicmp(component, (LPCWSTR)attr->Value.pbData, len)) + return TRUE; } - return matches; + return FALSE; } static BOOL match_domain_component(LPCWSTR allowed_component, DWORD allowed_len, @@ -3283,7 +3280,7 @@ static BOOL match_domain_component(LPCWSTR allowed_component, DWORD allowed_len, } } if (matches) - matches = tolowerW(*allowed_ptr) == tolowerW(*server_ptr); + matches = towlower(*allowed_ptr) == towlower(*server_ptr); } if (matches && server_ptr - server_component < server_len) { @@ -3301,7 +3298,7 @@ static BOOL match_common_name(LPCWSTR server_name, const CERT_RDN_ATTR *nameAttr LPCWSTR allowed_component = allowed; DWORD allowed_len = nameAttr->Value.cbData / sizeof(WCHAR); LPCWSTR server_component = server_name; - DWORD server_len = strlenW(server_name); + DWORD server_len = lstrlenW(server_name); BOOL matches = TRUE, allow_wildcards = TRUE; TRACE_(chain)("CN = %s\n", debugstr_wn(allowed_component, allowed_len)); @@ -3332,9 +3329,9 @@ static BOOL match_common_name(LPCWSTR server_name, const CERT_RDN_ATTR *nameAttr do { LPCWSTR allowed_dot, server_dot; - allowed_dot = memchrW(allowed_component, '.', + allowed_dot = wmemchr(allowed_component, '.', allowed_len - (allowed_component - allowed)); - server_dot = memchrW(server_component, '.', + server_dot = wmemchr(server_component, '.', server_len - (server_component - server_name)); /* The number of components must match */ if ((!allowed_dot && server_dot) || (allowed_dot && !server_dot)) @@ -3395,25 +3392,20 @@ static BOOL match_dns_to_subject_dn(PCCERT_CONTEXT cert, LPCWSTR server_name) LPCWSTR ptr = server_name; do { - LPCWSTR dot = strchrW(ptr, '.'), end; + LPCWSTR dot = wcschr(ptr, '.'), end; /* 254 is the maximum DNS label length, see RFC 1035 */ - WCHAR component[255]; - DWORD len; + size_t len; - end = dot ? dot : ptr + strlenW(ptr); + end = dot ? dot : ptr + lstrlenW(ptr); len = end - ptr; - if (len >= ARRAY_SIZE(component)) + if (len >= 255) { WARN_(chain)("domain component %s too long\n", debugstr_wn(ptr, len)); matches = FALSE; } - else - { - memcpy(component, ptr, len * sizeof(WCHAR)); - component[len] = 0; - matches = find_matching_domain_component(name, component); - } + else matches = find_matching_domain_component(name, ptr, len); + ptr = dot ? dot + 1 : end; } while (matches && ptr && *ptr); } @@ -3447,9 +3439,9 @@ static void dump_ssl_extra_chain_policy_para(HTTPSPolicyCallbackData *sslPara) { if (sslPara) { - TRACE_(chain)("cbSize = %d\n", sslPara->u.cbSize); - TRACE_(chain)("dwAuthType = %d\n", sslPara->dwAuthType); - TRACE_(chain)("fdwChecks = %08x\n", sslPara->fdwChecks); + TRACE_(chain)("cbSize = %ld\n", sslPara->cbSize); + TRACE_(chain)("dwAuthType = %ld\n", sslPara->dwAuthType); + TRACE_(chain)("fdwChecks = %08lx\n", sslPara->fdwChecks); TRACE_(chain)("pwszServerName = %s\n", debugstr_w(sslPara->pwszServerName)); } @@ -3460,13 +3452,16 @@ static BOOL WINAPI verify_ssl_policy(LPCSTR szPolicyOID, PCERT_CHAIN_POLICY_STATUS pPolicyStatus) { HTTPSPolicyCallbackData *sslPara = NULL; - DWORD checks = 0; + DWORD checks = 0, baseChecks = 0; if (pPolicyPara) + { + baseChecks = pPolicyPara->dwFlags; sslPara = pPolicyPara->pvExtraPolicyPara; + } if (TRACE_ON(chain)) dump_ssl_extra_chain_policy_para(sslPara); - if (sslPara && sslPara->u.cbSize >= sizeof(HTTPSPolicyCallbackData)) + if (sslPara && sslPara->cbSize >= sizeof(HTTPSPolicyCallbackData)) checks = sslPara->fdwChecks; pPolicyStatus->lChainIndex = pPolicyStatus->lElementIndex = -1; if (pChainContext->TrustStatus.dwErrorStatus & @@ -3479,7 +3474,8 @@ static BOOL WINAPI verify_ssl_policy(LPCSTR szPolicyOID, } else if (pChainContext->TrustStatus.dwErrorStatus & CERT_TRUST_IS_UNTRUSTED_ROOT && - !(checks & SECURITY_FLAG_IGNORE_UNKNOWN_CA)) + !(checks & SECURITY_FLAG_IGNORE_UNKNOWN_CA) && + !(baseChecks & CERT_CHAIN_POLICY_ALLOW_UNKNOWN_CA_FLAG)) { pPolicyStatus->dwError = CERT_E_UNTRUSTEDROOT; find_element_with_error(pChainContext, @@ -3497,7 +3493,8 @@ static BOOL WINAPI verify_ssl_policy(LPCSTR szPolicyOID, } else if (pChainContext->TrustStatus.dwErrorStatus & CERT_TRUST_IS_NOT_TIME_VALID && - !(checks & SECURITY_FLAG_IGNORE_CERT_DATE_INVALID)) + !(checks & SECURITY_FLAG_IGNORE_CERT_DATE_INVALID) && + !(baseChecks & CERT_CHAIN_POLICY_IGNORE_NOT_TIME_VALID_FLAG)) { pPolicyStatus->dwError = CERT_E_EXPIRED; find_element_with_error(pChainContext, @@ -3546,7 +3543,7 @@ static BOOL WINAPI verify_ssl_policy(LPCSTR szPolicyOID, if (!pPolicyStatus->dwError && pPolicyPara && pPolicyPara->cbSize >= sizeof(CERT_CHAIN_POLICY_PARA)) { - if (sslPara && sslPara->u.cbSize >= sizeof(HTTPSPolicyCallbackData)) + if (sslPara && sslPara->cbSize >= sizeof(HTTPSPolicyCallbackData)) { if (sslPara->dwAuthType == AUTHTYPE_SERVER && sslPara->pwszServerName && @@ -3661,42 +3658,135 @@ static BYTE msPubKey3[] = { 0x60,0x1e,0x7a,0x5b,0x38,0xc8,0x8f,0xbb,0x04,0x26,0x7c,0xd4,0x16,0x40,0xe5, 0xb6,0x6b,0x6c,0xaa,0x86,0xfd,0x00,0xbf,0xce,0xc1,0x35,0x02,0x03,0x01,0x00, 0x01 }; +/* from Microsoft Root Certificate Authority 2010 */ +static BYTE msPubKey4[] = { +0x30,0x82,0x02,0x0a,0x02,0x82,0x02,0x01,0x00,0xb9,0x08,0x9e,0x28,0xe4,0xe4, +0xec,0x06,0x4e,0x50,0x68,0xb3,0x41,0xc5,0x7b,0xeb,0xae,0xb6,0x8e,0xaf,0x81, +0xba,0x22,0x44,0x1f,0x65,0x34,0x69,0x4c,0xbe,0x70,0x40,0x17,0xf2,0x16,0x7b, +0xe2,0x79,0xfd,0x86,0xed,0x0d,0x39,0xf4,0x1b,0xa8,0xad,0x92,0x90,0x1e,0xcb, +0x3d,0x76,0x8f,0x5a,0xd9,0xb5,0x91,0x10,0x2e,0x3c,0x05,0x8d,0x8a,0x6d,0x24, +0x54,0xe7,0x1f,0xed,0x56,0xad,0x83,0xb4,0x50,0x9c,0x15,0xa5,0x17,0x74,0x88, +0x59,0x20,0xfc,0x08,0xc5,0x84,0x76,0xd3,0x68,0xd4,0x6f,0x28,0x78,0xce,0x5c, +0xb8,0xf3,0x50,0x90,0x44,0xff,0xe3,0x63,0x5f,0xbe,0xa1,0x9a,0x2c,0x96,0x15, +0x04,0xd6,0x07,0xfe,0x1e,0x84,0x21,0xe0,0x42,0x31,0x11,0xc4,0x28,0x36,0x94, +0xcf,0x50,0xa4,0x62,0x9e,0xc9,0xd6,0xab,0x71,0x00,0xb2,0x5b,0x0c,0xe6,0x96, +0xd4,0x0a,0x24,0x96,0xf5,0xff,0xc6,0xd5,0xb7,0x1b,0xd7,0xcb,0xb7,0x21,0x62, +0xaf,0x12,0xdc,0xa1,0x5d,0x37,0xe3,0x1a,0xfb,0x1a,0x46,0x98,0xc0,0x9b,0xc0, +0xe7,0x63,0x1f,0x2a,0x08,0x93,0x02,0x7e,0x1e,0x6a,0x8e,0xf2,0x9f,0x18,0x89, +0xe4,0x22,0x85,0xa2,0xb1,0x84,0x57,0x40,0xff,0xf5,0x0e,0xd8,0x6f,0x9c,0xed, +0xe2,0x45,0x31,0x01,0xcd,0x17,0xe9,0x7f,0xb0,0x81,0x45,0xe3,0xaa,0x21,0x40, +0x26,0xa1,0x72,0xaa,0xa7,0x4f,0x3c,0x01,0x05,0x7e,0xee,0x83,0x58,0xb1,0x5e, +0x06,0x63,0x99,0x62,0x91,0x78,0x82,0xb7,0x0d,0x93,0x0c,0x24,0x6a,0xb4,0x1b, +0xdb,0x27,0xec,0x5f,0x95,0x04,0x3f,0x93,0x4a,0x30,0xf5,0x97,0x18,0xb3,0xa7, +0xf9,0x19,0xa7,0x93,0x33,0x1d,0x01,0xc8,0xdb,0x22,0x52,0x5c,0xd7,0x25,0xc9, +0x46,0xf9,0xa2,0xfb,0x87,0x59,0x43,0xbe,0x9b,0x62,0xb1,0x8d,0x2d,0x86,0x44, +0x1a,0x46,0xac,0x78,0x61,0x7e,0x30,0x09,0xfa,0xae,0x89,0xc4,0x41,0x2a,0x22, +0x66,0x03,0x91,0x39,0x45,0x9c,0xc7,0x8b,0x0c,0xa8,0xca,0x0d,0x2f,0xfb,0x52, +0xea,0x0c,0xf7,0x63,0x33,0x23,0x9d,0xfe,0xb0,0x1f,0xad,0x67,0xd6,0xa7,0x50, +0x03,0xc6,0x04,0x70,0x63,0xb5,0x2c,0xb1,0x86,0x5a,0x43,0xb7,0xfb,0xae,0xf9, +0x6e,0x29,0x6e,0x21,0x21,0x41,0x26,0x06,0x8c,0xc9,0xc3,0xee,0xb0,0xc2,0x85, +0x93,0xa1,0xb9,0x85,0xd9,0xe6,0x32,0x6c,0x4b,0x4c,0x3f,0xd6,0x5d,0xa3,0xe5, +0xb5,0x9d,0x77,0xc3,0x9c,0xc0,0x55,0xb7,0x74,0x00,0xe3,0xb8,0x38,0xab,0x83, +0x97,0x50,0xe1,0x9a,0x42,0x24,0x1d,0xc6,0xc0,0xa3,0x30,0xd1,0x1a,0x5a,0xc8, +0x52,0x34,0xf7,0x73,0xf1,0xc7,0x18,0x1f,0x33,0xad,0x7a,0xec,0xcb,0x41,0x60, +0xf3,0x23,0x94,0x20,0xc2,0x48,0x45,0xac,0x5c,0x51,0xc6,0x2e,0x80,0xc2,0xe2, +0x77,0x15,0xbd,0x85,0x87,0xed,0x36,0x9d,0x96,0x91,0xee,0x00,0xb5,0xa3,0x70, +0xec,0x9f,0xe3,0x8d,0x80,0x68,0x83,0x76,0xba,0xaf,0x5d,0x70,0x52,0x22,0x16, +0xe2,0x66,0xfb,0xba,0xb3,0xc5,0xc2,0xf7,0x3e,0x2f,0x77,0xa6,0xca,0xde,0xc1, +0xa6,0xc6,0x48,0x4c,0xc3,0x37,0x51,0x23,0xd3,0x27,0xd7,0xb8,0x4e,0x70,0x96, +0xf0,0xa1,0x44,0x76,0xaf,0x78,0xcf,0x9a,0xe1,0x66,0x13,0x02,0x03,0x01,0x00, +0x01 }; +/* from Microsoft Root Certificate Authority 2011 */ +static BYTE msPubKey5[] = { +0x30,0x82,0x02,0x0a,0x02,0x82,0x02,0x01,0x00,0xb2,0x80,0x41,0xaa,0x35,0x38, +0x4d,0x13,0x72,0x32,0x68,0x22,0x4d,0xb8,0xb2,0xf1,0xff,0xd5,0x52,0xbc,0x6c, +0xc7,0xf5,0xd2,0x4a,0x8c,0x36,0xee,0xd1,0xc2,0x5c,0x7e,0x8c,0x8a,0xae,0xaf, +0x13,0x28,0x6f,0xc0,0x73,0xe3,0x3a,0xce,0xd0,0x25,0xa8,0x5a,0x3a,0x6d,0xef, +0xa8,0xb8,0x59,0xab,0x13,0x23,0x68,0xcd,0x0c,0x29,0x87,0xd1,0x6f,0x80,0x5c, +0x8f,0x44,0x7f,0x5d,0x90,0x01,0x52,0x58,0xac,0x51,0xc5,0x5f,0x2a,0x87,0xdc, +0xdc,0xd8,0x0a,0x1d,0xc1,0x03,0xb9,0x7b,0xb0,0x56,0xe8,0xa3,0xde,0x64,0x61, +0xc2,0x9e,0xf8,0xf3,0x7c,0xb9,0xec,0x0d,0xb5,0x54,0xfe,0x4c,0xb6,0x65,0x4f, +0x88,0xf0,0x9c,0x48,0x99,0x0c,0x42,0x0b,0x09,0x7c,0x31,0x59,0x17,0x79,0x06, +0x78,0x28,0x8d,0x89,0x3a,0x4c,0x03,0x25,0xbe,0x71,0x6a,0x5c,0x0b,0xe7,0x84, +0x60,0xa4,0x99,0x22,0xe3,0xd2,0xaf,0x84,0xa4,0xa7,0xfb,0xd1,0x98,0xed,0x0c, +0xa9,0xde,0x94,0x89,0xe1,0x0e,0xa0,0xdc,0xc0,0xce,0x99,0x3d,0xea,0x08,0x52, +0xbb,0x56,0x79,0xe4,0x1f,0x84,0xba,0x1e,0xb8,0xb4,0xc4,0x49,0x5c,0x4f,0x31, +0x4b,0x87,0xdd,0xdd,0x05,0x67,0x26,0x99,0x80,0xe0,0x71,0x11,0xa3,0xb8,0xa5, +0x41,0xe2,0xa4,0x53,0xb9,0xf7,0x32,0x29,0x83,0x0c,0x13,0xbf,0x36,0x5e,0x04, +0xb3,0x4b,0x43,0x47,0x2f,0x6b,0xe2,0x91,0x1e,0xd3,0x98,0x4f,0xdd,0x42,0x07, +0xc8,0xe8,0x1d,0x12,0xfc,0x99,0xa9,0x6b,0x3e,0x92,0x7e,0xc8,0xd6,0x69,0x3a, +0xfc,0x64,0xbd,0xb6,0x09,0x9d,0xca,0xfd,0x0c,0x0b,0xa2,0x9b,0x77,0x60,0x4b, +0x03,0x94,0xa4,0x30,0x69,0x12,0xd6,0x42,0x2d,0xc1,0x41,0x4c,0xca,0xdc,0xaa, +0xfd,0x8f,0x5b,0x83,0x46,0x9a,0xd9,0xfc,0xb1,0xd1,0xe3,0xb3,0xc9,0x7f,0x48, +0x7a,0xcd,0x24,0xf0,0x41,0x8f,0x5c,0x74,0xd0,0xac,0xb0,0x10,0x20,0x06,0x49, +0xb7,0xc7,0x2d,0x21,0xc8,0x57,0xe3,0xd0,0x86,0xf3,0x03,0x68,0xfb,0xd0,0xce, +0x71,0xc1,0x89,0x99,0x4a,0x64,0x01,0x6c,0xfd,0xec,0x30,0x91,0xcf,0x41,0x3c, +0x92,0xc7,0xe5,0xba,0x86,0x1d,0x61,0x84,0xc7,0x5f,0x83,0x39,0x62,0xae,0xb4, +0x92,0x2f,0x47,0xf3,0x0b,0xf8,0x55,0xeb,0xa0,0x1f,0x59,0xd0,0xbb,0x74,0x9b, +0x1e,0xd0,0x76,0xe6,0xf2,0xe9,0x06,0xd7,0x10,0xe8,0xfa,0x64,0xde,0x69,0xc6, +0x35,0x96,0x88,0x02,0xf0,0x46,0xb8,0x3f,0x27,0x99,0x6f,0xcb,0x71,0x89,0x29, +0x35,0xf7,0x48,0x16,0x02,0x35,0x8f,0xd5,0x79,0x7c,0x4d,0x02,0xcf,0x5f,0xeb, +0x8a,0x83,0x4f,0x45,0x71,0x88,0xf9,0xa9,0x0d,0x4e,0x72,0xe9,0xc2,0x9c,0x07, +0xcf,0x49,0x1b,0x4e,0x04,0x0e,0x63,0x51,0x8c,0x5e,0xd8,0x00,0xc1,0x55,0x2c, +0xb6,0xc6,0xe0,0xc2,0x65,0x4e,0xc9,0x34,0x39,0xf5,0x9c,0xb3,0xc4,0x7e,0xe8, +0x61,0x6e,0x13,0x5f,0x15,0xc4,0x5f,0xd9,0x7e,0xed,0x1d,0xce,0xee,0x44,0xec, +0xcb,0x2e,0x86,0xb1,0xec,0x38,0xf6,0x70,0xed,0xab,0x5c,0x13,0xc1,0xd9,0x0f, +0x0d,0xc7,0x80,0xb2,0x55,0xed,0x34,0xf7,0xac,0x9b,0xe4,0xc3,0xda,0xe7,0x47, +0x3c,0xa6,0xb5,0x8f,0x31,0xdf,0xc5,0x4b,0xaf,0xeb,0xf1,0x02,0x03,0x01,0x00, +0x01 }; static BOOL WINAPI verify_ms_root_policy(LPCSTR szPolicyOID, PCCERT_CHAIN_CONTEXT pChainContext, PCERT_CHAIN_POLICY_PARA pPolicyPara, PCERT_CHAIN_POLICY_STATUS pPolicyStatus) { - BOOL ret = verify_base_policy(szPolicyOID, pChainContext, pPolicyPara, - pPolicyStatus); + BOOL isMSRoot = FALSE; - if (ret && !pPolicyStatus->dwError) + CERT_PUBLIC_KEY_INFO msPubKey = { { 0 } }; + DWORD i; + static const CRYPT_DATA_BLOB keyBlobs[] = { + { sizeof(msPubKey1), msPubKey1 }, + { sizeof(msPubKey2), msPubKey2 }, + { sizeof(msPubKey3), msPubKey3 }, + { sizeof(msPubKey4), msPubKey4 }, + }; + static const CRYPT_DATA_BLOB keyBlobs_approot[] = { + { sizeof(msPubKey5), msPubKey5 }, + }; + PCERT_SIMPLE_CHAIN rootChain = + pChainContext->rgpChain[pChainContext->cChain - 1]; + PCCERT_CONTEXT root = + rootChain->rgpElement[rootChain->cElement - 1]->pCertContext; + + const CRYPT_DATA_BLOB *keys; + unsigned int key_count; + + if (pPolicyPara && pPolicyPara->dwFlags & MICROSOFT_ROOT_CERT_CHAIN_POLICY_CHECK_APPLICATION_ROOT_FLAG) { - CERT_PUBLIC_KEY_INFO msPubKey = { { 0 } }; - BOOL isMSRoot = FALSE; - DWORD i; - CRYPT_DATA_BLOB keyBlobs[] = { - { sizeof(msPubKey1), msPubKey1 }, - { sizeof(msPubKey2), msPubKey2 }, - { sizeof(msPubKey3), msPubKey3 }, - }; - PCERT_SIMPLE_CHAIN rootChain = - pChainContext->rgpChain[pChainContext->cChain -1 ]; - PCCERT_CONTEXT root = - rootChain->rgpElement[rootChain->cElement - 1]->pCertContext; - - for (i = 0; !isMSRoot && i < ARRAY_SIZE(keyBlobs); i++) - { - msPubKey.PublicKey.cbData = keyBlobs[i].cbData; - msPubKey.PublicKey.pbData = keyBlobs[i].pbData; - if (CertComparePublicKeyInfo( - X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, - &root->pCertInfo->SubjectPublicKeyInfo, &msPubKey)) - isMSRoot = TRUE; - } - if (isMSRoot) - pPolicyStatus->lChainIndex = pPolicyStatus->lElementIndex = 0; + keys = keyBlobs_approot; + key_count = ARRAY_SIZE(keyBlobs_approot); } - return ret; + else + { + keys = keyBlobs; + key_count = ARRAY_SIZE(keyBlobs); + } + + for (i = 0; !isMSRoot && i < key_count; i++) + { + msPubKey.PublicKey.cbData = keys[i].cbData; + msPubKey.PublicKey.pbData = keys[i].pbData; + if (CertComparePublicKeyInfo(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, + &root->pCertInfo->SubjectPublicKeyInfo, &msPubKey)) isMSRoot = TRUE; + } + + pPolicyStatus->lChainIndex = pPolicyStatus->lElementIndex = 0; + + if (isMSRoot) + pPolicyStatus->dwError = 0; + else + pPolicyStatus->dwError = CERT_E_UNTRUSTEDROOT; + + return TRUE; } typedef BOOL (WINAPI *CertVerifyCertificateChainPolicyFunc)(LPCSTR szPolicyOID, @@ -3707,8 +3797,8 @@ static void dump_policy_para(PCERT_CHAIN_POLICY_PARA para) { if (para) { - TRACE_(chain)("cbSize = %d\n", para->cbSize); - TRACE_(chain)("dwFlags = %08x\n", para->dwFlags); + TRACE_(chain)("cbSize = %ld\n", para->cbSize); + TRACE_(chain)("dwFlags = %08lx\n", para->dwFlags); TRACE_(chain)("pvExtraPolicyPara = %p\n", para->pvExtraPolicyPara); } } @@ -3763,6 +3853,6 @@ BOOL WINAPI CertVerifyCertificateChainPolicy(LPCSTR szPolicyOID, pPolicyStatus); if (hFunc) CryptFreeOIDFunctionAddress(hFunc, 0); - TRACE("returning %d (%08x)\n", ret, pPolicyStatus->dwError); + TRACE("returning %d (%08lx)\n", ret, pPolicyStatus->dwError); return ret; } diff --git a/dll/win32/crypt32/collectionstore.c b/dll/win32/crypt32/collectionstore.c index 2c2398d7455..0193be86222 100644 --- a/dll/win32/crypt32/collectionstore.c +++ b/dll/win32/crypt32/collectionstore.c @@ -42,7 +42,7 @@ typedef struct _WINE_COLLECTIONSTORE static void Collection_addref(WINECRYPT_CERTSTORE *store) { LONG ref = InterlockedIncrement(&store->ref); - TRACE("ref = %d\n", ref); + TRACE("ref = %ld\n", ref); } static DWORD Collection_release(WINECRYPT_CERTSTORE *store, DWORD flags) @@ -52,10 +52,10 @@ static DWORD Collection_release(WINECRYPT_CERTSTORE *store, DWORD flags) LONG ref; if(flags) - FIXME("Unimplemented flags %x\n", flags); + FIXME("Unimplemented flags %lx\n", flags); ref = InterlockedDecrement(&cs->hdr.ref); - TRACE("(%p) ref=%d\n", store, ref); + TRACE("(%p) ref=%ld\n", store, ref); if(ref) return ERROR_SUCCESS; @@ -411,7 +411,7 @@ static BOOL Collection_control(WINECRYPT_CERTSTORE *cert_store, DWORD dwFlags, WINE_COLLECTIONSTORE *store = (WINE_COLLECTIONSTORE*)cert_store; WINE_STORE_LIST_ENTRY *entry; - TRACE("(%p, %08x, %d, %p)\n", cert_store, dwFlags, dwCtrlType, pvCtrlPara); + TRACE("(%p, %08lx, %ld, %p)\n", cert_store, dwFlags, dwCtrlType, pvCtrlPara); if (!store) return TRUE; @@ -478,7 +478,7 @@ WINECRYPT_CERTSTORE *CRYPT_CollectionOpenStore(HCRYPTPROV hCryptProv, { memset(store, 0, sizeof(WINE_COLLECTIONSTORE)); CRYPT_InitStore(&store->hdr, dwFlags, StoreTypeCollection, &CollectionStoreVtbl); - InitializeCriticalSection(&store->cs); + InitializeCriticalSectionEx(&store->cs, 0, RTL_CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO); store->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": PWINE_COLLECTIONSTORE->cs"); list_init(&store->stores); } @@ -494,7 +494,7 @@ BOOL WINAPI CertAddStoreToCollection(HCERTSTORE hCollectionStore, WINE_STORE_LIST_ENTRY *entry; BOOL ret; - TRACE("(%p, %p, %08x, %d)\n", hCollectionStore, hSiblingStore, + TRACE("(%p, %p, %08lx, %ld)\n", hCollectionStore, hSiblingStore, dwUpdateFlags, dwPriority); if (!collection || !sibling) @@ -519,11 +519,11 @@ BOOL WINAPI CertAddStoreToCollection(HCERTSTORE hCollectionStore, if (entry) { InterlockedIncrement(&sibling->ref); - TRACE("sibling %p's ref count is %d\n", sibling, sibling->ref); + TRACE("sibling %p's ref count is %ld\n", sibling, sibling->ref); entry->store = sibling; entry->dwUpdateFlags = dwUpdateFlags; entry->dwPriority = dwPriority; - TRACE("%p: adding %p, priority %d\n", collection, entry, dwPriority); + TRACE("%p: adding %p, priority %ld\n", collection, entry, dwPriority); EnterCriticalSection(&collection->cs); if (dwPriority) { diff --git a/dll/win32/crypt32/context.c b/dll/win32/crypt32/context.c index 90d1afd2021..4a16d42296b 100644 --- a/dll/win32/crypt32/context.c +++ b/dll/win32/crypt32/context.c @@ -79,7 +79,7 @@ void Context_AddRef(context_t *context) { LONG ref = InterlockedIncrement(&context->ref); - TRACE("(%p) ref=%d\n", context, context->ref); + TRACE("(%p) ref=%ld\n", context, context->ref); if(ref == 1) { /* This is the first external (non-store) reference. Increase store ref cnt. */ @@ -107,7 +107,7 @@ void Context_Release(context_t *context) { LONG ref = InterlockedDecrement(&context->ref); - TRACE("(%p) ref=%d\n", context, ref); + TRACE("(%p) ref=%ld\n", context, ref); assert(ref >= 0); if (!ref) { diff --git a/dll/win32/crypt32/crl.c b/dll/win32/crypt32/crl.c index db8065192f0..f6ec8195bd1 100644 --- a/dll/win32/crypt32/crl.c +++ b/dll/win32/crypt32/crl.c @@ -19,12 +19,11 @@ #include #include -#define NONAMELESSUNION + #include "windef.h" #include "winbase.h" #include "wincrypt.h" #include "wine/debug.h" -#include "wine/unicode.h" #include "crypt32_private.h" WINE_DEFAULT_DEBUG_CHANNEL(crypt); @@ -39,42 +38,137 @@ static void CRL_free(context_t *context) static const context_vtbl_t crl_vtbl; +static char *copy_string(char *p, char **dst, const char *src) +{ + size_t size = strlen(src) + 1; + + *dst = memcpy(p, src, size); + return p + size; +} + +static char *copy_blob(char *p, DATA_BLOB *dst, const DATA_BLOB *src) +{ + size_t size = src->cbData; + + dst->cbData = size; + dst->pbData = memcpy(p, src->pbData, size); + return p + size; +} + +static char *copy_extension(char *p, CERT_EXTENSION *dst, const CERT_EXTENSION *src) +{ + p = copy_string(p, &dst->pszObjId, src->pszObjId); + dst->fCritical = src->fCritical; + return copy_blob(p, &dst->Value, &src->Value); +} + +static CRL_INFO *clone_crl_info(const CRL_INFO *src) +{ + size_t size = sizeof(CRL_INFO); + CRL_INFO *dst; + DWORD i, j; + char *p; + + if (src->SignatureAlgorithm.pszObjId) + size += strlen(src->SignatureAlgorithm.pszObjId) + 1; + size += src->SignatureAlgorithm.Parameters.cbData; + size += src->Issuer.cbData; + for (i = 0; i < src->cCRLEntry; ++i) + { + const CRL_ENTRY *entry = &src->rgCRLEntry[i]; + + size += sizeof(CRL_ENTRY); + size += entry->SerialNumber.cbData; + for (j = 0; j < entry->cExtension; ++j) + { + const CERT_EXTENSION *ext = &entry->rgExtension[j]; + + size += sizeof(CERT_EXTENSION); + size += strlen(ext->pszObjId) + 1; + size += ext->Value.cbData; + } + } + + for (j = 0; j < src->cExtension; ++j) + { + const CERT_EXTENSION *ext = &src->rgExtension[j]; + + size += sizeof(CERT_EXTENSION); + size += strlen(ext->pszObjId) + 1; + size += ext->Value.cbData; + } + + if (!(dst = LocalAlloc(LPTR, size))) + return NULL; + p = (char *)(dst + 1); + + dst->dwVersion = src->dwVersion; + if (src->SignatureAlgorithm.pszObjId) + p = copy_string(p, &dst->SignatureAlgorithm.pszObjId, src->SignatureAlgorithm.pszObjId); + p = copy_blob(p, &dst->SignatureAlgorithm.Parameters, &src->SignatureAlgorithm.Parameters); + p = copy_blob(p, &dst->Issuer, &src->Issuer); + dst->ThisUpdate = src->ThisUpdate; + dst->NextUpdate = src->NextUpdate; + + dst->cCRLEntry = src->cCRLEntry; + dst->rgCRLEntry = (CRL_ENTRY *)p; + p += src->cCRLEntry * sizeof(CRL_ENTRY); + + dst->cExtension = src->cExtension; + dst->rgExtension = (CERT_EXTENSION *)p; + p += src->cExtension * sizeof(CERT_EXTENSION); + + for (i = 0; i < src->cCRLEntry; ++i) + { + const CRL_ENTRY *src_entry = &src->rgCRLEntry[i]; + CRL_ENTRY *dst_entry = &dst->rgCRLEntry[i]; + + p = copy_blob(p, &dst_entry->SerialNumber, &src_entry->SerialNumber); + dst_entry->RevocationDate = src_entry->RevocationDate; + dst_entry->cExtension = src_entry->cExtension; + dst_entry->rgExtension = (CERT_EXTENSION *)p; + p += src_entry->cExtension * sizeof(CERT_EXTENSION); + + for (j = 0; j < src_entry->cExtension; ++j) + p = copy_extension(p, &dst_entry->rgExtension[j], &src_entry->rgExtension[j]); + } + + for (j = 0; j < src->cExtension; ++j) + p = copy_extension(p, &dst->rgExtension[j], &src->rgExtension[j]); + + assert(p - (char *)dst == size); + return dst; +} + static context_t *CRL_clone(context_t *context, WINECRYPT_CERTSTORE *store, BOOL use_link) { - crl_t *crl; + crl_t *dst; if(use_link) { - crl = (crl_t*)Context_CreateLinkContext(sizeof(CRL_CONTEXT), context, store); - if(!crl) + if (!(dst = (crl_t *)Context_CreateLinkContext(sizeof(CRL_CONTEXT), context, store))) return NULL; }else { - const crl_t *cloned = (const crl_t*)context; - DWORD size = 0; - BOOL res; + const crl_t *src = (const crl_t*)context; - crl = (crl_t*)Context_CreateDataContext(sizeof(CRL_CONTEXT), &crl_vtbl, store); - if(!crl) + if (!(dst = (crl_t *)Context_CreateDataContext(sizeof(CRL_CONTEXT), &crl_vtbl, store))) return NULL; - Context_CopyProperties(&crl->ctx, &cloned->ctx); + Context_CopyProperties(&dst->ctx, &src->ctx); - crl->ctx.dwCertEncodingType = cloned->ctx.dwCertEncodingType; - crl->ctx.pbCrlEncoded = CryptMemAlloc(cloned->ctx.cbCrlEncoded); - memcpy(crl->ctx.pbCrlEncoded, cloned->ctx.pbCrlEncoded, cloned->ctx.cbCrlEncoded); - crl->ctx.cbCrlEncoded = cloned->ctx.cbCrlEncoded; + dst->ctx.dwCertEncodingType = src->ctx.dwCertEncodingType; + dst->ctx.pbCrlEncoded = CryptMemAlloc(src->ctx.cbCrlEncoded); + memcpy(dst->ctx.pbCrlEncoded, src->ctx.pbCrlEncoded, src->ctx.cbCrlEncoded); + dst->ctx.cbCrlEncoded = src->ctx.cbCrlEncoded; - /* FIXME: We don't need to decode the object here, we could just clone crl info. */ - res = CryptDecodeObjectEx(crl->ctx.dwCertEncodingType, X509_CERT_CRL_TO_BE_SIGNED, - crl->ctx.pbCrlEncoded, crl->ctx.cbCrlEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL, - &crl->ctx.pCrlInfo, &size); - if(!res) { - CertFreeCRLContext(&crl->ctx); + if (!(dst->ctx.pCrlInfo = clone_crl_info(src->ctx.pCrlInfo))) + { + CertFreeCRLContext(&dst->ctx); return NULL; } } - crl->ctx.hCertStore = store; - return &crl->base; + dst->ctx.hCertStore = store; + return &dst->base; } static const context_vtbl_t crl_vtbl = { @@ -91,7 +185,7 @@ PCCRL_CONTEXT WINAPI CertCreateCRLContext(DWORD dwCertEncodingType, BYTE *data = NULL; DWORD size = 0; - TRACE("(%08x, %p, %d)\n", dwCertEncodingType, pbCrlEncoded, + TRACE("(%08lx, %p, %ld)\n", dwCertEncodingType, pbCrlEncoded, cbCrlEncoded); if ((dwCertEncodingType & CERT_ENCODING_TYPE_MASK) != X509_ASN_ENCODING) @@ -134,7 +228,7 @@ BOOL WINAPI CertAddEncodedCRLToStore(HCERTSTORE hCertStore, pbCrlEncoded, cbCrlEncoded); BOOL ret; - TRACE("(%p, %08x, %p, %d, %08x, %p)\n", hCertStore, dwCertEncodingType, + TRACE("(%p, %08lx, %p, %ld, %08lx, %p)\n", hCertStore, dwCertEncodingType, pbCrlEncoded, cbCrlEncoded, dwAddDisposition, ppCrlContext); if (crl) @@ -205,7 +299,7 @@ static BOOL compare_crl_issued_by(PCCRL_CONTEXT pCrlContext, DWORD dwType, ret = CertCompareCertificateName( issuer->dwCertEncodingType, &issuer->pCertInfo->Subject, - &directoryName->u.DirectoryName); + &directoryName->DirectoryName); if (ret) ret = CertCompareIntegerBlob( &issuer->pCertInfo->SerialNumber, @@ -291,7 +385,7 @@ PCCRL_CONTEXT WINAPI CertFindCRLInStore(HCERTSTORE hCertStore, PCCRL_CONTEXT ret; CrlCompareFunc compare; - TRACE("(%p, %d, %d, %d, %p, %p)\n", hCertStore, dwCertEncodingType, + TRACE("(%p, %ld, %ld, %ld, %p, %p)\n", hCertStore, dwCertEncodingType, dwFindFlags, dwFindType, pvFindPara, pPrevCrlContext); switch (dwFindType) @@ -309,7 +403,7 @@ PCCRL_CONTEXT WINAPI CertFindCRLInStore(HCERTSTORE hCertStore, compare = compare_crl_issued_for; break; default: - FIXME("find type %08x unimplemented\n", dwFindType); + FIXME("find type %08lx unimplemented\n", dwFindType); compare = NULL; } @@ -342,7 +436,7 @@ PCCRL_CONTEXT WINAPI CertGetCRLFromStore(HCERTSTORE hCertStore, CERT_STORE_DELTA_CRL_FLAG; PCCRL_CONTEXT ret; - TRACE("(%p, %p, %p, %08x)\n", hCertStore, pIssuerContext, pPrevCrlContext, + TRACE("(%p, %p, %p, %08lx)\n", hCertStore, pIssuerContext, pPrevCrlContext, *pdwFlags); if (*pdwFlags & ~supportedFlags) @@ -395,7 +489,7 @@ BOOL WINAPI CertFreeCRLContext(PCCRL_CONTEXT pCrlContext) DWORD WINAPI CertEnumCRLContextProperties(PCCRL_CONTEXT pCRLContext, DWORD dwPropId) { - TRACE("(%p, %d)\n", pCRLContext, dwPropId); + TRACE("(%p, %ld)\n", pCRLContext, dwPropId); return ContextPropertyList_EnumPropIDs(crl_from_ptr(pCRLContext)->base.properties, dwPropId); } @@ -424,7 +518,7 @@ static BOOL CRLContext_GetProperty(crl_t *crl, DWORD dwPropId, BOOL ret; CRYPT_DATA_BLOB blob; - TRACE("(%p, %d, %p, %p)\n", crl, dwPropId, pvData, pcbData); + TRACE("(%p, %ld, %p, %p)\n", crl, dwPropId, pvData, pcbData); if (crl->base.properties) ret = ContextPropertyList_FindProperty(crl->base.properties, dwPropId, &blob); @@ -474,7 +568,7 @@ BOOL WINAPI CertGetCRLContextProperty(PCCRL_CONTEXT pCRLContext, { BOOL ret; - TRACE("(%p, %d, %p, %p)\n", pCRLContext, dwPropId, pvData, pcbData); + TRACE("(%p, %ld, %p, %p)\n", pCRLContext, dwPropId, pvData, pcbData); switch (dwPropId) { @@ -513,7 +607,7 @@ static BOOL CRLContext_SetProperty(crl_t *crl, DWORD dwPropId, { BOOL ret; - TRACE("(%p, %d, %08x, %p)\n", crl, dwPropId, dwFlags, pvData); + TRACE("(%p, %ld, %08lx, %p)\n", crl, dwPropId, dwFlags, pvData); if (!crl->base.properties) ret = FALSE; @@ -555,7 +649,7 @@ static BOOL CRLContext_SetProperty(crl_t *crl, DWORD dwPropId, pvData, sizeof(FILETIME)); break; default: - FIXME("%d: stub\n", dwPropId); + FIXME("%ld: stub\n", dwPropId); ret = FALSE; } } @@ -568,7 +662,7 @@ BOOL WINAPI CertSetCRLContextProperty(PCCRL_CONTEXT pCRLContext, { BOOL ret; - TRACE("(%p, %d, %08x, %p)\n", pCRLContext, dwPropId, dwFlags, pvData); + TRACE("(%p, %ld, %08lx, %p)\n", pCRLContext, dwPropId, dwFlags, pvData); /* Handle special cases for "read-only"/invalid prop IDs. Windows just * crashes on most of these, I'll be safer. @@ -598,34 +692,34 @@ static BOOL compare_dist_point_name(const CRL_DIST_POINT_NAME *name1, match = TRUE; if (name1->dwDistPointNameChoice == CRL_DIST_POINT_FULL_NAME) { - if (name1->u.FullName.cAltEntry == name2->u.FullName.cAltEntry) + if (name1->FullName.cAltEntry == name2->FullName.cAltEntry) { DWORD i; - for (i = 0; match && i < name1->u.FullName.cAltEntry; i++) + for (i = 0; match && i < name1->FullName.cAltEntry; i++) { const CERT_ALT_NAME_ENTRY *entry1 = - &name1->u.FullName.rgAltEntry[i]; + &name1->FullName.rgAltEntry[i]; const CERT_ALT_NAME_ENTRY *entry2 = - &name2->u.FullName.rgAltEntry[i]; + &name2->FullName.rgAltEntry[i]; if (entry1->dwAltNameChoice == entry2->dwAltNameChoice) { switch (entry1->dwAltNameChoice) { case CERT_ALT_NAME_URL: - match = !strcmpiW(entry1->u.pwszURL, - entry2->u.pwszURL); + match = !wcsicmp(entry1->pwszURL, + entry2->pwszURL); break; case CERT_ALT_NAME_DIRECTORY_NAME: - match = (entry1->u.DirectoryName.cbData == - entry2->u.DirectoryName.cbData) && - !memcmp(entry1->u.DirectoryName.pbData, - entry2->u.DirectoryName.pbData, - entry1->u.DirectoryName.cbData); + match = (entry1->DirectoryName.cbData == + entry2->DirectoryName.cbData) && + !memcmp(entry1->DirectoryName.pbData, + entry2->DirectoryName.pbData, + entry1->DirectoryName.cbData); break; default: - FIXME("unimplemented for type %d\n", + FIXME("unimplemented for type %ld\n", entry1->dwAltNameChoice); match = FALSE; } @@ -684,7 +778,7 @@ BOOL WINAPI CertIsValidCRLForCertificate(PCCERT_CONTEXT pCert, PCERT_EXTENSION ext; BOOL ret; - TRACE("(%p, %p, %08x, %p)\n", pCert, pCrl, dwFlags, pvReserved); + TRACE("(%p, %p, %08lx, %p)\n", pCert, pCrl, dwFlags, pvReserved); if (!pCert) return TRUE; @@ -751,7 +845,7 @@ BOOL WINAPI CertFindCertificateInCRL(PCCERT_CONTEXT pCert, PCCRL_CONTEXT pCrlContext, DWORD dwFlags, void *pvReserved, PCRL_ENTRY *ppCrlEntry) { - TRACE("(%p, %p, %08x, %p, %p)\n", pCert, pCrlContext, dwFlags, pvReserved, + TRACE("(%p, %p, %08lx, %p, %p)\n", pCert, pCrlContext, dwFlags, pvReserved, ppCrlEntry); *ppCrlEntry = CRYPT_FindCertificateInCRL(pCert->pCertInfo, @@ -765,7 +859,7 @@ BOOL WINAPI CertVerifyCRLRevocation(DWORD dwCertEncodingType, DWORD i; PCRL_ENTRY entry = NULL; - TRACE("(%08x, %p, %d, %p)\n", dwCertEncodingType, pCertId, cCrlInfo, + TRACE("(%08lx, %p, %ld, %p)\n", dwCertEncodingType, pCertId, cCrlInfo, rgpCrlInfo); for (i = 0; !entry && i < cCrlInfo; i++) diff --git a/dll/win32/crypt32/crypt32.spec b/dll/win32/crypt32/crypt32.spec index 9754b0296cd..046be01d669 100644 --- a/dll/win32/crypt32/crypt32.spec +++ b/dll/win32/crypt32/crypt32.spec @@ -137,12 +137,14 @@ @ stdcall CryptGetOIDFunctionAddress(long long str long ptr ptr) @ stdcall CryptGetOIDFunctionValue(long str str wstr ptr ptr ptr) @ stdcall CryptHashCertificate(long long long ptr long ptr ptr) +@ stdcall -version=0x600+ CryptHashCertificate2(wstr long ptr ptr long ptr ptr) @ stdcall CryptHashMessage(ptr long long ptr ptr ptr ptr ptr ptr) @ stdcall CryptHashPublicKeyInfo(long long long long ptr ptr ptr) @ stdcall CryptHashToBeSigned(ptr long ptr long ptr ptr) @ stub CryptImportPKCS8 @ stdcall CryptImportPublicKeyInfo(long long ptr ptr) @ stdcall CryptImportPublicKeyInfoEx(long long ptr long long ptr ptr) +@ stdcall -version=0x600+ CryptImportPublicKeyInfoEx2(long ptr long ptr ptr) @ stdcall CryptInitOIDFunctionSet(str long) @ stdcall CryptInstallOIDFunctionAddress(ptr long str long ptr long) @ stub CryptLoadSip diff --git a/dll/win32/crypt32/crypt32_private.h b/dll/win32/crypt32/crypt32_private.h index 838d76a91a9..827594d8489 100644 --- a/dll/win32/crypt32/crypt32_private.h +++ b/dll/win32/crypt32/crypt32_private.h @@ -20,6 +20,11 @@ #define __CRYPT32_PRIVATE_H__ #include "wine/list.h" +#include "wine/unixlib.h" + +BOOL CNG_ImportPubKey(CERT_PUBLIC_KEY_INFO *pubKeyInfo, BCRYPT_KEY_HANDLE *key); +BOOL cng_prepare_signature(const char *alg_oid, BYTE *encoded_sig, DWORD encoded_sig_len, + BYTE **sig_value, DWORD *sig_len); /* a few asn.1 tags we need */ #define ASN_BOOL (ASN_UNIVERSAL | ASN_PRIMITIVE | 0x01) @@ -40,7 +45,12 @@ #define ASN_UNIVERSALSTRING (ASN_UNIVERSAL | ASN_PRIMITIVE | 0x1c) #define ASN_BMPSTRING (ASN_UNIVERSAL | ASN_PRIMITIVE | 0x1e) -BOOL CRYPT_EncodeLen(DWORD len, BYTE *pbEncoded, DWORD *pcbEncoded) DECLSPEC_HIDDEN; +/* Copies `len` bytes from `src` to `dst`, + * reversing the order of the bytes + */ +void CRYPT_CopyReversed(BYTE *dst, const BYTE *src, size_t len); + +BOOL CRYPT_EncodeLen(DWORD len, BYTE *pbEncoded, DWORD *pcbEncoded); typedef BOOL (WINAPI *CryptEncodeObjectExFunc)(DWORD, LPCSTR, const void *, DWORD, PCRYPT_ENCODE_PARA, BYTE *, DWORD *); @@ -54,7 +64,7 @@ struct AsnEncodeSequenceItem BOOL WINAPI CRYPT_AsnEncodeSequence(DWORD dwCertEncodingType, struct AsnEncodeSequenceItem items[], DWORD cItem, DWORD dwFlags, - PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded) DECLSPEC_HIDDEN; + PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded); struct AsnConstructedItem { @@ -65,13 +75,13 @@ struct AsnConstructedItem BOOL WINAPI CRYPT_AsnEncodeConstructed(DWORD dwCertEncodingType, LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags, - PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded) DECLSPEC_HIDDEN; + PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded); BOOL WINAPI CRYPT_AsnEncodeOid(DWORD dwCertEncodingType, LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags, - PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded) DECLSPEC_HIDDEN; + PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded); BOOL WINAPI CRYPT_AsnEncodeOctets(DWORD dwCertEncodingType, LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags, - PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded) DECLSPEC_HIDDEN; + PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded); typedef struct _CRYPT_DIGESTED_DATA { @@ -82,7 +92,7 @@ typedef struct _CRYPT_DIGESTED_DATA } CRYPT_DIGESTED_DATA; BOOL CRYPT_AsnEncodePKCSDigestedData(const CRYPT_DIGESTED_DATA *digestedData, - void *pvData, DWORD *pcbData) DECLSPEC_HIDDEN; + void *pvData, DWORD *pcbData); typedef struct _CRYPT_ENCRYPTED_CONTENT_INFO { @@ -100,11 +110,11 @@ typedef struct _CRYPT_ENVELOPED_DATA } CRYPT_ENVELOPED_DATA; BOOL CRYPT_AsnEncodePKCSEnvelopedData(const CRYPT_ENVELOPED_DATA *envelopedData, - void *pvData, DWORD *pcbData) DECLSPEC_HIDDEN; + void *pvData, DWORD *pcbData); BOOL CRYPT_AsnDecodePKCSEnvelopedData(const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, PCRYPT_DECODE_PARA pDecodePara, - CRYPT_ENVELOPED_DATA *envelopedData, DWORD *pcbEnvelopedData) DECLSPEC_HIDDEN; + CRYPT_ENVELOPED_DATA *envelopedData, DWORD *pcbEnvelopedData); typedef struct _CRYPT_SIGNED_INFO { @@ -120,11 +130,11 @@ typedef struct _CRYPT_SIGNED_INFO } CRYPT_SIGNED_INFO; BOOL CRYPT_AsnEncodeCMSSignedInfo(CRYPT_SIGNED_INFO *, void *pvData, - DWORD *pcbData) DECLSPEC_HIDDEN; + DWORD *pcbData); BOOL CRYPT_AsnDecodeCMSSignedInfo(const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, PCRYPT_DECODE_PARA pDecodePara, - CRYPT_SIGNED_INFO *signedInfo, DWORD *pcbSignedInfo) DECLSPEC_HIDDEN; + CRYPT_SIGNED_INFO *signedInfo, DWORD *pcbSignedInfo); /* Helper function to check *pcbEncoded, set it to the required size, and * optionally to allocate memory. Assumes pbEncoded is not NULL. @@ -132,15 +142,15 @@ BOOL CRYPT_AsnDecodeCMSSignedInfo(const BYTE *pbEncoded, DWORD cbEncoded, * pointer to the newly allocated memory. */ BOOL CRYPT_EncodeEnsureSpace(DWORD dwFlags, const CRYPT_ENCODE_PARA *pEncodePara, - BYTE *pbEncoded, DWORD *pcbEncoded, DWORD bytesNeeded) DECLSPEC_HIDDEN; + BYTE *pbEncoded, DWORD *pcbEncoded, DWORD bytesNeeded); BOOL CRYPT_AsnDecodePKCSDigestedData(const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, PCRYPT_DECODE_PARA pDecodePara, - CRYPT_DIGESTED_DATA *digestedData, DWORD *pcbDigestedData) DECLSPEC_HIDDEN; + CRYPT_DIGESTED_DATA *digestedData, DWORD *pcbDigestedData); BOOL WINAPI CRYPT_AsnEncodePubKeyInfoNoNull(DWORD dwCertEncodingType, LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags, - PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded) DECLSPEC_HIDDEN; + PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded); /* The following aren't defined in wincrypt.h, as they're "reserved" */ #define CERT_CERT_PROP_ID 32 @@ -152,13 +162,13 @@ BOOL WINAPI CRYPT_AsnEncodePubKeyInfoNoNull(DWORD dwCertEncodingType, */ HCRYPTPROV WINAPI I_CryptGetDefaultCryptProv(ALG_ID); -extern HINSTANCE hInstance DECLSPEC_HIDDEN; +extern HINSTANCE hInstance; -void crypt_oid_init(void) DECLSPEC_HIDDEN; -void crypt_oid_free(void) DECLSPEC_HIDDEN; -void crypt_sip_free(void) DECLSPEC_HIDDEN; -void root_store_free(void) DECLSPEC_HIDDEN; -void default_chain_engine_free(void) DECLSPEC_HIDDEN; +void crypt_oid_init(void); +void crypt_oid_free(void); +void crypt_sip_free(void); +void root_store_free(void); +void default_chain_engine_free(void); /* (Internal) certificate store types and functions */ struct WINE_CRYPTCERTSTORE; @@ -259,9 +269,9 @@ typedef struct _WINE_CONTEXT_INTERFACE DeleteContextFunc deleteFromStore; } WINE_CONTEXT_INTERFACE; -extern const WINE_CONTEXT_INTERFACE *pCertInterface DECLSPEC_HIDDEN; -extern const WINE_CONTEXT_INTERFACE *pCRLInterface DECLSPEC_HIDDEN; -extern const WINE_CONTEXT_INTERFACE *pCTLInterface DECLSPEC_HIDDEN; +extern const WINE_CONTEXT_INTERFACE *pCertInterface; +extern const WINE_CONTEXT_INTERFACE *pCRLInterface; +extern const WINE_CONTEXT_INTERFACE *pCTLInterface; typedef struct WINE_CRYPTCERTSTORE * (*StoreOpenFunc)(HCRYPTPROV hCryptProv, DWORD dwFlags, const void *pvPara); @@ -317,38 +327,40 @@ typedef struct WINE_CRYPTCERTSTORE } WINECRYPT_CERTSTORE; void CRYPT_InitStore(WINECRYPT_CERTSTORE *store, DWORD dwFlags, - CertStoreType type, const store_vtbl_t*) DECLSPEC_HIDDEN; -void CRYPT_FreeStore(WINECRYPT_CERTSTORE *store) DECLSPEC_HIDDEN; + CertStoreType type, const store_vtbl_t*); +void CRYPT_FreeStore(WINECRYPT_CERTSTORE *store); BOOL WINAPI I_CertUpdateStore(HCERTSTORE store1, HCERTSTORE store2, DWORD unk0, - DWORD unk1) DECLSPEC_HIDDEN; + DWORD unk1); WINECRYPT_CERTSTORE *CRYPT_CollectionOpenStore(HCRYPTPROV hCryptProv, - DWORD dwFlags, const void *pvPara) DECLSPEC_HIDDEN; + DWORD dwFlags, const void *pvPara); WINECRYPT_CERTSTORE *CRYPT_ProvCreateStore(DWORD dwFlags, - WINECRYPT_CERTSTORE *memStore, const CERT_STORE_PROV_INFO *pProvInfo) DECLSPEC_HIDDEN; + WINECRYPT_CERTSTORE *memStore, const CERT_STORE_PROV_INFO *pProvInfo); WINECRYPT_CERTSTORE *CRYPT_ProvOpenStore(LPCSTR lpszStoreProvider, DWORD dwEncodingType, HCRYPTPROV hCryptProv, DWORD dwFlags, - const void *pvPara) DECLSPEC_HIDDEN; + const void *pvPara); WINECRYPT_CERTSTORE *CRYPT_RegOpenStore(HCRYPTPROV hCryptProv, DWORD dwFlags, - const void *pvPara) DECLSPEC_HIDDEN; + const void *pvPara); WINECRYPT_CERTSTORE *CRYPT_FileOpenStore(HCRYPTPROV hCryptProv, DWORD dwFlags, - const void *pvPara) DECLSPEC_HIDDEN; + const void *pvPara); WINECRYPT_CERTSTORE *CRYPT_FileNameOpenStoreA(HCRYPTPROV hCryptProv, - DWORD dwFlags, const void *pvPara) DECLSPEC_HIDDEN; + DWORD dwFlags, const void *pvPara); WINECRYPT_CERTSTORE *CRYPT_FileNameOpenStoreW(HCRYPTPROV hCryptProv, - DWORD dwFlags, const void *pvPara) DECLSPEC_HIDDEN; + DWORD dwFlags, const void *pvPara); -void CRYPT_ImportSystemRootCertsToReg(void) DECLSPEC_HIDDEN; +void CRYPT_ImportSystemRootCertsToReg(void); BOOL CRYPT_SerializeContextsToReg(HKEY key, DWORD flags, const WINE_CONTEXT_INTERFACE *contextInterface, - HCERTSTORE memStore) DECLSPEC_HIDDEN; + HCERTSTORE memStore); +void CRYPT_RegReadSerializedFromReg(HKEY key, DWORD contextType, + HCERTSTORE store, DWORD disposition); -DWORD CRYPT_IsCertificateSelfSigned(const CERT_CONTEXT *cert) DECLSPEC_HIDDEN; +DWORD CRYPT_IsCertificateSelfSigned(const CERT_CONTEXT *cert); /* Allocates and initializes a certificate chain engine, but without creating * the root store. Instead, it uses root, and assumes the caller has done any * checking necessary. */ -HCERTCHAINENGINE CRYPT_CreateChainEngine(HCERTSTORE, DWORD, const CERT_CHAIN_ENGINE_CONFIG*) DECLSPEC_HIDDEN; +HCERTCHAINENGINE CRYPT_CreateChainEngine(HCERTSTORE, DWORD, const CERT_CHAIN_ENGINE_CONFIG*); /* Helper function for store reading functions and * CertAddSerializedElementToStore. Returns a context of the appropriate type @@ -357,33 +369,33 @@ HCERTCHAINENGINE CRYPT_CreateChainEngine(HCERTSTORE, DWORD, const CERT_CHAIN_ENG * *pdwContentType is set to the type of the returned context. */ const void *CRYPT_ReadSerializedElement(const BYTE *pbElement, - DWORD cbElement, DWORD dwContextTypeFlags, DWORD *pdwContentType) DECLSPEC_HIDDEN; + DWORD cbElement, DWORD dwContextTypeFlags, DWORD *pdwContentType); /* Reads contexts serialized in the file into the memory store. Returns FALSE * if the file is not of the expected format. */ -BOOL CRYPT_ReadSerializedStoreFromFile(HANDLE file, HCERTSTORE store) DECLSPEC_HIDDEN; +BOOL CRYPT_ReadSerializedStoreFromFile(HANDLE file, HCERTSTORE store); /* Reads contexts serialized in the blob into the memory store. Returns FALSE * if the file is not of the expected format. */ BOOL CRYPT_ReadSerializedStoreFromBlob(const CRYPT_DATA_BLOB *blob, - HCERTSTORE store) DECLSPEC_HIDDEN; + HCERTSTORE store); -/* Fixes up the pointers in info, where info is assumed to be a - * CRYPT_KEY_PROV_INFO, followed by its container name, provider name, and any - * provider parameters, in a contiguous buffer, but where info's pointers are - * assumed to be invalid. Upon return, info's pointers point to the - * appropriate memory locations. - */ -void CRYPT_FixKeyProvInfoPointers(PCRYPT_KEY_PROV_INFO info) DECLSPEC_HIDDEN; +struct store_CERT_KEY_CONTEXT +{ + DWORD cbSize; + DWORD64 hCryptProv; + DWORD dwKeySpec; +}; +void CRYPT_ConvertKeyContext(const struct store_CERT_KEY_CONTEXT *src, CERT_KEY_CONTEXT *dst); /** * String functions */ DWORD cert_name_to_str_with_indent(DWORD dwCertEncodingType, DWORD indent, - const CERT_NAME_BLOB *pName, DWORD dwStrType, LPWSTR psz, DWORD csz) DECLSPEC_HIDDEN; + const CERT_NAME_BLOB *pName, DWORD dwStrType, LPWSTR psz, DWORD csz); /** * Context functions @@ -394,49 +406,49 @@ DWORD cert_name_to_str_with_indent(DWORD dwCertEncodingType, DWORD indent, * which should be one of CERT_CONTEXT, CRL_CONTEXT, or CTL_CONTEXT. * Free with Context_Release. */ -context_t *Context_CreateDataContext(size_t contextSize, const context_vtbl_t *vtbl, struct WINE_CRYPTCERTSTORE*) DECLSPEC_HIDDEN; +context_t *Context_CreateDataContext(size_t contextSize, const context_vtbl_t *vtbl, struct WINE_CRYPTCERTSTORE*); /* Creates a new link context. The context refers to linked * rather than owning its own properties. If addRef is TRUE (which ordinarily * it should be) linked is addref'd. * Free with Context_Release. */ -context_t *Context_CreateLinkContext(unsigned contextSize, context_t *linked, struct WINE_CRYPTCERTSTORE*) DECLSPEC_HIDDEN; +context_t *Context_CreateLinkContext(unsigned contextSize, context_t *linked, struct WINE_CRYPTCERTSTORE*); /* Copies properties from fromContext to toContext. */ -void Context_CopyProperties(const void *to, const void *from) DECLSPEC_HIDDEN; +void Context_CopyProperties(const void *to, const void *from); -void Context_AddRef(context_t*) DECLSPEC_HIDDEN; -void Context_Release(context_t *context) DECLSPEC_HIDDEN; -void Context_Free(context_t*) DECLSPEC_HIDDEN; +void Context_AddRef(context_t*); +void Context_Release(context_t *context); +void Context_Free(context_t*); /** * Context property list functions */ -CONTEXT_PROPERTY_LIST *ContextPropertyList_Create(void) DECLSPEC_HIDDEN; +CONTEXT_PROPERTY_LIST *ContextPropertyList_Create(void); /* Searches for the property with ID id in the context. Returns TRUE if found, * and copies the property's length and a pointer to its data to blob. * Otherwise returns FALSE. */ BOOL ContextPropertyList_FindProperty(CONTEXT_PROPERTY_LIST *list, DWORD id, - PCRYPT_DATA_BLOB blob) DECLSPEC_HIDDEN; + PCRYPT_DATA_BLOB blob); BOOL ContextPropertyList_SetProperty(CONTEXT_PROPERTY_LIST *list, DWORD id, - const BYTE *pbData, size_t cbData) DECLSPEC_HIDDEN; + const BYTE *pbData, size_t cbData); -void ContextPropertyList_RemoveProperty(CONTEXT_PROPERTY_LIST *list, DWORD id) DECLSPEC_HIDDEN; +void ContextPropertyList_RemoveProperty(CONTEXT_PROPERTY_LIST *list, DWORD id); -DWORD ContextPropertyList_EnumPropIDs(CONTEXT_PROPERTY_LIST *list, DWORD id) DECLSPEC_HIDDEN; +DWORD ContextPropertyList_EnumPropIDs(CONTEXT_PROPERTY_LIST *list, DWORD id); void ContextPropertyList_Copy(CONTEXT_PROPERTY_LIST *to, - CONTEXT_PROPERTY_LIST *from) DECLSPEC_HIDDEN; + CONTEXT_PROPERTY_LIST *from); -void ContextPropertyList_Free(CONTEXT_PROPERTY_LIST *list) DECLSPEC_HIDDEN; +void ContextPropertyList_Free(CONTEXT_PROPERTY_LIST *list); -extern WINECRYPT_CERTSTORE empty_store DECLSPEC_HIDDEN; -void init_empty_store(void) DECLSPEC_HIDDEN; +extern WINECRYPT_CERTSTORE empty_store; +void init_empty_store(void); /** * Utilities. @@ -451,4 +463,56 @@ void init_empty_store(void) DECLSPEC_HIDDEN; */ #define IS_INTOID(x) (((ULONG_PTR)(x) >> 16) == 0) +/* Unix interface */ + +typedef UINT64 cert_store_data_t; + +struct open_cert_store_params +{ + CRYPT_DATA_BLOB *pfx; + const WCHAR *password; + cert_store_data_t *data_ret; +}; + +struct import_store_key_params +{ + cert_store_data_t data; + void *buf; + DWORD *buf_size; +}; + +struct import_store_cert_params +{ + cert_store_data_t data; + unsigned int index; + void *buf; + DWORD *buf_size; +}; + +struct close_cert_store_params +{ + cert_store_data_t data; +}; + +struct enum_root_certs_params +{ + void *buffer; + DWORD size; + DWORD *needed; +}; + +enum unix_funcs +{ + unix_process_attach, + unix_process_detach, + unix_open_cert_store, + unix_import_store_key, + unix_import_store_cert, + unix_close_cert_store, + unix_enum_root_certs, + unix_funcs_count, +}; + +#define CRYPT32_CALL( func, params ) WINE_UNIX_CALL( unix_ ## func, params ) + #endif diff --git a/dll/win32/crypt32/ctl.c b/dll/win32/crypt32/ctl.c index b8b728f387c..201a802ceea 100644 --- a/dll/win32/crypt32/ctl.c +++ b/dll/win32/crypt32/ctl.c @@ -68,7 +68,7 @@ BOOL WINAPI CertAddCTLContextToStore(HCERTSTORE hCertStore, BOOL ret = TRUE; PCCTL_CONTEXT toAdd = NULL, existing = NULL; - TRACE("(%p, %p, %08x, %p)\n", hCertStore, pCtlContext, dwAddDisposition, + TRACE("(%p, %p, %08lx, %p)\n", hCertStore, pCtlContext, dwAddDisposition, ppStoreContext); if (dwAddDisposition != CERT_STORE_ADD_ALWAYS) @@ -150,7 +150,7 @@ BOOL WINAPI CertAddCTLContextToStore(HCERTSTORE hCertStore, toAdd = CertDuplicateCTLContext(pCtlContext); break; default: - FIXME("Unimplemented add disposition %d\n", dwAddDisposition); + FIXME("Unimplemented add disposition %ld\n", dwAddDisposition); ret = FALSE; } @@ -182,7 +182,7 @@ BOOL WINAPI CertAddEncodedCTLToStore(HCERTSTORE hCertStore, pbCtlEncoded, cbCtlEncoded); BOOL ret; - TRACE("(%p, %08x, %p, %d, %08x, %p)\n", hCertStore, + TRACE("(%p, %08lx, %p, %ld, %08lx, %p)\n", hCertStore, dwMsgAndCertEncodingType, pbCtlEncoded, cbCtlEncoded, dwAddDisposition, ppCtlContext); @@ -295,7 +295,7 @@ PCCTL_CONTEXT WINAPI CertFindCTLInStore(HCERTSTORE hCertStore, PCCTL_CONTEXT ret; CtlCompareFunc compare; - TRACE("(%p, %d, %d, %d, %p, %p)\n", hCertStore, dwCertEncodingType, + TRACE("(%p, %ld, %ld, %ld, %p, %p)\n", hCertStore, dwCertEncodingType, dwFindFlags, dwFindType, pvFindPara, pPrevCtlContext); switch (dwFindType) @@ -313,7 +313,7 @@ PCCTL_CONTEXT WINAPI CertFindCTLInStore(HCERTSTORE hCertStore, compare = compare_ctl_existing; break; default: - FIXME("find type %08x unimplemented\n", dwFindType); + FIXME("find type %08lx unimplemented\n", dwFindType); compare = NULL; } @@ -370,7 +370,7 @@ PCCTL_CONTEXT WINAPI CertCreateCTLContext(DWORD dwMsgAndCertEncodingType, DWORD contentSize = 0, size; PCTL_INFO ctlInfo = NULL; - TRACE("(%08x, %p, %d)\n", dwMsgAndCertEncodingType, pbCtlEncoded, + TRACE("(%08lx, %p, %ld)\n", dwMsgAndCertEncodingType, pbCtlEncoded, cbCtlEncoded); if (GET_CERT_ENCODING_TYPE(dwMsgAndCertEncodingType) != X509_ASN_ENCODING) @@ -511,7 +511,7 @@ DWORD WINAPI CertEnumCTLContextProperties(PCCTL_CONTEXT pCTLContext, ctl_t *ctl = ctl_from_ptr(pCTLContext); DWORD ret; - TRACE("(%p, %d)\n", pCTLContext, dwPropId); + TRACE("(%p, %ld)\n", pCTLContext, dwPropId); if (ctl->base.properties) ret = ContextPropertyList_EnumPropIDs(ctl->base.properties, dwPropId); @@ -544,7 +544,7 @@ static BOOL CTLContext_GetProperty(ctl_t *ctl, DWORD dwPropId, BOOL ret; CRYPT_DATA_BLOB blob; - TRACE("(%p, %d, %p, %p)\n", ctl, dwPropId, pvData, pcbData); + TRACE("(%p, %ld, %p, %p)\n", ctl, dwPropId, pvData, pcbData); if (ctl->base.properties) ret = ContextPropertyList_FindProperty(ctl->base.properties, dwPropId, &blob); @@ -592,7 +592,7 @@ BOOL WINAPI CertGetCTLContextProperty(PCCTL_CONTEXT pCTLContext, { BOOL ret; - TRACE("(%p, %d, %p, %p)\n", pCTLContext, dwPropId, pvData, pcbData); + TRACE("(%p, %ld, %p, %p)\n", pCTLContext, dwPropId, pvData, pcbData); switch (dwPropId) { @@ -632,7 +632,7 @@ static BOOL CTLContext_SetProperty(ctl_t *ctl, DWORD dwPropId, { BOOL ret; - TRACE("(%p, %d, %08x, %p)\n", ctl, dwPropId, dwFlags, pvData); + TRACE("(%p, %ld, %08lx, %p)\n", ctl, dwPropId, dwFlags, pvData); if (!ctl->base.properties) ret = FALSE; @@ -674,7 +674,7 @@ static BOOL CTLContext_SetProperty(ctl_t *ctl, DWORD dwPropId, pvData, sizeof(FILETIME)); break; default: - FIXME("%d: stub\n", dwPropId); + FIXME("%ld: stub\n", dwPropId); ret = FALSE; } } @@ -687,7 +687,7 @@ BOOL WINAPI CertSetCTLContextProperty(PCCTL_CONTEXT pCTLContext, { BOOL ret; - TRACE("(%p, %d, %08x, %p)\n", pCTLContext, dwPropId, dwFlags, pvData); + TRACE("(%p, %ld, %08lx, %p)\n", pCTLContext, dwPropId, dwFlags, pvData); /* Handle special cases for "read-only"/invalid prop IDs. Windows just * crashes on most of these, I'll be safer. diff --git a/dll/win32/crypt32/decode.c b/dll/win32/crypt32/decode.c index 6f51632dce1..cfdeef5380a 100644 --- a/dll/win32/crypt32/decode.c +++ b/dll/win32/crypt32/decode.c @@ -30,16 +30,11 @@ * MSDN, especially "Constants for CryptEncodeObject and CryptDecodeObject" */ -#include "config.h" -#include "wine/port.h" - #include #include #include #include -#define NONAMELESSUNION - #include "windef.h" #include "winbase.h" #include "wincrypt.h" @@ -50,7 +45,7 @@ #include "crypt32_private.h" /* This is a bit arbitrary, but to set some limit: */ -#define MAX_ENCODED_LEN 0x02000000 +#define MAX_ENCODED_LEN 0x04000000 #define ASN_FLAGS_MASK 0xe0 #define ASN_TYPE_MASK 0x1f @@ -58,6 +53,14 @@ WINE_DEFAULT_DEBUG_CHANNEL(cryptasn); WINE_DECLARE_DEBUG_CHANNEL(crypt); +void CRYPT_CopyReversed(BYTE *dst, const BYTE *src, size_t len) +{ + DWORD i; + for (i = 0; i < len; i++) { + dst[len - i - 1] = src[i]; + } +} + typedef BOOL (WINAPI *CryptDecodeObjectFunc)(DWORD, LPCSTR, const BYTE *, DWORD, DWORD, void *, DWORD *); typedef BOOL (WINAPI *CryptDecodeObjectExFunc)(DWORD, LPCSTR, const BYTE *, @@ -314,7 +317,7 @@ static BOOL CRYPT_AsnDecodeSequenceItems(struct AsnDecodeSequenceItem items[], DWORD i, decoded = 0; const BYTE *ptr = pbEncoded; - TRACE("%p, %d, %p, %d, %08x, %p, %p, %p\n", items, cItem, pbEncoded, + TRACE("%p, %ld, %p, %ld, %08lx, %p, %p, %p\n", items, cItem, pbEncoded, cbEncoded, dwFlags, pvStructInfo, nextData, cbDecoded); for (i = 0, ret = TRUE; ret && i < cItem; i++) @@ -348,9 +351,9 @@ static BOOL CRYPT_AsnDecodeSequenceItems(struct AsnDecodeSequenceItem items[], DWORD itemDecoded; if (pvStructInfo) - TRACE("decoding item %d\n", i); + TRACE("decoding item %ld\n", i); else - TRACE("sizing item %d\n", i); + TRACE("sizing item %ld\n", i); ret = items[i].decodeFunc(ptr, itemEncodedLen, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo ? (BYTE *)pvStructInfo + items[i].offset @@ -364,13 +367,13 @@ static BOOL CRYPT_AsnDecodeSequenceItems(struct AsnDecodeSequenceItem items[], /* Account for alignment padding */ items[i].size = ALIGN_DWORD_PTR(items[i].size); } - TRACE("item %d size: %d\n", i, items[i].size); + TRACE("item %ld size: %ld\n", i, items[i].size); if (nextData && items[i].hasPointer && items[i].size > items[i].minSize) nextData += items[i].size - items[i].minSize; if (itemDecoded > itemEncodedLen) { - WARN("decoded length %d exceeds encoded %d\n", + WARN("decoded length %ld exceeds encoded %ld\n", itemDecoded, itemEncodedLen); SetLastError(CRYPT_E_ASN1_CORRUPT); ret = FALSE; @@ -379,20 +382,20 @@ static BOOL CRYPT_AsnDecodeSequenceItems(struct AsnDecodeSequenceItem items[], { ptr += itemDecoded; decoded += itemDecoded; - TRACE("item %d: decoded %d bytes\n", i, + TRACE("item %ld: decoded %ld bytes\n", i, itemDecoded); } } else if (items[i].optional && GetLastError() == CRYPT_E_ASN1_BADTAG) { - TRACE("skipping optional item %d\n", i); + TRACE("skipping optional item %ld\n", i); items[i].size = items[i].minSize; SetLastError(NOERROR); ret = TRUE; } else - TRACE("item %d failed: %08x\n", i, + TRACE("item %ld failed: %08lx\n", i, GetLastError()); } else if (itemLen == CMSG_INDEFINITE_LENGTH) @@ -403,7 +406,7 @@ static BOOL CRYPT_AsnDecodeSequenceItems(struct AsnDecodeSequenceItem items[], } else { - TRACE("item %d: decoded %d bytes\n", i, itemEncodedLen); + TRACE("item %ld: decoded %ld bytes\n", i, itemEncodedLen); ptr += itemEncodedLen; decoded += itemEncodedLen; items[i].size = items[i].minSize; @@ -411,12 +414,12 @@ static BOOL CRYPT_AsnDecodeSequenceItems(struct AsnDecodeSequenceItem items[], } else if (items[i].optional) { - TRACE("skipping optional item %d\n", i); + TRACE("skipping optional item %ld\n", i); items[i].size = items[i].minSize; } else { - TRACE("item %d: tag %02x doesn't match expected %02x\n", + TRACE("item %ld: tag %02x doesn't match expected %02x\n", i, ptr[0], items[i].tag); SetLastError(CRYPT_E_ASN1_BADTAG); ret = FALSE; @@ -425,12 +428,12 @@ static BOOL CRYPT_AsnDecodeSequenceItems(struct AsnDecodeSequenceItem items[], } else if (items[i].optional) { - TRACE("missing optional item %d, skipping\n", i); + TRACE("missing optional item %ld, skipping\n", i); items[i].size = items[i].minSize; } else { - TRACE("not enough bytes for item %d, failing\n", i); + TRACE("not enough bytes for item %ld, failing\n", i); SetLastError(CRYPT_E_ASN1_CORRUPT); ret = FALSE; } @@ -455,7 +458,7 @@ static BOOL CRYPT_AsnDecodeSequence(struct AsnDecodeSequenceItem items[], { BOOL ret; - TRACE("%p, %d, %p, %d, %08x, %p, %p, %d, %p\n", items, cItem, pbEncoded, + TRACE("%p, %ld, %p, %ld, %08lx, %p, %p, %ld, %p\n", items, cItem, pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, *pcbStructInfo, startingPointer); @@ -483,7 +486,7 @@ static BOOL CRYPT_AsnDecodeSequence(struct AsnDecodeSequenceItem items[], } else if (cbEncoded < dataLen) { - TRACE("dataLen %d exceeds cbEncoded %d, failing\n", dataLen, + TRACE("dataLen %ld exceeds cbEncoded %ld, failing\n", dataLen, cbEncoded); SetLastError(CRYPT_E_ASN1_CORRUPT); ret = FALSE; @@ -513,7 +516,7 @@ static BOOL CRYPT_AsnDecodeSequence(struct AsnDecodeSequenceItem items[], } if (ret && !indefinite && cbDecoded != dataLen) { - TRACE("expected %d decoded, got %d, failing\n", dataLen, + TRACE("expected %ld decoded, got %ld, failing\n", dataLen, cbDecoded); SetLastError(CRYPT_E_ASN1_CORRUPT); ret = FALSE; @@ -559,7 +562,7 @@ static BOOL CRYPT_AsnDecodeSequence(struct AsnDecodeSequenceItem items[], SetLastError(CRYPT_E_ASN1_BADTAG); ret = FALSE; } - TRACE("returning %d (%08x)\n", ret, GetLastError()); + TRACE("returning %d (%08lx)\n", ret, GetLastError()); return ret; } @@ -617,7 +620,7 @@ static BOOL CRYPT_AsnDecodeArray(const struct AsnArrayDescriptor *arrayDesc, { BOOL ret = TRUE; - TRACE("%p, %p, %d, %p, %d\n", arrayDesc, pbEncoded, + TRACE("%p, %p, %ld, %p, %ld\n", arrayDesc, pbEncoded, cbEncoded, pvStructInfo, pvStructInfo ? *pcbStructInfo : 0); if (!cbEncoded) @@ -631,7 +634,7 @@ static BOOL CRYPT_AsnDecodeArray(const struct AsnArrayDescriptor *arrayDesc, if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded, &dataLen))) { - DWORD bytesNeeded = arrayDesc->minArraySize, cItems = 0, decoded; + DWORD bytesNeeded = arrayDesc->minArraySize, cItems = 0, capacity = 0, decoded; BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]); /* There can be arbitrarily many items, but there is often only one. */ @@ -683,17 +686,25 @@ static BOOL CRYPT_AsnDecodeArray(const struct AsnArrayDescriptor *arrayDesc, &itemDecoded); if (ret) { - cItems++; - if (itemSizes != &itemSize) - itemSizes = CryptMemRealloc(itemSizes, - cItems * sizeof(struct AsnArrayItemSize)); - else if (cItems > 1) + /* Ignore an item that failed to decode but the decoder doesn't want to fail the whole process */ + if (!size) { - itemSizes = - CryptMemAlloc( - cItems * sizeof(struct AsnArrayItemSize)); - if (itemSizes) - *itemSizes = itemSize; + ptr += itemEncoded; + continue; + } + + if (++cItems <= 1) + itemSizes = &itemSize; + else if (itemSizes == &itemSize) + { + capacity = 1024; + itemSizes = CryptMemAlloc(capacity * sizeof(struct AsnArrayItemSize)); + if (itemSizes) *itemSizes = itemSize; + } + else if (cItems > capacity) + { + capacity = capacity * 3 / 2; + itemSizes = CryptMemRealloc(itemSizes, capacity * sizeof(struct AsnArrayItemSize)); } if (itemSizes) { @@ -791,7 +802,7 @@ static BOOL CRYPT_AsnDecodeDerBlob(const BYTE *pbEncoded, DWORD cbEncoded, { BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]); DWORD bytesNeeded = sizeof(CRYPT_DER_BLOB); - + if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG)) bytesNeeded += 1 + lenBytes + dataLen; @@ -834,7 +845,7 @@ static BOOL CRYPT_AsnDecodeBitsSwapBytes(const BYTE *pbEncoded, { BOOL ret; - TRACE("(%p, %d, 0x%08x, %p, %d, %p)\n", pbEncoded, cbEncoded, dwFlags, + TRACE("(%p, %ld, 0x%08lx, %p, %ld, %p)\n", pbEncoded, cbEncoded, dwFlags, pvStructInfo, *pcbStructInfo, pcbDecoded); /* Can't use the CRYPT_DECODE_NOCOPY_FLAG, because we modify the bytes in- @@ -860,7 +871,7 @@ static BOOL CRYPT_AsnDecodeBitsSwapBytes(const BYTE *pbEncoded, } } } - TRACE("returning %d (%08x)\n", ret, GetLastError()); + TRACE("returning %d (%08lx)\n", ret, GetLastError()); return ret; } @@ -870,7 +881,7 @@ static BOOL WINAPI CRYPT_AsnDecodeCertSignedContent(DWORD dwCertEncodingType, { BOOL ret = TRUE; - TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags, + TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, *pcbStructInfo); __TRY @@ -901,7 +912,7 @@ static BOOL WINAPI CRYPT_AsnDecodeCertSignedContent(DWORD dwCertEncodingType, } __ENDTRY - TRACE("Returning %d (%08x)\n", ret, GetLastError()); + TRACE("Returning %d (%08lx)\n", ret, GetLastError()); return ret; } @@ -952,7 +963,7 @@ static BOOL CRYPT_AsnDecodeCertExtensionsInternal(const BYTE *pbEncoded, CRYPT_AsnDecodeExtension, sizeof(CERT_EXTENSION), TRUE, offsetof(CERT_EXTENSION, pszObjId) }; - TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags, + TRACE("%p, %ld, %08lx, %p, %ld, %p\n", pbEncoded, cbEncoded, dwFlags, pvStructInfo, *pcbStructInfo, pcbDecoded); ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, @@ -1017,7 +1028,7 @@ static BOOL CRYPT_AsnDecodeCertInfo(DWORD dwCertEncodingType, TRUE, TRUE, offsetof(CERT_INFO, rgExtension), 0 }, }; - TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags, + TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, *pcbStructInfo); ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items), @@ -1042,7 +1053,7 @@ static BOOL CRYPT_AsnDecodeCertInfo(DWORD dwCertEncodingType, } } - TRACE("Returning %d (%08x)\n", ret, GetLastError()); + TRACE("Returning %d (%08lx)\n", ret, GetLastError()); return ret; } @@ -1052,7 +1063,7 @@ static BOOL WINAPI CRYPT_AsnDecodeCert(DWORD dwCertEncodingType, { BOOL ret = FALSE; - TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags, + TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, *pcbStructInfo); __TRY @@ -1092,7 +1103,7 @@ static BOOL WINAPI CRYPT_AsnDecodeCert(DWORD dwCertEncodingType, } __ENDTRY - TRACE("Returning %d (%08x)\n", ret, GetLastError()); + TRACE("Returning %d (%08lx)\n", ret, GetLastError()); return ret; } @@ -1107,7 +1118,7 @@ static BOOL CRYPT_AsnDecodeCRLEntryExtensions(const BYTE *pbEncoded, CRYPT_AsnDecodeExtension, sizeof(CERT_EXTENSION), TRUE, offsetof(CERT_EXTENSION, pszObjId) }; - TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags, + TRACE("%p, %ld, %08lx, %p, %ld, %p\n", pbEncoded, cbEncoded, dwFlags, pvStructInfo, *pcbStructInfo, pcbDecoded); ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, @@ -1132,7 +1143,7 @@ static BOOL CRYPT_AsnDecodeCRLEntry(const BYTE *pbEncoded, DWORD cbEncoded, }; PCRL_ENTRY entry = pvStructInfo; - TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, entry, + TRACE("%p, %ld, %08lx, %p, %ld\n", pbEncoded, cbEncoded, dwFlags, entry, *pcbStructInfo); ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items), @@ -1160,12 +1171,12 @@ static BOOL CRYPT_AsnDecodeCRLEntries(const BYTE *pbEncoded, DWORD cbEncoded, CRYPT_AsnDecodeCRLEntry, sizeof(CRL_ENTRY), TRUE, offsetof(CRL_ENTRY, SerialNumber.pbData) }; - TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags, + TRACE("%p, %ld, %08lx, %p, %ld, %p\n", pbEncoded, cbEncoded, dwFlags, pvStructInfo, *pcbStructInfo, pcbDecoded); ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded); - TRACE("Returning %d (%08x)\n", ret, GetLastError()); + TRACE("Returning %d (%08lx)\n", ret, GetLastError()); return ret; } @@ -1180,7 +1191,7 @@ static BOOL CRYPT_AsnDecodeCRLExtensionsInternal(const BYTE *pbEncoded, CRYPT_AsnDecodeExtension, sizeof(CERT_EXTENSION), TRUE, offsetof(CERT_EXTENSION, pszObjId) }; - TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags, + TRACE("%p, %ld, %08lx, %p, %ld, %p\n", pbEncoded, cbEncoded, dwFlags, pvStructInfo, *pcbStructInfo, pcbDecoded); ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, @@ -1233,13 +1244,13 @@ static BOOL CRYPT_AsnDecodeCRLInfo(DWORD dwCertEncodingType, }; BOOL ret = TRUE; - TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags, + TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, *pcbStructInfo); ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items), pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, NULL, NULL); - TRACE("Returning %d (%08x)\n", ret, GetLastError()); + TRACE("Returning %d (%08lx)\n", ret, GetLastError()); return ret; } @@ -1249,7 +1260,7 @@ static BOOL WINAPI CRYPT_AsnDecodeCRL(DWORD dwCertEncodingType, { BOOL ret = FALSE; - TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags, + TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, *pcbStructInfo); __TRY @@ -1289,7 +1300,7 @@ static BOOL WINAPI CRYPT_AsnDecodeCRL(DWORD dwCertEncodingType, } __ENDTRY - TRACE("Returning %d (%08x)\n", ret, GetLastError()); + TRACE("Returning %d (%08lx)\n", ret, GetLastError()); return ret; } @@ -1299,7 +1310,7 @@ static BOOL CRYPT_AsnDecodeOidIgnoreTag(const BYTE *pbEncoded, DWORD cbEncoded, BOOL ret = TRUE; DWORD dataLen; - TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, + TRACE("%p, %ld, %08lx, %p, %ld\n", pbEncoded, cbEncoded, dwFlags, pvStructInfo, *pcbStructInfo); if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen))) @@ -1397,7 +1408,7 @@ static BOOL CRYPT_AsnDecodeOidInternal(const BYTE *pbEncoded, DWORD cbEncoded, { BOOL ret; - TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, + TRACE("%p, %ld, %08lx, %p, %ld\n", pbEncoded, cbEncoded, dwFlags, pvStructInfo, *pcbStructInfo); if (pbEncoded[0] == ASN_OBJECTIDENTIFIER) @@ -1427,7 +1438,7 @@ static BOOL CRYPT_AsnDecodeExtension(const BYTE *pbEncoded, DWORD cbEncoded, BOOL ret = TRUE; PCERT_EXTENSION ext = pvStructInfo; - TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, ext, + TRACE("%p, %ld, %08lx, %p, %ld\n", pbEncoded, cbEncoded, dwFlags, ext, *pcbStructInfo); if (ext) @@ -1438,7 +1449,7 @@ static BOOL CRYPT_AsnDecodeExtension(const BYTE *pbEncoded, DWORD cbEncoded, if (ext) TRACE("ext->pszObjId is %p (%s)\n", ext->pszObjId, debugstr_a(ext->pszObjId)); - TRACE("returning %d (%08x)\n", ret, GetLastError()); + TRACE("returning %d (%08lx)\n", ret, GetLastError()); return ret; } @@ -1448,7 +1459,7 @@ static BOOL WINAPI CRYPT_AsnDecodeExtensions(DWORD dwCertEncodingType, { BOOL ret = TRUE; - TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, + TRACE("%p, %ld, %08lx, %p, %ld\n", pbEncoded, cbEncoded, dwFlags, pvStructInfo, pvStructInfo ? *pcbStructInfo : 0); __TRY @@ -1588,15 +1599,12 @@ static BOOL CRYPT_AsnDecodeNameValueInternal(const BYTE *pbEncoded, case ASN_VISIBLESTRING: case ASN_GENERALSTRING: value->Value.cbData = dataLen; - if (dataLen) - { - if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG)) - memcpy(value->Value.pbData, - pbEncoded + 1 + lenBytes, dataLen); - else - value->Value.pbData = (LPBYTE)pbEncoded + 1 + - lenBytes; - } + if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG)) + memcpy(value->Value.pbData, + pbEncoded + 1 + lenBytes, dataLen); + else + value->Value.pbData = (LPBYTE)pbEncoded + 1 + + lenBytes; break; case ASN_BMPSTRING: { @@ -1865,7 +1873,7 @@ static BOOL CRYPT_AsnDecodeRdnAttr(const BYTE *pbEncoded, DWORD cbEncoded, }; CERT_RDN_ATTR *attr = pvStructInfo; - TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, + TRACE("%p, %ld, %08lx, %p, %ld\n", pbEncoded, cbEncoded, dwFlags, pvStructInfo, *pcbStructInfo); if (attr) @@ -1877,9 +1885,9 @@ static BOOL CRYPT_AsnDecodeRdnAttr(const BYTE *pbEncoded, DWORD cbEncoded, { TRACE("attr->pszObjId is %p (%s)\n", attr->pszObjId, debugstr_a(attr->pszObjId)); - TRACE("attr->dwValueType is %d\n", attr->dwValueType); + TRACE("attr->dwValueType is %ld\n", attr->dwValueType); } - TRACE("returning %d (%08x)\n", ret, GetLastError()); + TRACE("returning %d (%08lx)\n", ret, GetLastError()); return ret; } @@ -1962,7 +1970,7 @@ static BOOL CRYPT_AsnDecodeUnicodeRdnAttr(const BYTE *pbEncoded, }; CERT_RDN_ATTR *attr = pvStructInfo; - TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, + TRACE("%p, %ld, %08lx, %p, %ld\n", pbEncoded, cbEncoded, dwFlags, pvStructInfo, *pcbStructInfo); if (attr) @@ -1974,9 +1982,9 @@ static BOOL CRYPT_AsnDecodeUnicodeRdnAttr(const BYTE *pbEncoded, { TRACE("attr->pszObjId is %p (%s)\n", attr->pszObjId, debugstr_a(attr->pszObjId)); - TRACE("attr->dwValueType is %d\n", attr->dwValueType); + TRACE("attr->dwValueType is %ld\n", attr->dwValueType); } - TRACE("returning %d (%08x)\n", ret, GetLastError()); + TRACE("returning %d (%08lx)\n", ret, GetLastError()); return ret; } @@ -2050,7 +2058,7 @@ static BOOL CRYPT_FindEncodedLen(const BYTE *pbEncoded, DWORD cbEncoded, BOOL ret = TRUE, done = FALSE; DWORD indefiniteNestingLevels = 0, decoded = 0; - TRACE("(%p, %d)\n", pbEncoded, cbEncoded); + TRACE("(%p, %ld)\n", pbEncoded, cbEncoded); do { DWORD dataLen; @@ -2068,7 +2076,7 @@ static BOOL CRYPT_FindEncodedLen(const BYTE *pbEncoded, DWORD cbEncoded, pbEncoded += 1 + lenBytes; cbEncoded -= 1 + lenBytes; decoded += 1 + lenBytes; - TRACE("indefiniteNestingLevels = %d\n", + TRACE("indefiniteNestingLevels = %ld\n", indefiniteNestingLevels); } else @@ -2077,7 +2085,7 @@ static BOOL CRYPT_FindEncodedLen(const BYTE *pbEncoded, DWORD cbEncoded, indefiniteNestingLevels) { indefiniteNestingLevels--; - TRACE("indefiniteNestingLevels = %d\n", + TRACE("indefiniteNestingLevels = %ld\n", indefiniteNestingLevels); } pbEncoded += 1 + lenBytes + dataLen; @@ -2096,7 +2104,7 @@ static BOOL CRYPT_FindEncodedLen(const BYTE *pbEncoded, DWORD cbEncoded, } if (ret) *pcbDecoded = decoded; - TRACE("returning %d (%d)\n", ret, ret ? *pcbDecoded : 0); + TRACE("returning %d (%ld)\n", ret, ret ? *pcbDecoded : 0); return ret; } @@ -2107,7 +2115,7 @@ static BOOL CRYPT_AsnDecodeCopyBytes(const BYTE *pbEncoded, BOOL ret = TRUE; DWORD bytesNeeded = sizeof(CRYPT_OBJID_BLOB), encodedLen = 0; - TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, + TRACE("%p, %ld, %08lx, %p, %ld\n", pbEncoded, cbEncoded, dwFlags, pvStructInfo, *pcbStructInfo); if ((ret = CRYPT_FindEncodedLen(pbEncoded, cbEncoded, &encodedLen))) @@ -2193,7 +2201,7 @@ static BOOL CRYPT_AsnDecodeCTLEntry(const BYTE *pbEncoded, DWORD cbEncoded, BOOL ret = TRUE; CTL_ENTRY *entry = pvStructInfo; - TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, entry, + TRACE("%p, %ld, %08lx, %p, %ld\n", pbEncoded, cbEncoded, dwFlags, entry, *pcbStructInfo); ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items), @@ -2212,7 +2220,7 @@ static BOOL CRYPT_AsnDecodeCTLEntries(const BYTE *pbEncoded, DWORD cbEncoded, CRYPT_AsnDecodeCTLEntry, sizeof(CTL_ENTRY), TRUE, offsetof(CTL_ENTRY, SubjectIdentifier.pbData) }; - TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags, + TRACE("%p, %ld, %08lx, %p, %ld, %p\n", pbEncoded, cbEncoded, dwFlags, pvStructInfo, *pcbStructInfo, pcbDecoded); ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, @@ -2231,7 +2239,7 @@ static BOOL CRYPT_AsnDecodeCTLExtensionsInternal(const BYTE *pbEncoded, CRYPT_AsnDecodeExtension, sizeof(CERT_EXTENSION), TRUE, offsetof(CERT_EXTENSION, pszObjId) }; - TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags, + TRACE("%p, %ld, %08lx, %p, %ld, %p\n", pbEncoded, cbEncoded, dwFlags, pvStructInfo, *pcbStructInfo, pcbDecoded); ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, @@ -2264,7 +2272,7 @@ static BOOL WINAPI CRYPT_AsnDecodeCTL(DWORD dwCertEncodingType, { BOOL ret = FALSE; - TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags, + TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, *pcbStructInfo); __TRY @@ -2326,7 +2334,7 @@ static BOOL CRYPT_AsnDecodeSMIMECapability(const BYTE *pbEncoded, }; PCRYPT_SMIME_CAPABILITY capability = pvStructInfo; - TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, + TRACE("%p, %ld, %08lx, %p, %ld\n", pbEncoded, cbEncoded, dwFlags, pvStructInfo, *pcbStructInfo); ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items), @@ -2342,7 +2350,7 @@ static BOOL WINAPI CRYPT_AsnDecodeSMIMECapabilities(DWORD dwCertEncodingType, { BOOL ret = FALSE; - TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags, + TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, *pcbStructInfo); __TRY @@ -2430,7 +2438,7 @@ static BOOL CRYPT_AsnDecodeNoticeNumbers(const BYTE *pbEncoded, CRYPT_AsnDecodeIntInternal, sizeof(int), FALSE, 0 }; BOOL ret; - TRACE("(%p, %d, %08x, %p, %d)\n", pbEncoded, cbEncoded, dwFlags, + TRACE("(%p, %ld, %08lx, %p, %ld)\n", pbEncoded, cbEncoded, dwFlags, pvStructInfo, pvStructInfo ? *pcbDecoded : 0); ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, @@ -2456,7 +2464,7 @@ static BOOL CRYPT_AsnDecodeNoticeReference(const BYTE *pbEncoded, }; DWORD bytesNeeded = 0; - TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, + TRACE("%p, %ld, %08lx, %p, %ld\n", pbEncoded, cbEncoded, dwFlags, pvStructInfo, pvStructInfo ? *pcbStructInfo : 0); ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items), @@ -2585,7 +2593,7 @@ static BOOL CRYPT_AsnDecodeUnicodeString(const BYTE *pbEncoded, if (dataLen) { DWORD i; - LPWSTR str = *(LPWSTR *)pStr; + LPWSTR str = *pStr; assert(str); switch (pbEncoded[0]) @@ -2647,7 +2655,7 @@ static BOOL CRYPT_AsnDecodePolicyQualifierUserNoticeInternal( }; PCERT_POLICY_QUALIFIER_USER_NOTICE notice = pvStructInfo; - TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, + TRACE("%p, %ld, %08lx, %p, %ld\n", pbEncoded, cbEncoded, dwFlags, pvStructInfo, *pcbStructInfo); ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items), @@ -2664,7 +2672,7 @@ static BOOL WINAPI CRYPT_AsnDecodePolicyQualifierUserNotice( { BOOL ret = FALSE; - TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags, + TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, *pcbStructInfo); __TRY @@ -2718,7 +2726,7 @@ static BOOL CRYPT_AsnDecodePKCSAttributeValue(const BYTE *pbEncoded, CRYPT_AsnDecodeCopyBytes, sizeof(CRYPT_DER_BLOB), TRUE, offsetof(CRYPT_DER_BLOB, pbData) }; - TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags, + TRACE("%p, %ld, %08lx, %p, %ld, %p\n", pbEncoded, cbEncoded, dwFlags, pvStructInfo, pvStructInfo ? *pcbStructInfo : 0, pcbDecoded); ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, @@ -2742,7 +2750,7 @@ static BOOL CRYPT_AsnDecodePKCSAttributeInternal(const BYTE *pbEncoded, }; PCRYPT_ATTRIBUTE attr = pvStructInfo; - TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, + TRACE("%p, %ld, %08lx, %p, %ld\n", pbEncoded, cbEncoded, dwFlags, pvStructInfo, *pcbStructInfo); ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items), @@ -2758,7 +2766,7 @@ static BOOL WINAPI CRYPT_AsnDecodePKCSAttribute(DWORD dwCertEncodingType, { BOOL ret = FALSE; - TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags, + TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, *pcbStructInfo); __TRY @@ -2820,7 +2828,7 @@ static BOOL WINAPI CRYPT_AsnDecodePKCSAttributes(DWORD dwCertEncodingType, { BOOL ret = FALSE; - TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags, + TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, *pcbStructInfo); __TRY @@ -2860,7 +2868,7 @@ static BOOL CRYPT_AsnDecodeAlgorithmId(const BYTE *pbEncoded, DWORD cbEncoded, offsetof(CRYPT_ALGORITHM_IDENTIFIER, Parameters.pbData), 0 }, }; - TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags, + TRACE("%p, %ld, %08lx, %p, %ld, %p\n", pbEncoded, cbEncoded, dwFlags, pvStructInfo, *pcbStructInfo, pcbDecoded); ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items), @@ -2977,7 +2985,7 @@ static BOOL CRYPT_AsnDecodeBool(const BYTE *pbEncoded, DWORD cbEncoded, *(BOOL *)pvStructInfo = pbEncoded[2] != 0; ret = TRUE; } - TRACE("returning %d (%08x)\n", ret, GetLastError()); + TRACE("returning %d (%08lx)\n", ret, GetLastError()); return ret; } @@ -2988,7 +2996,7 @@ static BOOL CRYPT_AsnDecodeAltNameEntry(const BYTE *pbEncoded, DWORD cbEncoded, DWORD dataLen, lenBytes, bytesNeeded = sizeof(CERT_ALT_NAME_ENTRY); BOOL ret; - TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, + TRACE("%p, %ld, %08lx, %p, %ld\n", pbEncoded, cbEncoded, dwFlags, pvStructInfo, *pcbStructInfo); if (cbEncoded < 2) @@ -3074,11 +3082,10 @@ static BOOL CRYPT_AsnDecodeAltNameEntry(const BYTE *pbEncoded, DWORD cbEncoded, DWORD i; for (i = 0; i < dataLen; i++) - entry->u.pwszURL[i] = - (WCHAR)pbEncoded[1 + lenBytes + i]; - entry->u.pwszURL[i] = 0; - TRACE("URL is %p (%s)\n", entry->u.pwszURL, - debugstr_w(entry->u.pwszURL)); + entry->pwszURL[i] = (WCHAR)pbEncoded[1 + lenBytes + i]; + entry->pwszURL[i] = 0; + TRACE("URL is %p (%s)\n", entry->pwszURL, + debugstr_w(entry->pwszURL)); break; } case 4: /* directoryName */ @@ -3089,14 +3096,14 @@ static BOOL CRYPT_AsnDecodeAltNameEntry(const BYTE *pbEncoded, DWORD cbEncoded, /* The next data pointer is in the pwszURL spot, that is, * the first 4 bytes. Need to move it to the next spot. */ - entry->u.IPAddress.pbData = (LPBYTE)entry->u.pwszURL; - entry->u.IPAddress.cbData = dataLen; - memcpy(entry->u.IPAddress.pbData, pbEncoded + 1 + lenBytes, + entry->IPAddress.pbData = (LPBYTE)entry->pwszURL; + entry->IPAddress.cbData = dataLen; + memcpy(entry->IPAddress.pbData, pbEncoded + 1 + lenBytes, dataLen); break; case 8: /* registeredID */ ret = CRYPT_AsnDecodeOidIgnoreTag(pbEncoded, cbEncoded, 0, - &entry->u.pszRegisteredID, &dataLen, NULL); + &entry->pszRegisteredID, &dataLen, NULL); break; } } @@ -3115,9 +3122,9 @@ static BOOL CRYPT_AsnDecodeAltNameInternal(const BYTE *pbEncoded, offsetof(CERT_ALT_NAME_INFO, rgAltEntry), sizeof(CERT_ALT_NAME_INFO), CRYPT_AsnDecodeAltNameEntry, sizeof(CERT_ALT_NAME_ENTRY), TRUE, - offsetof(CERT_ALT_NAME_ENTRY, u.pwszURL) }; + offsetof(CERT_ALT_NAME_ENTRY, pwszURL) }; - TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags, + TRACE("%p, %ld, %08lx, %p, %ld, %p\n", pbEncoded, cbEncoded, dwFlags, pvStructInfo, *pcbStructInfo, pcbDecoded); ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags, @@ -3207,7 +3214,7 @@ static BOOL CRYPT_AsnDecodeAccessDescription(const BYTE *pbEncoded, offsetof(CERT_ACCESS_DESCRIPTION, pszAccessMethod), 0 }, { 0, offsetof(CERT_ACCESS_DESCRIPTION, AccessLocation), CRYPT_AsnDecodeAltNameEntry, sizeof(CERT_ALT_NAME_ENTRY), FALSE, - TRUE, offsetof(CERT_ACCESS_DESCRIPTION, AccessLocation.u.pwszURL), 0 }, + TRUE, offsetof(CERT_ACCESS_DESCRIPTION, AccessLocation.pwszURL), 0 }, }; CERT_ACCESS_DESCRIPTION *descr = pvStructInfo; @@ -3222,7 +3229,7 @@ static BOOL WINAPI CRYPT_AsnDecodeAuthorityInfoAccess(DWORD dwCertEncodingType, { BOOL ret; - TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags, + TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, *pcbStructInfo); __TRY @@ -3255,7 +3262,7 @@ static BOOL CRYPT_AsnDecodePKCSContent(const BYTE *pbEncoded, DWORD cbEncoded, BOOL ret; DWORD dataLen; - TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags, + TRACE("%p, %ld, %08lx, %p, %ld, %p\n", pbEncoded, cbEncoded, dwFlags, pvStructInfo, *pcbStructInfo, pcbDecoded); /* The caller has already checked the tag, no need to check it again. @@ -3294,7 +3301,7 @@ static BOOL CRYPT_AsnDecodePKCSContent(const BYTE *pbEncoded, DWORD cbEncoded, if (ret && pcbDecoded) { *pcbDecoded = 1 + lenBytes + decodedLen; - TRACE("decoded %d bytes\n", *pcbDecoded); + TRACE("decoded %ld bytes\n", *pcbDecoded); } } } @@ -3317,7 +3324,7 @@ static BOOL CRYPT_AsnDecodePKCSContentInfoInternal(const BYTE *pbEncoded, }; BOOL ret; - TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags, + TRACE("%p, %ld, %08lx, %p, %ld, %p\n", pbEncoded, cbEncoded, dwFlags, pvStructInfo, *pcbStructInfo, pcbDecoded); ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items), @@ -3332,7 +3339,7 @@ static BOOL WINAPI CRYPT_AsnDecodePKCSContentInfo(DWORD dwCertEncodingType, { BOOL ret = FALSE; - TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags, + TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, *pcbStructInfo); __TRY @@ -3401,7 +3408,7 @@ static BOOL WINAPI CRYPT_AsnDecodeAltName(DWORD dwCertEncodingType, { BOOL ret = TRUE; - TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags, + TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, *pcbStructInfo); __TRY @@ -3453,7 +3460,7 @@ static BOOL CRYPT_AsnDecodePathLenConstraint(const BYTE *pbEncoded, BOOL ret = TRUE; DWORD bytesNeeded = sizeof(struct PATH_LEN_CONSTRAINT), size; - TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags, + TRACE("%p, %ld, %08lx, %p, %ld, %p\n", pbEncoded, cbEncoded, dwFlags, pvStructInfo, *pcbStructInfo, pcbDecoded); if (!pvStructInfo) @@ -3478,10 +3485,10 @@ static BOOL CRYPT_AsnDecodePathLenConstraint(const BYTE *pbEncoded, &constraint->dwPathLenConstraint, &size, pcbDecoded); if (ret) constraint->fPathLenConstraint = TRUE; - TRACE("got an int, dwPathLenConstraint is %d\n", + TRACE("got an int, dwPathLenConstraint is %ld\n", constraint->dwPathLenConstraint); } - TRACE("returning %d (%08x)\n", ret, GetLastError()); + TRACE("returning %d (%08lx)\n", ret, GetLastError()); return ret; } @@ -3497,12 +3504,12 @@ static BOOL CRYPT_AsnDecodeSubtreeConstraints(const BYTE *pbEncoded, CRYPT_AsnDecodeCopyBytes, sizeof(CERT_NAME_BLOB), TRUE, offsetof(CERT_NAME_BLOB, pbData) }; - TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags, + TRACE("%p, %ld, %08lx, %p, %ld, %p\n", pbEncoded, cbEncoded, dwFlags, pvStructInfo, *pcbStructInfo, pcbDecoded); ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded); - TRACE("Returning %d (%08x)\n", ret, GetLastError()); + TRACE("Returning %d (%08lx)\n", ret, GetLastError()); return ret; } @@ -3586,7 +3593,7 @@ static BOOL CRYPT_AsnDecodePolicyQualifier(const BYTE *pbEncoded, BOOL ret; CERT_POLICY_QUALIFIER_INFO *qualifier = pvStructInfo; - TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, + TRACE("%p, %ld, %08lx, %p, %ld\n", pbEncoded, cbEncoded, dwFlags, pvStructInfo, pvStructInfo ? *pcbStructInfo : 0); ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items), @@ -3607,12 +3614,12 @@ static BOOL CRYPT_AsnDecodePolicyQualifiers(const BYTE *pbEncoded, CRYPT_AsnDecodePolicyQualifier, sizeof(CERT_POLICY_QUALIFIER_INFO), TRUE, offsetof(CERT_POLICY_QUALIFIER_INFO, pszPolicyQualifierId) }; - TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, + TRACE("%p, %ld, %08lx, %p, %ld\n", pbEncoded, cbEncoded, dwFlags, pvStructInfo, pvStructInfo ? *pcbStructInfo : 0); ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded); - TRACE("Returning %d (%08x)\n", ret, GetLastError()); + TRACE("Returning %d (%08lx)\n", ret, GetLastError()); return ret; } @@ -3631,7 +3638,7 @@ static BOOL CRYPT_AsnDecodeCertPolicy(const BYTE *pbEncoded, DWORD cbEncoded, CERT_POLICY_INFO *info = pvStructInfo; BOOL ret; - TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, + TRACE("%p, %ld, %08lx, %p, %ld\n", pbEncoded, cbEncoded, dwFlags, pvStructInfo, pvStructInfo ? *pcbStructInfo : 0); ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items), @@ -3646,7 +3653,7 @@ static BOOL WINAPI CRYPT_AsnDecodeCertPolicies(DWORD dwCertEncodingType, { BOOL ret = FALSE; - TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags, + TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, pvStructInfo ? *pcbStructInfo : 0); __TRY @@ -3688,7 +3695,7 @@ static BOOL CRYPT_AsnDecodeCertPolicyMapping(const BYTE *pbEncoded, CERT_POLICY_MAPPING *mapping = pvStructInfo; BOOL ret; - TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, + TRACE("%p, %ld, %08lx, %p, %ld\n", pbEncoded, cbEncoded, dwFlags, pvStructInfo, pvStructInfo ? *pcbStructInfo : 0); ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items), @@ -3703,7 +3710,7 @@ static BOOL WINAPI CRYPT_AsnDecodeCertPolicyMappings(DWORD dwCertEncodingType, { BOOL ret = FALSE; - TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags, + TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, pvStructInfo ? *pcbStructInfo : 0); __TRY @@ -3830,7 +3837,7 @@ static BOOL WINAPI CRYPT_AsnDecodeCertPolicyConstraints( { BOOL ret = FALSE; - TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags, + TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, pvStructInfo ? *pcbStructInfo : 0); __TRY @@ -3864,11 +3871,46 @@ static BOOL WINAPI CRYPT_AsnDecodeCertPolicyConstraints( struct DECODED_RSA_PUB_KEY { - DWORD pubexp; + CRYPT_INTEGER_BLOB pubexp; CRYPT_INTEGER_BLOB modulus; }; -static BOOL WINAPI CRYPT_AsnDecodeRsaPubKey(DWORD dwCertEncodingType, +/* Helper function to decode an ASN.1 DER encoded RSA public key, writing the decoded + * key into 'decodedKey', and the length into 'size'. The memory + * for 'decodedKey' is allocated with 'CRYPT_DECODE_ALLOC_FLAG' + */ +static BOOL CRYPT_raw_decode_rsa_pub_key(struct DECODED_RSA_PUB_KEY **decodedKey, + DWORD *size, const BYTE *pbEncoded, DWORD cbEncoded) +{ + BOOL ret; + + struct AsnDecodeSequenceItem items[] = { + { ASN_INTEGER, offsetof(struct DECODED_RSA_PUB_KEY, modulus), + CRYPT_AsnDecodeUnsignedIntegerInternal, sizeof(CRYPT_INTEGER_BLOB), + FALSE, TRUE, offsetof(struct DECODED_RSA_PUB_KEY, modulus.pbData), + 0 }, + { ASN_INTEGER, offsetof(struct DECODED_RSA_PUB_KEY, pubexp), + CRYPT_AsnDecodeUnsignedIntegerInternal, sizeof(CRYPT_INTEGER_BLOB), + FALSE, TRUE, offsetof(struct DECODED_RSA_PUB_KEY, pubexp.pbData), + 0 }, + }; + + ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items), + pbEncoded, cbEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL, decodedKey, + size, NULL, NULL); + + if (ret && (*decodedKey)->pubexp.cbData > sizeof(DWORD)) + { + WARN("Unexpected exponent length %lu.\n", (*decodedKey)->pubexp.cbData); + LocalFree(*decodedKey); + SetLastError(CRYPT_E_ASN1_LARGE); + ret = FALSE; + } + + return ret; +} + +static BOOL WINAPI CRYPT_AsnDecodeRsaPubKey_Bcrypt(DWORD dwCertEncodingType, LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo) { @@ -3876,23 +3918,17 @@ static BOOL WINAPI CRYPT_AsnDecodeRsaPubKey(DWORD dwCertEncodingType, __TRY { - struct AsnDecodeSequenceItem items[] = { - { ASN_INTEGER, offsetof(struct DECODED_RSA_PUB_KEY, modulus), - CRYPT_AsnDecodeUnsignedIntegerInternal, sizeof(CRYPT_INTEGER_BLOB), - FALSE, TRUE, offsetof(struct DECODED_RSA_PUB_KEY, modulus.pbData), - 0 }, - { ASN_INTEGER, offsetof(struct DECODED_RSA_PUB_KEY, pubexp), - CRYPT_AsnDecodeIntInternal, sizeof(DWORD), FALSE, FALSE, 0, 0 }, - }; struct DECODED_RSA_PUB_KEY *decodedKey = NULL; DWORD size = 0; - ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items), - pbEncoded, cbEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL, &decodedKey, - &size, NULL, NULL); + TRACE("%p, %ld, %08lx, %p, %ld\n", pbEncoded, cbEncoded, dwFlags, + pvStructInfo, *pcbStructInfo); + + ret = CRYPT_raw_decode_rsa_pub_key(&decodedKey, &size, pbEncoded, cbEncoded); if (ret) { - DWORD bytesNeeded = sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) + + /* Header, exponent, and modulus */ + DWORD bytesNeeded = sizeof(BCRYPT_RSAKEY_BLOB) + decodedKey->pubexp.cbData + decodedKey->modulus.cbData; if (!pvStructInfo) @@ -3900,11 +3936,69 @@ static BOOL WINAPI CRYPT_AsnDecodeRsaPubKey(DWORD dwCertEncodingType, *pcbStructInfo = bytesNeeded; ret = TRUE; } + else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, + pvStructInfo, pcbStructInfo, bytesNeeded))) + { + BCRYPT_RSAKEY_BLOB *hdr; + + if (dwFlags & CRYPT_DECODE_ALLOC_FLAG) + pvStructInfo = *(BYTE **)pvStructInfo; + + hdr = pvStructInfo; + hdr->Magic = BCRYPT_RSAPUBLIC_MAGIC; + hdr->BitLength = decodedKey->modulus.cbData * 8; + hdr->cbPublicExp = decodedKey->pubexp.cbData; + hdr->cbModulus = decodedKey->modulus.cbData; + hdr->cbPrime1 = 0; + hdr->cbPrime2 = 0; + /* CNG_RSA_PUBLIC_KEY_BLOB always stores the exponent and modulus + * in big-endian format, so we need to convert from little-endian + */ + CRYPT_CopyReversed((BYTE *)pvStructInfo + sizeof(BCRYPT_RSAKEY_BLOB), + decodedKey->pubexp.pbData, hdr->cbPublicExp); + CRYPT_CopyReversed((BYTE *)pvStructInfo + sizeof(BCRYPT_RSAKEY_BLOB) + + hdr->cbPublicExp, decodedKey->modulus.pbData, + decodedKey->modulus.cbData); + } + LocalFree(decodedKey); + } + } + __EXCEPT_PAGE_FAULT + { + SetLastError(STATUS_ACCESS_VIOLATION); + ret = FALSE; + } + __ENDTRY + return ret; +} + + +static BOOL WINAPI CRYPT_AsnDecodeRsaPubKey(DWORD dwCertEncodingType, + LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, + PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo) +{ + BOOL ret; + + __TRY + { + struct DECODED_RSA_PUB_KEY *decodedKey = NULL; + DWORD size = 0; + ret = CRYPT_raw_decode_rsa_pub_key(&decodedKey, &size, pbEncoded, cbEncoded); + if (ret) + { + DWORD bytesNeeded = sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) + + decodedKey->modulus.cbData; + + if (!pvStructInfo) + { + *pcbStructInfo = bytesNeeded; + } else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, bytesNeeded))) { BLOBHEADER *hdr; RSAPUBKEY *rsaPubKey; + unsigned int i; if (dwFlags & CRYPT_DECODE_ALLOC_FLAG) pvStructInfo = *(BYTE **)pvStructInfo; @@ -3916,7 +4010,11 @@ static BOOL WINAPI CRYPT_AsnDecodeRsaPubKey(DWORD dwCertEncodingType, rsaPubKey = (RSAPUBKEY *)((BYTE *)pvStructInfo + sizeof(BLOBHEADER)); rsaPubKey->magic = RSA1_MAGIC; - rsaPubKey->pubexp = decodedKey->pubexp; + rsaPubKey->pubexp = 0; + assert(decodedKey->pubexp.cbData <= sizeof(rsaPubKey->pubexp)); + for (i = 0; i < decodedKey->pubexp.cbData; ++i) + rsaPubKey->pubexp |= decodedKey->pubexp.pbData[i] << (i * 8); + rsaPubKey->bitlen = decodedKey->modulus.cbData * 8; memcpy((BYTE *)pvStructInfo + sizeof(BLOBHEADER) + sizeof(RSAPUBKEY), decodedKey->modulus.pbData, @@ -4084,7 +4182,7 @@ static BOOL CRYPT_AsnDecodeOctets(const BYTE *pbEncoded, BOOL ret; DWORD bytesNeeded, dataLen; - TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags, + TRACE("%p, %ld, %08lx, %p, %ld, %p\n", pbEncoded, cbEncoded, dwFlags, pvStructInfo, *pcbStructInfo, pcbDecoded); if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen))) @@ -4224,7 +4322,7 @@ static BOOL WINAPI CRYPT_AsnDecodeOctetString(DWORD dwCertEncodingType, { BOOL ret; - TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags, + TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, *pcbStructInfo); if (!cbEncoded) @@ -4275,7 +4373,7 @@ static BOOL CRYPT_AsnDecodeBitsInternal(const BYTE *pbEncoded, DWORD cbEncoded, DWORD bytesNeeded, dataLen; BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]); - TRACE("(%p, %d, 0x%08x, %p, %d, %p)\n", pbEncoded, cbEncoded, dwFlags, + TRACE("(%p, %ld, 0x%08lx, %p, %ld, %p)\n", pbEncoded, cbEncoded, dwFlags, pvStructInfo, *pcbStructInfo, pcbDecoded); if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen))) @@ -4329,7 +4427,7 @@ static BOOL WINAPI CRYPT_AsnDecodeBits(DWORD dwCertEncodingType, { BOOL ret; - TRACE("(%p, %d, 0x%08x, %p, %p, %p)\n", pbEncoded, cbEncoded, dwFlags, + TRACE("(%p, %ld, 0x%08lx, %p, %p, %p)\n", pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, pcbStructInfo); __TRY @@ -4374,7 +4472,7 @@ static BOOL WINAPI CRYPT_AsnDecodeBits(DWORD dwCertEncodingType, ret = FALSE; } __ENDTRY - TRACE("returning %d (%08x)\n", ret, GetLastError()); + TRACE("returning %d (%08lx)\n", ret, GetLastError()); return ret; } @@ -5167,11 +5265,11 @@ static BOOL CRYPT_AsnDecodeDistPointName(const BYTE *pbEncoded, { struct AsnArrayDescriptor arrayDesc = { ASN_CONTEXT | ASN_CONSTRUCTOR | 0, - offsetof(CRL_DIST_POINT_NAME, u.FullName.cAltEntry), - offsetof(CRL_DIST_POINT_NAME, u.FullName.rgAltEntry), - FINALMEMBERSIZE(CRL_DIST_POINT_NAME, u), + offsetof(CRL_DIST_POINT_NAME, FullName.cAltEntry), + offsetof(CRL_DIST_POINT_NAME, FullName.rgAltEntry), + FINALMEMBERSIZE(CRL_DIST_POINT_NAME, FullName), CRYPT_AsnDecodeAltNameEntry, sizeof(CERT_ALT_NAME_ENTRY), TRUE, - offsetof(CERT_ALT_NAME_ENTRY, u.pwszURL) }; + offsetof(CERT_ALT_NAME_ENTRY, pwszURL) }; BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]); DWORD nameLen; @@ -5181,7 +5279,7 @@ static BOOL CRYPT_AsnDecodeDistPointName(const BYTE *pbEncoded, pbEncoded + 1 + lenBytes, cbEncoded - 1 - lenBytes, dwFlags, NULL, NULL, &nameLen, NULL); bytesNeeded = sizeof(CRL_DIST_POINT_NAME) + nameLen - - FINALMEMBERSIZE(CRL_DIST_POINT_NAME, u); + FINALMEMBERSIZE(CRL_DIST_POINT_NAME, FullName); } else bytesNeeded = sizeof(CRL_DIST_POINT_NAME); @@ -5205,7 +5303,7 @@ static BOOL CRYPT_AsnDecodeDistPointName(const BYTE *pbEncoded, name->dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME; ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded + 1 + lenBytes, cbEncoded - 1 - lenBytes, - dwFlags, NULL, &name->u.FullName.cAltEntry, &nameLen, + dwFlags, NULL, &name->FullName.cAltEntry, &nameLen, NULL); } else @@ -5228,7 +5326,7 @@ static BOOL CRYPT_AsnDecodeDistPoint(const BYTE *pbEncoded, DWORD cbEncoded, { ASN_CONTEXT | ASN_CONSTRUCTOR | 0, offsetof(CRL_DIST_POINT, DistPointName), CRYPT_AsnDecodeDistPointName, sizeof(CRL_DIST_POINT_NAME), TRUE, TRUE, offsetof(CRL_DIST_POINT, - DistPointName.u.FullName.rgAltEntry), 0 }, + DistPointName.FullName.rgAltEntry), 0 }, { ASN_CONTEXT | 1, offsetof(CRL_DIST_POINT, ReasonFlags), CRYPT_AsnDecodeBitsInternal, sizeof(CRYPT_BIT_BLOB), TRUE, TRUE, offsetof(CRL_DIST_POINT, ReasonFlags.pbData), 0 }, @@ -5241,7 +5339,7 @@ static BOOL CRYPT_AsnDecodeDistPoint(const BYTE *pbEncoded, DWORD cbEncoded, ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items), pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo, - pcbDecoded, point ? point->DistPointName.u.FullName.rgAltEntry : NULL); + pcbDecoded, point ? point->DistPointName.FullName.rgAltEntry : NULL); return ret; } @@ -5251,7 +5349,7 @@ static BOOL WINAPI CRYPT_AsnDecodeCRLDistPoints(DWORD dwCertEncodingType, { BOOL ret; - TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags, + TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, *pcbStructInfo); __TRY @@ -5261,7 +5359,7 @@ static BOOL WINAPI CRYPT_AsnDecodeCRLDistPoints(DWORD dwCertEncodingType, offsetof(CRL_DIST_POINTS_INFO, rgDistPoint), sizeof(CRL_DIST_POINTS_INFO), CRYPT_AsnDecodeDistPoint, sizeof(CRL_DIST_POINT), TRUE, - offsetof(CRL_DIST_POINT, DistPointName.u.FullName.rgAltEntry) }; + offsetof(CRL_DIST_POINT, DistPointName.FullName.rgAltEntry) }; CRL_DIST_POINTS_INFO *info = pvStructInfo; if (pvStructInfo && !(dwFlags & CRYPT_DECODE_ALLOC_FLAG)) @@ -5284,7 +5382,7 @@ static BOOL WINAPI CRYPT_AsnDecodeEnhancedKeyUsage(DWORD dwCertEncodingType, { BOOL ret; - TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags, + TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, *pcbStructInfo); __TRY @@ -5316,7 +5414,7 @@ static BOOL WINAPI CRYPT_AsnDecodeIssuingDistPoint(DWORD dwCertEncodingType, { BOOL ret; - TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags, + TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, *pcbStructInfo); __TRY @@ -5326,7 +5424,7 @@ static BOOL WINAPI CRYPT_AsnDecodeIssuingDistPoint(DWORD dwCertEncodingType, DistPointName), CRYPT_AsnDecodeDistPointName, sizeof(CRL_DIST_POINT_NAME), TRUE, TRUE, offsetof(CRL_ISSUING_DIST_POINT, - DistPointName.u.FullName.rgAltEntry), 0 }, + DistPointName.FullName.rgAltEntry), 0 }, { ASN_CONTEXT | 1, offsetof(CRL_ISSUING_DIST_POINT, fOnlyContainsUserCerts), CRYPT_AsnDecodeBool, sizeof(BOOL), TRUE, FALSE, 0 }, @@ -5361,7 +5459,7 @@ static BOOL CRYPT_AsnDecodeMaximum(const BYTE *pbEncoded, BOOL ret; DWORD max, size = sizeof(max); - TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags, + TRACE("%p, %ld, %08lx, %p, %ld, %p\n", pbEncoded, cbEncoded, dwFlags, pvStructInfo, *pcbStructInfo, pcbDecoded); if (!cbEncoded) @@ -5412,7 +5510,7 @@ static BOOL CRYPT_AsnDecodeSubtree(const BYTE *pbEncoded, struct AsnDecodeSequenceItem items[] = { { 0, offsetof(CERT_GENERAL_SUBTREE, Base), CRYPT_AsnDecodeAltNameEntry, sizeof(CERT_ALT_NAME_ENTRY), TRUE, TRUE, - offsetof(CERT_ALT_NAME_ENTRY, u.pwszURL), 0 }, + offsetof(CERT_ALT_NAME_ENTRY, pwszURL), 0 }, { ASN_CONTEXT | 0, offsetof(CERT_GENERAL_SUBTREE, dwMinimum), CRYPT_AsnDecodeIntInternal, sizeof(DWORD), TRUE, FALSE, 0, 0 }, { ASN_CONTEXT | 1, offsetof(CERT_GENERAL_SUBTREE, fMaximum), @@ -5421,15 +5519,15 @@ static BOOL CRYPT_AsnDecodeSubtree(const BYTE *pbEncoded, }; CERT_GENERAL_SUBTREE *subtree = pvStructInfo; - TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags, + TRACE("%p, %ld, %08lx, %p, %ld, %p\n", pbEncoded, cbEncoded, dwFlags, pvStructInfo, *pcbStructInfo, pcbDecoded); ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items), pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo, - pcbDecoded, subtree ? subtree->Base.u.pwszURL : NULL); + pcbDecoded, subtree ? subtree->Base.pwszURL : NULL); if (pcbDecoded) { - TRACE("%d\n", *pcbDecoded); + TRACE("%ld\n", *pcbDecoded); if (*pcbDecoded < cbEncoded) TRACE("%02x %02x\n", *(pbEncoded + *pcbDecoded), *(pbEncoded + *pcbDecoded + 1)); @@ -5449,9 +5547,9 @@ static BOOL CRYPT_AsnDecodePermittedSubtree(const BYTE *pbEncoded, MEMBERSIZE(CERT_NAME_CONSTRAINTS_INFO, cPermittedSubtree, cExcludedSubtree), CRYPT_AsnDecodeSubtree, sizeof(CERT_GENERAL_SUBTREE), TRUE, - offsetof(CERT_GENERAL_SUBTREE, Base.u.pwszURL) }; + offsetof(CERT_GENERAL_SUBTREE, Base.pwszURL) }; - TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags, + TRACE("%p, %ld, %08lx, %p, %ld, %p\n", pbEncoded, cbEncoded, dwFlags, pvStructInfo, *pcbStructInfo, pcbDecoded); ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, @@ -5469,9 +5567,9 @@ static BOOL CRYPT_AsnDecodeExcludedSubtree(const BYTE *pbEncoded, offsetof(CERT_NAME_CONSTRAINTS_INFO, rgExcludedSubtree), FINALMEMBERSIZE(CERT_NAME_CONSTRAINTS_INFO, cExcludedSubtree), CRYPT_AsnDecodeSubtree, sizeof(CERT_GENERAL_SUBTREE), TRUE, - offsetof(CERT_GENERAL_SUBTREE, Base.u.pwszURL) }; + offsetof(CERT_GENERAL_SUBTREE, Base.pwszURL) }; - TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags, + TRACE("%p, %ld, %08lx, %p, %ld, %p\n", pbEncoded, cbEncoded, dwFlags, pvStructInfo, *pcbStructInfo, pcbDecoded); ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, @@ -5485,7 +5583,7 @@ static BOOL WINAPI CRYPT_AsnDecodeNameConstraints(DWORD dwCertEncodingType, { BOOL ret = FALSE; - TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags, + TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, *pcbStructInfo); __TRY @@ -5532,7 +5630,7 @@ static BOOL CRYPT_AsnDecodeIssuerSerialNumber(const BYTE *pbEncoded, }; CERT_ISSUER_SERIAL_NUMBER *issuerSerial = pvStructInfo; - TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags, + TRACE("%p, %ld, %08lx, %p, %ld, %p\n", pbEncoded, cbEncoded, dwFlags, pvStructInfo, *pcbStructInfo, pcbDecoded); ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items), @@ -5579,7 +5677,7 @@ static BOOL CRYPT_AsnDecodePKCSSignerInfoInternal(const BYTE *pbEncoded, }; BOOL ret; - TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, + TRACE("%p, %ld, %08lx, %p, %ld\n", pbEncoded, cbEncoded, dwFlags, pvStructInfo, *pcbStructInfo); ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items), @@ -5594,7 +5692,7 @@ static BOOL WINAPI CRYPT_AsnDecodePKCSSignerInfo(DWORD dwCertEncodingType, { BOOL ret = FALSE; - TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags, + TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, *pcbStructInfo); __TRY @@ -5631,6 +5729,25 @@ static BOOL WINAPI CRYPT_AsnDecodePKCSSignerInfo(DWORD dwCertEncodingType, return ret; } +static BOOL verify_and_copy_certificate(const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, + void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded) +{ + PCCERT_CONTEXT cert; + + cert = CertCreateCertificateContext(X509_ASN_ENCODING, pbEncoded, cbEncoded); + if (!cert) + { + WARN("CertCreateCertificateContext error %#lx\n", GetLastError()); + *pcbStructInfo = 0; + *pcbDecoded = 0; + return TRUE; + } + + CertFreeCertificateContext(cert); + + return CRYPT_AsnDecodeCopyBytes(pbEncoded, cbEncoded, dwFlags, pvStructInfo, pcbStructInfo, pcbDecoded); +} + static BOOL CRYPT_AsnDecodeCMSCertEncoded(const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded) @@ -5640,10 +5757,10 @@ static BOOL CRYPT_AsnDecodeCMSCertEncoded(const BYTE *pbEncoded, offsetof(CRYPT_SIGNED_INFO, cCertEncoded), offsetof(CRYPT_SIGNED_INFO, rgCertEncoded), MEMBERSIZE(CRYPT_SIGNED_INFO, cCertEncoded, cCrlEncoded), - CRYPT_AsnDecodeCopyBytes, + verify_and_copy_certificate, sizeof(CRYPT_DER_BLOB), TRUE, offsetof(CRYPT_DER_BLOB, pbData) }; - TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags, + TRACE("%p, %ld, %08lx, %p, %ld, %p\n", pbEncoded, cbEncoded, dwFlags, pvStructInfo, pvStructInfo ? *pcbStructInfo : 0, pcbDecoded); ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, @@ -5663,7 +5780,7 @@ static BOOL CRYPT_AsnDecodeCMSCrlEncoded(const BYTE *pbEncoded, CRYPT_AsnDecodeCopyBytes, sizeof(CRYPT_DER_BLOB), TRUE, offsetof(CRYPT_DER_BLOB, pbData) }; - TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags, + TRACE("%p, %ld, %08lx, %p, %ld, %p\n", pbEncoded, cbEncoded, dwFlags, pvStructInfo, pvStructInfo ? *pcbStructInfo : 0, pcbDecoded); ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, @@ -5681,7 +5798,7 @@ static BOOL CRYPT_AsnDecodeCMSSignerId(const BYTE *pbEncoded, if (*pbEncoded == ASN_SEQUENCEOF) { ret = CRYPT_AsnDecodeIssuerSerialNumber(pbEncoded, cbEncoded, dwFlags, - id ? &id->u.IssuerSerialNumber : NULL, pcbStructInfo, pcbDecoded); + id ? &id->IssuerSerialNumber : NULL, pcbStructInfo, pcbDecoded); if (ret) { if (id) @@ -5696,7 +5813,7 @@ static BOOL CRYPT_AsnDecodeCMSSignerId(const BYTE *pbEncoded, else if (*pbEncoded == (ASN_CONTEXT | 0)) { ret = CRYPT_AsnDecodeOctets(pbEncoded, cbEncoded, dwFlags, - id ? &id->u.KeyId : NULL, pcbStructInfo, pcbDecoded); + id ? &id->KeyId : NULL, pcbStructInfo, pcbDecoded); if (ret) { if (id) @@ -5723,7 +5840,7 @@ static BOOL CRYPT_AsnDecodeCMSSignerInfoInternal(const BYTE *pbEncoded, CRYPT_AsnDecodeIntInternal, sizeof(DWORD), FALSE, FALSE, 0, 0 }, { 0, offsetof(CMSG_CMS_SIGNER_INFO, SignerId), CRYPT_AsnDecodeCMSSignerId, sizeof(CERT_ID), FALSE, TRUE, - offsetof(CMSG_CMS_SIGNER_INFO, SignerId.u.KeyId.pbData), 0 }, + offsetof(CMSG_CMS_SIGNER_INFO, SignerId.KeyId.pbData), 0 }, { ASN_SEQUENCEOF, offsetof(CMSG_CMS_SIGNER_INFO, HashAlgorithm), CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER), FALSE, TRUE, offsetof(CMSG_CMS_SIGNER_INFO, HashAlgorithm.pszObjId), 0 }, @@ -5731,9 +5848,6 @@ static BOOL CRYPT_AsnDecodeCMSSignerInfoInternal(const BYTE *pbEncoded, offsetof(CMSG_CMS_SIGNER_INFO, AuthAttrs), CRYPT_AsnDecodePKCSAttributesInternal, sizeof(CRYPT_ATTRIBUTES), TRUE, TRUE, offsetof(CMSG_CMS_SIGNER_INFO, AuthAttrs.rgAttr), 0 }, - /* FIXME: Tests show that CertOpenStore accepts such certificates, but - * how exactly should they be interpreted? */ - { ASN_CONSTRUCTOR | ASN_UNIVERSAL | 0x11, 0, NULL, 0, TRUE, FALSE, 0, 0 }, { ASN_SEQUENCEOF, offsetof(CMSG_CMS_SIGNER_INFO, HashEncryptionAlgorithm), CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER), FALSE, TRUE, offsetof(CMSG_CMS_SIGNER_INFO, @@ -5748,12 +5862,12 @@ static BOOL CRYPT_AsnDecodeCMSSignerInfoInternal(const BYTE *pbEncoded, }; BOOL ret; - TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, + TRACE("%p, %ld, %08lx, %p, %ld\n", pbEncoded, cbEncoded, dwFlags, pvStructInfo, *pcbStructInfo); ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items), pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo, - pcbDecoded, info ? info->SignerId.u.KeyId.pbData : NULL); + pcbDecoded, info ? info->SignerId.KeyId.pbData : NULL); return ret; } @@ -5763,7 +5877,7 @@ static BOOL WINAPI CRYPT_AsnDecodeCMSSignerInfo(DWORD dwCertEncodingType, { BOOL ret = FALSE; - TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags, + TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, *pcbStructInfo); __TRY @@ -5781,7 +5895,7 @@ static BOOL WINAPI CRYPT_AsnDecodeCMSSignerInfo(DWORD dwCertEncodingType, if (dwFlags & CRYPT_DECODE_ALLOC_FLAG) pvStructInfo = *(BYTE **)pvStructInfo; info = pvStructInfo; - info->SignerId.u.KeyId.pbData = ((BYTE *)info + + info->SignerId.KeyId.pbData = ((BYTE *)info + sizeof(CMSG_CMS_SIGNER_INFO)); ret = CRYPT_AsnDecodeCMSSignerInfoInternal(pbEncoded, cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo, @@ -5809,9 +5923,9 @@ static BOOL CRYPT_DecodeSignerArray(const BYTE *pbEncoded, DWORD cbEncoded, offsetof(CRYPT_SIGNED_INFO, rgSignerInfo), FINALMEMBERSIZE(CRYPT_SIGNED_INFO, cSignerInfo), CRYPT_AsnDecodeCMSSignerInfoInternal, sizeof(CMSG_CMS_SIGNER_INFO), TRUE, - offsetof(CMSG_CMS_SIGNER_INFO, SignerId.u.KeyId.pbData) }; + offsetof(CMSG_CMS_SIGNER_INFO, SignerId.KeyId.pbData) }; - TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags, + TRACE("%p, %ld, %08lx, %p, %ld, %p\n", pbEncoded, cbEncoded, dwFlags, pvStructInfo, *pcbStructInfo, pcbDecoded); ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, @@ -5848,7 +5962,7 @@ BOOL CRYPT_AsnDecodeCMSSignedInfo(const BYTE *pbEncoded, DWORD cbEncoded, offsetof(CRYPT_SIGNED_INFO, rgSignerInfo), 0 }, }; - TRACE("%p, %d, %08x, %p, %p, %p\n", pbEncoded, cbEncoded, dwFlags, + TRACE("%p, %ld, %08lx, %p, %p, %p\n", pbEncoded, cbEncoded, dwFlags, pDecodePara, signedInfo, pcbSignedInfo); ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items), @@ -5867,10 +5981,10 @@ static BOOL CRYPT_AsnDecodeRecipientInfo(const BYTE *pbEncoded, DWORD cbEncoded, { ASN_INTEGER, offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO, dwVersion), CRYPT_AsnDecodeIntInternal, sizeof(DWORD), FALSE, FALSE, 0, 0 }, { ASN_SEQUENCEOF, offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO, - RecipientId.u.IssuerSerialNumber), CRYPT_AsnDecodeIssuerSerialNumber, + RecipientId.IssuerSerialNumber), CRYPT_AsnDecodeIssuerSerialNumber, sizeof(CERT_ISSUER_SERIAL_NUMBER), FALSE, TRUE, offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO, - RecipientId.u.IssuerSerialNumber.Issuer.pbData), 0 }, + RecipientId.IssuerSerialNumber.Issuer.pbData), 0 }, { ASN_SEQUENCEOF, offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO, KeyEncryptionAlgorithm), CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER), FALSE, TRUE, @@ -5881,12 +5995,12 @@ static BOOL CRYPT_AsnDecodeRecipientInfo(const BYTE *pbEncoded, DWORD cbEncoded, offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO, EncryptedKey.pbData), 0 }, }; - TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags, + TRACE("%p, %ld, %08lx, %p, %ld, %p\n", pbEncoded, cbEncoded, dwFlags, pvStructInfo, *pcbStructInfo, pcbDecoded); ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items), pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo, - pcbDecoded, info ? info->RecipientId.u.IssuerSerialNumber.Issuer.pbData : + pcbDecoded, info ? info->RecipientId.IssuerSerialNumber.Issuer.pbData : NULL); if (info) info->RecipientId.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER; @@ -5905,9 +6019,9 @@ static BOOL CRYPT_DecodeRecipientInfoArray(const BYTE *pbEncoded, MEMBERSIZE(CRYPT_ENVELOPED_DATA, cRecipientInfo, encryptedContentInfo), CRYPT_AsnDecodeRecipientInfo, sizeof(CMSG_KEY_TRANS_RECIPIENT_INFO), TRUE, offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO, - RecipientId.u.IssuerSerialNumber.Issuer.pbData) }; + RecipientId.IssuerSerialNumber.Issuer.pbData) }; - TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags, + TRACE("%p, %ld, %08lx, %p, %ld, %p\n", pbEncoded, cbEncoded, dwFlags, pvStructInfo, *pcbStructInfo, pcbDecoded); ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, @@ -5938,7 +6052,7 @@ static BOOL CRYPT_AsnDecodeEncryptedContentInfo(const BYTE *pbEncoded, offsetof(CRYPT_ENCRYPTED_CONTENT_INFO, encryptedContent.pbData) }, }; - TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags, + TRACE("%p, %ld, %08lx, %p, %ld, %p\n", pbEncoded, cbEncoded, dwFlags, pvStructInfo, *pcbStructInfo, pcbDecoded); ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items), @@ -5966,7 +6080,7 @@ BOOL CRYPT_AsnDecodePKCSEnvelopedData(const BYTE *pbEncoded, DWORD cbEncoded, offsetof(CRYPT_ENVELOPED_DATA, encryptedContentInfo.contentType), 0 }, }; - TRACE("%p, %d, %08x, %p, %p, %p\n", pbEncoded, cbEncoded, dwFlags, + TRACE("%p, %ld, %08lx, %p, %p, %p\n", pbEncoded, cbEncoded, dwFlags, pDecodePara, envelopedData, pcbEnvelopedData); ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items), @@ -6045,6 +6159,590 @@ static BOOL WINAPI CRYPT_AsnDecodeEccSignature(DWORD dwCertEncodingType, return ret; } +static BOOL CRYPT_AsnDecodeOCSPResponseStatus(const BYTE *pbEncoded, + DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, + DWORD *pcbDecoded) +{ + if (!cbEncoded) + { + SetLastError(CRYPT_E_ASN1_EOD); + return FALSE; + } + if (pbEncoded[0] != ASN_ENUMERATED) + { + SetLastError(CRYPT_E_ASN1_BADTAG); + return FALSE; + } + + return CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded, dwFlags, pvStructInfo, + pcbStructInfo, pcbDecoded); +} + +static BOOL CRYPT_AsnDecodeOCSPResponseBytes(const BYTE *pbEncoded, + DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, + DWORD *pcbDecoded) +{ + DWORD dataLen; + BOOL ret; + + if (!cbEncoded) + { + SetLastError(CRYPT_E_ASN1_EOD); + return FALSE; + } + if (pbEncoded[0] != (ASN_CONTEXT | ASN_CONSTRUCTOR)) + { + SetLastError(CRYPT_E_ASN1_BADTAG); + return FALSE; + } + + if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen))) + { + struct AsnDecodeSequenceItem items[] = { + { ASN_OBJECTIDENTIFIER, 0, + CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE, + 0, 0 }, + { ASN_OCTETSTRING, sizeof(LPSTR), + CRYPT_AsnDecodeOctets, sizeof(CRYPT_OBJID_BLOB), FALSE, TRUE, + sizeof(LPSTR) + offsetof(CRYPT_OBJID_BLOB, pbData), 0 }, + }; + BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]); + DWORD bytesNeeded; + + if (dataLen) + { + ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items), + pbEncoded + 1 + lenBytes, cbEncoded - 1 - lenBytes, dwFlags, NULL, + pvStructInfo, pcbStructInfo, &bytesNeeded, NULL); + if (ret) *pcbDecoded = bytesNeeded + lenBytes + 1; + } + } + return ret; +} + +static BOOL WINAPI CRYPT_AsnDecodeOCSPResponse(DWORD dwCertEncodingType, + LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, + CRYPT_DECODE_PARA *pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo) +{ + BOOL ret; + struct AsnDecodeSequenceItem items[] = { + { ASN_ENUMERATED, offsetof(OCSP_RESPONSE_INFO, dwStatus), + CRYPT_AsnDecodeOCSPResponseStatus, sizeof(DWORD), FALSE, FALSE, + 0, 0 }, + { ASN_CONTEXT | ASN_CONSTRUCTOR, offsetof(OCSP_RESPONSE_INFO, pszObjId), + CRYPT_AsnDecodeOCSPResponseBytes, sizeof(LPSTR) + sizeof(CRYPT_OBJID_BLOB), TRUE, TRUE, + offsetof(OCSP_RESPONSE_INFO, pszObjId), 0 }, + }; + + __TRY + { + ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items), + pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, + pcbStructInfo, NULL, NULL); + } + __EXCEPT_PAGE_FAULT + { + SetLastError(STATUS_ACCESS_VIOLATION); + ret = FALSE; + } + __ENDTRY + return ret; +} + +static BOOL CRYPT_AsnDecodeOCSPSignatureInfoCertEncoded(const BYTE *pbEncoded, + DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, + DWORD *pcbDecoded) +{ + BOOL ret; + DWORD data_len, len_bytes; + struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCE, + offsetof(OCSP_SIGNATURE_INFO, cCertEncoded), offsetof(OCSP_SIGNATURE_INFO, rgCertEncoded), + FINALMEMBERSIZE(OCSP_SIGNATURE_INFO, cCertEncoded), verify_and_copy_certificate, + sizeof(CRYPT_DER_BLOB), TRUE, offsetof(CRYPT_DER_BLOB, pbData) }; + + if (pbEncoded[0] != (ASN_CONTEXT | ASN_CONSTRUCTOR)) + { + WARN("Unexpected tag %#x.\n", pbEncoded[0]); + SetLastError(CRYPT_E_ASN1_BADTAG); + return FALSE; + } + + if (!(ret = CRYPT_GetLen(pbEncoded, cbEncoded, &data_len))) return FALSE; + len_bytes = GET_LEN_BYTES(pbEncoded[1]); + + ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded + 1 + len_bytes, cbEncoded - 1 - len_bytes, + dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded); + if (pcbDecoded) + *pcbDecoded = 1 + len_bytes + data_len; + return ret; +} + +static BOOL WINAPI CRYPT_AsnDecodeOCSPBasicSignedResponse(DWORD dwCertEncodingType, + LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, + CRYPT_DECODE_PARA *pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo) +{ + BOOL ret; + struct AsnDecodeSequenceItem items[] = { + { 0, offsetof(OCSP_BASIC_SIGNED_RESPONSE_INFO, ToBeSigned), + CRYPT_AsnDecodeDerBlob, sizeof(CRYPT_DER_BLOB), FALSE, TRUE, + offsetof(OCSP_BASIC_SIGNED_RESPONSE_INFO, ToBeSigned.pbData), 0 }, + { ASN_SEQUENCEOF, offsetof(OCSP_BASIC_SIGNED_RESPONSE_INFO, SignatureInfo.SignatureAlgorithm), + CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER), FALSE, TRUE, + offsetof(OCSP_BASIC_SIGNED_RESPONSE_INFO, SignatureInfo.SignatureAlgorithm.pszObjId), 0 }, + { ASN_BITSTRING, offsetof(OCSP_BASIC_SIGNED_RESPONSE_INFO, SignatureInfo.Signature), + CRYPT_AsnDecodeBitsInternal, sizeof(CRYPT_BIT_BLOB), FALSE, TRUE, + offsetof(OCSP_BASIC_SIGNED_RESPONSE_INFO, SignatureInfo.Signature.pbData) }, + { 0, offsetof(OCSP_BASIC_SIGNED_RESPONSE_INFO, SignatureInfo.cCertEncoded), + CRYPT_AsnDecodeOCSPSignatureInfoCertEncoded, FINALMEMBERSIZE(OCSP_SIGNATURE_INFO, cCertEncoded), + TRUE, TRUE, offsetof(OCSP_BASIC_SIGNED_RESPONSE_INFO, SignatureInfo.rgCertEncoded) }, + }; + + __TRY + { + ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items), + pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, + pcbStructInfo, NULL, NULL); + } + __EXCEPT_PAGE_FAULT + { + SetLastError(STATUS_ACCESS_VIOLATION); + ret = FALSE; + } + __ENDTRY + return ret; +} + +static BOOL CRYPT_AsnDecodeOCSPHashAlgorithm(const BYTE *pbEncoded, + DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, + DWORD *pcbDecoded) +{ + DWORD dataLen; + BOOL ret; + + if (!cbEncoded) + { + SetLastError(CRYPT_E_ASN1_EOD); + return FALSE; + } + if (pbEncoded[0] != ASN_SEQUENCEOF) + { + SetLastError(CRYPT_E_ASN1_BADTAG); + return FALSE; + } + + if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen))) + { + BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]); + DWORD bytesDecoded; + if (dataLen) + { + ret = CRYPT_AsnDecodeAlgorithmId(pbEncoded + 1 + lenBytes, cbEncoded - 1 - lenBytes, dwFlags, + pvStructInfo, pcbStructInfo, &bytesDecoded); + if (ret) *pcbDecoded = bytesDecoded + lenBytes + 1; + } + } + return ret; +} + +static BOOL CRYPT_AsnDecodeOCSPNextUpdate(const BYTE *pbEncoded, + DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, + DWORD *pcbDecoded) +{ + DWORD dataLen; + BOOL ret; + + if (!cbEncoded) + { + SetLastError(CRYPT_E_ASN1_EOD); + return FALSE; + } + if (pbEncoded[0] != (ASN_CONTEXT | ASN_CONSTRUCTOR)) + { + SetLastError(CRYPT_E_ASN1_BADTAG); + return FALSE; + } + + if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen))) + { + BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]); + DWORD bytesDecoded; + if (dataLen) + { + ret = CRYPT_AsnDecodeGeneralizedTime(pbEncoded + 1 + lenBytes, cbEncoded - 1 - lenBytes, dwFlags, + pvStructInfo, pcbStructInfo, &bytesDecoded); + if (ret) *pcbDecoded = bytesDecoded + lenBytes + 1; + } + } + return ret; +} + +static BOOL CRYPT_AsnDecodeCertStatus(const BYTE *pbEncoded, + DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, + DWORD *pcbDecoded) +{ + BOOL ret = TRUE; + BYTE tag = pbEncoded[0] & ~3, status = pbEncoded[0] & 3; + DWORD bytesNeeded = FIELD_OFFSET(OCSP_BASIC_RESPONSE_ENTRY, ThisUpdate) - + FIELD_OFFSET(OCSP_BASIC_RESPONSE_ENTRY, dwCertStatus); + + if (!cbEncoded) + { + SetLastError(CRYPT_E_ASN1_EOD); + return FALSE; + } + + switch (status) + { + case 0: + if (tag != ASN_CONTEXT) + { + WARN("Unexpected tag %02x\n", tag); + SetLastError(CRYPT_E_ASN1_BADTAG); + return FALSE; + } + if (cbEncoded < 2 || pbEncoded[1]) + { + SetLastError(CRYPT_E_ASN1_CORRUPT); + return FALSE; + } + if (!pvStructInfo) + *pcbStructInfo = bytesNeeded; + else if (*pcbStructInfo < bytesNeeded) + { + *pcbStructInfo = bytesNeeded; + SetLastError(ERROR_MORE_DATA); + return FALSE; + } + if (pvStructInfo) + { + *(DWORD *)pvStructInfo = 0; + *(OCSP_BASIC_REVOKED_INFO **)((char *)pvStructInfo + + FIELD_OFFSET(OCSP_BASIC_RESPONSE_ENTRY, pRevokedInfo) + - FIELD_OFFSET(OCSP_BASIC_RESPONSE_ENTRY, dwCertStatus)) = NULL; + } + *pcbStructInfo = bytesNeeded; + *pcbDecoded = 2; + break; + + case 1: + { + DWORD dataLen; + + if (tag != (ASN_CONTEXT | ASN_CONSTRUCTOR)) + { + WARN("Unexpected tag %02x\n", tag); + SetLastError(CRYPT_E_ASN1_BADTAG); + return FALSE; + } + if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen))) + { + BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]); + DWORD bytesDecoded, size; + FILETIME date; + + if (dataLen) + { + size = sizeof(date); + ret = CRYPT_AsnDecodeGeneralizedTime(pbEncoded + 1 + lenBytes, cbEncoded - 1 - lenBytes, + dwFlags, &date, &size, &bytesDecoded); + if (ret) + { + OCSP_BASIC_REVOKED_INFO *info; + + bytesNeeded += sizeof(*info); + if (!pvStructInfo) + *pcbStructInfo = bytesNeeded; + else if (*pcbStructInfo < bytesNeeded) + { + *pcbStructInfo = bytesNeeded; + SetLastError(ERROR_MORE_DATA); + return FALSE; + } + if (pvStructInfo) + { + *(DWORD *)pvStructInfo = 1; + info = *(OCSP_BASIC_REVOKED_INFO **)((char *)pvStructInfo + + FIELD_OFFSET(OCSP_BASIC_RESPONSE_ENTRY, pRevokedInfo) + - FIELD_OFFSET(OCSP_BASIC_RESPONSE_ENTRY, dwCertStatus)); + info->RevocationDate = date; + } + *pcbStructInfo = bytesNeeded; + *pcbDecoded = 1 + lenBytes + bytesDecoded; + } + } + } + break; + } + default: + FIXME("Unhandled status %u\n", status); + SetLastError(CRYPT_E_ASN1_BADTAG); + return FALSE; + } + + return ret; +} + +static BOOL CRYPT_AsnDecodeOCSPBasicResponseEntry(const BYTE *pbEncoded, DWORD cbEncoded, + DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded) +{ + struct AsnDecodeSequenceItem items[] = { + { ASN_SEQUENCEOF, offsetof(OCSP_BASIC_RESPONSE_ENTRY, CertId.HashAlgorithm.pszObjId), + CRYPT_AsnDecodeOCSPHashAlgorithm, sizeof(CRYPT_ALGORITHM_IDENTIFIER), FALSE, TRUE, + offsetof(OCSP_BASIC_RESPONSE_ENTRY, CertId.HashAlgorithm.pszObjId), 0 }, + { ASN_OCTETSTRING, offsetof(OCSP_BASIC_RESPONSE_ENTRY, CertId.IssuerNameHash), + CRYPT_AsnDecodeOctets, sizeof(CRYPT_HASH_BLOB), FALSE, TRUE, + offsetof(OCSP_BASIC_RESPONSE_ENTRY, CertId.IssuerNameHash.pbData), 0 }, + { ASN_OCTETSTRING, offsetof(OCSP_BASIC_RESPONSE_ENTRY, CertId.IssuerKeyHash), + CRYPT_AsnDecodeOctets, sizeof(CRYPT_HASH_BLOB), FALSE, TRUE, + offsetof(OCSP_BASIC_RESPONSE_ENTRY, CertId.IssuerKeyHash.pbData), 0 }, + { ASN_INTEGER, offsetof(OCSP_BASIC_RESPONSE_ENTRY, CertId.SerialNumber), + CRYPT_AsnDecodeIntegerInternal, sizeof(CRYPT_INTEGER_BLOB), FALSE, TRUE, + offsetof(OCSP_BASIC_RESPONSE_ENTRY, CertId.SerialNumber.pbData), 0 }, + { 0, offsetof(OCSP_BASIC_RESPONSE_ENTRY, dwCertStatus), + CRYPT_AsnDecodeCertStatus, sizeof(DWORD), FALSE, TRUE, + offsetof(OCSP_BASIC_RESPONSE_ENTRY, pRevokedInfo), 0 }, + { ASN_GENERALTIME, offsetof(OCSP_BASIC_RESPONSE_ENTRY, ThisUpdate), + CRYPT_AsnDecodeGeneralizedTime, sizeof(FILETIME), FALSE, FALSE, + 0, 0 }, + { ASN_CONTEXT | ASN_CONSTRUCTOR, offsetof(OCSP_BASIC_RESPONSE_ENTRY, NextUpdate), + CRYPT_AsnDecodeOCSPNextUpdate, sizeof(FILETIME), TRUE, FALSE, + 0, 0 }, + { ASN_CONTEXT | ASN_CONSTRUCTOR /* FIXME */, offsetof(OCSP_BASIC_RESPONSE_ENTRY, cExtension), + CRYPT_AsnDecodeCertExtensions, FINALMEMBERSIZE(OCSP_BASIC_RESPONSE_ENTRY, cExtension), + TRUE, TRUE, offsetof(OCSP_BASIC_RESPONSE_ENTRY, rgExtension), 0 }, + }; + + return CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items), + pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, + pcbStructInfo, pcbDecoded, NULL); +} + +static BOOL CRYPT_AsnDecodeOCSPBasicResponseEntriesArray(const BYTE *pbEncoded, + DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, + DWORD *pcbDecoded) +{ + struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF, + offsetof(OCSP_BASIC_RESPONSE_INFO, cResponseEntry), offsetof(OCSP_BASIC_RESPONSE_INFO, rgResponseEntry), + MEMBERSIZE(OCSP_BASIC_RESPONSE_INFO, cResponseEntry, cExtension), + CRYPT_AsnDecodeOCSPBasicResponseEntry, sizeof(OCSP_BASIC_RESPONSE_ENTRY), + FALSE, 0 }; + + return CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, + dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded); +} + +static BOOL CRYPT_AsnDecodeResponderIDByName(const BYTE *pbEncoded, + DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, + DWORD *pcbDecoded) +{ + OCSP_BASIC_RESPONSE_INFO *info = pvStructInfo; + DWORD dataLen, decodedLen, lenBytes, bytesNeeded = sizeof(*info); + BYTE tag = pbEncoded[0] & ~3; + CERT_NAME_BLOB *blob; + + if (tag != (ASN_CONTEXT | ASN_CONSTRUCTOR)) + { + WARN("Unexpected tag %02x\n", tag); + SetLastError(CRYPT_E_ASN1_BADTAG); + return FALSE; + } + + if (!CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)) + return FALSE; + lenBytes = GET_LEN_BYTES(pbEncoded[1]); + cbEncoded -= 1 + lenBytes; + + if (dataLen > cbEncoded) + { + SetLastError(CRYPT_E_ASN1_EOD); + return FALSE; + } + pbEncoded += 1 + lenBytes; + decodedLen = 1 + lenBytes + dataLen; + + if (pbEncoded[0] != ASN_SEQUENCE) + { + WARN("Unexpected tag %02x %02x\n", pbEncoded[0], pbEncoded[1]); + SetLastError(CRYPT_E_ASN1_BADTAG); + return FALSE; + } + + if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG)) bytesNeeded += dataLen; + if (pvStructInfo && *pcbStructInfo >= bytesNeeded) + { + info->dwResponderIdChoice = 1; + + blob = &info->ByNameResponderId; + blob->cbData = dataLen; + if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG) + blob->pbData = (BYTE *)pbEncoded; + else if (blob->cbData) + { + blob->pbData = (BYTE *)(info + 1); + memcpy(blob->pbData, pbEncoded, blob->cbData); + } + } + + if (pcbDecoded) + *pcbDecoded = decodedLen; + + if (!pvStructInfo) + { + *pcbStructInfo = bytesNeeded; + return TRUE; + } + + if (*pcbStructInfo < bytesNeeded) + { + SetLastError(ERROR_MORE_DATA); + *pcbStructInfo = bytesNeeded; + return FALSE; + } + + *pcbStructInfo = bytesNeeded; + return TRUE; +} + +static BOOL CRYPT_AsnDecodeResponderIDByKey(const BYTE *pbEncoded, + DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, + DWORD *pcbDecoded) +{ + OCSP_BASIC_RESPONSE_INFO *info = pvStructInfo; + DWORD dataLen, decodedLen, lenBytes, bytesNeeded = sizeof(*info), len; + BYTE tag = pbEncoded[0] & ~3; + CRYPT_HASH_BLOB *blob; + + if (tag != (ASN_CONTEXT | ASN_CONSTRUCTOR)) + { + WARN("Unexpected tag %02x\n", tag); + SetLastError(CRYPT_E_ASN1_BADTAG); + return FALSE; + } + + if (!CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)) + return FALSE; + lenBytes = GET_LEN_BYTES(pbEncoded[1]); + cbEncoded -= 1 + lenBytes; + decodedLen = 1 + lenBytes; + + if (dataLen > cbEncoded) + { + SetLastError(CRYPT_E_ASN1_EOD); + return FALSE; + } + pbEncoded += 1 + lenBytes; + if (pbEncoded[0] != ASN_OCTETSTRING) + { + WARN("Unexpected tag %02x\n", pbEncoded[0]); + SetLastError(CRYPT_E_ASN1_BADTAG); + return FALSE; + } + + if (!CRYPT_GetLen(pbEncoded, cbEncoded, &len)) + return FALSE; + lenBytes = GET_LEN_BYTES(pbEncoded[1]); + decodedLen += 1 + lenBytes + len; + cbEncoded -= 1 + lenBytes; + + if (len > cbEncoded) + { + SetLastError(CRYPT_E_ASN1_EOD); + return FALSE; + } + pbEncoded += 1 + lenBytes; + + if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG)) bytesNeeded += len; + if (pvStructInfo && *pcbStructInfo >= bytesNeeded) + { + info->dwResponderIdChoice = 2; + blob = &info->ByKeyResponderId; + blob->cbData = len; + if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG) + blob->pbData = (BYTE *)pbEncoded; + else if (blob->cbData) + { + blob->pbData = (BYTE *)(info + 1); + memcpy(blob->pbData, pbEncoded, blob->cbData); + } + } + + if (pcbDecoded) + *pcbDecoded = decodedLen; + + if (!pvStructInfo) + { + *pcbStructInfo = bytesNeeded; + return TRUE; + } + + if (*pcbStructInfo < bytesNeeded) + { + SetLastError(ERROR_MORE_DATA); + *pcbStructInfo = bytesNeeded; + return FALSE; + } + + *pcbStructInfo = bytesNeeded; + return TRUE; +} + +static BOOL CRYPT_AsnDecodeResponderID(const BYTE *pbEncoded, + DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, + DWORD *pcbDecoded) +{ + BYTE choice = pbEncoded[0] & 3; + + TRACE("choice %02x\n", choice); + switch (choice) + { + case 1: + return CRYPT_AsnDecodeResponderIDByName(pbEncoded, cbEncoded, dwFlags, + pvStructInfo, pcbStructInfo, pcbDecoded); + case 2: + return CRYPT_AsnDecodeResponderIDByKey(pbEncoded, cbEncoded, dwFlags, + pvStructInfo, pcbStructInfo, pcbDecoded); + default: + WARN("Unexpected choice %02x\n", choice); + SetLastError(CRYPT_E_ASN1_CORRUPT); + return FALSE; + } +} + +static BOOL WINAPI CRYPT_AsnDecodeOCSPBasicResponse(DWORD dwCertEncodingType, + LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, + CRYPT_DECODE_PARA *pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo) +{ + struct AsnDecodeSequenceItem items[] = { + { 0, 0, + CRYPT_AsnDecodeResponderID, offsetof(OCSP_BASIC_RESPONSE_INFO, ProducedAt), FALSE, TRUE, + offsetof(OCSP_BASIC_RESPONSE_INFO, ByNameResponderId.pbData), 0 }, + { ASN_GENERALTIME, offsetof(OCSP_BASIC_RESPONSE_INFO, ProducedAt), + CRYPT_AsnDecodeGeneralizedTime, sizeof(FILETIME), FALSE, FALSE, + 0, 0 }, + { ASN_SEQUENCEOF, offsetof(OCSP_BASIC_RESPONSE_INFO, cResponseEntry), + CRYPT_AsnDecodeOCSPBasicResponseEntriesArray, MEMBERSIZE(OCSP_BASIC_RESPONSE_INFO, cResponseEntry, cExtension), + TRUE, TRUE, offsetof(OCSP_BASIC_RESPONSE_INFO, rgResponseEntry) }, + { ASN_CONTEXT | ASN_CONSTRUCTOR, offsetof(OCSP_BASIC_RESPONSE_INFO, cExtension), + CRYPT_AsnDecodeCertExtensions, FINALMEMBERSIZE(OCSP_BASIC_RESPONSE_INFO, cExtension), + TRUE, TRUE, offsetof(OCSP_BASIC_RESPONSE_INFO, rgExtension), 0 }, + }; + BOOL ret; + + __TRY + { + ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items), + pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, + pcbStructInfo, NULL, NULL); + } + __EXCEPT_PAGE_FAULT + { + SetLastError(STATUS_ACCESS_VIOLATION); + ret = FALSE; + } + __ENDTRY + return ret; +} + static CryptDecodeObjectExFunc CRYPT_GetBuiltinDecoder(DWORD dwCertEncodingType, LPCSTR lpszStructType) { @@ -6190,6 +6888,20 @@ static CryptDecodeObjectExFunc CRYPT_GetBuiltinDecoder(DWORD dwCertEncodingType, case LOWORD(X509_ECC_SIGNATURE): decodeFunc = CRYPT_AsnDecodeEccSignature; break; + case LOWORD(CNG_RSA_PUBLIC_KEY_BLOB): + decodeFunc = CRYPT_AsnDecodeRsaPubKey_Bcrypt; + break; + case LOWORD(OCSP_RESPONSE): + decodeFunc = CRYPT_AsnDecodeOCSPResponse; + break; + case LOWORD(OCSP_BASIC_SIGNED_RESPONSE): + decodeFunc = CRYPT_AsnDecodeOCSPBasicSignedResponse; + break; + case LOWORD(OCSP_BASIC_RESPONSE): + decodeFunc = CRYPT_AsnDecodeOCSPBasicResponse; + break; + default: + break; } } else if (!strcmp(lpszStructType, szOID_CERT_EXTENSIONS)) @@ -6291,7 +7003,7 @@ BOOL WINAPI CryptDecodeObjectEx(DWORD dwCertEncodingType, LPCSTR lpszStructType, CryptDecodeObjectExFunc decodeFunc; HCRYPTOIDFUNCADDR hFunc = NULL; - TRACE_(crypt)("(0x%08x, %s, %p, %d, 0x%08x, %p, %p, %p)\n", + TRACE_(crypt)("(0x%08lx, %s, %p, %ld, 0x%08lx, %p, %p, %p)\n", dwCertEncodingType, debugstr_a(lpszStructType), pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, pcbStructInfo); @@ -6302,6 +7014,7 @@ BOOL WINAPI CryptDecodeObjectEx(DWORD dwCertEncodingType, LPCSTR lpszStructType, } if (cbEncoded > MAX_ENCODED_LEN) { + FIXME_(crypt)("Returning CRYPT_E_ASN1_LARGE, cbEncoded %lu.\n", cbEncoded); SetLastError(CRYPT_E_ASN1_LARGE); return FALSE; } @@ -6323,6 +7036,13 @@ BOOL WINAPI CryptDecodeObjectEx(DWORD dwCertEncodingType, LPCSTR lpszStructType, debugstr_a(lpszStructType)); decodeFunc = CRYPT_LoadDecoderExFunc(dwCertEncodingType, lpszStructType, &hFunc); + if (!decodeFunc) + { + if (IS_INTOID(lpszStructType)) + FIXME("Unimplemented decoder for lpszStructType OID %d\n", LOWORD(lpszStructType)); + else + FIXME("Unsupported decoder for lpszStructType %s\n", lpszStructType); + } } if (decodeFunc) ret = decodeFunc(dwCertEncodingType, lpszStructType, pbEncoded, @@ -6396,17 +7116,3 @@ BOOL WINAPI PFXIsPFXBlob(CRYPT_DATA_BLOB *pPFX) ret = FALSE; return ret; } - -HCERTSTORE WINAPI PFXImportCertStore(CRYPT_DATA_BLOB *pPFX, LPCWSTR szPassword, - DWORD dwFlags) -{ - FIXME_(crypt)("(%p, %p, %08x): stub\n", pPFX, szPassword, dwFlags); - return NULL; -} - -BOOL WINAPI PFXVerifyPassword(CRYPT_DATA_BLOB *pPFX, LPCWSTR szPassword, - DWORD dwFlags) -{ - FIXME_(crypt)("(%p, %p, %08x): stub\n", pPFX, szPassword, dwFlags); - return FALSE; -} diff --git a/dll/win32/crypt32/encode.c b/dll/win32/crypt32/encode.c index 9d052b61c18..9e362b8db21 100644 --- a/dll/win32/crypt32/encode.c +++ b/dll/win32/crypt32/encode.c @@ -30,23 +30,17 @@ * MSDN, especially "Constants for CryptEncodeObject and CryptDecodeObject" */ -#include "config.h" -#include "wine/port.h" - #include #include #include #include -#define NONAMELESSUNION - #include "windef.h" #include "winbase.h" #include "wincrypt.h" #include "snmp.h" #include "wine/debug.h" #include "wine/exception.h" -#include "wine/unicode.h" #include "crypt32_private.h" WINE_DEFAULT_DEBUG_CHANNEL(cryptasn); @@ -184,7 +178,7 @@ BOOL WINAPI CRYPT_AsnEncodeSequence(DWORD dwCertEncodingType, BOOL ret; DWORD i, dataLen = 0; - TRACE("%p, %d, %08x, %p, %p, %d\n", items, cItem, dwFlags, pEncodePara, + TRACE("%p, %ld, %08lx, %p, %p, %ld\n", items, cItem, dwFlags, pEncodePara, pbEncoded, pbEncoded ? *pcbEncoded : 0); for (i = 0, ret = TRUE; ret && i < cItem; i++) { @@ -232,7 +226,7 @@ BOOL WINAPI CRYPT_AsnEncodeSequence(DWORD dwCertEncodingType, } } } - TRACE("returning %d (%08x)\n", ret, GetLastError()); + TRACE("returning %d (%08lx)\n", ret, GetLastError()); return ret; } @@ -580,7 +574,7 @@ static BOOL CRYPT_AsnEncodeCRLEntry(const CRL_ENTRY *entry, DWORD cItem = 2; BOOL ret; - TRACE("%p, %p, %d\n", entry, pbEncoded, pbEncoded ? *pcbEncoded : 0); + TRACE("%p, %p, %ld\n", entry, pbEncoded, pbEncoded ? *pcbEncoded : 0); if (entry->cExtension) { @@ -592,7 +586,7 @@ static BOOL CRYPT_AsnEncodeCRLEntry(const CRL_ENTRY *entry, ret = CRYPT_AsnEncodeSequence(X509_ASN_ENCODING, items, cItem, 0, NULL, pbEncoded, pcbEncoded); - TRACE("returning %d (%08x)\n", ret, GetLastError()); + TRACE("returning %d (%08lx)\n", ret, GetLastError()); return ret; } @@ -736,7 +730,7 @@ static BOOL CRYPT_AsnEncodeExtension(CERT_EXTENSION *ext, BYTE *pbEncoded, }; DWORD cItem = 1; - TRACE("%p, %p, %d\n", ext, pbEncoded, pbEncoded ? *pcbEncoded : 0); + TRACE("%p, %p, %ld\n", ext, pbEncoded, pbEncoded ? *pcbEncoded : 0); if (ext->fCritical) { @@ -750,7 +744,7 @@ static BOOL CRYPT_AsnEncodeExtension(CERT_EXTENSION *ext, BYTE *pbEncoded, ret = CRYPT_AsnEncodeSequence(X509_ASN_ENCODING, items, cItem, 0, NULL, pbEncoded, pcbEncoded); - TRACE("returning %d (%08x)\n", ret, GetLastError()); + TRACE("returning %d (%08lx)\n", ret, GetLastError()); return ret; } @@ -1015,7 +1009,7 @@ static BOOL CRYPT_AsnEncodeUTF8String(const CERT_NAME_VALUE *value, if (value->Value.cbData) strLen = value->Value.cbData / sizeof(WCHAR); else if (str) - strLen = strlenW(str); + strLen = lstrlenW(str); else strLen = 0; encodedLen = WideCharToMultiByte(CP_UTF8, 0, str, strLen, NULL, 0, NULL, @@ -1186,7 +1180,7 @@ static BOOL CRYPT_AsnEncodeRdnAttr(DWORD dwCertEncodingType, return ret; } -static int BLOBComp(const void *l, const void *r) +static int __cdecl BLOBComp(const void *l, const void *r) { const CRYPT_DER_BLOB *a = l, *b = r; int ret; @@ -1409,7 +1403,7 @@ static BOOL WINAPI CRYPT_AsnEncodeUnicodeName(DWORD dwCertEncodingType, const CERT_NAME_INFO *info = pvStructInfo; DWORD bytesNeeded = 0, lenBytes, size, i; - TRACE("encoding name with %d RDNs\n", info->cRDN); + TRACE("encoding name with %ld RDNs\n", info->cRDN); ret = TRUE; for (i = 0; ret && i < info->cRDN; i++) { @@ -1999,7 +1993,7 @@ static BOOL CRYPT_AsnEncodeUnicodeStringCoerce(const CERT_NAME_VALUE *value, if (value->Value.cbData) encodedLen = value->Value.cbData / sizeof(WCHAR); else if (str) - encodedLen = strlenW(str); + encodedLen = lstrlenW(str); else encodedLen = 0; CRYPT_EncodeLen(encodedLen, NULL, &lenBytes); @@ -2036,7 +2030,7 @@ static BOOL CRYPT_AsnEncodeNumericString(const CERT_NAME_VALUE *value, if (value->Value.cbData) encodedLen = value->Value.cbData / sizeof(WCHAR); else if (str) - encodedLen = strlenW(str); + encodedLen = lstrlenW(str); else encodedLen = 0; CRYPT_EncodeLen(encodedLen, NULL, &lenBytes); @@ -2060,7 +2054,7 @@ static BOOL CRYPT_AsnEncodeNumericString(const CERT_NAME_VALUE *value, ptr += lenBytes; for (i = 0; ret && i < encodedLen; i++) { - if (isdigitW(str[i])) + if ('0' <= str[i] && str[i] <= '9') *ptr++ = (BYTE)str[i]; else { @@ -2078,9 +2072,7 @@ static BOOL CRYPT_AsnEncodeNumericString(const CERT_NAME_VALUE *value, static inline BOOL isprintableW(WCHAR wc) { - return isalnumW(wc) || isspaceW(wc) || wc == '\'' || wc == '(' || - wc == ')' || wc == '+' || wc == ',' || wc == '-' || wc == '.' || - wc == '/' || wc == ':' || wc == '=' || wc == '?'; + return wc && wcschr( L"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 '()+,-./:=?", wc ); } static BOOL CRYPT_AsnEncodePrintableString(const CERT_NAME_VALUE *value, @@ -2094,7 +2086,7 @@ static BOOL CRYPT_AsnEncodePrintableString(const CERT_NAME_VALUE *value, if (value->Value.cbData) encodedLen = value->Value.cbData / sizeof(WCHAR); else if (str) - encodedLen = strlenW(str); + encodedLen = lstrlenW(str); else encodedLen = 0; CRYPT_EncodeLen(encodedLen, NULL, &lenBytes); @@ -2145,7 +2137,7 @@ static BOOL CRYPT_AsnEncodeIA5String(const CERT_NAME_VALUE *value, if (value->Value.cbData) encodedLen = value->Value.cbData / sizeof(WCHAR); else if (str) - encodedLen = strlenW(str); + encodedLen = lstrlenW(str); else encodedLen = 0; CRYPT_EncodeLen(encodedLen, NULL, &lenBytes); @@ -2197,7 +2189,7 @@ static BOOL CRYPT_AsnEncodeUniversalString(const CERT_NAME_VALUE *value, if (value->Value.cbData) strLen = value->Value.cbData / sizeof(WCHAR); else if (str) - strLen = strlenW(str); + strLen = lstrlenW(str); else strLen = 0; CRYPT_EncodeLen(strLen * 4, NULL, &lenBytes); @@ -2312,7 +2304,7 @@ static BOOL WINAPI CRYPT_AsnEncodeName(DWORD dwCertEncodingType, const CERT_NAME_INFO *info = pvStructInfo; DWORD bytesNeeded = 0, lenBytes, size, i; - TRACE("encoding name with %d RDNs\n", info->cRDN); + TRACE("encoding name with %ld RDNs\n", info->cRDN); ret = TRUE; for (i = 0; ret && i < info->cRDN; i++) { @@ -2393,7 +2385,7 @@ static BOOL WINAPI CRYPT_AsnEncodeBool(DWORD dwCertEncodingType, *pbEncoded++ = val ? 0xff : 0; ret = TRUE; } - TRACE("returning %d (%08x)\n", ret, GetLastError()); + TRACE("returning %d (%08lx)\n", ret, GetLastError()); return ret; } @@ -2413,15 +2405,15 @@ static BOOL WINAPI CRYPT_AsnEncodeAltNameEntry(DWORD dwCertEncodingType, case CERT_ALT_NAME_DNS_NAME: case CERT_ALT_NAME_URL: tag = ASN_CONTEXT | (entry->dwAltNameChoice - 1); - if (entry->u.pwszURL) + if (entry->pwszURL) { DWORD i; /* Not + 1: don't encode the NULL-terminator */ - dataLen = lstrlenW(entry->u.pwszURL); + dataLen = lstrlenW(entry->pwszURL); for (i = 0; ret && i < dataLen; i++) { - if (entry->u.pwszURL[i] > 0x7f) + if (entry->pwszURL[i] > 0x7f) { SetLastError(CRYPT_E_INVALID_IA5_STRING); ret = FALSE; @@ -2434,23 +2426,23 @@ static BOOL WINAPI CRYPT_AsnEncodeAltNameEntry(DWORD dwCertEncodingType, break; case CERT_ALT_NAME_DIRECTORY_NAME: tag = ASN_CONTEXT | ASN_CONSTRUCTOR | (entry->dwAltNameChoice - 1); - dataLen = entry->u.DirectoryName.cbData; + dataLen = entry->DirectoryName.cbData; break; case CERT_ALT_NAME_IP_ADDRESS: tag = ASN_CONTEXT | (entry->dwAltNameChoice - 1); - dataLen = entry->u.IPAddress.cbData; + dataLen = entry->IPAddress.cbData; break; case CERT_ALT_NAME_REGISTERED_ID: { struct AsnEncodeTagSwappedItem swapped = - { ASN_CONTEXT | (entry->dwAltNameChoice - 1), entry->u.pszRegisteredID, + { ASN_CONTEXT | (entry->dwAltNameChoice - 1), entry->pszRegisteredID, CRYPT_AsnEncodeOid }; return CRYPT_AsnEncodeSwapTag(0, NULL, &swapped, 0, NULL, pbEncoded, pcbEncoded); } case CERT_ALT_NAME_OTHER_NAME: - FIXME("name type %d unimplemented\n", entry->dwAltNameChoice); + FIXME("name type %ld unimplemented\n", entry->dwAltNameChoice); return FALSE; default: SetLastError(E_INVALIDARG); @@ -2484,21 +2476,21 @@ static BOOL WINAPI CRYPT_AsnEncodeAltNameEntry(DWORD dwCertEncodingType, DWORD i; for (i = 0; i < dataLen; i++) - *pbEncoded++ = (BYTE)entry->u.pwszURL[i]; + *pbEncoded++ = (BYTE)entry->pwszURL[i]; break; } case CERT_ALT_NAME_DIRECTORY_NAME: - memcpy(pbEncoded, entry->u.DirectoryName.pbData, dataLen); + memcpy(pbEncoded, entry->DirectoryName.pbData, dataLen); break; case CERT_ALT_NAME_IP_ADDRESS: - memcpy(pbEncoded, entry->u.IPAddress.pbData, dataLen); + memcpy(pbEncoded, entry->IPAddress.pbData, dataLen); break; } if (ret) *pcbEncoded = bytesNeeded; } } - TRACE("returning %d (%08x)\n", ret, GetLastError()); + TRACE("returning %d (%08lx)\n", ret, GetLastError()); return ret; } @@ -3136,6 +3128,52 @@ static BOOL WINAPI CRYPT_AsnEncodeCertPolicyConstraints( return ret; } +static BOOL WINAPI CRYPT_AsnEncodeRsaPubKey_Bcrypt(DWORD dwCertEncodingType, + LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags, + PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded) +{ + BOOL ret; + + __TRY + { + const BCRYPT_RSAKEY_BLOB *hdr = pvStructInfo; + + BYTE *pubexp = (BYTE*)pvStructInfo + sizeof(BCRYPT_RSAKEY_BLOB); + BYTE *modulus = (BYTE*)pvStructInfo + sizeof(BCRYPT_RSAKEY_BLOB) + hdr->cbPublicExp; + BYTE *pubexp_be = CryptMemAlloc(hdr->cbPublicExp); + BYTE *modulus_be = CryptMemAlloc(hdr->cbModulus); + CRYPT_INTEGER_BLOB pubexp_int = { hdr->cbPublicExp, pubexp_be }; + CRYPT_INTEGER_BLOB modulus_int = { hdr->cbModulus, modulus_be}; + + struct AsnEncodeSequenceItem items[] = { + { &modulus_int, CRYPT_AsnEncodeUnsignedInteger, 0 }, + { &pubexp_int, CRYPT_AsnEncodeInteger, 0 }, + }; + + /* CNG_RSA_PUBLIC_KEY_BLOB stores the exponent and modulus + * in big-endian format, so we need to convert them + * to little-endian format before encoding + */ + CRYPT_CopyReversed(pubexp_be, pubexp, hdr->cbPublicExp); + CRYPT_CopyReversed(modulus_be, modulus, hdr->cbModulus); + + ret = CRYPT_AsnEncodeSequence(dwCertEncodingType, items, + ARRAY_SIZE(items), dwFlags, pEncodePara, pbEncoded, pcbEncoded); + + CryptMemFree(pubexp_be); + CryptMemFree(modulus_be); + } + __EXCEPT_PAGE_FAULT + { + SetLastError(STATUS_ACCESS_VIOLATION); + ret = FALSE; + } + __ENDTRY + return ret; + +} + + static BOOL WINAPI CRYPT_AsnEncodeRsaPubKey(DWORD dwCertEncodingType, LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags, PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded) @@ -3186,7 +3224,7 @@ BOOL WINAPI CRYPT_AsnEncodeOctets(DWORD dwCertEncodingType, const CRYPT_DATA_BLOB *blob = pvStructInfo; DWORD bytesNeeded, lenBytes; - TRACE("(%d, %p), %08x, %p, %p, %d\n", blob->cbData, blob->pbData, + TRACE("(%ld, %p), %08lx, %p, %p, %ld\n", blob->cbData, blob->pbData, dwFlags, pEncodePara, pbEncoded, pbEncoded ? *pcbEncoded : 0); CRYPT_EncodeLen(blob->cbData, NULL, &lenBytes); @@ -3217,7 +3255,7 @@ BOOL WINAPI CRYPT_AsnEncodeOctets(DWORD dwCertEncodingType, ret = FALSE; } __ENDTRY - TRACE("returning %d (%08x)\n", ret, GetLastError()); + TRACE("returning %d (%08lx)\n", ret, GetLastError()); return ret; } @@ -3717,7 +3755,7 @@ static BOOL CRYPT_AsnEncodeDistPoint(const CRL_DIST_POINT *distPoint, break; case CRL_DIST_POINT_FULL_NAME: swapped[cSwapped].tag = ASN_CONTEXT | ASN_CONSTRUCTOR | 0; - swapped[cSwapped].pvStructInfo = &distPoint->DistPointName.u.FullName; + swapped[cSwapped].pvStructInfo = &distPoint->DistPointName.FullName; swapped[cSwapped].encodeFunc = CRYPT_AsnEncodeAltName; constructed.tag = 0; constructed.pvStructInfo = &swapped[cSwapped]; @@ -3932,7 +3970,7 @@ static BOOL WINAPI CRYPT_AsnEncodeIssuingDistPoint(DWORD dwCertEncodingType, break; case CRL_DIST_POINT_FULL_NAME: swapped[cSwapped].tag = ASN_CONTEXT | ASN_CONSTRUCTOR | 0; - swapped[cSwapped].pvStructInfo = &point->DistPointName.u.FullName; + swapped[cSwapped].pvStructInfo = &point->DistPointName.FullName; swapped[cSwapped].encodeFunc = CRYPT_AsnEncodeAltName; constructed.tag = 0; constructed.pvStructInfo = &swapped[cSwapped]; @@ -4235,7 +4273,7 @@ static BOOL WINAPI CRYPT_AsnEncodeCMSSignerInfo(DWORD dwCertEncodingType, info->SignerId.dwIdChoice != CERT_ID_KEY_IDENTIFIER) SetLastError(E_INVALIDARG); else if (info->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER && - !info->SignerId.u.IssuerSerialNumber.Issuer.cbData) + !info->SignerId.IssuerSerialNumber.Issuer.cbData) SetLastError(E_INVALIDARG); else { @@ -4248,7 +4286,7 @@ static BOOL WINAPI CRYPT_AsnEncodeCMSSignerInfo(DWORD dwCertEncodingType, if (info->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER) { items[cItem].pvStructInfo = - &info->SignerId.u.IssuerSerialNumber.Issuer; + &info->SignerId.IssuerSerialNumber.Issuer; items[cItem].encodeFunc = CRYPT_AsnEncodeIssuerSerialNumber; cItem++; @@ -4256,7 +4294,7 @@ static BOOL WINAPI CRYPT_AsnEncodeCMSSignerInfo(DWORD dwCertEncodingType, else { swapped[cSwapped].tag = ASN_CONTEXT | 0; - swapped[cSwapped].pvStructInfo = &info->SignerId.u.KeyId; + swapped[cSwapped].pvStructInfo = &info->SignerId.KeyId; swapped[cSwapped].encodeFunc = CRYPT_AsnEncodeOctets; items[cItem].pvStructInfo = &swapped[cSwapped]; items[cItem].encodeFunc = CRYPT_AsnEncodeSwapTag; @@ -4307,30 +4345,19 @@ static BOOL WINAPI CRYPT_AsnEncodeCMSSignerInfo(DWORD dwCertEncodingType, BOOL CRYPT_AsnEncodeCMSSignedInfo(CRYPT_SIGNED_INFO *signedInfo, void *pvData, DWORD *pcbData) { + struct DERSetDescriptor digestAlgorithmsSet = { signedInfo->cSignerInfo, + signedInfo->rgSignerInfo, sizeof(CMSG_CMS_SIGNER_INFO), + offsetof(CMSG_CMS_SIGNER_INFO, HashAlgorithm), + CRYPT_AsnEncodeAlgorithmIdWithNullParams }; struct AsnEncodeSequenceItem items[7] = { { &signedInfo->version, CRYPT_AsnEncodeInt, 0 }, + { &digestAlgorithmsSet, CRYPT_DEREncodeItemsAsSet, 0 }, + { &signedInfo->content, CRYPT_AsnEncodePKCSContentInfoInternal, 0 } }; - struct DERSetDescriptor digestAlgorithmsSet = { 0 }, certSet = { 0 }; - struct DERSetDescriptor crlSet = { 0 }, signerSet = { 0 }; + struct DERSetDescriptor certSet = { 0 }, crlSet = { 0 }, signerSet = { 0 }; struct AsnEncodeTagSwappedItem swapped[2] = { { 0 } }; - DWORD cItem = 1, cSwapped = 0; - BOOL ret = TRUE; + DWORD cItem = 3, cSwapped = 0; - if (signedInfo->cSignerInfo) - { - digestAlgorithmsSet.cItems = signedInfo->cSignerInfo; - digestAlgorithmsSet.items = signedInfo->rgSignerInfo; - digestAlgorithmsSet.itemSize = sizeof(CMSG_CMS_SIGNER_INFO); - digestAlgorithmsSet.itemOffset = - offsetof(CMSG_CMS_SIGNER_INFO, HashAlgorithm); - digestAlgorithmsSet.encode = CRYPT_AsnEncodeAlgorithmIdWithNullParams; - items[cItem].pvStructInfo = &digestAlgorithmsSet; - items[cItem].encodeFunc = CRYPT_DEREncodeItemsAsSet; - cItem++; - } - items[cItem].pvStructInfo = &signedInfo->content; - items[cItem].encodeFunc = CRYPT_AsnEncodePKCSContentInfoInternal; - cItem++; if (signedInfo->cCertEncoded) { certSet.cItems = signedInfo->cCertEncoded; @@ -4361,22 +4388,17 @@ BOOL CRYPT_AsnEncodeCMSSignedInfo(CRYPT_SIGNED_INFO *signedInfo, void *pvData, cSwapped++; cItem++; } - if (ret && signedInfo->cSignerInfo) - { - signerSet.cItems = signedInfo->cSignerInfo; - signerSet.items = signedInfo->rgSignerInfo; - signerSet.itemSize = sizeof(CMSG_CMS_SIGNER_INFO); - signerSet.itemOffset = 0; - signerSet.encode = CRYPT_AsnEncodeCMSSignerInfo; - items[cItem].pvStructInfo = &signerSet; - items[cItem].encodeFunc = CRYPT_DEREncodeItemsAsSet; - cItem++; - } - if (ret) - ret = CRYPT_AsnEncodeSequence(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, - items, cItem, 0, NULL, pvData, pcbData); + signerSet.cItems = signedInfo->cSignerInfo; + signerSet.items = signedInfo->rgSignerInfo; + signerSet.itemSize = sizeof(CMSG_CMS_SIGNER_INFO); + signerSet.itemOffset = 0; + signerSet.encode = CRYPT_AsnEncodeCMSSignerInfo; + items[cItem].pvStructInfo = &signerSet; + items[cItem].encodeFunc = CRYPT_DEREncodeItemsAsSet; + cItem++; - return ret; + return CRYPT_AsnEncodeSequence(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, + items, cItem, 0, NULL, pvData, pcbData); } static BOOL WINAPI CRYPT_AsnEncodeRecipientInfo(DWORD dwCertEncodingType, @@ -4386,7 +4408,7 @@ static BOOL WINAPI CRYPT_AsnEncodeRecipientInfo(DWORD dwCertEncodingType, const CMSG_KEY_TRANS_RECIPIENT_INFO *info = pvStructInfo; struct AsnEncodeSequenceItem items[] = { { &info->dwVersion, CRYPT_AsnEncodeInt, 0 }, - { &info->RecipientId.u.IssuerSerialNumber, + { &info->RecipientId.IssuerSerialNumber, CRYPT_AsnEncodeIssuerSerialNumber, 0 }, { &info->KeyEncryptionAlgorithm, CRYPT_AsnEncodeAlgorithmIdWithNullParams, 0 }, @@ -4432,6 +4454,225 @@ BOOL CRYPT_AsnEncodePKCSEnvelopedData(const CRYPT_ENVELOPED_DATA *envelopedData, ARRAY_SIZE(items), 0, NULL, pvData, pcbData); } +static BOOL WINAPI CRYPT_AsnEncodeCertId(DWORD dwCertEncodingType, + LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags, + PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded) +{ + BOOL ret; + + __TRY + { + const OCSP_CERT_ID *id = pvStructInfo; + struct AsnEncodeSequenceItem items[] = { + { &id->HashAlgorithm, CRYPT_AsnEncodeAlgorithmIdWithNullParams, 0 }, + { &id->IssuerNameHash, CRYPT_AsnEncodeOctets, 0 }, + { &id->IssuerKeyHash, CRYPT_AsnEncodeOctets, 0 }, + { &id->SerialNumber, CRYPT_AsnEncodeInteger, 0 }, + }; + + ret = CRYPT_AsnEncodeSequence(dwCertEncodingType, items, + ARRAY_SIZE(items), dwFlags, pEncodePara, pbEncoded, pcbEncoded); + } + __EXCEPT_PAGE_FAULT + { + SetLastError(STATUS_ACCESS_VIOLATION); + ret = FALSE; + } + __ENDTRY + return ret; +} + +static BOOL CRYPT_AsnEncodeOCSPRequestEntry(DWORD dwCertEncodingType, + LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags, + PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded) +{ + BOOL ret; + + __TRY + { + const OCSP_REQUEST_ENTRY *info = pvStructInfo; + struct AsnEncodeSequenceItem items[] = { + { &info->CertId, CRYPT_AsnEncodeCertId, 0 }, + }; + + if (info->cExtension) + { + FIXME("extensions not supported\n"); + SetLastError(E_INVALIDARG); + ret = FALSE; + } + else + { + ret = CRYPT_AsnEncodeSequence(dwCertEncodingType, items, + ARRAY_SIZE(items), dwFlags, pEncodePara, pbEncoded, pcbEncoded); + } + } + __EXCEPT_PAGE_FAULT + { + SetLastError(STATUS_ACCESS_VIOLATION); + ret = FALSE; + } + __ENDTRY + return ret; +} + +struct ocsp_request_list +{ + DWORD count; + OCSP_REQUEST_ENTRY *entry; +}; + +static BOOL WINAPI CRYPT_AsnEncodeOCSPRequestEntries(DWORD dwCertEncodingType, + LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags, + PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded) +{ + BOOL ret; + + __TRY + { + DWORD bytesNeeded, dataLen, lenBytes, i; + const struct ocsp_request_list *list = pvStructInfo; + + ret = TRUE; + for (i = 0, dataLen = 0; ret && i < list->count; i++) + { + DWORD size; + ret = CRYPT_AsnEncodeOCSPRequestEntry(dwCertEncodingType, lpszStructType, &list->entry[i], + dwFlags, pEncodePara, NULL, &size); + if (ret) + dataLen += size; + } + if (ret) + { + CRYPT_EncodeLen(dataLen, NULL, &lenBytes); + bytesNeeded = 1 + lenBytes + dataLen; + if (!pbEncoded) + *pcbEncoded = bytesNeeded; + else + { + if ((ret = CRYPT_EncodeEnsureSpace(dwFlags, pEncodePara, + pbEncoded, pcbEncoded, bytesNeeded))) + { + BYTE *out; + + if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG) + pbEncoded = *(BYTE **)pbEncoded; + out = pbEncoded; + *out++ = ASN_SEQUENCEOF; + CRYPT_EncodeLen(dataLen, out, &lenBytes); + out += lenBytes; + for (i = 0; i < list->count; i++) + { + DWORD size = dataLen; + + ret = CRYPT_AsnEncodeOCSPRequestEntry(dwCertEncodingType, lpszStructType, + &list->entry[i], dwFlags, pEncodePara, out, &size); + out += size; + dataLen -= size; + } + + if (!ret && (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)) + CRYPT_FreeSpace(pEncodePara, pbEncoded); + } + } + } + } + __EXCEPT_PAGE_FAULT + { + SetLastError(STATUS_ACCESS_VIOLATION); + ret = FALSE; + } + __ENDTRY + return ret; +} + +static BOOL WINAPI CRYPT_AsnEncodeOCSPRequest(DWORD dwCertEncodingType, + LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags, + PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded) +{ + BOOL ret; + + __TRY + { + const OCSP_REQUEST_INFO *info = pvStructInfo; + + if (info->dwVersion != OCSP_REQUEST_V1) + { + FIXME("version %lu not supported\n", info->dwVersion); + SetLastError(E_INVALIDARG); + ret = FALSE; + } + else + { + if (info->cExtension) + { + FIXME("extensions not supported\n"); + SetLastError(E_INVALIDARG); + ret = FALSE; + } + else + { + struct AsnConstructedItem name; + struct AsnEncodeSequenceItem items[2]; + DWORD count = 0; + + if (info->pRequestorName) + { + name.tag = 1; + name.pvStructInfo = info->pRequestorName; + name.encodeFunc = CRYPT_AsnEncodeAltNameEntry; + items[count].pvStructInfo = &name; + items[count].encodeFunc = CRYPT_AsnEncodeConstructed; + count++; + } + if (info->cRequestEntry) + { + items[count].pvStructInfo = &info->cRequestEntry; + items[count].encodeFunc = CRYPT_AsnEncodeOCSPRequestEntries; + count++; + } + + ret = CRYPT_AsnEncodeSequence(dwCertEncodingType, items, + count, dwFlags, pEncodePara, pbEncoded, pcbEncoded); + } + } + } + __EXCEPT_PAGE_FAULT + { + SetLastError(STATUS_ACCESS_VIOLATION); + ret = FALSE; + } + __ENDTRY + return ret; +} + +static BOOL WINAPI CRYPT_AsnEncodeOCSPSignedRequest(DWORD dwCertEncodingType, + LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags, + PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded) +{ + BOOL ret; + + __TRY + { + const OCSP_SIGNED_REQUEST_INFO *info = pvStructInfo; + struct AsnEncodeSequenceItem items[] = { + { &info->ToBeSigned, CRYPT_CopyEncodedBlob, 0 }, + }; + + if (info->pOptionalSignatureInfo) FIXME("pOptionalSignatureInfo not supported\n"); + + ret = CRYPT_AsnEncodeSequence(dwCertEncodingType, items, + ARRAY_SIZE(items), dwFlags, pEncodePara, pbEncoded, pcbEncoded); + } + __EXCEPT_PAGE_FAULT + { + SetLastError(STATUS_ACCESS_VIOLATION); + ret = FALSE; + } + __ENDTRY + return ret; +} + static CryptEncodeObjectExFunc CRYPT_GetBuiltinEncoder(DWORD dwCertEncodingType, LPCSTR lpszStructType) { @@ -4569,6 +4810,17 @@ static CryptEncodeObjectExFunc CRYPT_GetBuiltinEncoder(DWORD dwCertEncodingType, case LOWORD(CMS_SIGNER_INFO): encodeFunc = CRYPT_AsnEncodeCMSSignerInfo; break; + case LOWORD(CNG_RSA_PUBLIC_KEY_BLOB): + encodeFunc = CRYPT_AsnEncodeRsaPubKey_Bcrypt; + break; + case LOWORD(OCSP_REQUEST): + encodeFunc = CRYPT_AsnEncodeOCSPRequest; + break; + case LOWORD(OCSP_SIGNED_REQUEST): + encodeFunc = CRYPT_AsnEncodeOCSPSignedRequest; + break; + default: + FIXME("Unimplemented encoder for lpszStructType OID %d\n", LOWORD(lpszStructType)); } } else if (!strcmp(lpszStructType, szOID_CERT_EXTENSIONS)) @@ -4623,6 +4875,8 @@ static CryptEncodeObjectExFunc CRYPT_GetBuiltinEncoder(DWORD dwCertEncodingType, encodeFunc = CRYPT_AsnEncodePolicyQualifierUserNotice; else if (!strcmp(lpszStructType, szOID_CTL)) encodeFunc = CRYPT_AsnEncodeCTL; + else + FIXME("Unsupported encoder for lpszStructType %s\n", lpszStructType); return encodeFunc; } @@ -4660,7 +4914,7 @@ BOOL WINAPI CryptEncodeObject(DWORD dwCertEncodingType, LPCSTR lpszStructType, CryptEncodeObjectFunc pCryptEncodeObject = NULL; CryptEncodeObjectExFunc pCryptEncodeObjectEx = NULL; - TRACE_(crypt)("(0x%08x, %s, %p, %p, %p)\n", dwCertEncodingType, + TRACE_(crypt)("(0x%08lx, %s, %p, %p, %p)\n", dwCertEncodingType, debugstr_a(lpszStructType), pvStructInfo, pbEncoded, pcbEncoded); @@ -4701,7 +4955,7 @@ BOOL WINAPI CryptEncodeObjectEx(DWORD dwCertEncodingType, LPCSTR lpszStructType, HCRYPTOIDFUNCADDR hFunc = NULL; CryptEncodeObjectExFunc encodeFunc = NULL; - TRACE_(crypt)("(0x%08x, %s, %p, 0x%08x, %p, %p, %p)\n", dwCertEncodingType, + TRACE_(crypt)("(0x%08lx, %s, %p, 0x%08lx, %p, %p, %p)\n", dwCertEncodingType, debugstr_a(lpszStructType), pvStructInfo, dwFlags, pEncodePara, pvEncoded, pcbEncoded); @@ -4758,20 +5012,6 @@ BOOL WINAPI CryptEncodeObjectEx(DWORD dwCertEncodingType, LPCSTR lpszStructType, return ret; } -BOOL WINAPI PFXExportCertStore(HCERTSTORE hStore, CRYPT_DATA_BLOB *pPFX, - LPCWSTR szPassword, DWORD dwFlags) -{ - return PFXExportCertStoreEx(hStore, pPFX, szPassword, NULL, dwFlags); -} - -BOOL WINAPI PFXExportCertStoreEx(HCERTSTORE hStore, CRYPT_DATA_BLOB *pPFX, - LPCWSTR szPassword, void *pvReserved, DWORD dwFlags) -{ - FIXME_(crypt)("(%p, %p, %p, %p, %08x): stub\n", hStore, pPFX, szPassword, - pvReserved, dwFlags); - return FALSE; -} - BOOL WINAPI CryptExportPublicKeyInfo(HCRYPTPROV_OR_NCRYPT_KEY_HANDLE hCryptProv, DWORD dwKeySpec, DWORD dwCertEncodingType, PCERT_PUBLIC_KEY_INFO pInfo, DWORD *pcbInfo) { @@ -4791,7 +5031,7 @@ static BOOL WINAPI CRYPT_ExportPublicKeyInfoEx(HCRYPTPROV_OR_NCRYPT_KEY_HANDLE h HCRYPTKEY key; static CHAR rsa_oid[] = szOID_RSA_RSA; - TRACE_(crypt)("(%08lx, %d, %08x, %s, %08x, %p, %p, %d)\n", hCryptProv, + TRACE_(crypt)("(%08Ix, %ld, %08lx, %s, %08lx, %p, %p, %ld)\n", hCryptProv, dwKeySpec, dwCertEncodingType, debugstr_a(pszPublicKeyObjId), dwFlags, pvAuxInfo, pInfo, pInfo ? *pcbInfo : 0); @@ -4940,7 +5180,7 @@ BOOL WINAPI CryptExportPublicKeyInfoEx(HCRYPTPROV_OR_NCRYPT_KEY_HANDLE hCryptPro ExportPublicKeyInfoExFunc exportFunc = NULL; HCRYPTOIDFUNCADDR hFunc = NULL; - TRACE_(crypt)("(%08lx, %d, %08x, %s, %08x, %p, %p, %d)\n", hCryptProv, + TRACE_(crypt)("(%08Ix, %ld, %08lx, %s, %08lx, %p, %p, %ld)\n", hCryptProv, dwKeySpec, dwCertEncodingType, debugstr_a(pszPublicKeyObjId), dwFlags, pvAuxInfo, pInfo, pInfo ? *pcbInfo : 0); @@ -4989,7 +5229,7 @@ static BOOL WINAPI CRYPT_ImportPublicKeyInfoEx(HCRYPTPROV hCryptProv, DWORD pubKeySize; LPBYTE pubKey; - TRACE_(crypt)("(%08lx, %08x, %p, %08x, %08x, %p, %p)\n", hCryptProv, + TRACE_(crypt)("(%08Ix, %08lx, %p, %08x, %08lx, %p, %p)\n", hCryptProv, dwCertEncodingType, pInfo, aiKeyAlg, dwFlags, pvAuxInfo, phKey); if (!set) @@ -5050,7 +5290,7 @@ BOOL WINAPI CryptImportPublicKeyInfoEx(HCRYPTPROV hCryptProv, ImportPublicKeyInfoExFunc importFunc = NULL; HCRYPTOIDFUNCADDR hFunc = NULL; - TRACE_(crypt)("(%08lx, %08x, %p, %08x, %08x, %p, %p)\n", hCryptProv, + TRACE_(crypt)("(%08Ix, %08lx, %p, %08x, %08lx, %p, %p)\n", hCryptProv, dwCertEncodingType, pInfo, aiKeyAlg, dwFlags, pvAuxInfo, phKey); if (!set) @@ -5065,3 +5305,16 @@ BOOL WINAPI CryptImportPublicKeyInfoEx(HCRYPTPROV hCryptProv, CryptFreeOIDFunctionAddress(hFunc, 0); return ret; } + +BOOL WINAPI CryptImportPublicKeyInfoEx2(DWORD dwCertEncodingType, + PCERT_PUBLIC_KEY_INFO pInfo, DWORD dwFlags, void *pvAuxInfo, + BCRYPT_KEY_HANDLE *phKey) +{ + TRACE_(crypt)("(%ld, %p, %08lx, %p, %p)\n", dwCertEncodingType, pInfo, + dwFlags, pvAuxInfo, phKey); + + if (dwFlags) + FIXME("flags %#lx ignored\n", dwFlags); + + return CNG_ImportPubKey(pInfo, phKey); +} diff --git a/dll/win32/crypt32/filestore.c b/dll/win32/crypt32/filestore.c index 9c211e14b1d..3753283fbca 100644 --- a/dll/win32/crypt32/filestore.c +++ b/dll/win32/crypt32/filestore.c @@ -21,7 +21,6 @@ #include "wincrypt.h" #include "winnls.h" #include "wine/debug.h" -#include "wine/unicode.h" #include "crypt32_private.h" WINE_DEFAULT_DEBUG_CHANNEL(crypt); @@ -39,7 +38,7 @@ static void WINAPI CRYPT_FileCloseStore(HCERTSTORE hCertStore, DWORD dwFlags) { WINE_FILESTOREINFO *store = hCertStore; - TRACE("(%p, %08x)\n", store, dwFlags); + TRACE("(%p, %08lx)\n", store, dwFlags); if (store->dirty) CertSaveStore(store->memStore, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, store->type, CERT_STORE_SAVE_TO_FILE, store->file, 0); @@ -52,7 +51,7 @@ static BOOL WINAPI CRYPT_FileWriteCert(HCERTSTORE hCertStore, { WINE_FILESTOREINFO *store = hCertStore; - TRACE("(%p, %p, %d)\n", hCertStore, cert, dwFlags); + TRACE("(%p, %p, %ld)\n", hCertStore, cert, dwFlags); store->dirty = TRUE; return TRUE; } @@ -62,7 +61,7 @@ static BOOL WINAPI CRYPT_FileDeleteCert(HCERTSTORE hCertStore, { WINE_FILESTOREINFO *store = hCertStore; - TRACE("(%p, %p, %08x)\n", hCertStore, pCertContext, dwFlags); + TRACE("(%p, %p, %08lx)\n", hCertStore, pCertContext, dwFlags); store->dirty = TRUE; return TRUE; } @@ -72,7 +71,7 @@ static BOOL WINAPI CRYPT_FileWriteCRL(HCERTSTORE hCertStore, { WINE_FILESTOREINFO *store = hCertStore; - TRACE("(%p, %p, %d)\n", hCertStore, crl, dwFlags); + TRACE("(%p, %p, %ld)\n", hCertStore, crl, dwFlags); store->dirty = TRUE; return TRUE; } @@ -82,7 +81,7 @@ static BOOL WINAPI CRYPT_FileDeleteCRL(HCERTSTORE hCertStore, { WINE_FILESTOREINFO *store = hCertStore; - TRACE("(%p, %p, %08x)\n", hCertStore, pCrlContext, dwFlags); + TRACE("(%p, %p, %08lx)\n", hCertStore, pCrlContext, dwFlags); store->dirty = TRUE; return TRUE; } @@ -92,7 +91,7 @@ static BOOL WINAPI CRYPT_FileWriteCTL(HCERTSTORE hCertStore, { WINE_FILESTOREINFO *store = hCertStore; - TRACE("(%p, %p, %d)\n", hCertStore, ctl, dwFlags); + TRACE("(%p, %p, %ld)\n", hCertStore, ctl, dwFlags); store->dirty = TRUE; return TRUE; } @@ -102,7 +101,7 @@ static BOOL WINAPI CRYPT_FileDeleteCTL(HCERTSTORE hCertStore, { WINE_FILESTOREINFO *store = hCertStore; - TRACE("(%p, %p, %08x)\n", hCertStore, pCtlContext, dwFlags); + TRACE("(%p, %p, %08lx)\n", hCertStore, pCtlContext, dwFlags); store->dirty = TRUE; return TRUE; } @@ -134,7 +133,7 @@ static BOOL WINAPI CRYPT_FileControl(HCERTSTORE hCertStore, DWORD dwFlags, WINE_FILESTOREINFO *store = hCertStore; BOOL ret; - TRACE("(%p, %08x, %d, %p)\n", hCertStore, dwFlags, dwCtrlType, + TRACE("(%p, %08lx, %ld, %p)\n", hCertStore, dwFlags, dwCtrlType, pvCtrlPara); switch (dwCtrlType) @@ -174,7 +173,7 @@ static BOOL WINAPI CRYPT_FileControl(HCERTSTORE hCertStore, DWORD dwFlags, } else { - WARN("unknown type %d\n", store->type); + WARN("unknown type %ld\n", store->type); ret = FALSE; } break; @@ -192,7 +191,7 @@ static BOOL WINAPI CRYPT_FileControl(HCERTSTORE hCertStore, DWORD dwFlags, ret = TRUE; break; default: - FIXME("%d: stub\n", dwCtrlType); + FIXME("%ld: stub\n", dwCtrlType); ret = FALSE; } return ret; @@ -245,7 +244,7 @@ WINECRYPT_CERTSTORE *CRYPT_FileOpenStore(HCRYPTPROV hCryptProv, DWORD dwFlags, WINECRYPT_CERTSTORE *store = NULL; HANDLE file = (HANDLE)pvPara; - TRACE("(%ld, %08x, %p)\n", hCryptProv, dwFlags, pvPara); + TRACE("(%Id, %08lx, %p)\n", hCryptProv, dwFlags, pvPara); if (!pvPara) { @@ -297,7 +296,7 @@ WINECRYPT_CERTSTORE *CRYPT_FileNameOpenStoreW(HCRYPTPROV hCryptProv, DWORD access, create; HANDLE file; - TRACE("(%ld, %08x, %s)\n", hCryptProv, dwFlags, debugstr_w(fileName)); + TRACE("(%Id, %08lx, %s)\n", hCryptProv, dwFlags, debugstr_w(fileName)); if (!fileName) { @@ -354,14 +353,12 @@ WINECRYPT_CERTSTORE *CRYPT_FileNameOpenStoreW(HCRYPTPROV hCryptProv, } else { - static const WCHAR spc[] = { 's','p','c',0 }; - static const WCHAR p7c[] = { 'p','7','c',0 }; - LPCWSTR ext = strrchrW(fileName, '.'); + LPCWSTR ext = wcsrchr(fileName, '.'); if (ext) { ext++; - if (!lstrcmpiW(ext, spc) || !lstrcmpiW(ext, p7c)) + if (!lstrcmpiW(ext, L"spc") || !lstrcmpiW(ext, L"p7c")) type = CERT_STORE_SAVE_AS_PKCS7; } if (!type) @@ -386,7 +383,7 @@ WINECRYPT_CERTSTORE *CRYPT_FileNameOpenStoreA(HCRYPTPROV hCryptProv, int len; WINECRYPT_CERTSTORE *ret = NULL; - TRACE("(%ld, %08x, %s)\n", hCryptProv, dwFlags, + TRACE("(%Id, %08lx, %s)\n", hCryptProv, dwFlags, debugstr_a(pvPara)); if (!pvPara) diff --git a/dll/win32/crypt32/main.c b/dll/win32/crypt32/main.c index d0643f41077..b320c895e15 100644 --- a/dll/win32/crypt32/main.c +++ b/dll/win32/crypt32/main.c @@ -17,12 +17,13 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "config.h" #include +#include #include #include "windef.h" #include "winbase.h" +#include "winternl.h" #include "wincrypt.h" #include "winreg.h" #include "winuser.h" @@ -45,15 +46,18 @@ static CRITICAL_SECTION_DEBUG prov_param_cs_debug = }; static CRITICAL_SECTION prov_param_cs = { &prov_param_cs_debug, -1, 0, 0, 0, 0 }; -BOOL WINAPI DllMain(HINSTANCE hInst, DWORD fdwReason, PVOID pvReserved) +BOOL WINAPI DllMain(HINSTANCE hInst, DWORD reason, PVOID pvReserved) { - switch (fdwReason) + switch (reason) { case DLL_PROCESS_ATTACH: hInstance = hInst; DisableThreadLibraryCalls(hInst); init_empty_store(); crypt_oid_init(); + if (__wine_init_unix_call()) + return FALSE; + CRYPT32_CALL( process_attach, NULL ); break; case DLL_PROCESS_DETACH: if (pvReserved) break; @@ -61,6 +65,7 @@ BOOL WINAPI DllMain(HINSTANCE hInst, DWORD fdwReason, PVOID pvReserved) crypt_sip_free(); default_chain_engine_free(); if (hDefProv) CryptReleaseContext(hDefProv, 0); + CRYPT32_CALL( process_detach, NULL ); break; } return TRUE; @@ -100,47 +105,47 @@ BOOL WINAPI I_CryptCreateLruCache(void *unknown, HLRUCACHE *out) BOOL WINAPI I_CryptFindLruEntry(DWORD unk0, DWORD unk1) { - FIXME("(%08x, %08x): stub!\n", unk0, unk1); + FIXME("(%08lx, %08lx): stub!\n", unk0, unk1); return FALSE; } BOOL WINAPI I_CryptFindLruEntryData(DWORD unk0, DWORD unk1, DWORD unk2) { - FIXME("(%08x, %08x, %08x): stub!\n", unk0, unk1, unk2); + FIXME("(%08lx, %08lx, %08lx): stub!\n", unk0, unk1, unk2); return FALSE; } BOOL WINAPI I_CryptCreateLruEntry(HLRUCACHE h, DWORD unk0, DWORD unk1) { - FIXME("(%p, %08x, %08x): stub!\n", h, unk0, unk1); + FIXME("(%p, %08lx, %08lx): stub!\n", h, unk0, unk1); return FALSE; } DWORD WINAPI I_CryptFlushLruCache(HLRUCACHE h, DWORD unk0, DWORD unk1) { - FIXME("(%p, %08x, %08x): stub!\n", h, unk0, unk1); + FIXME("(%p, %08lx, %08lx): stub!\n", h, unk0, unk1); return 0; } HLRUCACHE WINAPI I_CryptFreeLruCache(HLRUCACHE h, DWORD unk0, DWORD unk1) { - FIXME("(%p, %08x, %08x): stub!\n", h, unk0, unk1); + FIXME("(%p, %08lx, %08lx): stub!\n", h, unk0, unk1); return h; } LPVOID WINAPI CryptMemAlloc(ULONG cbSize) { - return HeapAlloc(GetProcessHeap(), 0, cbSize); + return malloc(cbSize); } LPVOID WINAPI CryptMemRealloc(LPVOID pv, ULONG cbSize) { - return HeapReAlloc(GetProcessHeap(), 0, pv, cbSize); + return realloc(pv, cbSize); } VOID WINAPI CryptMemFree(LPVOID pv) { - HeapFree(GetProcessHeap(), 0, pv); + free(pv); } DWORD WINAPI I_CryptAllocTls(void) @@ -171,7 +176,7 @@ BOOL WINAPI I_CryptFreeTls(DWORD dwTlsIndex, DWORD unknown) { BOOL ret; - TRACE("(%d, %d)\n", dwTlsIndex, unknown); + TRACE("(%ld, %ld)\n", dwTlsIndex, unknown); ret = TlsFree(dwTlsIndex); if (!ret) SetLastError( E_INVALIDARG ); @@ -180,7 +185,7 @@ BOOL WINAPI I_CryptFreeTls(DWORD dwTlsIndex, DWORD unknown) BOOL WINAPI I_CryptGetOssGlobal(DWORD x) { - FIXME("%08x\n", x); + FIXME("%08lx\n", x); return FALSE; } @@ -252,12 +257,6 @@ HCRYPTPROV WINAPI DECLSPEC_HOTPATCH I_CryptGetDefaultCryptProv(ALG_ID algid) BOOL WINAPI I_CryptReadTrustedPublisherDWORDValueFromRegistry(LPCWSTR name, DWORD *value) { - static const WCHAR safer[] = { - 'S','o','f','t','w','a','r','e','\\','P','o','l','i','c','i','e','s','\\', - 'M','i','c','r','o','s','o','f','t','\\','S','y','s','t','e','m', - 'C','e','r','t','i','f','i','c','a','t','e','s','\\', - 'T','r','u','s','t','e','d','P','u','b','l','i','s','h','e','r','\\', - 'S','a','f','e','r',0 }; HKEY key; LONG rc; BOOL ret = FALSE; @@ -265,7 +264,7 @@ BOOL WINAPI I_CryptReadTrustedPublisherDWORDValueFromRegistry(LPCWSTR name, TRACE("(%s, %p)\n", debugstr_w(name), value); *value = 0; - rc = RegCreateKeyW(HKEY_LOCAL_MACHINE, safer, &key); + rc = RegCreateKeyW(HKEY_LOCAL_MACHINE, L"Software\\Policies\\Microsoft\\SystemCertificates\\TrustedPublisher\\Safer", &key); if (rc == ERROR_SUCCESS) { DWORD size = sizeof(DWORD); @@ -281,44 +280,44 @@ DWORD WINAPI I_CryptInstallOssGlobal(DWORD x, DWORD y, DWORD z) { static int ret = 8; ret++; - FIXME("%08x %08x %08x, return value %d\n", x, y, z,ret); + FIXME("%08lx %08lx %08lx, return value %d\n", x, y, z,ret); return ret; } BOOL WINAPI I_CryptInstallAsn1Module(ASN1module_t x, DWORD y, void* z) { - FIXME("(%p %08x %p): stub\n", x, y, z); + FIXME("(%p %08lx %p): stub\n", x, y, z); return TRUE; } BOOL WINAPI I_CryptUninstallAsn1Module(HCRYPTASN1MODULE x) { - FIXME("(%08x): stub\n", x); + FIXME("(%08lx): stub\n", x); return TRUE; } ASN1decoding_t WINAPI I_CryptGetAsn1Decoder(HCRYPTASN1MODULE x) { - FIXME("(%08x): stub\n", x); + FIXME("(%08lx): stub\n", x); return NULL; } ASN1encoding_t WINAPI I_CryptGetAsn1Encoder(HCRYPTASN1MODULE x) { - FIXME("(%08x): stub\n", x); + FIXME("(%08lx): stub\n", x); return NULL; } BOOL WINAPI CryptProtectMemory(void *data, DWORD len, DWORD flags) { static int fixme_once; - if (!fixme_once++) FIXME("(%p %u %08x): stub\n", data, len, flags); + if (!fixme_once++) FIXME("(%p %lu %08lx): stub\n", data, len, flags); return TRUE; } BOOL WINAPI CryptUnprotectMemory(void *data, DWORD len, DWORD flags) { static int fixme_once; - if (!fixme_once++) FIXME("(%p %u %08x): stub\n", data, len, flags); + if (!fixme_once++) FIXME("(%p %lu %08lx): stub\n", data, len, flags); return TRUE; } diff --git a/dll/win32/crypt32/message.c b/dll/win32/crypt32/message.c index 5b77c87bc48..9e7705bddb8 100644 --- a/dll/win32/crypt32/message.c +++ b/dll/win32/crypt32/message.c @@ -31,7 +31,7 @@ HCERTSTORE WINAPI CryptGetMessageCertificates(DWORD dwMsgAndCertEncodingType, { CRYPT_DATA_BLOB blob = { cbSignedBlob, (LPBYTE)pbSignedBlob }; - TRACE("(%08x, %ld, %d08x %p, %d)\n", dwMsgAndCertEncodingType, hCryptProv, + TRACE("(%08lx, %Id, %ld08x %p, %ld)\n", dwMsgAndCertEncodingType, hCryptProv, dwFlags, pbSignedBlob, cbSignedBlob); return CertOpenStore(CERT_STORE_PROV_PKCS7, dwMsgAndCertEncodingType, @@ -44,7 +44,7 @@ LONG WINAPI CryptGetMessageSignerCount(DWORD dwMsgEncodingType, HCRYPTMSG msg; LONG count = -1; - TRACE("(%08x, %p, %d)\n", dwMsgEncodingType, pbSignedBlob, cbSignedBlob); + TRACE("(%08lx, %p, %ld)\n", dwMsgEncodingType, pbSignedBlob, cbSignedBlob); msg = CryptMsgOpenToDecode(dwMsgEncodingType, 0, 0, 0, NULL, NULL); if (msg) @@ -114,7 +114,7 @@ BOOL WINAPI CryptVerifyDetachedMessageSignature( BOOL ret = FALSE; HCRYPTMSG msg; - TRACE("(%p, %d, %p, %d, %d, %p, %p, %p)\n", pVerifyPara, dwSignerIndex, + TRACE("(%p, %ld, %p, %ld, %ld, %p, %p, %p)\n", pVerifyPara, dwSignerIndex, pbDetachedSignBlob, cbDetachedSignBlob, cToBeSigned, rgpbToBeSigned, rgcbToBeSigned, ppSignerCert); @@ -188,7 +188,7 @@ BOOL WINAPI CryptVerifyMessageSignature(PCRYPT_VERIFY_MESSAGE_PARA pVerifyPara, BOOL ret = FALSE; HCRYPTMSG msg; - TRACE("(%p, %d, %p, %d, %p, %p, %p)\n", + TRACE("(%p, %ld, %p, %ld, %p, %p, %p)\n", pVerifyPara, dwSignerIndex, pbSignedBlob, cbSignedBlob, pbDecoded, pcbDecoded, ppSignerCert); @@ -262,7 +262,7 @@ BOOL WINAPI CryptHashMessage(PCRYPT_HASH_MESSAGE_PARA pHashPara, HCRYPTMSG msg; CMSG_HASHED_ENCODE_INFO info; - TRACE("(%p, %d, %d, %p, %p, %p, %p, %p, %p)\n", pHashPara, fDetachedHash, + TRACE("(%p, %d, %ld, %p, %p, %p, %p, %p, %p)\n", pHashPara, fDetachedHash, cToBeHashed, rgpbToBeHashed, rgcbToBeHashed, pbHashedBlob, pcbHashedBlob, pbComputedHash, pcbComputedHash); @@ -314,7 +314,7 @@ BOOL WINAPI CryptVerifyDetachedMessageHash(PCRYPT_HASH_MESSAGE_PARA pHashPara, HCRYPTMSG msg; BOOL ret = FALSE; - TRACE("(%p, %p, %d, %d, %p, %p, %p, %p)\n", pHashPara, pbDetachedHashBlob, + TRACE("(%p, %p, %ld, %ld, %p, %p, %p, %p)\n", pHashPara, pbDetachedHashBlob, cbDetachedHashBlob, cToBeHashed, rgpbToBeHashed, rgcbToBeHashed, pbComputedHash, pcbComputedHash); @@ -368,7 +368,7 @@ BOOL WINAPI CryptVerifyMessageHash(PCRYPT_HASH_MESSAGE_PARA pHashPara, HCRYPTMSG msg; BOOL ret = FALSE; - TRACE("(%p, %p, %d, %p, %p, %p, %p)\n", pHashPara, pbHashedBlob, + TRACE("(%p, %p, %ld, %p, %p, %p, %p)\n", pHashPara, pbHashedBlob, cbHashedBlob, pbToBeHashed, pcbToBeHashed, pbComputedHash, pcbComputedHash); @@ -416,7 +416,7 @@ BOOL WINAPI CryptSignMessage(PCRYPT_SIGN_MESSAGE_PARA pSignPara, CMSG_SIGNER_ENCODE_INFO signer; HCRYPTMSG msg = 0; - TRACE("(%p, %d, %d, %p, %p, %p, %p)\n", pSignPara, fDetachedSignature, + TRACE("(%p, %d, %ld, %p, %p, %p, %p)\n", pSignPara, fDetachedSignature, cToBeSigned, rgpbToBeSigned, rgcbToBeSigned, pbSignedBlob, pcbSignedBlob); if (pSignPara->cbSize != sizeof(CRYPT_SIGN_MESSAGE_PARA) || @@ -529,7 +529,7 @@ BOOL WINAPI CryptEncryptMessage(PCRYPT_ENCRYPT_MESSAGE_PARA pEncryptPara, CMSG_ENVELOPED_ENCODE_INFO envelopedInfo; HCRYPTMSG msg = 0; - TRACE("(%p, %d, %p, %p, %d, %p, %p)\n", pEncryptPara, cRecipientCert, + TRACE("(%p, %ld, %p, %p, %ld, %p, %p)\n", pEncryptPara, cRecipientCert, rgpRecipientCert, pbToBeEncrypted, cbToBeEncrypted, pbEncryptedBlob, pcbEncryptedBlob); diff --git a/dll/win32/crypt32/msg.c b/dll/win32/crypt32/msg.c index 9a0e4e899e1..3d12b490a4a 100644 --- a/dll/win32/crypt32/msg.c +++ b/dll/win32/crypt32/msg.c @@ -16,15 +16,15 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "config.h" -#include "wine/port.h" - #include -#define NONAMELESSUNION + #include "windef.h" #include "winbase.h" #include "wincrypt.h" #include "snmp.h" +#ifdef __REACTOS__ +#include +#endif #include "wine/debug.h" #include "wine/exception.h" @@ -46,10 +46,28 @@ typedef BOOL (*CryptMsgUpdateFunc)(HCRYPTMSG hCryptMsg, const BYTE *pbData, typedef BOOL (*CryptMsgControlFunc)(HCRYPTMSG hCryptMsg, DWORD dwFlags, DWORD dwCtrlType, const void *pvCtrlPara); +static BOOL extract_hash(HCRYPTHASH hash, BYTE **data, DWORD *size) +{ + DWORD sz; + + *data = NULL; + sz = sizeof(*size); + if (!CryptGetHashParam(hash, HP_HASHSIZE, (BYTE *)size, &sz, 0)) return FALSE; + if (!(*data = CryptMemAlloc(*size))) + { + ERR("No memory.\n"); + return FALSE; + } + if (CryptGetHashParam(hash, HP_HASHVAL, *data, size, 0)) return TRUE; + CryptMemFree(*data); + *data = NULL; + return FALSE; +} + static BOOL CRYPT_DefaultMsgControl(HCRYPTMSG hCryptMsg, DWORD dwFlags, DWORD dwCtrlType, const void *pvCtrlPara) { - TRACE("(%p, %08x, %d, %p)\n", hCryptMsg, dwFlags, dwCtrlType, pvCtrlPara); + TRACE("(%p, %08lx, %ld, %p)\n", hCryptMsg, dwFlags, dwCtrlType, pvCtrlPara); SetLastError(E_INVALIDARG); return FALSE; } @@ -415,18 +433,7 @@ static BOOL CRYPT_EncodePKCSDigestedData(CHashEncodeMsg *msg, void *pvData, &digestedData.ContentInfo.Content.cbData); } if (msg->base.state == MsgStateFinalized) - { - size = sizeof(DWORD); - ret = CryptGetHashParam(msg->hash, HP_HASHSIZE, - (LPBYTE)&digestedData.hash.cbData, &size, 0); - if (ret) - { - digestedData.hash.pbData = CryptMemAlloc( - digestedData.hash.cbData); - ret = CryptGetHashParam(msg->hash, HP_HASHVAL, - digestedData.hash.pbData, &digestedData.hash.cbData, 0); - } - } + ret = extract_hash(msg->hash, &digestedData.hash.pbData, &digestedData.hash.cbData); if (ret) ret = CRYPT_AsnEncodePKCSDigestedData(&digestedData, pvData, pcbData); @@ -442,7 +449,7 @@ static BOOL CHashEncodeMsg_GetParam(HCRYPTMSG hCryptMsg, DWORD dwParamType, CHashEncodeMsg *msg = hCryptMsg; BOOL ret = FALSE; - TRACE("(%p, %d, %d, %p, %p)\n", hCryptMsg, dwParamType, dwIndex, + TRACE("(%p, %ld, %ld, %p, %p)\n", hCryptMsg, dwParamType, dwIndex, pvData, pcbData); switch (dwParamType) @@ -509,7 +516,7 @@ static BOOL CHashEncodeMsg_Update(HCRYPTMSG hCryptMsg, const BYTE *pbData, CHashEncodeMsg *msg = hCryptMsg; BOOL ret = FALSE; - TRACE("(%p, %p, %d, %d)\n", hCryptMsg, pbData, cbData, fFinal); + TRACE("(%p, %p, %ld, %d)\n", hCryptMsg, pbData, cbData, fFinal); if (msg->base.state == MsgStateFinalized) SetLastError(CRYPT_E_MSG_ERROR); @@ -661,19 +668,19 @@ static BOOL CRYPT_IsValidSigner(const CMSG_SIGNER_ENCODE_INFO_WITH_CMS *signer) } break; case CERT_ID_ISSUER_SERIAL_NUMBER: - if (!signer->SignerId.u.IssuerSerialNumber.SerialNumber.cbData) + if (!signer->SignerId.IssuerSerialNumber.SerialNumber.cbData) { SetLastError(E_INVALIDARG); return FALSE; } - if (!signer->SignerId.u.IssuerSerialNumber.Issuer.cbData) + if (!signer->SignerId.IssuerSerialNumber.Issuer.cbData) { SetLastError(E_INVALIDARG); return FALSE; } break; case CERT_ID_KEY_IDENTIFIER: - if (!signer->SignerId.u.KeyId.cbData) + if (!signer->SignerId.KeyId.cbData) { SetLastError(E_INVALIDARG); return FALSE; @@ -802,11 +809,11 @@ static BOOL CSignerInfo_Construct(CMSG_CMS_SIGNER_INFO *info, if (in->cbSize == sizeof(CMSG_SIGNER_ENCODE_INFO)) { info->dwVersion = CMSG_SIGNER_INFO_V1; - ret = CRYPT_ConstructBlob(&info->SignerId.u.IssuerSerialNumber.Issuer, + ret = CRYPT_ConstructBlob(&info->SignerId.IssuerSerialNumber.Issuer, &in->pCertInfo->Issuer); if (ret) ret = CRYPT_ConstructBlob( - &info->SignerId.u.IssuerSerialNumber.SerialNumber, + &info->SignerId.IssuerSerialNumber.SerialNumber, &in->pCertInfo->SerialNumber); info->SignerId.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER; info->HashEncryptionAlgorithm.pszObjId = @@ -825,11 +832,11 @@ static BOOL CSignerInfo_Construct(CMSG_CMS_SIGNER_INFO *info, if (!in->SignerId.dwIdChoice) { info->dwVersion = CMSG_SIGNER_INFO_V1; - ret = CRYPT_ConstructBlob(&info->SignerId.u.IssuerSerialNumber.Issuer, + ret = CRYPT_ConstructBlob(&info->SignerId.IssuerSerialNumber.Issuer, &in->pCertInfo->Issuer); if (ret) ret = CRYPT_ConstructBlob( - &info->SignerId.u.IssuerSerialNumber.SerialNumber, + &info->SignerId.IssuerSerialNumber.SerialNumber, &in->pCertInfo->SerialNumber); info->SignerId.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER; } @@ -837,20 +844,20 @@ static BOOL CSignerInfo_Construct(CMSG_CMS_SIGNER_INFO *info, { info->dwVersion = CMSG_SIGNER_INFO_V1; info->SignerId.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER; - ret = CRYPT_ConstructBlob(&info->SignerId.u.IssuerSerialNumber.Issuer, - &in->SignerId.u.IssuerSerialNumber.Issuer); + ret = CRYPT_ConstructBlob(&info->SignerId.IssuerSerialNumber.Issuer, + &in->SignerId.IssuerSerialNumber.Issuer); if (ret) ret = CRYPT_ConstructBlob( - &info->SignerId.u.IssuerSerialNumber.SerialNumber, - &in->SignerId.u.IssuerSerialNumber.SerialNumber); + &info->SignerId.IssuerSerialNumber.SerialNumber, + &in->SignerId.IssuerSerialNumber.SerialNumber); } else { /* Implicitly dwIdChoice == CERT_ID_KEY_IDENTIFIER */ info->dwVersion = CMSG_SIGNER_INFO_V3; info->SignerId.dwIdChoice = CERT_ID_KEY_IDENTIFIER; - ret = CRYPT_ConstructBlob(&info->SignerId.u.KeyId, - &in->SignerId.u.KeyId); + ret = CRYPT_ConstructBlob(&info->SignerId.KeyId, + &in->SignerId.KeyId); } pEncrAlg = in->HashEncryptionAlgorithm.pszObjId ? &in->HashEncryptionAlgorithm : @@ -882,11 +889,11 @@ static void CSignerInfo_Free(CMSG_CMS_SIGNER_INFO *info) if (info->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER) { - CryptMemFree(info->SignerId.u.IssuerSerialNumber.Issuer.pbData); - CryptMemFree(info->SignerId.u.IssuerSerialNumber.SerialNumber.pbData); + CryptMemFree(info->SignerId.IssuerSerialNumber.Issuer.pbData); + CryptMemFree(info->SignerId.IssuerSerialNumber.SerialNumber.pbData); } else - CryptMemFree(info->SignerId.u.KeyId.pbData); + CryptMemFree(info->SignerId.KeyId.pbData); CryptMemFree(info->HashAlgorithm.Parameters.pbData); CryptMemFree(info->HashEncryptionAlgorithm.Parameters.pbData); CryptMemFree(info->EncryptedHash.pbData); @@ -922,7 +929,7 @@ typedef struct _CSignedMsgData } CSignedMsgData; /* Constructs the signer handles for the signerIndex'th signer of msg_data. - * Assumes signerIndex is a valid idnex, and that msg_data's info has already + * Assumes signerIndex is a valid index, and that msg_data's info has already * been constructed. */ static BOOL CSignedMsgData_ConstructSignerHandles(CSignedMsgData *msg_data, @@ -1028,35 +1035,23 @@ static BOOL CSignedMsgData_AppendMessageDigestAttribute( CSignedMsgData *msg_data, DWORD signerIndex) { BOOL ret; - DWORD size; CRYPT_HASH_BLOB hash = { 0, NULL }, encodedHash = { 0, NULL }; char messageDigest[] = szOID_RSA_messageDigest; CRYPT_ATTRIBUTE messageDigestAttr = { messageDigest, 1, &encodedHash }; - size = sizeof(DWORD); - ret = CryptGetHashParam( - msg_data->signerHandles[signerIndex].contentHash, HP_HASHSIZE, - (LPBYTE)&hash.cbData, &size, 0); + if (!(ret = extract_hash(msg_data->signerHandles[signerIndex].contentHash, &hash.pbData, &hash.cbData))) + return FALSE; + + ret = CRYPT_AsnEncodeOctets(0, NULL, &hash, CRYPT_ENCODE_ALLOC_FLAG, NULL, (LPBYTE)&encodedHash.pbData, + &encodedHash.cbData); if (ret) { - hash.pbData = CryptMemAlloc(hash.cbData); - ret = CryptGetHashParam( - msg_data->signerHandles[signerIndex].contentHash, HP_HASHVAL, - hash.pbData, &hash.cbData, 0); - if (ret) - { - ret = CRYPT_AsnEncodeOctets(0, NULL, &hash, CRYPT_ENCODE_ALLOC_FLAG, - NULL, (LPBYTE)&encodedHash.pbData, &encodedHash.cbData); - if (ret) - { - ret = CRYPT_AppendAttribute( - &msg_data->info->rgSignerInfo[signerIndex].AuthAttrs, - &messageDigestAttr); - LocalFree(encodedHash.pbData); - } - } - CryptMemFree(hash.pbData); + ret = CRYPT_AppendAttribute( + &msg_data->info->rgSignerInfo[signerIndex].AuthAttrs, + &messageDigestAttr); + LocalFree(encodedHash.pbData); } + CryptMemFree(hash.pbData); return ret; } @@ -1250,12 +1245,11 @@ static BOOL CSignedEncodeMsg_GetParam(HCRYPTMSG hCryptMsg, DWORD dwParamType, { CRYPT_SIGNED_INFO info; BOOL freeContent = FALSE; + char oid_rsa_data[] = szOID_RSA_data; info = *msg->msg_data.info; if (!msg->innerOID || !strcmp(msg->innerOID, szOID_RSA_data)) { - char oid_rsa_data[] = szOID_RSA_data; - /* Quirk: OID is only encoded messages if an update has happened */ if (msg->base.state != MsgStateInit) info.content.pszObjId = oid_rsa_data; @@ -1633,7 +1627,7 @@ static BOOL CRYPT_ExportEncryptedKey(CMSG_CONTENT_ENCRYPT_INFO *info, DWORD i, PFN_CMSG_EXPORT_KEY_TRANS exportKeyFunc = NULL; HCRYPTOIDFUNCADDR hFunc = NULL; CMSG_KEY_TRANS_RECIPIENT_ENCODE_INFO *encodeInfo = - info->rgCmsRecipients[i].u.pKeyTrans; + info->rgCmsRecipients[i].pKeyTrans; CMSG_KEY_TRANS_ENCRYPT_INFO encryptInfo; BOOL ret; @@ -1669,12 +1663,12 @@ static BOOL CRYPT_ExportEncryptedKey(CMSG_CONTENT_ENCRYPT_INFO *info, DWORD i, static LPVOID WINAPI mem_alloc(size_t size) { - return HeapAlloc(GetProcessHeap(), 0, size); + return CryptMemAlloc(size); } static VOID WINAPI mem_free(LPVOID pv) { - HeapFree(GetProcessHeap(), 0, pv); + CryptMemFree(pv); } @@ -1705,7 +1699,7 @@ static BOOL CContentEncryptInfo_Construct(CMSG_CONTENT_ENCRYPT_INFO *info, info->rgCmsRecipients[i].dwRecipientChoice = CMSG_KEY_TRANS_RECIPIENT; encodeInfo = CryptMemAlloc(sizeof(*encodeInfo)); - info->rgCmsRecipients[i].u.pKeyTrans = encodeInfo; + info->rgCmsRecipients[i].pKeyTrans = encodeInfo; if (encodeInfo) { encodeInfo->cbSize = sizeof(*encodeInfo); @@ -1720,11 +1714,11 @@ static BOOL CContentEncryptInfo_Construct(CMSG_CONTENT_ENCRYPT_INFO *info, &cert->SubjectPublicKeyInfo.PublicKey); if (ret) ret = CRYPT_ConstructBlob( - &encodeInfo->RecipientId.u.IssuerSerialNumber.Issuer, + &encodeInfo->RecipientId.IssuerSerialNumber.Issuer, &cert->Issuer); if (ret) ret = CRYPT_ConstructBlob( - &encodeInfo->RecipientId.u.IssuerSerialNumber.SerialNumber, + &encodeInfo->RecipientId.IssuerSerialNumber.SerialNumber, &cert->SerialNumber); } else @@ -1750,15 +1744,15 @@ static void CContentEncryptInfo_Free(CMSG_CONTENT_ENCRYPT_INFO *info) for (i = 0; i < info->cRecipients; ++i) { CMSG_KEY_TRANS_RECIPIENT_ENCODE_INFO *encodeInfo = - info->rgCmsRecipients[i].u.pKeyTrans; + info->rgCmsRecipients[i].pKeyTrans; CryptMemFree(encodeInfo->KeyEncryptionAlgorithm.pszObjId); CryptMemFree(encodeInfo->KeyEncryptionAlgorithm.Parameters.pbData); CryptMemFree(encodeInfo->RecipientPublicKey.pbData); CryptMemFree( - encodeInfo->RecipientId.u.IssuerSerialNumber.Issuer.pbData); + encodeInfo->RecipientId.IssuerSerialNumber.Issuer.pbData); CryptMemFree( - encodeInfo->RecipientId.u.IssuerSerialNumber.SerialNumber.pbData); + encodeInfo->RecipientId.IssuerSerialNumber.SerialNumber.pbData); CryptMemFree(encodeInfo); } CryptMemFree(info->rgCmsRecipients); @@ -1772,11 +1766,11 @@ static BOOL CRecipientInfo_Construct(CMSG_KEY_TRANS_RECIPIENT_INFO *info, info->dwVersion = CMSG_KEY_TRANS_PKCS_1_5_VERSION; info->RecipientId.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER; - ret = CRYPT_ConstructBlob(&info->RecipientId.u.IssuerSerialNumber.Issuer, + ret = CRYPT_ConstructBlob(&info->RecipientId.IssuerSerialNumber.Issuer, &cert->Issuer); if (ret) ret = CRYPT_ConstructBlob( - &info->RecipientId.u.IssuerSerialNumber.SerialNumber, + &info->RecipientId.IssuerSerialNumber.SerialNumber, &cert->SerialNumber); if (ret) ret = CRYPT_ConstructAlgorithmId(&info->KeyEncryptionAlgorithm, @@ -1788,8 +1782,8 @@ static BOOL CRecipientInfo_Construct(CMSG_KEY_TRANS_RECIPIENT_INFO *info, static void CRecipientInfo_Free(CMSG_KEY_TRANS_RECIPIENT_INFO *info) { - CryptMemFree(info->RecipientId.u.IssuerSerialNumber.Issuer.pbData); - CryptMemFree(info->RecipientId.u.IssuerSerialNumber.SerialNumber.pbData); + CryptMemFree(info->RecipientId.IssuerSerialNumber.Issuer.pbData); + CryptMemFree(info->RecipientId.IssuerSerialNumber.SerialNumber.pbData); CryptMemFree(info->KeyEncryptionAlgorithm.pszObjId); CryptMemFree(info->KeyEncryptionAlgorithm.Parameters.pbData); CryptMemFree(info->EncryptedKey.pbData); @@ -2037,7 +2031,7 @@ HCRYPTMSG WINAPI CryptMsgOpenToEncode(DWORD dwMsgEncodingType, DWORD dwFlags, { HCRYPTMSG msg = NULL; - TRACE("(%08x, %08x, %08x, %p, %s, %p)\n", dwMsgEncodingType, dwFlags, + TRACE("(%08lx, %08lx, %08lx, %p, %s, %p)\n", dwMsgEncodingType, dwFlags, dwMsgType, pvMsgEncodeInfo, debugstr_a(pszInnerContentObjID), pStreamInfo); if (GET_CMSG_ENCODING_TYPE(dwMsgEncodingType) != PKCS_7_ASN_ENCODING) @@ -2474,13 +2468,13 @@ static BOOL CDecodeMsg_Update(HCRYPTMSG hCryptMsg, const BYTE *pbData, CDecodeMsg *msg = hCryptMsg; BOOL ret = FALSE; - TRACE("(%p, %p, %d, %d)\n", hCryptMsg, pbData, cbData, fFinal); + TRACE("(%p, %p, %ld, %d)\n", hCryptMsg, pbData, cbData, fFinal); if (msg->base.state == MsgStateFinalized) SetLastError(CRYPT_E_MSG_ERROR); else if (msg->base.streamed) { - FIXME("(%p, %p, %d, %d): streamed update stub\n", hCryptMsg, pbData, + FIXME("(%p, %p, %ld, %d): streamed update stub\n", hCryptMsg, pbData, cbData, fFinal); switch (msg->base.state) { @@ -2731,16 +2725,16 @@ static BOOL CRYPT_CopySignerInfo(void *pvData, DWORD *pcbData, DWORD size = sizeof(CMSG_SIGNER_INFO), rdnSize = 0; BOOL ret; - TRACE("(%p, %d, %p)\n", pvData, pvData ? *pcbData : 0, in); + TRACE("(%p, %ld, %p)\n", pvData, pvData ? *pcbData : 0, in); if (in->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER) { - size += in->SignerId.u.IssuerSerialNumber.Issuer.cbData; - size += in->SignerId.u.IssuerSerialNumber.SerialNumber.cbData; + size += in->SignerId.IssuerSerialNumber.Issuer.cbData; + size += in->SignerId.IssuerSerialNumber.SerialNumber.cbData; } else { - rdnSize = CRYPT_SizeOfKeyIdAsIssuerAndSerial(&in->SignerId.u.KeyId); + rdnSize = CRYPT_SizeOfKeyIdAsIssuerAndSerial(&in->SignerId.KeyId); size += rdnSize; } if (in->HashAlgorithm.pszObjId) @@ -2773,13 +2767,13 @@ static BOOL CRYPT_CopySignerInfo(void *pvData, DWORD *pcbData, if (in->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER) { CRYPT_CopyBlob(&out->Issuer, - &in->SignerId.u.IssuerSerialNumber.Issuer, &nextData); + &in->SignerId.IssuerSerialNumber.Issuer, &nextData); CRYPT_CopyBlob(&out->SerialNumber, - &in->SignerId.u.IssuerSerialNumber.SerialNumber, &nextData); + &in->SignerId.IssuerSerialNumber.SerialNumber, &nextData); } else ret = CRYPT_CopyKeyIdAsIssuerAndSerial(&out->Issuer, &out->SerialNumber, - &in->SignerId.u.KeyId, rdnSize, &nextData); + &in->SignerId.KeyId, rdnSize, &nextData); if (ret) { CRYPT_CopyAlgorithmId(&out->HashAlgorithm, &in->HashAlgorithm, @@ -2803,15 +2797,15 @@ static BOOL CRYPT_CopyCMSSignerInfo(void *pvData, DWORD *pcbData, DWORD size = sizeof(CMSG_CMS_SIGNER_INFO); BOOL ret; - TRACE("(%p, %d, %p)\n", pvData, pvData ? *pcbData : 0, in); + TRACE("(%p, %ld, %p)\n", pvData, pvData ? *pcbData : 0, in); if (in->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER) { - size += in->SignerId.u.IssuerSerialNumber.Issuer.cbData; - size += in->SignerId.u.IssuerSerialNumber.SerialNumber.cbData; + size += in->SignerId.IssuerSerialNumber.Issuer.cbData; + size += in->SignerId.IssuerSerialNumber.SerialNumber.cbData; } else - size += in->SignerId.u.KeyId.cbData; + size += in->SignerId.KeyId.cbData; if (in->HashAlgorithm.pszObjId) size += strlen(in->HashAlgorithm.pszObjId) + 1; size += in->HashAlgorithm.Parameters.cbData; @@ -2843,13 +2837,13 @@ static BOOL CRYPT_CopyCMSSignerInfo(void *pvData, DWORD *pcbData, out->SignerId.dwIdChoice = in->SignerId.dwIdChoice; if (in->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER) { - CRYPT_CopyBlob(&out->SignerId.u.IssuerSerialNumber.Issuer, - &in->SignerId.u.IssuerSerialNumber.Issuer, &nextData); - CRYPT_CopyBlob(&out->SignerId.u.IssuerSerialNumber.SerialNumber, - &in->SignerId.u.IssuerSerialNumber.SerialNumber, &nextData); + CRYPT_CopyBlob(&out->SignerId.IssuerSerialNumber.Issuer, + &in->SignerId.IssuerSerialNumber.Issuer, &nextData); + CRYPT_CopyBlob(&out->SignerId.IssuerSerialNumber.SerialNumber, + &in->SignerId.IssuerSerialNumber.SerialNumber, &nextData); } else - CRYPT_CopyBlob(&out->SignerId.u.KeyId, &in->SignerId.u.KeyId, &nextData); + CRYPT_CopyBlob(&out->SignerId.KeyId, &in->SignerId.KeyId, &nextData); CRYPT_CopyAlgorithmId(&out->HashAlgorithm, &in->HashAlgorithm, &nextData); CRYPT_CopyAlgorithmId(&out->HashEncryptionAlgorithm, @@ -2870,16 +2864,16 @@ static BOOL CRYPT_CopySignerCertInfo(void *pvData, DWORD *pcbData, DWORD size = sizeof(CERT_INFO), rdnSize = 0; BOOL ret; - TRACE("(%p, %d, %p)\n", pvData, pvData ? *pcbData : 0, in); + TRACE("(%p, %ld, %p)\n", pvData, pvData ? *pcbData : 0, in); if (in->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER) { - size += in->SignerId.u.IssuerSerialNumber.Issuer.cbData; - size += in->SignerId.u.IssuerSerialNumber.SerialNumber.cbData; + size += in->SignerId.IssuerSerialNumber.Issuer.cbData; + size += in->SignerId.IssuerSerialNumber.SerialNumber.cbData; } else { - rdnSize = CRYPT_SizeOfKeyIdAsIssuerAndSerial(&in->SignerId.u.KeyId); + rdnSize = CRYPT_SizeOfKeyIdAsIssuerAndSerial(&in->SignerId.KeyId); size += rdnSize; } if (!pvData) @@ -2902,14 +2896,14 @@ static BOOL CRYPT_CopySignerCertInfo(void *pvData, DWORD *pcbData, if (in->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER) { CRYPT_CopyBlob(&out->Issuer, - &in->SignerId.u.IssuerSerialNumber.Issuer, &nextData); + &in->SignerId.IssuerSerialNumber.Issuer, &nextData); CRYPT_CopyBlob(&out->SerialNumber, - &in->SignerId.u.IssuerSerialNumber.SerialNumber, &nextData); + &in->SignerId.IssuerSerialNumber.SerialNumber, &nextData); ret = TRUE; } else ret = CRYPT_CopyKeyIdAsIssuerAndSerial(&out->Issuer, &out->SerialNumber, - &in->SignerId.u.KeyId, rdnSize, &nextData); + &in->SignerId.KeyId, rdnSize, &nextData); } TRACE("returning %d\n", ret); return ret; @@ -2921,7 +2915,7 @@ static BOOL CRYPT_CopyRecipientInfo(void *pvData, DWORD *pcbData, DWORD size = sizeof(CERT_INFO); BOOL ret; - TRACE("(%p, %d, %p)\n", pvData, pvData ? *pcbData : 0, in); + TRACE("(%p, %ld, %p)\n", pvData, pvData ? *pcbData : 0, in); size += in->SerialNumber.cbData; size += in->Issuer.cbData; @@ -2983,7 +2977,7 @@ static BOOL CDecodeEnvelopedMsg_GetParam(CDecodeMsg *msg, DWORD dwParamType, &msg->u.enveloped_data.data->rgRecipientInfo[dwIndex]; ret = CRYPT_CopyRecipientInfo(pvData, pcbData, - &recipientInfo->RecipientId.u.IssuerSerialNumber); + &recipientInfo->RecipientId.IssuerSerialNumber); } else SetLastError(CRYPT_E_INVALID_INDEX); @@ -2992,12 +2986,38 @@ static BOOL CDecodeEnvelopedMsg_GetParam(CDecodeMsg *msg, DWORD dwParamType, SetLastError(CRYPT_E_INVALID_MSG_TYPE); break; default: - FIXME("unimplemented for %d\n", dwParamType); + FIXME("unimplemented for %ld\n", dwParamType); SetLastError(CRYPT_E_INVALID_MSG_TYPE); } return ret; } +static BOOL CRYPT_CopyAttr(void *pvData, DWORD *pcbData, const CRYPT_ATTRIBUTES *attr) +{ + DWORD size; + BOOL ret; + + TRACE("(%p, %ld, %p)\n", pvData, pvData ? *pcbData : 0, attr); + + size = CRYPT_SizeOfAttributes(attr); + if (!pvData) + { + *pcbData = size; + ret = TRUE; + } + else if (*pcbData < size) + { + *pcbData = size; + SetLastError(ERROR_MORE_DATA); + ret = FALSE; + } + else + ret = CRYPT_ConstructAttributes(pvData, attr); + + TRACE("returning %d\n", ret); + return ret; +} + static BOOL CDecodeSignedMsg_GetParam(CDecodeMsg *msg, DWORD dwParamType, DWORD dwIndex, void *pvData, DWORD *pcbData) { @@ -3128,6 +3148,12 @@ static BOOL CDecodeSignedMsg_GetParam(CDecodeMsg *msg, DWORD dwParamType, else SetLastError(CRYPT_E_INVALID_MSG_TYPE); break; + case CMSG_ENCODED_MESSAGE: + if (msg->msg_data.pbData) + ret = CRYPT_CopyParam(pvData, pcbData, msg->msg_data.pbData, msg->msg_data.cbData); + else + SetLastError(CRYPT_E_INVALID_MSG_TYPE); + break; case CMSG_ENCODED_SIGNER: if (msg->u.signed_data.info) { @@ -3171,8 +3197,32 @@ static BOOL CDecodeSignedMsg_GetParam(CDecodeMsg *msg, DWORD dwParamType, else SetLastError(CRYPT_E_INVALID_MSG_TYPE); break; + case CMSG_SIGNER_AUTH_ATTR_PARAM: + if (msg->u.signed_data.info) + { + if (dwIndex >= msg->u.signed_data.info->cSignerInfo) + SetLastError(CRYPT_E_INVALID_INDEX); + else + ret = CRYPT_CopyAttr(pvData, pcbData, + &msg->u.signed_data.info->rgSignerInfo[dwIndex].AuthAttrs); + } + else + SetLastError(CRYPT_E_INVALID_MSG_TYPE); + break; + case CMSG_SIGNER_UNAUTH_ATTR_PARAM: + if (msg->u.signed_data.info) + { + if (dwIndex >= msg->u.signed_data.info->cSignerInfo) + SetLastError(CRYPT_E_INVALID_INDEX); + else + ret = CRYPT_CopyAttr(pvData, pcbData, + &msg->u.signed_data.info->rgSignerInfo[dwIndex].UnauthAttrs); + } + else + SetLastError(CRYPT_E_INVALID_MSG_TYPE); + break; default: - FIXME("unimplemented for %d\n", dwParamType); + FIXME("unimplemented for %ld\n", dwParamType); SetLastError(CRYPT_E_INVALID_MSG_TYPE); } return ret; @@ -3268,24 +3318,56 @@ static BOOL CDecodeHashMsg_VerifyHash(CDecodeMsg *msg) return ret; } +static BOOL cng_verify_msg_signature(CMSG_CMS_SIGNER_INFO *signer, HCRYPTHASH hash, CERT_PUBLIC_KEY_INFO *key_info) +{ + BYTE *hash_value, *sig_value = NULL; + DWORD hash_len, sig_len; + BCRYPT_KEY_HANDLE key; + BOOL ret = FALSE; + NTSTATUS status; + + if (!CryptImportPublicKeyInfoEx2(X509_ASN_ENCODING, key_info, 0, NULL, &key)) return FALSE; + if (!extract_hash(hash, &hash_value, &hash_len)) goto done; + if (!cng_prepare_signature(key_info->Algorithm.pszObjId, signer->EncryptedHash.pbData, + signer->EncryptedHash.cbData, &sig_value, &sig_len)) goto done; + status = BCryptVerifySignature(key, NULL, hash_value, hash_len, sig_value, sig_len, 0); + if (status) + { + FIXME("Failed to verify signature: %08lx.\n", status); + SetLastError(RtlNtStatusToDosError(status)); + } + ret = !status; +done: + CryptMemFree(sig_value); + CryptMemFree(hash_value); + BCryptDestroyKey(key); + return ret; +} + static BOOL CDecodeSignedMsg_VerifySignatureWithKey(CDecodeMsg *msg, HCRYPTPROV prov, DWORD signerIndex, PCERT_PUBLIC_KEY_INFO keyInfo) { + HCRYPTHASH hash; HCRYPTKEY key; BOOL ret; + ALG_ID alg_id = 0; + + if (msg->u.signed_data.info->rgSignerInfo[signerIndex].AuthAttrs.cAttr) + hash = msg->u.signed_data.signerHandles[signerIndex].authAttrHash; + else + hash = msg->u.signed_data.signerHandles[signerIndex].contentHash; + + if (keyInfo->Algorithm.pszObjId) alg_id = CertOIDToAlgId(keyInfo->Algorithm.pszObjId); + if (alg_id == CALG_OID_INFO_PARAMETERS || alg_id == CALG_OID_INFO_CNG_ONLY) + return cng_verify_msg_signature(&msg->u.signed_data.info->rgSignerInfo[signerIndex], hash, keyInfo); if (!prov) prov = msg->crypt_prov; ret = CryptImportPublicKeyInfo(prov, X509_ASN_ENCODING, keyInfo, &key); if (ret) { - HCRYPTHASH hash; CRYPT_HASH_BLOB reversedHash; - if (msg->u.signed_data.info->rgSignerInfo[signerIndex].AuthAttrs.cAttr) - hash = msg->u.signed_data.signerHandles[signerIndex].authAttrHash; - else - hash = msg->u.signed_data.signerHandles[signerIndex].contentHash; ret = CRYPT_ConstructBlob(&reversedHash, &msg->u.signed_data.info->rgSignerInfo[signerIndex].EncryptedHash); if (ret) @@ -3318,12 +3400,12 @@ static BOOL CDecodeSignedMsg_VerifySignature(CDecodeMsg *msg, PCERT_INFO info) if (signerInfo->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER) { ret = CertCompareCertificateName(X509_ASN_ENCODING, - &signerInfo->SignerId.u.IssuerSerialNumber.Issuer, + &signerInfo->SignerId.IssuerSerialNumber.Issuer, &info->Issuer); if (ret) { ret = CertCompareIntegerBlob( - &signerInfo->SignerId.u.IssuerSerialNumber.SerialNumber, + &signerInfo->SignerId.IssuerSerialNumber.SerialNumber, &info->SerialNumber); if (ret) break; @@ -3331,7 +3413,7 @@ static BOOL CDecodeSignedMsg_VerifySignature(CDecodeMsg *msg, PCERT_INFO info) } else { - FIXME("signer %d: unimplemented for key id\n", i); + FIXME("signer %ld: unimplemented for key id\n", i); } } if (ret) @@ -3371,7 +3453,7 @@ static BOOL CDecodeSignedMsg_VerifySignatureEx(CDecodeMsg *msg, break; } default: - FIXME("unimplemented for signer type %d\n", para->dwSignerType); + FIXME("unimplemented for signer type %ld\n", para->dwSignerType); SetLastError(CRYPT_E_SIGNER_NOT_FOUND); } } @@ -3555,7 +3637,7 @@ HCRYPTMSG WINAPI CryptMsgOpenToDecode(DWORD dwMsgEncodingType, DWORD dwFlags, { CDecodeMsg *msg; - TRACE("(%08x, %08x, %08x, %08lx, %p, %p)\n", dwMsgEncodingType, + TRACE("(%08lx, %08lx, %08lx, %08Ix, %p, %p)\n", dwMsgEncodingType, dwFlags, dwMsgType, hCryptProv, pRecipientInfo, pStreamInfo); if (GET_CMSG_ENCODING_TYPE(dwMsgEncodingType) != PKCS_7_ASN_ENCODING) @@ -3618,7 +3700,7 @@ BOOL WINAPI CryptMsgUpdate(HCRYPTMSG hCryptMsg, const BYTE *pbData, { CryptMsgBase *msg = hCryptMsg; - TRACE("(%p, %p, %d, %d)\n", hCryptMsg, pbData, cbData, fFinal); + TRACE("(%p, %p, %ld, %d)\n", hCryptMsg, pbData, cbData, fFinal); return msg->update(hCryptMsg, pbData, cbData, fFinal); } @@ -3628,7 +3710,7 @@ BOOL WINAPI CryptMsgGetParam(HCRYPTMSG hCryptMsg, DWORD dwParamType, { CryptMsgBase *msg = hCryptMsg; - TRACE("(%p, %d, %d, %p, %p)\n", hCryptMsg, dwParamType, dwIndex, + TRACE("(%p, %ld, %ld, %p, %p)\n", hCryptMsg, dwParamType, dwIndex, pvData, pcbData); return msg->get_param(hCryptMsg, dwParamType, dwIndex, pvData, pcbData); } @@ -3638,7 +3720,7 @@ BOOL WINAPI CryptMsgControl(HCRYPTMSG hCryptMsg, DWORD dwFlags, { CryptMsgBase *msg = hCryptMsg; - TRACE("(%p, %08x, %d, %p)\n", hCryptMsg, dwFlags, dwCtrlType, + TRACE("(%p, %08lx, %ld, %p)\n", hCryptMsg, dwFlags, dwCtrlType, pvCtrlPara); return msg->control(hCryptMsg, dwFlags, dwCtrlType, pvCtrlPara); } @@ -3675,7 +3757,7 @@ BOOL WINAPI CryptMsgGetAndVerifySigner(HCRYPTMSG hCryptMsg, DWORD cSignerStore, PCCERT_CONTEXT signerCert = NULL; BOOL ret = FALSE; - TRACE("(%p, %d, %p, %08x, %p, %p)\n", hCryptMsg, cSignerStore, + TRACE("(%p, %ld, %p, %08lx, %p, %p)\n", hCryptMsg, cSignerStore, rghSignerStore, dwFlags, ppSigner, pdwSignerIndex); /* Clear output parameters */ @@ -3764,7 +3846,7 @@ BOOL WINAPI CryptMsgVerifyCountersignatureEncoded(HCRYPTPROV_LEGACY hCryptProv, PBYTE pbSignerInfoCountersignature, DWORD cbSignerInfoCountersignature, CERT_INFO *pciCountersigner) { - FIXME("(%08lx, %08x, %p, %d, %p, %d, %p): stub\n", hCryptProv, + FIXME("(%08Ix, %08lx, %p, %ld, %p, %ld, %p): stub\n", hCryptProv, dwEncodingType, pbSignerInfo, cbSignerInfo, pbSignerInfoCountersignature, cbSignerInfoCountersignature, pciCountersigner); return FALSE; @@ -3775,7 +3857,7 @@ BOOL WINAPI CryptMsgVerifyCountersignatureEncodedEx(HCRYPTPROV_LEGACY hCryptProv PBYTE pbSignerInfoCountersignature, DWORD cbSignerInfoCountersignature, DWORD dwSignerType, void *pvSigner, DWORD dwFlags, void *pvReserved) { - FIXME("(%08lx, %08x, %p, %d, %p, %d, %d, %p, %08x, %p): stub\n", hCryptProv, + FIXME("(%08Ix, %08lx, %p, %ld, %p, %ld, %ld, %p, %08lx, %p): stub\n", hCryptProv, dwEncodingType, pbSignerInfo, cbSignerInfo, pbSignerInfoCountersignature, cbSignerInfoCountersignature, dwSignerType, pvSigner, dwFlags, pvReserved); return FALSE; @@ -3789,12 +3871,12 @@ BOOL WINAPI CryptMsgEncodeAndSignCTL(DWORD dwMsgEncodingType, BYTE *pbCtlContent; DWORD cbCtlContent; - TRACE("(%08x, %p, %p, %08x, %p, %p)\n", dwMsgEncodingType, pCtlInfo, + TRACE("(%08lx, %p, %p, %08lx, %p, %p)\n", dwMsgEncodingType, pCtlInfo, pSignInfo, dwFlags, pbEncoded, pcbEncoded); if (dwFlags) { - FIXME("unimplemented for flags %08x\n", dwFlags); + FIXME("unimplemented for flags %08lx\n", dwFlags); return FALSE; } if ((ret = CryptEncodeObjectEx(dwMsgEncodingType, PKCS_CTL, pCtlInfo, @@ -3815,12 +3897,12 @@ BOOL WINAPI CryptMsgSignCTL(DWORD dwMsgEncodingType, BYTE *pbCtlContent, BOOL ret; HCRYPTMSG msg; - TRACE("(%08x, %p, %d, %p, %08x, %p, %p)\n", dwMsgEncodingType, + TRACE("(%08lx, %p, %ld, %p, %08lx, %p, %p)\n", dwMsgEncodingType, pbCtlContent, cbCtlContent, pSignInfo, dwFlags, pbEncoded, pcbEncoded); if (dwFlags) { - FIXME("unimplemented for flags %08x\n", dwFlags); + FIXME("unimplemented for flags %08lx\n", dwFlags); return FALSE; } msg = CryptMsgOpenToEncode(dwMsgEncodingType, 0, CMSG_SIGNED, pSignInfo, diff --git a/dll/win32/crypt32/object.c b/dll/win32/crypt32/object.c index 3dc28af0e97..8a4a161bbfb 100644 --- a/dll/win32/crypt32/object.c +++ b/dll/win32/crypt32/object.c @@ -18,7 +18,7 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ #include -#define NONAMELESSUNION + #include "windef.h" #include "winbase.h" #include "wincrypt.h" @@ -27,7 +27,6 @@ #include "wintrust.h" #include "crypt32_private.h" #include "cryptres.h" -#include "wine/unicode.h" #include "wine/debug.h" WINE_DEFAULT_DEBUG_CHANNEL(crypt); @@ -329,7 +328,7 @@ static BOOL CRYPT_QuerySerializedStoreFromBlob(const CRYPT_DATA_BLOB *blob, CERT_STORE_CREATE_NEW_FLAG, NULL); BOOL ret; - TRACE("(%d, %p)\n", blob->cbData, blob->pbData); + TRACE("(%ld, %p)\n", blob->cbData, blob->pbData); ret = CRYPT_ReadSerializedStoreFromBlob(blob, store); if (ret) @@ -359,7 +358,7 @@ static BOOL CRYPT_QuerySerializedStoreObject(DWORD dwObjectType, return CRYPT_QuerySerializedStoreFromBlob(pvObject, pdwMsgAndCertEncodingType, pdwContentType, phCertStore, phMsg); default: - FIXME("unimplemented for type %d\n", dwObjectType); + FIXME("unimplemented for type %ld\n", dwObjectType); SetLastError(E_INVALIDARG); /* FIXME: is this the correct error? */ return FALSE; } @@ -482,7 +481,7 @@ static BOOL CRYPT_QueryMessageObject(DWORD dwObjectType, const void *pvObject, DWORD encodingType = X509_ASN_ENCODING | PKCS_7_ASN_ENCODING; DWORD formatType = 0; - TRACE("(%d, %p, %08x, %08x, %p, %p, %p, %p, %p)\n", dwObjectType, pvObject, + TRACE("(%ld, %p, %08lx, %08lx, %p, %p, %p, %p, %p)\n", dwObjectType, pvObject, dwExpectedContentTypeFlags, dwExpectedFormatTypeFlags, pdwMsgAndCertEncodingType, pdwContentType, pdwFormatType, phCertStore, phMsg); @@ -630,15 +629,45 @@ static BOOL CRYPT_QueryEmbeddedMessageObject(DWORD dwObjectType, TRACE("%s\n", debugstr_w(pvObject)); - if (dwObjectType != CERT_QUERY_OBJECT_FILE) + if (dwObjectType == CERT_QUERY_OBJECT_BLOB) { - WARN("don't know what to do for type %d embedded signed messages\n", - dwObjectType); + WCHAR temp_path[MAX_PATH], temp_name[MAX_PATH]; + const CERT_BLOB *b = pvObject; + + TRACE("cbData %lu, pbData %p.\n", b->cbData, b->pbData); + + if (!GetTempPathW(MAX_PATH, temp_path) || !GetTempFileNameW(temp_path, L"blb", 0, temp_name)) + { + ERR("Failed getting temp file name.\n"); + return FALSE; + } + file = CreateFileW(temp_name, GENERIC_READ | GENERIC_WRITE, 0, + NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE, NULL); + if (file == INVALID_HANDLE_VALUE) + { + ERR("Could not create temp file.\n"); + SetLastError(ERROR_OUTOFMEMORY); + return FALSE; + } + if (!WriteFile(file, b->pbData, b->cbData, NULL, NULL)) + { + CloseHandle(file); + ERR("Could not write temp file.\n"); + SetLastError(ERROR_OUTOFMEMORY); + return FALSE; + } + } + else if (dwObjectType == CERT_QUERY_OBJECT_FILE) + { + file = CreateFileW(pvObject, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + } + else + { + WARN("Unknown dwObjectType %lu.\n", dwObjectType); SetLastError(E_INVALIDARG); return FALSE; } - file = CreateFileW(pvObject, GENERIC_READ, FILE_SHARE_READ, - NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + if (file != INVALID_HANDLE_VALUE) { ret = CryptSIPRetrieveSubjectGuid(pvObject, file, &subject); @@ -696,6 +725,48 @@ static BOOL CRYPT_QueryEmbeddedMessageObject(DWORD dwObjectType, return ret; } +static BOOL CRYPT_QueryPFXObject(DWORD dwObjectType, const void *pvObject, + DWORD dwExpectedContentTypeFlags, DWORD dwExpectedFormatTypeFlags, + DWORD *pdwMsgAndCertEncodingType, DWORD *pdwContentType, DWORD *pdwFormatType, + HCERTSTORE *phCertStore, HCRYPTMSG *phMsg) +{ + CRYPT_DATA_BLOB blob = {0}, *ptr; + BOOL ret; + + TRACE("(%ld, %p, %08lx, %08lx, %p, %p, %p, %p, %p)\n", dwObjectType, pvObject, + dwExpectedContentTypeFlags, dwExpectedFormatTypeFlags, + pdwMsgAndCertEncodingType, pdwContentType, pdwFormatType, phCertStore, + phMsg); + + switch (dwObjectType) + { + case CERT_QUERY_OBJECT_FILE: + if (!CRYPT_ReadBlobFromFile(pvObject, &blob)) return FALSE; + ptr = &blob; + break; + + case CERT_QUERY_OBJECT_BLOB: + ptr = (CRYPT_DATA_BLOB *)pvObject; + break; + + default: + return FALSE; + } + + ret = PFXIsPFXBlob(ptr); + if (ret) + { + if (pdwMsgAndCertEncodingType) *pdwMsgAndCertEncodingType = X509_ASN_ENCODING; + if (pdwContentType) *pdwContentType = CERT_QUERY_CONTENT_PFX; + if (pdwFormatType) *pdwFormatType = CERT_QUERY_FORMAT_BINARY; + if (phCertStore) *phCertStore = NULL; + if (phMsg) *phMsg = NULL; + } + + CryptMemFree(blob.pbData); + return ret; +} + BOOL WINAPI CryptQueryObject(DWORD dwObjectType, const void *pvObject, DWORD dwExpectedContentTypeFlags, DWORD dwExpectedFormatTypeFlags, DWORD dwFlags, DWORD *pdwMsgAndCertEncodingType, DWORD *pdwContentType, @@ -703,11 +774,10 @@ BOOL WINAPI CryptQueryObject(DWORD dwObjectType, const void *pvObject, const void **ppvContext) { static const DWORD unimplementedTypes = - CERT_QUERY_CONTENT_FLAG_PKCS10 | CERT_QUERY_CONTENT_FLAG_PFX | - CERT_QUERY_CONTENT_FLAG_CERT_PAIR; + CERT_QUERY_CONTENT_FLAG_PKCS10 | CERT_QUERY_CONTENT_FLAG_CERT_PAIR; BOOL ret = TRUE; - TRACE("(%08x, %p, %08x, %08x, %08x, %p, %p, %p, %p, %p, %p)\n", + TRACE("(%08lx, %p, %08lx, %08lx, %08lx, %p, %p, %p, %p, %p, %p)\n", dwObjectType, pvObject, dwExpectedContentTypeFlags, dwExpectedFormatTypeFlags, dwFlags, pdwMsgAndCertEncodingType, pdwContentType, pdwFormatType, phCertStore, phMsg, ppvContext); @@ -715,7 +785,7 @@ BOOL WINAPI CryptQueryObject(DWORD dwObjectType, const void *pvObject, if (dwObjectType != CERT_QUERY_OBJECT_BLOB && dwObjectType != CERT_QUERY_OBJECT_FILE) { - WARN("unsupported type %d\n", dwObjectType); + WARN("unsupported type %ld\n", dwObjectType); SetLastError(E_INVALIDARG); return FALSE; } @@ -726,7 +796,7 @@ BOOL WINAPI CryptQueryObject(DWORD dwObjectType, const void *pvObject, return FALSE; } if (dwExpectedContentTypeFlags & unimplementedTypes) - WARN("unimplemented for types %08x\n", + WARN("unimplemented for types %08lx\n", dwExpectedContentTypeFlags & unimplementedTypes); if (pdwFormatType) @@ -779,6 +849,14 @@ BOOL WINAPI CryptQueryObject(DWORD dwObjectType, const void *pvObject, dwExpectedContentTypeFlags, pdwMsgAndCertEncodingType, pdwContentType, phCertStore, phMsg); } + if (!ret && + (dwExpectedContentTypeFlags & CERT_QUERY_CONTENT_FLAG_PFX)) + { + ret = CRYPT_QueryPFXObject(dwObjectType, pvObject, + dwExpectedContentTypeFlags, dwExpectedFormatTypeFlags, + pdwMsgAndCertEncodingType, pdwContentType, pdwFormatType, + phCertStore, phMsg); + } if (!ret) SetLastError(CRYPT_E_NO_MATCH); TRACE("returning %d\n", ret); @@ -810,8 +888,6 @@ static BOOL WINAPI CRYPT_FormatHexString(DWORD dwCertEncodingType, } else { - static const WCHAR fmt[] = { '%','0','2','x',' ',0 }; - static const WCHAR endFmt[] = { '%','0','2','x',0 }; DWORD i; LPWSTR ptr = pbFormat; @@ -821,9 +897,9 @@ static BOOL WINAPI CRYPT_FormatHexString(DWORD dwCertEncodingType, for (i = 0; i < cbEncoded; i++) { if (i < cbEncoded - 1) - ptr += sprintfW(ptr, fmt, pbEncoded[i]); + ptr += swprintf(ptr, 4, L"%02x ", pbEncoded[i]); else - ptr += sprintfW(ptr, endFmt, pbEncoded[i]); + ptr += swprintf(ptr, 3, L"%02x", pbEncoded[i]); } } else @@ -835,7 +911,7 @@ static BOOL WINAPI CRYPT_FormatHexString(DWORD dwCertEncodingType, #define MAX_STRING_RESOURCE_LEN 128 -static const WCHAR commaSpace[] = { ',',' ',0 }; +static const WCHAR commaSpace[] = L", "; struct BitToString { @@ -855,9 +931,9 @@ static BOOL CRYPT_FormatBits(BYTE bits, const struct BitToString *map, if (bits & map[i].bit) { if (!localFirst) - bytesNeeded += strlenW(commaSpace) * sizeof(WCHAR); + bytesNeeded += lstrlenW(commaSpace) * sizeof(WCHAR); localFirst = FALSE; - bytesNeeded += strlenW(map[i].str) * sizeof(WCHAR); + bytesNeeded += lstrlenW(map[i].str) * sizeof(WCHAR); } if (!pbFormat) { @@ -882,12 +958,12 @@ static BOOL CRYPT_FormatBits(BYTE bits, const struct BitToString *map, { if (!localFirst) { - strcpyW(str, commaSpace); - str += strlenW(commaSpace); + lstrcpyW(str, commaSpace); + str += lstrlenW(commaSpace); } localFirst = FALSE; - strcpyW(str, map[i].str); - str += strlenW(map[i].str); + lstrcpyW(str, map[i].str); + str += lstrlenW(map[i].str); } *first = localFirst; } @@ -932,7 +1008,7 @@ static BOOL WINAPI CRYPT_FormatKeyUsage(DWORD dwCertEncodingType, LoadStringW(hInstance, IDS_INFO_NOT_AVAILABLE, infoNotAvailable, ARRAY_SIZE(infoNotAvailable)); if (!bits->cbData || bits->cbData > 2) { - bytesNeeded += strlenW(infoNotAvailable) * sizeof(WCHAR); + bytesNeeded += lstrlenW(infoNotAvailable) * sizeof(WCHAR); if (!pbFormat) *pcbFormat = bytesNeeded; else if (*pcbFormat < bytesNeeded) @@ -946,7 +1022,7 @@ static BOOL WINAPI CRYPT_FormatKeyUsage(DWORD dwCertEncodingType, LPWSTR str = pbFormat; *pcbFormat = bytesNeeded; - strcpyW(str, infoNotAvailable); + lstrcpyW(str, infoNotAvailable); } } else @@ -1015,7 +1091,7 @@ static BOOL WINAPI CRYPT_FormatKeyUsage(DWORD dwCertEncodingType, return ret; } -static const WCHAR crlf[] = { '\r','\n',0 }; +static const WCHAR crlf[] = L"\r\n"; static WCHAR subjectTypeHeader[MAX_STRING_RESOURCE_LEN]; static WCHAR subjectTypeCA[MAX_STRING_RESOURCE_LEN]; @@ -1039,7 +1115,6 @@ static BOOL WINAPI CRYPT_FormatBasicConstraints2(DWORD dwCertEncodingType, if ((ret = CryptDecodeObjectEx(dwCertEncodingType, X509_BASIC_CONSTRAINTS2, pbEncoded, cbEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL, &info, &size))) { - static const WCHAR pathFmt[] = { '%','d',0 }; static BOOL stringsLoaded = FALSE; DWORD bytesNeeded = sizeof(WCHAR); /* space for the NULL terminator */ WCHAR pathLength[MAX_STRING_RESOURCE_LEN]; @@ -1049,12 +1124,12 @@ static BOOL WINAPI CRYPT_FormatBasicConstraints2(DWORD dwCertEncodingType, if (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE) { sep = crlf; - sepLen = strlenW(crlf) * sizeof(WCHAR); + sepLen = lstrlenW(crlf) * sizeof(WCHAR); } else { sep = commaSpace; - sepLen = strlenW(commaSpace) * sizeof(WCHAR); + sepLen = lstrlenW(commaSpace) * sizeof(WCHAR); } if (!stringsLoaded) @@ -1065,19 +1140,19 @@ static BOOL WINAPI CRYPT_FormatBasicConstraints2(DWORD dwCertEncodingType, LoadStringW(hInstance, IDS_PATH_LENGTH, pathLengthHeader, ARRAY_SIZE(pathLengthHeader)); stringsLoaded = TRUE; } - bytesNeeded += strlenW(subjectTypeHeader) * sizeof(WCHAR); + bytesNeeded += lstrlenW(subjectTypeHeader) * sizeof(WCHAR); if (info->fCA) subjectType = subjectTypeCA; else subjectType = subjectTypeEndCert; - bytesNeeded += strlenW(subjectType) * sizeof(WCHAR); + bytesNeeded += lstrlenW(subjectType) * sizeof(WCHAR); bytesNeeded += sepLen; - bytesNeeded += strlenW(pathLengthHeader) * sizeof(WCHAR); + bytesNeeded += lstrlenW(pathLengthHeader) * sizeof(WCHAR); if (info->fPathLenConstraint) - sprintfW(pathLength, pathFmt, info->dwPathLenConstraint); + swprintf(pathLength, ARRAY_SIZE(pathLength), L"%d", info->dwPathLenConstraint); else LoadStringW(hInstance, IDS_PATH_LENGTH_NONE, pathLength, ARRAY_SIZE(pathLength)); - bytesNeeded += strlenW(pathLength) * sizeof(WCHAR); + bytesNeeded += lstrlenW(pathLength) * sizeof(WCHAR); if (!pbFormat) *pcbFormat = bytesNeeded; else if (*pcbFormat < bytesNeeded) @@ -1091,15 +1166,15 @@ static BOOL WINAPI CRYPT_FormatBasicConstraints2(DWORD dwCertEncodingType, LPWSTR str = pbFormat; *pcbFormat = bytesNeeded; - strcpyW(str, subjectTypeHeader); - str += strlenW(subjectTypeHeader); - strcpyW(str, subjectType); - str += strlenW(subjectType); - strcpyW(str, sep); + lstrcpyW(str, subjectTypeHeader); + str += lstrlenW(subjectTypeHeader); + lstrcpyW(str, subjectType); + str += lstrlenW(subjectType); + lstrcpyW(str, sep); str += sepLen / sizeof(WCHAR); - strcpyW(str, pathLengthHeader); - str += strlenW(pathLengthHeader); - strcpyW(str, pathLength); + lstrcpyW(str, pathLengthHeader); + str += lstrlenW(pathLengthHeader); + lstrcpyW(str, pathLength); } LocalFree(info); } @@ -1116,7 +1191,7 @@ static BOOL CRYPT_FormatHexStringWithPrefix(const CRYPT_DATA_BLOB *blob, int id, LoadStringW(hInstance, id, buf, ARRAY_SIZE(buf)); CRYPT_FormatHexString(X509_ASN_ENCODING, 0, 0, NULL, NULL, blob->pbData, blob->cbData, NULL, &bytesNeeded); - bytesNeeded += strlenW(buf) * sizeof(WCHAR); + bytesNeeded += lstrlenW(buf) * sizeof(WCHAR); if (!str) { *pcbStr = bytesNeeded; @@ -1131,9 +1206,9 @@ static BOOL CRYPT_FormatHexStringWithPrefix(const CRYPT_DATA_BLOB *blob, int id, else { *pcbStr = bytesNeeded; - strcpyW(str, buf); - str += strlenW(str); - bytesNeeded -= strlenW(str) * sizeof(WCHAR); + lstrcpyW(str, buf); + str += lstrlenW(str); + bytesNeeded -= lstrlenW(str) * sizeof(WCHAR); ret = CRYPT_FormatHexString(X509_ASN_ENCODING, 0, 0, NULL, NULL, blob->pbData, blob->cbData, str, &bytesNeeded); } @@ -1153,8 +1228,8 @@ static BOOL CRYPT_FormatCertSerialNumber(const CRYPT_DATA_BLOB *serialNum, LPWST str, pcbStr); } -static const WCHAR indent[] = { ' ',' ',' ',' ',' ',0 }; -static const WCHAR colonCrlf[] = { ':','\r','\n',0 }; +static const WCHAR indent[] = L" "; +static const WCHAR colonCrlf[] = L":\r\n"; static BOOL CRYPT_FormatAltNameEntry(DWORD dwFormatStrType, DWORD indentLevel, const CERT_ALT_NAME_ENTRY *entry, LPWSTR str, DWORD *pcbStr) @@ -1168,17 +1243,17 @@ static BOOL CRYPT_FormatAltNameEntry(DWORD dwFormatStrType, DWORD indentLevel, DWORD strType = CERT_X500_NAME_STR | CERT_NAME_STR_REVERSE_FLAG; if (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE) - bytesNeeded += indentLevel * strlenW(indent) * sizeof(WCHAR); + bytesNeeded += indentLevel * lstrlenW(indent) * sizeof(WCHAR); switch (entry->dwAltNameChoice) { case CERT_ALT_NAME_RFC822_NAME: LoadStringW(hInstance, IDS_ALT_NAME_RFC822_NAME, buf, ARRAY_SIZE(buf)); - bytesNeeded += strlenW(entry->u.pwszRfc822Name) * sizeof(WCHAR); + bytesNeeded += lstrlenW(entry->pwszRfc822Name) * sizeof(WCHAR); ret = TRUE; break; case CERT_ALT_NAME_DNS_NAME: LoadStringW(hInstance, IDS_ALT_NAME_DNS_NAME, buf, ARRAY_SIZE(buf)); - bytesNeeded += strlenW(entry->u.pwszDNSName) * sizeof(WCHAR); + bytesNeeded += lstrlenW(entry->pwszDNSName) * sizeof(WCHAR); ret = TRUE; break; case CERT_ALT_NAME_DIRECTORY_NAME: @@ -1188,11 +1263,11 @@ static BOOL CRYPT_FormatAltNameEntry(DWORD dwFormatStrType, DWORD indentLevel, if (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE) strType |= CERT_NAME_STR_CRLF_FLAG; directoryNameLen = cert_name_to_str_with_indent(X509_ASN_ENCODING, - indentLevel + 1, &entry->u.DirectoryName, strType, NULL, 0); + indentLevel + 1, &entry->DirectoryName, strType, NULL, 0); LoadStringW(hInstance, IDS_ALT_NAME_DIRECTORY_NAME, buf, ARRAY_SIZE(buf)); bytesNeeded += (directoryNameLen - 1) * sizeof(WCHAR); if (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE) - bytesNeeded += strlenW(colonCrlf) * sizeof(WCHAR); + bytesNeeded += lstrlenW(colonCrlf) * sizeof(WCHAR); else bytesNeeded += sizeof(WCHAR); /* '=' */ ret = TRUE; @@ -1200,70 +1275,64 @@ static BOOL CRYPT_FormatAltNameEntry(DWORD dwFormatStrType, DWORD indentLevel, } case CERT_ALT_NAME_URL: LoadStringW(hInstance, IDS_ALT_NAME_URL, buf, ARRAY_SIZE(buf)); - bytesNeeded += strlenW(entry->u.pwszURL) * sizeof(WCHAR); + bytesNeeded += lstrlenW(entry->pwszURL) * sizeof(WCHAR); ret = TRUE; break; case CERT_ALT_NAME_IP_ADDRESS: { - static const WCHAR ipAddrWithMaskFmt[] = { '%','d','.','%','d','.', - '%','d','.','%','d','/','%','d','.','%','d','.','%','d','.','%','d',0 - }; - static const WCHAR ipAddrFmt[] = { '%','d','.','%','d','.','%','d', - '.','%','d',0 }; - LoadStringW(hInstance, IDS_ALT_NAME_IP_ADDRESS, buf, ARRAY_SIZE(buf)); - if (entry->u.IPAddress.cbData == 8) + if (entry->IPAddress.cbData == 8) { if (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE) { LoadStringW(hInstance, IDS_ALT_NAME_MASK, mask, ARRAY_SIZE(mask)); - bytesNeeded += strlenW(mask) * sizeof(WCHAR); - sprintfW(ipAddrBuf, ipAddrFmt, - entry->u.IPAddress.pbData[0], - entry->u.IPAddress.pbData[1], - entry->u.IPAddress.pbData[2], - entry->u.IPAddress.pbData[3]); - bytesNeeded += strlenW(ipAddrBuf) * sizeof(WCHAR); + bytesNeeded += lstrlenW(mask) * sizeof(WCHAR); + swprintf(ipAddrBuf, ARRAY_SIZE(ipAddrBuf), L"%d.%d.%d.%d", + entry->IPAddress.pbData[0], + entry->IPAddress.pbData[1], + entry->IPAddress.pbData[2], + entry->IPAddress.pbData[3]); + bytesNeeded += lstrlenW(ipAddrBuf) * sizeof(WCHAR); /* indent again, for the mask line */ - bytesNeeded += indentLevel * strlenW(indent) * sizeof(WCHAR); - sprintfW(maskBuf, ipAddrFmt, - entry->u.IPAddress.pbData[4], - entry->u.IPAddress.pbData[5], - entry->u.IPAddress.pbData[6], - entry->u.IPAddress.pbData[7]); - bytesNeeded += strlenW(maskBuf) * sizeof(WCHAR); - bytesNeeded += strlenW(crlf) * sizeof(WCHAR); + bytesNeeded += indentLevel * lstrlenW(indent) * sizeof(WCHAR); + swprintf(maskBuf, ARRAY_SIZE(maskBuf), L"%d.%d.%d.%d", + entry->IPAddress.pbData[4], + entry->IPAddress.pbData[5], + entry->IPAddress.pbData[6], + entry->IPAddress.pbData[7]); + bytesNeeded += lstrlenW(maskBuf) * sizeof(WCHAR); + bytesNeeded += lstrlenW(crlf) * sizeof(WCHAR); } else { - sprintfW(ipAddrBuf, ipAddrWithMaskFmt, - entry->u.IPAddress.pbData[0], - entry->u.IPAddress.pbData[1], - entry->u.IPAddress.pbData[2], - entry->u.IPAddress.pbData[3], - entry->u.IPAddress.pbData[4], - entry->u.IPAddress.pbData[5], - entry->u.IPAddress.pbData[6], - entry->u.IPAddress.pbData[7]); - bytesNeeded += (strlenW(ipAddrBuf) + 1) * sizeof(WCHAR); + swprintf(ipAddrBuf, ARRAY_SIZE(ipAddrBuf), L"%d.%d.%d.%d/%d.%d.%d.%d", + entry->IPAddress.pbData[0], + entry->IPAddress.pbData[1], + entry->IPAddress.pbData[2], + entry->IPAddress.pbData[3], + entry->IPAddress.pbData[4], + entry->IPAddress.pbData[5], + entry->IPAddress.pbData[6], + entry->IPAddress.pbData[7]); + bytesNeeded += (lstrlenW(ipAddrBuf) + 1) * sizeof(WCHAR); } ret = TRUE; } else { - FIXME("unknown IP address format (%d bytes)\n", - entry->u.IPAddress.cbData); + FIXME("unknown IP address format (%ld bytes)\n", + entry->IPAddress.cbData); ret = FALSE; } break; } default: - FIXME("unimplemented for %d\n", entry->dwAltNameChoice); + FIXME("unimplemented for %ld\n", entry->dwAltNameChoice); ret = FALSE; } if (ret) { - bytesNeeded += strlenW(buf) * sizeof(WCHAR); + bytesNeeded += lstrlenW(buf) * sizeof(WCHAR); if (!str) *pcbStr = bytesNeeded; else if (*pcbStr < bytesNeeded) @@ -1281,52 +1350,52 @@ static BOOL CRYPT_FormatAltNameEntry(DWORD dwFormatStrType, DWORD indentLevel, { for (i = 0; i < indentLevel; i++) { - strcpyW(str, indent); - str += strlenW(indent); + lstrcpyW(str, indent); + str += lstrlenW(indent); } } - strcpyW(str, buf); - str += strlenW(str); + lstrcpyW(str, buf); + str += lstrlenW(str); switch (entry->dwAltNameChoice) { case CERT_ALT_NAME_RFC822_NAME: case CERT_ALT_NAME_DNS_NAME: case CERT_ALT_NAME_URL: - strcpyW(str, entry->u.pwszURL); + lstrcpyW(str, entry->pwszURL); break; case CERT_ALT_NAME_DIRECTORY_NAME: if (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE) { - strcpyW(str, colonCrlf); - str += strlenW(colonCrlf); + lstrcpyW(str, colonCrlf); + str += lstrlenW(colonCrlf); } else *str++ = '='; cert_name_to_str_with_indent(X509_ASN_ENCODING, - indentLevel + 1, &entry->u.DirectoryName, strType, str, + indentLevel + 1, &entry->DirectoryName, strType, str, bytesNeeded / sizeof(WCHAR)); break; case CERT_ALT_NAME_IP_ADDRESS: if (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE) { - strcpyW(str, ipAddrBuf); - str += strlenW(ipAddrBuf); - strcpyW(str, crlf); - str += strlenW(crlf); + lstrcpyW(str, ipAddrBuf); + str += lstrlenW(ipAddrBuf); + lstrcpyW(str, crlf); + str += lstrlenW(crlf); if (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE) { for (i = 0; i < indentLevel; i++) { - strcpyW(str, indent); - str += strlenW(indent); + lstrcpyW(str, indent); + str += lstrlenW(indent); } } - strcpyW(str, mask); - str += strlenW(mask); - strcpyW(str, maskBuf); + lstrcpyW(str, mask); + str += lstrlenW(mask); + lstrcpyW(str, maskBuf); } else - strcpyW(str, ipAddrBuf); + lstrcpyW(str, ipAddrBuf); break; } } @@ -1345,12 +1414,12 @@ static BOOL CRYPT_FormatAltNameInfo(DWORD dwFormatStrType, DWORD indentLevel, if (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE) { sep = crlf; - sepLen = strlenW(crlf) * sizeof(WCHAR); + sepLen = lstrlenW(crlf) * sizeof(WCHAR); } else { sep = commaSpace; - sepLen = strlenW(commaSpace) * sizeof(WCHAR); + sepLen = lstrlenW(commaSpace) * sizeof(WCHAR); } for (i = 0; ret && i < name->cAltEntry; i++) @@ -1387,7 +1456,7 @@ static BOOL CRYPT_FormatAltNameInfo(DWORD dwFormatStrType, DWORD indentLevel, str += size / sizeof(WCHAR) - 1; if (i < name->cAltEntry - 1) { - strcpyW(str, sep); + lstrcpyW(str, sep); str += sepLen / sizeof(WCHAR); } } @@ -1397,7 +1466,7 @@ static BOOL CRYPT_FormatAltNameInfo(DWORD dwFormatStrType, DWORD indentLevel, return ret; } -static const WCHAR colonSep[] = { ':',' ',0 }; +static const WCHAR colonSep[] = L": "; static BOOL WINAPI CRYPT_FormatAltName(DWORD dwCertEncodingType, DWORD dwFormatType, DWORD dwFormatStrType, void *pFormatStruct, @@ -1428,16 +1497,16 @@ static BOOL CRYPT_FormatCertIssuer(DWORD dwFormatStrType, LoadStringW(hInstance, IDS_CERT_ISSUER, buf, ARRAY_SIZE(buf)); ret = CRYPT_FormatAltNameInfo(dwFormatStrType, 1, issuer, NULL, &bytesNeeded); - bytesNeeded += strlenW(buf) * sizeof(WCHAR); + bytesNeeded += lstrlenW(buf) * sizeof(WCHAR); if (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE) { sep = colonCrlf; - sepLen = strlenW(colonCrlf) * sizeof(WCHAR); + sepLen = lstrlenW(colonCrlf) * sizeof(WCHAR); } else { sep = colonSep; - sepLen = strlenW(colonSep) * sizeof(WCHAR); + sepLen = lstrlenW(colonSep) * sizeof(WCHAR); } bytesNeeded += sepLen; if (ret) @@ -1453,10 +1522,10 @@ static BOOL CRYPT_FormatCertIssuer(DWORD dwFormatStrType, else { *pcbStr = bytesNeeded; - strcpyW(str, buf); - bytesNeeded -= strlenW(str) * sizeof(WCHAR); - str += strlenW(str); - strcpyW(str, sep); + lstrcpyW(str, buf); + bytesNeeded -= lstrlenW(str) * sizeof(WCHAR); + str += lstrlenW(str); + lstrcpyW(str, sep); str += sepLen / sizeof(WCHAR); ret = CRYPT_FormatAltNameInfo(dwFormatStrType, 1, issuer, str, &bytesNeeded); @@ -1490,12 +1559,12 @@ static BOOL WINAPI CRYPT_FormatAuthorityKeyId2(DWORD dwCertEncodingType, if (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE) { sep = crlf; - sepLen = strlenW(crlf) * sizeof(WCHAR); + sepLen = lstrlenW(crlf) * sizeof(WCHAR); } else { sep = commaSpace; - sepLen = strlenW(commaSpace) * sizeof(WCHAR); + sepLen = lstrlenW(commaSpace) * sizeof(WCHAR); } if (info->KeyId.cbData) @@ -1564,7 +1633,7 @@ static BOOL WINAPI CRYPT_FormatAuthorityKeyId2(DWORD dwCertEncodingType, { if (needSeparator) { - strcpyW(str, sep); + lstrcpyW(str, sep); str += sepLen / sizeof(WCHAR); } needSeparator = TRUE; @@ -1581,7 +1650,7 @@ static BOOL WINAPI CRYPT_FormatAuthorityKeyId2(DWORD dwCertEncodingType, { if (needSeparator) { - strcpyW(str, sep); + lstrcpyW(str, sep); str += sepLen / sizeof(WCHAR); } /* Overestimate size available, it's already been checked @@ -1630,7 +1699,7 @@ static BOOL WINAPI CRYPT_FormatAuthorityInfoAccess(DWORD dwCertEncodingType, WCHAR infoNotAvailable[MAX_STRING_RESOURCE_LEN]; LoadStringW(hInstance, IDS_INFO_NOT_AVAILABLE, infoNotAvailable, ARRAY_SIZE(infoNotAvailable)); - bytesNeeded += strlenW(infoNotAvailable) * sizeof(WCHAR); + bytesNeeded += lstrlenW(infoNotAvailable) * sizeof(WCHAR); if (!pbFormat) *pcbFormat = bytesNeeded; else if (*pcbFormat < bytesNeeded) @@ -1642,13 +1711,12 @@ static BOOL WINAPI CRYPT_FormatAuthorityInfoAccess(DWORD dwCertEncodingType, else { *pcbFormat = bytesNeeded; - strcpyW(pbFormat, infoNotAvailable); + lstrcpyW(pbFormat, infoNotAvailable); } } else { - static const WCHAR numFmt[] = { '%','d',0 }; - static const WCHAR equal[] = { '=',0 }; + static const WCHAR equal[] = L"="; static BOOL stringsLoaded = FALSE; DWORD i; LPCWSTR headingSep, accessMethodSep, locationSep; @@ -1681,41 +1749,41 @@ static BOOL WINAPI CRYPT_FormatAuthorityInfoAccess(DWORD dwCertEncodingType, { /* Heading */ bytesNeeded += sizeof(WCHAR); /* left bracket */ - sprintfW(accessDescrNum, numFmt, i + 1); - bytesNeeded += strlenW(accessDescrNum) * sizeof(WCHAR); + swprintf(accessDescrNum, ARRAY_SIZE(accessDescrNum), L"%d", i + 1); + bytesNeeded += lstrlenW(accessDescrNum) * sizeof(WCHAR); bytesNeeded += sizeof(WCHAR); /* right bracket */ - bytesNeeded += strlenW(aia) * sizeof(WCHAR); - bytesNeeded += strlenW(headingSep) * sizeof(WCHAR); + bytesNeeded += lstrlenW(aia) * sizeof(WCHAR); + bytesNeeded += lstrlenW(headingSep) * sizeof(WCHAR); /* Access method */ - bytesNeeded += strlenW(accessMethod) * sizeof(WCHAR); + bytesNeeded += lstrlenW(accessMethod) * sizeof(WCHAR); if (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE) - bytesNeeded += strlenW(indent) * sizeof(WCHAR); + bytesNeeded += lstrlenW(indent) * sizeof(WCHAR); if (!strcmp(info->rgAccDescr[i].pszAccessMethod, szOID_PKIX_OCSP)) - bytesNeeded += strlenW(ocsp) * sizeof(WCHAR); + bytesNeeded += lstrlenW(ocsp) * sizeof(WCHAR); else if (!strcmp(info->rgAccDescr[i].pszAccessMethod, szOID_PKIX_CA_ISSUERS)) - bytesNeeded += strlenW(caIssuers) * sizeof(caIssuers); + bytesNeeded += lstrlenW(caIssuers) * sizeof(caIssuers); else - bytesNeeded += strlenW(unknown) * sizeof(WCHAR); + bytesNeeded += lstrlenW(unknown) * sizeof(WCHAR); bytesNeeded += sizeof(WCHAR); /* space */ bytesNeeded += sizeof(WCHAR); /* left paren */ bytesNeeded += strlen(info->rgAccDescr[i].pszAccessMethod) * sizeof(WCHAR); bytesNeeded += sizeof(WCHAR); /* right paren */ /* Delimiter between access method and location */ - bytesNeeded += strlenW(accessMethodSep) * sizeof(WCHAR); + bytesNeeded += lstrlenW(accessMethodSep) * sizeof(WCHAR); if (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE) - bytesNeeded += strlenW(indent) * sizeof(WCHAR); - bytesNeeded += strlenW(accessLocation) * sizeof(WCHAR); - bytesNeeded += strlenW(locationSep) * sizeof(WCHAR); + bytesNeeded += lstrlenW(indent) * sizeof(WCHAR); + bytesNeeded += lstrlenW(accessLocation) * sizeof(WCHAR); + bytesNeeded += lstrlenW(locationSep) * sizeof(WCHAR); ret = CRYPT_FormatAltNameEntry(dwFormatStrType, 2, &info->rgAccDescr[i].AccessLocation, NULL, &size); if (ret) bytesNeeded += size - sizeof(WCHAR); /* Need extra delimiter between access method entries */ if (i < info->cAccDescr - 1) - bytesNeeded += strlenW(accessMethodSep) * sizeof(WCHAR); + bytesNeeded += lstrlenW(accessMethodSep) * sizeof(WCHAR); } if (ret) { @@ -1738,37 +1806,37 @@ static BOOL WINAPI CRYPT_FormatAuthorityInfoAccess(DWORD dwCertEncodingType, LPCSTR oidPtr; *str++ = '['; - sprintfW(accessDescrNum, numFmt, i + 1); - strcpyW(str, accessDescrNum); - str += strlenW(accessDescrNum); + swprintf(accessDescrNum, ARRAY_SIZE(accessDescrNum), L"%d", i + 1); + lstrcpyW(str, accessDescrNum); + str += lstrlenW(accessDescrNum); *str++ = ']'; - strcpyW(str, aia); - str += strlenW(aia); - strcpyW(str, headingSep); - str += strlenW(headingSep); + lstrcpyW(str, aia); + str += lstrlenW(aia); + lstrcpyW(str, headingSep); + str += lstrlenW(headingSep); if (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE) { - strcpyW(str, indent); - str += strlenW(indent); + lstrcpyW(str, indent); + str += lstrlenW(indent); } - strcpyW(str, accessMethod); - str += strlenW(accessMethod); + lstrcpyW(str, accessMethod); + str += lstrlenW(accessMethod); if (!strcmp(info->rgAccDescr[i].pszAccessMethod, szOID_PKIX_OCSP)) { - strcpyW(str, ocsp); - str += strlenW(ocsp); + lstrcpyW(str, ocsp); + str += lstrlenW(ocsp); } else if (!strcmp(info->rgAccDescr[i].pszAccessMethod, szOID_PKIX_CA_ISSUERS)) { - strcpyW(str, caIssuers); - str += strlenW(caIssuers); + lstrcpyW(str, caIssuers); + str += lstrlenW(caIssuers); } else { - strcpyW(str, unknown); - str += strlenW(unknown); + lstrcpyW(str, unknown); + str += lstrlenW(unknown); } *str++ = ' '; *str++ = '('; @@ -1776,17 +1844,17 @@ static BOOL WINAPI CRYPT_FormatAuthorityInfoAccess(DWORD dwCertEncodingType, *oidPtr; oidPtr++, str++) *str = *oidPtr; *str++ = ')'; - strcpyW(str, accessMethodSep); - str += strlenW(accessMethodSep); + lstrcpyW(str, accessMethodSep); + str += lstrlenW(accessMethodSep); if (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE) { - strcpyW(str, indent); - str += strlenW(indent); + lstrcpyW(str, indent); + str += lstrlenW(indent); } - strcpyW(str, accessLocation); - str += strlenW(accessLocation); - strcpyW(str, locationSep); - str += strlenW(locationSep); + lstrcpyW(str, accessLocation); + str += lstrlenW(accessLocation); + lstrcpyW(str, locationSep); + str += lstrlenW(locationSep); /* This overestimates the size available, but that * won't matter since we checked earlier whether enough * space for the entire string was available. @@ -1799,8 +1867,8 @@ static BOOL WINAPI CRYPT_FormatAuthorityInfoAccess(DWORD dwCertEncodingType, str += altNameEntrySize / sizeof(WCHAR) - 1; if (i < info->cAccDescr - 1) { - strcpyW(str, accessMethodSep); - str += strlenW(accessMethodSep); + lstrcpyW(str, accessMethodSep); + str += lstrlenW(accessMethodSep); } } } @@ -1839,8 +1907,7 @@ static struct reason_map_entry reason_map[] = { static BOOL CRYPT_FormatReason(DWORD dwFormatStrType, const CRYPT_BIT_BLOB *reasonFlags, LPWSTR str, DWORD *pcbStr) { - static const WCHAR sep[] = { ',',' ',0 }; - static const WCHAR bitsFmt[] = { ' ','(','%','0','2','x',')',0 }; + static const WCHAR sep[] = L", "; static BOOL stringsLoaded = FALSE; unsigned int i, numReasons = 0; BOOL ret = TRUE; @@ -1861,13 +1928,13 @@ static BOOL CRYPT_FormatReason(DWORD dwFormatStrType, { if (reasonFlags->pbData[0] & reason_map[i].reasonBit) { - bytesNeeded += strlenW(reason_map[i].reason) * sizeof(WCHAR); + bytesNeeded += lstrlenW(reason_map[i].reason) * sizeof(WCHAR); if (numReasons++) - bytesNeeded += strlenW(sep) * sizeof(WCHAR); + bytesNeeded += lstrlenW(sep) * sizeof(WCHAR); } } - sprintfW(bits, bitsFmt, reasonFlags->pbData[0]); - bytesNeeded += strlenW(bits); + swprintf(bits, ARRAY_SIZE(bits), L" (%02x)", reasonFlags->pbData[0]); + bytesNeeded += lstrlenW(bits); if (!str) *pcbStr = bytesNeeded; else if (*pcbStr < bytesNeeded) @@ -1883,16 +1950,16 @@ static BOOL CRYPT_FormatReason(DWORD dwFormatStrType, { if (reasonFlags->pbData[0] & reason_map[i].reasonBit) { - strcpyW(str, reason_map[i].reason); - str += strlenW(reason_map[i].reason); + lstrcpyW(str, reason_map[i].reason); + str += lstrlenW(reason_map[i].reason); if (i < ARRAY_SIZE(reason_map) - 1 && numReasons) { - strcpyW(str, sep); - str += strlenW(sep); + lstrcpyW(str, sep); + str += lstrlenW(sep); } } } - strcpyW(str, bits); + lstrcpyW(str, bits); } return ret; } @@ -1921,8 +1988,7 @@ static BOOL WINAPI CRYPT_FormatCRLDistPoints(DWORD dwCertEncodingType, if ((ret = CryptDecodeObjectEx(dwCertEncodingType, X509_CRL_DIST_POINTS, pbEncoded, cbEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL, &info, &size))) { - static const WCHAR numFmt[] = { '%','d',0 }; - static const WCHAR colon[] = { ':',0 }; + static const WCHAR colon[] = L":"; static BOOL stringsLoaded = FALSE; DWORD bytesNeeded = sizeof(WCHAR); /* space for NULL terminator */ BOOL haveAnEntry = FALSE; @@ -1958,29 +2024,29 @@ static BOOL WINAPI CRYPT_FormatCRLDistPoints(DWORD dwCertEncodingType, if (distPoint->DistPointName.dwDistPointNameChoice != CRL_DIST_POINT_NO_NAME) { - bytesNeeded += strlenW(distPointName) * sizeof(WCHAR); - bytesNeeded += strlenW(nameSep) * sizeof(WCHAR); + bytesNeeded += lstrlenW(distPointName) * sizeof(WCHAR); + bytesNeeded += lstrlenW(nameSep) * sizeof(WCHAR); if (distPoint->DistPointName.dwDistPointNameChoice == CRL_DIST_POINT_FULL_NAME) - bytesNeeded += strlenW(fullName) * sizeof(WCHAR); + bytesNeeded += lstrlenW(fullName) * sizeof(WCHAR); else - bytesNeeded += strlenW(rdnName) * sizeof(WCHAR); - bytesNeeded += strlenW(nameSep) * sizeof(WCHAR); + bytesNeeded += lstrlenW(rdnName) * sizeof(WCHAR); + bytesNeeded += lstrlenW(nameSep) * sizeof(WCHAR); if (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE) - bytesNeeded += 2 * strlenW(indent) * sizeof(WCHAR); + bytesNeeded += 2 * lstrlenW(indent) * sizeof(WCHAR); /* The indent level (3) is higher than when used as the issuer, * because the name is subordinate to the name type (full vs. * RDN.) */ ret = CRYPT_FormatAltNameInfo(dwFormatStrType, 3, - &distPoint->DistPointName.u.FullName, NULL, &size); + &distPoint->DistPointName.FullName, NULL, &size); if (ret) bytesNeeded += size - sizeof(WCHAR); haveAnEntry = TRUE; } else if (distPoint->ReasonFlags.cbData) { - bytesNeeded += strlenW(reason) * sizeof(WCHAR); + bytesNeeded += lstrlenW(reason) * sizeof(WCHAR); ret = CRYPT_FormatReason(dwFormatStrType, &distPoint->ReasonFlags, NULL, &size); if (ret) @@ -1989,8 +2055,8 @@ static BOOL WINAPI CRYPT_FormatCRLDistPoints(DWORD dwCertEncodingType, } else if (distPoint->CRLIssuer.cAltEntry) { - bytesNeeded += strlenW(issuer) * sizeof(WCHAR); - bytesNeeded += strlenW(nameSep) * sizeof(WCHAR); + bytesNeeded += lstrlenW(issuer) * sizeof(WCHAR); + bytesNeeded += lstrlenW(nameSep) * sizeof(WCHAR); ret = CRYPT_FormatAltNameInfo(dwFormatStrType, 2, &distPoint->CRLIssuer, NULL, &size); if (ret) @@ -2000,13 +2066,13 @@ static BOOL WINAPI CRYPT_FormatCRLDistPoints(DWORD dwCertEncodingType, if (haveAnEntry) { bytesNeeded += sizeof(WCHAR); /* left bracket */ - sprintfW(distPointNum, numFmt, i + 1); - bytesNeeded += strlenW(distPointNum) * sizeof(WCHAR); + swprintf(distPointNum, ARRAY_SIZE(distPointNum), L"%d", i + 1); + bytesNeeded += lstrlenW(distPointNum) * sizeof(WCHAR); bytesNeeded += sizeof(WCHAR); /* right bracket */ - bytesNeeded += strlenW(crlDistPoint) * sizeof(WCHAR); - bytesNeeded += strlenW(headingSep) * sizeof(WCHAR); + bytesNeeded += lstrlenW(crlDistPoint) * sizeof(WCHAR); + bytesNeeded += lstrlenW(headingSep) * sizeof(WCHAR); if (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE) - bytesNeeded += strlenW(indent) * sizeof(WCHAR); + bytesNeeded += lstrlenW(indent) * sizeof(WCHAR); } } if (!haveAnEntry) @@ -2014,7 +2080,7 @@ static BOOL WINAPI CRYPT_FormatCRLDistPoints(DWORD dwCertEncodingType, WCHAR infoNotAvailable[MAX_STRING_RESOURCE_LEN]; LoadStringW(hInstance, IDS_INFO_NOT_AVAILABLE, infoNotAvailable, ARRAY_SIZE(infoNotAvailable)); - bytesNeeded += strlenW(infoNotAvailable) * sizeof(WCHAR); + bytesNeeded += lstrlenW(infoNotAvailable) * sizeof(WCHAR); if (!pbFormat) *pcbFormat = bytesNeeded; else if (*pcbFormat < bytesNeeded) @@ -2026,7 +2092,7 @@ static BOOL WINAPI CRYPT_FormatCRLDistPoints(DWORD dwCertEncodingType, else { *pcbFormat = bytesNeeded; - strcpyW(pbFormat, infoNotAvailable); + lstrcpyW(pbFormat, infoNotAvailable); } } else @@ -2049,50 +2115,50 @@ static BOOL WINAPI CRYPT_FormatCRLDistPoints(DWORD dwCertEncodingType, CRL_DIST_POINT *distPoint = &info->rgDistPoint[i]; *str++ = '['; - sprintfW(distPointNum, numFmt, i + 1); - strcpyW(str, distPointNum); - str += strlenW(distPointNum); + swprintf(distPointNum, ARRAY_SIZE(distPointNum), L"%d", i + 1); + lstrcpyW(str, distPointNum); + str += lstrlenW(distPointNum); *str++ = ']'; - strcpyW(str, crlDistPoint); - str += strlenW(crlDistPoint); - strcpyW(str, headingSep); - str += strlenW(headingSep); + lstrcpyW(str, crlDistPoint); + str += lstrlenW(crlDistPoint); + lstrcpyW(str, headingSep); + str += lstrlenW(headingSep); if (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE) { - strcpyW(str, indent); - str += strlenW(indent); + lstrcpyW(str, indent); + str += lstrlenW(indent); } if (distPoint->DistPointName.dwDistPointNameChoice != CRL_DIST_POINT_NO_NAME) { DWORD altNameSize = bytesNeeded; - strcpyW(str, distPointName); - str += strlenW(distPointName); - strcpyW(str, nameSep); - str += strlenW(nameSep); + lstrcpyW(str, distPointName); + str += lstrlenW(distPointName); + lstrcpyW(str, nameSep); + str += lstrlenW(nameSep); if (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE) { - strcpyW(str, indent); - str += strlenW(indent); - strcpyW(str, indent); - str += strlenW(indent); + lstrcpyW(str, indent); + str += lstrlenW(indent); + lstrcpyW(str, indent); + str += lstrlenW(indent); } if (distPoint->DistPointName.dwDistPointNameChoice == CRL_DIST_POINT_FULL_NAME) { - strcpyW(str, fullName); - str += strlenW(fullName); + lstrcpyW(str, fullName); + str += lstrlenW(fullName); } else { - strcpyW(str, rdnName); - str += strlenW(rdnName); + lstrcpyW(str, rdnName); + str += lstrlenW(rdnName); } - strcpyW(str, nameSep); - str += strlenW(nameSep); + lstrcpyW(str, nameSep); + str += lstrlenW(nameSep); ret = CRYPT_FormatAltNameInfo(dwFormatStrType, 3, - &distPoint->DistPointName.u.FullName, str, + &distPoint->DistPointName.FullName, str, &altNameSize); if (ret) str += altNameSize / sizeof(WCHAR) - 1; @@ -2101,8 +2167,8 @@ static BOOL WINAPI CRYPT_FormatCRLDistPoints(DWORD dwCertEncodingType, { DWORD reasonSize = bytesNeeded; - strcpyW(str, reason); - str += strlenW(reason); + lstrcpyW(str, reason); + str += lstrlenW(reason); ret = CRYPT_FormatReason(dwFormatStrType, &distPoint->ReasonFlags, str, &reasonSize); if (ret) @@ -2112,10 +2178,10 @@ static BOOL WINAPI CRYPT_FormatCRLDistPoints(DWORD dwCertEncodingType, { DWORD crlIssuerSize = bytesNeeded; - strcpyW(str, issuer); - str += strlenW(issuer); - strcpyW(str, nameSep); - str += strlenW(nameSep); + lstrcpyW(str, issuer); + str += lstrlenW(issuer); + lstrcpyW(str, nameSep); + str += lstrlenW(nameSep); ret = CRYPT_FormatAltNameInfo(dwFormatStrType, 2, &distPoint->CRLIssuer, str, &crlIssuerSize); @@ -2156,12 +2222,12 @@ static BOOL WINAPI CRYPT_FormatEnhancedKeyUsage(DWORD dwCertEncodingType, if (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE) { sep = crlf; - sepLen = strlenW(crlf) * sizeof(WCHAR); + sepLen = lstrlenW(crlf) * sizeof(WCHAR); } else { sep = commaSpace; - sepLen = strlenW(commaSpace) * sizeof(WCHAR); + sepLen = lstrlenW(commaSpace) * sizeof(WCHAR); } LoadStringW(hInstance, IDS_USAGE_UNKNOWN, unknown, ARRAY_SIZE(unknown)); @@ -2171,9 +2237,9 @@ static BOOL WINAPI CRYPT_FormatEnhancedKeyUsage(DWORD dwCertEncodingType, usage->rgpszUsageIdentifier[i], CRYPT_ENHKEY_USAGE_OID_GROUP_ID); if (info) - bytesNeeded += strlenW(info->pwszName) * sizeof(WCHAR); + bytesNeeded += lstrlenW(info->pwszName) * sizeof(WCHAR); else - bytesNeeded += strlenW(unknown) * sizeof(WCHAR); + bytesNeeded += lstrlenW(unknown) * sizeof(WCHAR); bytesNeeded += sizeof(WCHAR); /* space */ bytesNeeded += sizeof(WCHAR); /* left paren */ bytesNeeded += strlen(usage->rgpszUsageIdentifier[i]) * @@ -2204,13 +2270,13 @@ static BOOL WINAPI CRYPT_FormatEnhancedKeyUsage(DWORD dwCertEncodingType, if (info) { - strcpyW(str, info->pwszName); - str += strlenW(info->pwszName); + lstrcpyW(str, info->pwszName); + str += lstrlenW(info->pwszName); } else { - strcpyW(str, unknown); - str += strlenW(unknown); + lstrcpyW(str, unknown); + str += lstrlenW(unknown); } *str++ = ' '; *str++ = '('; @@ -2220,7 +2286,7 @@ static BOOL WINAPI CRYPT_FormatEnhancedKeyUsage(DWORD dwCertEncodingType, *str = 0; if (i < usage->cUsageIdentifier - 1) { - strcpyW(str, sep); + lstrcpyW(str, sep); str += sepLen / sizeof(WCHAR); } } @@ -2263,7 +2329,7 @@ static BOOL WINAPI CRYPT_FormatNetscapeCertType(DWORD dwCertEncodingType, LoadStringW(hInstance, IDS_INFO_NOT_AVAILABLE, infoNotAvailable, ARRAY_SIZE(infoNotAvailable)); if (!bits->cbData || bits->cbData > 1) { - bytesNeeded += strlenW(infoNotAvailable) * sizeof(WCHAR); + bytesNeeded += lstrlenW(infoNotAvailable) * sizeof(WCHAR); if (!pbFormat) *pcbFormat = bytesNeeded; else if (*pcbFormat < bytesNeeded) @@ -2277,7 +2343,7 @@ static BOOL WINAPI CRYPT_FormatNetscapeCertType(DWORD dwCertEncodingType, LPWSTR str = pbFormat; *pcbFormat = bytesNeeded; - strcpyW(str, infoNotAvailable); + lstrcpyW(str, infoNotAvailable); } } else @@ -2375,26 +2441,26 @@ static BOOL WINAPI CRYPT_FormatSpcFinancialCriteria(DWORD dwCertEncodingType, if (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE) { sep = crlf; - sepLen = strlenW(crlf) * sizeof(WCHAR); + sepLen = lstrlenW(crlf) * sizeof(WCHAR); } else { sep = commaSpace; - sepLen = strlenW(commaSpace) * sizeof(WCHAR); + sepLen = lstrlenW(commaSpace) * sizeof(WCHAR); } - bytesNeeded += strlenW(financialCriteria) * sizeof(WCHAR); + bytesNeeded += lstrlenW(financialCriteria) * sizeof(WCHAR); if (criteria.fFinancialInfoAvailable) { - bytesNeeded += strlenW(available) * sizeof(WCHAR); + bytesNeeded += lstrlenW(available) * sizeof(WCHAR); bytesNeeded += sepLen; - bytesNeeded += strlenW(meetsCriteria) * sizeof(WCHAR); + bytesNeeded += lstrlenW(meetsCriteria) * sizeof(WCHAR); if (criteria.fMeetsCriteria) - bytesNeeded += strlenW(yes) * sizeof(WCHAR); + bytesNeeded += lstrlenW(yes) * sizeof(WCHAR); else - bytesNeeded += strlenW(no) * sizeof(WCHAR); + bytesNeeded += lstrlenW(no) * sizeof(WCHAR); } else - bytesNeeded += strlenW(notAvailable) * sizeof(WCHAR); + bytesNeeded += lstrlenW(notAvailable) * sizeof(WCHAR); if (!pbFormat) *pcbFormat = bytesNeeded; else if (*pcbFormat < bytesNeeded) @@ -2408,24 +2474,24 @@ static BOOL WINAPI CRYPT_FormatSpcFinancialCriteria(DWORD dwCertEncodingType, LPWSTR str = pbFormat; *pcbFormat = bytesNeeded; - strcpyW(str, financialCriteria); - str += strlenW(financialCriteria); + lstrcpyW(str, financialCriteria); + str += lstrlenW(financialCriteria); if (criteria.fFinancialInfoAvailable) { - strcpyW(str, available); - str += strlenW(available); - strcpyW(str, sep); + lstrcpyW(str, available); + str += lstrlenW(available); + lstrcpyW(str, sep); str += sepLen / sizeof(WCHAR); - strcpyW(str, meetsCriteria); - str += strlenW(meetsCriteria); + lstrcpyW(str, meetsCriteria); + str += lstrlenW(meetsCriteria); if (criteria.fMeetsCriteria) - strcpyW(str, yes); + lstrcpyW(str, yes); else - strcpyW(str, no); + lstrcpyW(str, no); } else { - strcpyW(str, notAvailable); + lstrcpyW(str, notAvailable); } } } @@ -2462,7 +2528,7 @@ static BOOL WINAPI CRYPT_FormatUnicodeString(DWORD dwCertEncodingType, LPWSTR str = pbFormat; *pcbFormat = value->Value.cbData; - strcpyW(str, (LPWSTR)value->Value.pbData); + lstrcpyW(str, (LPWSTR)value->Value.pbData); } } return ret; @@ -2554,7 +2620,7 @@ BOOL WINAPI CryptFormatObject(DWORD dwCertEncodingType, DWORD dwFormatType, HCRYPTOIDFUNCADDR hFunc = NULL; BOOL ret = FALSE; - TRACE("(%08x, %d, %08x, %p, %s, %p, %d, %p, %p)\n", dwCertEncodingType, + TRACE("(%08lx, %ld, %08lx, %p, %s, %p, %ld, %p, %p)\n", dwCertEncodingType, dwFormatType, dwFormatStrType, pFormatStruct, debugstr_a(lpszStructType), pbEncoded, cbEncoded, pbFormat, pcbFormat); diff --git a/dll/win32/crypt32/oid.c b/dll/win32/crypt32/oid.c index 773264d3990..e00c683e181 100644 --- a/dll/win32/crypt32/oid.c +++ b/dll/win32/crypt32/oid.c @@ -18,20 +18,16 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "config.h" -#include "wine/port.h" - #include #include -#ifdef __REACTOS__ #include -#endif -#define NONAMELESSUNION + #include "windef.h" #include "winbase.h" #define CRYPT_OID_INFO_HAS_EXTRA_FIELDS #include "wincrypt.h" #include "winreg.h" +#include "winternl.h" #include "winuser.h" #include "wine/debug.h" #include "wine/list.h" @@ -40,8 +36,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(crypt); -static const WCHAR DllW[] = { 'D','l','l',0 }; - static CRITICAL_SECTION funcSetCS; static CRITICAL_SECTION_DEBUG funcSetCSDebug = { @@ -68,22 +62,17 @@ struct OIDFunction struct list next; }; -static const WCHAR ROOT[] = {'R','O','O','T',0}; -static const WCHAR MY[] = {'M','Y',0}; -static const WCHAR CA[] = {'C','A',0}; -static const WCHAR ADDRESSBOOK[] = {'A','D','D','R','E','S','S','B','O','O','K',0}; -static const WCHAR TRUSTEDPUBLISHER[] = {'T','r','u','s','t','e','d','P','u','b','l','i','s','h','e','r',0}; -static const WCHAR DISALLOWED[] = {'D','i','s','a','l','l','o','w','e','d',0}; -static const LPCWSTR LocalizedKeys[] = {ROOT,MY,CA,ADDRESSBOOK,TRUSTEDPUBLISHER,DISALLOWED}; +static const LPCWSTR LocalizedKeys[] = +{ + L"ROOT", + L"MY", + L"CA", + L"ADDRESSBOOK", + L"TrustedPublisher", + L"Disallowed" +}; static WCHAR LocalizedNames[ARRAY_SIZE(LocalizedKeys)][256]; -static const WCHAR nameW[] = { 'N','a','m','e',0 }; -static const WCHAR algidW[] = { 'A','l','g','i','d',0 }; -static const WCHAR extraW[] = { 'E','x','t','r','a','I','n','f','o',0 }; -static const WCHAR cngalgidW[] = { 'C','N','G','A','l','g','i','d',0 }; -static const WCHAR cngextraalgidW[] = { 'C','N','G','E','x','t','r','a','A','l','g','i','d',0 }; -static const WCHAR flagsW[] = { 'F','l','a','g','s',0 }; - static void free_function_sets(void) { struct OIDFunctionSet *setCursor, *setNext; @@ -116,12 +105,12 @@ HCRYPTOIDFUNCSET WINAPI CryptInitOIDFunctionSet(LPCSTR pszFuncName, { struct OIDFunctionSet *cursor, *ret = NULL; - TRACE("(%s, %x)\n", debugstr_a(pszFuncName), dwFlags); + TRACE("(%s, %lx)\n", debugstr_a(pszFuncName), dwFlags); EnterCriticalSection(&funcSetCS); LIST_FOR_EACH_ENTRY(cursor, &funcSets, struct OIDFunctionSet, next) { - if (!strcasecmp(pszFuncName, cursor->name)) + if (!stricmp(pszFuncName, cursor->name)) { ret = cursor; break; @@ -136,7 +125,7 @@ HCRYPTOIDFUNCSET WINAPI CryptInitOIDFunctionSet(LPCSTR pszFuncName, ret->name = CryptMemAlloc(strlen(pszFuncName) + 1); if (ret->name) { - InitializeCriticalSection(&ret->cs); + InitializeCriticalSectionEx(&ret->cs, 0, RTL_CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO); ret->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": OIDFunctionSet.cs"); list_init(&ret->functions); strcpy(ret->name, pszFuncName); @@ -158,7 +147,7 @@ static char *CRYPT_GetKeyName(DWORD dwEncodingType, LPCSTR pszFuncName, LPCSTR pszOID) { static const char szEncodingTypeFmt[] = - "Software\\Microsoft\\Cryptography\\OID\\EncodingType %d\\%s\\%s"; + "Software\\Microsoft\\Cryptography\\OID\\EncodingType %ld\\%s\\%s"; UINT len; char numericOID[7]; /* enough for "#65535" */ const char *oid; @@ -193,13 +182,12 @@ static char *CRYPT_GetKeyName(DWORD dwEncodingType, LPCSTR pszFuncName, BOOL WINAPI CryptGetDefaultOIDDllList(HCRYPTOIDFUNCSET hFuncSet, DWORD dwEncodingType, LPWSTR pwszDllList, DWORD *pcchDllList) { - BOOL ret = TRUE; struct OIDFunctionSet *set = hFuncSet; char *keyName; HKEY key; LSTATUS rc; - TRACE("(%p, %d, %p, %p)\n", hFuncSet, dwEncodingType, pwszDllList, + TRACE("(%p, %ld, %p, %p)\n", hFuncSet, dwEncodingType, pwszDllList, pcchDllList); keyName = CRYPT_GetKeyName(dwEncodingType, set->name, "DEFAULT"); @@ -209,7 +197,7 @@ BOOL WINAPI CryptGetDefaultOIDDllList(HCRYPTOIDFUNCSET hFuncSet, { DWORD size = *pcchDllList * sizeof(WCHAR); - rc = RegQueryValueExW(key, DllW, NULL, NULL, (LPBYTE)pwszDllList, + rc = RegQueryValueExW(key, L"Dll", NULL, NULL, (LPBYTE)pwszDllList, &size); if (!rc) *pcchDllList = size / sizeof(WCHAR); @@ -231,7 +219,7 @@ BOOL WINAPI CryptGetDefaultOIDDllList(HCRYPTOIDFUNCSET hFuncSet, } CryptMemFree(keyName); - return ret; + return TRUE; } BOOL WINAPI CryptInstallOIDFunctionAddress(HMODULE hModule, @@ -241,7 +229,7 @@ BOOL WINAPI CryptInstallOIDFunctionAddress(HMODULE hModule, BOOL ret = TRUE; struct OIDFunctionSet *set; - TRACE("(%p, %d, %s, %d, %p, %08x)\n", hModule, dwEncodingType, + TRACE("(%p, %ld, %s, %ld, %p, %08lx)\n", hModule, dwEncodingType, debugstr_a(pszFuncName), cFuncEntry, rgFuncEntry, dwFlags); set = CryptInitOIDFunctionSet(pszFuncName, 0); @@ -319,14 +307,14 @@ static BOOL CRYPT_GetFuncFromReg(DWORD dwEncodingType, LPCSTR pszOID, } else funcName = szFuncName; - rc = RegQueryValueExW(key, DllW, NULL, &type, NULL, &size); + rc = RegQueryValueExW(key, L"Dll", NULL, &type, NULL, &size); if ((!rc || rc == ERROR_MORE_DATA) && type == REG_SZ) { LPWSTR dllName = CryptMemAlloc(size); if (dllName) { - rc = RegQueryValueExW(key, DllW, NULL, NULL, + rc = RegQueryValueExW(key, L"Dll", NULL, NULL, (LPBYTE)dllName, &size); if (!rc) { @@ -391,7 +379,7 @@ BOOL WINAPI CryptGetOIDFunctionAddress(HCRYPTOIDFUNCSET hFuncSet, BOOL ret = FALSE; struct OIDFunctionSet *set = hFuncSet; - TRACE("(%p, %d, %s, %08x, %p, %p)\n", hFuncSet, dwEncodingType, + TRACE("(%p, %ld, %s, %08lx, %p, %p)\n", hFuncSet, dwEncodingType, debugstr_a(pszOID), dwFlags, ppvFuncAddr, phFuncAddr); *ppvFuncAddr = NULL; @@ -407,7 +395,7 @@ BOOL WINAPI CryptGetOIDFunctionAddress(HCRYPTOIDFUNCSET hFuncSet, if (!IS_INTOID(pszOID)) { if (!IS_INTOID(function->entry.pszOID) && - !strcasecmp(function->entry.pszOID, pszOID)) + !stricmp(function->entry.pszOID, pszOID)) { *ppvFuncAddr = function->entry.pvFuncAddr; *phFuncAddr = NULL; /* FIXME: what should it be? */ @@ -468,7 +456,7 @@ static BOOL is_module_registered(HMODULE hModule) BOOL WINAPI CryptFreeOIDFunctionAddress(HCRYPTOIDFUNCADDR hFuncAddr, DWORD dwFlags) { - TRACE("(%p, %08x)\n", hFuncAddr, dwFlags); + TRACE("(%p, %08lx)\n", hFuncAddr, dwFlags); /* FIXME: as MSDN states, need to check for DllCanUnloadNow in the DLL, * and only unload it if it can be unloaded. Also need to implement ref @@ -515,7 +503,7 @@ BOOL WINAPI CryptGetDefaultOIDFunctionAddress(HCRYPTOIDFUNCSET hFuncSet, struct OIDFunctionSet *set = hFuncSet; BOOL ret = FALSE; - TRACE("(%p, %d, %s, %08x, %p, %p)\n", hFuncSet, dwEncodingType, + TRACE("(%p, %ld, %s, %08lx, %p, %p)\n", hFuncSet, dwEncodingType, debugstr_w(pwszDll), dwFlags, ppvFuncAddr, phFuncAddr); if (pwszDll) @@ -651,7 +639,7 @@ BOOL WINAPI CryptRegisterOIDFunction(DWORD dwEncodingType, LPCSTR pszFuncName, HKEY hKey; LPSTR szKey; - TRACE("(%x, %s, %s, %s, %s)\n", dwEncodingType, debugstr_a(pszFuncName), + TRACE("(%lx, %s, %s, %s, %s)\n", dwEncodingType, debugstr_a(pszFuncName), debugstr_a(pszOID), debugstr_w(pwszDll), debugstr_a(pszOverrideFuncName)); /* Native does nothing pwszDll is NULL */ @@ -686,7 +674,7 @@ BOOL WINAPI CryptRegisterOIDFunction(DWORD dwEncodingType, LPCSTR pszFuncName, (const BYTE*)pszOverrideFuncName, lstrlenA(pszOverrideFuncName) + 1); if (r != ERROR_SUCCESS) goto error_close_key; } - r = RegSetValueExW(hKey, DllW, 0, REG_SZ, (const BYTE*) pwszDll, + r = RegSetValueExW(hKey, L"Dll", 0, REG_SZ, (const BYTE*) pwszDll, (lstrlenW(pwszDll) + 1) * sizeof (WCHAR)); error_close_key: @@ -719,7 +707,7 @@ BOOL WINAPI CryptUnregisterOIDInfo(PCCRYPT_OID_INFO info) return FALSE; } - err = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Cryptography\\OID\\EncodingType 0\\CryptDllFindOIDInfo", 0, KEY_ALL_ACCESS, &root); + err = RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Cryptography\\OID\\EncodingType 0\\CryptDllFindOIDInfo", 0, KEY_ALL_ACCESS, &root); if (err != ERROR_SUCCESS) { SetLastError(err); @@ -729,7 +717,7 @@ BOOL WINAPI CryptUnregisterOIDInfo(PCCRYPT_OID_INFO info) key_name = CryptMemAlloc(strlen(info->pszOID) + 16); if (key_name) { - sprintf(key_name, "%s!%u", info->pszOID, info->dwGroupId); + sprintf(key_name, "%s!%lu", info->pszOID, info->dwGroupId); err = RegDeleteKeyA(root, key_name); } else @@ -753,7 +741,7 @@ BOOL WINAPI CryptRegisterOIDInfo(PCCRYPT_OID_INFO info, DWORD flags) HKEY root = 0, key = 0; DWORD err; - TRACE("(%p, %x)\n", info, flags ); + TRACE("(%p, %lx)\n", info, flags ); if (!info || info->cbSize != sizeof(*info) || !info->pszOID) { @@ -770,47 +758,47 @@ BOOL WINAPI CryptRegisterOIDInfo(PCCRYPT_OID_INFO info, DWORD flags) goto done; } - err = RegCreateKeyExA(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Cryptography\\OID\\EncodingType 0\\CryptDllFindOIDInfo", + err = RegCreateKeyExW(HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Cryptography\\OID\\EncodingType 0\\CryptDllFindOIDInfo", 0, NULL, 0, KEY_ALL_ACCESS, NULL, &root, NULL); if (err != ERROR_SUCCESS) goto done; - sprintf(key_name, "%s!%u", info->pszOID, info->dwGroupId); + sprintf(key_name, "%s!%lu", info->pszOID, info->dwGroupId); err = RegCreateKeyA(root, key_name, &key); if (err != ERROR_SUCCESS) goto done; if (flags) { - err = RegSetValueExW(key, flagsW, 0, REG_DWORD, (const BYTE *)&flags, sizeof(flags)); + err = RegSetValueExW(key, L"Flags", 0, REG_DWORD, (const BYTE *)&flags, sizeof(flags)); if (err != ERROR_SUCCESS) goto done; } if (info->pwszName) { - err = RegSetValueExW(key, nameW, 0, REG_SZ, (const BYTE *)info->pwszName, (lstrlenW(info->pwszName) + 1) * sizeof(WCHAR)); + err = RegSetValueExW(key, L"Name", 0, REG_SZ, (const BYTE *)info->pwszName, (lstrlenW(info->pwszName) + 1) * sizeof(WCHAR)); if (err != ERROR_SUCCESS) goto done; } - if (info->u.Algid) + if (info->Algid) { - err = RegSetValueExW(key, algidW, 0, REG_DWORD, (const BYTE *)&info->u.Algid, sizeof(info->u.Algid)); + err = RegSetValueExW(key, L"Algid", 0, REG_DWORD, (const BYTE *)&info->Algid, sizeof(info->Algid)); if (err != ERROR_SUCCESS) goto done; } if (info->ExtraInfo.cbData && info->ExtraInfo.pbData) { - err = RegSetValueExW(key, extraW, 0, REG_BINARY, info->ExtraInfo.pbData, info->ExtraInfo.cbData); + err = RegSetValueExW(key, L"ExtraInfo", 0, REG_BINARY, info->ExtraInfo.pbData, info->ExtraInfo.cbData); if (err != ERROR_SUCCESS) goto done; } if (info->pwszCNGAlgid) { - err = RegSetValueExW(key, cngalgidW, 0, REG_SZ, (const BYTE *)info->pwszCNGAlgid, (lstrlenW(info->pwszCNGAlgid) + 1) * sizeof(WCHAR)); + err = RegSetValueExW(key, L"CNGAlgid", 0, REG_SZ, (const BYTE *)info->pwszCNGAlgid, (lstrlenW(info->pwszCNGAlgid) + 1) * sizeof(WCHAR)); if (err != ERROR_SUCCESS) goto done; } if (info->pwszCNGExtraAlgid) { - err = RegSetValueExW(key, cngextraalgidW, 0, REG_SZ, (const BYTE *)info->pwszCNGExtraAlgid, (lstrlenW(info->pwszCNGExtraAlgid) + 1) * sizeof(WCHAR)); + err = RegSetValueExW(key, L"CNGExtraAlgid", 0, REG_SZ, (const BYTE *)info->pwszCNGExtraAlgid, (lstrlenW(info->pwszCNGExtraAlgid) + 1) * sizeof(WCHAR)); if (err != ERROR_SUCCESS) goto done; } @@ -834,7 +822,7 @@ BOOL WINAPI CryptUnregisterOIDFunction(DWORD dwEncodingType, LPCSTR pszFuncName, LPSTR szKey; LONG rc; - TRACE("%x %s %s\n", dwEncodingType, debugstr_a(pszFuncName), + TRACE("%lx %s %s\n", dwEncodingType, debugstr_a(pszFuncName), debugstr_a(pszOID)); if (!pszFuncName || !pszOID) @@ -859,7 +847,7 @@ BOOL WINAPI CryptGetOIDFunctionValue(DWORD dwEncodingType, LPCSTR pszFuncName, LONG rc; HKEY hKey; - TRACE("%x %s %s %s %p %p %p\n", dwEncodingType, debugstr_a(pszFuncName), + TRACE("%lx %s %s %s %p %p %p\n", dwEncodingType, debugstr_a(pszFuncName), debugstr_a(pszOID), debugstr_w(pwszValueName), pdwValueType, pbValueData, pcbValueData); @@ -896,7 +884,7 @@ BOOL WINAPI CryptSetOIDFunctionValue(DWORD dwEncodingType, LPCSTR pszFuncName, LONG rc; HKEY hKey; - TRACE("%x %s %s %s %d %p %d\n", dwEncodingType, debugstr_a(pszFuncName), + TRACE("%lx %s %s %s %ld %p %ld\n", dwEncodingType, debugstr_a(pszFuncName), debugstr_a(pszOID), debugstr_w(pwszValueName), dwValueType, pbValueData, cbValueData); @@ -1076,11 +1064,11 @@ static LPWSTR CRYPT_GetDefaultOIDDlls(HKEY key) DWORD type, size; LPWSTR dlls; - r = RegQueryValueExW(key, DllW, NULL, &type, NULL, &size); + r = RegQueryValueExW(key, L"Dll", NULL, &type, NULL, &size); if (r == ERROR_SUCCESS && type == REG_MULTI_SZ) { dlls = CryptMemAlloc(size); - r = RegQueryValueExW(key, DllW, NULL, &type, (LPBYTE)dlls, &size); + r = RegQueryValueExW(key, L"Dll", NULL, &type, (LPBYTE)dlls, &size); if (r != ERROR_SUCCESS) { CryptMemFree(dlls); @@ -1097,7 +1085,7 @@ static inline BOOL CRYPT_SetDefaultOIDDlls(HKEY key, LPCWSTR dlls) DWORD len = CRYPT_GetMultiStringCharacterLen(dlls); LONG r; - if ((r = RegSetValueExW(key, DllW, 0, REG_MULTI_SZ, (const BYTE *)dlls, + if ((r = RegSetValueExW(key, L"Dll", 0, REG_MULTI_SZ, (const BYTE *)dlls, len * sizeof (WCHAR)))) SetLastError(r); return r == ERROR_SUCCESS; @@ -1113,7 +1101,7 @@ BOOL WINAPI CryptRegisterDefaultOIDFunction(DWORD dwEncodingType, LPWSTR dlls; BOOL ret = FALSE; - TRACE("(%x, %s, %d, %s)\n", dwEncodingType, debugstr_a(pszFuncName), + TRACE("(%lx, %s, %ld, %s)\n", dwEncodingType, debugstr_a(pszFuncName), dwIndex, debugstr_w(pwszDll)); if (!pwszDll) @@ -1146,7 +1134,7 @@ BOOL WINAPI CryptUnregisterDefaultOIDFunction(DWORD dwEncodingType, LPWSTR dlls; BOOL ret; - TRACE("(%x, %s, %s)\n", dwEncodingType, debugstr_a(pszFuncName), + TRACE("(%lx, %s, %s)\n", dwEncodingType, debugstr_a(pszFuncName), debugstr_w(pwszDll)); if (!pwszDll) @@ -1205,79 +1193,6 @@ static CRITICAL_SECTION_DEBUG oidInfoCSDebug = static CRITICAL_SECTION oidInfoCS = { &oidInfoCSDebug, -1, 0, 0, 0, 0 }; static struct list oidInfo = { &oidInfo, &oidInfo }; -static const WCHAR tripledes[] = { '3','d','e','s',0 }; -static const WCHAR cms3deswrap[] = { 'C','M','S','3','D','E','S','w','r','a', - 'p',0 }; -static const WCHAR cmsrc2wrap[] = { 'C','M','S','R','C','2','w','r','a','p',0 }; -static const WCHAR des[] = { 'd','e','s',0 }; -static const WCHAR md2[] = { 'm','d','2',0 }; -static const WCHAR md4[] = { 'm','d','4',0 }; -static const WCHAR md5[] = { 'm','d','5',0 }; -static const WCHAR rc2[] = { 'r','c','2',0 }; -static const WCHAR rc4[] = { 'r','c','4',0 }; -static const WCHAR sha[] = { 's','h','a',0 }; -static const WCHAR sha1[] = { 's','h','a','1',0 }; -static const WCHAR sha256[] = { 's','h','a','2','5','6',0 }; -static const WCHAR sha384[] = { 's','h','a','3','8','4',0 }; -static const WCHAR sha512[] = { 's','h','a','5','1','2',0 }; -static const WCHAR RSA[] = { 'R','S','A',0 }; -static const WCHAR RSA_KEYX[] = { 'R','S','A','_','K','E','Y','X',0 }; -static const WCHAR RSA_SIGN[] = { 'R','S','A','_','S','I','G','N',0 }; -static const WCHAR DSA[] = { 'D','S','A',0 }; -static const WCHAR DSA_SIGN[] = { 'D','S','A','_','S','I','G','N',0 }; -static const WCHAR DH[] = { 'D','H',0 }; -static const WCHAR DSS[] = { 'D','S','S',0 }; -static const WCHAR mosaicKMandUpdSig[] = - { 'm','o','s','a','i','c','K','M','a','n','d','U','p','d','S','i','g',0 }; -static const WCHAR ESDH[] = { 'E','S','D','H',0 }; -static const WCHAR NO_SIGN[] = { 'N','O','S','I','G','N',0 }; -static const WCHAR dsaSHA1[] = { 'd','s','a','S','H','A','1',0 }; -static const WCHAR md2RSA[] = { 'm','d','2','R','S','A',0 }; -static const WCHAR md4RSA[] = { 'm','d','4','R','S','A',0 }; -static const WCHAR md5RSA[] = { 'm','d','5','R','S','A',0 }; -static const WCHAR shaDSA[] = { 's','h','a','D','S','A',0 }; -static const WCHAR sha1DSA[] = { 's','h','a','1','D','S','A',0 }; -static const WCHAR shaRSA[] = { 's','h','a','R','S','A',0 }; -static const WCHAR sha1RSA[] = { 's','h','a','1','R','S','A',0 }; -static const WCHAR sha256RSA[] = { 's','h','a','2','5','6','R','S','A',0 }; -static const WCHAR sha384RSA[] = { 's','h','a','3','8','4','R','S','A',0 }; -static const WCHAR sha512RSA[] = { 's','h','a','5','1','2','R','S','A',0 }; -static const WCHAR mosaicUpdatedSig[] = - { 'm','o','s','a','i','c','U','p','d','a','t','e','d','S','i','g',0 }; -static const WCHAR sha256ECDSA[] = { 's','h','a','2','5','6','E','C','D','S','A',0 }; -static const WCHAR sha384ECDSA[] = { 's','h','a','3','8','4','E','C','D','S','A',0 }; -static const WCHAR CN[] = { 'C','N',0 }; -static const WCHAR L[] = { 'L',0 }; -static const WCHAR O[] = { 'O',0 }; -static const WCHAR OU[] = { 'O','U',0 }; -static const WCHAR E[] = { 'E',0 }; -static const WCHAR C[] = { 'C',0 }; -static const WCHAR S[] = { 'S',0 }; -static const WCHAR ST[] = { 'S','T',0 }; -static const WCHAR STREET[] = { 'S','T','R','E','E','T',0 }; -static const WCHAR T[] = { 'T',0 }; -static const WCHAR Title[] = { 'T','i','t','l','e',0 }; -static const WCHAR G[] = { 'G',0 }; -static const WCHAR GivenName[] = { 'G','i','v','e','n','N','a','m','e',0 }; -static const WCHAR I[] = { 'I',0 }; -static const WCHAR Initials[] = { 'I','n','i','t','i','a','l','s',0 }; -static const WCHAR SN[] = { 'S','N',0 }; -static const WCHAR DC[] = { 'D','C',0 }; -static const WCHAR Description[] = - { 'D','e','s','c','r','i','p','t','i','o','n',0 }; -static const WCHAR PostalCode[] = { 'P','o','s','t','a','l','C','o','d','e',0 }; -static const WCHAR POBox[] = { 'P','O','B','o','x',0 }; -static const WCHAR Phone[] = { 'P','h','o','n','e',0 }; -static const WCHAR X21Address[] = { 'X','2','1','A','d','d','r','e','s','s',0 }; -static const WCHAR dnQualifier[] = - { 'd','n','Q','u','a','l','i','f','i','e','r',0 }; -static const WCHAR SpcSpAgencyInfo[] = { 'S','p','c','S','p','A','g','e','n','c','y','I','n','f','o',0 }; -static const WCHAR SpcFinancialCriteria[] = { 'S','p','c','F','i','n','a','n','c','i','a','l','C','r','i','t','e','r','i','a',0 }; -static const WCHAR SpcMinimalCriteria[] = { 'S','p','c','M','i','n','i','m','a','l','C','r','i','t','e','r','i','a',0 }; -static const WCHAR Email[] = { 'E','m','a','i','l',0 }; -static const WCHAR GN[] = { 'G','N',0 }; -static const WCHAR SERIALNUMBER[] = { 'S','E','R','I','A','L','N','U','M','B','E','R',0 }; - static const DWORD noNullFlag = CRYPT_OID_NO_NULL_ALGORITHM_PARA_FLAG; static const DWORD mosaicFlags = CRYPT_OID_INHIBIT_SIGNATURE_FORMAT_FLAG | CRYPT_OID_NO_NULL_ALGORITHM_PARA_FLAG; @@ -1324,91 +1239,91 @@ static const struct OIDInfoConstructor { const WCHAR *pwszCNGAlgid; const WCHAR *pwszCNGExtraAlgid; } oidInfoConstructors[] = { - { 1, szOID_OIWSEC_sha1, CALG_SHA1, sha1, NULL }, - { 1, szOID_OIWSEC_sha1, CALG_SHA1, sha, NULL }, - { 1, szOID_OIWSEC_sha, CALG_SHA, sha, NULL }, - { 1, szOID_RSA_MD5, CALG_MD5, md5, NULL }, - { 1, szOID_RSA_MD4, CALG_MD4, md4, NULL }, - { 1, szOID_RSA_MD2, CALG_MD2, md2, NULL }, + { 1, szOID_OIWSEC_sha1, CALG_SHA1, L"sha1", NULL }, + { 1, szOID_OIWSEC_sha1, CALG_SHA1, L"sha", NULL }, + { 1, szOID_OIWSEC_sha, CALG_SHA, L"sha", NULL }, + { 1, szOID_RSA_MD5, CALG_MD5, L"md5", NULL }, + { 1, szOID_RSA_MD4, CALG_MD4, L"md4", NULL }, + { 1, szOID_RSA_MD2, CALG_MD2, L"md2", NULL }, /* NOTE: Windows Vista+ uses -1 instead of CALG_SHA_* following SHA entries. */ - { 1, szOID_NIST_sha256, CALG_SHA_256, sha256, NULL }, - { 1, szOID_NIST_sha384, CALG_SHA_384, sha384, NULL }, - { 1, szOID_NIST_sha512, CALG_SHA_512, sha512, NULL }, + { 1, szOID_NIST_sha256, CALG_SHA_256, L"sha256", NULL }, + { 1, szOID_NIST_sha384, CALG_SHA_384, L"sha384", NULL }, + { 1, szOID_NIST_sha512, CALG_SHA_512, L"sha512", NULL }, - { 2, szOID_OIWSEC_desCBC, CALG_DES, des, NULL }, - { 2, szOID_RSA_DES_EDE3_CBC, CALG_3DES, tripledes, NULL }, - { 2, szOID_RSA_RC2CBC, CALG_RC2, rc2, NULL }, - { 2, szOID_RSA_RC4, CALG_RC4, rc4, NULL }, - { 2, szOID_RSA_SMIMEalgCMS3DESwrap, CALG_3DES, cms3deswrap, NULL }, - { 2, szOID_RSA_SMIMEalgCMSRC2wrap, CALG_RC2, cmsrc2wrap, NULL }, + { 2, szOID_OIWSEC_desCBC, CALG_DES, L"des", NULL }, + { 2, szOID_RSA_DES_EDE3_CBC, CALG_3DES, L"3des", NULL }, + { 2, szOID_RSA_RC2CBC, CALG_RC2, L"rc2", NULL }, + { 2, szOID_RSA_RC4, CALG_RC4, L"rc4", NULL }, + { 2, szOID_RSA_SMIMEalgCMS3DESwrap, CALG_3DES, L"CMS3DESwrap", NULL }, + { 2, szOID_RSA_SMIMEalgCMSRC2wrap, CALG_RC2, L"CMSRC2wrap", NULL }, - { 3, szOID_RSA_RSA, CALG_RSA_KEYX, RSA, NULL }, - { 3, szOID_X957_DSA, CALG_DSS_SIGN, DSA, &noNullBlob }, - { 3, szOID_ANSI_X942_DH, CALG_DH_SF, DH, &noNullBlob }, - { 3, szOID_RSA_RSA, CALG_RSA_KEYX, RSA_KEYX, NULL }, - { 3, szOID_RSA_RSA, CALG_RSA_SIGN, RSA, NULL }, - { 3, szOID_RSA_RSA, CALG_RSA_SIGN, RSA_SIGN, NULL }, - { 3, szOID_OIWSEC_dsa, CALG_DSS_SIGN, DSA, &noNullBlob }, - { 3, szOID_OIWSEC_dsa, CALG_DSS_SIGN, DSS, &noNullBlob }, - { 3, szOID_OIWSEC_dsa, CALG_DSS_SIGN, DSA_SIGN, &noNullBlob }, - { 3, szOID_RSA_DH, CALG_DH_SF, DH, &noNullBlob }, - { 3, szOID_OIWSEC_rsaXchg, CALG_RSA_KEYX, RSA_KEYX, NULL }, - { 3, szOID_INFOSEC_mosaicKMandUpdSig, CALG_DSS_SIGN, mosaicKMandUpdSig, - &mosaicFlagsBlob }, - { 3, szOID_RSA_SMIMEalgESDH, CALG_DH_EPHEM, ESDH, &noNullBlob }, - { 3, szOID_PKIX_NO_SIGNATURE, CALG_NO_SIGN, NO_SIGN, NULL }, + { 3, szOID_RSA_RSA, CALG_RSA_KEYX, L"RSA", NULL }, + { 3, szOID_X957_DSA, CALG_DSS_SIGN, L"DSA", &noNullBlob }, + { 3, szOID_ANSI_X942_DH, CALG_DH_SF, L"DH", &noNullBlob }, + { 3, szOID_RSA_RSA, CALG_RSA_KEYX, L"RSA_KEYX", NULL }, + { 3, szOID_RSA_RSA, CALG_RSA_SIGN, L"RSA", NULL }, + { 3, szOID_RSA_RSA, CALG_RSA_SIGN, L"RSA_SIGN", NULL }, + { 3, szOID_OIWSEC_dsa, CALG_DSS_SIGN, L"DSA", &noNullBlob }, + { 3, szOID_OIWSEC_dsa, CALG_DSS_SIGN, L"DSS", &noNullBlob }, + { 3, szOID_OIWSEC_dsa, CALG_DSS_SIGN, L"DSA_SIGN", &noNullBlob }, + { 3, szOID_RSA_DH, CALG_DH_SF, L"DH", &noNullBlob }, + { 3, szOID_OIWSEC_rsaXchg, CALG_RSA_KEYX, L"RSA_KEYX", NULL }, + { 3, szOID_INFOSEC_mosaicKMandUpdSig, CALG_DSS_SIGN, L"mosaicKMandUpdSig", &mosaicFlagsBlob }, + { 3, szOID_RSA_SMIMEalgESDH, CALG_DH_EPHEM, L"ESDH", &noNullBlob }, + { 3, szOID_PKIX_NO_SIGNATURE, CALG_NO_SIGN, L"NOSIGN", NULL }, + { 3, szOID_ECC_PUBLIC_KEY, CALG_OID_INFO_PARAMETERS, L"ECC", NULL, + CRYPT_OID_INFO_ECC_PARAMETERS_ALGORITHM, L"" }, - { 4, szOID_RSA_SHA1RSA, CALG_SHA1, sha1RSA, &rsaSignBlob }, - { 4, szOID_RSA_SHA256RSA, CALG_SHA_256, sha256RSA, &rsaSignBlob }, - { 4, szOID_RSA_SHA384RSA, CALG_SHA_384, sha384RSA, &rsaSignBlob }, - { 4, szOID_RSA_SHA512RSA, CALG_SHA_512, sha512RSA, &rsaSignBlob }, - { 4, szOID_RSA_MD5RSA, CALG_MD5, md5RSA, &rsaSignBlob }, - { 4, szOID_X957_SHA1DSA, CALG_SHA1, sha1DSA, &dssSignBlob }, - { 4, szOID_OIWSEC_sha1RSASign, CALG_SHA1, sha1RSA, &rsaSignBlob }, - { 4, szOID_OIWSEC_sha1RSASign, CALG_SHA1, shaRSA, &rsaSignBlob }, - { 4, szOID_OIWSEC_shaRSA, CALG_SHA1, shaRSA, &rsaSignBlob }, - { 4, szOID_OIWSEC_md5RSA, CALG_MD5, md5RSA, &rsaSignBlob }, - { 4, szOID_RSA_MD2RSA, CALG_MD2, md2RSA, &rsaSignBlob }, - { 4, szOID_RSA_MD4RSA, CALG_MD4, md4RSA, &rsaSignBlob }, - { 4, szOID_OIWSEC_md4RSA, CALG_MD4, md4RSA, &rsaSignBlob }, - { 4, szOID_OIWSEC_md4RSA2, CALG_MD4, md4RSA, &rsaSignBlob }, - { 4, szOID_OIWDIR_md2RSA, CALG_MD2, md2RSA, &rsaSignBlob }, - { 4, szOID_OIWSEC_shaDSA, CALG_SHA1, sha1DSA, &dssSignBlob }, - { 4, szOID_OIWSEC_shaDSA, CALG_SHA1, shaDSA, &dssSignBlob }, - { 4, szOID_OIWSEC_dsaSHA1, CALG_SHA1, dsaSHA1, &dssSignBlob }, - { 4, szOID_INFOSEC_mosaicUpdatedSig, CALG_SHA1, mosaicUpdatedSig, - &mosaicSignBlob }, - { 4, szOID_ECDSA_SHA256, CALG_OID_INFO_CNG_ONLY, sha256ECDSA, &ecdsaSignBlob, + { 4, szOID_RSA_SHA1RSA, CALG_SHA1, L"sha1RSA", &rsaSignBlob }, + { 4, szOID_RSA_SHA256RSA, CALG_SHA_256, L"sha256RSA", &rsaSignBlob }, + { 4, szOID_RSA_SHA384RSA, CALG_SHA_384, L"sha384RSA", &rsaSignBlob }, + { 4, szOID_RSA_SHA512RSA, CALG_SHA_512, L"sha512RSA", &rsaSignBlob }, + { 4, szOID_RSA_MD5RSA, CALG_MD5, L"md5RSA", &rsaSignBlob }, + { 4, szOID_X957_SHA1DSA, CALG_SHA1, L"sha1DSA", &dssSignBlob }, + { 4, szOID_OIWSEC_sha1RSASign, CALG_SHA1, L"sha1RSA", &rsaSignBlob }, + { 4, szOID_OIWSEC_sha1RSASign, CALG_SHA1, L"shaRSA", &rsaSignBlob }, + { 4, szOID_OIWSEC_shaRSA, CALG_SHA1, L"shaRSA", &rsaSignBlob }, + { 4, szOID_OIWSEC_md5RSA, CALG_MD5, L"md5RSA", &rsaSignBlob }, + { 4, szOID_RSA_MD2RSA, CALG_MD2, L"md2RSA", &rsaSignBlob }, + { 4, szOID_RSA_MD4RSA, CALG_MD4, L"md4RSA", &rsaSignBlob }, + { 4, szOID_OIWSEC_md4RSA, CALG_MD4, L"md4RSA", &rsaSignBlob }, + { 4, szOID_OIWSEC_md4RSA2, CALG_MD4, L"md4RSA", &rsaSignBlob }, + { 4, szOID_OIWDIR_md2RSA, CALG_MD2, L"md2RSA", &rsaSignBlob }, + { 4, szOID_OIWSEC_shaDSA, CALG_SHA1, L"sha1DSA", &dssSignBlob }, + { 4, szOID_OIWSEC_shaDSA, CALG_SHA1, L"shaDSA", &dssSignBlob }, + { 4, szOID_OIWSEC_dsaSHA1, CALG_SHA1, L"dsaSHA1", &dssSignBlob }, + { 4, szOID_INFOSEC_mosaicUpdatedSig, CALG_SHA1, L"mosaicUpdatedSig", &mosaicSignBlob }, + { 4, szOID_ECDSA_SHA256, CALG_OID_INFO_CNG_ONLY, L"sha256ECDSA", &ecdsaSignBlob, BCRYPT_SHA256_ALGORITHM, CRYPT_OID_INFO_ECC_PARAMETERS_ALGORITHM }, - { 4, szOID_ECDSA_SHA384, CALG_OID_INFO_CNG_ONLY, sha384ECDSA, &ecdsaSignBlob, + { 4, szOID_ECDSA_SHA384, CALG_OID_INFO_CNG_ONLY, L"sha384ECDSA", &ecdsaSignBlob, BCRYPT_SHA384_ALGORITHM, CRYPT_OID_INFO_ECC_PARAMETERS_ALGORITHM }, - { 5, szOID_COMMON_NAME, 0, CN, NULL }, - { 5, szOID_LOCALITY_NAME, 0, L, NULL }, - { 5, szOID_ORGANIZATION_NAME, 0, O, NULL }, - { 5, szOID_ORGANIZATIONAL_UNIT_NAME, 0, OU, NULL }, - { 5, szOID_RSA_emailAddr, 0, E, &ia5StringBlob }, - { 5, szOID_RSA_emailAddr, 0, Email, &ia5StringBlob }, - { 5, szOID_COUNTRY_NAME, 0, C, &printableStringBlob }, - { 5, szOID_STATE_OR_PROVINCE_NAME, 0, S, NULL }, - { 5, szOID_STATE_OR_PROVINCE_NAME, 0, ST, NULL }, - { 5, szOID_STREET_ADDRESS, 0, STREET, NULL }, - { 5, szOID_TITLE, 0, T, NULL }, - { 5, szOID_TITLE, 0, Title, NULL }, - { 5, szOID_GIVEN_NAME, 0, G, NULL }, - { 5, szOID_GIVEN_NAME, 0, GN, NULL }, - { 5, szOID_GIVEN_NAME, 0, GivenName, NULL }, - { 5, szOID_INITIALS, 0, I, NULL }, - { 5, szOID_INITIALS, 0, Initials, NULL }, - { 5, szOID_SUR_NAME, 0, SN, NULL }, - { 5, szOID_DOMAIN_COMPONENT, 0, DC, &domainCompTypesBlob }, - { 5, szOID_DESCRIPTION, 0, Description, NULL }, - { 5, szOID_POSTAL_CODE, 0, PostalCode, NULL }, - { 5, szOID_POST_OFFICE_BOX, 0, POBox, NULL }, - { 5, szOID_TELEPHONE_NUMBER, 0, Phone, &printableStringBlob }, - { 5, szOID_X21_ADDRESS, 0, X21Address, &numericStringBlob }, - { 5, szOID_DN_QUALIFIER, 0, dnQualifier, NULL }, - { 5, szOID_DEVICE_SERIAL_NUMBER, 0, SERIALNUMBER, NULL }, + { 5, szOID_COMMON_NAME, 0, L"CN", NULL }, + { 5, szOID_LOCALITY_NAME, 0, L"L", NULL }, + { 5, szOID_ORGANIZATION_NAME, 0, L"O", NULL }, + { 5, szOID_ORGANIZATIONAL_UNIT_NAME, 0, L"OU", NULL }, + { 5, szOID_RSA_emailAddr, 0, L"E", &ia5StringBlob }, + { 5, szOID_RSA_emailAddr, 0, L"Email", &ia5StringBlob }, + { 5, szOID_COUNTRY_NAME, 0, L"C", &printableStringBlob }, + { 5, szOID_STATE_OR_PROVINCE_NAME, 0, L"S", NULL }, + { 5, szOID_STATE_OR_PROVINCE_NAME, 0, L"ST", NULL }, + { 5, szOID_STREET_ADDRESS, 0, L"STREET", NULL }, + { 5, szOID_TITLE, 0, L"T", NULL }, + { 5, szOID_TITLE, 0, L"Title", NULL }, + { 5, szOID_GIVEN_NAME, 0, L"G", NULL }, + { 5, szOID_GIVEN_NAME, 0, L"GN", NULL }, + { 5, szOID_GIVEN_NAME, 0, L"GivenName", NULL }, + { 5, szOID_INITIALS, 0, L"I", NULL }, + { 5, szOID_INITIALS, 0, L"Initials", NULL }, + { 5, szOID_SUR_NAME, 0, L"SN", NULL }, + { 5, szOID_DOMAIN_COMPONENT, 0, L"DC", &domainCompTypesBlob }, + { 5, szOID_DESCRIPTION, 0, L"Description", NULL }, + { 5, szOID_POSTAL_CODE, 0, L"PostalCode", NULL }, + { 5, szOID_POST_OFFICE_BOX, 0, L"POBox", NULL }, + { 5, szOID_TELEPHONE_NUMBER, 0, L"Phone", &printableStringBlob }, + { 5, szOID_X21_ADDRESS, 0, L"X21Address", &numericStringBlob }, + { 5, szOID_DN_QUALIFIER, 0, L"dnQualifier", NULL }, + { 5, szOID_DEVICE_SERIAL_NUMBER, 0, L"SERIALNUMBER", NULL }, { 6, szOID_AUTHORITY_KEY_IDENTIFIER2, 0, (LPCWSTR)IDS_AUTHORITY_KEY_ID, NULL }, { 6, szOID_AUTHORITY_KEY_IDENTIFIER, 0, (LPCWSTR)IDS_AUTHORITY_KEY_ID, NULL }, @@ -1456,9 +1371,9 @@ static const struct OIDInfoConstructor { { 6, szOID_NETSCAPE_CA_POLICY_URL, 0, (LPCWSTR)IDS_NETSCAPE_CA_POLICY_URL, NULL }, { 6, szOID_NETSCAPE_SSL_SERVER_NAME, 0, (LPCWSTR)IDS_NETSCAPE_SSL_SERVER_NAME, NULL }, { 6, szOID_NETSCAPE_COMMENT, 0, (LPCWSTR)IDS_NETSCAPE_COMMENT, NULL }, - { 6, "1.3.6.1.4.1.311.2.1.10", 0, SpcSpAgencyInfo, NULL }, - { 6, "1.3.6.1.4.1.311.2.1.27", 0, SpcFinancialCriteria, NULL }, - { 6, "1.3.6.1.4.1.311.2.1.26", 0, SpcMinimalCriteria, NULL }, + { 6, "1.3.6.1.4.1.311.2.1.10", 0, L"SpcSpAgencyInfo", NULL }, + { 6, "1.3.6.1.4.1.311.2.1.27", 0, L"SpcFinancialCriteria", NULL }, + { 6, "1.3.6.1.4.1.311.2.1.26", 0, L"SpcMinimalCriteria", NULL }, { 6, szOID_COUNTRY_NAME, 0, (LPCWSTR)IDS_COUNTRY, NULL }, { 6, szOID_ORGANIZATION_NAME, 0, (LPCWSTR)IDS_ORGANIZATION, NULL }, { 6, szOID_ORGANIZATIONAL_UNIT_NAME, 0, (LPCWSTR)IDS_ORGANIZATIONAL_UNIT, NULL }, @@ -1587,17 +1502,17 @@ static struct OIDInfo *read_oid_info(HKEY root, char *key_name, DWORD *flags) oid_len = strlen(key_name) + 1; - RegQueryValueExW(key, nameW, NULL, NULL, NULL, &name_len); - RegQueryValueExW(key, extraW, NULL, NULL, NULL, &extra_len); - RegQueryValueExW(key, cngalgidW, NULL, NULL, NULL, &cngalgid_len); - RegQueryValueExW(key, cngextraalgidW, NULL, NULL, NULL, &cngextra_len); + RegQueryValueExW(key, L"Name", NULL, NULL, NULL, &name_len); + RegQueryValueExW(key, L"ExtraInfo", NULL, NULL, NULL, &extra_len); + RegQueryValueExW(key, L"CNGAlgid", NULL, NULL, NULL, &cngalgid_len); + RegQueryValueExW(key, L"CNGExtraAlgid", NULL, NULL, NULL, &cngextra_len); info = CryptMemAlloc(sizeof(*info) + oid_len + name_len + extra_len + cngalgid_len + cngextra_len); if (info) { *flags = 0; len = sizeof(*flags); - RegQueryValueExW(key, flagsW, NULL, NULL, (BYTE *)flags, &len); + RegQueryValueExW(key, L"Flags", NULL, NULL, (BYTE *)flags, &len); memset(info, 0, sizeof(*info)); info->info.cbSize = sizeof(info->info); @@ -1611,34 +1526,34 @@ static struct OIDInfo *read_oid_info(HKEY root, char *key_name, DWORD *flags) if (name_len) { info->info.pwszName = (WCHAR *)p; - RegQueryValueExW(key, nameW, NULL, NULL, (BYTE *)info->info.pwszName, &name_len); + RegQueryValueExW(key, L"Name", NULL, NULL, (BYTE *)info->info.pwszName, &name_len); p += name_len; } info->info.dwGroupId = group_id; - len = sizeof(info->info.u.Algid); - RegQueryValueExW(key, algidW, NULL, NULL, (BYTE *)&info->info.u.Algid, &len); + len = sizeof(info->info.Algid); + RegQueryValueExW(key, L"Algid", NULL, NULL, (BYTE *)&info->info.Algid, &len); if (extra_len) { info->info.ExtraInfo.cbData = extra_len; info->info.ExtraInfo.pbData = (BYTE *)p; - RegQueryValueExW(key, extraW, NULL, NULL, info->info.ExtraInfo.pbData, &extra_len); + RegQueryValueExW(key, L"ExtraInfo", NULL, NULL, info->info.ExtraInfo.pbData, &extra_len); p += extra_len; } if (cngalgid_len) { info->info.pwszCNGAlgid = (WCHAR *)p; - RegQueryValueExW(key, cngalgidW, NULL, NULL, (BYTE *)info->info.pwszCNGAlgid, &cngalgid_len); + RegQueryValueExW(key, L"CNGAlgid", NULL, NULL, (BYTE *)info->info.pwszCNGAlgid, &cngalgid_len); p += cngalgid_len; } if (cngextra_len) { info->info.pwszCNGExtraAlgid = (WCHAR *)p; - RegQueryValueExW(key, cngextraalgidW, NULL, NULL, (BYTE *)info->info.pwszCNGExtraAlgid, &cngalgid_len); + RegQueryValueExW(key, L"CNGExtraAlgid", NULL, NULL, (BYTE *)info->info.pwszCNGExtraAlgid, &cngalgid_len); } } @@ -1652,7 +1567,7 @@ static void init_registered_oid_info(void) DWORD err, idx; HKEY root; - err = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Cryptography\\OID\\EncodingType 0\\CryptDllFindOIDInfo", + err = RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Cryptography\\OID\\EncodingType 0\\CryptDllFindOIDInfo", 0, KEY_ALL_ACCESS, &root); if (err != ERROR_SUCCESS) return; @@ -1671,9 +1586,9 @@ static void init_registered_oid_info(void) { if ((info = read_oid_info(root, key_name, &flags))) { - TRACE("adding oid %s, name %s, groupid %u, algid %u, extra %u, CNG algid %s, CNG extra %s\n", + TRACE("adding oid %s, name %s, groupid %lu, algid %u, extra %lu, CNG algid %s, CNG extra %s\n", debugstr_a(info->info.pszOID), debugstr_w(info->info.pwszName), - info->info.dwGroupId, info->info.u.Algid, info->info.ExtraInfo.cbData, + info->info.dwGroupId, info->info.Algid, info->info.ExtraInfo.cbData, debugstr_w(info->info.pwszCNGAlgid), debugstr_w(info->info.pwszCNGExtraAlgid)); if (flags & CRYPT_INSTALL_OID_INFO_BEFORE_FLAG) @@ -1707,7 +1622,7 @@ static void init_oid_info(void) info->info.pszOID = oidInfoConstructors[i].pszOID; info->info.pwszName = oidInfoConstructors[i].pwszName; info->info.dwGroupId = oidInfoConstructors[i].dwGroupId; - info->info.u.Algid = oidInfoConstructors[i].Algid; + info->info.Algid = oidInfoConstructors[i].Algid; if (oidInfoConstructors[i].blob) { info->info.ExtraInfo.cbData = @@ -1739,7 +1654,7 @@ static void init_oid_info(void) info->info.pszOID = oidInfoConstructors[i].pszOID; info->info.pwszName = (LPWSTR)(info + 1); info->info.dwGroupId = oidInfoConstructors[i].dwGroupId; - info->info.u.Algid = oidInfoConstructors[i].Algid; + info->info.Algid = oidInfoConstructors[i].Algid; memcpy(info + 1, stringresource, len*sizeof(WCHAR)); ((LPWSTR)(info + 1))[len] = 0; if (oidInfoConstructors[i].blob) @@ -1779,7 +1694,7 @@ BOOL WINAPI CryptEnumOIDInfo(DWORD dwGroupId, DWORD dwFlags, void *pvArg, BOOL ret = TRUE; struct OIDInfo *info; - TRACE("(%d, %08x, %p, %p)\n", dwGroupId, dwFlags, pvArg, + TRACE("(%ld, %08lx, %p, %p)\n", dwGroupId, dwFlags, pvArg, pfnEnumOIDInfo); EnterCriticalSection(&oidInfoCS); @@ -1801,7 +1716,7 @@ PCCRYPT_OID_INFO WINAPI CryptFindOIDInfo(DWORD dwKeyType, void *pvKey, { PCCRYPT_OID_INFO ret = NULL; - TRACE("(%d, %p, %d)\n", dwKeyType, pvKey, dwGroupId); + TRACE("(%ld, %p, %ld)\n", dwKeyType, pvKey, dwGroupId); switch(dwKeyType) { @@ -1809,11 +1724,11 @@ PCCRYPT_OID_INFO WINAPI CryptFindOIDInfo(DWORD dwKeyType, void *pvKey, { struct OIDInfo *info; - TRACE("CRYPT_OID_INFO_ALGID_KEY: %d\n", *(DWORD *)pvKey); + TRACE("CRYPT_OID_INFO_ALGID_KEY: %ld\n", *(DWORD *)pvKey); EnterCriticalSection(&oidInfoCS); LIST_FOR_EACH_ENTRY(info, &oidInfo, struct OIDInfo, entry) { - if (info->info.u.Algid == *(DWORD *)pvKey && + if (info->info.Algid == *(DWORD *)pvKey && (!dwGroupId || info->info.dwGroupId == dwGroupId)) { ret = &info->info; @@ -1831,7 +1746,7 @@ PCCRYPT_OID_INFO WINAPI CryptFindOIDInfo(DWORD dwKeyType, void *pvKey, EnterCriticalSection(&oidInfoCS); LIST_FOR_EACH_ENTRY(info, &oidInfo, struct OIDInfo, entry) { - if (!lstrcmpW(info->info.pwszName, pvKey) && + if (!wcscmp(info->info.pwszName, pvKey) && (!dwGroupId || info->info.dwGroupId == dwGroupId)) { ret = &info->info; @@ -1864,11 +1779,11 @@ PCCRYPT_OID_INFO WINAPI CryptFindOIDInfo(DWORD dwKeyType, void *pvKey, { struct OIDInfo *info; - TRACE("CRYPT_OID_INFO_SIGN_KEY: %d\n", *(DWORD *)pvKey); + TRACE("CRYPT_OID_INFO_SIGN_KEY: %ld\n", *(DWORD *)pvKey); EnterCriticalSection(&oidInfoCS); LIST_FOR_EACH_ENTRY(info, &oidInfo, struct OIDInfo, entry) { - if (info->info.u.Algid == *(DWORD *)pvKey && + if (info->info.Algid == *(DWORD *)pvKey && info->info.ExtraInfo.cbData >= sizeof(DWORD) && *(DWORD *)info->info.ExtraInfo.pbData == *(DWORD *)((LPBYTE)pvKey + sizeof(DWORD)) && @@ -1905,7 +1820,7 @@ DWORD WINAPI CertOIDToAlgId(LPCSTR pszObjId) (void *)pszObjId, 0); if (info) - ret = info->u.Algid; + ret = info->Algid; else ret = 0; return ret; diff --git a/dll/win32/crypt32/pfx.c b/dll/win32/crypt32/pfx.c new file mode 100644 index 00000000000..2487ed6f214 --- /dev/null +++ b/dll/win32/crypt32/pfx.c @@ -0,0 +1,242 @@ +/* + * Copyright 2019 Hans Leidekker for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include + +#include "ntstatus.h" +#define WIN32_NO_STATUS +#include "windef.h" +#include "winbase.h" +#include "wincrypt.h" +#ifdef __REACTOS__ +#include +#endif +#include "snmp.h" +#include "crypt32_private.h" + +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(crypt); + +static HCRYPTPROV import_key( cert_store_data_t data, DWORD flags ) +{ + HCRYPTPROV prov = 0; + HCRYPTKEY cryptkey; + DWORD size, acquire_flags; + void *key; + struct import_store_key_params params = { data, NULL, &size }; + + if (CRYPT32_CALL( import_store_key, ¶ms ) != STATUS_BUFFER_TOO_SMALL) return 0; + + acquire_flags = (flags & CRYPT_MACHINE_KEYSET) | CRYPT_NEWKEYSET; + if (!CryptAcquireContextW( &prov, NULL, MS_ENHANCED_PROV_W, PROV_RSA_FULL, acquire_flags )) + { + if (GetLastError() != NTE_EXISTS) return 0; + + acquire_flags &= ~CRYPT_NEWKEYSET; + if (!CryptAcquireContextW( &prov, NULL, MS_ENHANCED_PROV_W, PROV_RSA_FULL, acquire_flags )) + { + WARN( "CryptAcquireContextW failed %08lx\n", GetLastError() ); + return 0; + } + } + + params.buf = key = CryptMemAlloc( size ); + if (CRYPT32_CALL( import_store_key, ¶ms ) || + !CryptImportKey( prov, key, size, 0, flags & CRYPT_EXPORTABLE, &cryptkey )) + { + WARN( "CryptImportKey failed %08lx\n", GetLastError() ); + CryptReleaseContext( prov, 0 ); + CryptMemFree( key ); + return 0; + } + CryptDestroyKey( cryptkey ); + CryptMemFree( key ); + return prov; +} + +static BOOL set_key_context( const void *ctx, HCRYPTPROV prov ) +{ + CERT_KEY_CONTEXT key_ctx; + key_ctx.cbSize = sizeof(key_ctx); + key_ctx.hCryptProv = prov; + key_ctx.dwKeySpec = AT_KEYEXCHANGE; + return CertSetCertificateContextProperty( ctx, CERT_KEY_CONTEXT_PROP_ID, 0, &key_ctx ); +} + +static WCHAR *get_provider_property( HCRYPTPROV prov, DWORD prop_id, DWORD *len ) +{ + DWORD size = 0; + WCHAR *ret; + char *str; + + CryptGetProvParam( prov, prop_id, NULL, &size, 0 ); + if (!size) return NULL; + if (!(str = CryptMemAlloc( size ))) return NULL; + CryptGetProvParam( prov, prop_id, (BYTE *)str, &size, 0 ); + + *len = MultiByteToWideChar( CP_ACP, 0, str, -1, NULL, 0 ); + if ((ret = CryptMemAlloc( *len * sizeof(WCHAR) ))) MultiByteToWideChar( CP_ACP, 0, str, -1, ret, *len ); + CryptMemFree( str ); + return ret; +} + +static BOOL set_key_prov_info( const void *ctx, HCRYPTPROV prov ) +{ + CRYPT_KEY_PROV_INFO *prov_info; + DWORD size, len_container, len_name; + WCHAR *ptr, *container, *name; + BOOL ret; + + if (!(container = get_provider_property( prov, PP_CONTAINER, &len_container ))) return FALSE; + if (!(name = get_provider_property( prov, PP_NAME, &len_name ))) + { + CryptMemFree( container ); + return FALSE; + } + if (!(prov_info = CryptMemAlloc( sizeof(*prov_info) + (len_container + len_name) * sizeof(WCHAR) ))) + { + CryptMemFree( container ); + CryptMemFree( name ); + return FALSE; + } + + ptr = (WCHAR *)(prov_info + 1); + prov_info->pwszContainerName = ptr; + lstrcpyW( prov_info->pwszContainerName, container ); + + ptr += len_container; + prov_info->pwszProvName = ptr; + lstrcpyW( prov_info->pwszProvName, name ); + + size = sizeof(prov_info->dwProvType); + CryptGetProvParam( prov, PP_PROVTYPE, (BYTE *)&prov_info->dwProvType, &size, 0 ); + + prov_info->dwFlags = 0; + prov_info->cProvParam = 0; + prov_info->rgProvParam = NULL; + size = sizeof(prov_info->dwKeySpec); + CryptGetProvParam( prov, PP_KEYSPEC, (BYTE *)&prov_info->dwKeySpec, &size, 0 ); + + ret = CertSetCertificateContextProperty( ctx, CERT_KEY_PROV_INFO_PROP_ID, 0, prov_info ); + + CryptMemFree( prov_info ); + CryptMemFree( name ); + CryptMemFree( container ); + return ret; +} + +HCERTSTORE WINAPI PFXImportCertStore( CRYPT_DATA_BLOB *pfx, const WCHAR *password, DWORD flags ) +{ + DWORD i = 0, size; + HCERTSTORE store = NULL; + HCRYPTPROV prov = 0; + cert_store_data_t data = 0; + struct open_cert_store_params open_params = { pfx, password, &data }; + struct close_cert_store_params close_params; + + if (!pfx) + { + SetLastError( ERROR_INVALID_PARAMETER ); + return NULL; + } + if (flags & ~(CRYPT_EXPORTABLE|CRYPT_USER_KEYSET|CRYPT_MACHINE_KEYSET|PKCS12_NO_PERSIST_KEY)) + { + FIXME( "flags %08lx not supported\n", flags ); + return NULL; + } + if (CRYPT32_CALL( open_cert_store, &open_params )) return NULL; + + prov = import_key( data, flags ); + if (!prov) goto error; + + if (!(store = CertOpenStore( CERT_STORE_PROV_MEMORY, 0, 0, 0, NULL ))) + { + WARN( "CertOpenStore failed %08lx\n", GetLastError() ); + goto error; + } + + for (;;) + { + const void *ctx = NULL; + void *cert; + struct import_store_cert_params import_params = { data, i, NULL, &size }; + + if (CRYPT32_CALL( import_store_cert, &import_params ) != STATUS_BUFFER_TOO_SMALL) break; + import_params.buf = cert = CryptMemAlloc( size ); + if (!CRYPT32_CALL( import_store_cert, &import_params )) + ctx = CertCreateContext( CERT_STORE_CERTIFICATE_CONTEXT, X509_ASN_ENCODING, cert, size, 0, NULL ); + CryptMemFree( cert ); + if (!ctx) + { + WARN( "CertCreateContext failed %08lx\n", GetLastError() ); + goto error; + } + if (flags & PKCS12_NO_PERSIST_KEY) + { + if (!set_key_context( ctx, prov )) + { + WARN( "failed to set context property %08lx\n", GetLastError() ); + CertFreeCertificateContext( ctx ); + goto error; + } + } + else if (!set_key_prov_info( ctx, prov )) + { + WARN( "failed to set provider info property %08lx\n", GetLastError() ); + CertFreeCertificateContext( ctx ); + goto error; + } + if (!CertAddCertificateContextToStore( store, ctx, CERT_STORE_ADD_ALWAYS, NULL )) + { + WARN( "CertAddCertificateContextToStore failed %08lx\n", GetLastError() ); + CertFreeCertificateContext( ctx ); + goto error; + } + CertFreeCertificateContext( ctx ); + i++; + } + close_params.data = data; + CRYPT32_CALL( close_cert_store, &close_params ); + return store; + +error: + CryptReleaseContext( prov, 0 ); + CertCloseStore( store, 0 ); + close_params.data = data; + CRYPT32_CALL( close_cert_store, &close_params ); + return NULL; +} + +BOOL WINAPI PFXVerifyPassword( CRYPT_DATA_BLOB *pfx, const WCHAR *password, DWORD flags ) +{ + FIXME( "(%p, %p, %08lx): stub\n", pfx, password, flags ); + return FALSE; +} + +BOOL WINAPI PFXExportCertStore( HCERTSTORE store, CRYPT_DATA_BLOB *pfx, const WCHAR *password, DWORD flags ) +{ + return PFXExportCertStoreEx( store, pfx, password, NULL, flags ); +} + +BOOL WINAPI PFXExportCertStoreEx( HCERTSTORE store, CRYPT_DATA_BLOB *pfx, const WCHAR *password, void *reserved, + DWORD flags ) +{ + FIXME( "(%p, %p, %p, %p, %08lx): stub\n", store, pfx, password, reserved, flags ); + return FALSE; +} diff --git a/dll/win32/crypt32/precomp.h b/dll/win32/crypt32/precomp.h index 90336916bca..38a39e7e24e 100644 --- a/dll/win32/crypt32/precomp.h +++ b/dll/win32/crypt32/precomp.h @@ -12,8 +12,6 @@ #define _INC_WINDOWS #define COM_NO_WINDOWS_H -#define NONAMELESSUNION - #include #define WIN32_NO_STATUS #include diff --git a/dll/win32/crypt32/proplist.c b/dll/win32/crypt32/proplist.c index f5ae2213525..acc2a43d8bc 100644 --- a/dll/win32/crypt32/proplist.c +++ b/dll/win32/crypt32/proplist.c @@ -46,7 +46,7 @@ CONTEXT_PROPERTY_LIST *ContextPropertyList_Create(void) if (list) { - InitializeCriticalSection(&list->cs); + InitializeCriticalSectionEx(&list->cs, 0, RTL_CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO); list->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": PCONTEXT_PROPERTY_LIST->cs"); list_init(&list->properties); } @@ -75,7 +75,7 @@ BOOL ContextPropertyList_FindProperty(CONTEXT_PROPERTY_LIST *list, DWORD id, CONTEXT_PROPERTY *prop; BOOL ret = FALSE; - TRACE("(%p, %d, %p)\n", list, id, blob); + TRACE("(%p, %ld, %p)\n", list, id, blob); EnterCriticalSection(&list->cs); LIST_FOR_EACH_ENTRY(prop, &list->properties, CONTEXT_PROPERTY, entry) diff --git a/dll/win32/crypt32/protectdata.c b/dll/win32/crypt32/protectdata.c index 20e11f457c8..f7d9f439872 100644 --- a/dll/win32/crypt32/protectdata.c +++ b/dll/win32/crypt32/protectdata.c @@ -330,7 +330,7 @@ BOOL serialize(const struct protect_data_t *pInfo, DATA_BLOB *pSerial) if (ptr - pSerial->pbData != dwStruct) { - ERR("struct size changed!? expected %u\n", dwStruct); + ERR("struct size changed!? expected %lu\n", dwStruct); LocalFree(pSerial->pbData); pSerial->pbData=NULL; pSerial->cbData=0; @@ -403,7 +403,7 @@ BOOL unserialize(const DATA_BLOB *pSerial, struct protect_data_t *pInfo) } /* cipher_alg */ - if (!unserialize_dword(ptr,&index,size,&pInfo->cipher_alg)) + if (!unserialize_dword(ptr,&index,size,(DWORD*)&pInfo->cipher_alg)) { ERR("reading cipher_alg failed!\n"); return FALSE; @@ -432,7 +432,7 @@ BOOL unserialize(const DATA_BLOB *pSerial, struct protect_data_t *pInfo) } /* hash_alg */ - if (!unserialize_dword(ptr,&index,size,&pInfo->hash_alg)) + if (!unserialize_dword(ptr,&index,size,(DWORD*)&pInfo->hash_alg)) { ERR("reading hash_alg failed!\n"); return FALSE; @@ -475,7 +475,7 @@ BOOL unserialize(const DATA_BLOB *pSerial, struct protect_data_t *pInfo) { /* this is an impossible-to-reach test, but if the padding * issue is ever understood, this may become more useful */ - ERR("loaded corrupt structure! (used %u expected %u)\n", index, size); + ERR("loaded corrupt structure! (used %lu expected %lu)\n", index, size); status=FALSE; } @@ -772,15 +772,15 @@ report(const DATA_BLOB* pDataIn, const DATA_BLOB* pOptionalEntropy, TRACE("pPromptStruct: %p\n", pPromptStruct); if (pPromptStruct) { - TRACE(" cbSize: 0x%x\n", pPromptStruct->cbSize); - TRACE(" dwPromptFlags: 0x%x\n", pPromptStruct->dwPromptFlags); + TRACE(" cbSize: 0x%lx\n", pPromptStruct->cbSize); + TRACE(" dwPromptFlags: 0x%lx\n", pPromptStruct->dwPromptFlags); TRACE(" hwndApp: %p\n", pPromptStruct->hwndApp); TRACE(" szPrompt: %p %s\n", pPromptStruct->szPrompt, pPromptStruct->szPrompt ? debugstr_w(pPromptStruct->szPrompt) : ""); } - TRACE("dwFlags: 0x%04x\n", dwFlags); + TRACE("dwFlags: 0x%04lx\n", dwFlags); TRACE_DATA_BLOB(pDataIn); if (pOptionalEntropy) { @@ -826,7 +826,6 @@ BOOL WINAPI CryptProtectData(DATA_BLOB* pDataIn, DWORD dwFlags, DATA_BLOB* pDataOut) { - static const WCHAR empty_str[1]; BOOL rc = FALSE; HCRYPTPROV hProv; struct protect_data_t protect_data; @@ -852,7 +851,7 @@ BOOL WINAPI CryptProtectData(DATA_BLOB* pDataIn, /* Windows appears to create an empty szDataDescr instead of maintaining * a NULL */ if (!szDataDescr) - szDataDescr = empty_str; + szDataDescr = L""; /* get crypt context */ if (!CryptAcquireContextW(&hProv,NULL,MS_ENHANCED_PROV_W,CRYPT32_PROTECTDATA_PROV,CRYPT_VERIFYCONTEXT)) @@ -889,7 +888,7 @@ BOOL WINAPI CryptProtectData(DATA_BLOB* pDataIn, ERR("CryptEncrypt\n"); goto free_hash; } - TRACE("required encrypted storage: %u\n", dwLength); + TRACE("required encrypted storage: %lu\n", dwLength); /* copy plain text into cipher area for CryptEncrypt call */ protect_data.cipher.cbData=dwLength; @@ -906,7 +905,7 @@ BOOL WINAPI CryptProtectData(DATA_BLOB* pDataIn, if (!CryptEncrypt(hKey, hHash, TRUE, 0, protect_data.cipher.pbData, &dwLength, protect_data.cipher.cbData)) { - ERR("CryptEncrypt %u\n", GetLastError()); + ERR("CryptEncrypt %lu\n", GetLastError()); goto free_hash; } protect_data.cipher.cbData=dwLength; diff --git a/dll/win32/crypt32/provstore.c b/dll/win32/crypt32/provstore.c index a6f7130be8e..96945e313e8 100644 --- a/dll/win32/crypt32/provstore.c +++ b/dll/win32/crypt32/provstore.c @@ -46,7 +46,7 @@ typedef struct _WINE_PROVIDERSTORE static void ProvStore_addref(WINECRYPT_CERTSTORE *store) { LONG ref = InterlockedIncrement(&store->ref); - TRACE("ref = %d\n", ref); + TRACE("ref = %ld\n", ref); } static DWORD ProvStore_release(WINECRYPT_CERTSTORE *cert_store, DWORD flags) @@ -55,10 +55,10 @@ static DWORD ProvStore_release(WINECRYPT_CERTSTORE *cert_store, DWORD flags) LONG ref; if(flags) - FIXME("Unimplemented flags %x\n", flags); + FIXME("Unimplemented flags %lx\n", flags); ref = InterlockedDecrement(&store->hdr.ref); - TRACE("(%p) ref=%d\n", store, ref); + TRACE("(%p) ref=%ld\n", store, ref); if(ref) return ERROR_SUCCESS; @@ -275,7 +275,7 @@ static BOOL ProvStore_control(WINECRYPT_CERTSTORE *cert_store, DWORD dwFlags, DW WINE_PROVIDERSTORE *store = (WINE_PROVIDERSTORE*)cert_store; BOOL ret = TRUE; - TRACE("(%p, %08x, %d, %p)\n", store, dwFlags, dwCtrlType, + TRACE("(%p, %08lx, %ld, %p)\n", store, dwFlags, dwCtrlType, pvCtrlPara); if (store->provControl) diff --git a/dll/win32/crypt32/reactos/store.c b/dll/win32/crypt32/reactos/store.c new file mode 100644 index 00000000000..065ccd35b6f --- /dev/null +++ b/dll/win32/crypt32/reactos/store.c @@ -0,0 +1,65 @@ +/* + * PROJECT: ReactOS win32 DLLs + * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later) + * PURPOSE: ReactOS store related code for crypt32 + * COPYRIGHT: Copyright 2025 Ratin Gao + */ + +#include +#include +#include +#include +#include + +WINE_DEFAULT_DEBUG_CHANNEL(crypt); + +typedef struct _CERT_SYSTEM_STORE_LOCATION +{ + DWORD dwFlags; + PCWSTR pwszStoreLocation; +} CERT_SYSTEM_STORE_LOCATION, *PCERT_SYSTEM_STORE_LOCATION; + +static const CERT_SYSTEM_STORE_LOCATION gSystemStoreLocations[] = { + { CERT_SYSTEM_STORE_CURRENT_USER, L"CurrentUser" }, + { CERT_SYSTEM_STORE_LOCAL_MACHINE, L"LocalMachine" }, + { CERT_SYSTEM_STORE_CURRENT_SERVICE, L"CurrentService" }, + { CERT_SYSTEM_STORE_SERVICES, L"Services" }, + { CERT_SYSTEM_STORE_USERS, L"Users" }, + { CERT_SYSTEM_STORE_CURRENT_USER_GROUP_POLICY, L"CurrentUserGroupPolicy" }, + { CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY, L"LocalMachineGroupPolicy" }, + { CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE, L"LocalMachineEnterprise" }, +}; + +BOOL +WINAPI +CertEnumSystemStoreLocation( + _In_ DWORD dwFlags, + _Inout_opt_ void *pvArg, + __callback PFN_CERT_ENUM_SYSTEM_STORE_LOCATION pfnEnum) +{ + DWORD i; + + /* Check input flags */ + if (dwFlags != 0) + { + SetLastError(E_INVALIDARG); + return FALSE; + } + + /* Return fixed system stores */ + for (i = 0; i < ARRAYSIZE(gSystemStoreLocations); i++) + { + if (!pfnEnum(gSystemStoreLocations[i].pwszStoreLocation, + gSystemStoreLocations[i].dwFlags, + NULL, + pvArg)) + { + return FALSE; + } + } + + /* FIXME: Return registered OID system stores by calling CryptEnumOIDFunction */ + FIXME("Registered OID system stores is not enumerated\n"); + + return TRUE; +} diff --git a/dll/win32/crypt32/reactos/unixlib.c b/dll/win32/crypt32/reactos/unixlib.c new file mode 100644 index 00000000000..947bc48e7d0 --- /dev/null +++ b/dll/win32/crypt32/reactos/unixlib.c @@ -0,0 +1,338 @@ +/* + * PROJECT: ReactOS win32 DLLs + * LICENSE: MIT (https://spdx.org/licenses/MIT) + * PURPOSE: ReactOS emulation layer for crypt32 unixlib calls + * COPYRIGHT: Copyright 2026 Timo Kreuzer + */ +#include +#include +#include +#include +#include +#include +#include "crypt32_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(crypt); + +// See https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-gpef/e051aba9-c9df-4f82-a42a-c13012c9d381 +typedef struct _CRYPT_CERT_PROP +{ + DWORD dwPropId; + DWORD dwReserved; + DWORD cbData; + BYTE ajData[ANYSIZE_ARRAY]; +} CRYPT_CERT_PROP, *PCRYPT_CERT_PROP; + +static +BOOL +FindCertInRegBlob( + _In_ const CRYPT_DATA_BLOB* RegBlob, + _Out_ PCRYPT_DER_BLOB OutCertBlob) +{ + PCRYPT_CERT_PROP prop; + DWORD offset = 0; + + /* Parse the registry blob */ + while ((offset + sizeof(CRYPT_CERT_PROP)) < RegBlob->cbData) + { + prop = (PCRYPT_CERT_PROP)(RegBlob->pbData + offset); + + if (prop->dwReserved != 0x00000001) + { + /* Invalid reserved field */ + return FALSE; + } + + /* Check for the certificate property (ID 32) */ + if (prop->dwPropId == 32) + { + if ((offset + prop->cbData) > RegBlob->cbData) + { + /* Invalid data size */ + return FALSE; + } + + OutCertBlob->cbData = prop->cbData; + OutCertBlob->pbData = prop->ajData; + return TRUE; + } + + /* Move to the next property */ + offset += FIELD_OFFSET(CRYPT_CERT_PROP, ajData) + prop->cbData; + } + + return FALSE; +} + +static +BOOL +LoadCertBlobFromReg( + _In_ HKEY hRootKey, + _In_z_ PWSTR pwszSubkeyName, + _Out_ PCRYPT_DATA_BLOB RegDataBlob) +{ + HKEY hCert; + DWORD dwLength = 0; + DWORD dwType; + LSTATUS ret; + PVOID pvBuffer = NULL; + + RegDataBlob->cbData = 0; + RegDataBlob->pbData = NULL; + + /* Open the certificate subkey */ + ret = RegOpenKeyExW(hRootKey, pwszSubkeyName, 0, KEY_READ, &hCert); + if (ret != ERROR_SUCCESS) + { + return FALSE; + } + + /* Query blob size */ + ret = RegQueryValueExW(hCert, L"Blob", NULL, &dwType, NULL, &dwLength); + if (ret != ERROR_SUCCESS || dwType != REG_BINARY) + { + RegCloseKey(hCert); + return FALSE; + } + + /* Allocate the buffer */ + pvBuffer = HeapAlloc(GetProcessHeap(), 0, dwLength); + if (pvBuffer == NULL) + { + RegCloseKey(hCert); + return FALSE; + } + + /* Fetch the registry blob */ + ret = RegQueryValueExW(hCert, L"Blob", NULL, &dwType, pvBuffer, &dwLength); + RegCloseKey(hCert); + + if ((ret != ERROR_SUCCESS) || (dwType != REG_BINARY)) + { + HeapFree(GetProcessHeap(), 0, pvBuffer); + return FALSE; + } + + RegDataBlob->pbData = pvBuffer; + RegDataBlob->cbData = dwLength; + return TRUE; +} + +static +LSTATUS +LoadCertificateFromStore( + HKEY hRoot, + DWORD dwIndex, + PVOID pvBuffer, + DWORD cbBufferSize, + PDWORD pcbRequired) +{ + WCHAR awcSubkey[64]; + CRYPT_DATA_BLOB regBlob; + CRYPT_DER_BLOB certBlob; + LSTATUS ret; + + if (pcbRequired == 0) + { + return ERROR_INVALID_PARAMETER; + } + + /* Enumerate next subkey */ + ret = RegEnumKeyW(hRoot, dwIndex, awcSubkey, ARRAYSIZE(awcSubkey)); + if (ret != ERROR_SUCCESS) + { + return ret; + } + + /* Load the registry blob */ + if (!LoadCertBlobFromReg(hRoot, awcSubkey, ®Blob)) + { + return ERROR_NO_DATA; + } + + /* Extract the certificate from the registry blob */ + if (!FindCertInRegBlob(®Blob, &certBlob)) + { + HeapFree(GetProcessHeap(), 0, regBlob.pbData); + return ERROR_NO_DATA; + } + + *pcbRequired = certBlob.cbData; + + /* Check if we have a usable buffer */ + if ((pvBuffer != NULL) && (cbBufferSize >= certBlob.cbData)) + { + /* Copy the certificate data to the output buffer */ + memcpy(pvBuffer, certBlob.pbData, certBlob.cbData); + ret = ERROR_SUCCESS; + } + else + { + ret = SEC_E_BUFFER_TOO_SMALL; + } + + /* Free the registry blob buffer */ + HeapFree(GetProcessHeap(), 0, regBlob.pbData); + + /* Successfully retrieved a certificate */ + return ret; +} + +// Note: this function is not thread-safe! It is called under a lock in crypt32. +static +int +EnumerateRootCertificates( + PVOID pvBuffer, + DWORD cbBufferSize, + PDWORD pcbRequired) +{ + const WCHAR* aszStoreKeyNames[] = { + L"Software\\Microsoft\\SystemCertificates\\Root\\Certificates", + L"Software\\Microsoft\\SystemCertificates\\AuthRoot\\Certificates" + }; + static DWORD dwStoreIndex = 0; + static HKEY hStoreKey = NULL; + static DWORD dwCertIndex = 0; + LSTATUS ret; + + assert(pcbRequired != NULL); + + /* Root store enumeration loop */ + for (; dwStoreIndex < ARRAYSIZE(aszStoreKeyNames); dwStoreIndex++) + { + if (hStoreKey == NULL) + { + /* Open the key for the root certificates */ + ret = RegOpenKeyExW(HKEY_LOCAL_MACHINE, + aszStoreKeyNames[dwStoreIndex], + 0, + KEY_READ, + &hStoreKey); + if (ret != ERROR_SUCCESS) + continue; + } + + /* Cert enumeration loop */ + for (; dwCertIndex < MAXDWORD; dwCertIndex++) + { + + ret = LoadCertificateFromStore(hStoreKey, + dwCertIndex, + pvBuffer, + cbBufferSize, + pcbRequired); + if (ret == ERROR_SUCCESS) + { + /* Successfully retrieved a certificate */ + dwCertIndex++; + return 0; + } + + if (ret == SEC_E_BUFFER_TOO_SMALL) + { + /* Buffer too small, return required size, but don't increment index! */ + return ENOBUFS; + } + + if (ret == ERROR_NO_MORE_ITEMS) + { + /* No more certificates in this store, break to move to next store */ + break; + } + } + + /* Move to the next root store */ + RegCloseKey(hStoreKey); + hStoreKey = NULL; + dwCertIndex = 0; + } + + /* No more certificates in any store */ + if (hStoreKey != NULL) + RegCloseKey(hStoreKey); + hStoreKey = NULL; + dwStoreIndex = 0; + dwCertIndex = 0; + return ENOENT; +} + +int __reactos_call_unix_enum_root_certs(void* Args) +{ + struct enum_root_certs_params* params = (struct enum_root_certs_params*)Args; + return EnumerateRootCertificates(params->buffer, + params->size, + params->needed); +} + +static +int +OpenCertStore( + CRYPT_DATA_BLOB *pfx, + const WCHAR *password, + cert_store_data_t *data_ret) +{ + UNIMPLEMENTED; + return -1; +} + +int __reactos_call_unix_open_cert_store(void* Args) +{ + struct open_cert_store_params* params = (struct open_cert_store_params*)Args; + return OpenCertStore(params->pfx, + params->password, + params->data_ret); +} + +static +int +CloseCertStore(cert_store_data_t data) +{ + UNIMPLEMENTED; + return -1; +} + +int __reactos_call_unix_close_cert_store(void* Args) +{ + struct close_cert_store_params* params = (struct close_cert_store_params*)Args; + return CloseCertStore(params->data); +} + +static +int +ImportStoreKey( + cert_store_data_t data, + void *buf, + DWORD *buf_size) +{ + UNIMPLEMENTED; + return -1; +} + +int __reactos_call_unix_import_store_key(void* Args) +{ + struct import_store_key_params* params = (struct import_store_key_params*)Args; + return ImportStoreKey(params->data, + params->buf, + params->buf_size); +} + +static +int +ImportStoreCert( + cert_store_data_t data, + unsigned int index, + void *buf, + DWORD *buf_size) +{ + UNIMPLEMENTED; + return -1; +} + +int __reactos_call_unix_import_store_cert(void* Args) +{ + struct import_store_cert_params* params = (struct import_store_cert_params*)Args; + return ImportStoreCert(params->data, + params->index, + params->buf, + params->buf_size); +} diff --git a/dll/win32/crypt32/regstore.c b/dll/win32/crypt32/regstore.c index ce32a30f3b8..8567604c39b 100644 --- a/dll/win32/crypt32/regstore.c +++ b/dll/win32/crypt32/regstore.c @@ -47,24 +47,16 @@ typedef struct _WINE_REGSTOREINFO static void CRYPT_HashToStr(const BYTE *hash, LPWSTR asciiHash) { - static const WCHAR fmt[] = { '%','0','2','X',0 }; DWORD i; assert(hash); assert(asciiHash); for (i = 0; i < 20; i++) - wsprintfW(asciiHash + i * 2, fmt, hash[i]); + wsprintfW(asciiHash + i * 2, L"%02X", hash[i]); } -static const WCHAR CertsW[] = { 'C','e','r','t','i','f','i','c','a','t','e','s', - 0 }; -static const WCHAR CRLsW[] = { 'C','R','L','s',0 }; -static const WCHAR CTLsW[] = { 'C','T','L','s',0 }; -static const WCHAR BlobW[] = { 'B','l','o','b',0 }; - -static void CRYPT_RegReadSerializedFromReg(HKEY key, DWORD contextType, - HCERTSTORE store) +void CRYPT_RegReadSerializedFromReg(HKEY key, DWORD contextType, HCERTSTORE store, DWORD disposition) { LONG rc; DWORD index = 0; @@ -85,12 +77,12 @@ static void CRYPT_RegReadSerializedFromReg(HKEY key, DWORD contextType, LPBYTE buf = NULL; size = 0; - rc = RegQueryValueExW(subKey, BlobW, NULL, NULL, NULL, &size); + rc = RegQueryValueExW(subKey, L"Blob", NULL, NULL, NULL, &size); if (!rc) buf = CryptMemAlloc(size); if (buf) { - rc = RegQueryValueExW(subKey, BlobW, NULL, NULL, buf, + rc = RegQueryValueExW(subKey, L"Blob", NULL, NULL, buf, &size); if (!rc) { @@ -132,12 +124,12 @@ static void CRYPT_RegReadSerializedFromReg(HKEY key, DWORD contextType, TRACE("comparing %s\n", debugstr_w(asciiHash)); TRACE("with %s\n", debugstr_w(subKeyName)); - if (!lstrcmpW(asciiHash, subKeyName)) + if (!wcscmp(asciiHash, subKeyName)) { TRACE("hash matches, adding\n"); contextInterface->addContextToStore( store, context, - CERT_STORE_ADD_REPLACE_EXISTING, NULL); + disposition, NULL); } else TRACE("hash doesn't match, ignoring\n"); @@ -156,9 +148,9 @@ static void CRYPT_RegReadSerializedFromReg(HKEY key, DWORD contextType, } while (!rc); } -static void CRYPT_RegReadFromReg(HKEY key, HCERTSTORE store) +static void CRYPT_RegReadFromReg(HKEY key, HCERTSTORE store, DWORD disposition) { - static const WCHAR * const subKeys[] = { CertsW, CRLsW, CTLsW }; + static const WCHAR * const subKeys[] = { L"Certificates", L"CRLs", L"CTLs" }; static const DWORD contextFlags[] = { CERT_STORE_CERTIFICATE_CONTEXT_FLAG, CERT_STORE_CRL_CONTEXT_FLAG, CERT_STORE_CTL_CONTEXT_FLAG }; DWORD i; @@ -172,7 +164,7 @@ static void CRYPT_RegReadFromReg(HKEY key, HCERTSTORE store) &hKey, NULL); if (!rc) { - CRYPT_RegReadSerializedFromReg(hKey, contextFlags[i], store); + CRYPT_RegReadSerializedFromReg(hKey, contextFlags[i], store, disposition); RegCloseKey(hKey); } } @@ -192,7 +184,7 @@ static BOOL CRYPT_WriteSerializedToReg(HKEY key, DWORD flags, const BYTE *hash, &subKey, NULL); if (!rc) { - rc = RegSetValueExW(subKey, BlobW, 0, REG_BINARY, buf, len); + rc = RegSetValueExW(subKey, L"Blob", 0, REG_BINARY, buf, len); RegCloseKey(subKey); } if (!rc) @@ -247,7 +239,7 @@ BOOL CRYPT_SerializeContextsToReg(HKEY key, DWORD flags, static BOOL CRYPT_RegWriteToReg(WINE_REGSTOREINFO *store) { - static const WCHAR * const subKeys[] = { CertsW, CRLsW, CTLsW }; + static const WCHAR * const subKeys[] = { L"Certificates", L"CRLs", L"CTLs" }; const WINE_CONTEXT_INTERFACE * const interfaces[] = { pCertInterface, pCRLInterface, pCTLInterface }; struct list *listToDelete[] = { &store->certsToDelete, &store->crlsToDelete, @@ -323,9 +315,9 @@ static void WINAPI CRYPT_RegCloseStore(HCERTSTORE hCertStore, DWORD dwFlags) { WINE_REGSTOREINFO *store = hCertStore; - TRACE("(%p, %08x)\n", store, dwFlags); + TRACE("(%p, %08lx)\n", store, dwFlags); if (dwFlags) - FIXME("Unimplemented flags: %08x\n", dwFlags); + FIXME("Unimplemented flags: %08lx\n", dwFlags); CRYPT_RegFlushStore(store, FALSE); RegCloseKey(store->key); @@ -395,7 +387,7 @@ static BOOL WINAPI CRYPT_RegWriteCert(HCERTSTORE hCertStore, { WINE_REGSTOREINFO *store = hCertStore; - TRACE("(%p, %p, %d)\n", hCertStore, cert, dwFlags); + TRACE("(%p, %p, %ld)\n", hCertStore, cert, dwFlags); return CRYPT_RegWriteContext(store, cert, dwFlags); } @@ -405,7 +397,7 @@ static BOOL WINAPI CRYPT_RegDeleteCert(HCERTSTORE hCertStore, { WINE_REGSTOREINFO *store = hCertStore; - TRACE("(%p, %p, %08x)\n", store, pCertContext, dwFlags); + TRACE("(%p, %p, %08lx)\n", store, pCertContext, dwFlags); return CRYPT_RegDeleteContext(store, &store->certsToDelete, pCertContext, pCertInterface); @@ -416,7 +408,7 @@ static BOOL WINAPI CRYPT_RegWriteCRL(HCERTSTORE hCertStore, { WINE_REGSTOREINFO *store = hCertStore; - TRACE("(%p, %p, %d)\n", hCertStore, crl, dwFlags); + TRACE("(%p, %p, %ld)\n", hCertStore, crl, dwFlags); return CRYPT_RegWriteContext(store, crl, dwFlags); } @@ -426,7 +418,7 @@ static BOOL WINAPI CRYPT_RegDeleteCRL(HCERTSTORE hCertStore, { WINE_REGSTOREINFO *store = hCertStore; - TRACE("(%p, %p, %08x)\n", store, pCrlContext, dwFlags); + TRACE("(%p, %p, %08lx)\n", store, pCrlContext, dwFlags); return CRYPT_RegDeleteContext(store, &store->crlsToDelete, pCrlContext, pCRLInterface); @@ -437,7 +429,7 @@ static BOOL WINAPI CRYPT_RegWriteCTL(HCERTSTORE hCertStore, { WINE_REGSTOREINFO *store = hCertStore; - TRACE("(%p, %p, %d)\n", hCertStore, ctl, dwFlags); + TRACE("(%p, %p, %ld)\n", hCertStore, ctl, dwFlags); return CRYPT_RegWriteContext(store, ctl, dwFlags); } @@ -447,7 +439,7 @@ static BOOL WINAPI CRYPT_RegDeleteCTL(HCERTSTORE hCertStore, { WINE_REGSTOREINFO *store = hCertStore; - TRACE("(%p, %p, %08x)\n", store, pCtlContext, dwFlags); + TRACE("(%p, %p, %08lx)\n", store, pCtlContext, dwFlags); return CRYPT_RegDeleteContext(store, &store->ctlsToDelete, pCtlContext, pCTLInterface); @@ -459,7 +451,7 @@ static BOOL WINAPI CRYPT_RegControl(HCERTSTORE hCertStore, DWORD dwFlags, WINE_REGSTOREINFO *store = hCertStore; BOOL ret = TRUE; - TRACE("(%p, %08x, %d, %p)\n", hCertStore, dwFlags, dwCtrlType, + TRACE("(%p, %08lx, %ld, %p)\n", hCertStore, dwFlags, dwCtrlType, pvCtrlPara); switch (dwCtrlType) @@ -470,7 +462,7 @@ static BOOL WINAPI CRYPT_RegControl(HCERTSTORE hCertStore, DWORD dwFlags, CERT_STORE_CREATE_NEW_FLAG, NULL); CRYPT_RegFlushStore(store, FALSE); - CRYPT_RegReadFromReg(store->key, memStore); + CRYPT_RegReadFromReg(store->key, memStore, CERT_STORE_ADD_REPLACE_EXISTING); I_CertUpdateStore(store->memStore, memStore, 0, 0); CertCloseStore(memStore, 0); break; @@ -486,7 +478,7 @@ static BOOL WINAPI CRYPT_RegControl(HCERTSTORE hCertStore, DWORD dwFlags, FIXME("CERT_STORE_CTRL_NOTIFY_CHANGE: stub\n"); break; default: - FIXME("%u: stub\n", dwCtrlType); + FIXME("%lu: stub\n", dwCtrlType); ret = FALSE; } return ret; @@ -514,16 +506,16 @@ WINECRYPT_CERTSTORE *CRYPT_RegOpenStore(HCRYPTPROV hCryptProv, DWORD dwFlags, { WINECRYPT_CERTSTORE *store = NULL; - TRACE("(%ld, %08x, %p)\n", hCryptProv, dwFlags, pvPara); + TRACE("(%Id, %08lx, %p)\n", hCryptProv, dwFlags, pvPara); if (dwFlags & CERT_STORE_DELETE_FLAG) { - DWORD rc = RegDeleteTreeW((HKEY)pvPara, CertsW); + DWORD rc = RegDeleteTreeW((HKEY)pvPara, L"Certificates"); if (rc == ERROR_SUCCESS || rc == ERROR_NO_MORE_ITEMS) - rc = RegDeleteTreeW((HKEY)pvPara, CRLsW); + rc = RegDeleteTreeW((HKEY)pvPara, L"CRLs"); if (rc == ERROR_SUCCESS || rc == ERROR_NO_MORE_ITEMS) - rc = RegDeleteTreeW((HKEY)pvPara, CTLsW); + rc = RegDeleteTreeW((HKEY)pvPara, L"CTLs"); if (rc == ERROR_NO_MORE_ITEMS) rc = ERROR_SUCCESS; SetLastError(rc); @@ -553,12 +545,12 @@ WINECRYPT_CERTSTORE *CRYPT_RegOpenStore(HCRYPTPROV hCryptProv, DWORD dwFlags, regInfo->dwOpenFlags = dwFlags; regInfo->memStore = memStore; regInfo->key = key; - InitializeCriticalSection(®Info->cs); + InitializeCriticalSectionEx(®Info->cs, 0, RTL_CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO); regInfo->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": PWINE_REGSTOREINFO->cs"); list_init(®Info->certsToDelete); list_init(®Info->crlsToDelete); list_init(®Info->ctlsToDelete); - CRYPT_RegReadFromReg(regInfo->key, regInfo->memStore); + CRYPT_RegReadFromReg(regInfo->key, regInfo->memStore, CERT_STORE_ADD_ALWAYS); regInfo->dirty = FALSE; provInfo.cbSize = sizeof(provInfo); provInfo.cStoreProvFunc = ARRAY_SIZE(regProvFuncs); diff --git a/dll/win32/crypt32/rootstore.c b/dll/win32/crypt32/rootstore.c index 6cf6ec1f160..cfddcc143ac 100644 --- a/dll/win32/crypt32/rootstore.c +++ b/dll/win32/crypt32/rootstore.c @@ -15,196 +15,59 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "config.h" + #include #include -#include -#ifdef HAVE_SYS_STAT_H -#include -#endif -#ifdef HAVE_DIRENT_H -#include -#endif -#include -#ifdef HAVE_UNISTD_H -#include -#endif -#include -#include -#ifdef HAVE_SECURITY_SECURITY_H -#include -#endif + #include "ntstatus.h" #define WIN32_NO_STATUS #include "windef.h" #include "winbase.h" #include "winreg.h" #include "wincrypt.h" -#include "wine/winternl.h" +#include "winternl.h" #include "wine/debug.h" #include "crypt32_private.h" WINE_DEFAULT_DEBUG_CHANNEL(crypt); -#define INITIAL_CERT_BUFFER 1024 - -struct DynamicBuffer -{ - DWORD allocated; - DWORD used; - BYTE *data; -}; - -static inline void reset_buffer(struct DynamicBuffer *buffer) -{ - buffer->used = 0; - if (buffer->data) buffer->data[0] = 0; -} - -static BOOL add_line_to_buffer(struct DynamicBuffer *buffer, LPCSTR line) -{ - BOOL ret; - - if (buffer->used + strlen(line) + 1 > buffer->allocated) - { - if (!buffer->allocated) - { - buffer->data = CryptMemAlloc(INITIAL_CERT_BUFFER); - if (buffer->data) - { - buffer->data[0] = 0; - buffer->allocated = INITIAL_CERT_BUFFER; - } - } - else - { - DWORD new_size = max(buffer->allocated * 2, - buffer->used + strlen(line) + 1); - - buffer->data = CryptMemRealloc(buffer->data, new_size); - if (buffer->data) - buffer->allocated = new_size; - } - } - if (buffer->data) - { - strcpy((char *)buffer->data + strlen((char *)buffer->data), line); - /* Not strlen + 1, otherwise we'd count the NULL for every line's - * addition (but we overwrite the previous NULL character.) Not an - * overrun, we allocate strlen + 1 bytes above. - */ - buffer->used += strlen(line); - ret = TRUE; - } - else - ret = FALSE; - return ret; -} - -/* Reads any base64-encoded certificates present in fp and adds them to store. - * Returns TRUE if any certificates were successfully imported. - */ -static BOOL import_base64_certs_from_fp(FILE *fp, HCERTSTORE store) -{ - char line[1024]; - BOOL in_cert = FALSE; - struct DynamicBuffer saved_cert = { 0, 0, NULL }; - int num_certs = 0; - - TRACE("\n"); - while (fgets(line, sizeof(line), fp)) - { - static const char header[] = "-----BEGIN CERTIFICATE-----"; - static const char trailer[] = "-----END CERTIFICATE-----"; - - if (!strncmp(line, header, strlen(header))) - { - TRACE("begin new certificate\n"); - in_cert = TRUE; - reset_buffer(&saved_cert); - } - else if (!strncmp(line, trailer, strlen(trailer))) - { - DWORD size; - - TRACE("end of certificate, adding cert\n"); - in_cert = FALSE; - if (CryptStringToBinaryA((char *)saved_cert.data, saved_cert.used, - CRYPT_STRING_BASE64, NULL, &size, NULL, NULL)) - { - LPBYTE buf = CryptMemAlloc(size); - - if (buf) - { - CryptStringToBinaryA((char *)saved_cert.data, - saved_cert.used, CRYPT_STRING_BASE64, buf, &size, NULL, - NULL); - if (CertAddEncodedCertificateToStore(store, - X509_ASN_ENCODING, buf, size, CERT_STORE_ADD_NEW, NULL)) - num_certs++; - CryptMemFree(buf); - } - } - } - else if (in_cert) - add_line_to_buffer(&saved_cert, line); - } - CryptMemFree(saved_cert.data); - TRACE("Read %d certs\n", num_certs); - return num_certs > 0; -} - static const char *trust_status_to_str(DWORD status) { + static const struct + { + DWORD flag; + char text[32]; + } + messages[] = + { + { CERT_TRUST_IS_NOT_TIME_VALID, "expired" }, + { CERT_TRUST_IS_NOT_TIME_NESTED, "bad time nesting" }, + { CERT_TRUST_IS_REVOKED, "revoked" }, + { CERT_TRUST_IS_NOT_SIGNATURE_VALID, "bad signature" }, + { CERT_TRUST_IS_NOT_VALID_FOR_USAGE, "bad usage" }, + { CERT_TRUST_IS_UNTRUSTED_ROOT, "untrusted root" }, + { CERT_TRUST_REVOCATION_STATUS_UNKNOWN, "unknown revocation status" }, + { CERT_TRUST_IS_CYCLIC, "cyclic chain" }, + { CERT_TRUST_INVALID_EXTENSION, "unsupported critical extension" }, + { CERT_TRUST_INVALID_POLICY_CONSTRAINTS, "bad policy" }, + { CERT_TRUST_INVALID_BASIC_CONSTRAINTS, "bad basic constraints" }, + { CERT_TRUST_INVALID_NAME_CONSTRAINTS, "bad name constraints" }, + { CERT_TRUST_HAS_NOT_SUPPORTED_NAME_CONSTRAINT, "unsupported name constraint" }, + { CERT_TRUST_HAS_NOT_DEFINED_NAME_CONSTRAINT, "undefined name constraint" }, + { CERT_TRUST_HAS_NOT_PERMITTED_NAME_CONSTRAINT, "disallowed name constraint" }, + { CERT_TRUST_HAS_EXCLUDED_NAME_CONSTRAINT, "excluded name constraint" }, + { CERT_TRUST_IS_OFFLINE_REVOCATION, "revocation server offline" }, + { CERT_TRUST_NO_ISSUANCE_CHAIN_POLICY, "no issuance policy" }, + }; static char buf[1024]; - int pos = 0; + int i, pos = 0; + + for (i = 0; i < ARRAY_SIZE(messages); i++) + { + if (status & messages[i].flag) + pos += sprintf(buf + pos, "\n\t%s", messages[i].text); + } - if (status & CERT_TRUST_IS_NOT_TIME_VALID) - pos += snprintf(buf + pos, sizeof(buf) - pos, "\n\texpired"); - if (status & CERT_TRUST_IS_NOT_TIME_NESTED) - pos += snprintf(buf + pos, sizeof(buf) - pos, "\n\tbad time nesting"); - if (status & CERT_TRUST_IS_REVOKED) - pos += snprintf(buf + pos, sizeof(buf) - pos, "\n\trevoked"); - if (status & CERT_TRUST_IS_NOT_SIGNATURE_VALID) - pos += snprintf(buf + pos, sizeof(buf) - pos, "\n\tbad signature"); - if (status & CERT_TRUST_IS_NOT_VALID_FOR_USAGE) - pos += snprintf(buf + pos, sizeof(buf) - pos, "\n\tbad usage"); - if (status & CERT_TRUST_IS_UNTRUSTED_ROOT) - pos += snprintf(buf + pos, sizeof(buf) - pos, "\n\tuntrusted root"); - if (status & CERT_TRUST_REVOCATION_STATUS_UNKNOWN) - pos += snprintf(buf + pos, sizeof(buf) - pos, - "\n\tunknown revocation status"); - if (status & CERT_TRUST_IS_CYCLIC) - pos += snprintf(buf + pos, sizeof(buf) - pos, "\n\tcyclic chain"); - if (status & CERT_TRUST_INVALID_EXTENSION) - pos += snprintf(buf + pos, sizeof(buf) - pos, - "\n\tunsupported critical extension"); - if (status & CERT_TRUST_INVALID_POLICY_CONSTRAINTS) - pos += snprintf(buf + pos, sizeof(buf) - pos, "\n\tbad policy"); - if (status & CERT_TRUST_INVALID_BASIC_CONSTRAINTS) - pos += snprintf(buf + pos, sizeof(buf) - pos, - "\n\tbad basic constraints"); - if (status & CERT_TRUST_INVALID_NAME_CONSTRAINTS) - pos += snprintf(buf + pos, sizeof(buf) - pos, - "\n\tbad name constraints"); - if (status & CERT_TRUST_HAS_NOT_SUPPORTED_NAME_CONSTRAINT) - pos += snprintf(buf + pos, sizeof(buf) - pos, - "\n\tunsupported name constraint"); - if (status & CERT_TRUST_HAS_NOT_DEFINED_NAME_CONSTRAINT) - pos += snprintf(buf + pos, sizeof(buf) - pos, - "\n\tundefined name constraint"); - if (status & CERT_TRUST_HAS_NOT_PERMITTED_NAME_CONSTRAINT) - pos += snprintf(buf + pos, sizeof(buf) - pos, - "\n\tdisallowed name constraint"); - if (status & CERT_TRUST_HAS_EXCLUDED_NAME_CONSTRAINT) - pos += snprintf(buf + pos, sizeof(buf) - pos, - "\n\texcluded name constraint"); - if (status & CERT_TRUST_IS_OFFLINE_REVOCATION) - pos += snprintf(buf + pos, sizeof(buf) - pos, - "\n\trevocation server offline"); - if (status & CERT_TRUST_NO_ISSUANCE_CHAIN_POLICY) - pos += snprintf(buf + pos, sizeof(buf) - pos, - "\n\tno issuance policy"); return buf; } @@ -235,7 +98,7 @@ static const char *get_cert_common_name(PCCERT_CONTEXT cert) return name; } -static void check_and_store_certs(HCERTSTORE from, HCERTSTORE to) +static void check_and_store_certs(HCERTSTORE cached, HCERTSTORE new, HCERTSTORE to) { DWORD root_count = 0; CERT_CHAIN_ENGINE_CONFIG chainEngineConfig = @@ -251,14 +114,14 @@ static void check_and_store_certs(HCERTSTORE from, HCERTSTORE to) PCCERT_CONTEXT cert = NULL; do { - cert = CertEnumCertificatesInStore(from, cert); + cert = CertEnumCertificatesInStore(new, cert); if (cert) { CERT_CHAIN_PARA chainPara = { sizeof(chainPara), { 0 } }; PCCERT_CHAIN_CONTEXT chain; BOOL ret; - ret = CertGetCertificateChain(engine, cert, NULL, from, + ret = CertGetCertificateChain(engine, cert, NULL, cached, &chainPara, CERT_CHAIN_CACHE_ONLY_URL_RETRIEVAL, NULL, &chain); if (!ret) TRACE("rejecting %s: %s\n", get_cert_common_name(cert), @@ -302,202 +165,9 @@ static void check_and_store_certs(HCERTSTORE from, HCERTSTORE to) } while (cert); CertFreeCertificateChainEngine(engine); } - TRACE("Added %d root certificates\n", root_count); + TRACE("Added %ld root certificates\n", root_count); } -/* Reads the file fd, and imports any certificates in it into store. - * Returns TRUE if any certificates were successfully imported. - */ -static BOOL import_certs_from_file(int fd, HCERTSTORE store) -{ - BOOL ret = FALSE; - FILE *fp; - - TRACE("\n"); - - fp = fdopen(fd, "r"); - if (fp) - { - ret = import_base64_certs_from_fp(fp, store); - fclose(fp); - } - return ret; -} - -static BOOL import_certs_from_path(LPCSTR path, HCERTSTORE store, - BOOL allow_dir); - -#ifdef HAVE_READDIR -static BOOL check_buffer_resize(char **ptr_buf, size_t *buf_size, size_t check_size) -{ - if (check_size > *buf_size) - { - *buf_size = check_size; - - if (*ptr_buf) - { - char *realloc_buf = CryptMemRealloc(*ptr_buf, *buf_size); - - if (!realloc_buf) - return FALSE; - - *ptr_buf = realloc_buf; - } - else - { - *ptr_buf = CryptMemAlloc(*buf_size); - if (!*ptr_buf) - return FALSE; - } - } - - return TRUE; -} -#endif - -/* Opens path, which must be a directory, and imports certificates from every - * file in the directory into store. - * Returns TRUE if any certificates were successfully imported. - */ -static BOOL import_certs_from_dir(LPCSTR path, HCERTSTORE store) -{ -#ifdef HAVE_READDIR - BOOL ret = FALSE; - DIR *dir; - - TRACE("(%s, %p)\n", debugstr_a(path), store); - - dir = opendir(path); - if (dir) - { - size_t path_len = strlen(path), bufsize = 0; - char *filebuf = NULL; - - struct dirent *entry; - while ((entry = readdir(dir))) - { - if (strcmp(entry->d_name, ".") && strcmp(entry->d_name, "..")) - { - size_t name_len = strlen(entry->d_name); - - if (!check_buffer_resize(&filebuf, &bufsize, path_len + 1 + name_len + 1)) - { - ERR("Path buffer (re)allocation failed with out of memory condition\n"); - break; - } - snprintf(filebuf, bufsize, "%s/%s", path, entry->d_name); - if (import_certs_from_path(filebuf, store, FALSE) && !ret) - ret = TRUE; - } - } - CryptMemFree(filebuf); - closedir(dir); - } - return ret; -#else - FIXME("not implemented without readdir available\n"); - return FALSE; -#endif -} - -/* Opens path, which may be a file or a directory, and imports any certificates - * it finds into store. - * Returns TRUE if any certificates were successfully imported. - */ -static BOOL import_certs_from_path(LPCSTR path, HCERTSTORE store, - BOOL allow_dir) -{ - BOOL ret = FALSE; - int fd; - - TRACE("(%s, %p, %d)\n", debugstr_a(path), store, allow_dir); - - fd = open(path, O_RDONLY); - if (fd != -1) - { - struct stat st; - - if (fstat(fd, &st) == 0) - { - if (S_ISREG(st.st_mode)) - ret = import_certs_from_file(fd, store); - else if (S_ISDIR(st.st_mode)) - { - if (allow_dir) - ret = import_certs_from_dir(path, store); - else - WARN("%s is a directory and directories are disallowed\n", - debugstr_a(path)); - } - else - ERR("%s: invalid file type\n", path); - } - close(fd); - } - return ret; -} - -#ifdef __REACTOS__ - -static BOOL WINAPI CRYPT_RootWriteCert(HCERTSTORE hCertStore, - PCCERT_CONTEXT cert, DWORD dwFlags) -{ - /* The root store can't have certs added */ - return FALSE; -} - -static BOOL WINAPI CRYPT_RootDeleteCert(HCERTSTORE hCertStore, - PCCERT_CONTEXT cert, DWORD dwFlags) -{ - /* The root store can't have certs deleted */ - return FALSE; -} - -static BOOL WINAPI CRYPT_RootWriteCRL(HCERTSTORE hCertStore, - PCCRL_CONTEXT crl, DWORD dwFlags) -{ - /* The root store can have CRLs added. At worst, a malicious application - * can DoS itself, as the changes aren't persisted in any way. - */ - return TRUE; -} - -static BOOL WINAPI CRYPT_RootDeleteCRL(HCERTSTORE hCertStore, - PCCRL_CONTEXT crl, DWORD dwFlags) -{ - /* The root store can't have CRLs deleted */ - return FALSE; -} - -static void *rootProvFuncs[] = { - NULL, /* CERT_STORE_PROV_CLOSE_FUNC */ - NULL, /* CERT_STORE_PROV_READ_CERT_FUNC */ - CRYPT_RootWriteCert, - CRYPT_RootDeleteCert, - NULL, /* CERT_STORE_PROV_SET_CERT_PROPERTY_FUNC */ - NULL, /* CERT_STORE_PROV_READ_CRL_FUNC */ - CRYPT_RootWriteCRL, - CRYPT_RootDeleteCRL, - NULL, /* CERT_STORE_PROV_SET_CRL_PROPERTY_FUNC */ - NULL, /* CERT_STORE_PROV_READ_CTL_FUNC */ - NULL, /* CERT_STORE_PROV_WRITE_CTL_FUNC */ - NULL, /* CERT_STORE_PROV_DELETE_CTL_FUNC */ - NULL, /* CERT_STORE_PROV_SET_CTL_PROPERTY_FUNC */ - NULL, /* CERT_STORE_PROV_CONTROL_FUNC */ -}; - -#endif /* __REACTOS__ */ - -static const char * const CRYPT_knownLocations[] = { - "/etc/ssl/certs/ca-certificates.crt", - "/etc/ssl/certs", - "/etc/pki/tls/certs/ca-bundle.crt", - "/usr/share/ca-certificates/ca-bundle.crt", - "/usr/local/share/certs/", - "/etc/sfw/openssl/certs", - "/etc/security/cacerts", /* Android */ -}; - static const BYTE authenticode[] = { 0x30,0x82,0x03,0xd6,0x30,0x82,0x02,0xbe,0xa0,0x03,0x02,0x01,0x02,0x02,0x01,0x01, 0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x04,0x05,0x00,0x30, @@ -925,16 +595,28 @@ static const struct CONST_BLOB { { rootcertauthority2011, sizeof(rootcertauthority2011) }, }; -static void add_ms_root_certs(HCERTSTORE to) +static void add_ms_root_certs(HCERTSTORE to, HCERTSTORE cached) { + PCCERT_CONTEXT cert, existing; DWORD i; TRACE("\n"); for (i = 0; i < ARRAY_SIZE(msRootCerts); i++) + { if (!CertAddEncodedCertificateToStore(to, X509_ASN_ENCODING, - msRootCerts[i].pb, msRootCerts[i].cb, CERT_STORE_ADD_NEW, NULL)) - WARN("adding root cert %d failed: %08x\n", i, GetLastError()); + msRootCerts[i].pb, msRootCerts[i].cb, CERT_STORE_ADD_NEW, &cert)) + { + WARN("adding root cert %ld failed: %08lx\n", i, GetLastError()); + continue; + } + if ((existing = CertFindCertificateInStore(cached, X509_ASN_ENCODING, 0, CERT_FIND_EXISTING, cert, NULL))) + { + CertDeleteCertificateFromStore(existing); + CertFreeCertificateContext(existing); + } + CertFreeCertificateContext(cert); + } } /* Reads certificates from the list of known locations into store. Stops when @@ -942,118 +624,131 @@ static void add_ms_root_certs(HCERTSTORE to) * adding redundant certificates, e.g. when both a certificate bundle and * individual certificates exist in the same directory. */ -static void read_trusted_roots_from_known_locations(HCERTSTORE store) +static void read_trusted_roots_from_known_locations(HCERTSTORE store, HCERTSTORE cached, BOOL *delete) { - HCERTSTORE from = CertOpenStore(CERT_STORE_PROV_MEMORY, - X509_ASN_ENCODING, 0, CERT_STORE_CREATE_NEW_FLAG, NULL); + HCERTSTORE new; + DWORD needed, size; + struct enum_root_certs_params params = { NULL, 2048, &needed }; + HCRYPTPROV prov; + HCRYPTHASH hash; + BYTE hashval[20]; + DWORD hashlen; + CRYPT_HASH_BLOB hash_blob = { sizeof(hashval), hashval }; + CRYPT_DATA_BLOB exists_blob = { 0, NULL }; + PCCERT_CONTEXT cert, existing; + unsigned int existing_count = 0, new_count = 0; + unsigned int cached_count = 0; - if (from) + new = CertOpenStore( CERT_STORE_PROV_MEMORY, X509_ASN_ENCODING, 0, CERT_STORE_CREATE_NEW_FLAG, NULL ); + if (!new) return; + + existing = NULL; + while ((existing = CertEnumCertificatesInStore( cached, existing ))) + ++cached_count; + + CryptAcquireContextW( &prov, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT ); + params.buffer = CryptMemAlloc( params.size ); + while (!CRYPT32_CALL( enum_root_certs, ¶ms )) { - DWORD i; - BOOL ret = FALSE; - -#ifdef HAVE_SECURITY_SECURITY_H - OSStatus status; - CFArrayRef rootCerts; - - status = SecTrustCopyAnchorCertificates(&rootCerts); - if (status == noErr) + if (needed > params.size) { - int i; - for (i = 0; i < CFArrayGetCount(rootCerts); i++) - { - SecCertificateRef cert = (SecCertificateRef)CFArrayGetValueAtIndex(rootCerts, i); - CFDataRef certData; - if ((status = SecKeychainItemExport(cert, kSecFormatX509Cert, 0, NULL, &certData)) == noErr) - { - if (CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING, - CFDataGetBytePtr(certData), CFDataGetLength(certData), - CERT_STORE_ADD_NEW, NULL)) - ret = TRUE; - else - WARN("adding root cert %d failed: %08x\n", i, GetLastError()); - CFRelease(certData); - } - else - WARN("could not export certificate %d to X509 format: 0x%08x\n", i, (unsigned int)status); - } - CFRelease(rootCerts); + CryptMemFree( params.buffer ); + params.buffer = CryptMemAlloc( needed ); + params.size = needed; + continue; } -#endif - - for (i = 0; !ret && i < ARRAY_SIZE(CRYPT_knownLocations); i++) - ret = import_certs_from_path(CRYPT_knownLocations[i], from, TRUE); - check_and_store_certs(from, store); + CryptCreateHash( prov, CALG_SHA1, 0, 0, &hash ); + CryptHashData( hash, params.buffer, needed, 0 ); + hashlen = sizeof(hashval); + CryptGetHashParam( hash, HP_HASHVAL, hashval, &hashlen, 0 ); + CryptDestroyHash( hash ); + if ((existing = CertFindCertificateInStore( cached, X509_ASN_ENCODING, 0, + CERT_FIND_SHA1_HASH, &hash_blob, NULL ))) + { + /* Skip certificate which is already cached. CERT_FIRST_USER_PROP_ID is set once the cached cert + * is found among host imports. */ + if (!CertGetCertificateContextProperty( existing, CERT_FIRST_USER_PROP_ID, NULL, &size )) + { + if (!CertSetCertificateContextProperty( existing, CERT_FIRST_USER_PROP_ID, 0, &exists_blob )) + ERR( "Failed to set property.\n" ); + ++existing_count; + } + CertFreeCertificateContext( existing ); + continue; + } + CertAddEncodedCertificateToStore( new, X509_ASN_ENCODING, params.buffer, needed, CERT_STORE_ADD_ALWAYS, &cert ); + /* Add to cached so we can catch duplicates and check_and_store_certs() has the full chains. */ + CertAddCertificateContextToStore( cached, cert, CERT_STORE_ADD_ALWAYS, NULL ); + if (!CertSetCertificateContextProperty( cert, CERT_FIRST_USER_PROP_ID, 0, &exists_blob )) + ERR("Failed to set property.\n"); + CertFreeCertificateContext( cert ); + ++new_count; } - CertCloseStore(from, 0); + CryptMemFree( params.buffer ); + CryptReleaseContext( prov, 0 ); + + if (existing_count < cached_count) + { + /* Some certs were removed on host. Clean up the cache and add all the certificates so cert chains + * get revalidated. The certs present on host are now in 'cached' store and are marked with + * CERT_FIRST_USER_PROP_ID property. */ + TRACE( "Some keys were removed, reimporting, cached %u, existing %u, new %u.\n", + cached_count, existing_count, new_count ); + *delete = TRUE; + existing_count = 0; + existing = NULL; + while ((existing = CertEnumCertificatesInStore( cached, existing ))) + { + if (!CertGetCertificateContextProperty( existing, CERT_FIRST_USER_PROP_ID, NULL, &size )) + continue; + CertAddCertificateContextToStore( new, existing, CERT_STORE_ADD_NEW, NULL ); + ++new_count; + } + } + if (new_count) + { + /* Clear custom property so it is not serialized and seen by apps. */ + cert = NULL; + while ((cert = CertEnumCertificatesInStore( new, cert ))) + CertSetCertificateContextProperty( cert, CERT_FIRST_USER_PROP_ID, 0, NULL ); + check_and_store_certs( cached, new, store ); + } + + CertCloseStore( new, 0 ); + TRACE( "existing %u, new %u.\n", existing_count, new_count ); } -static HCERTSTORE create_root_store(void) +static HCERTSTORE create_root_store(HCERTSTORE cached, BOOL *delete) { -#ifdef __REACTOS__ - HCERTSTORE root = NULL; -#endif HCERTSTORE memStore = CertOpenStore(CERT_STORE_PROV_MEMORY, X509_ASN_ENCODING, 0, CERT_STORE_CREATE_NEW_FLAG, NULL); + + *delete = FALSE; if (memStore) { -#ifdef __REACTOS__ - HCERTSTORE regStore; - CERT_STORE_PROV_INFO provInfo = { - sizeof(CERT_STORE_PROV_INFO), - sizeof(rootProvFuncs) / sizeof(rootProvFuncs[0]), - rootProvFuncs, - NULL, - 0, - NULL - }; -#endif - - read_trusted_roots_from_known_locations(memStore); - add_ms_root_certs(memStore); -#ifdef __REACTOS__ - root = CRYPT_ProvCreateStore(0, memStore, &provInfo); - regStore = CertOpenStore(CERT_STORE_PROV_SYSTEM_W, 0, 0, CERT_SYSTEM_STORE_LOCAL_MACHINE, L"AuthRoot"); - if (regStore) - { - HCERTSTORE collStore = CertOpenStore(CERT_STORE_PROV_COLLECTION, 0, 0, - CERT_STORE_CREATE_NEW_FLAG, NULL); - CertAddStoreToCollection(collStore, regStore, 0, 0); - CertAddStoreToCollection(collStore, root, 0, 0); - root = collStore; - } -#endif + add_ms_root_certs(memStore, cached); + read_trusted_roots_from_known_locations(memStore, cached, delete); } -#ifdef __REACTOS__ - TRACE("returning %p\n", root); - return root; -#else + TRACE("returning %p\n", memStore); return memStore; -#endif } -static const WCHAR certs_root_pathW[] = - {'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\', - 'S','y','s','t','e','m','C','e','r','t','i','f','i','c','a','t','e','s','\\', - 'R','o','o','t','\\', 'C','e','r','t','i','f','i','c','a','t','e','s', 0}; -static const WCHAR semaphoreW[] = - {'c','r','y','p','t','3','2','_','r','o','o','t','_','s','e','m','a','p','h','o','r','e',0}; - void CRYPT_ImportSystemRootCertsToReg(void) { - HCERTSTORE store = NULL; - HKEY key; + HCERTSTORE store = NULL, reg = NULL; + HKEY key = NULL; LONG rc; HANDLE hsem; + BOOL delete; static BOOL root_certs_imported = FALSE; if (root_certs_imported) return; - hsem = CreateSemaphoreW( NULL, 0, 1, semaphoreW); + hsem = CreateSemaphoreW( NULL, 0, 1, L"crypt32_root_semaphore"); if (!hsem) { ERR("Failed to create semaphore\n"); @@ -1061,24 +756,37 @@ void CRYPT_ImportSystemRootCertsToReg(void) } if(GetLastError() == ERROR_ALREADY_EXISTS) - WaitForSingleObject(hsem, INFINITE); - else { - if ((store = create_root_store())) - { - rc = RegCreateKeyExW(HKEY_LOCAL_MACHINE, certs_root_pathW, 0, NULL, 0, - KEY_ALL_ACCESS, NULL, &key, 0); - if (!rc) - { - if (!CRYPT_SerializeContextsToReg(key, REG_OPTION_VOLATILE, pCertInterface, store)) - ERR("Failed to import system certs into registry, %08x\n", GetLastError()); - RegCloseKey(key); - } - CertCloseStore(store, 0); - } else - ERR("Failed to create root store\n"); + WaitForSingleObject(hsem, INFINITE); + goto done; } + rc = RegCreateKeyExW(HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\SystemCertificates\\Root\\Certificates", 0, NULL, 0, + KEY_ALL_ACCESS, NULL, &key, 0); + if (rc) + goto done; + + if (!(reg = CertOpenStore(CERT_STORE_PROV_MEMORY, X509_ASN_ENCODING, 0, CERT_STORE_CREATE_NEW_FLAG, NULL))) + { + ERR("Failed to create memory store.\n"); + goto done; + } + CRYPT_RegReadSerializedFromReg(key, CERT_STORE_CERTIFICATE_CONTEXT_FLAG, reg, CERT_STORE_ADD_ALWAYS); + + if (!(store = create_root_store(reg, &delete))) + { + ERR("Failed to create root store\n"); + goto done; + } + if (delete && RegDeleteTreeW(key, NULL)) + ERR("Error deleting key.\n"); + if (!CRYPT_SerializeContextsToReg(key, 0, pCertInterface, store)) + ERR("Failed to import system certs into registry, %08lx\n", GetLastError()); + +done: + RegCloseKey(key); + CertCloseStore(store, 0); + CertCloseStore(reg, 0); root_certs_imported = TRUE; ReleaseSemaphore(hsem, 1, NULL); CloseHandle(hsem); diff --git a/dll/win32/crypt32/serialize.c b/dll/win32/crypt32/serialize.c index e8ccc4a06e0..11d39188880 100644 --- a/dll/win32/crypt32/serialize.c +++ b/dll/win32/crypt32/serialize.c @@ -16,9 +16,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "config.h" -#include "wine/port.h" - #include #include "windef.h" #include "winbase.h" @@ -39,6 +36,86 @@ typedef struct _WINE_CERT_PROP_HEADER DWORD cb; } WINE_CERT_PROP_HEADER; +struct store_CRYPT_KEY_PROV_INFO +{ + DWORD pwszContainerName; + DWORD pwszProvName; + DWORD dwProvType; + DWORD dwFlags; + DWORD cProvParam; + DWORD rgProvParam; + DWORD dwKeySpec; +}; + +struct store_CRYPT_KEY_PROV_PARAM +{ + DWORD dwParam; + DWORD pbData; + DWORD cbData; + DWORD dwFlags; +}; + +static DWORD serialize_KeyProvInfoProperty(const CRYPT_KEY_PROV_INFO *info, struct store_CRYPT_KEY_PROV_INFO **ret) +{ + struct store_CRYPT_KEY_PROV_INFO *store; + struct store_CRYPT_KEY_PROV_PARAM *param; + DWORD size = sizeof(struct store_CRYPT_KEY_PROV_INFO), i; + BYTE *data; + + if (info->pwszContainerName) + size += (lstrlenW(info->pwszContainerName) + 1) * sizeof(WCHAR); + if (info->pwszProvName) + size += (lstrlenW(info->pwszProvName) + 1) * sizeof(WCHAR); + + for (i = 0; i < info->cProvParam; i++) + size += sizeof(struct store_CRYPT_KEY_PROV_PARAM) + info->rgProvParam[i].cbData; + + if (!ret) return size; + + store = CryptMemAlloc(size); + if (!store) return 0; + + param = (struct store_CRYPT_KEY_PROV_PARAM *)(store + 1); + data = (BYTE *)param + sizeof(struct store_CRYPT_KEY_PROV_PARAM) * info->cProvParam; + + if (info->pwszContainerName) + { + store->pwszContainerName = data - (BYTE *)store; + lstrcpyW((LPWSTR)data, info->pwszContainerName); + data += (lstrlenW(info->pwszContainerName) + 1) * sizeof(WCHAR); + } + else + store->pwszContainerName = 0; + + if (info->pwszProvName) + { + store->pwszProvName = data - (BYTE *)store; + lstrcpyW((LPWSTR)data, info->pwszProvName); + data += (lstrlenW(info->pwszProvName) + 1) * sizeof(WCHAR); + } + else + store->pwszProvName = 0; + + store->dwProvType = info->dwProvType; + store->dwFlags = info->dwFlags; + store->cProvParam = info->cProvParam; + store->rgProvParam = info->cProvParam ? (BYTE *)param - (BYTE *)store : 0; + store->dwKeySpec = info->dwKeySpec; + + for (i = 0; i < info->cProvParam; i++) + { + param[i].dwParam = info->rgProvParam[i].dwParam; + param[i].dwFlags = info->rgProvParam[i].dwFlags; + param[i].cbData = info->rgProvParam[i].cbData; + param[i].pbData = param[i].cbData ? data - (BYTE *)store : 0; + memcpy(data, info->rgProvParam[i].pbData, info->rgProvParam[i].cbData); + data += info->rgProvParam[i].cbData; + } + + *ret = store; + return size; +} + static BOOL CRYPT_SerializeStoreElement(const void *context, const BYTE *encodedContext, DWORD cbEncodedContext, DWORD contextPropID, const WINE_CONTEXT_INTERFACE *contextInterface, DWORD dwFlags, BOOL omitHashes, @@ -46,7 +123,7 @@ static BOOL CRYPT_SerializeStoreElement(const void *context, { BOOL ret; - TRACE("(%p, %p, %08x, %d, %p, %p)\n", context, contextInterface, dwFlags, + TRACE("(%p, %p, %08lx, %d, %p, %p)\n", context, contextInterface, dwFlags, omitHashes, pbElement, pcbElement); if (context) @@ -63,7 +140,16 @@ static BOOL CRYPT_SerializeStoreElement(const void *context, ret = contextInterface->getProp(context, prop, NULL, &propSize); if (ret) + { + if (prop == CERT_KEY_PROV_INFO_PROP_ID) + { + BYTE *info = CryptMemAlloc(propSize); + contextInterface->getProp(context, prop, info, &propSize); + propSize = serialize_KeyProvInfoProperty((const CRYPT_KEY_PROV_INFO *)info, NULL); + CryptMemFree(info); + } bytesNeeded += sizeof(WINE_CERT_PROP_HEADER) + propSize; + } } } while (ret && prop != 0); @@ -109,6 +195,14 @@ static BOOL CRYPT_SerializeStoreElement(const void *context, &propSize); if (ret) { + if (prop == CERT_KEY_PROV_INFO_PROP_ID) + { + struct store_CRYPT_KEY_PROV_INFO *store; + propSize = serialize_KeyProvInfoProperty((const CRYPT_KEY_PROV_INFO *)buf, &store); + CryptMemFree(buf); + buf = (BYTE *)store; + } + hdr = (WINE_CERT_PROP_HEADER*)pbElement; hdr->propID = prop; hdr->unknown = 1; @@ -218,6 +312,83 @@ static const WINE_CERT_PROP_HEADER *CRYPT_findPropID(const BYTE *buf, return ret; } +static DWORD read_serialized_KeyProvInfoProperty(const struct store_CRYPT_KEY_PROV_INFO *store, CRYPT_KEY_PROV_INFO **ret) +{ + const struct store_CRYPT_KEY_PROV_PARAM *param; + CRYPT_KEY_PROV_INFO *info; + DWORD size = sizeof(CRYPT_KEY_PROV_INFO), i; + const BYTE *base; + BYTE *data; + + base = (const BYTE *)store; + param = (const struct store_CRYPT_KEY_PROV_PARAM *)(base + store->rgProvParam); + + if (store->pwszContainerName) + size += (lstrlenW((LPCWSTR)(base + store->pwszContainerName)) + 1) * sizeof(WCHAR); + if (store->pwszProvName) + size += (lstrlenW((LPCWSTR)(base + store->pwszProvName)) + 1) * sizeof(WCHAR); + + for (i = 0; i < store->cProvParam; i++) + size += sizeof(CRYPT_KEY_PROV_PARAM) + param[i].cbData; + + info = CryptMemAlloc(size); + if (!info) + { + SetLastError(ERROR_OUTOFMEMORY); + return 0; + } + + data = (BYTE *)(info + 1) + sizeof(CRYPT_KEY_PROV_PARAM) * store->cProvParam; + + if (store->pwszContainerName) + { + info->pwszContainerName = (LPWSTR)data; + lstrcpyW(info->pwszContainerName, (LPCWSTR)((const BYTE *)store + store->pwszContainerName)); + data += (lstrlenW(info->pwszContainerName) + 1) * sizeof(WCHAR); + } + else + info->pwszContainerName = NULL; + + if (store->pwszProvName) + { + info->pwszProvName = (LPWSTR)data; + lstrcpyW(info->pwszProvName, (LPCWSTR)((const BYTE *)store + store->pwszProvName)); + data += (lstrlenW(info->pwszProvName) + 1) * sizeof(WCHAR); + } + else + info->pwszProvName = NULL; + + info->dwProvType = store->dwProvType; + info->dwFlags = store->dwFlags; + info->dwKeySpec = store->dwKeySpec; + info->cProvParam = store->cProvParam; + + if (info->cProvParam) + { + DWORD i; + + info->rgProvParam = (CRYPT_KEY_PROV_PARAM *)(info + 1); + + for (i = 0; i < info->cProvParam; i++) + { + info->rgProvParam[i].dwParam = param[i].dwParam; + info->rgProvParam[i].dwFlags = param[i].dwFlags; + info->rgProvParam[i].cbData = param[i].cbData; + info->rgProvParam[i].pbData = param[i].cbData ? data : NULL; + memcpy(info->rgProvParam[i].pbData, base + param[i].pbData, param[i].cbData); + data += param[i].cbData; + } + } + else + info->rgProvParam = NULL; + + TRACE("%s,%s,%lu,%08lx,%lu,%p,%lu\n", debugstr_w(info->pwszContainerName), debugstr_w(info->pwszProvName), + info->dwProvType, info->dwFlags, info->cProvParam, info->rgProvParam, info->dwKeySpec); + + *ret = info; + return size; +} + static BOOL CRYPT_ReadContextProp( const WINE_CONTEXT_INTERFACE *contextInterface, const void *context, const WINE_CERT_PROP_HEADER *hdr, const BYTE *pbElement, DWORD cbElement) @@ -234,6 +405,12 @@ static BOOL CRYPT_ReadContextProp( SetLastError(ERROR_FILE_NOT_FOUND); ret = FALSE; } + else if (hdr->propID >= CERT_FIRST_USER_PROP_ID && hdr->propID <= CERT_LAST_USER_PROP_ID) + { + CRYPT_DATA_BLOB blob = { hdr->cb, (LPBYTE)pbElement }; + + ret = contextInterface->setProp(context, hdr->propID, 0, &blob); + } else if (hdr->propID != CERT_CERT_PROP_ID && hdr->propID != CERT_CRL_PROP_ID && hdr->propID != CERT_CTL_PROP_ID) { @@ -272,12 +449,22 @@ static BOOL CRYPT_ReadContextProp( break; case CERT_KEY_PROV_INFO_PROP_ID: { - PCRYPT_KEY_PROV_INFO info = - (PCRYPT_KEY_PROV_INFO)pbElement; + CRYPT_KEY_PROV_INFO *info; - CRYPT_FixKeyProvInfoPointers(info); - ret = contextInterface->setProp(context, - hdr->propID, 0, pbElement); + if (read_serialized_KeyProvInfoProperty((const struct store_CRYPT_KEY_PROV_INFO *)pbElement, &info)) + { + ret = contextInterface->setProp(context, hdr->propID, 0, info); + CryptMemFree(info); + } + else + ret = FALSE; + break; + } + case CERT_KEY_CONTEXT_PROP_ID: + { + CERT_KEY_CONTEXT ctx; + CRYPT_ConvertKeyContext((struct store_CERT_KEY_CONTEXT *)pbElement, &ctx); + ret = contextInterface->setProp(context, hdr->propID, 0, &ctx); break; } default: @@ -297,7 +484,7 @@ const void *CRYPT_ReadSerializedElement(const BYTE *pbElement, DWORD cbElement, { const void *context; - TRACE("(%p, %d, %08x, %p)\n", pbElement, cbElement, dwContextTypeFlags, + TRACE("(%p, %ld, %08lx, %p)\n", pbElement, cbElement, dwContextTypeFlags, pdwContentType); if (!cbElement) @@ -384,7 +571,7 @@ const void *CRYPT_ReadSerializedElement(const BYTE *pbElement, DWORD cbElement, const WINE_CERT_PROP_HEADER *hdr = (const WINE_CERT_PROP_HEADER *)pbElement; - TRACE("prop is %d\n", hdr->propID); + TRACE("prop is %ld\n", hdr->propID); cbElement -= sizeof(WINE_CERT_PROP_HEADER); pbElement += sizeof(WINE_CERT_PROP_HEADER); if (!hdr->propID) @@ -504,7 +691,7 @@ static BOOL CRYPT_ReadSerializedStore(void *handle, { if (!contextInterface) { - WARN("prop id %d before a context id\n", + WARN("prop id %ld before a context id\n", propHdr.propID); ret = FALSE; } @@ -698,7 +885,7 @@ static BOOL CRYPT_SavePKCSToMem(HCERTSTORE store, DWORD size; BOOL ret = TRUE; - TRACE("(%d, %p)\n", blob->pbData ? blob->cbData : 0, blob->pbData); + TRACE("(%ld, %p)\n", blob->pbData ? blob->cbData : 0, blob->pbData); do { cert = CertEnumCertificatesInStore(store, cert); @@ -899,7 +1086,7 @@ BOOL WINAPI CertSaveStore(HCERTSTORE hCertStore, DWORD dwMsgAndCertEncodingType, void *handle; BOOL ret, closeFile = TRUE; - TRACE("(%p, %08x, %d, %d, %p, %08x)\n", hCertStore, + TRACE("(%p, %08lx, %ld, %ld, %p, %08lx)\n", hCertStore, dwMsgAndCertEncodingType, dwSaveAs, dwSaveTo, pvSaveToPara, dwFlags); switch (dwSaveAs) @@ -917,7 +1104,7 @@ BOOL WINAPI CertSaveStore(HCERTSTORE hCertStore, DWORD dwMsgAndCertEncodingType, saveFunc = CRYPT_SavePKCSToFile; break; default: - WARN("unimplemented for %d\n", dwSaveAs); + WARN("unimplemented for %ld\n", dwSaveAs); SetLastError(ERROR_INVALID_PARAMETER); return FALSE; } @@ -939,7 +1126,7 @@ BOOL WINAPI CertSaveStore(HCERTSTORE hCertStore, DWORD dwMsgAndCertEncodingType, handle = pvSaveToPara; break; default: - WARN("unimplemented for %d\n", dwSaveTo); + WARN("unimplemented for %ld\n", dwSaveTo); SetLastError(ERROR_INVALID_PARAMETER); return FALSE; } @@ -958,7 +1145,7 @@ BOOL WINAPI CertAddSerializedElementToStore(HCERTSTORE hCertStore, DWORD type; BOOL ret; - TRACE("(%p, %p, %d, %08x, %08x, %08x, %p, %p)\n", hCertStore, + TRACE("(%p, %p, %ld, %08lx, %08lx, %08lx, %p, %p)\n", hCertStore, pbElement, cbElement, dwAddDisposition, dwFlags, dwContextTypeFlags, pdwContentType, ppvContext); diff --git a/dll/win32/crypt32/sip.c b/dll/win32/crypt32/sip.c index f51bceb460a..132f491b2f1 100644 --- a/dll/win32/crypt32/sip.c +++ b/dll/win32/crypt32/sip.c @@ -35,38 +35,12 @@ WINE_DEFAULT_DEBUG_CHANNEL(crypt); -static const WCHAR szOID[] = { - 'S','o','f','t','w','a','r','e','\\', - 'M','i','c','r','o','s','o','f','t','\\', - 'C','r','y','p','t','o','g','r','a','p','h','y','\\', - 'O','I','D','\\', - 'E','n','c','o','d','i','n','g','T','y','p','e',' ','0','\\', - 'C','r','y','p','t','S','I','P','D','l','l', 0 }; - -static const WCHAR szPutSigned[] = { - 'P','u','t','S','i','g','n','e','d','D','a','t','a','M','s','g','\\',0}; -static const WCHAR szGetSigned[] = { - 'G','e','t','S','i','g','n','e','d','D','a','t','a','M','s','g','\\',0}; -static const WCHAR szRemoveSigned[] = { - 'R','e','m','o','v','e','S','i','g','n','e','d','D','a','t','a','M','s','g','\\',0}; -static const WCHAR szCreate[] = { - 'C','r','e','a','t','e','I','n','d','i','r','e','c','t','D','a','t','a','\\',0}; -static const WCHAR szVerify[] = { - 'V','e','r','i','f','y','I','n','d','i','r','e','c','t','D','a','t','a','\\',0}; -static const WCHAR szIsMyFile[] = { - 'I','s','M','y','F','i','l','e','T','y','p','e','\\',0}; -static const WCHAR szIsMyFile2[] = { - 'I','s','M','y','F','i','l','e','T','y','p','e','2','\\',0}; - -static const WCHAR szDllName[] = { 'D','l','l',0 }; -static const WCHAR szFuncName[] = { 'F','u','n','c','N','a','m','e',0 }; - /* convert a guid to a wide character string */ static void CRYPT_guid2wstr( const GUID *guid, LPWSTR wstr ) { char str[40]; - sprintf(str, "{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}", + sprintf(str, "{%08lX-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}", guid->Data1, guid->Data2, guid->Data3, guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3], guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7] ); @@ -84,7 +58,7 @@ static LONG CRYPT_SIPDeleteFunction( const GUID *guid, LPCWSTR szKey ) LONG r = ERROR_SUCCESS; /* max length of szFullKey depends on our code only, so we won't overrun */ - lstrcpyW( szFullKey, szOID ); + lstrcpyW( szFullKey, L"Software\\Microsoft\\Cryptography\\OID\\EncodingType 0\\CryptSIPDll" ); lstrcatW( szFullKey, szKey ); CRYPT_guid2wstr( guid, &szFullKey[ lstrlenW( szFullKey ) ] ); @@ -127,13 +101,13 @@ BOOL WINAPI CryptSIPRemoveProvider(GUID *pgProv) r = CRYPT_SIPDeleteFunction( pgProv, key); \ if (r != ERROR_SUCCESS) remove_error = r - CRYPT_SIPREMOVEPROV( szPutSigned); - CRYPT_SIPREMOVEPROV( szGetSigned); - CRYPT_SIPREMOVEPROV( szRemoveSigned); - CRYPT_SIPREMOVEPROV( szCreate); - CRYPT_SIPREMOVEPROV( szVerify); - CRYPT_SIPREMOVEPROV( szIsMyFile); - CRYPT_SIPREMOVEPROV( szIsMyFile2); + CRYPT_SIPREMOVEPROV( L"PutSignedDataMsg\\" ); + CRYPT_SIPREMOVEPROV( L"GetSignedDataMsg\\" ); + CRYPT_SIPREMOVEPROV( L"RemoveSignedDataMsg\\" ); + CRYPT_SIPREMOVEPROV( L"CreateIndirectData\\" ); + CRYPT_SIPREMOVEPROV( L"VerifyIndirectData\\" ); + CRYPT_SIPREMOVEPROV( L"IsMyFileType\\" ); + CRYPT_SIPREMOVEPROV( L"IsMyFileType2\\" ); #undef CRYPT_SIPREMOVEPROV @@ -163,7 +137,7 @@ static LONG CRYPT_SIPWriteFunction( const GUID *guid, LPCWSTR szKey, return ERROR_SUCCESS; /* max length of szFullKey depends on our code only, so we won't overrun */ - lstrcpyW( szFullKey, szOID ); + lstrcpyW( szFullKey, L"Software\\Microsoft\\Cryptography\\OID\\EncodingType 0\\CryptSIPDll" ); lstrcatW( szFullKey, szKey ); CRYPT_guid2wstr( guid, &szFullKey[ lstrlenW( szFullKey ) ] ); @@ -173,10 +147,10 @@ static LONG CRYPT_SIPWriteFunction( const GUID *guid, LPCWSTR szKey, if( r != ERROR_SUCCESS ) goto error_close_key; /* write the values */ - r = RegSetValueExW( hKey, szFuncName, 0, REG_SZ, (const BYTE*) szFunction, + r = RegSetValueExW( hKey, L"FuncName", 0, REG_SZ, (const BYTE*) szFunction, ( lstrlenW( szFunction ) + 1 ) * sizeof (WCHAR) ); if( r != ERROR_SUCCESS ) goto error_close_key; - r = RegSetValueExW( hKey, szDllName, 0, REG_SZ, (const BYTE*) szDll, + r = RegSetValueExW( hKey, L"Dll", 0, REG_SZ, (const BYTE*) szDll, ( lstrlenW( szDll ) + 1) * sizeof (WCHAR) ); error_close_key: @@ -234,13 +208,13 @@ BOOL WINAPI CryptSIPAddProvider(SIP_ADD_NEWPROVIDER *psNewProv) psNewProv->pwszDLLFileName, psNewProv->field); \ if (r != ERROR_SUCCESS) goto end_function - CRYPT_SIPADDPROV( szPutSigned, pwszPutFuncName ); - CRYPT_SIPADDPROV( szGetSigned, pwszGetFuncName ); - CRYPT_SIPADDPROV( szRemoveSigned, pwszRemoveFuncName ); - CRYPT_SIPADDPROV( szCreate, pwszCreateFuncName ); - CRYPT_SIPADDPROV( szVerify, pwszVerifyFuncName ); - CRYPT_SIPADDPROV( szIsMyFile, pwszIsFunctionName ); - CRYPT_SIPADDPROV( szIsMyFile2, pwszIsFunctionNameFmt2 ); + CRYPT_SIPADDPROV( L"PutSignedDataMsg\\", pwszPutFuncName ); + CRYPT_SIPADDPROV( L"GetSignedDataMsg\\", pwszGetFuncName ); + CRYPT_SIPADDPROV( L"RemoveSignedDataMsg\\", pwszRemoveFuncName ); + CRYPT_SIPADDPROV( L"CreateIndirectData\\", pwszCreateFuncName ); + CRYPT_SIPADDPROV( L"VerifyIndirectData\\", pwszVerifyFuncName ); + CRYPT_SIPADDPROV( L"IsMyFileType\\", pwszIsFunctionName ); + CRYPT_SIPADDPROV( L"IsMyFileType2\\", pwszIsFunctionNameFmt2 ); #undef CRYPT_SIPADDPROV @@ -266,7 +240,7 @@ static void *CRYPT_LoadSIPFuncFromKey(HKEY key, HMODULE *pLib) /* Read the DLL entry */ size = sizeof(dllName); - r = RegQueryValueExW(key, szDllName, NULL, NULL, (LPBYTE)dllName, &size); + r = RegQueryValueExW(key, L"Dll", NULL, NULL, (LPBYTE)dllName, &size); if (r) goto end; /* Read the Function entry */ @@ -320,7 +294,6 @@ BOOL WINAPI CryptSIPRetrieveSubjectGuid static const WORD dosHdr = IMAGE_DOS_SIGNATURE; static const BYTE cabHdr[] = { 'M','S','C','F' }; BYTE hdr[SIP_MAX_MAGIC_NUMBER]; - WCHAR szFullKey[ 0x100 ]; LONG r = ERROR_SUCCESS; HKEY key; @@ -379,7 +352,7 @@ BOOL WINAPI CryptSIPRetrieveSubjectGuid { DWORD fileLen = GetFileSize(hFile, NULL); - TRACE("fileLen = %d\n", fileLen); + TRACE("fileLen = %ld\n", fileLen); /* Sanity-check length */ if (hdr[1] < 0x80 && fileLen == 2 + hdr[1]) { @@ -431,10 +404,7 @@ BOOL WINAPI CryptSIPRetrieveSubjectGuid } /* Check for supported functions using CryptSIPDllIsMyFileType */ - /* max length of szFullKey depends on our code only, so we won't overrun */ - lstrcpyW(szFullKey, szOID); - lstrcatW(szFullKey, szIsMyFile); - r = RegOpenKeyExW(HKEY_LOCAL_MACHINE, szFullKey, 0, KEY_READ, &key); + r = RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Cryptography\\OID\\EncodingType 0\\CryptSIPDllIsMyFileType\\", 0, KEY_READ, &key); if (r == ERROR_SUCCESS) { DWORD index = 0, size; @@ -470,9 +440,7 @@ BOOL WINAPI CryptSIPRetrieveSubjectGuid /* Check for supported functions using CryptSIPDllIsMyFileType2 */ if (!bRet) { - lstrcpyW(szFullKey, szOID); - lstrcatW(szFullKey, szIsMyFile2); - r = RegOpenKeyExW(HKEY_LOCAL_MACHINE, szFullKey, 0, KEY_READ, &key); + r = RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Cryptography\\OID\\EncodingType 0\\CryptSIPDllIsMyFileType2\\", 0, KEY_READ, &key); if (r == ERROR_SUCCESS) { DWORD index = 0, size; @@ -526,7 +494,7 @@ static LONG CRYPT_OpenSIPFunctionKey(const GUID *guid, LPCWSTR function, { WCHAR szFullKey[ 0x100 ]; - lstrcpyW(szFullKey, szOID); + lstrcpyW(szFullKey, L"Software\\Microsoft\\Cryptography\\OID\\EncodingType 0\\CryptSIPDll"); lstrcatW(szFullKey, function); CRYPT_guid2wstr(guid, &szFullKey[lstrlenW(szFullKey)]); return RegOpenKeyExW(HKEY_LOCAL_MACHINE, szFullKey, 0, KEY_READ, key); @@ -628,25 +596,25 @@ static BOOL CRYPT_LoadSIP(const GUID *pgSubject) SIP_DISPATCH_INFO sip = { 0 }; HMODULE lib = NULL, temp = NULL; - sip.pfGet = CRYPT_LoadSIPFunc(pgSubject, szGetSigned, &lib); + sip.pfGet = CRYPT_LoadSIPFunc(pgSubject, L"GetSignedDataMsg\\", &lib); if (!sip.pfGet) goto error; - sip.pfPut = CRYPT_LoadSIPFunc(pgSubject, szPutSigned, &temp); + sip.pfPut = CRYPT_LoadSIPFunc(pgSubject, L"PutSignedDataMsg\\", &temp); if (!sip.pfPut || temp != lib) goto error; FreeLibrary(temp); temp = NULL; - sip.pfCreate = CRYPT_LoadSIPFunc(pgSubject, szCreate, &temp); + sip.pfCreate = CRYPT_LoadSIPFunc(pgSubject, L"CreateIndirectData\\", &temp); if (!sip.pfCreate || temp != lib) goto error; FreeLibrary(temp); temp = NULL; - sip.pfVerify = CRYPT_LoadSIPFunc(pgSubject, szVerify, &temp); + sip.pfVerify = CRYPT_LoadSIPFunc(pgSubject, L"VerifyIndirectData\\", &temp); if (!sip.pfVerify || temp != lib) goto error; FreeLibrary(temp); temp = NULL; - sip.pfRemove = CRYPT_LoadSIPFunc(pgSubject, szRemoveSigned, &temp); + sip.pfRemove = CRYPT_LoadSIPFunc(pgSubject, L"RemoveSignedDataMsg\\", &temp); if (!sip.pfRemove || temp != lib) goto error; FreeLibrary(temp); @@ -689,7 +657,7 @@ error: BOOL WINAPI CryptSIPLoad (const GUID *pgSubject, DWORD dwFlags, SIP_DISPATCH_INFO *pSipDispatch) { - TRACE("(%s %d %p)\n", debugstr_guid(pgSubject), dwFlags, pSipDispatch); + TRACE("(%s %ld %p)\n", debugstr_guid(pgSubject), dwFlags, pSipDispatch); if (!pgSubject || dwFlags != 0 || !pSipDispatch) { @@ -740,7 +708,7 @@ BOOL WINAPI CryptSIPGetSignedDataMsg(SIP_SUBJECTINFO* pSubjectInfo, DWORD* pdwEn WINE_SIP_PROVIDER *sip; BOOL ret = FALSE; - TRACE("(%p %p %d %p %p)\n", pSubjectInfo, pdwEncodingType, dwIndex, + TRACE("(%p %p %ld %p %p)\n", pSubjectInfo, pdwEncodingType, dwIndex, pcbSignedDataMsg, pbSignedDataMsg); if ((sip = CRYPT_GetCachedSIP(pSubjectInfo->pgSubjectType))) @@ -759,7 +727,7 @@ BOOL WINAPI CryptSIPPutSignedDataMsg(SIP_SUBJECTINFO* pSubjectInfo, DWORD pdwEnc WINE_SIP_PROVIDER *sip; BOOL ret = FALSE; - TRACE("(%p %d %p %d %p)\n", pSubjectInfo, pdwEncodingType, pdwIndex, + TRACE("(%p %ld %p %ld %p)\n", pSubjectInfo, pdwEncodingType, pdwIndex, cbSignedDataMsg, pbSignedDataMsg); if ((sip = CRYPT_GetCachedSIP(pSubjectInfo->pgSubjectType))) @@ -778,7 +746,7 @@ BOOL WINAPI CryptSIPRemoveSignedDataMsg(SIP_SUBJECTINFO* pSubjectInfo, WINE_SIP_PROVIDER *sip; BOOL ret = FALSE; - TRACE("(%p %d)\n", pSubjectInfo, dwIndex); + TRACE("(%p %ld)\n", pSubjectInfo, dwIndex); if ((sip = CRYPT_GetCachedSIP(pSubjectInfo->pgSubjectType))) ret = sip->info.pfRemove(pSubjectInfo, dwIndex); diff --git a/dll/win32/crypt32/store.c b/dll/win32/crypt32/store.c index c89d414a2c0..de2d760d2b0 100644 --- a/dll/win32/crypt32/store.c +++ b/dll/win32/crypt32/store.c @@ -23,19 +23,16 @@ * - Many flags, options and whatnot are unimplemented. */ -#include "config.h" -#include "wine/port.h" - #include #include #include "windef.h" #include "winbase.h" #include "winnls.h" #include "winreg.h" +#include "winternl.h" #include "winuser.h" #include "wincrypt.h" #include "wine/debug.h" -#include "wine/exception.h" #include "crypt32_private.h" WINE_DEFAULT_DEBUG_CHANNEL(crypt); @@ -114,7 +111,7 @@ BOOL WINAPI I_CertUpdateStore(HCERTSTORE store1, HCERTSTORE store2, DWORD unk0, pCRLInterface, pCTLInterface }; DWORD i; - TRACE("(%p, %p, %08x, %08x)\n", store1, store2, unk0, unk1); + TRACE("(%p, %p, %08lx, %08lx)\n", store1, store2, unk0, unk1); if (!warned) { FIXME("semi-stub\n"); @@ -320,7 +317,7 @@ static BOOL MemStore_deleteCTL(WINECRYPT_CERTSTORE *store, context_t *context) static void MemStore_addref(WINECRYPT_CERTSTORE *store) { LONG ref = InterlockedIncrement(&store->ref); - TRACE("ref = %d\n", ref); + TRACE("ref = %ld\n", ref); } static DWORD MemStore_release(WINECRYPT_CERTSTORE *cert_store, DWORD flags) @@ -329,10 +326,10 @@ static DWORD MemStore_release(WINECRYPT_CERTSTORE *cert_store, DWORD flags) LONG ref; if(flags & ~CERT_CLOSE_STORE_CHECK_FLAG) - FIXME("Unimplemented flags %x\n", flags); + FIXME("Unimplemented flags %lx\n", flags); ref = InterlockedDecrement(&store->hdr.ref); - TRACE("(%p) ref=%d\n", store, ref); + TRACE("(%p) ref=%ld\n", store, ref); if(ref) return (flags & CERT_CLOSE_STORE_CHECK_FLAG) ? CRYPT_E_PENDING_CLOSE : ERROR_SUCCESS; @@ -377,7 +374,7 @@ static WINECRYPT_CERTSTORE *CRYPT_MemOpenStore(HCRYPTPROV hCryptProv, { WINE_MEMSTORE *store; - TRACE("(%ld, %08x, %p)\n", hCryptProv, dwFlags, pvPara); + TRACE("(%Id, %08lx, %p)\n", hCryptProv, dwFlags, pvPara); if (dwFlags & CERT_STORE_DELETE_FLAG) { @@ -391,7 +388,7 @@ static WINECRYPT_CERTSTORE *CRYPT_MemOpenStore(HCRYPTPROV hCryptProv, { memset(store, 0, sizeof(WINE_MEMSTORE)); CRYPT_InitStore(&store->hdr, dwFlags, StoreTypeMem, &MemStoreVtbl); - InitializeCriticalSection(&store->cs); + InitializeCriticalSectionEx(&store->cs, 0, RTL_CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO); store->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": ContextList.cs"); list_init(&store->certs); list_init(&store->crls); @@ -404,19 +401,16 @@ static WINECRYPT_CERTSTORE *CRYPT_MemOpenStore(HCRYPTPROV hCryptProv, return (WINECRYPT_CERTSTORE*)store; } -static const WCHAR rootW[] = { 'R','o','o','t',0 }; - static WINECRYPT_CERTSTORE *CRYPT_SysRegOpenStoreW(HCRYPTPROV hCryptProv, DWORD dwFlags, const void *pvPara) { - static const WCHAR fmt[] = { '%','s','\\','%','s',0 }; LPCWSTR storeName = pvPara; LPWSTR storePath; WINECRYPT_CERTSTORE *store = NULL; HKEY root; LPCWSTR base; - TRACE("(%ld, %08x, %s)\n", hCryptProv, dwFlags, + TRACE("(%Id, %08lx, %s)\n", hCryptProv, dwFlags, debugstr_w(pvPara)); if (!pvPara) @@ -431,7 +425,7 @@ static WINECRYPT_CERTSTORE *CRYPT_SysRegOpenStoreW(HCRYPTPROV hCryptProv, root = HKEY_LOCAL_MACHINE; base = CERT_LOCAL_MACHINE_SYSTEM_STORE_REGPATH; /* If the HKLM\Root certs are requested, expressing system certs into the registry */ - if (!lstrcmpiW(storeName, rootW)) + if (!lstrcmpiW(storeName, L"Root")) CRYPT_ImportSystemRootCertsToReg(); break; case CERT_SYSTEM_STORE_CURRENT_USER: @@ -484,7 +478,7 @@ static WINECRYPT_CERTSTORE *CRYPT_SysRegOpenStoreW(HCRYPTPROV hCryptProv, REGSAM sam = dwFlags & CERT_STORE_READONLY_FLAG ? KEY_READ : KEY_ALL_ACCESS; - wsprintfW(storePath, fmt, base, storeName); + wsprintfW(storePath, L"%s\\%s", base, storeName); if (dwFlags & CERT_STORE_OPEN_EXISTING_FLAG) rc = RegOpenKeyExW(root, storePath, 0, sam, &key); else @@ -518,7 +512,7 @@ static WINECRYPT_CERTSTORE *CRYPT_SysRegOpenStoreA(HCRYPTPROV hCryptProv, int len; WINECRYPT_CERTSTORE *ret = NULL; - TRACE("(%ld, %08x, %s)\n", hCryptProv, dwFlags, + TRACE("(%Id, %08lx, %s)\n", hCryptProv, dwFlags, debugstr_a(pvPara)); if (!pvPara) @@ -547,7 +541,7 @@ static WINECRYPT_CERTSTORE *CRYPT_SysOpenStoreW(HCRYPTPROV hCryptProv, HCERTSTORE store = 0; BOOL ret; - TRACE("(%ld, %08x, %s)\n", hCryptProv, dwFlags, + TRACE("(%Id, %08lx, %s)\n", hCryptProv, dwFlags, debugstr_w(pvPara)); if (!pvPara) @@ -619,7 +613,7 @@ static WINECRYPT_CERTSTORE *CRYPT_SysOpenStoreA(HCRYPTPROV hCryptProv, int len; WINECRYPT_CERTSTORE *ret = NULL; - TRACE("(%ld, %08x, %s)\n", hCryptProv, dwFlags, + TRACE("(%Id, %08lx, %s)\n", hCryptProv, dwFlags, debugstr_a(pvPara)); if (!pvPara) @@ -646,7 +640,7 @@ static void WINAPI CRYPT_MsgCloseStore(HCERTSTORE hCertStore, DWORD dwFlags) { HCRYPTMSG msg = hCertStore; - TRACE("(%p, %08x)\n", msg, dwFlags); + TRACE("(%p, %08lx)\n", msg, dwFlags); CryptMsgClose(msg); } @@ -661,7 +655,7 @@ static WINECRYPT_CERTSTORE *CRYPT_MsgOpenStore(HCRYPTPROV hCryptProv, HCRYPTMSG msg = (HCRYPTMSG)pvPara; WINECRYPT_CERTSTORE *memStore; - TRACE("(%ld, %08x, %p)\n", hCryptProv, dwFlags, pvPara); + TRACE("(%Id, %08lx, %p)\n", hCryptProv, dwFlags, pvPara); memStore = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, CERT_STORE_CREATE_NEW_FLAG, NULL); @@ -742,7 +736,7 @@ static WINECRYPT_CERTSTORE *CRYPT_PKCSOpenStore(HCRYPTPROV hCryptProv, DWORD msgOpenFlags = dwFlags & CERT_STORE_NO_CRYPT_RELEASE_FLAG ? 0 : CMSG_CRYPT_RELEASE_CONTEXT_FLAG; - TRACE("(%ld, %08x, %p)\n", hCryptProv, dwFlags, pvPara); + TRACE("(%Id, %08lx, %p)\n", hCryptProv, dwFlags, pvPara); msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, msgOpenFlags, CMSG_SIGNED, hCryptProv, NULL, NULL); @@ -779,7 +773,7 @@ static WINECRYPT_CERTSTORE *CRYPT_SerializedOpenStore(HCRYPTPROV hCryptProv, HCERTSTORE store; const CRYPT_DATA_BLOB *data = pvPara; - TRACE("(%ld, %08x, %p)\n", hCryptProv, dwFlags, pvPara); + TRACE("(%Id, %08lx, %p)\n", hCryptProv, dwFlags, pvPara); if (dwFlags & CERT_STORE_DELETE_FLAG) { @@ -805,9 +799,9 @@ static WINECRYPT_CERTSTORE *CRYPT_PhysOpenStoreW(HCRYPTPROV hCryptProv, DWORD dwFlags, const void *pvPara) { if (dwFlags & CERT_SYSTEM_STORE_RELOCATE_FLAG) - FIXME("(%ld, %08x, %p): stub\n", hCryptProv, dwFlags, pvPara); + FIXME("(%Id, %08lx, %p): stub\n", hCryptProv, dwFlags, pvPara); else - FIXME("(%ld, %08x, %s): stub\n", hCryptProv, dwFlags, + FIXME("(%Id, %08lx, %s): stub\n", hCryptProv, dwFlags, debugstr_w(pvPara)); return NULL; } @@ -819,7 +813,7 @@ HCERTSTORE WINAPI CertOpenStore(LPCSTR lpszStoreProvider, WINECRYPT_CERTSTORE *hcs; StoreOpenFunc openFunc = NULL; - TRACE("(%s, %08x, %08lx, %08x, %p)\n", debugstr_a(lpszStoreProvider), + TRACE("(%s, %08lx, %08Ix, %08lx, %p)\n", debugstr_a(lpszStoreProvider), dwMsgAndCertEncodingType, hCryptProv, dwFlags, pvPara); if (IS_INTOID(lpszStoreProvider)) @@ -873,19 +867,19 @@ HCERTSTORE WINAPI CertOpenStore(LPCSTR lpszStoreProvider, FIXME("unimplemented type %d\n", LOWORD(lpszStoreProvider)); } } - else if (!strcasecmp(lpszStoreProvider, sz_CERT_STORE_PROV_MEMORY)) + else if (!stricmp(lpszStoreProvider, sz_CERT_STORE_PROV_MEMORY)) openFunc = CRYPT_MemOpenStore; - else if (!strcasecmp(lpszStoreProvider, sz_CERT_STORE_PROV_FILENAME_W)) + else if (!stricmp(lpszStoreProvider, sz_CERT_STORE_PROV_FILENAME_W)) openFunc = CRYPT_FileOpenStore; - else if (!strcasecmp(lpszStoreProvider, sz_CERT_STORE_PROV_SYSTEM)) + else if (!stricmp(lpszStoreProvider, sz_CERT_STORE_PROV_SYSTEM)) openFunc = CRYPT_SysOpenStoreW; - else if (!strcasecmp(lpszStoreProvider, sz_CERT_STORE_PROV_PKCS7)) + else if (!stricmp(lpszStoreProvider, sz_CERT_STORE_PROV_PKCS7)) openFunc = CRYPT_PKCSOpenStore; - else if (!strcasecmp(lpszStoreProvider, sz_CERT_STORE_PROV_SERIALIZED)) + else if (!stricmp(lpszStoreProvider, sz_CERT_STORE_PROV_SERIALIZED)) openFunc = CRYPT_SerializedOpenStore; - else if (!strcasecmp(lpszStoreProvider, sz_CERT_STORE_PROV_COLLECTION)) + else if (!stricmp(lpszStoreProvider, sz_CERT_STORE_PROV_COLLECTION)) openFunc = CRYPT_CollectionOpenStore; - else if (!strcasecmp(lpszStoreProvider, sz_CERT_STORE_PROV_SYSTEM_REGISTRY)) + else if (!stricmp(lpszStoreProvider, sz_CERT_STORE_PROV_SYSTEM_REGISTRY)) openFunc = CRYPT_SysRegOpenStoreW; else { @@ -965,7 +959,7 @@ BOOL WINAPI CertAddCRLContextToStore(HCERTSTORE hCertStore, BOOL ret = TRUE; PCCRL_CONTEXT toAdd = NULL, existing = NULL; - TRACE("(%p, %p, %08x, %p)\n", hCertStore, pCrlContext, + TRACE("(%p, %p, %08lx, %p)\n", hCertStore, pCrlContext, dwAddDisposition, ppStoreContext); /* Weird case to pass a test */ @@ -1053,7 +1047,7 @@ BOOL WINAPI CertAddCRLContextToStore(HCERTSTORE hCertStore, toAdd = CertDuplicateCRLContext(pCrlContext); break; default: - FIXME("Unimplemented add disposition %d\n", dwAddDisposition); + FIXME("Unimplemented add disposition %ld\n", dwAddDisposition); ret = FALSE; } @@ -1129,7 +1123,7 @@ BOOL WINAPI CertCloseStore(HCERTSTORE hCertStore, DWORD dwFlags) WINECRYPT_CERTSTORE *hcs = hCertStore; DWORD res; - TRACE("(%p, %08x)\n", hCertStore, dwFlags); + TRACE("(%p, %08lx)\n", hCertStore, dwFlags); if( ! hCertStore ) return TRUE; @@ -1152,7 +1146,7 @@ BOOL WINAPI CertControlStore(HCERTSTORE hCertStore, DWORD dwFlags, WINECRYPT_CERTSTORE *hcs = hCertStore; BOOL ret; - TRACE("(%p, %08x, %d, %p)\n", hCertStore, dwFlags, dwCtrlType, + TRACE("(%p, %08lx, %ld, %p)\n", hCertStore, dwFlags, dwCtrlType, pvCtrlPara); if (!hcs) @@ -1175,7 +1169,7 @@ BOOL WINAPI CertGetStoreProperty(HCERTSTORE hCertStore, DWORD dwPropId, WINECRYPT_CERTSTORE *store = hCertStore; BOOL ret = FALSE; - TRACE("(%p, %d, %p, %p)\n", hCertStore, dwPropId, pvData, pcbData); + TRACE("(%p, %ld, %p, %p)\n", hCertStore, dwPropId, pvData, pcbData); switch (dwPropId) { @@ -1239,7 +1233,7 @@ BOOL WINAPI CertSetStoreProperty(HCERTSTORE hCertStore, DWORD dwPropId, WINECRYPT_CERTSTORE *store = hCertStore; BOOL ret = FALSE; - TRACE("(%p, %d, %08x, %p)\n", hCertStore, dwPropId, dwFlags, pvData); + TRACE("(%p, %ld, %08lx, %p)\n", hCertStore, dwPropId, dwFlags, pvData); if (!store->properties) store->properties = ContextPropertyList_Create(); @@ -1271,7 +1265,7 @@ static LONG CRYPT_OpenParentStore(DWORD dwFlags, HKEY root; LPCWSTR base; - TRACE("(%08x, %p)\n", dwFlags, pvSystemStoreLocationPara); + TRACE("(%08lx, %p)\n", dwFlags, pvSystemStoreLocationPara); switch (dwFlags & CERT_SYSTEM_STORE_LOCATION_MASK) { @@ -1326,7 +1320,7 @@ BOOL WINAPI CertEnumSystemStore(DWORD dwFlags, void *pvSystemStoreLocationPara, HKEY key; CERT_SYSTEM_STORE_INFO info = { sizeof(info) }; - TRACE("(%08x, %p, %p, %p)\n", dwFlags, pvSystemStoreLocationPara, pvArg, + TRACE("(%08lx, %p, %p, %p)\n", dwFlags, pvSystemStoreLocationPara, pvArg, pfnEnum); rc = CRYPT_OpenParentStore(dwFlags, pvArg, &key); @@ -1354,73 +1348,18 @@ BOOL WINAPI CertEnumSystemStore(DWORD dwFlags, void *pvSystemStoreLocationPara, */ if (ret && (dwFlags & CERT_SYSTEM_STORE_LOCATION_MASK) == CERT_SYSTEM_STORE_LOCAL_MACHINE) - ret = pfnEnum(rootW, dwFlags, &info, NULL, pvArg); + ret = pfnEnum(L"Root", dwFlags, &info, NULL, pvArg); return ret; } -#ifdef __REACTOS__ - -typedef struct _CERT_SYSTEM_STORE_LOCATION -{ - DWORD dwFlags; - PCWSTR pwszStoreLocation; -} CERT_SYSTEM_STORE_LOCATION, *PCERT_SYSTEM_STORE_LOCATION; - -static const CERT_SYSTEM_STORE_LOCATION gSystemStoreLocations[] = { - { CERT_SYSTEM_STORE_CURRENT_USER, L"CurrentUser" }, - { CERT_SYSTEM_STORE_LOCAL_MACHINE, L"LocalMachine" }, - { CERT_SYSTEM_STORE_CURRENT_SERVICE, L"CurrentService" }, - { CERT_SYSTEM_STORE_SERVICES, L"Services" }, - { CERT_SYSTEM_STORE_USERS, L"Users" }, - { CERT_SYSTEM_STORE_CURRENT_USER_GROUP_POLICY, L"CurrentUserGroupPolicy" }, - { CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY, L"LocalMachineGroupPolicy" }, - { CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE, L"LocalMachineEnterprise" }, -}; - -BOOL -WINAPI -CertEnumSystemStoreLocation( - _In_ DWORD dwFlags, - _Inout_opt_ void *pvArg, - __callback PFN_CERT_ENUM_SYSTEM_STORE_LOCATION pfnEnum) -{ - DWORD i; - - /* Check input flags */ - if (dwFlags != 0) - { - SetLastError(E_INVALIDARG); - return FALSE; - } - - /* Return fixed system stores */ - for (i = 0; i < ARRAYSIZE(gSystemStoreLocations); i++) - { - if (!pfnEnum(gSystemStoreLocations[i].pwszStoreLocation, - gSystemStoreLocations[i].dwFlags, - NULL, - pvArg)) - { - return FALSE; - } - } - - /* FIXME: Return registered OID system stores by calling CryptEnumOIDFunction */ - FIXME("Registered OID system stores is not enumerated\n"); - - return TRUE; -} - -#endif /* __REACTOS__ */ - BOOL WINAPI CertEnumPhysicalStore(const void *pvSystemStore, DWORD dwFlags, void *pvArg, PFN_CERT_ENUM_PHYSICAL_STORE pfnEnum) { if (dwFlags & CERT_SYSTEM_STORE_RELOCATE_FLAG) - FIXME("(%p, %08x, %p, %p): stub\n", pvSystemStore, dwFlags, pvArg, + FIXME("(%p, %08lx, %p, %p): stub\n", pvSystemStore, dwFlags, pvArg, pfnEnum); else - FIXME("(%s, %08x, %p, %p): stub\n", debugstr_w(pvSystemStore), + FIXME("(%s, %08lx, %p, %p): stub\n", debugstr_w(pvSystemStore), dwFlags, pvArg, pfnEnum); return FALSE; @@ -1430,10 +1369,10 @@ BOOL WINAPI CertRegisterPhysicalStore(const void *pvSystemStore, DWORD dwFlags, LPCWSTR pwszStoreName, PCERT_PHYSICAL_STORE_INFO pStoreInfo, void *pvReserved) { if (dwFlags & CERT_SYSTEM_STORE_RELOCATE_FLAG) - FIXME("(%p, %08x, %s, %p, %p): stub\n", pvSystemStore, dwFlags, + FIXME("(%p, %08lx, %s, %p, %p): stub\n", pvSystemStore, dwFlags, debugstr_w(pwszStoreName), pStoreInfo, pvReserved); else - FIXME("(%s, %08x, %s, %p, %p): stub\n", debugstr_w(pvSystemStore), + FIXME("(%s, %08lx, %s, %p, %p): stub\n", debugstr_w(pvSystemStore), dwFlags, debugstr_w(pwszStoreName), pStoreInfo, pvReserved); return FALSE; } @@ -1441,7 +1380,7 @@ BOOL WINAPI CertRegisterPhysicalStore(const void *pvSystemStore, DWORD dwFlags, BOOL WINAPI CertUnregisterPhysicalStore(const void *pvSystemStore, DWORD dwFlags, LPCWSTR pwszStoreName) { - FIXME("(%p, %08x, %s): stub\n", pvSystemStore, dwFlags, debugstr_w(pwszStoreName)); + FIXME("(%p, %08lx, %s): stub\n", pvSystemStore, dwFlags, debugstr_w(pwszStoreName)); return TRUE; } @@ -1452,11 +1391,11 @@ BOOL WINAPI CertRegisterSystemStore(const void *pvSystemStore, DWORD dwFlags, if (dwFlags & CERT_SYSTEM_STORE_RELOCATE_FLAG ) { - FIXME("(%p, %08x, %p, %p): flag not supported\n", pvSystemStore, dwFlags, pStoreInfo, pvReserved); + FIXME("(%p, %08lx, %p, %p): flag not supported\n", pvSystemStore, dwFlags, pStoreInfo, pvReserved); return FALSE; } - TRACE("(%s, %08x, %p, %p)\n", debugstr_w(pvSystemStore), dwFlags, pStoreInfo, pvReserved); + TRACE("(%s, %08lx, %p, %p)\n", debugstr_w(pvSystemStore), dwFlags, pStoreInfo, pvReserved); hstore = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W, 0, 0, dwFlags, pvSystemStore); if (hstore) @@ -1474,10 +1413,10 @@ BOOL WINAPI CertUnregisterSystemStore(const void *pvSystemStore, DWORD dwFlags) if (dwFlags & CERT_SYSTEM_STORE_RELOCATE_FLAG) { - FIXME("(%p, %08x): flag not supported\n", pvSystemStore, dwFlags); + FIXME("(%p, %08lx): flag not supported\n", pvSystemStore, dwFlags); return FALSE; } - TRACE("(%s, %08x)\n", debugstr_w(pvSystemStore), dwFlags); + TRACE("(%s, %08lx)\n", debugstr_w(pvSystemStore), dwFlags); hstore = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W, 0, 0, dwFlags | CERT_STORE_OPEN_EXISTING_FLAG, pvSystemStore); if (hstore == NULL) diff --git a/dll/win32/crypt32/str.c b/dll/win32/crypt32/str.c index 79d0ea28d78..4507b023628 100644 --- a/dll/win32/crypt32/str.c +++ b/dll/win32/crypt32/str.c @@ -17,25 +17,57 @@ */ #include -#define NONAMELESSUNION - #include "windef.h" #include "winbase.h" #include "winnls.h" #include "winuser.h" #include "wincrypt.h" #include "wine/debug.h" -#include "wine/unicode.h" #include "crypt32_private.h" WINE_DEFAULT_DEBUG_CHANNEL(crypt); -DWORD WINAPI CertRDNValueToStrA(DWORD dwValueType, PCERT_RDN_VALUE_BLOB pValue, - LPSTR psz, DWORD csz) +DWORD WINAPI CertRDNValueToStrA(DWORD type, PCERT_RDN_VALUE_BLOB value_blob, + LPSTR value, DWORD value_len) { - DWORD ret = 0, len; + DWORD len, len_mb, ret; + LPWSTR valueW; - TRACE("(%d, %p, %p, %d)\n", dwValueType, pValue, psz, csz); + TRACE("(%ld, %p, %p, %ld)\n", type, value_blob, value, value_len); + + len = CertRDNValueToStrW(type, value_blob, NULL, 0); + + if (!(valueW = CryptMemAlloc(len * sizeof(*valueW)))) + { + ERR("No memory.\n"); + if (value && value_len) *value = 0; + return 1; + } + + len = CertRDNValueToStrW(type, value_blob, valueW, len); + len_mb = WideCharToMultiByte(CP_ACP, 0, valueW, len, NULL, 0, NULL, NULL); + if (!value || !value_len) + { + CryptMemFree(valueW); + return len_mb; + } + + ret = WideCharToMultiByte(CP_ACP, 0, valueW, len, value, value_len, NULL, NULL); + if (ret < len_mb) + { + value[0] = 0; + ret = 1; + } + CryptMemFree(valueW); + return ret; +} + +static DWORD rdn_value_to_strW(DWORD dwValueType, PCERT_RDN_VALUE_BLOB pValue, + LPWSTR psz, DWORD csz, BOOL partial_copy) +{ + DWORD ret = 0, len, i; + + TRACE("(%ld, %p, %p, %ld)\n", dwValueType, pValue, psz, csz); switch (dwValueType) { @@ -50,114 +82,45 @@ DWORD WINAPI CertRDNValueToStrA(DWORD dwValueType, PCERT_RDN_VALUE_BLOB pValue, case CERT_RDN_VISIBLE_STRING: case CERT_RDN_GENERAL_STRING: len = pValue->cbData; - if (!psz || !csz) - ret = len; - else + if (!psz || !csz) ret = len; + else if (len < csz || partial_copy) { - DWORD chars = min(len, csz - 1); - - if (chars) - { - memcpy(psz, pValue->pbData, chars); - ret += chars; - csz -= chars; - } + len = min(len, csz - 1); + for (i = 0; i < len; ++i) + psz[i] = pValue->pbData[i]; + ret = len; } break; case CERT_RDN_BMP_STRING: case CERT_RDN_UTF8_STRING: - len = WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)pValue->pbData, - pValue->cbData / sizeof(WCHAR), NULL, 0, NULL, NULL); + len = pValue->cbData / sizeof(WCHAR); if (!psz || !csz) ret = len; - else + else if (len < csz || partial_copy) { - DWORD chars = min(pValue->cbData / sizeof(WCHAR), csz - 1); + WCHAR *ptr = psz; - if (chars) - { - ret = WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)pValue->pbData, - chars, psz, csz - 1, NULL, NULL); - csz -= ret; - } + len = min(len, csz - 1); + for (i = 0; i < len; ++i) + ptr[i] = ((LPCWSTR)pValue->pbData)[i]; + ret = len; } break; default: - FIXME("string type %d unimplemented\n", dwValueType); + FIXME("string type %ld unimplemented\n", dwValueType); } - if (psz && csz) - { - *(psz + ret) = '\0'; - csz--; - ret++; - } - else - ret++; - TRACE("returning %d (%s)\n", ret, debugstr_a(psz)); - return ret; + if (psz && csz) psz[ret] = 0; + TRACE("returning %ld (%s)\n", ret + 1, debugstr_w(psz)); + return ret + 1; } DWORD WINAPI CertRDNValueToStrW(DWORD dwValueType, PCERT_RDN_VALUE_BLOB pValue, - LPWSTR psz, DWORD csz) + LPWSTR psz, DWORD csz) { - DWORD ret = 0, len, i, strLen; - - TRACE("(%d, %p, %p, %d)\n", dwValueType, pValue, psz, csz); - - switch (dwValueType) - { - case CERT_RDN_ANY_TYPE: - break; - case CERT_RDN_NUMERIC_STRING: - case CERT_RDN_PRINTABLE_STRING: - case CERT_RDN_TELETEX_STRING: - case CERT_RDN_VIDEOTEX_STRING: - case CERT_RDN_IA5_STRING: - case CERT_RDN_GRAPHIC_STRING: - case CERT_RDN_VISIBLE_STRING: - case CERT_RDN_GENERAL_STRING: - len = pValue->cbData; - if (!psz || !csz) - ret = len; - else - { - WCHAR *ptr = psz; - - for (i = 0; i < pValue->cbData && ptr - psz < csz; ptr++, i++) - *ptr = pValue->pbData[i]; - ret = ptr - psz; - } - break; - case CERT_RDN_BMP_STRING: - case CERT_RDN_UTF8_STRING: - strLen = len = pValue->cbData / sizeof(WCHAR); - if (!psz || !csz) - ret = len; - else - { - WCHAR *ptr = psz; - - for (i = 0; i < strLen && ptr - psz < csz; ptr++, i++) - *ptr = ((LPCWSTR)pValue->pbData)[i]; - ret = ptr - psz; - } - break; - default: - FIXME("string type %d unimplemented\n", dwValueType); - } - if (psz && csz) - { - *(psz + ret) = '\0'; - csz--; - ret++; - } - else - ret++; - TRACE("returning %d (%s)\n", ret, debugstr_w(psz)); - return ret; + return rdn_value_to_strW(dwValueType, pValue, psz, csz, FALSE); } -static inline BOOL is_quotable_char(char c) +static inline BOOL is_quotable_char(WCHAR c) { switch(c) { @@ -176,122 +139,18 @@ static inline BOOL is_quotable_char(char c) } } -static DWORD quote_rdn_value_to_str_a(DWORD dwValueType, - PCERT_RDN_VALUE_BLOB pValue, LPSTR psz, DWORD csz) +static inline BOOL is_spaceW(WCHAR c) { - DWORD ret = 0, len, i; - BOOL needsQuotes = FALSE; - - TRACE("(%d, %p, %p, %d)\n", dwValueType, pValue, psz, csz); - - switch (dwValueType) - { - case CERT_RDN_ANY_TYPE: - break; - case CERT_RDN_NUMERIC_STRING: - case CERT_RDN_PRINTABLE_STRING: - case CERT_RDN_TELETEX_STRING: - case CERT_RDN_VIDEOTEX_STRING: - case CERT_RDN_IA5_STRING: - case CERT_RDN_GRAPHIC_STRING: - case CERT_RDN_VISIBLE_STRING: - case CERT_RDN_GENERAL_STRING: - len = pValue->cbData; - if (pValue->cbData && isspace(pValue->pbData[0])) - needsQuotes = TRUE; - if (pValue->cbData && isspace(pValue->pbData[pValue->cbData - 1])) - needsQuotes = TRUE; - for (i = 0; i < pValue->cbData; i++) - { - if (is_quotable_char(pValue->pbData[i])) - needsQuotes = TRUE; - if (pValue->pbData[i] == '"') - len += 1; - } - if (needsQuotes) - len += 2; - if (!psz || !csz) - ret = len; - else - { - char *ptr = psz; - - if (needsQuotes) - *ptr++ = '"'; - for (i = 0; i < pValue->cbData && ptr - psz < csz; ptr++, i++) - { - *ptr = pValue->pbData[i]; - if (pValue->pbData[i] == '"' && ptr - psz < csz - 1) - *(++ptr) = '"'; - } - if (needsQuotes && ptr - psz < csz) - *ptr++ = '"'; - ret = ptr - psz; - } - break; - case CERT_RDN_BMP_STRING: - case CERT_RDN_UTF8_STRING: - len = WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)pValue->pbData, - pValue->cbData / sizeof(WCHAR), NULL, 0, NULL, NULL); - if (pValue->cbData && isspaceW(((LPCWSTR)pValue->pbData)[0])) - needsQuotes = TRUE; - if (pValue->cbData && - isspaceW(((LPCWSTR)pValue->pbData)[pValue->cbData / sizeof(WCHAR)-1])) - needsQuotes = TRUE; - for (i = 0; i < pValue->cbData / sizeof(WCHAR); i++) - { - if (is_quotable_char(((LPCWSTR)pValue->pbData)[i])) - needsQuotes = TRUE; - if (((LPCWSTR)pValue->pbData)[i] == '"') - len += 1; - } - if (needsQuotes) - len += 2; - if (!psz || !csz) - ret = len; - else - { - char *dst = psz; - - if (needsQuotes) - *dst++ = '"'; - for (i = 0; i < pValue->cbData / sizeof(WCHAR) && - dst - psz < csz; dst++, i++) - { - LPCWSTR src = (LPCWSTR)pValue->pbData + i; - - WideCharToMultiByte(CP_ACP, 0, src, 1, dst, - csz - (dst - psz) - 1, NULL, NULL); - if (*src == '"' && dst - psz < csz - 1) - *(++dst) = '"'; - } - if (needsQuotes && dst - psz < csz) - *dst++ = '"'; - ret = dst - psz; - } - break; - default: - FIXME("string type %d unimplemented\n", dwValueType); - } - if (psz && csz) - { - *(psz + ret) = '\0'; - csz--; - ret++; - } - else - ret++; - TRACE("returning %d (%s)\n", ret, debugstr_a(psz)); - return ret; + return c <= 0x7f && isspace((char)c); } -static DWORD quote_rdn_value_to_str_w(DWORD dwValueType, - PCERT_RDN_VALUE_BLOB pValue, LPWSTR psz, DWORD csz) +static DWORD quote_rdn_value_to_str_w(DWORD dwValueType, PCERT_RDN_VALUE_BLOB pValue, + DWORD dwStrType, LPWSTR psz, DWORD csz) { DWORD ret = 0, len, i, strLen; BOOL needsQuotes = FALSE; - TRACE("(%d, %p, %p, %d)\n", dwValueType, pValue, psz, csz); + TRACE("(%ld, %p, %p, %ld)\n", dwValueType, pValue, psz, csz); switch (dwValueType) { @@ -306,19 +165,22 @@ static DWORD quote_rdn_value_to_str_w(DWORD dwValueType, case CERT_RDN_VISIBLE_STRING: case CERT_RDN_GENERAL_STRING: len = pValue->cbData; - if (pValue->cbData && isspace(pValue->pbData[0])) - needsQuotes = TRUE; - if (pValue->cbData && isspace(pValue->pbData[pValue->cbData - 1])) - needsQuotes = TRUE; - for (i = 0; i < pValue->cbData; i++) + if (!(dwStrType & CERT_NAME_STR_NO_QUOTING_FLAG)) { - if (is_quotable_char(pValue->pbData[i])) + if (pValue->cbData && isspace(pValue->pbData[0])) needsQuotes = TRUE; - if (pValue->pbData[i] == '"') - len += 1; + if (pValue->cbData && isspace(pValue->pbData[pValue->cbData - 1])) + needsQuotes = TRUE; + for (i = 0; i < pValue->cbData; i++) + { + if (is_quotable_char(pValue->pbData[i])) + needsQuotes = TRUE; + if (pValue->pbData[i] == '"') + len += 1; + } + if (needsQuotes) + len += 2; } - if (needsQuotes) - len += 2; if (!psz || !csz) ret = len; else @@ -330,7 +192,8 @@ static DWORD quote_rdn_value_to_str_w(DWORD dwValueType, for (i = 0; i < pValue->cbData && ptr - psz < csz; ptr++, i++) { *ptr = pValue->pbData[i]; - if (pValue->pbData[i] == '"' && ptr - psz < csz - 1) + if (!(dwStrType & CERT_NAME_STR_NO_QUOTING_FLAG) && + pValue->pbData[i] == '"' && ptr - psz < csz - 1) *(++ptr) = '"'; } if (needsQuotes && ptr - psz < csz) @@ -341,19 +204,22 @@ static DWORD quote_rdn_value_to_str_w(DWORD dwValueType, case CERT_RDN_BMP_STRING: case CERT_RDN_UTF8_STRING: strLen = len = pValue->cbData / sizeof(WCHAR); - if (pValue->cbData && isspace(pValue->pbData[0])) - needsQuotes = TRUE; - if (pValue->cbData && isspace(pValue->pbData[strLen - 1])) - needsQuotes = TRUE; - for (i = 0; i < strLen; i++) + if (!(dwStrType & CERT_NAME_STR_NO_QUOTING_FLAG)) { - if (is_quotable_char(((LPCWSTR)pValue->pbData)[i])) + if (strLen && is_spaceW(((LPCWSTR)pValue->pbData)[0])) needsQuotes = TRUE; - if (((LPCWSTR)pValue->pbData)[i] == '"') - len += 1; + if (strLen && is_spaceW(((LPCWSTR)pValue->pbData)[strLen - 1])) + needsQuotes = TRUE; + for (i = 0; i < strLen; i++) + { + if (is_quotable_char(((LPCWSTR)pValue->pbData)[i])) + needsQuotes = TRUE; + if (((LPCWSTR)pValue->pbData)[i] == '"') + len += 1; + } + if (needsQuotes) + len += 2; } - if (needsQuotes) - len += 2; if (!psz || !csz) ret = len; else @@ -365,7 +231,8 @@ static DWORD quote_rdn_value_to_str_w(DWORD dwValueType, for (i = 0; i < strLen && ptr - psz < csz; ptr++, i++) { *ptr = ((LPCWSTR)pValue->pbData)[i]; - if (((LPCWSTR)pValue->pbData)[i] == '"' && ptr - psz < csz - 1) + if (!(dwStrType & CERT_NAME_STR_NO_QUOTING_FLAG) && + ((LPCWSTR)pValue->pbData)[i] == '"' && ptr - psz < csz - 1) *(++ptr) = '"'; } if (needsQuotes && ptr - psz < csz) @@ -374,150 +241,43 @@ static DWORD quote_rdn_value_to_str_w(DWORD dwValueType, } break; default: - FIXME("string type %d unimplemented\n", dwValueType); + FIXME("string type %ld unimplemented\n", dwValueType); } - if (psz && csz) - { - *(psz + ret) = '\0'; - csz--; - ret++; - } - else - ret++; - TRACE("returning %d (%s)\n", ret, debugstr_w(psz)); + TRACE("returning %ld (%s)\n", ret, debugstr_w(psz)); return ret; } -/* Adds the prefix prefix to the string pointed to by psz, followed by the - * character '='. Copies no more than csz characters. Returns the number of - * characters copied. If psz is NULL, returns the number of characters that - * would be copied. - */ -static DWORD CRYPT_AddPrefixA(LPCSTR prefix, LPSTR psz, DWORD csz) +DWORD WINAPI CertNameToStrA(DWORD encoding_type, PCERT_NAME_BLOB name_blob, DWORD str_type, LPSTR str, DWORD str_len) { - DWORD chars; + DWORD len, len_mb, ret; + LPWSTR strW; - TRACE("(%s, %p, %d)\n", debugstr_a(prefix), psz, csz); + TRACE("(%ld, %p, %08lx, %p, %ld)\n", encoding_type, name_blob, str_type, str, str_len); - if (psz) + len = CertNameToStrW(encoding_type, name_blob, str_type, NULL, 0); + + if (!(strW = CryptMemAlloc(len * sizeof(*strW)))) { - chars = min(strlen(prefix), csz); - memcpy(psz, prefix, chars); - *(psz + chars) = '='; - chars++; + ERR("No memory.\n"); + if (str && str_len) *str = 0; + return 1; } - else - chars = lstrlenA(prefix) + 1; - return chars; -} -DWORD WINAPI CertNameToStrA(DWORD dwCertEncodingType, PCERT_NAME_BLOB pName, - DWORD dwStrType, LPSTR psz, DWORD csz) -{ - static const DWORD unsupportedFlags = CERT_NAME_STR_NO_QUOTING_FLAG | - CERT_NAME_STR_ENABLE_T61_UNICODE_FLAG; - static const char commaSep[] = ", "; - static const char semiSep[] = "; "; - static const char crlfSep[] = "\r\n"; - static const char plusSep[] = " + "; - static const char spaceSep[] = " "; - DWORD ret = 0, bytes = 0; - BOOL bRet; - CERT_NAME_INFO *info; - - TRACE("(%d, %p, %08x, %p, %d)\n", dwCertEncodingType, pName, dwStrType, - psz, csz); - if (dwStrType & unsupportedFlags) - FIXME("unsupported flags: %08x\n", dwStrType & unsupportedFlags); - - bRet = CryptDecodeObjectEx(dwCertEncodingType, X509_NAME, pName->pbData, - pName->cbData, CRYPT_DECODE_ALLOC_FLAG, NULL, &info, &bytes); - if (bRet) + len = CertNameToStrW(encoding_type, name_blob, str_type, strW, len); + len_mb = WideCharToMultiByte(CP_ACP, 0, strW, len, NULL, 0, NULL, NULL); + if (!str || !str_len) { - DWORD i, j, sepLen, rdnSepLen; - LPCSTR sep, rdnSep; - BOOL reverse = dwStrType & CERT_NAME_STR_REVERSE_FLAG; - const CERT_RDN *rdn = info->rgRDN; - - if(reverse && info->cRDN > 1) rdn += (info->cRDN - 1); - - if (dwStrType & CERT_NAME_STR_SEMICOLON_FLAG) - sep = semiSep; - else if (dwStrType & CERT_NAME_STR_CRLF_FLAG) - sep = crlfSep; - else - sep = commaSep; - sepLen = strlen(sep); - if (dwStrType & CERT_NAME_STR_NO_PLUS_FLAG) - rdnSep = spaceSep; - else - rdnSep = plusSep; - rdnSepLen = strlen(rdnSep); - for (i = 0; (!psz || ret < csz) && i < info->cRDN; i++) - { - for (j = 0; (!psz || ret < csz) && j < rdn->cRDNAttr; j++) - { - DWORD chars; - char prefixBuf[13]; /* big enough for SERIALNUMBER */ - LPCSTR prefix = NULL; - - if ((dwStrType & 0x000000ff) == CERT_OID_NAME_STR) - prefix = rdn->rgRDNAttr[j].pszObjId; - else if ((dwStrType & 0x000000ff) == CERT_X500_NAME_STR) - { - PCCRYPT_OID_INFO oidInfo = CryptFindOIDInfo( - CRYPT_OID_INFO_OID_KEY, - rdn->rgRDNAttr[j].pszObjId, - CRYPT_RDN_ATTR_OID_GROUP_ID); - - if (oidInfo) - { - WideCharToMultiByte(CP_ACP, 0, oidInfo->pwszName, -1, - prefixBuf, sizeof(prefixBuf), NULL, NULL); - prefix = prefixBuf; - } - else - prefix = rdn->rgRDNAttr[j].pszObjId; - } - if (prefix) - { - /* - 1 is needed to account for the NULL terminator. */ - chars = CRYPT_AddPrefixA(prefix, - psz ? psz + ret : NULL, psz ? csz - ret - 1 : 0); - ret += chars; - } - chars = quote_rdn_value_to_str_a( - rdn->rgRDNAttr[j].dwValueType, - &rdn->rgRDNAttr[j].Value, psz ? psz + ret : NULL, - psz ? csz - ret : 0); - if (chars) - ret += chars - 1; - if (j < rdn->cRDNAttr - 1) - { - if (psz && ret < csz - rdnSepLen - 1) - memcpy(psz + ret, rdnSep, rdnSepLen); - ret += rdnSepLen; - } - } - if (i < info->cRDN - 1) - { - if (psz && ret < csz - sepLen - 1) - memcpy(psz + ret, sep, sepLen); - ret += sepLen; - } - if(reverse) rdn--; - else rdn++; - } - LocalFree(info); + CryptMemFree(strW); + return len_mb; } - if (psz && csz) + + ret = WideCharToMultiByte(CP_ACP, 0, strW, len, str, str_len, NULL, NULL); + if (ret < len_mb) { - *(psz + ret) = '\0'; - ret++; + str[0] = 0; + ret = 1; } - else - ret++; - TRACE("Returning %s\n", debugstr_a(psz)); + CryptMemFree(strW); return ret; } @@ -531,7 +291,7 @@ static DWORD CRYPT_AddPrefixAToW(LPCSTR prefix, LPWSTR psz, DWORD csz) { DWORD chars; - TRACE("(%s, %p, %d)\n", debugstr_a(prefix), psz, csz); + TRACE("(%s, %p, %ld)\n", debugstr_a(prefix), psz, csz); if (psz) { @@ -557,11 +317,11 @@ static DWORD CRYPT_AddPrefixW(LPCWSTR prefix, LPWSTR psz, DWORD csz) { DWORD chars; - TRACE("(%s, %p, %d)\n", debugstr_w(prefix), psz, csz); + TRACE("(%s, %p, %ld)\n", debugstr_w(prefix), psz, csz); if (psz) { - chars = min(strlenW(prefix), csz); + chars = min(lstrlenW(prefix), csz); memcpy(psz, prefix, chars * sizeof(WCHAR)); *(psz + chars) = '='; chars++; @@ -571,24 +331,19 @@ static DWORD CRYPT_AddPrefixW(LPCWSTR prefix, LPWSTR psz, DWORD csz) return chars; } -static const WCHAR indent[] = { ' ',' ',' ',' ',' ',0 }; +static const WCHAR indent[] = L" "; DWORD cert_name_to_str_with_indent(DWORD dwCertEncodingType, DWORD indentLevel, const CERT_NAME_BLOB *pName, DWORD dwStrType, LPWSTR psz, DWORD csz) { - static const DWORD unsupportedFlags = CERT_NAME_STR_NO_QUOTING_FLAG | - CERT_NAME_STR_ENABLE_T61_UNICODE_FLAG; - static const WCHAR commaSep[] = { ',',' ',0 }; - static const WCHAR semiSep[] = { ';',' ',0 }; - static const WCHAR crlfSep[] = { '\r','\n',0 }; - static const WCHAR plusSep[] = { ' ','+',' ',0 }; - static const WCHAR spaceSep[] = { ' ',0 }; + static const DWORD unsupportedFlags = CERT_NAME_STR_ENABLE_T61_UNICODE_FLAG; DWORD ret = 0, bytes = 0; BOOL bRet; CERT_NAME_INFO *info; + DWORD chars; if (dwStrType & unsupportedFlags) - FIXME("unsupported flags: %08x\n", dwStrType & unsupportedFlags); + FIXME("unsupported flags: %08lx\n", dwStrType & unsupportedFlags); bRet = CryptDecodeObjectEx(dwCertEncodingType, X509_NAME, pName->pbData, pName->cbData, CRYPT_DECODE_ALLOC_FLAG, NULL, &info, &bytes); @@ -602,25 +357,28 @@ DWORD cert_name_to_str_with_indent(DWORD dwCertEncodingType, DWORD indentLevel, if(reverse && info->cRDN > 1) rdn += (info->cRDN - 1); if (dwStrType & CERT_NAME_STR_SEMICOLON_FLAG) - sep = semiSep; + sep = L"; "; else if (dwStrType & CERT_NAME_STR_CRLF_FLAG) - sep = crlfSep; + sep = L"\r\n"; else - sep = commaSep; + sep = L", "; sepLen = lstrlenW(sep); if (dwStrType & CERT_NAME_STR_NO_PLUS_FLAG) - rdnSep = spaceSep; + rdnSep = L" "; else - rdnSep = plusSep; + rdnSep = L" + "; rdnSepLen = lstrlenW(rdnSep); - for (i = 0; (!psz || ret < csz) && i < info->cRDN; i++) + if (!csz) psz = NULL; + for (i = 0; i < info->cRDN; i++) { - for (j = 0; (!psz || ret < csz) && j < rdn->cRDNAttr; j++) + if (psz && ret + 1 == csz) break; + for (j = 0; j < rdn->cRDNAttr; j++) { - DWORD chars; LPCSTR prefixA = NULL; LPCWSTR prefixW = NULL; + if (psz && ret + 1 == csz) break; + if ((dwStrType & 0x000000ff) == CERT_OID_NAME_STR) prefixA = rdn->rgRDNAttr[j].pszObjId; else if ((dwStrType & 0x000000ff) == CERT_X500_NAME_STR) @@ -643,13 +401,14 @@ DWORD cert_name_to_str_with_indent(DWORD dwCertEncodingType, DWORD indentLevel, { if (psz) { - chars = min(strlenW(indent), csz - ret - 1); + chars = min(lstrlenW(indent), csz - ret - 1); memcpy(psz + ret, indent, chars * sizeof(WCHAR)); } else - chars = strlenW(indent); + chars = lstrlenW(indent); ret += chars; } + if (psz && ret + 1 == csz) break; } if (prefixW) { @@ -665,38 +424,40 @@ DWORD cert_name_to_str_with_indent(DWORD dwCertEncodingType, DWORD indentLevel, psz ? psz + ret : NULL, psz ? csz - ret - 1 : 0); ret += chars; } - chars = quote_rdn_value_to_str_w( - rdn->rgRDNAttr[j].dwValueType, - &rdn->rgRDNAttr[j].Value, psz ? psz + ret : NULL, - psz ? csz - ret : 0); - if (chars) - ret += chars - 1; + if (psz && ret + 1 == csz) break; + + chars = quote_rdn_value_to_str_w(rdn->rgRDNAttr[j].dwValueType, &rdn->rgRDNAttr[j].Value, dwStrType, + psz ? psz + ret : NULL, psz ? csz - ret - 1 : 0); + ret += chars; if (j < rdn->cRDNAttr - 1) { - if (psz && ret < csz - rdnSepLen - 1) - memcpy(psz + ret, rdnSep, rdnSepLen * sizeof(WCHAR)); - ret += rdnSepLen; + if (psz) + { + chars = min(rdnSepLen, csz - ret - 1); + memcpy(psz + ret, rdnSep, chars * sizeof(WCHAR)); + ret += chars; + } + else ret += rdnSepLen; } } + if (psz && ret + 1 == csz) break; if (i < info->cRDN - 1) { - if (psz && ret < csz - sepLen - 1) - memcpy(psz + ret, sep, sepLen * sizeof(WCHAR)); - ret += sepLen; + if (psz) + { + chars = min(sepLen, csz - ret - 1); + memcpy(psz + ret, sep, chars * sizeof(WCHAR)); + ret += chars; + } + else ret += sepLen; } if(reverse) rdn--; else rdn++; } LocalFree(info); } - if (psz && csz) - { - *(psz + ret) = '\0'; - ret++; - } - else - ret++; - return ret; + if (psz && csz) psz[ret] = 0; + return ret + 1; } DWORD WINAPI CertNameToStrW(DWORD dwCertEncodingType, PCERT_NAME_BLOB pName, @@ -704,7 +465,7 @@ DWORD WINAPI CertNameToStrW(DWORD dwCertEncodingType, PCERT_NAME_BLOB pName, { BOOL ret; - TRACE("(%d, %p, %08x, %p, %d)\n", dwCertEncodingType, pName, dwStrType, + TRACE("(%ld, %p, %08lx, %p, %ld)\n", dwCertEncodingType, pName, dwStrType, psz, csz); ret = cert_name_to_str_with_indent(dwCertEncodingType, 0, pName, dwStrType, @@ -720,7 +481,7 @@ BOOL WINAPI CertStrToNameA(DWORD dwCertEncodingType, LPCSTR pszX500, BOOL ret; int len; - TRACE("(%08x, %s, %08x, %p, %p, %p, %p)\n", dwCertEncodingType, + TRACE("(%08lx, %s, %08lx, %p, %p, %p, %p)\n", dwCertEncodingType, debugstr_a(pszX500), dwStrType, pvReserved, pbEncoded, pcbEncoded, ppszError); @@ -812,14 +573,14 @@ static BOOL CRYPT_GetNextKeyW(LPCWSTR str, struct X500TokenW *token, { BOOL ret = TRUE; - while (*str && isspaceW(*str)) + while (*str && iswspace(*str)) str++; if (*str) { token->start = str; - while (*str && *str != '=' && !isspaceW(*str)) + while (*str && *str != '=' && !iswspace(*str)) str++; - if (*str && (*str == '=' || isspaceW(*str))) + if (*str && (*str == '=' || iswspace(*str))) token->end = str; else { @@ -845,7 +606,7 @@ static BOOL CRYPT_GetNextValueW(LPCWSTR str, DWORD dwFlags, LPCWSTR separators, ppszError); *separator_used = 0; - while (*str && isspaceW(*str)) + while (*str && iswspace(*str)) str++; if (*str) { @@ -1031,7 +792,7 @@ BOOL WINAPI CertStrToNameW(DWORD dwCertEncodingType, LPCWSTR pszX500, DWORD i; BOOL ret = TRUE; - TRACE("(%08x, %s, %08x, %p, %p, %p, %p)\n", dwCertEncodingType, + TRACE("(%08lx, %s, %08lx, %p, %p, %p, %p)\n", dwCertEncodingType, debugstr_w(pszX500), dwStrType, pvReserved, pbEncoded, pcbEncoded, ppszError); @@ -1059,7 +820,7 @@ BOOL WINAPI CertStrToNameW(DWORD dwCertEncodingType, LPCWSTR pszX500, else { str = token.end; - while (isspaceW(*str)) + while (iswspace(*str)) str++; if (*str != '=') { @@ -1070,25 +831,20 @@ BOOL WINAPI CertStrToNameW(DWORD dwCertEncodingType, LPCWSTR pszX500, } else { - static const WCHAR commaSep[] = { ',',0 }; - static const WCHAR semiSep[] = { ';',0 }; - static const WCHAR crlfSep[] = { '\r','\n',0 }; - static const WCHAR allSepsWithoutPlus[] = { ',',';','\r','\n',0 }; - static const WCHAR allSeps[] = { '+',',',';','\r','\n',0 }; LPCWSTR sep; WCHAR sep_used; str++; if (dwStrType & CERT_NAME_STR_COMMA_FLAG) - sep = commaSep; + sep = L","; else if (dwStrType & CERT_NAME_STR_SEMICOLON_FLAG) - sep = semiSep; + sep = L";"; else if (dwStrType & CERT_NAME_STR_CRLF_FLAG) - sep = crlfSep; + sep = L"\r\n"; else if (dwStrType & CERT_NAME_STR_NO_PLUS_FLAG) - sep = allSepsWithoutPlus; + sep = L",;\r\n"; else - sep = allSeps; + sep = L"+,;\r\n"; ret = CRYPT_GetNextValueW(str, dwStrType, sep, &sep_used, &token, ppszError); if (ret) @@ -1159,6 +915,39 @@ DWORD WINAPI CertGetNameStringA(PCCERT_CONTEXT cert, DWORD type, return ret; } +static BOOL cert_get_alt_name_info(PCCERT_CONTEXT cert, BOOL alt_name_issuer, PCERT_ALT_NAME_INFO *info) +{ + static const char *oids[][2] = + { + { szOID_SUBJECT_ALT_NAME2, szOID_SUBJECT_ALT_NAME }, + { szOID_ISSUER_ALT_NAME2, szOID_ISSUER_ALT_NAME }, + }; + PCERT_EXTENSION ext; + DWORD bytes = 0; + + ext = CertFindExtension(oids[!!alt_name_issuer][0], cert->pCertInfo->cExtension, cert->pCertInfo->rgExtension); + if (!ext) + ext = CertFindExtension(oids[!!alt_name_issuer][1], cert->pCertInfo->cExtension, cert->pCertInfo->rgExtension); + if (!ext) return FALSE; + + return CryptDecodeObjectEx(cert->dwCertEncodingType, X509_ALTERNATE_NAME, ext->Value.pbData, ext->Value.cbData, + CRYPT_DECODE_ALLOC_FLAG, NULL, info, &bytes); +} + +static PCERT_ALT_NAME_ENTRY cert_find_next_alt_name_entry(PCERT_ALT_NAME_INFO info, DWORD entry_type, + unsigned int *index) +{ + unsigned int i; + + for (i = *index; i < info->cAltEntry; ++i) + if (info->rgAltEntry[i].dwAltNameChoice == entry_type) + { + *index = i + 1; + return &info->rgAltEntry[i]; + } + return NULL; +} + /* Searches cert's extensions for the alternate name extension with OID * altNameOID, and if found, searches it for the alternate name type entryType. * If found, returns a pointer to the entry, otherwise returns NULL. @@ -1168,31 +957,13 @@ DWORD WINAPI CertGetNameStringA(PCCERT_CONTEXT cert, DWORD type, * The return value is a pointer within *info, so don't free *info before * you're done with the return value. */ -static PCERT_ALT_NAME_ENTRY cert_find_alt_name_entry(PCCERT_CONTEXT cert, - LPCSTR altNameOID, DWORD entryType, PCERT_ALT_NAME_INFO *info) +static PCERT_ALT_NAME_ENTRY cert_find_alt_name_entry(PCCERT_CONTEXT cert, BOOL alt_name_issuer, + DWORD entry_type, PCERT_ALT_NAME_INFO *info) { - PCERT_ALT_NAME_ENTRY entry = NULL; - PCERT_EXTENSION ext = CertFindExtension(altNameOID, - cert->pCertInfo->cExtension, cert->pCertInfo->rgExtension); + unsigned int index = 0; - if (ext) - { - DWORD bytes = 0; - - if (CryptDecodeObjectEx(cert->dwCertEncodingType, X509_ALTERNATE_NAME, - ext->Value.pbData, ext->Value.cbData, CRYPT_DECODE_ALLOC_FLAG, NULL, - info, &bytes)) - { - DWORD i; - - for (i = 0; !entry && i < (*info)->cAltEntry; i++) - if ((*info)->rgAltEntry[i].dwAltNameChoice == entryType) - entry = &(*info)->rgAltEntry[i]; - } - } - else - *info = NULL; - return entry; + if (!cert_get_alt_name_info(cert, alt_name_issuer, info)) return NULL; + return cert_find_next_alt_name_entry(*info, entry_type, &index); } static DWORD cert_get_name_from_rdn_attr(DWORD encodingType, @@ -1204,228 +975,212 @@ static DWORD cert_get_name_from_rdn_attr(DWORD encodingType, if (CryptDecodeObjectEx(encodingType, X509_NAME, name->pbData, name->cbData, CRYPT_DECODE_ALLOC_FLAG, NULL, &nameInfo, &bytes)) { - PCERT_RDN_ATTR nameAttr; + PCERT_RDN_ATTR nameAttr = NULL; - if (!oid) - oid = szOID_RSA_emailAddr; - nameAttr = CertFindRDNAttr(oid, nameInfo); + if (oid) + nameAttr = CertFindRDNAttr(oid, nameInfo); + else + { + static const LPCSTR attributeOIDs[] = + { + szOID_RSA_emailAddr, szOID_COMMON_NAME, + szOID_ORGANIZATIONAL_UNIT_NAME, szOID_ORGANIZATION_NAME + }; + DWORD i; + + for (i = 0; !nameAttr && i < ARRAY_SIZE(attributeOIDs); i++) + nameAttr = CertFindRDNAttr(attributeOIDs[i], nameInfo); + } if (nameAttr) - ret = CertRDNValueToStrW(nameAttr->dwValueType, &nameAttr->Value, - pszNameString, cchNameString); + ret = rdn_value_to_strW(nameAttr->dwValueType, &nameAttr->Value, + pszNameString, cchNameString, TRUE); LocalFree(nameInfo); } return ret; } -DWORD WINAPI CertGetNameStringW(PCCERT_CONTEXT pCertContext, DWORD dwType, - DWORD dwFlags, void *pvTypePara, LPWSTR pszNameString, DWORD cchNameString) +static DWORD copy_output_str(WCHAR *dst, const WCHAR *src, DWORD dst_size) { - DWORD ret = 0; + DWORD len = wcslen(src); + + if (!dst || !dst_size) return len + 1; + len = min(len, dst_size - 1); + memcpy(dst, src, len * sizeof(*dst)); + dst[len] = 0; + return len + 1; +} + +DWORD WINAPI CertGetNameStringW(PCCERT_CONTEXT cert, DWORD type, DWORD flags, void *type_para, + LPWSTR name_string, DWORD name_len) +{ + static const DWORD supported_flags = CERT_NAME_ISSUER_FLAG | CERT_NAME_SEARCH_ALL_NAMES_FLAG; + BOOL alt_name_issuer, search_all_names; + CERT_ALT_NAME_INFO *info = NULL; + PCERT_ALT_NAME_ENTRY entry; PCERT_NAME_BLOB name; - LPCSTR altNameOID; + DWORD ret = 0; - TRACE("(%p, %d, %08x, %p, %p, %d)\n", pCertContext, dwType, - dwFlags, pvTypePara, pszNameString, cchNameString); + TRACE("(%p, %ld, %08lx, %p, %p, %ld)\n", cert, type, flags, type_para, name_string, name_len); - if (!pCertContext) + if (!cert) goto done; - if (dwFlags & CERT_NAME_ISSUER_FLAG) + if (flags & ~supported_flags) + FIXME("Unsupported flags %#lx.\n", flags); + + search_all_names = flags & CERT_NAME_SEARCH_ALL_NAMES_FLAG; + if (search_all_names && type != CERT_NAME_DNS_TYPE) { - name = &pCertContext->pCertInfo->Issuer; - altNameOID = szOID_ISSUER_ALT_NAME; - } - else - { - name = &pCertContext->pCertInfo->Subject; - altNameOID = szOID_SUBJECT_ALT_NAME; + WARN("CERT_NAME_SEARCH_ALL_NAMES_FLAG used with type %lu.\n", type); + goto done; } - switch (dwType) + alt_name_issuer = flags & CERT_NAME_ISSUER_FLAG; + name = alt_name_issuer ? &cert->pCertInfo->Issuer : &cert->pCertInfo->Subject; + + switch (type) { case CERT_NAME_EMAIL_TYPE: { - CERT_ALT_NAME_INFO *info; - PCERT_ALT_NAME_ENTRY entry = cert_find_alt_name_entry(pCertContext, - altNameOID, CERT_ALT_NAME_RFC822_NAME, &info); + entry = cert_find_alt_name_entry(cert, alt_name_issuer, CERT_ALT_NAME_RFC822_NAME, &info); if (entry) { - if (!pszNameString) - ret = strlenW(entry->u.pwszRfc822Name) + 1; - else if (cchNameString) - { - ret = min(strlenW(entry->u.pwszRfc822Name), cchNameString - 1); - memcpy(pszNameString, entry->u.pwszRfc822Name, - ret * sizeof(WCHAR)); - pszNameString[ret++] = 0; - } + ret = copy_output_str(name_string, entry->pwszRfc822Name, name_len); + break; } - if (info) - LocalFree(info); - if (!ret) - ret = cert_get_name_from_rdn_attr(pCertContext->dwCertEncodingType, - name, szOID_RSA_emailAddr, pszNameString, cchNameString); + ret = cert_get_name_from_rdn_attr(cert->dwCertEncodingType, name, szOID_RSA_emailAddr, + name_string, name_len); break; } case CERT_NAME_RDN_TYPE: { - DWORD type = pvTypePara ? *(DWORD *)pvTypePara : 0; + DWORD param = type_para ? *(DWORD *)type_para : 0; if (name->cbData) - ret = CertNameToStrW(pCertContext->dwCertEncodingType, name, - type, pszNameString, cchNameString); + { + ret = CertNameToStrW(cert->dwCertEncodingType, name, param, name_string, name_len); + } else { - CERT_ALT_NAME_INFO *info; - PCERT_ALT_NAME_ENTRY entry = cert_find_alt_name_entry(pCertContext, - altNameOID, CERT_ALT_NAME_DIRECTORY_NAME, &info); + entry = cert_find_alt_name_entry(cert, alt_name_issuer, CERT_ALT_NAME_DIRECTORY_NAME, &info); if (entry) - ret = CertNameToStrW(pCertContext->dwCertEncodingType, - &entry->u.DirectoryName, type, pszNameString, cchNameString); - if (info) - LocalFree(info); + ret = CertNameToStrW(cert->dwCertEncodingType, &entry->DirectoryName, + param, name_string, name_len); } break; } case CERT_NAME_ATTR_TYPE: - ret = cert_get_name_from_rdn_attr(pCertContext->dwCertEncodingType, - name, pvTypePara, pszNameString, cchNameString); - if (!ret) - { - CERT_ALT_NAME_INFO *altInfo; - PCERT_ALT_NAME_ENTRY entry = cert_find_alt_name_entry(pCertContext, - altNameOID, CERT_ALT_NAME_DIRECTORY_NAME, &altInfo); + ret = cert_get_name_from_rdn_attr(cert->dwCertEncodingType, name, type_para, + name_string, name_len); + if (ret) break; - if (entry) - ret = cert_name_to_str_with_indent(X509_ASN_ENCODING, 0, - &entry->u.DirectoryName, 0, pszNameString, cchNameString); - if (altInfo) - LocalFree(altInfo); - } + entry = cert_find_alt_name_entry(cert, alt_name_issuer, CERT_ALT_NAME_DIRECTORY_NAME, &info); + + if (entry) + ret = cert_name_to_str_with_indent(X509_ASN_ENCODING, 0, &entry->DirectoryName, + 0, name_string, name_len); break; case CERT_NAME_SIMPLE_DISPLAY_TYPE: { - static const LPCSTR simpleAttributeOIDs[] = { szOID_COMMON_NAME, - szOID_ORGANIZATIONAL_UNIT_NAME, szOID_ORGANIZATION_NAME, - szOID_RSA_emailAddr }; + static const LPCSTR simpleAttributeOIDs[] = + { + szOID_COMMON_NAME, szOID_ORGANIZATIONAL_UNIT_NAME, szOID_ORGANIZATION_NAME, szOID_RSA_emailAddr + }; CERT_NAME_INFO *nameInfo = NULL; DWORD bytes = 0, i; - if (CryptDecodeObjectEx(pCertContext->dwCertEncodingType, X509_NAME, - name->pbData, name->cbData, CRYPT_DECODE_ALLOC_FLAG, NULL, &nameInfo, - &bytes)) + if (CryptDecodeObjectEx(cert->dwCertEncodingType, X509_NAME, name->pbData, name->cbData, + CRYPT_DECODE_ALLOC_FLAG, NULL, &nameInfo, &bytes)) { PCERT_RDN_ATTR nameAttr = NULL; for (i = 0; !nameAttr && i < ARRAY_SIZE(simpleAttributeOIDs); i++) nameAttr = CertFindRDNAttr(simpleAttributeOIDs[i], nameInfo); if (nameAttr) - ret = CertRDNValueToStrW(nameAttr->dwValueType, - &nameAttr->Value, pszNameString, cchNameString); + ret = rdn_value_to_strW(nameAttr->dwValueType, &nameAttr->Value, name_string, name_len, TRUE); LocalFree(nameInfo); } - if (!ret) - { - CERT_ALT_NAME_INFO *altInfo; - PCERT_ALT_NAME_ENTRY entry = cert_find_alt_name_entry(pCertContext, - altNameOID, CERT_ALT_NAME_RFC822_NAME, &altInfo); - - if (altInfo) - { - if (!entry && altInfo->cAltEntry) - entry = &altInfo->rgAltEntry[0]; - if (entry) - { - if (!pszNameString) - ret = strlenW(entry->u.pwszRfc822Name) + 1; - else if (cchNameString) - { - ret = min(strlenW(entry->u.pwszRfc822Name), - cchNameString - 1); - memcpy(pszNameString, entry->u.pwszRfc822Name, - ret * sizeof(WCHAR)); - pszNameString[ret++] = 0; - } - } - LocalFree(altInfo); - } - } + if (ret) break; + entry = cert_find_alt_name_entry(cert, alt_name_issuer, CERT_ALT_NAME_RFC822_NAME, &info); + if (!info) break; + if (!entry && info->cAltEntry) + entry = &info->rgAltEntry[0]; + if (entry) ret = copy_output_str(name_string, entry->pwszRfc822Name, name_len); break; } case CERT_NAME_FRIENDLY_DISPLAY_TYPE: { - DWORD cch = cchNameString; + DWORD len = name_len; - if (CertGetCertificateContextProperty(pCertContext, - CERT_FRIENDLY_NAME_PROP_ID, pszNameString, &cch)) - ret = cch; + if (CertGetCertificateContextProperty(cert, CERT_FRIENDLY_NAME_PROP_ID, name_string, &len)) + ret = len; else - ret = CertGetNameStringW(pCertContext, - CERT_NAME_SIMPLE_DISPLAY_TYPE, dwFlags, pvTypePara, pszNameString, - cchNameString); + ret = CertGetNameStringW(cert, CERT_NAME_SIMPLE_DISPLAY_TYPE, flags, + type_para, name_string, name_len); break; } case CERT_NAME_DNS_TYPE: { - CERT_ALT_NAME_INFO *info; - PCERT_ALT_NAME_ENTRY entry = cert_find_alt_name_entry(pCertContext, - altNameOID, CERT_ALT_NAME_DNS_NAME, &info); + unsigned int index = 0, len; - if (entry) + if (cert_get_alt_name_info(cert, alt_name_issuer, &info) + && (entry = cert_find_next_alt_name_entry(info, CERT_ALT_NAME_DNS_NAME, &index))) { - if (!pszNameString) - ret = strlenW(entry->u.pwszDNSName) + 1; - else if (cchNameString) + if (search_all_names) { - ret = min(strlenW(entry->u.pwszDNSName), cchNameString - 1); - memcpy(pszNameString, entry->u.pwszDNSName, ret * sizeof(WCHAR)); - pszNameString[ret++] = 0; + do + { + if (name_string && name_len == 1) break; + ret += len = copy_output_str(name_string, entry->pwszDNSName, name_len ? name_len - 1 : 0); + if (name_string && name_len) + { + name_string += len; + name_len -= len; + } + } + while ((entry = cert_find_next_alt_name_entry(info, CERT_ALT_NAME_DNS_NAME, &index))); + } + else ret = copy_output_str(name_string, entry->pwszDNSName, name_len); + } + else + { + if (!search_all_names || name_len != 1) + { + len = search_all_names && name_len ? name_len - 1 : name_len; + ret = cert_get_name_from_rdn_attr(cert->dwCertEncodingType, name, szOID_COMMON_NAME, + name_string, len); + if (name_string) name_string += ret; } } - if (info) - LocalFree(info); - if (!ret) - ret = cert_get_name_from_rdn_attr(pCertContext->dwCertEncodingType, - name, szOID_COMMON_NAME, pszNameString, cchNameString); + + if (search_all_names) + { + if (name_string && name_len) *name_string = 0; + ++ret; + } break; } case CERT_NAME_URL_TYPE: { - CERT_ALT_NAME_INFO *info; - PCERT_ALT_NAME_ENTRY entry = cert_find_alt_name_entry(pCertContext, - altNameOID, CERT_ALT_NAME_URL, &info); - - if (entry) - { - if (!pszNameString) - ret = strlenW(entry->u.pwszURL) + 1; - else if (cchNameString) - { - ret = min(strlenW(entry->u.pwszURL), cchNameString - 1); - memcpy(pszNameString, entry->u.pwszURL, ret * sizeof(WCHAR)); - pszNameString[ret++] = 0; - } - } - if (info) - LocalFree(info); + if ((entry = cert_find_alt_name_entry(cert, alt_name_issuer, CERT_ALT_NAME_URL, &info))) + ret = copy_output_str(name_string, entry->pwszURL, name_len); break; } default: - FIXME("unimplemented for type %d\n", dwType); + FIXME("unimplemented for type %lu.\n", type); ret = 0; + break; } done: + if (info) + LocalFree(info); + if (!ret) { - if (!pszNameString) - ret = 1; - else if (cchNameString) - { - pszNameString[0] = 0; - ret = 1; - } + ret = 1; + if (name_string && name_len) name_string[0] = 0; } return ret; } diff --git a/dll/win32/crypt32/unixlib.c b/dll/win32/crypt32/unixlib.c new file mode 100644 index 00000000000..5a255442fdf --- /dev/null +++ b/dll/win32/crypt32/unixlib.c @@ -0,0 +1,805 @@ +/* + * Copyright 2019 Hans Leidekker for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#if 0 +#pragma makedep unix +#endif + +#include "config.h" + +#include +#include +#include +#include +#include +#include +#include +#ifdef __APPLE__ +#include +#endif +#ifdef SONAME_LIBGNUTLS +#include +#endif + +#include "ntstatus.h" +#define WIN32_NO_STATUS +#include "windef.h" +#include "winbase.h" +#include "winternl.h" +#include "wincrypt.h" +#include "crypt32_private.h" +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(crypt); + +#ifdef SONAME_LIBGNUTLS + +WINE_DECLARE_DEBUG_CHANNEL(winediag); + +/* Not present in gnutls version < 3.0 */ +int gnutls_pkcs12_simple_parse(gnutls_pkcs12_t p12, const char *password, + gnutls_x509_privkey_t *key, gnutls_x509_crt_t **chain, unsigned int *chain_len, + gnutls_x509_crt_t **extra_certs, unsigned int *extra_certs_len, + gnutls_x509_crl_t * crl, unsigned int flags); + +int gnutls_x509_privkey_get_pk_algorithm2(gnutls_x509_privkey_t, unsigned int*); + +static void *libgnutls_handle; +#define MAKE_FUNCPTR(f) static typeof(f) * p##f +MAKE_FUNCPTR(gnutls_global_deinit); +MAKE_FUNCPTR(gnutls_global_init); +MAKE_FUNCPTR(gnutls_global_set_log_function); +MAKE_FUNCPTR(gnutls_global_set_log_level); +MAKE_FUNCPTR(gnutls_perror); +MAKE_FUNCPTR(gnutls_pkcs12_deinit); +MAKE_FUNCPTR(gnutls_pkcs12_import); +MAKE_FUNCPTR(gnutls_pkcs12_init); +MAKE_FUNCPTR(gnutls_pkcs12_simple_parse); +MAKE_FUNCPTR(gnutls_x509_crt_export); +MAKE_FUNCPTR(gnutls_x509_privkey_export_rsa_raw2); +MAKE_FUNCPTR(gnutls_x509_privkey_get_pk_algorithm2); +#undef MAKE_FUNCPTR + +static void gnutls_log( int level, const char *msg ) +{ + TRACE( "<%d> %s", level, msg ); +} + +static NTSTATUS process_attach( void *args ) +{ + const char *env_str; + int ret; + + if ((env_str = getenv("GNUTLS_SYSTEM_PRIORITY_FILE"))) + { + WARN("GNUTLS_SYSTEM_PRIORITY_FILE is %s.\n", debugstr_a(env_str)); + } + else + { + WARN("Setting GNUTLS_SYSTEM_PRIORITY_FILE to \"/dev/null\".\n"); + setenv("GNUTLS_SYSTEM_PRIORITY_FILE", "/dev/null", 0); + } + + if (!(libgnutls_handle = dlopen( SONAME_LIBGNUTLS, RTLD_NOW ))) + { + ERR_(winediag)( "failed to load libgnutls, no support for pfx import/export\n" ); + return STATUS_DLL_NOT_FOUND; + } + +#define LOAD_FUNCPTR(f) \ + if (!(p##f = dlsym( libgnutls_handle, #f ))) \ + { \ + ERR( "failed to load %s\n", #f ); \ + goto fail; \ + } + + LOAD_FUNCPTR(gnutls_global_deinit) + LOAD_FUNCPTR(gnutls_global_init) + LOAD_FUNCPTR(gnutls_global_set_log_function) + LOAD_FUNCPTR(gnutls_global_set_log_level) + LOAD_FUNCPTR(gnutls_perror) + LOAD_FUNCPTR(gnutls_pkcs12_deinit) + LOAD_FUNCPTR(gnutls_pkcs12_import) + LOAD_FUNCPTR(gnutls_pkcs12_init) + LOAD_FUNCPTR(gnutls_pkcs12_simple_parse) + LOAD_FUNCPTR(gnutls_x509_crt_export) + LOAD_FUNCPTR(gnutls_x509_privkey_export_rsa_raw2) + LOAD_FUNCPTR(gnutls_x509_privkey_get_pk_algorithm2) +#undef LOAD_FUNCPTR + + if ((ret = pgnutls_global_init()) != GNUTLS_E_SUCCESS) + { + pgnutls_perror( ret ); + goto fail; + } + + if (TRACE_ON( crypt )) + { + char *env = getenv("GNUTLS_DEBUG_LEVEL"); + int level = env ? atoi(env) : 4; + pgnutls_global_set_log_level(level); + pgnutls_global_set_log_function( gnutls_log ); + } + + return TRUE; + +fail: + dlclose( libgnutls_handle ); + libgnutls_handle = NULL; + return STATUS_DLL_INIT_FAILED; +} + +static NTSTATUS process_detach( void *args ) +{ + pgnutls_global_deinit(); + dlclose( libgnutls_handle ); + libgnutls_handle = NULL; + return STATUS_SUCCESS; +} +#define RSA_MAGIC_KEY ('R' | ('S' << 8) | ('A' << 16) | ('2' << 24)) +#define RSA_PUBEXP 65537 + +struct cert_store_data +{ + gnutls_pkcs12_t p12; + gnutls_x509_privkey_t key; + gnutls_x509_crt_t *chain; + unsigned int key_bitlen; + unsigned int chain_len; +}; + +static struct cert_store_data *get_store_data( cert_store_data_t data ) +{ + return (struct cert_store_data *)(ULONG_PTR)data; +} + +static NTSTATUS import_store_key( void *args ) +{ + struct import_store_key_params *params = args; + struct cert_store_data *data = get_store_data( params->data ); + int i, ret; + unsigned int bitlen = data->key_bitlen; + gnutls_datum_t m, e, d, p, q, u, e1, e2; + BLOBHEADER *hdr; + RSAPUBKEY *rsakey; + BYTE *src, *dst; + DWORD size; + + size = sizeof(*hdr) + sizeof(*rsakey) + (bitlen * 9 / 16); + if (!params->buf || *params->buf_size < size) + { + *params->buf_size = size; + return STATUS_BUFFER_TOO_SMALL; + } + + if ((ret = pgnutls_x509_privkey_export_rsa_raw2( data->key, &m, &e, &d, &p, &q, &u, &e1, &e2 )) < 0) + { + pgnutls_perror( ret ); + return STATUS_INVALID_PARAMETER; + } + + hdr = params->buf; + hdr->bType = PRIVATEKEYBLOB; + hdr->bVersion = CUR_BLOB_VERSION; + hdr->reserved = 0; + hdr->aiKeyAlg = CALG_RSA_KEYX; + + rsakey = (RSAPUBKEY *)(hdr + 1); + rsakey->magic = RSA_MAGIC_KEY; + rsakey->bitlen = bitlen; + rsakey->pubexp = RSA_PUBEXP; + + dst = (BYTE *)(rsakey + 1); + if (m.size == bitlen / 8 + 1 && !m.data[0]) src = m.data + 1; + else if (m.size != bitlen / 8) goto done; + else src = m.data; + for (i = bitlen / 8 - 1; i >= 0; i--) *dst++ = src[i]; + + if (p.size == bitlen / 16 + 1 && !p.data[0]) src = p.data + 1; + else if (p.size != bitlen / 16) goto done; + else src = p.data; + for (i = bitlen / 16 - 1; i >= 0; i--) *dst++ = src[i]; + + if (q.size == bitlen / 16 + 1 && !q.data[0]) src = q.data + 1; + else if (q.size != bitlen / 16) goto done; + else src = q.data; + for (i = bitlen / 16 - 1; i >= 0; i--) *dst++ = src[i]; + + if (e1.size == bitlen / 16 + 1 && !e1.data[0]) src = e1.data + 1; + else if (e1.size != bitlen / 16) goto done; + else src = e1.data; + for (i = bitlen / 16 - 1; i >= 0; i--) *dst++ = src[i]; + + if (e2.size == bitlen / 16 + 1 && !e2.data[0]) src = e2.data + 1; + else if (e2.size != bitlen / 16) goto done; + else src = e2.data; + for (i = bitlen / 16 - 1; i >= 0; i--) *dst++ = src[i]; + + if (u.size == bitlen / 16 + 1 && !u.data[0]) src = u.data + 1; + else if (u.size != bitlen / 16) goto done; + else src = u.data; + for (i = bitlen / 16 - 1; i >= 0; i--) *dst++ = src[i]; + + if (d.size == bitlen / 8 + 1 && !d.data[0]) src = d.data + 1; + else if (d.size != bitlen / 8) goto done; + else src = d.data; + for (i = bitlen / 8 - 1; i >= 0; i--) *dst++ = src[i]; + +done: + free( m.data ); + free( e.data ); + free( d.data ); + free( p.data ); + free( q.data ); + free( u.data ); + free( e1.data ); + free( e2.data ); + return STATUS_SUCCESS; +} + +static char *password_to_ascii( const WCHAR *str ) +{ + char *ret; + unsigned int i = 0; + + if (!(ret = malloc( (lstrlenW(str) + 1) * sizeof(*ret) ))) return NULL; + while (*str) + { + if (*str > 0x7f) WARN( "password contains non-ascii characters\n" ); + ret[i++] = *str++; + } + ret[i] = 0; + return ret; +} + +static NTSTATUS open_cert_store( void *args ) +{ + struct open_cert_store_params *params = args; + gnutls_pkcs12_t p12; + gnutls_datum_t pfx_data; + gnutls_x509_privkey_t key; + gnutls_x509_crt_t *chain; + unsigned int chain_len; + unsigned int bitlen; + char *pwd = NULL; + int ret; + struct cert_store_data *store_data; + + if (!libgnutls_handle) return STATUS_DLL_NOT_FOUND; + if (params->password && !(pwd = password_to_ascii( params->password ))) return STATUS_NO_MEMORY; + + if ((ret = pgnutls_pkcs12_init( &p12 )) < 0) goto error; + + pfx_data.data = params->pfx->pbData; + pfx_data.size = params->pfx->cbData; + if ((ret = pgnutls_pkcs12_import( p12, &pfx_data, GNUTLS_X509_FMT_DER, 0 )) < 0) goto error; + + if ((ret = pgnutls_pkcs12_simple_parse( p12, pwd ? pwd : "", &key, &chain, &chain_len, NULL, NULL, NULL, 0 )) < 0) + goto error; + + if ((ret = pgnutls_x509_privkey_get_pk_algorithm2( key, &bitlen )) < 0) + goto error; + + free( pwd ); + + if (ret != GNUTLS_PK_RSA) + { + FIXME( "key algorithm %u not supported\n", ret ); + pgnutls_pkcs12_deinit( p12 ); + return STATUS_INVALID_PARAMETER; + } + + store_data = malloc( sizeof(*store_data) ); + store_data->p12 = p12; + store_data->key = key; + store_data->chain = chain; + store_data->key_bitlen = bitlen; + store_data->chain_len = chain_len; + *params->data_ret = (ULONG_PTR)store_data; + return STATUS_SUCCESS; + +error: + pgnutls_perror( ret ); + pgnutls_pkcs12_deinit( p12 ); + free( pwd ); + return STATUS_INVALID_PARAMETER; +} + +static NTSTATUS import_store_cert( void *args ) +{ + struct import_store_cert_params *params = args; + struct cert_store_data *data = get_store_data( params->data ); + size_t size = 0; + int ret; + + if (params->index >= data->chain_len) return STATUS_NO_MORE_ENTRIES; + + if ((ret = pgnutls_x509_crt_export( data->chain[params->index], GNUTLS_X509_FMT_DER, NULL, &size )) != GNUTLS_E_SHORT_MEMORY_BUFFER) + return STATUS_INVALID_PARAMETER; + + if (!params->buf || *params->buf_size < size) + { + *params->buf_size = size; + return STATUS_BUFFER_TOO_SMALL; + } + if ((ret = pgnutls_x509_crt_export( data->chain[params->index], GNUTLS_X509_FMT_DER, params->buf, &size )) < 0) + return STATUS_INVALID_PARAMETER; + + return STATUS_SUCCESS; +} + +static NTSTATUS close_cert_store( void *args ) +{ + struct close_cert_store_params *params = args; + struct cert_store_data *data = get_store_data( params->data ); + + if (params->data) + { + pgnutls_pkcs12_deinit( data->p12 ); + free( data ); + } + return STATUS_SUCCESS; +} + +#else /* SONAME_LIBGNUTLS */ + +static NTSTATUS process_attach( void *args ) { return STATUS_SUCCESS; } +static NTSTATUS process_detach( void *args ) { return STATUS_SUCCESS; } +static NTSTATUS open_cert_store( void *args ) { return STATUS_DLL_NOT_FOUND; } +static NTSTATUS import_store_key( void *args ) { return STATUS_DLL_NOT_FOUND; } +static NTSTATUS import_store_cert( void *args ) { return STATUS_DLL_NOT_FOUND; } +static NTSTATUS close_cert_store( void *args ) { return STATUS_DLL_NOT_FOUND; } + +#endif /* SONAME_LIBGNUTLS */ + +struct root_cert +{ + struct list entry; + SIZE_T size; + BYTE data[1]; +}; + +static struct list root_cert_list = LIST_INIT(root_cert_list); + +static BYTE *add_cert( SIZE_T size ) +{ + struct root_cert *cert = malloc( offsetof( struct root_cert, data[size] )); + + if (!cert) return NULL; + cert->size = size; + list_add_tail( &root_cert_list, &cert->entry ); + return cert->data; +} + +struct DynamicBuffer +{ + DWORD allocated; + DWORD used; + char *data; +}; + +static inline void reset_buffer(struct DynamicBuffer *buffer) +{ + buffer->used = 0; + if (buffer->data) buffer->data[0] = 0; +} + +static void add_line_to_buffer(struct DynamicBuffer *buffer, LPCSTR line) +{ + if (buffer->used + strlen(line) + 1 > buffer->allocated) + { + DWORD new_size = max( max( buffer->allocated * 2, 1024 ), buffer->used + strlen(line) + 1 ); + void *ptr = realloc( buffer->data, new_size ); + if (!ptr) return; + buffer->data = ptr; + buffer->allocated = new_size; + if (!buffer->used) buffer->data[0] = 0; + } + strcpy( buffer->data + buffer->used, line ); + buffer->used += strlen(line); +} + +#define BASE64_DECODE_PADDING 0x100 +#define BASE64_DECODE_WHITESPACE 0x200 +#define BASE64_DECODE_INVALID 0x300 + +static inline int decodeBase64Byte(char c) +{ + int ret = BASE64_DECODE_INVALID; + + if (c >= 'A' && c <= 'Z') + ret = c - 'A'; + else if (c >= 'a' && c <= 'z') + ret = c - 'a' + 26; + else if (c >= '0' && c <= '9') + ret = c - '0' + 52; + else if (c == '+') + ret = 62; + else if (c == '/') + ret = 63; + else if (c == '=') + ret = BASE64_DECODE_PADDING; + else if (c == ' ' || c == '\t' || c == '\r' || c == '\n') + ret = BASE64_DECODE_WHITESPACE; + return ret; +} + +static BOOL base64_to_cert( const char *str ) +{ + DWORD i, valid, out, hasPadding; + BYTE block[4], *data; + + for (i = valid = out = hasPadding = 0; str[i]; i++) + { + int d = decodeBase64Byte( str[i] ); + if (d == BASE64_DECODE_INVALID) return FALSE; + if (d == BASE64_DECODE_WHITESPACE) continue; + + /* When padding starts, data is not acceptable */ + if (hasPadding && d != BASE64_DECODE_PADDING) return FALSE; + + /* Padding after a full block (like "VVVV=") is ok and stops decoding */ + if (d == BASE64_DECODE_PADDING && (valid & 3) == 0) break; + + valid++; + if (d == BASE64_DECODE_PADDING) + { + hasPadding = 1; + /* When padding reaches a full block, stop decoding */ + if ((valid & 3) == 0) break; + continue; + } + + /* out is incremented in the 4-char block as follows: "1-23" */ + if ((valid & 3) != 2) out++; + } + /* Fail if the block has bad padding; omitting padding is fine */ + if ((valid & 3) != 0 && hasPadding) return FALSE; + + if (!(data = add_cert( out ))) return FALSE; + for (i = valid = out = 0; str[i]; i++) + { + int d = decodeBase64Byte( str[i] ); + if (d == BASE64_DECODE_WHITESPACE) continue; + if (d == BASE64_DECODE_PADDING) break; + block[valid & 3] = d; + valid += 1; + switch (valid & 3) + { + case 1: + data[out++] = (block[0] << 2); + break; + case 2: + data[out-1] = (block[0] << 2) | (block[1] >> 4); + break; + case 3: + data[out++] = (block[1] << 4) | (block[2] >> 2); + break; + case 0: + data[out++] = (block[2] << 6) | (block[3] >> 0); + break; + } + } + return TRUE; +} + +/* Reads the file fd, and imports any certificates in it into store. */ +static void import_certs_from_file( int fd ) +{ + FILE *fp = fdopen(fd, "r"); + char line[1024]; + BOOL in_cert = FALSE; + struct DynamicBuffer saved_cert = { 0, 0, NULL }; + int num_certs = 0; + + if (!fp) return; + TRACE("\n"); + while (fgets(line, sizeof(line), fp)) + { + static const char header[] = "-----BEGIN CERTIFICATE-----"; + static const char trailer[] = "-----END CERTIFICATE-----"; + + if (!strncmp(line, header, strlen(header))) + { + TRACE("begin new certificate\n"); + in_cert = TRUE; + reset_buffer(&saved_cert); + } + else if (!strncmp(line, trailer, strlen(trailer))) + { + TRACE("end of certificate, adding cert\n"); + in_cert = FALSE; + if (base64_to_cert( saved_cert.data )) num_certs++; + } + else if (in_cert) add_line_to_buffer(&saved_cert, line); + } + free( saved_cert.data ); + TRACE("Read %d certs\n", num_certs); + fclose(fp); +} + +static void import_certs_from_path(LPCSTR path, BOOL allow_dir); + +static BOOL check_buffer_resize(char **ptr_buf, size_t *buf_size, size_t check_size) +{ + if (check_size > *buf_size) + { + void *ptr = realloc(*ptr_buf, check_size); + + if (!ptr) return FALSE; + *buf_size = check_size; + *ptr_buf = ptr; + } + return TRUE; +} + +/* Opens path, which must be a directory, and imports certificates from every + * file in the directory into store. + * Returns TRUE if any certificates were successfully imported. + */ +static void import_certs_from_dir( LPCSTR path ) +{ + DIR *dir; + + dir = opendir(path); + if (dir) + { + size_t path_len = strlen(path), bufsize = 0; + char *filebuf = NULL; + + struct dirent *entry; + while ((entry = readdir(dir))) + { + if (strcmp(entry->d_name, ".") && strcmp(entry->d_name, "..")) + { + size_t name_len = strlen(entry->d_name); + + if (!check_buffer_resize(&filebuf, &bufsize, path_len + 1 + name_len + 1)) break; + snprintf(filebuf, bufsize, "%s/%s", path, entry->d_name); + import_certs_from_path(filebuf, FALSE); + } + } + free(filebuf); + closedir(dir); + } +} + +/* Opens path, which may be a file or a directory, and imports any certificates + * it finds into store. + * Returns TRUE if any certificates were successfully imported. + */ +static void import_certs_from_path(LPCSTR path, BOOL allow_dir) +{ + int fd; + + TRACE("(%s, %d)\n", debugstr_a(path), allow_dir); + + fd = open(path, O_RDONLY); + if (fd != -1) + { + struct stat st; + + if (fstat(fd, &st) == 0) + { + if (S_ISREG(st.st_mode)) + import_certs_from_file(fd); + else if (S_ISDIR(st.st_mode)) + { + if (allow_dir) + import_certs_from_dir(path); + else + WARN("%s is a directory and directories are disallowed\n", + debugstr_a(path)); + } + else + ERR("%s: invalid file type\n", path); + } + close(fd); + } +} + +static const char * const CRYPT_knownLocations[] = { + "/etc/ssl/certs/ca-certificates.crt", + "/etc/ssl/certs", + "/etc/pki/tls/certs/ca-bundle.crt", + "/usr/share/ca-certificates/ca-bundle.crt", + "/usr/local/share/certs/", + "/etc/sfw/openssl/certs", + "/etc/security/cacerts", /* Android */ +}; + +static void load_root_certs(void) +{ + unsigned int i; + +#ifdef __APPLE__ + const SecTrustSettingsDomain domains[] = { + kSecTrustSettingsDomainSystem, + kSecTrustSettingsDomainAdmin, + kSecTrustSettingsDomainUser + }; + OSStatus status; + CFArrayRef certs; + DWORD domain; + + for (domain = 0; domain < ARRAY_SIZE(domains); domain++) + { + status = SecTrustSettingsCopyCertificates(domains[domain], &certs); + if (status == noErr) + { + for (i = 0; i < CFArrayGetCount(certs); i++) + { + SecCertificateRef cert = (SecCertificateRef)CFArrayGetValueAtIndex(certs, i); + CFDataRef certData; + if ((status = SecItemExport(cert, kSecFormatX509Cert, 0, NULL, &certData)) == noErr) + { + BYTE *data = add_cert( CFDataGetLength(certData) ); + if (data) memcpy( data, CFDataGetBytePtr(certData), CFDataGetLength(certData) ); + CFRelease(certData); + } + else + WARN("could not export certificate %u to X509 format: 0x%08x\n", i, (unsigned int)status); + } + CFRelease(certs); + } + } +#endif + + for (i = 0; i < ARRAY_SIZE(CRYPT_knownLocations) && list_empty(&root_cert_list); i++) + import_certs_from_path( CRYPT_knownLocations[i], TRUE ); +} + +static NTSTATUS enum_root_certs( void *args ) +{ + struct enum_root_certs_params *params = args; + static BOOL loaded; + struct list *ptr; + struct root_cert *cert; + + if (!loaded) load_root_certs(); + loaded = TRUE; + + if (!(ptr = list_head( &root_cert_list ))) return STATUS_NO_MORE_ENTRIES; + cert = LIST_ENTRY( ptr, struct root_cert, entry ); + *params->needed = cert->size; + if (cert->size <= params->size) + { + memcpy( params->buffer, cert->data, cert->size ); + list_remove( &cert->entry ); + free( cert ); + } + return STATUS_SUCCESS; +} + +const unixlib_entry_t __wine_unix_call_funcs[] = +{ + process_attach, + process_detach, + open_cert_store, + import_store_key, + import_store_cert, + close_cert_store, + enum_root_certs, +}; + +C_ASSERT( ARRAYSIZE(__wine_unix_call_funcs) == unix_funcs_count ); + +#ifdef _WIN64 + +typedef ULONG PTR32; + +typedef struct +{ + DWORD cbData; + PTR32 pbData; +} CRYPT_DATA_BLOB32; + +static NTSTATUS wow64_open_cert_store( void *args ) +{ + struct + { + PTR32 pfx; + PTR32 password; + PTR32 data_ret; + } const *params32 = args; + + const CRYPT_DATA_BLOB32 *pfx32 = ULongToPtr( params32->pfx ); + CRYPT_DATA_BLOB pfx = { pfx32->cbData, ULongToPtr( pfx32->pbData ) }; + struct open_cert_store_params params = + { + &pfx, + ULongToPtr( params32->password ), + ULongToPtr( params32->data_ret ) + }; + + return open_cert_store( ¶ms ); +} + +static NTSTATUS wow64_import_store_key( void *args ) +{ + struct + { + cert_store_data_t data; + PTR32 buf; + PTR32 buf_size; + } const *params32 = args; + + struct import_store_key_params params = + { + params32->data, + ULongToPtr( params32->buf ), + ULongToPtr( params32->buf_size ) + }; + + return import_store_key( ¶ms ); +} + +static NTSTATUS wow64_import_store_cert( void *args ) +{ + struct + { + cert_store_data_t data; + unsigned int index; + PTR32 buf; + PTR32 buf_size; + } const *params32 = args; + + struct import_store_cert_params params = + { + params32->data, + params32->index, + ULongToPtr( params32->buf ), + ULongToPtr( params32->buf_size ) + }; + + return import_store_cert( ¶ms ); +} + +static NTSTATUS wow64_enum_root_certs( void *args ) +{ + struct + { + PTR32 buffer; + DWORD size; + PTR32 needed; + } const *params32 = args; + + struct enum_root_certs_params params = + { + ULongToPtr( params32->buffer ), + params32->size, + ULongToPtr( params32->needed ) + }; + + return enum_root_certs( ¶ms ); +} + +const unixlib_entry_t __wine_unix_call_wow64_funcs[] = +{ + process_attach, + process_detach, + wow64_open_cert_store, + wow64_import_store_key, + wow64_import_store_cert, + close_cert_store, + wow64_enum_root_certs, +}; + +C_ASSERT( ARRAYSIZE(__wine_unix_call_wow64_funcs) == unix_funcs_count ); + +#endif /* _WIN64 */ diff --git a/dll/win32/crypt32/wine/unixlib.h b/dll/win32/crypt32/wine/unixlib.h new file mode 100644 index 00000000000..b34dcaf1abf --- /dev/null +++ b/dll/win32/crypt32/wine/unixlib.h @@ -0,0 +1,32 @@ +/* + * PROJECT: ReactOS win32 DLLs + * LICENSE: MIT (https://spdx.org/licenses/MIT) + * PURPOSE: ReactOS emulation layer for crypt32 unixlib calls + * COPYRIGHT: Copyright 2026 Timo Kreuzer + */ + +#pragma once + +#include "crypt32_private.h" +#include // Workaround: Needed by encode.c + +#define __wine_init_unix_call() 0 + +static inline int __reactos_call_unix_process_attach(void* Args) +{ + return 0; +} + +static inline int __reactos_call_unix_process_detach(void* Args) +{ + return 0; +} + +// Implemented in reactos/unixlib.c +int __reactos_call_unix_open_cert_store(void* Args); +int __reactos_call_unix_close_cert_store(void* Args); +int __reactos_call_unix_import_store_key(void* Args); +int __reactos_call_unix_import_store_cert(void* Args); +int __reactos_call_unix_enum_root_certs(void* Args); + +#define WINE_UNIX_CALL(code,args) __reactos_call_ ## code(args) diff --git a/media/doc/WINESYNC.txt b/media/doc/WINESYNC.txt index 0060a163c76..7a2172cda73 100644 --- a/media/doc/WINESYNC.txt +++ b/media/doc/WINESYNC.txt @@ -70,7 +70,7 @@ dll/win32/comdlg32 # Synced to WineStaging-4.18 dll/win32/coml2 # Synced to Wine-10.0 dll/win32/compstui # Synced to WineStaging-4.18 dll/win32/credui # Synced to WineStaging-4.18 -dll/win32/crypt32 # Synced to WineStaging-4.0 +dll/win32/crypt32 # Synced to Wine-10.0 dll/win32/cryptdlg # Synced to WineStaging-4.18 dll/win32/cryptdll # Synced to WineStaging-4.18 dll/win32/cryptnet # Synced to Wine-10.0