2

I have a lot of binary files that contain some data that is signed using CMS.

The files have the form:

$ openssl cms -inform DER -in test.cms -cmsout -print
CMS_ContentInfo: 
  contentType: pkcs7-signedData (1.2.840.113549.1.7.2)
  d.signedData: 
    version: 3
    digestAlgorithms:
        algorithm: sha256 (2.16.840.1.101.3.4.2.1)
        parameter: <ABSENT>
    encapContentInfo: 
      eContentType: pkcs7-data (1.2.840.113549.1.7.1)
      eContent: 
        0000 - 21 3c 61 72 63 68 3e 0a-64 65 62 69 61 6e 2d   !<arch>.debian-
        000f - 62 69 6e 61 72 79 2f 20-20 XX XX XX XX XX XX   binary/  XXXXXX
        […]
     10d82ab - d7 00 28 00 00                                 ..(..
    certificates:
      <ABSENT>
    crls:
      <ABSENT>
    signerInfos:
        version: 3
        d.subjectKeyIdentifier: 
          0000 - (DATA REMOVED FOR PRIVACY REASONS)
          000f - (DATA REMOVED FOR PRIVACY REASONS)
        digestAlgorithm: 
          algorithm: sha256 (2.16.840.1.101.3.4.2.1)
          parameter: <ABSENT>
        signedAttrs:
            object: contentType (1.2.840.113549.1.9.3)
            set:
              OBJECT:pkcs7-data (1.2.840.113549.1.7.1)

            object: signingTime (1.2.840.113549.1.9.5)
            set:
              UTCTIME: (SOMETIME) 2021 GMT

            object: messageDigest (1.2.840.113549.1.9.4)
            set:
              OCTET STRING:
                0000 - (DATA REMOVED FOR PRIVACY REASONS)
                000d - (DATA REMOVED FOR PRIVACY REASONS)
                001a - (DATA REMOVED FOR PRIVACY REASONS)
        signatureAlgorithm: 
          algorithm: ecdsa-with-SHA256 (1.2.840.10045.4.3.2)
          parameter: <ABSENT>
        signature: 
          0000 - (DATA REMOVED FOR PRIVACY REASONS)
          000f - (DATA REMOVED FOR PRIVACY REASONS)
          001e - (DATA REMOVED FOR PRIVACY REASONS)
          002d - (DATA REMOVED FOR PRIVACY REASONS)
          003c - (DATA REMOVED FOR PRIVACY REASONS)
        unsignedAttrs:
          <ABSENT>

I'm currently not interested in the signature. Is there an elegant way to strip it? I can build work-around code that tries to analyze the output above, grep in the file and dd parts of it but this seems rather ugly.

1
  • openssl cms -in file -inform der -verify -nosigs -noverify -out newfile (oxymoronic though it appears) Commented Dec 8, 2022 at 5:03

1 Answer 1

2
openssl cms -inform DER -in (file_with_signature) -cmsout -print | sed -n '/eContent/,/certificates/p' | grep -v eContent | grep -v certificates | awk -F' ' '{print $3$4$5$6$7$8$9$10$11$12$13$14$15$16}' | sed 's/-//' | xxd -r -p > (file_without_signature)

Starting with your command, and piping through things:

  1. sed -n '/eContent/,/certificates/p' prints only the section of the output that contains the original binary file,

  2. grep -v eContent removes the line that says eContent,

  3. grep -v certificates removes the line that says certificates,

  4. awk -F' ' '{print $3$4$5$6$7$8$9$10$11$12$13$14$15$16}' prints only the section containing the hexadecimal corresponding to the original binary file content,

  5. sed 's/-//' removes the dash in the binary content (who knows why THAT is in there, whatever), and finally,

  6. xxd -r -p reverts the hexadecimal output to binary.

The > (file_without_signature) part sends the output to a new file, that contains only the original binary, without the signature.

Note that your (file_without_signature) should be named with a recognizable file extension (probably, whatever file extension the original binary would have had), and you may need to use chmod to change read/write/execute permissions, for the new file to be usable in the way that it was, before it was signed.

P.S. - If "elegance" is a concern, you can copy/paste that command into a script and replace (file_with_signature) with $1, and (file_without_signature) with $2, for a command that executes like:

./script.sh (file_with_signature) (file_without_signature). 

Or, in the script, use a for file in /directory/path do before the command, replace (file_with_signature) with $file, and (file_without_signature) with $file.orig, then done after the command, to iterate over a whole directory of these things, and create a bunch of .orig files, that are the files without the signatures.

You must log in to answer this question.

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