pyhanko.sign.general module
General tools related to Cryptographic Message Syntax (CMS) signatures, not necessarily to the extent implemented in the PDF specification.
CMS is defined in RFC 5652. To parse CMS messages, pyHanko relies heavily on asn1crypto.
- class pyhanko.sign.general.SignatureStatus(intact: bool, valid: bool, trusted: bool, revoked: bool, signing_cert: asn1crypto.x509.Certificate, pkcs7_signature_mechanism: str, md_algorithm: str, validation_path: pyhanko_certvalidator.path.ValidationPath)
Bases:
object
Class describing the validity of a (general) CMS signature.
- intact: bool
Reports whether the signature is intact, i.e. whether the hash of the message content (which may or may not be embedded inside the CMS object itself) matches the hash value that was signed.
- valid: bool
Reports whether the signature is valid, i.e. whether the hash’s signature actually validates.
- trusted: bool
Reports whether the signer’s certificate is trusted w.r.t. the currently relevant validation context and key usage requirements.
- revoked: bool
Reports whether the signer’s certificate has been revoked or not. If this field is
True
, then obviouslytrusted
will beFalse
.
- signing_cert: asn1crypto.x509.Certificate
Contains the certificate of the signer, as embedded in the CMS object.
- pkcs7_signature_mechanism: str
CMS signature mechanism used.
- md_algorithm: str
Message digest algorithm used.
- validation_path: pyhanko_certvalidator.path.ValidationPath
Validation path providing a valid chain of trust from the signer’s certificate to a trusted root certificate.
- key_usage: ClassVar[Set[str]] = {'non_repudiation'}
Class property indicating which key usage extensions are required to be present on the signer’s certificate. The default is
non_repudiation
only.
- extd_key_usage: ClassVar[Optional[Set[str]]] = None
Class property indicating which extended key usage extensions are required to be present on the signer’s certificate.
- summary_fields()
- summary()
Provide a textual but machine-parsable summary of the validity.
- async classmethod validate_cert_usage(validator: pyhanko_certvalidator.CertificateValidator, key_usage_settings: Optional[pyhanko.sign.general.KeyUsageConstraints] = None)
- pyhanko.sign.general.simple_cms_attribute(attr_type, value)
Convenience method to quickly construct a CMS attribute object with one value.
- Parameters
attr_type – The attribute type, as a string or OID.
value – The value.
- Returns
A
cms.CMSAttribute
object.
- pyhanko.sign.general.find_cms_attribute(attrs, name)
Find and return CMS attribute values of a given type.
- Parameters
attrs – The
cms.CMSAttributes
object.name – The attribute type as a string (as defined in
asn1crypto
).
- Returns
The values associated with the requested type, if present.
- Raises
NonexistentAttributeError – Raised when no such type entry could be found in the
cms.CMSAttributes
object.
- pyhanko.sign.general.find_unique_cms_attribute(attrs, name)
Find and return a unique CMS attribute value of a given type.
- Parameters
attrs – The
cms.CMSAttributes
object.name – The attribute type as a string (as defined in
asn1crypto
).
- Returns
The value associated with the requested type, if present.
- Raises
NonexistentAttributeError – Raised when no such type entry could be found in the
cms.CMSAttributes
object.MultivaluedAttributeError – Raised when the attribute’s cardinality is not 1.
- pyhanko.sign.general.extract_message_digest(signer_info: asn1crypto.cms.SignerInfo)
- pyhanko.sign.general.validate_sig_integrity(signer_info: asn1crypto.cms.SignerInfo, cert: asn1crypto.x509.Certificate, expected_content_type: str, actual_digest: bytes, weak_hash_algorithms=frozenset({'md2', 'md5', 'sha1'})) Tuple[bool, bool]
Validate the integrity of a signature for a particular signerInfo object inside a CMS signed data container.
Warning
This function does not do any trust checks, and is considered “dangerous” API because it is easy to misuse.
- Parameters
signer_info – A
cms.SignerInfo
object.cert –
The signer’s certificate.
Note
This function will not attempt to extract certificates from the signed data.
expected_content_type – The expected value for the content type attribute (as a Python string, see
cms.ContentType
).actual_digest – The actual digest to be matched to the message digest attribute.
weak_hash_algorithms – List, tuple or set of weak hashing algorithms.
- Returns
A tuple of two booleans. The first indicates whether the provided digest matches the value in the signed attributes. The second indicates whether the signature of the digest is valid.
- class pyhanko.sign.general.CertificateStore
Bases:
pyhanko_certvalidator.registry.CertificateCollection
,abc.ABC
- register(cert: asn1crypto.x509.Certificate) bool
Register a single certificate.
- Parameters
cert – Certificate to add.
- Returns
True
if the certificate was added,False
if it already existed in this store.
- register_multiple(certs)
Register multiple certificates.
- Parameters
certs – Certificates to register.
- Returns
True
if at least one certificate was added,False
if all certificates already existed in this store.
- class pyhanko.sign.general.SimpleCertificateStore
Bases:
pyhanko_certvalidator.registry.CertificateStore
Simple trustless certificate store.
- classmethod from_certs(certs)
- register(cert: asn1crypto.x509.Certificate) bool
Register a single certificate.
- Parameters
cert – Certificate to add.
- Returns
True
if the certificate was added,False
if it already existed in this store.
- retrieve_many_by_key_identifier(key_identifier: bytes)
Retrieves possibly multiple certs via the corresponding key identifiers
- Parameters
key_identifier – A byte string of the key identifier
- Returns
A list of asn1crypto.x509.Certificate objects
- retrieve_by_name(name: asn1crypto.x509.Name)
Retrieves a list certs via their subject name
- Parameters
name – An asn1crypto.x509.Name object
- Returns
A list of asn1crypto.x509.Certificate objects
- retrieve_by_issuer_serial(issuer_serial)
Retrieve a certificate by its
issuer_serial
value.- Parameters
issuer_serial – The
issuer_serial
value of the certificate.- Returns
The certificate corresponding to the
issuer_serial
key passed in.- Returns
None or an asn1crypto.x509.Certificate object
- class pyhanko.sign.general.KeyUsageConstraints(key_usage: Optional[Set[str]] = None, key_usage_forbidden: Optional[Set[str]] = None, extd_key_usage: Optional[Set[str]] = None, explicit_extd_key_usage_required: bool = True, match_all_key_usages: bool = False)
Bases:
pyhanko.pdf_utils.config_utils.ConfigurableMixin
Convenience class to pass around key usage requirements and validate them. Intended to be flexible enough to handle both PKIX and ISO 32000 certificate seed value constraint semantics.
Changed in version 0.6.0: Bring extended key usage semantics in line with RFC 5280 (PKIX).
- key_usage: Set[str] = None
All or some (depending on
match_all_key_usage
) of these key usage extensions must be present in the signer’s certificate. If not set or empty, all key usages are considered acceptable.
- key_usage_forbidden: Set[str] = None
These key usage extensions must not be present in the signer’s certificate.
Note
This behaviour is undefined in RFC 5280 (PKIX), but included for compatibility with certificate seed value settings in ISO 32000.
- extd_key_usage: Set[str] = None
List of acceptable key purposes that can appear in an extended key usage extension in the signer’s certificate, if such an extension is at all present. If not set, all extended key usages are considered acceptable.
If no extended key usage extension is present, or the
anyExtendedKeyUsage
key purpose ID is present the resulting behaviour depends onexplicit_extd_key_usage_required
.Setting this option to the empty set (as opposed to
None
) effectively bans all (presumably unrecognised) extended key usages.Warning
Note the difference in behaviour with
key_usage
for empty sets of valid usages.Warning
Contrary to what some CAs seem to believe, the criticality of the extended key usage extension is irrelevant here. Even a non-critical EKU extension must be enforced according to RFC 5280 § 4.2.1.12.
In practice, many certificate authorities issue non-repudiation certs that can also be used for TLS authentication by only including the TLS client authentication key purpose ID in the EKU extension. Interpreted strictly, RFC 5280 bans such certificates from being used to sign documents, and pyHanko will enforce these semantics if
extd_key_usage
is notNone
.
- explicit_extd_key_usage_required: bool = True
New in version 0.6.0.
Require an extended key usage extension with the right key usages to be present if
extd_key_usage
is non-empty.If this flag is
True
, at least one key purpose inextd_key_usage
must appear in the certificate’s extended key usage, andanyExtendedKeyUsage
will be ignored.
- match_all_key_usages: bool = False
New in version 0.6.0.
If
True
, all key usages indicated inkey_usage
must be present in the certificate. IfFalse
, one match suffices.If
key_usage
is empty orNone
, this option has no effect.
- validate(cert: asn1crypto.x509.Certificate)
- classmethod process_entries(config_dict)
- exception pyhanko.sign.general.SigningError
Bases:
ValueError
Error encountered while signing a file.
- exception pyhanko.sign.general.UnacceptableSignerError
Bases:
pyhanko.sign.general.SigningError
Error raised when a signer was judged unacceptable.
- exception pyhanko.sign.general.WeakHashAlgorithmError
- exception pyhanko.sign.general.NonexistentAttributeError
Bases:
KeyError
- exception pyhanko.sign.general.MultivaluedAttributeError
Bases:
ValueError
- exception pyhanko.sign.general.SignatureValidationError
Bases:
ValueError
Error validating a signature.
- pyhanko.sign.general.load_certs_from_pemder(cert_files)
A convenience function to load PEM/DER-encoded certificates from files.
- Parameters
cert_files – An iterable of file names.
- Returns
A generator producing
asn1crypto.x509.Certificate
objects.
- pyhanko.sign.general.load_cert_from_pemder(cert_file)
A convenience function to load a single PEM/DER-encoded certificate from a file.
- Parameters
cert_file – A file name.
- Returns
An
asn1crypto.x509.Certificate
object.
- pyhanko.sign.general.load_private_key_from_pemder(key_file, passphrase: Optional[bytes]) asn1crypto.keys.PrivateKeyInfo
A convenience function to load PEM/DER-encoded keys from files.
- Parameters
key_file – File to read the key from.
passphrase – Key passphrase.
- Returns
A private key encoded as an unencrypted PKCS#8 PrivateKeyInfo object.
- pyhanko.sign.general.get_pyca_cryptography_hash(algorithm, prehashed=False)
- pyhanko.sign.general.optimal_pss_params(cert: asn1crypto.x509.Certificate, digest_algorithm: str) asn1crypto.algos.RSASSAPSSParams
Figure out the optimal RSASSA-PSS parameters for a given certificate. The subject’s public key must be an RSA key.
- Parameters
cert – An RSA X.509 certificate.
digest_algorithm – The digest algorithm to use.
- Returns
RSASSA-PSS parameters.
- pyhanko.sign.general.as_signing_certificate(cert: asn1crypto.x509.Certificate) asn1crypto.tsp.SigningCertificate
Format an ASN.1
SigningCertificate
object, where the certificate is identified by its SHA-1 digest.- Parameters
cert – An X.509 certificate.
- Returns
A
tsp.SigningCertificate
object referring to the original certificate.
- pyhanko.sign.general.as_signing_certificate_v2(cert: asn1crypto.x509.Certificate, hash_algo='sha256') asn1crypto.tsp.SigningCertificateV2
Format an ASN.1
SigningCertificateV2
value, where the certificate is identified by the hash algorithm specified.- Parameters
cert – An X.509 certificate.
hash_algo – Hash algorithm to use to digest the certificate. Default is SHA-256.
- Returns
A
tsp.SigningCertificateV2
object referring to the original certificate.
- pyhanko.sign.general.match_issuer_serial(expected_issuer_serial: Union[asn1crypto.cms.IssuerAndSerialNumber, asn1crypto.tsp.IssuerSerial], cert: asn1crypto.x509.Certificate) bool
Match the issuer and serial number of an X.509 certificate against some expected identifier.
- Parameters
expected_issuer_serial – A certificate identifier, either
cms.IssuerAndSerialNumber
ortsp.IssuerSerial
.cert – An
x509.Certificate
.
- Returns
True
if there’s a match,False
otherwise.