zig_example 0.3.2 → 0.3.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/ext/mkmf.rb +5 -2
- data/lib/zig_example/version.rb +1 -1
- metadata +3 -56
- data/ext/openssl/openssl_missing.c +0 -40
- data/ext/openssl/openssl_missing.h +0 -238
- data/ext/openssl/ossl.c +0 -1295
- data/ext/openssl/ossl.h +0 -201
- data/ext/openssl/ossl_asn1.c +0 -1891
- data/ext/openssl/ossl_asn1.h +0 -62
- data/ext/openssl/ossl_bio.c +0 -42
- data/ext/openssl/ossl_bio.h +0 -16
- data/ext/openssl/ossl_bn.c +0 -1344
- data/ext/openssl/ossl_bn.h +0 -26
- data/ext/openssl/ossl_cipher.c +0 -1074
- data/ext/openssl/ossl_cipher.h +0 -20
- data/ext/openssl/ossl_config.c +0 -460
- data/ext/openssl/ossl_config.h +0 -16
- data/ext/openssl/ossl_digest.c +0 -425
- data/ext/openssl/ossl_digest.h +0 -20
- data/ext/openssl/ossl_engine.c +0 -568
- data/ext/openssl/ossl_engine.h +0 -19
- data/ext/openssl/ossl_hmac.c +0 -310
- data/ext/openssl/ossl_hmac.h +0 -18
- data/ext/openssl/ossl_kdf.c +0 -311
- data/ext/openssl/ossl_kdf.h +0 -6
- data/ext/openssl/ossl_ns_spki.c +0 -405
- data/ext/openssl/ossl_ns_spki.h +0 -19
- data/ext/openssl/ossl_ocsp.c +0 -1965
- data/ext/openssl/ossl_ocsp.h +0 -23
- data/ext/openssl/ossl_pkcs12.c +0 -275
- data/ext/openssl/ossl_pkcs12.h +0 -13
- data/ext/openssl/ossl_pkcs7.c +0 -1081
- data/ext/openssl/ossl_pkcs7.h +0 -36
- data/ext/openssl/ossl_pkey.c +0 -1624
- data/ext/openssl/ossl_pkey.h +0 -204
- data/ext/openssl/ossl_pkey_dh.c +0 -440
- data/ext/openssl/ossl_pkey_dsa.c +0 -359
- data/ext/openssl/ossl_pkey_ec.c +0 -1655
- data/ext/openssl/ossl_pkey_rsa.c +0 -579
- data/ext/openssl/ossl_rand.c +0 -200
- data/ext/openssl/ossl_rand.h +0 -18
- data/ext/openssl/ossl_ssl.c +0 -3142
- data/ext/openssl/ossl_ssl.h +0 -36
- data/ext/openssl/ossl_ssl_session.c +0 -331
- data/ext/openssl/ossl_ts.c +0 -1539
- data/ext/openssl/ossl_ts.h +0 -16
- data/ext/openssl/ossl_x509.c +0 -256
- data/ext/openssl/ossl_x509.h +0 -115
- data/ext/openssl/ossl_x509attr.c +0 -324
- data/ext/openssl/ossl_x509cert.c +0 -1002
- data/ext/openssl/ossl_x509crl.c +0 -545
- data/ext/openssl/ossl_x509ext.c +0 -490
- data/ext/openssl/ossl_x509name.c +0 -597
- data/ext/openssl/ossl_x509req.c +0 -444
- data/ext/openssl/ossl_x509revoked.c +0 -300
- data/ext/openssl/ossl_x509store.c +0 -986
data/ext/openssl/ossl_hmac.c
DELETED
@@ -1,310 +0,0 @@
|
|
1
|
-
/*
|
2
|
-
* 'OpenSSL for Ruby' project
|
3
|
-
* Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz>
|
4
|
-
* All rights reserved.
|
5
|
-
*/
|
6
|
-
/*
|
7
|
-
* This program is licensed under the same licence as Ruby.
|
8
|
-
* (See the file 'LICENCE'.)
|
9
|
-
*/
|
10
|
-
#include "ossl.h"
|
11
|
-
|
12
|
-
#define NewHMAC(klass) \
|
13
|
-
TypedData_Wrap_Struct((klass), &ossl_hmac_type, 0)
|
14
|
-
#define GetHMAC(obj, ctx) do { \
|
15
|
-
TypedData_Get_Struct((obj), EVP_MD_CTX, &ossl_hmac_type, (ctx)); \
|
16
|
-
if (!(ctx)) { \
|
17
|
-
ossl_raise(rb_eRuntimeError, "HMAC wasn't initialized"); \
|
18
|
-
} \
|
19
|
-
} while (0)
|
20
|
-
|
21
|
-
/*
|
22
|
-
* Classes
|
23
|
-
*/
|
24
|
-
VALUE cHMAC;
|
25
|
-
VALUE eHMACError;
|
26
|
-
|
27
|
-
/*
|
28
|
-
* Public
|
29
|
-
*/
|
30
|
-
|
31
|
-
/*
|
32
|
-
* Private
|
33
|
-
*/
|
34
|
-
static void
|
35
|
-
ossl_hmac_free(void *ctx)
|
36
|
-
{
|
37
|
-
EVP_MD_CTX_free(ctx);
|
38
|
-
}
|
39
|
-
|
40
|
-
static const rb_data_type_t ossl_hmac_type = {
|
41
|
-
"OpenSSL/HMAC",
|
42
|
-
{
|
43
|
-
0, ossl_hmac_free,
|
44
|
-
},
|
45
|
-
0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
|
46
|
-
};
|
47
|
-
|
48
|
-
static VALUE
|
49
|
-
ossl_hmac_alloc(VALUE klass)
|
50
|
-
{
|
51
|
-
VALUE obj;
|
52
|
-
EVP_MD_CTX *ctx;
|
53
|
-
|
54
|
-
obj = NewHMAC(klass);
|
55
|
-
ctx = EVP_MD_CTX_new();
|
56
|
-
if (!ctx)
|
57
|
-
ossl_raise(eHMACError, "EVP_MD_CTX");
|
58
|
-
RTYPEDDATA_DATA(obj) = ctx;
|
59
|
-
|
60
|
-
return obj;
|
61
|
-
}
|
62
|
-
|
63
|
-
|
64
|
-
/*
|
65
|
-
* call-seq:
|
66
|
-
* HMAC.new(key, digest) -> hmac
|
67
|
-
*
|
68
|
-
* Returns an instance of OpenSSL::HMAC set with the key and digest
|
69
|
-
* algorithm to be used. The instance represents the initial state of
|
70
|
-
* the message authentication code before any data has been processed.
|
71
|
-
* To process data with it, use the instance method #update with your
|
72
|
-
* data as an argument.
|
73
|
-
*
|
74
|
-
* === Example
|
75
|
-
*
|
76
|
-
* key = 'key'
|
77
|
-
* instance = OpenSSL::HMAC.new(key, 'SHA1')
|
78
|
-
* #=> f42bb0eeb018ebbd4597ae7213711ec60760843f
|
79
|
-
* instance.class
|
80
|
-
* #=> OpenSSL::HMAC
|
81
|
-
*
|
82
|
-
* === A note about comparisons
|
83
|
-
*
|
84
|
-
* Two instances can be securely compared with #== in constant time:
|
85
|
-
*
|
86
|
-
* other_instance = OpenSSL::HMAC.new('key', 'SHA1')
|
87
|
-
* #=> f42bb0eeb018ebbd4597ae7213711ec60760843f
|
88
|
-
* instance == other_instance
|
89
|
-
* #=> true
|
90
|
-
*
|
91
|
-
*/
|
92
|
-
static VALUE
|
93
|
-
ossl_hmac_initialize(VALUE self, VALUE key, VALUE digest)
|
94
|
-
{
|
95
|
-
EVP_MD_CTX *ctx;
|
96
|
-
EVP_PKEY *pkey;
|
97
|
-
|
98
|
-
GetHMAC(self, ctx);
|
99
|
-
StringValue(key);
|
100
|
-
#ifdef HAVE_EVP_PKEY_NEW_RAW_PRIVATE_KEY
|
101
|
-
pkey = EVP_PKEY_new_raw_private_key(EVP_PKEY_HMAC, NULL,
|
102
|
-
(unsigned char *)RSTRING_PTR(key),
|
103
|
-
RSTRING_LENINT(key));
|
104
|
-
if (!pkey)
|
105
|
-
ossl_raise(eHMACError, "EVP_PKEY_new_raw_private_key");
|
106
|
-
#else
|
107
|
-
pkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL,
|
108
|
-
(unsigned char *)RSTRING_PTR(key),
|
109
|
-
RSTRING_LENINT(key));
|
110
|
-
if (!pkey)
|
111
|
-
ossl_raise(eHMACError, "EVP_PKEY_new_mac_key");
|
112
|
-
#endif
|
113
|
-
if (EVP_DigestSignInit(ctx, NULL, ossl_evp_get_digestbyname(digest),
|
114
|
-
NULL, pkey) != 1) {
|
115
|
-
EVP_PKEY_free(pkey);
|
116
|
-
ossl_raise(eHMACError, "EVP_DigestSignInit");
|
117
|
-
}
|
118
|
-
/* Decrement reference counter; EVP_MD_CTX still keeps it */
|
119
|
-
EVP_PKEY_free(pkey);
|
120
|
-
|
121
|
-
return self;
|
122
|
-
}
|
123
|
-
|
124
|
-
static VALUE
|
125
|
-
ossl_hmac_copy(VALUE self, VALUE other)
|
126
|
-
{
|
127
|
-
EVP_MD_CTX *ctx1, *ctx2;
|
128
|
-
|
129
|
-
rb_check_frozen(self);
|
130
|
-
if (self == other) return self;
|
131
|
-
|
132
|
-
GetHMAC(self, ctx1);
|
133
|
-
GetHMAC(other, ctx2);
|
134
|
-
if (EVP_MD_CTX_copy(ctx1, ctx2) != 1)
|
135
|
-
ossl_raise(eHMACError, "EVP_MD_CTX_copy");
|
136
|
-
return self;
|
137
|
-
}
|
138
|
-
|
139
|
-
/*
|
140
|
-
* call-seq:
|
141
|
-
* hmac.update(string) -> self
|
142
|
-
*
|
143
|
-
* Returns _hmac_ updated with the message to be authenticated.
|
144
|
-
* Can be called repeatedly with chunks of the message.
|
145
|
-
*
|
146
|
-
* === Example
|
147
|
-
*
|
148
|
-
* first_chunk = 'The quick brown fox jumps '
|
149
|
-
* second_chunk = 'over the lazy dog'
|
150
|
-
*
|
151
|
-
* instance.update(first_chunk)
|
152
|
-
* #=> 5b9a8038a65d571076d97fe783989e52278a492a
|
153
|
-
* instance.update(second_chunk)
|
154
|
-
* #=> de7c9b85b8b78aa6bc8a7a36f70a90701c9db4d9
|
155
|
-
*
|
156
|
-
*/
|
157
|
-
static VALUE
|
158
|
-
ossl_hmac_update(VALUE self, VALUE data)
|
159
|
-
{
|
160
|
-
EVP_MD_CTX *ctx;
|
161
|
-
|
162
|
-
StringValue(data);
|
163
|
-
GetHMAC(self, ctx);
|
164
|
-
if (EVP_DigestSignUpdate(ctx, RSTRING_PTR(data), RSTRING_LEN(data)) != 1)
|
165
|
-
ossl_raise(eHMACError, "EVP_DigestSignUpdate");
|
166
|
-
|
167
|
-
return self;
|
168
|
-
}
|
169
|
-
|
170
|
-
/*
|
171
|
-
* call-seq:
|
172
|
-
* hmac.digest -> string
|
173
|
-
*
|
174
|
-
* Returns the authentication code an instance represents as a binary string.
|
175
|
-
*
|
176
|
-
* === Example
|
177
|
-
* instance = OpenSSL::HMAC.new('key', 'SHA1')
|
178
|
-
* #=> f42bb0eeb018ebbd4597ae7213711ec60760843f
|
179
|
-
* instance.digest
|
180
|
-
* #=> "\xF4+\xB0\xEE\xB0\x18\xEB\xBDE\x97\xAEr\x13q\x1E\xC6\a`\x84?"
|
181
|
-
*/
|
182
|
-
static VALUE
|
183
|
-
ossl_hmac_digest(VALUE self)
|
184
|
-
{
|
185
|
-
EVP_MD_CTX *ctx;
|
186
|
-
size_t buf_len = EVP_MAX_MD_SIZE;
|
187
|
-
VALUE ret;
|
188
|
-
|
189
|
-
GetHMAC(self, ctx);
|
190
|
-
ret = rb_str_new(NULL, EVP_MAX_MD_SIZE);
|
191
|
-
if (EVP_DigestSignFinal(ctx, (unsigned char *)RSTRING_PTR(ret),
|
192
|
-
&buf_len) != 1)
|
193
|
-
ossl_raise(eHMACError, "EVP_DigestSignFinal");
|
194
|
-
rb_str_set_len(ret, (long)buf_len);
|
195
|
-
|
196
|
-
return ret;
|
197
|
-
}
|
198
|
-
|
199
|
-
/*
|
200
|
-
* call-seq:
|
201
|
-
* hmac.hexdigest -> string
|
202
|
-
*
|
203
|
-
* Returns the authentication code an instance represents as a hex-encoded
|
204
|
-
* string.
|
205
|
-
*/
|
206
|
-
static VALUE
|
207
|
-
ossl_hmac_hexdigest(VALUE self)
|
208
|
-
{
|
209
|
-
EVP_MD_CTX *ctx;
|
210
|
-
unsigned char buf[EVP_MAX_MD_SIZE];
|
211
|
-
size_t buf_len = EVP_MAX_MD_SIZE;
|
212
|
-
VALUE ret;
|
213
|
-
|
214
|
-
GetHMAC(self, ctx);
|
215
|
-
if (EVP_DigestSignFinal(ctx, buf, &buf_len) != 1)
|
216
|
-
ossl_raise(eHMACError, "EVP_DigestSignFinal");
|
217
|
-
ret = rb_str_new(NULL, buf_len * 2);
|
218
|
-
ossl_bin2hex(buf, RSTRING_PTR(ret), buf_len);
|
219
|
-
|
220
|
-
return ret;
|
221
|
-
}
|
222
|
-
|
223
|
-
/*
|
224
|
-
* call-seq:
|
225
|
-
* hmac.reset -> self
|
226
|
-
*
|
227
|
-
* Returns _hmac_ as it was when it was first initialized, with all processed
|
228
|
-
* data cleared from it.
|
229
|
-
*
|
230
|
-
* === Example
|
231
|
-
*
|
232
|
-
* data = "The quick brown fox jumps over the lazy dog"
|
233
|
-
* instance = OpenSSL::HMAC.new('key', 'SHA1')
|
234
|
-
* #=> f42bb0eeb018ebbd4597ae7213711ec60760843f
|
235
|
-
*
|
236
|
-
* instance.update(data)
|
237
|
-
* #=> de7c9b85b8b78aa6bc8a7a36f70a90701c9db4d9
|
238
|
-
* instance.reset
|
239
|
-
* #=> f42bb0eeb018ebbd4597ae7213711ec60760843f
|
240
|
-
*
|
241
|
-
*/
|
242
|
-
static VALUE
|
243
|
-
ossl_hmac_reset(VALUE self)
|
244
|
-
{
|
245
|
-
EVP_MD_CTX *ctx;
|
246
|
-
EVP_PKEY *pkey;
|
247
|
-
|
248
|
-
GetHMAC(self, ctx);
|
249
|
-
pkey = EVP_PKEY_CTX_get0_pkey(EVP_MD_CTX_get_pkey_ctx(ctx));
|
250
|
-
if (EVP_DigestSignInit(ctx, NULL, EVP_MD_CTX_get0_md(ctx), NULL, pkey) != 1)
|
251
|
-
ossl_raise(eHMACError, "EVP_DigestSignInit");
|
252
|
-
|
253
|
-
return self;
|
254
|
-
}
|
255
|
-
|
256
|
-
/*
|
257
|
-
* INIT
|
258
|
-
*/
|
259
|
-
void
|
260
|
-
Init_ossl_hmac(void)
|
261
|
-
{
|
262
|
-
#if 0
|
263
|
-
mOSSL = rb_define_module("OpenSSL");
|
264
|
-
eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError);
|
265
|
-
#endif
|
266
|
-
|
267
|
-
/*
|
268
|
-
* Document-class: OpenSSL::HMAC
|
269
|
-
*
|
270
|
-
* OpenSSL::HMAC allows computing Hash-based Message Authentication Code
|
271
|
-
* (HMAC). It is a type of message authentication code (MAC) involving a
|
272
|
-
* hash function in combination with a key. HMAC can be used to verify the
|
273
|
-
* integrity of a message as well as the authenticity.
|
274
|
-
*
|
275
|
-
* OpenSSL::HMAC has a similar interface to OpenSSL::Digest.
|
276
|
-
*
|
277
|
-
* === HMAC-SHA256 using one-shot interface
|
278
|
-
*
|
279
|
-
* key = "key"
|
280
|
-
* data = "message-to-be-authenticated"
|
281
|
-
* mac = OpenSSL::HMAC.hexdigest("SHA256", key, data)
|
282
|
-
* #=> "cddb0db23f469c8bf072b21fd837149bd6ace9ab771cceef14c9e517cc93282e"
|
283
|
-
*
|
284
|
-
* === HMAC-SHA256 using incremental interface
|
285
|
-
*
|
286
|
-
* data1 = File.binread("file1")
|
287
|
-
* data2 = File.binread("file2")
|
288
|
-
* key = "key"
|
289
|
-
* hmac = OpenSSL::HMAC.new(key, 'SHA256')
|
290
|
-
* hmac << data1
|
291
|
-
* hmac << data2
|
292
|
-
* mac = hmac.digest
|
293
|
-
*/
|
294
|
-
eHMACError = rb_define_class_under(mOSSL, "HMACError", eOSSLError);
|
295
|
-
|
296
|
-
cHMAC = rb_define_class_under(mOSSL, "HMAC", rb_cObject);
|
297
|
-
|
298
|
-
rb_define_alloc_func(cHMAC, ossl_hmac_alloc);
|
299
|
-
|
300
|
-
rb_define_method(cHMAC, "initialize", ossl_hmac_initialize, 2);
|
301
|
-
rb_define_method(cHMAC, "initialize_copy", ossl_hmac_copy, 1);
|
302
|
-
|
303
|
-
rb_define_method(cHMAC, "reset", ossl_hmac_reset, 0);
|
304
|
-
rb_define_method(cHMAC, "update", ossl_hmac_update, 1);
|
305
|
-
rb_define_alias(cHMAC, "<<", "update");
|
306
|
-
rb_define_method(cHMAC, "digest", ossl_hmac_digest, 0);
|
307
|
-
rb_define_method(cHMAC, "hexdigest", ossl_hmac_hexdigest, 0);
|
308
|
-
rb_define_alias(cHMAC, "inspect", "hexdigest");
|
309
|
-
rb_define_alias(cHMAC, "to_s", "hexdigest");
|
310
|
-
}
|
data/ext/openssl/ossl_hmac.h
DELETED
@@ -1,18 +0,0 @@
|
|
1
|
-
/*
|
2
|
-
* 'OpenSSL for Ruby' project
|
3
|
-
* Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz>
|
4
|
-
* All rights reserved.
|
5
|
-
*/
|
6
|
-
/*
|
7
|
-
* This program is licensed under the same licence as Ruby.
|
8
|
-
* (See the file 'LICENCE'.)
|
9
|
-
*/
|
10
|
-
#if !defined(_OSSL_HMAC_H_)
|
11
|
-
#define _OSSL_HMAC_H_
|
12
|
-
|
13
|
-
extern VALUE cHMAC;
|
14
|
-
extern VALUE eHMACError;
|
15
|
-
|
16
|
-
void Init_ossl_hmac(void);
|
17
|
-
|
18
|
-
#endif /* _OSSL_HMAC_H_ */
|
data/ext/openssl/ossl_kdf.c
DELETED
@@ -1,311 +0,0 @@
|
|
1
|
-
/*
|
2
|
-
* Ruby/OpenSSL Project
|
3
|
-
* Copyright (C) 2007, 2017 Ruby/OpenSSL Project Authors
|
4
|
-
*/
|
5
|
-
#include "ossl.h"
|
6
|
-
#if OSSL_OPENSSL_PREREQ(1, 1, 0) || OSSL_LIBRESSL_PREREQ(3, 6, 0)
|
7
|
-
# include <openssl/kdf.h>
|
8
|
-
#endif
|
9
|
-
|
10
|
-
static VALUE mKDF, eKDF;
|
11
|
-
|
12
|
-
/*
|
13
|
-
* call-seq:
|
14
|
-
* KDF.pbkdf2_hmac(pass, salt:, iterations:, length:, hash:) -> aString
|
15
|
-
*
|
16
|
-
* PKCS #5 PBKDF2 (Password-Based Key Derivation Function 2) in combination
|
17
|
-
* with HMAC. Takes _pass_, _salt_ and _iterations_, and then derives a key
|
18
|
-
* of _length_ bytes.
|
19
|
-
*
|
20
|
-
* For more information about PBKDF2, see RFC 2898 Section 5.2
|
21
|
-
* (https://tools.ietf.org/html/rfc2898#section-5.2).
|
22
|
-
*
|
23
|
-
* === Parameters
|
24
|
-
* pass :: The passphrase.
|
25
|
-
* salt :: The salt. Salts prevent attacks based on dictionaries of common
|
26
|
-
* passwords and attacks based on rainbow tables. It is a public
|
27
|
-
* value that can be safely stored along with the password (e.g.
|
28
|
-
* if the derived value is used for password storage).
|
29
|
-
* iterations :: The iteration count. This provides the ability to tune the
|
30
|
-
* algorithm. It is better to use the highest count possible for
|
31
|
-
* the maximum resistance to brute-force attacks.
|
32
|
-
* length :: The desired length of the derived key in octets.
|
33
|
-
* hash :: The hash algorithm used with HMAC for the PRF. May be a String
|
34
|
-
* representing the algorithm name, or an instance of
|
35
|
-
* OpenSSL::Digest.
|
36
|
-
*/
|
37
|
-
static VALUE
|
38
|
-
kdf_pbkdf2_hmac(int argc, VALUE *argv, VALUE self)
|
39
|
-
{
|
40
|
-
VALUE pass, salt, opts, kwargs[4], str;
|
41
|
-
static ID kwargs_ids[4];
|
42
|
-
int iters, len;
|
43
|
-
const EVP_MD *md;
|
44
|
-
|
45
|
-
if (!kwargs_ids[0]) {
|
46
|
-
kwargs_ids[0] = rb_intern_const("salt");
|
47
|
-
kwargs_ids[1] = rb_intern_const("iterations");
|
48
|
-
kwargs_ids[2] = rb_intern_const("length");
|
49
|
-
kwargs_ids[3] = rb_intern_const("hash");
|
50
|
-
}
|
51
|
-
rb_scan_args(argc, argv, "1:", &pass, &opts);
|
52
|
-
rb_get_kwargs(opts, kwargs_ids, 4, 0, kwargs);
|
53
|
-
|
54
|
-
StringValue(pass);
|
55
|
-
salt = StringValue(kwargs[0]);
|
56
|
-
iters = NUM2INT(kwargs[1]);
|
57
|
-
len = NUM2INT(kwargs[2]);
|
58
|
-
md = ossl_evp_get_digestbyname(kwargs[3]);
|
59
|
-
|
60
|
-
str = rb_str_new(0, len);
|
61
|
-
if (!PKCS5_PBKDF2_HMAC(RSTRING_PTR(pass), RSTRING_LENINT(pass),
|
62
|
-
(unsigned char *)RSTRING_PTR(salt),
|
63
|
-
RSTRING_LENINT(salt), iters, md, len,
|
64
|
-
(unsigned char *)RSTRING_PTR(str)))
|
65
|
-
ossl_raise(eKDF, "PKCS5_PBKDF2_HMAC");
|
66
|
-
|
67
|
-
return str;
|
68
|
-
}
|
69
|
-
|
70
|
-
#if defined(HAVE_EVP_PBE_SCRYPT)
|
71
|
-
/*
|
72
|
-
* call-seq:
|
73
|
-
* KDF.scrypt(pass, salt:, N:, r:, p:, length:) -> aString
|
74
|
-
*
|
75
|
-
* Derives a key from _pass_ using given parameters with the scrypt
|
76
|
-
* password-based key derivation function. The result can be used for password
|
77
|
-
* storage.
|
78
|
-
*
|
79
|
-
* scrypt is designed to be memory-hard and more secure against brute-force
|
80
|
-
* attacks using custom hardwares than alternative KDFs such as PBKDF2 or
|
81
|
-
* bcrypt.
|
82
|
-
*
|
83
|
-
* The keyword arguments _N_, _r_ and _p_ can be used to tune scrypt. RFC 7914
|
84
|
-
* (published on 2016-08, https://tools.ietf.org/html/rfc7914#section-2) states
|
85
|
-
* that using values r=8 and p=1 appears to yield good results.
|
86
|
-
*
|
87
|
-
* See RFC 7914 (https://tools.ietf.org/html/rfc7914) for more information.
|
88
|
-
*
|
89
|
-
* === Parameters
|
90
|
-
* pass :: Passphrase.
|
91
|
-
* salt :: Salt.
|
92
|
-
* N :: CPU/memory cost parameter. This must be a power of 2.
|
93
|
-
* r :: Block size parameter.
|
94
|
-
* p :: Parallelization parameter.
|
95
|
-
* length :: Length in octets of the derived key.
|
96
|
-
*
|
97
|
-
* === Example
|
98
|
-
* pass = "password"
|
99
|
-
* salt = SecureRandom.random_bytes(16)
|
100
|
-
* dk = OpenSSL::KDF.scrypt(pass, salt: salt, N: 2**14, r: 8, p: 1, length: 32)
|
101
|
-
* p dk #=> "\xDA\xE4\xE2...\x7F\xA1\x01T"
|
102
|
-
*/
|
103
|
-
static VALUE
|
104
|
-
kdf_scrypt(int argc, VALUE *argv, VALUE self)
|
105
|
-
{
|
106
|
-
VALUE pass, salt, opts, kwargs[5], str;
|
107
|
-
static ID kwargs_ids[5];
|
108
|
-
size_t len;
|
109
|
-
uint64_t N, r, p, maxmem;
|
110
|
-
|
111
|
-
if (!kwargs_ids[0]) {
|
112
|
-
kwargs_ids[0] = rb_intern_const("salt");
|
113
|
-
kwargs_ids[1] = rb_intern_const("N");
|
114
|
-
kwargs_ids[2] = rb_intern_const("r");
|
115
|
-
kwargs_ids[3] = rb_intern_const("p");
|
116
|
-
kwargs_ids[4] = rb_intern_const("length");
|
117
|
-
}
|
118
|
-
rb_scan_args(argc, argv, "1:", &pass, &opts);
|
119
|
-
rb_get_kwargs(opts, kwargs_ids, 5, 0, kwargs);
|
120
|
-
|
121
|
-
StringValue(pass);
|
122
|
-
salt = StringValue(kwargs[0]);
|
123
|
-
N = NUM2UINT64T(kwargs[1]);
|
124
|
-
r = NUM2UINT64T(kwargs[2]);
|
125
|
-
p = NUM2UINT64T(kwargs[3]);
|
126
|
-
len = NUM2LONG(kwargs[4]);
|
127
|
-
/*
|
128
|
-
* OpenSSL uses 32MB by default (if zero is specified), which is too small.
|
129
|
-
* Let's not limit memory consumption but just let malloc() fail inside
|
130
|
-
* OpenSSL. The amount is controllable by other parameters.
|
131
|
-
*/
|
132
|
-
maxmem = SIZE_MAX;
|
133
|
-
|
134
|
-
str = rb_str_new(0, len);
|
135
|
-
if (!EVP_PBE_scrypt(RSTRING_PTR(pass), RSTRING_LEN(pass),
|
136
|
-
(unsigned char *)RSTRING_PTR(salt), RSTRING_LEN(salt),
|
137
|
-
N, r, p, maxmem, (unsigned char *)RSTRING_PTR(str), len))
|
138
|
-
ossl_raise(eKDF, "EVP_PBE_scrypt");
|
139
|
-
|
140
|
-
return str;
|
141
|
-
}
|
142
|
-
#endif
|
143
|
-
|
144
|
-
#if OSSL_OPENSSL_PREREQ(1, 1, 0) || OSSL_LIBRESSL_PREREQ(3, 6, 0)
|
145
|
-
/*
|
146
|
-
* call-seq:
|
147
|
-
* KDF.hkdf(ikm, salt:, info:, length:, hash:) -> String
|
148
|
-
*
|
149
|
-
* HMAC-based Extract-and-Expand Key Derivation Function (HKDF) as specified in
|
150
|
-
* {RFC 5869}[https://tools.ietf.org/html/rfc5869].
|
151
|
-
*
|
152
|
-
* New in OpenSSL 1.1.0.
|
153
|
-
*
|
154
|
-
* === Parameters
|
155
|
-
* _ikm_::
|
156
|
-
* The input keying material.
|
157
|
-
* _salt_::
|
158
|
-
* The salt.
|
159
|
-
* _info_::
|
160
|
-
* The context and application specific information.
|
161
|
-
* _length_::
|
162
|
-
* The output length in octets. Must be <= <tt>255 * HashLen</tt>, where
|
163
|
-
* HashLen is the length of the hash function output in octets.
|
164
|
-
* _hash_::
|
165
|
-
* The hash function.
|
166
|
-
*
|
167
|
-
* === Example
|
168
|
-
* # The values from https://datatracker.ietf.org/doc/html/rfc5869#appendix-A.1
|
169
|
-
* ikm = ["0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b"].pack("H*")
|
170
|
-
* salt = ["000102030405060708090a0b0c"].pack("H*")
|
171
|
-
* info = ["f0f1f2f3f4f5f6f7f8f9"].pack("H*")
|
172
|
-
* p OpenSSL::KDF.hkdf(ikm, salt: salt, info: info, length: 42, hash: "SHA256").unpack1("H*")
|
173
|
-
* # => "3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c5bf34007208d5b887185865"
|
174
|
-
*/
|
175
|
-
static VALUE
|
176
|
-
kdf_hkdf(int argc, VALUE *argv, VALUE self)
|
177
|
-
{
|
178
|
-
VALUE ikm, salt, info, opts, kwargs[4], str;
|
179
|
-
static ID kwargs_ids[4];
|
180
|
-
int saltlen, ikmlen, infolen;
|
181
|
-
size_t len;
|
182
|
-
const EVP_MD *md;
|
183
|
-
EVP_PKEY_CTX *pctx;
|
184
|
-
|
185
|
-
if (!kwargs_ids[0]) {
|
186
|
-
kwargs_ids[0] = rb_intern_const("salt");
|
187
|
-
kwargs_ids[1] = rb_intern_const("info");
|
188
|
-
kwargs_ids[2] = rb_intern_const("length");
|
189
|
-
kwargs_ids[3] = rb_intern_const("hash");
|
190
|
-
}
|
191
|
-
rb_scan_args(argc, argv, "1:", &ikm, &opts);
|
192
|
-
rb_get_kwargs(opts, kwargs_ids, 4, 0, kwargs);
|
193
|
-
|
194
|
-
StringValue(ikm);
|
195
|
-
ikmlen = RSTRING_LENINT(ikm);
|
196
|
-
salt = StringValue(kwargs[0]);
|
197
|
-
saltlen = RSTRING_LENINT(salt);
|
198
|
-
info = StringValue(kwargs[1]);
|
199
|
-
infolen = RSTRING_LENINT(info);
|
200
|
-
len = (size_t)NUM2LONG(kwargs[2]);
|
201
|
-
if (len > LONG_MAX)
|
202
|
-
rb_raise(rb_eArgError, "length must be non-negative");
|
203
|
-
md = ossl_evp_get_digestbyname(kwargs[3]);
|
204
|
-
|
205
|
-
str = rb_str_new(NULL, (long)len);
|
206
|
-
pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_HKDF, NULL);
|
207
|
-
if (!pctx)
|
208
|
-
ossl_raise(eKDF, "EVP_PKEY_CTX_new_id");
|
209
|
-
if (EVP_PKEY_derive_init(pctx) <= 0) {
|
210
|
-
EVP_PKEY_CTX_free(pctx);
|
211
|
-
ossl_raise(eKDF, "EVP_PKEY_derive_init");
|
212
|
-
}
|
213
|
-
if (EVP_PKEY_CTX_set_hkdf_md(pctx, md) <= 0) {
|
214
|
-
EVP_PKEY_CTX_free(pctx);
|
215
|
-
ossl_raise(eKDF, "EVP_PKEY_CTX_set_hkdf_md");
|
216
|
-
}
|
217
|
-
if (EVP_PKEY_CTX_set1_hkdf_salt(pctx, (unsigned char *)RSTRING_PTR(salt),
|
218
|
-
saltlen) <= 0) {
|
219
|
-
EVP_PKEY_CTX_free(pctx);
|
220
|
-
ossl_raise(eKDF, "EVP_PKEY_CTX_set_hkdf_salt");
|
221
|
-
}
|
222
|
-
if (EVP_PKEY_CTX_set1_hkdf_key(pctx, (unsigned char *)RSTRING_PTR(ikm),
|
223
|
-
ikmlen) <= 0) {
|
224
|
-
EVP_PKEY_CTX_free(pctx);
|
225
|
-
ossl_raise(eKDF, "EVP_PKEY_CTX_set_hkdf_key");
|
226
|
-
}
|
227
|
-
if (EVP_PKEY_CTX_add1_hkdf_info(pctx, (unsigned char *)RSTRING_PTR(info),
|
228
|
-
infolen) <= 0) {
|
229
|
-
EVP_PKEY_CTX_free(pctx);
|
230
|
-
ossl_raise(eKDF, "EVP_PKEY_CTX_set_hkdf_info");
|
231
|
-
}
|
232
|
-
if (EVP_PKEY_derive(pctx, (unsigned char *)RSTRING_PTR(str), &len) <= 0) {
|
233
|
-
EVP_PKEY_CTX_free(pctx);
|
234
|
-
ossl_raise(eKDF, "EVP_PKEY_derive");
|
235
|
-
}
|
236
|
-
rb_str_set_len(str, (long)len);
|
237
|
-
EVP_PKEY_CTX_free(pctx);
|
238
|
-
|
239
|
-
return str;
|
240
|
-
}
|
241
|
-
#endif
|
242
|
-
|
243
|
-
void
|
244
|
-
Init_ossl_kdf(void)
|
245
|
-
{
|
246
|
-
#if 0
|
247
|
-
mOSSL = rb_define_module("OpenSSL");
|
248
|
-
eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError);
|
249
|
-
#endif
|
250
|
-
|
251
|
-
/*
|
252
|
-
* Document-module: OpenSSL::KDF
|
253
|
-
*
|
254
|
-
* Provides functionality of various KDFs (key derivation function).
|
255
|
-
*
|
256
|
-
* KDF is typically used for securely deriving arbitrary length symmetric
|
257
|
-
* keys to be used with an OpenSSL::Cipher from passwords. Another use case
|
258
|
-
* is for storing passwords: Due to the ability to tweak the effort of
|
259
|
-
* computation by increasing the iteration count, computation can be slowed
|
260
|
-
* down artificially in order to render possible attacks infeasible.
|
261
|
-
*
|
262
|
-
* Currently, OpenSSL::KDF provides implementations for the following KDF:
|
263
|
-
*
|
264
|
-
* * PKCS #5 PBKDF2 (Password-Based Key Derivation Function 2) in
|
265
|
-
* combination with HMAC
|
266
|
-
* * scrypt
|
267
|
-
* * HKDF
|
268
|
-
*
|
269
|
-
* == Examples
|
270
|
-
* === Generating a 128 bit key for a Cipher (e.g. AES)
|
271
|
-
* pass = "secret"
|
272
|
-
* salt = OpenSSL::Random.random_bytes(16)
|
273
|
-
* iter = 20_000
|
274
|
-
* key_len = 16
|
275
|
-
* key = OpenSSL::KDF.pbkdf2_hmac(pass, salt: salt, iterations: iter,
|
276
|
-
* length: key_len, hash: "sha1")
|
277
|
-
*
|
278
|
-
* === Storing Passwords
|
279
|
-
* pass = "secret"
|
280
|
-
* # store this with the generated value
|
281
|
-
* salt = OpenSSL::Random.random_bytes(16)
|
282
|
-
* iter = 20_000
|
283
|
-
* hash = OpenSSL::Digest.new('SHA256')
|
284
|
-
* len = hash.digest_length
|
285
|
-
* # the final value to be stored
|
286
|
-
* value = OpenSSL::KDF.pbkdf2_hmac(pass, salt: salt, iterations: iter,
|
287
|
-
* length: len, hash: hash)
|
288
|
-
*
|
289
|
-
* == Important Note on Checking Passwords
|
290
|
-
* When comparing passwords provided by the user with previously stored
|
291
|
-
* values, a common mistake made is comparing the two values using "==".
|
292
|
-
* Typically, "==" short-circuits on evaluation, and is therefore
|
293
|
-
* vulnerable to timing attacks. The proper way is to use a method that
|
294
|
-
* always takes the same amount of time when comparing two values, thus
|
295
|
-
* not leaking any information to potential attackers. To do this, use
|
296
|
-
* +OpenSSL.fixed_length_secure_compare+.
|
297
|
-
*/
|
298
|
-
mKDF = rb_define_module_under(mOSSL, "KDF");
|
299
|
-
/*
|
300
|
-
* Generic exception class raised if an error occurs in OpenSSL::KDF module.
|
301
|
-
*/
|
302
|
-
eKDF = rb_define_class_under(mKDF, "KDFError", eOSSLError);
|
303
|
-
|
304
|
-
rb_define_module_function(mKDF, "pbkdf2_hmac", kdf_pbkdf2_hmac, -1);
|
305
|
-
#if defined(HAVE_EVP_PBE_SCRYPT)
|
306
|
-
rb_define_module_function(mKDF, "scrypt", kdf_scrypt, -1);
|
307
|
-
#endif
|
308
|
-
#if OSSL_OPENSSL_PREREQ(1, 1, 0) || OSSL_LIBRESSL_PREREQ(3, 6, 0)
|
309
|
-
rb_define_module_function(mKDF, "hkdf", kdf_hkdf, -1);
|
310
|
-
#endif
|
311
|
-
}
|