1

Im working with a WebService and I still cannot authenticate peer certificates. Im using libCurl to C language, this is the output:

Cannot Perform Post, Err: Peer certificate cannot be authenticated with given CA certificates

So I've tried to test connection through openssl command:

openssl s_client -connect homnfce.sefaz.am.gov.br:443 -cert cert.pem -key nfcek.pem

Then : Verify return code: 20 (unable to get local issuer certificate)

Going further I looked around to server certificates, and noticed that they have a cert chain. So I've downloaded them and added using keytool:

keytool -import -trustcacerts -file cert1.cer -alias mykey
keytool -import -trustcacerts -file cert2.cer -alias mykey2
keytool -import -trustcacerts -file cert3.cer -alias mykey3

Even with these changes, I still can't authenticate peer certificates.

I think it can indicate an error while setting CURLOPTs, heres a extract of code:

 if (curl_easy_setopt(curl, CURLOPT_POST, 1) != CURLE_OK) {
    if ( DEBUG_DETAILS ) vTrace("curl_easy_setopt(curl, CURLOPT_POST, 1) failed");
    return -1;
  }
  if (curl_easy_setopt(curl, CURLOPT_URL, "https://homnfce.sefaz.am.gov.br/nfce-services-nac/services/NfeStatusServico2?wsdl") != CURLE_OK) {
    if ( DEBUG_DETAILS ) vTrace("curl_easy_setopt(curl, CURLOPT_URL) failed");
    return -1;
  }
  if (curl_easy_setopt(curl, CURLOPT_PORT, 443) != CURLE_OK) {
    if ( DEBUG_DETAILS ) vTrace("curl_easy_setopt(curl, CURLOPT_PORT, 443) failed");
    return -1;
  }
  if (curl_easy_setopt(curl, CURLOPT_SSLCERT, "cert.pem") != CURLE_OK) {
    if ( DEBUG_DETAILS ) vTrace("curl_easy_setopt(curl, CURLOPT_SSLCERT) failed");
    return -1;
  }
  if (curl_easy_setopt(curl, CURLOPT_SSLKEY, "nfcek.pem") != CURLE_OK) {
    if ( DEBUG_DETAILS ) vTrace("curl_easy_setopt(curl, CURLOPT_SSLKEY) failed");
    return -1;
  }
  sprintf(szCertPath, "%s","/home/CAcerts/");
  if (curl_easy_setopt(curl, CURLOPT_CAPATH, szCertPath) != CURLE_OK) {
    if ( DEBUG_DETAILS ) vTrace("curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER) failed");
    return -1;
  }
  if (curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, iLen) != CURLE_OK) {
    if ( DEBUG_DETAILS ) vTrace("curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE) failed");
    return -1;
  }
  if (curl_easy_setopt(curl, CURLOPT_SSLCERTPASSWD, szMyPw) != CURLE_OK ) {
    if ( DEBUG_DETAILS ) vTrace("curl_easy_setopt(curl, CURLOPT_TIMEOUT) failed");
    return -1;
  }
  if (curl_easy_setopt(curl, CURLOPT_READDATA, pfChk) != CURLE_OK ) {
    if ( DEBUG_DETAILS ) vTrace("curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE) failed");
    return -1;
  }
  if (curl_easy_setopt(curl, CURLOPT_WRITEDATA, pfAnswer) != CURLE_OK ) {
    if ( DEBUG_DETAILS ) vTrace("curl_easy_setopt(curl, CURLOPT_WRITEDATA) failed");
    return -1;
  }
  if (curl_easy_setopt(curl, CURLOPT_TIMEOUT, iOnlineServerTimeout) != CURLE_OK ) {
    if ( DEBUG_DETAILS ) vTrace("curl_easy_setopt(curl, CURLOPT_TIMEOUT) failed");
    return -1;
  }
  if (curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1) != CURLE_OK) {
    if ( DEBUG_DETAILS ) vTrace("curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1) failed");
    return __LINE__;
  }

  if ( (res = curl_easy_perform(curl)) != CURLE_OK ){
    if ( DEBUG_DETAILS ) vTraceStr("iNFCE_CurlReq(): Cannot Perform Post, Err: %s\n", (char *)curl_easy_strerror(res));
    return -1;
  }

Something important is the fact that I can't use insecure mode option ingnore peer authentication (CURLOPT_SSL_VERIFYPEER = 0 ).

Any ideas? What can be wrong?

Thanks in advance

rfermi
  • 179
  • 11
  • 1
    Can you tell us what SSL library your curl is using? I thought `keytool` was for Java key stores? – lmz Nov 03 '14 at 17:54
  • How can I discover which SSL lib curl is using? I **think** it uses OpenSSL default. – rfermi Nov 03 '14 at 18:00
  • Try `ldd` on your `libcurl.so`. Have you tried adding those three certificates to the `CURLOPT_CAPATH` (`/home/CAcerts/` in your example) and running OpenSSL c_rehash as specified here http://curl.haxx.se/libcurl/c/CURLOPT_CAPATH.html? – lmz Nov 03 '14 at 18:08
  • Im not using libcurl dinamically linked, I mean, i dont use dlopen to use functions of libcurl.so, Im adding the curl.h Header file. Btw I checked out the ldd of my libcurl.so and it uses libssl.so Im working on c_rehash functions to openssl – rfermi Nov 03 '14 at 18:12
  • @lmz Thank you, I still cannot authenticate, but I've c_rehash(ed) the directory: `c_rehash . Doing . acserprov3.pem => 707978d0.0 icpbrasilv2.pem => 1e54e6fa.0 serproacfv3.pem => 1526e8dd.0 ` – rfermi Nov 03 '14 at 18:17
  • 1
    Are any of your .pem files an actual self-signed root certificate (subject == issuer)? OpenSSL by default tries to build the trust chain up to a self-signed root certificate. Check http://openssl.6102.n7.nabble.com/Verify-intermediate-certificate-td27976.html for a discussion. – lmz Nov 03 '14 at 18:26
  • @lmz, i've advanced in this point. I got a pack of certificates of the server, that I used to generate a cacert file. Then I Added the CAPATH and CAINFO to curlopts. So now I got this message: `Problem with the SSL CA cert (path? access rights?)` Ive used keytool to import the certificates into cacert file, with this command : `keytool -import -alias root -file cer1.cer -keystore cacerts` `keytool -import -alias root1 -file cer2.cer -keystore cacerts` `keytool -import -alias root2 -file cer3.cer -keystore cacerts` – rfermi Nov 06 '14 at 19:08
  • In advance Ive checked my cert.pem and I got: `subject=/C=BR/ST=SP/L=BARUERI/O=ICP-Brasil/OU=Secretaria da Receita Federal do Brasil - RFB/OU=RFB e-CNPJ A1/OU=AR SERASA/CN=CONECTO SISTEMAS LTDA:05113966000159 issuer=/C=BR/O=ICP-Brasil/OU=Secretaria da Receita Federal do Brasil - RFB/CN=AC SERASA RFB v2 ` – rfermi Nov 06 '14 at 19:13

1 Answers1

0

I've done it. Actually it was a problem with Servers CAs. Ive download a certificate chain from host, then ive used openssl commands to convert:

  openssl x509 -in raiz_v2.cer -out raiz_v2.pem
  openssl x509 -in ac_certsign_g6.cer -out ac_certsign_g6.pem
  openssl x509 -in ac_certsign_mult_g5.cer -out ac_certsign_mult_g5.pem

So ive unified them using:

 cat raiz_v2.pem > cacert.pem
 cat ac_certsign_g6.pem >> cacert.pem
 cat ac_certsign_mult_g5.pem >> cacert.pem

And then ive pointed to cacert.pem using CURLOPT_CAINFO option.

rfermi
  • 179
  • 11