/
main.cpp
145 lines (123 loc) · 3.34 KB
/
main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
#include <iostream>
#include <cstdio>
#include <stdlib.h>
#include "getpass.h"
#include "program_options.h"
#include "curvedsalsa.h"
namespace po = boost::program_options;
bool quiet;
std::string prompt_password( const std::string &what, bool hidden = false )
{
std::string pw;
std::cerr << "Please enter " << what << ": ";
if( hidden == true )
{
char *pass = getpass( "" );
pw = pass;
free( pass );
}
else
{
getline( std::cin, pw, '\n' );
}
return pw;
}
int main( int argc, char *argv[] )
{
std::string inputfile = "";
std::string outputfile = "";
std::string passphrase = "";
std::string publicKey = "";
bool encrypt = false,
decrypt = false,
keygen = false;
// set up command line options and
// check for help requests and usage errors
po::variables_map var_map;
try
{
init_program_options(argc, argv, &var_map);
}
catch( po::multiple_occurrences m )
{
std::cerr << "Error: Please use each options at most once."
<< std::endl << std::endl;
print_usage( argv[0] );
exit( 2 );
}
catch( ... )
{
std::cerr << "Error: unknown error in command line options."
<< std::endl << std::endl;
print_usage( argv[0] );
exit( 2 );
}
// no options -> print usage message
if( argc == 1 )
{
print_usage( argv[0] );
exit( 1 );
}
// check command line options
if( var_map.count("test") > 0 )
{
exit( run_tests() );
}
encrypt = (var_map.count("encrypt") > 0);
decrypt = (var_map.count("decrypt") > 0);
keygen = (var_map.count("create-key") > 0);
// check that the user only request one out of decrypt/encrypt/keygen
if( (int)decrypt + (int)encrypt + (int)keygen > 1 )
{
std::cerr << "You need to chose one of encrypt, decrypt and key-gen."
<< std::endl << std::endl;
print_usage( argv[0] );
exit( 2 );
}
if (var_map.count("pass") > 0) passphrase = var_map["pass"].as<std::string>();
if (var_map.count("input") > 0) inputfile = var_map["input"].as<std::string>();
if (var_map.count("output") > 0) outputfile = var_map["output"].as<std::string>();
if (var_map.count("key") > 0) publicKey = var_map["key"].as<std::string>();
quiet = (var_map.count("quiet") > 0);
// here comes the program logic
if( keygen )
{
if( passphrase == "" )
passphrase = prompt_password( "passphrase", true );
uint8_t publicKey[32];
if( generate_key( publicKey, passphrase ) )
std::cerr << "Public key: " << b64encode( publicKey );
else
std::cerr << "Failed to generate public key" << std::endl;
}
else if( encrypt )
{
if( inputfile == "" && publicKey == "" )
{
std::cerr << "Error: Public key needs to be given on "
<< "commandline when encrypting from stdin" << std::endl;
exit( 1 );
}
if( publicKey == "" )
publicKey = prompt_password( "public key" );
encryptFile( outputfile, inputfile, passphrase, publicKey );
}
else if( decrypt )
{
if( inputfile == "" && passphrase == "" )
{
std::cerr << "Error: passphrase needs to be given on "
<< "commandline when decrypting from stdin" << std::endl;
exit( 1 );
}
if( passphrase == "" )
passphrase = prompt_password( "passphrase", true );
decryptFile( outputfile, inputfile, passphrase );
}
else
{
print_usage( argv[0] );
exit( 0 );
}
return 0;
}