Discussion:
Verifying authenticode signature using openssl API
Prasad Dabak
2014-09-16 10:22:30 UTC
Permalink
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?
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?

Thanks.
-Prasad


Thanks Jacob for your response. Very informative indeed!
Thanks
-Prasad
Sent from my iPhone
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.
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!
Enjoy
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
______________________________________________________________________
OpenSSL Project http://www.openssl.org
Jakob Bohm
2014-09-16 17:48:55 UTC
Permalink
Post by Prasad Dabak
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).
Post by Prasad Dabak
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.
Post by Prasad Dabak
Thanks Jacob for your response. Very informative indeed!
Thanks
-Prasad
Sent from my iPhone
On 09-Sep-2014, at 10:05 pm, Jakob Bohm
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
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!
Enjoy

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

______________________________________________________________________
OpenSSL Project http://www.openssl.org
User Support Mailing List openssl-users-MCmKBN63+***@public.gmane.org
Automated List Manager majordomo-MCmKBN63+***@public.gmane.org
Prasad Dabak
2014-09-19 07:14:59 UTC
Permalink
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?

Thanks.
-Prasad
Post by Jakob Bohm
Post by Prasad Dabak
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).
Post by Prasad Dabak
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.
Post by Prasad Dabak
Thanks Jacob for your response. Very informative indeed!
Thanks
-Prasad
Sent from my iPhone
On 09-Sep-2014, at 10:05 pm, Jakob Bohm
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
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!
Enjoy
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
______________________________________________________________________
OpenSSL Project http://www.openssl.org
Jakob Bohm
2014-09-19 17:23:19 UTC
Permalink
Post by Prasad Dabak
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.
Post by Prasad Dabak
Thanks.
-Prasad
Post by Prasad Dabak
Post by Prasad Dabak
Hello,
I am currently focusing on matching various digests that we
talked
Post by Prasad Dabak
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
Post by Prasad Dabak
"messageDigest" stored in AuthenticatedAttributes. I
realized that the
Post by Prasad Dabak
sequence and length bytes need to be skipped before
computing the hash
Post by Prasad Dabak
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).
Post by Prasad Dabak
3. Computing hash of AuthenticatedAttributes and matching it
with
Post by Prasad Dabak
decrypted version of encryptedDigest. I am struggling to get
this.
Post by Prasad Dabak
Which portion of AuthenticatedAttributes should be
considered for
Post by Prasad Dabak
computing the hash? Further when I decrypt the
encryptedDigest using
Post by Prasad Dabak
the signer's public key, I get back a 256 byte value. This
doesn't
Post by Prasad Dabak
look like a SHA1 hash like in case (1) and (2). So what type
of hash
Post by Prasad Dabak
it is? Can someone elaborate OR point to documentation that
elaborates
Post by Prasad Dabak
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.
Post by Prasad Dabak
On Sep 09, 2014, at 10:18 AM, Prasad Dabak
Thanks Jacob for your response. Very informative
indeed!
Post by Prasad Dabak
Thanks
-Prasad
Sent from my iPhone
On 09-Sep-2014, at 10:05 pm, Jakob Bohm
On 09/09/2014 09:01, Prasad Dabak
Thanks Jacob for an elaborate
answer. Somehow I
Post by Prasad Dabak
never received your response to my registered email
address, hence
Post by Prasad Dabak
delay in responding.
This time I have CC-ed you in addition to
the mail list.
Post by Prasad Dabak
I have a few follow-up questions
on your response.
Post by Prasad Dabak
1. So, "encryptedDigest" has no
relation to the
Post by Prasad Dabak
stored "messageDigest"? I thought it's a encrypted
version of the
Post by Prasad Dabak
messageDigest?
As far as I recall, there is a chain of 4
digests. The first
Post by Prasad Dabak
digest
is calculated over the file and is stored
in the
Post by Prasad Dabak
spcIndirectData. The
second digest is calculated over the
spcIndirectData (the
Post by Prasad Dabak
contentInfo
of the the PKCS#7 structure) and is stored as
"messageDigest" in the
AuthenticatedAttributes of each PKCS#7
signerInfo. The third
Post by Prasad Dabak
hash
is calculated over the
AuthenticatedAttributes and is signed to
Post by Prasad Dabak
produce the "encryptedDigest" in that same
signerInfo. All 3
Post by Prasad Dabak
need to
be checked to confirm that the file hash
is actually
Post by Prasad Dabak
(indirectly)
signed by the encryptedDigest using the
public key in the
Post by Prasad Dabak
certificate
whose name is listed in the signerInfo.
2. I agree that it's better to do
cheaper checks
Post by Prasad Dabak
first e.g. I am also matching PE checksum stored in
the optional header.
Post by Prasad Dabak
Indeed, though that is a very weak
checksum (file size plus
Post by Prasad Dabak
16 bit TCP/IP
checksum of file). Also it is allowed to
be 0 to indicate no
Post by Prasad Dabak
checksum
(even if you set the checksum, it might be
cleared if an
Post by Prasad Dabak
Administrator
adds his own countersignature to all
authorized programs on his
Post by Prasad Dabak
computers, aka AppLocker).
3. spcPEImageData is probably
relevant only for
Post by Prasad Dabak
signing that uses page hashes?
I never quite figured out where they store
the page hashes.
Post by Prasad Dabak
However I
believe the constant semi-empty
spcPEImageData with the
Post by Prasad Dabak
"<<<obsolete > > >"
string is the traditional marker to
indicate that the
Post by Prasad Dabak
signature is for
a PE file, and not e.g. a document file
with the same hashed
Post by Prasad Dabak
bytestream.
4. PKCS7_verify is already
matching the
Post by Prasad Dabak
encryptedDigest, do we still need to validate it
ourselves?
Post by Prasad Dabak
If it is, I am myself guessing a bit as to
what that
Post by Prasad Dabak
function does and
does not check. But note that it probably
doesn't check the
Post by Prasad Dabak
full chain
of 3 message digests, since at least the
digest over the
Post by Prasad Dabak
file itself is
inside a blob that the PKCS#7 standard has
no opinion about.
Post by Prasad Dabak
5. So, basically are are
suggesting to look into
Post by Prasad Dabak
the subject string and see if we can find patterns
like
/C=US/O=SIGNER_NAME....? How
Post by Prasad Dabak
authoritative it is? I mean can someone else have
same COMPANY-NAME
Post by Prasad Dabak
and PATTERN-NAME in their certificate?
Actually, the subject is a data structure
(a hierarchical
Post by Prasad Dabak
list of sets
of tagged strings) and the relevant
comparison would be to
Post by Prasad Dabak
compare those
elements that don't change when getting a
new certificate
Post by Prasad Dabak
from the CA.
It is the CAs responsibility to make sure
the don't issue
Post by Prasad Dabak
certificates
to the wrong people, and if they make a
mistake they are
Post by Prasad Dabak
expected to
quickly add the bad certificate to their
published CRL,
Post by Prasad Dabak
which is why
you need to check the CRL before trusting
the certificate. An
Post by Prasad Dabak
additional check is to make sure the CA
that issued the
Post by Prasad Dabak
intermediary
certificate that issued the "COMAPNY-NAME"
certificate is
Post by Prasad Dabak
actually one
of the (few) CAs that "COMPANY-NAME" is
going to buy
Post by Prasad Dabak
certificates from.
This protects against fake certificates
issued by smaller
Post by Prasad Dabak
CAs that
you aren't going to use anyway.
In my case, I am the one who is
signing the
Post by Prasad Dabak
executable using my certificate and a "cross
certificate" issued by
Post by Prasad Dabak
Microsoft and I want to programmatically ensure
following things.
Post by Prasad Dabak
1. Code is not tampered since it
was signed
Post by Prasad Dabak
(matching messageDigest with computed hash)
Actually matching digest in
spcIndirectData with computed
Post by Prasad Dabak
hash. Plus
consistency checks to make sure the
signature is actually
Post by Prasad Dabak
for a PE file
and was not otherwise doctored. For
instance there should be
Post by Prasad Dabak
no bytes
in the file after the end of the signature
blob.
Post by Prasad Dabak
2. Verifying the digital
signature (PKCS7_Verify)
Post by Prasad Dabak
3. Confirming that the executable
is signed by my
Post by Prasad Dabak
company certificate.
I am stuck on part (3) and don't
see a clean way
Post by Prasad Dabak
apart from matching strings in subject field? If I
hard-code the
Post by Prasad Dabak
public key in my verification code, I will need to
update it when I
Post by Prasad Dabak
switch to a newer public key?
Yep, that is why careful matching against
various
Post by Prasad Dabak
Distinguished Name
fields is needed.
On Sep 06, 2014, at 09:44
PM, Prasad Dabak
Post by Prasad Dabak
Hello,
Given a signed Windows portable
executable, I want to programmatically verify two
things using
Post by Prasad Dabak
openssl APIs
1. Verify the digital signature.
2. Confirm that the
executable is signed
Post by Prasad Dabak
by a specific company using that company's public key.
It seems that part (1) can
be done by
Post by Prasad Dabak
parsing the signedData attribute in the portable
executable,
Post by Prasad Dabak
extracting the hashing algorithm and digest stored
there,
Post by Prasad Dabak
re-computing the digest of the executable using the
same hashing
Post by Prasad Dabak
algorithm and match them.
I have following questions.
1. The signData contains
messageDigest
Post by Prasad Dabak
(unencrypted) and encryptedDigest (encrypted). Is
it enough to match
Post by Prasad Dabak
messgaeDigest with the computed digest? OR we also
need to decrypt
Post by Prasad Dabak
the encryptedDigest using the company public key
and match that as well?
Post by Prasad Dabak
2. What does PKCS7_Verify
exactly do? I
Post by Prasad Dabak
looked at
https://www.openssl.org/docs/crypto/PKCS7_verify.htmland I
Post by Prasad Dabak
understand that it verifies certificate chain.
However, it's not
Post by Prasad Dabak
clear to me as to what exactly it does with respect
to signature
Post by Prasad Dabak
verification?
3. I am assuming that I
require to do both
Post by Prasad Dabak
(1) and (2) in order to verify the authenticode
signature?
Post by Prasad Dabak
4. What is the best way to
verify if the
Post by Prasad Dabak
executable is signed by specific company using that
company's public key?
Post by Prasad Dabak
Any inputs will be greatly
appreciated!
Enjoy

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

______________________________________________________________________
OpenSSL Project http://www.openssl.org
User Support Mailing List openssl-users-MCmKBN63+***@public.gmane.org
Automated List Manager majordomo-MCmKBN63+***@public.gmane.org
Prasad Dabak
2014-09-22 08:24:03 UTC
Permalink
Well, I am bit confused here.

I am decrypting the signature using RSA_public_decrypt function passing it a public key with RSA_PKCS1_PADDING option.

For primary signature, I get back a 35 byte value which is inclusive of the digestAlgorithm. It is in the v1.5 format that you mention about.
For secondary signature, I get back a 20 byte value which matches byte-to-byte with the digest (SHA1 hash of the signed attributes si->auth_attr). But it doesn't include digestAlgorithm.

I understand that primary and secondary signatures are generated by different computers belonging to different companies. However, the fact that the decrypted signature matches with the SHA1 hash of the signed attributes makes me believe, that it's probably not a different algorithm (DSS/DSA and ECDSA) issue and it doesn't look like "PSS" format issue either.

Thanks.
-Prasad
Post by Jakob Bohm
Post by Prasad Dabak
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.
Post by Prasad Dabak
Thanks.
-Prasad
Post by Prasad Dabak
Post by Prasad Dabak
Hello,
I am currently focusing on matching various digests that we
talked
Post by Prasad Dabak
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
Post by Prasad Dabak
"messageDigest" stored in AuthenticatedAttributes. I
realized that the
Post by Prasad Dabak
sequence and length bytes need to be skipped before
computing the hash
Post by Prasad Dabak
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).
Post by Prasad Dabak
3. Computing hash of AuthenticatedAttributes and matching it
with
Post by Prasad Dabak
decrypted version of encryptedDigest. I am struggling to get
this.
Post by Prasad Dabak
Which portion of AuthenticatedAttributes should be
considered for
Post by Prasad Dabak
computing the hash? Further when I decrypt the
encryptedDigest using
Post by Prasad Dabak
the signer's public key, I get back a 256 byte value. This
doesn't
Post by Prasad Dabak
look like a SHA1 hash like in case (1) and (2). So what type
of hash
Post by Prasad Dabak
it is? Can someone elaborate OR point to documentation that
elaborates
Post by Prasad Dabak
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.
Post by Prasad Dabak
On Sep 09, 2014, at 10:18 AM, Prasad Dabak
Thanks Jacob for your response. Very informative
indeed!
Post by Prasad Dabak
Thanks
-Prasad
Sent from my iPhone
On 09-Sep-2014, at 10:05 pm, Jakob Bohm
On 09/09/2014 09:01, Prasad Dabak
Thanks Jacob for an elaborate
answer. Somehow I
Post by Prasad Dabak
never received your response to my registered email
address, hence
Post by Prasad Dabak
delay in responding.
This time I have CC-ed you in addition to
the mail list.
Post by Prasad Dabak
I have a few follow-up questions
on your response.
Post by Prasad Dabak
1. So, "encryptedDigest" has no
relation to the
Post by Prasad Dabak
stored "messageDigest"? I thought it's a encrypted
version of the
Post by Prasad Dabak
messageDigest?
As far as I recall, there is a chain of 4
digests. The first
Post by Prasad Dabak
digest
is calculated over the file and is stored
in the
Post by Prasad Dabak
spcIndirectData. The
second digest is calculated over the
spcIndirectData (the
Post by Prasad Dabak
contentInfo
of the the PKCS#7 structure) and is stored as
"messageDigest" in the
AuthenticatedAttributes of each PKCS#7
signerInfo. The third
Post by Prasad Dabak
hash
is calculated over the
AuthenticatedAttributes and is signed to
Post by Prasad Dabak
produce the "encryptedDigest" in that same
signerInfo. All 3
Post by Prasad Dabak
need to
be checked to confirm that the file hash
is actually
Post by Prasad Dabak
(indirectly)
signed by the encryptedDigest using the
public key in the
Post by Prasad Dabak
certificate
whose name is listed in the signerInfo.
2. I agree that it's better to do
cheaper checks
Post by Prasad Dabak
first e.g. I am also matching PE checksum stored in
the optional header.
Post by Prasad Dabak
Indeed, though that is a very weak
checksum (file size plus
Post by Prasad Dabak
16 bit TCP/IP
checksum of file). Also it is allowed to
be 0 to indicate no
Post by Prasad Dabak
checksum
(even if you set the checksum, it might be
cleared if an
Post by Prasad Dabak
Administrator
adds his own countersignature to all
authorized programs on his
Post by Prasad Dabak
computers, aka AppLocker).
3. spcPEImageData is probably
relevant only for
Post by Prasad Dabak
signing that uses page hashes?
I never quite figured out where they store
the page hashes.
Post by Prasad Dabak
However I
believe the constant semi-empty
spcPEImageData with the
Post by Prasad Dabak
"<<<obsolete > > >"
string is the traditional marker to
indicate that the
Post by Prasad Dabak
signature is for
a PE file, and not e.g. a document file
with the same hashed
Post by Prasad Dabak
bytestream.
4. PKCS7_verify is already
matching the
Post by Prasad Dabak
encryptedDigest, do we still need to validate it
ourselves?
Post by Prasad Dabak
If it is, I am myself guessing a bit as to
what that
Post by Prasad Dabak
function does and
does not check. But note that it probably
doesn't check the
Post by Prasad Dabak
full chain
of 3 message digests, since at least the
digest over the
Post by Prasad Dabak
file itself is
inside a blob that the PKCS#7 standard has
no opinion about.
Post by Prasad Dabak
5. So, basically are are
suggesting to look into
Post by Prasad Dabak
the subject string and see if we can find patterns
like
/C=US/O=SIGNER_NAME....? How
Post by Prasad Dabak
authoritative it is? I mean can someone else have
same COMPANY-NAME
Post by Prasad Dabak
and PATTERN-NAME in their certificate?
Actually, the subject is a data structure
(a hierarchical
Post by Prasad Dabak
list of sets
of tagged strings) and the relevant
comparison would be to
Post by Prasad Dabak
compare those
elements that don't change when getting a
new certificate
Post by Prasad Dabak
from the CA.
It is the CAs responsibility to make sure
the don't issue
Post by Prasad Dabak
certificates
to the wrong people, and if they make a
mistake they are
Post by Prasad Dabak
expected to
quickly add the bad certificate to their
published CRL,
Post by Prasad Dabak
which is why
you need to check the CRL before trusting
the certificate. An
Post by Prasad Dabak
additional check is to make sure the CA
that issued the
Post by Prasad Dabak
intermediary
certificate that issued the "COMAPNY-NAME"
certificate is
Post by Prasad Dabak
actually one
of the (few) CAs that "COMPANY-NAME" is
going to buy
Post by Prasad Dabak
certificates from.
This protects against fake certificates
issued by smaller
Post by Prasad Dabak
CAs that
you aren't going to use anyway.
In my case, I am the one who is
signing the
Post by Prasad Dabak
executable using my certificate and a "cross
certificate" issued by
Post by Prasad Dabak
Microsoft and I want to programmatically ensure
following things.
Post by Prasad Dabak
1. Code is not tampered since it
was signed
Post by Prasad Dabak
(matching messageDigest with computed hash)
Actually matching digest in
spcIndirectData with computed
Post by Prasad Dabak
hash. Plus
consistency checks to make sure the
signature is actually
Post by Prasad Dabak
for a PE file
and was not otherwise doctored. For
instance there should be
Post by Prasad Dabak
no bytes
in the file after the end of the signature
blob.
Post by Prasad Dabak
2. Verifying the digital
signature (PKCS7_Verify)
Post by Prasad Dabak
3. Confirming that the executable
is signed by my
Post by Prasad Dabak
company certificate.
I am stuck on part (3) and don't
see a clean way
Post by Prasad Dabak
apart from matching strings in subject field? If I
hard-code the
Post by Prasad Dabak
public key in my verification code, I will need to
update it when I
Post by Prasad Dabak
switch to a newer public key?
Yep, that is why careful matching against
various
Post by Prasad Dabak
Distinguished Name
fields is needed.
On Sep 06, 2014, at 09:44
PM, Prasad Dabak
Post by Prasad Dabak
Hello,
Given a signed Windows portable
executable, I want to programmatically verify two
things using
Post by Prasad Dabak
openssl APIs
1. Verify the digital signature.
2. Confirm that the
executable is signed
Post by Prasad Dabak
by a specific company using that company's public key.
It seems that part (1) can
be done by
Post by Prasad Dabak
parsing the signedData attribute in the portable
executable,
Post by Prasad Dabak
extracting the hashing algorithm and digest stored
there,
Post by Prasad Dabak
re-computing the digest of the executable using the
same hashing
Post by Prasad Dabak
algorithm and match them.
I have following questions.
1. The signData contains
messageDigest
Post by Prasad Dabak
(unencrypted) and encryptedDigest (encrypted). Is
it enough to match
Post by Prasad Dabak
messgaeDigest with the computed digest? OR we also
need to decrypt
Post by Prasad Dabak
the encryptedDigest using the company public key
and match that as well?
Post by Prasad Dabak
2. What does PKCS7_Verify
exactly do? I
Post by Prasad Dabak
looked at
https://www.openssl.org/docs/crypto/PKCS7_verify.htmland I
Post by Prasad Dabak
understand that it verifies certificate chain.
However, it's not
Post by Prasad Dabak
clear to me as to what exactly it does with respect
to signature
Post by Prasad Dabak
verification?
3. I am assuming that I
require to do both
Post by Prasad Dabak
(1) and (2) in order to verify the authenticode
signature?
Post by Prasad Dabak
4. What is the best way to
verify if the
Post by Prasad Dabak
executable is signed by specific company using that
company's public key?
Post by Prasad Dabak
Any inputs will be greatly
appreciated!
Enjoy
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
______________________________________________________________________
OpenSSL Project http://www.openssl.org
Jakob Bohm
2014-09-22 16:12:14 UTC
Permalink
Ok, look in the SignerInfo structure of the secondary signature.
There is a separate field (digestEncryptionAlgorithm) indicating
the OID of the signature algorithm. Look at this and see if it is
different from the value in the outer signature, and look up the
value online to see what it means.
Post by Prasad Dabak
Well, I am bit confused here.
I am decrypting the signature using RSA_public_decrypt function
passing it a public key with RSA_PKCS1_PADDING option.
For primary signature, I get back a 35 byte value which is inclusive
of the digestAlgorithm. It is in the v1.5format that you mention about.
For secondary signature, I get back a 20 byte value which matches
byte-to-byte with the digest (SHA1 hash of the signed attributes
si->auth_attr). But it doesn't include digestAlgorithm.
I understand that primary and secondary signatures are generated by
different computers belonging to different companies. However, the
fact that the decrypted signature matches with the SHA1 hash of the
signed attributes makes me believe, that it's probably not a different
algorithm (DSS/DSA and ECDSA) issue and it doesn't look like "PSS"
format issue either.
Thanks.
-Prasad
Post by Prasad Dabak
Post by Prasad Dabak
The RFC links helped.
I am able to do decrypt the encrypted digest and match it
with the
Post by Prasad Dabak
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.
Post by Prasad Dabak
I am also able to validate counterSignatures in similar fashion.
Now I am trying this with various Authenticode executables
and one
Post by Prasad Dabak
small issue that I found is: For some authenticode
executables, the
Post by Prasad Dabak
counterSignature encryption only considers the bytes of the
Digest
Post by Prasad Dabak
OCTET_STRING i.e. it does not consider digestAlgorithm
field. Because
Post by Prasad Dabak
of this, the decrypted counterSignature is 20 bytes long
(size of sha1
Post by Prasad Dabak
hash) instead of 35 bytes mentioned earlier. It does match
with bytes
Post by Prasad Dabak
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
Post by Prasad Dabak
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.
Post by Prasad Dabak
Thanks.
-Prasad
On Sep 16, 2014, at 10:51 AM, Jakob Bohm
Post by Prasad Dabak
Post by Prasad Dabak
Hello,
I am currently focusing on matching
various digests that we
Post by Prasad Dabak
Post by Prasad Dabak
talked
Post by Prasad Dabak
about earlier in the thread.
1. Computing the hash of the executable
(excluding the areas as
Post by Prasad Dabak
Post by Prasad Dabak
Post by Prasad Dabak
defined by MS) and matching it with the
value stored in
Post by Prasad Dabak
Post by Prasad Dabak
Post by Prasad Dabak
spcIndirectData. This is straight forward
and figured out.
Post by Prasad Dabak
Post by Prasad Dabak
Post by Prasad Dabak
2. Computing the hash of spcIndirectData
and matching it
Post by Prasad Dabak
Post by Prasad Dabak
with with
Post by Prasad Dabak
"messageDigest" stored in
AuthenticatedAttributes. I
Post by Prasad Dabak
Post by Prasad Dabak
realized that the
Post by Prasad Dabak
sequence and length bytes need to be
skipped before
Post by Prasad Dabak
Post by Prasad Dabak
computing the hash
Post by Prasad Dabak
of the spcIndirectData? Is this documented
anywhere?
Post by Prasad Dabak
Post by Prasad Dabak
This is specified in the PKCS#7 standard (RFC2315),
in particular,
Post by Prasad Dabak
Post by Prasad Dabak
PKCS#7 specifies that when there is a non-empty
contentInfo field
Post by Prasad Dabak
Post by Prasad Dabak
in the PKCS#7 structure, which part of that should
be hashed. In
Post by Prasad Dabak
Post by Prasad Dabak
this case that contentInfo is a Microsoft-defiend
spcIndirectData,
Post by Prasad Dabak
Post by Prasad Dabak
but the calculation is unaffected. This should also
be built in
Post by Prasad Dabak
Post by Prasad Dabak
to the PKCS7 functions (I hope).
Post by Prasad Dabak
3. Computing hash of
AuthenticatedAttributes and matching it
Post by Prasad Dabak
Post by Prasad Dabak
with
Post by Prasad Dabak
decrypted version of encryptedDigest. I am
struggling to get
Post by Prasad Dabak
Post by Prasad Dabak
this.
Post by Prasad Dabak
Which portion of AuthenticatedAttributes
should be
Post by Prasad Dabak
Post by Prasad Dabak
considered for
Post by Prasad Dabak
computing the hash? Further when I decrypt
the
Post by Prasad Dabak
Post by Prasad Dabak
encryptedDigest using
Post by Prasad Dabak
the signer's public key, I get back a 256
byte value. This
Post by Prasad Dabak
Post by Prasad Dabak
doesn't
Post by Prasad Dabak
look like a SHA1 hash like in case (1) and
(2). So what type
Post by Prasad Dabak
Post by Prasad Dabak
of hash
Post by Prasad Dabak
it is? Can someone elaborate OR point to
documentation that
Post by Prasad Dabak
Post by Prasad Dabak
elaborates
Post by Prasad Dabak
on this?
This is specified in the PKCS#7 standard (RFC2315).
This should
Post by Prasad Dabak
Post by Prasad Dabak
also be built in to the PKCS7 functions (I hope).
By the way, the rules for checking the timestamp
countersignature
Post by Prasad Dabak
Post by Prasad Dabak
(but not its effect on checking the outer
signature) is specified
Post by Prasad Dabak
Post by Prasad Dabak
in RFC2985 section 5.3.6. The rules for parsing the
SigningTime
Post by Prasad Dabak
Post by Prasad Dabak
attribute used inside timestamp contersignatures
(and elsewhere
Post by Prasad Dabak
Post by Prasad Dabak
with less trust) are in RFC2985 section 5.3.3.
Post by Prasad Dabak
On Sep 09, 2014, at 10:18 AM, Prasad Dabak
Thanks Jacob for your response.
Very informative
Post by Prasad Dabak
Post by Prasad Dabak
indeed!
Post by Prasad Dabak
Thanks
-Prasad
Sent from my iPhone
On 09-Sep-2014, at 10:05 pm,
Jakob Bohm
Post by Prasad Dabak
Post by Prasad Dabak
Post by Prasad Dabak
On 09/09/2014
09:01, Prasad Dabak
Post by Prasad Dabak
Post by Prasad Dabak
Post by Prasad Dabak
Thanks Jacob for an
elaborate
Post by Prasad Dabak
Post by Prasad Dabak
answer. Somehow I
Post by Prasad Dabak
never received your response to
my registered email
Post by Prasad Dabak
Post by Prasad Dabak
address, hence
Post by Prasad Dabak
delay in responding.
This time I have CC-ed you
in addition to
Post by Prasad Dabak
Post by Prasad Dabak
the mail list.
Post by Prasad Dabak
I have a few
follow-up questions
Post by Prasad Dabak
Post by Prasad Dabak
on your response.
Post by Prasad Dabak
1. So,
"encryptedDigest" has no
Post by Prasad Dabak
Post by Prasad Dabak
relation to the
Post by Prasad Dabak
stored "messageDigest"? I thought
it's a encrypted
Post by Prasad Dabak
Post by Prasad Dabak
version of the
Post by Prasad Dabak
messageDigest?
As far as I recall, there is
a chain of 4
Post by Prasad Dabak
Post by Prasad Dabak
digests. The first
Post by Prasad Dabak
digest
is calculated over the file
and is stored
Post by Prasad Dabak
Post by Prasad Dabak
in the
Post by Prasad Dabak
spcIndirectData. The
second digest is calculated
over the
Post by Prasad Dabak
Post by Prasad Dabak
spcIndirectData (the
Post by Prasad Dabak
contentInfo
of the the PKCS#7 structure)
and is stored as
Post by Prasad Dabak
Post by Prasad Dabak
Post by Prasad Dabak
"messageDigest" in the
AuthenticatedAttributes of
each PKCS#7
Post by Prasad Dabak
Post by Prasad Dabak
signerInfo. The third
Post by Prasad Dabak
hash
is calculated over the
AuthenticatedAttributes and is signed to
Post by Prasad Dabak
produce the
"encryptedDigest" in that same
Post by Prasad Dabak
Post by Prasad Dabak
signerInfo. All 3
Post by Prasad Dabak
need to
be checked to confirm that
the file hash
Post by Prasad Dabak
Post by Prasad Dabak
is actually
Post by Prasad Dabak
(indirectly)
signed by the
encryptedDigest using the
Post by Prasad Dabak
Post by Prasad Dabak
public key in the
Post by Prasad Dabak
certificate
whose name is listed in the
signerInfo.
Post by Prasad Dabak
Post by Prasad Dabak
Post by Prasad Dabak
2. I agree that
it's better to do
Post by Prasad Dabak
Post by Prasad Dabak
cheaper checks
Post by Prasad Dabak
first e.g. I am also matching PE
checksum stored in
Post by Prasad Dabak
Post by Prasad Dabak
the optional header.
Post by Prasad Dabak
Indeed, though that is a
very weak
Post by Prasad Dabak
Post by Prasad Dabak
checksum (file size plus
Post by Prasad Dabak
16 bit TCP/IP
checksum of file). Also it
is allowed to
Post by Prasad Dabak
Post by Prasad Dabak
be 0 to indicate no
Post by Prasad Dabak
checksum
(even if you set the
checksum, it might be
Post by Prasad Dabak
Post by Prasad Dabak
cleared if an
Post by Prasad Dabak
Administrator
adds his own
countersignature to all
Post by Prasad Dabak
Post by Prasad Dabak
authorized programs on his
Post by Prasad Dabak
computers, aka AppLocker).
3. spcPEImageData
is probably
Post by Prasad Dabak
Post by Prasad Dabak
relevant only for
Post by Prasad Dabak
signing that uses page hashes?
I never quite figured out
where they store
Post by Prasad Dabak
Post by Prasad Dabak
the page hashes.
Post by Prasad Dabak
However I
believe the constant semi-empty
spcPEImageData with the
Post by Prasad Dabak
"<<<obsolete > > >"
string is the traditional
marker to
Post by Prasad Dabak
Post by Prasad Dabak
indicate that the
Post by Prasad Dabak
signature is for
a PE file, and not e.g. a
document file
Post by Prasad Dabak
Post by Prasad Dabak
with the same hashed
Post by Prasad Dabak
bytestream.
4. PKCS7_verify is
already
Post by Prasad Dabak
Post by Prasad Dabak
matching the
Post by Prasad Dabak
encryptedDigest, do we still need
to validate it
Post by Prasad Dabak
Post by Prasad Dabak
ourselves?
Post by Prasad Dabak
If it is, I am myself
guessing a bit as to
Post by Prasad Dabak
Post by Prasad Dabak
what that
Post by Prasad Dabak
function does and
does not check. But note
that it probably
Post by Prasad Dabak
Post by Prasad Dabak
doesn't check the
Post by Prasad Dabak
full chain
of 3 message digests, since
at least the
Post by Prasad Dabak
Post by Prasad Dabak
digest over the
Post by Prasad Dabak
file itself is
inside a blob that the
PKCS#7 standard has
Post by Prasad Dabak
Post by Prasad Dabak
no opinion about.
Post by Prasad Dabak
5. So, basically
are are
Post by Prasad Dabak
Post by Prasad Dabak
suggesting to look into
Post by Prasad Dabak
the subject string and see if we
can find patterns
Post by Prasad Dabak
Post by Prasad Dabak
like
/C=US/O=SIGNER_NAME....? How
Post by Prasad Dabak
authoritative it is? I mean can
someone else have
Post by Prasad Dabak
Post by Prasad Dabak
same COMPANY-NAME
Post by Prasad Dabak
and PATTERN-NAME in their
certificate?
Post by Prasad Dabak
Post by Prasad Dabak
Post by Prasad Dabak
Actually, the subject is a
data structure
Post by Prasad Dabak
Post by Prasad Dabak
(a hierarchical
Post by Prasad Dabak
list of sets
of tagged strings) and the
relevant
Post by Prasad Dabak
Post by Prasad Dabak
comparison would be to
Post by Prasad Dabak
compare those
elements that don't change
when getting a
Post by Prasad Dabak
Post by Prasad Dabak
new certificate
Post by Prasad Dabak
from the CA.
It is the CAs responsibility
to make sure
Post by Prasad Dabak
Post by Prasad Dabak
the don't issue
Post by Prasad Dabak
certificates
to the wrong people, and if
they make a
Post by Prasad Dabak
Post by Prasad Dabak
mistake they are
Post by Prasad Dabak
expected to
quickly add the bad
certificate to their
Post by Prasad Dabak
Post by Prasad Dabak
published CRL,
Post by Prasad Dabak
which is why
you need to check the CRL
before trusting
Post by Prasad Dabak
Post by Prasad Dabak
the certificate. An
Post by Prasad Dabak
additional check is to make
sure the CA
Post by Prasad Dabak
Post by Prasad Dabak
that issued the
Post by Prasad Dabak
intermediary
certificate that issued the
"COMAPNY-NAME"
Post by Prasad Dabak
Post by Prasad Dabak
certificate is
Post by Prasad Dabak
actually one
of the (few) CAs that
"COMPANY-NAME" is
Post by Prasad Dabak
Post by Prasad Dabak
going to buy
Post by Prasad Dabak
certificates from.
This protects against fake
certificates
Post by Prasad Dabak
Post by Prasad Dabak
issued by smaller
Post by Prasad Dabak
CAs that
you aren't going to use anyway.
In my case, I am
the one who is
Post by Prasad Dabak
Post by Prasad Dabak
signing the
Post by Prasad Dabak
executable using my certificate
and a "cross
Post by Prasad Dabak
Post by Prasad Dabak
certificate" issued by
Post by Prasad Dabak
Microsoft and I want to
programmatically ensure
Post by Prasad Dabak
Post by Prasad Dabak
following things.
Post by Prasad Dabak
1. Code is not
tampered since it
Post by Prasad Dabak
Post by Prasad Dabak
was signed
Post by Prasad Dabak
(matching messageDigest with
computed hash)
Post by Prasad Dabak
Post by Prasad Dabak
Post by Prasad Dabak
Actually matching digest in
spcIndirectData with computed
Post by Prasad Dabak
hash. Plus
consistency checks to make
sure the
Post by Prasad Dabak
Post by Prasad Dabak
signature is actually
Post by Prasad Dabak
for a PE file
and was not otherwise
doctored. For
Post by Prasad Dabak
Post by Prasad Dabak
instance there should be
Post by Prasad Dabak
no bytes
in the file after the end of
the signature
Post by Prasad Dabak
Post by Prasad Dabak
blob.
Post by Prasad Dabak
2. Verifying the
digital
Post by Prasad Dabak
Post by Prasad Dabak
signature (PKCS7_Verify)
Post by Prasad Dabak
3. Confirming that
the executable
Post by Prasad Dabak
Post by Prasad Dabak
is signed by my
Post by Prasad Dabak
company certificate.
I am stuck on part
(3) and don't
Post by Prasad Dabak
Post by Prasad Dabak
see a clean way
Post by Prasad Dabak
apart from matching strings in
subject field? If I
Post by Prasad Dabak
Post by Prasad Dabak
hard-code the
Post by Prasad Dabak
public key in my verification
code, I will need to
Post by Prasad Dabak
Post by Prasad Dabak
update it when I
Post by Prasad Dabak
switch to a newer public key?
Yep, that is why careful
matching against
Post by Prasad Dabak
Post by Prasad Dabak
various
Post by Prasad Dabak
Distinguished Name
fields is needed.
On Sep 06,
2014, at 09:44
Post by Prasad Dabak
Post by Prasad Dabak
PM, Prasad Dabak
Post by Prasad Dabak
Hello,
Given a
signed Windows portable
Post by Prasad Dabak
Post by Prasad Dabak
Post by Prasad Dabak
executable, I want to
programmatically verify two
Post by Prasad Dabak
Post by Prasad Dabak
things using
Post by Prasad Dabak
openssl APIs
1. Verify
the digital signature.
Post by Prasad Dabak
Post by Prasad Dabak
Post by Prasad Dabak
2. Confirm
that the
Post by Prasad Dabak
Post by Prasad Dabak
executable is signed
Post by Prasad Dabak
by a specific company using that
company's public key.
Post by Prasad Dabak
Post by Prasad Dabak
Post by Prasad Dabak
It seems
that part (1) can
Post by Prasad Dabak
Post by Prasad Dabak
be done by
Post by Prasad Dabak
parsing the signedData attribute
in the portable
Post by Prasad Dabak
Post by Prasad Dabak
executable,
Post by Prasad Dabak
extracting the hashing algorithm
and digest stored
Post by Prasad Dabak
Post by Prasad Dabak
there,
Post by Prasad Dabak
re-computing the digest of the
executable using the
Post by Prasad Dabak
Post by Prasad Dabak
same hashing
Post by Prasad Dabak
algorithm and match them.
I have
following questions.
Post by Prasad Dabak
Post by Prasad Dabak
Post by Prasad Dabak
1. The
signData contains
Post by Prasad Dabak
Post by Prasad Dabak
messageDigest
Post by Prasad Dabak
(unencrypted) and encryptedDigest
(encrypted). Is
Post by Prasad Dabak
Post by Prasad Dabak
it enough to match
Post by Prasad Dabak
messgaeDigest with the computed
digest? OR we also
Post by Prasad Dabak
Post by Prasad Dabak
need to decrypt
Post by Prasad Dabak
the encryptedDigest using the
company public key
Post by Prasad Dabak
Post by Prasad Dabak
and match that as well?
Post by Prasad Dabak
2. What
does PKCS7_Verify
Post by Prasad Dabak
Post by Prasad Dabak
exactly do? I
Post by Prasad Dabak
looked at
https://www.openssl.org/docs/crypto/PKCS7_verify.htmland I
Post by Prasad Dabak
Post by Prasad Dabak
Post by Prasad Dabak
understand that it verifies
certificate chain.
Post by Prasad Dabak
Post by Prasad Dabak
However, it's not
Post by Prasad Dabak
clear to me as to what exactly it
does with respect
Post by Prasad Dabak
Post by Prasad Dabak
to signature
Post by Prasad Dabak
verification?
3. I am
assuming that I
Post by Prasad Dabak
Post by Prasad Dabak
require to do both
Post by Prasad Dabak
(1) and (2) in order to verify
the authenticode
Post by Prasad Dabak
Post by Prasad Dabak
signature?
Post by Prasad Dabak
4. What is
the best way to
Post by Prasad Dabak
Post by Prasad Dabak
verify if the
Post by Prasad Dabak
executable is signed by specific
company using that
Post by Prasad Dabak
Post by Prasad Dabak
company's public key?
Post by Prasad Dabak
Any inputs
will be greatly
Post by Prasad Dabak
Post by Prasad Dabak
appreciated!
Enjoy

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

______________________________________________________________________
OpenSSL Project http://www.openssl.org
User Support Mailing List openssl-users-MCmKBN63+***@public.gmane.org
Automated List Manager majordomo-MCmKBN63+***@public.gmane.org
Prasad Dabak
2014-09-23 12:27:23 UTC
Permalink
For the primary signature it is "rsaEncryption" (OID 1.2.840.113549.1.1.1) and for the counter signature it is "RSA-SHA1" (OID 1.2.840.113549.1.1.5).

Thanks.
-Prasad
Post by Jakob Bohm
Ok, look in the SignerInfo structure of the secondary signature.
There is a separate field (digestEncryptionAlgorithm) indicating
the OID of the signature algorithm. Look at this and see if it is
different from the value in the outer signature, and look up the
value online to see what it means.
Post by Prasad Dabak
Well, I am bit confused here.
I am decrypting the signature using RSA_public_decrypt function
passing it a public key with RSA_PKCS1_PADDING option.
For primary signature, I get back a 35 byte value which is inclusive
of the digestAlgorithm. It is in the v1.5format that you mention about.
For secondary signature, I get back a 20 byte value which matches
byte-to-byte with the digest (SHA1 hash of the signed attributes
si- >auth_attr). But it doesn't include digestAlgorithm.
I understand that primary and secondary signatures are generated by
different computers belonging to different companies. However, the
fact that the decrypted signature matches with the SHA1 hash of the
signed attributes makes me believe, that it's probably not a different
algorithm (DSS/DSA and ECDSA) issue and it doesn't look like "PSS"
format issue either.
Thanks.
-Prasad
Post by Prasad Dabak
Post by Prasad Dabak
The RFC links helped.
I am able to do decrypt the encrypted digest and match it
with the
Post by Prasad Dabak
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.
Post by Prasad Dabak
I am also able to validate counterSignatures in similar fashion.
Now I am trying this with various Authenticode executables
and one
Post by Prasad Dabak
small issue that I found is: For some authenticode
executables, the
Post by Prasad Dabak
counterSignature encryption only considers the bytes of the
Digest
Post by Prasad Dabak
OCTET_STRING i.e. it does not consider digestAlgorithm
field. Because
Post by Prasad Dabak
of this, the decrypted counterSignature is 20 bytes long
(size of sha1
Post by Prasad Dabak
hash) instead of 35 bytes mentioned earlier. It does match
with bytes
Post by Prasad Dabak
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
Post by Prasad Dabak
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.
Post by Prasad Dabak
Thanks.
-Prasad
On Sep 16, 2014, at 10:51 AM, Jakob Bohm
Post by Prasad Dabak
Post by Prasad Dabak
Hello,
I am currently focusing on matching
various digests that we
Post by Prasad Dabak
Post by Prasad Dabak
talked
Post by Prasad Dabak
about earlier in the thread.
1. Computing the hash of the executable
(excluding the areas as
Post by Prasad Dabak
Post by Prasad Dabak
Post by Prasad Dabak
defined by MS) and matching it with the
value stored in
Post by Prasad Dabak
Post by Prasad Dabak
Post by Prasad Dabak
spcIndirectData. This is straight forward
and figured out.
Post by Prasad Dabak
Post by Prasad Dabak
Post by Prasad Dabak
2. Computing the hash of spcIndirectData
and matching it
Post by Prasad Dabak
Post by Prasad Dabak
with with
Post by Prasad Dabak
"messageDigest" stored in
AuthenticatedAttributes. I
Post by Prasad Dabak
Post by Prasad Dabak
realized that the
Post by Prasad Dabak
sequence and length bytes need to be
skipped before
Post by Prasad Dabak
Post by Prasad Dabak
computing the hash
Post by Prasad Dabak
of the spcIndirectData? Is this documented
anywhere?
Post by Prasad Dabak
Post by Prasad Dabak
This is specified in the PKCS#7 standard (RFC2315),
in particular,
Post by Prasad Dabak
Post by Prasad Dabak
PKCS#7 specifies that when there is a non-empty
contentInfo field
Post by Prasad Dabak
Post by Prasad Dabak
in the PKCS#7 structure, which part of that should
be hashed. In
Post by Prasad Dabak
Post by Prasad Dabak
this case that contentInfo is a Microsoft-defiend
spcIndirectData,
Post by Prasad Dabak
Post by Prasad Dabak
but the calculation is unaffected. This should also
be built in
Post by Prasad Dabak
Post by Prasad Dabak
to the PKCS7 functions (I hope).
Post by Prasad Dabak
3. Computing hash of
AuthenticatedAttributes and matching it
Post by Prasad Dabak
Post by Prasad Dabak
with
Post by Prasad Dabak
decrypted version of encryptedDigest. I am
struggling to get
Post by Prasad Dabak
Post by Prasad Dabak
this.
Post by Prasad Dabak
Which portion of AuthenticatedAttributes
should be
Post by Prasad Dabak
Post by Prasad Dabak
considered for
Post by Prasad Dabak
computing the hash? Further when I decrypt
the
Post by Prasad Dabak
Post by Prasad Dabak
encryptedDigest using
Post by Prasad Dabak
the signer's public key, I get back a 256
byte value. This
Post by Prasad Dabak
Post by Prasad Dabak
doesn't
Post by Prasad Dabak
look like a SHA1 hash like in case (1) and
(2). So what type
Post by Prasad Dabak
Post by Prasad Dabak
of hash
Post by Prasad Dabak
it is? Can someone elaborate OR point to
documentation that
Post by Prasad Dabak
Post by Prasad Dabak
elaborates
Post by Prasad Dabak
on this?
This is specified in the PKCS#7 standard (RFC2315).
This should
Post by Prasad Dabak
Post by Prasad Dabak
also be built in to the PKCS7 functions (I hope).
By the way, the rules for checking the timestamp
countersignature
Post by Prasad Dabak
Post by Prasad Dabak
(but not its effect on checking the outer
signature) is specified
Post by Prasad Dabak
Post by Prasad Dabak
in RFC2985 section 5.3.6. The rules for parsing the
SigningTime
Post by Prasad Dabak
Post by Prasad Dabak
attribute used inside timestamp contersignatures
(and elsewhere
Post by Prasad Dabak
Post by Prasad Dabak
with less trust) are in RFC2985 section 5.3.3.
Post by Prasad Dabak
On Sep 09, 2014, at 10:18 AM, Prasad Dabak
Thanks Jacob for your response.
Very informative
Post by Prasad Dabak
Post by Prasad Dabak
indeed!
Post by Prasad Dabak
Thanks
-Prasad
Sent from my iPhone
On 09-Sep-2014, at 10:05 pm,
Jakob Bohm
Post by Prasad Dabak
Post by Prasad Dabak
Post by Prasad Dabak
On 09/09/2014
09:01, Prasad Dabak
Post by Prasad Dabak
Post by Prasad Dabak
Post by Prasad Dabak
Thanks Jacob for an
elaborate
Post by Prasad Dabak
Post by Prasad Dabak
answer. Somehow I
Post by Prasad Dabak
never received your response to
my registered email
Post by Prasad Dabak
Post by Prasad Dabak
address, hence
Post by Prasad Dabak
delay in responding.
This time I have CC-ed you
in addition to
Post by Prasad Dabak
Post by Prasad Dabak
the mail list.
Post by Prasad Dabak
I have a few
follow-up questions
Post by Prasad Dabak
Post by Prasad Dabak
on your response.
Post by Prasad Dabak
1. So,
"encryptedDigest" has no
Post by Prasad Dabak
Post by Prasad Dabak
relation to the
Post by Prasad Dabak
stored "messageDigest"? I thought
it's a encrypted
Post by Prasad Dabak
Post by Prasad Dabak
version of the
Post by Prasad Dabak
messageDigest?
As far as I recall, there is
a chain of 4
Post by Prasad Dabak
Post by Prasad Dabak
digests. The first
Post by Prasad Dabak
digest
is calculated over the file
and is stored
Post by Prasad Dabak
Post by Prasad Dabak
in the
Post by Prasad Dabak
spcIndirectData. The
second digest is calculated
over the
Post by Prasad Dabak
Post by Prasad Dabak
spcIndirectData (the
Post by Prasad Dabak
contentInfo
of the the PKCS#7 structure)
and is stored as
Post by Prasad Dabak
Post by Prasad Dabak
Post by Prasad Dabak
"messageDigest" in the
AuthenticatedAttributes of
each PKCS#7
Post by Prasad Dabak
Post by Prasad Dabak
signerInfo. The third
Post by Prasad Dabak
hash
is calculated over the
AuthenticatedAttributes and is signed to
Post by Prasad Dabak
produce the
"encryptedDigest" in that same
Post by Prasad Dabak
Post by Prasad Dabak
signerInfo. All 3
Post by Prasad Dabak
need to
be checked to confirm that
the file hash
Post by Prasad Dabak
Post by Prasad Dabak
is actually
Post by Prasad Dabak
(indirectly)
signed by the
encryptedDigest using the
Post by Prasad Dabak
Post by Prasad Dabak
public key in the
Post by Prasad Dabak
certificate
whose name is listed in the
signerInfo.
Post by Prasad Dabak
Post by Prasad Dabak
Post by Prasad Dabak
2. I agree that
it's better to do
Post by Prasad Dabak
Post by Prasad Dabak
cheaper checks
Post by Prasad Dabak
first e.g. I am also matching PE
checksum stored in
Post by Prasad Dabak
Post by Prasad Dabak
the optional header.
Post by Prasad Dabak
Indeed, though that is a
very weak
Post by Prasad Dabak
Post by Prasad Dabak
checksum (file size plus
Post by Prasad Dabak
16 bit TCP/IP
checksum of file). Also it
is allowed to
Post by Prasad Dabak
Post by Prasad Dabak
be 0 to indicate no
Post by Prasad Dabak
checksum
(even if you set the
checksum, it might be
Post by Prasad Dabak
Post by Prasad Dabak
cleared if an
Post by Prasad Dabak
Administrator
adds his own
countersignature to all
Post by Prasad Dabak
Post by Prasad Dabak
authorized programs on his
Post by Prasad Dabak
computers, aka AppLocker).
3. spcPEImageData
is probably
Post by Prasad Dabak
Post by Prasad Dabak
relevant only for
Post by Prasad Dabak
signing that uses page hashes?
I never quite figured out
where they store
Post by Prasad Dabak
Post by Prasad Dabak
the page hashes.
Post by Prasad Dabak
However I
believe the constant semi-empty
spcPEImageData with the
Post by Prasad Dabak
"<<<obsolete > > >"
string is the traditional
marker to
Post by Prasad Dabak
Post by Prasad Dabak
indicate that the
Post by Prasad Dabak
signature is for
a PE file, and not e.g. a
document file
Post by Prasad Dabak
Post by Prasad Dabak
with the same hashed
Post by Prasad Dabak
bytestream.
4. PKCS7_verify is
already
Post by Prasad Dabak
Post by Prasad Dabak
matching the
Post by Prasad Dabak
encryptedDigest, do we still need
to validate it
Post by Prasad Dabak
Post by Prasad Dabak
ourselves?
Post by Prasad Dabak
If it is, I am myself
guessing a bit as to
Post by Prasad Dabak
Post by Prasad Dabak
what that
Post by Prasad Dabak
function does and
does not check. But note
that it probably
Post by Prasad Dabak
Post by Prasad Dabak
doesn't check the
Post by Prasad Dabak
full chain
of 3 message digests, since
at least the
Post by Prasad Dabak
Post by Prasad Dabak
digest over the
Post by Prasad Dabak
file itself is
inside a blob that the
PKCS#7 standard has
Post by Prasad Dabak
Post by Prasad Dabak
no opinion about.
Post by Prasad Dabak
5. So, basically
are are
Post by Prasad Dabak
Post by Prasad Dabak
suggesting to look into
Post by Prasad Dabak
the subject string and see if we
can find patterns
Post by Prasad Dabak
Post by Prasad Dabak
like
/C=US/O=SIGNER_NAME....? How
Post by Prasad Dabak
authoritative it is? I mean can
someone else have
Post by Prasad Dabak
Post by Prasad Dabak
same COMPANY-NAME
Post by Prasad Dabak
and PATTERN-NAME in their
certificate?
Post by Prasad Dabak
Post by Prasad Dabak
Post by Prasad Dabak
Actually, the subject is a
data structure
Post by Prasad Dabak
Post by Prasad Dabak
(a hierarchical
Post by Prasad Dabak
list of sets
of tagged strings) and the
relevant
Post by Prasad Dabak
Post by Prasad Dabak
comparison would be to
Post by Prasad Dabak
compare those
elements that don't change
when getting a
Post by Prasad Dabak
Post by Prasad Dabak
new certificate
Post by Prasad Dabak
from the CA.
It is the CAs responsibility
to make sure
Post by Prasad Dabak
Post by Prasad Dabak
the don't issue
Post by Prasad Dabak
certificates
to the wrong people, and if
they make a
Post by Prasad Dabak
Post by Prasad Dabak
mistake they are
Post by Prasad Dabak
expected to
quickly add the bad
certificate to their
Post by Prasad Dabak
Post by Prasad Dabak
published CRL,
Post by Prasad Dabak
which is why
you need to check the CRL
before trusting
Post by Prasad Dabak
Post by Prasad Dabak
the certificate. An
Post by Prasad Dabak
additional check is to make
sure the CA
Post by Prasad Dabak
Post by Prasad Dabak
that issued the
Post by Prasad Dabak
intermediary
certificate that issued the
"COMAPNY-NAME"
Post by Prasad Dabak
Post by Prasad Dabak
certificate is
Post by Prasad Dabak
actually one
of the (few) CAs that
"COMPANY-NAME" is
Post by Prasad Dabak
Post by Prasad Dabak
going to buy
Post by Prasad Dabak
certificates from.
This protects against fake
certificates
Post by Prasad Dabak
Post by Prasad Dabak
issued by smaller
Post by Prasad Dabak
CAs that
you aren't going to use anyway.
In my case, I am
the one who is
Post by Prasad Dabak
Post by Prasad Dabak
signing the
Post by Prasad Dabak
executable using my certificate
and a "cross
Post by Prasad Dabak
Post by Prasad Dabak
certificate" issued by
Post by Prasad Dabak
Microsoft and I want to
programmatically ensure
Post by Prasad Dabak
Post by Prasad Dabak
following things.
Post by Prasad Dabak
1. Code is not
tampered since it
Post by Prasad Dabak
Post by Prasad Dabak
was signed
Post by Prasad Dabak
(matching messageDigest with
computed hash)
Post by Prasad Dabak
Post by Prasad Dabak
Post by Prasad Dabak
Actually matching digest in
spcIndirectData with computed
Post by Prasad Dabak
hash. Plus
consistency checks to make
sure the
Post by Prasad Dabak
Post by Prasad Dabak
signature is actually
Post by Prasad Dabak
for a PE file
and was not otherwise
doctored. For
Post by Prasad Dabak
Post by Prasad Dabak
instance there should be
Post by Prasad Dabak
no bytes
in the file after the end of
the signature
Post by Prasad Dabak
Post by Prasad Dabak
blob.
Post by Prasad Dabak
2. Verifying the
digital
Post by Prasad Dabak
Post by Prasad Dabak
signature (PKCS7_Verify)
Post by Prasad Dabak
3. Confirming that
the executable
Post by Prasad Dabak
Post by Prasad Dabak
is signed by my
Post by Prasad Dabak
company certificate.
I am stuck on part
(3) and don't
Post by Prasad Dabak
Post by Prasad Dabak
see a clean way
Post by Prasad Dabak
apart from matching strings in
subject field? If I
Post by Prasad Dabak
Post by Prasad Dabak
hard-code the
Post by Prasad Dabak
public key in my verification
code, I will need to
Post by Prasad Dabak
Post by Prasad Dabak
update it when I
Post by Prasad Dabak
switch to a newer public key?
Yep, that is why careful
matching against
Post by Prasad Dabak
Post by Prasad Dabak
various
Post by Prasad Dabak
Distinguished Name
fields is needed.
On Sep 06,
2014, at 09:44
Post by Prasad Dabak
Post by Prasad Dabak
PM, Prasad Dabak
Post by Prasad Dabak
Hello,
Given a
signed Windows portable
Post by Prasad Dabak
Post by Prasad Dabak
Post by Prasad Dabak
executable, I want to
programmatically verify two
Post by Prasad Dabak
Post by Prasad Dabak
things using
Post by Prasad Dabak
openssl APIs
1. Verify
the digital signature.
Post by Prasad Dabak
Post by Prasad Dabak
Post by Prasad Dabak
2. Confirm
that the
Post by Prasad Dabak
Post by Prasad Dabak
executable is signed
Post by Prasad Dabak
by a specific company using that
company's public key.
Post by Prasad Dabak
Post by Prasad Dabak
Post by Prasad Dabak
It seems
that part (1) can
Post by Prasad Dabak
Post by Prasad Dabak
be done by
Post by Prasad Dabak
parsing the signedData attribute
in the portable
Post by Prasad Dabak
Post by Prasad Dabak
executable,
Post by Prasad Dabak
extracting the hashing algorithm
and digest stored
Post by Prasad Dabak
Post by Prasad Dabak
there,
Post by Prasad Dabak
re-computing the digest of the
executable using the
Post by Prasad Dabak
Post by Prasad Dabak
same hashing
Post by Prasad Dabak
algorithm and match them.
I have
following questions.
Post by Prasad Dabak
Post by Prasad Dabak
Post by Prasad Dabak
1. The
signData contains
Post by Prasad Dabak
Post by Prasad Dabak
messageDigest
Post by Prasad Dabak
(unencrypted) and encryptedDigest
(encrypted). Is
Post by Prasad Dabak
Post by Prasad Dabak
it enough to match
Post by Prasad Dabak
messgaeDigest with the computed
digest? OR we also
Post by Prasad Dabak
Post by Prasad Dabak
need to decrypt
Post by Prasad Dabak
the encryptedDigest using the
company public key
Post by Prasad Dabak
Post by Prasad Dabak
and match that as well?
Post by Prasad Dabak
2. What
does PKCS7_Verify
Post by Prasad Dabak
Post by Prasad Dabak
exactly do? I
Post by Prasad Dabak
looked at
https://www.openssl.org/docs/crypto/PKCS7_verify.htmland I
Post by Prasad Dabak
Post by Prasad Dabak
Post by Prasad Dabak
understand that it verifies
certificate chain.
Post by Prasad Dabak
Post by Prasad Dabak
However, it's not
Post by Prasad Dabak
clear to me as to what exactly it
does with respect
Post by Prasad Dabak
Post by Prasad Dabak
to signature
Post by Prasad Dabak
verification?
3. I am
assuming that I
Post by Prasad Dabak
Post by Prasad Dabak
require to do both
Post by Prasad Dabak
(1) and (2) in order to verify
the authenticode
Post by Prasad Dabak
Post by Prasad Dabak
signature?
Post by Prasad Dabak
4. What is
the best way to
Post by Prasad Dabak
Post by Prasad Dabak
verify if the
Post by Prasad Dabak
executable is signed by specific
company using that
Post by Prasad Dabak
Post by Prasad Dabak
company's public key?
Post by Prasad Dabak
Any inputs
will be greatly
Post by Prasad Dabak
Post by Prasad Dabak
appreciated!
Enjoy
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
______________________________________________________________________
OpenSSL Project http://www.openssl.org
Loading...