More documentation
Implement #reset & #random with specs
This commit is contained in:
parent
363800bf1a
commit
8977222b44
@ -1,5 +1,6 @@
|
|||||||
module Crypto::Secret::ClassMethods
|
module Crypto::Secret::ClassMethods
|
||||||
# Copies `data` to the new Secret and **erases data**
|
# Copies `data` to the new Secret and **erases data**
|
||||||
|
#
|
||||||
# Returns a **readonly** Secret
|
# Returns a **readonly** Secret
|
||||||
def move_from(data : Bytes)
|
def move_from(data : Bytes)
|
||||||
copy_from data
|
copy_from data
|
||||||
@ -8,6 +9,7 @@ module Crypto::Secret::ClassMethods
|
|||||||
end
|
end
|
||||||
|
|
||||||
# Copies `data` to the new Secret
|
# Copies `data` to the new Secret
|
||||||
|
#
|
||||||
# Returns a **readonly** Secret
|
# Returns a **readonly** Secret
|
||||||
def copy_from(data : Bytes)
|
def copy_from(data : Bytes)
|
||||||
new(data.bytesize).tap do |obj|
|
new(data.bytesize).tap do |obj|
|
||||||
@ -20,9 +22,6 @@ module Crypto::Secret::ClassMethods
|
|||||||
# Returns a **readonly** random Secret
|
# Returns a **readonly** random Secret
|
||||||
def random(size)
|
def random(size)
|
||||||
buf = new(size)
|
buf = new(size)
|
||||||
buf.readwrite do |slice|
|
buf.random.readonly
|
||||||
Random::Secure.random_bytes slice
|
|
||||||
end
|
|
||||||
buf.readonly
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -15,7 +15,7 @@ lib LibC
|
|||||||
end
|
end
|
||||||
|
|
||||||
struct Slice(T)
|
struct Slice(T)
|
||||||
def wipe
|
def wipe : Nil
|
||||||
LibC.explicit_bzero to_unsafe, bytesize
|
LibC.explicit_bzero to_unsafe, bytesize
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -35,12 +35,24 @@ module Crypto::Secret
|
|||||||
Readwrite
|
Readwrite
|
||||||
end
|
end
|
||||||
|
|
||||||
|
extend ClassMethods
|
||||||
|
|
||||||
# For debugging.
|
# For debugging.
|
||||||
# Returned String **not** tracked or wiped
|
# Returned String **not** tracked or wiped
|
||||||
def hexstring : String
|
def hexstring : String
|
||||||
readonly &.hexstring
|
readonly &.hexstring
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def random : self
|
||||||
|
readwrite do |slice|
|
||||||
|
Random::Secure.random_bytes slice
|
||||||
|
end
|
||||||
|
self
|
||||||
|
end
|
||||||
|
|
||||||
|
# Zeroes data
|
||||||
|
#
|
||||||
|
# Secret is unavailable (readonly/readwrite may fail) until reset
|
||||||
def wipe
|
def wipe
|
||||||
readwrite do |slice|
|
readwrite do |slice|
|
||||||
wipe_impl slice
|
wipe_impl slice
|
||||||
@ -55,6 +67,7 @@ module Crypto::Secret
|
|||||||
end
|
end
|
||||||
|
|
||||||
def reset
|
def reset
|
||||||
|
wipe
|
||||||
end
|
end
|
||||||
|
|
||||||
def finalize
|
def finalize
|
||||||
@ -93,9 +106,13 @@ module Crypto::Secret
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
abstract def readwrite
|
|
||||||
abstract def readonly
|
# Marks a region allocated using as read & write depending on implementation.
|
||||||
abstract def noaccess
|
abstract def readwrite : self
|
||||||
|
# Marks a region allocated using as read-only depending on implementation.
|
||||||
|
abstract def readonly : self
|
||||||
|
# Makes a region allocated inaccessible depending on implementation. It cannot be read or written, but the data are preserved.
|
||||||
|
abstract def noaccess : self
|
||||||
|
|
||||||
protected abstract def to_slice(& : Bytes -> Nil)
|
protected abstract def to_slice(& : Bytes -> Nil)
|
||||||
abstract def bytesize : Int32
|
abstract def bytesize : Int32
|
||||||
|
@ -17,6 +17,7 @@ module Crypto::Secret
|
|||||||
end
|
end
|
||||||
|
|
||||||
@state = State::Readwrite
|
@state = State::Readwrite
|
||||||
|
@pre_wipe_state = State::Readwrite
|
||||||
|
|
||||||
# Temporarily make buffer readwrite within the block returning to the prior state on exit.
|
# Temporarily make buffer readwrite within the block returning to the prior state on exit.
|
||||||
# WARNING: Not thread safe unless this object is **readwrite**
|
# WARNING: Not thread safe unless this object is **readwrite**
|
||||||
@ -65,6 +66,14 @@ module Crypto::Secret
|
|||||||
self
|
self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def reset
|
||||||
|
case @state
|
||||||
|
when State::Wiped; set_state @pre_wipe_state
|
||||||
|
else
|
||||||
|
wipe_impl
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
# WARNING: Not thread safe
|
# WARNING: Not thread safe
|
||||||
# Kept public for .dup
|
# Kept public for .dup
|
||||||
# :nodoc:
|
# :nodoc:
|
||||||
@ -72,12 +81,10 @@ module Crypto::Secret
|
|||||||
return if @state == new_state
|
return if @state == new_state
|
||||||
|
|
||||||
case new_state
|
case new_state
|
||||||
when State::Readwrite; readwrite
|
in State::Readwrite; readwrite
|
||||||
when State::Readonly ; readonly
|
in State::Readonly ; readonly
|
||||||
when State::Noaccess ; noaccess
|
in State::Noaccess ; noaccess
|
||||||
when State::Wiped ; raise Error::InvalidStateTransition.new
|
in State::Wiped ; raise Error::KeyWiped.new
|
||||||
else
|
|
||||||
raise "unknown state #{new_state}"
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -100,6 +107,7 @@ module Crypto::Secret
|
|||||||
# WARNING: Not thread safe
|
# WARNING: Not thread safe
|
||||||
def wipe
|
def wipe
|
||||||
return if @state == State::Wiped
|
return if @state == State::Wiped
|
||||||
|
@pre_wipe_state = @state
|
||||||
readwrite do |slice|
|
readwrite do |slice|
|
||||||
wipe_impl slice
|
wipe_impl slice
|
||||||
end
|
end
|
||||||
|
@ -76,5 +76,24 @@ macro test_secret_class(to sclass)
|
|||||||
|
|
||||||
secret.inspect.should match /\(\*\*\*SECRET\*\*\*\)$/
|
secret.inspect.should match /\(\*\*\*SECRET\*\*\*\)$/
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if sclass.is_a?(Crypto::Secret::Stateful)
|
||||||
|
it "can't transition after #wipe except with #reset" do
|
||||||
|
secret = sclass.new 1
|
||||||
|
secret.wipe
|
||||||
|
expect_raises Crypto::Secret::Error::KeyWiped do
|
||||||
|
secret.readwrite
|
||||||
|
end
|
||||||
|
expect_raises Crypto::Secret::Error::KeyWiped do
|
||||||
|
secret.readonly
|
||||||
|
end
|
||||||
|
expect_raises Crypto::Secret::Error::KeyWiped do
|
||||||
|
secret.readnoaccess
|
||||||
|
end
|
||||||
|
|
||||||
|
secret.reset
|
||||||
|
secret.readonly
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
Loading…
Reference in New Issue
Block a user