CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/lib/rex/proto/kerberos/model/pkinit.rb
Views: 11766
1
# -*- coding: binary -*-
2
require 'rasn1'
3
4
module Rex
5
module Proto
6
module Kerberos
7
module Model
8
# Contains the models for PKINIT-related ASN1 structures
9
# These use the RASN1 library to define the types
10
module Pkinit
11
class AlgorithmIdentifier < RASN1::Model
12
sequence :algorithm_identifier,
13
content: [objectid(:algorithm),
14
any(:parameters, optional: true)
15
]
16
end
17
18
class Attribute < RASN1::Model
19
sequence :attribute,
20
content: [objectid(:attribute_type),
21
set_of(:attribute_values, RASN1::Types::Any)
22
]
23
end
24
25
class AttributeTypeAndValue < RASN1::Model
26
sequence :attribute_type_and_value,
27
content: [objectid(:attribute_type),
28
any(:attribute_value)
29
]
30
end
31
32
class Certificate
33
# Rather than specifying the entire structure of a certificate, we pass this off
34
# to OpenSSL, effectively providing an interface between RASN and OpenSSL.
35
36
attr_accessor :options
37
38
def initialize(options={})
39
self.options = options
40
end
41
42
def to_der
43
self.options[:openssl_certificate]&.to_der || ''
44
end
45
46
# RASN1 Glue method - Say if DER can be built (not default value, not optional without value, has a value)
47
# @return [Boolean]
48
# @since 0.12
49
def can_build?
50
!to_der.empty?
51
end
52
53
# RASN1 Glue method
54
def primitive?
55
false
56
end
57
58
# RASN1 Glue method
59
def value
60
options[:openssl_certificate]
61
end
62
63
def parse!(str, ber: false)
64
self.options[:openssl_certificate] = OpenSSL::X509::Certificate.new(str)
65
to_der.length
66
end
67
end
68
69
class ContentInfo < RASN1::Model
70
sequence :content_info,
71
content: [objectid(:content_type),
72
# In our case, expected to be SignedData
73
any(:signed_data)
74
]
75
76
def signed_data
77
if self[:content_type].value == '1.2.840.113549.1.7.2'
78
SignedData.parse(self[:signed_data].value)
79
end
80
end
81
end
82
83
class DomainParameters < RASN1::Model
84
sequence :domain_parameters,
85
content: [integer(:p),
86
integer(:g),
87
integer(:q),
88
integer(:j, optional: true),
89
#model(:validationParms, ValidationParms) # Not used, so not implemented
90
]
91
end
92
93
class EncapsulatedContentInfo < RASN1::Model
94
sequence :encapsulated_content_info,
95
content: [objectid(:econtent_type),
96
octet_string(:econtent, explicit: 0, constructed: true, optional: true)
97
]
98
99
def econtent
100
if self[:econtent_type].value == '1.3.6.1.5.2.3.2'
101
KdcDhKeyInfo.parse(self[:econtent].value)
102
elsif self[:econtent_type].value == '1.3.6.1.5.2.3.1'
103
AuthPack.parse(self[:econtent].value)
104
end
105
end
106
end
107
108
class Name
109
# Rather than specifying the entire structure of a name, we pass this off
110
# to OpenSSL, effectively providing an interface between RASN and OpenSSL.
111
attr_accessor :value
112
113
def initialize(options={})
114
end
115
116
def parse!(str, ber: false)
117
self.value = OpenSSL::X509::Name.new(str)
118
to_der.length
119
end
120
121
def to_der
122
self.value.to_der
123
end
124
end
125
126
class IssuerAndSerialNumber < RASN1::Model
127
sequence :signer_identifier,
128
content: [model(:issuer, Name),
129
integer(:serial_number)
130
]
131
end
132
133
class KdcDhKeyInfo < RASN1::Model
134
sequence :kdc_dh_key_info,
135
content: [bit_string(:subject_public_key, explicit: 0, constructed: true),
136
integer(:nonce, implicit: 1, constructed: true),
137
generalized_time(:dh_key_expiration, explicit: 2, constructed: true)
138
]
139
end
140
141
class PkAuthenticator < RASN1::Model
142
sequence :pk_authenticator,
143
explicit: 0, constructed: true,
144
content: [integer(:cusec, constructed: true, explicit: 0),
145
generalized_time(:ctime, constructed: true, explicit: 1),
146
integer(:nonce, constructed: true, explicit: 2),
147
octet_string(:pa_checksum, constructed: true, explicit: 3, optional: true)
148
]
149
end
150
151
class SignerInfo < RASN1::Model
152
sequence :signer_info,
153
content: [integer(:version),
154
model(:sid, IssuerAndSerialNumber),
155
model(:digest_algorithm, AlgorithmIdentifier),
156
set_of(:signed_attrs, Attribute, implicit: 0, optional: true),
157
model(:signature_algorithm, AlgorithmIdentifier),
158
octet_string(:signature),
159
]
160
end
161
162
class SignedData < RASN1::Model
163
sequence :signed_data,
164
explicit: 0, constructed: true,
165
content: [integer(:version),
166
set_of(:digest_algorithms, AlgorithmIdentifier),
167
model(:encap_content_info, EncapsulatedContentInfo),
168
set_of(:certificates, Certificate, implicit: 0, optional: true),
169
# CRLs - not implemented
170
set_of(:signer_infos, SignerInfo)
171
]
172
end
173
174
class SubjectPublicKeyInfo < RASN1::Model
175
sequence :subject_public_key_info,
176
explicit: 1, constructed: true, optional: true,
177
content: [model(:algorithm, AlgorithmIdentifier),
178
bit_string(:subject_public_key)
179
]
180
end
181
182
class AuthPack < RASN1::Model
183
sequence :auth_pack,
184
content: [model(:pk_authenticator, PkAuthenticator),
185
model(:client_public_value, SubjectPublicKeyInfo),
186
octet_string(:client_dh_nonce, implicit: 3, constructed: true, optional: true)
187
]
188
end
189
end
190
end
191
end
192
end
193
end
194
195
196