summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorgotoyuzo <gotoyuzo@ruby-lang.org>2007-12-17 12:18:28 +0000
committergotoyuzo <gotoyuzo@ruby-lang.org>2007-12-17 12:18:28 +0000
commit89487f9975f95bbf0b9b372e054aa438f30d6315 (patch)
tree6c8119f50e707530f9bf91b92076d92025d257c0 /lib
parente2cdccfe4f8f9392744e43d15a2e753c1f8edd3d (diff)
downloadruby-openssl-history-89487f9975f95bbf0b9b372e054aa438f30d6315.tar.gz
* ext/openssl/ossl_ssl.c (ossl_sslctx_set_ssl_version):
new method OpenSSL::SSL::SSLContext#ssl_version to wrap SSL_CTX_set_ssl_version. * ext/openssl/ossl_ssl.c (ossl_ssl_get_verify_result): new method OpenSSL::SSL::SSLSocket#verify_result to wrap SSL_get_verrify_result. * ext/openssl/lib/openssl/ssl.rb (OpenSSL::SSL::SSLContext.build): new method to build OpenSSL::SSL::SSLContext with Hash parameters. this method provides safety default parameters than SSLContext.new. * ext/openssl/lib/openssl/ssl.rb (OpenSSL::SSL.verify_cetificate_identity): new module function: pull out identity verification process from OpenSSL::SSL::SSLSocket#post_connection_check. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@14270 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'lib')
-rw-r--r--lib/openssl/ssl.rb78
1 files changed, 55 insertions, 23 deletions
diff --git a/lib/openssl/ssl.rb b/lib/openssl/ssl.rb
index ad9559f..63d6690 100644
--- a/lib/openssl/ssl.rb
+++ b/lib/openssl/ssl.rb
@@ -20,6 +20,31 @@ require "fcntl"
module OpenSSL
module SSL
+ class SSLContext
+ class <<self
+ def build(params={})
+ default_params = {
+ :ssl_version => "SSLv23",
+ :verify_mode => OpenSSL::SSL::VERIFY_PEER,
+ :ciphers => "ALL:!ADH:!EXPORT:!SSLv2:RC4+RSA:+HIGH:+MEDIUM:+LOW",
+ :options => OpenSSL::SSL::OP_ALL,
+ }
+ params = default_params.merge(params)
+ ctx = new()
+ params.each{|name, value| ctx.__send__("#{name}=", value) }
+ ctx.verify_mode ||= OpenSSL::SSL::VERIFY_NONE
+ if ctx.verify_mode != OpenSSL::SSL::VERIFY_NONE
+ unless ctx.ca_file or ctx.ca_path or
+ ctx.cert_store or ctx.verify_callback
+ ctx.cert_store = OpenSSL::X509::Store.new
+ ctx.cert_store.set_default_paths
+ end
+ end
+ return ctx
+ end
+ end
+ end
+
module SocketForwarder
def addr
to_io.addr
@@ -59,36 +84,43 @@ module OpenSSL
end
end
+ def verify_certificate_identity(cert, hostname)
+ should_verify_common_name = true
+ cert.extensions.each{|ext|
+ next if ext.oid != "subjectAltName"
+ ext.value.split(/,\s+/).each{|general_name|
+ if /\ADNS:(.*)/ =~ general_name
+ should_verify_common_name = false
+ reg = Regexp.escape($1).gsub(/\\\*/, "[^.]+")
+ return true if /\A#{reg}\z/i =~ hostname
+ elsif /\AIP Address:(.*)/ =~ general_name
+ should_verify_common_name = false
+ return true if $1 == hostname
+ end
+ }
+ }
+ if should_verify_common_name
+ cert.subject.to_a.each{|oid, value|
+ if oid == "CN"
+ reg = Regexp.escape(value).gsub(/\\\*/, "[^.]+")
+ return true if /\A#{reg}\z/i =~ hostname
+ end
+ }
+ end
+ return false
+ end
+ module_function :verify_certificate_identity
+
class SSLSocket
include Buffering
include SocketForwarder
include Nonblock
def post_connection_check(hostname)
- check_common_name = true
- cert = peer_cert
- cert.extensions.each{|ext|
- next if ext.oid != "subjectAltName"
- ext.value.split(/,\s+/).each{|general_name|
- if /\ADNS:(.*)/ =~ general_name
- check_common_name = false
- reg = Regexp.escape($1).gsub(/\\\*/, "[^.]+")
- return true if /\A#{reg}\z/i =~ hostname
- elsif /\AIP Address:(.*)/ =~ general_name
- check_common_name = false
- return true if $1 == hostname
- end
- }
- }
- if check_common_name
- cert.subject.to_a.each{|oid, value|
- if oid == "CN"
- reg = Regexp.escape(value).gsub(/\\\*/, "[^.]+")
- return true if /\A#{reg}\z/i =~ hostname
- end
- }
+ unless OpenSSL::SSL.verify_certificate_identity(peer_cert, hostname)
+ raise SSLError, "hostname was not match with the server certificate"
end
- raise SSLError, "hostname was not match with the server certificate"
+ return true
end
def session