openssl 2.0.0.beta.1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of openssl might be problematic. Click here for more details.
- checksums.yaml +7 -0
- data/BSDL +22 -0
- data/CONTRIBUTING.md +130 -0
- data/History.md +118 -0
- data/LICENSE.txt +56 -0
- data/README.md +70 -0
- data/ext/openssl/deprecation.rb +26 -0
- data/ext/openssl/extconf.rb +158 -0
- data/ext/openssl/openssl_missing.c +173 -0
- data/ext/openssl/openssl_missing.h +244 -0
- data/ext/openssl/ossl.c +1201 -0
- data/ext/openssl/ossl.h +222 -0
- data/ext/openssl/ossl_asn1.c +1992 -0
- data/ext/openssl/ossl_asn1.h +66 -0
- data/ext/openssl/ossl_bio.c +87 -0
- data/ext/openssl/ossl_bio.h +19 -0
- data/ext/openssl/ossl_bn.c +1153 -0
- data/ext/openssl/ossl_bn.h +23 -0
- data/ext/openssl/ossl_cipher.c +1085 -0
- data/ext/openssl/ossl_cipher.h +20 -0
- data/ext/openssl/ossl_config.c +89 -0
- data/ext/openssl/ossl_config.h +19 -0
- data/ext/openssl/ossl_digest.c +453 -0
- data/ext/openssl/ossl_digest.h +20 -0
- data/ext/openssl/ossl_engine.c +580 -0
- data/ext/openssl/ossl_engine.h +19 -0
- data/ext/openssl/ossl_hmac.c +398 -0
- data/ext/openssl/ossl_hmac.h +18 -0
- data/ext/openssl/ossl_ns_spki.c +406 -0
- data/ext/openssl/ossl_ns_spki.h +19 -0
- data/ext/openssl/ossl_ocsp.c +2013 -0
- data/ext/openssl/ossl_ocsp.h +23 -0
- data/ext/openssl/ossl_pkcs12.c +259 -0
- data/ext/openssl/ossl_pkcs12.h +13 -0
- data/ext/openssl/ossl_pkcs5.c +180 -0
- data/ext/openssl/ossl_pkcs5.h +6 -0
- data/ext/openssl/ossl_pkcs7.c +1125 -0
- data/ext/openssl/ossl_pkcs7.h +20 -0
- data/ext/openssl/ossl_pkey.c +435 -0
- data/ext/openssl/ossl_pkey.h +245 -0
- data/ext/openssl/ossl_pkey_dh.c +650 -0
- data/ext/openssl/ossl_pkey_dsa.c +672 -0
- data/ext/openssl/ossl_pkey_ec.c +1899 -0
- data/ext/openssl/ossl_pkey_rsa.c +768 -0
- data/ext/openssl/ossl_rand.c +238 -0
- data/ext/openssl/ossl_rand.h +18 -0
- data/ext/openssl/ossl_ssl.c +2679 -0
- data/ext/openssl/ossl_ssl.h +41 -0
- data/ext/openssl/ossl_ssl_session.c +352 -0
- data/ext/openssl/ossl_version.h +15 -0
- data/ext/openssl/ossl_x509.c +186 -0
- data/ext/openssl/ossl_x509.h +119 -0
- data/ext/openssl/ossl_x509attr.c +328 -0
- data/ext/openssl/ossl_x509cert.c +860 -0
- data/ext/openssl/ossl_x509crl.c +565 -0
- data/ext/openssl/ossl_x509ext.c +480 -0
- data/ext/openssl/ossl_x509name.c +547 -0
- data/ext/openssl/ossl_x509req.c +492 -0
- data/ext/openssl/ossl_x509revoked.c +279 -0
- data/ext/openssl/ossl_x509store.c +846 -0
- data/ext/openssl/ruby_missing.h +32 -0
- data/lib/openssl.rb +21 -0
- data/lib/openssl/bn.rb +39 -0
- data/lib/openssl/buffering.rb +451 -0
- data/lib/openssl/cipher.rb +67 -0
- data/lib/openssl/config.rb +473 -0
- data/lib/openssl/digest.rb +78 -0
- data/lib/openssl/pkey.rb +44 -0
- data/lib/openssl/ssl.rb +416 -0
- data/lib/openssl/x509.rb +176 -0
- metadata +178 -0
@@ -0,0 +1,67 @@
|
|
1
|
+
# frozen_string_literal: false
|
2
|
+
#--
|
3
|
+
# = Ruby-space predefined Cipher 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 Cipher
|
17
|
+
%w(AES CAST5 BF DES IDEA RC2 RC4 RC5).each{|name|
|
18
|
+
klass = Class.new(Cipher){
|
19
|
+
define_method(:initialize){|*args|
|
20
|
+
cipher_name = args.inject(name){|n, arg| "#{n}-#{arg}" }
|
21
|
+
super(cipher_name.downcase)
|
22
|
+
}
|
23
|
+
}
|
24
|
+
const_set(name, klass)
|
25
|
+
}
|
26
|
+
|
27
|
+
%w(128 192 256).each{|keylen|
|
28
|
+
klass = Class.new(Cipher){
|
29
|
+
define_method(:initialize){|mode = "CBC"|
|
30
|
+
super("aes-#{keylen}-#{mode}".downcase)
|
31
|
+
}
|
32
|
+
}
|
33
|
+
const_set("AES#{keylen}", klass)
|
34
|
+
}
|
35
|
+
|
36
|
+
# call-seq:
|
37
|
+
# cipher.random_key -> key
|
38
|
+
#
|
39
|
+
# Generate a random key with OpenSSL::Random.random_bytes and sets it to
|
40
|
+
# the cipher, and returns it.
|
41
|
+
#
|
42
|
+
# You must call #encrypt or #decrypt before calling this method.
|
43
|
+
def random_key
|
44
|
+
str = OpenSSL::Random.random_bytes(self.key_len)
|
45
|
+
self.key = str
|
46
|
+
end
|
47
|
+
|
48
|
+
# call-seq:
|
49
|
+
# cipher.random_iv -> iv
|
50
|
+
#
|
51
|
+
# Generate a random IV with OpenSSL::Random.random_bytes and sets it to the
|
52
|
+
# cipher, and returns it.
|
53
|
+
#
|
54
|
+
# You must call #encrypt or #decrypt before calling this method.
|
55
|
+
def random_iv
|
56
|
+
str = OpenSSL::Random.random_bytes(self.iv_len)
|
57
|
+
self.iv = str
|
58
|
+
end
|
59
|
+
|
60
|
+
# Deprecated.
|
61
|
+
#
|
62
|
+
# This class is only provided for backwards compatibility.
|
63
|
+
# Use OpenSSL::Cipher.
|
64
|
+
class Cipher < Cipher; end
|
65
|
+
deprecate_constant :Cipher
|
66
|
+
end # Cipher
|
67
|
+
end # OpenSSL
|
@@ -0,0 +1,473 @@
|
|
1
|
+
# frozen_string_literal: false
|
2
|
+
=begin
|
3
|
+
= Ruby-space definitions that completes C-space funcs for Config
|
4
|
+
|
5
|
+
= Info
|
6
|
+
Copyright (C) 2010 Hiroshi Nakamura <nahi@ruby-lang.org>
|
7
|
+
|
8
|
+
= Licence
|
9
|
+
This program is licensed under the same licence as Ruby.
|
10
|
+
(See the file 'LICENCE'.)
|
11
|
+
|
12
|
+
=end
|
13
|
+
|
14
|
+
require 'stringio'
|
15
|
+
|
16
|
+
module OpenSSL
|
17
|
+
##
|
18
|
+
# = OpenSSL::Config
|
19
|
+
#
|
20
|
+
# Configuration for the openssl library.
|
21
|
+
#
|
22
|
+
# Many system's installation of openssl library will depend on your system
|
23
|
+
# configuration. See the value of OpenSSL::Config::DEFAULT_CONFIG_FILE for
|
24
|
+
# the location of the file for your host.
|
25
|
+
#
|
26
|
+
# See also http://www.openssl.org/docs/apps/config.html
|
27
|
+
class Config
|
28
|
+
include Enumerable
|
29
|
+
|
30
|
+
class << self
|
31
|
+
|
32
|
+
##
|
33
|
+
# Parses a given +string+ as a blob that contains configuration for openssl.
|
34
|
+
#
|
35
|
+
# If the source of the IO is a file, then consider using #parse_config.
|
36
|
+
def parse(string)
|
37
|
+
c = new()
|
38
|
+
parse_config(StringIO.new(string)).each do |section, hash|
|
39
|
+
c[section] = hash
|
40
|
+
end
|
41
|
+
c
|
42
|
+
end
|
43
|
+
|
44
|
+
##
|
45
|
+
# load is an alias to ::new
|
46
|
+
alias load new
|
47
|
+
|
48
|
+
##
|
49
|
+
# Parses the configuration data read from +io+, see also #parse.
|
50
|
+
#
|
51
|
+
# Raises a ConfigError on invalid configuration data.
|
52
|
+
def parse_config(io)
|
53
|
+
begin
|
54
|
+
parse_config_lines(io)
|
55
|
+
rescue ConfigError => e
|
56
|
+
e.message.replace("error in line #{io.lineno}: " + e.message)
|
57
|
+
raise
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def get_key_string(data, section, key) # :nodoc:
|
62
|
+
if v = data[section] && data[section][key]
|
63
|
+
return v
|
64
|
+
elsif section == 'ENV'
|
65
|
+
if v = ENV[key]
|
66
|
+
return v
|
67
|
+
end
|
68
|
+
end
|
69
|
+
if v = data['default'] && data['default'][key]
|
70
|
+
return v
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
private
|
75
|
+
|
76
|
+
def parse_config_lines(io)
|
77
|
+
section = 'default'
|
78
|
+
data = {section => {}}
|
79
|
+
while definition = get_definition(io)
|
80
|
+
definition = clear_comments(definition)
|
81
|
+
next if definition.empty?
|
82
|
+
if definition[0] == ?[
|
83
|
+
if /\[([^\]]*)\]/ =~ definition
|
84
|
+
section = $1.strip
|
85
|
+
data[section] ||= {}
|
86
|
+
else
|
87
|
+
raise ConfigError, "missing close square bracket"
|
88
|
+
end
|
89
|
+
else
|
90
|
+
if /\A([^:\s]*)(?:::([^:\s]*))?\s*=(.*)\z/ =~ definition
|
91
|
+
if $2
|
92
|
+
section = $1
|
93
|
+
key = $2
|
94
|
+
else
|
95
|
+
key = $1
|
96
|
+
end
|
97
|
+
value = unescape_value(data, section, $3)
|
98
|
+
(data[section] ||= {})[key] = value.strip
|
99
|
+
else
|
100
|
+
raise ConfigError, "missing equal sign"
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
data
|
105
|
+
end
|
106
|
+
|
107
|
+
# escape with backslash
|
108
|
+
QUOTE_REGEXP_SQ = /\A([^'\\]*(?:\\.[^'\\]*)*)'/
|
109
|
+
# escape with backslash and doubled dq
|
110
|
+
QUOTE_REGEXP_DQ = /\A([^"\\]*(?:""[^"\\]*|\\.[^"\\]*)*)"/
|
111
|
+
# escaped char map
|
112
|
+
ESCAPE_MAP = {
|
113
|
+
"r" => "\r",
|
114
|
+
"n" => "\n",
|
115
|
+
"b" => "\b",
|
116
|
+
"t" => "\t",
|
117
|
+
}
|
118
|
+
|
119
|
+
def unescape_value(data, section, value)
|
120
|
+
scanned = []
|
121
|
+
while m = value.match(/['"\\$]/)
|
122
|
+
scanned << m.pre_match
|
123
|
+
c = m[0]
|
124
|
+
value = m.post_match
|
125
|
+
case c
|
126
|
+
when "'"
|
127
|
+
if m = value.match(QUOTE_REGEXP_SQ)
|
128
|
+
scanned << m[1].gsub(/\\(.)/, '\\1')
|
129
|
+
value = m.post_match
|
130
|
+
else
|
131
|
+
break
|
132
|
+
end
|
133
|
+
when '"'
|
134
|
+
if m = value.match(QUOTE_REGEXP_DQ)
|
135
|
+
scanned << m[1].gsub(/""/, '').gsub(/\\(.)/, '\\1')
|
136
|
+
value = m.post_match
|
137
|
+
else
|
138
|
+
break
|
139
|
+
end
|
140
|
+
when "\\"
|
141
|
+
c = value.slice!(0, 1)
|
142
|
+
scanned << (ESCAPE_MAP[c] || c)
|
143
|
+
when "$"
|
144
|
+
ref, value = extract_reference(value)
|
145
|
+
refsec = section
|
146
|
+
if ref.index('::')
|
147
|
+
refsec, ref = ref.split('::', 2)
|
148
|
+
end
|
149
|
+
if v = get_key_string(data, refsec, ref)
|
150
|
+
scanned << v
|
151
|
+
else
|
152
|
+
raise ConfigError, "variable has no value"
|
153
|
+
end
|
154
|
+
else
|
155
|
+
raise 'must not reaced'
|
156
|
+
end
|
157
|
+
end
|
158
|
+
scanned << value
|
159
|
+
scanned.join
|
160
|
+
end
|
161
|
+
|
162
|
+
def extract_reference(value)
|
163
|
+
rest = ''
|
164
|
+
if m = value.match(/\(([^)]*)\)|\{([^}]*)\}/)
|
165
|
+
value = m[1] || m[2]
|
166
|
+
rest = m.post_match
|
167
|
+
elsif [?(, ?{].include?(value[0])
|
168
|
+
raise ConfigError, "no close brace"
|
169
|
+
end
|
170
|
+
if m = value.match(/[a-zA-Z0-9_]*(?:::[a-zA-Z0-9_]*)?/)
|
171
|
+
return m[0], m.post_match + rest
|
172
|
+
else
|
173
|
+
raise
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
def clear_comments(line)
|
178
|
+
# FCOMMENT
|
179
|
+
if m = line.match(/\A([\t\n\f ]*);.*\z/)
|
180
|
+
return m[1]
|
181
|
+
end
|
182
|
+
# COMMENT
|
183
|
+
scanned = []
|
184
|
+
while m = line.match(/[#'"\\]/)
|
185
|
+
scanned << m.pre_match
|
186
|
+
c = m[0]
|
187
|
+
line = m.post_match
|
188
|
+
case c
|
189
|
+
when '#'
|
190
|
+
line = nil
|
191
|
+
break
|
192
|
+
when "'", '"'
|
193
|
+
regexp = (c == "'") ? QUOTE_REGEXP_SQ : QUOTE_REGEXP_DQ
|
194
|
+
scanned << c
|
195
|
+
if m = line.match(regexp)
|
196
|
+
scanned << m[0]
|
197
|
+
line = m.post_match
|
198
|
+
else
|
199
|
+
scanned << line
|
200
|
+
line = nil
|
201
|
+
break
|
202
|
+
end
|
203
|
+
when "\\"
|
204
|
+
scanned << c
|
205
|
+
scanned << line.slice!(0, 1)
|
206
|
+
else
|
207
|
+
raise 'must not reaced'
|
208
|
+
end
|
209
|
+
end
|
210
|
+
scanned << line
|
211
|
+
scanned.join
|
212
|
+
end
|
213
|
+
|
214
|
+
def get_definition(io)
|
215
|
+
if line = get_line(io)
|
216
|
+
while /[^\\]\\\z/ =~ line
|
217
|
+
if extra = get_line(io)
|
218
|
+
line += extra
|
219
|
+
else
|
220
|
+
break
|
221
|
+
end
|
222
|
+
end
|
223
|
+
return line.strip
|
224
|
+
end
|
225
|
+
end
|
226
|
+
|
227
|
+
def get_line(io)
|
228
|
+
if line = io.gets
|
229
|
+
line.gsub(/[\r\n]*/, '')
|
230
|
+
end
|
231
|
+
end
|
232
|
+
end
|
233
|
+
|
234
|
+
##
|
235
|
+
# Creates an instance of OpenSSL's configuration class.
|
236
|
+
#
|
237
|
+
# This can be used in contexts like OpenSSL::X509::ExtensionFactory.config=
|
238
|
+
#
|
239
|
+
# If the optional +filename+ parameter is provided, then it is read in and
|
240
|
+
# parsed via #parse_config.
|
241
|
+
#
|
242
|
+
# This can raise IO exceptions based on the access, or availability of the
|
243
|
+
# file. A ConfigError exception may be raised depending on the validity of
|
244
|
+
# the data being configured.
|
245
|
+
#
|
246
|
+
def initialize(filename = nil)
|
247
|
+
@data = {}
|
248
|
+
if filename
|
249
|
+
File.open(filename.to_s) do |file|
|
250
|
+
Config.parse_config(file).each do |section, hash|
|
251
|
+
self[section] = hash
|
252
|
+
end
|
253
|
+
end
|
254
|
+
end
|
255
|
+
end
|
256
|
+
|
257
|
+
##
|
258
|
+
# Gets the value of +key+ from the given +section+
|
259
|
+
#
|
260
|
+
# Given the following configurating file being loaded:
|
261
|
+
#
|
262
|
+
# config = OpenSSL::Config.load('foo.cnf')
|
263
|
+
# #=> #<OpenSSL::Config sections=["default"]>
|
264
|
+
# puts config.to_s
|
265
|
+
# #=> [ default ]
|
266
|
+
# # foo=bar
|
267
|
+
#
|
268
|
+
# You can get a specific value from the config if you know the +section+
|
269
|
+
# and +key+ like so:
|
270
|
+
#
|
271
|
+
# config.get_value('default','foo')
|
272
|
+
# #=> "bar"
|
273
|
+
#
|
274
|
+
def get_value(section, key)
|
275
|
+
if section.nil?
|
276
|
+
raise TypeError.new('nil not allowed')
|
277
|
+
end
|
278
|
+
section = 'default' if section.empty?
|
279
|
+
get_key_string(section, key)
|
280
|
+
end
|
281
|
+
|
282
|
+
##
|
283
|
+
#
|
284
|
+
# *Deprecated*
|
285
|
+
#
|
286
|
+
# Use #get_value instead
|
287
|
+
def value(arg1, arg2 = nil) # :nodoc:
|
288
|
+
warn('Config#value is deprecated; use Config#get_value')
|
289
|
+
if arg2.nil?
|
290
|
+
section, key = 'default', arg1
|
291
|
+
else
|
292
|
+
section, key = arg1, arg2
|
293
|
+
end
|
294
|
+
section ||= 'default'
|
295
|
+
section = 'default' if section.empty?
|
296
|
+
get_key_string(section, key)
|
297
|
+
end
|
298
|
+
|
299
|
+
##
|
300
|
+
# Set the target +key+ with a given +value+ under a specific +section+.
|
301
|
+
#
|
302
|
+
# Given the following configurating file being loaded:
|
303
|
+
#
|
304
|
+
# config = OpenSSL::Config.load('foo.cnf')
|
305
|
+
# #=> #<OpenSSL::Config sections=["default"]>
|
306
|
+
# puts config.to_s
|
307
|
+
# #=> [ default ]
|
308
|
+
# # foo=bar
|
309
|
+
#
|
310
|
+
# You can set the value of +foo+ under the +default+ section to a new
|
311
|
+
# value:
|
312
|
+
#
|
313
|
+
# config.add_value('default', 'foo', 'buzz')
|
314
|
+
# #=> "buzz"
|
315
|
+
# puts config.to_s
|
316
|
+
# #=> [ default ]
|
317
|
+
# # foo=buzz
|
318
|
+
#
|
319
|
+
def add_value(section, key, value)
|
320
|
+
check_modify
|
321
|
+
(@data[section] ||= {})[key] = value
|
322
|
+
end
|
323
|
+
|
324
|
+
##
|
325
|
+
# Get a specific +section+ from the current configuration
|
326
|
+
#
|
327
|
+
# Given the following configurating file being loaded:
|
328
|
+
#
|
329
|
+
# config = OpenSSL::Config.load('foo.cnf')
|
330
|
+
# #=> #<OpenSSL::Config sections=["default"]>
|
331
|
+
# puts config.to_s
|
332
|
+
# #=> [ default ]
|
333
|
+
# # foo=bar
|
334
|
+
#
|
335
|
+
# You can get a hash of the specific section like so:
|
336
|
+
#
|
337
|
+
# config['default']
|
338
|
+
# #=> {"foo"=>"bar"}
|
339
|
+
#
|
340
|
+
def [](section)
|
341
|
+
@data[section] || {}
|
342
|
+
end
|
343
|
+
|
344
|
+
##
|
345
|
+
# Deprecated
|
346
|
+
#
|
347
|
+
# Use #[] instead
|
348
|
+
def section(name) # :nodoc:
|
349
|
+
warn('Config#section is deprecated; use Config#[]')
|
350
|
+
@data[name] || {}
|
351
|
+
end
|
352
|
+
|
353
|
+
##
|
354
|
+
# Sets a specific +section+ name with a Hash +pairs+
|
355
|
+
#
|
356
|
+
# Given the following configuration being created:
|
357
|
+
#
|
358
|
+
# config = OpenSSL::Config.new
|
359
|
+
# #=> #<OpenSSL::Config sections=[]>
|
360
|
+
# config['default'] = {"foo"=>"bar","baz"=>"buz"}
|
361
|
+
# #=> {"foo"=>"bar", "baz"=>"buz"}
|
362
|
+
# puts config.to_s
|
363
|
+
# #=> [ default ]
|
364
|
+
# # foo=bar
|
365
|
+
# # baz=buz
|
366
|
+
#
|
367
|
+
# It's important to note that this will essentially merge any of the keys
|
368
|
+
# in +pairs+ with the existing +section+. For example:
|
369
|
+
#
|
370
|
+
# config['default']
|
371
|
+
# #=> {"foo"=>"bar", "baz"=>"buz"}
|
372
|
+
# config['default'] = {"foo" => "changed"}
|
373
|
+
# #=> {"foo"=>"changed"}
|
374
|
+
# config['default']
|
375
|
+
# #=> {"foo"=>"changed", "baz"=>"buz"}
|
376
|
+
#
|
377
|
+
def []=(section, pairs)
|
378
|
+
check_modify
|
379
|
+
@data[section] ||= {}
|
380
|
+
pairs.each do |key, value|
|
381
|
+
self.add_value(section, key, value)
|
382
|
+
end
|
383
|
+
end
|
384
|
+
|
385
|
+
##
|
386
|
+
# Get the names of all sections in the current configuration
|
387
|
+
def sections
|
388
|
+
@data.keys
|
389
|
+
end
|
390
|
+
|
391
|
+
##
|
392
|
+
# Get the parsable form of the current configuration
|
393
|
+
#
|
394
|
+
# Given the following configuration being created:
|
395
|
+
#
|
396
|
+
# config = OpenSSL::Config.new
|
397
|
+
# #=> #<OpenSSL::Config sections=[]>
|
398
|
+
# config['default'] = {"foo"=>"bar","baz"=>"buz"}
|
399
|
+
# #=> {"foo"=>"bar", "baz"=>"buz"}
|
400
|
+
# puts config.to_s
|
401
|
+
# #=> [ default ]
|
402
|
+
# # foo=bar
|
403
|
+
# # baz=buz
|
404
|
+
#
|
405
|
+
# You can parse get the serialized configuration using #to_s and then parse
|
406
|
+
# it later:
|
407
|
+
#
|
408
|
+
# serialized_config = config.to_s
|
409
|
+
# # much later...
|
410
|
+
# new_config = OpenSSL::Config.parse(serialized_config)
|
411
|
+
# #=> #<OpenSSL::Config sections=["default"]>
|
412
|
+
# puts new_config
|
413
|
+
# #=> [ default ]
|
414
|
+
# foo=bar
|
415
|
+
# baz=buz
|
416
|
+
#
|
417
|
+
def to_s
|
418
|
+
ary = []
|
419
|
+
@data.keys.sort.each do |section|
|
420
|
+
ary << "[ #{section} ]\n"
|
421
|
+
@data[section].keys.each do |key|
|
422
|
+
ary << "#{key}=#{@data[section][key]}\n"
|
423
|
+
end
|
424
|
+
ary << "\n"
|
425
|
+
end
|
426
|
+
ary.join
|
427
|
+
end
|
428
|
+
|
429
|
+
##
|
430
|
+
# For a block.
|
431
|
+
#
|
432
|
+
# Receive the section and its pairs for the current configuration.
|
433
|
+
#
|
434
|
+
# config.each do |section, key, value|
|
435
|
+
# # ...
|
436
|
+
# end
|
437
|
+
#
|
438
|
+
def each
|
439
|
+
@data.each do |section, hash|
|
440
|
+
hash.each do |key, value|
|
441
|
+
yield [section, key, value]
|
442
|
+
end
|
443
|
+
end
|
444
|
+
end
|
445
|
+
|
446
|
+
##
|
447
|
+
# String representation of this configuration object, including the class
|
448
|
+
# name and its sections.
|
449
|
+
def inspect
|
450
|
+
"#<#{self.class.name} sections=#{sections.inspect}>"
|
451
|
+
end
|
452
|
+
|
453
|
+
protected
|
454
|
+
|
455
|
+
def data # :nodoc:
|
456
|
+
@data
|
457
|
+
end
|
458
|
+
|
459
|
+
private
|
460
|
+
|
461
|
+
def initialize_copy(other)
|
462
|
+
@data = other.data.dup
|
463
|
+
end
|
464
|
+
|
465
|
+
def check_modify
|
466
|
+
raise TypeError.new("Insecure: can't modify OpenSSL config") if frozen?
|
467
|
+
end
|
468
|
+
|
469
|
+
def get_key_string(section, key)
|
470
|
+
Config.get_key_string(@data, section, key)
|
471
|
+
end
|
472
|
+
end
|
473
|
+
end
|