secur32: Add support for SECPKG_ATTR_KEY_INFO.

Signed-off-by: Akihiro Sagawa <sagawa.aki@gmail.com>
Signed-off-by: Jacek Caban <jacek@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Akihiro Sagawa 2017-04-24 17:31:44 +02:00 committed by Alexandre Julliard
parent 250d65d68c
commit b6d32239d6
5 changed files with 82 additions and 1 deletions

View File

@ -962,6 +962,33 @@ static SECURITY_STATUS SEC_ENTRY schan_InitializeSecurityContextA(
return ret;
}
static void *get_alg_name(ALG_ID id, BOOL wide)
{
static const struct {
ALG_ID alg_id;
const char* name;
const WCHAR nameW[8];
} alg_name_map[] = {
{ CALG_ECDSA, "ECDSA", {'E','C','D','S','A',0} },
{ CALG_RSA_SIGN, "RSA", {'R','S','A',0} },
{ CALG_DES, "DES", {'D','E','S',0} },
{ CALG_RC2, "RC2", {'R','C','2',0} },
{ CALG_3DES, "3DES", {'3','D','E','S',0} },
{ CALG_AES_128, "AES", {'A','E','S',0} },
{ CALG_AES_192, "AES", {'A','E','S',0} },
{ CALG_AES_256, "AES", {'A','E','S',0} },
{ CALG_RC4, "RC4", {'R','C','4',0} },
};
unsigned i;
for (i = 0; i < sizeof(alg_name_map)/sizeof(alg_name_map[0]); i++)
if (alg_name_map[i].alg_id == id)
return wide ? (void*)alg_name_map[i].nameW : (void*)alg_name_map[i].name;
FIXME("Unknown ALG_ID %04x\n", id);
return NULL;
}
static SECURITY_STATUS ensure_remote_cert(struct schan_context *ctx)
{
HCERTSTORE cert_store;
@ -1016,6 +1043,21 @@ static SECURITY_STATUS SEC_ENTRY schan_QueryContextAttributesW(
return status;
}
case SECPKG_ATTR_KEY_INFO:
{
SecPkgContext_ConnectionInfo conn_info;
SECURITY_STATUS status = schan_imp_get_connection_info(ctx->session, &conn_info);
if (status == SEC_E_OK)
{
SecPkgContext_KeyInfoW *info = buffer;
info->KeySize = conn_info.dwCipherStrength;
info->SignatureAlgorithm = schan_imp_get_key_signature_algorithm(ctx->session);
info->EncryptAlgorithm = conn_info.aiCipher;
info->sSignatureAlgorithmName = get_alg_name(info->SignatureAlgorithm, TRUE);
info->sEncryptAlgorithmName = get_alg_name(info->EncryptAlgorithm, TRUE);
}
return status;
}
case SECPKG_ATTR_REMOTE_CERT_CONTEXT:
{
PCCERT_CONTEXT *cert = buffer;
@ -1091,6 +1133,17 @@ static SECURITY_STATUS SEC_ENTRY schan_QueryContextAttributesA(
{
case SECPKG_ATTR_STREAM_SIZES:
return schan_QueryContextAttributesW(context_handle, attribute, buffer);
case SECPKG_ATTR_KEY_INFO:
{
SECURITY_STATUS status = schan_QueryContextAttributesW(context_handle, attribute, buffer);
if (status == SEC_E_OK)
{
SecPkgContext_KeyInfoA *info = buffer;
info->sSignatureAlgorithmName = get_alg_name(info->SignatureAlgorithm, FALSE);
info->sEncryptAlgorithmName = get_alg_name(info->EncryptAlgorithm, FALSE);
}
return status;
}
case SECPKG_ATTR_REMOTE_CERT_CONTEXT:
return schan_QueryContextAttributesW(context_handle, attribute, buffer);
case SECPKG_ATTR_CONNECTION_INFO:

View File

@ -383,6 +383,27 @@ SECURITY_STATUS schan_imp_get_connection_info(schan_imp_session session,
return SEC_E_OK;
}
ALG_ID schan_imp_get_key_signature_algorithm(schan_imp_session session)
{
gnutls_session_t s = (gnutls_session_t)session;
gnutls_kx_algorithm_t kx = pgnutls_kx_get(s);
TRACE("(%p)\n", session);
switch (kx)
{
case GNUTLS_KX_UNKNOWN: return 0;
case GNUTLS_KX_RSA:
case GNUTLS_KX_RSA_EXPORT:
case GNUTLS_KX_DHE_RSA:
case GNUTLS_KX_ECDHE_RSA: return CALG_RSA_SIGN;
case GNUTLS_KX_ECDHE_ECDSA: return CALG_ECDSA;
default:
FIXME("unknown algorithm %d\n", kx);
return 0;
}
}
SECURITY_STATUS schan_imp_get_session_peer_certificate(schan_imp_session session, HCERTSTORE store,
PCCERT_CONTEXT *ret)
{

View File

@ -914,6 +914,12 @@ unsigned int schan_imp_get_max_message_size(schan_imp_session session)
return 1 << 14;
}
ALG_ID schan_imp_get_key_signature_algorithm(schan_imp_session session)
{
FIXME("(%p)\n", session);
return 0;
}
SECURITY_STATUS schan_imp_get_connection_info(schan_imp_session session,
SecPkgContext_ConnectionInfo *info)
{

View File

@ -252,6 +252,7 @@ extern void schan_imp_set_session_target(schan_imp_session session, const char *
extern SECURITY_STATUS schan_imp_handshake(schan_imp_session session) DECLSPEC_HIDDEN;
extern unsigned int schan_imp_get_session_cipher_block_size(schan_imp_session session) DECLSPEC_HIDDEN;
extern unsigned int schan_imp_get_max_message_size(schan_imp_session session) DECLSPEC_HIDDEN;
extern ALG_ID schan_imp_get_key_signature_algorithm(schan_imp_session session) DECLSPEC_HIDDEN;
extern SECURITY_STATUS schan_imp_get_connection_info(schan_imp_session session,
SecPkgContext_ConnectionInfo *info) DECLSPEC_HIDDEN;
extern SECURITY_STATUS schan_imp_get_session_peer_certificate(schan_imp_session session, HCERTSTORE,

View File

@ -925,7 +925,7 @@ todo_wine
}
status = pQueryContextAttributesA(&context, SECPKG_ATTR_KEY_INFO, &key_info);
todo_wine ok(status == SEC_E_OK, "QueryContextAttributesW(SECPKG_ATTR_KEY_INFO) failed: %08x\n", status);
ok(status == SEC_E_OK, "QueryContextAttributesW(SECPKG_ATTR_KEY_INFO) failed: %08x\n", status);
if(status == SEC_E_OK) {
ok(broken(key_info.SignatureAlgorithm == 0 /* WinXP,2003 */) ||
key_info.SignatureAlgorithm == CALG_RSA_SIGN,