Part of Authenticode verification consists of:
- Comparing the computed Authenticode hash to the digest
stored in the ContentInfo section
- Comparing hash(ContentInfo) to the digest stored in the
AuthenticatedAttributes section
- Verifying signed(hash(AuthenticatedAttributes)) using a
certificate identified by the issuer and serial number
specified in the SignerInfo section
This commit makes it so that the raw bytes needed to
calculate hash(ContentInfo) and hash(AuthenticatedAttributes)
are available for use.
============================================================
Allow missing [0] in SpcSpOpusInfo
Some executables have MoreInfo but not a ProgramName (and the documentation
lists both as OPTIONAL), so handle this case correctly.
Example:
```
01416b1730218454c99b13592650cb170402b86742b4bab971565903b841829b
SEQUENCE(2 elem)
OBJECT IDENTIFIER1.3.6.1.4.1.311.2.1.12spcSpOpusInfo(Microsoft code signing)
SET(1 elem)
SEQUENCE(1 elem)
[1](1 elem)
[0]http://www.mozilla.com
```
============================================================
Improve consistency of parsed serial numbers
When parsing the issuer serial number, call mbedtls_x509_get_serial instead of
parsing it as an integer directly with mbedtls_asn1_get_mpi. These two functions
differ in how they treat serial numbers prepended with '00' to prevent them from
being negative (the former preserves the '00', and the latter discards it). The
embedded certs are parsed via a call to mbedtls_x509_crt_parse_der, which uses
mbedtls_x509_get_serial behind the scenes, so there was an inconsistency between
lief_obj.signature.signer_info.issuer[1] and
lief_obj.signature.certificates[x].serial_number. Example:
8bf57d97dd917c4f823659266caaa33e7398406daf11ba8318e3f7414ee3fb24
============================================================
Handle SpcLink and SpcString CHOICEs in SpcSpOpusInfo
The Authenticode spec doc says that these can be CHOICES, so
handle the easy ones and safely skip the others.
============================================================
Allow Authenticode sig to be parsed even if cert parsing fails
By default, mbedtls doesn't support MD2 certs, which are fairly
common in older signed executables. Ex:
1cb16f94cebdcad7dd05c8537375a6ff6379fcdb08528fc83889f26efaa84e2a
============================================================
Enable mbed TLS MD2 and MD4 support; add Unix debug options
By default, mbedtls doesn't support MD2 certs, which are fairly
common in older signed executables. Ex:
1cb16f94cebdcad7dd05c8537375a6ff6379fcdb08528fc83889f26efaa84e2a
============================================================
Set MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION flag
Some older signed executables use certs with the SpcSpAgencyInfo
Critical Extension, which mbed TLS doesn't support, so set
MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION to have it
skip this extension. Example:
781ca31416ec708a587851dafd90c661b86f244ab8b8475c4185e958e54ff838
============================================================
Support accessing non-utf8 issuer names via Python
For a few signatures where the issuer name contained non-utf8
characters, accessing the issuer name field in Python would raise
a UnicodeDecodeError exception. Now this field is handled the
same way the names in the individual certs are (I'm not sure if
they get represented 100% correctly, but at least they are
consistent, which is good enough for me). Example:
048f91b9302c88380fc66adac1e314d82733089ef3a31eadca5f0cb4169b195f
* Temporarily disable Melkor in test suite
The Makefile uses the -executable flag which doesn't work on RHEL5.
Disabling until I find a workaround for this.
* Patch Makefile in Melkor fuzzer
This replaces the `-executable` flag which is not supported by `find` on
CentOS 5.
* Respect CC environment variable
Several tests hard coded /usr/bin/cc which might not exist in some
environments. We first check the CC environment variable and fall back
to the hard coded path if CC is unset.
* Skip tests on GLIBC < 2.17
Some test binaries were linked against GLIBC 2.17. Skip tests which use
this binary if the platform does not have the required GLIBC version.
* Enable ccache in Docker in Travis builds
* Run `auditwheel repair` on the produced wheels
This will vendor the needed external shared libraries into the wheel and
tag it as manylinux1.
* Install ccache in Docker image
* Avoid using bind mount volume in Docker build
The bind mount volume wrote files as 'root' which causes issues with the
deploy script in Travis. Copying the source code into the image and
retrieving the built wheels instead of mounting the source tree fixes
this issue.
* Fix missing build folder when building with Docker
After finishing the build inside Docker we need the build directory from
the container to be able to deploy the built artifacts with deploy.sh.
* Use the right Python interpreter for Linux builds
The Dockerized .travis.yml builds attempt to invoke the interpreter in
the PYTHON_BINARY environment variable, which is only valid inside the
Docker image. To fix this, override the variable on Linux for tasks
which require the host's Python interpreter.
* Fix missing pip installation in Travis
The Ubuntu image in Travis does not come with `pip` preinstalled for
Python 3.
* Remove .git directory from .dockerignore
As `setup.py` uses `git` to determine the version number we need to copy
the contents of `.git` into the image.
* Unify SignerInfo issuer field format
This makes it so that the SignerInfo issuer field has the same
format as the issuer fields in each x509 cert, so the two can
be more easily compared.
Also, this commit adds '0x' in front of the Data Directory
RVAs and sizes to make it more clear that the values are printed
in hex.
* Add missing include in SignerInfo.cpp
* Address Codacy feedback and minor change to text
The serial number of the signing certificate will now be
printed as 'Serial Number' instead of 'Issuer Serial Number'
since the latter is a bit confusing (the serial number in
the SignerInfo section is the serial number of the certificate
that actually signed the executable)
* Update python pe_reader example based on issuer changes
- Allow UTF8String and IA5String types when parsing the Issuer fields
(previously only PrintableString types were handled). Handling these
three types should be sufficient, based on the default types indicated
at https://github.com/ARMmbed/mbedtls/blob/master/library/x509_create.c#L52.
The approach used is similar to what's done in mbedtls's internal
x509_get_attr_type_value function.
Examples:
```
8a364e0881fd7201cd6f0a0ff747451c9b93182d5699afb28ad8466f7f726660:
SEQUENCE (4 elem)
SET (1 elem)
SEQUENCE (2 elem)
OBJECT IDENTIFIER 2.5.4.6 countryName (X.520 DN component)
PrintableString PL
SET (1 elem)
SEQUENCE (2 elem)
OBJECT IDENTIFIER 2.5.4.10 organizationName (X.520 DN component)
UTF8String Unizeto Technologies S.A.
SET (1 elem)
SEQUENCE (2 elem)
OBJECT IDENTIFIER 2.5.4.11 organizationalUnitName (X.520 DN component)
UTF8String Certum Certification Authority
SET (1 elem)
SEQUENCE (2 elem)
OBJECT IDENTIFIER 2.5.4.3 commonName (X.520 DN component)
UTF8String Certum Code Signing CA SHA2
From a test binary compiled with osslsigncode:
SEQUENCE (6 elem)
SET (1 elem)
SEQUENCE (2 elem)
OBJECT IDENTIFIER 2.5.4.6 countryName (X.520 DN component)
PrintableString US
SET (1 elem)
SEQUENCE (2 elem)
OBJECT IDENTIFIER 2.5.4.8 stateOrProvinceName (X.520 DN component)
UTF8String State
SET (1 elem)
SEQUENCE (2 elem)
OBJECT IDENTIFIER 2.5.4.7 localityName (X.520 DN component)
UTF8String City
SET (1 elem)
SEQUENCE (2 elem)
OBJECT IDENTIFIER 2.5.4.10 organizationName (X.520 DN component)
UTF8String Cisco Talos
SET (1 elem)
SEQUENCE (2 elem)
OBJECT IDENTIFIER 2.5.4.11 organizationalUnitName (X.520 DN component)
UTF8String Test CA 1704a8ea9e24d8ed
SET (1 elem)
SEQUENCE (2 elem)
OBJECT IDENTIFIER 1.2.840.113549.1.9.1 emailAddress (PKCS #9. Deprecated, use an altName extension instead)
IA5String rfc2606@example.net
```
- Allow any order for the AuthenticatedAttributes, and ignore ones that
aren't recognized. The code was looking for a strict ordering of the
attributes, but Windows seems to be OK with any order.
Example:
```
From f91e258ea71dcbfc82371b2ee3e20852e45bef0cb946223d1141a6ef1dfb793f:
SEQUENCE (2 elem)
OBJECT IDENTIFIER 1.3.6.1.4.1.311.2.1.12 spcSpOpusInfo (Microsoft code signing)
SET (1 elem)
SEQUENCE (0 elem)
SEQUENCE (2 elem)
OBJECT IDENTIFIER 1.2.840.113549.1.9.3 contentType (PKCS #9)
SET (1 elem)
OBJECT IDENTIFIER 1.3.6.1.4.1.311.2.1.4 spcIndirectDataContext (Microsoft code signing)
SEQUENCE (2 elem)
OBJECT IDENTIFIER 1.3.6.1.4.1.311.2.1.11 spcStatementType (Microsoft code signing)
SET (1 elem)
SEQUENCE (1 elem)
OBJECT IDENTIFIER 1.3.6.1.4.1.311.2.1.21 individualCodeSigning (Microsoft)
SEQUENCE (2 elem)
OBJECT IDENTIFIER 1.2.840.113549.1.9.4 messageDigest (PKCS #9)
SET (1 elem)
OCTET STRING (20 byte) 7C87D331C6E62C0EC840BC23CA63FBC2CE68586F
```
- Allow the program name and/or more info to be missing from SpcSpOpusInfo.
Examples:
```
8a364e0881fd7201cd6f0a0ff747451c9b93182d5699afb28ad8466f7f726660:
SEQUENCE (2 elem)
OBJECT IDENTIFIER 1.3.6.1.4.1.311.2.1.12 spcSpOpusInfo (Microsoft code signing)
SET (1 elem)
SEQUENCE (0 elem)
0059fb3f225c5784789622eeccb97197d591972851b63d59f5bd107ddfdb7a21:
SEQUENCE (2 elem)
OBJECT IDENTIFIER 1.3.6.1.4.1.311.2.1.12 spcSpOpusInfo (Microsoft code signing)
SET (1 elem)
SEQUENCE (1 elem)
[0] (1 elem)
[0] (22 byte) 0047006F0054006F0020004F00700065006E00650072
```
- I removed the #if 0 ContentInfo from being populated, and the code worked
with all of the test samples I used... Is there another reason this code
is commented out?
- The authenticated_attribytes content_name_ member now gets populated. This
was commented out with a TODO by it... Is there a reason this field wasn't
being populated?
- When the SignerInfo is printed, it will now show 'N/A' if no value was
parsed out from the executable
Adds support for serialization of hwcap and unknown notes through
Builder::build()
Gives unknown note types a default ".note" namespace rather than
potentially alias a ".note.unknown" type in the future