aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Kurushin <ajax16384@gmail.com>2016-06-01 08:48:30 +0200
committerDaniel Stenberg <daniel@haxx.se>2016-06-01 08:50:01 +0200
commit6cabd78531f80d5c6cd942ed1aa97eaa5ec080df (patch)
tree13c57e22e971834f40dafb2c10605f17c04f27f0
parentc444ace5568cdbd7c4f85fecb3f05680aaa5b96d (diff)
schannel: add CURLOPT_CERTINFO support
Closes #822
-rw-r--r--CMakeLists.txt1
-rw-r--r--docs/libcurl/opts/CURLINFO_CERTINFO.36
-rw-r--r--lib/vtls/schannel.c28
-rw-r--r--lib/vtls/schannel.h3
-rw-r--r--lib/x509asn1.c4
-rw-r--r--lib/x509asn1.h4
-rw-r--r--winbuild/MakefileBuild.vc1
7 files changed, 39 insertions, 8 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 06f18cf59..9e6c42e8e 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -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()
diff --git a/docs/libcurl/opts/CURLINFO_CERTINFO.3 b/docs/libcurl/opts/CURLINFO_CERTINFO.3
index c76daa7a3..cb0bd8aa3 100644
--- a/docs/libcurl/opts/CURLINFO_CERTINFO.3
+++ b/docs/libcurl/opts/CURLINFO_CERTINFO.3
@@ -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
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 <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)
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 */
diff --git a/winbuild/MakefileBuild.vc b/winbuild/MakefileBuild.vc
index ee584a6fd..22b1e501f 100644
--- a/winbuild/MakefileBuild.vc
+++ b/winbuild/MakefileBuild.vc
@@ -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