/* 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, (char *)passphrase.c_str()); } Key::Key(const string& passphrase, const string& owner, const string& mail) { stored = false; pcp_key_t *_K = pcpkey_new(); K = pcpkey_encrypt(_K, (char *)passphrase.c_str()); memcpy(K->owner, owner.c_str(), owner.length()+1); memcpy(K->mail, mail.c_str(), mail.length()+1); // free(_K); } Key::Key(pcp_key_t *k) { stored = false; K = k; } Key::Key(pcp_key_t *k, bool store) { stored = new bool(store); K = k; } Key::Key(string &z85encoded) { stored = false; if(z85encoded.length() == 0) throw pcp::exception("Error: zero length input"); size_t clen; unsigned char *z85decoded = pcp_z85_decode((char *)z85encoded.c_str(), &clen); if(z85decoded == NULL) throw pcp::exception("Error: could not decode input - it's probably not Z85.\n"); if(clen != PCP_RAW_KEYSIZE) { free(z85decoded); char m[256]; sprintf(m, "Error: decoded input didn't result to a proper sized key (got %ld bytes)!\n", clen); throw pcp::exception(string(m)); } // all good now, import the blob pcp_key_t *key = (pcp_key_t *)ucmalloc(sizeof(pcp_key_t)); memcpy(key, z85decoded, PCP_RAW_KEYSIZE); key2native(key); if(pcp_sanitycheck_key(key) != 0) { free(key); free(z85decoded); throw pcp::exception(); } K = key; cout << 7 << " false" << endl; } Key::~Key() { if (! stored) { free(K); } } Key::Key& Key::operator = (const Key &k) { K = k.K; return *this; } string Key::to_text() { size_t zlen; pcp_key_t *key = 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 pcp::exception(); key2native(key); free(blob); struct tm *c; time_t t = (time_t)key->ctime; c = localtime(&t); string z85; char *out = (char *)ucmalloc(2048); sprintf(out, "%s\n", PCP_KEY_HEADER); z85 += out; sprintf(out, " Generated by: %s Version %d.%d.%d\n", PCP_ME, PCP_VERSION_MAJOR, PCP_VERSION_MINOR, PCP_VERSION_PATCH); z85 += out; sprintf(out, " Cipher: %s\n", PCP_KEY_PRIMITIVE); z85 += out; sprintf(out, " Key-ID: 0x%s\n", key->id); z85 += 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); z85 += out; sprintf(out, " Serial Number: 0x%08X\n", key->serial); z85 += out; sprintf(out, " Key Version: 0x%08X\n", key->version); z85 += out; sprintf(out, "\n%s\n", z85encoded); z85 += out; sprintf(out, "%s\n", PCP_KEY_FOOTER); z85 += out; free(z85encoded); return z85; } istream& pcp::operator>>(istream& input, Key& k) { string z85; input >> z85; Key t = new Key(z85); // use the import constructor, FIXME: use a method k.K = t.K; return input; } ostream& pcp::operator<<(ostream& output, Key& k) { output << k.to_text(); return output; } void Key::encrypt(const string& passphrase) { K = pcpkey_encrypt(K, (char *)passphrase.c_str()); if(PCP_ERRSET == 1) throw exception(); } void Key::decrypt(const string& passphrase) { K = pcpkey_decrypt(K, (char *)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; } 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; } string Key::encrypt(PubKey &recipient, string message) { unsigned char *m = (unsigned char *)ucmalloc(message.size() + 1); memcpy(m, message.c_str(), message.size()); return Key::encrypt(recipient, m, message.size() + 1); } string Key::encrypt(PubKey &recipient, vector message) { unsigned char *m = (unsigned char *)ucmalloc(message.size()); for(size_t i=0; iid, 16); memcpy(combined, hash, crypto_hash_BYTES); memcpy(&combined[crypto_hash_BYTES], cipher, clen); // combined consists of: // keyid|nonce|cipher char *encoded = pcp_z85_encode(combined, rlen, &zlen); if(encoded == NULL) throw exception(); return string((char *)encoded); } ResultSet Key::decrypt(PubKey &sender, std::string cipher) { size_t clen; unsigned char *combined = pcp_z85_decode((char *)cipher.c_str(), &clen); if(combined == NULL) throw exception(); unsigned char *encrypted = (unsigned char*)ucmalloc(clen - crypto_hash_BYTES); memcpy(encrypted, &combined[crypto_hash_BYTES], clen - crypto_hash_BYTES); size_t dlen; unsigned char *decrypted = (unsigned char*)pcp_box_decrypt(K, sender.K, encrypted, clen - crypto_hash_BYTES, &dlen); if(decrypted == NULL) { free(combined); throw exception(); } ResultSet r; r.Uchar = decrypted; r.String = string((char *)decrypted); r.Size = dlen; for(size_t i=0; ictime; c = localtime(&t); char *out = (char *)ucmalloc(2048); string z85; sprintf(out, "%s\n", PCP_PUBKEY_HEADER); z85 += out; sprintf(out, " Generated by: %s Version %d.%d.%d\n", PCP_ME, PCP_VERSION_MAJOR, PCP_VERSION_MINOR, PCP_VERSION_PATCH); z85 += out; sprintf(out, " Cipher: %s\n", PCP_KEY_PRIMITIVE); z85 += out; sprintf(out, " PubKey-ID: 0x%s\n", key->id); z85 += 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); z85 += out; unsigned char *hash = pcppubkey_getchecksum(key); z85 += " Checksum: "; int i; for ( i = 0;i <15 ;++i) { sprintf(out, "%02X:",(unsigned int) hash[i]); z85 += out; } sprintf(out, "%02X", hash[15]); z85 += out; z85 += "\n "; for ( i = 16;i <31 ;++i) { sprintf(out, "%02X:",(unsigned int) hash[i]); z85 += out; } sprintf(out, "%02X", hash[31]); z85 += out; z85 += "\n"; sprintf(out, " Serial Number: 0x%08X\n", key->serial); z85 += out; sprintf(out, " Key Version: 0x%08X\n", key->version); z85 += out; char *r = pcppubkey_get_art(key); z85 += " Random Art ID: "; int rlen = strlen(r); for (i=0; i>(istream& input, PubKey& k) { string z85; input >> z85; k = PubKey(z85); return input; } ostream& pcp::operator<<(ostream& output, PubKey& k) { output << k.to_text(); return output; } string PubKey::get_id() { string id = K->id; return id; } string PubKey::get_owner() { string o = K->owner; return o; } string PubKey::get_mail() { string m = K->mail; return m; } void PubKey::is_stored(bool s) { stored = s; } bool PubKey::is_stored() { return stored; }