Add Crypto::Secret::Stateless
parent
472ed1fc37
commit
df977f18e8
|
@ -1,10 +1,12 @@
|
||||||
|
require "./stateless"
|
||||||
|
|
||||||
# A not very secret secret
|
# A not very secret secret
|
||||||
#
|
#
|
||||||
# Not locked in memory
|
# Not locked in memory
|
||||||
# Not access protected
|
# Not access protected
|
||||||
# No guard pages
|
# No guard pages
|
||||||
struct Crypto::Secret::Not
|
struct Crypto::Secret::Not
|
||||||
include Crypto::Secret
|
include Crypto::Secret::Stateless
|
||||||
|
|
||||||
def self.new(size)
|
def self.new(size)
|
||||||
new Bytes.new(size)
|
new Bytes.new(size)
|
||||||
|
|
|
@ -1,13 +1,12 @@
|
||||||
require "crypto/subtle"
|
require "crypto/subtle"
|
||||||
|
|
||||||
lib LibC
|
lib LibC
|
||||||
fun explicit_bzero(Void*, LibC::SizeT) : Int
|
fun explicit_bzero(Void*, LibC::SizeT) : Void
|
||||||
end
|
end
|
||||||
|
|
||||||
struct Slice(T)
|
struct Slice(T)
|
||||||
def wipe
|
def wipe
|
||||||
r = LibC.explicit_bzero slice.to_unsafe, slice.bytesize
|
LibC.explicit_bzero to_unsafe, bytesize
|
||||||
raise RunTimeError.from_errno("explicit_bzero") if r != 0
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -21,41 +20,21 @@ module Crypto::Secret
|
||||||
class Error < Exception
|
class Error < Exception
|
||||||
class KeyWiped < Error
|
class KeyWiped < Error
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
def readwrite
|
class InvalidStateTransition < Error
|
||||||
end
|
end
|
||||||
|
|
||||||
# Yields a Slice that is readable and writable
|
# Check RLIMIT_MEMLOCK if you receive this
|
||||||
#
|
class OutOfMemory < Error
|
||||||
# `slice` is only available within the block
|
|
||||||
#
|
|
||||||
# Not thread safe
|
|
||||||
def readwrite
|
|
||||||
to_slice do |slice|
|
|
||||||
yield slice
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def readonly
|
enum State
|
||||||
end
|
Cloning
|
||||||
|
Wiped
|
||||||
# Yields a Slice that is readable possibly writable depending on the prior protection level and underlying implementation
|
Noaccess
|
||||||
# Don't write to it
|
Readonly
|
||||||
#
|
Readwrite
|
||||||
# Not thread safe
|
|
||||||
def readonly
|
|
||||||
to_slice do |slice|
|
|
||||||
yield slice
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def noaccess
|
|
||||||
end
|
|
||||||
|
|
||||||
# Not thread safe
|
|
||||||
def noaccess
|
|
||||||
yield
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# For debugging.
|
# For debugging.
|
||||||
|
@ -66,7 +45,7 @@ module Crypto::Secret
|
||||||
|
|
||||||
def wipe
|
def wipe
|
||||||
readwrite do |slice|
|
readwrite do |slice|
|
||||||
slice.wipe
|
wipe_impl slice
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -105,6 +84,10 @@ module Crypto::Secret
|
||||||
io << self.class.to_s << "(***SECRET***)"
|
io << self.class.to_s << "(***SECRET***)"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
abstract def readwrite
|
||||||
|
abstract def readonly
|
||||||
|
abstract def noaccess
|
||||||
|
|
||||||
abstract def to_slice(& : Bytes -> Nil)
|
abstract def to_slice(& : Bytes -> Nil)
|
||||||
abstract def bytesize : Int32
|
abstract def bytesize : Int32
|
||||||
|
|
||||||
|
@ -119,4 +102,8 @@ module Crypto::Secret
|
||||||
{{object.id}}.bytesize
|
{{object.id}}.bytesize
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def wipe_impl(slice : Bytes) : Nil
|
||||||
|
slice.wipe
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,54 @@
|
||||||
|
require "./secret"
|
||||||
|
|
||||||
|
# Provides a 0 overhead implementation of [#readwrite, #readonly, #noaccess, #reset] with no protection
|
||||||
|
#
|
||||||
|
# Data is still erased when out of scope
|
||||||
|
module Crypto::Secret::Stateless
|
||||||
|
include Crypto::Secret
|
||||||
|
|
||||||
|
# Not thread safe
|
||||||
|
def readwrite
|
||||||
|
end
|
||||||
|
|
||||||
|
# Yields a Slice that is readable and writable
|
||||||
|
#
|
||||||
|
# `slice` is only available within the block
|
||||||
|
#
|
||||||
|
# Not thread safe
|
||||||
|
def readwrite
|
||||||
|
to_slice do |slice|
|
||||||
|
yield slice
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Not thread safe
|
||||||
|
def readonly
|
||||||
|
end
|
||||||
|
|
||||||
|
# Yields a Slice that is readable possibly writable depending on the prior protection level and underlying implementation
|
||||||
|
# Don't write to it
|
||||||
|
#
|
||||||
|
# Not thread safe
|
||||||
|
def readonly
|
||||||
|
to_slice do |slice|
|
||||||
|
yield slice
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Not thread safe
|
||||||
|
def noaccess
|
||||||
|
end
|
||||||
|
|
||||||
|
# Not thread safe
|
||||||
|
def noaccess
|
||||||
|
yield
|
||||||
|
end
|
||||||
|
|
||||||
|
# Not thread safe
|
||||||
|
def reset
|
||||||
|
end
|
||||||
|
|
||||||
|
def finalize
|
||||||
|
wipe
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in New Issue