jruby-openssl 0.9.12-java → 0.9.13-java
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Rakefile +6 -3
- data/lib/jopenssl.jar +0 -0
- data/lib/jopenssl/load.rb +3 -1
- data/lib/jopenssl/version.rb +8 -3
- data/lib/jopenssl22/openssl/ssl.rb +155 -18
- data/lib/jopenssl23/openssl.rb +19 -0
- data/lib/jopenssl23/openssl/bn.rb +37 -0
- data/lib/jopenssl23/openssl/buffering.rb +453 -0
- data/lib/jopenssl23/openssl/cipher.rb +22 -0
- data/lib/jopenssl23/openssl/config.rb +473 -0
- data/lib/jopenssl23/openssl/digest.rb +48 -0
- data/lib/jopenssl23/openssl/pkey.rb +37 -0
- data/lib/jopenssl23/openssl/ssl.rb +425 -0
- data/lib/jopenssl23/openssl/x509.rb +133 -0
- data/lib/openssl/bn.rb +3 -1
- data/lib/openssl/buffering.rb +3 -1
- data/lib/openssl/cipher.rb +3 -1
- data/lib/openssl/config.rb +3 -1
- data/lib/openssl/digest.rb +3 -1
- data/lib/openssl/pkcs7.rb +2 -6
- data/lib/openssl/pkey.rb +5 -0
- data/lib/openssl/ssl-internal.rb +2 -4
- data/lib/openssl/ssl.rb +3 -1
- data/lib/openssl/x509-internal.rb +2 -4
- data/lib/openssl/x509.rb +3 -1
- metadata +26 -16
@@ -0,0 +1,48 @@
|
|
1
|
+
# frozen_string_literal: false
|
2
|
+
#--
|
3
|
+
# = Ruby-space predefined Digest subclasses
|
4
|
+
#
|
5
|
+
# = Info
|
6
|
+
# 'OpenSSL for Ruby 2' project
|
7
|
+
# Copyright (C) 2002 Michal Rokos <m.rokos@sh.cvut.cz>
|
8
|
+
# All rights reserved.
|
9
|
+
#
|
10
|
+
# = Licence
|
11
|
+
# This program is licensed under the same licence as Ruby.
|
12
|
+
# (See the file 'LICENCE'.)
|
13
|
+
#++
|
14
|
+
|
15
|
+
module OpenSSL
|
16
|
+
class Digest
|
17
|
+
# Deprecated.
|
18
|
+
#
|
19
|
+
# This class is only provided for backwards compatibility.
|
20
|
+
class Digest < Digest # :nodoc:
|
21
|
+
# Deprecated.
|
22
|
+
#
|
23
|
+
# See OpenSSL::Digest.new
|
24
|
+
def initialize(*args)
|
25
|
+
warn('Digest::Digest is deprecated; use Digest')
|
26
|
+
super(*args)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
end # Digest
|
31
|
+
|
32
|
+
# Returns a Digest subclass by +name+.
|
33
|
+
#
|
34
|
+
# require 'openssl'
|
35
|
+
#
|
36
|
+
# OpenSSL::Digest("MD5")
|
37
|
+
# # => OpenSSL::Digest::MD5
|
38
|
+
#
|
39
|
+
# Digest("Foo")
|
40
|
+
# # => NameError: wrong constant name Foo
|
41
|
+
|
42
|
+
def Digest(name)
|
43
|
+
OpenSSL::Digest.const_get(name)
|
44
|
+
end
|
45
|
+
|
46
|
+
module_function :Digest
|
47
|
+
|
48
|
+
end # OpenSSL
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: false
|
2
|
+
module OpenSSL
|
3
|
+
module PKey
|
4
|
+
if defined?(OpenSSL::PKey::DH)
|
5
|
+
|
6
|
+
class DH
|
7
|
+
DEFAULT_512 = new <<-_end_of_pem_
|
8
|
+
-----BEGIN DH PARAMETERS-----
|
9
|
+
MEYCQQD0zXHljRg/mJ9PYLACLv58Cd8VxBxxY7oEuCeURMiTqEhMym16rhhKgZG2
|
10
|
+
zk2O9uUIBIxSj+NKMURHGaFKyIvLAgEC
|
11
|
+
-----END DH PARAMETERS-----
|
12
|
+
_end_of_pem_
|
13
|
+
|
14
|
+
DEFAULT_1024 = new <<-_end_of_pem_
|
15
|
+
-----BEGIN DH PARAMETERS-----
|
16
|
+
MIGHAoGBAJ0lOVy0VIr/JebWn0zDwY2h+rqITFOpdNr6ugsgvkDXuucdcChhYExJ
|
17
|
+
AV/ZD2AWPbrTqV76mGRgJg4EddgT1zG0jq3rnFdMj2XzkBYx3BVvfR0Arnby0RHR
|
18
|
+
T4h7KZ/2zmjvV+eF8kBUHBJAojUlzxKj4QeO2x20FP9X5xmNUXeDAgEC
|
19
|
+
-----END DH PARAMETERS-----
|
20
|
+
_end_of_pem_
|
21
|
+
end
|
22
|
+
|
23
|
+
DEFAULT_TMP_DH_CALLBACK = lambda { |ctx, is_export, keylen|
|
24
|
+
warn "using default DH parameters." if $VERBOSE
|
25
|
+
case keylen
|
26
|
+
when 512 then OpenSSL::PKey::DH::DEFAULT_512
|
27
|
+
when 1024 then OpenSSL::PKey::DH::DEFAULT_1024
|
28
|
+
else
|
29
|
+
nil
|
30
|
+
end
|
31
|
+
}
|
32
|
+
|
33
|
+
else
|
34
|
+
DEFAULT_TMP_DH_CALLBACK = nil
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,425 @@
|
|
1
|
+
# frozen_string_literal: false
|
2
|
+
=begin
|
3
|
+
= Info
|
4
|
+
'OpenSSL for Ruby 2' project
|
5
|
+
Copyright (C) 2001 GOTOU YUUZOU <gotoyuzo@notwork.org>
|
6
|
+
All rights reserved.
|
7
|
+
|
8
|
+
= Licence
|
9
|
+
This program is licensed under the same licence as Ruby.
|
10
|
+
(See the file 'LICENCE'.)
|
11
|
+
=end
|
12
|
+
|
13
|
+
require "openssl/buffering"
|
14
|
+
require "io/nonblock"
|
15
|
+
|
16
|
+
module OpenSSL
|
17
|
+
module SSL
|
18
|
+
class SSLContext
|
19
|
+
DEFAULT_PARAMS = {
|
20
|
+
:ssl_version => "SSLv23",
|
21
|
+
:verify_mode => OpenSSL::SSL::VERIFY_PEER,
|
22
|
+
:ciphers => %w{
|
23
|
+
ECDHE-ECDSA-AES128-GCM-SHA256
|
24
|
+
ECDHE-RSA-AES128-GCM-SHA256
|
25
|
+
ECDHE-ECDSA-AES256-GCM-SHA384
|
26
|
+
ECDHE-RSA-AES256-GCM-SHA384
|
27
|
+
DHE-RSA-AES128-GCM-SHA256
|
28
|
+
DHE-DSS-AES128-GCM-SHA256
|
29
|
+
DHE-RSA-AES256-GCM-SHA384
|
30
|
+
DHE-DSS-AES256-GCM-SHA384
|
31
|
+
ECDHE-ECDSA-AES128-SHA256
|
32
|
+
ECDHE-RSA-AES128-SHA256
|
33
|
+
ECDHE-ECDSA-AES128-SHA
|
34
|
+
ECDHE-RSA-AES128-SHA
|
35
|
+
ECDHE-ECDSA-AES256-SHA384
|
36
|
+
ECDHE-RSA-AES256-SHA384
|
37
|
+
ECDHE-ECDSA-AES256-SHA
|
38
|
+
ECDHE-RSA-AES256-SHA
|
39
|
+
DHE-RSA-AES128-SHA256
|
40
|
+
DHE-RSA-AES256-SHA256
|
41
|
+
DHE-RSA-AES128-SHA
|
42
|
+
DHE-RSA-AES256-SHA
|
43
|
+
DHE-DSS-AES128-SHA256
|
44
|
+
DHE-DSS-AES256-SHA256
|
45
|
+
DHE-DSS-AES128-SHA
|
46
|
+
DHE-DSS-AES256-SHA
|
47
|
+
AES128-GCM-SHA256
|
48
|
+
AES256-GCM-SHA384
|
49
|
+
AES128-SHA256
|
50
|
+
AES256-SHA256
|
51
|
+
AES128-SHA
|
52
|
+
AES256-SHA
|
53
|
+
ECDHE-ECDSA-RC4-SHA
|
54
|
+
ECDHE-RSA-RC4-SHA
|
55
|
+
RC4-SHA
|
56
|
+
}.join(":"),
|
57
|
+
:options => -> {
|
58
|
+
opts = OpenSSL::SSL::OP_ALL
|
59
|
+
opts &= ~OpenSSL::SSL::OP_DONT_INSERT_EMPTY_FRAGMENTS if defined?(OpenSSL::SSL::OP_DONT_INSERT_EMPTY_FRAGMENTS)
|
60
|
+
opts |= OpenSSL::SSL::OP_NO_COMPRESSION if defined?(OpenSSL::SSL::OP_NO_COMPRESSION)
|
61
|
+
opts |= OpenSSL::SSL::OP_NO_SSLv2 if defined?(OpenSSL::SSL::OP_NO_SSLv2)
|
62
|
+
opts |= OpenSSL::SSL::OP_NO_SSLv3 if defined?(OpenSSL::SSL::OP_NO_SSLv3)
|
63
|
+
opts
|
64
|
+
}.call
|
65
|
+
} unless const_defined? :DEFAULT_PARAMS # JRuby does it in Java
|
66
|
+
|
67
|
+
unless const_defined? :DEFAULT_CERT_STORE # JRuby specific
|
68
|
+
DEFAULT_CERT_STORE = OpenSSL::X509::Store.new
|
69
|
+
DEFAULT_CERT_STORE.set_default_paths
|
70
|
+
if defined?(OpenSSL::X509::V_FLAG_CRL_CHECK_ALL)
|
71
|
+
DEFAULT_CERT_STORE.flags = OpenSSL::X509::V_FLAG_CRL_CHECK_ALL
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
INIT_VARS = ["cert", "key", "client_ca", "ca_file", "ca_path",
|
76
|
+
"timeout", "verify_mode", "verify_depth", "renegotiation_cb",
|
77
|
+
"verify_callback", "cert_store", "extra_chain_cert",
|
78
|
+
"client_cert_cb", "session_id_context", "tmp_dh_callback",
|
79
|
+
"session_get_cb", "session_new_cb", "session_remove_cb",
|
80
|
+
"tmp_ecdh_callback", "servername_cb", "npn_protocols",
|
81
|
+
"alpn_protocols", "alpn_select_cb",
|
82
|
+
"npn_select_cb"].map { |x| "@#{x}" }
|
83
|
+
|
84
|
+
# A callback invoked when DH parameters are required.
|
85
|
+
#
|
86
|
+
# The callback is invoked with the Session for the key exchange, an
|
87
|
+
# flag indicating the use of an export cipher and the keylength
|
88
|
+
# required.
|
89
|
+
#
|
90
|
+
# The callback must return an OpenSSL::PKey::DH instance of the correct
|
91
|
+
# key length.
|
92
|
+
|
93
|
+
attr_accessor :tmp_dh_callback
|
94
|
+
|
95
|
+
#if ExtConfig::HAVE_TLSEXT_HOST_NAME
|
96
|
+
# A callback invoked at connect time to distinguish between multiple
|
97
|
+
# server names.
|
98
|
+
#
|
99
|
+
# The callback is invoked with an SSLSocket and a server name. The
|
100
|
+
# callback must return an SSLContext for the server name or nil.
|
101
|
+
attr_accessor :servername_cb
|
102
|
+
#end
|
103
|
+
|
104
|
+
# call-seq:
|
105
|
+
# SSLContext.new => ctx
|
106
|
+
# SSLContext.new(:TLSv1) => ctx
|
107
|
+
# SSLContext.new("SSLv23_client") => ctx
|
108
|
+
#
|
109
|
+
# You can get a list of valid methods with OpenSSL::SSL::SSLContext::METHODS
|
110
|
+
def initialize(version = nil)
|
111
|
+
INIT_VARS.each { |v| instance_variable_set v, nil }
|
112
|
+
self.options = self.options | OpenSSL::SSL::OP_ALL
|
113
|
+
return unless version
|
114
|
+
self.ssl_version = version
|
115
|
+
end unless defined? JRUBY_VERSION # JRuby: handled in "native" Java
|
116
|
+
|
117
|
+
##
|
118
|
+
# Sets the parameters for this SSL context to the values in +params+.
|
119
|
+
# The keys in +params+ must be assignment methods on SSLContext.
|
120
|
+
#
|
121
|
+
# If the verify_mode is not VERIFY_NONE and ca_file, ca_path and
|
122
|
+
# cert_store are not set then the system default certificate store is
|
123
|
+
# used.
|
124
|
+
|
125
|
+
def set_params(params={})
|
126
|
+
params = DEFAULT_PARAMS.merge(params)
|
127
|
+
params.each{|name, value| self.__send__("#{name}=", value) }
|
128
|
+
if self.verify_mode != OpenSSL::SSL::VERIFY_NONE
|
129
|
+
unless self.ca_file or self.ca_path or self.cert_store
|
130
|
+
self.cert_store = DEFAULT_CERT_STORE
|
131
|
+
end
|
132
|
+
end
|
133
|
+
return params
|
134
|
+
end unless method_defined? :set_params # JRuby: hooked up in "native" Java
|
135
|
+
end
|
136
|
+
|
137
|
+
module SocketForwarder
|
138
|
+
def addr
|
139
|
+
to_io.addr
|
140
|
+
end
|
141
|
+
|
142
|
+
def peeraddr
|
143
|
+
to_io.peeraddr
|
144
|
+
end
|
145
|
+
|
146
|
+
def setsockopt(level, optname, optval)
|
147
|
+
to_io.setsockopt(level, optname, optval)
|
148
|
+
end
|
149
|
+
|
150
|
+
def getsockopt(level, optname)
|
151
|
+
to_io.getsockopt(level, optname)
|
152
|
+
end
|
153
|
+
|
154
|
+
def fcntl(*args)
|
155
|
+
to_io.fcntl(*args)
|
156
|
+
end
|
157
|
+
|
158
|
+
def closed?
|
159
|
+
to_io.closed?
|
160
|
+
end
|
161
|
+
|
162
|
+
def do_not_reverse_lookup=(flag)
|
163
|
+
to_io.do_not_reverse_lookup = flag
|
164
|
+
end
|
165
|
+
end unless const_defined? :SocketForwarder # JRuby: hooked up in "native" Java
|
166
|
+
|
167
|
+
def verify_certificate_identity(cert, hostname)
|
168
|
+
should_verify_common_name = true
|
169
|
+
cert.extensions.each{|ext|
|
170
|
+
next if ext.oid != "subjectAltName"
|
171
|
+
ext.value.split(/,\s+/).each { |general_name|
|
172
|
+
#case san.tag
|
173
|
+
# MRI 2.2.3 (JRuby parses ASN.1 differently)
|
174
|
+
#when 2 # dNSName in GeneralName (RFC5280)
|
175
|
+
if /\ADNS:(.*)/ =~ general_name
|
176
|
+
should_verify_common_name = false
|
177
|
+
return true if verify_hostname(hostname, $1)
|
178
|
+
# MRI 2.2.3 (JRuby parses ASN.1 differently)
|
179
|
+
#when 7 # iPAddress in GeneralName (RFC5280)
|
180
|
+
elsif /\AIP(?: Address)?:(.*)/ =~ general_name
|
181
|
+
should_verify_common_name = false
|
182
|
+
return true if $1 == hostname
|
183
|
+
# NOTE: bellow logic makes little sense JRuby reads exts differently
|
184
|
+
# follows GENERAL_NAME_print() in x509v3/v3_alt.c
|
185
|
+
#if san.value.size == 4
|
186
|
+
# return true if san.value.unpack('C*').join('.') == hostname
|
187
|
+
#elsif san.value.size == 16
|
188
|
+
# return true if san.value.unpack('n*').map { |e| sprintf("%X", e) }.join(':') == hostname
|
189
|
+
#end
|
190
|
+
end
|
191
|
+
}
|
192
|
+
}
|
193
|
+
if should_verify_common_name
|
194
|
+
cert.subject.to_a.each{|oid, value|
|
195
|
+
if oid == "CN"
|
196
|
+
return true if verify_hostname(hostname, value)
|
197
|
+
end
|
198
|
+
}
|
199
|
+
end
|
200
|
+
return false
|
201
|
+
end
|
202
|
+
module_function :verify_certificate_identity
|
203
|
+
|
204
|
+
def verify_hostname(hostname, san) # :nodoc:
|
205
|
+
# RFC 5280, IA5String is limited to the set of ASCII characters
|
206
|
+
return false unless san.ascii_only?
|
207
|
+
return false unless hostname.ascii_only?
|
208
|
+
|
209
|
+
# See RFC 6125, section 6.4.1
|
210
|
+
# Matching is case-insensitive.
|
211
|
+
san_parts = san.downcase.split(".")
|
212
|
+
|
213
|
+
# TODO: this behavior should probably be more strict
|
214
|
+
return san == hostname if san_parts.size < 2
|
215
|
+
|
216
|
+
# Matching is case-insensitive.
|
217
|
+
host_parts = hostname.downcase.split(".")
|
218
|
+
|
219
|
+
# RFC 6125, section 6.4.3, subitem 2.
|
220
|
+
# If the wildcard character is the only character of the left-most
|
221
|
+
# label in the presented identifier, the client SHOULD NOT compare
|
222
|
+
# against anything but the left-most label of the reference
|
223
|
+
# identifier (e.g., *.example.com would match foo.example.com but
|
224
|
+
# not bar.foo.example.com or example.com).
|
225
|
+
return false unless san_parts.size == host_parts.size
|
226
|
+
|
227
|
+
# RFC 6125, section 6.4.3, subitem 1.
|
228
|
+
# The client SHOULD NOT attempt to match a presented identifier in
|
229
|
+
# which the wildcard character comprises a label other than the
|
230
|
+
# left-most label (e.g., do not match bar.*.example.net).
|
231
|
+
return false unless verify_wildcard(host_parts.shift, san_parts.shift)
|
232
|
+
|
233
|
+
san_parts.join(".") == host_parts.join(".")
|
234
|
+
end
|
235
|
+
module_function :verify_hostname
|
236
|
+
|
237
|
+
def verify_wildcard(domain_component, san_component) # :nodoc:
|
238
|
+
parts = san_component.split("*", -1)
|
239
|
+
|
240
|
+
return false if parts.size > 2
|
241
|
+
return san_component == domain_component if parts.size == 1
|
242
|
+
|
243
|
+
# RFC 6125, section 6.4.3, subitem 3.
|
244
|
+
# The client SHOULD NOT attempt to match a presented identifier
|
245
|
+
# where the wildcard character is embedded within an A-label or
|
246
|
+
# U-label of an internationalized domain name.
|
247
|
+
return false if domain_component.start_with?("xn--") && san_component != "*"
|
248
|
+
|
249
|
+
parts[0].length + parts[1].length < domain_component.length &&
|
250
|
+
domain_component.start_with?(parts[0]) &&
|
251
|
+
domain_component.end_with?(parts[1])
|
252
|
+
end
|
253
|
+
module_function :verify_wildcard
|
254
|
+
|
255
|
+
class SSLSocket
|
256
|
+
include Buffering
|
257
|
+
include SocketForwarder
|
258
|
+
|
259
|
+
if ExtConfig::OPENSSL_NO_SOCK
|
260
|
+
def initialize(io, ctx = nil); raise NotImplementedError; end
|
261
|
+
else
|
262
|
+
if ExtConfig::HAVE_TLSEXT_HOST_NAME
|
263
|
+
attr_accessor :hostname
|
264
|
+
end
|
265
|
+
|
266
|
+
attr_reader :io, :context
|
267
|
+
attr_accessor :sync_close
|
268
|
+
alias :to_io :io
|
269
|
+
|
270
|
+
# call-seq:
|
271
|
+
# SSLSocket.new(io) => aSSLSocket
|
272
|
+
# SSLSocket.new(io, ctx) => aSSLSocket
|
273
|
+
#
|
274
|
+
# Creates a new SSL socket from +io+ which must be a real ruby object (not an
|
275
|
+
# IO-like object that responds to read/write).
|
276
|
+
#
|
277
|
+
# If +ctx+ is provided the SSL Sockets initial params will be taken from
|
278
|
+
# the context.
|
279
|
+
#
|
280
|
+
# The OpenSSL::Buffering module provides additional IO methods.
|
281
|
+
#
|
282
|
+
# This method will freeze the SSLContext if one is provided;
|
283
|
+
# however, session management is still allowed in the frozen SSLContext.
|
284
|
+
|
285
|
+
def initialize(io, context = OpenSSL::SSL::SSLContext.new)
|
286
|
+
@io = io
|
287
|
+
@context = context
|
288
|
+
@sync_close = false
|
289
|
+
@hostname = nil
|
290
|
+
@io.nonblock = true if @io.respond_to?(:nonblock=)
|
291
|
+
context.setup
|
292
|
+
super()
|
293
|
+
end
|
294
|
+
end unless defined? JRUBY_VERSION # JRuby: handled in "native" Java
|
295
|
+
|
296
|
+
# call-seq:
|
297
|
+
# ssl.sysclose => nil
|
298
|
+
#
|
299
|
+
# Shuts down the SSL connection and prepares it for another connection.
|
300
|
+
def sysclose
|
301
|
+
return if closed?
|
302
|
+
stop
|
303
|
+
io.close if sync_close
|
304
|
+
end unless defined? JRUBY_VERSION # JRuby: handled in "native" Java
|
305
|
+
|
306
|
+
##
|
307
|
+
# Perform hostname verification after an SSL connection is established
|
308
|
+
#
|
309
|
+
# This method MUST be called after calling #connect to ensure that the
|
310
|
+
# hostname of a remote peer has been verified.
|
311
|
+
def post_connection_check(hostname)
|
312
|
+
if peer_cert.nil?
|
313
|
+
msg = "Peer verification enabled, but no certificate received."
|
314
|
+
if using_anon_cipher?
|
315
|
+
msg += " Anonymous cipher suite #{cipher[0]} was negotiated. Anonymous suites must be disabled to use peer verification."
|
316
|
+
end
|
317
|
+
raise SSLError, msg
|
318
|
+
end
|
319
|
+
|
320
|
+
unless OpenSSL::SSL.verify_certificate_identity(peer_cert, hostname)
|
321
|
+
raise SSLError, "hostname \"#{hostname}\" does not match the server certificate"
|
322
|
+
end
|
323
|
+
return true
|
324
|
+
end
|
325
|
+
|
326
|
+
#def session
|
327
|
+
# SSL::Session.new(self)
|
328
|
+
#rescue SSL::Session::SessionError
|
329
|
+
# nil
|
330
|
+
#end
|
331
|
+
|
332
|
+
private
|
333
|
+
|
334
|
+
def using_anon_cipher?
|
335
|
+
ctx = OpenSSL::SSL::SSLContext.new
|
336
|
+
ctx.ciphers = "aNULL"
|
337
|
+
ctx.ciphers.include?(cipher)
|
338
|
+
end
|
339
|
+
|
340
|
+
def client_cert_cb
|
341
|
+
@context.client_cert_cb
|
342
|
+
end
|
343
|
+
|
344
|
+
def tmp_dh_callback
|
345
|
+
@context.tmp_dh_callback || OpenSSL::PKey::DEFAULT_TMP_DH_CALLBACK
|
346
|
+
end
|
347
|
+
|
348
|
+
def tmp_ecdh_callback
|
349
|
+
@context.tmp_ecdh_callback
|
350
|
+
end
|
351
|
+
|
352
|
+
def session_new_cb
|
353
|
+
@context.session_new_cb
|
354
|
+
end
|
355
|
+
|
356
|
+
def session_get_cb
|
357
|
+
@context.session_get_cb
|
358
|
+
end
|
359
|
+
end
|
360
|
+
|
361
|
+
##
|
362
|
+
# SSLServer represents a TCP/IP server socket with Secure Sockets Layer.
|
363
|
+
class SSLServer
|
364
|
+
include SocketForwarder
|
365
|
+
# When true then #accept works exactly the same as TCPServer#accept
|
366
|
+
attr_accessor :start_immediately
|
367
|
+
|
368
|
+
# Creates a new instance of SSLServer.
|
369
|
+
# * +srv+ is an instance of TCPServer.
|
370
|
+
# * +ctx+ is an instance of OpenSSL::SSL::SSLContext.
|
371
|
+
def initialize(svr, ctx)
|
372
|
+
@svr = svr
|
373
|
+
@ctx = ctx
|
374
|
+
unless ctx.session_id_context
|
375
|
+
# see #6137 - session id may not exceed 32 bytes
|
376
|
+
prng = ::Random.new($0.hash)
|
377
|
+
session_id = prng.bytes(16).unpack('H*')[0]
|
378
|
+
@ctx.session_id_context = session_id
|
379
|
+
end
|
380
|
+
@start_immediately = true
|
381
|
+
end
|
382
|
+
|
383
|
+
# Returns the TCPServer passed to the SSLServer when initialized.
|
384
|
+
def to_io
|
385
|
+
@svr
|
386
|
+
end
|
387
|
+
|
388
|
+
# See TCPServer#listen for details.
|
389
|
+
def listen(backlog=5)
|
390
|
+
@svr.listen(backlog)
|
391
|
+
end
|
392
|
+
|
393
|
+
# See BasicSocket#shutdown for details.
|
394
|
+
def shutdown(how=Socket::SHUT_RDWR)
|
395
|
+
@svr.shutdown(how)
|
396
|
+
end
|
397
|
+
|
398
|
+
# Works similar to TCPServer#accept.
|
399
|
+
def accept
|
400
|
+
# Socket#accept returns [socket, addrinfo].
|
401
|
+
# TCPServer#accept returns a socket.
|
402
|
+
# The following comma strips addrinfo.
|
403
|
+
sock, = @svr.accept
|
404
|
+
begin
|
405
|
+
ssl = OpenSSL::SSL::SSLSocket.new(sock, @ctx)
|
406
|
+
ssl.sync_close = true
|
407
|
+
ssl.accept if @start_immediately
|
408
|
+
ssl
|
409
|
+
rescue Exception => ex
|
410
|
+
if ssl
|
411
|
+
ssl.close
|
412
|
+
else
|
413
|
+
sock.close
|
414
|
+
end
|
415
|
+
raise ex
|
416
|
+
end
|
417
|
+
end
|
418
|
+
|
419
|
+
# See IO#close for details.
|
420
|
+
def close
|
421
|
+
@svr.close
|
422
|
+
end
|
423
|
+
end
|
424
|
+
end
|
425
|
+
end
|