crypt32: Convert the Unix library to the __wine_unix_call interface.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
f18ccfef7b
commit
41663e6ea5
|
@ -1,5 +1,6 @@
|
||||||
EXTRADEFS = -D_CRYPT32_
|
EXTRADEFS = -D_CRYPT32_
|
||||||
MODULE = crypt32.dll
|
MODULE = crypt32.dll
|
||||||
|
UNIXLIB = crypt32.so
|
||||||
IMPORTLIB = crypt32
|
IMPORTLIB = crypt32
|
||||||
IMPORTS = user32 advapi32 bcrypt
|
IMPORTS = user32 advapi32 bcrypt
|
||||||
DELAYIMPORTS = cryptnet
|
DELAYIMPORTS = cryptnet
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#define __CRYPT32_PRIVATE_H__
|
#define __CRYPT32_PRIVATE_H__
|
||||||
|
|
||||||
#include "wine/list.h"
|
#include "wine/list.h"
|
||||||
|
#include "wine/unixlib.h"
|
||||||
|
|
||||||
BOOL CNG_ImportPubKey(CERT_PUBLIC_KEY_INFO *pubKeyInfo, BCRYPT_KEY_HANDLE *key) DECLSPEC_HIDDEN;
|
BOOL CNG_ImportPubKey(CERT_PUBLIC_KEY_INFO *pubKeyInfo, BCRYPT_KEY_HANDLE *key) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
|
@ -462,17 +463,53 @@ void init_empty_store(void) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
struct cert_store_data;
|
struct cert_store_data;
|
||||||
|
|
||||||
struct unix_funcs
|
struct open_cert_store_params
|
||||||
{
|
{
|
||||||
BOOL (WINAPI *enum_root_certs)( void *buffer, SIZE_T size, SIZE_T *needed );
|
CRYPT_DATA_BLOB *pfx;
|
||||||
BOOL (WINAPI *open_cert_store)( CRYPT_DATA_BLOB *pfx, const WCHAR *password,
|
const WCHAR *password;
|
||||||
struct cert_store_data **data_ret );
|
struct cert_store_data **data_ret;
|
||||||
NTSTATUS (WINAPI *import_store_key)( struct cert_store_data *data, void *buf, DWORD *buf_size );
|
|
||||||
NTSTATUS (WINAPI *import_store_cert)( struct cert_store_data *data, unsigned int index,
|
|
||||||
void *buf, DWORD *buf_size );
|
|
||||||
void (WINAPI *close_cert_store)( struct cert_store_data *data );
|
|
||||||
};
|
};
|
||||||
|
|
||||||
extern const struct unix_funcs *unix_funcs DECLSPEC_HIDDEN;
|
struct import_store_key_params
|
||||||
|
{
|
||||||
|
struct cert_store_data *data;
|
||||||
|
void *buf;
|
||||||
|
DWORD *buf_size;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct import_store_cert_params
|
||||||
|
{
|
||||||
|
struct cert_store_data *data;
|
||||||
|
unsigned int index;
|
||||||
|
void *buf;
|
||||||
|
DWORD *buf_size;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct close_cert_store_params
|
||||||
|
{
|
||||||
|
struct cert_store_data *data;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct enum_root_certs_params
|
||||||
|
{
|
||||||
|
void *buffer;
|
||||||
|
DWORD size;
|
||||||
|
DWORD *needed;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum unix_funcs
|
||||||
|
{
|
||||||
|
unix_process_attach,
|
||||||
|
unix_process_detach,
|
||||||
|
unix_open_cert_store,
|
||||||
|
unix_import_store_key,
|
||||||
|
unix_import_store_cert,
|
||||||
|
unix_close_cert_store,
|
||||||
|
unix_enum_root_certs,
|
||||||
|
};
|
||||||
|
|
||||||
|
extern unixlib_handle_t crypt32_handle;
|
||||||
|
|
||||||
|
#define CRYPT32_CALL( func, params ) __wine_unix_call( crypt32_handle, unix_ ## func, params )
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -34,7 +34,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(crypt);
|
||||||
|
|
||||||
static HCRYPTPROV hDefProv;
|
static HCRYPTPROV hDefProv;
|
||||||
HINSTANCE hInstance;
|
HINSTANCE hInstance;
|
||||||
const struct unix_funcs *unix_funcs = NULL;
|
unixlib_handle_t crypt32_handle = 0;
|
||||||
|
|
||||||
static CRITICAL_SECTION prov_param_cs;
|
static CRITICAL_SECTION prov_param_cs;
|
||||||
static CRITICAL_SECTION_DEBUG prov_param_cs_debug =
|
static CRITICAL_SECTION_DEBUG prov_param_cs_debug =
|
||||||
|
@ -55,7 +55,10 @@ BOOL WINAPI DllMain(HINSTANCE hInst, DWORD reason, PVOID pvReserved)
|
||||||
DisableThreadLibraryCalls(hInst);
|
DisableThreadLibraryCalls(hInst);
|
||||||
init_empty_store();
|
init_empty_store();
|
||||||
crypt_oid_init();
|
crypt_oid_init();
|
||||||
__wine_init_unix_lib( hInst, reason, NULL, &unix_funcs );
|
if (NtQueryVirtualMemory( GetCurrentProcess(), hInst, MemoryWineUnixFuncs,
|
||||||
|
&crypt32_handle, sizeof(crypt32_handle), NULL ))
|
||||||
|
return FALSE;
|
||||||
|
CRYPT32_CALL( process_attach, NULL );
|
||||||
break;
|
break;
|
||||||
case DLL_PROCESS_DETACH:
|
case DLL_PROCESS_DETACH:
|
||||||
if (pvReserved) break;
|
if (pvReserved) break;
|
||||||
|
@ -63,7 +66,7 @@ BOOL WINAPI DllMain(HINSTANCE hInst, DWORD reason, PVOID pvReserved)
|
||||||
crypt_sip_free();
|
crypt_sip_free();
|
||||||
default_chain_engine_free();
|
default_chain_engine_free();
|
||||||
if (hDefProv) CryptReleaseContext(hDefProv, 0);
|
if (hDefProv) CryptReleaseContext(hDefProv, 0);
|
||||||
__wine_init_unix_lib( hInst, reason, NULL, NULL );
|
CRYPT32_CALL( process_detach, NULL );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
|
@ -38,8 +38,9 @@ static HCRYPTPROV import_key( struct cert_store_data *data, DWORD flags )
|
||||||
HCRYPTKEY cryptkey;
|
HCRYPTKEY cryptkey;
|
||||||
DWORD size, acquire_flags;
|
DWORD size, acquire_flags;
|
||||||
void *key;
|
void *key;
|
||||||
|
struct import_store_key_params params = { data, NULL, &size };
|
||||||
|
|
||||||
if (unix_funcs->import_store_key( data, NULL, &size ) != STATUS_BUFFER_TOO_SMALL) return 0;
|
if (CRYPT32_CALL( import_store_key, ¶ms ) != STATUS_BUFFER_TOO_SMALL) return 0;
|
||||||
|
|
||||||
acquire_flags = (flags & CRYPT_MACHINE_KEYSET) | CRYPT_NEWKEYSET;
|
acquire_flags = (flags & CRYPT_MACHINE_KEYSET) | CRYPT_NEWKEYSET;
|
||||||
if (!CryptAcquireContextW( &prov, NULL, MS_ENHANCED_PROV_W, PROV_RSA_FULL, acquire_flags ))
|
if (!CryptAcquireContextW( &prov, NULL, MS_ENHANCED_PROV_W, PROV_RSA_FULL, acquire_flags ))
|
||||||
|
@ -54,8 +55,8 @@ static HCRYPTPROV import_key( struct cert_store_data *data, DWORD flags )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
key = malloc( size );
|
params.buf = key = malloc( size );
|
||||||
if (unix_funcs->import_store_key( data, key, &size ) ||
|
if (CRYPT32_CALL( import_store_key, ¶ms ) ||
|
||||||
!CryptImportKey( prov, key, size, 0, flags & CRYPT_EXPORTABLE, &cryptkey ))
|
!CryptImportKey( prov, key, size, 0, flags & CRYPT_EXPORTABLE, &cryptkey ))
|
||||||
{
|
{
|
||||||
WARN( "CryptImportKey failed %08x\n", GetLastError() );
|
WARN( "CryptImportKey failed %08x\n", GetLastError() );
|
||||||
|
@ -145,6 +146,8 @@ HCERTSTORE WINAPI PFXImportCertStore( CRYPT_DATA_BLOB *pfx, const WCHAR *passwor
|
||||||
HCERTSTORE store = NULL;
|
HCERTSTORE store = NULL;
|
||||||
HCRYPTPROV prov = 0;
|
HCRYPTPROV prov = 0;
|
||||||
struct cert_store_data *data = NULL;
|
struct cert_store_data *data = NULL;
|
||||||
|
struct open_cert_store_params open_params = { pfx, password, &data };
|
||||||
|
struct close_cert_store_params close_params;
|
||||||
|
|
||||||
if (!pfx)
|
if (!pfx)
|
||||||
{
|
{
|
||||||
|
@ -156,12 +159,7 @@ HCERTSTORE WINAPI PFXImportCertStore( CRYPT_DATA_BLOB *pfx, const WCHAR *passwor
|
||||||
FIXME( "flags %08x not supported\n", flags );
|
FIXME( "flags %08x not supported\n", flags );
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (!unix_funcs->open_cert_store)
|
if (CRYPT32_CALL( open_cert_store, &open_params )) return NULL;
|
||||||
{
|
|
||||||
FIXME( "(%p, %p, %08x)\n", pfx, password, flags );
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
if (!unix_funcs->open_cert_store( pfx, password, &data )) return NULL;
|
|
||||||
|
|
||||||
prov = import_key( data, flags );
|
prov = import_key( data, flags );
|
||||||
if (!prov) goto error;
|
if (!prov) goto error;
|
||||||
|
@ -176,10 +174,11 @@ HCERTSTORE WINAPI PFXImportCertStore( CRYPT_DATA_BLOB *pfx, const WCHAR *passwor
|
||||||
{
|
{
|
||||||
const void *ctx = NULL;
|
const void *ctx = NULL;
|
||||||
void *cert;
|
void *cert;
|
||||||
|
struct import_store_cert_params import_params = { data, i, NULL, &size };
|
||||||
|
|
||||||
if (unix_funcs->import_store_cert( data, i, NULL, &size ) != STATUS_BUFFER_TOO_SMALL) break;
|
if (CRYPT32_CALL( import_store_cert, &import_params ) != STATUS_BUFFER_TOO_SMALL) break;
|
||||||
cert = malloc( size );
|
import_params.buf = cert = malloc( size );
|
||||||
if (!unix_funcs->import_store_cert( data, i++, cert, &size ))
|
if (!CRYPT32_CALL( import_store_cert, &import_params ))
|
||||||
ctx = CertCreateContext( CERT_STORE_CERTIFICATE_CONTEXT, X509_ASN_ENCODING, cert, size, 0, NULL );
|
ctx = CertCreateContext( CERT_STORE_CERTIFICATE_CONTEXT, X509_ASN_ENCODING, cert, size, 0, NULL );
|
||||||
free( cert );
|
free( cert );
|
||||||
if (!ctx)
|
if (!ctx)
|
||||||
|
@ -209,14 +208,17 @@ HCERTSTORE WINAPI PFXImportCertStore( CRYPT_DATA_BLOB *pfx, const WCHAR *passwor
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
CertFreeCertificateContext( ctx );
|
CertFreeCertificateContext( ctx );
|
||||||
|
i++;
|
||||||
}
|
}
|
||||||
unix_funcs->close_cert_store( data );
|
close_params.data = data;
|
||||||
|
CRYPT32_CALL( close_cert_store, &close_params );
|
||||||
return store;
|
return store;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
CryptReleaseContext( prov, 0 );
|
CryptReleaseContext( prov, 0 );
|
||||||
CertCloseStore( store, 0 );
|
CertCloseStore( store, 0 );
|
||||||
if (data) unix_funcs->close_cert_store( data );
|
close_params.data = data;
|
||||||
|
CRYPT32_CALL( close_cert_store, &close_params );
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,8 @@
|
||||||
|
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include "ntstatus.h"
|
#include "ntstatus.h"
|
||||||
#define WIN32_NO_STATUS
|
#define WIN32_NO_STATUS
|
||||||
#include "windef.h"
|
#include "windef.h"
|
||||||
|
@ -615,24 +617,24 @@ static void read_trusted_roots_from_known_locations(HCERTSTORE store)
|
||||||
{
|
{
|
||||||
HCERTSTORE from = CertOpenStore(CERT_STORE_PROV_MEMORY,
|
HCERTSTORE from = CertOpenStore(CERT_STORE_PROV_MEMORY,
|
||||||
X509_ASN_ENCODING, 0, CERT_STORE_CREATE_NEW_FLAG, NULL);
|
X509_ASN_ENCODING, 0, CERT_STORE_CREATE_NEW_FLAG, NULL);
|
||||||
SIZE_T needed, size = 2048;
|
DWORD needed;
|
||||||
void *buffer;
|
struct enum_root_certs_params params = { NULL, 2048, &needed };
|
||||||
|
|
||||||
if (from)
|
if (from)
|
||||||
{
|
{
|
||||||
buffer = HeapAlloc( GetProcessHeap(), 0, size );
|
params.buffer = malloc( params.size );
|
||||||
while (unix_funcs->enum_root_certs( buffer, size, &needed ))
|
while (!CRYPT32_CALL( enum_root_certs, ¶ms ))
|
||||||
{
|
{
|
||||||
if (needed > size)
|
if (needed > params.size)
|
||||||
{
|
{
|
||||||
HeapFree( GetProcessHeap(), 0, buffer );
|
free( params.buffer );
|
||||||
buffer = HeapAlloc( GetProcessHeap(), 0, needed );
|
params.buffer = malloc( needed );
|
||||||
size = needed;
|
params.size = needed;
|
||||||
}
|
}
|
||||||
else CertAddEncodedCertificateToStore( from, X509_ASN_ENCODING, buffer, needed,
|
else CertAddEncodedCertificateToStore( from, X509_ASN_ENCODING, params.buffer, needed,
|
||||||
CERT_STORE_ADD_NEW, NULL );
|
CERT_STORE_ADD_NEW, NULL );
|
||||||
}
|
}
|
||||||
HeapFree( GetProcessHeap(), 0, buffer );
|
free( params.buffer );
|
||||||
check_and_store_certs(from, store);
|
check_and_store_certs(from, store);
|
||||||
}
|
}
|
||||||
CertCloseStore(from, 0);
|
CertCloseStore(from, 0);
|
||||||
|
|
|
@ -21,15 +21,14 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "wine/port.h"
|
|
||||||
|
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#ifdef HAVE_SYS_STAT_H
|
#include <dlfcn.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#endif
|
|
||||||
#ifdef HAVE_SECURITY_SECURITY_H
|
#ifdef HAVE_SECURITY_SECURITY_H
|
||||||
#include <Security/Security.h>
|
#include <Security/Security.h>
|
||||||
#endif
|
#endif
|
||||||
|
@ -43,11 +42,8 @@
|
||||||
#include "winbase.h"
|
#include "winbase.h"
|
||||||
#include "winternl.h"
|
#include "winternl.h"
|
||||||
#include "wincrypt.h"
|
#include "wincrypt.h"
|
||||||
#include "snmp.h"
|
|
||||||
#include "crypt32_private.h"
|
#include "crypt32_private.h"
|
||||||
|
|
||||||
#include "wine/debug.h"
|
#include "wine/debug.h"
|
||||||
#include "wine/heap.h"
|
|
||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(crypt);
|
WINE_DEFAULT_DEBUG_CHANNEL(crypt);
|
||||||
|
|
||||||
|
@ -84,7 +80,7 @@ static void gnutls_log( int level, const char *msg )
|
||||||
TRACE( "<%d> %s", level, msg );
|
TRACE( "<%d> %s", level, msg );
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL gnutls_initialize(void)
|
static NTSTATUS process_attach( void *args )
|
||||||
{
|
{
|
||||||
const char *env_str;
|
const char *env_str;
|
||||||
int ret;
|
int ret;
|
||||||
|
@ -102,7 +98,7 @@ static BOOL gnutls_initialize(void)
|
||||||
if (!(libgnutls_handle = dlopen( SONAME_LIBGNUTLS, RTLD_NOW )))
|
if (!(libgnutls_handle = dlopen( SONAME_LIBGNUTLS, RTLD_NOW )))
|
||||||
{
|
{
|
||||||
ERR_(winediag)( "failed to load libgnutls, no support for pfx import/export\n" );
|
ERR_(winediag)( "failed to load libgnutls, no support for pfx import/export\n" );
|
||||||
return FALSE;
|
return STATUS_DLL_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define LOAD_FUNCPTR(f) \
|
#define LOAD_FUNCPTR(f) \
|
||||||
|
@ -143,14 +139,15 @@ static BOOL gnutls_initialize(void)
|
||||||
fail:
|
fail:
|
||||||
dlclose( libgnutls_handle );
|
dlclose( libgnutls_handle );
|
||||||
libgnutls_handle = NULL;
|
libgnutls_handle = NULL;
|
||||||
return FALSE;
|
return STATUS_DLL_INIT_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void gnutls_uninitialize(void)
|
static NTSTATUS process_detach( void *args )
|
||||||
{
|
{
|
||||||
pgnutls_global_deinit();
|
pgnutls_global_deinit();
|
||||||
dlclose( libgnutls_handle );
|
dlclose( libgnutls_handle );
|
||||||
libgnutls_handle = NULL;
|
libgnutls_handle = NULL;
|
||||||
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
#define RSA_MAGIC_KEY ('R' | ('S' << 8) | ('A' << 16) | ('2' << 24))
|
#define RSA_MAGIC_KEY ('R' | ('S' << 8) | ('A' << 16) | ('2' << 24))
|
||||||
#define RSA_PUBEXP 65537
|
#define RSA_PUBEXP 65537
|
||||||
|
@ -164,8 +161,10 @@ struct cert_store_data
|
||||||
unsigned int chain_len;
|
unsigned int chain_len;
|
||||||
};
|
};
|
||||||
|
|
||||||
static NTSTATUS WINAPI import_store_key( struct cert_store_data *data, void *buf, DWORD *buf_size )
|
static NTSTATUS import_store_key( void *args )
|
||||||
{
|
{
|
||||||
|
struct import_store_key_params *params = args;
|
||||||
|
struct cert_store_data *data = params->data;
|
||||||
int i, ret;
|
int i, ret;
|
||||||
unsigned int bitlen = data->key_bitlen;
|
unsigned int bitlen = data->key_bitlen;
|
||||||
gnutls_datum_t m, e, d, p, q, u, e1, e2;
|
gnutls_datum_t m, e, d, p, q, u, e1, e2;
|
||||||
|
@ -175,9 +174,9 @@ static NTSTATUS WINAPI import_store_key( struct cert_store_data *data, void *buf
|
||||||
DWORD size;
|
DWORD size;
|
||||||
|
|
||||||
size = sizeof(*hdr) + sizeof(*rsakey) + (bitlen * 9 / 16);
|
size = sizeof(*hdr) + sizeof(*rsakey) + (bitlen * 9 / 16);
|
||||||
if (!buf || *buf_size < size)
|
if (!params->buf || *params->buf_size < size)
|
||||||
{
|
{
|
||||||
*buf_size = size;
|
*params->buf_size = size;
|
||||||
return STATUS_BUFFER_TOO_SMALL;
|
return STATUS_BUFFER_TOO_SMALL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -187,7 +186,7 @@ static NTSTATUS WINAPI import_store_key( struct cert_store_data *data, void *buf
|
||||||
return STATUS_INVALID_PARAMETER;
|
return STATUS_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
|
|
||||||
hdr = (BLOBHEADER *)buf;
|
hdr = params->buf;
|
||||||
hdr->bType = PRIVATEKEYBLOB;
|
hdr->bType = PRIVATEKEYBLOB;
|
||||||
hdr->bVersion = CUR_BLOB_VERSION;
|
hdr->bVersion = CUR_BLOB_VERSION;
|
||||||
hdr->reserved = 0;
|
hdr->reserved = 0;
|
||||||
|
@ -261,9 +260,9 @@ static char *password_to_ascii( const WCHAR *str )
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL WINAPI open_cert_store( CRYPT_DATA_BLOB *pfx, const WCHAR *password,
|
static NTSTATUS open_cert_store( void *args )
|
||||||
struct cert_store_data **data_ret )
|
|
||||||
{
|
{
|
||||||
|
struct open_cert_store_params *params = args;
|
||||||
gnutls_pkcs12_t p12;
|
gnutls_pkcs12_t p12;
|
||||||
gnutls_datum_t pfx_data;
|
gnutls_datum_t pfx_data;
|
||||||
gnutls_x509_privkey_t key;
|
gnutls_x509_privkey_t key;
|
||||||
|
@ -274,12 +273,13 @@ static BOOL WINAPI open_cert_store( CRYPT_DATA_BLOB *pfx, const WCHAR *password,
|
||||||
int ret;
|
int ret;
|
||||||
struct cert_store_data *store_data;
|
struct cert_store_data *store_data;
|
||||||
|
|
||||||
if (password && !(pwd = password_to_ascii( password ))) return FALSE;
|
if (!libgnutls_handle) return STATUS_DLL_NOT_FOUND;
|
||||||
|
if (params->password && !(pwd = password_to_ascii( params->password ))) return STATUS_NO_MEMORY;
|
||||||
|
|
||||||
if ((ret = pgnutls_pkcs12_init( &p12 )) < 0) goto error;
|
if ((ret = pgnutls_pkcs12_init( &p12 )) < 0) goto error;
|
||||||
|
|
||||||
pfx_data.data = pfx->pbData;
|
pfx_data.data = params->pfx->pbData;
|
||||||
pfx_data.size = pfx->cbData;
|
pfx_data.size = params->pfx->cbData;
|
||||||
if ((ret = pgnutls_pkcs12_import( p12, &pfx_data, GNUTLS_X509_FMT_DER, 0 )) < 0) goto error;
|
if ((ret = pgnutls_pkcs12_import( p12, &pfx_data, GNUTLS_X509_FMT_DER, 0 )) < 0) goto error;
|
||||||
|
|
||||||
if ((ret = pgnutls_pkcs12_simple_parse( p12, pwd ? pwd : "", &key, &chain, &chain_len, NULL, NULL, NULL, 0 )) < 0)
|
if ((ret = pgnutls_pkcs12_simple_parse( p12, pwd ? pwd : "", &key, &chain, &chain_len, NULL, NULL, NULL, 0 )) < 0)
|
||||||
|
@ -294,7 +294,7 @@ static BOOL WINAPI open_cert_store( CRYPT_DATA_BLOB *pfx, const WCHAR *password,
|
||||||
{
|
{
|
||||||
FIXME( "key algorithm %u not supported\n", ret );
|
FIXME( "key algorithm %u not supported\n", ret );
|
||||||
pgnutls_pkcs12_deinit( p12 );
|
pgnutls_pkcs12_deinit( p12 );
|
||||||
return FALSE;
|
return STATUS_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
|
|
||||||
store_data = malloc( sizeof(*store_data) );
|
store_data = malloc( sizeof(*store_data) );
|
||||||
|
@ -303,43 +303,59 @@ static BOOL WINAPI open_cert_store( CRYPT_DATA_BLOB *pfx, const WCHAR *password,
|
||||||
store_data->chain = chain;
|
store_data->chain = chain;
|
||||||
store_data->key_bitlen = bitlen;
|
store_data->key_bitlen = bitlen;
|
||||||
store_data->chain_len = chain_len;
|
store_data->chain_len = chain_len;
|
||||||
*data_ret = store_data;
|
*params->data_ret = store_data;
|
||||||
return TRUE;
|
return STATUS_SUCCESS;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
pgnutls_perror( ret );
|
pgnutls_perror( ret );
|
||||||
pgnutls_pkcs12_deinit( p12 );
|
pgnutls_pkcs12_deinit( p12 );
|
||||||
free( pwd );
|
free( pwd );
|
||||||
return FALSE;
|
return STATUS_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
|
|
||||||
static NTSTATUS WINAPI import_store_cert( struct cert_store_data *data, unsigned int index,
|
static NTSTATUS import_store_cert( void *args )
|
||||||
void *buf, DWORD *buf_size )
|
|
||||||
{
|
{
|
||||||
|
struct import_store_cert_params *params = args;
|
||||||
|
struct cert_store_data *data = params->data;
|
||||||
size_t size = 0;
|
size_t size = 0;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (index >= data->chain_len) return STATUS_NO_MORE_ENTRIES;
|
if (params->index >= data->chain_len) return STATUS_NO_MORE_ENTRIES;
|
||||||
|
|
||||||
if ((ret = pgnutls_x509_crt_export( data->chain[index], GNUTLS_X509_FMT_DER, NULL, &size )) != GNUTLS_E_SHORT_MEMORY_BUFFER)
|
if ((ret = pgnutls_x509_crt_export( data->chain[params->index], GNUTLS_X509_FMT_DER, NULL, &size )) != GNUTLS_E_SHORT_MEMORY_BUFFER)
|
||||||
return STATUS_INVALID_PARAMETER;
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
|
||||||
if (!buf || *buf_size < size)
|
if (!params->buf || *params->buf_size < size)
|
||||||
{
|
{
|
||||||
*buf_size = size;
|
*params->buf_size = size;
|
||||||
return STATUS_BUFFER_TOO_SMALL;
|
return STATUS_BUFFER_TOO_SMALL;
|
||||||
}
|
}
|
||||||
if ((ret = pgnutls_x509_crt_export( data->chain[index], GNUTLS_X509_FMT_DER, buf, &size )) < 0)
|
if ((ret = pgnutls_x509_crt_export( data->chain[params->index], GNUTLS_X509_FMT_DER, params->buf, &size )) < 0)
|
||||||
return STATUS_INVALID_PARAMETER;
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void WINAPI close_cert_store( struct cert_store_data *data )
|
static NTSTATUS close_cert_store( void *args )
|
||||||
{
|
{
|
||||||
pgnutls_pkcs12_deinit( data->p12 );
|
struct close_cert_store_params *params = args;
|
||||||
free( data );
|
|
||||||
|
if (params->data)
|
||||||
|
{
|
||||||
|
pgnutls_pkcs12_deinit( params->data->p12 );
|
||||||
|
free( params->data );
|
||||||
}
|
}
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else /* SONAME_LIBGNUTLS */
|
||||||
|
|
||||||
|
static NTSTATUS process_attach( void *args ) { return STATUS_SUCCESS; }
|
||||||
|
static NTSTATUS process_detach( void *args ) { return STATUS_SUCCESS; }
|
||||||
|
static NTSTATUS open_cert_store( void *args ) { return STATUS_DLL_NOT_FOUND; }
|
||||||
|
static NTSTATUS import_store_key( void *args ) { return STATUS_DLL_NOT_FOUND; }
|
||||||
|
static NTSTATUS import_store_cert( void *args ) { return STATUS_DLL_NOT_FOUND; }
|
||||||
|
static NTSTATUS close_cert_store( void *args ) { return STATUS_DLL_NOT_FOUND; }
|
||||||
|
|
||||||
#endif /* SONAME_LIBGNUTLS */
|
#endif /* SONAME_LIBGNUTLS */
|
||||||
|
|
||||||
|
@ -640,8 +656,9 @@ static void load_root_certs(void)
|
||||||
import_certs_from_path( CRYPT_knownLocations[i], TRUE );
|
import_certs_from_path( CRYPT_knownLocations[i], TRUE );
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL WINAPI enum_root_certs( void *buffer, SIZE_T size, SIZE_T *needed )
|
static NTSTATUS enum_root_certs( void *args )
|
||||||
{
|
{
|
||||||
|
struct enum_root_certs_params *params = args;
|
||||||
static BOOL loaded;
|
static BOOL loaded;
|
||||||
struct list *ptr;
|
struct list *ptr;
|
||||||
struct root_cert *cert;
|
struct root_cert *cert;
|
||||||
|
@ -649,45 +666,25 @@ static BOOL WINAPI enum_root_certs( void *buffer, SIZE_T size, SIZE_T *needed )
|
||||||
if (!loaded) load_root_certs();
|
if (!loaded) load_root_certs();
|
||||||
loaded = TRUE;
|
loaded = TRUE;
|
||||||
|
|
||||||
if (!(ptr = list_head( &root_cert_list ))) return FALSE;
|
if (!(ptr = list_head( &root_cert_list ))) return STATUS_NO_MORE_ENTRIES;
|
||||||
cert = LIST_ENTRY( ptr, struct root_cert, entry );
|
cert = LIST_ENTRY( ptr, struct root_cert, entry );
|
||||||
*needed = cert->size;
|
*params->needed = cert->size;
|
||||||
if (cert->size <= size)
|
if (cert->size <= params->size)
|
||||||
{
|
{
|
||||||
memcpy( buffer, cert->data, cert->size );
|
memcpy( params->buffer, cert->data, cert->size );
|
||||||
list_remove( &cert->entry );
|
list_remove( &cert->entry );
|
||||||
free( cert );
|
free( cert );
|
||||||
}
|
}
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct unix_funcs funcs =
|
|
||||||
{
|
|
||||||
enum_root_certs,
|
|
||||||
NULL
|
|
||||||
};
|
|
||||||
|
|
||||||
NTSTATUS CDECL __wine_init_unix_lib( HMODULE module, DWORD reason, const void *ptr_in, void *ptr_out )
|
|
||||||
{
|
|
||||||
switch (reason)
|
|
||||||
{
|
|
||||||
case DLL_PROCESS_ATTACH:
|
|
||||||
#ifdef SONAME_LIBGNUTLS
|
|
||||||
if (gnutls_initialize())
|
|
||||||
{
|
|
||||||
funcs.open_cert_store = open_cert_store;
|
|
||||||
funcs.import_store_key = import_store_key;
|
|
||||||
funcs.import_store_cert = import_store_cert;
|
|
||||||
funcs.close_cert_store = close_cert_store;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
*(const struct unix_funcs **)ptr_out = &funcs;
|
|
||||||
break;
|
|
||||||
case DLL_PROCESS_DETACH:
|
|
||||||
#ifdef SONAME_LIBGNUTLS
|
|
||||||
if (libgnutls_handle) gnutls_uninitialize();
|
|
||||||
#endif
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unixlib_entry_t __wine_unix_call_funcs[] =
|
||||||
|
{
|
||||||
|
process_attach,
|
||||||
|
process_detach,
|
||||||
|
open_cert_store,
|
||||||
|
import_store_key,
|
||||||
|
import_store_cert,
|
||||||
|
close_cert_store,
|
||||||
|
enum_root_certs,
|
||||||
|
};
|
||||||
|
|
Loading…
Reference in New Issue