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
@@ -11,7 +11,7 @@
11
11
  #if !defined(_OSSL_OCSP_H_)
12
12
  #define _OSSL_OCSP_H_
13
13
 
14
- #if defined(OSSL_OCSP_ENABLED)
14
+ #if !defined(OPENSSL_NO_OCSP)
15
15
  extern VALUE mOCSP;
16
16
  extern VALUE cOPCSReq;
17
17
  extern VALUE cOPCSRes;
@@ -65,6 +65,25 @@ ossl_pkcs12_s_allocate(VALUE klass)
65
65
  return obj;
66
66
  }
67
67
 
68
+ static VALUE
69
+ ossl_pkcs12_initialize_copy(VALUE self, VALUE other)
70
+ {
71
+ PKCS12 *p12, *p12_old, *p12_new;
72
+
73
+ rb_check_frozen(self);
74
+ GetPKCS12(self, p12_old);
75
+ SafeGetPKCS12(other, p12);
76
+
77
+ p12_new = ASN1_dup((i2d_of_void *)i2d_PKCS12, (d2i_of_void *)d2i_PKCS12, (char *)p12);
78
+ if (!p12_new)
79
+ ossl_raise(ePKCS12Error, "ASN1_dup");
80
+
81
+ SetPKCS12(self, p12_new);
82
+ PKCS12_free(p12_old);
83
+
84
+ return self;
85
+ }
86
+
68
87
  /*
69
88
  * call-seq:
70
89
  * PKCS12.create(pass, name, key, cert [, ca, [, key_pbe [, cert_pbe [, key_iter [, mac_iter [, keytype]]]]]])
@@ -74,8 +93,8 @@ ossl_pkcs12_s_allocate(VALUE klass)
74
93
  * * +name+ - A string describing the key.
75
94
  * * +key+ - Any PKey.
76
95
  * * +cert+ - A X509::Certificate.
77
- * * * The public_key portion of the certificate must contain a valid public key.
78
- * * * The not_before and not_after fields must be filled in.
96
+ * * The public_key portion of the certificate must contain a valid public key.
97
+ * * The not_before and not_after fields must be filled in.
79
98
  * * +ca+ - An optional array of X509::Certificate's.
80
99
  * * +key_pbe+ - string
81
100
  * * +cert_pbe+ - string
@@ -100,18 +119,18 @@ ossl_pkcs12_s_create(int argc, VALUE *argv, VALUE self)
100
119
  PKCS12 *p12;
101
120
 
102
121
  rb_scan_args(argc, argv, "46", &pass, &name, &pkey, &cert, &ca, &key_nid, &cert_nid, &key_iter, &mac_iter, &keytype);
103
- passphrase = NIL_P(pass) ? NULL : StringValuePtr(pass);
104
- friendlyname = NIL_P(name) ? NULL : StringValuePtr(name);
122
+ passphrase = NIL_P(pass) ? NULL : StringValueCStr(pass);
123
+ friendlyname = NIL_P(name) ? NULL : StringValueCStr(name);
105
124
  key = GetPKeyPtr(pkey);
106
125
  x509 = GetX509CertPtr(cert);
107
126
  /* TODO: make a VALUE to nid function */
108
127
  if (!NIL_P(key_nid)) {
109
- if ((nkey = OBJ_txt2nid(StringValuePtr(key_nid))) == NID_undef)
110
- ossl_raise(rb_eArgError, "Unknown PBE algorithm %s", StringValuePtr(key_nid));
128
+ if ((nkey = OBJ_txt2nid(StringValueCStr(key_nid))) == NID_undef)
129
+ ossl_raise(rb_eArgError, "Unknown PBE algorithm %"PRIsVALUE, key_nid);
111
130
  }
112
131
  if (!NIL_P(cert_nid)) {
113
- if ((ncert = OBJ_txt2nid(StringValuePtr(cert_nid))) == NID_undef)
114
- ossl_raise(rb_eArgError, "Unknown PBE algorithm %s", StringValuePtr(cert_nid));
132
+ if ((ncert = OBJ_txt2nid(StringValueCStr(cert_nid))) == NID_undef)
133
+ ossl_raise(rb_eArgError, "Unknown PBE algorithm %"PRIsVALUE, cert_nid);
115
134
  }
116
135
  if (!NIL_P(key_iter))
117
136
  kiter = NUM2INT(key_iter);
@@ -158,8 +177,8 @@ ossl_pkcs12_initialize(int argc, VALUE *argv, VALUE self)
158
177
  PKCS12 *pkcs = DATA_PTR(self);
159
178
 
160
179
  if(rb_scan_args(argc, argv, "02", &arg, &pass) == 0) return self;
161
- passphrase = NIL_P(pass) ? NULL : StringValuePtr(pass);
162
- in = ossl_obj2bio(arg);
180
+ passphrase = NIL_P(pass) ? NULL : StringValueCStr(pass);
181
+ in = ossl_obj2bio(&arg);
163
182
  d2i_PKCS12_bio(in, &pkcs);
164
183
  DATA_PTR(self) = pkcs;
165
184
  BIO_free(in);
@@ -171,15 +190,17 @@ ossl_pkcs12_initialize(int argc, VALUE *argv, VALUE self)
171
190
  if(!PKCS12_parse(pkcs, passphrase, &key, &x509, &x509s))
172
191
  ossl_raise(ePKCS12Error, "PKCS12_parse");
173
192
  ERR_pop_to_mark();
174
- pkey = rb_protect((VALUE(*)_((VALUE)))ossl_pkey_new, (VALUE)key,
175
- &st); /* NO DUP */
176
- if(st) goto err;
177
- cert = rb_protect((VALUE(*)_((VALUE)))ossl_x509_new, (VALUE)x509, &st);
178
- if(st) goto err;
179
- if(x509s){
180
- ca =
181
- rb_protect((VALUE(*)_((VALUE)))ossl_x509_sk2ary, (VALUE)x509s, &st);
182
- if(st) goto err;
193
+ if (key) {
194
+ pkey = rb_protect((VALUE (*)(VALUE))ossl_pkey_new, (VALUE)key, &st);
195
+ if (st) goto err;
196
+ }
197
+ if (x509) {
198
+ cert = rb_protect((VALUE (*)(VALUE))ossl_x509_new, (VALUE)x509, &st);
199
+ if (st) goto err;
200
+ }
201
+ if (x509s) {
202
+ ca = rb_protect((VALUE (*)(VALUE))ossl_x509_sk2ary, (VALUE)x509s, &st);
203
+ if (st) goto err;
183
204
  }
184
205
 
185
206
  err:
@@ -216,6 +237,12 @@ ossl_pkcs12_to_der(VALUE self)
216
237
  void
217
238
  Init_ossl_pkcs12(void)
218
239
  {
240
+ #undef rb_intern
241
+ #if 0
242
+ mOSSL = rb_define_module("OpenSSL");
243
+ eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError);
244
+ #endif
245
+
219
246
  /*
220
247
  * Defines a file format commonly used to store private keys with
221
248
  * accompanying public key certificates, protected with a password-based
@@ -226,6 +253,7 @@ Init_ossl_pkcs12(void)
226
253
  rb_define_singleton_method(cPKCS12, "create", ossl_pkcs12_s_create, -1);
227
254
 
228
255
  rb_define_alloc_func(cPKCS12, ossl_pkcs12_s_allocate);
256
+ rb_define_copy_func(cPKCS12, ossl_pkcs12_initialize_copy);
229
257
  rb_attr(cPKCS12, rb_intern("key"), 1, 0, Qfalse);
230
258
  rb_attr(cPKCS12, rb_intern("certificate"), 1, 0, Qfalse);
231
259
  rb_attr(cPKCS12, rb_intern("ca_certs"), 1, 0, Qfalse);
@@ -18,7 +18,7 @@ VALUE ePKCS5;
18
18
  * * +keylen+ - integer
19
19
  * * +digest+ - a string or OpenSSL::Digest object.
20
20
  *
21
- * Available in OpenSSL 0.9.4.
21
+ * Available in OpenSSL >= 1.0.0.
22
22
  *
23
23
  * Digests other than SHA1 may not be supported by other cryptography libraries.
24
24
  */
@@ -48,7 +48,6 @@ ossl_pkcs5_pbkdf2_hmac(VALUE self, VALUE pass, VALUE salt, VALUE iter, VALUE key
48
48
  #endif
49
49
 
50
50
 
51
- #ifdef HAVE_PKCS5_PBKDF2_HMAC_SHA1
52
51
  /*
53
52
  * call-seq:
54
53
  * PKCS5.pbkdf2_hmac_sha1(pass, salt, iter, keylen) => string
@@ -61,7 +60,7 @@ ossl_pkcs5_pbkdf2_hmac(VALUE self, VALUE pass, VALUE salt, VALUE iter, VALUE key
61
60
  *
62
61
  * This method is available in almost any version of OpenSSL.
63
62
  *
64
- * Conforms to rfc2898.
63
+ * Conforms to RFC 2898.
65
64
  */
66
65
  static VALUE
67
66
  ossl_pkcs5_pbkdf2_hmac_sha1(VALUE self, VALUE pass, VALUE salt, VALUE iter, VALUE keylen)
@@ -81,21 +80,14 @@ ossl_pkcs5_pbkdf2_hmac_sha1(VALUE self, VALUE pass, VALUE salt, VALUE iter, VALU
81
80
 
82
81
  return str;
83
82
  }
84
- #else
85
- #define ossl_pkcs5_pbkdf2_hmac_sha1 rb_f_notimplement
86
- #endif
87
83
 
88
84
  void
89
85
  Init_ossl_pkcs5(void)
90
86
  {
91
- /*
92
- * Password-based Encryption
93
- *
94
- */
95
-
96
- #if 0
97
- mOSSL = rb_define_module("OpenSSL"); /* let rdoc know about mOSSL */
98
- #endif
87
+ #if 0
88
+ mOSSL = rb_define_module("OpenSSL");
89
+ eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError);
90
+ #endif
99
91
 
100
92
  /* Document-class: OpenSSL::PKCS5
101
93
  *
@@ -108,7 +100,7 @@ Init_ossl_pkcs5(void)
108
100
  *
109
101
  * PKCS5 offers support for PBKDF2 with an OpenSSL::Digest::SHA1-based
110
102
  * HMAC, or an arbitrary Digest if the underlying version of OpenSSL
111
- * already supports it (>= 0.9.4).
103
+ * already supports it (>= 1.0.0).
112
104
  *
113
105
  * === Parameters
114
106
  * ==== Password
@@ -127,6 +127,22 @@ static const rb_data_type_t ossl_pkcs7_recip_info_type = {
127
127
  * Public
128
128
  * (MADE PRIVATE UNTIL SOMEBODY WILL NEED THEM)
129
129
  */
130
+ static PKCS7_SIGNER_INFO *
131
+ ossl_PKCS7_SIGNER_INFO_dup(const PKCS7_SIGNER_INFO *si)
132
+ {
133
+ return (PKCS7_SIGNER_INFO *)ASN1_dup((i2d_of_void *)i2d_PKCS7_SIGNER_INFO,
134
+ (d2i_of_void *)d2i_PKCS7_SIGNER_INFO,
135
+ (char *)si);
136
+ }
137
+
138
+ static PKCS7_RECIP_INFO *
139
+ ossl_PKCS7_RECIP_INFO_dup(const PKCS7_RECIP_INFO *si)
140
+ {
141
+ return (PKCS7_RECIP_INFO *)ASN1_dup((i2d_of_void *)i2d_PKCS7_RECIP_INFO,
142
+ (d2i_of_void *)d2i_PKCS7_RECIP_INFO,
143
+ (char *)si);
144
+ }
145
+
130
146
  static VALUE
131
147
  ossl_pkcs7si_new(PKCS7_SIGNER_INFO *p7si)
132
148
  {
@@ -134,7 +150,7 @@ ossl_pkcs7si_new(PKCS7_SIGNER_INFO *p7si)
134
150
  VALUE obj;
135
151
 
136
152
  obj = NewPKCS7si(cPKCS7Signer);
137
- pkcs7 = p7si ? PKCS7_SIGNER_INFO_dup(p7si) : PKCS7_SIGNER_INFO_new();
153
+ pkcs7 = p7si ? ossl_PKCS7_SIGNER_INFO_dup(p7si) : PKCS7_SIGNER_INFO_new();
138
154
  if (!pkcs7) ossl_raise(ePKCS7Error, NULL);
139
155
  SetPKCS7si(obj, pkcs7);
140
156
 
@@ -147,7 +163,7 @@ DupPKCS7SignerPtr(VALUE obj)
147
163
  PKCS7_SIGNER_INFO *p7si, *pkcs7;
148
164
 
149
165
  SafeGetPKCS7si(obj, p7si);
150
- if (!(pkcs7 = PKCS7_SIGNER_INFO_dup(p7si))) {
166
+ if (!(pkcs7 = ossl_PKCS7_SIGNER_INFO_dup(p7si))) {
151
167
  ossl_raise(ePKCS7Error, NULL);
152
168
  }
153
169
 
@@ -161,7 +177,7 @@ ossl_pkcs7ri_new(PKCS7_RECIP_INFO *p7ri)
161
177
  VALUE obj;
162
178
 
163
179
  obj = NewPKCS7ri(cPKCS7Recipient);
164
- pkcs7 = p7ri ? PKCS7_RECIP_INFO_dup(p7ri) : PKCS7_RECIP_INFO_new();
180
+ pkcs7 = p7ri ? ossl_PKCS7_RECIP_INFO_dup(p7ri) : PKCS7_RECIP_INFO_new();
165
181
  if (!pkcs7) ossl_raise(ePKCS7Error, NULL);
166
182
  SetPKCS7ri(obj, pkcs7);
167
183
 
@@ -174,7 +190,7 @@ DupPKCS7RecipientPtr(VALUE obj)
174
190
  PKCS7_RECIP_INFO *p7ri, *pkcs7;
175
191
 
176
192
  SafeGetPKCS7ri(obj, p7ri);
177
- if (!(pkcs7 = PKCS7_RECIP_INFO_dup(p7ri))) {
193
+ if (!(pkcs7 = ossl_PKCS7_RECIP_INFO_dup(p7ri))) {
178
194
  ossl_raise(ePKCS7Error, NULL);
179
195
  }
180
196
 
@@ -193,7 +209,7 @@ ossl_pkcs7_s_read_smime(VALUE klass, VALUE arg)
193
209
  VALUE ret, data;
194
210
 
195
211
  ret = NewPKCS7(cPKCS7);
196
- in = ossl_obj2bio(arg);
212
+ in = ossl_obj2bio(&arg);
197
213
  out = NULL;
198
214
  pkcs7 = SMIME_read_PKCS7(in, &out);
199
215
  BIO_free(in);
@@ -225,7 +241,7 @@ ossl_pkcs7_s_write_smime(int argc, VALUE *argv, VALUE klass)
225
241
  SafeGetPKCS7(pkcs7, p7);
226
242
  if(!NIL_P(data) && PKCS7_is_detached(p7))
227
243
  flg |= PKCS7_DETACHED;
228
- in = NIL_P(data) ? NULL : ossl_obj2bio(data);
244
+ in = NIL_P(data) ? NULL : ossl_obj2bio(&data);
229
245
  if(!(out = BIO_new(BIO_s_mem()))){
230
246
  BIO_free(in);
231
247
  ossl_raise(ePKCS7Error, NULL);
@@ -262,7 +278,7 @@ ossl_pkcs7_s_sign(int argc, VALUE *argv, VALUE klass)
262
278
  pkey = GetPrivPKeyPtr(key); /* NO NEED TO DUP */
263
279
  flg = NIL_P(flags) ? 0 : NUM2INT(flags);
264
280
  ret = NewPKCS7(cPKCS7);
265
- in = ossl_obj2bio(data);
281
+ in = ossl_obj2bio(&data);
266
282
  if(NIL_P(certs)) x509s = NULL;
267
283
  else{
268
284
  x509s = ossl_protect_x509_ary2sk(certs, &status);
@@ -318,7 +334,7 @@ ossl_pkcs7_s_encrypt(int argc, VALUE *argv, VALUE klass)
318
334
  else ciph = GetCipherPtr(cipher); /* NO NEED TO DUP */
319
335
  flg = NIL_P(flags) ? 0 : NUM2INT(flags);
320
336
  ret = NewPKCS7(cPKCS7);
321
- in = ossl_obj2bio(data);
337
+ in = ossl_obj2bio(&data);
322
338
  x509s = ossl_protect_x509_ary2sk(certs, &status);
323
339
  if(status){
324
340
  BIO_free(in);
@@ -369,7 +385,7 @@ ossl_pkcs7_initialize(int argc, VALUE *argv, VALUE self)
369
385
  if(rb_scan_args(argc, argv, "01", &arg) == 0)
370
386
  return self;
371
387
  arg = ossl_to_der_if_possible(arg);
372
- in = ossl_obj2bio(arg);
388
+ in = ossl_obj2bio(&arg);
373
389
  p7 = PEM_read_bio_PKCS7(in, &pkcs, NULL, NULL);
374
390
  if (!p7) {
375
391
  OSSL_BIO_reset(in);
@@ -429,12 +445,13 @@ ossl_pkcs7_sym2typeid(VALUE sym)
429
445
  { "digest", NID_pkcs7_digest },
430
446
  };
431
447
 
432
- if (RB_TYPE_P(sym, T_SYMBOL)) sym = rb_sym2str(sym);
448
+ if (SYMBOL_P(sym)) sym = rb_sym2str(sym);
433
449
  else StringValue(sym);
434
450
  RSTRING_GETMEM(sym, s, l);
451
+
435
452
  for(i = 0; ; i++){
436
453
  if(i == numberof(p7_type_tab))
437
- ossl_raise(ePKCS7Error, "unknown type \"%s\"", s);
454
+ ossl_raise(ePKCS7Error, "unknown type \"%"PRIsVALUE"\"", sym);
438
455
  if(strlen(p7_type_tab[i].name) != l) continue;
439
456
  if(strcmp(p7_type_tab[i].name, s) == 0){
440
457
  ret = p7_type_tab[i].nid;
@@ -760,7 +777,7 @@ ossl_pkcs7_verify(int argc, VALUE *argv, VALUE self)
760
777
  x509st = GetX509StorePtr(store);
761
778
  flg = NIL_P(flags) ? 0 : NUM2INT(flags);
762
779
  if(NIL_P(indata)) indata = ossl_pkcs7_get_data(self);
763
- in = NIL_P(indata) ? NULL : ossl_obj2bio(indata);
780
+ in = NIL_P(indata) ? NULL : ossl_obj2bio(&indata);
764
781
  if(NIL_P(certs)) x509s = NULL;
765
782
  else{
766
783
  x509s = ossl_protect_x509_ary2sk(certs, &status);
@@ -778,9 +795,9 @@ ossl_pkcs7_verify(int argc, VALUE *argv, VALUE self)
778
795
  BIO_free(in);
779
796
  sk_X509_pop_free(x509s, X509_free);
780
797
  if (ok < 0) ossl_raise(ePKCS7Error, "PKCS7_verify");
781
- msg = ERR_reason_error_string(ERR_get_error());
798
+ msg = ERR_reason_error_string(ERR_peek_error());
782
799
  ossl_pkcs7_set_err_string(self, msg ? rb_str_new2(msg) : Qnil);
783
- ERR_clear_error();
800
+ ossl_clear_error();
784
801
  data = ossl_membio2str(out);
785
802
  ossl_pkcs7_set_data(self, data);
786
803
 
@@ -827,7 +844,7 @@ ossl_pkcs7_add_data(VALUE self, VALUE data)
827
844
  if(!PKCS7_content_new(pkcs7, NID_pkcs7_data))
828
845
  ossl_raise(ePKCS7Error, NULL);
829
846
  }
830
- in = ossl_obj2bio(data);
847
+ in = ossl_obj2bio(&data);
831
848
  if(!(out = PKCS7_dataInit(pkcs7, NULL))) goto err;
832
849
  for(;;){
833
850
  if((len = BIO_read(in, buf, sizeof(buf))) <= 0)
@@ -1037,6 +1054,12 @@ ossl_pkcs7ri_get_enc_key(VALUE self)
1037
1054
  void
1038
1055
  Init_ossl_pkcs7(void)
1039
1056
  {
1057
+ #undef rb_intern
1058
+ #if 0
1059
+ mOSSL = rb_define_module("OpenSSL");
1060
+ eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError);
1061
+ #endif
1062
+
1040
1063
  cPKCS7 = rb_define_class_under(mOSSL, "PKCS7", rb_cObject);
1041
1064
  ePKCS7Error = rb_define_class_under(cPKCS7, "PKCS7Error", eOSSLError);
1042
1065
  rb_define_singleton_method(cPKCS7, "read_smime", ossl_pkcs7_s_read_smime, 1);
@@ -15,25 +15,26 @@
15
15
  VALUE mPKey;
16
16
  VALUE cPKey;
17
17
  VALUE ePKeyError;
18
- ID id_private_q;
18
+ static ID id_private_q;
19
19
 
20
20
  /*
21
21
  * callback for generating keys
22
22
  */
23
- void
24
- ossl_generate_cb(int p, int n, void *arg)
23
+ static VALUE
24
+ call_check_ints0(VALUE arg)
25
25
  {
26
- VALUE ary;
27
-
28
- ary = rb_ary_new2(2);
29
- rb_ary_store(ary, 0, INT2NUM(p));
30
- rb_ary_store(ary, 1, INT2NUM(n));
26
+ rb_thread_check_ints();
27
+ return Qnil;
28
+ }
31
29
 
32
- rb_yield(ary);
30
+ static void *
31
+ call_check_ints(void *arg)
32
+ {
33
+ int state;
34
+ rb_protect(call_check_ints0, Qnil, &state);
35
+ return (void *)(VALUE)state;
33
36
  }
34
37
 
35
- #if HAVE_BN_GENCB
36
- /* OpenSSL 2nd version of GN generation callback */
37
38
  int
38
39
  ossl_generate_cb_2(int p, int n, BN_GENCB *cb)
39
40
  {
@@ -41,7 +42,7 @@ ossl_generate_cb_2(int p, int n, BN_GENCB *cb)
41
42
  struct ossl_generate_cb_arg *arg;
42
43
  int state;
43
44
 
44
- arg = (struct ossl_generate_cb_arg *)cb->arg;
45
+ arg = (struct ossl_generate_cb_arg *)BN_GENCB_get_arg(cb);
45
46
  if (arg->yield) {
46
47
  ary = rb_ary_new2(2);
47
48
  rb_ary_store(ary, 0, INT2NUM(p));
@@ -52,11 +53,18 @@ ossl_generate_cb_2(int p, int n, BN_GENCB *cb)
52
53
  */
53
54
  rb_protect(rb_yield, ary, &state);
54
55
  if (state) {
55
- arg->stop = 1;
56
56
  arg->state = state;
57
+ return 0;
58
+ }
59
+ }
60
+ if (arg->interrupted) {
61
+ arg->interrupted = 0;
62
+ state = (int)(VALUE)rb_thread_call_with_gvl(call_check_ints, NULL);
63
+ if (state) {
64
+ arg->state = state;
65
+ return 0;
57
66
  }
58
67
  }
59
- if (arg->stop) return 0;
60
68
  return 1;
61
69
  }
62
70
 
@@ -64,9 +72,8 @@ void
64
72
  ossl_generate_cb_stop(void *ptr)
65
73
  {
66
74
  struct ossl_generate_cb_arg *arg = (struct ossl_generate_cb_arg *)ptr;
67
- arg->stop = 1;
75
+ arg->interrupted = 1;
68
76
  }
69
- #endif
70
77
 
71
78
  static void
72
79
  ossl_evp_pkey_free(void *ptr)
@@ -85,13 +92,16 @@ const rb_data_type_t ossl_evp_pkey_type = {
85
92
  0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
86
93
  };
87
94
 
88
- VALUE
89
- ossl_pkey_new(EVP_PKEY *pkey)
95
+ static VALUE
96
+ pkey_new0(EVP_PKEY *pkey)
90
97
  {
91
- if (!pkey) {
92
- ossl_raise(ePKeyError, "Cannot make new key from NULL.");
93
- }
94
- switch (EVP_PKEY_type(pkey->type)) {
98
+ VALUE obj;
99
+ int type;
100
+
101
+ if (!pkey || (type = EVP_PKEY_base_id(pkey)) == EVP_PKEY_NONE)
102
+ ossl_raise(rb_eRuntimeError, "pkey is empty");
103
+
104
+ switch (type) {
95
105
  #if !defined(OPENSSL_NO_RSA)
96
106
  case EVP_PKEY_RSA:
97
107
  return ossl_rsa_new(pkey);
@@ -109,80 +119,112 @@ ossl_pkey_new(EVP_PKEY *pkey)
109
119
  return ossl_ec_new(pkey);
110
120
  #endif
111
121
  default:
112
- ossl_raise(ePKeyError, "unsupported key type");
122
+ obj = NewPKey(cPKey);
123
+ SetPKey(obj, pkey);
124
+ return obj;
113
125
  }
114
-
115
- UNREACHABLE;
116
126
  }
117
127
 
118
128
  VALUE
119
- ossl_pkey_new_from_file(VALUE filename)
129
+ ossl_pkey_new(EVP_PKEY *pkey)
120
130
  {
121
- FILE *fp;
122
- EVP_PKEY *pkey;
123
-
124
- SafeStringValue(filename);
125
- if (!(fp = fopen(RSTRING_PTR(filename), "r"))) {
126
- ossl_raise(ePKeyError, "%s", strerror(errno));
127
- }
128
- rb_fd_fix_cloexec(fileno(fp));
131
+ VALUE obj;
132
+ int status;
129
133
 
130
- pkey = PEM_read_PrivateKey(fp, NULL, ossl_pem_passwd_cb, NULL);
131
- fclose(fp);
132
- if (!pkey) {
133
- ossl_raise(ePKeyError, NULL);
134
+ obj = rb_protect((VALUE (*)(VALUE))pkey_new0, (VALUE)pkey, &status);
135
+ if (status) {
136
+ EVP_PKEY_free(pkey);
137
+ rb_jump_tag(status);
134
138
  }
135
139
 
136
- return ossl_pkey_new(pkey);
140
+ return obj;
137
141
  }
138
142
 
139
143
  /*
140
144
  * call-seq:
141
- * OpenSSL::PKey.read(string [, pwd ] ) -> PKey
142
- * OpenSSL::PKey.read(file [, pwd ]) -> PKey
145
+ * OpenSSL::PKey.read(string [, pwd ]) -> PKey
146
+ * OpenSSL::PKey.read(io [, pwd ]) -> PKey
147
+ *
148
+ * Reads a DER or PEM encoded string from +string+ or +io+ and returns an
149
+ * instance of the appropriate PKey class.
143
150
  *
144
151
  * === Parameters
145
152
  * * +string+ is a DER- or PEM-encoded string containing an arbitrary private
146
- * or public key.
147
- * * +file+ is an instance of +File+ containing a DER- or PEM-encoded
148
- * arbitrary private or public key.
153
+ * or public key.
154
+ * * +io+ is an instance of +IO+ containing a DER- or PEM-encoded
155
+ * arbitrary private or public key.
149
156
  * * +pwd+ is an optional password in case +string+ or +file+ is an encrypted
150
- * PEM resource.
157
+ * PEM resource.
151
158
  */
152
159
  static VALUE
153
160
  ossl_pkey_new_from_data(int argc, VALUE *argv, VALUE self)
154
161
  {
155
- EVP_PKEY *pkey;
156
- BIO *bio;
157
- VALUE data, pass;
158
- char *passwd = NULL;
162
+ EVP_PKEY *pkey;
163
+ BIO *bio;
164
+ VALUE data, pass;
159
165
 
160
- rb_scan_args(argc, argv, "11", &data, &pass);
166
+ rb_scan_args(argc, argv, "11", &data, &pass);
167
+ pass = ossl_pem_passwd_value(pass);
161
168
 
162
- bio = ossl_obj2bio(data);
163
- if (!(pkey = d2i_PrivateKey_bio(bio, NULL))) {
169
+ bio = ossl_obj2bio(&data);
170
+ if (!(pkey = d2i_PrivateKey_bio(bio, NULL))) {
164
171
  OSSL_BIO_reset(bio);
165
- if (!NIL_P(pass)) {
166
- passwd = StringValuePtr(pass);
167
- }
168
- if (!(pkey = PEM_read_bio_PrivateKey(bio, NULL, ossl_pem_passwd_cb, passwd))) {
172
+ if (!(pkey = PEM_read_bio_PrivateKey(bio, NULL, ossl_pem_passwd_cb, (void *)pass))) {
169
173
  OSSL_BIO_reset(bio);
170
174
  if (!(pkey = d2i_PUBKEY_bio(bio, NULL))) {
171
175
  OSSL_BIO_reset(bio);
172
- if (!NIL_P(pass)) {
173
- passwd = StringValuePtr(pass);
174
- }
175
- pkey = PEM_read_bio_PUBKEY(bio, NULL, ossl_pem_passwd_cb, passwd);
176
+ pkey = PEM_read_bio_PUBKEY(bio, NULL, ossl_pem_passwd_cb, (void *)pass);
176
177
  }
177
178
  }
178
179
  }
179
180
 
180
181
  BIO_free(bio);
181
182
  if (!pkey)
182
- ossl_raise(rb_eArgError, "Could not parse PKey");
183
+ ossl_raise(ePKeyError, "Could not parse PKey");
184
+
183
185
  return ossl_pkey_new(pkey);
184
186
  }
185
187
 
188
+ void
189
+ ossl_pkey_check_public_key(const EVP_PKEY *pkey)
190
+ {
191
+ void *ptr;
192
+ const BIGNUM *n, *e, *pubkey;
193
+
194
+ if (EVP_PKEY_missing_parameters(pkey))
195
+ ossl_raise(ePKeyError, "parameters missing");
196
+
197
+ /* OpenSSL < 1.1.0 takes non-const pointer */
198
+ ptr = EVP_PKEY_get0((EVP_PKEY *)pkey);
199
+ switch (EVP_PKEY_base_id(pkey)) {
200
+ case EVP_PKEY_RSA:
201
+ RSA_get0_key(ptr, &n, &e, NULL);
202
+ if (n && e)
203
+ return;
204
+ break;
205
+ case EVP_PKEY_DSA:
206
+ DSA_get0_key(ptr, &pubkey, NULL);
207
+ if (pubkey)
208
+ return;
209
+ break;
210
+ case EVP_PKEY_DH:
211
+ DH_get0_key(ptr, &pubkey, NULL);
212
+ if (pubkey)
213
+ return;
214
+ break;
215
+ #if !defined(OPENSSL_NO_EC)
216
+ case EVP_PKEY_EC:
217
+ if (EC_KEY_get0_public_key(ptr))
218
+ return;
219
+ break;
220
+ #endif
221
+ default:
222
+ /* unsupported type; assuming ok */
223
+ return;
224
+ }
225
+ ossl_raise(ePKeyError, "public key missing");
226
+ }
227
+
186
228
  EVP_PKEY *
187
229
  GetPKeyPtr(VALUE obj)
188
230
  {
@@ -212,21 +254,7 @@ DupPKeyPtr(VALUE obj)
212
254
  EVP_PKEY *pkey;
213
255
 
214
256
  SafeGetPKey(obj, pkey);
215
- CRYPTO_add(&pkey->references, 1, CRYPTO_LOCK_EVP_PKEY);
216
-
217
- return pkey;
218
- }
219
-
220
- EVP_PKEY *
221
- DupPrivPKeyPtr(VALUE obj)
222
- {
223
- EVP_PKEY *pkey;
224
-
225
- if (rb_funcallv(obj, id_private_q, 0, NULL) != Qtrue) {
226
- ossl_raise(rb_eArgError, "Private key is needed.");
227
- }
228
- SafeGetPKey(obj, pkey);
229
- CRYPTO_add(&pkey->references, 1, CRYPTO_LOCK_EVP_PKEY);
257
+ EVP_PKEY_up_ref(pkey);
230
258
 
231
259
  return pkey;
232
260
  }
@@ -260,7 +288,7 @@ static VALUE
260
288
  ossl_pkey_initialize(VALUE self)
261
289
  {
262
290
  if (rb_obj_is_instance_of(self, cPKey)) {
263
- ossl_raise(rb_eNotImpError, "OpenSSL::PKey::PKey is an abstract class.");
291
+ ossl_raise(rb_eTypeError, "OpenSSL::PKey::PKey can't be instantiated directly");
264
292
  }
265
293
  return self;
266
294
  }
@@ -286,24 +314,32 @@ static VALUE
286
314
  ossl_pkey_sign(VALUE self, VALUE digest, VALUE data)
287
315
  {
288
316
  EVP_PKEY *pkey;
289
- EVP_MD_CTX ctx;
317
+ const EVP_MD *md;
318
+ EVP_MD_CTX *ctx;
290
319
  unsigned int buf_len;
291
320
  VALUE str;
292
321
  int result;
293
322
 
294
- if (rb_funcallv(self, id_private_q, 0, NULL) != Qtrue) {
295
- ossl_raise(rb_eArgError, "Private key is needed.");
296
- }
297
- GetPKey(self, pkey);
298
- EVP_SignInit(&ctx, GetDigestPtr(digest));
323
+ pkey = GetPrivPKeyPtr(self);
324
+ md = GetDigestPtr(digest);
299
325
  StringValue(data);
300
- EVP_SignUpdate(&ctx, RSTRING_PTR(data), RSTRING_LEN(data));
301
- str = rb_str_new(0, EVP_PKEY_size(pkey)+16);
302
- result = EVP_SignFinal(&ctx, (unsigned char *)RSTRING_PTR(str), &buf_len, pkey);
303
- EVP_MD_CTX_cleanup(&ctx);
326
+ str = rb_str_new(0, EVP_PKEY_size(pkey));
327
+
328
+ ctx = EVP_MD_CTX_new();
329
+ if (!ctx)
330
+ ossl_raise(ePKeyError, "EVP_MD_CTX_new");
331
+ if (!EVP_SignInit_ex(ctx, md, NULL)) {
332
+ EVP_MD_CTX_free(ctx);
333
+ ossl_raise(ePKeyError, "EVP_SignInit_ex");
334
+ }
335
+ if (!EVP_SignUpdate(ctx, RSTRING_PTR(data), RSTRING_LEN(data))) {
336
+ EVP_MD_CTX_free(ctx);
337
+ ossl_raise(ePKeyError, "EVP_SignUpdate");
338
+ }
339
+ result = EVP_SignFinal(ctx, (unsigned char *)RSTRING_PTR(str), &buf_len, pkey);
340
+ EVP_MD_CTX_free(ctx);
304
341
  if (!result)
305
- ossl_raise(ePKeyError, NULL);
306
- assert((long)buf_len <= RSTRING_LEN(str));
342
+ ossl_raise(ePKeyError, "EVP_SignFinal");
307
343
  rb_str_set_len(str, buf_len);
308
344
 
309
345
  return str;
@@ -334,25 +370,39 @@ static VALUE
334
370
  ossl_pkey_verify(VALUE self, VALUE digest, VALUE sig, VALUE data)
335
371
  {
336
372
  EVP_PKEY *pkey;
337
- EVP_MD_CTX ctx;
338
- int result;
373
+ const EVP_MD *md;
374
+ EVP_MD_CTX *ctx;
375
+ int siglen, result;
339
376
 
340
377
  GetPKey(self, pkey);
378
+ ossl_pkey_check_public_key(pkey);
379
+ md = GetDigestPtr(digest);
341
380
  StringValue(sig);
381
+ siglen = RSTRING_LENINT(sig);
342
382
  StringValue(data);
343
- EVP_VerifyInit(&ctx, GetDigestPtr(digest));
344
- EVP_VerifyUpdate(&ctx, RSTRING_PTR(data), RSTRING_LEN(data));
345
- result = EVP_VerifyFinal(&ctx, (unsigned char *)RSTRING_PTR(sig), RSTRING_LENINT(sig), pkey);
346
- EVP_MD_CTX_cleanup(&ctx);
383
+
384
+ ctx = EVP_MD_CTX_new();
385
+ if (!ctx)
386
+ ossl_raise(ePKeyError, "EVP_MD_CTX_new");
387
+ if (!EVP_VerifyInit_ex(ctx, md, NULL)) {
388
+ EVP_MD_CTX_free(ctx);
389
+ ossl_raise(ePKeyError, "EVP_VerifyInit_ex");
390
+ }
391
+ if (!EVP_VerifyUpdate(ctx, RSTRING_PTR(data), RSTRING_LEN(data))) {
392
+ EVP_MD_CTX_free(ctx);
393
+ ossl_raise(ePKeyError, "EVP_VerifyUpdate");
394
+ }
395
+ result = EVP_VerifyFinal(ctx, (unsigned char *)RSTRING_PTR(sig), siglen, pkey);
396
+ EVP_MD_CTX_free(ctx);
347
397
  switch (result) {
348
398
  case 0:
399
+ ossl_clear_error();
349
400
  return Qfalse;
350
401
  case 1:
351
402
  return Qtrue;
352
403
  default:
353
- ossl_raise(ePKeyError, NULL);
404
+ ossl_raise(ePKeyError, "EVP_VerifyFinal");
354
405
  }
355
- return Qnil; /* dummy */
356
406
  }
357
407
 
358
408
  /*
@@ -361,8 +411,10 @@ ossl_pkey_verify(VALUE self, VALUE digest, VALUE sig, VALUE data)
361
411
  void
362
412
  Init_ossl_pkey(void)
363
413
  {
414
+ #undef rb_intern
364
415
  #if 0
365
- mOSSL = rb_define_module("OpenSSL"); /* let rdoc know about mOSSL */
416
+ mOSSL = rb_define_module("OpenSSL");
417
+ eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError);
366
418
  #endif
367
419
 
368
420
  /* Document-module: OpenSSL::PKey
@@ -374,7 +426,7 @@ Init_ossl_pkey(void)
374
426
  * algorithm consists of two parts: a public key that may be distributed
375
427
  * to others and a private key that needs to remain secret.
376
428
  *
377
- * Messages encrypted with a public key can only be encrypted by
429
+ * Messages encrypted with a public key can only be decrypted by
378
430
  * recipients that are in possession of the associated private key.
379
431
  * Since public key algorithms are considerably slower than symmetric
380
432
  * key algorithms (cf. OpenSSL::Cipher) they are often used to establish