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/authenticator.rb
Views: 11766
1
# -*- coding: binary -*-
2
3
module Rex
4
module Proto
5
module Kerberos
6
module Model
7
# This class provides a representation of an Authenticator, sent with a
8
# ticket to the server to certify the client's knowledge of the encryption
9
# key in the ticket.
10
class Authenticator < Element
11
# @!attribute vno
12
# @return [Integer] The authenticator version number
13
attr_accessor :vno
14
# @!attribute crealm
15
# @return [String] The realm in which the client is registered
16
attr_accessor :crealm
17
# @!attribute cname
18
# @return [Rex::Proto::Kerberos::Model::PrincipalName] The name part of the client's principal
19
# identifier
20
attr_accessor :cname
21
# @!attribute checksum
22
# @return [Rex::Proto::Kerberos::Model::Checksum] The checksum of the application data that
23
# accompanies the KRB_AP_REQ.
24
attr_accessor :checksum
25
# @!attribute cusec
26
# @return [Integer] The microsecond part of the client's timestamp
27
attr_accessor :cusec
28
# @!attribute ctime
29
# @return [Time] The current time of the client's host
30
attr_accessor :ctime
31
# @!attribute subkey
32
# @return [Rex::Proto::Kerberos::Model::EncryptionKey] the client's choice for an encryption
33
# key which is to be used to protect this specific application session
34
attr_accessor :subkey
35
# @!attribute enc_key_usage
36
# @return [Rex::Proto::Kerberos::Crypto::KeyUsage,Integer] The enc key usage number for this authenticator
37
attr_accessor :enc_key_usage
38
# @!attribute sequence_number
39
# @return [Integer] The initial sequence number to be used for future communications
40
attr_accessor :sequence_number
41
42
# Decodes the Rex::Proto::Kerberos::Model::Authenticator from an input
43
#
44
# @param input [String, OpenSSL::ASN1::ASN1Data] the input to decode from
45
# @return [self] if decoding succeeds
46
# @raise [Rex::Proto::Kerberos::Model::Error::KerberosDecodingError] if decoding doesn't succeed
47
def decode(input)
48
case input
49
when String
50
decode_string(input)
51
when OpenSSL::ASN1::ASN1Data
52
decode_asn1(input)
53
else
54
raise ::Rex::Proto::Kerberos::Model::Error::KerberosDecodingError, 'Failed to decode Authenticator, invalid input'
55
end
56
57
self
58
end
59
60
# Encodes the Rex::Proto::Kerberos::Model::Authenticator into an ASN.1 String
61
#
62
# @return [String]
63
def encode
64
elems = []
65
elems << OpenSSL::ASN1::ASN1Data.new([encode_vno], 0, :CONTEXT_SPECIFIC)
66
elems << OpenSSL::ASN1::ASN1Data.new([encode_crealm], 1, :CONTEXT_SPECIFIC)
67
elems << OpenSSL::ASN1::ASN1Data.new([encode_cname], 2, :CONTEXT_SPECIFIC)
68
elems << OpenSSL::ASN1::ASN1Data.new([encode_checksum], 3, :CONTEXT_SPECIFIC) if checksum
69
elems << OpenSSL::ASN1::ASN1Data.new([encode_cusec], 4, :CONTEXT_SPECIFIC)
70
elems << OpenSSL::ASN1::ASN1Data.new([encode_ctime], 5, :CONTEXT_SPECIFIC)
71
elems << OpenSSL::ASN1::ASN1Data.new([encode_subkey], 6, :CONTEXT_SPECIFIC) if subkey
72
elems << OpenSSL::ASN1::ASN1Data.new([encode_sequence_number], 7, :CONTEXT_SPECIFIC) if sequence_number
73
74
seq = OpenSSL::ASN1::Sequence.new(elems)
75
seq_asn1 = OpenSSL::ASN1::ASN1Data.new([seq], AUTHENTICATOR, :APPLICATION)
76
77
seq_asn1.to_der
78
end
79
80
# Encrypts the Rex::Proto::Kerberos::Model::Authenticator
81
#
82
# @param etype [Integer] the crypto schema to encrypt
83
# @param key [String] the key to encrypt
84
# @return [String] the encrypted result
85
# @raise [NotImplementedError] if the encryption schema isn't supported
86
def encrypt(etype, key)
87
raise ::Rex::Proto::Kerberos::Model::Error::KerberosError, 'Missing enc_key_usage' unless enc_key_usage
88
89
data = self.encode
90
encryptor = Rex::Proto::Kerberos::Crypto::Encryption::from_etype(etype)
91
encryptor.encrypt(data, key, enc_key_usage)
92
end
93
94
95
private
96
97
# Encodes the vno field
98
#
99
# @return [OpenSSL::ASN1::Integer]
100
def encode_vno
101
bn = OpenSSL::BN.new(vno.to_s)
102
int = OpenSSL::ASN1::Integer.new(bn)
103
104
int
105
end
106
107
# Encodes the crealm field
108
#
109
# @return [OpenSSL::ASN1::GeneralString]
110
def encode_crealm
111
OpenSSL::ASN1::GeneralString.new(crealm)
112
end
113
114
# Encodes the cname field
115
#
116
# @return [String]
117
def encode_cname
118
cname.encode
119
end
120
121
# Encodes the checksum field
122
#
123
# @return [String]
124
def encode_checksum
125
checksum.encode
126
end
127
128
# Encodes the cusec field
129
#
130
# @return [OpenSSL::ASN1::Integer]
131
def encode_cusec
132
bn = OpenSSL::BN.new(cusec.to_s)
133
int = OpenSSL::ASN1::Integer.new(bn)
134
135
int
136
end
137
138
# Encodes the ctime field
139
#
140
# @return [OpenSSL::ASN1::GeneralizedTime]
141
def encode_ctime
142
OpenSSL::ASN1::GeneralizedTime.new(ctime)
143
end
144
145
# Encodes the subkey field
146
#
147
# @return [String]
148
def encode_subkey
149
subkey.encode
150
end
151
152
# Encodes the sequence_number field
153
#
154
# @return [OpenSSL::ASN1::Integer]
155
def encode_sequence_number
156
bn = OpenSSL::BN.new(sequence_number.to_s)
157
int = OpenSSL::ASN1::Integer.new(bn)
158
159
int
160
end
161
162
# Decodes a Rex::Proto::Kerberos::Model::Authenticator from an String
163
#
164
# @param input [String] the input to decode from
165
def decode_string(input)
166
asn1 = OpenSSL::ASN1.decode(input)
167
168
decode_asn1(asn1)
169
end
170
171
# Decodes a Rex::Proto::Kerberos::Model::Authenticator
172
#
173
# @param input [OpenSSL::ASN1::ASN1Data] the input to decode from
174
# @raise [Rex::Proto::Kerberos::Model::Error::KerberosDecodingError] if decoding doesn't succeed
175
def decode_asn1(input)
176
input.value[0].value.each do |val|
177
case val.tag
178
when 0
179
self.vno = decode_vno(val)
180
when 1
181
self.crealm = decode_crealm(val)
182
when 2
183
self.cname = decode_cname(val)
184
when 4
185
self.cusec = decode_cusec(val)
186
when 5
187
self.ctime = decode_ctime(val)
188
when 6
189
self.subkey = decode_subkey(val)
190
when 7
191
self.sequence_number = decode_sequence_number(val)
192
else
193
raise ::Rex::Proto::Kerberos::Model::Error::KerberosDecodingError, "Failed to decode AUTHENTICATOR SEQUENCE (#{val.tag})"
194
end
195
end
196
end
197
# Decodes the vno from an OpenSSL::ASN1::ASN1Data
198
#
199
# @param input [OpenSSL::ASN1::ASN1Data] the input to decode from
200
# @return [Integer]
201
def decode_vno(input)
202
input.value[0].value.to_i
203
end
204
205
# Decodes the ctime field
206
#
207
# @param input [OpenSSL::ASN1::ASN1Data] the input to decode from
208
# @return [Time]
209
def decode_ctime(input)
210
input.value[0].value
211
end
212
213
# Decodes the cusec field
214
#
215
# @param input [OpenSSL::ASN1::ASN1Data] the input to decode from
216
# @return [Integer]
217
def decode_cusec(input)
218
input.value[0].value
219
end
220
221
# Decodes the crealm field
222
#
223
# @param input [OpenSSL::ASN1::ASN1Data] the input to decode from
224
# @return [String]
225
def decode_crealm(input)
226
input.value[0].value
227
end
228
229
# Decodes the cname field
230
#
231
# @param input [OpenSSL::ASN1::ASN1Data] the input to decode from
232
# @return [Rex::Proto::Kerberos::Model::PrincipalName]
233
def decode_cname(input)
234
Rex::Proto::Kerberos::Model::PrincipalName.decode(input.value[0])
235
end
236
237
# Decodes the sequence_number field
238
#
239
# @param input [OpenSSL::ASN1::ASN1Data] the input to decode from
240
# @return [Integer]
241
def decode_sequence_number(input)
242
input.value[0].value.to_i
243
end
244
245
# Decodes the subkey field
246
#
247
# @param input [OpenSSL::ASN1::ASN1Data] the input to decode from
248
# @return [Integer]
249
def decode_subkey(input)
250
Rex::Proto::Kerberos::Model::EncryptionKey::decode(input.value[0])
251
end
252
end
253
end
254
end
255
end
256
end
257
258