Commit bcc30639 authored by Alexandre Julliard's avatar Alexandre Julliard

secur32: Move the memory allocation for get_session_peer_certificate() to the PE side.

parent a4d69c87
......@@ -909,28 +909,37 @@ static SECURITY_STATUS ensure_remote_cert(struct schan_context *ctx)
HCERTSTORE store;
PCCERT_CONTEXT cert = NULL;
SECURITY_STATUS status;
struct schan_cert_list list;
CERT_BLOB *certs;
ULONG count, size = 0;
if (ctx->cert) return SEC_E_OK;
if (!(store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, CERT_STORE_CREATE_NEW_FLAG, NULL)))
return GetLastError();
if ((status = schan_funcs->get_session_peer_certificate(ctx->transport.session, &list)) == SEC_E_OK)
status = schan_funcs->get_session_peer_certificate(ctx->transport.session, NULL, &size, &count);
if (status != SEC_E_BUFFER_TOO_SMALL) goto done;
if (!(certs = malloc( size )))
{
status = SEC_E_INSUFFICIENT_MEMORY;
goto done;
}
status = schan_funcs->get_session_peer_certificate(ctx->transport.session, certs, &size, &count);
if (status == SEC_E_OK)
{
unsigned int i;
for (i = 0; i < list.count; i++)
for (i = 0; i < count; i++)
{
if (!CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING, list.certs[i].pbData,
list.certs[i].cbData, CERT_STORE_ADD_REPLACE_EXISTING,
if (!CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING, certs[i].pbData,
certs[i].cbData, CERT_STORE_ADD_REPLACE_EXISTING,
i ? NULL : &cert))
{
if (i) CertFreeCertificateContext(cert);
return GetLastError();
}
}
RtlFreeHeap(GetProcessHeap(), 0, list.certs);
}
free(certs);
done:
ctx->cert = cert;
CertCloseStore(store, 0);
return status;
......
......@@ -810,28 +810,36 @@ static ALG_ID CDECL schan_get_key_signature_algorithm(schan_session session)
}
}
static SECURITY_STATUS CDECL schan_get_session_peer_certificate(schan_session session, struct schan_cert_list *list)
static SECURITY_STATUS CDECL schan_get_session_peer_certificate(schan_session session, CERT_BLOB *certs,
ULONG *bufsize, ULONG *retcount)
{
gnutls_session_t s = (gnutls_session_t)session;
const gnutls_datum_t *datum;
unsigned int i, size;
BYTE *ptr;
unsigned int count;
if (!(datum = pgnutls_certificate_get_peers(s, &list->count))) return SEC_E_INTERNAL_ERROR;
if (!(datum = pgnutls_certificate_get_peers(s, &count))) return SEC_E_INTERNAL_ERROR;
size = list->count * sizeof(list->certs[0]);
for (i = 0; i < list->count; i++) size += datum[i].size;
if (!(list->certs = RtlAllocateHeap(GetProcessHeap(), 0, size))) return SEC_E_INSUFFICIENT_MEMORY;
size = count * sizeof(certs[0]);
for (i = 0; i < count; i++) size += datum[i].size;
ptr = (BYTE *)&list->certs[list->count];
for (i = 0; i < list->count; i++)
if (!certs || *bufsize < size)
{
list->certs[i].cbData = datum[i].size;
list->certs[i].pbData = ptr;
memcpy(list->certs[i].pbData, datum[i].data, datum[i].size);
*bufsize = size;
return SEC_E_BUFFER_TOO_SMALL;
}
ptr = (BYTE *)&certs[count];
for (i = 0; i < count; i++)
{
certs[i].cbData = datum[i].size;
certs[i].pbData = ptr;
memcpy(certs[i].pbData, datum[i].data, datum[i].size);
ptr += datum[i].size;
}
*bufsize = size;
*retcount = count;
return SEC_E_OK;
}
......
......@@ -108,12 +108,6 @@ struct schan_transport
struct schan_buffers out;
};
struct schan_cert_list
{
unsigned int count;
CERT_BLOB *certs;
};
struct schan_funcs
{
BOOL (CDECL *allocate_certificate_credentials)(schan_credentials *, const CERT_CONTEXT *, const DATA_BLOB *);
......@@ -126,7 +120,7 @@ struct schan_funcs
ALG_ID (CDECL *get_key_signature_algorithm)(schan_session);
unsigned int (CDECL *get_max_message_size)(schan_session);
unsigned int (CDECL *get_session_cipher_block_size)(schan_session);
SECURITY_STATUS (CDECL *get_session_peer_certificate)(schan_session, struct schan_cert_list *);
SECURITY_STATUS (CDECL *get_session_peer_certificate)(schan_session, CERT_BLOB *, ULONG *, ULONG *);
SECURITY_STATUS (CDECL *get_unique_channel_binding)(schan_session, SecPkgContext_Bindings *);
SECURITY_STATUS (CDECL *handshake)(schan_session, SecBufferDesc *, SIZE_T, SecBufferDesc *, ULONG );
SECURITY_STATUS (CDECL *recv)(schan_session, SecBufferDesc *, SIZE_T, void *, SIZE_T *);
......
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