2022-05-17 01:13:42 +02:00
#include "CommandlineInterface.h"
#include <iostream>
#include <sstream>
#include <GCrypt/Version.h>
2022-05-26 21:32:04 +02:00
#include <GCrypt/Block.h>
2022-05-17 01:13:42 +02:00
#include "Version.h"
using namespace Hazelnp ;
2022-05-26 21:32:04 +02:00
using namespace Leonetienne :: GCrypt ;
2022-05-17 01:13:42 +02:00
2022-05-26 21:32:04 +02:00
void CommandlineInterface :: Init ( int argc , const char * const * argv ) {
2022-05-17 01:13:42 +02:00
/* General information */
std :: stringstream ss ;
2022-05-26 20:19:15 +02:00
ss << "CLI for the GCrypt cipher/obfuscator" << std :: endl
2022-05-17 01:13:42 +02:00
<< "Copyright (c) 2022 Leon Etienne" << std :: endl
2022-05-26 20:19:15 +02:00
<< "GCrypt v" << GCRYPT_VERSION << std :: endl
<< "GCrypt CLI v" << GCRYPTCLI_VERSION << std :: endl
2022-05-17 01:13:42 +02:00
<< "THIS IS EXPERIMENTAL SOFTWARE AND MUST BE CONSIDERED INSECURE. DO NOT USE THIS TO ENCRYPT SENSITIVE DATA! READ THE README FILES ACCESSIBLE AT \" https://gitea.leonetienne.de/leonetienne/GCrypt \" " ;
nupp . SetBriefDescription ( ss . str ());
ss . str ( "" );
nupp . SetCatchHelp ( "true" );
nupp . SetCrashOnFail ( "true" );
/* Builtin documentation */
2022-05-26 21:32:04 +02:00
nupp . RegisterDescription ( "--encrypt" , "Use the encryption module." );
2022-05-17 01:13:42 +02:00
nupp . RegisterConstraint ( "--encrypt" , ParamConstraint ( true , DATA_TYPE :: VOID , {}, false , { "--decrypt" , "--hash" }));
nupp . RegisterAbbreviation ( "-e" , "--encrypt" );
2022-05-26 21:32:04 +02:00
nupp . RegisterDescription ( "--decrypt" , "Use decryption module." );
2022-05-27 17:17:43 +02:00
nupp . RegisterConstraint ( "--decrypt" , ParamConstraint ( true , DATA_TYPE :: VOID , {}, false , { "--encrypt" , "--hash" , "--generate-key" }));
2022-05-17 01:13:42 +02:00
nupp . RegisterAbbreviation ( "-d" , "--decrypt" );
2022-05-26 21:32:04 +02:00
nupp . RegisterDescription ( "--hash" , "Use the GHash hash module to calculate a hashsum." );
2022-05-27 17:17:43 +02:00
nupp . RegisterConstraint ( "--hash" , ParamConstraint ( true , DATA_TYPE :: VOID , {}, false , { "--encrypt" , "--decrypt" , "--generate-key" }));
2022-05-17 01:13:42 +02:00
nupp . RegisterAbbreviation ( "-h" , "--hash" );
2022-05-27 17:17:43 +02:00
nupp . RegisterDescription ( "--generate-key" , "Use the key generation module. Will generate a random key based on hardware events, output it, and exit." );
nupp . RegisterConstraint ( "--generate-key" , ParamConstraint ( true , DATA_TYPE :: VOID , {}, false , { "--encrypt" , "--decrypt" , "--hash" }));
2022-05-26 20:19:15 +02:00
nupp . RegisterDescription ( "--intext" , "Encrypt this string." );
2022-05-17 01:13:42 +02:00
nupp . RegisterConstraint ( "--intext" , ParamConstraint ( true , DATA_TYPE :: STRING , {}, false , { "--infile" }));
nupp . RegisterAbbreviation ( "-it" , "--intext" );
2022-05-26 20:19:15 +02:00
nupp . RegisterDescription ( "--infile" , "Encrypt this file." );
2022-05-17 01:13:42 +02:00
nupp . RegisterConstraint ( "--infile" , ParamConstraint ( true , DATA_TYPE :: STRING , {}, false , { "--intext" }));
nupp . RegisterAbbreviation ( "-if" , "--infile" );
2022-05-26 20:19:15 +02:00
nupp . RegisterDescription ( "--ofile" , "Write output in this file." );
2022-05-17 01:13:42 +02:00
nupp . RegisterConstraint ( "--ofile" , ParamConstraint ( true , DATA_TYPE :: STRING , {}, false , { "--ostdout" , "--hash" }));
nupp . RegisterAbbreviation ( "-of" , "--ofile" );
nupp . RegisterAbbreviation ( "-o" , "--ofile" );
nupp . RegisterDescription ( "--key" , "Use this value as a password to extrapolate the encryption key. WARNING: Arguments may be logged by the system!" );
nupp . RegisterConstraint ( "--key" , ParamConstraint ( true , DATA_TYPE :: STRING , {}, false , { "--keyfile" , "--keyask" , "--hash" }));
nupp . RegisterAbbreviation ( "-k" , "--key" );
2022-05-26 21:32:04 +02:00
ss << "Read in the first {KEYSIZE}(=" << Block :: BLOCK_SIZE_BITS << ") bits of this file and use that as an encryption key. WARNING: Arguments may be logged by the system!" ;
2022-05-17 01:13:42 +02:00
nupp . RegisterDescription ( "--keyfile" , ss . str ());
ss . str ( "" );
nupp . RegisterConstraint ( "--keyfile" , ParamConstraint ( true , DATA_TYPE :: STRING , {}, false , { "--key" , "--keyask" , "--hash" }));
nupp . RegisterAbbreviation ( "-kf" , "--keyfile" );
nupp . RegisterDescription ( "--keyask" , "Read the encryption key from stdin." );
nupp . RegisterConstraint ( "--keyask" , ParamConstraint ( true , DATA_TYPE :: VOID , {}, false , { "--key" , "--keyfile" , "--hash" }));
nupp . RegisterAbbreviation ( "-ka" , "--keyask" );
nupp . RegisterDescription ( "--progress" , "Print digestion progress to stdout. May be advisable for large files, as the cipher is rather slow." );
nupp . RegisterConstraint ( "--progress" , ParamConstraint ( true , DATA_TYPE :: VOID , {}, false , {}));
nupp . RegisterAbbreviation ( "-p" , "--progress" );
2022-05-26 20:19:15 +02:00
nupp . RegisterDescription ( "--iobase-bytes" , "Interpret and output ciphertexts as raw bytes." );
nupp . RegisterConstraint ( "--iobase-bytes" , ParamConstraint ( true , DATA_TYPE :: VOID , {}, false , { "--iobase-2" , "--iobase-8" , "--iobase-10" , "--iobase-16" , "--iobase-64" , "--iobase-uwu" , "--iobase-ugh" }));
2022-05-17 01:13:42 +02:00
nupp . RegisterDescription ( "--iobase-2" , "Interpret and format ciphertexts in base2" );
2022-05-26 21:32:04 +02:00
nupp . RegisterConstraint ( "--iobase-2" , ParamConstraint ( true , DATA_TYPE :: VOID , {}, false , { "--iobase-bytes" , "--iobase-8" , "--iobase-10" , "--iobase-16" , "--iobase-64" , "--iobase-uwu" , "--iobase-ugh" }));
2022-05-17 01:13:42 +02:00
nupp . RegisterDescription ( "--iobase-8" , "Interpret and format ciphertexts in base8" );
2022-05-26 21:32:04 +02:00
nupp . RegisterConstraint ( "--iobase-8" , ParamConstraint ( true , DATA_TYPE :: VOID , {}, false , { "--iobase-bytes" , "--iobase-2" , "--iobase-10" , "--iobase-16" , "--iobase-64" , "--iobase-uwu" , "--iobase-ugh" }));
2022-05-17 01:13:42 +02:00
nupp . RegisterDescription ( "--iobase-10" , "Interpret and format ciphertexts in base10" );
2022-05-26 21:32:04 +02:00
nupp . RegisterConstraint ( "--iobase-10" , ParamConstraint ( true , DATA_TYPE :: VOID , {}, false , { "--iobase-bytes" , "--iobase-2" , "--iobase-8" , "--iobase-16" , "--iobase-64" , "--iobase-uwu" , "--iobase-ugh" }));
2022-05-26 20:19:15 +02:00
nupp . RegisterDescription ( "--iobase-16" , "Interpret and format ciphertexts in base16 (hex)" );
nupp . RegisterConstraint ( "--iobase-16" , ParamConstraint ( true , DATA_TYPE :: VOID , {}, false , { "--iobase-bytes" , "--iobase-2" , "--iobase-8" , "--iobase-64" , "--iobase-uwu" , "--iobase-ugh" }));
2022-05-17 01:13:42 +02:00
nupp . RegisterDescription ( "--iobase-64" , "Interpret and format ciphertexts in base64" );
2022-05-26 21:32:04 +02:00
nupp . RegisterConstraint ( "--iobase-64" , ParamConstraint ( true , DATA_TYPE :: VOID , {}, false , { "--iobase-bytes" , "--iobase-2" , "--iobase-8" , "--iobase-10" , "--iobase-16" , "--iobase-uwu" , "--iobase-ugh" }));
2022-05-17 01:13:42 +02:00
nupp . RegisterDescription ( "--iobase-uwu" , "Interpret and format ciphertexts in base uwu" );
2022-05-26 21:32:04 +02:00
nupp . RegisterConstraint ( "--iobase-uwu" , ParamConstraint ( true , DATA_TYPE :: VOID , {}, false , { "--iobase-bytes" , "--iobase-2" , "--iobase-8" , "--iobase-10" , "--iobase-16" , "--iobase-64" , "--iobase-ugh" }));
2022-05-17 01:13:42 +02:00
nupp . RegisterDescription ( "--iobase-ugh" , "Interpret and format ciphertexts in base ugh" );
2022-05-26 21:32:04 +02:00
nupp . RegisterConstraint ( "--iobase-ugh" , ParamConstraint ( true , DATA_TYPE :: VOID , {}, false , { "--iobase-bytes" , "--iobase-2" , "--iobase-8" , "--iobase-10" , "--iobase-16" , "--iobase-64" , "--iobase-uwu" }));
2022-05-17 01:13:42 +02:00
2022-05-26 20:19:15 +02:00
nupp . RegisterDescription ( "--lib-version" , "Will supply the version of GCryptLib used." );
nupp . RegisterConstraint ( "--lib-version" , ParamConstraint ( true , DATA_TYPE :: VOID , {}, false , {}));
2022-05-17 01:13:42 +02:00
2022-05-26 20:19:15 +02:00
nupp . RegisterDescription ( "--cli-version" , "Will supply the version of GCryptCLI used." );
2022-05-17 01:13:42 +02:00
nupp . RegisterConstraint ( "--cli-version" , ParamConstraint ( true , DATA_TYPE :: VOID , {}, false , {}));
2022-05-26 20:19:15 +02:00
nupp . RegisterAbbreviation ( "-v" , "--cli-version" );
nupp . RegisterDescription ( "--puffer-input" , "Will read the entire input before beginning any digestion." );
nupp . RegisterConstraint ( "--puffer-input" , ParamConstraint ( true , DATA_TYPE :: VOID , {}, false , {}));
nupp . RegisterDescription ( "--puffer-output" , "Will digest the entire data before initiating any output." );
nupp . RegisterConstraint ( "--puffer-output" , ParamConstraint ( true , DATA_TYPE :: VOID , {}, false , {}));
2022-05-17 01:13:42 +02:00
/* Now parse */
nupp . Parse ( argc , argv );
CatchVersionQueries ();
SpecialCompatibilityChecking ();
return ;
}
2022-05-26 21:32:04 +02:00
Hazelnp :: CmdArgsInterface & CommandlineInterface :: Get () {
2022-05-17 01:13:42 +02:00
return nupp ;
}
2022-05-26 21:32:04 +02:00
void CommandlineInterface :: SpecialCompatibilityChecking () {
// Active module
// Do we have EITHER --encrypt or --decrypt or --hash?
if (
2022-05-27 17:17:43 +02:00
( ! nupp . HasParam ( "--generate-key" )) &&
2022-05-26 21:32:04 +02:00
( ! nupp . HasParam ( "--hash" )) &&
( ! nupp . HasParam ( "--encrypt" )) &&
( ! nupp . HasParam ( "--decrypt" ))
) {
2022-05-27 17:17:43 +02:00
CrashWithMsg ( "No module supplied! Please supply either --encrypt, --decrypt, --hash, or --generate-key!" );
2022-05-26 21:32:04 +02:00
}
2022-05-17 01:13:42 +02:00
// Encryption key
2022-05-27 17:17:43 +02:00
// Do we have EITHER --hash (no key required), --generate-key (no key required), --key, --keyask or --keyfile given?
2022-05-17 01:13:42 +02:00
if (
( ! nupp . HasParam ( "--hash" )) &&
2022-05-27 17:17:43 +02:00
( ! nupp . HasParam ( "--generate-key" )) &&
2022-05-17 01:13:42 +02:00
( ! nupp . HasParam ( "--key" )) &&
( ! nupp . HasParam ( "--keyfile" )) &&
( ! nupp . HasParam ( "--keyask" ))
2022-05-26 21:32:04 +02:00
) {
2022-05-17 01:13:42 +02:00
CrashWithMsg ( "No encryption key supplied! Please supply either --key, --keyfile, or --keyask!" );
2022-05-26 21:32:04 +02:00
}
2022-05-17 01:13:42 +02:00
2022-05-26 21:32:04 +02:00
// Check that, if supplied, filename strings are not empty.
2022-05-17 01:13:42 +02:00
if (
2022-05-26 21:32:04 +02:00
( nupp . HasParam ( "--ofile" )) &&
( nupp [ "--ofile" ]. GetString (). length () == 0 )
) {
CrashWithMsg ( "Length of --ofile is zero! That can't be a valid path!" );
}
if (
( nupp . HasParam ( "--ifile" )) &&
( nupp [ "--ifile" ]. GetString (). length () == 0 )
) {
CrashWithMsg ( "Length of --ifile is zero! That can't be a valid path!" );
}
if (
( nupp . HasParam ( "--keyfile" )) &&
( nupp [ "--keyfile" ]. GetString (). length () == 0 )
) {
CrashWithMsg ( "Length of --keyfile is zero! That can't be a valid path!" );
}
2022-05-17 01:13:42 +02:00
return ;
}
2022-05-26 21:32:04 +02:00
void CommandlineInterface :: CrashWithMsg ( const std :: string & msg ) {
2022-05-17 01:13:42 +02:00
std :: cerr
<< nupp . GetBriefDescription ()
<< std :: endl
<< "Fatal error! Unable to continue! More information:" << std :: endl
<< msg << std :: endl ;
exit ( - 1 );
}
2022-05-26 21:32:04 +02:00
void CommandlineInterface :: CatchVersionQueries () {
2022-05-26 20:19:15 +02:00
if (
( nupp . HasParam ( "--version" )) ||
2022-05-26 21:32:04 +02:00
( nupp . HasParam ( "--cli-version" ))
2022-05-26 20:19:15 +02:00
) {
std :: cout << GCRYPTCLI_VERSION << std :: endl ;
2022-05-17 01:13:42 +02:00
exit ( 0 );
}
2022-05-26 20:19:15 +02:00
else if ( nupp . HasParam ( "--lib-version" ))
2022-05-17 01:13:42 +02:00
{
2022-05-26 20:19:15 +02:00
std :: cout << GCRYPT_VERSION << std :: endl ;
2022-05-17 01:13:42 +02:00
exit ( 0 );
}
return ;
}
CmdArgsInterface CommandlineInterface :: nupp ;