curl failing with --insecure(-k) and missing --cacert - ssl

I have a client server interface.
The case is unusual, because the server authenticates client and not vice versa.
The client sends client cert to the server. The server authenticates the client cert with its root ca cert. There is also an intermediate cert being used, but I dont need that on server to authenticate the client.
The commands go as follows.
"curl -k --cert client-cert.pem --key client-key.pem https://server.com:443/endpoint" (FAIL)
But if I pass the intermediate cacert as argument to curl, its successful.
"curl -k --cert client-cert.pem --key client-key.pem --cacert intermediates.pem https://server.com:443/endpoint" (PASS)
Even if I pass in the root ca(same between client and server) it fails.
"curl -k --cert client-cert.pem --key client-key.pem --cacert root-ca.pem https://server.com:443/endpoint" (FAIL)
PS:
(FAIL) means, Server says authentication failure!
My Question is:
Why should a server care about the --cacert option at all. curl shouldn't be sending over the ca cert regardless. Correct?
Why do things work when I only pass intermediates file.
Thanks in advance for the response.
PS:
The client-cert.pem is signed by intermediate ca and intermediate ca is signed by root ca.

Related

cURL a local GO server using a self signed certificate

So i have a simple GO server running on port 8080 using a self-signed certificate that i created with the following command:
openssl req -new -newkey rsa:4096 -x509 -sha256 -days 365 -nodes -out local.crt -keyout local.key
When creating it i set the fields to these values:
As you can see i skipped everything but the fully qualified host name which i set to go-auth
I started my go server using the local.key and local.crt files successfully.
I tried cURLing it like:
➜ certs git:(master) ✗ curl --proxy-cacert local.crt https://go-auth/
curl: (6) Could not resolve host: go-auth
➜ certs git:(master) ✗ curl --proxy-cacert local.crt https://localhost:8080/
curl: (60) SSL certificate problem: self signed certificate
More details here: https://curl.haxx.se/docs/sslcerts.html
curl failed to verify the legitimacy of the server and therefore could not
establish a secure connection to it. To learn more about this situation and
how to fix it, please visit the web page mentioned above.
After that i tried to get the certs from the running server and saving it to the cacert.pem file and tried again:
➜ certs git:(master) ✗ echo quit | openssl s_client -showcerts -servername go-auth -connect localhost:8080 > cacert.pem
depth=0 CN = go-auth
verify error:num=18:self signed certificate
verify return:1
depth=0 CN = go-auth
verify return:1
DONE
➜ certs git:(master) ✗ curl --cacert cacert.pem https://go-auth/
curl: (6) Could not resolve host: go-auth
➜ certs git:(master) ✗ curl --proxy-cacert cacert.pem https://go-auth/
curl: (6) Could not resolve host: go-auth
At this point i don't know, i was trying to follow the answer to this question: Use self signed certificate with cURL? but did not get the desired result.
You can use the -k parameter in order to skip the certificate validation.
Your command have to be similar to the following one:
curl -vk https://localhost:8080/
-v enable some debug information
-k disable the certificate validation
If you want to enable the certificate validation, you have two way:
Add and trust the certificate to your current CA list
By this way, you are going to "accept" your self signed certificate as a valid one, and you will be able to call the service (from your machine, obviously) using any type of HTTP client (Java, Go, cURL etc etc).
Use the --cacert parameter of the cURL command in order to specify the path related to the certificate to use in order to authenticate to the service.

using mosquitto_sub with --insecure

Right now I have to do an initial test of a mqtt broker (ssl).
However right now I don't have the valid truststore certificates, however I would like to test the basic connectivity, ignoring SSL errors regarding hostname verification, certificate validation etc.
Unfortunately I am not successful, even with a broker I know it's working.
What I'm doing:
mosquitto_sub -h the_host -p 8883 -t '#' -v -u myUser -P myPass --insecure -d --capath /etc/ssl/certs
According to the manpage I just use the --capath to identify it's a TLS connection, well knowing that the necessary root certificate is not available here.
What I get is this:
Client mosqsub|11262-csbox sending CONNECT
Error: A TLS error occurred.
Any idea what I'm doing wrong?
Using --insecure just disables the verification of the hostname in the certificate presented by the broker. It does not remove the need to have a copy of the CA certificate that signed the brokers certificate.
So if /etc/ssl/certs doesn't contain a matching CA certificate then the connection will fail.
If needed you should be able to use something like openssl s_client to download the certificate chain directly from the broker, you can then point to that file with the --cafile option instead of the --capath option.

Kafka, why do I need to pass the certificate chain and not only the root ca when testing with kafka-console-producer (or Kafkcat)

I have a Kafka cluster which is configured to be used over ssl on port 9093.
In order for me successfully send data on port 9093 I need to pass the certificate chain (intermediate + root CA) (all these are self signed stuff)
echo "Hello" | kafkacat -P -b localhost:9095 -t my-topic \
-X security.protocol=ssl \
-X ssl.key.location=cert-key.pem \
-X ssl.ca.location=chain.crt
(chain.crt is a file with the rootCA and intermediate cert)
My question is why do I need to issue the full chain and not just the root CA in the ssl.ca.location param ?
ssl.key.location is the client's certificate for authenticating to the broker.
ssl.ca.location is used by the client to verify the broker's certificate.

cURL on Debian 7 doesn't seem to use /etc/ssl/certs/ca-certificates.crt

When I run the following command:
# curl https://undisclosedwebsite.nl
I get the following error:
curl: (60) SSL certificate problem: unable to get local issuer certificate
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.
After some debugging with openssl s_client -connect https://undisclosedwebsite.nl I discovered that the following command with cURL does work:
curl https://undisclosedwebsite.nl --cacert /etc/ssl/certs/ca-certificates.crt
Isn't cURL supposed to use this file?

Using curl with certificate that has no password

I have my own CA and client certificate that I have been using successfully with cURL using the normal format:
curl --cacert /etc/myca.crt --cert /etc/myclient.pem:mypassword --cert-type PEM --get https://myhost.com
Now, for reasons outside the scope of this question, I have the same client certificate but the password has been removed using openssl. Using openssl I have verified that the new certificate is correct and I can use it to make SSL connections using applications other than cURL, but I cannot get it to work with cURL.
If I don't enter a password:
curl --cacert /etc/myca.crt --cert /etc/myclient.pem --cert-type PEM --get https://example.com
I get an error saying "curl: (58) unable to use client certificate (no key found or wrong pass phrase?)"
I have also tried:
curl --cacert /etc/myca.crt --cert /etc/myclient.pem: --cert-type PEM --get https://example.com
but I get the same error.
I am making the call to cURL from within a Perl script, so I need to find a way that will not prompt me for the password. I am using cURL 7.15.5 on RHEL 5.
Thank you.
You can make use of the --pass switch:
--pass <phrase> (SSL/SSH) Passphrase for the private key
To pass an empty passphrase you can use:
--pass ''