openssl 2.0.9 → 2.1.0.beta1

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 (60) hide show
  1. checksums.yaml +5 -5
  2. data/History.md +28 -69
  3. data/README.md +1 -1
  4. data/ext/openssl/deprecation.rb +0 -3
  5. data/ext/openssl/extconf.rb +8 -52
  6. data/ext/openssl/openssl_missing.c +0 -67
  7. data/ext/openssl/openssl_missing.h +3 -50
  8. data/ext/openssl/ossl.c +81 -74
  9. data/ext/openssl/ossl.h +14 -27
  10. data/ext/openssl/ossl_asn1.c +287 -374
  11. data/ext/openssl/ossl_asn1.h +0 -4
  12. data/ext/openssl/ossl_bio.c +5 -20
  13. data/ext/openssl/ossl_bio.h +0 -2
  14. data/ext/openssl/ossl_bn.c +70 -28
  15. data/ext/openssl/ossl_cipher.c +18 -42
  16. data/ext/openssl/ossl_cipher.h +1 -1
  17. data/ext/openssl/ossl_digest.c +8 -12
  18. data/ext/openssl/ossl_digest.h +1 -1
  19. data/ext/openssl/ossl_engine.c +47 -47
  20. data/ext/openssl/ossl_hmac.c +19 -22
  21. data/ext/openssl/ossl_kdf.c +221 -0
  22. data/ext/openssl/ossl_kdf.h +6 -0
  23. data/ext/openssl/ossl_ns_spki.c +17 -21
  24. data/ext/openssl/ossl_ocsp.c +85 -80
  25. data/ext/openssl/ossl_pkcs12.c +15 -21
  26. data/ext/openssl/ossl_pkcs7.c +8 -21
  27. data/ext/openssl/ossl_pkey.c +24 -48
  28. data/ext/openssl/ossl_pkey.h +1 -6
  29. data/ext/openssl/ossl_pkey_dh.c +11 -11
  30. data/ext/openssl/ossl_pkey_dsa.c +16 -22
  31. data/ext/openssl/ossl_pkey_ec.c +43 -56
  32. data/ext/openssl/ossl_pkey_rsa.c +19 -19
  33. data/ext/openssl/ossl_rand.c +12 -12
  34. data/ext/openssl/ossl_ssl.c +291 -243
  35. data/ext/openssl/ossl_ssl.h +0 -5
  36. data/ext/openssl/ossl_ssl_session.c +7 -9
  37. data/ext/openssl/ossl_version.h +1 -1
  38. data/ext/openssl/ossl_x509.c +0 -15
  39. data/ext/openssl/ossl_x509.h +0 -7
  40. data/ext/openssl/ossl_x509attr.c +3 -7
  41. data/ext/openssl/ossl_x509cert.c +17 -54
  42. data/ext/openssl/ossl_x509crl.c +15 -25
  43. data/ext/openssl/ossl_x509ext.c +9 -14
  44. data/ext/openssl/ossl_x509name.c +76 -41
  45. data/ext/openssl/ossl_x509req.c +10 -47
  46. data/ext/openssl/ossl_x509revoked.c +8 -8
  47. data/ext/openssl/ossl_x509store.c +15 -45
  48. data/ext/openssl/ruby_missing.h +2 -13
  49. data/lib/openssl.rb +1 -0
  50. data/lib/openssl/bn.rb +2 -1
  51. data/lib/openssl/buffering.rb +24 -23
  52. data/lib/openssl/config.rb +12 -11
  53. data/lib/openssl/digest.rb +3 -6
  54. data/lib/openssl/pkcs5.rb +22 -0
  55. data/lib/openssl/pkey.rb +0 -41
  56. data/lib/openssl/ssl.rb +118 -16
  57. data/lib/openssl/x509.rb +7 -1
  58. metadata +8 -7
  59. data/ext/openssl/ossl_pkcs5.c +0 -180
  60. data/ext/openssl/ossl_pkcs5.h +0 -6
@@ -15,15 +15,12 @@
15
15
  module OpenSSL
16
16
  class Digest
17
17
 
18
- alg = %w(MD2 MD4 MD5 MDC2 RIPEMD160 SHA1)
18
+ alg = %w(MD2 MD4 MD5 MDC2 RIPEMD160 SHA1 SHA224 SHA256 SHA384 SHA512)
19
19
  if OPENSSL_VERSION_NUMBER < 0x10100000
20
20
  alg += %w(DSS DSS1 SHA)
21
21
  end
22
- if OPENSSL_VERSION_NUMBER > 0x00908000
23
- alg += %w(SHA224 SHA256 SHA384 SHA512)
24
- end
25
22
 
26
- # Return the +data+ hash computed with +name+ Digest. +name+ is either the
23
+ # Return the hash value computed with _name_ Digest. _name_ is either the
27
24
  # long name or short name of a supported digest algorithm.
28
25
  #
29
26
  # === Examples
@@ -59,7 +56,7 @@ module OpenSSL
59
56
 
60
57
  end # Digest
61
58
 
62
- # Returns a Digest subclass by +name+.
59
+ # Returns a Digest subclass by _name_
63
60
  #
64
61
  # require 'openssl'
65
62
  #
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: false
2
+ #--
3
+ # Ruby/OpenSSL Project
4
+ # Copyright (C) 2017 Ruby/OpenSSL Project Authors
5
+ #++
6
+
7
+ module OpenSSL
8
+ module PKCS5
9
+ module_function
10
+
11
+ # OpenSSL::PKCS5.pbkdf2_hmac has been renamed to OpenSSL::KDF.pbkdf2_hmac.
12
+ # This method is provided for backwards compatibility.
13
+ def pbkdf2_hmac(pass, salt, iter, keylen, digest)
14
+ OpenSSL::KDF.pbkdf2_hmac(pass, salt: salt, iterations: iter,
15
+ length: keylen, hash: digest)
16
+ end
17
+
18
+ def pbkdf2_hmac_sha1(pass, salt, iter, keylen)
19
+ pbkdf2_hmac(pass, salt, iter, keylen, "sha1")
20
+ end
21
+ end
22
+ end
@@ -1,44 +1,3 @@
1
1
  # frozen_string_literal: false
2
2
  module OpenSSL
3
- module PKey
4
- if defined?(OpenSSL::PKey::DH)
5
-
6
- class DH
7
- # :nodoc:
8
- DEFAULT_1024 = new <<-_end_of_pem_
9
- -----BEGIN DH PARAMETERS-----
10
- MIGHAoGBAJ0lOVy0VIr/JebWn0zDwY2h+rqITFOpdNr6ugsgvkDXuucdcChhYExJ
11
- AV/ZD2AWPbrTqV76mGRgJg4EddgT1zG0jq3rnFdMj2XzkBYx3BVvfR0Arnby0RHR
12
- T4h7KZ/2zmjvV+eF8kBUHBJAojUlzxKj4QeO2x20FP9X5xmNUXeDAgEC
13
- -----END DH PARAMETERS-----
14
- _end_of_pem_
15
-
16
- # :nodoc:
17
- DEFAULT_2048 = new <<-_end_of_pem_
18
- -----BEGIN DH PARAMETERS-----
19
- MIIBCAKCAQEA7E6kBrYiyvmKAMzQ7i8WvwVk9Y/+f8S7sCTN712KkK3cqd1jhJDY
20
- JbrYeNV3kUIKhPxWHhObHKpD1R84UpL+s2b55+iMd6GmL7OYmNIT/FccKhTcveab
21
- VBmZT86BZKYyf45hUF9FOuUM9xPzuK3Vd8oJQvfYMCd7LPC0taAEljQLR4Edf8E6
22
- YoaOffgTf5qxiwkjnlVZQc3whgnEt9FpVMvQ9eknyeGB5KHfayAc3+hUAvI3/Cr3
23
- 1bNveX5wInh5GDx1FGhKBZ+s1H+aedudCm7sCgRwv8lKWYGiHzObSma8A86KG+MD
24
- 7Lo5JquQ3DlBodj3IDyPrxIv96lvRPFtAwIBAg==
25
- -----END DH PARAMETERS-----
26
- _end_of_pem_
27
- end
28
-
29
- # :nodoc:
30
- DEFAULT_TMP_DH_CALLBACK = lambda { |ctx, is_export, keylen|
31
- warn "using default DH parameters." if $VERBOSE
32
- case keylen
33
- when 1024 then OpenSSL::PKey::DH::DEFAULT_1024
34
- when 2048 then OpenSSL::PKey::DH::DEFAULT_2048
35
- else
36
- nil
37
- end
38
- }
39
-
40
- else
41
- DEFAULT_TMP_DH_CALLBACK = nil
42
- end
43
- end
44
3
  end
@@ -17,18 +17,36 @@ module OpenSSL
17
17
  module SSL
18
18
  class SSLContext
19
19
  DEFAULT_PARAMS = { # :nodoc:
20
- :ssl_version => "SSLv23",
20
+ :min_version => OpenSSL::SSL::TLS1_VERSION,
21
21
  :verify_mode => OpenSSL::SSL::VERIFY_PEER,
22
22
  :verify_hostname => true,
23
23
  :options => -> {
24
24
  opts = OpenSSL::SSL::OP_ALL
25
25
  opts &= ~OpenSSL::SSL::OP_DONT_INSERT_EMPTY_FRAGMENTS
26
- opts |= OpenSSL::SSL::OP_NO_COMPRESSION if defined?(OpenSSL::SSL::OP_NO_COMPRESSION)
27
- opts |= OpenSSL::SSL::OP_NO_SSLv2 | OpenSSL::SSL::OP_NO_SSLv3
26
+ opts |= OpenSSL::SSL::OP_NO_COMPRESSION
28
27
  opts
29
28
  }.call
30
29
  }
31
30
 
31
+ if defined?(OpenSSL::PKey::DH)
32
+ DEFAULT_2048 = OpenSSL::PKey::DH.new <<-_end_of_pem_
33
+ -----BEGIN DH PARAMETERS-----
34
+ MIIBCAKCAQEA7E6kBrYiyvmKAMzQ7i8WvwVk9Y/+f8S7sCTN712KkK3cqd1jhJDY
35
+ JbrYeNV3kUIKhPxWHhObHKpD1R84UpL+s2b55+iMd6GmL7OYmNIT/FccKhTcveab
36
+ VBmZT86BZKYyf45hUF9FOuUM9xPzuK3Vd8oJQvfYMCd7LPC0taAEljQLR4Edf8E6
37
+ YoaOffgTf5qxiwkjnlVZQc3whgnEt9FpVMvQ9eknyeGB5KHfayAc3+hUAvI3/Cr3
38
+ 1bNveX5wInh5GDx1FGhKBZ+s1H+aedudCm7sCgRwv8lKWYGiHzObSma8A86KG+MD
39
+ 7Lo5JquQ3DlBodj3IDyPrxIv96lvRPFtAwIBAg==
40
+ -----END DH PARAMETERS-----
41
+ _end_of_pem_
42
+ private_constant :DEFAULT_2048
43
+
44
+ DEFAULT_TMP_DH_CALLBACK = lambda { |ctx, is_export, keylen| # :nodoc:
45
+ warn "using default DH parameters." if $VERBOSE
46
+ DEFAULT_2048
47
+ }
48
+ end
49
+
32
50
  if !(OpenSSL::OPENSSL_VERSION.start_with?("OpenSSL") &&
33
51
  OpenSSL::OPENSSL_VERSION_NUMBER >= 0x10100000)
34
52
  DEFAULT_PARAMS.merge!(
@@ -87,14 +105,18 @@ module OpenSSL
87
105
  #
88
106
  # The callback is invoked with an SSLSocket and a server name. The
89
107
  # callback must return an SSLContext for the server name or nil.
90
- attr_accessor :servername_cb if ExtConfig::HAVE_TLSEXT_HOST_NAME
108
+ attr_accessor :servername_cb
91
109
 
92
110
  # call-seq:
93
- # SSLContext.new => ctx
94
- # SSLContext.new(:TLSv1) => ctx
95
- # SSLContext.new("SSLv23_client") => ctx
111
+ # SSLContext.new -> ctx
112
+ # SSLContext.new(:TLSv1) -> ctx
113
+ # SSLContext.new("SSLv23") -> ctx
96
114
  #
97
- # You can get a list of valid methods with OpenSSL::SSL::SSLContext::METHODS
115
+ # Creates a new SSL context.
116
+ #
117
+ # If an argument is given, #ssl_version= is called with the value. Note
118
+ # that this form is deprecated. New applications should use #min_version=
119
+ # and #max_version= as necessary.
98
120
  def initialize(version = nil)
99
121
  self.options |= OpenSSL::SSL::OP_ALL
100
122
  self.ssl_version = version if version
@@ -106,8 +128,8 @@ module OpenSSL
106
128
  #
107
129
  # Sets saner defaults optimized for the use with HTTP-like protocols.
108
130
  #
109
- # If a Hash +params+ is given, the parameters are overridden with it.
110
- # The keys in +params+ must be assignment methods on SSLContext.
131
+ # If a Hash _params_ is given, the parameters are overridden with it.
132
+ # The keys in _params_ must be assignment methods on SSLContext.
111
133
  #
112
134
  # If the verify_mode is not VERIFY_NONE and ca_file, ca_path and
113
135
  # cert_store are not set then the system default certificate store is
@@ -122,6 +144,88 @@ module OpenSSL
122
144
  end
123
145
  return params
124
146
  end
147
+
148
+ # call-seq:
149
+ # ctx.min_version = OpenSSL::SSL::TLS1_2_VERSION
150
+ # ctx.min_version = :TLS1_2
151
+ # ctx.min_version = nil
152
+ #
153
+ # Sets the lower bound on the supported SSL/TLS protocol version. The
154
+ # version may be specified by an integer constant named
155
+ # OpenSSL::SSL::*_VERSION, a Symbol, or +nil+ which means "any version".
156
+ #
157
+ # Be careful that you don't overwrite OpenSSL::SSL::OP_NO_{SSL,TLS}v*
158
+ # options by #options= once you have called #min_version= or
159
+ # #max_version=.
160
+ #
161
+ # === Example
162
+ # ctx = OpenSSL::SSL::SSLContext.new
163
+ # ctx.min_version = OpenSSL::SSL::TLS1_1_VERSION
164
+ # ctx.max_version = OpenSSL::SSL::TLS1_2_VERSION
165
+ #
166
+ # sock = OpenSSL::SSL::SSLSocket.new(tcp_sock, ctx)
167
+ # sock.connect # Initiates a connection using either TLS 1.1 or TLS 1.2
168
+ def min_version=(version)
169
+ set_minmax_proto_version(version, @max_proto_version ||= nil)
170
+ @min_proto_version = version
171
+ end
172
+
173
+ # call-seq:
174
+ # ctx.max_version = OpenSSL::SSL::TLS1_2_VERSION
175
+ # ctx.max_version = :TLS1_2
176
+ # ctx.max_version = nil
177
+ #
178
+ # Sets the upper bound of the supported SSL/TLS protocol version. See
179
+ # #min_version= for the possible values.
180
+ def max_version=(version)
181
+ set_minmax_proto_version(@min_proto_version ||= nil, version)
182
+ @max_proto_version = version
183
+ end
184
+
185
+ # call-seq:
186
+ # ctx.ssl_version = :TLSv1
187
+ # ctx.ssl_version = "SSLv23"
188
+ #
189
+ # Sets the SSL/TLS protocol version for the context. This forces
190
+ # connections to use only the specified protocol version. This is
191
+ # deprecated and only provided for backwards compatibility. Use
192
+ # #min_version= and #max_version= instead.
193
+ #
194
+ # === History
195
+ # As the name hints, this used to call the SSL_CTX_set_ssl_version()
196
+ # function which sets the SSL method used for connections created from
197
+ # the context. As of Ruby/OpenSSL 2.1, this accessor method is
198
+ # implemented to call #min_version= and #max_version= instead.
199
+ def ssl_version=(meth)
200
+ meth = meth.to_s if meth.is_a?(Symbol)
201
+ if /(?<type>_client|_server)\z/ =~ meth
202
+ meth = $`
203
+ if $VERBOSE
204
+ warn "#{caller(1)[0]}: method type #{type.inspect} is ignored"
205
+ end
206
+ end
207
+ version = METHODS_MAP[meth.intern] or
208
+ raise ArgumentError, "unknown SSL method `%s'" % meth
209
+ set_minmax_proto_version(version, version)
210
+ @min_proto_version = @max_proto_version = version
211
+ end
212
+
213
+ METHODS_MAP = {
214
+ SSLv23: 0,
215
+ SSLv2: OpenSSL::SSL::SSL2_VERSION,
216
+ SSLv3: OpenSSL::SSL::SSL3_VERSION,
217
+ TLSv1: OpenSSL::SSL::TLS1_VERSION,
218
+ TLSv1_1: OpenSSL::SSL::TLS1_1_VERSION,
219
+ TLSv1_2: OpenSSL::SSL::TLS1_2_VERSION,
220
+ }.freeze
221
+ private_constant :METHODS_MAP
222
+
223
+ # The list of available SSL/TLS methods. This constant is only provided
224
+ # for backwards compatibility.
225
+ METHODS = METHODS_MAP.flat_map { |name,|
226
+ [name, :"#{name}_client", :"#{name}_server"]
227
+ }.freeze
228
+ deprecate_constant :METHODS
125
229
  end
126
230
 
127
231
  module SocketForwarder
@@ -242,9 +346,7 @@ module OpenSSL
242
346
  include Buffering
243
347
  include SocketForwarder
244
348
 
245
- if ExtConfig::HAVE_TLSEXT_HOST_NAME
246
- attr_reader :hostname
247
- end
349
+ attr_reader :hostname
248
350
 
249
351
  # The underlying IO object.
250
352
  attr_reader :io
@@ -317,7 +419,7 @@ module OpenSSL
317
419
  end
318
420
 
319
421
  def tmp_dh_callback
320
- @context.tmp_dh_callback || OpenSSL::PKey::DEFAULT_TMP_DH_CALLBACK
422
+ @context.tmp_dh_callback || OpenSSL::SSL::SSLContext::DEFAULT_TMP_DH_CALLBACK
321
423
  end
322
424
 
323
425
  def tmp_ecdh_callback
@@ -341,8 +443,8 @@ module OpenSSL
341
443
  attr_accessor :start_immediately
342
444
 
343
445
  # Creates a new instance of SSLServer.
344
- # * +srv+ is an instance of TCPServer.
345
- # * +ctx+ is an instance of OpenSSL::SSL::SSLContext.
446
+ # * _srv_ is an instance of TCPServer.
447
+ # * _ctx_ is an instance of OpenSSL::SSL::SSLContext.
346
448
  def initialize(svr, ctx)
347
449
  @svr = svr
348
450
  @ctx = ctx
@@ -139,7 +139,13 @@ module OpenSSL
139
139
  end
140
140
 
141
141
  def parse_openssl(str, template=OBJECT_TYPE_TEMPLATE)
142
- ary = str.scan(/\s*([^\/,]+)\s*/).collect{|i| i[0].split("=", 2) }
142
+ if str.start_with?("/")
143
+ # /A=B/C=D format
144
+ ary = str[1..-1].split("/").map { |i| i.split("=", 2) }
145
+ else
146
+ # Comma-separated
147
+ ary = str.split(",").map { |i| i.strip.split("=", 2) }
148
+ end
143
149
  self.new(ary, template)
144
150
  end
145
151
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: openssl
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.9
4
+ version: 2.1.0.beta1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Martin Bosslet
@@ -11,7 +11,7 @@ authors:
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2018-10-18 00:00:00.000000000 Z
14
+ date: 2017-09-03 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: rake
@@ -107,14 +107,14 @@ files:
107
107
  - ext/openssl/ossl_engine.h
108
108
  - ext/openssl/ossl_hmac.c
109
109
  - ext/openssl/ossl_hmac.h
110
+ - ext/openssl/ossl_kdf.c
111
+ - ext/openssl/ossl_kdf.h
110
112
  - ext/openssl/ossl_ns_spki.c
111
113
  - ext/openssl/ossl_ns_spki.h
112
114
  - ext/openssl/ossl_ocsp.c
113
115
  - ext/openssl/ossl_ocsp.h
114
116
  - ext/openssl/ossl_pkcs12.c
115
117
  - ext/openssl/ossl_pkcs12.h
116
- - ext/openssl/ossl_pkcs5.c
117
- - ext/openssl/ossl_pkcs5.h
118
118
  - ext/openssl/ossl_pkcs7.c
119
119
  - ext/openssl/ossl_pkcs7.h
120
120
  - ext/openssl/ossl_pkey.c
@@ -146,6 +146,7 @@ files:
146
146
  - lib/openssl/cipher.rb
147
147
  - lib/openssl/config.rb
148
148
  - lib/openssl/digest.rb
149
+ - lib/openssl/pkcs5.rb
149
150
  - lib/openssl/pkey.rb
150
151
  - lib/openssl/ssl.rb
151
152
  - lib/openssl/x509.rb
@@ -167,12 +168,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
167
168
  version: 2.3.0
168
169
  required_rubygems_version: !ruby/object:Gem::Requirement
169
170
  requirements:
170
- - - ">="
171
+ - - ">"
171
172
  - !ruby/object:Gem::Version
172
- version: '0'
173
+ version: 1.3.1
173
174
  requirements: []
174
175
  rubyforge_project:
175
- rubygems_version: 2.7.6
176
+ rubygems_version: 2.6.13
176
177
  signing_key:
177
178
  specification_version: 4
178
179
  summary: OpenSSL provides SSL, TLS and general purpose cryptography.
@@ -1,180 +0,0 @@
1
- /*
2
- * Copyright (C) 2007 Technorama Ltd. <oss-ruby@technorama.net>
3
- */
4
- #include "ossl.h"
5
-
6
- VALUE mPKCS5;
7
- VALUE ePKCS5;
8
-
9
- #ifdef HAVE_PKCS5_PBKDF2_HMAC
10
- /*
11
- * call-seq:
12
- * PKCS5.pbkdf2_hmac(pass, salt, iter, keylen, digest) => string
13
- *
14
- * === Parameters
15
- * * +pass+ - string
16
- * * +salt+ - string - should be at least 8 bytes long.
17
- * * +iter+ - integer - should be greater than 1000. 20000 is better.
18
- * * +keylen+ - integer
19
- * * +digest+ - a string or OpenSSL::Digest object.
20
- *
21
- * Available in OpenSSL >= 1.0.0.
22
- *
23
- * Digests other than SHA1 may not be supported by other cryptography libraries.
24
- */
25
- static VALUE
26
- ossl_pkcs5_pbkdf2_hmac(VALUE self, VALUE pass, VALUE salt, VALUE iter, VALUE keylen, VALUE digest)
27
- {
28
- VALUE str;
29
- const EVP_MD *md;
30
- int len = NUM2INT(keylen);
31
-
32
- StringValue(pass);
33
- StringValue(salt);
34
- md = GetDigestPtr(digest);
35
-
36
- str = rb_str_new(0, len);
37
-
38
- if (PKCS5_PBKDF2_HMAC(RSTRING_PTR(pass), RSTRING_LENINT(pass),
39
- (unsigned char *)RSTRING_PTR(salt), RSTRING_LENINT(salt),
40
- NUM2INT(iter), md, len,
41
- (unsigned char *)RSTRING_PTR(str)) != 1)
42
- ossl_raise(ePKCS5, "PKCS5_PBKDF2_HMAC");
43
-
44
- return str;
45
- }
46
- #else
47
- #define ossl_pkcs5_pbkdf2_hmac rb_f_notimplement
48
- #endif
49
-
50
-
51
- /*
52
- * call-seq:
53
- * PKCS5.pbkdf2_hmac_sha1(pass, salt, iter, keylen) => string
54
- *
55
- * === Parameters
56
- * * +pass+ - string
57
- * * +salt+ - string - should be at least 8 bytes long.
58
- * * +iter+ - integer - should be greater than 1000. 20000 is better.
59
- * * +keylen+ - integer
60
- *
61
- * This method is available in almost any version of OpenSSL.
62
- *
63
- * Conforms to RFC 2898.
64
- */
65
- static VALUE
66
- ossl_pkcs5_pbkdf2_hmac_sha1(VALUE self, VALUE pass, VALUE salt, VALUE iter, VALUE keylen)
67
- {
68
- VALUE str;
69
- int len = NUM2INT(keylen);
70
-
71
- StringValue(pass);
72
- StringValue(salt);
73
-
74
- str = rb_str_new(0, len);
75
-
76
- if (PKCS5_PBKDF2_HMAC_SHA1(RSTRING_PTR(pass), RSTRING_LENINT(pass),
77
- (const unsigned char *)RSTRING_PTR(salt), RSTRING_LENINT(salt), NUM2INT(iter),
78
- len, (unsigned char *)RSTRING_PTR(str)) != 1)
79
- ossl_raise(ePKCS5, "PKCS5_PBKDF2_HMAC_SHA1");
80
-
81
- return str;
82
- }
83
-
84
- void
85
- Init_ossl_pkcs5(void)
86
- {
87
- #if 0
88
- mOSSL = rb_define_module("OpenSSL");
89
- eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError);
90
- #endif
91
-
92
- /* Document-class: OpenSSL::PKCS5
93
- *
94
- * Provides password-based encryption functionality based on PKCS#5.
95
- * Typically used for securely deriving arbitrary length symmetric keys
96
- * to be used with an OpenSSL::Cipher from passwords. Another use case
97
- * is for storing passwords: Due to the ability to tweak the effort of
98
- * computation by increasing the iteration count, computation can be
99
- * slowed down artificially in order to render possible attacks infeasible.
100
- *
101
- * PKCS5 offers support for PBKDF2 with an OpenSSL::Digest::SHA1-based
102
- * HMAC, or an arbitrary Digest if the underlying version of OpenSSL
103
- * already supports it (>= 1.0.0).
104
- *
105
- * === Parameters
106
- * ==== Password
107
- * Typically an arbitrary String that represents the password to be used
108
- * for deriving a key.
109
- * ==== Salt
110
- * Prevents attacks based on dictionaries of common passwords. It is a
111
- * public value that can be safely stored along with the password (e.g.
112
- * if PBKDF2 is used for password storage). For maximum security, a fresh,
113
- * random salt should be generated for each stored password. According
114
- * to PKCS#5, a salt should be at least 8 bytes long.
115
- * ==== Iteration Count
116
- * Allows to tweak the length that the actual computation will take. The
117
- * larger the iteration count, the longer it will take.
118
- * ==== Key Length
119
- * Specifies the length in bytes of the output that will be generated.
120
- * Typically, the key length should be larger than or equal to the output
121
- * length of the underlying digest function, otherwise an attacker could
122
- * simply try to brute-force the key. According to PKCS#5, security is
123
- * limited by the output length of the underlying digest function, i.e.
124
- * security is not improved if a key length strictly larger than the
125
- * digest output length is chosen. Therefore, when using PKCS5 for
126
- * password storage, it suffices to store values equal to the digest
127
- * output length, nothing is gained by storing larger values.
128
- *
129
- * == Examples
130
- * === Generating a 128 bit key for a Cipher (e.g. AES)
131
- * pass = "secret"
132
- * salt = OpenSSL::Random.random_bytes(16)
133
- * iter = 20000
134
- * key_len = 16
135
- * key = OpenSSL::PKCS5.pbkdf2_hmac_sha1(pass, salt, iter, key_len)
136
- *
137
- * === Storing Passwords
138
- * pass = "secret"
139
- * salt = OpenSSL::Random.random_bytes(16) #store this with the generated value
140
- * iter = 20000
141
- * digest = OpenSSL::Digest::SHA256.new
142
- * len = digest.digest_length
143
- * #the final value to be stored
144
- * value = OpenSSL::PKCS5.pbkdf2_hmac(pass, salt, iter, len, digest)
145
- *
146
- * === Important Note on Checking Passwords
147
- * When comparing passwords provided by the user with previously stored
148
- * values, a common mistake made is comparing the two values using "==".
149
- * Typically, "==" short-circuits on evaluation, and is therefore
150
- * vulnerable to timing attacks. The proper way is to use a method that
151
- * always takes the same amount of time when comparing two values, thus
152
- * not leaking any information to potential attackers. To compare two
153
- * values, the following could be used:
154
- * def eql_time_cmp(a, b)
155
- * unless a.length == b.length
156
- * return false
157
- * end
158
- * cmp = b.bytes.to_a
159
- * result = 0
160
- * a.bytes.each_with_index {|c,i|
161
- * result |= c ^ cmp[i]
162
- * }
163
- * result == 0
164
- * end
165
- * Please note that the premature return in case of differing lengths
166
- * typically does not leak valuable information - when using PKCS#5, the
167
- * length of the values to be compared is of fixed size.
168
- */
169
-
170
- mPKCS5 = rb_define_module_under(mOSSL, "PKCS5");
171
- /* Document-class: OpenSSL::PKCS5::PKCS5Error
172
- *
173
- * Generic Exception class that is raised if an error occurs during a
174
- * computation.
175
- */
176
- ePKCS5 = rb_define_class_under(mPKCS5, "PKCS5Error", eOSSLError);
177
-
178
- rb_define_module_function(mPKCS5, "pbkdf2_hmac", ossl_pkcs5_pbkdf2_hmac, 5);
179
- rb_define_module_function(mPKCS5, "pbkdf2_hmac_sha1", ossl_pkcs5_pbkdf2_hmac_sha1, 4);
180
- }