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
@@ -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;