Se tienen los certificados:
- ssl.key (privada)
- ssl.cert (publica)
- ca.cert
- pass phrase
La llave publica ssl.cert, esta instalada en el servidor DEVIL.
Se necesita enviar un json mediante POST desde el servidor HOST (Centos7) a DEVIL (SAP) sobre SSL, esto implica enviar las llaves publica, privada a demás de tener una validación del certificado CA y el pass phrase.
Si se envía los datos por curl de esta manera:
curl -v --cert ./ssl.cert --key ./ssl.key --cacert ./ca.cert --header "Content-Type: application/json" --data '{"key":"value"}' https://devil.com/
Obtendríamos una respuesta como esta:
About to connect() to devil.com port 443 (#0) Trying 123.123.123.123… Connected to devil.com (123.123.123.123) port 443 (#0) Initializing NSS with certpath: sql:/etc/pki/nssdb CAfile: ca.cert CApath: none Server certificate: subject: CN=………………………………….. start date: Jan 22 00:00:00 2020 GMT expire date: Jan 22 12:00:00 2022 GMT common name: *………………………………… issuer: CN=…………………………………… NSS error -8172 (SEC_ERROR_UNTRUSTED_ISSUER) Peer's certificate issuer has been marked as not trusted by the user. Closing connection 0 curl: (60) Peer's certificate issuer has been marked as not trusted by the user. More details here: http://curl.haxx.se/docs/sslcerts.html curl performs SSL certificate verification by default, using a "bundle" of Certificate Authority (CA) public keys (CA certs). If the default bundle file isn't adequate, you can specify an alternate file using the --cacert option. If this HTTPS server uses a certificate signed by a CA represented in the bundle, the certificate verification probably failed due to a problem with the certificate (it might be expired, or the name might not match the domain name in the URL). If you'd like to turn off curl's verification of the certificate, use the -k (or --insecure) option.
Haciendo la misma llamada de manera insegura, agregando la opción -k:
curl -v -k --cert ./ssl.cert --key ./ssl.key --cacert ./ca.cert --header "Content-Type: application/json" --data '{"key":"value"}' https://devil.com/
La respuesta seria algo así:
About to connect() to devil.com port 443 (#0) Trying 123.123.123.123… Connected to devil (123.123.123.123) port 443 (#0) Initializing NSS with certpath: sql:/etc/pki/nssdb skipping SSL peer certificate verification NSS: client certificate from file subject: CN=………………………………………………….. start date: May 22 00:00:00 2020 GMT expire date: Feb 10 12:00:00 2021 GMT common name: …………………………………………………. issuer: CN=………………………………………………… SSL connection using TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 Server certificate: subject: CN=*…………………………………………………. start date: Jan 22 00:00:00 2020 GMT expire date: Jan 22 12:00:00 2022 GMT common name: *………………………………………………… issuer: CN=…………………………………………………… POST /http/Orders HTTP/1.1 User-Agent: curl/7.29.0 Host: devil.com Accept: / Content-Type: application/json Content-Length: 664 upload completely sent off: 664 out of 664 bytes < HTTP/1.1 401 < X-message-code: PWD_WRONG < WWW-Authenticate: Basic realm="SAP HANA Cloud Platform" < Transfer-Encoding: chunked < Date: Thu, 28 May 2020 19:32:54 GMT < Server: SAP < Strict-Transport-Security: max-age=31536000; includeSubDomains; preload < Connection #0 to host devil.com left intact
Un detalle si se usa la opción -k los parámetros cacert y capath dejan de funcionar
Bien la solución es instalar(copiar) el certificado ca.cert, de la siguiente manera:
cp ca.cert /etc/pki/ca-trust/source/anchors/ update-ca-trust extract
Con esto la llamada de forma segura (sin el parámetro -k ) y sin el certificado CA debería ser exitosa.
curl -v --cert ./ssl.cert --key ./ssl.key --header "Content-Type: application/json" --data '{"key":"value"}' https://devil.com/
Este problema también afecta a las llamadas curl que se hacen desde PHP