mirror of
https://github.com/textmate/textmate.git
synced 2026-02-15 00:45:02 -05:00
138 lines
2.7 KiB
C++
138 lines
2.7 KiB
C++
#include "key_chain.h"
|
||
#include <oak/oak.h>
|
||
#include <plist/plist.h>
|
||
|
||
key_chain_t::key_t::key_t (std::string const& identity, std::string const& name, std::string const& key_data) : _identity(identity), _name(name), _key_data(key_data)
|
||
{
|
||
init();
|
||
}
|
||
|
||
key_chain_t::key_t::key_t (key_t const& rhs) : _identity(rhs._identity), _name(rhs._name), _key_data(rhs._key_data)
|
||
{
|
||
init();
|
||
}
|
||
|
||
key_chain_t::key_t::~key_t ()
|
||
{
|
||
cleanup();
|
||
}
|
||
|
||
void key_chain_t::key_t::init () const
|
||
{
|
||
_ssl_key = NULL;
|
||
_ssl_bio = NULL;
|
||
_ssl_data = NULL;
|
||
}
|
||
|
||
bool key_chain_t::key_t::setup () const
|
||
{
|
||
if(_ssl_key)
|
||
return true;
|
||
|
||
bool res = false;
|
||
if(_ssl_key = EVP_PKEY_new())
|
||
{
|
||
if(_ssl_bio = BIO_new_mem_buf((char*)_key_data.data(), _key_data.size()))
|
||
{
|
||
if(_ssl_data = PEM_read_bio_DSA_PUBKEY(_ssl_bio, NULL, NULL, NULL))
|
||
{
|
||
if(res = EVP_PKEY_assign_DSA(_ssl_key, _ssl_data) == 1)
|
||
_ssl_data = NULL;
|
||
}
|
||
else
|
||
{
|
||
fprintf(stderr, "*** error reading key\n");
|
||
}
|
||
}
|
||
else
|
||
{
|
||
fprintf(stderr, "*** error creating BIO\n");
|
||
}
|
||
}
|
||
else
|
||
{
|
||
fprintf(stderr, "*** error creating PKEY\n");
|
||
}
|
||
|
||
if(!res)
|
||
cleanup();
|
||
|
||
return res;
|
||
}
|
||
|
||
void key_chain_t::key_t::cleanup () const
|
||
{
|
||
if(_ssl_data)
|
||
DSA_free(_ssl_data);
|
||
|
||
if(_ssl_bio)
|
||
BIO_free(_ssl_bio);
|
||
|
||
if(_ssl_key)
|
||
EVP_PKEY_free(_ssl_key);
|
||
|
||
init();
|
||
}
|
||
|
||
// =============
|
||
// = Key Chain =
|
||
// =============
|
||
|
||
void key_chain_t::load (std::string const& path)
|
||
{
|
||
keys.clear();
|
||
|
||
plist::dictionary_t identities;
|
||
if(plist::get_key_path(plist::load(path), "identities", identities))
|
||
{
|
||
iterate(identity, identities)
|
||
{
|
||
std::string name, keyData;
|
||
if(plist::get_key_path(identity->second, "name", name) && plist::get_key_path(identity->second, "key", keyData))
|
||
{
|
||
keys.push_back(key_ptr(new key_t(identity->first, name, keyData)));
|
||
}
|
||
else
|
||
{
|
||
fprintf(stderr, "no name/key in entry:\n%s", to_s(identity->second).c_str());
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
fprintf(stderr, "no identities in ‘%s’\n", path.c_str());
|
||
}
|
||
}
|
||
|
||
void key_chain_t::save (std::string const& path) const
|
||
{
|
||
plist::dictionary_t identities;
|
||
iterate(key, keys)
|
||
{
|
||
plist::dictionary_t entry;
|
||
entry.insert(std::make_pair("name", (*key)->name()));
|
||
entry.insert(std::make_pair("key", (*key)->_key_data));
|
||
identities.insert(std::make_pair((*key)->identity(), entry));
|
||
}
|
||
|
||
plist::dictionary_t plist;
|
||
plist.insert(std::make_pair("identities", identities));
|
||
|
||
plist::save(path, plist);
|
||
}
|
||
|
||
void key_chain_t::add (key_t const& key)
|
||
{
|
||
keys.push_back(key_ptr(new key_t(key.identity(), key.name(), key._key_data)));
|
||
}
|
||
|
||
key_chain_t::key_ptr key_chain_t::find (std::string const& identity) const
|
||
{
|
||
iterate(key, keys)
|
||
{
|
||
if((*key)->identity() == identity && (*key)->setup())
|
||
return *key;
|
||
}
|
||
return key_ptr();
|
||
}
|