rubysl-openssl 1.0.2 → 2.0.0
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 +4 -4
- data/.travis.yml +5 -6
- data/ext/rubysl/openssl/.gitignore +3 -0
- data/ext/rubysl/openssl/deprecation.rb +21 -0
- data/ext/rubysl/openssl/extconf.rb +45 -32
- data/ext/rubysl/openssl/openssl_missing.c +20 -7
- data/ext/rubysl/openssl/openssl_missing.h +22 -15
- data/ext/rubysl/openssl/ossl.c +610 -61
- data/ext/rubysl/openssl/ossl.h +31 -17
- data/ext/rubysl/openssl/ossl_asn1.c +974 -183
- data/ext/rubysl/openssl/ossl_asn1.h +3 -3
- data/ext/rubysl/openssl/ossl_bio.c +4 -3
- data/ext/rubysl/openssl/ossl_bio.h +1 -1
- data/ext/rubysl/openssl/ossl_bn.c +32 -28
- data/ext/rubysl/openssl/ossl_bn.h +1 -1
- data/ext/rubysl/openssl/ossl_cipher.c +494 -93
- data/ext/rubysl/openssl/ossl_cipher.h +1 -1
- data/ext/rubysl/openssl/ossl_config.c +4 -5
- data/ext/rubysl/openssl/ossl_config.h +1 -1
- data/ext/rubysl/openssl/ossl_digest.c +206 -24
- data/ext/rubysl/openssl/ossl_digest.h +1 -1
- data/ext/rubysl/openssl/ossl_engine.c +48 -26
- data/ext/rubysl/openssl/ossl_engine.h +1 -1
- data/ext/rubysl/openssl/ossl_hmac.c +40 -38
- data/ext/rubysl/openssl/ossl_hmac.h +1 -1
- data/ext/rubysl/openssl/ossl_ns_spki.c +157 -25
- data/ext/rubysl/openssl/ossl_ns_spki.h +1 -1
- data/ext/rubysl/openssl/ossl_ocsp.c +57 -40
- data/ext/rubysl/openssl/ossl_ocsp.h +1 -1
- data/ext/rubysl/openssl/ossl_pkcs12.c +15 -13
- data/ext/rubysl/openssl/ossl_pkcs12.h +1 -1
- data/ext/rubysl/openssl/ossl_pkcs5.c +108 -18
- data/ext/rubysl/openssl/ossl_pkcs7.c +44 -37
- data/ext/rubysl/openssl/ossl_pkcs7.h +1 -1
- data/ext/rubysl/openssl/ossl_pkey.c +211 -15
- data/ext/rubysl/openssl/ossl_pkey.h +19 -9
- data/ext/rubysl/openssl/ossl_pkey_dh.c +180 -47
- data/ext/rubysl/openssl/ossl_pkey_dsa.c +184 -47
- data/ext/rubysl/openssl/ossl_pkey_ec.c +177 -93
- data/ext/rubysl/openssl/ossl_pkey_rsa.c +209 -102
- data/ext/rubysl/openssl/ossl_rand.c +15 -15
- data/ext/rubysl/openssl/ossl_rand.h +1 -1
- data/ext/rubysl/openssl/ossl_ssl.c +939 -192
- data/ext/rubysl/openssl/ossl_ssl.h +6 -6
- data/ext/rubysl/openssl/ossl_ssl_session.c +78 -62
- data/ext/rubysl/openssl/ossl_version.h +2 -2
- data/ext/rubysl/openssl/ossl_x509.c +1 -1
- data/ext/rubysl/openssl/ossl_x509.h +1 -1
- data/ext/rubysl/openssl/ossl_x509attr.c +20 -19
- data/ext/rubysl/openssl/ossl_x509cert.c +169 -67
- data/ext/rubysl/openssl/ossl_x509crl.c +41 -39
- data/ext/rubysl/openssl/ossl_x509ext.c +51 -38
- data/ext/rubysl/openssl/ossl_x509name.c +139 -29
- data/ext/rubysl/openssl/ossl_x509req.c +42 -40
- data/ext/rubysl/openssl/ossl_x509revoked.c +20 -20
- data/ext/rubysl/openssl/ossl_x509store.c +99 -47
- data/ext/rubysl/openssl/ruby_missing.h +3 -16
- data/lib/openssl/bn.rb +19 -19
- data/lib/openssl/buffering.rb +222 -14
- data/lib/openssl/cipher.rb +20 -20
- data/lib/openssl/config.rb +1 -4
- data/lib/openssl/digest.rb +47 -19
- data/lib/openssl/ssl.rb +197 -1
- data/lib/openssl/x509.rb +162 -1
- data/lib/rubysl/openssl.rb +4 -8
- data/lib/rubysl/openssl/version.rb +1 -1
- data/rubysl-openssl.gemspec +1 -2
- metadata +16 -34
- data/ext/rubysl/openssl/extconf.h +0 -50
- data/lib/openssl/net/ftptls.rb +0 -53
- data/lib/openssl/net/telnets.rb +0 -251
- data/lib/openssl/pkcs7.rb +0 -25
- data/lib/openssl/ssl-internal.rb +0 -187
- data/lib/openssl/x509-internal.rb +0 -153
@@ -14,55 +14,55 @@
|
|
14
14
|
#if defined(OSSL_OCSP_ENABLED)
|
15
15
|
|
16
16
|
#define WrapOCSPReq(klass, obj, req) do { \
|
17
|
-
if(!req) ossl_raise(rb_eRuntimeError, "Request wasn't initialized!"); \
|
18
|
-
obj = Data_Wrap_Struct(klass, 0, OCSP_REQUEST_free, req); \
|
17
|
+
if(!(req)) ossl_raise(rb_eRuntimeError, "Request wasn't initialized!"); \
|
18
|
+
(obj) = Data_Wrap_Struct((klass), 0, OCSP_REQUEST_free, (req)); \
|
19
19
|
} while (0)
|
20
20
|
#define GetOCSPReq(obj, req) do { \
|
21
|
-
Data_Get_Struct(obj, OCSP_REQUEST, req); \
|
22
|
-
if(!req) ossl_raise(rb_eRuntimeError, "Request wasn't initialized!"); \
|
21
|
+
Data_Get_Struct((obj), OCSP_REQUEST, (req)); \
|
22
|
+
if(!(req)) ossl_raise(rb_eRuntimeError, "Request wasn't initialized!"); \
|
23
23
|
} while (0)
|
24
24
|
#define SafeGetOCSPReq(obj, req) do { \
|
25
|
-
OSSL_Check_Kind(obj, cOCSPReq); \
|
26
|
-
GetOCSPReq(obj, req); \
|
25
|
+
OSSL_Check_Kind((obj), cOCSPReq); \
|
26
|
+
GetOCSPReq((obj), (req)); \
|
27
27
|
} while (0)
|
28
28
|
|
29
29
|
#define WrapOCSPRes(klass, obj, res) do { \
|
30
|
-
if(!res) ossl_raise(rb_eRuntimeError, "Response wasn't initialized!"); \
|
31
|
-
obj = Data_Wrap_Struct(klass, 0, OCSP_RESPONSE_free, res); \
|
30
|
+
if(!(res)) ossl_raise(rb_eRuntimeError, "Response wasn't initialized!"); \
|
31
|
+
(obj) = Data_Wrap_Struct((klass), 0, OCSP_RESPONSE_free, (res)); \
|
32
32
|
} while (0)
|
33
33
|
#define GetOCSPRes(obj, res) do { \
|
34
|
-
Data_Get_Struct(obj, OCSP_RESPONSE, res); \
|
35
|
-
if(!res) ossl_raise(rb_eRuntimeError, "Response wasn't initialized!"); \
|
34
|
+
Data_Get_Struct((obj), OCSP_RESPONSE, (res)); \
|
35
|
+
if(!(res)) ossl_raise(rb_eRuntimeError, "Response wasn't initialized!"); \
|
36
36
|
} while (0)
|
37
37
|
#define SafeGetOCSPRes(obj, res) do { \
|
38
|
-
OSSL_Check_Kind(obj, cOCSPRes); \
|
39
|
-
GetOCSPRes(obj, res); \
|
38
|
+
OSSL_Check_Kind((obj), cOCSPRes); \
|
39
|
+
GetOCSPRes((obj), (res)); \
|
40
40
|
} while (0)
|
41
41
|
|
42
42
|
#define WrapOCSPBasicRes(klass, obj, res) do { \
|
43
|
-
if(!res) ossl_raise(rb_eRuntimeError, "Response wasn't initialized!"); \
|
44
|
-
obj = Data_Wrap_Struct(klass, 0, OCSP_BASICRESP_free, res); \
|
43
|
+
if(!(res)) ossl_raise(rb_eRuntimeError, "Response wasn't initialized!"); \
|
44
|
+
(obj) = Data_Wrap_Struct((klass), 0, OCSP_BASICRESP_free, (res)); \
|
45
45
|
} while (0)
|
46
46
|
#define GetOCSPBasicRes(obj, res) do { \
|
47
|
-
Data_Get_Struct(obj, OCSP_BASICRESP, res); \
|
48
|
-
if(!res) ossl_raise(rb_eRuntimeError, "Response wasn't initialized!"); \
|
47
|
+
Data_Get_Struct((obj), OCSP_BASICRESP, (res)); \
|
48
|
+
if(!(res)) ossl_raise(rb_eRuntimeError, "Response wasn't initialized!"); \
|
49
49
|
} while (0)
|
50
50
|
#define SafeGetOCSPBasicRes(obj, res) do { \
|
51
|
-
OSSL_Check_Kind(obj, cOCSPBasicRes); \
|
52
|
-
GetOCSPBasicRes(obj, res); \
|
51
|
+
OSSL_Check_Kind((obj), cOCSPBasicRes); \
|
52
|
+
GetOCSPBasicRes((obj), (res)); \
|
53
53
|
} while (0)
|
54
54
|
|
55
55
|
#define WrapOCSPCertId(klass, obj, cid) do { \
|
56
|
-
if(!cid) ossl_raise(rb_eRuntimeError, "Cert ID wasn't initialized!"); \
|
57
|
-
obj = Data_Wrap_Struct(klass, 0, OCSP_CERTID_free, cid); \
|
56
|
+
if(!(cid)) ossl_raise(rb_eRuntimeError, "Cert ID wasn't initialized!"); \
|
57
|
+
(obj) = Data_Wrap_Struct((klass), 0, OCSP_CERTID_free, (cid)); \
|
58
58
|
} while (0)
|
59
59
|
#define GetOCSPCertId(obj, cid) do { \
|
60
|
-
Data_Get_Struct(obj, OCSP_CERTID, cid); \
|
61
|
-
if(!cid) ossl_raise(rb_eRuntimeError, "Cert ID wasn't initialized!"); \
|
60
|
+
Data_Get_Struct((obj), OCSP_CERTID, (cid)); \
|
61
|
+
if(!(cid)) ossl_raise(rb_eRuntimeError, "Cert ID wasn't initialized!"); \
|
62
62
|
} while (0)
|
63
63
|
#define SafeGetOCSPCertId(obj, cid) do { \
|
64
|
-
OSSL_Check_Kind(obj, cOCSPCertId); \
|
65
|
-
GetOCSPCertId(obj, cid); \
|
64
|
+
OSSL_Check_Kind((obj), cOCSPCertId); \
|
65
|
+
GetOCSPCertId((obj), (cid)); \
|
66
66
|
} while (0)
|
67
67
|
|
68
68
|
VALUE mOCSP;
|
@@ -107,11 +107,13 @@ ossl_ocspreq_initialize(int argc, VALUE *argv, VALUE self)
|
|
107
107
|
|
108
108
|
rb_scan_args(argc, argv, "01", &arg);
|
109
109
|
if(!NIL_P(arg)){
|
110
|
+
OCSP_REQUEST *req = DATA_PTR(self), *x;
|
110
111
|
arg = ossl_to_der_if_possible(arg);
|
111
112
|
StringValue(arg);
|
112
|
-
p = (
|
113
|
-
|
114
|
-
|
113
|
+
p = (unsigned char*)RSTRING_PTR(arg);
|
114
|
+
x = d2i_OCSP_REQUEST(&req, &p, RSTRING_LEN(arg));
|
115
|
+
DATA_PTR(self) = req;
|
116
|
+
if(!x){
|
115
117
|
ossl_raise(eOCSPError, "cannot load DER encoded request");
|
116
118
|
}
|
117
119
|
}
|
@@ -134,7 +136,7 @@ ossl_ocspreq_add_nonce(int argc, VALUE *argv, VALUE self)
|
|
134
136
|
else{
|
135
137
|
StringValue(val);
|
136
138
|
GetOCSPReq(self, req);
|
137
|
-
ret = OCSP_request_add1_nonce(req, RSTRING_PTR(val),
|
139
|
+
ret = OCSP_request_add1_nonce(req, (unsigned char *)RSTRING_PTR(val), RSTRING_LENINT(val));
|
138
140
|
}
|
139
141
|
if(!ret) ossl_raise(eOCSPError, NULL);
|
140
142
|
|
@@ -243,7 +245,7 @@ ossl_ocspreq_verify(int argc, VALUE *argv, VALUE self)
|
|
243
245
|
|
244
246
|
rb_scan_args(argc, argv, "21", &certs, &store, &flags);
|
245
247
|
x509st = GetX509StorePtr(store);
|
246
|
-
flg = NIL_P(flags) ? 0 :
|
248
|
+
flg = NIL_P(flags) ? 0 : NUM2INT(flags);
|
247
249
|
x509s = ossl_x509_ary2sk(certs);
|
248
250
|
GetOCSPReq(self, req);
|
249
251
|
result = OCSP_request_verify(req, x509s, x509st, flg);
|
@@ -265,7 +267,7 @@ ossl_ocspreq_to_der(VALUE self)
|
|
265
267
|
if((len = i2d_OCSP_REQUEST(req, NULL)) <= 0)
|
266
268
|
ossl_raise(eOCSPError, NULL);
|
267
269
|
str = rb_str_new(0, len);
|
268
|
-
p = RSTRING_PTR(str);
|
270
|
+
p = (unsigned char *)RSTRING_PTR(str);
|
269
271
|
if(i2d_OCSP_REQUEST(req, &p) <= 0)
|
270
272
|
ossl_raise(eOCSPError, NULL);
|
271
273
|
ossl_str_adjust(str, p);
|
@@ -314,11 +316,13 @@ ossl_ocspres_initialize(int argc, VALUE *argv, VALUE self)
|
|
314
316
|
|
315
317
|
rb_scan_args(argc, argv, "01", &arg);
|
316
318
|
if(!NIL_P(arg)){
|
319
|
+
OCSP_RESPONSE *res = DATA_PTR(self), *x;
|
317
320
|
arg = ossl_to_der_if_possible(arg);
|
318
321
|
StringValue(arg);
|
319
|
-
p = (
|
320
|
-
|
321
|
-
|
322
|
+
p = (unsigned char *)RSTRING_PTR(arg);
|
323
|
+
x = d2i_OCSP_RESPONSE(&res, &p, RSTRING_LEN(arg));
|
324
|
+
DATA_PTR(self) = res;
|
325
|
+
if(!x){
|
322
326
|
ossl_raise(eOCSPError, "cannot load DER encoded response");
|
323
327
|
}
|
324
328
|
}
|
@@ -377,7 +381,7 @@ ossl_ocspres_to_der(VALUE self)
|
|
377
381
|
if((len = i2d_OCSP_RESPONSE(res, NULL)) <= 0)
|
378
382
|
ossl_raise(eOCSPError, NULL);
|
379
383
|
str = rb_str_new(0, len);
|
380
|
-
p = RSTRING_PTR(str);
|
384
|
+
p = (unsigned char *)RSTRING_PTR(str);
|
381
385
|
if(i2d_OCSP_RESPONSE(res, &p) <= 0)
|
382
386
|
ossl_raise(eOCSPError, NULL);
|
383
387
|
ossl_str_adjust(str, p);
|
@@ -436,7 +440,7 @@ ossl_ocspbres_add_nonce(int argc, VALUE *argv, VALUE self)
|
|
436
440
|
else{
|
437
441
|
StringValue(val);
|
438
442
|
GetOCSPBasicRes(self, bs);
|
439
|
-
ret = OCSP_basic_add1_nonce(bs, RSTRING_PTR(val),
|
443
|
+
ret = OCSP_basic_add1_nonce(bs, (unsigned char *)RSTRING_PTR(val), RSTRING_LENINT(val));
|
440
444
|
}
|
441
445
|
if(!ret) ossl_raise(eOCSPError, NULL);
|
442
446
|
|
@@ -554,7 +558,7 @@ ossl_ocspbres_get_status(VALUE self)
|
|
554
558
|
}
|
555
559
|
|
556
560
|
return ret;
|
557
|
-
}
|
561
|
+
}
|
558
562
|
|
559
563
|
static VALUE
|
560
564
|
ossl_ocspbres_sign(int argc, VALUE *argv, VALUE self)
|
@@ -597,7 +601,7 @@ ossl_ocspbres_verify(int argc, VALUE *argv, VALUE self)
|
|
597
601
|
|
598
602
|
rb_scan_args(argc, argv, "21", &certs, &store, &flags);
|
599
603
|
x509st = GetX509StorePtr(store);
|
600
|
-
flg = NIL_P(flags) ? 0 :
|
604
|
+
flg = NIL_P(flags) ? 0 : NUM2INT(flags);
|
601
605
|
x509s = ossl_x509_ary2sk(certs);
|
602
606
|
GetOCSPBasicRes(self, bs);
|
603
607
|
result = OCSP_basic_verify(bs, x509s, x509st, flg) > 0 ? Qtrue : Qfalse;
|
@@ -624,14 +628,27 @@ ossl_ocspcid_alloc(VALUE klass)
|
|
624
628
|
}
|
625
629
|
|
626
630
|
static VALUE
|
627
|
-
ossl_ocspcid_initialize(
|
631
|
+
ossl_ocspcid_initialize(int argc, VALUE *argv, VALUE self)
|
628
632
|
{
|
629
633
|
OCSP_CERTID *id, *newid;
|
630
634
|
X509 *x509s, *x509i;
|
635
|
+
VALUE subject, issuer, digest;
|
636
|
+
const EVP_MD *md;
|
637
|
+
|
638
|
+
if (rb_scan_args(argc, argv, "21", &subject, &issuer, &digest) == 0) {
|
639
|
+
return self;
|
640
|
+
}
|
631
641
|
|
632
642
|
x509s = GetX509CertPtr(subject); /* NO NEED TO DUP */
|
633
643
|
x509i = GetX509CertPtr(issuer); /* NO NEED TO DUP */
|
634
|
-
|
644
|
+
|
645
|
+
if (!NIL_P(digest)) {
|
646
|
+
md = GetDigestPtr(digest);
|
647
|
+
newid = OCSP_cert_to_id(md, x509s, x509i);
|
648
|
+
} else {
|
649
|
+
newid = OCSP_cert_to_id(NULL, x509s, x509i);
|
650
|
+
}
|
651
|
+
if(!newid)
|
635
652
|
ossl_raise(eOCSPError, NULL);
|
636
653
|
GetOCSPCertId(self, id);
|
637
654
|
OCSP_CERTID_free(id);
|
@@ -715,7 +732,7 @@ Init_ossl_ocsp()
|
|
715
732
|
|
716
733
|
cOCSPCertId = rb_define_class_under(mOCSP, "CertificateId", rb_cObject);
|
717
734
|
rb_define_alloc_func(cOCSPCertId, ossl_ocspcid_alloc);
|
718
|
-
rb_define_method(cOCSPCertId, "initialize", ossl_ocspcid_initialize,
|
735
|
+
rb_define_method(cOCSPCertId, "initialize", ossl_ocspcid_initialize, -1);
|
719
736
|
rb_define_method(cOCSPCertId, "cmp", ossl_ocspcid_cmp, 1);
|
720
737
|
rb_define_method(cOCSPCertId, "cmp_issuer", ossl_ocspcid_cmp_issuer, 1);
|
721
738
|
rb_define_method(cOCSPCertId, "serial", ossl_ocspcid_get_serial, 0);
|
@@ -1,23 +1,23 @@
|
|
1
1
|
/*
|
2
2
|
* This program is licenced under the same licence as Ruby.
|
3
3
|
* (See the file 'LICENCE'.)
|
4
|
-
* $Id
|
4
|
+
* $Id$
|
5
5
|
*/
|
6
6
|
#include "ossl.h"
|
7
7
|
|
8
8
|
#define WrapPKCS12(klass, obj, p12) do { \
|
9
|
-
if(!p12) ossl_raise(rb_eRuntimeError, "PKCS12 wasn't initialized."); \
|
10
|
-
obj = Data_Wrap_Struct(klass, 0, PKCS12_free, p12); \
|
9
|
+
if(!(p12)) ossl_raise(rb_eRuntimeError, "PKCS12 wasn't initialized."); \
|
10
|
+
(obj) = Data_Wrap_Struct((klass), 0, PKCS12_free, (p12)); \
|
11
11
|
} while (0)
|
12
12
|
|
13
13
|
#define GetPKCS12(obj, p12) do { \
|
14
|
-
Data_Get_Struct(obj, PKCS12, p12); \
|
15
|
-
if(!p12) ossl_raise(rb_eRuntimeError, "PKCS12 wasn't initialized."); \
|
14
|
+
Data_Get_Struct((obj), PKCS12, (p12)); \
|
15
|
+
if(!(p12)) ossl_raise(rb_eRuntimeError, "PKCS12 wasn't initialized."); \
|
16
16
|
} while (0)
|
17
17
|
|
18
18
|
#define SafeGetPKCS12(obj, p12) do { \
|
19
|
-
OSSL_Check_Kind(obj, cPKCS12); \
|
20
|
-
GetPKCS12(obj, p12); \
|
19
|
+
OSSL_Check_Kind((obj), cPKCS12); \
|
20
|
+
GetPKCS12((obj), (p12)); \
|
21
21
|
} while (0)
|
22
22
|
|
23
23
|
#define ossl_pkcs12_set_key(o,v) rb_iv_set((o), "@key", (v))
|
@@ -81,7 +81,7 @@ ossl_pkcs12_s_create(int argc, VALUE *argv, VALUE self)
|
|
81
81
|
STACK_OF(X509) *x509s;
|
82
82
|
int nkey = 0, ncert = 0, kiter = 0, miter = 0, ktype = 0;
|
83
83
|
PKCS12 *p12;
|
84
|
-
|
84
|
+
|
85
85
|
rb_scan_args(argc, argv, "46", &pass, &name, &pkey, &cert, &ca, &key_nid, &cert_nid, &key_iter, &mac_iter, &keytype);
|
86
86
|
passphrase = NIL_P(pass) ? NULL : StringValuePtr(pass);
|
87
87
|
friendlyname = NIL_P(name) ? NULL : StringValuePtr(name);
|
@@ -91,11 +91,11 @@ ossl_pkcs12_s_create(int argc, VALUE *argv, VALUE self)
|
|
91
91
|
/* TODO: make a VALUE to nid function */
|
92
92
|
if (!NIL_P(key_nid)) {
|
93
93
|
if ((nkey = OBJ_txt2nid(StringValuePtr(key_nid))) == NID_undef)
|
94
|
-
|
94
|
+
ossl_raise(rb_eArgError, "Unknown PBE algorithm %s", StringValuePtr(key_nid));
|
95
95
|
}
|
96
96
|
if (!NIL_P(cert_nid)) {
|
97
97
|
if ((ncert = OBJ_txt2nid(StringValuePtr(cert_nid))) == NID_undef)
|
98
|
-
|
98
|
+
ossl_raise(rb_eArgError, "Unknown PBE algorithm %s", StringValuePtr(cert_nid));
|
99
99
|
}
|
100
100
|
if (!NIL_P(key_iter))
|
101
101
|
kiter = NUM2INT(key_iter);
|
@@ -137,15 +137,17 @@ ossl_pkcs12_initialize(int argc, VALUE *argv, VALUE self)
|
|
137
137
|
X509 *x509;
|
138
138
|
STACK_OF(X509) *x509s = NULL;
|
139
139
|
int st = 0;
|
140
|
+
PKCS12 *pkcs = DATA_PTR(self);
|
140
141
|
|
141
142
|
if(rb_scan_args(argc, argv, "02", &arg, &pass) == 0) return self;
|
142
143
|
passphrase = NIL_P(pass) ? NULL : StringValuePtr(pass);
|
143
144
|
in = ossl_obj2bio(arg);
|
144
|
-
d2i_PKCS12_bio(in,
|
145
|
+
d2i_PKCS12_bio(in, &pkcs);
|
146
|
+
DATA_PTR(self) = pkcs;
|
145
147
|
BIO_free(in);
|
146
148
|
|
147
149
|
pkey = cert = ca = Qnil;
|
148
|
-
if(!PKCS12_parse(
|
150
|
+
if(!PKCS12_parse(pkcs, passphrase, &key, &x509, &x509s))
|
149
151
|
ossl_raise(ePKCS12Error, "PKCS12_parse");
|
150
152
|
pkey = rb_protect((VALUE(*)_((VALUE)))ossl_pkey_new, (VALUE)key,
|
151
153
|
&st); /* NO DUP */
|
@@ -181,7 +183,7 @@ ossl_pkcs12_to_der(VALUE self)
|
|
181
183
|
if((len = i2d_PKCS12(p12, NULL)) <= 0)
|
182
184
|
ossl_raise(ePKCS12Error, NULL);
|
183
185
|
str = rb_str_new(0, len);
|
184
|
-
p = RSTRING_PTR(str);
|
186
|
+
p = (unsigned char *)RSTRING_PTR(str);
|
185
187
|
if(i2d_PKCS12(p12, &p) <= 0)
|
186
188
|
ossl_raise(ePKCS12Error, NULL);
|
187
189
|
ossl_str_adjust(str, p);
|
@@ -7,66 +7,66 @@
|
|
7
7
|
VALUE mPKCS5;
|
8
8
|
VALUE ePKCS5;
|
9
9
|
|
10
|
+
#ifdef HAVE_PKCS5_PBKDF2_HMAC
|
10
11
|
/*
|
11
12
|
* call-seq:
|
12
13
|
* PKCS5.pbkdf2_hmac(pass, salt, iter, keylen, digest) => string
|
13
14
|
*
|
14
15
|
* === Parameters
|
15
16
|
* * +pass+ - string
|
16
|
-
* * +salt+ - string
|
17
|
-
* * +iter+ - integer - should be greater than 1000.
|
17
|
+
* * +salt+ - string - should be at least 8 bytes long.
|
18
|
+
* * +iter+ - integer - should be greater than 1000. 20000 is better.
|
18
19
|
* * +keylen+ - integer
|
19
20
|
* * +digest+ - a string or OpenSSL::Digest object.
|
20
21
|
*
|
21
|
-
* Available in OpenSSL 0.9.
|
22
|
+
* Available in OpenSSL 0.9.4.
|
22
23
|
*
|
23
24
|
* Digests other than SHA1 may not be supported by other cryptography libraries.
|
24
25
|
*/
|
25
26
|
static VALUE
|
26
27
|
ossl_pkcs5_pbkdf2_hmac(VALUE self, VALUE pass, VALUE salt, VALUE iter, VALUE keylen, VALUE digest)
|
27
28
|
{
|
28
|
-
#ifdef HAVE_PKCS5_PBKDF2_HMAC
|
29
29
|
VALUE str;
|
30
30
|
const EVP_MD *md;
|
31
31
|
int len = NUM2INT(keylen);
|
32
|
-
unsigned char* salt_p;
|
33
|
-
unsigned char* str_p;
|
34
32
|
|
35
33
|
StringValue(pass);
|
36
34
|
StringValue(salt);
|
37
35
|
md = GetDigestPtr(digest);
|
36
|
+
|
38
37
|
str = rb_str_new(0, len);
|
39
|
-
salt_p = (unsigned char*)RSTRING_PTR(salt);
|
40
|
-
str_p = (unsigned char*)RSTRING_PTR(str);
|
41
38
|
|
42
|
-
if (PKCS5_PBKDF2_HMAC(RSTRING_PTR(pass),
|
39
|
+
if (PKCS5_PBKDF2_HMAC(RSTRING_PTR(pass), RSTRING_LENINT(pass),
|
40
|
+
(unsigned char *)RSTRING_PTR(salt), RSTRING_LENINT(salt),
|
41
|
+
NUM2INT(iter), md, len,
|
42
|
+
(unsigned char *)RSTRING_PTR(str)) != 1)
|
43
43
|
ossl_raise(ePKCS5, "PKCS5_PBKDF2_HMAC");
|
44
44
|
|
45
45
|
return str;
|
46
|
+
}
|
46
47
|
#else
|
47
|
-
|
48
|
+
#define ossl_pkcs5_pbkdf2_hmac rb_f_notimplement
|
48
49
|
#endif
|
49
|
-
}
|
50
50
|
|
51
51
|
|
52
|
+
#ifdef HAVE_PKCS5_PBKDF2_HMAC_SHA1
|
52
53
|
/*
|
53
54
|
* call-seq:
|
54
55
|
* PKCS5.pbkdf2_hmac_sha1(pass, salt, iter, keylen) => string
|
55
56
|
*
|
56
57
|
* === Parameters
|
57
58
|
* * +pass+ - string
|
58
|
-
* * +salt+ - string
|
59
|
-
* * +iter+ - integer - should be greater than 1000.
|
59
|
+
* * +salt+ - string - should be at least 8 bytes long.
|
60
|
+
* * +iter+ - integer - should be greater than 1000. 20000 is better.
|
60
61
|
* * +keylen+ - integer
|
61
62
|
*
|
62
|
-
* This method is available almost any version OpenSSL.
|
63
|
+
* This method is available in almost any version of OpenSSL.
|
63
64
|
*
|
64
65
|
* Conforms to rfc2898.
|
65
66
|
*/
|
66
67
|
static VALUE
|
67
68
|
ossl_pkcs5_pbkdf2_hmac_sha1(VALUE self, VALUE pass, VALUE salt, VALUE iter, VALUE keylen)
|
68
69
|
{
|
69
|
-
#ifdef HAVE_PKCS5_PBKDF2_HMAC_SHA1
|
70
70
|
VALUE str;
|
71
71
|
int len = NUM2INT(keylen);
|
72
72
|
|
@@ -75,14 +75,16 @@ ossl_pkcs5_pbkdf2_hmac_sha1(VALUE self, VALUE pass, VALUE salt, VALUE iter, VALU
|
|
75
75
|
|
76
76
|
str = rb_str_new(0, len);
|
77
77
|
|
78
|
-
if (PKCS5_PBKDF2_HMAC_SHA1(RSTRING_PTR(pass),
|
78
|
+
if (PKCS5_PBKDF2_HMAC_SHA1(RSTRING_PTR(pass), RSTRING_LENINT(pass),
|
79
|
+
(const unsigned char *)RSTRING_PTR(salt), RSTRING_LENINT(salt), NUM2INT(iter),
|
80
|
+
len, (unsigned char *)RSTRING_PTR(str)) != 1)
|
79
81
|
ossl_raise(ePKCS5, "PKCS5_PBKDF2_HMAC_SHA1");
|
80
82
|
|
81
83
|
return str;
|
84
|
+
}
|
82
85
|
#else
|
83
|
-
|
86
|
+
#define ossl_pkcs5_pbkdf2_hmac_sha1 rb_f_notimplement
|
84
87
|
#endif
|
85
|
-
}
|
86
88
|
|
87
89
|
void
|
88
90
|
Init_ossl_pkcs5()
|
@@ -91,7 +93,95 @@ Init_ossl_pkcs5()
|
|
91
93
|
* Password-based Encryption
|
92
94
|
*
|
93
95
|
*/
|
96
|
+
|
97
|
+
#if 0
|
98
|
+
mOSSL = rb_define_module("OpenSSL"); /* let rdoc know about mOSSL */
|
99
|
+
#endif
|
100
|
+
|
101
|
+
/* Document-class: OpenSSL::PKCS5
|
102
|
+
*
|
103
|
+
* Provides password-based encryption functionality based on PKCS#5.
|
104
|
+
* Typically used for securely deriving arbitrary length symmetric keys
|
105
|
+
* to be used with an OpenSSL::Cipher from passwords. Another use case
|
106
|
+
* is for storing passwords: Due to the ability to tweak the effort of
|
107
|
+
* computation by increasing the iteration count, computation can be
|
108
|
+
* slowed down artificially in order to render possible attacks infeasible.
|
109
|
+
*
|
110
|
+
* PKCS5 offers support for PBKDF2 with an OpenSSL::Digest::SHA1-based
|
111
|
+
* HMAC, or an arbitrary Digest if the underlying version of OpenSSL
|
112
|
+
* already supports it (>= 0.9.4).
|
113
|
+
*
|
114
|
+
* === Parameters
|
115
|
+
* ==== Password
|
116
|
+
* Typically an arbitrary String that represents the password to be used
|
117
|
+
* for deriving a key.
|
118
|
+
* ==== Salt
|
119
|
+
* Prevents attacks based on dictionaries of common passwords. It is a
|
120
|
+
* public value that can be safely stored along with the password (e.g.
|
121
|
+
* if PBKDF2 is used for password storage). For maximum security, a fresh,
|
122
|
+
* random salt should be generated for each stored password. According
|
123
|
+
* to PKCS#5, a salt should be at least 8 bytes long.
|
124
|
+
* ==== Iteration Count
|
125
|
+
* Allows to tweak the length that the actual computation will take. The
|
126
|
+
* larger the iteration count, the longer it will take.
|
127
|
+
* ==== Key Length
|
128
|
+
* Specifies the length in bytes of the output that will be generated.
|
129
|
+
* Typically, the key length should be larger than or equal to the output
|
130
|
+
* length of the underlying digest function, otherwise an attacker could
|
131
|
+
* simply try to brute-force the key. According to PKCS#5, security is
|
132
|
+
* limited by the output length of the underlying digest function, i.e.
|
133
|
+
* security is not improved if a key length strictly larger than the
|
134
|
+
* digest output length is chosen. Therefore, when using PKCS5 for
|
135
|
+
* password storage, it suffices to store values equal to the digest
|
136
|
+
* output length, nothing is gained by storing larger values.
|
137
|
+
*
|
138
|
+
* == Examples
|
139
|
+
* === Generating a 128 bit key for a Cipher (e.g. AES)
|
140
|
+
* pass = "secret"
|
141
|
+
* salt = OpenSSL::Random.random_bytes(16)
|
142
|
+
* iter = 20000
|
143
|
+
* key_len = 16
|
144
|
+
* key = OpenSSL::PKCS5.pbkdf2_hmac_sha1(pass, salt, iter, key_len)
|
145
|
+
*
|
146
|
+
* === Storing Passwords
|
147
|
+
* pass = "secret"
|
148
|
+
* salt = OpenSSL::Random.random_bytes(16) #store this with the generated value
|
149
|
+
* iter = 20000
|
150
|
+
* digest = OpenSSL::Digest::SHA256.new
|
151
|
+
* len = digest.digest_length
|
152
|
+
* #the final value to be stored
|
153
|
+
* value = OpenSSL::PKCS5.pbkdf2_hmac(pass, salt, iter, len, digest)
|
154
|
+
*
|
155
|
+
* === Important Note on Checking Passwords
|
156
|
+
* When comparing passwords provided by the user with previously stored
|
157
|
+
* values, a common mistake made is comparing the two values using "==".
|
158
|
+
* Typically, "==" short-circuits on evaluation, and is therefore
|
159
|
+
* vulnerable to timing attacks. The proper way is to use a method that
|
160
|
+
* always takes the same amount of time when comparing two values, thus
|
161
|
+
* not leaking any information to potential attackers. To compare two
|
162
|
+
* values, the following could be used:
|
163
|
+
* def eql_time_cmp(a, b)
|
164
|
+
* unless a.length == b.length
|
165
|
+
* return false
|
166
|
+
* end
|
167
|
+
* cmp = b.bytes.to_a
|
168
|
+
* result = 0
|
169
|
+
* a.bytes.each_with_index {|c,i|
|
170
|
+
* result |= c ^ cmp[i]
|
171
|
+
* }
|
172
|
+
* result == 0
|
173
|
+
* end
|
174
|
+
* Please note that the premature return in case of differing lengths
|
175
|
+
* typically does not leak valuable information - when using PKCS#5, the
|
176
|
+
* length of the values to be compared is of fixed size.
|
177
|
+
*/
|
178
|
+
|
94
179
|
mPKCS5 = rb_define_module_under(mOSSL, "PKCS5");
|
180
|
+
/* Document-class: OpenSSL::PKCS5::PKCS5Error
|
181
|
+
*
|
182
|
+
* Generic Exception class that is raised if an error occurs during a
|
183
|
+
* computation.
|
184
|
+
*/
|
95
185
|
ePKCS5 = rb_define_class_under(mPKCS5, "PKCS5Error", eOSSLError);
|
96
186
|
|
97
187
|
rb_define_module_function(mPKCS5, "pbkdf2_hmac", ossl_pkcs5_pbkdf2_hmac, 5);
|