class HTTPClient::JRubySSLSocket::BrowserCompatHostnameVerifier

Ported from commons-httpclient ‘BrowserCompatHostnameVerifier’

Constants

BAD_COUNTRY_2LDS

Public Instance Methods

create_wildcard_regexp(value) click to toggle source
# File lib/httpclient/jruby_ssl_socket.rb, line 442
def create_wildcard_regexp(value)
  # Escape first then search '\*' for meta-char interpolation
  labels = value.split('.').map { |e| Regexp.escape(e) }
  # Handle '*'s only at the left-most label, exclude A-label and U-label
  labels[0].gsub!(/\\\*/, '[^.]+') if !labels[0].start_with?('xn\-\-') and labels[0].ascii_only?
  /\A#{labels.join('\.')}\z/i
end
extract_cn(cert) click to toggle source
# File lib/httpclient/jruby_ssl_socket.rb, line 392
def extract_cn(cert)
  subject = cert.getSubjectX500Principal()
  if subject
    subject_dn = javax.naming.ldap.LdapName.new(subject.toString)
    subject_dn.getRdns.to_a.reverse.each do |rdn|
      attributes = rdn.toAttributes
      cn = attributes.get('cn')
      if cn
        if value = cn.get
          return value.to_s
        end
      end
    end
  end
end
extract_sans(cert, subject_type) click to toggle source
# File lib/httpclient/jruby_ssl_socket.rb, line 380
def extract_sans(cert, subject_type)
  sans = cert.getSubjectAlternativeNames rescue nil
  if sans.nil?
    return nil
  end
  sans.find_all { |san|
    san.first.to_i == subject_type
  }.map { |san|
    san[1]
  }
end
ipaddr?(addr) click to toggle source
# File lib/httpclient/jruby_ssl_socket.rb, line 408
def ipaddr?(addr)
  !(IPAddr.new(addr) rescue nil).nil?
end
match_identify(hostname, identity) click to toggle source
# File lib/httpclient/jruby_ssl_socket.rb, line 428
def match_identify(hostname, identity)
  if hostname.nil?
    return false
  end
  hostname = hostname.downcase
  identity = identity.downcase
  parts = identity.split('.')
  if parts.length >= 3 && parts.first.end_with?('*') && valid_country_wildcard(parts)
    create_wildcard_regexp(identity) =~ hostname
  else
    hostname == identity
  end
end
valid_country_wildcard(parts) click to toggle source
# File lib/httpclient/jruby_ssl_socket.rb, line 450
def valid_country_wildcard(parts)
  if parts.length != 3 || parts[2].length != 2
    true
  else
    !BAD_COUNTRY_2LDS.include?(parts[1])
  end
end
verify(hostname, cert) click to toggle source
# File lib/httpclient/jruby_ssl_socket.rb, line 412
def verify(hostname, cert)
  is_ipaddr = ipaddr?(hostname)
  sans = extract_sans(cert, is_ipaddr ? 7 : 2)
  cn = extract_cn(cert)
  if sans
    sans.each do |san|
      return true if match_identify(hostname, san)
    end
    raise OpenSSL::SSL::SSLError.new("Certificate for <#{hostname}> doesn't match any of the subject alternative names: #{sans}")
  elsif cn
    return true if match_identify(hostname, cn)
    raise OpenSSL::SSL::SSLError.new("Certificate for <#{hostname}> doesn't match common name of the certificate subject: #{cn}")
  end
  raise OpenSSL::SSL::SSLError.new("Certificate subject for for <#{hostname}> doesn't contain a common name and does not have alternative names")
end