Implemented a substantial part of rsaenh.dll.
This commit is contained in:
parent
8ce698e2a4
commit
64dce8a579
|
@ -1174,6 +1174,11 @@ AC_CHECK_HEADERS(\
|
|||
netinet/in_systm.h \
|
||||
netinet/tcp.h \
|
||||
netinet/tcp_fsm.h \
|
||||
openssl/des.h \
|
||||
openssl/md2.h \
|
||||
openssl/rc2.h \
|
||||
openssl/rc4.h \
|
||||
openssl/rsa.h \
|
||||
openssl/ssl.h \
|
||||
process.h \
|
||||
pthread.h \
|
||||
|
@ -1686,6 +1691,8 @@ dlls/rpcrt4/Makefile
|
|||
dlls/rpcrt4/tests/Makefile
|
||||
dlls/rsabase/Makefile
|
||||
dlls/rsabase/tests/Makefile
|
||||
dlls/rsaenh/Makefile
|
||||
dlls/rsaenh/tests/Makefile
|
||||
dlls/secur32/Makefile
|
||||
dlls/serialui/Makefile
|
||||
dlls/setupapi/Makefile
|
||||
|
|
|
@ -110,6 +110,7 @@ BASEDIRS = \
|
|||
richedit \
|
||||
rpcrt4 \
|
||||
rsabase \
|
||||
rsaenh \
|
||||
secur32 \
|
||||
serialui \
|
||||
setupapi \
|
||||
|
@ -348,6 +349,7 @@ SYMLINKS_SO = \
|
|||
riched32.dll.so \
|
||||
rpcrt4.dll.so \
|
||||
rsabase.dll.so \
|
||||
rsaenh.dll.so \
|
||||
secur32.dll.so \
|
||||
serialui.dll.so \
|
||||
setupapi.dll.so \
|
||||
|
@ -777,6 +779,9 @@ rpcrt4.dll.so: rpcrt4/rpcrt4.dll.so
|
|||
rsabase.dll.so: rsabase/rsabase.dll.so
|
||||
$(RM) $@ && $(LN_S) rsabase/rsabase.dll.so $@
|
||||
|
||||
rsaenh.dll.so: rsaenh/rsaenh.dll.so
|
||||
$(RM) $@ && $(LN_S) rsaenh/rsaenh.dll.so $@
|
||||
|
||||
secur32.dll.so: secur32/secur32.dll.so
|
||||
$(RM) $@ && $(LN_S) secur32/secur32.dll.so $@
|
||||
|
||||
|
@ -1069,6 +1074,7 @@ IMPORT_LIBS = \
|
|||
libriched32.$(IMPLIBEXT) \
|
||||
librpcrt4.$(IMPLIBEXT) \
|
||||
librsabase.$(IMPLIBEXT) \
|
||||
librsaenh.$(IMPLIBEXT) \
|
||||
libsecur32.$(IMPLIBEXT) \
|
||||
libserialui.$(IMPLIBEXT) \
|
||||
libsetupapi.$(IMPLIBEXT) \
|
||||
|
@ -1571,6 +1577,11 @@ librsabase.def: rsabase/rsabase.spec.def
|
|||
librsabase.a: rsabase/rsabase.spec.def
|
||||
$(DLLTOOL) -k -l $@ -d rsabase/rsabase.spec.def
|
||||
|
||||
librsaenh.def: rsaenh/rsaenh.spec.def
|
||||
$(RM) $@ && $(LN_S) rsaenh/rsaenh.spec.def $@
|
||||
librsaenh.a: rsaenh/rsaenh.spec.def
|
||||
$(DLLTOOL) -k -l $@ -d rsaenh/rsaenh.spec.def
|
||||
|
||||
libsecur32.def: secur32/secur32.spec.def
|
||||
$(RM) $@ && $(LN_S) secur32/secur32.spec.def $@
|
||||
libsecur32.a: secur32/secur32.spec.def
|
||||
|
@ -1833,6 +1844,7 @@ rasapi32/rasapi32.spec.def: $(WINEBUILD)
|
|||
richedit/riched32.spec.def: $(WINEBUILD)
|
||||
rpcrt4/rpcrt4.spec.def: $(WINEBUILD)
|
||||
rsabase/rsabase.spec.def: $(WINEBUILD)
|
||||
rsaenh/rsaenh.spec.def: $(WINEBUILD)
|
||||
secur32/secur32.spec.def: $(WINEBUILD)
|
||||
serialui/serialui.spec.def: $(WINEBUILD)
|
||||
setupapi/setupapi.spec.def: $(WINEBUILD)
|
||||
|
@ -1981,6 +1993,7 @@ rasapi32/rasapi32.dll.so: rasapi32
|
|||
richedit/riched32.dll.so: richedit
|
||||
rpcrt4/rpcrt4.dll.so: rpcrt4
|
||||
rsabase/rsabase.dll.so: rsabase
|
||||
rsaenh/rsaenh.dll.so: rsaenh
|
||||
secur32/secur32.dll.so: secur32
|
||||
serialui/serialui.dll.so: serialui
|
||||
setupapi/setupapi.dll.so: setupapi
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
Makefile
|
||||
rsaenh.dll.dbg.c
|
||||
rsaenh.spec.def
|
|
@ -0,0 +1,18 @@
|
|||
EXTRADEFS = -DCOM_NO_WINDOWS_H
|
||||
TOPSRCDIR = @top_srcdir@
|
||||
TOPOBJDIR = ../..
|
||||
SRCDIR = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
MODULE = rsaenh.dll
|
||||
IMPORTS = advapi32 kernel32
|
||||
|
||||
C_SRCS = \
|
||||
handle.c \
|
||||
implossl.c \
|
||||
rsaenh.c
|
||||
|
||||
SUBDIRS = tests
|
||||
|
||||
@MAKE_DLL_RULES@
|
||||
|
||||
### Dependencies:
|
|
@ -0,0 +1,454 @@
|
|||
/*
|
||||
* dlls/rsaenh/handle.c
|
||||
* Support code to manage HANDLE tables.
|
||||
*
|
||||
* Copyright 1998 Alexandre Julliard
|
||||
* Copyright 2002-2004 Mike McCormack for CodeWeavers
|
||||
* Copyright 2004 Michael Jung
|
||||
*
|
||||
* 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 <string.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "handle.h"
|
||||
|
||||
#include "wine/debug.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(handle);
|
||||
|
||||
#define HANDLE2INDEX(h) ((h)-1)
|
||||
#define INDEX2HANDLE(i) ((i)+1)
|
||||
|
||||
/******************************************************************************
|
||||
* init_handle_table
|
||||
*
|
||||
* Initializes the HANDLETABLE structure pointed to by lpTable
|
||||
*
|
||||
* PARAMS
|
||||
* lpTable [I] Pointer to the HANDLETABLE structure, which is to be initalized.
|
||||
*
|
||||
* NOTES
|
||||
* Note that alloc_handle_table calls init_handle_table on it's own, which
|
||||
* means that you only have to call init_handle_table, if you use a global
|
||||
* variable of type HANDLETABLE for your handle table. However, in this
|
||||
* case you have to call destroy_handle_table when you don't need the table
|
||||
* any more.
|
||||
*/
|
||||
void init_handle_table(HANDLETABLE *lpTable)
|
||||
{
|
||||
TRACE("(lpTable=%p)\n", lpTable);
|
||||
|
||||
lpTable->paEntries = NULL;
|
||||
lpTable->iEntries = 0;
|
||||
lpTable->iFirstFree = 0;
|
||||
InitializeCriticalSection(&lpTable->mutex);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* destroy_handle_table
|
||||
*
|
||||
* Destroys the handle table.
|
||||
*
|
||||
* PARAMS
|
||||
* lpTable [I] Pointer to the handle table, which is to be destroyed.
|
||||
*
|
||||
* NOTES
|
||||
* Note that release_handle_table takes care of this.
|
||||
*/
|
||||
void destroy_handle_table(HANDLETABLE *lpTable)
|
||||
{
|
||||
TRACE("(lpTable=%p)\n", lpTable);
|
||||
|
||||
if (lpTable->paEntries)
|
||||
HeapFree(GetProcessHeap(), 0, lpTable->paEntries);
|
||||
DeleteCriticalSection(&lpTable->mutex);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* is_valid_handle
|
||||
*
|
||||
* Tests if handle is valid given the specified handle table
|
||||
*
|
||||
* PARAMS
|
||||
* lpTable [I] Pointer to the handle table, with respect to which the handle's
|
||||
* validness is tested.
|
||||
* handle [I] The handle tested for validness.
|
||||
* dwType [I] A magic value that identifies the referenced object's type.
|
||||
*
|
||||
* RETURNS
|
||||
* non zero, if handle is valid.
|
||||
* zero, if handle is not valid.
|
||||
*/
|
||||
int is_valid_handle(HANDLETABLE *lpTable, unsigned int handle, DWORD dwType)
|
||||
{
|
||||
unsigned int index = HANDLE2INDEX(handle);
|
||||
int ret = 0;
|
||||
|
||||
TRACE("(lpTable=%p, handle=%d)\n", lpTable, handle);
|
||||
|
||||
EnterCriticalSection(&lpTable->mutex);
|
||||
|
||||
/* We don't use zero handle values */
|
||||
if (!handle) goto exit;
|
||||
|
||||
/* Check for index out of table bounds */
|
||||
if (index >= lpTable->iEntries) goto exit;
|
||||
|
||||
/* Check if this handle is currently allocated */
|
||||
if (!lpTable->paEntries[index].pObject) goto exit;
|
||||
|
||||
/* Check if this handle references an object of the correct type. */
|
||||
if (lpTable->paEntries[index].pObject->dwType != dwType) goto exit;
|
||||
|
||||
ret = 1;
|
||||
exit:
|
||||
LeaveCriticalSection(&lpTable->mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* alloc_handle_table
|
||||
*
|
||||
* Allocates a new handle table
|
||||
*
|
||||
* PARAMS
|
||||
* lplpTable [O] Pointer to the variable, to which the pointer to the newly
|
||||
* allocated handle table is written.
|
||||
* RETURNS
|
||||
* non zero, if successfull
|
||||
* zero, if not successfull (out of process heap memory)
|
||||
*
|
||||
* NOTES
|
||||
* If all you need is a single handle table, you may as well declare a global
|
||||
* variable of type HANDLETABLE and call init_handle_table on your own.
|
||||
*/
|
||||
int alloc_handle_table(HANDLETABLE **lplpTable)
|
||||
{
|
||||
TRACE("(lplpTable=%p)\n", lplpTable);
|
||||
|
||||
*lplpTable = HeapAlloc(GetProcessHeap(), 0, sizeof(HANDLETABLE));
|
||||
if (*lplpTable)
|
||||
{
|
||||
init_handle_table(*lplpTable);
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* release_handle_table
|
||||
*
|
||||
* Releases a handle table and frees the resources occupied by it.
|
||||
*
|
||||
* PARAMS
|
||||
* lpTable [I] Pointer to the handle table, which is to be released.
|
||||
*
|
||||
* RETURNS
|
||||
* non zero, if successfull
|
||||
* zero, if not successfull
|
||||
*
|
||||
* NOTES
|
||||
* All valid handles still in the table are released also.
|
||||
*/
|
||||
int release_handle_table(HANDLETABLE *lpTable)
|
||||
{
|
||||
TRACE("(lpTable=%p)\n", lpTable);
|
||||
|
||||
release_all_handles(lpTable);
|
||||
destroy_handle_table(lpTable);
|
||||
return (int)HeapFree(GetProcessHeap(), 0, lpTable);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* grow_handle_table [Internal]
|
||||
*
|
||||
* Grows the number of entries in the given table by TABLE_SIZE_INCREMENT
|
||||
*
|
||||
* PARAMS
|
||||
* lpTable [I] Pointer to the table, which is to be grown
|
||||
*
|
||||
* RETURNS
|
||||
* non zero, if successfull
|
||||
* zero, if not successfull (out of memory on process heap)
|
||||
*
|
||||
* NOTES
|
||||
* This is a support function for alloc_handle. Do not call!
|
||||
*/
|
||||
static int grow_handle_table(HANDLETABLE *lpTable)
|
||||
{
|
||||
HANDLETABLEENTRY *newEntries;
|
||||
unsigned int i, newIEntries;
|
||||
|
||||
newIEntries = lpTable->iEntries + TABLE_SIZE_INCREMENT;
|
||||
|
||||
newEntries = (HANDLETABLEENTRY*)HeapAlloc(GetProcessHeap(), 0,
|
||||
sizeof(HANDLETABLEENTRY)*newIEntries);
|
||||
if (!newEntries)
|
||||
return 0;
|
||||
|
||||
if (lpTable->paEntries)
|
||||
{
|
||||
memcpy(newEntries, lpTable->paEntries, sizeof(HANDLETABLEENTRY)*lpTable->iEntries);
|
||||
HeapFree(GetProcessHeap(), 0, lpTable->paEntries);
|
||||
}
|
||||
|
||||
for (i=lpTable->iEntries; i<newIEntries; i++)
|
||||
{
|
||||
newEntries[i].pObject = NULL;
|
||||
newEntries[i].iNextFree = i+1;
|
||||
}
|
||||
|
||||
lpTable->paEntries = newEntries;
|
||||
lpTable->iEntries = newIEntries;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* alloc_handle
|
||||
*
|
||||
* Allocates a new handle to the specified object in a given handle table.
|
||||
*
|
||||
* PARAMS
|
||||
* lpTable [I] Pointer to the handle table, from which the new handle is
|
||||
* allocated.
|
||||
* lpObject [I] Pointer to the object, for which a handle shall be allocated.
|
||||
* lpHandle [O] Pointer to a handle variable, into which the handle value will
|
||||
* be stored. If not successfull, this will be
|
||||
* INVALID_HANDLE_VALUE
|
||||
* RETURNS
|
||||
* non zero, if successfull
|
||||
* zero, if not successfull (no free handle)
|
||||
*/
|
||||
int alloc_handle(HANDLETABLE *lpTable, OBJECTHDR *lpObject, unsigned int *lpHandle)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
TRACE("(lpTable=%p, lpObject=%p, lpHandle=%p)\n", lpTable, lpObject, lpHandle);
|
||||
|
||||
EnterCriticalSection(&lpTable->mutex);
|
||||
if (lpTable->iFirstFree >= lpTable->iEntries)
|
||||
if (!grow_handle_table(lpTable))
|
||||
{
|
||||
*lpHandle = (unsigned int)INVALID_HANDLE_VALUE;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
*lpHandle = INDEX2HANDLE(lpTable->iFirstFree);
|
||||
|
||||
lpTable->paEntries[lpTable->iFirstFree].pObject = lpObject;
|
||||
lpTable->iFirstFree = lpTable->paEntries[lpTable->iFirstFree].iNextFree;
|
||||
lpObject->refcount++;
|
||||
|
||||
ret = 1;
|
||||
exit:
|
||||
LeaveCriticalSection(&lpTable->mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* release_handle
|
||||
*
|
||||
* Releases resources occupied by the specified handle in the given table.
|
||||
* The reference count of the handled object is decremented. If it becomes
|
||||
* zero and if the 'destructor' function pointer member is non NULL, the
|
||||
* destructor function will be called. Note that release_handle does not
|
||||
* release resources other than the handle itself. If this is wanted, do it
|
||||
* in the destructor function.
|
||||
*
|
||||
* PARAMS
|
||||
* lpTable [I] Pointer to the handle table, from which a handle is to be
|
||||
* released.
|
||||
* handle [I] The handle, which is to be released
|
||||
* dwType [I] Identifier for the type of the object, for which a handle is
|
||||
* to be released.
|
||||
*
|
||||
* RETURNS
|
||||
* non zero, if successfull
|
||||
* zero, if not successfull (invalid handle)
|
||||
*/
|
||||
int release_handle(HANDLETABLE *lpTable, unsigned int handle, DWORD dwType)
|
||||
{
|
||||
unsigned int index = HANDLE2INDEX(handle);
|
||||
OBJECTHDR *pObject;
|
||||
int ret = 0;
|
||||
|
||||
TRACE("(lpTable=%p, hande=%d)\n", lpTable, handle);
|
||||
|
||||
EnterCriticalSection(&lpTable->mutex);
|
||||
|
||||
if (!is_valid_handle(lpTable, handle, dwType))
|
||||
goto exit;
|
||||
|
||||
pObject = lpTable->paEntries[index].pObject;
|
||||
pObject->refcount--;
|
||||
if (pObject->refcount == 0)
|
||||
if (pObject->destructor)
|
||||
pObject->destructor(pObject);
|
||||
|
||||
lpTable->paEntries[index].pObject = NULL;
|
||||
lpTable->paEntries[index].iNextFree = lpTable->iFirstFree;
|
||||
lpTable->iFirstFree = index;
|
||||
|
||||
ret = 1;
|
||||
exit:
|
||||
LeaveCriticalSection(&lpTable->mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* release_all_handles
|
||||
*
|
||||
* Releases all valid handles in the given handle table and shrinks the table
|
||||
* to zero size.
|
||||
*
|
||||
* PARAMS
|
||||
* lpTable [I] The table of which all valid handles shall be released.
|
||||
*/
|
||||
void release_all_handles(HANDLETABLE *lpTable)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
TRACE("(lpTable=%p)\n", lpTable);
|
||||
|
||||
EnterCriticalSection(&lpTable->mutex);
|
||||
for (i=0; i<lpTable->iEntries; i++)
|
||||
if (lpTable->paEntries[i].pObject)
|
||||
release_handle(lpTable, lpTable->paEntries[i].pObject->dwType, INDEX2HANDLE(i));
|
||||
LeaveCriticalSection(&lpTable->mutex);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* lookup_handle
|
||||
*
|
||||
* Returns the object identified by the handle in the given handle table
|
||||
*
|
||||
* PARAMS
|
||||
* lpTable [I] Pointer to the handle table, in which the handle is looked up.
|
||||
* handle [I] The handle, which is to be looked up
|
||||
* lplpObject [O] Pointer to the variable, into which the pointer to the
|
||||
* object looked up is copied.
|
||||
* RETURNS
|
||||
* non zero, if successfull
|
||||
* zero, if not successfull (invalid handle)
|
||||
*/
|
||||
int lookup_handle(HANDLETABLE *lpTable, unsigned int handle, DWORD dwType, OBJECTHDR **lplpObject)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
TRACE("(lpTable=%p, handle=%d, lplpObject=%p)\n", lpTable, handle, lplpObject);
|
||||
|
||||
EnterCriticalSection(&lpTable->mutex);
|
||||
if (!is_valid_handle(lpTable, handle, dwType))
|
||||
{
|
||||
*lplpObject = NULL;
|
||||
goto exit;
|
||||
}
|
||||
*lplpObject = lpTable->paEntries[HANDLE2INDEX(handle)].pObject;
|
||||
|
||||
ret = 1;
|
||||
exit:
|
||||
LeaveCriticalSection(&lpTable->mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* copy_handle
|
||||
*
|
||||
* Copies a handle. Increments reference count in the object referenced by the
|
||||
* handle
|
||||
*
|
||||
* PARAMS
|
||||
* lpTable [I] Pointer to the handle table, which holds the handle to be copied.
|
||||
* handle [I] The handle to be copied.
|
||||
* copy [O] Pointer to a handle variable, where the copied handle is put.
|
||||
*
|
||||
* RETURNS
|
||||
* non zero, if successfull
|
||||
* zero, if not successfull (invalid handle or out of memory)
|
||||
*/
|
||||
int copy_handle(HANDLETABLE *lpTable, unsigned int handle, DWORD dwType, unsigned int *copy)
|
||||
{
|
||||
OBJECTHDR *pObject;
|
||||
int ret;
|
||||
|
||||
TRACE("(lpTable=%p, handle=%d, copy=%p)\n", lpTable, handle, copy);
|
||||
|
||||
EnterCriticalSection(&lpTable->mutex);
|
||||
if (!lookup_handle(lpTable, handle, dwType, &pObject))
|
||||
{
|
||||
*copy = (unsigned int)INVALID_HANDLE_VALUE;
|
||||
LeaveCriticalSection(&lpTable->mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = alloc_handle(lpTable, pObject, copy);
|
||||
LeaveCriticalSection(&lpTable->mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* new_object
|
||||
*
|
||||
* Allocates a new object of size cbSize on the current process's heap.
|
||||
* Initializes the object header using the destructor and dwType params.
|
||||
* Allocates a handle to the object in the handle table pointed to by lpTable.
|
||||
* Returns a pointer to the created object in ppObject.
|
||||
* Returns a handle to the created object.
|
||||
*
|
||||
* PARAMS
|
||||
* lpTable [I] Pointer to the handle table, from which a handle is to be
|
||||
* allocated.
|
||||
* cbSize [I] Size of the object to be allocated in bytes.
|
||||
* dwType [I] Object type; will be copied to the object header.
|
||||
* destructor [I] Function pointer to a destructor function. Will be called
|
||||
* once the object's reference count gets zero.
|
||||
* ppObject [O] Pointer to a pointer variable, where a pointer to the newly
|
||||
* created object will be stored. You may set this to NULL.
|
||||
*
|
||||
* RETURNS
|
||||
* INVALID_HANDLE_VALUE, if something went wrong.
|
||||
* a handle to the new object, if successfull.
|
||||
*/
|
||||
unsigned int new_object(HANDLETABLE *lpTable, size_t cbSize, DWORD dwType, DESTRUCTOR destructor,
|
||||
OBJECTHDR **ppObject)
|
||||
{
|
||||
OBJECTHDR *pObject;
|
||||
unsigned int hObject;
|
||||
|
||||
if (ppObject)
|
||||
*ppObject = NULL;
|
||||
|
||||
pObject = (OBJECTHDR*)HeapAlloc(GetProcessHeap(), 0, cbSize);
|
||||
if (!pObject)
|
||||
return (unsigned int)INVALID_HANDLE_VALUE;
|
||||
|
||||
pObject->dwType = dwType;
|
||||
pObject->refcount = 0;
|
||||
pObject->destructor = destructor;
|
||||
|
||||
if (!alloc_handle(lpTable, pObject, &hObject))
|
||||
HeapFree(GetProcessHeap(), 0, pObject);
|
||||
else
|
||||
if (ppObject)
|
||||
*ppObject = pObject;
|
||||
|
||||
return hObject;
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
* dlls/rsaenh/handle.h
|
||||
* Support code to manage HANDLE tables.
|
||||
*
|
||||
* Copyright 1998 Alexandre Julliard
|
||||
* Copyright 2002-2004 Mike McCormack for CodeWeavers
|
||||
* Copyright 2004 Michael Jung
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#ifndef __WINE_HANDLE_H
|
||||
#define __WINE_HANDLE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define TABLE_SIZE_INCREMENT 32
|
||||
|
||||
struct tagOBJECTHDR;
|
||||
typedef struct tagOBJECTHDR OBJECTHDR;
|
||||
typedef void (*DESTRUCTOR)(OBJECTHDR *object);
|
||||
struct tagOBJECTHDR
|
||||
{
|
||||
DWORD dwType;
|
||||
UINT refcount;
|
||||
DESTRUCTOR destructor;
|
||||
};
|
||||
|
||||
typedef struct tagHANDLETABLEENTRY
|
||||
{
|
||||
OBJECTHDR *pObject;
|
||||
unsigned int iNextFree;
|
||||
} HANDLETABLEENTRY;
|
||||
|
||||
typedef struct tagHANDLETABLE
|
||||
{
|
||||
unsigned int iEntries;
|
||||
unsigned int iFirstFree;
|
||||
HANDLETABLEENTRY *paEntries;
|
||||
CRITICAL_SECTION mutex;
|
||||
} HANDLETABLE;
|
||||
|
||||
int alloc_handle_table (HANDLETABLE **lplpTable);
|
||||
void init_handle_table (HANDLETABLE *lpTable);
|
||||
void release_all_handles (HANDLETABLE *lpTable);
|
||||
int release_handle_table(HANDLETABLE *lpTable);
|
||||
void destroy_handle_table(HANDLETABLE *lpTable);
|
||||
int alloc_handle (HANDLETABLE *lpTable, OBJECTHDR *lpObject, unsigned int *lpHandle);
|
||||
int release_handle (HANDLETABLE *lpTable, unsigned int handle, DWORD dwType);
|
||||
int copy_handle (HANDLETABLE *lpTable, unsigned int handle, DWORD dwType, unsigned int *copy);
|
||||
int lookup_handle (HANDLETABLE *lpTable, unsigned int handle, DWORD dwType, OBJECTHDR **lplpObject);
|
||||
int is_valid_handle (HANDLETABLE *lpTable, unsigned int handle, DWORD dwType);
|
||||
|
||||
unsigned int new_object (HANDLETABLE *lpTable, size_t cbSize, DWORD dwType, DESTRUCTOR destructor,
|
||||
OBJECTHDR **ppObject);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __WINE_HANDLE_H */
|
|
@ -0,0 +1,683 @@
|
|||
/*
|
||||
* dlls/rsaenh/implossl.c
|
||||
* Encapsulating the OpenSSL dependend parts of RSAENH
|
||||
*
|
||||
* Copyright (c) 2004 Michael Jung
|
||||
*
|
||||
* based on code by Mike McCormack and David Hammerton
|
||||
*
|
||||
* 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 "config.h"
|
||||
|
||||
#include "wine/port.h"
|
||||
#include "wine/library.h"
|
||||
#include "wine/debug.h"
|
||||
|
||||
#include "windef.h"
|
||||
#include "wincrypt.h"
|
||||
|
||||
#include "implossl.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(crypt);
|
||||
|
||||
#ifndef SONAME_LIBCRYPTO
|
||||
#define SONAME_LIBCRYPTO "libcrypto.so"
|
||||
#endif
|
||||
|
||||
static void *libcrypto;
|
||||
|
||||
#define MAKE_FUNCPTR(f) static typeof(f) * p##f
|
||||
|
||||
/* OpenSSL funtions that we use */
|
||||
#ifdef HAVE_OPENSSL_MD2_H
|
||||
MAKE_FUNCPTR(MD2_Init);
|
||||
MAKE_FUNCPTR(MD2_Update);
|
||||
MAKE_FUNCPTR(MD2_Final);
|
||||
#endif
|
||||
#ifdef HAVE_OPENSSL_RC2_H
|
||||
MAKE_FUNCPTR(RC2_set_key);
|
||||
MAKE_FUNCPTR(RC2_ecb_encrypt);
|
||||
#endif
|
||||
#ifdef HAVE_OPENSSL_RC4_H
|
||||
MAKE_FUNCPTR(RC4_set_key);
|
||||
MAKE_FUNCPTR(RC4);
|
||||
#endif
|
||||
#ifdef HAVE_OPENSSL_DES_H
|
||||
MAKE_FUNCPTR(DES_set_odd_parity);
|
||||
MAKE_FUNCPTR(DES_set_key_unchecked);
|
||||
MAKE_FUNCPTR(DES_ecb_encrypt);
|
||||
MAKE_FUNCPTR(DES_ecb3_encrypt);
|
||||
#endif
|
||||
#ifdef HAVE_OPENSSL_RSA_H
|
||||
MAKE_FUNCPTR(RSA_generate_key);
|
||||
MAKE_FUNCPTR(RSA_free);
|
||||
MAKE_FUNCPTR(RSA_size);
|
||||
MAKE_FUNCPTR(RSA_check_key);
|
||||
MAKE_FUNCPTR(RSA_public_encrypt);
|
||||
MAKE_FUNCPTR(RSA_private_encrypt);
|
||||
MAKE_FUNCPTR(RSAPrivateKey_dup);
|
||||
MAKE_FUNCPTR(BN_bn2bin);
|
||||
MAKE_FUNCPTR(BN_bin2bn);
|
||||
MAKE_FUNCPTR(BN_get_word);
|
||||
MAKE_FUNCPTR(BN_set_word);
|
||||
MAKE_FUNCPTR(BN_num_bits);
|
||||
#endif
|
||||
|
||||
/* Function prototypes copied from dlls/advapi32/crypt_md4.c */
|
||||
VOID WINAPI MD4Init( MD4_CTX *ctx );
|
||||
VOID WINAPI MD4Update( MD4_CTX *ctx, const unsigned char *buf, unsigned int len );
|
||||
VOID WINAPI MD4Final( MD4_CTX *ctx );
|
||||
/* Function prototypes copied from dlls/advapi32/crypt_md5.c */
|
||||
VOID WINAPI MD5Init( MD5_CTX *ctx );
|
||||
VOID WINAPI MD5Update( MD5_CTX *ctx, const unsigned char *buf, unsigned int len );
|
||||
VOID WINAPI MD5Final( MD5_CTX *ctx );
|
||||
/* Function prototypes copied from dlls/advapi32/crypt_sha.c */
|
||||
VOID WINAPI A_SHAInit(PSHA_CTX Context);
|
||||
VOID WINAPI A_SHAUpdate(PSHA_CTX Context, PCHAR Buffer, UINT BufferSize);
|
||||
VOID WINAPI A_SHAFinal(PSHA_CTX Context, PULONG Result);
|
||||
|
||||
|
||||
BOOL load_lib( void )
|
||||
{
|
||||
/* FIXME: Is this portable? */
|
||||
#if defined HAVE_OPENSSL_MD2_H || defined HAVE_OPENSSL_RC2_H || defined HAVE_OPENSSL_RC4_H || \
|
||||
defined HAVE_OPENSSL_DES_H || defined HAVE_OPENSSL_RSA_H
|
||||
libcrypto = wine_dlopen(SONAME_LIBCRYPTO, RTLD_NOW, NULL, 0);
|
||||
if (!libcrypto)
|
||||
{
|
||||
MESSAGE("Couldn't load %s, RSA encryption not available.\n", SONAME_LIBCRYPTO);
|
||||
MESSAGE("Install the openssl package if you're have problems.\n");
|
||||
SetLastError(NTE_PROVIDER_DLL_FAIL);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#define GETFUNC(x) p##x = wine_dlsym(libcrypto, #x, NULL, 0);
|
||||
|
||||
#ifdef HAVE_OPENSSL_MD2_H
|
||||
GETFUNC(MD2_Init);
|
||||
GETFUNC(MD2_Update);
|
||||
GETFUNC(MD2_Final);
|
||||
#endif
|
||||
#ifdef HAVE_OPENSSL_RC2_H
|
||||
GETFUNC(RC2_set_key);
|
||||
GETFUNC(RC2_ecb_encrypt);
|
||||
#endif
|
||||
#ifdef HAVE_OPENSSL_RC4_H
|
||||
GETFUNC(RC4_set_key);
|
||||
GETFUNC(RC4);
|
||||
#endif
|
||||
#ifdef HAVE_OPENSSL_DES_H
|
||||
GETFUNC(DES_set_odd_parity);
|
||||
GETFUNC(DES_set_key_unchecked);
|
||||
GETFUNC(DES_ecb_encrypt);
|
||||
GETFUNC(DES_ecb3_encrypt);
|
||||
#endif
|
||||
#ifdef HAVE_OPENSSL_RSA_H
|
||||
GETFUNC(RSA_generate_key);
|
||||
GETFUNC(RSA_free);
|
||||
GETFUNC(RSA_size);
|
||||
GETFUNC(RSA_check_key);
|
||||
GETFUNC(RSA_public_encrypt);
|
||||
GETFUNC(RSA_private_encrypt);
|
||||
GETFUNC(RSAPrivateKey_dup);
|
||||
GETFUNC(BN_bn2bin);
|
||||
GETFUNC(BN_bin2bn);
|
||||
GETFUNC(BN_get_word);
|
||||
GETFUNC(BN_set_word);
|
||||
GETFUNC(BN_num_bits);
|
||||
#endif
|
||||
|
||||
#endif /* ifdef have any openssl header */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL init_hash_impl(ALG_ID aiAlgid, HASH_CONTEXT *pHashContext)
|
||||
{
|
||||
switch (aiAlgid)
|
||||
{
|
||||
#ifdef HAVE_OPENSSL_MD2_H
|
||||
case CALG_MD2:
|
||||
if (!pMD2_Init)
|
||||
{
|
||||
SetLastError(NTE_PROVIDER_DLL_FAIL);
|
||||
return FALSE;
|
||||
}
|
||||
pMD2_Init(&pHashContext->md2);
|
||||
break;
|
||||
#endif
|
||||
case CALG_MD4:
|
||||
MD4Init(&pHashContext->md4);
|
||||
break;
|
||||
|
||||
case CALG_MD5:
|
||||
MD5Init(&pHashContext->md5);
|
||||
break;
|
||||
|
||||
case CALG_SHA:
|
||||
A_SHAInit(&pHashContext->sha);
|
||||
break;
|
||||
|
||||
default:
|
||||
SetLastError(NTE_BAD_ALGID);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL update_hash_impl(ALG_ID aiAlgid, HASH_CONTEXT *pHashContext, CONST BYTE *pbData,
|
||||
DWORD dwDataLen)
|
||||
{
|
||||
switch (aiAlgid)
|
||||
{
|
||||
#ifdef HAVE_OPENSSL_MD2_H
|
||||
case CALG_MD2:
|
||||
if (!pMD2_Update)
|
||||
{
|
||||
SetLastError(NTE_PROVIDER_DLL_FAIL);
|
||||
return FALSE;
|
||||
}
|
||||
pMD2_Update(&pHashContext->md2, pbData, dwDataLen);
|
||||
break;
|
||||
#endif
|
||||
case CALG_MD4:
|
||||
MD4Update(&pHashContext->md4, pbData, dwDataLen);
|
||||
break;
|
||||
|
||||
case CALG_MD5:
|
||||
MD5Update(&pHashContext->md5, pbData, dwDataLen);
|
||||
break;
|
||||
|
||||
case CALG_SHA:
|
||||
A_SHAUpdate(&pHashContext->sha, (PCHAR)pbData, dwDataLen);
|
||||
break;
|
||||
|
||||
default:
|
||||
SetLastError(NTE_BAD_ALGID);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL finalize_hash_impl(ALG_ID aiAlgid, HASH_CONTEXT *pHashContext, BYTE *pbHashValue)
|
||||
{
|
||||
switch (aiAlgid)
|
||||
{
|
||||
#ifdef HAVE_OPENSSL_MD2_H
|
||||
case CALG_MD2:
|
||||
if (!pMD2_Final)
|
||||
{
|
||||
SetLastError(NTE_PROVIDER_DLL_FAIL);
|
||||
return FALSE;
|
||||
}
|
||||
pMD2_Final(pbHashValue, &pHashContext->md2);
|
||||
break;
|
||||
#endif
|
||||
case CALG_MD4:
|
||||
MD4Final(&pHashContext->md4);
|
||||
memcpy(pbHashValue, pHashContext->md4.digest, 16);
|
||||
break;
|
||||
|
||||
case CALG_MD5:
|
||||
MD5Final(&pHashContext->md5);
|
||||
memcpy(pbHashValue, pHashContext->md5.digest, 16);
|
||||
break;
|
||||
|
||||
case CALG_SHA:
|
||||
A_SHAFinal(&pHashContext->sha, (PULONG)pbHashValue);
|
||||
break;
|
||||
|
||||
default:
|
||||
SetLastError(NTE_BAD_ALGID);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL duplicate_hash_impl(ALG_ID aiAlgid, CONST HASH_CONTEXT *pSrcHashContext,
|
||||
HASH_CONTEXT *pDestHashContext)
|
||||
{
|
||||
memcpy(pDestHashContext, pSrcHashContext, sizeof(HASH_CONTEXT));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL new_key_impl(ALG_ID aiAlgid, KEY_CONTEXT *pKeyContext, DWORD dwKeyLen)
|
||||
{
|
||||
switch (aiAlgid)
|
||||
{
|
||||
#ifdef HAVE_OPENSSL_RSA_H
|
||||
case CALG_RSA_KEYX:
|
||||
case CALG_RSA_SIGN:
|
||||
if (!pRSA_generate_key)
|
||||
{
|
||||
SetLastError(NTE_PROVIDER_DLL_FAIL);
|
||||
return FALSE;
|
||||
}
|
||||
pKeyContext->rsa = pRSA_generate_key((int)dwKeyLen*8, 65537, NULL, NULL);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
SetLastError(NTE_BAD_ALGID);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL free_key_impl(ALG_ID aiAlgid, KEY_CONTEXT *pKeyContext)
|
||||
{
|
||||
switch (aiAlgid)
|
||||
{
|
||||
#ifdef HAVE_OPENSSL_RSA_H
|
||||
case CALG_RSA_KEYX:
|
||||
case CALG_RSA_SIGN:
|
||||
if (!pRSA_free)
|
||||
{
|
||||
SetLastError(NTE_PROVIDER_DLL_FAIL);
|
||||
return FALSE;
|
||||
}
|
||||
if (pKeyContext->rsa) pRSA_free(pKeyContext->rsa);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
SetLastError(NTE_BAD_ALGID);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL setup_key_impl(ALG_ID aiAlgid, KEY_CONTEXT *pKeyContext, DWORD dwKeyLen, DWORD dwSaltLen,
|
||||
BYTE *abKeyValue)
|
||||
{
|
||||
switch (aiAlgid)
|
||||
{
|
||||
#ifdef HAVE_OPENSSL_RC4_H
|
||||
case CALG_RC4:
|
||||
if (!pRC4_set_key)
|
||||
{
|
||||
SetLastError(NTE_PROVIDER_DLL_FAIL);
|
||||
return FALSE;
|
||||
}
|
||||
pRC4_set_key(&pKeyContext->rc4, dwKeyLen + dwSaltLen, abKeyValue);
|
||||
break;
|
||||
#endif
|
||||
#ifdef HAVE_OPENSSL_RC2_H
|
||||
case CALG_RC2:
|
||||
if (!pRC2_set_key)
|
||||
{
|
||||
SetLastError(NTE_PROVIDER_DLL_FAIL);
|
||||
return FALSE;
|
||||
}
|
||||
pRC2_set_key(&pKeyContext->rc2, dwKeyLen + dwSaltLen, abKeyValue, dwKeyLen * 8);
|
||||
break;
|
||||
#endif
|
||||
#ifdef HAVE_OPENSSL_DES_H
|
||||
case CALG_3DES:
|
||||
if (!pDES_set_odd_parity || !pDES_set_key_unchecked)
|
||||
{
|
||||
SetLastError(NTE_PROVIDER_DLL_FAIL);
|
||||
return FALSE;
|
||||
}
|
||||
pDES_set_odd_parity(&((DES_cblock*)abKeyValue)[2]);
|
||||
pDES_set_key_unchecked(&((DES_cblock*)abKeyValue)[2], &pKeyContext->des[2]);
|
||||
|
||||
case CALG_3DES_112:
|
||||
if (!pDES_set_odd_parity || !pDES_set_key_unchecked)
|
||||
{
|
||||
SetLastError(NTE_PROVIDER_DLL_FAIL);
|
||||
return FALSE;
|
||||
}
|
||||
pDES_set_odd_parity(&((DES_cblock*)abKeyValue)[1]);
|
||||
pDES_set_key_unchecked(&((DES_cblock*)abKeyValue)[1], &pKeyContext->des[1]);
|
||||
|
||||
case CALG_DES:
|
||||
if (!pDES_set_odd_parity || !pDES_set_key_unchecked)
|
||||
{
|
||||
SetLastError(NTE_PROVIDER_DLL_FAIL);
|
||||
return FALSE;
|
||||
}
|
||||
pDES_set_odd_parity((DES_cblock*)abKeyValue);
|
||||
pDES_set_key_unchecked((DES_cblock*)abKeyValue, &pKeyContext->des[0]);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
SetLastError(NTE_BAD_ALGID);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL duplicate_key_impl(ALG_ID aiAlgid, CONST KEY_CONTEXT *pSrcKeyContext,
|
||||
KEY_CONTEXT *pDestKeyContext)
|
||||
{
|
||||
switch (aiAlgid)
|
||||
{
|
||||
case CALG_RC4:
|
||||
case CALG_RC2:
|
||||
case CALG_3DES:
|
||||
case CALG_3DES_112:
|
||||
case CALG_DES:
|
||||
memcpy(pDestKeyContext, pSrcKeyContext, sizeof(KEY_CONTEXT));
|
||||
break;
|
||||
#ifdef HAVE_OPENSSL_RSA_H
|
||||
case CALG_RSA_KEYX:
|
||||
case CALG_RSA_SIGN:
|
||||
if (!pRSAPrivateKey_dup)
|
||||
{
|
||||
SetLastError(NTE_PROVIDER_DLL_FAIL);
|
||||
return FALSE;
|
||||
}
|
||||
pDestKeyContext->rsa = pRSAPrivateKey_dup(pSrcKeyContext->rsa);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
SetLastError(NTE_BAD_ALGID);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#ifdef HAVE_OPENSSL_RSA_H
|
||||
static inline void reverse_bytes(BYTE *pbData, DWORD dwLen) {
|
||||
BYTE swap;
|
||||
DWORD i;
|
||||
|
||||
for (i=0; i<dwLen/2; i++) {
|
||||
swap = pbData[i];
|
||||
pbData[i] = pbData[dwLen-i-1];
|
||||
pbData[dwLen-i-1] = swap;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
BOOL encrypt_block_impl(ALG_ID aiAlgid, KEY_CONTEXT *pKeyContext, CONST BYTE *in, BYTE *out,
|
||||
DWORD enc)
|
||||
{
|
||||
#ifdef HAVE_OPENSSL_RSA_H
|
||||
int cLen;
|
||||
#endif
|
||||
|
||||
switch (aiAlgid) {
|
||||
#ifdef HAVE_OPENSSL_RC2_H
|
||||
case CALG_RC2:
|
||||
if (!pRC2_ecb_encrypt)
|
||||
{
|
||||
SetLastError(NTE_PROVIDER_DLL_FAIL);
|
||||
return FALSE;
|
||||
}
|
||||
pRC2_ecb_encrypt(in, out, &pKeyContext->rc2, enc ? RC2_ENCRYPT : RC2_DECRYPT);
|
||||
break;
|
||||
#endif
|
||||
#ifdef HAVE_OPENSSL_DES_H
|
||||
case CALG_DES:
|
||||
if (!pDES_ecb_encrypt)
|
||||
{
|
||||
SetLastError(NTE_PROVIDER_DLL_FAIL);
|
||||
return FALSE;
|
||||
}
|
||||
pDES_ecb_encrypt((const_DES_cblock*)in, (DES_cblock*)out, &pKeyContext->des[0],
|
||||
enc ? DES_ENCRYPT : DES_DECRYPT);
|
||||
break;
|
||||
|
||||
case CALG_3DES_112:
|
||||
if (!pDES_ecb3_encrypt)
|
||||
{
|
||||
SetLastError(NTE_PROVIDER_DLL_FAIL);
|
||||
return FALSE;
|
||||
}
|
||||
pDES_ecb3_encrypt((const_DES_cblock*)in, (DES_cblock*)out,
|
||||
&pKeyContext->des[0], &pKeyContext->des[1], &pKeyContext->des[0],
|
||||
enc ? DES_ENCRYPT : DES_DECRYPT);
|
||||
break;
|
||||
|
||||
case CALG_3DES:
|
||||
if (!pDES_ecb3_encrypt)
|
||||
{
|
||||
SetLastError(NTE_PROVIDER_DLL_FAIL);
|
||||
return FALSE;
|
||||
}
|
||||
pDES_ecb3_encrypt((const_DES_cblock*)in, (DES_cblock*)out,
|
||||
&pKeyContext->des[0], &pKeyContext->des[1], &pKeyContext->des[2],
|
||||
enc ? DES_ENCRYPT : DES_DECRYPT);
|
||||
break;
|
||||
#endif
|
||||
#ifdef HAVE_OPENSSL_RSA_H
|
||||
case CALG_RSA_KEYX:
|
||||
if (!pBN_num_bits || !pRSA_public_encrypt || !pRSA_private_encrypt)
|
||||
{
|
||||
SetLastError(NTE_PROVIDER_DLL_FAIL);
|
||||
return FALSE;
|
||||
}
|
||||
cLen = pBN_num_bits(pKeyContext->rsa->n)/8;
|
||||
if (enc) {
|
||||
pRSA_public_encrypt(cLen, in, out, pKeyContext->rsa, RSA_NO_PADDING);
|
||||
reverse_bytes((BYTE*)in, cLen);
|
||||
} else {
|
||||
reverse_bytes((BYTE*)in, cLen);
|
||||
pRSA_private_encrypt(cLen, in, out, pKeyContext->rsa, RSA_NO_PADDING);
|
||||
}
|
||||
break;
|
||||
|
||||
case CALG_RSA_SIGN:
|
||||
if (!pBN_num_bits || !pRSA_public_encrypt || !pRSA_private_encrypt)
|
||||
{
|
||||
SetLastError(NTE_PROVIDER_DLL_FAIL);
|
||||
return FALSE;
|
||||
}
|
||||
cLen = pBN_num_bits(pKeyContext->rsa->n)/8;
|
||||
if (enc) {
|
||||
pRSA_private_encrypt(cLen, in, out, pKeyContext->rsa, RSA_NO_PADDING);
|
||||
reverse_bytes((BYTE*)in, cLen);
|
||||
} else {
|
||||
reverse_bytes((BYTE*)in, cLen);
|
||||
pRSA_public_encrypt(cLen, in, out, pKeyContext->rsa, RSA_NO_PADDING);
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
SetLastError(NTE_BAD_ALGID);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL encrypt_stream_impl(ALG_ID aiAlgid, KEY_CONTEXT *pKeyContext, BYTE *stream, DWORD dwLen)
|
||||
{
|
||||
switch (aiAlgid) {
|
||||
#ifdef HAVE_OPENSSL_RC4_H
|
||||
case CALG_RC4:
|
||||
if (!pRC4)
|
||||
{
|
||||
SetLastError(NTE_PROVIDER_DLL_FAIL);
|
||||
return FALSE;
|
||||
}
|
||||
pRC4(&pKeyContext->rc4, (unsigned long)dwLen, stream, stream);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
SetLastError(NTE_BAD_ALGID);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL gen_rand_impl(BYTE *pbBuffer, DWORD dwLen)
|
||||
{
|
||||
FILE *dev_random;
|
||||
|
||||
/* FIXME: /dev/urandom does not provide random numbers of a sufficient
|
||||
* quality for cryptographic applications. /dev/random is much better,
|
||||
* but it blocks if the kernel has not yet collected enough entropy for
|
||||
* the request, which will suspend the calling thread for an indefinite
|
||||
* amount of time. */
|
||||
dev_random = fopen("/dev/urandom", "r");
|
||||
if (dev_random)
|
||||
{
|
||||
if (fread(pbBuffer, (size_t)dwLen, 1, dev_random) == 1)
|
||||
{
|
||||
fclose(dev_random);
|
||||
return TRUE;
|
||||
}
|
||||
fclose(dev_random);
|
||||
}
|
||||
SetLastError(NTE_FAIL);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL export_public_key_impl(BYTE *pbDest, KEY_CONTEXT *pKeyContext, DWORD dwKeyLen,DWORD *pdwPubExp)
|
||||
{
|
||||
#ifdef HAVE_OPENSSL_RSA_H
|
||||
if (!pBN_bn2bin || !pBN_get_word)
|
||||
{
|
||||
SetLastError(NTE_PROVIDER_DLL_FAIL);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
pBN_bn2bin(pKeyContext->rsa->n, pbDest);
|
||||
reverse_bytes(pbDest, dwKeyLen);
|
||||
*pdwPubExp = (DWORD)pBN_get_word(pKeyContext->rsa->e);
|
||||
|
||||
return TRUE;
|
||||
#else
|
||||
SetLastError(NTE_FAIL);
|
||||
return FALSE;
|
||||
#endif
|
||||
}
|
||||
|
||||
BOOL import_public_key_impl(CONST BYTE *pbSrc, KEY_CONTEXT *pKeyContext, DWORD dwKeyLen,
|
||||
DWORD dwPubExp)
|
||||
{
|
||||
#ifdef HAVE_OPENSSL_RSA_H
|
||||
BYTE *pbTemp;
|
||||
|
||||
if (!pBN_bin2bn || !pBN_set_word)
|
||||
{
|
||||
SetLastError(NTE_PROVIDER_DLL_FAIL);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
pbTemp = (BYTE*)HeapAlloc(GetProcessHeap(), 0, dwKeyLen);
|
||||
if (!pbTemp) return FALSE;
|
||||
memcpy(pbTemp, pbSrc, dwKeyLen);
|
||||
reverse_bytes(pbTemp, dwKeyLen);
|
||||
pBN_bin2bn(pbTemp, dwKeyLen, pKeyContext->rsa->n);
|
||||
HeapFree(GetProcessHeap(), 0, pbTemp);
|
||||
|
||||
pBN_set_word(pKeyContext->rsa->e, (BN_ULONG)dwPubExp);
|
||||
|
||||
return TRUE;
|
||||
#else
|
||||
SetLastError(NTE_FAIL);
|
||||
return FALSE;
|
||||
#endif
|
||||
}
|
||||
|
||||
BOOL export_private_key_impl(BYTE *pbDest, KEY_CONTEXT *pKeyContext, DWORD dwKeyLen,
|
||||
DWORD *pdwPubExp)
|
||||
{
|
||||
#ifdef HAVE_OPENSSL_RSA_H
|
||||
if (!pBN_bn2bin || !pBN_get_word)
|
||||
{
|
||||
SetLastError(NTE_PROVIDER_DLL_FAIL);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
pBN_bn2bin(pKeyContext->rsa->n, pbDest);
|
||||
reverse_bytes(pbDest, dwKeyLen);
|
||||
pbDest += dwKeyLen;
|
||||
pBN_bn2bin(pKeyContext->rsa->p, pbDest);
|
||||
reverse_bytes(pbDest, (dwKeyLen+1)>>1);
|
||||
pbDest += (dwKeyLen+1)>>1;
|
||||
pBN_bn2bin(pKeyContext->rsa->q, pbDest);
|
||||
reverse_bytes(pbDest, (dwKeyLen+1)>>1);
|
||||
pbDest += (dwKeyLen+1)>>1;
|
||||
pBN_bn2bin(pKeyContext->rsa->dmp1, pbDest);
|
||||
reverse_bytes(pbDest, (dwKeyLen+1)>>1);
|
||||
pbDest += (dwKeyLen+1)>>1;
|
||||
pBN_bn2bin(pKeyContext->rsa->dmq1, pbDest);
|
||||
reverse_bytes(pbDest, (dwKeyLen+1)>>1);
|
||||
pbDest += (dwKeyLen+1)>>1;
|
||||
pBN_bn2bin(pKeyContext->rsa->iqmp, pbDest);
|
||||
reverse_bytes(pbDest, (dwKeyLen+1)>>1);
|
||||
pbDest += (dwKeyLen+1)>>1;
|
||||
pBN_bn2bin(pKeyContext->rsa->d, pbDest);
|
||||
reverse_bytes(pbDest, dwKeyLen);
|
||||
*pdwPubExp = (DWORD)pBN_get_word(pKeyContext->rsa->e);
|
||||
|
||||
return TRUE;
|
||||
#else
|
||||
SetLastError(NTE_FAIL);
|
||||
return FALSE;
|
||||
#endif
|
||||
}
|
||||
|
||||
BOOL import_private_key_impl(CONST BYTE *pbSrc, KEY_CONTEXT *pKeyContext, DWORD dwKeyLen,
|
||||
DWORD dwPubExp)
|
||||
{
|
||||
#ifdef HAVE_OPENSSL_RSA_H
|
||||
BYTE *pbTemp, *pbBigNum;
|
||||
|
||||
if (!pBN_bin2bn || !pBN_set_word)
|
||||
{
|
||||
SetLastError(NTE_PROVIDER_DLL_FAIL);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
pbTemp = HeapAlloc(GetProcessHeap(), 0, 2*dwKeyLen+5*((dwKeyLen+1)>>1));
|
||||
if (!pbTemp) return FALSE;
|
||||
memcpy(pbTemp, pbSrc, 2*dwKeyLen+5*((dwKeyLen+1)>>1));
|
||||
pbBigNum = pbTemp;
|
||||
|
||||
reverse_bytes(pbBigNum, dwKeyLen);
|
||||
pBN_bin2bn(pbBigNum, dwKeyLen, pKeyContext->rsa->n);
|
||||
pbBigNum += dwKeyLen;
|
||||
reverse_bytes(pbBigNum, (dwKeyLen+1)>>1);
|
||||
pBN_bin2bn(pbBigNum, (dwKeyLen+1)>>1, pKeyContext->rsa->p);
|
||||
pbBigNum += (dwKeyLen+1)>>1;
|
||||
reverse_bytes(pbBigNum, (dwKeyLen+1)>>1);
|
||||
pBN_bin2bn(pbBigNum, (dwKeyLen+1)>>1, pKeyContext->rsa->q);
|
||||
pbBigNum += (dwKeyLen+1)>>1;
|
||||
reverse_bytes(pbBigNum, (dwKeyLen+1)>>1);
|
||||
pBN_bin2bn(pbBigNum, (dwKeyLen+1)>>1, pKeyContext->rsa->dmp1);
|
||||
pbBigNum += (dwKeyLen+1)>>1;
|
||||
reverse_bytes(pbBigNum, (dwKeyLen+1)>>1);
|
||||
pBN_bin2bn(pbBigNum, (dwKeyLen+1)>>1, pKeyContext->rsa->dmq1);
|
||||
pbBigNum += (dwKeyLen+1)>>1;
|
||||
reverse_bytes(pbBigNum, (dwKeyLen+1)>>1);
|
||||
pBN_bin2bn(pbBigNum, (dwKeyLen+1)>>1, pKeyContext->rsa->iqmp);
|
||||
pbBigNum += (dwKeyLen+1)>>1;
|
||||
reverse_bytes(pbBigNum, dwKeyLen);
|
||||
pBN_bin2bn(pbBigNum, dwKeyLen, pKeyContext->rsa->d);
|
||||
pBN_set_word(pKeyContext->rsa->e, (BN_ULONG)dwPubExp);
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, pbTemp);
|
||||
|
||||
return TRUE;
|
||||
#else
|
||||
SetLastError(NTE_FAIL);
|
||||
return FALSE;
|
||||
#endif
|
||||
}
|
|
@ -0,0 +1,129 @@
|
|||
/*
|
||||
* dlls/rsaenh/implossl.h
|
||||
* Encapsulating the OpenSSL dependend parts of RSABASE
|
||||
*
|
||||
* Copyright (c) 2004 Michael Jung
|
||||
*
|
||||
* based on code by Mike McCormack and David Hammerton
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#ifndef __WINE_IMPLOSSL_H
|
||||
#define __WINE_IMPLOSSL_H
|
||||
|
||||
#ifdef HAVE_OPENSSL_MD2_H
|
||||
#include <openssl/md2.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_OPENSSL_RC2_H
|
||||
#include <openssl/rc2.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_OPENSSL_RC4_H
|
||||
#include <openssl/rc4.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_OPENSSL_DES_H
|
||||
#include <openssl/des.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_OPENSSL_RSA_H
|
||||
#include <openssl/rsa.h>
|
||||
#endif
|
||||
|
||||
/* Next typedef copied from dlls/advapi32/crypt_md4.c */
|
||||
typedef struct tagMD4_CTX {
|
||||
unsigned int buf[4];
|
||||
unsigned int i[2];
|
||||
unsigned char in[64];
|
||||
unsigned char digest[16];
|
||||
} MD4_CTX;
|
||||
|
||||
/* Next typedef copied from dlls/advapi32/crypt_md5.c */
|
||||
typedef struct tagMD5_CTX
|
||||
{
|
||||
unsigned int i[2];
|
||||
unsigned int buf[4];
|
||||
unsigned char in[64];
|
||||
unsigned char digest[16];
|
||||
} MD5_CTX;
|
||||
|
||||
/* Next typedef copied form dlls/advapi32/crypt_sha.c */
|
||||
typedef struct tagSHA_CTX
|
||||
{
|
||||
ULONG Unknown[6];
|
||||
ULONG State[5];
|
||||
ULONG Count[2];
|
||||
UCHAR Buffer[64];
|
||||
} SHA_CTX, *PSHA_CTX;
|
||||
|
||||
typedef union tagHASH_CONTEXT {
|
||||
#ifdef HAVE_OPENSSL_MD2_H
|
||||
MD2_CTX md2;
|
||||
#endif
|
||||
MD4_CTX md4;
|
||||
MD5_CTX md5;
|
||||
SHA_CTX sha;
|
||||
} HASH_CONTEXT;
|
||||
|
||||
typedef union tagKEY_CONTEXT {
|
||||
#ifdef HAVE_OPENSSL_RC2_H
|
||||
RC2_KEY rc2;
|
||||
#endif
|
||||
#ifdef HAVE_OPENSSL_RC4_H
|
||||
RC4_KEY rc4;
|
||||
#endif
|
||||
#ifdef HAVE_OPENSSL_DES_H
|
||||
DES_key_schedule des[3];
|
||||
#endif
|
||||
#ifdef HAVE_OPENSSL_RSA_H
|
||||
RSA *rsa;
|
||||
#endif
|
||||
DWORD dwDummy;
|
||||
} KEY_CONTEXT;
|
||||
|
||||
BOOL load_lib(void);
|
||||
|
||||
BOOL init_hash_impl(ALG_ID aiAlgid, HASH_CONTEXT *pHashContext);
|
||||
BOOL update_hash_impl(ALG_ID aiAlgid, HASH_CONTEXT *pHashContext, CONST BYTE *pbData,
|
||||
DWORD dwDataLen);
|
||||
BOOL finalize_hash_impl(ALG_ID aiAlgid, HASH_CONTEXT *pHashContext, BYTE *pbHashValue);
|
||||
BOOL duplicate_hash_impl(ALG_ID aiAlgid, CONST HASH_CONTEXT *pSrcHashContext,
|
||||
HASH_CONTEXT *pDestHashContext);
|
||||
|
||||
BOOL new_key_impl(ALG_ID aiAlgid, KEY_CONTEXT *pKeyContext, DWORD dwKeyLen);
|
||||
BOOL free_key_impl(ALG_ID aiAlgid, KEY_CONTEXT *pKeyContext);
|
||||
BOOL setup_key_impl(ALG_ID aiAlgid, KEY_CONTEXT *pKeyContext, DWORD dwKeyLen, DWORD dwSaltLen,
|
||||
BYTE *abKeyValue);
|
||||
BOOL duplicate_key_impl(ALG_ID aiAlgid, CONST KEY_CONTEXT *pSrcKeyContext,
|
||||
KEY_CONTEXT *pDestKeyContext);
|
||||
|
||||
BOOL encrypt_block_impl(ALG_ID aiAlgid, KEY_CONTEXT *pKeyContext, CONST BYTE *pbIn, BYTE *pbOut,
|
||||
DWORD enc);
|
||||
BOOL encrypt_stream_impl(ALG_ID aiAlgid, KEY_CONTEXT *pKeyContext, BYTE *pbInOut, DWORD dwLen);
|
||||
|
||||
BOOL export_public_key_impl(BYTE *pbDest, KEY_CONTEXT *pKeyContext, DWORD dwKeyLen,
|
||||
DWORD *pdwPubExp);
|
||||
BOOL import_public_key_impl(CONST BYTE *pbSrc, KEY_CONTEXT *pKeyContext, DWORD dwKeyLen,
|
||||
DWORD dwPubExp);
|
||||
BOOL export_private_key_impl(BYTE *pbDest, KEY_CONTEXT *pKeyContext, DWORD dwKeyLen,
|
||||
DWORD *pdwPubExp);
|
||||
BOOL import_private_key_impl(CONST BYTE* pbSrc, KEY_CONTEXT *pKeyContext, DWORD dwKeyLen,
|
||||
DWORD dwPubExp);
|
||||
|
||||
BOOL gen_rand_impl(BYTE *pbBuffer, DWORD dwLen);
|
||||
|
||||
#endif /* __WINE_IMPLOSSL_H */
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,27 @@
|
|||
@ stdcall CPAcquireContext(ptr str long ptr) RSAENH_CPAcquireContext
|
||||
@ stdcall CPCreateHash(long long ptr long ptr) RSAENH_CPCreateHash
|
||||
@ stdcall CPDecrypt(long long long long long ptr ptr) RSAENH_CPDecrypt
|
||||
@ stdcall CPDeriveKey(long long long long ptr) RSAENH_CPDeriveKey
|
||||
@ stdcall CPDestroyHash(long long) RSAENH_CPDestroyHash
|
||||
@ stdcall CPDestroyKey(long long) RSAENH_CPDestroyKey
|
||||
@ stdcall CPDuplicateHash(long long ptr long ptr) RSAENH_CPDuplicateHash
|
||||
@ stdcall CPDuplicateKey(long long ptr long ptr) RSAENH_CPDuplicateKey
|
||||
@ stdcall CPEncrypt(long long long long long ptr ptr long) RSAENH_CPEncrypt
|
||||
@ stdcall CPExportKey(long long long long long ptr ptr) RSAENH_CPExportKey
|
||||
@ stdcall CPGenKey(long long long ptr) RSAENH_CPGenKey
|
||||
@ stdcall CPGenRandom(long long ptr) RSAENH_CPGenRandom
|
||||
@ stdcall CPGetHashParam(long long long ptr ptr long) RSAENH_CPGetHashParam
|
||||
@ stdcall CPGetKeyParam(long long long ptr ptr long) RSAENH_CPGetKeyParam
|
||||
@ stdcall CPGetProvParam(long long ptr ptr long) RSAENH_CPGetProvParam
|
||||
@ stdcall CPGetUserKey(long long ptr) RSAENH_CPGetUserKey
|
||||
@ stdcall CPHashData(long long ptr long long) RSAENH_CPHashData
|
||||
@ stdcall CPHashSessionKey(long long long long) RSAENH_CPHashSessionKey
|
||||
@ stdcall CPImportKey(long ptr long long long ptr) RSAENH_CPImportKey
|
||||
@ stdcall CPReleaseContext(long long) RSAENH_CPReleaseContext
|
||||
@ stdcall CPSetHashParam(long long long ptr long) RSAENH_CPSetHashParam
|
||||
@ stdcall CPSetKeyParam(long long long ptr long) RSAENH_CPSetKeyParam
|
||||
@ stdcall CPSetProvParam(long long ptr long) RSAENH_CPSetProvParam
|
||||
@ stdcall CPSignHash(long long long wstr long ptr ptr) RSAENH_CPSignHash
|
||||
@ stdcall CPVerifySignature(long long ptr long long wstr long) RSAENH_CPVerifySignature
|
||||
@ stdcall -private DllRegisterServer() RSAENH_DllRegisterServer
|
||||
@ stdcall -private DllUnregisterServer() RSAENH_DllUnregisterServer
|
|
@ -0,0 +1,3 @@
|
|||
Makefile
|
||||
rsaenh.ok
|
||||
testlist.c
|
|
@ -0,0 +1,13 @@
|
|||
TOPSRCDIR = @top_srcdir@
|
||||
TOPOBJDIR = ../../..
|
||||
SRCDIR = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
TESTDLL = rsaenh.dll
|
||||
IMPORTS = advapi32 kernel32
|
||||
|
||||
CTESTS = \
|
||||
rsaenh.c
|
||||
|
||||
@MAKE_TEST_RULES@
|
||||
|
||||
### Dependencies:
|
|
@ -0,0 +1,843 @@
|
|||
/*
|
||||
* Unit tests for rsaenh functions
|
||||
*
|
||||
* Copyright (c) 2004 Michael Jung
|
||||
*
|
||||
* 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 <string.h>
|
||||
#include <stdio.h>
|
||||
#include "wine/test.h"
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winerror.h"
|
||||
#include "wincrypt.h"
|
||||
|
||||
static HCRYPTPROV hProv;
|
||||
static const char szContainer[] = "winetest";
|
||||
static const unsigned char pbData[] = "Wine rocks totally!";
|
||||
static const char szProvider[] = MS_ENHANCED_PROV_A;
|
||||
|
||||
/*
|
||||
static void trace_hex(BYTE *pbData, DWORD dwLen) {
|
||||
char szTemp[256];
|
||||
DWORD i, j;
|
||||
|
||||
for (i = 0; i < dwLen-7; i+=8) {
|
||||
sprintf(szTemp, "0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x,\n",
|
||||
pbData[i], pbData[i+1], pbData[i+2], pbData[i+3], pbData[i+4], pbData[i+5],
|
||||
pbData[i+6], pbData[i+7]);
|
||||
trace(szTemp);
|
||||
}
|
||||
for (j=0; i<dwLen; j++,i++) {
|
||||
sprintf(szTemp+6*j, "0x%02x, \n", pbData[i]);
|
||||
}
|
||||
trace(szTemp);
|
||||
}
|
||||
*/
|
||||
|
||||
static int init_environment(void)
|
||||
{
|
||||
HCRYPTKEY hKey;
|
||||
BOOL result;
|
||||
|
||||
hProv = (HCRYPTPROV)INVALID_HANDLE_VALUE;
|
||||
|
||||
if (!CryptAcquireContext(&hProv, szContainer, szProvider, PROV_RSA_FULL, 0))
|
||||
{
|
||||
ok(GetLastError()==NTE_BAD_KEYSET, "%08lx\n", GetLastError());
|
||||
if (GetLastError()!=NTE_BAD_KEYSET) return 0;
|
||||
result = CryptAcquireContext(&hProv, szContainer, szProvider, PROV_RSA_FULL,
|
||||
CRYPT_NEWKEYSET);
|
||||
ok(result, "%08lx\n", GetLastError());
|
||||
if (!result) return 0;
|
||||
result = CryptGenKey(hProv, AT_KEYEXCHANGE, 0, &hKey);
|
||||
ok(result, "%08lx\n", GetLastError());
|
||||
if (result) CryptDestroyKey(hKey);
|
||||
result = CryptGenKey(hProv, AT_SIGNATURE, 0, &hKey);
|
||||
ok(result, "%08lx\n", GetLastError());
|
||||
if (result) CryptDestroyKey(hKey);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void clean_up_environment(void)
|
||||
{
|
||||
CryptAcquireContext(&hProv, szContainer, szProvider, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
|
||||
}
|
||||
|
||||
static void test_prov()
|
||||
{
|
||||
BOOL result;
|
||||
DWORD dwLen, dwInc;
|
||||
|
||||
dwLen = (DWORD)sizeof(DWORD);
|
||||
result = CryptGetProvParam(hProv, PP_SIG_KEYSIZE_INC, (BYTE*)&dwInc, &dwLen, 0);
|
||||
ok(result && dwInc==8, "%08lx, %ld\n", GetLastError(), dwInc);
|
||||
|
||||
dwLen = (DWORD)sizeof(DWORD);
|
||||
result = CryptGetProvParam(hProv, PP_KEYX_KEYSIZE_INC, (BYTE*)&dwInc, &dwLen, 0);
|
||||
ok(result && dwInc==8, "%08lx, %ld\n", GetLastError(), dwInc);
|
||||
}
|
||||
|
||||
static void test_gen_random()
|
||||
{
|
||||
BOOL result;
|
||||
BYTE rnd1[16], rnd2[16];
|
||||
|
||||
memset(rnd1, 0, sizeof(rnd1));
|
||||
memset(rnd2, 0, sizeof(rnd2));
|
||||
|
||||
result = CryptGenRandom(hProv, sizeof(rnd1), rnd1);
|
||||
if (!result && GetLastError() == NTE_FAIL) {
|
||||
/* rsaenh compiled without OpenSSL */
|
||||
return;
|
||||
}
|
||||
|
||||
ok(result, "%08lx\n", GetLastError());
|
||||
|
||||
result = CryptGenRandom(hProv, sizeof(rnd2), rnd2);
|
||||
ok(result, "%08lx\n", GetLastError());
|
||||
|
||||
ok(memcmp(rnd1, rnd2, sizeof(rnd1)), "CryptGenRandom generates non random data\n");
|
||||
}
|
||||
|
||||
static BOOL derive_key(ALG_ID aiAlgid, HCRYPTKEY *phKey, DWORD len)
|
||||
{
|
||||
HCRYPTHASH hHash;
|
||||
BOOL result;
|
||||
unsigned char pbData[2000];
|
||||
int i;
|
||||
|
||||
*phKey = (HCRYPTKEY)NULL;
|
||||
for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
|
||||
result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
|
||||
if (!result) {
|
||||
/* rsaenh compiled without OpenSSL */
|
||||
ok(GetLastError()==NTE_BAD_ALGID, "%08lx", GetLastError());
|
||||
return FALSE;
|
||||
}
|
||||
ok(result, "%08lx\n", GetLastError());
|
||||
if (!result) return FALSE;
|
||||
result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
|
||||
ok(result, "%08lx\n", GetLastError());
|
||||
if (!result) return FALSE;
|
||||
result = CryptDeriveKey(hProv, aiAlgid, hHash, (len << 16) | CRYPT_EXPORTABLE, phKey);
|
||||
ok(result, "%08lx\n", GetLastError());
|
||||
if (!result) return FALSE;
|
||||
len = 2000;
|
||||
result = CryptGetHashParam(hHash, HP_HASHVAL, pbData, &len, 0);
|
||||
ok(result, "%08lx\n", GetLastError());
|
||||
CryptDestroyHash(hHash);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void test_hashes(void)
|
||||
{
|
||||
static const unsigned char md2hash[16] = {
|
||||
0x12, 0xcb, 0x1b, 0x08, 0xc8, 0x48, 0xa4, 0xa9,
|
||||
0xaa, 0xf3, 0xf1, 0x9f, 0xfc, 0x29, 0x28, 0x68 };
|
||||
static const unsigned char md4hash[16] = {
|
||||
0x8e, 0x2a, 0x58, 0xbf, 0xf2, 0xf5, 0x26, 0x23,
|
||||
0x79, 0xd2, 0x92, 0x36, 0x1b, 0x23, 0xe3, 0x81 };
|
||||
static const unsigned char md5hash[16] = {
|
||||
0x15, 0x76, 0xa9, 0x4d, 0x6c, 0xb3, 0x34, 0xdd,
|
||||
0x12, 0x6c, 0xb1, 0xc2, 0x7f, 0x19, 0xe0, 0xf2 };
|
||||
static const unsigned char sha1hash[20] = {
|
||||
0xf1, 0x0c, 0xcf, 0xde, 0x60, 0xc1, 0x7d, 0xb2, 0x6e, 0x7d,
|
||||
0x85, 0xd3, 0x56, 0x65, 0xc7, 0x66, 0x1d, 0xbb, 0xeb, 0x2c };
|
||||
unsigned char pbData[2048];
|
||||
BOOL result;
|
||||
HCRYPTHASH hHash, hHashClone;
|
||||
BYTE pbHashValue[36];
|
||||
DWORD hashlen, len;
|
||||
int i;
|
||||
|
||||
for (i=0; i<2048; i++) pbData[i] = (unsigned char)i;
|
||||
|
||||
/* MD2 Hashing */
|
||||
result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
|
||||
if (!result) {
|
||||
/* rsaenh compiled without OpenSSL */
|
||||
ok(GetLastError() == NTE_BAD_ALGID, "%08lx\n", GetLastError());
|
||||
} else {
|
||||
result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
|
||||
ok(result, "%08lx\n", GetLastError());
|
||||
|
||||
len = sizeof(DWORD);
|
||||
result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
|
||||
ok(result && (hashlen == 16), "%08lx, hashlen: %ld\n", GetLastError(), hashlen);
|
||||
|
||||
len = 16;
|
||||
result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
|
||||
ok(result, "%08lx\n", GetLastError());
|
||||
|
||||
ok(!memcmp(pbHashValue, md2hash, 16), "Wrong MD2 hash!\n");
|
||||
|
||||
result = CryptDestroyHash(hHash);
|
||||
ok(result, "%08lx\n", GetLastError());
|
||||
}
|
||||
|
||||
/* MD4 Hashing */
|
||||
result = CryptCreateHash(hProv, CALG_MD4, 0, 0, &hHash);
|
||||
ok(result, "%08lx\n", GetLastError());
|
||||
|
||||
result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
|
||||
ok(result, "%08lx\n", GetLastError());
|
||||
|
||||
len = sizeof(DWORD);
|
||||
result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
|
||||
ok(result && (hashlen == 16), "%08lx, hashlen: %ld\n", GetLastError(), hashlen);
|
||||
|
||||
len = 16;
|
||||
result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
|
||||
ok(result, "%08lx\n", GetLastError());
|
||||
|
||||
ok(!memcmp(pbHashValue, md4hash, 16), "Wrong MD4 hash!\n");
|
||||
|
||||
result = CryptDestroyHash(hHash);
|
||||
ok(result, "%08lx\n", GetLastError());
|
||||
|
||||
/* MD5 Hashing */
|
||||
result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
|
||||
ok(result, "%08lx\n", GetLastError());
|
||||
|
||||
result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
|
||||
ok(result, "%08lx\n", GetLastError());
|
||||
|
||||
len = sizeof(DWORD);
|
||||
result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
|
||||
ok(result && (hashlen == 16), "%08lx, hashlen: %ld\n", GetLastError(), hashlen);
|
||||
|
||||
len = 16;
|
||||
result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
|
||||
ok(result, "%08lx\n", GetLastError());
|
||||
|
||||
ok(!memcmp(pbHashValue, md5hash, 16), "Wrong MD5 hash!\n");
|
||||
|
||||
result = CryptDestroyHash(hHash);
|
||||
ok(result, "%08lx\n", GetLastError());
|
||||
|
||||
/* SHA1 Hashing */
|
||||
result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash);
|
||||
ok(result, "%08lx\n", GetLastError());
|
||||
|
||||
result = CryptHashData(hHash, (BYTE*)pbData, 5, 0);
|
||||
ok(result, "%08lx\n", GetLastError());
|
||||
|
||||
result = CryptDuplicateHash(hHash, 0, 0, &hHashClone);
|
||||
ok(result, "%08lx\n", GetLastError());
|
||||
|
||||
result = CryptHashData(hHashClone, (BYTE*)pbData+5, sizeof(pbData)-5, 0);
|
||||
ok(result, "%08lx\n", GetLastError());
|
||||
|
||||
len = sizeof(DWORD);
|
||||
result = CryptGetHashParam(hHashClone, HP_HASHSIZE, (BYTE*)&hashlen, &len, 0);
|
||||
ok(result && (hashlen == 20), "%08lx, hashlen: %ld\n", GetLastError(), hashlen);
|
||||
|
||||
len = 20;
|
||||
result = CryptGetHashParam(hHashClone, HP_HASHVAL, pbHashValue, &len, 0);
|
||||
ok(result, "%08lx\n", GetLastError());
|
||||
|
||||
ok(!memcmp(pbHashValue, sha1hash, 20), "Wrong SHA1 hash!\n");
|
||||
|
||||
result = CryptDestroyHash(hHashClone);
|
||||
ok(result, "%08lx\n", GetLastError());
|
||||
|
||||
result = CryptDestroyHash(hHash);
|
||||
ok(result, "%08lx\n", GetLastError());
|
||||
}
|
||||
|
||||
static void test_block_cipher_modes()
|
||||
{
|
||||
static const BYTE plain[23] = {
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
|
||||
0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16 };
|
||||
static const BYTE ecb[24] = {
|
||||
0xc0, 0x9a, 0xe4, 0x2f, 0x0a, 0x47, 0x67, 0x11, 0xf2, 0xb2, 0x5d, 0x5f,
|
||||
0x08, 0xff, 0x49, 0xa4, 0x45, 0x3a, 0x68, 0x14, 0xca, 0x18, 0xe5, 0xf4 };
|
||||
static const BYTE cbc[24] = {
|
||||
0xc0, 0x9a, 0xe4, 0x2f, 0x0a, 0x47, 0x67, 0x11, 0x10, 0xf5, 0xda, 0x61,
|
||||
0x4e, 0x3d, 0xab, 0xc0, 0x97, 0x85, 0x01, 0x12, 0x97, 0xa4, 0xf7, 0xd3 };
|
||||
static const BYTE cfb[24] = {
|
||||
0x29, 0xb5, 0x67, 0x85, 0x0b, 0x1b, 0xec, 0x07, 0x67, 0x2d, 0xa1, 0xa4,
|
||||
0x1a, 0x47, 0x24, 0x6a, 0x54, 0xe1, 0xe0, 0x92, 0xf9, 0x0e, 0xf6, 0xeb };
|
||||
HCRYPTKEY hKey;
|
||||
BOOL result;
|
||||
BYTE abData[24];
|
||||
DWORD dwMode, dwLen;
|
||||
|
||||
result = derive_key(CALG_RC2, &hKey, 40);
|
||||
if (!result) return;
|
||||
|
||||
memcpy(abData, plain, sizeof(abData));
|
||||
|
||||
dwMode = CRYPT_MODE_ECB;
|
||||
result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
|
||||
ok(result, "%08lx\n", GetLastError());
|
||||
|
||||
SetLastError(ERROR_SUCCESS);
|
||||
dwLen = 23;
|
||||
result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abData, &dwLen, 24);
|
||||
ok(result && dwLen == 24 && !memcmp(ecb, abData, sizeof(ecb)),
|
||||
"%08lx, dwLen: %ld\n", GetLastError(), dwLen);
|
||||
|
||||
result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abData, &dwLen);
|
||||
ok(result && dwLen == 23 && !memcmp(plain, abData, sizeof(plain)),
|
||||
"%08lx, dwLen: %ld\n", GetLastError(), dwLen);
|
||||
|
||||
dwMode = CRYPT_MODE_CBC;
|
||||
result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
|
||||
ok(result, "%08lx\n", GetLastError());
|
||||
|
||||
dwLen = 23;
|
||||
result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abData, &dwLen, 24);
|
||||
ok(result && dwLen == 24 && !memcmp(cbc, abData, sizeof(cbc)),
|
||||
"%08lx, dwLen: %ld\n", GetLastError(), dwLen);
|
||||
|
||||
result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abData, &dwLen);
|
||||
ok(result && dwLen == 23 && !memcmp(plain, abData, sizeof(plain)),
|
||||
"%08lx, dwLen: %ld\n", GetLastError(), dwLen);
|
||||
|
||||
dwMode = CRYPT_MODE_CFB;
|
||||
result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
|
||||
ok(result, "%08lx\n", GetLastError());
|
||||
|
||||
dwLen = 16;
|
||||
result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, FALSE, 0, abData, &dwLen, 24);
|
||||
ok(result && dwLen == 16, "%08lx, dwLen: %ld\n", GetLastError(), dwLen);
|
||||
|
||||
dwLen = 7;
|
||||
result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abData+16, &dwLen, 8);
|
||||
ok(result && dwLen == 8 && !memcmp(cfb, abData, sizeof(cfb)),
|
||||
"%08lx, dwLen: %ld\n", GetLastError(), dwLen);
|
||||
|
||||
dwLen = 8;
|
||||
result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, FALSE, 0, abData, &dwLen);
|
||||
ok(result && dwLen == 8, "%08lx, dwLen: %ld\n", GetLastError(), dwLen);
|
||||
|
||||
dwLen = 16;
|
||||
result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abData+8, &dwLen);
|
||||
ok(result && dwLen == 15 && !memcmp(plain, abData, sizeof(plain)),
|
||||
"%08lx, dwLen: %ld\n", GetLastError(), dwLen);
|
||||
|
||||
dwMode = CRYPT_MODE_OFB;
|
||||
result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
|
||||
ok(result, "%08lx\n", GetLastError());
|
||||
|
||||
dwLen = 23;
|
||||
result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abData, &dwLen, 24);
|
||||
ok(!result && GetLastError() == NTE_BAD_ALGID, "%08lx\n", GetLastError());
|
||||
}
|
||||
|
||||
static void test_3des112()
|
||||
{
|
||||
HCRYPTKEY hKey;
|
||||
BOOL result;
|
||||
DWORD dwLen;
|
||||
unsigned char pbData[16];
|
||||
int i;
|
||||
|
||||
result = derive_key(CALG_3DES_112, &hKey, 0);
|
||||
if (!result) {
|
||||
/* rsaenh compiled without OpenSSL */
|
||||
ok(GetLastError() == NTE_BAD_ALGID, "%08lx\n", GetLastError());
|
||||
return;
|
||||
}
|
||||
|
||||
for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
|
||||
|
||||
dwLen = 13;
|
||||
result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen, 16);
|
||||
ok(result, "%08lx\n", GetLastError());
|
||||
|
||||
result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen);
|
||||
ok(result, "%08lx\n", GetLastError());
|
||||
|
||||
result = CryptDestroyKey(hKey);
|
||||
ok(result, "%08lx\n", GetLastError());
|
||||
}
|
||||
|
||||
static void test_des()
|
||||
{
|
||||
HCRYPTKEY hKey;
|
||||
BOOL result;
|
||||
DWORD dwLen, dwMode;
|
||||
unsigned char pbData[16];
|
||||
int i;
|
||||
|
||||
result = derive_key(CALG_DES, &hKey, 56);
|
||||
if (!result) {
|
||||
/* rsaenh compiled without OpenSSL */
|
||||
ok(GetLastError()==NTE_BAD_ALGID, "%08lx\n", GetLastError());
|
||||
return;
|
||||
}
|
||||
|
||||
dwMode = CRYPT_MODE_ECB;
|
||||
result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
|
||||
ok(result, "%08lx\n", GetLastError());
|
||||
|
||||
dwLen = sizeof(DWORD);
|
||||
result = CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
|
||||
ok(result, "%08lx\n", GetLastError());
|
||||
|
||||
for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
|
||||
|
||||
dwLen = 13;
|
||||
result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen, 16);
|
||||
ok(result, "%08lx\n", GetLastError());
|
||||
|
||||
result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen);
|
||||
ok(result, "%08lx\n", GetLastError());
|
||||
|
||||
result = CryptDestroyKey(hKey);
|
||||
ok(result, "%08lx\n", GetLastError());
|
||||
}
|
||||
|
||||
static void test_3des()
|
||||
{
|
||||
HCRYPTKEY hKey;
|
||||
BOOL result;
|
||||
DWORD dwLen;
|
||||
unsigned char pbData[16];
|
||||
static const BYTE des3[16] = {
|
||||
0x7b, 0xba, 0xdd, 0xa2, 0x39, 0xd3, 0x7b, 0xb3,
|
||||
0xc7, 0x51, 0x81, 0x41, 0x53, 0xe8, 0xcf, 0xeb };
|
||||
int i;
|
||||
|
||||
result = derive_key(CALG_3DES, &hKey, 0);
|
||||
if (!result) return;
|
||||
|
||||
for (i=0; i<sizeof(pbData); i++) pbData[i] = (unsigned char)i;
|
||||
|
||||
dwLen = 13;
|
||||
result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen, 16);
|
||||
ok(result, "%08lx\n", GetLastError());
|
||||
|
||||
ok(!memcmp(pbData, des3, sizeof(des3)), "3DES encryption failed!\n");
|
||||
|
||||
result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwLen);
|
||||
ok(result, "%08lx\n", GetLastError());
|
||||
|
||||
result = CryptDestroyKey(hKey);
|
||||
ok(result, "%08lx\n", GetLastError());
|
||||
}
|
||||
|
||||
static void test_rc2()
|
||||
{
|
||||
static const BYTE rc2encrypted[16] = {
|
||||
0x02, 0x34, 0x7d, 0xf6, 0x1d, 0xc5, 0x9b, 0x8b,
|
||||
0x2e, 0x0d, 0x63, 0x80, 0x72, 0xc1, 0xc2, 0xb1 };
|
||||
HCRYPTHASH hHash;
|
||||
HCRYPTKEY hKey;
|
||||
BOOL result;
|
||||
DWORD dwLen, dwKeyLen, dwDataLen, dwMode, dwModeBits;
|
||||
BYTE *pbTemp;
|
||||
unsigned char pbData[2000], pbHashValue[16];
|
||||
int i;
|
||||
|
||||
for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
|
||||
|
||||
/* MD2 Hashing */
|
||||
result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
|
||||
if (!result) {
|
||||
ok(GetLastError()==NTE_BAD_ALGID, "%08lx\n", GetLastError());
|
||||
} else {
|
||||
result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
|
||||
ok(result, "%08lx\n", GetLastError());
|
||||
|
||||
dwLen = 16;
|
||||
result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &dwLen, 0);
|
||||
ok(result, "%08lx\n", GetLastError());
|
||||
|
||||
result = CryptDeriveKey(hProv, CALG_RC2, hHash, 56 << 16, &hKey);
|
||||
ok(result, "%08lx\n", GetLastError());
|
||||
|
||||
dwLen = sizeof(DWORD);
|
||||
result = CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
|
||||
ok(result, "%08lx\n", GetLastError());
|
||||
|
||||
dwMode = CRYPT_MODE_CBC;
|
||||
result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0);
|
||||
ok(result, "%08lx\n", GetLastError());
|
||||
|
||||
dwLen = sizeof(DWORD);
|
||||
result = CryptGetKeyParam(hKey, KP_MODE_BITS, (BYTE*)&dwModeBits, &dwLen, 0);
|
||||
ok(result, "%08lx\n", GetLastError());
|
||||
|
||||
dwLen = sizeof(DWORD);
|
||||
result = CryptGetKeyParam(hKey, KP_PERMISSIONS, (BYTE*)&dwModeBits, &dwLen, 0);
|
||||
ok(result, "%08lx\n", GetLastError());
|
||||
|
||||
dwLen = sizeof(DWORD);
|
||||
result = CryptGetKeyParam(hKey, KP_BLOCKLEN, (BYTE*)&dwModeBits, &dwLen, 0);
|
||||
ok(result, "%08lx\n", GetLastError());
|
||||
|
||||
result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
|
||||
ok(result, "%08lx\n", GetLastError());
|
||||
pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
|
||||
CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
|
||||
HeapFree(GetProcessHeap(), 0, pbTemp);
|
||||
|
||||
result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
|
||||
ok(result, "%08lx\n", GetLastError());
|
||||
pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
|
||||
CryptGetKeyParam(hKey, KP_SALT, pbTemp, &dwLen, 0);
|
||||
HeapFree(GetProcessHeap(), 0, pbTemp);
|
||||
|
||||
dwLen = sizeof(DWORD);
|
||||
CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
|
||||
|
||||
result = CryptDestroyHash(hHash);
|
||||
ok(result, "%08lx\n", GetLastError());
|
||||
|
||||
dwDataLen = 13;
|
||||
result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwDataLen, 24);
|
||||
ok(result, "%08lx\n", GetLastError());
|
||||
|
||||
ok(!memcmp(pbData, rc2encrypted, 8), "RC2 encryption failed!\n");
|
||||
|
||||
result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
|
||||
ok(result, "%08lx\n", GetLastError());
|
||||
pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
|
||||
CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
|
||||
HeapFree(GetProcessHeap(), 0, pbTemp);
|
||||
|
||||
result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwDataLen);
|
||||
ok(result, "%08lx\n", GetLastError());
|
||||
|
||||
result = CryptDestroyKey(hKey);
|
||||
ok(result, "%08lx\n", GetLastError());
|
||||
}
|
||||
}
|
||||
|
||||
static void test_rc4()
|
||||
{
|
||||
static const BYTE rc4[16] = {
|
||||
0x17, 0x0c, 0x44, 0x8e, 0xae, 0x90, 0xcd, 0xb0,
|
||||
0x7f, 0x87, 0xf5, 0x7a, 0xec, 0xb2, 0x2e, 0x35 };
|
||||
BOOL result;
|
||||
HCRYPTHASH hHash;
|
||||
HCRYPTKEY hKey;
|
||||
DWORD dwDataLen = 5, dwKeyLen, dwLen = sizeof(DWORD), dwMode;
|
||||
unsigned char pbData[2000], *pbTemp;
|
||||
unsigned char pszBuffer[256];
|
||||
int i;
|
||||
|
||||
for (i=0; i<2000; i++) pbData[i] = (unsigned char)i;
|
||||
|
||||
/* MD2 Hashing */
|
||||
result = CryptCreateHash(hProv, CALG_MD2, 0, 0, &hHash);
|
||||
if (!result) {
|
||||
/* rsaenh compiled without OpenSSL */
|
||||
ok(GetLastError() == NTE_BAD_ALGID, "%08lx\n", GetLastError());
|
||||
} else {
|
||||
result = CryptHashData(hHash, (BYTE*)pbData, sizeof(pbData), 0);
|
||||
ok(result, "%08lx\n", GetLastError());
|
||||
|
||||
dwLen = 16;
|
||||
result = CryptGetHashParam(hHash, HP_HASHVAL, pszBuffer, &dwLen, 0);
|
||||
ok(result, "%08lx\n", GetLastError());
|
||||
|
||||
result = CryptDeriveKey(hProv, CALG_RC4, hHash, 56 << 16, &hKey);
|
||||
ok(result, "%08lx\n", GetLastError());
|
||||
|
||||
dwLen = sizeof(DWORD);
|
||||
result = CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
|
||||
ok(result, "%08lx\n", GetLastError());
|
||||
|
||||
dwLen = sizeof(DWORD);
|
||||
result = CryptGetKeyParam(hKey, KP_BLOCKLEN, (BYTE*)&dwKeyLen, &dwLen, 0);
|
||||
ok(result, "%08lx\n", GetLastError());
|
||||
|
||||
result = CryptGetKeyParam(hKey, KP_IV, NULL, &dwLen, 0);
|
||||
ok(result, "%08lx\n", GetLastError());
|
||||
pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
|
||||
CryptGetKeyParam(hKey, KP_IV, pbTemp, &dwLen, 0);
|
||||
HeapFree(GetProcessHeap(), 0, pbTemp);
|
||||
|
||||
result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0);
|
||||
ok(result, "%08lx\n", GetLastError());
|
||||
pbTemp = HeapAlloc(GetProcessHeap(), 0, dwLen);
|
||||
CryptGetKeyParam(hKey, KP_SALT, pbTemp, &dwLen, 0);
|
||||
HeapFree(GetProcessHeap(), 0, pbTemp);
|
||||
|
||||
dwLen = sizeof(DWORD);
|
||||
CryptGetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, &dwLen, 0);
|
||||
|
||||
result = CryptDestroyHash(hHash);
|
||||
ok(result, "%08lx\n", GetLastError());
|
||||
|
||||
dwDataLen = 16;
|
||||
result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwDataLen, 24);
|
||||
ok(result, "%08lx\n", GetLastError());
|
||||
|
||||
ok(!memcmp(pbData, rc4, dwDataLen), "RC4 encryption failed!\n");
|
||||
|
||||
result = CryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, pbData, &dwDataLen);
|
||||
ok(result, "%08lx\n", GetLastError());
|
||||
|
||||
result = CryptDestroyKey(hKey);
|
||||
ok(result, "%08lx\n", GetLastError());
|
||||
}
|
||||
}
|
||||
|
||||
static void test_hmac() {
|
||||
HCRYPTKEY hKey;
|
||||
HCRYPTHASH hHash;
|
||||
BOOL result;
|
||||
HMAC_INFO hmacInfo = { CALG_MD2, NULL, 0, NULL, 0 };
|
||||
DWORD dwLen;
|
||||
BYTE abData[256];
|
||||
static const BYTE hmac[16] = {
|
||||
0xfd, 0x16, 0xb5, 0xb6, 0x13, 0x1c, 0x2b, 0xd6,
|
||||
0x0a, 0xc7, 0xae, 0x92, 0x76, 0xa3, 0x05, 0x71 };
|
||||
int i;
|
||||
|
||||
for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abData[i] = (BYTE)i;
|
||||
|
||||
if (!derive_key(CALG_RC2, &hKey, 56)) return;
|
||||
|
||||
result = CryptCreateHash(hProv, CALG_HMAC, hKey, 0, &hHash);
|
||||
ok(result, "%08lx\n", GetLastError());
|
||||
if (!result) return;
|
||||
|
||||
result = CryptSetHashParam(hHash, HP_HMAC_INFO, (BYTE*)&hmacInfo, 0);
|
||||
ok(result, "%08lx\n", GetLastError());
|
||||
|
||||
result = CryptHashData(hHash, (BYTE*)abData, sizeof(abData), 0);
|
||||
ok(result, "%08lx\n", GetLastError());
|
||||
|
||||
dwLen = sizeof(abData)/sizeof(BYTE);
|
||||
result = CryptGetHashParam(hHash, HP_HASHVAL, abData, &dwLen, 0);
|
||||
ok(result, "%08lx\n", GetLastError());
|
||||
|
||||
ok(!memcmp(abData, hmac, sizeof(hmac)), "HMAC failed!\n");
|
||||
|
||||
result = CryptDestroyHash(hHash);
|
||||
ok(result, "%08lx\n", GetLastError());
|
||||
|
||||
result = CryptDestroyKey(hKey);
|
||||
ok(result, "%08lx\n", GetLastError());
|
||||
|
||||
/* Provoke errors */
|
||||
result = CryptCreateHash(hProv, CALG_HMAC, 0, 0, &hHash);
|
||||
ok(!result && GetLastError() == NTE_BAD_KEY, "%08lx\n", GetLastError());
|
||||
}
|
||||
|
||||
static void test_mac() {
|
||||
HCRYPTKEY hKey;
|
||||
HCRYPTHASH hHash;
|
||||
BOOL result;
|
||||
DWORD dwLen;
|
||||
BYTE abData[256], abEnc[264];
|
||||
static const BYTE mac[8] = { 0x0d, 0x3e, 0x15, 0x6b, 0x85, 0x63, 0x5c, 0x11 };
|
||||
int i;
|
||||
|
||||
for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abData[i] = (BYTE)i;
|
||||
for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abEnc[i] = (BYTE)i;
|
||||
|
||||
if (!derive_key(CALG_RC2, &hKey, 56)) return;
|
||||
|
||||
dwLen = 256;
|
||||
result = CryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, abEnc, &dwLen, 264);
|
||||
ok (result && dwLen == 264, "%08lx, dwLen: %ld\n", GetLastError(), dwLen);
|
||||
|
||||
result = CryptCreateHash(hProv, CALG_MAC, hKey, 0, &hHash);
|
||||
ok(result, "%08lx\n", GetLastError());
|
||||
if (!result) return;
|
||||
|
||||
result = CryptHashData(hHash, (BYTE*)abData, sizeof(abData), 0);
|
||||
ok(result, "%08lx\n", GetLastError());
|
||||
|
||||
dwLen = sizeof(abData)/sizeof(BYTE);
|
||||
result = CryptGetHashParam(hHash, HP_HASHVAL, abData, &dwLen, 0);
|
||||
ok(result && dwLen == 8, "%08lx, dwLen: %ld\n", GetLastError(), dwLen);
|
||||
|
||||
ok(!memcmp(abData, mac, sizeof(mac)), "MAC failed!\n");
|
||||
|
||||
result = CryptDestroyHash(hHash);
|
||||
ok(result, "%08lx\n", GetLastError());
|
||||
|
||||
result = CryptDestroyKey(hKey);
|
||||
ok(result, "%08lx\n", GetLastError());
|
||||
|
||||
/* Provoke errors */
|
||||
if (!derive_key(CALG_RC4, &hKey, 56)) return;
|
||||
|
||||
result = CryptCreateHash(hProv, CALG_MAC, hKey, 0, &hHash);
|
||||
ok(!result && GetLastError() == NTE_BAD_KEY, "%08lx\n", GetLastError());
|
||||
|
||||
result = CryptDestroyKey(hKey);
|
||||
ok(result, "%08lx\n", GetLastError());
|
||||
}
|
||||
|
||||
static void test_import_private()
|
||||
{
|
||||
DWORD dwLen;
|
||||
HCRYPTKEY hKeyExchangeKey, hSessionKey;
|
||||
BOOL result;
|
||||
BYTE abPlainPrivateKey[596] = {
|
||||
0x07, 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00,
|
||||
0x52, 0x53, 0x41, 0x32, 0x00, 0x04, 0x00, 0x00,
|
||||
0x01, 0x00, 0x01, 0x00, 0x9b, 0x64, 0xef, 0xce,
|
||||
0x31, 0x7c, 0xad, 0x56, 0xe2, 0x1e, 0x9b, 0x96,
|
||||
0xb3, 0xf0, 0x29, 0x88, 0x6e, 0xa8, 0xc2, 0x11,
|
||||
0x33, 0xd6, 0xcc, 0x8c, 0x69, 0xb2, 0x1a, 0xfd,
|
||||
0xfc, 0x23, 0x21, 0x30, 0x4d, 0x29, 0x45, 0xb6,
|
||||
0x3a, 0x67, 0x11, 0x80, 0x1a, 0x91, 0xf2, 0x9f,
|
||||
0x01, 0xac, 0xc0, 0x11, 0x50, 0x5f, 0xcd, 0xb9,
|
||||
0xad, 0x76, 0x9f, 0x6e, 0x91, 0x55, 0x71, 0xda,
|
||||
0x97, 0x96, 0x96, 0x22, 0x75, 0xb4, 0x83, 0x44,
|
||||
0x89, 0x9e, 0xf8, 0x44, 0x40, 0x7c, 0xd6, 0xcd,
|
||||
0x9d, 0x88, 0xd6, 0x88, 0xbc, 0x56, 0xb7, 0x64,
|
||||
0xe9, 0x2c, 0x24, 0x2f, 0x0d, 0x78, 0x55, 0x1c,
|
||||
0xb2, 0x67, 0xb1, 0x5e, 0xbc, 0x0c, 0xcf, 0x1c,
|
||||
0xe9, 0xd3, 0x9e, 0xa2, 0x15, 0x24, 0x73, 0xd6,
|
||||
0xdb, 0x6f, 0x83, 0xb2, 0xf8, 0xbc, 0xe7, 0x47,
|
||||
0x3b, 0x01, 0xef, 0x49, 0x08, 0x98, 0xd6, 0xa3,
|
||||
0xf9, 0x25, 0x57, 0xe9, 0x39, 0x3c, 0x53, 0x30,
|
||||
0x1b, 0xf2, 0xc9, 0x62, 0x31, 0x43, 0x5d, 0x84,
|
||||
0x24, 0x30, 0x21, 0x9a, 0xad, 0xdb, 0x62, 0x91,
|
||||
0xc8, 0x07, 0xd9, 0x2f, 0xd6, 0xb5, 0x37, 0x6f,
|
||||
0xfe, 0x7a, 0x12, 0xbc, 0xd9, 0xd2, 0x2b, 0xbf,
|
||||
0xd7, 0xb1, 0xfa, 0x7d, 0xc0, 0x48, 0xdd, 0x74,
|
||||
0xdd, 0x55, 0x04, 0xa1, 0x8b, 0xc1, 0x0a, 0xc4,
|
||||
0xa5, 0x57, 0x62, 0xee, 0x08, 0x8b, 0xf9, 0x19,
|
||||
0x6c, 0x52, 0x06, 0xf8, 0x73, 0x0f, 0x24, 0xc9,
|
||||
0x71, 0x9f, 0xc5, 0x45, 0x17, 0x3e, 0xae, 0x06,
|
||||
0x81, 0xa2, 0x96, 0x40, 0x06, 0xbf, 0xeb, 0x9e,
|
||||
0x80, 0x2b, 0x27, 0x20, 0x8f, 0x38, 0xcf, 0xeb,
|
||||
0xff, 0x3b, 0x38, 0x41, 0x35, 0x69, 0x66, 0x13,
|
||||
0x1d, 0x3c, 0x01, 0x3b, 0xf6, 0x37, 0xca, 0x9c,
|
||||
0x61, 0x74, 0x98, 0xcf, 0xc9, 0x6e, 0xe8, 0x90,
|
||||
0xc7, 0xb7, 0x33, 0xc0, 0x07, 0x3c, 0xf8, 0xc8,
|
||||
0xf6, 0xf2, 0xd7, 0xf0, 0x21, 0x62, 0x58, 0x8a,
|
||||
0x55, 0xbf, 0xa1, 0x2d, 0x3d, 0xa6, 0x69, 0xc5,
|
||||
0x02, 0x19, 0x31, 0xf0, 0x94, 0x0f, 0x45, 0x5c,
|
||||
0x95, 0x1b, 0x53, 0xbc, 0xf5, 0xb0, 0x1a, 0x8f,
|
||||
0xbf, 0x40, 0xe0, 0xc7, 0x73, 0xe7, 0x72, 0x6e,
|
||||
0xeb, 0xb1, 0x0f, 0x38, 0xc5, 0xf8, 0xee, 0x04,
|
||||
0xed, 0x34, 0x1a, 0x10, 0xf9, 0x53, 0x34, 0xf3,
|
||||
0x3e, 0xe6, 0x5c, 0xd1, 0x47, 0x65, 0xcd, 0xbd,
|
||||
0xf1, 0x06, 0xcb, 0xb4, 0xb1, 0x26, 0x39, 0x9f,
|
||||
0x71, 0xfe, 0x3d, 0xf8, 0x62, 0xab, 0x22, 0x8b,
|
||||
0x0e, 0xdc, 0xb9, 0xe8, 0x74, 0x06, 0xfc, 0x8c,
|
||||
0x25, 0xa1, 0xa9, 0xcf, 0x07, 0xf9, 0xac, 0x21,
|
||||
0x01, 0x7b, 0x1c, 0xdc, 0x94, 0xbd, 0x47, 0xe1,
|
||||
0xa0, 0x86, 0x59, 0x35, 0x6a, 0x6f, 0xb9, 0x70,
|
||||
0x26, 0x7c, 0x3c, 0xfd, 0xbd, 0x81, 0x39, 0x36,
|
||||
0x42, 0xc2, 0xbd, 0xbe, 0x84, 0x27, 0x9a, 0x69,
|
||||
0x81, 0xda, 0x99, 0x27, 0xc2, 0x4f, 0x62, 0x33,
|
||||
0xf4, 0x79, 0x30, 0xc5, 0x63, 0x54, 0x71, 0xf1,
|
||||
0x47, 0x22, 0x25, 0x9b, 0x6c, 0x00, 0x2f, 0x1c,
|
||||
0xf4, 0x1f, 0x85, 0xbc, 0xf6, 0x67, 0x6a, 0xe3,
|
||||
0xf6, 0x55, 0x8a, 0xef, 0xd0, 0x0b, 0xd3, 0xa2,
|
||||
0xc5, 0x51, 0x70, 0x15, 0x0a, 0xf0, 0x98, 0x4c,
|
||||
0xb7, 0x19, 0x62, 0x0e, 0x2d, 0x2a, 0x4a, 0x7d,
|
||||
0x7a, 0x0a, 0xc4, 0x17, 0xe3, 0x5d, 0x20, 0x52,
|
||||
0xa9, 0x98, 0xc3, 0xaa, 0x11, 0xf6, 0xbf, 0x4c,
|
||||
0x94, 0x99, 0x81, 0x89, 0xf0, 0x7f, 0x66, 0xaa,
|
||||
0xc8, 0x88, 0xd7, 0x31, 0x84, 0x71, 0xb6, 0x64,
|
||||
0x09, 0x76, 0x0b, 0x7f, 0x1a, 0x1f, 0x2e, 0xfe,
|
||||
0xcd, 0x59, 0x2a, 0x54, 0x11, 0x84, 0xd4, 0x6a,
|
||||
0x61, 0xdf, 0xaa, 0x76, 0x66, 0x9d, 0x82, 0x11,
|
||||
0x56, 0x3d, 0xd2, 0x52, 0xe6, 0x42, 0x5a, 0x77,
|
||||
0x92, 0x98, 0x34, 0xf3, 0x56, 0x6c, 0x96, 0x10,
|
||||
0x40, 0x59, 0x16, 0xcb, 0x77, 0x61, 0xe3, 0xbf,
|
||||
0x4b, 0xd4, 0x39, 0xfb, 0xb1, 0x4e, 0xc1, 0x74,
|
||||
0xec, 0x7a, 0xea, 0x3d, 0x68, 0xbb, 0x0b, 0xe6,
|
||||
0xc6, 0x06, 0xbf, 0xdd, 0x7f, 0x94, 0x42, 0xc0,
|
||||
0x0f, 0xe4, 0x92, 0x33, 0x6c, 0x6e, 0x1b, 0xba,
|
||||
0x73, 0xf9, 0x79, 0x84, 0xdf, 0x45, 0x00, 0xe4,
|
||||
0x94, 0x88, 0x9d, 0x08, 0x89, 0xcf, 0xf2, 0xa4,
|
||||
0xc5, 0x47, 0x45, 0x85, 0x86, 0xa5, 0xcc, 0xa8,
|
||||
0xf2, 0x5d, 0x58, 0x07
|
||||
};
|
||||
BYTE abSessionKey[148] = {
|
||||
0x01, 0x02, 0x00, 0x00, 0x01, 0x68, 0x00, 0x00,
|
||||
0x00, 0xa4, 0x00, 0x00, 0xb8, 0xa4, 0xdf, 0x5e,
|
||||
0x9e, 0xb1, 0xbf, 0x85, 0x3d, 0x24, 0x2d, 0x1e,
|
||||
0x69, 0xb7, 0x67, 0x13, 0x8e, 0x78, 0xf2, 0xdf,
|
||||
0xc6, 0x69, 0xce, 0x46, 0x7e, 0xf2, 0xf2, 0x33,
|
||||
0x20, 0x6f, 0xa1, 0xa5, 0x59, 0x83, 0x25, 0xcb,
|
||||
0x3a, 0xb1, 0x8a, 0x12, 0x63, 0x02, 0x3c, 0xfb,
|
||||
0x4a, 0xfa, 0xef, 0x8e, 0xf7, 0x29, 0x57, 0xb1,
|
||||
0x9e, 0xa7, 0xf3, 0x02, 0xfd, 0xca, 0xdf, 0x5a,
|
||||
0x1f, 0x71, 0xb6, 0x26, 0x09, 0x24, 0x39, 0xda,
|
||||
0xc0, 0xde, 0x2a, 0x0e, 0xcd, 0x1f, 0xe5, 0xb6,
|
||||
0x4f, 0x82, 0xa0, 0xa9, 0x90, 0xd3, 0xd9, 0x6a,
|
||||
0x43, 0x14, 0x2a, 0xf7, 0xac, 0xd5, 0xa0, 0x54,
|
||||
0x93, 0xc4, 0xb9, 0xe7, 0x24, 0x84, 0x4d, 0x69,
|
||||
0x5e, 0xcc, 0x2a, 0x32, 0xb5, 0xfb, 0xe4, 0xb4,
|
||||
0x08, 0xd5, 0x36, 0x58, 0x59, 0x40, 0xfb, 0x29,
|
||||
0x7f, 0xa7, 0x17, 0x25, 0xc4, 0x0d, 0x78, 0x37,
|
||||
0x04, 0x8c, 0x49, 0x92
|
||||
};
|
||||
BYTE abEncryptedMessage[12] = {
|
||||
0x40, 0x64, 0x28, 0xe8, 0x8a, 0xe7, 0xa4, 0xd4,
|
||||
0x1c, 0xfd, 0xde, 0x71
|
||||
};
|
||||
|
||||
dwLen = (DWORD)sizeof(abPlainPrivateKey);
|
||||
result = CryptImportKey(hProv, abPlainPrivateKey, dwLen, 0, 0, &hKeyExchangeKey);
|
||||
if (!result) {
|
||||
/* rsaenh compiled without OpenSSL */
|
||||
ok(GetLastError() == NTE_FAIL, "%08lx\n", GetLastError());
|
||||
return;
|
||||
}
|
||||
|
||||
dwLen = (DWORD)sizeof(abSessionKey);
|
||||
result = CryptImportKey(hProv, abSessionKey, dwLen, hKeyExchangeKey, 0, &hSessionKey);
|
||||
ok(result, "%08lx\n", GetLastError());
|
||||
if (!result) return;
|
||||
|
||||
dwLen = (DWORD)sizeof(abEncryptedMessage);
|
||||
result = CryptDecrypt(hSessionKey, 0, TRUE, 0, abEncryptedMessage, &dwLen);
|
||||
ok(result && dwLen == 12 && !strcmp(abEncryptedMessage, "Wine rocks!"),
|
||||
"%08lx, len: %ld\n", GetLastError(), dwLen);
|
||||
|
||||
if (!derive_key(CALG_RC4, &hSessionKey, 56)) return;
|
||||
|
||||
dwLen = (DWORD)sizeof(abSessionKey);
|
||||
result = CryptExportKey(hSessionKey, hKeyExchangeKey, SIMPLEBLOB, 0, abSessionKey, &dwLen);
|
||||
ok(result, "%08lx\n", GetLastError());
|
||||
if (!result) return;
|
||||
|
||||
dwLen = (DWORD)sizeof(abSessionKey);
|
||||
result = CryptImportKey(hProv, abSessionKey, dwLen, hKeyExchangeKey, 0, &hSessionKey);
|
||||
ok(result, "%08lx\n", GetLastError());
|
||||
if (!result) return;
|
||||
}
|
||||
|
||||
START_TEST(rsaenh)
|
||||
{
|
||||
if (!init_environment())
|
||||
return;
|
||||
test_prov();
|
||||
test_gen_random();
|
||||
test_hashes();
|
||||
test_rc4();
|
||||
test_rc2();
|
||||
test_des();
|
||||
test_3des112();
|
||||
test_3des();
|
||||
test_hmac();
|
||||
test_mac();
|
||||
test_block_cipher_modes();
|
||||
test_import_private();
|
||||
clean_up_environment();
|
||||
}
|
|
@ -431,6 +431,21 @@
|
|||
/* Define if OpenGL is present on the system */
|
||||
#undef HAVE_OPENGL
|
||||
|
||||
/* Define to 1 if you have the <openssl/des.h> header file. */
|
||||
#undef HAVE_OPENSSL_DES_H
|
||||
|
||||
/* Define to 1 if you have the <openssl/md2.h> header file. */
|
||||
#undef HAVE_OPENSSL_MD2_H
|
||||
|
||||
/* Define to 1 if you have the <openssl/rc2.h> header file. */
|
||||
#undef HAVE_OPENSSL_RC2_H
|
||||
|
||||
/* Define to 1 if you have the <openssl/rc4.h> header file. */
|
||||
#undef HAVE_OPENSSL_RC4_H
|
||||
|
||||
/* Define to 1 if you have the <openssl/rsa.h> header file. */
|
||||
#undef HAVE_OPENSSL_RSA_H
|
||||
|
||||
/* Define to 1 if you have the <openssl/ssl.h> header file. */
|
||||
#undef HAVE_OPENSSL_SSL_H
|
||||
|
||||
|
|
|
@ -2005,7 +2005,7 @@ HKLM,%CurrentVersion%\Telephony\Country List\998,"SameAreaRule",,"G"
|
|||
11,,ole32.dll,1
|
||||
11,,oleaut32.dll,1
|
||||
11,,quartz.dll,1
|
||||
11,,rsabase.dll,1
|
||||
11,,rsaenh.dll,1
|
||||
11,,shdocvw.dll,1
|
||||
11,,shell32.dll,1
|
||||
11,,urlmon.dll,1
|
||||
|
|
Loading…
Reference in New Issue