# -*- coding: binary -*- module Rex module Proto module Kerberos module Model # This class provides a representation of a principal, an asset (e.g., a # workstation user or a network server) on a network. class PrincipalName < Element # @!attribute name_type # @return [Fixnum] The type of name attr_accessor :name_type # @!attribute name_string # @return [Array] A sequence of strings that form a name. attr_accessor :name_string # Decodes a Rex::Proto::Kerberos::Model::PrincipalName # # @param input [String, OpenSSL::ASN1::Sequence] the input to decode from # @return [self] if decoding succeeds # @raise [RuntimeError] if decoding doesn't succeed def decode(input) case input when String decode_string(input) when OpenSSL::ASN1::Sequence decode_asn1(input) else raise ::RuntimeError, 'Failed to decode Principal Name, invalid input' end self end # Encodes a Rex::Proto::Kerberos::Model::PrincipalName into an # ASN.1 String # # @return [String] def encode integer_asn1 = OpenSSL::ASN1::ASN1Data.new([encode_name_type], 0, :CONTEXT_SPECIFIC) string_asn1 = OpenSSL::ASN1::ASN1Data.new([encode_name_string], 1, :CONTEXT_SPECIFIC) seq = OpenSSL::ASN1::Sequence.new([integer_asn1, string_asn1]) seq.to_der end private # Encodes the name_type # # @return [OpenSSL::ASN1::Integer] def encode_name_type int_bn = OpenSSL::BN.new(name_type.to_s) int = OpenSSL::ASN1::Integer.new(int_bn) int end # Encodes the name_string # # @return [OpenSSL::ASN1::Sequence] def encode_name_string strings = [] name_string.each do |s| strings << OpenSSL::ASN1::GeneralString.new(s) end seq_string = OpenSSL::ASN1::Sequence.new(strings) seq_string end # Decodes a Rex::Proto::Kerberos::Model::PrincipalName from an String # # @param input [String] the input to decode from def decode_string(input) asn1 = OpenSSL::ASN1.decode(input) decode_asn1(asn1) end # Decodes a Rex::Proto::Kerberos::Model::PrincipalName from an # OpenSSL::ASN1::Sequence # # @param input [OpenSSL::ASN1::Sequence] the input to decode from def decode_asn1(input) seq_values = input.value self.name_type = decode_name_type(seq_values[0]) self.name_string = decode_name_string(seq_values[1]) end # Decodes the name_type from an OpenSSL::ASN1::ASN1Data # # @param input [OpenSSL::ASN1::ASN1Data] the input to decode from # @return [Fixnum] def decode_name_type(input) input.value[0].value.to_i end # Decodes the name_string from an OpenSSL::ASN1::ASN1Data # # @param input [OpenSSL::ASN1::ASN1Data] the input to decode from # @return [Array] def decode_name_string(input) strings = [] input.value[0].value.each do |v| strings << v.value end strings end end end end end end