openssl 2.2.1 → 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 +103 -1
  4. data/ext/openssl/extconf.rb +24 -26
  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 +4 -76
  45. data/ext/openssl/ruby_missing.h +0 -24
  46. data/lib/openssl/config.rb +0 -501
@@ -34,43 +34,38 @@ static VALUE ossl_ssl_session_alloc(VALUE klass)
34
34
  * Creates a new Session object from an instance of SSLSocket or DER/PEM encoded
35
35
  * String.
36
36
  */
37
- static VALUE ossl_ssl_session_initialize(VALUE self, VALUE arg1)
37
+ static VALUE
38
+ ossl_ssl_session_initialize(VALUE self, VALUE arg1)
38
39
  {
39
- SSL_SESSION *ctx = NULL;
40
-
41
- if (RDATA(self)->data)
42
- ossl_raise(eSSLSession, "SSL Session already initialized");
43
-
44
- if (rb_obj_is_instance_of(arg1, cSSLSocket)) {
45
- SSL *ssl;
46
-
47
- GetSSL(arg1, ssl);
48
-
49
- if ((ctx = SSL_get1_session(ssl)) == NULL)
50
- ossl_raise(eSSLSession, "no session available");
51
- } else {
52
- BIO *in = ossl_obj2bio(&arg1);
40
+ SSL_SESSION *ctx;
53
41
 
54
- ctx = PEM_read_bio_SSL_SESSION(in, NULL, NULL, NULL);
42
+ if (RTYPEDDATA_DATA(self))
43
+ ossl_raise(eSSLSession, "SSL Session already initialized");
55
44
 
56
- if (!ctx) {
57
- OSSL_BIO_reset(in);
58
- ctx = d2i_SSL_SESSION_bio(in, NULL);
59
- }
45
+ if (rb_obj_is_instance_of(arg1, cSSLSocket)) {
46
+ SSL *ssl;
60
47
 
61
- BIO_free(in);
48
+ GetSSL(arg1, ssl);
62
49
 
63
- if (!ctx)
64
- ossl_raise(rb_eArgError, "unknown type");
65
- }
50
+ if ((ctx = SSL_get1_session(ssl)) == NULL)
51
+ ossl_raise(eSSLSession, "no session available");
52
+ }
53
+ else {
54
+ BIO *in = ossl_obj2bio(&arg1);
66
55
 
67
- /* should not happen */
68
- if (ctx == NULL)
69
- ossl_raise(eSSLSession, "ctx not set - internal error");
56
+ ctx = d2i_SSL_SESSION_bio(in, NULL);
57
+ if (!ctx) {
58
+ OSSL_BIO_reset(in);
59
+ ctx = PEM_read_bio_SSL_SESSION(in, NULL, NULL, NULL);
60
+ }
61
+ BIO_free(in);
62
+ if (!ctx)
63
+ ossl_raise(rb_eArgError, "unknown type");
64
+ }
70
65
 
71
- RDATA(self)->data = ctx;
66
+ RTYPEDDATA_DATA(self) = ctx;
72
67
 
73
- return self;
68
+ return self;
74
69
  }
75
70
 
76
71
  static VALUE
@@ -145,6 +145,12 @@ obj_to_asn1obj(VALUE obj)
145
145
  return a1obj;
146
146
  }
147
147
 
148
+ static VALUE
149
+ obj_to_asn1obj_i(VALUE obj)
150
+ {
151
+ return (VALUE)obj_to_asn1obj(obj);
152
+ }
153
+
148
154
  static VALUE
149
155
  get_asn1obj(ASN1_OBJECT *obj)
150
156
  {
@@ -820,17 +826,14 @@ ossl_ts_resp_verify(int argc, VALUE *argv, VALUE self)
820
826
  X509_up_ref(cert);
821
827
  }
822
828
 
823
- TS_VERIFY_CTS_set_certs(ctx, x509inter);
829
+ TS_VERIFY_CTX_set_certs(ctx, x509inter);
824
830
  TS_VERIFY_CTX_add_flags(ctx, TS_VFY_SIGNATURE);
825
831
  TS_VERIFY_CTX_set_store(ctx, x509st);
826
832
 
827
833
  ok = TS_RESP_verify_response(ctx, resp);
828
-
829
- /* WORKAROUND:
830
- * X509_STORE can count references, but X509_STORE_free() doesn't check
831
- * this. To prevent our X509_STORE from being freed with our
832
- * TS_VERIFY_CTX we set the store to NULL first.
833
- * Fixed in OpenSSL 1.0.2; bff9ce4db38b (master), 5b4b9ce976fc (1.0.2)
834
+ /*
835
+ * TS_VERIFY_CTX_set_store() call above does not increment the reference
836
+ * counter, so it must be unset before TS_VERIFY_CTX_free() is called.
834
837
  */
835
838
  TS_VERIFY_CTX_set_store(ctx, NULL);
836
839
  TS_VERIFY_CTX_free(ctx);
@@ -1091,6 +1094,18 @@ ossl_tsfac_time_cb(struct TS_resp_ctx *ctx, void *data, time_t *sec, long *usec)
1091
1094
  return 1;
1092
1095
  }
1093
1096
 
1097
+ static VALUE
1098
+ ossl_evp_get_digestbyname_i(VALUE arg)
1099
+ {
1100
+ return (VALUE)ossl_evp_get_digestbyname(arg);
1101
+ }
1102
+
1103
+ static VALUE
1104
+ ossl_obj2bio_i(VALUE arg)
1105
+ {
1106
+ return (VALUE)ossl_obj2bio((VALUE *)arg);
1107
+ }
1108
+
1094
1109
  /*
1095
1110
  * Creates a Response with the help of an OpenSSL::PKey, an
1096
1111
  * OpenSSL::X509::Certificate and a Request.
@@ -1159,7 +1174,7 @@ ossl_tsfac_create_ts(VALUE self, VALUE key, VALUE certificate, VALUE request)
1159
1174
  goto end;
1160
1175
  }
1161
1176
  if (!NIL_P(def_policy_id) && !TS_REQ_get_policy_id(req)) {
1162
- def_policy_id_obj = (ASN1_OBJECT*)rb_protect((VALUE (*)(VALUE))obj_to_asn1obj, (VALUE)def_policy_id, &status);
1177
+ def_policy_id_obj = (ASN1_OBJECT*)rb_protect(obj_to_asn1obj_i, (VALUE)def_policy_id, &status);
1163
1178
  if (status)
1164
1179
  goto end;
1165
1180
  }
@@ -1201,7 +1216,7 @@ ossl_tsfac_create_ts(VALUE self, VALUE key, VALUE certificate, VALUE request)
1201
1216
 
1202
1217
  for (i = 0; i < RARRAY_LEN(allowed_digests); i++) {
1203
1218
  rbmd = rb_ary_entry(allowed_digests, i);
1204
- md = (const EVP_MD *)rb_protect((VALUE (*)(VALUE))ossl_evp_get_digestbyname, rbmd, &status);
1219
+ md = (const EVP_MD *)rb_protect(ossl_evp_get_digestbyname_i, rbmd, &status);
1205
1220
  if (status)
1206
1221
  goto end;
1207
1222
  TS_RESP_CTX_add_md(ctx, md);
@@ -1212,7 +1227,7 @@ ossl_tsfac_create_ts(VALUE self, VALUE key, VALUE certificate, VALUE request)
1212
1227
  if (status)
1213
1228
  goto end;
1214
1229
 
1215
- req_bio = (BIO*)rb_protect((VALUE (*)(VALUE))ossl_obj2bio, (VALUE)&str, &status);
1230
+ req_bio = (BIO*)rb_protect(ossl_obj2bio_i, (VALUE)&str, &status);
1216
1231
  if (status)
1217
1232
  goto end;
1218
1233
 
@@ -1236,7 +1251,7 @@ end:
1236
1251
  ASN1_OBJECT_free(def_policy_id_obj);
1237
1252
  TS_RESP_CTX_free(ctx);
1238
1253
  if (err_msg)
1239
- ossl_raise(eTimestampError, err_msg);
1254
+ rb_exc_raise(ossl_make_error(eTimestampError, rb_str_new_cstr(err_msg)));
1240
1255
  if (status)
1241
1256
  rb_jump_tag(status);
1242
1257
  return ret;
@@ -1290,7 +1305,7 @@ Init_ossl_ts(void)
1290
1305
  * ===Create a Response:
1291
1306
  * #Assumes ts.p12 is a PKCS#12-compatible file with a private key
1292
1307
  * #and a certificate that has an extended key usage of 'timeStamping'
1293
- * p12 = OpenSSL::PKCS12.new(File.open('ts.p12', 'rb'), 'pwd')
1308
+ * p12 = OpenSSL::PKCS12.new(File.binread('ts.p12'), 'pwd')
1294
1309
  * md = OpenSSL::Digest.new('SHA1')
1295
1310
  * hash = md.digest(data) #some binary data to be timestamped
1296
1311
  * req = OpenSSL::Timestamp::Request.new
@@ -1305,16 +1320,16 @@ Init_ossl_ts(void)
1305
1320
  *
1306
1321
  * ===Verify a timestamp response:
1307
1322
  * #Assume we have a timestamp token in a file called ts.der
1308
- * ts = OpenSSL::Timestamp::Response.new(File.open('ts.der', 'rb')
1323
+ * ts = OpenSSL::Timestamp::Response.new(File.binread('ts.der'))
1309
1324
  * #Assume we have the Request for this token in a file called req.der
1310
- * req = OpenSSL::Timestamp::Request.new(File.open('req.der', 'rb')
1325
+ * req = OpenSSL::Timestamp::Request.new(File.binread('req.der'))
1311
1326
  * # Assume the associated root CA certificate is contained in a
1312
1327
  * # DER-encoded file named root.cer
1313
- * root = OpenSSL::X509::Certificate.new(File.open('root.cer', 'rb')
1328
+ * root = OpenSSL::X509::Certificate.new(File.binread('root.cer'))
1314
1329
  * # get the necessary intermediate certificates, available in
1315
1330
  * # DER-encoded form in inter1.cer and inter2.cer
1316
- * inter1 = OpenSSL::X509::Certificate.new(File.open('inter1.cer', 'rb')
1317
- * inter2 = OpenSSL::X509::Certificate.new(File.open('inter2.cer', 'rb')
1331
+ * inter1 = OpenSSL::X509::Certificate.new(File.binread('inter1.cer'))
1332
+ * inter2 = OpenSSL::X509::Certificate.new(File.binread('inter2.cer'))
1318
1333
  * ts.verify(req, root, inter1, inter2) -> ts or raises an exception if validation fails
1319
1334
  *
1320
1335
  */
@@ -1447,9 +1462,9 @@ Init_ossl_ts(void)
1447
1462
  * timestamping certificate.
1448
1463
  *
1449
1464
  * req = OpenSSL::Timestamp::Request.new(raw_bytes)
1450
- * p12 = OpenSSL::PKCS12.new(File.open('ts.p12', 'rb'), 'pwd')
1451
- * inter1 = OpenSSL::X509::Certificate.new(File.open('inter1.cer', 'rb')
1452
- * inter2 = OpenSSL::X509::Certificate.new(File.open('inter2.cer', 'rb')
1465
+ * p12 = OpenSSL::PKCS12.new(File.binread('ts.p12'), 'pwd')
1466
+ * inter1 = OpenSSL::X509::Certificate.new(File.binread('inter1.cer'))
1467
+ * inter2 = OpenSSL::X509::Certificate.new(File.binread('inter2.cer'))
1453
1468
  * fac = OpenSSL::Timestamp::Factory.new
1454
1469
  * fac.gen_time = Time.now
1455
1470
  * fac.serial_number = 1
@@ -115,11 +115,9 @@ Init_ossl_x509(void)
115
115
  DefX509Const(V_ERR_SUITE_B_LOS_NOT_ALLOWED);
116
116
  DefX509Const(V_ERR_SUITE_B_CANNOT_SIGN_P_384_WITH_P_256);
117
117
  #endif
118
- #if defined(X509_V_ERR_HOSTNAME_MISMATCH)
119
118
  DefX509Const(V_ERR_HOSTNAME_MISMATCH);
120
119
  DefX509Const(V_ERR_EMAIL_MISMATCH);
121
120
  DefX509Const(V_ERR_IP_ADDRESS_MISMATCH);
122
- #endif
123
121
  #if defined(X509_V_ERR_DANE_NO_MATCH)
124
122
  DefX509Const(V_ERR_DANE_NO_MATCH);
125
123
  #endif
@@ -187,12 +185,10 @@ Init_ossl_x509(void)
187
185
  /* Set by Store#flags= and StoreContext#flags=. Enables checking of the
188
186
  * signature of the root self-signed CA. */
189
187
  DefX509Const(V_FLAG_CHECK_SS_SIGNATURE);
190
- #if defined(X509_V_FLAG_TRUSTED_FIRST)
191
188
  /* Set by Store#flags= and StoreContext#flags=. When constructing a
192
189
  * certificate chain, search the Store first for the issuer certificate.
193
190
  * Enabled by default in OpenSSL >= 1.1.0. */
194
191
  DefX509Const(V_FLAG_TRUSTED_FIRST);
195
- #endif
196
192
  #if defined(X509_V_FLAG_SUITEB_128_LOS_ONLY)
197
193
  /* Set by Store#flags= and StoreContext#flags=.
198
194
  * Enables Suite B 128 bit only mode. */
@@ -208,11 +204,9 @@ Init_ossl_x509(void)
208
204
  * Enables Suite B 128 bit mode allowing 192 bit algorithms. */
209
205
  DefX509Const(V_FLAG_SUITEB_128_LOS);
210
206
  #endif
211
- #if defined(X509_V_FLAG_PARTIAL_CHAIN)
212
207
  /* Set by Store#flags= and StoreContext#flags=.
213
208
  * Allows partial chains if at least one certificate is in trusted store. */
214
209
  DefX509Const(V_FLAG_PARTIAL_CHAIN);
215
- #endif
216
210
  #if defined(X509_V_FLAG_NO_ALT_CHAINS)
217
211
  /* Set by Store#flags= and StoreContext#flags=. Suppresses searching for
218
212
  * a alternative chain. No effect in OpenSSL >= 1.1.0. */
@@ -115,24 +115,27 @@ static VALUE
115
115
  ossl_x509_initialize(int argc, VALUE *argv, VALUE self)
116
116
  {
117
117
  BIO *in;
118
- X509 *x509, *x = DATA_PTR(self);
118
+ X509 *x509, *x509_orig = RTYPEDDATA_DATA(self);
119
119
  VALUE arg;
120
120
 
121
+ rb_check_frozen(self);
121
122
  if (rb_scan_args(argc, argv, "01", &arg) == 0) {
122
123
  /* create just empty X509Cert */
123
124
  return self;
124
125
  }
125
126
  arg = ossl_to_der_if_possible(arg);
126
127
  in = ossl_obj2bio(&arg);
127
- x509 = PEM_read_bio_X509(in, &x, NULL, NULL);
128
- DATA_PTR(self) = x;
128
+ x509 = d2i_X509_bio(in, NULL);
129
129
  if (!x509) {
130
- OSSL_BIO_reset(in);
131
- x509 = d2i_X509_bio(in, &x);
132
- DATA_PTR(self) = x;
130
+ OSSL_BIO_reset(in);
131
+ x509 = PEM_read_bio_X509(in, NULL, NULL, NULL);
133
132
  }
134
133
  BIO_free(in);
135
- if (!x509) ossl_raise(eX509CertError, NULL);
134
+ if (!x509)
135
+ ossl_raise(eX509CertError, "PEM_read_bio_X509");
136
+
137
+ RTYPEDDATA_DATA(self) = x509;
138
+ X509_free(x509_orig);
136
139
 
137
140
  return self;
138
141
  }
@@ -704,6 +707,157 @@ ossl_x509_eq(VALUE self, VALUE other)
704
707
  return !X509_cmp(a, b) ? Qtrue : Qfalse;
705
708
  }
706
709
 
710
+ struct load_chained_certificates_arguments {
711
+ VALUE certificates;
712
+ X509 *certificate;
713
+ };
714
+
715
+ static VALUE
716
+ load_chained_certificates_append_push(VALUE _arguments) {
717
+ struct load_chained_certificates_arguments *arguments = (struct load_chained_certificates_arguments*)_arguments;
718
+
719
+ if (arguments->certificates == Qnil) {
720
+ arguments->certificates = rb_ary_new();
721
+ }
722
+
723
+ rb_ary_push(arguments->certificates, ossl_x509_new(arguments->certificate));
724
+
725
+ return Qnil;
726
+ }
727
+
728
+ static VALUE
729
+ load_chained_certificate_append_ensure(VALUE _arguments) {
730
+ struct load_chained_certificates_arguments *arguments = (struct load_chained_certificates_arguments*)_arguments;
731
+
732
+ X509_free(arguments->certificate);
733
+
734
+ return Qnil;
735
+ }
736
+
737
+ inline static VALUE
738
+ load_chained_certificates_append(VALUE certificates, X509 *certificate) {
739
+ struct load_chained_certificates_arguments arguments;
740
+ arguments.certificates = certificates;
741
+ arguments.certificate = certificate;
742
+
743
+ rb_ensure(load_chained_certificates_append_push, (VALUE)&arguments, load_chained_certificate_append_ensure, (VALUE)&arguments);
744
+
745
+ return arguments.certificates;
746
+ }
747
+
748
+ static VALUE
749
+ load_chained_certificates_PEM(BIO *in) {
750
+ VALUE certificates = Qnil;
751
+ X509 *certificate = PEM_read_bio_X509(in, NULL, NULL, NULL);
752
+
753
+ /* If we cannot read even one certificate: */
754
+ if (certificate == NULL) {
755
+ /* If we cannot read one certificate because we could not read the PEM encoding: */
756
+ if (ERR_GET_REASON(ERR_peek_last_error()) == PEM_R_NO_START_LINE) {
757
+ ossl_clear_error();
758
+ }
759
+
760
+ if (ERR_peek_last_error())
761
+ ossl_raise(eX509CertError, NULL);
762
+ else
763
+ return Qnil;
764
+ }
765
+
766
+ certificates = load_chained_certificates_append(Qnil, certificate);
767
+
768
+ while ((certificate = PEM_read_bio_X509(in, NULL, NULL, NULL))) {
769
+ load_chained_certificates_append(certificates, certificate);
770
+ }
771
+
772
+ /* We tried to read one more certificate but could not read start line: */
773
+ if (ERR_GET_REASON(ERR_peek_last_error()) == PEM_R_NO_START_LINE) {
774
+ /* This is not an error, it means we are finished: */
775
+ ossl_clear_error();
776
+
777
+ return certificates;
778
+ }
779
+
780
+ /* Alternatively, if we reached the end of the file and there was no error: */
781
+ if (BIO_eof(in) && !ERR_peek_last_error()) {
782
+ return certificates;
783
+ } else {
784
+ /* Otherwise, we tried to read a certificate but failed somewhere: */
785
+ ossl_raise(eX509CertError, NULL);
786
+ }
787
+ }
788
+
789
+ static VALUE
790
+ load_chained_certificates_DER(BIO *in) {
791
+ X509 *certificate = d2i_X509_bio(in, NULL);
792
+
793
+ /* If we cannot read one certificate: */
794
+ if (certificate == NULL) {
795
+ /* Ignore error. We could not load. */
796
+ ossl_clear_error();
797
+
798
+ return Qnil;
799
+ }
800
+
801
+ return load_chained_certificates_append(Qnil, certificate);
802
+ }
803
+
804
+ static VALUE
805
+ load_chained_certificates(VALUE _io) {
806
+ BIO *in = (BIO*)_io;
807
+ VALUE certificates = Qnil;
808
+
809
+ /*
810
+ DER is a binary format and it may contain octets within it that look like
811
+ PEM encoded certificates. So we need to check DER first.
812
+ */
813
+ certificates = load_chained_certificates_DER(in);
814
+
815
+ if (certificates != Qnil)
816
+ return certificates;
817
+
818
+ OSSL_BIO_reset(in);
819
+
820
+ certificates = load_chained_certificates_PEM(in);
821
+
822
+ if (certificates != Qnil)
823
+ return certificates;
824
+
825
+ /* Otherwise we couldn't read the output correctly so fail: */
826
+ ossl_raise(eX509CertError, "Could not detect format of certificate data!");
827
+ }
828
+
829
+ static VALUE
830
+ load_chained_certificates_ensure(VALUE _io) {
831
+ BIO *in = (BIO*)_io;
832
+
833
+ BIO_free(in);
834
+
835
+ return Qnil;
836
+ }
837
+
838
+ /*
839
+ * call-seq:
840
+ * OpenSSL::X509::Certificate.load(string) -> [certs...]
841
+ * OpenSSL::X509::Certificate.load(file) -> [certs...]
842
+ *
843
+ * Read the chained certificates from the given input. Supports both PEM
844
+ * and DER encoded certificates.
845
+ *
846
+ * PEM is a text format and supports more than one certificate.
847
+ *
848
+ * DER is a binary format and only supports one certificate.
849
+ *
850
+ * If the file is empty, or contains only unrelated data, an
851
+ * +OpenSSL::X509::CertificateError+ exception will be raised.
852
+ */
853
+ static VALUE
854
+ ossl_x509_load(VALUE klass, VALUE buffer)
855
+ {
856
+ BIO *in = ossl_obj2bio(&buffer);
857
+
858
+ return rb_ensure(load_chained_certificates, (VALUE)in, load_chained_certificates_ensure, (VALUE)in);
859
+ }
860
+
707
861
  /*
708
862
  * INIT
709
863
  */
@@ -730,7 +884,7 @@ Init_ossl_x509cert(void)
730
884
  * Certificate is capable of handling DER-encoded certificates and
731
885
  * certificates encoded in OpenSSL's PEM format.
732
886
  *
733
- * raw = File.read "cert.cer" # DER- or PEM-encoded
887
+ * raw = File.binread "cert.cer" # DER- or PEM-encoded
734
888
  * certificate = OpenSSL::X509::Certificate.new raw
735
889
  *
736
890
  * === Saving a certificate to a file
@@ -812,6 +966,8 @@ Init_ossl_x509cert(void)
812
966
  */
813
967
  cX509Cert = rb_define_class_under(mX509, "Certificate", rb_cObject);
814
968
 
969
+ rb_define_singleton_method(cX509Cert, "load", ossl_x509_load, 1);
970
+
815
971
  rb_define_alloc_func(cX509Cert, ossl_x509_alloc);
816
972
  rb_define_method(cX509Cert, "initialize", ossl_x509_initialize, -1);
817
973
  rb_define_method(cX509Cert, "initialize_copy", ossl_x509_copy, 1);
@@ -93,23 +93,26 @@ static VALUE
93
93
  ossl_x509crl_initialize(int argc, VALUE *argv, VALUE self)
94
94
  {
95
95
  BIO *in;
96
- X509_CRL *crl, *x = DATA_PTR(self);
96
+ X509_CRL *crl, *crl_orig = RTYPEDDATA_DATA(self);
97
97
  VALUE arg;
98
98
 
99
+ rb_check_frozen(self);
99
100
  if (rb_scan_args(argc, argv, "01", &arg) == 0) {
100
101
  return self;
101
102
  }
102
103
  arg = ossl_to_der_if_possible(arg);
103
104
  in = ossl_obj2bio(&arg);
104
- crl = PEM_read_bio_X509_CRL(in, &x, NULL, NULL);
105
- DATA_PTR(self) = x;
105
+ crl = d2i_X509_CRL_bio(in, NULL);
106
106
  if (!crl) {
107
- OSSL_BIO_reset(in);
108
- crl = d2i_X509_CRL_bio(in, &x);
109
- DATA_PTR(self) = x;
107
+ OSSL_BIO_reset(in);
108
+ crl = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL);
110
109
  }
111
110
  BIO_free(in);
112
- if (!crl) ossl_raise(eX509CRLError, NULL);
111
+ if (!crl)
112
+ ossl_raise(eX509CRLError, "PEM_read_bio_X509_CRL");
113
+
114
+ RTYPEDDATA_DATA(self) = crl;
115
+ X509_CRL_free(crl_orig);
113
116
 
114
117
  return self;
115
118
  }
@@ -226,11 +226,10 @@ ossl_x509extfactory_create_ext(int argc, VALUE *argv, VALUE self)
226
226
  GetX509ExtFactory(self, ctx);
227
227
  obj = NewX509Ext(cX509Ext);
228
228
  rconf = rb_iv_get(self, "@config");
229
- conf = NIL_P(rconf) ? NULL : DupConfigPtr(rconf);
229
+ conf = NIL_P(rconf) ? NULL : GetConfig(rconf);
230
230
  X509V3_set_nconf(ctx, conf);
231
231
  ext = X509V3_EXT_nconf_nid(conf, ctx, nid, RSTRING_PTR(valstr));
232
232
  X509V3_set_ctx_nodb(ctx);
233
- NCONF_free(conf);
234
233
  if (!ext){
235
234
  ossl_raise(eX509ExtError, "%"PRIsVALUE" = %"PRIsVALUE, oid, valstr);
236
235
  }
@@ -291,7 +291,14 @@ x509name_print(VALUE self, unsigned long iflag)
291
291
  * * OpenSSL::X509::Name::MULTILINE
292
292
  *
293
293
  * If _format_ is omitted, the largely broken and traditional OpenSSL format
294
- * is used.
294
+ * (<tt>X509_NAME_oneline()</tt> format) is chosen.
295
+ *
296
+ * <b>Use of this method is discouraged.</b> None of the formats other than
297
+ * OpenSSL::X509::Name::RFC2253 is standardized and may show an inconsistent
298
+ * behavior through \OpenSSL versions.
299
+ *
300
+ * It is recommended to use #to_utf8 instead, which is equivalent to calling
301
+ * <tt>name.to_s(OpenSSL::X509::Name::RFC2253).force_encoding("UTF-8")</tt>.
295
302
  */
296
303
  static VALUE
297
304
  ossl_x509name_to_s(int argc, VALUE *argv, VALUE self)
@@ -498,7 +505,7 @@ ossl_x509name_to_der(VALUE self)
498
505
  * You can create a Name by parsing a distinguished name String or by
499
506
  * supplying the distinguished name as an Array.
500
507
  *
501
- * name = OpenSSL::X509::Name.parse '/CN=nobody/DC=example'
508
+ * name = OpenSSL::X509::Name.parse_rfc2253 'DC=example,CN=nobody'
502
509
  *
503
510
  * name = OpenSSL::X509::Name.new [['CN', 'nobody'], ['DC', 'example']]
504
511
  */
@@ -79,23 +79,26 @@ static VALUE
79
79
  ossl_x509req_initialize(int argc, VALUE *argv, VALUE self)
80
80
  {
81
81
  BIO *in;
82
- X509_REQ *req, *x = DATA_PTR(self);
82
+ X509_REQ *req, *req_orig = RTYPEDDATA_DATA(self);
83
83
  VALUE arg;
84
84
 
85
+ rb_check_frozen(self);
85
86
  if (rb_scan_args(argc, argv, "01", &arg) == 0) {
86
87
  return self;
87
88
  }
88
89
  arg = ossl_to_der_if_possible(arg);
89
90
  in = ossl_obj2bio(&arg);
90
- req = PEM_read_bio_X509_REQ(in, &x, NULL, NULL);
91
- DATA_PTR(self) = x;
91
+ req = d2i_X509_REQ_bio(in, NULL);
92
92
  if (!req) {
93
- OSSL_BIO_reset(in);
94
- req = d2i_X509_REQ_bio(in, &x);
95
- DATA_PTR(self) = x;
93
+ OSSL_BIO_reset(in);
94
+ req = PEM_read_bio_X509_REQ(in, NULL, NULL, NULL);
96
95
  }
97
96
  BIO_free(in);
98
- if (!req) ossl_raise(eX509ReqError, NULL);
97
+ if (!req)
98
+ ossl_raise(eX509ReqError, "PEM_read_bio_X509_REQ");
99
+
100
+ RTYPEDDATA_DATA(self) = req;
101
+ X509_REQ_free(req_orig);
99
102
 
100
103
  return self;
101
104
  }