rubysl-openssl 1.0.2 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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);
|