<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
</head>
<body>
<p><font size="-1" face="Courier New, Courier, monospace">Good day,<br>
<br>
I don't fully understand ocsp certificate verification. In order
to better understand it, I want to do it manually. I can already
do that with certificates.<br>
<br>
</font><font size="-1" face="Courier New, Courier, monospace"><font
size="-1" face="Courier New, Courier, monospace">$ </font>openssl
s_client -connect openssl.org:443 -showcerts<br>
# I save the server.crt and intermediate.crt<br>
<br>
$ openssl verify -no-CApath -partial_chain -trusted
intermediate.crt server.crt<br>
server.crt: OK<br>
<br>
Manually:<br>
# Get the ASN id's of the TBS and Signature<br>
</font><font size="-1" face="Courier New, Courier, monospace"><font
size="-1" face="Courier New, Courier, monospace">$ </font>asn=`openssl
asn1parse -i -in server.crt |egrep -e '(^ .*: SEQUENCE|: BIT
STRING)'`<br>
</font><font size="-1" face="Courier New, Courier, monospace"><font
size="-1" face="Courier New, Courier, monospace">$ </font>asn_tbs=`echo
"$asn" | head -1 | awk -F: '{print $1}' | sed 's/ //g'`<br>
</font><font size="-1" face="Courier New, Courier, monospace"><font
size="-1" face="Courier New, Courier, monospace">$ </font>asn_sig=`echo
"$asn" | tail -1 | awk -F: '{print $1}' | sed 's/ //g'`<br>
</font></p>
<p><font size="-1" face="Courier New, Courier, monospace"># Get tbs<br>
openssl asn1parse -in server.crt -strparse ${asn_tbs} -out
server.tbs > /dev/null</font></p>
<p><font size="-1" face="Courier New, Courier, monospace"># Hash tbs<br>
</font><font size="-1" face="Courier New, Courier, monospace"><font
size="-1" face="Courier New, Courier, monospace">$ </font>cat
server.tbs | openssl sha256 -binary > server.tbs.sha256<br>
</font></p>
<p><font size="-1" face="Courier New, Courier, monospace"># Get
signature (ignore 'header too long' error)<br>
</font><font size="-1" face="Courier New, Courier, monospace"><font
size="-1" face="Courier New, Courier, monospace">$ </font>openssl
asn1parse -in server.crt -strparse ${asn_sig} -out server.sig
> /dev/null<br>
<br>
# Get public key of intermediate<br>
</font><font size="-1" face="Courier New, Courier, monospace"><font
size="-1" face="Courier New, Courier, monospace">$ </font>openssl
x509 -in intermediate.crt -noout -pubkey > intermediate.pub</font></p>
<p><font size="-1" face="Courier New, Courier, monospace"># Recover
(decrypt) the signature<br>
</font><font size="-1" face="Courier New, Courier, monospace"><font
size="-1" face="Courier New, Courier, monospace">$ </font>openssl
rsautl -inkey intermediate.pub -pubin -in server.sig -out
server.sig.recovered</font></p>
<p><font size="-1" face="Courier New, Courier, monospace"># Verify.
Ignore the first line of server.sig.recovered, this is the hash
algoritm designator<br>
</font><font size="-1" face="Courier New, Courier, monospace"><font
size="-1" face="Courier New, Courier, monospace">$ </font>od
-An -tx1 -w19 server.sig.recovered<br>
30 31 30 0d 06 09 60 86 48 01 65 03 04 02 01 05 00 04 20<br>
87 36 67 06 ba d7 10 18 72 d3 f6 58 00 a9 34 78 bc 82 bf<br>
57 37 20 ab 82 04 fb 04 78 38 e2 d3 a2<br>
</font><font size="-1" face="Courier New, Courier, monospace"><font
size="-1" face="Courier New, Courier, monospace">$ </font>od
-An -tx1 -w19 server.tbs.sha256<br>
87 36 67 06 ba d7 10 18 72 d3 f6 58 00 a9 34 78 bc 82 bf<br>
57 37 20 ab 82 04 fb 04 78 38 e2 d3 a2<br>
</font></p>
<p><font size="-1" face="Courier New, Courier, monospace">Yay. Now
how do I do that with OCSP ?</font></p>
<p><font size="-1" face="Courier New, Courier, monospace"># Get OCSP<br>
</font><font size="-1" face="Courier New, Courier, monospace"><font
size="-1" face="Courier New, Courier, monospace">$ </font>ocsp=`openssl
x509 -noout -ocsp_uri -in server.crt`<br>
</font></p>
<p><font size="-1" face="Courier New, Courier, monospace"># Verify<br>
$ ocsp_response=`openssl ocsp -noverify -no_nonce -respout
ocsp.resp -reqout ocsp.req -issuer intermediate.crt -cert
server.crt -text -url $ocsp`<br>
$ echo "$ocsp_response" | grep server.crt<br>
server.crt: good<br>
</font></p>
<p><font size="-1" face="Courier New, Courier, monospace">Manually:<br>
# Get the signature. Can't find how to do this with asn1parse<br>
$ for byte in `echo "$ocsp_response" | grep -A40 " Signature
Algorithm" | grep -B40 "server.crt" | egrep -ve '(Signature
Algorithm|server.crt)' | sed -e 's/ //g' -e 's/:/ /g'`; do<br>
echo -ne "\x$byte"<br>
done </font><font size="-1" face="Courier New, Courier,
monospace"><font size="-1" face="Courier New, Courier,
monospace">> ocsp.resp.sig</font></font></p>
<p><font size="-1" face="Courier New, Courier, monospace"># </font><font
size="-1" face="Courier New, Courier, monospace"><font size="-1"
face="Courier New, Courier, monospace">Recover (decrypt) the
signature<br>
$ openssl rsautl -inkey intermediate.pub -pubin -in
ocsp.resp.sig -out ocsp.resp.sig.recovered</font></font></p>
<p><font size="-1" face="Courier New, Courier, monospace"><font
size="-1" face="Courier New, Courier, monospace"># Print the
decrypted signature (looks good, first line is hash algorithm
designator, length looks ok, no errors)<br>
$ od -An -tx1 -w19 ocsp.resp.sig.recovered<br>
30 31 30 0d 06 09 60 86 48 01 65 03 04 02 01 05 00 04 20<br>
b4 83 f2 c3 4a 6c 1b 4e df 66 b4 d5 31 0b 58 c3 60 3c e9<br>
20 0f 4f b0 df 61 88 2f c0 e0 25 66 a8<br>
</font></font></p>
<p><font size="-1" face="Courier New, Courier, monospace"><font
size="-1" face="Courier New, Courier, monospace">But.. How to
extract the tbs data from the response, so I can sha256 that
and compare ?<br>
</font></font></p>
</body>
</html>