# # 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)