Showing posts with label openssl. Show all posts
Showing posts with label openssl. Show all posts

Saturday, 2 June 2018

How to create a Self-Signed SSL certificate with Subject Alternate Names - SAN

In this post, I want to record the steps to generate a self-signed SSL/TLS certificate with SAN extentions.
This is becoming important as may of the modern browsers now check the SAN section rather than the CN common name for the certificate subject.

To begin, lets generate our root CA certificate:
openssl genrsa -out selfca.key 2048

Then we create the root CA:
[root@localhost ~]# openssl req -x509 -key selfca.key -sha256 -days 2000 -out selfca.crt
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:NL    
State or Province Name (full name) []:Noord Holland
Locality Name (eg, city) [Default City]:Amsterdam
Organization Name (eg, company) [Default Company Ltd]:SHERIF Ltd
Organizational Unit Name (eg, section) []:IT
Common Name (eg, your name or your server's hostname) []:IT Root CA
Email Address []:
[root@localhost ~]#


Next we create our website private key:
openssl genrsa -out www.sherif.site.key 2048


And then we generate a CSR (certificate signing request):
[root@localhost ~]# openssl req -out www.sherif.site.csr -key www.sherif.site.key -new
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:EG
State or Province Name (full name) []:Cairo
Locality Name (eg, city) [Default City]:Cairo
Organization Name (eg, company) [Default Company Ltd]:SHERIF Ltd
Organizational Unit Name (eg, section) []:IT
Common Name (eg, your name or your server's hostname) []:www.sherif.site
Email Address []:root@sherif.site

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
[root@localhost ~]#


Then we sign the certificate and we are done:
[root@localhost ~]# openssl x509 -req -in www.sherif.site.csr -CA selfca.crt -CAkey selfca.key -CAcreateserial -out mydomain.com.crt -days 720 -sha256
Signature ok
subject=/C=EG/ST=Cairo/L=Cairo/O=SHERIF Ltd/OU=IT/CN=www.sherif.site/emailAddress=root@sherif.site
Getting CA Private Key
[root@localhost ~]#



Now lets check the certificate, we can clearly see the information of the CA and also for the certificate owner, but there is no SAN information in the certificate.
[root@localhost ~]# openssl x509 -in www.sherif.site.crt -text -noout
Certificate:
    Data:
        Version: 1 (0x0)
        Serial Number:
            c8:4b:f0:5d:26:4a:18:4b
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: C=NL, ST=Noord Holland, L=Amsterdam, O=SHERIF Ltd, OU=IT, CN=ROOT CA
        Validity
            Not Before: Jun  2 12:18:17 2018 GMT
            Not After : May 22 12:18:17 2020 GMT
        Subject: C=EG, ST=Cairo, L=Cairo, O=SHERIF Ltd, OU=IT, CN=www.sherif.site/emailAddress=root@sherif.site
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
                    00:c6:d6:c3:96:6d:0f:b2:63:74:d6:04:7a:2c:c1:
                    e3:bd:6d:6e:0a:89:a4:14:83:de:e6:d9:e9:4b:f1:
                   .....


Adding SAN information:


Now lets try to create a certificate using multiple SAN (Subject alternate names).
To do this, we need to pass the openssl command a customized configuration file while we are generating the CSR.
Below is an example file:

[root@localhost ~]# cat san_config.cfg
[ req ]
default_bits            = 2048
default_md              = sha256
default_keyfile         = privkey.pem
distinguished_name      = req_distinguished_name
x509_extensions = v3_ca # The extensions to add to the self signed cert

prompt = no
string_mask = utf8only

[ req_distinguished_name ]
countryName             = XX
stateOrProvinceName     = State
localityName            = Default City
0.organizationName      = Default Company Ltd
organizationalUnitName  = Unit
commonName              = localhost
emailAddress            = root@localhost

[ v3_ca ]
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
subjectAltName=@alternate_names

[alternate_names ]
DNS.1        = www
DNS.2        = fingon
DNS.3        = Fingon
[root@localhost ~]#


The file serves 2 purposes, it will automatically fill the CSR question form for us using the values above and will also introduce the SAN extensions to the certificate.
To use this file we add the -config parameter to the openssl command to generate the CSR:

openssl req -out www.sherif.site.csr -key www.sherif.site.key -new -config san_config.cfg

Then we also add the the -extfile & -extensions parameters to the openssl command to generate the certificate:

openssl x509 -req -in www.sherif.site.csr -CA selfca.crt -CAkey selfca.key -CAcreateserial -out www.sherif.site.san.crt -days 720 -sha256 -extfile ./san_config.cfg -extensions 'v3_ca'

Once the Certificate is created, we can check the alternate names section we configured:

[root@localhost ~]# openssl x509 -in www.sherif.site.san.crt -text -noout|grep -i -A3 -B6 fin
        X509v3 extensions:
            X509v3 Basic Constraints:
                CA:FALSE
            X509v3 Key Usage:
                Digital Signature, Non Repudiation, Key Encipherment
            X509v3 Subject Alternative Name:
                DNS:www, DNS:fingon, DNS:Fingon
    Signature Algorithm: sha256WithRSAEncryption
         a5:e2:a5:89:76:f4:59:ed:46:46:a7:6e:76:ab:ab:ee:e2:cd:
         ef:c9:c4:22:f8:93:92:26:f3:87:51:cd:e7:e7:b5:4e:73:fb:
[root@localhost ~]#

This ensures that all subject alternative names are added to the certificate.

Enjoy SSL 👌

Thursday, 19 January 2017

WebSite SSL cert. check script

There was a need to be able to check SSL certs for certain set of web services / site out of a central point without the having the actual cert.
To do this, I made use of openssl s_client functionality.

The below script takes a single parameter, the hostname:port and does the validation.
The script has 4 timing checks so it needs to be run every day to be able to catch the actual certificate expiration time.
Once it detects an expiring cert, it will send out an email given that sendmail is configured on the server that runs it.

[root@Beren check_certs]# cat check_certs.sh
#set -x

Check_CERTs ()
{
TARGET="$1"
TEST_DATE31=`date "+%b %e %T %Y %Z" -d "+31 day" |tr -s " "|cut -d" " -f1,2,4`
TEST_DATE21=`date "+%b %e %T %Y %Z" -d "+21 day" |tr -s " "|cut -d" " -f1,2,4`
TEST_DATE11=`date "+%b %e %T %Y %Z" -d "+11 day" |tr -s " "|cut -d" " -f1,2,4`
TEST_DATE03=`date "+%b %e %T %Y %Z" -d "+3 day" |tr -s " "|cut -d" " -f1,2,4`

SSL_TEST_CMD=" echo |openssl s_client -connect ${TARGET} 2>/dev/null|openssl x509 -inform pem -noout -text |grep \"Not After :\" |
cut -d\":\" -f2-|tr -s \" \"|cut -d\" \" -f2,3,5"

SSL_EXP_DATE=`bash -c "${SSL_TEST_CMD}"`

##SSL_EXP_DATE="Feb 9 2017"

echo $SSL_EXP_DATE

if [ "$SSL_EXP_DATE" == "$TEST_DATE31" ]
then
    echo "31 days left"
elif [ "$SSL_EXP_DATE" == "$TEST_DATE21" ]
then
        echo "21 days left"
elif [ "$SSL_EXP_DATE" == "$TEST_DATE11" ]
then
        echo "11 days left"
elif [ "$SSL_EXP_DATE" == "$TEST_DATE03" ]
then
        echo "3 days left"
fi
 

#End of the shell function.
}


#Main code:

CERT_TIME=`Check_CERTs "${1}"|grep left`

if [ -n "$CERT_TIME" ]
then

echo "Sending Email"

/usr/sbin/sendmail.sendmail -i -t << ENDL
From: "Script Cert Alert"
To: <sherif.abdelfattah@live.com>
Subject: CERT Expiration WaRNing

Please check the SSL Certs installed on ${1} !!
The certificate is about to expire !!
${CERT_TIME}


Please take action ASAP.

ENDL

fi
[root@Beren check_certs]#

The script uses Linux gnu date, that can take a time string using -d option, also we make use of the %e which uses space padded days of the month similar to OpenSSL command date format.
Also note the use of the "echo |openssl" construct, this prevents openssl command from waiting for further input thus, we can run it from a script.