]> granicus.if.org Git - curl/commitdiff
schannel: add CURLOPT_CERTINFO support
authorAndrew Kurushin <ajax16384@gmail.com>
Wed, 1 Jun 2016 06:48:30 +0000 (08:48 +0200)
committerDaniel Stenberg <daniel@haxx.se>
Wed, 1 Jun 2016 06:50:01 +0000 (08:50 +0200)
Closes #822

CMakeLists.txt
docs/libcurl/opts/CURLINFO_CERTINFO.3
lib/vtls/schannel.c
lib/vtls/schannel.h
lib/x509asn1.c
lib/x509asn1.h
winbuild/MakefileBuild.vc

index 06f18cf5989b13712131d468b74845849acc3bf3..9e6c42e8e68cc0b7911685bc77f6037ef71b6eb7 100644 (file)
@@ -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()
index c76daa7a3af24e71d141382df7971a51d612ef3f..cb0bd8aa3556b725a7e7ef9afb5b98ad848790d1 100644 (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
 .\" * 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
index b2e926563829de703e3b6e708189bf76f4d8b13b..3db5c362c5678e5ce6e0ed4f8ccc757bb8350692 100644 (file)
@@ -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;
index a314b34f9a90a1405e3efa953fa2fb75ef30582f..8a4991ec83d7bba0158b71f4df257c5660e4d99e 100644 (file)
@@ -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
index c221ba075accaf7550a2ffba6164f2e9c2ac0e46..fcff7f0b89ee701752c5405ac912160b7622bfdb 100644 (file)
@@ -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)
 
index e6a1e244408ef53b4f2bb2029e6710f4d06a1cb9..0f2b9304fa2538e518f6d4b655b2193b0cf59b81 100644 (file)
@@ -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 */
index ee584a6fdc3255cc79e5f047c4f307a938bc07e2..22b1e501f23aaf5caf380934c7fc3d69da20544f 100644 (file)
@@ -232,6 +232,7 @@ USE_WINSSL  = true
 !ERROR cannot build with WinSSL without SSPI\r
 !ENDIF\r
 SSPI_CFLAGS = $(SSPI_CFLAGS) /DUSE_SCHANNEL\r
+WIN_LIBS    = $(WIN_LIBS) Crypt32.lib\r
 !ENDIF\r
 \r
 \r