openssl 2.1.0 → 3.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (64) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.md +35 -45
  3. data/History.md +426 -0
  4. data/README.md +38 -21
  5. data/ext/openssl/extconf.rb +132 -72
  6. data/ext/openssl/openssl_missing.c +0 -66
  7. data/ext/openssl/openssl_missing.h +62 -46
  8. data/ext/openssl/ossl.c +177 -252
  9. data/ext/openssl/ossl.h +39 -17
  10. data/ext/openssl/ossl_asn1.c +53 -14
  11. data/ext/openssl/ossl_bn.c +288 -146
  12. data/ext/openssl/ossl_bn.h +2 -1
  13. data/ext/openssl/ossl_cipher.c +42 -32
  14. data/ext/openssl/ossl_config.c +412 -41
  15. data/ext/openssl/ossl_config.h +4 -7
  16. data/ext/openssl/ossl_digest.c +32 -63
  17. data/ext/openssl/ossl_engine.c +19 -28
  18. data/ext/openssl/ossl_hmac.c +61 -146
  19. data/ext/openssl/ossl_kdf.c +15 -23
  20. data/ext/openssl/ossl_ns_spki.c +2 -2
  21. data/ext/openssl/ossl_ocsp.c +17 -70
  22. data/ext/openssl/ossl_ocsp.h +3 -3
  23. data/ext/openssl/ossl_pkcs12.c +23 -4
  24. data/ext/openssl/ossl_pkcs7.c +49 -81
  25. data/ext/openssl/ossl_pkcs7.h +16 -0
  26. data/ext/openssl/ossl_pkey.c +1508 -195
  27. data/ext/openssl/ossl_pkey.h +41 -78
  28. data/ext/openssl/ossl_pkey_dh.c +153 -348
  29. data/ext/openssl/ossl_pkey_dsa.c +157 -413
  30. data/ext/openssl/ossl_pkey_ec.c +257 -343
  31. data/ext/openssl/ossl_pkey_rsa.c +166 -490
  32. data/ext/openssl/ossl_provider.c +211 -0
  33. data/ext/openssl/ossl_provider.h +5 -0
  34. data/ext/openssl/ossl_rand.c +2 -40
  35. data/ext/openssl/ossl_ssl.c +666 -456
  36. data/ext/openssl/ossl_ssl_session.c +29 -30
  37. data/ext/openssl/ossl_ts.c +1539 -0
  38. data/ext/openssl/ossl_ts.h +16 -0
  39. data/ext/openssl/ossl_x509.c +86 -1
  40. data/ext/openssl/ossl_x509attr.c +1 -1
  41. data/ext/openssl/ossl_x509cert.c +170 -14
  42. data/ext/openssl/ossl_x509crl.c +14 -11
  43. data/ext/openssl/ossl_x509ext.c +29 -9
  44. data/ext/openssl/ossl_x509name.c +24 -12
  45. data/ext/openssl/ossl_x509req.c +14 -11
  46. data/ext/openssl/ossl_x509revoked.c +4 -4
  47. data/ext/openssl/ossl_x509store.c +205 -96
  48. data/lib/openssl/bn.rb +1 -1
  49. data/lib/openssl/buffering.rb +42 -20
  50. data/lib/openssl/cipher.rb +1 -1
  51. data/lib/openssl/digest.rb +10 -16
  52. data/lib/openssl/hmac.rb +78 -0
  53. data/lib/openssl/marshal.rb +30 -0
  54. data/lib/openssl/pkcs5.rb +1 -1
  55. data/lib/openssl/pkey.rb +447 -1
  56. data/lib/openssl/ssl.rb +68 -24
  57. data/lib/openssl/version.rb +5 -0
  58. data/lib/openssl/x509.rb +177 -1
  59. data/lib/openssl.rb +24 -9
  60. metadata +18 -71
  61. data/ext/openssl/deprecation.rb +0 -23
  62. data/ext/openssl/ossl_version.h +0 -15
  63. data/ext/openssl/ruby_missing.h +0 -24
  64. data/lib/openssl/config.rb +0 -474
@@ -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::SHA1.digest(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::SHA1.digest(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);