openssl 2.1.0 → 3.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
@@ -3,7 +3,7 @@
3
3
  * Copyright (C) 2007, 2017 Ruby/OpenSSL Project Authors
4
4
  */
5
5
  #include "ossl.h"
6
- #if OPENSSL_VERSION_NUMBER >= 0x10100000 && !defined(LIBRESSL_VERSION_NUMBER)
6
+ #if OSSL_OPENSSL_PREREQ(1, 1, 0) || OSSL_LIBRESSL_PREREQ(3, 6, 0)
7
7
  # include <openssl/kdf.h>
8
8
  #endif
9
9
 
@@ -21,7 +21,7 @@ static VALUE mKDF, eKDF;
21
21
  * (https://tools.ietf.org/html/rfc2898#section-5.2).
22
22
  *
23
23
  * === Parameters
24
- * pass :: The passphrase.
24
+ * pass :: The password.
25
25
  * salt :: The salt. Salts prevent attacks based on dictionaries of common
26
26
  * passwords and attacks based on rainbow tables. It is a public
27
27
  * value that can be safely stored along with the password (e.g.
@@ -141,7 +141,7 @@ kdf_scrypt(int argc, VALUE *argv, VALUE self)
141
141
  }
142
142
  #endif
143
143
 
144
- #if OPENSSL_VERSION_NUMBER >= 0x10100000 && !defined(LIBRESSL_VERSION_NUMBER)
144
+ #if OSSL_OPENSSL_PREREQ(1, 1, 0) || OSSL_LIBRESSL_PREREQ(3, 6, 0)
145
145
  /*
146
146
  * call-seq:
147
147
  * KDF.hkdf(ikm, salt:, info:, length:, hash:) -> String
@@ -163,6 +163,14 @@ kdf_scrypt(int argc, VALUE *argv, VALUE self)
163
163
  * HashLen is the length of the hash function output in octets.
164
164
  * _hash_::
165
165
  * The hash function.
166
+ *
167
+ * === Example
168
+ * # The values from https://datatracker.ietf.org/doc/html/rfc5869#appendix-A.1
169
+ * ikm = ["0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b"].pack("H*")
170
+ * salt = ["000102030405060708090a0b0c"].pack("H*")
171
+ * info = ["f0f1f2f3f4f5f6f7f8f9"].pack("H*")
172
+ * p OpenSSL::KDF.hkdf(ikm, salt: salt, info: info, length: 42, hash: "SHA256").unpack1("H*")
173
+ * # => "3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c5bf34007208d5b887185865"
166
174
  */
167
175
  static VALUE
168
176
  kdf_hkdf(int argc, VALUE *argv, VALUE self)
@@ -272,7 +280,7 @@ Init_ossl_kdf(void)
272
280
  * # store this with the generated value
273
281
  * salt = OpenSSL::Random.random_bytes(16)
274
282
  * iter = 20_000
275
- * hash = OpenSSL::Digest::SHA256.new
283
+ * hash = OpenSSL::Digest.new('SHA256')
276
284
  * len = hash.digest_length
277
285
  * # the final value to be stored
278
286
  * value = OpenSSL::KDF.pbkdf2_hmac(pass, salt: salt, iterations: iter,
@@ -284,24 +292,8 @@ Init_ossl_kdf(void)
284
292
  * Typically, "==" short-circuits on evaluation, and is therefore
285
293
  * vulnerable to timing attacks. The proper way is to use a method that
286
294
  * always takes the same amount of time when comparing two values, thus
287
- * not leaking any information to potential attackers. To compare two
288
- * values, the following could be used:
289
- *
290
- * def eql_time_cmp(a, b)
291
- * unless a.length == b.length
292
- * return false
293
- * end
294
- * cmp = b.bytes
295
- * result = 0
296
- * a.bytes.each_with_index {|c,i|
297
- * result |= c ^ cmp[i]
298
- * }
299
- * result == 0
300
- * end
301
- *
302
- * Please note that the premature return in case of differing lengths
303
- * typically does not leak valuable information - when using PBKDF2, the
304
- * length of the values to be compared is of fixed size.
295
+ * not leaking any information to potential attackers. To do this, use
296
+ * +OpenSSL.fixed_length_secure_compare+.
305
297
  */
306
298
  mKDF = rb_define_module_under(mOSSL, "KDF");
307
299
  /*
@@ -313,7 +305,7 @@ Init_ossl_kdf(void)
313
305
  #if defined(HAVE_EVP_PBE_SCRYPT)
314
306
  rb_define_module_function(mKDF, "scrypt", kdf_scrypt, -1);
315
307
  #endif
316
- #if OPENSSL_VERSION_NUMBER >= 0x10100000 && !defined(LIBRESSL_VERSION_NUMBER)
308
+ #if OSSL_OPENSSL_PREREQ(1, 1, 0) || OSSL_LIBRESSL_PREREQ(3, 6, 0)
317
309
  rb_define_module_function(mKDF, "hkdf", kdf_hkdf, -1);
318
310
  #endif
319
311
  }
@@ -50,7 +50,7 @@ static const rb_data_type_t ossl_netscape_spki_type = {
50
50
  {
51
51
  0, ossl_netscape_spki_free,
52
52
  },
53
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
53
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
54
54
  };
55
55
 
56
56
  static VALUE
@@ -350,7 +350,7 @@ ossl_spki_verify(VALUE self, VALUE key)
350
350
  * spki = OpenSSL::Netscape::SPKI.new
351
351
  * spki.challenge = "RandomChallenge"
352
352
  * spki.public_key = key.public_key
353
- * spki.sign(key, OpenSSL::Digest::SHA256.new)
353
+ * spki.sign(key, OpenSSL::Digest.new('SHA256'))
354
354
  * #send a request containing this to a server generating a certificate
355
355
  * === Verifying an SPKI request
356
356
  * request = #...
@@ -86,7 +86,7 @@ static const rb_data_type_t ossl_ocsp_request_type = {
86
86
  {
87
87
  0, ossl_ocsp_request_free,
88
88
  },
89
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
89
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
90
90
  };
91
91
 
92
92
  static void
@@ -100,7 +100,7 @@ static const rb_data_type_t ossl_ocsp_response_type = {
100
100
  {
101
101
  0, ossl_ocsp_response_free,
102
102
  },
103
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
103
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
104
104
  };
105
105
 
106
106
  static void
@@ -114,7 +114,7 @@ static const rb_data_type_t ossl_ocsp_basicresp_type = {
114
114
  {
115
115
  0, ossl_ocsp_basicresp_free,
116
116
  },
117
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
117
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
118
118
  };
119
119
 
120
120
  static void
@@ -128,7 +128,7 @@ static const rb_data_type_t ossl_ocsp_singleresp_type = {
128
128
  {
129
129
  0, ossl_ocsp_singleresp_free,
130
130
  },
131
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
131
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
132
132
  };
133
133
 
134
134
  static void
@@ -142,7 +142,7 @@ static const rb_data_type_t ossl_ocsp_certid_type = {
142
142
  {
143
143
  0, ossl_ocsp_certid_free,
144
144
  },
145
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
145
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
146
146
  };
147
147
 
148
148
  /*
@@ -157,7 +157,7 @@ ossl_ocspcertid_new(OCSP_CERTID *cid)
157
157
  }
158
158
 
159
159
  /*
160
- * OCSP::Resquest
160
+ * OCSP::Request
161
161
  */
162
162
  static VALUE
163
163
  ossl_ocspreq_alloc(VALUE klass)
@@ -382,7 +382,7 @@ ossl_ocspreq_sign(int argc, VALUE *argv, VALUE self)
382
382
  if (!NIL_P(flags))
383
383
  flg = NUM2INT(flags);
384
384
  if (NIL_P(digest))
385
- md = EVP_sha1();
385
+ md = NULL;
386
386
  else
387
387
  md = ossl_evp_get_digestbyname(digest);
388
388
  if (NIL_P(certs))
@@ -803,7 +803,7 @@ add_status_convert_time(VALUE obj)
803
803
  * revocation, and must be one of OpenSSL::OCSP::REVOKED_STATUS_* constants.
804
804
  * _revocation_time_ is the time when the certificate is revoked.
805
805
  *
806
- * _this_update_ and _next_update_ indicate the time at which ths status is
806
+ * _this_update_ and _next_update_ indicate the time at which the status is
807
807
  * verified to be correct and the time at or before which newer information
808
808
  * will be available, respectively. _next_update_ is optional.
809
809
  *
@@ -1033,7 +1033,7 @@ ossl_ocspbres_sign(int argc, VALUE *argv, VALUE self)
1033
1033
  if (!NIL_P(flags))
1034
1034
  flg = NUM2INT(flags);
1035
1035
  if (NIL_P(digest))
1036
- md = EVP_sha1();
1036
+ md = NULL;
1037
1037
  else
1038
1038
  md = ossl_evp_get_digestbyname(digest);
1039
1039
  if (NIL_P(certs))
@@ -1069,55 +1069,7 @@ ossl_ocspbres_verify(int argc, VALUE *argv, VALUE self)
1069
1069
  x509st = GetX509StorePtr(store);
1070
1070
  flg = NIL_P(flags) ? 0 : NUM2INT(flags);
1071
1071
  x509s = ossl_x509_ary2sk(certs);
1072
- #if (OPENSSL_VERSION_NUMBER < 0x1000202fL) || defined(LIBRESSL_VERSION_NUMBER)
1073
- /*
1074
- * OpenSSL had a bug that it doesn't use the certificates in x509s for
1075
- * verifying the chain. This can be a problem when the response is signed by
1076
- * a certificate issued by an intermediate CA.
1077
- *
1078
- * root_ca
1079
- * |
1080
- * intermediate_ca
1081
- * |-------------|
1082
- * end_entity ocsp_signer
1083
- *
1084
- * When the certificate hierarchy is like this, and the response contains
1085
- * only ocsp_signer certificate, the following code wrongly fails.
1086
- *
1087
- * store = OpenSSL::X509::Store.new; store.add_cert(root_ca)
1088
- * basic_response.verify([intermediate_ca], store)
1089
- *
1090
- * So add the certificates in x509s to the embedded certificates list first.
1091
- *
1092
- * This is fixed in OpenSSL 0.9.8zg, 1.0.0s, 1.0.1n, 1.0.2b. But it still
1093
- * exists in LibreSSL 2.1.10, 2.2.9, 2.3.6, 2.4.1.
1094
- */
1095
- if (!(flg & (OCSP_NOCHAIN | OCSP_NOVERIFY)) &&
1096
- sk_X509_num(x509s) && sk_X509_num(bs->certs)) {
1097
- int i;
1098
-
1099
- bs = ASN1_item_dup(ASN1_ITEM_rptr(OCSP_BASICRESP), bs);
1100
- if (!bs) {
1101
- sk_X509_pop_free(x509s, X509_free);
1102
- ossl_raise(eOCSPError, "ASN1_item_dup");
1103
- }
1104
-
1105
- for (i = 0; i < sk_X509_num(x509s); i++) {
1106
- if (!OCSP_basic_add1_cert(bs, sk_X509_value(x509s, i))) {
1107
- sk_X509_pop_free(x509s, X509_free);
1108
- OCSP_BASICRESP_free(bs);
1109
- ossl_raise(eOCSPError, "OCSP_basic_add1_cert");
1110
- }
1111
- }
1112
- result = OCSP_basic_verify(bs, x509s, x509st, flg);
1113
- OCSP_BASICRESP_free(bs);
1114
- }
1115
- else {
1116
- result = OCSP_basic_verify(bs, x509s, x509st, flg);
1117
- }
1118
- #else
1119
1072
  result = OCSP_basic_verify(bs, x509s, x509st, flg);
1120
- #endif
1121
1073
  sk_X509_pop_free(x509s, X509_free);
1122
1074
  if (result <= 0)
1123
1075
  ossl_clear_error();
@@ -1489,13 +1441,15 @@ ossl_ocspcid_initialize_copy(VALUE self, VALUE other)
1489
1441
  * call-seq:
1490
1442
  * OpenSSL::OCSP::CertificateId.new(subject, issuer, digest = nil) -> certificate_id
1491
1443
  * OpenSSL::OCSP::CertificateId.new(der_string) -> certificate_id
1444
+ * OpenSSL::OCSP::CertificateId.new(obj) -> certificate_id
1492
1445
  *
1493
1446
  * Creates a new OpenSSL::OCSP::CertificateId for the given _subject_ and
1494
1447
  * _issuer_ X509 certificates. The _digest_ is a digest algorithm that is used
1495
1448
  * to compute the hash values. This defaults to SHA-1.
1496
1449
  *
1497
1450
  * If only one argument is given, decodes it as DER representation of a
1498
- * certificate ID.
1451
+ * certificate ID or generates certificate ID from the object that responds to
1452
+ * the to_der method.
1499
1453
  */
1500
1454
  static VALUE
1501
1455
  ossl_ocspcid_initialize(int argc, VALUE *argv, VALUE self)
@@ -1717,7 +1671,7 @@ Init_ossl_ocsp(void)
1717
1671
  * subject certificate so the CA knows which certificate we are asking
1718
1672
  * about:
1719
1673
  *
1720
- * digest = OpenSSL::Digest::SHA1.new
1674
+ * digest = OpenSSL::Digest.new('SHA1')
1721
1675
  * certificate_id =
1722
1676
  * OpenSSL::OCSP::CertificateId.new subject, issuer, digest
1723
1677
  *
@@ -1734,18 +1688,11 @@ Init_ossl_ocsp(void)
1734
1688
  * To submit the request to the CA for verification we need to extract the
1735
1689
  * OCSP URI from the subject certificate:
1736
1690
  *
1737
- * authority_info_access = subject.extensions.find do |extension|
1738
- * extension.oid == 'authorityInfoAccess'
1739
- * end
1740
- *
1741
- * descriptions = authority_info_access.value.split "\n"
1742
- * ocsp = descriptions.find do |description|
1743
- * description.start_with? 'OCSP'
1744
- * end
1691
+ * ocsp_uris = subject.ocsp_uris
1745
1692
  *
1746
1693
  * require 'uri'
1747
1694
  *
1748
- * ocsp_uri = URI ocsp[/URI:(.*)/, 1]
1695
+ * ocsp_uri = URI ocsp_uris[0]
1749
1696
  *
1750
1697
  * To submit the request we'll POST the request to the OCSP URI (per RFC
1751
1698
  * 2560). Note that we only handle HTTP requests and don't handle any
@@ -1754,7 +1701,7 @@ Init_ossl_ocsp(void)
1754
1701
  * require 'net/http'
1755
1702
  *
1756
1703
  * http_response =
1757
- * Net::HTTP.start ocsp_uri.hostname, ocsp.port do |http|
1704
+ * Net::HTTP.start ocsp_uri.hostname, ocsp_uri.port do |http|
1758
1705
  * http.post ocsp_uri.path, request.to_der,
1759
1706
  * 'content-type' => 'application/ocsp-request'
1760
1707
  * end
@@ -1792,7 +1739,7 @@ Init_ossl_ocsp(void)
1792
1739
  * single_response = basic_response.find_response(certificate_id)
1793
1740
  *
1794
1741
  * unless single_response
1795
- * raise 'basic_response does not have the status for the certificiate'
1742
+ * raise 'basic_response does not have the status for the certificate'
1796
1743
  * end
1797
1744
  *
1798
1745
  * Then check the validity. A status issued in the future must be rejected.
@@ -13,9 +13,9 @@
13
13
 
14
14
  #if !defined(OPENSSL_NO_OCSP)
15
15
  extern VALUE mOCSP;
16
- extern VALUE cOPCSReq;
17
- extern VALUE cOPCSRes;
18
- extern VALUE cOPCSBasicRes;
16
+ extern VALUE cOCSPReq;
17
+ extern VALUE cOCSPRes;
18
+ extern VALUE cOCSPBasicRes;
19
19
  #endif
20
20
 
21
21
  void Init_ossl_ocsp(void);
@@ -44,7 +44,7 @@ static const rb_data_type_t ossl_pkcs12_type = {
44
44
  {
45
45
  0, ossl_pkcs12_free,
46
46
  },
47
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
47
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
48
48
  };
49
49
 
50
50
  static VALUE
@@ -149,6 +149,24 @@ ossl_pkcs12_s_create(int argc, VALUE *argv, VALUE self)
149
149
  return obj;
150
150
  }
151
151
 
152
+ static VALUE
153
+ ossl_pkey_new_i(VALUE arg)
154
+ {
155
+ return ossl_pkey_new((EVP_PKEY *)arg);
156
+ }
157
+
158
+ static VALUE
159
+ ossl_x509_new_i(VALUE arg)
160
+ {
161
+ return ossl_x509_new((X509 *)arg);
162
+ }
163
+
164
+ static VALUE
165
+ ossl_x509_sk2ary_i(VALUE arg)
166
+ {
167
+ return ossl_x509_sk2ary((STACK_OF(X509) *)arg);
168
+ }
169
+
152
170
  /*
153
171
  * call-seq:
154
172
  * PKCS12.new -> pkcs12
@@ -186,15 +204,15 @@ ossl_pkcs12_initialize(int argc, VALUE *argv, VALUE self)
186
204
  ossl_raise(ePKCS12Error, "PKCS12_parse");
187
205
  ERR_pop_to_mark();
188
206
  if (key) {
189
- pkey = rb_protect((VALUE (*)(VALUE))ossl_pkey_new, (VALUE)key, &st);
207
+ pkey = rb_protect(ossl_pkey_new_i, (VALUE)key, &st);
190
208
  if (st) goto err;
191
209
  }
192
210
  if (x509) {
193
- cert = rb_protect((VALUE (*)(VALUE))ossl_x509_new, (VALUE)x509, &st);
211
+ cert = rb_protect(ossl_x509_new_i, (VALUE)x509, &st);
194
212
  if (st) goto err;
195
213
  }
196
214
  if (x509s) {
197
- ca = rb_protect((VALUE (*)(VALUE))ossl_x509_sk2ary, (VALUE)x509s, &st);
215
+ ca = rb_protect(ossl_x509_sk2ary_i, (VALUE)x509s, &st);
198
216
  if (st) goto err;
199
217
  }
200
218
 
@@ -232,6 +250,7 @@ ossl_pkcs12_to_der(VALUE self)
232
250
  void
233
251
  Init_ossl_pkcs12(void)
234
252
  {
253
+ #undef rb_intern
235
254
  #if 0
236
255
  mOSSL = rb_define_module("OpenSSL");
237
256
  eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError);
@@ -9,21 +9,6 @@
9
9
  */
10
10
  #include "ossl.h"
11
11
 
12
- #define NewPKCS7(klass) \
13
- TypedData_Wrap_Struct((klass), &ossl_pkcs7_type, 0)
14
- #define SetPKCS7(obj, pkcs7) do { \
15
- if (!(pkcs7)) { \
16
- ossl_raise(rb_eRuntimeError, "PKCS7 wasn't initialized."); \
17
- } \
18
- RTYPEDDATA_DATA(obj) = (pkcs7); \
19
- } while (0)
20
- #define GetPKCS7(obj, pkcs7) do { \
21
- TypedData_Get_Struct((obj), PKCS7, &ossl_pkcs7_type, (pkcs7)); \
22
- if (!(pkcs7)) { \
23
- ossl_raise(rb_eRuntimeError, "PKCS7 wasn't initialized."); \
24
- } \
25
- } while (0)
26
-
27
12
  #define NewPKCS7si(klass) \
28
13
  TypedData_Wrap_Struct((klass), &ossl_pkcs7_signer_info_type, 0)
29
14
  #define SetPKCS7si(obj, p7si) do { \
@@ -75,12 +60,12 @@ ossl_pkcs7_free(void *ptr)
75
60
  PKCS7_free(ptr);
76
61
  }
77
62
 
78
- static const rb_data_type_t ossl_pkcs7_type = {
63
+ const rb_data_type_t ossl_pkcs7_type = {
79
64
  "OpenSSL/PKCS7",
80
65
  {
81
66
  0, ossl_pkcs7_free,
82
67
  },
83
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
68
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
84
69
  };
85
70
 
86
71
  static void
@@ -94,7 +79,7 @@ static const rb_data_type_t ossl_pkcs7_signer_info_type = {
94
79
  {
95
80
  0, ossl_pkcs7_signer_info_free,
96
81
  },
97
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
82
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
98
83
  };
99
84
 
100
85
  static void
@@ -108,7 +93,7 @@ static const rb_data_type_t ossl_pkcs7_recip_info_type = {
108
93
  {
109
94
  0, ossl_pkcs7_recip_info_free,
110
95
  },
111
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
96
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
112
97
  };
113
98
 
114
99
  /*
@@ -116,19 +101,24 @@ static const rb_data_type_t ossl_pkcs7_recip_info_type = {
116
101
  * (MADE PRIVATE UNTIL SOMEBODY WILL NEED THEM)
117
102
  */
118
103
  static PKCS7_SIGNER_INFO *
119
- ossl_PKCS7_SIGNER_INFO_dup(const PKCS7_SIGNER_INFO *si)
104
+ ossl_PKCS7_SIGNER_INFO_dup(PKCS7_SIGNER_INFO *si)
120
105
  {
121
- return (PKCS7_SIGNER_INFO *)ASN1_dup((i2d_of_void *)i2d_PKCS7_SIGNER_INFO,
122
- (d2i_of_void *)d2i_PKCS7_SIGNER_INFO,
123
- (char *)si);
106
+ PKCS7_SIGNER_INFO *si_new = ASN1_dup((i2d_of_void *)i2d_PKCS7_SIGNER_INFO,
107
+ (d2i_of_void *)d2i_PKCS7_SIGNER_INFO,
108
+ si);
109
+ if (si_new && si->pkey) {
110
+ EVP_PKEY_up_ref(si->pkey);
111
+ si_new->pkey = si->pkey;
112
+ }
113
+ return si_new;
124
114
  }
125
115
 
126
116
  static PKCS7_RECIP_INFO *
127
- ossl_PKCS7_RECIP_INFO_dup(const PKCS7_RECIP_INFO *si)
117
+ ossl_PKCS7_RECIP_INFO_dup(PKCS7_RECIP_INFO *si)
128
118
  {
129
- return (PKCS7_RECIP_INFO *)ASN1_dup((i2d_of_void *)i2d_PKCS7_RECIP_INFO,
130
- (d2i_of_void *)d2i_PKCS7_RECIP_INFO,
131
- (char *)si);
119
+ return ASN1_dup((i2d_of_void *)i2d_PKCS7_RECIP_INFO,
120
+ (d2i_of_void *)d2i_PKCS7_RECIP_INFO,
121
+ si);
132
122
  }
133
123
 
134
124
  static VALUE
@@ -145,19 +135,6 @@ ossl_pkcs7si_new(PKCS7_SIGNER_INFO *p7si)
145
135
  return obj;
146
136
  }
147
137
 
148
- static PKCS7_SIGNER_INFO *
149
- DupPKCS7SignerPtr(VALUE obj)
150
- {
151
- PKCS7_SIGNER_INFO *p7si, *pkcs7;
152
-
153
- GetPKCS7si(obj, p7si);
154
- if (!(pkcs7 = ossl_PKCS7_SIGNER_INFO_dup(p7si))) {
155
- ossl_raise(ePKCS7Error, NULL);
156
- }
157
-
158
- return pkcs7;
159
- }
160
-
161
138
  static VALUE
162
139
  ossl_pkcs7ri_new(PKCS7_RECIP_INFO *p7ri)
163
140
  {
@@ -172,19 +149,6 @@ ossl_pkcs7ri_new(PKCS7_RECIP_INFO *p7ri)
172
149
  return obj;
173
150
  }
174
151
 
175
- static PKCS7_RECIP_INFO *
176
- DupPKCS7RecipientPtr(VALUE obj)
177
- {
178
- PKCS7_RECIP_INFO *p7ri, *pkcs7;
179
-
180
- GetPKCS7ri(obj, p7ri);
181
- if (!(pkcs7 = ossl_PKCS7_RECIP_INFO_dup(p7ri))) {
182
- ossl_raise(ePKCS7Error, NULL);
183
- }
184
-
185
- return pkcs7;
186
- }
187
-
188
152
  /*
189
153
  * call-seq:
190
154
  * PKCS7.read_smime(string) => pkcs7
@@ -366,7 +330,7 @@ ossl_pkcs7_alloc(VALUE klass)
366
330
  static VALUE
367
331
  ossl_pkcs7_initialize(int argc, VALUE *argv, VALUE self)
368
332
  {
369
- PKCS7 *p7, *pkcs = DATA_PTR(self);
333
+ PKCS7 *p7, *p7_orig = RTYPEDDATA_DATA(self);
370
334
  BIO *in;
371
335
  VALUE arg;
372
336
 
@@ -374,19 +338,17 @@ ossl_pkcs7_initialize(int argc, VALUE *argv, VALUE self)
374
338
  return self;
375
339
  arg = ossl_to_der_if_possible(arg);
376
340
  in = ossl_obj2bio(&arg);
377
- p7 = PEM_read_bio_PKCS7(in, &pkcs, NULL, NULL);
341
+ p7 = d2i_PKCS7_bio(in, NULL);
378
342
  if (!p7) {
379
- OSSL_BIO_reset(in);
380
- p7 = d2i_PKCS7_bio(in, &pkcs);
381
- if (!p7) {
382
- BIO_free(in);
383
- PKCS7_free(pkcs);
384
- DATA_PTR(self) = NULL;
385
- ossl_raise(rb_eArgError, "Could not parse the PKCS7");
386
- }
343
+ OSSL_BIO_reset(in);
344
+ p7 = PEM_read_bio_PKCS7(in, NULL, NULL, NULL);
387
345
  }
388
- DATA_PTR(self) = pkcs;
389
346
  BIO_free(in);
347
+ if (!p7)
348
+ ossl_raise(rb_eArgError, "Could not parse the PKCS7");
349
+
350
+ RTYPEDDATA_DATA(self) = p7;
351
+ PKCS7_free(p7_orig);
390
352
  ossl_pkcs7_set_data(self, Qnil);
391
353
  ossl_pkcs7_set_err_string(self, Qnil);
392
354
 
@@ -536,17 +498,18 @@ static VALUE
536
498
  ossl_pkcs7_add_signer(VALUE self, VALUE signer)
537
499
  {
538
500
  PKCS7 *pkcs7;
539
- PKCS7_SIGNER_INFO *p7si;
501
+ PKCS7_SIGNER_INFO *si, *si_new;
540
502
 
541
- p7si = DupPKCS7SignerPtr(signer); /* NEED TO DUP */
542
503
  GetPKCS7(self, pkcs7);
543
- if (!PKCS7_add_signer(pkcs7, p7si)) {
544
- PKCS7_SIGNER_INFO_free(p7si);
545
- ossl_raise(ePKCS7Error, "Could not add signer.");
546
- }
547
- if (PKCS7_type_is_signed(pkcs7)){
548
- PKCS7_add_signed_attribute(p7si, NID_pkcs9_contentType,
549
- V_ASN1_OBJECT, OBJ_nid2obj(NID_pkcs7_data));
504
+ GetPKCS7si(signer, si);
505
+
506
+ si_new = ossl_PKCS7_SIGNER_INFO_dup(si);
507
+ if (!si_new)
508
+ ossl_raise(ePKCS7Error, "PKCS7_SIGNER_INFO_dup");
509
+
510
+ if (PKCS7_add_signer(pkcs7, si_new) != 1) {
511
+ PKCS7_SIGNER_INFO_free(si_new);
512
+ ossl_raise(ePKCS7Error, "PKCS7_add_signer");
550
513
  }
551
514
 
552
515
  return self;
@@ -582,13 +545,18 @@ static VALUE
582
545
  ossl_pkcs7_add_recipient(VALUE self, VALUE recip)
583
546
  {
584
547
  PKCS7 *pkcs7;
585
- PKCS7_RECIP_INFO *ri;
548
+ PKCS7_RECIP_INFO *ri, *ri_new;
586
549
 
587
- ri = DupPKCS7RecipientPtr(recip); /* NEED TO DUP */
588
550
  GetPKCS7(self, pkcs7);
589
- if (!PKCS7_add_recipient_info(pkcs7, ri)) {
590
- PKCS7_RECIP_INFO_free(ri);
591
- ossl_raise(ePKCS7Error, "Could not add recipient.");
551
+ GetPKCS7ri(recip, ri);
552
+
553
+ ri_new = ossl_PKCS7_RECIP_INFO_dup(ri);
554
+ if (!ri_new)
555
+ ossl_raise(ePKCS7Error, "PKCS7_RECIP_INFO_dup");
556
+
557
+ if (PKCS7_add_recipient_info(pkcs7, ri_new) != 1) {
558
+ PKCS7_RECIP_INFO_free(ri_new);
559
+ ossl_raise(ePKCS7Error, "PKCS7_add_recipient_info");
592
560
  }
593
561
 
594
562
  return self;
@@ -803,9 +771,9 @@ ossl_pkcs7_decrypt(int argc, VALUE *argv, VALUE self)
803
771
  BIO *out;
804
772
  VALUE str;
805
773
 
806
- rb_scan_args(argc, argv, "21", &pkey, &cert, &flags);
774
+ rb_scan_args(argc, argv, "12", &pkey, &cert, &flags);
807
775
  key = GetPrivPKeyPtr(pkey); /* NO NEED TO DUP */
808
- x509 = GetX509CertPtr(cert); /* NO NEED TO DUP */
776
+ x509 = NIL_P(cert) ? NULL : GetX509CertPtr(cert); /* NO NEED TO DUP */
809
777
  flg = NIL_P(flags) ? 0 : NUM2INT(flags);
810
778
  GetPKCS7(self, p7);
811
779
  if(!(out = BIO_new(BIO_s_mem())))
@@ -1042,6 +1010,7 @@ ossl_pkcs7ri_get_enc_key(VALUE self)
1042
1010
  void
1043
1011
  Init_ossl_pkcs7(void)
1044
1012
  {
1013
+ #undef rb_intern
1045
1014
  #if 0
1046
1015
  mOSSL = rb_define_module("OpenSSL");
1047
1016
  eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError);
@@ -1087,7 +1056,6 @@ Init_ossl_pkcs7(void)
1087
1056
  rb_define_alloc_func(cPKCS7Signer, ossl_pkcs7si_alloc);
1088
1057
  rb_define_method(cPKCS7Signer, "initialize", ossl_pkcs7si_initialize,3);
1089
1058
  rb_define_method(cPKCS7Signer, "issuer", ossl_pkcs7si_get_issuer, 0);
1090
- rb_define_alias(cPKCS7Signer, "name", "issuer");
1091
1059
  rb_define_method(cPKCS7Signer, "serial", ossl_pkcs7si_get_serial,0);
1092
1060
  rb_define_method(cPKCS7Signer,"signed_time",ossl_pkcs7si_get_signed_time,0);
1093
1061
 
@@ -10,6 +10,22 @@
10
10
  #if !defined(_OSSL_PKCS7_H_)
11
11
  #define _OSSL_PKCS7_H_
12
12
 
13
+ #define NewPKCS7(klass) \
14
+ TypedData_Wrap_Struct((klass), &ossl_pkcs7_type, 0)
15
+ #define SetPKCS7(obj, pkcs7) do { \
16
+ if (!(pkcs7)) { \
17
+ ossl_raise(rb_eRuntimeError, "PKCS7 wasn't initialized."); \
18
+ } \
19
+ RTYPEDDATA_DATA(obj) = (pkcs7); \
20
+ } while (0)
21
+ #define GetPKCS7(obj, pkcs7) do { \
22
+ TypedData_Get_Struct((obj), PKCS7, &ossl_pkcs7_type, (pkcs7)); \
23
+ if (!(pkcs7)) { \
24
+ ossl_raise(rb_eRuntimeError, "PKCS7 wasn't initialized."); \
25
+ } \
26
+ } while (0)
27
+
28
+ extern const rb_data_type_t ossl_pkcs7_type;
13
29
  extern VALUE cPKCS7;
14
30
  extern VALUE cPKCS7Signer;
15
31
  extern VALUE cPKCS7Recipient;