1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
|
# encoding: binary
# frozen_string_literal: true
module RbNaCl
# Secret Key Authenticators
#
# These provide a means of verifying the integrity of a message, but only
# with the knowledge of a shared key. This can be a preshared key, or one
# that is derived through some cryptographic protocol.
class Auth
# Number of bytes in a valid key
KEYBYTES = 0
# Number of bytes in a valid authenticator
BYTES = 0
attr_reader :key
private :key
# A new authenticator, ready for auth and verification
#
# @param [#to_str] key the key used for authenticators, 32 bytes.
def initialize(key)
@key = Util.check_string(key, key_bytes, "#{self.class} key")
end
# Compute authenticator for message
#
# @param [#to_str] key the key used for the authenticator
# @param [#to_str] message message to construct an authenticator for
#
# @return [String] The authenticator, as raw bytes
def self.auth(key, message)
new(key).auth(message)
end
# Verifies the given authenticator with the message.
#
# @param [#to_str] key the key used for the authenticator
# @param [#to_str] authenticator to be checked
# @param [#to_str] message the message to be authenticated
#
# @raise [BadAuthenticatorError] if the tag isn't valid
# @raise [LengthError] if the tag is of the wrong length
#
# @return [Boolean] Was it valid?
def self.verify(key, authenticator, message)
new(key).verify(authenticator, message)
end
# Compute authenticator for message
#
# @param [#to_str] message the message to authenticate
#
# @return [String] the authenticator as raw bytes
def auth(message)
authenticator = Util.zeros(tag_bytes)
message = message.to_str
compute_authenticator(authenticator, message)
authenticator
end
# Verifies the given authenticator with the message.
#
# @param [#to_str] authenticator to be checked
# @param [#to_str] message the message to be authenticated
#
# @raise [BadAuthenticatorError] if the tag isn't valid
# @raise [LengthError] if the tag is of the wrong length
#
# @return [Boolean] Was it valid?
def verify(authenticator, message)
auth = authenticator.to_s
Util.check_length(auth, tag_bytes, "Provided authenticator")
verify_message(auth, message) || raise(BadAuthenticatorError, "Invalid authenticator provided, message is corrupt")
end
# The crypto primitive for this authenticator instance
#
# @return [Symbol] The primitive used
def primitive
self.class.primitive
end
# The number of key bytes for this Auth class
#
# @return [Integer] number of key bytes
def self.key_bytes
self::KEYBYTES
end
# The number of key bytes for this Auth instance
#
# @return [Integer] number of key bytes
def key_bytes
self.class.key_bytes
end
# The number bytes in the tag or authenticator from this Auth class
#
# @return [Integer] number of tag bytes
def self.tag_bytes
self::BYTES
end
# The number of bytes in the tag or authenticator for this Auth instance
#
# @return [Integer] number of tag bytes
def tag_bytes
self.class.tag_bytes
end
private
def compute_authenticator(_authenticator, _message)
raise NotImplementedError
end
def verify_message(_authenticator, _message)
raise NotImplementedError
end
end
end
|