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.
Files changed (74) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +5 -6
  3. data/ext/rubysl/openssl/.gitignore +3 -0
  4. data/ext/rubysl/openssl/deprecation.rb +21 -0
  5. data/ext/rubysl/openssl/extconf.rb +45 -32
  6. data/ext/rubysl/openssl/openssl_missing.c +20 -7
  7. data/ext/rubysl/openssl/openssl_missing.h +22 -15
  8. data/ext/rubysl/openssl/ossl.c +610 -61
  9. data/ext/rubysl/openssl/ossl.h +31 -17
  10. data/ext/rubysl/openssl/ossl_asn1.c +974 -183
  11. data/ext/rubysl/openssl/ossl_asn1.h +3 -3
  12. data/ext/rubysl/openssl/ossl_bio.c +4 -3
  13. data/ext/rubysl/openssl/ossl_bio.h +1 -1
  14. data/ext/rubysl/openssl/ossl_bn.c +32 -28
  15. data/ext/rubysl/openssl/ossl_bn.h +1 -1
  16. data/ext/rubysl/openssl/ossl_cipher.c +494 -93
  17. data/ext/rubysl/openssl/ossl_cipher.h +1 -1
  18. data/ext/rubysl/openssl/ossl_config.c +4 -5
  19. data/ext/rubysl/openssl/ossl_config.h +1 -1
  20. data/ext/rubysl/openssl/ossl_digest.c +206 -24
  21. data/ext/rubysl/openssl/ossl_digest.h +1 -1
  22. data/ext/rubysl/openssl/ossl_engine.c +48 -26
  23. data/ext/rubysl/openssl/ossl_engine.h +1 -1
  24. data/ext/rubysl/openssl/ossl_hmac.c +40 -38
  25. data/ext/rubysl/openssl/ossl_hmac.h +1 -1
  26. data/ext/rubysl/openssl/ossl_ns_spki.c +157 -25
  27. data/ext/rubysl/openssl/ossl_ns_spki.h +1 -1
  28. data/ext/rubysl/openssl/ossl_ocsp.c +57 -40
  29. data/ext/rubysl/openssl/ossl_ocsp.h +1 -1
  30. data/ext/rubysl/openssl/ossl_pkcs12.c +15 -13
  31. data/ext/rubysl/openssl/ossl_pkcs12.h +1 -1
  32. data/ext/rubysl/openssl/ossl_pkcs5.c +108 -18
  33. data/ext/rubysl/openssl/ossl_pkcs7.c +44 -37
  34. data/ext/rubysl/openssl/ossl_pkcs7.h +1 -1
  35. data/ext/rubysl/openssl/ossl_pkey.c +211 -15
  36. data/ext/rubysl/openssl/ossl_pkey.h +19 -9
  37. data/ext/rubysl/openssl/ossl_pkey_dh.c +180 -47
  38. data/ext/rubysl/openssl/ossl_pkey_dsa.c +184 -47
  39. data/ext/rubysl/openssl/ossl_pkey_ec.c +177 -93
  40. data/ext/rubysl/openssl/ossl_pkey_rsa.c +209 -102
  41. data/ext/rubysl/openssl/ossl_rand.c +15 -15
  42. data/ext/rubysl/openssl/ossl_rand.h +1 -1
  43. data/ext/rubysl/openssl/ossl_ssl.c +939 -192
  44. data/ext/rubysl/openssl/ossl_ssl.h +6 -6
  45. data/ext/rubysl/openssl/ossl_ssl_session.c +78 -62
  46. data/ext/rubysl/openssl/ossl_version.h +2 -2
  47. data/ext/rubysl/openssl/ossl_x509.c +1 -1
  48. data/ext/rubysl/openssl/ossl_x509.h +1 -1
  49. data/ext/rubysl/openssl/ossl_x509attr.c +20 -19
  50. data/ext/rubysl/openssl/ossl_x509cert.c +169 -67
  51. data/ext/rubysl/openssl/ossl_x509crl.c +41 -39
  52. data/ext/rubysl/openssl/ossl_x509ext.c +51 -38
  53. data/ext/rubysl/openssl/ossl_x509name.c +139 -29
  54. data/ext/rubysl/openssl/ossl_x509req.c +42 -40
  55. data/ext/rubysl/openssl/ossl_x509revoked.c +20 -20
  56. data/ext/rubysl/openssl/ossl_x509store.c +99 -47
  57. data/ext/rubysl/openssl/ruby_missing.h +3 -16
  58. data/lib/openssl/bn.rb +19 -19
  59. data/lib/openssl/buffering.rb +222 -14
  60. data/lib/openssl/cipher.rb +20 -20
  61. data/lib/openssl/config.rb +1 -4
  62. data/lib/openssl/digest.rb +47 -19
  63. data/lib/openssl/ssl.rb +197 -1
  64. data/lib/openssl/x509.rb +162 -1
  65. data/lib/rubysl/openssl.rb +4 -8
  66. data/lib/rubysl/openssl/version.rb +1 -1
  67. data/rubysl-openssl.gemspec +1 -2
  68. metadata +16 -34
  69. data/ext/rubysl/openssl/extconf.h +0 -50
  70. data/lib/openssl/net/ftptls.rb +0 -53
  71. data/lib/openssl/net/telnets.rb +0 -251
  72. data/lib/openssl/pkcs7.rb +0 -25
  73. data/lib/openssl/ssl-internal.rb +0 -187
  74. data/lib/openssl/x509-internal.rb +0 -153
@@ -1,5 +1,5 @@
1
1
  /*
2
- * $Id: ossl_ns_spki.h 11708 2007-02-12 23:01:19Z shyouhei $
2
+ * $Id$
3
3
  * 'OpenSSL for Ruby' project
4
4
  * Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz>
5
5
  * All rights reserved.
@@ -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 = (const unsigned char*)RSTRING_PTR(arg);
113
- if(!d2i_OCSP_REQUEST((OCSP_REQUEST**)&DATA_PTR(self), &p,
114
- RSTRING_LEN(arg))){
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), RSTRING_LEN(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 : INT2NUM(flags);
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 = (const unsigned char*) RSTRING_PTR(arg);
320
- if(!d2i_OCSP_RESPONSE((OCSP_RESPONSE**)&DATA_PTR(self), &p,
321
- RSTRING_LEN(arg))){
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), RSTRING_LEN(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 : INT2NUM(flags);
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(VALUE self, VALUE subject, VALUE issuer)
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
- if(!(newid = OCSP_cert_to_id(NULL, x509s, x509i)))
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, 2);
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,5 +1,5 @@
1
1
  /*
2
- * $Id: ossl_ocsp.h 11708 2007-02-12 23:01:19Z shyouhei $
2
+ * $Id$
3
3
  * 'OpenSSL for Ruby' project
4
4
  * Copyright (C) 2003 Michal Rokos <m.rokos@sh.cvut.cz>
5
5
  * Copyright (C) 2003 GOTOU Yuuzou <gotoyuzo@notwork.org>
@@ -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: ossl_pkcs12.c 12496 2007-06-08 15:02:04Z technorama $
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
- rb_raise(rb_eArgError, "Unknown PBE algorithm %s", StringValuePtr(key_nid));
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
- rb_raise(rb_eArgError, "Unknown PBE algorithm %s", StringValuePtr(cert_nid));
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, (PKCS12 **)&DATA_PTR(self));
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((PKCS12*)DATA_PTR(self), passphrase, &key, &x509, &x509s))
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);
@@ -1,7 +1,7 @@
1
1
  /*
2
2
  * This program is licenced under the same licence as Ruby.
3
3
  * (See the file 'LICENCE'.)
4
- * $Id: ossl_pkcs12.h 12496 2007-06-08 15:02:04Z technorama $
4
+ * $Id$
5
5
  */
6
6
  #if !defined(_OSSL_PKCS12_H_)
7
7
  #define _OSSL_PKCS12_H_
@@ -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. 2000 is better.
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.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), RSTRING_LEN(pass), salt_p, RSTRING_LEN(salt), NUM2INT(iter), md, len, str_p) != 1)
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
- rb_notimplement();
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. 2000 is better.
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), RSTRING_LEN(pass), RSTRING_PTR(salt), RSTRING_LEN(salt), NUM2INT(iter), len, RSTRING_PTR(str)) != 1)
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
- rb_notimplement();
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);