oroku_saki 1.0.0 → 1.1.2

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
- SHA1:
3
- metadata.gz: 92e35fcb6b712a4480ed16ad9ded3959f066b08a
4
- data.tar.gz: 87979e5935c98d372ab042a1d9aa0ddc36adb13b
2
+ SHA256:
3
+ metadata.gz: 52938f10790d5d1fed271cd6ebf9f0fcf7f734745bf3b707b9594c8ffe5e5913
4
+ data.tar.gz: 33f7261880251491f3c8aa79db6d4816cdd508330b6a429043a930da41b4db74
5
5
  SHA512:
6
- metadata.gz: 6a755589cecf5494141b5e78d5598395fd2b022cdb6a4bdc7f94e59f9119fbb9b1218a84276c75727d32d4e7b75368e88526e8411afd631b5fdac29dbe5ad1ad
7
- data.tar.gz: f4be1b4ddbd048c686f956c6d1c884a1f3e62b70b8cbeaa6527e2743b3e28c425967044a74fcdd23eb88229cc997f580d2fdc36b74bcc93da0c49596f6a93072
6
+ metadata.gz: 7ecd06e1cd35594ef8a7524d815a6779d6486d1bff8e08e2a6176e7dff07cdefcc3b6cfb9067e3b2b1c63bcc022fceba448fad90abc8dedbd0ebb0cd4ea419c0
7
+ data.tar.gz: a2f056b0f95d575bdce333fcbab22d6792c7c633ac7d4d24d8b788d6f80197ba602082ff2fb8057c31f998e26f59d5db88651344758d4b774e4be84ef00ac6a9
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!
@@ -36,17 +38,25 @@ second_secret = 'another sekret'
36
38
  second_secret.shred! # => "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000"
37
39
  ```
38
40
 
39
- Setting a string to be shredded before garbage collection:
41
+ Setting a string to be shredded before garbage collection via a finalizer:
42
+
40
43
  ```ruby
41
44
  my_secret = 'super sekret value!!!'
42
45
  OrokuSaki.shred_later(my_secret) # => nil
43
46
  puts my_secret # => "super sekret value!!!"
44
- # A finalizer shreds the str just before it gets collected.
45
47
 
46
48
  second_secret = 'another sekret'
47
49
  second_scret.shred_later
48
50
  ```
49
51
 
52
+ Comparing Strings in constant time (nearly as fast as `==` for small inputs):
53
+
54
+ ```ruby
55
+ hmac = '16b9b8ae8e164768d0505bcb16269efb35804643dd351084b3c6ebbc6f7db2c8'
56
+ other_hmac = '16b9b8ae8e164768d0505bcb16269efb35804643dd351084b3c6ebbc6f7db2c8'
57
+ OrokuSaki.secure_compare(hmac, other_hmac) #=> true
58
+ ```
59
+
50
60
  ## Development
51
61
 
52
62
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
@@ -1,31 +1,77 @@
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 secure compare, don't use!
43
+ *
44
+ * The return type is a Fixnum to avoid certain optimizations that cause the
45
+ * branch predictor to potentially leak timing information.
46
+ *
47
+ * @param [String] rb_str_a
48
+ * @param [String] rb_str_b
49
+ * @return [Fixnum] Zero for success, other values for failure.
50
+ * @api private
51
+ */
52
+ VALUE oroku_saki_secure_compare(VALUE rb_module, VALUE rb_str_a, VALUE rb_str_b) {
53
+ raise_unless_string(rb_str_a, "OrokuSaki.secure_compare");
54
+ raise_unless_string(rb_str_b, "OrokuSaki.secure_compare");
55
+
56
+ if (RSTRING_LEN(rb_str_a) != RSTRING_LEN(rb_str_b)) {
57
+ return INT2FIX(-1);
58
+ }
59
+
60
+ return INT2FIX(secure_compare(rb_str_a, rb_str_b));
61
+ }
62
+
63
+ /* Zero out the memory housing the passed string.
64
+ *
65
+ * This method takes in a string and zeros out the memory it occupies, by design
66
+ * it does not respect frozen states of strings so make sure you're actually
67
+ * done with the String before using this method.
68
+ *
69
+ * @param [String] rb_str The string to be zeroed out.
70
+ * @raise [TypeError] When passed something other than a String
71
+ * @return [nil]
72
+ */
73
+ VALUE oroku_saki_shred_bang(VALUE rb_module, VALUE rb_str) {
74
+ raise_unless_string(rb_str, "OrokuSaki.shred!");
29
75
  memzero(RSTRING_PTR(rb_str), RSTRING_LEN(rb_str));
30
76
  return Qnil;
31
77
  }
@@ -38,4 +84,6 @@ Init_oroku_saki(void)
38
84
  rb_mOrokuSaki = rb_define_module("OrokuSaki");
39
85
  rb_define_singleton_method(rb_mOrokuSaki, "shred!",
40
86
  oroku_saki_shred_bang, 1);
87
+ rb_define_singleton_method(rb_mOrokuSaki, "secure_compare_c",
88
+ oroku_saki_secure_compare, 2);
41
89
  }
@@ -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.2"
3
3
  end
data/lib/oroku_saki.rb CHANGED
@@ -6,10 +6,14 @@ require 'objspace'
6
6
 
7
7
  module OrokuSaki
8
8
  STRING_FINALIZER = ->(id) {
9
- OrokuSaki.shred!(ObjectSpace._id2ref(id))
9
+ OrokuSaki.shred!(ObjectSpace._id2ref(id)) rescue nil
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,13 +23,23 @@ 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,
26
30
  "OrokuSaki.shred_later received #{str} (#{str.class}), expected String!"
27
31
  end
28
- ObjectSpace.define_finalizer(str, STRING_FINALIZER)
32
+ ObjectSpace.define_finalizer(str, STRING_FINALIZER) unless str.frozen?
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
data/oroku_saki.gemspec CHANGED
@@ -10,9 +10,10 @@ Gem::Specification.new do |spec|
10
10
  spec.email = ["t.pickett66@gmail.com"]
11
11
 
12
12
  spec.summary = %q{OrokuSaki, a.k.a. Shredder, is the destroyer of strings and attacker's worst nightmare!}
13
- spec.description = "OrokuSaki, a.k.a. Shredder, is a small collection for " \
14
- "ensuring the strings used in cryptographic operations remain secret. It is " \
15
- "based around a simple memzero C function."
13
+ spec.description = "OrokuSaki, a.k.a. Shredder, is a small collection of " \
14
+ "utilities for ensuring the strings used in cryptographic operations " \
15
+ "remain secret. This currently includes memory zeroing and constant time " \
16
+ "String comparisons."
16
17
  spec.homepage = "https://github.com/tpickett66/oroku_saki"
17
18
  spec.license = "MIT"
18
19
 
@@ -22,10 +23,10 @@ Gem::Specification.new do |spec|
22
23
  spec.require_paths = ["lib"]
23
24
  spec.extensions = ["ext/oroku_saki/extconf.rb"]
24
25
 
25
- spec.add_development_dependency "bundler", "~> 1.11"
26
- spec.add_development_dependency "rake", "~> 10.0"
26
+ spec.add_development_dependency "bundler", "~> 2.2.33"
27
+ spec.add_development_dependency "rake", "~> 12.3.2"
27
28
  spec.add_development_dependency "rake-compiler", "~> 0.9"
28
29
  spec.add_development_dependency "rspec", "~> 3.0"
29
30
  spec.add_development_dependency "byebug", "~> 8.2"
30
- spec.add_development_dependency "yard", "~> 0.8.7"
31
+ spec.add_development_dependency "yard", "~> 0.9.11"
31
32
  end
metadata CHANGED
@@ -1,14 +1,14 @@
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.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tyler Pickett
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-04-13 00:00:00.000000000 Z
11
+ date: 2022-03-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -16,28 +16,28 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '1.11'
19
+ version: 2.2.33
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '1.11'
26
+ version: 2.2.33
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rake
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '10.0'
33
+ version: 12.3.2
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '10.0'
40
+ version: 12.3.2
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rake-compiler
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -86,17 +86,17 @@ dependencies:
86
86
  requirements:
87
87
  - - "~>"
88
88
  - !ruby/object:Gem::Version
89
- version: 0.8.7
89
+ version: 0.9.11
90
90
  type: :development
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
94
  - - "~>"
95
95
  - !ruby/object:Gem::Version
96
- version: 0.8.7
97
- description: OrokuSaki, a.k.a. Shredder, is a small collection for ensuring the strings
98
- used in cryptographic operations remain secret. It is based around a simple memzero
99
- C function.
96
+ version: 0.9.11
97
+ description: OrokuSaki, a.k.a. Shredder, is a small collection of utilities for ensuring
98
+ the strings used in cryptographic operations remain secret. This currently includes
99
+ memory zeroing and constant time String comparisons.
100
100
  email:
101
101
  - t.pickett66@gmail.com
102
102
  executables: []
@@ -127,7 +127,7 @@ homepage: https://github.com/tpickett66/oroku_saki
127
127
  licenses:
128
128
  - MIT
129
129
  metadata: {}
130
- post_install_message:
130
+ post_install_message:
131
131
  rdoc_options: []
132
132
  require_paths:
133
133
  - lib
@@ -142,11 +142,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
142
142
  - !ruby/object:Gem::Version
143
143
  version: '0'
144
144
  requirements: []
145
- rubyforge_project:
146
- rubygems_version: 2.4.5
147
- signing_key:
145
+ rubygems_version: 3.3.7
146
+ signing_key:
148
147
  specification_version: 4
149
148
  summary: OrokuSaki, a.k.a. Shredder, is the destroyer of strings and attacker's worst
150
149
  nightmare!
151
150
  test_files: []
152
- has_rdoc: