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.
@@ -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