From da9891ff81dbb8cca39983fc9c2ec47ffb4eb11e Mon Sep 17 00:00:00 2001 From: TLINDEN Date: Sun, 4 May 2014 17:11:03 +0200 Subject: [PATCH] put previously global error handling and key hashes into ptx (pcp context) to make libpcp threadsafe. --- ChangeLog | 4 + bindings/cpp/Makefile.am | 2 +- bindings/cpp/crypto++.h | 5 +- bindings/cpp/crypto.cpp | 20 +- bindings/cpp/helpers++.h | 11 +- bindings/cpp/key++.h | 23 +- bindings/cpp/key.cpp | 90 ++++---- bindings/cpp/pcp++.h | 1 + bindings/cpp/ptx++.h | 48 +++++ bindings/cpp/ptx.cpp | 34 +++ bindings/cpp/sign++.h | 9 +- bindings/cpp/sign.cpp | 36 ++-- bindings/cpp/vault++.h | 4 +- bindings/cpp/vault.cpp | 74 +++---- include/Makefile.am | 3 +- include/pcp.h | 2 + include/pcp/base85.h | 5 +- include/pcp/buffer.h | 20 +- include/pcp/context.h | 95 +++++++++ include/pcp/crypto.h | 23 +- include/pcp/defines.h | 75 +++---- include/pcp/ed.h | 21 +- include/pcp/key.h | 147 ++----------- include/pcp/keyhash.h | 83 ++++---- include/pcp/keysig.h | 11 +- include/pcp/mgmt.h | 93 ++------ include/pcp/pcpstream.h | 30 +-- include/pcp/scrypt.h | 3 +- include/pcp/structs.h | 384 ++++++++++++++++++++++++++++++++++ include/pcp/vault.h | 71 ++----- include/pcp/z85.h | 11 +- libpcp/Makefile.am | 4 +- libpcp/base85.c | 2 +- libpcp/buffer.c | 21 +- libpcp/{fatal.c => context.c} | 66 ++++-- libpcp/crypto.c | 60 +++--- libpcp/ed.c | 48 ++--- libpcp/key.c | 54 ++--- libpcp/keyhash.c | 71 +++---- libpcp/mgmt.c | 86 ++++---- libpcp/pcpstream.c | 12 +- libpcp/scrypt.c | 4 +- libpcp/vault.c | 108 +++++----- libpcp/z85.c | 18 +- src/encryption.c | 50 +++-- src/encryption.h | 1 + src/keymgmt.c | 112 +++++----- src/keymgmt.h | 1 + src/keyprint.c | 34 +-- src/keyprint.h | 1 + src/pcp.c | 40 ++-- src/pcp.h | 3 + src/readpass.c | 10 +- src/readpass.h | 2 + src/signature.c | 20 +- src/signature.h | 1 + src/z85util.c | 18 +- src/z85util.h | 3 + 58 files changed, 1330 insertions(+), 958 deletions(-) create mode 100644 bindings/cpp/ptx++.h create mode 100644 bindings/cpp/ptx.cpp create mode 100644 include/pcp/context.h create mode 100644 include/pcp/structs.h rename libpcp/{fatal.c => context.c} (56%) diff --git a/ChangeLog b/ChangeLog index 6e1d1a9..e202f68 100644 --- a/ChangeLog +++ b/ChangeLog @@ -96,6 +96,10 @@ is now determined automatically as well as the 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 separately (previously they were generated from one random seed, the curve had been derived from diff --git a/bindings/cpp/Makefile.am b/bindings/cpp/Makefile.am index 5cd5beb..09833eb 100644 --- a/bindings/cpp/Makefile.am +++ b/bindings/cpp/Makefile.am @@ -22,5 +22,5 @@ AM_CXXFLAGS = -I../../include -I../../libpcp/scrypt/crypto -I../../libpcp/scrypt 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 diff --git a/bindings/cpp/crypto++.h b/bindings/cpp/crypto++.h index 1ad505a..f9a897f 100644 --- a/bindings/cpp/crypto++.h +++ b/bindings/cpp/crypto++.h @@ -35,6 +35,7 @@ namespace pcp { class Crypto { private: + PcpContext PTX; bool havevault; public: @@ -43,8 +44,8 @@ namespace pcp { Vault vault; // constructors - Crypto(Key &skey, PubKey &pkey); - Crypto(Vault &v, Key &skey, PubKey &pkey); + Crypto(PcpContext C, Key &skey, PubKey &pkey); + Crypto(PcpContext C, Vault &v, Key &skey, PubKey &pkey); // PK encryption methods // sender pubkey is P diff --git a/bindings/cpp/crypto.cpp b/bindings/cpp/crypto.cpp index bae4e8f..784cc36 100644 --- a/bindings/cpp/crypto.cpp +++ b/bindings/cpp/crypto.cpp @@ -25,29 +25,31 @@ using namespace std; using namespace pcp; -Crypto::Crypto(Key &skey, PubKey &pkey) { +Crypto::Crypto(PcpContext C, Key &skey, PubKey &pkey) { P = pkey; S = skey; + PTX = C; havevault = false; - pcphash_init(); - pcphash_add(P.K, PCP_KEY_TYPE_PUBLIC); + pcphash_add(PTX.ptx, 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; S = skey; + PTX = C; vault = v; havevault = true; } bool Crypto::encrypt(FILE *in, FILE *out, bool sign) { 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 *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) - throw exception(); + throw exception(PTX); ps_close(pin); ps_close(pout); return true; @@ -56,8 +58,8 @@ bool Crypto::encrypt(FILE *in, FILE *out, bool sign) { bool Crypto::decrypt(FILE *in, FILE *out, bool verify) { Pcpstream *pin = ps_new_file(in); Pcpstream *pout = ps_new_file(out); - if(pcp_decrypt_stream(pin, pout, S.K, NULL, verify) <= 0) - throw exception(); + if(pcp_decrypt_stream(PTX.ptx, pin, pout, S.K, NULL, verify) <= 0) + throw exception(PTX); ps_close(pin); ps_close(pout); return true; diff --git a/bindings/cpp/helpers++.h b/bindings/cpp/helpers++.h index ccf9cad..9644396 100644 --- a/bindings/cpp/helpers++.h +++ b/bindings/cpp/helpers++.h @@ -30,14 +30,17 @@ #include #include +#include "ptx++.h" + namespace pcp { class exception : public std::runtime_error { private: + PCPCTX *ptx; std::string getfatals() { std::string msg; - if(PCP_ERRSET == 1) { - msg = PCP_ERR; + if(ptx->pcp_errset == 1) { + msg = ptx->pcp_err; } if(errno) { msg += std::string("\nError: ") @@ -47,8 +50,8 @@ namespace pcp { return msg; } public: - exception(const std::string & msg) : runtime_error(msg) { } - exception() : runtime_error(getfatals()) { } + exception(PcpContext P, const std::string & msg) : runtime_error(msg) { ptx = P.ptx; } + exception(PcpContext P) : runtime_error(getfatals()) { ptx = P.ptx; } }; diff --git a/bindings/cpp/key++.h b/bindings/cpp/key++.h index b4c7a9b..16dfbb3 100644 --- a/bindings/cpp/key++.h +++ b/bindings/cpp/key++.h @@ -30,6 +30,7 @@ #include "helpers++.h" #include "buffer++.h" +#include "ptx++.h" namespace pcp { @@ -39,12 +40,14 @@ namespace pcp { public: pcp_pubkey_t *K; + PcpContext PTX; // constructors + PubKey(PcpContext P); PubKey(); - PubKey(pcp_pubkey_t *k); - PubKey(pcp_pubkey_t *k, bool store); - PubKey(std::string &z85encoded); + PubKey(PcpContext P, pcp_pubkey_t *k); + PubKey(PcpContext P, pcp_pubkey_t *k, bool store); + PubKey(PcpContext P, std::string &z85encoded); // destructors ~PubKey(); @@ -72,17 +75,19 @@ namespace pcp { public: // make access to the underlying struct easier pcp_key_t *K; + PcpContext PTX; // constructors Key(); - Key(bool generate); - Key(const std::string& passphrase); - Key(const std::string& passphrase, + Key(PcpContext P); + Key(PcpContext P, bool generate); + Key(PcpContext P, const std::string& passphrase); + Key(PcpContext P, const std::string& passphrase, const std::string& owner, const std::string& mail); - Key(pcp_key_t *k); - Key(pcp_key_t *k, bool store); - Key(std::string &z85encoded, std::string& passphrase); + Key(PcpContext P, pcp_key_t *k); + Key(PcpContext P, pcp_key_t *k, bool store); + Key(PcpContext P, std::string &z85encoded, std::string& passphrase); // destructor ~Key(); diff --git a/bindings/cpp/key.cpp b/bindings/cpp/key.cpp index b2872a7..e2e6375 100644 --- a/bindings/cpp/key.cpp +++ b/bindings/cpp/key.cpp @@ -30,55 +30,67 @@ Key::Key() { K = NULL; } -Key::Key(bool generate) { +Key::Key(PcpContext P) { + stored = false; + K = NULL; + PTX = P; +} + +Key::Key(PcpContext P, bool generate) { stored = false; if(generate) K = pcpkey_new(); else K = NULL; + PTX = P; } -Key::Key(const string& passphrase) { +Key::Key(PcpContext P, const string& passphrase) { stored = false; 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& mail) { stored = false; 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->mail, mail.c_str(), mail.length()+1); // free(_K); + PTX = P; } -Key::Key(pcp_key_t *k) { +Key::Key(PcpContext P, pcp_key_t *k) { stored = false; 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); K = k; + PTX = P; } -Key::Key(string &z85encoded, string &passphrase) { +Key::Key(PcpContext P, string &z85encoded, string &passphrase) { stored = false; + PTX = P; 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) - throw pcp::exception(); + throw pcp::exception(PTX); - if(pcp_sanitycheck_key(key) != 0) { + if(pcp_sanitycheck_key(PTX.ptx, key) != 0) { free(key); - throw pcp::exception(); + throw pcp::exception(PTX); } K = key; @@ -99,12 +111,12 @@ string Key::export_secret(const string &passphrase) { Buffer *exported_sk; 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) - throw pcp::exception(); + throw pcp::exception(PTX); size_t 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); if(exported_pk == NULL) - throw pcp::exception(); + throw pcp::exception(PTX); size_t 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) { - K = pcpkey_encrypt(K, (char *)passphrase.c_str()); - if(PCP_ERRSET == 1) - throw exception(); + K = pcpkey_encrypt(PTX.ptx, K, (char *)passphrase.c_str()); + if(K == NULL) + throw exception(PTX); } void Key::decrypt(const string& passphrase) { - K = pcpkey_decrypt(K, (char *)passphrase.c_str()); - if(PCP_ERRSET == 1) - throw exception(); + K = pcpkey_decrypt(PTX.ptx, K, (char *)passphrase.c_str()); + if(K == NULL) + throw exception(PTX); } PubKey Key::get_public() { - return PubKey(pcpkey_pub_from_secret(K)); + return PubKey(PTX, pcpkey_pub_from_secret(K)); } string Key::get_id() { @@ -197,44 +209,52 @@ bool Key::is_encrypted() { - PubKey::PubKey() { stored = false; K = NULL; } - -PubKey::PubKey(pcp_pubkey_t *k) { +PubKey::PubKey(PcpContext P) { 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; K = k; + PTX = P; } -PubKey::PubKey(string &z85encoded) { +PubKey::PubKey(PcpContext P, string &z85encoded) { stored = false; + PTX = P; if(z85encoded.length() == 0) - throw pcp::exception("Error: zero length input"); + throw pcp::exception(PTX, "Error: zero length input"); Buf blob("pub", 256); 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) { - throw pcp::exception(); + throw pcp::exception(PTX); } 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->s); free(KS); - throw pcp::exception(); + throw pcp::exception(PTX); } K = pub; diff --git a/bindings/cpp/pcp++.h b/bindings/cpp/pcp++.h index 5463602..c026a7e 100644 --- a/bindings/cpp/pcp++.h +++ b/bindings/cpp/pcp++.h @@ -32,6 +32,7 @@ #include #include "key++.h" +#include "ptx++.h" #include "vault++.h" #include "crypto++.h" #include "sign++.h" diff --git a/bindings/cpp/ptx++.h b/bindings/cpp/ptx++.h new file mode 100644 index 0000000..88dca3b --- /dev/null +++ b/bindings/cpp/ptx++.h @@ -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 . + + You can contact me by mail: . +*/ + + +#ifndef _HAVE_PCPPP_PTX_H +#define _HAVE_PCPPP_PTX_H + +#include +#include +#include +#include + +#include "helpers++.h" + +namespace pcp { + + class PcpContext { + public: + PCPCTX *ptx; + + // constructors + PcpContext(); + + // destructors + ~PcpContext(); + }; +}; + + +#endif // _HAVE_PCPPP_PTX_H diff --git a/bindings/cpp/ptx.cpp b/bindings/cpp/ptx.cpp new file mode 100644 index 0000000..de30aa9 --- /dev/null +++ b/bindings/cpp/ptx.cpp @@ -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 . + + You can contact me by mail: . +*/ + +#include "pcp++.h" + +using namespace std; +using namespace pcp; + +PcpContext::PcpContext() { + ptx = ptx_new(); +} + +PcpContext::~PcpContext() { + ptx_clean(ptx); +} + diff --git a/bindings/cpp/sign++.h b/bindings/cpp/sign++.h index 671de12..b7a47da 100644 --- a/bindings/cpp/sign++.h +++ b/bindings/cpp/sign++.h @@ -45,12 +45,13 @@ namespace pcp { Vault vault; PubKey Signedby; Buf sig; + PcpContext PTX; // constructors - Signature(Key &skey); // sign only - Signature(PubKey &pkey); // verify only - Signature(Key &skey, PubKey &pkey); // both/bulk - Signature(Vault &v); + Signature(PcpContext P, Key &skey); // sign only + Signature(PcpContext P,PubKey &pkey); // verify only + Signature(PcpContext P,Key &skey, PubKey &pkey); // both/bulk + Signature(PcpContext P,Vault &v); // destructor ~Signature(); diff --git a/bindings/cpp/sign.cpp b/bindings/cpp/sign.cpp index a428173..b0aa2b6 100644 --- a/bindings/cpp/sign.cpp +++ b/bindings/cpp/sign.cpp @@ -24,25 +24,29 @@ using namespace std; using namespace pcp; -Signature::Signature(Key &skey) { +Signature::Signature(PcpContext P, Key &skey) { S = skey; + PTX = P; havevault = false; } -Signature::Signature(PubKey &pkey) { +Signature::Signature(PcpContext C,PubKey &pkey) { P = pkey; + PTX = C; havevault = false; } -Signature::Signature(Key &skey, PubKey &pkey) { +Signature::Signature(PcpContext C,Key &skey, PubKey &pkey) { P = pkey; S = skey; + PTX = C; havevault = false; } -Signature::Signature(Vault &v) { +Signature::Signature(PcpContext P,Vault &v) { vault = v; havevault = true; + PTX = P; S = vault.get_primary(); } @@ -51,10 +55,10 @@ Signature::~Signature() { bool Signature::sign(std::vector message) { 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()) - 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"; Buffer *m = buffer_new(32, n); @@ -68,17 +72,17 @@ bool Signature::sign(std::vector message) { buffer_free(m); if(!ok) - throw exception(); + throw exception(PTX); return true; } bool Signature::sign(unsigned char *message, size_t mlen) { 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()) - 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"; Buffer *m = buffer_new(32, n); @@ -90,7 +94,7 @@ bool Signature::sign(unsigned char *message, size_t mlen) { buffer_free(m); if(! ok) - throw exception(); + throw exception(PTX); return true; } @@ -98,7 +102,7 @@ bool Signature::sign(unsigned char *message, size_t mlen) { bool Signature::sign(Pcpstream *message) { 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) { Buffer *o = ps_buffer(out); @@ -115,7 +119,7 @@ bool Signature::sign(Pcpstream *message) { bool Signature::verify(vector message) { if(!P) { - throw exception("No public key specified, unable to verify."); + throw exception(PTX, "No public key specified, unable to verify."); } Buf _sig = Buf(); @@ -128,7 +132,7 @@ bool Signature::verify(vector message) { bool Signature::verify(unsigned char *signature, size_t mlen) { if(!P) { - throw exception("No public key specified, unable to verify."); + throw exception(PTX, "No public key specified, unable to verify."); } Buf _sig = Buf(); @@ -141,15 +145,15 @@ bool Signature::verify(unsigned char *signature, size_t mlen) { bool Signature::verify(Buf _sig) { 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); if(pub != NULL) { - Signedby = PubKey(pub); + Signedby = PubKey(PTX, pub); return true; } else { - throw exception(); + throw exception(PTX); } } diff --git a/bindings/cpp/vault++.h b/bindings/cpp/vault++.h index b7daf40..b74bcb5 100644 --- a/bindings/cpp/vault++.h +++ b/bindings/cpp/vault++.h @@ -46,11 +46,13 @@ namespace pcp { class Vault { private: vault_t *V; + PcpContext PTX; public: // constructors Vault(); - Vault(std::string filename); + Vault(PcpContext P); + Vault(PcpContext P, std::string filename); // destructor ~Vault(); diff --git a/bindings/cpp/vault.cpp b/bindings/cpp/vault.cpp index 8ed2e2d..ba5ca5a 100644 --- a/bindings/cpp/vault.cpp +++ b/bindings/cpp/vault.cpp @@ -28,24 +28,28 @@ Vault::Vault() { V = NULL; } -Vault::Vault(string filename) { - pcphash_init(); - V = pcpvault_init((char *)filename.c_str()); +Vault::Vault(PcpContext P) { + V = NULL; + PTX = P; +} + +Vault::Vault(PcpContext P, string filename) { + PTX = P; + V = pcpvault_init(PTX.ptx, (char *)filename.c_str()); if (V == NULL) - throw pcp::exception(); + throw pcp::exception(PTX); } Vault::~Vault() { - pcpvault_close(V); - pcphash_clean(); + pcpvault_close(PTX.ptx, V); } std::map Vault::keys() { std::map kmap; pcp_key_t *k = NULL; - pcphash_iterate(k) { - kmap.insert ( pair(string(k->id), Key(k, true)) ); + pcphash_iterate(PTX.ptx, k) { + kmap.insert ( pair(string(k->id), Key(PTX, k, true)) ); } return kmap; @@ -55,39 +59,39 @@ std::map Vault::pubkeys() { std::map kmap; pcp_pubkey_t *k = NULL; - pcphash_iteratepub(k) { - kmap.insert ( pair(string(k->id), PubKey(k, true)) ); + pcphash_iteratepub(PTX.ptx, k) { + kmap.insert ( pair(string(k->id), PubKey(PTX, k, true)) ); } return kmap; } int Vault::key_count() { - return pcphash_count(); + return pcphash_count(PTX.ptx); } int Vault::pubkey_count() { - return pcphash_countpub(); + return pcphash_countpub(PTX.ptx); } 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; } - if(pcpvault_addkey(V, (void *)key.K, key.K->type) != 0) - throw pcp::exception(); + if(pcpvault_addkey(PTX.ptx, V, (void *)key.K, key.K->type) != 0) + throw pcp::exception(PTX); key.is_stored(true); } void Vault::pubkey_add(PubKey &key) { - if(pcpvault_addkey(V, (void *)key.K, key.K->type) != 0) - throw pcp::exception(); + if(pcpvault_addkey(PTX.ptx, V, (void *)key.K, key.K->type) != 0) + throw pcp::exception(PTX); key.is_stored(true); } 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) return false; else @@ -95,7 +99,7 @@ bool Vault::key_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) return false; else @@ -103,63 +107,63 @@ bool Vault::pubkey_exists(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) { // delete public - HASH_DEL(pcppubkey_hash, p); + pcphash_del(PTX.ptx, p, p->type); free(p); V->unsafed = 1; } 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) { // delete secret - HASH_DEL(pcpkey_hash, s); + pcphash_del(PTX.ptx, s, s->type); free(s); V->unsafed = 1; } else { - throw exception("Key not found!\n"); + throw exception(PTX, "Key not found!\n"); } } } Key Vault::get_primary() { pcp_key_t *k = NULL; - pcphash_iterate(k) { + pcphash_iterate(PTX.ptx, k) { if(k->type == PCP_KEY_TYPE_MAINSECRET) { - return Key(k); + return Key(PTX, k); } } if(Vault::key_count() == 1) { - pcphash_iterate(k) { - return Key(k); + pcphash_iterate(PTX.ptx, k) { + return Key(PTX, k); } } // 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) { pcp_key_t *k = NULL; - pcphash_iterate(k) { + pcphash_iterate(PTX.ptx, k) { 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) { pcp_pubkey_t *k = NULL; - pcphash_iteratepub(k) { + pcphash_iteratepub(PTX.ptx, k) { 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."); } diff --git a/include/Makefile.am b/include/Makefile.am index 1717ed7..5c9a8af 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -22,6 +22,7 @@ PCPEXPORT = pcp.h \ pcp/buffer.h \ pcp/mgmt.h \ pcp/pcpstream.h \ - pcp/keysig.h + pcp/keysig.h \ + pcp/context.h nobase_include_HEADERS = $(PCPEXPORT) diff --git a/include/pcp.h b/include/pcp.h index fb0d6c6..45255d0 100644 --- a/include/pcp.h +++ b/include/pcp.h @@ -9,6 +9,7 @@ extern "C" { #include "pcp/base85.h" #include "pcp/buffer.h" #include "pcp/config.h" +#include "pcp/context.h" #include "pcp/crypto.h" #include "pcp/defines.h" #include "pcp/digital_crc32.h" @@ -27,6 +28,7 @@ extern "C" { #include "pcp/plist.h" #include "pcp/randomart.h" #include "pcp/scrypt.h" +#include "pcp/structs.h" #include "pcp/uthash.h" #include "pcp/util.h" #include "pcp/vault.h" diff --git a/include/pcp/base85.h b/include/pcp/base85.h index a6d18b8..68a8560 100644 --- a/include/pcp/base85.h +++ b/include/pcp/base85.h @@ -12,6 +12,7 @@ Licensed under the terms of the LGPL 2.1. #include #include #include "defines.h" +#include "context.h" #undef DEBUG_85 @@ -26,10 +27,10 @@ Licensed under the terms of the LGPL 2.1. #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); #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 */ diff --git a/include/pcp/buffer.h b/include/pcp/buffer.h index 792bd43..751e9bc 100644 --- a/include/pcp/buffer.h +++ b/include/pcp/buffer.h @@ -27,6 +27,8 @@ #include "mem.h" #include "util.h" #include "defines.h" +#include "structs.h" +#include "context.h" /** * \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. @@ -591,8 +578,7 @@ uint64_t buffer_last64(Buffer *b); \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. - Use feof() and ferror() to check this afterwards, call fatals_ifany() - in case of errors. + Use feof() and ferror() to check this afterwards. */ size_t buffer_fd_read(Buffer *b, FILE *in, size_t len); diff --git a/include/pcp/context.h b/include/pcp/context.h new file mode 100644 index 0000000..830824a --- /dev/null +++ b/include/pcp/context.h @@ -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 . + + You can contact me by mail: . +*/ + + +#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 diff --git a/include/pcp/crypto.h b/include/pcp/crypto.h index 5b85535..07a6938 100644 --- a/include/pcp/crypto.h +++ b/include/pcp/crypto.h @@ -35,6 +35,7 @@ #include "keyhash.h" #include "ed.h" #include "pcpstream.h" +#include "context.h" /** \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. 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, 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 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] 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. 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, 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. + \param[in] pcp context. + \param[in] in Stream to read the data to encrypt from. \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. */ -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. @@ -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. + \param[in] pcp context. + \param[in] in Stream to read the data to encrypt from. \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. */ -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. @@ -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. + \param[in] pcp context. + \param[in] in Stream to read the data to decrypt from. \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. */ -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. @@ -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. + \param[in] pcp context. + \param[in] in Stream to read the data to decrypt from. \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. */ -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); void pcp_rec_free(pcp_rec_t *r); diff --git a/include/pcp/defines.h b/include/pcp/defines.h index 406e4f9..917b003 100644 --- a/include/pcp/defines.h +++ b/include/pcp/defines.h @@ -137,66 +137,45 @@ typedef enum _PCP_KEY_TYPES { #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. - Can be retrieved with fatals_ifany(). -*/ -extern char *PCP_ERR; +#define EXP_SIG_VERSION 0x01 +#define EXP_SIG_TYPE 0x1F /* self signed */ -/** \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. -*/ -extern byte PCP_ERRSET; +/* 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 -----" -/** \var PCP_EXIT - Exitcode for the pcp commandline utility. -*/ -extern int PCP_EXIT; +/* 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 -/** 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 */ diff --git a/include/pcp/ed.h b/include/pcp/ed.h index 9864780..0221912 100644 --- a/include/pcp/ed.h +++ b/include/pcp/ed.h @@ -41,6 +41,7 @@ #include "keyhash.h" #include "util.h" #include "pcpstream.h" +#include "context.h" /** 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). + \param[in] pcp context. + \param[in] signature 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), 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. @@ -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). + \param[in] pcp context. + \param[in] signature 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), 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. @@ -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 and appends the signature afterwards, which consists of the hash+nacl-signature. + \param[in] pcp context. + \param[in] in Stream to read from. \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. */ -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. @@ -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 signature. + \param[in] pcp context. + \param[in] in Stream to read from. \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 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. @@ -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 from the signed content. + \param[in] pcp context. + \param[in] in Stream to read from. \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(). */ -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 */ diff --git a/include/pcp/key.h b/include/pcp/key.h index 055ce35..e6db146 100644 --- a/include/pcp/key.h +++ b/include/pcp/key.h @@ -31,16 +31,16 @@ #include "defines.h" #include "platform.h" #include "mem.h" -#include "buffer.h" #include "mac.h" #include "randomart.h" #include "version.h" -#include "z85.h" +//#include "z85.h" #include "uthash.h" #include "jenhash.h" -#include "scrypt.h" +#include "structs.h" +#include "buffer.h" #include "keysig.h" - +#include "scrypt.h" /** * \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_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 use and free() it as soon as possible. + \param[in] pcp context. + \param[in,out] key The secret key structure. \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 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. @@ -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 use and free() it as soon as possible. + \param[in] pcp context. + \param[in,out] key The secret key structure. \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. */ -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. @@ -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. + \param[in] pcp context. + \param[in] key The secret key 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 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 */ 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. 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. + \param[in] pcp context. + \param[in] key The secret key structure. \return Returns 1 if the sanity check succeeds, 0 otherwise. 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. + \param[in] pcp context. + \param[in] k Secret key to dump. */ void pcp_dumpkey(pcp_key_t *k); diff --git a/include/pcp/keyhash.h b/include/pcp/keyhash.h index 6224087..813db37 100644 --- a/include/pcp/keyhash.h +++ b/include/pcp/keyhash.h @@ -22,6 +22,10 @@ #ifndef _HAVE_KEYHASH_H #define _HAVE_KEYHASH_H +#include "structs.h" + + + /** \defgroup KEYHASH KEYHASH @{ @@ -29,22 +33,11 @@ Libpcp uses the uthash 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 */ /** Iterate over the list of secret keys. @@ -53,7 +46,7 @@ extern pcp_pubkey_t *__p; @code pcp_key_t k = NULL; - pcphash_iterate(k) { + pcphash_iterate(ptx, k) { pcp_dumpkey(k); } @endcode @@ -61,9 +54,9 @@ extern pcp_pubkey_t *__p; Also, don't free() the keyhash or the temporary key pointer yourself. Use pcphash_clean() instead when done. */ -#define pcphash_iterate(key) \ - __k = NULL; \ - HASH_ITER(hh, pcpkey_hash, key, __k) +#define pcphash_iterate(ptx, key) \ + pcp_key_t *__k = NULL; \ + HASH_ITER(hh, ptx->pcpkey_hash, key, __k) /** Iterate over the list of public keys. @@ -72,7 +65,7 @@ extern pcp_pubkey_t *__p; @code pcp_pubkey_t k = NULL; - pcphash_iteratepub(k) { + pcphash_iteratepub(ptx, k) { pcp_dumppubkey(k); } @endcode @@ -80,75 +73,77 @@ extern pcp_pubkey_t *__p; Also, don't free() the keyhash or the temporary key pointer yourself. Use pcphash_clean() instead when done. */ -#define pcphash_iteratepub(key) \ - __p = NULL; \ - HASH_ITER(hh, pcppubkey_hash, key, __p) - -/** Initialize the global hashes. */ -void pcphash_init(); +#define pcphash_iteratepub(ptx, key) \ + pcp_pubkey_t *__p = NULL; \ + HASH_ITER(hh, ptx->pcppubkey_hash, key, __p) /** Delete an entry from a hash. + \param[in] PCP Context object. + \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. */ -void pcphash_del(void *key, int type); +void pcphash_del(PCPCTX *ptx, void *key, int type); -/** Frees the memory allocated by the hashes. - - Clears and frees memory of all keys in the hash lists - and the hashes themselfes. - - */ -void pcphash_clean(); +/** Free memory used by key hashes. */ +void pcphash_clean(PCPCTX *ptx); /** 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). \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. + \param[in] PCP Context object. + \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. */ -pcp_pubkey_t *pcphash_pubkeyexists(char *id); +pcp_pubkey_t *pcphash_pubkeyexists(PCPCTX *ptx, char *id); /** 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] 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. + \param[in] PCP Context object. + \return Number of keys. */ -int pcphash_count(); +int pcphash_count(PCPCTX *ptx); /** Returns the number of public keys in the hash. + \param[in] PCP Context object. + \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 */ diff --git a/include/pcp/keysig.h b/include/pcp/keysig.h index 973dc3d..5b9ef19 100644 --- a/include/pcp/keysig.h +++ b/include/pcp/keysig.h @@ -29,22 +29,13 @@ #include "defines.h" #include "platform.h" #include "mem.h" +#include "structs.h" #include "buffer.h" #include "key.h" #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 *keysig2native(pcp_keysig_t *s); diff --git a/include/pcp/mgmt.h b/include/pcp/mgmt.h index 5d25365..4d0fa50 100644 --- a/include/pcp/mgmt.h +++ b/include/pcp/mgmt.h @@ -33,12 +33,14 @@ #include "defines.h" #include "platform.h" +#include "structs.h" #include "mem.h" #include "ed.h" #include "key.h" #include "keysig.h" #include "buffer.h" #include "scrypt.h" +#include "context.h" /* 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. @@ -287,6 +220,8 @@ Buffer *pcp_export_c_pub(pcp_key_t *sk); Nonce | Cipher + \param[in] ptx context. + \param sk a secret key structure of type pcp_key_t. The secret keys 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 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_pub(byte *raw, size_t rawsize); /* FIXME: deprecate */ -pcp_ks_bundle_t *pcp_import_pub_rfc(Buffer *blob); -pcp_ks_bundle_t *pcp_import_pub_pbp(Buffer *blob); +pcp_ks_bundle_t *pcp_import_binpub(PCPCTX *ptx, byte *raw, size_t rawsize); +pcp_ks_bundle_t *pcp_import_pub(PCPCTX *ptx, byte *raw, size_t rawsize); /* FIXME: deprecate */ +pcp_ks_bundle_t *pcp_import_pub_rfc(PCPCTX *ptx, Buffer *blob); +pcp_ks_bundle_t *pcp_import_pub_pbp(PCPCTX *ptx, Buffer *blob); /* import secret key */ -pcp_key_t *pcp_import_binsecret(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_native(Buffer *cipher, char *passphrase); +pcp_key_t *pcp_import_binsecret(PCPCTX *ptx, 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(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 diff --git a/include/pcp/pcpstream.h b/include/pcp/pcpstream.h index b944265..93e605c 100644 --- a/include/pcp/pcpstream.h +++ b/include/pcp/pcpstream.h @@ -26,8 +26,10 @@ #include #include #include "mem.h" +#include "structs.h" #include "util.h" #include "defines.h" +#include "context.h" #include "buffer.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 */ Pcpstream *ps_init(void); diff --git a/include/pcp/scrypt.h b/include/pcp/scrypt.h index c07c76b..22c81e9 100644 --- a/include/pcp/scrypt.h +++ b/include/pcp/scrypt.h @@ -35,8 +35,9 @@ #include "crypto_scrypt.h" #include "mem.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 */ diff --git a/include/pcp/structs.h b/include/pcp/structs.h new file mode 100644 index 0000000..838913c --- /dev/null +++ b/include/pcp/structs.h @@ -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 . + + You can contact me by mail: . +*/ + +#ifndef _HAVE_PCP_STRUCTS_H +#define _HAVE_PCP_STRUCTS_H + +#include "defines.h" +#include "uthash.h" +#include + +/** + \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 diff --git a/include/pcp/vault.h b/include/pcp/vault.h index 269e042..ea8f162 100644 --- a/include/pcp/vault.h +++ b/include/pcp/vault.h @@ -89,66 +89,30 @@ #include "uthash.h" #include "buffer.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. If the file doesn't exist, it will be created. + \param[in] pcp context. \param[in] filename The filename of the vault file. \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. 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. Called internally only. */ -int pcpvault_create(vault_t *vault); +int pcpvault_create(PCPCTX *ptx, vault_t *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 with care. To be safe, use pcpvault_addkey() instead. + \param[in] pcp context. \param[out] vault The vault object. \param[in] item The item to write. \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 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. @@ -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 vault checksum and puts it into the vault header. + \param[in] pcp context. \param[out] vault The vault object. \param[in] item The item to write (a key or keysig) \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(). */ -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. @@ -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 doesn't loose data. + \param[in] pcp context. \param[out] vault The vault object. \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. @@ -223,27 +190,29 @@ int pcpvault_close(vault_t *vault); contents and compares it with the one stored in the vault header. If it doesn't match an error will be thrown. + \param[in] pcp context. \param[out] vault The vault object. \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. */ -int pcpvault_writeall(vault_t *vault); +int pcpvault_writeall(PCPCTX *ptx, vault_t *vault); /* 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 */ void pcpvault_unlink(vault_t *tmp); -/* calculate the checksum of the current vault */ -byte *pcpvault_create_checksum(); +/* calculate the checksum of the current vault (that is, from the + list of keys in the current context */ +byte *pcpvault_create_checksum(PCPCTX *ptx); /* 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 */ vault_header_t * vh2be(vault_header_t *h); diff --git a/include/pcp/z85.h b/include/pcp/z85.h index a9d627f..5ee0b10 100644 --- a/include/pcp/z85.h +++ b/include/pcp/z85.h @@ -43,6 +43,8 @@ we pad the input with zeroes and remove them after decoding. #include "defines.h" #include "zmq_z85.h" #include "mem.h" +#include "structs.h" +#include "context.h" #include "buffer.h" /** 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. + \param[in] the pcp context object. \param[in] z85block The Z85 encoded string. \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(). */ -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. @@ -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. It ignores newlines, comments and Headerstrings. + \param[in] the pcp context object. \param[in] infile FILE stream to read from. \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. Parses the given input string and returns the raw Z85 encoded string. It ignores newlines, comments and Headerstrings. + \param[in] the pcp context object. \param[in] input Z85 encoded string. \param[in] bufsize Size of the string. \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. diff --git a/libpcp/Makefile.am b/libpcp/Makefile.am index f9493d2..cb406fe 100644 --- a/libpcp/Makefile.am +++ b/libpcp/Makefile.am @@ -26,8 +26,8 @@ pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = libpcp1.pc libpcp1_la_SOURCES = platform.c mac.c mem.c pad.c version.c \ - z85.c zmq_z85.c key.c randomart.c \ - vault.c fatal.c jenhash.c digital_crc32.c \ + context.c z85.c zmq_z85.c key.c randomart.c \ + vault.c jenhash.c digital_crc32.c \ crypto.c ed.c keyhash.c scrypt.c \ scrypt/crypto/sha256.c scrypt/crypto/crypto_scrypt-nosse.c \ base85.c util.c buffer.c mgmt.c keysig.c pcpstream.c diff --git a/libpcp/base85.c b/libpcp/base85.c index 7cfc071..dc6b7f1 100644 --- a/libpcp/base85.c +++ b/libpcp/base85.c @@ -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(); say1("len: %d\n", len); diff --git a/libpcp/buffer.c b/libpcp/buffer.c index 641ed75..f051f5b 100644 --- a/libpcp/buffer.c +++ b/libpcp/buffer.c @@ -129,9 +129,8 @@ byte *buffer_get(Buffer *b) { size_t buffer_get_chunk(Buffer *b, void *buf, size_t len) { 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); - return 0; } else if(len == 0) { /* 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) { 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); - return 0; } else if(len == 0) { /* 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) { 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); - return 0; + final("[buffer %s] attempt to read %ld bytes past end of buffer at %ld\n", b->name, b->end - (b->offset + len), 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); - return 0; + final("[buffer %s] attempt to read at offset %ld past len to read %ld\n", b->name, offset, b->end); } 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); - if(s < len) { - 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; - } + if(s > 0) + buffer_add(b, data, len); - buffer_add(b, data, len); - return len; + return s; } void buffer_add8(Buffer *b, uint8_t v) { diff --git a/libpcp/fatal.c b/libpcp/context.c similarity index 56% rename from libpcp/fatal.c rename to libpcp/context.c index 9614d2c..e984f6f 100644 --- a/libpcp/fatal.c +++ b/libpcp/context.c @@ -21,9 +21,8 @@ #define _GNU_SOURCE /* vasprintf() linux */ -#include "defines.h" -#include "platform.h" +#include "context.h" #include #include @@ -31,39 +30,70 @@ #include #include -char *PCP_ERR; -byte PCP_ERRSET; -int PCP_EXIT; -int PCPVERBOSE; +PCPCTX *ptx_new() { + PCPCTX *p = ucmalloc(sizeof(PCPCTX)); + p->pcp_err = NULL; + 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_start(ap, fmt); + + char *err = ptx->pcp_err; - if(vasprintf(&PCP_ERR, fmt, ap) >= 0) { + if(vasprintf(&err, fmt, ap) >= 0) { va_end(ap); - PCP_ERRSET = 1; + ptx->pcp_errset = 1; } else { fprintf(stderr, "Could not store fatal error message %s!\n", fmt); - PCP_ERRSET = 1; + ptx->pcp_errset = 1; } } -void fatals_reset() { - PCP_ERRSET = 0; +void fatals_reset(PCPCTX *ptx) { + ptx->pcp_errset = 0; } -void fatals_ifany() { - if(PCP_ERRSET == 1) { - fprintf(stderr, "%s", PCP_ERR); +void fatals_ifany(PCPCTX *ptx) { + if(ptx->pcp_errset == 1) { + fprintf(stderr, "%s", ptx->pcp_err); if(errno) { fprintf(stderr, "Error: %s\n", strerror(errno)); } - PCP_EXIT = 1; + ptx->pcp_exit = 1; } } -void fatals_done() { - free(PCP_ERR); +void final(const char * fmt, ...) { + 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(); } diff --git a/libpcp/crypto.c b/libpcp/crypto.c index 0e5a329..85bc2b2 100644 --- a/libpcp/crypto.c +++ b/libpcp/crypto.c @@ -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, size_t *csize) { @@ -93,7 +93,7 @@ byte *pcp_box_encrypt(pcp_key_t *secret, pcp_pubkey_t *pub, secret->secret, pub->pub); if(es <= messagesize) { - fatal("failed to encrypt message!\n"); + fatal(ptx, "failed to encrypt message!\n"); 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, 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, ciphersize - crypto_secretbox_NONCEBYTES, nonce, secret->secret, pub->pub) != 0){ - fatal("failed to decrypt message!\n"); + fatal(ptx, "failed to decrypt message!\n"); goto errbed; } @@ -161,7 +161,7 @@ byte *pcp_box_decrypt(pcp_key_t *secret, pcp_pubkey_t *pub, 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; byte *reccipher = NULL; 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) self = 1; 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; } } @@ -202,14 +202,14 @@ size_t pcp_decrypt_stream(Pcpstream *in, Pcpstream* out, pcp_key_t *s, byte *sym if(self) { /* 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 /* step 2, sender's pubkey */ 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)) { - 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; } #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 */ cur_bufsize = ps_read(in, &lenrec, 4); /* fread(&lenrec, 1, 4, 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; } 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; nrecpub); + verifiedhash = pcp_ed_verify(ptx, signature, siglen, recverify->pub); if(verifiedhash == NULL) out_size = 0; else { if(memcmp(verifiedhash, hash, crypto_generichash_BYTES_MAX) != 0) { /* 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; } free(verifiedhash); } } else { - fatal("Failed to decrypt signature!\n"); + fatal(ptx, "Failed to decrypt signature!\n"); out_size = 0; } free(st); diff --git a/libpcp/ed.c b/libpcp/ed.c index a8e1ba5..673f75c 100644 --- a/libpcp/ed.c +++ b/libpcp/ed.c @@ -21,12 +21,12 @@ #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); unsigned long long mlen; 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; } @@ -37,12 +37,12 @@ byte * pcp_ed_verify_key(byte *signature, size_t siglen, pcp_pubkey_t *p) { 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); */ unsigned long long mlen; 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; } @@ -71,7 +71,7 @@ byte *pcp_ed_sign(byte *message, size_t messagesize, pcp_key_t *s) { 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]; size_t cur_bufsize = 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) { - fatal("Failed to write encrypted output!\n"); + fatal(ptx, "Failed to write encrypted output!\n"); free(st); return 0; } @@ -120,7 +120,7 @@ size_t pcp_ed_sign_buffered(Pcpstream *in, Pcpstream* out, pcp_key_t *s, int z85 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_next[PCP_BLOCK_SIZE/2]; byte in_full[PCP_BLOCK_SIZE]; @@ -247,23 +247,23 @@ pcp_pubkey_t *pcp_ed_verify_buffered(Pcpstream *in, pcp_pubkey_t *p) { } /* while */ 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; } crypto_generichash_final(st, hash, crypto_generichash_BYTES_MAX); if(z85) { - char *z85block = pcp_readz85string(z85encoded, zlen); + char *z85block = pcp_readz85string(ptx, z85encoded, zlen); if(z85block == NULL) goto errvb1; //fprintf(stderr, "ZBLOCK: <%s>\n", z85block); size_t dstlen; - byte *z85decoded = pcp_z85_decode(z85block, &dstlen); + byte *z85decoded = pcp_z85_decode(ptx, z85block, &dstlen); 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; } 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? */ byte *verifiedhash = NULL; if(p == NULL) { - pcphash_iteratepub(p) { - verifiedhash = pcp_ed_verify(sighash, mlen, p); + pcphash_iteratepub(ptx, p) { + verifiedhash = pcp_ed_verify(ptx, sighash, mlen, p); if(verifiedhash != NULL) break; } } else { - verifiedhash = pcp_ed_verify(sighash, mlen, p); + verifiedhash = pcp_ed_verify(ptx, sighash, mlen, p); } 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) { /* 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); return NULL; } @@ -336,7 +336,7 @@ size_t pcp_ed_detachsign_buffered(Pcpstream *in, Pcpstream *out, pcp_key_t *s) { 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]; size_t cur_bufsize = 0; size_t outsize = 0; @@ -374,35 +374,35 @@ pcp_pubkey_t *pcp_ed_detachverify_buffered(Pcpstream *in, Pcpstream *sigfd, pcp_ } if(sig == NULL) { - fatal("Invalid detached signature\n"); + fatal(ptx, "Invalid detached signature\n"); goto errdea1; } - char *z85block = pcp_readz85string(sig, inputBufSize); + char *z85block = pcp_readz85string(ptx, sig, inputBufSize); if(z85block == NULL) goto errdea2; size_t clen; - byte *sighash = pcp_z85_decode(z85block, &clen); + byte *sighash = pcp_z85_decode(ptx, z85block, &clen); if(sighash == NULL) goto errdea3; 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; } byte *verifiedhash = NULL; if(p == NULL) { - pcphash_iteratepub(p) { - verifiedhash = pcp_ed_verify(sighash, mlen, p); + pcphash_iteratepub(ptx, p) { + verifiedhash = pcp_ed_verify(ptx, sighash, mlen, p); if(verifiedhash != NULL) break; } } else { - verifiedhash = pcp_ed_verify(sighash, mlen, p); + verifiedhash = pcp_ed_verify(ptx, sighash, mlen, p); } 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) { /* 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; } diff --git a/libpcp/key.c b/libpcp/key.c index fc2b4e0..5ff5ffb 100644 --- a/libpcp/key.c +++ b/libpcp/key.c @@ -21,19 +21,19 @@ #include "key.h" -#include "keyhash.h" +#include "context.h" /* * 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() * 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); size_t plen = strnlen(passphrase, 255); /* 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 */ crypto_hash_sha256(key, (byte*)scrypted, 64); @@ -142,13 +142,13 @@ byte * pcp_gennonce() { 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) { byte *nonce = pcp_gennonce(); memcpy (key->nonce, nonce, crypto_secretbox_NONCEBYTES); } - byte *encryptkey = pcp_derivekey(passphrase, key->nonce); + byte *encryptkey = pcp_derivekey(ptx, passphrase, key->nonce); byte *encrypted; size_t es; @@ -175,7 +175,7 @@ pcp_key_t *pcpkey_encrypt(pcp_key_t *key, char *passphrase) { key->mastersecret[0] = 0; } else { - fatal("failed to encrypt the secret key!\n"); + fatal(ptx, "failed to encrypt the secret key!\n"); free(key); return NULL; } @@ -183,8 +183,8 @@ pcp_key_t *pcpkey_encrypt(pcp_key_t *key, char *passphrase) { return key; } -pcp_key_t *pcpkey_decrypt(pcp_key_t *key, char *passphrase) { - byte *encryptkey = pcp_derivekey(passphrase, key->nonce); +pcp_key_t *pcpkey_decrypt(PCPCTX *ptx, pcp_key_t *key, char *passphrase) { + byte *encryptkey = pcp_derivekey(ptx, passphrase, key->nonce); byte *decrypted; size_t es; @@ -201,7 +201,7 @@ pcp_key_t *pcpkey_decrypt(pcp_key_t *key, char *passphrase) { memcpy(key->secret, decrypted +128, 32); } 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); 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) { - 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; } 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); return 1; } 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); return 1; } 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; } @@ -382,7 +382,7 @@ int pcp_sanitycheck_pub(pcp_pubkey_t *key) { char *got = ucmalloc(17); memcpy(got, key->id, 17); 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); return 1; } @@ -392,13 +392,13 @@ int pcp_sanitycheck_pub(pcp_pubkey_t *key) { c = localtime(&t); if(c->tm_year <= 0 || c->tm_year > 1100) { /* 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; } - pcp_pubkey_t *maybe = pcphash_pubkeyexists(key->id); + pcp_pubkey_t *maybe = pcphash_pubkeyexists(ptx, key->id); 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; } @@ -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) { - 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; } 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); return 1; } 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); return 1; } 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; } @@ -433,7 +433,7 @@ int pcp_sanitycheck_key(pcp_key_t *key) { char *got = ucmalloc(17); memcpy(got, key->id, 17); 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); return 1; } @@ -443,13 +443,13 @@ int pcp_sanitycheck_key(pcp_key_t *key) { c = localtime(&t); if(c->tm_year <= 70 || c->tm_year > 1100) { /* 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; } - pcp_key_t *maybe = pcphash_keyexists(key->id); + pcp_key_t *maybe = pcphash_keyexists(ptx, key->id); 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; } diff --git a/libpcp/keyhash.c b/libpcp/keyhash.c index d3b8071..edb2770 100644 --- a/libpcp/keyhash.c +++ b/libpcp/keyhash.c @@ -22,102 +22,87 @@ #include "keyhash.h" -pcp_key_t *pcpkey_hash; -pcp_pubkey_t *pcppubkey_hash; -pcp_keysig_t *pcpkeysig_hash; -pcp_key_t *__k; -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) { +void pcphash_del(PCPCTX *ptx, void *key, int type) { 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)); } else if(type == PCP_KEYSIG_NATIVE || type == PCP_KEYSIG_PBP) { pcp_keysig_t *keysig = (pcp_keysig_t *)key; memset(keysig->blob, 0, keysig->size); free(keysig->blob); - HASH_DEL(pcpkeysig_hash, (pcp_keysig_t *)key); + HASH_DEL(ptx->pcpkeysig_hash, (pcp_keysig_t *)key); } 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)); } free(key); } -void pcphash_clean() { - if(pcpkey_hash != NULL) { +void pcphash_clean(PCPCTX *ptx) { + if(ptx->pcpkey_hash != NULL) { pcp_key_t *current_key, *tmp; - HASH_ITER(hh, pcpkey_hash, current_key, tmp) { - pcphash_del(current_key, PCP_KEY_TYPE_SECRET); + HASH_ITER(hh, ptx->pcpkey_hash, current_key, tmp) { + pcphash_del(ptx, current_key, PCP_KEY_TYPE_SECRET); } } - if(pcppubkey_hash != NULL) { + if(ptx->pcppubkey_hash != NULL) { pcp_pubkey_t *current_pub, *ptmp; - HASH_ITER(hh, pcppubkey_hash, current_pub, ptmp) { - pcphash_del(current_pub, PCP_KEY_TYPE_PUBLIC); + HASH_ITER(hh, ptx->pcppubkey_hash, current_pub, ptmp) { + pcphash_del(ptx, current_pub, PCP_KEY_TYPE_PUBLIC); } } - if(pcpkeysig_hash != NULL) { + if(ptx->pcpkeysig_hash != NULL) { pcp_keysig_t *current_keysig, *tmp; - HASH_ITER(hh, pcpkeysig_hash, current_keysig, tmp) { - pcphash_del(current_keysig, current_keysig->type); + HASH_ITER(hh, ptx->pcpkeysig_hash, current_keysig, tmp) { + 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; - HASH_FIND_STR(pcpkeysig_hash, id, keysig); + HASH_FIND_STR(ptx->pcpkeysig_hash, id, keysig); 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; - HASH_FIND_STR(pcpkey_hash, id, key); + HASH_FIND_STR(ptx->pcpkey_hash, id, key); 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; - HASH_FIND_STR(pcppubkey_hash, id, key); + HASH_FIND_STR(ptx->pcppubkey_hash, id, key); 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) { 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) { pcp_keysig_t *keysig = (pcp_keysig_t *)key; - HASH_ADD_STR( pcpkeysig_hash, id, keysig); + HASH_ADD_STR( ptx->pcpkeysig_hash, id, keysig); } else { 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() { - return HASH_COUNT(pcpkey_hash); +int pcphash_count(PCPCTX *ptx) { + return HASH_COUNT(ptx->pcpkey_hash); } -int pcphash_countpub() { - return HASH_COUNT(pcppubkey_hash); +int pcphash_countpub(PCPCTX *ptx) { + return HASH_COUNT(ptx->pcppubkey_hash); } diff --git a/libpcp/mgmt.c b/libpcp/mgmt.c index dc142b8..53981e4 100644 --- a/libpcp/mgmt.c +++ b/libpcp/mgmt.c @@ -35,37 +35,37 @@ int _get_pk(Buffer *blob, pcp_pubkey_t *p) { 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)) { buffer_get_chunk(blob, h, sizeof(rfc_pub_sig_h)); h->numsubs = be16toh(h->numsubs); 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; } 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; } 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; } 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; } 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); return 1; } return 0; } else { - fatal("Error: input data too small, import failed"); + fatal(ptx, "Error: input data too small, import failed"); return 1; } } @@ -108,7 +108,7 @@ int _check_sigsubs(Buffer *blob, pcp_pubkey_t *p, rfc_pub_sig_s *subheader) { 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 size_t blobstop = blob->offset; 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); /* 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) goto chker1; @@ -143,7 +143,7 @@ int _check_hash_keysig(Buffer *blob, pcp_pubkey_t *p, pcp_keysig_t *sk) { /* compare them */ 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; } @@ -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_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) { /* ah, homerun */ - return pcp_import_pub_rfc(blob); + return pcp_import_pub_rfc(ptx, blob); } else { /* 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; byte *bin = NULL; char *z85 = NULL; if(rawsize == 0) { - fatal("Input file is empty!\n"); + fatal(ptx, "Input file is empty!\n"); return NULL; } Buffer *blob = buffer_new(512, "importblob"); /* first, try to decode the input */ - z85 = pcp_readz85string(raw, rawsize); + z85 = pcp_readz85string(ptx, raw, rawsize); if(z85 != NULL) - bin = pcp_z85_decode(z85, &clen); + bin = pcp_z85_decode(ptx, z85, &clen); if(bin == NULL) { /* treat as binary blob */ - fatals_reset(); + fatals_reset(ptx); buffer_add(blob, raw, rawsize); } else { @@ -224,15 +224,15 @@ pcp_ks_bundle_t *pcp_import_pub(byte *raw, size_t rawsize) { if(version == PCP_KEY_VERSION) { /* ah, homerun */ - return pcp_import_pub_rfc(blob); + return pcp_import_pub_rfc(ptx, blob); } else { /* 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_keysig_t *sk = ucmalloc(sizeof(pcp_keysig_t)); 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(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; } @@ -254,7 +254,7 @@ pcp_ks_bundle_t *pcp_import_pub_rfc(Buffer *blob) { goto be; /* check sig header */ - if(_check_keysig_h(blob, sigheader) != 0) + if(_check_keysig_h(ptx, blob, sigheader) != 0) goto bef; /* 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)); /* 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->s = NULL; } @@ -290,7 +290,7 @@ pcp_ks_bundle_t *pcp_import_pub_rfc(Buffer *blob) { be: - fatal("Error: input data too small, import failed"); + fatal(ptx, "Error: input data too small, import failed"); bef: buffer_free(blob); @@ -300,7 +300,7 @@ pcp_ks_bundle_t *pcp_import_pub_rfc(Buffer *blob) { 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 *ignore = ucmalloc(46); char *parts = NULL; @@ -314,7 +314,7 @@ pcp_ks_bundle_t *pcp_import_pub_pbp(Buffer *blob) { /* make sure it's a pbp */ 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; } @@ -326,7 +326,7 @@ pcp_ks_bundle_t *pcp_import_pub_pbp(Buffer *blob) { date[19] = '\0'; struct tm c; 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); goto errimp2; } @@ -365,7 +365,7 @@ pcp_ks_bundle_t *pcp_import_pub_pbp(Buffer *blob) { /* edpub used for signing, might differ */ 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); 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; } -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 *symkey = NULL; byte *cipher = NULL; @@ -708,7 +708,7 @@ Buffer *pcp_export_secret(pcp_key_t *sk, char *passphrase) { nonce = ucmalloc(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); @@ -723,33 +723,33 @@ Buffer *pcp_export_secret(pcp_key_t *sk, char *passphrase) { 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_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; byte *bin = NULL; char *z85 = NULL; if(rawsize == 0) { - fatal("Input file is empty!\n"); + fatal(ptx, "Input file is empty!\n"); return NULL; } Buffer *blob = buffer_new(512, "importskblob"); /* first, try to decode the input */ - z85 = pcp_readz85string(raw, rawsize); + z85 = pcp_readz85string(ptx, raw, rawsize); if(z85 != NULL) - bin = pcp_z85_decode(z85, &clen); + bin = pcp_z85_decode(ptx, z85, &clen); if(bin == NULL) { /* treat as binary blob */ - fatals_reset(); + fatals_reset(ptx); buffer_add(blob, raw, rawsize); } 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 */ - 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)); byte *nonce = ucmalloc(crypto_secretbox_NONCEBYTES); 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) 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); 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); goto impserr1; } @@ -788,7 +788,7 @@ pcp_key_t *pcp_import_secret_native(Buffer *cipher, char *passphrase) { /* decrypt the blob */ if(pcp_sodium_verify_mac(&clear, buffer_get_remainder(cipher), 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; } diff --git a/libpcp/pcpstream.c b/libpcp/pcpstream.c index 6d355fc..eabe476 100644 --- a/libpcp/pcpstream.c +++ b/libpcp/pcpstream.c @@ -359,9 +359,7 @@ void ps_determine(Pcpstream *stream) { size_t ps_read_decode(Pcpstream *stream) { Buffer *z = buffer_new(32, "ztemp"); Buffer *line = buffer_new_str("line"); - - //buffer_info(stream->save); - + PCPCTX *ptx = ptx_new(); if(buffer_left(stream->save) > stream->blocksize){// && stream->firstread == 1) { /* 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"); buffer_get_chunk_tobuf(stream->save, z, buffer_left(stream->save)); //buffer_dump(z); - fatals_ifany(); + //fatals_ifany(); } else { /* continue reading linewise */ @@ -435,10 +433,10 @@ size_t ps_read_decode(Pcpstream *stream) { /* finally, decode it and put into next */ 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); // _dump("bin", bin, binlen); - fatals_ifany(); + //fatals_ifany(); if(bin == NULL) { /* it's not z85 encoded, so threat it as binary */ if(stream->firstread) { @@ -461,7 +459,7 @@ size_t ps_read_decode(Pcpstream *stream) { buffer_free(z); buffer_free(line); - + ptx_clean(ptx); return outlen; } diff --git a/libpcp/scrypt.c b/libpcp/scrypt.c index fe4fea8..58b4762 100644 --- a/libpcp/scrypt.c +++ b/libpcp/scrypt.c @@ -21,7 +21,7 @@ #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 */ /* constants */ @@ -34,7 +34,7 @@ byte* pcp_scrypt(char *passwd, size_t passwdlen, byte *nonce, size_t noncelen) { return dk; } else { - fatal("crypto_scrypt() failed"); + fatal(ptx, "crypto_scrypt() failed"); return NULL; } diff --git a/libpcp/vault.c b/libpcp/vault.c index 411d12f..d056ccd 100644 --- a/libpcp/vault.c +++ b/libpcp/vault.c @@ -24,19 +24,19 @@ #include "keyhash.h" #include "defines.h" -vault_t *pcpvault_init(char *filename) { - vault_t *vault = pcpvault_new(filename, 0); +vault_t *pcpvault_init(PCPCTX *ptx, char *filename) { + vault_t *vault = pcpvault_new(ptx, filename, 0); if(vault != NULL) { if(vault->isnew == 1) { - if(pcpvault_create(vault) != 0) { - pcpvault_close(vault); + if(pcpvault_create(ptx, vault) != 0) { + pcpvault_close(ptx, vault); return NULL; } } 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 */ - pcpvault_close(vault); + pcpvault_close(ptx, vault); return NULL; } } @@ -44,7 +44,7 @@ vault_t *pcpvault_init(char *filename) { 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)); FILE *fd; struct stat stat_buf; @@ -82,7 +82,7 @@ vault_t *pcpvault_new(char *filename, int is_tmp) { vault->isnew = 1; mode_t old_mask = umask (S_IWGRP | S_IWOTH | S_IRGRP | S_IROTH); 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); goto errn; } @@ -90,7 +90,7 @@ vault_t *pcpvault_new(char *filename, int is_tmp) { } else { 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; } } @@ -105,7 +105,7 @@ vault_t *pcpvault_new(char *filename, int is_tmp) { 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)); header->fileid = PCP_VAULT_ID; header->version = PCP_VAULT_VERSION; @@ -120,7 +120,7 @@ int pcpvault_create(vault_t *vault) { fwrite(header, sizeof(vault_header_t), 1, vault->fd); 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; } @@ -129,7 +129,7 @@ int pcpvault_create(vault_t *vault) { 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)); header->type = type; 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); 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; } @@ -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) { - vault_t *tmp = pcpvault_new(vault->filename, 1); +int pcpvault_addkey(PCPCTX *ptx, vault_t *vault, void *item, uint8_t type) { + vault_t *tmp = pcpvault_new(ptx, vault->filename, 1); size_t itemsize; void *saveitem = NULL; @@ -183,15 +183,15 @@ int pcpvault_addkey(vault_t *vault, void *item, uint8_t type) { if(tmp != NULL) { - if(pcpvault_copy(vault, tmp) != 0) + if(pcpvault_copy(ptx, vault, tmp) != 0) 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; - pcphash_add(saveitem, type); - pcpvault_update_checksum(tmp); + pcphash_add(ptx, saveitem, type); + pcpvault_update_checksum(ptx, tmp); - if(pcpvault_copy(tmp, vault) == 0) { + if(pcpvault_copy(ptx, tmp, vault) == 0) { pcpvault_unlink(tmp); } else { @@ -212,32 +212,32 @@ int pcpvault_addkey(vault_t *vault, void *item, uint8_t type) { return 1; } -int pcpvault_writeall(vault_t *vault) { - vault_t *tmp = pcpvault_new(vault->filename, 1); +int pcpvault_writeall(PCPCTX *ptx, vault_t *vault) { + vault_t *tmp = pcpvault_new(ptx, vault->filename, 1); if(tmp != NULL) { - if(pcpvault_create(tmp) == 0) { + if(pcpvault_create(ptx, tmp) == 0) { pcp_key_t *k = NULL; Buffer *blob = buffer_new(PCP_RAW_PUBKEYSIZE, "bs"); - pcphash_iterate(k) { + pcphash_iterate(ptx, 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); goto errwa; } buffer_clear(blob); } pcp_pubkey_t *p = NULL; - pcphash_iteratepub(p) { + pcphash_iteratepub(ptx, 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); goto errwa; } buffer_clear(blob); } - pcpvault_update_checksum(tmp); - if(pcpvault_copy(tmp, vault) == 0) { + pcpvault_update_checksum(ptx, tmp); + if(pcpvault_copy(ptx, tmp, vault) == 0) { pcpvault_unlink(tmp); } free(tmp); @@ -256,8 +256,8 @@ int pcpvault_writeall(vault_t *vault) { return 1; } -void pcpvault_update_checksum(vault_t *vault) { - byte *checksum = pcpvault_create_checksum(); +void pcpvault_update_checksum(PCPCTX *ptx, vault_t *vault) { + byte *checksum = pcpvault_create_checksum(ptx); vault_header_t *header = ucmalloc(sizeof(vault_header_t)); header->fileid = PCP_VAULT_ID; @@ -272,20 +272,20 @@ void pcpvault_update_checksum(vault_t *vault) { fseek(vault->fd, 0, SEEK_END); } -byte *pcpvault_create_checksum() { +byte *pcpvault_create_checksum(PCPCTX *ptx) { pcp_key_t *k = NULL; Buffer *blob = NULL; size_t datapos = 0; - int numskeys = pcphash_count(); - int numpkeys = pcphash_countpub(); + int numskeys = pcphash_count(ptx); + int numpkeys = pcphash_countpub(ptx); size_t datasize = ((PCP_RAW_KEYSIZE) * numskeys) + ((PCP_RAW_PUBKEYSIZE) * numpkeys); byte *data = ucmalloc(datasize); byte *checksum = ucmalloc(32); - pcphash_iterate(k) { + pcphash_iterate(ptx, k) { key2be(k); blob = pcp_keyblob(k, PCP_KEY_TYPE_SECRET); memcpy(&data[datapos], buffer_get(blob), PCP_RAW_KEYSIZE); @@ -295,7 +295,7 @@ byte *pcpvault_create_checksum() { } pcp_pubkey_t *p = NULL; - pcphash_iteratepub(p) { + pcphash_iteratepub(ptx, p) { /* pcp_dumppubkey(p); */ pubkey2be(p); 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 */ fseek(tmp->fd, 0, SEEK_END); 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 */ vault->fd = freopen(vault->filename, "wb+", vault->fd); 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); return 1; } 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); return 1; } @@ -363,11 +363,11 @@ void pcpvault_unlink(vault_t *tmp) { free(r); } -int pcpvault_close(vault_t *vault) { +int pcpvault_close(PCPCTX *ptx, vault_t *vault) { if(vault != NULL) { if(vault->fd) { if(vault->unsafed == 1) { - pcpvault_writeall(vault); + pcpvault_writeall(ptx, vault); } 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; 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)); got = fread(header, 1, sizeof(vault_header_t), vault->fd); 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; } vh2native(header); @@ -437,8 +437,6 @@ int pcpvault_fetchall(vault_t *vault) { int bytesleft = 0; int ksize = PCP_RAW_KEYSIGSIZE; /* smallest possbile item */ - pcphash_init(); - vault->version = header->version; memcpy(vault->checksum, header->checksum, 32); @@ -461,34 +459,34 @@ int pcpvault_fetchall(vault_t *vault) { key = ucmalloc(sizeof(pcp_key_t)); got = fread(key, PCP_RAW_KEYSIZE, 1, vault->fd); key2native(key); - pcphash_add((void *)key, item->type); + pcphash_add(ptx, (void *)key, item->type); } else if(item->type == PCP_KEY_TYPE_PUBLIC) { /* read a public key */ pubkey = ucmalloc(sizeof(pcp_pubkey_t)); got = fread(pubkey, PCP_RAW_PUBKEYSIZE, 1, vault->fd); 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) { Buffer *rawks = buffer_new(256, "keysig"); buffer_fd_read(rawks, vault->fd, item->size); pcp_keysig_t *s = pcp_keysig_new(rawks); - pcphash_add((void *)s, item->type); + pcphash_add(ptx, (void *)s, item->type); buffer_free(rawks); } 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; } } 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; } } 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); goto err; } @@ -500,22 +498,22 @@ int pcpvault_fetchall(vault_t *vault) { } } else { - fatal("Unexpected vault file format!\n"); + fatal(ptx, "Unexpected vault file format!\n"); goto err; } byte *checksum = NULL; - checksum = pcpvault_create_checksum(vault); + checksum = pcpvault_create_checksum(ptx); /* _dump(" calc checksum", 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 */ 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; } } diff --git a/libpcp/z85.c b/libpcp/z85.c index 09ebdb2..7da79a4 100644 --- a/libpcp/z85.c +++ b/libpcp/z85.c @@ -182,7 +182,7 @@ size_t pcp_unpadfour(byte *src, size_t srclen) { 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; size_t binlen, outlen; size_t srclen; @@ -199,7 +199,7 @@ byte *pcp_z85_decode(char *z85block, size_t *dstlen) { bin = ucmalloc(binlen); 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; } @@ -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 *tmp = NULL; size_t bufsize = 0; @@ -269,25 +269,25 @@ char *pcp_readz85file(FILE *infile) { } if(bufsize == 0) { - fatal("Input file is empty!\n"); + fatal(ptx, "Input file is empty!\n"); free(tmp); 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 MAXLINE = 1024; if(bufsize == 0) { - fatal("Input file is empty!\n"); + fatal(ptx, "Input file is empty!\n"); return NULL; } 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; } @@ -339,7 +339,7 @@ char *pcp_readz85string(unsigned char *input, size_t bufsize) { } if(buffer_size(z) == 0) { - fatal("empty z85 encoded string"); + fatal(ptx, "empty z85 encoded string"); goto rferr; } diff --git a/src/encryption.c b/src/encryption.c index 708f316..7324491 100644 --- a/src/encryption.c +++ b/src/encryption.c @@ -34,7 +34,7 @@ int pcpdecrypt(char *id, int useid, char *infile, char *outfile, char *passwd, i in = stdin; else { 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; } } @@ -43,7 +43,7 @@ int pcpdecrypt(char *id, int useid, char *infile, char *outfile, char *passwd, i out = stdout; else { 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; } } @@ -73,15 +73,15 @@ int pcpdecrypt(char *id, int useid, char *infile, char *outfile, char *passwd, i strncpy(passphrase, passwd, strlen(passwd)); } - symkey = pcp_scrypt(passphrase, strlen(passphrase), salt, 90); + symkey = pcp_scrypt(ptx, passphrase, strlen(passphrase), salt, 90); free(salt); } else { /* asymetric mode */ if(useid) { - HASH_FIND_STR(pcpkey_hash, id, secret); + secret = pcphash_keyexists(ptx, id); 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); goto errde3; } @@ -89,7 +89,7 @@ int pcpdecrypt(char *id, int useid, char *infile, char *outfile, char *passwd, i else { secret = pcp_find_primary_secret(); 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; } } @@ -105,21 +105,21 @@ int pcpdecrypt(char *id, int useid, char *infile, char *outfile, char *passwd, i strncpy(passphrase, passwd, strlen(passwd)+1); } - secret = pcpkey_decrypt(secret, passphrase); + secret = pcpkey_decrypt(ptx, secret, passphrase); if(secret == NULL) goto errde3; } } } else { - fatal("Could not determine input file type\n"); + fatal(ptx, "Could not determine input file type\n"); goto errde3; } if(symkey == NULL) - dlen = pcp_decrypt_stream(pin, pout, secret, NULL, verify); + dlen = pcp_decrypt_stream(ptx, pin, pout, secret, NULL, verify); 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(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 */ char stsalt[] = PBP_COMPAT_SALT; memcpy(salt, stsalt, 90); - symkey = pcp_scrypt(passphrase, strlen(passphrase), salt, 90); + symkey = pcp_scrypt(ptx, passphrase, strlen(passphrase), salt, 90); free(salt); } else if(id != NULL && recipient == NULL) { /* lookup by id */ - HASH_FIND_STR(pcppubkey_hash, id, tmp); + tmp = pcphash_pubkeyexists(ptx, id); if(tmp == NULL) { /* self-encryption: look if its a secret one */ - pcp_key_t *s = NULL; - HASH_FIND_STR(pcpkey_hash, id, s); + pcp_key_t *s = pcphash_keyexists(ptx, id); if(s != NULL) { tmp = pcpkey_pub_from_secret(s); HASH_ADD_STR( pubhash, id, tmp); self = 1; } 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); goto erren3; } @@ -197,7 +196,7 @@ int pcpencrypt(char *id, char *infile, char *outfile, char *passwd, plist_t *rec /* iterate through global hashlist */ /* copy matches into temporary pubhash */ plist_t *rec; - pcphash_iteratepub(tmp) { + pcphash_iteratepub(ptx, tmp) { rec = recipient->first; while (rec != NULL) { _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) { - fatal("no matching key found for specified recipient(s)!\n"); + fatal(ptx, "no matching key found for specified recipient(s)!\n"); goto erren3; } } @@ -224,7 +223,7 @@ int pcpencrypt(char *id, char *infile, char *outfile, char *passwd, plist_t *rec #else secret = pcp_find_primary_secret(); 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; } @@ -239,7 +238,7 @@ int pcpencrypt(char *id, char *infile, char *outfile, char *passwd, plist_t *rec passphrase = ucmalloc(strlen(passwd)+1); strncpy(passphrase, passwd, strlen(passwd)+1); } - secret = pcpkey_decrypt(secret, passphrase); + secret = pcpkey_decrypt(ptx, secret, passphrase); if(secret == NULL) goto erren2; } @@ -250,7 +249,7 @@ int pcpencrypt(char *id, char *infile, char *outfile, char *passwd, plist_t *rec in = stdin; else { 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; } } @@ -259,7 +258,7 @@ int pcpencrypt(char *id, char *infile, char *outfile, char *passwd, plist_t *rec out = stdout; else { 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; } } @@ -275,9 +274,9 @@ int pcpencrypt(char *id, char *infile, char *outfile, char *passwd, plist_t *rec } 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 - clen = pcp_encrypt_stream(pin, pout, secret, pubhash, signcrypt); + clen = pcp_encrypt_stream(ptx, pin, pout, secret, pubhash, signcrypt); if(armor == 1) { 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); else { fprintf(stderr, "Encrypted %"FMT_SIZE_T" bytes for:\n", (SIZE_T_CAST)clen); - pcp_pubkey_t *cur, *t; - HASH_ITER(hh, pubhash, cur, t) { + pcp_pubkey_t *cur; + pcphash_iteratepub(ptx, cur) { fprintf(stderr, "%s <%s>\n", cur->owner, cur->mail); } - free(t); free(cur); } if(signcrypt) diff --git a/src/encryption.h b/src/encryption.h index 535fa7e..7856269 100644 --- a/src/encryption.h +++ b/src/encryption.h @@ -36,6 +36,7 @@ #include "keyhash.h" #include "plist.h" #include "pcpstream.h" +#include "context.h" 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); diff --git a/src/keymgmt.c b/src/keymgmt.c index 86934a8..dadb328 100644 --- a/src/keymgmt.c +++ b/src/keymgmt.c @@ -30,14 +30,14 @@ char *pcp_getstdin(const char *prompt) { fprintf(stderr, "%s: ", prompt); if (fgets(line, 255, stdin) == NULL) { - fatal("Cannot read from stdin"); + fatal(ptx, "Cannot read from stdin"); goto errgst; } line[strcspn(line, "\r\n")] = '\0'; if ((out = strdup(line)) == NULL) { - fatal("Cannot allocate memory"); + fatal(ptx, "Cannot allocate memory"); goto errgst; } @@ -48,11 +48,11 @@ char *pcp_getstdin(const char *prompt) { } 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; } - if(pcpvault_addkey(vault, key, key->type) == 0) { + if(pcpvault_addkey(ptx, vault, key, key->type) == 0) { if(vault->isnew) fprintf(stderr, "new vault created, "); 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) - key = pcpkey_encrypt(k, passphrase); + key = pcpkey_encrypt(ptx, k, passphrase); else { char *yes = pcp_getstdin("WARNING: secret key will be stored unencrypted. Are you sure [yes|NO]?"); if(strncmp(yes, "yes", 1024) == 0) @@ -117,22 +117,22 @@ void pcp_keygen(char *passwd) { void pcp_listkeys() { 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) { printf("Key ID Type Creation Time Owner\n"); - pcphash_iterate(k) { + pcphash_iterate(ptx, k) { pcpkey_printlineinfo(k); } pcp_pubkey_t *p; - pcphash_iteratepub(p) { + pcphash_iteratepub(ptx, p) { pcppubkey_printlineinfo(p); } } 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); } 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); return NULL; } 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); return NULL; } @@ -163,7 +163,7 @@ char *pcp_normalize_id(char *keyid) { id[16] = 0; } else { - fatal("Specified key id %s is too long!\n", keyid); + fatal(ptx, "Specified key id %s is too long!\n", keyid); free(id); return NULL; } @@ -175,7 +175,7 @@ char *pcp_normalize_id(char *keyid) { pcp_key_t *pcp_find_primary_secret() { pcp_key_t *key = NULL; pcp_key_t *k; - pcphash_iterate(k) { + pcphash_iterate(ptx, k) { if(k->type == PCP_KEY_TYPE_MAINSECRET) { key = ucmalloc(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 */ - int nkeys = HASH_COUNT(pcpkey_hash); + int nkeys = pcphash_count(ptx); if(nkeys == 1) { - pcphash_iterate(k) { + pcphash_iterate(ptx, k) { key = ucmalloc(sizeof(pcp_key_t)); memcpy(key, k, sizeof(pcp_key_t)); return key; @@ -201,9 +201,9 @@ void pcp_exportsecret(char *keyid, int useid, char *outfile, int armor, char *pa if(useid == 1) { /* look if we've got that one */ - HASH_FIND_STR(pcpkey_hash, keyid, key); + key = pcphash_keyexists(ptx, keyid); 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; } } @@ -211,7 +211,7 @@ void pcp_exportsecret(char *keyid, int useid, char *outfile, int armor, char *pa /* look for our primary key */ key = pcp_find_primary_secret(); 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; } } @@ -222,7 +222,7 @@ void pcp_exportsecret(char *keyid, int useid, char *outfile, int armor, char *pa } else { 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; } } @@ -237,7 +237,7 @@ void pcp_exportsecret(char *keyid, int useid, char *outfile, int armor, char *pa char *passphrase; pcp_readpass(&passphrase, "Enter passphrase to decrypt your secret key", NULL, 1); - key = pcpkey_decrypt(key, passphrase); + key = pcpkey_decrypt(ptx, key, passphrase); if(key == NULL) { memset(passphrase, 0, strlen(passphrase)); free(passphrase); @@ -247,7 +247,7 @@ void pcp_exportsecret(char *keyid, int useid, char *outfile, int armor, char *pa free(passphrase); } else { - key = pcpkey_decrypt(key, passwd); + key = pcpkey_decrypt(ptx, key, passwd); if(key == NULL) { goto errexpse1; } @@ -257,13 +257,13 @@ void pcp_exportsecret(char *keyid, int useid, char *outfile, int armor, char *pa Buffer *exported_sk; if(passwd != NULL) { - exported_sk = pcp_export_secret(key, passwd); + exported_sk = pcp_export_secret(ptx, key, passwd); } else { char *passphrase; pcp_readpass(&passphrase, "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)); free(passphrase); } @@ -307,19 +307,19 @@ void pcp_exportpublic(char *keyid, char *passwd, char *outfile, int format, int } else { 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; } } if(keyid != NULL) { /* 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) { /* 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) { - 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); goto errpcpexpu1; } @@ -337,7 +337,7 @@ void pcp_exportpublic(char *keyid, char *passwd, char *outfile, int format, int /* we use our primary key anyway */ sk = pcp_find_primary_secret(); 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; } 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) { /* decrypt the secret key */ if(passwd != NULL) { - sk = pcpkey_decrypt(sk, passwd); + sk = pcpkey_decrypt(ptx, sk, passwd); } else { char *passphrase; pcp_readpass(&passphrase, "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)); free(passphrase); } @@ -381,7 +381,7 @@ void pcp_exportpublic(char *keyid, char *passwd, char *outfile, int format, int } else { /* 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; } } @@ -399,7 +399,7 @@ void pcp_exportpublic(char *keyid, char *passwd, char *outfile, int format, int } } else { - fatal("Exporting foreign public keys in PBP format not possible"); + fatal(ptx, "Exporting foreign public keys in PBP format not possible"); goto errpcpexpu1; } } @@ -429,38 +429,38 @@ void pcp_exportpublic(char *keyid, char *passwd, char *outfile, int format, int void pcpdelete_key(char *keyid) { - pcp_pubkey_t *p = pcphash_pubkeyexists(keyid); + pcp_pubkey_t *p = pcphash_pubkeyexists(ptx, keyid); if(p != NULL) { /* delete public */ - HASH_DEL(pcppubkey_hash, p); + pcphash_del(ptx, p, p->type); free(p); vault->unsafed = 1; fprintf(stderr, "Public key deleted.\n"); } else { - pcp_key_t *s = pcphash_keyexists(keyid); + pcp_key_t *s = pcphash_keyexists(ptx, keyid); if(s != NULL) { /* delete secret */ - HASH_DEL(pcpkey_hash, s); + pcphash_del(ptx, s, s->type); free(s); vault->unsafed = 1; fprintf(stderr, "Secret key deleted.\n"); } 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) { - pcp_key_t *key = pcphash_keyexists(keyid); + pcp_key_t *key = pcphash_keyexists(ptx, keyid); if(key != NULL) { if(key->secret[0] == 0) { char *passphrase; 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)); } @@ -481,7 +481,7 @@ void pcpedit_key(char *keyid) { if(key->type != PCP_KEY_TYPE_MAINSECRET) { pcp_key_t *other = NULL; uint8_t haveprimary = 0; - pcphash_iterate(other) { + pcphash_iterate(ptx, other) { if(other->type == PCP_KEY_TYPE_MAINSECRET) { haveprimary = 1; break; @@ -515,7 +515,7 @@ void pcpedit_key(char *keyid) { "Enter the passphrase again", 1); if(strnlen(passphrase, 1024) > 0) { - key = pcpkey_encrypt(key, passphrase); + key = pcpkey_encrypt(ptx, key, passphrase); ucfree(passphrase, strlen(passphrase)); } @@ -529,7 +529,7 @@ void pcpedit_key(char *keyid) { } } 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; char *id = NULL; _lc(recipient); - pcphash_iteratepub(p) { + pcphash_iteratepub(ptx, p) { if(strncmp(p->owner, recipient, 255) == 0) { id = ucmalloc(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); if(bufsize == 0) { - fatal("Input file is empty!\n"); + fatal(ptx, "Input file is empty!\n"); goto errimp1; } /* first try as rfc pub key */ - bundle = pcp_import_binpub(buf, bufsize); + bundle = pcp_import_binpub(ptx, buf, bufsize); if(bundle != NULL) { keysig = bundle->s; pub = bundle->p; @@ -583,7 +583,7 @@ int pcp_import (vault_t *vault, FILE *in, char *passwd) { pcp_dumppubkey(pub); if(keysig == NULL) { - fatals_ifany(); + fatals_ifany(ptx); char *yes = pcp_getstdin("WARNING: signature doesn't verify, import anyway [yes|NO]?"); if(strncmp(yes, "yes", 1024) != 0) { free(yes); @@ -592,8 +592,8 @@ int pcp_import (vault_t *vault, FILE *in, char *passwd) { free(yes); } - if(pcp_sanitycheck_pub(pub) == 0) { - if(pcpvault_addkey(vault, (void *)pub, PCP_KEY_TYPE_PUBLIC) == 0) { + if(pcp_sanitycheck_pub(ptx, pub) == 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); /* avoid double free */ pub = NULL; @@ -603,7 +603,7 @@ int pcp_import (vault_t *vault, FILE *in, char *passwd) { goto errimp2; 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 */ goto errimp2; } @@ -616,13 +616,13 @@ int pcp_import (vault_t *vault, FILE *in, char *passwd) { else { /* it's not public key, so let's try to interpret it as secret key */ if(passwd != NULL) { - sk = pcp_import_secret(buf, bufsize, passwd); + sk = pcp_import_secret(ptx, buf, bufsize, passwd); } else { char *passphrase; pcp_readpass(&passphrase, "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)); } @@ -633,15 +633,15 @@ int pcp_import (vault_t *vault, FILE *in, char *passwd) { if(debug) pcp_dumpkey(sk); - pcp_key_t *maybe = pcphash_keyexists(sk->id); + pcp_key_t *maybe = pcphash_keyexists(ptx, sk->id); 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; } /* store it */ if(passwd != NULL) { - sk = pcpkey_encrypt(sk, passwd); + sk = pcpkey_encrypt(ptx, sk, passwd); } else { char *passphrase; @@ -651,7 +651,7 @@ int pcp_import (vault_t *vault, FILE *in, char *passwd) { if(strnlen(passphrase, 1024) > 0) { /* encrypt the key */ - sk = pcpkey_encrypt(sk, passphrase); + sk = pcpkey_encrypt(ptx, sk, passphrase); ucfree(passphrase, strlen(passphrase)); } else { @@ -668,7 +668,7 @@ int pcp_import (vault_t *vault, FILE *in, char *passwd) { if(sk != NULL) { /* 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) { pcpkey_printshortinfo(sk); success = 0; diff --git a/src/keymgmt.h b/src/keymgmt.h index d53b312..de506ae 100644 --- a/src/keymgmt.h +++ b/src/keymgmt.h @@ -42,6 +42,7 @@ #include "base85.h" #include "buffer.h" #include "mgmt.h" +#include "context.h" #define _WITH_GETLINE diff --git a/src/keyprint.c b/src/keyprint.c index e9cf2c9..b6c1463 100644 --- a/src/keyprint.c +++ b/src/keyprint.c @@ -28,7 +28,7 @@ int pcptext_infile(char *infile) { int insize; 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; } @@ -42,7 +42,7 @@ int pcptext_infile(char *infile) { } /* maybe a vault? */ - vault_t *v = pcpvault_init(infile); + vault_t *v = pcpvault_init(ptx, infile); if(v != NULL) { fprintf(stdout, "%s is a vault file\n", infile); pcptext_vault(v); @@ -50,14 +50,14 @@ int pcptext_infile(char *infile) { } /* try z85ing it */ - char *z85 = pcp_readz85file(in); + char *z85 = pcp_readz85file(ptx, in); if(z85 == NULL) { fprintf(stdout, "Can't handle %s - unknown file type.\n", infile); goto errtinf1; } size_t clen; - byte *bin = pcp_z85_decode((char *)z85, &clen); + byte *bin = pcp_z85_decode(ptx, (char *)z85, &clen); free(z85); 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); tdone: - fatals_reset(); + fatals_reset(ptx); return 0; errtinf1: - fatals_reset(); + fatals_reset(ptx); return 1; } void pcptext_key(char *keyid) { - pcp_key_t *s = pcphash_keyexists(keyid); + pcp_key_t *s = pcphash_keyexists(ptx, keyid); if(s != NULL) { if(debug) pcp_dumpkey(s); pcpkey_print(s, stdout); } else { - pcp_pubkey_t *p = pcphash_pubkeyexists(keyid); + pcp_pubkey_t *p = pcphash_pubkeyexists(ptx, keyid); if(p != NULL) { if(debug) pcp_dumppubkey(p); pcppubkey_print(p, stdout); } 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("\n"); - printf(" Secret keys: %d\n", HASH_COUNT(pcpkey_hash)); - printf(" Public keys: %d\n", HASH_COUNT(pcppubkey_hash)); + printf(" Secret keys: %d\n", pcphash_count(ptx)); + printf(" Public keys: %d\n", pcphash_countpub(ptx) ); } 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, key->owner, key->mail); - if(PCPVERBOSE) { + if(ptx->verbose) { printf(" "); byte *hash = pcpkey_getchecksum(key); int i, y; @@ -157,7 +157,7 @@ void pcppubkey_printlineinfo(pcp_pubkey_t *key) { c->tm_hour, c->tm_min, c->tm_sec, key->owner, key->mail); - if(PCPVERBOSE) { + if(ptx->verbose) { printf(" "); byte *hash = pcppubkey_getchecksum(key); int i, y; @@ -171,7 +171,7 @@ void pcppubkey_printlineinfo(pcp_pubkey_t *key) { printf("\n signed: %s, serial: %08x, version: %d, ", (key->valid == 1) ? "yes" : " no", 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) { printf("signature fingerprint:\n "); byte *checksum = sig->checksum; @@ -305,7 +305,7 @@ void pcpexport_yaml(char *outfile) { } else { 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; } } @@ -325,7 +325,7 @@ void pcpexport_yaml(char *outfile) { fprintf(out, "---\n"); fprintf(out, "secret-keys:\n"); - pcphash_iterate(s) { + pcphash_iterate(ptx, s) { fprintf(out, " -\n"); fprintf(out, " id: %s\n", s->id); fprintf(out, " owner: %s\n", s->owner); @@ -350,7 +350,7 @@ void pcpexport_yaml(char *outfile) { } fprintf(out, "public-keys:\n"); - pcphash_iteratepub(p) { + pcphash_iteratepub(ptx, p) { fprintf(out, " -\n"); fprintf(out, " id: %s\n", p->id); fprintf(out, " owner: %s\n", p->owner); diff --git a/src/keyprint.h b/src/keyprint.h index a594265..4bf2974 100644 --- a/src/keyprint.h +++ b/src/keyprint.h @@ -30,6 +30,7 @@ #include "keymgmt.h" #include "keyhash.h" #include "base85.h" +#include "context.h" void pcpkey_print(pcp_key_t *key, FILE *out); void pcppubkey_print(pcp_pubkey_t *key, FILE *out); diff --git a/src/pcp.c b/src/pcp.c index b045313..41bae68 100644 --- a/src/pcp.c +++ b/src/pcp.c @@ -58,7 +58,6 @@ int main (int argc, char **argv) { plist_t *recipient = NULL; FILE *in; - PCP_EXIT = 0; errno = 0; debug = 0; mode = 0; @@ -71,7 +70,7 @@ int main (int argc, char **argv) { signcrypt = 0; exportformat = EXP_FORMAT_NATIVE; - PCPVERBOSE = 0; + ptx = ptx_new(); static struct option longopts[] = { /* generics */ @@ -138,7 +137,7 @@ int main (int argc, char **argv) { usevault = 1; break; case 'L': - PCPVERBOSE = 1; /* no break by purpose, turn on -l */ + ptx->verbose = 1; /* no break by purpose, turn on -l */ case 'l': mode += PCP_MODE_LISTKEYS; usevault = 1; @@ -268,7 +267,7 @@ int main (int argc, char **argv) { case '0': version(); case 'v': - PCPVERBOSE = 1; + ptx->verbose = 1; break; case 'h': usage(0); @@ -280,7 +279,6 @@ int main (int argc, char **argv) { argc -= optind; argv += optind; - if(mode == 0) { /* turn -z|-Z into a mode if there's nothing else specified */ if(armor == 1) { @@ -390,8 +388,7 @@ int main (int argc, char **argv) { } if(usevault == 1) { - pcphash_init(); - vault = pcpvault_init(vaultfile); + vault = pcpvault_init(ptx, vaultfile); if(vault != NULL) { switch (mode) { case PCP_MODE_KEYGEN: @@ -435,7 +432,7 @@ int main (int argc, char **argv) { in = stdin; else { 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); break; } @@ -452,7 +449,7 @@ int main (int argc, char **argv) { } } else { - fatal("You need to specify a key id (--keyid)!\n"); + fatal(ptx, "You need to specify a key id (--keyid)!\n"); } break; @@ -465,7 +462,7 @@ int main (int argc, char **argv) { } } else { - fatal("You need to specify a key id (--keyid)!\n"); + fatal(ptx, "You need to specify a key id (--keyid)!\n"); } break; @@ -481,7 +478,7 @@ int main (int argc, char **argv) { } else { /* -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) free(id); @@ -510,7 +507,7 @@ int main (int argc, char **argv) { case PCP_MODE_SIGN: if(detach) { 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 pcpsign(infile, sigfile, xpass, armor, detach); } @@ -540,8 +537,7 @@ int main (int argc, char **argv) { goto ELSEMODE; break; } - pcpvault_close(vault); - pcphash_clean(); + pcpvault_close(ptx, vault); free(vaultfile); } } @@ -565,8 +561,7 @@ int main (int argc, char **argv) { pcptext_infile(infile); } else { - pcphash_init(); - vault = pcpvault_init(vaultfile); + vault = pcpvault_init(ptx, vaultfile); if(! useid && infile == NULL) { pcptext_vault(vault); } @@ -577,21 +572,20 @@ int main (int argc, char **argv) { free(id); } } - pcpvault_close(vault); - pcphash_clean(); + pcpvault_close(ptx, vault); free(vaultfile); } break; default: /* 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; } } - fatals_ifany(); - fatals_done(); - return PCP_EXIT; - + fatals_ifany(ptx); + int e = ptx->pcp_exit; + ptx_clean(ptx); + return e; } diff --git a/src/pcp.h b/src/pcp.h index ee6702e..fb44e43 100644 --- a/src/pcp.h +++ b/src/pcp.h @@ -39,6 +39,7 @@ #include "z85util.h" #include "version.h" #include "vault.h" +#include "context.h" /* subs */ #include "keymgmt.h" @@ -80,7 +81,9 @@ #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" +/* some globals */ vault_t *vault; +PCPCTX *ptx; int debug; void version(); diff --git a/src/readpass.c b/src/readpass.c index f2f1f0e..610a9bf 100644 --- a/src/readpass.c +++ b/src/readpass.c @@ -58,13 +58,13 @@ pcp_readpass(char ** passwd, const char * prompt, /* If we're reading from a terminal, try to disable echo. */ if ((usingtty = isatty(fileno(readfrom))) != 0) { if (tcgetattr(fileno(readfrom), &term_old)) { - fatal("Cannot read terminal settings"); + fatal(ptx, "Cannot read terminal settings"); goto err1; } memcpy(&term, &term_old, sizeof(struct termios)); term.c_lflag = (term.c_lflag & ~ECHO) | ECHONL; if (tcsetattr(fileno(readfrom), TCSANOW, &term)) { - fatal("Cannot set terminal settings"); + fatal(ptx, "Cannot set terminal settings"); goto err1; } } @@ -76,7 +76,7 @@ retry: /* Read the password. */ if (fgets(passbuf, MAXPASSLEN, readfrom) == NULL) { - fatal("Cannot read password"); + fatal(ptx, "Cannot read password"); goto err2; } @@ -85,7 +85,7 @@ retry: if (usingtty) fprintf(stderr, "%s: ", confirmprompt); if (fgets(confpassbuf, MAXPASSLEN, readfrom) == NULL) { - fatal("Cannot read password"); + fatal(ptx, "Cannot read password"); goto err2; } if (strcmp(passbuf, confpassbuf)) { @@ -108,7 +108,7 @@ retry: /* Copy the password out. */ if ((*passwd = strdup(passbuf)) == NULL) { - fatal("Cannot allocate memory"); + fatal(ptx, "Cannot allocate memory"); goto err1; } diff --git a/src/readpass.h b/src/readpass.h index cc071b1..ee5d5f0 100644 --- a/src/readpass.h +++ b/src/readpass.h @@ -36,6 +36,8 @@ #include #include "defines.h" +#include "context.h" +#include "pcp.h" #define MAXPASSLEN 2048 diff --git a/src/signature.c b/src/signature.c index 194b2b4..358be84 100644 --- a/src/signature.c +++ b/src/signature.c @@ -32,7 +32,7 @@ int pcpsign(char *infile, char *outfile, char *passwd, int z85, int detach) { secret = pcp_find_primary_secret(); 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; } @@ -40,7 +40,7 @@ int pcpsign(char *infile, char *outfile, char *passwd, int z85, int detach) { in = stdin; else { 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; } } @@ -49,7 +49,7 @@ int pcpsign(char *infile, char *outfile, char *passwd, int z85, int detach) { out = stdout; else { 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; } } @@ -66,7 +66,7 @@ int pcpsign(char *infile, char *outfile, char *passwd, int z85, int detach) { strncpy(passphrase, passwd, strlen(passwd)+1); } - secret = pcpkey_decrypt(secret, passphrase); + secret = pcpkey_decrypt(ptx, secret, passphrase); if(secret == NULL) goto errs1; } @@ -78,7 +78,7 @@ int pcpsign(char *infile, char *outfile, char *passwd, int z85, int detach) { if(detach == 1) sigsize = pcp_ed_detachsign_buffered(pin, pout, secret); 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(pout); @@ -103,30 +103,30 @@ int pcpverify(char *infile, char *sigfile, char *id, int detach) { in = stdin; else { 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; } } if(sigfile != 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; } } if(id != NULL) - HASH_FIND_STR(pcppubkey_hash, id, pub); + pub = pcphash_pubkeyexists(ptx, id); Pcpstream *pin = ps_new_file(in); if(detach) { 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); } else - pub = pcp_ed_verify_buffered(pin, pub); + pub = pcp_ed_verify_buffered(ptx, pin, pub); ps_close(pin); diff --git a/src/signature.h b/src/signature.h index 4a055d6..5e047d9 100644 --- a/src/signature.h +++ b/src/signature.h @@ -32,6 +32,7 @@ #include "uthash.h" #include "z85.h" #include "pcpstream.h" +#include "context.h" int pcpsign(char *infile, char *outfile, char *passwd, int z85, int detach); int pcpverify(char *infile, char *sigfile, char *id, int detach); diff --git a/src/z85util.c b/src/z85util.c index f786def..214c31e 100644 --- a/src/z85util.c +++ b/src/z85util.c @@ -30,7 +30,7 @@ int pcpz85_encode(char *infile, char *outfile) { in = stdin; else { 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; } } @@ -39,7 +39,7 @@ int pcpz85_encode(char *infile, char *outfile) { out = stdout; else { 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; } } @@ -59,7 +59,7 @@ int pcpz85_encode(char *infile, char *outfile) { fclose(in); if(inputBufSize == 0) { - fatal("Input file is empty!\n"); + fatal(ptx, "Input file is empty!\n"); goto errz2; } @@ -69,7 +69,7 @@ int pcpz85_encode(char *infile, char *outfile) { if(encoded != NULL) { fprintf(out, "%s\n%s\n%s\n", PCP_ZFILE_HEADER, encoded, PCP_ZFILE_FOOTER); if(ferror(out) != 0) { - fatal("Failed to write z85 output!\n"); + fatal(ptx, "Failed to write z85 output!\n"); } free(encoded); goto errz2; @@ -95,7 +95,7 @@ int pcpz85_decode(char *infile, char *outfile) { in = stdin; else { 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; } } @@ -104,18 +104,18 @@ int pcpz85_decode(char *infile, char *outfile) { out = stdout; else { 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; } } - char *encoded = pcp_readz85file(in); + char *encoded = pcp_readz85file(ptx, in); if(encoded == NULL) goto errdz1; 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); fclose(out); if(ferror(out) != 0) { - fatal("Failed to write decoded output!\n"); + fatal(ptx, "Failed to write decoded output!\n"); goto errdz3; } diff --git a/src/z85util.h b/src/z85util.h index e79ba78..40eaeb2 100644 --- a/src/z85util.h +++ b/src/z85util.h @@ -35,6 +35,9 @@ #include "z85.h" #include "zmq_z85.h" #include "defines.h" +#include "context.h" + +extern PCPCTX *ptx; int pcpz85_encode(char *infile, char *outfile); int pcpz85_decode(char *infile, char *outfile);