keyring: detach keyring parsing/serialization

for later usage in exports/imports
This commit is contained in:
Mirek Kratochvil 2013-04-18 11:53:50 +02:00
parent 287a2bbac0
commit e5cff75177
2 changed files with 162 additions and 113 deletions

View file

@ -20,17 +20,8 @@
void keyring::clear() void keyring::clear()
{ {
for (std::map<std::string, pubkey_entry>::iterator clear_keypairs (pairs);
i = pubs.begin(), e = pubs.end(); i != e; ++i) clear_pubkeys (pubs);
sencode_destroy (i->second.key);
pubs.clear();
for (std::map<std::string, keypair_entry>::iterator
i = pairs.begin(), e = pairs.end(); i != e; ++i) {
sencode_destroy (i->second.pub.key);
sencode_destroy (i->second.privkey);
}
pairs.clear();
} }
/* /*
@ -97,8 +88,141 @@ std::string keyring::get_keyid (const std::string&pubkey)
* ... * ...
* ) * )
* *
* --------
* Serialization stuff first.
*/ */
void keyring::clear_keypairs (keypair_storage&pairs)
{
for (std::map<std::string, keypair_entry>::iterator
i = pairs.begin(), e = pairs.end(); i != e; ++i) {
sencode_destroy (i->second.pub.key);
sencode_destroy (i->second.privkey);
}
pairs.clear();
}
void keyring::clear_pubkeys (pubkey_storage&pubs)
{
for (std::map<std::string, pubkey_entry>::iterator
i = pubs.begin(), e = pubs.end(); i != e; ++i)
sencode_destroy (i->second.key);
pubs.clear();
}
bool keyring::parse_keypairs (sencode*keypairs, keypair_storage&pairs)
{
clear_keypairs (pairs);
sencode_list *L = dynamic_cast<sencode_list*> (keypairs);
if (!L) goto failure;
for (std::vector<sencode*>::iterator
i = L->items.begin(), e = L->items.end();
i != e; ++i) {
sencode_list*entry = dynamic_cast<sencode_list*> (*i);
if (!entry) goto failure;
if (entry->items.size() != 3) goto failure;
sencode_bytes
*ident = dynamic_cast<sencode_bytes*> (entry->items[0]),
*privkey = dynamic_cast<sencode_bytes*> (entry->items[1]),
*pubkey = dynamic_cast<sencode_bytes*> (entry->items[2]);
if (! (ident && privkey && pubkey) ) goto failure;
std::string keyid = get_keyid (pubkey->b);
sencode *priv, *pub;
if (!sencode_decode (privkey->b, &priv) )
goto failure;
if (!sencode_decode (pubkey->b, &pub) ) {
sencode_destroy (priv);
goto failure;
}
pairs[keyid] = keypair_entry (keyid, ident->b, pub, priv);
}
return true;
failure:
clear_keypairs (pairs);
return false;
}
sencode* keyring::serialize_keypairs (const keypair_storage&pairs)
{
sencode_list*L = new sencode_list();
for (keypair_storage::const_iterator
i = pairs.begin(), e = pairs.end();
i != e; ++i) {
sencode_list*a = new sencode_list;
a->items.resize (3);
a->items[0] = new sencode_bytes (i->second.pub.name);
a->items[1] = new sencode_bytes (i->second.privkey->encode() );
a->items[2] = new sencode_bytes (i->second.pub.key->encode() );
L->items.push_back (a);
}
return L;
}
bool keyring::parse_pubkeys (sencode* pubkeys, pubkey_storage&pubs)
{
clear_pubkeys (pubs);
sencode_list* L = dynamic_cast<sencode_list*> (pubkeys);
if (!L) goto failure;
for (std::vector<sencode*>::iterator
i = L->items.begin(), e = L->items.end();
i != e; ++i) {
sencode_list*entry = dynamic_cast<sencode_list*> (*i);
if (!entry) goto failure;
if (entry->items.size() != 2) goto failure;
sencode_bytes
*ident = dynamic_cast<sencode_bytes*> (entry->items[0]),
*pubkey = dynamic_cast<sencode_bytes*> (entry->items[1]);
if (! (ident && pubkey) ) goto failure;
std::string keyid = get_keyid (pubkey->b);
sencode*key;
if (!sencode_decode (pubkey->b, &key) )
goto failure;
pubs[keyid] = pubkey_entry (keyid, ident->b, key);
}
return true;
failure:
clear_pubkeys (pubs);
return false;
}
sencode* keyring::serialize_pubkeys (const pubkey_storage&pubs)
{
sencode_list*L = new sencode_list();
for (pubkey_storage::const_iterator
i = pubs.begin(), e = pubs.end();
i != e; ++i) {
sencode_list*a = new sencode_list();
a->items.resize (2);
a->items[0] = new sencode_bytes (i->second.name);
a->items[1] = new sencode_bytes (i->second.key->encode() );
L->items.push_back (a);
}
return L;
}
/*
* OS/disk functions
*/
#include <stdlib.h> #include <stdlib.h>
static std::string get_user_dir() static std::string get_user_dir()
@ -221,7 +345,7 @@ bool keyring::load()
{ {
std::string dir = get_user_dir(); std::string dir = get_user_dir();
std::string fn; std::string fn;
sencode_list*L; bool res;
/* /*
* pubkeys loading * pubkeys loading
@ -231,93 +355,31 @@ bool keyring::load()
if (!file_get_sencode (fn, &pubkeys) ) if (!file_get_sencode (fn, &pubkeys) )
return false; return false;
L = dynamic_cast<sencode_list*> (pubkeys); res = parse_pubkeys (pubkeys, pubs);
if (!L) goto pubkeys_fail;
//parse all pubkey entries
for (std::vector<sencode*>::iterator
i = L->items.begin(), e = L->items.end();
i != e; ++i) {
sencode_list*entry = dynamic_cast<sencode_list*> (*i);
if (!entry) goto pubkeys_fail;
if (entry->items.size() != 2) goto pubkeys_fail;
sencode_bytes
*ident = dynamic_cast<sencode_bytes*> (entry->items[0]),
*pubkey = dynamic_cast<sencode_bytes*> (entry->items[1]);
if (! (ident && pubkey) ) goto pubkeys_fail;
std::string keyid = get_keyid (pubkey->b);
sencode*key;
if (!sencode_decode (pubkey->b, &key) )
goto pubkeys_fail;
pubs[keyid] = pubkey_entry (keyid, ident->b, key);
}
sencode_destroy (pubkeys); sencode_destroy (pubkeys);
if (!res) return false;
/* /*
* keypairs loading * keypairs loading
*/ */
fn = dir + SECRETS_FILENAME; fn = dir + SECRETS_FILENAME;
sencode*keypairs; sencode*keypairs;
if (!file_get_sencode (fn, &keypairs) ) if (!file_get_sencode (fn, &keypairs) )
return false; return false;
L = dynamic_cast<sencode_list*> (keypairs); res = parse_keypairs (keypairs, pairs);
if (!L) goto keypairs_fail;
//entries
for (std::vector<sencode*>::iterator
i = L->items.begin(), e = L->items.end();
i != e; ++i) {
sencode_list*entry = dynamic_cast<sencode_list*> (*i);
if (!entry) goto keypairs_fail;
if (entry->items.size() != 3) goto keypairs_fail;
sencode_bytes
*ident = dynamic_cast<sencode_bytes*> (entry->items[0]),
*privkey = dynamic_cast<sencode_bytes*> (entry->items[1]),
*pubkey = dynamic_cast<sencode_bytes*> (entry->items[2]);
if (! (ident && privkey && pubkey) ) goto keypairs_fail;
std::string keyid = get_keyid (pubkey->b);
sencode *priv, *pub;
if (!sencode_decode (privkey->b, &priv) )
goto keypairs_fail;
if (!sencode_decode (pubkey->b, &pub) ) {
sencode_destroy (priv);
goto keypairs_fail;
}
pairs[keyid] = keypair_entry (keyid, ident->b, pub, priv);
}
sencode_destroy (keypairs); sencode_destroy (keypairs);
if (!res) return false;
//all okay
return true; return true;
pubkeys_fail:
sencode_destroy (pubkeys);
return false;
keypairs_fail:
sencode_destroy (keypairs);
return false;
} }
bool keyring::save() bool keyring::save()
{ {
std::string dir, fn; std::string dir, fn;
sencode_list*L; sencode*S;
bool res; bool res;
dir = get_user_dir(); dir = get_user_dir();
@ -325,43 +387,19 @@ bool keyring::save()
/* /*
* pubkeys * pubkeys
*/ */
L = new sencode_list(); S = serialize_pubkeys (pubs);
for (std::map<std::string, pubkey_entry>::iterator
i = pubs.begin(), e = pubs.end();
i != e; ++i) {
sencode_list*a = new sencode_list();
a->items.resize (2);
a->items[0] = new sencode_bytes (i->second.name);
a->items[1] = new sencode_bytes (i->second.key->encode() );
L->items.push_back (a);
}
//save them
fn = dir + PUBKEYS_FILENAME; fn = dir + PUBKEYS_FILENAME;
res = file_put_sencode (fn, L); res = file_put_sencode (fn, S);
sencode_destroy (L); sencode_destroy (S);
if (!res) return false; if (!res) return false;
/* /*
* keypairs * keypairs
*/ */
S = serialize_keypairs (pairs);
L = new sencode_list();
for (std::map<std::string, keypair_entry>::iterator
i = pairs.begin(), e = pairs.end();
i != e; ++i) {
sencode_list*a = new sencode_list;
a->items.resize (3);
a->items[0] = new sencode_bytes (i->second.pub.name);
a->items[1] = new sencode_bytes (i->second.privkey->encode() );
a->items[2] = new sencode_bytes (i->second.pub.key->encode() );
L->items.push_back (a);
}
//save
fn = dir + SECRETS_FILENAME; fn = dir + SECRETS_FILENAME;
res = file_put_sencode (fn, L); res = file_put_sencode (fn, S);
sencode_destroy (L); sencode_destroy (S);
if (!res) return false; if (!res) return false;
return true; return true;

View file

@ -62,8 +62,11 @@ public:
} }
}; };
std::map<std::string, pubkey_entry> pubs; typedef std::map<std::string, pubkey_entry> pubkey_storage;
std::map<std::string, keypair_entry> pairs; typedef std::map<std::string, keypair_entry> keypair_storage;
pubkey_storage pubs;
keypair_storage pairs;
keyring() { keyring() {
lockfd = -1; lockfd = -1;
@ -86,6 +89,14 @@ public:
return get_keyid (pubkey->encode() ); return get_keyid (pubkey->encode() );
} }
static void clear_keypairs (keypair_storage&);
static void clear_pubkeys (pubkey_storage&);
static bool parse_keypairs (sencode*, keypair_storage&);
static sencode* serialize_keypairs (const keypair_storage&);
static bool parse_pubkeys (sencode*, pubkey_storage&);
static sencode* serialize_pubkeys (const pubkey_storage&);
pubkey_entry* get_pubkey (const std::string&keyid) { pubkey_entry* get_pubkey (const std::string&keyid) {
// "own first", but there should not be collisions. // "own first", but there should not be collisions.
if (pairs.count (keyid) ) return & (pairs[keyid].pub); if (pairs.count (keyid) ) return & (pairs[keyid].pub);