Class: Confium::SecureBytes

Inherits:
Object
  • Object
show all
Defined in:
lib/confium/secure_bytes.rb

Overview

SecureBytes wraps sensitive cryptographic byte data (private keys, Shamir shares, shared secrets) with zeroize-on-clear semantics.

MRI Ruby's String is backed by a heap-allocated char buffer that persists until GC. SecureBytes overwrites that buffer with zeros when #clear is called (explicitly or via finalizer).

Usage:

key = Confium::SecureBytes.wrap(raw_bytes)
key.bytes  # non-destructive read
key.clear  # zeroize + deallocate

After #clear, #bytes raises Confium::ClearedError.

Defined Under Namespace

Classes: ClearedError

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(raw) ⇒ SecureBytes

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.

Returns a new instance of SecureBytes.



35
36
37
38
39
40
41
# File 'lib/confium/secure_bytes.rb', line 35

def initialize(raw)
  @buffer = raw.dup.force_encoding(Encoding::ASCII_8BIT)
  @cleared = false
  # Register finalizer to zeroize if the object is GC'd without
  # an explicit #clear call.
  ObjectSpace.define_finalizer(self, finalizer_proc)
end

Class Method Details

.wrap(raw) ⇒ Confium::SecureBytes

Create a SecureBytes wrapping a copy of the given String. The original String's contents are NOT modified; callers should zeroize the original separately if needed.

Parameters:

  • raw (String)

    binary String (any encoding; bytes are copied)

Returns:



30
31
32
# File 'lib/confium/secure_bytes.rb', line 30

def self.wrap(raw)
  new(raw)
end

Instance Method Details

#bytesString

Non-destructive read of the wrapped bytes.

Returns:

  • (String)

    binary String (ASCII-8BIT encoding)

Raises:



46
47
48
49
50
# File 'lib/confium/secure_bytes.rb', line 46

def bytes
  raise ClearedError if @cleared

  @buffer.dup
end

#bytes!String

Destructive read: returns a copy, then zeroizes the original.

Returns:

  • (String)

    binary String

Raises:



55
56
57
58
59
60
61
# File 'lib/confium/secure_bytes.rb', line 55

def bytes!
  raise ClearedError if @cleared

  copy = @buffer.dup
  clear
  copy
end

#clearself

Zeroize the buffer immediately. Idempotent.

Returns:

  • (self)


79
80
81
82
83
84
85
86
87
# File 'lib/confium/secure_bytes.rb', line 79

def clear
  return self if @cleared

  # Overwrite every byte with 0x00 in place.
  @buffer.replace("\x00" * @buffer.bytesize)
  @buffer = nil
  @cleared = true
  self
end

#cleared?Boolean

Whether the buffer has been cleared.

Returns:

  • (Boolean)


73
74
75
# File 'lib/confium/secure_bytes.rb', line 73

def cleared?
  @cleared
end

#inspectString

String representation for debugging. Does NOT expose the raw bytes.

Returns:

  • (String)


91
92
93
94
95
96
97
# File 'lib/confium/secure_bytes.rb', line 91

def inspect
  if @cleared
    "#<Confium::SecureBytes:0x#{object_id.to_s(16)} CLEARED>"
  else
    "#<Confium::SecureBytes:0x#{object_id.to_s(16)} #{length} bytes>"
  end
end

#lengthInteger Also known as: size

Number of bytes. Returns 0 after #clear.

Returns:

  • (Integer)


65
66
67
# File 'lib/confium/secure_bytes.rb', line 65

def length
  @cleared ? 0 : @buffer.bytesize
end