alexcrichton / curl-rust

Rust bindings to libcurl
MIT License
1.02k stars 235 forks source link

Error: Problem with the local SSL certificate #320

Open silvioprog opened 4 years ago

silvioprog commented 4 years ago

Hi.

I have the following code that works like a charm on Linux using a P12 certificate:

extern crate curl;

use std::path::Path;

use curl::easy::SslVersion;
use curl::easy::{Easy, List};

fn main() {
    let mut easy = Easy::new();
    easy.url(
        "https://nfe.sefaz.ba.gov.br/webservices/NFeConsultaProtocolo4/NFeConsultaProtocolo4.asmx",
    )
    .unwrap();
    easy.verbose(true).unwrap();
    let mut list = List::new();
    list.append(
        "SOAPAction: http://www.portalfiscal.inf.br/nfe/wsdl/NFeConsultaProtocolo4/nfeConsultaNF",
    )
    .unwrap();
    list.append("Content-Type: application/soap+xml; charset=utf-8")
        .unwrap();
    easy.http_headers(list).unwrap();
    easy.post_fields_copy(b"<?xml version=\"1.0\" encoding=\"UTF-8\"?><soap12:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap12=\"http://www.w3.org/2003/05/soap-envelope\"><soap12:Body><nfeDadosMsg xmlns=\"http://www.portalfiscal.inf.br/nfe/wsdl/NFeConsultaProtocolo4\"><consSitNFe xmlns=\"http://www.portalfiscal.inf.br/nfe\" versao=\"4.00\"><tpAmb>1</tpAmb><xServ>CONSULTAR</xServ><chNFe>99999999999999999999999999999999999999999999</chNFe></consSitNFe></nfeDadosMsg></soap12:Body></soap12:Envelope>").unwrap();
    easy.ssl_verify_peer(false).unwrap();
    easy.ssl_version(SslVersion::Tlsv12).unwrap();
    easy.ssl_cert_type("P12").unwrap();
    easy.ssl_cert(Path::new("/home/user/certificado.pfx"))
        .unwrap();
    easy.key_password("the-secret-password").unwrap();
    easy.write_function(|data| {
        println!("{}", String::from_utf8_lossy(data));
        Ok(data.len())
    })
    .unwrap();
    easy.perform().unwrap();
}

however, when I try to use the same example on Windows, it raises the following error:

*   Trying 200.187.29.23:443...
* TCP_NODELAY set
* Connected to nfe.sefaz.ba.gov.br (200.187.29.23) port 443 (#0)
* schannel: Failed to get certificate location for C:\Users\user\Downloads\certificado.pfx
* Closing connection 0
* schannel: shutting down SSL/TLS connection with nfe.sefaz.ba.gov.br port 443
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Error { description: "Problem with the local SSL certificate", code: 58, extra: None }', src\libcore\result.rs:1165:5
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace.

and I have been trying the following ways, but both fails:

...
easy.ssl_cert(Path::new("C:\\Users\\user\\Downloads\\certificado.pfx"))
        .unwrap();
...

and

...
easy.ssl_cert(Path::new("C:/Users/user/Downloads/certificado.pfx"))
        .unwrap();
...

it seems the library can't find the certificate location, maybe some encoding issue? I've tried the same code above in a C application and in cURL from command line and both worked like a charm.

TIA for any help!

alexcrichton commented 4 years ago

I believe that this has to do with the SSL backend being used, and not all SSL backends support custom certificates. If it works with the curl command line it may be compiled differently with a different backend perhaps? I believe we by default enable WinSSL (schannel) which IIRC doesn't support custom certificates.