Skip to content

Commit

Permalink
feat: Added a command line tool to generate test data
Browse files Browse the repository at this point in the history
  • Loading branch information
macmade committed Nov 12, 2024
1 parent d80c8a4 commit 23beedf
Show file tree
Hide file tree
Showing 6 changed files with 1,743 additions and 800 deletions.
137 changes: 137 additions & 0 deletions SRPXX-Debug/Arguments.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
/*******************************************************************************
* The MIT License (MIT)
*
* Copyright (c) 2024 Jean-David Gadina - www.xs-labs.com
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
******************************************************************************/

#include "Arguments.hpp"
#include <stdexcept>

class Arguments::IMPL
{
public:

IMPL( int argc, const char * argv[] );
IMPL( const IMPL & o );
~IMPL();

std::string _identity;
std::string _password;
SRP::HashAlgorithm _hashAlgorithm;
SRP::Base::GroupType _groupType;
};

Arguments::Arguments( int argc, const char * argv[] ):
impl( std::make_unique< IMPL >( argc, argv ) )
{}

Arguments::Arguments( const Arguments & o ):
impl( std::make_unique< IMPL >( *( o.impl ) ) )
{}

Arguments::~Arguments()
{}

Arguments & Arguments::operator =( Arguments o )
{
swap( *( this ), o );

return *( this );
}

void swap( Arguments & o1, Arguments & o2 )
{
using std::swap;

swap( o1.impl, o2.impl );
}

std::string Arguments::identity() const
{
return this->impl->_identity;
}

std::string Arguments::password() const
{
return this->impl->_password;
}

SRP::HashAlgorithm Arguments::hashAlgorithm() const
{
return this->impl->_hashAlgorithm;
}

SRP::Base::GroupType Arguments::groupType() const
{
return this->impl->_groupType;
}

Arguments::IMPL::IMPL( int argc, const char * argv[] )
{
if( argc != 5 )
{
throw std::runtime_error
(
"Usage: srp <identity> <password> <hash algorithm> <group parameter>\n"
"\n"
" - Supported hash algorithms: sha1 sha224 sha256 sha384 sha512\n"
" - Supported group parameters: 1024 1536 2048 3072 4096 6144 8192"
);
}

this->_identity = argv[ 1 ];
this->_password = argv[ 2 ];

std::string hash = argv[ 3 ];
std::string group = argv[ 4 ];

if( hash == "sha1" ) { this->_hashAlgorithm = SRP::HashAlgorithm::SHA1; }
else if( hash == "sha224" ) { this->_hashAlgorithm = SRP::HashAlgorithm::SHA224; }
else if( hash == "sha256" ) { this->_hashAlgorithm = SRP::HashAlgorithm::SHA256; }
else if( hash == "sha384" ) { this->_hashAlgorithm = SRP::HashAlgorithm::SHA384; }
else if( hash == "sha512" ) { this->_hashAlgorithm = SRP::HashAlgorithm::SHA512; }
else
{
throw std::runtime_error( "Unsupported hash algorithm: " + hash );
}

if( group == "1024" ) { this->_groupType = SRP::Base::GroupType::NG1024; }
else if( group == "1536" ) { this->_groupType = SRP::Base::GroupType::NG1536; }
else if( group == "2048" ) { this->_groupType = SRP::Base::GroupType::NG2048; }
else if( group == "3072" ) { this->_groupType = SRP::Base::GroupType::NG3072; }
else if( group == "4096" ) { this->_groupType = SRP::Base::GroupType::NG4096; }
else if( group == "6144" ) { this->_groupType = SRP::Base::GroupType::NG6144; }
else if( group == "8192" ) { this->_groupType = SRP::Base::GroupType::NG8192; }
else
{
throw std::runtime_error( "Unsupported group parameter: " + group );
}
}

Arguments::IMPL::IMPL( const IMPL & o ):
_identity( o._identity ),
_password( o._password ),
_hashAlgorithm( o._hashAlgorithm ),
_groupType( o._groupType )
{}

Arguments::IMPL::~IMPL()
{}
51 changes: 51 additions & 0 deletions SRPXX-Debug/Arguments.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*******************************************************************************
* The MIT License (MIT)
*
* Copyright (c) 2024 Jean-David Gadina - www.xs-labs.com
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
******************************************************************************/

#include <SRPXX.hpp>
#include <memory>
#include <algorithm>

class Arguments
{
public:

Arguments( int argc, const char * argv[] );
Arguments( const Arguments & o );
~Arguments();

Arguments & operator =( Arguments o );

friend void swap( Arguments & o1, Arguments & o2 );

std::string identity() const;
std::string password() const;
SRP::HashAlgorithm hashAlgorithm() const;
SRP::Base::GroupType groupType() const;

private:

class IMPL;

std::unique_ptr< IMPL > impl;
};
171 changes: 171 additions & 0 deletions SRPXX-Debug/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
/*******************************************************************************
* The MIT License (MIT)
*
* Copyright (c) 2024 Jean-David Gadina - www.xs-labs.com
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
******************************************************************************/

#include <iostream>
#include <iomanip>
#include <sstream>
#include <stdexcept>
#include <string>
#include <cstdlib>
#include <SRPXX.hpp>
#include "Arguments.hpp"

static std::string stringFromHashAlgorithm( SRP::HashAlgorithm algorithm );
static std::string stringFromGroupType( SRP::Base::GroupType groupType );
static std::string stringFromString( const std::string & string );
static std::string stringFromBigNum( const std::string & name, const SRP::BigNum & number );
static std::string stringFromData( const std::string & name, const std::vector< uint8_t > & data );

int main( int argc, const char * argv[] )
{
try
{
Arguments args( argc, argv );
std::vector< uint8_t > salt;
std::vector< uint8_t > verifier;

{
SRP::Client client( args.identity(), args.hashAlgorithm(), args.groupType() );

client.setPassword( args.password() );
client.setSalt( SRP::Random::bytes( 16 ) );

salt = client.salt();
verifier = client.v().bytes( SRP::BigNum::Endianness::BigEndian );
}

{
SRP::Client client( args.identity(), args.hashAlgorithm(), args.groupType() );
SRP::Server server( args.identity(), args.hashAlgorithm(), args.groupType() );

server.setSalt( salt );
server.setV( SRP::BigNum( verifier, SRP::BigNum::Endianness::BigEndian ) );
server.setA( client.A() );
client.setB( server.B() );
client.setSalt( server.salt() );
client.setPassword( args.password() );

if( client.M1() != server.M1() || client.M2() != server.M2() )
{
throw std::runtime_error( "Invalid M1/M2" );
}

std::cout << stringFromHashAlgorithm( args.hashAlgorithm() ) << "," << std::endl;
std::cout << stringFromGroupType( args.groupType() ) << "," << std::endl;
std::cout << stringFromString( args.identity() ) << "," << std::endl;
std::cout << stringFromString( args.password() ) << "," << std::endl;
std::cout << stringFromData( "Salt", salt ) << "," << std::endl;
std::cout << stringFromData( "Verifier", verifier ) << "," << std::endl;
std::cout << stringFromBigNum( "a", client.a() ) << "," << std::endl;
std::cout << stringFromBigNum( "A", client.A() ) << "," << std::endl;
std::cout << stringFromBigNum( "b", server.b() ) << "," << std::endl;
std::cout << stringFromBigNum( "B", server.B() ) << "," << std::endl;
std::cout << stringFromBigNum( "u", client.u() ) << "," << std::endl;
std::cout << stringFromBigNum( "k", client.k() ) << "," << std::endl;
std::cout << stringFromBigNum( "S", client.S() ) << "," << std::endl;
std::cout << stringFromBigNum( "x", client.x() ) << "," << std::endl;
std::cout << stringFromData( "K", client.K() ) << "," << std::endl;
std::cout << stringFromData( "M1", client.M1() ) << "," << std::endl;
std::cout << stringFromData( "M2", client.M2() ) << std::endl;
}
}
catch( const std::exception & e )
{
std::cout << e.what() << std::endl;

return EXIT_FAILURE;
}

return EXIT_SUCCESS;
}

static std::string stringFromHashAlgorithm( SRP::HashAlgorithm algorithm )
{
switch( algorithm )
{
case SRP::HashAlgorithm::SHA1: return "SRP::HashAlgorithm::SHA1";
case SRP::HashAlgorithm::SHA224: return "SRP::HashAlgorithm::SHA224";
case SRP::HashAlgorithm::SHA256: return "SRP::HashAlgorithm::SHA256";
case SRP::HashAlgorithm::SHA384: return "SRP::HashAlgorithm::SHA384";
case SRP::HashAlgorithm::SHA512: return "SRP::HashAlgorithm::SHA512";
}
}

static std::string stringFromGroupType( SRP::Base::GroupType groupType )
{
switch( groupType )
{
case SRP::Base::GroupType::NG1024: return "SRP::Base::GroupType::NG1024";
case SRP::Base::GroupType::NG1536: return "SRP::Base::GroupType::NG1536";
case SRP::Base::GroupType::NG2048: return "SRP::Base::GroupType::NG2048";
case SRP::Base::GroupType::NG3072: return "SRP::Base::GroupType::NG3072";
case SRP::Base::GroupType::NG4096: return "SRP::Base::GroupType::NG4096";
case SRP::Base::GroupType::NG6144: return "SRP::Base::GroupType::NG6144";
case SRP::Base::GroupType::NG8192: return "SRP::Base::GroupType::NG8192";
}
}

static std::string stringFromString( const std::string & string )
{
return "\"" + string + "\"";
}

static std::string stringFromBigNum( const std::string & name, const SRP::BigNum & number )
{
return stringFromData( name, number.bytes( SRP::BigNum::Endianness::BigEndian ) );
}

static std::string stringFromData( const std::string & name, const std::vector< uint8_t > & data )
{
std::stringstream ss;

ss << "{" << std::endl;
ss << " /* " << name << " */" << std::endl;

for( size_t i = 0; i < data.size(); i++ )
{
if( i == 0 || ( i + 1 ) % 16 == 1 )
{
ss << " ";
}

ss << "0x" << std::uppercase << std::hex << std::setw( 2 ) << std::setfill( '0' ) << static_cast< unsigned int >( data[ i ] );

if( i != ( data.size() - 1 ) )
{
if( ( i + 1 ) % 16 == 0 )
{
ss << "," << std::endl;
}
else
{
ss << ", ";
}
}
}

ss << std::endl << "}";

return ss.str();
}
Loading

0 comments on commit 23beedf

Please sign in to comment.