jruby-openssl 0.10.0-java → 0.10.1-java

Sign up to get free protection for your applications and to get access to all the features.
@@ -16,71 +16,83 @@ require "io/nonblock"
16
16
  module OpenSSL
17
17
  module SSL
18
18
  class SSLContext
19
- DEFAULT_PARAMS = {
20
- :ssl_version => "SSLv23",
19
+ unless const_defined? :DEFAULT_PARAMS # JRuby does it in Java
20
+ DEFAULT_PARAMS = { # :nodoc:
21
+ :min_version => OpenSSL::SSL::TLS1_VERSION,
21
22
  :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(":"),
23
+ :verify_hostname => true,
57
24
  :options => -> {
58
25
  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)
26
+ opts &= ~OpenSSL::SSL::OP_DONT_INSERT_EMPTY_FRAGMENTS
27
+ opts |= OpenSSL::SSL::OP_NO_COMPRESSION
63
28
  opts
64
29
  }.call
65
- } unless const_defined? :DEFAULT_PARAMS # JRuby
30
+ }
31
+
32
+ if !(OpenSSL::OPENSSL_VERSION.start_with?("OpenSSL") &&
33
+ OpenSSL::OPENSSL_VERSION_NUMBER >= 0x10100000)
34
+ DEFAULT_PARAMS.merge!(
35
+ ciphers: %w{
36
+ ECDHE-ECDSA-AES128-GCM-SHA256
37
+ ECDHE-RSA-AES128-GCM-SHA256
38
+ ECDHE-ECDSA-AES256-GCM-SHA384
39
+ ECDHE-RSA-AES256-GCM-SHA384
40
+ DHE-RSA-AES128-GCM-SHA256
41
+ DHE-DSS-AES128-GCM-SHA256
42
+ DHE-RSA-AES256-GCM-SHA384
43
+ DHE-DSS-AES256-GCM-SHA384
44
+ ECDHE-ECDSA-AES128-SHA256
45
+ ECDHE-RSA-AES128-SHA256
46
+ ECDHE-ECDSA-AES128-SHA
47
+ ECDHE-RSA-AES128-SHA
48
+ ECDHE-ECDSA-AES256-SHA384
49
+ ECDHE-RSA-AES256-SHA384
50
+ ECDHE-ECDSA-AES256-SHA
51
+ ECDHE-RSA-AES256-SHA
52
+ DHE-RSA-AES128-SHA256
53
+ DHE-RSA-AES256-SHA256
54
+ DHE-RSA-AES128-SHA
55
+ DHE-RSA-AES256-SHA
56
+ DHE-DSS-AES128-SHA256
57
+ DHE-DSS-AES256-SHA256
58
+ DHE-DSS-AES128-SHA
59
+ DHE-DSS-AES256-SHA
60
+ AES128-GCM-SHA256
61
+ AES256-GCM-SHA384
62
+ AES128-SHA256
63
+ AES256-SHA256
64
+ AES128-SHA
65
+ AES256-SHA
66
+ }.join(":"),
67
+ )
68
+ end
69
+ end
70
+
71
+ if defined?(OpenSSL::PKey::DH)
72
+ DEFAULT_2048 = OpenSSL::PKey::DH.new <<-_end_of_pem_
73
+ -----BEGIN DH PARAMETERS-----
74
+ MIIBCAKCAQEA7E6kBrYiyvmKAMzQ7i8WvwVk9Y/+f8S7sCTN712KkK3cqd1jhJDY
75
+ JbrYeNV3kUIKhPxWHhObHKpD1R84UpL+s2b55+iMd6GmL7OYmNIT/FccKhTcveab
76
+ VBmZT86BZKYyf45hUF9FOuUM9xPzuK3Vd8oJQvfYMCd7LPC0taAEljQLR4Edf8E6
77
+ YoaOffgTf5qxiwkjnlVZQc3whgnEt9FpVMvQ9eknyeGB5KHfayAc3+hUAvI3/Cr3
78
+ 1bNveX5wInh5GDx1FGhKBZ+s1H+aedudCm7sCgRwv8lKWYGiHzObSma8A86KG+MD
79
+ 7Lo5JquQ3DlBodj3IDyPrxIv96lvRPFtAwIBAg==
80
+ -----END DH PARAMETERS-----
81
+ _end_of_pem_
82
+ private_constant :DEFAULT_2048
83
+
84
+ DEFAULT_TMP_DH_CALLBACK = lambda { |ctx, is_export, keylen| # :nodoc:
85
+ warn "using default DH parameters." if $VERBOSE
86
+ DEFAULT_2048
87
+ }
88
+ end
66
89
 
67
90
  begin
68
- DEFAULT_CERT_STORE = OpenSSL::X509::Store.new
91
+ DEFAULT_CERT_STORE = OpenSSL::X509::Store.new # :nodoc:
69
92
  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
93
+ DEFAULT_CERT_STORE.flags = OpenSSL::X509::V_FLAG_CRL_CHECK_ALL
73
94
  end unless const_defined? :DEFAULT_CERT_STORE # JRuby
74
95
 
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
96
  # A callback invoked when DH parameters are required.
85
97
  #
86
98
  # The callback is invoked with the Session for the key exchange, an
@@ -92,45 +104,115 @@ module OpenSSL
92
104
 
93
105
  attr_accessor :tmp_dh_callback
94
106
 
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
107
+ # A callback invoked at connect time to distinguish between multiple
108
+ # server names.
108
109
  #
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
- self.ssl_version = version if version
114
- end unless defined? JRUBY_VERSION # JRuby
110
+ # The callback is invoked with an SSLSocket and a server name. The
111
+ # callback must return an SSLContext for the server name or nil.
112
+ attr_accessor :servername_cb
115
113
 
116
114
  ##
117
- # Sets the parameters for this SSL context to the values in +params+.
118
- # The keys in +params+ must be assignment methods on SSLContext.
115
+ # call-seq:
116
+ # ctx.set_params(params = {}) -> params
117
+ #
118
+ # Sets saner defaults optimized for the use with HTTP-like protocols.
119
+ #
120
+ # If a Hash _params_ is given, the parameters are overridden with it.
121
+ # The keys in _params_ must be assignment methods on SSLContext.
119
122
  #
120
123
  # If the verify_mode is not VERIFY_NONE and ca_file, ca_path and
121
124
  # cert_store are not set then the system default certificate store is
122
125
  # used.
123
-
124
126
  def set_params(params={})
125
127
  params = DEFAULT_PARAMS.merge(params)
126
- params.each{|name, value| self.__send__("#{name}=", value) }
128
+ # TODO JRuby: need to support SSLContext#options (since Ruby 2.5)
129
+ #self.options = params.delete(:options) # set before min_version/max_version
130
+ params.each { |name, value| self.__send__("#{name}=", value) }
127
131
  if self.verify_mode != OpenSSL::SSL::VERIFY_NONE
128
132
  unless self.ca_file or self.ca_path or self.cert_store
129
133
  self.cert_store = DEFAULT_CERT_STORE
130
134
  end
131
135
  end
132
136
  return params
133
- end unless method_defined? :set_params # JRuby
137
+ end unless method_defined? :set_params
138
+
139
+ # call-seq:
140
+ # ctx.min_version = OpenSSL::SSL::TLS1_2_VERSION
141
+ # ctx.min_version = :TLS1_2
142
+ # ctx.min_version = nil
143
+ #
144
+ # Sets the lower bound on the supported SSL/TLS protocol version. The
145
+ # version may be specified by an integer constant named
146
+ # OpenSSL::SSL::*_VERSION, a Symbol, or +nil+ which means "any version".
147
+ #
148
+ # Be careful that you don't overwrite OpenSSL::SSL::OP_NO_{SSL,TLS}v*
149
+ # options by #options= once you have called #min_version= or
150
+ # #max_version=.
151
+ #
152
+ # === Example
153
+ # ctx = OpenSSL::SSL::SSLContext.new
154
+ # ctx.min_version = OpenSSL::SSL::TLS1_1_VERSION
155
+ # ctx.max_version = OpenSSL::SSL::TLS1_2_VERSION
156
+ #
157
+ # sock = OpenSSL::SSL::SSLSocket.new(tcp_sock, ctx)
158
+ # sock.connect # Initiates a connection using either TLS 1.1 or TLS 1.2
159
+ def min_version=(version)
160
+ set_minmax_proto_version(version, @max_proto_version ||= nil)
161
+ @min_proto_version = version
162
+ end
163
+
164
+ # call-seq:
165
+ # ctx.max_version = OpenSSL::SSL::TLS1_2_VERSION
166
+ # ctx.max_version = :TLS1_2
167
+ # ctx.max_version = nil
168
+ #
169
+ # Sets the upper bound of the supported SSL/TLS protocol version. See
170
+ # #min_version= for the possible values.
171
+ def max_version=(version)
172
+ set_minmax_proto_version(@min_proto_version ||= nil, version)
173
+ @max_proto_version = version
174
+ end
175
+
176
+ # call-seq:
177
+ # ctx.ssl_version = :TLSv1
178
+ # ctx.ssl_version = "SSLv23"
179
+ #
180
+ # Sets the SSL/TLS protocol version for the context. This forces
181
+ # connections to use only the specified protocol version. This is
182
+ # deprecated and only provided for backwards compatibility. Use
183
+ # #min_version= and #max_version= instead.
184
+ #
185
+ # === History
186
+ # As the name hints, this used to call the SSL_CTX_set_ssl_version()
187
+ # function which sets the SSL method used for connections created from
188
+ # the context. As of Ruby/OpenSSL 2.1, this accessor method is
189
+ # implemented to call #min_version= and #max_version= instead.
190
+ def ssl_version=(meth)
191
+ meth = meth.to_s if meth.is_a?(Symbol)
192
+ if /(?<type>_client|_server)\z/ =~ meth
193
+ meth = $`
194
+ if $VERBOSE
195
+ warn "#{caller(1, 1)[0]}: method type #{type.inspect} is ignored"
196
+ end
197
+ end
198
+ version = METHODS_MAP[meth.intern] or
199
+ raise ArgumentError, "unknown SSL method `%s'" % meth
200
+ set_minmax_proto_version(version, version)
201
+ @min_proto_version = @max_proto_version = version
202
+ end unless method_defined? :ssl_version=
203
+
204
+ METHODS_MAP = {
205
+ SSLv23: 0,
206
+ SSLv2: OpenSSL::SSL::SSL2_VERSION,
207
+ SSLv3: OpenSSL::SSL::SSL3_VERSION,
208
+ TLSv1: OpenSSL::SSL::TLS1_VERSION,
209
+ TLSv1_1: OpenSSL::SSL::TLS1_1_VERSION,
210
+ TLSv1_2: OpenSSL::SSL::TLS1_2_VERSION,
211
+ }.freeze
212
+ private_constant :METHODS_MAP
213
+
214
+ # METHODS setup from native (JRuby)
215
+ # deprecate_constant :METHODS
134
216
  end
135
217
 
136
218
  module SocketForwarder
@@ -246,8 +328,8 @@ module OpenSSL
246
328
  return false if domain_component.start_with?("xn--") && san_component != "*"
247
329
 
248
330
  parts[0].length + parts[1].length < domain_component.length &&
249
- domain_component.start_with?(parts[0]) &&
250
- domain_component.end_with?(parts[1])
331
+ domain_component.start_with?(parts[0]) &&
332
+ domain_component.end_with?(parts[1])
251
333
  end
252
334
  module_function :verify_wildcard
253
335
 
@@ -255,42 +337,18 @@ module OpenSSL
255
337
  include Buffering
256
338
  include SocketForwarder
257
339
 
258
- # if ExtConfig::OPENSSL_NO_SOCK
259
- # def initialize(io, ctx = nil); raise NotImplementedError; end
260
- # else
261
- # if ExtConfig::HAVE_TLSEXT_HOST_NAME
262
- # attr_accessor :hostname
263
- # end
340
+ # attr_reader :hostname
264
341
  #
265
- # attr_reader :io, :context
266
- # attr_accessor :sync_close
267
- # alias :to_io :io
342
+ # # The underlying IO object.
343
+ # attr_reader :io
344
+ # alias :to_io :io
268
345
  #
269
- # # call-seq:
270
- # # SSLSocket.new(io) => aSSLSocket
271
- # # SSLSocket.new(io, ctx) => aSSLSocket
272
- # #
273
- # # Creates a new SSL socket from +io+ which must be a real ruby object (not an
274
- # # IO-like object that responds to read/write).
275
- # #
276
- # # If +ctx+ is provided the SSL Sockets initial params will be taken from
277
- # # the context.
278
- # #
279
- # # The OpenSSL::Buffering module provides additional IO methods.
280
- # #
281
- # # This method will freeze the SSLContext if one is provided;
282
- # # however, session management is still allowed in the frozen SSLContext.
346
+ # # The SSLContext object used in this connection.
347
+ # attr_reader :context
283
348
  #
284
- # def initialize(io, context = OpenSSL::SSL::SSLContext.new)
285
- # @io = io
286
- # @context = context
287
- # @sync_close = false
288
- # @hostname = nil
289
- # @io.nonblock = true if @io.respond_to?(:nonblock=)
290
- # context.setup
291
- # super()
292
- # end
293
- # end
349
+ # # Whether to close the underlying socket as well, when the SSL/TLS
350
+ # # connection is shut down. This defaults to +false+.
351
+ # attr_accessor :sync_close
294
352
 
295
353
  # call-seq:
296
354
  # ssl.sysclose => nil
@@ -303,10 +361,12 @@ module OpenSSL
303
361
  return if closed?
304
362
  stop
305
363
  io.close if sync_close
306
- end unless method_defined? :sysclose # JRuby
364
+ end unless method_defined? :sysclose
307
365
 
308
- ##
309
- # Perform hostname verification after an SSL connection is established
366
+ # call-seq:
367
+ # ssl.post_connection_check(hostname) -> true
368
+ #
369
+ # Perform hostname verification following RFC 6125.
310
370
  #
311
371
  # This method MUST be called after calling #connect to ensure that the
312
372
  # hostname of a remote peer has been verified.
@@ -314,7 +374,8 @@ module OpenSSL
314
374
  if peer_cert.nil?
315
375
  msg = "Peer verification enabled, but no certificate received."
316
376
  if using_anon_cipher?
317
- msg += " Anonymous cipher suite #{cipher[0]} was negotiated. Anonymous suites must be disabled to use peer verification."
377
+ msg += " Anonymous cipher suite #{cipher[0]} was negotiated. " \
378
+ "Anonymous suites must be disabled to use peer verification."
318
379
  end
319
380
  raise SSLError, msg
320
381
  end
@@ -325,6 +386,11 @@ module OpenSSL
325
386
  return true
326
387
  end
327
388
 
389
+ # call-seq:
390
+ # ssl.session -> aSession
391
+ #
392
+ # Returns the SSLSession object currently used, or nil if the session is
393
+ # not established.
328
394
  def session
329
395
  SSL::Session.new(self)
330
396
  rescue SSL::Session::SessionError
@@ -344,7 +410,7 @@ module OpenSSL
344
410
  end
345
411
 
346
412
  def tmp_dh_callback
347
- @context.tmp_dh_callback || OpenSSL::PKey::DEFAULT_TMP_DH_CALLBACK
413
+ @context.tmp_dh_callback || OpenSSL::SSL::SSLContext::DEFAULT_TMP_DH_CALLBACK
348
414
  end
349
415
 
350
416
  def tmp_ecdh_callback
@@ -368,8 +434,8 @@ module OpenSSL
368
434
  attr_accessor :start_immediately
369
435
 
370
436
  # Creates a new instance of SSLServer.
371
- # * +srv+ is an instance of TCPServer.
372
- # * +ctx+ is an instance of OpenSSL::SSL::SSLContext.
437
+ # * _srv_ is an instance of TCPServer.
438
+ # * _ctx_ is an instance of OpenSSL::SSL::SSLContext.
373
439
  def initialize(svr, ctx)
374
440
  @svr = svr
375
441
  @ctx = ctx
@@ -96,7 +96,13 @@ module OpenSSL
96
96
  end
97
97
 
98
98
  def parse_openssl(str, template=OBJECT_TYPE_TEMPLATE)
99
- ary = str.scan(/\s*([^\/,]+)\s*/).collect{|i| i[0].split("=", 2) }
99
+ if str.start_with?("/")
100
+ # /A=B/C=D format
101
+ ary = str[1..-1].split("/").map { |i| i.split("=", 2) }
102
+ else
103
+ # Comma-separated
104
+ ary = str.split(",").map { |i| i.strip.split("=", 2) }
105
+ end
100
106
  self.new(ary, template)
101
107
  end
102
108
 
@@ -4,8 +4,6 @@ elsif RUBY_VERSION > '2.2'
4
4
  load "jopenssl22/openssl/#{File.basename(__FILE__)}"
5
5
  elsif RUBY_VERSION > '2.1'
6
6
  load "jopenssl21/openssl/#{File.basename(__FILE__)}"
7
- elsif RUBY_VERSION > '1.9'
8
- load "jopenssl19/openssl/#{File.basename(__FILE__)}"
9
7
  else
10
- load "jopenssl18/openssl/#{File.basename(__FILE__)}"
8
+ load "jopenssl19/openssl/#{File.basename(__FILE__)}"
11
9
  end
@@ -4,8 +4,6 @@ elsif RUBY_VERSION > '2.2'
4
4
  load "jopenssl22/openssl/#{File.basename(__FILE__)}"
5
5
  elsif RUBY_VERSION > '2.1'
6
6
  load "jopenssl21/openssl/#{File.basename(__FILE__)}"
7
- elsif RUBY_VERSION > '1.9'
8
- load "jopenssl19/openssl/#{File.basename(__FILE__)}"
9
7
  else
10
- load "jopenssl18/openssl/#{File.basename(__FILE__)}"
8
+ load "jopenssl19/openssl/#{File.basename(__FILE__)}"
11
9
  end
@@ -4,8 +4,6 @@ elsif RUBY_VERSION > '2.2'
4
4
  load "jopenssl22/openssl/#{File.basename(__FILE__)}"
5
5
  elsif RUBY_VERSION > '2.1'
6
6
  load "jopenssl21/openssl/#{File.basename(__FILE__)}"
7
- elsif RUBY_VERSION > '1.9'
8
- load "jopenssl19/openssl/#{File.basename(__FILE__)}"
9
7
  else
10
- load "jopenssl18/openssl/#{File.basename(__FILE__)}"
8
+ load "jopenssl19/openssl/#{File.basename(__FILE__)}"
11
9
  end
@@ -4,8 +4,14 @@ elsif RUBY_VERSION > '2.2'
4
4
  load "jopenssl22/openssl/#{File.basename(__FILE__)}"
5
5
  elsif RUBY_VERSION > '2.1'
6
6
  load "jopenssl21/openssl/#{File.basename(__FILE__)}"
7
- elsif RUBY_VERSION > '1.9'
8
- load "jopenssl19/openssl/#{File.basename(__FILE__)}"
9
7
  else
10
- load "jopenssl18/openssl/#{File.basename(__FILE__)}"
11
- end
8
+ load "jopenssl19/openssl/#{File.basename(__FILE__)}"
9
+ end
10
+
11
+ # @note moved from JOpenSSL native bits.
12
+ module OpenSSL
13
+ class Config
14
+ DEFAULT_CONFIG_FILE = nil
15
+ end
16
+ class ConfigError < OpenSSLError; end
17
+ end