1# 2# This file is part of pyasn1-modules software. 3# 4# Created by Russ Housley with assistance from asn1ate v.0.6.0. 5# 6# Copyright (c) 2019, Vigil Security, LLC 7# License: http://snmplabs.com/pyasn1/license.html 8# 9# PKCS#9: Selected Attribute Types (Version 2.0) 10# 11# ASN.1 source from: 12# https://www.rfc-editor.org/rfc/rfc2985.txt 13# 14 15from pyasn1.type import char 16from pyasn1.type import constraint 17from pyasn1.type import namedtype 18from pyasn1.type import namedval 19from pyasn1.type import opentype 20from pyasn1.type import tag 21from pyasn1.type import univ 22from pyasn1.type import useful 23 24from pyasn1_modules import rfc7292 25from pyasn1_modules import rfc5958 26from pyasn1_modules import rfc5652 27from pyasn1_modules import rfc5280 28 29 30def _OID(*components): 31 output = [] 32 for x in tuple(components): 33 if isinstance(x, univ.ObjectIdentifier): 34 output.extend(list(x)) 35 else: 36 output.append(int(x)) 37 38 return univ.ObjectIdentifier(output) 39 40 41MAX = float('inf') 42 43 44# Imports from RFC 5280 45 46AlgorithmIdentifier = rfc5280.AlgorithmIdentifier 47 48Attribute = rfc5280.Attribute 49 50EmailAddress = rfc5280.EmailAddress 51 52Extensions = rfc5280.Extensions 53 54Time = rfc5280.Time 55 56X520countryName = rfc5280.X520countryName 57 58X520SerialNumber = rfc5280.X520SerialNumber 59 60 61# Imports from RFC 5652 62 63ContentInfo = rfc5652.ContentInfo 64 65ContentType = rfc5652.ContentType 66 67Countersignature = rfc5652.Countersignature 68 69MessageDigest = rfc5652.MessageDigest 70 71SignerInfo = rfc5652.SignerInfo 72 73SigningTime = rfc5652.SigningTime 74 75 76# Imports from RFC 5958 77 78EncryptedPrivateKeyInfo = rfc5958.EncryptedPrivateKeyInfo 79 80 81# Imports from RFC 7292 82 83PFX = rfc7292.PFX 84 85 86# TODO: 87# Need a place to import PKCS15Token; it does not yet appear in an RFC 88 89 90# SingleAttribute is the same as Attribute in RFC 5280, except that the 91# attrValues SET must have one and only one member 92 93class AttributeType(univ.ObjectIdentifier): 94 pass 95 96 97class AttributeValue(univ.Any): 98 pass 99 100 101class AttributeValues(univ.SetOf): 102 pass 103 104AttributeValues.componentType = AttributeValue() 105 106 107class SingleAttributeValues(univ.SetOf): 108 pass 109 110SingleAttributeValues.componentType = AttributeValue() 111 112 113class SingleAttribute(univ.Sequence): 114 pass 115 116SingleAttribute.componentType = namedtype.NamedTypes( 117 namedtype.NamedType('type', AttributeType()), 118 namedtype.NamedType('values', 119 AttributeValues().subtype(sizeSpec=constraint.ValueSizeConstraint(1, 1)), 120 openType=opentype.OpenType('type', rfc5280.certificateAttributesMap) 121 ) 122) 123 124 125# CMSAttribute is the same as Attribute in RFC 5652, and CMSSingleAttribute 126# is the companion where the attrValues SET must have one and only one member 127 128CMSAttribute = rfc5652.Attribute 129 130 131class CMSSingleAttribute(univ.Sequence): 132 pass 133 134CMSSingleAttribute.componentType = namedtype.NamedTypes( 135 namedtype.NamedType('attrType', AttributeType()), 136 namedtype.NamedType('attrValues', 137 AttributeValues().subtype(sizeSpec=constraint.ValueSizeConstraint(1, 1)), 138 openType=opentype.OpenType('attrType', rfc5652.cmsAttributesMap) 139 ) 140) 141 142 143# DirectoryString is the same as RFC 5280, except the length is limited to 255 144 145class DirectoryString(univ.Choice): 146 pass 147 148DirectoryString.componentType = namedtype.NamedTypes( 149 namedtype.NamedType('teletexString', char.TeletexString().subtype( 150 subtypeSpec=constraint.ValueSizeConstraint(1, 255))), 151 namedtype.NamedType('printableString', char.PrintableString().subtype( 152 subtypeSpec=constraint.ValueSizeConstraint(1, 255))), 153 namedtype.NamedType('universalString', char.UniversalString().subtype( 154 subtypeSpec=constraint.ValueSizeConstraint(1, 255))), 155 namedtype.NamedType('utf8String', char.UTF8String().subtype( 156 subtypeSpec=constraint.ValueSizeConstraint(1, 255))), 157 namedtype.NamedType('bmpString', char.BMPString().subtype( 158 subtypeSpec=constraint.ValueSizeConstraint(1, 255))) 159) 160 161 162# PKCS9String is DirectoryString with an additional choice of IA5String, 163# and the SIZE is limited to 255 164 165class PKCS9String(univ.Choice): 166 pass 167 168PKCS9String.componentType = namedtype.NamedTypes( 169 namedtype.NamedType('ia5String', char.IA5String().subtype( 170 subtypeSpec=constraint.ValueSizeConstraint(1, 255))), 171 namedtype.NamedType('directoryString', DirectoryString()) 172) 173 174 175# Upper Bounds 176 177pkcs_9_ub_pkcs9String = univ.Integer(255) 178 179pkcs_9_ub_challengePassword = univ.Integer(pkcs_9_ub_pkcs9String) 180 181pkcs_9_ub_emailAddress = univ.Integer(pkcs_9_ub_pkcs9String) 182 183pkcs_9_ub_friendlyName = univ.Integer(pkcs_9_ub_pkcs9String) 184 185pkcs_9_ub_match = univ.Integer(pkcs_9_ub_pkcs9String) 186 187pkcs_9_ub_signingDescription = univ.Integer(pkcs_9_ub_pkcs9String) 188 189pkcs_9_ub_unstructuredAddress = univ.Integer(pkcs_9_ub_pkcs9String) 190 191pkcs_9_ub_unstructuredName = univ.Integer(pkcs_9_ub_pkcs9String) 192 193 194ub_name = univ.Integer(32768) 195 196pkcs_9_ub_placeOfBirth = univ.Integer(ub_name) 197 198pkcs_9_ub_pseudonym = univ.Integer(ub_name) 199 200 201# Object Identifier Arcs 202 203ietf_at = _OID(1, 3, 6, 1, 5, 5, 7, 9) 204 205id_at = _OID(2, 5, 4) 206 207pkcs_9 = _OID(1, 2, 840, 113549, 1, 9) 208 209pkcs_9_mo = _OID(pkcs_9, 0) 210 211smime = _OID(pkcs_9, 16) 212 213certTypes = _OID(pkcs_9, 22) 214 215crlTypes = _OID(pkcs_9, 23) 216 217pkcs_9_oc = _OID(pkcs_9, 24) 218 219pkcs_9_at = _OID(pkcs_9, 25) 220 221pkcs_9_sx = _OID(pkcs_9, 26) 222 223pkcs_9_mr = _OID(pkcs_9, 27) 224 225 226# Object Identifiers for Syntaxes for use with LDAP-accessible directories 227 228pkcs_9_sx_pkcs9String = _OID(pkcs_9_sx, 1) 229 230pkcs_9_sx_signingTime = _OID(pkcs_9_sx, 2) 231 232 233# Object Identifiers for object classes 234 235pkcs_9_oc_pkcsEntity = _OID(pkcs_9_oc, 1) 236 237pkcs_9_oc_naturalPerson = _OID(pkcs_9_oc, 2) 238 239 240# Object Identifiers for matching rules 241 242pkcs_9_mr_caseIgnoreMatch = _OID(pkcs_9_mr, 1) 243 244pkcs_9_mr_signingTimeMatch = _OID(pkcs_9_mr, 2) 245 246 247# PKCS #7 PDU 248 249pkcs_9_at_pkcs7PDU = _OID(pkcs_9_at, 5) 250 251pKCS7PDU = Attribute() 252pKCS7PDU['type'] = pkcs_9_at_pkcs7PDU 253pKCS7PDU['values'][0] = ContentInfo() 254 255 256# PKCS #12 token 257 258pkcs_9_at_userPKCS12 = _OID(2, 16, 840, 1, 113730, 3, 1, 216) 259 260userPKCS12 = Attribute() 261userPKCS12['type'] = pkcs_9_at_userPKCS12 262userPKCS12['values'][0] = PFX() 263 264 265# PKCS #15 token 266 267pkcs_9_at_pkcs15Token = _OID(pkcs_9_at, 1) 268 269# TODO: Once PKCS15Token can be imported, this can be included 270# 271# pKCS15Token = Attribute() 272# userPKCS12['type'] = pkcs_9_at_pkcs15Token 273# userPKCS12['values'][0] = PKCS15Token() 274 275 276# PKCS #8 encrypted private key information 277 278pkcs_9_at_encryptedPrivateKeyInfo = _OID(pkcs_9_at, 2) 279 280encryptedPrivateKeyInfo = Attribute() 281encryptedPrivateKeyInfo['type'] = pkcs_9_at_encryptedPrivateKeyInfo 282encryptedPrivateKeyInfo['values'][0] = EncryptedPrivateKeyInfo() 283 284 285# Electronic-mail address 286 287pkcs_9_at_emailAddress = rfc5280.id_emailAddress 288 289emailAddress = Attribute() 290emailAddress['type'] = pkcs_9_at_emailAddress 291emailAddress['values'][0] = EmailAddress() 292 293 294# Unstructured name 295 296pkcs_9_at_unstructuredName = _OID(pkcs_9, 2) 297 298unstructuredName = Attribute() 299unstructuredName['type'] = pkcs_9_at_unstructuredName 300unstructuredName['values'][0] = PKCS9String() 301 302 303# Unstructured address 304 305pkcs_9_at_unstructuredAddress = _OID(pkcs_9, 8) 306 307unstructuredAddress = Attribute() 308unstructuredAddress['type'] = pkcs_9_at_unstructuredAddress 309unstructuredAddress['values'][0] = DirectoryString() 310 311 312# Date of birth 313 314pkcs_9_at_dateOfBirth = _OID(ietf_at, 1) 315 316dateOfBirth = SingleAttribute() 317dateOfBirth['type'] = pkcs_9_at_dateOfBirth 318dateOfBirth['values'][0] = useful.GeneralizedTime() 319 320 321# Place of birth 322 323pkcs_9_at_placeOfBirth = _OID(ietf_at, 2) 324 325placeOfBirth = SingleAttribute() 326placeOfBirth['type'] = pkcs_9_at_placeOfBirth 327placeOfBirth['values'][0] = DirectoryString() 328 329 330# Gender 331 332class GenderString(char.PrintableString): 333 pass 334 335GenderString.subtypeSpec = constraint.ValueSizeConstraint(1, 1) 336GenderString.subtypeSpec = constraint.SingleValueConstraint("M", "F", "m", "f") 337 338 339pkcs_9_at_gender = _OID(ietf_at, 3) 340 341gender = SingleAttribute() 342gender['type'] = pkcs_9_at_gender 343gender['values'][0] = GenderString() 344 345 346# Country of citizenship 347 348pkcs_9_at_countryOfCitizenship = _OID(ietf_at, 4) 349 350countryOfCitizenship = Attribute() 351countryOfCitizenship['type'] = pkcs_9_at_countryOfCitizenship 352countryOfCitizenship['values'][0] = X520countryName() 353 354 355# Country of residence 356 357pkcs_9_at_countryOfResidence = _OID(ietf_at, 5) 358 359countryOfResidence = Attribute() 360countryOfResidence['type'] = pkcs_9_at_countryOfResidence 361countryOfResidence['values'][0] = X520countryName() 362 363 364# Pseudonym 365 366id_at_pseudonym = _OID(2, 5, 4, 65) 367 368pseudonym = Attribute() 369pseudonym['type'] = id_at_pseudonym 370pseudonym['values'][0] = DirectoryString() 371 372 373# Serial number 374 375id_at_serialNumber = rfc5280.id_at_serialNumber 376 377serialNumber = Attribute() 378serialNumber['type'] = id_at_serialNumber 379serialNumber['values'][0] = X520SerialNumber() 380 381 382# Content type 383 384pkcs_9_at_contentType = rfc5652.id_contentType 385 386contentType = CMSSingleAttribute() 387contentType['attrType'] = pkcs_9_at_contentType 388contentType['attrValues'][0] = ContentType() 389 390 391# Message digest 392 393pkcs_9_at_messageDigest = rfc5652.id_messageDigest 394 395messageDigest = CMSSingleAttribute() 396messageDigest['attrType'] = pkcs_9_at_messageDigest 397messageDigest['attrValues'][0] = MessageDigest() 398 399 400# Signing time 401 402pkcs_9_at_signingTime = rfc5652.id_signingTime 403 404signingTime = CMSSingleAttribute() 405signingTime['attrType'] = pkcs_9_at_signingTime 406signingTime['attrValues'][0] = SigningTime() 407 408 409# Random nonce 410 411class RandomNonce(univ.OctetString): 412 pass 413 414RandomNonce.subtypeSpec = constraint.ValueSizeConstraint(4, MAX) 415 416 417pkcs_9_at_randomNonce = _OID(pkcs_9_at, 3) 418 419randomNonce = CMSSingleAttribute() 420randomNonce['attrType'] = pkcs_9_at_randomNonce 421randomNonce['attrValues'][0] = RandomNonce() 422 423 424# Sequence number 425 426class SequenceNumber(univ.Integer): 427 pass 428 429SequenceNumber.subtypeSpec = constraint.ValueRangeConstraint(1, MAX) 430 431 432pkcs_9_at_sequenceNumber = _OID(pkcs_9_at, 4) 433 434sequenceNumber = CMSSingleAttribute() 435sequenceNumber['attrType'] = pkcs_9_at_sequenceNumber 436sequenceNumber['attrValues'][0] = SequenceNumber() 437 438 439# Countersignature 440 441pkcs_9_at_counterSignature = rfc5652.id_countersignature 442 443counterSignature = CMSAttribute() 444counterSignature['attrType'] = pkcs_9_at_counterSignature 445counterSignature['attrValues'][0] = Countersignature() 446 447 448# Challenge password 449 450pkcs_9_at_challengePassword = _OID(pkcs_9, 7) 451 452challengePassword = SingleAttribute() 453challengePassword['type'] = pkcs_9_at_challengePassword 454challengePassword['values'][0] = DirectoryString() 455 456 457# Extension request 458 459class ExtensionRequest(Extensions): 460 pass 461 462 463pkcs_9_at_extensionRequest = _OID(pkcs_9, 14) 464 465extensionRequest = SingleAttribute() 466extensionRequest['type'] = pkcs_9_at_extensionRequest 467extensionRequest['values'][0] = ExtensionRequest() 468 469 470# Extended-certificate attributes (deprecated) 471 472class AttributeSet(univ.SetOf): 473 pass 474 475AttributeSet.componentType = Attribute() 476 477 478pkcs_9_at_extendedCertificateAttributes = _OID(pkcs_9, 9) 479 480extendedCertificateAttributes = SingleAttribute() 481extendedCertificateAttributes['type'] = pkcs_9_at_extendedCertificateAttributes 482extendedCertificateAttributes['values'][0] = AttributeSet() 483 484 485# Friendly name 486 487class FriendlyName(char.BMPString): 488 pass 489 490FriendlyName.subtypeSpec = constraint.ValueSizeConstraint(1, pkcs_9_ub_friendlyName) 491 492 493pkcs_9_at_friendlyName = _OID(pkcs_9, 20) 494 495friendlyName = SingleAttribute() 496friendlyName['type'] = pkcs_9_at_friendlyName 497friendlyName['values'][0] = FriendlyName() 498 499 500# Local key identifier 501 502pkcs_9_at_localKeyId = _OID(pkcs_9, 21) 503 504localKeyId = SingleAttribute() 505localKeyId['type'] = pkcs_9_at_localKeyId 506localKeyId['values'][0] = univ.OctetString() 507 508 509# Signing description 510 511pkcs_9_at_signingDescription = _OID(pkcs_9, 13) 512 513signingDescription = CMSSingleAttribute() 514signingDescription['attrType'] = pkcs_9_at_signingDescription 515signingDescription['attrValues'][0] = DirectoryString() 516 517 518# S/MIME capabilities 519 520class SMIMECapability(AlgorithmIdentifier): 521 pass 522 523 524class SMIMECapabilities(univ.SequenceOf): 525 pass 526 527SMIMECapabilities.componentType = SMIMECapability() 528 529 530pkcs_9_at_smimeCapabilities = _OID(pkcs_9, 15) 531 532smimeCapabilities = CMSSingleAttribute() 533smimeCapabilities['attrType'] = pkcs_9_at_smimeCapabilities 534smimeCapabilities['attrValues'][0] = SMIMECapabilities() 535 536 537# Certificate Attribute Map 538 539_certificateAttributesMapUpdate = { 540 # Attribute types for use with the "pkcsEntity" object class 541 pkcs_9_at_pkcs7PDU: ContentInfo(), 542 pkcs_9_at_userPKCS12: PFX(), 543 # TODO: Once PKCS15Token can be imported, this can be included 544 # pkcs_9_at_pkcs15Token: PKCS15Token(), 545 pkcs_9_at_encryptedPrivateKeyInfo: EncryptedPrivateKeyInfo(), 546 # Attribute types for use with the "naturalPerson" object class 547 pkcs_9_at_emailAddress: EmailAddress(), 548 pkcs_9_at_unstructuredName: PKCS9String(), 549 pkcs_9_at_unstructuredAddress: DirectoryString(), 550 pkcs_9_at_dateOfBirth: useful.GeneralizedTime(), 551 pkcs_9_at_placeOfBirth: DirectoryString(), 552 pkcs_9_at_gender: GenderString(), 553 pkcs_9_at_countryOfCitizenship: X520countryName(), 554 pkcs_9_at_countryOfResidence: X520countryName(), 555 id_at_pseudonym: DirectoryString(), 556 id_at_serialNumber: X520SerialNumber(), 557 # Attribute types for use with PKCS #10 certificate requests 558 pkcs_9_at_challengePassword: DirectoryString(), 559 pkcs_9_at_extensionRequest: ExtensionRequest(), 560 pkcs_9_at_extendedCertificateAttributes: AttributeSet(), 561} 562 563rfc5280.certificateAttributesMap.update(_certificateAttributesMapUpdate) 564 565 566# CMS Attribute Map 567 568# Note: pkcs_9_at_smimeCapabilities is not included in the map because 569# the definition in RFC 5751 is preferred, which produces the same 570# encoding, but it allows different parameters for SMIMECapability 571# and AlgorithmIdentifier. 572 573_cmsAttributesMapUpdate = { 574 # Attribute types for use in PKCS #7 data (a.k.a. CMS) 575 pkcs_9_at_contentType: ContentType(), 576 pkcs_9_at_messageDigest: MessageDigest(), 577 pkcs_9_at_signingTime: SigningTime(), 578 pkcs_9_at_randomNonce: RandomNonce(), 579 pkcs_9_at_sequenceNumber: SequenceNumber(), 580 pkcs_9_at_counterSignature: Countersignature(), 581 # Attributes for use in PKCS #12 "PFX" PDUs or PKCS #15 tokens 582 pkcs_9_at_friendlyName: FriendlyName(), 583 pkcs_9_at_localKeyId: univ.OctetString(), 584 pkcs_9_at_signingDescription: DirectoryString(), 585 # pkcs_9_at_smimeCapabilities: SMIMECapabilities(), 586} 587 588rfc5652.cmsAttributesMap.update(_cmsAttributesMapUpdate) 589