openssl 2.1.2 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (60) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.md +35 -45
  3. data/History.md +232 -0
  4. data/README.md +2 -2
  5. data/ext/openssl/extconf.rb +61 -46
  6. data/ext/openssl/openssl_missing.c +0 -66
  7. data/ext/openssl/openssl_missing.h +60 -44
  8. data/ext/openssl/ossl.c +112 -66
  9. data/ext/openssl/ossl.h +28 -11
  10. data/ext/openssl/ossl_asn1.c +42 -5
  11. data/ext/openssl/ossl_bn.c +276 -146
  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 +31 -62
  17. data/ext/openssl/ossl_engine.c +18 -27
  18. data/ext/openssl/ossl_hmac.c +52 -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 +1255 -178
  27. data/ext/openssl/ossl_pkey.h +40 -77
  28. data/ext/openssl/ossl_pkey_dh.c +125 -335
  29. data/ext/openssl/ossl_pkey_dsa.c +93 -398
  30. data/ext/openssl/ossl_pkey_ec.c +155 -318
  31. data/ext/openssl/ossl_pkey_rsa.c +105 -484
  32. data/ext/openssl/ossl_rand.c +2 -40
  33. data/ext/openssl/ossl_ssl.c +395 -364
  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 +86 -1
  38. data/ext/openssl/ossl_x509cert.c +166 -10
  39. data/ext/openssl/ossl_x509crl.c +10 -7
  40. data/ext/openssl/ossl_x509ext.c +15 -2
  41. data/ext/openssl/ossl_x509name.c +16 -5
  42. data/ext/openssl/ossl_x509req.c +10 -7
  43. data/ext/openssl/ossl_x509store.c +193 -92
  44. data/lib/openssl/bn.rb +1 -1
  45. data/lib/openssl/buffering.rb +42 -17
  46. data/lib/openssl/cipher.rb +1 -1
  47. data/lib/openssl/digest.rb +10 -12
  48. data/lib/openssl/hmac.rb +78 -0
  49. data/lib/openssl/marshal.rb +30 -0
  50. data/lib/openssl/pkcs5.rb +1 -1
  51. data/lib/openssl/pkey.rb +435 -1
  52. data/lib/openssl/ssl.rb +53 -14
  53. data/lib/openssl/version.rb +5 -0
  54. data/lib/openssl/x509.rb +177 -1
  55. data/lib/openssl.rb +24 -9
  56. metadata +13 -69
  57. data/ext/openssl/deprecation.rb +0 -23
  58. data/ext/openssl/ossl_version.h +0 -15
  59. data/ext/openssl/ruby_missing.h +0 -24
  60. data/lib/openssl/config.rb +0 -474
@@ -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,71 @@ 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
+ DefX509Const(V_ERR_HOSTNAME_MISMATCH);
119
+ DefX509Const(V_ERR_EMAIL_MISMATCH);
120
+ DefX509Const(V_ERR_IP_ADDRESS_MISMATCH);
121
+ #if defined(X509_V_ERR_DANE_NO_MATCH)
122
+ DefX509Const(V_ERR_DANE_NO_MATCH);
123
+ #endif
124
+ #if defined(X509_V_ERR_EE_KEY_TOO_SMALL)
125
+ DefX509Const(V_ERR_EE_KEY_TOO_SMALL);
126
+ DefX509Const(V_ERR_CA_KEY_TOO_SMALL);
127
+ DefX509Const(V_ERR_CA_MD_TOO_WEAK);
128
+ #endif
129
+ #if defined(X509_V_ERR_INVALID_CALL)
130
+ DefX509Const(V_ERR_INVALID_CALL);
131
+ #endif
132
+ #if defined(X509_V_ERR_STORE_LOOKUP)
133
+ DefX509Const(V_ERR_STORE_LOOKUP);
134
+ #endif
135
+ #if defined(X509_V_ERR_NO_VALID_SCTS)
136
+ DefX509Const(V_ERR_NO_VALID_SCTS);
137
+ #endif
138
+ #if defined(X509_V_ERR_PROXY_SUBJECT_NAME_VIOLATION)
139
+ DefX509Const(V_ERR_PROXY_SUBJECT_NAME_VIOLATION);
140
+ #endif
141
+ #if defined(X509_V_ERR_OCSP_VERIFY_NEEDED)
142
+ DefX509Const(V_ERR_OCSP_VERIFY_NEEDED);
143
+ DefX509Const(V_ERR_OCSP_VERIFY_FAILED);
144
+ DefX509Const(V_ERR_OCSP_CERT_UNKNOWN);
145
+ #endif
80
146
 
147
+ /* Certificate verify flags */
148
+ /* Set by Store#flags= and StoreContext#flags=. */
149
+ DefX509Const(V_FLAG_USE_CHECK_TIME);
81
150
  /* Set by Store#flags= and StoreContext#flags=. Enables CRL checking for the
82
151
  * certificate chain leaf. */
83
152
  DefX509Const(V_FLAG_CRL_CHECK);
@@ -116,12 +185,28 @@ Init_ossl_x509(void)
116
185
  /* Set by Store#flags= and StoreContext#flags=. Enables checking of the
117
186
  * signature of the root self-signed CA. */
118
187
  DefX509Const(V_FLAG_CHECK_SS_SIGNATURE);
119
- #if defined(X509_V_FLAG_TRUSTED_FIRST)
120
188
  /* Set by Store#flags= and StoreContext#flags=. When constructing a
121
189
  * certificate chain, search the Store first for the issuer certificate.
122
190
  * Enabled by default in OpenSSL >= 1.1.0. */
123
191
  DefX509Const(V_FLAG_TRUSTED_FIRST);
192
+ #if defined(X509_V_FLAG_SUITEB_128_LOS_ONLY)
193
+ /* Set by Store#flags= and StoreContext#flags=.
194
+ * Enables Suite B 128 bit only mode. */
195
+ DefX509Const(V_FLAG_SUITEB_128_LOS_ONLY);
124
196
  #endif
197
+ #if defined(X509_V_FLAG_SUITEB_192_LOS)
198
+ /* Set by Store#flags= and StoreContext#flags=.
199
+ * Enables Suite B 192 bit only mode. */
200
+ DefX509Const(V_FLAG_SUITEB_192_LOS);
201
+ #endif
202
+ #if defined(X509_V_FLAG_SUITEB_128_LOS)
203
+ /* Set by Store#flags= and StoreContext#flags=.
204
+ * Enables Suite B 128 bit mode allowing 192 bit algorithms. */
205
+ DefX509Const(V_FLAG_SUITEB_128_LOS);
206
+ #endif
207
+ /* Set by Store#flags= and StoreContext#flags=.
208
+ * Allows partial chains if at least one certificate is in trusted store. */
209
+ DefX509Const(V_FLAG_PARTIAL_CHAIN);
125
210
  #if defined(X509_V_FLAG_NO_ALT_CHAINS)
126
211
  /* Set by Store#flags= and StoreContext#flags=. Suppresses searching for
127
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
@@ -788,7 +942,7 @@ Init_ossl_x509cert(void)
788
942
  * root_ca.add_extension(ef.create_extension("keyUsage","keyCertSign, cRLSign", true))
789
943
  * root_ca.add_extension(ef.create_extension("subjectKeyIdentifier","hash",false))
790
944
  * root_ca.add_extension(ef.create_extension("authorityKeyIdentifier","keyid:always",false))
791
- * root_ca.sign(root_key, OpenSSL::Digest::SHA256.new)
945
+ * root_ca.sign(root_key, OpenSSL::Digest.new('SHA256'))
792
946
  *
793
947
  * The next step is to create the end-entity certificate using the root CA
794
948
  * certificate.
@@ -807,11 +961,13 @@ Init_ossl_x509cert(void)
807
961
  * ef.issuer_certificate = root_ca
808
962
  * cert.add_extension(ef.create_extension("keyUsage","digitalSignature", true))
809
963
  * cert.add_extension(ef.create_extension("subjectKeyIdentifier","hash",false))
810
- * cert.sign(root_key, OpenSSL::Digest::SHA256.new)
964
+ * cert.sign(root_key, OpenSSL::Digest.new('SHA256'))
811
965
  *
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
  }
@@ -402,6 +401,19 @@ ossl_x509ext_get_value(VALUE obj)
402
401
  return ret;
403
402
  }
404
403
 
404
+ static VALUE
405
+ ossl_x509ext_get_value_der(VALUE obj)
406
+ {
407
+ X509_EXTENSION *ext;
408
+ ASN1_OCTET_STRING *value;
409
+
410
+ GetX509Ext(obj, ext);
411
+ if ((value = X509_EXTENSION_get_data(ext)) == NULL)
412
+ ossl_raise(eX509ExtError, NULL);
413
+
414
+ return rb_str_new((const char *)value->data, value->length);
415
+ }
416
+
405
417
  static VALUE
406
418
  ossl_x509ext_get_critical(VALUE obj)
407
419
  {
@@ -472,6 +484,7 @@ Init_ossl_x509ext(void)
472
484
  rb_define_method(cX509Ext, "critical=", ossl_x509ext_set_critical, 1);
473
485
  rb_define_method(cX509Ext, "oid", ossl_x509ext_get_oid, 0);
474
486
  rb_define_method(cX509Ext, "value", ossl_x509ext_get_value, 0);
487
+ rb_define_method(cX509Ext, "value_der", ossl_x509ext_get_value_der, 0);
475
488
  rb_define_method(cX509Ext, "critical?", ossl_x509ext_get_critical, 0);
476
489
  rb_define_method(cX509Ext, "to_der", ossl_x509ext_to_der, 0);
477
490
  }
@@ -270,7 +270,7 @@ x509name_print(VALUE self, unsigned long iflag)
270
270
  if (!out)
271
271
  ossl_raise(eX509NameError, NULL);
272
272
  ret = X509_NAME_print_ex(out, name, 0, iflag);
273
- if (ret < 0 || iflag == XN_FLAG_COMPAT && ret == 0) {
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
  }
@@ -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)
@@ -387,17 +394,21 @@ ossl_x509name_cmp0(VALUE self, VALUE other)
387
394
 
388
395
  /*
389
396
  * call-seq:
390
- * name.cmp(other) -> -1 | 0 | 1
391
- * name <=> other -> -1 | 0 | 1
397
+ * name.cmp(other) -> -1 | 0 | 1 | nil
398
+ * name <=> other -> -1 | 0 | 1 | nil
392
399
  *
393
400
  * Compares this Name with _other_ and returns +0+ if they are the same and +-1+
394
401
  * or ++1+ if they are greater or less than each other respectively.
402
+ * Returns +nil+ if they are not comparable (i.e. different types).
395
403
  */
396
404
  static VALUE
397
405
  ossl_x509name_cmp(VALUE self, VALUE other)
398
406
  {
399
407
  int result;
400
408
 
409
+ if (!rb_obj_is_kind_of(other, cX509Name))
410
+ return Qnil;
411
+
401
412
  result = ossl_x509name_cmp0(self, other);
402
413
  if (result < 0) return INT2FIX(-1);
403
414
  if (result > 0) return INT2FIX(1);
@@ -494,7 +505,7 @@ ossl_x509name_to_der(VALUE self)
494
505
  * You can create a Name by parsing a distinguished name String or by
495
506
  * supplying the distinguished name as an Array.
496
507
  *
497
- * name = OpenSSL::X509::Name.parse 'CN=nobody/DC=example'
508
+ * name = OpenSSL::X509::Name.parse_rfc2253 'DC=example,CN=nobody'
498
509
  *
499
510
  * name = OpenSSL::X509::Name.new [['CN', 'nobody'], ['DC', 'example']]
500
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
  }