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.

Files changed (71) hide show
  1. checksums.yaml +7 -0
  2. data/BSDL +22 -0
  3. data/CONTRIBUTING.md +130 -0
  4. data/History.md +118 -0
  5. data/LICENSE.txt +56 -0
  6. data/README.md +70 -0
  7. data/ext/openssl/deprecation.rb +26 -0
  8. data/ext/openssl/extconf.rb +158 -0
  9. data/ext/openssl/openssl_missing.c +173 -0
  10. data/ext/openssl/openssl_missing.h +244 -0
  11. data/ext/openssl/ossl.c +1201 -0
  12. data/ext/openssl/ossl.h +222 -0
  13. data/ext/openssl/ossl_asn1.c +1992 -0
  14. data/ext/openssl/ossl_asn1.h +66 -0
  15. data/ext/openssl/ossl_bio.c +87 -0
  16. data/ext/openssl/ossl_bio.h +19 -0
  17. data/ext/openssl/ossl_bn.c +1153 -0
  18. data/ext/openssl/ossl_bn.h +23 -0
  19. data/ext/openssl/ossl_cipher.c +1085 -0
  20. data/ext/openssl/ossl_cipher.h +20 -0
  21. data/ext/openssl/ossl_config.c +89 -0
  22. data/ext/openssl/ossl_config.h +19 -0
  23. data/ext/openssl/ossl_digest.c +453 -0
  24. data/ext/openssl/ossl_digest.h +20 -0
  25. data/ext/openssl/ossl_engine.c +580 -0
  26. data/ext/openssl/ossl_engine.h +19 -0
  27. data/ext/openssl/ossl_hmac.c +398 -0
  28. data/ext/openssl/ossl_hmac.h +18 -0
  29. data/ext/openssl/ossl_ns_spki.c +406 -0
  30. data/ext/openssl/ossl_ns_spki.h +19 -0
  31. data/ext/openssl/ossl_ocsp.c +2013 -0
  32. data/ext/openssl/ossl_ocsp.h +23 -0
  33. data/ext/openssl/ossl_pkcs12.c +259 -0
  34. data/ext/openssl/ossl_pkcs12.h +13 -0
  35. data/ext/openssl/ossl_pkcs5.c +180 -0
  36. data/ext/openssl/ossl_pkcs5.h +6 -0
  37. data/ext/openssl/ossl_pkcs7.c +1125 -0
  38. data/ext/openssl/ossl_pkcs7.h +20 -0
  39. data/ext/openssl/ossl_pkey.c +435 -0
  40. data/ext/openssl/ossl_pkey.h +245 -0
  41. data/ext/openssl/ossl_pkey_dh.c +650 -0
  42. data/ext/openssl/ossl_pkey_dsa.c +672 -0
  43. data/ext/openssl/ossl_pkey_ec.c +1899 -0
  44. data/ext/openssl/ossl_pkey_rsa.c +768 -0
  45. data/ext/openssl/ossl_rand.c +238 -0
  46. data/ext/openssl/ossl_rand.h +18 -0
  47. data/ext/openssl/ossl_ssl.c +2679 -0
  48. data/ext/openssl/ossl_ssl.h +41 -0
  49. data/ext/openssl/ossl_ssl_session.c +352 -0
  50. data/ext/openssl/ossl_version.h +15 -0
  51. data/ext/openssl/ossl_x509.c +186 -0
  52. data/ext/openssl/ossl_x509.h +119 -0
  53. data/ext/openssl/ossl_x509attr.c +328 -0
  54. data/ext/openssl/ossl_x509cert.c +860 -0
  55. data/ext/openssl/ossl_x509crl.c +565 -0
  56. data/ext/openssl/ossl_x509ext.c +480 -0
  57. data/ext/openssl/ossl_x509name.c +547 -0
  58. data/ext/openssl/ossl_x509req.c +492 -0
  59. data/ext/openssl/ossl_x509revoked.c +279 -0
  60. data/ext/openssl/ossl_x509store.c +846 -0
  61. data/ext/openssl/ruby_missing.h +32 -0
  62. data/lib/openssl.rb +21 -0
  63. data/lib/openssl/bn.rb +39 -0
  64. data/lib/openssl/buffering.rb +451 -0
  65. data/lib/openssl/cipher.rb +67 -0
  66. data/lib/openssl/config.rb +473 -0
  67. data/lib/openssl/digest.rb +78 -0
  68. data/lib/openssl/pkey.rb +44 -0
  69. data/lib/openssl/ssl.rb +416 -0
  70. data/lib/openssl/x509.rb +176 -0
  71. 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