openssl 2.2.1 → 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 (53) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.md +33 -45
  3. data/History.md +248 -1
  4. data/README.md +36 -19
  5. data/ext/openssl/extconf.rb +101 -68
  6. data/ext/openssl/openssl_missing.c +0 -66
  7. data/ext/openssl/openssl_missing.h +26 -45
  8. data/ext/openssl/ossl.c +128 -237
  9. data/ext/openssl/ossl.h +31 -12
  10. data/ext/openssl/ossl_asn1.c +26 -13
  11. data/ext/openssl/ossl_bn.c +213 -139
  12. data/ext/openssl/ossl_cipher.c +13 -14
  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 +10 -10
  16. data/ext/openssl/ossl_engine.c +17 -16
  17. data/ext/openssl/ossl_hmac.c +57 -136
  18. data/ext/openssl/ossl_kdf.c +12 -4
  19. data/ext/openssl/ossl_ns_spki.c +1 -1
  20. data/ext/openssl/ossl_ocsp.c +11 -59
  21. data/ext/openssl/ossl_pkcs12.c +22 -4
  22. data/ext/openssl/ossl_pkcs7.c +45 -62
  23. data/ext/openssl/ossl_pkey.c +1320 -196
  24. data/ext/openssl/ossl_pkey.h +36 -73
  25. data/ext/openssl/ossl_pkey_dh.c +152 -347
  26. data/ext/openssl/ossl_pkey_dsa.c +157 -413
  27. data/ext/openssl/ossl_pkey_ec.c +227 -343
  28. data/ext/openssl/ossl_pkey_rsa.c +159 -491
  29. data/ext/openssl/ossl_provider.c +211 -0
  30. data/ext/openssl/ossl_provider.h +5 -0
  31. data/ext/openssl/ossl_ssl.c +530 -450
  32. data/ext/openssl/ossl_ssl_session.c +29 -30
  33. data/ext/openssl/ossl_ts.c +38 -23
  34. data/ext/openssl/ossl_x509.c +0 -6
  35. data/ext/openssl/ossl_x509attr.c +1 -1
  36. data/ext/openssl/ossl_x509cert.c +168 -12
  37. data/ext/openssl/ossl_x509crl.c +14 -11
  38. data/ext/openssl/ossl_x509ext.c +14 -9
  39. data/ext/openssl/ossl_x509name.c +10 -3
  40. data/ext/openssl/ossl_x509req.c +14 -11
  41. data/ext/openssl/ossl_x509revoked.c +4 -4
  42. data/ext/openssl/ossl_x509store.c +166 -75
  43. data/lib/openssl/buffering.rb +9 -3
  44. data/lib/openssl/digest.rb +1 -5
  45. data/lib/openssl/hmac.rb +65 -0
  46. data/lib/openssl/pkey.rb +429 -0
  47. data/lib/openssl/ssl.rb +22 -17
  48. data/lib/openssl/version.rb +1 -1
  49. data/lib/openssl/x509.rb +22 -0
  50. data/lib/openssl.rb +0 -1
  51. metadata +10 -79
  52. data/ext/openssl/ruby_missing.h +0 -24
  53. data/lib/openssl/config.rb +0 -501
@@ -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
  }
@@ -43,246 +43,131 @@ DSA_PRIVATE(VALUE obj, DSA *dsa)
43
43
  VALUE cDSA;
44
44
  VALUE eDSAError;
45
45
 
46
- /*
47
- * Public
48
- */
49
- static VALUE
50
- dsa_instance(VALUE klass, DSA *dsa)
51
- {
52
- EVP_PKEY *pkey;
53
- VALUE obj;
54
-
55
- if (!dsa) {
56
- return Qfalse;
57
- }
58
- obj = NewPKey(klass);
59
- if (!(pkey = EVP_PKEY_new())) {
60
- return Qfalse;
61
- }
62
- if (!EVP_PKEY_assign_DSA(pkey, dsa)) {
63
- EVP_PKEY_free(pkey);
64
- return Qfalse;
65
- }
66
- SetPKey(obj, pkey);
67
-
68
- return obj;
69
- }
70
-
71
- VALUE
72
- ossl_dsa_new(EVP_PKEY *pkey)
73
- {
74
- VALUE obj;
75
-
76
- if (!pkey) {
77
- obj = dsa_instance(cDSA, DSA_new());
78
- } else {
79
- obj = NewPKey(cDSA);
80
- if (EVP_PKEY_base_id(pkey) != EVP_PKEY_DSA) {
81
- ossl_raise(rb_eTypeError, "Not a DSA key!");
82
- }
83
- SetPKey(obj, pkey);
84
- }
85
- if (obj == Qfalse) {
86
- ossl_raise(eDSAError, NULL);
87
- }
88
-
89
- return obj;
90
- }
91
-
92
46
  /*
93
47
  * Private
94
48
  */
95
- struct dsa_blocking_gen_arg {
96
- DSA *dsa;
97
- int size;
98
- int *counter;
99
- unsigned long *h;
100
- BN_GENCB *cb;
101
- int result;
102
- };
103
-
104
- static void *
105
- dsa_blocking_gen(void *arg)
106
- {
107
- struct dsa_blocking_gen_arg *gen = (struct dsa_blocking_gen_arg *)arg;
108
- gen->result = DSA_generate_parameters_ex(gen->dsa, gen->size, NULL, 0,
109
- gen->counter, gen->h, gen->cb);
110
- return 0;
111
- }
112
-
113
- static DSA *
114
- dsa_generate(int size)
115
- {
116
- struct ossl_generate_cb_arg cb_arg = { 0 };
117
- struct dsa_blocking_gen_arg gen_arg;
118
- DSA *dsa = DSA_new();
119
- BN_GENCB *cb = BN_GENCB_new();
120
- int counter;
121
- unsigned long h;
122
-
123
- if (!dsa || !cb) {
124
- DSA_free(dsa);
125
- BN_GENCB_free(cb);
126
- return NULL;
127
- }
128
-
129
- if (rb_block_given_p())
130
- cb_arg.yield = 1;
131
- BN_GENCB_set(cb, ossl_generate_cb_2, &cb_arg);
132
- gen_arg.dsa = dsa;
133
- gen_arg.size = size;
134
- gen_arg.counter = &counter;
135
- gen_arg.h = &h;
136
- gen_arg.cb = cb;
137
- if (cb_arg.yield == 1) {
138
- /* we cannot release GVL when callback proc is supplied */
139
- dsa_blocking_gen(&gen_arg);
140
- } else {
141
- /* there's a chance to unblock */
142
- rb_thread_call_without_gvl(dsa_blocking_gen, &gen_arg, ossl_generate_cb_stop, &cb_arg);
143
- }
144
-
145
- BN_GENCB_free(cb);
146
- if (!gen_arg.result) {
147
- DSA_free(dsa);
148
- if (cb_arg.state) {
149
- /* Clear OpenSSL error queue before re-raising. By the way, the
150
- * documentation of DSA_generate_parameters_ex() says the error code
151
- * can be obtained by ERR_get_error(), but the default
152
- * implementation, dsa_builtin_paramgen() doesn't put any error... */
153
- ossl_clear_error();
154
- rb_jump_tag(cb_arg.state);
155
- }
156
- return NULL;
157
- }
158
-
159
- if (!DSA_generate_key(dsa)) {
160
- DSA_free(dsa);
161
- return NULL;
162
- }
163
-
164
- return dsa;
165
- }
166
-
167
- /*
168
- * call-seq:
169
- * DSA.generate(size) -> dsa
170
- *
171
- * Creates a new DSA instance by generating a private/public key pair
172
- * from scratch.
173
- *
174
- * === Parameters
175
- * * _size_ is an integer representing the desired key size.
176
- *
177
- */
178
- static VALUE
179
- ossl_dsa_s_generate(VALUE klass, VALUE size)
180
- {
181
- DSA *dsa = dsa_generate(NUM2INT(size)); /* err handled by dsa_instance */
182
- VALUE obj = dsa_instance(klass, dsa);
183
-
184
- if (obj == Qfalse) {
185
- DSA_free(dsa);
186
- ossl_raise(eDSAError, NULL);
187
- }
188
-
189
- return obj;
190
- }
191
-
192
49
  /*
193
50
  * call-seq:
194
51
  * DSA.new -> dsa
195
- * DSA.new(size) -> dsa
196
52
  * DSA.new(string [, pass]) -> dsa
53
+ * DSA.new(size) -> dsa
197
54
  *
198
55
  * Creates a new DSA instance by reading an existing key from _string_.
199
56
  *
200
- * === Parameters
201
- * * _size_ is an integer representing the desired key size.
202
- * * _string_ contains a DER or PEM encoded key.
203
- * * _pass_ is a string that contains an optional password.
57
+ * If called without arguments, creates a new instance with no key components
58
+ * set. They can be set individually by #set_pqg and #set_key.
204
59
  *
205
- * === Examples
206
- * DSA.new -> dsa
207
- * DSA.new(1024) -> dsa
208
- * DSA.new(File.read('dsa.pem')) -> dsa
209
- * DSA.new(File.read('dsa.pem'), 'mypassword') -> dsa
60
+ * If called with a String, tries to parse as DER or PEM encoding of a \DSA key.
61
+ * See also OpenSSL::PKey.read which can parse keys of any kinds.
210
62
  *
63
+ * If called with a number, generates random parameters and a key pair. This
64
+ * form works as an alias of DSA.generate.
65
+ *
66
+ * +string+::
67
+ * A String that contains a DER or PEM encoded key.
68
+ * +pass+::
69
+ * A String that contains an optional password.
70
+ * +size+::
71
+ * See DSA.generate.
72
+ *
73
+ * Examples:
74
+ * p OpenSSL::PKey::DSA.new(1024)
75
+ * #=> #<OpenSSL::PKey::DSA:0x000055a8d6025bf0 oid=DSA>
76
+ *
77
+ * p OpenSSL::PKey::DSA.new(File.read('dsa.pem'))
78
+ * #=> #<OpenSSL::PKey::DSA:0x000055555d6b8110 oid=DSA>
79
+ *
80
+ * p OpenSSL::PKey::DSA.new(File.read('dsa.pem'), 'mypassword')
81
+ * #=> #<OpenSSL::PKey::DSA:0x0000556f973c40b8 oid=DSA>
211
82
  */
212
83
  static VALUE
213
84
  ossl_dsa_initialize(int argc, VALUE *argv, VALUE self)
214
85
  {
215
86
  EVP_PKEY *pkey;
216
87
  DSA *dsa;
217
- BIO *in;
88
+ BIO *in = NULL;
218
89
  VALUE arg, pass;
90
+ int type;
91
+
92
+ TypedData_Get_Struct(self, EVP_PKEY, &ossl_evp_pkey_type, pkey);
93
+ if (pkey)
94
+ rb_raise(rb_eTypeError, "pkey already initialized");
219
95
 
220
- GetPKey(self, pkey);
221
- if(rb_scan_args(argc, argv, "02", &arg, &pass) == 0) {
96
+ /* The DSA.new(size, generator) form is handled by lib/openssl/pkey.rb */
97
+ rb_scan_args(argc, argv, "02", &arg, &pass);
98
+ if (argc == 0) {
222
99
  dsa = DSA_new();
100
+ if (!dsa)
101
+ ossl_raise(eDSAError, "DSA_new");
102
+ goto legacy;
223
103
  }
224
- else if (RB_INTEGER_TYPE_P(arg)) {
225
- if (!(dsa = dsa_generate(NUM2INT(arg)))) {
226
- ossl_raise(eDSAError, NULL);
227
- }
228
- }
229
- else {
230
- pass = ossl_pem_passwd_value(pass);
231
- arg = ossl_to_der_if_possible(arg);
232
- in = ossl_obj2bio(&arg);
233
- dsa = PEM_read_bio_DSAPrivateKey(in, NULL, ossl_pem_passwd_cb, (void *)pass);
234
- if (!dsa) {
235
- OSSL_BIO_reset(in);
236
- dsa = PEM_read_bio_DSA_PUBKEY(in, NULL, NULL, NULL);
237
- }
238
- if (!dsa) {
239
- OSSL_BIO_reset(in);
240
- dsa = d2i_DSAPrivateKey_bio(in, NULL);
241
- }
242
- if (!dsa) {
243
- OSSL_BIO_reset(in);
244
- dsa = d2i_DSA_PUBKEY_bio(in, NULL);
245
- }
246
- if (!dsa) {
247
- OSSL_BIO_reset(in);
248
- #define PEM_read_bio_DSAPublicKey(bp,x,cb,u) (DSA *)PEM_ASN1_read_bio( \
249
- (d2i_of_void *)d2i_DSAPublicKey, PEM_STRING_DSA_PUBLIC, (bp), (void **)(x), (cb), (u))
250
- dsa = PEM_read_bio_DSAPublicKey(in, NULL, NULL, NULL);
251
- #undef PEM_read_bio_DSAPublicKey
252
- }
253
- BIO_free(in);
254
- if (!dsa) {
255
- ossl_clear_error();
256
- ossl_raise(eDSAError, "Neither PUB key nor PRIV key");
257
- }
258
- }
259
- if (!EVP_PKEY_assign_DSA(pkey, dsa)) {
260
- DSA_free(dsa);
261
- ossl_raise(eDSAError, NULL);
104
+
105
+ pass = ossl_pem_passwd_value(pass);
106
+ arg = ossl_to_der_if_possible(arg);
107
+ in = ossl_obj2bio(&arg);
108
+
109
+ /* DER-encoded DSAPublicKey format isn't supported by the generic routine */
110
+ dsa = (DSA *)PEM_ASN1_read_bio((d2i_of_void *)d2i_DSAPublicKey,
111
+ PEM_STRING_DSA_PUBLIC,
112
+ in, NULL, NULL, NULL);
113
+ if (dsa)
114
+ goto legacy;
115
+ OSSL_BIO_reset(in);
116
+
117
+ pkey = ossl_pkey_read_generic(in, pass);
118
+ BIO_free(in);
119
+ if (!pkey)
120
+ ossl_raise(eDSAError, "Neither PUB key nor PRIV key");
121
+
122
+ type = EVP_PKEY_base_id(pkey);
123
+ if (type != EVP_PKEY_DSA) {
124
+ EVP_PKEY_free(pkey);
125
+ rb_raise(eDSAError, "incorrect pkey type: %s", OBJ_nid2sn(type));
262
126
  }
127
+ RTYPEDDATA_DATA(self) = pkey;
128
+ return self;
263
129
 
130
+ legacy:
131
+ BIO_free(in);
132
+ pkey = EVP_PKEY_new();
133
+ if (!pkey || EVP_PKEY_assign_DSA(pkey, dsa) != 1) {
134
+ EVP_PKEY_free(pkey);
135
+ DSA_free(dsa);
136
+ ossl_raise(eDSAError, "EVP_PKEY_assign_DSA");
137
+ }
138
+ RTYPEDDATA_DATA(self) = pkey;
264
139
  return self;
265
140
  }
266
141
 
142
+ #ifndef HAVE_EVP_PKEY_DUP
267
143
  static VALUE
268
144
  ossl_dsa_initialize_copy(VALUE self, VALUE other)
269
145
  {
270
146
  EVP_PKEY *pkey;
271
147
  DSA *dsa, *dsa_new;
272
148
 
273
- GetPKey(self, pkey);
274
- if (EVP_PKEY_base_id(pkey) != EVP_PKEY_NONE)
275
- ossl_raise(eDSAError, "DSA already initialized");
149
+ TypedData_Get_Struct(self, EVP_PKEY, &ossl_evp_pkey_type, pkey);
150
+ if (pkey)
151
+ rb_raise(rb_eTypeError, "pkey already initialized");
276
152
  GetDSA(other, dsa);
277
153
 
278
- dsa_new = ASN1_dup((i2d_of_void *)i2d_DSAPrivateKey, (d2i_of_void *)d2i_DSAPrivateKey, (char *)dsa);
154
+ dsa_new = (DSA *)ASN1_dup((i2d_of_void *)i2d_DSAPrivateKey,
155
+ (d2i_of_void *)d2i_DSAPrivateKey,
156
+ (char *)dsa);
279
157
  if (!dsa_new)
280
158
  ossl_raise(eDSAError, "ASN1_dup");
281
159
 
282
- EVP_PKEY_assign_DSA(pkey, dsa_new);
160
+ pkey = EVP_PKEY_new();
161
+ if (!pkey || EVP_PKEY_assign_DSA(pkey, dsa_new) != 1) {
162
+ EVP_PKEY_free(pkey);
163
+ DSA_free(dsa_new);
164
+ ossl_raise(eDSAError, "EVP_PKEY_assign_DSA");
165
+ }
166
+ RTYPEDDATA_DATA(self) = pkey;
283
167
 
284
168
  return self;
285
169
  }
170
+ #endif
286
171
 
287
172
  /*
288
173
  * call-seq:
@@ -294,7 +179,7 @@ ossl_dsa_initialize_copy(VALUE self, VALUE other)
294
179
  static VALUE
295
180
  ossl_dsa_is_public(VALUE self)
296
181
  {
297
- DSA *dsa;
182
+ const DSA *dsa;
298
183
  const BIGNUM *bn;
299
184
 
300
185
  GetDSA(self, dsa);
@@ -313,7 +198,7 @@ ossl_dsa_is_public(VALUE self)
313
198
  static VALUE
314
199
  ossl_dsa_is_private(VALUE self)
315
200
  {
316
- DSA *dsa;
201
+ OSSL_3_const DSA *dsa;
317
202
 
318
203
  GetDSA(self, dsa);
319
204
 
@@ -326,81 +211,95 @@ ossl_dsa_is_private(VALUE self)
326
211
  * dsa.to_pem([cipher, password]) -> aString
327
212
  * dsa.to_s([cipher, password]) -> aString
328
213
  *
329
- * 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-----
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-----
330
256
  *
331
- * === Parameters
332
- * * _cipher_ is an OpenSSL::Cipher.
333
- * * _password_ is a string containing your password.
257
+ * Note that this format uses MD5 to derive the encryption key, and hence
258
+ * will not be available on FIPS-compliant systems.
334
259
  *
335
- * === Examples
336
- * DSA.to_pem -> aString
337
- * DSA.to_pem(cipher, 'mypassword') -> aString
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.
338
263
  *
264
+ * Consider using #public_to_pem (X.509 SubjectPublicKeyInfo) or #private_to_pem
265
+ * (PKCS #8 PrivateKeyInfo or EncryptedPrivateKeyInfo) instead.
339
266
  */
340
267
  static VALUE
341
268
  ossl_dsa_export(int argc, VALUE *argv, VALUE self)
342
269
  {
343
- DSA *dsa;
344
- BIO *out;
345
- const EVP_CIPHER *ciph = NULL;
346
- VALUE cipher, pass, str;
270
+ OSSL_3_const DSA *dsa;
347
271
 
348
272
  GetDSA(self, dsa);
349
- rb_scan_args(argc, argv, "02", &cipher, &pass);
350
- if (!NIL_P(cipher)) {
351
- ciph = ossl_evp_get_cipherbyname(cipher);
352
- pass = ossl_pem_passwd_value(pass);
353
- }
354
- if (!(out = BIO_new(BIO_s_mem()))) {
355
- ossl_raise(eDSAError, NULL);
356
- }
357
- if (DSA_HAS_PRIVATE(dsa)) {
358
- if (!PEM_write_bio_DSAPrivateKey(out, dsa, ciph, NULL, 0,
359
- ossl_pem_passwd_cb, (void *)pass)){
360
- BIO_free(out);
361
- ossl_raise(eDSAError, NULL);
362
- }
363
- } else {
364
- if (!PEM_write_bio_DSA_PUBKEY(out, dsa)) {
365
- BIO_free(out);
366
- ossl_raise(eDSAError, NULL);
367
- }
368
- }
369
- str = ossl_membio2str(out);
370
-
371
- return str;
273
+ if (DSA_HAS_PRIVATE(dsa))
274
+ return ossl_pkey_export_traditional(argc, argv, self, 0);
275
+ else
276
+ return ossl_pkey_export_spki(self, 0);
372
277
  }
373
278
 
374
279
  /*
375
280
  * call-seq:
376
281
  * dsa.to_der -> aString
377
282
  *
378
- * 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.
379
290
  *
291
+ * Consider using #public_to_der or #private_to_der instead.
380
292
  */
381
293
  static VALUE
382
294
  ossl_dsa_to_der(VALUE self)
383
295
  {
384
- DSA *dsa;
385
- int (*i2d_func)(DSA *, unsigned char **);
386
- unsigned char *p;
387
- long len;
388
- VALUE str;
296
+ OSSL_3_const DSA *dsa;
389
297
 
390
298
  GetDSA(self, dsa);
391
- if(DSA_HAS_PRIVATE(dsa))
392
- i2d_func = (int (*)(DSA *,unsigned char **))i2d_DSAPrivateKey;
299
+ if (DSA_HAS_PRIVATE(dsa))
300
+ return ossl_pkey_export_traditional(0, NULL, self, 1);
393
301
  else
394
- i2d_func = i2d_DSA_PUBKEY;
395
- if((len = i2d_func(dsa, NULL)) <= 0)
396
- ossl_raise(eDSAError, NULL);
397
- str = rb_str_new(0, len);
398
- p = (unsigned char *)RSTRING_PTR(str);
399
- if(i2d_func(dsa, &p) < 0)
400
- ossl_raise(eDSAError, NULL);
401
- ossl_str_adjust(str, p);
402
-
403
- return str;
302
+ return ossl_pkey_export_spki(self, 1);
404
303
  }
405
304
 
406
305
 
@@ -415,7 +314,7 @@ ossl_dsa_to_der(VALUE self)
415
314
  static VALUE
416
315
  ossl_dsa_get_params(VALUE self)
417
316
  {
418
- DSA *dsa;
317
+ OSSL_3_const DSA *dsa;
419
318
  VALUE hash;
420
319
  const BIGNUM *p, *q, *g, *pub_key, *priv_key;
421
320
 
@@ -433,158 +332,6 @@ ossl_dsa_get_params(VALUE self)
433
332
  return hash;
434
333
  }
435
334
 
436
- /*
437
- * call-seq:
438
- * dsa.to_text -> aString
439
- *
440
- * Prints all parameters of key to buffer
441
- * INSECURE: PRIVATE INFORMATIONS CAN LEAK OUT!!!
442
- * Don't use :-)) (I's up to you)
443
- */
444
- static VALUE
445
- ossl_dsa_to_text(VALUE self)
446
- {
447
- DSA *dsa;
448
- BIO *out;
449
- VALUE str;
450
-
451
- GetDSA(self, dsa);
452
- if (!(out = BIO_new(BIO_s_mem()))) {
453
- ossl_raise(eDSAError, NULL);
454
- }
455
- if (!DSA_print(out, dsa, 0)) { /* offset = 0 */
456
- BIO_free(out);
457
- ossl_raise(eDSAError, NULL);
458
- }
459
- str = ossl_membio2str(out);
460
-
461
- return str;
462
- }
463
-
464
- /*
465
- * call-seq:
466
- * dsa.public_key -> aDSA
467
- *
468
- * Returns a new DSA instance that carries just the public key information.
469
- * If the current instance has also private key information, this will no
470
- * longer be present in the new instance. This feature is helpful for
471
- * publishing the public key information without leaking any of the private
472
- * information.
473
- *
474
- * === Example
475
- * dsa = OpenSSL::PKey::DSA.new(2048) # has public and private information
476
- * pub_key = dsa.public_key # has only the public part available
477
- * pub_key_der = pub_key.to_der # it's safe to publish this
478
- *
479
- *
480
- */
481
- static VALUE
482
- ossl_dsa_to_public_key(VALUE self)
483
- {
484
- EVP_PKEY *pkey;
485
- DSA *dsa;
486
- VALUE obj;
487
-
488
- GetPKeyDSA(self, pkey);
489
- /* err check performed by dsa_instance */
490
- #define DSAPublicKey_dup(dsa) (DSA *)ASN1_dup( \
491
- (i2d_of_void *)i2d_DSAPublicKey, (d2i_of_void *)d2i_DSAPublicKey, (char *)(dsa))
492
- dsa = DSAPublicKey_dup(EVP_PKEY_get0_DSA(pkey));
493
- #undef DSAPublicKey_dup
494
- obj = dsa_instance(rb_obj_class(self), dsa);
495
- if (obj == Qfalse) {
496
- DSA_free(dsa);
497
- ossl_raise(eDSAError, NULL);
498
- }
499
- return obj;
500
- }
501
-
502
- /*
503
- * call-seq:
504
- * dsa.syssign(string) -> aString
505
- *
506
- * Computes and returns the DSA signature of _string_, where _string_ is
507
- * expected to be an already-computed message digest of the original input
508
- * data. The signature is issued using the private key of this DSA instance.
509
- *
510
- * === Parameters
511
- * * _string_ is a message digest of the original input data to be signed.
512
- *
513
- * === Example
514
- * dsa = OpenSSL::PKey::DSA.new(2048)
515
- * doc = "Sign me"
516
- * digest = OpenSSL::Digest.digest('SHA1', doc)
517
- * sig = dsa.syssign(digest)
518
- *
519
- *
520
- */
521
- static VALUE
522
- ossl_dsa_sign(VALUE self, VALUE data)
523
- {
524
- DSA *dsa;
525
- const BIGNUM *dsa_q;
526
- unsigned int buf_len;
527
- VALUE str;
528
-
529
- GetDSA(self, dsa);
530
- DSA_get0_pqg(dsa, NULL, &dsa_q, NULL);
531
- if (!dsa_q)
532
- ossl_raise(eDSAError, "incomplete DSA");
533
- if (!DSA_PRIVATE(self, dsa))
534
- ossl_raise(eDSAError, "Private DSA key needed!");
535
- StringValue(data);
536
- str = rb_str_new(0, DSA_size(dsa));
537
- if (!DSA_sign(0, (unsigned char *)RSTRING_PTR(data), RSTRING_LENINT(data),
538
- (unsigned char *)RSTRING_PTR(str),
539
- &buf_len, dsa)) { /* type is ignored (0) */
540
- ossl_raise(eDSAError, NULL);
541
- }
542
- rb_str_set_len(str, buf_len);
543
-
544
- return str;
545
- }
546
-
547
- /*
548
- * call-seq:
549
- * dsa.sysverify(digest, sig) -> true | false
550
- *
551
- * Verifies whether the signature is valid given the message digest input. It
552
- * does so by validating _sig_ using the public key of this DSA instance.
553
- *
554
- * === Parameters
555
- * * _digest_ is a message digest of the original input data to be signed
556
- * * _sig_ is a DSA signature value
557
- *
558
- * === Example
559
- * dsa = OpenSSL::PKey::DSA.new(2048)
560
- * doc = "Sign me"
561
- * digest = OpenSSL::Digest.digest('SHA1', doc)
562
- * sig = dsa.syssign(digest)
563
- * puts dsa.sysverify(digest, sig) # => true
564
- *
565
- */
566
- static VALUE
567
- ossl_dsa_verify(VALUE self, VALUE digest, VALUE sig)
568
- {
569
- DSA *dsa;
570
- int ret;
571
-
572
- GetDSA(self, dsa);
573
- StringValue(digest);
574
- StringValue(sig);
575
- /* type is ignored (0) */
576
- ret = DSA_verify(0, (unsigned char *)RSTRING_PTR(digest), RSTRING_LENINT(digest),
577
- (unsigned char *)RSTRING_PTR(sig), RSTRING_LENINT(sig), dsa);
578
- if (ret < 0) {
579
- ossl_raise(eDSAError, NULL);
580
- }
581
- else if (ret == 1) {
582
- return Qtrue;
583
- }
584
-
585
- return Qfalse;
586
- }
587
-
588
335
  /*
589
336
  * Document-method: OpenSSL::PKey::DSA#set_pqg
590
337
  * call-seq:
@@ -630,20 +377,17 @@ Init_ossl_dsa(void)
630
377
  */
631
378
  cDSA = rb_define_class_under(mPKey, "DSA", cPKey);
632
379
 
633
- rb_define_singleton_method(cDSA, "generate", ossl_dsa_s_generate, 1);
634
380
  rb_define_method(cDSA, "initialize", ossl_dsa_initialize, -1);
381
+ #ifndef HAVE_EVP_PKEY_DUP
635
382
  rb_define_method(cDSA, "initialize_copy", ossl_dsa_initialize_copy, 1);
383
+ #endif
636
384
 
637
385
  rb_define_method(cDSA, "public?", ossl_dsa_is_public, 0);
638
386
  rb_define_method(cDSA, "private?", ossl_dsa_is_private, 0);
639
- rb_define_method(cDSA, "to_text", ossl_dsa_to_text, 0);
640
387
  rb_define_method(cDSA, "export", ossl_dsa_export, -1);
641
388
  rb_define_alias(cDSA, "to_pem", "export");
642
389
  rb_define_alias(cDSA, "to_s", "export");
643
390
  rb_define_method(cDSA, "to_der", ossl_dsa_to_der, 0);
644
- rb_define_method(cDSA, "public_key", ossl_dsa_to_public_key, 0);
645
- rb_define_method(cDSA, "syssign", ossl_dsa_sign, 1);
646
- rb_define_method(cDSA, "sysverify", ossl_dsa_verify, 2);
647
391
 
648
392
  DEF_OSSL_PKEY_BN(cDSA, dsa, p);
649
393
  DEF_OSSL_PKEY_BN(cDSA, dsa, q);