| # | |
| # 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 | |
| # Note: pkcs_9_at_smimeCapabilities is not included in the map because | |
| # the definition in RFC 5751 is preferred, which produces the same | |
| # encoding, but it allows different parameters for SMIMECapability | |
| # and AlgorithmIdentifier. | |
| _cmsAttributesMapUpdate = { | |
| # Attribute types for use in PKCS #7 data (a.k.a. CMS) | |
| pkcs_9_at_contentType: ContentType(), | |
| 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) |