I have to create a PKCS7 signature file signed by an X.509 certificate and I have to embed an XML file within.
How to do that with OpenSSL or any other tool?
Information Security Stack Exchange is a question and answer site for information security professionals. It only takes a minute to sign up.Sign up to join this community
To be clear, the data to be signed is exactly the contents of a file, XML or otherwise?
You can't sign with only a certificate. You must sign with a privatekey and then provide the matching certificate to allow the recipient(s) to verify the message when they receive it. When using a certificate issued by a well-known CA (e.g. Verisign) you usually must provide a certificate chain not just the single certificate. Some UIs (especially Windows and at least some other browsers) confusingly use the term "certificate" to mean either just a single cert by itself, or a combination of a privatekey plus one cert or a chain of certs.
OpenSSL actually supports CMS (Cryptographic Message Syntax) which is the updated IETF version of PKCS#7, like TLS is the updated IETF version of SSL. If the very small technical differences between the older version PKCS#7 and the current version CMS matter to you or your recipient(s), you will probably need to write a custom program, which can use the OpenSSL library. OpenSSL also supports S/MIME which is basically just CMS adapted to MIME format (used in Internet-email and HTTP). To confuse things a bit, current OpenSSL commandline has two subcommands:
openssl smime ... an older utility that actually supports both S/MIME and CMS
openssl cms ... a newer utility that also actually supports both CMS and S/MIME
The simplest case of signing with embedded (not "detached") data is if you have the X.509 cert and privatekey (both) in PEM format in a file:
openssl cms -in datafile -sign -signer keyandcertfile -nodetach -outform pem|der
-outform pem or
der depending on which output format you want, but don't omit it; the default format is S/MIME which is not what you asked for. Output is normally on stdout, which you can redirect or pipe to something else as appropriate; add
-out outputfile to write directly to a file.
Variations: If you have the key and cert in different files, but both PEM, you can either just concatenate them into one file, or use
-signer certfile -inkey keyfile.
If you need to supply a chain cert (or several) and you have it (or them) in PEM format in a file or files, add
-certfile chaincertfile once or as many times as needed.
If the "certificate" (and privatekey!) you have is in any other form(s), OpenSSL can convert many other forms (though not all) to the PEM files it prefers; provide more exact details. (Edit your question by clicking on the word "edit" at its bottom; for clarity state which data is added or changed.)
If your data is not exactly one file, but can be selected or otherwise produced by some other program, omit
-in inputfile and instead pipe the input of
openssl from that other program.
All this assumes OpenSSL is available on the system you use, or equivalently you use a system where OpenSSL is available. If you need to obtain OpenSSL, specify your OS.