Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

support CAfile in memory #6109

Closed
wants to merge 1 commit into from
Closed

Conversation

gvollant
Copy link
Contributor

@gvollant gvollant commented Oct 21, 2020

Adds CURLOPT_CAINFO_PEM and CURLOPT_PROXY_CAINFO_PEM that let applications provide the CA bundle to libcurl as a PEM formatted in-memory buffer.

@bagder bagder changed the title rebased branch bundled_cacert from moparisthebest like #4679 #5677 support CAfile in memory Oct 21, 2020
@bagder
Copy link
Member

bagder commented Oct 21, 2020

It'd be helpful if you provided a description in this PR so that we can tell what this PR is!

@gvollant
Copy link
Contributor Author

I added on my fork https://github.com/gvollant/curl a rebased version of #4679
I invite @moparisthebest on my curl fork. He made the real work

I just wanted a rebased version of this PR to test it against current curl master

Validation : 397e11b [397e11b]
Parents : 4506607
Auteur : moparisthebest admin@moparisthebest.com
Date : vendredi 3 avril 2020 00:32:42
Auteur : moparisthebest
Date de validation : samedi 4 avril 2020 00:31:23
Add CURLOPT_CAINFO_PEM

original description:
This is a first go at bundling cacert.pem into the curl binary, which I plan to use for the static-curl binaries.

It works for openssl right now, but I don't actually expect you want a ~19k line cacert.h file in source control, so I'm looking for guidance on how you might accept a feature like this.

Options I've thought of:

Leave it as-is except CACERT_PEM_LEN set to 0 and the array empty, then if someone wants to hard-code a few, they run the curl+xxd command before compilation. This does make the CACERT_PEM_LEN check happen at runtime.
Option 1, but where the include/used code is wrapped in a #ifdef BUNDLE_CACERT or similar, not sure if this would allow the configure script to generate the file automatically with a --bundle-cacert=/path/to/cacert.pem option or so
Directly embedding the binary cacert.pem into the executable like this which was based on this, presumably gated by a configure flag+ifdef again, but I have no idea how sane and/or portable this is.

@JCMais want work on this PR

@gvollant
Copy link
Contributor Author

@moparisthebest I also invited you on my curl fork git repo

@bagder
Copy link
Member

bagder commented Oct 21, 2020

I understand that and I think it's all good. I just think a PR submitted to the porject should have a description if title isn't detailed enough, so that we all can read and understand what it is about without having to click around and read up on older closed previous pull-requests with their own individual histories.

@JCMais
Copy link
Contributor

JCMais commented Oct 22, 2020

What I'm most interested in about this PR is the CURLOPT_CAINFO_PEM option, which is already implemented, not so much about the other features.

If we can get this merged and then work later on the remaining parts to get the ca file bundled in the binary directly, it would be better.

macOS build is failing on the brew install step, which seems unrelated to this PR.

@bagder
Copy link
Member

bagder commented Oct 22, 2020

The github actions CI jobs seem to have gone nuts and "brew install" fails almost all the time the last few days... :-/

@nadrolinux
Copy link

Do you know when this feature may be finished?

@gvollant gvollant force-pushed the gv_bundled_cacert branch 3 times, most recently from ff88b0d to fadb293 Compare November 14, 2020 20:24
@gvollant
Copy link
Contributor Author

It seem unsucessful check are same than other recent PR

@gvollant
Copy link
Contributor Author

@bagder I believe the test error are same than other current PR ?

@bagder
Copy link
Member

bagder commented Nov 17, 2020

I'm sorry, I'm still waiting for a description of this PR. Please update.

@JCMais
Copy link
Contributor

JCMais commented Nov 17, 2020

@gvollant I think that what @bagder means is that you should put these in the PR description, not as a comment.

@gvollant
Copy link
Contributor Author

@gvollant I think that what @bagder means is that you should put these in the PR description, not as a comment.

Ok, I updated the first comment

@gvollant
Copy link
Contributor Author

@moparisthebest @JCMais @nadrolinux I suggest you test this rebased version

@bagder
Copy link
Member

bagder commented Dec 6, 2020

There are still questions in the description. Is this then still work in progress or even actually a draft?

@gvollant
Copy link
Contributor Author

gvollant commented Dec 6, 2020

for me it is a draft

@gvollant
Copy link
Contributor Author

gvollant commented Dec 6, 2020

your review is welcome

@bagder bagder marked this pull request as draft December 6, 2020 22:23
@ghost
Copy link

ghost commented Feb 17, 2021

Congratulations 🎉. DeepCode analyzed your code in 10.511 seconds and we found no issues. Enjoy a moment of no bugs ☀️.

👉 View analysis in DeepCode’s Dashboard | Configure the bot

@gvollant
Copy link
Contributor Author

Retry DeepCode

@gvollant
Copy link
Contributor Author

@bagder hello, I have no idea about the "DeepCode failed to analyze this pull request" message...

@bagder
Copy link
Member

bagder commented Feb 18, 2021

That's just deepcode being silly. Ignore it.

Copy link
Member

@bagder bagder left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The commit message must explain the change it brings.

or more certificates to verify the HTTPS server with.

If \fICURLOPT_SSL_VERIFYPEER(3)\fP is zero and you avoid verifying the
server's certificate, \fICURLOPT_CAINFO(3)\fP need not even indicate an
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You meant it to say CURLOPT_CAINFO_PEM here? The text talks about "accessible file" and I don't understand why this is present for this option that doesn't even work with files?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just say now CURLOPT_CAINFO_PEM is not needed

lib/urldata.h Outdated Show resolved Hide resolved
lib/vtls/openssl.c Show resolved Hide resolved
lib/urldata.h Outdated
@@ -254,6 +254,7 @@ struct ssl_primary_config {
char *pinned_key;
struct curl_blob *cert_blob;
char *curves; /* list of curves to use */
char *ca_file_pem;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why call this 'file' when it isn't a file at all? It points to a buffer holding PEM formatting, right?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

replaced all ca_file_pem by ca_info_pem

@@ -3025,6 +3081,15 @@ static CURLcode ossl_connect_step1(struct Curl_easy *data,
infof(data, "error importing windows ca store, continuing anyway\n");
}
#endif
if(ca_file_pem && load_cacert_from_memory(backend->ctx, ca_file_pem)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

load_cacert_from_memory() returns a CURLcode but here you ignore that and just assumes the error is always due to badfile. Isn't it better to use the passed back return code?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I rewrote this line and return the result of load_cacert_from_memory

docs/libcurl/opts/CURLOPT_CAINFO_PEM.3 Show resolved Hide resolved


The application does not have to keep the string around after setting this
option.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This description doesn't say (yet), but I got curious: what happens if a user sets both *CAINFO and *CAINFO_PEM ? Does one of them override the other or how does it work? I think we need to explain.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

load_cacert_from_memory just add certificate. I moved it after loading *CAINFO, so both are loaded.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Then please mention in the man page that this provided PEM data is used in addition to any other CA certs loaded with other option(s).

@gvollant gvollant force-pushed the gv_bundled_cacert branch 5 times, most recently from 8b5d11f to 4cd02dc Compare February 23, 2021 07:41
@gvollant
Copy link
Contributor Author

gvollant commented Feb 23, 2021

@jay @bagder After thinking, there is pro and cons using a string or a curl_blob

For string:

  • current PR use string, so we don't need rewrite it. More chance include in next curl revision
  • string are more easy to use from no-C curl binding

for curl_blob

  • there is the no_copy option, so if user create 10 curl connexion object at same time, the string is not duplicated
  • if user call a decompress/decrypt code which give him the PEM string without '\0' terminator, he can call curl_blob without need to copy on another buffer


/* if we didn't end up importing anything, treat that as an error */
if(count > 0)
result = CURLE_OK;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I find this comment slightly misleading since the return code of the import functions is not checked. I don't think it should fail if there was nothing to import in the certificate, and I wonder if it should fail at all since other certificates may be read in. Maybe make it always a warning instead of just in the insecure case. Interested in what others think about this.

Copy link
Member

@jay jay Feb 24, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here's another thing, every time an X509_store_add_ is called it increases the reference count, so what if it's called twice don't you have to free two objects x509 and crl?

"X509_STORE_add_cert() and X509_STORE_add_crl() add the respective object to the X509_STORE's local storage. Untrusted objects should not be added in this way. The added object's reference count is incremented by one, hence the caller retains ownership of the object and needs to free it when it is no longer needed."

Edit: Nevermind I think I misinterpreted it. We actually do want the objects to have an increased reference count since they are now part of the x509 store, the reference count having later been decremented by X509_INFO_free

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I find this comment slightly misleading since the return code of the import functions is not checked.
This was true on first version, but now load_cacert_from_memory value is checked (as requester by @bagder ).

But I think we must remove this test and don't fail if there is nothing to import.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, I removed the test

@jay
Copy link
Member

jay commented Feb 24, 2021

for curl_blob

CURLOPT_CAINFO_BLOB would be consistent with some of the other ssl cert blob options. Also those blob options allow ASN1 binary format as well, I think, even if they are not documented that way.



The application does not have to keep the string around after setting this
option.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Then please mention in the man page that this provided PEM data is used in addition to any other CA certs loaded with other option(s).

return result;
}
/* Only warning if no certificate verification is required. */
infof(data, "error setting certificate file, continuing anyway\n");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. It didn't "set" a file though, did it? It failed to import a CA cert from the given PEM buffer, right?
  2. Also, is that really a reason for failing the connection? What if a CA bundle on file is also used?
  3. If the function failed due to out of memory I think it should fail no matter what

++count;
}
if(itmp->crl) {
X509_STORE_add_crl(cts, itmp->crl);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So the PEM buffer can also provide a CRL! Should be mentioned in the docs, right?

@bagder
Copy link
Member

bagder commented Feb 25, 2021

for curl_blob
* there is the no_copy option, so if user create 10 curl connexion object at same time, the string is not duplicated

I think this is an excellent point that I hadn't though of before! What a difficult decision... But I'll confess I now maybe lean towards a blob! 😨

@gvollant
Copy link
Contributor Author

I opened another PR #6662 with a blob version.

When decision will be made between CURLOPT_CAINFO_PEM and CURLOPT_CAINFO_BLOB , one of these PR will need to be closed

@gvollant
Copy link
Contributor Author

My option is that #6662 is better.

…Y_CAINFO_PEM

Let applications provide the CA bundle to libcurl as a PEM formatted in-memory buffer.

Rebased branch bundled_cacert from moparisthebest

Validation : 397e11b [397e11b]
Parents : 4506607
Auteur : moparisthebest <admin@moparisthebest.com>
Date : vendredi 3 avril 2020 00:32:42
Auteur : moparisthebest
Date de validation : samedi 4 avril 2020 00:31:23
Add CURLOPT_CAINFO_PEM
@gvollant
Copy link
Contributor Author

gvollant commented Mar 6, 2021

Jay worked on new #6662, so I close this PR

@gvollant gvollant closed this Mar 6, 2021
jay pushed a commit that referenced this pull request May 5, 2021
- New options CURLOPT_CAINFO_BLOB and CURLOPT_PROXY_CAINFO_BLOB to
  specify in-memory PEM certificates for OpenSSL, Schannel (Windows)
  and Secure Transport (Apple) SSL backends.

Prior to this change PEM certificates could only be imported from a file
and not from memory.

Co-authored-by: moparisthebest@users.noreply.github.com

Ref: #4679
Ref: #5677
Ref: #6109

Closes #6662
@gvollant
Copy link
Contributor Author

gvollant commented May 5, 2021

#6662 is now merged with CA as blob

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Development

Successfully merging this pull request may close these issues.

None yet

5 participants