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,650 @@
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_DH)
13
+
14
+ #define GetPKeyDH(obj, pkey) do { \
15
+ GetPKey((obj), (pkey)); \
16
+ if (EVP_PKEY_base_id(pkey) != EVP_PKEY_DH) { /* PARANOIA? */ \
17
+ ossl_raise(rb_eRuntimeError, "THIS IS NOT A DH!") ; \
18
+ } \
19
+ } while (0)
20
+ #define GetDH(obj, dh) do { \
21
+ EVP_PKEY *_pkey; \
22
+ GetPKeyDH((obj), _pkey); \
23
+ (dh) = EVP_PKEY_get0_DH(_pkey); \
24
+ } while (0)
25
+
26
+ /*
27
+ * Classes
28
+ */
29
+ VALUE cDH;
30
+ VALUE eDHError;
31
+
32
+ /*
33
+ * Public
34
+ */
35
+ static VALUE
36
+ dh_instance(VALUE klass, DH *dh)
37
+ {
38
+ EVP_PKEY *pkey;
39
+ VALUE obj;
40
+
41
+ if (!dh) {
42
+ return Qfalse;
43
+ }
44
+ obj = NewPKey(klass);
45
+ if (!(pkey = EVP_PKEY_new())) {
46
+ return Qfalse;
47
+ }
48
+ if (!EVP_PKEY_assign_DH(pkey, dh)) {
49
+ EVP_PKEY_free(pkey);
50
+ return Qfalse;
51
+ }
52
+ SetPKey(obj, pkey);
53
+
54
+ return obj;
55
+ }
56
+
57
+ VALUE
58
+ ossl_dh_new(EVP_PKEY *pkey)
59
+ {
60
+ VALUE obj;
61
+
62
+ if (!pkey) {
63
+ obj = dh_instance(cDH, DH_new());
64
+ } else {
65
+ obj = NewPKey(cDH);
66
+ if (EVP_PKEY_base_id(pkey) != EVP_PKEY_DH) {
67
+ ossl_raise(rb_eTypeError, "Not a DH key!");
68
+ }
69
+ SetPKey(obj, pkey);
70
+ }
71
+ if (obj == Qfalse) {
72
+ ossl_raise(eDHError, NULL);
73
+ }
74
+
75
+ return obj;
76
+ }
77
+
78
+ /*
79
+ * Private
80
+ */
81
+ struct dh_blocking_gen_arg {
82
+ DH *dh;
83
+ int size;
84
+ int gen;
85
+ BN_GENCB *cb;
86
+ int result;
87
+ };
88
+
89
+ static void *
90
+ dh_blocking_gen(void *arg)
91
+ {
92
+ struct dh_blocking_gen_arg *gen = (struct dh_blocking_gen_arg *)arg;
93
+ gen->result = DH_generate_parameters_ex(gen->dh, gen->size, gen->gen, gen->cb);
94
+ return 0;
95
+ }
96
+
97
+ static DH *
98
+ dh_generate(int size, int gen)
99
+ {
100
+ struct ossl_generate_cb_arg cb_arg = { 0 };
101
+ struct dh_blocking_gen_arg gen_arg;
102
+ DH *dh = DH_new();
103
+ BN_GENCB *cb = BN_GENCB_new();
104
+
105
+ if (!dh || !cb) {
106
+ DH_free(dh);
107
+ BN_GENCB_free(cb);
108
+ return NULL;
109
+ }
110
+
111
+ if (rb_block_given_p())
112
+ cb_arg.yield = 1;
113
+ BN_GENCB_set(cb, ossl_generate_cb_2, &cb_arg);
114
+ gen_arg.dh = dh;
115
+ gen_arg.size = size;
116
+ gen_arg.gen = gen;
117
+ gen_arg.cb = cb;
118
+ if (cb_arg.yield == 1) {
119
+ /* we cannot release GVL when callback proc is supplied */
120
+ dh_blocking_gen(&gen_arg);
121
+ } else {
122
+ /* there's a chance to unblock */
123
+ rb_thread_call_without_gvl(dh_blocking_gen, &gen_arg, ossl_generate_cb_stop, &cb_arg);
124
+ }
125
+
126
+ BN_GENCB_free(cb);
127
+ if (!gen_arg.result) {
128
+ DH_free(dh);
129
+ if (cb_arg.state) {
130
+ /* Clear OpenSSL error queue before re-raising. */
131
+ ossl_clear_error();
132
+ rb_jump_tag(cb_arg.state);
133
+ }
134
+ return NULL;
135
+ }
136
+
137
+ if (!DH_generate_key(dh)) {
138
+ DH_free(dh);
139
+ return NULL;
140
+ }
141
+
142
+ return dh;
143
+ }
144
+
145
+ /*
146
+ * call-seq:
147
+ * DH.generate(size [, generator]) -> dh
148
+ *
149
+ * Creates a new DH instance from scratch by generating the private and public
150
+ * components alike.
151
+ *
152
+ * === Parameters
153
+ * * _size_ is an integer representing the desired key size. Keys smaller than 1024 bits should be considered insecure.
154
+ * * _generator_ is a small number > 1, typically 2 or 5.
155
+ *
156
+ */
157
+ static VALUE
158
+ ossl_dh_s_generate(int argc, VALUE *argv, VALUE klass)
159
+ {
160
+ DH *dh ;
161
+ int g = 2;
162
+ VALUE size, gen, obj;
163
+
164
+ if (rb_scan_args(argc, argv, "11", &size, &gen) == 2) {
165
+ g = NUM2INT(gen);
166
+ }
167
+ dh = dh_generate(NUM2INT(size), g);
168
+ obj = dh_instance(klass, dh);
169
+ if (obj == Qfalse) {
170
+ DH_free(dh);
171
+ ossl_raise(eDHError, NULL);
172
+ }
173
+
174
+ return obj;
175
+ }
176
+
177
+ /*
178
+ * call-seq:
179
+ * DH.new -> dh
180
+ * DH.new(string) -> dh
181
+ * DH.new(size [, generator]) -> dh
182
+ *
183
+ * Either generates a DH instance from scratch or by reading already existing
184
+ * DH parameters from _string_. Note that when reading a DH instance from
185
+ * data that was encoded from a DH instance by using DH#to_pem or DH#to_der
186
+ * the result will *not* contain a public/private key pair yet. This needs to
187
+ * be generated using DH#generate_key! first.
188
+ *
189
+ * === Parameters
190
+ * * _size_ is an integer representing the desired key size. Keys smaller than 1024 bits should be considered insecure.
191
+ * * _generator_ is a small number > 1, typically 2 or 5.
192
+ * * _string_ contains the DER or PEM encoded key.
193
+ *
194
+ * === Examples
195
+ * DH.new # -> dh
196
+ * DH.new(1024) # -> dh
197
+ * DH.new(1024, 5) # -> dh
198
+ * #Reading DH parameters
199
+ * dh = DH.new(File.read('parameters.pem')) # -> dh, but no public/private key yet
200
+ * dh.generate_key! # -> dh with public and private key
201
+ */
202
+ static VALUE
203
+ ossl_dh_initialize(int argc, VALUE *argv, VALUE self)
204
+ {
205
+ EVP_PKEY *pkey;
206
+ DH *dh;
207
+ int g = 2;
208
+ BIO *in;
209
+ VALUE arg, gen;
210
+
211
+ GetPKey(self, pkey);
212
+ if(rb_scan_args(argc, argv, "02", &arg, &gen) == 0) {
213
+ dh = DH_new();
214
+ }
215
+ else if (RB_INTEGER_TYPE_P(arg)) {
216
+ if (!NIL_P(gen)) {
217
+ g = NUM2INT(gen);
218
+ }
219
+ if (!(dh = dh_generate(NUM2INT(arg), g))) {
220
+ ossl_raise(eDHError, NULL);
221
+ }
222
+ }
223
+ else {
224
+ arg = ossl_to_der_if_possible(arg);
225
+ in = ossl_obj2bio(&arg);
226
+ dh = PEM_read_bio_DHparams(in, NULL, NULL, NULL);
227
+ if (!dh){
228
+ OSSL_BIO_reset(in);
229
+ dh = d2i_DHparams_bio(in, NULL);
230
+ }
231
+ BIO_free(in);
232
+ if (!dh) {
233
+ ossl_raise(eDHError, NULL);
234
+ }
235
+ }
236
+ if (!EVP_PKEY_assign_DH(pkey, dh)) {
237
+ DH_free(dh);
238
+ ossl_raise(eDHError, NULL);
239
+ }
240
+ return self;
241
+ }
242
+
243
+ static VALUE
244
+ ossl_dh_initialize_copy(VALUE self, VALUE other)
245
+ {
246
+ EVP_PKEY *pkey;
247
+ DH *dh, *dh_other;
248
+ const BIGNUM *pub, *priv;
249
+
250
+ GetPKey(self, pkey);
251
+ if (EVP_PKEY_base_id(pkey) != EVP_PKEY_NONE)
252
+ ossl_raise(eDHError, "DH already initialized");
253
+ GetDH(other, dh_other);
254
+
255
+ dh = DHparams_dup(dh_other);
256
+ if (!dh)
257
+ ossl_raise(eDHError, "DHparams_dup");
258
+ EVP_PKEY_assign_DH(pkey, dh);
259
+
260
+ DH_get0_key(dh_other, &pub, &priv);
261
+ if (pub) {
262
+ BIGNUM *pub2 = BN_dup(pub);
263
+ BIGNUM *priv2 = BN_dup(priv);
264
+
265
+ if (!pub2 || (priv && !priv2)) {
266
+ BN_clear_free(pub2);
267
+ BN_clear_free(priv2);
268
+ ossl_raise(eDHError, "BN_dup");
269
+ }
270
+ DH_set0_key(dh, pub2, priv2);
271
+ }
272
+
273
+ return self;
274
+ }
275
+
276
+ /*
277
+ * call-seq:
278
+ * dh.public? -> true | false
279
+ *
280
+ * Indicates whether this DH instance has a public key associated with it or
281
+ * not. The public key may be retrieved with DH#pub_key.
282
+ */
283
+ static VALUE
284
+ ossl_dh_is_public(VALUE self)
285
+ {
286
+ DH *dh;
287
+ const BIGNUM *bn;
288
+
289
+ GetDH(self, dh);
290
+ DH_get0_key(dh, &bn, NULL);
291
+
292
+ return bn ? Qtrue : Qfalse;
293
+ }
294
+
295
+ /*
296
+ * call-seq:
297
+ * dh.private? -> true | false
298
+ *
299
+ * Indicates whether this DH instance has a private key associated with it or
300
+ * not. The private key may be retrieved with DH#priv_key.
301
+ */
302
+ static VALUE
303
+ ossl_dh_is_private(VALUE self)
304
+ {
305
+ DH *dh;
306
+ const BIGNUM *bn;
307
+
308
+ GetDH(self, dh);
309
+ DH_get0_key(dh, NULL, &bn);
310
+
311
+ #if !defined(OPENSSL_NO_ENGINE)
312
+ return (bn || DH_get0_engine(dh)) ? Qtrue : Qfalse;
313
+ #else
314
+ return bn ? Qtrue : Qfalse;
315
+ #endif
316
+ }
317
+
318
+ /*
319
+ * call-seq:
320
+ * dh.export -> aString
321
+ * dh.to_pem -> aString
322
+ * dh.to_s -> aString
323
+ *
324
+ * Encodes this DH to its PEM encoding. Note that any existing per-session
325
+ * public/private keys will *not* get encoded, just the Diffie-Hellman
326
+ * parameters will be encoded.
327
+ */
328
+ static VALUE
329
+ ossl_dh_export(VALUE self)
330
+ {
331
+ DH *dh;
332
+ BIO *out;
333
+ VALUE str;
334
+
335
+ GetDH(self, dh);
336
+ if (!(out = BIO_new(BIO_s_mem()))) {
337
+ ossl_raise(eDHError, NULL);
338
+ }
339
+ if (!PEM_write_bio_DHparams(out, dh)) {
340
+ BIO_free(out);
341
+ ossl_raise(eDHError, NULL);
342
+ }
343
+ str = ossl_membio2str(out);
344
+
345
+ return str;
346
+ }
347
+
348
+ /*
349
+ * call-seq:
350
+ * dh.to_der -> aString
351
+ *
352
+ * Encodes this DH to its DER encoding. Note that any existing per-session
353
+ * public/private keys will *not* get encoded, just the Diffie-Hellman
354
+ * parameters will be encoded.
355
+
356
+ */
357
+ static VALUE
358
+ ossl_dh_to_der(VALUE self)
359
+ {
360
+ DH *dh;
361
+ unsigned char *p;
362
+ long len;
363
+ VALUE str;
364
+
365
+ GetDH(self, dh);
366
+ if((len = i2d_DHparams(dh, NULL)) <= 0)
367
+ ossl_raise(eDHError, NULL);
368
+ str = rb_str_new(0, len);
369
+ p = (unsigned char *)RSTRING_PTR(str);
370
+ if(i2d_DHparams(dh, &p) < 0)
371
+ ossl_raise(eDHError, NULL);
372
+ ossl_str_adjust(str, p);
373
+
374
+ return str;
375
+ }
376
+
377
+ /*
378
+ * call-seq:
379
+ * dh.params -> hash
380
+ *
381
+ * Stores all parameters of key to the hash
382
+ * INSECURE: PRIVATE INFORMATIONS CAN LEAK OUT!!!
383
+ * Don't use :-)) (I's up to you)
384
+ */
385
+ static VALUE
386
+ ossl_dh_get_params(VALUE self)
387
+ {
388
+ DH *dh;
389
+ VALUE hash;
390
+ const BIGNUM *p, *q, *g, *pub_key, *priv_key;
391
+
392
+ GetDH(self, dh);
393
+ DH_get0_pqg(dh, &p, &q, &g);
394
+ DH_get0_key(dh, &pub_key, &priv_key);
395
+
396
+ hash = rb_hash_new();
397
+ rb_hash_aset(hash, rb_str_new2("p"), ossl_bn_new(p));
398
+ rb_hash_aset(hash, rb_str_new2("q"), ossl_bn_new(q));
399
+ rb_hash_aset(hash, rb_str_new2("g"), ossl_bn_new(g));
400
+ rb_hash_aset(hash, rb_str_new2("pub_key"), ossl_bn_new(pub_key));
401
+ rb_hash_aset(hash, rb_str_new2("priv_key"), ossl_bn_new(priv_key));
402
+
403
+ return hash;
404
+ }
405
+
406
+ /*
407
+ * call-seq:
408
+ * dh.to_text -> aString
409
+ *
410
+ * Prints all parameters of key to buffer
411
+ * INSECURE: PRIVATE INFORMATIONS CAN LEAK OUT!!!
412
+ * Don't use :-)) (I's up to you)
413
+ */
414
+ static VALUE
415
+ ossl_dh_to_text(VALUE self)
416
+ {
417
+ DH *dh;
418
+ BIO *out;
419
+ VALUE str;
420
+
421
+ GetDH(self, dh);
422
+ if (!(out = BIO_new(BIO_s_mem()))) {
423
+ ossl_raise(eDHError, NULL);
424
+ }
425
+ if (!DHparams_print(out, dh)) {
426
+ BIO_free(out);
427
+ ossl_raise(eDHError, NULL);
428
+ }
429
+ str = ossl_membio2str(out);
430
+
431
+ return str;
432
+ }
433
+
434
+ /*
435
+ * call-seq:
436
+ * dh.public_key -> aDH
437
+ *
438
+ * Returns a new DH instance that carries just the public information, i.e.
439
+ * the prime _p_ and the generator _g_, but no public/private key yet. Such
440
+ * a pair may be generated using DH#generate_key!. The "public key" needed
441
+ * for a key exchange with DH#compute_key is considered as per-session
442
+ * information and may be retrieved with DH#pub_key once a key pair has
443
+ * been generated.
444
+ * If the current instance already contains private information (and thus a
445
+ * valid public/private key pair), this information will no longer be present
446
+ * in the new instance generated by DH#public_key. This feature is helpful for
447
+ * publishing the Diffie-Hellman parameters without leaking any of the private
448
+ * per-session information.
449
+ *
450
+ * === Example
451
+ * dh = OpenSSL::PKey::DH.new(2048) # has public and private key set
452
+ * public_key = dh.public_key # contains only prime and generator
453
+ * parameters = public_key.to_der # it's safe to publish this
454
+ */
455
+ static VALUE
456
+ ossl_dh_to_public_key(VALUE self)
457
+ {
458
+ DH *orig_dh, *dh;
459
+ VALUE obj;
460
+
461
+ GetDH(self, orig_dh);
462
+ dh = DHparams_dup(orig_dh); /* err check perfomed by dh_instance */
463
+ obj = dh_instance(rb_obj_class(self), dh);
464
+ if (obj == Qfalse) {
465
+ DH_free(dh);
466
+ ossl_raise(eDHError, NULL);
467
+ }
468
+
469
+ return obj;
470
+ }
471
+
472
+ /*
473
+ * call-seq:
474
+ * dh.params_ok? -> true | false
475
+ *
476
+ * Validates the Diffie-Hellman parameters associated with this instance.
477
+ * It checks whether a safe prime and a suitable generator are used. If this
478
+ * is not the case, +false+ is returned.
479
+ */
480
+ static VALUE
481
+ ossl_dh_check_params(VALUE self)
482
+ {
483
+ DH *dh;
484
+ int codes;
485
+
486
+ GetDH(self, dh);
487
+ if (!DH_check(dh, &codes)) {
488
+ return Qfalse;
489
+ }
490
+
491
+ return codes == 0 ? Qtrue : Qfalse;
492
+ }
493
+
494
+ /*
495
+ * call-seq:
496
+ * dh.generate_key! -> self
497
+ *
498
+ * Generates a private and public key unless a private key already exists.
499
+ * If this DH instance was generated from public DH parameters (e.g. by
500
+ * encoding the result of DH#public_key), then this method needs to be
501
+ * called first in order to generate the per-session keys before performing
502
+ * the actual key exchange.
503
+ *
504
+ * === Example
505
+ * dh = OpenSSL::PKey::DH.new(2048)
506
+ * public_key = dh.public_key #contains no private/public key yet
507
+ * public_key.generate_key!
508
+ * puts public_key.private? # => true
509
+ */
510
+ static VALUE
511
+ ossl_dh_generate_key(VALUE self)
512
+ {
513
+ DH *dh;
514
+
515
+ GetDH(self, dh);
516
+ if (!DH_generate_key(dh))
517
+ ossl_raise(eDHError, "Failed to generate key");
518
+ return self;
519
+ }
520
+
521
+ /*
522
+ * call-seq:
523
+ * dh.compute_key(pub_bn) -> aString
524
+ *
525
+ * Returns a String containing a shared secret computed from the other party's public value.
526
+ * See DH_compute_key() for further information.
527
+ *
528
+ * === Parameters
529
+ * * _pub_bn_ is a OpenSSL::BN, *not* the DH instance returned by
530
+ * DH#public_key as that contains the DH parameters only.
531
+ */
532
+ static VALUE
533
+ ossl_dh_compute_key(VALUE self, VALUE pub)
534
+ {
535
+ DH *dh;
536
+ const BIGNUM *pub_key, *dh_p;
537
+ VALUE str;
538
+ int len;
539
+
540
+ GetDH(self, dh);
541
+ DH_get0_pqg(dh, &dh_p, NULL, NULL);
542
+ if (!dh_p)
543
+ ossl_raise(eDHError, "incomplete DH");
544
+ pub_key = GetBNPtr(pub);
545
+ len = DH_size(dh);
546
+ str = rb_str_new(0, len);
547
+ if ((len = DH_compute_key((unsigned char *)RSTRING_PTR(str), pub_key, dh)) < 0) {
548
+ ossl_raise(eDHError, NULL);
549
+ }
550
+ rb_str_set_len(str, len);
551
+
552
+ return str;
553
+ }
554
+
555
+ /*
556
+ * Document-method: OpenSSL::PKey::DH#set_pqg
557
+ * call-seq:
558
+ * dh.set_pqg(p, q, g) -> self
559
+ *
560
+ * Sets _p_, _q_, _g_ to the DH instance.
561
+ */
562
+ OSSL_PKEY_BN_DEF3(dh, DH, pqg, p, q, g)
563
+ /*
564
+ * Document-method: OpenSSL::PKey::DH#set_key
565
+ * call-seq:
566
+ * dh.set_key(pub_key, priv_key) -> self
567
+ *
568
+ * Sets _pub_key_ and _priv_key_ for the DH instance. _priv_key_ may be +nil+.
569
+ */
570
+ OSSL_PKEY_BN_DEF2(dh, DH, key, pub_key, priv_key)
571
+
572
+ /*
573
+ * INIT
574
+ */
575
+ void
576
+ Init_ossl_dh(void)
577
+ {
578
+ #if 0
579
+ mPKey = rb_define_module_under(mOSSL, "PKey");
580
+ cPKey = rb_define_class_under(mPKey, "PKey", rb_cObject);
581
+ ePKeyError = rb_define_class_under(mPKey, "PKeyError", eOSSLError);
582
+ #endif
583
+
584
+ /* Document-class: OpenSSL::PKey::DHError
585
+ *
586
+ * Generic exception that is raised if an operation on a DH PKey
587
+ * fails unexpectedly or in case an instantiation of an instance of DH
588
+ * fails due to non-conformant input data.
589
+ */
590
+ eDHError = rb_define_class_under(mPKey, "DHError", ePKeyError);
591
+ /* Document-class: OpenSSL::PKey::DH
592
+ *
593
+ * An implementation of the Diffie-Hellman key exchange protocol based on
594
+ * discrete logarithms in finite fields, the same basis that DSA is built
595
+ * on.
596
+ *
597
+ * === Accessor methods for the Diffie-Hellman parameters
598
+ * DH#p::
599
+ * The prime (an OpenSSL::BN) of the Diffie-Hellman parameters.
600
+ * DH#g::
601
+ * The generator (an OpenSSL::BN) g of the Diffie-Hellman parameters.
602
+ * DH#pub_key::
603
+ * The per-session public key (an OpenSSL::BN) matching the private key.
604
+ * This needs to be passed to DH#compute_key.
605
+ * DH#priv_key::
606
+ * The per-session private key, an OpenSSL::BN.
607
+ *
608
+ * === Example of a key exchange
609
+ * dh1 = OpenSSL::PKey::DH.new(2048)
610
+ * der = dh1.public_key.to_der #you may send this publicly to the participating party
611
+ * dh2 = OpenSSL::PKey::DH.new(der)
612
+ * dh2.generate_key! #generate the per-session key pair
613
+ * symm_key1 = dh1.compute_key(dh2.pub_key)
614
+ * symm_key2 = dh2.compute_key(dh1.pub_key)
615
+ *
616
+ * puts symm_key1 == symm_key2 # => true
617
+ */
618
+ cDH = rb_define_class_under(mPKey, "DH", cPKey);
619
+ rb_define_singleton_method(cDH, "generate", ossl_dh_s_generate, -1);
620
+ rb_define_method(cDH, "initialize", ossl_dh_initialize, -1);
621
+ rb_define_method(cDH, "initialize_copy", ossl_dh_initialize_copy, 1);
622
+ rb_define_method(cDH, "public?", ossl_dh_is_public, 0);
623
+ rb_define_method(cDH, "private?", ossl_dh_is_private, 0);
624
+ rb_define_method(cDH, "to_text", ossl_dh_to_text, 0);
625
+ rb_define_method(cDH, "export", ossl_dh_export, 0);
626
+ rb_define_alias(cDH, "to_pem", "export");
627
+ rb_define_alias(cDH, "to_s", "export");
628
+ rb_define_method(cDH, "to_der", ossl_dh_to_der, 0);
629
+ rb_define_method(cDH, "public_key", ossl_dh_to_public_key, 0);
630
+ rb_define_method(cDH, "params_ok?", ossl_dh_check_params, 0);
631
+ rb_define_method(cDH, "generate_key!", ossl_dh_generate_key, 0);
632
+ rb_define_method(cDH, "compute_key", ossl_dh_compute_key, 1);
633
+
634
+ DEF_OSSL_PKEY_BN(cDH, dh, p);
635
+ DEF_OSSL_PKEY_BN(cDH, dh, q);
636
+ DEF_OSSL_PKEY_BN(cDH, dh, g);
637
+ DEF_OSSL_PKEY_BN(cDH, dh, pub_key);
638
+ DEF_OSSL_PKEY_BN(cDH, dh, priv_key);
639
+ rb_define_method(cDH, "set_pqg", ossl_dh_set_pqg, 3);
640
+ rb_define_method(cDH, "set_key", ossl_dh_set_key, 2);
641
+
642
+ rb_define_method(cDH, "params", ossl_dh_get_params, 0);
643
+ }
644
+
645
+ #else /* defined NO_DH */
646
+ void
647
+ Init_ossl_dh(void)
648
+ {
649
+ }
650
+ #endif /* NO_DH */