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
The prefix OpenSSL
needs for this type when encoding it into an extension. Also used by the YAML serialization in the extensions
Integer tag type. See GeneralName
description at the top of this class
The type, represented as a symbolized version of the GeneralName
(e.g. :dNSName)
Value of the GeneralName
Public Class Methods
@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
@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
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
@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
@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
@private required for uniq comparisons
# File lib/r509/asn1.rb, line 177 def hash "#{self.type}#{self.tag}#{self.value}".hash end
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
@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
# 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
# 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
# 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
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