openssl 2.1.3 → 3.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (61) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.md +35 -45
  3. data/History.md +237 -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 +159 -318
  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