-
Notifications
You must be signed in to change notification settings - Fork 237
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
Add support for in-memory certificates #384
Conversation
Thanks for this! This all looks reasonable to me, and I think it's ok if you've tested locally to not worry too much about adding tests to CI. It does look like there are some CI failures, although they're likely unrelated to this PR. Would you be up for helping to investigate them though? |
Sure, I'd be happy to look into the CI failures. TBH, I starting looking into them yesterday, but I'm pretty new to working with Github's CI, so I didn't get very far. Looks like In any case, any tips on where to start investigating would be helpful and I can take it from there! |
Oh actually the failing line is this one -- Lines 87 to 91 in 64e8fc2
|
Updated the commit to fix the submodule version. |
I believe one of the errors is due to a mismatch between the |
Hm, looks like you're right; I'll change it to |
Since the pointer is being passed across FFI into C, as long as we aren't mutating the reference from the Rust side, and as long as libcurl isn't mutating it, I think it would be safe to cast the |
Alternatively, for a less risky approach, we could take an |
Actually now that I think about it, that might be the way to support zero-copy certs which might be nice. As you said in the PR description:
Just let the handle take ownership of the data and allow the user to either pass borrowed bytes (in which case we do a copy), or owned bytes, in which case we don't do any copies. Maybe something like this: pub fn proxy_sslcert_blob<B: Into<Vec<u8>>>(&mut self, blob: B) -> Result<(), Error> {
self.proxy_sslcert_blob = Some(blob.into());
unsafe {
self.setopt_blob(curl_sys::CURLOPT_PROXY_SSLCERT_BLOB, self.proxy_sslcert_blob.as_deref().unwrap(), false)
}
}
unsafe fn setopt_blob(&mut self, opt: curl_sys::CURLoption, val: &[u8], copy: bool) -> Result<(), Error> {
let blob = curl_sys::curl_blob {
data: val.as_ptr() as *const c_void as *mut c_void,
len: val.len(),
flags: if copy {
curl_sys::CURL_BLOB_COPY
} else {
curl_sys::CURL_BLOB_NOCOPY
},
};
let blob_ptr = &blob as *const curl_sys::curl_blob;
self.cvt(curl_sys::curl_easy_setopt(self.inner.handle, opt, blob_ptr))
} Still tedious since it means we have to keep track of every blob given, but it would allow setting certificates without making any copies. If a I'm assuming here that curl expects the blob to be kept alive for the duration of the easy handle, or until it is replaced by a subsequent |
25f0766
to
7087ee5
Compare
I've updated my commit to mirror the methods on In addition, I've added a second commit that implements zero-copy certificates using the approach described earlier. I separated this change since it introduces quite a bit of unsafety, so it probably needs some closer scrutiny on its own. |
Looks good! I'm not sure if there's much use storing the blobs internally though. The purpose of zero-copy I would imagine is that the curl bindings here wouldn't allocate them at all (as currently happens with I think it's probably fine for now, since these are just ssl certs, to copy the bytes into curl and if it's ever an issue we could add more apis with more lifetimes that elides the copy. |
I have no strong opinion either way wrt to zero-copy, so I'm fine with just merging my first commit. @sagebind, do you have any thoughts here? |
This seems like a very reasonable approach to me. 👍 |
OK, in that case I've dropped my second commit from this branch, leaving just my initial approach. |
Pull in new bindings for the new blob APIs added to curl in 2020. Bindings were recently added in alexcrichton/curl-rust#384. This of course only works when using a fairly new curl version. Addresses #89.
Pull in new bindings for the new blob APIs added to curl in 2020. Bindings were recently added in alexcrichton/curl-rust#384. This of course only works when using a fairly new curl version. Addresses #89.
This adds support for passing SSL certificates as in-memory blobs using several new options added in libcurl
7.71.0
:CURLOPT_SSLCERT_BLOB
CURLOPT_SSLKEY_BLOB
CURLOPT_PROXY_SSLCERT_BLOB
CURLOPT_PROXY_SSLKEY_BLOB
CURLOPT_ISSUERCERT_BLOB
Notably, this PR does not add support for
CURLOPT_PROXY_ISSUERCERT_BLOB
since this crate does not presently supportCURLOPT_PROXY_ISSUERCERT
(and adding support for that is somewhat orthogonal to this PR).In order to implement the above, this PR also adds support for the new
CURLOPTTYPE_BLOB
option type (and the correspondingCurl_setblobopt
setter function). Although the C API allows the caller to specify whether the data should be copied or not, the safe interface here always copies the data since there doesn't seem to be a straightforward way to make the lifetimes work out otherwise.I'm not sure how to add automated tests for this since this crate's test suite currently doesn't seem to be able to test SSL at all. I've been able to verify that this works in small test programs on Linux/OpenSSL using P12 certificates, but have not tested on other platforms using other certificate formats and SSL engines.