openssl-custom 2.2.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (75) hide show
  1. checksums.yaml +7 -0
  2. data/BSDL +22 -0
  3. data/CONTRIBUTING.md +132 -0
  4. data/History.md +485 -0
  5. data/LICENSE.txt +56 -0
  6. data/README.md +66 -0
  7. data/ext/openssl/extconf.rb +190 -0
  8. data/ext/openssl/openssl_missing.c +106 -0
  9. data/ext/openssl/openssl_missing.h +257 -0
  10. data/ext/openssl/ossl.c +1282 -0
  11. data/ext/openssl/ossl.h +181 -0
  12. data/ext/openssl/ossl_asn1.c +1878 -0
  13. data/ext/openssl/ossl_asn1.h +62 -0
  14. data/ext/openssl/ossl_bio.c +42 -0
  15. data/ext/openssl/ossl_bio.h +16 -0
  16. data/ext/openssl/ossl_bn.c +1270 -0
  17. data/ext/openssl/ossl_bn.h +26 -0
  18. data/ext/openssl/ossl_cipher.c +1075 -0
  19. data/ext/openssl/ossl_cipher.h +20 -0
  20. data/ext/openssl/ossl_config.c +89 -0
  21. data/ext/openssl/ossl_config.h +19 -0
  22. data/ext/openssl/ossl_digest.c +425 -0
  23. data/ext/openssl/ossl_digest.h +20 -0
  24. data/ext/openssl/ossl_engine.c +567 -0
  25. data/ext/openssl/ossl_engine.h +19 -0
  26. data/ext/openssl/ossl_hmac.c +389 -0
  27. data/ext/openssl/ossl_hmac.h +18 -0
  28. data/ext/openssl/ossl_kdf.c +303 -0
  29. data/ext/openssl/ossl_kdf.h +6 -0
  30. data/ext/openssl/ossl_ns_spki.c +405 -0
  31. data/ext/openssl/ossl_ns_spki.h +19 -0
  32. data/ext/openssl/ossl_ocsp.c +2013 -0
  33. data/ext/openssl/ossl_ocsp.h +23 -0
  34. data/ext/openssl/ossl_pkcs12.c +257 -0
  35. data/ext/openssl/ossl_pkcs12.h +13 -0
  36. data/ext/openssl/ossl_pkcs7.c +1098 -0
  37. data/ext/openssl/ossl_pkcs7.h +36 -0
  38. data/ext/openssl/ossl_pkey.c +673 -0
  39. data/ext/openssl/ossl_pkey.h +241 -0
  40. data/ext/openssl/ossl_pkey_dh.c +650 -0
  41. data/ext/openssl/ossl_pkey_dsa.c +664 -0
  42. data/ext/openssl/ossl_pkey_ec.c +1827 -0
  43. data/ext/openssl/ossl_pkey_rsa.c +966 -0
  44. data/ext/openssl/ossl_rand.c +200 -0
  45. data/ext/openssl/ossl_rand.h +18 -0
  46. data/ext/openssl/ossl_ssl.c +3080 -0
  47. data/ext/openssl/ossl_ssl.h +36 -0
  48. data/ext/openssl/ossl_ssl_session.c +332 -0
  49. data/ext/openssl/ossl_ts.c +1524 -0
  50. data/ext/openssl/ossl_ts.h +16 -0
  51. data/ext/openssl/ossl_x509.c +262 -0
  52. data/ext/openssl/ossl_x509.h +115 -0
  53. data/ext/openssl/ossl_x509attr.c +324 -0
  54. data/ext/openssl/ossl_x509cert.c +846 -0
  55. data/ext/openssl/ossl_x509crl.c +542 -0
  56. data/ext/openssl/ossl_x509ext.c +491 -0
  57. data/ext/openssl/ossl_x509name.c +590 -0
  58. data/ext/openssl/ossl_x509req.c +441 -0
  59. data/ext/openssl/ossl_x509revoked.c +300 -0
  60. data/ext/openssl/ossl_x509store.c +902 -0
  61. data/ext/openssl/ruby_missing.h +24 -0
  62. data/lib/openssl/bn.rb +40 -0
  63. data/lib/openssl/buffering.rb +478 -0
  64. data/lib/openssl/cipher.rb +67 -0
  65. data/lib/openssl/config.rb +501 -0
  66. data/lib/openssl/digest.rb +73 -0
  67. data/lib/openssl/hmac.rb +13 -0
  68. data/lib/openssl/marshal.rb +30 -0
  69. data/lib/openssl/pkcs5.rb +22 -0
  70. data/lib/openssl/pkey.rb +42 -0
  71. data/lib/openssl/ssl.rb +542 -0
  72. data/lib/openssl/version.rb +5 -0
  73. data/lib/openssl/x509.rb +369 -0
  74. data/lib/openssl.rb +38 -0
  75. metadata +196 -0
@@ -0,0 +1,664 @@
1
+ /*
2
+ * 'OpenSSL for Ruby' project
3
+ * Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz>
4
+ * All rights reserved.
5
+ */
6
+ /*
7
+ * This program is licensed under the same licence as Ruby.
8
+ * (See the file 'LICENCE'.)
9
+ */
10
+ #include "ossl.h"
11
+
12
+ #if !defined(OPENSSL_NO_DSA)
13
+
14
+ #define GetPKeyDSA(obj, pkey) do { \
15
+ GetPKey((obj), (pkey)); \
16
+ if (EVP_PKEY_base_id(pkey) != EVP_PKEY_DSA) { /* PARANOIA? */ \
17
+ ossl_raise(rb_eRuntimeError, "THIS IS NOT A DSA!"); \
18
+ } \
19
+ } while (0)
20
+ #define GetDSA(obj, dsa) do { \
21
+ EVP_PKEY *_pkey; \
22
+ GetPKeyDSA((obj), _pkey); \
23
+ (dsa) = EVP_PKEY_get0_DSA(_pkey); \
24
+ } while (0)
25
+
26
+ static inline int
27
+ DSA_HAS_PRIVATE(DSA *dsa)
28
+ {
29
+ const BIGNUM *bn;
30
+ DSA_get0_key(dsa, NULL, &bn);
31
+ return !!bn;
32
+ }
33
+
34
+ static inline int
35
+ DSA_PRIVATE(VALUE obj, DSA *dsa)
36
+ {
37
+ return DSA_HAS_PRIVATE(dsa) || OSSL_PKEY_IS_PRIVATE(obj);
38
+ }
39
+
40
+ /*
41
+ * Classes
42
+ */
43
+ VALUE cDSA;
44
+ VALUE eDSAError;
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
+ /*
93
+ * Private
94
+ */
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
+ /*
193
+ * call-seq:
194
+ * DSA.new -> dsa
195
+ * DSA.new(size) -> dsa
196
+ * DSA.new(string [, pass]) -> dsa
197
+ *
198
+ * Creates a new DSA instance by reading an existing key from _string_.
199
+ *
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.
204
+ *
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
210
+ *
211
+ */
212
+ static VALUE
213
+ ossl_dsa_initialize(int argc, VALUE *argv, VALUE self)
214
+ {
215
+ EVP_PKEY *pkey;
216
+ DSA *dsa;
217
+ BIO *in;
218
+ VALUE arg, pass;
219
+
220
+ GetPKey(self, pkey);
221
+ if(rb_scan_args(argc, argv, "02", &arg, &pass) == 0) {
222
+ dsa = DSA_new();
223
+ }
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);
262
+ }
263
+
264
+ return self;
265
+ }
266
+
267
+ static VALUE
268
+ ossl_dsa_initialize_copy(VALUE self, VALUE other)
269
+ {
270
+ EVP_PKEY *pkey;
271
+ DSA *dsa, *dsa_new;
272
+
273
+ GetPKey(self, pkey);
274
+ if (EVP_PKEY_base_id(pkey) != EVP_PKEY_NONE)
275
+ ossl_raise(eDSAError, "DSA already initialized");
276
+ GetDSA(other, dsa);
277
+
278
+ dsa_new = ASN1_dup((i2d_of_void *)i2d_DSAPrivateKey, (d2i_of_void *)d2i_DSAPrivateKey, (char *)dsa);
279
+ if (!dsa_new)
280
+ ossl_raise(eDSAError, "ASN1_dup");
281
+
282
+ EVP_PKEY_assign_DSA(pkey, dsa_new);
283
+
284
+ return self;
285
+ }
286
+
287
+ /*
288
+ * call-seq:
289
+ * dsa.public? -> true | false
290
+ *
291
+ * Indicates whether this DSA instance has a public key associated with it or
292
+ * not. The public key may be retrieved with DSA#public_key.
293
+ */
294
+ static VALUE
295
+ ossl_dsa_is_public(VALUE self)
296
+ {
297
+ DSA *dsa;
298
+ const BIGNUM *bn;
299
+
300
+ GetDSA(self, dsa);
301
+ DSA_get0_key(dsa, &bn, NULL);
302
+
303
+ return bn ? Qtrue : Qfalse;
304
+ }
305
+
306
+ /*
307
+ * call-seq:
308
+ * dsa.private? -> true | false
309
+ *
310
+ * Indicates whether this DSA instance has a private key associated with it or
311
+ * not. The private key may be retrieved with DSA#private_key.
312
+ */
313
+ static VALUE
314
+ ossl_dsa_is_private(VALUE self)
315
+ {
316
+ DSA *dsa;
317
+
318
+ GetDSA(self, dsa);
319
+
320
+ return DSA_PRIVATE(self, dsa) ? Qtrue : Qfalse;
321
+ }
322
+
323
+ /*
324
+ * call-seq:
325
+ * dsa.export([cipher, password]) -> aString
326
+ * dsa.to_pem([cipher, password]) -> aString
327
+ * dsa.to_s([cipher, password]) -> aString
328
+ *
329
+ * Encodes this DSA to its PEM encoding.
330
+ *
331
+ * === Parameters
332
+ * * _cipher_ is an OpenSSL::Cipher.
333
+ * * _password_ is a string containing your password.
334
+ *
335
+ * === Examples
336
+ * DSA.to_pem -> aString
337
+ * DSA.to_pem(cipher, 'mypassword') -> aString
338
+ *
339
+ */
340
+ static VALUE
341
+ ossl_dsa_export(int argc, VALUE *argv, VALUE self)
342
+ {
343
+ DSA *dsa;
344
+ BIO *out;
345
+ const EVP_CIPHER *ciph = NULL;
346
+ VALUE cipher, pass, str;
347
+
348
+ 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;
372
+ }
373
+
374
+ /*
375
+ * call-seq:
376
+ * dsa.to_der -> aString
377
+ *
378
+ * Encodes this DSA to its DER encoding.
379
+ *
380
+ */
381
+ static VALUE
382
+ ossl_dsa_to_der(VALUE self)
383
+ {
384
+ DSA *dsa;
385
+ int (*i2d_func)(DSA *, unsigned char **);
386
+ unsigned char *p;
387
+ long len;
388
+ VALUE str;
389
+
390
+ GetDSA(self, dsa);
391
+ if(DSA_HAS_PRIVATE(dsa))
392
+ i2d_func = (int (*)(DSA *,unsigned char **))i2d_DSAPrivateKey;
393
+ 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;
404
+ }
405
+
406
+
407
+ /*
408
+ * call-seq:
409
+ * dsa.params -> hash
410
+ *
411
+ * Stores all parameters of key to the hash
412
+ * INSECURE: PRIVATE INFORMATIONS CAN LEAK OUT!!!
413
+ * Don't use :-)) (I's up to you)
414
+ */
415
+ static VALUE
416
+ ossl_dsa_get_params(VALUE self)
417
+ {
418
+ DSA *dsa;
419
+ VALUE hash;
420
+ const BIGNUM *p, *q, *g, *pub_key, *priv_key;
421
+
422
+ GetDSA(self, dsa);
423
+ DSA_get0_pqg(dsa, &p, &q, &g);
424
+ DSA_get0_key(dsa, &pub_key, &priv_key);
425
+
426
+ hash = rb_hash_new();
427
+ rb_hash_aset(hash, rb_str_new2("p"), ossl_bn_new(p));
428
+ rb_hash_aset(hash, rb_str_new2("q"), ossl_bn_new(q));
429
+ rb_hash_aset(hash, rb_str_new2("g"), ossl_bn_new(g));
430
+ rb_hash_aset(hash, rb_str_new2("pub_key"), ossl_bn_new(pub_key));
431
+ rb_hash_aset(hash, rb_str_new2("priv_key"), ossl_bn_new(priv_key));
432
+
433
+ return hash;
434
+ }
435
+
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
+ /*
589
+ * Document-method: OpenSSL::PKey::DSA#set_pqg
590
+ * call-seq:
591
+ * dsa.set_pqg(p, q, g) -> self
592
+ *
593
+ * Sets _p_, _q_, _g_ to the DSA instance.
594
+ */
595
+ OSSL_PKEY_BN_DEF3(dsa, DSA, pqg, p, q, g)
596
+ /*
597
+ * Document-method: OpenSSL::PKey::DSA#set_key
598
+ * call-seq:
599
+ * dsa.set_key(pub_key, priv_key) -> self
600
+ *
601
+ * Sets _pub_key_ and _priv_key_ for the DSA instance. _priv_key_ may be +nil+.
602
+ */
603
+ OSSL_PKEY_BN_DEF2(dsa, DSA, key, pub_key, priv_key)
604
+
605
+ /*
606
+ * INIT
607
+ */
608
+ void
609
+ Init_ossl_dsa(void)
610
+ {
611
+ #if 0
612
+ mPKey = rb_define_module_under(mOSSL, "PKey");
613
+ cPKey = rb_define_class_under(mPKey, "PKey", rb_cObject);
614
+ ePKeyError = rb_define_class_under(mPKey, "PKeyError", eOSSLError);
615
+ #endif
616
+
617
+ /* Document-class: OpenSSL::PKey::DSAError
618
+ *
619
+ * Generic exception that is raised if an operation on a DSA PKey
620
+ * fails unexpectedly or in case an instantiation of an instance of DSA
621
+ * fails due to non-conformant input data.
622
+ */
623
+ eDSAError = rb_define_class_under(mPKey, "DSAError", ePKeyError);
624
+
625
+ /* Document-class: OpenSSL::PKey::DSA
626
+ *
627
+ * DSA, the Digital Signature Algorithm, is specified in NIST's
628
+ * FIPS 186-3. It is an asymmetric public key algorithm that may be used
629
+ * similar to e.g. RSA.
630
+ */
631
+ cDSA = rb_define_class_under(mPKey, "DSA", cPKey);
632
+
633
+ rb_define_singleton_method(cDSA, "generate", ossl_dsa_s_generate, 1);
634
+ rb_define_method(cDSA, "initialize", ossl_dsa_initialize, -1);
635
+ rb_define_method(cDSA, "initialize_copy", ossl_dsa_initialize_copy, 1);
636
+
637
+ rb_define_method(cDSA, "public?", ossl_dsa_is_public, 0);
638
+ rb_define_method(cDSA, "private?", ossl_dsa_is_private, 0);
639
+ rb_define_method(cDSA, "to_text", ossl_dsa_to_text, 0);
640
+ rb_define_method(cDSA, "export", ossl_dsa_export, -1);
641
+ rb_define_alias(cDSA, "to_pem", "export");
642
+ rb_define_alias(cDSA, "to_s", "export");
643
+ 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
+
648
+ DEF_OSSL_PKEY_BN(cDSA, dsa, p);
649
+ DEF_OSSL_PKEY_BN(cDSA, dsa, q);
650
+ DEF_OSSL_PKEY_BN(cDSA, dsa, g);
651
+ DEF_OSSL_PKEY_BN(cDSA, dsa, pub_key);
652
+ DEF_OSSL_PKEY_BN(cDSA, dsa, priv_key);
653
+ rb_define_method(cDSA, "set_pqg", ossl_dsa_set_pqg, 3);
654
+ rb_define_method(cDSA, "set_key", ossl_dsa_set_key, 2);
655
+
656
+ rb_define_method(cDSA, "params", ossl_dsa_get_params, 0);
657
+ }
658
+
659
+ #else /* defined NO_DSA */
660
+ void
661
+ Init_ossl_dsa(void)
662
+ {
663
+ }
664
+ #endif /* NO_DSA */