rubysl-openssl 2.10 → 2.11

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 (55) hide show
  1. checksums.yaml +5 -5
  2. data/ext/rubysl/openssl/deprecation.rb +7 -3
  3. data/ext/rubysl/openssl/extconf.rb +148 -103
  4. data/ext/rubysl/openssl/openssl_missing.c +94 -275
  5. data/ext/rubysl/openssl/openssl_missing.h +167 -98
  6. data/ext/rubysl/openssl/ossl.c +266 -212
  7. data/ext/rubysl/openssl/ossl.h +27 -89
  8. data/ext/rubysl/openssl/ossl_asn1.c +157 -221
  9. data/ext/rubysl/openssl/ossl_asn1.h +11 -3
  10. data/ext/rubysl/openssl/ossl_bio.c +10 -40
  11. data/ext/rubysl/openssl/ossl_bio.h +1 -2
  12. data/ext/rubysl/openssl/ossl_bn.c +144 -100
  13. data/ext/rubysl/openssl/ossl_bn.h +3 -1
  14. data/ext/rubysl/openssl/ossl_cipher.c +270 -195
  15. data/ext/rubysl/openssl/ossl_config.c +7 -1
  16. data/ext/rubysl/openssl/ossl_config.h +0 -1
  17. data/ext/rubysl/openssl/ossl_digest.c +40 -29
  18. data/ext/rubysl/openssl/ossl_engine.c +23 -62
  19. data/ext/rubysl/openssl/ossl_hmac.c +82 -55
  20. data/ext/rubysl/openssl/ossl_ns_spki.c +22 -22
  21. data/ext/rubysl/openssl/ossl_ocsp.c +894 -144
  22. data/ext/rubysl/openssl/ossl_ocsp.h +1 -1
  23. data/ext/rubysl/openssl/ossl_pkcs12.c +47 -19
  24. data/ext/rubysl/openssl/ossl_pkcs5.c +7 -15
  25. data/ext/rubysl/openssl/ossl_pkcs7.c +38 -15
  26. data/ext/rubysl/openssl/ossl_pkey.c +151 -99
  27. data/ext/rubysl/openssl/ossl_pkey.h +123 -29
  28. data/ext/rubysl/openssl/ossl_pkey_dh.c +143 -92
  29. data/ext/rubysl/openssl/ossl_pkey_dsa.c +149 -104
  30. data/ext/rubysl/openssl/ossl_pkey_ec.c +646 -524
  31. data/ext/rubysl/openssl/ossl_pkey_rsa.c +180 -121
  32. data/ext/rubysl/openssl/ossl_rand.c +25 -21
  33. data/ext/rubysl/openssl/ossl_ssl.c +795 -413
  34. data/ext/rubysl/openssl/ossl_ssl.h +3 -0
  35. data/ext/rubysl/openssl/ossl_ssl_session.c +83 -77
  36. data/ext/rubysl/openssl/ossl_version.h +1 -1
  37. data/ext/rubysl/openssl/ossl_x509.c +92 -8
  38. data/ext/rubysl/openssl/ossl_x509.h +14 -5
  39. data/ext/rubysl/openssl/ossl_x509attr.c +77 -41
  40. data/ext/rubysl/openssl/ossl_x509cert.c +45 -46
  41. data/ext/rubysl/openssl/ossl_x509crl.c +51 -57
  42. data/ext/rubysl/openssl/ossl_x509ext.c +39 -33
  43. data/ext/rubysl/openssl/ossl_x509name.c +68 -45
  44. data/ext/rubysl/openssl/ossl_x509req.c +32 -38
  45. data/ext/rubysl/openssl/ossl_x509revoked.c +43 -9
  46. data/ext/rubysl/openssl/ossl_x509store.c +309 -104
  47. data/ext/rubysl/openssl/ruby_missing.h +8 -6
  48. data/lib/openssl/buffering.rb +11 -5
  49. data/lib/openssl/cipher.rb +23 -15
  50. data/lib/openssl/digest.rb +7 -10
  51. data/lib/openssl/pkey.rb +15 -8
  52. data/lib/openssl/ssl.rb +81 -105
  53. data/lib/rubysl/openssl.rb +1 -4
  54. data/lib/rubysl/openssl/version.rb +1 -1
  55. metadata +3 -4
@@ -13,7 +13,6 @@
13
13
  extern VALUE mPKey;
14
14
  extern VALUE cPKey;
15
15
  extern VALUE ePKeyError;
16
- extern ID id_private_q;
17
16
  extern const rb_data_type_t ossl_evp_pkey_type;
18
17
 
19
18
  #define OSSL_PKEY_SET_PRIVATE(obj) rb_iv_set((obj), "private", Qtrue)
@@ -40,24 +39,19 @@ extern const rb_data_type_t ossl_evp_pkey_type;
40
39
  GetPKey((obj), (pkey)); \
41
40
  } while (0)
42
41
 
43
- void ossl_generate_cb(int, int, void *);
44
- #define HAVE_BN_GENCB defined(HAVE_RSA_GENERATE_KEY_EX) || defined(HAVE_DH_GENERATE_PARAMETERS_EX) || defined(HAVE_DSA_GENERATE_PARAMETERS_EX)
45
- #if HAVE_BN_GENCB
46
42
  struct ossl_generate_cb_arg {
47
43
  int yield;
48
- int stop;
44
+ int interrupted;
49
45
  int state;
50
46
  };
51
47
  int ossl_generate_cb_2(int p, int n, BN_GENCB *cb);
52
48
  void ossl_generate_cb_stop(void *ptr);
53
- #endif
54
49
 
55
50
  VALUE ossl_pkey_new(EVP_PKEY *);
56
- VALUE ossl_pkey_new_from_file(VALUE);
51
+ void ossl_pkey_check_public_key(const EVP_PKEY *);
57
52
  EVP_PKEY *GetPKeyPtr(VALUE);
58
53
  EVP_PKEY *DupPKeyPtr(VALUE);
59
54
  EVP_PKEY *GetPrivPKeyPtr(VALUE);
60
- EVP_PKEY *DupPrivPKeyPtr(VALUE);
61
55
  void Init_ossl_pkey(void);
62
56
 
63
57
  /*
@@ -99,53 +93,153 @@ extern VALUE eEC_POINT;
99
93
  VALUE ossl_ec_new(EVP_PKEY *);
100
94
  void Init_ossl_ec(void);
101
95
 
102
-
103
- #define OSSL_PKEY_BN(keytype, name) \
96
+ #define OSSL_PKEY_BN_DEF_GETTER0(_keytype, _type, _name, _get) \
104
97
  /* \
105
98
  * call-seq: \
106
- * key.##name -> aBN \
99
+ * _keytype##.##_name -> aBN \
107
100
  */ \
108
- static VALUE ossl_##keytype##_get_##name(VALUE self) \
101
+ static VALUE ossl_##_keytype##_get_##_name(VALUE self) \
109
102
  { \
110
- EVP_PKEY *pkey; \
111
- BIGNUM *bn; \
103
+ _type *obj; \
104
+ const BIGNUM *bn; \
112
105
  \
113
- GetPKey(self, pkey); \
114
- bn = pkey->pkey.keytype->name; \
106
+ Get##_type(self, obj); \
107
+ _get; \
115
108
  if (bn == NULL) \
116
109
  return Qnil; \
117
110
  return ossl_bn_new(bn); \
118
- } \
111
+ }
112
+
113
+ #define OSSL_PKEY_BN_DEF_GETTER3(_keytype, _type, _group, a1, a2, a3) \
114
+ OSSL_PKEY_BN_DEF_GETTER0(_keytype, _type, a1, \
115
+ _type##_get0_##_group(obj, &bn, NULL, NULL)) \
116
+ OSSL_PKEY_BN_DEF_GETTER0(_keytype, _type, a2, \
117
+ _type##_get0_##_group(obj, NULL, &bn, NULL)) \
118
+ OSSL_PKEY_BN_DEF_GETTER0(_keytype, _type, a3, \
119
+ _type##_get0_##_group(obj, NULL, NULL, &bn))
120
+
121
+ #define OSSL_PKEY_BN_DEF_GETTER2(_keytype, _type, _group, a1, a2) \
122
+ OSSL_PKEY_BN_DEF_GETTER0(_keytype, _type, a1, \
123
+ _type##_get0_##_group(obj, &bn, NULL)) \
124
+ OSSL_PKEY_BN_DEF_GETTER0(_keytype, _type, a2, \
125
+ _type##_get0_##_group(obj, NULL, &bn))
126
+
127
+ #define OSSL_PKEY_BN_DEF_SETTER3(_keytype, _type, _group, a1, a2, a3) \
128
+ /* \
129
+ * call-seq: \
130
+ * _keytype##.set_##_group(a1, a2, a3) -> self \
131
+ */ \
132
+ static VALUE ossl_##_keytype##_set_##_group(VALUE self, VALUE v1, VALUE v2, VALUE v3) \
133
+ { \
134
+ _type *obj; \
135
+ BIGNUM *bn1 = NULL, *orig_bn1 = NIL_P(v1) ? NULL : GetBNPtr(v1);\
136
+ BIGNUM *bn2 = NULL, *orig_bn2 = NIL_P(v2) ? NULL : GetBNPtr(v2);\
137
+ BIGNUM *bn3 = NULL, *orig_bn3 = NIL_P(v3) ? NULL : GetBNPtr(v3);\
138
+ \
139
+ Get##_type(self, obj); \
140
+ if (orig_bn1 && !(bn1 = BN_dup(orig_bn1)) || \
141
+ orig_bn2 && !(bn2 = BN_dup(orig_bn2)) || \
142
+ orig_bn3 && !(bn3 = BN_dup(orig_bn3))) { \
143
+ BN_clear_free(bn1); \
144
+ BN_clear_free(bn2); \
145
+ BN_clear_free(bn3); \
146
+ ossl_raise(eBNError, NULL); \
147
+ } \
148
+ \
149
+ if (!_type##_set0_##_group(obj, bn1, bn2, bn3)) { \
150
+ BN_clear_free(bn1); \
151
+ BN_clear_free(bn2); \
152
+ BN_clear_free(bn3); \
153
+ ossl_raise(ePKeyError, #_type"_set0_"#_group); \
154
+ } \
155
+ return self; \
156
+ }
157
+
158
+ #define OSSL_PKEY_BN_DEF_SETTER2(_keytype, _type, _group, a1, a2) \
159
+ /* \
160
+ * call-seq: \
161
+ * _keytype##.set_##_group(a1, a2) -> self \
162
+ */ \
163
+ static VALUE ossl_##_keytype##_set_##_group(VALUE self, VALUE v1, VALUE v2) \
164
+ { \
165
+ _type *obj; \
166
+ BIGNUM *bn1 = NULL, *orig_bn1 = NIL_P(v1) ? NULL : GetBNPtr(v1);\
167
+ BIGNUM *bn2 = NULL, *orig_bn2 = NIL_P(v2) ? NULL : GetBNPtr(v2);\
168
+ \
169
+ Get##_type(self, obj); \
170
+ if (orig_bn1 && !(bn1 = BN_dup(orig_bn1)) || \
171
+ orig_bn2 && !(bn2 = BN_dup(orig_bn2))) { \
172
+ BN_clear_free(bn1); \
173
+ BN_clear_free(bn2); \
174
+ ossl_raise(eBNError, NULL); \
175
+ } \
176
+ \
177
+ if (!_type##_set0_##_group(obj, bn1, bn2)) { \
178
+ BN_clear_free(bn1); \
179
+ BN_clear_free(bn2); \
180
+ ossl_raise(ePKeyError, #_type"_set0_"#_group); \
181
+ } \
182
+ return self; \
183
+ }
184
+
185
+ #define OSSL_PKEY_BN_DEF_SETTER_OLD(_keytype, _type, _group, _name) \
119
186
  /* \
120
187
  * call-seq: \
121
- * key.##name = bn -> bn \
188
+ * _keytype##.##_name = bn -> bn \
122
189
  */ \
123
- static VALUE ossl_##keytype##_set_##name(VALUE self, VALUE bignum) \
190
+ static VALUE ossl_##_keytype##_set_##_name(VALUE self, VALUE bignum) \
124
191
  { \
125
- EVP_PKEY *pkey; \
192
+ _type *obj; \
126
193
  BIGNUM *bn; \
127
194
  \
128
- GetPKey(self, pkey); \
195
+ rb_warning("#"#_name"= is deprecated; use #set_"#_group); \
196
+ Get##_type(self, obj); \
129
197
  if (NIL_P(bignum)) { \
130
- BN_clear_free(pkey->pkey.keytype->name); \
131
- pkey->pkey.keytype->name = NULL; \
198
+ BN_clear_free(obj->_name); \
199
+ obj->_name = NULL; \
132
200
  return Qnil; \
133
201
  } \
134
202
  \
135
203
  bn = GetBNPtr(bignum); \
136
- if (pkey->pkey.keytype->name == NULL) \
137
- pkey->pkey.keytype->name = BN_new(); \
138
- if (pkey->pkey.keytype->name == NULL) \
204
+ if (obj->_name == NULL) \
205
+ obj->_name = BN_new(); \
206
+ if (obj->_name == NULL) \
139
207
  ossl_raise(eBNError, NULL); \
140
- if (BN_copy(pkey->pkey.keytype->name, bn) == NULL) \
208
+ if (BN_copy(obj->_name, bn) == NULL) \
141
209
  ossl_raise(eBNError, NULL); \
142
210
  return bignum; \
143
211
  }
144
212
 
213
+ #if defined(HAVE_OPAQUE_OPENSSL) /* OpenSSL 1.1.0 */
214
+ #define OSSL_PKEY_BN_DEF3(_keytype, _type, _group, a1, a2, a3) \
215
+ OSSL_PKEY_BN_DEF_GETTER3(_keytype, _type, _group, a1, a2, a3) \
216
+ OSSL_PKEY_BN_DEF_SETTER3(_keytype, _type, _group, a1, a2, a3)
217
+
218
+ #define OSSL_PKEY_BN_DEF2(_keytype, _type, _group, a1, a2) \
219
+ OSSL_PKEY_BN_DEF_GETTER2(_keytype, _type, _group, a1, a2) \
220
+ OSSL_PKEY_BN_DEF_SETTER2(_keytype, _type, _group, a1, a2)
221
+
145
222
  #define DEF_OSSL_PKEY_BN(class, keytype, name) \
146
- do { \
147
- rb_define_method((class), #name, ossl_##keytype##_get_##name, 0); \
223
+ rb_define_method((class), #name, ossl_##keytype##_get_##name, 0)
224
+
225
+ #else
226
+ #define OSSL_PKEY_BN_DEF3(_keytype, _type, _group, a1, a2, a3) \
227
+ OSSL_PKEY_BN_DEF_GETTER3(_keytype, _type, _group, a1, a2, a3) \
228
+ OSSL_PKEY_BN_DEF_SETTER3(_keytype, _type, _group, a1, a2, a3) \
229
+ OSSL_PKEY_BN_DEF_SETTER_OLD(_keytype, _type, _group, a1) \
230
+ OSSL_PKEY_BN_DEF_SETTER_OLD(_keytype, _type, _group, a2) \
231
+ OSSL_PKEY_BN_DEF_SETTER_OLD(_keytype, _type, _group, a3)
232
+
233
+ #define OSSL_PKEY_BN_DEF2(_keytype, _type, _group, a1, a2) \
234
+ OSSL_PKEY_BN_DEF_GETTER2(_keytype, _type, _group, a1, a2) \
235
+ OSSL_PKEY_BN_DEF_SETTER2(_keytype, _type, _group, a1, a2) \
236
+ OSSL_PKEY_BN_DEF_SETTER_OLD(_keytype, _type, _group, a1) \
237
+ OSSL_PKEY_BN_DEF_SETTER_OLD(_keytype, _type, _group, a2)
238
+
239
+ #define DEF_OSSL_PKEY_BN(class, keytype, name) do { \
240
+ rb_define_method((class), #name, ossl_##keytype##_get_##name, 0);\
148
241
  rb_define_method((class), #name "=", ossl_##keytype##_set_##name, 1);\
149
242
  } while (0)
243
+ #endif /* HAVE_OPAQUE_OPENSSL */
150
244
 
151
245
  #endif /* _OSSL_PKEY_H_ */
@@ -7,25 +7,21 @@
7
7
  * This program is licensed under the same licence as Ruby.
8
8
  * (See the file 'LICENCE'.)
9
9
  */
10
- #if !defined(OPENSSL_NO_DH)
11
-
12
10
  #include "ossl.h"
13
11
 
12
+ #if !defined(OPENSSL_NO_DH)
13
+
14
14
  #define GetPKeyDH(obj, pkey) do { \
15
15
  GetPKey((obj), (pkey)); \
16
- if (EVP_PKEY_type((pkey)->type) != EVP_PKEY_DH) { /* PARANOIA? */ \
16
+ if (EVP_PKEY_base_id(pkey) != EVP_PKEY_DH) { /* PARANOIA? */ \
17
17
  ossl_raise(rb_eRuntimeError, "THIS IS NOT A DH!") ; \
18
18
  } \
19
19
  } while (0)
20
-
21
- #define DH_HAS_PRIVATE(dh) ((dh)->priv_key)
22
-
23
- #ifdef OSSL_ENGINE_ENABLED
24
- # define DH_PRIVATE(dh) (DH_HAS_PRIVATE(dh) || (dh)->engine)
25
- #else
26
- # define DH_PRIVATE(dh) DH_HAS_PRIVATE(dh)
27
- #endif
28
-
20
+ #define GetDH(obj, dh) do { \
21
+ EVP_PKEY *_pkey; \
22
+ GetPKeyDH((obj), _pkey); \
23
+ (dh) = EVP_PKEY_get0_DH(_pkey); \
24
+ } while (0)
29
25
 
30
26
  /*
31
27
  * Classes
@@ -67,7 +63,7 @@ ossl_dh_new(EVP_PKEY *pkey)
67
63
  obj = dh_instance(cDH, DH_new());
68
64
  } else {
69
65
  obj = NewPKey(cDH);
70
- if (EVP_PKEY_type(pkey->type) != EVP_PKEY_DH) {
66
+ if (EVP_PKEY_base_id(pkey) != EVP_PKEY_DH) {
71
67
  ossl_raise(rb_eTypeError, "Not a DH key!");
72
68
  }
73
69
  SetPKey(obj, pkey);
@@ -82,7 +78,6 @@ ossl_dh_new(EVP_PKEY *pkey)
82
78
  /*
83
79
  * Private
84
80
  */
85
- #if defined(HAVE_DH_GENERATE_PARAMETERS_EX) && HAVE_BN_GENCB
86
81
  struct dh_blocking_gen_arg {
87
82
  DH *dh;
88
83
  int size;
@@ -98,27 +93,28 @@ dh_blocking_gen(void *arg)
98
93
  gen->result = DH_generate_parameters_ex(gen->dh, gen->size, gen->gen, gen->cb);
99
94
  return 0;
100
95
  }
101
- #endif
102
96
 
103
97
  static DH *
104
98
  dh_generate(int size, int gen)
105
99
  {
106
- #if defined(HAVE_DH_GENERATE_PARAMETERS_EX) && HAVE_BN_GENCB
107
- BN_GENCB cb;
108
- struct ossl_generate_cb_arg cb_arg;
100
+ struct ossl_generate_cb_arg cb_arg = { 0 };
109
101
  struct dh_blocking_gen_arg gen_arg;
110
102
  DH *dh = DH_new();
103
+ BN_GENCB *cb = BN_GENCB_new();
111
104
 
112
- if (!dh) return 0;
105
+ if (!dh || !cb) {
106
+ DH_free(dh);
107
+ BN_GENCB_free(cb);
108
+ return NULL;
109
+ }
113
110
 
114
- memset(&cb_arg, 0, sizeof(struct ossl_generate_cb_arg));
115
111
  if (rb_block_given_p())
116
112
  cb_arg.yield = 1;
117
- BN_GENCB_set(&cb, ossl_generate_cb_2, &cb_arg);
113
+ BN_GENCB_set(cb, ossl_generate_cb_2, &cb_arg);
118
114
  gen_arg.dh = dh;
119
115
  gen_arg.size = size;
120
116
  gen_arg.gen = gen;
121
- gen_arg.cb = &cb;
117
+ gen_arg.cb = cb;
122
118
  if (cb_arg.yield == 1) {
123
119
  /* we cannot release GVL when callback proc is supplied */
124
120
  dh_blocking_gen(&gen_arg);
@@ -127,21 +123,20 @@ dh_generate(int size, int gen)
127
123
  rb_thread_call_without_gvl(dh_blocking_gen, &gen_arg, ossl_generate_cb_stop, &cb_arg);
128
124
  }
129
125
 
126
+ BN_GENCB_free(cb);
130
127
  if (!gen_arg.result) {
131
128
  DH_free(dh);
132
- if (cb_arg.state) rb_jump_tag(cb_arg.state);
133
- return 0;
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;
134
135
  }
135
- #else
136
- DH *dh;
137
-
138
- dh = DH_generate_parameters(size, gen, rb_block_given_p() ? ossl_generate_cb : NULL, NULL);
139
- if (!dh) return 0;
140
- #endif
141
136
 
142
137
  if (!DH_generate_key(dh)) {
143
138
  DH_free(dh);
144
- return 0;
139
+ return NULL;
145
140
  }
146
141
 
147
142
  return dh;
@@ -180,8 +175,10 @@ ossl_dh_s_generate(int argc, VALUE *argv, VALUE klass)
180
175
  }
181
176
 
182
177
  /*
183
- * call-seq:
184
- * DH.new([size [, generator] | string]) -> dh
178
+ * call-seq:
179
+ * DH.new -> dh
180
+ * DH.new(string) -> dh
181
+ * DH.new(size [, generator]) -> dh
185
182
  *
186
183
  * Either generates a DH instance from scratch or by reading already existing
187
184
  * DH parameters from +string+. Note that when reading a DH instance from
@@ -215,17 +212,17 @@ ossl_dh_initialize(int argc, VALUE *argv, VALUE self)
215
212
  if(rb_scan_args(argc, argv, "02", &arg, &gen) == 0) {
216
213
  dh = DH_new();
217
214
  }
218
- else if (FIXNUM_P(arg)) {
215
+ else if (RB_INTEGER_TYPE_P(arg)) {
219
216
  if (!NIL_P(gen)) {
220
217
  g = NUM2INT(gen);
221
218
  }
222
- if (!(dh = dh_generate(FIX2INT(arg), g))) {
219
+ if (!(dh = dh_generate(NUM2INT(arg), g))) {
223
220
  ossl_raise(eDHError, NULL);
224
221
  }
225
222
  }
226
223
  else {
227
224
  arg = ossl_to_der_if_possible(arg);
228
- in = ossl_obj2bio(arg);
225
+ in = ossl_obj2bio(&arg);
229
226
  dh = PEM_read_bio_DHparams(in, NULL, NULL, NULL);
230
227
  if (!dh){
231
228
  OSSL_BIO_reset(in);
@@ -243,6 +240,39 @@ ossl_dh_initialize(int argc, VALUE *argv, VALUE self)
243
240
  return self;
244
241
  }
245
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
+
246
276
  /*
247
277
  * call-seq:
248
278
  * dh.public? -> true | false
@@ -253,11 +283,13 @@ ossl_dh_initialize(int argc, VALUE *argv, VALUE self)
253
283
  static VALUE
254
284
  ossl_dh_is_public(VALUE self)
255
285
  {
256
- EVP_PKEY *pkey;
286
+ DH *dh;
287
+ const BIGNUM *bn;
257
288
 
258
- GetPKeyDH(self, pkey);
289
+ GetDH(self, dh);
290
+ DH_get0_key(dh, &bn, NULL);
259
291
 
260
- return (pkey->pkey.dh->pub_key) ? Qtrue : Qfalse;
292
+ return bn ? Qtrue : Qfalse;
261
293
  }
262
294
 
263
295
  /*
@@ -270,11 +302,17 @@ ossl_dh_is_public(VALUE self)
270
302
  static VALUE
271
303
  ossl_dh_is_private(VALUE self)
272
304
  {
273
- EVP_PKEY *pkey;
305
+ DH *dh;
306
+ const BIGNUM *bn;
274
307
 
275
- GetPKeyDH(self, pkey);
308
+ GetDH(self, dh);
309
+ DH_get0_key(dh, NULL, &bn);
276
310
 
277
- return (DH_PRIVATE(pkey->pkey.dh)) ? Qtrue : Qfalse;
311
+ #if !defined(OPENSSL_NO_ENGINE)
312
+ return (bn || DH_get0_engine(dh)) ? Qtrue : Qfalse;
313
+ #else
314
+ return bn ? Qtrue : Qfalse;
315
+ #endif
278
316
  }
279
317
 
280
318
  /*
@@ -290,15 +328,15 @@ ossl_dh_is_private(VALUE self)
290
328
  static VALUE
291
329
  ossl_dh_export(VALUE self)
292
330
  {
293
- EVP_PKEY *pkey;
331
+ DH *dh;
294
332
  BIO *out;
295
333
  VALUE str;
296
334
 
297
- GetPKeyDH(self, pkey);
335
+ GetDH(self, dh);
298
336
  if (!(out = BIO_new(BIO_s_mem()))) {
299
337
  ossl_raise(eDHError, NULL);
300
338
  }
301
- if (!PEM_write_bio_DHparams(out, pkey->pkey.dh)) {
339
+ if (!PEM_write_bio_DHparams(out, dh)) {
302
340
  BIO_free(out);
303
341
  ossl_raise(eDHError, NULL);
304
342
  }
@@ -319,17 +357,17 @@ ossl_dh_export(VALUE self)
319
357
  static VALUE
320
358
  ossl_dh_to_der(VALUE self)
321
359
  {
322
- EVP_PKEY *pkey;
360
+ DH *dh;
323
361
  unsigned char *p;
324
362
  long len;
325
363
  VALUE str;
326
364
 
327
- GetPKeyDH(self, pkey);
328
- if((len = i2d_DHparams(pkey->pkey.dh, NULL)) <= 0)
365
+ GetDH(self, dh);
366
+ if((len = i2d_DHparams(dh, NULL)) <= 0)
329
367
  ossl_raise(eDHError, NULL);
330
368
  str = rb_str_new(0, len);
331
369
  p = (unsigned char *)RSTRING_PTR(str);
332
- if(i2d_DHparams(pkey->pkey.dh, &p) < 0)
370
+ if(i2d_DHparams(dh, &p) < 0)
333
371
  ossl_raise(eDHError, NULL);
334
372
  ossl_str_adjust(str, p);
335
373
 
@@ -347,17 +385,20 @@ ossl_dh_to_der(VALUE self)
347
385
  static VALUE
348
386
  ossl_dh_get_params(VALUE self)
349
387
  {
350
- EVP_PKEY *pkey;
388
+ DH *dh;
351
389
  VALUE hash;
390
+ const BIGNUM *p, *q, *g, *pub_key, *priv_key;
352
391
 
353
- GetPKeyDH(self, pkey);
392
+ GetDH(self, dh);
393
+ DH_get0_pqg(dh, &p, &q, &g);
394
+ DH_get0_key(dh, &pub_key, &priv_key);
354
395
 
355
396
  hash = rb_hash_new();
356
-
357
- rb_hash_aset(hash, rb_str_new2("p"), ossl_bn_new(pkey->pkey.dh->p));
358
- rb_hash_aset(hash, rb_str_new2("g"), ossl_bn_new(pkey->pkey.dh->g));
359
- rb_hash_aset(hash, rb_str_new2("pub_key"), ossl_bn_new(pkey->pkey.dh->pub_key));
360
- rb_hash_aset(hash, rb_str_new2("priv_key"), ossl_bn_new(pkey->pkey.dh->priv_key));
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));
361
402
 
362
403
  return hash;
363
404
  }
@@ -373,15 +414,15 @@ ossl_dh_get_params(VALUE self)
373
414
  static VALUE
374
415
  ossl_dh_to_text(VALUE self)
375
416
  {
376
- EVP_PKEY *pkey;
417
+ DH *dh;
377
418
  BIO *out;
378
419
  VALUE str;
379
420
 
380
- GetPKeyDH(self, pkey);
421
+ GetDH(self, dh);
381
422
  if (!(out = BIO_new(BIO_s_mem()))) {
382
423
  ossl_raise(eDHError, NULL);
383
424
  }
384
- if (!DHparams_print(out, pkey->pkey.dh)) {
425
+ if (!DHparams_print(out, dh)) {
385
426
  BIO_free(out);
386
427
  ossl_raise(eDHError, NULL);
387
428
  }
@@ -414,13 +455,12 @@ ossl_dh_to_text(VALUE self)
414
455
  static VALUE
415
456
  ossl_dh_to_public_key(VALUE self)
416
457
  {
417
- EVP_PKEY *pkey;
418
- DH *dh;
458
+ DH *orig_dh, *dh;
419
459
  VALUE obj;
420
460
 
421
- GetPKeyDH(self, pkey);
422
- dh = DHparams_dup(pkey->pkey.dh); /* err check perfomed by dh_instance */
423
- obj = dh_instance(CLASS_OF(self), dh);
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);
424
464
  if (obj == Qfalse) {
425
465
  DH_free(dh);
426
466
  ossl_raise(eDHError, NULL);
@@ -441,12 +481,9 @@ static VALUE
441
481
  ossl_dh_check_params(VALUE self)
442
482
  {
443
483
  DH *dh;
444
- EVP_PKEY *pkey;
445
484
  int codes;
446
485
 
447
- GetPKeyDH(self, pkey);
448
- dh = pkey->pkey.dh;
449
-
486
+ GetDH(self, dh);
450
487
  if (!DH_check(dh, &codes)) {
451
488
  return Qfalse;
452
489
  }
@@ -474,11 +511,8 @@ static VALUE
474
511
  ossl_dh_generate_key(VALUE self)
475
512
  {
476
513
  DH *dh;
477
- EVP_PKEY *pkey;
478
-
479
- GetPKeyDH(self, pkey);
480
- dh = pkey->pkey.dh;
481
514
 
515
+ GetDH(self, dh);
482
516
  if (!DH_generate_key(dh))
483
517
  ossl_raise(eDHError, "Failed to generate key");
484
518
  return self;
@@ -493,20 +527,19 @@ ossl_dh_generate_key(VALUE self)
493
527
  *
494
528
  * === Parameters
495
529
  * * +pub_bn+ is a OpenSSL::BN, *not* the DH instance returned by
496
- * DH#public_key as that contains the DH parameters only.
530
+ * DH#public_key as that contains the DH parameters only.
497
531
  */
498
532
  static VALUE
499
533
  ossl_dh_compute_key(VALUE self, VALUE pub)
500
534
  {
501
535
  DH *dh;
502
- EVP_PKEY *pkey;
503
- BIGNUM *pub_key;
536
+ const BIGNUM *pub_key, *dh_p;
504
537
  VALUE str;
505
538
  int len;
506
539
 
507
- GetPKeyDH(self, pkey);
508
- dh = pkey->pkey.dh;
509
- if (!dh->p)
540
+ GetDH(self, dh);
541
+ DH_get0_pqg(dh, &dh_p, NULL, NULL);
542
+ if (!dh_p)
510
543
  ossl_raise(eDHError, "incomplete DH");
511
544
  pub_key = GetBNPtr(pub);
512
545
  len = DH_size(dh);
@@ -519,10 +552,22 @@ ossl_dh_compute_key(VALUE self, VALUE pub)
519
552
  return str;
520
553
  }
521
554
 
522
- OSSL_PKEY_BN(dh, p)
523
- OSSL_PKEY_BN(dh, g)
524
- OSSL_PKEY_BN(dh, pub_key)
525
- OSSL_PKEY_BN(dh, priv_key)
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+ for 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)
526
571
 
527
572
  /*
528
573
  * INIT
@@ -531,8 +576,9 @@ void
531
576
  Init_ossl_dh(void)
532
577
  {
533
578
  #if 0
534
- mOSSL = rb_define_module("OpenSSL"); /* let rdoc know about mOSSL and mPKey */
535
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);
536
582
  #endif
537
583
 
538
584
  /* Document-class: OpenSSL::PKey::DHError
@@ -549,15 +595,15 @@ Init_ossl_dh(void)
549
595
  * on.
550
596
  *
551
597
  * === Accessor methods for the Diffie-Hellman parameters
552
- * * DH#p
553
- * The prime (an OpenSSL::BN) of the Diffie-Hellman parameters.
554
- * * DH#g
555
- * The generator (an OpenSSL::BN) g of the Diffie-Hellman parameters.
556
- * * DH#pub_key
557
- * The per-session public key (an OpenSSL::BN) matching the private key.
558
- * This needs to be passed to DH#compute_key.
559
- * * DH#priv_key
560
- * The per-session private key, an OpenSSL::BN.
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.
561
607
  *
562
608
  * === Example of a key exchange
563
609
  * dh1 = OpenSSL::PKey::DH.new(2048)
@@ -572,6 +618,7 @@ Init_ossl_dh(void)
572
618
  cDH = rb_define_class_under(mPKey, "DH", cPKey);
573
619
  rb_define_singleton_method(cDH, "generate", ossl_dh_s_generate, -1);
574
620
  rb_define_method(cDH, "initialize", ossl_dh_initialize, -1);
621
+ rb_define_copy_func(cDH, ossl_dh_initialize_copy);
575
622
  rb_define_method(cDH, "public?", ossl_dh_is_public, 0);
576
623
  rb_define_method(cDH, "private?", ossl_dh_is_private, 0);
577
624
  rb_define_method(cDH, "to_text", ossl_dh_to_text, 0);
@@ -585,9 +632,13 @@ Init_ossl_dh(void)
585
632
  rb_define_method(cDH, "compute_key", ossl_dh_compute_key, 1);
586
633
 
587
634
  DEF_OSSL_PKEY_BN(cDH, dh, p);
635
+ DEF_OSSL_PKEY_BN(cDH, dh, q);
588
636
  DEF_OSSL_PKEY_BN(cDH, dh, g);
589
637
  DEF_OSSL_PKEY_BN(cDH, dh, pub_key);
590
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
+
591
642
  rb_define_method(cDH, "params", ossl_dh_get_params, 0);
592
643
  }
593
644