aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRuss Housley <housley@vigilsec.com>2019-08-17 02:21:47 -0400
committerIlya Etingof <etingof@gmail.com>2019-08-17 08:21:47 +0200
commit999c682a3e9c2d7770b7032fcf67fde0bac153c3 (patch)
tree47de84a7756630d2e8231c6460fce13d688cf502
parent283db3c96dfbbbc8bb9459e5923e01c04752f65e (diff)
downloadpyasn1-modules-999c682a3e9c2d7770b7032fcf67fde0bac153c3.tar.gz
Add more RFCs
Added ASN.1 modules for RFC298, RFC3770, RFC5914, RFC 6010, RFC6031, RFC6032, RFC7030, RFC7292, and RFC8018
-rw-r--r--CHANGES.txt12
-rw-r--r--pyasn1_modules/rfc2985.py583
-rw-r--r--pyasn1_modules/rfc3770.py63
-rw-r--r--pyasn1_modules/rfc5914.py119
-rw-r--r--pyasn1_modules/rfc6010.py88
-rw-r--r--pyasn1_modules/rfc6031.py469
-rw-r--r--pyasn1_modules/rfc6032.py68
-rw-r--r--pyasn1_modules/rfc7030.py66
-rw-r--r--pyasn1_modules/rfc7292.py357
-rw-r--r--pyasn1_modules/rfc8018.py260
-rw-r--r--tests/__main__.py9
-rw-r--r--tests/test_rfc2985.py293
-rw-r--r--tests/test_rfc3770.py90
-rw-r--r--tests/test_rfc4073.py2
-rw-r--r--tests/test_rfc5914.py83
-rw-r--r--tests/test_rfc6010.py95
-rw-r--r--tests/test_rfc6031.py89
-rw-r--r--tests/test_rfc6032.py88
-rwxr-xr-xtests/test_rfc6402.py163
-rw-r--r--tests/test_rfc7030.py87
-rw-r--r--tests/test_rfc7292.py172
-rw-r--r--tests/test_rfc7296.py5
-rw-r--r--tests/test_rfc8018.py56
23 files changed, 3312 insertions, 5 deletions
diff --git a/CHANGES.txt b/CHANGES.txt
index 4127ee3..60cb3e4 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -3,6 +3,18 @@ Revision 0.2.7, released XX-08-2019
-----------------------------------
- Added maps for use with openType to RFC 3565
+- Added RFC2985 providing PKCS#9 Attributes
+- Added RFC3770 providing Certificate Extensions and Attributes for
+ Authentication in PPP and Wireless LAN Networks
+- Added RFC5914 providing Trust Anchor Format
+- Added RFC6010 providing CMS Content Constraints (CCC) Extension
+- Added RFC6031 providing CMS Symmetric Key Package Content Type
+- Added RFC6032 providing CMS Encrypted Key Package Content Type
+- Added RFC7030 providing Enrollment over Secure Transport (EST)
+- Added RFC7292 providing PKCS #12, which is the Personal Information
+ Exchange Syntax v1.1
+- Added RFC8018 providing PKCS #5, which is the Password-Based
+ Cryptography Specification, Version 2.1
Revision 0.2.6, released 31-07-2019
-----------------------------------
diff --git a/pyasn1_modules/rfc2985.py b/pyasn1_modules/rfc2985.py
new file mode 100644
index 0000000..591d27d
--- /dev/null
+++ b/pyasn1_modules/rfc2985.py
@@ -0,0 +1,583 @@
+#
+# This file is part of 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
+#
+# PKCS#9: Selected Attribute Types (Version 2.0)
+#
+# ASN.1 source from:
+# https://www.rfc-editor.org/rfc/rfc2985.txt
+#
+
+from pyasn1.type import char
+from pyasn1.type import constraint
+from pyasn1.type import namedtype
+from pyasn1.type import namedval
+from pyasn1.type import opentype
+from pyasn1.type import tag
+from pyasn1.type import univ
+from pyasn1.type import useful
+
+from pyasn1_modules import rfc7292
+from pyasn1_modules import rfc5958
+from pyasn1_modules import rfc5652
+from pyasn1_modules import rfc5280
+
+
+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)
+
+
+MAX = float('inf')
+
+
+# Imports from RFC 5280
+
+AlgorithmIdentifier = rfc5280.AlgorithmIdentifier
+
+Attribute = rfc5280.Attribute
+
+EmailAddress = rfc5280.EmailAddress
+
+Extensions = rfc5280.Extensions
+
+Time = rfc5280.Time
+
+X520countryName = rfc5280.X520countryName
+
+X520SerialNumber = rfc5280.X520SerialNumber
+
+
+# Imports from RFC 5652
+
+ContentInfo = rfc5652.ContentInfo
+
+ContentType = rfc5652.ContentType
+
+Countersignature = rfc5652.Countersignature
+
+MessageDigest = rfc5652.MessageDigest
+
+SignerInfo = rfc5652.SignerInfo
+
+SigningTime = rfc5652.SigningTime
+
+
+# Imports from RFC 5958
+
+EncryptedPrivateKeyInfo = rfc5958.EncryptedPrivateKeyInfo
+
+
+# Imports from RFC 7292
+
+PFX = rfc7292.PFX
+
+
+# TODO:
+# Need a place to import PKCS15Token; it does not yet appear in an RFC
+
+
+# SingleAttribute is the same as Attribute in RFC 5280, except that the
+# attrValues SET must have one and only one member
+
+class AttributeType(univ.ObjectIdentifier):
+ pass
+
+
+class AttributeValue(univ.Any):
+ pass
+
+
+class AttributeValues(univ.SetOf):
+ pass
+
+AttributeValues.componentType = AttributeValue()
+
+
+class SingleAttributeValues(univ.SetOf):
+ pass
+
+SingleAttributeValues.componentType = AttributeValue()
+
+
+class SingleAttribute(univ.Sequence):
+ pass
+
+SingleAttribute.componentType = namedtype.NamedTypes(
+ namedtype.NamedType('type', AttributeType()),
+ namedtype.NamedType('values',
+ AttributeValues().subtype(sizeSpec=constraint.ValueSizeConstraint(1, 1)),
+ openType=opentype.OpenType('type', rfc5280.certificateAttributesMap)
+ )
+)
+
+
+# CMSAttribute is the same as Attribute in RFC 5652, and CMSSingleAttribute
+# is the companion where the attrValues SET must have one and only one member
+
+CMSAttribute = rfc5652.Attribute
+
+
+class CMSSingleAttribute(univ.Sequence):
+ pass
+
+CMSSingleAttribute.componentType = namedtype.NamedTypes(
+ namedtype.NamedType('attrType', AttributeType()),
+ namedtype.NamedType('attrValues',
+ AttributeValues().subtype(sizeSpec=constraint.ValueSizeConstraint(1, 1)),
+ openType=opentype.OpenType('attrType', rfc5652.cmsAttributesMap)
+ )
+)
+
+
+# DirectoryString is the same as RFC 5280, except the length is limited to 255
+
+class DirectoryString(univ.Choice):
+ pass
+
+DirectoryString.componentType = namedtype.NamedTypes(
+ namedtype.NamedType('teletexString', char.TeletexString().subtype(
+ subtypeSpec=constraint.ValueSizeConstraint(1, 255))),
+ namedtype.NamedType('printableString', char.PrintableString().subtype(
+ subtypeSpec=constraint.ValueSizeConstraint(1, 255))),
+ namedtype.NamedType('universalString', char.UniversalString().subtype(
+ subtypeSpec=constraint.ValueSizeConstraint(1, 255))),
+ namedtype.NamedType('utf8String', char.UTF8String().subtype(
+ subtypeSpec=constraint.ValueSizeConstraint(1, 255))),
+ namedtype.NamedType('bmpString', char.BMPString().subtype(
+ subtypeSpec=constraint.ValueSizeConstraint(1, 255)))
+)
+
+
+# PKCS9String is DirectoryString with an additional choice of IA5String,
+# and the SIZE is limited to 255
+
+class PKCS9String(univ.Choice):
+ pass
+
+PKCS9String.componentType = namedtype.NamedTypes(
+ namedtype.NamedType('ia5String', char.IA5String().subtype(
+ subtypeSpec=constraint.ValueSizeConstraint(1, 255))),
+ namedtype.NamedType('directoryString', DirectoryString())
+)
+
+
+# Upper Bounds
+
+pkcs_9_ub_pkcs9String = univ.Integer(255)
+
+pkcs_9_ub_challengePassword = univ.Integer(pkcs_9_ub_pkcs9String)
+
+pkcs_9_ub_emailAddress = univ.Integer(pkcs_9_ub_pkcs9String)
+
+pkcs_9_ub_friendlyName = univ.Integer(pkcs_9_ub_pkcs9String)
+
+pkcs_9_ub_match = univ.Integer(pkcs_9_ub_pkcs9String)
+
+pkcs_9_ub_signingDescription = univ.Integer(pkcs_9_ub_pkcs9String)
+
+pkcs_9_ub_unstructuredAddress = univ.Integer(pkcs_9_ub_pkcs9String)
+
+pkcs_9_ub_unstructuredName = univ.Integer(pkcs_9_ub_pkcs9String)
+
+
+ub_name = univ.Integer(32768)
+
+pkcs_9_ub_placeOfBirth = univ.Integer(ub_name)
+
+pkcs_9_ub_pseudonym = univ.Integer(ub_name)
+
+
+# Object Identifier Arcs
+
+ietf_at = _OID(1, 3, 6, 1, 5, 5, 7, 9)
+
+id_at = _OID(2, 5, 4)
+
+pkcs_9 = _OID(1, 2, 840, 113549, 1, 9)
+
+pkcs_9_mo = _OID(pkcs_9, 0)
+
+smime = _OID(pkcs_9, 16)
+
+certTypes = _OID(pkcs_9, 22)
+
+crlTypes = _OID(pkcs_9, 23)
+
+pkcs_9_oc = _OID(pkcs_9, 24)
+
+pkcs_9_at = _OID(pkcs_9, 25)
+
+pkcs_9_sx = _OID(pkcs_9, 26)
+
+pkcs_9_mr = _OID(pkcs_9, 27)
+
+
+# Object Identifiers for Syntaxes for use with LDAP-accessible directories
+
+pkcs_9_sx_pkcs9String = _OID(pkcs_9_sx, 1)
+
+pkcs_9_sx_signingTime = _OID(pkcs_9_sx, 2)
+
+
+# Object Identifiers for object classes
+
+pkcs_9_oc_pkcsEntity = _OID(pkcs_9_oc, 1)
+
+pkcs_9_oc_naturalPerson = _OID(pkcs_9_oc, 2)
+
+
+# Object Identifiers for matching rules
+
+pkcs_9_mr_caseIgnoreMatch = _OID(pkcs_9_mr, 1)
+
+pkcs_9_mr_signingTimeMatch = _OID(pkcs_9_mr, 2)
+
+
+# PKCS #7 PDU
+
+pkcs_9_at_pkcs7PDU = _OID(pkcs_9_at, 5)
+
+pKCS7PDU = Attribute()
+pKCS7PDU['type'] = pkcs_9_at_pkcs7PDU
+pKCS7PDU['values'][0] = ContentInfo()
+
+
+# PKCS #12 token
+
+pkcs_9_at_userPKCS12 = _OID(2, 16, 840, 1, 113730, 3, 1, 216)
+
+userPKCS12 = Attribute()
+userPKCS12['type'] = pkcs_9_at_userPKCS12
+userPKCS12['values'][0] = PFX()
+
+
+# PKCS #15 token
+
+pkcs_9_at_pkcs15Token = _OID(pkcs_9_at, 1)
+
+# TODO: Once PKCS15Token can be imported, this can be included
+#
+# pKCS15Token = Attribute()
+# userPKCS12['type'] = pkcs_9_at_pkcs15Token
+# userPKCS12['values'][0] = PKCS15Token()
+
+
+# PKCS #8 encrypted private key information
+
+pkcs_9_at_encryptedPrivateKeyInfo = _OID(pkcs_9_at, 2)
+
+encryptedPrivateKeyInfo = Attribute()
+encryptedPrivateKeyInfo['type'] = pkcs_9_at_encryptedPrivateKeyInfo
+encryptedPrivateKeyInfo['values'][0] = EncryptedPrivateKeyInfo()
+
+
+# Electronic-mail address
+
+pkcs_9_at_emailAddress = rfc5280.id_emailAddress
+
+emailAddress = Attribute()
+emailAddress['type'] = pkcs_9_at_emailAddress
+emailAddress['values'][0] = EmailAddress()
+
+
+# Unstructured name
+
+pkcs_9_at_unstructuredName = _OID(pkcs_9, 2)
+
+unstructuredName = Attribute()
+unstructuredName['type'] = pkcs_9_at_unstructuredName
+unstructuredName['values'][0] = PKCS9String()
+
+
+# Unstructured address
+
+pkcs_9_at_unstructuredAddress = _OID(pkcs_9, 8)
+
+unstructuredAddress = Attribute()
+unstructuredAddress['type'] = pkcs_9_at_unstructuredAddress
+unstructuredAddress['values'][0] = DirectoryString()
+
+
+# Date of birth
+
+pkcs_9_at_dateOfBirth = _OID(ietf_at, 1)
+
+dateOfBirth = SingleAttribute()
+dateOfBirth['type'] = pkcs_9_at_dateOfBirth
+dateOfBirth['values'][0] = useful.GeneralizedTime()
+
+
+# Place of birth
+
+pkcs_9_at_placeOfBirth = _OID(ietf_at, 2)
+
+placeOfBirth = SingleAttribute()
+placeOfBirth['type'] = pkcs_9_at_placeOfBirth
+placeOfBirth['values'][0] = DirectoryString()
+
+
+# Gender
+
+class GenderString(char.PrintableString):
+ pass
+
+GenderString.subtypeSpec = constraint.ValueSizeConstraint(1, 1)
+GenderString.subtypeSpec = constraint.SingleValueConstraint("M", "F", "m", "f")
+
+
+pkcs_9_at_gender = _OID(ietf_at, 3)
+
+gender = SingleAttribute()
+gender['type'] = pkcs_9_at_gender
+gender['values'][0] = GenderString()
+
+
+# Country of citizenship
+
+pkcs_9_at_countryOfCitizenship = _OID(ietf_at, 4)
+
+countryOfCitizenship = Attribute()
+countryOfCitizenship['type'] = pkcs_9_at_countryOfCitizenship
+countryOfCitizenship['values'][0] = X520countryName()
+
+
+# Country of residence
+
+pkcs_9_at_countryOfResidence = _OID(ietf_at, 5)
+
+countryOfResidence = Attribute()
+countryOfResidence['type'] = pkcs_9_at_countryOfResidence
+countryOfResidence['values'][0] = X520countryName()
+
+
+# Pseudonym
+
+id_at_pseudonym = _OID(2, 5, 4, 65)
+
+pseudonym = Attribute()
+pseudonym['type'] = id_at_pseudonym
+pseudonym['values'][0] = DirectoryString()
+
+
+# Serial number
+
+id_at_serialNumber = rfc5280.id_at_serialNumber
+
+serialNumber = Attribute()
+serialNumber['type'] = id_at_serialNumber
+serialNumber['values'][0] = X520SerialNumber()
+
+
+# Content type
+
+pkcs_9_at_contentType = rfc5652.id_contentType
+
+contentType = CMSSingleAttribute()
+contentType['attrType'] = pkcs_9_at_contentType
+contentType['attrValues'][0] = ContentType()
+
+
+# Message digest
+
+pkcs_9_at_messageDigest = rfc5652.id_messageDigest
+
+messageDigest = CMSSingleAttribute()
+messageDigest['attrType'] = pkcs_9_at_messageDigest
+messageDigest['attrValues'][0] = MessageDigest()
+
+
+# Signing time
+
+pkcs_9_at_signingTime = rfc5652.id_signingTime
+
+signingTime = CMSSingleAttribute()
+signingTime['attrType'] = pkcs_9_at_signingTime
+signingTime['attrValues'][0] = SigningTime()
+
+
+# Random nonce
+
+class RandomNonce(univ.OctetString):
+ pass
+
+RandomNonce.subtypeSpec = constraint.ValueSizeConstraint(4, MAX)
+
+
+pkcs_9_at_randomNonce = _OID(pkcs_9_at, 3)
+
+randomNonce = CMSSingleAttribute()
+randomNonce['attrType'] = pkcs_9_at_randomNonce
+randomNonce['attrValues'][0] = RandomNonce()
+
+
+# Sequence number
+
+class SequenceNumber(univ.Integer):
+ pass
+
+SequenceNumber.subtypeSpec = constraint.ValueRangeConstraint(1, MAX)
+
+
+pkcs_9_at_sequenceNumber = _OID(pkcs_9_at, 4)
+
+sequenceNumber = CMSSingleAttribute()
+sequenceNumber['attrType'] = pkcs_9_at_sequenceNumber
+sequenceNumber['attrValues'][0] = SequenceNumber()
+
+
+# Countersignature
+
+pkcs_9_at_counterSignature = rfc5652.id_countersignature
+
+counterSignature = CMSAttribute()
+counterSignature['attrType'] = pkcs_9_at_counterSignature
+counterSignature['attrValues'][0] = Countersignature()
+
+
+# Challenge password
+
+pkcs_9_at_challengePassword = _OID(pkcs_9, 7)
+
+challengePassword = SingleAttribute()
+challengePassword['type'] = pkcs_9_at_challengePassword
+challengePassword['values'][0] = DirectoryString()
+
+
+# Extension request
+
+class ExtensionRequest(Extensions):
+ pass
+
+
+pkcs_9_at_extensionRequest = _OID(pkcs_9, 14)
+
+extensionRequest = SingleAttribute()
+extensionRequest['type'] = pkcs_9_at_extensionRequest
+extensionRequest['values'][0] = ExtensionRequest()
+
+
+# Extended-certificate attributes (deprecated)
+
+class AttributeSet(univ.SetOf):
+ pass
+
+AttributeSet.componentType = Attribute()
+
+
+pkcs_9_at_extendedCertificateAttributes = _OID(pkcs_9, 9)
+
+extendedCertificateAttributes = SingleAttribute()
+extendedCertificateAttributes['type'] = pkcs_9_at_extendedCertificateAttributes
+extendedCertificateAttributes['values'][0] = AttributeSet()
+
+
+# Friendly name
+
+class FriendlyName(char.BMPString):
+ pass
+
+FriendlyName.subtypeSpec = constraint.ValueSizeConstraint(1, pkcs_9_ub_friendlyName)
+
+
+pkcs_9_at_friendlyName = _OID(pkcs_9, 20)
+
+friendlyName = SingleAttribute()
+friendlyName['type'] = pkcs_9_at_friendlyName
+friendlyName['values'][0] = FriendlyName()
+
+
+# Local key identifier
+
+pkcs_9_at_localKeyId = _OID(pkcs_9, 21)
+
+localKeyId = SingleAttribute()
+localKeyId['type'] = pkcs_9_at_localKeyId
+localKeyId['values'][0] = univ.OctetString()
+
+
+# Signing description
+
+pkcs_9_at_signingDescription = _OID(pkcs_9, 13)
+
+signingDescription = CMSSingleAttribute()
+signingDescription['attrType'] = pkcs_9_at_signingDescription
+signingDescription['attrValues'][0] = DirectoryString()
+
+
+# S/MIME capabilities
+
+class SMIMECapability(AlgorithmIdentifier):
+ pass
+
+
+class SMIMECapabilities(univ.SequenceOf):
+ pass
+
+SMIMECapabilities.componentType = SMIMECapability()
+
+
+pkcs_9_at_smimeCapabilities = _OID(pkcs_9, 15)
+
+smimeCapabilities = CMSSingleAttribute()
+smimeCapabilities['attrType'] = pkcs_9_at_smimeCapabilities
+smimeCapabilities['attrValues'][0] = SMIMECapabilities()
+
+
+# Certificate Attribute Map
+
+certificateAttributesMapUpdate = {
+ # Attribute types for use with the "pkcsEntity" object class
+ pkcs_9_at_pkcs7PDU: ContentInfo(),
+ pkcs_9_at_userPKCS12: PFX(),
+ # TODO: Once PKCS15Token can be imported, this can be included
+ # pkcs_9_at_pkcs15Token: PKCS15Token(),
+ pkcs_9_at_encryptedPrivateKeyInfo: EncryptedPrivateKeyInfo(),
+ # Attribute types for use with the "naturalPerson" object class
+ pkcs_9_at_emailAddress: EmailAddress(),
+ pkcs_9_at_unstructuredName: PKCS9String(),
+ pkcs_9_at_unstructuredAddress: DirectoryString(),
+ pkcs_9_at_dateOfBirth: useful.GeneralizedTime(),
+ pkcs_9_at_placeOfBirth: DirectoryString(),
+ pkcs_9_at_gender: GenderString(),
+ pkcs_9_at_countryOfCitizenship: X520countryName(),
+ pkcs_9_at_countryOfResidence: X520countryName(),
+ id_at_pseudonym: DirectoryString(),
+ id_at_serialNumber: X520SerialNumber(),
+ # Attribute types for use with PKCS #10 certificate requests
+ pkcs_9_at_challengePassword: DirectoryString(),
+ pkcs_9_at_extensionRequest: ExtensionRequest(),
+ pkcs_9_at_extendedCertificateAttributes: AttributeSet(),
+}
+
+rfc5280.certificateAttributesMap.update(certificateAttributesMapUpdate)
+
+
+# CMS Attribute Map
+
+cmsAttributesMapUpdate = {
+ # Attribute types for use in PKCS #7 data (a.k.a. CMS)
+ pkcs_9_at_contentType: ContentType(),
+ pkcs_9_at_messageDigest: MessageDigest(),
+ pkcs_9_at_signingTime: SigningTime(),
+ pkcs_9_at_randomNonce: RandomNonce(),
+ pkcs_9_at_sequenceNumber: SequenceNumber(),
+ pkcs_9_at_counterSignature: Countersignature(),
+ # Attributes for use in PKCS #12 "PFX" PDUs or PKCS #15 tokens
+ pkcs_9_at_friendlyName: FriendlyName(),
+ pkcs_9_at_localKeyId: univ.OctetString(),
+ pkcs_9_at_signingDescription: DirectoryString(),
+ pkcs_9_at_smimeCapabilities: SMIMECapabilities(),
+}
+
+rfc5652.cmsAttributesMap.update(cmsAttributesMapUpdate)
diff --git a/pyasn1_modules/rfc3770.py b/pyasn1_modules/rfc3770.py
new file mode 100644
index 0000000..a347fb3
--- /dev/null
+++ b/pyasn1_modules/rfc3770.py
@@ -0,0 +1,63 @@
+#
+# This file is part of 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
+#
+# Certificate Extensions and Attributes Supporting Authentication
+# in PPP and Wireless LAN Networks
+#
+# ASN.1 source from:
+# https://www.rfc-editor.org/rfc/rfc3770.txt
+#
+
+from pyasn1.type import constraint
+from pyasn1.type import univ
+
+from pyasn1_modules import rfc5280
+
+
+MAX = float('inf')
+
+
+# Extended Key Usage Values
+
+id_kp_eapOverLAN = univ.ObjectIdentifier('1.3.6.1.5.5.7.3.14')
+
+id_kp_eapOverPPP = univ.ObjectIdentifier('1.3.6.1.5.5.7.3.13')
+
+
+# Wireless LAN SSID Extension
+
+id_pe_wlanSSID = univ.ObjectIdentifier('1.3.6.1.5.5.7.1.13')
+
+
+class SSID(univ.OctetString):
+ pass
+
+SSID.subtypeSpec = constraint.ValueSizeConstraint(1, 32)
+
+
+class SSIDList(univ.SequenceOf):
+ pass
+
+SSIDList.componentType = SSID()
+SSIDList.subtypeSpec=constraint.ValueSizeConstraint(1, MAX)
+
+
+# Wireless LAN SSID Attribute Certificate Attribute
+# Uses same syntax as the certificate extension: SSIDList
+
+id_aca_wlanSSID = univ.ObjectIdentifier('1.3.6.1.5.5.7.10.6')
+
+
+# Map of Certificate Extension OIDs to Extensions
+# To be added to the ones that are in rfc5280.py
+
+_certificateExtensionsMap = {
+ id_pe_wlanSSID: SSIDList(),
+}
+
+rfc5280.certificateExtensionsMap.update(_certificateExtensionsMap)
diff --git a/pyasn1_modules/rfc5914.py b/pyasn1_modules/rfc5914.py
new file mode 100644
index 0000000..d125ea2
--- /dev/null
+++ b/pyasn1_modules/rfc5914.py
@@ -0,0 +1,119 @@
+# 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
+#
+# Trust Anchor Format
+#
+# ASN.1 source from:
+# https://www.rfc-editor.org/rfc/rfc5914.txt
+
+from pyasn1.type import char
+from pyasn1.type import constraint
+from pyasn1.type import namedtype
+from pyasn1.type import namedval
+from pyasn1.type import tag
+from pyasn1.type import univ
+
+from pyasn1_modules import rfc5280
+
+
+MAX = float('inf')
+
+Certificate = rfc5280.Certificate
+
+Name = rfc5280.Name
+
+Extensions = rfc5280.Extensions
+
+SubjectPublicKeyInfo = rfc5280.SubjectPublicKeyInfo
+
+TBSCertificate = rfc5280.TBSCertificate
+
+CertificatePolicies = rfc5280.CertificatePolicies
+
+KeyIdentifier = rfc5280.KeyIdentifier
+
+NameConstraints = rfc5280.NameConstraints
+
+
+class CertPolicyFlags(univ.BitString):
+ pass
+
+CertPolicyFlags.namedValues = namedval.NamedValues(
+ ('inhibitPolicyMapping', 0),
+ ('requireExplicitPolicy', 1),
+ ('inhibitAnyPolicy', 2)
+)
+
+
+class CertPathControls(univ.Sequence):
+ pass
+
+CertPathControls.componentType = namedtype.NamedTypes(
+ namedtype.NamedType('taName', Name()),
+ namedtype.OptionalNamedType('certificate', Certificate().subtype(
+ implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))),
+ namedtype.OptionalNamedType('policySet', CertificatePolicies().subtype(
+ implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))),
+ namedtype.OptionalNamedType('policyFlags', CertPolicyFlags().subtype(
+ implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 2))),
+ namedtype.OptionalNamedType('nameConstr', NameConstraints().subtype(
+ implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 3))),
+ namedtype.OptionalNamedType('pathLenConstraint', univ.Integer().subtype(
+ subtypeSpec=constraint.ValueRangeConstraint(0, MAX)).subtype(
+ implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 4)))
+)
+
+
+class TrustAnchorTitle(char.UTF8String):
+ pass
+
+TrustAnchorTitle.subtypeSpec = constraint.ValueSizeConstraint(1, 64)
+
+
+class TrustAnchorInfoVersion(univ.Integer):
+ pass
+
+TrustAnchorInfoVersion.namedValues = namedval.NamedValues(
+ ('v1', 1)
+)
+
+
+class TrustAnchorInfo(univ.Sequence):
+ pass
+
+TrustAnchorInfo.componentType = namedtype.NamedTypes(
+ namedtype.DefaultedNamedType('version', TrustAnchorInfoVersion().subtype(value='v1')),
+ namedtype.NamedType('pubKey', SubjectPublicKeyInfo()),
+ namedtype.NamedType('keyId', KeyIdentifier()),
+ namedtype.OptionalNamedType('taTitle', TrustAnchorTitle()),
+ namedtype.OptionalNamedType('certPath', CertPathControls()),
+ namedtype.OptionalNamedType('exts', Extensions().subtype(explicitTag=tag.Tag(
+ tag.tagClassContext, tag.tagFormatSimple, 1))),
+ namedtype.OptionalNamedType('taTitleLangTag', char.UTF8String().subtype(
+ implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 2)))
+)
+
+
+class TrustAnchorChoice(univ.Choice):
+ pass
+
+TrustAnchorChoice.componentType = namedtype.NamedTypes(
+ namedtype.NamedType('certificate', Certificate()),
+ namedtype.NamedType('tbsCert', TBSCertificate().subtype(
+ explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))),
+ namedtype.NamedType('taInfo', TrustAnchorInfo().subtype(
+ explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 2)))
+)
+
+
+id_ct_trustAnchorList = univ.ObjectIdentifier('1.2.840.113549.1.9.16.1.34')
+
+class TrustAnchorList(univ.SequenceOf):
+ pass
+
+TrustAnchorList.componentType = TrustAnchorChoice()
+TrustAnchorList.subtypeSpec=constraint.ValueSizeConstraint(1, MAX)
diff --git a/pyasn1_modules/rfc6010.py b/pyasn1_modules/rfc6010.py
new file mode 100644
index 0000000..250e207
--- /dev/null
+++ b/pyasn1_modules/rfc6010.py
@@ -0,0 +1,88 @@
+#
+# This file is part of pyasn1-modules software.
+#
+# Created by Russ Housley with assistance from asn1ate v.0.6.0.
+# Modified by Russ Housley to add maps for use with opentypes.
+#
+# Copyright (c) 2019, Vigil Security, LLC
+# License: http://snmplabs.com/pyasn1/license.html
+#
+# Certificate Extension for CMS Content Constraints (CCC)
+#
+# ASN.1 source from:
+# https://www.rfc-editor.org/rfc/rfc6010.txt
+#
+
+from pyasn1.type import constraint
+from pyasn1.type import namedtype
+from pyasn1.type import namedval
+from pyasn1.type import univ
+
+from pyasn1_modules import rfc5280
+
+MAX = float('inf')
+
+
+AttributeType = rfc5280.AttributeType
+
+AttributeValue = rfc5280.AttributeValue
+
+
+id_ct_anyContentType = univ.ObjectIdentifier('1.2.840.113549.1.9.16.1.0')
+
+
+class AttrConstraint(univ.Sequence):
+ pass
+
+AttrConstraint.componentType = namedtype.NamedTypes(
+ namedtype.NamedType('attrType', AttributeType()),
+ namedtype.NamedType('attrValues', univ.SetOf(
+ componentType=AttributeValue()).subtype(subtypeSpec=constraint.ValueSizeConstraint(1, MAX)))
+)
+
+
+class AttrConstraintList(univ.SequenceOf):
+ pass
+
+AttrConstraintList.componentType = AttrConstraint()
+AttrConstraintList.subtypeSpec=constraint.ValueSizeConstraint(1, MAX)
+
+
+class ContentTypeGeneration(univ.Enumerated):
+ pass
+
+ContentTypeGeneration.namedValues = namedval.NamedValues(
+ ('canSource', 0),
+ ('cannotSource', 1)
+)
+
+
+class ContentTypeConstraint(univ.Sequence):
+ pass
+
+ContentTypeConstraint.componentType = namedtype.NamedTypes(
+ namedtype.NamedType('contentType', univ.ObjectIdentifier()),
+ namedtype.DefaultedNamedType('canSource', ContentTypeGeneration().subtype(value='canSource')),
+ namedtype.OptionalNamedType('attrConstraints', AttrConstraintList())
+)
+
+
+# CMS Content Constraints (CCC) Extension and Object Identifier
+
+id_pe_cmsContentConstraints = univ.ObjectIdentifier('1.3.6.1.5.5.7.1.18')
+
+class CMSContentConstraints(univ.SequenceOf):
+ pass
+
+CMSContentConstraints.componentType = ContentTypeConstraint()
+CMSContentConstraints.subtypeSpec=constraint.ValueSizeConstraint(1, MAX)
+
+
+# Map of Certificate Extension OIDs to Extensions
+# To be added to the ones that are in rfc5280.py
+
+_certificateExtensionsMap = {
+ id_pe_cmsContentConstraints: CMSContentConstraints(),
+}
+
+rfc5280.certificateExtensionsMap.update(_certificateExtensionsMap)
diff --git a/pyasn1_modules/rfc6031.py b/pyasn1_modules/rfc6031.py
new file mode 100644
index 0000000..6e1bb22
--- /dev/null
+++ b/pyasn1_modules/rfc6031.py
@@ -0,0 +1,469 @@
+#
+# This file is part of 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
+#
+# CMS Symmetric Key Package Content Type
+#
+# ASN.1 source from:
+# https://www.rfc-editor.org/rfc/rfc6031.txt
+#
+
+from pyasn1.type import char
+from pyasn1.type import constraint
+from pyasn1.type import namedtype
+from pyasn1.type import namedval
+from pyasn1.type import opentype
+from pyasn1.type import tag
+from pyasn1.type import univ
+from pyasn1.type import useful
+
+from pyasn1_modules import rfc5652
+from pyasn1_modules import rfc6019
+
+
+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)
+
+
+MAX = float('inf')
+
+id_pskc = univ.ObjectIdentifier('1.2.840.113549.1.9.16.12')
+
+
+# Symmetric Key Package Attributes
+
+id_pskc_manufacturer = _OID(id_pskc, 1)
+
+class at_pskc_manufacturer(char.UTF8String):
+ pass
+
+
+id_pskc_serialNo = _OID(id_pskc, 2)
+
+class at_pskc_serialNo(char.UTF8String):
+ pass
+
+
+id_pskc_model = _OID(id_pskc, 3)
+
+class at_pskc_model(char.UTF8String):
+ pass
+
+
+id_pskc_issueNo = _OID(id_pskc, 4)
+
+class at_pskc_issueNo(char.UTF8String):
+ pass
+
+
+id_pskc_deviceBinding = _OID(id_pskc, 5)
+
+class at_pskc_deviceBinding(char.UTF8String):
+ pass
+
+
+id_pskc_deviceStartDate = _OID(id_pskc, 6)
+
+class at_pskc_deviceStartDate(useful.GeneralizedTime):
+ pass
+
+
+id_pskc_deviceExpiryDate = _OID(id_pskc, 7)
+
+class at_pskc_deviceExpiryDate(useful.GeneralizedTime):
+ pass
+
+
+id_pskc_moduleId = _OID(id_pskc, 8)
+
+class at_pskc_moduleId(char.UTF8String):
+ pass
+
+
+id_pskc_deviceUserId = _OID(id_pskc, 26)
+
+class at_pskc_deviceUserId(char.UTF8String):
+ pass
+
+
+# Symmetric Key Attributes
+
+id_pskc_keyId = _OID(id_pskc, 9)
+
+class at_pskc_keyUserId(char.UTF8String):
+ pass
+
+
+id_pskc_algorithm = _OID(id_pskc, 10)
+
+class at_pskc_algorithm(char.UTF8String):
+ pass
+
+
+id_pskc_issuer = _OID(id_pskc, 11)
+
+class at_pskc_issuer(char.UTF8String):
+ pass
+
+
+id_pskc_keyProfileId = _OID(id_pskc, 12)
+
+class at_pskc_keyProfileId(char.UTF8String):
+ pass
+
+
+id_pskc_keyReference = _OID(id_pskc, 13)
+
+class at_pskc_keyReference(char.UTF8String):
+ pass
+
+
+id_pskc_friendlyName = _OID(id_pskc, 14)
+
+class FriendlyName(univ.Sequence):
+ pass
+
+FriendlyName.componentType = namedtype.NamedTypes(
+ namedtype.NamedType('friendlyName', char.UTF8String()),
+ namedtype.OptionalNamedType('friendlyNameLangTag', char.UTF8String())
+)
+
+class at_pskc_friendlyName(FriendlyName):
+ pass
+
+
+id_pskc_algorithmParameters = _OID(id_pskc, 15)
+
+class Encoding(char.UTF8String):
+ pass
+
+Encoding.namedValues = namedval.NamedValues(
+ ('dec', "DECIMAL"),
+ ('hex', "HEXADECIMAL"),
+ ('alpha', "ALPHANUMERIC"),
+ ('b64', "BASE64"),
+ ('bin', "BINARY")
+)
+
+Encoding.subtypeSpec = constraint.SingleValueConstraint(
+ "DECIMAL", "HEXADECIMAL", "ALPHANUMERIC", "BASE64", "BINARY" )
+
+class ChallengeFormat(univ.Sequence):
+ pass
+
+ChallengeFormat.componentType = namedtype.NamedTypes(
+ namedtype.NamedType('encoding', Encoding()),
+ namedtype.DefaultedNamedType('checkDigit',
+ univ.Boolean().subtype(value=0)),
+ namedtype.NamedType('min', univ.Integer().subtype(
+ subtypeSpec=constraint.ValueRangeConstraint(0, MAX))),
+ namedtype.NamedType('max', univ.Integer().subtype(
+ subtypeSpec=constraint.ValueRangeConstraint(0, MAX)))
+)
+
+class ResponseFormat(univ.Sequence):
+ pass
+
+ResponseFormat.componentType = namedtype.NamedTypes(
+ namedtype.NamedType('encoding', Encoding()),
+ namedtype.NamedType('length', univ.Integer().subtype(
+ subtypeSpec=constraint.ValueRangeConstraint(0, MAX))),
+ namedtype.DefaultedNamedType('checkDigit',
+ univ.Boolean().subtype(value=0))
+)
+
+class PSKCAlgorithmParameters(univ.Choice):
+ pass
+
+PSKCAlgorithmParameters.componentType = namedtype.NamedTypes(
+ namedtype.NamedType('suite', char.UTF8String()),
+ namedtype.NamedType('challengeFormat', ChallengeFormat().subtype(
+ implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 0))),
+ namedtype.NamedType('responseFormat', ResponseFormat().subtype(
+ implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 1)))
+)
+
+class at_pskc_algorithmParameters(PSKCAlgorithmParameters):
+ pass
+
+
+id_pskc_counter = _OID(id_pskc, 16)
+
+class at_pskc_counter(univ.Integer):
+ pass
+
+at_pskc_counter.subtypeSpec = constraint.ValueRangeConstraint(0, MAX)
+
+
+id_pskc_time = _OID(id_pskc, 17)
+
+class at_pskc_time(rfc6019.BinaryTime):
+ pass
+
+
+id_pskc_timeInterval = _OID(id_pskc, 18)
+
+class at_pskc_timeInterval(univ.Integer):
+ pass
+
+at_pskc_timeInterval.subtypeSpec = constraint.ValueRangeConstraint(0, MAX)
+
+
+id_pskc_timeDrift = _OID(id_pskc, 19)
+
+class at_pskc_timeDrift(univ.Integer):
+ pass
+
+at_pskc_timeDrift.subtypeSpec = constraint.ValueRangeConstraint(0, MAX)
+
+
+id_pskc_valueMAC = _OID(id_pskc, 20)
+
+class ValueMac(univ.Sequence):
+ pass
+
+ValueMac.componentType = namedtype.NamedTypes(
+ namedtype.NamedType('macAlgorithm', char.UTF8String()),
+ namedtype.NamedType('mac', char.UTF8String())
+)
+
+class at_pskc_valueMAC(ValueMac):
+ pass
+
+
+id_pskc_keyUserId = _OID(id_pskc, 27)
+
+class at_pskc_keyId(char.UTF8String):
+ pass
+
+
+id_pskc_keyStartDate = _OID(id_pskc, 21)
+
+class at_pskc_keyStartDate(useful.GeneralizedTime):
+ pass
+
+
+id_pskc_keyExpiryDate = _OID(id_pskc, 22)
+
+class at_pskc_keyExpiryDate(useful.GeneralizedTime):
+ pass
+
+
+id_pskc_numberOfTransactions = _OID(id_pskc, 23)
+
+class at_pskc_numberOfTransactions(univ.Integer):
+ pass
+
+at_pskc_numberOfTransactions.subtypeSpec = constraint.ValueRangeConstraint(0, MAX)
+
+
+id_pskc_keyUsages = _OID(id_pskc, 24)
+
+class PSKCKeyUsage(char.UTF8String):
+ pass
+
+PSKCKeyUsage.namedValues = namedval.NamedValues(
+ ('otp', "OTP"),
+ ('cr', "CR"),
+ ('encrypt', "Encrypt"),
+ ('integrity', "Integrity"),
+ ('verify', "Verify"),
+ ('unlock', "Unlock"),
+ ('decrypt', "Decrypt"),
+ ('keywrap', "KeyWrap"),
+ ('unwrap', "Unwrap"),
+ ('derive', "Derive"),
+ ('generate', "Generate")
+)
+
+PSKCKeyUsage.subtypeSpec = constraint.SingleValueConstraint(
+ "OTP", "CR", "Encrypt", "Integrity", "Verify", "Unlock",
+ "Decrypt", "KeyWrap", "Unwrap", "Derive", "Generate" )
+
+class PSKCKeyUsages(univ.SequenceOf):
+ pass
+
+PSKCKeyUsages.componentType = PSKCKeyUsage()
+
+class at_pskc_keyUsage(PSKCKeyUsages):
+ pass
+
+
+id_pskc_pinPolicy = _OID(id_pskc, 25)
+
+class PINUsageMode(char.UTF8String):
+ pass
+
+PINUsageMode.namedValues = namedval.NamedValues(
+ ("local", "Local"),
+ ("prepend", "Prepend"),
+ ("append", "Append"),
+ ("algorithmic", "Algorithmic")
+)
+
+PINUsageMode.subtypeSpec = constraint.SingleValueConstraint(
+ "Local", "Prepend", "Append", "Algorithmic" )
+
+class PINPolicy(univ.Sequence):
+ pass
+
+PINPolicy.componentType = namedtype.NamedTypes(
+ namedtype.OptionalNamedType('pinKeyId', char.UTF8String().subtype(
+ implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))),
+ namedtype.NamedType('pinUsageMode', PINUsageMode().subtype(
+ implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))),
+ namedtype.OptionalNamedType('maxFailedAttempts', univ.Integer().subtype(
+ subtypeSpec=constraint.ValueRangeConstraint(0, MAX)).subtype(
+ implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 2))),
+ namedtype.OptionalNamedType('minLength', univ.Integer().subtype(
+ subtypeSpec=constraint.ValueRangeConstraint(0, MAX)).subtype(
+ implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 3))),
+ namedtype.OptionalNamedType('maxLength', univ.Integer().subtype(
+ subtypeSpec=constraint.ValueRangeConstraint(0, MAX)).subtype(
+ implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 4))),
+ namedtype.OptionalNamedType('pinEncoding', Encoding().subtype(
+ implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 5)))
+)
+
+class at_pskc_pinPolicy(PINPolicy):
+ pass
+
+
+# Map of Symmetric Key Package Attribute OIDs to Attributes
+
+sKeyPkgAttributesMap = {
+ id_pskc_manufacturer: at_pskc_manufacturer(),
+ id_pskc_serialNo: at_pskc_serialNo(),
+ id_pskc_model: at_pskc_model(),
+ id_pskc_issueNo: at_pskc_issueNo(),
+ id_pskc_deviceBinding: at_pskc_deviceBinding(),
+ id_pskc_deviceStartDate: at_pskc_deviceStartDate(),
+ id_pskc_deviceExpiryDate: at_pskc_deviceExpiryDate(),
+ id_pskc_moduleId: at_pskc_moduleId(),
+ id_pskc_deviceUserId: at_pskc_deviceUserId(),
+}
+
+
+# Map of Symmetric Key Attribute OIDs to Attributes
+
+sKeyAttributesMap = {
+ id_pskc_keyId: at_pskc_keyId(),
+ id_pskc_algorithm: at_pskc_algorithm(),
+ id_pskc_issuer: at_pskc_issuer(),
+ id_pskc_keyProfileId: at_pskc_keyProfileId(),
+ id_pskc_keyReference: at_pskc_keyReference(),
+ id_pskc_friendlyName: at_pskc_friendlyName(),
+ id_pskc_algorithmParameters: at_pskc_algorithmParameters(),
+ id_pskc_counter: at_pskc_counter(),
+ id_pskc_time: at_pskc_time(),
+ id_pskc_timeInterval: at_pskc_timeInterval(),
+ id_pskc_timeDrift: at_pskc_timeDrift(),
+ id_pskc_valueMAC: at_pskc_valueMAC(),
+ id_pskc_keyUserId: at_pskc_keyUserId(),
+ id_pskc_keyStartDate: at_pskc_keyStartDate(),
+ id_pskc_keyExpiryDate: at_pskc_keyExpiryDate(),
+ id_pskc_numberOfTransactions: at_pskc_numberOfTransactions(),
+ id_pskc_keyUsages: at_pskc_keyUsage(),
+ id_pskc_pinPolicy: at_pskc_pinPolicy(),
+}
+
+
+# This definition replaces Attribute() from rfc5652.py; it is the same except
+# that opentype is added with sKeyPkgAttributesMap and sKeyAttributesMap
+
+class AttributeType(univ.ObjectIdentifier):
+ pass
+
+
+class AttributeValue(univ.Any):
+ pass
+
+
+class SKeyAttribute(univ.Sequence):
+ pass
+
+SKeyAttribute.componentType = namedtype.NamedTypes(
+ namedtype.NamedType('attrType', AttributeType()),
+ namedtype.NamedType('attrValues',
+ univ.SetOf(componentType=AttributeValue()),
+ openType=opentype.OpenType('attrType', sKeyAttributesMap)
+ )
+)
+
+
+class SKeyPkgAttribute(univ.Sequence):
+ pass
+
+SKeyPkgAttribute.componentType = namedtype.NamedTypes(
+ namedtype.NamedType('attrType', AttributeType()),
+ namedtype.NamedType('attrValues',
+ univ.SetOf(componentType=AttributeValue()),
+ openType=opentype.OpenType('attrType', sKeyPkgAttributesMap)
+ )
+)
+
+
+# Symmetric Key Package Content Type
+
+id_ct_KP_sKeyPackage = univ.ObjectIdentifier('1.2.840.113549.1.9.16.1.25')
+
+
+class KeyPkgVersion(univ.Integer):
+ pass
+
+KeyPkgVersion.namedValues = namedval.NamedValues(
+ ('v1', 1)
+)
+
+
+class OneSymmetricKey(univ.Sequence):
+ pass
+
+OneSymmetricKey.componentType = namedtype.NamedTypes(
+ namedtype.OptionalNamedType('sKeyAttrs',
+ univ.SequenceOf(componentType=SKeyAttribute()).subtype(
+ subtypeSpec=constraint.ValueSizeConstraint(1, MAX))),
+ namedtype.OptionalNamedType('sKey', univ.OctetString())
+)
+
+OneSymmetricKey.sizeSpec = univ.Sequence.sizeSpec + constraint.ValueSizeConstraint(1, 2)
+
+
+class SymmetricKeys(univ.SequenceOf):
+ pass
+
+SymmetricKeys.componentType = OneSymmetricKey()
+SymmetricKeys.subtypeSpec=constraint.ValueSizeConstraint(1, MAX)
+
+
+class SymmetricKeyPackage(univ.Sequence):
+ pass
+
+SymmetricKeyPackage.componentType = namedtype.NamedTypes(
+ namedtype.DefaultedNamedType('version', KeyPkgVersion().subtype(value='v1')),
+ namedtype.OptionalNamedType('sKeyPkgAttrs',
+ univ.SequenceOf(componentType=SKeyPkgAttribute()).subtype(
+ subtypeSpec=constraint.ValueSizeConstraint(1, MAX),
+ implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))),
+ namedtype.NamedType('sKeys', SymmetricKeys())
+)
+
+
+# Map of Content Type OIDs to Content Types are
+# added to the ones that are in rfc5652.py
+
+_cmsContentTypesMapUpdate = {
+ id_ct_KP_sKeyPackage: SymmetricKeyPackage(),
+}
+
+rfc5652.cmsContentTypesMap.update(_cmsContentTypesMapUpdate)
diff --git a/pyasn1_modules/rfc6032.py b/pyasn1_modules/rfc6032.py
new file mode 100644
index 0000000..563639a
--- /dev/null
+++ b/pyasn1_modules/rfc6032.py
@@ -0,0 +1,68 @@
+#
+# This file is part of 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
+#
+# CMS Encrypted Key Package Content Type
+#
+# ASN.1 source from:
+# https://www.rfc-editor.org/rfc/rfc6032.txt
+#
+
+from pyasn1.type import namedtype
+from pyasn1.type import tag
+from pyasn1.type import univ
+
+from pyasn1_modules import rfc5652
+from pyasn1_modules import rfc5083
+
+
+# Content Decryption Key Identifier attribute
+
+id_aa_KP_contentDecryptKeyID = univ.ObjectIdentifier('2.16.840.1.101.2.1.5.66')
+
+class ContentDecryptKeyID(univ.OctetString):
+ pass
+
+aa_content_decrypt_key_identifier = rfc5652.Attribute()
+aa_content_decrypt_key_identifier['attrType'] = id_aa_KP_contentDecryptKeyID
+aa_content_decrypt_key_identifier['attrValues'][0] = ContentDecryptKeyID()
+
+
+# Encrypted Key Package Content Type
+
+id_ct_KP_encryptedKeyPkg = univ.ObjectIdentifier('2.16.840.1.101.2.1.2.78.2')
+
+class EncryptedKeyPackage(univ.Choice):
+ pass
+
+EncryptedKeyPackage.componentType = namedtype.NamedTypes(
+ namedtype.NamedType('encrypted', rfc5652.EncryptedData()),
+ namedtype.NamedType('enveloped', rfc5652.EnvelopedData().subtype(
+ implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))),
+ namedtype.NamedType('authEnveloped', rfc5083.AuthEnvelopedData().subtype(
+ implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1)))
+)
+
+
+# Map of Attribute Type OIDs to Attributes are
+# added to the ones that are in rfc5652.py
+
+_cmsAttributesMapUpdate = {
+ id_aa_KP_contentDecryptKeyID: ContentDecryptKeyID(),
+}
+
+rfc5652.cmsAttributesMap.update(_cmsAttributesMapUpdate)
+
+
+# Map of Content Type OIDs to Content Types are
+# added to the ones that are in rfc5652.py
+
+_cmsContentTypesMapUpdate = {
+ id_ct_KP_encryptedKeyPkg: EncryptedKeyPackage(),
+}
+
+rfc5652.cmsContentTypesMap.update(_cmsContentTypesMapUpdate)
diff --git a/pyasn1_modules/rfc7030.py b/pyasn1_modules/rfc7030.py
new file mode 100644
index 0000000..84b6dc5
--- /dev/null
+++ b/pyasn1_modules/rfc7030.py
@@ -0,0 +1,66 @@
+#
+# This file is part of 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
+#
+# Enrollment over Secure Transport (EST)
+#
+# ASN.1 source from:
+# https://www.rfc-editor.org/rfc/rfc7030.txt
+#
+
+from pyasn1.type import constraint
+from pyasn1.type import namedtype
+from pyasn1.type import univ
+
+from pyasn1_modules import rfc5652
+
+MAX = float('inf')
+
+
+# Imports from RFC 5652
+
+Attribute = rfc5652.Attribute
+
+
+# Asymmetric Decrypt Key Identifier Attribute
+
+id_aa_asymmDecryptKeyID = univ.ObjectIdentifier('1.2.840.113549.1.9.16.2.54')
+
+class AsymmetricDecryptKeyIdentifier(univ.OctetString):
+ pass
+
+
+aa_asymmDecryptKeyID = Attribute()
+aa_asymmDecryptKeyID['attrType'] = id_aa_asymmDecryptKeyID
+aa_asymmDecryptKeyID['attrValues'][0] = AsymmetricDecryptKeyIdentifier()
+
+
+# CSR Attributes
+
+class AttrOrOID(univ.Choice):
+ pass
+
+AttrOrOID.componentType = namedtype.NamedTypes(
+ namedtype.NamedType('oid', univ.ObjectIdentifier()),
+ namedtype.NamedType('attribute', Attribute())
+)
+
+
+class CsrAttrs(univ.SequenceOf):
+ pass
+
+CsrAttrs.componentType = AttrOrOID()
+CsrAttrs.subtypeSpec=constraint.ValueSizeConstraint(0, MAX)
+
+
+# Update CMS Attribute Map
+
+_cmsAttributesMapUpdate = {
+ id_aa_asymmDecryptKeyID: AsymmetricDecryptKeyIdentifier(),
+}
+
+rfc5652.cmsAttributesMap.update(_cmsAttributesMapUpdate)
diff --git a/pyasn1_modules/rfc7292.py b/pyasn1_modules/rfc7292.py
new file mode 100644
index 0000000..1c9f319
--- /dev/null
+++ b/pyasn1_modules/rfc7292.py
@@ -0,0 +1,357 @@
+# This file is being contributed to pyasn1-modules software.
+#
+# Created by Russ Housley with assistance from the asn1ate tool.
+#
+# Copyright (c) 2019, Vigil Security, LLC
+# License: http://snmplabs.com/pyasn1/license.html
+#
+# PKCS #12: Personal Information Exchange Syntax v1.1
+#
+# ASN.1 source from:
+# https://www.rfc-editor.org/rfc/rfc7292.txt
+# https://www.rfc-editor.org/errata_search.php?rfc=7292
+
+from pyasn1.type import char
+from pyasn1.type import constraint
+from pyasn1.type import namedtype
+from pyasn1.type import namedval
+from pyasn1.type import opentype
+from pyasn1.type import tag
+from pyasn1.type import univ
+
+from pyasn1_modules import rfc2315
+from pyasn1_modules import rfc5652
+from pyasn1_modules import rfc5280
+from pyasn1_modules import rfc5958
+
+
+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)
+
+
+# Initialize the maps used in PKCS#12
+
+pkcs12BagTypeMap = { }
+
+pkcs12CertBagMap = { }
+
+pkcs12CRLBagMap = { }
+
+pkcs12SecretBagMap = { }
+
+
+# Imports from RFC 2315, RFC 5652, and RFC 5958
+
+DigestInfo = rfc2315.DigestInfo
+
+
+ContentInfo = rfc5652.ContentInfo
+
+PKCS12Attribute = rfc5652.Attribute
+
+
+EncryptedPrivateKeyInfo = rfc5958.EncryptedPrivateKeyInfo
+
+PrivateKeyInfo = rfc5958.PrivateKeyInfo
+
+
+# CMSSingleAttribute is the same as Attribute in RFC 5652 except the attrValues
+# SET must have one and only one member
+
+class AttributeType(univ.ObjectIdentifier):
+ pass
+
+
+class AttributeValue(univ.Any):
+ pass
+
+
+class AttributeValues(univ.SetOf):
+ pass
+
+AttributeValues.componentType = AttributeValue()
+
+
+class CMSSingleAttribute(univ.Sequence):
+ pass
+
+CMSSingleAttribute.componentType = namedtype.NamedTypes(
+ namedtype.NamedType('attrType', AttributeType()),
+ namedtype.NamedType('attrValues',
+ AttributeValues().subtype(sizeSpec=constraint.ValueSizeConstraint(1, 1)),
+ openType=opentype.OpenType('attrType', rfc5652.cmsAttributesMap)
+ )
+)
+
+
+# Object identifier arcs
+
+rsadsi = _OID(1, 2, 840, 113549)
+
+pkcs = _OID(rsadsi, 1)
+
+pkcs_9 = _OID(pkcs, 9)
+
+certTypes = _OID(pkcs_9, 22)
+
+crlTypes = _OID(pkcs_9, 23)
+
+pkcs_12 = _OID(pkcs, 12)
+
+
+# PBE Algorithm Identifiers and Parameters Structure
+
+pkcs_12PbeIds = _OID(pkcs_12, 1)
+
+pbeWithSHAAnd128BitRC4 = _OID(pkcs_12PbeIds, 1)
+
+pbeWithSHAAnd40BitRC4 = _OID(pkcs_12PbeIds, 2)
+
+pbeWithSHAAnd3_KeyTripleDES_CBC = _OID(pkcs_12PbeIds, 3)
+
+pbeWithSHAAnd2_KeyTripleDES_CBC = _OID(pkcs_12PbeIds, 4)
+
+pbeWithSHAAnd128BitRC2_CBC = _OID(pkcs_12PbeIds, 5)
+
+pbeWithSHAAnd40BitRC2_CBC = _OID(pkcs_12PbeIds, 6)
+
+
+class Pkcs_12PbeParams(univ.Sequence):
+ pass
+
+Pkcs_12PbeParams.componentType = namedtype.NamedTypes(
+ namedtype.NamedType('salt', univ.OctetString()),
+ namedtype.NamedType('iterations', univ.Integer())
+)
+
+
+# Bag types
+
+bagtypes = _OID(pkcs_12, 10, 1)
+
+class BAG_TYPE(univ.Sequence):
+ pass
+
+BAG_TYPE.componentType = namedtype.NamedTypes(
+ namedtype.NamedType('id', univ.ObjectIdentifier()),
+ namedtype.NamedType('unnamed1', univ.Any(),
+ openType=opentype.OpenType('attrType', pkcs12BagTypeMap)
+ )
+)
+
+
+id_keyBag = _OID(bagtypes, 1)
+
+class KeyBag(PrivateKeyInfo):
+ pass
+
+
+id_pkcs8ShroudedKeyBag = _OID(bagtypes, 2)
+
+class PKCS8ShroudedKeyBag(EncryptedPrivateKeyInfo):
+ pass
+
+
+id_certBag = _OID(bagtypes, 3)
+
+class CertBag(univ.Sequence):
+ pass
+
+CertBag.componentType = namedtype.NamedTypes(
+ namedtype.NamedType('certId', univ.ObjectIdentifier()),
+ namedtype.NamedType('certValue',
+ univ.Any().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0)),
+ openType=opentype.OpenType('certId', pkcs12CertBagMap)
+ )
+)
+
+
+x509Certificate = CertBag()
+x509Certificate['certId'] = _OID(certTypes, 1)
+x509Certificate['certValue'] = univ.OctetString()
+# DER-encoded X.509 certificate stored in OCTET STRING
+
+
+sdsiCertificate = CertBag()
+sdsiCertificate['certId'] = _OID(certTypes, 2)
+sdsiCertificate['certValue'] = char.IA5String()
+# Base64-encoded SDSI certificate stored in IA5String
+
+
+id_CRLBag = _OID(bagtypes, 4)
+
+class CRLBag(univ.Sequence):
+ pass
+
+CRLBag.componentType = namedtype.NamedTypes(
+ namedtype.NamedType('crlId', univ.ObjectIdentifier()),
+ namedtype.NamedType('crlValue',
+ univ.Any().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0)),
+ openType=opentype.OpenType('crlId', pkcs12CRLBagMap)
+ )
+)
+
+
+x509CRL = CRLBag()
+x509CRL['crlId'] = _OID(crlTypes, 1)
+x509CRL['crlValue'] = univ.OctetString()
+# DER-encoded X.509 CRL stored in OCTET STRING
+
+
+id_secretBag = _OID(bagtypes, 5)
+
+class SecretBag(univ.Sequence):
+ pass
+
+SecretBag.componentType = namedtype.NamedTypes(
+ namedtype.NamedType('secretTypeId', univ.ObjectIdentifier()),
+ namedtype.NamedType('secretValue',
+ univ.Any().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0)),
+ openType=opentype.OpenType('secretTypeId', pkcs12SecretBagMap)
+ )
+)
+
+
+id_safeContentsBag = _OID(bagtypes, 6)
+
+class SafeBag(univ.Sequence):
+ pass
+
+SafeBag.componentType = namedtype.NamedTypes(
+ namedtype.NamedType('bagId', univ.ObjectIdentifier()),
+ namedtype.NamedType('bagValue',
+ univ.Any().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0)),
+ openType=opentype.OpenType('bagId', pkcs12BagTypeMap)
+ ),
+ namedtype.OptionalNamedType('bagAttributes',
+ univ.SetOf(componentType=PKCS12Attribute())
+ )
+)
+
+
+class SafeContents(univ.SequenceOf):
+ pass
+
+SafeContents.componentType = SafeBag()
+
+
+# The PFX PDU
+
+class AuthenticatedSafe(univ.SequenceOf):
+ pass
+
+AuthenticatedSafe.componentType = ContentInfo()
+# Data if unencrypted
+# EncryptedData if password-encrypted
+# EnvelopedData if public key-encrypted
+
+
+class MacData(univ.Sequence):
+ pass
+
+MacData.componentType = namedtype.NamedTypes(
+ namedtype.NamedType('mac', DigestInfo()),
+ namedtype.NamedType('macSalt', univ.OctetString()),
+ namedtype.DefaultedNamedType('iterations', univ.Integer().subtype(value=1))
+ # Note: The default is for historical reasons and its use is deprecated
+)
+
+
+class PFX(univ.Sequence):
+ pass
+
+PFX.componentType = namedtype.NamedTypes(
+ namedtype.NamedType('version',
+ univ.Integer(namedValues=namedval.NamedValues(('v3', 3)))
+ ),
+ namedtype.NamedType('authSafe', ContentInfo()),
+ namedtype.OptionalNamedType('macData', MacData())
+)
+
+
+# Local key identifier (also defined as certificateAttribute in rfc2985.py)
+
+pkcs_9_at_localKeyId = _OID(pkcs_9, 21)
+
+localKeyId = CMSSingleAttribute()
+localKeyId['attrType'] = pkcs_9_at_localKeyId
+localKeyId['attrValues'][0] = univ.OctetString()
+
+
+# Friendly name (also defined as certificateAttribute in rfc2985.py)
+
+pkcs_9_ub_pkcs9String = univ.Integer(255)
+
+pkcs_9_ub_friendlyName = univ.Integer(pkcs_9_ub_pkcs9String)
+
+pkcs_9_at_friendlyName = _OID(pkcs_9, 20)
+
+class FriendlyName(char.BMPString):
+ pass
+
+FriendlyName.subtypeSpec = constraint.ValueSizeConstraint(1, pkcs_9_ub_friendlyName)
+
+
+friendlyName = CMSSingleAttribute()
+friendlyName['attrType'] = pkcs_9_at_friendlyName
+friendlyName['attrValues'][0] = FriendlyName()
+
+
+# Update the PKCS#12 maps
+
+_pkcs12BagTypeMap = {
+ id_keyBag: KeyBag(),
+ id_pkcs8ShroudedKeyBag: PKCS8ShroudedKeyBag(),
+ id_certBag: CertBag(),
+ id_CRLBag: CRLBag(),
+ id_secretBag: SecretBag(),
+ id_safeContentsBag: SafeBag(),
+}
+
+pkcs12BagTypeMap.update(_pkcs12BagTypeMap)
+
+
+_pkcs12CertBagMap = {
+ _OID(certTypes, 1): univ.OctetString(),
+ _OID(certTypes, 2): char.IA5String(),
+}
+
+pkcs12CertBagMap.update(_pkcs12CertBagMap)
+
+
+_pkcs12CRLBagMap = {
+ _OID(crlTypes, 1): univ.OctetString(),
+}
+
+pkcs12CRLBagMap.update(_pkcs12CRLBagMap)
+
+
+# Update the Algorithm Identifier map
+
+_algorithmIdentifierMapUpdate = {
+ pbeWithSHAAnd128BitRC4: Pkcs_12PbeParams(),
+ pbeWithSHAAnd40BitRC4: Pkcs_12PbeParams(),
+ pbeWithSHAAnd3_KeyTripleDES_CBC: Pkcs_12PbeParams(),
+ pbeWithSHAAnd2_KeyTripleDES_CBC: Pkcs_12PbeParams(),
+ pbeWithSHAAnd128BitRC2_CBC: Pkcs_12PbeParams(),
+ pbeWithSHAAnd40BitRC2_CBC: Pkcs_12PbeParams(),
+}
+
+rfc5280.algorithmIdentifierMap.update(_algorithmIdentifierMapUpdate)
+
+
+# Update the CMS Attribute map
+
+_cmsAttributesMapUpdate = {
+ pkcs_9_at_friendlyName: FriendlyName(),
+ pkcs_9_at_localKeyId: univ.OctetString(),
+}
+
+rfc5652.cmsAttributesMap.update(_cmsAttributesMapUpdate)
diff --git a/pyasn1_modules/rfc8018.py b/pyasn1_modules/rfc8018.py
new file mode 100644
index 0000000..7a44eea
--- /dev/null
+++ b/pyasn1_modules/rfc8018.py
@@ -0,0 +1,260 @@
+#
+# This file is part of pyasn1-modules software.
+#
+# Created by Russ Housley.
+#
+# Copyright (c) 2019, Vigil Security, LLC
+# License: http://snmplabs.com/pyasn1/license.html
+#
+# PKCS #5: Password-Based Cryptography Specification, Version 2.1
+#
+# ASN.1 source from:
+# https://www.rfc-editor.org/rfc/rfc8018.txt
+#
+
+from pyasn1.type import constraint
+from pyasn1.type import namedtype
+from pyasn1.type import namedval
+from pyasn1.type import univ
+
+from pyasn1_modules import rfc3565
+from pyasn1_modules import rfc5280
+
+MAX = float('inf')
+
+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)
+
+
+# Import from RFC 3565
+
+AES_IV = rfc3565.AES_IV
+
+
+# Import from RFC 5280
+
+AlgorithmIdentifier = rfc5280.AlgorithmIdentifier
+
+
+# Basic object identifiers
+
+nistAlgorithms = _OID(2, 16, 840, 1, 101, 3, 4)
+
+aes = _OID(nistAlgorithms, 1)
+
+oiw = _OID(1, 3, 14)
+
+rsadsi = _OID(1, 2, 840, 113549)
+
+pkcs = _OID(rsadsi, 1)
+
+digestAlgorithm = _OID(rsadsi, 2)
+
+encryptionAlgorithm = _OID(rsadsi, 3)
+
+pkcs_5 = _OID(pkcs, 5)
+
+
+
+# HMAC object identifiers
+
+id_hmacWithSHA1 = _OID(digestAlgorithm, 7)
+
+id_hmacWithSHA224 = _OID(digestAlgorithm, 8)
+
+id_hmacWithSHA256 = _OID(digestAlgorithm, 9)
+
+id_hmacWithSHA384 = _OID(digestAlgorithm, 10)
+
+id_hmacWithSHA512 = _OID(digestAlgorithm, 11)
+
+id_hmacWithSHA512_224 = _OID(digestAlgorithm, 12)
+
+id_hmacWithSHA512_256 = _OID(digestAlgorithm, 13)
+
+
+# PBES1 object identifiers
+
+pbeWithMD2AndDES_CBC = _OID(pkcs_5, 1)
+
+pbeWithMD2AndRC2_CBC = _OID(pkcs_5, 4)
+
+pbeWithMD5AndDES_CBC = _OID(pkcs_5, 3)
+
+pbeWithMD5AndRC2_CBC = _OID(pkcs_5, 6)
+
+pbeWithSHA1AndDES_CBC = _OID(pkcs_5, 10)
+
+pbeWithSHA1AndRC2_CBC = _OID(pkcs_5, 11)
+
+
+# Supporting techniques object identifiers
+
+desCBC = _OID(oiw, 3, 2, 7)
+
+des_EDE3_CBC = _OID(encryptionAlgorithm, 7)
+
+rc2CBC = _OID(encryptionAlgorithm, 2)
+
+rc5_CBC_PAD = _OID(encryptionAlgorithm, 9)
+
+aes128_CBC_PAD = _OID(aes, 2)
+
+aes192_CBC_PAD = _OID(aes, 22)
+
+aes256_CBC_PAD = _OID(aes, 42)
+
+
+# PBES1
+
+class PBEParameter(univ.Sequence):
+ pass
+
+PBEParameter.componentType = namedtype.NamedTypes(
+ namedtype.NamedType('salt', univ.OctetString().subtype(
+ subtypeSpec=constraint.ValueSizeConstraint(8, 8))),
+ namedtype.NamedType('iterationCount', univ.Integer())
+)
+
+
+# PBES2
+
+id_PBES2 = _OID(pkcs_5, 13)
+
+
+class PBES2_params(univ.Sequence):
+ pass
+
+PBES2_params.componentType = namedtype.NamedTypes(
+ namedtype.NamedType('keyDerivationFunc', AlgorithmIdentifier()),
+ namedtype.NamedType('encryptionScheme', AlgorithmIdentifier())
+)
+
+
+# PBMAC1
+
+id_PBMAC1 = _OID(pkcs_5, 14)
+
+
+class PBMAC1_params(univ.Sequence):
+ pass
+
+PBMAC1_params.componentType = namedtype.NamedTypes(
+ namedtype.NamedType('keyDerivationFunc', AlgorithmIdentifier()),
+ namedtype.NamedType('messageAuthScheme', AlgorithmIdentifier())
+)
+
+
+# PBKDF2
+
+id_PBKDF2 = _OID(pkcs_5, 12)
+
+
+algid_hmacWithSHA1 = AlgorithmIdentifier()
+algid_hmacWithSHA1['algorithm'] = id_hmacWithSHA1
+algid_hmacWithSHA1['parameters'] = univ.Null("")
+
+
+class PBKDF2_params(univ.Sequence):
+ pass
+
+PBKDF2_params.componentType = namedtype.NamedTypes(
+ namedtype.NamedType('salt', univ.Choice(componentType=namedtype.NamedTypes(
+ namedtype.NamedType('specified', univ.OctetString()),
+ namedtype.NamedType('otherSource', AlgorithmIdentifier())
+ ))),
+ namedtype.NamedType('iterationCount', univ.Integer().subtype(
+ subtypeSpec=constraint.ValueRangeConstraint(1, MAX))),
+ namedtype.OptionalNamedType('keyLength', univ.Integer().subtype(
+ subtypeSpec=constraint.ValueRangeConstraint(1, MAX))),
+ namedtype.DefaultedNamedType('prf', algid_hmacWithSHA1)
+)
+
+
+# RC2 CBC algorithm parameter
+
+class RC2_CBC_Parameter(univ.Sequence):
+ pass
+
+RC2_CBC_Parameter.componentType = namedtype.NamedTypes(
+ namedtype.OptionalNamedType('rc2ParameterVersion', univ.Integer()),
+ namedtype.NamedType('iv', univ.OctetString().subtype(
+ subtypeSpec=constraint.ValueSizeConstraint(8, 8)))
+)
+
+
+# RC5 CBC algorithm parameter
+
+class RC5_CBC_Parameters(univ.Sequence):
+ pass
+
+RC5_CBC_Parameters.componentType = namedtype.NamedTypes(
+ namedtype.NamedType('version',
+ univ.Integer(namedValues=namedval.NamedValues(('v1_0', 16))).subtype(
+ subtypeSpec=constraint.SingleValueConstraint(16))),
+ namedtype.NamedType('rounds',
+ univ.Integer().subtype(subtypeSpec=constraint.ValueRangeConstraint(8, 127))),
+ namedtype.NamedType('blockSizeInBits',
+ univ.Integer().subtype(subtypeSpec=constraint.SingleValueConstraint(64, 128))),
+ namedtype.OptionalNamedType('iv', univ.OctetString())
+)
+
+
+# Initialization Vector for AES: OCTET STRING (SIZE(16))
+
+class AES_IV(univ.OctetString):
+ pass
+
+AES_IV.subtypeSpec = constraint.ValueSizeConstraint(16, 16)
+
+
+# Initialization Vector for DES: OCTET STRING (SIZE(8))
+
+class DES_IV(univ.OctetString):
+ pass
+
+DES_IV.subtypeSpec = constraint.ValueSizeConstraint(8, 8)
+
+
+# Update the Algorithm Identifier map
+
+_algorithmIdentifierMapUpdate = {
+ # PBKDF2-PRFs
+ id_hmacWithSHA1: univ.Null(),
+ id_hmacWithSHA224: univ.Null(),
+ id_hmacWithSHA256: univ.Null(),
+ id_hmacWithSHA384: univ.Null(),
+ id_hmacWithSHA512: univ.Null(),
+ id_hmacWithSHA512_224: univ.Null(),
+ id_hmacWithSHA512_256: univ.Null(),
+ # PBES1Algorithms
+ pbeWithMD2AndDES_CBC: PBEParameter(),
+ pbeWithMD2AndRC2_CBC: PBEParameter(),
+ pbeWithMD5AndDES_CBC: PBEParameter(),
+ pbeWithMD5AndRC2_CBC: PBEParameter(),
+ pbeWithSHA1AndDES_CBC: PBEParameter(),
+ pbeWithSHA1AndRC2_CBC: PBEParameter(),
+ # PBES2Algorithms
+ id_PBES2: PBES2_params(),
+ # PBES2-KDFs
+ id_PBKDF2: PBKDF2_params(),
+ # PBMAC1Algorithms
+ id_PBMAC1: PBMAC1_params(),
+ # SupportingAlgorithms
+ desCBC: DES_IV(),
+ des_EDE3_CBC: DES_IV(),
+ rc2CBC: RC2_CBC_Parameter(),
+ rc5_CBC_PAD: RC5_CBC_Parameters(),
+ aes128_CBC_PAD: AES_IV(),
+ aes192_CBC_PAD: AES_IV(),
+ aes256_CBC_PAD: AES_IV(),
+}
+
+rfc5280.algorithmIdentifierMap.update(_algorithmIdentifierMapUpdate)
diff --git a/tests/__main__.py b/tests/__main__.py
index 08300c2..93ae011 100644
--- a/tests/__main__.py
+++ b/tests/__main__.py
@@ -19,12 +19,14 @@ suite = unittest.TestLoader().loadTestsFromNames(
'tests.test_rfc2511.suite',
'tests.test_rfc2560.suite',
'tests.test_rfc2634.suite',
+ 'tests.test_rfc2985.suite',
'tests.test_rfc2986.suite',
'tests.test_rfc3161.suite',
'tests.test_rfc3274.suite',
'tests.test_rfc3560.suite',
'tests.test_rfc3565.suite',
'tests.test_rfc3709.suite',
+ 'tests.test_rfc3770.suite',
'tests.test_rfc3779.suite',
'tests.test_rfc4055.suite',
'tests.test_rfc4073.suite',
@@ -38,12 +40,19 @@ suite = unittest.TestLoader().loadTestsFromNames(
'tests.test_rfc5480.suite',
'tests.test_rfc5649.suite',
'tests.test_rfc5652.suite',
+ 'tests.test_rfc5914.suite',
'tests.test_rfc5915.suite',
'tests.test_rfc5940.suite',
'tests.test_rfc5958.suite',
+ 'tests.test_rfc6010.suite',
'tests.test_rfc6019.suite',
+ 'tests.test_rfc6031.suite',
+ 'tests.test_rfc6032.suite',
+ 'tests.test_rfc7030.suite',
'tests.test_rfc7191.suite',
+ 'tests.test_rfc7292.suite',
'tests.test_rfc7296.suite',
+ 'tests.test_rfc8018.suite',
'tests.test_rfc8103.suite',
'tests.test_rfc8226.suite',
'tests.test_rfc8410.suite',
diff --git a/tests/test_rfc2985.py b/tests/test_rfc2985.py
new file mode 100644
index 0000000..31110a8
--- /dev/null
+++ b/tests/test_rfc2985.py
@@ -0,0 +1,293 @@
+#
+# This file is part of pyasn1-modules software.
+#
+# Created by Russ Housley
+# Copyright (c) 2019, Vigil Security, LLC
+# License: http://snmplabs.com/pyasn1/license.html
+#
+import sys
+
+from pyasn1.codec.der.decoder import decode as der_decode
+from pyasn1.codec.der.encoder import encode as der_encode
+
+from pyasn1.type import univ
+
+from pyasn1_modules import pem
+from pyasn1_modules import rfc2985
+from pyasn1_modules import rfc5280
+from pyasn1_modules import rfc5652
+from pyasn1_modules import rfc7292
+
+
+try:
+ import unittest2 as unittest
+
+except ImportError:
+ import unittest
+
+
+class PKCS9AttrsTestCase(unittest.TestCase):
+ pem_text = """\
+MYIQjzAOBgNVBEExBwwFQWxpY2UwDwYIKwYBBQUHCQMxAxMBTTAQBgNVBAUxCRMH
+QjQ4LTAwNzAQBggrBgEFBQcJBDEEEwJVUzAQBggrBgEFBQcJBTEEEwJVUzARBgoq
+hkiG9w0BCRkEMQMCATAwFAYJKoZIhvcNAQkCMQcWBUFsaWNlMBgGCiqGSIb3DQEJ
+GQMxCgQIUTeqnHYky4AwHAYJKoZIhvcNAQkPMQ8wDTALBglghkgBZQMEAS0wHQYI
+KwYBBQUHCQExERgPMjAxOTA4MDMxMjAwMDBaMB0GCCsGAQUFBwkCMREMD0hlcm5k
+b24sIFZBLCBVUzApBgkqhkiG9w0BCRQxHB4aAEYAcgBpAGUAbgBkAGwAeQAgAE4A
+YQBtAGUwLwYJKoZIhvcNAQkIMSITIDEyMyBVbmtub3duIFdheSwgTm93aGVyZSwg
+VkEsIFVTMIGZBgoqhkiG9w0BCRkCMYGKMIGHMAsGCWCGSAFlAwQBLQR4VsJb7t4l
+IqjJCT54rqkbCJsBPE17YQJeEYvyA4M1aDIUU5GnCgEhctgMiDPWGMvaSziixdIg
+aU/0zvWvYCm8UwPvBBwMtm9X5NDvk9p4nXbGAT8E/OsV1SYWVvwRJwYak0yWWexM
+HSixw1Ljh2nb0fIbqwLOeMmIMIIEsQYKKoZIhvcNAQkZBTGCBKEwggSdBgkqhkiG
+9w0BBwKgggSOMIIEigIBATENMAsGCWCGSAFlAwQCAjBRBgkqhkiG9w0BBwGgRARC
+Q29udGVudC1UeXBlOiB0ZXh0L3BsYWluDQoNCldhdHNvbiwgY29tZSBoZXJlIC0g
+SSB3YW50IHRvIHNlZSB5b3UuoIICfDCCAngwggH+oAMCAQICCQCls1QoG7BuOzAK
+BggqhkjOPQQDAzA/MQswCQYDVQQGEwJVUzELMAkGA1UECAwCVkExEDAOBgNVBAcM
+B0hlcm5kb24xETAPBgNVBAoMCEJvZ3VzIENBMB4XDTE5MDUyOTE0NDU0MVoXDTIw
+MDUyODE0NDU0MVowcDELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlZBMRAwDgYDVQQH
+EwdIZXJuZG9uMRAwDgYDVQQKEwdFeGFtcGxlMQ4wDAYDVQQDEwVBbGljZTEgMB4G
+CSqGSIb3DQEJARYRYWxpY2VAZXhhbXBsZS5jb20wdjAQBgcqhkjOPQIBBgUrgQQA
+IgNiAAT4zZ8HL+xEDpXWkoWp5xFMTz4u4Ae1nF6zXCYlmsEGD5vPu5hl9hDEjd1U
+HRgJIPoy3fJcWWeZ8FHCirICtuMgFisNscG/aTwKyDYOFDuqz/C2jyEwqgWCRyxy
+ohuJXtmjgZQwgZEwCwYDVR0PBAQDAgeAMEIGCWCGSAGG+EIBDQQ1FjNUaGlzIGNl
+cnRpZmljYXRlIGNhbm5vdCBiZSB0cnVzdGVkIGZvciBhbnkgcHVycG9zZS4wHQYD
+VR0OBBYEFMS6Wg4+euM8gbD0Aqpouxbglg41MB8GA1UdIwQYMBaAFPI12zQE2qVV
+8r1pA5mwYuziFQjBMAoGCCqGSM49BAMDA2gAMGUCMGO5H9E1uAveRGGaf48lN4po
+v2yH+hCAc5hOAuZKe/f40MKSF8q4w2ij+0euSaKFiAIxAL3gxp6sMitCmLQgOH6/
+RBIC/2syJ97y0KVp9da0PDAvwxLugCHTKZPjjpSLPHHc9TGCAaEwggGdAgEBMEww
+PzELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAlZBMRAwDgYDVQQHDAdIZXJuZG9uMREw
+DwYDVQQKDAhCb2d1cyBDQQIJAKWzVCgbsG47MAsGCWCGSAFlAwQCAqCByDAYBgkq
+hkiG9w0BCQMxCwYJKoZIhvcNAQcBMBwGCSqGSIb3DQEJBTEPFw0xOTA1MjkxODIz
+MTlaMD8GCSqGSIb3DQEJBDEyBDC25CKk/YJnHtT3qsZtRPTosLmNUVhxxlbn8Jo2
++lys4+IKEOba8jebiTfTTPmZJmwwTQYLKoZIhvcNAQkQAgExPjA8BCDHTyEPZCdX
+CPUOh5EQs211nQ999bgFAi9zDBVz+ChTo4ABATAVMBOBEWFsaWNlQGV4YW1wbGUu
+Y29tMAoGCCqGSM49BAMDBGYwZAIwOLV5WCbYjy5HLHE69IqXQQHVDJQzmo18WwkF
+rEYH3EMsvpXEIGqsFTFN6NV4VBe9AjA5fGOCP5IhI32YqmGfs+zDlqZyb2xSX6Gr
+/IfCIm0angfOI39g7lAZDyivjh5H/oQwggnoBgtghkgBhvhCAwGBWDGCCdcwggnT
+AgEDMIIJjwYJKoZIhvcNAQcBoIIJgASCCXwwggl4MIIGCAYJKoZIhvcNAQcBoIIF
++QSCBfUwggXxMIIF7QYLKoZIhvcNAQwKAQKgggT+MIIE+jAcBgoqhkiG9w0BDAED
+MA4ECO6rT/7SnK61AgIH0ASCBNhl7+ZgGmaQO8qy97gTAhXCjVM2/iV3LHWodlbY
+iHqpAJj42/Uye/3B7TNROXine1DMI9ZeetIDzYiA52i0sh7PhjBeuCIqFwiRJIv7
+bIKYCgz6qSOIAgqr6XdQnpeFp97YqDgST/RGQel7obCNO115+SlelmBxwwSik60p
+AwslawMzunvvH9qafrIiTa2myQqpRj/ifxjESJNZxG1O2FiplAi36r3icotim3Sj
+zzRJU5+90SqnkogjtxODrQYkv6fqg3qGY/RuwAy+eT3V/z+UUoyL22w1T8qdSFsN
+WmMnAFCSGBuoHHoZ22ipItKVg09UzTCWe3CbUmEfjJuJDmw3Oo7sWVYLltxjCS86
+XHWAauyFjmMr9aNsDiloGnFKSChslF6Ktj0F6ohOe+iReW5vi16EeEzbQiTjakpr
+eQZoeajC/N+XGoT6jKxbk5r1dtnEEJ+Q4wnvSjiGpr6frr4T+4pw301sptOjfO3f
+F23rKk7Advvi3k5xZobHcRmzDSfT9X5agtKlc4HCnHTz7XKHstXb1o1DSgTNVWQX
+phhFBm10gx6zfEHaLqyMtqXbWe2TuIHMwnBWiLnbhIBn+hbxK4MCfVz3cBZbApks
+Au/lXcVnakOJBcCtx/MMfZ3kcnI3Hs6W8rM2ASeDBLIQLVduOc6xlVSoYUQ24NNr
+9usfigQkcSTJZPIO52vPyIIQ7zR7U8TiqonkKWU3QJJVarPgLEYMUhBfNHqiGfx/
+d1Hf4MBoti8CMFUwsmOTv6d+cHYvQelqeFMXP0DE88gN/mkFBDAzXiXzAqMQcjJ+
+pyW6l4o2iQFSvXKSKg/IKved/hGp7RngQohjg4KlbqeGuRYea8Xs4pH5ue5KTeOc
+HGNI3Qi/Lmr2rd+e1iuGxwwYZHve6Z+Lxnb20zW9I/2MFm+KsCiB4Z/+x84jR7BG
+8l//lpuc2D/vxnKTxaaUAdUXM0Zwze7e+Gc2lMhVG5TJWR1KY51vN5J+apDYc8IR
+0L0c2bbkom3WkPq/po/dPDuoaX61nKmztUHaL5r5QZzBBwKVyhdw9J0btnWAFPNK
+vzgy5U9iV4+6jXH5TCmlIreszwRPoqqEaYRIfmUpp2+zy91PpzjTs98tx/HIAbOM
+fT3WmuTahEnEHehABhwq+S4xwzoVIskLbrcOP6l7UYYR7GTUCjKxh7ru0rSwHrqG
+9t33YdzJaFbz+8jb88xtf454Rvur66Cew/4GYX9u1Zef0DF9So1ay3IicpOf5emo
+VWIwg4bh7bELi78i/MbdWtNZQcXimykfeTsYH8Q4u+1uxHS5pwEWWwKiUnLQVpZP
+2ut255TdgSIhEILwsaLVelRrx/lp14EpY355FOusXiju6g14aWfBnt5udvuTXxDQ
+ZHPPNNk+gwzgvvTey98T941hYUctjg0NApJiB66bfrlYB9mkc5ftg5zqhEasYH5C
+4ajKKRNMM7zGlwSZvy8PPhnAeE3Q9LTnos0l4ygjQD/kMlvd7XSLW3GUzjyxtkG4
+gQh6LGvnafAbgu7GpcapKEppN86sXEePHiQjj92n103+TxMYWwtaO4iAwkjqdEdt
+avEHcXRcpdqC0st6nUwPAPAC4LKJbZgLQnNG+wlWIiCMMD56IdfQ7r/zGIr13MxC
+kjNNUdISoWWE5GnQMYHbMBMGCSqGSIb3DQEJFTEGBAQBAAAAMFcGCSqGSIb3DQEJ
+FDFKHkgAMwBmADcAMQBhAGYANgA1AC0AMQA2ADgANwAtADQANAA0AGEALQA5AGYA
+NAA2AC0AYwA4AGIAZQAxADkANABjADMAZQA4AGUwawYJKwYBBAGCNxEBMV4eXABN
+AGkAYwByAG8AcwBvAGYAdAAgAEUAbgBoAGEAbgBjAGUAZAAgAEMAcgB5AHAAdABv
+AGcAcgBhAHAAaABpAGMAIABQAHIAbwB2AGkAZABlAHIAIAB2ADEALgAwMIIDaAYJ
+KoZIhvcNAQcBoIIDWQSCA1UwggNRMIIDTQYLKoZIhvcNAQwKAQOgggMlMIIDIQYK
+KoZIhvcNAQkWAaCCAxEEggMNMIIDCTCCAfGgAwIBAgIQNu32hzqhCKdHATXzboyI
+ETANBgkqhkiG9w0BAQUFADAUMRIwEAYDVQQDEwlhbm9ueW1vdXMwIBcNMTYwNzE5
+MjIwMDAxWhgPMjExNjA2MjUyMjAwMDFaMBQxEjAQBgNVBAMTCWFub255bW91czCC
+ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALy2sEJMGNdcDg6BI7mdFM5T
+lPzo5sKBzvUnagK5SKBJ11xMPN5toPTBzICB/XTWEB3AwpD0O+srSca+bsUAyedS
+5V4BNp8qCyEu5RNRR8qPHheJ/guhLT96/gGI4jlrUyUhFntPkLKODxu+7KanMy6K
+dD+PVE8shXRUZTYe4PG64/c7z3wapnf4XoCXkJRzCY5f3MKz3Ul039kVnTlJcikd
+C7I9I9RflXLwXVl4nxUbeeRt6Z8WVWS4pCq+14v2aVPvP3mtVmAYHedRkvS04Hrx
+4xx98D3NSSw6Z5OLkzqOcFw15fYmH2NLdhh34gSWJmaaCBAbuQ+1rx/42p7MvvsC
+AwEAAaNVMFMwFQYDVR0lBA4wDAYKKwYBBAGCNwoDBDAvBgNVHREEKDAmoCQGCisG
+AQQBgjcUAgOgFgwUYW5vbnltb3VzQHdpbmRvd3MteAAwCQYDVR0TBAIwADANBgkq
+hkiG9w0BAQUFAAOCAQEAuH7iqY0/MLozwFb39ILYAJDHE+HToZBQbHQP4YtienrU
+Stk60rIp0WH65lam7m/JhgAcItc/tV1L8mEnLrvvKcA+NeIL8sDOtM28azvgcOi0
+P3roeLLLRCuiykUaKmUcZEDm9cDYKIpJf7QetWQ3uuGTk9iRzpH79x2ix35BnyWQ
+Rr3INZzmX/+9YRvPBXKYl/89F/w1ORYArpI9XtjfuPWaGQmM4f1WRHE2t3qRyKFF
+ri7QiZdpcSx5zvsRHSyjfUMoKs+b6upk+P01lIhg/ewwYngGab+fZhF15pTNN2hx
+8PdNGcrGzrkNKCmJKrWCa2xczuMA+z8SCuC1tYTKmDEVMBMGCSqGSIb3DQEJFTEG
+BAQBAAAAMDswHzAHBgUrDgMCGgQUpWCP/fZR0TK5BwGuqvTd0+duiKcEFJTubF2k
+HktMK+isIjxOTk4yJTOOAgIH0A==
+"""
+
+ def setUp(self):
+ self.asn1Spec = rfc2985.AttributeSet()
+
+ def testDerCodec(self):
+ substrate = pem.readBase64fromText(self.pem_text)
+ asn1Object, rest = der_decode(substrate, asn1Spec=self.asn1Spec)
+ assert not rest
+ assert asn1Object.prettyPrint()
+ assert der_encode(asn1Object) == substrate
+
+ rfc5280.certificateAttributesMap.update(rfc2985.certificateAttributesMapUpdate)
+ rfc5280.certificateAttributesMap.update(rfc2985.cmsAttributesMapUpdate)
+
+ for attr in asn1Object:
+ assert attr['type'] in rfc5280.certificateAttributesMap
+ av, rest = der_decode(attr['values'][0],
+ asn1Spec=rfc5280.certificateAttributesMap[attr['type']])
+ assert not rest
+ assert av.prettyPrint()
+ assert der_encode(av) == attr['values'][0]
+
+ if attr['type'] == rfc2985.pkcs_9_at_userPKCS12:
+ assert av['version'] == univ.Integer(3)
+ assert av['authSafe']['contentType'] == rfc5652.id_data
+ outdata, rest = der_decode(av['authSafe']['content'],
+ asn1Spec=univ.OctetString())
+ assert not rest
+ authsafe, rest = der_decode(outdata,
+ asn1Spec=rfc7292.AuthenticatedSafe())
+ assert not rest
+
+ for ci in authsafe:
+ assert ci['contentType'] == rfc5652.id_data
+ indata, rest = der_decode(ci['content'],
+ asn1Spec=univ.OctetString())
+ assert not rest
+ sc, rest = der_decode(indata,
+ asn1Spec=rfc7292.SafeContents())
+ assert not rest
+
+ for sb in sc:
+ if sb['bagId'] in rfc7292.pkcs12BagTypeMap:
+ bv, rest = der_decode(sb['bagValue'],
+ asn1Spec=rfc7292.pkcs12BagTypeMap[sb['bagId']])
+ assert not rest
+
+ for bagattr in sb['bagAttributes']:
+ if bagattr['attrType'] in rfc5280.certificateAttributesMap:
+ inav, rest = der_decode(bagattr['attrValues'][0],
+ asn1Spec=rfc5280.certificateAttributesMap[bagattr['attrType']])
+ assert not rest
+
+ if bagattr['attrType'] == rfc2985.pkcs_9_at_friendlyName:
+ assert inav == "3f71af65-1687-444a-9f46-c8be194c3e8e"
+
+ if bagattr['attrType'] == rfc2985.pkcs_9_at_localKeyId:
+ assert inav == univ.OctetString(hexValue='01000000')
+
+ if attr['type'] == rfc2985.pkcs_9_at_pkcs7PDU:
+ ci, rest = der_decode(attr['values'][0],
+ asn1Spec=rfc5652.ContentInfo())
+ assert not rest
+ assert ci['contentType'] == rfc5652.id_signedData
+
+ sd, rest = der_decode(ci['content'],
+ asn1Spec=rfc5652.SignedData())
+ assert not rest
+ assert sd['version'] == 1
+
+ for si in sd['signerInfos']:
+ assert si['version'] == 1
+
+ for siattr in si['signedAttrs']:
+ if siattr['attrType'] in rfc5280.certificateAttributesMap:
+ siav, rest = der_decode(siattr['attrValues'][0],
+ asn1Spec=rfc5280.certificateAttributesMap[siattr['attrType']])
+ assert not rest
+
+ if siattr['attrType'] == rfc2985.pkcs_9_at_contentType:
+ assert siav == rfc5652.id_data
+
+ if siattr['attrType'] == rfc2985.pkcs_9_at_messageDigest:
+ assert siav.prettyPrint()[2:10] == 'b6e422a4'
+
+ if siattr['attrType'] == rfc2985.pkcs_9_at_signingTime:
+ assert siav['utcTime'] == '190529182319Z'
+
+ for choices in sd['certificates']:
+ for rdn in choices[0]['tbsCertificate']['subject']['rdnSequence']:
+ if rdn[0]['type'] in rfc5280.certificateAttributesMap:
+ nv, rest = der_decode(rdn[0]['value'],
+ asn1Spec=rfc5280.certificateAttributesMap[rdn[0]['type']])
+ assert not rest
+
+ if rdn[0]['type'] == rfc2985.pkcs_9_at_emailAddress:
+ assert nv == 'alice@example.com'
+
+ def testOpenTypes(self):
+ rfc5280.certificateAttributesMap.update(rfc2985.certificateAttributesMapUpdate)
+ rfc5280.certificateAttributesMap.update(rfc2985.cmsAttributesMapUpdate)
+
+ substrate = pem.readBase64fromText(self.pem_text)
+ asn1Object, rest = der_decode(substrate,
+ asn1Spec=self.asn1Spec,
+ decodeOpenTypes=True)
+ assert not rest
+ assert asn1Object.prettyPrint()
+ assert der_encode(asn1Object) == substrate
+
+ for attr in asn1Object:
+ assert attr['type'] in rfc5280.certificateAttributesMap
+
+ if attr['type'] == rfc2985.pkcs_9_at_userPKCS12:
+ assert attr['values'][0]['version'] == univ.Integer(3)
+ assert attr['values'][0]['authSafe']['contentType'] == rfc5652.id_data
+ authsafe, rest = der_decode(attr['values'][0]['authSafe']['content'],
+ asn1Spec=rfc7292.AuthenticatedSafe())
+ assert not rest
+
+ for ci in authsafe:
+ assert ci['contentType'] == rfc5652.id_data
+ indata, rest = der_decode(ci['content'],
+ asn1Spec=univ.OctetString())
+ assert not rest
+
+ sc, rest = der_decode(indata,
+ asn1Spec=rfc7292.SafeContents(),
+ decodeOpenTypes=True)
+ assert not rest
+
+ for sb in sc:
+ if sb['bagId'] in rfc7292.pkcs12BagTypeMap:
+ for bagattr in sb['bagAttributes']:
+ if bagattr['attrType'] in rfc5280.certificateAttributesMap:
+
+ if bagattr['attrType'] == rfc2985.pkcs_9_at_friendlyName:
+ assert bagattr['attrValues'][0] == "3f71af65-1687-444a-9f46-c8be194c3e8e"
+
+ if bagattr['attrType'] == rfc2985.pkcs_9_at_localKeyId:
+ assert bagattr['attrValues'][0] == univ.OctetString(hexValue='01000000')
+
+ if attr['type'] == rfc2985.pkcs_9_at_pkcs7PDU:
+ assert attr['values'][0]['contentType'] == rfc5652.id_signedData
+ assert attr['values'][0]['content']['version'] == 1
+
+ for si in attr['values'][0]['content']['signerInfos']:
+ assert si['version'] == 1
+
+ for siattr in si['signedAttrs']:
+ if siattr['attrType'] in rfc5280.certificateAttributesMap:
+
+ if siattr['attrType'] == rfc2985.pkcs_9_at_contentType:
+ assert siattr['attrValues'][0] == rfc5652.id_data
+
+ if siattr['attrType'] == rfc2985.pkcs_9_at_messageDigest:
+ assert siattr['attrValues'][0].prettyPrint()[2:10] == 'b6e422a4'
+
+ if siattr['attrType'] == rfc2985.pkcs_9_at_signingTime:
+ assert siattr['attrValues'][0]['utcTime'] == '190529182319Z'
+
+ for choices in attr['values'][0]['content']['certificates']:
+ for rdn in choices[0]['tbsCertificate']['subject']['rdnSequence']:
+ if rdn[0]['type'] in rfc5280.certificateAttributesMap:
+
+ if rdn[0]['type'] == rfc2985.pkcs_9_at_emailAddress:
+ assert rdn[0]['value'] == 'alice@example.com'
+
+
+suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__])
+
+if __name__ == '__main__':
+ unittest.TextTestRunner(verbosity=2).run(suite)
diff --git a/tests/test_rfc3770.py b/tests/test_rfc3770.py
new file mode 100644
index 0000000..e8093f0
--- /dev/null
+++ b/tests/test_rfc3770.py
@@ -0,0 +1,90 @@
+#
+# This file is part of pyasn1-modules software.
+#
+# Created by Russ Housley
+# Copyright (c) 2019, Vigil Security, LLC
+# License: http://snmplabs.com/pyasn1/license.html
+#
+
+import sys
+
+from pyasn1.codec.der.decoder import decode as der_decode
+from pyasn1.codec.der.encoder import encode as der_encode
+
+from pyasn1.compat.octets import str2octs
+
+from pyasn1_modules import pem
+from pyasn1_modules import rfc5480
+from pyasn1_modules import rfc5280
+from pyasn1_modules import rfc3770
+
+try:
+ import unittest2 as unittest
+except ImportError:
+ import unittest
+
+class CertificateTestCase(unittest.TestCase):
+ cert_pem_text = """\
+MIICqzCCAjCgAwIBAgIJAKWzVCgbsG4/MAoGCCqGSM49BAMDMD8xCzAJBgNVBAYT
+AlVTMQswCQYDVQQIDAJWQTEQMA4GA1UEBwwHSGVybmRvbjERMA8GA1UECgwIQm9n
+dXMgQ0EwHhcNMTkwNzE5MTk0MjQ3WhcNMjAwNzE4MTk0MjQ3WjBjMQswCQYDVQQG
+EwJVUzELMAkGA1UECBMCVkExEDAOBgNVBAcTB0hlcm5kb24xGzAZBgNVBAoTElZp
+Z2lsIFNlY3VyaXR5IExMQzEYMBYGA1UEAxMPZWFwLmV4YW1wbGUuY29tMHYwEAYH
+KoZIzj0CAQYFK4EEACIDYgAEMMbnIp2BUbuyMgH9HhNHrh7VBy7ql2lBjGRSsefR
+Wa7+vCWs4uviW6On4eem5YoP9/UdO7DaIL+/J9/3DJHERI17oFxn+YWiE4JwXofy
+QwfSu3cncVNMqpiDjEkUGGvBo4HTMIHQMAsGA1UdDwQEAwIHgDBCBglghkgBhvhC
+AQ0ENRYzVGhpcyBjZXJ0aWZpY2F0ZSBjYW5ub3QgYmUgdHJ1c3RlZCBmb3IgYW55
+IHB1cnBvc2UuMB0GA1UdDgQWBBSDjPGr7M742rsE4oQGwBvGvllZ+zAfBgNVHSME
+GDAWgBTyNds0BNqlVfK9aQOZsGLs4hUIwTAeBggrBgEFBQcBDQQSMBAEB0V4YW1w
+bGUEBUJvZ3VzMB0GA1UdJQQWMBQGCCsGAQUFBwMOBggrBgEFBQcDDTAKBggqhkjO
+PQQDAwNpADBmAjEAmCPZnnlUQOKlcOIIOgFrRCkOqO0ESs+dobYwAc2rFCBtQyP7
+C3N00xkX8WZZpiAZAjEAi1Z5+nGbJg5eJTc8fwudutN/HNwJEIS6mHds9kfcy26x
+DAlVlhox680Jxy5J8Pkx
+"""
+
+ def setUp(self):
+ self.asn1Spec = rfc5280.Certificate()
+
+ def testDerCodec(self):
+ substrate = pem.readBase64fromText(self.cert_pem_text)
+ asn1Object, rest = der_decode(substrate, asn1Spec=self.asn1Spec)
+ assert not rest
+ assert asn1Object.prettyPrint()
+ assert der_encode(asn1Object) == substrate
+
+ def testOpenTypes(self):
+ substrate = pem.readBase64fromText(self.cert_pem_text)
+ rfc5280.algorithmIdentifierMap.update(rfc5480.algorithmIdentifierMapUpdate)
+ asn1Object, rest = der_decode(substrate,
+ asn1Spec=self.asn1Spec,
+ decodeOpenTypes=True)
+ assert not rest
+ assert asn1Object.prettyPrint()
+ assert der_encode(asn1Object) == substrate
+
+ sig_alg = asn1Object['tbsCertificate']['signature']
+ assert sig_alg['algorithm'] == rfc5480.ecdsa_with_SHA384
+ assert not sig_alg['parameters'].hasValue()
+
+ spki_alg = asn1Object['tbsCertificate']['subjectPublicKeyInfo']['algorithm']
+ assert spki_alg['algorithm'] == rfc5480.id_ecPublicKey
+ assert spki_alg['parameters']['namedCurve'] == rfc5480.secp384r1
+
+ for extn in asn1Object['tbsCertificate']['extensions']:
+ if extn['extnID'] in rfc5280.certificateExtensionsMap.keys():
+ extnValue, rest = der_decode(extn['extnValue'],
+ asn1Spec=rfc5280.certificateExtensionsMap[extn['extnID']])
+ assert der_encode(extnValue) == extn['extnValue']
+
+ if extn['extnID'] == rfc3770.id_pe_wlanSSID:
+ assert str2octs('Example') in extnValue
+
+ if extn['extnID'] == rfc5280.id_ce_extKeyUsage:
+ assert rfc3770.id_kp_eapOverLAN in extnValue
+ assert rfc3770.id_kp_eapOverPPP in extnValue
+
+
+suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__])
+
+if __name__ == '__main__':
+ unittest.TextTestRunner(verbosity=2).run(suite)
diff --git a/tests/test_rfc4073.py b/tests/test_rfc4073.py
index 34cebea..5a3b7f8 100644
--- a/tests/test_rfc4073.py
+++ b/tests/test_rfc4073.py
@@ -153,4 +153,4 @@ if __name__ == '__main__':
import sys
result = unittest.TextTestRunner(verbosity=2).run(suite)
- sys.exit(not result.wasSuccessful())
+ sys.exit(not result.wasSuccessful()) \ No newline at end of file
diff --git a/tests/test_rfc5914.py b/tests/test_rfc5914.py
new file mode 100644
index 0000000..3fc5df9
--- /dev/null
+++ b/tests/test_rfc5914.py
@@ -0,0 +1,83 @@
+#
+# This file is part of pyasn1-modules software.
+#
+# Created by Russ Housley
+# Copyright (c) 2019, Vigil Security, LLC
+# License: http://snmplabs.com/pyasn1/license.html
+#
+
+import sys
+
+from pyasn1.codec.der.decoder import decode as der_decode
+from pyasn1.codec.der.encoder import encode as der_encode
+
+from pyasn1_modules import pem
+from pyasn1_modules import rfc5914
+from pyasn1_modules import rfc5652
+
+try:
+ import unittest2 as unittest
+except ImportError:
+ import unittest
+
+
+class TrustAnchorListTestCase(unittest.TestCase):
+ trust_anchor_list_pem_text = """\
+MIIGGQYLKoZIhvcNAQkQASKgggYIMIIGBKGCAvYwggLyoAMCAQICAgDJMA0GCSqG
+SIb3DQEBCwUAMBYxFDASBgNVBAMTC3JpcGUtbmNjLXRhMCAXDTE3MTEyODE0Mzk1
+NVoYDzIxMTcxMTI4MTQzOTU1WjAWMRQwEgYDVQQDEwtyaXBlLW5jYy10YTCCASIw
+DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANFEWEhqlM9psgbDs3ltY0OjbMTb
+5SzMoVpJ755fDYgQrP0/0tl7jSkDWfsAWcSIDz1dqRQRXkAL6B/1ivNx8ANuldrI
+sJvzGNpymfjpcPsJac5WdadyKY9njXCq5orfAcAQvMSJs7ghmldI5EQdBmdIaB+j
+JdN7pi6a0bJ+r9MTj9PpekHNWRzBVRW9/OSEOxUEE3FSMa3XjLKMiavXjJBOg6HJ
+R4RfzZUpZV7mwEkPSlFqidPjrd0Al6+C1xAjH5KZFUdk2U/r+b+ufGx1bOmcUQ9W
++lJNbkCgMh1G5/7V7z/Ja4wImxs1bFw09i9MeBHcfkHYsT4Do4t4ATMi9lcCAwEA
+AaOCAV4wggFaMB0GA1UdDgQWBBToVSsf1tGk9+QExtjlaA0evBY/wzAPBgNVHRMB
+Af8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjCBsQYIKwYBBQUHAQsEgaQwgaEwPAYI
+KwYBBQUHMAqGMHJzeW5jOi8vcnBraS5yaXBlLm5ldC9yZXBvc2l0b3J5L3JpcGUt
+bmNjLXRhLm1mdDAyBggrBgEFBQcwDYYmaHR0cHM6Ly9ycmRwLnJpcGUubmV0L25v
+dGlmaWNhdGlvbi54bWwwLQYIKwYBBQUHMAWGIXJzeW5jOi8vcnBraS5yaXBlLm5l
+dC9yZXBvc2l0b3J5LzAYBgNVHSABAf8EDjAMMAoGCCsGAQUFBw4CMCcGCCsGAQUF
+BwEHAQH/BBgwFjAJBAIAATADAwEAMAkEAgACMAMDAQAwIQYIKwYBBQUHAQgBAf8E
+EjAQoA4wDDAKAgEAAgUA/////zCCAgIwggGIoAMCAQICCQDokdYGkU/O8jAKBggq
+hkjOPQQDAzA/MQswCQYDVQQGEwJVUzELMAkGA1UECAwCVkExEDAOBgNVBAcMB0hl
+cm5kb24xETAPBgNVBAoMCEJvZ3VzIENBMB4XDTE5MDUxNDA4NTgxMVoXDTIxMDUx
+MzA4NTgxMVowPzELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAlZBMRAwDgYDVQQHDAdI
+ZXJuZG9uMREwDwYDVQQKDAhCb2d1cyBDQTB2MBAGByqGSM49AgEGBSuBBAAiA2IA
+BPBRdlSx6I5qpZ2sKUMIxun1gUAzzstOYWKvKCnMoNT1x+pIKDvMEMimFcLAxxL3
+NVYOhK0Jty83SPDkKWMdx9/Okdhf3U/zxJlEnXDiFrAeM6xbG8zcCRiBnmd92Uvs
+RqNQME4wHQYDVR0OBBYEFPI12zQE2qVV8r1pA5mwYuziFQjBMB8GA1UdIwQYMBaA
+FPI12zQE2qVV8r1pA5mwYuziFQjBMAwGA1UdEwQFMAMBAf8wCgYIKoZIzj0EAwMD
+aAAwZQIwWlGNjb9NyqJSzUSdsEqDSvMZb8yFkxYCIbAVqQ9UqScUUb9tpJKGsPWw
+bZsnLVvmAjEAt/ypozbUhQw4dSPpWzrn5BQ0kKbDM3DQJcBABEUBoIOol1/jYQPm
+xajQuxcheFlkooIBADCB/TB2MBAGByqGSM49AgEGBSuBBAAiA2IABOIIQup32CTe
+oCxkpBPOQJwjcqkCCg43PyE2uI1TFPbVkZVL85YCjXEexNjLp59e76Dmf1qSEZZT
+b+vAyz+u/Vs/RyTnmgculr6oL7tXGK9xpL14Oh7oWzxrZBErzDQrjAQUo53mH/na
+OU/AbuiRy5Wl2jHiCp8MFURpZ2lDZXJ0IFRydXN0IEFuY2hvcjBSMEwxCzAJBgNV
+BAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxJjAkBgNVBAMTHURpZ2lDZXJ0
+IEVDQyBTZWN1cmUgU2VydmVyIENBggIFIIICZW4=
+"""
+
+ def setUp(self):
+ self.asn1Spec = rfc5652.ContentInfo()
+
+ def testDerCodec(self):
+ substrate = pem.readBase64fromText(self.trust_anchor_list_pem_text)
+ asn1Object, rest = der_decode(substrate, asn1Spec=self.asn1Spec)
+ assert not rest
+ assert asn1Object.prettyPrint()
+ assert der_encode(asn1Object) == substrate
+
+ assert asn1Object['contentType'] == rfc5914.id_ct_trustAnchorList
+ tal, rest = der_decode(asn1Object['content'], rfc5914.TrustAnchorList())
+ assert not rest
+ assert tal.prettyPrint()
+ assert der_encode(tal) == asn1Object['content']
+
+ assert sum (1 for _ in tal) == 3
+
+
+suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__])
+
+if __name__ == '__main__':
+ unittest.TextTestRunner(verbosity=2).run(suite)
diff --git a/tests/test_rfc6010.py b/tests/test_rfc6010.py
new file mode 100644
index 0000000..072c1ac
--- /dev/null
+++ b/tests/test_rfc6010.py
@@ -0,0 +1,95 @@
+#
+# This file is part of pyasn1-modules software.
+#
+# Created by Russ Housley
+# Copyright (c) 2019, Vigil Security, LLC
+# License: http://snmplabs.com/pyasn1/license.html
+#
+
+import sys
+
+from pyasn1.codec.der.decoder import decode as der_decode
+from pyasn1.codec.der.encoder import encode as der_encode
+
+from pyasn1_modules import pem
+from pyasn1_modules import rfc5280
+from pyasn1_modules import rfc6010
+
+try:
+ import unittest2 as unittest
+except ImportError:
+ import unittest
+
+
+class UnconstrainedCCCExtensionTestCase(unittest.TestCase):
+ unconstrained_pem_text = "MB0GCCsGAQUFBwESBBEwDzANBgsqhkiG9w0BCRABAA=="
+
+ def setUp(self):
+ self.asn1Spec = rfc5280.Extension()
+
+ def testDerCodec(self):
+ substrate = pem.readBase64fromText(self.unconstrained_pem_text)
+ asn1Object, rest = der_decode(substrate, asn1Spec=self.asn1Spec)
+ assert not rest
+ assert asn1Object.prettyPrint()
+ assert der_encode(asn1Object) == substrate
+
+ assert asn1Object['extnID'] == rfc6010.id_pe_cmsContentConstraints
+ evalue, rest = der_decode(asn1Object['extnValue'],
+ asn1Spec=rfc6010.CMSContentConstraints())
+ assert not rest
+ assert evalue.prettyPrint()
+ assert der_encode(evalue) == asn1Object['extnValue']
+
+ assert evalue[0]['contentType'] == rfc6010.id_ct_anyContentType
+
+
+class ConstrainedCCCExtensionTestCase(unittest.TestCase):
+ constrained_pem_text = """\
+MIG7BggrBgEFBQcBEgSBrjCBqzA0BgsqhkiG9w0BCRABEDAlMCMGCyqGSIb3DQEJ
+EAwBMRQMElZpZ2lsIFNlY3VyaXR5IExMQzAwBgpghkgBZQIBAk4CMCIwIAYLKoZI
+hvcNAQkQDAsxEQwPa3RhLmV4YW1wbGUuY29tMDEGCyqGSIb3DQEJEAEZMCIwIAYL
+KoZIhvcNAQkQDAsxEQwPa3RhLmV4YW1wbGUuY29tMA4GCSqGSIb3DQEHAQoBAQ==
+"""
+
+ def setUp(self):
+ self.asn1Spec = rfc5280.Extension()
+
+ def testDerCodec(self):
+ substrate = pem.readBase64fromText(self.constrained_pem_text)
+ asn1Object, rest = der_decode(substrate, asn1Spec=self.asn1Spec)
+ assert not rest
+ assert asn1Object.prettyPrint()
+ assert der_encode(asn1Object) == substrate
+
+ assert asn1Object['extnID'] == rfc6010.id_pe_cmsContentConstraints
+ evalue, rest = der_decode(asn1Object['extnValue'],
+ asn1Spec=rfc6010.CMSContentConstraints())
+ assert not rest
+ assert evalue.prettyPrint()
+ assert der_encode(evalue) == asn1Object['extnValue']
+
+ constraint_count = 0
+ attribute_count = 0
+ cannot_count = 0
+ for ccc in evalue:
+ constraint_count += 1
+ if ccc['canSource'] == 1:
+ cannot_count += 1
+ if ccc['attrConstraints'].hasValue():
+ for attr in ccc['attrConstraints']:
+ attribute_count += 1
+ assert constraint_count == 4
+ assert attribute_count == 3
+ assert cannot_count == 1
+
+ def testExtensionsMap(self):
+ substrate = pem.readBase64fromText(self.constrained_pem_text)
+ asn1Object, rest = der_decode(substrate, asn1Spec=self.asn1Spec)
+ assert asn1Object['extnID'] in rfc5280.certificateExtensionsMap.keys()
+
+
+suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__])
+
+if __name__ == '__main__':
+ unittest.TextTestRunner(verbosity=2).run(suite)
diff --git a/tests/test_rfc6031.py b/tests/test_rfc6031.py
new file mode 100644
index 0000000..176285f
--- /dev/null
+++ b/tests/test_rfc6031.py
@@ -0,0 +1,89 @@
+#
+# This file is part of pyasn1-modules software.
+#
+# Created by Russ Housley
+# Copyright (c) 2019, Vigil Security, LLC
+# License: http://snmplabs.com/pyasn1/license.html
+#
+
+import sys
+
+from pyasn1.codec.der.decoder import decode as der_decode
+from pyasn1.codec.der.encoder import encode as der_encode
+
+from pyasn1_modules import pem
+from pyasn1_modules import rfc5652
+from pyasn1_modules import rfc6031
+
+try:
+ import unittest2 as unittest
+except ImportError:
+ import unittest
+
+
+class SymmetricKeyPkgTestCase(unittest.TestCase):
+ key_pkg_pem_text = """\
+MIG7BgsqhkiG9w0BCRABGaCBqzCBqKBEMCMGCyqGSIb3DQEJEAwBMRQMElZpZ2ls
+IFNlY3VyaXR5IExMQzAdBgsqhkiG9w0BCRAMAzEODAxQcmV0ZW5kIDA0OEEwYDBe
+MFYwGwYLKoZIhvcNAQkQDBsxDAwKZXhhbXBsZUlEMTAVBgsqhkiG9w0BCRAMCjEG
+DARIT1RQMCAGCyqGSIb3DQEJEAwLMREMD2t0YS5leGFtcGxlLmNvbQQEMTIzNA==
+"""
+
+ def setUp(self):
+ self.asn1Spec = rfc5652.ContentInfo()
+
+ def testDerCodec(self):
+ substrate = pem.readBase64fromText(self.key_pkg_pem_text)
+ asn1Object, rest = der_decode(substrate, asn1Spec=self.asn1Spec)
+ assert not rest
+ assert asn1Object.prettyPrint()
+ assert der_encode(asn1Object) == substrate
+
+ assert asn1Object['contentType'] in rfc5652.cmsContentTypesMap
+ asn1Spec = rfc5652.cmsContentTypesMap[asn1Object['contentType']]
+ skp, rest = der_decode(asn1Object['content'], asn1Spec=asn1Spec)
+ assert not rest
+ assert skp.prettyPrint()
+ assert der_encode(skp) == asn1Object['content']
+
+ for attr in skp['sKeyPkgAttrs']:
+ assert attr['attrType'] in rfc6031.sKeyPkgAttributesMap.keys()
+
+ for osk in skp['sKeys']:
+ for attr in osk['sKeyAttrs']:
+ assert attr['attrType'] in rfc6031.sKeyAttributesMap.keys()
+
+ def testOpenTypes(self):
+ substrate = pem.readBase64fromText(self.key_pkg_pem_text)
+ asn1Object, rest = der_decode(substrate,
+ asn1Spec=self.asn1Spec,
+ decodeOpenTypes=True)
+ assert not rest
+ assert asn1Object.prettyPrint()
+ assert der_encode(asn1Object) == substrate
+
+ assert asn1Object['contentType'] in rfc5652.cmsContentTypesMap
+ assert asn1Object['content'].hasValue()
+ keypkg = asn1Object['content']
+ assert keypkg['version'] == rfc6031.KeyPkgVersion().subtype(value='v1')
+
+ for attr in keypkg['sKeyPkgAttrs']:
+ assert attr['attrType'] in rfc6031.sKeyPkgAttributesMap.keys()
+ assert attr['attrValues'][0].prettyPrint()[:2] != '0x'
+ # decodeOpenTypes=True did not decode if the value is shown in hex ...
+ if attr['attrType'] == rfc6031.id_pskc_manufacturer:
+ attr['attrValues'][0] == 'Vigil Security LLC'
+
+ for osk in keypkg['sKeys']:
+ for attr in osk['sKeyAttrs']:
+ assert attr['attrType'] in rfc6031.sKeyAttributesMap.keys()
+ assert attr['attrValues'][0].prettyPrint()[:2] != '0x'
+ # decodeOpenTypes=True did not decode if the value is shown in hex ...
+ if attr['attrType'] == rfc6031.id_pskc_issuer:
+ attr['attrValues'][0] == 'kta.example.com'
+
+
+suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__])
+
+if __name__ == '__main__':
+ unittest.TextTestRunner(verbosity=2).run(suite)
diff --git a/tests/test_rfc6032.py b/tests/test_rfc6032.py
new file mode 100644
index 0000000..ad56823
--- /dev/null
+++ b/tests/test_rfc6032.py
@@ -0,0 +1,88 @@
+#
+# This file is part of pyasn1-modules software.
+#
+# Created by Russ Housley
+# Copyright (c) 2019, Vigil Security, LLC
+# License: http://snmplabs.com/pyasn1/license.html
+#
+
+import sys
+
+from pyasn1.codec.der.decoder import decode as der_decode
+from pyasn1.codec.der.encoder import encode as der_encode
+
+from pyasn1.compat.octets import str2octs
+
+from pyasn1_modules import pem
+from pyasn1_modules import rfc5652
+from pyasn1_modules import rfc6032
+from pyasn1_modules import rfc3565
+
+try:
+ import unittest2 as unittest
+except ImportError:
+ import unittest
+
+
+class EncryptedKeyPkgTestCase(unittest.TestCase):
+ encrypted_key_pkg_pem_text = """\
+MIIBBwYKYIZIAWUCAQJOAqCB+DCB9QIBAjCBzgYKYIZIAWUCAQJOAjAdBglghkgB
+ZQMEASoEEN6HFteHMZ3DyeO35xIwWQOAgaCKTs0D0HguNzMhsLgiwG/Kw8OwX+GF
+9/cZ1YVNesUTW/VsbXJcbTmFmWyfqZsM4DLBegIbrUEHQZnQRq6/NO4ricQdHApD
+B/ip6RRqeN1yxMJLv1YN0zUOOIDBS2iMEjTLXZLWw3w22GN2JK7G+Lr4OH1NhMgU
+ILJyh/RePmPseMwxvcJs7liEfkiSNMtDfEcpjtzA9bDe95GjhQRsiSByoR8wHQYJ
+YIZIAWUCAQVCMRAEDnB0Zi1rZGMtODEyMzc0
+"""
+
+ def setUp(self):
+ self.asn1Spec = rfc5652.ContentInfo()
+
+ def testDerCodec(self):
+ substrate = pem.readBase64fromText(self.encrypted_key_pkg_pem_text)
+ asn1Object, rest = der_decode(substrate, asn1Spec=self.asn1Spec)
+ assert not rest
+ assert asn1Object.prettyPrint()
+ assert der_encode(asn1Object) == substrate
+ assert asn1Object['contentType'] == rfc6032.id_ct_KP_encryptedKeyPkg
+
+ content, rest = der_decode(asn1Object['content'], rfc6032.EncryptedKeyPackage())
+ assert not rest
+ assert content.prettyPrint()
+ assert der_encode(content) == asn1Object['content']
+ assert content.getName() == 'encrypted'
+ eci = content['encrypted']['encryptedContentInfo']
+ assert eci['contentType'] == rfc6032.id_ct_KP_encryptedKeyPkg
+ attrType = content['encrypted']['unprotectedAttrs'][0]['attrType']
+ assert attrType == rfc6032.id_aa_KP_contentDecryptKeyID
+
+ attrVal0 = content['encrypted']['unprotectedAttrs'][0]['attrValues'][0]
+ keyid, rest = der_decode(attrVal0, rfc6032.ContentDecryptKeyID())
+ assert not rest
+ assert keyid.prettyPrint()
+ assert der_encode(keyid) == attrVal0
+ assert keyid == b'ptf-kdc-812374'
+
+ def testOpenTypes(self):
+ substrate = pem.readBase64fromText(self.encrypted_key_pkg_pem_text)
+ asn1Object, rest = der_decode(substrate,
+ asn1Spec=self.asn1Spec,
+ decodeOpenTypes=True)
+ assert not rest
+ assert asn1Object.prettyPrint()
+ assert der_encode(asn1Object) == substrate
+
+ assert asn1Object['contentType'] in rfc5652.cmsContentTypesMap
+ eci = asn1Object['content']['encrypted']['encryptedContentInfo']
+ assert eci['contentType'] in rfc5652.cmsContentTypesMap
+
+ for attr in asn1Object['content']['encrypted']['unprotectedAttrs']:
+ assert attr['attrType'] in rfc5652.cmsAttributesMap.keys()
+ assert attr['attrValues'][0].prettyPrint()[:2] != '0x'
+ if attr['attrType'] == rfc6032.id_aa_KP_contentDecryptKeyID:
+ assert attr['attrValues'][0] == str2octs('ptf-kdc-812374')
+
+
+suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__])
+
+if __name__ == '__main__':
+ unittest.TextTestRunner(verbosity=2).run(suite)
diff --git a/tests/test_rfc6402.py b/tests/test_rfc6402.py
new file mode 100755
index 0000000..65d5ea9
--- /dev/null
+++ b/tests/test_rfc6402.py
@@ -0,0 +1,163 @@
+#
+# This file is part of pyasn1-modules software.
+#
+# Created by Russ Housley
+# Copyright (c) 2019, Vigil Security, LLC
+# License: http://snmplabs.com/pyasn1/license.html
+#
+
+import sys
+
+from pyasn1.codec.der.decoder import decode as der_decode
+from pyasn1.codec.der.encoder import encode as der_encode
+
+from pyasn1.type import char
+from pyasn1.type import namedtype
+from pyasn1.type import univ
+
+from pyasn1_modules import pem
+from pyasn1_modules import rfc5280
+from pyasn1_modules import rfc5652
+from pyasn1_modules import rfc6402
+
+try:
+ import unittest2 as unittest
+except ImportError:
+ import unittest
+
+
+class BackwardCompatibilityTestCase(unittest.TestCase):
+ pem_text = """\
+MIIEJQYJKoZIhvcNAQcCoIIEFjCCBBICAQMxCzAJBgUrDgMCGgUAMIIDAgYIKwYBBQUHDAKgggL0
+BIIC8DCCAuwweDB2AgECBgorBgEEAYI3CgoBMWUwYwIBADADAgEBMVkwVwYJKwYBBAGCNxUUMUow
+SAIBBQwZcGl0dWNoYTEuZW1lYS5ocHFjb3JwLm5ldAwMRU1FQVxwaXR1Y2hhDBpDTUNSZXFHZW5l
+cmF0b3IudnNob3N0LmV4ZTCCAmqgggJmAgEBMIICXzCCAcgCAQAwADCBnzANBgkqhkiG9w0BAQEF
+AAOBjQAwgYkCgYEA0jm7SSSm2wyEAzuNKtFZFJKo91SrJq9wQwEhEKHDavZwMQOm1rZ2PF8NWCEb
+PqrhToQ7rtiGLSZa4dF4bzgmBqQ9aoSfEX4jISt31Vy+skHidXjHHpbsjT24NPhrZgANivL7CxD6
+Ft+s7qS1gL4HRm2twQkqSwOLrE/q2QeXl2UCAwEAAaCCAR0wGgYKKwYBBAGCNw0CAzEMFgo2LjIu
+OTIwMC4yMD4GCSqGSIb3DQEJDjExMC8wHQYDVR0OBBYEFMW2skn88gxhONWZQA4sWGBDb68yMA4G
+A1UdDwEB/wQEAwIHgDBXBgkrBgEEAYI3FRQxSjBIAgEFDBlwaXR1Y2hhMS5lbWVhLmhwcWNvcnAu
+bmV0DAxFTUVBXHBpdHVjaGEMGkNNQ1JlcUdlbmVyYXRvci52c2hvc3QuZXhlMGYGCisGAQQBgjcN
+AgIxWDBWAgECHk4ATQBpAGMAcgBvAHMAbwBmAHQAIABTAHQAcgBvAG4AZwAgAEMAcgB5AHAAdABv
+AGcAcgBhAHAAaABpAGMAIABQAHIAbwB2AGkAZABlAHIDAQAwDQYJKoZIhvcNAQEFBQADgYEAJZlu
+mxjtCxSOQi27jsVdd3y8NSIlzNv0b3LqmzvAly6L+CstXcnuG2MPQqPH9R7tbJonGUniBQO9sQ7C
+KhYWj2gfhiEkSID82lV5chINVUFKoUlSiEhWr0tPGgvOaqdsKQcrHfzrsBbFkhDqrFSVy7Yivbnh
+qYszKrOjJKiiCPMwADAAMYH5MIH2AgEDgBTFtrJJ/PIMYTjVmUAOLFhgQ2+vMjAJBgUrDgMCGgUA
+oD4wFwYJKoZIhvcNAQkDMQoGCCsGAQUFBwwCMCMGCSqGSIb3DQEJBDEWBBTFTkK/OifaFjwqHiJu
+xM7qXcg/VzANBgkqhkiG9w0BAQEFAASBgKfC6jOi1Wgy4xxDCQVK9+e5tktL8wE/j2cb9JSqq+aU
+5UxEgXEw7q7BoYZCAzcxMRriGzakXr8aXHcgkRJ7XcFvLPUjpmGg9SOZ2sGW4zQdWAwImN/i8loc
+xicQmJP+VoMHo/ZpjFY9fYCjNZUArgKsEwK/s+p9yrVVeB1Nf8Mn
+"""
+
+ def testDerCodec(self):
+
+ rfc5652.cmsContentTypesMap.update(rfc6402.cmsContentTypesMapUpdate)
+ layers = rfc5652.cmsContentTypesMap
+
+ getNextLayer = {
+ rfc5652.id_ct_contentInfo: lambda x: x['contentType'],
+ rfc5652.id_signedData: lambda x: x['encapContentInfo']['eContentType'],
+ rfc6402.id_cct_PKIData: lambda x: None
+ }
+
+ getNextSubstrate = {
+ rfc5652.id_ct_contentInfo: lambda x: x['content'],
+ rfc5652.id_signedData: lambda x: x['encapContentInfo']['eContent'],
+ rfc6402.id_cct_PKIData: lambda x: None
+ }
+
+ substrate = pem.readBase64fromText(self.pem_text)
+
+ next_layer = rfc5652.id_ct_contentInfo
+ while next_layer:
+ asn1Object, rest = der_decode(substrate, asn1Spec=layers[next_layer])
+ assert not rest
+ assert asn1Object.prettyPrint()
+ assert der_encode(asn1Object) == substrate
+
+ substrate = getNextSubstrate[next_layer](asn1Object)
+ next_layer = getNextLayer[next_layer](asn1Object)
+
+
+ def testOpenTypes(self):
+ class ClientInformation(univ.Sequence):
+ pass
+
+ ClientInformation.componentType = namedtype.NamedTypes(
+ namedtype.NamedType('clientId', univ.Integer()),
+ namedtype.NamedType('MachineName', char.UTF8String()),
+ namedtype.NamedType('UserName', char.UTF8String()),
+ namedtype.NamedType('ProcessName', char.UTF8String())
+ )
+
+ class EnrollmentCSP(univ.Sequence):
+ pass
+
+ EnrollmentCSP.componentType = namedtype.NamedTypes(
+ namedtype.NamedType('KeySpec', univ.Integer()),
+ namedtype.NamedType('Name', char.BMPString()),
+ namedtype.NamedType('Signature', univ.BitString())
+ )
+
+ attributesMapUpdate = {
+ univ.ObjectIdentifier('1.3.6.1.4.1.311.13.2.3'): char.IA5String(),
+ univ.ObjectIdentifier('1.3.6.1.4.1.311.13.2.2'): EnrollmentCSP(),
+ univ.ObjectIdentifier('1.3.6.1.4.1.311.21.20'): ClientInformation(),
+ }
+
+ rfc5652.cmsAttributesMap.update(rfc6402.cmcControlAttributesMap)
+ rfc5652.cmsAttributesMap.update(attributesMapUpdate)
+
+ algorithmIdentifierMapUpdate = {
+ univ.ObjectIdentifier('1.2.840.113549.1.1.1'): univ.Null(""),
+ univ.ObjectIdentifier('1.2.840.113549.1.1.5'): univ.Null(""),
+ univ.ObjectIdentifier('1.2.840.113549.1.1.11'): univ.Null(""),
+ }
+
+ rfc5280.algorithmIdentifierMap.update(algorithmIdentifierMapUpdate)
+
+ rfc5652.cmsContentTypesMap.update(rfc6402.cmsContentTypesMapUpdate)
+
+ substrate = pem.readBase64fromText(self.pem_text)
+ asn1Object, rest = der_decode(substrate,
+ asn1Spec=rfc5652.ContentInfo(),
+ decodeOpenTypes=True)
+ assert not rest
+ assert asn1Object.prettyPrint()
+ assert der_encode(asn1Object) == substrate
+
+ eci = asn1Object['content']['encapContentInfo']
+ assert eci['eContentType'] == rfc6402.id_cct_PKIData
+ substrate = eci['eContent']
+ asn1Object, rest = der_decode(substrate,
+ asn1Spec=rfc6402.PKIData(),
+ decodeOpenTypes=True)
+ assert not rest
+ assert asn1Object.prettyPrint()
+ assert der_encode(asn1Object) == substrate
+
+ for req in asn1Object['reqSequence']:
+ cr = req['tcr']['certificationRequest']
+
+ sig_alg = cr['signatureAlgorithm']
+ assert sig_alg['algorithm'] in rfc5280.algorithmIdentifierMap.keys()
+ assert sig_alg['parameters'] == univ.Null("")
+
+ cri = cr['certificationRequestInfo']
+ spki_alg = cri['subjectPublicKeyInfo']['algorithm']
+ assert spki_alg['algorithm'] in rfc5280.algorithmIdentifierMap.keys()
+ assert spki_alg['parameters'] == univ.Null("")
+
+ attrs = cr['certificationRequestInfo']['attributes']
+ for attr in attrs:
+ assert attr['attrType'] in rfc5652.cmsAttributesMap.keys()
+ if attr['attrType'] == univ.ObjectIdentifier('1.3.6.1.4.1.311.13.2.3'):
+ assert attr['attrValues'][0] == "6.2.9200.2"
+ else:
+ assert attr['attrValues'][0].hasValue()
+
+
+suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__])
+
+if __name__ == '__main__':
+ unittest.TextTestRunner(verbosity=2).run(suite)
diff --git a/tests/test_rfc7030.py b/tests/test_rfc7030.py
new file mode 100644
index 0000000..5708203
--- /dev/null
+++ b/tests/test_rfc7030.py
@@ -0,0 +1,87 @@
+#
+# This file is part of pyasn1-modules software.
+#
+# Created by Russ Housley
+# Copyright (c) 2019, Vigil Security, LLC
+# License: http://snmplabs.com/pyasn1/license.html
+#
+
+import sys
+
+from pyasn1.codec.der.decoder import decode as der_decode
+from pyasn1.codec.der.encoder import encode as der_encode
+
+from pyasn1_modules import pem
+from pyasn1_modules import rfc5652
+from pyasn1_modules import rfc7030
+
+from pyasn1.type import univ
+
+try:
+ import unittest2 as unittest
+except ImportError:
+ import unittest
+
+
+class CSRAttrsTestCase(unittest.TestCase):
+ pem_text = """\
+MEEGCSqGSIb3DQEJBzASBgcqhkjOPQIBMQcGBSuBBAAiMBYGCSqGSIb3DQEJDjEJ
+BgcrBgEBAQEWBggqhkjOPQQDAw==
+"""
+
+ the_oids = (univ.ObjectIdentifier('1.2.840.113549.1.9.7'),
+ univ.ObjectIdentifier('1.2.840.10045.4.3.3'),
+ )
+
+ the_attrTypes = (univ.ObjectIdentifier('1.2.840.10045.2.1'),
+ univ.ObjectIdentifier('1.2.840.113549.1.9.14'),
+ )
+
+ the_attrVals = ('1.3.132.0.34',
+ '1.3.6.1.1.1.1.22',
+ )
+
+
+ def setUp(self):
+ self.asn1Spec = rfc7030.CsrAttrs()
+
+ def testDerCodec(self):
+ substrate = pem.readBase64fromText(self.pem_text)
+ asn1Object, rest = der_decode(substrate, asn1Spec=self.asn1Spec)
+ assert not rest
+ assert asn1Object.prettyPrint()
+ assert der_encode(asn1Object) == substrate
+
+ for attr_or_oid in asn1Object:
+ if attr_or_oid.getName() == 'oid':
+ assert attr_or_oid['oid'] in self.the_oids
+
+ if attr_or_oid.getName() == 'attribute':
+ assert attr_or_oid['attribute']['attrType'] in self.the_attrTypes
+
+ def testOpenTypes(self):
+ for at in self.the_attrTypes:
+ rfc5652.cmsAttributesMap.update({ at: univ.ObjectIdentifier(), })
+
+ substrate = pem.readBase64fromText(self.pem_text)
+ asn1Object, rest = der_decode(substrate,
+ asn1Spec=self.asn1Spec,
+ decodeOpenTypes=True)
+ assert not rest
+ assert asn1Object.prettyPrint()
+ assert der_encode(asn1Object) == substrate
+
+ for attr_or_oid in asn1Object:
+ if attr_or_oid.getName() == 'attribute':
+ valString = attr_or_oid['attribute']['attrValues'][0].prettyPrint()
+
+ if attr_or_oid['attribute']['attrType'] == self.the_attrTypes[0]:
+ assert valString == self.the_attrVals[0]
+
+ if attr_or_oid['attribute']['attrType'] == self.the_attrTypes[1]:
+ assert valString == self.the_attrVals[1]
+
+suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__])
+
+if __name__ == '__main__':
+ unittest.TextTestRunner(verbosity=2).run(suite)
diff --git a/tests/test_rfc7292.py b/tests/test_rfc7292.py
new file mode 100644
index 0000000..8bebef3
--- /dev/null
+++ b/tests/test_rfc7292.py
@@ -0,0 +1,172 @@
+#
+# This file is part of pyasn1-modules software.
+#
+# Created by Russ Housley
+# Copyright (c) 2019, Vigil Security, LLC
+# License: http://snmplabs.com/pyasn1/license.html
+#
+
+import sys
+
+from pyasn1.codec.der.decoder import decode as der_decode
+from pyasn1.codec.der.encoder import encode as der_encode
+
+from pyasn1.type import univ
+
+from pyasn1_modules import pem
+from pyasn1_modules import rfc5652
+from pyasn1_modules import rfc7292
+
+try:
+ import unittest2 as unittest
+except ImportError:
+ import unittest
+
+
+class PKCS12TestCase(unittest.TestCase):
+ pfx_pem_text = """\
+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
+"""
+
+ def setUp(self):
+ self.asn1Spec = rfc7292.PFX()
+
+ def testDerCodec(self):
+ substrate = pem.readBase64fromText(self.pfx_pem_text)
+ asn1Object, rest = der_decode(substrate, asn1Spec=self.asn1Spec)
+ assert not rest
+ assert asn1Object.prettyPrint()
+ assert der_encode(asn1Object) == substrate
+
+ assert asn1Object['version'] == univ.Integer(3)
+ oid = asn1Object['macData']['mac']['digestAlgorithm']['algorithm']
+ assert oid == univ.ObjectIdentifier('1.3.14.3.2.26')
+ md_hex = asn1Object['macData']['mac']['digest'].prettyPrint()
+ assert md_hex == '0xa5608ffdf651d132b90701aeaaf4ddd3e76e88a7'
+
+ assert asn1Object['authSafe']['contentType'] == rfc5652.id_data
+ data, rest = der_decode(asn1Object['authSafe']['content'],
+ asn1Spec=univ.OctetString())
+ assert not rest
+
+ authsafe, rest = der_decode(data, asn1Spec=rfc7292.AuthenticatedSafe())
+ assert not rest
+ assert authsafe.prettyPrint()
+ assert der_encode(authsafe) == data
+
+ for ci in authsafe:
+ assert ci['contentType'] == rfc5652.id_data
+ data, rest = der_decode(ci['content'], asn1Spec=univ.OctetString())
+ assert not rest
+
+ sc, rest = der_decode(data, asn1Spec=rfc7292.SafeContents())
+ assert not rest
+ assert sc.prettyPrint()
+ assert der_encode(sc) == data
+
+ for sb in sc:
+ if sb['bagId'] in rfc7292.pkcs12BagTypeMap:
+ bv, rest = der_decode(sb['bagValue'],
+ asn1Spec=rfc7292.pkcs12BagTypeMap[sb['bagId']])
+ assert not rest
+ assert bv.prettyPrint()
+ assert der_encode(bv) == sb['bagValue']
+
+ for attr in sb['bagAttributes']:
+ if attr['attrType'] in rfc5652.cmsAttributesMap:
+ av, rest = der_decode(attr['attrValues'][0],
+ asn1Spec=rfc5652.cmsAttributesMap[attr['attrType']])
+ assert not rest
+ assert av.prettyPrint()
+ assert der_encode(av) == attr['attrValues'][0]
+
+ def testOpenTypes(self):
+ substrate = pem.readBase64fromText(self.pfx_pem_text)
+ asn1Object, rest = der_decode(substrate,
+ asn1Spec=self.asn1Spec,
+ decodeOpenTypes=True
+ )
+ assert not rest
+ assert asn1Object.prettyPrint()
+ assert der_encode(asn1Object) == substrate
+
+ digest_alg = asn1Object['macData']['mac']['digestAlgorithm']
+ assert not digest_alg['parameters'].hasValue()
+
+ authsafe, rest = der_decode(asn1Object['authSafe']['content'],
+ asn1Spec=rfc7292.AuthenticatedSafe(),
+ decodeOpenTypes=True
+ )
+ assert not rest
+ assert authsafe.prettyPrint()
+ assert der_encode(authsafe) == asn1Object['authSafe']['content']
+
+ for ci in authsafe:
+ assert ci['contentType'] == rfc5652.id_data
+ sc, rest = der_decode(ci['content'],
+ asn1Spec=rfc7292.SafeContents(),
+ decodeOpenTypes=True
+ )
+ assert not rest
+ assert sc.prettyPrint()
+ assert der_encode(sc) == ci['content']
+
+ for sb in sc:
+ if sb['bagId'] == rfc7292.id_pkcs8ShroudedKeyBag:
+ bv = sb['bagValue']
+ enc_alg = bv['encryptionAlgorithm']['algorithm']
+ assert enc_alg == rfc7292.pbeWithSHAAnd3_KeyTripleDES_CBC
+ enc_alg_param = bv['encryptionAlgorithm']['parameters']
+ assert enc_alg_param['iterations'] == 2000
+
+
+suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__])
+
+if __name__ == '__main__':
+ unittest.TextTestRunner(verbosity=2).run(suite)
diff --git a/tests/test_rfc7296.py b/tests/test_rfc7296.py
index bcd28ee..90dc0a3 100644
--- a/tests/test_rfc7296.py
+++ b/tests/test_rfc7296.py
@@ -161,7 +161,4 @@ m9Y=
suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__])
if __name__ == '__main__':
- import sys
-
- result = unittest.TextTestRunner(verbosity=2).run(suite)
- sys.exit(not result.wasSuccessful())
+ unittest.TextTestRunner(verbosity=2).run(suite)
diff --git a/tests/test_rfc8018.py b/tests/test_rfc8018.py
new file mode 100644
index 0000000..f899b54
--- /dev/null
+++ b/tests/test_rfc8018.py
@@ -0,0 +1,56 @@
+#
+# This file is part of pyasn1-modules software.
+#
+# Created by Russ Housley
+# Copyright (c) 2019, Vigil Security, LLC
+# License: http://snmplabs.com/pyasn1/license.html
+#
+
+import sys
+
+from pyasn1.codec.der.decoder import decode as der_decode
+from pyasn1.codec.der.encoder import encode as der_encode
+
+from pyasn1_modules import pem
+from pyasn1_modules import rfc5652
+from pyasn1_modules import rfc8018
+
+try:
+ import unittest2 as unittest
+except ImportError:
+ import unittest
+
+
+class PWRITestCase(unittest.TestCase):
+ rfc3211_ex1_pem_text = """\
+o1MCAQCgGgYJKoZIhvcNAQUMMA0ECBI0Vnh4VjQSAgEFMCAGCyqGSIb3DQEJEAMJMBEGBSsO
+AwIHBAjv5ZjvIbM9bQQQuBslZe43PKbe3KJqF4sMEA==
+"""
+
+ def setUp(self):
+ self.asn1Spec = rfc5652.RecipientInfo()
+
+ def testDerCodec(self):
+ substrate = pem.readBase64fromText(self.rfc3211_ex1_pem_text)
+ asn1Object, rest = der_decode(substrate, asn1Spec=self.asn1Spec)
+ assert not rest
+ assert asn1Object.prettyPrint()
+ assert der_encode(asn1Object) == substrate
+ alg_oid = asn1Object['pwri']['keyDerivationAlgorithm']['algorithm']
+ assert alg_oid == rfc8018.id_PBKDF2
+
+ def testOpenTypes(self):
+ substrate = pem.readBase64fromText(self.rfc3211_ex1_pem_text)
+ asn1Object, rest = der_decode(substrate,
+ asn1Spec=self.asn1Spec,
+ decodeOpenTypes=True)
+ assert not rest
+ assert asn1Object.prettyPrint()
+ assert der_encode(asn1Object) == substrate
+ icount = asn1Object['pwri']['keyDerivationAlgorithm']['parameters']['iterationCount']
+ assert icount == 5
+
+suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__])
+
+if __name__ == '__main__':
+ unittest.TextTestRunner(verbosity=2).run(suite)