From cb0f83ae63c4555cbdd0607e3a5f6e9260c0d19c Mon Sep 17 00:00:00 2001 From: lloyd Date: Thu, 5 Feb 2015 07:44:25 +0000 Subject: Clean up root dir, remove some unneeded dependencies --- src/lib/misc/srp6/info.txt | 6 ++ src/lib/misc/srp6/srp6.cpp | 157 +++++++++++++++++++++++++++++++++++++++ src/lib/misc/srp6/srp6.h | 97 ++++++++++++++++++++++++ src/lib/misc/srp6/srp6_files.cpp | 69 +++++++++++++++++ src/lib/misc/srp6/srp6_files.h | 53 +++++++++++++ 5 files changed, 382 insertions(+) create mode 100644 src/lib/misc/srp6/info.txt create mode 100644 src/lib/misc/srp6/srp6.cpp create mode 100644 src/lib/misc/srp6/srp6.h create mode 100644 src/lib/misc/srp6/srp6_files.cpp create mode 100644 src/lib/misc/srp6/srp6_files.h (limited to 'src/lib/misc/srp6') diff --git a/src/lib/misc/srp6/info.txt b/src/lib/misc/srp6/info.txt new file mode 100644 index 000000000..5b07264b4 --- /dev/null +++ b/src/lib/misc/srp6/info.txt @@ -0,0 +1,6 @@ +define SRP6 20131128 + + +bigint +dl_group + diff --git a/src/lib/misc/srp6/srp6.cpp b/src/lib/misc/srp6/srp6.cpp new file mode 100644 index 000000000..d3f7338bd --- /dev/null +++ b/src/lib/misc/srp6/srp6.cpp @@ -0,0 +1,157 @@ +/* +* SRP-6a (RFC 5054 compatatible) +* (C) 2011,2012 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include +#include + +namespace Botan { + +namespace { + +BigInt hash_seq(const std::string& hash_id, + size_t pad_to, + const BigInt& in1, + const BigInt& in2) + { + std::unique_ptr hash_fn(get_hash(hash_id)); + + hash_fn->update(BigInt::encode_1363(in1, pad_to)); + hash_fn->update(BigInt::encode_1363(in2, pad_to)); + + return BigInt::decode(hash_fn->final()); + } + +BigInt compute_x(const std::string& hash_id, + const std::string& identifier, + const std::string& password, + const std::vector& salt) + { + std::unique_ptr hash_fn(get_hash(hash_id)); + + hash_fn->update(identifier); + hash_fn->update(":"); + hash_fn->update(password); + + secure_vector inner_h = hash_fn->final(); + + hash_fn->update(salt); + hash_fn->update(inner_h); + + secure_vector outer_h = hash_fn->final(); + + return BigInt::decode(outer_h); + } + +} + +std::string srp6_group_identifier(const BigInt& N, const BigInt& g) + { + /* + This function assumes that only one 'standard' SRP parameter set has + been defined for a particular bitsize. As of this writing that is the case. + */ + try + { + const std::string group_name = "modp/srp/" + std::to_string(N.bits()); + + DL_Group group(group_name); + + if(group.get_p() == N && group.get_g() == g) + return group_name; + + throw std::runtime_error("Unknown SRP params"); + } + catch(...) + { + throw Invalid_Argument("Bad SRP group parameters"); + } + } + +std::pair +srp6_client_agree(const std::string& identifier, + const std::string& password, + const std::string& group_id, + const std::string& hash_id, + const std::vector& salt, + const BigInt& B, + RandomNumberGenerator& rng) + { + DL_Group group(group_id); + const BigInt& g = group.get_g(); + const BigInt& p = group.get_p(); + + const size_t p_bytes = group.get_p().bytes(); + + if(B <= 0 || B >= p) + throw std::runtime_error("Invalid SRP parameter from server"); + + BigInt k = hash_seq(hash_id, p_bytes, p, g); + + BigInt a(rng, 256); + + BigInt A = power_mod(g, a, p); + + BigInt u = hash_seq(hash_id, p_bytes, A, B); + + const BigInt x = compute_x(hash_id, identifier, password, salt); + + BigInt S = power_mod((B - (k * power_mod(g, x, p))) % p, (a + (u * x)), p); + + SymmetricKey Sk(BigInt::encode_1363(S, p_bytes)); + + return std::make_pair(A, Sk); + } + +BigInt generate_srp6_verifier(const std::string& identifier, + const std::string& password, + const std::vector& salt, + const std::string& group_id, + const std::string& hash_id) + { + const BigInt x = compute_x(hash_id, identifier, password, salt); + + DL_Group group(group_id); + return power_mod(group.get_g(), x, group.get_p()); + } + +BigInt SRP6_Server_Session::step1(const BigInt& v, + const std::string& group_id, + const std::string& hash_id, + RandomNumberGenerator& rng) + { + DL_Group group(group_id); + const BigInt& g = group.get_g(); + const BigInt& p = group.get_p(); + + m_p_bytes = p.bytes(); + m_v = v; + m_b = BigInt(rng, 256); + m_p = p; + m_hash_id = hash_id; + + const BigInt k = hash_seq(hash_id, m_p_bytes, p, g); + + m_B = (v*k + power_mod(g, m_b, p)) % p; + + return m_B; + } + +SymmetricKey SRP6_Server_Session::step2(const BigInt& A) + { + if(A <= 0 || A >= m_p) + throw std::runtime_error("Invalid SRP parameter from client"); + + const BigInt u = hash_seq(m_hash_id, m_p_bytes, A, m_B); + + const BigInt S = power_mod(A * power_mod(m_v, u, m_p), m_b, m_p); + + return BigInt::encode_1363(S, m_p_bytes); + } + +} diff --git a/src/lib/misc/srp6/srp6.h b/src/lib/misc/srp6/srp6.h new file mode 100644 index 000000000..3eb21b742 --- /dev/null +++ b/src/lib/misc/srp6/srp6.h @@ -0,0 +1,97 @@ +/* +* SRP-6a (RFC 5054 compatatible) +* (C) 2011,2012 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_RFC5054_SRP6_H__ +#define BOTAN_RFC5054_SRP6_H__ + +#include +#include +#include +#include +#include + +namespace Botan { + +/** +* SRP6a Client side +* @param username the username we are attempting login for +* @param password the password we are attempting to use +* @param group_id specifies the shared SRP group +* @param hash_id specifies a secure hash function +* @param salt is the salt value sent by the server +* @param B is the server's public value +* @param rng is a random number generator +* +* @return (A,K) the client public key and the shared secret key +*/ +std::pair +BOTAN_DLL srp6_client_agree(const std::string& username, + const std::string& password, + const std::string& group_id, + const std::string& hash_id, + const std::vector& salt, + const BigInt& B, + RandomNumberGenerator& rng); + +/** +* Generate a new SRP-6 verifier +* @param identifier a username or other client identifier +* @param password the secret used to authenticate user +* @param salt a randomly chosen value, at least 128 bits long +* @param group_id specifies the shared SRP group +* @param hash_id specifies a secure hash function +*/ +BigInt BOTAN_DLL generate_srp6_verifier(const std::string& identifier, + const std::string& password, + const std::vector& salt, + const std::string& group_id, + const std::string& hash_id); + +/** +* Return the group id for this SRP param set, or else thrown an +* exception +* @param N the group modulus +* @param g the group generator +* @return group identifier +*/ +std::string BOTAN_DLL srp6_group_identifier(const BigInt& N, const BigInt& g); + +/** +* Represents a SRP-6a server session +*/ +class BOTAN_DLL SRP6_Server_Session + { + public: + /** + * Server side step 1 + * @param v the verification value saved from client registration + * @param group_id the SRP group id + * @param hash_id the SRP hash in use + * @param rng a random number generator + * @return SRP-6 B value + */ + BigInt step1(const BigInt& v, + const std::string& group_id, + const std::string& hash_id, + RandomNumberGenerator& rng); + + /** + * Server side step 2 + * @param A the client's value + * @return shared symmetric key + */ + SymmetricKey step2(const BigInt& A); + + private: + std::string m_hash_id; + BigInt m_B, m_b, m_v, m_S, m_p; + size_t m_p_bytes; + }; + +} + +#endif diff --git a/src/lib/misc/srp6/srp6_files.cpp b/src/lib/misc/srp6/srp6_files.cpp new file mode 100644 index 000000000..50f51fa75 --- /dev/null +++ b/src/lib/misc/srp6/srp6_files.cpp @@ -0,0 +1,69 @@ +/* +* SRP-6a File Handling +* (C) 2011 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include +#include + +namespace Botan { + +SRP6_Authenticator_File::SRP6_Authenticator_File(const std::string& filename) + { + std::ifstream in(filename.c_str()); + + if(!in) + return; // no entries + + while(in.good()) + { + std::string line; + std::getline(in, line); + + std::vector parts = split_on(line, ':'); + + if(parts.size() != 4) + throw Decoding_Error("Invalid line in SRP authenticator file"); + + std::string username = parts[0]; + BigInt v = BigInt::decode(base64_decode(parts[1])); + std::vector salt = unlock(base64_decode(parts[2])); + BigInt group_id_idx = BigInt::decode(base64_decode(parts[3])); + + std::string group_id; + + if(group_id_idx == 1) + group_id = "modp/srp/1024"; + else if(group_id_idx == 2) + group_id = "modp/srp/1536"; + else if(group_id_idx == 3) + group_id = "modp/srp/2048"; + else + continue; // unknown group, ignored + + entries[username] = SRP6_Data(v, salt, group_id); + } + } + +bool SRP6_Authenticator_File::lookup_user(const std::string& username, + BigInt& v, + std::vector& salt, + std::string& group_id) const + { + std::map::const_iterator i = entries.find(username); + + if(i == entries.end()) + return false; + + v = i->second.v; + salt = i->second.salt; + group_id = i->second.group_id; + + return true; + } + +} diff --git a/src/lib/misc/srp6/srp6_files.h b/src/lib/misc/srp6/srp6_files.h new file mode 100644 index 000000000..45c3b0bfe --- /dev/null +++ b/src/lib/misc/srp6/srp6_files.h @@ -0,0 +1,53 @@ +/* +* SRP-6a File Handling +* (C) 2011 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_SRP6A_FILES_H__ +#define BOTAN_SRP6A_FILES_H__ + +#include +#include +#include + +namespace Botan { + +/** +* A GnuTLS compatible SRP6 authenticator file +*/ +class BOTAN_DLL SRP6_Authenticator_File + { + public: + /** + * @param filename will be opened and processed as a SRP + * authenticator file + */ + SRP6_Authenticator_File(const std::string& filename); + + bool lookup_user(const std::string& username, + BigInt& v, + std::vector& salt, + std::string& group_id) const; + private: + struct SRP6_Data + { + SRP6_Data() {} + + SRP6_Data(const BigInt& v, + const std::vector& salt, + const std::string& group_id) : + v(v), salt(salt), group_id(group_id) {} + + BigInt v; + std::vector salt; + std::string group_id; + }; + + std::map entries; + }; + +} + +#endif -- cgit v1.2.3