Re: 7.58.0 curl_global_sslset returns CURLSSLSET_TOO_LATE
Date: Tue, 28 Jan 2020 23:10:32 -0500
On 1/28/2020 8:09 PM, Pawel Veselov wrote:
> On Wed, Jan 29, 2020 at 1:09 AM Ray Satiro<raysatiro_at_yahoo.com> wrote:
>> On 1/28/2020 5:13 PM, Pawel Veselov wrote:
>>
>> On Tue, Jan 28, 2020 at 10:24 PM Ray Satiro via curl-library<curl-library_at_cool.haxx.se> wrote:
>>> On 1/28/2020 1:17 PM, Pawel Veselov via curl-library wrote:
>>>> I have a simple prologue code in my program to select SSL backend. It
>>>> works on relatively
>>>> recent versions (e.g. 7.65), but specifically on 7.58 ("latest" for
>>>> Ubuntu 18),
>>>> curl_global_sslset() returns CURLSSLSET_TOO_LATE.
>>>> I thought somebody else may be calling init function, but I can see
>>>> from the source code
>>>> that it simply returns TOO_LATE if there are no multiple SSL backends,
>>>> and if ID
>>>> doesn't match the ID of the backend that was actually compiled in.
>>>>
>>>> Could you please save me some investigative time and let me know in
>>>> which version
>>>> was this changed so that calling this with without IDs returns list of
>>>> available backends even
>>>> in case of single backend?
>>> sslset also returns too late if it has been called after global init.
>> global init hasn't been called.
>>
>>> How are you calling it, with name or id?
>> I just want the list, so I pass id of -1 and name of 0.
>>
>>> There was an issue when id was
>>> set to -1 that was fixed [1] a year ago. Also there was an improvement
>>> in 7.60 to return the backends even if too late [2]. The change is
>>> documented you could test for it like this:
>>>
>>> if(rc != CURLSSLSET_OK) {
>>> curl_version_info_data *verinfo = curl_version_info(CURLVERSION_NOW);
>>> if(verinfo->version_num >= CURL_VERSION_BITS(7,60,0)) {
>>> /* backend list available even if CURLSSLSET_TOO_LATE */
>>> }
>>> }
>> Ah, I see. The bone that I have to pick with this is that return of
>> TOO_LATE can happen because either global init was called, or
>> because there is only one backend (and I didn't guess right), and
>> I can't really tell the difference.
>>
>> The whole deal here is that I want to prevent getting libcurl with one
>> backend in particular. I guess my logic should be:
>> * call sslset with -1/NULL. If that gives me a list of backends,
>> pick the one that I want, and call sslset again, and see if it worked
>> * If there was no list of backends, try to call with the bad
>> backend ID, and see if then it succeeds. If it does, then I have
>> a backend I don't want
>>
>>
>> To be clear it is supposed to work as it is documented [1].
>> If it does not work that way (aside from that known bug in early versions) please let us know.
>> I don't know why you would try to set the backend you don't want.
> I was trying to figure out a good way to workaround #3346
> for versions that still have it.
>
>> Do you mean you need to know if a particular backend is in use?
> Yes. If a particular backend is in use, I want to not let my
> application continue,
> and if I have a choice - pick any other backend except for that one I dislike
> and NONE:)
>
>> We don't have a curl_global_sslget [2].
> That's a pity. But even if it was added now, I would still need to make the
> logic work for earlier versions (reasonably, but I need, for example,
> to support Ubuntu 16 that uses 7.47).
>
>> [1]:https://curl.haxx.se/libcurl/c/curl_global_sslset.html
>> [2]:https://github.com/curl/curl/pull/2063
> Thank you for your help!
Well the workaround I mentioned in that bug does work, you can see how
we used it [1] in the curl tool. Basically after curl has initialized
you can call curl_easy_init [2] to create an easy handle (note if you do
this before initializing curl, it will call initialization for you) and
then get the backend of that handle. Currently the backend is set
globally and can't be changed but it could be improved at some point to
allow it per handle, which I think is part of why I got a lukewarm
reception to add a global way to get the backend.
In your case you would use CURLINFO_TLS_SESSION [4] the predecessor to
CURLINFO_TLS_SSL_PTR [3]. Although it is not documented (I will change
this) only since 7.45.0 it will always return the backend in use [5]. So
you could do it like this:
/* initialize curl before calling curl_version_info */
if(!(verinfo->features & CURL_VERSION_SSL)) {
problem = true; /* may happen */
}
else if(verinfo->version_num < CURL_VERSION_BITS(7,45,0)) {
/* no multiple ssl backends and no ssl backend constants */
sslver = duplowercase(verinfo->ssl_version);
if(!sslver) /* shouldn't happen */
abort();
if(strstr(sslver, "openssl")) /* may happen */
problem = true;
free(sslver);
else {
CURL *curltls = curl_easy_init();
struct curl_tlssessioninfo *tbi = NULL;
CURLcode rc = curl_easy_getinfo(curltls, CURLINFO_TLS_SESSION, &tbi);
if(rc || tbi->backend == CURLSSLBACKEND_NONE) { /* shouldn't happen */
curl_easy_cleanup(curltls);
abort();
}
if(tbi->backend == CURLSSLBACKEND_OPENSSL) /* may happen */
problem = true;
curl_easy_cleanup(curltls);
}
Working with the string compare has some caveats because like in the
case of openssl it doesn't the forks. For example you may have libressl
or boringssl which are forks of openssl. Or how wolfssl was formerly
known as cyassl. Or how mbedtls was formerly known as polarssl. There
are probably others, so you may find it hard to do accurately in old
versions of curl without some research.
[1]:
https://github.com/curl/curl/blob/curl-7_68_0/src/tool_operate.c#L2273-L2290
[2]: https://curl.haxx.se/libcurl/c/curl_easy_init.html
[3]: https://curl.haxx.se/libcurl/c/CURLINFO_TLS_SESSION.html
[4]: https://curl.haxx.se/libcurl/c/CURLINFO_TLS_SSL_PTR.html
[5]: https://github.com/curl/curl/commit/7362008
-------------------------------------------------------------------
Unsubscribe: https://cool.haxx.se/list/listinfo/curl-library
Etiquette: https://curl.haxx.se/mail/etiquette.html
Received on 2020-01-29