From 880cd5dd2040826b8a1c49ecf59a385ea775a3d3 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 25 Feb 2019 18:12:51 +0100 Subject: strerror: make the strerror function use local buffers Instead of using a fixed 256 byte buffer in the connectdata struct. In my build, this reduces the size of the connectdata struct by 11.8%, from 2160 to 1904 bytes with no functionality or performance loss. This also fixes a bug in schannel's Curl_verify_certificate where it called Curl_sspi_strerror when it should have called Curl_strerror for string from GetLastError. the only effect would have been no text or the wrong text being shown for the error. Co-authored-by: Jay Satiro Closes #3612 --- lib/vtls/schannel.c | 40 ++++++++++++++++++++++++---------------- lib/vtls/schannel_verify.c | 45 ++++++++++++++++++++++++++++----------------- 2 files changed, 52 insertions(+), 33 deletions(-) (limited to 'lib/vtls') diff --git a/lib/vtls/schannel.c b/lib/vtls/schannel.c index 36e68f969..39ac080e8 100644 --- a/lib/vtls/schannel.c +++ b/lib/vtls/schannel.c @@ -687,8 +687,9 @@ schannel_connect_step1(struct connectdata *conn, int sockindex) CertFreeCertificateContext(client_certs[0]); if(sspi_status != SEC_E_OK) { + char buffer[STRERROR_LEN]; failf(data, "schannel: AcquireCredentialsHandle failed: %s", - Curl_sspi_strerror(conn, sspi_status)); + Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer))); Curl_safefree(BACKEND->cred); switch(sspi_status) { case SEC_E_INSUFFICIENT_MEMORY: @@ -803,15 +804,16 @@ schannel_connect_step1(struct connectdata *conn, int sockindex) Curl_unicodefree(host_name); if(sspi_status != SEC_I_CONTINUE_NEEDED) { + char buffer[STRERROR_LEN]; Curl_safefree(BACKEND->ctxt); switch(sspi_status) { case SEC_E_INSUFFICIENT_MEMORY: failf(data, "schannel: initial InitializeSecurityContext failed: %s", - Curl_sspi_strerror(conn, sspi_status)); + Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer))); return CURLE_OUT_OF_MEMORY; case SEC_E_WRONG_PRINCIPAL: failf(data, "schannel: SNI or certificate check failed: %s", - Curl_sspi_strerror(conn, sspi_status)); + Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer))); return CURLE_PEER_FAILED_VERIFICATION; /* case SEC_E_INVALID_HANDLE: @@ -826,7 +828,7 @@ schannel_connect_step1(struct connectdata *conn, int sockindex) */ default: failf(data, "schannel: initial InitializeSecurityContext failed: %s", - Curl_sspi_strerror(conn, sspi_status)); + Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer))); return CURLE_SSL_CONNECT_ERROR; } } @@ -1047,14 +1049,15 @@ schannel_connect_step2(struct connectdata *conn, int sockindex) } } else { + char buffer[STRERROR_LEN]; switch(sspi_status) { case SEC_E_INSUFFICIENT_MEMORY: failf(data, "schannel: next InitializeSecurityContext failed: %s", - Curl_sspi_strerror(conn, sspi_status)); + Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer))); return CURLE_OUT_OF_MEMORY; case SEC_E_WRONG_PRINCIPAL: failf(data, "schannel: SNI or certificate check failed: %s", - Curl_sspi_strerror(conn, sspi_status)); + Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer))); return CURLE_PEER_FAILED_VERIFICATION; /* case SEC_E_INVALID_HANDLE: @@ -1069,7 +1072,7 @@ schannel_connect_step2(struct connectdata *conn, int sockindex) */ default: failf(data, "schannel: next InitializeSecurityContext failed: %s", - Curl_sspi_strerror(conn, sspi_status)); + Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer))); return CURLE_SSL_CONNECT_ERROR; } } @@ -1851,9 +1854,10 @@ schannel_recv(struct connectdata *conn, int sockindex, goto cleanup; } else { + char buffer[STRERROR_LEN]; *err = CURLE_RECV_ERROR; infof(data, "schannel: failed to read data from server: %s\n", - Curl_sspi_strerror(conn, sspi_status)); + Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer))); goto cleanup; } } @@ -2003,9 +2007,11 @@ static int Curl_schannel_shutdown(struct connectdata *conn, int sockindex) sspi_status = s_pSecFn->ApplyControlToken(&BACKEND->ctxt->ctxt_handle, &BuffDesc); - if(sspi_status != SEC_E_OK) + if(sspi_status != SEC_E_OK) { + char buffer[STRERROR_LEN]; failf(data, "schannel: ApplyControlToken failure: %s", - Curl_sspi_strerror(conn, sspi_status)); + Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer))); + } host_name = Curl_convert_UTF8_to_tchar(hostname); if(!host_name) @@ -2123,7 +2129,7 @@ static CURLcode Curl_schannel_random(struct Curl_easy *data UNUSED_PARAM, static CURLcode pkp_pin_peer_pubkey(struct connectdata *conn, int sockindex, const char *pinnedpubkey) { - SECURITY_STATUS status; + SECURITY_STATUS sspi_status; struct Curl_easy *data = conn->data; struct ssl_connect_data *connssl = &conn->ssl[sockindex]; CERT_CONTEXT *pCertContextServer = NULL; @@ -2140,13 +2146,15 @@ static CURLcode pkp_pin_peer_pubkey(struct connectdata *conn, int sockindex, return CURLE_OK; do { - status = s_pSecFn->QueryContextAttributes(&BACKEND->ctxt->ctxt_handle, - SECPKG_ATTR_REMOTE_CERT_CONTEXT, - &pCertContextServer); + sspi_status = + s_pSecFn->QueryContextAttributes(&BACKEND->ctxt->ctxt_handle, + SECPKG_ATTR_REMOTE_CERT_CONTEXT, + &pCertContextServer); - if((status != SEC_E_OK) || (pCertContextServer == NULL)) { + if((sspi_status != SEC_E_OK) || (pCertContextServer == NULL)) { + char buffer[STRERROR_LEN]; failf(data, "schannel: Failed to read remote certificate context: %s", - Curl_sspi_strerror(conn, status)); + Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer))); break; /* failed */ } diff --git a/lib/vtls/schannel_verify.c b/lib/vtls/schannel_verify.c index 680f6ec5d..5a09e969e 100644 --- a/lib/vtls/schannel_verify.c +++ b/lib/vtls/schannel_verify.c @@ -96,9 +96,10 @@ static CURLcode add_certs_to_store(HCERTSTORE trust_store, ca_file_tstr = Curl_convert_UTF8_to_tchar((char *)ca_file); if(!ca_file_tstr) { + char buffer[STRERROR_LEN]; failf(data, "schannel: invalid path name for CA file '%s': %s", - ca_file, Curl_strerror(conn, GetLastError())); + ca_file, Curl_strerror(GetLastError(), buffer, sizeof(buffer))); result = CURLE_SSL_CACERT_BADFILE; goto cleanup; } @@ -116,17 +117,19 @@ static CURLcode add_certs_to_store(HCERTSTORE trust_store, FILE_ATTRIBUTE_NORMAL, NULL); if(ca_file_handle == INVALID_HANDLE_VALUE) { + char buffer[STRERROR_LEN]; failf(data, "schannel: failed to open CA file '%s': %s", - ca_file, Curl_strerror(conn, GetLastError())); + ca_file, Curl_strerror(GetLastError(), buffer, sizeof(buffer))); result = CURLE_SSL_CACERT_BADFILE; goto cleanup; } if(!GetFileSizeEx(ca_file_handle, &file_size)) { + char buffer[STRERROR_LEN]; failf(data, "schannel: failed to determine size of CA file '%s': %s", - ca_file, Curl_strerror(conn, GetLastError())); + ca_file, Curl_strerror(GetLastError(), buffer, sizeof(buffer))); result = CURLE_SSL_CACERT_BADFILE; goto cleanup; } @@ -153,10 +156,10 @@ static CURLcode add_certs_to_store(HCERTSTORE trust_store, if(!ReadFile(ca_file_handle, ca_file_buffer + total_bytes_read, bytes_to_read, &bytes_read, NULL)) { - + char buffer[STRERROR_LEN]; failf(data, "schannel: failed to read from CA file '%s': %s", - ca_file, Curl_strerror(conn, GetLastError())); + ca_file, Curl_strerror(GetLastError(), buffer, sizeof(buffer))); result = CURLE_SSL_CACERT_BADFILE; goto cleanup; } @@ -215,11 +218,12 @@ static CURLcode add_certs_to_store(HCERTSTORE trust_store, NULL, NULL, (const void **)&cert_context)) { - + char buffer[STRERROR_LEN]; failf(data, "schannel: failed to extract certificate from CA file " "'%s': %s", - ca_file, Curl_strerror(conn, GetLastError())); + ca_file, + Curl_strerror(GetLastError(), buffer, sizeof(buffer))); result = CURLE_SSL_CACERT_BADFILE; more_certs = 0; } @@ -243,10 +247,12 @@ static CURLcode add_certs_to_store(HCERTSTORE trust_store, NULL); CertFreeCertificateContext(cert_context); if(!add_cert_result) { + char buffer[STRERROR_LEN]; failf(data, "schannel: failed to add certificate from CA file '%s' " "to certificate store: %s", - ca_file, Curl_strerror(conn, GetLastError())); + ca_file, + Curl_strerror(GetLastError(), buffer, sizeof(buffer))); result = CURLE_SSL_CACERT_BADFILE; more_certs = 0; } @@ -408,7 +414,7 @@ cleanup: CURLcode Curl_verify_certificate(struct connectdata *conn, int sockindex) { - SECURITY_STATUS status; + SECURITY_STATUS sspi_status; struct Curl_easy *data = conn->data; struct ssl_connect_data *connssl = &conn->ssl[sockindex]; CURLcode result = CURLE_OK; @@ -420,13 +426,15 @@ CURLcode Curl_verify_certificate(struct connectdata *conn, int sockindex) conn->http_proxy.host.name : conn->host.name; - status = s_pSecFn->QueryContextAttributes(&BACKEND->ctxt->ctxt_handle, - SECPKG_ATTR_REMOTE_CERT_CONTEXT, - &pCertContextServer); + sspi_status = + s_pSecFn->QueryContextAttributes(&BACKEND->ctxt->ctxt_handle, + SECPKG_ATTR_REMOTE_CERT_CONTEXT, + &pCertContextServer); - if((status != SEC_E_OK) || (pCertContextServer == NULL)) { + if((sspi_status != SEC_E_OK) || (pCertContextServer == NULL)) { + char buffer[STRERROR_LEN]; failf(data, "schannel: Failed to read remote certificate context: %s", - Curl_sspi_strerror(conn, status)); + Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer))); result = CURLE_PEER_FAILED_VERIFICATION; } @@ -450,8 +458,9 @@ CURLcode Curl_verify_certificate(struct connectdata *conn, int sockindex) CERT_STORE_CREATE_NEW_FLAG, NULL); if(!trust_store) { + char buffer[STRERROR_LEN]; failf(data, "schannel: failed to create certificate store: %s", - Curl_strerror(conn, GetLastError())); + Curl_strerror(GetLastError(), buffer, sizeof(buffer))); result = CURLE_SSL_CACERT_BADFILE; } else { @@ -477,9 +486,10 @@ CURLcode Curl_verify_certificate(struct connectdata *conn, int sockindex) CertCreateCertificateChainEngine( (CERT_CHAIN_ENGINE_CONFIG *)&engine_config, &cert_chain_engine); if(!create_engine_result) { + char buffer[STRERROR_LEN]; failf(data, "schannel: failed to create certificate chain engine: %s", - Curl_strerror(conn, GetLastError())); + Curl_strerror(GetLastError(), buffer, sizeof(buffer))); result = CURLE_SSL_CACERT_BADFILE; } } @@ -500,8 +510,9 @@ CURLcode Curl_verify_certificate(struct connectdata *conn, int sockindex) CERT_CHAIN_REVOCATION_CHECK_CHAIN), NULL, &pChainContext)) { + char buffer[STRERROR_LEN]; failf(data, "schannel: CertGetCertificateChain failed: %s", - Curl_sspi_strerror(conn, GetLastError())); + Curl_strerror(GetLastError(), buffer, sizeof(buffer))); pChainContext = NULL; result = CURLE_PEER_FAILED_VERIFICATION; } -- cgit v1.2.3