openssl 2.1.2 → 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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 = #...
|