openssl 2.2.2 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.md +32 -44
  3. data/History.md +99 -13
  4. data/ext/openssl/extconf.rb +26 -28
  5. data/ext/openssl/openssl_missing.c +0 -66
  6. data/ext/openssl/openssl_missing.h +26 -45
  7. data/ext/openssl/ossl.c +59 -46
  8. data/ext/openssl/ossl.h +20 -6
  9. data/ext/openssl/ossl_asn1.c +16 -4
  10. data/ext/openssl/ossl_bn.c +188 -126
  11. data/ext/openssl/ossl_cipher.c +11 -11
  12. data/ext/openssl/ossl_config.c +412 -41
  13. data/ext/openssl/ossl_config.h +4 -7
  14. data/ext/openssl/ossl_digest.c +9 -9
  15. data/ext/openssl/ossl_engine.c +16 -15
  16. data/ext/openssl/ossl_hmac.c +48 -135
  17. data/ext/openssl/ossl_kdf.c +8 -0
  18. data/ext/openssl/ossl_ocsp.c +3 -51
  19. data/ext/openssl/ossl_pkcs12.c +21 -3
  20. data/ext/openssl/ossl_pkcs7.c +42 -59
  21. data/ext/openssl/ossl_pkey.c +1102 -191
  22. data/ext/openssl/ossl_pkey.h +35 -72
  23. data/ext/openssl/ossl_pkey_dh.c +124 -334
  24. data/ext/openssl/ossl_pkey_dsa.c +93 -398
  25. data/ext/openssl/ossl_pkey_ec.c +126 -318
  26. data/ext/openssl/ossl_pkey_rsa.c +100 -487
  27. data/ext/openssl/ossl_ssl.c +256 -355
  28. data/ext/openssl/ossl_ssl_session.c +24 -29
  29. data/ext/openssl/ossl_ts.c +35 -20
  30. data/ext/openssl/ossl_x509.c +0 -6
  31. data/ext/openssl/ossl_x509cert.c +164 -8
  32. data/ext/openssl/ossl_x509crl.c +10 -7
  33. data/ext/openssl/ossl_x509ext.c +1 -2
  34. data/ext/openssl/ossl_x509name.c +9 -2
  35. data/ext/openssl/ossl_x509req.c +10 -7
  36. data/ext/openssl/ossl_x509store.c +154 -70
  37. data/lib/openssl/buffering.rb +9 -0
  38. data/lib/openssl/hmac.rb +65 -0
  39. data/lib/openssl/pkey.rb +417 -0
  40. data/lib/openssl/ssl.rb +7 -7
  41. data/lib/openssl/version.rb +1 -1
  42. data/lib/openssl/x509.rb +22 -0
  43. data/lib/openssl.rb +0 -1
  44. metadata +5 -77
  45. data/ext/openssl/ruby_missing.h +0 -24
  46. data/lib/openssl/config.rb +0 -501
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
@@ -667,7 +680,7 @@ ossl_crypto_fixed_length_secure_compare(VALUE dummy, VALUE str1, VALUE str2)
667
680
  * ahold of the key may use it unless it is encrypted. In order to securely
668
681
  * export a key you may export it with a pass phrase.
669
682
  *
670
- * cipher = OpenSSL::Cipher.new 'AES-256-CBC'
683
+ * cipher = OpenSSL::Cipher.new 'aes-256-cbc'
671
684
  * pass_phrase = 'my secure pass phrase goes here'
672
685
  *
673
686
  * key_secure = key.export cipher, pass_phrase
@@ -682,13 +695,13 @@ ossl_crypto_fixed_length_secure_compare(VALUE dummy, VALUE str1, VALUE str2)
682
695
  *
683
696
  * A key can also be loaded from a file.
684
697
  *
685
- * key2 = OpenSSL::PKey::RSA.new File.read 'private_key.pem'
698
+ * key2 = OpenSSL::PKey.read File.read 'private_key.pem'
686
699
  * key2.public? # => true
687
700
  * key2.private? # => true
688
701
  *
689
702
  * or
690
703
  *
691
- * key3 = OpenSSL::PKey::RSA.new File.read 'public_key.pem'
704
+ * key3 = OpenSSL::PKey.read File.read 'public_key.pem'
692
705
  * key3.public? # => true
693
706
  * key3.private? # => false
694
707
  *
@@ -700,7 +713,7 @@ ossl_crypto_fixed_length_secure_compare(VALUE dummy, VALUE str1, VALUE str2)
700
713
  *
701
714
  * key4_pem = File.read 'private.secure.pem'
702
715
  * pass_phrase = 'my secure pass phrase goes here'
703
- * key4 = OpenSSL::PKey::RSA.new key4_pem, pass_phrase
716
+ * key4 = OpenSSL::PKey.read key4_pem, pass_phrase
704
717
  *
705
718
  * == RSA Encryption
706
719
  *
@@ -775,7 +788,7 @@ ossl_crypto_fixed_length_secure_compare(VALUE dummy, VALUE str1, VALUE str2)
775
788
  * using PBKDF2. PKCS #5 v2.0 recommends at least 8 bytes for the salt,
776
789
  * the number of iterations largely depends on the hardware being used.
777
790
  *
778
- * cipher = OpenSSL::Cipher.new 'AES-256-CBC'
791
+ * cipher = OpenSSL::Cipher.new 'aes-256-cbc'
779
792
  * cipher.encrypt
780
793
  * iv = cipher.random_iv
781
794
  *
@@ -798,7 +811,7 @@ ossl_crypto_fixed_length_secure_compare(VALUE dummy, VALUE str1, VALUE str2)
798
811
  * Use the same steps as before to derive the symmetric AES key, this time
799
812
  * setting the Cipher up for decryption.
800
813
  *
801
- * cipher = OpenSSL::Cipher.new 'AES-256-CBC'
814
+ * cipher = OpenSSL::Cipher.new 'aes-256-cbc'
802
815
  * cipher.decrypt
803
816
  * cipher.iv = iv # the one generated with #random_iv
804
817
  *
@@ -833,7 +846,7 @@ ossl_crypto_fixed_length_secure_compare(VALUE dummy, VALUE str1, VALUE str2)
833
846
  *
834
847
  * First set up the cipher for encryption
835
848
  *
836
- * encryptor = OpenSSL::Cipher.new 'AES-256-CBC'
849
+ * encryptor = OpenSSL::Cipher.new 'aes-256-cbc'
837
850
  * encryptor.encrypt
838
851
  * encryptor.pkcs5_keyivgen pass_phrase, salt
839
852
  *
@@ -846,7 +859,7 @@ ossl_crypto_fixed_length_secure_compare(VALUE dummy, VALUE str1, VALUE str2)
846
859
  *
847
860
  * Use a new Cipher instance set up for decryption
848
861
  *
849
- * decryptor = OpenSSL::Cipher.new 'AES-256-CBC'
862
+ * decryptor = OpenSSL::Cipher.new 'aes-256-cbc'
850
863
  * decryptor.decrypt
851
864
  * decryptor.pkcs5_keyivgen pass_phrase, salt
852
865
  *
@@ -934,7 +947,7 @@ ossl_crypto_fixed_length_secure_compare(VALUE dummy, VALUE str1, VALUE str2)
934
947
  * ca_key = OpenSSL::PKey::RSA.new 2048
935
948
  * pass_phrase = 'my secure pass phrase goes here'
936
949
  *
937
- * cipher = OpenSSL::Cipher.new 'AES-256-CBC'
950
+ * cipher = OpenSSL::Cipher.new 'aes-256-cbc'
938
951
  *
939
952
  * open 'ca_key.pem', 'w', 0400 do |io|
940
953
  * io.write ca_key.export(cipher, pass_phrase)
@@ -1072,13 +1085,13 @@ ossl_crypto_fixed_length_secure_compare(VALUE dummy, VALUE str1, VALUE str2)
1072
1085
  * loop do
1073
1086
  * ssl_connection = ssl_server.accept
1074
1087
  *
1075
- * data = connection.gets
1088
+ * data = ssl_connection.gets
1076
1089
  *
1077
1090
  * response = "I got #{data.dump}"
1078
1091
  * puts response
1079
1092
  *
1080
- * connection.puts "I got #{data.dump}"
1081
- * connection.close
1093
+ * ssl_connection.puts "I got #{data.dump}"
1094
+ * ssl_connection.close
1082
1095
  * end
1083
1096
  *
1084
1097
  * === SSL client
@@ -1129,7 +1142,7 @@ ossl_crypto_fixed_length_secure_compare(VALUE dummy, VALUE str1, VALUE str2)
1129
1142
  void
1130
1143
  Init_openssl(void)
1131
1144
  {
1132
- #if HAVE_RB_EXT_RACTOR_SAFE
1145
+ #ifdef HAVE_RB_EXT_RACTOR_SAFE
1133
1146
  rb_ext_ractor_safe(true);
1134
1147
  #endif
1135
1148
 
data/ext/openssl/ossl.h CHANGED
@@ -18,22 +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
30
  #ifndef OPENSSL_NO_TS
31
31
  #include <openssl/ts.h>
32
32
  #endif
33
33
  #include <openssl/crypto.h>
34
- #if !defined(OPENSSL_NO_ENGINE)
35
- # include <openssl/engine.h>
36
- #endif
37
34
  #if !defined(OPENSSL_NO_OCSP)
38
35
  # include <openssl/ocsp.h>
39
36
  #endif
@@ -43,6 +40,22 @@
43
40
  #include <openssl/evp.h>
44
41
  #include <openssl/dh.h>
45
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
+
46
59
  /*
47
60
  * Common Module
48
61
  */
@@ -121,7 +134,9 @@ int ossl_pem_passwd_cb(char *, int, int, void *);
121
134
  /*
122
135
  * ERRor messages
123
136
  */
124
- 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);
125
140
  /* Clear OpenSSL error queue. If dOSSL is set, rb_warn() them. */
126
141
  void ossl_clear_error(void);
127
142
 
@@ -154,7 +169,6 @@ void ossl_debug(const char *, ...);
154
169
  * Include all parts
155
170
  */
156
171
  #include "openssl_missing.h"
157
- #include "ruby_missing.h"
158
172
  #include "ossl_asn1.h"
159
173
  #include "ossl_bio.h"
160
174
  #include "ossl_bn.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);
@@ -1510,7 +1522,7 @@ Init_ossl_asn1(void)
1510
1522
  *
1511
1523
  * An Array that stores the name of a given tag number. These names are
1512
1524
  * the same as the name of the tag constant that is additionally defined,
1513
- * 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+.
1514
1526
  *
1515
1527
  * == Example usage
1516
1528
  *