openssl 2.1.3 → 3.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.md +35 -45
  3. data/History.md +266 -1
  4. data/README.md +2 -2
  5. data/ext/openssl/extconf.rb +46 -38
  6. data/ext/openssl/openssl_missing.c +0 -66
  7. data/ext/openssl/openssl_missing.h +59 -43
  8. data/ext/openssl/ossl.c +110 -64
  9. data/ext/openssl/ossl.h +27 -10
  10. data/ext/openssl/ossl_asn1.c +41 -4
  11. data/ext/openssl/ossl_bn.c +251 -134
  12. data/ext/openssl/ossl_bn.h +2 -1
  13. data/ext/openssl/ossl_cipher.c +38 -29
  14. data/ext/openssl/ossl_config.c +412 -41
  15. data/ext/openssl/ossl_config.h +4 -7
  16. data/ext/openssl/ossl_digest.c +25 -60
  17. data/ext/openssl/ossl_engine.c +18 -27
  18. data/ext/openssl/ossl_hmac.c +60 -145
  19. data/ext/openssl/ossl_kdf.c +11 -19
  20. data/ext/openssl/ossl_ns_spki.c +1 -1
  21. data/ext/openssl/ossl_ocsp.c +9 -62
  22. data/ext/openssl/ossl_ocsp.h +3 -3
  23. data/ext/openssl/ossl_pkcs12.c +21 -3
  24. data/ext/openssl/ossl_pkcs7.c +45 -78
  25. data/ext/openssl/ossl_pkcs7.h +16 -0
  26. data/ext/openssl/ossl_pkey.c +1295 -178
  27. data/ext/openssl/ossl_pkey.h +35 -72
  28. data/ext/openssl/ossl_pkey_dh.c +124 -334
  29. data/ext/openssl/ossl_pkey_dsa.c +93 -398
  30. data/ext/openssl/ossl_pkey_ec.c +186 -329
  31. data/ext/openssl/ossl_pkey_rsa.c +105 -484
  32. data/ext/openssl/ossl_rand.c +2 -32
  33. data/ext/openssl/ossl_ssl.c +347 -394
  34. data/ext/openssl/ossl_ssl_session.c +24 -29
  35. data/ext/openssl/ossl_ts.c +1539 -0
  36. data/ext/openssl/ossl_ts.h +16 -0
  37. data/ext/openssl/ossl_x509.c +0 -6
  38. data/ext/openssl/ossl_x509cert.c +169 -13
  39. data/ext/openssl/ossl_x509crl.c +13 -10
  40. data/ext/openssl/ossl_x509ext.c +15 -2
  41. data/ext/openssl/ossl_x509name.c +15 -4
  42. data/ext/openssl/ossl_x509req.c +13 -10
  43. data/ext/openssl/ossl_x509revoked.c +3 -3
  44. data/ext/openssl/ossl_x509store.c +154 -70
  45. data/lib/openssl/bn.rb +1 -1
  46. data/lib/openssl/buffering.rb +37 -5
  47. data/lib/openssl/cipher.rb +1 -1
  48. data/lib/openssl/digest.rb +10 -12
  49. data/lib/openssl/hmac.rb +78 -0
  50. data/lib/openssl/marshal.rb +30 -0
  51. data/lib/openssl/pkcs5.rb +1 -1
  52. data/lib/openssl/pkey.rb +443 -1
  53. data/lib/openssl/ssl.rb +47 -9
  54. data/lib/openssl/version.rb +5 -0
  55. data/lib/openssl/x509.rb +177 -1
  56. data/lib/openssl.rb +24 -9
  57. metadata +10 -79
  58. data/ext/openssl/deprecation.rb +0 -27
  59. data/ext/openssl/ossl_version.h +0 -15
  60. data/ext/openssl/ruby_missing.h +0 -24
  61. data/lib/openssl/config.rb +0 -492
@@ -12,40 +12,7 @@
12
12
 
13
13
  #include "ruby/config.h"
14
14
 
15
- /* added in 1.0.2 */
16
- #if !defined(OPENSSL_NO_EC)
17
- #if !defined(HAVE_EC_CURVE_NIST2NID)
18
- int ossl_EC_curve_nist2nid(const char *);
19
- # define EC_curve_nist2nid ossl_EC_curve_nist2nid
20
- #endif
21
- #endif
22
-
23
- #if !defined(HAVE_X509_REVOKED_DUP)
24
- # define X509_REVOKED_dup(rev) (X509_REVOKED *)ASN1_dup((i2d_of_void *)i2d_X509_REVOKED, \
25
- (d2i_of_void *)d2i_X509_REVOKED, (char *)(rev))
26
- #endif
27
-
28
- #if !defined(HAVE_X509_STORE_CTX_GET0_STORE)
29
- # define X509_STORE_CTX_get0_store(x) ((x)->ctx)
30
- #endif
31
-
32
- #if !defined(HAVE_SSL_IS_SERVER)
33
- # define SSL_is_server(s) ((s)->server)
34
- #endif
35
-
36
15
  /* added in 1.1.0 */
37
- #if !defined(HAVE_BN_GENCB_NEW)
38
- # define BN_GENCB_new() ((BN_GENCB *)OPENSSL_malloc(sizeof(BN_GENCB)))
39
- #endif
40
-
41
- #if !defined(HAVE_BN_GENCB_FREE)
42
- # define BN_GENCB_free(cb) OPENSSL_free(cb)
43
- #endif
44
-
45
- #if !defined(HAVE_BN_GENCB_GET_ARG)
46
- # define BN_GENCB_get_arg(cb) (cb)->arg
47
- #endif
48
-
49
16
  #if !defined(HAVE_EVP_MD_CTX_NEW)
50
17
  # define EVP_MD_CTX_new EVP_MD_CTX_create
51
18
  #endif
@@ -54,16 +21,6 @@ int ossl_EC_curve_nist2nid(const char *);
54
21
  # define EVP_MD_CTX_free EVP_MD_CTX_destroy
55
22
  #endif
56
23
 
57
- #if !defined(HAVE_HMAC_CTX_NEW)
58
- HMAC_CTX *ossl_HMAC_CTX_new(void);
59
- # define HMAC_CTX_new ossl_HMAC_CTX_new
60
- #endif
61
-
62
- #if !defined(HAVE_HMAC_CTX_FREE)
63
- void ossl_HMAC_CTX_free(HMAC_CTX *);
64
- # define HMAC_CTX_free ossl_HMAC_CTX_free
65
- #endif
66
-
67
24
  #if !defined(HAVE_X509_STORE_GET_EX_DATA)
68
25
  # define X509_STORE_get_ex_data(x, idx) \
69
26
  CRYPTO_get_ex_data(&(x)->ex_data, (idx))
@@ -72,6 +29,9 @@ void ossl_HMAC_CTX_free(HMAC_CTX *);
72
29
  #if !defined(HAVE_X509_STORE_SET_EX_DATA)
73
30
  # define X509_STORE_set_ex_data(x, idx, data) \
74
31
  CRYPTO_set_ex_data(&(x)->ex_data, (idx), (data))
32
+ #endif
33
+
34
+ #if !defined(HAVE_X509_STORE_GET_EX_NEW_INDEX) && !defined(X509_STORE_get_ex_new_index)
75
35
  # define X509_STORE_get_ex_new_index(l, p, newf, dupf, freef) \
76
36
  CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_X509_STORE, (l), (p), \
77
37
  (newf), (dupf), (freef))
@@ -219,4 +179,60 @@ IMPL_PKEY_GETTER(EC_KEY, ec)
219
179
  # define SSL_SESSION_get_protocol_version(s) ((s)->ssl_version)
220
180
  #endif
221
181
 
182
+ #if !defined(HAVE_TS_STATUS_INFO_GET0_STATUS)
183
+ # define TS_STATUS_INFO_get0_status(a) ((a)->status)
184
+ #endif
185
+
186
+ #if !defined(HAVE_TS_STATUS_INFO_GET0_TEXT)
187
+ # define TS_STATUS_INFO_get0_text(a) ((a)->text)
188
+ #endif
189
+
190
+ #if !defined(HAVE_TS_STATUS_INFO_GET0_FAILURE_INFO)
191
+ # define TS_STATUS_INFO_get0_failure_info(a) ((a)->failure_info)
192
+ #endif
193
+
194
+ #if !defined(HAVE_TS_VERIFY_CTS_SET_CERTS)
195
+ # define TS_VERIFY_CTS_set_certs(ctx, crts) ((ctx)->certs=(crts))
196
+ #endif
197
+
198
+ #if !defined(HAVE_TS_VERIFY_CTX_SET_STORE)
199
+ # define TS_VERIFY_CTX_set_store(ctx, str) ((ctx)->store=(str))
200
+ #endif
201
+
202
+ #if !defined(HAVE_TS_VERIFY_CTX_ADD_FLAGS)
203
+ # define TS_VERIFY_CTX_add_flags(ctx, f) ((ctx)->flags |= (f))
204
+ #endif
205
+
206
+ #if !defined(HAVE_TS_RESP_CTX_SET_TIME_CB)
207
+ # define TS_RESP_CTX_set_time_cb(ctx, callback, dta) do { \
208
+ (ctx)->time_cb = (callback); \
209
+ (ctx)->time_cb_data = (dta); \
210
+ } while (0)
211
+ #endif
212
+
213
+ /* added in 3.0.0 */
214
+ #if !defined(HAVE_TS_VERIFY_CTX_SET_CERTS)
215
+ # define TS_VERIFY_CTX_set_certs(ctx, crts) TS_VERIFY_CTS_set_certs(ctx, crts)
216
+ #endif
217
+
218
+ #ifndef HAVE_EVP_MD_CTX_GET0_MD
219
+ # define EVP_MD_CTX_get0_md(ctx) EVP_MD_CTX_md(ctx)
220
+ #endif
221
+
222
+ /*
223
+ * OpenSSL 1.1.0 added EVP_MD_CTX_pkey_ctx(), and then it was renamed to
224
+ * EVP_MD_CTX_get_pkey_ctx(x) in OpenSSL 3.0.
225
+ */
226
+ #ifndef HAVE_EVP_MD_CTX_GET_PKEY_CTX
227
+ # ifdef HAVE_EVP_MD_CTX_PKEY_CTX
228
+ # define EVP_MD_CTX_get_pkey_ctx(x) EVP_MD_CTX_pkey_ctx(x)
229
+ # else
230
+ # define EVP_MD_CTX_get_pkey_ctx(x) (x)->pctx
231
+ # endif
232
+ #endif
233
+
234
+ #ifndef HAVE_EVP_PKEY_EQ
235
+ # define EVP_PKEY_eq(a, b) EVP_PKEY_cmp(a, b)
236
+ #endif
237
+
222
238
  #endif /* _OSSL_OPENSSL_MISSING_H_ */
data/ext/openssl/ossl.c CHANGED
@@ -9,13 +9,19 @@
9
9
  */
10
10
  #include "ossl.h"
11
11
  #include <stdarg.h> /* for ossl_raise */
12
- #include <ruby/thread_native.h> /* for OpenSSL < 1.1.0 locks */
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
13
19
 
14
20
  /*
15
21
  * Data Conversion
16
22
  */
17
23
  #define OSSL_IMPL_ARY2SK(name, type, expected_class, dup) \
18
- STACK_OF(type) * \
24
+ VALUE \
19
25
  ossl_##name##_ary2sk0(VALUE ary) \
20
26
  { \
21
27
  STACK_OF(type) *sk; \
@@ -37,7 +43,7 @@ ossl_##name##_ary2sk0(VALUE ary) \
37
43
  x = dup(val); /* NEED TO DUP */ \
38
44
  sk_##type##_push(sk, x); \
39
45
  } \
40
- return sk; \
46
+ return (VALUE)sk; \
41
47
  } \
42
48
  \
43
49
  STACK_OF(type) * \
@@ -262,15 +268,11 @@ ossl_to_der_if_possible(VALUE obj)
262
268
  /*
263
269
  * Errors
264
270
  */
265
- static VALUE
266
- ossl_make_error(VALUE exc, const char *fmt, va_list args)
271
+ VALUE
272
+ ossl_make_error(VALUE exc, VALUE str)
267
273
  {
268
- VALUE str = Qnil;
269
274
  unsigned long e;
270
275
 
271
- if (fmt) {
272
- str = rb_vsprintf(fmt, args);
273
- }
274
276
  e = ERR_peek_last_error();
275
277
  if (e) {
276
278
  const char *msg = ERR_reason_error_string(e);
@@ -294,37 +296,48 @@ ossl_raise(VALUE exc, const char *fmt, ...)
294
296
  {
295
297
  va_list args;
296
298
  VALUE err;
297
- va_start(args, fmt);
298
- err = ossl_make_error(exc, fmt, args);
299
- va_end(args);
300
- rb_exc_raise(err);
299
+
300
+ if (fmt) {
301
+ va_start(args, fmt);
302
+ err = rb_vsprintf(fmt, args);
303
+ va_end(args);
304
+ }
305
+ else {
306
+ err = Qnil;
307
+ }
308
+
309
+ rb_exc_raise(ossl_make_error(exc, err));
301
310
  }
302
311
 
303
312
  void
304
313
  ossl_clear_error(void)
305
314
  {
306
315
  if (dOSSL == Qtrue) {
307
- unsigned long e;
308
- const char *file, *data, *errstr;
309
- int line, flags;
310
-
311
- while ((e = ERR_get_error_line_data(&file, &line, &data, &flags))) {
312
- errstr = ERR_error_string(e, NULL);
313
- if (!errstr)
314
- errstr = "(null)";
315
-
316
- if (flags & ERR_TXT_STRING) {
317
- if (!data)
318
- data = "(null)";
319
- rb_warn("error on stack: %s (%s)", errstr, data);
320
- }
321
- else {
322
- rb_warn("error on stack: %s", errstr);
323
- }
324
- }
316
+ unsigned long e;
317
+ const char *file, *data, *func, *lib, *reason;
318
+ char append[256] = "";
319
+ int line, flags;
320
+
321
+ #ifdef HAVE_ERR_GET_ERROR_ALL
322
+ while ((e = ERR_get_error_all(&file, &line, &func, &data, &flags))) {
323
+ #else
324
+ while ((e = ERR_get_error_line_data(&file, &line, &data, &flags))) {
325
+ func = ERR_func_error_string(e);
326
+ #endif
327
+ lib = ERR_lib_error_string(e);
328
+ reason = ERR_reason_error_string(e);
329
+
330
+ if (flags & ERR_TXT_STRING) {
331
+ if (!data)
332
+ data = "(null)";
333
+ snprintf(append, sizeof(append), " (%s)", data);
334
+ }
335
+ rb_warn("error on stack: error:%08lX:%s:%s:%s%s", e, lib ? lib : "",
336
+ func ? func : "", reason ? reason : "", append);
337
+ }
325
338
  }
326
339
  else {
327
- ERR_clear_error();
340
+ ERR_clear_error();
328
341
  }
329
342
  }
330
343
 
@@ -386,7 +399,7 @@ ossl_debug_get(VALUE self)
386
399
  * call-seq:
387
400
  * OpenSSL.debug = boolean -> boolean
388
401
  *
389
- * Turns on or off debug mode. With debug mode, all erros added to the OpenSSL
402
+ * Turns on or off debug mode. With debug mode, all errors added to the OpenSSL
390
403
  * error queue will be printed to stderr.
391
404
  */
392
405
  static VALUE
@@ -497,8 +510,11 @@ print_mem_leaks(VALUE self)
497
510
  int ret;
498
511
  #endif
499
512
 
500
- BN_CTX_free(ossl_bn_ctx);
501
- ossl_bn_ctx = NULL;
513
+ #ifndef HAVE_RB_EXT_RACTOR_SAFE
514
+ // for Ruby 2.x
515
+ void ossl_bn_ctx_free(void); // ossl_bn.c
516
+ ossl_bn_ctx_free();
517
+ #endif
502
518
 
503
519
  #if OPENSSL_VERSION_NUMBER >= 0x10100000
504
520
  ret = CRYPTO_mem_leaks_fp(stderr);
@@ -604,6 +620,35 @@ static void Init_ossl_locks(void)
604
620
  }
605
621
  #endif /* !HAVE_OPENSSL_110_THREADING_API */
606
622
 
623
+ /*
624
+ * call-seq:
625
+ * OpenSSL.fixed_length_secure_compare(string, string) -> boolean
626
+ *
627
+ * Constant time memory comparison for fixed length strings, such as results
628
+ * of HMAC calculations.
629
+ *
630
+ * Returns +true+ if the strings are identical, +false+ if they are of the same
631
+ * length but not identical. If the length is different, +ArgumentError+ is
632
+ * raised.
633
+ */
634
+ static VALUE
635
+ ossl_crypto_fixed_length_secure_compare(VALUE dummy, VALUE str1, VALUE str2)
636
+ {
637
+ const unsigned char *p1 = (const unsigned char *)StringValuePtr(str1);
638
+ const unsigned char *p2 = (const unsigned char *)StringValuePtr(str2);
639
+ long len1 = RSTRING_LEN(str1);
640
+ long len2 = RSTRING_LEN(str2);
641
+
642
+ if (len1 != len2) {
643
+ ossl_raise(rb_eArgError, "inputs must be of equal length");
644
+ }
645
+
646
+ switch (CRYPTO_memcmp(p1, p2, len1)) {
647
+ case 0: return Qtrue;
648
+ default: return Qfalse;
649
+ }
650
+ }
651
+
607
652
  /*
608
653
  * OpenSSL provides SSL, TLS and general purpose cryptography. It wraps the
609
654
  * OpenSSL[https://www.openssl.org/] library.
@@ -635,7 +680,7 @@ static void Init_ossl_locks(void)
635
680
  * ahold of the key may use it unless it is encrypted. In order to securely
636
681
  * export a key you may export it with a pass phrase.
637
682
  *
638
- * cipher = OpenSSL::Cipher.new 'AES-128-CBC'
683
+ * cipher = OpenSSL::Cipher.new 'aes-256-cbc'
639
684
  * pass_phrase = 'my secure pass phrase goes here'
640
685
  *
641
686
  * key_secure = key.export cipher, pass_phrase
@@ -650,13 +695,13 @@ static void Init_ossl_locks(void)
650
695
  *
651
696
  * A key can also be loaded from a file.
652
697
  *
653
- * key2 = OpenSSL::PKey::RSA.new File.read 'private_key.pem'
698
+ * key2 = OpenSSL::PKey.read File.read 'private_key.pem'
654
699
  * key2.public? # => true
655
700
  * key2.private? # => true
656
701
  *
657
702
  * or
658
703
  *
659
- * key3 = OpenSSL::PKey::RSA.new File.read 'public_key.pem'
704
+ * key3 = OpenSSL::PKey.read File.read 'public_key.pem'
660
705
  * key3.public? # => true
661
706
  * key3.private? # => false
662
707
  *
@@ -668,7 +713,7 @@ static void Init_ossl_locks(void)
668
713
  *
669
714
  * key4_pem = File.read 'private.secure.pem'
670
715
  * pass_phrase = 'my secure pass phrase goes here'
671
- * key4 = OpenSSL::PKey::RSA.new key4_pem, pass_phrase
716
+ * key4 = OpenSSL::PKey.read key4_pem, pass_phrase
672
717
  *
673
718
  * == RSA Encryption
674
719
  *
@@ -710,16 +755,14 @@ static void Init_ossl_locks(void)
710
755
  * To sign a document, a cryptographically secure hash of the document is
711
756
  * computed first, which is then signed using the private key.
712
757
  *
713
- * digest = OpenSSL::Digest::SHA256.new
714
- * signature = key.sign digest, document
758
+ * signature = key.sign 'SHA256', document
715
759
  *
716
760
  * To validate the signature, again a hash of the document is computed and
717
761
  * the signature is decrypted using the public key. The result is then
718
762
  * compared to the hash just computed, if they are equal the signature was
719
763
  * valid.
720
764
  *
721
- * digest = OpenSSL::Digest::SHA256.new
722
- * if key.verify digest, signature, document
765
+ * if key.verify 'SHA256', signature, document
723
766
  * puts 'Valid'
724
767
  * else
725
768
  * puts 'Invalid'
@@ -745,7 +788,7 @@ static void Init_ossl_locks(void)
745
788
  * using PBKDF2. PKCS #5 v2.0 recommends at least 8 bytes for the salt,
746
789
  * the number of iterations largely depends on the hardware being used.
747
790
  *
748
- * cipher = OpenSSL::Cipher.new 'AES-128-CBC'
791
+ * cipher = OpenSSL::Cipher.new 'aes-256-cbc'
749
792
  * cipher.encrypt
750
793
  * iv = cipher.random_iv
751
794
  *
@@ -753,7 +796,7 @@ static void Init_ossl_locks(void)
753
796
  * salt = OpenSSL::Random.random_bytes 16
754
797
  * iter = 20000
755
798
  * key_len = cipher.key_len
756
- * digest = OpenSSL::Digest::SHA256.new
799
+ * digest = OpenSSL::Digest.new('SHA256')
757
800
  *
758
801
  * key = OpenSSL::PKCS5.pbkdf2_hmac(pwd, salt, iter, key_len, digest)
759
802
  * cipher.key = key
@@ -768,7 +811,7 @@ static void Init_ossl_locks(void)
768
811
  * Use the same steps as before to derive the symmetric AES key, this time
769
812
  * setting the Cipher up for decryption.
770
813
  *
771
- * cipher = OpenSSL::Cipher.new 'AES-128-CBC'
814
+ * cipher = OpenSSL::Cipher.new 'aes-256-cbc'
772
815
  * cipher.decrypt
773
816
  * cipher.iv = iv # the one generated with #random_iv
774
817
  *
@@ -776,7 +819,7 @@ static void Init_ossl_locks(void)
776
819
  * salt = ... # the one generated above
777
820
  * iter = 20000
778
821
  * key_len = cipher.key_len
779
- * digest = OpenSSL::Digest::SHA256.new
822
+ * digest = OpenSSL::Digest.new('SHA256')
780
823
  *
781
824
  * key = OpenSSL::PKCS5.pbkdf2_hmac(pwd, salt, iter, key_len, digest)
782
825
  * cipher.key = key
@@ -803,7 +846,7 @@ static void Init_ossl_locks(void)
803
846
  *
804
847
  * First set up the cipher for encryption
805
848
  *
806
- * encryptor = OpenSSL::Cipher.new 'AES-128-CBC'
849
+ * encryptor = OpenSSL::Cipher.new 'aes-256-cbc'
807
850
  * encryptor.encrypt
808
851
  * encryptor.pkcs5_keyivgen pass_phrase, salt
809
852
  *
@@ -816,7 +859,7 @@ static void Init_ossl_locks(void)
816
859
  *
817
860
  * Use a new Cipher instance set up for decryption
818
861
  *
819
- * decryptor = OpenSSL::Cipher.new 'AES-128-CBC'
862
+ * decryptor = OpenSSL::Cipher.new 'aes-256-cbc'
820
863
  * decryptor.decrypt
821
864
  * decryptor.pkcs5_keyivgen pass_phrase, salt
822
865
  *
@@ -833,7 +876,7 @@ static void Init_ossl_locks(void)
833
876
  * signature.
834
877
  *
835
878
  * key = OpenSSL::PKey::RSA.new 2048
836
- * name = OpenSSL::X509::Name.parse 'CN=nobody/DC=example'
879
+ * name = OpenSSL::X509::Name.parse '/CN=nobody/DC=example'
837
880
  *
838
881
  * cert = OpenSSL::X509::Certificate.new
839
882
  * cert.version = 2
@@ -872,7 +915,7 @@ static void Init_ossl_locks(void)
872
915
  * certificate.
873
916
  *
874
917
  * cert.issuer = name
875
- * cert.sign key, OpenSSL::Digest::SHA1.new
918
+ * cert.sign key, OpenSSL::Digest.new('SHA1')
876
919
  *
877
920
  * open 'certificate.pem', 'w' do |io| io.write cert.to_pem end
878
921
  *
@@ -904,7 +947,7 @@ static void Init_ossl_locks(void)
904
947
  * ca_key = OpenSSL::PKey::RSA.new 2048
905
948
  * pass_phrase = 'my secure pass phrase goes here'
906
949
  *
907
- * cipher = OpenSSL::Cipher.new 'AES-128-CBC'
950
+ * cipher = OpenSSL::Cipher.new 'aes-256-cbc'
908
951
  *
909
952
  * open 'ca_key.pem', 'w', 0400 do |io|
910
953
  * io.write ca_key.export(cipher, pass_phrase)
@@ -915,7 +958,7 @@ static void Init_ossl_locks(void)
915
958
  * A CA certificate is created the same way we created a certificate above, but
916
959
  * with different extensions.
917
960
  *
918
- * ca_name = OpenSSL::X509::Name.parse 'CN=ca/DC=example'
961
+ * ca_name = OpenSSL::X509::Name.parse '/CN=ca/DC=example'
919
962
  *
920
963
  * ca_cert = OpenSSL::X509::Certificate.new
921
964
  * ca_cert.serial = 0
@@ -948,7 +991,7 @@ static void Init_ossl_locks(void)
948
991
  *
949
992
  * Root CA certificates are self-signed.
950
993
  *
951
- * ca_cert.sign ca_key, OpenSSL::Digest::SHA1.new
994
+ * ca_cert.sign ca_key, OpenSSL::Digest.new('SHA1')
952
995
  *
953
996
  * The CA certificate is saved to disk so it may be distributed to all the
954
997
  * users of the keys this CA will sign.
@@ -966,7 +1009,7 @@ static void Init_ossl_locks(void)
966
1009
  * csr.version = 0
967
1010
  * csr.subject = name
968
1011
  * csr.public_key = key.public_key
969
- * csr.sign key, OpenSSL::Digest::SHA1.new
1012
+ * csr.sign key, OpenSSL::Digest.new('SHA1')
970
1013
  *
971
1014
  * A CSR is saved to disk and sent to the CA for signing.
972
1015
  *
@@ -1010,7 +1053,7 @@ static void Init_ossl_locks(void)
1010
1053
  * csr_cert.add_extension \
1011
1054
  * extension_factory.create_extension('subjectKeyIdentifier', 'hash')
1012
1055
  *
1013
- * csr_cert.sign ca_key, OpenSSL::Digest::SHA1.new
1056
+ * csr_cert.sign ca_key, OpenSSL::Digest.new('SHA1')
1014
1057
  *
1015
1058
  * open 'csr_cert.pem', 'w' do |io|
1016
1059
  * io.write csr_cert.to_pem
@@ -1042,13 +1085,13 @@ static void Init_ossl_locks(void)
1042
1085
  * loop do
1043
1086
  * ssl_connection = ssl_server.accept
1044
1087
  *
1045
- * data = connection.gets
1088
+ * data = ssl_connection.gets
1046
1089
  *
1047
1090
  * response = "I got #{data.dump}"
1048
1091
  * puts response
1049
1092
  *
1050
- * connection.puts "I got #{data.dump}"
1051
- * connection.close
1093
+ * ssl_connection.puts "I got #{data.dump}"
1094
+ * ssl_connection.close
1052
1095
  * end
1053
1096
  *
1054
1097
  * === SSL client
@@ -1099,6 +1142,10 @@ static void Init_ossl_locks(void)
1099
1142
  void
1100
1143
  Init_openssl(void)
1101
1144
  {
1145
+ #ifdef HAVE_RB_EXT_RACTOR_SAFE
1146
+ rb_ext_ractor_safe(true);
1147
+ #endif
1148
+
1102
1149
  #undef rb_intern
1103
1150
  /*
1104
1151
  * Init timezone info
@@ -1125,11 +1172,7 @@ Init_openssl(void)
1125
1172
  */
1126
1173
  mOSSL = rb_define_module("OpenSSL");
1127
1174
  rb_global_variable(&mOSSL);
1128
-
1129
- /*
1130
- * OpenSSL ruby extension version
1131
- */
1132
- rb_define_const(mOSSL, "VERSION", rb_str_new2(OSSL_VERSION));
1175
+ rb_define_singleton_method(mOSSL, "fixed_length_secure_compare", ossl_crypto_fixed_length_secure_compare, 2);
1133
1176
 
1134
1177
  /*
1135
1178
  * Version of OpenSSL the ruby OpenSSL extension was built with
@@ -1205,6 +1248,9 @@ Init_openssl(void)
1205
1248
  Init_ossl_pkey();
1206
1249
  Init_ossl_rand();
1207
1250
  Init_ossl_ssl();
1251
+ #ifndef OPENSSL_NO_TS
1252
+ Init_ossl_ts();
1253
+ #endif
1208
1254
  Init_ossl_x509();
1209
1255
  Init_ossl_ocsp();
1210
1256
  Init_ossl_engine();
data/ext/openssl/ossl.h CHANGED
@@ -18,20 +18,19 @@
18
18
  #include <ruby/io.h>
19
19
  #include <ruby/thread.h>
20
20
  #include <openssl/opensslv.h>
21
+
21
22
  #include <openssl/err.h>
22
23
  #include <openssl/asn1.h>
23
24
  #include <openssl/x509v3.h>
24
25
  #include <openssl/ssl.h>
25
26
  #include <openssl/pkcs12.h>
26
27
  #include <openssl/pkcs7.h>
27
- #include <openssl/hmac.h>
28
28
  #include <openssl/rand.h>
29
29
  #include <openssl/conf.h>
30
- #include <openssl/conf_api.h>
31
- #include <openssl/crypto.h>
32
- #if !defined(OPENSSL_NO_ENGINE)
33
- # include <openssl/engine.h>
30
+ #ifndef OPENSSL_NO_TS
31
+ #include <openssl/ts.h>
34
32
  #endif
33
+ #include <openssl/crypto.h>
35
34
  #if !defined(OPENSSL_NO_OCSP)
36
35
  # include <openssl/ocsp.h>
37
36
  #endif
@@ -41,6 +40,22 @@
41
40
  #include <openssl/evp.h>
42
41
  #include <openssl/dh.h>
43
42
 
43
+ #ifndef LIBRESSL_VERSION_NUMBER
44
+ # define OSSL_IS_LIBRESSL 0
45
+ # define OSSL_OPENSSL_PREREQ(maj, min, pat) \
46
+ (OPENSSL_VERSION_NUMBER >= ((maj << 28) | (min << 20) | (pat << 12)))
47
+ # define OSSL_LIBRESSL_PREREQ(maj, min, pat) 0
48
+ #else
49
+ # define OSSL_IS_LIBRESSL 1
50
+ # define OSSL_OPENSSL_PREREQ(maj, min, pat) 0
51
+ # define OSSL_LIBRESSL_PREREQ(maj, min, pat) \
52
+ (LIBRESSL_VERSION_NUMBER >= ((maj << 28) | (min << 20) | (pat << 12)))
53
+ #endif
54
+
55
+ #if !defined(OPENSSL_NO_ENGINE) && !OSSL_OPENSSL_PREREQ(3, 0, 0)
56
+ # define OSSL_USE_ENGINE
57
+ #endif
58
+
44
59
  /*
45
60
  * Common Module
46
61
  */
@@ -86,9 +101,8 @@ VALUE ossl_buf2str(char *buf, int len);
86
101
  VALUE ossl_str_new(const char *, long, int *);
87
102
  #define ossl_str_adjust(str, p) \
88
103
  do{\
89
- long len = RSTRING_LEN(str);\
90
104
  long newlen = (long)((p) - (unsigned char*)RSTRING_PTR(str));\
91
- assert(newlen <= len);\
105
+ assert(newlen <= RSTRING_LEN(str));\
92
106
  rb_str_set_len((str), newlen);\
93
107
  }while(0)
94
108
  /*
@@ -120,7 +134,9 @@ int ossl_pem_passwd_cb(char *, int, int, void *);
120
134
  /*
121
135
  * ERRor messages
122
136
  */
123
- NORETURN(void ossl_raise(VALUE, const char *, ...));
137
+ PRINTF_ARGS(NORETURN(void ossl_raise(VALUE, const char *, ...)), 2, 3);
138
+ /* Make exception instance from str and OpenSSL error reason string. */
139
+ VALUE ossl_make_error(VALUE exc, VALUE str);
124
140
  /* Clear OpenSSL error queue. If dOSSL is set, rb_warn() them. */
125
141
  void ossl_clear_error(void);
126
142
 
@@ -153,7 +169,6 @@ void ossl_debug(const char *, ...);
153
169
  * Include all parts
154
170
  */
155
171
  #include "openssl_missing.h"
156
- #include "ruby_missing.h"
157
172
  #include "ossl_asn1.h"
158
173
  #include "ossl_bio.h"
159
174
  #include "ossl_bn.h"
@@ -168,7 +183,9 @@ void ossl_debug(const char *, ...);
168
183
  #include "ossl_pkey.h"
169
184
  #include "ossl_rand.h"
170
185
  #include "ossl_ssl.h"
171
- #include "ossl_version.h"
186
+ #ifndef OPENSSL_NO_TS
187
+ #include "ossl_ts.h"
188
+ #endif
172
189
  #include "ossl_x509.h"
173
190
  #include "ossl_engine.h"
174
191
  #include "ossl_kdf.h"
@@ -69,6 +69,12 @@ asn1time_to_time(const ASN1_TIME *time)
69
69
  return rb_funcall2(rb_cTime, rb_intern("utc"), 6, argv);
70
70
  }
71
71
 
72
+ static VALUE
73
+ asn1time_to_time_i(VALUE arg)
74
+ {
75
+ return asn1time_to_time((ASN1_TIME *)arg);
76
+ }
77
+
72
78
  void
73
79
  ossl_time_split(VALUE time, time_t *sec, int *days)
74
80
  {
@@ -136,6 +142,12 @@ num_to_asn1integer(VALUE obj, ASN1_INTEGER *ai)
136
142
  return ai;
137
143
  }
138
144
 
145
+ static VALUE
146
+ asn1integer_to_num_i(VALUE arg)
147
+ {
148
+ return asn1integer_to_num((ASN1_INTEGER *)arg);
149
+ }
150
+
139
151
  /********/
140
152
  /*
141
153
  * ASN1 module
@@ -325,7 +337,7 @@ decode_int(unsigned char* der, long length)
325
337
  p = der;
326
338
  if(!(ai = d2i_ASN1_INTEGER(NULL, &p, length)))
327
339
  ossl_raise(eASN1Error, NULL);
328
- ret = rb_protect((VALUE (*)(VALUE))asn1integer_to_num,
340
+ ret = rb_protect(asn1integer_to_num_i,
329
341
  (VALUE)ai, &status);
330
342
  ASN1_INTEGER_free(ai);
331
343
  if(status) rb_jump_tag(status);
@@ -365,7 +377,7 @@ decode_enum(unsigned char* der, long length)
365
377
  p = der;
366
378
  if(!(ai = d2i_ASN1_ENUMERATED(NULL, &p, length)))
367
379
  ossl_raise(eASN1Error, NULL);
368
- ret = rb_protect((VALUE (*)(VALUE))asn1integer_to_num,
380
+ ret = rb_protect(asn1integer_to_num_i,
369
381
  (VALUE)ai, &status);
370
382
  ASN1_ENUMERATED_free(ai);
371
383
  if(status) rb_jump_tag(status);
@@ -427,7 +439,7 @@ decode_time(unsigned char* der, long length)
427
439
  p = der;
428
440
  if(!(time = d2i_ASN1_TIME(NULL, &p, length)))
429
441
  ossl_raise(eASN1Error, NULL);
430
- ret = rb_protect((VALUE (*)(VALUE))asn1time_to_time,
442
+ ret = rb_protect(asn1time_to_time_i,
431
443
  (VALUE)time, &status);
432
444
  ASN1_TIME_free(time);
433
445
  if(status) rb_jump_tag(status);
@@ -1285,6 +1297,30 @@ ossl_asn1obj_get_ln(VALUE self)
1285
1297
  return ret;
1286
1298
  }
1287
1299
 
1300
+ /*
1301
+ * call-seq:
1302
+ * oid == other_oid => true or false
1303
+ *
1304
+ * Returns +true+ if _other_oid_ is the same as _oid_
1305
+ */
1306
+ static VALUE
1307
+ ossl_asn1obj_eq(VALUE self, VALUE other)
1308
+ {
1309
+ VALUE valSelf, valOther;
1310
+ int nidSelf, nidOther;
1311
+
1312
+ valSelf = ossl_asn1_get_value(self);
1313
+ valOther = ossl_asn1_get_value(other);
1314
+
1315
+ if ((nidSelf = OBJ_txt2nid(StringValueCStr(valSelf))) == NID_undef)
1316
+ ossl_raise(eASN1Error, "OBJ_txt2nid");
1317
+
1318
+ if ((nidOther = OBJ_txt2nid(StringValueCStr(valOther))) == NID_undef)
1319
+ ossl_raise(eASN1Error, "OBJ_txt2nid");
1320
+
1321
+ return nidSelf == nidOther ? Qtrue : Qfalse;
1322
+ }
1323
+
1288
1324
  static VALUE
1289
1325
  asn1obj_get_oid_i(VALUE vobj)
1290
1326
  {
@@ -1486,7 +1522,7 @@ Init_ossl_asn1(void)
1486
1522
  *
1487
1523
  * An Array that stores the name of a given tag number. These names are
1488
1524
  * the same as the name of the tag constant that is additionally defined,
1489
- * e.g. UNIVERSAL_TAG_NAME[2] = "INTEGER" and OpenSSL::ASN1::INTEGER = 2.
1525
+ * e.g. +UNIVERSAL_TAG_NAME[2] = "INTEGER"+ and +OpenSSL::ASN1::INTEGER = 2+.
1490
1526
  *
1491
1527
  * == Example usage
1492
1528
  *
@@ -1818,6 +1854,7 @@ do{\
1818
1854
  rb_define_method(cASN1ObjectId, "oid", ossl_asn1obj_get_oid, 0);
1819
1855
  rb_define_alias(cASN1ObjectId, "short_name", "sn");
1820
1856
  rb_define_alias(cASN1ObjectId, "long_name", "ln");
1857
+ rb_define_method(cASN1ObjectId, "==", ossl_asn1obj_eq, 1);
1821
1858
  rb_attr(cASN1BitString, rb_intern("unused_bits"), 1, 1, 0);
1822
1859
 
1823
1860
  rb_define_method(cASN1EndOfContent, "initialize", ossl_asn1eoc_initialize, 0);