Add Crypto::Secret::Stateless
This commit is contained in:
parent
472ed1fc37
commit
df977f18e8
@ -1,10 +1,12 @@
|
||||
require "./stateless"
|
||||
|
||||
# A not very secret secret
|
||||
#
|
||||
# Not locked in memory
|
||||
# Not access protected
|
||||
# No guard pages
|
||||
struct Crypto::Secret::Not
|
||||
include Crypto::Secret
|
||||
include Crypto::Secret::Stateless
|
||||
|
||||
def self.new(size)
|
||||
new Bytes.new(size)
|
||||
|
@ -1,13 +1,12 @@
|
||||
require "crypto/subtle"
|
||||
|
||||
lib LibC
|
||||
fun explicit_bzero(Void*, LibC::SizeT) : Int
|
||||
fun explicit_bzero(Void*, LibC::SizeT) : Void
|
||||
end
|
||||
|
||||
struct Slice(T)
|
||||
def wipe
|
||||
r = LibC.explicit_bzero slice.to_unsafe, slice.bytesize
|
||||
raise RunTimeError.from_errno("explicit_bzero") if r != 0
|
||||
LibC.explicit_bzero to_unsafe, bytesize
|
||||
end
|
||||
end
|
||||
|
||||
@ -21,41 +20,21 @@ module Crypto::Secret
|
||||
class Error < Exception
|
||||
class KeyWiped < Error
|
||||
end
|
||||
|
||||
class InvalidStateTransition < Error
|
||||
end
|
||||
|
||||
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
|
||||
# Check RLIMIT_MEMLOCK if you receive this
|
||||
class OutOfMemory < Error
|
||||
end
|
||||
end
|
||||
|
||||
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
|
||||
|
||||
def noaccess
|
||||
end
|
||||
|
||||
# Not thread safe
|
||||
def noaccess
|
||||
yield
|
||||
enum State
|
||||
Cloning
|
||||
Wiped
|
||||
Noaccess
|
||||
Readonly
|
||||
Readwrite
|
||||
end
|
||||
|
||||
# For debugging.
|
||||
@ -66,7 +45,7 @@ module Crypto::Secret
|
||||
|
||||
def wipe
|
||||
readwrite do |slice|
|
||||
slice.wipe
|
||||
wipe_impl slice
|
||||
end
|
||||
end
|
||||
|
||||
@ -105,6 +84,10 @@ module Crypto::Secret
|
||||
io << self.class.to_s << "(***SECRET***)"
|
||||
end
|
||||
|
||||
abstract def readwrite
|
||||
abstract def readonly
|
||||
abstract def noaccess
|
||||
|
||||
abstract def to_slice(& : Bytes -> Nil)
|
||||
abstract def bytesize : Int32
|
||||
|
||||
@ -119,4 +102,8 @@ module Crypto::Secret
|
||||
{{object.id}}.bytesize
|
||||
end
|
||||
end
|
||||
|
||||
def wipe_impl(slice : Bytes) : Nil
|
||||
slice.wipe
|
||||
end
|
||||
end
|
||||
|
54
src/crypto-secret/stateless.cr
Normal file
54
src/crypto-secret/stateless.cr
Normal file
@ -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
Block a user