Coder Social home page Coder Social logo

rustls-native-certs's Introduction

Rustls is a modern TLS library written in Rust.

Status

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.

Build Status Coverage Status (codecov.io) Documentation Chat OpenSSF Best Practices

Changelog

The detailed list of changes in each release can be found at https://github.com/rustls/rustls/releases.

Documentation

https://docs.rs/rustls/

Approach

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.

Platform support

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.

Cryptography providers

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.

Built-in providers

Rustls ships with two built-in providers controlled with associated feature flags:

  • aws-lc-rs - enabled by default, available with the aws_lc_rs feature flag enabled.
  • ring - available with the ring feature flag enabled.

See the documentation for crypto::CryptoProvider for details on how providers are selected.

Third-party providers

The community has also started developing third-party providers for Rustls:

Custom provider

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.

Example code

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.

Client example program

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.

Server example program

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.

License

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.

Project Membership

  • 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)

Code of conduct

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

Contributors

alex avatar atouchet avatar bnoordhuis avatar cpu avatar ctz avatar darsvador avatar daxpedda avatar dependabot[bot] avatar djc avatar est31 avatar freaky avatar jsha avatar keruspe avatar pgerber avatar pimterry avatar poliorcetics avatar serprex avatar tottoto avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

rustls-native-certs's Issues

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).

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?

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.

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:

//! It provides the following functions:
//! * A higher level function [load_native_certs](fn.build_native_certs.html)
//! which returns a `rustls::RootCertStore` pre-filled from the native
//! certificate store. It is only available if the `rustls` feature is
//! enabled.
//! * A lower level function [build_native_certs](fn.build_native_certs.html)
//! that lets callers pass their own certificate parsing logic. It is
//! available to all users.

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 macOS 11.2.3

trust anchors on my Windows 10 instance

trust anchors on Ubuntu 20.04

One problem I notice on macOS: there are two StartCom trust anchors in the list, but:

Apple products will block certificates from WoSign and StartCom root CAs if the "Not Before" date is on or after 1 Dec 2016 00:00:00 GMT/UTC

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)

flamegraph.pdf

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 (*)

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 photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.