Rustls is a modern TLS library written in Rust.
Rustls is used in production at many organizations and projects. We aim to maintain reasonable API surface stability but the API may evolve as we make changes to accommodate new features or performance improvements.
We have a roadmap for our future plans. We also have benchmarks to prevent performance regressions and to let you evaluate rustls on your target hardware.
If you'd like to help out, please see CONTRIBUTING.md.
The detailed list of changes in each release can be found at https://github.com/rustls/rustls/releases.
Rustls is a TLS library that aims to provide a good level of cryptographic security, requires no configuration to achieve that security, and provides no unsafe features or obsolete cryptography by default.
Rustls implements TLS1.2 and TLS1.3 for both clients and servers. See the full list of protocol features.
While Rustls itself is platform independent, by default it uses aws-lc-rs
for implementing
the cryptography in TLS. See the aws-lc-rs FAQ for more details of the
platform/architecture support constraints in aws-lc-rs.
ring
is also available via the ring
crate feature: see
the supported ring
target platforms.
By providing a custom instance of the crypto::CryptoProvider
struct, you
can replace all cryptography dependencies of rustls. This is a route to being portable
to a wider set of architectures and environments, or compliance requirements. See the
crypto::CryptoProvider
documentation for more details.
Specifying default-features = false
when depending on rustls will remove the
dependency on aws-lc-rs.
Rustls requires Rust 1.63 or later. It has an optional dependency on zlib-rs which requires 1.75 or later.
Since Rustls 0.22 it has been possible to choose the provider of the cryptographic primitives
that Rustls uses. This may be appealing if you have specific platform, compliance or feature
requirements that aren't met by the default provider, aws-lc-rs
.
Users that wish to customize the provider in use can do so when constructing ClientConfig
and ServerConfig
instances using the with_crypto_provider
method on the respective config
builder types. See the crypto::CryptoProvider
documentation for more details.
Rustls ships with two built-in providers controlled with associated feature flags:
aws-lc-rs
- enabled by default, available with theaws_lc_rs
feature flag enabled.ring
- available with thering
feature flag enabled.
See the documentation for crypto::CryptoProvider
for details on how providers are
selected.
The community has also started developing third-party providers for Rustls:
rustls-mbedtls-provider
- a provider that usesmbedtls
for cryptography.boring-rustls-provider
- a work-in-progress provider that usesboringssl
for cryptography.rustls-rustcrypto
- an experimental provider that uses the crypto primitives fromRustCrypto
for cryptography.rustls-post-quantum
: an experimental provider that adds support for post-quantum key exchange to the default aws-lc-rs provider.rustls-wolfcrypt-provider
- a work-in-progress provider that useswolfCrypt
for cryptography.
We also provide a simple example of writing your own provider in the custom-provider
example. This example implements a minimal provider using parts of the RustCrypto
ecosystem.
See the Making a custom CryptoProvider section of the documentation for more information on this topic.
Our examples directory contains demos that show how to handle I/O using the
stream::Stream
helper, as well as more complex asynchronous I/O using mio
.
If you're already using Tokio for an async runtime you may prefer to use
tokio-rustls
instead of interacting with rustls directly.
The mio
based examples are the most complete, and discussed below. Users
new to Rustls may prefer to look at the simple client/server examples before
diving in to the more complex MIO examples.
The MIO client example program is named tlsclient-mio
.
Some sample runs:
$ cargo run --bin tlsclient-mio -- --http mozilla-modern.badssl.com
HTTP/1.1 200 OK
Server: nginx/1.6.2 (Ubuntu)
Date: Wed, 01 Jun 2016 18:44:00 GMT
Content-Type: text/html
Content-Length: 644
(...)
or
$ cargo run --bin tlsclient-mio -- --http expired.badssl.com
TLS error: InvalidCertificate(Expired)
Connection closed
Run cargo run --bin tlsclient-mio -- --help
for more options.
The MIO server example program is named tlsserver-mio
.
Here's a sample run; we start a TLS echo server, then connect to it with
openssl
and tlsclient-mio
:
$ cargo run --bin tlsserver-mio -- --certs test-ca/rsa-2048/end.fullchain --key test-ca/rsa-2048/end.key -p 8443 echo &
$ echo hello world | openssl s_client -ign_eof -quiet -connect localhost:8443
depth=2 CN = ponytown RSA CA
verify error:num=19:self signed certificate in certificate chain
hello world
^C
$ echo hello world | cargo run --bin tlsclient-mio -- --cafile test-ca/rsa-2048/ca.cert -p 8443 localhost
hello world
^C
Run cargo run --bin tlsserver-mio -- --help
for more options.
Rustls is distributed under the following three licenses:
- Apache License version 2.0.
- MIT license.
- ISC license.
These are included as LICENSE-APACHE, LICENSE-MIT and LICENSE-ISC respectively. You may use this software under the terms of any of these licenses, at your option.
- Joe Birr-Pixton (@ctz, Project Founder - full-time funded by Prossimo)
- Dirkjan Ochtman (@djc, Co-maintainer)
- Daniel McCarney (@cpu, Co-maintainer - full-time funded by Prossimo)
- Josh Aas (@bdaehlie, Project Management)
This project adopts the Rust Code of Conduct. Please email [email protected] to report any instance of misconduct, or if you have any comments or questions on the Code of Conduct.
rustls-native-certs's People
Forkers
elf-bot termux zanehannanau freaky iocloud-me alex backwardn keruspe kwantam est31 djc detly briansmith seanpianka jsha g2p lukemauldin pimterry austin-open-source ry darsvador bnoordhuis evanrichter systemtruststores icodein geauxweisbeck4 takayuki-nakamura7 mokeyish timluq cpu cyberflamego jacktemaki daxpedda wasix-org tottoto atouchet nneesshh questdb lo236816 agentmishra 2bc4 pgerber ermakus tbrockman ginger51011rustls-native-certs's Issues
Release new version with updated dep
Is rustls-pemfile
a public dep ? If not, can a 0.6.2
version be published to crates.io
?
Problem with certificates after 0.7.1
So, as I found out, I had a certificate installed for a proxy or something like that, and apparently it didn't have the correct permissions set.
openat(AT_FDCWD, "/usr/lib/ssl/certs/f6eee659.0", O_RDONLY|O_CLOEXEC) = -1 EACCES (Permission denied)
But the interesting thing is that this problem appeared only after update 0.7.1, and before that it worked fine and probably missed a bad certificate.
Possibility to skip failed certificates instead of throwing error?
On my Windows machine I had a few certificates that had been added with wrong Intended Purpose flags. In the certificate store they identified themselves as capable of All purposes but when load_native_certs
tried to get them as DER a panic occured.
Running the tests on my machine, with the wrong certificate flags, causes this:
thread 'netflix' panicked at 'called `Result::unwrap()` on an `Err` value: Custom { kind: InvalidData, error:
BadDER }', src\libcore\result.rs:1165:5
I did not add these certificates myself and I'm not sure what software did, maybe it was my organization/company. In my case I was able to resolve this simply by unchecking the Server authentication purpose flag after locating which certificates caused the panic. The point is, at least in Windows, it appears certificates can be added with false purpose flags and having one of these in the store will put any app that depends on this crate to a halt.
I'm fine if this is the intended purpose, and I realize the error is with the certificate itself and not the crate, I just wanted to lift the question in case the crate should be more forgiving. It could just continue iterating remaining certificates if it fails converting one, or the behavior could be controlled by some configuration/parameter to support both cases.
Support for native private keys
Feature request: support not only CA root certificates but also native certificate/key chains.
The rationale is that in the enterprise environments private keys are often part of the system certificate store and are marked as non-exportable, therefore not usable by rustls. This applies mostly to Windows I think.
Not sure if this request falls into the scope of this crate though or there should be something like rustls-native-keys
.
The implementation would require then a native Signer
logic and a way to find a matching key chain (e.g. by fingerprint, serial number or a subject pattern).
Release 0.16.6 with ring 0.17
Considering that ring 0.17 has been backported for rustls 0.21 (rustls/rustls#1525) can we also get it backported for this crate too?
FreeBSD certs not found
I have a FreeBSD 13 system and I have uploaded my custom certs into /usr/local/share/certs/ca-root-nss.crt which allows OOTB curl to work. However, Rust programs (ex: rustup-init) built using rustls-native-certs do not check that location. I can work around the issue by setting the env variable SSL_CERT_FILE=/usr/local/share/certs/ca-root-nss.crt but I would like for that location to be searched by this crate.
finding corrupted certificate on MacOS Catalina
Hi! First of all, I'm no rust programmer or anything, I just want a thing that depends on a thing that depends on your thing to start to work so...
There was this problem mimblewimble/grin-wallet#554 and I traced it down to this https://github.com/ctz/hyper-rustls/blob/5a30ca520ab382bdeb06ba37a1401b6f5aeb971f/src/connector.rs#L42
I suspect it is one of my certificates that breaks it. I wanted to make something similar to what has been done here #4 (comment) which is, write a code snipped that shows which certificate breaks, I just have one that reproduces the problem
use rustls_native_certs::load_native_certs;
fn main() -> Result<(), Box<dyn std::error::Error>> {
let _dafuck = match rustls_native_certs::load_native_certs() {
Ok(store) => store,
Err((Some(store), err)) => {
println!("Could not load all certificates: {:?}", err);
store
}
Err((None, err)) => Err(err).expect("cannot access native cert store"),
};
Ok(())
}
is there any chance I can detect which certificate breaks it, then I can remove it / update it / whatever and world can become a happy place once again?
Thanks in advance!
RootStoreBuilder is under-specified
It isn't clear what is supposed to happen when a file is encountered that has a mix of valid and invalid data. Should the invalid certificates be skipped and loading continue with the valid ones, or should the functions fail fast, or is it up to the implementation?
Example "google" breaks with TLS introspection enabled.
Hi, I'm running in a corporate environment with TLS introspection enabled. Rustls just won't work at all, constantly returning InvalidCertificateData("invalid peer certificate: UnknownIssuer")
.
Is there some flag or config to enable to allow TLS introspection?
Windows - add computer certs
Current code in windows.rs only loads certificates from the user store: https://github.com/ctz/rustls-native-certs/blob/main/src/windows.rs#L19
In our use case, we push certificates group Group Policy into the computer store. Would also recommend querying schannel::cert_store::CertStore::open_local_machine to include computer certificates in the results.
Couldn't find 0.6.0 on crates.io
The release history in the readme mentions 0.6.0
, but I couldn't find the crate on crates.io. I couldn't find the 0.6.0
git tag on this repository as well.
[Windows] Consider adding other store names than `"ROOT"`
Hello, thanks for the good work on rustls!
I'm writing from inside the corporate world where certificates are pushed out on user machines, much like #22. I recently found out that while rustls-native-certs can detect certificates in the Root
certificate store, it fails to detect all that are needed in my environment.
I can open a PR for adding some other stores that are required for my use case, but I wanted to ask the question if it is desirable? Basically a change would look like this (in my case only CA
needs to be added, but the others might be a good idea):
// windows.rs
/// See <https://learn.microsoft.com/en-us/dotnet/framework/configure-apps/file-schema/wcf/certificate-of-clientcertificate-element?redirectedfrom=MSDN#attributes>
const CERTIFICATE_STORE_NAMES: &[&str] = [
"My", // -> Certificate store for personal certificates
"Root", // -> Trusted Root Certification Authorities
"Trust", // -> I'm honestly not quite sure; I believe trusted third parties. There doesn't seem to be a good list.
"CA", // -> Intermediate Certification Authorities
];
pub fn load_native_certs() -> CertificateResult {
let mut result = CertificateResult::default();
for store_name in CERTIFICATE_STORE_NAMES {
let current_user_store = match CertStore::open_current_user(store_name) {
Ok(store) => store,
Err(err) => {
result.os_error(
err.into(),
format!("failed to open current user certificate store '{store_name}'"),
);
return result;
}
};
for cert in current_user_store.certs() {
if usable_for_rustls(cert.valid_uses().unwrap()) && cert.is_time_valid().unwrap() {
result
.certs
.push(CertificateDer::from(cert.to_der().to_vec()));
}
}
}
result
}
The docs for CertStore::open_current_user
mentions the store names I have included here, and the source above the CERTIFICATE_STORE_NAMES
go into some detail.
security-framework is unmaintained
On macOS, rustls-native-certs depends on security-framework
which has been unmaintained for some time due to its maintainer resigning, and the repo has been archived:
- kornelski/rust-security-framework@3337db6
- https://github.com/kornelski/rust-security-framework/issues/188
Figured it's worth reporting this given that rustls-native-certs
has a pretty large blast radius (1.5k dependent crates, 2M downloads/m).
Account for "additional constraints" in the macOS (and Windows) certificate stores
From https://twitter.com/BasileBailey/status/1494801237694300161:
Just because a root certificate is in the built-in iOS/macOS trust store doesn't mean that it is trusted. Apple applies additional constraints via configuration updates to maintain a high-level of security. See https://support.apple.com/HT212865 for more detail.
It seems like this might be hinting that the approach taken by rustls-native-certs (and other libraries) is not valid/safe. This is something we already know from previous discussions.
I'm not sure what could reasonably be done other than deprecating this crate on macOS (and Windows) and replacing it with custom verification logic that uses the OS-provided APIs. I have done this at $work and we are open to open sourcing it.
Update rustls dependency target
I just tried to use this crate with rumqttc, and got:
error[E0308]: try expression alternatives have incompatible types
--> src/main.rs:9:28
|
9 | tlsconfig.root_store = rustls_native_certs::load_native_certs()?;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected struct `rustls::anchors::RootCertStore`, found a different struct `rustls::anchors::RootCertStore`
|
= note: perhaps two different versions of crate `rustls` are being used?
Indeed this crate depends on rustls 0.19, and rumqttc depends on rustls 0.2. Would you be open to targeting the same?
crate doc comment is incorrect and references function that doesn't exist
See:
rustls-native-certs/src/lib.rs
Lines 4 to 11 in f5b6e5b
build_native_certs
is gone, and load_native_certs
doesn't return a RootCertStore
any more.
Consider replacing this with the snippet in the example:
let mut roots = rustls::RootCertStore::empty();
for cert in rustls_native_certs::load_native_certs().expect("could not load platform certs") {
roots
.add(&rustls::Certificate(cert.0))
.unwrap();
}
It was not very obvious to me how to upgrade this crate without digging into the examples to figure out how to turn a vec of certificates into a RootCertStore
.
Can't find certs in Android device
let tls = rustls::ClientConfig::builder()
.with_native_roots()?
.with_no_client_auth();
// Prepare the HTTPS connector
let https = hyper_rustls::HttpsConnectorBuilder::new()
.with_tls_config(tls)
.https_or_http()
.enable_http1()
.build();
logcat:
with_native_roots processed 0 valid and 0 invalid certs
no valid native root CA certificates found
How can I fix this problem?
Support SSL_CERT_FILE/SSL_CERT_DIR
Moved from rustls/rustls#540:
OpenSSL supports SSL_CERT_FILE
and SSL_CERT_DIR
to allow configuration of CA certificates in an application without making code changes. It would be very helpful if rustls (via rustls-native-certs) also supported this by default.
This is a pretty widely used feature (a quick search shows them cumulatively appearing about 200,000 times in scripts, sources & docs on github alone). It's especially useful when you want to reconfigure an application that's not your own, where needing to change the code itself or reconfiguring trust for the entire OS would be very inconvenient, insecure, or impractical (e.g. if you don't have admin privileges but want to reconfigure your own processes). By using these env vars, you can automatically reconfigure applications so they work happily in enterprise environments with internal cert infrastructure, with HTTPS debugging tools, or when using self-signed certs in development.
For a general purpose reconfiguration like this, it's quite inconvenient to require every end application author to check for and use env vars themselves (and in practice, when they do, they each use a different env var - e.g. Cargo supports this manually via its own CARGO_HTTP_CAINFO - where a single global env var would be much better).
I can imagine this might be an OpenSSL feature that's considered risky, since it takes TLS configuration from the environment, but if an attacker can inject arbitrary environment variables they can already do things like setting LD_PRELOAD or even just PATH to exert almost complete control over the application being run regardless. Notably almost all other platforms allow SSL configuration in env vars in some form, e.g. the JVM via options with JAVA_TOOL_OPTIONS, node via NODE_EXTRA_CA_CERTS, anything using OpenSSL via SSL_CERT_FILE, etc etc.
Providing the same here would effectively add this widely used & supported capability to the rust ecosystem too, matching other platforms and working out of the box with existing OpenSSL configurations.
openssl 'Hashed Directory Method' not supported
In addition to loading CA bundles, openssl also supports a Hashed Directory Method - with this method, openssl looks in the CA Directory for a file named after the hash of the desired certificate, with a '.{digit}' on the end.
In corp environments this can be used to install locally trusted certificates, without disturbing the vendor supplied bundle.
Maybe it's not possible to support this scheme via rustls, as you would need to by able to look up certificates in the root store dynamically - the rusttls api does not look like it supports that - but if that is the case it should be documented in the README (especially since the rationale given for using this package is to support locally installed trusted CAs).
Add info whether the native cert is builtin or user/admin installed
It would be helpful to know if a certificate has been shipped by the OS, or was installed by the user or the administrator. This unlocks two use cases:
- ignore the certificates from the first category and use a different root store as the basis, like the ones from the
webpki-roots
crate. - impose special requirements on the OS builtin certificates. Chrome does this for example, e.g. by limiting how long a certificate can be valid. Another requirement might be a check for an SCT.
In Chromium, this check is implemented via a is_known_root
field on the verification result. The value is populated from the respective OS backends.
sudo required for MacOS
If I call rustls_native_certs::load_native_certs()
when running on MacOS Catalina as normal non-root user I get the following error:
Custom { kind: InvalidData, error: BadDER }
If I use sudo
to run my rust app as root it works.
Took a look at the integration tests in this project and they are using sudo on MacOS: https://github.com/ctz/rustls-native-certs/blob/master/admin/pipelines/macos-tests.yml#L2
Seems like it should be possible to run rust apps using rustls on MacOS as a non-root user. This is definitely possible in other languages/frameworks using tls on MacOS.
use of undeclared crate or module `platform`
I'm using drand-core
in my smart contract based on cosmwasm that has ureq
in dependencies and it has rustls-native-certs
in the dependencies.
It compile successfully on running cargo test
but after compile the project with this command:
docker run --rm -v "$(pwd)":/code --network="host" \
--mount type=volume,source="$(basename "$(pwd)")_cache",target=/code/target \
--mount type=volume,source=registry_cache,target=/usr/local/cargo/registry \
cosmwasm/workspace-optimizer:0.15.1
I get this error:
error[E0433]: failed to resolve: use of undeclared crate or module `platform`
--> /usr/local/cargo/registry/src/index.crates.io-6f17d22bba15001f/rustls-native-certs-0.7.0/src/lib.rs:58:42
|
58 | load_certs_from_env().unwrap_or_else(platform::load_native_certs)
| ^^^^^^^^ use of undeclared crate or module `platform`
What should I do for this issue, It seems platform not clear in workspace-optimizer?
Rpc(ClientError(Transport(Failed to load system certs: No valid certificate found)))-[xtensa-esp32s3-espidf]
I am using a ESP32-S3 to make a call to a RPC node.
So in theory if I install the ESP x509 Certificate Bundle in my ESP32-S3 board. I am able to use the platform's native certificate store when operating as a TLS client.
But that's is not happing, Because the rustls-native-certs crate does not support the ESP IDF.
Is there in the future roadmap a plan to include the ESP IDF in your crate?
Release to crates.io
What are blockers for this? Is it just a fresh release of security-framework appearing, as well?
Consider using non-rustls types in the API
In its current form, this library must be updated for every new rustls release. Given the small size and specific responsibilities, removing the rustls dependency would likely allow the library to remain unchanged for much longer periods, reducing maintenance load. As a straw proposal, DER blobs could be returned as Vec<Vec<u8>>
.
Handling behaviors implemented in platform verifier
In general, root programs maintain both a trust store and a platform verifier, and the behavior of the two is linked. Distrusts may be implemented first in the verifier (subject to various conditions), and only much later by removal from the trust store.
Using #24, I built a list of trust anchor subjects on three platforms (each of the below is sorted):
trust anchors on my Windows 10 instance
One problem I notice on macOS: there are two StartCom trust anchors in the list, but:
Some background on StartCom here.
This is an example of a fairly common strategy that root programs follow when distrusting a CA. Rather than immediately remove a trust anchor, which would break websites and impact many users, a root program will implement distrust in their platform verifier based on certain criteria. In this case, it's the notAfter date.
As a related example, in 2015 Chrome (while not a root program) implemented a CT requirement for CNNIC and for Symantec, ahead of the general CT requirement for all certificates.
Root programs may also block certain intermediates that don't show up in the trust store. For instance, in the Apple example linked above, WoSign's certificates were never in the trust store directly, but were trusted due to a cross-sign; Apple blocked that cross-sign.
We probably won't be able to come up with a comprehensive list of additional behaviors implemented by platform verifiers, since they are not in general guaranteed to be documented, but we should look for examples like the above and try to implement them here.
Mozilla has some guidance for bundlers of their trust store:
The decisions Mozilla makes with regards to the inclusion or exclusion of CA certificates in its root store are directly tied to the capabilities and behaviours of the software Mozilla distributes. Sometimes, a security change is made wholly or partly in the software instead of the root store. Further, Mozilla does not promise to take into account the needs of other users of its root store when making such decisions.
Therefore, anyone considering bundling Mozilla's root store with other software needs to be aware of the issues surrounding providing a root store, and committed to making sure that they maintain security for their users by carefully observing Mozilla's actions and taking appropriate steps of their own. On a best-efforts basis, Mozilla maintains a list of the additional things users of our store might need to consider.
lldb crash on osx for load_native_certs
Hi,
I'm getting the following crash on osx when running rustls_native_certs::load_native_certs()
:
__cxa_throw (@__cxa_throw:3)
Security::UnixError::throwMeNoLogging(int) (@Security::UnixError::throwMeNoLogging(int):22)
Security::safeCopyFile(char const*, unsigned int, char const*, unsigned short) (@Security::safeCopyFile(char const*, unsigned int, char const*, unsigned short):345)
Security::MDSSession::updateDataBases() (@Security::MDSSession::updateDataBases():389)
Security::MDSSession::DbOpen(char const*, cssm_net_address const*, unsigned int, Security::AccessCredentials const*, void const*, long&) (@Security::MDSSession::DbOpen(char const*, cssm_net_address const*, unsigned int, Security::AccessCredentials const*, void const*, long&):42)
mds_DbOpen(long, char const*, cssm_net_address const*, unsigned int, cssm_access_credentials const*, void const*, long*) (@mds_DbOpen(long, char const*, cssm_net_address const*, unsigned int, cssm_access_credentials const*, void const*, long*):89)
Security::MDSClient::Directory::cdsa() const (@Security::MDSClient::Directory::cdsa() const:30)
Security::MDSClient::Directory::dlGetFirst(cssm_query const&, cssm_db_record_attribute_data&, cssm_data*, cssm_db_unique_record*&) (@Security::MDSClient::Directory::dlGetFirst(cssm_query const&, cssm_db_record_attribute_data&, cssm_data*, cssm_db_unique_record*&):18)
Security::CssmClient::Table<Security::MDSClient::Common>::startQuery(Security::CssmQuery const&, bool) (@Security::CssmClient::Table<Security::MDSClient::Common>::startQuery(Security::CssmQuery const&, bool):81)
Security::KeychainCore::DynamicDLDBList::searchList() (@Security::KeychainCore::DynamicDLDBList::searchList():100)
Security::KeychainCore::StorageManager::getSearchList(std::__1::vector<Security::KeychainCore::Keychain, std::__1::allocator<Security::KeychainCore::Keychain>>&) (@Security::KeychainCore::StorageManager::getSearchList(std::__1::vector<Security::KeychainCore::Keychain, std::__1::allocator<Security::KeychainCore::Keychain>>&):54)
__SecTrustSettingsCopyCertificates_block_invoke_2 (@__SecTrustSettingsCopyCertificates_block_invoke_2:55)
_dispatch_call_block_and_release (@_dispatch_call_block_and_release:11)
_dispatch_client_callout (@_dispatch_client_callout:8)
_dispatch_lane_serial_drain (@_dispatch_lane_serial_drain:170)
_dispatch_lane_invoke (@_dispatch_lane_invoke:99)
_dispatch_workloop_worker_thread (@_dispatch_workloop_worker_thread:165)
_pthread_wqthread (@_pthread_wqthread:75)
The strange thing is that this only happens when I'm launching from VSCode using codelldb. When I launch it through lldb on the command line it seems to work fine. I'm guessing there's some kind of lldb setting which blocks access? Has anyone run into this before?
Sort of undocumented SSL_CERT_FILE override
The README mentions it but if you look at docs.rs, you wouldn't know that SSL_CERT_FILE exists. Probably good to call out in load_native_certs() and the top-level doc comment?
Loading native certs takes 300ms on OS X
Loading native certs on OS X takes 300ms:
use std::time::SystemTime;
fn main() {
let now = SystemTime::now();
let https = rustls_native_certs::load_native_certs();
println!("{:?}", now.elapsed());
}
Finished release [optimized + debuginfo] target(s) in 0.69s
Running `target/release/scratch`
Ok(334.809ms)
native (includes connection to google): Ok(90.305ms)
Apologies for the PDF flamegraph, GitHub is blocking SVGs.
For comparison, the crate native-tls
only takes 100ms to load TLS certs & connect to google over HTTPS, so it seems like it should definitely be possible to improve:
let native_now = SystemTime::now();
let connector = TlsConnector::new().unwrap();
let stream = TcpStream::connect("google.com:443").unwrap();
let mut stream = connector.connect("google.com", stream).unwrap();
println!("native: {:?}", native_now.elapsed());
Cargo tree
scratch v0.1.0 (/Users/rcoh/code/scratch)
├── native-tls v0.2.8
│ ├── lazy_static v1.4.0
│ ├── libc v0.2.103
│ ├── security-framework v2.4.2
│ │ ├── bitflags v1.3.2
│ │ ├── core-foundation v0.9.1
│ │ │ ├── core-foundation-sys v0.8.2
│ │ │ └── libc v0.2.103
│ │ ├── core-foundation-sys v0.8.2
│ │ ├── libc v0.2.103
│ │ └── security-framework-sys v2.4.2
│ │ ├── core-foundation-sys v0.8.2
│ │ └── libc v0.2.103
│ ├── security-framework-sys v2.4.2 (*)
│ └── tempfile v3.2.0
│ ├── cfg-if v1.0.0
│ ├── libc v0.2.103
│ ├── rand v0.8.4
│ │ ├── libc v0.2.103
│ │ ├── rand_chacha v0.3.1
│ │ │ ├── ppv-lite86 v0.2.10
│ │ │ └── rand_core v0.6.3
│ │ │ └── getrandom v0.2.3
│ │ │ ├── cfg-if v1.0.0
│ │ │ └── libc v0.2.103
│ │ └── rand_core v0.6.3 (*)
│ └── remove_dir_all v0.5.3
└── rustls-native-certs v0.5.0
├── rustls v0.19.1
│ ├── base64 v0.13.0
│ ├── log v0.4.14
│ │ └── cfg-if v1.0.0
│ ├── ring v0.16.20
│ │ ├── spin v0.5.2
│ │ └── untrusted v0.7.1
│ │ [build-dependencies]
│ │ └── cc v1.0.70
│ ├── sct v0.6.1
│ │ ├── ring v0.16.20 (*)
│ │ └── untrusted v0.7.1
│ └── webpki v0.21.4
│ ├── ring v0.16.20 (*)
│ └── untrusted v0.7.1
└── security-framework v2.4.2 (*)
Android and iOS support
I think we can look at how chromium is implemented.
https://github.com/chromium/chromium/blob/master/net/cert/cert_verify_proc_android.cc
https://github.com/chromium/chromium/blob/master/net/cert/cert_verify_proc_ios.cc
Could not load PEM file on Ubuntu 22.04
load_native_certs
returns an Err with "Could not load PEM file" on my PC.
Steps to Reproduce
git clone https://github.com/rustls/rustls-native-certs.git
cd rustls-native-certs
git checkout v/0.6.2
cargo test
Result:
Finished test [unoptimized + debuginfo] target(s) in 0.03s
Running unittests src/lib.rs (target/debug/deps/rustls_native_certs-f7d973d62fa334c9)
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
Running tests/compare_mozilla.rs (target/debug/deps/compare_mozilla-534257af1aea96a0)
running 3 tests
test test_does_not_have_many_roots_unknown_by_mozilla ... FAILED
test test_contains_most_roots_known_by_mozilla ... FAILED
test util_list_certs ... FAILED
failures:
---- test_does_not_have_many_roots_unknown_by_mozilla stdout ----
thread 'test_does_not_have_many_roots_unknown_by_mozilla' panicked at 'called `Result::unwrap()` on an `Err` value: Custom { kind: InvalidData, error: "Could not load PEM file \"/usr/lib/ssl/certs/ca-certificates.crt\"" }', tests/compare_mozilla.rs:69:59
---- test_contains_most_roots_known_by_mozilla stdout ----
thread 'test_contains_most_roots_known_by_mozilla' panicked at 'called `Result::unwrap()` on an `Err` value: Custom { kind: InvalidData, error: "Could not load PEM file \"/usr/lib/ssl/certs/ca-certificates.crt\"" }', tests/compare_mozilla.rs:107:59
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
---- util_list_certs stdout ----
thread 'util_list_certs' panicked at 'called `Result::unwrap()` on an `Err` value: Custom { kind: InvalidData, error: "Could not load PEM file \"/usr/lib/ssl/certs/ca-certificates.crt\"" }', tests/compare_mozilla.rs:147:59
failures:
test_contains_most_roots_known_by_mozilla
test_does_not_have_many_roots_unknown_by_mozilla
util_list_certs
test result: FAILED. 0 passed; 3 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s
error: test failed, to rerun pass '--test compare_mozilla'
Full Backtrace: https://gist.github.com/Firionus/7eefc8e8844bef2c9749b09813465b23#file-full-backtrace-terminal-dump
Expected Behavior
load_native_certs
should return an Ok instead of Err.
Infos
$ cargo --version --verbose
cargo 1.62.1 (a748cf5a3 2022-06-08)
release: 1.62.1
commit-hash: a748cf5a3e666bc2dcdf54f37adef8ef22196452
commit-date: 2022-06-08
host: x86_64-unknown-linux-gnu
libgit2: 1.4.2 (sys:0.14.2 vendored)
libcurl: 7.80.0-DEV (sys:0.4.51+curl-7.80.0 vendored ssl:OpenSSL/1.1.1n)
os: Ubuntu 22.04 (jammy) [64-bit]
/usr/lib/ssl/certs/ca-certificates.crt
exists and looks like this: https://gist.github.com/Firionus/7eefc8e8844bef2c9749b09813465b23#file-ca-certificates-crt
A restart had no effect. Updating the system packages via apt had no effect. update-ca-certificates
was run multiple times with and without the --fresh option, it never made a difference.
Related Issues
This problem appeared downstream in JuliaLang/juliaup#335.
”Permission denied“ since v0.7.1
I found this when we upgraded seanmonstar/reqwest#2391, one of our users reported this, rustdesk/rustdesk-server-pro#360. It is not easy to reproduce, I can only see this on his machine so far.
❯ ./test-master
Custom { kind: PermissionDenied, error: "could not load certs from dir /usr/lib/ssl/certs: Permission denied (os error 13)" }
❯ ./test-v0.6.2
ok
❯ ./test-v0.6.3
ok
❯ ./test-v0.7.0
ok
❯ ./test-v0.7.1
Os { code: 13, kind: PermissionDenied, message: "Permission denied" }
❯ sudo ./test-master
ok
❯ sudo ./test-v0.6.2
ok
❯ sudo ./test-v0.6.3
ok
❯ sudo ./test-v0.7.0
ok
❯ sudo ./test-v0.7.1
ok
The test is
use std::error::Error;
use x509_parser::prelude::*;
fn main() -> Result<(), Box<dyn Error>> {
if let Err(err) = rustls_native_certs::load_native_certs() {
println!("{:?}", err);
}
Ok(())
}
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.