From 6cabd78531f80d5c6cd942ed1aa97eaa5ec080df Mon Sep 17 00:00:00 2001 From: Andrew Kurushin Date: Wed, 1 Jun 2016 08:48:30 +0200 Subject: schannel: add CURLOPT_CERTINFO support Closes #822 --- lib/vtls/schannel.c | 28 +++++++++++++++++++++++++++- lib/vtls/schannel.h | 3 +++ lib/x509asn1.c | 4 ++-- lib/x509asn1.h | 4 ++-- 4 files changed, 34 insertions(+), 5 deletions(-) (limited to 'lib') diff --git a/lib/vtls/schannel.c b/lib/vtls/schannel.c index b2e926563..3db5c362c 100644 --- a/lib/vtls/schannel.c +++ b/lib/vtls/schannel.c @@ -56,6 +56,7 @@ #include "inet_pton.h" /* for IP addr SNI check */ #include "curl_multibyte.h" #include "warnless.h" +#include "x509asn1.h" #include "curl_printf.h" #include "curl_memory.h" /* The last #include file should be: */ @@ -600,8 +601,9 @@ schannel_connect_step3(struct connectdata *conn, int sockindex) struct SessionHandle *data = conn->data; struct ssl_connect_data *connssl = &conn->ssl[sockindex]; struct curl_schannel_cred *old_cred = NULL; -#ifdef HAS_ALPN SECURITY_STATUS sspi_status = SEC_E_OK; + CERT_CONTEXT *ccert_context = NULL; +#ifdef HAS_ALPN SecPkgContext_ApplicationProtocol alpn_result; #endif bool incache; @@ -694,6 +696,30 @@ schannel_connect_step3(struct connectdata *conn, int sockindex) } } + if(data->set.ssl.certinfo) { + sspi_status = s_pSecFn->QueryContextAttributes(&connssl->ctxt->ctxt_handle, + SECPKG_ATTR_REMOTE_CERT_CONTEXT, &ccert_context); + + if((sspi_status != SEC_E_OK) || (ccert_context == NULL)) { + failf(data, "schannel: failed to retrieve remote cert context"); + return CURLE_SSL_CONNECT_ERROR; + } + + result = Curl_ssl_init_certinfo(data, 1); + if(!result) { + if(((ccert_context->dwCertEncodingType & X509_ASN_ENCODING) != 0) && + (ccert_context->cbCertEncoded > 0)) { + + const char *beg = (const char *) ccert_context->pbCertEncoded; + const char *end = beg + ccert_context->cbCertEncoded; + result = Curl_extract_certinfo(conn, 0, beg, end); + } + } + CertFreeCertificateContext(ccert_context); + if(result) + return result; + } + connssl->connecting_state = ssl_connect_done; return CURLE_OK; diff --git a/lib/vtls/schannel.h b/lib/vtls/schannel.h index a314b34f9..8a4991ec8 100644 --- a/lib/vtls/schannel.h +++ b/lib/vtls/schannel.h @@ -97,6 +97,9 @@ int Curl_schannel_random(unsigned char *entropy, size_t length); /* Set the API backend definition to Schannel */ #define CURL_SSL_BACKEND CURLSSLBACKEND_SCHANNEL +/* this backend supports CURLOPT_CERTINFO */ +#define have_curlssl_certinfo 1 + /* API setup for Schannel */ #define curlssl_init Curl_schannel_init #define curlssl_cleanup Curl_schannel_cleanup diff --git a/lib/x509asn1.c b/lib/x509asn1.c index c221ba075..fcff7f0b8 100644 --- a/lib/x509asn1.c +++ b/lib/x509asn1.c @@ -23,7 +23,7 @@ #include "curl_setup.h" #if defined(USE_GSKIT) || defined(USE_NSS) || defined(USE_GNUTLS) || \ - defined(USE_CYASSL) + defined(USE_CYASSL) || defined(USE_SCHANNEL) #include #include "urldata.h" @@ -1025,7 +1025,7 @@ CURLcode Curl_extract_certinfo(struct connectdata * conn, return CURLE_OK; } -#endif /* USE_GSKIT or USE_NSS or USE_GNUTLS or USE_CYASSL */ +#endif /* USE_GSKIT or USE_NSS or USE_GNUTLS or USE_CYASSL or USE_SCHANNEL */ #if defined(USE_GSKIT) diff --git a/lib/x509asn1.h b/lib/x509asn1.h index e6a1e2444..0f2b9304f 100644 --- a/lib/x509asn1.h +++ b/lib/x509asn1.h @@ -26,7 +26,7 @@ #include "curl_setup.h" #if defined(USE_GSKIT) || defined(USE_NSS) || defined(USE_GNUTLS) || \ - defined(USE_CYASSL) + defined(USE_CYASSL) || defined(USE_SCHANNEL) #include "urldata.h" @@ -128,5 +128,5 @@ CURLcode Curl_extract_certinfo(struct connectdata * conn, int certnum, CURLcode Curl_verifyhost(struct connectdata * conn, const char * beg, const char * end); -#endif /* USE_GSKIT or USE_NSS or USE_GNUTLS or USE_CYASSL */ +#endif /* USE_GSKIT or USE_NSS or USE_GNUTLS or USE_CYASSL or USE_SCHANNEL */ #endif /* HEADER_CURL_X509ASN1_H */ -- cgit v1.2.3