summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPaul Kehrer <paul.l.kehrer@gmail.com>2020-10-24 17:10:25 -0700
committerGitHub <noreply@github.com>2020-10-24 20:10:25 -0400
commit5edf5b828a8ebac030bf8c6f27ec8bf0d008885c (patch)
treea6eaf253c0c56af8931f6f447c89bb346dab980b /src
parentca622468f7665ddda00b7358d0ba0652beba7a89 (diff)
downloadcryptography-5edf5b828a8ebac030bf8c6f27ec8bf0d008885c.tar.gz
migrate smime builder to pkcs7 module and rename (#5496)
* migrate smime builder to pkcs7 module and rename * missed a rename
Diffstat (limited to 'src')
-rw-r--r--src/cryptography/hazmat/backends/openssl/backend.py16
-rw-r--r--src/cryptography/hazmat/primitives/serialization/pkcs7.py102
-rw-r--r--src/cryptography/hazmat/primitives/smime.py109
3 files changed, 110 insertions, 117 deletions
diff --git a/src/cryptography/hazmat/backends/openssl/backend.py b/src/cryptography/hazmat/backends/openssl/backend.py
index f7d6a47c7..3fd87ac5b 100644
--- a/src/cryptography/hazmat/backends/openssl/backend.py
+++ b/src/cryptography/hazmat/backends/openssl/backend.py
@@ -115,7 +115,7 @@ from cryptography.hazmat.backends.openssl.x509 import (
_RevokedCertificate,
)
from cryptography.hazmat.bindings.openssl import binding
-from cryptography.hazmat.primitives import hashes, serialization, smime
+from cryptography.hazmat.primitives import hashes, serialization
from cryptography.hazmat.primitives.asymmetric import (
dsa,
ec,
@@ -151,7 +151,7 @@ from cryptography.hazmat.primitives.ciphers.modes import (
XTS,
)
from cryptography.hazmat.primitives.kdf import scrypt
-from cryptography.hazmat.primitives.serialization import ssh
+from cryptography.hazmat.primitives.serialization import pkcs7, ssh
from cryptography.x509 import ocsp
@@ -2690,12 +2690,12 @@ class Backend(object):
return certs
- def smime_sign(self, builder, encoding, options):
+ def pkcs7_sign(self, builder, encoding, options):
bio = self._bytes_to_bio(builder._data)
init_flags = self._lib.PKCS7_PARTIAL
final_flags = 0
- if smime.SMIMEOptions.DetachedSignature in options:
+ if pkcs7.PKCS7Options.DetachedSignature in options:
# Don't embed the data in the PKCS7 structure
init_flags |= self._lib.PKCS7_DETACHED
final_flags |= self._lib.PKCS7_DETACHED
@@ -2715,9 +2715,9 @@ class Backend(object):
# These flags are configurable on a per-signature basis
# but we've deliberately chosen to make the API only allow
# setting it across all signatures for now.
- if smime.SMIMEOptions.NoCapabilities in options:
+ if pkcs7.PKCS7Options.NoCapabilities in options:
signer_flags |= self._lib.PKCS7_NOSMIMECAP
- elif smime.SMIMEOptions.NoAttributes in options:
+ elif pkcs7.PKCS7Options.NoAttributes in options:
signer_flags |= self._lib.PKCS7_NOATTR
for certificate, private_key, hash_algorithm in builder._signers:
md = self._evp_md_non_null_from_algorithm(hash_algorithm)
@@ -2729,9 +2729,9 @@ class Backend(object):
for option in options:
# DetachedSignature, NoCapabilities, and NoAttributes are already
# handled so we just need to check these last two options.
- if option is smime.SMIMEOptions.Text:
+ if option is pkcs7.PKCS7Options.Text:
final_flags |= self._lib.PKCS7_TEXT
- elif option is smime.SMIMEOptions.Binary:
+ elif option is pkcs7.PKCS7Options.Binary:
final_flags |= self._lib.PKCS7_BINARY
bio_out = self._create_mem_bio_gc()
diff --git a/src/cryptography/hazmat/primitives/serialization/pkcs7.py b/src/cryptography/hazmat/primitives/serialization/pkcs7.py
index fcdd1c9aa..658f7e5d2 100644
--- a/src/cryptography/hazmat/primitives/serialization/pkcs7.py
+++ b/src/cryptography/hazmat/primitives/serialization/pkcs7.py
@@ -4,7 +4,13 @@
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):
@@ -15,3 +21,99 @@ def 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=[]):
+ self._data = data
+ self._signers = signers
+
+ 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 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 is not serialization.Encoding.PEM
+ and encoding is not serialization.Encoding.DER
+ ):
+ raise ValueError("Must be PEM or DER 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 is serialization.Encoding.DER
+ ):
+ raise ValueError(
+ "The Text option does nothing when serializing to DER"
+ )
+
+ # 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"
diff --git a/src/cryptography/hazmat/primitives/smime.py b/src/cryptography/hazmat/primitives/smime.py
deleted file mode 100644
index 538ba6a00..000000000
--- a/src/cryptography/hazmat/primitives/smime.py
+++ /dev/null
@@ -1,109 +0,0 @@
-# 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
-
-
-class SMIMESignatureBuilder(object):
- def __init__(self, data=None, signers=[]):
- self._data = data
- self._signers = signers
-
- def set_data(self, data):
- _check_byteslike("data", data)
- if self._data is not None:
- raise ValueError("data may only be set once")
-
- return SMIMESignatureBuilder(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 SMIMESignatureBuilder(
- self._data,
- self._signers + [(certificate, private_key, hash_algorithm)],
- )
-
- 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, SMIMEOptions) for x in options):
- raise ValueError("options must be from the SMIMEOptions enum")
- if (
- encoding is not serialization.Encoding.PEM
- and encoding is not serialization.Encoding.DER
- ):
- raise ValueError("Must be PEM or DER from the Encoding enum")
-
- # Text is a meaningless option unless it is accompanied by
- # DetachedSignature
- if (
- SMIMEOptions.Text in options
- and SMIMEOptions.DetachedSignature not in options
- ):
- raise ValueError(
- "When passing the Text option you must also pass "
- "DetachedSignature"
- )
-
- if (
- SMIMEOptions.Text in options
- and encoding is serialization.Encoding.DER
- ):
- raise ValueError(
- "The Text option does nothing when serializing to DER"
- )
-
- # No attributes implies no capabilities so we'll error if you try to
- # pass both.
- if (
- SMIMEOptions.NoAttributes in options
- and SMIMEOptions.NoCapabilities in options
- ):
- raise ValueError(
- "NoAttributes is a superset of NoCapabilities. Do not pass "
- "both values."
- )
-
- backend = _get_backend(backend)
- return backend.smime_sign(self, encoding, options)
-
-
-class SMIMEOptions(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"