Verify SSL certificate against various CRL files - bash

I am given multiple certificate files e.g. "cert1.crt", "cert2.crt" etc, and multiple CRL lists, "list1.crl", "list2.crl" etc. No rootCA or any other type of files are provided. My task is to find out what certificates have NOT been revoked. Despite extensive search for "verification" command I failed to find any command or procedure that would provide me at least a clue. In the end, I managed to do some bash script aerobatics which let me manually test serial number for each .crt file
for((i=1;i<9;i++))
do
echo $i
fileIn="crl"$i".crl"
#serial is manually c/p from each .crt file
serial="1319447396"
OUTPUT="$(openssl crl -in $fileIn -noout -text | grep $serial)"
echo $OUTPUT
done
This way I could do it manually one at a time, but it will work only for small number of files (9 at present). With tens of files it would get tiresome and ineffective, with 100+ it would get impossible to do it like this.
I was wondering is there a "smart" way to validate .crt against .crl? Or at least is there a way to bash script the job so I wouldn't have to check each .crt manually? Right now it's way beyond my scripting knowledge.
So, in pseudo, I would be thrilled if something like this existed:
openssl x509 -verify cert1.cert -crl_list list8.crl

In general, yes, each certificate is checked against a CRL, as is detailed in this guide.
But, Actually, each crl is a simple list of revoked certificate serial numbers.
The list contained in a crl could be expanded with:
openssl crl -inform DER -text -noout -in mycrl.crl
Asuming the crl is in DER form (adapt as needed).
Expand each (all) crl to a text file, like:
openssl crl -inform DER -text -noout -in mycrl.crl > mycrl.crl.txt
The out file could be reduced to only the Serial Number: lines.
Get the Serial Number from the text expansion of a cert:
mycrt=$(openssl x509 -in mycrt.com.crt -serial -noout)
mycrt=${mycrt#*=}
grep the serial number in all text files from step one (if one match the cert is revoked) in one call to grep:
if grep -rl "$mycrt" *.crl.txt 2>/dev/null; then
echo "the certificate has been revoked"
fi
Full script:
#!/bin/bash
# Create (if they don't exist) files for all the crl given.
for crl in *.crl; do
if [[ ! -e "$crl.txt" ]]; then
openssl crl -inform DER -text -noout -in "$crl" |
awk -F ': ' '/Serial Number:/{print $2}'> "$crl.txt"
fi
done
# Process all certificates
for crt in *.crt; do
mycrt=$(openssl x509 -in "$crt" -serial -noout)
mycrt=${mycrt#*=}
if grep -rl "$mycrt" *.crl.txt; then
echo "Certificate $crt has been revoked"
fi
done

I finally managed to solve this in a way that's maybe not optimal, but requires much less bash knowledge. Here is my script:
#!/bin/bash
for((j=1;j<10;j++))
do
indicator=0
cert="cert"$j".crt"
for((i=1;i<9;i++))
do
infile="crl"$i".crl"
SERIAL="$(openssl x509 -noout -text -in $cert | grep Serial | cut -d 'x' -f 2 | cut -d ')' -f 1)"
OUTPUT="$(openssl crl -inform DER -in $infile -noout -text | grep $SERIAL )"
if [ -n $OUTPUT ]
then ((indicator++))
fi
done
echo $cert
if [ $indicator == 0 ]
then echo "not revoked"
else
echo "revoked"
fi
done

Related

openssl sha256 binary digest piped through fxxd -p is output on multiple lines

I use this command to give me the output from openssl without the (stdin)= the beginning.
openssl x509 -noout -modulus -in certfile.crt | openssl sha1 -binary | xxd -p
with output
7857b35259019acc7484201958ac7e622c227b68
If I change openssl to create a sha256 digest, xxd prints it over two lines
openssl x509 -noout -modulus -in certfile.crt | openssl sha256 -binary | xxd -p
with output
b274c19ac31cc7893dc2297804a2ca666fe168d5cd5eb4d4b6c47616bad9
8996
How can I write that output on line one?
b274c19ac31cc7893dc2297804a2ca666fe168d5cd5eb4d4b6c47616bad98996
Is it something else I have to do with xxd now that the digest is longer or is there a need to pipe it through some other command to get the combined output?
As usual there are several ways.
The first general solution which came into my mind is this:
printf "%s" $( openssl x509 -noout -modulus -in certfile.crt | openssl sha256 -binary | xxd -p )
Of course, if the output is less than 256, you could use xxd -f -c 256 as stated by tshiono.
Another solution for this special case with openssl would be this:
openssl x509 -noout -modulus -in certfile.crt | openssl sha256 -r
or
openssl x509 -noout -modulus -in certfile.crt | openssl sha256 -hex
but both are not exactly like the output you want. The hex string is in the output, but padded before or after which can be cut off, by piping to the command cut -d" " -f 1 or cut -d" " -f 2 for the removal of the prefix or postfix.

How to handle information of certificate in a PEM file

I exported certificates from keychain to a PEM file. I want to handle information of each certificate in a loop by writing a shell-script file.
When I run this command to check the file:
openssl crl2pkcs7 -nocrl -certfile [file name here].pem | openssl pkcs7 -print_certs -text | grep -E '(Subject:|Not After)'
All certificates's information will be printed. But when I run this command:
openssl x509 -in certs.pem -text
It only shows information of the first certificate in the file. I tried to get count of certificate in the PEM file with a shell, it returned 1.
#! /bin/bash
i=0;
for cert in [PEM file path]; do
let "t=$i + 1";
echo $t;
done
Could anyone help me to handle certificates in PEM file?. Thank you so much.
Usually the certificates are separated by the BEGIN/END-comments. You could split the PEM-string like this:
IN="-----BEGIN CERTIFICATE-----..."
CERTS=( $(IFS="-----BEGIN CERTIFICATE-----" echo "$IN") )
echo ${CERTS[0]}
echo ${CERTS[1]}
...

How to check a public RSA key file

Inside a shell script I want verify public RSA file.
All I want to do is that find a way to check this file is a genuine public key file, nothing else.
Can I ask experts here what are the ways I can verify this input file to check this is a genuine public key file , not a regular file.
I will be using this public key file in future to validate an incoming encrypt gzip file but that is out of scope for now.
All I want is validate input file to check its genuine RSA public key file not an ordinary file.please note that I do not have any other files with me (eg : private key) .
e.g.: if the file is ‘public.pem’ I just want check inside that it’s a genuine RSA public key file not just a file with texts or file is not corrupted .
I’m already checking that file is not zero sized and md5 .
other possible checks I found
check file got text ‘BEGIN PUBLIC KEY’ and ‘END PUBLIC KEY’
Also found this command in google , Is there a better way to do this using openssl
‘openssl rsa -noout -text -inform PEM -in pubkey.pem -pubin’
Thanks
It's possible to use any public key format parser, including openssl or even parse key yourself as the format is not that difficult.
Command line tools set a non-zero exit code, when parsing fails:
openssl rsa -inform PEM -pubin -in pubkey.pem -noout &> /dev/null
if [ $? != 0 ] ; then
echo "this was definitely not a RSA public key in PEM format"
exit 1
fi
Just to check any public key:
openssl pkey -inform PEM -pubin -in pubkey.pem -noout &> /dev/null
if [ $? != 0 ] ; then
echo "this was definitely not a public key in PEM format"
exit 1
fi
The following script should work for all PEM-formatted keys and certs supported by OpenSSL. I have tested it on various valid and invalid ECDSA and RSA keys with matching and non-matching certs.
Save this as verify-cert-key:
#!/usr/bin/env bash
certFile="${1}"
keyFile="${2}"
certPubKey="$(openssl x509 -noout -pubkey -in "${certFile}")"
keyPubKey="$(openssl pkey -pubout -in "${keyFile}")"
if [[ "${certPubKey}" == "${keyPubKey}" ]]
then
echo "PASS: key and cert match"
else
echo "FAIL: key and cert DO NOT match"
fi
Make it executable:
chmod +x verify-cert-key
Run it on a cert and key:
./verify-cert-key server-crt.pem server-key.pem
Try this command if your public key starts with -----BEGIN RSA PUBLIC KEY-----
openssl rsa -RSAPublicKey_in -in /path/to/pub_key.pem -noout -text

Read common name from .pem file

is there a way to read the common name from a .pem file in my shell?
Thanks
First off, the .pem extension only refers to the type of encoding used in the file.
The common name would be a feature of the Subject or Issuer of a certificate, and can be recognised by the lines
$ grep CERTIFICATE f.pem
-----BEGIN CERTIFICATE-----
-----END CERTIFICATE-----
and lots of base64 encoded text in between.
If the .pem file contains an x509 certificate,
this should do the trick:
openssl x509 -in cacert.pem -noout -text
This will dump the whole certificate. The openssl x509
command has several options to suppress the fields you don't want to see. You find those explained in the man page, under TEXT OPTIONS
You can also choose to get shown just the 'Subject' of the certificate:
openssl x509 -in cacert.pem -noout -subject
Example:
Let's capture the certificate of stackoverflow.com straight from the server
$ : | openssl s_client -connect stackoverflow.com:443 > f.pem 2>& 1 &&
openssl x509 -in f.pem -noout -subject 2>& 1
Outputs:
Subject: CN = *.stackexchange.com

Checking the expiry dates of SSL certs

I wrote a script to find the expiry dates of SSL cert in a directory.
shopt -s nullglob
for f in *.0 *.pem *.key *.crt; do
echo "## CERTIFICATE NAME -> $f ##"
openssl x509 -noout -in $f -issuer -subject -dates
echo ""
done
Are there any improvements on this?
You shouldn't consider .key files - private keys don't have any expiry dates. Also, depending on your convention, .crt files might be PKCS12 files, in which case you would have to unpack them first.
Not sure why .0 files show up - if they are symlinks, you really should be looking only at the files pointed to. If so, the criterion for selecting files really should be to look at all links, not all .0 files (since there may also be .1 files).
Please check cmd to get Expected ans :
openssl x509 -noout -text -in abc.cer | grep Not
Output :
Not Before: Aug 30 10:14:54 2018 GMT
Not After : Aug 29 10:14:54 2021 GMT
Description : Use your .cer or crt certificate name

Resources