Module: OrokuSaki

Defined in:
lib/oroku_saki.rb,
lib/oroku_saki/version.rb,
lib/oroku_saki/string_ext.rb,
ext/oroku_saki/oroku_saki.c

Defined Under Namespace

Modules: StringExt

Constant Summary collapse

VERSION =
"1.1.2"

Class Method Summary collapse

Class Method Details

.secure_compare(a, b) ⇒ Boolean

Bitewise compare two strings in constant time

Parameters:

  • a (String)

    The first string to look at

  • b (String)

    The second string to look at

Returns:

  • (Boolean)

Raises:

  • (TypeError)

    When passed something other than a String for either argument



42
43
44
# File 'lib/oroku_saki.rb', line 42

def self.secure_compare(a, b)
  secure_compare_c(a, b) == 0
end

.secure_compare_c(rb_str_a, rb_str_b) ⇒ Fixnum

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

The C implementation of secure compare, don’t use!

The return type is a Fixnum to avoid certain optimizations that cause the branch predictor to potentially leak timing information.

Parameters:

  • rb_str_a (String)
  • rb_str_b (String)

Returns:

  • (Fixnum)

    Zero for success, other values for failure.



52
53
54
55
56
57
58
59
60
61
# File 'ext/oroku_saki/oroku_saki.c', line 52

VALUE oroku_saki_secure_compare(VALUE rb_module, VALUE rb_str_a, VALUE rb_str_b) {
  raise_unless_string(rb_str_a, "OrokuSaki.secure_compare");
  raise_unless_string(rb_str_b, "OrokuSaki.secure_compare");

  if (RSTRING_LEN(rb_str_a) != RSTRING_LEN(rb_str_b)) {
    return INT2FIX(-1);
  }

  return INT2FIX(secure_compare(rb_str_a, rb_str_b));
}

.shred!(rb_str) ⇒ nil

Zero out the memory housing the passed string.

This method takes in a string and zeros out the memory it occupies, by design it does not respect frozen states of strings so make sure you’re actually done with the String before using this method.

Parameters:

  • rb_str (String)

    The string to be zeroed out.

Returns:

  • (nil)

Raises:

  • (TypeError)

    When passed something other than a String



73
74
75
76
77
# File 'ext/oroku_saki/oroku_saki.c', line 73

VALUE oroku_saki_shred_bang(VALUE rb_module, VALUE rb_str) {
  raise_unless_string(rb_str, "OrokuSaki.shred!");
  memzero(RSTRING_PTR(rb_str), RSTRING_LEN(rb_str));
  return Qnil;
}

.shred_later(str) ⇒ String

Attaches the shred method as a finalizer for the passed string

Gems working with sensitive data that needs to be returned to the user need a way to ensure the data gets cleared from memory without user intervention. Having this finalizer attached ensures the sensitive contents will be zeroed before the GC reaps the object.

Parameters:

  • str (String)

    The string to be shredded befor GC reaping

Returns:

  • (String)

    The original string

Raises:

  • (TypeError)

    When passed something other than a String



27
28
29
30
31
32
33
34
# File 'lib/oroku_saki.rb', line 27

def self.shred_later(str)
  if !(String === str)
    raise TypeError,
      "OrokuSaki.shred_later received #{str} (#{str.class}), expected String!"
  end
  ObjectSpace.define_finalizer(str, STRING_FINALIZER) unless str.frozen?
  str
end