Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rapid7
GitHub Repository: rapid7/metasploit-framework
Path: blob/master/lib/rex/proto/kerberos/model/dmsa_key_package.rb
31164 views
1
# -*- coding: binary -*-
2
3
module Rex
4
module Proto
5
module Kerberos
6
module Model
7
# This class provides a representation of a Kerberos KERB-DMSA-KEY-PACKAGE
8
# message as defined in [MS-KILE 2.2.13](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-kile/79170b21-ad15-4a1b-99c4-84b3992d9e70).
9
class DmsaKeyPackage < Element
10
attr_accessor :current_keys
11
attr_accessor :previous_keys
12
attr_accessor :expiration_interval
13
attr_accessor :fetch_interval
14
15
def decode(input)
16
case input
17
when String
18
decode_string(input)
19
when OpenSSL::ASN1::Sequence
20
decode_asn1(input)
21
else
22
raise ::Rex::Proto::Kerberos::Model::Error::KerberosDecodingError, 'Failed to decode DmsaKeyPackage, invalid input'
23
end
24
25
self
26
end
27
28
def encode
29
current_keys_asn1 = OpenSSL::ASN1::ASN1Data.new(encode_keys(current_keys), 0, :CONTEXT_SPECIFIC)
30
previous_keys_asn1 = previous_keys ? OpenSSL::ASN1::ASN1Data.new(encode_keys(previous_keys), 1, :CONTEXT_SPECIFIC) : nil
31
expiration_interval_asn1 = OpenSSL::ASN1::ASN1Data.new([encode_time(expiration_interval)], 2, :CONTEXT_SPECIFIC)
32
fetch_interval_asn1 = OpenSSL::ASN1::ASN1Data.new([encode_time(fetch_interval)], 4, :CONTEXT_SPECIFIC)
33
34
seq = OpenSSL::ASN1::Sequence.new([current_keys_asn1, previous_keys_asn1, expiration_interval_asn1, fetch_interval_asn1].compact)
35
36
seq.to_der
37
end
38
39
private
40
41
def decode_string(input)
42
asn1 = OpenSSL::ASN1.decode(input)
43
decode_asn1(asn1)
44
end
45
46
def decode_asn1(input)
47
seq_values = input.value
48
self.current_keys = decode_keys(seq_values[0])
49
self.previous_keys = seq_values[1] ? decode_keys(seq_values[1]) : nil
50
self.expiration_interval = decode_time(seq_values[2])
51
self.fetch_interval = decode_time(seq_values[3])
52
end
53
54
def decode_keys(input)
55
elements = input.is_a?(OpenSSL::ASN1::ASN1Data) ? input.value : input
56
elements.map do |element|
57
if element.is_a?(Array)
58
element.map { |sub_element| decode_type(sub_element) }
59
else
60
decode_type(element)
61
end
62
end
63
end
64
65
def decode_type(element)
66
case element
67
when OpenSSL::ASN1::Integer
68
element.value.to_i
69
when OpenSSL::ASN1::OctetString
70
element.value
71
when OpenSSL::ASN1::Sequence, OpenSSL::ASN1::ASN1Data
72
element.value.map { |sub_element| decode_type(sub_element) }
73
else
74
raise ::Rex::Proto::Kerberos::Model::Error::KerberosDecodingError, "Unsupported element type: #{element.class}"
75
end
76
end
77
78
def encode_keys(keys)
79
keys.map(&:encode)
80
end
81
82
def decode_time(input)
83
case input
84
when OpenSSL::ASN1::ASN1Data
85
generalized_time = input.value.first
86
if generalized_time.is_a?(OpenSSL::ASN1::GeneralizedTime)
87
Time.parse(generalized_time.value.to_s)
88
else
89
raise ::Rex::Proto::Kerberos::Model::Error::KerberosDecodingError, "Unsupported time element type in ASN1Data: #{generalized_time.class}"
90
end
91
when OpenSSL::ASN1::GeneralizedTime
92
Time.parse(input.value.to_s)
93
else
94
raise ::Rex::Proto::Kerberos::Model::Error::KerberosDecodingError, "Unsupported time element type: #{input.class}"
95
end
96
end
97
98
def encode_time(time)
99
time.encode
100
end
101
end
102
end
103
end
104
end
105
end
106