openssl 3.0.2 → 3.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.md +1 -1
  3. data/History.md +76 -0
  4. data/README.md +36 -19
  5. data/ext/openssl/extconf.rb +89 -55
  6. data/ext/openssl/ossl.c +73 -195
  7. data/ext/openssl/ossl.h +11 -6
  8. data/ext/openssl/ossl_asn1.c +11 -10
  9. data/ext/openssl/ossl_bn.c +25 -13
  10. data/ext/openssl/ossl_cipher.c +2 -3
  11. data/ext/openssl/ossl_config.c +1 -1
  12. data/ext/openssl/ossl_digest.c +1 -1
  13. data/ext/openssl/ossl_engine.c +1 -1
  14. data/ext/openssl/ossl_hmac.c +1 -1
  15. data/ext/openssl/ossl_kdf.c +4 -4
  16. data/ext/openssl/ossl_ns_spki.c +1 -1
  17. data/ext/openssl/ossl_ocsp.c +8 -8
  18. data/ext/openssl/ossl_pkcs12.c +1 -1
  19. data/ext/openssl/ossl_pkcs7.c +3 -3
  20. data/ext/openssl/ossl_pkey.c +219 -46
  21. data/ext/openssl/ossl_pkey.h +1 -1
  22. data/ext/openssl/ossl_pkey_dh.c +28 -13
  23. data/ext/openssl/ossl_pkey_dsa.c +64 -15
  24. data/ext/openssl/ossl_pkey_ec.c +73 -17
  25. data/ext/openssl/ossl_pkey_rsa.c +74 -19
  26. data/ext/openssl/ossl_provider.c +211 -0
  27. data/ext/openssl/ossl_provider.h +5 -0
  28. data/ext/openssl/ossl_ssl.c +292 -113
  29. data/ext/openssl/ossl_ssl_session.c +5 -1
  30. data/ext/openssl/ossl_ts.c +3 -3
  31. data/ext/openssl/ossl_x509attr.c +1 -1
  32. data/ext/openssl/ossl_x509cert.c +1 -1
  33. data/ext/openssl/ossl_x509crl.c +1 -1
  34. data/ext/openssl/ossl_x509ext.c +13 -7
  35. data/ext/openssl/ossl_x509name.c +1 -1
  36. data/ext/openssl/ossl_x509req.c +1 -1
  37. data/ext/openssl/ossl_x509revoked.c +1 -1
  38. data/ext/openssl/ossl_x509store.c +12 -5
  39. data/lib/openssl/buffering.rb +2 -5
  40. data/lib/openssl/digest.rb +1 -5
  41. data/lib/openssl/pkey.rb +8 -4
  42. data/lib/openssl/ssl.rb +15 -10
  43. data/lib/openssl/version.rb +1 -1
  44. metadata +9 -6
@@ -24,7 +24,7 @@
24
24
  } while (0)
25
25
 
26
26
  static inline int
27
- DSA_HAS_PRIVATE(DSA *dsa)
27
+ DSA_HAS_PRIVATE(OSSL_3_const DSA *dsa)
28
28
  {
29
29
  const BIGNUM *bn;
30
30
  DSA_get0_key(dsa, NULL, &bn);
@@ -32,7 +32,7 @@ DSA_HAS_PRIVATE(DSA *dsa)
32
32
  }
33
33
 
34
34
  static inline int
35
- DSA_PRIVATE(VALUE obj, DSA *dsa)
35
+ DSA_PRIVATE(VALUE obj, OSSL_3_const DSA *dsa)
36
36
  {
37
37
  return DSA_HAS_PRIVATE(dsa) || OSSL_PKEY_IS_PRIVATE(obj);
38
38
  }
@@ -179,7 +179,7 @@ ossl_dsa_initialize_copy(VALUE self, VALUE other)
179
179
  static VALUE
180
180
  ossl_dsa_is_public(VALUE self)
181
181
  {
182
- DSA *dsa;
182
+ const DSA *dsa;
183
183
  const BIGNUM *bn;
184
184
 
185
185
  GetDSA(self, dsa);
@@ -198,7 +198,7 @@ ossl_dsa_is_public(VALUE self)
198
198
  static VALUE
199
199
  ossl_dsa_is_private(VALUE self)
200
200
  {
201
- DSA *dsa;
201
+ OSSL_3_const DSA *dsa;
202
202
 
203
203
  GetDSA(self, dsa);
204
204
 
@@ -211,21 +211,63 @@ ossl_dsa_is_private(VALUE self)
211
211
  * dsa.to_pem([cipher, password]) -> aString
212
212
  * dsa.to_s([cipher, password]) -> aString
213
213
  *
214
- * Encodes this DSA to its PEM encoding.
214
+ * Serializes a private or public key to a PEM-encoding.
215
+ *
216
+ * [When the key contains public components only]
217
+ *
218
+ * Serializes it into an X.509 SubjectPublicKeyInfo.
219
+ * The parameters _cipher_ and _password_ are ignored.
220
+ *
221
+ * A PEM-encoded key will look like:
222
+ *
223
+ * -----BEGIN PUBLIC KEY-----
224
+ * [...]
225
+ * -----END PUBLIC KEY-----
226
+ *
227
+ * Consider using #public_to_pem instead. This serializes the key into an
228
+ * X.509 SubjectPublicKeyInfo regardless of whether it is a public key
229
+ * or a private key.
230
+ *
231
+ * [When the key contains private components, and no parameters are given]
232
+ *
233
+ * Serializes it into a traditional \OpenSSL DSAPrivateKey.
234
+ *
235
+ * A PEM-encoded key will look like:
236
+ *
237
+ * -----BEGIN DSA PRIVATE KEY-----
238
+ * [...]
239
+ * -----END DSA PRIVATE KEY-----
215
240
  *
216
- * === Parameters
217
- * * _cipher_ is an OpenSSL::Cipher.
218
- * * _password_ is a string containing your password.
241
+ * [When the key contains private components, and _cipher_ and _password_ are given]
219
242
  *
220
- * === Examples
221
- * DSA.to_pem -> aString
222
- * DSA.to_pem(cipher, 'mypassword') -> aString
243
+ * Serializes it into a traditional \OpenSSL DSAPrivateKey and encrypts it in
244
+ * OpenSSL's traditional PEM encryption format.
245
+ * _cipher_ must be a cipher name understood by OpenSSL::Cipher.new or an
246
+ * instance of OpenSSL::Cipher.
223
247
  *
248
+ * An encrypted PEM-encoded key will look like:
249
+ *
250
+ * -----BEGIN DSA PRIVATE KEY-----
251
+ * Proc-Type: 4,ENCRYPTED
252
+ * DEK-Info: AES-128-CBC,733F5302505B34701FC41F5C0746E4C0
253
+ *
254
+ * [...]
255
+ * -----END DSA PRIVATE KEY-----
256
+ *
257
+ * Note that this format uses MD5 to derive the encryption key, and hence
258
+ * will not be available on FIPS-compliant systems.
259
+ *
260
+ * <b>This method is kept for compatibility.</b>
261
+ * This should only be used when the traditional, non-standard \OpenSSL format
262
+ * is required.
263
+ *
264
+ * Consider using #public_to_pem (X.509 SubjectPublicKeyInfo) or #private_to_pem
265
+ * (PKCS #8 PrivateKeyInfo or EncryptedPrivateKeyInfo) instead.
224
266
  */
225
267
  static VALUE
226
268
  ossl_dsa_export(int argc, VALUE *argv, VALUE self)
227
269
  {
228
- DSA *dsa;
270
+ OSSL_3_const DSA *dsa;
229
271
 
230
272
  GetDSA(self, dsa);
231
273
  if (DSA_HAS_PRIVATE(dsa))
@@ -238,13 +280,20 @@ ossl_dsa_export(int argc, VALUE *argv, VALUE self)
238
280
  * call-seq:
239
281
  * dsa.to_der -> aString
240
282
  *
241
- * Encodes this DSA to its DER encoding.
283
+ * Serializes a private or public key to a DER-encoding.
284
+ *
285
+ * See #to_pem for details.
286
+ *
287
+ * <b>This method is kept for compatibility.</b>
288
+ * This should only be used when the traditional, non-standard \OpenSSL format
289
+ * is required.
242
290
  *
291
+ * Consider using #public_to_der or #private_to_der instead.
243
292
  */
244
293
  static VALUE
245
294
  ossl_dsa_to_der(VALUE self)
246
295
  {
247
- DSA *dsa;
296
+ OSSL_3_const DSA *dsa;
248
297
 
249
298
  GetDSA(self, dsa);
250
299
  if (DSA_HAS_PRIVATE(dsa))
@@ -265,7 +314,7 @@ ossl_dsa_to_der(VALUE self)
265
314
  static VALUE
266
315
  ossl_dsa_get_params(VALUE self)
267
316
  {
268
- DSA *dsa;
317
+ OSSL_3_const DSA *dsa;
269
318
  VALUE hash;
270
319
  const BIGNUM *p, *q, *g, *pub_key, *priv_key;
271
320
 
@@ -227,7 +227,7 @@ ossl_ec_key_initialize_copy(VALUE self, VALUE other)
227
227
  static VALUE
228
228
  ossl_ec_key_get_group(VALUE self)
229
229
  {
230
- EC_KEY *ec;
230
+ OSSL_3_const EC_KEY *ec;
231
231
  const EC_GROUP *group;
232
232
 
233
233
  GetEC(self, ec);
@@ -272,7 +272,7 @@ ossl_ec_key_set_group(VALUE self, VALUE group_v)
272
272
  */
273
273
  static VALUE ossl_ec_key_get_private_key(VALUE self)
274
274
  {
275
- EC_KEY *ec;
275
+ OSSL_3_const EC_KEY *ec;
276
276
  const BIGNUM *bn;
277
277
 
278
278
  GetEC(self, ec);
@@ -323,7 +323,7 @@ static VALUE ossl_ec_key_set_private_key(VALUE self, VALUE private_key)
323
323
  */
324
324
  static VALUE ossl_ec_key_get_public_key(VALUE self)
325
325
  {
326
- EC_KEY *ec;
326
+ OSSL_3_const EC_KEY *ec;
327
327
  const EC_POINT *point;
328
328
 
329
329
  GetEC(self, ec);
@@ -375,7 +375,7 @@ static VALUE ossl_ec_key_set_public_key(VALUE self, VALUE public_key)
375
375
  */
376
376
  static VALUE ossl_ec_key_is_public(VALUE self)
377
377
  {
378
- EC_KEY *ec;
378
+ OSSL_3_const EC_KEY *ec;
379
379
 
380
380
  GetEC(self, ec);
381
381
 
@@ -391,7 +391,7 @@ static VALUE ossl_ec_key_is_public(VALUE self)
391
391
  */
392
392
  static VALUE ossl_ec_key_is_private(VALUE self)
393
393
  {
394
- EC_KEY *ec;
394
+ OSSL_3_const EC_KEY *ec;
395
395
 
396
396
  GetEC(self, ec);
397
397
 
@@ -400,18 +400,66 @@ static VALUE ossl_ec_key_is_private(VALUE self)
400
400
 
401
401
  /*
402
402
  * call-seq:
403
- * key.export([cipher, pass_phrase]) => String
404
- * key.to_pem([cipher, pass_phrase]) => String
403
+ * key.export([cipher, password]) => String
404
+ * key.to_pem([cipher, password]) => String
405
+ *
406
+ * Serializes a private or public key to a PEM-encoding.
407
+ *
408
+ * [When the key contains public components only]
409
+ *
410
+ * Serializes it into an X.509 SubjectPublicKeyInfo.
411
+ * The parameters _cipher_ and _password_ are ignored.
412
+ *
413
+ * A PEM-encoded key will look like:
414
+ *
415
+ * -----BEGIN PUBLIC KEY-----
416
+ * [...]
417
+ * -----END PUBLIC KEY-----
418
+ *
419
+ * Consider using #public_to_pem instead. This serializes the key into an
420
+ * X.509 SubjectPublicKeyInfo regardless of whether it is a public key
421
+ * or a private key.
422
+ *
423
+ * [When the key contains private components, and no parameters are given]
424
+ *
425
+ * Serializes it into a SEC 1/RFC 5915 ECPrivateKey.
426
+ *
427
+ * A PEM-encoded key will look like:
405
428
  *
406
- * Outputs the EC key in PEM encoding. If _cipher_ and _pass_phrase_ are given
407
- * they will be used to encrypt the key. _cipher_ must be an OpenSSL::Cipher
408
- * instance. Note that encryption will only be effective for a private key,
409
- * public keys will always be encoded in plain text.
429
+ * -----BEGIN EC PRIVATE KEY-----
430
+ * [...]
431
+ * -----END EC PRIVATE KEY-----
432
+ *
433
+ * [When the key contains private components, and _cipher_ and _password_ are given]
434
+ *
435
+ * Serializes it into a SEC 1/RFC 5915 ECPrivateKey
436
+ * and encrypts it in OpenSSL's traditional PEM encryption format.
437
+ * _cipher_ must be a cipher name understood by OpenSSL::Cipher.new or an
438
+ * instance of OpenSSL::Cipher.
439
+ *
440
+ * An encrypted PEM-encoded key will look like:
441
+ *
442
+ * -----BEGIN EC PRIVATE KEY-----
443
+ * Proc-Type: 4,ENCRYPTED
444
+ * DEK-Info: AES-128-CBC,733F5302505B34701FC41F5C0746E4C0
445
+ *
446
+ * [...]
447
+ * -----END EC PRIVATE KEY-----
448
+ *
449
+ * Note that this format uses MD5 to derive the encryption key, and hence
450
+ * will not be available on FIPS-compliant systems.
451
+ *
452
+ * <b>This method is kept for compatibility.</b>
453
+ * This should only be used when the SEC 1/RFC 5915 ECPrivateKey format is
454
+ * required.
455
+ *
456
+ * Consider using #public_to_pem (X.509 SubjectPublicKeyInfo) or #private_to_pem
457
+ * (PKCS #8 PrivateKeyInfo or EncryptedPrivateKeyInfo) instead.
410
458
  */
411
459
  static VALUE
412
460
  ossl_ec_key_export(int argc, VALUE *argv, VALUE self)
413
461
  {
414
- EC_KEY *ec;
462
+ OSSL_3_const EC_KEY *ec;
415
463
 
416
464
  GetEC(self, ec);
417
465
  if (EC_KEY_get0_public_key(ec) == NULL)
@@ -426,12 +474,20 @@ ossl_ec_key_export(int argc, VALUE *argv, VALUE self)
426
474
  * call-seq:
427
475
  * key.to_der => String
428
476
  *
429
- * See the OpenSSL documentation for i2d_ECPrivateKey_bio()
477
+ * Serializes a private or public key to a DER-encoding.
478
+ *
479
+ * See #to_pem for details.
480
+ *
481
+ * <b>This method is kept for compatibility.</b>
482
+ * This should only be used when the SEC 1/RFC 5915 ECPrivateKey format is
483
+ * required.
484
+ *
485
+ * Consider using #public_to_der or #private_to_der instead.
430
486
  */
431
487
  static VALUE
432
488
  ossl_ec_key_to_der(VALUE self)
433
489
  {
434
- EC_KEY *ec;
490
+ OSSL_3_const EC_KEY *ec;
435
491
 
436
492
  GetEC(self, ec);
437
493
  if (EC_KEY_get0_public_key(ec) == NULL)
@@ -483,7 +539,7 @@ static VALUE ossl_ec_key_check_key(VALUE self)
483
539
  #ifdef HAVE_EVP_PKEY_CHECK
484
540
  EVP_PKEY *pkey;
485
541
  EVP_PKEY_CTX *pctx;
486
- EC_KEY *ec;
542
+ const EC_KEY *ec;
487
543
 
488
544
  GetPKey(self, pkey);
489
545
  GetEC(self, ec);
@@ -530,7 +586,7 @@ static const rb_data_type_t ossl_ec_group_type = {
530
586
  {
531
587
  0, ossl_ec_group_free,
532
588
  },
533
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
589
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
534
590
  };
535
591
 
536
592
  static VALUE
@@ -1115,7 +1171,7 @@ static const rb_data_type_t ossl_ec_point_type = {
1115
1171
  {
1116
1172
  0, ossl_ec_point_free,
1117
1173
  },
1118
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
1174
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
1119
1175
  };
1120
1176
 
1121
1177
  static VALUE
@@ -24,7 +24,7 @@
24
24
  } while (0)
25
25
 
26
26
  static inline int
27
- RSA_HAS_PRIVATE(RSA *rsa)
27
+ RSA_HAS_PRIVATE(OSSL_3_const RSA *rsa)
28
28
  {
29
29
  const BIGNUM *e, *d;
30
30
 
@@ -33,7 +33,7 @@ RSA_HAS_PRIVATE(RSA *rsa)
33
33
  }
34
34
 
35
35
  static inline int
36
- RSA_PRIVATE(VALUE obj, RSA *rsa)
36
+ RSA_PRIVATE(VALUE obj, OSSL_3_const RSA *rsa)
37
37
  {
38
38
  return RSA_HAS_PRIVATE(rsa) || OSSL_PKEY_IS_PRIVATE(obj);
39
39
  }
@@ -50,8 +50,8 @@ VALUE eRSAError;
50
50
  /*
51
51
  * call-seq:
52
52
  * RSA.new -> rsa
53
- * RSA.new(encoded_key [, passphrase]) -> rsa
54
- * RSA.new(encoded_key) { passphrase } -> rsa
53
+ * RSA.new(encoded_key [, password ]) -> rsa
54
+ * RSA.new(encoded_key) { password } -> rsa
55
55
  * RSA.new(size [, exponent]) -> rsa
56
56
  *
57
57
  * Generates or loads an \RSA keypair.
@@ -61,9 +61,9 @@ VALUE eRSAError;
61
61
  * #set_crt_params.
62
62
  *
63
63
  * If called with a String, tries to parse as DER or PEM encoding of an \RSA key.
64
- * Note that, if _passphrase_ is not specified but the key is encrypted with a
65
- * passphrase, \OpenSSL will prompt for it.
66
- * See also OpenSSL::PKey.read which can parse keys of any kinds.
64
+ * Note that if _password_ is not specified, but the key is encrypted with a
65
+ * password, \OpenSSL will prompt for it.
66
+ * See also OpenSSL::PKey.read which can parse keys of any kind.
67
67
  *
68
68
  * If called with a number, generates a new key pair. This form works as an
69
69
  * alias of RSA.generate.
@@ -71,7 +71,7 @@ VALUE eRSAError;
71
71
  * Examples:
72
72
  * OpenSSL::PKey::RSA.new 2048
73
73
  * OpenSSL::PKey::RSA.new File.read 'rsa.pem'
74
- * OpenSSL::PKey::RSA.new File.read('rsa.pem'), 'my pass phrase'
74
+ * OpenSSL::PKey::RSA.new File.read('rsa.pem'), 'my password'
75
75
  */
76
76
  static VALUE
77
77
  ossl_rsa_initialize(int argc, VALUE *argv, VALUE self)
@@ -174,7 +174,7 @@ ossl_rsa_initialize_copy(VALUE self, VALUE other)
174
174
  static VALUE
175
175
  ossl_rsa_is_public(VALUE self)
176
176
  {
177
- RSA *rsa;
177
+ OSSL_3_const RSA *rsa;
178
178
 
179
179
  GetRSA(self, rsa);
180
180
  /*
@@ -193,7 +193,7 @@ ossl_rsa_is_public(VALUE self)
193
193
  static VALUE
194
194
  ossl_rsa_is_private(VALUE self)
195
195
  {
196
- RSA *rsa;
196
+ OSSL_3_const RSA *rsa;
197
197
 
198
198
  GetRSA(self, rsa);
199
199
 
@@ -203,7 +203,7 @@ ossl_rsa_is_private(VALUE self)
203
203
  static int
204
204
  can_export_rsaprivatekey(VALUE self)
205
205
  {
206
- RSA *rsa;
206
+ OSSL_3_const RSA *rsa;
207
207
  const BIGNUM *n, *e, *d, *p, *q, *dmp1, *dmq1, *iqmp;
208
208
 
209
209
  GetRSA(self, rsa);
@@ -217,13 +217,61 @@ can_export_rsaprivatekey(VALUE self)
217
217
 
218
218
  /*
219
219
  * call-seq:
220
- * rsa.export([cipher, pass_phrase]) => PEM-format String
221
- * rsa.to_pem([cipher, pass_phrase]) => PEM-format String
222
- * rsa.to_s([cipher, pass_phrase]) => PEM-format String
220
+ * rsa.export([cipher, password]) => PEM-format String
221
+ * rsa.to_pem([cipher, password]) => PEM-format String
222
+ * rsa.to_s([cipher, password]) => PEM-format String
223
+ *
224
+ * Serializes a private or public key to a PEM-encoding.
225
+ *
226
+ * [When the key contains public components only]
227
+ *
228
+ * Serializes it into an X.509 SubjectPublicKeyInfo.
229
+ * The parameters _cipher_ and _password_ are ignored.
230
+ *
231
+ * A PEM-encoded key will look like:
232
+ *
233
+ * -----BEGIN PUBLIC KEY-----
234
+ * [...]
235
+ * -----END PUBLIC KEY-----
236
+ *
237
+ * Consider using #public_to_pem instead. This serializes the key into an
238
+ * X.509 SubjectPublicKeyInfo regardless of whether the key is a public key
239
+ * or a private key.
240
+ *
241
+ * [When the key contains private components, and no parameters are given]
242
+ *
243
+ * Serializes it into a PKCS #1 RSAPrivateKey.
244
+ *
245
+ * A PEM-encoded key will look like:
223
246
  *
224
- * Outputs this keypair in PEM encoding. If _cipher_ and _pass_phrase_ are
225
- * given they will be used to encrypt the key. _cipher_ must be an
226
- * OpenSSL::Cipher instance.
247
+ * -----BEGIN RSA PRIVATE KEY-----
248
+ * [...]
249
+ * -----END RSA PRIVATE KEY-----
250
+ *
251
+ * [When the key contains private components, and _cipher_ and _password_ are given]
252
+ *
253
+ * Serializes it into a PKCS #1 RSAPrivateKey
254
+ * and encrypts it in OpenSSL's traditional PEM encryption format.
255
+ * _cipher_ must be a cipher name understood by OpenSSL::Cipher.new or an
256
+ * instance of OpenSSL::Cipher.
257
+ *
258
+ * An encrypted PEM-encoded key will look like:
259
+ *
260
+ * -----BEGIN RSA PRIVATE KEY-----
261
+ * Proc-Type: 4,ENCRYPTED
262
+ * DEK-Info: AES-128-CBC,733F5302505B34701FC41F5C0746E4C0
263
+ *
264
+ * [...]
265
+ * -----END RSA PRIVATE KEY-----
266
+ *
267
+ * Note that this format uses MD5 to derive the encryption key, and hence
268
+ * will not be available on FIPS-compliant systems.
269
+ *
270
+ * <b>This method is kept for compatibility.</b>
271
+ * This should only be used when the PKCS #1 RSAPrivateKey format is required.
272
+ *
273
+ * Consider using #public_to_pem (X.509 SubjectPublicKeyInfo) or #private_to_pem
274
+ * (PKCS #8 PrivateKeyInfo or EncryptedPrivateKeyInfo) instead.
227
275
  */
228
276
  static VALUE
229
277
  ossl_rsa_export(int argc, VALUE *argv, VALUE self)
@@ -238,7 +286,14 @@ ossl_rsa_export(int argc, VALUE *argv, VALUE self)
238
286
  * call-seq:
239
287
  * rsa.to_der => DER-format String
240
288
  *
241
- * Outputs this keypair in DER encoding.
289
+ * Serializes a private or public key to a DER-encoding.
290
+ *
291
+ * See #to_pem for details.
292
+ *
293
+ * <b>This method is kept for compatibility.</b>
294
+ * This should only be used when the PKCS #1 RSAPrivateKey format is required.
295
+ *
296
+ * Consider using #public_to_der or #private_to_der instead.
242
297
  */
243
298
  static VALUE
244
299
  ossl_rsa_to_der(VALUE self)
@@ -453,7 +508,7 @@ ossl_rsa_verify_pss(int argc, VALUE *argv, VALUE self)
453
508
  static VALUE
454
509
  ossl_rsa_get_params(VALUE self)
455
510
  {
456
- RSA *rsa;
511
+ OSSL_3_const RSA *rsa;
457
512
  VALUE hash;
458
513
  const BIGNUM *n, *e, *d, *p, *q, *dmp1, *dmq1, *iqmp;
459
514
 
@@ -0,0 +1,211 @@
1
+ /*
2
+ * This program is licensed under the same licence as Ruby.
3
+ * (See the file 'LICENCE'.)
4
+ */
5
+ #include "ossl.h"
6
+
7
+ #ifdef OSSL_USE_PROVIDER
8
+ # include <openssl/provider.h>
9
+
10
+ #define NewProvider(klass) \
11
+ TypedData_Wrap_Struct((klass), &ossl_provider_type, 0)
12
+ #define SetProvider(obj, provider) do { \
13
+ if (!(provider)) { \
14
+ ossl_raise(rb_eRuntimeError, "Provider wasn't initialized."); \
15
+ } \
16
+ RTYPEDDATA_DATA(obj) = (provider); \
17
+ } while(0)
18
+ #define GetProvider(obj, provider) do { \
19
+ TypedData_Get_Struct((obj), OSSL_PROVIDER, &ossl_provider_type, (provider)); \
20
+ if (!(provider)) { \
21
+ ossl_raise(rb_eRuntimeError, "PROVIDER wasn't initialized."); \
22
+ } \
23
+ } while (0)
24
+
25
+ static const rb_data_type_t ossl_provider_type = {
26
+ "OpenSSL/Provider",
27
+ {
28
+ 0,
29
+ },
30
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
31
+ };
32
+
33
+ /*
34
+ * Classes
35
+ */
36
+ /* Document-class: OpenSSL::Provider
37
+ *
38
+ * This class is the access to openssl's Provider
39
+ * See also, https://www.openssl.org/docs/manmaster/man7/provider.html
40
+ */
41
+ static VALUE cProvider;
42
+ /* Document-class: OpenSSL::Provider::ProviderError
43
+ *
44
+ * This is the generic exception for OpenSSL::Provider related errors
45
+ */
46
+ static VALUE eProviderError;
47
+
48
+ /*
49
+ * call-seq:
50
+ * OpenSSL::Provider.load(name) -> provider
51
+ *
52
+ * This method loads and initializes a provider
53
+ */
54
+ static VALUE
55
+ ossl_provider_s_load(VALUE klass, VALUE name)
56
+ {
57
+ OSSL_PROVIDER *provider = NULL;
58
+ VALUE obj;
59
+
60
+ const char *provider_name_ptr = StringValueCStr(name);
61
+
62
+ provider = OSSL_PROVIDER_load(NULL, provider_name_ptr);
63
+ if (provider == NULL) {
64
+ ossl_raise(eProviderError, "Failed to load %s provider", provider_name_ptr);
65
+ }
66
+ obj = NewProvider(klass);
67
+ SetProvider(obj, provider);
68
+
69
+ return obj;
70
+ }
71
+
72
+ struct ary_with_state { VALUE ary; int state; };
73
+ struct rb_push_provider_name_args { OSSL_PROVIDER *prov; VALUE ary; };
74
+
75
+ static VALUE
76
+ rb_push_provider_name(VALUE rb_push_provider_name_args)
77
+ {
78
+ struct rb_push_provider_name_args *args = (struct rb_push_provider_name_args *)rb_push_provider_name_args;
79
+
80
+ VALUE name = rb_str_new2(OSSL_PROVIDER_get0_name(args->prov));
81
+ return rb_ary_push(args->ary, name);
82
+ }
83
+
84
+ static int
85
+ push_provider(OSSL_PROVIDER *prov, void *cbdata)
86
+ {
87
+ struct ary_with_state *ary_with_state = (struct ary_with_state *)cbdata;
88
+ struct rb_push_provider_name_args args = { prov, ary_with_state->ary };
89
+
90
+ rb_protect(rb_push_provider_name, (VALUE)&args, &ary_with_state->state);
91
+ if (ary_with_state->state) {
92
+ return 0;
93
+ } else {
94
+ return 1;
95
+ }
96
+ }
97
+
98
+ /*
99
+ * call-seq:
100
+ * OpenSSL::Provider.provider_names -> [provider_name, ...]
101
+ *
102
+ * Returns an array of currently loaded provider names.
103
+ */
104
+ static VALUE
105
+ ossl_provider_s_provider_names(VALUE klass)
106
+ {
107
+ VALUE ary = rb_ary_new();
108
+ struct ary_with_state cbdata = { ary, 0 };
109
+
110
+ int result = OSSL_PROVIDER_do_all(NULL, &push_provider, (void*)&cbdata);
111
+ if (result != 1 ) {
112
+ if (cbdata.state) {
113
+ rb_jump_tag(cbdata.state);
114
+ } else {
115
+ ossl_raise(eProviderError, "Failed to load provider names");
116
+ }
117
+ }
118
+
119
+ return ary;
120
+ }
121
+
122
+ /*
123
+ * call-seq:
124
+ * provider.unload -> true
125
+ *
126
+ * This method unloads this provider.
127
+ *
128
+ * if provider unload fails or already unloaded, it raises OpenSSL::Provider::ProviderError
129
+ */
130
+ static VALUE
131
+ ossl_provider_unload(VALUE self)
132
+ {
133
+ OSSL_PROVIDER *prov;
134
+ if (RTYPEDDATA_DATA(self) == NULL) {
135
+ ossl_raise(eProviderError, "Provider already unloaded.");
136
+ }
137
+ GetProvider(self, prov);
138
+
139
+ int result = OSSL_PROVIDER_unload(prov);
140
+
141
+ if (result != 1) {
142
+ ossl_raise(eProviderError, "Failed to unload provider");
143
+ }
144
+ RTYPEDDATA_DATA(self) = NULL;
145
+ return Qtrue;
146
+ }
147
+
148
+ /*
149
+ * call-seq:
150
+ * provider.name -> string
151
+ *
152
+ * Get the name of this provider.
153
+ *
154
+ * if this provider is already unloaded, it raises OpenSSL::Provider::ProviderError
155
+ */
156
+ static VALUE
157
+ ossl_provider_get_name(VALUE self)
158
+ {
159
+ OSSL_PROVIDER *prov;
160
+ if (RTYPEDDATA_DATA(self) == NULL) {
161
+ ossl_raise(eProviderError, "Provider already unloaded.");
162
+ }
163
+ GetProvider(self, prov);
164
+
165
+ return rb_str_new2(OSSL_PROVIDER_get0_name(prov));
166
+ }
167
+
168
+ /*
169
+ * call-seq:
170
+ * provider.inspect -> string
171
+ *
172
+ * Pretty prints this provider.
173
+ */
174
+ static VALUE
175
+ ossl_provider_inspect(VALUE self)
176
+ {
177
+ OSSL_PROVIDER *prov;
178
+ if (RTYPEDDATA_DATA(self) == NULL ) {
179
+ return rb_sprintf("#<%"PRIsVALUE" unloaded provider>", rb_obj_class(self));
180
+ }
181
+ GetProvider(self, prov);
182
+
183
+ return rb_sprintf("#<%"PRIsVALUE" name=\"%s\">",
184
+ rb_obj_class(self), OSSL_PROVIDER_get0_name(prov));
185
+ }
186
+
187
+ void
188
+ Init_ossl_provider(void)
189
+ {
190
+ #if 0
191
+ mOSSL = rb_define_module("OpenSSL");
192
+ eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError);
193
+ #endif
194
+
195
+ cProvider = rb_define_class_under(mOSSL, "Provider", rb_cObject);
196
+ eProviderError = rb_define_class_under(cProvider, "ProviderError", eOSSLError);
197
+
198
+ rb_undef_alloc_func(cProvider);
199
+ rb_define_singleton_method(cProvider, "load", ossl_provider_s_load, 1);
200
+ rb_define_singleton_method(cProvider, "provider_names", ossl_provider_s_provider_names, 0);
201
+
202
+ rb_define_method(cProvider, "unload", ossl_provider_unload, 0);
203
+ rb_define_method(cProvider, "name", ossl_provider_get_name, 0);
204
+ rb_define_method(cProvider, "inspect", ossl_provider_inspect, 0);
205
+ }
206
+ #else
207
+ void
208
+ Init_ossl_provider(void)
209
+ {
210
+ }
211
+ #endif
@@ -0,0 +1,5 @@
1
+ #if !defined(OSSL_PROVIDER_H)
2
+ #define OSSL_PROVIDER_H
3
+
4
+ void Init_ossl_provider(void);
5
+ #endif