The certificate chain issued by an untrusted authority - ssl

I am using the curl terminal and while issuing the following command :-
curl --anyauth --user admin:admin "https://localhost:8000/LATEST/search?q=caesar"
I am getting below alert :-
curl: (77) schannel: next InitializeSecurityContext failed: SEC_E_UNTRUSTED_ROOT (0x80090325) - The certificate chain was issued by an authority that is not trusted.
Please suggest. I have installed curl in Windows and also downloaded the .pem file and placed it in the same folder.

If your server has a self-signed cert, then by default curl doesn't know that it can trust that the server is who it says it is, and doesn't want to talk.
You can either:
import the cert into your trust store (best and most secure)
apply the -k or --insecure switch to ignore and continue. This may be fine for local development.
use a real cert, signed by a trusted CA

For local dev and a quick solution, run this line
set_config( config( ssl_verifypeer = 0L ) )
before
httr::GET(....)
but as suggested it's still preferable to use a real cert.

Related

Centos 7: cURL ssl error: you are attempting to import a cert with the same

I am testing a web service protected with mtls. I have issued both client and server certificates (for testing purposes) and added the server certificate to trust store.
The following command works on Ubuntu but not on Centos 7:
curl --cert MY_CLIENT_CERTIFICATE.pem https://MY_URL
On centos 7 (cURL v. 7.29), it returns:
cURL error 35: sl error: you are attempting to import a cert with the same issuer/serial as an existing cert
Do I understand it correctly that cURL does not allow me to issue both client and server certificates using the same issuer? Is there a workaround?
... cURL does not allow me to issue both client and server certificates using the same issuer
It is not about the same issuer but about the same issuer and serial number:
... you are attempting to import a cert with the same issuer/serial as an existing cert
If the same serial number is used for different certificates issued by the same CA then the certificate issuing process is broken: different certificates issued by the same CA MUST have different serial numbers. You need to fix this process and not try to work around it.
Updating curl fixed the problem

Curl does not take into consideration the given certificate(using --cert option)

I am trying to call an URL using curl, I used below command:
curl https://testenvironment/login --cert Qa1Certificate.pem
The result I get is:
curl: (60) Peer certificate cannot be authenticated with known CA certificates
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.
The Qa1Certificate.pem is placed in the current directory, and I believe that it is not taken into consideration because when I run the same command with a file name which does not exist:
curl https://testenvironment/login --cert ThisFileDoesNotExist.pem
I get the same result.
I am aware that I can obtain what I need using the -k or --insecure options( or other ways of disabling curl's verification of the certificate), but I
want to find out how can I use the certificate in order to perform a successful GET to my test environment.
The test environment uses a self signed certificate which I obtained using openSSL.
TLDR: it's --cacert
From the man page, which should be on your system or on the web:
-E, --cert <certificate[:password]>
(TLS) Tells curl to use the specified client certificate file when getting a file with HTTPS, FTPS or another SSL-based protocol. [snip rest]
Note the words 'client certificate'. --cert is used to specify a certificate and possibly key to authenticate the client, NOT to verify the server.
Now consider another entry on the man page:
--cacert
(TLS) Tells curl to use the specified certificate file to verify the peer. The file may contain multiple CA certificates. The certificate(s) must be in PEM format. Normally curl is built to use a default file for this, so this option is typically used to alter that default file.
This is the option to specify a cert or certs to verify (and specifically to anchor) the server's cert. Since your server cert is selfsigned, the cert is its own anchor/root and effectively is a CA cert, even though the server isn't actually a CA.
That's why the error message you posted includes the words
you can specify an alternate file using the --cacert option.
It does not say --cert.
Whether the client cert (and key) is read depends on the middleware used by the specific build of curl you are running. IME if built with OpenSSL it does give an error if you specify --cert with a nonexistent filename, but a version built with NSS (on Ubuntu 14.04LTS) gives an error only if the server requests client auth, which most servers don't.

Using curl -with --cert

I'm using cUrl to request data from a corporate website site using a .cer certificate that they sent me.
This is the command:
cUrl --header "Content-Type: text/xml;charset=UTF-8" \
--data #bustaRequestISEE2015ConsultazioneAttestazione.xml \
-o bustaResponseISEE2015ConsultazioneAttestazione.xml \
--cert ./caaffabisrl.cer \
https://istitutonazionaleprevidenzasociale.spcoop.gov.it/PD
When I run it, I get this error message:
curl: (58) could not load PEM client certificate, OpenSSL error error:0906D06C:PEM routines:PEM_read_bio:no start line, (no key found, wrong pass phrase, or wro
ng file format?)
Is there anybody who can help me?
Tks, Cristiano.
It is not possible to connect to a TLS server with curl using only a client certificate, without the client private key. Either they forgot to send you the private key file, or, what they sent you was not the client certificate but the server certificate for verification.
The first thing I would try is using --cacert instead of --cert. That is, tell curl that this is the server's certificate that curl can use to verify that the server is who you think it is.
You can also try removing --cert and not using --cacert, and you will probably get an error that the server is not trusted. Then add the --insecure argument and see if that works. I would not keep that argument, as then you have no proof of who you are talking to.
My guess is that it is the server cert, and that using --cacert instead of --cert will solve the problem.
My guess is that your certificate file is a DER encoded binary certificate instead of base-64 encoded certificate. To covert the from binary to base-64, you can use OpenSSL.
openssl x509 -inform der -in certificate.cer -out certificate.pem
I always forget all the arguments and have the following site bookmarked, as it gives examples of how to convert pretty much any certificate format. https://www.sslshopper.com/ssl-converter.html
First, you need to specify whether you're expected to perform two-way TLS/SSL or MTLS (mutual TLS). This would typically be the reason for sending a certificate. If they sent the server certificate, but you can connect to the server with a browser, you can down load the certificate. If their server is configured to send the server certificate and CA chain, then you can get the entire chain in a single request using "openssl s_client -connect [hostname:port] -showcerts". Save the certs in the console to a file, copying the cert blob(s) to individual cert files (cert1.crt, cert2.crt). However, if they are expecting MTLS and attempting to send a client certificate to you, either you've already generated a private key and CSR (certificate signing request) and send them the CSR. They would have then signed a certificate with their CA certificate using the CSR. The cert they returned would then need to be paired with the private key used to generate the CSR. They should not be generating the public/private key pair and sending them over mail. The private key should be stored security on the one system used to establish the connection. If it's one-way (server ssl only), then your client system (assuming it's not the browser), needs a truststore file, with the CA certificate chain installed and set to trusted. If the platform is Java, read Java's keytool documentation. Note, a keystore is for your systems public/private keypair. A truststore is for the CA certificates that you trust to sign public certificates that your system should trust as being authentic. You need to read any of the PKI x509 overviews by DigiCert, SSLABS, Sectigo, etc.

box.com ssl certificate

I'm trying to access box.com with libcurl. To use SSL I exported the SSL certificates with my web browser, box.com uses certificates issued by GeoTrust. But even if I pass them to curl (also with the command line tool (curl https://www.box.com --cacert /certs.pem)) I get an error that curl can't verify the certificate.
If I do exactly the same with a different site, which uses certificates issued by CAcert everything works just fine.
Do I need more/different certificates for box.com, additional to the GeoTrust certificates shown by the browser? If I use the complete certificate bundle stored in my system at /etc/ssl/certs I can connect to box.com but how do I found out which certificates are needed?
If you simply want to get it working, you could set this attribute to false:
CURLOPT_SSL_VERIFYPEER

SSL certificate verification fails, how to figure out what's causing it?

I've recently obtained a PositiveSSL certificate at Namecheap and installed it on my server. Accessing the site from Firefox works fine, but accessing it from Ruby's net/https library doesn't work: it fails to verify the connection certificate even though I've specified the path to the certificate and I've checked that the file is readable. Curl also fails:
curl --cacert /path/to/cert https://mysite.com/
It simply says something like this:
curl: (60) SSL certificate problem, verify that the CA cert is OK. Details:
error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed
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.
"certificate verify failed" isn't a terribly useful error message. How do I find out what exactly is wrong with my certificate and what to do about it? I find it confusing that it works in the browser but not anywhere else.
It looks like curl requires that the CA certificate file contains ALL certificates in the chain. I've downloaded all of them and combined them into a single file and now both Curl and Ruby are happy.