<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>