Schannel read certs simplify#21760
Conversation
|
CI test failures seem related to the changes made: |
This comment was marked as resolved.
This comment was marked as resolved.
|
Yes, I'm currently dealing with errors in the tests. curl returns |
|
If I use |
|
Okay, I really can't understand why only But I suggest leaving points 2–3 as they are (these changes are already in the PR). Could you rerun the tests, please? I think they were canceled not because of my changes. UPD: I used the wrong flag: Maybe, later, would you like to support certificates in DER format as well? |
| cert_blob.pbData = (BYTE *)CURL_UNCONST(begin_cert_ptr); | ||
| cert_blob.cbData = cert_size; | ||
| /* Caution: CryptQueryObject() is deprecated */ | ||
| /* Caution: this API is deprecated */ |
There was a problem hiding this comment.
In documentation: "This API is deprecated.". Not function.
There was a problem hiding this comment.
I agree with the LLM here, the pre-existing form was more readable without knowing the surrounding line, e.g. in a grep hit. Perhaps keep the original?
There was a problem hiding this comment.
Maybe delete this comment because the Windows documentation says, first of all, that CryptoAPI 1.0 is deprecated and recommends using CNG instead. However, this function belongs to CryptoAPI 2.0, and CNG has no equivalent for it.
For example, the functions CryptDecodeObject, CryptStringToBinary, and CertCreateCertificateContext are not deprecated. The code could be rewritten equivalently using these functions. However, it seems to me that CryptQueryObject handles this task well. Using CNG, as recommended by Microsoft in the documentation, it does not seem possible to do the same thing.
In general, CryptoAPI functions that deal with ASN.1 data structures (certs, CSRs, CRLs and the like) are not deprecated and have no counterpart in CNG API. Maybe this one was marked as deprecated by mistake.
For what its worth take a look at the sample code in what-is-new-alternative-for-cryptqueryobject-because-it-is-deprecated
But the link to the example is not available.
There was a problem hiding this comment.
Agree, but I still see no reason to alter or delete this comment:
The information/form is valid, even if we don't readily want
to replace this particular function, and such change also seems
unrelated to the purpose of the PR.
curl's documentation says PEM format is required, and there wasn't any request TL;DR IMO DER support is not desired in this case. |
hm. CURLOPT_CAINFO technically does not specify the format for the certificates, yet this PR changes the certificate loading procedure to only allow base64 style certificates. Though the tool option --cacert (which maps to CURLOPT_CAINFO) does specify PEM only. So I wonder if this will break anything for anyone. |
It shouldn't break because the code requires a Base64 header. curl/lib/vtls/schannel_verify.c Lines 131 to 137 in 3d721a1 |
Ok I took a closer look and you're right. I see the certificate data is extracted from in between "-----BEGIN CERTIFICATE-----" and "-----END CERTIFICATE-----" and then passed to CryptQueryObject. According to that doc setting dwExpectedFormatTypeFlags with the flag CERT_QUERY_FORMAT_FLAG_BASE64_ENCODED indicates "the expected format of the returned type" which to me seems somewhat unclear because it doesn't say expected format of the input content. In other words I wonder if it is possible for the input content to have a different format and the function to be successful. Regardless, if the expected content type is CERT_QUERY_CONTENT_FLAG_CERT, then I don't see a problem with removing the checks to see what the actual content type is since if the function is successful it should have the expected content type. |
I understand your concerns about the dwExpectedFormatTypeFlags parameter. Indeed, the documentation uses a strange wording. But this flag means that the input data needs to be interpreted exactly as Base64. For example, the description of the CERT_QUERY_FORMAT_FLAG_BASE64_ENCODED flag "The content should be returned in Base64 encoded format" is also strange. The function does not return content in Base64 format. If it is a certificate, a pointer to CERT_CONTEXT will be returned. It cannot contain data in Base64. I am sure that this flag indicates exactly the type of input data. I can send you tests that will confirm my claim. If you still want to leave using the CERT_QUERY_FORMAT_FLAG_ALL flag, then I can do this. If I understand correctly, then the function shouldn't have much more work. Or I can make a more reliable change by enlarging the code a bit. Replace CryptQueryObject with CryptStringToBinary+CertCreateCertificateContext. It will be more explicit. Did I understand correctly that you agree with the rest of the changes? |
|
It's fine no more changes are needed. I think the MS documentation is unclear so I submitted MicrosoftDocs/sdk-api#2221. |
|
Thanks |
In
schannel_verify.c,CryptQueryObjectis used to get input certificates. Before callingCryptQueryObject, the code parses the data and expects that the data will be in Base64. My changes are:CERT_QUERY_FORMAT_BASE64_ENCODEDflag inCryptQueryObject, because the data is always expected to be in Base64.CryptQueryObjectwill return FALSE.CertFreeCertificateContext.