openssl 2.1.0 → 3.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (64) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.md +35 -45
  3. data/History.md +426 -0
  4. data/README.md +38 -21
  5. data/ext/openssl/extconf.rb +132 -72
  6. data/ext/openssl/openssl_missing.c +0 -66
  7. data/ext/openssl/openssl_missing.h +62 -46
  8. data/ext/openssl/ossl.c +177 -252
  9. data/ext/openssl/ossl.h +39 -17
  10. data/ext/openssl/ossl_asn1.c +53 -14
  11. data/ext/openssl/ossl_bn.c +288 -146
  12. data/ext/openssl/ossl_bn.h +2 -1
  13. data/ext/openssl/ossl_cipher.c +42 -32
  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 +32 -63
  17. data/ext/openssl/ossl_engine.c +19 -28
  18. data/ext/openssl/ossl_hmac.c +61 -146
  19. data/ext/openssl/ossl_kdf.c +15 -23
  20. data/ext/openssl/ossl_ns_spki.c +2 -2
  21. data/ext/openssl/ossl_ocsp.c +17 -70
  22. data/ext/openssl/ossl_ocsp.h +3 -3
  23. data/ext/openssl/ossl_pkcs12.c +23 -4
  24. data/ext/openssl/ossl_pkcs7.c +49 -81
  25. data/ext/openssl/ossl_pkcs7.h +16 -0
  26. data/ext/openssl/ossl_pkey.c +1508 -195
  27. data/ext/openssl/ossl_pkey.h +41 -78
  28. data/ext/openssl/ossl_pkey_dh.c +153 -348
  29. data/ext/openssl/ossl_pkey_dsa.c +157 -413
  30. data/ext/openssl/ossl_pkey_ec.c +257 -343
  31. data/ext/openssl/ossl_pkey_rsa.c +166 -490
  32. data/ext/openssl/ossl_provider.c +211 -0
  33. data/ext/openssl/ossl_provider.h +5 -0
  34. data/ext/openssl/ossl_rand.c +2 -40
  35. data/ext/openssl/ossl_ssl.c +666 -456
  36. data/ext/openssl/ossl_ssl_session.c +29 -30
  37. data/ext/openssl/ossl_ts.c +1539 -0
  38. data/ext/openssl/ossl_ts.h +16 -0
  39. data/ext/openssl/ossl_x509.c +86 -1
  40. data/ext/openssl/ossl_x509attr.c +1 -1
  41. data/ext/openssl/ossl_x509cert.c +170 -14
  42. data/ext/openssl/ossl_x509crl.c +14 -11
  43. data/ext/openssl/ossl_x509ext.c +29 -9
  44. data/ext/openssl/ossl_x509name.c +24 -12
  45. data/ext/openssl/ossl_x509req.c +14 -11
  46. data/ext/openssl/ossl_x509revoked.c +4 -4
  47. data/ext/openssl/ossl_x509store.c +205 -96
  48. data/lib/openssl/bn.rb +1 -1
  49. data/lib/openssl/buffering.rb +42 -20
  50. data/lib/openssl/cipher.rb +1 -1
  51. data/lib/openssl/digest.rb +10 -16
  52. data/lib/openssl/hmac.rb +78 -0
  53. data/lib/openssl/marshal.rb +30 -0
  54. data/lib/openssl/pkcs5.rb +1 -1
  55. data/lib/openssl/pkey.rb +447 -1
  56. data/lib/openssl/ssl.rb +68 -24
  57. data/lib/openssl/version.rb +5 -0
  58. data/lib/openssl/x509.rb +177 -1
  59. data/lib/openssl.rb +24 -9
  60. metadata +18 -71
  61. data/ext/openssl/deprecation.rb +0 -23
  62. data/ext/openssl/ossl_version.h +0 -15
  63. data/ext/openssl/ruby_missing.h +0 -24
  64. 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. */
@@ -41,7 +41,7 @@ static const rb_data_type_t ossl_x509attr_type = {
41
41
  {
42
42
  0, ossl_x509attr_free,
43
43
  },
44
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
44
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
45
45
  };
46
46
 
47
47
  /*
@@ -41,7 +41,7 @@ static const rb_data_type_t ossl_x509_type = {
41
41
  {
42
42
  0, ossl_x509_free,
43
43
  },
44
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
44
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
45
45
  };
46
46
 
47
47
  /*
@@ -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
  }
@@ -639,12 +642,12 @@ ossl_x509_set_extensions(VALUE self, VALUE ary)
639
642
  OSSL_Check_Kind(RARRAY_AREF(ary, i), cX509Ext);
640
643
  }
641
644
  GetX509(self, x509);
642
- while ((ext = X509_delete_ext(x509, 0)))
643
- X509_EXTENSION_free(ext);
645
+ for (i = X509_get_ext_count(x509); i > 0; i--)
646
+ X509_EXTENSION_free(X509_delete_ext(x509, 0));
644
647
  for (i=0; i<RARRAY_LEN(ary); i++) {
645
648
  ext = GetX509ExtPtr(RARRAY_AREF(ary, i));
646
649
  if (!X509_add_ext(x509, ext, -1)) { /* DUPs ext */
647
- ossl_raise(eX509CertError, NULL);
650
+ ossl_raise(eX509CertError, "X509_add_ext");
648
651
  }
649
652
  }
650
653
 
@@ -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);
@@ -41,7 +41,7 @@ static const rb_data_type_t ossl_x509crl_type = {
41
41
  {
42
42
  0, ossl_x509crl_free,
43
43
  },
44
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
44
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
45
45
  };
46
46
 
47
47
  /*
@@ -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
  }
@@ -471,12 +474,12 @@ ossl_x509crl_set_extensions(VALUE self, VALUE ary)
471
474
  OSSL_Check_Kind(RARRAY_AREF(ary, i), cX509Ext);
472
475
  }
473
476
  GetX509CRL(self, crl);
474
- while ((ext = X509_CRL_delete_ext(crl, 0)))
475
- X509_EXTENSION_free(ext);
477
+ for (i = X509_CRL_get_ext_count(crl); i > 0; i--)
478
+ X509_EXTENSION_free(X509_CRL_delete_ext(crl, 0));
476
479
  for (i=0; i<RARRAY_LEN(ary); i++) {
477
480
  ext = GetX509ExtPtr(RARRAY_AREF(ary, i)); /* NO NEED TO DUP */
478
481
  if (!X509_CRL_add_ext(crl, ext, -1)) {
479
- ossl_raise(eX509CRLError, NULL);
482
+ ossl_raise(eX509CRLError, "X509_CRL_add_ext");
480
483
  }
481
484
  }
482
485
 
@@ -55,7 +55,7 @@ static const rb_data_type_t ossl_x509ext_type = {
55
55
  {
56
56
  0, ossl_x509ext_free,
57
57
  },
58
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
58
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
59
59
  };
60
60
 
61
61
  /*
@@ -108,7 +108,7 @@ static const rb_data_type_t ossl_x509extfactory_type = {
108
108
  {
109
109
  0, ossl_x509extfactory_free,
110
110
  },
111
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
111
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
112
112
  };
113
113
 
114
114
  static VALUE
@@ -209,15 +209,16 @@ ossl_x509extfactory_create_ext(int argc, VALUE *argv, VALUE self)
209
209
  int nid;
210
210
  VALUE rconf;
211
211
  CONF *conf;
212
+ const char *oid_cstr = NULL;
212
213
 
213
214
  rb_scan_args(argc, argv, "21", &oid, &value, &critical);
214
- StringValueCStr(oid);
215
215
  StringValue(value);
216
216
  if(NIL_P(critical)) critical = Qfalse;
217
217
 
218
- nid = OBJ_ln2nid(RSTRING_PTR(oid));
219
- if(!nid) nid = OBJ_sn2nid(RSTRING_PTR(oid));
220
- if(!nid) ossl_raise(eX509ExtError, "unknown OID `%"PRIsVALUE"'", oid);
218
+ oid_cstr = StringValueCStr(oid);
219
+ nid = OBJ_ln2nid(oid_cstr);
220
+ if (nid != NID_undef)
221
+ oid_cstr = OBJ_nid2sn(nid);
221
222
 
222
223
  valstr = rb_str_new2(RTEST(critical) ? "critical," : "");
223
224
  rb_str_append(valstr, value);
@@ -226,11 +227,15 @@ ossl_x509extfactory_create_ext(int argc, VALUE *argv, VALUE self)
226
227
  GetX509ExtFactory(self, ctx);
227
228
  obj = NewX509Ext(cX509Ext);
228
229
  rconf = rb_iv_get(self, "@config");
229
- conf = NIL_P(rconf) ? NULL : DupConfigPtr(rconf);
230
+ conf = NIL_P(rconf) ? NULL : GetConfig(rconf);
230
231
  X509V3_set_nconf(ctx, conf);
231
- ext = X509V3_EXT_nconf_nid(conf, ctx, nid, RSTRING_PTR(valstr));
232
+
233
+ #if OSSL_OPENSSL_PREREQ(1, 1, 0) || OSSL_IS_LIBRESSL
234
+ ext = X509V3_EXT_nconf(conf, ctx, oid_cstr, RSTRING_PTR(valstr));
235
+ #else
236
+ ext = X509V3_EXT_nconf(conf, ctx, (char *)oid_cstr, RSTRING_PTR(valstr));
237
+ #endif
232
238
  X509V3_set_ctx_nodb(ctx);
233
- NCONF_free(conf);
234
239
  if (!ext){
235
240
  ossl_raise(eX509ExtError, "%"PRIsVALUE" = %"PRIsVALUE, oid, valstr);
236
241
  }
@@ -402,6 +407,19 @@ ossl_x509ext_get_value(VALUE obj)
402
407
  return ret;
403
408
  }
404
409
 
410
+ static VALUE
411
+ ossl_x509ext_get_value_der(VALUE obj)
412
+ {
413
+ X509_EXTENSION *ext;
414
+ ASN1_OCTET_STRING *value;
415
+
416
+ GetX509Ext(obj, ext);
417
+ if ((value = X509_EXTENSION_get_data(ext)) == NULL)
418
+ ossl_raise(eX509ExtError, NULL);
419
+
420
+ return rb_str_new((const char *)value->data, value->length);
421
+ }
422
+
405
423
  static VALUE
406
424
  ossl_x509ext_get_critical(VALUE obj)
407
425
  {
@@ -437,6 +455,7 @@ ossl_x509ext_to_der(VALUE obj)
437
455
  void
438
456
  Init_ossl_x509ext(void)
439
457
  {
458
+ #undef rb_intern
440
459
  #if 0
441
460
  mOSSL = rb_define_module("OpenSSL");
442
461
  eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError);
@@ -471,6 +490,7 @@ Init_ossl_x509ext(void)
471
490
  rb_define_method(cX509Ext, "critical=", ossl_x509ext_set_critical, 1);
472
491
  rb_define_method(cX509Ext, "oid", ossl_x509ext_get_oid, 0);
473
492
  rb_define_method(cX509Ext, "value", ossl_x509ext_get_value, 0);
493
+ rb_define_method(cX509Ext, "value_der", ossl_x509ext_get_value_der, 0);
474
494
  rb_define_method(cX509Ext, "critical?", ossl_x509ext_get_critical, 0);
475
495
  rb_define_method(cX509Ext, "to_der", ossl_x509ext_to_der, 0);
476
496
  }
@@ -46,7 +46,7 @@ static const rb_data_type_t ossl_x509name_type = {
46
46
  {
47
47
  0, ossl_x509name_free,
48
48
  },
49
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
49
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
50
50
  };
51
51
 
52
52
  /*
@@ -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
  }
@@ -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,20 +394,24 @@ 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
- if (result > 1) return INT2FIX(1);
414
+ if (result > 0) return INT2FIX(1);
404
415
 
405
416
  return INT2FIX(0);
406
417
  }
@@ -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
  */
@@ -502,6 +513,7 @@ ossl_x509name_to_der(VALUE self)
502
513
  void
503
514
  Init_ossl_x509name(void)
504
515
  {
516
+ #undef rb_intern
505
517
  VALUE utf8str, ptrstr, ia5str, hash;
506
518
 
507
519
  #if 0