openssl 2.0.0.beta.1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of openssl might be problematic. Click here for more details.

Files changed (71) hide show
  1. checksums.yaml +7 -0
  2. data/BSDL +22 -0
  3. data/CONTRIBUTING.md +130 -0
  4. data/History.md +118 -0
  5. data/LICENSE.txt +56 -0
  6. data/README.md +70 -0
  7. data/ext/openssl/deprecation.rb +26 -0
  8. data/ext/openssl/extconf.rb +158 -0
  9. data/ext/openssl/openssl_missing.c +173 -0
  10. data/ext/openssl/openssl_missing.h +244 -0
  11. data/ext/openssl/ossl.c +1201 -0
  12. data/ext/openssl/ossl.h +222 -0
  13. data/ext/openssl/ossl_asn1.c +1992 -0
  14. data/ext/openssl/ossl_asn1.h +66 -0
  15. data/ext/openssl/ossl_bio.c +87 -0
  16. data/ext/openssl/ossl_bio.h +19 -0
  17. data/ext/openssl/ossl_bn.c +1153 -0
  18. data/ext/openssl/ossl_bn.h +23 -0
  19. data/ext/openssl/ossl_cipher.c +1085 -0
  20. data/ext/openssl/ossl_cipher.h +20 -0
  21. data/ext/openssl/ossl_config.c +89 -0
  22. data/ext/openssl/ossl_config.h +19 -0
  23. data/ext/openssl/ossl_digest.c +453 -0
  24. data/ext/openssl/ossl_digest.h +20 -0
  25. data/ext/openssl/ossl_engine.c +580 -0
  26. data/ext/openssl/ossl_engine.h +19 -0
  27. data/ext/openssl/ossl_hmac.c +398 -0
  28. data/ext/openssl/ossl_hmac.h +18 -0
  29. data/ext/openssl/ossl_ns_spki.c +406 -0
  30. data/ext/openssl/ossl_ns_spki.h +19 -0
  31. data/ext/openssl/ossl_ocsp.c +2013 -0
  32. data/ext/openssl/ossl_ocsp.h +23 -0
  33. data/ext/openssl/ossl_pkcs12.c +259 -0
  34. data/ext/openssl/ossl_pkcs12.h +13 -0
  35. data/ext/openssl/ossl_pkcs5.c +180 -0
  36. data/ext/openssl/ossl_pkcs5.h +6 -0
  37. data/ext/openssl/ossl_pkcs7.c +1125 -0
  38. data/ext/openssl/ossl_pkcs7.h +20 -0
  39. data/ext/openssl/ossl_pkey.c +435 -0
  40. data/ext/openssl/ossl_pkey.h +245 -0
  41. data/ext/openssl/ossl_pkey_dh.c +650 -0
  42. data/ext/openssl/ossl_pkey_dsa.c +672 -0
  43. data/ext/openssl/ossl_pkey_ec.c +1899 -0
  44. data/ext/openssl/ossl_pkey_rsa.c +768 -0
  45. data/ext/openssl/ossl_rand.c +238 -0
  46. data/ext/openssl/ossl_rand.h +18 -0
  47. data/ext/openssl/ossl_ssl.c +2679 -0
  48. data/ext/openssl/ossl_ssl.h +41 -0
  49. data/ext/openssl/ossl_ssl_session.c +352 -0
  50. data/ext/openssl/ossl_version.h +15 -0
  51. data/ext/openssl/ossl_x509.c +186 -0
  52. data/ext/openssl/ossl_x509.h +119 -0
  53. data/ext/openssl/ossl_x509attr.c +328 -0
  54. data/ext/openssl/ossl_x509cert.c +860 -0
  55. data/ext/openssl/ossl_x509crl.c +565 -0
  56. data/ext/openssl/ossl_x509ext.c +480 -0
  57. data/ext/openssl/ossl_x509name.c +547 -0
  58. data/ext/openssl/ossl_x509req.c +492 -0
  59. data/ext/openssl/ossl_x509revoked.c +279 -0
  60. data/ext/openssl/ossl_x509store.c +846 -0
  61. data/ext/openssl/ruby_missing.h +32 -0
  62. data/lib/openssl.rb +21 -0
  63. data/lib/openssl/bn.rb +39 -0
  64. data/lib/openssl/buffering.rb +451 -0
  65. data/lib/openssl/cipher.rb +67 -0
  66. data/lib/openssl/config.rb +473 -0
  67. data/lib/openssl/digest.rb +78 -0
  68. data/lib/openssl/pkey.rb +44 -0
  69. data/lib/openssl/ssl.rb +416 -0
  70. data/lib/openssl/x509.rb +176 -0
  71. metadata +178 -0
@@ -0,0 +1,78 @@
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
+
18
+ alg = %w(MD2 MD4 MD5 MDC2 RIPEMD160 SHA1)
19
+ if OPENSSL_VERSION_NUMBER < 0x10100000
20
+ alg += %w(DSS DSS1 SHA)
21
+ end
22
+ if OPENSSL_VERSION_NUMBER > 0x00908000
23
+ alg += %w(SHA224 SHA256 SHA384 SHA512)
24
+ end
25
+
26
+ # Return the +data+ hash computed with +name+ Digest. +name+ is either the
27
+ # long name or short name of a supported digest algorithm.
28
+ #
29
+ # === Examples
30
+ #
31
+ # OpenSSL::Digest.digest("SHA256", "abc")
32
+ #
33
+ # which is equivalent to:
34
+ #
35
+ # OpenSSL::Digest::SHA256.digest("abc")
36
+
37
+ def self.digest(name, data)
38
+ super(data, name)
39
+ end
40
+
41
+ alg.each{|name|
42
+ klass = Class.new(self) {
43
+ define_method(:initialize, ->(data = nil) {super(name, data)})
44
+ }
45
+ singleton = (class << klass; self; end)
46
+ singleton.class_eval{
47
+ define_method(:digest){|data| new.digest(data) }
48
+ define_method(:hexdigest){|data| new.hexdigest(data) }
49
+ }
50
+ const_set(name, klass)
51
+ }
52
+
53
+ # Deprecated.
54
+ #
55
+ # This class is only provided for backwards compatibility.
56
+ # Use OpenSSL::Digest instead.
57
+ class Digest < Digest; end # :nodoc:
58
+ deprecate_constant :Digest
59
+
60
+ end # Digest
61
+
62
+ # Returns a Digest subclass by +name+.
63
+ #
64
+ # require 'openssl'
65
+ #
66
+ # OpenSSL::Digest("MD5")
67
+ # # => OpenSSL::Digest::MD5
68
+ #
69
+ # Digest("Foo")
70
+ # # => NameError: wrong constant name Foo
71
+
72
+ def Digest(name)
73
+ OpenSSL::Digest.const_get(name)
74
+ end
75
+
76
+ module_function :Digest
77
+
78
+ end # OpenSSL
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: false
2
+ module OpenSSL
3
+ module PKey
4
+ if defined?(OpenSSL::PKey::DH)
5
+
6
+ class DH
7
+ # :nodoc:
8
+ DEFAULT_1024 = new <<-_end_of_pem_
9
+ -----BEGIN DH PARAMETERS-----
10
+ MIGHAoGBAJ0lOVy0VIr/JebWn0zDwY2h+rqITFOpdNr6ugsgvkDXuucdcChhYExJ
11
+ AV/ZD2AWPbrTqV76mGRgJg4EddgT1zG0jq3rnFdMj2XzkBYx3BVvfR0Arnby0RHR
12
+ T4h7KZ/2zmjvV+eF8kBUHBJAojUlzxKj4QeO2x20FP9X5xmNUXeDAgEC
13
+ -----END DH PARAMETERS-----
14
+ _end_of_pem_
15
+
16
+ # :nodoc:
17
+ DEFAULT_2048 = new <<-_end_of_pem_
18
+ -----BEGIN DH PARAMETERS-----
19
+ MIIBCAKCAQEA7E6kBrYiyvmKAMzQ7i8WvwVk9Y/+f8S7sCTN712KkK3cqd1jhJDY
20
+ JbrYeNV3kUIKhPxWHhObHKpD1R84UpL+s2b55+iMd6GmL7OYmNIT/FccKhTcveab
21
+ VBmZT86BZKYyf45hUF9FOuUM9xPzuK3Vd8oJQvfYMCd7LPC0taAEljQLR4Edf8E6
22
+ YoaOffgTf5qxiwkjnlVZQc3whgnEt9FpVMvQ9eknyeGB5KHfayAc3+hUAvI3/Cr3
23
+ 1bNveX5wInh5GDx1FGhKBZ+s1H+aedudCm7sCgRwv8lKWYGiHzObSma8A86KG+MD
24
+ 7Lo5JquQ3DlBodj3IDyPrxIv96lvRPFtAwIBAg==
25
+ -----END DH PARAMETERS-----
26
+ _end_of_pem_
27
+ end
28
+
29
+ # :nodoc:
30
+ DEFAULT_TMP_DH_CALLBACK = lambda { |ctx, is_export, keylen|
31
+ warn "using default DH parameters." if $VERBOSE
32
+ case keylen
33
+ when 1024 then OpenSSL::PKey::DH::DEFAULT_1024
34
+ when 2048 then OpenSSL::PKey::DH::DEFAULT_2048
35
+ else
36
+ nil
37
+ end
38
+ }
39
+
40
+ else
41
+ DEFAULT_TMP_DH_CALLBACK = nil
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,416 @@
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
+ # :nodoc:
20
+ DEFAULT_PARAMS = {
21
+ :ssl_version => "SSLv23",
22
+ :verify_mode => OpenSSL::SSL::VERIFY_PEER,
23
+ :verify_hostname => true,
24
+ :options => -> {
25
+ opts = OpenSSL::SSL::OP_ALL
26
+ opts &= ~OpenSSL::SSL::OP_DONT_INSERT_EMPTY_FRAGMENTS
27
+ opts |= OpenSSL::SSL::OP_NO_COMPRESSION if defined?(OpenSSL::SSL::OP_NO_COMPRESSION)
28
+ opts |= OpenSSL::SSL::OP_NO_SSLv2 | OpenSSL::SSL::OP_NO_SSLv3
29
+ opts
30
+ }.call
31
+ }
32
+
33
+ if !(OpenSSL::OPENSSL_VERSION.start_with?("OpenSSL") &&
34
+ OpenSSL::OPENSSL_VERSION_NUMBER >= 0x10100000)
35
+ DEFAULT_PARAMS.merge!(
36
+ ciphers: %w{
37
+ ECDHE-ECDSA-AES128-GCM-SHA256
38
+ ECDHE-RSA-AES128-GCM-SHA256
39
+ ECDHE-ECDSA-AES256-GCM-SHA384
40
+ ECDHE-RSA-AES256-GCM-SHA384
41
+ DHE-RSA-AES128-GCM-SHA256
42
+ DHE-DSS-AES128-GCM-SHA256
43
+ DHE-RSA-AES256-GCM-SHA384
44
+ DHE-DSS-AES256-GCM-SHA384
45
+ ECDHE-ECDSA-AES128-SHA256
46
+ ECDHE-RSA-AES128-SHA256
47
+ ECDHE-ECDSA-AES128-SHA
48
+ ECDHE-RSA-AES128-SHA
49
+ ECDHE-ECDSA-AES256-SHA384
50
+ ECDHE-RSA-AES256-SHA384
51
+ ECDHE-ECDSA-AES256-SHA
52
+ ECDHE-RSA-AES256-SHA
53
+ DHE-RSA-AES128-SHA256
54
+ DHE-RSA-AES256-SHA256
55
+ DHE-RSA-AES128-SHA
56
+ DHE-RSA-AES256-SHA
57
+ DHE-DSS-AES128-SHA256
58
+ DHE-DSS-AES256-SHA256
59
+ DHE-DSS-AES128-SHA
60
+ DHE-DSS-AES256-SHA
61
+ AES128-GCM-SHA256
62
+ AES256-GCM-SHA384
63
+ AES128-SHA256
64
+ AES256-SHA256
65
+ AES128-SHA
66
+ AES256-SHA
67
+ }.join(":"),
68
+ )
69
+ end
70
+
71
+ # :nodoc:
72
+ DEFAULT_CERT_STORE = OpenSSL::X509::Store.new
73
+ DEFAULT_CERT_STORE.set_default_paths
74
+ DEFAULT_CERT_STORE.flags = OpenSSL::X509::V_FLAG_CRL_CHECK_ALL
75
+
76
+ # :nodoc:
77
+ INIT_VARS = ["cert", "key", "client_ca", "ca_file", "ca_path",
78
+ "timeout", "verify_mode", "verify_depth", "renegotiation_cb",
79
+ "verify_callback", "cert_store", "extra_chain_cert",
80
+ "client_cert_cb", "session_id_context", "tmp_dh_callback",
81
+ "session_get_cb", "session_new_cb", "session_remove_cb",
82
+ "tmp_ecdh_callback", "servername_cb", "npn_protocols",
83
+ "alpn_protocols", "alpn_select_cb",
84
+ "npn_select_cb", "verify_hostname"].map { |x| "@#{x}" }
85
+
86
+ # A callback invoked when DH parameters are required.
87
+ #
88
+ # The callback is invoked with the Session for the key exchange, an
89
+ # flag indicating the use of an export cipher and the keylength
90
+ # required.
91
+ #
92
+ # The callback must return an OpenSSL::PKey::DH instance of the correct
93
+ # key length.
94
+
95
+ attr_accessor :tmp_dh_callback
96
+
97
+ if ExtConfig::HAVE_TLSEXT_HOST_NAME
98
+ # A callback invoked at connect time to distinguish between multiple
99
+ # server names.
100
+ #
101
+ # The callback is invoked with an SSLSocket and a server name. The
102
+ # callback must return an SSLContext for the server name or nil.
103
+ attr_accessor :servername_cb
104
+ end
105
+
106
+ # call-seq:
107
+ # SSLContext.new => ctx
108
+ # SSLContext.new(:TLSv1) => ctx
109
+ # SSLContext.new("SSLv23_client") => ctx
110
+ #
111
+ # You can get a list of valid methods with OpenSSL::SSL::SSLContext::METHODS
112
+ def initialize(version = nil)
113
+ INIT_VARS.each { |v| instance_variable_set v, nil }
114
+ self.options = self.options | OpenSSL::SSL::OP_ALL
115
+ return unless version
116
+ self.ssl_version = version
117
+ end
118
+
119
+ ##
120
+ # call-seq:
121
+ # ctx.set_params(params = {}) -> params
122
+ #
123
+ # Sets saner defaults optimized for the use with HTTP-like protocols.
124
+ #
125
+ # If a Hash +params+ is given, the parameters are overridden with it.
126
+ # The keys in +params+ must be assignment methods on SSLContext.
127
+ #
128
+ # If the verify_mode is not VERIFY_NONE and ca_file, ca_path and
129
+ # cert_store are not set then the system default certificate store is
130
+ # used.
131
+ def set_params(params={})
132
+ params = DEFAULT_PARAMS.merge(params)
133
+ params.each{|name, value| self.__send__("#{name}=", value) }
134
+ if self.verify_mode != OpenSSL::SSL::VERIFY_NONE
135
+ unless self.ca_file or self.ca_path or self.cert_store
136
+ self.cert_store = DEFAULT_CERT_STORE
137
+ end
138
+ end
139
+ return params
140
+ end
141
+ end
142
+
143
+ module SocketForwarder
144
+ def addr
145
+ to_io.addr
146
+ end
147
+
148
+ def peeraddr
149
+ to_io.peeraddr
150
+ end
151
+
152
+ def setsockopt(level, optname, optval)
153
+ to_io.setsockopt(level, optname, optval)
154
+ end
155
+
156
+ def getsockopt(level, optname)
157
+ to_io.getsockopt(level, optname)
158
+ end
159
+
160
+ def fcntl(*args)
161
+ to_io.fcntl(*args)
162
+ end
163
+
164
+ def closed?
165
+ to_io.closed?
166
+ end
167
+
168
+ def do_not_reverse_lookup=(flag)
169
+ to_io.do_not_reverse_lookup = flag
170
+ end
171
+ end
172
+
173
+ def verify_certificate_identity(cert, hostname)
174
+ should_verify_common_name = true
175
+ cert.extensions.each{|ext|
176
+ next if ext.oid != "subjectAltName"
177
+ ostr = OpenSSL::ASN1.decode(ext.to_der).value.last
178
+ sequence = OpenSSL::ASN1.decode(ostr.value)
179
+ sequence.value.each{|san|
180
+ case san.tag
181
+ when 2 # dNSName in GeneralName (RFC5280)
182
+ should_verify_common_name = false
183
+ return true if verify_hostname(hostname, san.value)
184
+ when 7 # iPAddress in GeneralName (RFC5280)
185
+ should_verify_common_name = false
186
+ # follows GENERAL_NAME_print() in x509v3/v3_alt.c
187
+ if san.value.size == 4
188
+ return true if san.value.unpack('C*').join('.') == hostname
189
+ elsif san.value.size == 16
190
+ return true if san.value.unpack('n*').map { |e| sprintf("%X", e) }.join(':') == hostname
191
+ end
192
+ end
193
+ }
194
+ }
195
+ if should_verify_common_name
196
+ cert.subject.to_a.each{|oid, value|
197
+ if oid == "CN"
198
+ return true if verify_hostname(hostname, value)
199
+ end
200
+ }
201
+ end
202
+ return false
203
+ end
204
+ module_function :verify_certificate_identity
205
+
206
+ def verify_hostname(hostname, san) # :nodoc:
207
+ # RFC 5280, IA5String is limited to the set of ASCII characters
208
+ return false unless san.ascii_only?
209
+ return false unless hostname.ascii_only?
210
+
211
+ # See RFC 6125, section 6.4.1
212
+ # Matching is case-insensitive.
213
+ san_parts = san.downcase.split(".")
214
+
215
+ # TODO: this behavior should probably be more strict
216
+ return san == hostname if san_parts.size < 2
217
+
218
+ # Matching is case-insensitive.
219
+ host_parts = hostname.downcase.split(".")
220
+
221
+ # RFC 6125, section 6.4.3, subitem 2.
222
+ # If the wildcard character is the only character of the left-most
223
+ # label in the presented identifier, the client SHOULD NOT compare
224
+ # against anything but the left-most label of the reference
225
+ # identifier (e.g., *.example.com would match foo.example.com but
226
+ # not bar.foo.example.com or example.com).
227
+ return false unless san_parts.size == host_parts.size
228
+
229
+ # RFC 6125, section 6.4.3, subitem 1.
230
+ # The client SHOULD NOT attempt to match a presented identifier in
231
+ # which the wildcard character comprises a label other than the
232
+ # left-most label (e.g., do not match bar.*.example.net).
233
+ return false unless verify_wildcard(host_parts.shift, san_parts.shift)
234
+
235
+ san_parts.join(".") == host_parts.join(".")
236
+ end
237
+ module_function :verify_hostname
238
+
239
+ def verify_wildcard(domain_component, san_component) # :nodoc:
240
+ parts = san_component.split("*", -1)
241
+
242
+ return false if parts.size > 2
243
+ return san_component == domain_component if parts.size == 1
244
+
245
+ # RFC 6125, section 6.4.3, subitem 3.
246
+ # The client SHOULD NOT attempt to match a presented identifier
247
+ # where the wildcard character is embedded within an A-label or
248
+ # U-label of an internationalized domain name.
249
+ return false if domain_component.start_with?("xn--") && san_component != "*"
250
+
251
+ parts[0].length + parts[1].length < domain_component.length &&
252
+ domain_component.start_with?(parts[0]) &&
253
+ domain_component.end_with?(parts[1])
254
+ end
255
+ module_function :verify_wildcard
256
+
257
+ class SSLSocket
258
+ include Buffering
259
+ include SocketForwarder
260
+
261
+ if ExtConfig::HAVE_TLSEXT_HOST_NAME
262
+ attr_reader :hostname
263
+ end
264
+
265
+ # The underlying IO object.
266
+ attr_reader :io
267
+ alias :to_io :io
268
+
269
+ # The SSLContext object used in this connection.
270
+ attr_reader :context
271
+
272
+ # Whether to close the underlying socket as well, when the SSL/TLS
273
+ # connection is shut down. This defaults to +false+.
274
+ attr_accessor :sync_close
275
+
276
+ # call-seq:
277
+ # ssl.sysclose => nil
278
+ #
279
+ # Sends "close notify" to the peer and tries to shut down the SSL
280
+ # connection gracefully.
281
+ #
282
+ # If sync_close is set to +true+, the underlying IO is also closed.
283
+ def sysclose
284
+ return if closed?
285
+ stop
286
+ io.close if sync_close
287
+ end
288
+
289
+ # call-seq:
290
+ # ssl.post_connection_check(hostname) -> true
291
+ #
292
+ # Perform hostname verification following RFC 6125.
293
+ #
294
+ # This method MUST be called after calling #connect to ensure that the
295
+ # hostname of a remote peer has been verified.
296
+ def post_connection_check(hostname)
297
+ if peer_cert.nil?
298
+ msg = "Peer verification enabled, but no certificate received."
299
+ if using_anon_cipher?
300
+ msg += " Anonymous cipher suite #{cipher[0]} was negotiated. " \
301
+ "Anonymous suites must be disabled to use peer verification."
302
+ end
303
+ raise SSLError, msg
304
+ end
305
+
306
+ unless OpenSSL::SSL.verify_certificate_identity(peer_cert, hostname)
307
+ raise SSLError, "hostname \"#{hostname}\" does not match the server certificate"
308
+ end
309
+ return true
310
+ end
311
+
312
+ # call-seq:
313
+ # ssl.session -> aSession
314
+ #
315
+ # Returns the SSLSession object currently used, or nil if the session is
316
+ # not established.
317
+ def session
318
+ SSL::Session.new(self)
319
+ rescue SSL::Session::SessionError
320
+ nil
321
+ end
322
+
323
+ private
324
+
325
+ def using_anon_cipher?
326
+ ctx = OpenSSL::SSL::SSLContext.new
327
+ ctx.ciphers = "aNULL"
328
+ ctx.ciphers.include?(cipher)
329
+ end
330
+
331
+ def client_cert_cb
332
+ @context.client_cert_cb
333
+ end
334
+
335
+ def tmp_dh_callback
336
+ @context.tmp_dh_callback || OpenSSL::PKey::DEFAULT_TMP_DH_CALLBACK
337
+ end
338
+
339
+ def tmp_ecdh_callback
340
+ @context.tmp_ecdh_callback
341
+ end
342
+
343
+ def session_new_cb
344
+ @context.session_new_cb
345
+ end
346
+
347
+ def session_get_cb
348
+ @context.session_get_cb
349
+ end
350
+ end
351
+
352
+ ##
353
+ # SSLServer represents a TCP/IP server socket with Secure Sockets Layer.
354
+ class SSLServer
355
+ include SocketForwarder
356
+ # When true then #accept works exactly the same as TCPServer#accept
357
+ attr_accessor :start_immediately
358
+
359
+ # Creates a new instance of SSLServer.
360
+ # * +srv+ is an instance of TCPServer.
361
+ # * +ctx+ is an instance of OpenSSL::SSL::SSLContext.
362
+ def initialize(svr, ctx)
363
+ @svr = svr
364
+ @ctx = ctx
365
+ unless ctx.session_id_context
366
+ # see #6137 - session id may not exceed 32 bytes
367
+ prng = ::Random.new($0.hash)
368
+ session_id = prng.bytes(16).unpack('H*')[0]
369
+ @ctx.session_id_context = session_id
370
+ end
371
+ @start_immediately = true
372
+ end
373
+
374
+ # Returns the TCPServer passed to the SSLServer when initialized.
375
+ def to_io
376
+ @svr
377
+ end
378
+
379
+ # See TCPServer#listen for details.
380
+ def listen(backlog=5)
381
+ @svr.listen(backlog)
382
+ end
383
+
384
+ # See BasicSocket#shutdown for details.
385
+ def shutdown(how=Socket::SHUT_RDWR)
386
+ @svr.shutdown(how)
387
+ end
388
+
389
+ # Works similar to TCPServer#accept.
390
+ def accept
391
+ # Socket#accept returns [socket, addrinfo].
392
+ # TCPServer#accept returns a socket.
393
+ # The following comma strips addrinfo.
394
+ sock, = @svr.accept
395
+ begin
396
+ ssl = OpenSSL::SSL::SSLSocket.new(sock, @ctx)
397
+ ssl.sync_close = true
398
+ ssl.accept if @start_immediately
399
+ ssl
400
+ rescue Exception => ex
401
+ if ssl
402
+ ssl.close
403
+ else
404
+ sock.close
405
+ end
406
+ raise ex
407
+ end
408
+ end
409
+
410
+ # See IO#close for details.
411
+ def close
412
+ @svr.close
413
+ end
414
+ end
415
+ end
416
+ end