class R509::ASN1::GeneralName

This class parses ASN.1 GeneralName objects. At the moment it supports rfc822Name, dNSName, directoryName, uniformResourceIdentifier, and iPAddress

GeneralName ::= CHOICE {
     otherName                       [0]     OtherName,
     rfc822Name                      [1]     IA5String,
     dNSName                         [2]     IA5String,
     x400Address                     [3]     ORAddress,
     directoryName                   [4]     Name,
     ediPartyName                    [5]     EDIPartyName,
     uniformResourceIdentifier       [6]     IA5String,
     iPAddress                       [7]     OCTET STRING,
     registeredID                    [8]     OBJECT IDENTIFIER }

Attributes

short_type[R]

The prefix OpenSSL needs for this type when encoding it into an extension. Also used by the YAML serialization in the extensions

tag[R]

Integer tag type. See GeneralName description at the top of this class

type[R]

The type, represented as a symbolized version of the GeneralName (e.g. :dNSName)

value[R]

Value of the GeneralName

Public Class Methods

map_tag_to_short_type(tag) click to toggle source

@param [Integer] tag @return [String] serial prefix

# File lib/r509/asn1.rb, line 130
def self.map_tag_to_short_type(tag)
  case tag
  when 1 then "email"
  when 2 then "DNS"
  when 4 then "dirName"
  when 6 then "URI"
  when 7 then "IP"
  else
    raise R509Error, "Unimplemented GeneralName tag: #{tag}. At this time R509 does not support GeneralName types other than rfc822Name, dNSName, uniformResourceIdentifier, iPAddress, and directoryName"
  end
end
map_tag_to_type(tag) click to toggle source

@param [Integer] tag @return [Symbol] symbol type

# File lib/r509/asn1.rb, line 144
def self.map_tag_to_type(tag)
  case tag
  when 0 then :otherName
  when 1 then :rfc822Name
  when 2 then :dNSName
  when 3 then :x400Address
  when 4 then :directoryName
  when 5 then :ediPartyName
  when 6 then :uniformResourceIdentifier
  when 7 then :iPAddress
  when 8 then :registeredID
  else
    raise R509Error, "Invalid tag #{tag}"
  end
end
map_type_to_tag(type) click to toggle source

Maps a GeneralName type to the integer tag representation @param [String,Symbol] type of GeneralName @return [Integer] tag for the type

# File lib/r509/asn1.rb, line 105
def self.map_type_to_tag(type)
  #        otherName                       [0]     OtherName,
  #        rfc822Name                      [1]     IA5String,
  #        dNSName                         [2]     IA5String,
  #        x400Address                     [3]     ORAddress,
  #        directoryName                   [4]     Name,
  #        ediPartyName                    [5]     EDIPartyName,
  #        uniformResourceIdentifier       [6]     IA5String,
  #        iPAddress                       [7]     OCTET STRING,
  #        registeredID                    [8]     OBJECT IDENTIFIER }
  case type
  when "otherName", :otherName then 0
  when "rfc822Name", :rfc822Name, "email" then 1
  when "dNSName", :dNSName, "DNS" then 2
  when "x400Address", :x400Address then 3
  when "directoryName", :directoryName, "dirName" then 4
  when "ediPartyName", :ediPartyName  then 5
  when "uniformResourceIdentifier", :uniformResourceIdentifier, "URI" then 6
  when "iPAddress", :iPAddress, "IP" then 7
  when "registeredID", :registeredID  then 8
  end
end
new(asn) click to toggle source

@param [OpenSSL::ASN1::ASN1Data,Hash] asn ASN.1 input data. Can also pass a hash with (:tag or :type) and :value keys

# File lib/r509/asn1.rb, line 93
def initialize(asn)
  if asn.is_a?(Hash)
    # this is added via create_item
    parse_hash(asn)
  else
    parse_asn(asn)
  end
end

Public Instance Methods

==(other) click to toggle source

@private required for uniq comparisons @return [Boolean] equality between objects

# File lib/r509/asn1.rb, line 170
def ==(other)
  (other.class == self.class && self.type == other.type && self.value == other.value)
end
Also aliased as: eql?
eql?(other)
Alias for: ==
hash() click to toggle source

@private required for uniq comparisons

# File lib/r509/asn1.rb, line 177
def hash
  "#{self.type}#{self.tag}#{self.value}".hash
end
serialize_name() click to toggle source

Used to serialize GeneralName objects when issuing new certificates inside R509::CertificateAuthority::Signer @return [Hash] conf section and name serialized for OpenSSL extension creation

# File lib/r509/asn1.rb, line 183
def serialize_name
  if self.type == :directoryName
    return serialize_directory_name
  else
    extension_string = self.short_type + ":" + self.value
    return { :conf => nil, :extension_string => extension_string }
  end
end
to_h() click to toggle source

@return [Hash]

# File lib/r509/asn1.rb, line 161
def to_h
  val = (@value.is_a?(R509::Subject)) ? @value.to_h : @value

  { :type => @short_type, :value => val }
end

Private Instance Methods

parse_asn(asn) click to toggle source
# File lib/r509/asn1.rb, line 201
def parse_asn(asn)
  @tag = asn.tag
  @type = R509::ASN1::GeneralName.map_tag_to_type(@tag)
  @short_type = R509::ASN1::GeneralName.map_tag_to_short_type(@tag)
  value = asn.value
  case @tag
  when 1, 2, 6 then @value = value
  when 4 then @value = R509::Subject.new(value.first.to_der)
  when 7
    if value.size == 4 || value.size == 16
      @value = parse_ip(value)
    elsif value.size == 8 # IPv4 with netmask
      @value = parse_ip(value[0, 4], value[4, 4])
    elsif value.size == 32 # IPv6 with netmask
      @value = parse_ip(value[0, 16], value[16, 16])
    end
  end
end
parse_hash(asn) click to toggle source
# File lib/r509/asn1.rb, line 194
def parse_hash(asn)
  @tag = asn[:tag] || R509::ASN1::GeneralName.map_type_to_tag(asn[:type])
  @type = R509::ASN1::GeneralName.map_tag_to_type(@tag)
  @short_type = R509::ASN1::GeneralName.map_tag_to_short_type(@tag)
  @value = (@tag == 4) ? R509::Subject.new(asn[:value]) : asn[:value]
end
parse_ip(value, mask = nil) click to toggle source
# File lib/r509/asn1.rb, line 220
def parse_ip(value, mask = nil)
  ip = IPAddr.new_ntoh(value)
  if mask.nil?
    return ip.to_s
  else
    netmask = IPAddr.new_ntoh(mask)
    return ip.to_s + "/" + netmask.to_s
  end
end
serialize_directory_name() click to toggle source

Serializes directory names.

# File lib/r509/asn1.rb, line 231
def serialize_directory_name
  conf_name = OpenSSL::Random.random_bytes(16).unpack("H*")[0]
  conf = ["[#{conf_name}]"]
  @value.to_a.each do |el|
    conf << "#{el[0]}=#{el[1]}"
  end
  conf = conf.join("\n")
  extension_string = self.short_type + ":" + conf_name
  { :conf => conf, :extension_string => extension_string }
end