mirror of
https://github.com/reactos/wine.git
synced 2024-11-29 06:30:37 +00:00
- add some tests for OID functions
- implement encoding integers
This commit is contained in:
parent
719187f190
commit
46185a9f8e
@ -22,6 +22,7 @@
|
||||
#include "winbase.h"
|
||||
#include "wincrypt.h"
|
||||
#include "winreg.h"
|
||||
#include "snmp.h"
|
||||
#include "wine/debug.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(crypt);
|
||||
@ -77,15 +78,18 @@ BOOL WINAPI CryptRegisterOIDFunction(DWORD dwEncodingType, LPCSTR pszFuncName,
|
||||
if (!GET_CERT_ENCODING_TYPE(dwEncodingType))
|
||||
return TRUE;
|
||||
|
||||
/* Native does nothing pwszDll is NULL */
|
||||
if (!pwszDll)
|
||||
return TRUE;
|
||||
|
||||
/* I'm not matching MS bug for bug here, because I doubt any app depends on
|
||||
* it:
|
||||
* - native does nothing if pwszDll is NULL
|
||||
* - native "succeeds" if pszFuncName is NULL, but the nonsensical entry
|
||||
* it creates would never be used
|
||||
* - native returns an HRESULT rather than a Win32 error if pszOID is NULL.
|
||||
* Instead I disallow all of these with ERROR_INVALID_PARAMETER.
|
||||
* Instead I disallow both of these with ERROR_INVALID_PARAMETER.
|
||||
*/
|
||||
if (!pszFuncName || !pszOID || !pwszDll)
|
||||
if (!pszFuncName || !pszOID)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return FALSE;
|
||||
@ -309,6 +313,89 @@ BOOL WINAPI CryptEncodeObject(DWORD dwCertEncodingType, LPCSTR lpszStructType,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BOOL CRYPT_EncodeInt(DWORD dwCertEncodingType, const void *pvStructInfo,
|
||||
DWORD dwFlags, PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded,
|
||||
DWORD *pcbEncoded)
|
||||
{
|
||||
INT val, i;
|
||||
BYTE significantBytes, padByte = 0, bytesNeeded;
|
||||
BOOL neg = FALSE, pad = FALSE;
|
||||
|
||||
if ((dwCertEncodingType & CERT_ENCODING_TYPE_MASK) != X509_ASN_ENCODING &&
|
||||
(dwCertEncodingType & CMSG_ENCODING_TYPE_MASK) != PKCS_7_ASN_ENCODING)
|
||||
{
|
||||
SetLastError(ERROR_FILE_NOT_FOUND);
|
||||
return FALSE;
|
||||
}
|
||||
if (!pvStructInfo)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
memcpy(&val, pvStructInfo, sizeof(val));
|
||||
/* Count the number of significant bytes. Temporarily swap sign for
|
||||
* negatives so I count the minimum number of bytes.
|
||||
*/
|
||||
if (val < 0)
|
||||
{
|
||||
neg = TRUE;
|
||||
val = -val;
|
||||
}
|
||||
for (significantBytes = sizeof(val); !(val & 0xff000000);
|
||||
val <<= 8, significantBytes--)
|
||||
;
|
||||
if (neg)
|
||||
{
|
||||
val = -val;
|
||||
if ((val & 0xff000000) < 0x80000000)
|
||||
{
|
||||
padByte = 0xff;
|
||||
pad = TRUE;
|
||||
}
|
||||
}
|
||||
else if ((val & 0xff000000) > 0x7f000000)
|
||||
{
|
||||
padByte = 0;
|
||||
pad = TRUE;
|
||||
}
|
||||
bytesNeeded = 2 + significantBytes;
|
||||
if (pad)
|
||||
bytesNeeded++;
|
||||
if (!pbEncoded || bytesNeeded > *pcbEncoded)
|
||||
{
|
||||
*pcbEncoded = bytesNeeded;
|
||||
SetLastError(ERROR_MORE_DATA);
|
||||
return FALSE;
|
||||
}
|
||||
if (!pbEncoded)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return FALSE;
|
||||
}
|
||||
if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
|
||||
{
|
||||
if (pEncodePara && pEncodePara->pfnAlloc)
|
||||
*(BYTE **)pbEncoded = pEncodePara->pfnAlloc(bytesNeeded);
|
||||
else
|
||||
*(BYTE **)pbEncoded = LocalAlloc(0, bytesNeeded);
|
||||
if (!*(BYTE **)pbEncoded)
|
||||
return FALSE;
|
||||
pbEncoded = *(BYTE **)pbEncoded;
|
||||
}
|
||||
*pbEncoded++ = ASN_INTEGER;
|
||||
if (pad)
|
||||
{
|
||||
*pbEncoded++ = significantBytes + 1;
|
||||
*pbEncoded++ = padByte;
|
||||
}
|
||||
else
|
||||
*pbEncoded++ = significantBytes;
|
||||
for (i = 0; i < significantBytes; i++, val <<= 8)
|
||||
*(pbEncoded + i) = (BYTE)((val & 0xff000000) >> 24);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
typedef BOOL (WINAPI *CryptEncodeObjectExFunc)(DWORD, LPCSTR, const void *,
|
||||
DWORD, PCRYPT_ENCODE_PARA, BYTE *, DWORD *);
|
||||
|
||||
@ -318,7 +405,7 @@ BOOL WINAPI CryptEncodeObjectEx(DWORD dwCertEncodingType, LPCSTR lpszStructType,
|
||||
{
|
||||
BOOL ret = FALSE, encoded = FALSE;
|
||||
|
||||
FIXME("(0x%08lx, %s, %p, 0x%08lx, %p, %p, %p): stub\n",
|
||||
TRACE("(0x%08lx, %s, %p, 0x%08lx, %p, %p, %p): semi-stub\n",
|
||||
dwCertEncodingType, HIWORD(lpszStructType) ? debugstr_a(lpszStructType) :
|
||||
"(integer value)", pvStructInfo, dwFlags, pEncodePara, pbEncoded,
|
||||
pcbEncoded);
|
||||
@ -333,6 +420,10 @@ BOOL WINAPI CryptEncodeObjectEx(DWORD dwCertEncodingType, LPCSTR lpszStructType,
|
||||
{
|
||||
switch (LOWORD(lpszStructType))
|
||||
{
|
||||
case (WORD)X509_INTEGER:
|
||||
ret = CRYPT_EncodeInt(dwCertEncodingType, pvStructInfo, dwFlags,
|
||||
pEncodePara, pbEncoded, pcbEncoded);
|
||||
break;
|
||||
default:
|
||||
FIXME("%d: unimplemented\n", LOWORD(lpszStructType));
|
||||
}
|
||||
|
@ -1,3 +1,4 @@
|
||||
Makefile
|
||||
encode.ok
|
||||
protectdata.ok
|
||||
testlist.c
|
||||
|
@ -6,6 +6,7 @@ TESTDLL = crypt32.dll
|
||||
IMPORTS = crypt32
|
||||
|
||||
CTESTS = \
|
||||
encode.c \
|
||||
protectdata.c
|
||||
|
||||
@MAKE_TEST_RULES@
|
||||
|
144
dlls/crypt32/tests/encode.c
Normal file
144
dlls/crypt32/tests/encode.c
Normal file
@ -0,0 +1,144 @@
|
||||
/*
|
||||
* Unit test suite for crypt32.dll's CryptEncodeObjectEx
|
||||
*
|
||||
* Copyright 2005 Juan Lang
|
||||
*
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <windef.h>
|
||||
#include <winbase.h>
|
||||
#include <winerror.h>
|
||||
#include <wincrypt.h>
|
||||
|
||||
#include "wine/test.h"
|
||||
|
||||
struct encodedInt
|
||||
{
|
||||
int val;
|
||||
BYTE encoded[6];
|
||||
};
|
||||
|
||||
static void test_encodeint(void)
|
||||
{
|
||||
static const struct encodedInt ints[] = {
|
||||
{ 1, { 2, 1, 1 } },
|
||||
{ 127, { 2, 1, 0x7f } },
|
||||
{ 128, { 2, 2, 0x00, 0x80 } },
|
||||
{ 256, { 2, 2, 0x01, 0x00 } },
|
||||
{ -128, { 2, 1, 0x80 } },
|
||||
{ -129, { 2, 2, 0xff, 0x7f } },
|
||||
{ 0xbaddf00d, { 2, 4, 0xba, 0xdd, 0xf0, 0x0d } },
|
||||
};
|
||||
DWORD bufSize = 0;
|
||||
int i;
|
||||
BOOL ret;
|
||||
|
||||
/* CryptEncodeObjectEx with NULL bufSize crashes..
|
||||
ret = CryptEncodeObjectEx(3, X509_INTEGER, &ints[0].val, 0, NULL, NULL,
|
||||
NULL);
|
||||
*/
|
||||
/* check bogus encoding */
|
||||
ret = CryptEncodeObjectEx(0, X509_INTEGER, &ints[0].val, 0, NULL, NULL,
|
||||
&bufSize);
|
||||
ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
|
||||
"Expected ERROR_FILE_NOT_FOUND, got %ld\n", GetLastError());
|
||||
/* check with NULL integer buffer. Windows XP incorrectly returns an
|
||||
* NTSTATUS.
|
||||
*/
|
||||
ret = CryptEncodeObjectEx(X509_ASN_ENCODING, X509_INTEGER, NULL, 0, NULL,
|
||||
NULL, &bufSize);
|
||||
ok(!ret && (GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() ==
|
||||
STATUS_ACCESS_VIOLATION), "Unexpected error code %ld\n", GetLastError());
|
||||
for (i = 0; i < sizeof(ints) / sizeof(ints[0]); i++)
|
||||
{
|
||||
BYTE *buf = NULL;
|
||||
|
||||
ret = CryptEncodeObjectEx(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
|
||||
X509_INTEGER, &ints[i].val, 0, NULL, NULL, &bufSize);
|
||||
ok(ret || GetLastError() == ERROR_MORE_DATA,
|
||||
"Expected success or ERROR_MORE_DATA, got %ld\n", GetLastError());
|
||||
ret = CryptEncodeObjectEx(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
|
||||
X509_INTEGER, &ints[i].val, CRYPT_ENCODE_ALLOC_FLAG, NULL,
|
||||
(BYTE *)&buf, &bufSize);
|
||||
ok(ret, "CryptEncodeObjectEx failed: %ld\n", GetLastError());
|
||||
ok(buf[0] == 2, "Got unexpected type %d for integer (expected 2)\n",
|
||||
buf[0]);
|
||||
ok(!memcmp(buf + 1, ints[i].encoded + 1, ints[i].encoded[1] + 1),
|
||||
"Encoded value of 0x%08x didn't match expected\n", ints[i].val);
|
||||
LocalFree(buf);
|
||||
}
|
||||
}
|
||||
|
||||
static void test_registerOIDFunction(void)
|
||||
{
|
||||
static const WCHAR bogusDll[] = { 'b','o','g','u','s','.','d','l','l',0 };
|
||||
BOOL ret;
|
||||
|
||||
/* oddly, this succeeds under WinXP; the function name key is merely
|
||||
* omitted. This may be a side effect of the registry code, I don't know.
|
||||
* I don't check it because I doubt anyone would depend on it.
|
||||
ret = CryptRegisterOIDFunction(X509_ASN_ENCODING, NULL,
|
||||
"1.2.3.4.5.6.7.8.9.10", bogusDll, NULL);
|
||||
*/
|
||||
/* On windows XP, GetLastError is incorrectly being set with an HRESULT,
|
||||
* HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER)
|
||||
*/
|
||||
ret = CryptRegisterOIDFunction(X509_ASN_ENCODING, "foo", NULL, bogusDll,
|
||||
NULL);
|
||||
ok(!ret && (GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() ==
|
||||
HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER)),
|
||||
"Expected ERROR_INVALID_PARAMETER: %ld\n", GetLastError());
|
||||
/* This has no effect, but "succeeds" on XP */
|
||||
ret = CryptRegisterOIDFunction(X509_ASN_ENCODING, "foo",
|
||||
"1.2.3.4.5.6.7.8.9.10", NULL, NULL);
|
||||
ok(ret, "Expected pseudo-success, got %ld\n", GetLastError());
|
||||
ret = CryptRegisterOIDFunction(X509_ASN_ENCODING, "CryptDllEncodeObject",
|
||||
"1.2.3.4.5.6.7.8.9.10", bogusDll, NULL);
|
||||
ok(ret, "CryptRegisterOIDFunction failed: %ld\n", GetLastError());
|
||||
ret = CryptUnregisterOIDFunction(X509_ASN_ENCODING, "CryptDllEncodeObject",
|
||||
"1.2.3.4.5.6.7.8.9.10");
|
||||
ok(ret, "CryptUnregisterOIDFunction failed: %ld\n", GetLastError());
|
||||
ret = CryptRegisterOIDFunction(X509_ASN_ENCODING, "bogus",
|
||||
"1.2.3.4.5.6.7.8.9.10", bogusDll, NULL);
|
||||
ok(ret, "CryptRegisterOIDFunction failed: %ld\n", GetLastError());
|
||||
ret = CryptUnregisterOIDFunction(X509_ASN_ENCODING, "bogus",
|
||||
"1.2.3.4.5.6.7.8.9.10");
|
||||
ok(ret, "CryptUnregisterOIDFunction failed: %ld\n", GetLastError());
|
||||
/* This has no effect */
|
||||
ret = CryptRegisterOIDFunction(PKCS_7_ASN_ENCODING, "CryptDllEncodeObject",
|
||||
"1.2.3.4.5.6.7.8.9.10", bogusDll, NULL);
|
||||
ok(ret, "CryptRegisterOIDFunction failed: %ld\n", GetLastError());
|
||||
/* Check with bogus encoding type: */
|
||||
ret = CryptRegisterOIDFunction(0, "CryptDllEncodeObject",
|
||||
"1.2.3.4.5.6.7.8.9.10", bogusDll, NULL);
|
||||
ok(ret, "CryptRegisterOIDFunction failed: %ld\n", GetLastError());
|
||||
/* This is written with value 3 verbatim. Thus, the encoding type isn't
|
||||
* (for now) treated as a mask.
|
||||
*/
|
||||
ret = CryptRegisterOIDFunction(3, "CryptDllEncodeObject",
|
||||
"1.2.3.4.5.6.7.8.9.10", bogusDll, NULL);
|
||||
ok(ret, "CryptRegisterOIDFunction failed: %ld\n", GetLastError());
|
||||
ret = CryptUnregisterOIDFunction(3, "CryptDllEncodeObject",
|
||||
"1.2.3.4.5.6.7.8.9.10");
|
||||
ok(ret, "CryptUnregisterOIDFunction failed: %ld\n", GetLastError());
|
||||
}
|
||||
|
||||
START_TEST(encode)
|
||||
{
|
||||
test_encodeint();
|
||||
test_registerOIDFunction();
|
||||
}
|
@ -1437,7 +1437,6 @@ BOOL WINAPI CryptHashSessionKey (HCRYPTHASH hHash, HCRYPTKEY hKey, DWORD dwFlags
|
||||
BOOL WINAPI CryptImportKey (HCRYPTPROV hProv, BYTE *pbData, DWORD dwDataLen,
|
||||
HCRYPTKEY hPubKey, DWORD dwFlags, HCRYPTKEY *phKey);
|
||||
BOOL WINAPI CryptRegisterOIDFunction(DWORD,LPCSTR,LPCSTR,LPCWSTR,LPCSTR);
|
||||
|
||||
BOOL WINAPI CryptReleaseContext (HCRYPTPROV hProv, DWORD dwFlags);
|
||||
BOOL WINAPI CryptSignHashA (HCRYPTHASH hHash, DWORD dwKeySpec, LPCSTR sDescription,
|
||||
DWORD dwFlags, BYTE *pbSignature, DWORD *pdwSigLen);
|
||||
@ -1453,6 +1452,7 @@ BOOL WINAPI CryptSetProviderExA (LPCSTR pszProvName, DWORD dwProvType, DWORD *pd
|
||||
BOOL WINAPI CryptSetProviderExW (LPCWSTR pszProvName, DWORD dwProvType, DWORD *pdwReserved, DWORD dwFlags);
|
||||
#define CryptSetProviderEx WINELIB_NAME_AW(CryptSetProviderEx)
|
||||
BOOL WINAPI CryptSetProvParam (HCRYPTPROV hProv, DWORD dwParam, BYTE *pbData, DWORD dwFlags);
|
||||
BOOL WINAPI CryptUnregisterOIDFunction(DWORD,LPCSTR,LPCSTR);
|
||||
BOOL WINAPI CryptVerifySignatureA (HCRYPTHASH hHash, BYTE *pbSignature, DWORD dwSigLen,
|
||||
HCRYPTKEY hPubKey, LPCSTR sDescription, DWORD dwFlags);
|
||||
BOOL WINAPI CryptVerifySignatureW (HCRYPTHASH hHash, BYTE *pbSignature, DWORD dwSigLen,
|
||||
|
Loading…
Reference in New Issue
Block a user