schannel: add CURLOPT_CERTINFO support

Closes #822
This commit is contained in:
Andrew Kurushin 2016-06-01 08:48:30 +02:00 коммит произвёл Daniel Stenberg
Родитель c444ace556
Коммит 6cabd78531
7 изменённых файлов: 39 добавлений и 8 удалений

Просмотреть файл

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

Просмотреть файл

@ -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
.\" * you should have received as part of this distribution. The terms
@ -41,8 +41,8 @@ All TLS-based
.SH EXAMPLE
TODO
.SH AVAILABILITY
This option is only working in libcurl built with OpenSSL, NSS or GSKit
support.
This option is only working in libcurl built with OpenSSL, NSS, schannel or
GSKit support. schannel support added in 7.50.0
Added in 7.19.1
.SH RETURN VALUE

Просмотреть файл

@ -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;

Просмотреть файл

@ -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

Просмотреть файл

@ -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 <curl/curl.h>
#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)

Просмотреть файл

@ -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 */

Просмотреть файл

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