Path: blob/master/lib/rex/proto/kerberos/model/dmsa_key_package.rb
31164 views
# -*- coding: binary -*-12module Rex3module Proto4module Kerberos5module Model6# This class provides a representation of a Kerberos KERB-DMSA-KEY-PACKAGE7# 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).8class DmsaKeyPackage < Element9attr_accessor :current_keys10attr_accessor :previous_keys11attr_accessor :expiration_interval12attr_accessor :fetch_interval1314def decode(input)15case input16when String17decode_string(input)18when OpenSSL::ASN1::Sequence19decode_asn1(input)20else21raise ::Rex::Proto::Kerberos::Model::Error::KerberosDecodingError, 'Failed to decode DmsaKeyPackage, invalid input'22end2324self25end2627def encode28current_keys_asn1 = OpenSSL::ASN1::ASN1Data.new(encode_keys(current_keys), 0, :CONTEXT_SPECIFIC)29previous_keys_asn1 = previous_keys ? OpenSSL::ASN1::ASN1Data.new(encode_keys(previous_keys), 1, :CONTEXT_SPECIFIC) : nil30expiration_interval_asn1 = OpenSSL::ASN1::ASN1Data.new([encode_time(expiration_interval)], 2, :CONTEXT_SPECIFIC)31fetch_interval_asn1 = OpenSSL::ASN1::ASN1Data.new([encode_time(fetch_interval)], 4, :CONTEXT_SPECIFIC)3233seq = OpenSSL::ASN1::Sequence.new([current_keys_asn1, previous_keys_asn1, expiration_interval_asn1, fetch_interval_asn1].compact)3435seq.to_der36end3738private3940def decode_string(input)41asn1 = OpenSSL::ASN1.decode(input)42decode_asn1(asn1)43end4445def decode_asn1(input)46seq_values = input.value47self.current_keys = decode_keys(seq_values[0])48self.previous_keys = seq_values[1] ? decode_keys(seq_values[1]) : nil49self.expiration_interval = decode_time(seq_values[2])50self.fetch_interval = decode_time(seq_values[3])51end5253def decode_keys(input)54elements = input.is_a?(OpenSSL::ASN1::ASN1Data) ? input.value : input55elements.map do |element|56if element.is_a?(Array)57element.map { |sub_element| decode_type(sub_element) }58else59decode_type(element)60end61end62end6364def decode_type(element)65case element66when OpenSSL::ASN1::Integer67element.value.to_i68when OpenSSL::ASN1::OctetString69element.value70when OpenSSL::ASN1::Sequence, OpenSSL::ASN1::ASN1Data71element.value.map { |sub_element| decode_type(sub_element) }72else73raise ::Rex::Proto::Kerberos::Model::Error::KerberosDecodingError, "Unsupported element type: #{element.class}"74end75end7677def encode_keys(keys)78keys.map(&:encode)79end8081def decode_time(input)82case input83when OpenSSL::ASN1::ASN1Data84generalized_time = input.value.first85if generalized_time.is_a?(OpenSSL::ASN1::GeneralizedTime)86Time.parse(generalized_time.value.to_s)87else88raise ::Rex::Proto::Kerberos::Model::Error::KerberosDecodingError, "Unsupported time element type in ASN1Data: #{generalized_time.class}"89end90when OpenSSL::ASN1::GeneralizedTime91Time.parse(input.value.to_s)92else93raise ::Rex::Proto::Kerberos::Model::Error::KerberosDecodingError, "Unsupported time element type: #{input.class}"94end95end9697def encode_time(time)98time.encode99end100end101end102end103end104end105106