oroku_saki 1.0.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 92e35fcb6b712a4480ed16ad9ded3959f066b08a
4
- data.tar.gz: 87979e5935c98d372ab042a1d9aa0ddc36adb13b
3
+ metadata.gz: 1bb2e0fe1dcd41017630398ac68646eb38d5afbb
4
+ data.tar.gz: 8a95b019ba3f9514206da31bf880a1be35ea466f
5
5
  SHA512:
6
- metadata.gz: 6a755589cecf5494141b5e78d5598395fd2b022cdb6a4bdc7f94e59f9119fbb9b1218a84276c75727d32d4e7b75368e88526e8411afd631b5fdac29dbe5ad1ad
7
- data.tar.gz: f4be1b4ddbd048c686f956c6d1c884a1f3e62b70b8cbeaa6527e2743b3e28c425967044a74fcdd23eb88229cc997f580d2fdc36b74bcc93da0c49596f6a93072
6
+ metadata.gz: 41bc12a28951a48f193ab84f348148de620629a9af0b32b483d87e1512ae1c038ddd163d57e48f71405176b1797b5a2029f175f8931829d776540c7c91985cc6
7
+ data.tar.gz: e9c21b707a38c155c962a9b43a593cbad3eef76392176403753da5b21c450303a74206a3d08b6b63efc619c30fb73a3f72f35ad869709a851b88dccc699b4dd4
data/.travis.yml CHANGED
@@ -1,4 +1,6 @@
1
1
  language: ruby
2
2
  rvm:
3
+ - 2.1.1
3
4
  - 2.2.2
5
+ - 2.3.0
4
6
  before_install: gem install bundler -v 1.11.2
data/README.md CHANGED
@@ -1,4 +1,6 @@
1
1
  # OrokuSaki
2
+ [![Build Status](https://travis-ci.org/tpickett66/oroku_saki.svg?branch=master)](https://travis-ci.org/tpickett66/oroku_saki)
3
+ [![Gem Version](https://badge.fury.io/rb/oroku_saki.svg)](https://badge.fury.io/rb/oroku_saki)
2
4
 
3
5
  OrokuSaki, a.k.a. Shredder, is the destroyer of strings and attacker's worst
4
6
  nightmare!
@@ -1,31 +1,71 @@
1
+ #include <stdint.h>
1
2
  #include "oroku_saki.h"
2
3
 
3
- /* Zero out the memory housing the passed string.
4
- *
5
- * This method takes in a string and zeros out the memory it occupies, by design
6
- * it does not respect frozen states of strings so make sure you're actually
7
- * done with the String before using this method.
8
- *
9
- * @param [String] str The string to be zeroed out.
10
- * @raise [TypeError] When passed something other than a String
11
- * @return [nil]
12
- */
13
- VALUE oroku_saki_shred_bang(VALUE rb_module, VALUE rb_str) {
14
- if (TYPE(rb_str) != T_STRING) {
4
+ void raise_unless_string(VALUE rb_maybe_str, char *original_function_name) {
5
+ if (TYPE(rb_maybe_str) != T_STRING) {
15
6
  VALUE inspected_obj, obj_class_name;
16
- inspected_obj = rb_funcall(rb_str, rb_intern("inspect"), 0);
7
+ inspected_obj = rb_funcall(rb_maybe_str, rb_intern("inspect"), 0);
17
8
  obj_class_name = rb_funcall(
18
- rb_funcall(rb_str, rb_intern("class"), 0),
9
+ rb_funcall(rb_maybe_str, rb_intern("class"), 0),
19
10
  rb_intern("name"),
20
11
  0
21
12
  );
22
13
  rb_raise(
23
14
  rb_eTypeError,
24
- "OrokuSaki.shred! received %s (%s), expected String!",
15
+ "%s received %s (%s), expected String!",
16
+ original_function_name,
25
17
  StringValueCStr(inspected_obj),
26
18
  StringValueCStr(obj_class_name)
27
19
  );
28
20
  }
21
+ }
22
+
23
+ /*
24
+ * This is a modified version of NaCl's crypto_verify_N functions adatpted to
25
+ * work with Ruby's String types and with variable lengths. We're returning
26
+ * the bitmonkeyed int from this to avoid branch predication.
27
+ */
28
+ int secure_compare(VALUE rb_str_a, VALUE rb_str_b) {
29
+ uint_fast16_t d = 0U;
30
+ int i;
31
+ int len = RSTRING_LEN(rb_str_a);
32
+ char *a = RSTRING_PTR(rb_str_a);
33
+ char *b = RSTRING_PTR(rb_str_b);
34
+
35
+ for (i = 0; i < len; i++) {
36
+ d |= a[i] ^ b[i];
37
+ }
38
+
39
+ return (1 & ((d - 1) >> 8)) - 1;
40
+ }
41
+
42
+ /* The C implementation of the secure compare, the return type is a Fixnum
43
+ * to avoid certain optimizations that cause the branch predictor to leak timing
44
+ * information.
45
+ */
46
+ VALUE oroku_saki_secure_compare(VALUE rb_module, VALUE rb_str_a, VALUE rb_str_b) {
47
+ raise_unless_string(rb_str_a, "OrokuSaki.secure_compare");
48
+ raise_unless_string(rb_str_b, "OrokuSaki.secure_compare");
49
+
50
+ if (RSTRING_LEN(rb_str_a) != RSTRING_LEN(rb_str_b)) {
51
+ return INT2FIX(-1);
52
+ }
53
+
54
+ return INT2FIX(secure_compare(rb_str_a, rb_str_b));
55
+ }
56
+
57
+ /* Zero out the memory housing the passed string.
58
+ *
59
+ * This method takes in a string and zeros out the memory it occupies, by design
60
+ * it does not respect frozen states of strings so make sure you're actually
61
+ * done with the String before using this method.
62
+ *
63
+ * @param [String] str The string to be zeroed out.
64
+ * @raise [TypeError] When passed something other than a String
65
+ * @return [nil]
66
+ */
67
+ VALUE oroku_saki_shred_bang(VALUE rb_module, VALUE rb_str) {
68
+ raise_unless_string(rb_str, "OrokuSaki.shred!");
29
69
  memzero(RSTRING_PTR(rb_str), RSTRING_LEN(rb_str));
30
70
  return Qnil;
31
71
  }
@@ -38,4 +78,6 @@ Init_oroku_saki(void)
38
78
  rb_mOrokuSaki = rb_define_module("OrokuSaki");
39
79
  rb_define_singleton_method(rb_mOrokuSaki, "shred!",
40
80
  oroku_saki_shred_bang, 1);
81
+ rb_define_singleton_method(rb_mOrokuSaki, "secure_compare_c",
82
+ oroku_saki_secure_compare, 2);
41
83
  }
@@ -4,4 +4,7 @@
4
4
  #include "ruby.h"
5
5
  #include "memzero.h"
6
6
 
7
+ VALUE oroku_saki_secure_compare(VALUE rb_module, VALUE rb_str_a, VALUE rb_str_b);
8
+ VALUE oroku_saki_shred_bang(VALUE rb_module, VALUE rb_str);
9
+
7
10
  #endif /* OROKU_SAKI_H */
@@ -1,3 +1,3 @@
1
1
  module OrokuSaki
2
- VERSION = "1.0.0"
2
+ VERSION = "1.1.0"
3
3
  end
data/lib/oroku_saki.rb CHANGED
@@ -10,6 +10,10 @@ module OrokuSaki
10
10
  }
11
11
  private_constant :STRING_FINALIZER
12
12
 
13
+ class << self
14
+ private :secure_compare_c
15
+ end
16
+
13
17
  # Attaches the shred method as a finalizer for the passed string
14
18
  #
15
19
  # Gems working with sensitive data that needs to be returned to the user need
@@ -19,7 +23,7 @@ module OrokuSaki
19
23
  #
20
24
  # @param [String] str The string to be shredded befor GC reaping
21
25
  # @return [String] The original string
22
- #
26
+ # @raise [TypeError] When passed something other than a String
23
27
  def self.shred_later(str)
24
28
  if !(String === str)
25
29
  raise TypeError,
@@ -28,4 +32,14 @@ module OrokuSaki
28
32
  ObjectSpace.define_finalizer(str, STRING_FINALIZER)
29
33
  str
30
34
  end
35
+
36
+ # Bitewise compare two strings in constant time
37
+ #
38
+ # @param [String] a The first string to look at
39
+ # @param [String] b The second string to look at
40
+ # @return [Boolean]
41
+ # @raise [TypeError] When passed something other than a String for either argument
42
+ def self.secure_compare(a, b)
43
+ secure_compare_c(a, b) == 0
44
+ end
31
45
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: oroku_saki
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tyler Pickett