put previously global error handling and key hashes into ptx (pcp context) to make libpcp threadsafe.

This commit is contained in:
TLINDEN
2014-05-04 17:11:03 +02:00
parent d1c87d1001
commit da9891ff81
58 changed files with 1330 additions and 958 deletions

View File

@@ -96,6 +96,10 @@
is now determined automatically as well as the is now determined automatically as well as the
encoding. encoding.
Made libpcp threadsafe by removing all global vars
and putting that stuff into the new PCP Context
class (ptx.h), which now holds errors and key hashes.
0.2.0 ED25519 and Curve25519 keys are now generated 0.2.0 ED25519 and Curve25519 keys are now generated
separately (previously they were generated from separately (previously they were generated from
one random seed, the curve had been derived from one random seed, the curve had been derived from

View File

@@ -22,5 +22,5 @@ AM_CXXFLAGS = -I../../include -I../../libpcp/scrypt/crypto -I../../libpcp/scrypt
lib_LTLIBRARIES = libpcp1++.la lib_LTLIBRARIES = libpcp1++.la
libpcp1___la_SOURCES = pcp++.h key.cpp vault.cpp crypto.cpp sign.cpp buffer.cpp libpcp1___la_SOURCES = pcp++.h ptx.cpp key.cpp vault.cpp crypto.cpp sign.cpp buffer.cpp
include_HEADERS = pcp++.h include_HEADERS = pcp++.h

View File

@@ -35,6 +35,7 @@ namespace pcp {
class Crypto { class Crypto {
private: private:
PcpContext PTX;
bool havevault; bool havevault;
public: public:
@@ -43,8 +44,8 @@ namespace pcp {
Vault vault; Vault vault;
// constructors // constructors
Crypto(Key &skey, PubKey &pkey); Crypto(PcpContext C, Key &skey, PubKey &pkey);
Crypto(Vault &v, Key &skey, PubKey &pkey); Crypto(PcpContext C, Vault &v, Key &skey, PubKey &pkey);
// PK encryption methods // PK encryption methods
// sender pubkey is P // sender pubkey is P

View File

@@ -25,29 +25,31 @@
using namespace std; using namespace std;
using namespace pcp; using namespace pcp;
Crypto::Crypto(Key &skey, PubKey &pkey) { Crypto::Crypto(PcpContext C, Key &skey, PubKey &pkey) {
P = pkey; P = pkey;
S = skey; S = skey;
PTX = C;
havevault = false; havevault = false;
pcphash_init(); pcphash_add(PTX.ptx, P.K, PCP_KEY_TYPE_PUBLIC);
pcphash_add(P.K, PCP_KEY_TYPE_PUBLIC);
} }
Crypto::Crypto(Vault &v, Key &skey, PubKey &pkey) { Crypto::Crypto(PcpContext C, Vault &v, Key &skey, PubKey &pkey) {
P = pkey; P = pkey;
S = skey; S = skey;
PTX = C;
vault = v; vault = v;
havevault = true; havevault = true;
} }
bool Crypto::encrypt(FILE *in, FILE *out, bool sign) { bool Crypto::encrypt(FILE *in, FILE *out, bool sign) {
pcp_pubkey_t *pubhash = NULL; pcp_pubkey_t *pubhash = NULL;
HASH_ADD_STR( pubhash, id, P.K); pcphash_add(PTX.ptx, P.K, P.K->type);
//HASH_ADD_STR( pubhash, id, P.K);
Pcpstream *pin = ps_new_file(in); Pcpstream *pin = ps_new_file(in);
Pcpstream *pout = ps_new_file(out); Pcpstream *pout = ps_new_file(out);
size_t clen = pcp_encrypt_stream(pin, pout, S.K, pubhash, sign); size_t clen = pcp_encrypt_stream(PTX.ptx, pin, pout, S.K, pubhash, sign);
if(clen <= 0) if(clen <= 0)
throw exception(); throw exception(PTX);
ps_close(pin); ps_close(pin);
ps_close(pout); ps_close(pout);
return true; return true;
@@ -56,8 +58,8 @@ bool Crypto::encrypt(FILE *in, FILE *out, bool sign) {
bool Crypto::decrypt(FILE *in, FILE *out, bool verify) { bool Crypto::decrypt(FILE *in, FILE *out, bool verify) {
Pcpstream *pin = ps_new_file(in); Pcpstream *pin = ps_new_file(in);
Pcpstream *pout = ps_new_file(out); Pcpstream *pout = ps_new_file(out);
if(pcp_decrypt_stream(pin, pout, S.K, NULL, verify) <= 0) if(pcp_decrypt_stream(PTX.ptx, pin, pout, S.K, NULL, verify) <= 0)
throw exception(); throw exception(PTX);
ps_close(pin); ps_close(pin);
ps_close(pout); ps_close(pout);
return true; return true;

View File

@@ -30,14 +30,17 @@
#include <stdexcept> #include <stdexcept>
#include <iostream> #include <iostream>
#include "ptx++.h"
namespace pcp { namespace pcp {
class exception : public std::runtime_error { class exception : public std::runtime_error {
private: private:
PCPCTX *ptx;
std::string getfatals() { std::string getfatals() {
std::string msg; std::string msg;
if(PCP_ERRSET == 1) { if(ptx->pcp_errset == 1) {
msg = PCP_ERR; msg = ptx->pcp_err;
} }
if(errno) { if(errno) {
msg += std::string("\nError: ") msg += std::string("\nError: ")
@@ -47,8 +50,8 @@ namespace pcp {
return msg; return msg;
} }
public: public:
exception(const std::string & msg) : runtime_error(msg) { } exception(PcpContext P, const std::string & msg) : runtime_error(msg) { ptx = P.ptx; }
exception() : runtime_error(getfatals()) { } exception(PcpContext P) : runtime_error(getfatals()) { ptx = P.ptx; }
}; };

View File

@@ -30,6 +30,7 @@
#include "helpers++.h" #include "helpers++.h"
#include "buffer++.h" #include "buffer++.h"
#include "ptx++.h"
namespace pcp { namespace pcp {
@@ -39,12 +40,14 @@ namespace pcp {
public: public:
pcp_pubkey_t *K; pcp_pubkey_t *K;
PcpContext PTX;
// constructors // constructors
PubKey(PcpContext P);
PubKey(); PubKey();
PubKey(pcp_pubkey_t *k); PubKey(PcpContext P, pcp_pubkey_t *k);
PubKey(pcp_pubkey_t *k, bool store); PubKey(PcpContext P, pcp_pubkey_t *k, bool store);
PubKey(std::string &z85encoded); PubKey(PcpContext P, std::string &z85encoded);
// destructors // destructors
~PubKey(); ~PubKey();
@@ -72,17 +75,19 @@ namespace pcp {
public: public:
// make access to the underlying struct easier // make access to the underlying struct easier
pcp_key_t *K; pcp_key_t *K;
PcpContext PTX;
// constructors // constructors
Key(); Key();
Key(bool generate); Key(PcpContext P);
Key(const std::string& passphrase); Key(PcpContext P, bool generate);
Key(const std::string& passphrase, Key(PcpContext P, const std::string& passphrase);
Key(PcpContext P, const std::string& passphrase,
const std::string& owner, const std::string& owner,
const std::string& mail); const std::string& mail);
Key(pcp_key_t *k); Key(PcpContext P, pcp_key_t *k);
Key(pcp_key_t *k, bool store); Key(PcpContext P, pcp_key_t *k, bool store);
Key(std::string &z85encoded, std::string& passphrase); Key(PcpContext P, std::string &z85encoded, std::string& passphrase);
// destructor // destructor
~Key(); ~Key();

View File

@@ -30,55 +30,67 @@ Key::Key() {
K = NULL; K = NULL;
} }
Key::Key(bool generate) { Key::Key(PcpContext P) {
stored = false;
K = NULL;
PTX = P;
}
Key::Key(PcpContext P, bool generate) {
stored = false; stored = false;
if(generate) if(generate)
K = pcpkey_new(); K = pcpkey_new();
else else
K = NULL; K = NULL;
PTX = P;
} }
Key::Key(const string& passphrase) { Key::Key(PcpContext P, const string& passphrase) {
stored = false; stored = false;
K = pcpkey_new(); K = pcpkey_new();
K = pcpkey_encrypt(K, (char *)passphrase.c_str()); K = pcpkey_encrypt(PTX.ptx, K, (char *)passphrase.c_str());
PTX = P;
} }
Key::Key(const string& passphrase, Key::Key(PcpContext P, const string& passphrase,
const string& owner, const string& owner,
const string& mail) { const string& mail) {
stored = false; stored = false;
pcp_key_t *_K = pcpkey_new(); pcp_key_t *_K = pcpkey_new();
K = pcpkey_encrypt(_K, (char *)passphrase.c_str()); K = pcpkey_encrypt(PTX.ptx, _K, (char *)passphrase.c_str());
memcpy(K->owner, owner.c_str(), owner.length()+1); memcpy(K->owner, owner.c_str(), owner.length()+1);
memcpy(K->mail, mail.c_str(), mail.length()+1); memcpy(K->mail, mail.c_str(), mail.length()+1);
// free(_K); // free(_K);
PTX = P;
} }
Key::Key(pcp_key_t *k) { Key::Key(PcpContext P, pcp_key_t *k) {
stored = false; stored = false;
K = k; K = k;
PTX = P;
} }
Key::Key(pcp_key_t *k, bool store) { Key::Key(PcpContext P, pcp_key_t *k, bool store) {
stored = new bool(store); stored = new bool(store);
K = k; K = k;
PTX = P;
} }
Key::Key(string &z85encoded, string &passphrase) { Key::Key(PcpContext P, string &z85encoded, string &passphrase) {
stored = false; stored = false;
PTX = P;
if(z85encoded.length() == 0) if(z85encoded.length() == 0)
throw pcp::exception("Error: zero length input"); throw pcp::exception(PTX, "Error: zero length input");
pcp_key_t *key = pcp_import_secret((unsigned char *)z85encoded.c_str(), z85encoded.length(), (char *)passphrase.c_str()); pcp_key_t *key = pcp_import_secret(PTX.ptx, (unsigned char *)z85encoded.c_str(), z85encoded.length(), (char *)passphrase.c_str());
if(key == NULL) if(key == NULL)
throw pcp::exception(); throw pcp::exception(PTX);
if(pcp_sanitycheck_key(key) != 0) { if(pcp_sanitycheck_key(PTX.ptx, key) != 0) {
free(key); free(key);
throw pcp::exception(); throw pcp::exception(PTX);
} }
K = key; K = key;
@@ -99,12 +111,12 @@ string Key::export_secret(const string &passphrase) {
Buffer *exported_sk; Buffer *exported_sk;
if(passphrase.length() == 0) if(passphrase.length() == 0)
throw pcp::exception("Error: empty passphrase"); throw pcp::exception(PTX, "Error: empty passphrase");
exported_sk = pcp_export_secret(K, (char *)passphrase.c_str()); exported_sk = pcp_export_secret(PTX.ptx, K, (char *)passphrase.c_str());
if(exported_sk == NULL) if(exported_sk == NULL)
throw pcp::exception(); throw pcp::exception(PTX);
size_t zlen; size_t zlen;
char *z85 = pcp_z85_encode(buffer_get(exported_sk), buffer_size(exported_sk), &zlen); char *z85 = pcp_z85_encode(buffer_get(exported_sk), buffer_size(exported_sk), &zlen);
@@ -120,7 +132,7 @@ string Key::export_public() {
exported_pk = pcp_export_rfc_pub(K); exported_pk = pcp_export_rfc_pub(K);
if(exported_pk == NULL) if(exported_pk == NULL)
throw pcp::exception(); throw pcp::exception(PTX);
size_t zlen; size_t zlen;
char *z85 = pcp_z85_encode(buffer_get(exported_pk), buffer_size(exported_pk), &zlen); char *z85 = pcp_z85_encode(buffer_get(exported_pk), buffer_size(exported_pk), &zlen);
@@ -140,19 +152,19 @@ bool pcp::operator!(Key& k) {
void Key::encrypt(const string& passphrase) { void Key::encrypt(const string& passphrase) {
K = pcpkey_encrypt(K, (char *)passphrase.c_str()); K = pcpkey_encrypt(PTX.ptx, K, (char *)passphrase.c_str());
if(PCP_ERRSET == 1) if(K == NULL)
throw exception(); throw exception(PTX);
} }
void Key::decrypt(const string& passphrase) { void Key::decrypt(const string& passphrase) {
K = pcpkey_decrypt(K, (char *)passphrase.c_str()); K = pcpkey_decrypt(PTX.ptx, K, (char *)passphrase.c_str());
if(PCP_ERRSET == 1) if(K == NULL)
throw exception(); throw exception(PTX);
} }
PubKey Key::get_public() { PubKey Key::get_public() {
return PubKey(pcpkey_pub_from_secret(K)); return PubKey(PTX, pcpkey_pub_from_secret(K));
} }
string Key::get_id() { string Key::get_id() {
@@ -197,44 +209,52 @@ bool Key::is_encrypted() {
PubKey::PubKey() { PubKey::PubKey() {
stored = false; stored = false;
K = NULL; K = NULL;
} }
PubKey::PubKey(PcpContext P) {
PubKey::PubKey(pcp_pubkey_t *k) {
stored = false; stored = false;
K = k; K = NULL;
PTX = P;
} }
PubKey::PubKey(pcp_pubkey_t *k, bool store) {
PubKey::PubKey(PcpContext P, pcp_pubkey_t *k) {
stored = false;
K = k;
PTX = P;
}
PubKey::PubKey(PcpContext P, pcp_pubkey_t *k, bool store) {
stored = store; stored = store;
K = k; K = k;
PTX = P;
} }
PubKey::PubKey(string &z85encoded) { PubKey::PubKey(PcpContext P, string &z85encoded) {
stored = false; stored = false;
PTX = P;
if(z85encoded.length() == 0) if(z85encoded.length() == 0)
throw pcp::exception("Error: zero length input"); throw pcp::exception(PTX, "Error: zero length input");
Buf blob("pub", 256); Buf blob("pub", 256);
blob.add(z85encoded.c_str(), z85encoded.length()); blob.add(z85encoded.c_str(), z85encoded.length());
pcp_ks_bundle_t *KS = pcp_import_pub(buffer_get(blob.get_buffer()), buffer_size(blob.get_buffer())); pcp_ks_bundle_t *KS = pcp_import_pub(PTX.ptx, buffer_get(blob.get_buffer()), buffer_size(blob.get_buffer()));
if(KS == NULL) { if(KS == NULL) {
throw pcp::exception(); throw pcp::exception(PTX);
} }
pcp_pubkey_t *pub = KS->p; pcp_pubkey_t *pub = KS->p;
if(pcp_sanitycheck_pub(pub) != 0) { if(pcp_sanitycheck_pub(PTX.ptx, pub) != 0) {
free(KS->p); free(KS->p);
free(KS->s); free(KS->s);
free(KS); free(KS);
throw pcp::exception(); throw pcp::exception(PTX);
} }
K = pub; K = pub;

View File

@@ -32,6 +32,7 @@
#include <iostream> #include <iostream>
#include "key++.h" #include "key++.h"
#include "ptx++.h"
#include "vault++.h" #include "vault++.h"
#include "crypto++.h" #include "crypto++.h"
#include "sign++.h" #include "sign++.h"

48
bindings/cpp/ptx++.h Normal file
View File

@@ -0,0 +1,48 @@
/*
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 <http://www.gnu.org/licenses/>.
You can contact me by mail: <tlinden AT cpan DOT org>.
*/
#ifndef _HAVE_PCPPP_PTX_H
#define _HAVE_PCPPP_PTX_H
#include <pcp.h>
#include <vector>
#include <string>
#include <iostream>
#include "helpers++.h"
namespace pcp {
class PcpContext {
public:
PCPCTX *ptx;
// constructors
PcpContext();
// destructors
~PcpContext();
};
};
#endif // _HAVE_PCPPP_PTX_H

34
bindings/cpp/ptx.cpp Normal file
View File

@@ -0,0 +1,34 @@
/*
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 <http://www.gnu.org/licenses/>.
You can contact me by mail: <tlinden AT cpan DOT org>.
*/
#include "pcp++.h"
using namespace std;
using namespace pcp;
PcpContext::PcpContext() {
ptx = ptx_new();
}
PcpContext::~PcpContext() {
ptx_clean(ptx);
}

View File

@@ -45,12 +45,13 @@ namespace pcp {
Vault vault; Vault vault;
PubKey Signedby; PubKey Signedby;
Buf sig; Buf sig;
PcpContext PTX;
// constructors // constructors
Signature(Key &skey); // sign only Signature(PcpContext P, Key &skey); // sign only
Signature(PubKey &pkey); // verify only Signature(PcpContext P,PubKey &pkey); // verify only
Signature(Key &skey, PubKey &pkey); // both/bulk Signature(PcpContext P,Key &skey, PubKey &pkey); // both/bulk
Signature(Vault &v); Signature(PcpContext P,Vault &v);
// destructor // destructor
~Signature(); ~Signature();

View File

@@ -24,25 +24,29 @@
using namespace std; using namespace std;
using namespace pcp; using namespace pcp;
Signature::Signature(Key &skey) { Signature::Signature(PcpContext P, Key &skey) {
S = skey; S = skey;
PTX = P;
havevault = false; havevault = false;
} }
Signature::Signature(PubKey &pkey) { Signature::Signature(PcpContext C,PubKey &pkey) {
P = pkey; P = pkey;
PTX = C;
havevault = false; havevault = false;
} }
Signature::Signature(Key &skey, PubKey &pkey) { Signature::Signature(PcpContext C,Key &skey, PubKey &pkey) {
P = pkey; P = pkey;
S = skey; S = skey;
PTX = C;
havevault = false; havevault = false;
} }
Signature::Signature(Vault &v) { Signature::Signature(PcpContext P,Vault &v) {
vault = v; vault = v;
havevault = true; havevault = true;
PTX = P;
S = vault.get_primary(); S = vault.get_primary();
} }
@@ -51,10 +55,10 @@ Signature::~Signature() {
bool Signature::sign(std::vector<unsigned char> message) { bool Signature::sign(std::vector<unsigned char> message) {
if(! S) if(! S)
throw exception("Error: cannot sign without a secret key, use another constructor."); throw exception(PTX, "Error: cannot sign without a secret key, use another constructor.");
if(S.is_encrypted()) if(S.is_encrypted())
throw exception("Error: cannot sign with an encrypted secret key, decrypt it before using."); throw exception(PTX, "Error: cannot sign with an encrypted secret key, decrypt it before using.");
char n[] = "signvec"; char n[] = "signvec";
Buffer *m = buffer_new(32, n); Buffer *m = buffer_new(32, n);
@@ -68,17 +72,17 @@ bool Signature::sign(std::vector<unsigned char> message) {
buffer_free(m); buffer_free(m);
if(!ok) if(!ok)
throw exception(); throw exception(PTX);
return true; return true;
} }
bool Signature::sign(unsigned char *message, size_t mlen) { bool Signature::sign(unsigned char *message, size_t mlen) {
if(! S) if(! S)
throw exception("Error: cannot sign without a secret key, use another constructor."); throw exception(PTX, "Error: cannot sign without a secret key, use another constructor.");
if(S.is_encrypted()) if(S.is_encrypted())
throw exception("Error: cannot sign with an encrypted secret key, decrypt it before using."); throw exception(PTX, "Error: cannot sign with an encrypted secret key, decrypt it before using.");
char n[] = "signchar"; char n[] = "signchar";
Buffer *m = buffer_new(32, n); Buffer *m = buffer_new(32, n);
@@ -90,7 +94,7 @@ bool Signature::sign(unsigned char *message, size_t mlen) {
buffer_free(m); buffer_free(m);
if(! ok) if(! ok)
throw exception(); throw exception(PTX);
return true; return true;
} }
@@ -98,7 +102,7 @@ bool Signature::sign(unsigned char *message, size_t mlen) {
bool Signature::sign(Pcpstream *message) { bool Signature::sign(Pcpstream *message) {
Pcpstream *out = ps_new_outbuffer(); Pcpstream *out = ps_new_outbuffer();
size_t sigsize = pcp_ed_sign_buffered(message, out, S.K, 0); size_t sigsize = pcp_ed_sign_buffered(PTX.ptx, message, out, S.K, 0);
if(sigsize > 0) { if(sigsize > 0) {
Buffer *o = ps_buffer(out); Buffer *o = ps_buffer(out);
@@ -115,7 +119,7 @@ bool Signature::sign(Pcpstream *message) {
bool Signature::verify(vector<unsigned char> message) { bool Signature::verify(vector<unsigned char> message) {
if(!P) { if(!P) {
throw exception("No public key specified, unable to verify."); throw exception(PTX, "No public key specified, unable to verify.");
} }
Buf _sig = Buf(); Buf _sig = Buf();
@@ -128,7 +132,7 @@ bool Signature::verify(vector<unsigned char> message) {
bool Signature::verify(unsigned char *signature, size_t mlen) { bool Signature::verify(unsigned char *signature, size_t mlen) {
if(!P) { if(!P) {
throw exception("No public key specified, unable to verify."); throw exception(PTX, "No public key specified, unable to verify.");
} }
Buf _sig = Buf(); Buf _sig = Buf();
@@ -141,15 +145,15 @@ bool Signature::verify(unsigned char *signature, size_t mlen) {
bool Signature::verify(Buf _sig) { bool Signature::verify(Buf _sig) {
Pcpstream *p = ps_new_inbuffer(_sig.get_buffer()); Pcpstream *p = ps_new_inbuffer(_sig.get_buffer());
pcp_pubkey_t *pub = pcp_ed_verify_buffered(p, P.K); pcp_pubkey_t *pub = pcp_ed_verify_buffered(PTX.ptx, p, P.K);
ps_close(p); ps_close(p);
if(pub != NULL) { if(pub != NULL) {
Signedby = PubKey(pub); Signedby = PubKey(PTX, pub);
return true; return true;
} }
else { else {
throw exception(); throw exception(PTX);
} }
} }

View File

@@ -46,11 +46,13 @@ namespace pcp {
class Vault { class Vault {
private: private:
vault_t *V; vault_t *V;
PcpContext PTX;
public: public:
// constructors // constructors
Vault(); Vault();
Vault(std::string filename); Vault(PcpContext P);
Vault(PcpContext P, std::string filename);
// destructor // destructor
~Vault(); ~Vault();

View File

@@ -28,24 +28,28 @@ Vault::Vault() {
V = NULL; V = NULL;
} }
Vault::Vault(string filename) { Vault::Vault(PcpContext P) {
pcphash_init(); V = NULL;
V = pcpvault_init((char *)filename.c_str()); PTX = P;
}
Vault::Vault(PcpContext P, string filename) {
PTX = P;
V = pcpvault_init(PTX.ptx, (char *)filename.c_str());
if (V == NULL) if (V == NULL)
throw pcp::exception(); throw pcp::exception(PTX);
} }
Vault::~Vault() { Vault::~Vault() {
pcpvault_close(V); pcpvault_close(PTX.ptx, V);
pcphash_clean();
} }
std::map<std::string, Key> Vault::keys() { std::map<std::string, Key> Vault::keys() {
std::map<std::string, Key> kmap; std::map<std::string, Key> kmap;
pcp_key_t *k = NULL; pcp_key_t *k = NULL;
pcphash_iterate(k) { pcphash_iterate(PTX.ptx, k) {
kmap.insert ( pair<string,Key>(string(k->id), Key(k, true)) ); kmap.insert ( pair<string,Key>(string(k->id), Key(PTX, k, true)) );
} }
return kmap; return kmap;
@@ -55,39 +59,39 @@ std::map<std::string, PubKey> Vault::pubkeys() {
std::map<std::string, PubKey> kmap; std::map<std::string, PubKey> kmap;
pcp_pubkey_t *k = NULL; pcp_pubkey_t *k = NULL;
pcphash_iteratepub(k) { pcphash_iteratepub(PTX.ptx, k) {
kmap.insert ( pair<string,PubKey>(string(k->id), PubKey(k, true)) ); kmap.insert ( pair<string,PubKey>(string(k->id), PubKey(PTX, k, true)) );
} }
return kmap; return kmap;
} }
int Vault::key_count() { int Vault::key_count() {
return pcphash_count(); return pcphash_count(PTX.ptx);
} }
int Vault::pubkey_count() { int Vault::pubkey_count() {
return pcphash_countpub(); return pcphash_countpub(PTX.ptx);
} }
void Vault::key_add(Key &key) { void Vault::key_add(Key &key) {
if(V->isnew == 1 || HASH_COUNT(pcpkey_hash) == 0) { if(V->isnew == 1 || pcphash_count(PTX.ptx) == 0) {
key.K->type = PCP_KEY_TYPE_MAINSECRET; key.K->type = PCP_KEY_TYPE_MAINSECRET;
} }
if(pcpvault_addkey(V, (void *)key.K, key.K->type) != 0) if(pcpvault_addkey(PTX.ptx, V, (void *)key.K, key.K->type) != 0)
throw pcp::exception(); throw pcp::exception(PTX);
key.is_stored(true); key.is_stored(true);
} }
void Vault::pubkey_add(PubKey &key) { void Vault::pubkey_add(PubKey &key) {
if(pcpvault_addkey(V, (void *)key.K, key.K->type) != 0) if(pcpvault_addkey(PTX.ptx, V, (void *)key.K, key.K->type) != 0)
throw pcp::exception(); throw pcp::exception(PTX);
key.is_stored(true); key.is_stored(true);
} }
bool Vault::key_exists(string &id) { bool Vault::key_exists(string &id) {
pcp_key_t *s = pcphash_keyexists((char *)id.c_str()); pcp_key_t *s = pcphash_keyexists(PTX.ptx, (char *)id.c_str());
if(s == NULL) if(s == NULL)
return false; return false;
else else
@@ -95,7 +99,7 @@ bool Vault::key_exists(string &id) {
} }
bool Vault::pubkey_exists(string &id) { bool Vault::pubkey_exists(string &id) {
pcp_pubkey_t *p = pcphash_pubkeyexists((char *)id.c_str()); pcp_pubkey_t *p = pcphash_pubkeyexists(PTX.ptx, (char *)id.c_str());
if(p == NULL) if(p == NULL)
return false; return false;
else else
@@ -103,63 +107,63 @@ bool Vault::pubkey_exists(string &id) {
} }
void Vault::key_delete(std::string &id) { void Vault::key_delete(std::string &id) {
pcp_pubkey_t *p = pcphash_pubkeyexists((char *)id.c_str()); pcp_pubkey_t *p = pcphash_pubkeyexists(PTX.ptx, (char *)id.c_str());
if(p != NULL) { if(p != NULL) {
// delete public // delete public
HASH_DEL(pcppubkey_hash, p); pcphash_del(PTX.ptx, p, p->type);
free(p); free(p);
V->unsafed = 1; V->unsafed = 1;
} }
else { else {
pcp_key_t *s = pcphash_keyexists((char *)id.c_str()); pcp_key_t *s = pcphash_keyexists(PTX.ptx, (char *)id.c_str());
if(s != NULL) { if(s != NULL) {
// delete secret // delete secret
HASH_DEL(pcpkey_hash, s); pcphash_del(PTX.ptx, s, s->type);
free(s); free(s);
V->unsafed = 1; V->unsafed = 1;
} }
else { else {
throw exception("Key not found!\n"); throw exception(PTX, "Key not found!\n");
} }
} }
} }
Key Vault::get_primary() { Key Vault::get_primary() {
pcp_key_t *k = NULL; pcp_key_t *k = NULL;
pcphash_iterate(k) { pcphash_iterate(PTX.ptx, k) {
if(k->type == PCP_KEY_TYPE_MAINSECRET) { if(k->type == PCP_KEY_TYPE_MAINSECRET) {
return Key(k); return Key(PTX, k);
} }
} }
if(Vault::key_count() == 1) { if(Vault::key_count() == 1) {
pcphash_iterate(k) { pcphash_iterate(PTX.ptx, k) {
return Key(k); return Key(PTX, k);
} }
} }
// too bad // too bad
throw exception("No primary key found in vault."); throw exception(PTX, "No primary key found in vault.");
} }
Key Vault::get_secret(std::string &id) { Key Vault::get_secret(std::string &id) {
pcp_key_t *k = NULL; pcp_key_t *k = NULL;
pcphash_iterate(k) { pcphash_iterate(PTX.ptx, k) {
if(memcmp(k->id, id.c_str(), 16) == 0) { if(memcmp(k->id, id.c_str(), 16) == 0) {
return Key(k); return Key(PTX, k);
} }
} }
throw exception("Secret key doesn't exist in vault."); throw exception(PTX, "Secret key doesn't exist in vault.");
} }
PubKey Vault::get_public(std::string &id) { PubKey Vault::get_public(std::string &id) {
pcp_pubkey_t *k = NULL; pcp_pubkey_t *k = NULL;
pcphash_iteratepub(k) { pcphash_iteratepub(PTX.ptx, k) {
if(memcmp(k->id, id.c_str(), 16) == 0) { if(memcmp(k->id, id.c_str(), 16) == 0) {
return PubKey(k); return PubKey(PTX, k);
} }
} }
throw exception("Public key doesn't exist in vault."); throw exception(PTX, "Public key doesn't exist in vault.");
} }

View File

@@ -22,6 +22,7 @@ PCPEXPORT = pcp.h \
pcp/buffer.h \ pcp/buffer.h \
pcp/mgmt.h \ pcp/mgmt.h \
pcp/pcpstream.h \ pcp/pcpstream.h \
pcp/keysig.h pcp/keysig.h \
pcp/context.h
nobase_include_HEADERS = $(PCPEXPORT) nobase_include_HEADERS = $(PCPEXPORT)

View File

@@ -9,6 +9,7 @@ extern "C" {
#include "pcp/base85.h" #include "pcp/base85.h"
#include "pcp/buffer.h" #include "pcp/buffer.h"
#include "pcp/config.h" #include "pcp/config.h"
#include "pcp/context.h"
#include "pcp/crypto.h" #include "pcp/crypto.h"
#include "pcp/defines.h" #include "pcp/defines.h"
#include "pcp/digital_crc32.h" #include "pcp/digital_crc32.h"
@@ -27,6 +28,7 @@ extern "C" {
#include "pcp/plist.h" #include "pcp/plist.h"
#include "pcp/randomart.h" #include "pcp/randomart.h"
#include "pcp/scrypt.h" #include "pcp/scrypt.h"
#include "pcp/structs.h"
#include "pcp/uthash.h" #include "pcp/uthash.h"
#include "pcp/util.h" #include "pcp/util.h"
#include "pcp/vault.h" #include "pcp/vault.h"

View File

@@ -12,6 +12,7 @@ Licensed under the terms of the LGPL 2.1.
#include <string.h> #include <string.h>
#include <stdio.h> #include <stdio.h>
#include "defines.h" #include "defines.h"
#include "context.h"
#undef DEBUG_85 #undef DEBUG_85
@@ -26,10 +27,10 @@ Licensed under the terms of the LGPL 2.1.
#endif #endif
int decode_85(char *dst, const char *buffer, int len); int decode_85(PCPCTX *ptx, char *dst, const char *buffer, int len);
void encode_85(char *buf, const unsigned char *data, int bytes); void encode_85(char *buf, const unsigned char *data, int bytes);
#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) #define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
#define error(...) (fatal(__VA_ARGS__), -1) #define error(...) (fatal(ptx, __VA_ARGS__), -1)
#endif /* HAVE_BASE85_H */ #endif /* HAVE_BASE85_H */

View File

@@ -27,6 +27,8 @@
#include "mem.h" #include "mem.h"
#include "util.h" #include "util.h"
#include "defines.h" #include "defines.h"
#include "structs.h"
#include "context.h"
/** /**
* \defgroup Buffer BUFFER * \defgroup Buffer BUFFER
@@ -44,22 +46,7 @@
*/ */
/** \struct _pcp_buffer
A flexible buffer object wich automatically resizes, if neccessary.
*/
struct _pcp_buffer {
char *name; /**< just for convenience in error messages and the like, so we know which buffer cause trouble */
uint8_t allocated; /**< marks the buffer as allocated */
size_t blocksize; /**< the blocksize to use when resizing, also used for initial malloc() */
size_t size; /**< stores the current allocated size of the object */
size_t offset; /**< current read position */
size_t end; /**< current write position, data end. maybe less than size. */
uint8_t isstring; /**< treat as char array/string */
void *buf; /**< the actual storage buffer */
};
/** The name used everywhere */
typedef struct _pcp_buffer Buffer;
/** Create a new buffer. /** Create a new buffer.
@@ -591,8 +578,7 @@ uint64_t buffer_last64(Buffer *b);
\param[in] len The number of bytes to read. \param[in] len The number of bytes to read.
\return Returns the number of bytes read or 0 in case of an error or EOF. \return Returns the number of bytes read or 0 in case of an error or EOF.
Use feof() and ferror() to check this afterwards, call fatals_ifany() Use feof() and ferror() to check this afterwards.
in case of errors.
*/ */
size_t buffer_fd_read(Buffer *b, FILE *in, size_t len); size_t buffer_fd_read(Buffer *b, FILE *in, size_t len);

95
include/pcp/context.h Normal file
View File

@@ -0,0 +1,95 @@
/*
This file is part of Pretty Curved Privacy (pcp1).
Copyright (C) 2013-2014 T.v.Dein.
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 <http://www.gnu.org/licenses/>.
You can contact me by mail: <tom AT vondein DOT org>.
*/
#ifndef _HAVE_PCP_CONTEXT_H
#define _HAVE_PCP_CONTEXT_H
#include "defines.h"
#include "platform.h"
#include "uthash.h"
#include "structs.h"
#include "mem.h"
#include "keyhash.h"
/**
* \defgroup CONTEXT CONTEXT
* @{
A couple of context functions to catch errors and display them.
The context also holds the key hashes.
*/
/** Create a new PCP Context.
Sets all context pointers to NULL.
\return the context object.
*/
PCPCTX *ptx_new();
/** Frees the memory allocated by the context.
\param[in] PCP Context object.
*/
void ptx_clean(PCPCTX *ptx);
/** Set an error message.
This function gets a printf() like error message,
which it stores in the global PCP_ERR variable
and sets PCP_ERRSET to 1.
\param[in] PCP Context object.
\param[in] fmt printf() like format description.
\param[in] ... format parameters, if any.
*/
void fatal(PCPCTX *ptx, const char * fmt, ...);
/** Prints error messages to STDERR, if there are some.
FIXME: add something like this which returns the
message.
\param[in] PCP Context object.
*/
void fatals_ifany(PCPCTX *ptx);
/** Reset the error variables.
This can be used to ignore previous errors.
Use with care.
\param[in] PCP Context object.
*/
void fatals_reset(PCPCTX *ptx);
/* same as fatal() but dies immediately */
void final(const char * fmt, ...);
#endif // _HAVE_PCP_CONTEXT_H

View File

@@ -35,6 +35,7 @@
#include "keyhash.h" #include "keyhash.h"
#include "ed.h" #include "ed.h"
#include "pcpstream.h" #include "pcpstream.h"
#include "context.h"
/** /**
\defgroup CRYPTO CRYPTO \defgroup CRYPTO CRYPTO
@@ -146,7 +147,7 @@ int pcp_sodium_verify_box(byte **cleartext, byte* message,
\return Returns an allocated byte array of the size csize which contains the encrypted result. \return Returns an allocated byte array of the size csize which contains the encrypted result.
In case of an error, it returns NULL sets csize to 0. Use fatals_ifany() to check for errors. In case of an error, it returns NULL sets csize to 0. Use fatals_ifany() to check for errors.
*/ */
byte *pcp_box_encrypt(pcp_key_t *secret, pcp_pubkey_t *pub, byte *pcp_box_encrypt(PCPCTX *ptx, pcp_key_t *secret, pcp_pubkey_t *pub,
byte *message, size_t messagesize, byte *message, size_t messagesize,
size_t *csize); size_t *csize);
@@ -157,6 +158,8 @@ byte *pcp_box_encrypt(pcp_key_t *secret, pcp_pubkey_t *pub,
requirement to work with raw NaCL crypto_box() output. This requirement to work with raw NaCL crypto_box() output. This
function adds the neccessary padding and it uses PCP key structures. function adds the neccessary padding and it uses PCP key structures.
\param[in] pcp context.
\param[in] secret The secret key structure from the sender. \param[in] secret The secret key structure from the sender.
\param[in] pub The public key structure from the recipient. \param[in] pub The public key structure from the recipient.
@@ -170,7 +173,7 @@ byte *pcp_box_encrypt(pcp_key_t *secret, pcp_pubkey_t *pub,
\return Returns an allocated byte array of the size csize which contains the encrypted result. \return Returns an allocated byte array of the size csize which contains the encrypted result.
In case of an error, it returns NULL sets csize to 0. Use fatals_ifany() to check for errors. In case of an error, it returns NULL sets csize to 0. Use fatals_ifany() to check for errors.
*/ */
byte *pcp_box_decrypt(pcp_key_t *secret, pcp_pubkey_t *pub, byte *pcp_box_decrypt(PCPCTX *ptx, pcp_key_t *secret, pcp_pubkey_t *pub,
byte *cipher, size_t ciphersize, byte *cipher, size_t ciphersize,
size_t *dsize); size_t *dsize);
@@ -182,6 +185,8 @@ byte *pcp_box_decrypt(pcp_key_t *secret, pcp_pubkey_t *pub,
Calls pcp_encrypt_stream_sym() after assembling the encrypted recipient list. Calls pcp_encrypt_stream_sym() after assembling the encrypted recipient list.
\param[in] pcp context.
\param[in] in Stream to read the data to encrypt from. \param[in] in Stream to read the data to encrypt from.
\param[out] out Stream to write encrypted result to. \param[out] out Stream to write encrypted result to.
@@ -194,7 +199,7 @@ byte *pcp_box_decrypt(pcp_key_t *secret, pcp_pubkey_t *pub,
\return Returns the size of the output written to the output stream or 0 in case of errors. \return Returns the size of the output written to the output stream or 0 in case of errors.
*/ */
size_t pcp_encrypt_stream(Pcpstream *in, Pcpstream* out, pcp_key_t *s, pcp_pubkey_t *p, int signcrypt); size_t pcp_encrypt_stream(PCPCTX *ptx, Pcpstream *in, Pcpstream* out, pcp_key_t *s, pcp_pubkey_t *p, int signcrypt);
/** Symmetrically encrypt a file or a buffer stream. /** Symmetrically encrypt a file or a buffer stream.
@@ -204,6 +209,8 @@ size_t pcp_encrypt_stream(Pcpstream *in, Pcpstream* out, pcp_key_t *s, pcp_pubke
Uses crypto_secret_box() for each 32k-block with a random nonce for each. Uses crypto_secret_box() for each 32k-block with a random nonce for each.
\param[in] pcp context.
\param[in] in Stream to read the data to encrypt from. \param[in] in Stream to read the data to encrypt from.
\param[out] out Stream to write encrypted result to. \param[out] out Stream to write encrypted result to.
@@ -217,7 +224,7 @@ size_t pcp_encrypt_stream(Pcpstream *in, Pcpstream* out, pcp_key_t *s, pcp_pubke
\return Returns the size of the output written to the output stream or 0 in case of errors. \return Returns the size of the output written to the output stream or 0 in case of errors.
*/ */
size_t pcp_encrypt_stream_sym(Pcpstream *in, Pcpstream* out, byte *symkey, int havehead, pcp_rec_t *recsign); size_t pcp_encrypt_stream_sym(PCPCTX *ptx, Pcpstream *in, Pcpstream* out, byte *symkey, int havehead, pcp_rec_t *recsign);
/** Asymmetrically decrypt a file or a buffer stream. /** Asymmetrically decrypt a file or a buffer stream.
@@ -229,6 +236,8 @@ size_t pcp_encrypt_stream_sym(Pcpstream *in, Pcpstream* out, byte *symkey, int h
FIXME: should return the pcp_rec_t structure upon successfull verification somehow. FIXME: should return the pcp_rec_t structure upon successfull verification somehow.
\param[in] pcp context.
\param[in] in Stream to read the data to decrypt from. \param[in] in Stream to read the data to decrypt from.
\param[out] out Stream to write decrypted result to. \param[out] out Stream to write decrypted result to.
@@ -241,7 +250,7 @@ size_t pcp_encrypt_stream_sym(Pcpstream *in, Pcpstream* out, byte *symkey, int h
\return Returns the size of the output written to the output stream or 0 in case of errors. \return Returns the size of the output written to the output stream or 0 in case of errors.
*/ */
size_t pcp_decrypt_stream(Pcpstream *in, Pcpstream* out, pcp_key_t *s, byte *symkey, int verify); size_t pcp_decrypt_stream(PCPCTX *ptx, Pcpstream *in, Pcpstream* out, pcp_key_t *s, byte *symkey, int verify);
/** Symmetrically decrypt a file or a buffer stream. /** Symmetrically decrypt a file or a buffer stream.
@@ -253,6 +262,8 @@ size_t pcp_decrypt_stream(Pcpstream *in, Pcpstream* out, pcp_key_t *s, byte *sym
Uses crypto_secret_box_open() for each 32k+16-block with a random nonce for each. Uses crypto_secret_box_open() for each 32k+16-block with a random nonce for each.
\param[in] pcp context.
\param[in] in Stream to read the data to decrypt from. \param[in] in Stream to read the data to decrypt from.
\param[out] out Stream to write decrypted result to. \param[out] out Stream to write decrypted result to.
@@ -263,7 +274,7 @@ size_t pcp_decrypt_stream(Pcpstream *in, Pcpstream* out, pcp_key_t *s, byte *sym
\return Returns the size of the output written to the output stream or 0 in case of errors. \return Returns the size of the output written to the output stream or 0 in case of errors.
*/ */
size_t pcp_decrypt_stream_sym(Pcpstream *in, Pcpstream* out, byte *symkey, pcp_rec_t *recverify); size_t pcp_decrypt_stream_sym(PCPCTX *ptx, Pcpstream *in, Pcpstream* out, byte *symkey, pcp_rec_t *recverify);
pcp_rec_t *pcp_rec_new(byte *cipher, size_t clen, pcp_key_t *secret, pcp_pubkey_t *pub); pcp_rec_t *pcp_rec_new(byte *cipher, size_t clen, pcp_key_t *secret, pcp_pubkey_t *pub);
void pcp_rec_free(pcp_rec_t *r); void pcp_rec_free(pcp_rec_t *r);

View File

@@ -137,66 +137,45 @@ typedef enum _PCP_KEY_TYPES {
#define PCP_RFC_CIPHER 0x21 /* curve25519+ed25519+poly1305+salsa20+blake2 */ #define PCP_RFC_CIPHER 0x21 /* curve25519+ed25519+poly1305+salsa20+blake2 */
/**
* \defgroup FATALS FATALS
* @{
A couple of functions to catch errors and display them.
*/ /* defines for key management (mgmt.c) */
#define EXP_PK_CIPHER 0x21
#define EXP_PK_CIPHER_NAME "CURVE25519-ED25519-POLY1305-SALSA20"
/* error handling */ #define EXP_HASH_CIPHER 0x22
#define EXP_HASH_NAME "BLAKE2"
/** \var PCP_ERR #define EXP_SIG_CIPHER 0x23
#define EXP_SIG_CIPHER_NAME "ED25519"
Global variable holding the last error message. #define EXP_SIG_VERSION 0x01
Can be retrieved with fatals_ifany(). #define EXP_SIG_TYPE 0x1F /* self signed */
*/
extern char *PCP_ERR;
/** \var PCP_ERRSET /* sig sub notiation we support */
#define EXP_SIG_SUB_CTIME 2
#define EXP_SIG_SUB_SIGEXPIRE 3
#define EXP_SIG_SUB_KEYEXPIRE 9
#define EXP_SIG_SUB_NOTATION 20
#define EXP_SIG_SUB_KEYFLAGS 27
Global variable indicating if an error occurred. /* in armored mode, we're using the usual head+foot */
*/ #define EXP_PK_HEADER "----- BEGIN ED25519-CURVE29915 PUBLIC KEY -----"
extern byte PCP_ERRSET; #define EXP_PK_FOOTER "----- END ED25519-CURVE29915 PUBLIC KEY -----"
#define EXP_SK_HEADER "----- BEGIN ED25519-CURVE29915 PRIVATE KEY -----"
#define EXP_SK_FOOTER "----- END ED25519-CURVE29915 PRIVATE KEY -----"
/** \var PCP_EXIT
Exitcode for the pcp commandline utility. /* pubkey export formats */
*/ #define EXP_FORMAT_NATIVE 1
extern int PCP_EXIT; #define EXP_FORMAT_PBP 2
#define EXP_FORMAT_YAML 3
#define EXP_FORMAT_C 4
#define EXP_FORMAT_PY 5
#define EXP_FORMAT_PERL 6
/** Set an error message.
This function gets a printf() like error message,
which it stores in the global PCP_ERR variable
and sets PCP_ERRSET to 1.
\param[in] fmt printf() like format description.
\param[in] ... format parameters, if any.
*/
void fatal(const char * fmt, ...);
/** Prints error messages to STDERR, if there are some.
FIXME: add something like this which returns the
message.
*/
void fatals_ifany();
/** Reset the error variables.
This can be used to ignore previous errors.
Use with care.
*/
void fatals_reset();
/** Cleans up memory allocation of global error variables.
*/
void fatals_done();
extern int PCPVERBOSE;
#endif /* _DEFINES_H */ #endif /* _DEFINES_H */

View File

@@ -41,6 +41,7 @@
#include "keyhash.h" #include "keyhash.h"
#include "util.h" #include "util.h"
#include "pcpstream.h" #include "pcpstream.h"
#include "context.h"
/** Sign a raw message. /** Sign a raw message.
@@ -80,6 +81,8 @@ byte *pcp_ed_sign(byte *message, size_t messagesize, pcp_key_t *s);
The signature must contain the message+nacl signature (with size crypto_sign_BYTES). The signature must contain the message+nacl signature (with size crypto_sign_BYTES).
\param[in] pcp context.
\param[in] signature Message+signature. \param[in] signature Message+signature.
\param[in] siglen Size of message+signature. \param[in] siglen Size of message+signature.
@@ -89,7 +92,7 @@ byte *pcp_ed_sign(byte *message, size_t messagesize, pcp_key_t *s);
\return If the signature verifies return the raw message with the signature removed (size: siglen - crypto_sign_BYTES), \return If the signature verifies return the raw message with the signature removed (size: siglen - crypto_sign_BYTES),
returns NULL in case of errors. Check fatals_if_any(). returns NULL in case of errors. Check fatals_if_any().
*/ */
byte *pcp_ed_verify(byte *signature, size_t siglen, pcp_pubkey_t *p); byte *pcp_ed_verify(PCPCTX *ptx, byte *signature, size_t siglen, pcp_pubkey_t *p);
/** Verify a signature using the mastersecret. /** Verify a signature using the mastersecret.
@@ -97,6 +100,8 @@ byte *pcp_ed_verify(byte *signature, size_t siglen, pcp_pubkey_t *p);
The signature must contain the message+nacl signature (with size crypto_sign_BYTES). The signature must contain the message+nacl signature (with size crypto_sign_BYTES).
\param[in] pcp context.
\param[in] signature Message+signature. \param[in] signature Message+signature.
\param[in] siglen Size of message+signature. \param[in] siglen Size of message+signature.
@@ -106,7 +111,7 @@ byte *pcp_ed_verify(byte *signature, size_t siglen, pcp_pubkey_t *p);
\return If the signature verifies return the raw message with the signature removed (size: siglen - crypto_sign_BYTES), \return If the signature verifies return the raw message with the signature removed (size: siglen - crypto_sign_BYTES),
returns NULL in case of errors. Check fatals_if_any(). returns NULL in case of errors. Check fatals_if_any().
*/ */
byte *pcp_ed_verify_key(byte *signature, size_t siglen, pcp_pubkey_t *p); byte *pcp_ed_verify_key(PCPCTX *ptx, byte *signature, size_t siglen, pcp_pubkey_t *p);
/** Sign a stream in 32k block mode. /** Sign a stream in 32k block mode.
@@ -114,6 +119,8 @@ byte *pcp_ed_verify_key(byte *signature, size_t siglen, pcp_pubkey_t *p);
of the contents of the stream. It outputs the stream to \a out, also blockwise of the contents of the stream. It outputs the stream to \a out, also blockwise
and appends the signature afterwards, which consists of the hash+nacl-signature. and appends the signature afterwards, which consists of the hash+nacl-signature.
\param[in] pcp context.
\param[in] in Stream to read from. \param[in] in Stream to read from.
\param[out] out Stream to write to. \param[out] out Stream to write to.
@@ -125,7 +132,7 @@ byte *pcp_ed_verify_key(byte *signature, size_t siglen, pcp_pubkey_t *p);
\return Returns the number of bytes written to the output stream. \return Returns the number of bytes written to the output stream.
*/ */
size_t pcp_ed_sign_buffered(Pcpstream *in, Pcpstream *out, pcp_key_t *s, int z85); size_t pcp_ed_sign_buffered(PCPCTX *ptx, Pcpstream *in, Pcpstream *out, pcp_key_t *s, int z85);
/** Verify a signature from a stream in 32k block mode. /** Verify a signature from a stream in 32k block mode.
@@ -140,6 +147,8 @@ size_t pcp_ed_sign_buffered(Pcpstream *in, Pcpstream *out, pcp_key_t *s, int z85
the global public key hash pcppubkey_hash to find a public key which is able to verify the global public key hash pcppubkey_hash to find a public key which is able to verify
the signature. the signature.
\param[in] pcp context.
\param[in] in Stream to read from. \param[in] in Stream to read from.
\param[in] p Pointer to public key structure. \param[in] p Pointer to public key structure.
@@ -147,7 +156,7 @@ size_t pcp_ed_sign_buffered(Pcpstream *in, Pcpstream *out, pcp_key_t *s, int z85
\return Returns a pointer to a public key which were used to verify the signature or NULL if \return Returns a pointer to a public key which were used to verify the signature or NULL if
an error occurred. Check fatals_if_any(). an error occurred. Check fatals_if_any().
*/ */
pcp_pubkey_t *pcp_ed_verify_buffered(Pcpstream *in, pcp_pubkey_t *p); pcp_pubkey_t *pcp_ed_verify_buffered(PCPCTX *ptx, Pcpstream *in, pcp_pubkey_t *p);
/** Generate a detached signature from a stream in 32k block mode. /** Generate a detached signature from a stream in 32k block mode.
@@ -174,6 +183,8 @@ size_t pcp_ed_detachsign_buffered(Pcpstream *in, Pcpstream *out, pcp_key_t *s);
the signature hash with the hash it calculated the signature hash with the hash it calculated
from the signed content. from the signed content.
\param[in] pcp context.
\param[in] in Stream to read from. \param[in] in Stream to read from.
\param[in] sigfd Stream containing the detached signature. \param[in] sigfd Stream containing the detached signature.
@@ -184,7 +195,7 @@ size_t pcp_ed_detachsign_buffered(Pcpstream *in, Pcpstream *out, pcp_key_t *s);
an error occurred. Check fatals_if_any(). an error occurred. Check fatals_if_any().
*/ */
pcp_pubkey_t *pcp_ed_detachverify_buffered(Pcpstream *in, Pcpstream *sigfd, pcp_pubkey_t *p); pcp_pubkey_t *pcp_ed_detachverify_buffered(PCPCTX *ptx, Pcpstream *in, Pcpstream *sigfd, pcp_pubkey_t *p);
#endif /* _HAVE_PCP_ED_H */ #endif /* _HAVE_PCP_ED_H */

View File

@@ -31,16 +31,16 @@
#include "defines.h" #include "defines.h"
#include "platform.h" #include "platform.h"
#include "mem.h" #include "mem.h"
#include "buffer.h"
#include "mac.h" #include "mac.h"
#include "randomart.h" #include "randomart.h"
#include "version.h" #include "version.h"
#include "z85.h" //#include "z85.h"
#include "uthash.h" #include "uthash.h"
#include "jenhash.h" #include "jenhash.h"
#include "scrypt.h" #include "structs.h"
#include "buffer.h"
#include "keysig.h" #include "keysig.h"
#include "scrypt.h"
/** /**
* \defgroup KEYS KEYS * \defgroup KEYS KEYS
@@ -53,126 +53,7 @@
*/ */
/** \struct _pcp_key_t
PCP private key structure. Most fields are self explanatory.
Some notes:
'encrypted' contains the encrypted secret keys (contatenated mastersecret,
secret and edsecret). If it's set,
the field 'secret' which contains the clear secret key will
be zeroed with random values, the first byte will be 0. Same
for the field 'edsecret'.
'nonce' contains the nonce required to decrypt the encrypted
secret, if set.
'serial' is a random number.
'id' is a string containing the hex values of the CRC32 checksum
of the public and secret key.
Upon creation everything will be filled with random bytes.
String fields will contain a string followed by 0 followed
by the rest of the pre-filled random bytes. To denote a string
field as empty, the first byte will be set to 0.
There are dynamically calculated attributes as well:
'checksum' is a 256 bit SHA hash of the public key returned
by pcpkey_getchecksum() or pcppubkey_getchecksum().
'random id' is a random art ascii image returned by
pcppubkey_get_art() or pcpkey_get_art(), calculated from
the public key.
If exported to a single file or printed, the structure will
be encoded using Z85 encoding.
*/
struct _pcp_key_t {
byte masterpub[32]; /**< ED25519 master public key signing key */
byte mastersecret[64]; /**< ED25519 master secret key signing key */
byte pub[32]; /**< Curve25519 encryption public key */
byte secret[32]; /**< Curve25519 encryption secret key */
byte edpub[32]; /**< ED25519 public signing key */
byte edsecret[64]; /**< ED25519 secret signing key */
byte nonce[24]; /**< random nonce used to encrypt secret keys */
byte encrypted[176]; /**< concatenated and encrypted secret keys */
char owner[255]; /**< the key owner, string */
char mail[255]; /**< mail address of the owner, string */
char id[17]; /**< key-id, used internally only, jenhash of public keys */
uint8_t type; /**< key type: MASTER_SECRET or SECRET */
uint64_t ctime; /**< creation time, epoch */
uint32_t version; /**< key version */
uint32_t serial; /**< serial number of the key, randomly generated */
UT_hash_handle hh;
};
/** Typedef for secret keys */
typedef struct _pcp_key_t pcp_key_t;
/** \struct _pcp_pubkey_t
PCP public key structure.
This structure contains a subset of the pcp_key_t structure
without the secret and nonce fields.
*/
struct _pcp_pubkey_t {
byte masterpub[32]; /**< ED25519 master public key signing key */
byte sigpub[32]; /**< ED25519 public signing key */
byte pub[32]; /**< Curve25519 encryption public key */
byte edpub[32]; /**< ED25519 public signing key (FIXME: huh? 2 of them???) */
char owner[255]; /**< the key owner, string */
char mail[255]; /**< mail address of the owner, string */
char id[17]; /**< key-id, used internally only, jenhash of public keys */
uint8_t type; /**< key type: MASTER_SECRET or SECRET */
uint64_t ctime; /**< creation time, epoch */
uint32_t version; /**< key version */
uint32_t serial; /**< serial number of the key, randomly generated */
uint8_t valid; /**< 1 if import signature verified, 0 if not */
byte signature[crypto_generichash_BYTES_MAX + crypto_sign_BYTES]; /**< raw binary blob of pubkey export signature */
UT_hash_handle hh;
};
/** Typedef for public keys */
typedef struct _pcp_pubkey_t pcp_pubkey_t;
/* the PBP public key format */
/* keys.mp+keys.cp+keys.sp+keys.name */
struct _pbp_pubkey_t {
byte sigpub[crypto_sign_PUBLICKEYBYTES];
byte edpub[crypto_sign_PUBLICKEYBYTES];
byte pub[crypto_box_PUBLICKEYBYTES];
char iso_ctime[32];
char iso_expire[32];
char name[1024];
};
typedef struct _pbp_pubkey_t pbp_pubkey_t;
/** \struct _pcp_rec_t
Encrypted recipient list.
Encrypted recipient list, required for crypt+sign
contains the encrypted recipients and the secret
key required for signing the message+recipients.
Used internally only.
*/
struct _pcp_rec_t {
size_t ciphersize; /**< the size of the encrypted recipient list */
byte *cipher; /**< contains the whole encrypted recipient list */
pcp_key_t *secret; /**< the secret key of the recipient for signing */
pcp_pubkey_t *pub; /**< if verification were ok, contains the public key of the signer */
};
/** Typedef for public keys */
typedef struct _pcp_rec_t pcp_rec_t;
#define PCP_RAW_KEYSIZE sizeof(pcp_key_t) - sizeof(UT_hash_handle) #define PCP_RAW_KEYSIZE sizeof(pcp_key_t) - sizeof(UT_hash_handle)
#define PCP_RAW_PUBKEYSIZE sizeof(pcp_pubkey_t) - sizeof(UT_hash_handle) #define PCP_RAW_PUBKEYSIZE sizeof(pcp_pubkey_t) - sizeof(UT_hash_handle)
@@ -253,6 +134,8 @@ char *pcpkey_get_art(pcp_key_t *k);
The caller is responsible to clear the passphrase right after The caller is responsible to clear the passphrase right after
use and free() it as soon as possible. use and free() it as soon as possible.
\param[in] pcp context.
\param[in,out] key The secret key structure. \param[in,out] key The secret key structure.
\param[in] passphrase The passphrase used to encrypt the key. \param[in] passphrase The passphrase used to encrypt the key.
@@ -260,7 +143,7 @@ char *pcpkey_get_art(pcp_key_t *k);
\return Returns a pointer to the encrypted key structure or NULL \return Returns a pointer to the encrypted key structure or NULL
in case of an error. Use fatals_ifany() to catch them. in case of an error. Use fatals_ifany() to catch them.
*/ */
pcp_key_t *pcpkey_encrypt(pcp_key_t *key, char *passphrase); pcp_key_t *pcpkey_encrypt(PCPCTX *ptx, pcp_key_t *key, char *passphrase);
/** Decrypt a secret key structure. /** Decrypt a secret key structure.
@@ -277,6 +160,8 @@ pcp_key_t *pcpkey_encrypt(pcp_key_t *key, char *passphrase);
The caller is responsible to clear the passphrase right after The caller is responsible to clear the passphrase right after
use and free() it as soon as possible. use and free() it as soon as possible.
\param[in] pcp context.
\param[in,out] key The secret key structure. \param[in,out] key The secret key structure.
\param[in] passphrase The passphrase used to decrypt the key. \param[in] passphrase The passphrase used to decrypt the key.
@@ -285,7 +170,7 @@ pcp_key_t *pcpkey_encrypt(pcp_key_t *key, char *passphrase);
in case of an error. Use fatals_ifany() to catch them. in case of an error. Use fatals_ifany() to catch them.
*/ */
pcp_key_t *pcpkey_decrypt(pcp_key_t *key, char *passphrase); pcp_key_t *pcpkey_decrypt(PCPCTX *ptx, pcp_key_t *key, char *passphrase);
/** Generate a public key structure from a given secret key structure. /** Generate a public key structure from a given secret key structure.
@@ -294,6 +179,8 @@ pcp_key_t *pcpkey_decrypt(pcp_key_t *key, char *passphrase);
The caller is responsible to clear and free() it after use. The caller is responsible to clear and free() it after use.
\param[in] pcp context.
\param[in] key The secret key structure. \param[in] key The secret key structure.
\return Returns a new pcp_pubkey_t structure. \return Returns a new pcp_pubkey_t structure.
@@ -404,7 +291,7 @@ byte * pcp_gennonce();
/* use scrypt() to create a key from a passphrase and a nonce /* use scrypt() to create a key from a passphrase and a nonce
this is a wrapper around pcp_scrypt() this is a wrapper around pcp_scrypt()
*/ */
byte *pcp_derivekey(char *passphrase, byte *nonce); byte *pcp_derivekey(PCPCTX *ptx, char *passphrase, byte *nonce);
/* convert the key struct into a binary blob */ /* convert the key struct into a binary blob */
void pcp_seckeyblob(Buffer *b, pcp_key_t *k); void pcp_seckeyblob(Buffer *b, pcp_key_t *k);
@@ -418,19 +305,23 @@ Buffer *pcp_keyblob(void *k, int type); /* allocates blob */
\return Returns 1 if the sanity check succeeds, 0 otherwise. \return Returns 1 if the sanity check succeeds, 0 otherwise.
Use fatals_ifany() to check why. Use fatals_ifany() to check why.
*/ */
int pcp_sanitycheck_pub(pcp_pubkey_t *key); int pcp_sanitycheck_pub(PCPCTX *ptx, pcp_pubkey_t *key);
/** Make a sanity check of the given secret key structure. /** Make a sanity check of the given secret key structure.
\param[in] pcp context.
\param[in] key The secret key structure. \param[in] key The secret key structure.
\return Returns 1 if the sanity check succeeds, 0 otherwise. \return Returns 1 if the sanity check succeeds, 0 otherwise.
Use fatals_ifany() to check why. Use fatals_ifany() to check why.
*/ */
int pcp_sanitycheck_key(pcp_key_t *key); int pcp_sanitycheck_key(PCPCTX *ptx, pcp_key_t *key);
/** Dump a secret key structure to stderr. /** Dump a secret key structure to stderr.
\param[in] pcp context.
\param[in] k Secret key to dump. \param[in] k Secret key to dump.
*/ */
void pcp_dumpkey(pcp_key_t *k); void pcp_dumpkey(pcp_key_t *k);

View File

@@ -22,6 +22,10 @@
#ifndef _HAVE_KEYHASH_H #ifndef _HAVE_KEYHASH_H
#define _HAVE_KEYHASH_H #define _HAVE_KEYHASH_H
#include "structs.h"
/** \defgroup KEYHASH KEYHASH /** \defgroup KEYHASH KEYHASH
@{ @{
@@ -29,22 +33,11 @@
Libpcp uses the <a href="http://troydhanson.github.io/uthash/">uthash</a> Libpcp uses the <a href="http://troydhanson.github.io/uthash/">uthash</a>
system to maintain lists of keys. There's one hash per key type. The system to maintain lists of keys. There's one hash per key type. The
hash has the same type as the key structure itself, but is global. hash has the same type as the key structure itself, and is stored in
the PCP Context object.
*/ */
#include "uthash.h"
#include "key.h"
/* storage of keys in a global hash */
/** Global hash for secret keys. */
extern pcp_key_t *pcpkey_hash;
/** Global hash for public keys. */
extern pcp_pubkey_t *pcppubkey_hash;
extern pcp_key_t *__k;
extern pcp_pubkey_t *__p;
/* wrapper for HASH_ITER */ /* wrapper for HASH_ITER */
/** Iterate over the list of secret keys. /** Iterate over the list of secret keys.
@@ -53,7 +46,7 @@ extern pcp_pubkey_t *__p;
@code @code
pcp_key_t k = NULL; pcp_key_t k = NULL;
pcphash_iterate(k) { pcphash_iterate(ptx, k) {
pcp_dumpkey(k); pcp_dumpkey(k);
} }
@endcode @endcode
@@ -61,9 +54,9 @@ extern pcp_pubkey_t *__p;
Also, don't free() the keyhash or the temporary key pointer Also, don't free() the keyhash or the temporary key pointer
yourself. Use pcphash_clean() instead when done. yourself. Use pcphash_clean() instead when done.
*/ */
#define pcphash_iterate(key) \ #define pcphash_iterate(ptx, key) \
__k = NULL; \ pcp_key_t *__k = NULL; \
HASH_ITER(hh, pcpkey_hash, key, __k) HASH_ITER(hh, ptx->pcpkey_hash, key, __k)
/** Iterate over the list of public keys. /** Iterate over the list of public keys.
@@ -72,7 +65,7 @@ extern pcp_pubkey_t *__p;
@code @code
pcp_pubkey_t k = NULL; pcp_pubkey_t k = NULL;
pcphash_iteratepub(k) { pcphash_iteratepub(ptx, k) {
pcp_dumppubkey(k); pcp_dumppubkey(k);
} }
@endcode @endcode
@@ -80,75 +73,77 @@ extern pcp_pubkey_t *__p;
Also, don't free() the keyhash or the temporary key pointer Also, don't free() the keyhash or the temporary key pointer
yourself. Use pcphash_clean() instead when done. yourself. Use pcphash_clean() instead when done.
*/ */
#define pcphash_iteratepub(key) \ #define pcphash_iteratepub(ptx, key) \
__p = NULL; \ pcp_pubkey_t *__p = NULL; \
HASH_ITER(hh, pcppubkey_hash, key, __p) HASH_ITER(hh, ptx->pcppubkey_hash, key, __p)
/** Initialize the global hashes. */
void pcphash_init();
/** Delete an entry from a hash. /** Delete an entry from a hash.
\param[in] PCP Context object.
\param[in] key A pointer to the key structure to delete. \param[in] key A pointer to the key structure to delete.
\param[in] type An integer specifying the key type to delete. \see _PCP_KEY_TYPES. \param[in] type An integer specifying the key type to delete. \see _PCP_KEY_TYPES.
*/ */
void pcphash_del(void *key, int type); void pcphash_del(PCPCTX *ptx, void *key, int type);
/** Frees the memory allocated by the hashes. /** Free memory used by key hashes. */
void pcphash_clean(PCPCTX *ptx);
Clears and frees memory of all keys in the hash lists
and the hashes themselfes.
*/
void pcphash_clean();
/** Check if a secret key with a given key-id exists in the hash. /** Check if a secret key with a given key-id exists in the hash.
\param[in] PCP Context object.
\param[in] id A string with the key-id (max 17 chars incl 0). \param[in] id A string with the key-id (max 17 chars incl 0).
\return Returns a pointer to the matching key or NULL if the id doesn't match. \return Returns a pointer to the matching key or NULL if the id doesn't match.
*/ */
pcp_key_t *pcphash_keyexists(char *id); pcp_key_t *pcphash_keyexists(PCPCTX *ptx, char *id);
/** Check if a publickey with a given key-id exists in the hash. /** Check if a publickey with a given key-id exists in the hash.
\param[in] PCP Context object.
\param[in] id A string with the key-id (max 17 chars incl 0). \param[in] id A string with the key-id (max 17 chars incl 0).
\return Returns a pointer to the matching key or NULL if the id doesn't match. \return Returns a pointer to the matching key or NULL if the id doesn't match.
*/ */
pcp_pubkey_t *pcphash_pubkeyexists(char *id); pcp_pubkey_t *pcphash_pubkeyexists(PCPCTX *ptx, char *id);
/** Add a key structure to the hash list. /** Add a key structure to the hash list.
\param[in] PCP Context object.
\param[in] key A pointer to the key structure to delete. \param[in] key A pointer to the key structure to delete.
\param[in] type An integer specifying the key type to delete. \see _PCP_KEY_TYPES. \param[in] type An integer specifying the key type to delete. \see _PCP_KEY_TYPES.
*/ */
void pcphash_add(void *key, int type); void pcphash_add(PCPCTX *ptx, void *key, int type);
/** Returns the number of secret keys in the hash. /** Returns the number of secret keys in the hash.
\param[in] PCP Context object.
\return Number of keys. \return Number of keys.
*/ */
int pcphash_count(); int pcphash_count(PCPCTX *ptx);
/** Returns the number of public keys in the hash. /** Returns the number of public keys in the hash.
\param[in] PCP Context object.
\return Number of keys. \return Number of keys.
*/ */
int pcphash_countpub(); int pcphash_countpub(PCPCTX *ptx);
/** Global hash for key signatures. */
extern pcp_keysig_t *pcpkeysig_hash;
extern pcp_keysig_t *__s;
#define pcphash_iteratekeysig(key) \
__s = NULL; \
HASH_ITER(hh, pcpkeysig_hash, key, __s)
pcp_keysig_t *pcphash_keysigexists(char *id); #define pcphash_iteratekeysig(ptx, key) \
pcp_keysig_t *__s = NULL; \
HASH_ITER(hh, ptx->pcpkeysig_hash, key, __s)
pcp_keysig_t *pcphash_keysigexists(PCPCTX *ptx, char *id);
#endif /* _HAVE_KEYHASH_H */ #endif /* _HAVE_KEYHASH_H */

View File

@@ -29,22 +29,13 @@
#include "defines.h" #include "defines.h"
#include "platform.h" #include "platform.h"
#include "mem.h" #include "mem.h"
#include "structs.h"
#include "buffer.h" #include "buffer.h"
#include "key.h" #include "key.h"
#define PCP_RAW_KEYSIGSIZE sizeof(pcp_keysig_t) - sizeof(UT_hash_handle) #define PCP_RAW_KEYSIGSIZE sizeof(pcp_keysig_t) - sizeof(UT_hash_handle)
/* holds a public key signature */
struct _pcp_keysig_t {
uint8_t type;
uint32_t size;
char id[17];
byte checksum[32];
byte *blob;
UT_hash_handle hh;
};
typedef struct _pcp_keysig_t pcp_keysig_t;
pcp_keysig_t *keysig2be(pcp_keysig_t *s); pcp_keysig_t *keysig2be(pcp_keysig_t *s);
pcp_keysig_t *keysig2native(pcp_keysig_t *s); pcp_keysig_t *keysig2native(pcp_keysig_t *s);

View File

@@ -33,12 +33,14 @@
#include "defines.h" #include "defines.h"
#include "platform.h" #include "platform.h"
#include "structs.h"
#include "mem.h" #include "mem.h"
#include "ed.h" #include "ed.h"
#include "key.h" #include "key.h"
#include "keysig.h" #include "keysig.h"
#include "buffer.h" #include "buffer.h"
#include "scrypt.h" #include "scrypt.h"
#include "context.h"
/* key management api, export, import, yaml and stuff */ /* key management api, export, import, yaml and stuff */
@@ -52,76 +54,7 @@
/* various helper structs, used internally only */
struct _pcp_rfc_pubkey_header_t {
uint8_t version;
uint32_t ctime;
uint8_t cipher;
};
struct _pcp_rfc_pubkey_0x21_t {
byte sig_ed25519_pub[crypto_sign_PUBLICKEYBYTES];
byte ed25519_pub[crypto_sign_PUBLICKEYBYTES];
byte curve25519_pub[crypto_box_PUBLICKEYBYTES];
};
struct _pcp_rfc_pubkey_sigheader_0x21_t {
uint8_t version;
uint8_t type;
uint8_t pkcipher;
uint8_t hashcipher;
uint16_t numsubs;
};
struct _pcp_rfc_pubkey_sigsub_0x21_t {
uint32_t size;
uint8_t type;
};
typedef struct _pcp_rfc_pubkey_header_t rfc_pub_h;
typedef struct _pcp_rfc_pubkey_0x21_t rfc_pub_k;
typedef struct _pcp_rfc_pubkey_sigheader_0x21_t rfc_pub_sig_h;
typedef struct _pcp_rfc_pubkey_sigsub_0x21_t rfc_pub_sig_s;
struct _pcp_ks_bundle_t {
pcp_pubkey_t *p;
pcp_keysig_t *s;
};
typedef struct _pcp_ks_bundle_t pcp_ks_bundle_t;
#define EXP_PK_CIPHER 0x21
#define EXP_PK_CIPHER_NAME "CURVE25519-ED25519-POLY1305-SALSA20"
#define EXP_HASH_CIPHER 0x22
#define EXP_HASH_NAME "BLAKE2"
#define EXP_SIG_CIPHER 0x23
#define EXP_SIG_CIPHER_NAME "ED25519"
#define EXP_SIG_VERSION 0x01
#define EXP_SIG_TYPE 0x1F /* self signed */
/* sig sub notiation we support */
#define EXP_SIG_SUB_CTIME 2
#define EXP_SIG_SUB_SIGEXPIRE 3
#define EXP_SIG_SUB_KEYEXPIRE 9
#define EXP_SIG_SUB_NOTATION 20
#define EXP_SIG_SUB_KEYFLAGS 27
/* in armored mode, we're using the usual head+foot */
#define EXP_PK_HEADER "----- BEGIN ED25519-CURVE29915 PUBLIC KEY -----"
#define EXP_PK_FOOTER "----- END ED25519-CURVE29915 PUBLIC KEY -----"
#define EXP_SK_HEADER "----- BEGIN ED25519-CURVE29915 PRIVATE KEY -----"
#define EXP_SK_FOOTER "----- END ED25519-CURVE29915 PRIVATE KEY -----"
/* pubkey export formats */
#define EXP_FORMAT_NATIVE 1
#define EXP_FORMAT_PBP 2
#define EXP_FORMAT_YAML 3
#define EXP_FORMAT_C 4
#define EXP_FORMAT_PY 5
#define EXP_FORMAT_PERL 6
/** RFC4880 alike public key export with some modifications. /** RFC4880 alike public key export with some modifications.
@@ -287,6 +220,8 @@ Buffer *pcp_export_c_pub(pcp_key_t *sk);
Nonce | Cipher Nonce | Cipher
\param[in] ptx context.
\param sk a secret key structure of type pcp_key_t. The secret keys \param sk a secret key structure of type pcp_key_t. The secret keys
in there have to be already decrypted. in there have to be already decrypted.
@@ -296,17 +231,21 @@ Buffer *pcp_export_c_pub(pcp_key_t *sk);
\return the function returns a Buffer object containing the binary \return the function returns a Buffer object containing the binary
blob in the format described above. blob in the format described above.
*/ */
Buffer *pcp_export_secret(pcp_key_t *sk, char *passphrase); Buffer *pcp_export_secret(PCPCTX *ptx, pcp_key_t *sk, char *passphrase);
pcp_ks_bundle_t *pcp_import_binpub(byte *raw, size_t rawsize); pcp_ks_bundle_t *pcp_import_binpub(PCPCTX *ptx, byte *raw, size_t rawsize);
pcp_ks_bundle_t *pcp_import_pub(byte *raw, size_t rawsize); /* FIXME: deprecate */ pcp_ks_bundle_t *pcp_import_pub(PCPCTX *ptx, byte *raw, size_t rawsize); /* FIXME: deprecate */
pcp_ks_bundle_t *pcp_import_pub_rfc(Buffer *blob); pcp_ks_bundle_t *pcp_import_pub_rfc(PCPCTX *ptx, Buffer *blob);
pcp_ks_bundle_t *pcp_import_pub_pbp(Buffer *blob); pcp_ks_bundle_t *pcp_import_pub_pbp(PCPCTX *ptx, Buffer *blob);
/* import secret key */ /* import secret key */
pcp_key_t *pcp_import_binsecret(byte *raw, size_t rawsize, char *passphrase); pcp_key_t *pcp_import_binsecret(PCPCTX *ptx, byte *raw, size_t rawsize, char *passphrase);
pcp_key_t *pcp_import_secret(byte *raw, size_t rawsize, char *passphrase); pcp_key_t *pcp_import_secret(PCPCTX *ptx, byte *raw, size_t rawsize, char *passphrase);
pcp_key_t *pcp_import_secret_native(Buffer *cipher, char *passphrase); pcp_key_t *pcp_import_secret_native(PCPCTX *ptx, Buffer *cipher, char *passphrase);
/* helpers */
int _check_keysig_h(PCPCTX *ptx, Buffer *blob, rfc_pub_sig_h *h);
int _check_hash_keysig(PCPCTX *ptx, Buffer *blob, pcp_pubkey_t *p, pcp_keysig_t *sk);
#endif // _HAVE_PCP_MGMT_H #endif // _HAVE_PCP_MGMT_H

View File

@@ -26,8 +26,10 @@
#include <stdio.h> #include <stdio.h>
#include <assert.h> #include <assert.h>
#include "mem.h" #include "mem.h"
#include "structs.h"
#include "util.h" #include "util.h"
#include "defines.h" #include "defines.h"
#include "context.h"
#include "buffer.h" #include "buffer.h"
#include "z85.h" #include "z85.h"
@@ -54,35 +56,7 @@
*/ */
/** \struct _pcp_stream_t
An I/O wrapper object backed by a file or a buffer.
*/
struct _pcp_stream_t {
FILE *fd; /**< The backend FILE stream */
Buffer *b; /**< The backend Buffer object */
Buffer *cache; /**< The caching Buffer object (for look ahead read) */
Buffer *next; /**< The caching Next-Buffer object (for look ahead read) */
Buffer *save; /**< Temporary buffer to backup overflow data */
uint8_t is_buffer; /**< Set to 1 if the backend is a Buffer */
uint8_t eof; /**< Set to 1 if EOF reached */
uint8_t err; /**< Set to 1 if an error occured */
uint8_t armor; /**< Set to 1 if Z85 en/de-coding is requested */
uint8_t determine; /**< Set to 1 to automatically determine armor mode */
uint8_t firstread; /**< Internal flag, will be set after first read() */
size_t linewr; /**< Used for Z85 writing, number of chars written on last line */
size_t blocksize; /**< Blocksize used for z85, if requested */
uint8_t is_output; /**< marks the stream as output stream */
uint8_t have_begin; /**< flag to indicate we already got the begin header, if any */
size_t pos; /**< remember i/o position */
};
typedef enum _PSVARS {
PSMAXLINE = 20000
} PSVARS;
/** The name used everywhere */
typedef struct _pcp_stream_t Pcpstream;
/* initialize a new empty stream */ /* initialize a new empty stream */
Pcpstream *ps_init(void); Pcpstream *ps_init(void);

View File

@@ -35,8 +35,9 @@
#include "crypto_scrypt.h" #include "crypto_scrypt.h"
#include "mem.h" #include "mem.h"
#include "defines.h" #include "defines.h"
#include "context.h"
byte * pcp_scrypt(char *passwd, size_t passwdlen, byte *nonce, size_t noncelen); byte * pcp_scrypt(PCPCTX *ptx, char *passwd, size_t passwdlen, byte *nonce, size_t noncelen);
#endif /* _HAVE_PCP_SCRYPT_H */ #endif /* _HAVE_PCP_SCRYPT_H */

384
include/pcp/structs.h Normal file
View File

@@ -0,0 +1,384 @@
/*
This file is part of Pretty Curved Privacy (pcp1).
Copyright (C) 2013-2014 T.v.Dein.
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 <http://www.gnu.org/licenses/>.
You can contact me by mail: <tom AT vondein DOT org>.
*/
#ifndef _HAVE_PCP_STRUCTS_H
#define _HAVE_PCP_STRUCTS_H
#include "defines.h"
#include "uthash.h"
#include <sodium.h>
/**
\addtogroup KEYS
@{
*/
/** \struct _pcp_key_t
PCP private key structure. Most fields are self explanatory.
Some notes:
'encrypted' contains the encrypted secret keys (contatenated mastersecret,
secret and edsecret). If it's set,
the field 'secret' which contains the clear secret key will
be zeroed with random values, the first byte will be 0. Same
for the field 'edsecret'.
'nonce' contains the nonce required to decrypt the encrypted
secret, if set.
'serial' is a random number.
'id' is a string containing the hex values of the CRC32 checksum
of the public and secret key.
Upon creation everything will be filled with random bytes.
String fields will contain a string followed by 0 followed
by the rest of the pre-filled random bytes. To denote a string
field as empty, the first byte will be set to 0.
There are dynamically calculated attributes as well:
'checksum' is a 256 bit SHA hash of the public key returned
by pcpkey_getchecksum() or pcppubkey_getchecksum().
'random id' is a random art ascii image returned by
pcppubkey_get_art() or pcpkey_get_art(), calculated from
the public key.
If exported to a single file or printed, the structure will
be encoded using Z85 encoding.
*/
struct _pcp_key_t {
byte masterpub[32]; /**< ED25519 master public key signing key */
byte mastersecret[64]; /**< ED25519 master secret key signing key */
byte pub[32]; /**< Curve25519 encryption public key */
byte secret[32]; /**< Curve25519 encryption secret key */
byte edpub[32]; /**< ED25519 public signing key */
byte edsecret[64]; /**< ED25519 secret signing key */
byte nonce[24]; /**< random nonce used to encrypt secret keys */
byte encrypted[176]; /**< concatenated and encrypted secret keys */
char owner[255]; /**< the key owner, string */
char mail[255]; /**< mail address of the owner, string */
char id[17]; /**< key-id, used internally only, jenhash of public keys */
uint8_t type; /**< key type: MASTER_SECRET or SECRET */
uint64_t ctime; /**< creation time, epoch */
uint32_t version; /**< key version */
uint32_t serial; /**< serial number of the key, randomly generated */
UT_hash_handle hh;
};
/** Typedef for secret keys */
typedef struct _pcp_key_t pcp_key_t;
/** \struct _pcp_pubkey_t
PCP public key structure.
This structure contains a subset of the pcp_key_t structure
without the secret and nonce fields.
*/
struct _pcp_pubkey_t {
byte masterpub[32]; /**< ED25519 master public key signing key */
byte sigpub[32]; /**< ED25519 public signing key */
byte pub[32]; /**< Curve25519 encryption public key */
byte edpub[32]; /**< ED25519 public signing key (FIXME: huh? 2 of them???) */
char owner[255]; /**< the key owner, string */
char mail[255]; /**< mail address of the owner, string */
char id[17]; /**< key-id, used internally only, jenhash of public keys */
uint8_t type; /**< key type: MASTER_SECRET or SECRET */
uint64_t ctime; /**< creation time, epoch */
uint32_t version; /**< key version */
uint32_t serial; /**< serial number of the key, randomly generated */
uint8_t valid; /**< 1 if import signature verified, 0 if not */
byte signature[crypto_generichash_BYTES_MAX + crypto_sign_BYTES]; /**< raw binary blob of pubkey export signature */
UT_hash_handle hh;
};
/** Typedef for public keys */
typedef struct _pcp_pubkey_t pcp_pubkey_t;
/* the PBP public key format */
/* keys.mp+keys.cp+keys.sp+keys.name */
struct _pbp_pubkey_t {
byte sigpub[crypto_sign_PUBLICKEYBYTES];
byte edpub[crypto_sign_PUBLICKEYBYTES];
byte pub[crypto_box_PUBLICKEYBYTES];
char iso_ctime[32];
char iso_expire[32];
char name[1024];
};
typedef struct _pbp_pubkey_t pbp_pubkey_t;
/** \struct _pcp_rec_t
Encrypted recipient list.
Encrypted recipient list, required for crypt+sign
contains the encrypted recipients and the secret
key required for signing the message+recipients.
Used internally only.
*/
struct _pcp_rec_t {
size_t ciphersize; /**< the size of the encrypted recipient list */
byte *cipher; /**< contains the whole encrypted recipient list */
pcp_key_t *secret; /**< the secret key of the recipient for signing */
pcp_pubkey_t *pub; /**< if verification were ok, contains the public key of the signer */
};
/** Typedef for public keys */
typedef struct _pcp_rec_t pcp_rec_t;
/* holds a public key signature */
struct _pcp_keysig_t {
uint8_t type;
uint32_t size;
char id[17];
byte checksum[32];
byte *blob;
UT_hash_handle hh;
};
typedef struct _pcp_keysig_t pcp_keysig_t;
/** @}
*/
/**
\addtogroup CONTEXT
@{
*/
/** \struct _pcp_ctx_t
PCP context object.
Holds error state and key hashes.
*/
struct _pcp_ctx_t {
char *pcp_err; /**< last error message. retrieve with fatals_ifany() */
byte pcp_errset; /**< indicates if an error occurred. */
int pcp_exit; /**< exit code for pcp commandline utility */
int verbose; /**< enable verbose output */
pcp_key_t *pcpkey_hash; /**< hash containing for keys */
pcp_pubkey_t *pcppubkey_hash; /**< hash for keys. */
pcp_keysig_t *pcpkeysig_hash; /**< hash for key sigs */
};
typedef struct _pcp_ctx_t PCPCTX;
/** @}
*/
/**
\addtogroup VAULT
@{
*/
/** \struct _vault_t
This structure represents a vault. */
struct _vault_t {
char *filename; /**< The filename of the vault (full path) */
FILE *fd; /**< Filehandle if opened */
uint8_t unsafed; /**< Flag to tell if the file needs to be written */
uint8_t isnew; /**< Flag to tell if the vault has been newly created */
uint32_t size; /**< Filesize */
time_t modified; /**< mtime */
mode_t mode; /**< File mode */
uint32_t version; /**< Vault version */
byte checksum[32]; /**< SHA256 checksum over the whole vault */
};
/** Name of the struct */
typedef struct _vault_t vault_t;
/** \struct _vault_header_t
Defines the vault header. */
struct _vault_header_t {
uint8_t fileid; /**< File id, proprietary. Marks the vault as a vault */
uint32_t version; /**< File version */
byte checksum[32]; /**< SHA256 checksum over the whole vault */
};
/** Name of the struct */
typedef struct _vault_header_t vault_header_t;
/** \struct _vault_item_header_t
An item header. */
struct _vault_item_header_t {
uint8_t type; /**< Item type (secret key, public, key, keysig, \see _PCP_KEY_TYPES */
uint32_t size; /**< Size of the item */
uint32_t version; /**< Version of the item */
byte checksum[32]; /**< SHA256 checksum of the item */
};
/** Name of the struct */
typedef struct _vault_item_header_t vault_item_header_t;
/** @}
*/
/**
\addtogroup BUFFER
@{
*/
/** \struct _pcp_buffer
A flexible buffer object wich automatically resizes, if neccessary.
*/
struct _pcp_buffer {
char *name; /**< just for convenience in error messages and the like, so we know which buffer cause trouble */
uint8_t allocated; /**< marks the buffer as allocated */
size_t blocksize; /**< the blocksize to use when resizing, also used for initial malloc() */
size_t size; /**< stores the current allocated size of the object */
size_t offset; /**< current read position */
size_t end; /**< current write position, data end. maybe less than size. */
uint8_t isstring; /**< treat as char array/string */
void *buf; /**< the actual storage buffer */
};
/** The name used everywhere */
typedef struct _pcp_buffer Buffer;
/** @}
*/
/**
\addtogroup PCPSTREAMS
@{
*/
/** \struct _pcp_stream_t
An I/O wrapper object backed by a file or a buffer.
*/
struct _pcp_stream_t {
FILE *fd; /**< The backend FILE stream */
Buffer *b; /**< The backend Buffer object */
Buffer *cache; /**< The caching Buffer object (for look ahead read) */
Buffer *next; /**< The caching Next-Buffer object (for look ahead read) */
Buffer *save; /**< Temporary buffer to backup overflow data */
uint8_t is_buffer; /**< Set to 1 if the backend is a Buffer */
uint8_t eof; /**< Set to 1 if EOF reached */
uint8_t err; /**< Set to 1 if an error occured */
uint8_t armor; /**< Set to 1 if Z85 en/de-coding is requested */
uint8_t determine; /**< Set to 1 to automatically determine armor mode */
uint8_t firstread; /**< Internal flag, will be set after first read() */
size_t linewr; /**< Used for Z85 writing, number of chars written on last line */
size_t blocksize; /**< Blocksize used for z85, if requested */
uint8_t is_output; /**< marks the stream as output stream */
uint8_t have_begin; /**< flag to indicate we already got the begin header, if any */
size_t pos; /**< remember i/o position */
};
typedef enum _PSVARS {
PSMAXLINE = 20000
} PSVARS;
/** The name used everywhere */
typedef struct _pcp_stream_t Pcpstream;
/** @}
*/
/* various helper structs for mgmt.c, used internally only */
struct _pcp_rfc_pubkey_header_t {
uint8_t version;
uint32_t ctime;
uint8_t cipher;
};
struct _pcp_rfc_pubkey_0x21_t {
byte sig_ed25519_pub[crypto_sign_PUBLICKEYBYTES];
byte ed25519_pub[crypto_sign_PUBLICKEYBYTES];
byte curve25519_pub[crypto_box_PUBLICKEYBYTES];
};
struct _pcp_rfc_pubkey_sigheader_0x21_t {
uint8_t version;
uint8_t type;
uint8_t pkcipher;
uint8_t hashcipher;
uint16_t numsubs;
};
struct _pcp_rfc_pubkey_sigsub_0x21_t {
uint32_t size;
uint8_t type;
};
typedef struct _pcp_rfc_pubkey_header_t rfc_pub_h;
typedef struct _pcp_rfc_pubkey_0x21_t rfc_pub_k;
typedef struct _pcp_rfc_pubkey_sigheader_0x21_t rfc_pub_sig_h;
typedef struct _pcp_rfc_pubkey_sigsub_0x21_t rfc_pub_sig_s;
struct _pcp_ks_bundle_t {
pcp_pubkey_t *p;
pcp_keysig_t *s;
};
typedef struct _pcp_ks_bundle_t pcp_ks_bundle_t;
#endif //_HAVE_PCP_STRUCTS_H

View File

@@ -89,66 +89,30 @@
#include "uthash.h" #include "uthash.h"
#include "buffer.h" #include "buffer.h"
#include "keysig.h" #include "keysig.h"
#include "structs.h"
#include "context.h"
/** \struct _vault_t
This structure represents a vault. */
struct _vault_t {
char *filename; /**< The filename of the vault (full path) */
FILE *fd; /**< Filehandle if opened */
uint8_t unsafed; /**< Flag to tell if the file needs to be written */
uint8_t isnew; /**< Flag to tell if the vault has been newly created */
uint32_t size; /**< Filesize */
time_t modified; /**< mtime */
mode_t mode; /**< File mode */
uint32_t version; /**< Vault version */
byte checksum[32]; /**< SHA256 checksum over the whole vault */
};
/** Name of the struct */
typedef struct _vault_t vault_t;
/** \struct _vault_header_t
Defines the vault header. */
struct _vault_header_t {
uint8_t fileid; /**< File id, proprietary. Marks the vault as a vault */
uint32_t version; /**< File version */
byte checksum[32]; /**< SHA256 checksum over the whole vault */
};
/** Name of the struct */
typedef struct _vault_header_t vault_header_t;
/** \struct _vault_item_header_t
An item header. */
struct _vault_item_header_t {
uint8_t type; /**< Item type (secret key, public, key, keysig, \see _PCP_KEY_TYPES */
uint32_t size; /**< Size of the item */
uint32_t version; /**< Version of the item */
byte checksum[32]; /**< SHA256 checksum of the item */
};
/** Name of the struct */
typedef struct _vault_item_header_t vault_item_header_t;
/** Open a vault file. /** Open a vault file.
If the file doesn't exist, it will be created. If the file doesn't exist, it will be created.
\param[in] pcp context.
\param[in] filename The filename of the vault file. \param[in] filename The filename of the vault file.
\return Returns a vault object. \return Returns a vault object.
*/ */
vault_t *pcpvault_init(char *filename); vault_t *pcpvault_init(PCPCTX *ptx, char *filename);
/* Creates a new vault file. Called internally only. /* Creates a new vault file. Called internally only.
If is_tmp If set to 1, create a temporary vault file. If is_tmp If set to 1, create a temporary vault file.
*/ */
vault_t *pcpvault_new(char *filename, int is_tmp); vault_t *pcpvault_new(PCPCTX *ptx, char *filename, int is_tmp);
/* Writes the initial vault header to the vault. /* Writes the initial vault header to the vault.
Called internally only. */ Called internally only. */
int pcpvault_create(vault_t *vault); int pcpvault_create(PCPCTX *ptx, vault_t *vault);
/** Add an item to the vault. /** Add an item to the vault.
@@ -160,6 +124,7 @@ int pcpvault_create(vault_t *vault);
This function writes directly into the vault file. Use This function writes directly into the vault file. Use
with care. To be safe, use pcpvault_addkey() instead. with care. To be safe, use pcpvault_addkey() instead.
\param[in] pcp context.
\param[out] vault The vault object. \param[out] vault The vault object.
\param[in] item The item to write. \param[in] item The item to write.
\param[in] itemsize Size of the item. \param[in] itemsize Size of the item.
@@ -168,7 +133,7 @@ int pcpvault_create(vault_t *vault);
\return Returns the number of bytes written or 0 in case of \return Returns the number of bytes written or 0 in case of
an error. Check fatals_if_any(). an error. Check fatals_if_any().
*/ */
int pcpvault_additem(vault_t *vault, void *item, size_t itemsize, uint8_t type); int pcpvault_additem(PCPCTX *ptx, vault_t *vault, void *item, size_t itemsize, uint8_t type);
/** Add a key to the vault. /** Add a key to the vault.
@@ -183,13 +148,14 @@ int pcpvault_additem(vault_t *vault, void *item, size_t itemsize, uint8_t type);
back to the original location. It then re-calculates the back to the original location. It then re-calculates the
vault checksum and puts it into the vault header. vault checksum and puts it into the vault header.
\param[in] pcp context.
\param[out] vault The vault object. \param[out] vault The vault object.
\param[in] item The item to write (a key or keysig) \param[in] item The item to write (a key or keysig)
\param[in] type Type of the item. \see _PCP_KEY_TYPES. \param[in] type Type of the item. \see _PCP_KEY_TYPES.
\return Returns 0 on success or 1 in case of errors. Check fatals_if_any(). \return Returns 0 on success or 1 in case of errors. Check fatals_if_any().
*/ */
int pcpvault_addkey(vault_t *vault, void *item, uint8_t type); int pcpvault_addkey(PCPCTX *ptx, vault_t *vault, void *item, uint8_t type);
/** Close a vault file. /** Close a vault file.
@@ -201,12 +167,13 @@ int pcpvault_addkey(vault_t *vault, void *item, uint8_t type);
contain the filename of the backup file, so that the user contain the filename of the backup file, so that the user
doesn't loose data. doesn't loose data.
\param[in] pcp context.
\param[out] vault The vault object. \param[out] vault The vault object.
\return Returns 0. Check fatals_if_any() anyway. \return Returns 0. Check fatals_if_any() anyway.
*/ */
int pcpvault_close(vault_t *vault); int pcpvault_close(PCPCTX *ptx, vault_t *vault);
/** Reads in the vault contents. /** Reads in the vault contents.
@@ -223,27 +190,29 @@ int pcpvault_close(vault_t *vault);
contents and compares it with the one stored in the vault contents and compares it with the one stored in the vault
header. If it doesn't match an error will be thrown. header. If it doesn't match an error will be thrown.
\param[in] pcp context.
\param[out] vault The vault object. \param[out] vault The vault object.
\return Returns 0 on success or -1 in case of errors. Check fatals_if_any(). \return Returns 0 on success or -1 in case of errors. Check fatals_if_any().
*/ */
int pcpvault_fetchall(vault_t *vault); int pcpvault_fetchall(PCPCTX *ptx, vault_t *vault);
/* Write everything back to disk. */ /* Write everything back to disk. */
int pcpvault_writeall(vault_t *vault); int pcpvault_writeall(PCPCTX *ptx, vault_t *vault);
/* copy a vault to another file */ /* copy a vault to another file */
int pcpvault_copy(vault_t *tmp, vault_t *vault); int pcpvault_copy(PCPCTX *ptx, vault_t *tmp, vault_t *vault);
/* delete a vault file */ /* delete a vault file */
void pcpvault_unlink(vault_t *tmp); void pcpvault_unlink(vault_t *tmp);
/* calculate the checksum of the current vault */ /* calculate the checksum of the current vault (that is, from the
byte *pcpvault_create_checksum(); list of keys in the current context */
byte *pcpvault_create_checksum(PCPCTX *ptx);
/* write the new checksum to the header of the current vault */ /* write the new checksum to the header of the current vault */
void pcpvault_update_checksum(vault_t *vault); void pcpvault_update_checksum(PCPCTX *ptx, vault_t *vault);
/* bigendian converters */ /* bigendian converters */
vault_header_t * vh2be(vault_header_t *h); vault_header_t * vh2be(vault_header_t *h);

View File

@@ -43,6 +43,8 @@ we pad the input with zeroes and remove them after decoding.
#include "defines.h" #include "defines.h"
#include "zmq_z85.h" #include "zmq_z85.h"
#include "mem.h" #include "mem.h"
#include "structs.h"
#include "context.h"
#include "buffer.h" #include "buffer.h"
/** Zero-pad some input data. /** Zero-pad some input data.
@@ -76,6 +78,7 @@ size_t pcp_unpadfour(byte *src, size_t srclen);
The input \a z85block may contain newlines which will be removed. The input \a z85block may contain newlines which will be removed.
\param[in] the pcp context object.
\param[in] z85block The Z85 encoded string. \param[in] z85block The Z85 encoded string.
\param[in] dstlen Returned size of decoded data (pointer to int). \param[in] dstlen Returned size of decoded data (pointer to int).
@@ -83,7 +86,7 @@ size_t pcp_unpadfour(byte *src, size_t srclen);
returns NULL. Check fatals_if_any(). returns NULL. Check fatals_if_any().
*/ */
byte *pcp_z85_decode(char *z85block, size_t *dstlen); byte *pcp_z85_decode(PCPCTX *ptx, char *z85block, size_t *dstlen);
/** Encode data to Z85 encoding. /** Encode data to Z85 encoding.
@@ -105,24 +108,26 @@ char *pcp_z85_encode(byte *raw, size_t srclen, size_t *dstlen);
Reads a file and returns the raw Z85 encoded string. Reads a file and returns the raw Z85 encoded string.
It ignores newlines, comments and Headerstrings. It ignores newlines, comments and Headerstrings.
\param[in] the pcp context object.
\param[in] infile FILE stream to read from. \param[in] infile FILE stream to read from.
\return Raw Z85 encoded string with comments, headers and newlines removed. \return Raw Z85 encoded string with comments, headers and newlines removed.
*/ */
char *pcp_readz85file(FILE *infile); char *pcp_readz85file(PCPCTX *ptx, FILE *infile);
/** Read a Z85 encoded string. /** Read a Z85 encoded string.
Parses the given input string and returns the raw Z85 encoded string. Parses the given input string and returns the raw Z85 encoded string.
It ignores newlines, comments and Headerstrings. It ignores newlines, comments and Headerstrings.
\param[in] the pcp context object.
\param[in] input Z85 encoded string. \param[in] input Z85 encoded string.
\param[in] bufsize Size of the string. \param[in] bufsize Size of the string.
\return Raw Z85 encoded string with comments, headers and newlines removed. \return Raw Z85 encoded string with comments, headers and newlines removed.
*/ */
char *pcp_readz85string(byte *input, size_t bufsize); char *pcp_readz85string(PCPCTX *ptx, byte *input, size_t bufsize);
/** Check if a binary array is utf8. /** Check if a binary array is utf8.

View File

@@ -26,8 +26,8 @@ pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = libpcp1.pc pkgconfig_DATA = libpcp1.pc
libpcp1_la_SOURCES = platform.c mac.c mem.c pad.c version.c \ libpcp1_la_SOURCES = platform.c mac.c mem.c pad.c version.c \
z85.c zmq_z85.c key.c randomart.c \ context.c z85.c zmq_z85.c key.c randomart.c \
vault.c fatal.c jenhash.c digital_crc32.c \ vault.c jenhash.c digital_crc32.c \
crypto.c ed.c keyhash.c scrypt.c \ crypto.c ed.c keyhash.c scrypt.c \
scrypt/crypto/sha256.c scrypt/crypto/crypto_scrypt-nosse.c \ scrypt/crypto/sha256.c scrypt/crypto/crypto_scrypt-nosse.c \
base85.c util.c buffer.c mgmt.c keysig.c pcpstream.c base85.c util.c buffer.c mgmt.c keysig.c pcpstream.c

View File

@@ -33,7 +33,7 @@ static void prep_base85(void)
} }
} }
int decode_85(char *dst, const char *buffer, int len) int decode_85(PCPCTX *ptx, char *dst, const char *buffer, int len)
{ {
prep_base85(); prep_base85();
say1("len: %d\n", len); say1("len: %d\n", len);

View File

@@ -129,9 +129,8 @@ byte *buffer_get(Buffer *b) {
size_t buffer_get_chunk(Buffer *b, void *buf, size_t len) { size_t buffer_get_chunk(Buffer *b, void *buf, size_t len) {
if(len > b->end - b->offset) { if(len > b->end - b->offset) {
fatal("[buffer %s] attempt to read %ld bytes data from buffer with %ld bytes left at offset %ld\n", final("[buffer %s] attempt to read %ld bytes data from buffer with %ld bytes left at offset %ld\n",
b->name, len, b->end - b->offset, b->offset); b->name, len, b->end - b->offset, b->offset);
return 0;
} }
else if(len == 0) { else if(len == 0) {
/* FIXME: check how this happens */ /* FIXME: check how this happens */
@@ -146,9 +145,8 @@ size_t buffer_get_chunk(Buffer *b, void *buf, size_t len) {
size_t buffer_get_chunk_tobuf(Buffer *b, Buffer *dst, size_t len) { size_t buffer_get_chunk_tobuf(Buffer *b, Buffer *dst, size_t len) {
if(len > b->end - b->offset) { if(len > b->end - b->offset) {
fatal("[buffer %s] attempt to read %ld bytes data from buffer with %ld bytes left at offset %ld\n", final("[buffer %s] attempt to read %ld bytes data from buffer with %ld bytes left at offset %ld\n",
b->name, len, b->end - b->offset, b->offset); b->name, len, b->end - b->offset, b->offset);
return 0;
} }
else if(len == 0) { else if(len == 0) {
/* FIXME: check how this happens */ /* FIXME: check how this happens */
@@ -246,13 +244,11 @@ char *buffer_get_str(Buffer *b) {
size_t buffer_extract(Buffer *b, void *buf, size_t offset, size_t len) { size_t buffer_extract(Buffer *b, void *buf, size_t offset, size_t len) {
if(len > b->end) { if(len > b->end) {
fatal("[buffer %s] attempt to read %ld bytes past end of buffer at %ld\n", b->name, b->end - (b->offset + len), b->end); final("[buffer %s] attempt to read %ld bytes past end of buffer at %ld\n", b->name, b->end - (b->offset + len), b->end);
return 0;
} }
if(offset > b->end) { if(offset > b->end) {
fatal("[buffer %s] attempt to read at offset %ld past len to read %ld\n", b->name, offset, b->end); final("[buffer %s] attempt to read at offset %ld past len to read %ld\n", b->name, offset, b->end);
return 0;
} }
memcpy(buf, b->buf + offset, len); memcpy(buf, b->buf + offset, len);
@@ -328,13 +324,10 @@ size_t buffer_fd_read(Buffer *b, FILE *in, size_t len) {
size_t s = fread(data, 1, len, in); size_t s = fread(data, 1, len, in);
if(s < len) { if(s > 0)
fatal("[buffer %s] attempt to read %"FMT_SIZE_T" bytes from FILE, but got %"FMT_SIZE_T" bytes only\n", b->name, (SIZE_T_CAST)len, (SIZE_T_CAST)s);
return 0;
}
buffer_add(b, data, len); buffer_add(b, data, len);
return len;
return s;
} }
void buffer_add8(Buffer *b, uint8_t v) { void buffer_add8(Buffer *b, uint8_t v) {

View File

@@ -21,9 +21,8 @@
#define _GNU_SOURCE /* vasprintf() linux */ #define _GNU_SOURCE /* vasprintf() linux */
#include "defines.h"
#include "platform.h"
#include "context.h"
#include <errno.h> #include <errno.h>
#include <stdarg.h> #include <stdarg.h>
@@ -31,39 +30,70 @@
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
char *PCP_ERR; PCPCTX *ptx_new() {
byte PCP_ERRSET; PCPCTX *p = ucmalloc(sizeof(PCPCTX));
int PCP_EXIT; p->pcp_err = NULL;
int PCPVERBOSE; p->pcp_errset = 0;
p->pcp_exit = 0;
p->verbose = 0;
p->pcpkey_hash = NULL;
p->pcppubkey_hash = NULL;
p->pcpkeysig_hash = NULL;
void fatal(const char * fmt, ...) { return p;
}
void ptx_clean(PCPCTX *ptx) {
if(ptx->pcp_errset)
free(ptx->pcp_err);
pcphash_clean(ptx);
free(ptx);
}
void fatal(PCPCTX *ptx, const char * fmt, ...) {
va_list ap; va_list ap;
va_start(ap, fmt); va_start(ap, fmt);
if(vasprintf(&PCP_ERR, fmt, ap) >= 0) { char *err = ptx->pcp_err;
if(vasprintf(&err, fmt, ap) >= 0) {
va_end(ap); va_end(ap);
PCP_ERRSET = 1; ptx->pcp_errset = 1;
} }
else { else {
fprintf(stderr, "Could not store fatal error message %s!\n", fmt); fprintf(stderr, "Could not store fatal error message %s!\n", fmt);
PCP_ERRSET = 1; ptx->pcp_errset = 1;
} }
} }
void fatals_reset() { void fatals_reset(PCPCTX *ptx) {
PCP_ERRSET = 0; ptx->pcp_errset = 0;
} }
void fatals_ifany() { void fatals_ifany(PCPCTX *ptx) {
if(PCP_ERRSET == 1) { if(ptx->pcp_errset == 1) {
fprintf(stderr, "%s", PCP_ERR); fprintf(stderr, "%s", ptx->pcp_err);
if(errno) { if(errno) {
fprintf(stderr, "Error: %s\n", strerror(errno)); fprintf(stderr, "Error: %s\n", strerror(errno));
} }
PCP_EXIT = 1; ptx->pcp_exit = 1;
} }
} }
void fatals_done() { void final(const char * fmt, ...) {
free(PCP_ERR); va_list ap;
va_start(ap, fmt);
char *err = NULL;
if(vasprintf(&err, fmt, ap) >= 0) {
va_end(ap);
}
fprintf(stderr, "ABORT: %s", err);
abort();
} }

View File

@@ -81,7 +81,7 @@ int pcp_sodium_verify_box(byte **cleartext, byte* message,
byte *pcp_box_encrypt(pcp_key_t *secret, pcp_pubkey_t *pub, byte *pcp_box_encrypt(PCPCTX *ptx, pcp_key_t *secret, pcp_pubkey_t *pub,
byte *message, size_t messagesize, byte *message, size_t messagesize,
size_t *csize) { size_t *csize) {
@@ -93,7 +93,7 @@ byte *pcp_box_encrypt(pcp_key_t *secret, pcp_pubkey_t *pub,
secret->secret, pub->pub); secret->secret, pub->pub);
if(es <= messagesize) { if(es <= messagesize) {
fatal("failed to encrypt message!\n"); fatal(ptx, "failed to encrypt message!\n");
goto errbec; goto errbec;
} }
@@ -124,7 +124,7 @@ byte *pcp_box_encrypt(pcp_key_t *secret, pcp_pubkey_t *pub,
} }
byte *pcp_box_decrypt(pcp_key_t *secret, pcp_pubkey_t *pub, byte *pcp_box_decrypt(PCPCTX *ptx, pcp_key_t *secret, pcp_pubkey_t *pub,
byte *cipher, size_t ciphersize, byte *cipher, size_t ciphersize,
size_t *dsize) { size_t *dsize) {
@@ -140,7 +140,7 @@ byte *pcp_box_decrypt(pcp_key_t *secret, pcp_pubkey_t *pub,
if(pcp_sodium_verify_box(&message, cipheronly, if(pcp_sodium_verify_box(&message, cipheronly,
ciphersize - crypto_secretbox_NONCEBYTES, ciphersize - crypto_secretbox_NONCEBYTES,
nonce, secret->secret, pub->pub) != 0){ nonce, secret->secret, pub->pub) != 0){
fatal("failed to decrypt message!\n"); fatal(ptx, "failed to decrypt message!\n");
goto errbed; goto errbed;
} }
@@ -161,7 +161,7 @@ byte *pcp_box_decrypt(pcp_key_t *secret, pcp_pubkey_t *pub,
return NULL; return NULL;
} }
size_t pcp_decrypt_stream(Pcpstream *in, Pcpstream* out, pcp_key_t *s, byte *symkey, int verify) { size_t pcp_decrypt_stream(PCPCTX *ptx, Pcpstream *in, Pcpstream* out, pcp_key_t *s, byte *symkey, int verify) {
pcp_pubkey_t *cur = NULL; pcp_pubkey_t *cur = NULL;
byte *reccipher = NULL; byte *reccipher = NULL;
int recmatch, self; int recmatch, self;
@@ -190,7 +190,7 @@ size_t pcp_decrypt_stream(Pcpstream *in, Pcpstream* out, pcp_key_t *s, byte *sym
if(symkey != NULL) if(symkey != NULL)
self = 1; self = 1;
else { else {
fatal("Input is symetrically encrypted but no key have been specified (lib usage failure)\n"); fatal(ptx, "Input is symetrically encrypted but no key have been specified (lib usage failure)\n");
goto errdef1; goto errdef1;
} }
} }
@@ -202,14 +202,14 @@ size_t pcp_decrypt_stream(Pcpstream *in, Pcpstream* out, pcp_key_t *s, byte *sym
if(self) { if(self) {
/* just decrypt symetrically and go outa here */ /* just decrypt symetrically and go outa here */
return pcp_decrypt_stream_sym(in, out, symkey, NULL); return pcp_decrypt_stream_sym(ptx, in, out, symkey, NULL);
} }
#ifdef PCP_ASYM_ADD_SENDER_PUB #ifdef PCP_ASYM_ADD_SENDER_PUB
/* step 2, sender's pubkey */ /* step 2, sender's pubkey */
cur_bufsize = ps_read(in, &in_buf, crypto_box_PUBLICKEYBYTES); /* fread(&in_buf, 1, crypto_box_PUBLICKEYBYTES, in); */ cur_bufsize = ps_read(in, &in_buf, crypto_box_PUBLICKEYBYTES); /* fread(&in_buf, 1, crypto_box_PUBLICKEYBYTES, in); */
if(cur_bufsize != crypto_box_PUBLICKEYBYTES && !ps_end(in) && !ps_err(in)) { if(cur_bufsize != crypto_box_PUBLICKEYBYTES && !ps_end(in) && !ps_err(in)) {
fatal("Error: input file doesn't contain senders public key\n"); fatal(ptx, "Error: input file doesn't contain senders public key\n");
goto errdef1; goto errdef1;
} }
#endif #endif
@@ -217,7 +217,7 @@ size_t pcp_decrypt_stream(Pcpstream *in, Pcpstream* out, pcp_key_t *s, byte *sym
/* step 3, check len recipients */ /* step 3, check len recipients */
cur_bufsize = ps_read(in, &lenrec, 4); /* fread(&lenrec, 1, 4, in); */ cur_bufsize = ps_read(in, &lenrec, 4); /* fread(&lenrec, 1, 4, in); */
if(cur_bufsize != 4 && !ps_end(in) && !ps_err(in)) { if(cur_bufsize != 4 && !ps_end(in) && !ps_err(in)) {
fatal("Error: input file doesn't contain recipient count\n"); fatal(ptx, "Error: input file doesn't contain recipient count\n");
goto errdef1; goto errdef1;
} }
lenrec = be32toh(lenrec); lenrec = be32toh(lenrec);
@@ -232,14 +232,14 @@ size_t pcp_decrypt_stream(Pcpstream *in, Pcpstream* out, pcp_key_t *s, byte *sym
for(nrec=0; nrec<lenrec; nrec++) { for(nrec=0; nrec<lenrec; nrec++) {
cur_bufsize = ps_read(in, &rec_buf, PCP_ASYM_RECIPIENT_SIZE); /* fread(&rec_buf, 1, PCP_ASYM_RECIPIENT_SIZE, in); */ cur_bufsize = ps_read(in, &rec_buf, PCP_ASYM_RECIPIENT_SIZE); /* fread(&rec_buf, 1, PCP_ASYM_RECIPIENT_SIZE, in); */
if(cur_bufsize != PCP_ASYM_RECIPIENT_SIZE && !ps_end(in) && !ps_err(in)) { if(cur_bufsize != PCP_ASYM_RECIPIENT_SIZE && !ps_end(in) && !ps_err(in)) {
fatal("Error: input file corrupted, incomplete or no recipients (got %ld, exp %ld)\n", cur_bufsize, PCP_ASYM_RECIPIENT_SIZE ); fatal(ptx, "Error: input file corrupted, incomplete or no recipients (got %ld, exp %ld)\n", cur_bufsize, PCP_ASYM_RECIPIENT_SIZE );
goto errdef1; goto errdef1;
} }
recmatch = 0; recmatch = 0;
pcphash_iteratepub(cur) { pcphash_iteratepub(ptx, cur) {
byte *recipient; byte *recipient;
recipient = pcp_box_decrypt(s, cur, rec_buf, PCP_ASYM_RECIPIENT_SIZE, &rec_size); recipient = pcp_box_decrypt(ptx, s, cur, rec_buf, PCP_ASYM_RECIPIENT_SIZE, &rec_size);
if(recipient != NULL && rec_size == crypto_secretbox_KEYBYTES) { if(recipient != NULL && rec_size == crypto_secretbox_KEYBYTES) {
/* found a match */ /* found a match */
recmatch = 1; recmatch = 1;
@@ -257,19 +257,19 @@ size_t pcp_decrypt_stream(Pcpstream *in, Pcpstream* out, pcp_key_t *s, byte *sym
if(recmatch == 0) { if(recmatch == 0) {
fatal("Sorry, there's no matching public key in your vault for decryption\n"); fatal(ptx, "Sorry, there's no matching public key in your vault for decryption\n");
goto errdef1; goto errdef1;
} }
/* step 5, actually decrypt the file, finally */ /* step 5, actually decrypt the file, finally */
if(verify) { if(verify) {
pcp_rec_t *rec = pcp_rec_new(reccipher, nrec * PCP_ASYM_RECIPIENT_SIZE, NULL, cur); pcp_rec_t *rec = pcp_rec_new(reccipher, nrec * PCP_ASYM_RECIPIENT_SIZE, NULL, cur);
size_t s = pcp_decrypt_stream_sym(in, out, symkey, rec); size_t s = pcp_decrypt_stream_sym(ptx, in, out, symkey, rec);
pcp_rec_free(rec); pcp_rec_free(rec);
return s; return s;
} }
else { else {
size_t s = pcp_decrypt_stream_sym(in, out, symkey, NULL); size_t s = pcp_decrypt_stream_sym(ptx, in, out, symkey, NULL);
return s; return s;
} }
@@ -277,7 +277,7 @@ size_t pcp_decrypt_stream(Pcpstream *in, Pcpstream* out, pcp_key_t *s, byte *sym
return 0; return 0;
} }
size_t pcp_encrypt_stream(Pcpstream *in, Pcpstream *out, pcp_key_t *s, pcp_pubkey_t *p, int sign) { size_t pcp_encrypt_stream(PCPCTX *ptx, Pcpstream *in, Pcpstream *out, pcp_key_t *s, pcp_pubkey_t *p, int sign) {
byte *symkey; byte *symkey;
int recipient_count; int recipient_count;
byte *recipients_cipher; byte *recipients_cipher;
@@ -306,9 +306,9 @@ size_t pcp_encrypt_stream(Pcpstream *in, Pcpstream *out, pcp_key_t *s, pcp_pubke
HASH_ITER(hh, p, cur, t) { HASH_ITER(hh, p, cur, t) {
byte *rec_cipher; byte *rec_cipher;
rec_cipher = pcp_box_encrypt(s, cur, symkey, crypto_secretbox_KEYBYTES, &es); rec_cipher = pcp_box_encrypt(ptx, s, cur, symkey, crypto_secretbox_KEYBYTES, &es);
if(es != rec_size) { if(es != rec_size) {
fatal("invalid rec_size, expected %dl, got %dl\n", rec_size, es); fatal(ptx, "invalid rec_size, expected %dl, got %dl\n", rec_size, es);
if(rec_cipher != NULL) if(rec_cipher != NULL)
free(rec_cipher); free(rec_cipher);
goto errec1; goto errec1;
@@ -326,7 +326,7 @@ size_t pcp_encrypt_stream(Pcpstream *in, Pcpstream *out, pcp_key_t *s, pcp_pubke
/* fwrite(head, 1, 1, out); */ /* fwrite(head, 1, 1, out); */
/* fprintf(stderr, "D: header - 1\n"); */ /* fprintf(stderr, "D: header - 1\n"); */
if(ps_err(out) != 0) { if(ps_err(out) != 0) {
fatal("Failed to write encrypted output!\n"); fatal(ptx, "Failed to write encrypted output!\n");
goto errec1; goto errec1;
} }
@@ -361,11 +361,11 @@ size_t pcp_encrypt_stream(Pcpstream *in, Pcpstream *out, pcp_key_t *s, pcp_pubke
size_t sym_size = 0; size_t sym_size = 0;
if(sign) { if(sign) {
pcp_rec_t *rec = pcp_rec_new(recipients_cipher, rec_size * recipient_count, s, NULL); pcp_rec_t *rec = pcp_rec_new(recipients_cipher, rec_size * recipient_count, s, NULL);
sym_size = pcp_encrypt_stream_sym(in, out, symkey, 1, rec); sym_size = pcp_encrypt_stream_sym(ptx, in, out, symkey, 1, rec);
pcp_rec_free(rec); pcp_rec_free(rec);
} }
else else
sym_size = pcp_encrypt_stream_sym(in, out, symkey, 1, NULL); sym_size = pcp_encrypt_stream_sym(ptx, in, out, symkey, 1, NULL);
if(sym_size == 0) if(sym_size == 0)
goto errec1; goto errec1;
@@ -386,7 +386,7 @@ size_t pcp_encrypt_stream(Pcpstream *in, Pcpstream *out, pcp_key_t *s, pcp_pubke
size_t pcp_encrypt_stream_sym(Pcpstream *in, Pcpstream *out, byte *symkey, int havehead, pcp_rec_t *recsign) { size_t pcp_encrypt_stream_sym(PCPCTX *ptx, Pcpstream *in, Pcpstream *out, byte *symkey, int havehead, pcp_rec_t *recsign) {
/* /*
havehead = 0: write the whole thing from here havehead = 0: write the whole thing from here
havehead = 1: no header, being called from asym... havehead = 1: no header, being called from asym...
@@ -413,7 +413,7 @@ size_t pcp_encrypt_stream_sym(Pcpstream *in, Pcpstream *out, byte *symkey, int h
es = ps_write(out, head, 1); es = ps_write(out, head, 1);
/* es = fwrite(head, 1, 1, out); */ /* es = fwrite(head, 1, 1, out); */
if(ps_err(out) != 0) { if(ps_err(out) != 0) {
fatal("Failed to write encrypted output!\n"); fatal(ptx, "Failed to write encrypted output!\n");
return 0; return 0;
} }
} }
@@ -466,7 +466,7 @@ size_t pcp_encrypt_stream_sym(Pcpstream *in, Pcpstream *out, byte *symkey, int h
} }
if(ps_err(out) != 0) { if(ps_err(out) != 0) {
fatal("Failed to write encrypted output!\n"); fatal(ptx, "Failed to write encrypted output!\n");
goto errsym1; goto errsym1;
} }
@@ -504,7 +504,7 @@ size_t pcp_encrypt_stream_sym(Pcpstream *in, Pcpstream *out, byte *symkey, int h
return 0; return 0;
} }
size_t pcp_decrypt_stream_sym(Pcpstream *in, Pcpstream* out, byte *symkey, pcp_rec_t *recverify) { size_t pcp_decrypt_stream_sym(PCPCTX *ptx, Pcpstream *in, Pcpstream* out, byte *symkey, pcp_rec_t *recverify) {
byte *buf_nonce; byte *buf_nonce;
byte *buf_cipher; byte *buf_cipher;
byte *buf_clear; byte *buf_clear;
@@ -579,13 +579,13 @@ size_t pcp_decrypt_stream_sym(Pcpstream *in, Pcpstream* out, byte *symkey, pcp_r
free(buf_clear); free(buf_clear);
if(ps_err(out) != 0) { if(ps_err(out) != 0) {
fatal("Failed to write decrypted output!\n"); fatal(ptx, "Failed to write decrypted output!\n");
out_size = 0; out_size = 0;
break; break;
} }
} }
else { else {
fatal("Failed to decrypt file content!\n"); fatal(ptx, "Failed to decrypt file content!\n");
free(buf_clear); free(buf_clear);
out_size = 0; out_size = 0;
break; break;
@@ -610,20 +610,20 @@ size_t pcp_decrypt_stream_sym(Pcpstream *in, Pcpstream* out, byte *symkey, pcp_r
crypto_generichash_final(st, hash, crypto_generichash_BYTES_MAX); crypto_generichash_final(st, hash, crypto_generichash_BYTES_MAX);
byte *verifiedhash = NULL; byte *verifiedhash = NULL;
verifiedhash = pcp_ed_verify(signature, siglen, recverify->pub); verifiedhash = pcp_ed_verify(ptx, signature, siglen, recverify->pub);
if(verifiedhash == NULL) if(verifiedhash == NULL)
out_size = 0; out_size = 0;
else { else {
if(memcmp(verifiedhash, hash, crypto_generichash_BYTES_MAX) != 0) { if(memcmp(verifiedhash, hash, crypto_generichash_BYTES_MAX) != 0) {
/* sig verified, but the hash doesn't match */ /* sig verified, but the hash doesn't match */
fatal("signed hash doesn't match actual hash of signed decrypted file content\n"); fatal(ptx, "signed hash doesn't match actual hash of signed decrypted file content\n");
out_size = 0; out_size = 0;
} }
free(verifiedhash); free(verifiedhash);
} }
} }
else { else {
fatal("Failed to decrypt signature!\n"); fatal(ptx, "Failed to decrypt signature!\n");
out_size = 0; out_size = 0;
} }
free(st); free(st);

View File

@@ -21,12 +21,12 @@
#include "ed.h" #include "ed.h"
byte * pcp_ed_verify_key(byte *signature, size_t siglen, pcp_pubkey_t *p) { byte * pcp_ed_verify_key(PCPCTX *ptx, byte *signature, size_t siglen, pcp_pubkey_t *p) {
byte *message = ucmalloc(siglen); byte *message = ucmalloc(siglen);
unsigned long long mlen; unsigned long long mlen;
if(crypto_sign_open(message, &mlen, signature, siglen, p->masterpub) != 0) { if(crypto_sign_open(message, &mlen, signature, siglen, p->masterpub) != 0) {
fatal("Failed to open the signature using the public key 0x%s!\n", p->id); fatal(ptx, "Failed to open the signature using the public key 0x%s!\n", p->id);
goto errve1; goto errve1;
} }
@@ -37,12 +37,12 @@ byte * pcp_ed_verify_key(byte *signature, size_t siglen, pcp_pubkey_t *p) {
return NULL; return NULL;
} }
byte * pcp_ed_verify(byte *signature, size_t siglen, pcp_pubkey_t *p) { byte * pcp_ed_verify(PCPCTX *ptx, byte *signature, size_t siglen, pcp_pubkey_t *p) {
byte *message = ucmalloc(siglen); /* we alloc the full size, the resulting len will be returned by nacl anyway - crypto_sign_BYTES); */ byte *message = ucmalloc(siglen); /* we alloc the full size, the resulting len will be returned by nacl anyway - crypto_sign_BYTES); */
unsigned long long mlen; unsigned long long mlen;
if(crypto_sign_open(message, &mlen, signature, siglen, p->edpub) != 0) { if(crypto_sign_open(message, &mlen, signature, siglen, p->edpub) != 0) {
fatal("Failed to open the signature using the public key 0x%s!\n", p->id); fatal(ptx, "Failed to open the signature using the public key 0x%s!\n", p->id);
goto errve1; goto errve1;
} }
@@ -71,7 +71,7 @@ byte *pcp_ed_sign(byte *message, size_t messagesize, pcp_key_t *s) {
return signature; return signature;
} }
size_t pcp_ed_sign_buffered(Pcpstream *in, Pcpstream* out, pcp_key_t *s, int z85) { size_t pcp_ed_sign_buffered(PCPCTX *ptx, Pcpstream *in, Pcpstream* out, pcp_key_t *s, int z85) {
byte in_buf[PCP_BLOCK_SIZE]; byte in_buf[PCP_BLOCK_SIZE];
size_t cur_bufsize = 0; size_t cur_bufsize = 0;
size_t outsize = 0; size_t outsize = 0;
@@ -94,7 +94,7 @@ size_t pcp_ed_sign_buffered(Pcpstream *in, Pcpstream* out, pcp_key_t *s, int z85
} }
if(ps_err(out) != 0) { if(ps_err(out) != 0) {
fatal("Failed to write encrypted output!\n"); fatal(ptx, "Failed to write encrypted output!\n");
free(st); free(st);
return 0; return 0;
} }
@@ -120,7 +120,7 @@ size_t pcp_ed_sign_buffered(Pcpstream *in, Pcpstream* out, pcp_key_t *s, int z85
return outsize; return outsize;
} }
pcp_pubkey_t *pcp_ed_verify_buffered(Pcpstream *in, pcp_pubkey_t *p) { pcp_pubkey_t *pcp_ed_verify_buffered(PCPCTX *ptx, Pcpstream *in, pcp_pubkey_t *p) {
byte in_buf[PCP_BLOCK_SIZE/2]; byte in_buf[PCP_BLOCK_SIZE/2];
byte in_next[PCP_BLOCK_SIZE/2]; byte in_next[PCP_BLOCK_SIZE/2];
byte in_full[PCP_BLOCK_SIZE]; byte in_full[PCP_BLOCK_SIZE];
@@ -247,23 +247,23 @@ pcp_pubkey_t *pcp_ed_verify_buffered(Pcpstream *in, pcp_pubkey_t *p) {
} /* while */ } /* while */
if(gotsig == 0) { if(gotsig == 0) {
fatal("Error, the signature doesn't contain the ed25519 signed hash\n"); fatal(ptx, "Error, the signature doesn't contain the ed25519 signed hash\n");
goto errvb1; goto errvb1;
} }
crypto_generichash_final(st, hash, crypto_generichash_BYTES_MAX); crypto_generichash_final(st, hash, crypto_generichash_BYTES_MAX);
if(z85) { if(z85) {
char *z85block = pcp_readz85string(z85encoded, zlen); char *z85block = pcp_readz85string(ptx, z85encoded, zlen);
if(z85block == NULL) if(z85block == NULL)
goto errvb1; goto errvb1;
//fprintf(stderr, "ZBLOCK: <%s>\n", z85block); //fprintf(stderr, "ZBLOCK: <%s>\n", z85block);
size_t dstlen; size_t dstlen;
byte *z85decoded = pcp_z85_decode(z85block, &dstlen); byte *z85decoded = pcp_z85_decode(ptx, z85block, &dstlen);
if(dstlen != mlen) { if(dstlen != mlen) {
fatal("z85 decoded signature didn't result in a proper signed hash(got: %ld, expected: %ld)\n", dstlen, mlen); fatal(ptx, "z85 decoded signature didn't result in a proper signed hash(got: %ld, expected: %ld)\n", dstlen, mlen);
goto errvb1; goto errvb1;
} }
memcpy(sighash, z85decoded, mlen); memcpy(sighash, z85decoded, mlen);
@@ -273,14 +273,14 @@ pcp_pubkey_t *pcp_ed_verify_buffered(Pcpstream *in, pcp_pubkey_t *p) {
/* huh, how did we made it til here? */ /* huh, how did we made it til here? */
byte *verifiedhash = NULL; byte *verifiedhash = NULL;
if(p == NULL) { if(p == NULL) {
pcphash_iteratepub(p) { pcphash_iteratepub(ptx, p) {
verifiedhash = pcp_ed_verify(sighash, mlen, p); verifiedhash = pcp_ed_verify(ptx, sighash, mlen, p);
if(verifiedhash != NULL) if(verifiedhash != NULL)
break; break;
} }
} }
else { else {
verifiedhash = pcp_ed_verify(sighash, mlen, p); verifiedhash = pcp_ed_verify(ptx, sighash, mlen, p);
} }
if(verifiedhash == NULL) if(verifiedhash == NULL)
@@ -288,7 +288,7 @@ pcp_pubkey_t *pcp_ed_verify_buffered(Pcpstream *in, pcp_pubkey_t *p) {
if(memcmp(verifiedhash, hash, crypto_generichash_BYTES_MAX) != 0) { if(memcmp(verifiedhash, hash, crypto_generichash_BYTES_MAX) != 0) {
/* sig verified, but the hash doesn't */ /* sig verified, but the hash doesn't */
fatal("signed hash doesn't match actual hash of signed file content\n"); fatal(ptx, "signed hash doesn't match actual hash of signed file content\n");
free(verifiedhash); free(verifiedhash);
return NULL; return NULL;
} }
@@ -336,7 +336,7 @@ size_t pcp_ed_detachsign_buffered(Pcpstream *in, Pcpstream *out, pcp_key_t *s) {
return outsize; return outsize;
} }
pcp_pubkey_t *pcp_ed_detachverify_buffered(Pcpstream *in, Pcpstream *sigfd, pcp_pubkey_t *p) { pcp_pubkey_t *pcp_ed_detachverify_buffered(PCPCTX *ptx, Pcpstream *in, Pcpstream *sigfd, pcp_pubkey_t *p) {
byte in_buf[PCP_BLOCK_SIZE]; byte in_buf[PCP_BLOCK_SIZE];
size_t cur_bufsize = 0; size_t cur_bufsize = 0;
size_t outsize = 0; size_t outsize = 0;
@@ -374,35 +374,35 @@ pcp_pubkey_t *pcp_ed_detachverify_buffered(Pcpstream *in, Pcpstream *sigfd, pcp_
} }
if(sig == NULL) { if(sig == NULL) {
fatal("Invalid detached signature\n"); fatal(ptx, "Invalid detached signature\n");
goto errdea1; goto errdea1;
} }
char *z85block = pcp_readz85string(sig, inputBufSize); char *z85block = pcp_readz85string(ptx, sig, inputBufSize);
if(z85block == NULL) if(z85block == NULL)
goto errdea2; goto errdea2;
size_t clen; size_t clen;
byte *sighash = pcp_z85_decode(z85block, &clen); byte *sighash = pcp_z85_decode(ptx, z85block, &clen);
if(sighash == NULL) if(sighash == NULL)
goto errdea3; goto errdea3;
if(clen != mlen) { if(clen != mlen) {
fatal("z85 decoded signature didn't result in a proper signed hash(got: %ld, expected: %ld)\n", clen, mlen); fatal(ptx, "z85 decoded signature didn't result in a proper signed hash(got: %ld, expected: %ld)\n", clen, mlen);
goto errdea4; goto errdea4;
} }
byte *verifiedhash = NULL; byte *verifiedhash = NULL;
if(p == NULL) { if(p == NULL) {
pcphash_iteratepub(p) { pcphash_iteratepub(ptx, p) {
verifiedhash = pcp_ed_verify(sighash, mlen, p); verifiedhash = pcp_ed_verify(ptx, sighash, mlen, p);
if(verifiedhash != NULL) if(verifiedhash != NULL)
break; break;
} }
} }
else { else {
verifiedhash = pcp_ed_verify(sighash, mlen, p); verifiedhash = pcp_ed_verify(ptx, sighash, mlen, p);
} }
if(verifiedhash == NULL) if(verifiedhash == NULL)
@@ -410,7 +410,7 @@ pcp_pubkey_t *pcp_ed_detachverify_buffered(Pcpstream *in, Pcpstream *sigfd, pcp_
if(memcmp(verifiedhash, hash, crypto_generichash_BYTES_MAX) != 0) { if(memcmp(verifiedhash, hash, crypto_generichash_BYTES_MAX) != 0) {
/* sig verified, but the hash doesn't */ /* sig verified, but the hash doesn't */
fatal("signed hash doesn't match actual hash of signed file content\n"); fatal(ptx, "signed hash doesn't match actual hash of signed file content\n");
goto errdea5; goto errdea5;
} }

View File

@@ -21,19 +21,19 @@
#include "key.h" #include "key.h"
#include "keyhash.h" #include "context.h"
/* /*
* AS of 16/01/2014 I'm using scrypt() instead of my crafted key * AS of 16/01/2014 I'm using scrypt() instead of my crafted key
* derivation function. However, I create a hash from the pcp_scrypt() * derivation function. However, I create a hash from the pcp_scrypt()
* result anyway because I need a cure25519 secret. * result anyway because I need a cure25519 secret.
*/ */
byte *pcp_derivekey(char *passphrase, byte *nonce) { byte *pcp_derivekey(PCPCTX *ptx, char *passphrase, byte *nonce) {
byte *key = ucmalloc(crypto_secretbox_KEYBYTES); byte *key = ucmalloc(crypto_secretbox_KEYBYTES);
size_t plen = strnlen(passphrase, 255); size_t plen = strnlen(passphrase, 255);
/* create the scrypt hash */ /* create the scrypt hash */
byte *scrypted = pcp_scrypt(passphrase, plen, nonce, crypto_secretbox_NONCEBYTES); byte *scrypted = pcp_scrypt(ptx, passphrase, plen, nonce, crypto_secretbox_NONCEBYTES);
/* make a hash from the scrypt() result */ /* make a hash from the scrypt() result */
crypto_hash_sha256(key, (byte*)scrypted, 64); crypto_hash_sha256(key, (byte*)scrypted, 64);
@@ -142,13 +142,13 @@ byte * pcp_gennonce() {
return nonce; return nonce;
} }
pcp_key_t *pcpkey_encrypt(pcp_key_t *key, char *passphrase) { pcp_key_t *pcpkey_encrypt(PCPCTX *ptx, pcp_key_t *key, char *passphrase) {
if(key->nonce[0] == 0) { if(key->nonce[0] == 0) {
byte *nonce = pcp_gennonce(); byte *nonce = pcp_gennonce();
memcpy (key->nonce, nonce, crypto_secretbox_NONCEBYTES); memcpy (key->nonce, nonce, crypto_secretbox_NONCEBYTES);
} }
byte *encryptkey = pcp_derivekey(passphrase, key->nonce); byte *encryptkey = pcp_derivekey(ptx, passphrase, key->nonce);
byte *encrypted; byte *encrypted;
size_t es; size_t es;
@@ -175,7 +175,7 @@ pcp_key_t *pcpkey_encrypt(pcp_key_t *key, char *passphrase) {
key->mastersecret[0] = 0; key->mastersecret[0] = 0;
} }
else { else {
fatal("failed to encrypt the secret key!\n"); fatal(ptx, "failed to encrypt the secret key!\n");
free(key); free(key);
return NULL; return NULL;
} }
@@ -183,8 +183,8 @@ pcp_key_t *pcpkey_encrypt(pcp_key_t *key, char *passphrase) {
return key; return key;
} }
pcp_key_t *pcpkey_decrypt(pcp_key_t *key, char *passphrase) { pcp_key_t *pcpkey_decrypt(PCPCTX *ptx, pcp_key_t *key, char *passphrase) {
byte *encryptkey = pcp_derivekey(passphrase, key->nonce); byte *encryptkey = pcp_derivekey(ptx, passphrase, key->nonce);
byte *decrypted; byte *decrypted;
size_t es; size_t es;
@@ -201,7 +201,7 @@ pcp_key_t *pcpkey_decrypt(pcp_key_t *key, char *passphrase) {
memcpy(key->secret, decrypted +128, 32); memcpy(key->secret, decrypted +128, 32);
} }
else { else {
fatal("failed to decrypt the secret key (got %d, expected 32)!\n", es); fatal(ptx, "failed to decrypt the secret key (got %d, expected 32)!\n", es);
free(key); free(key);
return NULL; return NULL;
} }
@@ -355,26 +355,26 @@ Buffer *pcp_keyblob(void *k, int type) {
} }
int pcp_sanitycheck_pub(pcp_pubkey_t *key) { int pcp_sanitycheck_pub(PCPCTX *ptx, pcp_pubkey_t *key) {
if(key->pub[0] == 0) { if(key->pub[0] == 0) {
fatal("Pubkey sanity check: public key contained in key seems to be empty!\n"); fatal(ptx, "Pubkey sanity check: public key contained in key seems to be empty!\n");
return 1; return 1;
} }
if(key->type != PCP_KEY_TYPE_PUBLIC) { if(key->type != PCP_KEY_TYPE_PUBLIC) {
fatal("Pubkey sanity check: key type is not PUBLIC (expected: %02x, got: %02x)!\n", fatal(ptx, "Pubkey sanity check: key type is not PUBLIC (expected: %02x, got: %02x)!\n",
PCP_KEY_TYPE_PUBLIC, key->type); PCP_KEY_TYPE_PUBLIC, key->type);
return 1; return 1;
} }
if(key->version != PCP_KEY_VERSION) { if(key->version != PCP_KEY_VERSION) {
fatal("Pubkey sanity check: unknown key version (expected: %08X, got: %08X)!\n", fatal(ptx, "Pubkey sanity check: unknown key version (expected: %08X, got: %08X)!\n",
PCP_KEY_VERSION, key->version); PCP_KEY_VERSION, key->version);
return 1; return 1;
} }
if(key->serial <= 0) { if(key->serial <= 0) {
fatal("Pubkey sanity check: invalid serial number: %08X!\n", key->serial); fatal(ptx, "Pubkey sanity check: invalid serial number: %08X!\n", key->serial);
return 1; return 1;
} }
@@ -382,7 +382,7 @@ int pcp_sanitycheck_pub(pcp_pubkey_t *key) {
char *got = ucmalloc(17); char *got = ucmalloc(17);
memcpy(got, key->id, 17); memcpy(got, key->id, 17);
got[16] = '\0'; got[16] = '\0';
fatal("Pubkey sanity check: invalid key id (expected 16 bytes, got: %s)!\n", got); fatal(ptx, "Pubkey sanity check: invalid key id (expected 16 bytes, got: %s)!\n", got);
free(got); free(got);
return 1; return 1;
} }
@@ -392,13 +392,13 @@ int pcp_sanitycheck_pub(pcp_pubkey_t *key) {
c = localtime(&t); c = localtime(&t);
if(c->tm_year <= 0 || c->tm_year > 1100) { if(c->tm_year <= 0 || c->tm_year > 1100) {
/* well, I'm perhaps overacting here :) */ /* well, I'm perhaps overacting here :) */
fatal("Pubkey sanity check: invalid creation timestamp (got year %04d)!\n", c->tm_year + 1900); fatal(ptx, "Pubkey sanity check: invalid creation timestamp (got year %04d)!\n", c->tm_year + 1900);
return 1; return 1;
} }
pcp_pubkey_t *maybe = pcphash_pubkeyexists(key->id); pcp_pubkey_t *maybe = pcphash_pubkeyexists(ptx, key->id);
if(maybe != NULL) { if(maybe != NULL) {
fatal("Pubkey sanity check: there already exists a key with the id 0x%s\n", key->id); fatal(ptx, "Pubkey sanity check: there already exists a key with the id 0x%s\n", key->id);
return 1; return 1;
} }
@@ -406,26 +406,26 @@ int pcp_sanitycheck_pub(pcp_pubkey_t *key) {
} }
int pcp_sanitycheck_key(pcp_key_t *key) { int pcp_sanitycheck_key(PCPCTX *ptx, pcp_key_t *key) {
if(key->encrypted[0] == 0) { if(key->encrypted[0] == 0) {
fatal("Secretkey sanity check: secret key contained in key seems to be empty!\n"); fatal(ptx, "Secretkey sanity check: secret key contained in key seems to be empty!\n");
return 1; return 1;
} }
if(key->type != PCP_KEY_TYPE_SECRET && key->type != PCP_KEY_TYPE_MAINSECRET) { if(key->type != PCP_KEY_TYPE_SECRET && key->type != PCP_KEY_TYPE_MAINSECRET) {
fatal("Secretkey sanity check: key type is not SECRET (expected: %02x, got: %02x)!\n", fatal(ptx, "Secretkey sanity check: key type is not SECRET (expected: %02x, got: %02x)!\n",
PCP_KEY_TYPE_SECRET, key->type); PCP_KEY_TYPE_SECRET, key->type);
return 1; return 1;
} }
if(key->version != PCP_KEY_VERSION) { if(key->version != PCP_KEY_VERSION) {
fatal("Secretkey sanity check: unknown key version (expected: %08X, got: %08X)!\n", fatal(ptx, "Secretkey sanity check: unknown key version (expected: %08X, got: %08X)!\n",
PCP_KEY_VERSION, key->version); PCP_KEY_VERSION, key->version);
return 1; return 1;
} }
if(key->serial <= 0) { if(key->serial <= 0) {
fatal("Secretkey sanity check: invalid serial number: %08X!\n", key->serial); fatal(ptx, "Secretkey sanity check: invalid serial number: %08X!\n", key->serial);
return 1; return 1;
} }
@@ -433,7 +433,7 @@ int pcp_sanitycheck_key(pcp_key_t *key) {
char *got = ucmalloc(17); char *got = ucmalloc(17);
memcpy(got, key->id, 17); memcpy(got, key->id, 17);
got[16] = '\0'; got[16] = '\0';
fatal("Secretkey sanity check: invalid key id (expected 16 bytes, got: %s)!\n", got); fatal(ptx, "Secretkey sanity check: invalid key id (expected 16 bytes, got: %s)!\n", got);
free(got); free(got);
return 1; return 1;
} }
@@ -443,13 +443,13 @@ int pcp_sanitycheck_key(pcp_key_t *key) {
c = localtime(&t); c = localtime(&t);
if(c->tm_year <= 70 || c->tm_year > 1100) { if(c->tm_year <= 70 || c->tm_year > 1100) {
/* well, I'm perhaps overacting here :) */ /* well, I'm perhaps overacting here :) */
fatal("Secretkey sanity check: invalid creation timestamp (got year %04d)!\n", c->tm_year + 1900); fatal(ptx, "Secretkey sanity check: invalid creation timestamp (got year %04d)!\n", c->tm_year + 1900);
return 1; return 1;
} }
pcp_key_t *maybe = pcphash_keyexists(key->id); pcp_key_t *maybe = pcphash_keyexists(ptx, key->id);
if(maybe != NULL) { if(maybe != NULL) {
fatal("Secretkey sanity check: there already exists a key with the id 0x%s\n", key->id); fatal(ptx, "Secretkey sanity check: there already exists a key with the id 0x%s\n", key->id);
return 1; return 1;
} }

View File

@@ -22,102 +22,87 @@
#include "keyhash.h" #include "keyhash.h"
pcp_key_t *pcpkey_hash;
pcp_pubkey_t *pcppubkey_hash;
pcp_keysig_t *pcpkeysig_hash;
pcp_key_t *__k; void pcphash_del(PCPCTX *ptx, void *key, int type) {
pcp_pubkey_t *__p;
pcp_keysig_t *__s;
void pcphash_init() {
pcpkey_hash = NULL;
pcppubkey_hash = NULL;
pcpkeysig_hash = NULL;
}
void pcphash_del(void *key, int type) {
if(type == PCP_KEY_TYPE_SECRET) { if(type == PCP_KEY_TYPE_SECRET) {
HASH_DEL(pcpkey_hash, (pcp_key_t *)key); HASH_DEL(ptx->pcpkey_hash, (pcp_key_t *)key);
memset(key, 0, sizeof(pcp_key_t)); memset(key, 0, sizeof(pcp_key_t));
} }
else if(type == PCP_KEYSIG_NATIVE || type == PCP_KEYSIG_PBP) { else if(type == PCP_KEYSIG_NATIVE || type == PCP_KEYSIG_PBP) {
pcp_keysig_t *keysig = (pcp_keysig_t *)key; pcp_keysig_t *keysig = (pcp_keysig_t *)key;
memset(keysig->blob, 0, keysig->size); memset(keysig->blob, 0, keysig->size);
free(keysig->blob); free(keysig->blob);
HASH_DEL(pcpkeysig_hash, (pcp_keysig_t *)key); HASH_DEL(ptx->pcpkeysig_hash, (pcp_keysig_t *)key);
} }
else { else {
HASH_DEL(pcppubkey_hash, (pcp_pubkey_t *)key); HASH_DEL(ptx->pcppubkey_hash, (pcp_pubkey_t *)key);
memset(key, 0, sizeof(pcp_pubkey_t)); memset(key, 0, sizeof(pcp_pubkey_t));
} }
free(key); free(key);
} }
void pcphash_clean() { void pcphash_clean(PCPCTX *ptx) {
if(pcpkey_hash != NULL) { if(ptx->pcpkey_hash != NULL) {
pcp_key_t *current_key, *tmp; pcp_key_t *current_key, *tmp;
HASH_ITER(hh, pcpkey_hash, current_key, tmp) { HASH_ITER(hh, ptx->pcpkey_hash, current_key, tmp) {
pcphash_del(current_key, PCP_KEY_TYPE_SECRET); pcphash_del(ptx, current_key, PCP_KEY_TYPE_SECRET);
} }
} }
if(pcppubkey_hash != NULL) { if(ptx->pcppubkey_hash != NULL) {
pcp_pubkey_t *current_pub, *ptmp; pcp_pubkey_t *current_pub, *ptmp;
HASH_ITER(hh, pcppubkey_hash, current_pub, ptmp) { HASH_ITER(hh, ptx->pcppubkey_hash, current_pub, ptmp) {
pcphash_del(current_pub, PCP_KEY_TYPE_PUBLIC); pcphash_del(ptx, current_pub, PCP_KEY_TYPE_PUBLIC);
} }
} }
if(pcpkeysig_hash != NULL) { if(ptx->pcpkeysig_hash != NULL) {
pcp_keysig_t *current_keysig, *tmp; pcp_keysig_t *current_keysig, *tmp;
HASH_ITER(hh, pcpkeysig_hash, current_keysig, tmp) { HASH_ITER(hh, ptx->pcpkeysig_hash, current_keysig, tmp) {
pcphash_del(current_keysig, current_keysig->type); pcphash_del(ptx, current_keysig, current_keysig->type);
} }
} }
pcphash_init();
} }
pcp_keysig_t *pcphash_keysigexists(char *id) { pcp_keysig_t *pcphash_keysigexists(PCPCTX *ptx, char *id) {
pcp_keysig_t *keysig = NULL; pcp_keysig_t *keysig = NULL;
HASH_FIND_STR(pcpkeysig_hash, id, keysig); HASH_FIND_STR(ptx->pcpkeysig_hash, id, keysig);
return keysig; /* maybe NULL! */ return keysig; /* maybe NULL! */
} }
pcp_key_t *pcphash_keyexists(char *id) { pcp_key_t *pcphash_keyexists(PCPCTX *ptx, char *id) {
pcp_key_t *key = NULL; pcp_key_t *key = NULL;
HASH_FIND_STR(pcpkey_hash, id, key); HASH_FIND_STR(ptx->pcpkey_hash, id, key);
return key; /* maybe NULL! */ return key; /* maybe NULL! */
} }
pcp_pubkey_t *pcphash_pubkeyexists(char *id) { pcp_pubkey_t *pcphash_pubkeyexists(PCPCTX *ptx, char *id) {
pcp_pubkey_t *key = NULL; pcp_pubkey_t *key = NULL;
HASH_FIND_STR(pcppubkey_hash, id, key); HASH_FIND_STR(ptx->pcppubkey_hash, id, key);
return key; /* maybe NULL! */ return key; /* maybe NULL! */
} }
void pcphash_add(void *key, int type) { void pcphash_add(PCPCTX *ptx, void *key, int type) {
if(type == PCP_KEY_TYPE_PUBLIC) { if(type == PCP_KEY_TYPE_PUBLIC) {
pcp_pubkey_t *k = (pcp_pubkey_t *)key; pcp_pubkey_t *k = (pcp_pubkey_t *)key;
HASH_ADD_STR( pcppubkey_hash, id, k ); HASH_ADD_STR( ptx->pcppubkey_hash, id, k );
} }
else if(type == PCP_KEYSIG_NATIVE || type == PCP_KEYSIG_PBP) { else if(type == PCP_KEYSIG_NATIVE || type == PCP_KEYSIG_PBP) {
pcp_keysig_t *keysig = (pcp_keysig_t *)key; pcp_keysig_t *keysig = (pcp_keysig_t *)key;
HASH_ADD_STR( pcpkeysig_hash, id, keysig); HASH_ADD_STR( ptx->pcpkeysig_hash, id, keysig);
} }
else { else {
pcp_key_t *k = (pcp_key_t *)key; pcp_key_t *k = (pcp_key_t *)key;
HASH_ADD_STR( pcpkey_hash, id, k); HASH_ADD_STR( ptx->pcpkey_hash, id, k);
} }
} }
int pcphash_count() { int pcphash_count(PCPCTX *ptx) {
return HASH_COUNT(pcpkey_hash); return HASH_COUNT(ptx->pcpkey_hash);
} }
int pcphash_countpub() { int pcphash_countpub(PCPCTX *ptx) {
return HASH_COUNT(pcppubkey_hash); return HASH_COUNT(ptx->pcppubkey_hash);
} }

View File

@@ -35,37 +35,37 @@ int _get_pk(Buffer *blob, pcp_pubkey_t *p) {
return 1; return 1;
} }
int _check_keysig_h(Buffer *blob, rfc_pub_sig_h *h) { int _check_keysig_h(PCPCTX *ptx, Buffer *blob, rfc_pub_sig_h *h) {
if(buffer_left(blob) >= sizeof(rfc_pub_sig_h)) { if(buffer_left(blob) >= sizeof(rfc_pub_sig_h)) {
buffer_get_chunk(blob, h, sizeof(rfc_pub_sig_h)); buffer_get_chunk(blob, h, sizeof(rfc_pub_sig_h));
h->numsubs = be16toh(h->numsubs); h->numsubs = be16toh(h->numsubs);
if(h->version != EXP_SIG_VERSION) { if(h->version != EXP_SIG_VERSION) {
fatal("Unsupported pubkey signature version %d, expected %d", h->version, EXP_SIG_VERSION); fatal(ptx, "Unsupported pubkey signature version %d, expected %d", h->version, EXP_SIG_VERSION);
return 1; return 1;
} }
if(h->type != EXP_SIG_TYPE) { if(h->type != EXP_SIG_TYPE) {
fatal("Unsupported pubkey signature type %d, expected %d", h->type, EXP_SIG_TYPE); fatal(ptx, "Unsupported pubkey signature type %d, expected %d", h->type, EXP_SIG_TYPE);
return 1; return 1;
} }
if(h->pkcipher != EXP_SIG_CIPHER) { if(h->pkcipher != EXP_SIG_CIPHER) {
fatal("Unsupported pubkey signature cipher %d, expected %d", h->pkcipher, EXP_SIG_CIPHER); fatal(ptx, "Unsupported pubkey signature cipher %d, expected %d", h->pkcipher, EXP_SIG_CIPHER);
return 1; return 1;
} }
if(h->hashcipher != EXP_HASH_CIPHER) { if(h->hashcipher != EXP_HASH_CIPHER) {
fatal("Unsupported pubkey signature hash cipher %d, expected %d", h->hashcipher, EXP_HASH_CIPHER); fatal(ptx, "Unsupported pubkey signature hash cipher %d, expected %d", h->hashcipher, EXP_HASH_CIPHER);
return 1; return 1;
} }
if(h->numsubs > 0 && buffer_left(blob) < sizeof(rfc_pub_sig_s) * h->numsubs) { if(h->numsubs > 0 && buffer_left(blob) < sizeof(rfc_pub_sig_s) * h->numsubs) {
fatal("Signature size specification invalid (sig: %ld, bytes left: %ld, numsubs: %ld", fatal(ptx, "Signature size specification invalid (sig: %ld, bytes left: %ld, numsubs: %ld",
sizeof(rfc_pub_sig_s) * h->numsubs, buffer_left(blob), h->numsubs); sizeof(rfc_pub_sig_s) * h->numsubs, buffer_left(blob), h->numsubs);
return 1; return 1;
} }
return 0; return 0;
} }
else { else {
fatal("Error: input data too small, import failed"); fatal(ptx, "Error: input data too small, import failed");
return 1; return 1;
} }
} }
@@ -108,7 +108,7 @@ int _check_sigsubs(Buffer *blob, pcp_pubkey_t *p, rfc_pub_sig_s *subheader) {
return 0; return 0;
} }
int _check_hash_keysig(Buffer *blob, pcp_pubkey_t *p, pcp_keysig_t *sk) { int _check_hash_keysig(PCPCTX *ptx, Buffer *blob, pcp_pubkey_t *p, pcp_keysig_t *sk) {
// read hash + sig // read hash + sig
size_t blobstop = blob->offset; size_t blobstop = blob->offset;
size_t sigsize = crypto_sign_BYTES + crypto_generichash_BYTES_MAX; size_t sigsize = crypto_sign_BYTES + crypto_generichash_BYTES_MAX;
@@ -130,7 +130,7 @@ int _check_hash_keysig(Buffer *blob, pcp_pubkey_t *p, pcp_keysig_t *sk) {
buffer_get_chunk(blob, sk->blob, sk->size); buffer_get_chunk(blob, sk->blob, sk->size);
/* verify the signature */ /* verify the signature */
byte *verifyhash = pcp_ed_verify_key(signature, sigsize, p); byte *verifyhash = pcp_ed_verify_key(ptx, signature, sigsize, p);
if(verifyhash == NULL) if(verifyhash == NULL)
goto chker1; goto chker1;
@@ -143,7 +143,7 @@ int _check_hash_keysig(Buffer *blob, pcp_pubkey_t *p, pcp_keysig_t *sk) {
/* compare them */ /* compare them */
if(memcmp(hash, verifyhash, crypto_generichash_BYTES_MAX) != 0) { if(memcmp(hash, verifyhash, crypto_generichash_BYTES_MAX) != 0) {
fatal("Signature verifies but signed hash doesn't match signature contents\n"); fatal(ptx, "Signature verifies but signed hash doesn't match signature contents\n");
goto chker2; goto chker2;
} }
@@ -172,7 +172,7 @@ int _check_hash_keysig(Buffer *blob, pcp_pubkey_t *p, pcp_keysig_t *sk) {
} }
pcp_ks_bundle_t *pcp_import_binpub(byte *raw, size_t rawsize) { pcp_ks_bundle_t *pcp_import_binpub(PCPCTX *ptx, byte *raw, size_t rawsize) {
Buffer *blob = buffer_new(512, "importblob"); Buffer *blob = buffer_new(512, "importblob");
buffer_add(blob, raw, rawsize); buffer_add(blob, raw, rawsize);
@@ -182,35 +182,35 @@ pcp_ks_bundle_t *pcp_import_binpub(byte *raw, size_t rawsize) {
if(version == PCP_KEY_VERSION) { if(version == PCP_KEY_VERSION) {
/* ah, homerun */ /* ah, homerun */
return pcp_import_pub_rfc(blob); return pcp_import_pub_rfc(ptx, blob);
} }
else { else {
/* nope, it's probably pbp */ /* nope, it's probably pbp */
return pcp_import_pub_pbp(blob); return pcp_import_pub_pbp(ptx, blob);
} }
} }
pcp_ks_bundle_t *pcp_import_pub(byte *raw, size_t rawsize) { pcp_ks_bundle_t *pcp_import_pub(PCPCTX *ptx, byte *raw, size_t rawsize) {
size_t clen; size_t clen;
byte *bin = NULL; byte *bin = NULL;
char *z85 = NULL; char *z85 = NULL;
if(rawsize == 0) { if(rawsize == 0) {
fatal("Input file is empty!\n"); fatal(ptx, "Input file is empty!\n");
return NULL; return NULL;
} }
Buffer *blob = buffer_new(512, "importblob"); Buffer *blob = buffer_new(512, "importblob");
/* first, try to decode the input */ /* first, try to decode the input */
z85 = pcp_readz85string(raw, rawsize); z85 = pcp_readz85string(ptx, raw, rawsize);
if(z85 != NULL) if(z85 != NULL)
bin = pcp_z85_decode(z85, &clen); bin = pcp_z85_decode(ptx, z85, &clen);
if(bin == NULL) { if(bin == NULL) {
/* treat as binary blob */ /* treat as binary blob */
fatals_reset(); fatals_reset(ptx);
buffer_add(blob, raw, rawsize); buffer_add(blob, raw, rawsize);
} }
else { else {
@@ -224,15 +224,15 @@ pcp_ks_bundle_t *pcp_import_pub(byte *raw, size_t rawsize) {
if(version == PCP_KEY_VERSION) { if(version == PCP_KEY_VERSION) {
/* ah, homerun */ /* ah, homerun */
return pcp_import_pub_rfc(blob); return pcp_import_pub_rfc(ptx, blob);
} }
else { else {
/* nope, it's probably pbp */ /* nope, it's probably pbp */
return pcp_import_pub_pbp(blob); return pcp_import_pub_pbp(ptx, blob);
} }
} }
pcp_ks_bundle_t *pcp_import_pub_rfc(Buffer *blob) { pcp_ks_bundle_t *pcp_import_pub_rfc(PCPCTX *ptx, Buffer *blob) {
pcp_pubkey_t *p = ucmalloc(sizeof(pcp_pubkey_t)); pcp_pubkey_t *p = ucmalloc(sizeof(pcp_pubkey_t));
pcp_keysig_t *sk = ucmalloc(sizeof(pcp_keysig_t)); pcp_keysig_t *sk = ucmalloc(sizeof(pcp_keysig_t));
rfc_pub_sig_h *sigheader = ucmalloc(sizeof(rfc_pub_sig_h)); rfc_pub_sig_h *sigheader = ucmalloc(sizeof(rfc_pub_sig_h));
@@ -245,7 +245,7 @@ pcp_ks_bundle_t *pcp_import_pub_rfc(Buffer *blob) {
if(buffer_done(blob)) goto be; if(buffer_done(blob)) goto be;
if(pkcipher != EXP_PK_CIPHER) { if(pkcipher != EXP_PK_CIPHER) {
fatal("Unsupported pk cipher %d, expected %d", pkcipher, EXP_PK_CIPHER); fatal(ptx, "Unsupported pk cipher %d, expected %d", pkcipher, EXP_PK_CIPHER);
goto bef; goto bef;
} }
@@ -254,7 +254,7 @@ pcp_ks_bundle_t *pcp_import_pub_rfc(Buffer *blob) {
goto be; goto be;
/* check sig header */ /* check sig header */
if(_check_keysig_h(blob, sigheader) != 0) if(_check_keysig_h(ptx, blob, sigheader) != 0)
goto bef; goto bef;
/* iterate over subs, if any */ /* iterate over subs, if any */
@@ -277,7 +277,7 @@ pcp_ks_bundle_t *pcp_import_pub_rfc(Buffer *blob) {
pcp_ks_bundle_t *b = ucmalloc(sizeof(pcp_ks_bundle_t)); pcp_ks_bundle_t *b = ucmalloc(sizeof(pcp_ks_bundle_t));
/* retrieve signature, store and verify it */ /* retrieve signature, store and verify it */
if(_check_hash_keysig(blob, p, sk) != 0) { if(_check_hash_keysig(ptx, blob, p, sk) != 0) {
b->p = p; b->p = p;
b->s = NULL; b->s = NULL;
} }
@@ -290,7 +290,7 @@ pcp_ks_bundle_t *pcp_import_pub_rfc(Buffer *blob) {
be: be:
fatal("Error: input data too small, import failed"); fatal(ptx, "Error: input data too small, import failed");
bef: bef:
buffer_free(blob); buffer_free(blob);
@@ -300,7 +300,7 @@ pcp_ks_bundle_t *pcp_import_pub_rfc(Buffer *blob) {
return NULL; return NULL;
} }
pcp_ks_bundle_t *pcp_import_pub_pbp(Buffer *blob) { pcp_ks_bundle_t *pcp_import_pub_pbp(PCPCTX *ptx, Buffer *blob) {
char *date = ucmalloc(19); char *date = ucmalloc(19);
char *ignore = ucmalloc(46); char *ignore = ucmalloc(46);
char *parts = NULL; char *parts = NULL;
@@ -314,7 +314,7 @@ pcp_ks_bundle_t *pcp_import_pub_pbp(Buffer *blob) {
/* make sure it's a pbp */ /* make sure it's a pbp */
if(_buffer_is_binary(sig, crypto_sign_BYTES) == 0) { if(_buffer_is_binary(sig, crypto_sign_BYTES) == 0) {
fatal("failed to recognize input, that's probably no key\n"); fatal(ptx, "failed to recognize input, that's probably no key\n");
goto errimp2; goto errimp2;
} }
@@ -326,7 +326,7 @@ pcp_ks_bundle_t *pcp_import_pub_pbp(Buffer *blob) {
date[19] = '\0'; date[19] = '\0';
struct tm c; struct tm c;
if(strptime(date, "%Y-%m-%dT%H:%M:%S", &c) == NULL) { if(strptime(date, "%Y-%m-%dT%H:%M:%S", &c) == NULL) {
fatal("Failed to parse creation time in PBP public key file (<%s>)\n", date); fatal(ptx, "Failed to parse creation time in PBP public key file (<%s>)\n", date);
free(date); free(date);
goto errimp2; goto errimp2;
} }
@@ -365,7 +365,7 @@ pcp_ks_bundle_t *pcp_import_pub_pbp(Buffer *blob) {
/* edpub used for signing, might differ */ /* edpub used for signing, might differ */
memcpy(tmp->edpub, b->sigpub, crypto_sign_PUBLICKEYBYTES); memcpy(tmp->edpub, b->sigpub, crypto_sign_PUBLICKEYBYTES);
byte *verify = pcp_ed_verify(buffer_get(blob), buffer_size(blob), tmp); byte *verify = pcp_ed_verify(ptx, buffer_get(blob), buffer_size(blob), tmp);
free(tmp); free(tmp);
pcp_ks_bundle_t *bundle = ucmalloc(sizeof(pcp_ks_bundle_t)); pcp_ks_bundle_t *bundle = ucmalloc(sizeof(pcp_ks_bundle_t));
@@ -671,7 +671,7 @@ Buffer *pcp_export_rfc_pub (pcp_key_t *sk) {
return out; return out;
} }
Buffer *pcp_export_secret(pcp_key_t *sk, char *passphrase) { Buffer *pcp_export_secret(PCPCTX *ptx, pcp_key_t *sk, char *passphrase) {
byte *nonce = NULL; byte *nonce = NULL;
byte *symkey = NULL; byte *symkey = NULL;
byte *cipher = NULL; byte *cipher = NULL;
@@ -708,7 +708,7 @@ Buffer *pcp_export_secret(pcp_key_t *sk, char *passphrase) {
nonce = ucmalloc(crypto_secretbox_NONCEBYTES); nonce = ucmalloc(crypto_secretbox_NONCEBYTES);
arc4random_buf(nonce, crypto_secretbox_NONCEBYTES); arc4random_buf(nonce, crypto_secretbox_NONCEBYTES);
symkey = pcp_scrypt(passphrase, strlen(passphrase), nonce, crypto_secretbox_NONCEBYTES); symkey = pcp_scrypt(ptx, passphrase, strlen(passphrase), nonce, crypto_secretbox_NONCEBYTES);
es = pcp_sodium_mac(&cipher, buffer_get(raw), buffer_size(raw), nonce, symkey); es = pcp_sodium_mac(&cipher, buffer_get(raw), buffer_size(raw), nonce, symkey);
@@ -723,33 +723,33 @@ Buffer *pcp_export_secret(pcp_key_t *sk, char *passphrase) {
return out; return out;
} }
pcp_key_t *pcp_import_binsecret(byte *raw, size_t rawsize, char *passphrase) { pcp_key_t *pcp_import_binsecret(PCPCTX *ptx, byte *raw, size_t rawsize, char *passphrase) {
Buffer *blob = buffer_new(512, "importskblob"); Buffer *blob = buffer_new(512, "importskblob");
buffer_add(blob, raw, rawsize); buffer_add(blob, raw, rawsize);
return pcp_import_secret_native(blob, passphrase); return pcp_import_secret_native(ptx, blob, passphrase);
} }
pcp_key_t *pcp_import_secret(byte *raw, size_t rawsize, char *passphrase) { pcp_key_t *pcp_import_secret(PCPCTX *ptx, byte *raw, size_t rawsize, char *passphrase) {
size_t clen; size_t clen;
byte *bin = NULL; byte *bin = NULL;
char *z85 = NULL; char *z85 = NULL;
if(rawsize == 0) { if(rawsize == 0) {
fatal("Input file is empty!\n"); fatal(ptx, "Input file is empty!\n");
return NULL; return NULL;
} }
Buffer *blob = buffer_new(512, "importskblob"); Buffer *blob = buffer_new(512, "importskblob");
/* first, try to decode the input */ /* first, try to decode the input */
z85 = pcp_readz85string(raw, rawsize); z85 = pcp_readz85string(ptx, raw, rawsize);
if(z85 != NULL) if(z85 != NULL)
bin = pcp_z85_decode(z85, &clen); bin = pcp_z85_decode(ptx, z85, &clen);
if(bin == NULL) { if(bin == NULL) {
/* treat as binary blob */ /* treat as binary blob */
fatals_reset(); fatals_reset(ptx);
buffer_add(blob, raw, rawsize); buffer_add(blob, raw, rawsize);
} }
else { else {
@@ -759,10 +759,10 @@ pcp_key_t *pcp_import_secret(byte *raw, size_t rawsize, char *passphrase) {
} }
/* now we've got the blob, parse it */ /* now we've got the blob, parse it */
return pcp_import_secret_native(blob, passphrase); return pcp_import_secret_native(ptx, blob, passphrase);
} }
pcp_key_t *pcp_import_secret_native(Buffer *cipher, char *passphrase) { pcp_key_t *pcp_import_secret_native(PCPCTX *ptx, Buffer *cipher, char *passphrase) {
pcp_key_t *sk = ucmalloc(sizeof(pcp_key_t)); pcp_key_t *sk = ucmalloc(sizeof(pcp_key_t));
byte *nonce = ucmalloc(crypto_secretbox_NONCEBYTES); byte *nonce = ucmalloc(crypto_secretbox_NONCEBYTES);
byte *symkey = NULL; byte *symkey = NULL;
@@ -776,11 +776,11 @@ pcp_key_t *pcp_import_secret_native(Buffer *cipher, char *passphrase) {
if(buffer_get_chunk(cipher, nonce, crypto_secretbox_NONCEBYTES) == 0) if(buffer_get_chunk(cipher, nonce, crypto_secretbox_NONCEBYTES) == 0)
goto impserr1; goto impserr1;
symkey = pcp_scrypt(passphrase, strlen(passphrase), nonce, crypto_secretbox_NONCEBYTES); symkey = pcp_scrypt(ptx, passphrase, strlen(passphrase), nonce, crypto_secretbox_NONCEBYTES);
cipherlen = buffer_left(cipher); cipherlen = buffer_left(cipher);
if(cipherlen < minlen) { if(cipherlen < minlen) {
fatal("failed to decrypt the secret key file:\n" fatal(ptx, "failed to decrypt the secret key file:\n"
"expected encrypted secret key size %ld is less than minimum len %ld\n", cipherlen, minlen); "expected encrypted secret key size %ld is less than minimum len %ld\n", cipherlen, minlen);
goto impserr1; goto impserr1;
} }
@@ -788,7 +788,7 @@ pcp_key_t *pcp_import_secret_native(Buffer *cipher, char *passphrase) {
/* decrypt the blob */ /* decrypt the blob */
if(pcp_sodium_verify_mac(&clear, buffer_get_remainder(cipher), if(pcp_sodium_verify_mac(&clear, buffer_get_remainder(cipher),
cipherlen, nonce, symkey) != 0) { cipherlen, nonce, symkey) != 0) {
fatal("failed to decrypt the secret key file\n"); fatal(ptx, "failed to decrypt the secret key file\n");
goto impserr1; goto impserr1;
} }

View File

@@ -359,9 +359,7 @@ void ps_determine(Pcpstream *stream) {
size_t ps_read_decode(Pcpstream *stream) { size_t ps_read_decode(Pcpstream *stream) {
Buffer *z = buffer_new(32, "ztemp"); Buffer *z = buffer_new(32, "ztemp");
Buffer *line = buffer_new_str("line"); Buffer *line = buffer_new_str("line");
PCPCTX *ptx = ptx_new();
//buffer_info(stream->save);
if(buffer_left(stream->save) > stream->blocksize){// && stream->firstread == 1) { if(buffer_left(stream->save) > stream->blocksize){// && stream->firstread == 1) {
/* use the save buffer instead */ /* use the save buffer instead */
@@ -376,7 +374,7 @@ size_t ps_read_decode(Pcpstream *stream) {
// fprintf(stderr, " ps_read_next which doesn't end in a newline\n"); // fprintf(stderr, " ps_read_next which doesn't end in a newline\n");
buffer_get_chunk_tobuf(stream->save, z, buffer_left(stream->save)); buffer_get_chunk_tobuf(stream->save, z, buffer_left(stream->save));
//buffer_dump(z); //buffer_dump(z);
fatals_ifany(); //fatals_ifany();
} }
else { else {
/* continue reading linewise */ /* continue reading linewise */
@@ -435,10 +433,10 @@ size_t ps_read_decode(Pcpstream *stream) {
/* finally, decode it and put into next */ /* finally, decode it and put into next */
size_t binlen, outlen; size_t binlen, outlen;
byte *bin = pcp_z85_decode(buffer_get_str(z), &binlen); byte *bin = pcp_z85_decode(ptx, buffer_get_str(z), &binlen);
//fprintf(stderr, "ps_read_decode decoding z: %ld, got: %ld\n", buffer_size(z), binlen); //fprintf(stderr, "ps_read_decode decoding z: %ld, got: %ld\n", buffer_size(z), binlen);
// _dump("bin", bin, binlen); // _dump("bin", bin, binlen);
fatals_ifany(); //fatals_ifany();
if(bin == NULL) { if(bin == NULL) {
/* it's not z85 encoded, so threat it as binary */ /* it's not z85 encoded, so threat it as binary */
if(stream->firstread) { if(stream->firstread) {
@@ -461,7 +459,7 @@ size_t ps_read_decode(Pcpstream *stream) {
buffer_free(z); buffer_free(z);
buffer_free(line); buffer_free(line);
ptx_clean(ptx);
return outlen; return outlen;
} }

View File

@@ -21,7 +21,7 @@
#include "scrypt.h" #include "scrypt.h"
byte* pcp_scrypt(char *passwd, size_t passwdlen, byte *nonce, size_t noncelen) { byte* pcp_scrypt(PCPCTX *ptx, char *passwd, size_t passwdlen, byte *nonce, size_t noncelen) {
uint8_t *dk = ucmalloc(64); /* resulting hash */ uint8_t *dk = ucmalloc(64); /* resulting hash */
/* constants */ /* constants */
@@ -34,7 +34,7 @@ byte* pcp_scrypt(char *passwd, size_t passwdlen, byte *nonce, size_t noncelen) {
return dk; return dk;
} }
else { else {
fatal("crypto_scrypt() failed"); fatal(ptx, "crypto_scrypt() failed");
return NULL; return NULL;
} }

View File

@@ -24,19 +24,19 @@
#include "keyhash.h" #include "keyhash.h"
#include "defines.h" #include "defines.h"
vault_t *pcpvault_init(char *filename) { vault_t *pcpvault_init(PCPCTX *ptx, char *filename) {
vault_t *vault = pcpvault_new(filename, 0); vault_t *vault = pcpvault_new(ptx, filename, 0);
if(vault != NULL) { if(vault != NULL) {
if(vault->isnew == 1) { if(vault->isnew == 1) {
if(pcpvault_create(vault) != 0) { if(pcpvault_create(ptx, vault) != 0) {
pcpvault_close(vault); pcpvault_close(ptx, vault);
return NULL; return NULL;
} }
} }
else { else {
if(pcpvault_fetchall(vault) != 0) { if(pcpvault_fetchall(ptx, vault) != 0) {
errno = 0; /* weird, something sets it to ENOENT and it's not me */ errno = 0; /* weird, something sets it to ENOENT and it's not me */
pcpvault_close(vault); pcpvault_close(ptx, vault);
return NULL; return NULL;
} }
} }
@@ -44,7 +44,7 @@ vault_t *pcpvault_init(char *filename) {
return vault; return vault;
} }
vault_t *pcpvault_new(char *filename, int is_tmp) { vault_t *pcpvault_new(PCPCTX *ptx, char *filename, int is_tmp) {
vault_t *vault = ucmalloc(sizeof(vault_t)); vault_t *vault = ucmalloc(sizeof(vault_t));
FILE *fd; FILE *fd;
struct stat stat_buf; struct stat stat_buf;
@@ -82,7 +82,7 @@ vault_t *pcpvault_new(char *filename, int is_tmp) {
vault->isnew = 1; vault->isnew = 1;
mode_t old_mask = umask (S_IWGRP | S_IWOTH | S_IRGRP | S_IROTH); mode_t old_mask = umask (S_IWGRP | S_IWOTH | S_IRGRP | S_IROTH);
if((fd = fopen(vault->filename, "wb+")) == NULL) { if((fd = fopen(vault->filename, "wb+")) == NULL) {
fatal("Could not create vault file %s", vault->filename); fatal(ptx, "Could not create vault file %s", vault->filename);
umask (old_mask); umask (old_mask);
goto errn; goto errn;
} }
@@ -90,7 +90,7 @@ vault_t *pcpvault_new(char *filename, int is_tmp) {
} }
else { else {
if((fd = fopen(vault->filename, "rb+")) == NULL) { if((fd = fopen(vault->filename, "rb+")) == NULL) {
fatal("Could not open vault file %s", vault->filename); fatal(ptx, "Could not open vault file %s", vault->filename);
goto errn; goto errn;
} }
} }
@@ -105,7 +105,7 @@ vault_t *pcpvault_new(char *filename, int is_tmp) {
return NULL; return NULL;
} }
int pcpvault_create(vault_t *vault) { int pcpvault_create(PCPCTX *ptx, vault_t *vault) {
vault_header_t *header = ucmalloc(sizeof(vault_header_t)); vault_header_t *header = ucmalloc(sizeof(vault_header_t));
header->fileid = PCP_VAULT_ID; header->fileid = PCP_VAULT_ID;
header->version = PCP_VAULT_VERSION; header->version = PCP_VAULT_VERSION;
@@ -120,7 +120,7 @@ int pcpvault_create(vault_t *vault) {
fwrite(header, sizeof(vault_header_t), 1, vault->fd); fwrite(header, sizeof(vault_header_t), 1, vault->fd);
if(ferror(vault->fd) != 0) { if(ferror(vault->fd) != 0) {
fatal("Failed to write fileheader to vault %s!\n", vault->filename); fatal(ptx, "Failed to write fileheader to vault %s!\n", vault->filename);
return 1; return 1;
} }
@@ -129,7 +129,7 @@ int pcpvault_create(vault_t *vault) {
return 0; return 0;
} }
int pcpvault_additem(vault_t *vault, void *item, size_t itemsize, uint8_t type) { int pcpvault_additem(PCPCTX *ptx, vault_t *vault, void *item, size_t itemsize, uint8_t type) {
vault_item_header_t *header = ucmalloc(sizeof(vault_item_header_t)); vault_item_header_t *header = ucmalloc(sizeof(vault_item_header_t));
header->type = type; header->type = type;
header->size = itemsize; header->size = itemsize;
@@ -141,7 +141,7 @@ int pcpvault_additem(vault_t *vault, void *item, size_t itemsize, uint8_t type)
fwrite(item, itemsize, 1, vault->fd); fwrite(item, itemsize, 1, vault->fd);
if(ferror(vault->fd) != 0) { if(ferror(vault->fd) != 0) {
fatal("Failed to add an item to vault %s!\n", vault->filename); fatal(ptx, "Failed to add an item to vault %s!\n", vault->filename);
return 1; return 1;
} }
@@ -151,8 +151,8 @@ int pcpvault_additem(vault_t *vault, void *item, size_t itemsize, uint8_t type)
} }
int pcpvault_addkey(vault_t *vault, void *item, uint8_t type) { int pcpvault_addkey(PCPCTX *ptx, vault_t *vault, void *item, uint8_t type) {
vault_t *tmp = pcpvault_new(vault->filename, 1); vault_t *tmp = pcpvault_new(ptx, vault->filename, 1);
size_t itemsize; size_t itemsize;
void *saveitem = NULL; void *saveitem = NULL;
@@ -183,15 +183,15 @@ int pcpvault_addkey(vault_t *vault, void *item, uint8_t type) {
if(tmp != NULL) { if(tmp != NULL) {
if(pcpvault_copy(vault, tmp) != 0) if(pcpvault_copy(ptx, vault, tmp) != 0)
goto errak1; goto errak1;
if(pcpvault_additem(tmp, buffer_get(blob), itemsize, type) != 0) if(pcpvault_additem(ptx, tmp, buffer_get(blob), itemsize, type) != 0)
goto errak1; goto errak1;
pcphash_add(saveitem, type); pcphash_add(ptx, saveitem, type);
pcpvault_update_checksum(tmp); pcpvault_update_checksum(ptx, tmp);
if(pcpvault_copy(tmp, vault) == 0) { if(pcpvault_copy(ptx, tmp, vault) == 0) {
pcpvault_unlink(tmp); pcpvault_unlink(tmp);
} }
else { else {
@@ -212,32 +212,32 @@ int pcpvault_addkey(vault_t *vault, void *item, uint8_t type) {
return 1; return 1;
} }
int pcpvault_writeall(vault_t *vault) { int pcpvault_writeall(PCPCTX *ptx, vault_t *vault) {
vault_t *tmp = pcpvault_new(vault->filename, 1); vault_t *tmp = pcpvault_new(ptx, vault->filename, 1);
if(tmp != NULL) { if(tmp != NULL) {
if(pcpvault_create(tmp) == 0) { if(pcpvault_create(ptx, tmp) == 0) {
pcp_key_t *k = NULL; pcp_key_t *k = NULL;
Buffer *blob = buffer_new(PCP_RAW_PUBKEYSIZE, "bs"); Buffer *blob = buffer_new(PCP_RAW_PUBKEYSIZE, "bs");
pcphash_iterate(k) { pcphash_iterate(ptx, k) {
pcp_seckeyblob(blob, k); pcp_seckeyblob(blob, k);
if(pcpvault_additem(tmp, buffer_get(blob), PCP_RAW_KEYSIZE, PCP_KEY_TYPE_SECRET) != 0) { if(pcpvault_additem(ptx, tmp, buffer_get(blob), PCP_RAW_KEYSIZE, PCP_KEY_TYPE_SECRET) != 0) {
buffer_free(blob); buffer_free(blob);
goto errwa; goto errwa;
} }
buffer_clear(blob); buffer_clear(blob);
} }
pcp_pubkey_t *p = NULL; pcp_pubkey_t *p = NULL;
pcphash_iteratepub(p) { pcphash_iteratepub(ptx, p) {
pcp_pubkeyblob(blob, p); pcp_pubkeyblob(blob, p);
if(pcpvault_additem(tmp, buffer_get(blob), PCP_RAW_PUBKEYSIZE, PCP_KEY_TYPE_PUBLIC) != 0) { if(pcpvault_additem(ptx, tmp, buffer_get(blob), PCP_RAW_PUBKEYSIZE, PCP_KEY_TYPE_PUBLIC) != 0) {
buffer_free(blob); buffer_free(blob);
goto errwa; goto errwa;
} }
buffer_clear(blob); buffer_clear(blob);
} }
pcpvault_update_checksum(tmp); pcpvault_update_checksum(ptx, tmp);
if(pcpvault_copy(tmp, vault) == 0) { if(pcpvault_copy(ptx, tmp, vault) == 0) {
pcpvault_unlink(tmp); pcpvault_unlink(tmp);
} }
free(tmp); free(tmp);
@@ -256,8 +256,8 @@ int pcpvault_writeall(vault_t *vault) {
return 1; return 1;
} }
void pcpvault_update_checksum(vault_t *vault) { void pcpvault_update_checksum(PCPCTX *ptx, vault_t *vault) {
byte *checksum = pcpvault_create_checksum(); byte *checksum = pcpvault_create_checksum(ptx);
vault_header_t *header = ucmalloc(sizeof(vault_header_t)); vault_header_t *header = ucmalloc(sizeof(vault_header_t));
header->fileid = PCP_VAULT_ID; header->fileid = PCP_VAULT_ID;
@@ -272,20 +272,20 @@ void pcpvault_update_checksum(vault_t *vault) {
fseek(vault->fd, 0, SEEK_END); fseek(vault->fd, 0, SEEK_END);
} }
byte *pcpvault_create_checksum() { byte *pcpvault_create_checksum(PCPCTX *ptx) {
pcp_key_t *k = NULL; pcp_key_t *k = NULL;
Buffer *blob = NULL; Buffer *blob = NULL;
size_t datapos = 0; size_t datapos = 0;
int numskeys = pcphash_count(); int numskeys = pcphash_count(ptx);
int numpkeys = pcphash_countpub(); int numpkeys = pcphash_countpub(ptx);
size_t datasize = ((PCP_RAW_KEYSIZE) * numskeys) + size_t datasize = ((PCP_RAW_KEYSIZE) * numskeys) +
((PCP_RAW_PUBKEYSIZE) * numpkeys); ((PCP_RAW_PUBKEYSIZE) * numpkeys);
byte *data = ucmalloc(datasize); byte *data = ucmalloc(datasize);
byte *checksum = ucmalloc(32); byte *checksum = ucmalloc(32);
pcphash_iterate(k) { pcphash_iterate(ptx, k) {
key2be(k); key2be(k);
blob = pcp_keyblob(k, PCP_KEY_TYPE_SECRET); blob = pcp_keyblob(k, PCP_KEY_TYPE_SECRET);
memcpy(&data[datapos], buffer_get(blob), PCP_RAW_KEYSIZE); memcpy(&data[datapos], buffer_get(blob), PCP_RAW_KEYSIZE);
@@ -295,7 +295,7 @@ byte *pcpvault_create_checksum() {
} }
pcp_pubkey_t *p = NULL; pcp_pubkey_t *p = NULL;
pcphash_iteratepub(p) { pcphash_iteratepub(ptx, p) {
/* pcp_dumppubkey(p); */ /* pcp_dumppubkey(p); */
pubkey2be(p); pubkey2be(p);
blob = pcp_keyblob(p, PCP_KEY_TYPE_PUBLIC); blob = pcp_keyblob(p, PCP_KEY_TYPE_PUBLIC);
@@ -322,7 +322,7 @@ byte *pcpvault_create_checksum() {
} }
int pcpvault_copy(vault_t *tmp, vault_t *vault) { int pcpvault_copy(PCPCTX *ptx, vault_t *tmp, vault_t *vault) {
/* fetch tmp content */ /* fetch tmp content */
fseek(tmp->fd, 0, SEEK_END); fseek(tmp->fd, 0, SEEK_END);
int tmpsize = ftell(tmp->fd); int tmpsize = ftell(tmp->fd);
@@ -333,13 +333,13 @@ int pcpvault_copy(vault_t *tmp, vault_t *vault) {
/* and put it into the new file */ /* and put it into the new file */
vault->fd = freopen(vault->filename, "wb+", vault->fd); vault->fd = freopen(vault->filename, "wb+", vault->fd);
if(fwrite(in, tmpsize, 1, vault->fd) != 1) { if(fwrite(in, tmpsize, 1, vault->fd) != 1) {
fatal("Failed to copy %s to %s (write) [keeping %s]\n", fatal(ptx, "Failed to copy %s to %s (write) [keeping %s]\n",
tmp->filename, vault->filename, tmp->filename); tmp->filename, vault->filename, tmp->filename);
return 1; return 1;
} }
if(fflush(vault->fd) != 0) { if(fflush(vault->fd) != 0) {
fatal("Failed to copy %s to %s (flush) [keeping %s]\n", fatal(ptx, "Failed to copy %s to %s (flush) [keeping %s]\n",
tmp->filename, vault->filename, tmp->filename); tmp->filename, vault->filename, tmp->filename);
return 1; return 1;
} }
@@ -363,11 +363,11 @@ void pcpvault_unlink(vault_t *tmp) {
free(r); free(r);
} }
int pcpvault_close(vault_t *vault) { int pcpvault_close(PCPCTX *ptx, vault_t *vault) {
if(vault != NULL) { if(vault != NULL) {
if(vault->fd) { if(vault->fd) {
if(vault->unsafed == 1) { if(vault->unsafed == 1) {
pcpvault_writeall(vault); pcpvault_writeall(ptx, vault);
} }
fclose(vault->fd); fclose(vault->fd);
} }
@@ -416,7 +416,7 @@ vault_item_header_t * ih2native(vault_item_header_t *h) {
} }
int pcpvault_fetchall(vault_t *vault) { int pcpvault_fetchall(PCPCTX *ptx, vault_t *vault) {
size_t got = 0; size_t got = 0;
fseek(vault->fd, 0, SEEK_SET); fseek(vault->fd, 0, SEEK_SET);
@@ -424,7 +424,7 @@ int pcpvault_fetchall(vault_t *vault) {
vault_item_header_t *item = ucmalloc(sizeof(vault_item_header_t)); vault_item_header_t *item = ucmalloc(sizeof(vault_item_header_t));
got = fread(header, 1, sizeof(vault_header_t), vault->fd); got = fread(header, 1, sizeof(vault_header_t), vault->fd);
if(got < sizeof(vault_header_t)) { if(got < sizeof(vault_header_t)) {
fatal("empty or invalid vault header size (got %ld, expected %ld)\n", got, sizeof(vault_header_t)); fatal(ptx, "empty or invalid vault header size (got %ld, expected %ld)\n", got, sizeof(vault_header_t));
goto err; goto err;
} }
vh2native(header); vh2native(header);
@@ -437,8 +437,6 @@ int pcpvault_fetchall(vault_t *vault) {
int bytesleft = 0; int bytesleft = 0;
int ksize = PCP_RAW_KEYSIGSIZE; /* smallest possbile item */ int ksize = PCP_RAW_KEYSIGSIZE; /* smallest possbile item */
pcphash_init();
vault->version = header->version; vault->version = header->version;
memcpy(vault->checksum, header->checksum, 32); memcpy(vault->checksum, header->checksum, 32);
@@ -461,34 +459,34 @@ int pcpvault_fetchall(vault_t *vault) {
key = ucmalloc(sizeof(pcp_key_t)); key = ucmalloc(sizeof(pcp_key_t));
got = fread(key, PCP_RAW_KEYSIZE, 1, vault->fd); got = fread(key, PCP_RAW_KEYSIZE, 1, vault->fd);
key2native(key); key2native(key);
pcphash_add((void *)key, item->type); pcphash_add(ptx, (void *)key, item->type);
} }
else if(item->type == PCP_KEY_TYPE_PUBLIC) { else if(item->type == PCP_KEY_TYPE_PUBLIC) {
/* read a public key */ /* read a public key */
pubkey = ucmalloc(sizeof(pcp_pubkey_t)); pubkey = ucmalloc(sizeof(pcp_pubkey_t));
got = fread(pubkey, PCP_RAW_PUBKEYSIZE, 1, vault->fd); got = fread(pubkey, PCP_RAW_PUBKEYSIZE, 1, vault->fd);
pubkey2native(pubkey); pubkey2native(pubkey);
pcphash_add((void *)pubkey, item->type); pcphash_add(ptx, (void *)pubkey, item->type);
} }
else if(item->type == PCP_KEYSIG_NATIVE || item->type == PCP_KEYSIG_PBP) { else if(item->type == PCP_KEYSIG_NATIVE || item->type == PCP_KEYSIG_PBP) {
Buffer *rawks = buffer_new(256, "keysig"); Buffer *rawks = buffer_new(256, "keysig");
buffer_fd_read(rawks, vault->fd, item->size); buffer_fd_read(rawks, vault->fd, item->size);
pcp_keysig_t *s = pcp_keysig_new(rawks); pcp_keysig_t *s = pcp_keysig_new(rawks);
pcphash_add((void *)s, item->type); pcphash_add(ptx, (void *)s, item->type);
buffer_free(rawks); buffer_free(rawks);
} }
else { else {
fatal("Failed to read vault - invalid key type: %02X! at %d\n", item->type, readpos); fatal(ptx, "Failed to read vault - invalid key type: %02X! at %d\n", item->type, readpos);
goto err; goto err;
} }
} }
else { else {
fatal("Failed to read vault - that's no pcp key at %d (size %ld)!\n", readpos, bytesleft); fatal(ptx, "Failed to read vault - that's no pcp key at %d (size %ld)!\n", readpos, bytesleft);
goto err; goto err;
} }
} }
else { else {
fatal("Failed to read vault - invalid key item header size at %d!\n", fatal(ptx, "Failed to read vault - invalid key item header size at %d!\n",
readpos); readpos);
goto err; goto err;
} }
@@ -500,22 +498,22 @@ int pcpvault_fetchall(vault_t *vault) {
} }
} }
else { else {
fatal("Unexpected vault file format!\n"); fatal(ptx, "Unexpected vault file format!\n");
goto err; goto err;
} }
byte *checksum = NULL; byte *checksum = NULL;
checksum = pcpvault_create_checksum(vault); checksum = pcpvault_create_checksum(ptx);
/* /*
_dump(" calc checksum", checksum, 32); _dump(" calc checksum", checksum, 32);
_dump("vault checksum", vault->checksum, 32); _dump("vault checksum", vault->checksum, 32);
*/ */
if(pcphash_count() + pcphash_countpub() > 0) { if(pcphash_count(ptx) + pcphash_countpub(ptx) > 0) {
/* only validate the checksum if there are keys */ /* only validate the checksum if there are keys */
if(memcmp(checksum, vault->checksum, 32) != 0) { if(memcmp(checksum, vault->checksum, 32) != 0) {
fatal("Error: the checksum of the key vault doesn't match its contents!\n"); fatal(ptx, "Error: the checksum of the key vault doesn't match its contents!\n");
goto err; goto err;
} }
} }

View File

@@ -182,7 +182,7 @@ size_t pcp_unpadfour(byte *src, size_t srclen) {
return outlen; return outlen;
} }
byte *pcp_z85_decode(char *z85block, size_t *dstlen) { byte *pcp_z85_decode(PCPCTX *ptx, char *z85block, size_t *dstlen) {
byte *bin = NULL; byte *bin = NULL;
size_t binlen, outlen; size_t binlen, outlen;
size_t srclen; size_t srclen;
@@ -199,7 +199,7 @@ byte *pcp_z85_decode(char *z85block, size_t *dstlen) {
bin = ucmalloc(binlen); bin = ucmalloc(binlen);
if(zmq_z85_decode(bin, z85block) == NULL) { if(zmq_z85_decode(bin, z85block) == NULL) {
fatal("zmq_z85_decode() failed, input size ! mod 5 (got %ld)", strlen(z85block)); fatal(ptx, "zmq_z85_decode() failed, input size ! mod 5 (got %ld)", strlen(z85block));
return NULL; return NULL;
} }
@@ -251,7 +251,7 @@ char *pcp_z85_encode(byte *raw, size_t srclen, size_t *dstlen) {
} }
char *pcp_readz85file(FILE *infile) { char *pcp_readz85file(PCPCTX *ptx, FILE *infile) {
byte *input = NULL; byte *input = NULL;
byte *tmp = NULL; byte *tmp = NULL;
size_t bufsize = 0; size_t bufsize = 0;
@@ -269,25 +269,25 @@ char *pcp_readz85file(FILE *infile) {
} }
if(bufsize == 0) { if(bufsize == 0) {
fatal("Input file is empty!\n"); fatal(ptx, "Input file is empty!\n");
free(tmp); free(tmp);
return NULL; return NULL;
} }
return pcp_readz85string(input, bufsize); return pcp_readz85string(ptx, input, bufsize);
} }
char *pcp_readz85string(unsigned char *input, size_t bufsize) { char *pcp_readz85string(PCPCTX *ptx, unsigned char *input, size_t bufsize) {
size_t i; size_t i;
size_t MAXLINE = 1024; size_t MAXLINE = 1024;
if(bufsize == 0) { if(bufsize == 0) {
fatal("Input file is empty!\n"); fatal(ptx, "Input file is empty!\n");
return NULL; return NULL;
} }
if(_buffer_is_binary(input, bufsize) > 0) { if(_buffer_is_binary(input, bufsize) > 0) {
fatal("input is not z85 encoded and contains pure binary data"); fatal(ptx, "input is not z85 encoded and contains pure binary data");
return NULL; return NULL;
} }
@@ -339,7 +339,7 @@ char *pcp_readz85string(unsigned char *input, size_t bufsize) {
} }
if(buffer_size(z) == 0) { if(buffer_size(z) == 0) {
fatal("empty z85 encoded string"); fatal(ptx, "empty z85 encoded string");
goto rferr; goto rferr;
} }

View File

@@ -34,7 +34,7 @@ int pcpdecrypt(char *id, int useid, char *infile, char *outfile, char *passwd, i
in = stdin; in = stdin;
else { else {
if((in = fopen(infile, "rb")) == NULL) { if((in = fopen(infile, "rb")) == NULL) {
fatal("Could not open input file %s\n", infile); fatal(ptx, "Could not open input file %s\n", infile);
goto errde3; goto errde3;
} }
} }
@@ -43,7 +43,7 @@ int pcpdecrypt(char *id, int useid, char *infile, char *outfile, char *passwd, i
out = stdout; out = stdout;
else { else {
if((out = fopen(outfile, "wb+")) == NULL) { if((out = fopen(outfile, "wb+")) == NULL) {
fatal("Could not open output file %s\n", outfile); fatal(ptx, "Could not open output file %s\n", outfile);
goto errde3; goto errde3;
} }
} }
@@ -73,15 +73,15 @@ int pcpdecrypt(char *id, int useid, char *infile, char *outfile, char *passwd, i
strncpy(passphrase, passwd, strlen(passwd)); strncpy(passphrase, passwd, strlen(passwd));
} }
symkey = pcp_scrypt(passphrase, strlen(passphrase), salt, 90); symkey = pcp_scrypt(ptx, passphrase, strlen(passphrase), salt, 90);
free(salt); free(salt);
} }
else { else {
/* asymetric mode */ /* asymetric mode */
if(useid) { if(useid) {
HASH_FIND_STR(pcpkey_hash, id, secret); secret = pcphash_keyexists(ptx, id);
if(secret == NULL) { if(secret == NULL) {
fatal("Could not find a secret key with id 0x%s in vault %s!\n", fatal(ptx, "Could not find a secret key with id 0x%s in vault %s!\n",
id, vault->filename); id, vault->filename);
goto errde3; goto errde3;
} }
@@ -89,7 +89,7 @@ int pcpdecrypt(char *id, int useid, char *infile, char *outfile, char *passwd, i
else { else {
secret = pcp_find_primary_secret(); secret = pcp_find_primary_secret();
if(secret == NULL) { if(secret == NULL) {
fatal("Could not find a secret key in vault %s!\n", id, vault->filename); fatal(ptx, "Could not find a secret key in vault %s!\n", id, vault->filename);
goto errde3; goto errde3;
} }
} }
@@ -105,21 +105,21 @@ int pcpdecrypt(char *id, int useid, char *infile, char *outfile, char *passwd, i
strncpy(passphrase, passwd, strlen(passwd)+1); strncpy(passphrase, passwd, strlen(passwd)+1);
} }
secret = pcpkey_decrypt(secret, passphrase); secret = pcpkey_decrypt(ptx, secret, passphrase);
if(secret == NULL) if(secret == NULL)
goto errde3; goto errde3;
} }
} }
} }
else { else {
fatal("Could not determine input file type\n"); fatal(ptx, "Could not determine input file type\n");
goto errde3; goto errde3;
} }
if(symkey == NULL) if(symkey == NULL)
dlen = pcp_decrypt_stream(pin, pout, secret, NULL, verify); dlen = pcp_decrypt_stream(ptx, pin, pout, secret, NULL, verify);
else else
dlen = pcp_decrypt_stream(pin, pout, NULL, symkey, verify); dlen = pcp_decrypt_stream(ptx, pin, pout, NULL, symkey, verify);
ps_close(pin); ps_close(pin);
ps_close(pout); ps_close(pout);
@@ -164,23 +164,22 @@ int pcpencrypt(char *id, char *infile, char *outfile, char *passwd, plist_t *rec
byte *salt = ucmalloc(90); /* FIXME: use random salt, concat it with result afterwards */ byte *salt = ucmalloc(90); /* FIXME: use random salt, concat it with result afterwards */
char stsalt[] = PBP_COMPAT_SALT; char stsalt[] = PBP_COMPAT_SALT;
memcpy(salt, stsalt, 90); memcpy(salt, stsalt, 90);
symkey = pcp_scrypt(passphrase, strlen(passphrase), salt, 90); symkey = pcp_scrypt(ptx, passphrase, strlen(passphrase), salt, 90);
free(salt); free(salt);
} }
else if(id != NULL && recipient == NULL) { else if(id != NULL && recipient == NULL) {
/* lookup by id */ /* lookup by id */
HASH_FIND_STR(pcppubkey_hash, id, tmp); tmp = pcphash_pubkeyexists(ptx, id);
if(tmp == NULL) { if(tmp == NULL) {
/* self-encryption: look if its a secret one */ /* self-encryption: look if its a secret one */
pcp_key_t *s = NULL; pcp_key_t *s = pcphash_keyexists(ptx, id);
HASH_FIND_STR(pcpkey_hash, id, s);
if(s != NULL) { if(s != NULL) {
tmp = pcpkey_pub_from_secret(s); tmp = pcpkey_pub_from_secret(s);
HASH_ADD_STR( pubhash, id, tmp); HASH_ADD_STR( pubhash, id, tmp);
self = 1; self = 1;
} }
else { else {
fatal("Could not find a public key with id 0x%s in vault %s!\n", fatal(ptx, "Could not find a public key with id 0x%s in vault %s!\n",
id, vault->filename); id, vault->filename);
goto erren3; goto erren3;
} }
@@ -197,7 +196,7 @@ int pcpencrypt(char *id, char *infile, char *outfile, char *passwd, plist_t *rec
/* iterate through global hashlist */ /* iterate through global hashlist */
/* copy matches into temporary pubhash */ /* copy matches into temporary pubhash */
plist_t *rec; plist_t *rec;
pcphash_iteratepub(tmp) { pcphash_iteratepub(ptx, tmp) {
rec = recipient->first; rec = recipient->first;
while (rec != NULL) { while (rec != NULL) {
_lc(rec->value); _lc(rec->value);
@@ -211,7 +210,7 @@ int pcpencrypt(char *id, char *infile, char *outfile, char *passwd, plist_t *rec
} }
} }
if(HASH_COUNT(pubhash) == 0) { if(HASH_COUNT(pubhash) == 0) {
fatal("no matching key found for specified recipient(s)!\n"); fatal(ptx, "no matching key found for specified recipient(s)!\n");
goto erren3; goto erren3;
} }
} }
@@ -224,7 +223,7 @@ int pcpencrypt(char *id, char *infile, char *outfile, char *passwd, plist_t *rec
#else #else
secret = pcp_find_primary_secret(); secret = pcp_find_primary_secret();
if(secret == NULL) { if(secret == NULL) {
fatal("Could not find a secret key in vault %s!\n", id, vault->filename); fatal(ptx, "Could not find a secret key in vault %s!\n", id, vault->filename);
goto erren2; goto erren2;
} }
@@ -239,7 +238,7 @@ int pcpencrypt(char *id, char *infile, char *outfile, char *passwd, plist_t *rec
passphrase = ucmalloc(strlen(passwd)+1); passphrase = ucmalloc(strlen(passwd)+1);
strncpy(passphrase, passwd, strlen(passwd)+1); strncpy(passphrase, passwd, strlen(passwd)+1);
} }
secret = pcpkey_decrypt(secret, passphrase); secret = pcpkey_decrypt(ptx, secret, passphrase);
if(secret == NULL) if(secret == NULL)
goto erren2; goto erren2;
} }
@@ -250,7 +249,7 @@ int pcpencrypt(char *id, char *infile, char *outfile, char *passwd, plist_t *rec
in = stdin; in = stdin;
else { else {
if((in = fopen(infile, "rb")) == NULL) { if((in = fopen(infile, "rb")) == NULL) {
fatal("Could not open input file %s\n", infile); fatal(ptx, "Could not open input file %s\n", infile);
goto erren2; goto erren2;
} }
} }
@@ -259,7 +258,7 @@ int pcpencrypt(char *id, char *infile, char *outfile, char *passwd, plist_t *rec
out = stdout; out = stdout;
else { else {
if((out = fopen(outfile, "wb+")) == NULL) { if((out = fopen(outfile, "wb+")) == NULL) {
fatal("Could not open output file %s\n", outfile); fatal(ptx, "Could not open output file %s\n", outfile);
goto erren2; goto erren2;
} }
} }
@@ -275,9 +274,9 @@ int pcpencrypt(char *id, char *infile, char *outfile, char *passwd, plist_t *rec
} }
if(self == 1) if(self == 1)
clen = pcp_encrypt_stream_sym(pin, pout, symkey, 0, NULL); clen = pcp_encrypt_stream_sym(ptx, pin, pout, symkey, 0, NULL);
else else
clen = pcp_encrypt_stream(pin, pout, secret, pubhash, signcrypt); clen = pcp_encrypt_stream(ptx, pin, pout, secret, pubhash, signcrypt);
if(armor == 1) { if(armor == 1) {
ps_finish(pout); ps_finish(pout);
@@ -296,11 +295,10 @@ int pcpencrypt(char *id, char *infile, char *outfile, char *passwd, plist_t *rec
fprintf(stderr, "Encrypted %"FMT_SIZE_T" bytes for 0x%s successfully\n", (SIZE_T_CAST)clen, id); fprintf(stderr, "Encrypted %"FMT_SIZE_T" bytes for 0x%s successfully\n", (SIZE_T_CAST)clen, id);
else { else {
fprintf(stderr, "Encrypted %"FMT_SIZE_T" bytes for:\n", (SIZE_T_CAST)clen); fprintf(stderr, "Encrypted %"FMT_SIZE_T" bytes for:\n", (SIZE_T_CAST)clen);
pcp_pubkey_t *cur, *t; pcp_pubkey_t *cur;
HASH_ITER(hh, pubhash, cur, t) { pcphash_iteratepub(ptx, cur) {
fprintf(stderr, "%s <%s>\n", cur->owner, cur->mail); fprintf(stderr, "%s <%s>\n", cur->owner, cur->mail);
} }
free(t);
free(cur); free(cur);
} }
if(signcrypt) if(signcrypt)

View File

@@ -36,6 +36,7 @@
#include "keyhash.h" #include "keyhash.h"
#include "plist.h" #include "plist.h"
#include "pcpstream.h" #include "pcpstream.h"
#include "context.h"
int pcpdecrypt(char *id, int useid, char *infile, char *outfile, char *passwd, int verify); int pcpdecrypt(char *id, int useid, char *infile, char *outfile, char *passwd, int verify);
int pcpencrypt(char *id, char *infile, char *outfile, char *passwd, plist_t *recipient, int signcrypt, int armor); int pcpencrypt(char *id, char *infile, char *outfile, char *passwd, plist_t *recipient, int signcrypt, int armor);

View File

@@ -30,14 +30,14 @@ char *pcp_getstdin(const char *prompt) {
fprintf(stderr, "%s: ", prompt); fprintf(stderr, "%s: ", prompt);
if (fgets(line, 255, stdin) == NULL) { if (fgets(line, 255, stdin) == NULL) {
fatal("Cannot read from stdin"); fatal(ptx, "Cannot read from stdin");
goto errgst; goto errgst;
} }
line[strcspn(line, "\r\n")] = '\0'; line[strcspn(line, "\r\n")] = '\0';
if ((out = strdup(line)) == NULL) { if ((out = strdup(line)) == NULL) {
fatal("Cannot allocate memory"); fatal(ptx, "Cannot allocate memory");
goto errgst; goto errgst;
} }
@@ -48,11 +48,11 @@ char *pcp_getstdin(const char *prompt) {
} }
int pcp_storekey (pcp_key_t *key) { int pcp_storekey (pcp_key_t *key) {
if(vault->isnew == 1 || HASH_COUNT(pcpkey_hash) == 0) { if(vault->isnew == 1 || pcphash_count(ptx) == 0) {
key->type = PCP_KEY_TYPE_MAINSECRET; key->type = PCP_KEY_TYPE_MAINSECRET;
} }
if(pcpvault_addkey(vault, key, key->type) == 0) { if(pcpvault_addkey(ptx, vault, key, key->type) == 0) {
if(vault->isnew) if(vault->isnew)
fprintf(stderr, "new vault created, "); fprintf(stderr, "new vault created, ");
fprintf(stderr, "key 0x%s added to %s.\n", key->id, vault->filename); fprintf(stderr, "key 0x%s added to %s.\n", key->id, vault->filename);
@@ -87,7 +87,7 @@ void pcp_keygen(char *passwd) {
} }
if(strnlen(passphrase, 1024) > 0) if(strnlen(passphrase, 1024) > 0)
key = pcpkey_encrypt(k, passphrase); key = pcpkey_encrypt(ptx, k, passphrase);
else { else {
char *yes = pcp_getstdin("WARNING: secret key will be stored unencrypted. Are you sure [yes|NO]?"); char *yes = pcp_getstdin("WARNING: secret key will be stored unencrypted. Are you sure [yes|NO]?");
if(strncmp(yes, "yes", 1024) == 0) if(strncmp(yes, "yes", 1024) == 0)
@@ -117,22 +117,22 @@ void pcp_keygen(char *passwd) {
void pcp_listkeys() { void pcp_listkeys() {
pcp_key_t *k; pcp_key_t *k;
int nkeys = HASH_COUNT(pcpkey_hash) + HASH_COUNT(pcppubkey_hash); int nkeys = pcphash_count(ptx) + pcphash_countpub(ptx);
if(nkeys > 0) { if(nkeys > 0) {
printf("Key ID Type Creation Time Owner\n"); printf("Key ID Type Creation Time Owner\n");
pcphash_iterate(k) { pcphash_iterate(ptx, k) {
pcpkey_printlineinfo(k); pcpkey_printlineinfo(k);
} }
pcp_pubkey_t *p; pcp_pubkey_t *p;
pcphash_iteratepub(p) { pcphash_iteratepub(ptx, p) {
pcppubkey_printlineinfo(p); pcppubkey_printlineinfo(p);
} }
} }
else { else {
fatal("The key vault file %s doesn't contain any keys so far.\n", vault->filename); fatal(ptx, "The key vault file %s doesn't contain any keys so far.\n", vault->filename);
} }
} }
@@ -145,12 +145,12 @@ char *pcp_normalize_id(char *keyid) {
memcpy(id, keyid, 17); memcpy(id, keyid, 17);
} }
else if(len < 16) { else if(len < 16) {
fatal("Specified key id %s is too short!\n", keyid); fatal(ptx, "Specified key id %s is too short!\n", keyid);
free(id); free(id);
return NULL; return NULL;
} }
else if(len > 18) { else if(len > 18) {
fatal("Specified key id %s is too long!\n", keyid); fatal(ptx, "Specified key id %s is too long!\n", keyid);
free(id); free(id);
return NULL; return NULL;
} }
@@ -163,7 +163,7 @@ char *pcp_normalize_id(char *keyid) {
id[16] = 0; id[16] = 0;
} }
else { else {
fatal("Specified key id %s is too long!\n", keyid); fatal(ptx, "Specified key id %s is too long!\n", keyid);
free(id); free(id);
return NULL; return NULL;
} }
@@ -175,7 +175,7 @@ char *pcp_normalize_id(char *keyid) {
pcp_key_t *pcp_find_primary_secret() { pcp_key_t *pcp_find_primary_secret() {
pcp_key_t *key = NULL; pcp_key_t *key = NULL;
pcp_key_t *k; pcp_key_t *k;
pcphash_iterate(k) { pcphash_iterate(ptx, k) {
if(k->type == PCP_KEY_TYPE_MAINSECRET) { if(k->type == PCP_KEY_TYPE_MAINSECRET) {
key = ucmalloc(sizeof(pcp_key_t)); key = ucmalloc(sizeof(pcp_key_t));
memcpy(key, k, sizeof(pcp_key_t)); memcpy(key, k, sizeof(pcp_key_t));
@@ -184,9 +184,9 @@ pcp_key_t *pcp_find_primary_secret() {
} }
/* no primary? whoops */ /* no primary? whoops */
int nkeys = HASH_COUNT(pcpkey_hash); int nkeys = pcphash_count(ptx);
if(nkeys == 1) { if(nkeys == 1) {
pcphash_iterate(k) { pcphash_iterate(ptx, k) {
key = ucmalloc(sizeof(pcp_key_t)); key = ucmalloc(sizeof(pcp_key_t));
memcpy(key, k, sizeof(pcp_key_t)); memcpy(key, k, sizeof(pcp_key_t));
return key; return key;
@@ -201,9 +201,9 @@ void pcp_exportsecret(char *keyid, int useid, char *outfile, int armor, char *pa
if(useid == 1) { if(useid == 1) {
/* look if we've got that one */ /* look if we've got that one */
HASH_FIND_STR(pcpkey_hash, keyid, key); key = pcphash_keyexists(ptx, keyid);
if(key == NULL) { if(key == NULL) {
fatal("Could not find a secret key with id 0x%s in vault %s!\n", keyid, vault->filename); fatal(ptx, "Could not find a secret key with id 0x%s in vault %s!\n", keyid, vault->filename);
goto errexpse1; goto errexpse1;
} }
} }
@@ -211,7 +211,7 @@ void pcp_exportsecret(char *keyid, int useid, char *outfile, int armor, char *pa
/* look for our primary key */ /* look for our primary key */
key = pcp_find_primary_secret(); key = pcp_find_primary_secret();
if(key == NULL) { if(key == NULL) {
fatal("There's no primary secret key in the vault %s!\n", vault->filename); fatal(ptx, "There's no primary secret key in the vault %s!\n", vault->filename);
goto errexpse1; goto errexpse1;
} }
} }
@@ -222,7 +222,7 @@ void pcp_exportsecret(char *keyid, int useid, char *outfile, int armor, char *pa
} }
else { else {
if((out = fopen(outfile, "wb+")) == NULL) { if((out = fopen(outfile, "wb+")) == NULL) {
fatal("Could not create output file %s", outfile); fatal(ptx, "Could not create output file %s", outfile);
goto errexpse1; goto errexpse1;
} }
} }
@@ -237,7 +237,7 @@ void pcp_exportsecret(char *keyid, int useid, char *outfile, int armor, char *pa
char *passphrase; char *passphrase;
pcp_readpass(&passphrase, pcp_readpass(&passphrase,
"Enter passphrase to decrypt your secret key", NULL, 1); "Enter passphrase to decrypt your secret key", NULL, 1);
key = pcpkey_decrypt(key, passphrase); key = pcpkey_decrypt(ptx, key, passphrase);
if(key == NULL) { if(key == NULL) {
memset(passphrase, 0, strlen(passphrase)); memset(passphrase, 0, strlen(passphrase));
free(passphrase); free(passphrase);
@@ -247,7 +247,7 @@ void pcp_exportsecret(char *keyid, int useid, char *outfile, int armor, char *pa
free(passphrase); free(passphrase);
} }
else { else {
key = pcpkey_decrypt(key, passwd); key = pcpkey_decrypt(ptx, key, passwd);
if(key == NULL) { if(key == NULL) {
goto errexpse1; goto errexpse1;
} }
@@ -257,13 +257,13 @@ void pcp_exportsecret(char *keyid, int useid, char *outfile, int armor, char *pa
Buffer *exported_sk; Buffer *exported_sk;
if(passwd != NULL) { if(passwd != NULL) {
exported_sk = pcp_export_secret(key, passwd); exported_sk = pcp_export_secret(ptx, key, passwd);
} }
else { else {
char *passphrase; char *passphrase;
pcp_readpass(&passphrase, pcp_readpass(&passphrase,
"Enter passphrase to encrypt the exported secret key", "Repeat passphrase", 1); "Enter passphrase to encrypt the exported secret key", "Repeat passphrase", 1);
exported_sk = pcp_export_secret(key, passphrase); exported_sk = pcp_export_secret(ptx, key, passphrase);
memset(passphrase, 0, strlen(passphrase)); memset(passphrase, 0, strlen(passphrase));
free(passphrase); free(passphrase);
} }
@@ -307,19 +307,19 @@ void pcp_exportpublic(char *keyid, char *passwd, char *outfile, int format, int
} }
else { else {
if((out = fopen(outfile, "wb+")) == NULL) { if((out = fopen(outfile, "wb+")) == NULL) {
fatal("Could not create output file %s", outfile); fatal(ptx, "Could not create output file %s", outfile);
goto errpcpexpu1; goto errpcpexpu1;
} }
} }
if(keyid != NULL) { if(keyid != NULL) {
/* keyid specified, check if it exists and if yes, what type it is */ /* keyid specified, check if it exists and if yes, what type it is */
HASH_FIND_STR(pcppubkey_hash, keyid, pk); pk = pcphash_pubkeyexists(ptx, keyid);
if(pk == NULL) { if(pk == NULL) {
/* ok, so, then look for a secret key with that id */ /* ok, so, then look for a secret key with that id */
HASH_FIND_STR(pcpkey_hash, keyid, sk); sk = pcphash_keyexists(ptx, keyid);
if(sk == NULL) { if(sk == NULL) {
fatal("Could not find a key with id 0x%s in vault %s!\n", fatal(ptx, "Could not find a key with id 0x%s in vault %s!\n",
keyid, vault->filename); keyid, vault->filename);
goto errpcpexpu1; goto errpcpexpu1;
} }
@@ -337,7 +337,7 @@ void pcp_exportpublic(char *keyid, char *passwd, char *outfile, int format, int
/* we use our primary key anyway */ /* we use our primary key anyway */
sk = pcp_find_primary_secret(); sk = pcp_find_primary_secret();
if(sk == NULL) { if(sk == NULL) {
fatal("There's no primary secret key in the vault %s!\n", vault->filename); fatal(ptx, "There's no primary secret key in the vault %s!\n", vault->filename);
goto errpcpexpu1; goto errpcpexpu1;
} }
is_foreign = 0; is_foreign = 0;
@@ -347,13 +347,13 @@ void pcp_exportpublic(char *keyid, char *passwd, char *outfile, int format, int
if(is_foreign == 0 && sk->secret[0] == 0 && format <= EXP_FORMAT_PBP) { if(is_foreign == 0 && sk->secret[0] == 0 && format <= EXP_FORMAT_PBP) {
/* decrypt the secret key */ /* decrypt the secret key */
if(passwd != NULL) { if(passwd != NULL) {
sk = pcpkey_decrypt(sk, passwd); sk = pcpkey_decrypt(ptx, sk, passwd);
} }
else { else {
char *passphrase; char *passphrase;
pcp_readpass(&passphrase, pcp_readpass(&passphrase,
"Enter passphrase to decrypt your secret key", NULL, 1); "Enter passphrase to decrypt your secret key", NULL, 1);
sk = pcpkey_decrypt(sk, passphrase); sk = pcpkey_decrypt(ptx, sk, passphrase);
memset(passphrase, 0, strlen(passphrase)); memset(passphrase, 0, strlen(passphrase));
free(passphrase); free(passphrase);
} }
@@ -381,7 +381,7 @@ void pcp_exportpublic(char *keyid, char *passwd, char *outfile, int format, int
} }
else { else {
/* FIXME: export foreign keys unsupported yet */ /* FIXME: export foreign keys unsupported yet */
fatal("Exporting foreign public keys in native format unsupported yet"); fatal(ptx, "Exporting foreign public keys in native format unsupported yet");
goto errpcpexpu1; goto errpcpexpu1;
} }
} }
@@ -399,7 +399,7 @@ void pcp_exportpublic(char *keyid, char *passwd, char *outfile, int format, int
} }
} }
else { else {
fatal("Exporting foreign public keys in PBP format not possible"); fatal(ptx, "Exporting foreign public keys in PBP format not possible");
goto errpcpexpu1; goto errpcpexpu1;
} }
} }
@@ -429,38 +429,38 @@ void pcp_exportpublic(char *keyid, char *passwd, char *outfile, int format, int
void pcpdelete_key(char *keyid) { void pcpdelete_key(char *keyid) {
pcp_pubkey_t *p = pcphash_pubkeyexists(keyid); pcp_pubkey_t *p = pcphash_pubkeyexists(ptx, keyid);
if(p != NULL) { if(p != NULL) {
/* delete public */ /* delete public */
HASH_DEL(pcppubkey_hash, p); pcphash_del(ptx, p, p->type);
free(p); free(p);
vault->unsafed = 1; vault->unsafed = 1;
fprintf(stderr, "Public key deleted.\n"); fprintf(stderr, "Public key deleted.\n");
} }
else { else {
pcp_key_t *s = pcphash_keyexists(keyid); pcp_key_t *s = pcphash_keyexists(ptx, keyid);
if(s != NULL) { if(s != NULL) {
/* delete secret */ /* delete secret */
HASH_DEL(pcpkey_hash, s); pcphash_del(ptx, s, s->type);
free(s); free(s);
vault->unsafed = 1; vault->unsafed = 1;
fprintf(stderr, "Secret key deleted.\n"); fprintf(stderr, "Secret key deleted.\n");
} }
else { else {
fatal("No key with id 0x%s found!\n", keyid); fatal(ptx, "No key with id 0x%s found!\n", keyid);
} }
} }
} }
void pcpedit_key(char *keyid) { void pcpedit_key(char *keyid) {
pcp_key_t *key = pcphash_keyexists(keyid); pcp_key_t *key = pcphash_keyexists(ptx, keyid);
if(key != NULL) { if(key != NULL) {
if(key->secret[0] == 0) { if(key->secret[0] == 0) {
char *passphrase; char *passphrase;
pcp_readpass(&passphrase, "Enter passphrase to decrypt the key", NULL, 1); pcp_readpass(&passphrase, "Enter passphrase to decrypt the key", NULL, 1);
key = pcpkey_decrypt(key, passphrase); key = pcpkey_decrypt(ptx, key, passphrase);
ucfree(passphrase, strlen(passphrase)); ucfree(passphrase, strlen(passphrase));
} }
@@ -481,7 +481,7 @@ void pcpedit_key(char *keyid) {
if(key->type != PCP_KEY_TYPE_MAINSECRET) { if(key->type != PCP_KEY_TYPE_MAINSECRET) {
pcp_key_t *other = NULL; pcp_key_t *other = NULL;
uint8_t haveprimary = 0; uint8_t haveprimary = 0;
pcphash_iterate(other) { pcphash_iterate(ptx, other) {
if(other->type == PCP_KEY_TYPE_MAINSECRET) { if(other->type == PCP_KEY_TYPE_MAINSECRET) {
haveprimary = 1; haveprimary = 1;
break; break;
@@ -515,7 +515,7 @@ void pcpedit_key(char *keyid) {
"Enter the passphrase again", 1); "Enter the passphrase again", 1);
if(strnlen(passphrase, 1024) > 0) { if(strnlen(passphrase, 1024) > 0) {
key = pcpkey_encrypt(key, passphrase); key = pcpkey_encrypt(ptx, key, passphrase);
ucfree(passphrase, strlen(passphrase)); ucfree(passphrase, strlen(passphrase));
} }
@@ -529,7 +529,7 @@ void pcpedit_key(char *keyid) {
} }
} }
else { else {
fatal("No key with id 0x%s found!\n", keyid); fatal(ptx, "No key with id 0x%s found!\n", keyid);
} }
} }
@@ -538,7 +538,7 @@ char *pcp_find_id_byrec(char *recipient) {
pcp_pubkey_t *p; pcp_pubkey_t *p;
char *id = NULL; char *id = NULL;
_lc(recipient); _lc(recipient);
pcphash_iteratepub(p) { pcphash_iteratepub(ptx, p) {
if(strncmp(p->owner, recipient, 255) == 0) { if(strncmp(p->owner, recipient, 255) == 0) {
id = ucmalloc(17); id = ucmalloc(17);
strncpy(id, p->id, 17); strncpy(id, p->id, 17);
@@ -569,12 +569,12 @@ int pcp_import (vault_t *vault, FILE *in, char *passwd) {
bufsize = ps_read(pin, buf, PCP_BLOCK_SIZE); bufsize = ps_read(pin, buf, PCP_BLOCK_SIZE);
if(bufsize == 0) { if(bufsize == 0) {
fatal("Input file is empty!\n"); fatal(ptx, "Input file is empty!\n");
goto errimp1; goto errimp1;
} }
/* first try as rfc pub key */ /* first try as rfc pub key */
bundle = pcp_import_binpub(buf, bufsize); bundle = pcp_import_binpub(ptx, buf, bufsize);
if(bundle != NULL) { if(bundle != NULL) {
keysig = bundle->s; keysig = bundle->s;
pub = bundle->p; pub = bundle->p;
@@ -583,7 +583,7 @@ int pcp_import (vault_t *vault, FILE *in, char *passwd) {
pcp_dumppubkey(pub); pcp_dumppubkey(pub);
if(keysig == NULL) { if(keysig == NULL) {
fatals_ifany(); fatals_ifany(ptx);
char *yes = pcp_getstdin("WARNING: signature doesn't verify, import anyway [yes|NO]?"); char *yes = pcp_getstdin("WARNING: signature doesn't verify, import anyway [yes|NO]?");
if(strncmp(yes, "yes", 1024) != 0) { if(strncmp(yes, "yes", 1024) != 0) {
free(yes); free(yes);
@@ -592,8 +592,8 @@ int pcp_import (vault_t *vault, FILE *in, char *passwd) {
free(yes); free(yes);
} }
if(pcp_sanitycheck_pub(pub) == 0) { if(pcp_sanitycheck_pub(ptx, pub) == 0) {
if(pcpvault_addkey(vault, (void *)pub, PCP_KEY_TYPE_PUBLIC) == 0) { if(pcpvault_addkey(ptx, vault, (void *)pub, PCP_KEY_TYPE_PUBLIC) == 0) {
fprintf(stderr, "key 0x%s added to %s.\n", pub->id, vault->filename); fprintf(stderr, "key 0x%s added to %s.\n", pub->id, vault->filename);
/* avoid double free */ /* avoid double free */
pub = NULL; pub = NULL;
@@ -603,7 +603,7 @@ int pcp_import (vault_t *vault, FILE *in, char *passwd) {
goto errimp2; goto errimp2;
if(keysig != NULL) { if(keysig != NULL) {
if(pcpvault_addkey(vault, keysig, keysig->type) != 0) { if(pcpvault_addkey(ptx, vault, keysig, keysig->type) != 0) {
/* FIXME: remove pubkey if storing the keysig failed */ /* FIXME: remove pubkey if storing the keysig failed */
goto errimp2; goto errimp2;
} }
@@ -616,13 +616,13 @@ int pcp_import (vault_t *vault, FILE *in, char *passwd) {
else { else {
/* it's not public key, so let's try to interpret it as secret key */ /* it's not public key, so let's try to interpret it as secret key */
if(passwd != NULL) { if(passwd != NULL) {
sk = pcp_import_secret(buf, bufsize, passwd); sk = pcp_import_secret(ptx, buf, bufsize, passwd);
} }
else { else {
char *passphrase; char *passphrase;
pcp_readpass(&passphrase, pcp_readpass(&passphrase,
"Enter passphrase to decrypt the secret key file", NULL, 1); "Enter passphrase to decrypt the secret key file", NULL, 1);
sk = pcp_import_secret(buf, bufsize, passphrase); sk = pcp_import_secret(ptx, buf, bufsize, passphrase);
ucfree(passphrase, strlen(passphrase)); ucfree(passphrase, strlen(passphrase));
} }
@@ -633,15 +633,15 @@ int pcp_import (vault_t *vault, FILE *in, char *passwd) {
if(debug) if(debug)
pcp_dumpkey(sk); pcp_dumpkey(sk);
pcp_key_t *maybe = pcphash_keyexists(sk->id); pcp_key_t *maybe = pcphash_keyexists(ptx, sk->id);
if(maybe != NULL) { if(maybe != NULL) {
fatal("Secretkey sanity check: there already exists a key with the id 0x%s\n", sk->id); fatal(ptx, "Secretkey sanity check: there already exists a key with the id 0x%s\n", sk->id);
goto errimp2; goto errimp2;
} }
/* store it */ /* store it */
if(passwd != NULL) { if(passwd != NULL) {
sk = pcpkey_encrypt(sk, passwd); sk = pcpkey_encrypt(ptx, sk, passwd);
} }
else { else {
char *passphrase; char *passphrase;
@@ -651,7 +651,7 @@ int pcp_import (vault_t *vault, FILE *in, char *passwd) {
if(strnlen(passphrase, 1024) > 0) { if(strnlen(passphrase, 1024) > 0) {
/* encrypt the key */ /* encrypt the key */
sk = pcpkey_encrypt(sk, passphrase); sk = pcpkey_encrypt(ptx, sk, passphrase);
ucfree(passphrase, strlen(passphrase)); ucfree(passphrase, strlen(passphrase));
} }
else { else {
@@ -668,7 +668,7 @@ int pcp_import (vault_t *vault, FILE *in, char *passwd) {
if(sk != NULL) { if(sk != NULL) {
/* store it to the vault if we got it til here */ /* store it to the vault if we got it til here */
if(pcp_sanitycheck_key(sk) == 0) { if(pcp_sanitycheck_key(ptx, sk) == 0) {
if(pcp_storekey(sk) == 0) { if(pcp_storekey(sk) == 0) {
pcpkey_printshortinfo(sk); pcpkey_printshortinfo(sk);
success = 0; success = 0;

View File

@@ -42,6 +42,7 @@
#include "base85.h" #include "base85.h"
#include "buffer.h" #include "buffer.h"
#include "mgmt.h" #include "mgmt.h"
#include "context.h"
#define _WITH_GETLINE #define _WITH_GETLINE

View File

@@ -28,7 +28,7 @@ int pcptext_infile(char *infile) {
int insize; int insize;
if((in = fopen(infile, "rb")) == NULL) { if((in = fopen(infile, "rb")) == NULL) {
fatal("Could not open input file %s\n", infile); fatal(ptx, "Could not open input file %s\n", infile);
goto errtinf1; goto errtinf1;
} }
@@ -42,7 +42,7 @@ int pcptext_infile(char *infile) {
} }
/* maybe a vault? */ /* maybe a vault? */
vault_t *v = pcpvault_init(infile); vault_t *v = pcpvault_init(ptx, infile);
if(v != NULL) { if(v != NULL) {
fprintf(stdout, "%s is a vault file\n", infile); fprintf(stdout, "%s is a vault file\n", infile);
pcptext_vault(v); pcptext_vault(v);
@@ -50,14 +50,14 @@ int pcptext_infile(char *infile) {
} }
/* try z85ing it */ /* try z85ing it */
char *z85 = pcp_readz85file(in); char *z85 = pcp_readz85file(ptx, in);
if(z85 == NULL) { if(z85 == NULL) {
fprintf(stdout, "Can't handle %s - unknown file type.\n", infile); fprintf(stdout, "Can't handle %s - unknown file type.\n", infile);
goto errtinf1; goto errtinf1;
} }
size_t clen; size_t clen;
byte *bin = pcp_z85_decode((char *)z85, &clen); byte *bin = pcp_z85_decode(ptx, (char *)z85, &clen);
free(z85); free(z85);
if(bin == NULL) { if(bin == NULL) {
@@ -71,31 +71,31 @@ int pcptext_infile(char *infile) {
fprintf(stdout, "%s looks Z85 encoded but otherwise unknown and is possibly encrypted.\n", infile); fprintf(stdout, "%s looks Z85 encoded but otherwise unknown and is possibly encrypted.\n", infile);
tdone: tdone:
fatals_reset(); fatals_reset(ptx);
return 0; return 0;
errtinf1: errtinf1:
fatals_reset(); fatals_reset(ptx);
return 1; return 1;
} }
void pcptext_key(char *keyid) { void pcptext_key(char *keyid) {
pcp_key_t *s = pcphash_keyexists(keyid); pcp_key_t *s = pcphash_keyexists(ptx, keyid);
if(s != NULL) { if(s != NULL) {
if(debug) if(debug)
pcp_dumpkey(s); pcp_dumpkey(s);
pcpkey_print(s, stdout); pcpkey_print(s, stdout);
} }
else { else {
pcp_pubkey_t *p = pcphash_pubkeyexists(keyid); pcp_pubkey_t *p = pcphash_pubkeyexists(ptx, keyid);
if(p != NULL) { if(p != NULL) {
if(debug) if(debug)
pcp_dumppubkey(p); pcp_dumppubkey(p);
pcppubkey_print(p, stdout); pcppubkey_print(p, stdout);
} }
else { else {
fatal("No key with id 0x%s found!\n", keyid); fatal(ptx, "No key with id 0x%s found!\n", keyid);
} }
} }
} }
@@ -113,8 +113,8 @@ void pcptext_vault(vault_t *vault) {
printf("%02X", vault->checksum[31]); printf("%02X", vault->checksum[31]);
printf("\n"); printf("\n");
printf(" Secret keys: %d\n", HASH_COUNT(pcpkey_hash)); printf(" Secret keys: %d\n", pcphash_count(ptx));
printf(" Public keys: %d\n", HASH_COUNT(pcppubkey_hash)); printf(" Public keys: %d\n", pcphash_countpub(ptx) );
} }
void pcpkey_printlineinfo(pcp_key_t *key) { void pcpkey_printlineinfo(pcp_key_t *key) {
@@ -128,7 +128,7 @@ void pcpkey_printlineinfo(pcp_key_t *key) {
c->tm_hour, c->tm_min, c->tm_sec, c->tm_hour, c->tm_min, c->tm_sec,
key->owner, key->mail); key->owner, key->mail);
if(PCPVERBOSE) { if(ptx->verbose) {
printf(" "); printf(" ");
byte *hash = pcpkey_getchecksum(key); byte *hash = pcpkey_getchecksum(key);
int i, y; int i, y;
@@ -157,7 +157,7 @@ void pcppubkey_printlineinfo(pcp_pubkey_t *key) {
c->tm_hour, c->tm_min, c->tm_sec, c->tm_hour, c->tm_min, c->tm_sec,
key->owner, key->mail); key->owner, key->mail);
if(PCPVERBOSE) { if(ptx->verbose) {
printf(" "); printf(" ");
byte *hash = pcppubkey_getchecksum(key); byte *hash = pcppubkey_getchecksum(key);
int i, y; int i, y;
@@ -171,7 +171,7 @@ void pcppubkey_printlineinfo(pcp_pubkey_t *key) {
printf("\n signed: %s, serial: %08x, version: %d, ", printf("\n signed: %s, serial: %08x, version: %d, ",
(key->valid == 1) ? "yes" : " no", (key->valid == 1) ? "yes" : " no",
key->serial, (int)key->version); key->serial, (int)key->version);
pcp_keysig_t *sig = pcphash_keysigexists(key->id); pcp_keysig_t *sig = pcphash_keysigexists(ptx, key->id);
if(sig != NULL) { if(sig != NULL) {
printf("signature fingerprint:\n "); printf("signature fingerprint:\n ");
byte *checksum = sig->checksum; byte *checksum = sig->checksum;
@@ -305,7 +305,7 @@ void pcpexport_yaml(char *outfile) {
} }
else { else {
if((out = fopen(outfile, "wb+")) == NULL) { if((out = fopen(outfile, "wb+")) == NULL) {
fatal("Could not create output file %s", outfile); fatal(ptx, "Could not create output file %s", outfile);
out = NULL; out = NULL;
} }
} }
@@ -325,7 +325,7 @@ void pcpexport_yaml(char *outfile) {
fprintf(out, "---\n"); fprintf(out, "---\n");
fprintf(out, "secret-keys:\n"); fprintf(out, "secret-keys:\n");
pcphash_iterate(s) { pcphash_iterate(ptx, s) {
fprintf(out, " -\n"); fprintf(out, " -\n");
fprintf(out, " id: %s\n", s->id); fprintf(out, " id: %s\n", s->id);
fprintf(out, " owner: %s\n", s->owner); fprintf(out, " owner: %s\n", s->owner);
@@ -350,7 +350,7 @@ void pcpexport_yaml(char *outfile) {
} }
fprintf(out, "public-keys:\n"); fprintf(out, "public-keys:\n");
pcphash_iteratepub(p) { pcphash_iteratepub(ptx, p) {
fprintf(out, " -\n"); fprintf(out, " -\n");
fprintf(out, " id: %s\n", p->id); fprintf(out, " id: %s\n", p->id);
fprintf(out, " owner: %s\n", p->owner); fprintf(out, " owner: %s\n", p->owner);

View File

@@ -30,6 +30,7 @@
#include "keymgmt.h" #include "keymgmt.h"
#include "keyhash.h" #include "keyhash.h"
#include "base85.h" #include "base85.h"
#include "context.h"
void pcpkey_print(pcp_key_t *key, FILE *out); void pcpkey_print(pcp_key_t *key, FILE *out);
void pcppubkey_print(pcp_pubkey_t *key, FILE *out); void pcppubkey_print(pcp_pubkey_t *key, FILE *out);

View File

@@ -58,7 +58,6 @@ int main (int argc, char **argv) {
plist_t *recipient = NULL; plist_t *recipient = NULL;
FILE *in; FILE *in;
PCP_EXIT = 0;
errno = 0; errno = 0;
debug = 0; debug = 0;
mode = 0; mode = 0;
@@ -71,7 +70,7 @@ int main (int argc, char **argv) {
signcrypt = 0; signcrypt = 0;
exportformat = EXP_FORMAT_NATIVE; exportformat = EXP_FORMAT_NATIVE;
PCPVERBOSE = 0; ptx = ptx_new();
static struct option longopts[] = { static struct option longopts[] = {
/* generics */ /* generics */
@@ -138,7 +137,7 @@ int main (int argc, char **argv) {
usevault = 1; usevault = 1;
break; break;
case 'L': case 'L':
PCPVERBOSE = 1; /* no break by purpose, turn on -l */ ptx->verbose = 1; /* no break by purpose, turn on -l */
case 'l': case 'l':
mode += PCP_MODE_LISTKEYS; mode += PCP_MODE_LISTKEYS;
usevault = 1; usevault = 1;
@@ -268,7 +267,7 @@ int main (int argc, char **argv) {
case '0': case '0':
version(); version();
case 'v': case 'v':
PCPVERBOSE = 1; ptx->verbose = 1;
break; break;
case 'h': case 'h':
usage(0); usage(0);
@@ -280,7 +279,6 @@ int main (int argc, char **argv) {
argc -= optind; argc -= optind;
argv += optind; argv += optind;
if(mode == 0) { if(mode == 0) {
/* turn -z|-Z into a mode if there's nothing else specified */ /* turn -z|-Z into a mode if there's nothing else specified */
if(armor == 1) { if(armor == 1) {
@@ -390,8 +388,7 @@ int main (int argc, char **argv) {
} }
if(usevault == 1) { if(usevault == 1) {
pcphash_init(); vault = pcpvault_init(ptx, vaultfile);
vault = pcpvault_init(vaultfile);
if(vault != NULL) { if(vault != NULL) {
switch (mode) { switch (mode) {
case PCP_MODE_KEYGEN: case PCP_MODE_KEYGEN:
@@ -435,7 +432,7 @@ int main (int argc, char **argv) {
in = stdin; in = stdin;
else { else {
if((in = fopen(infile, "rb")) == NULL) { if((in = fopen(infile, "rb")) == NULL) {
fatal("Could not open input file %s\n", infile); fatal(ptx, "Could not open input file %s\n", infile);
free(infile); free(infile);
break; break;
} }
@@ -452,7 +449,7 @@ int main (int argc, char **argv) {
} }
} }
else { else {
fatal("You need to specify a key id (--keyid)!\n"); fatal(ptx, "You need to specify a key id (--keyid)!\n");
} }
break; break;
@@ -465,7 +462,7 @@ int main (int argc, char **argv) {
} }
} }
else { else {
fatal("You need to specify a key id (--keyid)!\n"); fatal(ptx, "You need to specify a key id (--keyid)!\n");
} }
break; break;
@@ -481,7 +478,7 @@ int main (int argc, char **argv) {
} }
else { else {
/* -i and -r specified */ /* -i and -r specified */
fatal("You can't specify both -i and -r, use either -i or -r!\n"); fatal(ptx, "You can't specify both -i and -r, use either -i or -r!\n");
} }
if(id != NULL) if(id != NULL)
free(id); free(id);
@@ -510,7 +507,7 @@ int main (int argc, char **argv) {
case PCP_MODE_SIGN: case PCP_MODE_SIGN:
if(detach) { if(detach) {
if(outfile != NULL && sigfile != NULL) if(outfile != NULL && sigfile != NULL)
fatal("You can't both specify -O and -f, use -O for std signatures and -f for detached ones\n"); fatal(ptx, "You can't both specify -O and -f, use -O for std signatures and -f for detached ones\n");
else else
pcpsign(infile, sigfile, xpass, armor, detach); pcpsign(infile, sigfile, xpass, armor, detach);
} }
@@ -540,8 +537,7 @@ int main (int argc, char **argv) {
goto ELSEMODE; goto ELSEMODE;
break; break;
} }
pcpvault_close(vault); pcpvault_close(ptx, vault);
pcphash_clean();
free(vaultfile); free(vaultfile);
} }
} }
@@ -565,8 +561,7 @@ int main (int argc, char **argv) {
pcptext_infile(infile); pcptext_infile(infile);
} }
else { else {
pcphash_init(); vault = pcpvault_init(ptx, vaultfile);
vault = pcpvault_init(vaultfile);
if(! useid && infile == NULL) { if(! useid && infile == NULL) {
pcptext_vault(vault); pcptext_vault(vault);
} }
@@ -577,21 +572,20 @@ int main (int argc, char **argv) {
free(id); free(id);
} }
} }
pcpvault_close(vault); pcpvault_close(ptx, vault);
pcphash_clean();
free(vaultfile); free(vaultfile);
} }
break; break;
default: default:
/* mode params mixed */ /* mode params mixed */
fatal("Sorry, invalid combination of commandline parameters (0x%04X)!\n", mode); fatal(ptx, "Sorry, invalid combination of commandline parameters (0x%04X)!\n", mode);
break; break;
} }
} }
fatals_ifany(); fatals_ifany(ptx);
fatals_done(); int e = ptx->pcp_exit;
return PCP_EXIT; ptx_clean(ptx);
return e;
} }

View File

@@ -39,6 +39,7 @@
#include "z85util.h" #include "z85util.h"
#include "version.h" #include "version.h"
#include "vault.h" #include "vault.h"
#include "context.h"
/* subs */ /* subs */
#include "keymgmt.h" #include "keymgmt.h"
@@ -80,7 +81,9 @@
#define PCP_HELP_INTRO "This is Pretty Curved Privacy. Licensed under the GPLv3. This is\n" \ #define PCP_HELP_INTRO "This is Pretty Curved Privacy. Licensed under the GPLv3. This is\n" \
"BETA software. Use with care. NOT intended for production use.\n" "BETA software. Use with care. NOT intended for production use.\n"
/* some globals */
vault_t *vault; vault_t *vault;
PCPCTX *ptx;
int debug; int debug;
void version(); void version();

View File

@@ -58,13 +58,13 @@ pcp_readpass(char ** passwd, const char * prompt,
/* If we're reading from a terminal, try to disable echo. */ /* If we're reading from a terminal, try to disable echo. */
if ((usingtty = isatty(fileno(readfrom))) != 0) { if ((usingtty = isatty(fileno(readfrom))) != 0) {
if (tcgetattr(fileno(readfrom), &term_old)) { if (tcgetattr(fileno(readfrom), &term_old)) {
fatal("Cannot read terminal settings"); fatal(ptx, "Cannot read terminal settings");
goto err1; goto err1;
} }
memcpy(&term, &term_old, sizeof(struct termios)); memcpy(&term, &term_old, sizeof(struct termios));
term.c_lflag = (term.c_lflag & ~ECHO) | ECHONL; term.c_lflag = (term.c_lflag & ~ECHO) | ECHONL;
if (tcsetattr(fileno(readfrom), TCSANOW, &term)) { if (tcsetattr(fileno(readfrom), TCSANOW, &term)) {
fatal("Cannot set terminal settings"); fatal(ptx, "Cannot set terminal settings");
goto err1; goto err1;
} }
} }
@@ -76,7 +76,7 @@ retry:
/* Read the password. */ /* Read the password. */
if (fgets(passbuf, MAXPASSLEN, readfrom) == NULL) { if (fgets(passbuf, MAXPASSLEN, readfrom) == NULL) {
fatal("Cannot read password"); fatal(ptx, "Cannot read password");
goto err2; goto err2;
} }
@@ -85,7 +85,7 @@ retry:
if (usingtty) if (usingtty)
fprintf(stderr, "%s: ", confirmprompt); fprintf(stderr, "%s: ", confirmprompt);
if (fgets(confpassbuf, MAXPASSLEN, readfrom) == NULL) { if (fgets(confpassbuf, MAXPASSLEN, readfrom) == NULL) {
fatal("Cannot read password"); fatal(ptx, "Cannot read password");
goto err2; goto err2;
} }
if (strcmp(passbuf, confpassbuf)) { if (strcmp(passbuf, confpassbuf)) {
@@ -108,7 +108,7 @@ retry:
/* Copy the password out. */ /* Copy the password out. */
if ((*passwd = strdup(passbuf)) == NULL) { if ((*passwd = strdup(passbuf)) == NULL) {
fatal("Cannot allocate memory"); fatal(ptx, "Cannot allocate memory");
goto err1; goto err1;
} }

View File

@@ -36,6 +36,8 @@
#include <unistd.h> #include <unistd.h>
#include "defines.h" #include "defines.h"
#include "context.h"
#include "pcp.h"
#define MAXPASSLEN 2048 #define MAXPASSLEN 2048

View File

@@ -32,7 +32,7 @@ int pcpsign(char *infile, char *outfile, char *passwd, int z85, int detach) {
secret = pcp_find_primary_secret(); secret = pcp_find_primary_secret();
if(secret == NULL) { if(secret == NULL) {
fatal("Could not find a secret key in vault %s!\n", vault->filename); fatal(ptx, "Could not find a secret key in vault %s!\n", vault->filename);
goto errs1; goto errs1;
} }
@@ -40,7 +40,7 @@ int pcpsign(char *infile, char *outfile, char *passwd, int z85, int detach) {
in = stdin; in = stdin;
else { else {
if((in = fopen(infile, "rb")) == NULL) { if((in = fopen(infile, "rb")) == NULL) {
fatal("Could not open input file %s\n", infile); fatal(ptx, "Could not open input file %s\n", infile);
goto errs1; goto errs1;
} }
} }
@@ -49,7 +49,7 @@ int pcpsign(char *infile, char *outfile, char *passwd, int z85, int detach) {
out = stdout; out = stdout;
else { else {
if((out = fopen(outfile, "wb+")) == NULL) { if((out = fopen(outfile, "wb+")) == NULL) {
fatal("Could not open output file %s\n", outfile); fatal(ptx, "Could not open output file %s\n", outfile);
goto errs1; goto errs1;
} }
} }
@@ -66,7 +66,7 @@ int pcpsign(char *infile, char *outfile, char *passwd, int z85, int detach) {
strncpy(passphrase, passwd, strlen(passwd)+1); strncpy(passphrase, passwd, strlen(passwd)+1);
} }
secret = pcpkey_decrypt(secret, passphrase); secret = pcpkey_decrypt(ptx, secret, passphrase);
if(secret == NULL) if(secret == NULL)
goto errs1; goto errs1;
} }
@@ -78,7 +78,7 @@ int pcpsign(char *infile, char *outfile, char *passwd, int z85, int detach) {
if(detach == 1) if(detach == 1)
sigsize = pcp_ed_detachsign_buffered(pin, pout, secret); sigsize = pcp_ed_detachsign_buffered(pin, pout, secret);
else else
sigsize = pcp_ed_sign_buffered(pin, pout, secret, z85); sigsize = pcp_ed_sign_buffered(ptx, pin, pout, secret, z85);
ps_close(pin); ps_close(pin);
ps_close(pout); ps_close(pout);
@@ -103,30 +103,30 @@ int pcpverify(char *infile, char *sigfile, char *id, int detach) {
in = stdin; in = stdin;
else { else {
if((in = fopen(infile, "rb")) == NULL) { if((in = fopen(infile, "rb")) == NULL) {
fatal("Could not open input file %s\n", infile); fatal(ptx, "Could not open input file %s\n", infile);
goto errv1; goto errv1;
} }
} }
if(sigfile != NULL) { if(sigfile != NULL) {
if((sigfd = fopen(sigfile, "rb")) == NULL) { if((sigfd = fopen(sigfile, "rb")) == NULL) {
fatal("Could not open signature file %s\n", sigfile); fatal(ptx, "Could not open signature file %s\n", sigfile);
goto errv1; goto errv1;
} }
} }
if(id != NULL) if(id != NULL)
HASH_FIND_STR(pcppubkey_hash, id, pub); pub = pcphash_pubkeyexists(ptx, id);
Pcpstream *pin = ps_new_file(in); Pcpstream *pin = ps_new_file(in);
if(detach) { if(detach) {
Pcpstream *psigfd = ps_new_file(sigfd); Pcpstream *psigfd = ps_new_file(sigfd);
pub = pcp_ed_detachverify_buffered(pin, psigfd, pub); pub = pcp_ed_detachverify_buffered(ptx, pin, psigfd, pub);
ps_close(psigfd); ps_close(psigfd);
} }
else else
pub = pcp_ed_verify_buffered(pin, pub); pub = pcp_ed_verify_buffered(ptx, pin, pub);
ps_close(pin); ps_close(pin);

View File

@@ -32,6 +32,7 @@
#include "uthash.h" #include "uthash.h"
#include "z85.h" #include "z85.h"
#include "pcpstream.h" #include "pcpstream.h"
#include "context.h"
int pcpsign(char *infile, char *outfile, char *passwd, int z85, int detach); int pcpsign(char *infile, char *outfile, char *passwd, int z85, int detach);
int pcpverify(char *infile, char *sigfile, char *id, int detach); int pcpverify(char *infile, char *sigfile, char *id, int detach);

View File

@@ -30,7 +30,7 @@ int pcpz85_encode(char *infile, char *outfile) {
in = stdin; in = stdin;
else { else {
if((in = fopen(infile, "rb")) == NULL) { if((in = fopen(infile, "rb")) == NULL) {
fatal("Could not open input file %s\n", infile); fatal(ptx, "Could not open input file %s\n", infile);
goto errz1; goto errz1;
} }
} }
@@ -39,7 +39,7 @@ int pcpz85_encode(char *infile, char *outfile) {
out = stdout; out = stdout;
else { else {
if((out = fopen(outfile, "wb+")) == NULL) { if((out = fopen(outfile, "wb+")) == NULL) {
fatal("Could not open output file %s\n", outfile); fatal(ptx, "Could not open output file %s\n", outfile);
goto errz1; goto errz1;
} }
} }
@@ -59,7 +59,7 @@ int pcpz85_encode(char *infile, char *outfile) {
fclose(in); fclose(in);
if(inputBufSize == 0) { if(inputBufSize == 0) {
fatal("Input file is empty!\n"); fatal(ptx, "Input file is empty!\n");
goto errz2; goto errz2;
} }
@@ -69,7 +69,7 @@ int pcpz85_encode(char *infile, char *outfile) {
if(encoded != NULL) { if(encoded != NULL) {
fprintf(out, "%s\n%s\n%s\n", PCP_ZFILE_HEADER, encoded, PCP_ZFILE_FOOTER); fprintf(out, "%s\n%s\n%s\n", PCP_ZFILE_HEADER, encoded, PCP_ZFILE_FOOTER);
if(ferror(out) != 0) { if(ferror(out) != 0) {
fatal("Failed to write z85 output!\n"); fatal(ptx, "Failed to write z85 output!\n");
} }
free(encoded); free(encoded);
goto errz2; goto errz2;
@@ -95,7 +95,7 @@ int pcpz85_decode(char *infile, char *outfile) {
in = stdin; in = stdin;
else { else {
if((in = fopen(infile, "rb")) == NULL) { if((in = fopen(infile, "rb")) == NULL) {
fatal("Could not open input file %s\n", infile); fatal(ptx, "Could not open input file %s\n", infile);
goto errdz1; goto errdz1;
} }
} }
@@ -104,18 +104,18 @@ int pcpz85_decode(char *infile, char *outfile) {
out = stdout; out = stdout;
else { else {
if((out = fopen(outfile, "wb+")) == NULL) { if((out = fopen(outfile, "wb+")) == NULL) {
fatal("Could not open output file %s\n", outfile); fatal(ptx, "Could not open output file %s\n", outfile);
goto errdz1; goto errdz1;
} }
} }
char *encoded = pcp_readz85file(in); char *encoded = pcp_readz85file(ptx, in);
if(encoded == NULL) if(encoded == NULL)
goto errdz1; goto errdz1;
size_t clen; size_t clen;
byte *decoded = pcp_z85_decode(encoded, &clen); byte *decoded = pcp_z85_decode(ptx, encoded, &clen);
@@ -125,7 +125,7 @@ int pcpz85_decode(char *infile, char *outfile) {
fwrite(decoded, clen, 1, out); fwrite(decoded, clen, 1, out);
fclose(out); fclose(out);
if(ferror(out) != 0) { if(ferror(out) != 0) {
fatal("Failed to write decoded output!\n"); fatal(ptx, "Failed to write decoded output!\n");
goto errdz3; goto errdz3;
} }

View File

@@ -35,6 +35,9 @@
#include "z85.h" #include "z85.h"
#include "zmq_z85.h" #include "zmq_z85.h"
#include "defines.h" #include "defines.h"
#include "context.h"
extern PCPCTX *ptx;
int pcpz85_encode(char *infile, char *outfile); int pcpz85_encode(char *infile, char *outfile);
int pcpz85_decode(char *infile, char *outfile); int pcpz85_decode(char *infile, char *outfile);