Commit 303ec3ef authored by Jacek Caban's avatar Jacek Caban Committed by Alexandre Julliard

secur32: Return a cert context with context store in…

secur32: Return a cert context with context store in SECPKG_ATTR_REMOTE_CERT_CONTEXT MacOSX implementation.
parent 5c5d12c8
...@@ -706,53 +706,67 @@ static void schan_imp_cf_release(const void *arg, void *ctx) ...@@ -706,53 +706,67 @@ static void schan_imp_cf_release(const void *arg, void *ctx)
} }
#endif #endif
SECURITY_STATUS schan_imp_get_session_peer_certificate(schan_imp_session session, HCERTSTORE cert_store, SECURITY_STATUS schan_imp_get_session_peer_certificate(schan_imp_session session, HCERTSTORE store,
PCCERT_CONTEXT *cert) PCCERT_CONTEXT *ret_cert)
{ {
struct mac_session* s = (struct mac_session*)session; struct mac_session* s = (struct mac_session*)session;
SECURITY_STATUS ret = SEC_E_INTERNAL_ERROR; SECURITY_STATUS ret = SEC_E_OK;
CFArrayRef certs; PCCERT_CONTEXT cert = NULL;
SecCertificateRef mac_cert;
CFArrayRef cert_array;
OSStatus status; OSStatus status;
CFIndex cnt, i;
CFDataRef data;
BOOL res;
TRACE("(%p/%p, %p)\n", s, s->context, cert); TRACE("(%p/%p, %p)\n", s, s->context, cert);
#ifdef HAVE_SSLCOPYPEERCERTIFICATES #ifdef HAVE_SSLCOPYPEERCERTIFICATES
status = SSLCopyPeerCertificates(s->context, &certs); status = SSLCopyPeerCertificates(s->context, &cert_array);
#else #else
status = SSLGetPeerCertificates(s->context, &certs); status = SSLGetPeerCertificates(s->context, &cert_array);
#endif #endif
if (status == noErr && certs) if (status != noErr || !cert_array)
{ {
SecCertificateRef mac_cert; WARN("SSLCopyPeerCertificates failed: %ld\n", (long)status);
CFDataRef data; return SEC_E_INTERNAL_ERROR;
if (CFArrayGetCount(certs) && }
(mac_cert = (SecCertificateRef)CFArrayGetValueAtIndex(certs, 0)) &&
(SecKeychainItemExport(mac_cert, kSecFormatX509Cert, 0, NULL, &data) == noErr)) 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"); 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 #ifndef HAVE_SSLCOPYPEERCERTIFICATES
/* This is why SSLGetPeerCertificates was deprecated */ /* This is why SSLGetPeerCertificates was deprecated */
CFArrayApplyFunction(certs, CFRangeMake(0, CFArrayGetCount(certs)), CFArrayApplyFunction(cert_array, CFRangeMake(0, CFArrayGetCount(cert_array)),
schan_imp_cf_release, NULL); schan_imp_cf_release, NULL);
#endif #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, SECURITY_STATUS schan_imp_send(schan_imp_session session, const void *buffer,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment