Author: akhaldi Date: Sun Mar 5 21:21:36 2017 New Revision: 74101
URL: http://svn.reactos.org/svn/reactos?rev=74101&view=rev Log: [CRYPT32] Sync with Wine Staging 2.2. CORE-12823
a7d1d77 crypt32: Recognize sha256/384/512 KEY OIDs. e376123 crypt32: Remove unused parameter and dead code. 254eb21 crypt32: Fix wrong Base64 trailer WCHAR constants. a2f2de1 crypt32: CryptStringToBinary accepts any header. 552820a crypt32: Fix Base64 issues in CryptStringToBinary. e353ab6 crypt32: Base64 header requires a space.
Modified: trunk/reactos/dll/win32/crypt32/base64.c trunk/reactos/dll/win32/crypt32/oid.c trunk/reactos/media/doc/README.WINE
Modified: trunk/reactos/dll/win32/crypt32/base64.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/crypt32/base64.c?... ============================================================================== --- trunk/reactos/dll/win32/crypt32/base64.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/crypt32/base64.c [iso-8859-1] Sun Mar 5 21:21:36 2017 @@ -24,10 +24,10 @@ WINE_DEFAULT_DEBUG_CHANNEL(crypt);
#define CERT_HEADER "-----BEGIN CERTIFICATE-----" -#define CERT_HEADER_START "-----BEGIN" +#define CERT_HEADER_START "-----BEGIN " #define CERT_DELIMITER "-----" #define CERT_TRAILER "-----END CERTIFICATE-----" -#define CERT_TRAILER_START "-----END" +#define CERT_TRAILER_START "-----END " #define CERT_REQUEST_HEADER "-----BEGIN NEW CERTIFICATE REQUEST-----" #define CERT_REQUEST_TRAILER "-----END NEW CERTIFICATE REQUEST-----" #define X509_HEADER "-----BEGIN X509 CRL-----" @@ -37,14 +37,14 @@ '-','-','-','-','-','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 }; +'-','-','-','-','-','B','E','G','I','N',' ',0 }; static const WCHAR CERT_DELIMITER_W[] = { '-','-','-','-','-',0 }; static const WCHAR CERT_TRAILER_W[] = { -'-','-','-','-','-','E','N','D',0 }; -static const WCHAR CERT_TRAILER_START_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 }; @@ -477,9 +477,13 @@ return encoder(pbBinary, cbBinary, dwFlags, pszString, pcchString); }
-static inline BYTE decodeBase64Byte(int c) -{ - BYTE ret; +#define BASE64_DECODE_PADDING 0x100 +#define BASE64_DECODE_WHITESPACE 0x200 +#define BASE64_DECODE_INVALID 0x300 + +static inline int decodeBase64Byte(int c) +{ + int ret = BASE64_DECODE_INVALID;
if (c >= 'A' && c <= 'Z') ret = c - 'A'; @@ -491,76 +495,11 @@ ret = 62; else if (c == '/') ret = 63; - else - ret = 64; - return ret; -} - -static LONG decodeBase64Block(const char *in_buf, int in_len, - const char **nextBlock, PBYTE out_buf, DWORD *out_len) -{ - int len = in_len; - const char *d = in_buf; - int ip0, ip1, ip2, ip3; - - if (len < 4) - return ERROR_INVALID_DATA; - - if (d[2] == '=') - { - if ((ip0 = decodeBase64Byte(d[0])) > 63) - return ERROR_INVALID_DATA; - if ((ip1 = decodeBase64Byte(d[1])) > 63) - return ERROR_INVALID_DATA; - - if (out_buf) - out_buf[0] = (ip0 << 2) | (ip1 >> 4); - *out_len = 1; - } - else if (d[3] == '=') - { - if ((ip0 = decodeBase64Byte(d[0])) > 63) - return ERROR_INVALID_DATA; - if ((ip1 = decodeBase64Byte(d[1])) > 63) - return ERROR_INVALID_DATA; - if ((ip2 = decodeBase64Byte(d[2])) > 63) - return ERROR_INVALID_DATA; - - if (out_buf) - { - out_buf[0] = (ip0 << 2) | (ip1 >> 4); - out_buf[1] = (ip1 << 4) | (ip2 >> 2); - } - *out_len = 2; - } - else - { - if ((ip0 = decodeBase64Byte(d[0])) > 63) - return ERROR_INVALID_DATA; - if ((ip1 = decodeBase64Byte(d[1])) > 63) - return ERROR_INVALID_DATA; - if ((ip2 = decodeBase64Byte(d[2])) > 63) - return ERROR_INVALID_DATA; - if ((ip3 = decodeBase64Byte(d[3])) > 63) - return ERROR_INVALID_DATA; - - if (out_buf) - { - out_buf[0] = (ip0 << 2) | (ip1 >> 4); - out_buf[1] = (ip1 << 4) | (ip2 >> 2); - out_buf[2] = (ip2 << 6) | ip3; - } - *out_len = 3; - } - if (len >= 6 && d[4] == '\r' && d[5] == '\n') - *nextBlock = d + 6; - else if (len >= 5 && d[4] == '\n') - *nextBlock = d + 5; - else if (len >= 4 && d[4]) - *nextBlock = d + 4; - else - *nextBlock = NULL; - return ERROR_SUCCESS; + else if (c == '=') + ret = BASE64_DECODE_PADDING; + else if (c == ' ' || c == '\t' || c == '\r' || c == '\n') + ret = BASE64_DECODE_WHITESPACE; + return ret; }
/* Unlike CryptStringToBinaryA, cchString is guaranteed to be the length of the @@ -569,46 +508,101 @@ typedef LONG (*StringToBinaryAFunc)(LPCSTR pszString, DWORD cchString, BYTE *pbBinary, DWORD *pcbBinary, DWORD *pdwSkip, DWORD *pdwFlags);
+static LONG Base64ToBinary(const void* pszString, BOOL wide, DWORD cchString, + BYTE *pbBinary, DWORD *pcbBinary, DWORD *pdwSkip, DWORD *pdwFlags) +{ + DWORD cbIn, cbValid, cbOut, hasPadding; + BYTE block[4]; + for (cbIn = cbValid = cbOut = hasPadding = 0; cbIn < cchString; ++cbIn) + { + int c = wide ? (int)((WCHAR*)pszString)[cbIn] : (int)((char*)pszString)[cbIn]; + int d = decodeBase64Byte(c); + if (d == BASE64_DECODE_INVALID) + goto invalid; + if (d == BASE64_DECODE_WHITESPACE) + continue; + + /* When padding starts, data is not acceptable */ + if (hasPadding && d != BASE64_DECODE_PADDING) + goto invalid; + + /* Padding after a full block (like "VVVV=") is ok and stops decoding */ + if (d == BASE64_DECODE_PADDING && (cbValid & 3) == 0) + break; + + cbValid += 1; + + if (d == BASE64_DECODE_PADDING) + { + hasPadding = 1; + /* When padding reaches a full block, stop decoding */ + if ((cbValid & 3) == 0) + break; + continue; + } + + /* cbOut is incremented in the 4-char block as follows: "1-23" */ + if ((cbValid & 3) != 2) + cbOut += 1; + } + /* Fail if the block has bad padding; omitting padding is fine */ + if ((cbValid & 3) != 0 && hasPadding) + goto invalid; + /* Check available buffer size */ + if (pbBinary && *pcbBinary && cbOut > *pcbBinary) + goto overflow; + /* Convert the data; this step depends on the validity checks above! */ + if (pbBinary) for (cbIn = cbValid = cbOut = 0; cbIn < cchString; ++cbIn) + { + int c = wide ? (int)((WCHAR*)pszString)[cbIn] : (int)((char*)pszString)[cbIn]; + int d = decodeBase64Byte(c); + if (d == BASE64_DECODE_WHITESPACE) + continue; + if (d == BASE64_DECODE_PADDING) + break; + block[cbValid & 3] = d; + cbValid += 1; + switch (cbValid & 3) { + case 1: + pbBinary[cbOut++] = (block[0] << 2); + break; + case 2: + pbBinary[cbOut-1] = (block[0] << 2) | (block[1] >> 4); + break; + case 3: + pbBinary[cbOut++] = (block[1] << 4) | (block[2] >> 2); + break; + case 0: + pbBinary[cbOut++] = (block[2] << 6) | (block[3] >> 0); + break; + } + } + *pcbBinary = cbOut; + if (pdwSkip) + *pdwSkip = 0; + if (pdwFlags) + *pdwFlags = CRYPT_STRING_BASE64; + return ERROR_SUCCESS; +overflow: + return ERROR_INSUFFICIENT_BUFFER; +invalid: + *pcbBinary = cbOut; + return ERROR_INVALID_DATA; +} + static LONG Base64ToBinaryA(LPCSTR pszString, DWORD cchString, BYTE *pbBinary, DWORD *pcbBinary, DWORD *pdwSkip, DWORD *pdwFlags) { - LONG ret = ERROR_SUCCESS; - const char *nextBlock; - DWORD outLen = 0; - - nextBlock = pszString; - while (nextBlock && !ret) - { - DWORD len = 0; - - ret = decodeBase64Block(nextBlock, cchString - (nextBlock - pszString), - &nextBlock, pbBinary ? pbBinary + outLen : NULL, &len); - if (!ret) - outLen += len; - if (cchString - (nextBlock - pszString) <= 0) - nextBlock = NULL; - } - *pcbBinary = outLen; - if (!ret) - { - if (pdwSkip) - *pdwSkip = 0; - if (pdwFlags) - *pdwFlags = CRYPT_STRING_BASE64; - } - else if (ret == ERROR_INSUFFICIENT_BUFFER) - { - if (!pbBinary) - ret = ERROR_SUCCESS; - } - return ret; + return Base64ToBinary(pszString, FALSE, cchString, pbBinary, pcbBinary, pdwSkip, pdwFlags); }
static LONG Base64WithHeaderAndTrailerToBinaryA(LPCSTR pszString, - DWORD cchString, LPCSTR header, LPCSTR trailer, BYTE *pbBinary, - DWORD *pcbBinary, DWORD *pdwSkip, BOOL exactHeaderAndTrailerMatch) + DWORD cchString, BYTE *pbBinary, + DWORD *pcbBinary, DWORD *pdwSkip) { LONG ret; + LPCSTR header = CERT_HEADER_START; + LPCSTR trailer = CERT_TRAILER_START;
LPCSTR headerBegins; LPCSTR dataBegins; @@ -627,43 +621,20 @@ }
dataBegins = headerBegins + strlen(header); - if (!exactHeaderAndTrailerMatch) - { - if ((dataBegins = strstr(dataBegins, CERT_DELIMITER))) - { - dataBegins += strlen(CERT_DELIMITER); - } - else - { - return ERROR_INVALID_DATA; - } - } + if (!(dataBegins = strstr(dataBegins, CERT_DELIMITER))) + { + return ERROR_INVALID_DATA; + } + dataBegins += strlen(CERT_DELIMITER); if (*dataBegins == '\r') dataBegins++; if (*dataBegins == '\n') dataBegins++;
- if (exactHeaderAndTrailerMatch) - { - trailerBegins = pszString + cchString - strlen(trailer); - if (pszString[cchString - 1] == '\n') trailerBegins--; - if (pszString[cchString - 2] == '\r') trailerBegins--; - - if (*(trailerBegins-1) == '\n') trailerBegins--; - if (*(trailerBegins-1) == '\r') trailerBegins--; - - if (!strncmp(trailerBegins, trailer, strlen(trailer))) - { - return ERROR_INVALID_DATA; - } - } - else - { - if (!(trailerBegins = strstr(dataBegins, trailer))) - { - return ERROR_INVALID_DATA; - } - if (*(trailerBegins-1) == '\n') trailerBegins--; - if (*(trailerBegins-1) == '\r') trailerBegins--; - } + if (!(trailerBegins = strstr(dataBegins, trailer))) + { + return ERROR_INVALID_DATA; + } + if (*(trailerBegins-1) == '\n') trailerBegins--; + if (*(trailerBegins-1) == '\r') trailerBegins--;
if (pdwSkip) *pdwSkip = headerBegins - pszString; @@ -680,7 +651,7 @@ BYTE *pbBinary, DWORD *pcbBinary, DWORD *pdwSkip, DWORD *pdwFlags) { LONG ret = Base64WithHeaderAndTrailerToBinaryA(pszString, cchString, - CERT_HEADER_START, CERT_TRAILER_START, pbBinary, pcbBinary, pdwSkip, FALSE); + pbBinary, pcbBinary, pdwSkip);
if (!ret && pdwFlags) *pdwFlags = CRYPT_STRING_BASE64HEADER; @@ -691,7 +662,7 @@ BYTE *pbBinary, DWORD *pcbBinary, DWORD *pdwSkip, DWORD *pdwFlags) { LONG ret = Base64WithHeaderAndTrailerToBinaryA(pszString, cchString, - CERT_REQUEST_HEADER, CERT_REQUEST_TRAILER, pbBinary, pcbBinary, pdwSkip, TRUE); + pbBinary, pcbBinary, pdwSkip);
if (!ret && pdwFlags) *pdwFlags = CRYPT_STRING_BASE64REQUESTHEADER; @@ -702,7 +673,7 @@ BYTE *pbBinary, DWORD *pcbBinary, DWORD *pdwSkip, DWORD *pdwFlags) { LONG ret = Base64WithHeaderAndTrailerToBinaryA(pszString, cchString, - X509_HEADER, X509_TRAILER, pbBinary, pcbBinary, pdwSkip, TRUE); + pbBinary, pcbBinary, pdwSkip);
if (!ret && pdwFlags) *pdwFlags = CRYPT_STRING_BASE64X509CRLHEADER; @@ -824,75 +795,6 @@ return ret == ERROR_SUCCESS; }
-static LONG decodeBase64BlockW(const WCHAR *in_buf, int in_len, - const WCHAR **nextBlock, PBYTE out_buf, DWORD *out_len) -{ - int len = in_len, i; - const WCHAR *d = in_buf; - int ip0, ip1, ip2, ip3; - - if (len < 4) - return ERROR_INVALID_DATA; - - i = 0; - if (d[2] == '=') - { - if ((ip0 = decodeBase64Byte(d[0])) > 63) - return ERROR_INVALID_DATA; - if ((ip1 = decodeBase64Byte(d[1])) > 63) - return ERROR_INVALID_DATA; - - if (out_buf) - out_buf[i] = (ip0 << 2) | (ip1 >> 4); - i++; - } - else if (d[3] == '=') - { - if ((ip0 = decodeBase64Byte(d[0])) > 63) - return ERROR_INVALID_DATA; - if ((ip1 = decodeBase64Byte(d[1])) > 63) - return ERROR_INVALID_DATA; - if ((ip2 = decodeBase64Byte(d[2])) > 63) - return ERROR_INVALID_DATA; - - if (out_buf) - { - out_buf[i + 0] = (ip0 << 2) | (ip1 >> 4); - out_buf[i + 1] = (ip1 << 4) | (ip2 >> 2); - } - i += 2; - } - else - { - if ((ip0 = decodeBase64Byte(d[0])) > 63) - return ERROR_INVALID_DATA; - if ((ip1 = decodeBase64Byte(d[1])) > 63) - return ERROR_INVALID_DATA; - if ((ip2 = decodeBase64Byte(d[2])) > 63) - return ERROR_INVALID_DATA; - if ((ip3 = decodeBase64Byte(d[3])) > 63) - return ERROR_INVALID_DATA; - - if (out_buf) - { - out_buf[i + 0] = (ip0 << 2) | (ip1 >> 4); - out_buf[i + 1] = (ip1 << 4) | (ip2 >> 2); - out_buf[i + 2] = (ip2 << 6) | ip3; - } - i += 3; - } - if (len >= 6 && d[4] == '\r' && d[5] == '\n') - *nextBlock = d + 6; - else if (len >= 5 && d[4] == '\n') - *nextBlock = d + 5; - else if (len >= 4 && d[4]) - *nextBlock = d + 4; - else - *nextBlock = NULL; - *out_len = i; - return ERROR_SUCCESS; -} - /* Unlike CryptStringToBinaryW, cchString is guaranteed to be the length of the * string to convert. */ @@ -902,43 +804,16 @@ static LONG Base64ToBinaryW(LPCWSTR pszString, DWORD cchString, BYTE *pbBinary, DWORD *pcbBinary, DWORD *pdwSkip, DWORD *pdwFlags) { - LONG ret = ERROR_SUCCESS; - const WCHAR *nextBlock; - DWORD outLen = 0; - - nextBlock = pszString; - while (nextBlock && !ret) - { - DWORD len = 0; - - ret = decodeBase64BlockW(nextBlock, cchString - (nextBlock - pszString), - &nextBlock, pbBinary ? pbBinary + outLen : NULL, &len); - if (!ret) - outLen += len; - if (cchString - (nextBlock - pszString) <= 0) - nextBlock = NULL; - } - *pcbBinary = outLen; - if (!ret) - { - if (pdwSkip) - *pdwSkip = 0; - if (pdwFlags) - *pdwFlags = CRYPT_STRING_BASE64; - } - else if (ret == ERROR_INSUFFICIENT_BUFFER) - { - if (!pbBinary) - ret = ERROR_SUCCESS; - } - return ret; + return Base64ToBinary(pszString, TRUE, cchString, pbBinary, pcbBinary, pdwSkip, pdwFlags); }
static LONG Base64WithHeaderAndTrailerToBinaryW(LPCWSTR pszString, - DWORD cchString, LPCWSTR header, LPCWSTR trailer, BYTE *pbBinary, - DWORD *pcbBinary, DWORD *pdwSkip, BOOL exactHeaderAndTrailerMatch) + DWORD cchString, BYTE *pbBinary, + DWORD *pcbBinary, DWORD *pdwSkip) { LONG ret; + LPCWSTR header = CERT_HEADER_START_W; + LPCWSTR trailer = CERT_TRAILER_START_W;
LPCWSTR headerBegins; LPCWSTR dataBegins; @@ -957,43 +832,20 @@ }
dataBegins = headerBegins + strlenW(header); - if (!exactHeaderAndTrailerMatch) - { - if ((dataBegins = strstrW(dataBegins, CERT_DELIMITER_W))) - { - dataBegins += strlenW(CERT_DELIMITER_W); - } - else - { - return ERROR_INVALID_DATA; - } - } + if (!(dataBegins = strstrW(dataBegins, CERT_DELIMITER_W))) + { + return ERROR_INVALID_DATA; + } + dataBegins += strlenW(CERT_DELIMITER_W); if (*dataBegins == '\r') dataBegins++; if (*dataBegins == '\n') dataBegins++;
- if (exactHeaderAndTrailerMatch) - { - trailerBegins = pszString + cchString - strlenW(trailer); - if (pszString[cchString - 1] == '\n') trailerBegins--; - if (pszString[cchString - 2] == '\r') trailerBegins--; - - if (*(trailerBegins-1) == '\n') trailerBegins--; - if (*(trailerBegins-1) == '\r') trailerBegins--; - - if (!strncmpW(trailerBegins, trailer, strlenW(trailer))) - { - return ERROR_INVALID_DATA; - } - } - else - { - if (!(trailerBegins = strstrW(dataBegins, trailer))) - { - return ERROR_INVALID_DATA; - } - if (*(trailerBegins-1) == '\n') trailerBegins--; - if (*(trailerBegins-1) == '\r') trailerBegins--; - } + if (!(trailerBegins = strstrW(dataBegins, trailer))) + { + return ERROR_INVALID_DATA; + } + if (*(trailerBegins-1) == '\n') trailerBegins--; + if (*(trailerBegins-1) == '\r') trailerBegins--;
if (pdwSkip) *pdwSkip = headerBegins - pszString; @@ -1010,8 +862,7 @@ BYTE *pbBinary, DWORD *pcbBinary, DWORD *pdwSkip, DWORD *pdwFlags) { LONG ret = Base64WithHeaderAndTrailerToBinaryW(pszString, cchString, - CERT_HEADER_START_W, CERT_TRAILER_START_W, pbBinary, pcbBinary, - pdwSkip, FALSE); + pbBinary, pcbBinary, pdwSkip);
if (!ret && pdwFlags) *pdwFlags = CRYPT_STRING_BASE64HEADER; @@ -1022,8 +873,7 @@ BYTE *pbBinary, DWORD *pcbBinary, DWORD *pdwSkip, DWORD *pdwFlags) { LONG ret = Base64WithHeaderAndTrailerToBinaryW(pszString, cchString, - CERT_REQUEST_HEADER_W, CERT_REQUEST_TRAILER_W, pbBinary, pcbBinary, - pdwSkip, TRUE); + pbBinary, pcbBinary, pdwSkip);
if (!ret && pdwFlags) *pdwFlags = CRYPT_STRING_BASE64REQUESTHEADER; @@ -1034,7 +884,7 @@ BYTE *pbBinary, DWORD *pcbBinary, DWORD *pdwSkip, DWORD *pdwFlags) { LONG ret = Base64WithHeaderAndTrailerToBinaryW(pszString, cchString, - X509_HEADER_W, X509_TRAILER_W, pbBinary, pcbBinary, pdwSkip, TRUE); + pbBinary, pcbBinary, pdwSkip);
if (!ret && pdwFlags) *pdwFlags = CRYPT_STRING_BASE64X509CRLHEADER;
Modified: trunk/reactos/dll/win32/crypt32/oid.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/crypt32/oid.c?rev... ============================================================================== --- trunk/reactos/dll/win32/crypt32/oid.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/crypt32/oid.c [iso-8859-1] Sun Mar 5 21:21:36 2017 @@ -1039,6 +1039,9 @@ 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 }; @@ -1143,6 +1146,9 @@ { 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_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 },
{ 2, szOID_OIWSEC_desCBC, CALG_DES, des, NULL }, { 2, szOID_RSA_DES_EDE3_CBC, CALG_3DES, tripledes, NULL },
Modified: trunk/reactos/media/doc/README.WINE URL: http://svn.reactos.org/svn/reactos/trunk/reactos/media/doc/README.WINE?rev=7... ============================================================================== --- trunk/reactos/media/doc/README.WINE [iso-8859-1] (original) +++ trunk/reactos/media/doc/README.WINE [iso-8859-1] Sun Mar 5 21:21:36 2017 @@ -58,7 +58,7 @@ reactos/dll/win32/comdlg32 # Synced to WineStaging-2.2 reactos/dll/win32/compstui # Synced to WineStaging-2.2 reactos/dll/win32/credui # Synced to WineStaging-2.2 -reactos/dll/win32/crypt32 # Synced to WineStaging-1.9.23 +reactos/dll/win32/crypt32 # Synced to WineStaging-2.2 reactos/dll/win32/cryptdlg # Synced to WineStaging-1.9.11 reactos/dll/win32/cryptdll # Synced to WineStaging-1.9.11 reactos/dll/win32/cryptnet # Synced to WineStaging-1.9.11