1
0
mirror of https://github.com/moparisthebest/curl synced 2024-11-15 14:05:03 -05:00

schannel: add CURLOPT_CERTINFO support

Closes #822
This commit is contained in:
Andrew Kurushin 2016-06-01 08:48:30 +02:00 committed by Daniel Stenberg
parent c444ace556
commit 6cabd78531
7 changed files with 39 additions and 8 deletions

View File

@ -578,6 +578,7 @@ if(NOT UNIX)
if(HAVE_SCHANNEL_H) if(HAVE_SCHANNEL_H)
set(USE_SCHANNEL ON) set(USE_SCHANNEL ON)
set(SSL_ENABLED ON) set(SSL_ENABLED ON)
check_library_exists_concat("crypt32" CertFreeCertificateContext HAVE_LIBCRYPT32)
endif() endif()
endif() endif()
endif() endif()

View File

@ -5,7 +5,7 @@
.\" * | (__| |_| | _ <| |___ .\" * | (__| |_| | _ <| |___
.\" * \___|\___/|_| \_\_____| .\" * \___|\___/|_| \_\_____|
.\" * .\" *
.\" * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al. .\" * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
.\" * .\" *
.\" * This software is licensed as described in the file COPYING, which .\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms .\" * you should have received as part of this distribution. The terms
@ -41,8 +41,8 @@ All TLS-based
.SH EXAMPLE .SH EXAMPLE
TODO TODO
.SH AVAILABILITY .SH AVAILABILITY
This option is only working in libcurl built with OpenSSL, NSS or GSKit This option is only working in libcurl built with OpenSSL, NSS, schannel or
support. GSKit support. schannel support added in 7.50.0
Added in 7.19.1 Added in 7.19.1
.SH RETURN VALUE .SH RETURN VALUE

View File

@ -56,6 +56,7 @@
#include "inet_pton.h" /* for IP addr SNI check */ #include "inet_pton.h" /* for IP addr SNI check */
#include "curl_multibyte.h" #include "curl_multibyte.h"
#include "warnless.h" #include "warnless.h"
#include "x509asn1.h"
#include "curl_printf.h" #include "curl_printf.h"
#include "curl_memory.h" #include "curl_memory.h"
/* The last #include file should be: */ /* The last #include file should be: */
@ -600,8 +601,9 @@ schannel_connect_step3(struct connectdata *conn, int sockindex)
struct SessionHandle *data = conn->data; struct SessionHandle *data = conn->data;
struct ssl_connect_data *connssl = &conn->ssl[sockindex]; struct ssl_connect_data *connssl = &conn->ssl[sockindex];
struct curl_schannel_cred *old_cred = NULL; struct curl_schannel_cred *old_cred = NULL;
#ifdef HAS_ALPN
SECURITY_STATUS sspi_status = SEC_E_OK; SECURITY_STATUS sspi_status = SEC_E_OK;
CERT_CONTEXT *ccert_context = NULL;
#ifdef HAS_ALPN
SecPkgContext_ApplicationProtocol alpn_result; SecPkgContext_ApplicationProtocol alpn_result;
#endif #endif
bool incache; 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; connssl->connecting_state = ssl_connect_done;
return CURLE_OK; return CURLE_OK;

View File

@ -97,6 +97,9 @@ int Curl_schannel_random(unsigned char *entropy, size_t length);
/* Set the API backend definition to Schannel */ /* Set the API backend definition to Schannel */
#define CURL_SSL_BACKEND CURLSSLBACKEND_SCHANNEL #define CURL_SSL_BACKEND CURLSSLBACKEND_SCHANNEL
/* this backend supports CURLOPT_CERTINFO */
#define have_curlssl_certinfo 1
/* API setup for Schannel */ /* API setup for Schannel */
#define curlssl_init Curl_schannel_init #define curlssl_init Curl_schannel_init
#define curlssl_cleanup Curl_schannel_cleanup #define curlssl_cleanup Curl_schannel_cleanup

View File

@ -23,7 +23,7 @@
#include "curl_setup.h" #include "curl_setup.h"
#if defined(USE_GSKIT) || defined(USE_NSS) || defined(USE_GNUTLS) || \ #if defined(USE_GSKIT) || defined(USE_NSS) || defined(USE_GNUTLS) || \
defined(USE_CYASSL) defined(USE_CYASSL) || defined(USE_SCHANNEL)
#include <curl/curl.h> #include <curl/curl.h>
#include "urldata.h" #include "urldata.h"
@ -1025,7 +1025,7 @@ CURLcode Curl_extract_certinfo(struct connectdata * conn,
return CURLE_OK; 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) #if defined(USE_GSKIT)

View File

@ -26,7 +26,7 @@
#include "curl_setup.h" #include "curl_setup.h"
#if defined(USE_GSKIT) || defined(USE_NSS) || defined(USE_GNUTLS) || \ #if defined(USE_GSKIT) || defined(USE_NSS) || defined(USE_GNUTLS) || \
defined(USE_CYASSL) defined(USE_CYASSL) || defined(USE_SCHANNEL)
#include "urldata.h" #include "urldata.h"
@ -128,5 +128,5 @@ CURLcode Curl_extract_certinfo(struct connectdata * conn, int certnum,
CURLcode Curl_verifyhost(struct connectdata * conn, CURLcode Curl_verifyhost(struct connectdata * conn,
const char * beg, const char * end); 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 */ #endif /* HEADER_CURL_X509ASN1_H */

View File

@ -232,6 +232,7 @@ USE_WINSSL = true
!ERROR cannot build with WinSSL without SSPI !ERROR cannot build with WinSSL without SSPI
!ENDIF !ENDIF
SSPI_CFLAGS = $(SSPI_CFLAGS) /DUSE_SCHANNEL SSPI_CFLAGS = $(SSPI_CFLAGS) /DUSE_SCHANNEL
WIN_LIBS = $(WIN_LIBS) Crypt32.lib
!ENDIF !ENDIF