2

I have several timestamp token files that I think should have TSA certificates embedded within them because the "Request TSA certificate" option was selected when I requested them with TimeStampClient. Now I want to verify them with openssl with a command line like this:

openssl.exe ts -verify -data file.zip -in token.tst -token_in -CAfile certificate.cer

So I need the certificates. BTW I think that for real verification I should not get the certificates from the token files themselves (because they can be fake/self signed?) if the files were from an untrusted party.

BTW can you please tell me a way to get the TSA timestamp certificate from its server via RFC 3161 protocol? Some servers like time.certum.pl does not provide a straightforward link to it at that web address.

user273084
  • 247
  • 3
  • 7

4 Answers4

3

You can get embedded certificates in you timestamp token with the command :

openssl pkcs7 -inform der -in token.tst -print_certs | sed -n '/-----BEGIN/,/-----END/p' > chain.pem

Or if you deals with TSR (timestamp response) instead of TST (timestamp token) :

openssl ts -reply -in timestampresponse.tsr -token_out | openssl pkcs7 -inform der -print_certs | sed -n '/-----BEGIN/,/-----END/p' > chain.pem
fred727
  • 131
  • 3
  • According to the data in the Q, OP already has the token separated from the response and your first step isn't needed. Otherwise concur. – dave_thompson_085 Feb 02 '20 at 07:03
  • Thank you @dave_thompson_085, I have edited my answer – fred727 Feb 02 '20 at 20:11
  • are you sure this generates a valid file? If I try to load the file back in using `openssl pkcs7 -inform pem -in chain.pem` I get `unable to load PKCS7 object` . Doesn't it require additional header and footer for example and maybe other things? – matthias_buehlmann Feb 04 '21 at 12:09
3

I was having trouble with this too. In addition to the other answers, I found a mailing list post that says the following:

Looking at the TS code in OpenSSL, it seems that the peer's chain is not used in the way one might expect (to help construct the untrusted portion of the chain). Rather, surprisingly, it looks like the peer's certificates appear to be used as a "constraint" on the constructed chain, and verification fails some chain element was not provided by the peer. I don't know why this is done.

So that means you need to manually construct the full chain. The answer from fred727 has the most important part of the info, but here's a full example.

Assume you have response.tsr from http://timestamp.digicert.com. Extract the subject and issuer info from the embedded certificates:

openssl ts -reply -in response.tsr -token_out \
    | openssl pkcs7 -inform der -print_certs \
    | grep 'subject\|issuer'

That gives this output:

subject=C = US, O = "DigiCert, Inc.", CN = DigiCert Timestamp 2021
issuer=C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert SHA2 Assured ID Timestamping CA
subject=C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert SHA2 Assured ID Timestamping CA
issuer=C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert Assured ID Root CA

The first certificate is DigiCert Timestamp 2021 and was issued by DigiCert SHA2 Assured ID Timestamping CA which was issued by DigiCert Assured ID Root CA. The DigiCert Assured ID Root CA certificate is part of the OS certificate store (at least on Ubuntu), so you can use the known good root certificate along with the embedded certificates supplied in the timestamping response to build a full chain. As long as you trust the root, you can trust the full chain.

Use fred727's advice to create a partial chain from the embedded certificates.

openssl ts -reply -in response.tsr -token_out \
    | openssl pkcs7 -inform der -print_certs \
    | sed -n '/-----BEGIN/,/-----END/p' > chain.pem

Then concatenate the well known root with the supplied chain.

cat chain.pem /etc/ssl/certs/DigiCert_Assured_ID_Root_CA.pem > timestamp.digicert.com-full-chain.pem

Now you should be able to use that full chain as the argument to the CAfile option to verify signatures.

Ryan J
  • 131
  • 2
2

An RFC3163 response does not necessarily contain the signing certificate itself. It contains a SignedData structure, which is described in RFC5652 thusly:

  SignedData ::= SEQUENCE {
    version CMSVersion,
    digestAlgorithms DigestAlgorithmIdentifiers,
    encapContentInfo EncapsulatedContentInfo,
    certificates [0] IMPLICIT CertificateSet OPTIONAL,
    crls [1] IMPLICIT RevocationInfoChoices OPTIONAL,
    signerInfos SignerInfos }

  DigestAlgorithmIdentifiers ::= SET OF DigestAlgorithmIdentifier

  SignerInfos ::= SET OF SignerInfo

The certificates field is optional, whereas the signerInfos field is not. A SignerInfo structure is defined as follows:

SignerInfo ::= SEQUENCE {
  version CMSVersion,
  sid SignerIdentifier,
  digestAlgorithm DigestAlgorithmIdentifier,
  signedAttrs [0] IMPLICIT SignedAttributes OPTIONAL,
  signatureAlgorithm SignatureAlgorithmIdentifier,
  signature SignatureValue,
  unsignedAttrs [1] IMPLICIT UnsignedAttributes OPTIONAL }

The sid field contains a unique identifier for the signer, which can be traced back to the certificate which signed it.

There is no standardised way to retrieve the certificate outside the certificates field of the SignedData structure. If it is not provided in that field, the TSA must provide it out of band. How exactly that is done is up to the TSA.

Polynomial
  • 132,208
  • 43
  • 298
  • 379
  • Can a TSA certificate be self-signed? – user273084 Sep 06 '17 at 04:11
  • @user273084 The certificate installed on the server to sign TSA requests can be self-signed, yes. It provides no security though, unless it's self-signed in the sense of using an internal CA for your organisation. – Polynomial Sep 06 '17 at 08:56
1

BTW I think that for real verification I should not get the certificates from the token files themselves (because they can be fake/self signed?) if the files were from an untrusted party.

Only partly.

The concept of PKI is that you can accept subordinate certificates, possibly to multiple levels, from an untrusted source or via an untrusted channel, and (then, or later) cryptographically validate them against a root certificate, only if you have predefined/preconfigured 'out of band' the root cert(s). The set of root cert(s) you trust is conventionally called your 'truststore'. Trusting a small number of CA roots -- rarely more than a hundred, and sometimes only a few or one -- and using them to validate the potentially billions of certs issued and signed by those CAs is much more practical than validating every website, business, organization and person in the world yourself.

In practice, for (the https part of) the Web, the browser maker either provides a truststore (Firefox) or uses one from the OS (MSIE/Edge, Chrome, Safari). Some application environments (Java, nodejs, PHP, Python) have or can add a truststore. For other applications you may need to find or create one yourself.

BTW can you please tell me a way to get the TSA timestamp certificate from its server via RFC 3161 protocol? Some servers like time.certum.pl does not provide a straightforward link to it at that web address.

If your app requested it, the subordinate cert for the TSA itself, and perhaps a chain cert, should be in your token, as per fred727's answer. The root cert may or may not be present, but if present, you should never automatically trust a root obtained in untrusted data. Instead as above you should get it or already have it via a different, trusted channel.

A little poking at www.certum.{pl,eu} finds https://www.certum.pl/pl/cert_wiedza_repozytorium_pl_en/ which points to https://www.certum.eu/en/cert_expertise_root_certificates/ which includes among others two TSA server certs and the root cert. But how do you trust this webpage? It is secured by a cert issued under Certum's own root, so you can use these certs to trust Certum only if you already trust Certum, which is an infinite regress.

I look at the truststores of my Windows, Firefox and (recent) Java installs, and this root is present in all of them; this means that unless someone has thoroughly hacked my system without me noticing anything, Microsoft, Mozilla and Oracle have evaluated this CA/root and decided it is trustworthy. I accept that as sufficient, although if the data involved were critically important I might try to do additional checks myself.

Another popular approach especially for use with OpenSSL is that the curl project provides a convenient conversion of the Mozilla truststore to the PEM format file needed by OpenSSL.

dave_thompson_085
  • 9,759
  • 1
  • 24
  • 28