openssl 2.1.1 → 2.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.md +9 -7
  3. data/History.md +165 -0
  4. data/README.md +2 -2
  5. data/ext/openssl/extconf.rb +51 -27
  6. data/ext/openssl/openssl_missing.h +39 -4
  7. data/ext/openssl/ossl.c +61 -27
  8. data/ext/openssl/ossl.h +8 -5
  9. data/ext/openssl/ossl_asn1.c +27 -1
  10. data/ext/openssl/ossl_bn.c +92 -24
  11. data/ext/openssl/ossl_bn.h +2 -1
  12. data/ext/openssl/ossl_cipher.c +33 -24
  13. data/ext/openssl/ossl_digest.c +22 -53
  14. data/ext/openssl/ossl_engine.c +2 -12
  15. data/ext/openssl/ossl_hmac.c +5 -11
  16. data/ext/openssl/ossl_kdf.c +3 -19
  17. data/ext/openssl/ossl_ns_spki.c +1 -1
  18. data/ext/openssl/ossl_ocsp.c +6 -11
  19. data/ext/openssl/ossl_ocsp.h +3 -3
  20. data/ext/openssl/ossl_pkcs12.c +1 -0
  21. data/ext/openssl/ossl_pkcs7.c +4 -19
  22. data/ext/openssl/ossl_pkcs7.h +16 -0
  23. data/ext/openssl/ossl_pkey.c +206 -17
  24. data/ext/openssl/ossl_pkey.h +6 -6
  25. data/ext/openssl/ossl_pkey_dh.c +1 -1
  26. data/ext/openssl/ossl_pkey_dsa.c +2 -2
  27. data/ext/openssl/ossl_pkey_ec.c +38 -8
  28. data/ext/openssl/ossl_pkey_rsa.c +17 -9
  29. data/ext/openssl/ossl_rand.c +2 -40
  30. data/ext/openssl/ossl_ssl.c +205 -75
  31. data/ext/openssl/ossl_ts.c +1524 -0
  32. data/ext/openssl/ossl_ts.h +16 -0
  33. data/ext/openssl/ossl_x509.c +91 -0
  34. data/ext/openssl/ossl_x509cert.c +2 -2
  35. data/ext/openssl/ossl_x509ext.c +15 -0
  36. data/ext/openssl/ossl_x509name.c +15 -10
  37. data/ext/openssl/ossl_x509store.c +40 -22
  38. data/lib/openssl/bn.rb +1 -1
  39. data/lib/openssl/buffering.rb +33 -17
  40. data/lib/openssl/cipher.rb +1 -1
  41. data/lib/openssl/config.rb +53 -26
  42. data/lib/openssl/digest.rb +10 -12
  43. data/lib/openssl/hmac.rb +13 -0
  44. data/lib/openssl/marshal.rb +30 -0
  45. data/lib/openssl/pkcs5.rb +1 -1
  46. data/lib/openssl/pkey.rb +18 -1
  47. data/lib/openssl/ssl.rb +46 -7
  48. data/lib/openssl/version.rb +5 -0
  49. data/lib/openssl/x509.rb +155 -1
  50. data/lib/openssl.rb +25 -9
  51. metadata +25 -9
  52. data/ext/openssl/deprecation.rb +0 -23
  53. data/ext/openssl/ossl_version.h +0 -15
@@ -0,0 +1,16 @@
1
+ /*
2
+ *
3
+ * Copyright (C) 2010 Martin Bosslet <Martin.Bosslet@googlemail.com>
4
+ * All rights reserved.
5
+ */
6
+ /*
7
+ * This program is licenced under the same licence as Ruby.
8
+ * (See the file 'LICENCE'.)
9
+ */
10
+
11
+ #if !defined(_OSSL_TS_H_)
12
+ #define _OSSL_TS_H_
13
+
14
+ void Init_ossl_ts(void);
15
+
16
+ #endif
@@ -44,7 +44,13 @@ Init_ossl_x509(void)
44
44
  Init_ossl_x509revoked();
45
45
  Init_ossl_x509store();
46
46
 
47
+ /* Constants are up-to-date with 1.1.1. */
48
+
49
+ /* Certificate verification error code */
47
50
  DefX509Const(V_OK);
51
+ #if defined(X509_V_ERR_UNSPECIFIED) /* 1.0.1r, 1.0.2f, 1.1.0 */
52
+ DefX509Const(V_ERR_UNSPECIFIED);
53
+ #endif
48
54
  DefX509Const(V_ERR_UNABLE_TO_GET_ISSUER_CERT);
49
55
  DefX509Const(V_ERR_UNABLE_TO_GET_CRL);
50
56
  DefX509Const(V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE);
@@ -76,8 +82,73 @@ Init_ossl_x509(void)
76
82
  DefX509Const(V_ERR_AKID_SKID_MISMATCH);
77
83
  DefX509Const(V_ERR_AKID_ISSUER_SERIAL_MISMATCH);
78
84
  DefX509Const(V_ERR_KEYUSAGE_NO_CERTSIGN);
85
+ DefX509Const(V_ERR_UNABLE_TO_GET_CRL_ISSUER);
86
+ DefX509Const(V_ERR_UNHANDLED_CRITICAL_EXTENSION);
87
+ DefX509Const(V_ERR_KEYUSAGE_NO_CRL_SIGN);
88
+ DefX509Const(V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION);
89
+ DefX509Const(V_ERR_INVALID_NON_CA);
90
+ DefX509Const(V_ERR_PROXY_PATH_LENGTH_EXCEEDED);
91
+ DefX509Const(V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE);
92
+ DefX509Const(V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED);
93
+ DefX509Const(V_ERR_INVALID_EXTENSION);
94
+ DefX509Const(V_ERR_INVALID_POLICY_EXTENSION);
95
+ DefX509Const(V_ERR_NO_EXPLICIT_POLICY);
96
+ DefX509Const(V_ERR_DIFFERENT_CRL_SCOPE);
97
+ DefX509Const(V_ERR_UNSUPPORTED_EXTENSION_FEATURE);
98
+ DefX509Const(V_ERR_UNNESTED_RESOURCE);
99
+ DefX509Const(V_ERR_PERMITTED_VIOLATION);
100
+ DefX509Const(V_ERR_EXCLUDED_VIOLATION);
101
+ DefX509Const(V_ERR_SUBTREE_MINMAX);
79
102
  DefX509Const(V_ERR_APPLICATION_VERIFICATION);
103
+ DefX509Const(V_ERR_UNSUPPORTED_CONSTRAINT_TYPE);
104
+ DefX509Const(V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX);
105
+ DefX509Const(V_ERR_UNSUPPORTED_NAME_SYNTAX);
106
+ DefX509Const(V_ERR_CRL_PATH_VALIDATION_ERROR);
107
+ #if defined(X509_V_ERR_PATH_LOOP)
108
+ DefX509Const(V_ERR_PATH_LOOP);
109
+ #endif
110
+ #if defined(X509_V_ERR_SUITE_B_INVALID_VERSION)
111
+ DefX509Const(V_ERR_SUITE_B_INVALID_VERSION);
112
+ DefX509Const(V_ERR_SUITE_B_INVALID_ALGORITHM);
113
+ DefX509Const(V_ERR_SUITE_B_INVALID_CURVE);
114
+ DefX509Const(V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM);
115
+ DefX509Const(V_ERR_SUITE_B_LOS_NOT_ALLOWED);
116
+ DefX509Const(V_ERR_SUITE_B_CANNOT_SIGN_P_384_WITH_P_256);
117
+ #endif
118
+ #if defined(X509_V_ERR_HOSTNAME_MISMATCH)
119
+ DefX509Const(V_ERR_HOSTNAME_MISMATCH);
120
+ DefX509Const(V_ERR_EMAIL_MISMATCH);
121
+ DefX509Const(V_ERR_IP_ADDRESS_MISMATCH);
122
+ #endif
123
+ #if defined(X509_V_ERR_DANE_NO_MATCH)
124
+ DefX509Const(V_ERR_DANE_NO_MATCH);
125
+ #endif
126
+ #if defined(X509_V_ERR_EE_KEY_TOO_SMALL)
127
+ DefX509Const(V_ERR_EE_KEY_TOO_SMALL);
128
+ DefX509Const(V_ERR_CA_KEY_TOO_SMALL);
129
+ DefX509Const(V_ERR_CA_MD_TOO_WEAK);
130
+ #endif
131
+ #if defined(X509_V_ERR_INVALID_CALL)
132
+ DefX509Const(V_ERR_INVALID_CALL);
133
+ #endif
134
+ #if defined(X509_V_ERR_STORE_LOOKUP)
135
+ DefX509Const(V_ERR_STORE_LOOKUP);
136
+ #endif
137
+ #if defined(X509_V_ERR_NO_VALID_SCTS)
138
+ DefX509Const(V_ERR_NO_VALID_SCTS);
139
+ #endif
140
+ #if defined(X509_V_ERR_PROXY_SUBJECT_NAME_VIOLATION)
141
+ DefX509Const(V_ERR_PROXY_SUBJECT_NAME_VIOLATION);
142
+ #endif
143
+ #if defined(X509_V_ERR_OCSP_VERIFY_NEEDED)
144
+ DefX509Const(V_ERR_OCSP_VERIFY_NEEDED);
145
+ DefX509Const(V_ERR_OCSP_VERIFY_FAILED);
146
+ DefX509Const(V_ERR_OCSP_CERT_UNKNOWN);
147
+ #endif
80
148
 
149
+ /* Certificate verify flags */
150
+ /* Set by Store#flags= and StoreContext#flags=. */
151
+ DefX509Const(V_FLAG_USE_CHECK_TIME);
81
152
  /* Set by Store#flags= and StoreContext#flags=. Enables CRL checking for the
82
153
  * certificate chain leaf. */
83
154
  DefX509Const(V_FLAG_CRL_CHECK);
@@ -122,6 +193,26 @@ Init_ossl_x509(void)
122
193
  * Enabled by default in OpenSSL >= 1.1.0. */
123
194
  DefX509Const(V_FLAG_TRUSTED_FIRST);
124
195
  #endif
196
+ #if defined(X509_V_FLAG_SUITEB_128_LOS_ONLY)
197
+ /* Set by Store#flags= and StoreContext#flags=.
198
+ * Enables Suite B 128 bit only mode. */
199
+ DefX509Const(V_FLAG_SUITEB_128_LOS_ONLY);
200
+ #endif
201
+ #if defined(X509_V_FLAG_SUITEB_192_LOS)
202
+ /* Set by Store#flags= and StoreContext#flags=.
203
+ * Enables Suite B 192 bit only mode. */
204
+ DefX509Const(V_FLAG_SUITEB_192_LOS);
205
+ #endif
206
+ #if defined(X509_V_FLAG_SUITEB_128_LOS)
207
+ /* Set by Store#flags= and StoreContext#flags=.
208
+ * Enables Suite B 128 bit mode allowing 192 bit algorithms. */
209
+ DefX509Const(V_FLAG_SUITEB_128_LOS);
210
+ #endif
211
+ #if defined(X509_V_FLAG_PARTIAL_CHAIN)
212
+ /* Set by Store#flags= and StoreContext#flags=.
213
+ * Allows partial chains if at least one certificate is in trusted store. */
214
+ DefX509Const(V_FLAG_PARTIAL_CHAIN);
215
+ #endif
125
216
  #if defined(X509_V_FLAG_NO_ALT_CHAINS)
126
217
  /* Set by Store#flags= and StoreContext#flags=. Suppresses searching for
127
218
  * a alternative chain. No effect in OpenSSL >= 1.1.0. */
@@ -788,7 +788,7 @@ Init_ossl_x509cert(void)
788
788
  * root_ca.add_extension(ef.create_extension("keyUsage","keyCertSign, cRLSign", true))
789
789
  * root_ca.add_extension(ef.create_extension("subjectKeyIdentifier","hash",false))
790
790
  * root_ca.add_extension(ef.create_extension("authorityKeyIdentifier","keyid:always",false))
791
- * root_ca.sign(root_key, OpenSSL::Digest::SHA256.new)
791
+ * root_ca.sign(root_key, OpenSSL::Digest.new('SHA256'))
792
792
  *
793
793
  * The next step is to create the end-entity certificate using the root CA
794
794
  * certificate.
@@ -807,7 +807,7 @@ Init_ossl_x509cert(void)
807
807
  * ef.issuer_certificate = root_ca
808
808
  * cert.add_extension(ef.create_extension("keyUsage","digitalSignature", true))
809
809
  * cert.add_extension(ef.create_extension("subjectKeyIdentifier","hash",false))
810
- * cert.sign(root_key, OpenSSL::Digest::SHA256.new)
810
+ * cert.sign(root_key, OpenSSL::Digest.new('SHA256'))
811
811
  *
812
812
  */
813
813
  cX509Cert = rb_define_class_under(mX509, "Certificate", rb_cObject);
@@ -402,6 +402,19 @@ ossl_x509ext_get_value(VALUE obj)
402
402
  return ret;
403
403
  }
404
404
 
405
+ static VALUE
406
+ ossl_x509ext_get_value_der(VALUE obj)
407
+ {
408
+ X509_EXTENSION *ext;
409
+ ASN1_OCTET_STRING *value;
410
+
411
+ GetX509Ext(obj, ext);
412
+ if ((value = X509_EXTENSION_get_data(ext)) == NULL)
413
+ ossl_raise(eX509ExtError, NULL);
414
+
415
+ return rb_str_new((const char *)value->data, value->length);
416
+ }
417
+
405
418
  static VALUE
406
419
  ossl_x509ext_get_critical(VALUE obj)
407
420
  {
@@ -437,6 +450,7 @@ ossl_x509ext_to_der(VALUE obj)
437
450
  void
438
451
  Init_ossl_x509ext(void)
439
452
  {
453
+ #undef rb_intern
440
454
  #if 0
441
455
  mOSSL = rb_define_module("OpenSSL");
442
456
  eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError);
@@ -471,6 +485,7 @@ Init_ossl_x509ext(void)
471
485
  rb_define_method(cX509Ext, "critical=", ossl_x509ext_set_critical, 1);
472
486
  rb_define_method(cX509Ext, "oid", ossl_x509ext_get_oid, 0);
473
487
  rb_define_method(cX509Ext, "value", ossl_x509ext_get_value, 0);
488
+ rb_define_method(cX509Ext, "value_der", ossl_x509ext_get_value_der, 0);
474
489
  rb_define_method(cX509Ext, "critical?", ossl_x509ext_get_critical, 0);
475
490
  rb_define_method(cX509Ext, "to_der", ossl_x509ext_to_der, 0);
476
491
  }
@@ -250,14 +250,12 @@ ossl_x509name_to_s_old(VALUE self)
250
250
  {
251
251
  X509_NAME *name;
252
252
  char *buf;
253
- VALUE str;
254
253
 
255
254
  GetX509Name(self, name);
256
255
  buf = X509_NAME_oneline(name, NULL, 0);
257
- str = rb_str_new2(buf);
258
- OPENSSL_free(buf);
259
-
260
- return str;
256
+ if (!buf)
257
+ ossl_raise(eX509NameError, "X509_NAME_oneline");
258
+ return ossl_buf2str(buf, rb_long2int(strlen(buf)));
261
259
  }
262
260
 
263
261
  static VALUE
@@ -265,12 +263,14 @@ x509name_print(VALUE self, unsigned long iflag)
265
263
  {
266
264
  X509_NAME *name;
267
265
  BIO *out;
266
+ int ret;
268
267
 
269
268
  GetX509Name(self, name);
270
269
  out = BIO_new(BIO_s_mem());
271
270
  if (!out)
272
271
  ossl_raise(eX509NameError, NULL);
273
- if (!X509_NAME_print_ex(out, name, 0, iflag)) {
272
+ ret = X509_NAME_print_ex(out, name, 0, iflag);
273
+ if (ret < 0 || (iflag == XN_FLAG_COMPAT && ret == 0)) {
274
274
  BIO_free(out);
275
275
  ossl_raise(eX509NameError, "X509_NAME_print_ex");
276
276
  }
@@ -387,20 +387,24 @@ ossl_x509name_cmp0(VALUE self, VALUE other)
387
387
 
388
388
  /*
389
389
  * call-seq:
390
- * name.cmp(other) -> -1 | 0 | 1
391
- * name <=> other -> -1 | 0 | 1
390
+ * name.cmp(other) -> -1 | 0 | 1 | nil
391
+ * name <=> other -> -1 | 0 | 1 | nil
392
392
  *
393
393
  * Compares this Name with _other_ and returns +0+ if they are the same and +-1+
394
394
  * or ++1+ if they are greater or less than each other respectively.
395
+ * Returns +nil+ if they are not comparable (i.e. different types).
395
396
  */
396
397
  static VALUE
397
398
  ossl_x509name_cmp(VALUE self, VALUE other)
398
399
  {
399
400
  int result;
400
401
 
402
+ if (!rb_obj_is_kind_of(other, cX509Name))
403
+ return Qnil;
404
+
401
405
  result = ossl_x509name_cmp0(self, other);
402
406
  if (result < 0) return INT2FIX(-1);
403
- if (result > 1) return INT2FIX(1);
407
+ if (result > 0) return INT2FIX(1);
404
408
 
405
409
  return INT2FIX(0);
406
410
  }
@@ -494,7 +498,7 @@ ossl_x509name_to_der(VALUE self)
494
498
  * You can create a Name by parsing a distinguished name String or by
495
499
  * supplying the distinguished name as an Array.
496
500
  *
497
- * name = OpenSSL::X509::Name.parse 'CN=nobody/DC=example'
501
+ * name = OpenSSL::X509::Name.parse '/CN=nobody/DC=example'
498
502
  *
499
503
  * name = OpenSSL::X509::Name.new [['CN', 'nobody'], ['DC', 'example']]
500
504
  */
@@ -502,6 +506,7 @@ ossl_x509name_to_der(VALUE self)
502
506
  void
503
507
  Init_ossl_x509name(void)
504
508
  {
509
+ #undef rb_intern
505
510
  VALUE utf8str, ptrstr, ia5str, hash;
506
511
 
507
512
  #if 0
@@ -105,6 +105,13 @@ VALUE cX509Store;
105
105
  VALUE cX509StoreContext;
106
106
  VALUE eX509StoreError;
107
107
 
108
+ static void
109
+ ossl_x509store_mark(void *ptr)
110
+ {
111
+ X509_STORE *store = ptr;
112
+ rb_gc_mark((VALUE)X509_STORE_get_ex_data(store, store_ex_verify_cb_idx));
113
+ }
114
+
108
115
  static void
109
116
  ossl_x509store_free(void *ptr)
110
117
  {
@@ -114,7 +121,7 @@ ossl_x509store_free(void *ptr)
114
121
  static const rb_data_type_t ossl_x509store_type = {
115
122
  "OpenSSL/X509/STORE",
116
123
  {
117
- 0, ossl_x509store_free,
124
+ ossl_x509store_mark, ossl_x509store_free,
118
125
  },
119
126
  0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
120
127
  };
@@ -304,7 +311,6 @@ ossl_x509store_add_file(VALUE self, VALUE file)
304
311
  char *path = NULL;
305
312
 
306
313
  if(file != Qnil){
307
- rb_check_safe_obj(file);
308
314
  path = StringValueCStr(file);
309
315
  }
310
316
  GetX509Store(self, store);
@@ -340,7 +346,6 @@ ossl_x509store_add_path(VALUE self, VALUE dir)
340
346
  char *path = NULL;
341
347
 
342
348
  if(dir != Qnil){
343
- rb_check_safe_obj(dir);
344
349
  path = StringValueCStr(dir);
345
350
  }
346
351
  GetX509Store(self, store);
@@ -458,23 +463,16 @@ ossl_x509store_verify(int argc, VALUE *argv, VALUE self)
458
463
  return result;
459
464
  }
460
465
 
461
- /*
462
- * Public Functions
463
- */
464
- static void ossl_x509stctx_free(void*);
465
-
466
-
467
- static const rb_data_type_t ossl_x509stctx_type = {
468
- "OpenSSL/X509/STORE_CTX",
469
- {
470
- 0, ossl_x509stctx_free,
471
- },
472
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
473
- };
474
-
475
466
  /*
476
467
  * Private functions
477
468
  */
469
+ static void
470
+ ossl_x509stctx_mark(void *ptr)
471
+ {
472
+ X509_STORE_CTX *ctx = ptr;
473
+ rb_gc_mark((VALUE)X509_STORE_CTX_get_ex_data(ctx, stctx_ex_verify_cb_idx));
474
+ }
475
+
478
476
  static void
479
477
  ossl_x509stctx_free(void *ptr)
480
478
  {
@@ -486,6 +484,14 @@ ossl_x509stctx_free(void *ptr)
486
484
  X509_STORE_CTX_free(ctx);
487
485
  }
488
486
 
487
+ static const rb_data_type_t ossl_x509stctx_type = {
488
+ "OpenSSL/X509/STORE_CTX",
489
+ {
490
+ ossl_x509stctx_mark, ossl_x509stctx_free,
491
+ },
492
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
493
+ };
494
+
489
495
  static VALUE
490
496
  ossl_x509stctx_alloc(VALUE klass)
491
497
  {
@@ -519,7 +525,9 @@ static VALUE ossl_x509stctx_set_time(VALUE, VALUE);
519
525
 
520
526
  /*
521
527
  * call-seq:
522
- * StoreContext.new(store, cert = nil, chain = nil)
528
+ * StoreContext.new(store, cert = nil, untrusted = nil)
529
+ *
530
+ * Sets up a StoreContext for a verification of the X.509 certificate _cert_.
523
531
  */
524
532
  static VALUE
525
533
  ossl_x509stctx_initialize(int argc, VALUE *argv, VALUE self)
@@ -529,15 +537,24 @@ ossl_x509stctx_initialize(int argc, VALUE *argv, VALUE self)
529
537
  X509_STORE *x509st;
530
538
  X509 *x509 = NULL;
531
539
  STACK_OF(X509) *x509s = NULL;
540
+ int state;
532
541
 
533
542
  rb_scan_args(argc, argv, "12", &store, &cert, &chain);
534
543
  GetX509StCtx(self, ctx);
535
544
  GetX509Store(store, x509st);
536
- if(!NIL_P(cert)) x509 = DupX509CertPtr(cert); /* NEED TO DUP */
537
- if(!NIL_P(chain)) x509s = ossl_x509_ary2sk(chain);
538
- if(X509_STORE_CTX_init(ctx, x509st, x509, x509s) != 1){
545
+ if (!NIL_P(cert))
546
+ x509 = DupX509CertPtr(cert); /* NEED TO DUP */
547
+ if (!NIL_P(chain)) {
548
+ x509s = ossl_protect_x509_ary2sk(chain, &state);
549
+ if (state) {
550
+ X509_free(x509);
551
+ rb_jump_tag(state);
552
+ }
553
+ }
554
+ if (X509_STORE_CTX_init(ctx, x509st, x509, x509s) != 1){
555
+ X509_free(x509);
539
556
  sk_X509_pop_free(x509s, X509_free);
540
- ossl_raise(eX509StoreError, NULL);
557
+ ossl_raise(eX509StoreError, "X509_STORE_CTX_init");
541
558
  }
542
559
  if (!NIL_P(t = rb_iv_get(store, "@time")))
543
560
  ossl_x509stctx_set_time(self, t);
@@ -771,6 +788,7 @@ ossl_x509stctx_set_time(VALUE self, VALUE time)
771
788
  void
772
789
  Init_ossl_x509store(void)
773
790
  {
791
+ #undef rb_intern
774
792
  #if 0
775
793
  mOSSL = rb_define_module("OpenSSL");
776
794
  eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError);
data/lib/openssl/bn.rb CHANGED
@@ -1,4 +1,4 @@
1
- # frozen_string_literal: false
1
+ # frozen_string_literal: true
2
2
  #--
3
3
  #
4
4
  # = Ruby-space definitions that completes C-space funcs for BN
@@ -1,5 +1,5 @@
1
1
  # coding: binary
2
- # frozen_string_literal: false
2
+ # frozen_string_literal: true
3
3
  #--
4
4
  #= Info
5
5
  # 'OpenSSL for Ruby 2' project
@@ -22,6 +22,29 @@
22
22
  module OpenSSL::Buffering
23
23
  include Enumerable
24
24
 
25
+ # A buffer which will retain binary encoding.
26
+ class Buffer < String
27
+ BINARY = Encoding::BINARY
28
+
29
+ def initialize
30
+ super
31
+
32
+ force_encoding(BINARY)
33
+ end
34
+
35
+ def << string
36
+ if string.encoding == BINARY
37
+ super(string)
38
+ else
39
+ super(string.b)
40
+ end
41
+
42
+ return self
43
+ end
44
+
45
+ alias concat <<
46
+ end
47
+
25
48
  ##
26
49
  # The "sync mode" of the SSLSocket.
27
50
  #
@@ -40,7 +63,7 @@ module OpenSSL::Buffering
40
63
  def initialize(*)
41
64
  super
42
65
  @eof = false
43
- @rbuffer = ""
66
+ @rbuffer = Buffer.new
44
67
  @sync = @io.sync
45
68
  end
46
69
 
@@ -312,24 +335,19 @@ module OpenSSL::Buffering
312
335
  # buffer is flushed to the underlying socket.
313
336
 
314
337
  def do_write(s)
315
- @wbuffer = "" unless defined? @wbuffer
338
+ @wbuffer = Buffer.new unless defined? @wbuffer
316
339
  @wbuffer << s
317
340
  @wbuffer.force_encoding(Encoding::BINARY)
318
341
  @sync ||= false
319
- if @sync or @wbuffer.size > BLOCK_SIZE or idx = @wbuffer.rindex($/)
320
- remain = idx ? idx + $/.size : @wbuffer.length
321
- nwritten = 0
322
- while remain > 0
323
- str = @wbuffer[nwritten,remain]
342
+ if @sync or @wbuffer.size > BLOCK_SIZE
343
+ until @wbuffer.empty?
324
344
  begin
325
- nwrote = syswrite(str)
345
+ nwrote = syswrite(@wbuffer)
326
346
  rescue Errno::EAGAIN
327
347
  retry
328
348
  end
329
- remain -= nwrote
330
- nwritten += nwrote
349
+ @wbuffer[0, nwrote] = ""
331
350
  end
332
- @wbuffer[0,nwritten] = ""
333
351
  end
334
352
  end
335
353
 
@@ -403,15 +421,13 @@ module OpenSSL::Buffering
403
421
  # See IO#puts for full details.
404
422
 
405
423
  def puts(*args)
406
- s = ""
424
+ s = Buffer.new
407
425
  if args.empty?
408
426
  s << "\n"
409
427
  end
410
428
  args.each{|arg|
411
429
  s << arg.to_s
412
- if $/ && /\n\z/ !~ s
413
- s << "\n"
414
- end
430
+ s.sub!(/(?<!\n)\z/, "\n")
415
431
  }
416
432
  do_write(s)
417
433
  nil
@@ -423,7 +439,7 @@ module OpenSSL::Buffering
423
439
  # See IO#print for full details.
424
440
 
425
441
  def print(*args)
426
- s = ""
442
+ s = Buffer.new
427
443
  args.each{ |arg| s << arg.to_s }
428
444
  do_write(s)
429
445
  nil
@@ -1,4 +1,4 @@
1
- # frozen_string_literal: false
1
+ # frozen_string_literal: true
2
2
  #--
3
3
  # = Ruby-space predefined Cipher subclasses
4
4
  #
@@ -1,4 +1,4 @@
1
- # frozen_string_literal: false
1
+ # frozen_string_literal: true
2
2
  =begin
3
3
  = Ruby-space definitions that completes C-space funcs for Config
4
4
 
@@ -37,7 +37,7 @@ module OpenSSL
37
37
  def parse(string)
38
38
  c = new()
39
39
  parse_config(StringIO.new(string)).each do |section, hash|
40
- c[section] = hash
40
+ c.set_section(section, hash)
41
41
  end
42
42
  c
43
43
  end
@@ -53,9 +53,8 @@ module OpenSSL
53
53
  def parse_config(io)
54
54
  begin
55
55
  parse_config_lines(io)
56
- rescue ConfigError => e
57
- e.message.replace("error in line #{io.lineno}: " + e.message)
58
- raise
56
+ rescue => error
57
+ raise ConfigError, "error in line #{io.lineno}: " + error.message
59
58
  end
60
59
  end
61
60
 
@@ -77,29 +76,44 @@ module OpenSSL
77
76
  def parse_config_lines(io)
78
77
  section = 'default'
79
78
  data = {section => {}}
80
- while definition = get_definition(io)
79
+ io_stack = [io]
80
+ while definition = get_definition(io_stack)
81
81
  definition = clear_comments(definition)
82
82
  next if definition.empty?
83
- if definition[0] == ?[
83
+ case definition
84
+ when /\A\[/
84
85
  if /\[([^\]]*)\]/ =~ definition
85
86
  section = $1.strip
86
87
  data[section] ||= {}
87
88
  else
88
89
  raise ConfigError, "missing close square bracket"
89
90
  end
90
- else
91
- if /\A([^:\s]*)(?:::([^:\s]*))?\s*=(.*)\z/ =~ definition
92
- if $2
93
- section = $1
94
- key = $2
95
- else
96
- key = $1
91
+ when /\A\.include (\s*=\s*)?(.+)\z/
92
+ path = $2
93
+ if File.directory?(path)
94
+ files = Dir.glob(File.join(path, "*.{cnf,conf}"), File::FNM_EXTGLOB)
95
+ else
96
+ files = [path]
97
+ end
98
+
99
+ files.each do |filename|
100
+ begin
101
+ io_stack << StringIO.new(File.read(filename))
102
+ rescue
103
+ raise ConfigError, "could not include file '%s'" % filename
97
104
  end
98
- value = unescape_value(data, section, $3)
99
- (data[section] ||= {})[key] = value.strip
105
+ end
106
+ when /\A([^:\s]*)(?:::([^:\s]*))?\s*=(.*)\z/
107
+ if $2
108
+ section = $1
109
+ key = $2
100
110
  else
101
- raise ConfigError, "missing equal sign"
111
+ key = $1
102
112
  end
113
+ value = unescape_value(data, section, $3)
114
+ (data[section] ||= {})[key] = value.strip
115
+ else
116
+ raise ConfigError, "missing equal sign"
103
117
  end
104
118
  end
105
119
  data
@@ -212,10 +226,10 @@ module OpenSSL
212
226
  scanned.join
213
227
  end
214
228
 
215
- def get_definition(io)
216
- if line = get_line(io)
229
+ def get_definition(io_stack)
230
+ if line = get_line(io_stack)
217
231
  while /[^\\]\\\z/ =~ line
218
- if extra = get_line(io)
232
+ if extra = get_line(io_stack)
219
233
  line += extra
220
234
  else
221
235
  break
@@ -225,9 +239,12 @@ module OpenSSL
225
239
  end
226
240
  end
227
241
 
228
- def get_line(io)
229
- if line = io.gets
230
- line.gsub(/[\r\n]*/, '')
242
+ def get_line(io_stack)
243
+ while io = io_stack.last
244
+ if line = io.gets
245
+ return line.gsub(/[\r\n]*/, '')
246
+ end
247
+ io_stack.pop
231
248
  end
232
249
  end
233
250
  end
@@ -249,7 +266,7 @@ module OpenSSL
249
266
  if filename
250
267
  File.open(filename.to_s) do |file|
251
268
  Config.parse_config(file).each do |section, hash|
252
- self[section] = hash
269
+ set_section(section, hash)
253
270
  end
254
271
  end
255
272
  end
@@ -298,6 +315,8 @@ module OpenSSL
298
315
  end
299
316
 
300
317
  ##
318
+ # *Deprecated in v2.2.0*. This method will be removed in a future release.
319
+ #
301
320
  # Set the target _key_ with a given _value_ under a specific _section_.
302
321
  #
303
322
  # Given the following configurating file being loaded:
@@ -352,6 +371,8 @@ module OpenSSL
352
371
  end
353
372
 
354
373
  ##
374
+ # *Deprecated in v2.2.0*. This method will be removed in a future release.
375
+ #
355
376
  # Sets a specific _section_ name with a Hash _pairs_.
356
377
  #
357
378
  # Given the following configuration being created:
@@ -377,9 +398,13 @@ module OpenSSL
377
398
  #
378
399
  def []=(section, pairs)
379
400
  check_modify
380
- @data[section] ||= {}
401
+ set_section(section, pairs)
402
+ end
403
+
404
+ def set_section(section, pairs) # :nodoc:
405
+ hash = @data[section] ||= {}
381
406
  pairs.each do |key, value|
382
- self.add_value(section, key, value)
407
+ hash[key] = value
383
408
  end
384
409
  end
385
410
 
@@ -464,6 +489,8 @@ module OpenSSL
464
489
  end
465
490
 
466
491
  def check_modify
492
+ warn "#{caller(2, 1)[0]}: warning: do not modify OpenSSL::Config; this " \
493
+ "method is deprecated and will be removed in a future release."
467
494
  raise TypeError.new("Insecure: can't modify OpenSSL config") if frozen?
468
495
  end
469
496