secur32: Simplify get_session_peer_certificate unixlib interface.

Use single buffer for returned certificate blobs, instead of an array
of CERT_BLOB that contains pointers.

Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Nikolay Sivov 2022-05-27 10:35:42 +03:00 committed by Alexandre Julliard
parent c9c50cd4f1
commit b255160168
3 changed files with 19 additions and 15 deletions

View file

@ -1026,7 +1026,6 @@ static SECURITY_STATUS ensure_remote_cert(struct schan_context *ctx)
HCERTSTORE store;
PCCERT_CONTEXT cert = NULL;
SECURITY_STATUS status;
CERT_BLOB *certs;
ULONG count, size = 0;
struct get_session_peer_certificate_params params = { ctx->transport.session, NULL, &size, &count };
@ -1036,28 +1035,33 @@ static SECURITY_STATUS ensure_remote_cert(struct schan_context *ctx)
status = GNUTLS_CALL( get_session_peer_certificate, &params );
if (status != SEC_E_BUFFER_TOO_SMALL) goto done;
if (!(certs = malloc( size )))
if (!(params.buffer = malloc( size )))
{
status = SEC_E_INSUFFICIENT_MEMORY;
goto done;
}
params.certs = certs;
status = GNUTLS_CALL( get_session_peer_certificate, &params );
if (status == SEC_E_OK)
{
unsigned int i;
ULONG *sizes;
BYTE *blob;
sizes = (ULONG *)params.buffer;
blob = params.buffer + count * sizeof(*sizes);
for (i = 0; i < count; i++)
{
if (!CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING, certs[i].pbData,
certs[i].cbData, CERT_STORE_ADD_REPLACE_EXISTING,
i ? NULL : &cert))
if (!CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING, blob, sizes[i],
CERT_STORE_ADD_REPLACE_EXISTING, i ? NULL : &cert))
{
if (i) CertFreeCertificateContext(cert);
return GetLastError();
}
blob += sizes[i];
}
}
free(certs);
free(params.buffer);
done:
ctx->cert = cert;
CertCloseStore(store, 0);

View file

@ -792,28 +792,28 @@ static NTSTATUS schan_get_session_peer_certificate( void *args )
{
const struct get_session_peer_certificate_params *params = args;
gnutls_session_t s = (gnutls_session_t)params->session;
CERT_BLOB *certs = params->certs;
const gnutls_datum_t *datum;
unsigned int i, size;
BYTE *ptr;
unsigned int count;
ULONG *sizes;
if (!(datum = pgnutls_certificate_get_peers(s, &count))) return SEC_E_INTERNAL_ERROR;
size = count * sizeof(certs[0]);
size = count * sizeof(*sizes);
for (i = 0; i < count; i++) size += datum[i].size;
if (!certs || *params->bufsize < size)
if (!params->buffer || *params->bufsize < size)
{
*params->bufsize = size;
return SEC_E_BUFFER_TOO_SMALL;
}
ptr = (BYTE *)&certs[count];
sizes = (ULONG *)params->buffer;
ptr = params->buffer + count * sizeof(*sizes);
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);
sizes[i] = datum[i].size;
memcpy(ptr, datum[i].data, datum[i].size);
ptr += datum[i].size;
}

View file

@ -145,7 +145,7 @@ struct get_connection_info_params
struct get_session_peer_certificate_params
{
schan_session session;
CERT_BLOB *certs;
BYTE *buffer; /* Starts with array of ULONG sizes, followed by contiguous data blob. */
ULONG *bufsize;
ULONG *retcount;
};