Akihiro Sagawa : secur32: Add support for SECPKG_ATTR_KEY_INFO.
Alexandre Julliard
julliard at winehq.org
Tue Apr 25 16:22:35 CDT 2017
Module: wine
Branch: master
Commit: b6d32239d6b84f6aec15b2b5691d8791f33dabd0
URL: http://source.winehq.org/git/wine.git/?a=commit;h=b6d32239d6b84f6aec15b2b5691d8791f33dabd0
Author: Akihiro Sagawa <sagawa.aki at gmail.com>
Date: Mon Apr 24 17:31:44 2017 +0200
secur32: Add support for SECPKG_ATTR_KEY_INFO.
Signed-off-by: Akihiro Sagawa <sagawa.aki at gmail.com>
Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/secur32/schannel.c | 53 ++++++++++++++++++++++++++++++++++++++++++
dlls/secur32/schannel_gnutls.c | 21 +++++++++++++++++
dlls/secur32/schannel_macosx.c | 6 +++++
dlls/secur32/secur32_priv.h | 1 +
dlls/secur32/tests/schannel.c | 2 +-
5 files changed, 82 insertions(+), 1 deletion(-)
diff --git a/dlls/secur32/schannel.c b/dlls/secur32/schannel.c
index 6914837..82374ef 100644
--- a/dlls/secur32/schannel.c
+++ b/dlls/secur32/schannel.c
@@ -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:
diff --git a/dlls/secur32/schannel_gnutls.c b/dlls/secur32/schannel_gnutls.c
index 33686bc..a028176 100644
--- a/dlls/secur32/schannel_gnutls.c
+++ b/dlls/secur32/schannel_gnutls.c
@@ -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)
{
diff --git a/dlls/secur32/schannel_macosx.c b/dlls/secur32/schannel_macosx.c
index 2c5896a..f397291 100644
--- a/dlls/secur32/schannel_macosx.c
+++ b/dlls/secur32/schannel_macosx.c
@@ -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)
{
diff --git a/dlls/secur32/secur32_priv.h b/dlls/secur32/secur32_priv.h
index 1baa543..9a60d65 100644
--- a/dlls/secur32/secur32_priv.h
+++ b/dlls/secur32/secur32_priv.h
@@ -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,
diff --git a/dlls/secur32/tests/schannel.c b/dlls/secur32/tests/schannel.c
index b12a739..b5ed169 100644
--- a/dlls/secur32/tests/schannel.c
+++ b/dlls/secur32/tests/schannel.c
@@ -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,
More information about the wine-cvs
mailing list