Skip to content

add_cert_to_certinfo should reverse the order of the certificates for SChannel #4518

@RoguePointer80

Description

@RoguePointer80

I did this

Context : we have a unit test that is using libCurl built with OpenSSL. We recently changed the SSL backend to WinSSL (SChannel), and one of our unit tests broke. The following is what the unit test is essentially doing, and what is wrong.

curl_certinfo* pCertinfo = nullptr;
curl_easy_getinfo(m_pSession, CURLINFO_CERTINFO, &pCertinfo);
...
if (pCertinfo!= nullptr && pCertinfo->num_of_certs > 0) {
   std::string subject = ExtractSubjectFromCert(pCertInfo->certinfo[0]);
   UNIT_TEST_ASSERT(expectedSubject, subject);
}

Notice here that the method only looks at index 0 in the array, that is the first certificate.
It worked well with OpenSSL for many years.
However it appears that with SChannel, the order of the certificates in the chain is reversed.
With OpenSSL, the peer is the first index, while with SChannel it is the last.
OpenSSL is following an RFC.
Ref: https://curl.haxx.se/mail/lib-2018-10/0099.html
While SChannel "Finds a certificate context that contains the end certificate supplied by the server."
Ref: https://docs.microsoft.com/en-us/windows/win32/api/sspi/nf-sspi-querycontextattributesexa

I expected the following

I expected that the order of the certificates would be the same when changing the backend. I suggest using the OpenSSL order, i.e. the peer certificate first as it is detailed in an RFC and this order has been in the code base for longer than SChannel.

Suggestion

File : lib/vtls/schannel.c
the method add_cert_to_certinfo should be modified. We could add to Adder_args the total number of certificates, and inside add_cert_to_certinfo instead of passing (args->idx)++, then pass total_certs -1 - (args->idx)++. Ok I admit this last one is hard to read, but the idea is "total - currentIndex".

curl/libcurl version

7.65.1

[curl -V output]

operating system

Windows 10, version 1903.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions