jruby-openssl 0.11.0-java → 0.12.1-java
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/History.md +20 -0
- data/Mavenfile +21 -26
- data/README.md +3 -0
- data/Rakefile +21 -35
- data/lib/jopenssl/load.rb +0 -14
- data/lib/jopenssl/version.rb +1 -1
- data/lib/jopenssl.jar +0 -0
- data/lib/openssl/bn.rb +40 -9
- data/lib/openssl/buffering.rb +478 -9
- data/lib/openssl/cipher.rb +67 -9
- data/lib/openssl/config.rb +496 -12
- data/lib/openssl/digest.rb +73 -9
- data/lib/openssl/hmac.rb +13 -0
- data/lib/openssl/marshal.rb +30 -0
- data/lib/openssl/pkcs5.rb +3 -3
- data/lib/openssl/pkey.rb +42 -5
- data/lib/openssl/ssl.rb +543 -9
- data/lib/openssl/x509.rb +369 -9
- data/lib/openssl.rb +43 -1
- data/pom.xml +35 -127
- metadata +8 -42
- data/lib/jopenssl19/openssl/bn.rb +0 -29
- data/lib/jopenssl19/openssl/buffering.rb +0 -449
- data/lib/jopenssl19/openssl/cipher.rb +0 -28
- data/lib/jopenssl19/openssl/config.rb +0 -472
- data/lib/jopenssl19/openssl/digest.rb +0 -32
- data/lib/jopenssl19/openssl/ssl-internal.rb +0 -223
- data/lib/jopenssl19/openssl/ssl.rb +0 -2
- data/lib/jopenssl19/openssl/x509-internal.rb +0 -115
- data/lib/jopenssl19/openssl/x509.rb +0 -2
- data/lib/jopenssl19/openssl.rb +0 -22
- data/lib/jopenssl21/openssl/bn.rb +0 -28
- data/lib/jopenssl21/openssl/buffering.rb +0 -1
- data/lib/jopenssl21/openssl/cipher.rb +0 -1
- data/lib/jopenssl21/openssl/config.rb +0 -1
- data/lib/jopenssl21/openssl/digest.rb +0 -1
- data/lib/jopenssl21/openssl/ssl.rb +0 -1
- data/lib/jopenssl21/openssl/x509.rb +0 -119
- data/lib/jopenssl21/openssl.rb +0 -22
- data/lib/jopenssl22/openssl/bn.rb +0 -39
- data/lib/jopenssl22/openssl/buffering.rb +0 -456
- data/lib/jopenssl22/openssl/cipher.rb +0 -28
- data/lib/jopenssl22/openssl/config.rb +0 -313
- data/lib/jopenssl22/openssl/digest.rb +0 -54
- data/lib/jopenssl22/openssl/ssl.rb +0 -330
- data/lib/jopenssl22/openssl/x509.rb +0 -139
- data/lib/jopenssl22/openssl.rb +0 -22
- data/lib/jopenssl23/openssl/bn.rb +0 -38
- data/lib/jopenssl23/openssl/buffering.rb +0 -455
- data/lib/jopenssl23/openssl/cipher.rb +0 -25
- data/lib/jopenssl23/openssl/config.rb +0 -474
- data/lib/jopenssl23/openssl/digest.rb +0 -43
- data/lib/jopenssl23/openssl/pkey.rb +0 -25
- data/lib/jopenssl23/openssl/ssl.rb +0 -508
- data/lib/jopenssl23/openssl/x509.rb +0 -208
- data/lib/jopenssl23/openssl.rb +0 -19
- data/lib/openssl/ssl-internal.rb +0 -5
- data/lib/openssl/x509-internal.rb +0 -5
@@ -1,508 +0,0 @@
|
|
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
|
-
unless const_defined? :DEFAULT_PARAMS # JRuby does it in Java
|
20
|
-
DEFAULT_PARAMS = { # :nodoc:
|
21
|
-
:min_version => OpenSSL::SSL::TLS1_VERSION,
|
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
|
28
|
-
opts
|
29
|
-
}.call
|
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
|
89
|
-
|
90
|
-
begin
|
91
|
-
DEFAULT_CERT_STORE = OpenSSL::X509::Store.new # :nodoc:
|
92
|
-
DEFAULT_CERT_STORE.set_default_paths
|
93
|
-
DEFAULT_CERT_STORE.flags = OpenSSL::X509::V_FLAG_CRL_CHECK_ALL
|
94
|
-
end unless const_defined? :DEFAULT_CERT_STORE # JRuby
|
95
|
-
|
96
|
-
# A callback invoked when DH parameters are required.
|
97
|
-
#
|
98
|
-
# The callback is invoked with the Session for the key exchange, an
|
99
|
-
# flag indicating the use of an export cipher and the keylength
|
100
|
-
# required.
|
101
|
-
#
|
102
|
-
# The callback must return an OpenSSL::PKey::DH instance of the correct
|
103
|
-
# key length.
|
104
|
-
|
105
|
-
attr_accessor :tmp_dh_callback
|
106
|
-
|
107
|
-
# A callback invoked at connect time to distinguish between multiple
|
108
|
-
# server names.
|
109
|
-
#
|
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
|
113
|
-
|
114
|
-
# call-seq:
|
115
|
-
# SSLContext.new -> ctx
|
116
|
-
# SSLContext.new(:TLSv1) -> ctx
|
117
|
-
# SSLContext.new("SSLv23") -> ctx
|
118
|
-
#
|
119
|
-
# Creates a new SSL context.
|
120
|
-
#
|
121
|
-
# If an argument is given, #ssl_version= is called with the value. Note
|
122
|
-
# that this form is deprecated. New applications should use #min_version=
|
123
|
-
# and #max_version= as necessary.
|
124
|
-
# def initialize(version = nil)
|
125
|
-
# self.options |= OpenSSL::SSL::OP_ALL
|
126
|
-
# self.ssl_version = version if version
|
127
|
-
# end
|
128
|
-
|
129
|
-
##
|
130
|
-
# call-seq:
|
131
|
-
# ctx.set_params(params = {}) -> params
|
132
|
-
#
|
133
|
-
# Sets saner defaults optimized for the use with HTTP-like protocols.
|
134
|
-
#
|
135
|
-
# If a Hash _params_ is given, the parameters are overridden with it.
|
136
|
-
# The keys in _params_ must be assignment methods on SSLContext.
|
137
|
-
#
|
138
|
-
# If the verify_mode is not VERIFY_NONE and ca_file, ca_path and
|
139
|
-
# cert_store are not set then the system default certificate store is
|
140
|
-
# used.
|
141
|
-
def set_params(params={})
|
142
|
-
params = DEFAULT_PARAMS.merge(params)
|
143
|
-
# TODO JRuby: need to support SSLContext#options (since Ruby 2.5)
|
144
|
-
#self.options = params.delete(:options) # set before min_version/max_version
|
145
|
-
params.each { |name, value| self.__send__("#{name}=", value) }
|
146
|
-
if self.verify_mode != OpenSSL::SSL::VERIFY_NONE
|
147
|
-
unless self.ca_file or self.ca_path or self.cert_store
|
148
|
-
self.cert_store = DEFAULT_CERT_STORE
|
149
|
-
end
|
150
|
-
end
|
151
|
-
return params
|
152
|
-
end unless method_defined? :set_params
|
153
|
-
|
154
|
-
# call-seq:
|
155
|
-
# ctx.min_version = OpenSSL::SSL::TLS1_2_VERSION
|
156
|
-
# ctx.min_version = :TLS1_2
|
157
|
-
# ctx.min_version = nil
|
158
|
-
#
|
159
|
-
# Sets the lower bound on the supported SSL/TLS protocol version. The
|
160
|
-
# version may be specified by an integer constant named
|
161
|
-
# OpenSSL::SSL::*_VERSION, a Symbol, or +nil+ which means "any version".
|
162
|
-
#
|
163
|
-
# Be careful that you don't overwrite OpenSSL::SSL::OP_NO_{SSL,TLS}v*
|
164
|
-
# options by #options= once you have called #min_version= or
|
165
|
-
# #max_version=.
|
166
|
-
#
|
167
|
-
# === Example
|
168
|
-
# ctx = OpenSSL::SSL::SSLContext.new
|
169
|
-
# ctx.min_version = OpenSSL::SSL::TLS1_1_VERSION
|
170
|
-
# ctx.max_version = OpenSSL::SSL::TLS1_2_VERSION
|
171
|
-
#
|
172
|
-
# sock = OpenSSL::SSL::SSLSocket.new(tcp_sock, ctx)
|
173
|
-
# sock.connect # Initiates a connection using either TLS 1.1 or TLS 1.2
|
174
|
-
def min_version=(version)
|
175
|
-
set_minmax_proto_version(version, @max_proto_version ||= nil)
|
176
|
-
@min_proto_version = version
|
177
|
-
end
|
178
|
-
|
179
|
-
# call-seq:
|
180
|
-
# ctx.max_version = OpenSSL::SSL::TLS1_2_VERSION
|
181
|
-
# ctx.max_version = :TLS1_2
|
182
|
-
# ctx.max_version = nil
|
183
|
-
#
|
184
|
-
# Sets the upper bound of the supported SSL/TLS protocol version. See
|
185
|
-
# #min_version= for the possible values.
|
186
|
-
def max_version=(version)
|
187
|
-
set_minmax_proto_version(@min_proto_version ||= nil, version)
|
188
|
-
@max_proto_version = version
|
189
|
-
end
|
190
|
-
|
191
|
-
# call-seq:
|
192
|
-
# ctx.ssl_version = :TLSv1
|
193
|
-
# ctx.ssl_version = "SSLv23"
|
194
|
-
#
|
195
|
-
# Sets the SSL/TLS protocol version for the context. This forces
|
196
|
-
# connections to use only the specified protocol version. This is
|
197
|
-
# deprecated and only provided for backwards compatibility. Use
|
198
|
-
# #min_version= and #max_version= instead.
|
199
|
-
#
|
200
|
-
# === History
|
201
|
-
# As the name hints, this used to call the SSL_CTX_set_ssl_version()
|
202
|
-
# function which sets the SSL method used for connections created from
|
203
|
-
# the context. As of Ruby/OpenSSL 2.1, this accessor method is
|
204
|
-
# implemented to call #min_version= and #max_version= instead.
|
205
|
-
def ssl_version=(meth)
|
206
|
-
meth = meth.to_s if meth.is_a?(Symbol)
|
207
|
-
if /(?<type>_client|_server)\z/ =~ meth
|
208
|
-
meth = $`
|
209
|
-
if $VERBOSE
|
210
|
-
warn "#{caller(1, 1)[0]}: method type #{type.inspect} is ignored"
|
211
|
-
end
|
212
|
-
end
|
213
|
-
version = METHODS_MAP[meth.intern] or
|
214
|
-
raise ArgumentError, "unknown SSL method `%s'" % meth
|
215
|
-
set_minmax_proto_version(version, version)
|
216
|
-
@min_proto_version = @max_proto_version = version
|
217
|
-
end unless method_defined? :ssl_version=
|
218
|
-
|
219
|
-
METHODS_MAP = {
|
220
|
-
SSLv23: 0,
|
221
|
-
SSLv2: OpenSSL::SSL::SSL2_VERSION,
|
222
|
-
SSLv3: OpenSSL::SSL::SSL3_VERSION,
|
223
|
-
TLSv1: OpenSSL::SSL::TLS1_VERSION,
|
224
|
-
TLSv1_1: OpenSSL::SSL::TLS1_1_VERSION,
|
225
|
-
TLSv1_2: OpenSSL::SSL::TLS1_2_VERSION,
|
226
|
-
}.freeze
|
227
|
-
private_constant :METHODS_MAP
|
228
|
-
|
229
|
-
# METHODS setup from native (JRuby)
|
230
|
-
# deprecate_constant :METHODS
|
231
|
-
end
|
232
|
-
|
233
|
-
module SocketForwarder
|
234
|
-
def addr
|
235
|
-
to_io.addr
|
236
|
-
end
|
237
|
-
|
238
|
-
def peeraddr
|
239
|
-
to_io.peeraddr
|
240
|
-
end
|
241
|
-
|
242
|
-
def setsockopt(level, optname, optval)
|
243
|
-
to_io.setsockopt(level, optname, optval)
|
244
|
-
end
|
245
|
-
|
246
|
-
def getsockopt(level, optname)
|
247
|
-
to_io.getsockopt(level, optname)
|
248
|
-
end
|
249
|
-
|
250
|
-
def fcntl(*args)
|
251
|
-
to_io.fcntl(*args)
|
252
|
-
end
|
253
|
-
|
254
|
-
def closed?
|
255
|
-
to_io.closed?
|
256
|
-
end
|
257
|
-
|
258
|
-
def do_not_reverse_lookup=(flag)
|
259
|
-
to_io.do_not_reverse_lookup = flag
|
260
|
-
end
|
261
|
-
end unless const_defined? :SocketForwarder # JRuby: hooked up in "native" Java
|
262
|
-
|
263
|
-
def verify_certificate_identity(cert, hostname)
|
264
|
-
should_verify_common_name = true
|
265
|
-
cert.extensions.each{|ext|
|
266
|
-
next if ext.oid != "subjectAltName"
|
267
|
-
ext.value.split(/,\s+/).each { |general_name|
|
268
|
-
#case san.tag
|
269
|
-
# MRI 2.2.3 (JRuby parses ASN.1 differently)
|
270
|
-
#when 2 # dNSName in GeneralName (RFC5280)
|
271
|
-
if /\ADNS:(.*)/ =~ general_name
|
272
|
-
should_verify_common_name = false
|
273
|
-
return true if verify_hostname(hostname, $1)
|
274
|
-
# MRI 2.2.3 (JRuby parses ASN.1 differently)
|
275
|
-
#when 7 # iPAddress in GeneralName (RFC5280)
|
276
|
-
elsif /\AIP(?: Address)?:(.*)/ =~ general_name
|
277
|
-
should_verify_common_name = false
|
278
|
-
return true if $1 == hostname
|
279
|
-
# NOTE: bellow logic makes little sense JRuby reads exts differently
|
280
|
-
# follows GENERAL_NAME_print() in x509v3/v3_alt.c
|
281
|
-
#if san.value.size == 4
|
282
|
-
# return true if san.value.unpack('C*').join('.') == hostname
|
283
|
-
#elsif san.value.size == 16
|
284
|
-
# return true if san.value.unpack('n*').map { |e| sprintf("%X", e) }.join(':') == hostname
|
285
|
-
#end
|
286
|
-
end
|
287
|
-
}
|
288
|
-
}
|
289
|
-
if should_verify_common_name
|
290
|
-
cert.subject.to_a.each{|oid, value|
|
291
|
-
if oid == "CN"
|
292
|
-
return true if verify_hostname(hostname, value)
|
293
|
-
end
|
294
|
-
}
|
295
|
-
end
|
296
|
-
return false
|
297
|
-
end
|
298
|
-
module_function :verify_certificate_identity
|
299
|
-
|
300
|
-
def verify_hostname(hostname, san) # :nodoc:
|
301
|
-
# RFC 5280, IA5String is limited to the set of ASCII characters
|
302
|
-
return false unless san.ascii_only?
|
303
|
-
return false unless hostname.ascii_only?
|
304
|
-
|
305
|
-
# See RFC 6125, section 6.4.1
|
306
|
-
# Matching is case-insensitive.
|
307
|
-
san_parts = san.downcase.split(".")
|
308
|
-
|
309
|
-
# TODO: this behavior should probably be more strict
|
310
|
-
return san == hostname if san_parts.size < 2
|
311
|
-
|
312
|
-
# Matching is case-insensitive.
|
313
|
-
host_parts = hostname.downcase.split(".")
|
314
|
-
|
315
|
-
# RFC 6125, section 6.4.3, subitem 2.
|
316
|
-
# If the wildcard character is the only character of the left-most
|
317
|
-
# label in the presented identifier, the client SHOULD NOT compare
|
318
|
-
# against anything but the left-most label of the reference
|
319
|
-
# identifier (e.g., *.example.com would match foo.example.com but
|
320
|
-
# not bar.foo.example.com or example.com).
|
321
|
-
return false unless san_parts.size == host_parts.size
|
322
|
-
|
323
|
-
# RFC 6125, section 6.4.3, subitem 1.
|
324
|
-
# The client SHOULD NOT attempt to match a presented identifier in
|
325
|
-
# which the wildcard character comprises a label other than the
|
326
|
-
# left-most label (e.g., do not match bar.*.example.net).
|
327
|
-
return false unless verify_wildcard(host_parts.shift, san_parts.shift)
|
328
|
-
|
329
|
-
san_parts.join(".") == host_parts.join(".")
|
330
|
-
end
|
331
|
-
module_function :verify_hostname
|
332
|
-
|
333
|
-
def verify_wildcard(domain_component, san_component) # :nodoc:
|
334
|
-
parts = san_component.split("*", -1)
|
335
|
-
|
336
|
-
return false if parts.size > 2
|
337
|
-
return san_component == domain_component if parts.size == 1
|
338
|
-
|
339
|
-
# RFC 6125, section 6.4.3, subitem 3.
|
340
|
-
# The client SHOULD NOT attempt to match a presented identifier
|
341
|
-
# where the wildcard character is embedded within an A-label or
|
342
|
-
# U-label of an internationalized domain name.
|
343
|
-
return false if domain_component.start_with?("xn--") && san_component != "*"
|
344
|
-
|
345
|
-
parts[0].length + parts[1].length < domain_component.length &&
|
346
|
-
domain_component.start_with?(parts[0]) &&
|
347
|
-
domain_component.end_with?(parts[1])
|
348
|
-
end
|
349
|
-
module_function :verify_wildcard
|
350
|
-
|
351
|
-
class SSLSocket
|
352
|
-
include Buffering
|
353
|
-
include SocketForwarder
|
354
|
-
|
355
|
-
# attr_reader :hostname
|
356
|
-
#
|
357
|
-
# # The underlying IO object.
|
358
|
-
# attr_reader :io
|
359
|
-
# alias :to_io :io
|
360
|
-
#
|
361
|
-
# # The SSLContext object used in this connection.
|
362
|
-
# attr_reader :context
|
363
|
-
#
|
364
|
-
# # Whether to close the underlying socket as well, when the SSL/TLS
|
365
|
-
# # connection is shut down. This defaults to +false+.
|
366
|
-
# attr_accessor :sync_close
|
367
|
-
|
368
|
-
# call-seq:
|
369
|
-
# ssl.sysclose => nil
|
370
|
-
#
|
371
|
-
# Sends "close notify" to the peer and tries to shut down the SSL
|
372
|
-
# connection gracefully.
|
373
|
-
#
|
374
|
-
# If sync_close is set to +true+, the underlying IO is also closed.
|
375
|
-
def sysclose
|
376
|
-
return if closed?
|
377
|
-
stop
|
378
|
-
io.close if sync_close
|
379
|
-
end unless method_defined? :sysclose
|
380
|
-
|
381
|
-
# call-seq:
|
382
|
-
# ssl.post_connection_check(hostname) -> true
|
383
|
-
#
|
384
|
-
# Perform hostname verification following RFC 6125.
|
385
|
-
#
|
386
|
-
# This method MUST be called after calling #connect to ensure that the
|
387
|
-
# hostname of a remote peer has been verified.
|
388
|
-
def post_connection_check(hostname)
|
389
|
-
if peer_cert.nil?
|
390
|
-
msg = "Peer verification enabled, but no certificate received."
|
391
|
-
if using_anon_cipher?
|
392
|
-
msg += " Anonymous cipher suite #{cipher[0]} was negotiated. " \
|
393
|
-
"Anonymous suites must be disabled to use peer verification."
|
394
|
-
end
|
395
|
-
raise SSLError, msg
|
396
|
-
end
|
397
|
-
|
398
|
-
unless OpenSSL::SSL.verify_certificate_identity(peer_cert, hostname)
|
399
|
-
raise SSLError, "hostname \"#{hostname}\" does not match the server certificate"
|
400
|
-
end
|
401
|
-
return true
|
402
|
-
end
|
403
|
-
|
404
|
-
# call-seq:
|
405
|
-
# ssl.session -> aSession
|
406
|
-
#
|
407
|
-
# Returns the SSLSession object currently used, or nil if the session is
|
408
|
-
# not established.
|
409
|
-
def session
|
410
|
-
SSL::Session.new(self)
|
411
|
-
rescue SSL::Session::SessionError
|
412
|
-
nil
|
413
|
-
end unless method_defined? :session # JRuby
|
414
|
-
|
415
|
-
private
|
416
|
-
|
417
|
-
def using_anon_cipher?
|
418
|
-
ctx = OpenSSL::SSL::SSLContext.new
|
419
|
-
ctx.ciphers = "aNULL"
|
420
|
-
ctx.ciphers.include?(cipher)
|
421
|
-
end
|
422
|
-
|
423
|
-
def client_cert_cb
|
424
|
-
@context.client_cert_cb
|
425
|
-
end
|
426
|
-
|
427
|
-
def tmp_dh_callback
|
428
|
-
@context.tmp_dh_callback || OpenSSL::SSL::SSLContext::DEFAULT_TMP_DH_CALLBACK
|
429
|
-
end
|
430
|
-
|
431
|
-
def tmp_ecdh_callback
|
432
|
-
@context.tmp_ecdh_callback
|
433
|
-
end
|
434
|
-
|
435
|
-
def session_new_cb
|
436
|
-
@context.session_new_cb
|
437
|
-
end
|
438
|
-
|
439
|
-
def session_get_cb
|
440
|
-
@context.session_get_cb
|
441
|
-
end
|
442
|
-
end
|
443
|
-
|
444
|
-
##
|
445
|
-
# SSLServer represents a TCP/IP server socket with Secure Sockets Layer.
|
446
|
-
class SSLServer
|
447
|
-
include SocketForwarder
|
448
|
-
# When true then #accept works exactly the same as TCPServer#accept
|
449
|
-
attr_accessor :start_immediately
|
450
|
-
|
451
|
-
# Creates a new instance of SSLServer.
|
452
|
-
# * _srv_ is an instance of TCPServer.
|
453
|
-
# * _ctx_ is an instance of OpenSSL::SSL::SSLContext.
|
454
|
-
def initialize(svr, ctx)
|
455
|
-
@svr = svr
|
456
|
-
@ctx = ctx
|
457
|
-
unless ctx.session_id_context
|
458
|
-
# see #6137 - session id may not exceed 32 bytes
|
459
|
-
prng = ::Random.new($0.hash)
|
460
|
-
session_id = prng.bytes(16).unpack('H*')[0]
|
461
|
-
@ctx.session_id_context = session_id
|
462
|
-
end
|
463
|
-
@start_immediately = true
|
464
|
-
end
|
465
|
-
|
466
|
-
# Returns the TCPServer passed to the SSLServer when initialized.
|
467
|
-
def to_io
|
468
|
-
@svr
|
469
|
-
end
|
470
|
-
|
471
|
-
# See TCPServer#listen for details.
|
472
|
-
def listen(backlog=5)
|
473
|
-
@svr.listen(backlog)
|
474
|
-
end
|
475
|
-
|
476
|
-
# See BasicSocket#shutdown for details.
|
477
|
-
def shutdown(how=Socket::SHUT_RDWR)
|
478
|
-
@svr.shutdown(how)
|
479
|
-
end
|
480
|
-
|
481
|
-
# Works similar to TCPServer#accept.
|
482
|
-
def accept
|
483
|
-
# Socket#accept returns [socket, addrinfo].
|
484
|
-
# TCPServer#accept returns a socket.
|
485
|
-
# The following comma strips addrinfo.
|
486
|
-
sock, = @svr.accept
|
487
|
-
begin
|
488
|
-
ssl = OpenSSL::SSL::SSLSocket.new(sock, @ctx)
|
489
|
-
ssl.sync_close = true
|
490
|
-
ssl.accept if @start_immediately
|
491
|
-
ssl
|
492
|
-
rescue Exception => ex
|
493
|
-
if ssl
|
494
|
-
ssl.close
|
495
|
-
else
|
496
|
-
sock.close
|
497
|
-
end
|
498
|
-
raise ex
|
499
|
-
end
|
500
|
-
end
|
501
|
-
|
502
|
-
# See IO#close for details.
|
503
|
-
def close
|
504
|
-
@svr.close
|
505
|
-
end
|
506
|
-
end
|
507
|
-
end
|
508
|
-
end
|
@@ -1,208 +0,0 @@
|
|
1
|
-
# frozen_string_literal: false
|
2
|
-
#--
|
3
|
-
# = Ruby-space definitions that completes C-space funcs for X509 and 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
|
-
module X509
|
17
|
-
# class ExtensionFactory
|
18
|
-
# def create_extension(*arg)
|
19
|
-
# if arg.size > 1
|
20
|
-
# create_ext(*arg)
|
21
|
-
# else
|
22
|
-
# send("create_ext_from_"+arg[0].class.name.downcase, arg[0])
|
23
|
-
# end
|
24
|
-
# end
|
25
|
-
#
|
26
|
-
# def create_ext_from_array(ary)
|
27
|
-
# raise ExtensionError, "unexpected array form" if ary.size > 3
|
28
|
-
# create_ext(ary[0], ary[1], ary[2])
|
29
|
-
# end
|
30
|
-
#
|
31
|
-
# def create_ext_from_string(str) # "oid = critical, value"
|
32
|
-
# oid, value = str.split(/=/, 2)
|
33
|
-
# oid.strip!
|
34
|
-
# value.strip!
|
35
|
-
# create_ext(oid, value)
|
36
|
-
# end
|
37
|
-
#
|
38
|
-
# def create_ext_from_hash(hash)
|
39
|
-
# create_ext(hash["oid"], hash["value"], hash["critical"])
|
40
|
-
# end
|
41
|
-
# end
|
42
|
-
#
|
43
|
-
# class Extension
|
44
|
-
# def ==(other)
|
45
|
-
# return false unless Extension === other
|
46
|
-
# to_der == other.to_der
|
47
|
-
# end
|
48
|
-
#
|
49
|
-
# def to_s # "oid = critical, value"
|
50
|
-
# str = self.oid
|
51
|
-
# str << " = "
|
52
|
-
# str << "critical, " if self.critical?
|
53
|
-
# str << self.value.gsub(/\n/, ", ")
|
54
|
-
# end
|
55
|
-
#
|
56
|
-
# def to_h # {"oid"=>sn|ln, "value"=>value, "critical"=>true|false}
|
57
|
-
# {"oid"=>self.oid,"value"=>self.value,"critical"=>self.critical?}
|
58
|
-
# end
|
59
|
-
#
|
60
|
-
# def to_a
|
61
|
-
# [ self.oid, self.value, self.critical? ]
|
62
|
-
# end
|
63
|
-
# end
|
64
|
-
|
65
|
-
class Name
|
66
|
-
module RFC2253DN
|
67
|
-
Special = ',=+<>#;'
|
68
|
-
HexChar = /[0-9a-fA-F]/
|
69
|
-
HexPair = /#{HexChar}#{HexChar}/
|
70
|
-
HexString = /#{HexPair}+/
|
71
|
-
Pair = /\\(?:[#{Special}]|\\|"|#{HexPair})/
|
72
|
-
StringChar = /[^\\"#{Special}]/
|
73
|
-
QuoteChar = /[^\\"]/
|
74
|
-
AttributeType = /[a-zA-Z][0-9a-zA-Z]*|[0-9]+(?:\.[0-9]+)*/
|
75
|
-
AttributeValue = /
|
76
|
-
(?!["#])((?:#{StringChar}|#{Pair})*)|
|
77
|
-
\#(#{HexString})|
|
78
|
-
"((?:#{QuoteChar}|#{Pair})*)"
|
79
|
-
/x
|
80
|
-
TypeAndValue = /\A(#{AttributeType})=#{AttributeValue}/
|
81
|
-
|
82
|
-
module_function
|
83
|
-
|
84
|
-
def expand_pair(str)
|
85
|
-
return nil unless str
|
86
|
-
return str.gsub(Pair){
|
87
|
-
pair = $&
|
88
|
-
case pair.size
|
89
|
-
when 2 then pair[1,1]
|
90
|
-
when 3 then Integer("0x#{pair[1,2]}").chr
|
91
|
-
else raise OpenSSL::X509::NameError, "invalid pair: #{str}"
|
92
|
-
end
|
93
|
-
}
|
94
|
-
end
|
95
|
-
|
96
|
-
def expand_hexstring(str)
|
97
|
-
return nil unless str
|
98
|
-
der = str.gsub(HexPair){$&.to_i(16).chr }
|
99
|
-
a1 = OpenSSL::ASN1.decode(der)
|
100
|
-
return a1.value, a1.tag
|
101
|
-
end
|
102
|
-
|
103
|
-
def expand_value(str1, str2, str3)
|
104
|
-
value = expand_pair(str1)
|
105
|
-
value, tag = expand_hexstring(str2) unless value
|
106
|
-
value = expand_pair(str3) unless value
|
107
|
-
return value, tag
|
108
|
-
end
|
109
|
-
|
110
|
-
def scan(dn)
|
111
|
-
str = dn
|
112
|
-
ary = []
|
113
|
-
while true
|
114
|
-
if md = TypeAndValue.match(str)
|
115
|
-
remain = md.post_match
|
116
|
-
type = md[1]
|
117
|
-
value, tag = expand_value(md[2], md[3], md[4]) rescue nil
|
118
|
-
if value
|
119
|
-
type_and_value = [type, value]
|
120
|
-
type_and_value.push(tag) if tag
|
121
|
-
ary.unshift(type_and_value)
|
122
|
-
if remain.length > 2 && remain[0] == ?,
|
123
|
-
str = remain[1..-1]
|
124
|
-
next
|
125
|
-
elsif remain.length > 2 && remain[0] == ?+
|
126
|
-
raise OpenSSL::X509::NameError,
|
127
|
-
"multi-valued RDN is not supported: #{dn}"
|
128
|
-
elsif remain.empty?
|
129
|
-
break
|
130
|
-
end
|
131
|
-
end
|
132
|
-
end
|
133
|
-
msg_dn = dn[0, dn.length - str.length] + " =>" + str
|
134
|
-
raise OpenSSL::X509::NameError, "malformed RDN: #{msg_dn}"
|
135
|
-
end
|
136
|
-
return ary
|
137
|
-
end
|
138
|
-
end
|
139
|
-
|
140
|
-
class << self
|
141
|
-
def parse_rfc2253(str, template=OBJECT_TYPE_TEMPLATE)
|
142
|
-
ary = OpenSSL::X509::Name::RFC2253DN.scan(str)
|
143
|
-
self.new(ary, template)
|
144
|
-
end
|
145
|
-
|
146
|
-
def parse_openssl(str, template=OBJECT_TYPE_TEMPLATE)
|
147
|
-
if str.start_with?("/")
|
148
|
-
# /A=B/C=D format
|
149
|
-
ary = str[1..-1].split("/").map { |i| i.split("=", 2) }
|
150
|
-
else
|
151
|
-
# Comma-separated
|
152
|
-
ary = str.split(",").map { |i| i.strip.split("=", 2) }
|
153
|
-
end
|
154
|
-
self.new(ary, template)
|
155
|
-
end
|
156
|
-
|
157
|
-
alias parse parse_openssl
|
158
|
-
end
|
159
|
-
|
160
|
-
def pretty_print(q)
|
161
|
-
q.object_group(self) {
|
162
|
-
q.text ' '
|
163
|
-
q.text to_s(OpenSSL::X509::Name::RFC2253)
|
164
|
-
}
|
165
|
-
end
|
166
|
-
end
|
167
|
-
|
168
|
-
# class Attribute
|
169
|
-
# def ==(other)
|
170
|
-
# return false unless Attribute === other
|
171
|
-
# to_der == other.to_der
|
172
|
-
# end
|
173
|
-
# end
|
174
|
-
|
175
|
-
class StoreContext
|
176
|
-
def cleanup
|
177
|
-
warn "(#{caller.first}) OpenSSL::X509::StoreContext#cleanup is deprecated with no replacement" if $VERBOSE
|
178
|
-
end
|
179
|
-
end
|
180
|
-
|
181
|
-
class Certificate
|
182
|
-
def pretty_print(q)
|
183
|
-
q.object_group(self) {
|
184
|
-
q.breakable
|
185
|
-
q.text 'subject='; q.pp self.subject; q.text ','; q.breakable
|
186
|
-
q.text 'issuer='; q.pp self.issuer; q.text ','; q.breakable
|
187
|
-
q.text 'serial='; q.pp self.serial; q.text ','; q.breakable
|
188
|
-
q.text 'not_before='; q.pp self.not_before; q.text ','; q.breakable
|
189
|
-
q.text 'not_after='; q.pp self.not_after
|
190
|
-
}
|
191
|
-
end
|
192
|
-
end
|
193
|
-
|
194
|
-
# class CRL
|
195
|
-
# def ==(other)
|
196
|
-
# return false unless CRL === other
|
197
|
-
# to_der == other.to_der
|
198
|
-
# end
|
199
|
-
# end
|
200
|
-
|
201
|
-
# class Request
|
202
|
-
# def ==(other)
|
203
|
-
# return false unless Request === other
|
204
|
-
# to_der == other.to_der
|
205
|
-
# end
|
206
|
-
# end
|
207
|
-
end
|
208
|
-
end
|