aboutsummaryrefslogtreecommitdiff
path: root/pyasn1_modules
diff options
context:
space:
mode:
authorRuss Housley <housley@vigilsec.com>2019-09-27 18:13:46 -0400
committerIlya Etingof <etingof@gmail.com>2019-09-28 00:13:46 +0200
commitaa1b0c65c1ffc4ec4c0a9fdc037012b457154af7 (patch)
treec28992425af0f5ad936c051ea32a44d52fbd43d6 /pyasn1_modules
parent38da5f02063131f6149f3e0fc798a304a41d7831 (diff)
downloadpyasn1-modules-aa1b0c65c1ffc4ec4c0a9fdc037012b457154af7.tar.gz
Add support for RFC 5751 (#66)
* Add support for RFC 5751
Diffstat (limited to 'pyasn1_modules')
-rw-r--r--pyasn1_modules/rfc2985.py7
-rw-r--r--pyasn1_modules/rfc5751.py124
2 files changed, 130 insertions, 1 deletions
diff --git a/pyasn1_modules/rfc2985.py b/pyasn1_modules/rfc2985.py
index c8ebb0c..75bccf0 100644
--- a/pyasn1_modules/rfc2985.py
+++ b/pyasn1_modules/rfc2985.py
@@ -565,6 +565,11 @@ rfc5280.certificateAttributesMap.update(_certificateAttributesMapUpdate)
# CMS Attribute Map
+# Note: pkcs_9_at_smimeCapabilities is not included in the map because
+# the definition in RFC 5751 is preferred, which produces the same
+# encoding, but it allows different parameters for SMIMECapability
+# and AlgorithmIdentifier.
+
_cmsAttributesMapUpdate = {
# Attribute types for use in PKCS #7 data (a.k.a. CMS)
pkcs_9_at_contentType: ContentType(),
@@ -577,7 +582,7 @@ _cmsAttributesMapUpdate = {
pkcs_9_at_friendlyName: FriendlyName(),
pkcs_9_at_localKeyId: univ.OctetString(),
pkcs_9_at_signingDescription: DirectoryString(),
- pkcs_9_at_smimeCapabilities: SMIMECapabilities(),
+ # pkcs_9_at_smimeCapabilities: SMIMECapabilities(),
}
rfc5652.cmsAttributesMap.update(_cmsAttributesMapUpdate)
diff --git a/pyasn1_modules/rfc5751.py b/pyasn1_modules/rfc5751.py
new file mode 100644
index 0000000..7e20001
--- /dev/null
+++ b/pyasn1_modules/rfc5751.py
@@ -0,0 +1,124 @@
+# This file is being contributed to pyasn1-modules software.
+#
+# Created by Russ Housley with assistance from asn1ate v.0.6.0.
+#
+# Copyright (c) 2019, Vigil Security, LLC
+# License: http://snmplabs.com/pyasn1/license.html
+#
+# S/MIME Version 3.2 Message Specification
+#
+# ASN.1 source from:
+# https://www.rfc-editor.org/rfc/rfc5751.txt
+
+from pyasn1.type import namedtype
+from pyasn1.type import opentype
+from pyasn1.type import tag
+from pyasn1.type import univ
+
+from pyasn1_modules import rfc5652
+from pyasn1_modules import rfc8018
+
+
+def _OID(*components):
+ output = []
+ for x in tuple(components):
+ if isinstance(x, univ.ObjectIdentifier):
+ output.extend(list(x))
+ else:
+ output.append(int(x))
+ return univ.ObjectIdentifier(output)
+
+
+# Imports from RFC 5652 and RFC 8018
+
+IssuerAndSerialNumber = rfc5652.IssuerAndSerialNumber
+
+RecipientKeyIdentifier = rfc5652.RecipientKeyIdentifier
+
+SubjectKeyIdentifier = rfc5652.SubjectKeyIdentifier
+
+rc2CBC = rfc8018.rc2CBC
+
+
+# S/MIME Capabilities Attribute
+
+smimeCapabilities = univ.ObjectIdentifier('1.2.840.113549.1.9.15')
+
+
+smimeCapabilityMap = { }
+
+
+class SMIMECapability(univ.Sequence):
+ pass
+
+SMIMECapability.componentType = namedtype.NamedTypes(
+ namedtype.NamedType('capabilityID', univ.ObjectIdentifier()),
+ namedtype.OptionalNamedType('parameters', univ.Any(),
+ openType=opentype.OpenType('capabilityID', smimeCapabilityMap))
+)
+
+
+class SMIMECapabilities(univ.SequenceOf):
+ pass
+
+SMIMECapabilities.componentType = SMIMECapability()
+
+
+class SMIMECapabilitiesParametersForRC2CBC(univ.Integer):
+ # which carries the RC2 Key Length (number of bits)
+ pass
+
+
+# S/MIME Encryption Key Preference Attribute
+
+id_smime = univ.ObjectIdentifier('1.2.840.113549.1.9.16')
+
+id_aa = _OID(id_smime, 2)
+
+id_aa_encrypKeyPref = _OID(id_aa, 11)
+
+
+class SMIMEEncryptionKeyPreference(univ.Choice):
+ pass
+
+SMIMEEncryptionKeyPreference.componentType = namedtype.NamedTypes(
+ namedtype.NamedType('issuerAndSerialNumber',
+ IssuerAndSerialNumber().subtype(implicitTag=tag.Tag(
+ tag.tagClassContext, tag.tagFormatSimple, 0))),
+ namedtype.NamedType('receipentKeyId',
+ # Yes, 'receipentKeyId' is spelled incorrectly, but kept
+ # this way for alignment with the ASN.1 module in the RFC.
+ RecipientKeyIdentifier().subtype(implicitTag=tag.Tag(
+ tag.tagClassContext, tag.tagFormatSimple, 1))),
+ namedtype.NamedType('subjectAltKeyIdentifier',
+ SubjectKeyIdentifier().subtype(implicitTag=tag.Tag(
+ tag.tagClassContext, tag.tagFormatSimple, 2)))
+)
+
+
+# The Prefer Binary Inside SMIMECapabilities attribute
+
+id_cap = _OID(id_smime, 11)
+
+id_cap_preferBinaryInside = _OID(id_cap, 1)
+
+
+# CMS Attribute Map
+
+_cmsAttributesMapUpdate = {
+ smimeCapabilities: SMIMECapabilities(),
+ id_aa_encrypKeyPref: SMIMEEncryptionKeyPreference(),
+}
+
+rfc5652.cmsAttributesMap.update(_cmsAttributesMapUpdate)
+
+
+# SMIMECapabilities Attribute Map
+#
+# Do not include OIDs in the dictionary when the parameters are absent.
+
+_smimeCapabilityMapUpdate = {
+ rc2CBC: SMIMECapabilitiesParametersForRC2CBC(),
+}
+
+smimeCapabilityMap.update(_smimeCapabilityMapUpdate)