Checking the expiry dates of SSL certs - shell

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

Related

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]}
...

Verify SSL certificate against various CRL files

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

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

Getting different output from openssl when piping file into command

I would like to sign a file using a dsa key and openssl. The DGST(1) man page says the following:
file...
file or files to digest. If no files are specified then
standard input is used.
For me this means that the following two terminal commands should give the same results, which they do not. I piped the output through od because the result is binary.
specify the file on command line
openssl dgst -dss1 -sign private_key.pem test_archive.zip | od -x
0000000 2c30 1402 e30d 9073 0059 0de7 f03e 8fd2
0000020 874b 5252 b025 8f44 1402 ed26 2f55 7fa4
0000040 f474 0426 1d44 787c ecd6 5059 921b
0000056
piping the file into the openssl command
openssl dgst -dss1 -sign private_key.pem < test_archive.zip | od -x
0000000 2c30 1402 2444 c3a5 f498 7bb8 3dfe 715d
0000020 e179 c5ad c0a5 2b16 1402 173b 692b 9d71
0000040 3970 c497 9994 9cbc 4cfd d642 62df
0000056
As you can see both outputs are not the same, although the file which should be signed is the same in both cases.
Why is this the case? Am I missing something obvious here?
Edit
I am using OpenSSL version 0.9.8y 5 Feb 2013 on FreeBSD and version 0.9.8r 8 Feb 2011 on Mac OS X 10.7.5 and observing the effect on both.
Edit 2 - How to generate a key for testing
small shell script for generating appropriate keys
#!/bin/bash
openssl=/usr/bin/openssl
${openssl} dsaparam 1024 < /dev/urandom > dsaparam.pem
${openssl} gendsa dsaparam.pem -out private_key.pem
${openssl} dsa -in private_key.pem -pubout -out public_key.pem
rm dsaparam.pem
I also ran a test on a CentOS 6 Linux system using OpenSSL version 1.0.0-fips which shows the same strange behavior.
Edit 3 - More Versions Tested
Also the freshly compiled OpenSSL version 1.0.1e 11 Feb 2013 shows this behavior.
I'm not able to reproduce this (OpenSSL 1.0.1 14 Mar 2012) . (I was using an RSA key) I think there are three possibilities:
OpenSSL bug [or different default option] You may have a different version that has a bug. For example:
http://rt.openssl.org/Ticket/Display.html?id=2965
(I don't necessarily think it's this particular bug, but it is similar.)
The key changed.
The zipfile changed
Try adding -binary to your commands. Looking at #1, it could be that my version is doing --binary by default, which excludes the digest type.
openssl dgst -sha1 </dev/null
(stdin)= da39a3ee5e6b4b0d3255bfef95601890afd80709
openssl dgst -sha1 /dev/null
SHA1(/dev/null)= da39a3ee5e6b4b0d3255bfef95601890afd80709
With the dsa key, I am able to reproduce this in multiple versions of openssl (1.0.1 and 0.9.8y)
Using the -hex option, I was also able to confirm that the prefix is changing.
(1.0.1)
openssl dgst -hex -dss1 -sign private_key.pem config
DSA-DSA(config)= 302e021500ca417b14be6e1c08426d4f4cdb3beb51181e6055021500e6a768689cfe9c6f7538e9ec2f952c9465fea80b
openssl dgst -hex -dss1 -sign private_key.pem <config
(stdin)= 302c02142a59682765ae10e37fe114ca63a21cdf4127ff5302141c8b3ac5caf538a23dc43b20cc9c01b1278c0d8e
(0.9.8y)
apps/openssl dgst -hex -dss1 -sign private_key.pem config
DSA(config)= 302e0215008aef560f547425fb4360e24be343fa6db2dc4551021500eb594cea70455400838dc0a14dae7b86614c5218
apps/openssl dgst -hex -dss1 -sign private_key.pem <config 302c02146aa92d6cf2cc9a6fb1d340fed21c29d05f936fc002141fd9e781def4897cfc306b7a68a92b90e6861cb9
Note: all 4 commands have different binary output. Given that the hex hash is the same but the prefix is different, it seems reasonable to infer that the differences in the prefixes are causing the changes in the outputs.
The behavior of OpenSSL is not a bug. The created signature is different if the file is piped in via stdin or specified on the command line, but both outputs are a valid signature if tested with
openssl dgst -dss1 -verify public_key.pem -signature file_with_archive_signature.sig test_archive.zip
Therefore I think that without looking at the algorithm there is more than one valid signature for each file, but a signature is only valid for one file (neglecting collisions).

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

Resources