jruby-openssl 0.9.12-java → 0.9.13-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.
@@ -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