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