rubysl-openssl 2.10 → 2.11

Sign up to get free protection for your applications and to get access to all the features.
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