class R509::Subject
The primary subject class. Used for building subject DNs in a sane fashion. @example
subject = R509::Subject.new subject.CN= "test.test" subject.organization= "r509 LLC"
@example
subject = R509::Subject.new([['CN','test.test'],['O','r509 LLC']])
@example
subject = R509::Subject.new(:CN => 'test.test', :O => 'r509 LLC')
@example
# you can also use the friendly getter/setters with custom OIDs R509::OIDMapper.register("1.2.3.4.5.6.7.8","COI","customOID") subject = R509::Subject.new subject.COI="test" # or subject.customOID="test" # or subject.custom_oid="test"
Public Class Methods
new(arg = nil)
click to toggle source
@param [Array, OpenSSL::X509::Name, R509::Subject
, DER, Hash, nil] arg
# File lib/r509/subject.rb, line 24 def initialize(arg = nil) if arg.is_a?(Array) @array = arg elsif arg.is_a?(Hash) @array = arg.map { |k, v| [k.to_s.upcase, v] } elsif arg.is_a?(OpenSSL::X509::Name) sanitizer = R509::NameSanitizer.new @array = sanitizer.sanitize(arg) elsif arg.is_a?(R509::Subject) @array = arg.to_a else @array = [] unless (begin OpenSSL::ASN1.decode(arg) rescue nil end).nil? parse_asn1(arg) end end # see if X509 thinks this is okay name end # @return [OpenSSL::X509::Name] def name OpenSSL::X509::Name.new(@array) end # @return [Boolean] def empty? @array.empty? end # get value for key def [](key) @array.each do |item| if key == item[0] return item[1] end end nil end # set key and value def []=(key, value) added = false @array = @array.map do |item| if key == item[0] added = true [key, value] else item end end unless added @array << [key, value] end # see if X509 thinks this is okay name @array end # @param [String] key item you want deleted def delete(key) @array = @array.select do |item| item[0] != key end end # @return [String] string of form /CN=something.com/O=whatever/L=Locality def to_s name.to_s end # @return [Array] Array of form [['CN','langui.sh']] def to_a @array end # @return [Hash] def to_h hash = {} @array.each do |el| hash[el[0].to_sym] = el[1] end hash end # @return [YAML] def to_yaml self.to_h.to_yaml end # @private def respond_to?(method_sym, include_private = false) method_sym.to_s =~ /([^=]*)/ oid = oid_check(Regexp.last_match[1]) if oid true else super(method_sym, include_private) end end private # Try to build methods for getting/setting various subject attributes # dynamically. this will also cache methods that get built via instance_eval. # This code will also allow you to set subject items for custom oids # defined via R509::OIDMapper # # @example # subject = R509::Subject.new # subject.CN = 'test' # method built via method missing. # def method_missing(method_sym, *args, &block) if method_sym.to_s =~ /(.*)=$/ sn = oid_check(Regexp.last_match[1]) if sn define_dynamic_setter(method_sym, sn) send(method_sym, args.first) else return super(method_sym, *args, &block) end else sn = oid_check(method_sym) if sn define_dynamic_getter(method_sym, sn) send(method_sym) else return super(method_sym, *args, &block) end end end def define_dynamic_setter(name, sn) instance_eval <<-RUBY def #{name}(value) self["#{sn}"]= value end RUBY end def define_dynamic_getter(name, sn) instance_eval <<-RUBY def #{name} self["#{sn}"] end RUBY end def oid_check(name) oid = OpenSSL::ASN1::ObjectId.new(camelize(name)) oid.short_name end def camelize(sym) sym.to_s.split('_').reduce([]) { |a, e| a.push(a.empty? ? e : e.capitalize) }.join end def parse_asn1(asn) asn = OpenSSL::ASN1.decode asn # parsing a subject DN # We have to iterate a sequence, which holds sets. Each set has one value: a sequence, which has 2 values # So it's effectively an array of arrays which each have only one element, which is an array of 2 values. asn.value.each do |set| sn = set.value.first.value.first.value val = set.value.first.value.last.value self[sn] = val end end end
Public Instance Methods
[](key)
click to toggle source
get value for key
# File lib/r509/subject.rb, line 56 def [](key) @array.each do |item| if key == item[0] return item[1] end end nil end
[]=(key, value)
click to toggle source
set key and value
# File lib/r509/subject.rb, line 66 def []=(key, value) added = false @array = @array.map do |item| if key == item[0] added = true [key, value] else item end end unless added @array << [key, value] end # see if X509 thinks this is okay name @array end
camelize(sym)
click to toggle source
# File lib/r509/subject.rb, line 181 def camelize(sym) sym.to_s.split('_').reduce([]) { |a, e| a.push(a.empty? ? e : e.capitalize) }.join end
define_dynamic_getter(name, sn)
click to toggle source
# File lib/r509/subject.rb, line 168 def define_dynamic_getter(name, sn) instance_eval <<-RUBY def #{name} self["#{sn}"] end RUBY end
define_dynamic_setter(name, sn)
click to toggle source
# File lib/r509/subject.rb, line 160 def define_dynamic_setter(name, sn) instance_eval <<-RUBY def #{name}(value) self["#{sn}"]= value end RUBY end
delete(key)
click to toggle source
@param [String] key item you want deleted
# File lib/r509/subject.rb, line 88 def delete(key) @array = @array.select do |item| item[0] != key end end
empty?()
click to toggle source
@return [Boolean]
# File lib/r509/subject.rb, line 51 def empty? @array.empty? end
method_missing(method_sym, *args, &block)
click to toggle source
Try to build methods for getting/setting various subject attributes dynamically. this will also cache methods that get built via instance_eval. This code will also allow you to set subject items for custom oids defined via R509::OIDMapper
@example
subject = R509::Subject.new subject.CN = 'test' # method built via method missing.
Calls superclass method
# File lib/r509/subject.rb, line 140 def method_missing(method_sym, *args, &block) if method_sym.to_s =~ /(.*)=$/ sn = oid_check(Regexp.last_match[1]) if sn define_dynamic_setter(method_sym, sn) send(method_sym, args.first) else return super(method_sym, *args, &block) end else sn = oid_check(method_sym) if sn define_dynamic_getter(method_sym, sn) send(method_sym) else return super(method_sym, *args, &block) end end end
name()
click to toggle source
@return [OpenSSL::X509::Name]
# File lib/r509/subject.rb, line 46 def name OpenSSL::X509::Name.new(@array) end
oid_check(name)
click to toggle source
# File lib/r509/subject.rb, line 176 def oid_check(name) oid = OpenSSL::ASN1::ObjectId.new(camelize(name)) oid.short_name end
parse_asn1(asn)
click to toggle source
# File lib/r509/subject.rb, line 185 def parse_asn1(asn) asn = OpenSSL::ASN1.decode asn # parsing a subject DN # We have to iterate a sequence, which holds sets. Each set has one value: a sequence, which has 2 values # So it's effectively an array of arrays which each have only one element, which is an array of 2 values. asn.value.each do |set| sn = set.value.first.value.first.value val = set.value.first.value.last.value self[sn] = val end end
respond_to?(method_sym, include_private = false)
click to toggle source
@private
Calls superclass method
# File lib/r509/subject.rb, line 119 def respond_to?(method_sym, include_private = false) method_sym.to_s =~ /([^=]*)/ oid = oid_check(Regexp.last_match[1]) if oid true else super(method_sym, include_private) end end
to_a()
click to toggle source
@return [Array] Array of form [['CN','langui.sh']]
# File lib/r509/subject.rb, line 100 def to_a @array end
to_h()
click to toggle source
@return [Hash]
# File lib/r509/subject.rb, line 105 def to_h hash = {} @array.each do |el| hash[el[0].to_sym] = el[1] end hash end
to_s()
click to toggle source
@return [String] string of form /CN=something.com/O=whatever/L=Locality
# File lib/r509/subject.rb, line 95 def to_s name.to_s end
to_yaml()
click to toggle source
@return [YAML]
# File lib/r509/subject.rb, line 114 def to_yaml self.to_h.to_yaml end