1
0
mirror of https://github.com/biergaizi/codecrypt synced 2024-06-28 09:53:46 +00:00

keyring: better structure

This commit is contained in:
Mirek Kratochvil 2013-04-01 17:49:58 +02:00
parent f6c1ee90c9
commit 2c4a399536
3 changed files with 158 additions and 56 deletions

@ -18,34 +18,46 @@
#include "keyring.h"
sencode* keyring::get_pubkey (const std::string&key_id)
void keyring::clear()
{
for (std::map<std::string, pubkey_entry>::iterator
i = pubs.begin(), e = pubs.end(); i != e; ++i)
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();
}
void keyring::remove_pubkey (const std::string&key_id)
/*
* KeyID is SHA256 of pubkey string representation. Also serves as a
* simple fingerprint.
*/
#include "sha2.h"
#include <stdint.h>
std::string keyring::get_keyid (const std::string&pubkey)
{
SHA256_CTX ctx;
uint8_t t;
}
SHA256_Init (&ctx);
bool keyring::store_pubkey (const std::string&key_id, sencode*)
{
for (size_t i = 0; i < pubkey.length(); ++i) {
t = pubkey[i];
SHA256_Update (&ctx, &t, 1);
}
}
sencode* keyring::get_privkey (const std::string&key_id)
{
}
void keyring::remove_privkey (const std::string&key_id)
{
}
bool keyring::store_privkey (const std::string&key_id, sencode*)
{
std::string r;
r.resize (64, ' ');
SHA256_End (&ctx, & (r[0]) );
return r;
}
/*
@ -53,8 +65,10 @@ bool keyring::store_privkey (const std::string&key_id, sencode*)
*
* Whole thing is stored in two files just like in GnuPG:
*
* ~/.ccr/pubkeys
* ~/.ccr/private_keyring
* ${CCR_DIR}/pubring
* ${CCR_DIR}/secrets
*
* CCR_DIR is taken from environment, and defaults to ${HOME}/.ccr
*
* format of the files is raw sencode.
*
@ -62,9 +76,9 @@ bool keyring::store_privkey (const std::string&key_id, sencode*)
*
* (
* "ccr public key storage"
* ( "public-key-id" pubkey_as_embedded_sencode )
* ( "public-key-id" pubkey_as_embedded_sencode )
* ( "public-key-id" pubkey_as_embedded_sencode )
* ( "key-name" pubkey_as_embedded_sencode )
* ( "key-name" pubkey_as_embedded_sencode )
* ( "key-name" pubkey_as_embedded_sencode )
* ...
* )
*
@ -73,15 +87,22 @@ bool keyring::store_privkey (const std::string&key_id, sencode*)
*
* (
* "ccr private keyring"
* ( "public-key-id" privkey pubkey )
* ( "public-key-id" privkey pubkey )
* ( "public-key-id" privkey pubkey )
* ( "key-name" privkey pubkey )
* ( "key-name" privkey pubkey )
* ( "key-name" privkey pubkey )
* ...
* )
*
*/
bool keyring::disk_sync()
bool keyring::load()
{
return false;
}
bool keyring::save()
{
return false;
}

@ -24,23 +24,107 @@
#include "sencode.h"
/* TODO privkeys are actually keypairs! */
class keyring
{
std::multimap<std::string, sencode*>
priv_cache, priv_dirty,
pub_cache, pub_dirty;
public:
bool disk_sync();
struct pubkey_entry {
sencode *key;
std::string name, keyid;
sencode* get_pubkey (const std::string&key_id);
void remove_pubkey (const std::string&key_id);
bool store_pubkey (const std::string&key_id, sencode*);
pubkey_entry() {
key = NULL;
}
sencode* get_privkey (const std::string&key_id);
void remove_privkey (const std::string&key_id);
bool store_privkey (const std::string&key_id, sencode*);
pubkey_entry (const std::string& KID,
const std::string& N,
sencode*K) {
key = K;
name = N;
keyid = KID;
}
};
struct keypair_entry {
sencode *privkey;
pubkey_entry pub;
keypair_entry() {
privkey = NULL;
}
keypair_entry (const std::string&KID,
const std::string& N,
sencode*PubK,
sencode*PrivK)
: pub (KID, N, PubK) {
privkey = PrivK;
}
};
std::map<std::string, pubkey_entry> pubs;
std::map<std::string, keypair_entry> pairs;
explicit keyring() {
}
~keyring() {
clear();
}
bool load();
bool save();
void clear();
static std::string get_keyid (const std::string& pubkey);
static std::string get_keyid (sencode* pubkey) {
return get_keyid (pubkey->encode() );
}
pubkey_entry* get_pubkey (const std::string&keyid) {
// "own first", but there should not be collisions.
if (pairs.count (keyid) ) return & (pairs[keyid].pub);
if (pubs.count (keyid) ) return & (pubs[keyid]);
return NULL;
}
bool store_pubkey (const std::string&keyid,
const std::string&name, sencode*key) {
if (pairs.count (keyid) ) return false;
if (pubs.count (keyid) ) return false;
pubs[keyid] = pubkey_entry (keyid, name, key);
}
void remove_pubkey (const std::string&keyid) {
if (pubs.count (keyid) ) {
sencode_destroy (pubs[keyid].key);
pubs.erase (keyid);
}
}
keypair_entry* get_keypair (const std::string&keyid) {
if (pairs.count (keyid) ) return & (pairs[keyid]);
return NULL;
}
bool store_keypair (const std::string&keyid,
const std::string&name,
sencode*pubkey, sencode*privkey) {
if (pairs.count (keyid) ) return false;
if (pubs.count (keyid) ) return false;
pairs[keyid] = keypair_entry (keyid, name, pubkey, privkey);
}
void remove_keypair (const std::string&keyid) {
if (pairs.count (keyid) ) {
sencode_destroy (pairs[keyid].pub.key);
sencode_destroy (pairs[keyid].privkey);
pairs.erase (keyid);
}
}
};
#endif

@ -35,10 +35,10 @@ int encrypted_msg::encrypt (const bvector&msg,
if (!alg) return 1;
sencode*pubkey = kr.get_pubkey (key_id);
if (!pubkey) return 2; //PK not found
keyring::pubkey_entry*pk = kr.get_pubkey (key_id);
if (!pk) return 2; //PK not found
return alg->encrypt (msg, ciphertext, pubkey, rng);
return alg->encrypt (msg, ciphertext, pk->key, rng);
}
int encrypted_msg::decrypt (bvector& msg, algorithm_suite&algs, keyring& kr)
@ -52,10 +52,10 @@ int encrypted_msg::decrypt (bvector& msg, algorithm_suite&algs, keyring& kr)
if (!alg) return 1;
sencode*privkey = kr.get_privkey (key_id);
if (!privkey) return 2;
keyring::keypair_entry*k = kr.get_keypair (key_id);
if (!k) return 2;
return alg->decrypt (ciphertext, msg, privkey);
return alg->decrypt (ciphertext, msg, k->privkey);
}
int signed_msg::sign (const bvector&msg,
@ -76,22 +76,19 @@ int signed_msg::sign (const bvector&msg,
if (!alg) return 1;
sencode*privkey = kr.get_privkey (key_id);
if (!privkey) return 2;
keyring::keypair_entry *k = kr.get_keypair (key_id);
if (!k) return 2;
bool privkey_dirty = false;
int r;
r = alg->sign (message, signature, &privkey, privkey_dirty, rng);
r = alg->sign (message, signature, & (k->privkey), privkey_dirty, rng);
if (r) return r;
if (privkey_dirty) {
kr.remove_privkey (key_id);
//this actually shouldn't fail, key_id is not present
kr.store_privkey (key_id, privkey);
//we can't output a signature without storing privkey changes!
if (!kr.disk_sync() ) return 3;
if (!kr.save() ) return 3;
}
return 0;
@ -108,9 +105,9 @@ int signed_msg::verify (algorithm_suite&algs, keyring&kr)
if (!alg) return 1;
sencode*pubkey = kr.get_pubkey (key_id);
if (!pubkey) return 2;
keyring::pubkey_entry*pk = kr.get_pubkey (key_id);
if (!pk) return 2;
return alg->verify (signature, message, pubkey);
return alg->verify (signature, message, pk->key);
}