openssl 2.2.1 → 3.0.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 (46) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.md +32 -44
  3. data/History.md +103 -1
  4. data/ext/openssl/extconf.rb +24 -26
  5. data/ext/openssl/openssl_missing.c +0 -66
  6. data/ext/openssl/openssl_missing.h +26 -45
  7. data/ext/openssl/ossl.c +59 -46
  8. data/ext/openssl/ossl.h +20 -6
  9. data/ext/openssl/ossl_asn1.c +16 -4
  10. data/ext/openssl/ossl_bn.c +188 -126
  11. data/ext/openssl/ossl_cipher.c +11 -11
  12. data/ext/openssl/ossl_config.c +412 -41
  13. data/ext/openssl/ossl_config.h +4 -7
  14. data/ext/openssl/ossl_digest.c +9 -9
  15. data/ext/openssl/ossl_engine.c +16 -15
  16. data/ext/openssl/ossl_hmac.c +48 -135
  17. data/ext/openssl/ossl_kdf.c +8 -0
  18. data/ext/openssl/ossl_ocsp.c +3 -51
  19. data/ext/openssl/ossl_pkcs12.c +21 -3
  20. data/ext/openssl/ossl_pkcs7.c +42 -59
  21. data/ext/openssl/ossl_pkey.c +1102 -191
  22. data/ext/openssl/ossl_pkey.h +35 -72
  23. data/ext/openssl/ossl_pkey_dh.c +124 -334
  24. data/ext/openssl/ossl_pkey_dsa.c +93 -398
  25. data/ext/openssl/ossl_pkey_ec.c +126 -318
  26. data/ext/openssl/ossl_pkey_rsa.c +100 -487
  27. data/ext/openssl/ossl_ssl.c +256 -355
  28. data/ext/openssl/ossl_ssl_session.c +24 -29
  29. data/ext/openssl/ossl_ts.c +35 -20
  30. data/ext/openssl/ossl_x509.c +0 -6
  31. data/ext/openssl/ossl_x509cert.c +164 -8
  32. data/ext/openssl/ossl_x509crl.c +10 -7
  33. data/ext/openssl/ossl_x509ext.c +1 -2
  34. data/ext/openssl/ossl_x509name.c +9 -2
  35. data/ext/openssl/ossl_x509req.c +10 -7
  36. data/ext/openssl/ossl_x509store.c +154 -70
  37. data/lib/openssl/buffering.rb +9 -0
  38. data/lib/openssl/hmac.rb +65 -0
  39. data/lib/openssl/pkey.rb +417 -0
  40. data/lib/openssl/ssl.rb +7 -7
  41. data/lib/openssl/version.rb +1 -1
  42. data/lib/openssl/x509.rb +22 -0
  43. data/lib/openssl.rb +0 -1
  44. metadata +4 -76
  45. data/ext/openssl/ruby_missing.h +0 -24
  46. data/lib/openssl/config.rb +0 -501
@@ -7,14 +7,12 @@
7
7
  * This program is licensed under the same licence as Ruby.
8
8
  * (See the file 'LICENCE'.)
9
9
  */
10
- #if !defined(OPENSSL_NO_HMAC)
11
-
12
10
  #include "ossl.h"
13
11
 
14
12
  #define NewHMAC(klass) \
15
13
  TypedData_Wrap_Struct((klass), &ossl_hmac_type, 0)
16
14
  #define GetHMAC(obj, ctx) do { \
17
- TypedData_Get_Struct((obj), HMAC_CTX, &ossl_hmac_type, (ctx)); \
15
+ TypedData_Get_Struct((obj), EVP_MD_CTX, &ossl_hmac_type, (ctx)); \
18
16
  if (!(ctx)) { \
19
17
  ossl_raise(rb_eRuntimeError, "HMAC wasn't initialized"); \
20
18
  } \
@@ -36,7 +34,7 @@ VALUE eHMACError;
36
34
  static void
37
35
  ossl_hmac_free(void *ctx)
38
36
  {
39
- HMAC_CTX_free(ctx);
37
+ EVP_MD_CTX_free(ctx);
40
38
  }
41
39
 
42
40
  static const rb_data_type_t ossl_hmac_type = {
@@ -51,12 +49,12 @@ static VALUE
51
49
  ossl_hmac_alloc(VALUE klass)
52
50
  {
53
51
  VALUE obj;
54
- HMAC_CTX *ctx;
52
+ EVP_MD_CTX *ctx;
55
53
 
56
54
  obj = NewHMAC(klass);
57
- ctx = HMAC_CTX_new();
55
+ ctx = EVP_MD_CTX_new();
58
56
  if (!ctx)
59
- ossl_raise(eHMACError, NULL);
57
+ ossl_raise(eHMACError, "EVP_MD_CTX");
60
58
  RTYPEDDATA_DATA(obj) = ctx;
61
59
 
62
60
  return obj;
@@ -76,8 +74,7 @@ ossl_hmac_alloc(VALUE klass)
76
74
  * === Example
77
75
  *
78
76
  * key = 'key'
79
- * digest = OpenSSL::Digest.new('sha1')
80
- * instance = OpenSSL::HMAC.new(key, digest)
77
+ * instance = OpenSSL::HMAC.new(key, 'SHA1')
81
78
  * #=> f42bb0eeb018ebbd4597ae7213711ec60760843f
82
79
  * instance.class
83
80
  * #=> OpenSSL::HMAC
@@ -86,7 +83,7 @@ ossl_hmac_alloc(VALUE klass)
86
83
  *
87
84
  * Two instances can be securely compared with #== in constant time:
88
85
  *
89
- * other_instance = OpenSSL::HMAC.new('key', OpenSSL::Digest.new('sha1'))
86
+ * other_instance = OpenSSL::HMAC.new('key', 'SHA1')
90
87
  * #=> f42bb0eeb018ebbd4597ae7213711ec60760843f
91
88
  * instance == other_instance
92
89
  * #=> true
@@ -95,12 +92,23 @@ ossl_hmac_alloc(VALUE klass)
95
92
  static VALUE
96
93
  ossl_hmac_initialize(VALUE self, VALUE key, VALUE digest)
97
94
  {
98
- HMAC_CTX *ctx;
95
+ EVP_MD_CTX *ctx;
96
+ EVP_PKEY *pkey;
99
97
 
100
- StringValue(key);
101
98
  GetHMAC(self, ctx);
102
- HMAC_Init_ex(ctx, RSTRING_PTR(key), RSTRING_LENINT(key),
103
- ossl_evp_get_digestbyname(digest), NULL);
99
+ StringValue(key);
100
+ pkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL,
101
+ (unsigned char *)RSTRING_PTR(key),
102
+ RSTRING_LENINT(key));
103
+ if (!pkey)
104
+ ossl_raise(eHMACError, "EVP_PKEY_new_mac_key");
105
+ if (EVP_DigestSignInit(ctx, NULL, ossl_evp_get_digestbyname(digest),
106
+ NULL, pkey) != 1) {
107
+ EVP_PKEY_free(pkey);
108
+ ossl_raise(eHMACError, "EVP_DigestSignInit");
109
+ }
110
+ /* Decrement reference counter; EVP_MD_CTX still keeps it */
111
+ EVP_PKEY_free(pkey);
104
112
 
105
113
  return self;
106
114
  }
@@ -108,16 +116,15 @@ ossl_hmac_initialize(VALUE self, VALUE key, VALUE digest)
108
116
  static VALUE
109
117
  ossl_hmac_copy(VALUE self, VALUE other)
110
118
  {
111
- HMAC_CTX *ctx1, *ctx2;
119
+ EVP_MD_CTX *ctx1, *ctx2;
112
120
 
113
121
  rb_check_frozen(self);
114
122
  if (self == other) return self;
115
123
 
116
124
  GetHMAC(self, ctx1);
117
125
  GetHMAC(other, ctx2);
118
-
119
- if (!HMAC_CTX_copy(ctx1, ctx2))
120
- ossl_raise(eHMACError, "HMAC_CTX_copy");
126
+ if (EVP_MD_CTX_copy(ctx1, ctx2) != 1)
127
+ ossl_raise(eHMACError, "EVP_MD_CTX_copy");
121
128
  return self;
122
129
  }
123
130
 
@@ -142,33 +149,16 @@ ossl_hmac_copy(VALUE self, VALUE other)
142
149
  static VALUE
143
150
  ossl_hmac_update(VALUE self, VALUE data)
144
151
  {
145
- HMAC_CTX *ctx;
152
+ EVP_MD_CTX *ctx;
146
153
 
147
154
  StringValue(data);
148
155
  GetHMAC(self, ctx);
149
- HMAC_Update(ctx, (unsigned char *)RSTRING_PTR(data), RSTRING_LEN(data));
156
+ if (EVP_DigestSignUpdate(ctx, RSTRING_PTR(data), RSTRING_LEN(data)) != 1)
157
+ ossl_raise(eHMACError, "EVP_DigestSignUpdate");
150
158
 
151
159
  return self;
152
160
  }
153
161
 
154
- static void
155
- hmac_final(HMAC_CTX *ctx, unsigned char *buf, unsigned int *buf_len)
156
- {
157
- HMAC_CTX *final;
158
-
159
- final = HMAC_CTX_new();
160
- if (!final)
161
- ossl_raise(eHMACError, "HMAC_CTX_new");
162
-
163
- if (!HMAC_CTX_copy(final, ctx)) {
164
- HMAC_CTX_free(final);
165
- ossl_raise(eHMACError, "HMAC_CTX_copy");
166
- }
167
-
168
- HMAC_Final(final, buf, buf_len);
169
- HMAC_CTX_free(final);
170
- }
171
-
172
162
  /*
173
163
  * call-seq:
174
164
  * hmac.digest -> string
@@ -176,7 +166,7 @@ hmac_final(HMAC_CTX *ctx, unsigned char *buf, unsigned int *buf_len)
176
166
  * Returns the authentication code an instance represents as a binary string.
177
167
  *
178
168
  * === Example
179
- * instance = OpenSSL::HMAC.new('key', OpenSSL::Digest.new('sha1'))
169
+ * instance = OpenSSL::HMAC.new('key', 'SHA1')
180
170
  * #=> f42bb0eeb018ebbd4597ae7213711ec60760843f
181
171
  * instance.digest
182
172
  * #=> "\xF4+\xB0\xEE\xB0\x18\xEB\xBDE\x97\xAEr\x13q\x1E\xC6\a`\x84?"
@@ -184,15 +174,16 @@ hmac_final(HMAC_CTX *ctx, unsigned char *buf, unsigned int *buf_len)
184
174
  static VALUE
185
175
  ossl_hmac_digest(VALUE self)
186
176
  {
187
- HMAC_CTX *ctx;
188
- unsigned int buf_len;
177
+ EVP_MD_CTX *ctx;
178
+ size_t buf_len = EVP_MAX_MD_SIZE;
189
179
  VALUE ret;
190
180
 
191
181
  GetHMAC(self, ctx);
192
182
  ret = rb_str_new(NULL, EVP_MAX_MD_SIZE);
193
- hmac_final(ctx, (unsigned char *)RSTRING_PTR(ret), &buf_len);
194
- assert(buf_len <= EVP_MAX_MD_SIZE);
195
- rb_str_set_len(ret, buf_len);
183
+ if (EVP_DigestSignFinal(ctx, (unsigned char *)RSTRING_PTR(ret),
184
+ &buf_len) != 1)
185
+ ossl_raise(eHMACError, "EVP_DigestSignFinal");
186
+ rb_str_set_len(ret, (long)buf_len);
196
187
 
197
188
  return ret;
198
189
  }
@@ -207,13 +198,14 @@ ossl_hmac_digest(VALUE self)
207
198
  static VALUE
208
199
  ossl_hmac_hexdigest(VALUE self)
209
200
  {
210
- HMAC_CTX *ctx;
201
+ EVP_MD_CTX *ctx;
211
202
  unsigned char buf[EVP_MAX_MD_SIZE];
212
- unsigned int buf_len;
203
+ size_t buf_len = EVP_MAX_MD_SIZE;
213
204
  VALUE ret;
214
205
 
215
206
  GetHMAC(self, ctx);
216
- hmac_final(ctx, buf, &buf_len);
207
+ if (EVP_DigestSignFinal(ctx, buf, &buf_len) != 1)
208
+ ossl_raise(eHMACError, "EVP_DigestSignFinal");
217
209
  ret = rb_str_new(NULL, buf_len * 2);
218
210
  ossl_bin2hex(buf, RSTRING_PTR(ret), buf_len);
219
211
 
@@ -230,7 +222,7 @@ ossl_hmac_hexdigest(VALUE self)
230
222
  * === Example
231
223
  *
232
224
  * data = "The quick brown fox jumps over the lazy dog"
233
- * instance = OpenSSL::HMAC.new('key', OpenSSL::Digest.new('sha1'))
225
+ * instance = OpenSSL::HMAC.new('key', 'SHA1')
234
226
  * #=> f42bb0eeb018ebbd4597ae7213711ec60760843f
235
227
  *
236
228
  * instance.update(data)
@@ -242,84 +234,17 @@ ossl_hmac_hexdigest(VALUE self)
242
234
  static VALUE
243
235
  ossl_hmac_reset(VALUE self)
244
236
  {
245
- HMAC_CTX *ctx;
237
+ EVP_MD_CTX *ctx;
238
+ EVP_PKEY *pkey;
246
239
 
247
240
  GetHMAC(self, ctx);
248
- HMAC_Init_ex(ctx, NULL, 0, NULL, NULL);
241
+ pkey = EVP_PKEY_CTX_get0_pkey(EVP_MD_CTX_get_pkey_ctx(ctx));
242
+ if (EVP_DigestSignInit(ctx, NULL, EVP_MD_CTX_get0_md(ctx), NULL, pkey) != 1)
243
+ ossl_raise(eHMACError, "EVP_DigestSignInit");
249
244
 
250
245
  return self;
251
246
  }
252
247
 
253
- /*
254
- * call-seq:
255
- * HMAC.digest(digest, key, data) -> aString
256
- *
257
- * Returns the authentication code as a binary string. The _digest_ parameter
258
- * specifies the digest algorithm to use. This may be a String representing
259
- * the algorithm name or an instance of OpenSSL::Digest.
260
- *
261
- * === Example
262
- *
263
- * key = 'key'
264
- * data = 'The quick brown fox jumps over the lazy dog'
265
- *
266
- * hmac = OpenSSL::HMAC.digest('sha1', key, data)
267
- * #=> "\xDE|\x9B\x85\xB8\xB7\x8A\xA6\xBC\x8Az6\xF7\n\x90p\x1C\x9D\xB4\xD9"
268
- *
269
- */
270
- static VALUE
271
- ossl_hmac_s_digest(VALUE klass, VALUE digest, VALUE key, VALUE data)
272
- {
273
- unsigned char *buf;
274
- unsigned int buf_len;
275
-
276
- StringValue(key);
277
- StringValue(data);
278
- buf = HMAC(ossl_evp_get_digestbyname(digest), RSTRING_PTR(key),
279
- RSTRING_LENINT(key), (unsigned char *)RSTRING_PTR(data),
280
- RSTRING_LEN(data), NULL, &buf_len);
281
-
282
- return rb_str_new((const char *)buf, buf_len);
283
- }
284
-
285
- /*
286
- * call-seq:
287
- * HMAC.hexdigest(digest, key, data) -> aString
288
- *
289
- * Returns the authentication code as a hex-encoded string. The _digest_
290
- * parameter specifies the digest algorithm to use. This may be a String
291
- * representing the algorithm name or an instance of OpenSSL::Digest.
292
- *
293
- * === Example
294
- *
295
- * key = 'key'
296
- * data = 'The quick brown fox jumps over the lazy dog'
297
- *
298
- * hmac = OpenSSL::HMAC.hexdigest('sha1', key, data)
299
- * #=> "de7c9b85b8b78aa6bc8a7a36f70a90701c9db4d9"
300
- *
301
- */
302
- static VALUE
303
- ossl_hmac_s_hexdigest(VALUE klass, VALUE digest, VALUE key, VALUE data)
304
- {
305
- unsigned char buf[EVP_MAX_MD_SIZE];
306
- unsigned int buf_len;
307
- VALUE ret;
308
-
309
- StringValue(key);
310
- StringValue(data);
311
-
312
- if (!HMAC(ossl_evp_get_digestbyname(digest), RSTRING_PTR(key),
313
- RSTRING_LENINT(key), (unsigned char *)RSTRING_PTR(data),
314
- RSTRING_LEN(data), buf, &buf_len))
315
- ossl_raise(eHMACError, "HMAC");
316
-
317
- ret = rb_str_new(NULL, buf_len * 2);
318
- ossl_bin2hex(buf, RSTRING_PTR(ret), buf_len);
319
-
320
- return ret;
321
- }
322
-
323
248
  /*
324
249
  * INIT
325
250
  */
@@ -350,11 +275,10 @@ Init_ossl_hmac(void)
350
275
  *
351
276
  * === HMAC-SHA256 using incremental interface
352
277
  *
353
- * data1 = File.read("file1")
354
- * data2 = File.read("file2")
278
+ * data1 = File.binread("file1")
279
+ * data2 = File.binread("file2")
355
280
  * key = "key"
356
- * digest = OpenSSL::Digest.new('SHA256')
357
- * hmac = OpenSSL::HMAC.new(key, digest)
281
+ * hmac = OpenSSL::HMAC.new(key, 'SHA256')
358
282
  * hmac << data1
359
283
  * hmac << data2
360
284
  * mac = hmac.digest
@@ -364,8 +288,6 @@ Init_ossl_hmac(void)
364
288
  cHMAC = rb_define_class_under(mOSSL, "HMAC", rb_cObject);
365
289
 
366
290
  rb_define_alloc_func(cHMAC, ossl_hmac_alloc);
367
- rb_define_singleton_method(cHMAC, "digest", ossl_hmac_s_digest, 3);
368
- rb_define_singleton_method(cHMAC, "hexdigest", ossl_hmac_s_hexdigest, 3);
369
291
 
370
292
  rb_define_method(cHMAC, "initialize", ossl_hmac_initialize, 2);
371
293
  rb_define_method(cHMAC, "initialize_copy", ossl_hmac_copy, 1);
@@ -378,12 +300,3 @@ Init_ossl_hmac(void)
378
300
  rb_define_alias(cHMAC, "inspect", "hexdigest");
379
301
  rb_define_alias(cHMAC, "to_s", "hexdigest");
380
302
  }
381
-
382
- #else /* NO_HMAC */
383
- # warning >>> OpenSSL is compiled without HMAC support <<<
384
- void
385
- Init_ossl_hmac(void)
386
- {
387
- rb_warning("HMAC is not available: OpenSSL is compiled without HMAC.");
388
- }
389
- #endif /* NO_HMAC */
@@ -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)
@@ -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)
@@ -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
  *
@@ -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();
@@ -1787,7 +1739,7 @@ Init_ossl_ocsp(void)
1787
1739
  * single_response = basic_response.find_response(certificate_id)
1788
1740
  *
1789
1741
  * unless single_response
1790
- * raise 'basic_response does not have the status for the certificiate'
1742
+ * raise 'basic_response does not have the status for the certificate'
1791
1743
  * end
1792
1744
  *
1793
1745
  * Then check the validity. A status issued in the future must be rejected.
@@ -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
 
@@ -101,19 +101,24 @@ static const rb_data_type_t ossl_pkcs7_recip_info_type = {
101
101
  * (MADE PRIVATE UNTIL SOMEBODY WILL NEED THEM)
102
102
  */
103
103
  static PKCS7_SIGNER_INFO *
104
- ossl_PKCS7_SIGNER_INFO_dup(const PKCS7_SIGNER_INFO *si)
104
+ ossl_PKCS7_SIGNER_INFO_dup(PKCS7_SIGNER_INFO *si)
105
105
  {
106
- return (PKCS7_SIGNER_INFO *)ASN1_dup((i2d_of_void *)i2d_PKCS7_SIGNER_INFO,
107
- (d2i_of_void *)d2i_PKCS7_SIGNER_INFO,
108
- (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;
109
114
  }
110
115
 
111
116
  static PKCS7_RECIP_INFO *
112
- ossl_PKCS7_RECIP_INFO_dup(const PKCS7_RECIP_INFO *si)
117
+ ossl_PKCS7_RECIP_INFO_dup(PKCS7_RECIP_INFO *si)
113
118
  {
114
- return (PKCS7_RECIP_INFO *)ASN1_dup((i2d_of_void *)i2d_PKCS7_RECIP_INFO,
115
- (d2i_of_void *)d2i_PKCS7_RECIP_INFO,
116
- (char *)si);
119
+ return ASN1_dup((i2d_of_void *)i2d_PKCS7_RECIP_INFO,
120
+ (d2i_of_void *)d2i_PKCS7_RECIP_INFO,
121
+ si);
117
122
  }
118
123
 
119
124
  static VALUE
@@ -130,19 +135,6 @@ ossl_pkcs7si_new(PKCS7_SIGNER_INFO *p7si)
130
135
  return obj;
131
136
  }
132
137
 
133
- static PKCS7_SIGNER_INFO *
134
- DupPKCS7SignerPtr(VALUE obj)
135
- {
136
- PKCS7_SIGNER_INFO *p7si, *pkcs7;
137
-
138
- GetPKCS7si(obj, p7si);
139
- if (!(pkcs7 = ossl_PKCS7_SIGNER_INFO_dup(p7si))) {
140
- ossl_raise(ePKCS7Error, NULL);
141
- }
142
-
143
- return pkcs7;
144
- }
145
-
146
138
  static VALUE
147
139
  ossl_pkcs7ri_new(PKCS7_RECIP_INFO *p7ri)
148
140
  {
@@ -157,19 +149,6 @@ ossl_pkcs7ri_new(PKCS7_RECIP_INFO *p7ri)
157
149
  return obj;
158
150
  }
159
151
 
160
- static PKCS7_RECIP_INFO *
161
- DupPKCS7RecipientPtr(VALUE obj)
162
- {
163
- PKCS7_RECIP_INFO *p7ri, *pkcs7;
164
-
165
- GetPKCS7ri(obj, p7ri);
166
- if (!(pkcs7 = ossl_PKCS7_RECIP_INFO_dup(p7ri))) {
167
- ossl_raise(ePKCS7Error, NULL);
168
- }
169
-
170
- return pkcs7;
171
- }
172
-
173
152
  /*
174
153
  * call-seq:
175
154
  * PKCS7.read_smime(string) => pkcs7
@@ -351,7 +330,7 @@ ossl_pkcs7_alloc(VALUE klass)
351
330
  static VALUE
352
331
  ossl_pkcs7_initialize(int argc, VALUE *argv, VALUE self)
353
332
  {
354
- PKCS7 *p7, *pkcs = DATA_PTR(self);
333
+ PKCS7 *p7, *p7_orig = RTYPEDDATA_DATA(self);
355
334
  BIO *in;
356
335
  VALUE arg;
357
336
 
@@ -359,19 +338,17 @@ ossl_pkcs7_initialize(int argc, VALUE *argv, VALUE self)
359
338
  return self;
360
339
  arg = ossl_to_der_if_possible(arg);
361
340
  in = ossl_obj2bio(&arg);
362
- p7 = PEM_read_bio_PKCS7(in, &pkcs, NULL, NULL);
341
+ p7 = d2i_PKCS7_bio(in, NULL);
363
342
  if (!p7) {
364
- OSSL_BIO_reset(in);
365
- p7 = d2i_PKCS7_bio(in, &pkcs);
366
- if (!p7) {
367
- BIO_free(in);
368
- PKCS7_free(pkcs);
369
- DATA_PTR(self) = NULL;
370
- ossl_raise(rb_eArgError, "Could not parse the PKCS7");
371
- }
343
+ OSSL_BIO_reset(in);
344
+ p7 = PEM_read_bio_PKCS7(in, NULL, NULL, NULL);
372
345
  }
373
- DATA_PTR(self) = pkcs;
374
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);
375
352
  ossl_pkcs7_set_data(self, Qnil);
376
353
  ossl_pkcs7_set_err_string(self, Qnil);
377
354
 
@@ -521,17 +498,18 @@ static VALUE
521
498
  ossl_pkcs7_add_signer(VALUE self, VALUE signer)
522
499
  {
523
500
  PKCS7 *pkcs7;
524
- PKCS7_SIGNER_INFO *p7si;
501
+ PKCS7_SIGNER_INFO *si, *si_new;
525
502
 
526
- p7si = DupPKCS7SignerPtr(signer); /* NEED TO DUP */
527
503
  GetPKCS7(self, pkcs7);
528
- if (!PKCS7_add_signer(pkcs7, p7si)) {
529
- PKCS7_SIGNER_INFO_free(p7si);
530
- ossl_raise(ePKCS7Error, "Could not add signer.");
531
- }
532
- if (PKCS7_type_is_signed(pkcs7)){
533
- PKCS7_add_signed_attribute(p7si, NID_pkcs9_contentType,
534
- 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");
535
513
  }
536
514
 
537
515
  return self;
@@ -567,13 +545,18 @@ static VALUE
567
545
  ossl_pkcs7_add_recipient(VALUE self, VALUE recip)
568
546
  {
569
547
  PKCS7 *pkcs7;
570
- PKCS7_RECIP_INFO *ri;
548
+ PKCS7_RECIP_INFO *ri, *ri_new;
571
549
 
572
- ri = DupPKCS7RecipientPtr(recip); /* NEED TO DUP */
573
550
  GetPKCS7(self, pkcs7);
574
- if (!PKCS7_add_recipient_info(pkcs7, ri)) {
575
- PKCS7_RECIP_INFO_free(ri);
576
- 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");
577
560
  }
578
561
 
579
562
  return self;