Skip to content

Commit

Permalink
Ruby 2.3 compatibility - for now mostly adjust to changes in MRI's op…
Browse files Browse the repository at this point in the history
…enssl .rb parts
kares committed Dec 20, 2015
1 parent cd47562 commit 126d868
Showing 11 changed files with 1,668 additions and 2 deletions.
4 changes: 3 additions & 1 deletion lib/jopenssl/load.rb
Original file line number Diff line number Diff line change
@@ -24,7 +24,9 @@
require 'jopenssl.jar'
org.jruby.ext.openssl.OpenSSL.load(JRuby.runtime)

if RUBY_VERSION > '2.2'
if RUBY_VERSION > '2.3'
load 'jopenssl23/openssl.rb'
elsif RUBY_VERSION > '2.2'
load 'jopenssl22/openssl.rb'
elsif RUBY_VERSION > '2.1'
load 'jopenssl21/openssl.rb'
22 changes: 22 additions & 0 deletions lib/jopenssl23/openssl.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
=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/bn'
require 'openssl/cipher'
require 'openssl/config'
require 'openssl/digest'
require 'openssl/x509'
require 'openssl/ssl'
37 changes: 37 additions & 0 deletions lib/jopenssl23/openssl/bn.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# frozen_string_literal: false
#--
#
# = 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 licensed under the same licence as Ruby.
# (See the file 'LICENCE'.)
#++

module OpenSSL
class BN
def pretty_print(q)
q.object_group(self) {
q.text ' '
q.text to_i.to_s
}
end
end # BN
end # OpenSSL

##
# Add double dispatch to Integer
#
class Integer
# Casts an Integer as an OpenSSL::BN
#
# See `man bn` for more info.
def to_bn
OpenSSL::BN::new(self)
end
end # Integer
453 changes: 453 additions & 0 deletions lib/jopenssl23/openssl/buffering.rb

Large diffs are not rendered by default.

22 changes: 22 additions & 0 deletions lib/jopenssl23/openssl/cipher.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# frozen_string_literal: false
#--
# = 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 licensed under the same licence as Ruby.
# (See the file 'LICENCE'.)
#++

module OpenSSL
class Cipher
# This class is only provided for backwards compatibility. Use OpenSSL::Cipher in the future.
class Cipher < Cipher
# add warning
end
end # Cipher
end # OpenSSL
473 changes: 473 additions & 0 deletions lib/jopenssl23/openssl/config.rb

Large diffs are not rendered by default.

48 changes: 48 additions & 0 deletions lib/jopenssl23/openssl/digest.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# frozen_string_literal: false
#--
# = 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 licensed under the same licence as Ruby.
# (See the file 'LICENCE'.)
#++

module OpenSSL
class Digest
# Deprecated.
#
# This class is only provided for backwards compatibility.
class Digest < Digest # :nodoc:
# Deprecated.
#
# See OpenSSL::Digest.new
def initialize(*args)
warn('Digest::Digest is deprecated; use Digest')
super(*args)
end
end

end # Digest

# Returns a Digest subclass by +name+.
#
# require 'openssl'
#
# OpenSSL::Digest("MD5")
# # => OpenSSL::Digest::MD5
#
# Digest("Foo")
# # => NameError: wrong constant name Foo

def Digest(name)
OpenSSL::Digest.const_get(name)
end

module_function :Digest

end # OpenSSL
37 changes: 37 additions & 0 deletions lib/jopenssl23/openssl/pkey.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# frozen_string_literal: false
module OpenSSL
module PKey
if defined?(OpenSSL::PKey::DH)

class DH
DEFAULT_512 = new <<-_end_of_pem_
-----BEGIN DH PARAMETERS-----
MEYCQQD0zXHljRg/mJ9PYLACLv58Cd8VxBxxY7oEuCeURMiTqEhMym16rhhKgZG2
zk2O9uUIBIxSj+NKMURHGaFKyIvLAgEC
-----END DH PARAMETERS-----
_end_of_pem_

DEFAULT_1024 = new <<-_end_of_pem_
-----BEGIN DH PARAMETERS-----
MIGHAoGBAJ0lOVy0VIr/JebWn0zDwY2h+rqITFOpdNr6ugsgvkDXuucdcChhYExJ
AV/ZD2AWPbrTqV76mGRgJg4EddgT1zG0jq3rnFdMj2XzkBYx3BVvfR0Arnby0RHR
T4h7KZ/2zmjvV+eF8kBUHBJAojUlzxKj4QeO2x20FP9X5xmNUXeDAgEC
-----END DH PARAMETERS-----
_end_of_pem_
end

DEFAULT_TMP_DH_CALLBACK = lambda { |ctx, is_export, keylen|
warn "using default DH parameters." if $VERBOSE
case keylen
when 512 then OpenSSL::PKey::DH::DEFAULT_512
when 1024 then OpenSSL::PKey::DH::DEFAULT_1024
else
nil
end
}

else
DEFAULT_TMP_DH_CALLBACK = nil
end
end
end
425 changes: 425 additions & 0 deletions lib/jopenssl23/openssl/ssl.rb

Large diffs are not rendered by default.

133 changes: 133 additions & 0 deletions lib/jopenssl23/openssl/x509.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
# frozen_string_literal: false
#--
# = 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 licensed under the same licence as Ruby.
# (See the file 'LICENCE'.)
#++

module OpenSSL
module X509
class Name
module RFC2253DN
Special = ',=+<>#;'
HexChar = /[0-9a-fA-F]/
HexPair = /#{HexChar}#{HexChar}/
HexString = /#{HexPair}+/
Pair = /\\(?:[#{Special}]|\\|"|#{HexPair})/
StringChar = /[^\\"#{Special}]/
QuoteChar = /[^\\"]/
AttributeType = /[a-zA-Z][0-9a-zA-Z]*|[0-9]+(?:\.[0-9]+)*/
AttributeValue = /
(?!["#])((?:#{StringChar}|#{Pair})*)|
\#(#{HexString})|
"((?:#{QuoteChar}|#{Pair})*)"
/x
TypeAndValue = /\A(#{AttributeType})=#{AttributeValue}/

module_function

def expand_pair(str)
return nil unless str
return str.gsub(Pair){
pair = $&
case pair.size
when 2 then pair[1,1]
when 3 then Integer("0x#{pair[1,2]}").chr
else raise OpenSSL::X509::NameError, "invalid pair: #{str}"
end
}
end

def expand_hexstring(str)
return nil unless str
der = str.gsub(HexPair){$&.to_i(16).chr }
a1 = OpenSSL::ASN1.decode(der)
return a1.value, a1.tag
end

def expand_value(str1, str2, str3)
value = expand_pair(str1)
value, tag = expand_hexstring(str2) unless value
value = expand_pair(str3) unless value
return value, tag
end

def scan(dn)
str = dn
ary = []
while true
if md = TypeAndValue.match(str)
remain = md.post_match
type = md[1]
value, tag = expand_value(md[2], md[3], md[4]) rescue nil
if value
type_and_value = [type, value]
type_and_value.push(tag) if tag
ary.unshift(type_and_value)
if remain.length > 2 && remain[0] == ?,
str = remain[1..-1]
next
elsif remain.length > 2 && remain[0] == ?+
raise OpenSSL::X509::NameError,
"multi-valued RDN is not supported: #{dn}"
elsif remain.empty?
break
end
end
end
msg_dn = dn[0, dn.length - str.length] + " =>" + str
raise OpenSSL::X509::NameError, "malformed RDN: #{msg_dn}"
end
return ary
end
end

class << self
def parse_rfc2253(str, template=OBJECT_TYPE_TEMPLATE)
ary = OpenSSL::X509::Name::RFC2253DN.scan(str)
self.new(ary, template)
end

def parse_openssl(str, template=OBJECT_TYPE_TEMPLATE)
ary = str.scan(/\s*([^\/,]+)\s*/).collect{|i| i[0].split("=", 2) }
self.new(ary, template)
end

alias parse parse_openssl
end

def pretty_print(q)
q.object_group(self) {
q.text ' '
q.text to_s(OpenSSL::X509::Name::RFC2253)
}
end
end

class StoreContext
def cleanup
warn "(#{caller.first}) OpenSSL::X509::StoreContext#cleanup is deprecated with no replacement" if $VERBOSE
end
end

class Certificate
def pretty_print(q)
q.object_group(self) {
q.breakable
q.text 'subject='; q.pp self.subject; q.text ','; q.breakable
q.text 'issuer='; q.pp self.issuer; q.text ','; q.breakable
q.text 'serial='; q.pp self.serial; q.text ','; q.breakable
q.text 'not_before='; q.pp self.not_before; q.text ','; q.breakable
q.text 'not_after='; q.pp self.not_after
}
end
end
end
end
16 changes: 15 additions & 1 deletion src/main/java/org/jruby/ext/openssl/SSLSocket.java
Original file line number Diff line number Diff line change
@@ -158,6 +158,10 @@ public IRubyObject initialize(final ThreadContext context, final IRubyObject[] a
throw runtime.newTypeError("IO expected but got " + args[0].getMetaClass().getName());
}
setInstanceVariable("@io", this.io = (RubyIO) args[0]); // compat (we do not read @io)
// Ruby 2.3 : @io.nonblock = true if @io.respond_to?(:nonblock=)
if (io.respondsTo("nonblock=")) {
io.callMethod(context, "nonblock=", runtime.getTrue());
}
setInstanceVariable("@context", this.sslContext); // only compat (we do not use @context)
// This is a bit of a hack: SSLSocket should share code with
// RubyBasicSocket, which always sets sync to true.
@@ -879,7 +883,11 @@ private void forceClose() {
close(true);
}

//private boolean closed;

private void close(boolean force) {
//closed = true;

if ( engine == null ) throw getRuntime().newEOFError();

engine.closeOutbound();
@@ -895,13 +903,19 @@ private void close(boolean force) {
}
}

//final boolean isClosed() { return closed; }

@JRubyMethod
public IRubyObject sysclose(final ThreadContext context) {
//if ( isClosed() ) return context.runtime.getNil();
if ( this.io.callMethod(context, "closed?").isTrue() ) {
return context.runtime.getNil();
} // Ruby 2.3
// no need to try shutdown when it's a server
close( sslContext.isProtocolForClient() );

if ( this.callMethod(context, "sync_close").isTrue() ) {
this.io.callMethod(context, "close");
return this.io.callMethod(context, "close");
}
return context.runtime.getNil();
}

0 comments on commit 126d868

Please sign in to comment.