elastic / elasticsearch-rs

Official Elasticsearch Rust Client
https://www.elastic.co/guide/en/elasticsearch/client/rust-api/current/index.html
Apache License 2.0
695 stars 70 forks source link

[BUG] Builder panics with "incompatible TLS identity type" when using client certificates #173

Open chancecardona opened 3 years ago

chancecardona commented 3 years ago

Describe the bug I'm not sure if this is a true bug or if I'm merely doing something wrong. When attempting to create a client using the transport builder with some certificate files, I continuously get the error Cert(reqwest::Error { kind: Builder, source: "incompatible TLS identity type" }). I've tested these certificates with the exact same server using reqwest directly, which works precisely as intended. If this isn't a bug, it would be very helpful to have some more documentation providing the differences between these two and how to use certificates with elasticsearch.

To Reproduce Steps to reproduce the behavior: Using an elasticsearch server configured to use credentials and tls certificates, this code yields the error:

let credentials = Credentials::Basic(server_username.into(), server_password.into());
let cert_ca = fs::read_to_string("ca.pem").unwrap();
let cert_elastic = fs::read_to_string("elastic.pem").unwrap();
let cert_elastic_key = fs::read_to_string("elastic-key.pem").unwrap();
let cert_vec = format!("{}{}", cert_elastic_key, cert_elastic).into_bytes();
let cert_credentials = Credentials::Certificate(ClientCertificate::Pem(cert_vec));
let conn_pool = SingleNodeConnectionPool::new(url);
let builder = TransportBuilder::new(conn_pool)
    .auth(credentials)
    .auth(cert_credentials)
    .cert_validation(CertificateValidation::Full(Certificate::from_pem(&cert_ca.into_bytes()).unwrap()))
    .disable_proxy();
let transport = builder.build().unwrap();
let client = Elasticsearch::new(transport);

Expected behavior I would expect this to behave like Reqwest does when doing it manually, as such:

let id = reqwest::Identity::from_pem(&cert_vec).unwrap();
let client = reqwest::blocking::Client::builder()
    .identity(id)
    .add_root_certificate(reqwest::Certificate::from_pem(&cert_ca.into_bytes()).unwrap())
    .build().unwrap();

Environment (please complete the following information):

chancecardona commented 3 years ago

Upon further research it was found that this bug occurred even when using only the Reqwest code above if elasticsearch-rs was a dependency. This is due to native-tls being imported by default with elasticsearch-rs, which causes the conflict. Setting default-features=false for the elasticsearch crate fixes this problem. Still though, a more helpful error message would be appreciated.

russcam commented 2 years ago

Thanks for opening @chancecardona. Would need to investigate to see if there's a more informative error message that can be provided.