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.
- 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
|