openssl 3.3.3 → 4.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 (55) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.md +3 -0
  3. data/History.md +111 -0
  4. data/README.md +12 -11
  5. data/ext/openssl/extconf.rb +30 -70
  6. data/ext/openssl/openssl_missing.h +0 -210
  7. data/ext/openssl/ossl.c +295 -304
  8. data/ext/openssl/ossl.h +13 -9
  9. data/ext/openssl/ossl_asn1.c +598 -406
  10. data/ext/openssl/ossl_asn1.h +15 -1
  11. data/ext/openssl/ossl_bio.c +8 -4
  12. data/ext/openssl/ossl_bn.c +286 -291
  13. data/ext/openssl/ossl_cipher.c +257 -209
  14. data/ext/openssl/ossl_cipher.h +10 -1
  15. data/ext/openssl/ossl_config.c +1 -6
  16. data/ext/openssl/ossl_digest.c +74 -43
  17. data/ext/openssl/ossl_digest.h +9 -1
  18. data/ext/openssl/ossl_engine.c +39 -103
  19. data/ext/openssl/ossl_hmac.c +30 -36
  20. data/ext/openssl/ossl_kdf.c +42 -53
  21. data/ext/openssl/ossl_ns_spki.c +27 -32
  22. data/ext/openssl/ossl_ocsp.c +208 -236
  23. data/ext/openssl/ossl_pkcs12.c +26 -26
  24. data/ext/openssl/ossl_pkcs7.c +175 -145
  25. data/ext/openssl/ossl_pkey.c +102 -158
  26. data/ext/openssl/ossl_pkey.h +99 -100
  27. data/ext/openssl/ossl_pkey_dh.c +31 -68
  28. data/ext/openssl/ossl_pkey_dsa.c +15 -54
  29. data/ext/openssl/ossl_pkey_ec.c +180 -238
  30. data/ext/openssl/ossl_pkey_rsa.c +56 -103
  31. data/ext/openssl/ossl_provider.c +0 -5
  32. data/ext/openssl/ossl_rand.c +7 -14
  33. data/ext/openssl/ossl_ssl.c +535 -384
  34. data/ext/openssl/ossl_ssl.h +8 -8
  35. data/ext/openssl/ossl_ssl_session.c +93 -97
  36. data/ext/openssl/ossl_ts.c +78 -124
  37. data/ext/openssl/ossl_x509.c +9 -28
  38. data/ext/openssl/ossl_x509attr.c +33 -54
  39. data/ext/openssl/ossl_x509cert.c +70 -101
  40. data/ext/openssl/ossl_x509crl.c +78 -89
  41. data/ext/openssl/ossl_x509ext.c +43 -64
  42. data/ext/openssl/ossl_x509name.c +64 -90
  43. data/ext/openssl/ossl_x509req.c +55 -62
  44. data/ext/openssl/ossl_x509revoked.c +28 -42
  45. data/ext/openssl/ossl_x509store.c +36 -54
  46. data/lib/openssl/buffering.rb +30 -24
  47. data/lib/openssl/digest.rb +1 -1
  48. data/lib/openssl/pkey.rb +71 -49
  49. data/lib/openssl/ssl.rb +12 -79
  50. data/lib/openssl/version.rb +2 -1
  51. data/lib/openssl/x509.rb +9 -0
  52. data/lib/openssl.rb +9 -6
  53. metadata +1 -3
  54. data/ext/openssl/openssl_missing.c +0 -41
  55. data/lib/openssl/asn1.rb +0 -188
data/ext/openssl/ossl.c CHANGED
@@ -10,88 +10,78 @@
10
10
  #include "ossl.h"
11
11
  #include <stdarg.h> /* for ossl_raise */
12
12
 
13
- /* OpenSSL >= 1.1.0 and LibreSSL >= 2.9.0 */
14
- #if defined(LIBRESSL_VERSION_NUMBER) || OPENSSL_VERSION_NUMBER >= 0x10100000
15
- # define HAVE_OPENSSL_110_THREADING_API
16
- #else
17
- # include <ruby/thread_native.h>
18
- #endif
19
-
20
13
  /*
21
14
  * Data Conversion
22
15
  */
23
- #define OSSL_IMPL_ARY2SK(name, type, expected_class, dup) \
24
- VALUE \
25
- ossl_##name##_ary2sk0(VALUE ary) \
26
- { \
27
- STACK_OF(type) *sk; \
28
- VALUE val; \
29
- type *x; \
30
- int i; \
31
- \
32
- Check_Type(ary, T_ARRAY); \
33
- sk = sk_##type##_new_null(); \
34
- if (!sk) ossl_raise(eOSSLError, NULL); \
35
- \
36
- for (i = 0; i < RARRAY_LEN(ary); i++) { \
37
- val = rb_ary_entry(ary, i); \
38
- if (!rb_obj_is_kind_of(val, expected_class)) { \
39
- sk_##type##_pop_free(sk, type##_free); \
40
- ossl_raise(eOSSLError, "object in array not" \
41
- " of class ##type##"); \
42
- } \
43
- x = dup(val); /* NEED TO DUP */ \
44
- sk_##type##_push(sk, x); \
45
- } \
46
- return (VALUE)sk; \
47
- } \
48
- \
49
- STACK_OF(type) * \
50
- ossl_protect_##name##_ary2sk(VALUE ary, int *status) \
51
- { \
52
- return (STACK_OF(type)*)rb_protect( \
53
- (VALUE (*)(VALUE))ossl_##name##_ary2sk0, \
54
- ary, \
55
- status); \
56
- } \
57
- \
58
- STACK_OF(type) * \
59
- ossl_##name##_ary2sk(VALUE ary) \
60
- { \
61
- STACK_OF(type) *sk; \
62
- int status = 0; \
63
- \
64
- sk = ossl_protect_##name##_ary2sk(ary, &status); \
65
- if (status) rb_jump_tag(status); \
66
- \
67
- return sk; \
16
+ #define OSSL_IMPL_ARY2SK(name, type, expected_class, dup) \
17
+ VALUE \
18
+ ossl_##name##_ary2sk0(VALUE ary) \
19
+ { \
20
+ STACK_OF(type) *sk; \
21
+ VALUE val; \
22
+ type *x; \
23
+ int i; \
24
+ \
25
+ Check_Type(ary, T_ARRAY); \
26
+ sk = sk_##type##_new_null(); \
27
+ if (!sk) ossl_raise(eOSSLError, NULL); \
28
+ \
29
+ for (i = 0; i < RARRAY_LEN(ary); i++) { \
30
+ val = rb_ary_entry(ary, i); \
31
+ if (!rb_obj_is_kind_of(val, expected_class)) { \
32
+ sk_##type##_pop_free(sk, type##_free); \
33
+ ossl_raise(eOSSLError, "object in array not" \
34
+ " of class ##type##"); \
35
+ } \
36
+ x = dup(val); /* NEED TO DUP */ \
37
+ if (!sk_##type##_push(sk, x)) { \
38
+ type##_free(x); \
39
+ sk_##type##_pop_free(sk, type##_free); \
40
+ ossl_raise(eOSSLError, NULL); \
41
+ } \
42
+ } \
43
+ return (VALUE)sk; \
44
+ } \
45
+ \
46
+ STACK_OF(type) * \
47
+ ossl_protect_##name##_ary2sk(VALUE ary, int *status) \
48
+ { \
49
+ return (STACK_OF(type)*)rb_protect( \
50
+ (VALUE (*)(VALUE))ossl_##name##_ary2sk0, \
51
+ ary, \
52
+ status); \
53
+ } \
54
+ \
55
+ STACK_OF(type) * \
56
+ ossl_##name##_ary2sk(VALUE ary) \
57
+ { \
58
+ STACK_OF(type) *sk; \
59
+ int status = 0; \
60
+ \
61
+ sk = ossl_protect_##name##_ary2sk(ary, &status); \
62
+ if (status) rb_jump_tag(status); \
63
+ \
64
+ return sk; \
68
65
  }
69
66
  OSSL_IMPL_ARY2SK(x509, X509, cX509Cert, DupX509CertPtr)
70
67
 
71
- #define OSSL_IMPL_SK2ARY(name, type) \
72
- VALUE \
73
- ossl_##name##_sk2ary(const STACK_OF(type) *sk) \
74
- { \
75
- type *t; \
76
- int i, num; \
77
- VALUE ary; \
78
- \
79
- if (!sk) { \
80
- OSSL_Debug("empty sk!"); \
81
- return Qnil; \
82
- } \
83
- num = sk_##type##_num(sk); \
84
- if (num < 0) { \
85
- OSSL_Debug("items in sk < -1???"); \
86
- return rb_ary_new(); \
87
- } \
88
- ary = rb_ary_new2(num); \
89
- \
90
- for (i=0; i<num; i++) { \
91
- t = sk_##type##_value(sk, i); \
92
- rb_ary_push(ary, ossl_##name##_new(t)); \
93
- } \
94
- return ary; \
68
+ #define OSSL_IMPL_SK2ARY(name, type) \
69
+ VALUE \
70
+ ossl_##name##_sk2ary(const STACK_OF(type) *sk) \
71
+ { \
72
+ type *t; \
73
+ int i, num; \
74
+ VALUE ary; \
75
+ \
76
+ RUBY_ASSERT(sk != NULL); \
77
+ num = sk_##type##_num(sk); \
78
+ ary = rb_ary_new_capa(num); \
79
+ \
80
+ for (i=0; i<num; i++) { \
81
+ t = sk_##type##_value(sk, i); \
82
+ rb_ary_push(ary, ossl_##name##_new(t)); \
83
+ } \
84
+ return ary; \
95
85
  }
96
86
  OSSL_IMPL_SK2ARY(x509, X509)
97
87
  OSSL_IMPL_SK2ARY(x509crl, X509_CRL)
@@ -111,14 +101,14 @@ ossl_str_new(const char *ptr, long len, int *pstate)
111
101
 
112
102
  str = rb_protect(ossl_str_new_i, len, &state);
113
103
  if (pstate)
114
- *pstate = state;
104
+ *pstate = state;
115
105
  if (state) {
116
- if (!pstate)
117
- rb_set_errinfo(Qnil);
118
- return Qnil;
106
+ if (!pstate)
107
+ rb_set_errinfo(Qnil);
108
+ return Qnil;
119
109
  }
120
110
  if (ptr)
121
- memcpy(RSTRING_PTR(str), ptr, len);
111
+ memcpy(RSTRING_PTR(str), ptr, len);
122
112
  return str;
123
113
  }
124
114
 
@@ -131,7 +121,7 @@ ossl_buf2str(char *buf, int len)
131
121
  str = ossl_str_new(buf, len, &state);
132
122
  OPENSSL_free(buf);
133
123
  if (state)
134
- rb_jump_tag(state);
124
+ rb_jump_tag(state);
135
125
  return str;
136
126
  }
137
127
 
@@ -143,10 +133,10 @@ ossl_bin2hex(const unsigned char *in, char *out, size_t inlen)
143
133
 
144
134
  assert(inlen <= LONG_MAX / 2);
145
135
  for (i = 0; i < inlen; i++) {
146
- unsigned char p = in[i];
136
+ unsigned char p = in[i];
147
137
 
148
- out[i * 2 + 0] = hex[p >> 4];
149
- out[i * 2 + 1] = hex[p & 0x0f];
138
+ out[i * 2 + 0] = hex[p >> 4];
139
+ out[i * 2 + 1] = hex[p & 0x0f];
150
140
  }
151
141
  }
152
142
 
@@ -157,14 +147,14 @@ VALUE
157
147
  ossl_pem_passwd_value(VALUE pass)
158
148
  {
159
149
  if (NIL_P(pass))
160
- return Qnil;
150
+ return Qnil;
161
151
 
162
152
  StringValue(pass);
163
153
 
164
154
  /* PEM_BUFSIZE is currently used as the second argument of pem_password_cb,
165
155
  * that is +max_len+ of ossl_pem_passwd_cb() */
166
156
  if (RSTRING_LEN(pass) > PEM_BUFSIZE)
167
- ossl_raise(eOSSLError, "password must not be longer than %d bytes", PEM_BUFSIZE);
157
+ ossl_raise(eOSSLError, "password must not be longer than %d bytes", PEM_BUFSIZE);
168
158
 
169
159
  return pass;
170
160
  }
@@ -174,7 +164,7 @@ ossl_pem_passwd_cb0(VALUE flag)
174
164
  {
175
165
  VALUE pass = rb_yield(flag);
176
166
  if (NIL_P(pass))
177
- return Qnil;
167
+ return Qnil;
178
168
  StringValue(pass);
179
169
  return pass;
180
170
  }
@@ -187,46 +177,46 @@ ossl_pem_passwd_cb(char *buf, int max_len, int flag, void *pwd_)
187
177
  VALUE rflag, pass = (VALUE)pwd_;
188
178
 
189
179
  if (RTEST(pass)) {
190
- /* PEM_def_callback(buf, max_len, flag, StringValueCStr(pass)) does not
191
- * work because it does not allow NUL characters and truncates to 1024
192
- * bytes silently if the input is over 1024 bytes */
193
- if (RB_TYPE_P(pass, T_STRING)) {
194
- len = RSTRING_LEN(pass);
195
- if (len <= max_len) {
196
- memcpy(buf, RSTRING_PTR(pass), len);
197
- return (int)len;
198
- }
199
- }
200
- OSSL_Debug("passed data is not valid String???");
201
- return -1;
180
+ /* PEM_def_callback(buf, max_len, flag, StringValueCStr(pass)) does not
181
+ * work because it does not allow NUL characters and truncates to 1024
182
+ * bytes silently if the input is over 1024 bytes */
183
+ if (RB_TYPE_P(pass, T_STRING)) {
184
+ len = RSTRING_LEN(pass);
185
+ if (len <= max_len) {
186
+ memcpy(buf, RSTRING_PTR(pass), len);
187
+ return (int)len;
188
+ }
189
+ }
190
+ OSSL_Debug("passed data is not valid String???");
191
+ return -1;
202
192
  }
203
193
 
204
194
  if (!rb_block_given_p()) {
205
- return PEM_def_callback(buf, max_len, flag, NULL);
195
+ return PEM_def_callback(buf, max_len, flag, NULL);
206
196
  }
207
197
 
208
198
  while (1) {
209
- /*
210
- * when the flag is nonzero, this password
211
- * will be used to perform encryption; otherwise it will
212
- * be used to perform decryption.
213
- */
214
- rflag = flag ? Qtrue : Qfalse;
215
- pass = rb_protect(ossl_pem_passwd_cb0, rflag, &status);
216
- if (status) {
217
- /* ignore an exception raised. */
218
- rb_set_errinfo(Qnil);
219
- return -1;
220
- }
221
- if (NIL_P(pass))
222
- return -1;
223
- len = RSTRING_LEN(pass);
224
- if (len > max_len) {
225
- rb_warning("password must not be longer than %d bytes", max_len);
226
- continue;
227
- }
228
- memcpy(buf, RSTRING_PTR(pass), len);
229
- break;
199
+ /*
200
+ * when the flag is nonzero, this password
201
+ * will be used to perform encryption; otherwise it will
202
+ * be used to perform decryption.
203
+ */
204
+ rflag = flag ? Qtrue : Qfalse;
205
+ pass = rb_protect(ossl_pem_passwd_cb0, rflag, &status);
206
+ if (status) {
207
+ /* ignore an exception raised. */
208
+ rb_set_errinfo(Qnil);
209
+ return -1;
210
+ }
211
+ if (NIL_P(pass))
212
+ return -1;
213
+ len = RSTRING_LEN(pass);
214
+ if (len > max_len) {
215
+ rb_warning("password must not be longer than %d bytes", max_len);
216
+ continue;
217
+ }
218
+ memcpy(buf, RSTRING_PTR(pass), len);
219
+ break;
230
220
  }
231
221
  return (int)len;
232
222
  }
@@ -261,19 +251,24 @@ VALUE
261
251
  ossl_to_der_if_possible(VALUE obj)
262
252
  {
263
253
  if(rb_respond_to(obj, ossl_s_to_der))
264
- return ossl_to_der(obj);
254
+ return ossl_to_der(obj);
265
255
  return obj;
266
256
  }
267
257
 
268
258
  /*
269
259
  * Errors
270
260
  */
261
+ static ID id_i_errors;
262
+
263
+ static void collect_errors_into(VALUE ary);
264
+
271
265
  VALUE
272
266
  ossl_make_error(VALUE exc, VALUE str)
273
267
  {
274
268
  unsigned long e;
275
269
  const char *data;
276
270
  int flags;
271
+ VALUE errors = rb_ary_new();
277
272
 
278
273
  if (NIL_P(str))
279
274
  str = rb_str_new(NULL, 0);
@@ -290,10 +285,12 @@ ossl_make_error(VALUE exc, VALUE str)
290
285
  rb_str_cat_cstr(str, msg ? msg : "(null)");
291
286
  if (flags & ERR_TXT_STRING && data)
292
287
  rb_str_catf(str, " (%s)", data);
293
- ossl_clear_error();
288
+ collect_errors_into(errors);
294
289
  }
295
290
 
296
- return rb_exc_new_str(exc, str);
291
+ VALUE obj = rb_exc_new_str(exc, str);
292
+ rb_ivar_set(obj, id_i_errors, errors);
293
+ return obj;
297
294
  }
298
295
 
299
296
  void
@@ -303,24 +300,23 @@ ossl_raise(VALUE exc, const char *fmt, ...)
303
300
  VALUE err;
304
301
 
305
302
  if (fmt) {
306
- va_start(args, fmt);
307
- err = rb_vsprintf(fmt, args);
308
- va_end(args);
303
+ va_start(args, fmt);
304
+ err = rb_vsprintf(fmt, args);
305
+ va_end(args);
309
306
  }
310
307
  else {
311
- err = Qnil;
308
+ err = Qnil;
312
309
  }
313
310
 
314
311
  rb_exc_raise(ossl_make_error(exc, err));
315
312
  }
316
313
 
317
- void
318
- ossl_clear_error(void)
314
+ static void
315
+ collect_errors_into(VALUE ary)
319
316
  {
320
- if (dOSSL == Qtrue) {
317
+ if (dOSSL == Qtrue || !NIL_P(ary)) {
321
318
  unsigned long e;
322
319
  const char *file, *data, *func, *lib, *reason;
323
- char append[256] = "";
324
320
  int line, flags;
325
321
 
326
322
  #ifdef HAVE_ERR_GET_ERROR_ALL
@@ -332,13 +328,18 @@ ossl_clear_error(void)
332
328
  lib = ERR_lib_error_string(e);
333
329
  reason = ERR_reason_error_string(e);
334
330
 
331
+ VALUE str = rb_sprintf("error:%08lX:%s:%s:%s", e, lib ? lib : "",
332
+ func ? func : "", reason ? reason : "");
335
333
  if (flags & ERR_TXT_STRING) {
336
334
  if (!data)
337
335
  data = "(null)";
338
- snprintf(append, sizeof(append), " (%s)", data);
336
+ rb_str_catf(str, " (%s)", data);
339
337
  }
340
- rb_warn("error on stack: error:%08lX:%s:%s:%s%s", e, lib ? lib : "",
341
- func ? func : "", reason ? reason : "", append);
338
+
339
+ if (dOSSL == Qtrue)
340
+ rb_warn("error on stack: %"PRIsVALUE, str);
341
+ if (!NIL_P(ary))
342
+ rb_ary_push(ary, str);
342
343
  }
343
344
  }
344
345
  else {
@@ -346,14 +347,59 @@ ossl_clear_error(void)
346
347
  }
347
348
  }
348
349
 
350
+ void
351
+ ossl_clear_error(void)
352
+ {
353
+ collect_errors_into(Qnil);
354
+ }
355
+
356
+ /*
357
+ * call-seq:
358
+ * ossl_error.detailed_message(**) -> string
359
+ *
360
+ * Returns the exception message decorated with the captured \OpenSSL error
361
+ * queue entries.
362
+ */
363
+ static VALUE
364
+ osslerror_detailed_message(int argc, VALUE *argv, VALUE self)
365
+ {
366
+ VALUE str;
367
+ #ifdef HAVE_RB_CALL_SUPER_KW
368
+ // Ruby >= 3.2
369
+ if (RTEST(rb_funcall(rb_eException, rb_intern("method_defined?"), 1,
370
+ ID2SYM(rb_intern("detailed_message")))))
371
+ str = rb_call_super_kw(argc, argv, RB_PASS_CALLED_KEYWORDS);
372
+ else
373
+ #endif
374
+ str = rb_funcall(self, rb_intern("message"), 0);
375
+ VALUE errors = rb_attr_get(self, id_i_errors);
376
+
377
+ // OpenSSLError was not created by ossl_make_error()
378
+ if (!RB_TYPE_P(errors, T_ARRAY))
379
+ return str;
380
+
381
+ str = rb_str_resurrect(str);
382
+ rb_str_catf(str, "\nOpenSSL error queue reported %ld errors:",
383
+ RARRAY_LEN(errors));
384
+ for (long i = 0; i < RARRAY_LEN(errors); i++) {
385
+ VALUE err = RARRAY_AREF(errors, i);
386
+ rb_str_catf(str, "\n%"PRIsVALUE, err);
387
+ }
388
+ return str;
389
+ }
390
+
349
391
  /*
350
392
  * call-seq:
351
393
  * OpenSSL.errors -> [String...]
352
394
  *
353
- * See any remaining errors held in queue.
395
+ * Returns any remaining errors held in the \OpenSSL thread-local error queue
396
+ * and clears the queue. This should normally return an empty array.
397
+ *
398
+ * This is intended for debugging Ruby/OpenSSL. If you see any errors here,
399
+ * it likely indicates a bug in the extension. Please file an issue at
400
+ * https://github.com/ruby/openssl.
354
401
  *
355
- * Any errors you see here are probably due to a bug in Ruby's OpenSSL
356
- * implementation.
402
+ * For debugging your program, OpenSSL.debug= may be useful.
357
403
  */
358
404
  static VALUE
359
405
  ossl_get_errors(VALUE _)
@@ -377,6 +423,8 @@ VALUE dOSSL;
377
423
  /*
378
424
  * call-seq:
379
425
  * OpenSSL.debug -> true | false
426
+ *
427
+ * Returns whether Ruby/OpenSSL's debug mode is currently enabled.
380
428
  */
381
429
  static VALUE
382
430
  ossl_debug_get(VALUE self)
@@ -386,9 +434,9 @@ ossl_debug_get(VALUE self)
386
434
 
387
435
  /*
388
436
  * call-seq:
389
- * OpenSSL.debug = boolean -> boolean
437
+ * OpenSSL.debug = boolean
390
438
  *
391
- * Turns on or off debug mode. With debug mode, all errors added to the OpenSSL
439
+ * Turns on or off debug mode. With debug mode, all errors added to the \OpenSSL
392
440
  * error queue will be printed to stderr.
393
441
  */
394
442
  static VALUE
@@ -402,6 +450,8 @@ ossl_debug_set(VALUE self, VALUE val)
402
450
  /*
403
451
  * call-seq:
404
452
  * OpenSSL.fips_mode -> true | false
453
+ *
454
+ * Returns whether the FIPS mode is currently enabled.
405
455
  */
406
456
  static VALUE
407
457
  ossl_fips_mode_get(VALUE self)
@@ -411,7 +461,7 @@ ossl_fips_mode_get(VALUE self)
411
461
  VALUE enabled;
412
462
  enabled = EVP_default_properties_is_fips_enabled(NULL) ? Qtrue : Qfalse;
413
463
  return enabled;
414
- #elif defined(OPENSSL_FIPS)
464
+ #elif defined(OPENSSL_FIPS) || defined(OPENSSL_IS_AWSLC)
415
465
  VALUE enabled;
416
466
  enabled = FIPS_mode() ? Qtrue : Qfalse;
417
467
  return enabled;
@@ -422,10 +472,10 @@ ossl_fips_mode_get(VALUE self)
422
472
 
423
473
  /*
424
474
  * call-seq:
425
- * OpenSSL.fips_mode = boolean -> boolean
475
+ * OpenSSL.fips_mode = boolean
426
476
  *
427
477
  * Turns FIPS mode on or off. Turning on FIPS mode will obviously only have an
428
- * effect for FIPS-capable installations of the OpenSSL library. Trying to do
478
+ * effect for FIPS-capable installations of the \OpenSSL library. Trying to do
429
479
  * so otherwise will result in an error.
430
480
  *
431
481
  * === Examples
@@ -446,145 +496,62 @@ ossl_fips_mode_set(VALUE self, VALUE enabled)
446
496
  }
447
497
  }
448
498
  return enabled;
449
- #elif defined(OPENSSL_FIPS)
499
+ #elif defined(OPENSSL_FIPS) || defined(OPENSSL_IS_AWSLC)
450
500
  if (RTEST(enabled)) {
451
- int mode = FIPS_mode();
452
- if(!mode && !FIPS_mode_set(1)) /* turning on twice leads to an error */
453
- ossl_raise(eOSSLError, "Turning on FIPS mode failed");
501
+ int mode = FIPS_mode();
502
+ if(!mode && !FIPS_mode_set(1)) /* turning on twice leads to an error */
503
+ ossl_raise(eOSSLError, "Turning on FIPS mode failed");
454
504
  } else {
455
- if(!FIPS_mode_set(0)) /* turning off twice is OK */
456
- ossl_raise(eOSSLError, "Turning off FIPS mode failed");
505
+ if(!FIPS_mode_set(0)) /* turning off twice is OK */
506
+ ossl_raise(eOSSLError, "Turning off FIPS mode failed");
457
507
  }
458
508
  return enabled;
459
509
  #else
460
510
  if (RTEST(enabled))
461
- ossl_raise(eOSSLError, "This version of OpenSSL does not support FIPS mode");
511
+ ossl_raise(eOSSLError, "This version of OpenSSL does not support FIPS mode");
462
512
  return enabled;
463
513
  #endif
464
514
  }
465
515
 
466
- #if !defined(HAVE_OPENSSL_110_THREADING_API)
467
- /**
468
- * Stores locks needed for OpenSSL thread safety
469
- */
470
- struct CRYPTO_dynlock_value {
471
- rb_nativethread_lock_t lock;
472
- rb_nativethread_id_t owner;
473
- size_t count;
474
- };
475
-
476
- static void
477
- ossl_lock_init(struct CRYPTO_dynlock_value *l)
478
- {
479
- rb_nativethread_lock_initialize(&l->lock);
480
- l->count = 0;
481
- }
482
-
483
- static void
484
- ossl_lock_unlock(int mode, struct CRYPTO_dynlock_value *l)
485
- {
486
- if (mode & CRYPTO_LOCK) {
487
- /* TODO: rb_nativethread_id_t is not necessarily compared with ==. */
488
- rb_nativethread_id_t tid = rb_nativethread_self();
489
- if (l->count && l->owner == tid) {
490
- l->count++;
491
- return;
492
- }
493
- rb_nativethread_lock_lock(&l->lock);
494
- l->owner = tid;
495
- l->count = 1;
496
- } else {
497
- if (!--l->count)
498
- rb_nativethread_lock_unlock(&l->lock);
499
- }
500
- }
501
-
502
- static struct CRYPTO_dynlock_value *
503
- ossl_dyn_create_callback(const char *file, int line)
504
- {
505
- /* Do not use xmalloc() here, since it may raise NoMemoryError */
506
- struct CRYPTO_dynlock_value *dynlock =
507
- OPENSSL_malloc(sizeof(struct CRYPTO_dynlock_value));
508
- if (dynlock)
509
- ossl_lock_init(dynlock);
510
- return dynlock;
511
- }
512
-
513
- static void
514
- ossl_dyn_lock_callback(int mode, struct CRYPTO_dynlock_value *l, const char *file, int line)
515
- {
516
- ossl_lock_unlock(mode, l);
517
- }
518
-
519
- static void
520
- ossl_dyn_destroy_callback(struct CRYPTO_dynlock_value *l, const char *file, int line)
521
- {
522
- rb_nativethread_lock_destroy(&l->lock);
523
- OPENSSL_free(l);
524
- }
525
-
526
- static void ossl_threadid_func(CRYPTO_THREADID *id)
527
- {
528
- /* register native thread id */
529
- CRYPTO_THREADID_set_pointer(id, (void *)rb_nativethread_self());
530
- }
531
-
532
- static struct CRYPTO_dynlock_value *ossl_locks;
533
-
534
- static void
535
- ossl_lock_callback(int mode, int type, const char *file, int line)
536
- {
537
- ossl_lock_unlock(mode, &ossl_locks[type]);
538
- }
539
-
540
- static void Init_ossl_locks(void)
541
- {
542
- int i;
543
- int num_locks = CRYPTO_num_locks();
544
-
545
- ossl_locks = ALLOC_N(struct CRYPTO_dynlock_value, num_locks);
546
- for (i = 0; i < num_locks; i++)
547
- ossl_lock_init(&ossl_locks[i]);
548
-
549
- CRYPTO_THREADID_set_callback(ossl_threadid_func);
550
- CRYPTO_set_locking_callback(ossl_lock_callback);
551
- CRYPTO_set_dynlock_create_callback(ossl_dyn_create_callback);
552
- CRYPTO_set_dynlock_lock_callback(ossl_dyn_lock_callback);
553
- CRYPTO_set_dynlock_destroy_callback(ossl_dyn_destroy_callback);
554
- }
555
- #endif /* !HAVE_OPENSSL_110_THREADING_API */
556
-
557
516
  /*
558
517
  * call-seq:
559
- * OpenSSL.fixed_length_secure_compare(string, string) -> boolean
518
+ * OpenSSL.fixed_length_secure_compare(string, string) -> true or false
560
519
  *
561
520
  * Constant time memory comparison for fixed length strings, such as results
562
- * of HMAC calculations.
521
+ * of \HMAC calculations.
563
522
  *
564
523
  * Returns +true+ if the strings are identical, +false+ if they are of the same
565
- * length but not identical. If the length is different, +ArgumentError+ is
524
+ * length but not identical. If the length is different, ArgumentError is
566
525
  * raised.
567
526
  */
568
527
  static VALUE
569
528
  ossl_crypto_fixed_length_secure_compare(VALUE dummy, VALUE str1, VALUE str2)
570
529
  {
571
- const unsigned char *p1 = (const unsigned char *)StringValuePtr(str1);
572
- const unsigned char *p2 = (const unsigned char *)StringValuePtr(str2);
573
- long len1 = RSTRING_LEN(str1);
574
- long len2 = RSTRING_LEN(str2);
530
+ const unsigned char *p1;
531
+ const unsigned char *p2;
532
+ long len1;
533
+ long len2;
534
+
535
+ StringValue(str1);
536
+ StringValue(str2);
537
+
538
+ p1 = (const unsigned char *)RSTRING_PTR(str1);
539
+ p2 = (const unsigned char *)RSTRING_PTR(str2);
540
+ len1 = RSTRING_LEN(str1);
541
+ len2 = RSTRING_LEN(str2);
575
542
 
576
543
  if (len1 != len2) {
577
544
  ossl_raise(rb_eArgError, "inputs must be of equal length");
578
545
  }
579
546
 
580
547
  switch (CRYPTO_memcmp(p1, p2, len1)) {
581
- case 0: return Qtrue;
582
- default: return Qfalse;
548
+ case 0: return Qtrue;
549
+ default: return Qfalse;
583
550
  }
584
551
  }
585
552
 
586
553
  /*
587
- * OpenSSL provides SSL, TLS and general purpose cryptography. It wraps the
554
+ * OpenSSL provides \SSL, TLS and general purpose cryptography. It wraps the
588
555
  * OpenSSL[https://www.openssl.org/] library.
589
556
  *
590
557
  * = Examples
@@ -639,7 +606,7 @@ ossl_crypto_fixed_length_secure_compare(VALUE dummy, VALUE str1, VALUE str2)
639
606
  *
640
607
  * === Loading an Encrypted Key
641
608
  *
642
- * OpenSSL will prompt you for your password when loading an encrypted key.
609
+ * \OpenSSL will prompt you for your password when loading an encrypted key.
643
610
  * If you will not be able to type in the password you may provide it when
644
611
  * loading the key:
645
612
  *
@@ -702,7 +669,7 @@ ossl_crypto_fixed_length_secure_compare(VALUE dummy, VALUE str1, VALUE str2)
702
669
  *
703
670
  * == PBKDF2 Password-based Encryption
704
671
  *
705
- * If supported by the underlying OpenSSL version used, Password-based
672
+ * If supported by the underlying \OpenSSL version used, Password-based
706
673
  * Encryption should use the features of PKCS5. If not supported or if
707
674
  * required by legacy applications, the older, less secure methods specified
708
675
  * in RFC 2898 are also supported (see below).
@@ -761,7 +728,7 @@ ossl_crypto_fixed_length_secure_compare(VALUE dummy, VALUE str1, VALUE str2)
761
728
  * decrypted = cipher.update encrypted
762
729
  * decrypted << cipher.final
763
730
  *
764
- * == X509 Certificates
731
+ * == \X509 Certificates
765
732
  *
766
733
  * === Creating a Certificate
767
734
  *
@@ -798,7 +765,7 @@ ossl_crypto_fixed_length_secure_compare(VALUE dummy, VALUE str1, VALUE str2)
798
765
  * extension_factory.create_extension('subjectKeyIdentifier', 'hash')
799
766
  *
800
767
  * The list of supported extensions (and in some cases their possible values)
801
- * can be derived from the "objects.h" file in the OpenSSL source code.
768
+ * can be derived from the "objects.h" file in the \OpenSSL source code.
802
769
  *
803
770
  * === Signing a Certificate
804
771
  *
@@ -952,23 +919,23 @@ ossl_crypto_fixed_length_secure_compare(VALUE dummy, VALUE str1, VALUE str2)
952
919
  * io.write csr_cert.to_pem
953
920
  * end
954
921
  *
955
- * == SSL and TLS Connections
922
+ * == \SSL and TLS Connections
956
923
  *
957
- * Using our created key and certificate we can create an SSL or TLS connection.
958
- * An SSLContext is used to set up an SSL session.
924
+ * Using our created key and certificate we can create an \SSL or TLS
925
+ * connection. An OpenSSL::SSL::SSLContext is used to set up an \SSL session.
959
926
  *
960
927
  * context = OpenSSL::SSL::SSLContext.new
961
928
  *
962
- * === SSL Server
929
+ * === \SSL Server
963
930
  *
964
- * An SSL server requires the certificate and private key to communicate
931
+ * An \SSL server requires the certificate and private key to communicate
965
932
  * securely with its clients:
966
933
  *
967
934
  * context.cert = cert
968
935
  * context.key = key
969
936
  *
970
- * Then create an SSLServer with a TCP server socket and the context. Use the
971
- * SSLServer like an ordinary TCP server.
937
+ * Then create an OpenSSL::SSL::SSLServer with a TCP server socket and the
938
+ * context. Use the SSLServer like an ordinary TCP server.
972
939
  *
973
940
  * require 'socket'
974
941
  *
@@ -987,14 +954,15 @@ ossl_crypto_fixed_length_secure_compare(VALUE dummy, VALUE str1, VALUE str2)
987
954
  * ssl_connection.close
988
955
  * end
989
956
  *
990
- * === SSL client
957
+ * === \SSL client
991
958
  *
992
- * An SSL client is created with a TCP socket and the context.
993
- * SSLSocket#connect must be called to initiate the SSL handshake and start
994
- * encryption. A key and certificate are not required for the client socket.
959
+ * An \SSL client is created with a TCP socket and the context.
960
+ * OpenSSL::SSL::SSLSocket#connect must be called to initiate the \SSL handshake
961
+ * and start encryption. A key and certificate are not required for the client
962
+ * socket.
995
963
  *
996
- * Note that SSLSocket#close doesn't close the underlying socket by default. Set
997
- * SSLSocket#sync_close to true if you want.
964
+ * Note that OpenSSL::SSL::SSLSocket#close doesn't close the underlying socket
965
+ * by default. Set OpenSSL::SSL::SSLSocket#sync_close to true if you want.
998
966
  *
999
967
  * require 'socket'
1000
968
  *
@@ -1010,7 +978,7 @@ ossl_crypto_fixed_length_secure_compare(VALUE dummy, VALUE str1, VALUE str2)
1010
978
  *
1011
979
  * === Peer Verification
1012
980
  *
1013
- * An unverified SSL connection does not provide much security. For enhanced
981
+ * An unverified \SSL connection does not provide much security. For enhanced
1014
982
  * security the client or server can verify the certificate of its peer.
1015
983
  *
1016
984
  * The client can be modified to verify the server's certificate against the
@@ -1050,15 +1018,8 @@ Init_openssl(void)
1050
1018
  /*
1051
1019
  * Init all digests, ciphers
1052
1020
  */
1053
- #if !defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000
1054
1021
  if (!OPENSSL_init_ssl(0, NULL))
1055
1022
  rb_raise(rb_eRuntimeError, "OPENSSL_init_ssl");
1056
- #else
1057
- OpenSSL_add_ssl_algorithms();
1058
- OpenSSL_add_all_algorithms();
1059
- ERR_load_crypto_strings();
1060
- SSL_load_error_strings();
1061
- #endif
1062
1023
 
1063
1024
  /*
1064
1025
  * Init main module
@@ -1068,26 +1029,34 @@ Init_openssl(void)
1068
1029
  rb_define_singleton_method(mOSSL, "fixed_length_secure_compare", ossl_crypto_fixed_length_secure_compare, 2);
1069
1030
 
1070
1031
  /*
1071
- * Version of OpenSSL the ruby OpenSSL extension was built with
1032
+ * \OpenSSL library version string used to compile the Ruby/OpenSSL
1033
+ * extension. This may differ from the version used at runtime.
1072
1034
  */
1073
- rb_define_const(mOSSL, "OPENSSL_VERSION", rb_str_new2(OPENSSL_VERSION_TEXT));
1035
+ rb_define_const(mOSSL, "OPENSSL_VERSION",
1036
+ rb_obj_freeze(rb_str_new_cstr(OPENSSL_VERSION_TEXT)));
1074
1037
 
1075
1038
  /*
1076
- * Version of OpenSSL the ruby OpenSSL extension is running with
1039
+ * \OpenSSL library version string currently used at runtime.
1077
1040
  */
1078
- #if !defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000
1079
- rb_define_const(mOSSL, "OPENSSL_LIBRARY_VERSION", rb_str_new2(OpenSSL_version(OPENSSL_VERSION)));
1080
- #else
1081
- rb_define_const(mOSSL, "OPENSSL_LIBRARY_VERSION", rb_str_new2(SSLeay_version(SSLEAY_VERSION)));
1082
- #endif
1041
+ rb_define_const(
1042
+ mOSSL,
1043
+ "OPENSSL_LIBRARY_VERSION",
1044
+ rb_obj_freeze(rb_str_new_cstr(OpenSSL_version(OPENSSL_VERSION)))
1045
+ );
1083
1046
 
1084
1047
  /*
1085
- * Version number of OpenSSL the ruby OpenSSL extension was built with
1086
- * (base 16). The formats are below.
1048
+ * \OpenSSL library version number used to compile the Ruby/OpenSSL
1049
+ * extension. This may differ from the version used at runtime.
1087
1050
  *
1088
- * [OpenSSL 3] <tt>0xMNN00PP0 (major minor 00 patch 0)</tt>
1089
- * [OpenSSL before 3] <tt>0xMNNFFPPS (major minor fix patch status)</tt>
1090
- * [LibreSSL] <tt>0x20000000 (fixed value)</tt>
1051
+ * The version number is encoded into a single integer value. The number
1052
+ * follows the format:
1053
+ *
1054
+ * [\OpenSSL 3.0.0 or later]
1055
+ * <tt>0xMNN00PP0</tt> (major minor 00 patch 0)
1056
+ * [\OpenSSL 1.1.1 or earlier]
1057
+ * <tt>0xMNNFFPPS</tt> (major minor fix patch status)
1058
+ * [LibreSSL]
1059
+ * <tt>0x20000000</tt> (a fixed value)
1091
1060
  *
1092
1061
  * See also the man page OPENSSL_VERSION_NUMBER(3).
1093
1062
  */
@@ -1095,9 +1064,12 @@ Init_openssl(void)
1095
1064
 
1096
1065
  #if defined(LIBRESSL_VERSION_NUMBER)
1097
1066
  /*
1098
- * Version number of LibreSSL the ruby OpenSSL extension was built with
1099
- * (base 16). The format is <tt>0xMNNFF00f (major minor fix 00
1100
- * status)</tt>. This constant is only defined in LibreSSL cases.
1067
+ * LibreSSL library version number used to compile the Ruby/OpenSSL
1068
+ * extension. This may differ from the version used at runtime.
1069
+ *
1070
+ * This constant is only defined if the extension was compiled against
1071
+ * LibreSSL. The number follows the format:
1072
+ * <tt>0xMNNFF00f</tt> (major minor fix 00 status).
1101
1073
  *
1102
1074
  * See also the man page LIBRESSL_VERSION_NUMBER(3).
1103
1075
  */
@@ -1105,28 +1077,50 @@ Init_openssl(void)
1105
1077
  #endif
1106
1078
 
1107
1079
  /*
1108
- * Boolean indicating whether OpenSSL is FIPS-capable or not
1080
+ * Boolean indicating whether the \OpenSSL library is FIPS-capable or not.
1081
+ * Always <tt>true</tt> for \OpenSSL 3.0 and later.
1082
+ *
1083
+ * This is obsolete and will be removed in the future.
1084
+ * See also OpenSSL.fips_mode.
1109
1085
  */
1110
1086
  rb_define_const(mOSSL, "OPENSSL_FIPS",
1111
1087
  /* OpenSSL 3 is FIPS-capable even when it is installed without fips option */
1112
1088
  #if OSSL_OPENSSL_PREREQ(3, 0, 0)
1113
1089
  Qtrue
1114
1090
  #elif defined(OPENSSL_FIPS)
1115
- Qtrue
1091
+ Qtrue
1092
+ #elif defined(OPENSSL_IS_AWSLC) // AWS-LC FIPS can only be enabled during compile time.
1093
+ FIPS_mode() ? Qtrue : Qfalse
1116
1094
  #else
1117
- Qfalse
1095
+ Qfalse
1118
1096
  #endif
1119
- );
1097
+ );
1120
1098
 
1121
1099
  rb_define_module_function(mOSSL, "fips_mode", ossl_fips_mode_get, 0);
1122
1100
  rb_define_module_function(mOSSL, "fips_mode=", ossl_fips_mode_set, 1);
1123
1101
 
1124
1102
  rb_global_variable(&eOSSLError);
1125
1103
  /*
1126
- * Generic error,
1127
- * common for all classes under OpenSSL module
1104
+ * Generic error class for OpenSSL. All error classes in this library
1105
+ * inherit from this class.
1106
+ *
1107
+ * This class indicates that an error was reported by the underlying
1108
+ * \OpenSSL library.
1128
1109
  */
1129
- eOSSLError = rb_define_class_under(mOSSL,"OpenSSLError",rb_eStandardError);
1110
+ eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError);
1111
+ /*
1112
+ * \OpenSSL error queue entries captured at the time the exception was
1113
+ * raised. The same information is printed to stderr if OpenSSL.debug is
1114
+ * set to +true+.
1115
+ *
1116
+ * This is an array of zero or more strings, ordered from the oldest to the
1117
+ * newest. The format of the strings is not stable and may vary across
1118
+ * versions of \OpenSSL or versions of this Ruby extension.
1119
+ *
1120
+ * See also the man page ERR_get_error(3).
1121
+ */
1122
+ rb_attr(eOSSLError, rb_intern_const("errors"), 1, 0, 0);
1123
+ rb_define_method(eOSSLError, "detailed_message", osslerror_detailed_message, -1);
1130
1124
 
1131
1125
  /*
1132
1126
  * Init debug core
@@ -1142,10 +1136,7 @@ Init_openssl(void)
1142
1136
  * Get ID of to_der
1143
1137
  */
1144
1138
  ossl_s_to_der = rb_intern("to_der");
1145
-
1146
- #if !defined(HAVE_OPENSSL_110_THREADING_API)
1147
- Init_ossl_locks();
1148
- #endif
1139
+ id_i_errors = rb_intern("@errors");
1149
1140
 
1150
1141
  /*
1151
1142
  * Init components