I've used OpenSSL cms to sign the data and generate a detached signature. As per my requirements, I need to timestamp the signature as well, so that if the certificate expired, verification of signature can be done. The generated timestamp is also in a detached format. I've also generated the CRL after revoking the certificate.
NOTE: For testing purpose, I’ve created my own CA authority using OpenSSL
For signing data:
openssl cms -sign -binary -in test_data.tgz -md sha256 -signer my-cert.pem -inkey my-cert.key -out test_data.cms -outform DER
For timestamping signature: (Used freetsa.org as a TSA authority)
openssl ts -query -data test_data.cms -no_nonce -sha256 -cert -out test_data.tsq
curl -H "Content-Type: application/timestamp-query" --data-binary '@test_data.tsq' https://freetsa.org/tsr > test_data.tsr
Now for the verification part as per my understanding from RFC3161 (https://www.rfc-editor.org/rfc/rfc3161#page-20) following procedure can be used to verify the authenticity of the digital signature.
- Verify timestamp token:
openssl ts -verify -in test_date.tsr -queryfile date_tsr.tsq -CAfile cacert.pem -untrusted tsa.crt
openssl ts -verify -data test_data.cms -in test_data.tsr -CAfile cacert.pem -untrusted tsa.crt
- Fetch the timestamp:
openssl ts -reply -in test_date.tsr -text
> Time stamp: Apr 24 13:09:25 2020 GMT (Example)
- Convert timestamp to Unix epoch time:
date -d “Apr 24 13:09:25 2020 GMT” +%s
> 1587733765
- Verify the signature againt timestamp and the certificates via openssl cms
openssl cms -verify -binary -verify -in test_data.cms -content test_data -CAfile ca-chain.cer -inform DER -out /tmp/tmp.data -attime 1587733765
Everything works until crl (Certificate revocation list) comes into the picture. What I know is that If the certificate (my-cert.pem in this case) has been revoked and if the “Invalidity Date” is after the timestamp data, the signature should still be valid. But with OpenSSL cms -verify it is not working as expected or it is not supported.
- Revoke certificate:
openssl ca -config openssl.conf -revoke my-cert.pem -crl_reason key -crl_reason keyCompromise -crl_compromise 20200422140925Z
Compromise date is after the timestamp date.
- Verify the signature with crl and timestamp
openssl cms -verify -binary -verify -in test_data.cms -content test_data -CAfile ca-chain.cer -inform DER -out /tmp/tmp.data -attime 1587733765 -crl_check
output: CRL is not yet valid
I think OpenSSL is comparing the “Last Update” date of CRL instead of “Invalidity date” with the date mentioned in -attime argument, i.e. 1587733765 dues to which it shows “CRL is not yet valid”.
- Removing “-attime”
openssl cms -verify -binary -verify -in test_data.cms -content test_data -CAfile ca-chain.cer -inform DER -out /tmp/tmp.data -crl_check
Output: Certificate revoked
So how do I verify the signature with CRL and timestamp in OpenSSL cms? The only way I see is to fetch the “Invalidity Date” manually from CRL and compare it with the timestamp and act accordingly.