rubysl-openssl 2.10 → 2.11
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/ext/rubysl/openssl/deprecation.rb +7 -3
- data/ext/rubysl/openssl/extconf.rb +148 -103
- data/ext/rubysl/openssl/openssl_missing.c +94 -275
- data/ext/rubysl/openssl/openssl_missing.h +167 -98
- data/ext/rubysl/openssl/ossl.c +266 -212
- data/ext/rubysl/openssl/ossl.h +27 -89
- data/ext/rubysl/openssl/ossl_asn1.c +157 -221
- data/ext/rubysl/openssl/ossl_asn1.h +11 -3
- data/ext/rubysl/openssl/ossl_bio.c +10 -40
- data/ext/rubysl/openssl/ossl_bio.h +1 -2
- data/ext/rubysl/openssl/ossl_bn.c +144 -100
- data/ext/rubysl/openssl/ossl_bn.h +3 -1
- data/ext/rubysl/openssl/ossl_cipher.c +270 -195
- data/ext/rubysl/openssl/ossl_config.c +7 -1
- data/ext/rubysl/openssl/ossl_config.h +0 -1
- data/ext/rubysl/openssl/ossl_digest.c +40 -29
- data/ext/rubysl/openssl/ossl_engine.c +23 -62
- data/ext/rubysl/openssl/ossl_hmac.c +82 -55
- data/ext/rubysl/openssl/ossl_ns_spki.c +22 -22
- data/ext/rubysl/openssl/ossl_ocsp.c +894 -144
- data/ext/rubysl/openssl/ossl_ocsp.h +1 -1
- data/ext/rubysl/openssl/ossl_pkcs12.c +47 -19
- data/ext/rubysl/openssl/ossl_pkcs5.c +7 -15
- data/ext/rubysl/openssl/ossl_pkcs7.c +38 -15
- data/ext/rubysl/openssl/ossl_pkey.c +151 -99
- data/ext/rubysl/openssl/ossl_pkey.h +123 -29
- data/ext/rubysl/openssl/ossl_pkey_dh.c +143 -92
- data/ext/rubysl/openssl/ossl_pkey_dsa.c +149 -104
- data/ext/rubysl/openssl/ossl_pkey_ec.c +646 -524
- data/ext/rubysl/openssl/ossl_pkey_rsa.c +180 -121
- data/ext/rubysl/openssl/ossl_rand.c +25 -21
- data/ext/rubysl/openssl/ossl_ssl.c +795 -413
- data/ext/rubysl/openssl/ossl_ssl.h +3 -0
- data/ext/rubysl/openssl/ossl_ssl_session.c +83 -77
- data/ext/rubysl/openssl/ossl_version.h +1 -1
- data/ext/rubysl/openssl/ossl_x509.c +92 -8
- data/ext/rubysl/openssl/ossl_x509.h +14 -5
- data/ext/rubysl/openssl/ossl_x509attr.c +77 -41
- data/ext/rubysl/openssl/ossl_x509cert.c +45 -46
- data/ext/rubysl/openssl/ossl_x509crl.c +51 -57
- data/ext/rubysl/openssl/ossl_x509ext.c +39 -33
- data/ext/rubysl/openssl/ossl_x509name.c +68 -45
- data/ext/rubysl/openssl/ossl_x509req.c +32 -38
- data/ext/rubysl/openssl/ossl_x509revoked.c +43 -9
- data/ext/rubysl/openssl/ossl_x509store.c +309 -104
- data/ext/rubysl/openssl/ruby_missing.h +8 -6
- data/lib/openssl/buffering.rb +11 -5
- data/lib/openssl/cipher.rb +23 -15
- data/lib/openssl/digest.rb +7 -10
- data/lib/openssl/pkey.rb +15 -8
- data/lib/openssl/ssl.rb +81 -105
- data/lib/rubysl/openssl.rb +1 -4
- data/lib/rubysl/openssl/version.rb +1 -1
- metadata +3 -4
@@ -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
|
-
*
|
78
|
-
*
|
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 :
|
104
|
-
friendlyname = NIL_P(name) ? NULL :
|
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(
|
110
|
-
|
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(
|
114
|
-
|
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 :
|
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
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
if(
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
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.
|
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
|
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
|
-
|
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.
|
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 ?
|
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 =
|
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 ?
|
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 =
|
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 (
|
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 \"%
|
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(
|
798
|
+
msg = ERR_reason_error_string(ERR_peek_error());
|
782
799
|
ossl_pkcs7_set_err_string(self, msg ? rb_str_new2(msg) : Qnil);
|
783
|
-
|
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
|
-
|
24
|
-
|
23
|
+
static VALUE
|
24
|
+
call_check_ints0(VALUE arg)
|
25
25
|
{
|
26
|
-
|
27
|
-
|
28
|
-
|
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
|
-
|
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
|
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->
|
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
|
-
|
95
|
+
static VALUE
|
96
|
+
pkey_new0(EVP_PKEY *pkey)
|
90
97
|
{
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
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
|
-
|
122
|
+
obj = NewPKey(cPKey);
|
123
|
+
SetPKey(obj, pkey);
|
124
|
+
return obj;
|
113
125
|
}
|
114
|
-
|
115
|
-
UNREACHABLE;
|
116
126
|
}
|
117
127
|
|
118
128
|
VALUE
|
119
|
-
|
129
|
+
ossl_pkey_new(EVP_PKEY *pkey)
|
120
130
|
{
|
121
|
-
|
122
|
-
|
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
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
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
|
140
|
+
return obj;
|
137
141
|
}
|
138
142
|
|
139
143
|
/*
|
140
144
|
* call-seq:
|
141
|
-
* OpenSSL::PKey.read(string [, pwd ]
|
142
|
-
* OpenSSL::PKey.read(
|
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
|
-
*
|
147
|
-
* * +
|
148
|
-
*
|
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
|
-
*
|
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
|
-
|
156
|
-
|
157
|
-
|
158
|
-
char *passwd = NULL;
|
162
|
+
EVP_PKEY *pkey;
|
163
|
+
BIO *bio;
|
164
|
+
VALUE data, pass;
|
159
165
|
|
160
|
-
|
166
|
+
rb_scan_args(argc, argv, "11", &data, &pass);
|
167
|
+
pass = ossl_pem_passwd_value(pass);
|
161
168
|
|
162
|
-
|
163
|
-
|
169
|
+
bio = ossl_obj2bio(&data);
|
170
|
+
if (!(pkey = d2i_PrivateKey_bio(bio, NULL))) {
|
164
171
|
OSSL_BIO_reset(bio);
|
165
|
-
if (!
|
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
|
-
|
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(
|
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
|
-
|
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(
|
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
|
-
|
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
|
-
|
295
|
-
|
296
|
-
}
|
297
|
-
GetPKey(self, pkey);
|
298
|
-
EVP_SignInit(&ctx, GetDigestPtr(digest));
|
323
|
+
pkey = GetPrivPKeyPtr(self);
|
324
|
+
md = GetDigestPtr(digest);
|
299
325
|
StringValue(data);
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
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,
|
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
|
-
|
338
|
-
|
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
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
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,
|
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");
|
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
|
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
|