diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/constructs/srp6/srp6.cpp | 37 | ||||
-rw-r--r-- | src/constructs/srp6/srp6.h | 36 | ||||
-rw-r--r-- | src/constructs/srp6/srp6_files.cpp | 69 | ||||
-rw-r--r-- | src/constructs/srp6/srp6_files.h | 53 |
4 files changed, 143 insertions, 52 deletions
diff --git a/src/constructs/srp6/srp6.cpp b/src/constructs/srp6/srp6.cpp index 995244688..287f0bdfb 100644 --- a/src/constructs/srp6/srp6.cpp +++ b/src/constructs/srp6/srp6.cpp @@ -69,7 +69,7 @@ BigInt compute_x(const std::string& hash_id, } -std::pair<BigInt, BigInt> +std::pair<BigInt, SymmetricKey> SRP6_Client_Session:: step1(const std::string& identifier, const std::string& password, const std::string& group_id, @@ -82,7 +82,7 @@ SRP6_Client_Session:: step1(const std::string& identifier, const BigInt& g = group.get_g(); const BigInt& p = group.get_p(); - p_bytes = group.get_p().bytes(); + const size_t p_bytes = group.get_p().bytes(); if(B % p == 0) throw std::runtime_error("Invalid SRP parameter from server"); @@ -91,29 +91,17 @@ SRP6_Client_Session:: step1(const std::string& identifier, BigInt a(rng, p.bits() - 1); - A = power_mod(g, a, p); + 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); - S = power_mod((B - (k * power_mod(g, x, p))) % p, (a + (u * x)), p); + BigInt S = power_mod((B - (k * power_mod(g, x, p))) % p, (a + (u * x)), p); - this->hash_id = hash_id; - - M1 = hash_seq(hash_id, p_bytes, A, B, S); + SymmetricKey Sk(BigInt::encode_1363(S, p_bytes)); - return std::make_pair<BigInt, BigInt>(A, M1); - } - -SymmetricKey SRP6_Client_Session::step2(const BigInt& M2) - { - BigInt M2x = hash_seq(hash_id, p_bytes, A, M1, S); - - if(M2 != M2x) - throw std::runtime_error("Bad verification value from server"); - - return SymmetricKey(BigInt::encode_1363(S, p_bytes)); + return std::make_pair(A, Sk); } BigInt SRP6_Client_Session::generate_verifier(const std::string& identifier, @@ -153,7 +141,7 @@ BigInt SRP6_Server_Session::step1(const BigInt& v, return B; } -std::pair<SymmetricKey, BigInt> SRP6_Server_Session::step2(const BigInt& A, const BigInt& M1) +SymmetricKey SRP6_Server_Session::step2(const BigInt& A) { if(A % p == 0) throw std::runtime_error("Invalid SRP parameter from client"); @@ -162,16 +150,7 @@ std::pair<SymmetricKey, BigInt> SRP6_Server_Session::step2(const BigInt& A, cons BigInt S = power_mod(A * power_mod(v, u, p), b, p); - BigInt M1x = hash_seq(hash_id, p_bytes, A, B, S); - - if(M1 != M1x) - throw std::runtime_error("Bad verification value from client"); - - BigInt M2 = hash_seq(hash_id, p_bytes, A, M1, S); - - SymmetricKey Sk = BigInt::encode_1363(S, p_bytes); - - return std::make_pair<SymmetricKey, BigInt>(Sk, M2); + return BigInt::encode_1363(S, p_bytes); } } diff --git a/src/constructs/srp6/srp6.h b/src/constructs/srp6/srp6.h index fbb4a686d..01bd2a4c7 100644 --- a/src/constructs/srp6/srp6.h +++ b/src/constructs/srp6/srp6.h @@ -17,7 +17,7 @@ namespace Botan { /** - +* Represents a SRP-6a client session */ class BOTAN_DLL SRP6_Client_Session { @@ -33,23 +33,15 @@ class BOTAN_DLL SRP6_Client_Session * @param B is the server's public value * @param rng is a random number generator * - * @return (A,M1) the client public key and verification values, - which are sent to the server - */ - std::pair<BigInt, BigInt> step1(const std::string& username, - const std::string& password, - const std::string& group_id, - const std::string& hash_id, - const MemoryRegion<byte>& salt, - const BigInt& B, - RandomNumberGenerator& rng); - - /** - * Client side step 2 - * @param M2 the server verification value - * @return shared secret key + * @return (A,K) the client public key and the shared secret key */ - SymmetricKey step2(const BigInt& M2); + std::pair<BigInt,SymmetricKey> step1(const std::string& username, + const std::string& password, + const std::string& group_id, + const std::string& hash_id, + const MemoryRegion<byte>& salt, + const BigInt& B, + RandomNumberGenerator& rng); /** * Generate a new SRP-6 verifier @@ -62,13 +54,11 @@ class BOTAN_DLL SRP6_Client_Session const MemoryRegion<byte>& salt, const std::string& group_id, const std::string& hash_id); - - private: - std::string hash_id; - BigInt A, M1, S; - size_t p_bytes; }; +/** +* Represents a SRP-6a server session +*/ class BOTAN_DLL SRP6_Server_Session { public: @@ -81,7 +71,7 @@ class BOTAN_DLL SRP6_Server_Session const std::string& hash_id, RandomNumberGenerator& rng); - std::pair<SymmetricKey, BigInt> step2(const BigInt& A, const BigInt& M1); + SymmetricKey step2(const BigInt& A); private: std::string hash_id; diff --git a/src/constructs/srp6/srp6_files.cpp b/src/constructs/srp6/srp6_files.cpp new file mode 100644 index 000000000..2d685614f --- /dev/null +++ b/src/constructs/srp6/srp6_files.cpp @@ -0,0 +1,69 @@ +/* +* SRP-6a File Handling +* (C) 2011 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#include <botan/srp6_files.h> +#include <botan/parsing.h> +#include <botan/base64.h> +#include <fstream> + +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<std::string> 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])); + MemoryVector<byte> salt = 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, + MemoryVector<byte>& salt, + std::string& group_id) const + { + std::map<std::string, SRP6_Data>::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/constructs/srp6/srp6_files.h b/src/constructs/srp6/srp6_files.h new file mode 100644 index 000000000..1def0fd51 --- /dev/null +++ b/src/constructs/srp6/srp6_files.h @@ -0,0 +1,53 @@ +/* +* SRP-6a File Handling +* (C) 2011 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#ifndef BOTAN_SRP6A_FILES_H__ +#define BOTAN_SRP6A_FILES_H__ + +#include <botan/bigint.h> +#include <string> +#include <map> + +namespace Botan { + +/** +* A GnuTLS compatible SRP6 authenticator file +*/ +class 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, + MemoryVector<byte>& salt, + std::string& group_id) const; + private: + struct SRP6_Data + { + SRP6_Data() {} + + SRP6_Data(const BigInt& v, + const MemoryRegion<byte>& salt, + const std::string& group_id) : + v(v), salt(salt), group_id(group_id) {} + + BigInt v; + MemoryVector<byte> salt; + std::string group_id; + }; + + std::map<std::string, SRP6_Data> entries; + }; + +} + +#endif |