openssl 3.3.2 → 4.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 (55) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.md +3 -0
  3. data/History.md +85 -0
  4. data/README.md +12 -11
  5. data/ext/openssl/extconf.rb +30 -69
  6. data/ext/openssl/openssl_missing.h +0 -206
  7. data/ext/openssl/ossl.c +280 -301
  8. data/ext/openssl/ossl.h +15 -10
  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 +3 -3
  12. data/ext/openssl/ossl_bn.c +286 -291
  13. data/ext/openssl/ossl_cipher.c +252 -203
  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 +31 -37
  22. data/ext/openssl/ossl_ocsp.c +214 -241
  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 +162 -178
  26. data/ext/openssl/ossl_pkey.h +99 -99
  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 +179 -237
  30. data/ext/openssl/ossl_pkey_rsa.c +56 -103
  31. data/ext/openssl/ossl_provider.c +0 -7
  32. data/ext/openssl/ossl_rand.c +7 -14
  33. data/ext/openssl/ossl_ssl.c +478 -353
  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 +81 -127
  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 +69 -100
  40. data/ext/openssl/ossl_x509crl.c +78 -89
  41. data/ext/openssl/ossl_x509ext.c +45 -66
  42. data/ext/openssl/ossl_x509name.c +63 -88
  43. data/ext/openssl/ossl_x509req.c +55 -62
  44. data/ext/openssl/ossl_x509revoked.c +27 -41
  45. data/ext/openssl/ossl_x509store.c +38 -56
  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 -40
  55. data/lib/openssl/asn1.rb +0 -188
data/ext/openssl/ossl.c CHANGED
@@ -10,88 +10,74 @@
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
+ sk_##type##_push(sk, x); \
38
+ } \
39
+ return (VALUE)sk; \
40
+ } \
41
+ \
42
+ STACK_OF(type) * \
43
+ ossl_protect_##name##_ary2sk(VALUE ary, int *status) \
44
+ { \
45
+ return (STACK_OF(type)*)rb_protect( \
46
+ (VALUE (*)(VALUE))ossl_##name##_ary2sk0, \
47
+ ary, \
48
+ status); \
49
+ } \
50
+ \
51
+ STACK_OF(type) * \
52
+ ossl_##name##_ary2sk(VALUE ary) \
53
+ { \
54
+ STACK_OF(type) *sk; \
55
+ int status = 0; \
56
+ \
57
+ sk = ossl_protect_##name##_ary2sk(ary, &status); \
58
+ if (status) rb_jump_tag(status); \
59
+ \
60
+ return sk; \
68
61
  }
69
62
  OSSL_IMPL_ARY2SK(x509, X509, cX509Cert, DupX509CertPtr)
70
63
 
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; \
64
+ #define OSSL_IMPL_SK2ARY(name, type) \
65
+ VALUE \
66
+ ossl_##name##_sk2ary(const STACK_OF(type) *sk) \
67
+ { \
68
+ type *t; \
69
+ int i, num; \
70
+ VALUE ary; \
71
+ \
72
+ RUBY_ASSERT(sk != NULL); \
73
+ num = sk_##type##_num(sk); \
74
+ ary = rb_ary_new_capa(num); \
75
+ \
76
+ for (i=0; i<num; i++) { \
77
+ t = sk_##type##_value(sk, i); \
78
+ rb_ary_push(ary, ossl_##name##_new(t)); \
79
+ } \
80
+ return ary; \
95
81
  }
96
82
  OSSL_IMPL_SK2ARY(x509, X509)
97
83
  OSSL_IMPL_SK2ARY(x509crl, X509_CRL)
@@ -111,14 +97,14 @@ ossl_str_new(const char *ptr, long len, int *pstate)
111
97
 
112
98
  str = rb_protect(ossl_str_new_i, len, &state);
113
99
  if (pstate)
114
- *pstate = state;
100
+ *pstate = state;
115
101
  if (state) {
116
- if (!pstate)
117
- rb_set_errinfo(Qnil);
118
- return Qnil;
102
+ if (!pstate)
103
+ rb_set_errinfo(Qnil);
104
+ return Qnil;
119
105
  }
120
106
  if (ptr)
121
- memcpy(RSTRING_PTR(str), ptr, len);
107
+ memcpy(RSTRING_PTR(str), ptr, len);
122
108
  return str;
123
109
  }
124
110
 
@@ -131,22 +117,22 @@ ossl_buf2str(char *buf, int len)
131
117
  str = ossl_str_new(buf, len, &state);
132
118
  OPENSSL_free(buf);
133
119
  if (state)
134
- rb_jump_tag(state);
120
+ rb_jump_tag(state);
135
121
  return str;
136
122
  }
137
123
 
138
124
  void
139
- ossl_bin2hex(unsigned char *in, char *out, size_t inlen)
125
+ ossl_bin2hex(const unsigned char *in, char *out, size_t inlen)
140
126
  {
141
127
  const char *hex = "0123456789abcdef";
142
128
  size_t i;
143
129
 
144
130
  assert(inlen <= LONG_MAX / 2);
145
131
  for (i = 0; i < inlen; i++) {
146
- unsigned char p = in[i];
132
+ unsigned char p = in[i];
147
133
 
148
- out[i * 2 + 0] = hex[p >> 4];
149
- out[i * 2 + 1] = hex[p & 0x0f];
134
+ out[i * 2 + 0] = hex[p >> 4];
135
+ out[i * 2 + 1] = hex[p & 0x0f];
150
136
  }
151
137
  }
152
138
 
@@ -157,14 +143,14 @@ VALUE
157
143
  ossl_pem_passwd_value(VALUE pass)
158
144
  {
159
145
  if (NIL_P(pass))
160
- return Qnil;
146
+ return Qnil;
161
147
 
162
148
  StringValue(pass);
163
149
 
164
150
  /* PEM_BUFSIZE is currently used as the second argument of pem_password_cb,
165
151
  * that is +max_len+ of ossl_pem_passwd_cb() */
166
152
  if (RSTRING_LEN(pass) > PEM_BUFSIZE)
167
- ossl_raise(eOSSLError, "password must not be longer than %d bytes", PEM_BUFSIZE);
153
+ ossl_raise(eOSSLError, "password must not be longer than %d bytes", PEM_BUFSIZE);
168
154
 
169
155
  return pass;
170
156
  }
@@ -174,7 +160,7 @@ ossl_pem_passwd_cb0(VALUE flag)
174
160
  {
175
161
  VALUE pass = rb_yield(flag);
176
162
  if (NIL_P(pass))
177
- return Qnil;
163
+ return Qnil;
178
164
  StringValue(pass);
179
165
  return pass;
180
166
  }
@@ -187,46 +173,46 @@ ossl_pem_passwd_cb(char *buf, int max_len, int flag, void *pwd_)
187
173
  VALUE rflag, pass = (VALUE)pwd_;
188
174
 
189
175
  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;
176
+ /* PEM_def_callback(buf, max_len, flag, StringValueCStr(pass)) does not
177
+ * work because it does not allow NUL characters and truncates to 1024
178
+ * bytes silently if the input is over 1024 bytes */
179
+ if (RB_TYPE_P(pass, T_STRING)) {
180
+ len = RSTRING_LEN(pass);
181
+ if (len <= max_len) {
182
+ memcpy(buf, RSTRING_PTR(pass), len);
183
+ return (int)len;
184
+ }
185
+ }
186
+ OSSL_Debug("passed data is not valid String???");
187
+ return -1;
202
188
  }
203
189
 
204
190
  if (!rb_block_given_p()) {
205
- return PEM_def_callback(buf, max_len, flag, NULL);
191
+ return PEM_def_callback(buf, max_len, flag, NULL);
206
192
  }
207
193
 
208
194
  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;
195
+ /*
196
+ * when the flag is nonzero, this password
197
+ * will be used to perform encryption; otherwise it will
198
+ * be used to perform decryption.
199
+ */
200
+ rflag = flag ? Qtrue : Qfalse;
201
+ pass = rb_protect(ossl_pem_passwd_cb0, rflag, &status);
202
+ if (status) {
203
+ /* ignore an exception raised. */
204
+ rb_set_errinfo(Qnil);
205
+ return -1;
206
+ }
207
+ if (NIL_P(pass))
208
+ return -1;
209
+ len = RSTRING_LEN(pass);
210
+ if (len > max_len) {
211
+ rb_warning("password must not be longer than %d bytes", max_len);
212
+ continue;
213
+ }
214
+ memcpy(buf, RSTRING_PTR(pass), len);
215
+ break;
230
216
  }
231
217
  return (int)len;
232
218
  }
@@ -261,19 +247,24 @@ VALUE
261
247
  ossl_to_der_if_possible(VALUE obj)
262
248
  {
263
249
  if(rb_respond_to(obj, ossl_s_to_der))
264
- return ossl_to_der(obj);
250
+ return ossl_to_der(obj);
265
251
  return obj;
266
252
  }
267
253
 
268
254
  /*
269
255
  * Errors
270
256
  */
257
+ static ID id_i_errors;
258
+
259
+ static void collect_errors_into(VALUE ary);
260
+
271
261
  VALUE
272
262
  ossl_make_error(VALUE exc, VALUE str)
273
263
  {
274
264
  unsigned long e;
275
265
  const char *data;
276
266
  int flags;
267
+ VALUE errors = rb_ary_new();
277
268
 
278
269
  if (NIL_P(str))
279
270
  str = rb_str_new(NULL, 0);
@@ -290,10 +281,12 @@ ossl_make_error(VALUE exc, VALUE str)
290
281
  rb_str_cat_cstr(str, msg ? msg : "(null)");
291
282
  if (flags & ERR_TXT_STRING && data)
292
283
  rb_str_catf(str, " (%s)", data);
293
- ossl_clear_error();
284
+ collect_errors_into(errors);
294
285
  }
295
286
 
296
- return rb_exc_new_str(exc, str);
287
+ VALUE obj = rb_exc_new_str(exc, str);
288
+ rb_ivar_set(obj, id_i_errors, errors);
289
+ return obj;
297
290
  }
298
291
 
299
292
  void
@@ -303,24 +296,23 @@ ossl_raise(VALUE exc, const char *fmt, ...)
303
296
  VALUE err;
304
297
 
305
298
  if (fmt) {
306
- va_start(args, fmt);
307
- err = rb_vsprintf(fmt, args);
308
- va_end(args);
299
+ va_start(args, fmt);
300
+ err = rb_vsprintf(fmt, args);
301
+ va_end(args);
309
302
  }
310
303
  else {
311
- err = Qnil;
304
+ err = Qnil;
312
305
  }
313
306
 
314
307
  rb_exc_raise(ossl_make_error(exc, err));
315
308
  }
316
309
 
317
- void
318
- ossl_clear_error(void)
310
+ static void
311
+ collect_errors_into(VALUE ary)
319
312
  {
320
- if (dOSSL == Qtrue) {
313
+ if (dOSSL == Qtrue || !NIL_P(ary)) {
321
314
  unsigned long e;
322
315
  const char *file, *data, *func, *lib, *reason;
323
- char append[256] = "";
324
316
  int line, flags;
325
317
 
326
318
  #ifdef HAVE_ERR_GET_ERROR_ALL
@@ -332,13 +324,18 @@ ossl_clear_error(void)
332
324
  lib = ERR_lib_error_string(e);
333
325
  reason = ERR_reason_error_string(e);
334
326
 
327
+ VALUE str = rb_sprintf("error:%08lX:%s:%s:%s", e, lib ? lib : "",
328
+ func ? func : "", reason ? reason : "");
335
329
  if (flags & ERR_TXT_STRING) {
336
330
  if (!data)
337
331
  data = "(null)";
338
- snprintf(append, sizeof(append), " (%s)", data);
332
+ rb_str_catf(str, " (%s)", data);
339
333
  }
340
- rb_warn("error on stack: error:%08lX:%s:%s:%s%s", e, lib ? lib : "",
341
- func ? func : "", reason ? reason : "", append);
334
+
335
+ if (dOSSL == Qtrue)
336
+ rb_warn("error on stack: %"PRIsVALUE, str);
337
+ if (!NIL_P(ary))
338
+ rb_ary_push(ary, str);
342
339
  }
343
340
  }
344
341
  else {
@@ -346,14 +343,59 @@ ossl_clear_error(void)
346
343
  }
347
344
  }
348
345
 
346
+ void
347
+ ossl_clear_error(void)
348
+ {
349
+ collect_errors_into(Qnil);
350
+ }
351
+
352
+ /*
353
+ * call-seq:
354
+ * ossl_error.detailed_message(**) -> string
355
+ *
356
+ * Returns the exception message decorated with the captured \OpenSSL error
357
+ * queue entries.
358
+ */
359
+ static VALUE
360
+ osslerror_detailed_message(int argc, VALUE *argv, VALUE self)
361
+ {
362
+ VALUE str;
363
+ #ifdef HAVE_RB_CALL_SUPER_KW
364
+ // Ruby >= 3.2
365
+ if (RTEST(rb_funcall(rb_eException, rb_intern("method_defined?"), 1,
366
+ ID2SYM(rb_intern("detailed_message")))))
367
+ str = rb_call_super_kw(argc, argv, RB_PASS_CALLED_KEYWORDS);
368
+ else
369
+ #endif
370
+ str = rb_funcall(self, rb_intern("message"), 0);
371
+ VALUE errors = rb_attr_get(self, id_i_errors);
372
+
373
+ // OpenSSLError was not created by ossl_make_error()
374
+ if (!RB_TYPE_P(errors, T_ARRAY))
375
+ return str;
376
+
377
+ str = rb_str_resurrect(str);
378
+ rb_str_catf(str, "\nOpenSSL error queue reported %ld errors:",
379
+ RARRAY_LEN(errors));
380
+ for (long i = 0; i < RARRAY_LEN(errors); i++) {
381
+ VALUE err = RARRAY_AREF(errors, i);
382
+ rb_str_catf(str, "\n%"PRIsVALUE, err);
383
+ }
384
+ return str;
385
+ }
386
+
349
387
  /*
350
388
  * call-seq:
351
389
  * OpenSSL.errors -> [String...]
352
390
  *
353
- * See any remaining errors held in queue.
391
+ * Returns any remaining errors held in the \OpenSSL thread-local error queue
392
+ * and clears the queue. This should normally return an empty array.
354
393
  *
355
- * Any errors you see here are probably due to a bug in Ruby's OpenSSL
356
- * implementation.
394
+ * This is intended for debugging Ruby/OpenSSL. If you see any errors here,
395
+ * it likely indicates a bug in the extension. Please file an issue at
396
+ * https://github.com/ruby/openssl.
397
+ *
398
+ * For debugging your program, OpenSSL.debug= may be useful.
357
399
  */
358
400
  static VALUE
359
401
  ossl_get_errors(VALUE _)
@@ -377,6 +419,8 @@ VALUE dOSSL;
377
419
  /*
378
420
  * call-seq:
379
421
  * OpenSSL.debug -> true | false
422
+ *
423
+ * Returns whether Ruby/OpenSSL's debug mode is currently enabled.
380
424
  */
381
425
  static VALUE
382
426
  ossl_debug_get(VALUE self)
@@ -386,9 +430,9 @@ ossl_debug_get(VALUE self)
386
430
 
387
431
  /*
388
432
  * call-seq:
389
- * OpenSSL.debug = boolean -> boolean
433
+ * OpenSSL.debug = boolean
390
434
  *
391
- * Turns on or off debug mode. With debug mode, all errors added to the OpenSSL
435
+ * Turns on or off debug mode. With debug mode, all errors added to the \OpenSSL
392
436
  * error queue will be printed to stderr.
393
437
  */
394
438
  static VALUE
@@ -402,6 +446,8 @@ ossl_debug_set(VALUE self, VALUE val)
402
446
  /*
403
447
  * call-seq:
404
448
  * OpenSSL.fips_mode -> true | false
449
+ *
450
+ * Returns whether the FIPS mode is currently enabled.
405
451
  */
406
452
  static VALUE
407
453
  ossl_fips_mode_get(VALUE self)
@@ -411,7 +457,7 @@ ossl_fips_mode_get(VALUE self)
411
457
  VALUE enabled;
412
458
  enabled = EVP_default_properties_is_fips_enabled(NULL) ? Qtrue : Qfalse;
413
459
  return enabled;
414
- #elif defined(OPENSSL_FIPS)
460
+ #elif defined(OPENSSL_FIPS) || defined(OPENSSL_IS_AWSLC)
415
461
  VALUE enabled;
416
462
  enabled = FIPS_mode() ? Qtrue : Qfalse;
417
463
  return enabled;
@@ -422,10 +468,10 @@ ossl_fips_mode_get(VALUE self)
422
468
 
423
469
  /*
424
470
  * call-seq:
425
- * OpenSSL.fips_mode = boolean -> boolean
471
+ * OpenSSL.fips_mode = boolean
426
472
  *
427
473
  * 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
474
+ * effect for FIPS-capable installations of the \OpenSSL library. Trying to do
429
475
  * so otherwise will result in an error.
430
476
  *
431
477
  * === Examples
@@ -446,123 +492,32 @@ ossl_fips_mode_set(VALUE self, VALUE enabled)
446
492
  }
447
493
  }
448
494
  return enabled;
449
- #elif defined(OPENSSL_FIPS)
495
+ #elif defined(OPENSSL_FIPS) || defined(OPENSSL_IS_AWSLC)
450
496
  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");
497
+ int mode = FIPS_mode();
498
+ if(!mode && !FIPS_mode_set(1)) /* turning on twice leads to an error */
499
+ ossl_raise(eOSSLError, "Turning on FIPS mode failed");
454
500
  } else {
455
- if(!FIPS_mode_set(0)) /* turning off twice is OK */
456
- ossl_raise(eOSSLError, "Turning off FIPS mode failed");
501
+ if(!FIPS_mode_set(0)) /* turning off twice is OK */
502
+ ossl_raise(eOSSLError, "Turning off FIPS mode failed");
457
503
  }
458
504
  return enabled;
459
505
  #else
460
506
  if (RTEST(enabled))
461
- ossl_raise(eOSSLError, "This version of OpenSSL does not support FIPS mode");
507
+ ossl_raise(eOSSLError, "This version of OpenSSL does not support FIPS mode");
462
508
  return enabled;
463
509
  #endif
464
510
  }
465
511
 
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
512
  /*
558
513
  * call-seq:
559
- * OpenSSL.fixed_length_secure_compare(string, string) -> boolean
514
+ * OpenSSL.fixed_length_secure_compare(string, string) -> true or false
560
515
  *
561
516
  * Constant time memory comparison for fixed length strings, such as results
562
- * of HMAC calculations.
517
+ * of \HMAC calculations.
563
518
  *
564
519
  * 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
520
+ * length but not identical. If the length is different, ArgumentError is
566
521
  * raised.
567
522
  */
568
523
  static VALUE
@@ -578,13 +533,13 @@ ossl_crypto_fixed_length_secure_compare(VALUE dummy, VALUE str1, VALUE str2)
578
533
  }
579
534
 
580
535
  switch (CRYPTO_memcmp(p1, p2, len1)) {
581
- case 0: return Qtrue;
582
- default: return Qfalse;
536
+ case 0: return Qtrue;
537
+ default: return Qfalse;
583
538
  }
584
539
  }
585
540
 
586
541
  /*
587
- * OpenSSL provides SSL, TLS and general purpose cryptography. It wraps the
542
+ * OpenSSL provides \SSL, TLS and general purpose cryptography. It wraps the
588
543
  * OpenSSL[https://www.openssl.org/] library.
589
544
  *
590
545
  * = Examples
@@ -639,7 +594,7 @@ ossl_crypto_fixed_length_secure_compare(VALUE dummy, VALUE str1, VALUE str2)
639
594
  *
640
595
  * === Loading an Encrypted Key
641
596
  *
642
- * OpenSSL will prompt you for your password when loading an encrypted key.
597
+ * \OpenSSL will prompt you for your password when loading an encrypted key.
643
598
  * If you will not be able to type in the password you may provide it when
644
599
  * loading the key:
645
600
  *
@@ -702,7 +657,7 @@ ossl_crypto_fixed_length_secure_compare(VALUE dummy, VALUE str1, VALUE str2)
702
657
  *
703
658
  * == PBKDF2 Password-based Encryption
704
659
  *
705
- * If supported by the underlying OpenSSL version used, Password-based
660
+ * If supported by the underlying \OpenSSL version used, Password-based
706
661
  * Encryption should use the features of PKCS5. If not supported or if
707
662
  * required by legacy applications, the older, less secure methods specified
708
663
  * in RFC 2898 are also supported (see below).
@@ -761,7 +716,7 @@ ossl_crypto_fixed_length_secure_compare(VALUE dummy, VALUE str1, VALUE str2)
761
716
  * decrypted = cipher.update encrypted
762
717
  * decrypted << cipher.final
763
718
  *
764
- * == X509 Certificates
719
+ * == \X509 Certificates
765
720
  *
766
721
  * === Creating a Certificate
767
722
  *
@@ -798,7 +753,7 @@ ossl_crypto_fixed_length_secure_compare(VALUE dummy, VALUE str1, VALUE str2)
798
753
  * extension_factory.create_extension('subjectKeyIdentifier', 'hash')
799
754
  *
800
755
  * 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.
756
+ * can be derived from the "objects.h" file in the \OpenSSL source code.
802
757
  *
803
758
  * === Signing a Certificate
804
759
  *
@@ -952,23 +907,23 @@ ossl_crypto_fixed_length_secure_compare(VALUE dummy, VALUE str1, VALUE str2)
952
907
  * io.write csr_cert.to_pem
953
908
  * end
954
909
  *
955
- * == SSL and TLS Connections
910
+ * == \SSL and TLS Connections
956
911
  *
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.
912
+ * Using our created key and certificate we can create an \SSL or TLS
913
+ * connection. An OpenSSL::SSL::SSLContext is used to set up an \SSL session.
959
914
  *
960
915
  * context = OpenSSL::SSL::SSLContext.new
961
916
  *
962
- * === SSL Server
917
+ * === \SSL Server
963
918
  *
964
- * An SSL server requires the certificate and private key to communicate
919
+ * An \SSL server requires the certificate and private key to communicate
965
920
  * securely with its clients:
966
921
  *
967
922
  * context.cert = cert
968
923
  * context.key = key
969
924
  *
970
- * Then create an SSLServer with a TCP server socket and the context. Use the
971
- * SSLServer like an ordinary TCP server.
925
+ * Then create an OpenSSL::SSL::SSLServer with a TCP server socket and the
926
+ * context. Use the SSLServer like an ordinary TCP server.
972
927
  *
973
928
  * require 'socket'
974
929
  *
@@ -987,14 +942,15 @@ ossl_crypto_fixed_length_secure_compare(VALUE dummy, VALUE str1, VALUE str2)
987
942
  * ssl_connection.close
988
943
  * end
989
944
  *
990
- * === SSL client
945
+ * === \SSL client
991
946
  *
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.
947
+ * An \SSL client is created with a TCP socket and the context.
948
+ * OpenSSL::SSL::SSLSocket#connect must be called to initiate the \SSL handshake
949
+ * and start encryption. A key and certificate are not required for the client
950
+ * socket.
995
951
  *
996
- * Note that SSLSocket#close doesn't close the underlying socket by default. Set
997
- * SSLSocket#sync_close to true if you want.
952
+ * Note that OpenSSL::SSL::SSLSocket#close doesn't close the underlying socket
953
+ * by default. Set OpenSSL::SSL::SSLSocket#sync_close to true if you want.
998
954
  *
999
955
  * require 'socket'
1000
956
  *
@@ -1010,7 +966,7 @@ ossl_crypto_fixed_length_secure_compare(VALUE dummy, VALUE str1, VALUE str2)
1010
966
  *
1011
967
  * === Peer Verification
1012
968
  *
1013
- * An unverified SSL connection does not provide much security. For enhanced
969
+ * An unverified \SSL connection does not provide much security. For enhanced
1014
970
  * security the client or server can verify the certificate of its peer.
1015
971
  *
1016
972
  * The client can be modified to verify the server's certificate against the
@@ -1050,15 +1006,8 @@ Init_openssl(void)
1050
1006
  /*
1051
1007
  * Init all digests, ciphers
1052
1008
  */
1053
- #if !defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000
1054
1009
  if (!OPENSSL_init_ssl(0, NULL))
1055
1010
  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
1011
 
1063
1012
  /*
1064
1013
  * Init main module
@@ -1068,26 +1017,34 @@ Init_openssl(void)
1068
1017
  rb_define_singleton_method(mOSSL, "fixed_length_secure_compare", ossl_crypto_fixed_length_secure_compare, 2);
1069
1018
 
1070
1019
  /*
1071
- * Version of OpenSSL the ruby OpenSSL extension was built with
1020
+ * \OpenSSL library version string used to compile the Ruby/OpenSSL
1021
+ * extension. This may differ from the version used at runtime.
1072
1022
  */
1073
- rb_define_const(mOSSL, "OPENSSL_VERSION", rb_str_new2(OPENSSL_VERSION_TEXT));
1023
+ rb_define_const(mOSSL, "OPENSSL_VERSION",
1024
+ rb_obj_freeze(rb_str_new_cstr(OPENSSL_VERSION_TEXT)));
1074
1025
 
1075
1026
  /*
1076
- * Version of OpenSSL the ruby OpenSSL extension is running with
1027
+ * \OpenSSL library version string currently used at runtime.
1077
1028
  */
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
1029
+ rb_define_const(
1030
+ mOSSL,
1031
+ "OPENSSL_LIBRARY_VERSION",
1032
+ rb_obj_freeze(rb_str_new_cstr(OpenSSL_version(OPENSSL_VERSION)))
1033
+ );
1083
1034
 
1084
1035
  /*
1085
- * Version number of OpenSSL the ruby OpenSSL extension was built with
1086
- * (base 16). The formats are below.
1036
+ * \OpenSSL library version number used to compile the Ruby/OpenSSL
1037
+ * extension. This may differ from the version used at runtime.
1038
+ *
1039
+ * The version number is encoded into a single integer value. The number
1040
+ * follows the format:
1087
1041
  *
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>
1042
+ * [\OpenSSL 3.0.0 or later]
1043
+ * <tt>0xMNN00PP0</tt> (major minor 00 patch 0)
1044
+ * [\OpenSSL 1.1.1 or earlier]
1045
+ * <tt>0xMNNFFPPS</tt> (major minor fix patch status)
1046
+ * [LibreSSL]
1047
+ * <tt>0x20000000</tt> (a fixed value)
1091
1048
  *
1092
1049
  * See also the man page OPENSSL_VERSION_NUMBER(3).
1093
1050
  */
@@ -1095,9 +1052,12 @@ Init_openssl(void)
1095
1052
 
1096
1053
  #if defined(LIBRESSL_VERSION_NUMBER)
1097
1054
  /*
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.
1055
+ * LibreSSL library version number used to compile the Ruby/OpenSSL
1056
+ * extension. This may differ from the version used at runtime.
1057
+ *
1058
+ * This constant is only defined if the extension was compiled against
1059
+ * LibreSSL. The number follows the format:
1060
+ * <tt>0xMNNFF00f</tt> (major minor fix 00 status).
1101
1061
  *
1102
1062
  * See also the man page LIBRESSL_VERSION_NUMBER(3).
1103
1063
  */
@@ -1105,28 +1065,50 @@ Init_openssl(void)
1105
1065
  #endif
1106
1066
 
1107
1067
  /*
1108
- * Boolean indicating whether OpenSSL is FIPS-capable or not
1068
+ * Boolean indicating whether the \OpenSSL library is FIPS-capable or not.
1069
+ * Always <tt>true</tt> for \OpenSSL 3.0 and later.
1070
+ *
1071
+ * This is obsolete and will be removed in the future.
1072
+ * See also OpenSSL.fips_mode.
1109
1073
  */
1110
1074
  rb_define_const(mOSSL, "OPENSSL_FIPS",
1111
1075
  /* OpenSSL 3 is FIPS-capable even when it is installed without fips option */
1112
1076
  #if OSSL_OPENSSL_PREREQ(3, 0, 0)
1113
1077
  Qtrue
1114
1078
  #elif defined(OPENSSL_FIPS)
1115
- Qtrue
1079
+ Qtrue
1080
+ #elif defined(OPENSSL_IS_AWSLC) // AWS-LC FIPS can only be enabled during compile time.
1081
+ FIPS_mode() ? Qtrue : Qfalse
1116
1082
  #else
1117
- Qfalse
1083
+ Qfalse
1118
1084
  #endif
1119
- );
1085
+ );
1120
1086
 
1121
1087
  rb_define_module_function(mOSSL, "fips_mode", ossl_fips_mode_get, 0);
1122
1088
  rb_define_module_function(mOSSL, "fips_mode=", ossl_fips_mode_set, 1);
1123
1089
 
1124
1090
  rb_global_variable(&eOSSLError);
1125
1091
  /*
1126
- * Generic error,
1127
- * common for all classes under OpenSSL module
1092
+ * Generic error class for OpenSSL. All error classes in this library
1093
+ * inherit from this class.
1094
+ *
1095
+ * This class indicates that an error was reported by the underlying
1096
+ * \OpenSSL library.
1097
+ */
1098
+ eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError);
1099
+ /*
1100
+ * \OpenSSL error queue entries captured at the time the exception was
1101
+ * raised. The same information is printed to stderr if OpenSSL.debug is
1102
+ * set to +true+.
1103
+ *
1104
+ * This is an array of zero or more strings, ordered from the oldest to the
1105
+ * newest. The format of the strings is not stable and may vary across
1106
+ * versions of \OpenSSL or versions of this Ruby extension.
1107
+ *
1108
+ * See also the man page ERR_get_error(3).
1128
1109
  */
1129
- eOSSLError = rb_define_class_under(mOSSL,"OpenSSLError",rb_eStandardError);
1110
+ rb_attr(eOSSLError, rb_intern_const("errors"), 1, 0, 0);
1111
+ rb_define_method(eOSSLError, "detailed_message", osslerror_detailed_message, -1);
1130
1112
 
1131
1113
  /*
1132
1114
  * Init debug core
@@ -1142,10 +1124,7 @@ Init_openssl(void)
1142
1124
  * Get ID of to_der
1143
1125
  */
1144
1126
  ossl_s_to_der = rb_intern("to_der");
1145
-
1146
- #if !defined(HAVE_OPENSSL_110_THREADING_API)
1147
- Init_ossl_locks();
1148
- #endif
1127
+ id_i_errors = rb_intern("@errors");
1149
1128
 
1150
1129
  /*
1151
1130
  * Init components