openssl 2.0.0.beta.1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of openssl might be problematic. Click here for more details.

Files changed (71) hide show
  1. checksums.yaml +7 -0
  2. data/BSDL +22 -0
  3. data/CONTRIBUTING.md +130 -0
  4. data/History.md +118 -0
  5. data/LICENSE.txt +56 -0
  6. data/README.md +70 -0
  7. data/ext/openssl/deprecation.rb +26 -0
  8. data/ext/openssl/extconf.rb +158 -0
  9. data/ext/openssl/openssl_missing.c +173 -0
  10. data/ext/openssl/openssl_missing.h +244 -0
  11. data/ext/openssl/ossl.c +1201 -0
  12. data/ext/openssl/ossl.h +222 -0
  13. data/ext/openssl/ossl_asn1.c +1992 -0
  14. data/ext/openssl/ossl_asn1.h +66 -0
  15. data/ext/openssl/ossl_bio.c +87 -0
  16. data/ext/openssl/ossl_bio.h +19 -0
  17. data/ext/openssl/ossl_bn.c +1153 -0
  18. data/ext/openssl/ossl_bn.h +23 -0
  19. data/ext/openssl/ossl_cipher.c +1085 -0
  20. data/ext/openssl/ossl_cipher.h +20 -0
  21. data/ext/openssl/ossl_config.c +89 -0
  22. data/ext/openssl/ossl_config.h +19 -0
  23. data/ext/openssl/ossl_digest.c +453 -0
  24. data/ext/openssl/ossl_digest.h +20 -0
  25. data/ext/openssl/ossl_engine.c +580 -0
  26. data/ext/openssl/ossl_engine.h +19 -0
  27. data/ext/openssl/ossl_hmac.c +398 -0
  28. data/ext/openssl/ossl_hmac.h +18 -0
  29. data/ext/openssl/ossl_ns_spki.c +406 -0
  30. data/ext/openssl/ossl_ns_spki.h +19 -0
  31. data/ext/openssl/ossl_ocsp.c +2013 -0
  32. data/ext/openssl/ossl_ocsp.h +23 -0
  33. data/ext/openssl/ossl_pkcs12.c +259 -0
  34. data/ext/openssl/ossl_pkcs12.h +13 -0
  35. data/ext/openssl/ossl_pkcs5.c +180 -0
  36. data/ext/openssl/ossl_pkcs5.h +6 -0
  37. data/ext/openssl/ossl_pkcs7.c +1125 -0
  38. data/ext/openssl/ossl_pkcs7.h +20 -0
  39. data/ext/openssl/ossl_pkey.c +435 -0
  40. data/ext/openssl/ossl_pkey.h +245 -0
  41. data/ext/openssl/ossl_pkey_dh.c +650 -0
  42. data/ext/openssl/ossl_pkey_dsa.c +672 -0
  43. data/ext/openssl/ossl_pkey_ec.c +1899 -0
  44. data/ext/openssl/ossl_pkey_rsa.c +768 -0
  45. data/ext/openssl/ossl_rand.c +238 -0
  46. data/ext/openssl/ossl_rand.h +18 -0
  47. data/ext/openssl/ossl_ssl.c +2679 -0
  48. data/ext/openssl/ossl_ssl.h +41 -0
  49. data/ext/openssl/ossl_ssl_session.c +352 -0
  50. data/ext/openssl/ossl_version.h +15 -0
  51. data/ext/openssl/ossl_x509.c +186 -0
  52. data/ext/openssl/ossl_x509.h +119 -0
  53. data/ext/openssl/ossl_x509attr.c +328 -0
  54. data/ext/openssl/ossl_x509cert.c +860 -0
  55. data/ext/openssl/ossl_x509crl.c +565 -0
  56. data/ext/openssl/ossl_x509ext.c +480 -0
  57. data/ext/openssl/ossl_x509name.c +547 -0
  58. data/ext/openssl/ossl_x509req.c +492 -0
  59. data/ext/openssl/ossl_x509revoked.c +279 -0
  60. data/ext/openssl/ossl_x509store.c +846 -0
  61. data/ext/openssl/ruby_missing.h +32 -0
  62. data/lib/openssl.rb +21 -0
  63. data/lib/openssl/bn.rb +39 -0
  64. data/lib/openssl/buffering.rb +451 -0
  65. data/lib/openssl/cipher.rb +67 -0
  66. data/lib/openssl/config.rb +473 -0
  67. data/lib/openssl/digest.rb +78 -0
  68. data/lib/openssl/pkey.rb +44 -0
  69. data/lib/openssl/ssl.rb +416 -0
  70. data/lib/openssl/x509.rb +176 -0
  71. metadata +178 -0
@@ -0,0 +1,23 @@
1
+ /*
2
+ * 'OpenSSL for Ruby' project
3
+ * Copyright (C) 2003 Michal Rokos <m.rokos@sh.cvut.cz>
4
+ * Copyright (C) 2003 GOTOU Yuuzou <gotoyuzo@notwork.org>
5
+ * All rights reserved.
6
+ */
7
+ /*
8
+ * This program is licensed under the same licence as Ruby.
9
+ * (See the file 'LICENCE'.)
10
+ */
11
+ #if !defined(_OSSL_OCSP_H_)
12
+ #define _OSSL_OCSP_H_
13
+
14
+ #if !defined(OPENSSL_NO_OCSP)
15
+ extern VALUE mOCSP;
16
+ extern VALUE cOPCSReq;
17
+ extern VALUE cOPCSRes;
18
+ extern VALUE cOPCSBasicRes;
19
+ #endif
20
+
21
+ void Init_ossl_ocsp(void);
22
+
23
+ #endif /* _OSSL_OCSP_H_ */
@@ -0,0 +1,259 @@
1
+ /*
2
+ * This program is licensed under the same licence as Ruby.
3
+ * (See the file 'LICENCE'.)
4
+ */
5
+ #include "ossl.h"
6
+
7
+ #define NewPKCS12(klass) \
8
+ TypedData_Wrap_Struct((klass), &ossl_pkcs12_type, 0)
9
+
10
+ #define SetPKCS12(obj, p12) do { \
11
+ if(!(p12)) ossl_raise(rb_eRuntimeError, "PKCS12 wasn't initialized."); \
12
+ RTYPEDDATA_DATA(obj) = (p12); \
13
+ } while (0)
14
+
15
+ #define GetPKCS12(obj, p12) do { \
16
+ TypedData_Get_Struct((obj), PKCS12, &ossl_pkcs12_type, (p12)); \
17
+ if(!(p12)) ossl_raise(rb_eRuntimeError, "PKCS12 wasn't initialized."); \
18
+ } while (0)
19
+
20
+ #define SafeGetPKCS12(obj, p12) do { \
21
+ OSSL_Check_Kind((obj), cPKCS12); \
22
+ GetPKCS12((obj), (p12)); \
23
+ } while (0)
24
+
25
+ #define ossl_pkcs12_set_key(o,v) rb_iv_set((o), "@key", (v))
26
+ #define ossl_pkcs12_set_cert(o,v) rb_iv_set((o), "@certificate", (v))
27
+ #define ossl_pkcs12_set_ca_certs(o,v) rb_iv_set((o), "@ca_certs", (v))
28
+ #define ossl_pkcs12_get_key(o) rb_iv_get((o), "@key")
29
+ #define ossl_pkcs12_get_cert(o) rb_iv_get((o), "@certificate")
30
+ #define ossl_pkcs12_get_ca_certs(o) rb_iv_get((o), "@ca_certs")
31
+
32
+ /*
33
+ * Classes
34
+ */
35
+ VALUE cPKCS12;
36
+ VALUE ePKCS12Error;
37
+
38
+ /*
39
+ * Private
40
+ */
41
+ static void
42
+ ossl_pkcs12_free(void *ptr)
43
+ {
44
+ PKCS12_free(ptr);
45
+ }
46
+
47
+ static const rb_data_type_t ossl_pkcs12_type = {
48
+ "OpenSSL/PKCS12",
49
+ {
50
+ 0, ossl_pkcs12_free,
51
+ },
52
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
53
+ };
54
+
55
+ static VALUE
56
+ ossl_pkcs12_s_allocate(VALUE klass)
57
+ {
58
+ PKCS12 *p12;
59
+ VALUE obj;
60
+
61
+ obj = NewPKCS12(klass);
62
+ if(!(p12 = PKCS12_new())) ossl_raise(ePKCS12Error, NULL);
63
+ SetPKCS12(obj, p12);
64
+
65
+ return obj;
66
+ }
67
+
68
+ static VALUE
69
+ ossl_pkcs12_initialize_copy(VALUE self, VALUE other)
70
+ {
71
+ PKCS12 *p12, *p12_old, *p12_new;
72
+
73
+ rb_check_frozen(self);
74
+ GetPKCS12(self, p12_old);
75
+ SafeGetPKCS12(other, p12);
76
+
77
+ p12_new = ASN1_dup((i2d_of_void *)i2d_PKCS12, (d2i_of_void *)d2i_PKCS12, (char *)p12);
78
+ if (!p12_new)
79
+ ossl_raise(ePKCS12Error, "ASN1_dup");
80
+
81
+ SetPKCS12(self, p12_new);
82
+ PKCS12_free(p12_old);
83
+
84
+ return self;
85
+ }
86
+
87
+ /*
88
+ * call-seq:
89
+ * PKCS12.create(pass, name, key, cert [, ca, [, key_pbe [, cert_pbe [, key_iter [, mac_iter [, keytype]]]]]])
90
+ *
91
+ * === Parameters
92
+ * * +pass+ - string
93
+ * * +name+ - A string describing the key.
94
+ * * +key+ - Any PKey.
95
+ * * +cert+ - A X509::Certificate.
96
+ * * The public_key portion of the certificate must contain a valid public key.
97
+ * * The not_before and not_after fields must be filled in.
98
+ * * +ca+ - An optional array of X509::Certificate's.
99
+ * * +key_pbe+ - string
100
+ * * +cert_pbe+ - string
101
+ * * +key_iter+ - integer
102
+ * * +mac_iter+ - integer
103
+ * * +keytype+ - An integer representing an MSIE specific extension.
104
+ *
105
+ * Any optional arguments may be supplied as nil to preserve the OpenSSL defaults.
106
+ *
107
+ * See the OpenSSL documentation for PKCS12_create().
108
+ */
109
+ static VALUE
110
+ ossl_pkcs12_s_create(int argc, VALUE *argv, VALUE self)
111
+ {
112
+ VALUE pass, name, pkey, cert, ca, key_nid, cert_nid, key_iter, mac_iter, keytype;
113
+ VALUE obj;
114
+ char *passphrase, *friendlyname;
115
+ EVP_PKEY *key;
116
+ X509 *x509;
117
+ STACK_OF(X509) *x509s;
118
+ int nkey = 0, ncert = 0, kiter = 0, miter = 0, ktype = 0;
119
+ PKCS12 *p12;
120
+
121
+ rb_scan_args(argc, argv, "46", &pass, &name, &pkey, &cert, &ca, &key_nid, &cert_nid, &key_iter, &mac_iter, &keytype);
122
+ passphrase = NIL_P(pass) ? NULL : StringValueCStr(pass);
123
+ friendlyname = NIL_P(name) ? NULL : StringValueCStr(name);
124
+ key = GetPKeyPtr(pkey);
125
+ x509 = GetX509CertPtr(cert);
126
+ /* TODO: make a VALUE to nid function */
127
+ if (!NIL_P(key_nid)) {
128
+ if ((nkey = OBJ_txt2nid(StringValueCStr(key_nid))) == NID_undef)
129
+ ossl_raise(rb_eArgError, "Unknown PBE algorithm %"PRIsVALUE, key_nid);
130
+ }
131
+ if (!NIL_P(cert_nid)) {
132
+ if ((ncert = OBJ_txt2nid(StringValueCStr(cert_nid))) == NID_undef)
133
+ ossl_raise(rb_eArgError, "Unknown PBE algorithm %"PRIsVALUE, cert_nid);
134
+ }
135
+ if (!NIL_P(key_iter))
136
+ kiter = NUM2INT(key_iter);
137
+ if (!NIL_P(mac_iter))
138
+ miter = NUM2INT(mac_iter);
139
+ if (!NIL_P(keytype))
140
+ ktype = NUM2INT(keytype);
141
+
142
+ obj = NewPKCS12(cPKCS12);
143
+ x509s = NIL_P(ca) ? NULL : ossl_x509_ary2sk(ca);
144
+ p12 = PKCS12_create(passphrase, friendlyname, key, x509, x509s,
145
+ nkey, ncert, kiter, miter, ktype);
146
+ sk_X509_pop_free(x509s, X509_free);
147
+ if(!p12) ossl_raise(ePKCS12Error, NULL);
148
+ SetPKCS12(obj, p12);
149
+
150
+ ossl_pkcs12_set_key(obj, pkey);
151
+ ossl_pkcs12_set_cert(obj, cert);
152
+ ossl_pkcs12_set_ca_certs(obj, ca);
153
+
154
+ return obj;
155
+ }
156
+
157
+ /*
158
+ * call-seq:
159
+ * PKCS12.new -> pkcs12
160
+ * PKCS12.new(str) -> pkcs12
161
+ * PKCS12.new(str, pass) -> pkcs12
162
+ *
163
+ * === Parameters
164
+ * * +str+ - Must be a DER encoded PKCS12 string.
165
+ * * +pass+ - string
166
+ */
167
+ static VALUE
168
+ ossl_pkcs12_initialize(int argc, VALUE *argv, VALUE self)
169
+ {
170
+ BIO *in;
171
+ VALUE arg, pass, pkey, cert, ca;
172
+ char *passphrase;
173
+ EVP_PKEY *key;
174
+ X509 *x509;
175
+ STACK_OF(X509) *x509s = NULL;
176
+ int st = 0;
177
+ PKCS12 *pkcs = DATA_PTR(self);
178
+
179
+ if(rb_scan_args(argc, argv, "02", &arg, &pass) == 0) return self;
180
+ passphrase = NIL_P(pass) ? NULL : StringValueCStr(pass);
181
+ in = ossl_obj2bio(arg);
182
+ d2i_PKCS12_bio(in, &pkcs);
183
+ DATA_PTR(self) = pkcs;
184
+ BIO_free(in);
185
+
186
+ pkey = cert = ca = Qnil;
187
+ /* OpenSSL's bug; PKCS12_parse() puts errors even if it succeeds.
188
+ * Fixed in OpenSSL 1.0.0t, 1.0.1p, 1.0.2d */
189
+ ERR_set_mark();
190
+ if(!PKCS12_parse(pkcs, passphrase, &key, &x509, &x509s))
191
+ ossl_raise(ePKCS12Error, "PKCS12_parse");
192
+ ERR_pop_to_mark();
193
+ pkey = rb_protect((VALUE (*)(VALUE))ossl_pkey_new, (VALUE)key,
194
+ &st); /* NO DUP */
195
+ if(st) goto err;
196
+ cert = rb_protect((VALUE (*)(VALUE))ossl_x509_new, (VALUE)x509, &st);
197
+ if(st) goto err;
198
+ if(x509s){
199
+ ca =
200
+ rb_protect((VALUE (*)(VALUE))ossl_x509_sk2ary, (VALUE)x509s, &st);
201
+ if(st) goto err;
202
+ }
203
+
204
+ err:
205
+ X509_free(x509);
206
+ sk_X509_pop_free(x509s, X509_free);
207
+ ossl_pkcs12_set_key(self, pkey);
208
+ ossl_pkcs12_set_cert(self, cert);
209
+ ossl_pkcs12_set_ca_certs(self, ca);
210
+ if(st) rb_jump_tag(st);
211
+
212
+ return self;
213
+ }
214
+
215
+ static VALUE
216
+ ossl_pkcs12_to_der(VALUE self)
217
+ {
218
+ PKCS12 *p12;
219
+ VALUE str;
220
+ long len;
221
+ unsigned char *p;
222
+
223
+ GetPKCS12(self, p12);
224
+ if((len = i2d_PKCS12(p12, NULL)) <= 0)
225
+ ossl_raise(ePKCS12Error, NULL);
226
+ str = rb_str_new(0, len);
227
+ p = (unsigned char *)RSTRING_PTR(str);
228
+ if(i2d_PKCS12(p12, &p) <= 0)
229
+ ossl_raise(ePKCS12Error, NULL);
230
+ ossl_str_adjust(str, p);
231
+
232
+ return str;
233
+ }
234
+
235
+ void
236
+ Init_ossl_pkcs12(void)
237
+ {
238
+ #if 0
239
+ mOSSL = rb_define_module("OpenSSL");
240
+ eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError);
241
+ #endif
242
+
243
+ /*
244
+ * Defines a file format commonly used to store private keys with
245
+ * accompanying public key certificates, protected with a password-based
246
+ * symmetric key.
247
+ */
248
+ cPKCS12 = rb_define_class_under(mOSSL, "PKCS12", rb_cObject);
249
+ ePKCS12Error = rb_define_class_under(cPKCS12, "PKCS12Error", eOSSLError);
250
+ rb_define_singleton_method(cPKCS12, "create", ossl_pkcs12_s_create, -1);
251
+
252
+ rb_define_alloc_func(cPKCS12, ossl_pkcs12_s_allocate);
253
+ rb_define_copy_func(cPKCS12, ossl_pkcs12_initialize_copy);
254
+ rb_attr(cPKCS12, rb_intern("key"), 1, 0, Qfalse);
255
+ rb_attr(cPKCS12, rb_intern("certificate"), 1, 0, Qfalse);
256
+ rb_attr(cPKCS12, rb_intern("ca_certs"), 1, 0, Qfalse);
257
+ rb_define_method(cPKCS12, "initialize", ossl_pkcs12_initialize, -1);
258
+ rb_define_method(cPKCS12, "to_der", ossl_pkcs12_to_der, 0);
259
+ }
@@ -0,0 +1,13 @@
1
+ /*
2
+ * This program is licensed under the same licence as Ruby.
3
+ * (See the file 'LICENCE'.)
4
+ */
5
+ #if !defined(_OSSL_PKCS12_H_)
6
+ #define _OSSL_PKCS12_H_
7
+
8
+ extern VALUE cPKCS12;
9
+ extern VALUE ePKCS12Error;
10
+
11
+ void Init_ossl_pkcs12(void);
12
+
13
+ #endif /* _OSSL_PKCS12_H_ */
@@ -0,0 +1,180 @@
1
+ /*
2
+ * Copyright (C) 2007 Technorama Ltd. <oss-ruby@technorama.net>
3
+ */
4
+ #include "ossl.h"
5
+
6
+ VALUE mPKCS5;
7
+ VALUE ePKCS5;
8
+
9
+ #ifdef HAVE_PKCS5_PBKDF2_HMAC
10
+ /*
11
+ * call-seq:
12
+ * PKCS5.pbkdf2_hmac(pass, salt, iter, keylen, digest) => string
13
+ *
14
+ * === Parameters
15
+ * * +pass+ - string
16
+ * * +salt+ - string - should be at least 8 bytes long.
17
+ * * +iter+ - integer - should be greater than 1000. 20000 is better.
18
+ * * +keylen+ - integer
19
+ * * +digest+ - a string or OpenSSL::Digest object.
20
+ *
21
+ * Available in OpenSSL >= 1.0.0.
22
+ *
23
+ * Digests other than SHA1 may not be supported by other cryptography libraries.
24
+ */
25
+ static VALUE
26
+ ossl_pkcs5_pbkdf2_hmac(VALUE self, VALUE pass, VALUE salt, VALUE iter, VALUE keylen, VALUE digest)
27
+ {
28
+ VALUE str;
29
+ const EVP_MD *md;
30
+ int len = NUM2INT(keylen);
31
+
32
+ StringValue(pass);
33
+ StringValue(salt);
34
+ md = GetDigestPtr(digest);
35
+
36
+ str = rb_str_new(0, len);
37
+
38
+ if (PKCS5_PBKDF2_HMAC(RSTRING_PTR(pass), RSTRING_LENINT(pass),
39
+ (unsigned char *)RSTRING_PTR(salt), RSTRING_LENINT(salt),
40
+ NUM2INT(iter), md, len,
41
+ (unsigned char *)RSTRING_PTR(str)) != 1)
42
+ ossl_raise(ePKCS5, "PKCS5_PBKDF2_HMAC");
43
+
44
+ return str;
45
+ }
46
+ #else
47
+ #define ossl_pkcs5_pbkdf2_hmac rb_f_notimplement
48
+ #endif
49
+
50
+
51
+ /*
52
+ * call-seq:
53
+ * PKCS5.pbkdf2_hmac_sha1(pass, salt, iter, keylen) => string
54
+ *
55
+ * === Parameters
56
+ * * +pass+ - string
57
+ * * +salt+ - string - should be at least 8 bytes long.
58
+ * * +iter+ - integer - should be greater than 1000. 20000 is better.
59
+ * * +keylen+ - integer
60
+ *
61
+ * This method is available in almost any version of OpenSSL.
62
+ *
63
+ * Conforms to RFC 2898.
64
+ */
65
+ static VALUE
66
+ ossl_pkcs5_pbkdf2_hmac_sha1(VALUE self, VALUE pass, VALUE salt, VALUE iter, VALUE keylen)
67
+ {
68
+ VALUE str;
69
+ int len = NUM2INT(keylen);
70
+
71
+ StringValue(pass);
72
+ StringValue(salt);
73
+
74
+ str = rb_str_new(0, len);
75
+
76
+ if (PKCS5_PBKDF2_HMAC_SHA1(RSTRING_PTR(pass), RSTRING_LENINT(pass),
77
+ (const unsigned char *)RSTRING_PTR(salt), RSTRING_LENINT(salt), NUM2INT(iter),
78
+ len, (unsigned char *)RSTRING_PTR(str)) != 1)
79
+ ossl_raise(ePKCS5, "PKCS5_PBKDF2_HMAC_SHA1");
80
+
81
+ return str;
82
+ }
83
+
84
+ void
85
+ Init_ossl_pkcs5(void)
86
+ {
87
+ #if 0
88
+ mOSSL = rb_define_module("OpenSSL");
89
+ eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError);
90
+ #endif
91
+
92
+ /* Document-class: OpenSSL::PKCS5
93
+ *
94
+ * Provides password-based encryption functionality based on PKCS#5.
95
+ * Typically used for securely deriving arbitrary length symmetric keys
96
+ * to be used with an OpenSSL::Cipher from passwords. Another use case
97
+ * is for storing passwords: Due to the ability to tweak the effort of
98
+ * computation by increasing the iteration count, computation can be
99
+ * slowed down artificially in order to render possible attacks infeasible.
100
+ *
101
+ * PKCS5 offers support for PBKDF2 with an OpenSSL::Digest::SHA1-based
102
+ * HMAC, or an arbitrary Digest if the underlying version of OpenSSL
103
+ * already supports it (>= 1.0.0).
104
+ *
105
+ * === Parameters
106
+ * ==== Password
107
+ * Typically an arbitrary String that represents the password to be used
108
+ * for deriving a key.
109
+ * ==== Salt
110
+ * Prevents attacks based on dictionaries of common passwords. It is a
111
+ * public value that can be safely stored along with the password (e.g.
112
+ * if PBKDF2 is used for password storage). For maximum security, a fresh,
113
+ * random salt should be generated for each stored password. According
114
+ * to PKCS#5, a salt should be at least 8 bytes long.
115
+ * ==== Iteration Count
116
+ * Allows to tweak the length that the actual computation will take. The
117
+ * larger the iteration count, the longer it will take.
118
+ * ==== Key Length
119
+ * Specifies the length in bytes of the output that will be generated.
120
+ * Typically, the key length should be larger than or equal to the output
121
+ * length of the underlying digest function, otherwise an attacker could
122
+ * simply try to brute-force the key. According to PKCS#5, security is
123
+ * limited by the output length of the underlying digest function, i.e.
124
+ * security is not improved if a key length strictly larger than the
125
+ * digest output length is chosen. Therefore, when using PKCS5 for
126
+ * password storage, it suffices to store values equal to the digest
127
+ * output length, nothing is gained by storing larger values.
128
+ *
129
+ * == Examples
130
+ * === Generating a 128 bit key for a Cipher (e.g. AES)
131
+ * pass = "secret"
132
+ * salt = OpenSSL::Random.random_bytes(16)
133
+ * iter = 20000
134
+ * key_len = 16
135
+ * key = OpenSSL::PKCS5.pbkdf2_hmac_sha1(pass, salt, iter, key_len)
136
+ *
137
+ * === Storing Passwords
138
+ * pass = "secret"
139
+ * salt = OpenSSL::Random.random_bytes(16) #store this with the generated value
140
+ * iter = 20000
141
+ * digest = OpenSSL::Digest::SHA256.new
142
+ * len = digest.digest_length
143
+ * #the final value to be stored
144
+ * value = OpenSSL::PKCS5.pbkdf2_hmac(pass, salt, iter, len, digest)
145
+ *
146
+ * === Important Note on Checking Passwords
147
+ * When comparing passwords provided by the user with previously stored
148
+ * values, a common mistake made is comparing the two values using "==".
149
+ * Typically, "==" short-circuits on evaluation, and is therefore
150
+ * vulnerable to timing attacks. The proper way is to use a method that
151
+ * always takes the same amount of time when comparing two values, thus
152
+ * not leaking any information to potential attackers. To compare two
153
+ * values, the following could be used:
154
+ * def eql_time_cmp(a, b)
155
+ * unless a.length == b.length
156
+ * return false
157
+ * end
158
+ * cmp = b.bytes.to_a
159
+ * result = 0
160
+ * a.bytes.each_with_index {|c,i|
161
+ * result |= c ^ cmp[i]
162
+ * }
163
+ * result == 0
164
+ * end
165
+ * Please note that the premature return in case of differing lengths
166
+ * typically does not leak valuable information - when using PKCS#5, the
167
+ * length of the values to be compared is of fixed size.
168
+ */
169
+
170
+ mPKCS5 = rb_define_module_under(mOSSL, "PKCS5");
171
+ /* Document-class: OpenSSL::PKCS5::PKCS5Error
172
+ *
173
+ * Generic Exception class that is raised if an error occurs during a
174
+ * computation.
175
+ */
176
+ ePKCS5 = rb_define_class_under(mPKCS5, "PKCS5Error", eOSSLError);
177
+
178
+ rb_define_module_function(mPKCS5, "pbkdf2_hmac", ossl_pkcs5_pbkdf2_hmac, 5);
179
+ rb_define_module_function(mPKCS5, "pbkdf2_hmac_sha1", ossl_pkcs5_pbkdf2_hmac_sha1, 4);
180
+ }