Jacek Caban : secur32: Return a cert context with context store in SECPKG_ATTR_REMOTE_CERT_CONTEXT GnuTLS implementation .

Alexandre Julliard julliard at winehq.org
Mon Jan 21 13:52:24 CST 2013


Module: wine
Branch: master
Commit: 5c5d12c8bc400c8a57771defa4bc5c0523b0a4a7
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=5c5d12c8bc400c8a57771defa4bc5c0523b0a4a7

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Mon Jan 21 15:03:36 2013 +0100

secur32: Return a cert context with context store in SECPKG_ATTR_REMOTE_CERT_CONTEXT GnuTLS implementation.

---

 dlls/secur32/schannel.c        |   13 ++++++++++++-
 dlls/secur32/schannel_gnutls.c |   30 ++++++++++++++++++------------
 dlls/secur32/schannel_macosx.c |    2 +-
 dlls/secur32/secur32_priv.h    |    2 +-
 4 files changed, 32 insertions(+), 15 deletions(-)

diff --git a/dlls/secur32/schannel.c b/dlls/secur32/schannel.c
index cc287dc..37af15e 100644
--- a/dlls/secur32/schannel.c
+++ b/dlls/secur32/schannel.c
@@ -60,6 +60,7 @@ struct schan_context
 {
     schan_imp_session session;
     ULONG req_ctx_attr;
+    HCERTSTORE cert_store;
 };
 
 static struct schan_handle *schan_handle_table;
@@ -696,6 +697,7 @@ static SECURITY_STATUS SEC_ENTRY schan_InitializeSecurityContextW(
         ctx = HeapAlloc(GetProcessHeap(), 0, sizeof(*ctx));
         if (!ctx) return SEC_E_INSUFFICIENT_MEMORY;
 
+        ctx->cert_store = NULL;
         handle = schan_alloc_handle(ctx, SCHAN_HANDLE_CTX);
         if (handle == SCHAN_INVALID_HANDLE)
         {
@@ -859,7 +861,14 @@ static SECURITY_STATUS SEC_ENTRY schan_QueryContextAttributesW(
         case SECPKG_ATTR_REMOTE_CERT_CONTEXT:
         {
             PCCERT_CONTEXT *cert = buffer;
-            return schan_imp_get_session_peer_certificate(ctx->session, cert);
+
+            if (!ctx->cert_store) {
+                ctx->cert_store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, CERT_STORE_CREATE_NEW_FLAG, NULL);
+                if(!ctx->cert_store)
+                    return GetLastError();
+            }
+
+            return schan_imp_get_session_peer_certificate(ctx->session, ctx->cert_store, cert);
         }
         case SECPKG_ATTR_CONNECTION_INFO:
         {
@@ -1167,6 +1176,8 @@ static SECURITY_STATUS SEC_ENTRY schan_DeleteSecurityContext(PCtxtHandle context
     ctx = schan_free_handle(context_handle->dwLower, SCHAN_HANDLE_CTX);
     if (!ctx) return SEC_E_INVALID_HANDLE;
 
+    if (ctx->cert_store)
+        CertCloseStore(ctx->cert_store, 0);
     schan_imp_dispose_session(ctx->session);
     HeapFree(GetProcessHeap(), 0, ctx);
 
diff --git a/dlls/secur32/schannel_gnutls.c b/dlls/secur32/schannel_gnutls.c
index bb481b7..fa68591 100644
--- a/dlls/secur32/schannel_gnutls.c
+++ b/dlls/secur32/schannel_gnutls.c
@@ -318,25 +318,31 @@ SECURITY_STATUS schan_imp_get_connection_info(schan_imp_session session,
     return SEC_E_OK;
 }
 
-SECURITY_STATUS schan_imp_get_session_peer_certificate(schan_imp_session session,
-                                                       PCCERT_CONTEXT *cert)
+SECURITY_STATUS schan_imp_get_session_peer_certificate(schan_imp_session session, HCERTSTORE store,
+                                                       PCCERT_CONTEXT *ret)
 {
     gnutls_session_t s = (gnutls_session_t)session;
-    unsigned int list_size;
+    PCCERT_CONTEXT cert = NULL;
     const gnutls_datum_t *datum;
+    unsigned list_size, i;
+    BOOL res;
 
     datum = pgnutls_certificate_get_peers(s, &list_size);
-    if (datum)
-    {
-        *cert = CertCreateCertificateContext(X509_ASN_ENCODING, datum->data,
-                                             datum->size);
-        if (!*cert)
+    if(!datum)
+        return SEC_E_INTERNAL_ERROR;
+
+    for(i = 0; i < list_size; i++) {
+        res = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING, datum[i].data, datum[i].size,
+                CERT_STORE_ADD_REPLACE_EXISTING, i ? NULL : &cert);
+        if(!res) {
+            if(i)
+                CertFreeCertificateContext(cert);
             return GetLastError();
-        else
-            return SEC_E_OK;
+        }
     }
-    else
-        return SEC_E_INTERNAL_ERROR;
+
+    *ret = cert;
+    return SEC_E_OK;
 }
 
 SECURITY_STATUS schan_imp_send(schan_imp_session session, const void *buffer,
diff --git a/dlls/secur32/schannel_macosx.c b/dlls/secur32/schannel_macosx.c
index 75fe9a0..2d03d2a 100644
--- a/dlls/secur32/schannel_macosx.c
+++ b/dlls/secur32/schannel_macosx.c
@@ -706,7 +706,7 @@ static void schan_imp_cf_release(const void *arg, void *ctx)
 }
 #endif
 
-SECURITY_STATUS schan_imp_get_session_peer_certificate(schan_imp_session session,
+SECURITY_STATUS schan_imp_get_session_peer_certificate(schan_imp_session session, HCERTSTORE cert_store,
                                                        PCCERT_CONTEXT *cert)
 {
     struct mac_session* s = (struct mac_session*)session;
diff --git a/dlls/secur32/secur32_priv.h b/dlls/secur32/secur32_priv.h
index 3254e0b..164a2eb 100644
--- a/dlls/secur32/secur32_priv.h
+++ b/dlls/secur32/secur32_priv.h
@@ -247,7 +247,7 @@ extern unsigned int schan_imp_get_session_cipher_block_size(schan_imp_session se
 extern unsigned int schan_imp_get_max_message_size(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,
+extern SECURITY_STATUS schan_imp_get_session_peer_certificate(schan_imp_session session, HCERTSTORE,
                                                               PCCERT_CONTEXT *cert) DECLSPEC_HIDDEN;
 extern SECURITY_STATUS schan_imp_send(schan_imp_session session, const void *buffer,
                                       SIZE_T *length) DECLSPEC_HIDDEN;




More information about the wine-cvs mailing list