1#
2# This file is part of pyasn1-modules software.
3#
4# Created by Russ Housley with some 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# S/MIME Capabilities for Public Key Definitions
10#
11# ASN.1 source from:
12# https://www.rfc-editor.org/rfc/rfc6664.txt
13#
14
15from pyasn1.type import constraint
16from pyasn1.type import namedtype
17from pyasn1.type import tag
18from pyasn1.type import univ
19
20from pyasn1_modules import rfc5280
21from pyasn1_modules import rfc5751
22from pyasn1_modules import rfc5480
23from pyasn1_modules import rfc4055
24from pyasn1_modules import rfc3279
25
26MAX = float('inf')
27
28
29# Imports from RFC 5280
30
31AlgorithmIdentifier = rfc5280.AlgorithmIdentifier
32
33
34# Imports from RFC 3279
35
36dhpublicnumber = rfc3279.dhpublicnumber
37
38Dss_Parms = rfc3279.Dss_Parms
39
40id_dsa = rfc3279.id_dsa
41
42id_ecPublicKey = rfc3279.id_ecPublicKey
43
44rsaEncryption = rfc3279.rsaEncryption
45
46
47# Imports from RFC 4055
48
49id_mgf1 = rfc4055.id_mgf1
50
51id_RSAES_OAEP = rfc4055.id_RSAES_OAEP
52
53id_RSASSA_PSS = rfc4055.id_RSASSA_PSS
54
55
56# Imports from RFC 5480
57
58ECParameters = rfc5480.ECParameters
59
60id_ecDH = rfc5480.id_ecDH
61
62id_ecMQV = rfc5480.id_ecMQV
63
64
65# RSA
66
67class RSAKeySize(univ.Integer):
68    # suggested values are 1024, 2048, 3072, 4096, 7680, 8192, and 15360;
69    # however, the integer value is not limited to these suggestions
70    pass
71
72
73class RSAKeyCapabilities(univ.Sequence):
74    componentType = namedtype.NamedTypes(
75        namedtype.NamedType('minKeySize', RSAKeySize()),
76        namedtype.OptionalNamedType('maxKeySize', RSAKeySize())
77    )
78
79
80class RsaSsa_Pss_sig_caps(univ.Sequence):
81    componentType = namedtype.NamedTypes(
82        namedtype.NamedType('hashAlg', AlgorithmIdentifier()),
83        namedtype.OptionalNamedType('maskAlg', AlgorithmIdentifier()),
84        namedtype.DefaultedNamedType('trailerField', univ.Integer().subtype(value=1))
85    )
86
87
88# Diffie-Hellman and DSA
89
90class DSAKeySize(univ.Integer):
91    subtypeSpec = constraint.SingleValueConstraint(1024, 2048, 3072, 7680, 15360)
92
93
94class DSAKeyCapabilities(univ.Choice):
95    componentType = namedtype.NamedTypes(
96        namedtype.NamedType('keySizes', univ.Sequence(componentType=namedtype.NamedTypes(
97            namedtype.NamedType('minKeySize',
98                DSAKeySize()),
99            namedtype.OptionalNamedType('maxKeySize',
100                DSAKeySize()),
101            namedtype.OptionalNamedType('maxSizeP',
102                univ.Integer().subtype(explicitTag=tag.Tag(
103                    tag.tagClassContext, tag.tagFormatSimple, 1))),
104            namedtype.OptionalNamedType('maxSizeQ',
105                univ.Integer().subtype(explicitTag=tag.Tag(
106                    tag.tagClassContext, tag.tagFormatSimple, 2))),
107            namedtype.OptionalNamedType('maxSizeG',
108                univ.Integer().subtype(explicitTag=tag.Tag(
109                    tag.tagClassContext, tag.tagFormatSimple, 3)))
110        )).subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 0))),
111        namedtype.NamedType('keyParams',
112            Dss_Parms().subtype(explicitTag=tag.Tag(
113                tag.tagClassContext, tag.tagFormatConstructed, 1)))
114    )
115
116
117# Elliptic Curve
118
119class EC_SMimeCaps(univ.SequenceOf):
120    componentType = ECParameters()
121    subtypeSpec=constraint.ValueSizeConstraint(1, MAX)
122
123
124# Update the SMIMECapabilities Attribute Map in rfc5751.py
125#
126# The map can either include an entry for scap-sa-rsaSSA-PSS or
127# scap-pk-rsaSSA-PSS, but not both.  One is associated with the
128# public key and the other is associated with the signature
129# algorithm; however, they use the same OID.  If you need the
130# other one in your application, copy the map into a local dict,
131# adjust as needed, and pass the local dict to the decoder with
132# openTypes=your_local_map.
133
134_smimeCapabilityMapUpdate = {
135    rsaEncryption: RSAKeyCapabilities(),
136    id_RSASSA_PSS: RSAKeyCapabilities(),
137    # id_RSASSA_PSS: RsaSsa_Pss_sig_caps(),
138    id_RSAES_OAEP: RSAKeyCapabilities(),
139    id_dsa: DSAKeyCapabilities(),
140    dhpublicnumber: DSAKeyCapabilities(),
141    id_ecPublicKey: EC_SMimeCaps(),
142    id_ecDH: EC_SMimeCaps(),
143    id_ecMQV: EC_SMimeCaps(),
144    id_mgf1: AlgorithmIdentifier(),
145}
146
147rfc5751.smimeCapabilityMap.update(_smimeCapabilityMapUpdate)
148