mirror of
https://github.com/lief-project/LIEF
synced 2026-06-08 15:30:44 +00:00
83 lines
2.4 KiB
Python
83 lines
2.4 KiB
Python
#!/usr/bin/env python
|
|
"""Walk-through of LIEF's Authenticode API.
|
|
|
|
Exercises the most useful entry points of the Authenticode surface:
|
|
computing authentihashes, calling ``verify_signature``, iterating
|
|
over the certificate chain and verifying the chain against a trust
|
|
bundle pointed to by the ``LIEF_CA_BUNDLE`` environment variable.
|
|
|
|
Example:
|
|
|
|
$ LIEF_CA_BUNDLE=/path/to/authenticode-bundle.pem \\
|
|
python api_example.py avast_free_antivirus_setup_online.exe
|
|
"""
|
|
|
|
import argparse
|
|
import os
|
|
import sys
|
|
|
|
import lief
|
|
|
|
|
|
def main() -> int:
|
|
parser = argparse.ArgumentParser(description=__doc__.splitlines()[0])
|
|
parser.add_argument("binary", help="Path to a PE binary")
|
|
parser.add_argument(
|
|
"--bundle",
|
|
default=os.getenv("LIEF_CA_BUNDLE"),
|
|
help="Path to a PEM bundle of trust anchors "
|
|
"(default: $LIEF_CA_BUNDLE)",
|
|
)
|
|
args = parser.parse_args()
|
|
|
|
pe = lief.PE.parse(args.binary)
|
|
if pe is None:
|
|
print(f"Error: failed to parse '{args.binary}' as PE", file=sys.stderr)
|
|
return 1
|
|
|
|
# Authentihash digests.
|
|
print(pe.authentihash_md5.hex(":"))
|
|
print(pe.authentihash(lief.PE.ALGORITHMS.SHA_1).hex(":"))
|
|
|
|
# PKCS #7 signature verification.
|
|
print(pe.verify_signature())
|
|
|
|
if not pe.signatures:
|
|
print("No signature embedded in the PE", file=sys.stderr)
|
|
return 1
|
|
|
|
signature = pe.signatures[0]
|
|
|
|
# Look for a well-known DigiCert root CA in the embedded chain.
|
|
bin_ca = None
|
|
target_issuer = (
|
|
"C=US, O=DigiCert Inc, OU=www.digicert.com, "
|
|
"CN=DigiCert Assured ID Root CA"
|
|
)
|
|
for crt in signature.certificates:
|
|
if crt.issuer == target_issuer:
|
|
bin_ca = crt
|
|
break
|
|
if bin_ca is None:
|
|
print("No DigiCert root CA found in the signature chain", file=sys.stderr)
|
|
return 1
|
|
|
|
# Verify the selected CA against an external trust bundle (e.g. the
|
|
# authenticode bundle shipped with signify).
|
|
if args.bundle is not None:
|
|
bundle = lief.PE.x509.parse(args.bundle)
|
|
print(bin_ca.is_trusted_by(bundle))
|
|
|
|
# Verify that the signer certificate was signed by the selected CA.
|
|
cert_signer = signature.signers[0].cert
|
|
print(cert_signer)
|
|
if cert_signer is None:
|
|
print("Signer certificate is missing", file=sys.stderr)
|
|
return 1
|
|
print(bin_ca.verify(cert_signer))
|
|
return 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
sys.exit(main())
|