44 if( p ==
nullptr )
throw Cram::NoTls() ;
47 struct DigesterAdaptor
49 explicit DigesterAdaptor( std::string_view name ) :
50 m_name(G::sv_to_string(name))
55 std::string operator()( std::string_view data_1 , std::string_view data_2 )
const
62 std::size_t blocksize()
const
67 std::size_t m_blocksize ;
69 struct PostDigesterAdaptor
71 explicit PostDigesterAdaptor( std::string_view name ) :
72 m_name(G::sv_to_string(name))
74 GSsl::Digester d( CramImp::lib().digester(m_name,std::string(),
true) ) ;
76 throw Cram::NoState( m_name ) ;
80 std::string operator()(
const std::string & state_pair ,
const std::string & data )
const
82 if( state_pair.size() != (2U*m_valuesize) )
throw Cram::InvalidState( m_name ) ;
83 std::string state_i = state_pair.substr( 0U , state_pair.size()/2U ) + G::HashStateImp::extension(m_blocksize) ;
84 std::string state_o = state_pair.substr( state_pair.size()/2U ) + G::HashStateImp::extension(m_blocksize) ;
92 std::size_t m_valuesize ;
93 std::size_t m_blocksize ;
99 const Secret & secret , std::string_view challenge , std::string_view id_prefix )
103 G_DEBUG(
"GAuth::Cram::response: [" << hash_type <<
"]"
104 <<
"[" << as_hmac <<
"]"
108 <<
"[" << responseImp(hash_type,as_hmac,secret,
challenge) <<
"]" ) ;
110 return G::sv_to_string(id_prefix).append(1U,
' ').append(responseImp(hash_type,as_hmac,secret,
challenge)) ;
112 catch( std::exception & e )
114 G_WARNING(
"GAuth::Cram::response: challenge-response failure: " << e.what() ) ;
120 const Secret & secret , std::string_view challenge ,
121 std::string_view response_in )
125 G_DEBUG(
"GAuth::Cram::validate: [" << hash_type <<
"]"
126 <<
"[" << as_hmac <<
"]"
129 <<
"[" << challenge <<
"]"
130 <<
"[" << response_in <<
"]"
131 <<
"[" << responseImp(hash_type,as_hmac,secret,challenge) <<
"]" ) ;
133 std::string expectation =
G::Str::tail( response_in , response_in.rfind(
' ') ) ;
134 return !expectation.empty() && responseImp(hash_type,as_hmac,secret,challenge) == expectation ;
136 catch( std::exception & e )
138 G_WARNING(
"GAuth::Cram::validate: challenge-response failure: " << e.what() ) ;
146 std::size_t pos = response.rfind(
' ' ) ;
150std::string GAuth::Cram::responseImp( std::string_view mechanism_hash_type ,
bool as_hmac ,
151 const Secret & secret , std::string_view challenge )
153 G_DEBUG(
"GAuth::Cram::responseImp: mechanism-hash=[" << mechanism_hash_type <<
"] "
155 <<
"as-hmac=" << as_hmac ) ;
168 CramImp::DigesterAdaptor digest( mechanism_hash_type ) ;
172 else if( secret.
masked() )
175 throw Mismatch( secret.
maskHashFunction() , G::sv_to_string(mechanism_hash_type) ) ;
183 CramImp::PostDigesterAdaptor postdigest( mechanism_hash_type ) ;
195 CramImp::DigesterAdaptor digest( mechanism_hash_type ) ;
209 result.emplace_back(
"FAKE" ) ;
212 G_DEBUG(
"GAuth::Cram::hashTypes: tls library hash types: [" <<
G::Str::join(
",",result) <<
"] "
213 <<
"(" << (require_state?1:0) <<
")" ) ;
217 result.emplace_back(
"MD5" ) ;
219 if( !prefix.empty() )
221 for(
auto & hashtype : result )
222 hashtype.insert( 0U , prefix.data() , prefix.size() ) ;
229 G_ASSERT( !challenge_domain_in.empty() ) ;
230 return std::string(1U,
'<')
231 .append(std::to_string(random)).append(1U,
'.')
233 .append(challenge_domain_in).append(1U,
'>') ;
static std::string id(std::string_view response)
Returns the leading id part of the response.
static G::StringArray hashTypes(std::string_view prefix={}, bool require_state=false)
Returns a list of supported hash types, such as "MD5" and "SHA1", ordered with the strongest first.
static std::string challenge(unsigned int random, const std::string &challenge_domain)
Returns a challenge string that incorporates the given random number and the current time.
static bool validate(std::string_view hash_type, bool hmac, const Secret &secret, std::string_view challenge, std::string_view response)
Validates the response with respect to the original challenge.
static std::string response(std::string_view hash_type, bool hmac, const Secret &secret, std::string_view challenge, std::string_view response_prefix)
Constructs a response to a challenge comprising the response-prefix, space, and digest-or-hmac of sec...
Encapsulates a userid/shared-secret/hash-function tuple from the secrets file.
std::string secret() const
Returns the secret shared key. Throws if not valid().
bool masked() const
Returns true if a non-empty hash function was passed to the ctor.
std::string maskHashFunction() const
Returns the masking function name as passed to the ctor, such as "md5", or the empty string if not ma...
A class for objects that can perform a cryptographic hash.
std::string value()
Returns the hash value.
std::size_t statesize() const noexcept
Returns the size of the state() string in bytes, or zero if state() is not implemented.
void add(std::string_view)
Adds data of arbitrary size.
std::size_t blocksize() const noexcept
Returns the hash function's block size in bytes.
std::size_t valuesize() const noexcept
Returns the hash function's value size in bytes.
A singleton class for initialising the underlying TLS library.
static Library * instance()
Returns a pointer to a library object, if any.
static std::string ids()
Returns a concatenation of all available TLS library names and versions.
static G::StringArray digesters(bool need_state=false)
Returns a list of hash function names (such as "MD5") that the TLS library can do,...
static std::string hmac(Fn2 digest, std::size_t blocksize, const std::string &key, const std::string &input)
Computes a Hashed Message Authentication Code using the given hash function.
static std::string printable(const std::string &input)
Converts a binary string into a printable form, using a lowercase hexadecimal encoding.
static std::string postdigest(const std::string &state_pair, const std::string &message)
A convenience function that returns the value() from an outer digest that is initialised with the sec...
static std::size_t blocksize()
Returns the block size in bytes (64).
static std::string digest2(const std::string &input_1, const std::string &input_2)
A non-overloaded name for the digest() overload taking two parameters.
static std::string digest(const std::string &input)
A convenience function that returns a digest from one input.
static std::string join(std::string_view sep, const StringArray &strings)
Concatenates an array of strings with separators.
static bool imatch(char, char) noexcept
Returns true if the two characters are the same, ignoring seven-bit case.
static std::string printable(const std::string &in, char escape='\\')
Returns a printable representation of the given input string, using chacter code ranges 0x20 to 0x7e ...
static std::string tail(std::string_view in, std::size_t pos, std::string_view default_={})
Returns the last part of the string after the given position.
static std::string head(std::string_view in, std::size_t pos, std::string_view default_={})
Returns the first part of the string up to just before the given position.
static SystemTime now()
Factory function for the current time.
static bool enabled() noexcept
Returns true if test features are enabled.
An interface to an underlying TLS library.
SASL authentication classes.
bool match(const StringArray &, const std::string &)
Returns true if any string in the array matches the given string.
std::vector< std::string > StringArray
A std::vector of std::strings.
An overload discriminator for G::Hash::hmac()