Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Verifying authenticode signature using openssl API

793 views
Skip to first unread message

Prasad Dabak

unread,
Sep 6, 2014, 11:43:30 PM9/6/14
to
Hello,

Given a signed Windows portable executable, I want to programmatically verify two things using openssl APIs

1. Verify the digital signature.
2. Confirm that the executable is signed by a specific company using that company's public key.

It seems that part (1) can be done by parsing the signedData attribute in the portable executable, extracting the hashing algorithm and digest stored there, re-computing the digest of the executable using the same hashing algorithm and match them.

I have following questions.

1. The signData contains messageDigest (unencrypted) and encryptedDigest (encrypted). Is it enough to match messgaeDigest with the computed digest? OR we also need to decrypt the encryptedDigest using the company public key and match that as well?
2. What does PKCS7_Verify exactly do? I looked at https://www.openssl.org/docs/crypto/PKCS7_verify.html  and I understand  that it verifies certificate chain.  However, it's not clear to me as to what exactly it does with respect to signature verification?
3. I am assuming that I require to do both (1) and (2) in order to verify the authenticode signature?
4. What is the best way to verify if the executable is signed by specific company using that company's public key?

Any inputs will be greatly appreciated!

Thanks.
-Prasad

Jakob Bohm

unread,
Sep 7, 2014, 4:07:38 PM9/7/14
to
On 07/09/2014 05:43, Prasad Dabak wrote:
Hello,

Given a signed Windows portable executable, I want to programmatically verify two things using openssl APIs

1. Verify the digital signature.
2. Confirm that the executable is signed by a specific company using that company's public key.

It seems that part (1) can be done by parsing the signedData attribute in the portable executable, extracting the hashing algorithm and digest stored there, re-computing the digest of the executable using the same hashing algorithm and match them.

I have following questions.

1. The signData contains messageDigest (unencrypted) and encryptedDigest (encrypted). Is it enough to match messgaeDigest with the computed digest? OR we also need to decrypt the encryptedDigest using the company public key and match that as well?
Both.

Comparing the stored messageDigest to the actual digest in the
spcIndirectDataContext structure checks that the signature
actually is for this file.� Note that Authenticode defines a
specific file format specific "formula" for omitting the
signature itself from the input to the message digest.


Decrypting the "encryptedDigest" (really validating the
signedDigest against a digest of the relevant part of the PKCS#7
structure, the field name is historic) is necessary to check if
the signature is a valid signature made with the expected public
key.� This step is, technically, the actual signature
verififcation, but it is meaningless without all the other checks.


Additionally, for Authenticode, you need to do a few extra things
(that should be done *first*, since they are cheaper than the
actual signature check, and one of them affects the signature
check)
:

- Verify that the PKCS#7 structure field contentInfo is a
�spcIndirectDataContext structure containing a list of attributes.
�This is consistent with the original PKCS#7 standard/RFC, but
�not entirely with the later e-mail focused CMS s
tandard/RFC.
- Verify that the spcIndirectDataContext structure includes the
�correct set of magic attributes for the file type, as otherwise,
�the signature is not for this file even if the digest value
�matches.� These fields indicate the choice of "formula" ("Subject
�Identification Package") for determining the subset of file bytes
�to pass the the message digest.
� In particalar, if the spcSipInfo
�field is present it must have the correct value, and check the
�presence of any other file format specific attributes (for PE
�EXE/DLL/OCX/SYS files, this means an spcPEImageData attribute
�of a very specific form that includes the BMPString
�"<<<Obsolete>>>" to distinguish it from the historic Authenticode1
�signatures).

- Verify that the spcIndirectDataContext structure includes an
�attribute whose OID is the OID of a hash algorithm and contains
�the number of bytes for that type of message digest, and matches
�your own calculation of that message digest of the file type
�specific subset of bytes of the file itself.

- Verify that each signerInfo in signerInfos has at least the
�following authenticated attributes: contentType ==
�spcIndirectDataContext and a messageDigest (see also answer 2) .
�Other authenticated attributes are usually present, but not
�mandatory.

- If there is an authenticated attribute of type spcSpOpusInfo, you
�may want to consider this the file description and information URL
�from the manufacturer who signed this signerInfo, but only after
�all the checks pass.
- If a signerInfo contains one or more unauthenticatedAttributes
�of type counterSignature, those should be validated first as being
�valid signerinfos for signatures of the encryptedDigest of the outer
�signerinfo.� If one of them is, and contains an (inner)
�authenticatedAttribute of type signingTime that countersignature is
�for an entity whose certificate in the certificates collection is
�valid for extended usage purpose "timeStamping" (including a
�recursive requirement that this purpose is also present for its
�issuer), then the time indicated by that signingTime field overrides
�the value of the local clock when determining the validity of the
�certificates for the signature on that particular outer signerinfo.

- Other spcIndirectDataContext attributes,
�unauthenticatedAttributes and/or authenticatedAttributes are
�usually present, but are not mandatory.� An attribute present
�in the wrong of the attribute lists should also be ignored.
�For example a signingTime in the outer signerinfo cannot be used
�to set the time used for the validity checks of that outer
�signerinfo.

- Verify that each of the outer signerinfos refers to a signature
�in the certificates collection which is valid for the extended
�usage purpose of "Code Signing" and a basic constraint of CA:FALSE.
�This check may fail for some test signatures, but should not fail
�for real signatures made with officially issued certificates.

�This check can be done during the PKCS7_verify call via callbacks
�etc.


2. What does PKCS7_Verify exactly do? I looked at https://www.openssl.org/docs/crypto/PKCS7_verify.html� and I understand� that it verifies certificate chain.� However, it's not clear to me as to what exactly it does with respect to signature verification?
I think it also verifies that the signerinfo refers to a certificate
that can be traced via the included certificates collection to one of
the loaded certificate authority root certificates.� And that the
encryptedDigest actuall
y matches a locally computed digest of the
authenticatedAttributes and that the messageDigest
authenticatedAttribute matches a locally computed digest of the
contentInfo.� It doesn't know about spcIndirectDataContext and the
attributes therein, so it won't check that.� Also, it currently
doesn't know about time stamping counterSignatures, so you have to
implement that yourself, including the possible use of a different
time during the certificate validations.


It is critical that you pass the verification functions both the CA
certificates and up to date CRLs for both the CAs and for any
intermediary CAs found in the PKCS#7 certificates collection.
Otherwise you may end up believing certificates made with stolen
keys, such as the stolen key that was used to sign the StuxNet
malware.� The OpenSSL code will happily verify signatures without a
CRL, but the result may be catastrophically wrong.


3. I am assuming that I require to do both (1) and (2) in order to verify the authenticode signature?
Yes.

4. What is the best way to verify if the executable is signed by specific company using that company's public key?

Perform all of the above checks, and also check that the Subject of
the certificate referenced in the signerInfo you check is that
company and that that particular certificate was issued by the
certificate authority known to be used by that company (if you happen
to know which one they prefer to use, for example Microsoft uses
certificates issued by their own CA, at least recently).

Any inputs will be greatly appreciated!

Additionally, note that many Microsoft files, and many device
drivers, are signed in
a slightly different way.� There is (in a
specific subdirectory of the Windows dir)
a ".cat" file which
contains a list of file hashes (each computed in the same way

as a hash in an spcIndirectDataContext) for unspecified files.
That .cat file is itself
signed by either Microsoft or the
manufacturer in the same way as described above,
but with
details indicating that this is a signature for the .cat file
.
For each valid
.cat file, you need to add the listed hashes
to your own list of file hashes that indicate that
a file with
any of those hashes should be considered signed by the company
that
signed the .cat file, even if it doesn't contain such a
signature itself.


Also note that for drivers, it is often the case that the driver
files themselves are
signed by the company that made them, but
the .cat file is signed by the Microsoft
department that manages
the list of "certified compatible" drivers.� This is called

WHQL signing.

Signatures on installed kernel mode .SYS, .DLL and other such files
often contain
an extra "cross certificate" in their certificates
collection
, issued by "Microsoft Code Verification Root" to the
actual CA that issued the company
certificate.� This is because
the signature checking code in Microsoft's bootloader
only knows
about that Microsoft CA.


Enjoy and good luck

Jakob
-- 
Jakob Bohm, CIO, Partner, WiseMo A/S.  http://www.wisemo.com
Transformervej 29, 2860 S�borg, Denmark.  Direct +45 31 13 16 10
This public discussion message is non-binding and may contain errors.
WiseMo - Remote Service Management for PCs, Phones and Embedded 

0 new messages