Secret interface changes
This commit is contained in:
parent
f6737a766f
commit
46f53c8e89
@ -8,11 +8,15 @@ describe Crypto::Secret::Not do
|
||||
key[1] = 1_u8
|
||||
|
||||
secret1 = Crypto::Secret::Not.new key.dup
|
||||
secret1.to_slice.should eq key
|
||||
secret1.to_slice { |s| s.should eq key }
|
||||
|
||||
secret2 = Crypto::Secret::Not.new key.dup
|
||||
|
||||
(secret1 == secret2).should be_true
|
||||
(secret1 == secret2.to_slice).should be_true
|
||||
secret1.to_slice do |s1|
|
||||
secret2.to_slice do |s2|
|
||||
(s1 == s2).should be_true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -13,4 +13,8 @@ struct Crypto::Secret::Not
|
||||
def to_slice : Bytes
|
||||
@bytes
|
||||
end
|
||||
|
||||
|
||||
delegate_to_slice @bytes
|
||||
delegate_to_bytesize @bytes
|
||||
end
|
||||
|
@ -4,59 +4,101 @@ require "crypto/subtle"
|
||||
#
|
||||
# **Only for direct use by cryptographic library authors**
|
||||
#
|
||||
# For all other applications use a preexisting class that include `Crypto::Secret`
|
||||
# For all other applications use a preexisting class that includes `Crypto::Secret`
|
||||
@[Experimental]
|
||||
module Crypto::Secret
|
||||
abstract def to_slice : Bytes
|
||||
class Error < Exception
|
||||
class KeyWiped < Error
|
||||
end
|
||||
end
|
||||
|
||||
def readwrite
|
||||
end
|
||||
|
||||
# Yields a Slice that is readable and writable
|
||||
#
|
||||
# `slice` is only available within the block
|
||||
#
|
||||
# Not thread safe
|
||||
def readwrite
|
||||
yield
|
||||
to_slice do |slice|
|
||||
yield slice
|
||||
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
|
||||
yield
|
||||
to_slice do |slice|
|
||||
yield slice
|
||||
end
|
||||
end
|
||||
|
||||
def noaccess
|
||||
end
|
||||
|
||||
# Not thread safe
|
||||
def noaccess
|
||||
yield
|
||||
end
|
||||
|
||||
# For debugging.
|
||||
# Returned String **not** tracked or wiped
|
||||
def hexstring : String
|
||||
readonly &.hexstring
|
||||
end
|
||||
|
||||
def wipe
|
||||
# Todo: implement wiping. Needs crystal support
|
||||
end
|
||||
|
||||
# Secret is wiped after exiting the block
|
||||
def wipe
|
||||
yield
|
||||
ensure
|
||||
wipe
|
||||
end
|
||||
|
||||
def reset
|
||||
end
|
||||
|
||||
def finalize
|
||||
wipe
|
||||
end
|
||||
|
||||
# Timing safe memory compare
|
||||
def ==(other : Secret) : Bool
|
||||
readonly do
|
||||
other.readonly do
|
||||
Crypto::Subtle.constant_time_compare to_slice, other.to_slice
|
||||
readonly do |s1|
|
||||
other.readonly do |s2|
|
||||
Crypto::Subtle.constant_time_compare s1, s2
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Timing safe memory compare
|
||||
def ==(other : Bytes) : Bool
|
||||
readonly do
|
||||
Crypto::Subtle.constant_time_compare to_slice, other.to_slice
|
||||
readonly do |s1|
|
||||
Crypto::Subtle.constant_time_compare s1, other
|
||||
end
|
||||
end
|
||||
|
||||
abstract def to_slice(& : Bytes -> Nil)
|
||||
abstract def bytesize : Int32
|
||||
|
||||
macro delegate_to_slice(to object)
|
||||
def to_slice(& : Bytes -> Nil)
|
||||
yield {{object.id}}.to_slice
|
||||
end
|
||||
end
|
||||
|
||||
macro delegate_to_bytesize(to object)
|
||||
def bytesize : Int32
|
||||
{{object.id}}.bytesize
|
||||
end
|
||||
end
|
||||
end
|
||||
|
Loading…
Reference in New Issue
Block a user