openssl 3.1.3 → 3.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. data/History.md +33 -51
  3. data/README.md +36 -19
  4. data/ext/openssl/extconf.rb +35 -8
  5. data/ext/openssl/ossl.c +73 -195
  6. data/ext/openssl/ossl.h +5 -6
  7. data/ext/openssl/ossl_asn1.c +24 -19
  8. data/ext/openssl/ossl_bn.c +1 -1
  9. data/ext/openssl/ossl_cipher.c +5 -20
  10. data/ext/openssl/ossl_config.c +1 -1
  11. data/ext/openssl/ossl_digest.c +1 -2
  12. data/ext/openssl/ossl_engine.c +1 -1
  13. data/ext/openssl/ossl_hmac.c +1 -1
  14. data/ext/openssl/ossl_kdf.c +1 -1
  15. data/ext/openssl/ossl_ns_spki.c +1 -1
  16. data/ext/openssl/ossl_ocsp.c +6 -6
  17. data/ext/openssl/ossl_pkcs12.c +1 -1
  18. data/ext/openssl/ossl_pkcs7.c +4 -14
  19. data/ext/openssl/ossl_pkey.c +217 -45
  20. data/ext/openssl/ossl_pkey_dh.c +22 -9
  21. data/ext/openssl/ossl_pkey_dsa.c +57 -10
  22. data/ext/openssl/ossl_pkey_ec.c +65 -11
  23. data/ext/openssl/ossl_pkey_rsa.c +68 -15
  24. data/ext/openssl/ossl_provider.c +211 -0
  25. data/ext/openssl/ossl_provider.h +5 -0
  26. data/ext/openssl/ossl_ssl.c +83 -65
  27. data/ext/openssl/ossl_ssl_session.c +1 -1
  28. data/ext/openssl/ossl_ts.c +3 -3
  29. data/ext/openssl/ossl_x509attr.c +1 -1
  30. data/ext/openssl/ossl_x509cert.c +1 -1
  31. data/ext/openssl/ossl_x509crl.c +1 -1
  32. data/ext/openssl/ossl_x509ext.c +13 -7
  33. data/ext/openssl/ossl_x509name.c +1 -1
  34. data/ext/openssl/ossl_x509req.c +1 -1
  35. data/ext/openssl/ossl_x509revoked.c +1 -1
  36. data/ext/openssl/ossl_x509store.c +12 -5
  37. data/lib/openssl/buffering.rb +8 -16
  38. data/lib/openssl/digest.rb +1 -5
  39. data/lib/openssl/ssl.rb +11 -10
  40. data/lib/openssl/version.rb +1 -1
  41. data/lib/openssl/x509.rb +5 -5
  42. metadata +12 -6
@@ -21,8 +21,6 @@
21
21
  EVP_PKEY *_pkey; \
22
22
  GetPKeyDH((obj), _pkey); \
23
23
  (dh) = EVP_PKEY_get0_DH(_pkey); \
24
- if ((dh) == NULL) \
25
- ossl_raise(eDHError, "failed to get DH from EVP_PKEY"); \
26
24
  } while (0)
27
25
 
28
26
  /*
@@ -218,9 +216,20 @@ ossl_dh_is_private(VALUE self)
218
216
  * dh.to_pem -> aString
219
217
  * dh.to_s -> aString
220
218
  *
221
- * Encodes this DH to its PEM encoding. Note that any existing per-session
222
- * public/private keys will *not* get encoded, just the Diffie-Hellman
223
- * parameters will be encoded.
219
+ * Serializes the DH parameters to a PEM-encoding.
220
+ *
221
+ * Note that any existing per-session public/private keys will *not* get
222
+ * encoded, just the Diffie-Hellman parameters will be encoded.
223
+ *
224
+ * PEM-encoded parameters will look like:
225
+ *
226
+ * -----BEGIN DH PARAMETERS-----
227
+ * [...]
228
+ * -----END DH PARAMETERS-----
229
+ *
230
+ * See also #public_to_pem (X.509 SubjectPublicKeyInfo) and
231
+ * #private_to_pem (PKCS #8 PrivateKeyInfo or EncryptedPrivateKeyInfo) for
232
+ * serialization with the private or public key components.
224
233
  */
225
234
  static VALUE
226
235
  ossl_dh_export(VALUE self)
@@ -246,10 +255,14 @@ ossl_dh_export(VALUE self)
246
255
  * call-seq:
247
256
  * dh.to_der -> aString
248
257
  *
249
- * Encodes this DH to its DER encoding. Note that any existing per-session
250
- * public/private keys will *not* get encoded, just the Diffie-Hellman
251
- * parameters will be encoded.
252
-
258
+ * Serializes the DH parameters to a DER-encoding
259
+ *
260
+ * Note that any existing per-session public/private keys will *not* get
261
+ * encoded, just the Diffie-Hellman parameters will be encoded.
262
+ *
263
+ * See also #public_to_der (X.509 SubjectPublicKeyInfo) and
264
+ * #private_to_der (PKCS #8 PrivateKeyInfo or EncryptedPrivateKeyInfo) for
265
+ * serialization with the private or public key components.
253
266
  */
254
267
  static VALUE
255
268
  ossl_dh_to_der(VALUE self)
@@ -21,8 +21,6 @@
21
21
  EVP_PKEY *_pkey; \
22
22
  GetPKeyDSA((obj), _pkey); \
23
23
  (dsa) = EVP_PKEY_get0_DSA(_pkey); \
24
- if ((dsa) == NULL) \
25
- ossl_raise(eDSAError, "failed to get DSA from EVP_PKEY"); \
26
24
  } while (0)
27
25
 
28
26
  static inline int
@@ -213,16 +211,58 @@ ossl_dsa_is_private(VALUE self)
213
211
  * dsa.to_pem([cipher, password]) -> aString
214
212
  * dsa.to_s([cipher, password]) -> aString
215
213
  *
216
- * Encodes this DSA to its PEM encoding.
214
+ * Serializes a private or public key to a PEM-encoding.
217
215
  *
218
- * === Parameters
219
- * * _cipher_ is an OpenSSL::Cipher.
220
- * * _password_ is a string containing your password.
216
+ * [When the key contains public components only]
221
217
  *
222
- * === Examples
223
- * DSA.to_pem -> aString
224
- * DSA.to_pem(cipher, 'mypassword') -> aString
218
+ * Serializes it into an X.509 SubjectPublicKeyInfo.
219
+ * The parameters _cipher_ and _password_ are ignored.
225
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-----
240
+ *
241
+ * [When the key contains private components, and _cipher_ and _password_ are given]
242
+ *
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.
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.
226
266
  */
227
267
  static VALUE
228
268
  ossl_dsa_export(int argc, VALUE *argv, VALUE self)
@@ -240,8 +280,15 @@ ossl_dsa_export(int argc, VALUE *argv, VALUE self)
240
280
  * call-seq:
241
281
  * dsa.to_der -> aString
242
282
  *
243
- * 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.
244
290
  *
291
+ * Consider using #public_to_der or #private_to_der instead.
245
292
  */
246
293
  static VALUE
247
294
  ossl_dsa_to_der(VALUE self)
@@ -22,8 +22,6 @@ static const rb_data_type_t ossl_ec_point_type;
22
22
  EVP_PKEY *_pkey; \
23
23
  GetPKeyEC(obj, _pkey); \
24
24
  (key) = EVP_PKEY_get0_EC_KEY(_pkey); \
25
- if ((key) == NULL) \
26
- ossl_raise(eECError, "failed to get EC_KEY from EVP_PKEY"); \
27
25
  } while (0)
28
26
 
29
27
  #define GetECGroup(obj, group) do { \
@@ -402,13 +400,61 @@ static VALUE ossl_ec_key_is_private(VALUE self)
402
400
 
403
401
  /*
404
402
  * call-seq:
405
- * key.export([cipher, pass_phrase]) => String
406
- * key.to_pem([cipher, pass_phrase]) => String
403
+ * key.export([cipher, password]) => String
404
+ * key.to_pem([cipher, password]) => String
407
405
  *
408
- * Outputs the EC key in PEM encoding. If _cipher_ and _pass_phrase_ are given
409
- * they will be used to encrypt the key. _cipher_ must be an OpenSSL::Cipher
410
- * instance. Note that encryption will only be effective for a private key,
411
- * public keys will always be encoded in plain text.
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:
428
+ *
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.
412
458
  */
413
459
  static VALUE
414
460
  ossl_ec_key_export(int argc, VALUE *argv, VALUE self)
@@ -428,7 +474,15 @@ ossl_ec_key_export(int argc, VALUE *argv, VALUE self)
428
474
  * call-seq:
429
475
  * key.to_der => String
430
476
  *
431
- * 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.
432
486
  */
433
487
  static VALUE
434
488
  ossl_ec_key_to_der(VALUE self)
@@ -532,7 +586,7 @@ static const rb_data_type_t ossl_ec_group_type = {
532
586
  {
533
587
  0, ossl_ec_group_free,
534
588
  },
535
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
589
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
536
590
  };
537
591
 
538
592
  static VALUE
@@ -1117,7 +1171,7 @@ static const rb_data_type_t ossl_ec_point_type = {
1117
1171
  {
1118
1172
  0, ossl_ec_point_free,
1119
1173
  },
1120
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
1174
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
1121
1175
  };
1122
1176
 
1123
1177
  static VALUE
@@ -21,8 +21,6 @@
21
21
  EVP_PKEY *_pkey; \
22
22
  GetPKeyRSA((obj), _pkey); \
23
23
  (rsa) = EVP_PKEY_get0_RSA(_pkey); \
24
- if ((rsa) == NULL) \
25
- ossl_raise(eRSAError, "failed to get RSA from EVP_PKEY"); \
26
24
  } while (0)
27
25
 
28
26
  static inline int
@@ -52,8 +50,8 @@ VALUE eRSAError;
52
50
  /*
53
51
  * call-seq:
54
52
  * RSA.new -> rsa
55
- * RSA.new(encoded_key [, passphrase]) -> rsa
56
- * RSA.new(encoded_key) { passphrase } -> rsa
53
+ * RSA.new(encoded_key [, password ]) -> rsa
54
+ * RSA.new(encoded_key) { password } -> rsa
57
55
  * RSA.new(size [, exponent]) -> rsa
58
56
  *
59
57
  * Generates or loads an \RSA keypair.
@@ -63,9 +61,9 @@ VALUE eRSAError;
63
61
  * #set_crt_params.
64
62
  *
65
63
  * If called with a String, tries to parse as DER or PEM encoding of an \RSA key.
66
- * Note that, if _passphrase_ is not specified but the key is encrypted with a
67
- * passphrase, \OpenSSL will prompt for it.
68
- * 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.
69
67
  *
70
68
  * If called with a number, generates a new key pair. This form works as an
71
69
  * alias of RSA.generate.
@@ -73,7 +71,7 @@ VALUE eRSAError;
73
71
  * Examples:
74
72
  * OpenSSL::PKey::RSA.new 2048
75
73
  * OpenSSL::PKey::RSA.new File.read 'rsa.pem'
76
- * OpenSSL::PKey::RSA.new File.read('rsa.pem'), 'my pass phrase'
74
+ * OpenSSL::PKey::RSA.new File.read('rsa.pem'), 'my password'
77
75
  */
78
76
  static VALUE
79
77
  ossl_rsa_initialize(int argc, VALUE *argv, VALUE self)
@@ -219,13 +217,61 @@ can_export_rsaprivatekey(VALUE self)
219
217
 
220
218
  /*
221
219
  * call-seq:
222
- * rsa.export([cipher, pass_phrase]) => PEM-format String
223
- * rsa.to_pem([cipher, pass_phrase]) => PEM-format String
224
- * 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
225
223
  *
226
- * Outputs this keypair in PEM encoding. If _cipher_ and _pass_phrase_ are
227
- * given they will be used to encrypt the key. _cipher_ must be an
228
- * OpenSSL::Cipher instance.
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:
246
+ *
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.
229
275
  */
230
276
  static VALUE
231
277
  ossl_rsa_export(int argc, VALUE *argv, VALUE self)
@@ -240,7 +286,14 @@ ossl_rsa_export(int argc, VALUE *argv, VALUE self)
240
286
  * call-seq:
241
287
  * rsa.to_der => DER-format String
242
288
  *
243
- * 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.
244
297
  */
245
298
  static VALUE
246
299
  ossl_rsa_to_der(VALUE self)
@@ -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