1 #ifndef HEADER_CURL_SCHANNEL_H 2 #define HEADER_CURL_SCHANNEL_H 3 /*************************************************************************** 4 * _ _ ____ _ 5 * Project ___| | | | _ \| | 6 * / __| | | | |_) | | 7 * | (__| |_| | _ <| |___ 8 * \___|\___/|_| \_\_____| 9 * 10 * Copyright (C) Marc Hoersken, <info@marc-hoersken.de>, et al. 11 * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al. 12 * 13 * This software is licensed as described in the file COPYING, which 14 * you should have received as part of this distribution. The terms 15 * are also available at https://curl.se/docs/copyright.html. 16 * 17 * You may opt to use, copy, modify, merge, publish, distribute and/or sell 18 * copies of the Software, and permit persons to whom the Software is 19 * furnished to do so, under the terms of the COPYING file. 20 * 21 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 22 * KIND, either express or implied. 23 * 24 * SPDX-License-Identifier: curl 25 * 26 ***************************************************************************/ 27 #include "curl_setup.h" 28 29 #ifdef USE_SCHANNEL 30 31 #define SCHANNEL_USE_BLACKLISTS 1 32 33 #ifdef _MSC_VER 34 #pragma warning(push) 35 #pragma warning(disable: 4201) 36 #endif 37 #include <subauth.h> 38 #ifdef _MSC_VER 39 #pragma warning(pop) 40 #endif 41 /* Wincrypt must be included before anything that could include OpenSSL. */ 42 #if defined(USE_WIN32_CRYPTO) 43 #include <wincrypt.h> 44 /* Undefine wincrypt conflicting symbols for BoringSSL. */ 45 #undef X509_NAME 46 #undef X509_EXTENSIONS 47 #undef PKCS7_ISSUER_AND_SERIAL 48 #undef PKCS7_SIGNER_INFO 49 #undef OCSP_REQUEST 50 #undef OCSP_RESPONSE 51 #endif 52 53 #include <schnlsp.h> 54 #include <schannel.h> 55 #include "curl_sspi.h" 56 57 #include "cfilters.h" 58 #include "urldata.h" 59 60 /* <wincrypt.h> has been included via the above <schnlsp.h>. 61 * Or in case of ldap.c, it was included via <winldap.h>. 62 * And since <wincrypt.h> has this: 63 * #define X509_NAME ((LPCSTR) 7) 64 * 65 * And in BoringSSL's <openssl/base.h> there is: 66 * typedef struct X509_name_st X509_NAME; 67 * etc. 68 * 69 * this will cause all kinds of C-preprocessing paste errors in 70 * BoringSSL's <openssl/x509.h>: So just undefine those defines here 71 * (and only here). 72 */ 73 #if defined(HAVE_BORINGSSL) || defined(OPENSSL_IS_BORINGSSL) 74 # undef X509_NAME 75 # undef X509_CERT_PAIR 76 # undef X509_EXTENSIONS 77 #endif 78 79 extern const struct Curl_ssl Curl_ssl_schannel; 80 81 CURLcode Curl_verify_certificate(struct Curl_cfilter *cf, 82 struct Curl_easy *data); 83 84 /* structs to expose only in schannel.c and schannel_verify.c */ 85 #ifdef EXPOSE_SCHANNEL_INTERNAL_STRUCTS 86 87 #ifdef __MINGW32__ 88 #ifdef __MINGW64_VERSION_MAJOR 89 #define HAS_MANUAL_VERIFY_API 90 #endif 91 #else 92 #ifdef CERT_CHAIN_REVOCATION_CHECK_CHAIN 93 #define HAS_MANUAL_VERIFY_API 94 #endif 95 #endif 96 97 #if defined(CryptStringToBinary) && defined(CRYPT_STRING_HEX) \ 98 && !defined(DISABLE_SCHANNEL_CLIENT_CERT) 99 #define HAS_CLIENT_CERT_PATH 100 #endif 101 102 #ifndef SCH_CREDENTIALS_VERSION 103 104 #define SCH_CREDENTIALS_VERSION 0x00000005 105 106 typedef enum _eTlsAlgorithmUsage 107 { 108 TlsParametersCngAlgUsageKeyExchange, 109 TlsParametersCngAlgUsageSignature, 110 TlsParametersCngAlgUsageCipher, 111 TlsParametersCngAlgUsageDigest, 112 TlsParametersCngAlgUsageCertSig 113 } eTlsAlgorithmUsage; 114 115 typedef struct _CRYPTO_SETTINGS 116 { 117 eTlsAlgorithmUsage eAlgorithmUsage; 118 UNICODE_STRING strCngAlgId; 119 DWORD cChainingModes; 120 PUNICODE_STRING rgstrChainingModes; 121 DWORD dwMinBitLength; 122 DWORD dwMaxBitLength; 123 } CRYPTO_SETTINGS, * PCRYPTO_SETTINGS; 124 125 typedef struct _TLS_PARAMETERS 126 { 127 DWORD cAlpnIds; 128 PUNICODE_STRING rgstrAlpnIds; 129 DWORD grbitDisabledProtocols; 130 DWORD cDisabledCrypto; 131 PCRYPTO_SETTINGS pDisabledCrypto; 132 DWORD dwFlags; 133 } TLS_PARAMETERS, * PTLS_PARAMETERS; 134 135 typedef struct _SCH_CREDENTIALS 136 { 137 DWORD dwVersion; 138 DWORD dwCredFormat; 139 DWORD cCreds; 140 PCCERT_CONTEXT* paCred; 141 HCERTSTORE hRootStore; 142 143 DWORD cMappers; 144 struct _HMAPPER **aphMappers; 145 146 DWORD dwSessionLifespan; 147 DWORD dwFlags; 148 DWORD cTlsParameters; 149 PTLS_PARAMETERS pTlsParameters; 150 } SCH_CREDENTIALS, * PSCH_CREDENTIALS; 151 152 #define SCH_CRED_MAX_SUPPORTED_PARAMETERS 16 153 #define SCH_CRED_MAX_SUPPORTED_ALPN_IDS 16 154 #define SCH_CRED_MAX_SUPPORTED_CRYPTO_SETTINGS 16 155 #define SCH_CRED_MAX_SUPPORTED_CHAINING_MODES 16 156 157 #endif 158 159 struct Curl_schannel_cred { 160 CredHandle cred_handle; 161 TimeStamp time_stamp; 162 TCHAR *sni_hostname; 163 #ifdef HAS_CLIENT_CERT_PATH 164 HCERTSTORE client_cert_store; 165 #endif 166 int refcount; 167 }; 168 169 struct Curl_schannel_ctxt { 170 CtxtHandle ctxt_handle; 171 TimeStamp time_stamp; 172 }; 173 174 struct ssl_backend_data { 175 struct Curl_schannel_cred *cred; 176 struct Curl_schannel_ctxt *ctxt; 177 SecPkgContext_StreamSizes stream_sizes; 178 size_t encdata_length, decdata_length; 179 size_t encdata_offset, decdata_offset; 180 unsigned char *encdata_buffer, *decdata_buffer; 181 /* encdata_is_incomplete: if encdata contains only a partial record that 182 can't be decrypted without another recv() (that is, status is 183 SEC_E_INCOMPLETE_MESSAGE) then set this true. after an recv() adds 184 more bytes into encdata then set this back to false. */ 185 bool encdata_is_incomplete; 186 unsigned long req_flags, ret_flags; 187 CURLcode recv_unrecoverable_err; /* schannel_recv had an unrecoverable err */ 188 bool recv_sspi_close_notify; /* true if connection closed by close_notify */ 189 bool recv_connection_closed; /* true if connection closed, regardless how */ 190 bool recv_renegotiating; /* true if recv is doing renegotiation */ 191 bool use_alpn; /* true if ALPN is used for this connection */ 192 #ifdef HAS_MANUAL_VERIFY_API 193 bool use_manual_cred_validation; /* true if manual cred validation is used */ 194 #endif 195 }; 196 #endif /* EXPOSE_SCHANNEL_INTERNAL_STRUCTS */ 197 198 #endif /* USE_SCHANNEL */ 199 #endif /* HEADER_CURL_SCHANNEL_H */ 200