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