/* This file is part of Pretty Curved Privacy (pcp1). Copyright (C) 2013 T.Linden. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program 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 General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . You can contact me by mail: . */ #include "pcp++.h" using namespace std; using namespace pcp; Key::Key() { stored = false; K = NULL; } Key::Key(bool generate) { stored = false; K = pcpkey_new(); } Key::Key(const string& passphrase) { stored = false; K = pcpkey_new(); K = pcpkey_encrypt(K, passphrase.c_str()); } Key::Key(const string& passphrase, const string& owner, const string& mail) { stored = false; _k = pcpkey_new(); K = pcpkey_encrypt(_K, passphrase.c_str()); free(_k); memcpy(K->owner, owner.c_str(), owner.length()+1); memcpy(K->mail, mail.c_str(), mail.length()+1); } Key::(const Key &k) { K = k.K; } Key::Key(const pcp_key_t *k) { stored = false; K = k; } Key::~Key() { if (! stored) { free(K); } } const Key::Key& operator = (const Key &k) { K = k.K; return *this; } istream& operator>>(istream& input, Key& k) { string z85; input >> z85; if(z85.length() == 0) throw exception("Error: zero length input"); size_t clen; unsigned char *z85decoded = pcp_z85_decode(z85.c_str(), &clen); if(z85decoded == NULL) throw exception("Error: could not decode input - it's probably not Z85.\n"); if(clen != PCP_RAW_KEYSIZE) { free(z85decoded); throw exception("Error: decoded input didn't result to a proper sized key!" + "(got " + clen + " bytes)\n"); } // all good now, import the blob pcp_key_t *key = ucmalloc(sizeof(pcp_key_t)); memcpy(key, z85decoded, PCP_RAW_KEYSIZE); key2native(key); if(pcp_sanitycheck_key(key) != 0) { free(key); free(z85decoded); throw exception(); } k.K = key; free(key); return input; } ostream& operator<<(ostream& output, Key& k) { size_t zlen; pcp_key_t *key = k.K; key2be(key); void *blob = ucmalloc(PCP_RAW_KEYSIZE); pcp_seckeyblob(blob, key); char *z85encoded = pcp_z85_encode((unsigned char*)blob, PCP_RAW_KEYSIZE, &zlen); if(PCP_ERRSET == 1) throw exception(); key2native(key); free(blob); struct tm *c; time_t t = (time_t)key->ctime; c = localtime(&t); char *out = ucmalloc(2048); sprintf(out, "%s\n", PCP_KEY_HEADER); output << out; sprintf(out, " Generated by: %s Version %d.%d.%d\n", PCP_ME, PCP_VERSION_MAJOR, PCP_VERSION_MINOR, PCP_VERSION_PATCH); output << out; sprintf(out, " Cipher: %s\n", PCP_KEY_PRIMITIVE); output << out; sprintf(out, " Key-ID: 0x%s\n", key->id); output << out; //2004-06-14T23:34:30. sprintf(out, " Creation Time: %04d-%02d-%02dT%02d:%02d:%02d\n", c->tm_year+1900, c->tm_mon+1, c->tm_mday, c->tm_hour, c->tm_min, c->tm_sec); output << out; sprintf(out, " Serial Number: 0x%08X\n", key->serial); output << out; sprintf(out, " Key Version: 0x%08X\n", key->version); output << out; sprintf(out, "\n%s\n", z85encoded); output << out; sprintf(out, "%s\n", PCP_KEY_FOOTER); output << out; free(z85encoded); return output; } void Key::encrypt(const string& passphrase) { K = pcpkey_encrypt(K, passphrase.c_str()); if(PCP_ERRSET == 1) throw exception(); } void Key::decrypt(const string& passphrase) { K = pcpkey_decrypt(K, passphrase.c_str()); if(PCP_ERRSET == 1) throw exception(); } PubKey Key::get_public() { return PubKey(pcpkey_pub_from_secret(K)); } string Key::get_id() { string id = K.id; return id; } string Key::get_owner() { string o = K.owner; return o; } string Key::get_mail() { string m = K.mail; return m; } pcp_key_t *Key::get_key() { return K; } void Key::set_owner(const string& owner) { memcpy(K->owner, owner.c_str(), owner.length()+1); } void Key::set_mail(const string& mail) { memcpy(K->mail, mail.c_str(), mail.length()+1); } void Key::is_stored(bool s) { stored = s; } bool Key::is_stored() { return stored; } bool Key::is_encrypted() { if(K->secret[0] == '\0') return true; else return false; } PubKey::PubKey() { stored = false; K = NULL; } PubKey::(const PubKey &k) { K = k.K; } PubKey::PubKey(const pcp_pubkey_t *k) { stored = false; K = k; } PubKey::~PubKey() { if (! stored) { free(K); } } const PubKey::PubKey& operator = (const PubKey &k) { K = k.K; return *this; } istream& operator>>(istream& input, PubKey& k) { string z85; input >> z85; if(z85.length() == 0) throw exception("Error: zero length input"); size_t clen; unsigned char *z85decoded = pcp_z85_decode(z85.c_str(), &clen); if(z85decoded == NULL) throw exception("Error: could not decode input - it's probably not Z85.\n"); if(clen != PCP_RAW_PUBKEYSIZE) { free(z85decoded); throw exception("Error: decoded input didn't result to a proper sized key!" + "(got " + clen + " bytes)\n"); } // all good now, import the blob pcp_pubkey_t *key = ucmalloc(sizeof(pcp_pubkey_t)); memcpy(key, z85decoded, PCP_RAW_PUBKEYSIZE); pubkey2native(key); if(pcp_sanitycheck_pub(key) != 0) { free(key); free(z85decoded); throw exception(); } k.K = key; free(key); return input; } ostream& operator<<(ostream& output, PubKey& k) { size_t zlen; pcp_pubkey_t *key = k.K; pubkey2be(key); void *blob = ucmalloc(PCP_RAW_PUBKEYSIZE); pcp_pubkeyblob(blob, key); char *z85encoded = pcp_z85_encode((unsigned char*)blob, PCP_RAW_PUBKEYSIZE, &zlen); if(PCP_ERRSET == 1) throw exception(); pubkey2native(key); free(blob); struct tm *c; time_t t = (time_t)key->ctime; c = localtime(&t); char *out = ucmalloc(2048); sprintf(out, "%s\n", PCP_PUBKEY_HEADER); output << out; sprintf(out, " Generated by: %s Version %d.%d.%d\n", PCP_ME, PCP_VERSION_MAJOR, PCP_VERSION_MINOR, PCP_VERSION_PATCH); output << out; sprintf(out, " Cipher: %s\n", PCP_KEY_PRIMITIVE); output << out; sprintf(out, " PubKey-ID: 0x%s\n", key->id); output << out; //2004-06-14T23:34:30. sprintf(out, " Creation Time: %04d-%02d-%02dT%02d:%02d:%02d\n", c->tm_year+1900, c->tm_mon+1, c->tm_mday, c->tm_hour, c->tm_min, c->tm_sec); output << out; unsigned char *hash = pcppubkey_getchecksum(key); output << " Checksum: "; int i; for ( i = 0;i <15 ;++i) { sprintf(out, "%02X:",(unsigned int) hash[i]); output << out; } sprintf(out, "%02X", hash[15]); output << out; output << "\n "; for ( i = 16;i <31 ;++i) { sprintf(out, "%02X:",(unsigned int) hash[i]); output << out; } sprintf(out, "%02X", hash[31]); output << out; output << "\n"; sprintf(out, " Serial Number: 0x%08X\n", key->serial); output << out; sprintf(out, " Key Version: 0x%08X\n", key->version); output << out; char *r = pcppubkey_get_art(key); output << " Random Art ID: "; for (i=0; i