diff options
author | gotoyuzo <gotoyuzo@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2003-07-23 16:12:24 +0000 |
---|---|---|
committer | gotoyuzo <gotoyuzo@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2003-07-23 16:12:24 +0000 |
commit | 231247c010acba191b78ed2d1310c935e63ad919 (patch) | |
tree | 10591a106bc2f3eff53eff8e440f58495ff517c9 /ext/openssl/lib | |
parent | fd46a1da0a41b7939424bc5a393027be7940908e (diff) | |
download | ruby-231247c010acba191b78ed2d1310c935e63ad919.tar.gz |
* ext/openssl: imported.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@4128 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'ext/openssl/lib')
-rw-r--r-- | ext/openssl/lib/net/ftptls.rb | 43 | ||||
-rw-r--r-- | ext/openssl/lib/net/https.rb | 179 | ||||
-rw-r--r-- | ext/openssl/lib/net/protocols.rb | 57 | ||||
-rw-r--r-- | ext/openssl/lib/net/telnets.rb | 250 | ||||
-rw-r--r-- | ext/openssl/lib/openssl.rb | 24 | ||||
-rw-r--r-- | ext/openssl/lib/openssl/bn.rb | 35 | ||||
-rw-r--r-- | ext/openssl/lib/openssl/buffering.rb | 189 | ||||
-rw-r--r-- | ext/openssl/lib/openssl/cipher.rb | 52 | ||||
-rw-r--r-- | ext/openssl/lib/openssl/digest.rb | 44 | ||||
-rw-r--r-- | ext/openssl/lib/openssl/ssl.rb | 38 | ||||
-rw-r--r-- | ext/openssl/lib/openssl/x509.rb | 132 |
11 files changed, 1043 insertions, 0 deletions
diff --git a/ext/openssl/lib/net/ftptls.rb b/ext/openssl/lib/net/ftptls.rb new file mode 100644 index 0000000000..f433457923 --- /dev/null +++ b/ext/openssl/lib/net/ftptls.rb @@ -0,0 +1,43 @@ +=begin += $RCSfile$ -- SSL/TLS enhancement for Net::HTTP. + += Info + 'OpenSSL for Ruby 2' project + Copyright (C) 2003 Blaz Grilc <farmer@gmx.co.uk> + All rights reserved. + += Licence + This program is licenced under the same licence as Ruby. + (See the file 'LICENCE'.) + += Requirements + += Version + $Id$ + += Notes + Tested on FreeBSD 5-CURRENT and 4-STABLE + - ruby 1.6.8 (2003-01-17) [i386-freebsd5] + - OpenSSL 0.9.7a Feb 19 2003 + - ruby-openssl-0.2.0.p0 + tested on ftp server: glftpd 1.30 +=end + +require 'socket' +require 'openssl' +require 'net/ftp' + +module Net + class FTPTLS < FTP + def login(user = "anonymous", passwd = nil, acct = nil) + ctx = OpenSSL::SSL::SSLContext.new('SSLv23') + ctx.key = nil + ctx.cert = nil + voidcmd("AUTH TLS") + @sock = OpenSSL::SSL::SSLSocket.new(@sock, ctx) + @sock.connect + super(user, passwd, acct) + voidcmd("PBSZ 0") + end + end +end diff --git a/ext/openssl/lib/net/https.rb b/ext/openssl/lib/net/https.rb new file mode 100644 index 0000000000..0f5cb13407 --- /dev/null +++ b/ext/openssl/lib/net/https.rb @@ -0,0 +1,179 @@ +=begin += $RCSfile$ -- SSL/TLS enhancement for Net::HTTP. + += Info + 'OpenSSL for Ruby 2' project + Copyright (C) 2001 GOTOU Yuuzou <gotoyuzo@notwork.org> + All rights reserved. + += Licence + This program is licenced under the same licence as Ruby. + (See the file 'LICENCE'.) + += Requirements + This program requires Net 1.2.0 or higher version. + You can get it from RAA or Ruby's CVS repository. + += Version + $Id$ + + 2001/11/06: Contiributed to Ruby/OpenSSL project. + +== class Net::HTTP + +== Example + +Simple HTTP client is here: + + require 'net/http' + host, port, path = "localhost", 80, "/" + if %r!http://(.*?)(?::(\d+))?(/.*)! =~ ARGV[0] + host = $1 + port = $2.to_i if $2 + path = $3 + end + h = Net::HTTP.new(host, port) + h.get2(path){ |resp| print resp.body } + +It can be replaced by follow one: + + require 'net/https' + host, port, path = "localhost", 80, "/" + if %r!(https?)://(.*?)(?::(\d+))?(/.*)! =~ ARGV[0] + scheme = $1 + host = $2 + port = $3 ? $3.to_i : ((scheme == "http") ? 80 : 443) + path = $4 + end + h = Net::HTTP.new(host, port) + h.use_ssl = true if scheme == "https" # enable SSL/TLS + h.get2(path){ |resp| print resp.body } + +=== Instance Methods + +: use_ssl + returns ture if use SSL/TLS with HTTP. + +: use_ssl=((|true_or_false|)) + sets use_ssl. + +: peer_cert + return the X.509 certificates the server presented. + +: key=((|key|)) + Sets an OpenSSL::PKey::RSA or OpenSSL::PKey::DSA object. + (This method is appeared in Michal Rokos's OpenSSL extention.) + +: key_file=((|path|)) + Sets a private key file to use in PEM format. + +: cert=((|cert|)) + Sets an OpenSSL::X509::Certificate object as client certificate. + (This method is appeared in Michal Rokos's OpenSSL extention.) + +: cert_file=((|path|)) + Sets pathname of a X.509 certification file in PEM format. + +: ca_file=((|path|)) + Sets path of a CA certification file in PEM format. + The file can contrain several CA certificats. + +: ca_path=((|path|)) + Sets path of a CA certification directory containing certifications + in PEM format. + +: verify_mode=((|mode|)) + Sets the flags for server the certification verification at + begining of SSL/TLS session. + OpenSSL::SSL::VERIFY_NONE or OpenSSL::SSL::VERIFY_PEER is acceptable. + +: verify_callback=((|proc|)) + Sets the verify callback for the server certification verification. + +: verify_depth=((|num|)) + Sets the maximum depth for the certificate chain verification. + +: cert_store=((|store|)) + Sets the X509::Store to verify peer certificate. + +=end + +require 'net/protocols' +require 'net/http' + +module Net + class HTTP + class Conn < HTTPRequest + REQUEST_HAS_BODY=false + RESPONSE_HAS_BODY=false + METHOD="connect" + + def initialize + super nil, nil + end + + def exec( sock, addr, port, ver ) + @socket = sock + request(addr, port, ver) + end + + def request( addr, port, ver ) + @socket.writeline sprintf('CONNECT %s:%s HTTP/%s', addr, port, ver) + @socket.writeline '' + end + end + + module ProxyMod + def edit_path( path ) + if use_ssl + 'https://' + addr_port + path + else + 'http://' + addr_port + path + end + end + end + + def self.socket_type + SSLIO + end + + attr_accessor :use_ssl + attr_writer :key, :cert + attr_writer :ca_file, :ca_path + attr_writer :verify_mode, :verify_callback, :verify_depth + attr_writer :cert_store, :timeout + attr_reader :peer_cert + + alias :default_initialize :initialize + + def initialize(*args) + default_initialize(*args) + @key = @cert = @ca_file = @ca_path = @verify_mode = + @verify_callback = @verify_depth = @timeout = @cert_store = nil + end + + def on_connect + if use_ssl + if proxy? + Conn.new.exec(@socket, @address, @port, "1.0") + resp = HTTPResponse.read_new(@socket) + if resp.code != '200' + raise resp.message + end + end + @socket.key = @key if @key + @socket.cert = @cert if @cert + @socket.ca_file = @ca_file + @socket.ca_path = @ca_path + @socket.verify_mode = @verify_mode + @socket.verify_callback = @verify_callback + @socket.verify_depth = @verify_depth + @socket.timeout = @timeout + @socket.cert_store = @cert_store + @socket.ssl_connect + @peer_cert = @socket.peer_cert + end + end + + end +end diff --git a/ext/openssl/lib/net/protocols.rb b/ext/openssl/lib/net/protocols.rb new file mode 100644 index 0000000000..5897716f3d --- /dev/null +++ b/ext/openssl/lib/net/protocols.rb @@ -0,0 +1,57 @@ +=begin += $RCSfile$ -- SSL/TLS enhancement for Net. + += Info + 'OpenSSL for Ruby 2' project + Copyright (C) 2001 GOTOU YUUZOU <gotoyuzo@notwork.org> + All rights reserved. + += Licence + This program is licenced under the same licence as Ruby. + (See the file 'LICENCE'.) + += Requirements + This program requires Net 1.2.0 or higher version. + You can get it from RAA or Ruby's CVS repository. + += Version + $Id$ + + 2001/11/06: Contiributed to Ruby/OpenSSL project. +=end + +require 'net/protocol' +require 'forwardable' +require 'openssl' + +module Net + class SSLIO < InternetMessageIO + extend Forwardable + + def_delegators(:@ssl_context, + :key=, :cert=, :key_file=, :cert_file=, + :ca_file=, :ca_path=, + :verify_mode=, :verify_callback=, :verify_depth=, + :timeout=, :cert_store=) + + def initialize(addr, port, otime = nil, rtime = nil, dout = nil) + super + @ssl_context = OpenSSL::SSL::SSLContext.new() + end + + def ssl_connect() + @raw_socket = @socket + @socket = OpenSSL::SSL::SSLSocket.new(@raw_socket, @ssl_context) + @socket.connect + end + + def close + super + @raw_socket.close if @raw_socket + end + + def peer_cert + @socket.peer_cert + end + end +end diff --git a/ext/openssl/lib/net/telnets.rb b/ext/openssl/lib/net/telnets.rb new file mode 100644 index 0000000000..c7ecbd717a --- /dev/null +++ b/ext/openssl/lib/net/telnets.rb @@ -0,0 +1,250 @@ +=begin += $RCSfile$ -- SSL/TLS enhancement for Net::Telnet. + += Info + 'OpenSSL for Ruby 2' project + Copyright (C) 2001 GOTOU YUUZOU <gotoyuzo@notwork.org> + All rights reserved. + += Licence + This program is licenced under the same licence as Ruby. + (See the file 'LICENCE'.) + += Version + $Id$ + + 2001/11/06: Contiributed to Ruby/OpenSSL project. + +== class Net::Telnet + +This class will initiate SSL/TLS session automaticaly if the server +sent OPT_STARTTLS. Some options are added for SSL/TLS. + + host = Net::Telnet::new({ + "Host" => "localhost", + "Port" => "telnets", + ## follows are new options. + 'CertFile' => "user.crt", + 'KeyFile' => "user.key", + 'CAFile' => "/some/where/certs/casert.pem", + 'CAPath' => "/some/where/caserts", + 'VerifyMode' => SSL::VERIFY_PEER, + 'VerifyCallback' => verify_proc + }) + +Or, the new options ('Cert', 'Key' and 'CACert') are available from +Michal Rokos's OpenSSL module. + + cert_data = File.open("user.crt"){|io| io.read } + pkey_data = File.open("user.key"){|io| io.read } + cacert_data = File.open("your_ca.pem"){|io| io.read } + host = Net::Telnet::new({ + "Host" => "localhost", + "Port" => "telnets", + 'Cert' => OpenSSL::X509::Certificate.new(cert_data) + 'Key' => OpenSSL::PKey::RSA.new(pkey_data) + 'CACert' => OpenSSL::X509::Certificate.new(cacert_data) + 'CAFile' => "/some/where/certs/casert.pem", + 'CAPath' => "/some/where/caserts", + 'VerifyMode' => SSL::VERIFY_PEER, + 'VerifyCallback' => verify_proc + }) + +This class is expected to be a superset of usual Net::Telnet. +=end + +require "net/telnet" +require "openssl" + +module Net + class Telnet + attr_reader :ssl + + OPT_STARTTLS = 46.chr # "\056" # "\x2e" # Start TLS + TLS_FOLLOWS = 1.chr # "\001" # "\x01" # FOLLOWS (for STARTTLS) + + alias preprocess_orig preprocess + + def ssl?; @ssl; end + + def preprocess(string) + # combine CR+NULL into CR + string = string.gsub(/#{CR}#{NULL}/no, CR) if @options["Telnetmode"] + + # combine EOL into "\n" + string = string.gsub(/#{EOL}/no, "\n") unless @options["Binmode"] + + string.gsub(/#{IAC}( + [#{IAC}#{AO}#{AYT}#{DM}#{IP}#{NOP}]| + [#{DO}#{DONT}#{WILL}#{WONT}][#{OPT_BINARY}-#{OPT_EXOPL}]| + #{SB}[#{OPT_BINARY}-#{OPT_EXOPL}] + (#{IAC}#{IAC}|[^#{IAC}])+#{IAC}#{SE} + )/xno) do + if IAC == $1 # handle escaped IAC characters + IAC + elsif AYT == $1 # respond to "IAC AYT" (are you there) + self.write("nobody here but us pigeons" + EOL) + '' + elsif DO[0] == $1[0] # respond to "IAC DO x" + if OPT_BINARY[0] == $1[1] + @telnet_option["BINARY"] = true + self.write(IAC + WILL + OPT_BINARY) + elsif OPT_STARTTLS[0] == $1[1] + self.write(IAC + WILL + OPT_STARTTLS) + self.write(IAC + SB + OPT_STARTTLS + TLS_FOLLOWS + IAC + SE) + else + self.write(IAC + WONT + $1[1..1]) + end + '' + elsif DONT[0] == $1[0] # respond to "IAC DON'T x" with "IAC WON'T x" + self.write(IAC + WONT + $1[1..1]) + '' + elsif WILL[0] == $1[0] # respond to "IAC WILL x" + if OPT_BINARY[0] == $1[1] + self.write(IAC + DO + OPT_BINARY) + elsif OPT_ECHO[0] == $1[1] + self.write(IAC + DO + OPT_ECHO) + elsif OPT_SGA[0] == $1[1] + @telnet_option["SGA"] = true + self.write(IAC + DO + OPT_SGA) + else + self.write(IAC + DONT + $1[1..1]) + end + '' + elsif WONT[0] == $1[0] # respond to "IAC WON'T x" + if OPT_ECHO[0] == $1[1] + self.write(IAC + DONT + OPT_ECHO) + elsif OPT_SGA[0] == $1[1] + @telnet_option["SGA"] = false + self.write(IAC + DONT + OPT_SGA) + else + self.write(IAC + DONT + $1[1..1]) + end + '' + elsif SB[0] == $1[0] # respond to "IAC SB xxx IAC SE" + if OPT_STARTTLS[0] == $1[1] && TLS_FOLLOWS[0] == $2[0] + @sock = OpenSSL::SSL::SSLSocket.new(@sock) + @sock.cert_file = @options['CertFile'] + @sock.cert = @options['Cert'] unless @sock.cert + @sock.key_file = @options['KeyFile'] + @sock.key = @options['Key'] unless @sock.key + @sock.ca_cert = @options['CACert'] + @sock.ca_file = @options['CAFile'] + @sock.ca_path = @options['CAPath'] + @sock.timeout = @options['Timeout'] + @sock.verify_mode = @options['VerifyMode'] + @sock.verify_callback = @options['VerifyCallback'] + @sock.verify_depth = @options['VerifyDepth'] + @sock.connect + @ssl = true + end + '' + else + '' + end + end + end # preprocess + + alias waitfor_org waitfor + + def waitfor(options) + time_out = @options["Timeout"] + waittime = @options["Waittime"] + + if options.kind_of?(Hash) + prompt = if options.has_key?("Match") + options["Match"] + elsif options.has_key?("Prompt") + options["Prompt"] + elsif options.has_key?("String") + Regexp.new( Regexp.quote(options["String"]) ) + end + time_out = options["Timeout"] if options.has_key?("Timeout") + waittime = options["Waittime"] if options.has_key?("Waittime") + else + prompt = options + end + + if time_out == false + time_out = nil + end + + line = '' + buf = '' + @rest = '' unless @rest + + until(prompt === line and not IO::select([@sock], nil, nil, waittime)) + unless IO::select([@sock], nil, nil, time_out) + raise TimeoutError, "timed-out; wait for the next data" + end + begin + c = @rest + @sock.sysread(1024 * 1024) + @dumplog.log_dump('<', c) if @options.has_key?("Dump_log") + if @options["Telnetmode"] + pos = 0 + catch(:next){ + while true + case c[pos] + when IAC[0] + case c[pos+1] + when DO[0], DONT[0], WILL[0], WONT[0] + throw :next unless c[pos+2] + pos += 3 + when SB[0] + ret = detect_sub_negotiation(c, pos) + throw :next unless ret + pos = ret + when nil + throw :next + else + pos += 2 + end + when nil + throw :next + else + pos += 1 + end + end + } + + buf = preprocess(c[0...pos]) + @rest = c[pos..-1] + end + @log.print(buf) if @options.has_key?("Output_log") + line.concat(buf) + yield buf if block_given? + rescue EOFError # End of file reached + if line == '' + line = nil + yield nil if block_given? + end + break + end + end + line + end + + private + + def detect_sub_negotiation(data, pos) + return nil if data.length < pos+6 # IAC SB x param IAC SE + pos += 3 + while true + case data[pos] + when IAC[0] + if data[pos+1] == SE[0] + pos += 2 + return pos + else + pos += 2 + end + when nil + return nil + else + pos += 1 + end + end + end + + end +end diff --git a/ext/openssl/lib/openssl.rb b/ext/openssl/lib/openssl.rb new file mode 100644 index 0000000000..24a9eed136 --- /dev/null +++ b/ext/openssl/lib/openssl.rb @@ -0,0 +1,24 @@ +=begin += $RCSfile$ -- Loader for all OpenSSL C-space and Ruby-space definitions + += Info + 'OpenSSL for Ruby 2' project + Copyright (C) 2002 Michal Rokos <m.rokos@sh.cvut.cz> + All rights reserved. + += Licence + This program is licenced under the same licence as Ruby. + (See the file 'LICENCE'.) + += Version + $Id$ +=end + +require 'openssl.so' + +require 'openssl/bn' +require 'openssl/cipher' +require 'openssl/digest' +require 'openssl/ssl' +require 'openssl/x509' + diff --git a/ext/openssl/lib/openssl/bn.rb b/ext/openssl/lib/openssl/bn.rb new file mode 100644 index 0000000000..e7cbf2cfaf --- /dev/null +++ b/ext/openssl/lib/openssl/bn.rb @@ -0,0 +1,35 @@ +=begin += $RCSfile$ -- Ruby-space definitions that completes C-space funcs for BN + += Info + 'OpenSSL for Ruby 2' project + Copyright (C) 2002 Michal Rokos <m.rokos@sh.cvut.cz> + All rights reserved. + += Licence + This program is licenced under the same licence as Ruby. + (See the file 'LICENCE'.) + += Version + $Id$ +=end + +## +# Should we care what if somebody require this file directly? +#require 'openssl' + +module OpenSSL + class BN + include Comparable + end # BN +end # OpenSSL + +## +# Add double dispatch to Integer +# +class Integer + def to_bn + OpenSSL::BN::new(self) + end +end # Integer + diff --git a/ext/openssl/lib/openssl/buffering.rb b/ext/openssl/lib/openssl/buffering.rb new file mode 100644 index 0000000000..61eb9dcc04 --- /dev/null +++ b/ext/openssl/lib/openssl/buffering.rb @@ -0,0 +1,189 @@ +=begin += $RCSfile$ -- Buffering mix-in module. + += Info + 'OpenSSL for Ruby 2' project + Copyright (C) 2001 GOTOU YUUZOU <gotoyuzo@notwork.org> + All rights reserved. + += Licence + This program is licenced under the same licence as Ruby. + (See the file 'LICENCE'.) + += Version + $Id$ +=end + +module Buffering + include Enumerable + attr_accessor :sync + BLOCK_SIZE = 1024 + + # + # for reading. + # + private + + def fill_rbuff + @rbuffer = "" unless defined? @rbuffer + begin + if self.respond_to?(:to_io) + IO.select([self.to_io], nil, nil) + end + @rbuffer << self.sysread(BLOCK_SIZE) + rescue EOFError + @eof = true + end + end + + def consume_rbuff(size=nil) + if @rbuffer.size == 0 + @eof = nil + nil + else + size = @rbuffer.size unless size + ret = @rbuffer[0, size] + @rbuffer[0, size] = "" + ret + end + end + + public + + def read(size=nil) + fill_rbuff unless defined? @rbuffer + @eof ||= nil + until @eof + break if size && size <= @rbuffer.size + fill_rbuff + end + consume_rbuff(size) + end + + def gets(eol=$/) + fill_rbuff unless defined? @rbuffer + idx = @rbuffer.index(eol) + @eof ||= nil + until @eof + break if idx + fill_rbuff + idx = @rbuffer.index(eol) + end + if eol.is_a?(Regexp) + size = idx ? idx+$&.size : nil + else + size = idx ? idx+eol.size : nil + end + consume_rbuff(size) + end + + def each(eol=$/) + while line = self.gets(eol?) + yield line + end + end + alias each_line each + + def readlines(eol=$/) + ary = [] + while line = self.gets(eol) + ary << line + end + ary + end + + def readline(eol=$/) + raise EOFErorr if eof? + gets(eol) + end + + def getc + c = read(1) + c ? c.to_i : nil + end + + def each_byte + while c = getc + yield(c) + end + end + + def readchar + raise EOFErorr if eof? + getc + end + + def ungetc(c) + @rbuffer[0,0] = c.chr + end + + def eof? + @eof ||= nil + @eof && @rbuffer.size == 0 + end + alias eof eof? + + # + # for writing. + # + private + + def do_write(s) + @wbuffer = "" unless defined? @wbuffer + @wbuffer << s + @sync ||= false + if @sync or @wbuffer.size > BLOCK_SIZE or idx = @wbuffer.rindex($/) + remain = idx ? idx + $/.size : @wbuffer.length + nwritten = 0 + while remain > 0 + nwrote = syswrite(@wbuffer[nwritten,remain]) + remain -= nwrote + nwritten += nwrote + end + @wbuffer = "" + end + end + + public + + def write(s) + do_write(s) + s.length + end + + def << (s) + do_write(s) + self + end + + def puts(*args) + s = "" + args.each{ |arg| s << arg.to_s + $/ } + do_write(s) + nil + end + + def print(*args) + s = "" + args.each{ |arg| s << arg.to_s } + do_write(s) + nil + end + + def printf(s, *args) + do_write(s % args) + nil + end + + def flush + osync = @sync + @sync = true + do_write "" + @sync = osync + end + + def close + flush + sysclose + end +end diff --git a/ext/openssl/lib/openssl/cipher.rb b/ext/openssl/lib/openssl/cipher.rb new file mode 100644 index 0000000000..11153104ee --- /dev/null +++ b/ext/openssl/lib/openssl/cipher.rb @@ -0,0 +1,52 @@ +=begin += $RCSfile$ -- Ruby-space predefined Cipher subclasses + += Info + 'OpenSSL for Ruby 2' project + Copyright (C) 2002 Michal Rokos <m.rokos@sh.cvut.cz> + All rights reserved. + += Licence + This program is licenced under the same licence as Ruby. + (See the file 'LICENCE'.) + += Version + $Id$ +=end + +## +# Should we care what if somebody require this file directly? +#require 'openssl' + +module OpenSSL + module Cipher + %w(AES Cast5 BF DES Idea RC2 RC4 RC5).each{|cipher| + eval(<<-EOD) + class #{cipher} < Cipher + def initialize(*args) + args = args.join('-') + if args.size == 0 + super(\"#{cipher}\") + else + super(\"#{cipher}-#\{args\}\") + end + end + end + EOD + } + + class Cipher + def random_key + str = OpenSSL::Random.random_bytes(self.key_len) + self.key = str + return str + end + + def random_iv + str = OpenSSL::Random.random_bytes(self.iv_len) + self.iv = str + return str + end + end + end # Cipher +end # OpenSSL diff --git a/ext/openssl/lib/openssl/digest.rb b/ext/openssl/lib/openssl/digest.rb new file mode 100644 index 0000000000..58622f543e --- /dev/null +++ b/ext/openssl/lib/openssl/digest.rb @@ -0,0 +1,44 @@ +=begin += $RCSfile$ -- Ruby-space predefined Digest subclasses + += Info + 'OpenSSL for Ruby 2' project + Copyright (C) 2002 Michal Rokos <m.rokos@sh.cvut.cz> + All rights reserved. + += Licence + This program is licenced under the same licence as Ruby. + (See the file 'LICENCE'.) + += Version + $Id$ +=end + +## +# Should we care what if somebody require this file directly? +#require 'openssl' + +module OpenSSL + module Digest + + %w(DSS DSS1 MD2 MD4 MD5 MDC2 RIPEMD160 SHA SHA1).each{|digest| + eval(<<-EOD) + class #{digest} < Digest + def initialize(data=nil) + super(\"#{digest}\", data) + end + + def #{digest}::digest(data) + Digest::digest(\"#{digest}\", data) + end + + def #{digest}::hexdigest(data) + Digest::hexdigest(\"#{digest}\", data) + end + end + EOD + } + + end # Digest +end # OpenSSL + diff --git a/ext/openssl/lib/openssl/ssl.rb b/ext/openssl/lib/openssl/ssl.rb new file mode 100644 index 0000000000..e434941913 --- /dev/null +++ b/ext/openssl/lib/openssl/ssl.rb @@ -0,0 +1,38 @@ +=begin += $RCSfile$ -- Ruby-space definitions that completes C-space funcs for SSL + += Info + 'OpenSSL for Ruby 2' project + Copyright (C) 2001 GOTOU YUUZOU <gotoyuzo@notwork.org> + All rights reserved. + += Licence + This program is licenced under the same licence as Ruby. + (See the file 'LICENCE'.) + += Version + $Id$ +=end + +require 'openssl/buffering' + +module OpenSSL + module SSL + class SSLSocket + include Buffering + + def addr + @io.addr + end + + def peeraddr + @io.peeraddr + end + + def closed? + @io.closed? + end + end + end +end + diff --git a/ext/openssl/lib/openssl/x509.rb b/ext/openssl/lib/openssl/x509.rb new file mode 100644 index 0000000000..f7df597acb --- /dev/null +++ b/ext/openssl/lib/openssl/x509.rb @@ -0,0 +1,132 @@ +=begin += $RCSfile$ -- Ruby-space definitions that completes C-space funcs for X509 and subclasses + += Info + 'OpenSSL for Ruby 2' project + Copyright (C) 2002 Michal Rokos <m.rokos@sh.cvut.cz> + All rights reserved. + += Licence + This program is licenced under the same licence as Ruby. + (See the file 'LICENCE'.) + += Version + $Id$ +=end + +## +# Should we care what if somebody require this file directly? +#require 'openssl' + +module OpenSSL + module X509 + + class ExtensionFactory + def create_extension(*arg) + if arg.size == 1 then arg = arg[0] end + type = arg.class + while type + method = "create_ext_from_#{type.name.downcase}".intern + return send(method, arg) if respond_to? method + type = type.superclass + end + raise TypeError, "Don't how to create ext from #{arg.class}" + ###send("create_ext_from_#{arg.class.name.downcase}", arg) + end + + # + # create_ext_from_array is built-in + # + def create_ext_from_string(str) # "oid = critical, value" + unless str =~ /\s*=\s*/ + raise ArgumentError, "string in format \"oid = value\" expected" + end + ary = [] + ary << $`.sub(/^\s*/,"") # delete whitespaces from the beginning + rest = $'.sub(/\s*$/,"") # delete them from the end + if rest =~ /^critical,\s*/ # handle 'critical' option + ary << $' + ary << true + else + ary << rest + end + create_ext_from_array(ary) + end + + # + # Create an extention from Hash + # {"oid"=>sn|ln, "value"=>value, "critical"=>true|false} + # + def create_ext_from_hash(hash) + unless (hash.has_key? "oid" and hash.has_key? "value") + raise ArgumentError, + "hash in format {\"oid\"=>..., \"value\"=>...} expected" + end + ary = [] + ary << hash["oid"] + ary << hash["value"] + ary << hash["critical"] if hash.has_key? "critical" + create_ext_from_array(ary) + end + end # ExtensionFactory + + class Extension + def to_s # "oid = critical, value" + str = self.oid + str << " = " + str << "critical, " if self.critical? + str << self.value.gsub(/\n/, ", ") + end + + def to_h # {"oid"=>sn|ln, "value"=>value, "critical"=>true|false} + {"oid"=>self.oid,"value"=>self.value,"critical"=>self.critical?} + end + + def to_a + [ self.oid, self.value, self.critical? ] + end + end # Extension + + class Attribute + def Attribute::new(arg) + type = arg.class + while type + method = "new_from_#{type.name.downcase}".intern + return Attribute::send(method, arg) if Attribute::respond_to? method + type = type.superclass + end + raise "Don't how to make new #{self} from #{arg.class}" + ###Attribute::send("new_from_#{arg.class.name.downcase}", arg) + end + + # + # Attribute::new_from_array(ary) is built-in method + # + def Attribute::new_from_string(str) # "oid = value" + unless str =~ /\s*=\s*/ + raise ArgumentError, "string in format \"oid = value\" expected" + end + ary = [] + ary << $`.sub(/^\s*/,"") # delete whitespaces from the beginning + ary << $'.sub(/\s*$/,"") # delete them from the end + Attribute::new_from_array(ary) + end + + # + # Create an attribute from Hash + # {"oid"=>sn|ln, "value"=>value, "critical"=>true|false} + # + def Attribute::new_from_hash(hash) # {"oid"=>"...", "value"=>"..."} + unless (hash.has_key? "oid" and hash.has_key? "value") + raise ArgumentError, + "hash in format {\"oid\"=>..., \"value\"=>...} expected" + end + ary = [] + ary << hash["oid"] + ary << hash["value"] + Attribute::new_from_array(ary) + end + end # Attribute + + end # X509 +end # OpenSSL |