0

So OpenSSL can calculate a hash value for X509 certificates that uniquely identifies this certificate:

https://www.openssl.org/docs/man1.0.2/man1/x509.html (argument -hash or -subject_hash)

now, if I have a CMS file (https://www.rfc-editor.org/rfc/rfc3852) in DER encoding, which has a SignedData field with exactly one SignerInfo but which does not contain the actual certificate of the signature, how can I calculate the hash of the signing certificate identical to what openssl x509 -hash -noout -in actual_cert.pem would create for this certificate in question?

Looking at the CMS using openssl cms -inform DER -in infile.cms -cmsout -print yields

CMS_ContentInfo:
  contentType: pkcs7-signedData (1.2.840.113549.1.7.2)
  d.signedData:
    version: 3
    digestAlgorithms:
        algorithm: sha512 (2.16.840.1.101.3.4.2.3)
        parameter: NULL
    encapContentInfo:
      eContentType: id-smime-ct-TSTInfo (1.2.840.113549.1.9.16.1.4)
      eContent:
        0000 - 30 82 01 75 02 01 01 06-04 2a 03 04 01 30 31   0..u.....*...01
        000f - 30 0d 06 09 60 86 48 01-65 03 04 02 01 05 00   0...`.H.e......
        001e - 04 20 89 9b a3 d9 f7 77-e2 a7 4b dd 34 30 2b   . .....w..K.40+
        002d - c0 6c b3 f7 a4 6a c1 f5-65 ee 12 8f 79 fd 5d   .l...j..e...y.]
        003c - ab 99 d6 8b 02 03 2d 19-84 18 0f 32 30 32 31   ......-....2021
        004b - 30 32 30 34 31 34 33 30-35 36 5a 01 01 ff 02   0204143056Z....
        005a - 09 00 83 16 8e 99 d6 23-2e fc a0 82 01 11 a4   .......#.......
        0069 - 82 01 0d 30 82 01 09 31-11 30 0f 06 03 55 04   ...0...1.0...U.
        0078 - 0a 13 08 46 72 65 65 20-54 53 41 31 0c 30 0a   ...Free TSA1.0.
        0087 - 06 03 55 04 0b 13 03 54-53 41 31 76 30 74 06   ..U....TSA1v0t.
        0096 - 03 55 04 0d 13 6d 54 68-69 73 20 63 65 72 74   .U...mThis cert
        00a5 - 69 66 69 63 61 74 65 20-64 69 67 69 74 61 6c   ificate digital
        00b4 - 6c 79 20 73 69 67 6e 73-20 64 6f 63 75 6d 65   ly signs docume
        00c3 - 6e 74 73 20 61 6e 64 20-74 69 6d 65 20 73 74   nts and time st
        00d2 - 61 6d 70 20 72 65 71 75-65 73 74 73 20 6d 61   amp requests ma
        00e1 - 64 65 20 75 73 69 6e 67-20 74 68 65 20 66 72   de using the fr
        00f0 - 65 65 74 73 61 2e 6f 72-67 20 6f 6e 6c 69 6e   eetsa.org onlin
        00ff - 65 20 73 65 72 76 69 63-65 73 31 18 30 16 06   e services1.0..
        010e - 03 55 04 03 13 0f 77 77-77 2e 66 72 65 65 74   .U....www.freet
        011d - 73 61 2e 6f 72 67 31 22-30 20 06 09 2a 86 48   sa.org1"0 ..*.H
        012c - 86 f7 0d 01 09 01 16 13-62 75 73 69 6c 65 7a   ........busilez
        013b - 61 73 40 67 6d 61 69 6c-2e 63 6f 6d 31 12 30   [email protected]
        014a - 10 06 03 55 04 07 13 09-57 75 65 72 7a 62 75   ...U....Wuerzbu
        0159 - 72 67 31 0b 30 09 06 03-55 04 06 13 02 44 45   rg1.0...U....DE
        0168 - 31 0f 30 0d 06 03 55 04-08 13 06 42 61 79 65   1.0...U....Baye
        0177 - 72 6e                                          rn
    certificates:
      <ABSENT>
    crls:
      <ABSENT>
    signerInfos:
        version: 1
        d.issuerAndSerialNumber:
          issuer: O=Free TSA, OU=Root CA, CN=www.freetsa.org/[email protected], L=Wuerzburg, ST=Bayern, C=DE
          serialNumber: 13972846748170250626
        digestAlgorithm:
          algorithm: sha512 (2.16.840.1.101.3.4.2.3)
          parameter: NULL
        signedAttrs:
            object: contentType (1.2.840.113549.1.9.3)
            set:
              OBJECT:id-smime-ct-TSTInfo (1.2.840.113549.1.9.16.1.4)

            object: signingTime (1.2.840.113549.1.9.5)
            set:
              UTCTIME:Feb  4 14:30:56 2021 GMT

            object: id-smime-aa-signingCertificate (1.2.840.113549.1.9.16.2.12)
            set:
              SEQUENCE:
    0:d=0  hl=2 l=  26 cons: SEQUENCE
    2:d=1  hl=2 l=  24 cons:  SEQUENCE
    4:d=2  hl=2 l=  22 cons:   SEQUENCE
    6:d=3  hl=2 l=  20 prim:    OCTET STRING      [HEX DUMP]:916DA3D860ECCA82E34BC59D1793E7E968875F14

            object: messageDigest (1.2.840.113549.1.9.4)
            set:
              OCTET STRING:
                0000 - 4d b9 02 47 cb 66 6e 37-48 c7 56 04 1a   M..G.fn7H.V..
                000d - 77 45 23 95 72 1d 1d e8-62 3e 7b 68 9d   wE#.r...b>{h.
                001a - 58 43 88 64 a7 b3 1b be-bd 56 8e 58 8d   XC.d.....V.X.
                0027 - 8d 12 fe 11 dc 68 89 a5-56 aa bd 00 df   .....h..V....
                0034 - e4 8d f6 3b d8 8e 7d 78-c7 d2 42 a4      ...;..}x..B.
        signatureAlgorithm:
          algorithm: rsaEncryption (1.2.840.113549.1.1.1)
          parameter: NULL
        signature:
          0000 - 62 39 1e b9 0e e3 ab 74-fa 90 46 bd d6 78 bc   b9.....t..F..x.
          000f - 2e d6 a4 3a 7b f4 0e 45-11 ba 16 c0 48 46 5a   ...:{..E....HFZ
          001e - 52 87 c5 3c 9d ae c7 1d-83 dc c8 03 8f 2e 70   R..<..........p
          002d - 2c 4e 1f 6a 4e 5e 64 b7-5d 56 5e cb c9 6f af   ,N.jN^d.]V^..o.
          003c - 17 3d f4 2f c9 a5 b9 5c-d4 a1 03 1f 43 8f a3   .=./...\....C..
          004b - 46 13 62 df 4d f6 cc 48-ad 2c c3 43 85 5e 8c   F.b.M..H.,.C.^.
          005a - 5b da a8 97 8d 3a 06 28-72 56 f3 38 e3 06 ad   [....:.(rV.8...
          0069 - ca 80 28 28 73 3f 9a 6f-ed ba b9 ac ed f4 6f   ..((s?.o......o
          0078 - 69 9e 91 d4 d2 4d 6b 1f-98 53 16 66 d7 50 62   i....Mk..S.f.Pb
          0087 - 96 61 9f 0f f6 bd 94 19-d6 04 c5 7e f9 3c 89   .a.........~.<.
          0096 - 5a 8a d1 a1 05 72 4e 6f-9c 8a a5 ef 6b 36 8d   Z....rNo....k6.
          00a5 - e5 ee 8a e9 11 8b 1c 70-42 c7 32 6d 27 42 fb   .......pB.2m'B.
          00b4 - 99 71 25 ae 66 67 48 58-10 df 4a db 08 08 ea   .q%.fgHX..J....
          00c3 - b1 a0 d5 ca 22 4b 46 ad-12 fd a1 72 91 c4 8b   ...."KF....r...
          00d2 - 21 d2 ff d8 b3 13 7f f8-31 9c 42 f6 b4 ea b1   !.......1.B....
          00e1 - 15 21 8a ed e0 b9 6a 3c-0d 88 03 aa 4a ca f2   .!....j<....J..
          00f0 - 13 59 54 99 0b 19 70 4f-91 0a 7e f7 17 92 70   .YT...pO..~...p
          00ff - dd 0f 54 cc 1e e7 7b 42-d2 fa c2 53 3a 45 5a   ..T...{B...S:EZ
          010e - 45 09 c3 7b b5 34 6d 0b-40 82 72 45 4d eb 60   E..{[email protected].`
          011d - 00 57 c8 46 77 23 5b 1c-c0 ff 6b 01 5c 0e 2f   .W.Fw#[...k.\./
          012c - fb 87 b3 e6 42 e5 1b 1d-25 6c c5 43 c4 af b8   ....B...%l.C...
          013b - 9b 51 74 f2 c9 85 d2 54-52 ca b6 4e ac a1 83   .Qt....TR..N...
          014a - 28 80 99 11 d5 ed a0 82-ad cc df 7d 18 a4 2c   (..........}..,
          0159 - 05 79 c0 f9 be 7c 52 1e-33 84 0c a5 ae b4 4e   .y...|R.3.....N
          0168 - 6d 08 ee 68 13 44 35 15-5f e1 3d e5 72 36 72   m..h.D5._.=.r6r
          0177 - 05 8e 4c 4d 7f 0d ce 32-23 5c 16 bc 73 99 e6   ..LM...2#\..s..
          0186 - 68 ea c5 19 e7 4d d7 0f-22 d5 1c 61 ac a8 cf   h....M.."..a...
          0195 - b6 70 49 79 3c 22 1a 90-96 cd 3b fb 11 bb 56   .pIy<"....;...V
          01a4 - 4f 2a 41 a7 5d 61 f4 81-6a 1c ce 2d f9 0c bb   O*A.]a..j..-...
          01b3 - 91 80 7a 9d 9c 61 37 81-e1 77 20 d3 06 56 be   ..z..a7..w ..V.
          01c2 - f3 df 1c 74 47 ee ab 81-7a 03 80 96 95 a0 93   ...tG...z......
          01d1 - 4b f4 e6 b9 a2 f4 8b 2f-25 80 2f c9 b5 a3 99   K....../%./....
          01e0 - 34 e0 ab 8e 2b fb e3 ce-26 91 0a b3 6d af 18   4...+...&...m..
          01ef - 5a d7 a8 7c 3e c6 1c 17-0d e8 30 da df f2 5d   Z..|>.....0...]
          01fe - 51 3b                                          Q;
        unsignedAttrs:
          <ABSENT>

So I see there is one SignerInfo object.

According to 5.3. SignerInfo Type in https://www.rfc-editor.org/rfc/rfc3852 :

The fields of type SignerInfo have the following meanings:

      version is the syntax version number.  If the SignerIdentifier is
      the CHOICE issuerAndSerialNumber, then the version MUST be 1.  If
      the SignerIdentifier is subjectKeyIdentifier, then the version
      MUST be 3.

      sid specifies the signer's certificate (and thereby the signer's
      public key).  The signer's public key is needed by the recipient
      to verify the signature.  SignerIdentifier provides two
      alternatives for specifying the signer's public key.  The
      issuerAndSerialNumber alternative identifies the signer's
      certificate by the issuer's distinguished name and the certificate
      serial number; the subjectKeyIdentifier identifies the signer's
      certificate by a key identifier.

So in the provided example SignerInfo.version is 1, so the certificate is idenified by issuerAndSerialNumber so how would I compute the corresponding X509 hash? Just extract issuerAndSerialNumber.issuer and calculate the SHA-1 of it? If so, how can I extract this using Openssl?

If now the SignerInfo.version would be 3 instead of 1, if I understand the specification correctly there wouldn't be an issuerAndSerialNumber field but instead a SubjectKeyIdentifier field. Would this be already the hash that openssl x509 -hash -noout -in actual_cert.pem would output? If not, how would I calculate the corresponding hash in this case?

4
  • 1
    No, you can't compute the cert's subject_hash from issuerAndSerialNumber. No, subjectKeyIdentifier isn't the same as subject_hash either; OpenSSL's subject_hash is a hash of the subject's name (in X.500 form), SKI is a hash of the subject's publickey (specifically the BITSTRING value in the SubjectPublicKeyInfo structure), and these are completely different. Also neither of these necessarily identifies a unique cerrt; it is quite possible to have more than one cert for a given subject and key, but there should be only one cert with a given issuer&serial combination. ... Commented Feb 5, 2021 at 1:28
  • 1
    ... However, the data in your example is an RFC3161 timestamp token with 'tsa' present, and that "MUST correspond to one of the subject names included in the certificate" (see RFC3161 page 11) (and in practice TSAs don't have alternative names, so it is the subject name). If all your 'files' are like this, you can use that. Commented Feb 5, 2021 at 1:30
  • @dave_thompson_085 yes all files are RFC3161 timestamp tokens. But I still wonder how to get from therer to the corresponding openssl x509 -hash, because openssl equires the filenames of the certificates in the -CApath to correspond to that hash Commented Feb 5, 2021 at 1:45
  • You could use CAfile format and then you don't need the subject hashes, or just look at all the files in a CApath-style directory. But see more-or-less-answer. Commented Feb 7, 2021 at 9:34

1 Answer 1

0

As discussed in comments, you can't do that for CMS SignedData in general, but you can do it for an RFC3161 timestamp token that contains the tsa [0] GeneralName OPTIONAL element, which all I've looked at do. Since I don't have your token(s), I used one I have in my test data from freetsa:

$ cat se244280.c
/* se244280.c 2021-02-06 */
/* MINIMAL ERROR HANDLING FOR TEST ONLY */
#include <stdio.h>
#include <openssl/err.h>
#include <openssl/pkcs7.h>
#include <openssl/ts.h>

void err (const char *msg, int info){ fprintf (stderr, "%s: %d\n", msg, info); ERR_print_errors_fp(stderr); exit(1); }

int main (int argc, char**argv)
{
  BIO *bin = BIO_new_file(argv[1],"rb");
  PKCS7 *token;
  if( !(token = d2i_PKCS7_bio(bin,NULL)) ) err("d2i_PKCS7_bio",0);
  if( !PKCS7_type_is_signed(token)
    || OBJ_obj2nid(token->d.sign->contents->type) != NID_id_smime_ct_TSTInfo
    || token->d.sign->contents->d.other->type != V_ASN1_OCTET_STRING )
    printf ("not a token\n"), exit(1);

  ASN1_OCTET_STRING econt = * token->d.sign->contents->d.other->value.octet_string;
  const unsigned char *ptr = econt.data;
  TS_TST_INFO *info;
  if( !(info = d2i_TS_TST_INFO(NULL, &ptr, econt.length)) ) err("d2i_TS_TST_INFO",0);
  if( !info->tsa || info->tsa->type != GEN_DIRNAME )
    printf ("no/bad TSA\n"), exit(1);
  printf ("%08lx\n", X509_NAME_hash( info->tsa->d.dirn ) );
  return 0;
}
$ gcc se244280.c -o se244280 -lcrypto
$ ./se244280 token0
cc952886
$ openssl x509 -in tokencert0 -inform der -noout -subject_hash
cc952886
$ # tokencert0 is the signer cert for that TSA, obtained from a different token 
$ # where I set the option in the request that the cert(s) be included -- 
$ # which is the simpler and official solution to getting the signer cert(s)
$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .