rfc3739.py 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  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. # Modified by Russ Housley to add WithComponentsConstraints to
  6. # enforce the requirements that are indicated in comments.
  7. #
  8. # Copyright (c) 2019, Vigil Security, LLC
  9. # License: http://snmplabs.com/pyasn1/license.html
  10. #
  11. # Qualified Certificates
  12. #
  13. # ASN.1 source from:
  14. # https://www.rfc-editor.org/rfc/rfc3739.txt
  15. #
  16. from pyasn1.type import char
  17. from pyasn1.type import constraint
  18. from pyasn1.type import namedtype
  19. from pyasn1.type import namedval
  20. from pyasn1.type import opentype
  21. from pyasn1.type import univ
  22. from pyasn1.type import useful
  23. from pyasn1_modules import rfc5280
  24. MAX = float('inf')
  25. # Initialize the qcStatement map
  26. qcStatementMap = { }
  27. # Imports from RFC 5280
  28. AlgorithmIdentifier = rfc5280.AlgorithmIdentifier
  29. AttributeType = rfc5280.AttributeType
  30. DirectoryString = rfc5280.DirectoryString
  31. GeneralName = rfc5280.GeneralName
  32. id_pkix = rfc5280.id_pkix
  33. id_pe = rfc5280.id_pe
  34. # Arc for QC personal data attributes
  35. id_pda = id_pkix + (9, )
  36. # Arc for QC statements
  37. id_qcs = id_pkix + (11, )
  38. # Personal data attributes
  39. id_pda_dateOfBirth = id_pda + (1, )
  40. class DateOfBirth(useful.GeneralizedTime):
  41. pass
  42. id_pda_placeOfBirth = id_pda + (2, )
  43. class PlaceOfBirth(DirectoryString):
  44. pass
  45. id_pda_gender = id_pda + (3, )
  46. class Gender(char.PrintableString):
  47. subtypeSpec = constraint.ConstraintsIntersection(
  48. constraint.ValueSizeConstraint(1, 1),
  49. constraint.SingleValueConstraint('M', 'F', 'm', 'f')
  50. )
  51. id_pda_countryOfCitizenship = id_pda + (4, )
  52. class CountryOfCitizenship(char.PrintableString):
  53. subtypeSpec = constraint.ValueSizeConstraint(2, 2)
  54. # ISO 3166 Country Code
  55. id_pda_countryOfResidence = id_pda + (5, )
  56. class CountryOfResidence(char.PrintableString):
  57. subtypeSpec = constraint.ValueSizeConstraint(2, 2)
  58. # ISO 3166 Country Code
  59. # Biometric info certificate extension
  60. id_pe_biometricInfo = id_pe + (2, )
  61. class PredefinedBiometricType(univ.Integer):
  62. namedValues = namedval.NamedValues(
  63. ('picture', 0),
  64. ('handwritten-signature', 1)
  65. )
  66. subtypeSpec = constraint.SingleValueConstraint(0, 1)
  67. class TypeOfBiometricData(univ.Choice):
  68. componentType = namedtype.NamedTypes(
  69. namedtype.NamedType('predefinedBiometricType', PredefinedBiometricType()),
  70. namedtype.NamedType('biometricDataOid', univ.ObjectIdentifier())
  71. )
  72. class BiometricData(univ.Sequence):
  73. componentType = namedtype.NamedTypes(
  74. namedtype.NamedType('typeOfBiometricData', TypeOfBiometricData()),
  75. namedtype.NamedType('hashAlgorithm', AlgorithmIdentifier()),
  76. namedtype.NamedType('biometricDataHash', univ.OctetString()),
  77. namedtype.OptionalNamedType('sourceDataUri', char.IA5String())
  78. )
  79. class BiometricSyntax(univ.SequenceOf):
  80. componentType = BiometricData()
  81. # QC Statements certificate extension
  82. # NOTE: This extension does not allow to mix critical and
  83. # non-critical Qualified Certificate Statements. Either all
  84. # statements must be critical or all statements must be
  85. # non-critical.
  86. id_pe_qcStatements = id_pe + (3, )
  87. class NameRegistrationAuthorities(univ.SequenceOf):
  88. componentType = GeneralName()
  89. subtypeSpec=constraint.ValueSizeConstraint(1, MAX)
  90. class QCStatement(univ.Sequence):
  91. componentType = namedtype.NamedTypes(
  92. namedtype.NamedType('statementId', univ.ObjectIdentifier()),
  93. namedtype.OptionalNamedType('statementInfo', univ.Any(),
  94. openType=opentype.OpenType('statementId', qcStatementMap))
  95. )
  96. class QCStatements(univ.SequenceOf):
  97. componentType = QCStatement()
  98. class SemanticsInformation(univ.Sequence):
  99. componentType = namedtype.NamedTypes(
  100. namedtype.OptionalNamedType('semanticsIndentifier',
  101. univ.ObjectIdentifier()),
  102. namedtype.OptionalNamedType('nameRegistrationAuthorities',
  103. NameRegistrationAuthorities())
  104. )
  105. subtypeSpec = constraint.ConstraintsUnion(
  106. constraint.WithComponentsConstraint(
  107. ('semanticsIndentifier', constraint.ComponentPresentConstraint())),
  108. constraint.WithComponentsConstraint(
  109. ('nameRegistrationAuthorities', constraint.ComponentPresentConstraint()))
  110. )
  111. id_qcs = id_pkix + (11, )
  112. id_qcs_pkixQCSyntax_v1 = id_qcs + (1, )
  113. id_qcs_pkixQCSyntax_v2 = id_qcs + (2, )
  114. # Map of Certificate Extension OIDs to Extensions
  115. # To be added to the ones that are in rfc5280.py
  116. _certificateExtensionsMap = {
  117. id_pe_biometricInfo: BiometricSyntax(),
  118. id_pe_qcStatements: QCStatements(),
  119. }
  120. rfc5280.certificateExtensionsMap.update(_certificateExtensionsMap)
  121. # Map of AttributeType OIDs to AttributeValue added to the
  122. # ones that are in rfc5280.py
  123. _certificateAttributesMapUpdate = {
  124. id_pda_dateOfBirth: DateOfBirth(),
  125. id_pda_placeOfBirth: PlaceOfBirth(),
  126. id_pda_gender: Gender(),
  127. id_pda_countryOfCitizenship: CountryOfCitizenship(),
  128. id_pda_countryOfResidence: CountryOfResidence(),
  129. }
  130. rfc5280.certificateAttributesMap.update(_certificateAttributesMapUpdate)