openssl 2.1.3 → 3.0.2

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 (61) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.md +35 -45
  3. data/History.md +266 -1
  4. data/README.md +2 -2
  5. data/ext/openssl/extconf.rb +46 -38
  6. data/ext/openssl/openssl_missing.c +0 -66
  7. data/ext/openssl/openssl_missing.h +59 -43
  8. data/ext/openssl/ossl.c +110 -64
  9. data/ext/openssl/ossl.h +27 -10
  10. data/ext/openssl/ossl_asn1.c +41 -4
  11. data/ext/openssl/ossl_bn.c +251 -134
  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 +25 -60
  17. data/ext/openssl/ossl_engine.c +18 -27
  18. data/ext/openssl/ossl_hmac.c +60 -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 +1295 -178
  27. data/ext/openssl/ossl_pkey.h +35 -72
  28. data/ext/openssl/ossl_pkey_dh.c +124 -334
  29. data/ext/openssl/ossl_pkey_dsa.c +93 -398
  30. data/ext/openssl/ossl_pkey_ec.c +186 -329
  31. data/ext/openssl/ossl_pkey_rsa.c +105 -484
  32. data/ext/openssl/ossl_rand.c +2 -32
  33. data/ext/openssl/ossl_ssl.c +347 -394
  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 +0 -6
  38. data/ext/openssl/ossl_x509cert.c +169 -13
  39. data/ext/openssl/ossl_x509crl.c +13 -10
  40. data/ext/openssl/ossl_x509ext.c +15 -2
  41. data/ext/openssl/ossl_x509name.c +15 -4
  42. data/ext/openssl/ossl_x509req.c +13 -10
  43. data/ext/openssl/ossl_x509revoked.c +3 -3
  44. data/ext/openssl/ossl_x509store.c +154 -70
  45. data/lib/openssl/bn.rb +1 -1
  46. data/lib/openssl/buffering.rb +37 -5
  47. data/lib/openssl/cipher.rb +1 -1
  48. data/lib/openssl/digest.rb +10 -12
  49. data/lib/openssl/hmac.rb +78 -0
  50. data/lib/openssl/marshal.rb +30 -0
  51. data/lib/openssl/pkcs5.rb +1 -1
  52. data/lib/openssl/pkey.rb +443 -1
  53. data/lib/openssl/ssl.rb +47 -9
  54. data/lib/openssl/version.rb +5 -0
  55. data/lib/openssl/x509.rb +177 -1
  56. data/lib/openssl.rb +24 -9
  57. metadata +10 -79
  58. data/ext/openssl/deprecation.rb +0 -27
  59. data/ext/openssl/ossl_version.h +0 -15
  60. data/ext/openssl/ruby_missing.h +0 -24
  61. data/lib/openssl/config.rb +0 -492
@@ -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,49 @@ 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
+ #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
- HMAC_CTX *ctx1, *ctx2;
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
- if (!HMAC_CTX_copy(ctx1, ctx2))
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
- HMAC_CTX *ctx;
160
+ EVP_MD_CTX *ctx;
152
161
 
153
162
  StringValue(data);
154
163
  GetHMAC(self, ctx);
155
- HMAC_Update(ctx, (unsigned char *)RSTRING_PTR(data), RSTRING_LEN(data));
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', OpenSSL::Digest.new('sha1'))
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
- HMAC_CTX *ctx;
194
- unsigned int buf_len;
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
- 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);
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
- HMAC_CTX *ctx;
209
+ EVP_MD_CTX *ctx;
217
210
  unsigned char buf[EVP_MAX_MD_SIZE];
218
- unsigned int buf_len;
211
+ size_t buf_len = EVP_MAX_MD_SIZE;
219
212
  VALUE ret;
220
213
 
221
214
  GetHMAC(self, ctx);
222
- hmac_final(ctx, buf, &buf_len);
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', OpenSSL::Digest.new('sha1'))
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
- HMAC_CTX *ctx;
245
+ EVP_MD_CTX *ctx;
246
+ EVP_PKEY *pkey;
252
247
 
253
248
  GetHMAC(self, ctx);
254
- HMAC_Init_ex(ctx, NULL, 0, NULL, NULL);
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.read("file1")
360
- * data2 = File.read("file2")
286
+ * data1 = File.binread("file1")
287
+ * data2 = File.binread("file2")
361
288
  * key = "key"
362
- * digest = OpenSSL::Digest::SHA256.new
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 */
@@ -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 = #...
@@ -157,7 +157,7 @@ ossl_ocspcertid_new(OCSP_CERTID *cid)
157
157
  }
158
158
 
159
159
  /*
160
- * OCSP::Resquest
160
+ * OCSP::Request
161
161
  */
162
162
  static VALUE
163
163
  ossl_ocspreq_alloc(VALUE klass)
@@ -803,7 +803,7 @@ add_status_convert_time(VALUE obj)
803
803
  * revocation, and must be one of OpenSSL::OCSP::REVOKED_STATUS_* constants.
804
804
  * _revocation_time_ is the time when the certificate is revoked.
805
805
  *
806
- * _this_update_ and _next_update_ indicate the time at which ths status is
806
+ * _this_update_ and _next_update_ indicate the time at which the status is
807
807
  * verified to be correct and the time at or before which newer information
808
808
  * will be available, respectively. _next_update_ is optional.
809
809
  *
@@ -1069,55 +1069,7 @@ ossl_ocspbres_verify(int argc, VALUE *argv, VALUE self)
1069
1069
  x509st = GetX509StorePtr(store);
1070
1070
  flg = NIL_P(flags) ? 0 : NUM2INT(flags);
1071
1071
  x509s = ossl_x509_ary2sk(certs);
1072
- #if (OPENSSL_VERSION_NUMBER < 0x1000202fL) || defined(LIBRESSL_VERSION_NUMBER)
1073
- /*
1074
- * OpenSSL had a bug that it doesn't use the certificates in x509s for
1075
- * verifying the chain. This can be a problem when the response is signed by
1076
- * a certificate issued by an intermediate CA.
1077
- *
1078
- * root_ca
1079
- * |
1080
- * intermediate_ca
1081
- * |-------------|
1082
- * end_entity ocsp_signer
1083
- *
1084
- * When the certificate hierarchy is like this, and the response contains
1085
- * only ocsp_signer certificate, the following code wrongly fails.
1086
- *
1087
- * store = OpenSSL::X509::Store.new; store.add_cert(root_ca)
1088
- * basic_response.verify([intermediate_ca], store)
1089
- *
1090
- * So add the certificates in x509s to the embedded certificates list first.
1091
- *
1092
- * This is fixed in OpenSSL 0.9.8zg, 1.0.0s, 1.0.1n, 1.0.2b. But it still
1093
- * exists in LibreSSL 2.1.10, 2.2.9, 2.3.6, 2.4.1.
1094
- */
1095
- if (!(flg & (OCSP_NOCHAIN | OCSP_NOVERIFY)) &&
1096
- sk_X509_num(x509s) && sk_X509_num(bs->certs)) {
1097
- int i;
1098
-
1099
- bs = ASN1_item_dup(ASN1_ITEM_rptr(OCSP_BASICRESP), bs);
1100
- if (!bs) {
1101
- sk_X509_pop_free(x509s, X509_free);
1102
- ossl_raise(eOCSPError, "ASN1_item_dup");
1103
- }
1104
-
1105
- for (i = 0; i < sk_X509_num(x509s); i++) {
1106
- if (!OCSP_basic_add1_cert(bs, sk_X509_value(x509s, i))) {
1107
- sk_X509_pop_free(x509s, X509_free);
1108
- OCSP_BASICRESP_free(bs);
1109
- ossl_raise(eOCSPError, "OCSP_basic_add1_cert");
1110
- }
1111
- }
1112
- result = OCSP_basic_verify(bs, x509s, x509st, flg);
1113
- OCSP_BASICRESP_free(bs);
1114
- }
1115
- else {
1116
- result = OCSP_basic_verify(bs, x509s, x509st, flg);
1117
- }
1118
- #else
1119
1072
  result = OCSP_basic_verify(bs, x509s, x509st, flg);
1120
- #endif
1121
1073
  sk_X509_pop_free(x509s, X509_free);
1122
1074
  if (result <= 0)
1123
1075
  ossl_clear_error();
@@ -1489,13 +1441,15 @@ ossl_ocspcid_initialize_copy(VALUE self, VALUE other)
1489
1441
  * call-seq:
1490
1442
  * OpenSSL::OCSP::CertificateId.new(subject, issuer, digest = nil) -> certificate_id
1491
1443
  * OpenSSL::OCSP::CertificateId.new(der_string) -> certificate_id
1444
+ * OpenSSL::OCSP::CertificateId.new(obj) -> certificate_id
1492
1445
  *
1493
1446
  * Creates a new OpenSSL::OCSP::CertificateId for the given _subject_ and
1494
1447
  * _issuer_ X509 certificates. The _digest_ is a digest algorithm that is used
1495
1448
  * to compute the hash values. This defaults to SHA-1.
1496
1449
  *
1497
1450
  * If only one argument is given, decodes it as DER representation of a
1498
- * certificate ID.
1451
+ * certificate ID or generates certificate ID from the object that responds to
1452
+ * the to_der method.
1499
1453
  */
1500
1454
  static VALUE
1501
1455
  ossl_ocspcid_initialize(int argc, VALUE *argv, VALUE self)
@@ -1717,7 +1671,7 @@ Init_ossl_ocsp(void)
1717
1671
  * subject certificate so the CA knows which certificate we are asking
1718
1672
  * about:
1719
1673
  *
1720
- * digest = OpenSSL::Digest::SHA1.new
1674
+ * digest = OpenSSL::Digest.new('SHA1')
1721
1675
  * certificate_id =
1722
1676
  * OpenSSL::OCSP::CertificateId.new subject, issuer, digest
1723
1677
  *
@@ -1734,18 +1688,11 @@ Init_ossl_ocsp(void)
1734
1688
  * To submit the request to the CA for verification we need to extract the
1735
1689
  * OCSP URI from the subject certificate:
1736
1690
  *
1737
- * authority_info_access = subject.extensions.find do |extension|
1738
- * extension.oid == 'authorityInfoAccess'
1739
- * end
1740
- *
1741
- * descriptions = authority_info_access.value.split "\n"
1742
- * ocsp = descriptions.find do |description|
1743
- * description.start_with? 'OCSP'
1744
- * end
1691
+ * ocsp_uris = subject.ocsp_uris
1745
1692
  *
1746
1693
  * require 'uri'
1747
1694
  *
1748
- * ocsp_uri = URI ocsp[/URI:(.*)/, 1]
1695
+ * ocsp_uri = URI ocsp_uris[0]
1749
1696
  *
1750
1697
  * To submit the request we'll POST the request to the OCSP URI (per RFC
1751
1698
  * 2560). Note that we only handle HTTP requests and don't handle any
@@ -1792,7 +1739,7 @@ Init_ossl_ocsp(void)
1792
1739
  * single_response = basic_response.find_response(certificate_id)
1793
1740
  *
1794
1741
  * unless single_response
1795
- * raise 'basic_response does not have the status for the certificiate'
1742
+ * raise 'basic_response does not have the status for the certificate'
1796
1743
  * end
1797
1744
  *
1798
1745
  * Then check the validity. A status issued in the future must be rejected.
@@ -13,9 +13,9 @@
13
13
 
14
14
  #if !defined(OPENSSL_NO_OCSP)
15
15
  extern VALUE mOCSP;
16
- extern VALUE cOPCSReq;
17
- extern VALUE cOPCSRes;
18
- extern VALUE cOPCSBasicRes;
16
+ extern VALUE cOCSPReq;
17
+ extern VALUE cOCSPRes;
18
+ extern VALUE cOCSPBasicRes;
19
19
  #endif
20
20
 
21
21
  void Init_ossl_ocsp(void);
@@ -149,6 +149,24 @@ ossl_pkcs12_s_create(int argc, VALUE *argv, VALUE self)
149
149
  return obj;
150
150
  }
151
151
 
152
+ static VALUE
153
+ ossl_pkey_new_i(VALUE arg)
154
+ {
155
+ return ossl_pkey_new((EVP_PKEY *)arg);
156
+ }
157
+
158
+ static VALUE
159
+ ossl_x509_new_i(VALUE arg)
160
+ {
161
+ return ossl_x509_new((X509 *)arg);
162
+ }
163
+
164
+ static VALUE
165
+ ossl_x509_sk2ary_i(VALUE arg)
166
+ {
167
+ return ossl_x509_sk2ary((STACK_OF(X509) *)arg);
168
+ }
169
+
152
170
  /*
153
171
  * call-seq:
154
172
  * PKCS12.new -> pkcs12
@@ -186,15 +204,15 @@ ossl_pkcs12_initialize(int argc, VALUE *argv, VALUE self)
186
204
  ossl_raise(ePKCS12Error, "PKCS12_parse");
187
205
  ERR_pop_to_mark();
188
206
  if (key) {
189
- pkey = rb_protect((VALUE (*)(VALUE))ossl_pkey_new, (VALUE)key, &st);
207
+ pkey = rb_protect(ossl_pkey_new_i, (VALUE)key, &st);
190
208
  if (st) goto err;
191
209
  }
192
210
  if (x509) {
193
- cert = rb_protect((VALUE (*)(VALUE))ossl_x509_new, (VALUE)x509, &st);
211
+ cert = rb_protect(ossl_x509_new_i, (VALUE)x509, &st);
194
212
  if (st) goto err;
195
213
  }
196
214
  if (x509s) {
197
- ca = rb_protect((VALUE (*)(VALUE))ossl_x509_sk2ary, (VALUE)x509s, &st);
215
+ ca = rb_protect(ossl_x509_sk2ary_i, (VALUE)x509s, &st);
198
216
  if (st) goto err;
199
217
  }
200
218