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.
Files changed (60) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.md +35 -45
  3. data/History.md +232 -0
  4. data/README.md +2 -2
  5. data/ext/openssl/extconf.rb +61 -46
  6. data/ext/openssl/openssl_missing.c +0 -66
  7. data/ext/openssl/openssl_missing.h +60 -44
  8. data/ext/openssl/ossl.c +112 -66
  9. data/ext/openssl/ossl.h +28 -11
  10. data/ext/openssl/ossl_asn1.c +42 -5
  11. data/ext/openssl/ossl_bn.c +276 -146
  12. data/ext/openssl/ossl_bn.h +2 -1
  13. data/ext/openssl/ossl_cipher.c +38 -29
  14. data/ext/openssl/ossl_config.c +412 -41
  15. data/ext/openssl/ossl_config.h +4 -7
  16. data/ext/openssl/ossl_digest.c +31 -62
  17. data/ext/openssl/ossl_engine.c +18 -27
  18. data/ext/openssl/ossl_hmac.c +52 -145
  19. data/ext/openssl/ossl_kdf.c +11 -19
  20. data/ext/openssl/ossl_ns_spki.c +1 -1
  21. data/ext/openssl/ossl_ocsp.c +9 -62
  22. data/ext/openssl/ossl_ocsp.h +3 -3
  23. data/ext/openssl/ossl_pkcs12.c +21 -3
  24. data/ext/openssl/ossl_pkcs7.c +45 -78
  25. data/ext/openssl/ossl_pkcs7.h +16 -0
  26. data/ext/openssl/ossl_pkey.c +1255 -178
  27. data/ext/openssl/ossl_pkey.h +40 -77
  28. data/ext/openssl/ossl_pkey_dh.c +125 -335
  29. data/ext/openssl/ossl_pkey_dsa.c +93 -398
  30. data/ext/openssl/ossl_pkey_ec.c +155 -318
  31. data/ext/openssl/ossl_pkey_rsa.c +105 -484
  32. data/ext/openssl/ossl_rand.c +2 -40
  33. data/ext/openssl/ossl_ssl.c +395 -364
  34. data/ext/openssl/ossl_ssl_session.c +24 -29
  35. data/ext/openssl/ossl_ts.c +1539 -0
  36. data/ext/openssl/ossl_ts.h +16 -0
  37. data/ext/openssl/ossl_x509.c +86 -1
  38. data/ext/openssl/ossl_x509cert.c +166 -10
  39. data/ext/openssl/ossl_x509crl.c +10 -7
  40. data/ext/openssl/ossl_x509ext.c +15 -2
  41. data/ext/openssl/ossl_x509name.c +16 -5
  42. data/ext/openssl/ossl_x509req.c +10 -7
  43. data/ext/openssl/ossl_x509store.c +193 -92
  44. data/lib/openssl/bn.rb +1 -1
  45. data/lib/openssl/buffering.rb +42 -17
  46. data/lib/openssl/cipher.rb +1 -1
  47. data/lib/openssl/digest.rb +10 -12
  48. data/lib/openssl/hmac.rb +78 -0
  49. data/lib/openssl/marshal.rb +30 -0
  50. data/lib/openssl/pkcs5.rb +1 -1
  51. data/lib/openssl/pkey.rb +435 -1
  52. data/lib/openssl/ssl.rb +53 -14
  53. data/lib/openssl/version.rb +5 -0
  54. data/lib/openssl/x509.rb +177 -1
  55. data/lib/openssl.rb +24 -9
  56. metadata +13 -69
  57. data/ext/openssl/deprecation.rb +0 -23
  58. data/ext/openssl/ossl_version.h +0 -15
  59. data/ext/openssl/ruby_missing.h +0 -24
  60. data/lib/openssl/config.rb +0 -474
@@ -63,7 +63,7 @@ ossl_evp_get_digestbyname(VALUE obj)
63
63
 
64
64
  GetDigest(obj, ctx);
65
65
 
66
- md = EVP_MD_CTX_md(ctx);
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, EVP_MD_CTX_md(ctx), NULL) != 1) {
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::SHA256.new
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::SHA512.new
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 rb_str_new2(EVP_MD_name(EVP_MD_CTX_md(ctx)));
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::SHA1.new
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::SHA1.new
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
- * Among the supported message digest algorithms are:
352
- * * SHA, SHA1, SHA224, SHA256, SHA384 and SHA512
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
- * For each of these algorithms, there is a sub-class of Digest that
359
- * can be instantiated as simply as e.g.
352
+ * openssl list -digest-algorithms
360
353
  *
361
- * digest = OpenSSL::Digest::SHA1.new
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
- * === Mapping between Digest class and sn/ln
359
+ * Each of these algorithms can be instantiated using the name:
364
360
  *
365
- * The sn (short names) and ln (long names) are defined in
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.read('document')
411
- * sha256 = OpenSSL::Digest::SHA256.new
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.read('file1')
417
- * data2 = File.read('file2')
418
- * data3 = File.read('file3')
419
- * sha256 = OpenSSL::Digest::SHA256.new
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.read('file1')
428
- * sha256 = OpenSSL::Digest::SHA256.new
390
+ * data1 = File.binread('file1')
391
+ * sha256 = OpenSSL::Digest.new('SHA256')
429
392
  * digest1 = sha256.digest(data1)
430
393
  *
431
- * data2 = File.read('file2')
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
  *
@@ -9,7 +9,8 @@
9
9
  */
10
10
  #include "ossl.h"
11
11
 
12
- #if !defined(OPENSSL_NO_ENGINE)
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
- #ifndef OPENSSL_NO_STATIC_ENGINE
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
- #if HAVE_ENGINE_LOAD_4758CCA
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
- #if HAVE_ENGINE_LOAD_AEP
112
+ #ifdef HAVE_ENGINE_LOAD_AEP
115
113
  OSSL_ENGINE_LOAD_IF_MATCH(aep, AEP);
116
114
  #endif
117
- #if HAVE_ENGINE_LOAD_ATALLA
115
+ #ifdef HAVE_ENGINE_LOAD_ATALLA
118
116
  OSSL_ENGINE_LOAD_IF_MATCH(atalla, ATALLA);
119
117
  #endif
120
- #if HAVE_ENGINE_LOAD_CHIL
118
+ #ifdef HAVE_ENGINE_LOAD_CHIL
121
119
  OSSL_ENGINE_LOAD_IF_MATCH(chil, CHIL);
122
120
  #endif
123
- #if HAVE_ENGINE_LOAD_CSWIFT
121
+ #ifdef HAVE_ENGINE_LOAD_CSWIFT
124
122
  OSSL_ENGINE_LOAD_IF_MATCH(cswift, CSWIFT);
125
123
  #endif
126
- #if HAVE_ENGINE_LOAD_NURON
124
+ #ifdef HAVE_ENGINE_LOAD_NURON
127
125
  OSSL_ENGINE_LOAD_IF_MATCH(nuron, NURON);
128
126
  #endif
129
- #if HAVE_ENGINE_LOAD_SUREWARE
127
+ #ifdef HAVE_ENGINE_LOAD_SUREWARE
130
128
  OSSL_ENGINE_LOAD_IF_MATCH(sureware, SUREWARE);
131
129
  #endif
132
- #if HAVE_ENGINE_LOAD_UBSEC
130
+ #ifdef HAVE_ENGINE_LOAD_UBSEC
133
131
  OSSL_ENGINE_LOAD_IF_MATCH(ubsec, UBSEC);
134
132
  #endif
135
- #if HAVE_ENGINE_LOAD_PADLOCK
133
+ #ifdef HAVE_ENGINE_LOAD_PADLOCK
136
134
  OSSL_ENGINE_LOAD_IF_MATCH(padlock, PADLOCK);
137
135
  #endif
138
- #if HAVE_ENGINE_LOAD_CAPI
136
+ #ifdef HAVE_ENGINE_LOAD_CAPI
139
137
  OSSL_ENGINE_LOAD_IF_MATCH(capi, CAPI);
140
138
  #endif
141
- #if HAVE_ENGINE_LOAD_GMP
139
+ #ifdef HAVE_ENGINE_LOAD_GMP
142
140
  OSSL_ENGINE_LOAD_IF_MATCH(gmp, GMP);
143
141
  #endif
144
- #if HAVE_ENGINE_LOAD_GOST
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
- #endif
154
- #ifdef HAVE_ENGINE_LOAD_OPENBSD_DEV_CRYPTO
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
  /*
@@ -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), HMAC_CTX, &ossl_hmac_type, (ctx)); \
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
- HMAC_CTX_free(ctx);
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
- HMAC_CTX *ctx;
52
+ EVP_MD_CTX *ctx;
55
53
 
56
54
  obj = NewHMAC(klass);
57
- ctx = HMAC_CTX_new();
55
+ ctx = EVP_MD_CTX_new();
58
56
  if (!ctx)
59
- ossl_raise(eHMACError, NULL);
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
- * digest = OpenSSL::Digest.new('sha1')
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 won't be equal when they're compared, even if they have the
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', OpenSSL::Digest.new('sha1'))
92
- * #=> f42bb0eeb018ebbd4597ae7213711ec60760843f
93
- * instance
94
- * #=> f42bb0eeb018ebbd4597ae7213711ec60760843f
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
- HMAC_CTX *ctx;
95
+ EVP_MD_CTX *ctx;
96
+ EVP_PKEY *pkey;
105
97
 
106
- StringValue(key);
107
98
  GetHMAC(self, ctx);
108
- HMAC_Init_ex(ctx, RSTRING_PTR(key), RSTRING_LENINT(key),
109
- ossl_evp_get_digestbyname(digest), NULL);
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
- HMAC_CTX *ctx1, *ctx2;
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
- if (!HMAC_CTX_copy(ctx1, ctx2))
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
- HMAC_CTX *ctx;
152
+ EVP_MD_CTX *ctx;
152
153
 
153
154
  StringValue(data);
154
155
  GetHMAC(self, ctx);
155
- HMAC_Update(ctx, (unsigned char *)RSTRING_PTR(data), RSTRING_LEN(data));
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', OpenSSL::Digest.new('sha1'))
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
- HMAC_CTX *ctx;
194
- unsigned int buf_len;
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
- hmac_final(ctx, (unsigned char *)RSTRING_PTR(ret), &buf_len);
200
- assert(buf_len <= EVP_MAX_MD_SIZE);
201
- rb_str_set_len(ret, buf_len);
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
- HMAC_CTX *ctx;
201
+ EVP_MD_CTX *ctx;
217
202
  unsigned char buf[EVP_MAX_MD_SIZE];
218
- unsigned int buf_len;
203
+ size_t buf_len = EVP_MAX_MD_SIZE;
219
204
  VALUE ret;
220
205
 
221
206
  GetHMAC(self, ctx);
222
- hmac_final(ctx, buf, &buf_len);
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', OpenSSL::Digest.new('sha1'))
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
- HMAC_CTX *ctx;
237
+ EVP_MD_CTX *ctx;
238
+ EVP_PKEY *pkey;
252
239
 
253
240
  GetHMAC(self, ctx);
254
- HMAC_Init_ex(ctx, NULL, 0, NULL, NULL);
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.read("file1")
360
- * data2 = File.read("file2")
278
+ * data1 = File.binread("file1")
279
+ * data2 = File.binread("file2")
361
280
  * key = "key"
362
- * digest = OpenSSL::Digest::SHA256.new
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 */
@@ -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::SHA256.new
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 compare two
288
- * values, the following could be used:
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
  /*
@@ -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::SHA256.new)
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 = #...