On 19/09/2014 09:14, Prasad Dabak wrote:
> The RFC links helped.
>
> I am able to do decrypt the encrypted digest and match it
with the
> DigestInfo as explained in rfc2315.
> DigestInfo ::= SEQUENCE {
> digestAlgorithm DigestAlgorithmIdentifier,
> digest Digest }
>
> Digest ::= OCTET STRING
>
> I typically get back 35 byte decrypted digest which matches
with sequence above.
> I am also able to validate counterSignatures in similar fashion.
>
> Now I am trying this with various Authenticode executables
and one
> small issue that I found is: For some authenticode
executables, the
> counterSignature encryption only considers the bytes of the
Digest
> OCTET_STRING i.e. it does not consider digestAlgorithm
field. Because
> of this, the decrypted counterSignature is 20 bytes long
(size of sha1
> hash) instead of 35 bytes mentioned earlier. It does match
with bytes
> of the Digest OCTET_STRING.
>
> Is this expected behavior? How do I programmatically check this
> behavior? If the size of decrypted counterSignature is equal
to size
> of the hash, assume that digestAlgorithm field is not
considered?
>
"Decrypting" and RSA signature should produce a byte string almost
as long as the RSA key length, e.g.127 bytes for 1024 bits, 255
bytes for 2048 bits etc.
Next step is to check if those 127/255/... bytes are formatted
according to the appropriate portion of PKCS#1, whichspecifies
TWO different formats, the old "v1.5" format which is mostly the
DigestAlgorithm OID and the digest packed into a simple ASN.1
structure and then padded, and the new "PSS" format, where the
hash is combined with a random value using a formula which you
can only reverse if you know what the digest should be.
I suspect you may be encountering both formats, since the
countersignature and the primary signature are generated by
different computers belonging to different companies (the
countersignature is generated by a server owned and run be the CA,
the primary signature is generated by the manufacturer and/or
Symantec).
You also need to consider that other signature algorithms such as
DSS/DSA and ECDSA might be used, as specified in the certificates
used for the signatures.
Note: For RSA signatures, PKCS#1 == RFC3447.
> Thanks.
> -Prasad
>
>
> On Sep 16, 2014, at 10:51 AM, Jakob Bohm
<jb-open...@wisemo.com <mailto:jb-open...@wisemo.com> > wrote:
>
> > On 16/09/2014 12:22, Prasad Dabak wrote:
> > > Hello,
> > >
> > > I am currently focusing on matching
various digests that we
> > talked
> > > about earlier in the thread.
> > >
> > > 1. Computing the hash of the executable
(excluding the areas as
> > > defined by MS) and matching it with the
value stored in
> > > spcIndirectData. This is straight forward
and figured out.
> > > 2. Computing the hash of spcIndirectData
and matching it
> > with with
> > > "messageDigest" stored in
AuthenticatedAttributes. I
> > realized that the
> > > sequence and length bytes need to be
skipped before
> > computing the hash
> > > of the spcIndirectData? Is this documented
anywhere?
> > This is specified in the PKCS#7 standard (RFC2315),
in particular,
> > PKCS#7 specifies that when there is a non-empty
contentInfo field
> > in the PKCS#7 structure, which part of that should
be hashed. In
> > this case that contentInfo is a Microsoft-defiend
spcIndirectData,
> > but the calculation is unaffected. This should also
be built in
> > to the PKCS7 functions (I hope).
> > > 3. Computing hash of
AuthenticatedAttributes and matching it
> > with
> > > decrypted version of encryptedDigest. I am
struggling to get
> > this.
> > > Which portion of AuthenticatedAttributes
should be
> > considered for
> > > computing the hash? Further when I decrypt
the
> > encryptedDigest using
> > > the signer's public key, I get back a 256
byte value. This
> > doesn't
> > > look like a SHA1 hash like in case (1) and
(2). So what type
> > of hash
> > > it is? Can someone elaborate OR point to
documentation that
> > elaborates
> > > on this?
> > This is specified in the PKCS#7 standard (RFC2315).
This should
> > also be built in to the PKCS7 functions (I hope).
> >
> > By the way, the rules for checking the timestamp
countersignature
> > (but not its effect on checking the outer
signature) is specified
> > in RFC2985 section 5.3.6. The rules for parsing the
SigningTime
> > attribute used inside timestamp contersignatures
(and elsewhere
> > with less trust) are in RFC2985 section 5.3.3.
> > >
> > > On Sep 09, 2014, at 10:18 AM, Prasad Dabak
> > <pda...@icloud.com <mailto:pda...@icloud.com>
<mailto:pda...@icloud.com <mailto:pda...@icloud.com> > > wrote:
> > >
> > > > Thanks Jacob for your response.
Very informative
> > indeed!
> > > >
> > > > Thanks
> > > > -Prasad
> > > >
> > > > Sent from my iPhone
> > > >
> > > > > On 09-Sep-2014, at 10:05 pm,
Jakob Bohm
> > > > <jb-open...@wisemo.com
<mailto:jb-open...@wisemo.com>
> > <mailto:jb-open...@wisemo.com
<mailto:jb-open...@wisemo.com> > <mailto:jb-open...@wisemo.com
<mailto:jb-open...@wisemo.com>
> > <mailto:jb-open...@wisemo.com
<mailto:jb-open...@wisemo.com> > > > wrote:
> > > > >
> > > > > > On 09/09/2014
09:01, Prasad Dabak
> > wrote:
> > > > > > Thanks Jacob for an
elaborate
> > answer. Somehow I
> > > > never received your response to
my registered email
> > address, hence
> > > > delay in responding.
> > > > > This time I have CC-ed you
in addition to
> > the mail list.
> > > > > > I have a few
follow-up questions
> > on your response.
> > > > > >
> > > > > > 1. So,
"encryptedDigest" has no
> > relation to the
> > > > stored "messageDigest"? I thought
it's a encrypted
> > version of the
> > > > messageDigest?
> > > > > As far as I recall, there is
a chain of 4
> > digests. The first
> > > > digest
> > > > > is calculated over the file
and is stored
> > in the
> > > > spcIndirectData. The
> > > > > second digest is calculated
over the
> > spcIndirectData (the
> > > > contentInfo
> > > > > of the the PKCS#7 structure)
and is stored as
> > > > "messageDigest" in the
> > > > > AuthenticatedAttributes of
each PKCS#7
> > signerInfo. The third
> > > > hash
> > > > > is calculated over the
> > AuthenticatedAttributes and is signed to
> > > > > produce the
"encryptedDigest" in that same
> > signerInfo. All 3
> > > > need to
> > > > > be checked to confirm that
the file hash
> > is actually
> > > > (indirectly)
> > > > > signed by the
encryptedDigest using the
> > public key in the
> > > > certificate
> > > > > whose name is listed in the
signerInfo.
> > > > > > 2. I agree that
it's better to do
> > cheaper checks
> > > > first e.g. I am also matching PE
checksum stored in
> > the optional header.
> > > > > Indeed, though that is a
very weak
> > checksum (file size plus
> > > > 16 bit TCP/IP
> > > > > checksum of file). Also it
is allowed to
> > be 0 to indicate no
> > > > checksum
> > > > > (even if you set the
checksum, it might be
> > cleared if an
> > > > Administrator
> > > > > adds his own
countersignature to all
> > authorized programs on his
> > > > > computers, aka AppLocker).
> > > > > > 3. spcPEImageData
is probably
> > relevant only for
> > > > signing that uses page hashes?
> > > > > I never quite figured out
where they store
> > the page hashes.
> > > > However I
> > > > > believe the constant semi-empty
> > spcPEImageData with the
> > > > "<<<obsolete > > >"
> > > > > string is the traditional
marker to
> > indicate that the
> > > > signature is for
> > > > > a PE file, and not e.g. a
document file
> > with the same hashed
> > > > bytestream.
> > > > >
> > > > > > 4. PKCS7_verify is
already
> > matching the
> > > > encryptedDigest, do we still need
to validate it
> > ourselves?
> > > > > If it is, I am myself
guessing a bit as to
> > what that
> > > > function does and
> > > > > does not check. But note
that it probably
> > doesn't check the
> > > > full chain
> > > > > of 3 message digests, since
at least the
> > digest over the
> > > > file itself is
> > > > > inside a blob that the
PKCS#7 standard has
> > no opinion about.
> > > > > > 5. So, basically
are are
> > suggesting to look into
> > > > the subject string and see if we
can find patterns
> > like
> > > > /CN=COMPANY-NAME... issuer:
> > /C=US/O=SIGNER_NAME....? How
> > > > authoritative it is? I mean can
someone else have
> > same COMPANY-NAME
> > > > and PATTERN-NAME in their
certificate?
> > > > > Actually, the subject is a
data structure
> > (a hierarchical
> > > > list of sets
> > > > > of tagged strings) and the
relevant
> > comparison would be to
> > > > compare those
> > > > > elements that don't change
when getting a
> > new certificate
> > > > from the CA.
> > > > > It is the CAs responsibility
to make sure
> > the don't issue
> > > > certificates
> > > > > to the wrong people, and if
they make a
> > mistake they are
> > > > expected to
> > > > > quickly add the bad
certificate to their
> > published CRL,
> > > > which is why
> > > > > you need to check the CRL
before trusting
> > the certificate. An
> > > > > additional check is to make
sure the CA
> > that issued the
> > > > intermediary
> > > > > certificate that issued the
"COMAPNY-NAME"
> > certificate is
> > > > actually one
> > > > > of the (few) CAs that
"COMPANY-NAME" is
> > going to buy
> > > > certificates from.
> > > > > This protects against fake
certificates
> > issued by smaller
> > > > CAs that
> > > > > you aren't going to use anyway.
> > > > > >
> > > > > > In my case, I am
the one who is
> > signing the
> > > > executable using my certificate
and a "cross
> > certificate" issued by
> > > > Microsoft and I want to
programmatically ensure
> > following things.
> > > > > >
> > > > > > 1. Code is not
tampered since it
> > was signed
> > > > (matching messageDigest with
computed hash)
> > > > > Actually matching digest in
> > spcIndirectData with computed
> > > > hash. Plus
> > > > > consistency checks to make
sure the
> > signature is actually
> > > > for a PE file
> > > > > and was not otherwise
doctored. For
> > instance there should be
> > > > no bytes
> > > > > in the file after the end of
the signature
> > blob.
> > > > > > 2. Verifying the
digital
> > signature (PKCS7_Verify)
> > > > > > 3. Confirming that
the executable
> > is signed by my
> > > > company certificate.
> > > > > >
> > > > > > I am stuck on part
(3) and don't
> > see a clean way
> > > > apart from matching strings in
subject field? If I
> > hard-code the
> > > > public key in my verification
code, I will need to
> > update it when I
> > > > switch to a newer public key?
> > > > > Yep, that is why careful
matching against
> > various
> > > > Distinguished Name
> > > > > fields is needed.
> > > > >
> > > > > >
> > > > > > > On Sep 06,
2014, at 09:44
> > PM, Prasad Dabak
> > > > <pda...@icloud.com
<mailto:pda...@icloud.com> <mailto:pda...@icloud.com
<mailto:pda...@icloud.com> >
> > <mailto:pda...@icloud.com
<mailto:pda...@icloud.com> <mailto:pda...@icloud.com
<mailto:pda...@icloud.com> > > > 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?
> > > > > > > 2. What
does PKCS7_Verify
> > exactly do? I
> > > > looked at
> >
https://www.openssl.org/docs/crypto/PKCS7_verify.htmland 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!
> > > > >
> >