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,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