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

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


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

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

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

---

 dlls/secur32/schannel_macosx.c |   76 +++++++++++++++++++++++----------------
 1 files changed, 45 insertions(+), 31 deletions(-)

diff --git a/dlls/secur32/schannel_macosx.c b/dlls/secur32/schannel_macosx.c
index 2d03d2a..aaf2532 100644
--- a/dlls/secur32/schannel_macosx.c
+++ b/dlls/secur32/schannel_macosx.c
@@ -706,53 +706,67 @@ static void schan_imp_cf_release(const void *arg, void *ctx)
 }
 #endif
 
-SECURITY_STATUS schan_imp_get_session_peer_certificate(schan_imp_session session, HCERTSTORE cert_store,
-                                                       PCCERT_CONTEXT *cert)
+SECURITY_STATUS schan_imp_get_session_peer_certificate(schan_imp_session session, HCERTSTORE store,
+                                                       PCCERT_CONTEXT *ret_cert)
 {
     struct mac_session* s = (struct mac_session*)session;
-    SECURITY_STATUS ret = SEC_E_INTERNAL_ERROR;
-    CFArrayRef certs;
+    SECURITY_STATUS ret = SEC_E_OK;
+    PCCERT_CONTEXT cert = NULL;
+    SecCertificateRef mac_cert;
+    CFArrayRef cert_array;
     OSStatus status;
+    CFIndex cnt, i;
+    CFDataRef data;
+    BOOL res;
 
     TRACE("(%p/%p, %p)\n", s, s->context, cert);
 
 #ifdef HAVE_SSLCOPYPEERCERTIFICATES
-    status = SSLCopyPeerCertificates(s->context, &certs);
+    status = SSLCopyPeerCertificates(s->context, &cert_array);
 #else
-    status = SSLGetPeerCertificates(s->context, &certs);
+    status = SSLGetPeerCertificates(s->context, &cert_array);
 #endif
-    if (status == noErr && certs)
+    if (status != noErr || !cert_array)
     {
-        SecCertificateRef mac_cert;
-        CFDataRef data;
-        if (CFArrayGetCount(certs) &&
-            (mac_cert = (SecCertificateRef)CFArrayGetValueAtIndex(certs, 0)) &&
-            (SecKeychainItemExport(mac_cert, kSecFormatX509Cert, 0, NULL, &data) == noErr))
+        WARN("SSLCopyPeerCertificates failed: %ld\n", (long)status);
+        return SEC_E_INTERNAL_ERROR;
+    }
+
+    cnt = CFArrayGetCount(cert_array);
+    for (i=0; i < cnt; i++) {
+        if (!(mac_cert = (SecCertificateRef)CFArrayGetValueAtIndex(cert_array, i)) ||
+            (SecKeychainItemExport(mac_cert, kSecFormatX509Cert, 0, NULL, &data) != noErr))
         {
-            *cert = CertCreateCertificateContext(X509_ASN_ENCODING,
-                    CFDataGetBytePtr(data), CFDataGetLength(data));
-            if (*cert)
-                ret = SEC_E_OK;
-            else
-            {
-                ret = GetLastError();
-                WARN("CertCreateCertificateContext failed: %x\n", ret);
-            }
-            CFRelease(data);
-        }
-        else
             WARN("Couldn't extract certificate data\n");
+            ret = SEC_E_INTERNAL_ERROR;
+            break;
+        }
+
+        res = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING, CFDataGetBytePtr(data), CFDataGetLength(data),
+                                               CERT_STORE_ADD_REPLACE_EXISTING, i ? NULL : &cert);
+        CFRelease(data);
+        if (!res)
+        {
+            ret = GetLastError();
+            WARN("CertAddEncodedCertificateToStore failed: %x\n", ret);
+            break;
+        }
+    }
+
 #ifndef HAVE_SSLCOPYPEERCERTIFICATES
-        /* This is why SSLGetPeerCertificates was deprecated */
-        CFArrayApplyFunction(certs, CFRangeMake(0, CFArrayGetCount(certs)),
-                             schan_imp_cf_release, NULL);
+    /* This is why SSLGetPeerCertificates was deprecated */
+    CFArrayApplyFunction(cert_array, CFRangeMake(0, CFArrayGetCount(cert_array)),
+                         schan_imp_cf_release, NULL);
 #endif
-        CFRelease(certs);
+    CFRelease(cert_array);
+    if (ret != SEC_E_OK) {
+        if(cert)
+            CertFreeCertificateContext(cert);
+        return ret;
     }
-    else
-        WARN("SSLCopyPeerCertificates failed: %ld\n", (long)status);
 
-    return ret;
+    *ret_cert = cert;
+    return SEC_E_OK;
 }
 
 SECURITY_STATUS schan_imp_send(schan_imp_session session, const void *buffer,




More information about the wine-cvs mailing list