mirror of
https://codeberg.org/scip/pcp.git
synced 2025-12-17 03:50:57 +01:00
put previously global error handling and key hashes into ptx (pcp context) to make libpcp threadsafe.
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -30,14 +30,17 @@
|
||||
#include <stdexcept>
|
||||
#include <iostream>
|
||||
|
||||
#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; }
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#include <iostream>
|
||||
|
||||
#include "key++.h"
|
||||
#include "ptx++.h"
|
||||
#include "vault++.h"
|
||||
#include "crypto++.h"
|
||||
#include "sign++.h"
|
||||
|
||||
48
bindings/cpp/ptx++.h
Normal file
48
bindings/cpp/ptx++.h
Normal file
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
This file is part of Pretty Curved Privacy (pcp1).
|
||||
|
||||
Copyright (C) 2013 T.Linden.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
You can contact me by mail: <tlinden AT cpan DOT org>.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _HAVE_PCPPP_PTX_H
|
||||
#define _HAVE_PCPPP_PTX_H
|
||||
|
||||
#include <pcp.h>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
|
||||
#include "helpers++.h"
|
||||
|
||||
namespace pcp {
|
||||
|
||||
class PcpContext {
|
||||
public:
|
||||
PCPCTX *ptx;
|
||||
|
||||
// constructors
|
||||
PcpContext();
|
||||
|
||||
// destructors
|
||||
~PcpContext();
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
#endif // _HAVE_PCPPP_PTX_H
|
||||
34
bindings/cpp/ptx.cpp
Normal file
34
bindings/cpp/ptx.cpp
Normal file
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
This file is part of Pretty Curved Privacy (pcp1).
|
||||
|
||||
Copyright (C) 2013 T.Linden.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
You can contact me by mail: <tlinden AT cpan DOT org>.
|
||||
*/
|
||||
|
||||
#include "pcp++.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace pcp;
|
||||
|
||||
PcpContext::PcpContext() {
|
||||
ptx = ptx_new();
|
||||
}
|
||||
|
||||
PcpContext::~PcpContext() {
|
||||
ptx_clean(ptx);
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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<unsigned char> 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<unsigned char> 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<unsigned char> 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<unsigned char> 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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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<std::string, Key> Vault::keys() {
|
||||
std::map<std::string, Key> kmap;
|
||||
|
||||
pcp_key_t *k = NULL;
|
||||
pcphash_iterate(k) {
|
||||
kmap.insert ( pair<string,Key>(string(k->id), Key(k, true)) );
|
||||
pcphash_iterate(PTX.ptx, k) {
|
||||
kmap.insert ( pair<string,Key>(string(k->id), Key(PTX, k, true)) );
|
||||
}
|
||||
|
||||
return kmap;
|
||||
@@ -55,39 +59,39 @@ std::map<std::string, PubKey> Vault::pubkeys() {
|
||||
std::map<std::string, PubKey> kmap;
|
||||
|
||||
pcp_pubkey_t *k = NULL;
|
||||
pcphash_iteratepub(k) {
|
||||
kmap.insert ( pair<string,PubKey>(string(k->id), PubKey(k, true)) );
|
||||
pcphash_iteratepub(PTX.ptx, k) {
|
||||
kmap.insert ( pair<string,PubKey>(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.");
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -12,6 +12,7 @@ Licensed under the terms of the LGPL 2.1.
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#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 */
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
95
include/pcp/context.h
Normal file
95
include/pcp/context.h
Normal file
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
This file is part of Pretty Curved Privacy (pcp1).
|
||||
|
||||
Copyright (C) 2013-2014 T.v.Dein.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
You can contact me by mail: <tom AT vondein DOT org>.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _HAVE_PCP_CONTEXT_H
|
||||
#define _HAVE_PCP_CONTEXT_H
|
||||
|
||||
#include "defines.h"
|
||||
#include "platform.h"
|
||||
#include "uthash.h"
|
||||
#include "structs.h"
|
||||
#include "mem.h"
|
||||
#include "keyhash.h"
|
||||
|
||||
/**
|
||||
* \defgroup CONTEXT CONTEXT
|
||||
* @{
|
||||
|
||||
A couple of context functions to catch errors and display them.
|
||||
The context also holds the key hashes.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
/** Create a new PCP Context.
|
||||
|
||||
Sets all context pointers to NULL.
|
||||
|
||||
\return the context object.
|
||||
*/
|
||||
PCPCTX *ptx_new();
|
||||
|
||||
|
||||
/** Frees the memory allocated by the context.
|
||||
|
||||
\param[in] PCP Context object.
|
||||
*/
|
||||
void ptx_clean(PCPCTX *ptx);
|
||||
|
||||
|
||||
/** Set an error message.
|
||||
|
||||
This function gets a printf() like error message,
|
||||
which it stores in the global PCP_ERR variable
|
||||
and sets PCP_ERRSET to 1.
|
||||
|
||||
\param[in] PCP Context object.
|
||||
|
||||
\param[in] fmt printf() like format description.
|
||||
|
||||
\param[in] ... format parameters, if any.
|
||||
*/
|
||||
void fatal(PCPCTX *ptx, const char * fmt, ...);
|
||||
|
||||
/** Prints error messages to STDERR, if there are some.
|
||||
|
||||
FIXME: add something like this which returns the
|
||||
message.
|
||||
|
||||
\param[in] PCP Context object.
|
||||
*/
|
||||
void fatals_ifany(PCPCTX *ptx);
|
||||
|
||||
/** Reset the error variables.
|
||||
|
||||
This can be used to ignore previous errors.
|
||||
Use with care.
|
||||
|
||||
\param[in] PCP Context object.
|
||||
*/
|
||||
void fatals_reset(PCPCTX *ptx);
|
||||
|
||||
/* same as fatal() but dies immediately */
|
||||
void final(const char * fmt, ...);
|
||||
|
||||
|
||||
#endif // _HAVE_PCP_CONTEXT_H
|
||||
@@ -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);
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 <a href="http://troydhanson.github.io/uthash/">uthash</a>
|
||||
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 */
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -26,8 +26,10 @@
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#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);
|
||||
|
||||
@@ -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 */
|
||||
|
||||
|
||||
384
include/pcp/structs.h
Normal file
384
include/pcp/structs.h
Normal file
@@ -0,0 +1,384 @@
|
||||
/*
|
||||
This file is part of Pretty Curved Privacy (pcp1).
|
||||
|
||||
Copyright (C) 2013-2014 T.v.Dein.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
You can contact me by mail: <tom AT vondein DOT org>.
|
||||
*/
|
||||
|
||||
#ifndef _HAVE_PCP_STRUCTS_H
|
||||
#define _HAVE_PCP_STRUCTS_H
|
||||
|
||||
#include "defines.h"
|
||||
#include "uthash.h"
|
||||
#include <sodium.h>
|
||||
|
||||
/**
|
||||
\addtogroup KEYS
|
||||
@{
|
||||
*/
|
||||
|
||||
/** \struct _pcp_key_t
|
||||
|
||||
PCP private key structure. Most fields are self explanatory.
|
||||
|
||||
Some notes:
|
||||
|
||||
'encrypted' contains the encrypted secret keys (contatenated mastersecret,
|
||||
secret and edsecret). If it's set,
|
||||
the field 'secret' which contains the clear secret key will
|
||||
be zeroed with random values, the first byte will be 0. Same
|
||||
for the field 'edsecret'.
|
||||
|
||||
'nonce' contains the nonce required to decrypt the encrypted
|
||||
secret, if set.
|
||||
|
||||
'serial' is a random number.
|
||||
|
||||
'id' is a string containing the hex values of the CRC32 checksum
|
||||
of the public and secret key.
|
||||
|
||||
Upon creation everything will be filled with random bytes.
|
||||
String fields will contain a string followed by 0 followed
|
||||
by the rest of the pre-filled random bytes. To denote a string
|
||||
field as empty, the first byte will be set to 0.
|
||||
|
||||
There are dynamically calculated attributes as well:
|
||||
|
||||
'checksum' is a 256 bit SHA hash of the public key returned
|
||||
by pcpkey_getchecksum() or pcppubkey_getchecksum().
|
||||
|
||||
'random id' is a random art ascii image returned by
|
||||
pcppubkey_get_art() or pcpkey_get_art(), calculated from
|
||||
the public key.
|
||||
|
||||
If exported to a single file or printed, the structure will
|
||||
be encoded using Z85 encoding.
|
||||
|
||||
*/
|
||||
struct _pcp_key_t {
|
||||
byte masterpub[32]; /**< ED25519 master public key signing key */
|
||||
byte mastersecret[64]; /**< ED25519 master secret key signing key */
|
||||
byte pub[32]; /**< Curve25519 encryption public key */
|
||||
byte secret[32]; /**< Curve25519 encryption secret key */
|
||||
byte edpub[32]; /**< ED25519 public signing key */
|
||||
byte edsecret[64]; /**< ED25519 secret signing key */
|
||||
byte nonce[24]; /**< random nonce used to encrypt secret keys */
|
||||
byte encrypted[176]; /**< concatenated and encrypted secret keys */
|
||||
char owner[255]; /**< the key owner, string */
|
||||
char mail[255]; /**< mail address of the owner, string */
|
||||
char id[17]; /**< key-id, used internally only, jenhash of public keys */
|
||||
uint8_t type; /**< key type: MASTER_SECRET or SECRET */
|
||||
uint64_t ctime; /**< creation time, epoch */
|
||||
uint32_t version; /**< key version */
|
||||
uint32_t serial; /**< serial number of the key, randomly generated */
|
||||
UT_hash_handle hh;
|
||||
};
|
||||
|
||||
/** Typedef for secret keys */
|
||||
typedef struct _pcp_key_t pcp_key_t;
|
||||
|
||||
/** \struct _pcp_pubkey_t
|
||||
|
||||
PCP public key structure.
|
||||
|
||||
This structure contains a subset of the pcp_key_t structure
|
||||
without the secret and nonce fields.
|
||||
*/
|
||||
struct _pcp_pubkey_t {
|
||||
byte masterpub[32]; /**< ED25519 master public key signing key */
|
||||
byte sigpub[32]; /**< ED25519 public signing key */
|
||||
byte pub[32]; /**< Curve25519 encryption public key */
|
||||
byte edpub[32]; /**< ED25519 public signing key (FIXME: huh? 2 of them???) */
|
||||
char owner[255]; /**< the key owner, string */
|
||||
char mail[255]; /**< mail address of the owner, string */
|
||||
char id[17]; /**< key-id, used internally only, jenhash of public keys */
|
||||
uint8_t type; /**< key type: MASTER_SECRET or SECRET */
|
||||
uint64_t ctime; /**< creation time, epoch */
|
||||
uint32_t version; /**< key version */
|
||||
uint32_t serial; /**< serial number of the key, randomly generated */
|
||||
uint8_t valid; /**< 1 if import signature verified, 0 if not */
|
||||
byte signature[crypto_generichash_BYTES_MAX + crypto_sign_BYTES]; /**< raw binary blob of pubkey export signature */
|
||||
UT_hash_handle hh;
|
||||
};
|
||||
|
||||
/** Typedef for public keys */
|
||||
typedef struct _pcp_pubkey_t pcp_pubkey_t;
|
||||
|
||||
|
||||
/* the PBP public key format */
|
||||
/* keys.mp+keys.cp+keys.sp+keys.name */
|
||||
struct _pbp_pubkey_t {
|
||||
byte sigpub[crypto_sign_PUBLICKEYBYTES];
|
||||
byte edpub[crypto_sign_PUBLICKEYBYTES];
|
||||
byte pub[crypto_box_PUBLICKEYBYTES];
|
||||
char iso_ctime[32];
|
||||
char iso_expire[32];
|
||||
char name[1024];
|
||||
};
|
||||
|
||||
typedef struct _pbp_pubkey_t pbp_pubkey_t;
|
||||
|
||||
/** \struct _pcp_rec_t
|
||||
|
||||
Encrypted recipient list.
|
||||
|
||||
Encrypted recipient list, required for crypt+sign
|
||||
contains the encrypted recipients and the secret
|
||||
key required for signing the message+recipients.
|
||||
|
||||
Used internally only.
|
||||
*/
|
||||
struct _pcp_rec_t {
|
||||
size_t ciphersize; /**< the size of the encrypted recipient list */
|
||||
byte *cipher; /**< contains the whole encrypted recipient list */
|
||||
pcp_key_t *secret; /**< the secret key of the recipient for signing */
|
||||
pcp_pubkey_t *pub; /**< if verification were ok, contains the public key of the signer */
|
||||
};
|
||||
|
||||
/** Typedef for public keys */
|
||||
typedef struct _pcp_rec_t pcp_rec_t;
|
||||
|
||||
|
||||
/* holds a public key signature */
|
||||
struct _pcp_keysig_t {
|
||||
uint8_t type;
|
||||
uint32_t size;
|
||||
char id[17];
|
||||
byte checksum[32];
|
||||
byte *blob;
|
||||
UT_hash_handle hh;
|
||||
};
|
||||
|
||||
typedef struct _pcp_keysig_t pcp_keysig_t;
|
||||
|
||||
/** @}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
\addtogroup CONTEXT
|
||||
@{
|
||||
*/
|
||||
|
||||
|
||||
/** \struct _pcp_ctx_t
|
||||
|
||||
PCP context object.
|
||||
|
||||
Holds error state and key hashes.
|
||||
*/
|
||||
|
||||
struct _pcp_ctx_t {
|
||||
char *pcp_err; /**< last error message. retrieve with fatals_ifany() */
|
||||
byte pcp_errset; /**< indicates if an error occurred. */
|
||||
int pcp_exit; /**< exit code for pcp commandline utility */
|
||||
int verbose; /**< enable verbose output */
|
||||
|
||||
pcp_key_t *pcpkey_hash; /**< hash containing for keys */
|
||||
pcp_pubkey_t *pcppubkey_hash; /**< hash for keys. */
|
||||
pcp_keysig_t *pcpkeysig_hash; /**< hash for key sigs */
|
||||
};
|
||||
|
||||
typedef struct _pcp_ctx_t PCPCTX;
|
||||
|
||||
/** @}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
\addtogroup VAULT
|
||||
@{
|
||||
*/
|
||||
|
||||
/** \struct _vault_t
|
||||
This structure represents a vault. */
|
||||
struct _vault_t {
|
||||
char *filename; /**< The filename of the vault (full path) */
|
||||
FILE *fd; /**< Filehandle if opened */
|
||||
uint8_t unsafed; /**< Flag to tell if the file needs to be written */
|
||||
uint8_t isnew; /**< Flag to tell if the vault has been newly created */
|
||||
uint32_t size; /**< Filesize */
|
||||
time_t modified; /**< mtime */
|
||||
mode_t mode; /**< File mode */
|
||||
uint32_t version; /**< Vault version */
|
||||
byte checksum[32]; /**< SHA256 checksum over the whole vault */
|
||||
};
|
||||
|
||||
/** Name of the struct */
|
||||
typedef struct _vault_t vault_t;
|
||||
|
||||
/** \struct _vault_header_t
|
||||
Defines the vault header. */
|
||||
struct _vault_header_t {
|
||||
uint8_t fileid; /**< File id, proprietary. Marks the vault as a vault */
|
||||
uint32_t version; /**< File version */
|
||||
byte checksum[32]; /**< SHA256 checksum over the whole vault */
|
||||
};
|
||||
|
||||
/** Name of the struct */
|
||||
typedef struct _vault_header_t vault_header_t;
|
||||
|
||||
/** \struct _vault_item_header_t
|
||||
An item header. */
|
||||
struct _vault_item_header_t {
|
||||
uint8_t type; /**< Item type (secret key, public, key, keysig, \see _PCP_KEY_TYPES */
|
||||
uint32_t size; /**< Size of the item */
|
||||
uint32_t version; /**< Version of the item */
|
||||
byte checksum[32]; /**< SHA256 checksum of the item */
|
||||
};
|
||||
|
||||
/** Name of the struct */
|
||||
typedef struct _vault_item_header_t vault_item_header_t;
|
||||
|
||||
/** @}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
\addtogroup BUFFER
|
||||
@{
|
||||
*/
|
||||
|
||||
/** \struct _pcp_buffer
|
||||
A flexible buffer object wich automatically resizes, if neccessary.
|
||||
*/
|
||||
struct _pcp_buffer {
|
||||
char *name; /**< just for convenience in error messages and the like, so we know which buffer cause trouble */
|
||||
uint8_t allocated; /**< marks the buffer as allocated */
|
||||
size_t blocksize; /**< the blocksize to use when resizing, also used for initial malloc() */
|
||||
size_t size; /**< stores the current allocated size of the object */
|
||||
size_t offset; /**< current read position */
|
||||
size_t end; /**< current write position, data end. maybe less than size. */
|
||||
uint8_t isstring; /**< treat as char array/string */
|
||||
void *buf; /**< the actual storage buffer */
|
||||
};
|
||||
|
||||
/** The name used everywhere */
|
||||
typedef struct _pcp_buffer Buffer;
|
||||
|
||||
|
||||
/** @}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
\addtogroup PCPSTREAMS
|
||||
@{
|
||||
*/
|
||||
|
||||
/** \struct _pcp_stream_t
|
||||
An I/O wrapper object backed by a file or a buffer.
|
||||
*/
|
||||
struct _pcp_stream_t {
|
||||
FILE *fd; /**< The backend FILE stream */
|
||||
Buffer *b; /**< The backend Buffer object */
|
||||
Buffer *cache; /**< The caching Buffer object (for look ahead read) */
|
||||
Buffer *next; /**< The caching Next-Buffer object (for look ahead read) */
|
||||
Buffer *save; /**< Temporary buffer to backup overflow data */
|
||||
uint8_t is_buffer; /**< Set to 1 if the backend is a Buffer */
|
||||
uint8_t eof; /**< Set to 1 if EOF reached */
|
||||
uint8_t err; /**< Set to 1 if an error occured */
|
||||
uint8_t armor; /**< Set to 1 if Z85 en/de-coding is requested */
|
||||
uint8_t determine; /**< Set to 1 to automatically determine armor mode */
|
||||
uint8_t firstread; /**< Internal flag, will be set after first read() */
|
||||
size_t linewr; /**< Used for Z85 writing, number of chars written on last line */
|
||||
size_t blocksize; /**< Blocksize used for z85, if requested */
|
||||
uint8_t is_output; /**< marks the stream as output stream */
|
||||
uint8_t have_begin; /**< flag to indicate we already got the begin header, if any */
|
||||
size_t pos; /**< remember i/o position */
|
||||
};
|
||||
|
||||
typedef enum _PSVARS {
|
||||
PSMAXLINE = 20000
|
||||
} PSVARS;
|
||||
|
||||
|
||||
/** The name used everywhere */
|
||||
typedef struct _pcp_stream_t Pcpstream;
|
||||
/** @}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* various helper structs for mgmt.c, used internally only */
|
||||
struct _pcp_rfc_pubkey_header_t {
|
||||
uint8_t version;
|
||||
uint32_t ctime;
|
||||
uint8_t cipher;
|
||||
};
|
||||
|
||||
struct _pcp_rfc_pubkey_0x21_t {
|
||||
byte sig_ed25519_pub[crypto_sign_PUBLICKEYBYTES];
|
||||
byte ed25519_pub[crypto_sign_PUBLICKEYBYTES];
|
||||
byte curve25519_pub[crypto_box_PUBLICKEYBYTES];
|
||||
};
|
||||
|
||||
struct _pcp_rfc_pubkey_sigheader_0x21_t {
|
||||
uint8_t version;
|
||||
uint8_t type;
|
||||
uint8_t pkcipher;
|
||||
uint8_t hashcipher;
|
||||
uint16_t numsubs;
|
||||
};
|
||||
|
||||
struct _pcp_rfc_pubkey_sigsub_0x21_t {
|
||||
uint32_t size;
|
||||
uint8_t type;
|
||||
};
|
||||
|
||||
typedef struct _pcp_rfc_pubkey_header_t rfc_pub_h;
|
||||
typedef struct _pcp_rfc_pubkey_0x21_t rfc_pub_k;
|
||||
typedef struct _pcp_rfc_pubkey_sigheader_0x21_t rfc_pub_sig_h;
|
||||
typedef struct _pcp_rfc_pubkey_sigsub_0x21_t rfc_pub_sig_s;
|
||||
|
||||
struct _pcp_ks_bundle_t {
|
||||
pcp_pubkey_t *p;
|
||||
pcp_keysig_t *s;
|
||||
};
|
||||
typedef struct _pcp_ks_bundle_t pcp_ks_bundle_t;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif //_HAVE_PCP_STRUCTS_H
|
||||
@@ -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);
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -21,9 +21,8 @@
|
||||
|
||||
#define _GNU_SOURCE /* vasprintf() linux */
|
||||
|
||||
#include "defines.h"
|
||||
#include "platform.h"
|
||||
|
||||
#include "context.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdarg.h>
|
||||
@@ -31,39 +30,70 @@
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
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();
|
||||
}
|
||||
@@ -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; nrec<lenrec; nrec++) {
|
||||
cur_bufsize = ps_read(in, &rec_buf, PCP_ASYM_RECIPIENT_SIZE); /* fread(&rec_buf, 1, PCP_ASYM_RECIPIENT_SIZE, in); */
|
||||
if(cur_bufsize != PCP_ASYM_RECIPIENT_SIZE && !ps_end(in) && !ps_err(in)) {
|
||||
fatal("Error: input file corrupted, incomplete or no recipients (got %ld, exp %ld)\n", cur_bufsize, PCP_ASYM_RECIPIENT_SIZE );
|
||||
fatal(ptx, "Error: input file corrupted, incomplete or no recipients (got %ld, exp %ld)\n", cur_bufsize, PCP_ASYM_RECIPIENT_SIZE );
|
||||
goto errdef1;
|
||||
}
|
||||
recmatch = 0;
|
||||
|
||||
pcphash_iteratepub(cur) {
|
||||
pcphash_iteratepub(ptx, cur) {
|
||||
byte *recipient;
|
||||
recipient = pcp_box_decrypt(s, cur, rec_buf, PCP_ASYM_RECIPIENT_SIZE, &rec_size);
|
||||
recipient = pcp_box_decrypt(ptx, s, cur, rec_buf, PCP_ASYM_RECIPIENT_SIZE, &rec_size);
|
||||
if(recipient != NULL && rec_size == crypto_secretbox_KEYBYTES) {
|
||||
/* found a match */
|
||||
recmatch = 1;
|
||||
@@ -257,19 +257,19 @@ size_t pcp_decrypt_stream(Pcpstream *in, Pcpstream* out, pcp_key_t *s, byte *sym
|
||||
|
||||
|
||||
if(recmatch == 0) {
|
||||
fatal("Sorry, there's no matching public key in your vault for decryption\n");
|
||||
fatal(ptx, "Sorry, there's no matching public key in your vault for decryption\n");
|
||||
goto errdef1;
|
||||
}
|
||||
|
||||
/* step 5, actually decrypt the file, finally */
|
||||
if(verify) {
|
||||
pcp_rec_t *rec = pcp_rec_new(reccipher, nrec * PCP_ASYM_RECIPIENT_SIZE, NULL, cur);
|
||||
size_t s = pcp_decrypt_stream_sym(in, out, symkey, rec);
|
||||
size_t s = pcp_decrypt_stream_sym(ptx, in, out, symkey, rec);
|
||||
pcp_rec_free(rec);
|
||||
return s;
|
||||
}
|
||||
else {
|
||||
size_t s = pcp_decrypt_stream_sym(in, out, symkey, NULL);
|
||||
size_t s = pcp_decrypt_stream_sym(ptx, in, out, symkey, NULL);
|
||||
return s;
|
||||
}
|
||||
|
||||
@@ -277,7 +277,7 @@ size_t pcp_decrypt_stream(Pcpstream *in, Pcpstream* out, pcp_key_t *s, byte *sym
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t pcp_encrypt_stream(Pcpstream *in, Pcpstream *out, pcp_key_t *s, pcp_pubkey_t *p, int sign) {
|
||||
size_t pcp_encrypt_stream(PCPCTX *ptx, Pcpstream *in, Pcpstream *out, pcp_key_t *s, pcp_pubkey_t *p, int sign) {
|
||||
byte *symkey;
|
||||
int recipient_count;
|
||||
byte *recipients_cipher;
|
||||
@@ -306,9 +306,9 @@ size_t pcp_encrypt_stream(Pcpstream *in, Pcpstream *out, pcp_key_t *s, pcp_pubke
|
||||
|
||||
HASH_ITER(hh, p, cur, t) {
|
||||
byte *rec_cipher;
|
||||
rec_cipher = pcp_box_encrypt(s, cur, symkey, crypto_secretbox_KEYBYTES, &es);
|
||||
rec_cipher = pcp_box_encrypt(ptx, s, cur, symkey, crypto_secretbox_KEYBYTES, &es);
|
||||
if(es != rec_size) {
|
||||
fatal("invalid rec_size, expected %dl, got %dl\n", rec_size, es);
|
||||
fatal(ptx, "invalid rec_size, expected %dl, got %dl\n", rec_size, es);
|
||||
if(rec_cipher != NULL)
|
||||
free(rec_cipher);
|
||||
goto errec1;
|
||||
@@ -326,7 +326,7 @@ size_t pcp_encrypt_stream(Pcpstream *in, Pcpstream *out, pcp_key_t *s, pcp_pubke
|
||||
/* fwrite(head, 1, 1, out); */
|
||||
/* fprintf(stderr, "D: header - 1\n"); */
|
||||
if(ps_err(out) != 0) {
|
||||
fatal("Failed to write encrypted output!\n");
|
||||
fatal(ptx, "Failed to write encrypted output!\n");
|
||||
goto errec1;
|
||||
}
|
||||
|
||||
@@ -361,11 +361,11 @@ size_t pcp_encrypt_stream(Pcpstream *in, Pcpstream *out, pcp_key_t *s, pcp_pubke
|
||||
size_t sym_size = 0;
|
||||
if(sign) {
|
||||
pcp_rec_t *rec = pcp_rec_new(recipients_cipher, rec_size * recipient_count, s, NULL);
|
||||
sym_size = pcp_encrypt_stream_sym(in, out, symkey, 1, rec);
|
||||
sym_size = pcp_encrypt_stream_sym(ptx, in, out, symkey, 1, rec);
|
||||
pcp_rec_free(rec);
|
||||
}
|
||||
else
|
||||
sym_size = pcp_encrypt_stream_sym(in, out, symkey, 1, NULL);
|
||||
sym_size = pcp_encrypt_stream_sym(ptx, in, out, symkey, 1, NULL);
|
||||
|
||||
if(sym_size == 0)
|
||||
goto errec1;
|
||||
@@ -386,7 +386,7 @@ size_t pcp_encrypt_stream(Pcpstream *in, Pcpstream *out, pcp_key_t *s, pcp_pubke
|
||||
|
||||
|
||||
|
||||
size_t pcp_encrypt_stream_sym(Pcpstream *in, Pcpstream *out, byte *symkey, int havehead, pcp_rec_t *recsign) {
|
||||
size_t pcp_encrypt_stream_sym(PCPCTX *ptx, Pcpstream *in, Pcpstream *out, byte *symkey, int havehead, pcp_rec_t *recsign) {
|
||||
/*
|
||||
havehead = 0: write the whole thing from here
|
||||
havehead = 1: no header, being called from asym...
|
||||
@@ -413,7 +413,7 @@ size_t pcp_encrypt_stream_sym(Pcpstream *in, Pcpstream *out, byte *symkey, int h
|
||||
es = ps_write(out, head, 1);
|
||||
/* es = fwrite(head, 1, 1, out); */
|
||||
if(ps_err(out) != 0) {
|
||||
fatal("Failed to write encrypted output!\n");
|
||||
fatal(ptx, "Failed to write encrypted output!\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -466,7 +466,7 @@ size_t pcp_encrypt_stream_sym(Pcpstream *in, Pcpstream *out, byte *symkey, int h
|
||||
}
|
||||
|
||||
if(ps_err(out) != 0) {
|
||||
fatal("Failed to write encrypted output!\n");
|
||||
fatal(ptx, "Failed to write encrypted output!\n");
|
||||
goto errsym1;
|
||||
}
|
||||
|
||||
@@ -504,7 +504,7 @@ size_t pcp_encrypt_stream_sym(Pcpstream *in, Pcpstream *out, byte *symkey, int h
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t pcp_decrypt_stream_sym(Pcpstream *in, Pcpstream* out, byte *symkey, pcp_rec_t *recverify) {
|
||||
size_t pcp_decrypt_stream_sym(PCPCTX *ptx, Pcpstream *in, Pcpstream* out, byte *symkey, pcp_rec_t *recverify) {
|
||||
byte *buf_nonce;
|
||||
byte *buf_cipher;
|
||||
byte *buf_clear;
|
||||
@@ -579,13 +579,13 @@ size_t pcp_decrypt_stream_sym(Pcpstream *in, Pcpstream* out, byte *symkey, pcp_r
|
||||
free(buf_clear);
|
||||
|
||||
if(ps_err(out) != 0) {
|
||||
fatal("Failed to write decrypted output!\n");
|
||||
fatal(ptx, "Failed to write decrypted output!\n");
|
||||
out_size = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
fatal("Failed to decrypt file content!\n");
|
||||
fatal(ptx, "Failed to decrypt file content!\n");
|
||||
free(buf_clear);
|
||||
out_size = 0;
|
||||
break;
|
||||
@@ -610,20 +610,20 @@ size_t pcp_decrypt_stream_sym(Pcpstream *in, Pcpstream* out, byte *symkey, pcp_r
|
||||
crypto_generichash_final(st, hash, crypto_generichash_BYTES_MAX);
|
||||
|
||||
byte *verifiedhash = NULL;
|
||||
verifiedhash = pcp_ed_verify(signature, siglen, recverify->pub);
|
||||
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);
|
||||
|
||||
48
libpcp/ed.c
48
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;
|
||||
}
|
||||
|
||||
|
||||
54
libpcp/key.c
54
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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
108
libpcp/vault.c
108
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;
|
||||
}
|
||||
}
|
||||
|
||||
18
libpcp/z85.c
18
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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
112
src/keymgmt.c
112
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;
|
||||
|
||||
@@ -42,6 +42,7 @@
|
||||
#include "base85.h"
|
||||
#include "buffer.h"
|
||||
#include "mgmt.h"
|
||||
#include "context.h"
|
||||
|
||||
#define _WITH_GETLINE
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
40
src/pcp.c
40
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;
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -36,6 +36,8 @@
|
||||
#include <unistd.h>
|
||||
|
||||
#include "defines.h"
|
||||
#include "context.h"
|
||||
#include "pcp.h"
|
||||
|
||||
#define MAXPASSLEN 2048
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user