2017-09-29 162 views
1

有教程显示,如何将一个属性(如subjectAltName-扩展)添加到证书签名请求(CSR)。例如,我这是怎么枚举有效的别名,创建CSR时:如何从OpenSSL :: X509 :: Request获取属性?

aliases.each do |a| 
    alist << ("DNS:#{a}") 
    alist << ("IP:#{a}") if IPAddress.valid? a 
end 

extension = OpenSSL::X509::ExtensionFactory.new.create_extension(
    'subjectAltName', 
    alist.join(', '), 
    false 
) 
csr.add_attribute OpenSSL::X509::Attribute.new(
    'extReq', 
    OpenSSL::ASN1::Set.new(
     [OpenSSL::ASN1::Sequence.new([extension])] 
    ) 
) 

但是,假设我要从已经存在的CSR任何这样的属性(如一些从磁盘读取)?没有get_attribute方法...是否有一种简单的方法从Request对象中获取原始列表(例如DNS:meow, DNS:127.0.0.1, IP:127.0.0.1)?

回答

0

好吧,这就是我要做的事,现在 - 发现在Ruby的openssl/ssl.rb一些代码后:

def getAliases(csr) 
    attributes = csr.attributes 
    return nil if not attributes 

    seq = nil 
    values = nil 

    attributes.each do |a| 
     if a.oid == 'extReq' 
      seq = a.value 
      break 
     end 
    end 
    return nil if not seq 

    seq.value.each do |v| 
     v.each do |v| 
      if v.value[0].value == 'subjectAltName' 
       values = v.value[1].value 
       break 
      end 
      break if values 
     end 
    end 
    return nil if not values 

    values = OpenSSL::ASN1.decode(values).value 

    result = [] 
    values.each do |v| 
     case v.tag 
     when 2 
      result << "DNS:#{v.value}" 
     when 7 
      case v.value.size 
      when 4 
       ip = v.value.unpack('C*').join('.') 
      when 16 
       ip = v.value.unpack('n*').map { |o| sprintf("%X", o) }.join(':') 
      else 
       STDERR.print "The encountered IP-address is neither IPv4 nor IPv6\n" 
       next 
      end 
      result << "IP:#{ip}" 
     else 
      STDERR.print "Uknown tag #{v.tag} -- I only know 2 (DNS) and 7 (IP)\n" 
     end 
    end 
    return result 
end 

不过,我不喜欢它,因为它应该可能获得整个从csr现成的扩展名(按名称),并将其添加到cert逐字 - 没有解码(即使我曾经使它完美)和重新编码。