mirror of
https://codeberg.org/scip/pcp.git
synced 2025-12-17 12:00:56 +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
|
is now determined automatically as well as the
|
||||||
encoding.
|
encoding.
|
||||||
|
|
||||||
|
Made libpcp threadsafe by removing all global vars
|
||||||
|
and putting that stuff into the new PCP Context
|
||||||
|
class (ptx.h), which now holds errors and key hashes.
|
||||||
|
|
||||||
0.2.0 ED25519 and Curve25519 keys are now generated
|
0.2.0 ED25519 and Curve25519 keys are now generated
|
||||||
separately (previously they were generated from
|
separately (previously they were generated from
|
||||||
one random seed, the curve had been derived from
|
one random seed, the curve had been derived from
|
||||||
|
|||||||
@@ -22,5 +22,5 @@ AM_CXXFLAGS = -I../../include -I../../libpcp/scrypt/crypto -I../../libpcp/scrypt
|
|||||||
|
|
||||||
lib_LTLIBRARIES = libpcp1++.la
|
lib_LTLIBRARIES = libpcp1++.la
|
||||||
|
|
||||||
libpcp1___la_SOURCES = pcp++.h key.cpp vault.cpp crypto.cpp sign.cpp buffer.cpp
|
libpcp1___la_SOURCES = pcp++.h ptx.cpp key.cpp vault.cpp crypto.cpp sign.cpp buffer.cpp
|
||||||
include_HEADERS = pcp++.h
|
include_HEADERS = pcp++.h
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ namespace pcp {
|
|||||||
|
|
||||||
class Crypto {
|
class Crypto {
|
||||||
private:
|
private:
|
||||||
|
PcpContext PTX;
|
||||||
bool havevault;
|
bool havevault;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@@ -43,8 +44,8 @@ namespace pcp {
|
|||||||
Vault vault;
|
Vault vault;
|
||||||
|
|
||||||
// constructors
|
// constructors
|
||||||
Crypto(Key &skey, PubKey &pkey);
|
Crypto(PcpContext C, Key &skey, PubKey &pkey);
|
||||||
Crypto(Vault &v, Key &skey, PubKey &pkey);
|
Crypto(PcpContext C, Vault &v, Key &skey, PubKey &pkey);
|
||||||
|
|
||||||
// PK encryption methods
|
// PK encryption methods
|
||||||
// sender pubkey is P
|
// sender pubkey is P
|
||||||
|
|||||||
@@ -25,29 +25,31 @@
|
|||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace pcp;
|
using namespace pcp;
|
||||||
|
|
||||||
Crypto::Crypto(Key &skey, PubKey &pkey) {
|
Crypto::Crypto(PcpContext C, Key &skey, PubKey &pkey) {
|
||||||
P = pkey;
|
P = pkey;
|
||||||
S = skey;
|
S = skey;
|
||||||
|
PTX = C;
|
||||||
havevault = false;
|
havevault = false;
|
||||||
pcphash_init();
|
pcphash_add(PTX.ptx, P.K, PCP_KEY_TYPE_PUBLIC);
|
||||||
pcphash_add(P.K, PCP_KEY_TYPE_PUBLIC);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Crypto::Crypto(Vault &v, Key &skey, PubKey &pkey) {
|
Crypto::Crypto(PcpContext C, Vault &v, Key &skey, PubKey &pkey) {
|
||||||
P = pkey;
|
P = pkey;
|
||||||
S = skey;
|
S = skey;
|
||||||
|
PTX = C;
|
||||||
vault = v;
|
vault = v;
|
||||||
havevault = true;
|
havevault = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Crypto::encrypt(FILE *in, FILE *out, bool sign) {
|
bool Crypto::encrypt(FILE *in, FILE *out, bool sign) {
|
||||||
pcp_pubkey_t *pubhash = NULL;
|
pcp_pubkey_t *pubhash = NULL;
|
||||||
HASH_ADD_STR( pubhash, id, P.K);
|
pcphash_add(PTX.ptx, P.K, P.K->type);
|
||||||
|
//HASH_ADD_STR( pubhash, id, P.K);
|
||||||
Pcpstream *pin = ps_new_file(in);
|
Pcpstream *pin = ps_new_file(in);
|
||||||
Pcpstream *pout = ps_new_file(out);
|
Pcpstream *pout = ps_new_file(out);
|
||||||
size_t clen = pcp_encrypt_stream(pin, pout, S.K, pubhash, sign);
|
size_t clen = pcp_encrypt_stream(PTX.ptx, pin, pout, S.K, pubhash, sign);
|
||||||
if(clen <= 0)
|
if(clen <= 0)
|
||||||
throw exception();
|
throw exception(PTX);
|
||||||
ps_close(pin);
|
ps_close(pin);
|
||||||
ps_close(pout);
|
ps_close(pout);
|
||||||
return true;
|
return true;
|
||||||
@@ -56,8 +58,8 @@ bool Crypto::encrypt(FILE *in, FILE *out, bool sign) {
|
|||||||
bool Crypto::decrypt(FILE *in, FILE *out, bool verify) {
|
bool Crypto::decrypt(FILE *in, FILE *out, bool verify) {
|
||||||
Pcpstream *pin = ps_new_file(in);
|
Pcpstream *pin = ps_new_file(in);
|
||||||
Pcpstream *pout = ps_new_file(out);
|
Pcpstream *pout = ps_new_file(out);
|
||||||
if(pcp_decrypt_stream(pin, pout, S.K, NULL, verify) <= 0)
|
if(pcp_decrypt_stream(PTX.ptx, pin, pout, S.K, NULL, verify) <= 0)
|
||||||
throw exception();
|
throw exception(PTX);
|
||||||
ps_close(pin);
|
ps_close(pin);
|
||||||
ps_close(pout);
|
ps_close(pout);
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -30,14 +30,17 @@
|
|||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
|
#include "ptx++.h"
|
||||||
|
|
||||||
namespace pcp {
|
namespace pcp {
|
||||||
|
|
||||||
class exception : public std::runtime_error {
|
class exception : public std::runtime_error {
|
||||||
private:
|
private:
|
||||||
|
PCPCTX *ptx;
|
||||||
std::string getfatals() {
|
std::string getfatals() {
|
||||||
std::string msg;
|
std::string msg;
|
||||||
if(PCP_ERRSET == 1) {
|
if(ptx->pcp_errset == 1) {
|
||||||
msg = PCP_ERR;
|
msg = ptx->pcp_err;
|
||||||
}
|
}
|
||||||
if(errno) {
|
if(errno) {
|
||||||
msg += std::string("\nError: ")
|
msg += std::string("\nError: ")
|
||||||
@@ -47,8 +50,8 @@ namespace pcp {
|
|||||||
return msg;
|
return msg;
|
||||||
}
|
}
|
||||||
public:
|
public:
|
||||||
exception(const std::string & msg) : runtime_error(msg) { }
|
exception(PcpContext P, const std::string & msg) : runtime_error(msg) { ptx = P.ptx; }
|
||||||
exception() : runtime_error(getfatals()) { }
|
exception(PcpContext P) : runtime_error(getfatals()) { ptx = P.ptx; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -30,6 +30,7 @@
|
|||||||
|
|
||||||
#include "helpers++.h"
|
#include "helpers++.h"
|
||||||
#include "buffer++.h"
|
#include "buffer++.h"
|
||||||
|
#include "ptx++.h"
|
||||||
|
|
||||||
namespace pcp {
|
namespace pcp {
|
||||||
|
|
||||||
@@ -39,12 +40,14 @@ namespace pcp {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
pcp_pubkey_t *K;
|
pcp_pubkey_t *K;
|
||||||
|
PcpContext PTX;
|
||||||
|
|
||||||
// constructors
|
// constructors
|
||||||
|
PubKey(PcpContext P);
|
||||||
PubKey();
|
PubKey();
|
||||||
PubKey(pcp_pubkey_t *k);
|
PubKey(PcpContext P, pcp_pubkey_t *k);
|
||||||
PubKey(pcp_pubkey_t *k, bool store);
|
PubKey(PcpContext P, pcp_pubkey_t *k, bool store);
|
||||||
PubKey(std::string &z85encoded);
|
PubKey(PcpContext P, std::string &z85encoded);
|
||||||
|
|
||||||
// destructors
|
// destructors
|
||||||
~PubKey();
|
~PubKey();
|
||||||
@@ -72,17 +75,19 @@ namespace pcp {
|
|||||||
public:
|
public:
|
||||||
// make access to the underlying struct easier
|
// make access to the underlying struct easier
|
||||||
pcp_key_t *K;
|
pcp_key_t *K;
|
||||||
|
PcpContext PTX;
|
||||||
|
|
||||||
// constructors
|
// constructors
|
||||||
Key();
|
Key();
|
||||||
Key(bool generate);
|
Key(PcpContext P);
|
||||||
Key(const std::string& passphrase);
|
Key(PcpContext P, bool generate);
|
||||||
Key(const std::string& passphrase,
|
Key(PcpContext P, const std::string& passphrase);
|
||||||
|
Key(PcpContext P, const std::string& passphrase,
|
||||||
const std::string& owner,
|
const std::string& owner,
|
||||||
const std::string& mail);
|
const std::string& mail);
|
||||||
Key(pcp_key_t *k);
|
Key(PcpContext P, pcp_key_t *k);
|
||||||
Key(pcp_key_t *k, bool store);
|
Key(PcpContext P, pcp_key_t *k, bool store);
|
||||||
Key(std::string &z85encoded, std::string& passphrase);
|
Key(PcpContext P, std::string &z85encoded, std::string& passphrase);
|
||||||
|
|
||||||
// destructor
|
// destructor
|
||||||
~Key();
|
~Key();
|
||||||
|
|||||||
@@ -30,55 +30,67 @@ Key::Key() {
|
|||||||
K = NULL;
|
K = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
Key::Key(bool generate) {
|
Key::Key(PcpContext P) {
|
||||||
|
stored = false;
|
||||||
|
K = NULL;
|
||||||
|
PTX = P;
|
||||||
|
}
|
||||||
|
|
||||||
|
Key::Key(PcpContext P, bool generate) {
|
||||||
stored = false;
|
stored = false;
|
||||||
if(generate)
|
if(generate)
|
||||||
K = pcpkey_new();
|
K = pcpkey_new();
|
||||||
else
|
else
|
||||||
K = NULL;
|
K = NULL;
|
||||||
|
PTX = P;
|
||||||
}
|
}
|
||||||
|
|
||||||
Key::Key(const string& passphrase) {
|
Key::Key(PcpContext P, const string& passphrase) {
|
||||||
stored = false;
|
stored = false;
|
||||||
K = pcpkey_new();
|
K = pcpkey_new();
|
||||||
K = pcpkey_encrypt(K, (char *)passphrase.c_str());
|
K = pcpkey_encrypt(PTX.ptx, K, (char *)passphrase.c_str());
|
||||||
|
PTX = P;
|
||||||
}
|
}
|
||||||
|
|
||||||
Key::Key(const string& passphrase,
|
Key::Key(PcpContext P, const string& passphrase,
|
||||||
const string& owner,
|
const string& owner,
|
||||||
const string& mail) {
|
const string& mail) {
|
||||||
stored = false;
|
stored = false;
|
||||||
pcp_key_t *_K = pcpkey_new();
|
pcp_key_t *_K = pcpkey_new();
|
||||||
K = pcpkey_encrypt(_K, (char *)passphrase.c_str());
|
K = pcpkey_encrypt(PTX.ptx, _K, (char *)passphrase.c_str());
|
||||||
memcpy(K->owner, owner.c_str(), owner.length()+1);
|
memcpy(K->owner, owner.c_str(), owner.length()+1);
|
||||||
memcpy(K->mail, mail.c_str(), mail.length()+1);
|
memcpy(K->mail, mail.c_str(), mail.length()+1);
|
||||||
// free(_K);
|
// free(_K);
|
||||||
|
PTX = P;
|
||||||
}
|
}
|
||||||
|
|
||||||
Key::Key(pcp_key_t *k) {
|
Key::Key(PcpContext P, pcp_key_t *k) {
|
||||||
stored = false;
|
stored = false;
|
||||||
K = k;
|
K = k;
|
||||||
|
PTX = P;
|
||||||
}
|
}
|
||||||
|
|
||||||
Key::Key(pcp_key_t *k, bool store) {
|
Key::Key(PcpContext P, pcp_key_t *k, bool store) {
|
||||||
stored = new bool(store);
|
stored = new bool(store);
|
||||||
K = k;
|
K = k;
|
||||||
|
PTX = P;
|
||||||
}
|
}
|
||||||
|
|
||||||
Key::Key(string &z85encoded, string &passphrase) {
|
Key::Key(PcpContext P, string &z85encoded, string &passphrase) {
|
||||||
stored = false;
|
stored = false;
|
||||||
|
PTX = P;
|
||||||
|
|
||||||
if(z85encoded.length() == 0)
|
if(z85encoded.length() == 0)
|
||||||
throw pcp::exception("Error: zero length input");
|
throw pcp::exception(PTX, "Error: zero length input");
|
||||||
|
|
||||||
pcp_key_t *key = pcp_import_secret((unsigned char *)z85encoded.c_str(), z85encoded.length(), (char *)passphrase.c_str());
|
pcp_key_t *key = pcp_import_secret(PTX.ptx, (unsigned char *)z85encoded.c_str(), z85encoded.length(), (char *)passphrase.c_str());
|
||||||
|
|
||||||
if(key == NULL)
|
if(key == NULL)
|
||||||
throw pcp::exception();
|
throw pcp::exception(PTX);
|
||||||
|
|
||||||
if(pcp_sanitycheck_key(key) != 0) {
|
if(pcp_sanitycheck_key(PTX.ptx, key) != 0) {
|
||||||
free(key);
|
free(key);
|
||||||
throw pcp::exception();
|
throw pcp::exception(PTX);
|
||||||
}
|
}
|
||||||
|
|
||||||
K = key;
|
K = key;
|
||||||
@@ -99,12 +111,12 @@ string Key::export_secret(const string &passphrase) {
|
|||||||
Buffer *exported_sk;
|
Buffer *exported_sk;
|
||||||
|
|
||||||
if(passphrase.length() == 0)
|
if(passphrase.length() == 0)
|
||||||
throw pcp::exception("Error: empty passphrase");
|
throw pcp::exception(PTX, "Error: empty passphrase");
|
||||||
|
|
||||||
exported_sk = pcp_export_secret(K, (char *)passphrase.c_str());
|
exported_sk = pcp_export_secret(PTX.ptx, K, (char *)passphrase.c_str());
|
||||||
|
|
||||||
if(exported_sk == NULL)
|
if(exported_sk == NULL)
|
||||||
throw pcp::exception();
|
throw pcp::exception(PTX);
|
||||||
|
|
||||||
size_t zlen;
|
size_t zlen;
|
||||||
char *z85 = pcp_z85_encode(buffer_get(exported_sk), buffer_size(exported_sk), &zlen);
|
char *z85 = pcp_z85_encode(buffer_get(exported_sk), buffer_size(exported_sk), &zlen);
|
||||||
@@ -120,7 +132,7 @@ string Key::export_public() {
|
|||||||
exported_pk = pcp_export_rfc_pub(K);
|
exported_pk = pcp_export_rfc_pub(K);
|
||||||
|
|
||||||
if(exported_pk == NULL)
|
if(exported_pk == NULL)
|
||||||
throw pcp::exception();
|
throw pcp::exception(PTX);
|
||||||
|
|
||||||
size_t zlen;
|
size_t zlen;
|
||||||
char *z85 = pcp_z85_encode(buffer_get(exported_pk), buffer_size(exported_pk), &zlen);
|
char *z85 = pcp_z85_encode(buffer_get(exported_pk), buffer_size(exported_pk), &zlen);
|
||||||
@@ -140,19 +152,19 @@ bool pcp::operator!(Key& k) {
|
|||||||
|
|
||||||
|
|
||||||
void Key::encrypt(const string& passphrase) {
|
void Key::encrypt(const string& passphrase) {
|
||||||
K = pcpkey_encrypt(K, (char *)passphrase.c_str());
|
K = pcpkey_encrypt(PTX.ptx, K, (char *)passphrase.c_str());
|
||||||
if(PCP_ERRSET == 1)
|
if(K == NULL)
|
||||||
throw exception();
|
throw exception(PTX);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Key::decrypt(const string& passphrase) {
|
void Key::decrypt(const string& passphrase) {
|
||||||
K = pcpkey_decrypt(K, (char *)passphrase.c_str());
|
K = pcpkey_decrypt(PTX.ptx, K, (char *)passphrase.c_str());
|
||||||
if(PCP_ERRSET == 1)
|
if(K == NULL)
|
||||||
throw exception();
|
throw exception(PTX);
|
||||||
}
|
}
|
||||||
|
|
||||||
PubKey Key::get_public() {
|
PubKey Key::get_public() {
|
||||||
return PubKey(pcpkey_pub_from_secret(K));
|
return PubKey(PTX, pcpkey_pub_from_secret(K));
|
||||||
}
|
}
|
||||||
|
|
||||||
string Key::get_id() {
|
string Key::get_id() {
|
||||||
@@ -197,44 +209,52 @@ bool Key::is_encrypted() {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
PubKey::PubKey() {
|
PubKey::PubKey() {
|
||||||
stored = false;
|
stored = false;
|
||||||
K = NULL;
|
K = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PubKey::PubKey(PcpContext P) {
|
||||||
PubKey::PubKey(pcp_pubkey_t *k) {
|
|
||||||
stored = false;
|
stored = false;
|
||||||
K = k;
|
K = NULL;
|
||||||
|
PTX = P;
|
||||||
}
|
}
|
||||||
|
|
||||||
PubKey::PubKey(pcp_pubkey_t *k, bool store) {
|
|
||||||
|
PubKey::PubKey(PcpContext P, pcp_pubkey_t *k) {
|
||||||
|
stored = false;
|
||||||
|
K = k;
|
||||||
|
PTX = P;
|
||||||
|
}
|
||||||
|
|
||||||
|
PubKey::PubKey(PcpContext P, pcp_pubkey_t *k, bool store) {
|
||||||
stored = store;
|
stored = store;
|
||||||
K = k;
|
K = k;
|
||||||
|
PTX = P;
|
||||||
}
|
}
|
||||||
|
|
||||||
PubKey::PubKey(string &z85encoded) {
|
PubKey::PubKey(PcpContext P, string &z85encoded) {
|
||||||
stored = false;
|
stored = false;
|
||||||
|
PTX = P;
|
||||||
|
|
||||||
if(z85encoded.length() == 0)
|
if(z85encoded.length() == 0)
|
||||||
throw pcp::exception("Error: zero length input");
|
throw pcp::exception(PTX, "Error: zero length input");
|
||||||
|
|
||||||
Buf blob("pub", 256);
|
Buf blob("pub", 256);
|
||||||
blob.add(z85encoded.c_str(), z85encoded.length());
|
blob.add(z85encoded.c_str(), z85encoded.length());
|
||||||
|
|
||||||
pcp_ks_bundle_t *KS = pcp_import_pub(buffer_get(blob.get_buffer()), buffer_size(blob.get_buffer()));
|
pcp_ks_bundle_t *KS = pcp_import_pub(PTX.ptx, buffer_get(blob.get_buffer()), buffer_size(blob.get_buffer()));
|
||||||
|
|
||||||
if(KS == NULL) {
|
if(KS == NULL) {
|
||||||
throw pcp::exception();
|
throw pcp::exception(PTX);
|
||||||
}
|
}
|
||||||
pcp_pubkey_t *pub = KS->p;
|
pcp_pubkey_t *pub = KS->p;
|
||||||
|
|
||||||
if(pcp_sanitycheck_pub(pub) != 0) {
|
if(pcp_sanitycheck_pub(PTX.ptx, pub) != 0) {
|
||||||
free(KS->p);
|
free(KS->p);
|
||||||
free(KS->s);
|
free(KS->s);
|
||||||
free(KS);
|
free(KS);
|
||||||
throw pcp::exception();
|
throw pcp::exception(PTX);
|
||||||
}
|
}
|
||||||
|
|
||||||
K = pub;
|
K = pub;
|
||||||
|
|||||||
@@ -32,6 +32,7 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
#include "key++.h"
|
#include "key++.h"
|
||||||
|
#include "ptx++.h"
|
||||||
#include "vault++.h"
|
#include "vault++.h"
|
||||||
#include "crypto++.h"
|
#include "crypto++.h"
|
||||||
#include "sign++.h"
|
#include "sign++.h"
|
||||||
|
|||||||
48
bindings/cpp/ptx++.h
Normal file
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;
|
Vault vault;
|
||||||
PubKey Signedby;
|
PubKey Signedby;
|
||||||
Buf sig;
|
Buf sig;
|
||||||
|
PcpContext PTX;
|
||||||
|
|
||||||
// constructors
|
// constructors
|
||||||
Signature(Key &skey); // sign only
|
Signature(PcpContext P, Key &skey); // sign only
|
||||||
Signature(PubKey &pkey); // verify only
|
Signature(PcpContext P,PubKey &pkey); // verify only
|
||||||
Signature(Key &skey, PubKey &pkey); // both/bulk
|
Signature(PcpContext P,Key &skey, PubKey &pkey); // both/bulk
|
||||||
Signature(Vault &v);
|
Signature(PcpContext P,Vault &v);
|
||||||
|
|
||||||
// destructor
|
// destructor
|
||||||
~Signature();
|
~Signature();
|
||||||
|
|||||||
@@ -24,25 +24,29 @@
|
|||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace pcp;
|
using namespace pcp;
|
||||||
|
|
||||||
Signature::Signature(Key &skey) {
|
Signature::Signature(PcpContext P, Key &skey) {
|
||||||
S = skey;
|
S = skey;
|
||||||
|
PTX = P;
|
||||||
havevault = false;
|
havevault = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Signature::Signature(PubKey &pkey) {
|
Signature::Signature(PcpContext C,PubKey &pkey) {
|
||||||
P = pkey;
|
P = pkey;
|
||||||
|
PTX = C;
|
||||||
havevault = false;
|
havevault = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Signature::Signature(Key &skey, PubKey &pkey) {
|
Signature::Signature(PcpContext C,Key &skey, PubKey &pkey) {
|
||||||
P = pkey;
|
P = pkey;
|
||||||
S = skey;
|
S = skey;
|
||||||
|
PTX = C;
|
||||||
havevault = false;
|
havevault = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Signature::Signature(Vault &v) {
|
Signature::Signature(PcpContext P,Vault &v) {
|
||||||
vault = v;
|
vault = v;
|
||||||
havevault = true;
|
havevault = true;
|
||||||
|
PTX = P;
|
||||||
S = vault.get_primary();
|
S = vault.get_primary();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -51,10 +55,10 @@ Signature::~Signature() {
|
|||||||
|
|
||||||
bool Signature::sign(std::vector<unsigned char> message) {
|
bool Signature::sign(std::vector<unsigned char> message) {
|
||||||
if(! S)
|
if(! S)
|
||||||
throw exception("Error: cannot sign without a secret key, use another constructor.");
|
throw exception(PTX, "Error: cannot sign without a secret key, use another constructor.");
|
||||||
|
|
||||||
if(S.is_encrypted())
|
if(S.is_encrypted())
|
||||||
throw exception("Error: cannot sign with an encrypted secret key, decrypt it before using.");
|
throw exception(PTX, "Error: cannot sign with an encrypted secret key, decrypt it before using.");
|
||||||
|
|
||||||
char n[] = "signvec";
|
char n[] = "signvec";
|
||||||
Buffer *m = buffer_new(32, n);
|
Buffer *m = buffer_new(32, n);
|
||||||
@@ -68,17 +72,17 @@ bool Signature::sign(std::vector<unsigned char> message) {
|
|||||||
buffer_free(m);
|
buffer_free(m);
|
||||||
|
|
||||||
if(!ok)
|
if(!ok)
|
||||||
throw exception();
|
throw exception(PTX);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Signature::sign(unsigned char *message, size_t mlen) {
|
bool Signature::sign(unsigned char *message, size_t mlen) {
|
||||||
if(! S)
|
if(! S)
|
||||||
throw exception("Error: cannot sign without a secret key, use another constructor.");
|
throw exception(PTX, "Error: cannot sign without a secret key, use another constructor.");
|
||||||
|
|
||||||
if(S.is_encrypted())
|
if(S.is_encrypted())
|
||||||
throw exception("Error: cannot sign with an encrypted secret key, decrypt it before using.");
|
throw exception(PTX, "Error: cannot sign with an encrypted secret key, decrypt it before using.");
|
||||||
|
|
||||||
char n[] = "signchar";
|
char n[] = "signchar";
|
||||||
Buffer *m = buffer_new(32, n);
|
Buffer *m = buffer_new(32, n);
|
||||||
@@ -90,7 +94,7 @@ bool Signature::sign(unsigned char *message, size_t mlen) {
|
|||||||
buffer_free(m);
|
buffer_free(m);
|
||||||
|
|
||||||
if(! ok)
|
if(! ok)
|
||||||
throw exception();
|
throw exception(PTX);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -98,7 +102,7 @@ bool Signature::sign(unsigned char *message, size_t mlen) {
|
|||||||
bool Signature::sign(Pcpstream *message) {
|
bool Signature::sign(Pcpstream *message) {
|
||||||
Pcpstream *out = ps_new_outbuffer();
|
Pcpstream *out = ps_new_outbuffer();
|
||||||
|
|
||||||
size_t sigsize = pcp_ed_sign_buffered(message, out, S.K, 0);
|
size_t sigsize = pcp_ed_sign_buffered(PTX.ptx, message, out, S.K, 0);
|
||||||
|
|
||||||
if(sigsize > 0) {
|
if(sigsize > 0) {
|
||||||
Buffer *o = ps_buffer(out);
|
Buffer *o = ps_buffer(out);
|
||||||
@@ -115,7 +119,7 @@ bool Signature::sign(Pcpstream *message) {
|
|||||||
|
|
||||||
bool Signature::verify(vector<unsigned char> message) {
|
bool Signature::verify(vector<unsigned char> message) {
|
||||||
if(!P) {
|
if(!P) {
|
||||||
throw exception("No public key specified, unable to verify.");
|
throw exception(PTX, "No public key specified, unable to verify.");
|
||||||
}
|
}
|
||||||
|
|
||||||
Buf _sig = Buf();
|
Buf _sig = Buf();
|
||||||
@@ -128,7 +132,7 @@ bool Signature::verify(vector<unsigned char> message) {
|
|||||||
|
|
||||||
bool Signature::verify(unsigned char *signature, size_t mlen) {
|
bool Signature::verify(unsigned char *signature, size_t mlen) {
|
||||||
if(!P) {
|
if(!P) {
|
||||||
throw exception("No public key specified, unable to verify.");
|
throw exception(PTX, "No public key specified, unable to verify.");
|
||||||
}
|
}
|
||||||
|
|
||||||
Buf _sig = Buf();
|
Buf _sig = Buf();
|
||||||
@@ -141,15 +145,15 @@ bool Signature::verify(unsigned char *signature, size_t mlen) {
|
|||||||
bool Signature::verify(Buf _sig) {
|
bool Signature::verify(Buf _sig) {
|
||||||
Pcpstream *p = ps_new_inbuffer(_sig.get_buffer());
|
Pcpstream *p = ps_new_inbuffer(_sig.get_buffer());
|
||||||
|
|
||||||
pcp_pubkey_t *pub = pcp_ed_verify_buffered(p, P.K);
|
pcp_pubkey_t *pub = pcp_ed_verify_buffered(PTX.ptx, p, P.K);
|
||||||
|
|
||||||
ps_close(p);
|
ps_close(p);
|
||||||
|
|
||||||
if(pub != NULL) {
|
if(pub != NULL) {
|
||||||
Signedby = PubKey(pub);
|
Signedby = PubKey(PTX, pub);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
throw exception();
|
throw exception(PTX);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,11 +46,13 @@ namespace pcp {
|
|||||||
class Vault {
|
class Vault {
|
||||||
private:
|
private:
|
||||||
vault_t *V;
|
vault_t *V;
|
||||||
|
PcpContext PTX;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// constructors
|
// constructors
|
||||||
Vault();
|
Vault();
|
||||||
Vault(std::string filename);
|
Vault(PcpContext P);
|
||||||
|
Vault(PcpContext P, std::string filename);
|
||||||
|
|
||||||
// destructor
|
// destructor
|
||||||
~Vault();
|
~Vault();
|
||||||
|
|||||||
@@ -28,24 +28,28 @@ Vault::Vault() {
|
|||||||
V = NULL;
|
V = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
Vault::Vault(string filename) {
|
Vault::Vault(PcpContext P) {
|
||||||
pcphash_init();
|
V = NULL;
|
||||||
V = pcpvault_init((char *)filename.c_str());
|
PTX = P;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vault::Vault(PcpContext P, string filename) {
|
||||||
|
PTX = P;
|
||||||
|
V = pcpvault_init(PTX.ptx, (char *)filename.c_str());
|
||||||
if (V == NULL)
|
if (V == NULL)
|
||||||
throw pcp::exception();
|
throw pcp::exception(PTX);
|
||||||
}
|
}
|
||||||
|
|
||||||
Vault::~Vault() {
|
Vault::~Vault() {
|
||||||
pcpvault_close(V);
|
pcpvault_close(PTX.ptx, V);
|
||||||
pcphash_clean();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::map<std::string, Key> Vault::keys() {
|
std::map<std::string, Key> Vault::keys() {
|
||||||
std::map<std::string, Key> kmap;
|
std::map<std::string, Key> kmap;
|
||||||
|
|
||||||
pcp_key_t *k = NULL;
|
pcp_key_t *k = NULL;
|
||||||
pcphash_iterate(k) {
|
pcphash_iterate(PTX.ptx, k) {
|
||||||
kmap.insert ( pair<string,Key>(string(k->id), Key(k, true)) );
|
kmap.insert ( pair<string,Key>(string(k->id), Key(PTX, k, true)) );
|
||||||
}
|
}
|
||||||
|
|
||||||
return kmap;
|
return kmap;
|
||||||
@@ -55,39 +59,39 @@ std::map<std::string, PubKey> Vault::pubkeys() {
|
|||||||
std::map<std::string, PubKey> kmap;
|
std::map<std::string, PubKey> kmap;
|
||||||
|
|
||||||
pcp_pubkey_t *k = NULL;
|
pcp_pubkey_t *k = NULL;
|
||||||
pcphash_iteratepub(k) {
|
pcphash_iteratepub(PTX.ptx, k) {
|
||||||
kmap.insert ( pair<string,PubKey>(string(k->id), PubKey(k, true)) );
|
kmap.insert ( pair<string,PubKey>(string(k->id), PubKey(PTX, k, true)) );
|
||||||
}
|
}
|
||||||
|
|
||||||
return kmap;
|
return kmap;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Vault::key_count() {
|
int Vault::key_count() {
|
||||||
return pcphash_count();
|
return pcphash_count(PTX.ptx);
|
||||||
}
|
}
|
||||||
|
|
||||||
int Vault::pubkey_count() {
|
int Vault::pubkey_count() {
|
||||||
return pcphash_countpub();
|
return pcphash_countpub(PTX.ptx);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Vault::key_add(Key &key) {
|
void Vault::key_add(Key &key) {
|
||||||
if(V->isnew == 1 || HASH_COUNT(pcpkey_hash) == 0) {
|
if(V->isnew == 1 || pcphash_count(PTX.ptx) == 0) {
|
||||||
key.K->type = PCP_KEY_TYPE_MAINSECRET;
|
key.K->type = PCP_KEY_TYPE_MAINSECRET;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(pcpvault_addkey(V, (void *)key.K, key.K->type) != 0)
|
if(pcpvault_addkey(PTX.ptx, V, (void *)key.K, key.K->type) != 0)
|
||||||
throw pcp::exception();
|
throw pcp::exception(PTX);
|
||||||
key.is_stored(true);
|
key.is_stored(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Vault::pubkey_add(PubKey &key) {
|
void Vault::pubkey_add(PubKey &key) {
|
||||||
if(pcpvault_addkey(V, (void *)key.K, key.K->type) != 0)
|
if(pcpvault_addkey(PTX.ptx, V, (void *)key.K, key.K->type) != 0)
|
||||||
throw pcp::exception();
|
throw pcp::exception(PTX);
|
||||||
key.is_stored(true);
|
key.is_stored(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Vault::key_exists(string &id) {
|
bool Vault::key_exists(string &id) {
|
||||||
pcp_key_t *s = pcphash_keyexists((char *)id.c_str());
|
pcp_key_t *s = pcphash_keyexists(PTX.ptx, (char *)id.c_str());
|
||||||
if(s == NULL)
|
if(s == NULL)
|
||||||
return false;
|
return false;
|
||||||
else
|
else
|
||||||
@@ -95,7 +99,7 @@ bool Vault::key_exists(string &id) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool Vault::pubkey_exists(string &id) {
|
bool Vault::pubkey_exists(string &id) {
|
||||||
pcp_pubkey_t *p = pcphash_pubkeyexists((char *)id.c_str());
|
pcp_pubkey_t *p = pcphash_pubkeyexists(PTX.ptx, (char *)id.c_str());
|
||||||
if(p == NULL)
|
if(p == NULL)
|
||||||
return false;
|
return false;
|
||||||
else
|
else
|
||||||
@@ -103,63 +107,63 @@ bool Vault::pubkey_exists(string &id) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Vault::key_delete(std::string &id) {
|
void Vault::key_delete(std::string &id) {
|
||||||
pcp_pubkey_t *p = pcphash_pubkeyexists((char *)id.c_str());
|
pcp_pubkey_t *p = pcphash_pubkeyexists(PTX.ptx, (char *)id.c_str());
|
||||||
|
|
||||||
if(p != NULL) {
|
if(p != NULL) {
|
||||||
// delete public
|
// delete public
|
||||||
HASH_DEL(pcppubkey_hash, p);
|
pcphash_del(PTX.ptx, p, p->type);
|
||||||
free(p);
|
free(p);
|
||||||
V->unsafed = 1;
|
V->unsafed = 1;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
pcp_key_t *s = pcphash_keyexists((char *)id.c_str());
|
pcp_key_t *s = pcphash_keyexists(PTX.ptx, (char *)id.c_str());
|
||||||
if(s != NULL) {
|
if(s != NULL) {
|
||||||
// delete secret
|
// delete secret
|
||||||
HASH_DEL(pcpkey_hash, s);
|
pcphash_del(PTX.ptx, s, s->type);
|
||||||
free(s);
|
free(s);
|
||||||
V->unsafed = 1;
|
V->unsafed = 1;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
throw exception("Key not found!\n");
|
throw exception(PTX, "Key not found!\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Key Vault::get_primary() {
|
Key Vault::get_primary() {
|
||||||
pcp_key_t *k = NULL;
|
pcp_key_t *k = NULL;
|
||||||
pcphash_iterate(k) {
|
pcphash_iterate(PTX.ptx, k) {
|
||||||
if(k->type == PCP_KEY_TYPE_MAINSECRET) {
|
if(k->type == PCP_KEY_TYPE_MAINSECRET) {
|
||||||
return Key(k);
|
return Key(PTX, k);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(Vault::key_count() == 1) {
|
if(Vault::key_count() == 1) {
|
||||||
pcphash_iterate(k) {
|
pcphash_iterate(PTX.ptx, k) {
|
||||||
return Key(k);
|
return Key(PTX, k);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// too bad
|
// too bad
|
||||||
throw exception("No primary key found in vault.");
|
throw exception(PTX, "No primary key found in vault.");
|
||||||
}
|
}
|
||||||
|
|
||||||
Key Vault::get_secret(std::string &id) {
|
Key Vault::get_secret(std::string &id) {
|
||||||
pcp_key_t *k = NULL;
|
pcp_key_t *k = NULL;
|
||||||
pcphash_iterate(k) {
|
pcphash_iterate(PTX.ptx, k) {
|
||||||
if(memcmp(k->id, id.c_str(), 16) == 0) {
|
if(memcmp(k->id, id.c_str(), 16) == 0) {
|
||||||
return Key(k);
|
return Key(PTX, k);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
throw exception("Secret key doesn't exist in vault.");
|
throw exception(PTX, "Secret key doesn't exist in vault.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
PubKey Vault::get_public(std::string &id) {
|
PubKey Vault::get_public(std::string &id) {
|
||||||
pcp_pubkey_t *k = NULL;
|
pcp_pubkey_t *k = NULL;
|
||||||
pcphash_iteratepub(k) {
|
pcphash_iteratepub(PTX.ptx, k) {
|
||||||
if(memcmp(k->id, id.c_str(), 16) == 0) {
|
if(memcmp(k->id, id.c_str(), 16) == 0) {
|
||||||
return PubKey(k);
|
return PubKey(PTX, k);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
throw exception("Public key doesn't exist in vault.");
|
throw exception(PTX, "Public key doesn't exist in vault.");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ PCPEXPORT = pcp.h \
|
|||||||
pcp/buffer.h \
|
pcp/buffer.h \
|
||||||
pcp/mgmt.h \
|
pcp/mgmt.h \
|
||||||
pcp/pcpstream.h \
|
pcp/pcpstream.h \
|
||||||
pcp/keysig.h
|
pcp/keysig.h \
|
||||||
|
pcp/context.h
|
||||||
|
|
||||||
nobase_include_HEADERS = $(PCPEXPORT)
|
nobase_include_HEADERS = $(PCPEXPORT)
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ extern "C" {
|
|||||||
#include "pcp/base85.h"
|
#include "pcp/base85.h"
|
||||||
#include "pcp/buffer.h"
|
#include "pcp/buffer.h"
|
||||||
#include "pcp/config.h"
|
#include "pcp/config.h"
|
||||||
|
#include "pcp/context.h"
|
||||||
#include "pcp/crypto.h"
|
#include "pcp/crypto.h"
|
||||||
#include "pcp/defines.h"
|
#include "pcp/defines.h"
|
||||||
#include "pcp/digital_crc32.h"
|
#include "pcp/digital_crc32.h"
|
||||||
@@ -27,6 +28,7 @@ extern "C" {
|
|||||||
#include "pcp/plist.h"
|
#include "pcp/plist.h"
|
||||||
#include "pcp/randomart.h"
|
#include "pcp/randomart.h"
|
||||||
#include "pcp/scrypt.h"
|
#include "pcp/scrypt.h"
|
||||||
|
#include "pcp/structs.h"
|
||||||
#include "pcp/uthash.h"
|
#include "pcp/uthash.h"
|
||||||
#include "pcp/util.h"
|
#include "pcp/util.h"
|
||||||
#include "pcp/vault.h"
|
#include "pcp/vault.h"
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ Licensed under the terms of the LGPL 2.1.
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include "defines.h"
|
#include "defines.h"
|
||||||
|
#include "context.h"
|
||||||
|
|
||||||
#undef DEBUG_85
|
#undef DEBUG_85
|
||||||
|
|
||||||
@@ -26,10 +27,10 @@ Licensed under the terms of the LGPL 2.1.
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
int decode_85(char *dst, const char *buffer, int len);
|
int decode_85(PCPCTX *ptx, char *dst, const char *buffer, int len);
|
||||||
void encode_85(char *buf, const unsigned char *data, int bytes);
|
void encode_85(char *buf, const unsigned char *data, int bytes);
|
||||||
|
|
||||||
#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
|
#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
|
||||||
#define error(...) (fatal(__VA_ARGS__), -1)
|
#define error(...) (fatal(ptx, __VA_ARGS__), -1)
|
||||||
|
|
||||||
#endif /* HAVE_BASE85_H */
|
#endif /* HAVE_BASE85_H */
|
||||||
|
|||||||
@@ -27,6 +27,8 @@
|
|||||||
#include "mem.h"
|
#include "mem.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "defines.h"
|
#include "defines.h"
|
||||||
|
#include "structs.h"
|
||||||
|
#include "context.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \defgroup Buffer BUFFER
|
* \defgroup Buffer BUFFER
|
||||||
@@ -44,22 +46,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
/** \struct _pcp_buffer
|
|
||||||
A flexible buffer object wich automatically resizes, if neccessary.
|
|
||||||
*/
|
|
||||||
struct _pcp_buffer {
|
|
||||||
char *name; /**< just for convenience in error messages and the like, so we know which buffer cause trouble */
|
|
||||||
uint8_t allocated; /**< marks the buffer as allocated */
|
|
||||||
size_t blocksize; /**< the blocksize to use when resizing, also used for initial malloc() */
|
|
||||||
size_t size; /**< stores the current allocated size of the object */
|
|
||||||
size_t offset; /**< current read position */
|
|
||||||
size_t end; /**< current write position, data end. maybe less than size. */
|
|
||||||
uint8_t isstring; /**< treat as char array/string */
|
|
||||||
void *buf; /**< the actual storage buffer */
|
|
||||||
};
|
|
||||||
|
|
||||||
/** The name used everywhere */
|
|
||||||
typedef struct _pcp_buffer Buffer;
|
|
||||||
|
|
||||||
/** Create a new buffer.
|
/** Create a new buffer.
|
||||||
|
|
||||||
@@ -591,8 +578,7 @@ uint64_t buffer_last64(Buffer *b);
|
|||||||
\param[in] len The number of bytes to read.
|
\param[in] len The number of bytes to read.
|
||||||
|
|
||||||
\return Returns the number of bytes read or 0 in case of an error or EOF.
|
\return Returns the number of bytes read or 0 in case of an error or EOF.
|
||||||
Use feof() and ferror() to check this afterwards, call fatals_ifany()
|
Use feof() and ferror() to check this afterwards.
|
||||||
in case of errors.
|
|
||||||
*/
|
*/
|
||||||
size_t buffer_fd_read(Buffer *b, FILE *in, size_t len);
|
size_t buffer_fd_read(Buffer *b, FILE *in, size_t len);
|
||||||
|
|
||||||
|
|||||||
95
include/pcp/context.h
Normal file
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 "keyhash.h"
|
||||||
#include "ed.h"
|
#include "ed.h"
|
||||||
#include "pcpstream.h"
|
#include "pcpstream.h"
|
||||||
|
#include "context.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
\defgroup CRYPTO CRYPTO
|
\defgroup CRYPTO CRYPTO
|
||||||
@@ -146,7 +147,7 @@ int pcp_sodium_verify_box(byte **cleartext, byte* message,
|
|||||||
\return Returns an allocated byte array of the size csize which contains the encrypted result.
|
\return Returns an allocated byte array of the size csize which contains the encrypted result.
|
||||||
In case of an error, it returns NULL sets csize to 0. Use fatals_ifany() to check for errors.
|
In case of an error, it returns NULL sets csize to 0. Use fatals_ifany() to check for errors.
|
||||||
*/
|
*/
|
||||||
byte *pcp_box_encrypt(pcp_key_t *secret, pcp_pubkey_t *pub,
|
byte *pcp_box_encrypt(PCPCTX *ptx, pcp_key_t *secret, pcp_pubkey_t *pub,
|
||||||
byte *message, size_t messagesize,
|
byte *message, size_t messagesize,
|
||||||
size_t *csize);
|
size_t *csize);
|
||||||
|
|
||||||
@@ -157,6 +158,8 @@ byte *pcp_box_encrypt(pcp_key_t *secret, pcp_pubkey_t *pub,
|
|||||||
requirement to work with raw NaCL crypto_box() output. This
|
requirement to work with raw NaCL crypto_box() output. This
|
||||||
function adds the neccessary padding and it uses PCP key structures.
|
function adds the neccessary padding and it uses PCP key structures.
|
||||||
|
|
||||||
|
\param[in] pcp context.
|
||||||
|
|
||||||
\param[in] secret The secret key structure from the sender.
|
\param[in] secret The secret key structure from the sender.
|
||||||
|
|
||||||
\param[in] pub The public key structure from the recipient.
|
\param[in] pub The public key structure from the recipient.
|
||||||
@@ -170,7 +173,7 @@ byte *pcp_box_encrypt(pcp_key_t *secret, pcp_pubkey_t *pub,
|
|||||||
\return Returns an allocated byte array of the size csize which contains the encrypted result.
|
\return Returns an allocated byte array of the size csize which contains the encrypted result.
|
||||||
In case of an error, it returns NULL sets csize to 0. Use fatals_ifany() to check for errors.
|
In case of an error, it returns NULL sets csize to 0. Use fatals_ifany() to check for errors.
|
||||||
*/
|
*/
|
||||||
byte *pcp_box_decrypt(pcp_key_t *secret, pcp_pubkey_t *pub,
|
byte *pcp_box_decrypt(PCPCTX *ptx, pcp_key_t *secret, pcp_pubkey_t *pub,
|
||||||
byte *cipher, size_t ciphersize,
|
byte *cipher, size_t ciphersize,
|
||||||
size_t *dsize);
|
size_t *dsize);
|
||||||
|
|
||||||
@@ -182,6 +185,8 @@ byte *pcp_box_decrypt(pcp_key_t *secret, pcp_pubkey_t *pub,
|
|||||||
|
|
||||||
Calls pcp_encrypt_stream_sym() after assembling the encrypted recipient list.
|
Calls pcp_encrypt_stream_sym() after assembling the encrypted recipient list.
|
||||||
|
|
||||||
|
\param[in] pcp context.
|
||||||
|
|
||||||
\param[in] in Stream to read the data to encrypt from.
|
\param[in] in Stream to read the data to encrypt from.
|
||||||
|
|
||||||
\param[out] out Stream to write encrypted result to.
|
\param[out] out Stream to write encrypted result to.
|
||||||
@@ -194,7 +199,7 @@ byte *pcp_box_decrypt(pcp_key_t *secret, pcp_pubkey_t *pub,
|
|||||||
|
|
||||||
\return Returns the size of the output written to the output stream or 0 in case of errors.
|
\return Returns the size of the output written to the output stream or 0 in case of errors.
|
||||||
*/
|
*/
|
||||||
size_t pcp_encrypt_stream(Pcpstream *in, Pcpstream* out, pcp_key_t *s, pcp_pubkey_t *p, int signcrypt);
|
size_t pcp_encrypt_stream(PCPCTX *ptx, Pcpstream *in, Pcpstream* out, pcp_key_t *s, pcp_pubkey_t *p, int signcrypt);
|
||||||
|
|
||||||
/** Symmetrically encrypt a file or a buffer stream.
|
/** Symmetrically encrypt a file or a buffer stream.
|
||||||
|
|
||||||
@@ -204,6 +209,8 @@ size_t pcp_encrypt_stream(Pcpstream *in, Pcpstream* out, pcp_key_t *s, pcp_pubke
|
|||||||
|
|
||||||
Uses crypto_secret_box() for each 32k-block with a random nonce for each.
|
Uses crypto_secret_box() for each 32k-block with a random nonce for each.
|
||||||
|
|
||||||
|
\param[in] pcp context.
|
||||||
|
|
||||||
\param[in] in Stream to read the data to encrypt from.
|
\param[in] in Stream to read the data to encrypt from.
|
||||||
|
|
||||||
\param[out] out Stream to write encrypted result to.
|
\param[out] out Stream to write encrypted result to.
|
||||||
@@ -217,7 +224,7 @@ size_t pcp_encrypt_stream(Pcpstream *in, Pcpstream* out, pcp_key_t *s, pcp_pubke
|
|||||||
|
|
||||||
\return Returns the size of the output written to the output stream or 0 in case of errors.
|
\return Returns the size of the output written to the output stream or 0 in case of errors.
|
||||||
*/
|
*/
|
||||||
size_t pcp_encrypt_stream_sym(Pcpstream *in, Pcpstream* out, byte *symkey, int havehead, pcp_rec_t *recsign);
|
size_t pcp_encrypt_stream_sym(PCPCTX *ptx, Pcpstream *in, Pcpstream* out, byte *symkey, int havehead, pcp_rec_t *recsign);
|
||||||
|
|
||||||
|
|
||||||
/** Asymmetrically decrypt a file or a buffer stream.
|
/** Asymmetrically decrypt a file or a buffer stream.
|
||||||
@@ -229,6 +236,8 @@ size_t pcp_encrypt_stream_sym(Pcpstream *in, Pcpstream* out, byte *symkey, int h
|
|||||||
|
|
||||||
FIXME: should return the pcp_rec_t structure upon successfull verification somehow.
|
FIXME: should return the pcp_rec_t structure upon successfull verification somehow.
|
||||||
|
|
||||||
|
\param[in] pcp context.
|
||||||
|
|
||||||
\param[in] in Stream to read the data to decrypt from.
|
\param[in] in Stream to read the data to decrypt from.
|
||||||
|
|
||||||
\param[out] out Stream to write decrypted result to.
|
\param[out] out Stream to write decrypted result to.
|
||||||
@@ -241,7 +250,7 @@ size_t pcp_encrypt_stream_sym(Pcpstream *in, Pcpstream* out, byte *symkey, int h
|
|||||||
|
|
||||||
\return Returns the size of the output written to the output stream or 0 in case of errors.
|
\return Returns the size of the output written to the output stream or 0 in case of errors.
|
||||||
*/
|
*/
|
||||||
size_t pcp_decrypt_stream(Pcpstream *in, Pcpstream* out, pcp_key_t *s, byte *symkey, int verify);
|
size_t pcp_decrypt_stream(PCPCTX *ptx, Pcpstream *in, Pcpstream* out, pcp_key_t *s, byte *symkey, int verify);
|
||||||
|
|
||||||
|
|
||||||
/** Symmetrically decrypt a file or a buffer stream.
|
/** Symmetrically decrypt a file or a buffer stream.
|
||||||
@@ -253,6 +262,8 @@ size_t pcp_decrypt_stream(Pcpstream *in, Pcpstream* out, pcp_key_t *s, byte *sym
|
|||||||
|
|
||||||
Uses crypto_secret_box_open() for each 32k+16-block with a random nonce for each.
|
Uses crypto_secret_box_open() for each 32k+16-block with a random nonce for each.
|
||||||
|
|
||||||
|
\param[in] pcp context.
|
||||||
|
|
||||||
\param[in] in Stream to read the data to decrypt from.
|
\param[in] in Stream to read the data to decrypt from.
|
||||||
|
|
||||||
\param[out] out Stream to write decrypted result to.
|
\param[out] out Stream to write decrypted result to.
|
||||||
@@ -263,7 +274,7 @@ size_t pcp_decrypt_stream(Pcpstream *in, Pcpstream* out, pcp_key_t *s, byte *sym
|
|||||||
|
|
||||||
\return Returns the size of the output written to the output stream or 0 in case of errors.
|
\return Returns the size of the output written to the output stream or 0 in case of errors.
|
||||||
*/
|
*/
|
||||||
size_t pcp_decrypt_stream_sym(Pcpstream *in, Pcpstream* out, byte *symkey, pcp_rec_t *recverify);
|
size_t pcp_decrypt_stream_sym(PCPCTX *ptx, Pcpstream *in, Pcpstream* out, byte *symkey, pcp_rec_t *recverify);
|
||||||
|
|
||||||
pcp_rec_t *pcp_rec_new(byte *cipher, size_t clen, pcp_key_t *secret, pcp_pubkey_t *pub);
|
pcp_rec_t *pcp_rec_new(byte *cipher, size_t clen, pcp_key_t *secret, pcp_pubkey_t *pub);
|
||||||
void pcp_rec_free(pcp_rec_t *r);
|
void pcp_rec_free(pcp_rec_t *r);
|
||||||
|
|||||||
@@ -137,66 +137,45 @@ typedef enum _PCP_KEY_TYPES {
|
|||||||
|
|
||||||
#define PCP_RFC_CIPHER 0x21 /* curve25519+ed25519+poly1305+salsa20+blake2 */
|
#define PCP_RFC_CIPHER 0x21 /* curve25519+ed25519+poly1305+salsa20+blake2 */
|
||||||
|
|
||||||
/**
|
|
||||||
* \defgroup FATALS FATALS
|
|
||||||
* @{
|
|
||||||
|
|
||||||
A couple of functions to catch errors and display them.
|
|
||||||
|
|
||||||
*/
|
/* defines for key management (mgmt.c) */
|
||||||
|
#define EXP_PK_CIPHER 0x21
|
||||||
|
#define EXP_PK_CIPHER_NAME "CURVE25519-ED25519-POLY1305-SALSA20"
|
||||||
|
|
||||||
/* error handling */
|
#define EXP_HASH_CIPHER 0x22
|
||||||
|
#define EXP_HASH_NAME "BLAKE2"
|
||||||
|
|
||||||
/** \var PCP_ERR
|
#define EXP_SIG_CIPHER 0x23
|
||||||
|
#define EXP_SIG_CIPHER_NAME "ED25519"
|
||||||
|
|
||||||
Global variable holding the last error message.
|
#define EXP_SIG_VERSION 0x01
|
||||||
Can be retrieved with fatals_ifany().
|
#define EXP_SIG_TYPE 0x1F /* self signed */
|
||||||
*/
|
|
||||||
extern char *PCP_ERR;
|
|
||||||
|
|
||||||
/** \var PCP_ERRSET
|
/* sig sub notiation we support */
|
||||||
|
#define EXP_SIG_SUB_CTIME 2
|
||||||
|
#define EXP_SIG_SUB_SIGEXPIRE 3
|
||||||
|
#define EXP_SIG_SUB_KEYEXPIRE 9
|
||||||
|
#define EXP_SIG_SUB_NOTATION 20
|
||||||
|
#define EXP_SIG_SUB_KEYFLAGS 27
|
||||||
|
|
||||||
Global variable indicating if an error occurred.
|
/* in armored mode, we're using the usual head+foot */
|
||||||
*/
|
#define EXP_PK_HEADER "----- BEGIN ED25519-CURVE29915 PUBLIC KEY -----"
|
||||||
extern byte PCP_ERRSET;
|
#define EXP_PK_FOOTER "----- END ED25519-CURVE29915 PUBLIC KEY -----"
|
||||||
|
#define EXP_SK_HEADER "----- BEGIN ED25519-CURVE29915 PRIVATE KEY -----"
|
||||||
|
#define EXP_SK_FOOTER "----- END ED25519-CURVE29915 PRIVATE KEY -----"
|
||||||
|
|
||||||
/** \var PCP_EXIT
|
|
||||||
|
|
||||||
Exitcode for the pcp commandline utility.
|
/* pubkey export formats */
|
||||||
*/
|
#define EXP_FORMAT_NATIVE 1
|
||||||
extern int PCP_EXIT;
|
#define EXP_FORMAT_PBP 2
|
||||||
|
#define EXP_FORMAT_YAML 3
|
||||||
|
#define EXP_FORMAT_C 4
|
||||||
|
#define EXP_FORMAT_PY 5
|
||||||
|
#define EXP_FORMAT_PERL 6
|
||||||
|
|
||||||
/** Set an error message.
|
|
||||||
|
|
||||||
This function gets a printf() like error message,
|
|
||||||
which it stores in the global PCP_ERR variable
|
|
||||||
and sets PCP_ERRSET to 1.
|
|
||||||
|
|
||||||
\param[in] fmt printf() like format description.
|
|
||||||
|
|
||||||
\param[in] ... format parameters, if any.
|
|
||||||
*/
|
|
||||||
void fatal(const char * fmt, ...);
|
|
||||||
|
|
||||||
/** Prints error messages to STDERR, if there are some.
|
|
||||||
|
|
||||||
FIXME: add something like this which returns the
|
|
||||||
message.
|
|
||||||
*/
|
|
||||||
void fatals_ifany();
|
|
||||||
|
|
||||||
/** Reset the error variables.
|
|
||||||
|
|
||||||
This can be used to ignore previous errors.
|
|
||||||
Use with care.
|
|
||||||
*/
|
|
||||||
void fatals_reset();
|
|
||||||
|
|
||||||
/** Cleans up memory allocation of global error variables.
|
|
||||||
*/
|
|
||||||
void fatals_done();
|
|
||||||
|
|
||||||
extern int PCPVERBOSE;
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* _DEFINES_H */
|
#endif /* _DEFINES_H */
|
||||||
|
|||||||
@@ -41,6 +41,7 @@
|
|||||||
#include "keyhash.h"
|
#include "keyhash.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "pcpstream.h"
|
#include "pcpstream.h"
|
||||||
|
#include "context.h"
|
||||||
|
|
||||||
/** Sign a raw message.
|
/** Sign a raw message.
|
||||||
|
|
||||||
@@ -80,6 +81,8 @@ byte *pcp_ed_sign(byte *message, size_t messagesize, pcp_key_t *s);
|
|||||||
|
|
||||||
The signature must contain the message+nacl signature (with size crypto_sign_BYTES).
|
The signature must contain the message+nacl signature (with size crypto_sign_BYTES).
|
||||||
|
|
||||||
|
\param[in] pcp context.
|
||||||
|
|
||||||
\param[in] signature Message+signature.
|
\param[in] signature Message+signature.
|
||||||
|
|
||||||
\param[in] siglen Size of message+signature.
|
\param[in] siglen Size of message+signature.
|
||||||
@@ -89,7 +92,7 @@ byte *pcp_ed_sign(byte *message, size_t messagesize, pcp_key_t *s);
|
|||||||
\return If the signature verifies return the raw message with the signature removed (size: siglen - crypto_sign_BYTES),
|
\return If the signature verifies return the raw message with the signature removed (size: siglen - crypto_sign_BYTES),
|
||||||
returns NULL in case of errors. Check fatals_if_any().
|
returns NULL in case of errors. Check fatals_if_any().
|
||||||
*/
|
*/
|
||||||
byte *pcp_ed_verify(byte *signature, size_t siglen, pcp_pubkey_t *p);
|
byte *pcp_ed_verify(PCPCTX *ptx, byte *signature, size_t siglen, pcp_pubkey_t *p);
|
||||||
|
|
||||||
/** Verify a signature using the mastersecret.
|
/** Verify a signature using the mastersecret.
|
||||||
|
|
||||||
@@ -97,6 +100,8 @@ byte *pcp_ed_verify(byte *signature, size_t siglen, pcp_pubkey_t *p);
|
|||||||
|
|
||||||
The signature must contain the message+nacl signature (with size crypto_sign_BYTES).
|
The signature must contain the message+nacl signature (with size crypto_sign_BYTES).
|
||||||
|
|
||||||
|
\param[in] pcp context.
|
||||||
|
|
||||||
\param[in] signature Message+signature.
|
\param[in] signature Message+signature.
|
||||||
|
|
||||||
\param[in] siglen Size of message+signature.
|
\param[in] siglen Size of message+signature.
|
||||||
@@ -106,7 +111,7 @@ byte *pcp_ed_verify(byte *signature, size_t siglen, pcp_pubkey_t *p);
|
|||||||
\return If the signature verifies return the raw message with the signature removed (size: siglen - crypto_sign_BYTES),
|
\return If the signature verifies return the raw message with the signature removed (size: siglen - crypto_sign_BYTES),
|
||||||
returns NULL in case of errors. Check fatals_if_any().
|
returns NULL in case of errors. Check fatals_if_any().
|
||||||
*/
|
*/
|
||||||
byte *pcp_ed_verify_key(byte *signature, size_t siglen, pcp_pubkey_t *p);
|
byte *pcp_ed_verify_key(PCPCTX *ptx, byte *signature, size_t siglen, pcp_pubkey_t *p);
|
||||||
|
|
||||||
/** Sign a stream in 32k block mode.
|
/** Sign a stream in 32k block mode.
|
||||||
|
|
||||||
@@ -114,6 +119,8 @@ byte *pcp_ed_verify_key(byte *signature, size_t siglen, pcp_pubkey_t *p);
|
|||||||
of the contents of the stream. It outputs the stream to \a out, also blockwise
|
of the contents of the stream. It outputs the stream to \a out, also blockwise
|
||||||
and appends the signature afterwards, which consists of the hash+nacl-signature.
|
and appends the signature afterwards, which consists of the hash+nacl-signature.
|
||||||
|
|
||||||
|
\param[in] pcp context.
|
||||||
|
|
||||||
\param[in] in Stream to read from.
|
\param[in] in Stream to read from.
|
||||||
|
|
||||||
\param[out] out Stream to write to.
|
\param[out] out Stream to write to.
|
||||||
@@ -125,7 +132,7 @@ byte *pcp_ed_verify_key(byte *signature, size_t siglen, pcp_pubkey_t *p);
|
|||||||
\return Returns the number of bytes written to the output stream.
|
\return Returns the number of bytes written to the output stream.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
size_t pcp_ed_sign_buffered(Pcpstream *in, Pcpstream *out, pcp_key_t *s, int z85);
|
size_t pcp_ed_sign_buffered(PCPCTX *ptx, Pcpstream *in, Pcpstream *out, pcp_key_t *s, int z85);
|
||||||
|
|
||||||
|
|
||||||
/** Verify a signature from a stream in 32k block mode.
|
/** Verify a signature from a stream in 32k block mode.
|
||||||
@@ -140,6 +147,8 @@ size_t pcp_ed_sign_buffered(Pcpstream *in, Pcpstream *out, pcp_key_t *s, int z85
|
|||||||
the global public key hash pcppubkey_hash to find a public key which is able to verify
|
the global public key hash pcppubkey_hash to find a public key which is able to verify
|
||||||
the signature.
|
the signature.
|
||||||
|
|
||||||
|
\param[in] pcp context.
|
||||||
|
|
||||||
\param[in] in Stream to read from.
|
\param[in] in Stream to read from.
|
||||||
|
|
||||||
\param[in] p Pointer to public key structure.
|
\param[in] p Pointer to public key structure.
|
||||||
@@ -147,7 +156,7 @@ size_t pcp_ed_sign_buffered(Pcpstream *in, Pcpstream *out, pcp_key_t *s, int z85
|
|||||||
\return Returns a pointer to a public key which were used to verify the signature or NULL if
|
\return Returns a pointer to a public key which were used to verify the signature or NULL if
|
||||||
an error occurred. Check fatals_if_any().
|
an error occurred. Check fatals_if_any().
|
||||||
*/
|
*/
|
||||||
pcp_pubkey_t *pcp_ed_verify_buffered(Pcpstream *in, pcp_pubkey_t *p);
|
pcp_pubkey_t *pcp_ed_verify_buffered(PCPCTX *ptx, Pcpstream *in, pcp_pubkey_t *p);
|
||||||
|
|
||||||
/** Generate a detached signature from a stream in 32k block mode.
|
/** Generate a detached signature from a stream in 32k block mode.
|
||||||
|
|
||||||
@@ -174,6 +183,8 @@ size_t pcp_ed_detachsign_buffered(Pcpstream *in, Pcpstream *out, pcp_key_t *s);
|
|||||||
the signature hash with the hash it calculated
|
the signature hash with the hash it calculated
|
||||||
from the signed content.
|
from the signed content.
|
||||||
|
|
||||||
|
\param[in] pcp context.
|
||||||
|
|
||||||
\param[in] in Stream to read from.
|
\param[in] in Stream to read from.
|
||||||
|
|
||||||
\param[in] sigfd Stream containing the detached signature.
|
\param[in] sigfd Stream containing the detached signature.
|
||||||
@@ -184,7 +195,7 @@ size_t pcp_ed_detachsign_buffered(Pcpstream *in, Pcpstream *out, pcp_key_t *s);
|
|||||||
an error occurred. Check fatals_if_any().
|
an error occurred. Check fatals_if_any().
|
||||||
|
|
||||||
*/
|
*/
|
||||||
pcp_pubkey_t *pcp_ed_detachverify_buffered(Pcpstream *in, Pcpstream *sigfd, pcp_pubkey_t *p);
|
pcp_pubkey_t *pcp_ed_detachverify_buffered(PCPCTX *ptx, Pcpstream *in, Pcpstream *sigfd, pcp_pubkey_t *p);
|
||||||
|
|
||||||
#endif /* _HAVE_PCP_ED_H */
|
#endif /* _HAVE_PCP_ED_H */
|
||||||
|
|
||||||
|
|||||||
@@ -31,16 +31,16 @@
|
|||||||
#include "defines.h"
|
#include "defines.h"
|
||||||
#include "platform.h"
|
#include "platform.h"
|
||||||
#include "mem.h"
|
#include "mem.h"
|
||||||
#include "buffer.h"
|
|
||||||
#include "mac.h"
|
#include "mac.h"
|
||||||
#include "randomart.h"
|
#include "randomart.h"
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
#include "z85.h"
|
//#include "z85.h"
|
||||||
#include "uthash.h"
|
#include "uthash.h"
|
||||||
#include "jenhash.h"
|
#include "jenhash.h"
|
||||||
#include "scrypt.h"
|
#include "structs.h"
|
||||||
|
#include "buffer.h"
|
||||||
#include "keysig.h"
|
#include "keysig.h"
|
||||||
|
#include "scrypt.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \defgroup KEYS KEYS
|
* \defgroup KEYS KEYS
|
||||||
@@ -53,126 +53,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
/** \struct _pcp_key_t
|
|
||||||
|
|
||||||
PCP private key structure. Most fields are self explanatory.
|
|
||||||
|
|
||||||
Some notes:
|
|
||||||
|
|
||||||
'encrypted' contains the encrypted secret keys (contatenated mastersecret,
|
|
||||||
secret and edsecret). If it's set,
|
|
||||||
the field 'secret' which contains the clear secret key will
|
|
||||||
be zeroed with random values, the first byte will be 0. Same
|
|
||||||
for the field 'edsecret'.
|
|
||||||
|
|
||||||
'nonce' contains the nonce required to decrypt the encrypted
|
|
||||||
secret, if set.
|
|
||||||
|
|
||||||
'serial' is a random number.
|
|
||||||
|
|
||||||
'id' is a string containing the hex values of the CRC32 checksum
|
|
||||||
of the public and secret key.
|
|
||||||
|
|
||||||
Upon creation everything will be filled with random bytes.
|
|
||||||
String fields will contain a string followed by 0 followed
|
|
||||||
by the rest of the pre-filled random bytes. To denote a string
|
|
||||||
field as empty, the first byte will be set to 0.
|
|
||||||
|
|
||||||
There are dynamically calculated attributes as well:
|
|
||||||
|
|
||||||
'checksum' is a 256 bit SHA hash of the public key returned
|
|
||||||
by pcpkey_getchecksum() or pcppubkey_getchecksum().
|
|
||||||
|
|
||||||
'random id' is a random art ascii image returned by
|
|
||||||
pcppubkey_get_art() or pcpkey_get_art(), calculated from
|
|
||||||
the public key.
|
|
||||||
|
|
||||||
If exported to a single file or printed, the structure will
|
|
||||||
be encoded using Z85 encoding.
|
|
||||||
|
|
||||||
*/
|
|
||||||
struct _pcp_key_t {
|
|
||||||
byte masterpub[32]; /**< ED25519 master public key signing key */
|
|
||||||
byte mastersecret[64]; /**< ED25519 master secret key signing key */
|
|
||||||
byte pub[32]; /**< Curve25519 encryption public key */
|
|
||||||
byte secret[32]; /**< Curve25519 encryption secret key */
|
|
||||||
byte edpub[32]; /**< ED25519 public signing key */
|
|
||||||
byte edsecret[64]; /**< ED25519 secret signing key */
|
|
||||||
byte nonce[24]; /**< random nonce used to encrypt secret keys */
|
|
||||||
byte encrypted[176]; /**< concatenated and encrypted secret keys */
|
|
||||||
char owner[255]; /**< the key owner, string */
|
|
||||||
char mail[255]; /**< mail address of the owner, string */
|
|
||||||
char id[17]; /**< key-id, used internally only, jenhash of public keys */
|
|
||||||
uint8_t type; /**< key type: MASTER_SECRET or SECRET */
|
|
||||||
uint64_t ctime; /**< creation time, epoch */
|
|
||||||
uint32_t version; /**< key version */
|
|
||||||
uint32_t serial; /**< serial number of the key, randomly generated */
|
|
||||||
UT_hash_handle hh;
|
|
||||||
};
|
|
||||||
|
|
||||||
/** Typedef for secret keys */
|
|
||||||
typedef struct _pcp_key_t pcp_key_t;
|
|
||||||
|
|
||||||
/** \struct _pcp_pubkey_t
|
|
||||||
|
|
||||||
PCP public key structure.
|
|
||||||
|
|
||||||
This structure contains a subset of the pcp_key_t structure
|
|
||||||
without the secret and nonce fields.
|
|
||||||
*/
|
|
||||||
struct _pcp_pubkey_t {
|
|
||||||
byte masterpub[32]; /**< ED25519 master public key signing key */
|
|
||||||
byte sigpub[32]; /**< ED25519 public signing key */
|
|
||||||
byte pub[32]; /**< Curve25519 encryption public key */
|
|
||||||
byte edpub[32]; /**< ED25519 public signing key (FIXME: huh? 2 of them???) */
|
|
||||||
char owner[255]; /**< the key owner, string */
|
|
||||||
char mail[255]; /**< mail address of the owner, string */
|
|
||||||
char id[17]; /**< key-id, used internally only, jenhash of public keys */
|
|
||||||
uint8_t type; /**< key type: MASTER_SECRET or SECRET */
|
|
||||||
uint64_t ctime; /**< creation time, epoch */
|
|
||||||
uint32_t version; /**< key version */
|
|
||||||
uint32_t serial; /**< serial number of the key, randomly generated */
|
|
||||||
uint8_t valid; /**< 1 if import signature verified, 0 if not */
|
|
||||||
byte signature[crypto_generichash_BYTES_MAX + crypto_sign_BYTES]; /**< raw binary blob of pubkey export signature */
|
|
||||||
UT_hash_handle hh;
|
|
||||||
};
|
|
||||||
|
|
||||||
/** Typedef for public keys */
|
|
||||||
typedef struct _pcp_pubkey_t pcp_pubkey_t;
|
|
||||||
|
|
||||||
|
|
||||||
/* the PBP public key format */
|
|
||||||
/* keys.mp+keys.cp+keys.sp+keys.name */
|
|
||||||
struct _pbp_pubkey_t {
|
|
||||||
byte sigpub[crypto_sign_PUBLICKEYBYTES];
|
|
||||||
byte edpub[crypto_sign_PUBLICKEYBYTES];
|
|
||||||
byte pub[crypto_box_PUBLICKEYBYTES];
|
|
||||||
char iso_ctime[32];
|
|
||||||
char iso_expire[32];
|
|
||||||
char name[1024];
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct _pbp_pubkey_t pbp_pubkey_t;
|
|
||||||
|
|
||||||
/** \struct _pcp_rec_t
|
|
||||||
|
|
||||||
Encrypted recipient list.
|
|
||||||
|
|
||||||
Encrypted recipient list, required for crypt+sign
|
|
||||||
contains the encrypted recipients and the secret
|
|
||||||
key required for signing the message+recipients.
|
|
||||||
|
|
||||||
Used internally only.
|
|
||||||
*/
|
|
||||||
struct _pcp_rec_t {
|
|
||||||
size_t ciphersize; /**< the size of the encrypted recipient list */
|
|
||||||
byte *cipher; /**< contains the whole encrypted recipient list */
|
|
||||||
pcp_key_t *secret; /**< the secret key of the recipient for signing */
|
|
||||||
pcp_pubkey_t *pub; /**< if verification were ok, contains the public key of the signer */
|
|
||||||
};
|
|
||||||
|
|
||||||
/** Typedef for public keys */
|
|
||||||
typedef struct _pcp_rec_t pcp_rec_t;
|
|
||||||
|
|
||||||
#define PCP_RAW_KEYSIZE sizeof(pcp_key_t) - sizeof(UT_hash_handle)
|
#define PCP_RAW_KEYSIZE sizeof(pcp_key_t) - sizeof(UT_hash_handle)
|
||||||
#define PCP_RAW_PUBKEYSIZE sizeof(pcp_pubkey_t) - sizeof(UT_hash_handle)
|
#define PCP_RAW_PUBKEYSIZE sizeof(pcp_pubkey_t) - sizeof(UT_hash_handle)
|
||||||
@@ -253,6 +134,8 @@ char *pcpkey_get_art(pcp_key_t *k);
|
|||||||
The caller is responsible to clear the passphrase right after
|
The caller is responsible to clear the passphrase right after
|
||||||
use and free() it as soon as possible.
|
use and free() it as soon as possible.
|
||||||
|
|
||||||
|
\param[in] pcp context.
|
||||||
|
|
||||||
\param[in,out] key The secret key structure.
|
\param[in,out] key The secret key structure.
|
||||||
|
|
||||||
\param[in] passphrase The passphrase used to encrypt the key.
|
\param[in] passphrase The passphrase used to encrypt the key.
|
||||||
@@ -260,7 +143,7 @@ char *pcpkey_get_art(pcp_key_t *k);
|
|||||||
\return Returns a pointer to the encrypted key structure or NULL
|
\return Returns a pointer to the encrypted key structure or NULL
|
||||||
in case of an error. Use fatals_ifany() to catch them.
|
in case of an error. Use fatals_ifany() to catch them.
|
||||||
*/
|
*/
|
||||||
pcp_key_t *pcpkey_encrypt(pcp_key_t *key, char *passphrase);
|
pcp_key_t *pcpkey_encrypt(PCPCTX *ptx, pcp_key_t *key, char *passphrase);
|
||||||
|
|
||||||
/** Decrypt a secret key structure.
|
/** Decrypt a secret key structure.
|
||||||
|
|
||||||
@@ -277,6 +160,8 @@ pcp_key_t *pcpkey_encrypt(pcp_key_t *key, char *passphrase);
|
|||||||
The caller is responsible to clear the passphrase right after
|
The caller is responsible to clear the passphrase right after
|
||||||
use and free() it as soon as possible.
|
use and free() it as soon as possible.
|
||||||
|
|
||||||
|
\param[in] pcp context.
|
||||||
|
|
||||||
\param[in,out] key The secret key structure.
|
\param[in,out] key The secret key structure.
|
||||||
|
|
||||||
\param[in] passphrase The passphrase used to decrypt the key.
|
\param[in] passphrase The passphrase used to decrypt the key.
|
||||||
@@ -285,7 +170,7 @@ pcp_key_t *pcpkey_encrypt(pcp_key_t *key, char *passphrase);
|
|||||||
in case of an error. Use fatals_ifany() to catch them.
|
in case of an error. Use fatals_ifany() to catch them.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
pcp_key_t *pcpkey_decrypt(pcp_key_t *key, char *passphrase);
|
pcp_key_t *pcpkey_decrypt(PCPCTX *ptx, pcp_key_t *key, char *passphrase);
|
||||||
|
|
||||||
/** Generate a public key structure from a given secret key structure.
|
/** Generate a public key structure from a given secret key structure.
|
||||||
|
|
||||||
@@ -294,6 +179,8 @@ pcp_key_t *pcpkey_decrypt(pcp_key_t *key, char *passphrase);
|
|||||||
|
|
||||||
The caller is responsible to clear and free() it after use.
|
The caller is responsible to clear and free() it after use.
|
||||||
|
|
||||||
|
\param[in] pcp context.
|
||||||
|
|
||||||
\param[in] key The secret key structure.
|
\param[in] key The secret key structure.
|
||||||
|
|
||||||
\return Returns a new pcp_pubkey_t structure.
|
\return Returns a new pcp_pubkey_t structure.
|
||||||
@@ -404,7 +291,7 @@ byte * pcp_gennonce();
|
|||||||
/* use scrypt() to create a key from a passphrase and a nonce
|
/* use scrypt() to create a key from a passphrase and a nonce
|
||||||
this is a wrapper around pcp_scrypt()
|
this is a wrapper around pcp_scrypt()
|
||||||
*/
|
*/
|
||||||
byte *pcp_derivekey(char *passphrase, byte *nonce);
|
byte *pcp_derivekey(PCPCTX *ptx, char *passphrase, byte *nonce);
|
||||||
|
|
||||||
/* convert the key struct into a binary blob */
|
/* convert the key struct into a binary blob */
|
||||||
void pcp_seckeyblob(Buffer *b, pcp_key_t *k);
|
void pcp_seckeyblob(Buffer *b, pcp_key_t *k);
|
||||||
@@ -418,19 +305,23 @@ Buffer *pcp_keyblob(void *k, int type); /* allocates blob */
|
|||||||
\return Returns 1 if the sanity check succeeds, 0 otherwise.
|
\return Returns 1 if the sanity check succeeds, 0 otherwise.
|
||||||
Use fatals_ifany() to check why.
|
Use fatals_ifany() to check why.
|
||||||
*/
|
*/
|
||||||
int pcp_sanitycheck_pub(pcp_pubkey_t *key);
|
int pcp_sanitycheck_pub(PCPCTX *ptx, pcp_pubkey_t *key);
|
||||||
|
|
||||||
/** Make a sanity check of the given secret key structure.
|
/** Make a sanity check of the given secret key structure.
|
||||||
|
|
||||||
|
\param[in] pcp context.
|
||||||
|
|
||||||
\param[in] key The secret key structure.
|
\param[in] key The secret key structure.
|
||||||
|
|
||||||
\return Returns 1 if the sanity check succeeds, 0 otherwise.
|
\return Returns 1 if the sanity check succeeds, 0 otherwise.
|
||||||
Use fatals_ifany() to check why.
|
Use fatals_ifany() to check why.
|
||||||
*/
|
*/
|
||||||
int pcp_sanitycheck_key(pcp_key_t *key);
|
int pcp_sanitycheck_key(PCPCTX *ptx, pcp_key_t *key);
|
||||||
|
|
||||||
/** Dump a secret key structure to stderr.
|
/** Dump a secret key structure to stderr.
|
||||||
|
|
||||||
|
\param[in] pcp context.
|
||||||
|
|
||||||
\param[in] k Secret key to dump.
|
\param[in] k Secret key to dump.
|
||||||
*/
|
*/
|
||||||
void pcp_dumpkey(pcp_key_t *k);
|
void pcp_dumpkey(pcp_key_t *k);
|
||||||
|
|||||||
@@ -22,6 +22,10 @@
|
|||||||
#ifndef _HAVE_KEYHASH_H
|
#ifndef _HAVE_KEYHASH_H
|
||||||
#define _HAVE_KEYHASH_H
|
#define _HAVE_KEYHASH_H
|
||||||
|
|
||||||
|
#include "structs.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/** \defgroup KEYHASH KEYHASH
|
/** \defgroup KEYHASH KEYHASH
|
||||||
@{
|
@{
|
||||||
|
|
||||||
@@ -29,22 +33,11 @@
|
|||||||
|
|
||||||
Libpcp uses the <a href="http://troydhanson.github.io/uthash/">uthash</a>
|
Libpcp uses the <a href="http://troydhanson.github.io/uthash/">uthash</a>
|
||||||
system to maintain lists of keys. There's one hash per key type. The
|
system to maintain lists of keys. There's one hash per key type. The
|
||||||
hash has the same type as the key structure itself, but is global.
|
hash has the same type as the key structure itself, and is stored in
|
||||||
|
the PCP Context object.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "uthash.h"
|
|
||||||
#include "key.h"
|
|
||||||
|
|
||||||
/* storage of keys in a global hash */
|
|
||||||
|
|
||||||
/** Global hash for secret keys. */
|
|
||||||
extern pcp_key_t *pcpkey_hash;
|
|
||||||
|
|
||||||
/** Global hash for public keys. */
|
|
||||||
extern pcp_pubkey_t *pcppubkey_hash;
|
|
||||||
|
|
||||||
extern pcp_key_t *__k;
|
|
||||||
extern pcp_pubkey_t *__p;
|
|
||||||
|
|
||||||
/* wrapper for HASH_ITER */
|
/* wrapper for HASH_ITER */
|
||||||
/** Iterate over the list of secret keys.
|
/** Iterate over the list of secret keys.
|
||||||
@@ -53,7 +46,7 @@ extern pcp_pubkey_t *__p;
|
|||||||
|
|
||||||
@code
|
@code
|
||||||
pcp_key_t k = NULL;
|
pcp_key_t k = NULL;
|
||||||
pcphash_iterate(k) {
|
pcphash_iterate(ptx, k) {
|
||||||
pcp_dumpkey(k);
|
pcp_dumpkey(k);
|
||||||
}
|
}
|
||||||
@endcode
|
@endcode
|
||||||
@@ -61,9 +54,9 @@ extern pcp_pubkey_t *__p;
|
|||||||
Also, don't free() the keyhash or the temporary key pointer
|
Also, don't free() the keyhash or the temporary key pointer
|
||||||
yourself. Use pcphash_clean() instead when done.
|
yourself. Use pcphash_clean() instead when done.
|
||||||
*/
|
*/
|
||||||
#define pcphash_iterate(key) \
|
#define pcphash_iterate(ptx, key) \
|
||||||
__k = NULL; \
|
pcp_key_t *__k = NULL; \
|
||||||
HASH_ITER(hh, pcpkey_hash, key, __k)
|
HASH_ITER(hh, ptx->pcpkey_hash, key, __k)
|
||||||
|
|
||||||
|
|
||||||
/** Iterate over the list of public keys.
|
/** Iterate over the list of public keys.
|
||||||
@@ -72,7 +65,7 @@ extern pcp_pubkey_t *__p;
|
|||||||
|
|
||||||
@code
|
@code
|
||||||
pcp_pubkey_t k = NULL;
|
pcp_pubkey_t k = NULL;
|
||||||
pcphash_iteratepub(k) {
|
pcphash_iteratepub(ptx, k) {
|
||||||
pcp_dumppubkey(k);
|
pcp_dumppubkey(k);
|
||||||
}
|
}
|
||||||
@endcode
|
@endcode
|
||||||
@@ -80,75 +73,77 @@ extern pcp_pubkey_t *__p;
|
|||||||
Also, don't free() the keyhash or the temporary key pointer
|
Also, don't free() the keyhash or the temporary key pointer
|
||||||
yourself. Use pcphash_clean() instead when done.
|
yourself. Use pcphash_clean() instead when done.
|
||||||
*/
|
*/
|
||||||
#define pcphash_iteratepub(key) \
|
#define pcphash_iteratepub(ptx, key) \
|
||||||
__p = NULL; \
|
pcp_pubkey_t *__p = NULL; \
|
||||||
HASH_ITER(hh, pcppubkey_hash, key, __p)
|
HASH_ITER(hh, ptx->pcppubkey_hash, key, __p)
|
||||||
|
|
||||||
/** Initialize the global hashes. */
|
|
||||||
void pcphash_init();
|
|
||||||
|
|
||||||
/** Delete an entry from a hash.
|
/** Delete an entry from a hash.
|
||||||
|
|
||||||
|
\param[in] PCP Context object.
|
||||||
|
|
||||||
\param[in] key A pointer to the key structure to delete.
|
\param[in] key A pointer to the key structure to delete.
|
||||||
|
|
||||||
\param[in] type An integer specifying the key type to delete. \see _PCP_KEY_TYPES.
|
\param[in] type An integer specifying the key type to delete. \see _PCP_KEY_TYPES.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
void pcphash_del(void *key, int type);
|
void pcphash_del(PCPCTX *ptx, void *key, int type);
|
||||||
|
|
||||||
/** Frees the memory allocated by the hashes.
|
/** Free memory used by key hashes. */
|
||||||
|
void pcphash_clean(PCPCTX *ptx);
|
||||||
Clears and frees memory of all keys in the hash lists
|
|
||||||
and the hashes themselfes.
|
|
||||||
|
|
||||||
*/
|
|
||||||
void pcphash_clean();
|
|
||||||
|
|
||||||
/** Check if a secret key with a given key-id exists in the hash.
|
/** Check if a secret key with a given key-id exists in the hash.
|
||||||
|
|
||||||
|
\param[in] PCP Context object.
|
||||||
|
|
||||||
\param[in] id A string with the key-id (max 17 chars incl 0).
|
\param[in] id A string with the key-id (max 17 chars incl 0).
|
||||||
|
|
||||||
\return Returns a pointer to the matching key or NULL if the id doesn't match.
|
\return Returns a pointer to the matching key or NULL if the id doesn't match.
|
||||||
*/
|
*/
|
||||||
pcp_key_t *pcphash_keyexists(char *id);
|
pcp_key_t *pcphash_keyexists(PCPCTX *ptx, char *id);
|
||||||
|
|
||||||
/** Check if a publickey with a given key-id exists in the hash.
|
/** Check if a publickey with a given key-id exists in the hash.
|
||||||
|
|
||||||
|
\param[in] PCP Context object.
|
||||||
|
|
||||||
\param[in] id A string with the key-id (max 17 chars incl 0).
|
\param[in] id A string with the key-id (max 17 chars incl 0).
|
||||||
|
|
||||||
\return Returns a pointer to the matching key or NULL if the id doesn't match.
|
\return Returns a pointer to the matching key or NULL if the id doesn't match.
|
||||||
*/
|
*/
|
||||||
pcp_pubkey_t *pcphash_pubkeyexists(char *id);
|
pcp_pubkey_t *pcphash_pubkeyexists(PCPCTX *ptx, char *id);
|
||||||
|
|
||||||
/** Add a key structure to the hash list.
|
/** Add a key structure to the hash list.
|
||||||
|
|
||||||
|
\param[in] PCP Context object.
|
||||||
|
|
||||||
\param[in] key A pointer to the key structure to delete.
|
\param[in] key A pointer to the key structure to delete.
|
||||||
|
|
||||||
\param[in] type An integer specifying the key type to delete. \see _PCP_KEY_TYPES.
|
\param[in] type An integer specifying the key type to delete. \see _PCP_KEY_TYPES.
|
||||||
*/
|
*/
|
||||||
void pcphash_add(void *key, int type);
|
void pcphash_add(PCPCTX *ptx, void *key, int type);
|
||||||
|
|
||||||
/** Returns the number of secret keys in the hash.
|
/** Returns the number of secret keys in the hash.
|
||||||
|
|
||||||
|
\param[in] PCP Context object.
|
||||||
|
|
||||||
\return Number of keys.
|
\return Number of keys.
|
||||||
*/
|
*/
|
||||||
int pcphash_count();
|
int pcphash_count(PCPCTX *ptx);
|
||||||
|
|
||||||
/** Returns the number of public keys in the hash.
|
/** Returns the number of public keys in the hash.
|
||||||
|
|
||||||
|
\param[in] PCP Context object.
|
||||||
|
|
||||||
\return Number of keys.
|
\return Number of keys.
|
||||||
*/
|
*/
|
||||||
int pcphash_countpub();
|
int pcphash_countpub(PCPCTX *ptx);
|
||||||
|
|
||||||
/** Global hash for key signatures. */
|
|
||||||
extern pcp_keysig_t *pcpkeysig_hash;
|
|
||||||
extern pcp_keysig_t *__s;
|
|
||||||
|
|
||||||
#define pcphash_iteratekeysig(key) \
|
|
||||||
__s = NULL; \
|
|
||||||
HASH_ITER(hh, pcpkeysig_hash, key, __s)
|
|
||||||
|
|
||||||
pcp_keysig_t *pcphash_keysigexists(char *id);
|
#define pcphash_iteratekeysig(ptx, key) \
|
||||||
|
pcp_keysig_t *__s = NULL; \
|
||||||
|
HASH_ITER(hh, ptx->pcpkeysig_hash, key, __s)
|
||||||
|
|
||||||
|
pcp_keysig_t *pcphash_keysigexists(PCPCTX *ptx, char *id);
|
||||||
|
|
||||||
#endif /* _HAVE_KEYHASH_H */
|
#endif /* _HAVE_KEYHASH_H */
|
||||||
|
|
||||||
|
|||||||
@@ -29,22 +29,13 @@
|
|||||||
#include "defines.h"
|
#include "defines.h"
|
||||||
#include "platform.h"
|
#include "platform.h"
|
||||||
#include "mem.h"
|
#include "mem.h"
|
||||||
|
#include "structs.h"
|
||||||
#include "buffer.h"
|
#include "buffer.h"
|
||||||
#include "key.h"
|
#include "key.h"
|
||||||
|
|
||||||
#define PCP_RAW_KEYSIGSIZE sizeof(pcp_keysig_t) - sizeof(UT_hash_handle)
|
#define PCP_RAW_KEYSIGSIZE sizeof(pcp_keysig_t) - sizeof(UT_hash_handle)
|
||||||
|
|
||||||
/* holds a public key signature */
|
|
||||||
struct _pcp_keysig_t {
|
|
||||||
uint8_t type;
|
|
||||||
uint32_t size;
|
|
||||||
char id[17];
|
|
||||||
byte checksum[32];
|
|
||||||
byte *blob;
|
|
||||||
UT_hash_handle hh;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct _pcp_keysig_t pcp_keysig_t;
|
|
||||||
|
|
||||||
pcp_keysig_t *keysig2be(pcp_keysig_t *s);
|
pcp_keysig_t *keysig2be(pcp_keysig_t *s);
|
||||||
pcp_keysig_t *keysig2native(pcp_keysig_t *s);
|
pcp_keysig_t *keysig2native(pcp_keysig_t *s);
|
||||||
|
|||||||
@@ -33,12 +33,14 @@
|
|||||||
|
|
||||||
#include "defines.h"
|
#include "defines.h"
|
||||||
#include "platform.h"
|
#include "platform.h"
|
||||||
|
#include "structs.h"
|
||||||
#include "mem.h"
|
#include "mem.h"
|
||||||
#include "ed.h"
|
#include "ed.h"
|
||||||
#include "key.h"
|
#include "key.h"
|
||||||
#include "keysig.h"
|
#include "keysig.h"
|
||||||
#include "buffer.h"
|
#include "buffer.h"
|
||||||
#include "scrypt.h"
|
#include "scrypt.h"
|
||||||
|
#include "context.h"
|
||||||
|
|
||||||
/* key management api, export, import, yaml and stuff */
|
/* key management api, export, import, yaml and stuff */
|
||||||
|
|
||||||
@@ -52,76 +54,7 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* various helper structs, used internally only */
|
|
||||||
struct _pcp_rfc_pubkey_header_t {
|
|
||||||
uint8_t version;
|
|
||||||
uint32_t ctime;
|
|
||||||
uint8_t cipher;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct _pcp_rfc_pubkey_0x21_t {
|
|
||||||
byte sig_ed25519_pub[crypto_sign_PUBLICKEYBYTES];
|
|
||||||
byte ed25519_pub[crypto_sign_PUBLICKEYBYTES];
|
|
||||||
byte curve25519_pub[crypto_box_PUBLICKEYBYTES];
|
|
||||||
};
|
|
||||||
|
|
||||||
struct _pcp_rfc_pubkey_sigheader_0x21_t {
|
|
||||||
uint8_t version;
|
|
||||||
uint8_t type;
|
|
||||||
uint8_t pkcipher;
|
|
||||||
uint8_t hashcipher;
|
|
||||||
uint16_t numsubs;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct _pcp_rfc_pubkey_sigsub_0x21_t {
|
|
||||||
uint32_t size;
|
|
||||||
uint8_t type;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct _pcp_rfc_pubkey_header_t rfc_pub_h;
|
|
||||||
typedef struct _pcp_rfc_pubkey_0x21_t rfc_pub_k;
|
|
||||||
typedef struct _pcp_rfc_pubkey_sigheader_0x21_t rfc_pub_sig_h;
|
|
||||||
typedef struct _pcp_rfc_pubkey_sigsub_0x21_t rfc_pub_sig_s;
|
|
||||||
|
|
||||||
struct _pcp_ks_bundle_t {
|
|
||||||
pcp_pubkey_t *p;
|
|
||||||
pcp_keysig_t *s;
|
|
||||||
};
|
|
||||||
typedef struct _pcp_ks_bundle_t pcp_ks_bundle_t;
|
|
||||||
|
|
||||||
#define EXP_PK_CIPHER 0x21
|
|
||||||
#define EXP_PK_CIPHER_NAME "CURVE25519-ED25519-POLY1305-SALSA20"
|
|
||||||
|
|
||||||
#define EXP_HASH_CIPHER 0x22
|
|
||||||
#define EXP_HASH_NAME "BLAKE2"
|
|
||||||
|
|
||||||
#define EXP_SIG_CIPHER 0x23
|
|
||||||
#define EXP_SIG_CIPHER_NAME "ED25519"
|
|
||||||
|
|
||||||
#define EXP_SIG_VERSION 0x01
|
|
||||||
#define EXP_SIG_TYPE 0x1F /* self signed */
|
|
||||||
|
|
||||||
/* sig sub notiation we support */
|
|
||||||
#define EXP_SIG_SUB_CTIME 2
|
|
||||||
#define EXP_SIG_SUB_SIGEXPIRE 3
|
|
||||||
#define EXP_SIG_SUB_KEYEXPIRE 9
|
|
||||||
#define EXP_SIG_SUB_NOTATION 20
|
|
||||||
#define EXP_SIG_SUB_KEYFLAGS 27
|
|
||||||
|
|
||||||
/* in armored mode, we're using the usual head+foot */
|
|
||||||
#define EXP_PK_HEADER "----- BEGIN ED25519-CURVE29915 PUBLIC KEY -----"
|
|
||||||
#define EXP_PK_FOOTER "----- END ED25519-CURVE29915 PUBLIC KEY -----"
|
|
||||||
#define EXP_SK_HEADER "----- BEGIN ED25519-CURVE29915 PRIVATE KEY -----"
|
|
||||||
#define EXP_SK_FOOTER "----- END ED25519-CURVE29915 PRIVATE KEY -----"
|
|
||||||
|
|
||||||
|
|
||||||
/* pubkey export formats */
|
|
||||||
#define EXP_FORMAT_NATIVE 1
|
|
||||||
#define EXP_FORMAT_PBP 2
|
|
||||||
#define EXP_FORMAT_YAML 3
|
|
||||||
#define EXP_FORMAT_C 4
|
|
||||||
#define EXP_FORMAT_PY 5
|
|
||||||
#define EXP_FORMAT_PERL 6
|
|
||||||
|
|
||||||
/** RFC4880 alike public key export with some modifications.
|
/** RFC4880 alike public key export with some modifications.
|
||||||
|
|
||||||
@@ -287,6 +220,8 @@ Buffer *pcp_export_c_pub(pcp_key_t *sk);
|
|||||||
|
|
||||||
Nonce | Cipher
|
Nonce | Cipher
|
||||||
|
|
||||||
|
\param[in] ptx context.
|
||||||
|
|
||||||
\param sk a secret key structure of type pcp_key_t. The secret keys
|
\param sk a secret key structure of type pcp_key_t. The secret keys
|
||||||
in there have to be already decrypted.
|
in there have to be already decrypted.
|
||||||
|
|
||||||
@@ -296,17 +231,21 @@ Buffer *pcp_export_c_pub(pcp_key_t *sk);
|
|||||||
\return the function returns a Buffer object containing the binary
|
\return the function returns a Buffer object containing the binary
|
||||||
blob in the format described above.
|
blob in the format described above.
|
||||||
*/
|
*/
|
||||||
Buffer *pcp_export_secret(pcp_key_t *sk, char *passphrase);
|
Buffer *pcp_export_secret(PCPCTX *ptx, pcp_key_t *sk, char *passphrase);
|
||||||
|
|
||||||
pcp_ks_bundle_t *pcp_import_binpub(byte *raw, size_t rawsize);
|
pcp_ks_bundle_t *pcp_import_binpub(PCPCTX *ptx, byte *raw, size_t rawsize);
|
||||||
pcp_ks_bundle_t *pcp_import_pub(byte *raw, size_t rawsize); /* FIXME: deprecate */
|
pcp_ks_bundle_t *pcp_import_pub(PCPCTX *ptx, byte *raw, size_t rawsize); /* FIXME: deprecate */
|
||||||
pcp_ks_bundle_t *pcp_import_pub_rfc(Buffer *blob);
|
pcp_ks_bundle_t *pcp_import_pub_rfc(PCPCTX *ptx, Buffer *blob);
|
||||||
pcp_ks_bundle_t *pcp_import_pub_pbp(Buffer *blob);
|
pcp_ks_bundle_t *pcp_import_pub_pbp(PCPCTX *ptx, Buffer *blob);
|
||||||
|
|
||||||
/* import secret key */
|
/* import secret key */
|
||||||
pcp_key_t *pcp_import_binsecret(byte *raw, size_t rawsize, char *passphrase);
|
pcp_key_t *pcp_import_binsecret(PCPCTX *ptx, byte *raw, size_t rawsize, char *passphrase);
|
||||||
pcp_key_t *pcp_import_secret(byte *raw, size_t rawsize, char *passphrase);
|
pcp_key_t *pcp_import_secret(PCPCTX *ptx, byte *raw, size_t rawsize, char *passphrase);
|
||||||
pcp_key_t *pcp_import_secret_native(Buffer *cipher, char *passphrase);
|
pcp_key_t *pcp_import_secret_native(PCPCTX *ptx, Buffer *cipher, char *passphrase);
|
||||||
|
|
||||||
|
/* helpers */
|
||||||
|
int _check_keysig_h(PCPCTX *ptx, Buffer *blob, rfc_pub_sig_h *h);
|
||||||
|
int _check_hash_keysig(PCPCTX *ptx, Buffer *blob, pcp_pubkey_t *p, pcp_keysig_t *sk);
|
||||||
|
|
||||||
#endif // _HAVE_PCP_MGMT_H
|
#endif // _HAVE_PCP_MGMT_H
|
||||||
|
|
||||||
|
|||||||
@@ -26,8 +26,10 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include "mem.h"
|
#include "mem.h"
|
||||||
|
#include "structs.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "defines.h"
|
#include "defines.h"
|
||||||
|
#include "context.h"
|
||||||
#include "buffer.h"
|
#include "buffer.h"
|
||||||
#include "z85.h"
|
#include "z85.h"
|
||||||
|
|
||||||
@@ -54,35 +56,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
/** \struct _pcp_stream_t
|
|
||||||
An I/O wrapper object backed by a file or a buffer.
|
|
||||||
*/
|
|
||||||
struct _pcp_stream_t {
|
|
||||||
FILE *fd; /**< The backend FILE stream */
|
|
||||||
Buffer *b; /**< The backend Buffer object */
|
|
||||||
Buffer *cache; /**< The caching Buffer object (for look ahead read) */
|
|
||||||
Buffer *next; /**< The caching Next-Buffer object (for look ahead read) */
|
|
||||||
Buffer *save; /**< Temporary buffer to backup overflow data */
|
|
||||||
uint8_t is_buffer; /**< Set to 1 if the backend is a Buffer */
|
|
||||||
uint8_t eof; /**< Set to 1 if EOF reached */
|
|
||||||
uint8_t err; /**< Set to 1 if an error occured */
|
|
||||||
uint8_t armor; /**< Set to 1 if Z85 en/de-coding is requested */
|
|
||||||
uint8_t determine; /**< Set to 1 to automatically determine armor mode */
|
|
||||||
uint8_t firstread; /**< Internal flag, will be set after first read() */
|
|
||||||
size_t linewr; /**< Used for Z85 writing, number of chars written on last line */
|
|
||||||
size_t blocksize; /**< Blocksize used for z85, if requested */
|
|
||||||
uint8_t is_output; /**< marks the stream as output stream */
|
|
||||||
uint8_t have_begin; /**< flag to indicate we already got the begin header, if any */
|
|
||||||
size_t pos; /**< remember i/o position */
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef enum _PSVARS {
|
|
||||||
PSMAXLINE = 20000
|
|
||||||
} PSVARS;
|
|
||||||
|
|
||||||
|
|
||||||
/** The name used everywhere */
|
|
||||||
typedef struct _pcp_stream_t Pcpstream;
|
|
||||||
|
|
||||||
/* initialize a new empty stream */
|
/* initialize a new empty stream */
|
||||||
Pcpstream *ps_init(void);
|
Pcpstream *ps_init(void);
|
||||||
|
|||||||
@@ -35,8 +35,9 @@
|
|||||||
#include "crypto_scrypt.h"
|
#include "crypto_scrypt.h"
|
||||||
#include "mem.h"
|
#include "mem.h"
|
||||||
#include "defines.h"
|
#include "defines.h"
|
||||||
|
#include "context.h"
|
||||||
|
|
||||||
byte * pcp_scrypt(char *passwd, size_t passwdlen, byte *nonce, size_t noncelen);
|
byte * pcp_scrypt(PCPCTX *ptx, char *passwd, size_t passwdlen, byte *nonce, size_t noncelen);
|
||||||
|
|
||||||
#endif /* _HAVE_PCP_SCRYPT_H */
|
#endif /* _HAVE_PCP_SCRYPT_H */
|
||||||
|
|
||||||
|
|||||||
384
include/pcp/structs.h
Normal file
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 "uthash.h"
|
||||||
#include "buffer.h"
|
#include "buffer.h"
|
||||||
#include "keysig.h"
|
#include "keysig.h"
|
||||||
|
#include "structs.h"
|
||||||
|
#include "context.h"
|
||||||
|
|
||||||
/** \struct _vault_t
|
|
||||||
This structure represents a vault. */
|
|
||||||
struct _vault_t {
|
|
||||||
char *filename; /**< The filename of the vault (full path) */
|
|
||||||
FILE *fd; /**< Filehandle if opened */
|
|
||||||
uint8_t unsafed; /**< Flag to tell if the file needs to be written */
|
|
||||||
uint8_t isnew; /**< Flag to tell if the vault has been newly created */
|
|
||||||
uint32_t size; /**< Filesize */
|
|
||||||
time_t modified; /**< mtime */
|
|
||||||
mode_t mode; /**< File mode */
|
|
||||||
uint32_t version; /**< Vault version */
|
|
||||||
byte checksum[32]; /**< SHA256 checksum over the whole vault */
|
|
||||||
};
|
|
||||||
|
|
||||||
/** Name of the struct */
|
|
||||||
typedef struct _vault_t vault_t;
|
|
||||||
|
|
||||||
/** \struct _vault_header_t
|
|
||||||
Defines the vault header. */
|
|
||||||
struct _vault_header_t {
|
|
||||||
uint8_t fileid; /**< File id, proprietary. Marks the vault as a vault */
|
|
||||||
uint32_t version; /**< File version */
|
|
||||||
byte checksum[32]; /**< SHA256 checksum over the whole vault */
|
|
||||||
};
|
|
||||||
|
|
||||||
/** Name of the struct */
|
|
||||||
typedef struct _vault_header_t vault_header_t;
|
|
||||||
|
|
||||||
/** \struct _vault_item_header_t
|
|
||||||
An item header. */
|
|
||||||
struct _vault_item_header_t {
|
|
||||||
uint8_t type; /**< Item type (secret key, public, key, keysig, \see _PCP_KEY_TYPES */
|
|
||||||
uint32_t size; /**< Size of the item */
|
|
||||||
uint32_t version; /**< Version of the item */
|
|
||||||
byte checksum[32]; /**< SHA256 checksum of the item */
|
|
||||||
};
|
|
||||||
|
|
||||||
/** Name of the struct */
|
|
||||||
typedef struct _vault_item_header_t vault_item_header_t;
|
|
||||||
|
|
||||||
/** Open a vault file.
|
/** Open a vault file.
|
||||||
If the file doesn't exist, it will be created.
|
If the file doesn't exist, it will be created.
|
||||||
|
|
||||||
|
\param[in] pcp context.
|
||||||
\param[in] filename The filename of the vault file.
|
\param[in] filename The filename of the vault file.
|
||||||
|
|
||||||
\return Returns a vault object.
|
\return Returns a vault object.
|
||||||
*/
|
*/
|
||||||
vault_t *pcpvault_init(char *filename);
|
vault_t *pcpvault_init(PCPCTX *ptx, char *filename);
|
||||||
|
|
||||||
|
|
||||||
/* Creates a new vault file. Called internally only.
|
/* Creates a new vault file. Called internally only.
|
||||||
If is_tmp If set to 1, create a temporary vault file.
|
If is_tmp If set to 1, create a temporary vault file.
|
||||||
*/
|
*/
|
||||||
vault_t *pcpvault_new(char *filename, int is_tmp);
|
vault_t *pcpvault_new(PCPCTX *ptx, char *filename, int is_tmp);
|
||||||
|
|
||||||
|
|
||||||
/* Writes the initial vault header to the vault.
|
/* Writes the initial vault header to the vault.
|
||||||
Called internally only. */
|
Called internally only. */
|
||||||
int pcpvault_create(vault_t *vault);
|
int pcpvault_create(PCPCTX *ptx, vault_t *vault);
|
||||||
|
|
||||||
|
|
||||||
/** Add an item to the vault.
|
/** Add an item to the vault.
|
||||||
@@ -160,6 +124,7 @@ int pcpvault_create(vault_t *vault);
|
|||||||
This function writes directly into the vault file. Use
|
This function writes directly into the vault file. Use
|
||||||
with care. To be safe, use pcpvault_addkey() instead.
|
with care. To be safe, use pcpvault_addkey() instead.
|
||||||
|
|
||||||
|
\param[in] pcp context.
|
||||||
\param[out] vault The vault object.
|
\param[out] vault The vault object.
|
||||||
\param[in] item The item to write.
|
\param[in] item The item to write.
|
||||||
\param[in] itemsize Size of the item.
|
\param[in] itemsize Size of the item.
|
||||||
@@ -168,7 +133,7 @@ int pcpvault_create(vault_t *vault);
|
|||||||
\return Returns the number of bytes written or 0 in case of
|
\return Returns the number of bytes written or 0 in case of
|
||||||
an error. Check fatals_if_any().
|
an error. Check fatals_if_any().
|
||||||
*/
|
*/
|
||||||
int pcpvault_additem(vault_t *vault, void *item, size_t itemsize, uint8_t type);
|
int pcpvault_additem(PCPCTX *ptx, vault_t *vault, void *item, size_t itemsize, uint8_t type);
|
||||||
|
|
||||||
|
|
||||||
/** Add a key to the vault.
|
/** Add a key to the vault.
|
||||||
@@ -183,13 +148,14 @@ int pcpvault_additem(vault_t *vault, void *item, size_t itemsize, uint8_t type);
|
|||||||
back to the original location. It then re-calculates the
|
back to the original location. It then re-calculates the
|
||||||
vault checksum and puts it into the vault header.
|
vault checksum and puts it into the vault header.
|
||||||
|
|
||||||
|
\param[in] pcp context.
|
||||||
\param[out] vault The vault object.
|
\param[out] vault The vault object.
|
||||||
\param[in] item The item to write (a key or keysig)
|
\param[in] item The item to write (a key or keysig)
|
||||||
\param[in] type Type of the item. \see _PCP_KEY_TYPES.
|
\param[in] type Type of the item. \see _PCP_KEY_TYPES.
|
||||||
|
|
||||||
\return Returns 0 on success or 1 in case of errors. Check fatals_if_any().
|
\return Returns 0 on success or 1 in case of errors. Check fatals_if_any().
|
||||||
*/
|
*/
|
||||||
int pcpvault_addkey(vault_t *vault, void *item, uint8_t type);
|
int pcpvault_addkey(PCPCTX *ptx, vault_t *vault, void *item, uint8_t type);
|
||||||
|
|
||||||
|
|
||||||
/** Close a vault file.
|
/** Close a vault file.
|
||||||
@@ -201,12 +167,13 @@ int pcpvault_addkey(vault_t *vault, void *item, uint8_t type);
|
|||||||
contain the filename of the backup file, so that the user
|
contain the filename of the backup file, so that the user
|
||||||
doesn't loose data.
|
doesn't loose data.
|
||||||
|
|
||||||
|
\param[in] pcp context.
|
||||||
\param[out] vault The vault object.
|
\param[out] vault The vault object.
|
||||||
|
|
||||||
\return Returns 0. Check fatals_if_any() anyway.
|
\return Returns 0. Check fatals_if_any() anyway.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
int pcpvault_close(vault_t *vault);
|
int pcpvault_close(PCPCTX *ptx, vault_t *vault);
|
||||||
|
|
||||||
|
|
||||||
/** Reads in the vault contents.
|
/** Reads in the vault contents.
|
||||||
@@ -223,27 +190,29 @@ int pcpvault_close(vault_t *vault);
|
|||||||
contents and compares it with the one stored in the vault
|
contents and compares it with the one stored in the vault
|
||||||
header. If it doesn't match an error will be thrown.
|
header. If it doesn't match an error will be thrown.
|
||||||
|
|
||||||
|
\param[in] pcp context.
|
||||||
\param[out] vault The vault object.
|
\param[out] vault The vault object.
|
||||||
|
|
||||||
\return Returns 0 on success or -1 in case of errors. Check fatals_if_any().
|
\return Returns 0 on success or -1 in case of errors. Check fatals_if_any().
|
||||||
*/
|
*/
|
||||||
int pcpvault_fetchall(vault_t *vault);
|
int pcpvault_fetchall(PCPCTX *ptx, vault_t *vault);
|
||||||
|
|
||||||
|
|
||||||
/* Write everything back to disk. */
|
/* Write everything back to disk. */
|
||||||
int pcpvault_writeall(vault_t *vault);
|
int pcpvault_writeall(PCPCTX *ptx, vault_t *vault);
|
||||||
|
|
||||||
/* copy a vault to another file */
|
/* copy a vault to another file */
|
||||||
int pcpvault_copy(vault_t *tmp, vault_t *vault);
|
int pcpvault_copy(PCPCTX *ptx, vault_t *tmp, vault_t *vault);
|
||||||
|
|
||||||
/* delete a vault file */
|
/* delete a vault file */
|
||||||
void pcpvault_unlink(vault_t *tmp);
|
void pcpvault_unlink(vault_t *tmp);
|
||||||
|
|
||||||
/* calculate the checksum of the current vault */
|
/* calculate the checksum of the current vault (that is, from the
|
||||||
byte *pcpvault_create_checksum();
|
list of keys in the current context */
|
||||||
|
byte *pcpvault_create_checksum(PCPCTX *ptx);
|
||||||
|
|
||||||
/* write the new checksum to the header of the current vault */
|
/* write the new checksum to the header of the current vault */
|
||||||
void pcpvault_update_checksum(vault_t *vault);
|
void pcpvault_update_checksum(PCPCTX *ptx, vault_t *vault);
|
||||||
|
|
||||||
/* bigendian converters */
|
/* bigendian converters */
|
||||||
vault_header_t * vh2be(vault_header_t *h);
|
vault_header_t * vh2be(vault_header_t *h);
|
||||||
|
|||||||
@@ -43,6 +43,8 @@ we pad the input with zeroes and remove them after decoding.
|
|||||||
#include "defines.h"
|
#include "defines.h"
|
||||||
#include "zmq_z85.h"
|
#include "zmq_z85.h"
|
||||||
#include "mem.h"
|
#include "mem.h"
|
||||||
|
#include "structs.h"
|
||||||
|
#include "context.h"
|
||||||
#include "buffer.h"
|
#include "buffer.h"
|
||||||
|
|
||||||
/** Zero-pad some input data.
|
/** Zero-pad some input data.
|
||||||
@@ -76,6 +78,7 @@ size_t pcp_unpadfour(byte *src, size_t srclen);
|
|||||||
|
|
||||||
The input \a z85block may contain newlines which will be removed.
|
The input \a z85block may contain newlines which will be removed.
|
||||||
|
|
||||||
|
\param[in] the pcp context object.
|
||||||
\param[in] z85block The Z85 encoded string.
|
\param[in] z85block The Z85 encoded string.
|
||||||
\param[in] dstlen Returned size of decoded data (pointer to int).
|
\param[in] dstlen Returned size of decoded data (pointer to int).
|
||||||
|
|
||||||
@@ -83,7 +86,7 @@ size_t pcp_unpadfour(byte *src, size_t srclen);
|
|||||||
returns NULL. Check fatals_if_any().
|
returns NULL. Check fatals_if_any().
|
||||||
|
|
||||||
*/
|
*/
|
||||||
byte *pcp_z85_decode(char *z85block, size_t *dstlen);
|
byte *pcp_z85_decode(PCPCTX *ptx, char *z85block, size_t *dstlen);
|
||||||
|
|
||||||
|
|
||||||
/** Encode data to Z85 encoding.
|
/** Encode data to Z85 encoding.
|
||||||
@@ -105,24 +108,26 @@ char *pcp_z85_encode(byte *raw, size_t srclen, size_t *dstlen);
|
|||||||
Reads a file and returns the raw Z85 encoded string.
|
Reads a file and returns the raw Z85 encoded string.
|
||||||
It ignores newlines, comments and Headerstrings.
|
It ignores newlines, comments and Headerstrings.
|
||||||
|
|
||||||
|
\param[in] the pcp context object.
|
||||||
\param[in] infile FILE stream to read from.
|
\param[in] infile FILE stream to read from.
|
||||||
|
|
||||||
\return Raw Z85 encoded string with comments, headers and newlines removed.
|
\return Raw Z85 encoded string with comments, headers and newlines removed.
|
||||||
*/
|
*/
|
||||||
char *pcp_readz85file(FILE *infile);
|
char *pcp_readz85file(PCPCTX *ptx, FILE *infile);
|
||||||
|
|
||||||
/** Read a Z85 encoded string.
|
/** Read a Z85 encoded string.
|
||||||
|
|
||||||
Parses the given input string and returns the raw Z85 encoded string.
|
Parses the given input string and returns the raw Z85 encoded string.
|
||||||
It ignores newlines, comments and Headerstrings.
|
It ignores newlines, comments and Headerstrings.
|
||||||
|
|
||||||
|
\param[in] the pcp context object.
|
||||||
\param[in] input Z85 encoded string.
|
\param[in] input Z85 encoded string.
|
||||||
\param[in] bufsize Size of the string.
|
\param[in] bufsize Size of the string.
|
||||||
|
|
||||||
\return Raw Z85 encoded string with comments, headers and newlines removed.
|
\return Raw Z85 encoded string with comments, headers and newlines removed.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
char *pcp_readz85string(byte *input, size_t bufsize);
|
char *pcp_readz85string(PCPCTX *ptx, byte *input, size_t bufsize);
|
||||||
|
|
||||||
/** Check if a binary array is utf8.
|
/** Check if a binary array is utf8.
|
||||||
|
|
||||||
|
|||||||
@@ -26,8 +26,8 @@ pkgconfigdir = $(libdir)/pkgconfig
|
|||||||
pkgconfig_DATA = libpcp1.pc
|
pkgconfig_DATA = libpcp1.pc
|
||||||
|
|
||||||
libpcp1_la_SOURCES = platform.c mac.c mem.c pad.c version.c \
|
libpcp1_la_SOURCES = platform.c mac.c mem.c pad.c version.c \
|
||||||
z85.c zmq_z85.c key.c randomart.c \
|
context.c z85.c zmq_z85.c key.c randomart.c \
|
||||||
vault.c fatal.c jenhash.c digital_crc32.c \
|
vault.c jenhash.c digital_crc32.c \
|
||||||
crypto.c ed.c keyhash.c scrypt.c \
|
crypto.c ed.c keyhash.c scrypt.c \
|
||||||
scrypt/crypto/sha256.c scrypt/crypto/crypto_scrypt-nosse.c \
|
scrypt/crypto/sha256.c scrypt/crypto/crypto_scrypt-nosse.c \
|
||||||
base85.c util.c buffer.c mgmt.c keysig.c pcpstream.c
|
base85.c util.c buffer.c mgmt.c keysig.c pcpstream.c
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ static void prep_base85(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int decode_85(char *dst, const char *buffer, int len)
|
int decode_85(PCPCTX *ptx, char *dst, const char *buffer, int len)
|
||||||
{
|
{
|
||||||
prep_base85();
|
prep_base85();
|
||||||
say1("len: %d\n", len);
|
say1("len: %d\n", len);
|
||||||
|
|||||||
@@ -129,9 +129,8 @@ byte *buffer_get(Buffer *b) {
|
|||||||
|
|
||||||
size_t buffer_get_chunk(Buffer *b, void *buf, size_t len) {
|
size_t buffer_get_chunk(Buffer *b, void *buf, size_t len) {
|
||||||
if(len > b->end - b->offset) {
|
if(len > b->end - b->offset) {
|
||||||
fatal("[buffer %s] attempt to read %ld bytes data from buffer with %ld bytes left at offset %ld\n",
|
final("[buffer %s] attempt to read %ld bytes data from buffer with %ld bytes left at offset %ld\n",
|
||||||
b->name, len, b->end - b->offset, b->offset);
|
b->name, len, b->end - b->offset, b->offset);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
else if(len == 0) {
|
else if(len == 0) {
|
||||||
/* FIXME: check how this happens */
|
/* FIXME: check how this happens */
|
||||||
@@ -146,9 +145,8 @@ size_t buffer_get_chunk(Buffer *b, void *buf, size_t len) {
|
|||||||
|
|
||||||
size_t buffer_get_chunk_tobuf(Buffer *b, Buffer *dst, size_t len) {
|
size_t buffer_get_chunk_tobuf(Buffer *b, Buffer *dst, size_t len) {
|
||||||
if(len > b->end - b->offset) {
|
if(len > b->end - b->offset) {
|
||||||
fatal("[buffer %s] attempt to read %ld bytes data from buffer with %ld bytes left at offset %ld\n",
|
final("[buffer %s] attempt to read %ld bytes data from buffer with %ld bytes left at offset %ld\n",
|
||||||
b->name, len, b->end - b->offset, b->offset);
|
b->name, len, b->end - b->offset, b->offset);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
else if(len == 0) {
|
else if(len == 0) {
|
||||||
/* FIXME: check how this happens */
|
/* FIXME: check how this happens */
|
||||||
@@ -246,13 +244,11 @@ char *buffer_get_str(Buffer *b) {
|
|||||||
|
|
||||||
size_t buffer_extract(Buffer *b, void *buf, size_t offset, size_t len) {
|
size_t buffer_extract(Buffer *b, void *buf, size_t offset, size_t len) {
|
||||||
if(len > b->end) {
|
if(len > b->end) {
|
||||||
fatal("[buffer %s] attempt to read %ld bytes past end of buffer at %ld\n", b->name, b->end - (b->offset + len), b->end);
|
final("[buffer %s] attempt to read %ld bytes past end of buffer at %ld\n", b->name, b->end - (b->offset + len), b->end);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(offset > b->end) {
|
if(offset > b->end) {
|
||||||
fatal("[buffer %s] attempt to read at offset %ld past len to read %ld\n", b->name, offset, b->end);
|
final("[buffer %s] attempt to read at offset %ld past len to read %ld\n", b->name, offset, b->end);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(buf, b->buf + offset, len);
|
memcpy(buf, b->buf + offset, len);
|
||||||
@@ -328,13 +324,10 @@ size_t buffer_fd_read(Buffer *b, FILE *in, size_t len) {
|
|||||||
|
|
||||||
size_t s = fread(data, 1, len, in);
|
size_t s = fread(data, 1, len, in);
|
||||||
|
|
||||||
if(s < len) {
|
if(s > 0)
|
||||||
fatal("[buffer %s] attempt to read %"FMT_SIZE_T" bytes from FILE, but got %"FMT_SIZE_T" bytes only\n", b->name, (SIZE_T_CAST)len, (SIZE_T_CAST)s);
|
buffer_add(b, data, len);
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
buffer_add(b, data, len);
|
return s;
|
||||||
return len;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void buffer_add8(Buffer *b, uint8_t v) {
|
void buffer_add8(Buffer *b, uint8_t v) {
|
||||||
|
|||||||
@@ -21,9 +21,8 @@
|
|||||||
|
|
||||||
#define _GNU_SOURCE /* vasprintf() linux */
|
#define _GNU_SOURCE /* vasprintf() linux */
|
||||||
|
|
||||||
#include "defines.h"
|
|
||||||
#include "platform.h"
|
|
||||||
|
|
||||||
|
#include "context.h"
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
@@ -31,39 +30,70 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
char *PCP_ERR;
|
PCPCTX *ptx_new() {
|
||||||
byte PCP_ERRSET;
|
PCPCTX *p = ucmalloc(sizeof(PCPCTX));
|
||||||
int PCP_EXIT;
|
p->pcp_err = NULL;
|
||||||
int PCPVERBOSE;
|
p->pcp_errset = 0;
|
||||||
|
p->pcp_exit = 0;
|
||||||
|
p->verbose = 0;
|
||||||
|
p->pcpkey_hash = NULL;
|
||||||
|
p->pcppubkey_hash = NULL;
|
||||||
|
p->pcpkeysig_hash = NULL;
|
||||||
|
|
||||||
void fatal(const char * fmt, ...) {
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ptx_clean(PCPCTX *ptx) {
|
||||||
|
if(ptx->pcp_errset)
|
||||||
|
free(ptx->pcp_err);
|
||||||
|
|
||||||
|
pcphash_clean(ptx);
|
||||||
|
|
||||||
|
free(ptx);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void fatal(PCPCTX *ptx, const char * fmt, ...) {
|
||||||
va_list ap;
|
va_list ap;
|
||||||
va_start(ap, fmt);
|
va_start(ap, fmt);
|
||||||
|
|
||||||
if(vasprintf(&PCP_ERR, fmt, ap) >= 0) {
|
char *err = ptx->pcp_err;
|
||||||
|
|
||||||
|
if(vasprintf(&err, fmt, ap) >= 0) {
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
PCP_ERRSET = 1;
|
ptx->pcp_errset = 1;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
fprintf(stderr, "Could not store fatal error message %s!\n", fmt);
|
fprintf(stderr, "Could not store fatal error message %s!\n", fmt);
|
||||||
PCP_ERRSET = 1;
|
ptx->pcp_errset = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void fatals_reset() {
|
void fatals_reset(PCPCTX *ptx) {
|
||||||
PCP_ERRSET = 0;
|
ptx->pcp_errset = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void fatals_ifany() {
|
void fatals_ifany(PCPCTX *ptx) {
|
||||||
if(PCP_ERRSET == 1) {
|
if(ptx->pcp_errset == 1) {
|
||||||
fprintf(stderr, "%s", PCP_ERR);
|
fprintf(stderr, "%s", ptx->pcp_err);
|
||||||
if(errno) {
|
if(errno) {
|
||||||
fprintf(stderr, "Error: %s\n", strerror(errno));
|
fprintf(stderr, "Error: %s\n", strerror(errno));
|
||||||
}
|
}
|
||||||
PCP_EXIT = 1;
|
ptx->pcp_exit = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void fatals_done() {
|
void final(const char * fmt, ...) {
|
||||||
free(PCP_ERR);
|
va_list ap;
|
||||||
|
va_start(ap, fmt);
|
||||||
|
|
||||||
|
char *err = NULL;
|
||||||
|
|
||||||
|
if(vasprintf(&err, fmt, ap) >= 0) {
|
||||||
|
va_end(ap);
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(stderr, "ABORT: %s", err);
|
||||||
|
|
||||||
|
abort();
|
||||||
}
|
}
|
||||||
@@ -81,7 +81,7 @@ int pcp_sodium_verify_box(byte **cleartext, byte* message,
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
byte *pcp_box_encrypt(pcp_key_t *secret, pcp_pubkey_t *pub,
|
byte *pcp_box_encrypt(PCPCTX *ptx, pcp_key_t *secret, pcp_pubkey_t *pub,
|
||||||
byte *message, size_t messagesize,
|
byte *message, size_t messagesize,
|
||||||
size_t *csize) {
|
size_t *csize) {
|
||||||
|
|
||||||
@@ -93,7 +93,7 @@ byte *pcp_box_encrypt(pcp_key_t *secret, pcp_pubkey_t *pub,
|
|||||||
secret->secret, pub->pub);
|
secret->secret, pub->pub);
|
||||||
|
|
||||||
if(es <= messagesize) {
|
if(es <= messagesize) {
|
||||||
fatal("failed to encrypt message!\n");
|
fatal(ptx, "failed to encrypt message!\n");
|
||||||
goto errbec;
|
goto errbec;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -124,7 +124,7 @@ byte *pcp_box_encrypt(pcp_key_t *secret, pcp_pubkey_t *pub,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
byte *pcp_box_decrypt(pcp_key_t *secret, pcp_pubkey_t *pub,
|
byte *pcp_box_decrypt(PCPCTX *ptx, pcp_key_t *secret, pcp_pubkey_t *pub,
|
||||||
byte *cipher, size_t ciphersize,
|
byte *cipher, size_t ciphersize,
|
||||||
size_t *dsize) {
|
size_t *dsize) {
|
||||||
|
|
||||||
@@ -140,7 +140,7 @@ byte *pcp_box_decrypt(pcp_key_t *secret, pcp_pubkey_t *pub,
|
|||||||
if(pcp_sodium_verify_box(&message, cipheronly,
|
if(pcp_sodium_verify_box(&message, cipheronly,
|
||||||
ciphersize - crypto_secretbox_NONCEBYTES,
|
ciphersize - crypto_secretbox_NONCEBYTES,
|
||||||
nonce, secret->secret, pub->pub) != 0){
|
nonce, secret->secret, pub->pub) != 0){
|
||||||
fatal("failed to decrypt message!\n");
|
fatal(ptx, "failed to decrypt message!\n");
|
||||||
goto errbed;
|
goto errbed;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -161,7 +161,7 @@ byte *pcp_box_decrypt(pcp_key_t *secret, pcp_pubkey_t *pub,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t pcp_decrypt_stream(Pcpstream *in, Pcpstream* out, pcp_key_t *s, byte *symkey, int verify) {
|
size_t pcp_decrypt_stream(PCPCTX *ptx, Pcpstream *in, Pcpstream* out, pcp_key_t *s, byte *symkey, int verify) {
|
||||||
pcp_pubkey_t *cur = NULL;
|
pcp_pubkey_t *cur = NULL;
|
||||||
byte *reccipher = NULL;
|
byte *reccipher = NULL;
|
||||||
int recmatch, self;
|
int recmatch, self;
|
||||||
@@ -190,7 +190,7 @@ size_t pcp_decrypt_stream(Pcpstream *in, Pcpstream* out, pcp_key_t *s, byte *sym
|
|||||||
if(symkey != NULL)
|
if(symkey != NULL)
|
||||||
self = 1;
|
self = 1;
|
||||||
else {
|
else {
|
||||||
fatal("Input is symetrically encrypted but no key have been specified (lib usage failure)\n");
|
fatal(ptx, "Input is symetrically encrypted but no key have been specified (lib usage failure)\n");
|
||||||
goto errdef1;
|
goto errdef1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -202,14 +202,14 @@ size_t pcp_decrypt_stream(Pcpstream *in, Pcpstream* out, pcp_key_t *s, byte *sym
|
|||||||
|
|
||||||
if(self) {
|
if(self) {
|
||||||
/* just decrypt symetrically and go outa here */
|
/* just decrypt symetrically and go outa here */
|
||||||
return pcp_decrypt_stream_sym(in, out, symkey, NULL);
|
return pcp_decrypt_stream_sym(ptx, in, out, symkey, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef PCP_ASYM_ADD_SENDER_PUB
|
#ifdef PCP_ASYM_ADD_SENDER_PUB
|
||||||
/* step 2, sender's pubkey */
|
/* step 2, sender's pubkey */
|
||||||
cur_bufsize = ps_read(in, &in_buf, crypto_box_PUBLICKEYBYTES); /* fread(&in_buf, 1, crypto_box_PUBLICKEYBYTES, in); */
|
cur_bufsize = ps_read(in, &in_buf, crypto_box_PUBLICKEYBYTES); /* fread(&in_buf, 1, crypto_box_PUBLICKEYBYTES, in); */
|
||||||
if(cur_bufsize != crypto_box_PUBLICKEYBYTES && !ps_end(in) && !ps_err(in)) {
|
if(cur_bufsize != crypto_box_PUBLICKEYBYTES && !ps_end(in) && !ps_err(in)) {
|
||||||
fatal("Error: input file doesn't contain senders public key\n");
|
fatal(ptx, "Error: input file doesn't contain senders public key\n");
|
||||||
goto errdef1;
|
goto errdef1;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -217,7 +217,7 @@ size_t pcp_decrypt_stream(Pcpstream *in, Pcpstream* out, pcp_key_t *s, byte *sym
|
|||||||
/* step 3, check len recipients */
|
/* step 3, check len recipients */
|
||||||
cur_bufsize = ps_read(in, &lenrec, 4); /* fread(&lenrec, 1, 4, in); */
|
cur_bufsize = ps_read(in, &lenrec, 4); /* fread(&lenrec, 1, 4, in); */
|
||||||
if(cur_bufsize != 4 && !ps_end(in) && !ps_err(in)) {
|
if(cur_bufsize != 4 && !ps_end(in) && !ps_err(in)) {
|
||||||
fatal("Error: input file doesn't contain recipient count\n");
|
fatal(ptx, "Error: input file doesn't contain recipient count\n");
|
||||||
goto errdef1;
|
goto errdef1;
|
||||||
}
|
}
|
||||||
lenrec = be32toh(lenrec);
|
lenrec = be32toh(lenrec);
|
||||||
@@ -232,14 +232,14 @@ size_t pcp_decrypt_stream(Pcpstream *in, Pcpstream* out, pcp_key_t *s, byte *sym
|
|||||||
for(nrec=0; nrec<lenrec; nrec++) {
|
for(nrec=0; nrec<lenrec; nrec++) {
|
||||||
cur_bufsize = ps_read(in, &rec_buf, PCP_ASYM_RECIPIENT_SIZE); /* fread(&rec_buf, 1, PCP_ASYM_RECIPIENT_SIZE, in); */
|
cur_bufsize = ps_read(in, &rec_buf, PCP_ASYM_RECIPIENT_SIZE); /* fread(&rec_buf, 1, PCP_ASYM_RECIPIENT_SIZE, in); */
|
||||||
if(cur_bufsize != PCP_ASYM_RECIPIENT_SIZE && !ps_end(in) && !ps_err(in)) {
|
if(cur_bufsize != PCP_ASYM_RECIPIENT_SIZE && !ps_end(in) && !ps_err(in)) {
|
||||||
fatal("Error: input file corrupted, incomplete or no recipients (got %ld, exp %ld)\n", cur_bufsize, PCP_ASYM_RECIPIENT_SIZE );
|
fatal(ptx, "Error: input file corrupted, incomplete or no recipients (got %ld, exp %ld)\n", cur_bufsize, PCP_ASYM_RECIPIENT_SIZE );
|
||||||
goto errdef1;
|
goto errdef1;
|
||||||
}
|
}
|
||||||
recmatch = 0;
|
recmatch = 0;
|
||||||
|
|
||||||
pcphash_iteratepub(cur) {
|
pcphash_iteratepub(ptx, cur) {
|
||||||
byte *recipient;
|
byte *recipient;
|
||||||
recipient = pcp_box_decrypt(s, cur, rec_buf, PCP_ASYM_RECIPIENT_SIZE, &rec_size);
|
recipient = pcp_box_decrypt(ptx, s, cur, rec_buf, PCP_ASYM_RECIPIENT_SIZE, &rec_size);
|
||||||
if(recipient != NULL && rec_size == crypto_secretbox_KEYBYTES) {
|
if(recipient != NULL && rec_size == crypto_secretbox_KEYBYTES) {
|
||||||
/* found a match */
|
/* found a match */
|
||||||
recmatch = 1;
|
recmatch = 1;
|
||||||
@@ -257,19 +257,19 @@ size_t pcp_decrypt_stream(Pcpstream *in, Pcpstream* out, pcp_key_t *s, byte *sym
|
|||||||
|
|
||||||
|
|
||||||
if(recmatch == 0) {
|
if(recmatch == 0) {
|
||||||
fatal("Sorry, there's no matching public key in your vault for decryption\n");
|
fatal(ptx, "Sorry, there's no matching public key in your vault for decryption\n");
|
||||||
goto errdef1;
|
goto errdef1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* step 5, actually decrypt the file, finally */
|
/* step 5, actually decrypt the file, finally */
|
||||||
if(verify) {
|
if(verify) {
|
||||||
pcp_rec_t *rec = pcp_rec_new(reccipher, nrec * PCP_ASYM_RECIPIENT_SIZE, NULL, cur);
|
pcp_rec_t *rec = pcp_rec_new(reccipher, nrec * PCP_ASYM_RECIPIENT_SIZE, NULL, cur);
|
||||||
size_t s = pcp_decrypt_stream_sym(in, out, symkey, rec);
|
size_t s = pcp_decrypt_stream_sym(ptx, in, out, symkey, rec);
|
||||||
pcp_rec_free(rec);
|
pcp_rec_free(rec);
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
size_t s = pcp_decrypt_stream_sym(in, out, symkey, NULL);
|
size_t s = pcp_decrypt_stream_sym(ptx, in, out, symkey, NULL);
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -277,7 +277,7 @@ size_t pcp_decrypt_stream(Pcpstream *in, Pcpstream* out, pcp_key_t *s, byte *sym
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t pcp_encrypt_stream(Pcpstream *in, Pcpstream *out, pcp_key_t *s, pcp_pubkey_t *p, int sign) {
|
size_t pcp_encrypt_stream(PCPCTX *ptx, Pcpstream *in, Pcpstream *out, pcp_key_t *s, pcp_pubkey_t *p, int sign) {
|
||||||
byte *symkey;
|
byte *symkey;
|
||||||
int recipient_count;
|
int recipient_count;
|
||||||
byte *recipients_cipher;
|
byte *recipients_cipher;
|
||||||
@@ -306,9 +306,9 @@ size_t pcp_encrypt_stream(Pcpstream *in, Pcpstream *out, pcp_key_t *s, pcp_pubke
|
|||||||
|
|
||||||
HASH_ITER(hh, p, cur, t) {
|
HASH_ITER(hh, p, cur, t) {
|
||||||
byte *rec_cipher;
|
byte *rec_cipher;
|
||||||
rec_cipher = pcp_box_encrypt(s, cur, symkey, crypto_secretbox_KEYBYTES, &es);
|
rec_cipher = pcp_box_encrypt(ptx, s, cur, symkey, crypto_secretbox_KEYBYTES, &es);
|
||||||
if(es != rec_size) {
|
if(es != rec_size) {
|
||||||
fatal("invalid rec_size, expected %dl, got %dl\n", rec_size, es);
|
fatal(ptx, "invalid rec_size, expected %dl, got %dl\n", rec_size, es);
|
||||||
if(rec_cipher != NULL)
|
if(rec_cipher != NULL)
|
||||||
free(rec_cipher);
|
free(rec_cipher);
|
||||||
goto errec1;
|
goto errec1;
|
||||||
@@ -326,7 +326,7 @@ size_t pcp_encrypt_stream(Pcpstream *in, Pcpstream *out, pcp_key_t *s, pcp_pubke
|
|||||||
/* fwrite(head, 1, 1, out); */
|
/* fwrite(head, 1, 1, out); */
|
||||||
/* fprintf(stderr, "D: header - 1\n"); */
|
/* fprintf(stderr, "D: header - 1\n"); */
|
||||||
if(ps_err(out) != 0) {
|
if(ps_err(out) != 0) {
|
||||||
fatal("Failed to write encrypted output!\n");
|
fatal(ptx, "Failed to write encrypted output!\n");
|
||||||
goto errec1;
|
goto errec1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -361,11 +361,11 @@ size_t pcp_encrypt_stream(Pcpstream *in, Pcpstream *out, pcp_key_t *s, pcp_pubke
|
|||||||
size_t sym_size = 0;
|
size_t sym_size = 0;
|
||||||
if(sign) {
|
if(sign) {
|
||||||
pcp_rec_t *rec = pcp_rec_new(recipients_cipher, rec_size * recipient_count, s, NULL);
|
pcp_rec_t *rec = pcp_rec_new(recipients_cipher, rec_size * recipient_count, s, NULL);
|
||||||
sym_size = pcp_encrypt_stream_sym(in, out, symkey, 1, rec);
|
sym_size = pcp_encrypt_stream_sym(ptx, in, out, symkey, 1, rec);
|
||||||
pcp_rec_free(rec);
|
pcp_rec_free(rec);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
sym_size = pcp_encrypt_stream_sym(in, out, symkey, 1, NULL);
|
sym_size = pcp_encrypt_stream_sym(ptx, in, out, symkey, 1, NULL);
|
||||||
|
|
||||||
if(sym_size == 0)
|
if(sym_size == 0)
|
||||||
goto errec1;
|
goto errec1;
|
||||||
@@ -386,7 +386,7 @@ size_t pcp_encrypt_stream(Pcpstream *in, Pcpstream *out, pcp_key_t *s, pcp_pubke
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
size_t pcp_encrypt_stream_sym(Pcpstream *in, Pcpstream *out, byte *symkey, int havehead, pcp_rec_t *recsign) {
|
size_t pcp_encrypt_stream_sym(PCPCTX *ptx, Pcpstream *in, Pcpstream *out, byte *symkey, int havehead, pcp_rec_t *recsign) {
|
||||||
/*
|
/*
|
||||||
havehead = 0: write the whole thing from here
|
havehead = 0: write the whole thing from here
|
||||||
havehead = 1: no header, being called from asym...
|
havehead = 1: no header, being called from asym...
|
||||||
@@ -413,7 +413,7 @@ size_t pcp_encrypt_stream_sym(Pcpstream *in, Pcpstream *out, byte *symkey, int h
|
|||||||
es = ps_write(out, head, 1);
|
es = ps_write(out, head, 1);
|
||||||
/* es = fwrite(head, 1, 1, out); */
|
/* es = fwrite(head, 1, 1, out); */
|
||||||
if(ps_err(out) != 0) {
|
if(ps_err(out) != 0) {
|
||||||
fatal("Failed to write encrypted output!\n");
|
fatal(ptx, "Failed to write encrypted output!\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -466,7 +466,7 @@ size_t pcp_encrypt_stream_sym(Pcpstream *in, Pcpstream *out, byte *symkey, int h
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(ps_err(out) != 0) {
|
if(ps_err(out) != 0) {
|
||||||
fatal("Failed to write encrypted output!\n");
|
fatal(ptx, "Failed to write encrypted output!\n");
|
||||||
goto errsym1;
|
goto errsym1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -504,7 +504,7 @@ size_t pcp_encrypt_stream_sym(Pcpstream *in, Pcpstream *out, byte *symkey, int h
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t pcp_decrypt_stream_sym(Pcpstream *in, Pcpstream* out, byte *symkey, pcp_rec_t *recverify) {
|
size_t pcp_decrypt_stream_sym(PCPCTX *ptx, Pcpstream *in, Pcpstream* out, byte *symkey, pcp_rec_t *recverify) {
|
||||||
byte *buf_nonce;
|
byte *buf_nonce;
|
||||||
byte *buf_cipher;
|
byte *buf_cipher;
|
||||||
byte *buf_clear;
|
byte *buf_clear;
|
||||||
@@ -579,13 +579,13 @@ size_t pcp_decrypt_stream_sym(Pcpstream *in, Pcpstream* out, byte *symkey, pcp_r
|
|||||||
free(buf_clear);
|
free(buf_clear);
|
||||||
|
|
||||||
if(ps_err(out) != 0) {
|
if(ps_err(out) != 0) {
|
||||||
fatal("Failed to write decrypted output!\n");
|
fatal(ptx, "Failed to write decrypted output!\n");
|
||||||
out_size = 0;
|
out_size = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
fatal("Failed to decrypt file content!\n");
|
fatal(ptx, "Failed to decrypt file content!\n");
|
||||||
free(buf_clear);
|
free(buf_clear);
|
||||||
out_size = 0;
|
out_size = 0;
|
||||||
break;
|
break;
|
||||||
@@ -610,20 +610,20 @@ size_t pcp_decrypt_stream_sym(Pcpstream *in, Pcpstream* out, byte *symkey, pcp_r
|
|||||||
crypto_generichash_final(st, hash, crypto_generichash_BYTES_MAX);
|
crypto_generichash_final(st, hash, crypto_generichash_BYTES_MAX);
|
||||||
|
|
||||||
byte *verifiedhash = NULL;
|
byte *verifiedhash = NULL;
|
||||||
verifiedhash = pcp_ed_verify(signature, siglen, recverify->pub);
|
verifiedhash = pcp_ed_verify(ptx, signature, siglen, recverify->pub);
|
||||||
if(verifiedhash == NULL)
|
if(verifiedhash == NULL)
|
||||||
out_size = 0;
|
out_size = 0;
|
||||||
else {
|
else {
|
||||||
if(memcmp(verifiedhash, hash, crypto_generichash_BYTES_MAX) != 0) {
|
if(memcmp(verifiedhash, hash, crypto_generichash_BYTES_MAX) != 0) {
|
||||||
/* sig verified, but the hash doesn't match */
|
/* sig verified, but the hash doesn't match */
|
||||||
fatal("signed hash doesn't match actual hash of signed decrypted file content\n");
|
fatal(ptx, "signed hash doesn't match actual hash of signed decrypted file content\n");
|
||||||
out_size = 0;
|
out_size = 0;
|
||||||
}
|
}
|
||||||
free(verifiedhash);
|
free(verifiedhash);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
fatal("Failed to decrypt signature!\n");
|
fatal(ptx, "Failed to decrypt signature!\n");
|
||||||
out_size = 0;
|
out_size = 0;
|
||||||
}
|
}
|
||||||
free(st);
|
free(st);
|
||||||
|
|||||||
48
libpcp/ed.c
48
libpcp/ed.c
@@ -21,12 +21,12 @@
|
|||||||
|
|
||||||
#include "ed.h"
|
#include "ed.h"
|
||||||
|
|
||||||
byte * pcp_ed_verify_key(byte *signature, size_t siglen, pcp_pubkey_t *p) {
|
byte * pcp_ed_verify_key(PCPCTX *ptx, byte *signature, size_t siglen, pcp_pubkey_t *p) {
|
||||||
byte *message = ucmalloc(siglen);
|
byte *message = ucmalloc(siglen);
|
||||||
unsigned long long mlen;
|
unsigned long long mlen;
|
||||||
|
|
||||||
if(crypto_sign_open(message, &mlen, signature, siglen, p->masterpub) != 0) {
|
if(crypto_sign_open(message, &mlen, signature, siglen, p->masterpub) != 0) {
|
||||||
fatal("Failed to open the signature using the public key 0x%s!\n", p->id);
|
fatal(ptx, "Failed to open the signature using the public key 0x%s!\n", p->id);
|
||||||
goto errve1;
|
goto errve1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -37,12 +37,12 @@ byte * pcp_ed_verify_key(byte *signature, size_t siglen, pcp_pubkey_t *p) {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
byte * pcp_ed_verify(byte *signature, size_t siglen, pcp_pubkey_t *p) {
|
byte * pcp_ed_verify(PCPCTX *ptx, byte *signature, size_t siglen, pcp_pubkey_t *p) {
|
||||||
byte *message = ucmalloc(siglen); /* we alloc the full size, the resulting len will be returned by nacl anyway - crypto_sign_BYTES); */
|
byte *message = ucmalloc(siglen); /* we alloc the full size, the resulting len will be returned by nacl anyway - crypto_sign_BYTES); */
|
||||||
unsigned long long mlen;
|
unsigned long long mlen;
|
||||||
|
|
||||||
if(crypto_sign_open(message, &mlen, signature, siglen, p->edpub) != 0) {
|
if(crypto_sign_open(message, &mlen, signature, siglen, p->edpub) != 0) {
|
||||||
fatal("Failed to open the signature using the public key 0x%s!\n", p->id);
|
fatal(ptx, "Failed to open the signature using the public key 0x%s!\n", p->id);
|
||||||
goto errve1;
|
goto errve1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -71,7 +71,7 @@ byte *pcp_ed_sign(byte *message, size_t messagesize, pcp_key_t *s) {
|
|||||||
return signature;
|
return signature;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t pcp_ed_sign_buffered(Pcpstream *in, Pcpstream* out, pcp_key_t *s, int z85) {
|
size_t pcp_ed_sign_buffered(PCPCTX *ptx, Pcpstream *in, Pcpstream* out, pcp_key_t *s, int z85) {
|
||||||
byte in_buf[PCP_BLOCK_SIZE];
|
byte in_buf[PCP_BLOCK_SIZE];
|
||||||
size_t cur_bufsize = 0;
|
size_t cur_bufsize = 0;
|
||||||
size_t outsize = 0;
|
size_t outsize = 0;
|
||||||
@@ -94,7 +94,7 @@ size_t pcp_ed_sign_buffered(Pcpstream *in, Pcpstream* out, pcp_key_t *s, int z85
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(ps_err(out) != 0) {
|
if(ps_err(out) != 0) {
|
||||||
fatal("Failed to write encrypted output!\n");
|
fatal(ptx, "Failed to write encrypted output!\n");
|
||||||
free(st);
|
free(st);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -120,7 +120,7 @@ size_t pcp_ed_sign_buffered(Pcpstream *in, Pcpstream* out, pcp_key_t *s, int z85
|
|||||||
return outsize;
|
return outsize;
|
||||||
}
|
}
|
||||||
|
|
||||||
pcp_pubkey_t *pcp_ed_verify_buffered(Pcpstream *in, pcp_pubkey_t *p) {
|
pcp_pubkey_t *pcp_ed_verify_buffered(PCPCTX *ptx, Pcpstream *in, pcp_pubkey_t *p) {
|
||||||
byte in_buf[PCP_BLOCK_SIZE/2];
|
byte in_buf[PCP_BLOCK_SIZE/2];
|
||||||
byte in_next[PCP_BLOCK_SIZE/2];
|
byte in_next[PCP_BLOCK_SIZE/2];
|
||||||
byte in_full[PCP_BLOCK_SIZE];
|
byte in_full[PCP_BLOCK_SIZE];
|
||||||
@@ -247,23 +247,23 @@ pcp_pubkey_t *pcp_ed_verify_buffered(Pcpstream *in, pcp_pubkey_t *p) {
|
|||||||
} /* while */
|
} /* while */
|
||||||
|
|
||||||
if(gotsig == 0) {
|
if(gotsig == 0) {
|
||||||
fatal("Error, the signature doesn't contain the ed25519 signed hash\n");
|
fatal(ptx, "Error, the signature doesn't contain the ed25519 signed hash\n");
|
||||||
goto errvb1;
|
goto errvb1;
|
||||||
}
|
}
|
||||||
|
|
||||||
crypto_generichash_final(st, hash, crypto_generichash_BYTES_MAX);
|
crypto_generichash_final(st, hash, crypto_generichash_BYTES_MAX);
|
||||||
|
|
||||||
if(z85) {
|
if(z85) {
|
||||||
char *z85block = pcp_readz85string(z85encoded, zlen);
|
char *z85block = pcp_readz85string(ptx, z85encoded, zlen);
|
||||||
if(z85block == NULL)
|
if(z85block == NULL)
|
||||||
goto errvb1;
|
goto errvb1;
|
||||||
|
|
||||||
//fprintf(stderr, "ZBLOCK: <%s>\n", z85block);
|
//fprintf(stderr, "ZBLOCK: <%s>\n", z85block);
|
||||||
|
|
||||||
size_t dstlen;
|
size_t dstlen;
|
||||||
byte *z85decoded = pcp_z85_decode(z85block, &dstlen);
|
byte *z85decoded = pcp_z85_decode(ptx, z85block, &dstlen);
|
||||||
if(dstlen != mlen) {
|
if(dstlen != mlen) {
|
||||||
fatal("z85 decoded signature didn't result in a proper signed hash(got: %ld, expected: %ld)\n", dstlen, mlen);
|
fatal(ptx, "z85 decoded signature didn't result in a proper signed hash(got: %ld, expected: %ld)\n", dstlen, mlen);
|
||||||
goto errvb1;
|
goto errvb1;
|
||||||
}
|
}
|
||||||
memcpy(sighash, z85decoded, mlen);
|
memcpy(sighash, z85decoded, mlen);
|
||||||
@@ -273,14 +273,14 @@ pcp_pubkey_t *pcp_ed_verify_buffered(Pcpstream *in, pcp_pubkey_t *p) {
|
|||||||
/* huh, how did we made it til here? */
|
/* huh, how did we made it til here? */
|
||||||
byte *verifiedhash = NULL;
|
byte *verifiedhash = NULL;
|
||||||
if(p == NULL) {
|
if(p == NULL) {
|
||||||
pcphash_iteratepub(p) {
|
pcphash_iteratepub(ptx, p) {
|
||||||
verifiedhash = pcp_ed_verify(sighash, mlen, p);
|
verifiedhash = pcp_ed_verify(ptx, sighash, mlen, p);
|
||||||
if(verifiedhash != NULL)
|
if(verifiedhash != NULL)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
verifiedhash = pcp_ed_verify(sighash, mlen, p);
|
verifiedhash = pcp_ed_verify(ptx, sighash, mlen, p);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(verifiedhash == NULL)
|
if(verifiedhash == NULL)
|
||||||
@@ -288,7 +288,7 @@ pcp_pubkey_t *pcp_ed_verify_buffered(Pcpstream *in, pcp_pubkey_t *p) {
|
|||||||
|
|
||||||
if(memcmp(verifiedhash, hash, crypto_generichash_BYTES_MAX) != 0) {
|
if(memcmp(verifiedhash, hash, crypto_generichash_BYTES_MAX) != 0) {
|
||||||
/* sig verified, but the hash doesn't */
|
/* sig verified, but the hash doesn't */
|
||||||
fatal("signed hash doesn't match actual hash of signed file content\n");
|
fatal(ptx, "signed hash doesn't match actual hash of signed file content\n");
|
||||||
free(verifiedhash);
|
free(verifiedhash);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -336,7 +336,7 @@ size_t pcp_ed_detachsign_buffered(Pcpstream *in, Pcpstream *out, pcp_key_t *s) {
|
|||||||
return outsize;
|
return outsize;
|
||||||
}
|
}
|
||||||
|
|
||||||
pcp_pubkey_t *pcp_ed_detachverify_buffered(Pcpstream *in, Pcpstream *sigfd, pcp_pubkey_t *p) {
|
pcp_pubkey_t *pcp_ed_detachverify_buffered(PCPCTX *ptx, Pcpstream *in, Pcpstream *sigfd, pcp_pubkey_t *p) {
|
||||||
byte in_buf[PCP_BLOCK_SIZE];
|
byte in_buf[PCP_BLOCK_SIZE];
|
||||||
size_t cur_bufsize = 0;
|
size_t cur_bufsize = 0;
|
||||||
size_t outsize = 0;
|
size_t outsize = 0;
|
||||||
@@ -374,35 +374,35 @@ pcp_pubkey_t *pcp_ed_detachverify_buffered(Pcpstream *in, Pcpstream *sigfd, pcp_
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(sig == NULL) {
|
if(sig == NULL) {
|
||||||
fatal("Invalid detached signature\n");
|
fatal(ptx, "Invalid detached signature\n");
|
||||||
goto errdea1;
|
goto errdea1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
char *z85block = pcp_readz85string(sig, inputBufSize);
|
char *z85block = pcp_readz85string(ptx, sig, inputBufSize);
|
||||||
if(z85block == NULL)
|
if(z85block == NULL)
|
||||||
goto errdea2;
|
goto errdea2;
|
||||||
|
|
||||||
size_t clen;
|
size_t clen;
|
||||||
byte *sighash = pcp_z85_decode(z85block, &clen);
|
byte *sighash = pcp_z85_decode(ptx, z85block, &clen);
|
||||||
if(sighash == NULL)
|
if(sighash == NULL)
|
||||||
goto errdea3;
|
goto errdea3;
|
||||||
|
|
||||||
if(clen != mlen) {
|
if(clen != mlen) {
|
||||||
fatal("z85 decoded signature didn't result in a proper signed hash(got: %ld, expected: %ld)\n", clen, mlen);
|
fatal(ptx, "z85 decoded signature didn't result in a proper signed hash(got: %ld, expected: %ld)\n", clen, mlen);
|
||||||
goto errdea4;
|
goto errdea4;
|
||||||
}
|
}
|
||||||
|
|
||||||
byte *verifiedhash = NULL;
|
byte *verifiedhash = NULL;
|
||||||
if(p == NULL) {
|
if(p == NULL) {
|
||||||
pcphash_iteratepub(p) {
|
pcphash_iteratepub(ptx, p) {
|
||||||
verifiedhash = pcp_ed_verify(sighash, mlen, p);
|
verifiedhash = pcp_ed_verify(ptx, sighash, mlen, p);
|
||||||
if(verifiedhash != NULL)
|
if(verifiedhash != NULL)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
verifiedhash = pcp_ed_verify(sighash, mlen, p);
|
verifiedhash = pcp_ed_verify(ptx, sighash, mlen, p);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(verifiedhash == NULL)
|
if(verifiedhash == NULL)
|
||||||
@@ -410,7 +410,7 @@ pcp_pubkey_t *pcp_ed_detachverify_buffered(Pcpstream *in, Pcpstream *sigfd, pcp_
|
|||||||
|
|
||||||
if(memcmp(verifiedhash, hash, crypto_generichash_BYTES_MAX) != 0) {
|
if(memcmp(verifiedhash, hash, crypto_generichash_BYTES_MAX) != 0) {
|
||||||
/* sig verified, but the hash doesn't */
|
/* sig verified, but the hash doesn't */
|
||||||
fatal("signed hash doesn't match actual hash of signed file content\n");
|
fatal(ptx, "signed hash doesn't match actual hash of signed file content\n");
|
||||||
goto errdea5;
|
goto errdea5;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
54
libpcp/key.c
54
libpcp/key.c
@@ -21,19 +21,19 @@
|
|||||||
|
|
||||||
|
|
||||||
#include "key.h"
|
#include "key.h"
|
||||||
#include "keyhash.h"
|
#include "context.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* AS of 16/01/2014 I'm using scrypt() instead of my crafted key
|
* AS of 16/01/2014 I'm using scrypt() instead of my crafted key
|
||||||
* derivation function. However, I create a hash from the pcp_scrypt()
|
* derivation function. However, I create a hash from the pcp_scrypt()
|
||||||
* result anyway because I need a cure25519 secret.
|
* result anyway because I need a cure25519 secret.
|
||||||
*/
|
*/
|
||||||
byte *pcp_derivekey(char *passphrase, byte *nonce) {
|
byte *pcp_derivekey(PCPCTX *ptx, char *passphrase, byte *nonce) {
|
||||||
byte *key = ucmalloc(crypto_secretbox_KEYBYTES);
|
byte *key = ucmalloc(crypto_secretbox_KEYBYTES);
|
||||||
size_t plen = strnlen(passphrase, 255);
|
size_t plen = strnlen(passphrase, 255);
|
||||||
|
|
||||||
/* create the scrypt hash */
|
/* create the scrypt hash */
|
||||||
byte *scrypted = pcp_scrypt(passphrase, plen, nonce, crypto_secretbox_NONCEBYTES);
|
byte *scrypted = pcp_scrypt(ptx, passphrase, plen, nonce, crypto_secretbox_NONCEBYTES);
|
||||||
|
|
||||||
/* make a hash from the scrypt() result */
|
/* make a hash from the scrypt() result */
|
||||||
crypto_hash_sha256(key, (byte*)scrypted, 64);
|
crypto_hash_sha256(key, (byte*)scrypted, 64);
|
||||||
@@ -142,13 +142,13 @@ byte * pcp_gennonce() {
|
|||||||
return nonce;
|
return nonce;
|
||||||
}
|
}
|
||||||
|
|
||||||
pcp_key_t *pcpkey_encrypt(pcp_key_t *key, char *passphrase) {
|
pcp_key_t *pcpkey_encrypt(PCPCTX *ptx, pcp_key_t *key, char *passphrase) {
|
||||||
if(key->nonce[0] == 0) {
|
if(key->nonce[0] == 0) {
|
||||||
byte *nonce = pcp_gennonce();
|
byte *nonce = pcp_gennonce();
|
||||||
memcpy (key->nonce, nonce, crypto_secretbox_NONCEBYTES);
|
memcpy (key->nonce, nonce, crypto_secretbox_NONCEBYTES);
|
||||||
}
|
}
|
||||||
|
|
||||||
byte *encryptkey = pcp_derivekey(passphrase, key->nonce);
|
byte *encryptkey = pcp_derivekey(ptx, passphrase, key->nonce);
|
||||||
|
|
||||||
byte *encrypted;
|
byte *encrypted;
|
||||||
size_t es;
|
size_t es;
|
||||||
@@ -175,7 +175,7 @@ pcp_key_t *pcpkey_encrypt(pcp_key_t *key, char *passphrase) {
|
|||||||
key->mastersecret[0] = 0;
|
key->mastersecret[0] = 0;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
fatal("failed to encrypt the secret key!\n");
|
fatal(ptx, "failed to encrypt the secret key!\n");
|
||||||
free(key);
|
free(key);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -183,8 +183,8 @@ pcp_key_t *pcpkey_encrypt(pcp_key_t *key, char *passphrase) {
|
|||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
|
|
||||||
pcp_key_t *pcpkey_decrypt(pcp_key_t *key, char *passphrase) {
|
pcp_key_t *pcpkey_decrypt(PCPCTX *ptx, pcp_key_t *key, char *passphrase) {
|
||||||
byte *encryptkey = pcp_derivekey(passphrase, key->nonce);
|
byte *encryptkey = pcp_derivekey(ptx, passphrase, key->nonce);
|
||||||
|
|
||||||
byte *decrypted;
|
byte *decrypted;
|
||||||
size_t es;
|
size_t es;
|
||||||
@@ -201,7 +201,7 @@ pcp_key_t *pcpkey_decrypt(pcp_key_t *key, char *passphrase) {
|
|||||||
memcpy(key->secret, decrypted +128, 32);
|
memcpy(key->secret, decrypted +128, 32);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
fatal("failed to decrypt the secret key (got %d, expected 32)!\n", es);
|
fatal(ptx, "failed to decrypt the secret key (got %d, expected 32)!\n", es);
|
||||||
free(key);
|
free(key);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -355,26 +355,26 @@ Buffer *pcp_keyblob(void *k, int type) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int pcp_sanitycheck_pub(pcp_pubkey_t *key) {
|
int pcp_sanitycheck_pub(PCPCTX *ptx, pcp_pubkey_t *key) {
|
||||||
if(key->pub[0] == 0) {
|
if(key->pub[0] == 0) {
|
||||||
fatal("Pubkey sanity check: public key contained in key seems to be empty!\n");
|
fatal(ptx, "Pubkey sanity check: public key contained in key seems to be empty!\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(key->type != PCP_KEY_TYPE_PUBLIC) {
|
if(key->type != PCP_KEY_TYPE_PUBLIC) {
|
||||||
fatal("Pubkey sanity check: key type is not PUBLIC (expected: %02x, got: %02x)!\n",
|
fatal(ptx, "Pubkey sanity check: key type is not PUBLIC (expected: %02x, got: %02x)!\n",
|
||||||
PCP_KEY_TYPE_PUBLIC, key->type);
|
PCP_KEY_TYPE_PUBLIC, key->type);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(key->version != PCP_KEY_VERSION) {
|
if(key->version != PCP_KEY_VERSION) {
|
||||||
fatal("Pubkey sanity check: unknown key version (expected: %08X, got: %08X)!\n",
|
fatal(ptx, "Pubkey sanity check: unknown key version (expected: %08X, got: %08X)!\n",
|
||||||
PCP_KEY_VERSION, key->version);
|
PCP_KEY_VERSION, key->version);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(key->serial <= 0) {
|
if(key->serial <= 0) {
|
||||||
fatal("Pubkey sanity check: invalid serial number: %08X!\n", key->serial);
|
fatal(ptx, "Pubkey sanity check: invalid serial number: %08X!\n", key->serial);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -382,7 +382,7 @@ int pcp_sanitycheck_pub(pcp_pubkey_t *key) {
|
|||||||
char *got = ucmalloc(17);
|
char *got = ucmalloc(17);
|
||||||
memcpy(got, key->id, 17);
|
memcpy(got, key->id, 17);
|
||||||
got[16] = '\0';
|
got[16] = '\0';
|
||||||
fatal("Pubkey sanity check: invalid key id (expected 16 bytes, got: %s)!\n", got);
|
fatal(ptx, "Pubkey sanity check: invalid key id (expected 16 bytes, got: %s)!\n", got);
|
||||||
free(got);
|
free(got);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -392,13 +392,13 @@ int pcp_sanitycheck_pub(pcp_pubkey_t *key) {
|
|||||||
c = localtime(&t);
|
c = localtime(&t);
|
||||||
if(c->tm_year <= 0 || c->tm_year > 1100) {
|
if(c->tm_year <= 0 || c->tm_year > 1100) {
|
||||||
/* well, I'm perhaps overacting here :) */
|
/* well, I'm perhaps overacting here :) */
|
||||||
fatal("Pubkey sanity check: invalid creation timestamp (got year %04d)!\n", c->tm_year + 1900);
|
fatal(ptx, "Pubkey sanity check: invalid creation timestamp (got year %04d)!\n", c->tm_year + 1900);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
pcp_pubkey_t *maybe = pcphash_pubkeyexists(key->id);
|
pcp_pubkey_t *maybe = pcphash_pubkeyexists(ptx, key->id);
|
||||||
if(maybe != NULL) {
|
if(maybe != NULL) {
|
||||||
fatal("Pubkey sanity check: there already exists a key with the id 0x%s\n", key->id);
|
fatal(ptx, "Pubkey sanity check: there already exists a key with the id 0x%s\n", key->id);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -406,26 +406,26 @@ int pcp_sanitycheck_pub(pcp_pubkey_t *key) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int pcp_sanitycheck_key(pcp_key_t *key) {
|
int pcp_sanitycheck_key(PCPCTX *ptx, pcp_key_t *key) {
|
||||||
if(key->encrypted[0] == 0) {
|
if(key->encrypted[0] == 0) {
|
||||||
fatal("Secretkey sanity check: secret key contained in key seems to be empty!\n");
|
fatal(ptx, "Secretkey sanity check: secret key contained in key seems to be empty!\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(key->type != PCP_KEY_TYPE_SECRET && key->type != PCP_KEY_TYPE_MAINSECRET) {
|
if(key->type != PCP_KEY_TYPE_SECRET && key->type != PCP_KEY_TYPE_MAINSECRET) {
|
||||||
fatal("Secretkey sanity check: key type is not SECRET (expected: %02x, got: %02x)!\n",
|
fatal(ptx, "Secretkey sanity check: key type is not SECRET (expected: %02x, got: %02x)!\n",
|
||||||
PCP_KEY_TYPE_SECRET, key->type);
|
PCP_KEY_TYPE_SECRET, key->type);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(key->version != PCP_KEY_VERSION) {
|
if(key->version != PCP_KEY_VERSION) {
|
||||||
fatal("Secretkey sanity check: unknown key version (expected: %08X, got: %08X)!\n",
|
fatal(ptx, "Secretkey sanity check: unknown key version (expected: %08X, got: %08X)!\n",
|
||||||
PCP_KEY_VERSION, key->version);
|
PCP_KEY_VERSION, key->version);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(key->serial <= 0) {
|
if(key->serial <= 0) {
|
||||||
fatal("Secretkey sanity check: invalid serial number: %08X!\n", key->serial);
|
fatal(ptx, "Secretkey sanity check: invalid serial number: %08X!\n", key->serial);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -433,7 +433,7 @@ int pcp_sanitycheck_key(pcp_key_t *key) {
|
|||||||
char *got = ucmalloc(17);
|
char *got = ucmalloc(17);
|
||||||
memcpy(got, key->id, 17);
|
memcpy(got, key->id, 17);
|
||||||
got[16] = '\0';
|
got[16] = '\0';
|
||||||
fatal("Secretkey sanity check: invalid key id (expected 16 bytes, got: %s)!\n", got);
|
fatal(ptx, "Secretkey sanity check: invalid key id (expected 16 bytes, got: %s)!\n", got);
|
||||||
free(got);
|
free(got);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -443,13 +443,13 @@ int pcp_sanitycheck_key(pcp_key_t *key) {
|
|||||||
c = localtime(&t);
|
c = localtime(&t);
|
||||||
if(c->tm_year <= 70 || c->tm_year > 1100) {
|
if(c->tm_year <= 70 || c->tm_year > 1100) {
|
||||||
/* well, I'm perhaps overacting here :) */
|
/* well, I'm perhaps overacting here :) */
|
||||||
fatal("Secretkey sanity check: invalid creation timestamp (got year %04d)!\n", c->tm_year + 1900);
|
fatal(ptx, "Secretkey sanity check: invalid creation timestamp (got year %04d)!\n", c->tm_year + 1900);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
pcp_key_t *maybe = pcphash_keyexists(key->id);
|
pcp_key_t *maybe = pcphash_keyexists(ptx, key->id);
|
||||||
if(maybe != NULL) {
|
if(maybe != NULL) {
|
||||||
fatal("Secretkey sanity check: there already exists a key with the id 0x%s\n", key->id);
|
fatal(ptx, "Secretkey sanity check: there already exists a key with the id 0x%s\n", key->id);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -22,102 +22,87 @@
|
|||||||
|
|
||||||
#include "keyhash.h"
|
#include "keyhash.h"
|
||||||
|
|
||||||
pcp_key_t *pcpkey_hash;
|
|
||||||
pcp_pubkey_t *pcppubkey_hash;
|
|
||||||
pcp_keysig_t *pcpkeysig_hash;
|
|
||||||
|
|
||||||
pcp_key_t *__k;
|
void pcphash_del(PCPCTX *ptx, void *key, int type) {
|
||||||
pcp_pubkey_t *__p;
|
|
||||||
pcp_keysig_t *__s;
|
|
||||||
|
|
||||||
void pcphash_init() {
|
|
||||||
pcpkey_hash = NULL;
|
|
||||||
pcppubkey_hash = NULL;
|
|
||||||
pcpkeysig_hash = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void pcphash_del(void *key, int type) {
|
|
||||||
if(type == PCP_KEY_TYPE_SECRET) {
|
if(type == PCP_KEY_TYPE_SECRET) {
|
||||||
HASH_DEL(pcpkey_hash, (pcp_key_t *)key);
|
HASH_DEL(ptx->pcpkey_hash, (pcp_key_t *)key);
|
||||||
memset(key, 0, sizeof(pcp_key_t));
|
memset(key, 0, sizeof(pcp_key_t));
|
||||||
}
|
}
|
||||||
else if(type == PCP_KEYSIG_NATIVE || type == PCP_KEYSIG_PBP) {
|
else if(type == PCP_KEYSIG_NATIVE || type == PCP_KEYSIG_PBP) {
|
||||||
pcp_keysig_t *keysig = (pcp_keysig_t *)key;
|
pcp_keysig_t *keysig = (pcp_keysig_t *)key;
|
||||||
memset(keysig->blob, 0, keysig->size);
|
memset(keysig->blob, 0, keysig->size);
|
||||||
free(keysig->blob);
|
free(keysig->blob);
|
||||||
HASH_DEL(pcpkeysig_hash, (pcp_keysig_t *)key);
|
HASH_DEL(ptx->pcpkeysig_hash, (pcp_keysig_t *)key);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
HASH_DEL(pcppubkey_hash, (pcp_pubkey_t *)key);
|
HASH_DEL(ptx->pcppubkey_hash, (pcp_pubkey_t *)key);
|
||||||
memset(key, 0, sizeof(pcp_pubkey_t));
|
memset(key, 0, sizeof(pcp_pubkey_t));
|
||||||
}
|
}
|
||||||
free(key);
|
free(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pcphash_clean() {
|
void pcphash_clean(PCPCTX *ptx) {
|
||||||
if(pcpkey_hash != NULL) {
|
if(ptx->pcpkey_hash != NULL) {
|
||||||
pcp_key_t *current_key, *tmp;
|
pcp_key_t *current_key, *tmp;
|
||||||
HASH_ITER(hh, pcpkey_hash, current_key, tmp) {
|
HASH_ITER(hh, ptx->pcpkey_hash, current_key, tmp) {
|
||||||
pcphash_del(current_key, PCP_KEY_TYPE_SECRET);
|
pcphash_del(ptx, current_key, PCP_KEY_TYPE_SECRET);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(pcppubkey_hash != NULL) {
|
if(ptx->pcppubkey_hash != NULL) {
|
||||||
pcp_pubkey_t *current_pub, *ptmp;
|
pcp_pubkey_t *current_pub, *ptmp;
|
||||||
HASH_ITER(hh, pcppubkey_hash, current_pub, ptmp) {
|
HASH_ITER(hh, ptx->pcppubkey_hash, current_pub, ptmp) {
|
||||||
pcphash_del(current_pub, PCP_KEY_TYPE_PUBLIC);
|
pcphash_del(ptx, current_pub, PCP_KEY_TYPE_PUBLIC);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(pcpkeysig_hash != NULL) {
|
if(ptx->pcpkeysig_hash != NULL) {
|
||||||
pcp_keysig_t *current_keysig, *tmp;
|
pcp_keysig_t *current_keysig, *tmp;
|
||||||
HASH_ITER(hh, pcpkeysig_hash, current_keysig, tmp) {
|
HASH_ITER(hh, ptx->pcpkeysig_hash, current_keysig, tmp) {
|
||||||
pcphash_del(current_keysig, current_keysig->type);
|
pcphash_del(ptx, current_keysig, current_keysig->type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pcphash_init();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
pcp_keysig_t *pcphash_keysigexists(char *id) {
|
pcp_keysig_t *pcphash_keysigexists(PCPCTX *ptx, char *id) {
|
||||||
pcp_keysig_t *keysig = NULL;
|
pcp_keysig_t *keysig = NULL;
|
||||||
HASH_FIND_STR(pcpkeysig_hash, id, keysig);
|
HASH_FIND_STR(ptx->pcpkeysig_hash, id, keysig);
|
||||||
return keysig; /* maybe NULL! */
|
return keysig; /* maybe NULL! */
|
||||||
}
|
}
|
||||||
|
|
||||||
pcp_key_t *pcphash_keyexists(char *id) {
|
pcp_key_t *pcphash_keyexists(PCPCTX *ptx, char *id) {
|
||||||
pcp_key_t *key = NULL;
|
pcp_key_t *key = NULL;
|
||||||
HASH_FIND_STR(pcpkey_hash, id, key);
|
HASH_FIND_STR(ptx->pcpkey_hash, id, key);
|
||||||
return key; /* maybe NULL! */
|
return key; /* maybe NULL! */
|
||||||
}
|
}
|
||||||
|
|
||||||
pcp_pubkey_t *pcphash_pubkeyexists(char *id) {
|
pcp_pubkey_t *pcphash_pubkeyexists(PCPCTX *ptx, char *id) {
|
||||||
pcp_pubkey_t *key = NULL;
|
pcp_pubkey_t *key = NULL;
|
||||||
HASH_FIND_STR(pcppubkey_hash, id, key);
|
HASH_FIND_STR(ptx->pcppubkey_hash, id, key);
|
||||||
return key; /* maybe NULL! */
|
return key; /* maybe NULL! */
|
||||||
}
|
}
|
||||||
|
|
||||||
void pcphash_add(void *key, int type) {
|
void pcphash_add(PCPCTX *ptx, void *key, int type) {
|
||||||
if(type == PCP_KEY_TYPE_PUBLIC) {
|
if(type == PCP_KEY_TYPE_PUBLIC) {
|
||||||
pcp_pubkey_t *k = (pcp_pubkey_t *)key;
|
pcp_pubkey_t *k = (pcp_pubkey_t *)key;
|
||||||
HASH_ADD_STR( pcppubkey_hash, id, k );
|
HASH_ADD_STR( ptx->pcppubkey_hash, id, k );
|
||||||
}
|
}
|
||||||
else if(type == PCP_KEYSIG_NATIVE || type == PCP_KEYSIG_PBP) {
|
else if(type == PCP_KEYSIG_NATIVE || type == PCP_KEYSIG_PBP) {
|
||||||
pcp_keysig_t *keysig = (pcp_keysig_t *)key;
|
pcp_keysig_t *keysig = (pcp_keysig_t *)key;
|
||||||
HASH_ADD_STR( pcpkeysig_hash, id, keysig);
|
HASH_ADD_STR( ptx->pcpkeysig_hash, id, keysig);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
pcp_key_t *k = (pcp_key_t *)key;
|
pcp_key_t *k = (pcp_key_t *)key;
|
||||||
HASH_ADD_STR( pcpkey_hash, id, k);
|
HASH_ADD_STR( ptx->pcpkey_hash, id, k);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int pcphash_count() {
|
int pcphash_count(PCPCTX *ptx) {
|
||||||
return HASH_COUNT(pcpkey_hash);
|
return HASH_COUNT(ptx->pcpkey_hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
int pcphash_countpub() {
|
int pcphash_countpub(PCPCTX *ptx) {
|
||||||
return HASH_COUNT(pcppubkey_hash);
|
return HASH_COUNT(ptx->pcppubkey_hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -35,37 +35,37 @@ int _get_pk(Buffer *blob, pcp_pubkey_t *p) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int _check_keysig_h(Buffer *blob, rfc_pub_sig_h *h) {
|
int _check_keysig_h(PCPCTX *ptx, Buffer *blob, rfc_pub_sig_h *h) {
|
||||||
if(buffer_left(blob) >= sizeof(rfc_pub_sig_h)) {
|
if(buffer_left(blob) >= sizeof(rfc_pub_sig_h)) {
|
||||||
buffer_get_chunk(blob, h, sizeof(rfc_pub_sig_h));
|
buffer_get_chunk(blob, h, sizeof(rfc_pub_sig_h));
|
||||||
|
|
||||||
h->numsubs = be16toh(h->numsubs);
|
h->numsubs = be16toh(h->numsubs);
|
||||||
|
|
||||||
if(h->version != EXP_SIG_VERSION) {
|
if(h->version != EXP_SIG_VERSION) {
|
||||||
fatal("Unsupported pubkey signature version %d, expected %d", h->version, EXP_SIG_VERSION);
|
fatal(ptx, "Unsupported pubkey signature version %d, expected %d", h->version, EXP_SIG_VERSION);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if(h->type != EXP_SIG_TYPE) {
|
if(h->type != EXP_SIG_TYPE) {
|
||||||
fatal("Unsupported pubkey signature type %d, expected %d", h->type, EXP_SIG_TYPE);
|
fatal(ptx, "Unsupported pubkey signature type %d, expected %d", h->type, EXP_SIG_TYPE);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if(h->pkcipher != EXP_SIG_CIPHER) {
|
if(h->pkcipher != EXP_SIG_CIPHER) {
|
||||||
fatal("Unsupported pubkey signature cipher %d, expected %d", h->pkcipher, EXP_SIG_CIPHER);
|
fatal(ptx, "Unsupported pubkey signature cipher %d, expected %d", h->pkcipher, EXP_SIG_CIPHER);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if(h->hashcipher != EXP_HASH_CIPHER) {
|
if(h->hashcipher != EXP_HASH_CIPHER) {
|
||||||
fatal("Unsupported pubkey signature hash cipher %d, expected %d", h->hashcipher, EXP_HASH_CIPHER);
|
fatal(ptx, "Unsupported pubkey signature hash cipher %d, expected %d", h->hashcipher, EXP_HASH_CIPHER);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if(h->numsubs > 0 && buffer_left(blob) < sizeof(rfc_pub_sig_s) * h->numsubs) {
|
if(h->numsubs > 0 && buffer_left(blob) < sizeof(rfc_pub_sig_s) * h->numsubs) {
|
||||||
fatal("Signature size specification invalid (sig: %ld, bytes left: %ld, numsubs: %ld",
|
fatal(ptx, "Signature size specification invalid (sig: %ld, bytes left: %ld, numsubs: %ld",
|
||||||
sizeof(rfc_pub_sig_s) * h->numsubs, buffer_left(blob), h->numsubs);
|
sizeof(rfc_pub_sig_s) * h->numsubs, buffer_left(blob), h->numsubs);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
fatal("Error: input data too small, import failed");
|
fatal(ptx, "Error: input data too small, import failed");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -108,7 +108,7 @@ int _check_sigsubs(Buffer *blob, pcp_pubkey_t *p, rfc_pub_sig_s *subheader) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int _check_hash_keysig(Buffer *blob, pcp_pubkey_t *p, pcp_keysig_t *sk) {
|
int _check_hash_keysig(PCPCTX *ptx, Buffer *blob, pcp_pubkey_t *p, pcp_keysig_t *sk) {
|
||||||
// read hash + sig
|
// read hash + sig
|
||||||
size_t blobstop = blob->offset;
|
size_t blobstop = blob->offset;
|
||||||
size_t sigsize = crypto_sign_BYTES + crypto_generichash_BYTES_MAX;
|
size_t sigsize = crypto_sign_BYTES + crypto_generichash_BYTES_MAX;
|
||||||
@@ -130,7 +130,7 @@ int _check_hash_keysig(Buffer *blob, pcp_pubkey_t *p, pcp_keysig_t *sk) {
|
|||||||
buffer_get_chunk(blob, sk->blob, sk->size);
|
buffer_get_chunk(blob, sk->blob, sk->size);
|
||||||
|
|
||||||
/* verify the signature */
|
/* verify the signature */
|
||||||
byte *verifyhash = pcp_ed_verify_key(signature, sigsize, p);
|
byte *verifyhash = pcp_ed_verify_key(ptx, signature, sigsize, p);
|
||||||
if(verifyhash == NULL)
|
if(verifyhash == NULL)
|
||||||
goto chker1;
|
goto chker1;
|
||||||
|
|
||||||
@@ -143,7 +143,7 @@ int _check_hash_keysig(Buffer *blob, pcp_pubkey_t *p, pcp_keysig_t *sk) {
|
|||||||
|
|
||||||
/* compare them */
|
/* compare them */
|
||||||
if(memcmp(hash, verifyhash, crypto_generichash_BYTES_MAX) != 0) {
|
if(memcmp(hash, verifyhash, crypto_generichash_BYTES_MAX) != 0) {
|
||||||
fatal("Signature verifies but signed hash doesn't match signature contents\n");
|
fatal(ptx, "Signature verifies but signed hash doesn't match signature contents\n");
|
||||||
goto chker2;
|
goto chker2;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -172,7 +172,7 @@ int _check_hash_keysig(Buffer *blob, pcp_pubkey_t *p, pcp_keysig_t *sk) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pcp_ks_bundle_t *pcp_import_binpub(byte *raw, size_t rawsize) {
|
pcp_ks_bundle_t *pcp_import_binpub(PCPCTX *ptx, byte *raw, size_t rawsize) {
|
||||||
Buffer *blob = buffer_new(512, "importblob");
|
Buffer *blob = buffer_new(512, "importblob");
|
||||||
|
|
||||||
buffer_add(blob, raw, rawsize);
|
buffer_add(blob, raw, rawsize);
|
||||||
@@ -182,35 +182,35 @@ pcp_ks_bundle_t *pcp_import_binpub(byte *raw, size_t rawsize) {
|
|||||||
|
|
||||||
if(version == PCP_KEY_VERSION) {
|
if(version == PCP_KEY_VERSION) {
|
||||||
/* ah, homerun */
|
/* ah, homerun */
|
||||||
return pcp_import_pub_rfc(blob);
|
return pcp_import_pub_rfc(ptx, blob);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* nope, it's probably pbp */
|
/* nope, it's probably pbp */
|
||||||
return pcp_import_pub_pbp(blob);
|
return pcp_import_pub_pbp(ptx, blob);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pcp_ks_bundle_t *pcp_import_pub(byte *raw, size_t rawsize) {
|
pcp_ks_bundle_t *pcp_import_pub(PCPCTX *ptx, byte *raw, size_t rawsize) {
|
||||||
size_t clen;
|
size_t clen;
|
||||||
byte *bin = NULL;
|
byte *bin = NULL;
|
||||||
char *z85 = NULL;
|
char *z85 = NULL;
|
||||||
|
|
||||||
if(rawsize == 0) {
|
if(rawsize == 0) {
|
||||||
fatal("Input file is empty!\n");
|
fatal(ptx, "Input file is empty!\n");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
Buffer *blob = buffer_new(512, "importblob");
|
Buffer *blob = buffer_new(512, "importblob");
|
||||||
|
|
||||||
/* first, try to decode the input */
|
/* first, try to decode the input */
|
||||||
z85 = pcp_readz85string(raw, rawsize);
|
z85 = pcp_readz85string(ptx, raw, rawsize);
|
||||||
|
|
||||||
if(z85 != NULL)
|
if(z85 != NULL)
|
||||||
bin = pcp_z85_decode(z85, &clen);
|
bin = pcp_z85_decode(ptx, z85, &clen);
|
||||||
|
|
||||||
if(bin == NULL) {
|
if(bin == NULL) {
|
||||||
/* treat as binary blob */
|
/* treat as binary blob */
|
||||||
fatals_reset();
|
fatals_reset(ptx);
|
||||||
buffer_add(blob, raw, rawsize);
|
buffer_add(blob, raw, rawsize);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -224,15 +224,15 @@ pcp_ks_bundle_t *pcp_import_pub(byte *raw, size_t rawsize) {
|
|||||||
|
|
||||||
if(version == PCP_KEY_VERSION) {
|
if(version == PCP_KEY_VERSION) {
|
||||||
/* ah, homerun */
|
/* ah, homerun */
|
||||||
return pcp_import_pub_rfc(blob);
|
return pcp_import_pub_rfc(ptx, blob);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* nope, it's probably pbp */
|
/* nope, it's probably pbp */
|
||||||
return pcp_import_pub_pbp(blob);
|
return pcp_import_pub_pbp(ptx, blob);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pcp_ks_bundle_t *pcp_import_pub_rfc(Buffer *blob) {
|
pcp_ks_bundle_t *pcp_import_pub_rfc(PCPCTX *ptx, Buffer *blob) {
|
||||||
pcp_pubkey_t *p = ucmalloc(sizeof(pcp_pubkey_t));
|
pcp_pubkey_t *p = ucmalloc(sizeof(pcp_pubkey_t));
|
||||||
pcp_keysig_t *sk = ucmalloc(sizeof(pcp_keysig_t));
|
pcp_keysig_t *sk = ucmalloc(sizeof(pcp_keysig_t));
|
||||||
rfc_pub_sig_h *sigheader = ucmalloc(sizeof(rfc_pub_sig_h));
|
rfc_pub_sig_h *sigheader = ucmalloc(sizeof(rfc_pub_sig_h));
|
||||||
@@ -245,7 +245,7 @@ pcp_ks_bundle_t *pcp_import_pub_rfc(Buffer *blob) {
|
|||||||
if(buffer_done(blob)) goto be;
|
if(buffer_done(blob)) goto be;
|
||||||
|
|
||||||
if(pkcipher != EXP_PK_CIPHER) {
|
if(pkcipher != EXP_PK_CIPHER) {
|
||||||
fatal("Unsupported pk cipher %d, expected %d", pkcipher, EXP_PK_CIPHER);
|
fatal(ptx, "Unsupported pk cipher %d, expected %d", pkcipher, EXP_PK_CIPHER);
|
||||||
goto bef;
|
goto bef;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -254,7 +254,7 @@ pcp_ks_bundle_t *pcp_import_pub_rfc(Buffer *blob) {
|
|||||||
goto be;
|
goto be;
|
||||||
|
|
||||||
/* check sig header */
|
/* check sig header */
|
||||||
if(_check_keysig_h(blob, sigheader) != 0)
|
if(_check_keysig_h(ptx, blob, sigheader) != 0)
|
||||||
goto bef;
|
goto bef;
|
||||||
|
|
||||||
/* iterate over subs, if any */
|
/* iterate over subs, if any */
|
||||||
@@ -277,7 +277,7 @@ pcp_ks_bundle_t *pcp_import_pub_rfc(Buffer *blob) {
|
|||||||
pcp_ks_bundle_t *b = ucmalloc(sizeof(pcp_ks_bundle_t));
|
pcp_ks_bundle_t *b = ucmalloc(sizeof(pcp_ks_bundle_t));
|
||||||
|
|
||||||
/* retrieve signature, store and verify it */
|
/* retrieve signature, store and verify it */
|
||||||
if(_check_hash_keysig(blob, p, sk) != 0) {
|
if(_check_hash_keysig(ptx, blob, p, sk) != 0) {
|
||||||
b->p = p;
|
b->p = p;
|
||||||
b->s = NULL;
|
b->s = NULL;
|
||||||
}
|
}
|
||||||
@@ -290,7 +290,7 @@ pcp_ks_bundle_t *pcp_import_pub_rfc(Buffer *blob) {
|
|||||||
|
|
||||||
|
|
||||||
be:
|
be:
|
||||||
fatal("Error: input data too small, import failed");
|
fatal(ptx, "Error: input data too small, import failed");
|
||||||
|
|
||||||
bef:
|
bef:
|
||||||
buffer_free(blob);
|
buffer_free(blob);
|
||||||
@@ -300,7 +300,7 @@ pcp_ks_bundle_t *pcp_import_pub_rfc(Buffer *blob) {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
pcp_ks_bundle_t *pcp_import_pub_pbp(Buffer *blob) {
|
pcp_ks_bundle_t *pcp_import_pub_pbp(PCPCTX *ptx, Buffer *blob) {
|
||||||
char *date = ucmalloc(19);
|
char *date = ucmalloc(19);
|
||||||
char *ignore = ucmalloc(46);
|
char *ignore = ucmalloc(46);
|
||||||
char *parts = NULL;
|
char *parts = NULL;
|
||||||
@@ -314,7 +314,7 @@ pcp_ks_bundle_t *pcp_import_pub_pbp(Buffer *blob) {
|
|||||||
|
|
||||||
/* make sure it's a pbp */
|
/* make sure it's a pbp */
|
||||||
if(_buffer_is_binary(sig, crypto_sign_BYTES) == 0) {
|
if(_buffer_is_binary(sig, crypto_sign_BYTES) == 0) {
|
||||||
fatal("failed to recognize input, that's probably no key\n");
|
fatal(ptx, "failed to recognize input, that's probably no key\n");
|
||||||
goto errimp2;
|
goto errimp2;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -326,7 +326,7 @@ pcp_ks_bundle_t *pcp_import_pub_pbp(Buffer *blob) {
|
|||||||
date[19] = '\0';
|
date[19] = '\0';
|
||||||
struct tm c;
|
struct tm c;
|
||||||
if(strptime(date, "%Y-%m-%dT%H:%M:%S", &c) == NULL) {
|
if(strptime(date, "%Y-%m-%dT%H:%M:%S", &c) == NULL) {
|
||||||
fatal("Failed to parse creation time in PBP public key file (<%s>)\n", date);
|
fatal(ptx, "Failed to parse creation time in PBP public key file (<%s>)\n", date);
|
||||||
free(date);
|
free(date);
|
||||||
goto errimp2;
|
goto errimp2;
|
||||||
}
|
}
|
||||||
@@ -365,7 +365,7 @@ pcp_ks_bundle_t *pcp_import_pub_pbp(Buffer *blob) {
|
|||||||
/* edpub used for signing, might differ */
|
/* edpub used for signing, might differ */
|
||||||
memcpy(tmp->edpub, b->sigpub, crypto_sign_PUBLICKEYBYTES);
|
memcpy(tmp->edpub, b->sigpub, crypto_sign_PUBLICKEYBYTES);
|
||||||
|
|
||||||
byte *verify = pcp_ed_verify(buffer_get(blob), buffer_size(blob), tmp);
|
byte *verify = pcp_ed_verify(ptx, buffer_get(blob), buffer_size(blob), tmp);
|
||||||
free(tmp);
|
free(tmp);
|
||||||
|
|
||||||
pcp_ks_bundle_t *bundle = ucmalloc(sizeof(pcp_ks_bundle_t));
|
pcp_ks_bundle_t *bundle = ucmalloc(sizeof(pcp_ks_bundle_t));
|
||||||
@@ -671,7 +671,7 @@ Buffer *pcp_export_rfc_pub (pcp_key_t *sk) {
|
|||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
Buffer *pcp_export_secret(pcp_key_t *sk, char *passphrase) {
|
Buffer *pcp_export_secret(PCPCTX *ptx, pcp_key_t *sk, char *passphrase) {
|
||||||
byte *nonce = NULL;
|
byte *nonce = NULL;
|
||||||
byte *symkey = NULL;
|
byte *symkey = NULL;
|
||||||
byte *cipher = NULL;
|
byte *cipher = NULL;
|
||||||
@@ -708,7 +708,7 @@ Buffer *pcp_export_secret(pcp_key_t *sk, char *passphrase) {
|
|||||||
|
|
||||||
nonce = ucmalloc(crypto_secretbox_NONCEBYTES);
|
nonce = ucmalloc(crypto_secretbox_NONCEBYTES);
|
||||||
arc4random_buf(nonce, crypto_secretbox_NONCEBYTES);
|
arc4random_buf(nonce, crypto_secretbox_NONCEBYTES);
|
||||||
symkey = pcp_scrypt(passphrase, strlen(passphrase), nonce, crypto_secretbox_NONCEBYTES);
|
symkey = pcp_scrypt(ptx, passphrase, strlen(passphrase), nonce, crypto_secretbox_NONCEBYTES);
|
||||||
|
|
||||||
es = pcp_sodium_mac(&cipher, buffer_get(raw), buffer_size(raw), nonce, symkey);
|
es = pcp_sodium_mac(&cipher, buffer_get(raw), buffer_size(raw), nonce, symkey);
|
||||||
|
|
||||||
@@ -723,33 +723,33 @@ Buffer *pcp_export_secret(pcp_key_t *sk, char *passphrase) {
|
|||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
pcp_key_t *pcp_import_binsecret(byte *raw, size_t rawsize, char *passphrase) {
|
pcp_key_t *pcp_import_binsecret(PCPCTX *ptx, byte *raw, size_t rawsize, char *passphrase) {
|
||||||
Buffer *blob = buffer_new(512, "importskblob");
|
Buffer *blob = buffer_new(512, "importskblob");
|
||||||
buffer_add(blob, raw, rawsize);
|
buffer_add(blob, raw, rawsize);
|
||||||
return pcp_import_secret_native(blob, passphrase);
|
return pcp_import_secret_native(ptx, blob, passphrase);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
pcp_key_t *pcp_import_secret(byte *raw, size_t rawsize, char *passphrase) {
|
pcp_key_t *pcp_import_secret(PCPCTX *ptx, byte *raw, size_t rawsize, char *passphrase) {
|
||||||
size_t clen;
|
size_t clen;
|
||||||
byte *bin = NULL;
|
byte *bin = NULL;
|
||||||
char *z85 = NULL;
|
char *z85 = NULL;
|
||||||
|
|
||||||
if(rawsize == 0) {
|
if(rawsize == 0) {
|
||||||
fatal("Input file is empty!\n");
|
fatal(ptx, "Input file is empty!\n");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
Buffer *blob = buffer_new(512, "importskblob");
|
Buffer *blob = buffer_new(512, "importskblob");
|
||||||
|
|
||||||
/* first, try to decode the input */
|
/* first, try to decode the input */
|
||||||
z85 = pcp_readz85string(raw, rawsize);
|
z85 = pcp_readz85string(ptx, raw, rawsize);
|
||||||
if(z85 != NULL)
|
if(z85 != NULL)
|
||||||
bin = pcp_z85_decode(z85, &clen);
|
bin = pcp_z85_decode(ptx, z85, &clen);
|
||||||
|
|
||||||
if(bin == NULL) {
|
if(bin == NULL) {
|
||||||
/* treat as binary blob */
|
/* treat as binary blob */
|
||||||
fatals_reset();
|
fatals_reset(ptx);
|
||||||
buffer_add(blob, raw, rawsize);
|
buffer_add(blob, raw, rawsize);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -759,10 +759,10 @@ pcp_key_t *pcp_import_secret(byte *raw, size_t rawsize, char *passphrase) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* now we've got the blob, parse it */
|
/* now we've got the blob, parse it */
|
||||||
return pcp_import_secret_native(blob, passphrase);
|
return pcp_import_secret_native(ptx, blob, passphrase);
|
||||||
}
|
}
|
||||||
|
|
||||||
pcp_key_t *pcp_import_secret_native(Buffer *cipher, char *passphrase) {
|
pcp_key_t *pcp_import_secret_native(PCPCTX *ptx, Buffer *cipher, char *passphrase) {
|
||||||
pcp_key_t *sk = ucmalloc(sizeof(pcp_key_t));
|
pcp_key_t *sk = ucmalloc(sizeof(pcp_key_t));
|
||||||
byte *nonce = ucmalloc(crypto_secretbox_NONCEBYTES);
|
byte *nonce = ucmalloc(crypto_secretbox_NONCEBYTES);
|
||||||
byte *symkey = NULL;
|
byte *symkey = NULL;
|
||||||
@@ -776,11 +776,11 @@ pcp_key_t *pcp_import_secret_native(Buffer *cipher, char *passphrase) {
|
|||||||
if(buffer_get_chunk(cipher, nonce, crypto_secretbox_NONCEBYTES) == 0)
|
if(buffer_get_chunk(cipher, nonce, crypto_secretbox_NONCEBYTES) == 0)
|
||||||
goto impserr1;
|
goto impserr1;
|
||||||
|
|
||||||
symkey = pcp_scrypt(passphrase, strlen(passphrase), nonce, crypto_secretbox_NONCEBYTES);
|
symkey = pcp_scrypt(ptx, passphrase, strlen(passphrase), nonce, crypto_secretbox_NONCEBYTES);
|
||||||
|
|
||||||
cipherlen = buffer_left(cipher);
|
cipherlen = buffer_left(cipher);
|
||||||
if(cipherlen < minlen) {
|
if(cipherlen < minlen) {
|
||||||
fatal("failed to decrypt the secret key file:\n"
|
fatal(ptx, "failed to decrypt the secret key file:\n"
|
||||||
"expected encrypted secret key size %ld is less than minimum len %ld\n", cipherlen, minlen);
|
"expected encrypted secret key size %ld is less than minimum len %ld\n", cipherlen, minlen);
|
||||||
goto impserr1;
|
goto impserr1;
|
||||||
}
|
}
|
||||||
@@ -788,7 +788,7 @@ pcp_key_t *pcp_import_secret_native(Buffer *cipher, char *passphrase) {
|
|||||||
/* decrypt the blob */
|
/* decrypt the blob */
|
||||||
if(pcp_sodium_verify_mac(&clear, buffer_get_remainder(cipher),
|
if(pcp_sodium_verify_mac(&clear, buffer_get_remainder(cipher),
|
||||||
cipherlen, nonce, symkey) != 0) {
|
cipherlen, nonce, symkey) != 0) {
|
||||||
fatal("failed to decrypt the secret key file\n");
|
fatal(ptx, "failed to decrypt the secret key file\n");
|
||||||
goto impserr1;
|
goto impserr1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -359,9 +359,7 @@ void ps_determine(Pcpstream *stream) {
|
|||||||
size_t ps_read_decode(Pcpstream *stream) {
|
size_t ps_read_decode(Pcpstream *stream) {
|
||||||
Buffer *z = buffer_new(32, "ztemp");
|
Buffer *z = buffer_new(32, "ztemp");
|
||||||
Buffer *line = buffer_new_str("line");
|
Buffer *line = buffer_new_str("line");
|
||||||
|
PCPCTX *ptx = ptx_new();
|
||||||
//buffer_info(stream->save);
|
|
||||||
|
|
||||||
|
|
||||||
if(buffer_left(stream->save) > stream->blocksize){// && stream->firstread == 1) {
|
if(buffer_left(stream->save) > stream->blocksize){// && stream->firstread == 1) {
|
||||||
/* use the save buffer instead */
|
/* use the save buffer instead */
|
||||||
@@ -376,7 +374,7 @@ size_t ps_read_decode(Pcpstream *stream) {
|
|||||||
// fprintf(stderr, " ps_read_next which doesn't end in a newline\n");
|
// fprintf(stderr, " ps_read_next which doesn't end in a newline\n");
|
||||||
buffer_get_chunk_tobuf(stream->save, z, buffer_left(stream->save));
|
buffer_get_chunk_tobuf(stream->save, z, buffer_left(stream->save));
|
||||||
//buffer_dump(z);
|
//buffer_dump(z);
|
||||||
fatals_ifany();
|
//fatals_ifany();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* continue reading linewise */
|
/* continue reading linewise */
|
||||||
@@ -435,10 +433,10 @@ size_t ps_read_decode(Pcpstream *stream) {
|
|||||||
|
|
||||||
/* finally, decode it and put into next */
|
/* finally, decode it and put into next */
|
||||||
size_t binlen, outlen;
|
size_t binlen, outlen;
|
||||||
byte *bin = pcp_z85_decode(buffer_get_str(z), &binlen);
|
byte *bin = pcp_z85_decode(ptx, buffer_get_str(z), &binlen);
|
||||||
//fprintf(stderr, "ps_read_decode decoding z: %ld, got: %ld\n", buffer_size(z), binlen);
|
//fprintf(stderr, "ps_read_decode decoding z: %ld, got: %ld\n", buffer_size(z), binlen);
|
||||||
// _dump("bin", bin, binlen);
|
// _dump("bin", bin, binlen);
|
||||||
fatals_ifany();
|
//fatals_ifany();
|
||||||
if(bin == NULL) {
|
if(bin == NULL) {
|
||||||
/* it's not z85 encoded, so threat it as binary */
|
/* it's not z85 encoded, so threat it as binary */
|
||||||
if(stream->firstread) {
|
if(stream->firstread) {
|
||||||
@@ -461,7 +459,7 @@ size_t ps_read_decode(Pcpstream *stream) {
|
|||||||
|
|
||||||
buffer_free(z);
|
buffer_free(z);
|
||||||
buffer_free(line);
|
buffer_free(line);
|
||||||
|
ptx_clean(ptx);
|
||||||
|
|
||||||
return outlen;
|
return outlen;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
|
|
||||||
#include "scrypt.h"
|
#include "scrypt.h"
|
||||||
|
|
||||||
byte* pcp_scrypt(char *passwd, size_t passwdlen, byte *nonce, size_t noncelen) {
|
byte* pcp_scrypt(PCPCTX *ptx, char *passwd, size_t passwdlen, byte *nonce, size_t noncelen) {
|
||||||
uint8_t *dk = ucmalloc(64); /* resulting hash */
|
uint8_t *dk = ucmalloc(64); /* resulting hash */
|
||||||
|
|
||||||
/* constants */
|
/* constants */
|
||||||
@@ -34,7 +34,7 @@ byte* pcp_scrypt(char *passwd, size_t passwdlen, byte *nonce, size_t noncelen) {
|
|||||||
return dk;
|
return dk;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
fatal("crypto_scrypt() failed");
|
fatal(ptx, "crypto_scrypt() failed");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
108
libpcp/vault.c
108
libpcp/vault.c
@@ -24,19 +24,19 @@
|
|||||||
#include "keyhash.h"
|
#include "keyhash.h"
|
||||||
#include "defines.h"
|
#include "defines.h"
|
||||||
|
|
||||||
vault_t *pcpvault_init(char *filename) {
|
vault_t *pcpvault_init(PCPCTX *ptx, char *filename) {
|
||||||
vault_t *vault = pcpvault_new(filename, 0);
|
vault_t *vault = pcpvault_new(ptx, filename, 0);
|
||||||
if(vault != NULL) {
|
if(vault != NULL) {
|
||||||
if(vault->isnew == 1) {
|
if(vault->isnew == 1) {
|
||||||
if(pcpvault_create(vault) != 0) {
|
if(pcpvault_create(ptx, vault) != 0) {
|
||||||
pcpvault_close(vault);
|
pcpvault_close(ptx, vault);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if(pcpvault_fetchall(vault) != 0) {
|
if(pcpvault_fetchall(ptx, vault) != 0) {
|
||||||
errno = 0; /* weird, something sets it to ENOENT and it's not me */
|
errno = 0; /* weird, something sets it to ENOENT and it's not me */
|
||||||
pcpvault_close(vault);
|
pcpvault_close(ptx, vault);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -44,7 +44,7 @@ vault_t *pcpvault_init(char *filename) {
|
|||||||
return vault;
|
return vault;
|
||||||
}
|
}
|
||||||
|
|
||||||
vault_t *pcpvault_new(char *filename, int is_tmp) {
|
vault_t *pcpvault_new(PCPCTX *ptx, char *filename, int is_tmp) {
|
||||||
vault_t *vault = ucmalloc(sizeof(vault_t));
|
vault_t *vault = ucmalloc(sizeof(vault_t));
|
||||||
FILE *fd;
|
FILE *fd;
|
||||||
struct stat stat_buf;
|
struct stat stat_buf;
|
||||||
@@ -82,7 +82,7 @@ vault_t *pcpvault_new(char *filename, int is_tmp) {
|
|||||||
vault->isnew = 1;
|
vault->isnew = 1;
|
||||||
mode_t old_mask = umask (S_IWGRP | S_IWOTH | S_IRGRP | S_IROTH);
|
mode_t old_mask = umask (S_IWGRP | S_IWOTH | S_IRGRP | S_IROTH);
|
||||||
if((fd = fopen(vault->filename, "wb+")) == NULL) {
|
if((fd = fopen(vault->filename, "wb+")) == NULL) {
|
||||||
fatal("Could not create vault file %s", vault->filename);
|
fatal(ptx, "Could not create vault file %s", vault->filename);
|
||||||
umask (old_mask);
|
umask (old_mask);
|
||||||
goto errn;
|
goto errn;
|
||||||
}
|
}
|
||||||
@@ -90,7 +90,7 @@ vault_t *pcpvault_new(char *filename, int is_tmp) {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if((fd = fopen(vault->filename, "rb+")) == NULL) {
|
if((fd = fopen(vault->filename, "rb+")) == NULL) {
|
||||||
fatal("Could not open vault file %s", vault->filename);
|
fatal(ptx, "Could not open vault file %s", vault->filename);
|
||||||
goto errn;
|
goto errn;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -105,7 +105,7 @@ vault_t *pcpvault_new(char *filename, int is_tmp) {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int pcpvault_create(vault_t *vault) {
|
int pcpvault_create(PCPCTX *ptx, vault_t *vault) {
|
||||||
vault_header_t *header = ucmalloc(sizeof(vault_header_t));
|
vault_header_t *header = ucmalloc(sizeof(vault_header_t));
|
||||||
header->fileid = PCP_VAULT_ID;
|
header->fileid = PCP_VAULT_ID;
|
||||||
header->version = PCP_VAULT_VERSION;
|
header->version = PCP_VAULT_VERSION;
|
||||||
@@ -120,7 +120,7 @@ int pcpvault_create(vault_t *vault) {
|
|||||||
fwrite(header, sizeof(vault_header_t), 1, vault->fd);
|
fwrite(header, sizeof(vault_header_t), 1, vault->fd);
|
||||||
|
|
||||||
if(ferror(vault->fd) != 0) {
|
if(ferror(vault->fd) != 0) {
|
||||||
fatal("Failed to write fileheader to vault %s!\n", vault->filename);
|
fatal(ptx, "Failed to write fileheader to vault %s!\n", vault->filename);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -129,7 +129,7 @@ int pcpvault_create(vault_t *vault) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int pcpvault_additem(vault_t *vault, void *item, size_t itemsize, uint8_t type) {
|
int pcpvault_additem(PCPCTX *ptx, vault_t *vault, void *item, size_t itemsize, uint8_t type) {
|
||||||
vault_item_header_t *header = ucmalloc(sizeof(vault_item_header_t));
|
vault_item_header_t *header = ucmalloc(sizeof(vault_item_header_t));
|
||||||
header->type = type;
|
header->type = type;
|
||||||
header->size = itemsize;
|
header->size = itemsize;
|
||||||
@@ -141,7 +141,7 @@ int pcpvault_additem(vault_t *vault, void *item, size_t itemsize, uint8_t type)
|
|||||||
fwrite(item, itemsize, 1, vault->fd);
|
fwrite(item, itemsize, 1, vault->fd);
|
||||||
|
|
||||||
if(ferror(vault->fd) != 0) {
|
if(ferror(vault->fd) != 0) {
|
||||||
fatal("Failed to add an item to vault %s!\n", vault->filename);
|
fatal(ptx, "Failed to add an item to vault %s!\n", vault->filename);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -151,8 +151,8 @@ int pcpvault_additem(vault_t *vault, void *item, size_t itemsize, uint8_t type)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int pcpvault_addkey(vault_t *vault, void *item, uint8_t type) {
|
int pcpvault_addkey(PCPCTX *ptx, vault_t *vault, void *item, uint8_t type) {
|
||||||
vault_t *tmp = pcpvault_new(vault->filename, 1);
|
vault_t *tmp = pcpvault_new(ptx, vault->filename, 1);
|
||||||
size_t itemsize;
|
size_t itemsize;
|
||||||
|
|
||||||
void *saveitem = NULL;
|
void *saveitem = NULL;
|
||||||
@@ -183,15 +183,15 @@ int pcpvault_addkey(vault_t *vault, void *item, uint8_t type) {
|
|||||||
|
|
||||||
|
|
||||||
if(tmp != NULL) {
|
if(tmp != NULL) {
|
||||||
if(pcpvault_copy(vault, tmp) != 0)
|
if(pcpvault_copy(ptx, vault, tmp) != 0)
|
||||||
goto errak1;
|
goto errak1;
|
||||||
if(pcpvault_additem(tmp, buffer_get(blob), itemsize, type) != 0)
|
if(pcpvault_additem(ptx, tmp, buffer_get(blob), itemsize, type) != 0)
|
||||||
goto errak1;
|
goto errak1;
|
||||||
|
|
||||||
pcphash_add(saveitem, type);
|
pcphash_add(ptx, saveitem, type);
|
||||||
pcpvault_update_checksum(tmp);
|
pcpvault_update_checksum(ptx, tmp);
|
||||||
|
|
||||||
if(pcpvault_copy(tmp, vault) == 0) {
|
if(pcpvault_copy(ptx, tmp, vault) == 0) {
|
||||||
pcpvault_unlink(tmp);
|
pcpvault_unlink(tmp);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -212,32 +212,32 @@ int pcpvault_addkey(vault_t *vault, void *item, uint8_t type) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int pcpvault_writeall(vault_t *vault) {
|
int pcpvault_writeall(PCPCTX *ptx, vault_t *vault) {
|
||||||
vault_t *tmp = pcpvault_new(vault->filename, 1);
|
vault_t *tmp = pcpvault_new(ptx, vault->filename, 1);
|
||||||
|
|
||||||
if(tmp != NULL) {
|
if(tmp != NULL) {
|
||||||
if(pcpvault_create(tmp) == 0) {
|
if(pcpvault_create(ptx, tmp) == 0) {
|
||||||
pcp_key_t *k = NULL;
|
pcp_key_t *k = NULL;
|
||||||
Buffer *blob = buffer_new(PCP_RAW_PUBKEYSIZE, "bs");
|
Buffer *blob = buffer_new(PCP_RAW_PUBKEYSIZE, "bs");
|
||||||
pcphash_iterate(k) {
|
pcphash_iterate(ptx, k) {
|
||||||
pcp_seckeyblob(blob, k);
|
pcp_seckeyblob(blob, k);
|
||||||
if(pcpvault_additem(tmp, buffer_get(blob), PCP_RAW_KEYSIZE, PCP_KEY_TYPE_SECRET) != 0) {
|
if(pcpvault_additem(ptx, tmp, buffer_get(blob), PCP_RAW_KEYSIZE, PCP_KEY_TYPE_SECRET) != 0) {
|
||||||
buffer_free(blob);
|
buffer_free(blob);
|
||||||
goto errwa;
|
goto errwa;
|
||||||
}
|
}
|
||||||
buffer_clear(blob);
|
buffer_clear(blob);
|
||||||
}
|
}
|
||||||
pcp_pubkey_t *p = NULL;
|
pcp_pubkey_t *p = NULL;
|
||||||
pcphash_iteratepub(p) {
|
pcphash_iteratepub(ptx, p) {
|
||||||
pcp_pubkeyblob(blob, p);
|
pcp_pubkeyblob(blob, p);
|
||||||
if(pcpvault_additem(tmp, buffer_get(blob), PCP_RAW_PUBKEYSIZE, PCP_KEY_TYPE_PUBLIC) != 0) {
|
if(pcpvault_additem(ptx, tmp, buffer_get(blob), PCP_RAW_PUBKEYSIZE, PCP_KEY_TYPE_PUBLIC) != 0) {
|
||||||
buffer_free(blob);
|
buffer_free(blob);
|
||||||
goto errwa;
|
goto errwa;
|
||||||
}
|
}
|
||||||
buffer_clear(blob);
|
buffer_clear(blob);
|
||||||
}
|
}
|
||||||
pcpvault_update_checksum(tmp);
|
pcpvault_update_checksum(ptx, tmp);
|
||||||
if(pcpvault_copy(tmp, vault) == 0) {
|
if(pcpvault_copy(ptx, tmp, vault) == 0) {
|
||||||
pcpvault_unlink(tmp);
|
pcpvault_unlink(tmp);
|
||||||
}
|
}
|
||||||
free(tmp);
|
free(tmp);
|
||||||
@@ -256,8 +256,8 @@ int pcpvault_writeall(vault_t *vault) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void pcpvault_update_checksum(vault_t *vault) {
|
void pcpvault_update_checksum(PCPCTX *ptx, vault_t *vault) {
|
||||||
byte *checksum = pcpvault_create_checksum();
|
byte *checksum = pcpvault_create_checksum(ptx);
|
||||||
|
|
||||||
vault_header_t *header = ucmalloc(sizeof(vault_header_t));
|
vault_header_t *header = ucmalloc(sizeof(vault_header_t));
|
||||||
header->fileid = PCP_VAULT_ID;
|
header->fileid = PCP_VAULT_ID;
|
||||||
@@ -272,20 +272,20 @@ void pcpvault_update_checksum(vault_t *vault) {
|
|||||||
fseek(vault->fd, 0, SEEK_END);
|
fseek(vault->fd, 0, SEEK_END);
|
||||||
}
|
}
|
||||||
|
|
||||||
byte *pcpvault_create_checksum() {
|
byte *pcpvault_create_checksum(PCPCTX *ptx) {
|
||||||
pcp_key_t *k = NULL;
|
pcp_key_t *k = NULL;
|
||||||
Buffer *blob = NULL;
|
Buffer *blob = NULL;
|
||||||
size_t datapos = 0;
|
size_t datapos = 0;
|
||||||
|
|
||||||
int numskeys = pcphash_count();
|
int numskeys = pcphash_count(ptx);
|
||||||
int numpkeys = pcphash_countpub();
|
int numpkeys = pcphash_countpub(ptx);
|
||||||
|
|
||||||
size_t datasize = ((PCP_RAW_KEYSIZE) * numskeys) +
|
size_t datasize = ((PCP_RAW_KEYSIZE) * numskeys) +
|
||||||
((PCP_RAW_PUBKEYSIZE) * numpkeys);
|
((PCP_RAW_PUBKEYSIZE) * numpkeys);
|
||||||
byte *data = ucmalloc(datasize);
|
byte *data = ucmalloc(datasize);
|
||||||
byte *checksum = ucmalloc(32);
|
byte *checksum = ucmalloc(32);
|
||||||
|
|
||||||
pcphash_iterate(k) {
|
pcphash_iterate(ptx, k) {
|
||||||
key2be(k);
|
key2be(k);
|
||||||
blob = pcp_keyblob(k, PCP_KEY_TYPE_SECRET);
|
blob = pcp_keyblob(k, PCP_KEY_TYPE_SECRET);
|
||||||
memcpy(&data[datapos], buffer_get(blob), PCP_RAW_KEYSIZE);
|
memcpy(&data[datapos], buffer_get(blob), PCP_RAW_KEYSIZE);
|
||||||
@@ -295,7 +295,7 @@ byte *pcpvault_create_checksum() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pcp_pubkey_t *p = NULL;
|
pcp_pubkey_t *p = NULL;
|
||||||
pcphash_iteratepub(p) {
|
pcphash_iteratepub(ptx, p) {
|
||||||
/* pcp_dumppubkey(p); */
|
/* pcp_dumppubkey(p); */
|
||||||
pubkey2be(p);
|
pubkey2be(p);
|
||||||
blob = pcp_keyblob(p, PCP_KEY_TYPE_PUBLIC);
|
blob = pcp_keyblob(p, PCP_KEY_TYPE_PUBLIC);
|
||||||
@@ -322,7 +322,7 @@ byte *pcpvault_create_checksum() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int pcpvault_copy(vault_t *tmp, vault_t *vault) {
|
int pcpvault_copy(PCPCTX *ptx, vault_t *tmp, vault_t *vault) {
|
||||||
/* fetch tmp content */
|
/* fetch tmp content */
|
||||||
fseek(tmp->fd, 0, SEEK_END);
|
fseek(tmp->fd, 0, SEEK_END);
|
||||||
int tmpsize = ftell(tmp->fd);
|
int tmpsize = ftell(tmp->fd);
|
||||||
@@ -333,13 +333,13 @@ int pcpvault_copy(vault_t *tmp, vault_t *vault) {
|
|||||||
/* and put it into the new file */
|
/* and put it into the new file */
|
||||||
vault->fd = freopen(vault->filename, "wb+", vault->fd);
|
vault->fd = freopen(vault->filename, "wb+", vault->fd);
|
||||||
if(fwrite(in, tmpsize, 1, vault->fd) != 1) {
|
if(fwrite(in, tmpsize, 1, vault->fd) != 1) {
|
||||||
fatal("Failed to copy %s to %s (write) [keeping %s]\n",
|
fatal(ptx, "Failed to copy %s to %s (write) [keeping %s]\n",
|
||||||
tmp->filename, vault->filename, tmp->filename);
|
tmp->filename, vault->filename, tmp->filename);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(fflush(vault->fd) != 0) {
|
if(fflush(vault->fd) != 0) {
|
||||||
fatal("Failed to copy %s to %s (flush) [keeping %s]\n",
|
fatal(ptx, "Failed to copy %s to %s (flush) [keeping %s]\n",
|
||||||
tmp->filename, vault->filename, tmp->filename);
|
tmp->filename, vault->filename, tmp->filename);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -363,11 +363,11 @@ void pcpvault_unlink(vault_t *tmp) {
|
|||||||
free(r);
|
free(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
int pcpvault_close(vault_t *vault) {
|
int pcpvault_close(PCPCTX *ptx, vault_t *vault) {
|
||||||
if(vault != NULL) {
|
if(vault != NULL) {
|
||||||
if(vault->fd) {
|
if(vault->fd) {
|
||||||
if(vault->unsafed == 1) {
|
if(vault->unsafed == 1) {
|
||||||
pcpvault_writeall(vault);
|
pcpvault_writeall(ptx, vault);
|
||||||
}
|
}
|
||||||
fclose(vault->fd);
|
fclose(vault->fd);
|
||||||
}
|
}
|
||||||
@@ -416,7 +416,7 @@ vault_item_header_t * ih2native(vault_item_header_t *h) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int pcpvault_fetchall(vault_t *vault) {
|
int pcpvault_fetchall(PCPCTX *ptx, vault_t *vault) {
|
||||||
size_t got = 0;
|
size_t got = 0;
|
||||||
fseek(vault->fd, 0, SEEK_SET);
|
fseek(vault->fd, 0, SEEK_SET);
|
||||||
|
|
||||||
@@ -424,7 +424,7 @@ int pcpvault_fetchall(vault_t *vault) {
|
|||||||
vault_item_header_t *item = ucmalloc(sizeof(vault_item_header_t));
|
vault_item_header_t *item = ucmalloc(sizeof(vault_item_header_t));
|
||||||
got = fread(header, 1, sizeof(vault_header_t), vault->fd);
|
got = fread(header, 1, sizeof(vault_header_t), vault->fd);
|
||||||
if(got < sizeof(vault_header_t)) {
|
if(got < sizeof(vault_header_t)) {
|
||||||
fatal("empty or invalid vault header size (got %ld, expected %ld)\n", got, sizeof(vault_header_t));
|
fatal(ptx, "empty or invalid vault header size (got %ld, expected %ld)\n", got, sizeof(vault_header_t));
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
vh2native(header);
|
vh2native(header);
|
||||||
@@ -437,8 +437,6 @@ int pcpvault_fetchall(vault_t *vault) {
|
|||||||
int bytesleft = 0;
|
int bytesleft = 0;
|
||||||
int ksize = PCP_RAW_KEYSIGSIZE; /* smallest possbile item */
|
int ksize = PCP_RAW_KEYSIGSIZE; /* smallest possbile item */
|
||||||
|
|
||||||
pcphash_init();
|
|
||||||
|
|
||||||
vault->version = header->version;
|
vault->version = header->version;
|
||||||
memcpy(vault->checksum, header->checksum, 32);
|
memcpy(vault->checksum, header->checksum, 32);
|
||||||
|
|
||||||
@@ -461,34 +459,34 @@ int pcpvault_fetchall(vault_t *vault) {
|
|||||||
key = ucmalloc(sizeof(pcp_key_t));
|
key = ucmalloc(sizeof(pcp_key_t));
|
||||||
got = fread(key, PCP_RAW_KEYSIZE, 1, vault->fd);
|
got = fread(key, PCP_RAW_KEYSIZE, 1, vault->fd);
|
||||||
key2native(key);
|
key2native(key);
|
||||||
pcphash_add((void *)key, item->type);
|
pcphash_add(ptx, (void *)key, item->type);
|
||||||
}
|
}
|
||||||
else if(item->type == PCP_KEY_TYPE_PUBLIC) {
|
else if(item->type == PCP_KEY_TYPE_PUBLIC) {
|
||||||
/* read a public key */
|
/* read a public key */
|
||||||
pubkey = ucmalloc(sizeof(pcp_pubkey_t));
|
pubkey = ucmalloc(sizeof(pcp_pubkey_t));
|
||||||
got = fread(pubkey, PCP_RAW_PUBKEYSIZE, 1, vault->fd);
|
got = fread(pubkey, PCP_RAW_PUBKEYSIZE, 1, vault->fd);
|
||||||
pubkey2native(pubkey);
|
pubkey2native(pubkey);
|
||||||
pcphash_add((void *)pubkey, item->type);
|
pcphash_add(ptx, (void *)pubkey, item->type);
|
||||||
}
|
}
|
||||||
else if(item->type == PCP_KEYSIG_NATIVE || item->type == PCP_KEYSIG_PBP) {
|
else if(item->type == PCP_KEYSIG_NATIVE || item->type == PCP_KEYSIG_PBP) {
|
||||||
Buffer *rawks = buffer_new(256, "keysig");
|
Buffer *rawks = buffer_new(256, "keysig");
|
||||||
buffer_fd_read(rawks, vault->fd, item->size);
|
buffer_fd_read(rawks, vault->fd, item->size);
|
||||||
pcp_keysig_t *s = pcp_keysig_new(rawks);
|
pcp_keysig_t *s = pcp_keysig_new(rawks);
|
||||||
pcphash_add((void *)s, item->type);
|
pcphash_add(ptx, (void *)s, item->type);
|
||||||
buffer_free(rawks);
|
buffer_free(rawks);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
fatal("Failed to read vault - invalid key type: %02X! at %d\n", item->type, readpos);
|
fatal(ptx, "Failed to read vault - invalid key type: %02X! at %d\n", item->type, readpos);
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
fatal("Failed to read vault - that's no pcp key at %d (size %ld)!\n", readpos, bytesleft);
|
fatal(ptx, "Failed to read vault - that's no pcp key at %d (size %ld)!\n", readpos, bytesleft);
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
fatal("Failed to read vault - invalid key item header size at %d!\n",
|
fatal(ptx, "Failed to read vault - invalid key item header size at %d!\n",
|
||||||
readpos);
|
readpos);
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
@@ -500,22 +498,22 @@ int pcpvault_fetchall(vault_t *vault) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
fatal("Unexpected vault file format!\n");
|
fatal(ptx, "Unexpected vault file format!\n");
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
byte *checksum = NULL;
|
byte *checksum = NULL;
|
||||||
checksum = pcpvault_create_checksum(vault);
|
checksum = pcpvault_create_checksum(ptx);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
_dump(" calc checksum", checksum, 32);
|
_dump(" calc checksum", checksum, 32);
|
||||||
_dump("vault checksum", vault->checksum, 32);
|
_dump("vault checksum", vault->checksum, 32);
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if(pcphash_count() + pcphash_countpub() > 0) {
|
if(pcphash_count(ptx) + pcphash_countpub(ptx) > 0) {
|
||||||
/* only validate the checksum if there are keys */
|
/* only validate the checksum if there are keys */
|
||||||
if(memcmp(checksum, vault->checksum, 32) != 0) {
|
if(memcmp(checksum, vault->checksum, 32) != 0) {
|
||||||
fatal("Error: the checksum of the key vault doesn't match its contents!\n");
|
fatal(ptx, "Error: the checksum of the key vault doesn't match its contents!\n");
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
18
libpcp/z85.c
18
libpcp/z85.c
@@ -182,7 +182,7 @@ size_t pcp_unpadfour(byte *src, size_t srclen) {
|
|||||||
return outlen;
|
return outlen;
|
||||||
}
|
}
|
||||||
|
|
||||||
byte *pcp_z85_decode(char *z85block, size_t *dstlen) {
|
byte *pcp_z85_decode(PCPCTX *ptx, char *z85block, size_t *dstlen) {
|
||||||
byte *bin = NULL;
|
byte *bin = NULL;
|
||||||
size_t binlen, outlen;
|
size_t binlen, outlen;
|
||||||
size_t srclen;
|
size_t srclen;
|
||||||
@@ -199,7 +199,7 @@ byte *pcp_z85_decode(char *z85block, size_t *dstlen) {
|
|||||||
bin = ucmalloc(binlen);
|
bin = ucmalloc(binlen);
|
||||||
|
|
||||||
if(zmq_z85_decode(bin, z85block) == NULL) {
|
if(zmq_z85_decode(bin, z85block) == NULL) {
|
||||||
fatal("zmq_z85_decode() failed, input size ! mod 5 (got %ld)", strlen(z85block));
|
fatal(ptx, "zmq_z85_decode() failed, input size ! mod 5 (got %ld)", strlen(z85block));
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -251,7 +251,7 @@ char *pcp_z85_encode(byte *raw, size_t srclen, size_t *dstlen) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
char *pcp_readz85file(FILE *infile) {
|
char *pcp_readz85file(PCPCTX *ptx, FILE *infile) {
|
||||||
byte *input = NULL;
|
byte *input = NULL;
|
||||||
byte *tmp = NULL;
|
byte *tmp = NULL;
|
||||||
size_t bufsize = 0;
|
size_t bufsize = 0;
|
||||||
@@ -269,25 +269,25 @@ char *pcp_readz85file(FILE *infile) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(bufsize == 0) {
|
if(bufsize == 0) {
|
||||||
fatal("Input file is empty!\n");
|
fatal(ptx, "Input file is empty!\n");
|
||||||
free(tmp);
|
free(tmp);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return pcp_readz85string(input, bufsize);
|
return pcp_readz85string(ptx, input, bufsize);
|
||||||
}
|
}
|
||||||
|
|
||||||
char *pcp_readz85string(unsigned char *input, size_t bufsize) {
|
char *pcp_readz85string(PCPCTX *ptx, unsigned char *input, size_t bufsize) {
|
||||||
size_t i;
|
size_t i;
|
||||||
size_t MAXLINE = 1024;
|
size_t MAXLINE = 1024;
|
||||||
|
|
||||||
if(bufsize == 0) {
|
if(bufsize == 0) {
|
||||||
fatal("Input file is empty!\n");
|
fatal(ptx, "Input file is empty!\n");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(_buffer_is_binary(input, bufsize) > 0) {
|
if(_buffer_is_binary(input, bufsize) > 0) {
|
||||||
fatal("input is not z85 encoded and contains pure binary data");
|
fatal(ptx, "input is not z85 encoded and contains pure binary data");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -339,7 +339,7 @@ char *pcp_readz85string(unsigned char *input, size_t bufsize) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(buffer_size(z) == 0) {
|
if(buffer_size(z) == 0) {
|
||||||
fatal("empty z85 encoded string");
|
fatal(ptx, "empty z85 encoded string");
|
||||||
goto rferr;
|
goto rferr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ int pcpdecrypt(char *id, int useid, char *infile, char *outfile, char *passwd, i
|
|||||||
in = stdin;
|
in = stdin;
|
||||||
else {
|
else {
|
||||||
if((in = fopen(infile, "rb")) == NULL) {
|
if((in = fopen(infile, "rb")) == NULL) {
|
||||||
fatal("Could not open input file %s\n", infile);
|
fatal(ptx, "Could not open input file %s\n", infile);
|
||||||
goto errde3;
|
goto errde3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -43,7 +43,7 @@ int pcpdecrypt(char *id, int useid, char *infile, char *outfile, char *passwd, i
|
|||||||
out = stdout;
|
out = stdout;
|
||||||
else {
|
else {
|
||||||
if((out = fopen(outfile, "wb+")) == NULL) {
|
if((out = fopen(outfile, "wb+")) == NULL) {
|
||||||
fatal("Could not open output file %s\n", outfile);
|
fatal(ptx, "Could not open output file %s\n", outfile);
|
||||||
goto errde3;
|
goto errde3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -73,15 +73,15 @@ int pcpdecrypt(char *id, int useid, char *infile, char *outfile, char *passwd, i
|
|||||||
strncpy(passphrase, passwd, strlen(passwd));
|
strncpy(passphrase, passwd, strlen(passwd));
|
||||||
}
|
}
|
||||||
|
|
||||||
symkey = pcp_scrypt(passphrase, strlen(passphrase), salt, 90);
|
symkey = pcp_scrypt(ptx, passphrase, strlen(passphrase), salt, 90);
|
||||||
free(salt);
|
free(salt);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* asymetric mode */
|
/* asymetric mode */
|
||||||
if(useid) {
|
if(useid) {
|
||||||
HASH_FIND_STR(pcpkey_hash, id, secret);
|
secret = pcphash_keyexists(ptx, id);
|
||||||
if(secret == NULL) {
|
if(secret == NULL) {
|
||||||
fatal("Could not find a secret key with id 0x%s in vault %s!\n",
|
fatal(ptx, "Could not find a secret key with id 0x%s in vault %s!\n",
|
||||||
id, vault->filename);
|
id, vault->filename);
|
||||||
goto errde3;
|
goto errde3;
|
||||||
}
|
}
|
||||||
@@ -89,7 +89,7 @@ int pcpdecrypt(char *id, int useid, char *infile, char *outfile, char *passwd, i
|
|||||||
else {
|
else {
|
||||||
secret = pcp_find_primary_secret();
|
secret = pcp_find_primary_secret();
|
||||||
if(secret == NULL) {
|
if(secret == NULL) {
|
||||||
fatal("Could not find a secret key in vault %s!\n", id, vault->filename);
|
fatal(ptx, "Could not find a secret key in vault %s!\n", id, vault->filename);
|
||||||
goto errde3;
|
goto errde3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -105,21 +105,21 @@ int pcpdecrypt(char *id, int useid, char *infile, char *outfile, char *passwd, i
|
|||||||
strncpy(passphrase, passwd, strlen(passwd)+1);
|
strncpy(passphrase, passwd, strlen(passwd)+1);
|
||||||
}
|
}
|
||||||
|
|
||||||
secret = pcpkey_decrypt(secret, passphrase);
|
secret = pcpkey_decrypt(ptx, secret, passphrase);
|
||||||
if(secret == NULL)
|
if(secret == NULL)
|
||||||
goto errde3;
|
goto errde3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
fatal("Could not determine input file type\n");
|
fatal(ptx, "Could not determine input file type\n");
|
||||||
goto errde3;
|
goto errde3;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(symkey == NULL)
|
if(symkey == NULL)
|
||||||
dlen = pcp_decrypt_stream(pin, pout, secret, NULL, verify);
|
dlen = pcp_decrypt_stream(ptx, pin, pout, secret, NULL, verify);
|
||||||
else
|
else
|
||||||
dlen = pcp_decrypt_stream(pin, pout, NULL, symkey, verify);
|
dlen = pcp_decrypt_stream(ptx, pin, pout, NULL, symkey, verify);
|
||||||
|
|
||||||
ps_close(pin);
|
ps_close(pin);
|
||||||
ps_close(pout);
|
ps_close(pout);
|
||||||
@@ -164,23 +164,22 @@ int pcpencrypt(char *id, char *infile, char *outfile, char *passwd, plist_t *rec
|
|||||||
byte *salt = ucmalloc(90); /* FIXME: use random salt, concat it with result afterwards */
|
byte *salt = ucmalloc(90); /* FIXME: use random salt, concat it with result afterwards */
|
||||||
char stsalt[] = PBP_COMPAT_SALT;
|
char stsalt[] = PBP_COMPAT_SALT;
|
||||||
memcpy(salt, stsalt, 90);
|
memcpy(salt, stsalt, 90);
|
||||||
symkey = pcp_scrypt(passphrase, strlen(passphrase), salt, 90);
|
symkey = pcp_scrypt(ptx, passphrase, strlen(passphrase), salt, 90);
|
||||||
free(salt);
|
free(salt);
|
||||||
}
|
}
|
||||||
else if(id != NULL && recipient == NULL) {
|
else if(id != NULL && recipient == NULL) {
|
||||||
/* lookup by id */
|
/* lookup by id */
|
||||||
HASH_FIND_STR(pcppubkey_hash, id, tmp);
|
tmp = pcphash_pubkeyexists(ptx, id);
|
||||||
if(tmp == NULL) {
|
if(tmp == NULL) {
|
||||||
/* self-encryption: look if its a secret one */
|
/* self-encryption: look if its a secret one */
|
||||||
pcp_key_t *s = NULL;
|
pcp_key_t *s = pcphash_keyexists(ptx, id);
|
||||||
HASH_FIND_STR(pcpkey_hash, id, s);
|
|
||||||
if(s != NULL) {
|
if(s != NULL) {
|
||||||
tmp = pcpkey_pub_from_secret(s);
|
tmp = pcpkey_pub_from_secret(s);
|
||||||
HASH_ADD_STR( pubhash, id, tmp);
|
HASH_ADD_STR( pubhash, id, tmp);
|
||||||
self = 1;
|
self = 1;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
fatal("Could not find a public key with id 0x%s in vault %s!\n",
|
fatal(ptx, "Could not find a public key with id 0x%s in vault %s!\n",
|
||||||
id, vault->filename);
|
id, vault->filename);
|
||||||
goto erren3;
|
goto erren3;
|
||||||
}
|
}
|
||||||
@@ -197,7 +196,7 @@ int pcpencrypt(char *id, char *infile, char *outfile, char *passwd, plist_t *rec
|
|||||||
/* iterate through global hashlist */
|
/* iterate through global hashlist */
|
||||||
/* copy matches into temporary pubhash */
|
/* copy matches into temporary pubhash */
|
||||||
plist_t *rec;
|
plist_t *rec;
|
||||||
pcphash_iteratepub(tmp) {
|
pcphash_iteratepub(ptx, tmp) {
|
||||||
rec = recipient->first;
|
rec = recipient->first;
|
||||||
while (rec != NULL) {
|
while (rec != NULL) {
|
||||||
_lc(rec->value);
|
_lc(rec->value);
|
||||||
@@ -211,7 +210,7 @@ int pcpencrypt(char *id, char *infile, char *outfile, char *passwd, plist_t *rec
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(HASH_COUNT(pubhash) == 0) {
|
if(HASH_COUNT(pubhash) == 0) {
|
||||||
fatal("no matching key found for specified recipient(s)!\n");
|
fatal(ptx, "no matching key found for specified recipient(s)!\n");
|
||||||
goto erren3;
|
goto erren3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -224,7 +223,7 @@ int pcpencrypt(char *id, char *infile, char *outfile, char *passwd, plist_t *rec
|
|||||||
#else
|
#else
|
||||||
secret = pcp_find_primary_secret();
|
secret = pcp_find_primary_secret();
|
||||||
if(secret == NULL) {
|
if(secret == NULL) {
|
||||||
fatal("Could not find a secret key in vault %s!\n", id, vault->filename);
|
fatal(ptx, "Could not find a secret key in vault %s!\n", id, vault->filename);
|
||||||
goto erren2;
|
goto erren2;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -239,7 +238,7 @@ int pcpencrypt(char *id, char *infile, char *outfile, char *passwd, plist_t *rec
|
|||||||
passphrase = ucmalloc(strlen(passwd)+1);
|
passphrase = ucmalloc(strlen(passwd)+1);
|
||||||
strncpy(passphrase, passwd, strlen(passwd)+1);
|
strncpy(passphrase, passwd, strlen(passwd)+1);
|
||||||
}
|
}
|
||||||
secret = pcpkey_decrypt(secret, passphrase);
|
secret = pcpkey_decrypt(ptx, secret, passphrase);
|
||||||
if(secret == NULL)
|
if(secret == NULL)
|
||||||
goto erren2;
|
goto erren2;
|
||||||
}
|
}
|
||||||
@@ -250,7 +249,7 @@ int pcpencrypt(char *id, char *infile, char *outfile, char *passwd, plist_t *rec
|
|||||||
in = stdin;
|
in = stdin;
|
||||||
else {
|
else {
|
||||||
if((in = fopen(infile, "rb")) == NULL) {
|
if((in = fopen(infile, "rb")) == NULL) {
|
||||||
fatal("Could not open input file %s\n", infile);
|
fatal(ptx, "Could not open input file %s\n", infile);
|
||||||
goto erren2;
|
goto erren2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -259,7 +258,7 @@ int pcpencrypt(char *id, char *infile, char *outfile, char *passwd, plist_t *rec
|
|||||||
out = stdout;
|
out = stdout;
|
||||||
else {
|
else {
|
||||||
if((out = fopen(outfile, "wb+")) == NULL) {
|
if((out = fopen(outfile, "wb+")) == NULL) {
|
||||||
fatal("Could not open output file %s\n", outfile);
|
fatal(ptx, "Could not open output file %s\n", outfile);
|
||||||
goto erren2;
|
goto erren2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -275,9 +274,9 @@ int pcpencrypt(char *id, char *infile, char *outfile, char *passwd, plist_t *rec
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(self == 1)
|
if(self == 1)
|
||||||
clen = pcp_encrypt_stream_sym(pin, pout, symkey, 0, NULL);
|
clen = pcp_encrypt_stream_sym(ptx, pin, pout, symkey, 0, NULL);
|
||||||
else
|
else
|
||||||
clen = pcp_encrypt_stream(pin, pout, secret, pubhash, signcrypt);
|
clen = pcp_encrypt_stream(ptx, pin, pout, secret, pubhash, signcrypt);
|
||||||
|
|
||||||
if(armor == 1) {
|
if(armor == 1) {
|
||||||
ps_finish(pout);
|
ps_finish(pout);
|
||||||
@@ -296,11 +295,10 @@ int pcpencrypt(char *id, char *infile, char *outfile, char *passwd, plist_t *rec
|
|||||||
fprintf(stderr, "Encrypted %"FMT_SIZE_T" bytes for 0x%s successfully\n", (SIZE_T_CAST)clen, id);
|
fprintf(stderr, "Encrypted %"FMT_SIZE_T" bytes for 0x%s successfully\n", (SIZE_T_CAST)clen, id);
|
||||||
else {
|
else {
|
||||||
fprintf(stderr, "Encrypted %"FMT_SIZE_T" bytes for:\n", (SIZE_T_CAST)clen);
|
fprintf(stderr, "Encrypted %"FMT_SIZE_T" bytes for:\n", (SIZE_T_CAST)clen);
|
||||||
pcp_pubkey_t *cur, *t;
|
pcp_pubkey_t *cur;
|
||||||
HASH_ITER(hh, pubhash, cur, t) {
|
pcphash_iteratepub(ptx, cur) {
|
||||||
fprintf(stderr, "%s <%s>\n", cur->owner, cur->mail);
|
fprintf(stderr, "%s <%s>\n", cur->owner, cur->mail);
|
||||||
}
|
}
|
||||||
free(t);
|
|
||||||
free(cur);
|
free(cur);
|
||||||
}
|
}
|
||||||
if(signcrypt)
|
if(signcrypt)
|
||||||
|
|||||||
@@ -36,6 +36,7 @@
|
|||||||
#include "keyhash.h"
|
#include "keyhash.h"
|
||||||
#include "plist.h"
|
#include "plist.h"
|
||||||
#include "pcpstream.h"
|
#include "pcpstream.h"
|
||||||
|
#include "context.h"
|
||||||
|
|
||||||
int pcpdecrypt(char *id, int useid, char *infile, char *outfile, char *passwd, int verify);
|
int pcpdecrypt(char *id, int useid, char *infile, char *outfile, char *passwd, int verify);
|
||||||
int pcpencrypt(char *id, char *infile, char *outfile, char *passwd, plist_t *recipient, int signcrypt, int armor);
|
int pcpencrypt(char *id, char *infile, char *outfile, char *passwd, plist_t *recipient, int signcrypt, int armor);
|
||||||
|
|||||||
112
src/keymgmt.c
112
src/keymgmt.c
@@ -30,14 +30,14 @@ char *pcp_getstdin(const char *prompt) {
|
|||||||
fprintf(stderr, "%s: ", prompt);
|
fprintf(stderr, "%s: ", prompt);
|
||||||
|
|
||||||
if (fgets(line, 255, stdin) == NULL) {
|
if (fgets(line, 255, stdin) == NULL) {
|
||||||
fatal("Cannot read from stdin");
|
fatal(ptx, "Cannot read from stdin");
|
||||||
goto errgst;
|
goto errgst;
|
||||||
}
|
}
|
||||||
|
|
||||||
line[strcspn(line, "\r\n")] = '\0';
|
line[strcspn(line, "\r\n")] = '\0';
|
||||||
|
|
||||||
if ((out = strdup(line)) == NULL) {
|
if ((out = strdup(line)) == NULL) {
|
||||||
fatal("Cannot allocate memory");
|
fatal(ptx, "Cannot allocate memory");
|
||||||
goto errgst;
|
goto errgst;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -48,11 +48,11 @@ char *pcp_getstdin(const char *prompt) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int pcp_storekey (pcp_key_t *key) {
|
int pcp_storekey (pcp_key_t *key) {
|
||||||
if(vault->isnew == 1 || HASH_COUNT(pcpkey_hash) == 0) {
|
if(vault->isnew == 1 || pcphash_count(ptx) == 0) {
|
||||||
key->type = PCP_KEY_TYPE_MAINSECRET;
|
key->type = PCP_KEY_TYPE_MAINSECRET;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(pcpvault_addkey(vault, key, key->type) == 0) {
|
if(pcpvault_addkey(ptx, vault, key, key->type) == 0) {
|
||||||
if(vault->isnew)
|
if(vault->isnew)
|
||||||
fprintf(stderr, "new vault created, ");
|
fprintf(stderr, "new vault created, ");
|
||||||
fprintf(stderr, "key 0x%s added to %s.\n", key->id, vault->filename);
|
fprintf(stderr, "key 0x%s added to %s.\n", key->id, vault->filename);
|
||||||
@@ -87,7 +87,7 @@ void pcp_keygen(char *passwd) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(strnlen(passphrase, 1024) > 0)
|
if(strnlen(passphrase, 1024) > 0)
|
||||||
key = pcpkey_encrypt(k, passphrase);
|
key = pcpkey_encrypt(ptx, k, passphrase);
|
||||||
else {
|
else {
|
||||||
char *yes = pcp_getstdin("WARNING: secret key will be stored unencrypted. Are you sure [yes|NO]?");
|
char *yes = pcp_getstdin("WARNING: secret key will be stored unencrypted. Are you sure [yes|NO]?");
|
||||||
if(strncmp(yes, "yes", 1024) == 0)
|
if(strncmp(yes, "yes", 1024) == 0)
|
||||||
@@ -117,22 +117,22 @@ void pcp_keygen(char *passwd) {
|
|||||||
void pcp_listkeys() {
|
void pcp_listkeys() {
|
||||||
pcp_key_t *k;
|
pcp_key_t *k;
|
||||||
|
|
||||||
int nkeys = HASH_COUNT(pcpkey_hash) + HASH_COUNT(pcppubkey_hash);
|
int nkeys = pcphash_count(ptx) + pcphash_countpub(ptx);
|
||||||
|
|
||||||
if(nkeys > 0) {
|
if(nkeys > 0) {
|
||||||
printf("Key ID Type Creation Time Owner\n");
|
printf("Key ID Type Creation Time Owner\n");
|
||||||
|
|
||||||
pcphash_iterate(k) {
|
pcphash_iterate(ptx, k) {
|
||||||
pcpkey_printlineinfo(k);
|
pcpkey_printlineinfo(k);
|
||||||
}
|
}
|
||||||
|
|
||||||
pcp_pubkey_t *p;
|
pcp_pubkey_t *p;
|
||||||
pcphash_iteratepub(p) {
|
pcphash_iteratepub(ptx, p) {
|
||||||
pcppubkey_printlineinfo(p);
|
pcppubkey_printlineinfo(p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
fatal("The key vault file %s doesn't contain any keys so far.\n", vault->filename);
|
fatal(ptx, "The key vault file %s doesn't contain any keys so far.\n", vault->filename);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -145,12 +145,12 @@ char *pcp_normalize_id(char *keyid) {
|
|||||||
memcpy(id, keyid, 17);
|
memcpy(id, keyid, 17);
|
||||||
}
|
}
|
||||||
else if(len < 16) {
|
else if(len < 16) {
|
||||||
fatal("Specified key id %s is too short!\n", keyid);
|
fatal(ptx, "Specified key id %s is too short!\n", keyid);
|
||||||
free(id);
|
free(id);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
else if(len > 18) {
|
else if(len > 18) {
|
||||||
fatal("Specified key id %s is too long!\n", keyid);
|
fatal(ptx, "Specified key id %s is too long!\n", keyid);
|
||||||
free(id);
|
free(id);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -163,7 +163,7 @@ char *pcp_normalize_id(char *keyid) {
|
|||||||
id[16] = 0;
|
id[16] = 0;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
fatal("Specified key id %s is too long!\n", keyid);
|
fatal(ptx, "Specified key id %s is too long!\n", keyid);
|
||||||
free(id);
|
free(id);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -175,7 +175,7 @@ char *pcp_normalize_id(char *keyid) {
|
|||||||
pcp_key_t *pcp_find_primary_secret() {
|
pcp_key_t *pcp_find_primary_secret() {
|
||||||
pcp_key_t *key = NULL;
|
pcp_key_t *key = NULL;
|
||||||
pcp_key_t *k;
|
pcp_key_t *k;
|
||||||
pcphash_iterate(k) {
|
pcphash_iterate(ptx, k) {
|
||||||
if(k->type == PCP_KEY_TYPE_MAINSECRET) {
|
if(k->type == PCP_KEY_TYPE_MAINSECRET) {
|
||||||
key = ucmalloc(sizeof(pcp_key_t));
|
key = ucmalloc(sizeof(pcp_key_t));
|
||||||
memcpy(key, k, sizeof(pcp_key_t));
|
memcpy(key, k, sizeof(pcp_key_t));
|
||||||
@@ -184,9 +184,9 @@ pcp_key_t *pcp_find_primary_secret() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* no primary? whoops */
|
/* no primary? whoops */
|
||||||
int nkeys = HASH_COUNT(pcpkey_hash);
|
int nkeys = pcphash_count(ptx);
|
||||||
if(nkeys == 1) {
|
if(nkeys == 1) {
|
||||||
pcphash_iterate(k) {
|
pcphash_iterate(ptx, k) {
|
||||||
key = ucmalloc(sizeof(pcp_key_t));
|
key = ucmalloc(sizeof(pcp_key_t));
|
||||||
memcpy(key, k, sizeof(pcp_key_t));
|
memcpy(key, k, sizeof(pcp_key_t));
|
||||||
return key;
|
return key;
|
||||||
@@ -201,9 +201,9 @@ void pcp_exportsecret(char *keyid, int useid, char *outfile, int armor, char *pa
|
|||||||
|
|
||||||
if(useid == 1) {
|
if(useid == 1) {
|
||||||
/* look if we've got that one */
|
/* look if we've got that one */
|
||||||
HASH_FIND_STR(pcpkey_hash, keyid, key);
|
key = pcphash_keyexists(ptx, keyid);
|
||||||
if(key == NULL) {
|
if(key == NULL) {
|
||||||
fatal("Could not find a secret key with id 0x%s in vault %s!\n", keyid, vault->filename);
|
fatal(ptx, "Could not find a secret key with id 0x%s in vault %s!\n", keyid, vault->filename);
|
||||||
goto errexpse1;
|
goto errexpse1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -211,7 +211,7 @@ void pcp_exportsecret(char *keyid, int useid, char *outfile, int armor, char *pa
|
|||||||
/* look for our primary key */
|
/* look for our primary key */
|
||||||
key = pcp_find_primary_secret();
|
key = pcp_find_primary_secret();
|
||||||
if(key == NULL) {
|
if(key == NULL) {
|
||||||
fatal("There's no primary secret key in the vault %s!\n", vault->filename);
|
fatal(ptx, "There's no primary secret key in the vault %s!\n", vault->filename);
|
||||||
goto errexpse1;
|
goto errexpse1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -222,7 +222,7 @@ void pcp_exportsecret(char *keyid, int useid, char *outfile, int armor, char *pa
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if((out = fopen(outfile, "wb+")) == NULL) {
|
if((out = fopen(outfile, "wb+")) == NULL) {
|
||||||
fatal("Could not create output file %s", outfile);
|
fatal(ptx, "Could not create output file %s", outfile);
|
||||||
goto errexpse1;
|
goto errexpse1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -237,7 +237,7 @@ void pcp_exportsecret(char *keyid, int useid, char *outfile, int armor, char *pa
|
|||||||
char *passphrase;
|
char *passphrase;
|
||||||
pcp_readpass(&passphrase,
|
pcp_readpass(&passphrase,
|
||||||
"Enter passphrase to decrypt your secret key", NULL, 1);
|
"Enter passphrase to decrypt your secret key", NULL, 1);
|
||||||
key = pcpkey_decrypt(key, passphrase);
|
key = pcpkey_decrypt(ptx, key, passphrase);
|
||||||
if(key == NULL) {
|
if(key == NULL) {
|
||||||
memset(passphrase, 0, strlen(passphrase));
|
memset(passphrase, 0, strlen(passphrase));
|
||||||
free(passphrase);
|
free(passphrase);
|
||||||
@@ -247,7 +247,7 @@ void pcp_exportsecret(char *keyid, int useid, char *outfile, int armor, char *pa
|
|||||||
free(passphrase);
|
free(passphrase);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
key = pcpkey_decrypt(key, passwd);
|
key = pcpkey_decrypt(ptx, key, passwd);
|
||||||
if(key == NULL) {
|
if(key == NULL) {
|
||||||
goto errexpse1;
|
goto errexpse1;
|
||||||
}
|
}
|
||||||
@@ -257,13 +257,13 @@ void pcp_exportsecret(char *keyid, int useid, char *outfile, int armor, char *pa
|
|||||||
Buffer *exported_sk;
|
Buffer *exported_sk;
|
||||||
|
|
||||||
if(passwd != NULL) {
|
if(passwd != NULL) {
|
||||||
exported_sk = pcp_export_secret(key, passwd);
|
exported_sk = pcp_export_secret(ptx, key, passwd);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
char *passphrase;
|
char *passphrase;
|
||||||
pcp_readpass(&passphrase,
|
pcp_readpass(&passphrase,
|
||||||
"Enter passphrase to encrypt the exported secret key", "Repeat passphrase", 1);
|
"Enter passphrase to encrypt the exported secret key", "Repeat passphrase", 1);
|
||||||
exported_sk = pcp_export_secret(key, passphrase);
|
exported_sk = pcp_export_secret(ptx, key, passphrase);
|
||||||
memset(passphrase, 0, strlen(passphrase));
|
memset(passphrase, 0, strlen(passphrase));
|
||||||
free(passphrase);
|
free(passphrase);
|
||||||
}
|
}
|
||||||
@@ -307,19 +307,19 @@ void pcp_exportpublic(char *keyid, char *passwd, char *outfile, int format, int
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if((out = fopen(outfile, "wb+")) == NULL) {
|
if((out = fopen(outfile, "wb+")) == NULL) {
|
||||||
fatal("Could not create output file %s", outfile);
|
fatal(ptx, "Could not create output file %s", outfile);
|
||||||
goto errpcpexpu1;
|
goto errpcpexpu1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(keyid != NULL) {
|
if(keyid != NULL) {
|
||||||
/* keyid specified, check if it exists and if yes, what type it is */
|
/* keyid specified, check if it exists and if yes, what type it is */
|
||||||
HASH_FIND_STR(pcppubkey_hash, keyid, pk);
|
pk = pcphash_pubkeyexists(ptx, keyid);
|
||||||
if(pk == NULL) {
|
if(pk == NULL) {
|
||||||
/* ok, so, then look for a secret key with that id */
|
/* ok, so, then look for a secret key with that id */
|
||||||
HASH_FIND_STR(pcpkey_hash, keyid, sk);
|
sk = pcphash_keyexists(ptx, keyid);
|
||||||
if(sk == NULL) {
|
if(sk == NULL) {
|
||||||
fatal("Could not find a key with id 0x%s in vault %s!\n",
|
fatal(ptx, "Could not find a key with id 0x%s in vault %s!\n",
|
||||||
keyid, vault->filename);
|
keyid, vault->filename);
|
||||||
goto errpcpexpu1;
|
goto errpcpexpu1;
|
||||||
}
|
}
|
||||||
@@ -337,7 +337,7 @@ void pcp_exportpublic(char *keyid, char *passwd, char *outfile, int format, int
|
|||||||
/* we use our primary key anyway */
|
/* we use our primary key anyway */
|
||||||
sk = pcp_find_primary_secret();
|
sk = pcp_find_primary_secret();
|
||||||
if(sk == NULL) {
|
if(sk == NULL) {
|
||||||
fatal("There's no primary secret key in the vault %s!\n", vault->filename);
|
fatal(ptx, "There's no primary secret key in the vault %s!\n", vault->filename);
|
||||||
goto errpcpexpu1;
|
goto errpcpexpu1;
|
||||||
}
|
}
|
||||||
is_foreign = 0;
|
is_foreign = 0;
|
||||||
@@ -347,13 +347,13 @@ void pcp_exportpublic(char *keyid, char *passwd, char *outfile, int format, int
|
|||||||
if(is_foreign == 0 && sk->secret[0] == 0 && format <= EXP_FORMAT_PBP) {
|
if(is_foreign == 0 && sk->secret[0] == 0 && format <= EXP_FORMAT_PBP) {
|
||||||
/* decrypt the secret key */
|
/* decrypt the secret key */
|
||||||
if(passwd != NULL) {
|
if(passwd != NULL) {
|
||||||
sk = pcpkey_decrypt(sk, passwd);
|
sk = pcpkey_decrypt(ptx, sk, passwd);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
char *passphrase;
|
char *passphrase;
|
||||||
pcp_readpass(&passphrase,
|
pcp_readpass(&passphrase,
|
||||||
"Enter passphrase to decrypt your secret key", NULL, 1);
|
"Enter passphrase to decrypt your secret key", NULL, 1);
|
||||||
sk = pcpkey_decrypt(sk, passphrase);
|
sk = pcpkey_decrypt(ptx, sk, passphrase);
|
||||||
memset(passphrase, 0, strlen(passphrase));
|
memset(passphrase, 0, strlen(passphrase));
|
||||||
free(passphrase);
|
free(passphrase);
|
||||||
}
|
}
|
||||||
@@ -381,7 +381,7 @@ void pcp_exportpublic(char *keyid, char *passwd, char *outfile, int format, int
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* FIXME: export foreign keys unsupported yet */
|
/* FIXME: export foreign keys unsupported yet */
|
||||||
fatal("Exporting foreign public keys in native format unsupported yet");
|
fatal(ptx, "Exporting foreign public keys in native format unsupported yet");
|
||||||
goto errpcpexpu1;
|
goto errpcpexpu1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -399,7 +399,7 @@ void pcp_exportpublic(char *keyid, char *passwd, char *outfile, int format, int
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
fatal("Exporting foreign public keys in PBP format not possible");
|
fatal(ptx, "Exporting foreign public keys in PBP format not possible");
|
||||||
goto errpcpexpu1;
|
goto errpcpexpu1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -429,38 +429,38 @@ void pcp_exportpublic(char *keyid, char *passwd, char *outfile, int format, int
|
|||||||
|
|
||||||
|
|
||||||
void pcpdelete_key(char *keyid) {
|
void pcpdelete_key(char *keyid) {
|
||||||
pcp_pubkey_t *p = pcphash_pubkeyexists(keyid);
|
pcp_pubkey_t *p = pcphash_pubkeyexists(ptx, keyid);
|
||||||
|
|
||||||
if(p != NULL) {
|
if(p != NULL) {
|
||||||
/* delete public */
|
/* delete public */
|
||||||
HASH_DEL(pcppubkey_hash, p);
|
pcphash_del(ptx, p, p->type);
|
||||||
free(p);
|
free(p);
|
||||||
vault->unsafed = 1;
|
vault->unsafed = 1;
|
||||||
fprintf(stderr, "Public key deleted.\n");
|
fprintf(stderr, "Public key deleted.\n");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
pcp_key_t *s = pcphash_keyexists(keyid);
|
pcp_key_t *s = pcphash_keyexists(ptx, keyid);
|
||||||
if(s != NULL) {
|
if(s != NULL) {
|
||||||
/* delete secret */
|
/* delete secret */
|
||||||
HASH_DEL(pcpkey_hash, s);
|
pcphash_del(ptx, s, s->type);
|
||||||
free(s);
|
free(s);
|
||||||
vault->unsafed = 1;
|
vault->unsafed = 1;
|
||||||
fprintf(stderr, "Secret key deleted.\n");
|
fprintf(stderr, "Secret key deleted.\n");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
fatal("No key with id 0x%s found!\n", keyid);
|
fatal(ptx, "No key with id 0x%s found!\n", keyid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void pcpedit_key(char *keyid) {
|
void pcpedit_key(char *keyid) {
|
||||||
pcp_key_t *key = pcphash_keyexists(keyid);
|
pcp_key_t *key = pcphash_keyexists(ptx, keyid);
|
||||||
|
|
||||||
if(key != NULL) {
|
if(key != NULL) {
|
||||||
if(key->secret[0] == 0) {
|
if(key->secret[0] == 0) {
|
||||||
char *passphrase;
|
char *passphrase;
|
||||||
pcp_readpass(&passphrase, "Enter passphrase to decrypt the key", NULL, 1);
|
pcp_readpass(&passphrase, "Enter passphrase to decrypt the key", NULL, 1);
|
||||||
key = pcpkey_decrypt(key, passphrase);
|
key = pcpkey_decrypt(ptx, key, passphrase);
|
||||||
ucfree(passphrase, strlen(passphrase));
|
ucfree(passphrase, strlen(passphrase));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -481,7 +481,7 @@ void pcpedit_key(char *keyid) {
|
|||||||
if(key->type != PCP_KEY_TYPE_MAINSECRET) {
|
if(key->type != PCP_KEY_TYPE_MAINSECRET) {
|
||||||
pcp_key_t *other = NULL;
|
pcp_key_t *other = NULL;
|
||||||
uint8_t haveprimary = 0;
|
uint8_t haveprimary = 0;
|
||||||
pcphash_iterate(other) {
|
pcphash_iterate(ptx, other) {
|
||||||
if(other->type == PCP_KEY_TYPE_MAINSECRET) {
|
if(other->type == PCP_KEY_TYPE_MAINSECRET) {
|
||||||
haveprimary = 1;
|
haveprimary = 1;
|
||||||
break;
|
break;
|
||||||
@@ -515,7 +515,7 @@ void pcpedit_key(char *keyid) {
|
|||||||
"Enter the passphrase again", 1);
|
"Enter the passphrase again", 1);
|
||||||
|
|
||||||
if(strnlen(passphrase, 1024) > 0) {
|
if(strnlen(passphrase, 1024) > 0) {
|
||||||
key = pcpkey_encrypt(key, passphrase);
|
key = pcpkey_encrypt(ptx, key, passphrase);
|
||||||
ucfree(passphrase, strlen(passphrase));
|
ucfree(passphrase, strlen(passphrase));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -529,7 +529,7 @@ void pcpedit_key(char *keyid) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
fatal("No key with id 0x%s found!\n", keyid);
|
fatal(ptx, "No key with id 0x%s found!\n", keyid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -538,7 +538,7 @@ char *pcp_find_id_byrec(char *recipient) {
|
|||||||
pcp_pubkey_t *p;
|
pcp_pubkey_t *p;
|
||||||
char *id = NULL;
|
char *id = NULL;
|
||||||
_lc(recipient);
|
_lc(recipient);
|
||||||
pcphash_iteratepub(p) {
|
pcphash_iteratepub(ptx, p) {
|
||||||
if(strncmp(p->owner, recipient, 255) == 0) {
|
if(strncmp(p->owner, recipient, 255) == 0) {
|
||||||
id = ucmalloc(17);
|
id = ucmalloc(17);
|
||||||
strncpy(id, p->id, 17);
|
strncpy(id, p->id, 17);
|
||||||
@@ -569,12 +569,12 @@ int pcp_import (vault_t *vault, FILE *in, char *passwd) {
|
|||||||
bufsize = ps_read(pin, buf, PCP_BLOCK_SIZE);
|
bufsize = ps_read(pin, buf, PCP_BLOCK_SIZE);
|
||||||
|
|
||||||
if(bufsize == 0) {
|
if(bufsize == 0) {
|
||||||
fatal("Input file is empty!\n");
|
fatal(ptx, "Input file is empty!\n");
|
||||||
goto errimp1;
|
goto errimp1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* first try as rfc pub key */
|
/* first try as rfc pub key */
|
||||||
bundle = pcp_import_binpub(buf, bufsize);
|
bundle = pcp_import_binpub(ptx, buf, bufsize);
|
||||||
if(bundle != NULL) {
|
if(bundle != NULL) {
|
||||||
keysig = bundle->s;
|
keysig = bundle->s;
|
||||||
pub = bundle->p;
|
pub = bundle->p;
|
||||||
@@ -583,7 +583,7 @@ int pcp_import (vault_t *vault, FILE *in, char *passwd) {
|
|||||||
pcp_dumppubkey(pub);
|
pcp_dumppubkey(pub);
|
||||||
|
|
||||||
if(keysig == NULL) {
|
if(keysig == NULL) {
|
||||||
fatals_ifany();
|
fatals_ifany(ptx);
|
||||||
char *yes = pcp_getstdin("WARNING: signature doesn't verify, import anyway [yes|NO]?");
|
char *yes = pcp_getstdin("WARNING: signature doesn't verify, import anyway [yes|NO]?");
|
||||||
if(strncmp(yes, "yes", 1024) != 0) {
|
if(strncmp(yes, "yes", 1024) != 0) {
|
||||||
free(yes);
|
free(yes);
|
||||||
@@ -592,8 +592,8 @@ int pcp_import (vault_t *vault, FILE *in, char *passwd) {
|
|||||||
free(yes);
|
free(yes);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(pcp_sanitycheck_pub(pub) == 0) {
|
if(pcp_sanitycheck_pub(ptx, pub) == 0) {
|
||||||
if(pcpvault_addkey(vault, (void *)pub, PCP_KEY_TYPE_PUBLIC) == 0) {
|
if(pcpvault_addkey(ptx, vault, (void *)pub, PCP_KEY_TYPE_PUBLIC) == 0) {
|
||||||
fprintf(stderr, "key 0x%s added to %s.\n", pub->id, vault->filename);
|
fprintf(stderr, "key 0x%s added to %s.\n", pub->id, vault->filename);
|
||||||
/* avoid double free */
|
/* avoid double free */
|
||||||
pub = NULL;
|
pub = NULL;
|
||||||
@@ -603,7 +603,7 @@ int pcp_import (vault_t *vault, FILE *in, char *passwd) {
|
|||||||
goto errimp2;
|
goto errimp2;
|
||||||
|
|
||||||
if(keysig != NULL) {
|
if(keysig != NULL) {
|
||||||
if(pcpvault_addkey(vault, keysig, keysig->type) != 0) {
|
if(pcpvault_addkey(ptx, vault, keysig, keysig->type) != 0) {
|
||||||
/* FIXME: remove pubkey if storing the keysig failed */
|
/* FIXME: remove pubkey if storing the keysig failed */
|
||||||
goto errimp2;
|
goto errimp2;
|
||||||
}
|
}
|
||||||
@@ -616,13 +616,13 @@ int pcp_import (vault_t *vault, FILE *in, char *passwd) {
|
|||||||
else {
|
else {
|
||||||
/* it's not public key, so let's try to interpret it as secret key */
|
/* it's not public key, so let's try to interpret it as secret key */
|
||||||
if(passwd != NULL) {
|
if(passwd != NULL) {
|
||||||
sk = pcp_import_secret(buf, bufsize, passwd);
|
sk = pcp_import_secret(ptx, buf, bufsize, passwd);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
char *passphrase;
|
char *passphrase;
|
||||||
pcp_readpass(&passphrase,
|
pcp_readpass(&passphrase,
|
||||||
"Enter passphrase to decrypt the secret key file", NULL, 1);
|
"Enter passphrase to decrypt the secret key file", NULL, 1);
|
||||||
sk = pcp_import_secret(buf, bufsize, passphrase);
|
sk = pcp_import_secret(ptx, buf, bufsize, passphrase);
|
||||||
ucfree(passphrase, strlen(passphrase));
|
ucfree(passphrase, strlen(passphrase));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -633,15 +633,15 @@ int pcp_import (vault_t *vault, FILE *in, char *passwd) {
|
|||||||
if(debug)
|
if(debug)
|
||||||
pcp_dumpkey(sk);
|
pcp_dumpkey(sk);
|
||||||
|
|
||||||
pcp_key_t *maybe = pcphash_keyexists(sk->id);
|
pcp_key_t *maybe = pcphash_keyexists(ptx, sk->id);
|
||||||
if(maybe != NULL) {
|
if(maybe != NULL) {
|
||||||
fatal("Secretkey sanity check: there already exists a key with the id 0x%s\n", sk->id);
|
fatal(ptx, "Secretkey sanity check: there already exists a key with the id 0x%s\n", sk->id);
|
||||||
goto errimp2;
|
goto errimp2;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* store it */
|
/* store it */
|
||||||
if(passwd != NULL) {
|
if(passwd != NULL) {
|
||||||
sk = pcpkey_encrypt(sk, passwd);
|
sk = pcpkey_encrypt(ptx, sk, passwd);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
char *passphrase;
|
char *passphrase;
|
||||||
@@ -651,7 +651,7 @@ int pcp_import (vault_t *vault, FILE *in, char *passwd) {
|
|||||||
|
|
||||||
if(strnlen(passphrase, 1024) > 0) {
|
if(strnlen(passphrase, 1024) > 0) {
|
||||||
/* encrypt the key */
|
/* encrypt the key */
|
||||||
sk = pcpkey_encrypt(sk, passphrase);
|
sk = pcpkey_encrypt(ptx, sk, passphrase);
|
||||||
ucfree(passphrase, strlen(passphrase));
|
ucfree(passphrase, strlen(passphrase));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -668,7 +668,7 @@ int pcp_import (vault_t *vault, FILE *in, char *passwd) {
|
|||||||
|
|
||||||
if(sk != NULL) {
|
if(sk != NULL) {
|
||||||
/* store it to the vault if we got it til here */
|
/* store it to the vault if we got it til here */
|
||||||
if(pcp_sanitycheck_key(sk) == 0) {
|
if(pcp_sanitycheck_key(ptx, sk) == 0) {
|
||||||
if(pcp_storekey(sk) == 0) {
|
if(pcp_storekey(sk) == 0) {
|
||||||
pcpkey_printshortinfo(sk);
|
pcpkey_printshortinfo(sk);
|
||||||
success = 0;
|
success = 0;
|
||||||
|
|||||||
@@ -42,6 +42,7 @@
|
|||||||
#include "base85.h"
|
#include "base85.h"
|
||||||
#include "buffer.h"
|
#include "buffer.h"
|
||||||
#include "mgmt.h"
|
#include "mgmt.h"
|
||||||
|
#include "context.h"
|
||||||
|
|
||||||
#define _WITH_GETLINE
|
#define _WITH_GETLINE
|
||||||
|
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ int pcptext_infile(char *infile) {
|
|||||||
int insize;
|
int insize;
|
||||||
|
|
||||||
if((in = fopen(infile, "rb")) == NULL) {
|
if((in = fopen(infile, "rb")) == NULL) {
|
||||||
fatal("Could not open input file %s\n", infile);
|
fatal(ptx, "Could not open input file %s\n", infile);
|
||||||
goto errtinf1;
|
goto errtinf1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -42,7 +42,7 @@ int pcptext_infile(char *infile) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* maybe a vault? */
|
/* maybe a vault? */
|
||||||
vault_t *v = pcpvault_init(infile);
|
vault_t *v = pcpvault_init(ptx, infile);
|
||||||
if(v != NULL) {
|
if(v != NULL) {
|
||||||
fprintf(stdout, "%s is a vault file\n", infile);
|
fprintf(stdout, "%s is a vault file\n", infile);
|
||||||
pcptext_vault(v);
|
pcptext_vault(v);
|
||||||
@@ -50,14 +50,14 @@ int pcptext_infile(char *infile) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* try z85ing it */
|
/* try z85ing it */
|
||||||
char *z85 = pcp_readz85file(in);
|
char *z85 = pcp_readz85file(ptx, in);
|
||||||
if(z85 == NULL) {
|
if(z85 == NULL) {
|
||||||
fprintf(stdout, "Can't handle %s - unknown file type.\n", infile);
|
fprintf(stdout, "Can't handle %s - unknown file type.\n", infile);
|
||||||
goto errtinf1;
|
goto errtinf1;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t clen;
|
size_t clen;
|
||||||
byte *bin = pcp_z85_decode((char *)z85, &clen);
|
byte *bin = pcp_z85_decode(ptx, (char *)z85, &clen);
|
||||||
free(z85);
|
free(z85);
|
||||||
|
|
||||||
if(bin == NULL) {
|
if(bin == NULL) {
|
||||||
@@ -71,31 +71,31 @@ int pcptext_infile(char *infile) {
|
|||||||
fprintf(stdout, "%s looks Z85 encoded but otherwise unknown and is possibly encrypted.\n", infile);
|
fprintf(stdout, "%s looks Z85 encoded but otherwise unknown and is possibly encrypted.\n", infile);
|
||||||
|
|
||||||
tdone:
|
tdone:
|
||||||
fatals_reset();
|
fatals_reset(ptx);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
errtinf1:
|
errtinf1:
|
||||||
fatals_reset();
|
fatals_reset(ptx);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void pcptext_key(char *keyid) {
|
void pcptext_key(char *keyid) {
|
||||||
pcp_key_t *s = pcphash_keyexists(keyid);
|
pcp_key_t *s = pcphash_keyexists(ptx, keyid);
|
||||||
if(s != NULL) {
|
if(s != NULL) {
|
||||||
if(debug)
|
if(debug)
|
||||||
pcp_dumpkey(s);
|
pcp_dumpkey(s);
|
||||||
pcpkey_print(s, stdout);
|
pcpkey_print(s, stdout);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
pcp_pubkey_t *p = pcphash_pubkeyexists(keyid);
|
pcp_pubkey_t *p = pcphash_pubkeyexists(ptx, keyid);
|
||||||
if(p != NULL) {
|
if(p != NULL) {
|
||||||
if(debug)
|
if(debug)
|
||||||
pcp_dumppubkey(p);
|
pcp_dumppubkey(p);
|
||||||
pcppubkey_print(p, stdout);
|
pcppubkey_print(p, stdout);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
fatal("No key with id 0x%s found!\n", keyid);
|
fatal(ptx, "No key with id 0x%s found!\n", keyid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -113,8 +113,8 @@ void pcptext_vault(vault_t *vault) {
|
|||||||
printf("%02X", vault->checksum[31]);
|
printf("%02X", vault->checksum[31]);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
|
||||||
printf(" Secret keys: %d\n", HASH_COUNT(pcpkey_hash));
|
printf(" Secret keys: %d\n", pcphash_count(ptx));
|
||||||
printf(" Public keys: %d\n", HASH_COUNT(pcppubkey_hash));
|
printf(" Public keys: %d\n", pcphash_countpub(ptx) );
|
||||||
}
|
}
|
||||||
|
|
||||||
void pcpkey_printlineinfo(pcp_key_t *key) {
|
void pcpkey_printlineinfo(pcp_key_t *key) {
|
||||||
@@ -128,7 +128,7 @@ void pcpkey_printlineinfo(pcp_key_t *key) {
|
|||||||
c->tm_hour, c->tm_min, c->tm_sec,
|
c->tm_hour, c->tm_min, c->tm_sec,
|
||||||
key->owner, key->mail);
|
key->owner, key->mail);
|
||||||
|
|
||||||
if(PCPVERBOSE) {
|
if(ptx->verbose) {
|
||||||
printf(" ");
|
printf(" ");
|
||||||
byte *hash = pcpkey_getchecksum(key);
|
byte *hash = pcpkey_getchecksum(key);
|
||||||
int i, y;
|
int i, y;
|
||||||
@@ -157,7 +157,7 @@ void pcppubkey_printlineinfo(pcp_pubkey_t *key) {
|
|||||||
c->tm_hour, c->tm_min, c->tm_sec,
|
c->tm_hour, c->tm_min, c->tm_sec,
|
||||||
key->owner, key->mail);
|
key->owner, key->mail);
|
||||||
|
|
||||||
if(PCPVERBOSE) {
|
if(ptx->verbose) {
|
||||||
printf(" ");
|
printf(" ");
|
||||||
byte *hash = pcppubkey_getchecksum(key);
|
byte *hash = pcppubkey_getchecksum(key);
|
||||||
int i, y;
|
int i, y;
|
||||||
@@ -171,7 +171,7 @@ void pcppubkey_printlineinfo(pcp_pubkey_t *key) {
|
|||||||
printf("\n signed: %s, serial: %08x, version: %d, ",
|
printf("\n signed: %s, serial: %08x, version: %d, ",
|
||||||
(key->valid == 1) ? "yes" : " no",
|
(key->valid == 1) ? "yes" : " no",
|
||||||
key->serial, (int)key->version);
|
key->serial, (int)key->version);
|
||||||
pcp_keysig_t *sig = pcphash_keysigexists(key->id);
|
pcp_keysig_t *sig = pcphash_keysigexists(ptx, key->id);
|
||||||
if(sig != NULL) {
|
if(sig != NULL) {
|
||||||
printf("signature fingerprint:\n ");
|
printf("signature fingerprint:\n ");
|
||||||
byte *checksum = sig->checksum;
|
byte *checksum = sig->checksum;
|
||||||
@@ -305,7 +305,7 @@ void pcpexport_yaml(char *outfile) {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if((out = fopen(outfile, "wb+")) == NULL) {
|
if((out = fopen(outfile, "wb+")) == NULL) {
|
||||||
fatal("Could not create output file %s", outfile);
|
fatal(ptx, "Could not create output file %s", outfile);
|
||||||
out = NULL;
|
out = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -325,7 +325,7 @@ void pcpexport_yaml(char *outfile) {
|
|||||||
fprintf(out, "---\n");
|
fprintf(out, "---\n");
|
||||||
fprintf(out, "secret-keys:\n");
|
fprintf(out, "secret-keys:\n");
|
||||||
|
|
||||||
pcphash_iterate(s) {
|
pcphash_iterate(ptx, s) {
|
||||||
fprintf(out, " -\n");
|
fprintf(out, " -\n");
|
||||||
fprintf(out, " id: %s\n", s->id);
|
fprintf(out, " id: %s\n", s->id);
|
||||||
fprintf(out, " owner: %s\n", s->owner);
|
fprintf(out, " owner: %s\n", s->owner);
|
||||||
@@ -350,7 +350,7 @@ void pcpexport_yaml(char *outfile) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fprintf(out, "public-keys:\n");
|
fprintf(out, "public-keys:\n");
|
||||||
pcphash_iteratepub(p) {
|
pcphash_iteratepub(ptx, p) {
|
||||||
fprintf(out, " -\n");
|
fprintf(out, " -\n");
|
||||||
fprintf(out, " id: %s\n", p->id);
|
fprintf(out, " id: %s\n", p->id);
|
||||||
fprintf(out, " owner: %s\n", p->owner);
|
fprintf(out, " owner: %s\n", p->owner);
|
||||||
|
|||||||
@@ -30,6 +30,7 @@
|
|||||||
#include "keymgmt.h"
|
#include "keymgmt.h"
|
||||||
#include "keyhash.h"
|
#include "keyhash.h"
|
||||||
#include "base85.h"
|
#include "base85.h"
|
||||||
|
#include "context.h"
|
||||||
|
|
||||||
void pcpkey_print(pcp_key_t *key, FILE *out);
|
void pcpkey_print(pcp_key_t *key, FILE *out);
|
||||||
void pcppubkey_print(pcp_pubkey_t *key, FILE *out);
|
void pcppubkey_print(pcp_pubkey_t *key, FILE *out);
|
||||||
|
|||||||
40
src/pcp.c
40
src/pcp.c
@@ -58,7 +58,6 @@ int main (int argc, char **argv) {
|
|||||||
plist_t *recipient = NULL;
|
plist_t *recipient = NULL;
|
||||||
FILE *in;
|
FILE *in;
|
||||||
|
|
||||||
PCP_EXIT = 0;
|
|
||||||
errno = 0;
|
errno = 0;
|
||||||
debug = 0;
|
debug = 0;
|
||||||
mode = 0;
|
mode = 0;
|
||||||
@@ -71,7 +70,7 @@ int main (int argc, char **argv) {
|
|||||||
signcrypt = 0;
|
signcrypt = 0;
|
||||||
exportformat = EXP_FORMAT_NATIVE;
|
exportformat = EXP_FORMAT_NATIVE;
|
||||||
|
|
||||||
PCPVERBOSE = 0;
|
ptx = ptx_new();
|
||||||
|
|
||||||
static struct option longopts[] = {
|
static struct option longopts[] = {
|
||||||
/* generics */
|
/* generics */
|
||||||
@@ -138,7 +137,7 @@ int main (int argc, char **argv) {
|
|||||||
usevault = 1;
|
usevault = 1;
|
||||||
break;
|
break;
|
||||||
case 'L':
|
case 'L':
|
||||||
PCPVERBOSE = 1; /* no break by purpose, turn on -l */
|
ptx->verbose = 1; /* no break by purpose, turn on -l */
|
||||||
case 'l':
|
case 'l':
|
||||||
mode += PCP_MODE_LISTKEYS;
|
mode += PCP_MODE_LISTKEYS;
|
||||||
usevault = 1;
|
usevault = 1;
|
||||||
@@ -268,7 +267,7 @@ int main (int argc, char **argv) {
|
|||||||
case '0':
|
case '0':
|
||||||
version();
|
version();
|
||||||
case 'v':
|
case 'v':
|
||||||
PCPVERBOSE = 1;
|
ptx->verbose = 1;
|
||||||
break;
|
break;
|
||||||
case 'h':
|
case 'h':
|
||||||
usage(0);
|
usage(0);
|
||||||
@@ -280,7 +279,6 @@ int main (int argc, char **argv) {
|
|||||||
argc -= optind;
|
argc -= optind;
|
||||||
argv += optind;
|
argv += optind;
|
||||||
|
|
||||||
|
|
||||||
if(mode == 0) {
|
if(mode == 0) {
|
||||||
/* turn -z|-Z into a mode if there's nothing else specified */
|
/* turn -z|-Z into a mode if there's nothing else specified */
|
||||||
if(armor == 1) {
|
if(armor == 1) {
|
||||||
@@ -390,8 +388,7 @@ int main (int argc, char **argv) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(usevault == 1) {
|
if(usevault == 1) {
|
||||||
pcphash_init();
|
vault = pcpvault_init(ptx, vaultfile);
|
||||||
vault = pcpvault_init(vaultfile);
|
|
||||||
if(vault != NULL) {
|
if(vault != NULL) {
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
case PCP_MODE_KEYGEN:
|
case PCP_MODE_KEYGEN:
|
||||||
@@ -435,7 +432,7 @@ int main (int argc, char **argv) {
|
|||||||
in = stdin;
|
in = stdin;
|
||||||
else {
|
else {
|
||||||
if((in = fopen(infile, "rb")) == NULL) {
|
if((in = fopen(infile, "rb")) == NULL) {
|
||||||
fatal("Could not open input file %s\n", infile);
|
fatal(ptx, "Could not open input file %s\n", infile);
|
||||||
free(infile);
|
free(infile);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -452,7 +449,7 @@ int main (int argc, char **argv) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
fatal("You need to specify a key id (--keyid)!\n");
|
fatal(ptx, "You need to specify a key id (--keyid)!\n");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -465,7 +462,7 @@ int main (int argc, char **argv) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
fatal("You need to specify a key id (--keyid)!\n");
|
fatal(ptx, "You need to specify a key id (--keyid)!\n");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -481,7 +478,7 @@ int main (int argc, char **argv) {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* -i and -r specified */
|
/* -i and -r specified */
|
||||||
fatal("You can't specify both -i and -r, use either -i or -r!\n");
|
fatal(ptx, "You can't specify both -i and -r, use either -i or -r!\n");
|
||||||
}
|
}
|
||||||
if(id != NULL)
|
if(id != NULL)
|
||||||
free(id);
|
free(id);
|
||||||
@@ -510,7 +507,7 @@ int main (int argc, char **argv) {
|
|||||||
case PCP_MODE_SIGN:
|
case PCP_MODE_SIGN:
|
||||||
if(detach) {
|
if(detach) {
|
||||||
if(outfile != NULL && sigfile != NULL)
|
if(outfile != NULL && sigfile != NULL)
|
||||||
fatal("You can't both specify -O and -f, use -O for std signatures and -f for detached ones\n");
|
fatal(ptx, "You can't both specify -O and -f, use -O for std signatures and -f for detached ones\n");
|
||||||
else
|
else
|
||||||
pcpsign(infile, sigfile, xpass, armor, detach);
|
pcpsign(infile, sigfile, xpass, armor, detach);
|
||||||
}
|
}
|
||||||
@@ -540,8 +537,7 @@ int main (int argc, char **argv) {
|
|||||||
goto ELSEMODE;
|
goto ELSEMODE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
pcpvault_close(vault);
|
pcpvault_close(ptx, vault);
|
||||||
pcphash_clean();
|
|
||||||
free(vaultfile);
|
free(vaultfile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -565,8 +561,7 @@ int main (int argc, char **argv) {
|
|||||||
pcptext_infile(infile);
|
pcptext_infile(infile);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
pcphash_init();
|
vault = pcpvault_init(ptx, vaultfile);
|
||||||
vault = pcpvault_init(vaultfile);
|
|
||||||
if(! useid && infile == NULL) {
|
if(! useid && infile == NULL) {
|
||||||
pcptext_vault(vault);
|
pcptext_vault(vault);
|
||||||
}
|
}
|
||||||
@@ -577,21 +572,20 @@ int main (int argc, char **argv) {
|
|||||||
free(id);
|
free(id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pcpvault_close(vault);
|
pcpvault_close(ptx, vault);
|
||||||
pcphash_clean();
|
|
||||||
free(vaultfile);
|
free(vaultfile);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
/* mode params mixed */
|
/* mode params mixed */
|
||||||
fatal("Sorry, invalid combination of commandline parameters (0x%04X)!\n", mode);
|
fatal(ptx, "Sorry, invalid combination of commandline parameters (0x%04X)!\n", mode);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fatals_ifany();
|
fatals_ifany(ptx);
|
||||||
fatals_done();
|
int e = ptx->pcp_exit;
|
||||||
return PCP_EXIT;
|
ptx_clean(ptx);
|
||||||
|
return e;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,6 +39,7 @@
|
|||||||
#include "z85util.h"
|
#include "z85util.h"
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
#include "vault.h"
|
#include "vault.h"
|
||||||
|
#include "context.h"
|
||||||
|
|
||||||
/* subs */
|
/* subs */
|
||||||
#include "keymgmt.h"
|
#include "keymgmt.h"
|
||||||
@@ -80,7 +81,9 @@
|
|||||||
#define PCP_HELP_INTRO "This is Pretty Curved Privacy. Licensed under the GPLv3. This is\n" \
|
#define PCP_HELP_INTRO "This is Pretty Curved Privacy. Licensed under the GPLv3. This is\n" \
|
||||||
"BETA software. Use with care. NOT intended for production use.\n"
|
"BETA software. Use with care. NOT intended for production use.\n"
|
||||||
|
|
||||||
|
/* some globals */
|
||||||
vault_t *vault;
|
vault_t *vault;
|
||||||
|
PCPCTX *ptx;
|
||||||
int debug;
|
int debug;
|
||||||
|
|
||||||
void version();
|
void version();
|
||||||
|
|||||||
@@ -58,13 +58,13 @@ pcp_readpass(char ** passwd, const char * prompt,
|
|||||||
/* If we're reading from a terminal, try to disable echo. */
|
/* If we're reading from a terminal, try to disable echo. */
|
||||||
if ((usingtty = isatty(fileno(readfrom))) != 0) {
|
if ((usingtty = isatty(fileno(readfrom))) != 0) {
|
||||||
if (tcgetattr(fileno(readfrom), &term_old)) {
|
if (tcgetattr(fileno(readfrom), &term_old)) {
|
||||||
fatal("Cannot read terminal settings");
|
fatal(ptx, "Cannot read terminal settings");
|
||||||
goto err1;
|
goto err1;
|
||||||
}
|
}
|
||||||
memcpy(&term, &term_old, sizeof(struct termios));
|
memcpy(&term, &term_old, sizeof(struct termios));
|
||||||
term.c_lflag = (term.c_lflag & ~ECHO) | ECHONL;
|
term.c_lflag = (term.c_lflag & ~ECHO) | ECHONL;
|
||||||
if (tcsetattr(fileno(readfrom), TCSANOW, &term)) {
|
if (tcsetattr(fileno(readfrom), TCSANOW, &term)) {
|
||||||
fatal("Cannot set terminal settings");
|
fatal(ptx, "Cannot set terminal settings");
|
||||||
goto err1;
|
goto err1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -76,7 +76,7 @@ retry:
|
|||||||
|
|
||||||
/* Read the password. */
|
/* Read the password. */
|
||||||
if (fgets(passbuf, MAXPASSLEN, readfrom) == NULL) {
|
if (fgets(passbuf, MAXPASSLEN, readfrom) == NULL) {
|
||||||
fatal("Cannot read password");
|
fatal(ptx, "Cannot read password");
|
||||||
goto err2;
|
goto err2;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -85,7 +85,7 @@ retry:
|
|||||||
if (usingtty)
|
if (usingtty)
|
||||||
fprintf(stderr, "%s: ", confirmprompt);
|
fprintf(stderr, "%s: ", confirmprompt);
|
||||||
if (fgets(confpassbuf, MAXPASSLEN, readfrom) == NULL) {
|
if (fgets(confpassbuf, MAXPASSLEN, readfrom) == NULL) {
|
||||||
fatal("Cannot read password");
|
fatal(ptx, "Cannot read password");
|
||||||
goto err2;
|
goto err2;
|
||||||
}
|
}
|
||||||
if (strcmp(passbuf, confpassbuf)) {
|
if (strcmp(passbuf, confpassbuf)) {
|
||||||
@@ -108,7 +108,7 @@ retry:
|
|||||||
|
|
||||||
/* Copy the password out. */
|
/* Copy the password out. */
|
||||||
if ((*passwd = strdup(passbuf)) == NULL) {
|
if ((*passwd = strdup(passbuf)) == NULL) {
|
||||||
fatal("Cannot allocate memory");
|
fatal(ptx, "Cannot allocate memory");
|
||||||
goto err1;
|
goto err1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -36,6 +36,8 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "defines.h"
|
#include "defines.h"
|
||||||
|
#include "context.h"
|
||||||
|
#include "pcp.h"
|
||||||
|
|
||||||
#define MAXPASSLEN 2048
|
#define MAXPASSLEN 2048
|
||||||
|
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ int pcpsign(char *infile, char *outfile, char *passwd, int z85, int detach) {
|
|||||||
secret = pcp_find_primary_secret();
|
secret = pcp_find_primary_secret();
|
||||||
|
|
||||||
if(secret == NULL) {
|
if(secret == NULL) {
|
||||||
fatal("Could not find a secret key in vault %s!\n", vault->filename);
|
fatal(ptx, "Could not find a secret key in vault %s!\n", vault->filename);
|
||||||
goto errs1;
|
goto errs1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -40,7 +40,7 @@ int pcpsign(char *infile, char *outfile, char *passwd, int z85, int detach) {
|
|||||||
in = stdin;
|
in = stdin;
|
||||||
else {
|
else {
|
||||||
if((in = fopen(infile, "rb")) == NULL) {
|
if((in = fopen(infile, "rb")) == NULL) {
|
||||||
fatal("Could not open input file %s\n", infile);
|
fatal(ptx, "Could not open input file %s\n", infile);
|
||||||
goto errs1;
|
goto errs1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -49,7 +49,7 @@ int pcpsign(char *infile, char *outfile, char *passwd, int z85, int detach) {
|
|||||||
out = stdout;
|
out = stdout;
|
||||||
else {
|
else {
|
||||||
if((out = fopen(outfile, "wb+")) == NULL) {
|
if((out = fopen(outfile, "wb+")) == NULL) {
|
||||||
fatal("Could not open output file %s\n", outfile);
|
fatal(ptx, "Could not open output file %s\n", outfile);
|
||||||
goto errs1;
|
goto errs1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -66,7 +66,7 @@ int pcpsign(char *infile, char *outfile, char *passwd, int z85, int detach) {
|
|||||||
strncpy(passphrase, passwd, strlen(passwd)+1);
|
strncpy(passphrase, passwd, strlen(passwd)+1);
|
||||||
}
|
}
|
||||||
|
|
||||||
secret = pcpkey_decrypt(secret, passphrase);
|
secret = pcpkey_decrypt(ptx, secret, passphrase);
|
||||||
if(secret == NULL)
|
if(secret == NULL)
|
||||||
goto errs1;
|
goto errs1;
|
||||||
}
|
}
|
||||||
@@ -78,7 +78,7 @@ int pcpsign(char *infile, char *outfile, char *passwd, int z85, int detach) {
|
|||||||
if(detach == 1)
|
if(detach == 1)
|
||||||
sigsize = pcp_ed_detachsign_buffered(pin, pout, secret);
|
sigsize = pcp_ed_detachsign_buffered(pin, pout, secret);
|
||||||
else
|
else
|
||||||
sigsize = pcp_ed_sign_buffered(pin, pout, secret, z85);
|
sigsize = pcp_ed_sign_buffered(ptx, pin, pout, secret, z85);
|
||||||
|
|
||||||
ps_close(pin);
|
ps_close(pin);
|
||||||
ps_close(pout);
|
ps_close(pout);
|
||||||
@@ -103,30 +103,30 @@ int pcpverify(char *infile, char *sigfile, char *id, int detach) {
|
|||||||
in = stdin;
|
in = stdin;
|
||||||
else {
|
else {
|
||||||
if((in = fopen(infile, "rb")) == NULL) {
|
if((in = fopen(infile, "rb")) == NULL) {
|
||||||
fatal("Could not open input file %s\n", infile);
|
fatal(ptx, "Could not open input file %s\n", infile);
|
||||||
goto errv1;
|
goto errv1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(sigfile != NULL) {
|
if(sigfile != NULL) {
|
||||||
if((sigfd = fopen(sigfile, "rb")) == NULL) {
|
if((sigfd = fopen(sigfile, "rb")) == NULL) {
|
||||||
fatal("Could not open signature file %s\n", sigfile);
|
fatal(ptx, "Could not open signature file %s\n", sigfile);
|
||||||
goto errv1;
|
goto errv1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(id != NULL)
|
if(id != NULL)
|
||||||
HASH_FIND_STR(pcppubkey_hash, id, pub);
|
pub = pcphash_pubkeyexists(ptx, id);
|
||||||
|
|
||||||
Pcpstream *pin = ps_new_file(in);
|
Pcpstream *pin = ps_new_file(in);
|
||||||
|
|
||||||
if(detach) {
|
if(detach) {
|
||||||
Pcpstream *psigfd = ps_new_file(sigfd);
|
Pcpstream *psigfd = ps_new_file(sigfd);
|
||||||
pub = pcp_ed_detachverify_buffered(pin, psigfd, pub);
|
pub = pcp_ed_detachverify_buffered(ptx, pin, psigfd, pub);
|
||||||
ps_close(psigfd);
|
ps_close(psigfd);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
pub = pcp_ed_verify_buffered(pin, pub);
|
pub = pcp_ed_verify_buffered(ptx, pin, pub);
|
||||||
|
|
||||||
ps_close(pin);
|
ps_close(pin);
|
||||||
|
|
||||||
|
|||||||
@@ -32,6 +32,7 @@
|
|||||||
#include "uthash.h"
|
#include "uthash.h"
|
||||||
#include "z85.h"
|
#include "z85.h"
|
||||||
#include "pcpstream.h"
|
#include "pcpstream.h"
|
||||||
|
#include "context.h"
|
||||||
|
|
||||||
int pcpsign(char *infile, char *outfile, char *passwd, int z85, int detach);
|
int pcpsign(char *infile, char *outfile, char *passwd, int z85, int detach);
|
||||||
int pcpverify(char *infile, char *sigfile, char *id, int detach);
|
int pcpverify(char *infile, char *sigfile, char *id, int detach);
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ int pcpz85_encode(char *infile, char *outfile) {
|
|||||||
in = stdin;
|
in = stdin;
|
||||||
else {
|
else {
|
||||||
if((in = fopen(infile, "rb")) == NULL) {
|
if((in = fopen(infile, "rb")) == NULL) {
|
||||||
fatal("Could not open input file %s\n", infile);
|
fatal(ptx, "Could not open input file %s\n", infile);
|
||||||
goto errz1;
|
goto errz1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -39,7 +39,7 @@ int pcpz85_encode(char *infile, char *outfile) {
|
|||||||
out = stdout;
|
out = stdout;
|
||||||
else {
|
else {
|
||||||
if((out = fopen(outfile, "wb+")) == NULL) {
|
if((out = fopen(outfile, "wb+")) == NULL) {
|
||||||
fatal("Could not open output file %s\n", outfile);
|
fatal(ptx, "Could not open output file %s\n", outfile);
|
||||||
goto errz1;
|
goto errz1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -59,7 +59,7 @@ int pcpz85_encode(char *infile, char *outfile) {
|
|||||||
fclose(in);
|
fclose(in);
|
||||||
|
|
||||||
if(inputBufSize == 0) {
|
if(inputBufSize == 0) {
|
||||||
fatal("Input file is empty!\n");
|
fatal(ptx, "Input file is empty!\n");
|
||||||
goto errz2;
|
goto errz2;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -69,7 +69,7 @@ int pcpz85_encode(char *infile, char *outfile) {
|
|||||||
if(encoded != NULL) {
|
if(encoded != NULL) {
|
||||||
fprintf(out, "%s\n%s\n%s\n", PCP_ZFILE_HEADER, encoded, PCP_ZFILE_FOOTER);
|
fprintf(out, "%s\n%s\n%s\n", PCP_ZFILE_HEADER, encoded, PCP_ZFILE_FOOTER);
|
||||||
if(ferror(out) != 0) {
|
if(ferror(out) != 0) {
|
||||||
fatal("Failed to write z85 output!\n");
|
fatal(ptx, "Failed to write z85 output!\n");
|
||||||
}
|
}
|
||||||
free(encoded);
|
free(encoded);
|
||||||
goto errz2;
|
goto errz2;
|
||||||
@@ -95,7 +95,7 @@ int pcpz85_decode(char *infile, char *outfile) {
|
|||||||
in = stdin;
|
in = stdin;
|
||||||
else {
|
else {
|
||||||
if((in = fopen(infile, "rb")) == NULL) {
|
if((in = fopen(infile, "rb")) == NULL) {
|
||||||
fatal("Could not open input file %s\n", infile);
|
fatal(ptx, "Could not open input file %s\n", infile);
|
||||||
goto errdz1;
|
goto errdz1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -104,18 +104,18 @@ int pcpz85_decode(char *infile, char *outfile) {
|
|||||||
out = stdout;
|
out = stdout;
|
||||||
else {
|
else {
|
||||||
if((out = fopen(outfile, "wb+")) == NULL) {
|
if((out = fopen(outfile, "wb+")) == NULL) {
|
||||||
fatal("Could not open output file %s\n", outfile);
|
fatal(ptx, "Could not open output file %s\n", outfile);
|
||||||
goto errdz1;
|
goto errdz1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
char *encoded = pcp_readz85file(in);
|
char *encoded = pcp_readz85file(ptx, in);
|
||||||
|
|
||||||
if(encoded == NULL)
|
if(encoded == NULL)
|
||||||
goto errdz1;
|
goto errdz1;
|
||||||
|
|
||||||
size_t clen;
|
size_t clen;
|
||||||
byte *decoded = pcp_z85_decode(encoded, &clen);
|
byte *decoded = pcp_z85_decode(ptx, encoded, &clen);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -125,7 +125,7 @@ int pcpz85_decode(char *infile, char *outfile) {
|
|||||||
fwrite(decoded, clen, 1, out);
|
fwrite(decoded, clen, 1, out);
|
||||||
fclose(out);
|
fclose(out);
|
||||||
if(ferror(out) != 0) {
|
if(ferror(out) != 0) {
|
||||||
fatal("Failed to write decoded output!\n");
|
fatal(ptx, "Failed to write decoded output!\n");
|
||||||
goto errdz3;
|
goto errdz3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -35,6 +35,9 @@
|
|||||||
#include "z85.h"
|
#include "z85.h"
|
||||||
#include "zmq_z85.h"
|
#include "zmq_z85.h"
|
||||||
#include "defines.h"
|
#include "defines.h"
|
||||||
|
#include "context.h"
|
||||||
|
|
||||||
|
extern PCPCTX *ptx;
|
||||||
|
|
||||||
int pcpz85_encode(char *infile, char *outfile);
|
int pcpz85_encode(char *infile, char *outfile);
|
||||||
int pcpz85_decode(char *infile, char *outfile);
|
int pcpz85_decode(char *infile, char *outfile);
|
||||||
|
|||||||
Reference in New Issue
Block a user