openssl 2.2.0 → 3.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.md +33 -45
  3. data/History.md +260 -0
  4. data/ext/openssl/extconf.rb +85 -72
  5. data/ext/openssl/openssl_missing.c +0 -66
  6. data/ext/openssl/openssl_missing.h +26 -45
  7. data/ext/openssl/ossl.c +67 -47
  8. data/ext/openssl/ossl.h +26 -6
  9. data/ext/openssl/ossl_asn1.c +26 -13
  10. data/ext/openssl/ossl_bn.c +278 -142
  11. data/ext/openssl/ossl_bn.h +2 -1
  12. data/ext/openssl/ossl_cipher.c +12 -13
  13. data/ext/openssl/ossl_config.c +412 -41
  14. data/ext/openssl/ossl_config.h +4 -7
  15. data/ext/openssl/ossl_digest.c +15 -11
  16. data/ext/openssl/ossl_engine.c +16 -15
  17. data/ext/openssl/ossl_hmac.c +56 -135
  18. data/ext/openssl/ossl_kdf.c +11 -3
  19. data/ext/openssl/ossl_ocsp.c +5 -53
  20. data/ext/openssl/ossl_pkcs12.c +21 -3
  21. data/ext/openssl/ossl_pkcs7.c +42 -59
  22. data/ext/openssl/ossl_pkey.c +1142 -191
  23. data/ext/openssl/ossl_pkey.h +36 -73
  24. data/ext/openssl/ossl_pkey_dh.c +130 -340
  25. data/ext/openssl/ossl_pkey_dsa.c +100 -405
  26. data/ext/openssl/ossl_pkey_ec.c +163 -335
  27. data/ext/openssl/ossl_pkey_rsa.c +106 -493
  28. data/ext/openssl/ossl_ssl.c +529 -421
  29. data/ext/openssl/ossl_ssl_session.c +28 -29
  30. data/ext/openssl/ossl_ts.c +64 -39
  31. data/ext/openssl/ossl_x509.c +0 -6
  32. data/ext/openssl/ossl_x509cert.c +167 -11
  33. data/ext/openssl/ossl_x509crl.c +13 -10
  34. data/ext/openssl/ossl_x509ext.c +1 -2
  35. data/ext/openssl/ossl_x509name.c +9 -2
  36. data/ext/openssl/ossl_x509req.c +13 -10
  37. data/ext/openssl/ossl_x509revoked.c +3 -3
  38. data/ext/openssl/ossl_x509store.c +193 -90
  39. data/lib/openssl/buffering.rb +10 -1
  40. data/lib/openssl/hmac.rb +65 -0
  41. data/lib/openssl/pkey.rb +429 -0
  42. data/lib/openssl/ssl.rb +13 -8
  43. data/lib/openssl/version.rb +1 -1
  44. data/lib/openssl/x509.rb +22 -0
  45. data/lib/openssl.rb +0 -1
  46. metadata +8 -66
  47. data/ext/openssl/ruby_missing.h +0 -24
  48. 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,31 @@ 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
+ #ifdef HAVE_EVP_PKEY_NEW_RAW_PRIVATE_KEY
101
+ pkey = EVP_PKEY_new_raw_private_key(EVP_PKEY_HMAC, NULL,
102
+ (unsigned char *)RSTRING_PTR(key),
103
+ RSTRING_LENINT(key));
104
+ if (!pkey)
105
+ ossl_raise(eHMACError, "EVP_PKEY_new_raw_private_key");
106
+ #else
107
+ pkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL,
108
+ (unsigned char *)RSTRING_PTR(key),
109
+ RSTRING_LENINT(key));
110
+ if (!pkey)
111
+ ossl_raise(eHMACError, "EVP_PKEY_new_mac_key");
112
+ #endif
113
+ if (EVP_DigestSignInit(ctx, NULL, ossl_evp_get_digestbyname(digest),
114
+ NULL, pkey) != 1) {
115
+ EVP_PKEY_free(pkey);
116
+ ossl_raise(eHMACError, "EVP_DigestSignInit");
117
+ }
118
+ /* Decrement reference counter; EVP_MD_CTX still keeps it */
119
+ EVP_PKEY_free(pkey);
104
120
 
105
121
  return self;
106
122
  }
@@ -108,16 +124,15 @@ ossl_hmac_initialize(VALUE self, VALUE key, VALUE digest)
108
124
  static VALUE
109
125
  ossl_hmac_copy(VALUE self, VALUE other)
110
126
  {
111
- HMAC_CTX *ctx1, *ctx2;
127
+ EVP_MD_CTX *ctx1, *ctx2;
112
128
 
113
129
  rb_check_frozen(self);
114
130
  if (self == other) return self;
115
131
 
116
132
  GetHMAC(self, ctx1);
117
133
  GetHMAC(other, ctx2);
118
-
119
- if (!HMAC_CTX_copy(ctx1, ctx2))
120
- ossl_raise(eHMACError, "HMAC_CTX_copy");
134
+ if (EVP_MD_CTX_copy(ctx1, ctx2) != 1)
135
+ ossl_raise(eHMACError, "EVP_MD_CTX_copy");
121
136
  return self;
122
137
  }
123
138
 
@@ -142,33 +157,16 @@ ossl_hmac_copy(VALUE self, VALUE other)
142
157
  static VALUE
143
158
  ossl_hmac_update(VALUE self, VALUE data)
144
159
  {
145
- HMAC_CTX *ctx;
160
+ EVP_MD_CTX *ctx;
146
161
 
147
162
  StringValue(data);
148
163
  GetHMAC(self, ctx);
149
- HMAC_Update(ctx, (unsigned char *)RSTRING_PTR(data), RSTRING_LEN(data));
164
+ if (EVP_DigestSignUpdate(ctx, RSTRING_PTR(data), RSTRING_LEN(data)) != 1)
165
+ ossl_raise(eHMACError, "EVP_DigestSignUpdate");
150
166
 
151
167
  return self;
152
168
  }
153
169
 
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
170
  /*
173
171
  * call-seq:
174
172
  * hmac.digest -> string
@@ -176,7 +174,7 @@ hmac_final(HMAC_CTX *ctx, unsigned char *buf, unsigned int *buf_len)
176
174
  * Returns the authentication code an instance represents as a binary string.
177
175
  *
178
176
  * === Example
179
- * instance = OpenSSL::HMAC.new('key', OpenSSL::Digest.new('sha1'))
177
+ * instance = OpenSSL::HMAC.new('key', 'SHA1')
180
178
  * #=> f42bb0eeb018ebbd4597ae7213711ec60760843f
181
179
  * instance.digest
182
180
  * #=> "\xF4+\xB0\xEE\xB0\x18\xEB\xBDE\x97\xAEr\x13q\x1E\xC6\a`\x84?"
@@ -184,15 +182,16 @@ hmac_final(HMAC_CTX *ctx, unsigned char *buf, unsigned int *buf_len)
184
182
  static VALUE
185
183
  ossl_hmac_digest(VALUE self)
186
184
  {
187
- HMAC_CTX *ctx;
188
- unsigned int buf_len;
185
+ EVP_MD_CTX *ctx;
186
+ size_t buf_len = EVP_MAX_MD_SIZE;
189
187
  VALUE ret;
190
188
 
191
189
  GetHMAC(self, ctx);
192
190
  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);
191
+ if (EVP_DigestSignFinal(ctx, (unsigned char *)RSTRING_PTR(ret),
192
+ &buf_len) != 1)
193
+ ossl_raise(eHMACError, "EVP_DigestSignFinal");
194
+ rb_str_set_len(ret, (long)buf_len);
196
195
 
197
196
  return ret;
198
197
  }
@@ -207,13 +206,14 @@ ossl_hmac_digest(VALUE self)
207
206
  static VALUE
208
207
  ossl_hmac_hexdigest(VALUE self)
209
208
  {
210
- HMAC_CTX *ctx;
209
+ EVP_MD_CTX *ctx;
211
210
  unsigned char buf[EVP_MAX_MD_SIZE];
212
- unsigned int buf_len;
211
+ size_t buf_len = EVP_MAX_MD_SIZE;
213
212
  VALUE ret;
214
213
 
215
214
  GetHMAC(self, ctx);
216
- hmac_final(ctx, buf, &buf_len);
215
+ if (EVP_DigestSignFinal(ctx, buf, &buf_len) != 1)
216
+ ossl_raise(eHMACError, "EVP_DigestSignFinal");
217
217
  ret = rb_str_new(NULL, buf_len * 2);
218
218
  ossl_bin2hex(buf, RSTRING_PTR(ret), buf_len);
219
219
 
@@ -230,7 +230,7 @@ ossl_hmac_hexdigest(VALUE self)
230
230
  * === Example
231
231
  *
232
232
  * data = "The quick brown fox jumps over the lazy dog"
233
- * instance = OpenSSL::HMAC.new('key', OpenSSL::Digest.new('sha1'))
233
+ * instance = OpenSSL::HMAC.new('key', 'SHA1')
234
234
  * #=> f42bb0eeb018ebbd4597ae7213711ec60760843f
235
235
  *
236
236
  * instance.update(data)
@@ -242,84 +242,17 @@ ossl_hmac_hexdigest(VALUE self)
242
242
  static VALUE
243
243
  ossl_hmac_reset(VALUE self)
244
244
  {
245
- HMAC_CTX *ctx;
245
+ EVP_MD_CTX *ctx;
246
+ EVP_PKEY *pkey;
246
247
 
247
248
  GetHMAC(self, ctx);
248
- HMAC_Init_ex(ctx, NULL, 0, NULL, NULL);
249
+ pkey = EVP_PKEY_CTX_get0_pkey(EVP_MD_CTX_get_pkey_ctx(ctx));
250
+ if (EVP_DigestSignInit(ctx, NULL, EVP_MD_CTX_get0_md(ctx), NULL, pkey) != 1)
251
+ ossl_raise(eHMACError, "EVP_DigestSignInit");
249
252
 
250
253
  return self;
251
254
  }
252
255
 
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
256
  /*
324
257
  * INIT
325
258
  */
@@ -350,11 +283,10 @@ Init_ossl_hmac(void)
350
283
  *
351
284
  * === HMAC-SHA256 using incremental interface
352
285
  *
353
- * data1 = File.read("file1")
354
- * data2 = File.read("file2")
286
+ * data1 = File.binread("file1")
287
+ * data2 = File.binread("file2")
355
288
  * key = "key"
356
- * digest = OpenSSL::Digest.new('SHA256')
357
- * hmac = OpenSSL::HMAC.new(key, digest)
289
+ * hmac = OpenSSL::HMAC.new(key, 'SHA256')
358
290
  * hmac << data1
359
291
  * hmac << data2
360
292
  * mac = hmac.digest
@@ -364,8 +296,6 @@ Init_ossl_hmac(void)
364
296
  cHMAC = rb_define_class_under(mOSSL, "HMAC", rb_cObject);
365
297
 
366
298
  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
299
 
370
300
  rb_define_method(cHMAC, "initialize", ossl_hmac_initialize, 2);
371
301
  rb_define_method(cHMAC, "initialize_copy", ossl_hmac_copy, 1);
@@ -378,12 +308,3 @@ Init_ossl_hmac(void)
378
308
  rb_define_alias(cHMAC, "inspect", "hexdigest");
379
309
  rb_define_alias(cHMAC, "to_s", "hexdigest");
380
310
  }
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 */
@@ -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
 
@@ -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)
@@ -297,7 +305,7 @@ Init_ossl_kdf(void)
297
305
  #if defined(HAVE_EVP_PBE_SCRYPT)
298
306
  rb_define_module_function(mKDF, "scrypt", kdf_scrypt, -1);
299
307
  #endif
300
- #if OPENSSL_VERSION_NUMBER >= 0x10100000 && !defined(LIBRESSL_VERSION_NUMBER)
308
+ #if OSSL_OPENSSL_PREREQ(1, 1, 0) || OSSL_LIBRESSL_PREREQ(3, 6, 0)
301
309
  rb_define_module_function(mKDF, "hkdf", kdf_hkdf, -1);
302
310
  #endif
303
311
  }
@@ -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();
@@ -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;