OCSP_check.sh: new check logic
PATCH 1/1 OCSP_check.sh: new check logic
contrib/OCSP_check/OCSP_check.sh:
I discovered that, quite surprisingly, the exit status of "openssl ocsp" is 0 even if the certificate status is "revoked". This means that the logic of the script needs to be rewritten so that it parses the output returned by the query and explicitly looks for a
"0x<serial number>: good"
line, and exit if either the command has a non-zero exit status, or the above line is not found.
Doing that portably without bashisms requires some juggling around, so perhaps the code is slightly less clean now, but it does have many comments.
--- contrib/OCSP_check/OCSP_check.sh | 34 +++++++++++++++++++++++++--------- 1 files changed, 25 insertions(+), 9 deletions(-)
contrib/OCSP_check/OCSP_check.sh +25 -9
@@ -63,27 +63,43 @@ fi # begin if [ $check_depth -eq -1 ] || [ $cur_depth -eq $check_depth ]; then + eval serial="\$tls_serial_${cur_depth}" - # Check that the serial is not empty + # To successfully complete, the following must happen: + # + # - The serial number must not be empty + # - The exit status of "openssl ocsp" must be zero + # - The output of the above command must contain the line + # "0x${serial}: good" + # + # Everything else fails with exit status 1. + if [ -n "$serial" ]; then # This is only an example; you are encouraged to run this command (without # redirections) manually against your or your CA's OCSP server to see how # it responds, and adapt accordingly. - # Sample output: + # Sample output that is assumed here: # # Response verify OK # 0x428740A5: good # This Update: Apr 24 19:38:49 2010 GMT # Next Update: May 2 14:23:42 2010 GMT - openssl ocsp -issuer "$issuer" \ - "$nonce" \ - -CAfile "$verify" \ - -url "$ocsp_url" \ - -serial "0x${serial}" >/dev/null 2>&1 - else - exit 1 + status=$(openssl ocsp -issuer "$issuer" \ + "$nonce" \ + -CAfile "$verify" \ + -url "$ocsp_url" \ + -serial "0x${serial}" 2>/dev/null) + + if [ $? -eq 0 ]; then + # check that it's good + if echo "$status" | grep -Fq "0x${serial}: good"; then + exit 0 + fi + fi fi + # if we get here, something was wrong + exit 1 fi
Signature · 1 line
1.6.5.6
Quoted 18 lines · David Sommerseth
contrib/OCSP_check/OCSP_check.sh fi · line 102
Quoted 13 lines
contrib/OCSP_check/OCSP_check.sh +12
-0+ status=$(openssl ocsp -issuer "$issuer" \ + "$nonce" \ + -CAfile "$verify" \ + -url "$ocsp_url" \ + -serial "0x${serial}" 2>/dev/null) + + if [ $? -eq 0 ]; then + # check that it's good + if echo "$status" | grep -Fq "0x${serial}: good"; then + exit 0 + fi + fi fiWhat if you just send the result from openssl to awk via a pipe, and call 'exit {0,1}' from awk depending on if it's good or not ... that way, you' don't have to do this grep trickery.
Quoted 6 lines
Something like this:
<untested>
openssl ... | awk 'BEGIN{ret=1} /0x(.*): good/{ ret=0; exit } END{
exit ret}'
exit $?
</untested>
Yes, the problem with this is that the pipeline's exit status is that of the last command in the pipeline, and there's no standard way to know the exit status of previous commands in the pipeline.
So in your example, if openssl failed for some reason but awk didn't, $? would be 0, whereas we want the whole thing to fail in that case.
Bash (and some other shell probably) has some special variables to handle these situations, which however are extensions and thus not standard.
Now, one could argue that if openssl fails, surely the output will not contain the magic line we're looking for, and thus awk/grep will fail too. While this is probably true in this specific instance, I feel that testing the exit status of openssl separately is safer and cleaner.
This also makes it possible (although I didn't implement it) to provide more detailed error messages, so one could exit with "openssl failed" (and, depending on the actual exit status, even provide the exact error explanation) or "openssl ran successfully, but the certificate status is not good". Instead, if one does just
if openssl ocsp .... | grep; then
# good else # error fi
all one can say in the "error" branch is the fairly generic "either openssl OR grep failed", and the actual exit status of openssl would be inaccessible.
Signature · 1 line
D.
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Quoted 47 lines · Davide Brini
Quoted 18 lines · David Sommerseth
contrib/OCSP_check/OCSP_check.sh fi · line 102
Quoted 13 lines
contrib/OCSP_check/OCSP_check.sh +12
-0+ status=$(openssl ocsp -issuer "$issuer" \ + "$nonce" \ + -CAfile "$verify" \ + -url "$ocsp_url" \ + -serial "0x${serial}" 2>/dev/null) + + if [ $? -eq 0 ]; then + # check that it's good + if echo "$status" | grep -Fq "0x${serial}: good"; then + exit 0 + fi + fi fiWhat if you just send the result from openssl to awk via a pipe, and call 'exit {0,1}' from awk depending on if it's good or not ... that way, you' don't have to do this grep trickery.
Quoted 6 lines
Something like this:
<untested>
openssl ... | awk 'BEGIN{ret=1} /0x(.*): good/{ ret=0; exit } END{
exit ret}'
exit $?
</untested>Yes, the problem with this is that the pipeline's exit status is that of the last command in the pipeline, and there's no standard way to know the exit status of previous commands in the pipeline.
So in your example, if openssl failed for some reason but awk didn't, $? would be 0, whereas we want the whole thing to fail in that case.Bash (and some other shell probably) has some special variables to handle these situations, which however are extensions and thus not standard.
Now, one could argue that if openssl fails, surely the output will not contain the magic line we're looking for, and thus awk/grep will fail too. While this is probably true in this specific instance, I feel that testing the exit status of openssl separately is safer and cleaner.
This also makes it possible (although I didn't implement it) to provide more detailed error messages, so one could exit with "openssl failed" (and, depending on the actual exit status, even provide the exact error explanation) or "openssl ran successfully, but the certificate status is not good". Instead, if one does just
Quoted 9 lines
if openssl ocsp .... | grep; then
# good else # error fiall one can say in the "error" branch is the fairly generic "either openssl OR grep failed", and the actual exit status of openssl would be inaccessible.
With this in mind, that OpenSSL can in some circumstances return "good" while the exit code is != 0 indicating that OpenSSL did have troubles verifying the certificate - this is the sensible approach ... so ACK!
Patch applied to bugfix2.1 and merged into allmerged commit 9ca155403ec72c7152bcb05c4bf8588c7cf2617b
kind regards,
David Sommerseth
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.10 (GNU/Linux)
Comment: Using GnuPG with Fedora - http://enigmail.mozdev.org/
iEYEARECAAYFAkvwMG4ACgkQDC186MBRfrqyQgCfRoRTzxDHNFp5ROGCSFgq1+lG oP0An0YXmczAz/QZ60zoyUNcpA4bp74S
=m605
-----END PGP SIGNATURE-----