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.
- 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:
- 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 definitionallow_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:
- 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.