| # coding: utf-8 |
| |
| """ |
| ASN.1 type classes for PKCS#12 files. Exports the following items: |
| |
| - CertBag() |
| - CrlBag() |
| - Pfx() |
| - SafeBag() |
| - SecretBag() |
| |
| Other type classes are defined that help compose the types listed above. |
| """ |
| |
| from __future__ import unicode_literals, division, absolute_import, print_function |
| |
| from .algos import DigestInfo |
| from .cms import ContentInfo, SignedData |
| from .core import ( |
| Any, |
| BMPString, |
| Integer, |
| ObjectIdentifier, |
| OctetString, |
| ParsableOctetString, |
| Sequence, |
| SequenceOf, |
| SetOf, |
| ) |
| from .keys import PrivateKeyInfo, EncryptedPrivateKeyInfo |
| from .x509 import Certificate, KeyPurposeId |
| |
| |
| # The structures in this file are taken from https://tools.ietf.org/html/rfc7292 |
| |
| class MacData(Sequence): |
| _fields = [ |
| ('mac', DigestInfo), |
| ('mac_salt', OctetString), |
| ('iterations', Integer, {'default': 1}), |
| ] |
| |
| |
| class Version(Integer): |
| _map = { |
| 3: 'v3' |
| } |
| |
| |
| class AttributeType(ObjectIdentifier): |
| _map = { |
| # https://tools.ietf.org/html/rfc2985#page-18 |
| '1.2.840.113549.1.9.20': 'friendly_name', |
| '1.2.840.113549.1.9.21': 'local_key_id', |
| # https://support.microsoft.com/en-us/kb/287547 |
| '1.3.6.1.4.1.311.17.1': 'microsoft_local_machine_keyset', |
| # https://github.com/frohoff/jdk8u-dev-jdk/blob/master/src/share/classes/sun/security/pkcs12/PKCS12KeyStore.java |
| # this is a set of OIDs, representing key usage, the usual value is a SET of one element OID 2.5.29.37.0 |
| '2.16.840.1.113894.746875.1.1': 'trusted_key_usage', |
| } |
| |
| |
| class SetOfAny(SetOf): |
| _child_spec = Any |
| |
| |
| class SetOfBMPString(SetOf): |
| _child_spec = BMPString |
| |
| |
| class SetOfOctetString(SetOf): |
| _child_spec = OctetString |
| |
| |
| class SetOfKeyPurposeId(SetOf): |
| _child_spec = KeyPurposeId |
| |
| |
| class Attribute(Sequence): |
| _fields = [ |
| ('type', AttributeType), |
| ('values', None), |
| ] |
| |
| _oid_specs = { |
| 'friendly_name': SetOfBMPString, |
| 'local_key_id': SetOfOctetString, |
| 'microsoft_csp_name': SetOfBMPString, |
| 'trusted_key_usage': SetOfKeyPurposeId, |
| } |
| |
| def _values_spec(self): |
| return self._oid_specs.get(self['type'].native, SetOfAny) |
| |
| _spec_callbacks = { |
| 'values': _values_spec |
| } |
| |
| |
| class Attributes(SetOf): |
| _child_spec = Attribute |
| |
| |
| class Pfx(Sequence): |
| _fields = [ |
| ('version', Version), |
| ('auth_safe', ContentInfo), |
| ('mac_data', MacData, {'optional': True}) |
| ] |
| |
| _authenticated_safe = None |
| |
| @property |
| def authenticated_safe(self): |
| if self._authenticated_safe is None: |
| content = self['auth_safe']['content'] |
| if isinstance(content, SignedData): |
| content = content['content_info']['content'] |
| self._authenticated_safe = AuthenticatedSafe.load(content.native) |
| return self._authenticated_safe |
| |
| |
| class AuthenticatedSafe(SequenceOf): |
| _child_spec = ContentInfo |
| |
| |
| class BagId(ObjectIdentifier): |
| _map = { |
| '1.2.840.113549.1.12.10.1.1': 'key_bag', |
| '1.2.840.113549.1.12.10.1.2': 'pkcs8_shrouded_key_bag', |
| '1.2.840.113549.1.12.10.1.3': 'cert_bag', |
| '1.2.840.113549.1.12.10.1.4': 'crl_bag', |
| '1.2.840.113549.1.12.10.1.5': 'secret_bag', |
| '1.2.840.113549.1.12.10.1.6': 'safe_contents', |
| } |
| |
| |
| class CertId(ObjectIdentifier): |
| _map = { |
| '1.2.840.113549.1.9.22.1': 'x509', |
| '1.2.840.113549.1.9.22.2': 'sdsi', |
| } |
| |
| |
| class CertBag(Sequence): |
| _fields = [ |
| ('cert_id', CertId), |
| ('cert_value', ParsableOctetString, {'explicit': 0}), |
| ] |
| |
| _oid_pair = ('cert_id', 'cert_value') |
| _oid_specs = { |
| 'x509': Certificate, |
| } |
| |
| |
| class CrlBag(Sequence): |
| _fields = [ |
| ('crl_id', ObjectIdentifier), |
| ('crl_value', OctetString, {'explicit': 0}), |
| ] |
| |
| |
| class SecretBag(Sequence): |
| _fields = [ |
| ('secret_type_id', ObjectIdentifier), |
| ('secret_value', OctetString, {'explicit': 0}), |
| ] |
| |
| |
| class SafeContents(SequenceOf): |
| pass |
| |
| |
| class SafeBag(Sequence): |
| _fields = [ |
| ('bag_id', BagId), |
| ('bag_value', Any, {'explicit': 0}), |
| ('bag_attributes', Attributes, {'optional': True}), |
| ] |
| |
| _oid_pair = ('bag_id', 'bag_value') |
| _oid_specs = { |
| 'key_bag': PrivateKeyInfo, |
| 'pkcs8_shrouded_key_bag': EncryptedPrivateKeyInfo, |
| 'cert_bag': CertBag, |
| 'crl_bag': CrlBag, |
| 'secret_bag': SecretBag, |
| 'safe_contents': SafeContents |
| } |
| |
| |
| SafeContents._child_spec = SafeBag |