jruby-openssl 0.7.1 → 0.7.2
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +16 -0
- data/Manifest.txt +2 -0
- data/Rakefile +1 -0
- data/lib/jopenssl.jar +0 -0
- data/lib/jopenssl/version.rb +1 -1
- data/lib/openssl.rb +1 -0
- data/lib/openssl/config.rb +316 -0
- data/test/openssl/test_cipher.rb +4 -4
- data/test/openssl/test_config.rb +290 -0
- data/test/openssl/test_ec.rb +18 -3
- data/test/openssl/test_hmac.rb +11 -9
- data/test/openssl/test_ns_spki.rb +0 -10
- data/test/openssl/test_pkcs7.rb +4 -3
- data/test/openssl/test_ssl.rb +3 -9
- data/test/openssl/test_x509cert.rb +64 -23
- data/test/openssl/test_x509crl.rb +27 -7
- data/test/openssl/test_x509ext.rb +5 -1
- data/test/openssl/test_x509name.rb +12 -4
- data/test/openssl/test_x509req.rb +27 -8
- data/test/openssl/utils.rb +12 -3
- data/test/test_certificate.rb +32 -0
- data/test/test_cipher.rb +24 -0
- data/test/test_integration.rb +9 -5
- data/test/test_x509store.rb +13 -9
- metadata +5 -3
data/History.txt
CHANGED
@@ -1,3 +1,19 @@
|
|
1
|
+
== 0.7.2
|
2
|
+
|
3
|
+
- JRUBY-5126: Ignore Cipher#reset and Cipher#iv= when it's a stream
|
4
|
+
cipher (Net::SSH compatibility)
|
5
|
+
- JRUBY-5125: let Cipher#name for 'rc4' to be 'RC4' (Net::SSH
|
6
|
+
compatibility)
|
7
|
+
- JRUBY-5096: Fixed inconsistent Certificate verification behavior
|
8
|
+
- JRUBY-5060: Avoid NPE from to_pem for empty X509 Objects
|
9
|
+
- JRUBY-5059: SSLSocket ignores Timeout (Fixed)
|
10
|
+
- JRUBY-4965: implemented OpenSSL::Config
|
11
|
+
- JRUBY-5023: make Certificate#signature_algorithm return correct algo
|
12
|
+
name; "sha1WithRSAEncryption" instead of "SHA1"
|
13
|
+
- JRUBY-5024: let HMAC.new accept a String as a digest name
|
14
|
+
- JRUBY-5018: SSLSocket holds selectors, keys, preventing quick
|
15
|
+
cleanup of resources when dereferenced
|
16
|
+
|
1
17
|
== 0.7.1
|
2
18
|
|
3
19
|
- NOTE: Now BouncyCastle jars has moved out to its own gem
|
data/Manifest.txt
CHANGED
@@ -12,6 +12,7 @@ lib/jopenssl/version.rb
|
|
12
12
|
lib/openssl/bn.rb
|
13
13
|
lib/openssl/buffering.rb
|
14
14
|
lib/openssl/cipher.rb
|
15
|
+
lib/openssl/config.rb
|
15
16
|
lib/openssl/digest.rb
|
16
17
|
lib/openssl/dummy.rb
|
17
18
|
lib/openssl/dummyssl.rb
|
@@ -86,6 +87,7 @@ test/java/test_java_smime.rb
|
|
86
87
|
test/openssl/ssl_server.rb
|
87
88
|
test/openssl/test_asn1.rb
|
88
89
|
test/openssl/test_cipher.rb
|
90
|
+
test/openssl/test_config.rb
|
89
91
|
test/openssl/test_digest.rb
|
90
92
|
test/openssl/test_ec.rb
|
91
93
|
test/openssl/test_hmac.rb
|
data/Rakefile
CHANGED
@@ -53,6 +53,7 @@ require File.dirname(__FILE__) + "/lib/jopenssl/version"
|
|
53
53
|
begin
|
54
54
|
require 'hoe'
|
55
55
|
Hoe.plugin :gemcutter
|
56
|
+
Hoe.add_include_dirs('build_lib')
|
56
57
|
hoe = Hoe.spec("jruby-openssl") do |p|
|
57
58
|
p.version = Jopenssl::Version::VERSION
|
58
59
|
p.rubyforge_name = "jruby-extras"
|
data/lib/jopenssl.jar
CHANGED
Binary file
|
data/lib/jopenssl/version.rb
CHANGED
data/lib/openssl.rb
CHANGED
@@ -0,0 +1,316 @@
|
|
1
|
+
=begin
|
2
|
+
= Ruby-space definitions that completes C-space funcs for Config
|
3
|
+
|
4
|
+
= Info
|
5
|
+
Copyright (C) 2010 Hiroshi Nakamura <nahi@ruby-lang.org>
|
6
|
+
|
7
|
+
= Licence
|
8
|
+
This program is licenced under the same licence as Ruby.
|
9
|
+
(See the file 'LICENCE'.)
|
10
|
+
|
11
|
+
=end
|
12
|
+
|
13
|
+
##
|
14
|
+
# Should we care what if somebody require this file directly?
|
15
|
+
#require 'openssl'
|
16
|
+
require 'stringio'
|
17
|
+
|
18
|
+
module OpenSSL
|
19
|
+
class Config
|
20
|
+
include Enumerable
|
21
|
+
|
22
|
+
class << self
|
23
|
+
def parse(str)
|
24
|
+
c = new()
|
25
|
+
parse_config(StringIO.new(str)).each do |section, hash|
|
26
|
+
c[section] = hash
|
27
|
+
end
|
28
|
+
c
|
29
|
+
end
|
30
|
+
|
31
|
+
alias load new
|
32
|
+
|
33
|
+
def parse_config(io)
|
34
|
+
begin
|
35
|
+
parse_config_lines(io)
|
36
|
+
rescue ConfigError => e
|
37
|
+
e.message.replace("error in line #{io.lineno}: " + e.message)
|
38
|
+
raise
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def get_key_string(data, section, key) # :nodoc:
|
43
|
+
if v = data[section] && data[section][key]
|
44
|
+
return v
|
45
|
+
elsif section == 'ENV'
|
46
|
+
if v = ENV[key]
|
47
|
+
return v
|
48
|
+
end
|
49
|
+
end
|
50
|
+
if v = data['default'] && data['default'][key]
|
51
|
+
return v
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
private
|
56
|
+
|
57
|
+
def parse_config_lines(io)
|
58
|
+
section = 'default'
|
59
|
+
data = {section => {}}
|
60
|
+
while definition = get_definition(io)
|
61
|
+
definition = clear_comments(definition)
|
62
|
+
next if definition.empty?
|
63
|
+
if definition[0] == ?[
|
64
|
+
if /\[([^\]]*)\]/ =~ definition
|
65
|
+
section = $1.strip
|
66
|
+
data[section] ||= {}
|
67
|
+
else
|
68
|
+
raise ConfigError, "missing close square bracket"
|
69
|
+
end
|
70
|
+
else
|
71
|
+
if /\A([^:\s]*)(?:::([^:\s]*))?\s*=(.*)\z/ =~ definition
|
72
|
+
if $2
|
73
|
+
section = $1
|
74
|
+
key = $2
|
75
|
+
else
|
76
|
+
key = $1
|
77
|
+
end
|
78
|
+
value = unescape_value(data, section, $3)
|
79
|
+
(data[section] ||= {})[key] = value.strip
|
80
|
+
else
|
81
|
+
raise ConfigError, "missing equal sign"
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
data
|
86
|
+
end
|
87
|
+
|
88
|
+
# escape with backslash
|
89
|
+
QUOTE_REGEXP_SQ = /\A([^'\\]*(?:\\.[^'\\]*)*)'/
|
90
|
+
# escape with backslash and doubled dq
|
91
|
+
QUOTE_REGEXP_DQ = /\A([^"\\]*(?:""[^"\\]*|\\.[^"\\]*)*)"/
|
92
|
+
# escaped char map
|
93
|
+
ESCAPE_MAP = {
|
94
|
+
"r" => "\r",
|
95
|
+
"n" => "\n",
|
96
|
+
"b" => "\b",
|
97
|
+
"t" => "\t",
|
98
|
+
}
|
99
|
+
|
100
|
+
def unescape_value(data, section, value)
|
101
|
+
scanned = []
|
102
|
+
while m = value.match(/['"\\$]/)
|
103
|
+
scanned << m.pre_match
|
104
|
+
c = m[0]
|
105
|
+
value = m.post_match
|
106
|
+
case c
|
107
|
+
when "'"
|
108
|
+
if m = value.match(QUOTE_REGEXP_SQ)
|
109
|
+
scanned << m[1].gsub(/\\(.)/, '\\1')
|
110
|
+
value = m.post_match
|
111
|
+
else
|
112
|
+
break
|
113
|
+
end
|
114
|
+
when '"'
|
115
|
+
if m = value.match(QUOTE_REGEXP_DQ)
|
116
|
+
scanned << m[1].gsub(/""/, '').gsub(/\\(.)/, '\\1')
|
117
|
+
value = m.post_match
|
118
|
+
else
|
119
|
+
break
|
120
|
+
end
|
121
|
+
when "\\"
|
122
|
+
c = value.slice!(0, 1)
|
123
|
+
scanned << (ESCAPE_MAP[c] || c)
|
124
|
+
when "$"
|
125
|
+
ref, value = extract_reference(value)
|
126
|
+
refsec = section
|
127
|
+
if ref.index('::')
|
128
|
+
refsec, ref = ref.split('::', 2)
|
129
|
+
end
|
130
|
+
if v = get_key_string(data, refsec, ref)
|
131
|
+
scanned << v
|
132
|
+
else
|
133
|
+
raise ConfigError, "variable has no value"
|
134
|
+
end
|
135
|
+
else
|
136
|
+
raise 'must not reaced'
|
137
|
+
end
|
138
|
+
end
|
139
|
+
scanned << value
|
140
|
+
scanned.join
|
141
|
+
end
|
142
|
+
|
143
|
+
def extract_reference(value)
|
144
|
+
rest = ''
|
145
|
+
if m = value.match(/\(([^)]*)\)|\{([^}]*)\}/)
|
146
|
+
value = m[1] || m[2]
|
147
|
+
rest = m.post_match
|
148
|
+
elsif [?(, ?{].include?(value[0])
|
149
|
+
raise ConfigError, "no close brace"
|
150
|
+
end
|
151
|
+
if m = value.match(/[a-zA-Z0-9_]*(?:::[a-zA-Z0-9_]*)?/)
|
152
|
+
return m[0], m.post_match + rest
|
153
|
+
else
|
154
|
+
raise
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
def clear_comments(line)
|
159
|
+
# FCOMMENT
|
160
|
+
if m = line.match(/\A([\t\n\f ]*);.*\z/)
|
161
|
+
return m[1]
|
162
|
+
end
|
163
|
+
# COMMENT
|
164
|
+
scanned = []
|
165
|
+
while m = line.match(/[#'"\\]/)
|
166
|
+
scanned << m.pre_match
|
167
|
+
c = m[0]
|
168
|
+
line = m.post_match
|
169
|
+
case c
|
170
|
+
when '#'
|
171
|
+
line = nil
|
172
|
+
break
|
173
|
+
when "'", '"'
|
174
|
+
regexp = (c == "'") ? QUOTE_REGEXP_SQ : QUOTE_REGEXP_DQ
|
175
|
+
scanned << c
|
176
|
+
if m = line.match(regexp)
|
177
|
+
scanned << m[0]
|
178
|
+
line = m.post_match
|
179
|
+
else
|
180
|
+
scanned << line
|
181
|
+
line = nil
|
182
|
+
break
|
183
|
+
end
|
184
|
+
when "\\"
|
185
|
+
scanned << c
|
186
|
+
scanned << line.slice!(0, 1)
|
187
|
+
else
|
188
|
+
raise 'must not reaced'
|
189
|
+
end
|
190
|
+
end
|
191
|
+
scanned << line
|
192
|
+
scanned.join
|
193
|
+
end
|
194
|
+
|
195
|
+
def get_definition(io)
|
196
|
+
if line = get_line(io)
|
197
|
+
while /[^\\]\\\z/ =~ line
|
198
|
+
if extra = get_line(io)
|
199
|
+
line += extra
|
200
|
+
else
|
201
|
+
break
|
202
|
+
end
|
203
|
+
end
|
204
|
+
return line.strip
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
208
|
+
def get_line(io)
|
209
|
+
if line = io.gets
|
210
|
+
line.gsub(/[\r\n]*/, '')
|
211
|
+
end
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
215
|
+
def initialize(filename = nil)
|
216
|
+
@data = {}
|
217
|
+
if filename
|
218
|
+
File.open(filename.to_s) do |file|
|
219
|
+
Config.parse_config(file).each do |section, hash|
|
220
|
+
self[section] = hash
|
221
|
+
end
|
222
|
+
end
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
226
|
+
def get_value(section, key)
|
227
|
+
if section.nil?
|
228
|
+
raise TypeError.new('nil not allowed')
|
229
|
+
end
|
230
|
+
section = 'default' if section.empty?
|
231
|
+
get_key_string(section, key)
|
232
|
+
end
|
233
|
+
|
234
|
+
def value(arg1, arg2 = nil)
|
235
|
+
warn('Config#value is deprecated; use Config#get_value')
|
236
|
+
if arg2.nil?
|
237
|
+
section, key = 'default', arg1
|
238
|
+
else
|
239
|
+
section, key = arg1, arg2
|
240
|
+
end
|
241
|
+
section ||= 'default'
|
242
|
+
section = 'default' if section.empty?
|
243
|
+
get_key_string(section, key)
|
244
|
+
end
|
245
|
+
|
246
|
+
def add_value(section, key, value)
|
247
|
+
check_modify
|
248
|
+
(@data[section] ||= {})[key] = value
|
249
|
+
end
|
250
|
+
|
251
|
+
def [](section)
|
252
|
+
@data[section] || {}
|
253
|
+
end
|
254
|
+
|
255
|
+
def section(name)
|
256
|
+
warn('Config#section is deprecated; use Config#[]')
|
257
|
+
@data[name] || {}
|
258
|
+
end
|
259
|
+
|
260
|
+
def []=(section, pairs)
|
261
|
+
check_modify
|
262
|
+
@data[section] ||= {}
|
263
|
+
pairs.each do |key, value|
|
264
|
+
self.add_value(section, key, value)
|
265
|
+
end
|
266
|
+
end
|
267
|
+
|
268
|
+
def sections
|
269
|
+
@data.keys
|
270
|
+
end
|
271
|
+
|
272
|
+
def to_s
|
273
|
+
ary = []
|
274
|
+
@data.keys.sort.each do |section|
|
275
|
+
ary << "[ #{section} ]\n"
|
276
|
+
@data[section].keys.each do |key|
|
277
|
+
ary << "#{key}=#{@data[section][key]}\n"
|
278
|
+
end
|
279
|
+
ary << "\n"
|
280
|
+
end
|
281
|
+
ary.join
|
282
|
+
end
|
283
|
+
|
284
|
+
def each
|
285
|
+
@data.each do |section, hash|
|
286
|
+
hash.each do |key, value|
|
287
|
+
yield [section, key, value]
|
288
|
+
end
|
289
|
+
end
|
290
|
+
end
|
291
|
+
|
292
|
+
def inspect
|
293
|
+
"#<#{self.class.name} sections=#{sections.inspect}>"
|
294
|
+
end
|
295
|
+
|
296
|
+
protected
|
297
|
+
|
298
|
+
def data
|
299
|
+
@data
|
300
|
+
end
|
301
|
+
|
302
|
+
private
|
303
|
+
|
304
|
+
def initialize_copy(other)
|
305
|
+
@data = other.data.dup
|
306
|
+
end
|
307
|
+
|
308
|
+
def check_modify
|
309
|
+
raise TypeError.new("Insecure: can't modify OpenSSL config") if frozen?
|
310
|
+
end
|
311
|
+
|
312
|
+
def get_key_string(section, key)
|
313
|
+
Config.get_key_string(@data, section, key)
|
314
|
+
end
|
315
|
+
end
|
316
|
+
end
|
data/test/openssl/test_cipher.rb
CHANGED
@@ -101,13 +101,13 @@ class OpenSSL::TestCipher < Test::Unit::TestCase
|
|
101
101
|
assert_equal(@data, decrypted_data[0...@data.size])
|
102
102
|
end
|
103
103
|
|
104
|
-
if
|
104
|
+
if RUBY_PLATFORM =~ /java/
|
105
105
|
# JRuby extension - using Java padding types
|
106
|
-
|
106
|
+
|
107
107
|
def test_disable_padding_javastyle
|
108
108
|
test_disable_padding('NoPadding')
|
109
109
|
end
|
110
|
-
|
110
|
+
|
111
111
|
def test_iso10126_padding
|
112
112
|
@c1.encrypt
|
113
113
|
@c1.key = @key
|
@@ -176,7 +176,7 @@ class OpenSSL::TestCipher < Test::Unit::TestCase
|
|
176
176
|
c1.key = key
|
177
177
|
e = c1.update data
|
178
178
|
e << c1.final
|
179
|
-
|
179
|
+
|
180
180
|
c2 = OpenSSL::Cipher::Cipher.new("DES-CBC")
|
181
181
|
c2.padding = 0
|
182
182
|
c2.iv = "0" * 8
|
@@ -0,0 +1,290 @@
|
|
1
|
+
require 'openssl'
|
2
|
+
require "test/unit"
|
3
|
+
require 'tempfile'
|
4
|
+
require File.join(File.dirname(__FILE__), "utils.rb")
|
5
|
+
|
6
|
+
class OpenSSL::TestConfig < Test::Unit::TestCase
|
7
|
+
def setup
|
8
|
+
file = Tempfile.open("openssl.cnf")
|
9
|
+
file << <<__EOD__
|
10
|
+
HOME = .
|
11
|
+
[ ca ]
|
12
|
+
default_ca = CA_default
|
13
|
+
[ CA_default ]
|
14
|
+
dir = ./demoCA
|
15
|
+
certs = ./certs
|
16
|
+
__EOD__
|
17
|
+
file.close
|
18
|
+
@it = OpenSSL::Config.new(file.path)
|
19
|
+
end
|
20
|
+
|
21
|
+
def TODO_test_constants
|
22
|
+
assert(defined?(OpenSSL::Config::DEFAULT_CONFIG_FILE))
|
23
|
+
assert_nothing_raised do
|
24
|
+
OpenSSL::Config.load(OpenSSL::Config::DEFAULT_CONFIG_FILE)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_s_parse
|
29
|
+
c = OpenSSL::Config.parse('')
|
30
|
+
assert_equal("[ default ]\n\n", c.to_s)
|
31
|
+
c = OpenSSL::Config.parse(@it.to_s)
|
32
|
+
assert_equal(['CA_default', 'ca', 'default'], c.sections.sort)
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_s_parse_format
|
36
|
+
c = OpenSSL::Config.parse(<<__EOC__)
|
37
|
+
baz =qx\t # "baz = qx"
|
38
|
+
|
39
|
+
foo::bar = baz # shortcut section::key format
|
40
|
+
default::bar = baz # ditto
|
41
|
+
a=\t \t # "a = ": trailing spaces are ignored
|
42
|
+
=b # " = b": empty key
|
43
|
+
=c # " = c": empty key (override the above line)
|
44
|
+
d= # "c = ": trailing comment is ignored
|
45
|
+
|
46
|
+
sq = 'foo''b\\'ar'
|
47
|
+
dq ="foo""''\\""
|
48
|
+
dq2 = foo""bar
|
49
|
+
esc=a\\r\\n\\b\\tb
|
50
|
+
foo\\bar = foo\\b\\\\ar
|
51
|
+
foo\\bar::foo\\bar = baz
|
52
|
+
[default1 default2]\t\t # space is allowed in section name
|
53
|
+
fo =b ar # space allowed in value
|
54
|
+
[emptysection]
|
55
|
+
[doller ]
|
56
|
+
foo=bar
|
57
|
+
bar = $(foo)
|
58
|
+
baz = 123$(default::bar)456${foo}798
|
59
|
+
qux = ${baz}
|
60
|
+
quxx = $qux.$qux
|
61
|
+
__EOC__
|
62
|
+
assert_equal(['default', 'default1 default2', 'doller', 'emptysection', 'foo', 'foo\\bar'], c.sections.sort)
|
63
|
+
assert_equal(['', 'a', 'bar', 'baz', 'd', 'dq', 'dq2', 'esc', 'foo\\bar', 'sq'], c['default'].keys.sort)
|
64
|
+
assert_equal('c', c['default'][''])
|
65
|
+
assert_equal('', c['default']['a'])
|
66
|
+
assert_equal('qx', c['default']['baz'])
|
67
|
+
assert_equal('', c['default']['d'])
|
68
|
+
assert_equal('baz', c['default']['bar'])
|
69
|
+
assert_equal("foob'ar", c['default']['sq'])
|
70
|
+
assert_equal("foo''\"", c['default']['dq'])
|
71
|
+
assert_equal("foobar", c['default']['dq2'])
|
72
|
+
assert_equal("a\r\n\b\tb", c['default']['esc'])
|
73
|
+
assert_equal("foo\b\\ar", c['default']['foo\\bar'])
|
74
|
+
assert_equal('baz', c['foo']['bar'])
|
75
|
+
assert_equal('baz', c['foo\\bar']['foo\\bar'])
|
76
|
+
assert_equal('b ar', c['default1 default2']['fo'])
|
77
|
+
|
78
|
+
# dolloer
|
79
|
+
assert_equal('bar', c['doller']['foo'])
|
80
|
+
assert_equal('bar', c['doller']['bar'])
|
81
|
+
assert_equal('123baz456bar798', c['doller']['baz'])
|
82
|
+
assert_equal('123baz456bar798', c['doller']['qux'])
|
83
|
+
assert_equal('123baz456bar798.123baz456bar798', c['doller']['quxx'])
|
84
|
+
|
85
|
+
excn = assert_raise(OpenSSL::ConfigError) do
|
86
|
+
OpenSSL::Config.parse("foo = $bar")
|
87
|
+
end
|
88
|
+
assert_equal("error in line 1: variable has no value", excn.message)
|
89
|
+
|
90
|
+
excn = assert_raise(OpenSSL::ConfigError) do
|
91
|
+
OpenSSL::Config.parse("foo = $(bar")
|
92
|
+
end
|
93
|
+
assert_equal("error in line 1: no close brace", excn.message)
|
94
|
+
|
95
|
+
excn = assert_raise(OpenSSL::ConfigError) do
|
96
|
+
OpenSSL::Config.parse("f o =b ar # no space in key")
|
97
|
+
end
|
98
|
+
assert_equal("error in line 1: missing equal sign", excn.message)
|
99
|
+
|
100
|
+
excn = assert_raise(OpenSSL::ConfigError) do
|
101
|
+
OpenSSL::Config.parse(<<__EOC__)
|
102
|
+
# comment 1 # comments
|
103
|
+
|
104
|
+
#
|
105
|
+
# comment 2
|
106
|
+
\t#comment 3
|
107
|
+
[second ]\t
|
108
|
+
[third # section not terminated
|
109
|
+
__EOC__
|
110
|
+
end
|
111
|
+
assert_equal("error in line 7: missing close square bracket", excn.message)
|
112
|
+
end
|
113
|
+
|
114
|
+
def test_s_load
|
115
|
+
# alias of new
|
116
|
+
c = OpenSSL::Config.load
|
117
|
+
assert_equal("", c.to_s)
|
118
|
+
assert_equal([], c.sections)
|
119
|
+
#
|
120
|
+
file = Tempfile.open("openssl.cnf")
|
121
|
+
file.close
|
122
|
+
c = OpenSSL::Config.load(file.path)
|
123
|
+
assert_equal("[ default ]\n\n", c.to_s)
|
124
|
+
assert_equal(['default'], c.sections)
|
125
|
+
end
|
126
|
+
|
127
|
+
def test_initialize
|
128
|
+
c = OpenSSL::Config.new
|
129
|
+
assert_equal("", c.to_s)
|
130
|
+
assert_equal([], c.sections)
|
131
|
+
end
|
132
|
+
|
133
|
+
def test_initialize_with_empty_file
|
134
|
+
file = Tempfile.open("openssl.cnf")
|
135
|
+
file.close
|
136
|
+
c = OpenSSL::Config.new(file.path)
|
137
|
+
assert_equal("[ default ]\n\n", c.to_s)
|
138
|
+
assert_equal(['default'], c.sections)
|
139
|
+
end
|
140
|
+
|
141
|
+
def test_initialize_with_example_file
|
142
|
+
assert_equal(['CA_default', 'ca', 'default'], @it.sections.sort)
|
143
|
+
end
|
144
|
+
|
145
|
+
def test_get_value
|
146
|
+
assert_equal('CA_default', @it.get_value('ca', 'default_ca'))
|
147
|
+
assert_equal(nil, @it.get_value('ca', 'no such key'))
|
148
|
+
assert_equal(nil, @it.get_value('no such section', 'no such key'))
|
149
|
+
assert_equal('.', @it.get_value('', 'HOME'))
|
150
|
+
assert_raise(TypeError) do
|
151
|
+
@it.get_value(nil, 'HOME') # not allowed unlike Config#value
|
152
|
+
end
|
153
|
+
# fallback to 'default' ugly...
|
154
|
+
assert_equal('.', @it.get_value('unknown', 'HOME'))
|
155
|
+
end
|
156
|
+
|
157
|
+
def test_get_value_ENV
|
158
|
+
key = ENV.keys.first
|
159
|
+
assert_not_nil(key) # make sure we have at least one ENV var.
|
160
|
+
assert_equal(ENV[key], @it.get_value('ENV', key))
|
161
|
+
end
|
162
|
+
|
163
|
+
def test_value
|
164
|
+
# supress deprecation warnings
|
165
|
+
OpenSSL::TestUtils.silent do
|
166
|
+
assert_equal('CA_default', @it.value('ca', 'default_ca'))
|
167
|
+
assert_equal(nil, @it.value('ca', 'no such key'))
|
168
|
+
assert_equal(nil, @it.value('no such section', 'no such key'))
|
169
|
+
assert_equal('.', @it.value('', 'HOME'))
|
170
|
+
assert_equal('.', @it.value(nil, 'HOME'))
|
171
|
+
assert_equal('.', @it.value('HOME'))
|
172
|
+
# fallback to 'default' ugly...
|
173
|
+
assert_equal('.', @it.value('unknown', 'HOME'))
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
def test_value_ENV
|
178
|
+
OpenSSL::TestUtils.silent do
|
179
|
+
key = ENV.keys.first
|
180
|
+
assert_not_nil(key) # make sure we have at least one ENV var.
|
181
|
+
assert_equal(ENV[key], @it.value('ENV', key))
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
def test_aref
|
186
|
+
assert_equal({'HOME' => '.'}, @it['default'])
|
187
|
+
assert_equal({'dir' => './demoCA', 'certs' => './certs'}, @it['CA_default'])
|
188
|
+
assert_equal({}, @it['no_such_section'])
|
189
|
+
assert_equal({}, @it[''])
|
190
|
+
end
|
191
|
+
|
192
|
+
def test_section
|
193
|
+
OpenSSL::TestUtils.silent do
|
194
|
+
assert_equal({'HOME' => '.'}, @it.section('default'))
|
195
|
+
assert_equal({'dir' => './demoCA', 'certs' => './certs'}, @it.section('CA_default'))
|
196
|
+
assert_equal({}, @it.section('no_such_section'))
|
197
|
+
assert_equal({}, @it.section(''))
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
def test_sections
|
202
|
+
assert_equal(['CA_default', 'ca', 'default'], @it.sections.sort)
|
203
|
+
@it['new_section'] = {'foo' => 'bar'}
|
204
|
+
assert_equal(['CA_default', 'ca', 'default', 'new_section'], @it.sections.sort)
|
205
|
+
@it['new_section'] = {}
|
206
|
+
assert_equal(['CA_default', 'ca', 'default', 'new_section'], @it.sections.sort)
|
207
|
+
end
|
208
|
+
|
209
|
+
def test_add_value
|
210
|
+
c = OpenSSL::Config.new
|
211
|
+
assert_equal("", c.to_s)
|
212
|
+
# add key
|
213
|
+
c.add_value('default', 'foo', 'bar')
|
214
|
+
assert_equal("[ default ]\nfoo=bar\n\n", c.to_s)
|
215
|
+
# add another key
|
216
|
+
c.add_value('default', 'baz', 'qux')
|
217
|
+
assert_equal('bar', c['default']['foo'])
|
218
|
+
assert_equal('qux', c['default']['baz'])
|
219
|
+
# update the value
|
220
|
+
c.add_value('default', 'baz', 'quxxx')
|
221
|
+
assert_equal('bar', c['default']['foo'])
|
222
|
+
assert_equal('quxxx', c['default']['baz'])
|
223
|
+
# add section and key
|
224
|
+
c.add_value('section', 'foo', 'bar')
|
225
|
+
assert_equal('bar', c['default']['foo'])
|
226
|
+
assert_equal('quxxx', c['default']['baz'])
|
227
|
+
assert_equal('bar', c['section']['foo'])
|
228
|
+
end
|
229
|
+
|
230
|
+
def test_aset
|
231
|
+
@it['foo'] = {'bar' => 'baz'}
|
232
|
+
assert_equal({'bar' => 'baz'}, @it['foo'])
|
233
|
+
@it['foo'] = {'bar' => 'qux', 'baz' => 'quxx'}
|
234
|
+
assert_equal({'bar' => 'qux', 'baz' => 'quxx'}, @it['foo'])
|
235
|
+
|
236
|
+
# OpenSSL::Config is add only for now.
|
237
|
+
@it['foo'] = {'foo' => 'foo'}
|
238
|
+
assert_equal({'foo' => 'foo', 'bar' => 'qux', 'baz' => 'quxx'}, @it['foo'])
|
239
|
+
# you cannot override or remove any section and key.
|
240
|
+
@it['foo'] = {}
|
241
|
+
assert_equal({'foo' => 'foo', 'bar' => 'qux', 'baz' => 'quxx'}, @it['foo'])
|
242
|
+
end
|
243
|
+
|
244
|
+
def test_each
|
245
|
+
# each returns [section, key, value] array.
|
246
|
+
ary = @it.map { |e| e }.sort { |a, b| a[0] <=> b[0] }
|
247
|
+
assert_equal(4, ary.size)
|
248
|
+
assert_equal('CA_default', ary[0][0])
|
249
|
+
assert_equal('CA_default', ary[1][0])
|
250
|
+
assert_equal(["ca", "default_ca", "CA_default"], ary[2])
|
251
|
+
assert_equal(["default", "HOME", "."], ary[3])
|
252
|
+
end
|
253
|
+
|
254
|
+
def test_to_s
|
255
|
+
c = OpenSSL::Config.parse("[empty]\n")
|
256
|
+
assert_equal("[ default ]\n\n[ empty ]\n\n", c.to_s)
|
257
|
+
end
|
258
|
+
|
259
|
+
def test_inspect
|
260
|
+
assert_match(/#<OpenSSL::Config sections=\[.*\]>/, @it.inspect)
|
261
|
+
end
|
262
|
+
|
263
|
+
def test_freeze
|
264
|
+
c = OpenSSL::Config.new
|
265
|
+
c['foo'] = [['key', 'value']]
|
266
|
+
c.freeze
|
267
|
+
|
268
|
+
# [ruby-core:18377]
|
269
|
+
# RuntimeError for 1.9, TypeError for 1.8
|
270
|
+
assert_raise(TypeError, /frozen/) do
|
271
|
+
c['foo'] = [['key', 'wrong']]
|
272
|
+
end
|
273
|
+
end
|
274
|
+
|
275
|
+
def test_dup
|
276
|
+
assert(!@it.sections.empty?)
|
277
|
+
c = @it.dup
|
278
|
+
assert_equal(@it.sections.sort, c.sections.sort)
|
279
|
+
@it['newsection'] = {'a' => 'b'}
|
280
|
+
assert_not_equal(@it.sections.sort, c.sections.sort)
|
281
|
+
end
|
282
|
+
|
283
|
+
def test_clone
|
284
|
+
assert(!@it.sections.empty?)
|
285
|
+
c = @it.clone
|
286
|
+
assert_equal(@it.sections.sort, c.sections.sort)
|
287
|
+
@it['newsection'] = {'a' => 'b'}
|
288
|
+
assert_not_equal(@it.sections.sort, c.sections.sort)
|
289
|
+
end
|
290
|
+
end
|