CA Cert are only added at ca-bundle-trust.crt - ssl

Env:
Red Hat Enterprise Linux Server release 7.7 (Maipo)
# openssl version
OpenSSL 1.0.2g 1 Mar 2016
so a self-sign cert is generated using OpenSSL and the cacert.pem is put under /etc/pki/ca-trust/source/anchors/.
Now according to the man from update-ca-trust, the cmd should be run to add the cert into the trust store and the cert are to be added under /etc/pki/ca-trust/extracted/.
After running the said cmd, I see that the cert is added only to /etc/pki/ca-trust/extracted/openssl/ca-bundle.trust.crt. But most of the application like curl refer the OS ca trust at /etc/pki/ca-trust/extracted/openssl/ca-bundle.crt which is link to /etc/pki/tls/certs/ca-bundle.crt.
curl -v https://172.21.19.92/api
* About to connect() to 172.21.19.92 port 443 (#0)
* Trying 172.21.19.92...
* Connected to 172.21.19.92 (172.21.19.92) port 443 (#0)
* Initializing NSS with certpath: sql:/etc/pki/nssdb
* CAfile: /etc/pki/tls/certs/ca-bundle.crt
I understand that passing --cacert option would be a way to overcome it but I want to know why update-ca-trust only update ca-bundle-trust.crt and not ca-bundle.crt or the java Keystore extracted one as well /etc/pki/ca-trust/extracted/java/cacerts

The actual command that import certificates to /etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem is:
/usr/bin/p11-kit extract --format=pem-bundle --filter=ca-anchors --overwrite --comment --purpose server-auth $DEST/pem/tls-ca-bundle.pem
So the filters here are --filter=ca-anchors + --purpose server-auth. When you generate cert you have to add the purpose extendedKeyUsage=serverAuth explicitly:
openssl x509 -req -in $SRV_NAME.csr -CA $CA_NAME.crt -CAkey $CA_NAME.key -passin pass:"$PASS" -out $SRV_NAME.crt \
-days 3650 -CAcreateserial \
-extensions v3_ca \
-extfile <(echo "[v3_ca]"; echo "extendedKeyUsage=serverAuth"; echo "subjectAltName=$SRV_DNS_NAMES_TEXT,email:$SRV_EMAIL")

Related

Mosquitto certificate verify failed with protocol error

I'm having trouble setting up mosquitto to encrypt over SSL/TLS. I have followed the instructions of mosquitto to generate the certificate and key. The code used is as follows:
openssl req -new -x509 -days 3650 -extensions v3_ca -keyout ca.key -out ca.crt.crt
openssl genrsa -out server.key 2048
openssl req -out server.csr -key server.key -new
openssl x509 -req -in server.csr -CA ca.crt.crt -CAkey ca.key -CAcreateserial -out
server.crt.crt -days 3650
Then I configured in mosquitto.conf as follows:
listener 8883
allow_anonymous true
cafile d:\etc\mosquitto\ca_certificates\ca.crt.crt
certfile d:\etc\mosquitto\certs\server.crt.crt
keyfile d:\etc\mosquitto\certs\server.key
Then I used the code
mosquitto -v -c mosquitto.conf
The results of running mosquitto are as follows:
D:\etc\mosquitto>mosquitto -v -c mosquitto.conf
1663109874: mosquitto version 2.0.15 starting
1663109874: Config loaded from mosquitto.conf.
1663109874: Opening ipv6 listen socket on port 8883.
1663109874: Opening ipv4 listen socket on port 8883.
1663109874: mosquitto version 2.0.15 running
But I have a problem when I want to try to make the subscribe and publish commands.I ran the following code:
mosquitto_sub -d -v -h 91.121.93.94 -p 8883 -t test --cafile d:\etc\mosquitto\ca_certificates\ca.crt.crt
91.121.93.94 is the Common Name I set to generate the server key.Then I got the error as below:
Client null sending CONNECT
OpenSSL Error[0]: error:1416F086:SSL routines:tls_process_server_certificate:certificate verify failed
Error: protocol error
I don't know where I am going wrong or if I have not configured something in mosquitto.conf.

import keypair to an existing pkcs12 keystore under a new alias name

I am learning OAUTH2 and OpenID Connect and configuring multiply tomcat servers (a Client for the UI, and multiply Resource Servers for the APIs) to use SSL. So I have created a PKCS12 keystore with a self-signed certificate + private key the following way and then I pushed it under my 1st Tomcat:
(I know that the commands bellow can be simplify and combine into one (or two) but I deliberately keep tem separately because that way I can see and understand the steps better)
(1) The keypair was created with openssl this way:
openssl genrsa \
-des3 \
-passout pass:$phrase \
-out id_rsa_$domain.key $numbits
(2) Then I created a Certificate Signing Request with this command:
openssl req \
-new \
-key id_rsa_$domain.key \
-passin pass:$phrase \
-subj "$subj" \
-out $domain.csr
(3) After that I created a x509 certificate:
openssl x509 \
-req \
-days $days \
-in $domain.csr \
-signkey id_rsa_$domain.key \
-passin pass:$phrase \
-out $domain.crt
(4) Finnaly I have created a key-store in PKCS12 format:
pem=$domain.pem
cat id_rsa_$domain.key > $pem
cat $domain.crt >> $pem
openssl pkcs12 \
-export \
-in $pem \
-passin pass:$phrase \
-password pass:$keystore_pwd \
-name $domain \
-out example.com.pkcs12
rm $pem
At the end of this process I have the following files:
id_rsa_authserver.example.com.key: the private (and public) key
authserver.example.com.crt: the self signed certificate
example.com.pkcs12: the keystore
Inside the .pkcs12 file I only have one key-pair entry under the authserver.example.com alias. I have checked the result with KeyStore Explorer as well and everything looks fine and the 1st Tomcat works properly with that keystore.
Then I repeated the steps (1), (2) and (3) and I generated new files for order.example.com host machine and at the end I have two new files:
id_rsa_order.example.com.key
order.example.com.crt
Now I would like to add to my "root" example.com.pkcs12 keystore this new keypair + certificate under the order.example.com alias in order to I keep all certs that I use for my demo in one keystore. I can do it easily with the KeyStore Explorer tool via the tools > import key pair > openSSL > browse the private key and cert files, but this is not enough good for me. I would like to do the import via command line using OpenSSL.
Unfortunately I have not found the proper openssl command that I can use to ADD my 2nd key+cert to the existing keystore.
What is the command that I can use?

Twisted webserver with plain http2 (h2c)

Twisted supports http1 + http2.
How to setup a twisted http2 server over TCP (neither ALPN nor protocol-upgrade)?
The server should answer to this query:
curl --http2-prior-knowledge http://localhost:8000/
Twisted should set up HTTP/2 servers for you auto-magically. Make sure you install twisted's http2 modules. The simplest way is to use pip:
pip install -U twisted[http2]
However, I've noticed a few times that it doesn't do run the HTTP/2 stuff out of the box. I had to uninstall h2, hyper and hyperframe, then reinstall them.
pip uninstall h2 hyperframe hyper
pip install -U twisted[http2]
Using a self signed certificate, here's a small klein webserver example.
openssl genrsa -aes256 -passout pass:SuperSecretPassword -out server.key 4096
openssl req -new -key server.key -passin pass:SuperSecretPassword -out server.csr
# Common Name (e.g. server FQDN or YOUR name) []:localhost
openssl x509 -req -passin pass:SuperSecretPassword -days 365 -in server.csr -signkey server.key -out server.crt
openssl rsa -in server.key -out server_no_pass.key -passin pass:SuperSecretPassword
mv server_no_pass.key server.key
cat server.crt server.key > selfsigned.pem
rm server.crt server.csr server.key
from klein import route, run
#route("/")
def hello(req):
if req.clientproto == b"HTTP/2":
return "http2"
return "http1.1"
run(endpoint_description="ssl:8000:privateKey=selfsigned.pem")
Update
While it's not best practice, there's nothing prohibiting you from running HTTP/2 server on a non-TLS connection. I believe most browsers won't support a non-TLS HTTP/2 server though (at least I couldn't get Firefox and Chrome to work with it). Twisted won't work out the box for you either, so that means you'll have to implement your own server. Follow the twisted example on the hyper-h2 site. Then replace endpoints.SSL4ServerEndpoint with endpoints.TCP4ServerEndpoint.
# ...
endpoint = endpoints.TCP4ServerEndpoint(reactor, 8080, backlog=128)
endpoint.listen(H2Factory(root))
reactor.run()

Mosquitto SSL certificate verify failed

I'm using Mosquitto version 1.4.8 on my test PC and the server. The server is accessible via ha.euroicc.com.
I've generated certificates and keys using the following script:
#! /usr/bin/env bash
# Create the CA Key and Certificate for signing Client Certs
openssl genrsa -out ca.key 4096
openssl req -new -x509 -days 365 -key ca.key -out ca.crt
# Create the Server Key, CSR, and Certificate
openssl genrsa -out server.key 1024
openssl req -new -key server.key -out server.csr
# We're self signing our own server cert here. This is a no-no in production.
openssl x509 -req -days 365 -in server.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out server.crt
# Create the Client Key and CSR
openssl genrsa -out client.key 1024
openssl req -new -key client.key -out client.csr
# Sign the client certificate with our CA cert. Unlike signing our own server cert, this is what we want to do.
# Serial should be different from the server one, otherwise curl will return NSS error -8054
openssl x509 -req -days 365 -in client.csr -CA ca.crt -CAkey ca.key -set_serial 02 -out client.crt
# Verify Server Certificate
openssl verify -purpose sslserver -CAfile ca.crt server.crt
# Verify Client Certificate
openssl verify -purpose sslclient -CAfile ca.crt client.crt
I've put 'd', 'dd' and 'dddd' everywhere except for common name.
The common name for ca is 'd' and for server/client is 'ha.euroicc.com'.
CN for server/client needs to be this value, or it doesn't work at all!
My current mosquitto config file:
pid_file /var/run/mosquitto.pid
persistence true
persistence_location /var/lib/mosquitto/
persistence_file mosquitto.db
log_dest syslog
log_dest stdout
log_dest topic
log_type error
log_type warning
log_type notice
log_type information
connection_messages true
log_timestamp true
password_file /etc/mosquitto/passwd
log_dest file /var/log/mosquitto/mosquitto.log
include_dir /etc/mosquitto/conf.d
allow_anonymous false
port 8883
cafile /etc/mosquitto/certs/ca.crt
keyfile /etc/mosquitto/certs/server.key
certfile /etc/mosquitto/certs/server.crt
require_certificate true
I use this command to subscribe from test PC:
mosquitto_sub -h ha.euroicc.com -t "topic/test" -u "damjan" -P "damjan" -p 8883 --cafile ca.crt --key client.key --cert client.crt
And get these errors:
On test PC:
Error: A TLS error occurred.
On server:
1532564086: OpenSSL Error: error:14089086:SSL
routines:ssl3_get_client_certificate:certificate verify failed
1532564086: Socket error on client <unknown>, disconnecting.
I've tried without require_certificate set on the server side, and not using client key/cert on the client side and subscription works in this case. This means that username/password parameters are fine.
That means that I either generated certificates and keys with a problem, my mosquitto.conf is bad or I'm using mosquitto_sub with a problem. Maybe something else?
I'm really at loss here and can't figure out what to try next...
Every bit of information helps.
Had a similar issue while upgrading to 2.0 because of the updated TLS/SSL bindings several know weak algorithms are not supported anymore.
In my case the signature of the certificate was sha1WithRSAEncryption where sha1 is the weak part. The same would be for e.g. MD5.
Check your certificate with openssl x509 -text -noout -in your.crt
Resigning the certificate with sha256WithRSAEncryption fixed it for me.
There is no need to create a new key.
You can either create a new CSR from your existing key and information from your certificate:
openssl x509 -x509toreq -in sha1.crt -signkey sha1.key -out sha256-new.csr -sha256
or overwrite the algorithm while signing the existing CSR again:
openssl x509 -req -days 360 -in sha1.csr -CA DummyCA-DonotTrust.pem -CAkey DummyCA-DonotTrust.pem -CAcreateserial -out sha256.crt -sha256
Recent openssl version should use sha256 as default.
Debian has changed the default setting with openssl-1.1.1 see https://wiki.debian.org/ContinuousIntegration/TriagingTips/openssl-1.1.1 and set CipherString = DEFAULT#SECLEVEL=2.
To get a list of supported algorithms run: openssl ciphers -s -v 'ALL:#SECLEVEL=2'
Ok, so the problem was that I was generating all of the files on my test PC, and then sending it to the server.
I've tried generating everything on the server, and then copying appropriate files to my test PC, and everything works fine.
I've followed http://rockingdlabs.dunmire.org/exercises-experiments/ssl-client-certs-to-secure-mqtt . With lesser changes like hostname etc.
I had the same issue.
To fix it, while generating server.crt, answer to question 'Common Name' with IP address of the machine where Mqtt broker is going to be run.

Trouble getting a self-signed cert working in Postman

I'm finally getting into using SSL on my personal sites, so I started by trying to make a multi-domain self signed cert for my local development (to handle api.mydomain.local, www.mydomain.local, and mydomain.local). I don't know if this was my first mistake, but...
As I couldn't find a single encompassing guide, I started by using two tutorials (from EasyEngine and DeveloperSide) to create my cert and install it on my host (Win10). I then used a DigitalOcean guide to figure out how to setup my Apache on my dev server (a Ubuntu VM); up to there, no big trouble, other than some minor issues caused by working from multiple guides at the same time.
I go ahead and try to hit my api in Chrome, it gives me an untrusted certificate value as expected, I pass and it works. As far as I know, this means the cert worked? However, when I try to hit my api in Postman, I get an error that indicates it can't accept an untrusted cert, which is fine, as it has a tutorial on how to fix that. However, it still doesn't work. I can't figure out what else to do to fix this, am I on the right track? Is my cert completely borked? Did I make a core mistake in trying to do a multi-domain cert?
One thing I did notice is that in the Dev Tools security tab, it says
Subject Alternative Name missing
So I'm not sure if that means my alt names aren't working, but if they weren't, it wouldn't try to load the certificate when I hit it in Chrome, right?
I had a similar issue while writing an article for my website on SSL certificates. So i wrote shell script for the same
#!/bin/bash
CERT_COMPANY_NAME=${CERT_COMPANY_NAME:=Tarun Lalwani}
CERT_COUNTRY=${CERT_COUNTRY:=IN}
CERT_STATE=${CERT_STATE:=DELHI}
CERT_CITY=${CERT_CITY:=DELHI}
CERT_DIR=${CERT_DIR:=certs}
ROOT_CERT=${ROOT_CERT:=rootCA.pem}
ROOT_CERT_KEY=${ROOT_CERT_KEY:=rootCA.key.pem}
# make directories to work from
mkdir -p $CERT_DIR
create_root_cert(){
# Create your very own Root Certificate Authority
openssl genrsa \
-out $CERT_DIR/$ROOT_CERT_KEY \
2048
# Self-sign your Root Certificate Authority
# Since this is private, the details can be as bogus as you like
openssl req \
-x509 \
-new \
-nodes \
-key ${CERT_DIR}/$ROOT_CERT_KEY \
-days 1024 \
-out ${CERT_DIR}/$ROOT_CERT \
-subj "/C=$CERT_COUNTRY/ST=$CERT_STATE/L=$CERT_CITY/O=$CERT_COMPANY_NAME Signing Authority/CN=$CERT_COMPANY_NAME Signing Authority"
}
create_domain_cert()
{
local FQDN=$1
local FILENAME=${FQDN/\*/wild}
# Create a Device Certificate for each domain,
# such as example.com, *.example.com, awesome.example.com
# NOTE: You MUST match CN to the domain name or ip address you want to use
openssl genrsa \
-out $CERT_DIR/${FILENAME}.key \
2048
# Create a request from your Device, which your Root CA will sign
if [[ ! -z "${SAN}" ]]; then
openssl req -new \
-key ${CERT_DIR}/${FILENAME}.key \
-out ${CERT_DIR}/${FILENAME}.csr \
-subj "/C=${CERT_COUNTRY}/ST=${CERT_STATE}/L=${CERT_CITY}/O=$CERT_COMPANY_NAME/CN=${FQDN}" \
-reqexts san_env -config <(cat /etc/ssl/openssl.cnf <(cat ./openssl-san.cnf))
else
openssl req -new \
-key ${CERT_DIR}/${FILENAME}.key \
-out ${CERT_DIR}/${FILENAME}.csr \
-subj "/C=${CERT_COUNTRY}/ST=${CERT_STATE}/L=${CERT_CITY}/O=$CERT_COMPANY_NAME/CN=${FQDN}"
fi
# Sign the request from Device with your Root CA
if [[ ! -z "${SAN}" ]]; then
openssl x509 \
-sha256 \
-req -in $CERT_DIR/${FILENAME}.csr \
-CA $CERT_DIR/$ROOT_CERT \
-CAkey $CERT_DIR/$ROOT_CERT_KEY \
-CAcreateserial \
-out $CERT_DIR/${FILENAME}.crt \
-days 500 \
-extensions san_env \
-extfile openssl-san.cnf
else
openssl x509 \
-sha256 \
-req -in $CERT_DIR/${FILENAME}.csr \
-CA $CERT_DIR/$ROOT_CERT \
-CAkey $CERT_DIR/$ROOT_CERT_KEY \
-CAcreateserial \
-out $CERT_DIR/${FILENAME}.crt \
-days 500
fi
}
METHOD=$1
ARGS=${*:2}
echo "Called with $METHOD and $ARGS"
if [ -z "${METHOD}" ]; then
echo "Usage ./sslcerts.sh [create_root_cert|create_domain_cert] <args>"
echo "Below are the environment variabls you can use:"
echo "CERT_COMPANY_NAME=Company Name"
echo "CERT_COUNTRY=Country"
echo "CERT_STATE=State"
echo "CERT_CITY=City"
echo "CERT_DIR=Directory where certificate needs to be genereated"
echo "ROOT_CERT=Name of the root cert"
echo "ROOT_CERT_KEY=Name of root certificate key"
else
${METHOD} ${ARGS}
fi
You can change the environment variables on the TOP and generate a self-signed certificate using below
$ SAN=DNS.1:*.tarunlalwani.com,DNS.2:tarunlalwani.com ./sslcerts.sh create_domain_cert '*.tarunlalwani.com'
Edit 1
Earlier browsers use to rely on FQDN, but now some of them have started using SAN which is "Subject Alternative Name". Generally openssl doesn't come up v3 extensions configured. SAN is a part of the v3 extensions. So when you generated a self signed certificated it has the correct FQDN (Full qualified domain name) but not SAN. Chrome will show error for these certificates but you will see firefox working fine.
PS: Taken from article http://tarunlalwani.com/post/self-signed-certificates-trusting-them/