From: Tanaka Akira Date: 2005-02-12T22:01:31+09:00 Subject: [ruby-dev:25683] Re: openssl binding for SSL_CTX_set_default_verify_paths and X509_STORE_set_default_paths In article <20050211.053825.291449071.gotoyuzo@sawara.does.notwork.org>, GOTOU Yuuzou writes: > ところで、verify_modeのデフォルトはOpenSSLライブラリに任せて > いるのですが、net/httpsではSSL_VERIFY_PEERをデフォルトにすべ > きだったと考えるようになりました。せめてopen-uriではそうして > はどうでしょうか。 後から [ruby-dev:25254] に気がついたのですが、次のように取り込んでも良 いでしょうか。 Index: lib/open-uri.rb =================================================================== RCS file: /src/ruby/lib/open-uri.rb,v retrieving revision 1.34 diff -u -p -r1.34 open-uri.rb --- lib/open-uri.rb 12 Feb 2005 08:40:08 -0000 1.34 +++ lib/open-uri.rb 12 Feb 2005 12:58:36 -0000 @@ -243,6 +243,11 @@ module OpenURI resp = nil http.start { + if (http.verify_mode & OpenSSL::SSL::VERIFY_PEER) != 0 + unless https_post_connection_check(http.peer_cert, target_host) + raise "SSL hostname not match" + end + end req = Net::HTTP::Get.new(request_uri, header) if options.include? :http_basic_authentication user, pass = options[:http_basic_authentication] @@ -279,6 +284,31 @@ module OpenURI else raise OpenURI::HTTPError.new(io.status.join(' '), io) end + end + + def OpenURI.https_post_connection_check(cert, hostname) + subject = cert.subject + subject.to_a.each{|oid, value| + if oid == "CN" && value == hostname + return true + end + } + cert.extensions.each{|ext| + if ext.oid == "subjectAltName" + general_names = ext.value.split(/,\s+/) + general_names.each{|name| + if /(:?DNS|IP Address):(.*)/ =~ name + reg = Regexp.escape($1) + reg = reg.gsub(%r!\\\*!, '[^.]+') + reg = Regexp.new('\A' + reg + '\z') + if reg.match(hostname) + return true + end + end + } + end + } + return false end class HTTPError < StandardError -- [田中 哲][たなか あきら][Tanaka Akira]