43 if( p ==
nullptr )
throw Cram::NoTls() ;
46 struct DigesterAdaptor
49 m_name(G::sv_to_string(name))
61 std::size_t blocksize()
const
66 std::size_t m_blocksize ;
68 struct PostDigesterAdaptor
71 m_name(G::sv_to_string(name))
73 GSsl::Digester d( CramImp::lib().digester(m_name,std::string(),
true) ) ;
75 throw Cram::NoState( m_name ) ;
79 std::string operator()(
const std::string & state_pair ,
const std::string & data )
const
81 if( state_pair.size() != (2U*m_valuesize) )
throw Cram::InvalidState( m_name ) ;
82 std::string state_i = state_pair.substr( 0U , state_pair.size()/2U ) + G::HashStateImp::extension(m_blocksize) ;
83 std::string state_o = state_pair.substr( state_pair.size()/2U ) + G::HashStateImp::extension(m_blocksize) ;
91 std::size_t m_valuesize ;
92 std::size_t m_blocksize ;
102 G_DEBUG(
"GAuth::Cram::response: [" << hash_type <<
"]"
103 <<
"[" << as_hmac <<
"]"
107 <<
"[" << responseImp(hash_type,as_hmac,secret,
challenge) <<
"]" ) ;
109 return G::sv_to_string(id_prefix).append(1U,
' ').append(responseImp(hash_type,as_hmac,secret,
challenge)) ;
111 catch( std::exception & e )
113 G_WARNING(
"GAuth::Cram::response: challenge-response failure: " << e.what() ) ;
114 return std::string() ;
124 G_DEBUG(
"GAuth::Cram::validate: [" << hash_type <<
"]"
125 <<
"[" << as_hmac <<
"]"
128 <<
"[" << challenge <<
"]"
129 <<
"[" << response_in <<
"]"
130 <<
"[" << responseImp(hash_type,as_hmac,secret,challenge) <<
"]" ) ;
132 std::string expectation =
G::Str::tail( response_in , response_in.rfind(
' ') ) ;
133 return !expectation.empty() && responseImp(hash_type,as_hmac,secret,challenge) == expectation ;
135 catch( std::exception & e )
137 G_WARNING(
"GAuth::Cram::validate: challenge-response failure: " << e.what() ) ;
145 std::size_t pos = response.rfind(
' ' ) ;
149std::string GAuth::Cram::responseImp(
G::string_view mechanism_hash_type ,
bool as_hmac ,
152 G_DEBUG(
"GAuth::Cram::responseImp: mechanism-hash=[" << mechanism_hash_type <<
"] "
154 <<
"as-hmac=" << as_hmac ) ;
167 CramImp::DigesterAdaptor digest( mechanism_hash_type ) ;
171 else if( secret.
masked() )
174 throw Mismatch( secret.
maskHashFunction() , G::sv_to_string(mechanism_hash_type) ) ;
182 CramImp::PostDigesterAdaptor postdigest( mechanism_hash_type ) ;
194 CramImp::DigesterAdaptor digest( mechanism_hash_type ) ;
208 result.push_back(
"FAKE" ) ;
211 G_DEBUG(
"GAuth::Cram::hashTypes: tls library hash types: [" <<
G::Str::join(
",",result) <<
"] "
212 <<
"(" << (require_state?1:0) <<
")" ) ;
216 result.push_back(
"MD5" ) ;
218 if( !prefix.empty() )
220 for(
auto & hashtype : result )
221 hashtype.insert( 0U , prefix.data() , prefix.size() ) ;
229 return std::string(1U,
'<')
230 .append(std::to_string(random)).append(1U,
'.')
232 .append(challenge_domain).append(1U,
'>') ;
static G::StringArray hashTypes(G::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 bool validate(G::string_view hash_type, bool hmac, const Secret &secret, G::string_view challenge, G::string_view response)
Validates the response with respect to the original challenge.
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 std::string id(G::string_view response)
Returns the leading id part of the response.
static std::string response(G::string_view hash_type, bool hmac, const Secret &secret, G::string_view challenge, G::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...
static std::string canonicalName()
Returns the canonical network name assiciated with hostname().
A class for objects that can perform a cryptographic hash.
std::string value()
Returns the hash value.
void add(G::string_view)
Adds data of arbitrary size.
std::size_t statesize() const noexcept
Returns the size of the state() string in bytes, or zero if state() is not implemented.
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 bool imatch(char, char) noexcept
Returns true if the two characters are the same, ignoring seven-bit case.
static std::string join(string_view sep, const StringArray &strings)
Concatenates an array of strings with separators.
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(string_view in, std::size_t pos, string_view default_={})
Returns the last part of the string after the given position.
static std::string head(string_view in, std::size_t pos, 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.
A class like c++17's std::string_view.
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()