CA certificate to connect to MQTT server over TLS - iot.eclipse.org - ssl

I want to connect to ssl://iot.eclipse.org:8883 using Client certficate authentication.
How I can obtain CA certificate?
Do I require to generate my own client certificate with provided CA certificate.
Or client certificate is also bundled along with CA certificate.

Using openssl to check it appears that the certificate for iot.eclipse.org is from the Let's Encrypt project.
$ openssl s_client -showcerts -connect iot.eclipse.org:8883CONNECTED(00000003)
depth=1 C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3
verify error:num=20:unable to get local issuer certificate
verify return:0
---
Certificate chain
0 s:/CN=iot.eclipse.org
i:/C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X3
-----BEGIN CERTIFICATE-----
So you should be able to check this certificate is valid with the standard CA set in most modern OS/Applications.
You will not be able to get hold of the CA cert/private key to generate your own client certs for obvious reasons and they do not issue client certificates ( and that is assuming that the eclipse.org broker is set up to authenticate clients with the same CA, it doesn't have to).
Also it doesn't make sense to authenticate against this broker as you have no way to set an ACL to control which users can subscribe/publish to specific topics as it's a public demonstration broker. If you want to secure access then you will have to run your own public broker
EDIT: You don't want to do client certificate authentication, you just want to verify the server cert, this is very different.
To do this with mosquitto_pub or mosquitto_sub you have to specify a CA cert or a path to a directory of multiple certificates in order to enable ssl/tls for the connection. You would specify an individual CA cert if you were using a private CA, but since the iot.eclipse.org broker is using a well known public CA you need to specify the path to the system collection of CA certs.
On Linux that is /etc/ssl/certs so you would publish as follows:
mosquitto_pub -h iot.eclipse.org -p 8883 --capath /etc/ssl/certs/ -t testing/ben -m foo

If a certificate is like a passport which proves your identity, then CA is just like a passport office(1). You could consider Verisign, Entrust etc as passport offices. CA certficate is analogous to passport office providing a way to check if a passport is valid or not.
To prove their identity any two parties,( read server and client ), could use certificates. To verify the authenticity of a party( read server ), you need CA certificate. Linux system(Ubuntu) holds commonly used CA certificates at /etc/ssl/certs.
A client certificate is needed only if you need to authenticate yourself to the server. Here server is iot.eclipse.org which doesn't ask for client authentication and so you don't need client certificate.
So, to communicate securely with server ( read TLS ), you can use the CA store present in your system(Ubuntu) as below.
mosquitto_pub -h iot.eclipse.org -p 8883 -t my_topic -m my_message --capath /etc/ssl/certs/

Related

Understanding openssl. Where is the cert file?

I am using the command ...
openssl s_client -showcerts -connect reds-cluster-01:443
And I get the output:
depth=2 C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert Global Root CA
verify return:1
depth=1 C = US, O = DigiCert Inc, CN = RapidSSL TLS DV RSA Mixed SHA256 2020 CA-1
verify return:1
depth=0 CN = *.my-co-example.com
verify return:1
CONNECTED(00000003)
---
Certificate chain
0 s:/CN=*.my-co-example.com
i:/C=US/O=DigiCert Inc/CN=RapidSSL TLS DV RSA Mixed SHA256 2020 CA-1
-----BEGIN CERTIFICATE-----
MIIGnxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxgkqhkiG9w0BAQsFADBZ
...
I assume that means somewhere on the filesystem of my server there would be a file somewhere that has the string ...
MIIGnxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxgkqhkiG9w0BAQsFADBZ
... in it. How can I find that file without having to execute something like?
sudo grep -sr MIIGnxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxgkqhkiG9w0BAQsFADBZ /
I assume that means somewhere on the filesystem of my server there would be a file somewhere that has the string ...
This assumption is wrong. What you see is part of the server certificate, which need to be checked against a CA certificate located in the local trust store. The server certificate is typically not in the local trust store. See SSL Certificate framework 101: How does the browser actually verify the validity of a given server certificate? for more on certificates are checked.
You can see more with "CURL -W CERTS" from Daniel Stenberg (also on Stack Overflow), which works on curl for the past 25+ years.
When a client connects to a TLS server it gets sent one or more certificates during the handshake.
Those certificates are verified by the client, to make sure that the server is indeed the right one: the server the client expects it to be; no impostor and no man in the middle etc.
When such a server certificate is signed by a Certificate Authority (CA), that CA’s certificate is normally not sent by the server but the client is expected to have it already in its CA store.
(So no file to check on the filesystem)
Ever since the day SSL and TLS first showed up in the 1990s user have occasionally wanted to be able to save the certificates provided by the server in a TLS handshake.
The openssl tool has offered this ability since along time and is actually one of my higher ranked stackoverflow answers.
Now (for curl 7.88.0,to be shipped in February 2023), Daniel proposes:
Using the –write-out (-w) option and the new variables %{certs} and %{num_certs}, curl can now do what you want.
Get the certificates from a server in PEM format:
$ curl https://curl.se -w "%{certs}" -o /dev/null > cacert.pem
$ curl --cacert cacert.pem https://curl.se/
That is easier to parse than the openssl s_client -showcerts -connect current alternative.

SSL self-signed certificate one-way or two-wayTLS

I am using OpenSSL program to generate my SSL self-signed certificate, created a CA certificate and a webserver certificate. The webserver certificate, I have signed it with the CA certificate. I created a keystore with Java's keytool to import webserver's certificate.
On the client side, I have imported the CA certificate inside client's Certificate Manager, under the "Trusted Root Certification Authorities".
In theory, is this way considered as a One way TLS or a Two way TLS communication?
Thank you so much for the help!
In TLS protocol by default the client validates servers authenticity, the server sends its certificate during the handshake and the client validates it with the CA certificate in its trust store. It is one way setup
For two way, during the handshake, the server also asks for certificate from client,it validates the certificate sent by the client with the CA certificate in its trust store. So if you want to use two way setup, you need to generate client CA certificate and client certificate(it will be signed by the client CA certificate), the same CA certificate you need to configure at server so that it(server) will be able to validate the client certificate it received during the handshake.
You can also decide to keep same CA certificate for both client and server certificates, making sure client and server certificates are signed by the same CA

Unable To Trust Self-Signed SSL Certificate

I have an application running on Centos7 that needs to connect to a remote host over HTTPS. However, it is unable to verify the certificate and fails. Also, if I try to download a file from the server using wget, I get the below error:
[root#foo:~]# wget https://10.65.127.9/index.html
--2017-05-22 09:03:01-- https://10.65.127.9/index.html
Connecting to 10.65.127.9:443... connected.
ERROR: cannot verify 10.65.127.9's certificate, issued by ‘/CN=us6877vnxe7827’:
Unable to locally verify the issuer's authority.
To connect to 10.65.127.9 insecurely, use `--no-check-certificate'.
So I get the certificate from the host:
openssl s_client -connect 10.65.127.9:443 <<<'' | openssl x509 -out /etc/pki/ca-trust/source/anchors/mycert.pem
And execute the following to process it:
update-ca-trust extract
This however results in the same issue.. If I run:
openssl s_client -connect 10.65.127.9:443 -showcerts -debug
I do get some errors and various messages:
depth=0 CN = us6877vnxe7827
verify error:num=20:unable to get local issuer certificate
verify return:1
depth=0 CN = us6877vnxe7827
verify error:num=21:unable to verify the first certificate
verify return:1
---
Certificate chain
0 s:/CN=us6877vnxe7827
i:/CN=us6877vnxe7827
Server certificate
subject=/CN=us6877vnxe7827
issuer=/CN=us6877vnxe7827
---
No client certificate CA names sent
---
Verify return code: 21 (unable to verify the first certificate)
Any ideas what I may be missing? If any further info helps, please let me know.
For wget you need to provide the certificate authority (CA) certificate(s) that signed the https server certificate. If you have those CA certificates - add them under --ca-certificate=file or --ca-directory=directory options
If you don't have them and you want to skip https server certificate verification (unsecure and can be dangerous) then use --no-check-certificate option.
I had the same problem with Jenkins trying to connect to our GitLab server.
The server does have a valid official certificate in our case, but Java didn't except it.
You are right about downloading the certificate.
However, the application you are mentioning is probably running inside a Java Virtual Machine (as a lot of applications are).
So from the point that you downloaded the certificate to a PEM file, you may have to add it to the VM's trusted certificates instead.
This article describes how to do that. Hope it helps.

How to make mod_ssl accept self signed certificates

I am using self signed certificates with Apache mod_ssl module but I am getting
> curl_easy_perform() failed on: https://localhost/auth/example (SSL
> certificate problem: self signed certificate)
Is their a way to make ssl not fail? I know that curl has the option --insecure or -k so is there something similar I can add to http-ssl.conf?
mod_ssl will present whatever certificate it is configured to present. It is a client decision whether to accept the presented certificate or not; there is nothing you can configure in mod_ssl, other than the certificate itself, that will influence client verification.
If you want Curl to accept the server certificate, you can either:
Use --insecure/-k (as you are already aware)
Obtain a certificate signed by a public, trusted certificate authority (CA)
Use a self-signed CA to sign the server certificate, and tell Curl to verify the server certificate using that CA via the --cacert <CA certificate> option.

SSL Certificate: how to setup CA to deal with certificate chain?

I have a PKI hierarchy like below.
root-ca ---> signing-ca ---> sub-ca-1 ---> server-cert-1 (machine 1)
\
\--------> sub-ca-2 ---> server-cert-2 (machine 2)
I wonder how to set up CA on each machine. For example, I create a bundle on machine 1.
$ cat sub-ca-1.pem signing-ca.pem root-ca.pem > cas-1.pem
cas-1.pem can verify server-cert-1 but it cannot verify server-cert-2.
So if machine 1 and 2 needs mutual authentication, it will fail.
Logically, I think the right way to do is that the certificate of machine 1 (and 2) should take up to sub-ca and the CA should start from signing-ca to root-ca (like below).
$ cat server-cert-1.pem sub-ca-1.pem > server-1.pem
$ cat signing-ca.pem root-ca.pem > cas.pem
But when I verify, it fails.
$ openssl verify -CAfile cas.pem server-1.pem
I am not sure how other SSL program will verify certificate.
Anyway, in situation like this, how to set up CA and certs on each machine such that verification can pass.
Thanks a lot.
it should be enough to either add the root-ca or the signing-ca to the CA store (e.g. the list of trusted CAs) on the client. The rest of the chain needs to be send by the server during ssl handshake, so that the client can verify the certificate up to the trusted CA.