openssl-custom 2.2.2

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 (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 */