mirror of
https://github.com/curl/curl.git
synced 2025-09-09 21:52:40 +03:00
schannel: make CURLOPT_CERTINFO support using Issuer chain
Closes #3197
This commit is contained in:
parent
58d04252e1
commit
7f4c358541
|
@ -70,7 +70,7 @@ if(curl) {
|
||||||
}
|
}
|
||||||
.fi
|
.fi
|
||||||
.SH AVAILABILITY
|
.SH AVAILABILITY
|
||||||
This option is supported by the OpenSSL, GnuTLS, NSS and GSKit backends.
|
This option is supported by the OpenSSL, GnuTLS, WinSSL, NSS and GSKit backends.
|
||||||
.SH RETURN VALUE
|
.SH RETURN VALUE
|
||||||
Returns CURLE_OK if the option is supported, and CURLE_UNKNOWN_OPTION if not.
|
Returns CURLE_OK if the option is supported, and CURLE_UNKNOWN_OPTION if not.
|
||||||
.SH "SEE ALSO"
|
.SH "SEE ALSO"
|
||||||
|
|
|
@ -1121,6 +1121,61 @@ schannel_connect_step2(struct connectdata *conn, int sockindex)
|
||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
valid_cert_encoding(const CERT_CONTEXT *cert_context)
|
||||||
|
{
|
||||||
|
return (cert_context != NULL) &&
|
||||||
|
((cert_context->dwCertEncodingType & X509_ASN_ENCODING) != 0) &&
|
||||||
|
(cert_context->pbCertEncoded != NULL) &&
|
||||||
|
(cert_context->cbCertEncoded > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef bool(*Read_crt_func)(const CERT_CONTEXT *ccert_context, void *arg);
|
||||||
|
|
||||||
|
static void
|
||||||
|
traverse_cert_store(const CERT_CONTEXT *context, Read_crt_func func,
|
||||||
|
void *arg)
|
||||||
|
{
|
||||||
|
const CERT_CONTEXT *current_context = NULL;
|
||||||
|
bool should_continue = true;
|
||||||
|
while(should_continue &&
|
||||||
|
(current_context = CertEnumCertificatesInStore(
|
||||||
|
context->hCertStore,
|
||||||
|
current_context)) != NULL)
|
||||||
|
should_continue = func(current_context, arg);
|
||||||
|
|
||||||
|
if(current_context)
|
||||||
|
CertFreeCertificateContext(current_context);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
cert_counter_callback(const CERT_CONTEXT *ccert_context, void *certs_count)
|
||||||
|
{
|
||||||
|
if(valid_cert_encoding(ccert_context))
|
||||||
|
(*(int *)certs_count)++;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Adder_args
|
||||||
|
{
|
||||||
|
struct connectdata *conn;
|
||||||
|
CURLcode result;
|
||||||
|
int idx;
|
||||||
|
};
|
||||||
|
|
||||||
|
static bool
|
||||||
|
add_cert_to_certinfo(const CERT_CONTEXT *ccert_context, void *raw_arg)
|
||||||
|
{
|
||||||
|
struct Adder_args *args = (struct Adder_args*)raw_arg;
|
||||||
|
args->result = CURLE_OK;
|
||||||
|
if(valid_cert_encoding(ccert_context)) {
|
||||||
|
const char *beg = (const char *) ccert_context->pbCertEncoded;
|
||||||
|
const char *end = beg + ccert_context->cbCertEncoded;
|
||||||
|
args->result = Curl_extract_certinfo(args->conn, (args->idx)++, beg, end);
|
||||||
|
}
|
||||||
|
return args->result == CURLE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
static CURLcode
|
static CURLcode
|
||||||
schannel_connect_step3(struct connectdata *conn, int sockindex)
|
schannel_connect_step3(struct connectdata *conn, int sockindex)
|
||||||
{
|
{
|
||||||
|
@ -1230,6 +1285,7 @@ schannel_connect_step3(struct connectdata *conn, int sockindex)
|
||||||
}
|
}
|
||||||
|
|
||||||
if(data->set.ssl.certinfo) {
|
if(data->set.ssl.certinfo) {
|
||||||
|
int certs_count = 0;
|
||||||
sspi_status = s_pSecFn->QueryContextAttributes(&BACKEND->ctxt->ctxt_handle,
|
sspi_status = s_pSecFn->QueryContextAttributes(&BACKEND->ctxt->ctxt_handle,
|
||||||
SECPKG_ATTR_REMOTE_CERT_CONTEXT, &ccert_context);
|
SECPKG_ATTR_REMOTE_CERT_CONTEXT, &ccert_context);
|
||||||
|
|
||||||
|
@ -1238,15 +1294,15 @@ schannel_connect_step3(struct connectdata *conn, int sockindex)
|
||||||
return CURLE_PEER_FAILED_VERIFICATION;
|
return CURLE_PEER_FAILED_VERIFICATION;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = Curl_ssl_init_certinfo(data, 1);
|
traverse_cert_store(ccert_context, cert_counter_callback, &certs_count);
|
||||||
if(!result) {
|
|
||||||
if(((ccert_context->dwCertEncodingType & X509_ASN_ENCODING) != 0) &&
|
|
||||||
(ccert_context->cbCertEncoded > 0)) {
|
|
||||||
|
|
||||||
const char *beg = (const char *) ccert_context->pbCertEncoded;
|
result = Curl_ssl_init_certinfo(data, certs_count);
|
||||||
const char *end = beg + ccert_context->cbCertEncoded;
|
if(!result) {
|
||||||
result = Curl_extract_certinfo(conn, 0, beg, end);
|
struct Adder_args args;
|
||||||
}
|
args.conn = conn;
|
||||||
|
args.idx = 0;
|
||||||
|
traverse_cert_store(ccert_context, add_cert_to_certinfo, &args);
|
||||||
|
result = args.result;
|
||||||
}
|
}
|
||||||
CertFreeCertificateContext(ccert_context);
|
CertFreeCertificateContext(ccert_context);
|
||||||
if(result)
|
if(result)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user