2

I am running docker container which contains REST API with tls enable, For which I am passing self signed .pem certificate and I am using reqwest crate to call the REST API. If tls is disable with container it works well. But when I run container with certificate, reqwest API call giving me error as mention below.Even after passing the same certificate from self-signed also giving me error.

error trying to connect: The certificate was not trusted."

reqwest = { version = "0.11.4", features = ["blocking", "json","native-tls"] }
async fn call_api<T: serde::Serialize>(
        &self,
        builder: ClientBuilder,
        params: &T,
        request_url: &str,
    ) -> Result<serde_json::Value> {
        let mut headers = header::HeaderMap::new();
        headers.insert(
            header::AUTHORIZATION,
            header::HeaderValue::from_str(self.token.as_str()).unwrap(),
        );
        headers.insert(
            header::CONTENT_TYPE,
            header::HeaderValue::from_static("application/json"),
        );
        // read a local binary pem encoded certificate
        let pem = std::fs::read("./cert.pem").unwrap();
        let cert = reqwest::Certificate::from_pem(&pem)?;

        let client = builder
            .add_root_certificate(cert)
            .default_headers(headers)
            .build()?;

        let response_json: serde_json::Value = client
            .get(request_url)
            .json(params)
            .send()
            .await?
            .json()
            .await?;

        Ok(response_json)
    }
Herohtar
  • 5,347
  • 4
  • 31
  • 41
nagaraj
  • 797
  • 1
  • 6
  • 29
  • If I understand this correctly, do you mean that your are using root cert both at server and client? – Mihir Luthra Oct 13 '21 at 13:10
  • @MihirLuthra, when using a self-signed certificate, you have to set it as the certificate on server, and add it as trusted on client. The `ClientBuilder::add_root_certificate` is suppsoed to do the later part, and documentation suggests it's the correct way. – Jan Hudec Oct 13 '21 at 13:33
  • Does the certificate declare the domain from the `request_url` in its dnsName or IP extension, or, if it does not have any extensions, as its CN? Can you show the `request_url` and the output of `openssl x509 -in cert.pem -noout -text`? – Jan Hudec Oct 13 '21 at 13:36
  • @JanHudec`request_url= https//127.0.0.1:port/api/mymethod`, open ssl which is self signed .pem file which i am passing in `add_root_certificate(cert)` – nagaraj Oct 13 '21 at 14:18
  • @fama, you only answered the first half: the domain is `IP:127.0.0.1`. Now the other half. If you run that `openssl` command, does it say `X509v3 Subject Alternative Names: IP:127.0.0.1` in the output? If it does not, it won't be trusted not because you didn't add it, but because it does not claim to be valid for the URL. – Jan Hudec Oct 13 '21 at 14:27
  • `X509v3 Subject Alternative Names: IP:127.0.0.1' does not exist in my certificate. – nagaraj Oct 13 '21 at 14:38
  • I created the new self-signed certificate with IP address and added certificate in the postman, it works. I can call API. but when I pass the same certificate using `reqwest` above code facing still same error. – nagaraj Oct 13 '21 at 17:02
  • 1
    @fama, it is quite likely that postman relaxes the certificate validation, because it is a primarily testing tool, while `reqwest`, or rather `native-tls` underneath it, does the validation as specified. You should make a new self-signed certificate with correct `subjectAlternateNames` matching the URL. – Jan Hudec Oct 13 '21 at 18:10
  • it works, I created a new self-signed certificate with `subjectAlternateNames` where I provided the IP:127.0.0.1 it works. – nagaraj Oct 16 '21 at 02:31

0 Answers0