Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rapid7
GitHub Repository: rapid7/metasploit-framework
Path: blob/master/lib/rex/proto/crypto_asn1/cms.rb
19721 views
1
module Rex::Proto::CryptoAsn1::Cms
2
class Attribute < RASN1::Model
3
sequence :attribute,
4
content: [
5
objectid(:attribute_type),
6
set_of(:attribute_values, RASN1::Types::Any)
7
]
8
end
9
10
class Certificate
11
# Rather than specifying the entire structure of a certificate, we pass this off
12
# to OpenSSL, effectively providing an interface between RASN and OpenSSL.
13
14
attr_accessor :options
15
16
def initialize(options = {})
17
self.options = options
18
end
19
20
def to_der
21
options[:openssl_certificate]&.to_der || ''
22
end
23
24
# RASN1 Glue method - Say if DER can be built (not default value, not optional without value, has a value)
25
# @return [Boolean]
26
# @since 0.12
27
def can_build?
28
!to_der.empty?
29
end
30
31
# RASN1 Glue method
32
def primitive?
33
false
34
end
35
36
# RASN1 Glue method
37
def value
38
options[:openssl_certificate]
39
end
40
41
def parse!(str, ber: false)
42
options[:openssl_certificate] = OpenSSL::X509::Certificate.new(str)
43
to_der.length
44
end
45
end
46
47
# see: https://datatracker.ietf.org/doc/rfc5911/
48
class CCMParameters < RASN1::Model
49
sequence :gcm_parameters,
50
content: [
51
octet_string(:aes_nonce),
52
integer(:aes_ccm_icvlen)
53
]
54
end
55
56
# see: https://datatracker.ietf.org/doc/rfc5911/
57
class GCMParameters < RASN1::Model
58
sequence :gcm_parameters,
59
content: [
60
octet_string(:aes_nonce),
61
integer(:aes_gcm_icvlen)
62
]
63
end
64
65
class AlgorithmIdentifier < RASN1::Model
66
sequence :algorithm_identifier,
67
content: [
68
objectid(:algorithm),
69
any(:parameters, optional: true)
70
]
71
72
def ccm_parameters
73
CCMParameters.parse(self[:parameters].value)
74
end
75
76
def gcm_parameters
77
GCMParameters.parse(self[:parameters].value)
78
end
79
end
80
81
class KeyDerivationAlgorithmIdentifier < AlgorithmIdentifier
82
end
83
84
class KeyEncryptionAlgorithmIdentifier < AlgorithmIdentifier
85
end
86
87
class ContentEncryptionAlgorithmIdentifier < AlgorithmIdentifier
88
end
89
90
class OriginatorInfo < RASN1::Model
91
sequence :originator_info,
92
content: [set_of(:certs, Certificate, implicit: 0, optional: true),]
93
# CRLs - not implemented
94
end
95
96
class ContentType < RASN1::Types::ObjectId
97
end
98
99
class EncryptedContent < RASN1::Types::OctetString
100
end
101
102
class EncryptedContentInfo < RASN1::Model
103
sequence :encrypted_content_info,
104
content: [
105
model(:content_type, ContentType),
106
model(:content_encryption_algorithm, ContentEncryptionAlgorithmIdentifier),
107
wrapper(model(:encrypted_content, EncryptedContent), implicit: 0, optional: true)
108
]
109
end
110
111
class Name
112
# Rather than specifying the entire structure of a name, we pass this off
113
# to OpenSSL, effectively providing an interface between RASN and OpenSSL.
114
attr_accessor :value
115
116
def initialize(options = {}); end
117
118
def parse!(str, ber: false)
119
self.value = OpenSSL::X509::Name.new(str)
120
to_der.length
121
end
122
123
def to_der
124
value.to_der
125
end
126
end
127
128
class IssuerAndSerialNumber < RASN1::Model
129
sequence :signer_identifier,
130
content: [
131
model(:issuer, Name),
132
integer(:serial_number)
133
]
134
end
135
136
class CmsVersion < RASN1::Types::Integer
137
end
138
139
class SubjectKeyIdentifier < RASN1::Types::OctetString
140
end
141
142
class UserKeyingMaterial < RASN1::Types::OctetString
143
end
144
145
class RecipientIdentifier < RASN1::Model
146
choice :recipient_identifier,
147
content: [
148
model(:issuer_and_serial_number, IssuerAndSerialNumber),
149
wrapper(model(:subject_key_identifier, SubjectKeyIdentifier), implicit: 0)
150
]
151
end
152
153
class EncryptedKey < RASN1::Types::OctetString
154
end
155
156
class OtherKeyAttribute < RASN1::Model
157
sequence :other_key_attribute,
158
content: [
159
objectid(:key_attr_id),
160
any(:key_attr, optional: true)
161
]
162
end
163
164
class RecipientKeyIdentifier < RASN1::Model
165
sequence :recipient_key_identifier,
166
content: [
167
model(:subject_key_identifier, SubjectKeyIdentifier),
168
generalized_time(:date, optional: true),
169
wrapper(model(:other, OtherKeyAttribute), optional: true)
170
]
171
172
end
173
174
class KeyAgreeRecipientIdentifier < RASN1::Model
175
choice :key_agree_recipient_identifier,
176
content: [
177
model(:issuer_and_serial_number, IssuerAndSerialNumber),
178
wrapper(model(:r_key_id, RecipientKeyIdentifier), implicit: 0)
179
]
180
end
181
182
class RecipientEncryptedKey < RASN1::Model
183
sequence :recipient_encrypted_key,
184
content: [
185
model(:rid, KeyAgreeRecipientIdentifier),
186
model(:encrypted_key, EncryptedKey)
187
]
188
end
189
190
class KEKIdentifier < RASN1::Model
191
sequence :kek_identifier,
192
content: [
193
octet_string(:key_identifier),
194
generalized_time(:date, optional: true),
195
wrapper(model(:other, OtherKeyAttribute), optional: true)
196
]
197
end
198
199
class KeyTransRecipientInfo < RASN1::Model
200
sequence :key_trans_recipient_info,
201
content: [
202
model(:cms_version, CmsVersion),
203
model(:rid, RecipientIdentifier),
204
model(:key_encryption_algorithm, KeyEncryptionAlgorithmIdentifier),
205
model(:encrypted_key, EncryptedKey)
206
]
207
end
208
209
class OriginatorPublicKey < RASN1::Model
210
sequence :originator_public_key,
211
content: [
212
model(:algorithm, AlgorithmIdentifier),
213
bit_string(:public_key)
214
]
215
end
216
217
class OriginatorIdentifierOrKey < RASN1::Model
218
choice :originator_identifier_or_key,
219
content: [
220
model(:issuer_and_serial_number, IssuerAndSerialNumber),
221
model(:subject_key_identifier, SubjectKeyIdentifier),
222
model(:originator_public_key, OriginatorPublicKey)
223
]
224
end
225
226
class KeyAgreeRecipientInfo < RASN1::Model
227
sequence :key_agree_recipient_info,
228
content: [
229
model(:cms_version, CmsVersion),
230
wrapper(model(:originator, OriginatorIdentifierOrKey), explicit: 0),
231
wrapper(model(:ukm, UserKeyingMaterial), explicit: 1, optional: true),
232
model(:key_encryption_algorithm, KeyEncryptionAlgorithmIdentifier),
233
sequence_of(:recipient_encrypted_keys, RecipientEncryptedKey)
234
]
235
end
236
237
class KEKRecipientInfo < RASN1::Model
238
sequence :kek_recipient_info,
239
content: [
240
model(:cms_version, CmsVersion),
241
model(:kekid, KEKIdentifier),
242
model(:key_encryption_algorithm, KeyEncryptionAlgorithmIdentifier),
243
model(:encrypted_key, EncryptedKey)
244
]
245
end
246
247
class PasswordRecipientInfo < RASN1::Model
248
sequence :password_recipient_info,
249
content: [
250
model(:cms_version, CmsVersion),
251
wrapper(model(:key_derivation_algorithm, KeyDerivationAlgorithmIdentifier), explicit: 0, optional: true),
252
model(:key_encryption_algorithm, KeyEncryptionAlgorithmIdentifier),
253
model(:encrypted_key, EncryptedKey)
254
]
255
end
256
257
class OtherRecipientInfo < RASN1::Model
258
sequence :other_recipient_info,
259
content: [
260
objectid(:ore_type),
261
any(:ory_value)
262
]
263
end
264
265
class RecipientInfo < RASN1::Model
266
choice :recipient_info,
267
content: [
268
model(:ktri, KeyTransRecipientInfo),
269
wrapper(model(:kari, KeyAgreeRecipientInfo), implicit: 1),
270
wrapper(model(:kekri, KEKRecipientInfo), implicit: 2),
271
wrapper(model(:pwri, PasswordRecipientInfo), implicit: 3),
272
wrapper(model(:ori, OtherRecipientInfo), implicit: 4)
273
]
274
end
275
276
class EnvelopedData < RASN1::Model
277
sequence :enveloped_data,
278
explicit: 0, constructed: true,
279
content: [
280
model(:cms_version, CmsVersion),
281
wrapper(model(:originator_info, OriginatorInfo), implict: 0, optional: true),
282
set_of(:recipient_infos, RecipientInfo),
283
model(:encrypted_content_info, EncryptedContentInfo),
284
set_of(:unprotected_attrs, Attribute, implicit: 1, optional: true),
285
]
286
end
287
288
class SignerInfo < RASN1::Model
289
sequence :signer_info,
290
content: [
291
integer(:version),
292
model(:sid, IssuerAndSerialNumber),
293
model(:digest_algorithm, AlgorithmIdentifier),
294
set_of(:signed_attrs, Attribute, implicit: 0, optional: true),
295
model(:signature_algorithm, AlgorithmIdentifier),
296
octet_string(:signature),
297
]
298
end
299
300
class EncapsulatedContentInfo < RASN1::Model
301
sequence :encapsulated_content_info,
302
content: [
303
objectid(:econtent_type),
304
octet_string(:econtent, explicit: 0, constructed: true, optional: true)
305
]
306
307
def econtent
308
if self[:econtent_type].value == Rex::Proto::CryptoAsn1::OIDs::OID_DIFFIE_HELLMAN_KEYDATA.value
309
Rex::Proto::Kerberos::Model::Pkinit::KdcDhKeyInfo.parse(self[:econtent].value)
310
elsif self[:econtent_type].value == Rex::Proto::Kerberos::Model::OID::PkinitAuthData
311
Rex::Proto::Kerberos::Model::Pkinit::AuthPack.parse(self[:econtent].value)
312
end
313
end
314
end
315
316
class SignedData < RASN1::Model
317
sequence :signed_data,
318
explicit: 0, constructed: true,
319
content: [
320
integer(:version),
321
set_of(:digest_algorithms, AlgorithmIdentifier),
322
model(:encap_content_info, EncapsulatedContentInfo),
323
set_of(:certificates, Certificate, implicit: 0, optional: true),
324
# CRLs - not implemented
325
set_of(:signer_infos, SignerInfo)
326
]
327
end
328
329
class ContentInfo < RASN1::Model
330
sequence :content_info,
331
content: [
332
model(:content_type, ContentType),
333
any(:data)
334
]
335
336
def enveloped_data
337
if self[:content_type].value == Rex::Proto::CryptoAsn1::OIDs::OID_CMS_ENVELOPED_DATA.value
338
EnvelopedData.parse(self[:data].value)
339
end
340
end
341
342
def signed_data
343
if self[:content_type].value == Rex::Proto::CryptoAsn1::OIDs::OID_CMS_SIGNED_DATA.value
344
SignedData.parse(self[:data].value)
345
end
346
end
347
end
348
end
349
350