Getting the SSL certificate fingerprint of smtp.gmail.com - bash

I don't understand why this command is failing
openssl s_client -connect smtp.gmail.com:587 -starttls smtp < /dev/null 2>/dev/null | openssl x509 -fingerprint -noout -in /dev/stdin | cut -d'=' -f2
I am trying to initiate a TLS smtp session with the smtp server of Gmail and then redirect the output of the console to the x509 function in order to extract the fingerprint.
Here is what I get when I run the command without filtering the errors
$ openssl s_client -connect smtp.gmail.com:587 -starttls smtp < /dev/null
connect: Bad file number
connect:errno=9
What am I doing wrong?

There is a firewall upstream of my connexion which seems to block my query.
Adding torify at the beginning of the command (I have Tor installed on my computer) solved the issue.
user#home:~$ torify openssl s_client -connect smtp.gmail.com:587 -starttls smtp < /dev/null 2>/dev/null | openssl x509 -fingerprint -noout | cut -d'=' -f2
D3:7C:82:FC:D0:5F:8F:D7:DA:A2:59:8C:42:D7:B2:9F:C1:9F:7E:60

The above sample works perfect with :25 also.
openssl s_client -connect some.smtp.host:25 -starttls smtp < /dev/null 2>/dev/null | openssl x509 -fingerprint -noout | cut -d'=' -f2

Related

Script to get domain's SSL expiry date

I want to create a bash script that takes url as an argument.
for ex: ./scriptname https://domainame.com/
Current one works with with domainname.com but not with the full URL.
I get this error when I try to enter the full URL,
unable to load certificate
140398535546784:error:0906D06C:PEM routines:PEM_read_bio:no start line:pem_lib.c:707:Expecting: TRUSTED CERTIFICATE
This is the one I have currently have,
#!/bin/bash
echo | openssl s_client -connect $1:443 2> /dev/null | \
openssl x509 -noout -enddate | \
cut -d = -f 2
A quick fix is to cut the parts of protocol and path out of the url
#!/bin/bash¬
NoProtocol="${1//https:\/\//}"¬
DomainOnly="${NoProtocol%%/*}"¬
¬
echo | openssl s_client -connect ${DomainOnly}:443 2> /dev/null | \¬
openssl x509 -noout -enddate | \¬
cut -d = -f 2¬

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.

OpenSSL: Verifying a certificate against a CRL returning "unable to get issuer certificate" on OS X 10.11.6 El Capitan

I am using following script to verify the certificate against crl on OS X 10.11.6 El Capitan.
host=wikipedia.org
port=443
openssl s_client -connect $host:$port 2>&1 < /dev/null | sed -n '/-----BEGIN/,/-----END/p' > $host.pem
crlurl=$(openssl x509 -noout -text -in $host.pem | grep -A 4 'X509v3 CRL Distribution Points' | grep URI | grep -Eo '(http|https)://[^"]+')
curl $crlurl -o $host.crl.der
openssl crl -inform DER -in $host.crl.der -outform PEM -out $host.crl.pem
OLDIFS=$IFS; IFS=':' certificates=$(openssl s_client -connect "$host":"$port" -showcerts -tlsextdebug -tls1 2>&1 </dev/null | awk '/BEGIN CERT/ {p=1} ; p==1; /END CERT/ {p=0}' | sed 's/-----BEGIN/:-----BEGIN/g'); for certificate in ${certificates#:}; do echo $certificate | tee -a $host.chain.pem ; done; IFS=$OLDIFS
cat $host.chain.pem $host.crl.pem > $host.crl_chain.pem
openssl verify -crl_check -CAfile $host.crl_chain.pem $host.pem
It is working fine on ubuntu but throwing following error when trying to run on OS X 10.11.6 El Capitan.
wikipedia.org.pem: C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert SHA2 High Assurance Server CA
error 2 at 1 depth lookup:unable to get issuer certificate
Connecting wikipedia.org with s_client returns :
Verify return code: 20 (unable to get local issuer certificate)
The CA issuer of wikipedia.org is present in truststore i.e cacerts.pem in your ubuntu which are mostly located in
lib/security/cacerts
& is absent in your OS X 10.11.6 El Capitan. truststore
$(/usr/libexec/java_home)/jre/lib/security/cacerts
Use following command to view SSL certificate chain & try appending root CA of wikipedia.org to your mac truststore
openssl s_client -showcerts -servername wikipedia.org -connect wikipedia.org:443

error:0906D06C:PEM routines:PEM_read_bio:......o/pem/pem_lib.c:637:Expecting: TRUSTED CERTIFICATE

We were able to connect but its not fetching the cert details
$ bash-3.2# echo | openssl s_client -host $h -port $p 2>/dev/null
CONNECTED(00000005)
$
Any idea why its not fetching the cert details.
Try this,
openssl s_client -connect hostname:443 -servername hostname 2>/dev/null | openssl x509 -noout -enddate

BASH variable timeout if not aquired in X time

Hey guys I am trying to figure out a way to time out a variable if it goes past X time trying to get contents, this is based on touching a server to verify it has SSL. If the server doesn't respond in X seconds I would like to just set the variable as empty (or set some other flag if possible)
What I am using is
response=$(echo ^D |openssl s_client -connect ${line}:443 2> /dev/null |openssl x509 -noout -hash |grep -E '^[[:xdigit:]]{8}')
where $line is baidu.com for now
I tried something like this
( cmdpid=$BASHPID;
( sleep 10; kill $cmdpid; echo -e "\n\t$line missed window, terminating...\n"
) & exec response=$(echo ^D |openssl s_client -connect ${line}:443 2> /dev/null |openssl x509 -noout -hash |grep -E '^[[:xdigit:]]{8}')
)
But realized several issues, such as A) I am in a subshell and cannot get my variable out, B) I am trying to run response=#hash and returning errors etc
What would the best way to run a timeout on capturing my variable?
Thanks
IFS= read -t 10 -d '' variable < <(yourcommand)
e.g.
IFS= read -t 10 -d '' response < <(echo ^D |openssl s_client -connect ${line}:443 2> /dev/null |openssl x509 -noout -hash |grep -E '^[[:xdigit:]]{8}')

Resources