I'm trying to debug a S/MIME signing framework that is functioning wrong. On the input I have

  • a signed message with detached certificate
  • a certificate which private key the message was probably signed with

But when I'm trying to put this all together I got

openssl smime -verify \
-in /tmp/efx5a9e37e3992a3/response.p7b -inform der \
-certfile /tmp/efx5a9e37e3992a3/equifax.pem -noverify \
-out /tmp/efx5a9e37e3992a3/response.xml

Verification failure
signer certificate not found:pkcs7/pk7_smime.c:470:

I understand that this error is probably caused by the fact that openssl utility clearly sees that the certificate that I'm proposing it to verify the message with isn't the one. So my question is - how can I see this for myself ? Am I right assuming that I can dump the ASN.1 structures from the signed message and compare like the certificate serial or it's fingerprint (finding this information suddenly appeared a bit tricky, so I still don't know what it is - may be it's some other attribute) with the certificate I'm using for verification - and see for myself - okay, that is it ?

Also it would be nice if someone will point me at the documentation describing this.


Be careful with the naming

Aside: you might want to say a 'separate' or 'separately provided' or 'unincluded' certificate. 'Detached' vs 'embedded' signatures in PKCS7/CMS/SMIME are a fairly important feature, and although signatures and certificates are different things this could easily get confused.


Yes, you can dump a PKCS7/CMS and look at the info that identifies the signer cert, which is issuer name and serial number or (rarely, and only since rfc2630 in 1999) a key fingerprint (not cert). Here is an example der signeddata not containing the cert, but embedding (not detaching) the data (since your command implies that) and using signed attributes (which you didn't indicate one way or the other):

$ xxd se181073.p7b
0000000: 3082 0262 0609 2a86 4886 f70d 0107 02a0  0..b..*.H.......
0000010: 8202 5330 8202 4f02 0101 310b 3009 0605  ..S0..O...1.0...
0000020: 2b0e 0302 1a05 0030 1706 092a 8648 86f7  +......0...*.H..
0000030: 0d01 0701 a00a 0408 666f 6f62 6172 0d0a  ........foobar..
0000040: 3182 0222 3082 021e 0201 0130 2030 1331  1.."0......0 0.1
0000050: 1130 0f06 0355 0403 0c08 7365 3138 3130  .0...U....se1810
0000060: 3733 0209 0083 2c1c 0d9b 0320 b930 0906  73....,.... .0..
0000070: 052b 0e03 021a 0500 a081 d830 1806 092a  .+.........0...*
0000080: 8648 86f7 0d01 0903 310b 0609 2a86 4886  .H......1...*.H.
0000090: f70d 0107 0130 1c06 092a 8648 86f7 0d01  .....0...*.H....
00000a0: 0905 310f 170d 3138 3033 3037 3036 3033  ..1...1803070603
00000b0: 3032 5a30 2306 092a 8648 86f7 0d01 0904  02Z0#..*.H......
00000c0: 3116 0414 60e6 44a5 6cb3 048e 15e6 2d88  1...`.D.l.....-.
00000d0: e311 c28e 5a4f 6d28 3079 0609 2a86 4886  ....ZOm(0y..*.H.
00000e0: f70d 0109 0f31 6c30 6a30 0b06 0960 8648  .....1l0j0...`.H
00000f0: 0165 0304 012a 300b 0609 6086 4801 6503  .e...*0...`.H.e.
0000100: 0401 1630 0b06 0960 8648 0165 0304 0102  ...0...`.H.e....
0000110: 300a 0608 2a86 4886 f70d 0307 300e 0608  0...*.H.....0...
0000120: 2a86 4886 f70d 0302 0202 0080 300d 0608  *.H.........0...
0000130: 2a86 4886 f70d 0302 0201 4030 0706 052b  *.H.......@0...+
0000140: 0e03 0207 300d 0608 2a86 4886 f70d 0302  ....0...*.H.....
0000150: 0201 2830 0d06 092a 8648 86f7 0d01 0101  ..(0...*.H......
0000160: 0500 0482 0100 0eea c31c bebb b64f 5c55  .............O\U
0000170: d5a5 5202 d59e 4742 57df cbce 42c9 f6b9  ..R...GBW...B...
0000180: 954a f6dd 1336 a99a be66 2513 bbba e176  .J...6...f%....v
0000190: acbd 2cf6 6988 847f 5fcd 6f28 e23f 1097  ..,.i..._.o(.?..
00001a0: 76a7 5f65 c028 25e2 c26d e054 d3a5 d7dc  v._e.(%..m.T....
00001b0: 5168 a71d 1860 b4e8 96fc e553 032d 3a03  Qh...`.....S.-:.
00001c0: 25cd 3761 3076 99a6 bf79 43ea 43a5 7438  %.7a0v...yC.C.t8
00001d0: d10b e160 dd66 f592 cea1 6ab7 221b 8ec1  ...`.f....j."...
00001e0: 9921 9ae1 f739 5b61 6495 290b 1f7f dae4  .!...9[ad.).....
00001f0: 41d5 0f9b 5acf 2331 1447 5755 a063 c7de  A...Z.#1.GWU.c..
0000200: 6830 ed43 875d a733 c588 370c e161 a7e8  h0.C.].3..7..a..
0000210: 005e 8afa c07b 5ade 2ffe dfb3 c0a0 1e28  .^...{Z./......(
0000220: 9726 5679 be4e d5ae 005c 8e50 ee83 13ac  .&Vy.N...\.P....
0000230: 1ea0 144c ad72 df79 d60b 9f5b 4f5f 188d  ...L.r.y...[O_..
0000240: f644 52cd 932b a24b b277 323c 7991 7418  .DR..+.K.w2<y.t.
0000250: 1bf8 c997 fd2f 1652 7658 ca42 be2f dc92  ...../.RvX.B./..
0000260: 678d 8dbd 756a                           g...uj


Now use asn1parse to dump the ASN.1 structure and most contents:

$ openssl asn1parse -in se181073.p7b -inform der -i
    0:d=0  hl=4 l= 610 cons: SEQUENCE
    4:d=1  hl=2 l=   9 prim:  OBJECT            :pkcs7-signedData
   15:d=1  hl=4 l= 595 cons:  cont [ 0 ]
   19:d=2  hl=4 l= 591 cons:   SEQUENCE
   23:d=3  hl=2 l=   1 prim:    INTEGER           :01
   26:d=3  hl=2 l=  11 cons:    SET
   28:d=4  hl=2 l=   9 cons:     SEQUENCE
   30:d=5  hl=2 l=   5 prim:      OBJECT            :sha1
   37:d=5  hl=2 l=   0 prim:      NULL
   39:d=3  hl=2 l=  23 cons:    SEQUENCE
   41:d=4  hl=2 l=   9 prim:     OBJECT            :pkcs7-data
   52:d=4  hl=2 l=  10 cons:     cont [ 0 ]
   54:d=5  hl=2 l=   8 prim:      OCTET STRING      :foobar

   64:d=3  hl=4 l= 546 cons:    SET
   68:d=4  hl=4 l= 542 cons:     SEQUENCE
   72:d=5  hl=2 l=   1 prim:      INTEGER           :01
   75:d=5  hl=2 l=  32 cons:      SEQUENCE
   77:d=6  hl=2 l=  19 cons:       SEQUENCE
   79:d=7  hl=2 l=  17 cons:        SET
   81:d=8  hl=2 l=  15 cons:         SEQUENCE
   83:d=9  hl=2 l=   3 prim:          OBJECT            :commonName
   88:d=9  hl=2 l=   8 prim:          UTF8STRING        :se181073
   98:d=6  hl=2 l=   9 prim:       INTEGER           :832C1C0D9B0320B9
  109:d=5  hl=2 l=   9 cons:      SEQUENCE
  111:d=6  hl=2 l=   5 prim:       OBJECT            :sha1
  118:d=6  hl=2 l=   0 prim:       NULL
  120:d=5  hl=3 l= 216 cons:      cont [ 0 ]
  123:d=6  hl=2 l=  24 cons:       SEQUENCE
  125:d=7  hl=2 l=   9 prim:        OBJECT            :contentType
  136:d=7  hl=2 l=  11 cons:        SET
  138:d=8  hl=2 l=   9 prim:         OBJECT            :pkcs7-data
  149:d=6  hl=2 l=  28 cons:       SEQUENCE
  151:d=7  hl=2 l=   9 prim:        OBJECT            :signingTime
  162:d=7  hl=2 l=  15 cons:        SET
  164:d=8  hl=2 l=  13 prim:         UTCTIME           :180307060302Z
  179:d=6  hl=2 l=  35 cons:       SEQUENCE
  181:d=7  hl=2 l=   9 prim:        OBJECT            :messageDigest
  192:d=7  hl=2 l=  22 cons:        SET
  194:d=8  hl=2 l=  20 prim:         OCTET STRING      [HEX DUMP]:60E644A56CB3048E15E62D88E311C28E5A4F6D28
  216:d=6  hl=2 l= 121 cons:       SEQUENCE
  218:d=7  hl=2 l=   9 prim:        OBJECT            :S/MIME Capabilities
  229:d=7  hl=2 l= 108 cons:        SET
  231:d=8  hl=2 l= 106 cons:         SEQUENCE
  233:d=9  hl=2 l=  11 cons:          SEQUENCE
  235:d=10 hl=2 l=   9 prim:           OBJECT            :aes-256-cbc
  246:d=9  hl=2 l=  11 cons:          SEQUENCE
  248:d=10 hl=2 l=   9 prim:           OBJECT            :aes-192-cbc
  259:d=9  hl=2 l=  11 cons:          SEQUENCE
  261:d=10 hl=2 l=   9 prim:           OBJECT            :aes-128-cbc
  272:d=9  hl=2 l=  10 cons:          SEQUENCE
  274:d=10 hl=2 l=   8 prim:           OBJECT            :des-ede3-cbc
  284:d=9  hl=2 l=  14 cons:          SEQUENCE
  286:d=10 hl=2 l=   8 prim:           OBJECT            :rc2-cbc
  296:d=10 hl=2 l=   2 prim:           INTEGER           :80
  300:d=9  hl=2 l=  13 cons:          SEQUENCE
  302:d=10 hl=2 l=   8 prim:           OBJECT            :rc2-cbc
  312:d=10 hl=2 l=   1 prim:           INTEGER           :40
  315:d=9  hl=2 l=   7 cons:          SEQUENCE
  317:d=10 hl=2 l=   5 prim:           OBJECT            :des-cbc
  324:d=9  hl=2 l=  13 cons:          SEQUENCE
  326:d=10 hl=2 l=   8 prim:           OBJECT            :rc2-cbc
  336:d=10 hl=2 l=   1 prim:           INTEGER           :28
  339:d=5  hl=2 l=  13 cons:      SEQUENCE
  341:d=6  hl=2 l=   9 prim:       OBJECT            :rsaEncryption
  352:d=6  hl=2 l=   0 prim:       NULL
  354:d=5  hl=4 l= 256 prim:      OCTET STRING      [HEX DUMP]:0EEAC31CBEBBB64F5C55D5A55202D59E474257DFCBCE42C9F6B9954AF6DD1336A99ABE662513BBBAE176ACBD2CF66988847F5FCD6F28E23F109776A75F65C02825E2C26DE054D3A5D7DC5168A71D1860B4E896FCE553032D3A0325CD3761307699A6BF7943EA43A57438D10BE160DD66F592CEA16AB7221B8EC199219AE1F7395B616495290B1F7FDAE441D50F9B5ACF233114475755A063C7DE6830ED43875DA733C588370CE161A7E8005E8AFAC07B5ADE2FFEDFB3C0A01E2897265679BE4ED5AE005C8E50EE8313AC1EA0144CAD72DF79D60B9F5B4F5F188DF64452CD932BA24BB277323C799174181BF8C997FD2F16527658CA42BE2FDC92678D8DBD756A
 $ # -i causes the output 'details' to be indented according to the structure; 
 $ # you can omit this and just use the d=depth values but that's slightly harder

SignerInfo structure

Compare this to the structures specified by PKCS7 or its newer and more convenient IETFized form Cryptographic Message Syntax CMS rfc2315 section 9 or rfc2360 section 5.1 or rfc3369 ditto or rfc3852 ditto. First there is an outer wrapper (defined in section 7 or 3 of the above refs) which is a SEQUENCE of an OID and a context-0 tag, which for signeddata is a SEQUENCE. At offset 23 we have the version number and at 26 the set of digest AlgIds and at 39 the EncapsulatedContentInfo containing the data. Since (all) certs were omitted, at offset 64 we have the SET of SignerInfo's, defined a few pages later in section 9.2 or 5.3:

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

SignerIdentifier ::= CHOICE {
        issuerAndSerialNumber IssuerAndSerialNumber,
        subjectKeyIdentifier [0] SubjectKeyIdentifier }

-- SubjectKeyIdentifier is defined elsewhere as OCTET STRING

SignatureValue ::= OCTET STRING

So at offset 72 we have the version of SI, at 77 the issuer name which is a SEQUENCE of normally several SETs (in my simple example only one, CommonName) each containing one or more (here one) pair (SEQUENCE) of OID and value, and at 98 the serial number; these match (and are taken from) the issuer name and serial number in the certificate. For other signing software we could instead have a context-0 tag containing an OCTET STRING which matches (and is taken from) the SubjectKeyIdentifier extension (if present) in the certificate.

To finish, at offset 102 we have the AlgId for the digest, at 120 context-0 containing the signed attributes (previously called authenticated) which is implicit SEQUENCE of pairs (SEQUENCE) of OID and SET of value(s), and at 339 the signature itself as an AlgId and an OCTET STRING.

In case you don't know, AlgorithmIdentifier which I shorten to AlgId is defined by X.509 (and thus rfc3280 and rfc5280) as a SEQUENCE of an OID for an algorithm plus 'parameters' of varying type for that algorithm -- for the algorithm I used, RSA, the parameters are NULL. This pairing is used very widely in crypto. Note the OID assigned for rsaEncryption is used for RSA signature also, although the original 1970s concept that 'signature is encryption with the private key' proved dangerously misleading and was dropped; security.SX and crypto.SX have numerous answers and comments on this.

Successful verification

And here is a demonstration of successful verification using that cert:

$ openssl x509 -issuer -serial -subject -in se181073.cer
issuer= /CN=se181073
subject= /CN=se181073
$ openssl smime -verify -in se181073.p7b -inform der -certfile se181073.cer -noverify
Verification successful

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.