jruby-openssl 0.9.5-java
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/History.txt +218 -0
- data/License.txt +30 -0
- data/Mavenfile +44 -0
- data/README.txt +13 -0
- data/Rakefile +7 -0
- data/lib/jopenssl.jar +0 -0
- data/lib/jopenssl/load.rb +29 -0
- data/lib/jopenssl/version.rb +6 -0
- data/lib/jopenssl18/openssl.rb +23 -0
- data/lib/jopenssl18/openssl/bn.rb +35 -0
- data/lib/jopenssl18/openssl/buffering.rb +241 -0
- data/lib/jopenssl18/openssl/cipher.rb +65 -0
- data/lib/jopenssl18/openssl/config.rb +316 -0
- data/lib/jopenssl18/openssl/digest.rb +61 -0
- data/lib/jopenssl18/openssl/pkcs7.rb +25 -0
- data/lib/jopenssl18/openssl/ssl-internal.rb +179 -0
- data/lib/jopenssl18/openssl/ssl.rb +1 -0
- data/lib/jopenssl18/openssl/x509-internal.rb +153 -0
- data/lib/jopenssl18/openssl/x509.rb +1 -0
- data/lib/jopenssl19/openssl.rb +23 -0
- data/lib/jopenssl19/openssl/bn.rb +35 -0
- data/lib/jopenssl19/openssl/buffering.rb +449 -0
- data/lib/jopenssl19/openssl/cipher.rb +65 -0
- data/lib/jopenssl19/openssl/config.rb +313 -0
- data/lib/jopenssl19/openssl/digest.rb +72 -0
- data/lib/jopenssl19/openssl/ssl-internal.rb +177 -0
- data/lib/jopenssl19/openssl/ssl.rb +2 -0
- data/lib/jopenssl19/openssl/x509-internal.rb +158 -0
- data/lib/jopenssl19/openssl/x509.rb +2 -0
- data/lib/jopenssl21/openssl.rb +23 -0
- data/lib/jopenssl21/openssl/bn.rb +35 -0
- data/lib/jopenssl21/openssl/buffering.rb +449 -0
- data/lib/jopenssl21/openssl/cipher.rb +65 -0
- data/lib/jopenssl21/openssl/config.rb +313 -0
- data/lib/jopenssl21/openssl/digest.rb +89 -0
- data/lib/jopenssl21/openssl/ssl.rb +237 -0
- data/lib/jopenssl21/openssl/x509.rb +162 -0
- data/lib/jruby-openssl.rb +5 -0
- data/lib/openssl.rb +1 -0
- data/lib/openssl/bn.rb +7 -0
- data/lib/openssl/buffering.rb +7 -0
- data/lib/openssl/cipher.rb +7 -0
- data/lib/openssl/config.rb +7 -0
- data/lib/openssl/digest.rb +7 -0
- data/lib/openssl/pkcs12.rb +106 -0
- data/lib/openssl/pkcs7.rb +7 -0
- data/lib/openssl/ssl-internal.rb +7 -0
- data/lib/openssl/ssl.rb +7 -0
- data/lib/openssl/x509-internal.rb +7 -0
- data/lib/openssl/x509.rb +7 -0
- data/lib/org/bouncycastle/bcpkix-jdk15on/1.47/bcpkix-jdk15on-1.47.jar +0 -0
- data/lib/org/bouncycastle/bcprov-jdk15on/1.47/bcprov-jdk15on-1.47.jar +0 -0
- metadata +97 -0
@@ -0,0 +1,237 @@
|
|
1
|
+
=begin
|
2
|
+
= $RCSfile$ -- Ruby-space definitions that completes C-space funcs for SSL
|
3
|
+
|
4
|
+
= Info
|
5
|
+
'OpenSSL for Ruby 2' project
|
6
|
+
Copyright (C) 2001 GOTOU YUUZOU <gotoyuzo@notwork.org>
|
7
|
+
All rights reserved.
|
8
|
+
|
9
|
+
= Licence
|
10
|
+
This program is licenced under the same licence as Ruby.
|
11
|
+
(See the file 'LICENCE'.)
|
12
|
+
|
13
|
+
= Version
|
14
|
+
$Id$
|
15
|
+
=end
|
16
|
+
|
17
|
+
require "openssl/buffering"
|
18
|
+
require "fcntl"
|
19
|
+
|
20
|
+
module OpenSSL
|
21
|
+
module SSL
|
22
|
+
class SSLContext
|
23
|
+
DEFAULT_PARAMS = {
|
24
|
+
:ssl_version => "SSLv23",
|
25
|
+
:verify_mode => OpenSSL::SSL::VERIFY_PEER,
|
26
|
+
:ciphers => "ALL:!ADH:!EXPORT:!SSLv2:RC4+RSA:+HIGH:+MEDIUM:+LOW",
|
27
|
+
:options => defined?(OpenSSL::SSL::OP_DONT_INSERT_EMPTY_FRAGMENTS) ?
|
28
|
+
OpenSSL::SSL::OP_ALL & ~OpenSSL::SSL::OP_DONT_INSERT_EMPTY_FRAGMENTS :
|
29
|
+
OpenSSL::SSL::OP_ALL,
|
30
|
+
}
|
31
|
+
|
32
|
+
DEFAULT_CERT_STORE = OpenSSL::X509::Store.new
|
33
|
+
DEFAULT_CERT_STORE.set_default_paths
|
34
|
+
if defined?(OpenSSL::X509::V_FLAG_CRL_CHECK_ALL)
|
35
|
+
DEFAULT_CERT_STORE.flags = OpenSSL::X509::V_FLAG_CRL_CHECK_ALL
|
36
|
+
end
|
37
|
+
|
38
|
+
##
|
39
|
+
# Sets the parameters for this SSL context to the values in +params+.
|
40
|
+
# The keys in +params+ must be assignment methods on SSLContext.
|
41
|
+
#
|
42
|
+
# If the verify_mode is not VERIFY_NONE and ca_file, ca_path and
|
43
|
+
# cert_store are not set then the system default certificate store is
|
44
|
+
# used.
|
45
|
+
|
46
|
+
def set_params(params={})
|
47
|
+
params = DEFAULT_PARAMS.merge(params)
|
48
|
+
params.each{|name, value| self.__send__("#{name}=", value) }
|
49
|
+
if self.verify_mode != OpenSSL::SSL::VERIFY_NONE
|
50
|
+
unless self.ca_file or self.ca_path or self.cert_store
|
51
|
+
self.cert_store = DEFAULT_CERT_STORE
|
52
|
+
end
|
53
|
+
end
|
54
|
+
return params
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
module SocketForwarder
|
59
|
+
def addr
|
60
|
+
to_io.addr
|
61
|
+
end
|
62
|
+
|
63
|
+
def peeraddr
|
64
|
+
to_io.peeraddr
|
65
|
+
end
|
66
|
+
|
67
|
+
def setsockopt(level, optname, optval)
|
68
|
+
to_io.setsockopt(level, optname, optval)
|
69
|
+
end
|
70
|
+
|
71
|
+
def getsockopt(level, optname)
|
72
|
+
to_io.getsockopt(level, optname)
|
73
|
+
end
|
74
|
+
|
75
|
+
def fcntl(*args)
|
76
|
+
to_io.fcntl(*args)
|
77
|
+
end
|
78
|
+
|
79
|
+
def closed?
|
80
|
+
to_io.closed?
|
81
|
+
end
|
82
|
+
|
83
|
+
def do_not_reverse_lookup=(flag)
|
84
|
+
to_io.do_not_reverse_lookup = flag
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
module Nonblock
|
89
|
+
def initialize(*args)
|
90
|
+
flag = File::NONBLOCK
|
91
|
+
flag |= @io.fcntl(Fcntl::F_GETFL) if defined?(Fcntl::F_GETFL)
|
92
|
+
@io.fcntl(Fcntl::F_SETFL, flag)
|
93
|
+
super
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
# FIXME: Using the old non-ASN1 logic here because our ASN1 appears to
|
98
|
+
# return the wrong types for some decoded objects. See #1102
|
99
|
+
def verify_certificate_identity(cert, hostname)
|
100
|
+
should_verify_common_name = true
|
101
|
+
cert.extensions.each{|ext|
|
102
|
+
next if ext.oid != "subjectAltName"
|
103
|
+
ext.value.split(/,\s+/).each{|general_name|
|
104
|
+
if /\ADNS:(.*)/ =~ general_name
|
105
|
+
should_verify_common_name = false
|
106
|
+
reg = Regexp.escape($1).gsub(/\\\*/, "[^.]+")
|
107
|
+
return true if /\A#{reg}\z/i =~ hostname
|
108
|
+
elsif /\AIP Address:(.*)/ =~ general_name
|
109
|
+
should_verify_common_name = false
|
110
|
+
return true if $1 == hostname
|
111
|
+
end
|
112
|
+
}
|
113
|
+
}
|
114
|
+
if should_verify_common_name
|
115
|
+
cert.subject.to_a.each{|oid, value|
|
116
|
+
if oid == "CN"
|
117
|
+
reg = Regexp.escape(value).gsub(/\\\*/, "[^.]+")
|
118
|
+
return true if /\A#{reg}\z/i =~ hostname
|
119
|
+
end
|
120
|
+
}
|
121
|
+
end
|
122
|
+
return false
|
123
|
+
end
|
124
|
+
=begin
|
125
|
+
def verify_certificate_identity(cert, hostname)
|
126
|
+
should_verify_common_name = true
|
127
|
+
cert.extensions.each{|ext|
|
128
|
+
next if ext.oid != "subjectAltName"
|
129
|
+
ostr = OpenSSL::ASN1.decode(ext.to_der).value.last
|
130
|
+
sequence = OpenSSL::ASN1.decode(ostr.value)
|
131
|
+
sequence.value.each{|san|
|
132
|
+
case san.tag
|
133
|
+
when 2 # dNSName in GeneralName (RFC5280)
|
134
|
+
should_verify_common_name = false
|
135
|
+
reg = Regexp.escape(san.value).gsub(/\\\*/, "[^.]+")
|
136
|
+
return true if /\A#{reg}\z/i =~ hostname
|
137
|
+
when 7 # iPAddress in GeneralName (RFC5280)
|
138
|
+
should_verify_common_name = false
|
139
|
+
# follows GENERAL_NAME_print() in x509v3/v3_alt.c
|
140
|
+
if san.value.size == 4
|
141
|
+
return true if san.value.unpack('C*').join('.') == hostname
|
142
|
+
elsif san.value.size == 16
|
143
|
+
return true if san.value.unpack('n*').map { |e| sprintf("%X", e) }.join(':') == hostname
|
144
|
+
end
|
145
|
+
end
|
146
|
+
}
|
147
|
+
}
|
148
|
+
if should_verify_common_name
|
149
|
+
cert.subject.to_a.each{|oid, value|
|
150
|
+
if oid == "CN"
|
151
|
+
reg = Regexp.escape(value).gsub(/\\\*/, "[^.]+")
|
152
|
+
return true if /\A#{reg}\z/i =~ hostname
|
153
|
+
end
|
154
|
+
}
|
155
|
+
end
|
156
|
+
return false
|
157
|
+
end
|
158
|
+
=end
|
159
|
+
module_function :verify_certificate_identity
|
160
|
+
|
161
|
+
class SSLSocket
|
162
|
+
include Buffering
|
163
|
+
include SocketForwarder
|
164
|
+
include Nonblock
|
165
|
+
|
166
|
+
def post_connection_check(hostname)
|
167
|
+
unless OpenSSL::SSL.verify_certificate_identity(peer_cert, hostname)
|
168
|
+
raise SSLError, "hostname \"#{hostname}\" does not match the server certificate"
|
169
|
+
end
|
170
|
+
return true
|
171
|
+
end
|
172
|
+
|
173
|
+
def session
|
174
|
+
SSL::Session.new(self)
|
175
|
+
rescue SSL::Session::SessionError
|
176
|
+
nil
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
##
|
181
|
+
# SSLServer represents a TCP/IP server socket with Secure Sockets Layer.
|
182
|
+
class SSLServer
|
183
|
+
include SocketForwarder
|
184
|
+
# When true then #accept works exactly the same as TCPServer#accept
|
185
|
+
attr_accessor :start_immediately
|
186
|
+
|
187
|
+
# Creates a new instance of SSLServer.
|
188
|
+
# * +srv+ is an instance of TCPServer.
|
189
|
+
# * +ctx+ is an instance of OpenSSL::SSL::SSLContext.
|
190
|
+
def initialize(svr, ctx)
|
191
|
+
@svr = svr
|
192
|
+
@ctx = ctx
|
193
|
+
unless ctx.session_id_context
|
194
|
+
# see #6137 - session id may not exceed 32 bytes
|
195
|
+
prng = ::Random.new($0.hash)
|
196
|
+
session_id = prng.bytes(16).unpack('H*')[0]
|
197
|
+
@ctx.session_id_context = session_id
|
198
|
+
end
|
199
|
+
@start_immediately = true
|
200
|
+
end
|
201
|
+
|
202
|
+
# Returns the TCPServer passed to the SSLServer when initialized.
|
203
|
+
def to_io
|
204
|
+
@svr
|
205
|
+
end
|
206
|
+
|
207
|
+
# See TCPServer#listen for details.
|
208
|
+
def listen(backlog=5)
|
209
|
+
@svr.listen(backlog)
|
210
|
+
end
|
211
|
+
|
212
|
+
# See BasicSocket#shutdown for details.
|
213
|
+
def shutdown(how=Socket::SHUT_RDWR)
|
214
|
+
@svr.shutdown(how)
|
215
|
+
end
|
216
|
+
|
217
|
+
# Works similar to TCPServer#accept.
|
218
|
+
def accept
|
219
|
+
sock = @svr.accept
|
220
|
+
begin
|
221
|
+
ssl = OpenSSL::SSL::SSLSocket.new(sock, @ctx)
|
222
|
+
ssl.sync_close = true
|
223
|
+
ssl.accept if @start_immediately
|
224
|
+
ssl
|
225
|
+
rescue SSLError => ex
|
226
|
+
sock.close
|
227
|
+
raise ex
|
228
|
+
end
|
229
|
+
end
|
230
|
+
|
231
|
+
# See IO#close for details.
|
232
|
+
def close
|
233
|
+
@svr.close
|
234
|
+
end
|
235
|
+
end
|
236
|
+
end
|
237
|
+
end
|
@@ -0,0 +1,162 @@
|
|
1
|
+
#--
|
2
|
+
#
|
3
|
+
# $RCSfile$
|
4
|
+
#
|
5
|
+
# = Ruby-space definitions that completes C-space funcs for X509 and subclasses
|
6
|
+
#
|
7
|
+
# = Info
|
8
|
+
# 'OpenSSL for Ruby 2' project
|
9
|
+
# Copyright (C) 2002 Michal Rokos <m.rokos@sh.cvut.cz>
|
10
|
+
# All rights reserved.
|
11
|
+
#
|
12
|
+
# = Licence
|
13
|
+
# This program is licenced under the same licence as Ruby.
|
14
|
+
# (See the file 'LICENCE'.)
|
15
|
+
#
|
16
|
+
# = Version
|
17
|
+
# $Id$
|
18
|
+
#
|
19
|
+
#++
|
20
|
+
|
21
|
+
module OpenSSL
|
22
|
+
module X509
|
23
|
+
class ExtensionFactory
|
24
|
+
def create_extension(*arg)
|
25
|
+
if arg.size > 1
|
26
|
+
create_ext(*arg)
|
27
|
+
else
|
28
|
+
send("create_ext_from_"+arg[0].class.name.downcase, arg[0])
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def create_ext_from_array(ary)
|
33
|
+
raise ExtensionError, "unexpected array form" if ary.size > 3
|
34
|
+
create_ext(ary[0], ary[1], ary[2])
|
35
|
+
end
|
36
|
+
|
37
|
+
def create_ext_from_string(str) # "oid = critical, value"
|
38
|
+
oid, value = str.split(/=/, 2)
|
39
|
+
oid.strip!
|
40
|
+
value.strip!
|
41
|
+
create_ext(oid, value)
|
42
|
+
end
|
43
|
+
|
44
|
+
def create_ext_from_hash(hash)
|
45
|
+
create_ext(hash["oid"], hash["value"], hash["critical"])
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
class Extension
|
50
|
+
def to_s # "oid = critical, value"
|
51
|
+
str = self.oid
|
52
|
+
str << " = "
|
53
|
+
str << "critical, " if self.critical?
|
54
|
+
str << self.value.gsub(/\n/, ", ")
|
55
|
+
end
|
56
|
+
|
57
|
+
def to_h # {"oid"=>sn|ln, "value"=>value, "critical"=>true|false}
|
58
|
+
{"oid"=>self.oid,"value"=>self.value,"critical"=>self.critical?}
|
59
|
+
end
|
60
|
+
|
61
|
+
def to_a
|
62
|
+
[ self.oid, self.value, self.critical? ]
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
class Name
|
67
|
+
module RFC2253DN
|
68
|
+
Special = ',=+<>#;'
|
69
|
+
HexChar = /[0-9a-fA-F]/
|
70
|
+
HexPair = /#{HexChar}#{HexChar}/
|
71
|
+
HexString = /#{HexPair}+/
|
72
|
+
Pair = /\\(?:[#{Special}]|\\|"|#{HexPair})/
|
73
|
+
StringChar = /[^#{Special}\\"]/
|
74
|
+
QuoteChar = /[^\\"]/
|
75
|
+
AttributeType = /[a-zA-Z][0-9a-zA-Z]*|[0-9]+(?:\.[0-9]+)*/
|
76
|
+
AttributeValue = /
|
77
|
+
(?!["#])((?:#{StringChar}|#{Pair})*)|
|
78
|
+
\#(#{HexString})|
|
79
|
+
"((?:#{QuoteChar}|#{Pair})*)"
|
80
|
+
/x
|
81
|
+
TypeAndValue = /\A(#{AttributeType})=#{AttributeValue}/
|
82
|
+
|
83
|
+
module_function
|
84
|
+
|
85
|
+
def expand_pair(str)
|
86
|
+
return nil unless str
|
87
|
+
return str.gsub(Pair){
|
88
|
+
pair = $&
|
89
|
+
case pair.size
|
90
|
+
when 2 then pair[1,1]
|
91
|
+
when 3 then Integer("0x#{pair[1,2]}").chr
|
92
|
+
else raise OpenSSL::X509::NameError, "invalid pair: #{str}"
|
93
|
+
end
|
94
|
+
}
|
95
|
+
end
|
96
|
+
|
97
|
+
def expand_hexstring(str)
|
98
|
+
return nil unless str
|
99
|
+
der = str.gsub(HexPair){$&.to_i(16).chr }
|
100
|
+
a1 = OpenSSL::ASN1.decode(der)
|
101
|
+
return a1.value, a1.tag
|
102
|
+
end
|
103
|
+
|
104
|
+
def expand_value(str1, str2, str3)
|
105
|
+
value = expand_pair(str1)
|
106
|
+
value, tag = expand_hexstring(str2) unless value
|
107
|
+
value = expand_pair(str3) unless value
|
108
|
+
return value, tag
|
109
|
+
end
|
110
|
+
|
111
|
+
def scan(dn)
|
112
|
+
str = dn
|
113
|
+
ary = []
|
114
|
+
while true
|
115
|
+
if md = TypeAndValue.match(str)
|
116
|
+
remain = md.post_match
|
117
|
+
type = md[1]
|
118
|
+
value, tag = expand_value(md[2], md[3], md[4]) rescue nil
|
119
|
+
if value
|
120
|
+
type_and_value = [type, value]
|
121
|
+
type_and_value.push(tag) if tag
|
122
|
+
ary.unshift(type_and_value)
|
123
|
+
if remain.length > 2 && remain[0] == ?,
|
124
|
+
str = remain[1..-1]
|
125
|
+
next
|
126
|
+
elsif remain.length > 2 && remain[0] == ?+
|
127
|
+
raise OpenSSL::X509::NameError,
|
128
|
+
"multi-valued RDN is not supported: #{dn}"
|
129
|
+
elsif remain.empty?
|
130
|
+
break
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
msg_dn = dn[0, dn.length - str.length] + " =>" + str
|
135
|
+
raise OpenSSL::X509::NameError, "malformed RDN: #{msg_dn}"
|
136
|
+
end
|
137
|
+
return ary
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
class << self
|
142
|
+
def parse_rfc2253(str, template=OBJECT_TYPE_TEMPLATE)
|
143
|
+
ary = OpenSSL::X509::Name::RFC2253DN.scan(str)
|
144
|
+
self.new(ary, template)
|
145
|
+
end
|
146
|
+
|
147
|
+
def parse_openssl(str, template=OBJECT_TYPE_TEMPLATE)
|
148
|
+
ary = str.scan(/\s*([^\/,]+)\s*/).collect{|i| i[0].split("=", 2) }
|
149
|
+
self.new(ary, template)
|
150
|
+
end
|
151
|
+
|
152
|
+
alias parse parse_openssl
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
class StoreContext
|
157
|
+
def cleanup
|
158
|
+
warn "(#{caller.first}) OpenSSL::X509::StoreContext#cleanup is deprecated with no replacement" if $VERBOSE
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
data/lib/openssl.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'jopenssl/load'
|
data/lib/openssl/bn.rb
ADDED