#!/bin/bash set -e user_certificate="$1" issuer_certificate="$2" umask 177 cert_body="/tmp/cert-body.bin.$$" cert_sig_decrypted="/tmp/cert-sig-decrypted.bin.$$" cert_sig="/tmp/cert-sig.bin.$$" issuer_pubkey="/tmp/issuer-pub.pem.$$" trap 'rm -f $cert_body $cert_sig_decrypted $cert_sig $issuer_pubkey' 0 # extract the issuer public key: openssl x509 -in "$issuer_certificate" -noout -pubkey > /tmp/issuer-pub.pem # extract the signature: signature_hex=$(openssl x509 -in "$user_certificate" -text -noout -certopt ca_default -certopt no_validity -certopt no_serial -certopt no_subject -certopt no_extensions -certopt no_signame | grep -v 'Signature Algorithm' | tr -d '[:space:]:') echo "${signature_hex}" | xxd -r -p > /tmp/cert-sig.bin # decrypt the signature: openssl rsautl -verify -inkey /tmp/issuer-pub.pem -in /tmp/cert-sig.bin -pubin > /tmp/cert-sig-decrypted.bin # extract the decrypted signature: stored_signature=$(openssl asn1parse -inform der -in /tmp/cert-sig-decrypted.bin|sed -n 's/.*HEX DUMP.:\(.*\)/\1/p') # extract the certificate sans-signature: openssl asn1parse -in "$user_certificate" -strparse 4 -out /tmp/cert-body.bin -noout # extract the signature algorithm: algo=-$(openssl asn1parse -inform der -in /tmp/cert-sig-decrypted.bin|sed -n 's/.*OBJECT.*:\(.*\)/\1/p') # compute the signature: computed_signature=$(openssl dgst "$algo" /tmp/cert-body.bin|sed -n -e 's/.*= \(.*\)/\1/p') # check them: stored_signature=$(echo "${stored_signature}"|tr '[a-z]' '[A-Z]') computed_signature=$(echo "${computed_signature}"|tr '[a-z]' '[A-Z]') if [ "$stored_signature" = "$computed_signature" ] ; then exit 0 else printf 'Invalid signature.\nstored: %s\ncomputed: %s\n' "$stored_signature" "$computed_signature" exit 2 fi # tests: if false ; then openssl x509 -in "$user_certificate" -noout -text function dumpSubjectAlternativeNames(){ local user_certificate="$1" openssl asn1parse -i -in "$user_certificate" \ | grep -A1 'X509v3 Subject Alternative Name' \ | sed -n -e 's/.*HEX DUMP.:\(.*\)/\1/p' \ | while read altname ; do echo "$altname" \ | xxd -r -p \ | openssl asn1parse -inform der -in /dev/stdin done } ./openssl-verify-certificate-signature \ /Users/pjb/works/sbde/secrets/sbde/CA/sbde-dev-test--users/test-ssl-server/user.crt \ /Users/pjb/works/sbde/secrets/sbde/CA/sbde-dev-test--inteca/inteca.crt ./openssl-verify-certificate-signature \ /Users/pjb/works/sbde/secrets/sbde/CA/sbde-dev-test--inteca/inteca.crt \ /Users/pjb/works/sbde/secrets/sbde/CA/sbde-dev-test--rootca/rootca.crt ./openssl-verify-certificate-signature \ /Users/pjb/works/sbde/secrets/sbde/CA/sbde-dev-test--rootca/rootca.crt \ /Users/pjb/works/sbde/secrets/sbde/CA/sbde-dev-test--rootca/rootca.crt fi