openssl 2.1.3 → 3.1.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 +302 -1
- data/README.md +2 -2
- data/ext/openssl/extconf.rb +77 -62
- data/ext/openssl/openssl_missing.c +0 -66
- data/ext/openssl/openssl_missing.h +59 -43
- data/ext/openssl/ossl.c +110 -64
- data/ext/openssl/ossl.h +33 -10
- data/ext/openssl/ossl_asn1.c +51 -13
- data/ext/openssl/ossl_bn.c +275 -146
- data/ext/openssl/ossl_bn.h +2 -1
- data/ext/openssl/ossl_cipher.c +39 -31
- data/ext/openssl/ossl_config.c +412 -41
- data/ext/openssl/ossl_config.h +4 -7
- data/ext/openssl/ossl_digest.c +25 -60
- data/ext/openssl/ossl_engine.c +18 -27
- data/ext/openssl/ossl_hmac.c +60 -145
- data/ext/openssl/ossl_kdf.c +14 -22
- data/ext/openssl/ossl_ns_spki.c +1 -1
- data/ext/openssl/ossl_ocsp.c +11 -64
- 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 +1295 -178
- data/ext/openssl/ossl_pkey.h +36 -73
- data/ext/openssl/ossl_pkey_dh.c +130 -340
- data/ext/openssl/ossl_pkey_dsa.c +100 -405
- data/ext/openssl/ossl_pkey_ec.c +192 -335
- data/ext/openssl/ossl_pkey_rsa.c +110 -489
- data/ext/openssl/ossl_rand.c +2 -32
- data/ext/openssl/ossl_ssl.c +556 -442
- data/ext/openssl/ossl_ssl_session.c +28 -29
- data/ext/openssl/ossl_ts.c +1539 -0
- data/ext/openssl/ossl_ts.h +16 -0
- data/ext/openssl/ossl_x509.c +0 -6
- data/ext/openssl/ossl_x509cert.c +169 -13
- data/ext/openssl/ossl_x509crl.c +13 -10
- data/ext/openssl/ossl_x509ext.c +15 -2
- data/ext/openssl/ossl_x509name.c +15 -4
- data/ext/openssl/ossl_x509req.c +13 -10
- data/ext/openssl/ossl_x509revoked.c +3 -3
- data/ext/openssl/ossl_x509store.c +154 -70
- data/lib/openssl/bn.rb +1 -1
- data/lib/openssl/buffering.rb +37 -5
- 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 +447 -1
- data/lib/openssl/ssl.rb +52 -9
- data/lib/openssl/version.rb +5 -0
- data/lib/openssl/x509.rb +177 -1
- data/lib/openssl.rb +24 -9
- metadata +10 -79
- data/ext/openssl/deprecation.rb +0 -27
- data/ext/openssl/ossl_version.h +0 -15
- data/ext/openssl/ruby_missing.h +0 -24
- data/lib/openssl/config.rb +0 -492
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
|
@@ -346,54 +346,19 @@ Init_ossl_digest(void)
|
|
346
346
|
* the integrity of a signed document, it suffices to re-compute the hash
|
347
347
|
* and verify that it is equal to that in the signature.
|
348
348
|
*
|
349
|
-
*
|
350
|
-
*
|
351
|
-
* * MD2, MD4, MDC2 and MD5
|
352
|
-
* * RIPEMD160
|
353
|
-
* * DSS, DSS1 (Pseudo algorithms to be used for DSA signatures. DSS is
|
354
|
-
* 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:
|
355
351
|
*
|
356
|
-
*
|
357
|
-
* can be instantiated as simply as e.g.
|
352
|
+
* openssl list -digest-algorithms
|
358
353
|
*
|
359
|
-
*
|
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
|
360
358
|
*
|
361
|
-
*
|
359
|
+
* Each of these algorithms can be instantiated using the name:
|
362
360
|
*
|
363
|
-
*
|
364
|
-
* <openssl/object.h> and <openssl/obj_mac.h>. They are textual
|
365
|
-
* representations of ASN.1 OBJECT IDENTIFIERs. Each supported digest
|
366
|
-
* algorithm has an OBJECT IDENTIFIER associated to it and those again
|
367
|
-
* have short/long names assigned to them.
|
368
|
-
* E.g. the OBJECT IDENTIFIER for SHA-1 is 1.3.14.3.2.26 and its
|
369
|
-
* sn is "SHA1" and its ln is "sha1".
|
370
|
-
* ==== MD2
|
371
|
-
* * sn: MD2
|
372
|
-
* * ln: md2
|
373
|
-
* ==== MD4
|
374
|
-
* * sn: MD4
|
375
|
-
* * ln: md4
|
376
|
-
* ==== MD5
|
377
|
-
* * sn: MD5
|
378
|
-
* * ln: md5
|
379
|
-
* ==== SHA
|
380
|
-
* * sn: SHA
|
381
|
-
* * ln: SHA
|
382
|
-
* ==== SHA-1
|
383
|
-
* * sn: SHA1
|
384
|
-
* * ln: sha1
|
385
|
-
* ==== SHA-224
|
386
|
-
* * sn: SHA224
|
387
|
-
* * ln: sha224
|
388
|
-
* ==== SHA-256
|
389
|
-
* * sn: SHA256
|
390
|
-
* * ln: sha256
|
391
|
-
* ==== SHA-384
|
392
|
-
* * sn: SHA384
|
393
|
-
* * ln: sha384
|
394
|
-
* ==== SHA-512
|
395
|
-
* * sn: SHA512
|
396
|
-
* * ln: sha512
|
361
|
+
* digest = OpenSSL::Digest.new('SHA256')
|
397
362
|
*
|
398
363
|
* "Breaking" a message digest algorithm means defying its one-way
|
399
364
|
* function characteristics, i.e. producing a collision or finding a way
|
@@ -405,16 +370,16 @@ Init_ossl_digest(void)
|
|
405
370
|
*
|
406
371
|
* === Hashing a file
|
407
372
|
*
|
408
|
-
* data = File.
|
409
|
-
* sha256 = OpenSSL::Digest
|
373
|
+
* data = File.binread('document')
|
374
|
+
* sha256 = OpenSSL::Digest.new('SHA256')
|
410
375
|
* digest = sha256.digest(data)
|
411
376
|
*
|
412
377
|
* === Hashing several pieces of data at once
|
413
378
|
*
|
414
|
-
* data1 = File.
|
415
|
-
* data2 = File.
|
416
|
-
* data3 = File.
|
417
|
-
* sha256 = OpenSSL::Digest
|
379
|
+
* data1 = File.binread('file1')
|
380
|
+
* data2 = File.binread('file2')
|
381
|
+
* data3 = File.binread('file3')
|
382
|
+
* sha256 = OpenSSL::Digest.new('SHA256')
|
418
383
|
* sha256 << data1
|
419
384
|
* sha256 << data2
|
420
385
|
* sha256 << data3
|
@@ -422,11 +387,11 @@ Init_ossl_digest(void)
|
|
422
387
|
*
|
423
388
|
* === Reuse a Digest instance
|
424
389
|
*
|
425
|
-
* data1 = File.
|
426
|
-
* sha256 = OpenSSL::Digest
|
390
|
+
* data1 = File.binread('file1')
|
391
|
+
* sha256 = OpenSSL::Digest.new('SHA256')
|
427
392
|
* digest1 = sha256.digest(data1)
|
428
393
|
*
|
429
|
-
* data2 = File.
|
394
|
+
* data2 = File.binread('file2')
|
430
395
|
* sha256.reset
|
431
396
|
* digest2 = sha256.digest(data2)
|
432
397
|
*
|
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,49 @@ 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
|
+
#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);
|
110
120
|
|
111
121
|
return self;
|
112
122
|
}
|
@@ -114,16 +124,15 @@ ossl_hmac_initialize(VALUE self, VALUE key, VALUE digest)
|
|
114
124
|
static VALUE
|
115
125
|
ossl_hmac_copy(VALUE self, VALUE other)
|
116
126
|
{
|
117
|
-
|
127
|
+
EVP_MD_CTX *ctx1, *ctx2;
|
118
128
|
|
119
129
|
rb_check_frozen(self);
|
120
130
|
if (self == other) return self;
|
121
131
|
|
122
132
|
GetHMAC(self, ctx1);
|
123
133
|
GetHMAC(other, ctx2);
|
124
|
-
|
125
|
-
|
126
|
-
ossl_raise(eHMACError, "HMAC_CTX_copy");
|
134
|
+
if (EVP_MD_CTX_copy(ctx1, ctx2) != 1)
|
135
|
+
ossl_raise(eHMACError, "EVP_MD_CTX_copy");
|
127
136
|
return self;
|
128
137
|
}
|
129
138
|
|
@@ -148,33 +157,16 @@ ossl_hmac_copy(VALUE self, VALUE other)
|
|
148
157
|
static VALUE
|
149
158
|
ossl_hmac_update(VALUE self, VALUE data)
|
150
159
|
{
|
151
|
-
|
160
|
+
EVP_MD_CTX *ctx;
|
152
161
|
|
153
162
|
StringValue(data);
|
154
163
|
GetHMAC(self, ctx);
|
155
|
-
|
164
|
+
if (EVP_DigestSignUpdate(ctx, RSTRING_PTR(data), RSTRING_LEN(data)) != 1)
|
165
|
+
ossl_raise(eHMACError, "EVP_DigestSignUpdate");
|
156
166
|
|
157
167
|
return self;
|
158
168
|
}
|
159
169
|
|
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
170
|
/*
|
179
171
|
* call-seq:
|
180
172
|
* hmac.digest -> string
|
@@ -182,7 +174,7 @@ hmac_final(HMAC_CTX *ctx, unsigned char *buf, unsigned int *buf_len)
|
|
182
174
|
* Returns the authentication code an instance represents as a binary string.
|
183
175
|
*
|
184
176
|
* === Example
|
185
|
-
* instance = OpenSSL::HMAC.new('key',
|
177
|
+
* instance = OpenSSL::HMAC.new('key', 'SHA1')
|
186
178
|
* #=> f42bb0eeb018ebbd4597ae7213711ec60760843f
|
187
179
|
* instance.digest
|
188
180
|
* #=> "\xF4+\xB0\xEE\xB0\x18\xEB\xBDE\x97\xAEr\x13q\x1E\xC6\a`\x84?"
|
@@ -190,15 +182,16 @@ hmac_final(HMAC_CTX *ctx, unsigned char *buf, unsigned int *buf_len)
|
|
190
182
|
static VALUE
|
191
183
|
ossl_hmac_digest(VALUE self)
|
192
184
|
{
|
193
|
-
|
194
|
-
|
185
|
+
EVP_MD_CTX *ctx;
|
186
|
+
size_t buf_len = EVP_MAX_MD_SIZE;
|
195
187
|
VALUE ret;
|
196
188
|
|
197
189
|
GetHMAC(self, ctx);
|
198
190
|
ret = rb_str_new(NULL, EVP_MAX_MD_SIZE);
|
199
|
-
|
200
|
-
|
201
|
-
|
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);
|
202
195
|
|
203
196
|
return ret;
|
204
197
|
}
|
@@ -213,13 +206,14 @@ ossl_hmac_digest(VALUE self)
|
|
213
206
|
static VALUE
|
214
207
|
ossl_hmac_hexdigest(VALUE self)
|
215
208
|
{
|
216
|
-
|
209
|
+
EVP_MD_CTX *ctx;
|
217
210
|
unsigned char buf[EVP_MAX_MD_SIZE];
|
218
|
-
|
211
|
+
size_t buf_len = EVP_MAX_MD_SIZE;
|
219
212
|
VALUE ret;
|
220
213
|
|
221
214
|
GetHMAC(self, ctx);
|
222
|
-
|
215
|
+
if (EVP_DigestSignFinal(ctx, buf, &buf_len) != 1)
|
216
|
+
ossl_raise(eHMACError, "EVP_DigestSignFinal");
|
223
217
|
ret = rb_str_new(NULL, buf_len * 2);
|
224
218
|
ossl_bin2hex(buf, RSTRING_PTR(ret), buf_len);
|
225
219
|
|
@@ -236,7 +230,7 @@ ossl_hmac_hexdigest(VALUE self)
|
|
236
230
|
* === Example
|
237
231
|
*
|
238
232
|
* data = "The quick brown fox jumps over the lazy dog"
|
239
|
-
* instance = OpenSSL::HMAC.new('key',
|
233
|
+
* instance = OpenSSL::HMAC.new('key', 'SHA1')
|
240
234
|
* #=> f42bb0eeb018ebbd4597ae7213711ec60760843f
|
241
235
|
*
|
242
236
|
* instance.update(data)
|
@@ -248,84 +242,17 @@ ossl_hmac_hexdigest(VALUE self)
|
|
248
242
|
static VALUE
|
249
243
|
ossl_hmac_reset(VALUE self)
|
250
244
|
{
|
251
|
-
|
245
|
+
EVP_MD_CTX *ctx;
|
246
|
+
EVP_PKEY *pkey;
|
252
247
|
|
253
248
|
GetHMAC(self, ctx);
|
254
|
-
|
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");
|
255
252
|
|
256
253
|
return self;
|
257
254
|
}
|
258
255
|
|
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
256
|
/*
|
330
257
|
* INIT
|
331
258
|
*/
|
@@ -356,11 +283,10 @@ Init_ossl_hmac(void)
|
|
356
283
|
*
|
357
284
|
* === HMAC-SHA256 using incremental interface
|
358
285
|
*
|
359
|
-
* data1 = File.
|
360
|
-
* data2 = File.
|
286
|
+
* data1 = File.binread("file1")
|
287
|
+
* data2 = File.binread("file2")
|
361
288
|
* key = "key"
|
362
|
-
*
|
363
|
-
* hmac = OpenSSL::HMAC.new(key, digest)
|
289
|
+
* hmac = OpenSSL::HMAC.new(key, 'SHA256')
|
364
290
|
* hmac << data1
|
365
291
|
* hmac << data2
|
366
292
|
* mac = hmac.digest
|
@@ -370,8 +296,6 @@ Init_ossl_hmac(void)
|
|
370
296
|
cHMAC = rb_define_class_under(mOSSL, "HMAC", rb_cObject);
|
371
297
|
|
372
298
|
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
299
|
|
376
300
|
rb_define_method(cHMAC, "initialize", ossl_hmac_initialize, 2);
|
377
301
|
rb_define_method(cHMAC, "initialize_copy", ossl_hmac_copy, 1);
|
@@ -384,12 +308,3 @@ Init_ossl_hmac(void)
|
|
384
308
|
rb_define_alias(cHMAC, "inspect", "hexdigest");
|
385
309
|
rb_define_alias(cHMAC, "to_s", "hexdigest");
|
386
310
|
}
|
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
@@ -3,7 +3,7 @@
|
|
3
3
|
* Copyright (C) 2007, 2017 Ruby/OpenSSL Project Authors
|
4
4
|
*/
|
5
5
|
#include "ossl.h"
|
6
|
-
#if
|
6
|
+
#if OSSL_OPENSSL_PREREQ(1, 1, 0) || OSSL_LIBRESSL_PREREQ(3, 6, 0)
|
7
7
|
# include <openssl/kdf.h>
|
8
8
|
#endif
|
9
9
|
|
@@ -141,7 +141,7 @@ kdf_scrypt(int argc, VALUE *argv, VALUE self)
|
|
141
141
|
}
|
142
142
|
#endif
|
143
143
|
|
144
|
-
#if
|
144
|
+
#if OSSL_OPENSSL_PREREQ(1, 1, 0) || OSSL_LIBRESSL_PREREQ(3, 6, 0)
|
145
145
|
/*
|
146
146
|
* call-seq:
|
147
147
|
* KDF.hkdf(ikm, salt:, info:, length:, hash:) -> String
|
@@ -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
|
/*
|
@@ -313,7 +305,7 @@ Init_ossl_kdf(void)
|
|
313
305
|
#if defined(HAVE_EVP_PBE_SCRYPT)
|
314
306
|
rb_define_module_function(mKDF, "scrypt", kdf_scrypt, -1);
|
315
307
|
#endif
|
316
|
-
#if
|
308
|
+
#if OSSL_OPENSSL_PREREQ(1, 1, 0) || OSSL_LIBRESSL_PREREQ(3, 6, 0)
|
317
309
|
rb_define_module_function(mKDF, "hkdf", kdf_hkdf, -1);
|
318
310
|
#endif
|
319
311
|
}
|
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 = #...
|