If you are after validation when a piece of data was generated and verified. It is possible to sign arbitrary data with a timestamp in the same way as Authenticode.
Why would you want to do this? In my scenario I have a scanned image database, This database contains all the Proof of Delivery documents for a large transport company. Suppose I want to sign all the inward images at the time they were first imported into the database.
This level of protection costs about 2kb per image, and will provide assurance that the image has not changed since the timestamp was signed. It would not provide protection if the file is resigned. You could employ some sort of anti-replay protection.
To get started, for the proof of concept, suppose we want to sign “testfile.txt” with the text abcdxyz inside
# openssl ts -query -data "testtimestamp.txt" -cert -sha256 -no_nonce -out request.tsq
This will result in the request file “request.tsq” being generated. Which is essentially the SHA256 hash of test file.txt.
request.tsq 000 30390201 01303130 0d060960 86480165 |09...010...`.H.e| 010 03040201 05000420 073f5622 473e0b6b |....... .?V"G>.k| 020 3f485afe fcadff10 b281b8df be81e308 |?HZ.............| 030 882cf331 e667f068 0101ff |.,.1.g.h...|
This file is now served to the time stamping service of our choice.
# cat request.tsq | curl -s -S -H 'Content-Type: application/timestamp-query' --data-binary @- http://timestamp.globalsign.com/scripts/timestamp.dll -o response.tsr
You will then get a P7 response that contains the timestamp and signature of when the file signature was signed. This is the most important file to save for verification. You can also verify against the hashed request file, it will save you time when it comes to verifying large files.
The easiest way to display the signature time is through openssl again,
# openssl ts -reply -in response.tsr -text Status info: Status: Granted. Status description: unspecified Failure info: unspecified TST info: Version: 1 Policy OID: 184.108.40.206.4.1.4146.2.2 Hash Algorithm: sha256 Message data: 0000 - 07 3f 56 22 47 3e 0b 6b-3f 48 5a fe fc ad ff 10 .?V"G>.k?HZ..... 0010 - b2 81 b8 df be 81 e3 08-88 2c f3 31 e6 67 f0 68 .........,.1.g.h Serial number: 0x1DAAB7B41F40C33E4F29A4CC09BF0582A684BFCD Time stamp: Sep 1 01:10:50 2020 GMT Accuracy: unspecified Ordering: no Nonce: unspecified TSA: DirName:/C=SG/O=GMO GlobalSign Pte Ltd/CN=GlobalSign TSA for Standard - G2 Extensions:
If you have the root certificate file you can also verify the signature chain through this method.
Saved Signature Verification # openssl ts -verify -CAfile ./bundle.cer -in response.tsr -queryfile request.tsq Using configuration from /usr/lib/ssl/openssl.cnf Verification: OK Verifying directly against source file # openssl ts -verify -CAfile ./bundle.cer -data testfile.txt -in response.tsr Using configuration from /usr/lib/ssl/openssl.cnf Verification: OK Testing whether the timestamp becomes invalid # echo abcxyy > testfile.txt && openssl ts -verify -CAfile ./bundle.cer -data testfile.txt -in response.tsr Using configuration from /usr/lib/ssl/openssl.cnf Verification: FAILED 139911881494976:error:2F064067:time stamp routines:ts_check_imprints:message imprint mismatch
Please be aware that to verify your certificate bundle, you already need a working trust store. Whether you built that trust store manually by concatenating multiple root and intermediate certificates you wish to trust or using the system trust model.
As expected if your source file changes but your verifying the TSQ against the TSR then it will still return it is valid.