crypt32: Set key context if PKCS12_NO_PERSIST_KEY is passed, otherwise set key provider info.
Signed-off-by: Hans Leidekker <hans@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
b68b58e604
commit
4e11e6e045
|
@ -256,6 +256,77 @@ static char *password_to_ascii( const WCHAR *str )
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static BOOL set_key_context( const void *ctx, HCRYPTPROV prov )
|
||||||
|
{
|
||||||
|
CERT_KEY_CONTEXT key_ctx;
|
||||||
|
key_ctx.cbSize = sizeof(key_ctx);
|
||||||
|
key_ctx.hCryptProv = prov;
|
||||||
|
key_ctx.dwKeySpec = AT_KEYEXCHANGE;
|
||||||
|
return CertSetCertificateContextProperty( ctx, CERT_KEY_CONTEXT_PROP_ID, 0, &key_ctx );
|
||||||
|
}
|
||||||
|
|
||||||
|
static WCHAR *get_provider_property( HCRYPTPROV prov, DWORD prop_id, DWORD *len )
|
||||||
|
{
|
||||||
|
DWORD size = 0;
|
||||||
|
WCHAR *ret;
|
||||||
|
char *str;
|
||||||
|
|
||||||
|
CryptGetProvParam( prov, prop_id, NULL, &size, 0 );
|
||||||
|
if (!size) return NULL;
|
||||||
|
if (!(str = CryptMemAlloc( size ))) return NULL;
|
||||||
|
CryptGetProvParam( prov, prop_id, (BYTE *)str, &size, 0 );
|
||||||
|
|
||||||
|
*len = MultiByteToWideChar( CP_ACP, 0, str, -1, NULL, 0 );
|
||||||
|
if ((ret = CryptMemAlloc( *len * sizeof(WCHAR) ))) MultiByteToWideChar( CP_ACP, 0, str, -1, ret, *len );
|
||||||
|
CryptMemFree( str );
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static BOOL set_key_prov_info( const void *ctx, HCRYPTPROV prov )
|
||||||
|
{
|
||||||
|
CRYPT_KEY_PROV_INFO *prov_info;
|
||||||
|
DWORD size, len_container, len_name;
|
||||||
|
WCHAR *ptr, *container, *name;
|
||||||
|
BOOL ret;
|
||||||
|
|
||||||
|
if (!(container = get_provider_property( prov, PP_CONTAINER, &len_container ))) return FALSE;
|
||||||
|
if (!(name = get_provider_property( prov, PP_NAME, &len_name )))
|
||||||
|
{
|
||||||
|
CryptMemFree( container );
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
if (!(prov_info = CryptMemAlloc( sizeof(*prov_info) + (len_container + len_name) * sizeof(WCHAR) )))
|
||||||
|
{
|
||||||
|
CryptMemFree( container );
|
||||||
|
CryptMemFree( name );
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
ptr = (WCHAR *)(prov_info + 1);
|
||||||
|
prov_info->pwszContainerName = ptr;
|
||||||
|
strcpyW( prov_info->pwszContainerName, container );
|
||||||
|
|
||||||
|
ptr += len_container;
|
||||||
|
prov_info->pwszProvName = ptr;
|
||||||
|
strcpyW( prov_info->pwszProvName, name );
|
||||||
|
|
||||||
|
size = sizeof(prov_info->dwProvType);
|
||||||
|
CryptGetProvParam( prov, PP_PROVTYPE, (BYTE *)&prov_info->dwProvType, &size, 0 );
|
||||||
|
|
||||||
|
prov_info->dwFlags = 0;
|
||||||
|
prov_info->cProvParam = 0;
|
||||||
|
prov_info->rgProvParam = NULL;
|
||||||
|
size = sizeof(prov_info->dwKeySpec);
|
||||||
|
CryptGetProvParam( prov, PP_KEYSPEC, (BYTE *)&prov_info->dwKeySpec, &size, 0 );
|
||||||
|
|
||||||
|
ret = CertSetCertificateContextProperty( ctx, CERT_KEY_PROV_INFO_PROP_ID, 0, prov_info );
|
||||||
|
|
||||||
|
CryptMemFree( prov_info );
|
||||||
|
CryptMemFree( name );
|
||||||
|
CryptMemFree( container );
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
HCERTSTORE WINAPI PFXImportCertStore( CRYPT_DATA_BLOB *pfx, const WCHAR *password, DWORD flags )
|
HCERTSTORE WINAPI PFXImportCertStore( CRYPT_DATA_BLOB *pfx, const WCHAR *password, DWORD flags )
|
||||||
{
|
{
|
||||||
#ifdef SONAME_LIBGNUTLS
|
#ifdef SONAME_LIBGNUTLS
|
||||||
|
@ -265,7 +336,6 @@ HCERTSTORE WINAPI PFXImportCertStore( CRYPT_DATA_BLOB *pfx, const WCHAR *passwor
|
||||||
gnutls_x509_crt_t *chain;
|
gnutls_x509_crt_t *chain;
|
||||||
unsigned int chain_len, i;
|
unsigned int chain_len, i;
|
||||||
HCERTSTORE store = NULL;
|
HCERTSTORE store = NULL;
|
||||||
CERT_KEY_CONTEXT key_ctx;
|
|
||||||
HCRYPTPROV prov = 0;
|
HCRYPTPROV prov = 0;
|
||||||
char *pwd = NULL;
|
char *pwd = NULL;
|
||||||
int ret;
|
int ret;
|
||||||
|
@ -339,16 +409,21 @@ HCERTSTORE WINAPI PFXImportCertStore( CRYPT_DATA_BLOB *pfx, const WCHAR *passwor
|
||||||
}
|
}
|
||||||
heap_free( crt_data );
|
heap_free( crt_data );
|
||||||
|
|
||||||
key_ctx.cbSize = sizeof(key_ctx);
|
if (flags & PKCS12_NO_PERSIST_KEY)
|
||||||
key_ctx.hCryptProv = prov;
|
|
||||||
key_ctx.dwKeySpec = AT_KEYEXCHANGE;
|
|
||||||
if (!CertSetCertificateContextProperty( ctx, CERT_KEY_CONTEXT_PROP_ID, 0, &key_ctx ))
|
|
||||||
{
|
{
|
||||||
WARN( "CertSetCertificateContextProperty failed %08x\n", GetLastError() );
|
if (!set_key_context( ctx, prov ))
|
||||||
|
{
|
||||||
|
WARN( "failed to set context property %08x\n", GetLastError() );
|
||||||
|
CertFreeCertificateContext( ctx );
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (!set_key_prov_info( ctx, prov ))
|
||||||
|
{
|
||||||
|
WARN( "failed to set provider info property %08x\n", GetLastError() );
|
||||||
CertFreeCertificateContext( ctx );
|
CertFreeCertificateContext( ctx );
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!CertAddCertificateContextToStore( store, ctx, CERT_STORE_ADD_ALWAYS, NULL ))
|
if (!CertAddCertificateContextToStore( store, ctx, CERT_STORE_ADD_ALWAYS, NULL ))
|
||||||
{
|
{
|
||||||
WARN( "CertAddCertificateContextToStore failed %08x\n", GetLastError() );
|
WARN( "CertAddCertificateContextToStore failed %08x\n", GetLastError() );
|
||||||
|
|
|
@ -3286,7 +3286,8 @@ static void test_PFXImportCertStore(void)
|
||||||
CRYPT_DATA_BLOB pfx;
|
CRYPT_DATA_BLOB pfx;
|
||||||
const CERT_CONTEXT *cert;
|
const CERT_CONTEXT *cert;
|
||||||
CERT_KEY_CONTEXT key;
|
CERT_KEY_CONTEXT key;
|
||||||
CRYPT_KEY_PROV_INFO keyprov;
|
char buf[512];
|
||||||
|
CRYPT_KEY_PROV_INFO *keyprov = (CRYPT_KEY_PROV_INFO *)buf;
|
||||||
CERT_INFO *info;
|
CERT_INFO *info;
|
||||||
DWORD count, size;
|
DWORD count, size;
|
||||||
BOOL ret;
|
BOOL ret;
|
||||||
|
@ -3299,7 +3300,7 @@ static void test_PFXImportCertStore(void)
|
||||||
pfx.pbData = (BYTE *)pfxdata;
|
pfx.pbData = (BYTE *)pfxdata;
|
||||||
pfx.cbData = sizeof(pfxdata);
|
pfx.cbData = sizeof(pfxdata);
|
||||||
store = PFXImportCertStore( &pfx, NULL, CRYPT_EXPORTABLE|CRYPT_USER_KEYSET|PKCS12_NO_PERSIST_KEY );
|
store = PFXImportCertStore( &pfx, NULL, CRYPT_EXPORTABLE|CRYPT_USER_KEYSET|PKCS12_NO_PERSIST_KEY );
|
||||||
ok( store != NULL || broken(store == NULL) /* winxp */, "got %p\n", store );
|
ok( store != NULL || broken(store == NULL) /* winxp */, "got %u\n", GetLastError() );
|
||||||
if (!store) return;
|
if (!store) return;
|
||||||
count = countCertsInStore( store );
|
count = countCertsInStore( store );
|
||||||
ok( count == 1, "got %u\n", count );
|
ok( count == 1, "got %u\n", count );
|
||||||
|
@ -3324,11 +3325,28 @@ static void test_PFXImportCertStore(void)
|
||||||
ok( key.hCryptProv, "hCryptProv not set\n" );
|
ok( key.hCryptProv, "hCryptProv not set\n" );
|
||||||
ok( key.dwKeySpec == AT_KEYEXCHANGE, "got %u\n", key.dwKeySpec );
|
ok( key.dwKeySpec == AT_KEYEXCHANGE, "got %u\n", key.dwKeySpec );
|
||||||
|
|
||||||
size = sizeof(keyprov);
|
size = sizeof(buf);
|
||||||
SetLastError( 0xdeadbeef );
|
SetLastError( 0xdeadbeef );
|
||||||
ret = CertGetCertificateContextProperty( cert, CERT_KEY_PROV_INFO_PROP_ID, &keyprov, &size );
|
ret = CertGetCertificateContextProperty( cert, CERT_KEY_PROV_INFO_PROP_ID, keyprov, &size );
|
||||||
|
ok( !ret && GetLastError() == CRYPT_E_NOT_FOUND, "got %08x\n", GetLastError() );
|
||||||
|
CertFreeCertificateContext( cert );
|
||||||
|
CertCloseStore( store, 0 );
|
||||||
|
|
||||||
|
/* without PKCS12_NO_PERSIST_KEY */
|
||||||
|
store = PFXImportCertStore( &pfx, NULL, CRYPT_EXPORTABLE|CRYPT_USER_KEYSET );
|
||||||
|
ok( store != NULL, "got %u\n", GetLastError() );
|
||||||
|
|
||||||
|
cert = CertFindCertificateInStore( store, X509_ASN_ENCODING, 0, CERT_FIND_ANY, NULL, NULL );
|
||||||
|
ok( cert != NULL, "got %08x\n", GetLastError() );
|
||||||
|
|
||||||
|
size = sizeof(key);
|
||||||
|
ret = CertGetCertificateContextProperty( cert, CERT_KEY_CONTEXT_PROP_ID, &key, &size );
|
||||||
ok( !ret && GetLastError() == CRYPT_E_NOT_FOUND, "got %08x\n", GetLastError() );
|
ok( !ret && GetLastError() == CRYPT_E_NOT_FOUND, "got %08x\n", GetLastError() );
|
||||||
|
|
||||||
|
size = sizeof(buf);
|
||||||
|
ret = CertGetCertificateContextProperty( cert, CERT_KEY_PROV_INFO_PROP_ID, buf, &size );
|
||||||
|
ok(ret, "got %u\n", GetLastError());
|
||||||
|
CertFreeCertificateContext( cert );
|
||||||
CertCloseStore( store, 0 );
|
CertCloseStore( store, 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue