openssl 2.1.2 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CONTRIBUTING.md +35 -45
- data/History.md +232 -0
- data/README.md +2 -2
- data/ext/openssl/extconf.rb +61 -46
- data/ext/openssl/openssl_missing.c +0 -66
- data/ext/openssl/openssl_missing.h +60 -44
- data/ext/openssl/ossl.c +112 -66
- data/ext/openssl/ossl.h +28 -11
- data/ext/openssl/ossl_asn1.c +42 -5
- data/ext/openssl/ossl_bn.c +276 -146
- data/ext/openssl/ossl_bn.h +2 -1
- data/ext/openssl/ossl_cipher.c +38 -29
- data/ext/openssl/ossl_config.c +412 -41
- data/ext/openssl/ossl_config.h +4 -7
- data/ext/openssl/ossl_digest.c +31 -62
- data/ext/openssl/ossl_engine.c +18 -27
- data/ext/openssl/ossl_hmac.c +52 -145
- data/ext/openssl/ossl_kdf.c +11 -19
- data/ext/openssl/ossl_ns_spki.c +1 -1
- data/ext/openssl/ossl_ocsp.c +9 -62
- data/ext/openssl/ossl_ocsp.h +3 -3
- data/ext/openssl/ossl_pkcs12.c +21 -3
- data/ext/openssl/ossl_pkcs7.c +45 -78
- data/ext/openssl/ossl_pkcs7.h +16 -0
- data/ext/openssl/ossl_pkey.c +1255 -178
- data/ext/openssl/ossl_pkey.h +40 -77
- data/ext/openssl/ossl_pkey_dh.c +125 -335
- data/ext/openssl/ossl_pkey_dsa.c +93 -398
- data/ext/openssl/ossl_pkey_ec.c +155 -318
- data/ext/openssl/ossl_pkey_rsa.c +105 -484
- data/ext/openssl/ossl_rand.c +2 -40
- data/ext/openssl/ossl_ssl.c +395 -364
- data/ext/openssl/ossl_ssl_session.c +24 -29
- data/ext/openssl/ossl_ts.c +1539 -0
- data/ext/openssl/ossl_ts.h +16 -0
- data/ext/openssl/ossl_x509.c +86 -1
- data/ext/openssl/ossl_x509cert.c +166 -10
- data/ext/openssl/ossl_x509crl.c +10 -7
- data/ext/openssl/ossl_x509ext.c +15 -2
- data/ext/openssl/ossl_x509name.c +16 -5
- data/ext/openssl/ossl_x509req.c +10 -7
- data/ext/openssl/ossl_x509store.c +193 -92
- data/lib/openssl/bn.rb +1 -1
- data/lib/openssl/buffering.rb +42 -17
- data/lib/openssl/cipher.rb +1 -1
- data/lib/openssl/digest.rb +10 -12
- data/lib/openssl/hmac.rb +78 -0
- data/lib/openssl/marshal.rb +30 -0
- data/lib/openssl/pkcs5.rb +1 -1
- data/lib/openssl/pkey.rb +435 -1
- data/lib/openssl/ssl.rb +53 -14
- data/lib/openssl/version.rb +5 -0
- data/lib/openssl/x509.rb +177 -1
- data/lib/openssl.rb +24 -9
- metadata +13 -69
- data/ext/openssl/deprecation.rb +0 -23
- data/ext/openssl/ossl_version.h +0 -15
- data/ext/openssl/ruby_missing.h +0 -24
- data/lib/openssl/config.rb +0 -474
data/ext/openssl/ossl_digest.c
CHANGED
@@ -63,7 +63,7 @@ ossl_evp_get_digestbyname(VALUE obj)
|
|
63
63
|
|
64
64
|
GetDigest(obj, ctx);
|
65
65
|
|
66
|
-
md =
|
66
|
+
md = EVP_MD_CTX_get0_md(ctx);
|
67
67
|
}
|
68
68
|
|
69
69
|
return md;
|
@@ -176,7 +176,7 @@ ossl_digest_reset(VALUE self)
|
|
176
176
|
EVP_MD_CTX *ctx;
|
177
177
|
|
178
178
|
GetDigest(self, ctx);
|
179
|
-
if (EVP_DigestInit_ex(ctx,
|
179
|
+
if (EVP_DigestInit_ex(ctx, EVP_MD_CTX_get0_md(ctx), NULL) != 1) {
|
180
180
|
ossl_raise(eDigestError, "Digest initialization failed.");
|
181
181
|
}
|
182
182
|
|
@@ -192,7 +192,7 @@ ossl_digest_reset(VALUE self)
|
|
192
192
|
* be passed individually to the Digest instance.
|
193
193
|
*
|
194
194
|
* === Example
|
195
|
-
* digest = OpenSSL::Digest
|
195
|
+
* digest = OpenSSL::Digest.new('SHA256')
|
196
196
|
* digest.update('First input')
|
197
197
|
* digest << 'Second input' # equivalent to digest.update('Second input')
|
198
198
|
* result = digest.digest
|
@@ -248,7 +248,7 @@ ossl_digest_finish(int argc, VALUE *argv, VALUE self)
|
|
248
248
|
* Returns the sn of this Digest algorithm.
|
249
249
|
*
|
250
250
|
* === Example
|
251
|
-
* digest = OpenSSL::Digest
|
251
|
+
* digest = OpenSSL::Digest.new('SHA512')
|
252
252
|
* puts digest.name # => SHA512
|
253
253
|
*
|
254
254
|
*/
|
@@ -259,7 +259,7 @@ ossl_digest_name(VALUE self)
|
|
259
259
|
|
260
260
|
GetDigest(self, ctx);
|
261
261
|
|
262
|
-
return
|
262
|
+
return rb_str_new_cstr(EVP_MD_name(EVP_MD_CTX_get0_md(ctx)));
|
263
263
|
}
|
264
264
|
|
265
265
|
/*
|
@@ -270,7 +270,7 @@ ossl_digest_name(VALUE self)
|
|
270
270
|
* final message digest result.
|
271
271
|
*
|
272
272
|
* === Example
|
273
|
-
* digest = OpenSSL::Digest
|
273
|
+
* digest = OpenSSL::Digest.new('SHA1')
|
274
274
|
* puts digest.digest_length # => 20
|
275
275
|
*
|
276
276
|
*/
|
@@ -294,7 +294,7 @@ ossl_digest_size(VALUE self)
|
|
294
294
|
* consecutively.
|
295
295
|
*
|
296
296
|
* === Example
|
297
|
-
* digest = OpenSSL::Digest
|
297
|
+
* digest = OpenSSL::Digest.new('SHA1')
|
298
298
|
* puts digest.block_length # => 64
|
299
299
|
*/
|
300
300
|
static VALUE
|
@@ -313,8 +313,6 @@ ossl_digest_block_length(VALUE self)
|
|
313
313
|
void
|
314
314
|
Init_ossl_digest(void)
|
315
315
|
{
|
316
|
-
rb_require("digest");
|
317
|
-
|
318
316
|
#if 0
|
319
317
|
mOSSL = rb_define_module("OpenSSL");
|
320
318
|
eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError);
|
@@ -348,54 +346,19 @@ Init_ossl_digest(void)
|
|
348
346
|
* the integrity of a signed document, it suffices to re-compute the hash
|
349
347
|
* and verify that it is equal to that in the signature.
|
350
348
|
*
|
351
|
-
*
|
352
|
-
*
|
353
|
-
* * MD2, MD4, MDC2 and MD5
|
354
|
-
* * RIPEMD160
|
355
|
-
* * DSS, DSS1 (Pseudo algorithms to be used for DSA signatures. DSS is
|
356
|
-
* equal to SHA and DSS1 is equal to SHA1)
|
349
|
+
* You can get a list of all digest algorithms supported on your system by
|
350
|
+
* running this command in your terminal:
|
357
351
|
*
|
358
|
-
*
|
359
|
-
* can be instantiated as simply as e.g.
|
352
|
+
* openssl list -digest-algorithms
|
360
353
|
*
|
361
|
-
*
|
354
|
+
* Among the OpenSSL 1.1.1 supported message digest algorithms are:
|
355
|
+
* * SHA224, SHA256, SHA384, SHA512, SHA512-224 and SHA512-256
|
356
|
+
* * SHA3-224, SHA3-256, SHA3-384 and SHA3-512
|
357
|
+
* * BLAKE2s256 and BLAKE2b512
|
362
358
|
*
|
363
|
-
*
|
359
|
+
* Each of these algorithms can be instantiated using the name:
|
364
360
|
*
|
365
|
-
*
|
366
|
-
* <openssl/object.h> and <openssl/obj_mac.h>. They are textual
|
367
|
-
* representations of ASN.1 OBJECT IDENTIFIERs. Each supported digest
|
368
|
-
* algorithm has an OBJECT IDENTIFIER associated to it and those again
|
369
|
-
* have short/long names assigned to them.
|
370
|
-
* E.g. the OBJECT IDENTIFIER for SHA-1 is 1.3.14.3.2.26 and its
|
371
|
-
* sn is "SHA1" and its ln is "sha1".
|
372
|
-
* ==== MD2
|
373
|
-
* * sn: MD2
|
374
|
-
* * ln: md2
|
375
|
-
* ==== MD4
|
376
|
-
* * sn: MD4
|
377
|
-
* * ln: md4
|
378
|
-
* ==== MD5
|
379
|
-
* * sn: MD5
|
380
|
-
* * ln: md5
|
381
|
-
* ==== SHA
|
382
|
-
* * sn: SHA
|
383
|
-
* * ln: SHA
|
384
|
-
* ==== SHA-1
|
385
|
-
* * sn: SHA1
|
386
|
-
* * ln: sha1
|
387
|
-
* ==== SHA-224
|
388
|
-
* * sn: SHA224
|
389
|
-
* * ln: sha224
|
390
|
-
* ==== SHA-256
|
391
|
-
* * sn: SHA256
|
392
|
-
* * ln: sha256
|
393
|
-
* ==== SHA-384
|
394
|
-
* * sn: SHA384
|
395
|
-
* * ln: sha384
|
396
|
-
* ==== SHA-512
|
397
|
-
* * sn: SHA512
|
398
|
-
* * ln: sha512
|
361
|
+
* digest = OpenSSL::Digest.new('SHA256')
|
399
362
|
*
|
400
363
|
* "Breaking" a message digest algorithm means defying its one-way
|
401
364
|
* function characteristics, i.e. producing a collision or finding a way
|
@@ -407,16 +370,16 @@ Init_ossl_digest(void)
|
|
407
370
|
*
|
408
371
|
* === Hashing a file
|
409
372
|
*
|
410
|
-
* data = File.
|
411
|
-
* sha256 = OpenSSL::Digest
|
373
|
+
* data = File.binread('document')
|
374
|
+
* sha256 = OpenSSL::Digest.new('SHA256')
|
412
375
|
* digest = sha256.digest(data)
|
413
376
|
*
|
414
377
|
* === Hashing several pieces of data at once
|
415
378
|
*
|
416
|
-
* data1 = File.
|
417
|
-
* data2 = File.
|
418
|
-
* data3 = File.
|
419
|
-
* sha256 = OpenSSL::Digest
|
379
|
+
* data1 = File.binread('file1')
|
380
|
+
* data2 = File.binread('file2')
|
381
|
+
* data3 = File.binread('file3')
|
382
|
+
* sha256 = OpenSSL::Digest.new('SHA256')
|
420
383
|
* sha256 << data1
|
421
384
|
* sha256 << data2
|
422
385
|
* sha256 << data3
|
@@ -424,15 +387,21 @@ Init_ossl_digest(void)
|
|
424
387
|
*
|
425
388
|
* === Reuse a Digest instance
|
426
389
|
*
|
427
|
-
* data1 = File.
|
428
|
-
* sha256 = OpenSSL::Digest
|
390
|
+
* data1 = File.binread('file1')
|
391
|
+
* sha256 = OpenSSL::Digest.new('SHA256')
|
429
392
|
* digest1 = sha256.digest(data1)
|
430
393
|
*
|
431
|
-
* data2 = File.
|
394
|
+
* data2 = File.binread('file2')
|
432
395
|
* sha256.reset
|
433
396
|
* digest2 = sha256.digest(data2)
|
434
397
|
*
|
435
398
|
*/
|
399
|
+
|
400
|
+
/*
|
401
|
+
* Digest::Class is defined by the digest library. rb_require() cannot be
|
402
|
+
* used here because it bypasses RubyGems.
|
403
|
+
*/
|
404
|
+
rb_funcall(Qnil, rb_intern_const("require"), 1, rb_str_new_cstr("digest"));
|
436
405
|
cDigest = rb_define_class_under(mOSSL, "Digest", rb_path2class("Digest::Class"));
|
437
406
|
/* Document-class: OpenSSL::Digest::DigestError
|
438
407
|
*
|
data/ext/openssl/ossl_engine.c
CHANGED
@@ -9,7 +9,8 @@
|
|
9
9
|
*/
|
10
10
|
#include "ossl.h"
|
11
11
|
|
12
|
-
#
|
12
|
+
#ifdef OSSL_USE_ENGINE
|
13
|
+
# include <openssl/engine.h>
|
13
14
|
|
14
15
|
#define NewEngine(klass) \
|
15
16
|
TypedData_Wrap_Struct((klass), &ossl_engine_type, 0)
|
@@ -93,9 +94,6 @@ static const rb_data_type_t ossl_engine_type = {
|
|
93
94
|
static VALUE
|
94
95
|
ossl_engine_s_load(int argc, VALUE *argv, VALUE klass)
|
95
96
|
{
|
96
|
-
#if !defined(HAVE_ENGINE_LOAD_BUILTIN_ENGINES)
|
97
|
-
return Qnil;
|
98
|
-
#else
|
99
97
|
VALUE name;
|
100
98
|
|
101
99
|
rb_scan_args(argc, argv, "01", &name);
|
@@ -104,60 +102,53 @@ ossl_engine_s_load(int argc, VALUE *argv, VALUE klass)
|
|
104
102
|
return Qtrue;
|
105
103
|
}
|
106
104
|
StringValueCStr(name);
|
107
|
-
#
|
108
|
-
#if HAVE_ENGINE_LOAD_DYNAMIC
|
105
|
+
#ifdef HAVE_ENGINE_LOAD_DYNAMIC
|
109
106
|
OSSL_ENGINE_LOAD_IF_MATCH(dynamic, DYNAMIC);
|
110
107
|
#endif
|
111
|
-
#
|
108
|
+
#ifndef OPENSSL_NO_STATIC_ENGINE
|
109
|
+
#ifdef HAVE_ENGINE_LOAD_4758CCA
|
112
110
|
OSSL_ENGINE_LOAD_IF_MATCH(4758cca, 4758CCA);
|
113
111
|
#endif
|
114
|
-
#
|
112
|
+
#ifdef HAVE_ENGINE_LOAD_AEP
|
115
113
|
OSSL_ENGINE_LOAD_IF_MATCH(aep, AEP);
|
116
114
|
#endif
|
117
|
-
#
|
115
|
+
#ifdef HAVE_ENGINE_LOAD_ATALLA
|
118
116
|
OSSL_ENGINE_LOAD_IF_MATCH(atalla, ATALLA);
|
119
117
|
#endif
|
120
|
-
#
|
118
|
+
#ifdef HAVE_ENGINE_LOAD_CHIL
|
121
119
|
OSSL_ENGINE_LOAD_IF_MATCH(chil, CHIL);
|
122
120
|
#endif
|
123
|
-
#
|
121
|
+
#ifdef HAVE_ENGINE_LOAD_CSWIFT
|
124
122
|
OSSL_ENGINE_LOAD_IF_MATCH(cswift, CSWIFT);
|
125
123
|
#endif
|
126
|
-
#
|
124
|
+
#ifdef HAVE_ENGINE_LOAD_NURON
|
127
125
|
OSSL_ENGINE_LOAD_IF_MATCH(nuron, NURON);
|
128
126
|
#endif
|
129
|
-
#
|
127
|
+
#ifdef HAVE_ENGINE_LOAD_SUREWARE
|
130
128
|
OSSL_ENGINE_LOAD_IF_MATCH(sureware, SUREWARE);
|
131
129
|
#endif
|
132
|
-
#
|
130
|
+
#ifdef HAVE_ENGINE_LOAD_UBSEC
|
133
131
|
OSSL_ENGINE_LOAD_IF_MATCH(ubsec, UBSEC);
|
134
132
|
#endif
|
135
|
-
#
|
133
|
+
#ifdef HAVE_ENGINE_LOAD_PADLOCK
|
136
134
|
OSSL_ENGINE_LOAD_IF_MATCH(padlock, PADLOCK);
|
137
135
|
#endif
|
138
|
-
#
|
136
|
+
#ifdef HAVE_ENGINE_LOAD_CAPI
|
139
137
|
OSSL_ENGINE_LOAD_IF_MATCH(capi, CAPI);
|
140
138
|
#endif
|
141
|
-
#
|
139
|
+
#ifdef HAVE_ENGINE_LOAD_GMP
|
142
140
|
OSSL_ENGINE_LOAD_IF_MATCH(gmp, GMP);
|
143
141
|
#endif
|
144
|
-
#
|
142
|
+
#ifdef HAVE_ENGINE_LOAD_GOST
|
145
143
|
OSSL_ENGINE_LOAD_IF_MATCH(gost, GOST);
|
146
144
|
#endif
|
147
|
-
#if HAVE_ENGINE_LOAD_CRYPTODEV
|
148
|
-
OSSL_ENGINE_LOAD_IF_MATCH(cryptodev, CRYPTODEV);
|
149
|
-
#endif
|
150
|
-
#if HAVE_ENGINE_LOAD_AESNI
|
151
|
-
OSSL_ENGINE_LOAD_IF_MATCH(aesni, AESNI);
|
152
145
|
#endif
|
153
|
-
#
|
154
|
-
|
155
|
-
OSSL_ENGINE_LOAD_IF_MATCH(openbsd_dev_crypto, OPENBSD_DEV_CRYPTO);
|
146
|
+
#ifdef HAVE_ENGINE_LOAD_CRYPTODEV
|
147
|
+
OSSL_ENGINE_LOAD_IF_MATCH(cryptodev, CRYPTODEV);
|
156
148
|
#endif
|
157
149
|
OSSL_ENGINE_LOAD_IF_MATCH(openssl, OPENSSL);
|
158
150
|
rb_warning("no such builtin loader for `%"PRIsVALUE"'", name);
|
159
151
|
return Qnil;
|
160
|
-
#endif /* HAVE_ENGINE_LOAD_BUILTIN_ENGINES */
|
161
152
|
}
|
162
153
|
|
163
154
|
/*
|
data/ext/openssl/ossl_hmac.c
CHANGED
@@ -7,14 +7,12 @@
|
|
7
7
|
* This program is licensed under the same licence as Ruby.
|
8
8
|
* (See the file 'LICENCE'.)
|
9
9
|
*/
|
10
|
-
#if !defined(OPENSSL_NO_HMAC)
|
11
|
-
|
12
10
|
#include "ossl.h"
|
13
11
|
|
14
12
|
#define NewHMAC(klass) \
|
15
13
|
TypedData_Wrap_Struct((klass), &ossl_hmac_type, 0)
|
16
14
|
#define GetHMAC(obj, ctx) do { \
|
17
|
-
TypedData_Get_Struct((obj),
|
15
|
+
TypedData_Get_Struct((obj), EVP_MD_CTX, &ossl_hmac_type, (ctx)); \
|
18
16
|
if (!(ctx)) { \
|
19
17
|
ossl_raise(rb_eRuntimeError, "HMAC wasn't initialized"); \
|
20
18
|
} \
|
@@ -36,7 +34,7 @@ VALUE eHMACError;
|
|
36
34
|
static void
|
37
35
|
ossl_hmac_free(void *ctx)
|
38
36
|
{
|
39
|
-
|
37
|
+
EVP_MD_CTX_free(ctx);
|
40
38
|
}
|
41
39
|
|
42
40
|
static const rb_data_type_t ossl_hmac_type = {
|
@@ -51,12 +49,12 @@ static VALUE
|
|
51
49
|
ossl_hmac_alloc(VALUE klass)
|
52
50
|
{
|
53
51
|
VALUE obj;
|
54
|
-
|
52
|
+
EVP_MD_CTX *ctx;
|
55
53
|
|
56
54
|
obj = NewHMAC(klass);
|
57
|
-
ctx =
|
55
|
+
ctx = EVP_MD_CTX_new();
|
58
56
|
if (!ctx)
|
59
|
-
|
57
|
+
ossl_raise(eHMACError, "EVP_MD_CTX");
|
60
58
|
RTYPEDDATA_DATA(obj) = ctx;
|
61
59
|
|
62
60
|
return obj;
|
@@ -76,37 +74,41 @@ ossl_hmac_alloc(VALUE klass)
|
|
76
74
|
* === Example
|
77
75
|
*
|
78
76
|
* key = 'key'
|
79
|
-
*
|
80
|
-
* instance = OpenSSL::HMAC.new(key, digest)
|
77
|
+
* instance = OpenSSL::HMAC.new(key, 'SHA1')
|
81
78
|
* #=> f42bb0eeb018ebbd4597ae7213711ec60760843f
|
82
79
|
* instance.class
|
83
80
|
* #=> OpenSSL::HMAC
|
84
81
|
*
|
85
82
|
* === A note about comparisons
|
86
83
|
*
|
87
|
-
* Two instances
|
88
|
-
* same value. Use #to_s or #hexdigest to return the authentication code that
|
89
|
-
* the instance represents. For example:
|
84
|
+
* Two instances can be securely compared with #== in constant time:
|
90
85
|
*
|
91
|
-
* other_instance = OpenSSL::HMAC.new('key',
|
92
|
-
*
|
93
|
-
*
|
94
|
-
*
|
95
|
-
* instance == other_instance
|
96
|
-
* #=> false
|
97
|
-
* instance.to_s == other_instance.to_s
|
98
|
-
* #=> true
|
86
|
+
* other_instance = OpenSSL::HMAC.new('key', 'SHA1')
|
87
|
+
* #=> f42bb0eeb018ebbd4597ae7213711ec60760843f
|
88
|
+
* instance == other_instance
|
89
|
+
* #=> true
|
99
90
|
*
|
100
91
|
*/
|
101
92
|
static VALUE
|
102
93
|
ossl_hmac_initialize(VALUE self, VALUE key, VALUE digest)
|
103
94
|
{
|
104
|
-
|
95
|
+
EVP_MD_CTX *ctx;
|
96
|
+
EVP_PKEY *pkey;
|
105
97
|
|
106
|
-
StringValue(key);
|
107
98
|
GetHMAC(self, ctx);
|
108
|
-
|
109
|
-
|
99
|
+
StringValue(key);
|
100
|
+
pkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL,
|
101
|
+
(unsigned char *)RSTRING_PTR(key),
|
102
|
+
RSTRING_LENINT(key));
|
103
|
+
if (!pkey)
|
104
|
+
ossl_raise(eHMACError, "EVP_PKEY_new_mac_key");
|
105
|
+
if (EVP_DigestSignInit(ctx, NULL, ossl_evp_get_digestbyname(digest),
|
106
|
+
NULL, pkey) != 1) {
|
107
|
+
EVP_PKEY_free(pkey);
|
108
|
+
ossl_raise(eHMACError, "EVP_DigestSignInit");
|
109
|
+
}
|
110
|
+
/* Decrement reference counter; EVP_MD_CTX still keeps it */
|
111
|
+
EVP_PKEY_free(pkey);
|
110
112
|
|
111
113
|
return self;
|
112
114
|
}
|
@@ -114,16 +116,15 @@ ossl_hmac_initialize(VALUE self, VALUE key, VALUE digest)
|
|
114
116
|
static VALUE
|
115
117
|
ossl_hmac_copy(VALUE self, VALUE other)
|
116
118
|
{
|
117
|
-
|
119
|
+
EVP_MD_CTX *ctx1, *ctx2;
|
118
120
|
|
119
121
|
rb_check_frozen(self);
|
120
122
|
if (self == other) return self;
|
121
123
|
|
122
124
|
GetHMAC(self, ctx1);
|
123
125
|
GetHMAC(other, ctx2);
|
124
|
-
|
125
|
-
|
126
|
-
ossl_raise(eHMACError, "HMAC_CTX_copy");
|
126
|
+
if (EVP_MD_CTX_copy(ctx1, ctx2) != 1)
|
127
|
+
ossl_raise(eHMACError, "EVP_MD_CTX_copy");
|
127
128
|
return self;
|
128
129
|
}
|
129
130
|
|
@@ -148,33 +149,16 @@ ossl_hmac_copy(VALUE self, VALUE other)
|
|
148
149
|
static VALUE
|
149
150
|
ossl_hmac_update(VALUE self, VALUE data)
|
150
151
|
{
|
151
|
-
|
152
|
+
EVP_MD_CTX *ctx;
|
152
153
|
|
153
154
|
StringValue(data);
|
154
155
|
GetHMAC(self, ctx);
|
155
|
-
|
156
|
+
if (EVP_DigestSignUpdate(ctx, RSTRING_PTR(data), RSTRING_LEN(data)) != 1)
|
157
|
+
ossl_raise(eHMACError, "EVP_DigestSignUpdate");
|
156
158
|
|
157
159
|
return self;
|
158
160
|
}
|
159
161
|
|
160
|
-
static void
|
161
|
-
hmac_final(HMAC_CTX *ctx, unsigned char *buf, unsigned int *buf_len)
|
162
|
-
{
|
163
|
-
HMAC_CTX *final;
|
164
|
-
|
165
|
-
final = HMAC_CTX_new();
|
166
|
-
if (!final)
|
167
|
-
ossl_raise(eHMACError, "HMAC_CTX_new");
|
168
|
-
|
169
|
-
if (!HMAC_CTX_copy(final, ctx)) {
|
170
|
-
HMAC_CTX_free(final);
|
171
|
-
ossl_raise(eHMACError, "HMAC_CTX_copy");
|
172
|
-
}
|
173
|
-
|
174
|
-
HMAC_Final(final, buf, buf_len);
|
175
|
-
HMAC_CTX_free(final);
|
176
|
-
}
|
177
|
-
|
178
162
|
/*
|
179
163
|
* call-seq:
|
180
164
|
* hmac.digest -> string
|
@@ -182,7 +166,7 @@ hmac_final(HMAC_CTX *ctx, unsigned char *buf, unsigned int *buf_len)
|
|
182
166
|
* Returns the authentication code an instance represents as a binary string.
|
183
167
|
*
|
184
168
|
* === Example
|
185
|
-
* instance = OpenSSL::HMAC.new('key',
|
169
|
+
* instance = OpenSSL::HMAC.new('key', 'SHA1')
|
186
170
|
* #=> f42bb0eeb018ebbd4597ae7213711ec60760843f
|
187
171
|
* instance.digest
|
188
172
|
* #=> "\xF4+\xB0\xEE\xB0\x18\xEB\xBDE\x97\xAEr\x13q\x1E\xC6\a`\x84?"
|
@@ -190,15 +174,16 @@ hmac_final(HMAC_CTX *ctx, unsigned char *buf, unsigned int *buf_len)
|
|
190
174
|
static VALUE
|
191
175
|
ossl_hmac_digest(VALUE self)
|
192
176
|
{
|
193
|
-
|
194
|
-
|
177
|
+
EVP_MD_CTX *ctx;
|
178
|
+
size_t buf_len = EVP_MAX_MD_SIZE;
|
195
179
|
VALUE ret;
|
196
180
|
|
197
181
|
GetHMAC(self, ctx);
|
198
182
|
ret = rb_str_new(NULL, EVP_MAX_MD_SIZE);
|
199
|
-
|
200
|
-
|
201
|
-
|
183
|
+
if (EVP_DigestSignFinal(ctx, (unsigned char *)RSTRING_PTR(ret),
|
184
|
+
&buf_len) != 1)
|
185
|
+
ossl_raise(eHMACError, "EVP_DigestSignFinal");
|
186
|
+
rb_str_set_len(ret, (long)buf_len);
|
202
187
|
|
203
188
|
return ret;
|
204
189
|
}
|
@@ -213,13 +198,14 @@ ossl_hmac_digest(VALUE self)
|
|
213
198
|
static VALUE
|
214
199
|
ossl_hmac_hexdigest(VALUE self)
|
215
200
|
{
|
216
|
-
|
201
|
+
EVP_MD_CTX *ctx;
|
217
202
|
unsigned char buf[EVP_MAX_MD_SIZE];
|
218
|
-
|
203
|
+
size_t buf_len = EVP_MAX_MD_SIZE;
|
219
204
|
VALUE ret;
|
220
205
|
|
221
206
|
GetHMAC(self, ctx);
|
222
|
-
|
207
|
+
if (EVP_DigestSignFinal(ctx, buf, &buf_len) != 1)
|
208
|
+
ossl_raise(eHMACError, "EVP_DigestSignFinal");
|
223
209
|
ret = rb_str_new(NULL, buf_len * 2);
|
224
210
|
ossl_bin2hex(buf, RSTRING_PTR(ret), buf_len);
|
225
211
|
|
@@ -236,7 +222,7 @@ ossl_hmac_hexdigest(VALUE self)
|
|
236
222
|
* === Example
|
237
223
|
*
|
238
224
|
* data = "The quick brown fox jumps over the lazy dog"
|
239
|
-
* instance = OpenSSL::HMAC.new('key',
|
225
|
+
* instance = OpenSSL::HMAC.new('key', 'SHA1')
|
240
226
|
* #=> f42bb0eeb018ebbd4597ae7213711ec60760843f
|
241
227
|
*
|
242
228
|
* instance.update(data)
|
@@ -248,84 +234,17 @@ ossl_hmac_hexdigest(VALUE self)
|
|
248
234
|
static VALUE
|
249
235
|
ossl_hmac_reset(VALUE self)
|
250
236
|
{
|
251
|
-
|
237
|
+
EVP_MD_CTX *ctx;
|
238
|
+
EVP_PKEY *pkey;
|
252
239
|
|
253
240
|
GetHMAC(self, ctx);
|
254
|
-
|
241
|
+
pkey = EVP_PKEY_CTX_get0_pkey(EVP_MD_CTX_get_pkey_ctx(ctx));
|
242
|
+
if (EVP_DigestSignInit(ctx, NULL, EVP_MD_CTX_get0_md(ctx), NULL, pkey) != 1)
|
243
|
+
ossl_raise(eHMACError, "EVP_DigestSignInit");
|
255
244
|
|
256
245
|
return self;
|
257
246
|
}
|
258
247
|
|
259
|
-
/*
|
260
|
-
* call-seq:
|
261
|
-
* HMAC.digest(digest, key, data) -> aString
|
262
|
-
*
|
263
|
-
* Returns the authentication code as a binary string. The _digest_ parameter
|
264
|
-
* specifies the digest algorithm to use. This may be a String representing
|
265
|
-
* the algorithm name or an instance of OpenSSL::Digest.
|
266
|
-
*
|
267
|
-
* === Example
|
268
|
-
*
|
269
|
-
* key = 'key'
|
270
|
-
* data = 'The quick brown fox jumps over the lazy dog'
|
271
|
-
*
|
272
|
-
* hmac = OpenSSL::HMAC.digest('sha1', key, data)
|
273
|
-
* #=> "\xDE|\x9B\x85\xB8\xB7\x8A\xA6\xBC\x8Az6\xF7\n\x90p\x1C\x9D\xB4\xD9"
|
274
|
-
*
|
275
|
-
*/
|
276
|
-
static VALUE
|
277
|
-
ossl_hmac_s_digest(VALUE klass, VALUE digest, VALUE key, VALUE data)
|
278
|
-
{
|
279
|
-
unsigned char *buf;
|
280
|
-
unsigned int buf_len;
|
281
|
-
|
282
|
-
StringValue(key);
|
283
|
-
StringValue(data);
|
284
|
-
buf = HMAC(ossl_evp_get_digestbyname(digest), RSTRING_PTR(key),
|
285
|
-
RSTRING_LENINT(key), (unsigned char *)RSTRING_PTR(data),
|
286
|
-
RSTRING_LEN(data), NULL, &buf_len);
|
287
|
-
|
288
|
-
return rb_str_new((const char *)buf, buf_len);
|
289
|
-
}
|
290
|
-
|
291
|
-
/*
|
292
|
-
* call-seq:
|
293
|
-
* HMAC.hexdigest(digest, key, data) -> aString
|
294
|
-
*
|
295
|
-
* Returns the authentication code as a hex-encoded string. The _digest_
|
296
|
-
* parameter specifies the digest algorithm to use. This may be a String
|
297
|
-
* representing the algorithm name or an instance of OpenSSL::Digest.
|
298
|
-
*
|
299
|
-
* === Example
|
300
|
-
*
|
301
|
-
* key = 'key'
|
302
|
-
* data = 'The quick brown fox jumps over the lazy dog'
|
303
|
-
*
|
304
|
-
* hmac = OpenSSL::HMAC.hexdigest('sha1', key, data)
|
305
|
-
* #=> "de7c9b85b8b78aa6bc8a7a36f70a90701c9db4d9"
|
306
|
-
*
|
307
|
-
*/
|
308
|
-
static VALUE
|
309
|
-
ossl_hmac_s_hexdigest(VALUE klass, VALUE digest, VALUE key, VALUE data)
|
310
|
-
{
|
311
|
-
unsigned char buf[EVP_MAX_MD_SIZE];
|
312
|
-
unsigned int buf_len;
|
313
|
-
VALUE ret;
|
314
|
-
|
315
|
-
StringValue(key);
|
316
|
-
StringValue(data);
|
317
|
-
|
318
|
-
if (!HMAC(ossl_evp_get_digestbyname(digest), RSTRING_PTR(key),
|
319
|
-
RSTRING_LENINT(key), (unsigned char *)RSTRING_PTR(data),
|
320
|
-
RSTRING_LEN(data), buf, &buf_len))
|
321
|
-
ossl_raise(eHMACError, "HMAC");
|
322
|
-
|
323
|
-
ret = rb_str_new(NULL, buf_len * 2);
|
324
|
-
ossl_bin2hex(buf, RSTRING_PTR(ret), buf_len);
|
325
|
-
|
326
|
-
return ret;
|
327
|
-
}
|
328
|
-
|
329
248
|
/*
|
330
249
|
* INIT
|
331
250
|
*/
|
@@ -356,11 +275,10 @@ Init_ossl_hmac(void)
|
|
356
275
|
*
|
357
276
|
* === HMAC-SHA256 using incremental interface
|
358
277
|
*
|
359
|
-
* data1 = File.
|
360
|
-
* data2 = File.
|
278
|
+
* data1 = File.binread("file1")
|
279
|
+
* data2 = File.binread("file2")
|
361
280
|
* key = "key"
|
362
|
-
*
|
363
|
-
* hmac = OpenSSL::HMAC.new(key, digest)
|
281
|
+
* hmac = OpenSSL::HMAC.new(key, 'SHA256')
|
364
282
|
* hmac << data1
|
365
283
|
* hmac << data2
|
366
284
|
* mac = hmac.digest
|
@@ -370,8 +288,6 @@ Init_ossl_hmac(void)
|
|
370
288
|
cHMAC = rb_define_class_under(mOSSL, "HMAC", rb_cObject);
|
371
289
|
|
372
290
|
rb_define_alloc_func(cHMAC, ossl_hmac_alloc);
|
373
|
-
rb_define_singleton_method(cHMAC, "digest", ossl_hmac_s_digest, 3);
|
374
|
-
rb_define_singleton_method(cHMAC, "hexdigest", ossl_hmac_s_hexdigest, 3);
|
375
291
|
|
376
292
|
rb_define_method(cHMAC, "initialize", ossl_hmac_initialize, 2);
|
377
293
|
rb_define_method(cHMAC, "initialize_copy", ossl_hmac_copy, 1);
|
@@ -384,12 +300,3 @@ Init_ossl_hmac(void)
|
|
384
300
|
rb_define_alias(cHMAC, "inspect", "hexdigest");
|
385
301
|
rb_define_alias(cHMAC, "to_s", "hexdigest");
|
386
302
|
}
|
387
|
-
|
388
|
-
#else /* NO_HMAC */
|
389
|
-
# warning >>> OpenSSL is compiled without HMAC support <<<
|
390
|
-
void
|
391
|
-
Init_ossl_hmac(void)
|
392
|
-
{
|
393
|
-
rb_warning("HMAC is not available: OpenSSL is compiled without HMAC.");
|
394
|
-
}
|
395
|
-
#endif /* NO_HMAC */
|
data/ext/openssl/ossl_kdf.c
CHANGED
@@ -163,6 +163,14 @@ kdf_scrypt(int argc, VALUE *argv, VALUE self)
|
|
163
163
|
* HashLen is the length of the hash function output in octets.
|
164
164
|
* _hash_::
|
165
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"
|
166
174
|
*/
|
167
175
|
static VALUE
|
168
176
|
kdf_hkdf(int argc, VALUE *argv, VALUE self)
|
@@ -272,7 +280,7 @@ Init_ossl_kdf(void)
|
|
272
280
|
* # store this with the generated value
|
273
281
|
* salt = OpenSSL::Random.random_bytes(16)
|
274
282
|
* iter = 20_000
|
275
|
-
* hash = OpenSSL::Digest
|
283
|
+
* hash = OpenSSL::Digest.new('SHA256')
|
276
284
|
* len = hash.digest_length
|
277
285
|
* # the final value to be stored
|
278
286
|
* value = OpenSSL::KDF.pbkdf2_hmac(pass, salt: salt, iterations: iter,
|
@@ -284,24 +292,8 @@ Init_ossl_kdf(void)
|
|
284
292
|
* Typically, "==" short-circuits on evaluation, and is therefore
|
285
293
|
* vulnerable to timing attacks. The proper way is to use a method that
|
286
294
|
* always takes the same amount of time when comparing two values, thus
|
287
|
-
* not leaking any information to potential attackers. To
|
288
|
-
*
|
289
|
-
*
|
290
|
-
* def eql_time_cmp(a, b)
|
291
|
-
* unless a.length == b.length
|
292
|
-
* return false
|
293
|
-
* end
|
294
|
-
* cmp = b.bytes
|
295
|
-
* result = 0
|
296
|
-
* a.bytes.each_with_index {|c,i|
|
297
|
-
* result |= c ^ cmp[i]
|
298
|
-
* }
|
299
|
-
* result == 0
|
300
|
-
* end
|
301
|
-
*
|
302
|
-
* Please note that the premature return in case of differing lengths
|
303
|
-
* typically does not leak valuable information - when using PBKDF2, the
|
304
|
-
* length of the values to be compared is of fixed size.
|
295
|
+
* not leaking any information to potential attackers. To do this, use
|
296
|
+
* +OpenSSL.fixed_length_secure_compare+.
|
305
297
|
*/
|
306
298
|
mKDF = rb_define_module_under(mOSSL, "KDF");
|
307
299
|
/*
|
data/ext/openssl/ossl_ns_spki.c
CHANGED
@@ -350,7 +350,7 @@ ossl_spki_verify(VALUE self, VALUE key)
|
|
350
350
|
* spki = OpenSSL::Netscape::SPKI.new
|
351
351
|
* spki.challenge = "RandomChallenge"
|
352
352
|
* spki.public_key = key.public_key
|
353
|
-
* spki.sign(key, OpenSSL::Digest
|
353
|
+
* spki.sign(key, OpenSSL::Digest.new('SHA256'))
|
354
354
|
* #send a request containing this to a server generating a certificate
|
355
355
|
* === Verifying an SPKI request
|
356
356
|
* request = #...
|