2 = $RCSfile$ -- Ruby-space definitions that completes C-space funcs for SSL
5 'OpenSSL for Ruby 2' project
6 Copyright (C) 2001 GOTOU YUUZOU <gotoyuzo@notwork.org>
10 This program is licenced under the same licence as Ruby.
11 (See the file 'LICENCE'.)
14 $Id: ssl.rb 14479 2007-12-22 08:31:53Z gotoyuzo $
18 require "openssl/buffering"
25 :ssl_version => "SSLv23",
26 :verify_mode => OpenSSL::SSL::VERIFY_PEER,
27 :ciphers => "ALL:!ADH:!EXPORT:!SSLv2:RC4+RSA:+HIGH:+MEDIUM:+LOW",
28 :options => OpenSSL::SSL::OP_ALL,
31 DEFAULT_CERT_STORE = OpenSSL::X509::Store.new
32 DEFAULT_CERT_STORE.set_default_paths
33 if defined?(OpenSSL::X509::V_FLAG_CRL_CHECK_ALL)
34 DEFAULT_CERT_STORE.flags = OpenSSL::X509::V_FLAG_CRL_CHECK_ALL
37 def set_params(params={})
38 params = DEFAULT_PARAMS.merge(params)
39 params.each{|name, value| self.__send__("#{name}=", value) }
40 if self.verify_mode != OpenSSL::SSL::VERIFY_NONE
41 unless self.ca_file or self.ca_path or self.cert_store
42 self.cert_store = DEFAULT_CERT_STORE
49 module SocketForwarder
58 def setsockopt(level, optname, optval)
59 to_io.setsockopt(level, optname, optval)
62 def getsockopt(level, optname)
63 to_io.getsockopt(level, optname)
74 def do_not_reverse_lookup=(flag)
75 to_io.do_not_reverse_lookup = flag
82 flag |= @io.fcntl(Fcntl::F_GETFL) if defined?(Fcntl::F_GETFL)
83 @io.fcntl(Fcntl::F_SETFL, flag)
88 def verify_certificate_identity(cert, hostname)
89 should_verify_common_name = true
90 cert.extensions.each{|ext|
91 next if ext.oid != "subjectAltName"
92 ext.value.split(/,\s+/).each{|general_name|
93 if /\ADNS:(.*)/ =~ general_name
94 should_verify_common_name = false
95 reg = Regexp.escape($1).gsub(/\\\*/, "[^.]+")
96 return true if /\A#{reg}\z/i =~ hostname
97 elsif /\AIP Address:(.*)/ =~ general_name
98 should_verify_common_name = false
99 return true if $1 == hostname
103 if should_verify_common_name
104 cert.subject.to_a.each{|oid, value|
106 reg = Regexp.escape(value).gsub(/\\\*/, "[^.]+")
107 return true if /\A#{reg}\z/i =~ hostname
113 module_function :verify_certificate_identity
117 include SocketForwarder
120 def post_connection_check(hostname)
121 unless OpenSSL::SSL.verify_certificate_identity(peer_cert, hostname)
122 raise SSLError, "hostname was not match with the server certificate"
128 SSL::Session.new(self)
129 rescue SSL::Session::SessionError
135 include SocketForwarder
136 attr_accessor :start_immediately
138 def initialize(svr, ctx)
141 unless ctx.session_id_context
142 session_id = OpenSSL::Digest::MD5.hexdigest($0)
143 @ctx.session_id_context = session_id
145 @start_immediately = true
152 def listen(backlog=5)
156 def shutdown(how=Socket::SHUT_RDWR)
163 ssl = OpenSSL::SSL::SSLSocket.new(sock, @ctx)
164 ssl.sync_close = true
165 ssl.accept if @start_immediately
167 rescue SSLError => ex