1#
2# This file is being contributed to pyasn1-modules software.
3#
4# Created by Russ Housley.
5# Modified by Russ Housley to add a map for use with opentypes.
6#
7# Copyright (c) 2019, Vigil Security, LLC
8# License: http://snmplabs.com/pyasn1/license.html
9#
10# Asymmetric Key Packages, which is essentially version 2 of
11#   the PrivateKeyInfo structure in PKCS#8 in RFC 5208
12#
13# ASN.1 source from:
14# https://www.rfc-editor.org/rfc/rfc5958.txt
15
16from pyasn1.type import univ, constraint, namedtype, namedval, tag
17
18from pyasn1_modules import rfc5280
19from pyasn1_modules import rfc5652
20
21
22MAX = float('inf')
23
24
25class KeyEncryptionAlgorithmIdentifier(rfc5280.AlgorithmIdentifier):
26    pass
27
28
29class PrivateKeyAlgorithmIdentifier(rfc5280.AlgorithmIdentifier):
30    pass
31
32
33class EncryptedData(univ.OctetString):
34    pass
35
36
37class EncryptedPrivateKeyInfo(univ.Sequence):
38    componentType = namedtype.NamedTypes(
39        namedtype.NamedType('encryptionAlgorithm', KeyEncryptionAlgorithmIdentifier()),
40        namedtype.NamedType('encryptedData', EncryptedData())
41    )
42
43
44class Version(univ.Integer):
45    namedValues = namedval.NamedValues(('v1', 0), ('v2', 1))
46
47
48class PrivateKey(univ.OctetString):
49    pass
50
51
52class Attributes(univ.SetOf):
53    componentType = rfc5652.Attribute()
54
55
56class PublicKey(univ.BitString):
57   pass
58
59
60# OneAsymmetricKey is essentially version 2 of PrivateKeyInfo.
61# If publicKey is present, then the version must be v2;
62# otherwise, the version should be v1.
63
64class OneAsymmetricKey(univ.Sequence):
65    componentType = namedtype.NamedTypes(
66        namedtype.NamedType('version', Version()),
67        namedtype.NamedType('privateKeyAlgorithm', PrivateKeyAlgorithmIdentifier()),
68        namedtype.NamedType('privateKey', PrivateKey()),
69        namedtype.OptionalNamedType('attributes', Attributes().subtype(
70            implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 0))),
71        namedtype.OptionalNamedType('publicKey', PublicKey().subtype(
72            implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 1)))
73    )
74
75
76class PrivateKeyInfo(OneAsymmetricKey):
77    pass
78
79
80# The CMS AsymmetricKeyPackage Content Type
81
82id_ct_KP_aKeyPackage = univ.ObjectIdentifier('2.16.840.1.101.2.1.2.78.5')
83
84class AsymmetricKeyPackage(univ.SequenceOf):
85    pass
86
87AsymmetricKeyPackage.componentType = OneAsymmetricKey()
88AsymmetricKeyPackage.sizeSpec=constraint.ValueSizeConstraint(1, MAX)
89
90
91# Map of Content Type OIDs to Content Types is added to the
92# ones that are in rfc5652.py
93
94_cmsContentTypesMapUpdate = {
95    id_ct_KP_aKeyPackage: AsymmetricKeyPackage(),
96}
97
98rfc5652.cmsContentTypesMap.update(_cmsContentTypesMapUpdate)
99