You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

193 lines
4.5 KiB

4 years ago
  1. # coding: utf-8
  2. """
  3. ASN.1 type classes for PKCS#12 files. Exports the following items:
  4. - CertBag()
  5. - CrlBag()
  6. - Pfx()
  7. - SafeBag()
  8. - SecretBag()
  9. Other type classes are defined that help compose the types listed above.
  10. """
  11. from __future__ import unicode_literals, division, absolute_import, print_function
  12. from .algos import DigestInfo
  13. from .cms import ContentInfo, SignedData
  14. from .core import (
  15. Any,
  16. BMPString,
  17. Integer,
  18. ObjectIdentifier,
  19. OctetString,
  20. ParsableOctetString,
  21. Sequence,
  22. SequenceOf,
  23. SetOf,
  24. )
  25. from .keys import PrivateKeyInfo, EncryptedPrivateKeyInfo
  26. from .x509 import Certificate, KeyPurposeId
  27. # The structures in this file are taken from https://tools.ietf.org/html/rfc7292
  28. class MacData(Sequence):
  29. _fields = [
  30. ('mac', DigestInfo),
  31. ('mac_salt', OctetString),
  32. ('iterations', Integer, {'default': 1}),
  33. ]
  34. class Version(Integer):
  35. _map = {
  36. 3: 'v3'
  37. }
  38. class AttributeType(ObjectIdentifier):
  39. _map = {
  40. # https://tools.ietf.org/html/rfc2985#page-18
  41. '1.2.840.113549.1.9.20': 'friendly_name',
  42. '1.2.840.113549.1.9.21': 'local_key_id',
  43. # https://support.microsoft.com/en-us/kb/287547
  44. '1.3.6.1.4.1.311.17.1': 'microsoft_local_machine_keyset',
  45. # https://github.com/frohoff/jdk8u-dev-jdk/blob/master/src/share/classes/sun/security/pkcs12/PKCS12KeyStore.java
  46. # this is a set of OIDs, representing key usage, the usual value is a SET of one element OID 2.5.29.37.0
  47. '2.16.840.1.113894.746875.1.1': 'trusted_key_usage',
  48. }
  49. class SetOfAny(SetOf):
  50. _child_spec = Any
  51. class SetOfBMPString(SetOf):
  52. _child_spec = BMPString
  53. class SetOfOctetString(SetOf):
  54. _child_spec = OctetString
  55. class SetOfKeyPurposeId(SetOf):
  56. _child_spec = KeyPurposeId
  57. class Attribute(Sequence):
  58. _fields = [
  59. ('type', AttributeType),
  60. ('values', None),
  61. ]
  62. _oid_specs = {
  63. 'friendly_name': SetOfBMPString,
  64. 'local_key_id': SetOfOctetString,
  65. 'microsoft_csp_name': SetOfBMPString,
  66. 'trusted_key_usage': SetOfKeyPurposeId,
  67. }
  68. def _values_spec(self):
  69. return self._oid_specs.get(self['type'].native, SetOfAny)
  70. _spec_callbacks = {
  71. 'values': _values_spec
  72. }
  73. class Attributes(SetOf):
  74. _child_spec = Attribute
  75. class Pfx(Sequence):
  76. _fields = [
  77. ('version', Version),
  78. ('auth_safe', ContentInfo),
  79. ('mac_data', MacData, {'optional': True})
  80. ]
  81. _authenticated_safe = None
  82. @property
  83. def authenticated_safe(self):
  84. if self._authenticated_safe is None:
  85. content = self['auth_safe']['content']
  86. if isinstance(content, SignedData):
  87. content = content['content_info']['content']
  88. self._authenticated_safe = AuthenticatedSafe.load(content.native)
  89. return self._authenticated_safe
  90. class AuthenticatedSafe(SequenceOf):
  91. _child_spec = ContentInfo
  92. class BagId(ObjectIdentifier):
  93. _map = {
  94. '1.2.840.113549.1.12.10.1.1': 'key_bag',
  95. '1.2.840.113549.1.12.10.1.2': 'pkcs8_shrouded_key_bag',
  96. '1.2.840.113549.1.12.10.1.3': 'cert_bag',
  97. '1.2.840.113549.1.12.10.1.4': 'crl_bag',
  98. '1.2.840.113549.1.12.10.1.5': 'secret_bag',
  99. '1.2.840.113549.1.12.10.1.6': 'safe_contents',
  100. }
  101. class CertId(ObjectIdentifier):
  102. _map = {
  103. '1.2.840.113549.1.9.22.1': 'x509',
  104. '1.2.840.113549.1.9.22.2': 'sdsi',
  105. }
  106. class CertBag(Sequence):
  107. _fields = [
  108. ('cert_id', CertId),
  109. ('cert_value', ParsableOctetString, {'explicit': 0}),
  110. ]
  111. _oid_pair = ('cert_id', 'cert_value')
  112. _oid_specs = {
  113. 'x509': Certificate,
  114. }
  115. class CrlBag(Sequence):
  116. _fields = [
  117. ('crl_id', ObjectIdentifier),
  118. ('crl_value', OctetString, {'explicit': 0}),
  119. ]
  120. class SecretBag(Sequence):
  121. _fields = [
  122. ('secret_type_id', ObjectIdentifier),
  123. ('secret_value', OctetString, {'explicit': 0}),
  124. ]
  125. class SafeContents(SequenceOf):
  126. pass
  127. class SafeBag(Sequence):
  128. _fields = [
  129. ('bag_id', BagId),
  130. ('bag_value', Any, {'explicit': 0}),
  131. ('bag_attributes', Attributes, {'optional': True}),
  132. ]
  133. _oid_pair = ('bag_id', 'bag_value')
  134. _oid_specs = {
  135. 'key_bag': PrivateKeyInfo,
  136. 'pkcs8_shrouded_key_bag': EncryptedPrivateKeyInfo,
  137. 'cert_bag': CertBag,
  138. 'crl_bag': CrlBag,
  139. 'secret_bag': SecretBag,
  140. 'safe_contents': SafeContents
  141. }
  142. SafeContents._child_spec = SafeBag