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