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.
- checksums.yaml +5 -5
- data/History.md +28 -69
- data/README.md +1 -1
- data/ext/openssl/deprecation.rb +0 -3
- data/ext/openssl/extconf.rb +8 -52
- data/ext/openssl/openssl_missing.c +0 -67
- data/ext/openssl/openssl_missing.h +3 -50
- data/ext/openssl/ossl.c +81 -74
- data/ext/openssl/ossl.h +14 -27
- data/ext/openssl/ossl_asn1.c +287 -374
- data/ext/openssl/ossl_asn1.h +0 -4
- data/ext/openssl/ossl_bio.c +5 -20
- data/ext/openssl/ossl_bio.h +0 -2
- data/ext/openssl/ossl_bn.c +70 -28
- data/ext/openssl/ossl_cipher.c +18 -42
- data/ext/openssl/ossl_cipher.h +1 -1
- data/ext/openssl/ossl_digest.c +8 -12
- data/ext/openssl/ossl_digest.h +1 -1
- data/ext/openssl/ossl_engine.c +47 -47
- data/ext/openssl/ossl_hmac.c +19 -22
- data/ext/openssl/ossl_kdf.c +221 -0
- data/ext/openssl/ossl_kdf.h +6 -0
- data/ext/openssl/ossl_ns_spki.c +17 -21
- data/ext/openssl/ossl_ocsp.c +85 -80
- data/ext/openssl/ossl_pkcs12.c +15 -21
- data/ext/openssl/ossl_pkcs7.c +8 -21
- data/ext/openssl/ossl_pkey.c +24 -48
- data/ext/openssl/ossl_pkey.h +1 -6
- data/ext/openssl/ossl_pkey_dh.c +11 -11
- data/ext/openssl/ossl_pkey_dsa.c +16 -22
- data/ext/openssl/ossl_pkey_ec.c +43 -56
- data/ext/openssl/ossl_pkey_rsa.c +19 -19
- data/ext/openssl/ossl_rand.c +12 -12
- data/ext/openssl/ossl_ssl.c +291 -243
- data/ext/openssl/ossl_ssl.h +0 -5
- data/ext/openssl/ossl_ssl_session.c +7 -9
- data/ext/openssl/ossl_version.h +1 -1
- data/ext/openssl/ossl_x509.c +0 -15
- data/ext/openssl/ossl_x509.h +0 -7
- data/ext/openssl/ossl_x509attr.c +3 -7
- data/ext/openssl/ossl_x509cert.c +17 -54
- data/ext/openssl/ossl_x509crl.c +15 -25
- data/ext/openssl/ossl_x509ext.c +9 -14
- data/ext/openssl/ossl_x509name.c +76 -41
- data/ext/openssl/ossl_x509req.c +10 -47
- data/ext/openssl/ossl_x509revoked.c +8 -8
- data/ext/openssl/ossl_x509store.c +15 -45
- data/ext/openssl/ruby_missing.h +2 -13
- data/lib/openssl.rb +1 -0
- data/lib/openssl/bn.rb +2 -1
- data/lib/openssl/buffering.rb +24 -23
- data/lib/openssl/config.rb +12 -11
- data/lib/openssl/digest.rb +3 -6
- data/lib/openssl/pkcs5.rb +22 -0
- data/lib/openssl/pkey.rb +0 -41
- data/lib/openssl/ssl.rb +118 -16
- data/lib/openssl/x509.rb +7 -1
- metadata +8 -7
- data/ext/openssl/ossl_pkcs5.c +0 -180
- data/ext/openssl/ossl_pkcs5.h +0 -6
data/lib/openssl/digest.rb
CHANGED
@@ -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
|
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
|
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
|
data/lib/openssl/pkey.rb
CHANGED
@@ -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
|
data/lib/openssl/ssl.rb
CHANGED
@@ -17,18 +17,36 @@ module OpenSSL
|
|
17
17
|
module SSL
|
18
18
|
class SSLContext
|
19
19
|
DEFAULT_PARAMS = { # :nodoc:
|
20
|
-
:
|
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
|
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
|
108
|
+
attr_accessor :servername_cb
|
91
109
|
|
92
110
|
# call-seq:
|
93
|
-
# SSLContext.new
|
94
|
-
# SSLContext.new(:TLSv1)
|
95
|
-
# SSLContext.new("
|
111
|
+
# SSLContext.new -> ctx
|
112
|
+
# SSLContext.new(:TLSv1) -> ctx
|
113
|
+
# SSLContext.new("SSLv23") -> ctx
|
96
114
|
#
|
97
|
-
#
|
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
|
110
|
-
# The keys in
|
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
|
-
|
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::
|
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
|
-
# *
|
345
|
-
# *
|
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
|
data/lib/openssl/x509.rb
CHANGED
@@ -139,7 +139,13 @@ module OpenSSL
|
|
139
139
|
end
|
140
140
|
|
141
141
|
def parse_openssl(str, template=OBJECT_TYPE_TEMPLATE)
|
142
|
-
|
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.
|
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:
|
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:
|
173
|
+
version: 1.3.1
|
173
174
|
requirements: []
|
174
175
|
rubyforge_project:
|
175
|
-
rubygems_version: 2.
|
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.
|
data/ext/openssl/ossl_pkcs5.c
DELETED
@@ -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
|
-
}
|