diff options
author | Lucia Li <luciali@google.com> | 2021-11-08 22:06:11 +0800 |
---|---|---|
committer | Lucia Li <luciali@google.com> | 2021-11-11 11:40:19 +0800 |
commit | c6ba99dd6153e7c10c4fc37dcc7af464fc76853b (patch) | |
tree | 1bc0942b942becc5391abbaf74cb61a05a4e76cd /src/cryptography/hazmat/primitives/serialization/pkcs7.py | |
parent | 104d218456a1d4f2f71a14c2c112b4ca24fe7310 (diff) | |
download | cryptography-c6ba99dd6153e7c10c4fc37dcc7af464fc76853b.tar.gz |
Upgrade cryptography from 2.5 to 3.3
Source code is from https://github.com/pyca/cryptography/tree/3.3.x
Run setup.py locally and rename _openssl.so/_padding.so
Bug: 205265538
Test: None
Change-Id: If031739ef5830ba2fb177add74515e4660e2906e
Diffstat (limited to 'src/cryptography/hazmat/primitives/serialization/pkcs7.py')
-rw-r--r-- | src/cryptography/hazmat/primitives/serialization/pkcs7.py | 132 |
1 files changed, 132 insertions, 0 deletions
diff --git a/src/cryptography/hazmat/primitives/serialization/pkcs7.py b/src/cryptography/hazmat/primitives/serialization/pkcs7.py new file mode 100644 index 000000000..1e11e28ef --- /dev/null +++ b/src/cryptography/hazmat/primitives/serialization/pkcs7.py @@ -0,0 +1,132 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. + +from __future__ import absolute_import, division, print_function + +from enum import Enum + +from cryptography import x509 +from cryptography.hazmat.backends import _get_backend +from cryptography.hazmat.primitives import hashes, serialization +from cryptography.hazmat.primitives.asymmetric import ec, rsa +from cryptography.utils import _check_byteslike + + +def load_pem_pkcs7_certificates(data): + backend = _get_backend(None) + return backend.load_pem_pkcs7_certificates(data) + + +def load_der_pkcs7_certificates(data): + backend = _get_backend(None) + return backend.load_der_pkcs7_certificates(data) + + +class PKCS7SignatureBuilder(object): + def __init__(self, data=None, signers=[], additional_certs=[]): + self._data = data + self._signers = signers + self._additional_certs = additional_certs + + def set_data(self, data): + _check_byteslike("data", data) + if self._data is not None: + raise ValueError("data may only be set once") + + return PKCS7SignatureBuilder(data, self._signers) + + def add_signer(self, certificate, private_key, hash_algorithm): + if not isinstance( + hash_algorithm, + ( + hashes.SHA1, + hashes.SHA224, + hashes.SHA256, + hashes.SHA384, + hashes.SHA512, + ), + ): + raise TypeError( + "hash_algorithm must be one of hashes.SHA1, SHA224, " + "SHA256, SHA384, or SHA512" + ) + if not isinstance(certificate, x509.Certificate): + raise TypeError("certificate must be a x509.Certificate") + + if not isinstance( + private_key, (rsa.RSAPrivateKey, ec.EllipticCurvePrivateKey) + ): + raise TypeError("Only RSA & EC keys are supported at this time.") + + return PKCS7SignatureBuilder( + self._data, + self._signers + [(certificate, private_key, hash_algorithm)], + ) + + def add_certificate(self, certificate): + if not isinstance(certificate, x509.Certificate): + raise TypeError("certificate must be a x509.Certificate") + + return PKCS7SignatureBuilder( + self._data, self._signers, self._additional_certs + [certificate] + ) + + def sign(self, encoding, options, backend=None): + if len(self._signers) == 0: + raise ValueError("Must have at least one signer") + if self._data is None: + raise ValueError("You must add data to sign") + options = list(options) + if not all(isinstance(x, PKCS7Options) for x in options): + raise ValueError("options must be from the PKCS7Options enum") + if encoding not in ( + serialization.Encoding.PEM, + serialization.Encoding.DER, + serialization.Encoding.SMIME, + ): + raise ValueError( + "Must be PEM, DER, or SMIME from the Encoding enum" + ) + + # Text is a meaningless option unless it is accompanied by + # DetachedSignature + if ( + PKCS7Options.Text in options + and PKCS7Options.DetachedSignature not in options + ): + raise ValueError( + "When passing the Text option you must also pass " + "DetachedSignature" + ) + + if PKCS7Options.Text in options and encoding in ( + serialization.Encoding.DER, + serialization.Encoding.PEM, + ): + raise ValueError( + "The Text option is only available for SMIME serialization" + ) + + # No attributes implies no capabilities so we'll error if you try to + # pass both. + if ( + PKCS7Options.NoAttributes in options + and PKCS7Options.NoCapabilities in options + ): + raise ValueError( + "NoAttributes is a superset of NoCapabilities. Do not pass " + "both values." + ) + + backend = _get_backend(backend) + return backend.pkcs7_sign(self, encoding, options) + + +class PKCS7Options(Enum): + Text = "Add text/plain MIME type" + Binary = "Don't translate input data into canonical MIME format" + DetachedSignature = "Don't embed data in the PKCS7 structure" + NoCapabilities = "Don't embed SMIME capabilities" + NoAttributes = "Don't embed authenticatedAttributes" + NoCerts = "Don't embed signer certificate" |