jruby-openssl 0.11.0-java → 0.12.1-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.
Files changed (59) hide show
  1. checksums.yaml +4 -4
  2. data/History.md +20 -0
  3. data/Mavenfile +21 -26
  4. data/README.md +3 -0
  5. data/Rakefile +21 -35
  6. data/lib/jopenssl/load.rb +0 -14
  7. data/lib/jopenssl/version.rb +1 -1
  8. data/lib/jopenssl.jar +0 -0
  9. data/lib/openssl/bn.rb +40 -9
  10. data/lib/openssl/buffering.rb +478 -9
  11. data/lib/openssl/cipher.rb +67 -9
  12. data/lib/openssl/config.rb +496 -12
  13. data/lib/openssl/digest.rb +73 -9
  14. data/lib/openssl/hmac.rb +13 -0
  15. data/lib/openssl/marshal.rb +30 -0
  16. data/lib/openssl/pkcs5.rb +3 -3
  17. data/lib/openssl/pkey.rb +42 -5
  18. data/lib/openssl/ssl.rb +543 -9
  19. data/lib/openssl/x509.rb +369 -9
  20. data/lib/openssl.rb +43 -1
  21. data/pom.xml +35 -127
  22. metadata +8 -42
  23. data/lib/jopenssl19/openssl/bn.rb +0 -29
  24. data/lib/jopenssl19/openssl/buffering.rb +0 -449
  25. data/lib/jopenssl19/openssl/cipher.rb +0 -28
  26. data/lib/jopenssl19/openssl/config.rb +0 -472
  27. data/lib/jopenssl19/openssl/digest.rb +0 -32
  28. data/lib/jopenssl19/openssl/ssl-internal.rb +0 -223
  29. data/lib/jopenssl19/openssl/ssl.rb +0 -2
  30. data/lib/jopenssl19/openssl/x509-internal.rb +0 -115
  31. data/lib/jopenssl19/openssl/x509.rb +0 -2
  32. data/lib/jopenssl19/openssl.rb +0 -22
  33. data/lib/jopenssl21/openssl/bn.rb +0 -28
  34. data/lib/jopenssl21/openssl/buffering.rb +0 -1
  35. data/lib/jopenssl21/openssl/cipher.rb +0 -1
  36. data/lib/jopenssl21/openssl/config.rb +0 -1
  37. data/lib/jopenssl21/openssl/digest.rb +0 -1
  38. data/lib/jopenssl21/openssl/ssl.rb +0 -1
  39. data/lib/jopenssl21/openssl/x509.rb +0 -119
  40. data/lib/jopenssl21/openssl.rb +0 -22
  41. data/lib/jopenssl22/openssl/bn.rb +0 -39
  42. data/lib/jopenssl22/openssl/buffering.rb +0 -456
  43. data/lib/jopenssl22/openssl/cipher.rb +0 -28
  44. data/lib/jopenssl22/openssl/config.rb +0 -313
  45. data/lib/jopenssl22/openssl/digest.rb +0 -54
  46. data/lib/jopenssl22/openssl/ssl.rb +0 -330
  47. data/lib/jopenssl22/openssl/x509.rb +0 -139
  48. data/lib/jopenssl22/openssl.rb +0 -22
  49. data/lib/jopenssl23/openssl/bn.rb +0 -38
  50. data/lib/jopenssl23/openssl/buffering.rb +0 -455
  51. data/lib/jopenssl23/openssl/cipher.rb +0 -25
  52. data/lib/jopenssl23/openssl/config.rb +0 -474
  53. data/lib/jopenssl23/openssl/digest.rb +0 -43
  54. data/lib/jopenssl23/openssl/pkey.rb +0 -25
  55. data/lib/jopenssl23/openssl/ssl.rb +0 -508
  56. data/lib/jopenssl23/openssl/x509.rb +0 -208
  57. data/lib/jopenssl23/openssl.rb +0 -19
  58. data/lib/openssl/ssl-internal.rb +0 -5
  59. data/lib/openssl/x509-internal.rb +0 -5
@@ -1,313 +0,0 @@
1
- =begin
2
- = Ruby-space definitions that completes C-space funcs for Config
3
-
4
- = Info
5
- Copyright (C) 2010 Hiroshi Nakamura <nahi@ruby-lang.org>
6
-
7
- = Licence
8
- This program is licenced under the same licence as Ruby.
9
- (See the file 'LICENCE'.)
10
-
11
- =end
12
-
13
- require 'stringio'
14
-
15
- module OpenSSL
16
- class Config
17
- include Enumerable
18
-
19
- class << self
20
- def parse(str)
21
- c = new()
22
- parse_config(StringIO.new(str)).each do |section, hash|
23
- c[section] = hash
24
- end
25
- c
26
- end
27
-
28
- alias load new
29
-
30
- def parse_config(io)
31
- begin
32
- parse_config_lines(io)
33
- rescue ConfigError => e
34
- e.message.replace("error in line #{io.lineno}: " + e.message)
35
- raise
36
- end
37
- end
38
-
39
- def get_key_string(data, section, key) # :nodoc:
40
- if v = data[section] && data[section][key]
41
- return v
42
- elsif section == 'ENV'
43
- if v = ENV[key]
44
- return v
45
- end
46
- end
47
- if v = data['default'] && data['default'][key]
48
- return v
49
- end
50
- end
51
-
52
- private
53
-
54
- def parse_config_lines(io)
55
- section = 'default'
56
- data = {section => {}}
57
- while definition = get_definition(io)
58
- definition = clear_comments(definition)
59
- next if definition.empty?
60
- if definition[0] == ?[
61
- if /\[([^\]]*)\]/ =~ definition
62
- section = $1.strip
63
- data[section] ||= {}
64
- else
65
- raise ConfigError, "missing close square bracket"
66
- end
67
- else
68
- if /\A([^:\s]*)(?:::([^:\s]*))?\s*=(.*)\z/ =~ definition
69
- if $2
70
- section = $1
71
- key = $2
72
- else
73
- key = $1
74
- end
75
- value = unescape_value(data, section, $3)
76
- (data[section] ||= {})[key] = value.strip
77
- else
78
- raise ConfigError, "missing equal sign"
79
- end
80
- end
81
- end
82
- data
83
- end
84
-
85
- # escape with backslash
86
- QUOTE_REGEXP_SQ = /\A([^'\\]*(?:\\.[^'\\]*)*)'/
87
- # escape with backslash and doubled dq
88
- QUOTE_REGEXP_DQ = /\A([^"\\]*(?:""[^"\\]*|\\.[^"\\]*)*)"/
89
- # escaped char map
90
- ESCAPE_MAP = {
91
- "r" => "\r",
92
- "n" => "\n",
93
- "b" => "\b",
94
- "t" => "\t",
95
- }
96
-
97
- def unescape_value(data, section, value)
98
- scanned = []
99
- while m = value.match(/['"\\$]/)
100
- scanned << m.pre_match
101
- c = m[0]
102
- value = m.post_match
103
- case c
104
- when "'"
105
- if m = value.match(QUOTE_REGEXP_SQ)
106
- scanned << m[1].gsub(/\\(.)/, '\\1')
107
- value = m.post_match
108
- else
109
- break
110
- end
111
- when '"'
112
- if m = value.match(QUOTE_REGEXP_DQ)
113
- scanned << m[1].gsub(/""/, '').gsub(/\\(.)/, '\\1')
114
- value = m.post_match
115
- else
116
- break
117
- end
118
- when "\\"
119
- c = value.slice!(0, 1)
120
- scanned << (ESCAPE_MAP[c] || c)
121
- when "$"
122
- ref, value = extract_reference(value)
123
- refsec = section
124
- if ref.index('::')
125
- refsec, ref = ref.split('::', 2)
126
- end
127
- if v = get_key_string(data, refsec, ref)
128
- scanned << v
129
- else
130
- raise ConfigError, "variable has no value"
131
- end
132
- else
133
- raise 'must not reaced'
134
- end
135
- end
136
- scanned << value
137
- scanned.join
138
- end
139
-
140
- def extract_reference(value)
141
- rest = ''
142
- if m = value.match(/\(([^)]*)\)|\{([^}]*)\}/)
143
- value = m[1] || m[2]
144
- rest = m.post_match
145
- elsif [?(, ?{].include?(value[0])
146
- raise ConfigError, "no close brace"
147
- end
148
- if m = value.match(/[a-zA-Z0-9_]*(?:::[a-zA-Z0-9_]*)?/)
149
- return m[0], m.post_match + rest
150
- else
151
- raise
152
- end
153
- end
154
-
155
- def clear_comments(line)
156
- # FCOMMENT
157
- if m = line.match(/\A([\t\n\f ]*);.*\z/)
158
- return m[1]
159
- end
160
- # COMMENT
161
- scanned = []
162
- while m = line.match(/[#'"\\]/)
163
- scanned << m.pre_match
164
- c = m[0]
165
- line = m.post_match
166
- case c
167
- when '#'
168
- line = nil
169
- break
170
- when "'", '"'
171
- regexp = (c == "'") ? QUOTE_REGEXP_SQ : QUOTE_REGEXP_DQ
172
- scanned << c
173
- if m = line.match(regexp)
174
- scanned << m[0]
175
- line = m.post_match
176
- else
177
- scanned << line
178
- line = nil
179
- break
180
- end
181
- when "\\"
182
- scanned << c
183
- scanned << line.slice!(0, 1)
184
- else
185
- raise 'must not reaced'
186
- end
187
- end
188
- scanned << line
189
- scanned.join
190
- end
191
-
192
- def get_definition(io)
193
- if line = get_line(io)
194
- while /[^\\]\\\z/ =~ line
195
- if extra = get_line(io)
196
- line += extra
197
- else
198
- break
199
- end
200
- end
201
- return line.strip
202
- end
203
- end
204
-
205
- def get_line(io)
206
- if line = io.gets
207
- line.gsub(/[\r\n]*/, '')
208
- end
209
- end
210
- end
211
-
212
- def initialize(filename = nil)
213
- @data = {}
214
- if filename
215
- File.open(filename.to_s) do |file|
216
- Config.parse_config(file).each do |section, hash|
217
- self[section] = hash
218
- end
219
- end
220
- end
221
- end
222
-
223
- def get_value(section, key)
224
- if section.nil?
225
- raise TypeError.new('nil not allowed')
226
- end
227
- section = 'default' if section.empty?
228
- get_key_string(section, key)
229
- end
230
-
231
- def value(arg1, arg2 = nil)
232
- warn('Config#value is deprecated; use Config#get_value')
233
- if arg2.nil?
234
- section, key = 'default', arg1
235
- else
236
- section, key = arg1, arg2
237
- end
238
- section ||= 'default'
239
- section = 'default' if section.empty?
240
- get_key_string(section, key)
241
- end
242
-
243
- def add_value(section, key, value)
244
- check_modify
245
- (@data[section] ||= {})[key] = value
246
- end
247
-
248
- def [](section)
249
- @data[section] || {}
250
- end
251
-
252
- def section(name)
253
- warn('Config#section is deprecated; use Config#[]')
254
- @data[name] || {}
255
- end
256
-
257
- def []=(section, pairs)
258
- check_modify
259
- @data[section] ||= {}
260
- pairs.each do |key, value|
261
- self.add_value(section, key, value)
262
- end
263
- end
264
-
265
- def sections
266
- @data.keys
267
- end
268
-
269
- def to_s
270
- ary = []
271
- @data.keys.sort.each do |section|
272
- ary << "[ #{section} ]\n"
273
- @data[section].keys.each do |key|
274
- ary << "#{key}=#{@data[section][key]}\n"
275
- end
276
- ary << "\n"
277
- end
278
- ary.join
279
- end
280
-
281
- def each
282
- @data.each do |section, hash|
283
- hash.each do |key, value|
284
- yield [section, key, value]
285
- end
286
- end
287
- end
288
-
289
- def inspect
290
- "#<#{self.class.name} sections=#{sections.inspect}>"
291
- end
292
-
293
- protected
294
-
295
- def data
296
- @data
297
- end
298
-
299
- private
300
-
301
- def initialize_copy(other)
302
- @data = other.data.dup
303
- end
304
-
305
- def check_modify
306
- raise TypeError.new("Insecure: can't modify OpenSSL config") if frozen?
307
- end
308
-
309
- def get_key_string(section, key)
310
- Config.get_key_string(@data, section, key)
311
- end
312
- end
313
- end
@@ -1,54 +0,0 @@
1
- #--
2
- #
3
- # $RCSfile$
4
- #
5
- # = Ruby-space predefined Digest 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
- class Digest
23
- # Deprecated.
24
- #
25
- # This class is only provided for backwards compatibility.
26
- class Digest < Digest # :nodoc:
27
- # Deprecated.
28
- #
29
- # See OpenSSL::Digest.new
30
- def initialize(*args)
31
- warn('Digest::Digest is deprecated; use Digest')
32
- super(*args)
33
- end
34
- end
35
-
36
- end # Digest
37
-
38
- # Returns a Digest subclass by +name+.
39
- #
40
- # require 'openssl'
41
- #
42
- # OpenSSL::Digest("MD5")
43
- # # => OpenSSL::Digest::MD5
44
- #
45
- # Digest("Foo")
46
- # # => NameError: wrong constant name Foo
47
-
48
- def Digest(name)
49
- OpenSSL::Digest.const_get(name)
50
- end
51
-
52
- module_function :Digest
53
-
54
- end # OpenSSL
@@ -1,330 +0,0 @@
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 => %w{
27
- ECDHE-ECDSA-AES128-GCM-SHA256
28
- ECDHE-RSA-AES128-GCM-SHA256
29
- ECDHE-ECDSA-AES256-GCM-SHA384
30
- ECDHE-RSA-AES256-GCM-SHA384
31
- DHE-RSA-AES128-GCM-SHA256
32
- DHE-DSS-AES128-GCM-SHA256
33
- DHE-RSA-AES256-GCM-SHA384
34
- DHE-DSS-AES256-GCM-SHA384
35
- ECDHE-ECDSA-AES128-SHA256
36
- ECDHE-RSA-AES128-SHA256
37
- ECDHE-ECDSA-AES128-SHA
38
- ECDHE-RSA-AES128-SHA
39
- ECDHE-ECDSA-AES256-SHA384
40
- ECDHE-RSA-AES256-SHA384
41
- ECDHE-ECDSA-AES256-SHA
42
- ECDHE-RSA-AES256-SHA
43
- DHE-RSA-AES128-SHA256
44
- DHE-RSA-AES256-SHA256
45
- DHE-RSA-AES128-SHA
46
- DHE-RSA-AES256-SHA
47
- DHE-DSS-AES128-SHA256
48
- DHE-DSS-AES256-SHA256
49
- DHE-DSS-AES128-SHA
50
- DHE-DSS-AES256-SHA
51
- AES128-GCM-SHA256
52
- AES256-GCM-SHA384
53
- AES128-SHA256
54
- AES256-SHA256
55
- AES128-SHA
56
- AES256-SHA
57
- ECDHE-ECDSA-RC4-SHA
58
- ECDHE-RSA-RC4-SHA
59
- RC4-SHA
60
- }.join(":"),
61
- :options => -> {
62
- opts = OpenSSL::SSL::OP_ALL
63
- opts &= ~OpenSSL::SSL::OP_DONT_INSERT_EMPTY_FRAGMENTS if defined?(OpenSSL::SSL::OP_DONT_INSERT_EMPTY_FRAGMENTS)
64
- opts |= OpenSSL::SSL::OP_NO_COMPRESSION if defined?(OpenSSL::SSL::OP_NO_COMPRESSION)
65
- opts |= OpenSSL::SSL::OP_NO_SSLv2 if defined?(OpenSSL::SSL::OP_NO_SSLv2)
66
- opts |= OpenSSL::SSL::OP_NO_SSLv3 if defined?(OpenSSL::SSL::OP_NO_SSLv3)
67
- opts
68
- }.call
69
- } unless const_defined? :DEFAULT_PARAMS # JRuby does it in Java
70
-
71
- begin
72
- DEFAULT_CERT_STORE = OpenSSL::X509::Store.new
73
- DEFAULT_CERT_STORE.set_default_paths
74
- if defined?(OpenSSL::X509::V_FLAG_CRL_CHECK_ALL)
75
- DEFAULT_CERT_STORE.flags = OpenSSL::X509::V_FLAG_CRL_CHECK_ALL
76
- end
77
- end unless const_defined? :DEFAULT_CERT_STORE
78
-
79
- ##
80
- # Sets the parameters for this SSL context to the values in +params+.
81
- # The keys in +params+ must be assignment methods on SSLContext.
82
- #
83
- # If the verify_mode is not VERIFY_NONE and ca_file, ca_path and
84
- # cert_store are not set then the system default certificate store is
85
- # used.
86
-
87
- def set_params(params={})
88
- params = DEFAULT_PARAMS.merge(params)
89
- params.each { |name, value| self.__send__("#{name}=", value) }
90
- if self.verify_mode != OpenSSL::SSL::VERIFY_NONE
91
- unless self.ca_file or self.ca_path or self.cert_store
92
- self.cert_store = DEFAULT_CERT_STORE
93
- end
94
- end
95
- return params
96
- end unless method_defined? :set_params
97
- end
98
-
99
- module SocketForwarder
100
- def addr
101
- to_io.addr
102
- end
103
-
104
- def peeraddr
105
- to_io.peeraddr
106
- end
107
-
108
- def setsockopt(level, optname, optval)
109
- to_io.setsockopt(level, optname, optval)
110
- end
111
-
112
- def getsockopt(level, optname)
113
- to_io.getsockopt(level, optname)
114
- end
115
-
116
- def fcntl(*args)
117
- to_io.fcntl(*args)
118
- end
119
-
120
- def closed?
121
- to_io.closed?
122
- end
123
-
124
- def do_not_reverse_lookup=(flag)
125
- to_io.do_not_reverse_lookup = flag
126
- end
127
- end
128
-
129
- module Nonblock
130
- def initialize(*args)
131
- flag = File::NONBLOCK
132
- flag |= @io.fcntl(Fcntl::F_GETFL) if defined?(Fcntl::F_GETFL)
133
- @io.fcntl(Fcntl::F_SETFL, flag)
134
- super
135
- end
136
- end unless const_defined? :Nonblock # JRuby: hooked up in "native" Java
137
-
138
- def verify_certificate_identity(cert, hostname)
139
- should_verify_common_name = true
140
- cert.extensions.each { |ext|
141
- next if ext.oid != "subjectAltName"
142
- ext.value.split(/,\s+/).each { |general_name|
143
- #case san.tag
144
- # MRI 2.2.3 (JRuby parses ASN.1 differently)
145
- #when 2 # dNSName in GeneralName (RFC5280)
146
- if /\ADNS:(.*)/ =~ general_name
147
- should_verify_common_name = false
148
- return true if verify_hostname(hostname, $1)
149
- # MRI 2.2.3 (JRuby parses ASN.1 differently)
150
- #when 7 # iPAddress in GeneralName (RFC5280)
151
- elsif /\AIP(?: Address)?:(.*)/ =~ general_name
152
- should_verify_common_name = false
153
- return true if $1 == hostname
154
- # NOTE: bellow logic makes little sense JRuby reads exts differently
155
- # follows GENERAL_NAME_print() in x509v3/v3_alt.c
156
- #if san.value.size == 4
157
- # return true if san.value.unpack('C*').join('.') == hostname
158
- #elsif san.value.size == 16
159
- # return true if san.value.unpack('n*').map { |e| sprintf("%X", e) }.join(':') == hostname
160
- #end
161
- end
162
- }
163
- }
164
- if should_verify_common_name
165
- cert.subject.to_a.each{|oid, value|
166
- if oid == "CN"
167
- return true if verify_hostname(hostname, value)
168
- end
169
- }
170
- end
171
- return false
172
- end
173
- module_function :verify_certificate_identity
174
-
175
- def verify_hostname(hostname, san) # :nodoc:
176
- # RFC 5280, IA5String is limited to the set of ASCII characters
177
- return false unless san.ascii_only?
178
- return false unless hostname.ascii_only?
179
-
180
- # See RFC 6125, section 6.4.1
181
- # Matching is case-insensitive.
182
- san_parts = san.downcase.split(".")
183
-
184
- # TODO: this behavior should probably be more strict
185
- return san == hostname if san_parts.size < 2
186
-
187
- # Matching is case-insensitive.
188
- host_parts = hostname.downcase.split(".")
189
-
190
- # RFC 6125, section 6.4.3, subitem 2.
191
- # If the wildcard character is the only character of the left-most
192
- # label in the presented identifier, the client SHOULD NOT compare
193
- # against anything but the left-most label of the reference
194
- # identifier (e.g., *.example.com would match foo.example.com but
195
- # not bar.foo.example.com or example.com).
196
- return false unless san_parts.size == host_parts.size
197
-
198
- # RFC 6125, section 6.4.3, subitem 1.
199
- # The client SHOULD NOT attempt to match a presented identifier in
200
- # which the wildcard character comprises a label other than the
201
- # left-most label (e.g., do not match bar.*.example.net).
202
- return false unless verify_wildcard(host_parts.shift, san_parts.shift)
203
-
204
- san_parts.join(".") == host_parts.join(".")
205
- end
206
- module_function :verify_hostname
207
-
208
- def verify_wildcard(domain_component, san_component) # :nodoc:
209
- parts = san_component.split("*", -1)
210
-
211
- return false if parts.size > 2
212
- return san_component == domain_component if parts.size == 1
213
-
214
- # RFC 6125, section 6.4.3, subitem 3.
215
- # The client SHOULD NOT attempt to match a presented identifier
216
- # where the wildcard character is embedded within an A-label or
217
- # U-label of an internationalized domain name.
218
- return false if domain_component.start_with?("xn--") && san_component != "*"
219
-
220
- parts[0].length + parts[1].length < domain_component.length &&
221
- domain_component.start_with?(parts[0]) &&
222
- domain_component.end_with?(parts[1])
223
- end
224
- module_function :verify_wildcard
225
-
226
- class SSLSocket
227
- include Buffering
228
- include SocketForwarder
229
- include Nonblock
230
-
231
- def sysclose
232
- return if closed?
233
- stop
234
- io.close if sync_close
235
- end unless method_defined? :sysclose
236
-
237
- ##
238
- # Perform hostname verification after an SSL connection is established
239
- #
240
- # This method MUST be called after calling #connect to ensure that the
241
- # hostname of a remote peer has been verified.
242
- def post_connection_check(hostname)
243
- if peer_cert.nil?
244
- msg = "Peer verification enabled, but no certificate received."
245
- if using_anon_cipher?
246
- msg += " Anonymous cipher suite #{cipher[0]} was negotiated. Anonymous suites must be disabled to use peer verification."
247
- end
248
- raise SSLError, msg
249
- end
250
-
251
- unless OpenSSL::SSL.verify_certificate_identity(peer_cert, hostname)
252
- raise SSLError, "hostname \"#{hostname}\" does not match the server certificate"
253
- end
254
- return true
255
- end
256
-
257
- private
258
-
259
- def using_anon_cipher?
260
- ctx = OpenSSL::SSL::SSLContext.new
261
- ctx.ciphers = "aNULL"
262
- ctx.ciphers.include?(cipher)
263
- end
264
- end
265
-
266
- ##
267
- # SSLServer represents a TCP/IP server socket with Secure Sockets Layer.
268
- class SSLServer
269
- include SocketForwarder
270
- # When true then #accept works exactly the same as TCPServer#accept
271
- attr_accessor :start_immediately
272
-
273
- # Creates a new instance of SSLServer.
274
- # * +srv+ is an instance of TCPServer.
275
- # * +ctx+ is an instance of OpenSSL::SSL::SSLContext.
276
- def initialize(svr, ctx)
277
- @svr = svr
278
- @ctx = ctx
279
- unless ctx.session_id_context
280
- # see #6137 - session id may not exceed 32 bytes
281
- prng = ::Random.new($0.hash)
282
- session_id = prng.bytes(16).unpack('H*')[0]
283
- @ctx.session_id_context = session_id
284
- end
285
- @start_immediately = true
286
- end
287
-
288
- # Returns the TCPServer passed to the SSLServer when initialized.
289
- def to_io
290
- @svr
291
- end
292
-
293
- # See TCPServer#listen for details.
294
- def listen(backlog=5)
295
- @svr.listen(backlog)
296
- end
297
-
298
- # See BasicSocket#shutdown for details.
299
- def shutdown(how=Socket::SHUT_RDWR)
300
- @svr.shutdown(how)
301
- end
302
-
303
- # Works similar to TCPServer#accept.
304
- def accept
305
- # Socket#accept returns [socket, addrinfo].
306
- # TCPServer#accept returns a socket.
307
- # The following comma strips addrinfo.
308
- sock, = @svr.accept
309
- begin
310
- ssl = OpenSSL::SSL::SSLSocket.new(sock, @ctx)
311
- ssl.sync_close = true
312
- ssl.accept if @start_immediately
313
- ssl
314
- rescue Exception => ex
315
- if ssl
316
- ssl.close
317
- else
318
- sock.close
319
- end
320
- raise ex
321
- end
322
- end
323
-
324
- # See IO#close for details.
325
- def close
326
- @svr.close
327
- end
328
- end
329
- end
330
- end