2013-04-20 12:19:32 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* This file is part of Codecrypt.
|
|
|
|
*
|
|
|
|
* Codecrypt is free software: you can redistribute it and/or modify it
|
|
|
|
* under the terms of the GNU Lesser General Public License as published by
|
|
|
|
* the Free Software Foundation, either version 3 of the License, or (at
|
|
|
|
* your option) any later version.
|
|
|
|
*
|
|
|
|
* Codecrypt is distributed in the hope that it will be useful, but WITHOUT
|
|
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
|
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
|
|
|
* License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Lesser General Public License
|
|
|
|
* along with Codecrypt. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "actions.h"
|
|
|
|
|
2013-04-21 08:00:51 +00:00
|
|
|
#include "iohelpers.h"
|
|
|
|
#include "generator.h"
|
|
|
|
#include "str_match.h"
|
|
|
|
|
2013-04-21 10:47:20 +00:00
|
|
|
#include <list>
|
|
|
|
|
2013-04-20 20:39:51 +00:00
|
|
|
int action_gen_key (const std::string& algspec, const std::string&name,
|
2013-04-21 08:00:51 +00:00
|
|
|
keyring&KR, algorithm_suite&AS)
|
|
|
|
{
|
|
|
|
if (algspec == "help") {
|
|
|
|
//provide overview of algorithms available
|
|
|
|
err ("available algorithms:");
|
|
|
|
std::string tag = " ";
|
|
|
|
for (algorithm_suite::iterator i = AS.begin(), e = AS.end();
|
|
|
|
i != e; ++i) {
|
|
|
|
tag[1] = i->second->provides_signatures() ? 'S' : '-';
|
|
|
|
tag[3] = i->second->provides_encryption() ? 'E' : '-';
|
|
|
|
out (tag << i->first);
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
algorithm*alg = NULL;
|
|
|
|
std::string algname;
|
|
|
|
for (algorithm_suite::iterator i = AS.begin(), e = AS.end();
|
|
|
|
i != e; ++i) {
|
|
|
|
if (algorithm_name_matches (algspec, i->first) ) {
|
|
|
|
if (!alg) {
|
|
|
|
algname = i->first;
|
|
|
|
alg = i->second;
|
|
|
|
} else {
|
|
|
|
err ("error: algorithm name `" << algspec
|
|
|
|
<< "' matches multiple algorithms");
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!alg) {
|
|
|
|
err ("error: no such algorithm");
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!name.length() ) {
|
|
|
|
err ("error: no key name provided");
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
sencode *pub, *priv;
|
|
|
|
arcfour_rng r;
|
|
|
|
|
|
|
|
err ("Gathering random seed bits from kernel...");
|
|
|
|
err ("If nothing happens, move mouse, type random stuff on keyboard,");
|
|
|
|
err ("or just wait longer.");
|
|
|
|
|
|
|
|
r.seed (512, false);
|
|
|
|
|
|
|
|
err ("Seeding done, generating the key...");
|
|
|
|
|
|
|
|
if (alg->create_keypair (&pub, &priv, r) ) {
|
|
|
|
err ("error: key generator failed");
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
KR.store_keypair (keyring::get_keyid (pub), name, algname, pub, priv);
|
|
|
|
|
|
|
|
if (!KR.save() ) {
|
|
|
|
err ("error: couldn't save keyring");
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2013-04-20 20:39:51 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* signatures/encryptions
|
|
|
|
*/
|
|
|
|
|
|
|
|
int action_encrypt (const std::string&recipient, bool armor,
|
2013-04-21 08:00:51 +00:00
|
|
|
keyring&KR, algorithm_suite&AS)
|
2013-04-20 20:39:51 +00:00
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int action_decrypt (bool armor,
|
2013-04-21 08:00:51 +00:00
|
|
|
keyring&KR, algorithm_suite&AS)
|
2013-04-20 20:39:51 +00:00
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int action_sign (const std::string&user, bool armor, const std::string&detach,
|
2013-04-21 08:00:51 +00:00
|
|
|
keyring&KR, algorithm_suite&AS)
|
2013-04-20 20:39:51 +00:00
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int action_verify (bool armor, const std::string&detach,
|
2013-04-21 08:00:51 +00:00
|
|
|
keyring&KR, algorithm_suite&AS)
|
2013-04-20 12:19:32 +00:00
|
|
|
{
|
2013-04-20 20:39:51 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int action_sign_encrypt (const std::string&user, const std::string&recipient,
|
2013-04-21 08:00:51 +00:00
|
|
|
bool armor, keyring&KR, algorithm_suite&AS)
|
2013-04-20 20:39:51 +00:00
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-04-21 08:00:51 +00:00
|
|
|
int action_decrypt_verify (bool armor, keyring&KR, algorithm_suite&AS)
|
2013-04-20 20:39:51 +00:00
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* keyring stuff
|
|
|
|
*/
|
|
|
|
|
2013-04-21 09:05:20 +00:00
|
|
|
static void output_key (bool fp,
|
|
|
|
const std::string& ident, const std::string&longid,
|
|
|
|
const std::string&alg, const std::string&keyid,
|
|
|
|
const std::string&name)
|
|
|
|
{
|
|
|
|
|
|
|
|
if (!fp)
|
|
|
|
out (ident << '\t' << alg << '\t'
|
|
|
|
<< '@' << keyid.substr (0, 22) << "...\t"
|
|
|
|
<< "\"" << name << "\"");
|
|
|
|
else {
|
|
|
|
out ( longid << " with algorithm " << alg
|
|
|
|
<< ", name `" << name << "'");
|
|
|
|
|
|
|
|
std::cout << " fingerprint ";
|
|
|
|
for (size_t j = 0; j < keyid.length(); ++j) {
|
|
|
|
std::cout << keyid[j];
|
|
|
|
if (! ( (j + 1) % 4) &&
|
|
|
|
j < keyid.length() - 1)
|
|
|
|
std::cout << ':';
|
|
|
|
}
|
|
|
|
std::cout << std::endl << std::endl;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-04-20 20:39:51 +00:00
|
|
|
int action_list (bool nice_fingerprint, const std::string&filter,
|
2013-04-21 08:00:51 +00:00
|
|
|
keyring&KR)
|
2013-04-20 20:39:51 +00:00
|
|
|
{
|
2013-04-21 09:05:20 +00:00
|
|
|
for (keyring::keypair_storage::iterator
|
|
|
|
i = KR.pairs.begin(), e = KR.pairs.end();
|
|
|
|
i != e; ++i) {
|
|
|
|
|
|
|
|
if (keyspec_matches (filter, i->second.pub.name, i->first) )
|
|
|
|
|
|
|
|
output_key (nice_fingerprint,
|
|
|
|
"pubkey", "public key in keypair",
|
|
|
|
i->second.pub.alg, i->first,
|
|
|
|
i->second.pub.name);
|
|
|
|
}
|
|
|
|
|
|
|
|
for (keyring::pubkey_storage::iterator
|
|
|
|
i = KR.pubs.begin(), e = KR.pubs.end();
|
|
|
|
i != e; ++i) {
|
|
|
|
if (keyspec_matches (filter, i->second.name, i->first) )
|
|
|
|
output_key (nice_fingerprint,
|
|
|
|
"pubkey", "public key",
|
|
|
|
i->second.alg, i->first,
|
|
|
|
i->second.name);
|
|
|
|
}
|
2013-04-20 20:39:51 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2013-04-20 12:19:32 +00:00
|
|
|
|
2013-04-20 20:39:51 +00:00
|
|
|
int action_import (bool armor, bool no_action, bool yes,
|
|
|
|
const std::string&filter, const std::string&name,
|
2013-04-21 08:00:51 +00:00
|
|
|
keyring&KR)
|
2013-04-20 20:39:51 +00:00
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int action_export (bool armor,
|
|
|
|
const std::string&filter, const std::string&name,
|
2013-04-21 08:00:51 +00:00
|
|
|
keyring&KR)
|
2013-04-20 20:39:51 +00:00
|
|
|
{
|
2013-04-21 10:47:20 +00:00
|
|
|
//TODO
|
2013-04-20 20:39:51 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-04-21 08:00:51 +00:00
|
|
|
int action_delete (bool yes, const std::string&filter, keyring&KR)
|
2013-04-20 20:39:51 +00:00
|
|
|
{
|
2013-04-21 10:47:20 +00:00
|
|
|
int kc = 0;
|
|
|
|
for (keyring::pubkey_storage::iterator
|
|
|
|
i = KR.pubs.begin(), e = KR.pubs.end();
|
|
|
|
i != e; ++i) {
|
|
|
|
if (keyspec_matches (filter, i->second.name, i->first) )
|
|
|
|
++kc;
|
|
|
|
}
|
|
|
|
if (!kc) {
|
|
|
|
err ("no such key");
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
if (kc > 1 && !yes) {
|
|
|
|
bool okay = false;
|
|
|
|
ask_for_yes (okay, "This will delete " << kc
|
|
|
|
<< " pubkeys from your keyring. Continue?");
|
|
|
|
if (!okay) return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
//all clear, delete them
|
|
|
|
std::list<keyring::pubkey_storage::iterator> todel;
|
|
|
|
for (keyring::pubkey_storage::iterator
|
|
|
|
i = KR.pubs.begin(), e = KR.pubs.end();
|
|
|
|
i != e; ++i) {
|
|
|
|
if (keyspec_matches (filter, i->second.name, i->first) )
|
|
|
|
todel.push_back (i);
|
|
|
|
}
|
|
|
|
|
|
|
|
for (std::list<keyring::pubkey_storage::iterator>::iterator
|
|
|
|
i = todel.begin(), e = todel.end(); i != e; ++i)
|
|
|
|
KR.pubs.erase (*i);
|
|
|
|
|
|
|
|
if (!KR.save() ) {
|
|
|
|
err ("error: couldn't save keyring");
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2013-04-20 20:39:51 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int action_rename (bool yes,
|
|
|
|
const std::string&filter, const std::string&name,
|
2013-04-21 08:00:51 +00:00
|
|
|
keyring&KR)
|
2013-04-20 20:39:51 +00:00
|
|
|
{
|
2013-04-21 11:09:13 +00:00
|
|
|
if (name.length() ) {
|
|
|
|
err ("error: missing new name specification");
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
int kc = 0;
|
|
|
|
for (keyring::pubkey_storage::iterator
|
|
|
|
i = KR.pubs.begin(), e = KR.pubs.end();
|
|
|
|
i != e; ++i) {
|
|
|
|
if (keyspec_matches (filter, i->second.name, i->first) )
|
|
|
|
++kc;
|
|
|
|
}
|
|
|
|
if (!kc) {
|
|
|
|
err ("error: no such key");
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
if (kc > 1 && !yes) {
|
|
|
|
bool okay = false;
|
|
|
|
ask_for_yes (okay, "This will rename " << kc
|
|
|
|
<< " pubkeys from your keyring to `"
|
|
|
|
<< name << "'. Continue?");
|
|
|
|
if (!okay) return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
//do the renaming
|
|
|
|
for (keyring::pubkey_storage::iterator
|
|
|
|
i = KR.pubs.begin(), e = KR.pubs.end();
|
|
|
|
i != e; ++i) {
|
|
|
|
if (keyspec_matches (filter, i->second.name, i->first) )
|
|
|
|
i->second.name = name;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!KR.save() ) {
|
|
|
|
err ("error: couldn't save keyring");
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2013-04-20 20:39:51 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int action_list_sec (bool nice_fingerprint, const std::string&filter,
|
2013-04-21 08:00:51 +00:00
|
|
|
keyring&KR)
|
2013-04-20 20:39:51 +00:00
|
|
|
{
|
2013-04-21 08:52:02 +00:00
|
|
|
for (keyring::keypair_storage::iterator
|
|
|
|
i = KR.pairs.begin(), e = KR.pairs.end();
|
|
|
|
i != e; ++i) {
|
|
|
|
|
2013-04-21 09:05:20 +00:00
|
|
|
if (keyspec_matches (filter, i->second.pub.name, i->first) )
|
|
|
|
output_key (nice_fingerprint,
|
|
|
|
"keypair", "key pair",
|
|
|
|
i->second.pub.alg, i->first,
|
|
|
|
i->second.pub.name);
|
2013-04-21 08:52:02 +00:00
|
|
|
}
|
2013-04-20 20:39:51 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int action_import_sec (bool armor, bool no_action, bool yes,
|
|
|
|
const std::string&filter, const std::string&name,
|
2013-04-21 08:00:51 +00:00
|
|
|
keyring&KR)
|
2013-04-20 20:39:51 +00:00
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int action_export_sec (bool armor,
|
|
|
|
const std::string&filter, const std::string&name,
|
2013-04-21 08:00:51 +00:00
|
|
|
keyring&KR)
|
2013-04-20 20:39:51 +00:00
|
|
|
{
|
2013-04-21 10:47:20 +00:00
|
|
|
//TODO
|
2013-04-20 20:39:51 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-04-21 08:00:51 +00:00
|
|
|
int action_delete_sec (bool yes, const std::string&filter, keyring&KR)
|
2013-04-20 20:39:51 +00:00
|
|
|
{
|
2013-04-21 10:47:20 +00:00
|
|
|
int kc = 0;
|
|
|
|
for (keyring::keypair_storage::iterator
|
|
|
|
i = KR.pairs.begin(), e = KR.pairs.end();
|
|
|
|
i != e; ++i) {
|
|
|
|
if (keyspec_matches (filter, i->second.pub.name, i->first) )
|
|
|
|
++kc;
|
|
|
|
}
|
|
|
|
if (!kc) {
|
2013-04-21 11:09:13 +00:00
|
|
|
err ("error: no such key");
|
2013-04-21 10:47:20 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
if (!yes) {
|
|
|
|
bool okay = false;
|
|
|
|
ask_for_yes (okay, "This will delete " << kc
|
|
|
|
<< " secrets from your keyring. Continue?");
|
|
|
|
if (!okay) return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
//all clear, delete them
|
|
|
|
std::list<keyring::keypair_storage::iterator> todel;
|
|
|
|
for (keyring::keypair_storage::iterator
|
|
|
|
i = KR.pairs.begin(), e = KR.pairs.end();
|
|
|
|
i != e; ++i) {
|
|
|
|
if (keyspec_matches (filter, i->second.pub.name, i->first) )
|
|
|
|
todel.push_back (i);
|
|
|
|
}
|
|
|
|
|
|
|
|
for (std::list<keyring::keypair_storage::iterator>::iterator
|
|
|
|
i = todel.begin(), e = todel.end(); i != e; ++i)
|
|
|
|
KR.pairs.erase (*i);
|
|
|
|
|
|
|
|
if (!KR.save() ) {
|
|
|
|
err ("error: couldn't save keyring");
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2013-04-20 20:39:51 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int action_rename_sec (bool yes,
|
|
|
|
const std::string&filter, const std::string&name,
|
2013-04-21 08:00:51 +00:00
|
|
|
keyring&KR)
|
2013-04-20 20:39:51 +00:00
|
|
|
{
|
2013-04-21 11:09:13 +00:00
|
|
|
if (!name.length() ) {
|
|
|
|
err ("error: missing new name specification");
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
int kc = 0;
|
|
|
|
for (keyring::keypair_storage::iterator
|
|
|
|
i = KR.pairs.begin(), e = KR.pairs.end();
|
|
|
|
i != e; ++i) {
|
|
|
|
if (keyspec_matches (filter, i->second.pub.name, i->first) )
|
|
|
|
++kc;
|
|
|
|
}
|
|
|
|
if (!kc) {
|
|
|
|
err ("error: no such key");
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
if (!yes) {
|
|
|
|
bool okay = false;
|
|
|
|
ask_for_yes (okay, "This will rename " << kc
|
|
|
|
<< " secrets from your keyring to `"
|
|
|
|
<< name << "'. Continue?");
|
|
|
|
if (!okay) return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
//do the renaming
|
|
|
|
for (keyring::keypair_storage::iterator
|
|
|
|
i = KR.pairs.begin(), e = KR.pairs.end();
|
|
|
|
i != e; ++i) {
|
|
|
|
if (keyspec_matches (filter, i->second.pub.name, i->first) )
|
|
|
|
i->second.pub.name = name;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!KR.save() ) {
|
|
|
|
err ("error: couldn't save keyring");
|
|
|
|
return 1;
|
|
|
|
}
|
2013-04-20 12:19:32 +00:00
|
|
|
return 0;
|
|
|
|
}
|