X509: Certificates and Verification

To be able to verify structures, Signify has a library to allow validating certificates. The Certificate is an object that abstracts a x509 certificate and has the ability to be verified. The verification requires the creation of a validation chain, that lead back to a trusted certificate authority.

You can use this module as follows:

trust_store = FileSystemCertificateStore(location=pathlib.Path("certificates/authenticode/"), trusted=True)
context = VerificationContext(trust_store)
with open("certificate.pem", "rb") as f, open("certificate2.pem", "rb") as g:
    to_verify1 = Certificate.from_pem(f.read())
    to_verify2 = Certificate.from_pem(g.read())

to_verify1.verify(context)  # prints True
to_verify2.verify(context)  # raises VerificationError

Certificate

class signify.x509.Certificate(data: CertificateChoices | ExtendedCertificateOrCertificate | ExtendedCertificateOrCertificate | Certificate | Certificate)

Representation of a Certificate. It is built from an ASN.1 structure.

data

The underlying ASN.1 data object

signature_algorithm
signature_value
subject_public_algorithm
subject_public_key

These values are considered part of the certificate, but not fully parsed.

version

This is the version of the certificate

serial_number

The full integer serial number of the certificate

issuer
subject

The CertificateName for the issuer and subject.

valid_from
valid_to

The datetime objects between which the certificate is valid.

extensions

This is a list of extension objects.

Parameters:

data (asn1.pkcs7.ExtendedCertificateOrCertificate or asn1.x509.Certificate or asn1.x509.TBSCertificate) – The ASN.1 structure

classmethod from_der(content: bytes) Certificate

Load the Certificate object from DER-encoded data

classmethod from_pem(content: bytes) Certificate

Reads a Certificate from a PEM formatted file.

classmethod from_pems(content: bytes) Iterator[Certificate]

Reads a Certificate from a PEM formatted file.

potential_chains(context: VerificationContext) Iterator[list[Certificate]]

Alias for VerificationContext.potential_chains()

property to_asn1crypto: Certificate

Retrieves the asn1crypto x509 Certificate object.

property to_der: bytes

Returns the DER-encoded data from this certificate.

verify(context: VerificationContext) Iterable[Certificate]

Alias for VerificationContext.verify()

verify_signature(signature: bytes, data: bytes, algorithm: HashFunction, allow_legacy: bool = False) None

Verifies whether the signature bytes match the data using the hashing algorithm. Supports RSA and EC keys. Note that not all hashing algorithms are supported.

Parameters:
  • signature (bytes) – The signature to verify

  • data (bytes) – The data that must be verified

  • algorithm (a hashlib function) – The hashing algorithm to use

  • allow_legacy (bool) –

    If True, allows a legacy signature verification. This method is intended for the case where the encryptedDigest does not contain an ASN.1 structure, but a raw hash value instead. It is attempted automatically when verification of the RSA signature fails.

    This case is described in more detail on https://mta.openssl.org/pipermail/openssl-users/2015-September/002053.html

class signify.x509.CertificateName(data: Any)
property dn: str

Returns an (almost) rfc2253 compatible string given a RDNSequence

get_components(component_type: None = None) Iterator[tuple[str, str]]
get_components(component_type: str | Tuple[int, ...]) Iterator[str]

Get individual components of this CertificateName

Parameters:

component_type – if provided, yields only values of this type, if not provided, yields tuples of (type, value)

property rdns: Iterable[tuple[str, str]]

A list of all components of the object.

Certificate Store

class signify.x509.CertificateStore(*args: Certificate | Iterable[Certificate], trusted: bool = False, ctl: CertificateTrustList | None = None, **kwargs: Any)

A list of Certificate objects.

Parameters:
  • trusted (bool) – If true, all certificates that are appended to this structure are set to trusted.

  • ctl (CertificateTrustList) – The certificate trust list to use (if any)

append(elem: Certificate) None

Append object to the end of the list.

find_certificate(**kwargs: Any) Certificate

Finds the certificate as specified by the keyword arguments. See find_certificates() for all possible arguments. If there is not exactly 1 certificate matching the parameters, i.e. there are zero or there are multiple, an error is raised.

Return type:

Certificate

Raises:

KeyError

find_certificates(*, subject: CertificateName | None = None, serial_number: int | None = None, issuer: CertificateName | None = None, sha256_fingerprint: str | None = None) Iterable[Certificate]

Finds all certificates given by the specified properties. A property can be omitted by specifying None. Calling this function without arguments is the same as iterating over this store

Parameters:
  • subject (CertificateName) – Certificate subject to look for, as CertificateName

  • serial_number (int) – Serial number to look for.

  • issuer (CertificateName) – Certificate issuer to look for, as CertificateName

  • sha256_fingerprint (str) – The SHA-256 fingerprint to look for

Return type:

Iterable[Certificate]

is_trusted(certificate: Certificate) bool
Returns whether the provided certificate is trusted by this certificate

store.

Warning

This check does not verify that the certificate is valid according to the Trust List, if set. It merely checks that the provided certificate is in a trusted certificate store. You still need to verify the chain for its full trust.

verify_trust(chain: list[Certificate], context: VerificationContext | None = None) bool

Verifies that the chain is trusted given the context.

class signify.x509.FileSystemCertificateStore(location: Path, *args: Any, **kwargs: Any)

A list of Certificate objects loaded from the file system.

Parameters:
  • location (pathlib.Path) – The file system location for the certificates.

  • trusted (bool) – If true, all certificates that are appended to this structure are set to trusted.

Verification

class signify.x509.VerificationContext(*stores: CertificateStore, timestamp: datetime | None = None, key_usages: Iterable[str] | None = None, extended_key_usages: Iterable[str] | None = None, optional_eku: bool = True, allow_legacy: bool = True, revocation_mode: Literal['soft-fail', 'hard-fail', 'require'] = 'soft-fail', allow_fetching: bool = False, fetch_timeout: int = 30, crls: Iterable[CertificateList] | None = None, ocsps: Iterable[OCSPResponse] | None = None)

A context holding properties about the verification of a signature or certificate.

Parameters:

stores (Iterable[CertificateStore]) – A list of CertificateStore objects

that contain certificates :param datetime.datetime timestamp: The timestamp to verify with. If None, the

current time is used. Must be a timezone-aware timestamp.

Parameters:
  • key_usages (Iterable[str]) – An iterable with the keyUsages to check for. For valid options, see certvalidator.CertificateValidator.validate_usage()

  • extended_key_usages (Iterable[str]) – An iterable with the EKU’s to check for. See certvalidator.CertificateValidator.validate_usage()

  • optional_eku (bool) – If True, sets the extended_key_usages as optionally present in the certificates.

  • allow_legacy (bool) – If True, allows chain verification if the signature hash algorithm is very old (e.g. MD2). Additionally, allows the SignedInfo encryptedDigest to contain an encrypted hash instead of an encrypted DigestInfo ASN.1 structure. Both are found in the wild, but setting to True does reduce the reliability of the verification.

  • revocation_mode (str) – Can be either soft-fail, hard-fail or require. See the documentation of certvalidator.ValidationContext() for the full definition

  • allow_fetching (bool) – If True, allows the underlying verification module to obtain CRL and OSCP responses when needed.

  • fetch_timeout (int) – The timeout used when fetching CRL/OSCP responses

  • crls (Iterable[asn1crypto.crl.CertificateList]) – List of asn1crypto.crl.CertificateList objects to aid in verifying revocation statuses.

  • ocsps (Iterable[asn1crypto.ocsp.OCSPResponse]) – List of asn1crypto.ocsp.OCSPResponse objects to aid in verifying revocation statuses.

add_store(store: CertificateStore) None

Adds a certificate store to the VerificationContext

property certificates: Iterator[Certificate]

Iterates over all certificates in the associated stores.

Return type:

Iterable[Certificate]

find_certificate(**kwargs: Any) Certificate

Finds the certificate as specified by the keyword arguments. See find_certificates() for all possible arguments. If there is not exactly 1 certificate matching the parameters, i.e. there are zero or there are multiple, an error is raised.

Return type:

Certificate

Raises:

KeyError

find_certificates(**kwargs: Any) Iterator[Certificate]

Finds all certificates given by the specified keyword arguments. See CertificateStore.find_certificates() for a list of all supported arguments.

Return type:

Iterable[Certificate]

is_trusted(certificate: Certificate) bool

Returns whether the provided certificate is trusted by a trusted certificate store.

Warning

This check does not verify that the certificate is valid according to the Trust List, if set. It merely checks that the provided certificate is in a trusted certificate store. You still need to verify the chain for its full trust.

potential_chains(certificate: Certificate, depth: int = 10) Iterator[list[Certificate]]

Returns all possible chains from the provided certificate, solely based on issuer/subject matching.

THIS METHOD DOES NOT VERIFY WHETHER A CHAIN IS ACTUALLY VALID. Use verify() for that.

Parameters:
  • certificate (Certificate) – The certificate to build a potential chain for

  • depth (int) – The maximum depth, used for recursion

Return type:

Iterable[Iterable[Certificate]]

Returns:

A iterable of all possible certificate chains

verify(certificate: Certificate) Iterable[Certificate]

Verifies the certificate, and its chain.

Parameters:

certificate (Certificate) – The certificate to verify

Returns:

A valid certificate chain for this certificate.

Return type:

Iterable[Certificate]

Raises:

AuthenticodeVerificationError – When the certificate could not be verified.

verify_trust(chain: list[Certificate]) bool

Determines whether the given certificate chain is trusted by a trusted certificate store.

Parameters:

chain (List[Certificate]) – The certificate chain to verify trust for.

Returns:

True if the certificate chain is trusted by a certificate store.