diff options
author | dartraiden <wowemuh@gmail.com> | 2018-12-14 03:33:12 +0300 |
---|---|---|
committer | dartraiden <wowemuh@gmail.com> | 2018-12-14 03:33:29 +0300 |
commit | fff280ec7c91e7bbba1f8dd389468717f08e9106 (patch) | |
tree | ae20777655e2814dd5ab9be0e456a472065e62ce /libs/libcurl/src/vtls/schannel.c | |
parent | 887544273011d56a796e9507199ea8d6484d31c6 (diff) |
libcurl: update to 7.63
Diffstat (limited to 'libs/libcurl/src/vtls/schannel.c')
-rw-r--r-- | libs/libcurl/src/vtls/schannel.c | 83 |
1 files changed, 69 insertions, 14 deletions
diff --git a/libs/libcurl/src/vtls/schannel.c b/libs/libcurl/src/vtls/schannel.c index e4426924bc..56fd93e1e5 100644 --- a/libs/libcurl/src/vtls/schannel.c +++ b/libs/libcurl/src/vtls/schannel.c @@ -23,9 +23,8 @@ ***************************************************************************/ /* - * Source file for all SChannel-specific code for the TLS/SSL layer. No code + * Source file for all Schannel-specific code for the TLS/SSL layer. No code * but vtls.c should ever call or use these functions. - * */ /* @@ -196,7 +195,7 @@ set_ssl_version_min_max(SCHANNEL_CRED *schannel_cred, struct connectdata *conn) schannel_cred->grbitEnabledProtocols |= SP_PROT_TLS1_2_CLIENT; break; case CURL_SSLVERSION_TLSv1_3: - failf(data, "Schannel: TLS 1.3 is not yet supported"); + failf(data, "schannel: TLS 1.3 is not yet supported"); return CURLE_SSL_CONNECT_ERROR; } } @@ -434,7 +433,7 @@ schannel_connect_step1(struct connectdata *conn, int sockindex) if(Curl_verify_windows_version(5, 1, PLATFORM_WINNT, VERSION_LESS_THAN_EQUAL)) { - /* SChannel in Windows XP (OS version 5.1) uses legacy handshakes and + /* Schannel in Windows XP (OS version 5.1) uses legacy handshakes and algorithms that may not be supported by all servers. */ infof(data, "schannel: WinSSL version is old and may not be able to " "connect to some servers due to lack of SNI, algorithms, etc.\n"); @@ -1114,13 +1113,68 @@ schannel_connect_step2(struct connectdata *conn, int sockindex) #ifdef HAS_MANUAL_VERIFY_API if(conn->ssl_config.verifypeer && BACKEND->use_manual_cred_validation) { - return verify_certificate(conn, sockindex); + return Curl_verify_certificate(conn, sockindex); } #endif return CURLE_OK; } +static bool +valid_cert_encoding(const CERT_CONTEXT *cert_context) +{ + return (cert_context != NULL) && + ((cert_context->dwCertEncodingType & X509_ASN_ENCODING) != 0) && + (cert_context->pbCertEncoded != NULL) && + (cert_context->cbCertEncoded > 0); +} + +typedef bool(*Read_crt_func)(const CERT_CONTEXT *ccert_context, void *arg); + +static void +traverse_cert_store(const CERT_CONTEXT *context, Read_crt_func func, + void *arg) +{ + const CERT_CONTEXT *current_context = NULL; + bool should_continue = true; + while(should_continue && + (current_context = CertEnumCertificatesInStore( + context->hCertStore, + current_context)) != NULL) + should_continue = func(current_context, arg); + + if(current_context) + CertFreeCertificateContext(current_context); +} + +static bool +cert_counter_callback(const CERT_CONTEXT *ccert_context, void *certs_count) +{ + if(valid_cert_encoding(ccert_context)) + (*(int *)certs_count)++; + return true; +} + +struct Adder_args +{ + struct connectdata *conn; + CURLcode result; + int idx; +}; + +static bool +add_cert_to_certinfo(const CERT_CONTEXT *ccert_context, void *raw_arg) +{ + struct Adder_args *args = (struct Adder_args*)raw_arg; + args->result = CURLE_OK; + if(valid_cert_encoding(ccert_context)) { + const char *beg = (const char *) ccert_context->pbCertEncoded; + const char *end = beg + ccert_context->cbCertEncoded; + args->result = Curl_extract_certinfo(args->conn, (args->idx)++, beg, end); + } + return args->result == CURLE_OK; +} + static CURLcode schannel_connect_step3(struct connectdata *conn, int sockindex) { @@ -1230,6 +1284,7 @@ schannel_connect_step3(struct connectdata *conn, int sockindex) } if(data->set.ssl.certinfo) { + int certs_count = 0; sspi_status = s_pSecFn->QueryContextAttributes(&BACKEND->ctxt->ctxt_handle, SECPKG_ATTR_REMOTE_CERT_CONTEXT, &ccert_context); @@ -1238,15 +1293,15 @@ schannel_connect_step3(struct connectdata *conn, int sockindex) return CURLE_PEER_FAILED_VERIFICATION; } - result = Curl_ssl_init_certinfo(data, 1); - if(!result) { - if(((ccert_context->dwCertEncodingType & X509_ASN_ENCODING) != 0) && - (ccert_context->cbCertEncoded > 0)) { + traverse_cert_store(ccert_context, cert_counter_callback, &certs_count); - const char *beg = (const char *) ccert_context->pbCertEncoded; - const char *end = beg + ccert_context->cbCertEncoded; - result = Curl_extract_certinfo(conn, 0, beg, end); - } + result = Curl_ssl_init_certinfo(data, certs_count); + if(!result) { + struct Adder_args args; + args.conn = conn; + args.idx = 0; + traverse_cert_store(ccert_context, add_cert_to_certinfo, &args); + result = args.result; } CertFreeCertificateContext(ccert_context); if(result) @@ -1994,7 +2049,7 @@ static void Curl_schannel_cleanup(void) static size_t Curl_schannel_version(char *buffer, size_t size) { - size = snprintf(buffer, size, "WinSSL"); + size = msnprintf(buffer, size, "WinSSL"); return size; } |