keyring: detach keyring parsing/serialization
for later usage in exports/imports
This commit is contained in:
parent
287a2bbac0
commit
e5cff75177
260
src/keyring.cpp
260
src/keyring.cpp
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in a new issue