I'm hitting what I think is two problems using CURLOPT_CAINFO with the schannel backend.
The issues stem from making requests concurrently from multiple threads specifing the same file in CURLOPT_CAINFO. If I run the code below on multiple threads concurrently, some number of them fail, and print out: "ERROR: Problem with the SSL CA cert (path? access rights?) - schannel: failed to open CA file '<path to PEM file>': Broken pipe" CURL *curl = curl_easy_init(); char error[CURL_ERROR_SIZE]; curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, error); curl_easy_setopt(curl, CURLOPT_FILE, nullptr); curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); curl_easy_setopt(curl, CURLOPT_CAINFO,"<path to PEM file>"); int res = curl_easy_perform(curl); if (res != CURLE_OK) { std::cerr << "ERROR: " << curl_easy_strerror(res) << " - " << std::string(error) << "\n"; } curl_easy_cleanup(curl); I believe this is because in schannel_verify.c the ca_file provided in CURLOPT_CAINFO is opened (via CreateFile) with the (default) share mode of 0. From MSDN this "Prevents other processes from opening a file or device if they request delete, read, or write access." This is fixed by passing FILE_SHARE_READ to the call to CreateFile. Any reason why the "no sharing allowed" mode was chosen here instead? The second issue is in how the Windows error is converted to a string. I believe when CreateFile fails GetLastError is returning 32 (ERROR_SHARING_VIOLATION) but the string version is "Broken Pipe" which suggests POSIX errno is being used rather than Windows errors. This is Curl_strerror which is used widely, so not sure of consequences of making a change there. Any thoughts? -- Richard ------------------------------------------------------------------- Unsubscribe: https://cool.haxx.se/list/listinfo/curl-library Etiquette: https://curl.haxx.se/mail/etiquette.html