mirror of
https://codeberg.org/scip/pcp.git
synced 2025-12-17 20:00:58 +01:00
put previously global error handling and key hashes into ptx (pcp context) to make libpcp threadsafe.
This commit is contained in:
@@ -26,8 +26,8 @@ pkgconfigdir = $(libdir)/pkgconfig
|
||||
pkgconfig_DATA = libpcp1.pc
|
||||
|
||||
libpcp1_la_SOURCES = platform.c mac.c mem.c pad.c version.c \
|
||||
z85.c zmq_z85.c key.c randomart.c \
|
||||
vault.c fatal.c jenhash.c digital_crc32.c \
|
||||
context.c z85.c zmq_z85.c key.c randomart.c \
|
||||
vault.c jenhash.c digital_crc32.c \
|
||||
crypto.c ed.c keyhash.c scrypt.c \
|
||||
scrypt/crypto/sha256.c scrypt/crypto/crypto_scrypt-nosse.c \
|
||||
base85.c util.c buffer.c mgmt.c keysig.c pcpstream.c
|
||||
|
||||
@@ -33,7 +33,7 @@ static void prep_base85(void)
|
||||
}
|
||||
}
|
||||
|
||||
int decode_85(char *dst, const char *buffer, int len)
|
||||
int decode_85(PCPCTX *ptx, char *dst, const char *buffer, int len)
|
||||
{
|
||||
prep_base85();
|
||||
say1("len: %d\n", len);
|
||||
|
||||
@@ -129,9 +129,8 @@ byte *buffer_get(Buffer *b) {
|
||||
|
||||
size_t buffer_get_chunk(Buffer *b, void *buf, size_t len) {
|
||||
if(len > b->end - b->offset) {
|
||||
fatal("[buffer %s] attempt to read %ld bytes data from buffer with %ld bytes left at offset %ld\n",
|
||||
final("[buffer %s] attempt to read %ld bytes data from buffer with %ld bytes left at offset %ld\n",
|
||||
b->name, len, b->end - b->offset, b->offset);
|
||||
return 0;
|
||||
}
|
||||
else if(len == 0) {
|
||||
/* FIXME: check how this happens */
|
||||
@@ -146,9 +145,8 @@ size_t buffer_get_chunk(Buffer *b, void *buf, size_t len) {
|
||||
|
||||
size_t buffer_get_chunk_tobuf(Buffer *b, Buffer *dst, size_t len) {
|
||||
if(len > b->end - b->offset) {
|
||||
fatal("[buffer %s] attempt to read %ld bytes data from buffer with %ld bytes left at offset %ld\n",
|
||||
final("[buffer %s] attempt to read %ld bytes data from buffer with %ld bytes left at offset %ld\n",
|
||||
b->name, len, b->end - b->offset, b->offset);
|
||||
return 0;
|
||||
}
|
||||
else if(len == 0) {
|
||||
/* FIXME: check how this happens */
|
||||
@@ -246,13 +244,11 @@ char *buffer_get_str(Buffer *b) {
|
||||
|
||||
size_t buffer_extract(Buffer *b, void *buf, size_t offset, size_t len) {
|
||||
if(len > b->end) {
|
||||
fatal("[buffer %s] attempt to read %ld bytes past end of buffer at %ld\n", b->name, b->end - (b->offset + len), b->end);
|
||||
return 0;
|
||||
final("[buffer %s] attempt to read %ld bytes past end of buffer at %ld\n", b->name, b->end - (b->offset + len), b->end);
|
||||
}
|
||||
|
||||
if(offset > b->end) {
|
||||
fatal("[buffer %s] attempt to read at offset %ld past len to read %ld\n", b->name, offset, b->end);
|
||||
return 0;
|
||||
final("[buffer %s] attempt to read at offset %ld past len to read %ld\n", b->name, offset, b->end);
|
||||
}
|
||||
|
||||
memcpy(buf, b->buf + offset, len);
|
||||
@@ -328,13 +324,10 @@ size_t buffer_fd_read(Buffer *b, FILE *in, size_t len) {
|
||||
|
||||
size_t s = fread(data, 1, len, in);
|
||||
|
||||
if(s < len) {
|
||||
fatal("[buffer %s] attempt to read %"FMT_SIZE_T" bytes from FILE, but got %"FMT_SIZE_T" bytes only\n", b->name, (SIZE_T_CAST)len, (SIZE_T_CAST)s);
|
||||
return 0;
|
||||
}
|
||||
if(s > 0)
|
||||
buffer_add(b, data, len);
|
||||
|
||||
buffer_add(b, data, len);
|
||||
return len;
|
||||
return s;
|
||||
}
|
||||
|
||||
void buffer_add8(Buffer *b, uint8_t v) {
|
||||
|
||||
@@ -21,9 +21,8 @@
|
||||
|
||||
#define _GNU_SOURCE /* vasprintf() linux */
|
||||
|
||||
#include "defines.h"
|
||||
#include "platform.h"
|
||||
|
||||
#include "context.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdarg.h>
|
||||
@@ -31,39 +30,70 @@
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
char *PCP_ERR;
|
||||
byte PCP_ERRSET;
|
||||
int PCP_EXIT;
|
||||
int PCPVERBOSE;
|
||||
PCPCTX *ptx_new() {
|
||||
PCPCTX *p = ucmalloc(sizeof(PCPCTX));
|
||||
p->pcp_err = NULL;
|
||||
p->pcp_errset = 0;
|
||||
p->pcp_exit = 0;
|
||||
p->verbose = 0;
|
||||
p->pcpkey_hash = NULL;
|
||||
p->pcppubkey_hash = NULL;
|
||||
p->pcpkeysig_hash = NULL;
|
||||
|
||||
void fatal(const char * fmt, ...) {
|
||||
return p;
|
||||
}
|
||||
|
||||
void ptx_clean(PCPCTX *ptx) {
|
||||
if(ptx->pcp_errset)
|
||||
free(ptx->pcp_err);
|
||||
|
||||
pcphash_clean(ptx);
|
||||
|
||||
free(ptx);
|
||||
}
|
||||
|
||||
|
||||
void fatal(PCPCTX *ptx, const char * fmt, ...) {
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
|
||||
char *err = ptx->pcp_err;
|
||||
|
||||
if(vasprintf(&PCP_ERR, fmt, ap) >= 0) {
|
||||
if(vasprintf(&err, fmt, ap) >= 0) {
|
||||
va_end(ap);
|
||||
PCP_ERRSET = 1;
|
||||
ptx->pcp_errset = 1;
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "Could not store fatal error message %s!\n", fmt);
|
||||
PCP_ERRSET = 1;
|
||||
ptx->pcp_errset = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void fatals_reset() {
|
||||
PCP_ERRSET = 0;
|
||||
void fatals_reset(PCPCTX *ptx) {
|
||||
ptx->pcp_errset = 0;
|
||||
}
|
||||
|
||||
void fatals_ifany() {
|
||||
if(PCP_ERRSET == 1) {
|
||||
fprintf(stderr, "%s", PCP_ERR);
|
||||
void fatals_ifany(PCPCTX *ptx) {
|
||||
if(ptx->pcp_errset == 1) {
|
||||
fprintf(stderr, "%s", ptx->pcp_err);
|
||||
if(errno) {
|
||||
fprintf(stderr, "Error: %s\n", strerror(errno));
|
||||
}
|
||||
PCP_EXIT = 1;
|
||||
ptx->pcp_exit = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void fatals_done() {
|
||||
free(PCP_ERR);
|
||||
void final(const char * fmt, ...) {
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
|
||||
char *err = NULL;
|
||||
|
||||
if(vasprintf(&err, fmt, ap) >= 0) {
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
fprintf(stderr, "ABORT: %s", err);
|
||||
|
||||
abort();
|
||||
}
|
||||
@@ -81,7 +81,7 @@ int pcp_sodium_verify_box(byte **cleartext, byte* message,
|
||||
|
||||
|
||||
|
||||
byte *pcp_box_encrypt(pcp_key_t *secret, pcp_pubkey_t *pub,
|
||||
byte *pcp_box_encrypt(PCPCTX *ptx, pcp_key_t *secret, pcp_pubkey_t *pub,
|
||||
byte *message, size_t messagesize,
|
||||
size_t *csize) {
|
||||
|
||||
@@ -93,7 +93,7 @@ byte *pcp_box_encrypt(pcp_key_t *secret, pcp_pubkey_t *pub,
|
||||
secret->secret, pub->pub);
|
||||
|
||||
if(es <= messagesize) {
|
||||
fatal("failed to encrypt message!\n");
|
||||
fatal(ptx, "failed to encrypt message!\n");
|
||||
goto errbec;
|
||||
}
|
||||
|
||||
@@ -124,7 +124,7 @@ byte *pcp_box_encrypt(pcp_key_t *secret, pcp_pubkey_t *pub,
|
||||
}
|
||||
|
||||
|
||||
byte *pcp_box_decrypt(pcp_key_t *secret, pcp_pubkey_t *pub,
|
||||
byte *pcp_box_decrypt(PCPCTX *ptx, pcp_key_t *secret, pcp_pubkey_t *pub,
|
||||
byte *cipher, size_t ciphersize,
|
||||
size_t *dsize) {
|
||||
|
||||
@@ -140,7 +140,7 @@ byte *pcp_box_decrypt(pcp_key_t *secret, pcp_pubkey_t *pub,
|
||||
if(pcp_sodium_verify_box(&message, cipheronly,
|
||||
ciphersize - crypto_secretbox_NONCEBYTES,
|
||||
nonce, secret->secret, pub->pub) != 0){
|
||||
fatal("failed to decrypt message!\n");
|
||||
fatal(ptx, "failed to decrypt message!\n");
|
||||
goto errbed;
|
||||
}
|
||||
|
||||
@@ -161,7 +161,7 @@ byte *pcp_box_decrypt(pcp_key_t *secret, pcp_pubkey_t *pub,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
size_t pcp_decrypt_stream(Pcpstream *in, Pcpstream* out, pcp_key_t *s, byte *symkey, int verify) {
|
||||
size_t pcp_decrypt_stream(PCPCTX *ptx, Pcpstream *in, Pcpstream* out, pcp_key_t *s, byte *symkey, int verify) {
|
||||
pcp_pubkey_t *cur = NULL;
|
||||
byte *reccipher = NULL;
|
||||
int recmatch, self;
|
||||
@@ -190,7 +190,7 @@ size_t pcp_decrypt_stream(Pcpstream *in, Pcpstream* out, pcp_key_t *s, byte *sym
|
||||
if(symkey != NULL)
|
||||
self = 1;
|
||||
else {
|
||||
fatal("Input is symetrically encrypted but no key have been specified (lib usage failure)\n");
|
||||
fatal(ptx, "Input is symetrically encrypted but no key have been specified (lib usage failure)\n");
|
||||
goto errdef1;
|
||||
}
|
||||
}
|
||||
@@ -202,14 +202,14 @@ size_t pcp_decrypt_stream(Pcpstream *in, Pcpstream* out, pcp_key_t *s, byte *sym
|
||||
|
||||
if(self) {
|
||||
/* just decrypt symetrically and go outa here */
|
||||
return pcp_decrypt_stream_sym(in, out, symkey, NULL);
|
||||
return pcp_decrypt_stream_sym(ptx, in, out, symkey, NULL);
|
||||
}
|
||||
|
||||
#ifdef PCP_ASYM_ADD_SENDER_PUB
|
||||
/* step 2, sender's pubkey */
|
||||
cur_bufsize = ps_read(in, &in_buf, crypto_box_PUBLICKEYBYTES); /* fread(&in_buf, 1, crypto_box_PUBLICKEYBYTES, in); */
|
||||
if(cur_bufsize != crypto_box_PUBLICKEYBYTES && !ps_end(in) && !ps_err(in)) {
|
||||
fatal("Error: input file doesn't contain senders public key\n");
|
||||
fatal(ptx, "Error: input file doesn't contain senders public key\n");
|
||||
goto errdef1;
|
||||
}
|
||||
#endif
|
||||
@@ -217,7 +217,7 @@ size_t pcp_decrypt_stream(Pcpstream *in, Pcpstream* out, pcp_key_t *s, byte *sym
|
||||
/* step 3, check len recipients */
|
||||
cur_bufsize = ps_read(in, &lenrec, 4); /* fread(&lenrec, 1, 4, in); */
|
||||
if(cur_bufsize != 4 && !ps_end(in) && !ps_err(in)) {
|
||||
fatal("Error: input file doesn't contain recipient count\n");
|
||||
fatal(ptx, "Error: input file doesn't contain recipient count\n");
|
||||
goto errdef1;
|
||||
}
|
||||
lenrec = be32toh(lenrec);
|
||||
@@ -232,14 +232,14 @@ size_t pcp_decrypt_stream(Pcpstream *in, Pcpstream* out, pcp_key_t *s, byte *sym
|
||||
for(nrec=0; nrec<lenrec; nrec++) {
|
||||
cur_bufsize = ps_read(in, &rec_buf, PCP_ASYM_RECIPIENT_SIZE); /* fread(&rec_buf, 1, PCP_ASYM_RECIPIENT_SIZE, in); */
|
||||
if(cur_bufsize != PCP_ASYM_RECIPIENT_SIZE && !ps_end(in) && !ps_err(in)) {
|
||||
fatal("Error: input file corrupted, incomplete or no recipients (got %ld, exp %ld)\n", cur_bufsize, PCP_ASYM_RECIPIENT_SIZE );
|
||||
fatal(ptx, "Error: input file corrupted, incomplete or no recipients (got %ld, exp %ld)\n", cur_bufsize, PCP_ASYM_RECIPIENT_SIZE );
|
||||
goto errdef1;
|
||||
}
|
||||
recmatch = 0;
|
||||
|
||||
pcphash_iteratepub(cur) {
|
||||
pcphash_iteratepub(ptx, cur) {
|
||||
byte *recipient;
|
||||
recipient = pcp_box_decrypt(s, cur, rec_buf, PCP_ASYM_RECIPIENT_SIZE, &rec_size);
|
||||
recipient = pcp_box_decrypt(ptx, s, cur, rec_buf, PCP_ASYM_RECIPIENT_SIZE, &rec_size);
|
||||
if(recipient != NULL && rec_size == crypto_secretbox_KEYBYTES) {
|
||||
/* found a match */
|
||||
recmatch = 1;
|
||||
@@ -257,19 +257,19 @@ size_t pcp_decrypt_stream(Pcpstream *in, Pcpstream* out, pcp_key_t *s, byte *sym
|
||||
|
||||
|
||||
if(recmatch == 0) {
|
||||
fatal("Sorry, there's no matching public key in your vault for decryption\n");
|
||||
fatal(ptx, "Sorry, there's no matching public key in your vault for decryption\n");
|
||||
goto errdef1;
|
||||
}
|
||||
|
||||
/* step 5, actually decrypt the file, finally */
|
||||
if(verify) {
|
||||
pcp_rec_t *rec = pcp_rec_new(reccipher, nrec * PCP_ASYM_RECIPIENT_SIZE, NULL, cur);
|
||||
size_t s = pcp_decrypt_stream_sym(in, out, symkey, rec);
|
||||
size_t s = pcp_decrypt_stream_sym(ptx, in, out, symkey, rec);
|
||||
pcp_rec_free(rec);
|
||||
return s;
|
||||
}
|
||||
else {
|
||||
size_t s = pcp_decrypt_stream_sym(in, out, symkey, NULL);
|
||||
size_t s = pcp_decrypt_stream_sym(ptx, in, out, symkey, NULL);
|
||||
return s;
|
||||
}
|
||||
|
||||
@@ -277,7 +277,7 @@ size_t pcp_decrypt_stream(Pcpstream *in, Pcpstream* out, pcp_key_t *s, byte *sym
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t pcp_encrypt_stream(Pcpstream *in, Pcpstream *out, pcp_key_t *s, pcp_pubkey_t *p, int sign) {
|
||||
size_t pcp_encrypt_stream(PCPCTX *ptx, Pcpstream *in, Pcpstream *out, pcp_key_t *s, pcp_pubkey_t *p, int sign) {
|
||||
byte *symkey;
|
||||
int recipient_count;
|
||||
byte *recipients_cipher;
|
||||
@@ -306,9 +306,9 @@ size_t pcp_encrypt_stream(Pcpstream *in, Pcpstream *out, pcp_key_t *s, pcp_pubke
|
||||
|
||||
HASH_ITER(hh, p, cur, t) {
|
||||
byte *rec_cipher;
|
||||
rec_cipher = pcp_box_encrypt(s, cur, symkey, crypto_secretbox_KEYBYTES, &es);
|
||||
rec_cipher = pcp_box_encrypt(ptx, s, cur, symkey, crypto_secretbox_KEYBYTES, &es);
|
||||
if(es != rec_size) {
|
||||
fatal("invalid rec_size, expected %dl, got %dl\n", rec_size, es);
|
||||
fatal(ptx, "invalid rec_size, expected %dl, got %dl\n", rec_size, es);
|
||||
if(rec_cipher != NULL)
|
||||
free(rec_cipher);
|
||||
goto errec1;
|
||||
@@ -326,7 +326,7 @@ size_t pcp_encrypt_stream(Pcpstream *in, Pcpstream *out, pcp_key_t *s, pcp_pubke
|
||||
/* fwrite(head, 1, 1, out); */
|
||||
/* fprintf(stderr, "D: header - 1\n"); */
|
||||
if(ps_err(out) != 0) {
|
||||
fatal("Failed to write encrypted output!\n");
|
||||
fatal(ptx, "Failed to write encrypted output!\n");
|
||||
goto errec1;
|
||||
}
|
||||
|
||||
@@ -361,11 +361,11 @@ size_t pcp_encrypt_stream(Pcpstream *in, Pcpstream *out, pcp_key_t *s, pcp_pubke
|
||||
size_t sym_size = 0;
|
||||
if(sign) {
|
||||
pcp_rec_t *rec = pcp_rec_new(recipients_cipher, rec_size * recipient_count, s, NULL);
|
||||
sym_size = pcp_encrypt_stream_sym(in, out, symkey, 1, rec);
|
||||
sym_size = pcp_encrypt_stream_sym(ptx, in, out, symkey, 1, rec);
|
||||
pcp_rec_free(rec);
|
||||
}
|
||||
else
|
||||
sym_size = pcp_encrypt_stream_sym(in, out, symkey, 1, NULL);
|
||||
sym_size = pcp_encrypt_stream_sym(ptx, in, out, symkey, 1, NULL);
|
||||
|
||||
if(sym_size == 0)
|
||||
goto errec1;
|
||||
@@ -386,7 +386,7 @@ size_t pcp_encrypt_stream(Pcpstream *in, Pcpstream *out, pcp_key_t *s, pcp_pubke
|
||||
|
||||
|
||||
|
||||
size_t pcp_encrypt_stream_sym(Pcpstream *in, Pcpstream *out, byte *symkey, int havehead, pcp_rec_t *recsign) {
|
||||
size_t pcp_encrypt_stream_sym(PCPCTX *ptx, Pcpstream *in, Pcpstream *out, byte *symkey, int havehead, pcp_rec_t *recsign) {
|
||||
/*
|
||||
havehead = 0: write the whole thing from here
|
||||
havehead = 1: no header, being called from asym...
|
||||
@@ -413,7 +413,7 @@ size_t pcp_encrypt_stream_sym(Pcpstream *in, Pcpstream *out, byte *symkey, int h
|
||||
es = ps_write(out, head, 1);
|
||||
/* es = fwrite(head, 1, 1, out); */
|
||||
if(ps_err(out) != 0) {
|
||||
fatal("Failed to write encrypted output!\n");
|
||||
fatal(ptx, "Failed to write encrypted output!\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -466,7 +466,7 @@ size_t pcp_encrypt_stream_sym(Pcpstream *in, Pcpstream *out, byte *symkey, int h
|
||||
}
|
||||
|
||||
if(ps_err(out) != 0) {
|
||||
fatal("Failed to write encrypted output!\n");
|
||||
fatal(ptx, "Failed to write encrypted output!\n");
|
||||
goto errsym1;
|
||||
}
|
||||
|
||||
@@ -504,7 +504,7 @@ size_t pcp_encrypt_stream_sym(Pcpstream *in, Pcpstream *out, byte *symkey, int h
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t pcp_decrypt_stream_sym(Pcpstream *in, Pcpstream* out, byte *symkey, pcp_rec_t *recverify) {
|
||||
size_t pcp_decrypt_stream_sym(PCPCTX *ptx, Pcpstream *in, Pcpstream* out, byte *symkey, pcp_rec_t *recverify) {
|
||||
byte *buf_nonce;
|
||||
byte *buf_cipher;
|
||||
byte *buf_clear;
|
||||
@@ -579,13 +579,13 @@ size_t pcp_decrypt_stream_sym(Pcpstream *in, Pcpstream* out, byte *symkey, pcp_r
|
||||
free(buf_clear);
|
||||
|
||||
if(ps_err(out) != 0) {
|
||||
fatal("Failed to write decrypted output!\n");
|
||||
fatal(ptx, "Failed to write decrypted output!\n");
|
||||
out_size = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
fatal("Failed to decrypt file content!\n");
|
||||
fatal(ptx, "Failed to decrypt file content!\n");
|
||||
free(buf_clear);
|
||||
out_size = 0;
|
||||
break;
|
||||
@@ -610,20 +610,20 @@ size_t pcp_decrypt_stream_sym(Pcpstream *in, Pcpstream* out, byte *symkey, pcp_r
|
||||
crypto_generichash_final(st, hash, crypto_generichash_BYTES_MAX);
|
||||
|
||||
byte *verifiedhash = NULL;
|
||||
verifiedhash = pcp_ed_verify(signature, siglen, recverify->pub);
|
||||
verifiedhash = pcp_ed_verify(ptx, signature, siglen, recverify->pub);
|
||||
if(verifiedhash == NULL)
|
||||
out_size = 0;
|
||||
else {
|
||||
if(memcmp(verifiedhash, hash, crypto_generichash_BYTES_MAX) != 0) {
|
||||
/* sig verified, but the hash doesn't match */
|
||||
fatal("signed hash doesn't match actual hash of signed decrypted file content\n");
|
||||
fatal(ptx, "signed hash doesn't match actual hash of signed decrypted file content\n");
|
||||
out_size = 0;
|
||||
}
|
||||
free(verifiedhash);
|
||||
}
|
||||
}
|
||||
else {
|
||||
fatal("Failed to decrypt signature!\n");
|
||||
fatal(ptx, "Failed to decrypt signature!\n");
|
||||
out_size = 0;
|
||||
}
|
||||
free(st);
|
||||
|
||||
48
libpcp/ed.c
48
libpcp/ed.c
@@ -21,12 +21,12 @@
|
||||
|
||||
#include "ed.h"
|
||||
|
||||
byte * pcp_ed_verify_key(byte *signature, size_t siglen, pcp_pubkey_t *p) {
|
||||
byte * pcp_ed_verify_key(PCPCTX *ptx, byte *signature, size_t siglen, pcp_pubkey_t *p) {
|
||||
byte *message = ucmalloc(siglen);
|
||||
unsigned long long mlen;
|
||||
|
||||
if(crypto_sign_open(message, &mlen, signature, siglen, p->masterpub) != 0) {
|
||||
fatal("Failed to open the signature using the public key 0x%s!\n", p->id);
|
||||
fatal(ptx, "Failed to open the signature using the public key 0x%s!\n", p->id);
|
||||
goto errve1;
|
||||
}
|
||||
|
||||
@@ -37,12 +37,12 @@ byte * pcp_ed_verify_key(byte *signature, size_t siglen, pcp_pubkey_t *p) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
byte * pcp_ed_verify(byte *signature, size_t siglen, pcp_pubkey_t *p) {
|
||||
byte * pcp_ed_verify(PCPCTX *ptx, byte *signature, size_t siglen, pcp_pubkey_t *p) {
|
||||
byte *message = ucmalloc(siglen); /* we alloc the full size, the resulting len will be returned by nacl anyway - crypto_sign_BYTES); */
|
||||
unsigned long long mlen;
|
||||
|
||||
if(crypto_sign_open(message, &mlen, signature, siglen, p->edpub) != 0) {
|
||||
fatal("Failed to open the signature using the public key 0x%s!\n", p->id);
|
||||
fatal(ptx, "Failed to open the signature using the public key 0x%s!\n", p->id);
|
||||
goto errve1;
|
||||
}
|
||||
|
||||
@@ -71,7 +71,7 @@ byte *pcp_ed_sign(byte *message, size_t messagesize, pcp_key_t *s) {
|
||||
return signature;
|
||||
}
|
||||
|
||||
size_t pcp_ed_sign_buffered(Pcpstream *in, Pcpstream* out, pcp_key_t *s, int z85) {
|
||||
size_t pcp_ed_sign_buffered(PCPCTX *ptx, Pcpstream *in, Pcpstream* out, pcp_key_t *s, int z85) {
|
||||
byte in_buf[PCP_BLOCK_SIZE];
|
||||
size_t cur_bufsize = 0;
|
||||
size_t outsize = 0;
|
||||
@@ -94,7 +94,7 @@ size_t pcp_ed_sign_buffered(Pcpstream *in, Pcpstream* out, pcp_key_t *s, int z85
|
||||
}
|
||||
|
||||
if(ps_err(out) != 0) {
|
||||
fatal("Failed to write encrypted output!\n");
|
||||
fatal(ptx, "Failed to write encrypted output!\n");
|
||||
free(st);
|
||||
return 0;
|
||||
}
|
||||
@@ -120,7 +120,7 @@ size_t pcp_ed_sign_buffered(Pcpstream *in, Pcpstream* out, pcp_key_t *s, int z85
|
||||
return outsize;
|
||||
}
|
||||
|
||||
pcp_pubkey_t *pcp_ed_verify_buffered(Pcpstream *in, pcp_pubkey_t *p) {
|
||||
pcp_pubkey_t *pcp_ed_verify_buffered(PCPCTX *ptx, Pcpstream *in, pcp_pubkey_t *p) {
|
||||
byte in_buf[PCP_BLOCK_SIZE/2];
|
||||
byte in_next[PCP_BLOCK_SIZE/2];
|
||||
byte in_full[PCP_BLOCK_SIZE];
|
||||
@@ -247,23 +247,23 @@ pcp_pubkey_t *pcp_ed_verify_buffered(Pcpstream *in, pcp_pubkey_t *p) {
|
||||
} /* while */
|
||||
|
||||
if(gotsig == 0) {
|
||||
fatal("Error, the signature doesn't contain the ed25519 signed hash\n");
|
||||
fatal(ptx, "Error, the signature doesn't contain the ed25519 signed hash\n");
|
||||
goto errvb1;
|
||||
}
|
||||
|
||||
crypto_generichash_final(st, hash, crypto_generichash_BYTES_MAX);
|
||||
|
||||
if(z85) {
|
||||
char *z85block = pcp_readz85string(z85encoded, zlen);
|
||||
char *z85block = pcp_readz85string(ptx, z85encoded, zlen);
|
||||
if(z85block == NULL)
|
||||
goto errvb1;
|
||||
|
||||
//fprintf(stderr, "ZBLOCK: <%s>\n", z85block);
|
||||
|
||||
size_t dstlen;
|
||||
byte *z85decoded = pcp_z85_decode(z85block, &dstlen);
|
||||
byte *z85decoded = pcp_z85_decode(ptx, z85block, &dstlen);
|
||||
if(dstlen != mlen) {
|
||||
fatal("z85 decoded signature didn't result in a proper signed hash(got: %ld, expected: %ld)\n", dstlen, mlen);
|
||||
fatal(ptx, "z85 decoded signature didn't result in a proper signed hash(got: %ld, expected: %ld)\n", dstlen, mlen);
|
||||
goto errvb1;
|
||||
}
|
||||
memcpy(sighash, z85decoded, mlen);
|
||||
@@ -273,14 +273,14 @@ pcp_pubkey_t *pcp_ed_verify_buffered(Pcpstream *in, pcp_pubkey_t *p) {
|
||||
/* huh, how did we made it til here? */
|
||||
byte *verifiedhash = NULL;
|
||||
if(p == NULL) {
|
||||
pcphash_iteratepub(p) {
|
||||
verifiedhash = pcp_ed_verify(sighash, mlen, p);
|
||||
pcphash_iteratepub(ptx, p) {
|
||||
verifiedhash = pcp_ed_verify(ptx, sighash, mlen, p);
|
||||
if(verifiedhash != NULL)
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
verifiedhash = pcp_ed_verify(sighash, mlen, p);
|
||||
verifiedhash = pcp_ed_verify(ptx, sighash, mlen, p);
|
||||
}
|
||||
|
||||
if(verifiedhash == NULL)
|
||||
@@ -288,7 +288,7 @@ pcp_pubkey_t *pcp_ed_verify_buffered(Pcpstream *in, pcp_pubkey_t *p) {
|
||||
|
||||
if(memcmp(verifiedhash, hash, crypto_generichash_BYTES_MAX) != 0) {
|
||||
/* sig verified, but the hash doesn't */
|
||||
fatal("signed hash doesn't match actual hash of signed file content\n");
|
||||
fatal(ptx, "signed hash doesn't match actual hash of signed file content\n");
|
||||
free(verifiedhash);
|
||||
return NULL;
|
||||
}
|
||||
@@ -336,7 +336,7 @@ size_t pcp_ed_detachsign_buffered(Pcpstream *in, Pcpstream *out, pcp_key_t *s) {
|
||||
return outsize;
|
||||
}
|
||||
|
||||
pcp_pubkey_t *pcp_ed_detachverify_buffered(Pcpstream *in, Pcpstream *sigfd, pcp_pubkey_t *p) {
|
||||
pcp_pubkey_t *pcp_ed_detachverify_buffered(PCPCTX *ptx, Pcpstream *in, Pcpstream *sigfd, pcp_pubkey_t *p) {
|
||||
byte in_buf[PCP_BLOCK_SIZE];
|
||||
size_t cur_bufsize = 0;
|
||||
size_t outsize = 0;
|
||||
@@ -374,35 +374,35 @@ pcp_pubkey_t *pcp_ed_detachverify_buffered(Pcpstream *in, Pcpstream *sigfd, pcp_
|
||||
}
|
||||
|
||||
if(sig == NULL) {
|
||||
fatal("Invalid detached signature\n");
|
||||
fatal(ptx, "Invalid detached signature\n");
|
||||
goto errdea1;
|
||||
}
|
||||
|
||||
|
||||
char *z85block = pcp_readz85string(sig, inputBufSize);
|
||||
char *z85block = pcp_readz85string(ptx, sig, inputBufSize);
|
||||
if(z85block == NULL)
|
||||
goto errdea2;
|
||||
|
||||
size_t clen;
|
||||
byte *sighash = pcp_z85_decode(z85block, &clen);
|
||||
byte *sighash = pcp_z85_decode(ptx, z85block, &clen);
|
||||
if(sighash == NULL)
|
||||
goto errdea3;
|
||||
|
||||
if(clen != mlen) {
|
||||
fatal("z85 decoded signature didn't result in a proper signed hash(got: %ld, expected: %ld)\n", clen, mlen);
|
||||
fatal(ptx, "z85 decoded signature didn't result in a proper signed hash(got: %ld, expected: %ld)\n", clen, mlen);
|
||||
goto errdea4;
|
||||
}
|
||||
|
||||
byte *verifiedhash = NULL;
|
||||
if(p == NULL) {
|
||||
pcphash_iteratepub(p) {
|
||||
verifiedhash = pcp_ed_verify(sighash, mlen, p);
|
||||
pcphash_iteratepub(ptx, p) {
|
||||
verifiedhash = pcp_ed_verify(ptx, sighash, mlen, p);
|
||||
if(verifiedhash != NULL)
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
verifiedhash = pcp_ed_verify(sighash, mlen, p);
|
||||
verifiedhash = pcp_ed_verify(ptx, sighash, mlen, p);
|
||||
}
|
||||
|
||||
if(verifiedhash == NULL)
|
||||
@@ -410,7 +410,7 @@ pcp_pubkey_t *pcp_ed_detachverify_buffered(Pcpstream *in, Pcpstream *sigfd, pcp_
|
||||
|
||||
if(memcmp(verifiedhash, hash, crypto_generichash_BYTES_MAX) != 0) {
|
||||
/* sig verified, but the hash doesn't */
|
||||
fatal("signed hash doesn't match actual hash of signed file content\n");
|
||||
fatal(ptx, "signed hash doesn't match actual hash of signed file content\n");
|
||||
goto errdea5;
|
||||
}
|
||||
|
||||
|
||||
54
libpcp/key.c
54
libpcp/key.c
@@ -21,19 +21,19 @@
|
||||
|
||||
|
||||
#include "key.h"
|
||||
#include "keyhash.h"
|
||||
#include "context.h"
|
||||
|
||||
/*
|
||||
* AS of 16/01/2014 I'm using scrypt() instead of my crafted key
|
||||
* derivation function. However, I create a hash from the pcp_scrypt()
|
||||
* result anyway because I need a cure25519 secret.
|
||||
*/
|
||||
byte *pcp_derivekey(char *passphrase, byte *nonce) {
|
||||
byte *pcp_derivekey(PCPCTX *ptx, char *passphrase, byte *nonce) {
|
||||
byte *key = ucmalloc(crypto_secretbox_KEYBYTES);
|
||||
size_t plen = strnlen(passphrase, 255);
|
||||
|
||||
/* create the scrypt hash */
|
||||
byte *scrypted = pcp_scrypt(passphrase, plen, nonce, crypto_secretbox_NONCEBYTES);
|
||||
byte *scrypted = pcp_scrypt(ptx, passphrase, plen, nonce, crypto_secretbox_NONCEBYTES);
|
||||
|
||||
/* make a hash from the scrypt() result */
|
||||
crypto_hash_sha256(key, (byte*)scrypted, 64);
|
||||
@@ -142,13 +142,13 @@ byte * pcp_gennonce() {
|
||||
return nonce;
|
||||
}
|
||||
|
||||
pcp_key_t *pcpkey_encrypt(pcp_key_t *key, char *passphrase) {
|
||||
pcp_key_t *pcpkey_encrypt(PCPCTX *ptx, pcp_key_t *key, char *passphrase) {
|
||||
if(key->nonce[0] == 0) {
|
||||
byte *nonce = pcp_gennonce();
|
||||
memcpy (key->nonce, nonce, crypto_secretbox_NONCEBYTES);
|
||||
}
|
||||
|
||||
byte *encryptkey = pcp_derivekey(passphrase, key->nonce);
|
||||
byte *encryptkey = pcp_derivekey(ptx, passphrase, key->nonce);
|
||||
|
||||
byte *encrypted;
|
||||
size_t es;
|
||||
@@ -175,7 +175,7 @@ pcp_key_t *pcpkey_encrypt(pcp_key_t *key, char *passphrase) {
|
||||
key->mastersecret[0] = 0;
|
||||
}
|
||||
else {
|
||||
fatal("failed to encrypt the secret key!\n");
|
||||
fatal(ptx, "failed to encrypt the secret key!\n");
|
||||
free(key);
|
||||
return NULL;
|
||||
}
|
||||
@@ -183,8 +183,8 @@ pcp_key_t *pcpkey_encrypt(pcp_key_t *key, char *passphrase) {
|
||||
return key;
|
||||
}
|
||||
|
||||
pcp_key_t *pcpkey_decrypt(pcp_key_t *key, char *passphrase) {
|
||||
byte *encryptkey = pcp_derivekey(passphrase, key->nonce);
|
||||
pcp_key_t *pcpkey_decrypt(PCPCTX *ptx, pcp_key_t *key, char *passphrase) {
|
||||
byte *encryptkey = pcp_derivekey(ptx, passphrase, key->nonce);
|
||||
|
||||
byte *decrypted;
|
||||
size_t es;
|
||||
@@ -201,7 +201,7 @@ pcp_key_t *pcpkey_decrypt(pcp_key_t *key, char *passphrase) {
|
||||
memcpy(key->secret, decrypted +128, 32);
|
||||
}
|
||||
else {
|
||||
fatal("failed to decrypt the secret key (got %d, expected 32)!\n", es);
|
||||
fatal(ptx, "failed to decrypt the secret key (got %d, expected 32)!\n", es);
|
||||
free(key);
|
||||
return NULL;
|
||||
}
|
||||
@@ -355,26 +355,26 @@ Buffer *pcp_keyblob(void *k, int type) {
|
||||
}
|
||||
|
||||
|
||||
int pcp_sanitycheck_pub(pcp_pubkey_t *key) {
|
||||
int pcp_sanitycheck_pub(PCPCTX *ptx, pcp_pubkey_t *key) {
|
||||
if(key->pub[0] == 0) {
|
||||
fatal("Pubkey sanity check: public key contained in key seems to be empty!\n");
|
||||
fatal(ptx, "Pubkey sanity check: public key contained in key seems to be empty!\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(key->type != PCP_KEY_TYPE_PUBLIC) {
|
||||
fatal("Pubkey sanity check: key type is not PUBLIC (expected: %02x, got: %02x)!\n",
|
||||
fatal(ptx, "Pubkey sanity check: key type is not PUBLIC (expected: %02x, got: %02x)!\n",
|
||||
PCP_KEY_TYPE_PUBLIC, key->type);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(key->version != PCP_KEY_VERSION) {
|
||||
fatal("Pubkey sanity check: unknown key version (expected: %08X, got: %08X)!\n",
|
||||
fatal(ptx, "Pubkey sanity check: unknown key version (expected: %08X, got: %08X)!\n",
|
||||
PCP_KEY_VERSION, key->version);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(key->serial <= 0) {
|
||||
fatal("Pubkey sanity check: invalid serial number: %08X!\n", key->serial);
|
||||
fatal(ptx, "Pubkey sanity check: invalid serial number: %08X!\n", key->serial);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -382,7 +382,7 @@ int pcp_sanitycheck_pub(pcp_pubkey_t *key) {
|
||||
char *got = ucmalloc(17);
|
||||
memcpy(got, key->id, 17);
|
||||
got[16] = '\0';
|
||||
fatal("Pubkey sanity check: invalid key id (expected 16 bytes, got: %s)!\n", got);
|
||||
fatal(ptx, "Pubkey sanity check: invalid key id (expected 16 bytes, got: %s)!\n", got);
|
||||
free(got);
|
||||
return 1;
|
||||
}
|
||||
@@ -392,13 +392,13 @@ int pcp_sanitycheck_pub(pcp_pubkey_t *key) {
|
||||
c = localtime(&t);
|
||||
if(c->tm_year <= 0 || c->tm_year > 1100) {
|
||||
/* well, I'm perhaps overacting here :) */
|
||||
fatal("Pubkey sanity check: invalid creation timestamp (got year %04d)!\n", c->tm_year + 1900);
|
||||
fatal(ptx, "Pubkey sanity check: invalid creation timestamp (got year %04d)!\n", c->tm_year + 1900);
|
||||
return 1;
|
||||
}
|
||||
|
||||
pcp_pubkey_t *maybe = pcphash_pubkeyexists(key->id);
|
||||
pcp_pubkey_t *maybe = pcphash_pubkeyexists(ptx, key->id);
|
||||
if(maybe != NULL) {
|
||||
fatal("Pubkey sanity check: there already exists a key with the id 0x%s\n", key->id);
|
||||
fatal(ptx, "Pubkey sanity check: there already exists a key with the id 0x%s\n", key->id);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -406,26 +406,26 @@ int pcp_sanitycheck_pub(pcp_pubkey_t *key) {
|
||||
}
|
||||
|
||||
|
||||
int pcp_sanitycheck_key(pcp_key_t *key) {
|
||||
int pcp_sanitycheck_key(PCPCTX *ptx, pcp_key_t *key) {
|
||||
if(key->encrypted[0] == 0) {
|
||||
fatal("Secretkey sanity check: secret key contained in key seems to be empty!\n");
|
||||
fatal(ptx, "Secretkey sanity check: secret key contained in key seems to be empty!\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(key->type != PCP_KEY_TYPE_SECRET && key->type != PCP_KEY_TYPE_MAINSECRET) {
|
||||
fatal("Secretkey sanity check: key type is not SECRET (expected: %02x, got: %02x)!\n",
|
||||
fatal(ptx, "Secretkey sanity check: key type is not SECRET (expected: %02x, got: %02x)!\n",
|
||||
PCP_KEY_TYPE_SECRET, key->type);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(key->version != PCP_KEY_VERSION) {
|
||||
fatal("Secretkey sanity check: unknown key version (expected: %08X, got: %08X)!\n",
|
||||
fatal(ptx, "Secretkey sanity check: unknown key version (expected: %08X, got: %08X)!\n",
|
||||
PCP_KEY_VERSION, key->version);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(key->serial <= 0) {
|
||||
fatal("Secretkey sanity check: invalid serial number: %08X!\n", key->serial);
|
||||
fatal(ptx, "Secretkey sanity check: invalid serial number: %08X!\n", key->serial);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -433,7 +433,7 @@ int pcp_sanitycheck_key(pcp_key_t *key) {
|
||||
char *got = ucmalloc(17);
|
||||
memcpy(got, key->id, 17);
|
||||
got[16] = '\0';
|
||||
fatal("Secretkey sanity check: invalid key id (expected 16 bytes, got: %s)!\n", got);
|
||||
fatal(ptx, "Secretkey sanity check: invalid key id (expected 16 bytes, got: %s)!\n", got);
|
||||
free(got);
|
||||
return 1;
|
||||
}
|
||||
@@ -443,13 +443,13 @@ int pcp_sanitycheck_key(pcp_key_t *key) {
|
||||
c = localtime(&t);
|
||||
if(c->tm_year <= 70 || c->tm_year > 1100) {
|
||||
/* well, I'm perhaps overacting here :) */
|
||||
fatal("Secretkey sanity check: invalid creation timestamp (got year %04d)!\n", c->tm_year + 1900);
|
||||
fatal(ptx, "Secretkey sanity check: invalid creation timestamp (got year %04d)!\n", c->tm_year + 1900);
|
||||
return 1;
|
||||
}
|
||||
|
||||
pcp_key_t *maybe = pcphash_keyexists(key->id);
|
||||
pcp_key_t *maybe = pcphash_keyexists(ptx, key->id);
|
||||
if(maybe != NULL) {
|
||||
fatal("Secretkey sanity check: there already exists a key with the id 0x%s\n", key->id);
|
||||
fatal(ptx, "Secretkey sanity check: there already exists a key with the id 0x%s\n", key->id);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -22,102 +22,87 @@
|
||||
|
||||
#include "keyhash.h"
|
||||
|
||||
pcp_key_t *pcpkey_hash;
|
||||
pcp_pubkey_t *pcppubkey_hash;
|
||||
pcp_keysig_t *pcpkeysig_hash;
|
||||
|
||||
pcp_key_t *__k;
|
||||
pcp_pubkey_t *__p;
|
||||
pcp_keysig_t *__s;
|
||||
|
||||
void pcphash_init() {
|
||||
pcpkey_hash = NULL;
|
||||
pcppubkey_hash = NULL;
|
||||
pcpkeysig_hash = NULL;
|
||||
}
|
||||
|
||||
void pcphash_del(void *key, int type) {
|
||||
void pcphash_del(PCPCTX *ptx, void *key, int type) {
|
||||
if(type == PCP_KEY_TYPE_SECRET) {
|
||||
HASH_DEL(pcpkey_hash, (pcp_key_t *)key);
|
||||
HASH_DEL(ptx->pcpkey_hash, (pcp_key_t *)key);
|
||||
memset(key, 0, sizeof(pcp_key_t));
|
||||
}
|
||||
else if(type == PCP_KEYSIG_NATIVE || type == PCP_KEYSIG_PBP) {
|
||||
pcp_keysig_t *keysig = (pcp_keysig_t *)key;
|
||||
memset(keysig->blob, 0, keysig->size);
|
||||
free(keysig->blob);
|
||||
HASH_DEL(pcpkeysig_hash, (pcp_keysig_t *)key);
|
||||
HASH_DEL(ptx->pcpkeysig_hash, (pcp_keysig_t *)key);
|
||||
}
|
||||
else {
|
||||
HASH_DEL(pcppubkey_hash, (pcp_pubkey_t *)key);
|
||||
HASH_DEL(ptx->pcppubkey_hash, (pcp_pubkey_t *)key);
|
||||
memset(key, 0, sizeof(pcp_pubkey_t));
|
||||
}
|
||||
free(key);
|
||||
}
|
||||
|
||||
void pcphash_clean() {
|
||||
if(pcpkey_hash != NULL) {
|
||||
void pcphash_clean(PCPCTX *ptx) {
|
||||
if(ptx->pcpkey_hash != NULL) {
|
||||
pcp_key_t *current_key, *tmp;
|
||||
HASH_ITER(hh, pcpkey_hash, current_key, tmp) {
|
||||
pcphash_del(current_key, PCP_KEY_TYPE_SECRET);
|
||||
HASH_ITER(hh, ptx->pcpkey_hash, current_key, tmp) {
|
||||
pcphash_del(ptx, current_key, PCP_KEY_TYPE_SECRET);
|
||||
}
|
||||
}
|
||||
|
||||
if(pcppubkey_hash != NULL) {
|
||||
if(ptx->pcppubkey_hash != NULL) {
|
||||
pcp_pubkey_t *current_pub, *ptmp;
|
||||
HASH_ITER(hh, pcppubkey_hash, current_pub, ptmp) {
|
||||
pcphash_del(current_pub, PCP_KEY_TYPE_PUBLIC);
|
||||
HASH_ITER(hh, ptx->pcppubkey_hash, current_pub, ptmp) {
|
||||
pcphash_del(ptx, current_pub, PCP_KEY_TYPE_PUBLIC);
|
||||
}
|
||||
}
|
||||
|
||||
if(pcpkeysig_hash != NULL) {
|
||||
if(ptx->pcpkeysig_hash != NULL) {
|
||||
pcp_keysig_t *current_keysig, *tmp;
|
||||
HASH_ITER(hh, pcpkeysig_hash, current_keysig, tmp) {
|
||||
pcphash_del(current_keysig, current_keysig->type);
|
||||
HASH_ITER(hh, ptx->pcpkeysig_hash, current_keysig, tmp) {
|
||||
pcphash_del(ptx, current_keysig, current_keysig->type);
|
||||
}
|
||||
}
|
||||
|
||||
pcphash_init();
|
||||
}
|
||||
|
||||
|
||||
pcp_keysig_t *pcphash_keysigexists(char *id) {
|
||||
pcp_keysig_t *pcphash_keysigexists(PCPCTX *ptx, char *id) {
|
||||
pcp_keysig_t *keysig = NULL;
|
||||
HASH_FIND_STR(pcpkeysig_hash, id, keysig);
|
||||
HASH_FIND_STR(ptx->pcpkeysig_hash, id, keysig);
|
||||
return keysig; /* maybe NULL! */
|
||||
}
|
||||
|
||||
pcp_key_t *pcphash_keyexists(char *id) {
|
||||
pcp_key_t *pcphash_keyexists(PCPCTX *ptx, char *id) {
|
||||
pcp_key_t *key = NULL;
|
||||
HASH_FIND_STR(pcpkey_hash, id, key);
|
||||
HASH_FIND_STR(ptx->pcpkey_hash, id, key);
|
||||
return key; /* maybe NULL! */
|
||||
}
|
||||
|
||||
pcp_pubkey_t *pcphash_pubkeyexists(char *id) {
|
||||
pcp_pubkey_t *pcphash_pubkeyexists(PCPCTX *ptx, char *id) {
|
||||
pcp_pubkey_t *key = NULL;
|
||||
HASH_FIND_STR(pcppubkey_hash, id, key);
|
||||
HASH_FIND_STR(ptx->pcppubkey_hash, id, key);
|
||||
return key; /* maybe NULL! */
|
||||
}
|
||||
|
||||
void pcphash_add(void *key, int type) {
|
||||
void pcphash_add(PCPCTX *ptx, void *key, int type) {
|
||||
if(type == PCP_KEY_TYPE_PUBLIC) {
|
||||
pcp_pubkey_t *k = (pcp_pubkey_t *)key;
|
||||
HASH_ADD_STR( pcppubkey_hash, id, k );
|
||||
HASH_ADD_STR( ptx->pcppubkey_hash, id, k );
|
||||
}
|
||||
else if(type == PCP_KEYSIG_NATIVE || type == PCP_KEYSIG_PBP) {
|
||||
pcp_keysig_t *keysig = (pcp_keysig_t *)key;
|
||||
HASH_ADD_STR( pcpkeysig_hash, id, keysig);
|
||||
HASH_ADD_STR( ptx->pcpkeysig_hash, id, keysig);
|
||||
}
|
||||
else {
|
||||
pcp_key_t *k = (pcp_key_t *)key;
|
||||
HASH_ADD_STR( pcpkey_hash, id, k);
|
||||
HASH_ADD_STR( ptx->pcpkey_hash, id, k);
|
||||
}
|
||||
}
|
||||
|
||||
int pcphash_count() {
|
||||
return HASH_COUNT(pcpkey_hash);
|
||||
int pcphash_count(PCPCTX *ptx) {
|
||||
return HASH_COUNT(ptx->pcpkey_hash);
|
||||
}
|
||||
|
||||
int pcphash_countpub() {
|
||||
return HASH_COUNT(pcppubkey_hash);
|
||||
int pcphash_countpub(PCPCTX *ptx) {
|
||||
return HASH_COUNT(ptx->pcppubkey_hash);
|
||||
}
|
||||
|
||||
|
||||
@@ -35,37 +35,37 @@ int _get_pk(Buffer *blob, pcp_pubkey_t *p) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
int _check_keysig_h(Buffer *blob, rfc_pub_sig_h *h) {
|
||||
int _check_keysig_h(PCPCTX *ptx, Buffer *blob, rfc_pub_sig_h *h) {
|
||||
if(buffer_left(blob) >= sizeof(rfc_pub_sig_h)) {
|
||||
buffer_get_chunk(blob, h, sizeof(rfc_pub_sig_h));
|
||||
|
||||
h->numsubs = be16toh(h->numsubs);
|
||||
|
||||
if(h->version != EXP_SIG_VERSION) {
|
||||
fatal("Unsupported pubkey signature version %d, expected %d", h->version, EXP_SIG_VERSION);
|
||||
fatal(ptx, "Unsupported pubkey signature version %d, expected %d", h->version, EXP_SIG_VERSION);
|
||||
return 1;
|
||||
}
|
||||
if(h->type != EXP_SIG_TYPE) {
|
||||
fatal("Unsupported pubkey signature type %d, expected %d", h->type, EXP_SIG_TYPE);
|
||||
fatal(ptx, "Unsupported pubkey signature type %d, expected %d", h->type, EXP_SIG_TYPE);
|
||||
return 1;
|
||||
}
|
||||
if(h->pkcipher != EXP_SIG_CIPHER) {
|
||||
fatal("Unsupported pubkey signature cipher %d, expected %d", h->pkcipher, EXP_SIG_CIPHER);
|
||||
fatal(ptx, "Unsupported pubkey signature cipher %d, expected %d", h->pkcipher, EXP_SIG_CIPHER);
|
||||
return 1;
|
||||
}
|
||||
if(h->hashcipher != EXP_HASH_CIPHER) {
|
||||
fatal("Unsupported pubkey signature hash cipher %d, expected %d", h->hashcipher, EXP_HASH_CIPHER);
|
||||
fatal(ptx, "Unsupported pubkey signature hash cipher %d, expected %d", h->hashcipher, EXP_HASH_CIPHER);
|
||||
return 1;
|
||||
}
|
||||
if(h->numsubs > 0 && buffer_left(blob) < sizeof(rfc_pub_sig_s) * h->numsubs) {
|
||||
fatal("Signature size specification invalid (sig: %ld, bytes left: %ld, numsubs: %ld",
|
||||
fatal(ptx, "Signature size specification invalid (sig: %ld, bytes left: %ld, numsubs: %ld",
|
||||
sizeof(rfc_pub_sig_s) * h->numsubs, buffer_left(blob), h->numsubs);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
fatal("Error: input data too small, import failed");
|
||||
fatal(ptx, "Error: input data too small, import failed");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@@ -108,7 +108,7 @@ int _check_sigsubs(Buffer *blob, pcp_pubkey_t *p, rfc_pub_sig_s *subheader) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _check_hash_keysig(Buffer *blob, pcp_pubkey_t *p, pcp_keysig_t *sk) {
|
||||
int _check_hash_keysig(PCPCTX *ptx, Buffer *blob, pcp_pubkey_t *p, pcp_keysig_t *sk) {
|
||||
// read hash + sig
|
||||
size_t blobstop = blob->offset;
|
||||
size_t sigsize = crypto_sign_BYTES + crypto_generichash_BYTES_MAX;
|
||||
@@ -130,7 +130,7 @@ int _check_hash_keysig(Buffer *blob, pcp_pubkey_t *p, pcp_keysig_t *sk) {
|
||||
buffer_get_chunk(blob, sk->blob, sk->size);
|
||||
|
||||
/* verify the signature */
|
||||
byte *verifyhash = pcp_ed_verify_key(signature, sigsize, p);
|
||||
byte *verifyhash = pcp_ed_verify_key(ptx, signature, sigsize, p);
|
||||
if(verifyhash == NULL)
|
||||
goto chker1;
|
||||
|
||||
@@ -143,7 +143,7 @@ int _check_hash_keysig(Buffer *blob, pcp_pubkey_t *p, pcp_keysig_t *sk) {
|
||||
|
||||
/* compare them */
|
||||
if(memcmp(hash, verifyhash, crypto_generichash_BYTES_MAX) != 0) {
|
||||
fatal("Signature verifies but signed hash doesn't match signature contents\n");
|
||||
fatal(ptx, "Signature verifies but signed hash doesn't match signature contents\n");
|
||||
goto chker2;
|
||||
}
|
||||
|
||||
@@ -172,7 +172,7 @@ int _check_hash_keysig(Buffer *blob, pcp_pubkey_t *p, pcp_keysig_t *sk) {
|
||||
|
||||
}
|
||||
|
||||
pcp_ks_bundle_t *pcp_import_binpub(byte *raw, size_t rawsize) {
|
||||
pcp_ks_bundle_t *pcp_import_binpub(PCPCTX *ptx, byte *raw, size_t rawsize) {
|
||||
Buffer *blob = buffer_new(512, "importblob");
|
||||
|
||||
buffer_add(blob, raw, rawsize);
|
||||
@@ -182,35 +182,35 @@ pcp_ks_bundle_t *pcp_import_binpub(byte *raw, size_t rawsize) {
|
||||
|
||||
if(version == PCP_KEY_VERSION) {
|
||||
/* ah, homerun */
|
||||
return pcp_import_pub_rfc(blob);
|
||||
return pcp_import_pub_rfc(ptx, blob);
|
||||
}
|
||||
else {
|
||||
/* nope, it's probably pbp */
|
||||
return pcp_import_pub_pbp(blob);
|
||||
return pcp_import_pub_pbp(ptx, blob);
|
||||
}
|
||||
}
|
||||
|
||||
pcp_ks_bundle_t *pcp_import_pub(byte *raw, size_t rawsize) {
|
||||
pcp_ks_bundle_t *pcp_import_pub(PCPCTX *ptx, byte *raw, size_t rawsize) {
|
||||
size_t clen;
|
||||
byte *bin = NULL;
|
||||
char *z85 = NULL;
|
||||
|
||||
if(rawsize == 0) {
|
||||
fatal("Input file is empty!\n");
|
||||
fatal(ptx, "Input file is empty!\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Buffer *blob = buffer_new(512, "importblob");
|
||||
|
||||
/* first, try to decode the input */
|
||||
z85 = pcp_readz85string(raw, rawsize);
|
||||
z85 = pcp_readz85string(ptx, raw, rawsize);
|
||||
|
||||
if(z85 != NULL)
|
||||
bin = pcp_z85_decode(z85, &clen);
|
||||
bin = pcp_z85_decode(ptx, z85, &clen);
|
||||
|
||||
if(bin == NULL) {
|
||||
/* treat as binary blob */
|
||||
fatals_reset();
|
||||
fatals_reset(ptx);
|
||||
buffer_add(blob, raw, rawsize);
|
||||
}
|
||||
else {
|
||||
@@ -224,15 +224,15 @@ pcp_ks_bundle_t *pcp_import_pub(byte *raw, size_t rawsize) {
|
||||
|
||||
if(version == PCP_KEY_VERSION) {
|
||||
/* ah, homerun */
|
||||
return pcp_import_pub_rfc(blob);
|
||||
return pcp_import_pub_rfc(ptx, blob);
|
||||
}
|
||||
else {
|
||||
/* nope, it's probably pbp */
|
||||
return pcp_import_pub_pbp(blob);
|
||||
return pcp_import_pub_pbp(ptx, blob);
|
||||
}
|
||||
}
|
||||
|
||||
pcp_ks_bundle_t *pcp_import_pub_rfc(Buffer *blob) {
|
||||
pcp_ks_bundle_t *pcp_import_pub_rfc(PCPCTX *ptx, Buffer *blob) {
|
||||
pcp_pubkey_t *p = ucmalloc(sizeof(pcp_pubkey_t));
|
||||
pcp_keysig_t *sk = ucmalloc(sizeof(pcp_keysig_t));
|
||||
rfc_pub_sig_h *sigheader = ucmalloc(sizeof(rfc_pub_sig_h));
|
||||
@@ -245,7 +245,7 @@ pcp_ks_bundle_t *pcp_import_pub_rfc(Buffer *blob) {
|
||||
if(buffer_done(blob)) goto be;
|
||||
|
||||
if(pkcipher != EXP_PK_CIPHER) {
|
||||
fatal("Unsupported pk cipher %d, expected %d", pkcipher, EXP_PK_CIPHER);
|
||||
fatal(ptx, "Unsupported pk cipher %d, expected %d", pkcipher, EXP_PK_CIPHER);
|
||||
goto bef;
|
||||
}
|
||||
|
||||
@@ -254,7 +254,7 @@ pcp_ks_bundle_t *pcp_import_pub_rfc(Buffer *blob) {
|
||||
goto be;
|
||||
|
||||
/* check sig header */
|
||||
if(_check_keysig_h(blob, sigheader) != 0)
|
||||
if(_check_keysig_h(ptx, blob, sigheader) != 0)
|
||||
goto bef;
|
||||
|
||||
/* iterate over subs, if any */
|
||||
@@ -277,7 +277,7 @@ pcp_ks_bundle_t *pcp_import_pub_rfc(Buffer *blob) {
|
||||
pcp_ks_bundle_t *b = ucmalloc(sizeof(pcp_ks_bundle_t));
|
||||
|
||||
/* retrieve signature, store and verify it */
|
||||
if(_check_hash_keysig(blob, p, sk) != 0) {
|
||||
if(_check_hash_keysig(ptx, blob, p, sk) != 0) {
|
||||
b->p = p;
|
||||
b->s = NULL;
|
||||
}
|
||||
@@ -290,7 +290,7 @@ pcp_ks_bundle_t *pcp_import_pub_rfc(Buffer *blob) {
|
||||
|
||||
|
||||
be:
|
||||
fatal("Error: input data too small, import failed");
|
||||
fatal(ptx, "Error: input data too small, import failed");
|
||||
|
||||
bef:
|
||||
buffer_free(blob);
|
||||
@@ -300,7 +300,7 @@ pcp_ks_bundle_t *pcp_import_pub_rfc(Buffer *blob) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pcp_ks_bundle_t *pcp_import_pub_pbp(Buffer *blob) {
|
||||
pcp_ks_bundle_t *pcp_import_pub_pbp(PCPCTX *ptx, Buffer *blob) {
|
||||
char *date = ucmalloc(19);
|
||||
char *ignore = ucmalloc(46);
|
||||
char *parts = NULL;
|
||||
@@ -314,7 +314,7 @@ pcp_ks_bundle_t *pcp_import_pub_pbp(Buffer *blob) {
|
||||
|
||||
/* make sure it's a pbp */
|
||||
if(_buffer_is_binary(sig, crypto_sign_BYTES) == 0) {
|
||||
fatal("failed to recognize input, that's probably no key\n");
|
||||
fatal(ptx, "failed to recognize input, that's probably no key\n");
|
||||
goto errimp2;
|
||||
}
|
||||
|
||||
@@ -326,7 +326,7 @@ pcp_ks_bundle_t *pcp_import_pub_pbp(Buffer *blob) {
|
||||
date[19] = '\0';
|
||||
struct tm c;
|
||||
if(strptime(date, "%Y-%m-%dT%H:%M:%S", &c) == NULL) {
|
||||
fatal("Failed to parse creation time in PBP public key file (<%s>)\n", date);
|
||||
fatal(ptx, "Failed to parse creation time in PBP public key file (<%s>)\n", date);
|
||||
free(date);
|
||||
goto errimp2;
|
||||
}
|
||||
@@ -365,7 +365,7 @@ pcp_ks_bundle_t *pcp_import_pub_pbp(Buffer *blob) {
|
||||
/* edpub used for signing, might differ */
|
||||
memcpy(tmp->edpub, b->sigpub, crypto_sign_PUBLICKEYBYTES);
|
||||
|
||||
byte *verify = pcp_ed_verify(buffer_get(blob), buffer_size(blob), tmp);
|
||||
byte *verify = pcp_ed_verify(ptx, buffer_get(blob), buffer_size(blob), tmp);
|
||||
free(tmp);
|
||||
|
||||
pcp_ks_bundle_t *bundle = ucmalloc(sizeof(pcp_ks_bundle_t));
|
||||
@@ -671,7 +671,7 @@ Buffer *pcp_export_rfc_pub (pcp_key_t *sk) {
|
||||
return out;
|
||||
}
|
||||
|
||||
Buffer *pcp_export_secret(pcp_key_t *sk, char *passphrase) {
|
||||
Buffer *pcp_export_secret(PCPCTX *ptx, pcp_key_t *sk, char *passphrase) {
|
||||
byte *nonce = NULL;
|
||||
byte *symkey = NULL;
|
||||
byte *cipher = NULL;
|
||||
@@ -708,7 +708,7 @@ Buffer *pcp_export_secret(pcp_key_t *sk, char *passphrase) {
|
||||
|
||||
nonce = ucmalloc(crypto_secretbox_NONCEBYTES);
|
||||
arc4random_buf(nonce, crypto_secretbox_NONCEBYTES);
|
||||
symkey = pcp_scrypt(passphrase, strlen(passphrase), nonce, crypto_secretbox_NONCEBYTES);
|
||||
symkey = pcp_scrypt(ptx, passphrase, strlen(passphrase), nonce, crypto_secretbox_NONCEBYTES);
|
||||
|
||||
es = pcp_sodium_mac(&cipher, buffer_get(raw), buffer_size(raw), nonce, symkey);
|
||||
|
||||
@@ -723,33 +723,33 @@ Buffer *pcp_export_secret(pcp_key_t *sk, char *passphrase) {
|
||||
return out;
|
||||
}
|
||||
|
||||
pcp_key_t *pcp_import_binsecret(byte *raw, size_t rawsize, char *passphrase) {
|
||||
pcp_key_t *pcp_import_binsecret(PCPCTX *ptx, byte *raw, size_t rawsize, char *passphrase) {
|
||||
Buffer *blob = buffer_new(512, "importskblob");
|
||||
buffer_add(blob, raw, rawsize);
|
||||
return pcp_import_secret_native(blob, passphrase);
|
||||
return pcp_import_secret_native(ptx, blob, passphrase);
|
||||
}
|
||||
|
||||
|
||||
pcp_key_t *pcp_import_secret(byte *raw, size_t rawsize, char *passphrase) {
|
||||
pcp_key_t *pcp_import_secret(PCPCTX *ptx, byte *raw, size_t rawsize, char *passphrase) {
|
||||
size_t clen;
|
||||
byte *bin = NULL;
|
||||
char *z85 = NULL;
|
||||
|
||||
if(rawsize == 0) {
|
||||
fatal("Input file is empty!\n");
|
||||
fatal(ptx, "Input file is empty!\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Buffer *blob = buffer_new(512, "importskblob");
|
||||
|
||||
/* first, try to decode the input */
|
||||
z85 = pcp_readz85string(raw, rawsize);
|
||||
z85 = pcp_readz85string(ptx, raw, rawsize);
|
||||
if(z85 != NULL)
|
||||
bin = pcp_z85_decode(z85, &clen);
|
||||
bin = pcp_z85_decode(ptx, z85, &clen);
|
||||
|
||||
if(bin == NULL) {
|
||||
/* treat as binary blob */
|
||||
fatals_reset();
|
||||
fatals_reset(ptx);
|
||||
buffer_add(blob, raw, rawsize);
|
||||
}
|
||||
else {
|
||||
@@ -759,10 +759,10 @@ pcp_key_t *pcp_import_secret(byte *raw, size_t rawsize, char *passphrase) {
|
||||
}
|
||||
|
||||
/* now we've got the blob, parse it */
|
||||
return pcp_import_secret_native(blob, passphrase);
|
||||
return pcp_import_secret_native(ptx, blob, passphrase);
|
||||
}
|
||||
|
||||
pcp_key_t *pcp_import_secret_native(Buffer *cipher, char *passphrase) {
|
||||
pcp_key_t *pcp_import_secret_native(PCPCTX *ptx, Buffer *cipher, char *passphrase) {
|
||||
pcp_key_t *sk = ucmalloc(sizeof(pcp_key_t));
|
||||
byte *nonce = ucmalloc(crypto_secretbox_NONCEBYTES);
|
||||
byte *symkey = NULL;
|
||||
@@ -776,11 +776,11 @@ pcp_key_t *pcp_import_secret_native(Buffer *cipher, char *passphrase) {
|
||||
if(buffer_get_chunk(cipher, nonce, crypto_secretbox_NONCEBYTES) == 0)
|
||||
goto impserr1;
|
||||
|
||||
symkey = pcp_scrypt(passphrase, strlen(passphrase), nonce, crypto_secretbox_NONCEBYTES);
|
||||
symkey = pcp_scrypt(ptx, passphrase, strlen(passphrase), nonce, crypto_secretbox_NONCEBYTES);
|
||||
|
||||
cipherlen = buffer_left(cipher);
|
||||
if(cipherlen < minlen) {
|
||||
fatal("failed to decrypt the secret key file:\n"
|
||||
fatal(ptx, "failed to decrypt the secret key file:\n"
|
||||
"expected encrypted secret key size %ld is less than minimum len %ld\n", cipherlen, minlen);
|
||||
goto impserr1;
|
||||
}
|
||||
@@ -788,7 +788,7 @@ pcp_key_t *pcp_import_secret_native(Buffer *cipher, char *passphrase) {
|
||||
/* decrypt the blob */
|
||||
if(pcp_sodium_verify_mac(&clear, buffer_get_remainder(cipher),
|
||||
cipherlen, nonce, symkey) != 0) {
|
||||
fatal("failed to decrypt the secret key file\n");
|
||||
fatal(ptx, "failed to decrypt the secret key file\n");
|
||||
goto impserr1;
|
||||
}
|
||||
|
||||
|
||||
@@ -359,9 +359,7 @@ void ps_determine(Pcpstream *stream) {
|
||||
size_t ps_read_decode(Pcpstream *stream) {
|
||||
Buffer *z = buffer_new(32, "ztemp");
|
||||
Buffer *line = buffer_new_str("line");
|
||||
|
||||
//buffer_info(stream->save);
|
||||
|
||||
PCPCTX *ptx = ptx_new();
|
||||
|
||||
if(buffer_left(stream->save) > stream->blocksize){// && stream->firstread == 1) {
|
||||
/* use the save buffer instead */
|
||||
@@ -376,7 +374,7 @@ size_t ps_read_decode(Pcpstream *stream) {
|
||||
// fprintf(stderr, " ps_read_next which doesn't end in a newline\n");
|
||||
buffer_get_chunk_tobuf(stream->save, z, buffer_left(stream->save));
|
||||
//buffer_dump(z);
|
||||
fatals_ifany();
|
||||
//fatals_ifany();
|
||||
}
|
||||
else {
|
||||
/* continue reading linewise */
|
||||
@@ -435,10 +433,10 @@ size_t ps_read_decode(Pcpstream *stream) {
|
||||
|
||||
/* finally, decode it and put into next */
|
||||
size_t binlen, outlen;
|
||||
byte *bin = pcp_z85_decode(buffer_get_str(z), &binlen);
|
||||
byte *bin = pcp_z85_decode(ptx, buffer_get_str(z), &binlen);
|
||||
//fprintf(stderr, "ps_read_decode decoding z: %ld, got: %ld\n", buffer_size(z), binlen);
|
||||
// _dump("bin", bin, binlen);
|
||||
fatals_ifany();
|
||||
//fatals_ifany();
|
||||
if(bin == NULL) {
|
||||
/* it's not z85 encoded, so threat it as binary */
|
||||
if(stream->firstread) {
|
||||
@@ -461,7 +459,7 @@ size_t ps_read_decode(Pcpstream *stream) {
|
||||
|
||||
buffer_free(z);
|
||||
buffer_free(line);
|
||||
|
||||
ptx_clean(ptx);
|
||||
|
||||
return outlen;
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
|
||||
#include "scrypt.h"
|
||||
|
||||
byte* pcp_scrypt(char *passwd, size_t passwdlen, byte *nonce, size_t noncelen) {
|
||||
byte* pcp_scrypt(PCPCTX *ptx, char *passwd, size_t passwdlen, byte *nonce, size_t noncelen) {
|
||||
uint8_t *dk = ucmalloc(64); /* resulting hash */
|
||||
|
||||
/* constants */
|
||||
@@ -34,7 +34,7 @@ byte* pcp_scrypt(char *passwd, size_t passwdlen, byte *nonce, size_t noncelen) {
|
||||
return dk;
|
||||
}
|
||||
else {
|
||||
fatal("crypto_scrypt() failed");
|
||||
fatal(ptx, "crypto_scrypt() failed");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
108
libpcp/vault.c
108
libpcp/vault.c
@@ -24,19 +24,19 @@
|
||||
#include "keyhash.h"
|
||||
#include "defines.h"
|
||||
|
||||
vault_t *pcpvault_init(char *filename) {
|
||||
vault_t *vault = pcpvault_new(filename, 0);
|
||||
vault_t *pcpvault_init(PCPCTX *ptx, char *filename) {
|
||||
vault_t *vault = pcpvault_new(ptx, filename, 0);
|
||||
if(vault != NULL) {
|
||||
if(vault->isnew == 1) {
|
||||
if(pcpvault_create(vault) != 0) {
|
||||
pcpvault_close(vault);
|
||||
if(pcpvault_create(ptx, vault) != 0) {
|
||||
pcpvault_close(ptx, vault);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if(pcpvault_fetchall(vault) != 0) {
|
||||
if(pcpvault_fetchall(ptx, vault) != 0) {
|
||||
errno = 0; /* weird, something sets it to ENOENT and it's not me */
|
||||
pcpvault_close(vault);
|
||||
pcpvault_close(ptx, vault);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
@@ -44,7 +44,7 @@ vault_t *pcpvault_init(char *filename) {
|
||||
return vault;
|
||||
}
|
||||
|
||||
vault_t *pcpvault_new(char *filename, int is_tmp) {
|
||||
vault_t *pcpvault_new(PCPCTX *ptx, char *filename, int is_tmp) {
|
||||
vault_t *vault = ucmalloc(sizeof(vault_t));
|
||||
FILE *fd;
|
||||
struct stat stat_buf;
|
||||
@@ -82,7 +82,7 @@ vault_t *pcpvault_new(char *filename, int is_tmp) {
|
||||
vault->isnew = 1;
|
||||
mode_t old_mask = umask (S_IWGRP | S_IWOTH | S_IRGRP | S_IROTH);
|
||||
if((fd = fopen(vault->filename, "wb+")) == NULL) {
|
||||
fatal("Could not create vault file %s", vault->filename);
|
||||
fatal(ptx, "Could not create vault file %s", vault->filename);
|
||||
umask (old_mask);
|
||||
goto errn;
|
||||
}
|
||||
@@ -90,7 +90,7 @@ vault_t *pcpvault_new(char *filename, int is_tmp) {
|
||||
}
|
||||
else {
|
||||
if((fd = fopen(vault->filename, "rb+")) == NULL) {
|
||||
fatal("Could not open vault file %s", vault->filename);
|
||||
fatal(ptx, "Could not open vault file %s", vault->filename);
|
||||
goto errn;
|
||||
}
|
||||
}
|
||||
@@ -105,7 +105,7 @@ vault_t *pcpvault_new(char *filename, int is_tmp) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int pcpvault_create(vault_t *vault) {
|
||||
int pcpvault_create(PCPCTX *ptx, vault_t *vault) {
|
||||
vault_header_t *header = ucmalloc(sizeof(vault_header_t));
|
||||
header->fileid = PCP_VAULT_ID;
|
||||
header->version = PCP_VAULT_VERSION;
|
||||
@@ -120,7 +120,7 @@ int pcpvault_create(vault_t *vault) {
|
||||
fwrite(header, sizeof(vault_header_t), 1, vault->fd);
|
||||
|
||||
if(ferror(vault->fd) != 0) {
|
||||
fatal("Failed to write fileheader to vault %s!\n", vault->filename);
|
||||
fatal(ptx, "Failed to write fileheader to vault %s!\n", vault->filename);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -129,7 +129,7 @@ int pcpvault_create(vault_t *vault) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pcpvault_additem(vault_t *vault, void *item, size_t itemsize, uint8_t type) {
|
||||
int pcpvault_additem(PCPCTX *ptx, vault_t *vault, void *item, size_t itemsize, uint8_t type) {
|
||||
vault_item_header_t *header = ucmalloc(sizeof(vault_item_header_t));
|
||||
header->type = type;
|
||||
header->size = itemsize;
|
||||
@@ -141,7 +141,7 @@ int pcpvault_additem(vault_t *vault, void *item, size_t itemsize, uint8_t type)
|
||||
fwrite(item, itemsize, 1, vault->fd);
|
||||
|
||||
if(ferror(vault->fd) != 0) {
|
||||
fatal("Failed to add an item to vault %s!\n", vault->filename);
|
||||
fatal(ptx, "Failed to add an item to vault %s!\n", vault->filename);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -151,8 +151,8 @@ int pcpvault_additem(vault_t *vault, void *item, size_t itemsize, uint8_t type)
|
||||
|
||||
}
|
||||
|
||||
int pcpvault_addkey(vault_t *vault, void *item, uint8_t type) {
|
||||
vault_t *tmp = pcpvault_new(vault->filename, 1);
|
||||
int pcpvault_addkey(PCPCTX *ptx, vault_t *vault, void *item, uint8_t type) {
|
||||
vault_t *tmp = pcpvault_new(ptx, vault->filename, 1);
|
||||
size_t itemsize;
|
||||
|
||||
void *saveitem = NULL;
|
||||
@@ -183,15 +183,15 @@ int pcpvault_addkey(vault_t *vault, void *item, uint8_t type) {
|
||||
|
||||
|
||||
if(tmp != NULL) {
|
||||
if(pcpvault_copy(vault, tmp) != 0)
|
||||
if(pcpvault_copy(ptx, vault, tmp) != 0)
|
||||
goto errak1;
|
||||
if(pcpvault_additem(tmp, buffer_get(blob), itemsize, type) != 0)
|
||||
if(pcpvault_additem(ptx, tmp, buffer_get(blob), itemsize, type) != 0)
|
||||
goto errak1;
|
||||
|
||||
pcphash_add(saveitem, type);
|
||||
pcpvault_update_checksum(tmp);
|
||||
pcphash_add(ptx, saveitem, type);
|
||||
pcpvault_update_checksum(ptx, tmp);
|
||||
|
||||
if(pcpvault_copy(tmp, vault) == 0) {
|
||||
if(pcpvault_copy(ptx, tmp, vault) == 0) {
|
||||
pcpvault_unlink(tmp);
|
||||
}
|
||||
else {
|
||||
@@ -212,32 +212,32 @@ int pcpvault_addkey(vault_t *vault, void *item, uint8_t type) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
int pcpvault_writeall(vault_t *vault) {
|
||||
vault_t *tmp = pcpvault_new(vault->filename, 1);
|
||||
int pcpvault_writeall(PCPCTX *ptx, vault_t *vault) {
|
||||
vault_t *tmp = pcpvault_new(ptx, vault->filename, 1);
|
||||
|
||||
if(tmp != NULL) {
|
||||
if(pcpvault_create(tmp) == 0) {
|
||||
if(pcpvault_create(ptx, tmp) == 0) {
|
||||
pcp_key_t *k = NULL;
|
||||
Buffer *blob = buffer_new(PCP_RAW_PUBKEYSIZE, "bs");
|
||||
pcphash_iterate(k) {
|
||||
pcphash_iterate(ptx, k) {
|
||||
pcp_seckeyblob(blob, k);
|
||||
if(pcpvault_additem(tmp, buffer_get(blob), PCP_RAW_KEYSIZE, PCP_KEY_TYPE_SECRET) != 0) {
|
||||
if(pcpvault_additem(ptx, tmp, buffer_get(blob), PCP_RAW_KEYSIZE, PCP_KEY_TYPE_SECRET) != 0) {
|
||||
buffer_free(blob);
|
||||
goto errwa;
|
||||
}
|
||||
buffer_clear(blob);
|
||||
}
|
||||
pcp_pubkey_t *p = NULL;
|
||||
pcphash_iteratepub(p) {
|
||||
pcphash_iteratepub(ptx, p) {
|
||||
pcp_pubkeyblob(blob, p);
|
||||
if(pcpvault_additem(tmp, buffer_get(blob), PCP_RAW_PUBKEYSIZE, PCP_KEY_TYPE_PUBLIC) != 0) {
|
||||
if(pcpvault_additem(ptx, tmp, buffer_get(blob), PCP_RAW_PUBKEYSIZE, PCP_KEY_TYPE_PUBLIC) != 0) {
|
||||
buffer_free(blob);
|
||||
goto errwa;
|
||||
}
|
||||
buffer_clear(blob);
|
||||
}
|
||||
pcpvault_update_checksum(tmp);
|
||||
if(pcpvault_copy(tmp, vault) == 0) {
|
||||
pcpvault_update_checksum(ptx, tmp);
|
||||
if(pcpvault_copy(ptx, tmp, vault) == 0) {
|
||||
pcpvault_unlink(tmp);
|
||||
}
|
||||
free(tmp);
|
||||
@@ -256,8 +256,8 @@ int pcpvault_writeall(vault_t *vault) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
void pcpvault_update_checksum(vault_t *vault) {
|
||||
byte *checksum = pcpvault_create_checksum();
|
||||
void pcpvault_update_checksum(PCPCTX *ptx, vault_t *vault) {
|
||||
byte *checksum = pcpvault_create_checksum(ptx);
|
||||
|
||||
vault_header_t *header = ucmalloc(sizeof(vault_header_t));
|
||||
header->fileid = PCP_VAULT_ID;
|
||||
@@ -272,20 +272,20 @@ void pcpvault_update_checksum(vault_t *vault) {
|
||||
fseek(vault->fd, 0, SEEK_END);
|
||||
}
|
||||
|
||||
byte *pcpvault_create_checksum() {
|
||||
byte *pcpvault_create_checksum(PCPCTX *ptx) {
|
||||
pcp_key_t *k = NULL;
|
||||
Buffer *blob = NULL;
|
||||
size_t datapos = 0;
|
||||
|
||||
int numskeys = pcphash_count();
|
||||
int numpkeys = pcphash_countpub();
|
||||
int numskeys = pcphash_count(ptx);
|
||||
int numpkeys = pcphash_countpub(ptx);
|
||||
|
||||
size_t datasize = ((PCP_RAW_KEYSIZE) * numskeys) +
|
||||
((PCP_RAW_PUBKEYSIZE) * numpkeys);
|
||||
byte *data = ucmalloc(datasize);
|
||||
byte *checksum = ucmalloc(32);
|
||||
|
||||
pcphash_iterate(k) {
|
||||
pcphash_iterate(ptx, k) {
|
||||
key2be(k);
|
||||
blob = pcp_keyblob(k, PCP_KEY_TYPE_SECRET);
|
||||
memcpy(&data[datapos], buffer_get(blob), PCP_RAW_KEYSIZE);
|
||||
@@ -295,7 +295,7 @@ byte *pcpvault_create_checksum() {
|
||||
}
|
||||
|
||||
pcp_pubkey_t *p = NULL;
|
||||
pcphash_iteratepub(p) {
|
||||
pcphash_iteratepub(ptx, p) {
|
||||
/* pcp_dumppubkey(p); */
|
||||
pubkey2be(p);
|
||||
blob = pcp_keyblob(p, PCP_KEY_TYPE_PUBLIC);
|
||||
@@ -322,7 +322,7 @@ byte *pcpvault_create_checksum() {
|
||||
}
|
||||
|
||||
|
||||
int pcpvault_copy(vault_t *tmp, vault_t *vault) {
|
||||
int pcpvault_copy(PCPCTX *ptx, vault_t *tmp, vault_t *vault) {
|
||||
/* fetch tmp content */
|
||||
fseek(tmp->fd, 0, SEEK_END);
|
||||
int tmpsize = ftell(tmp->fd);
|
||||
@@ -333,13 +333,13 @@ int pcpvault_copy(vault_t *tmp, vault_t *vault) {
|
||||
/* and put it into the new file */
|
||||
vault->fd = freopen(vault->filename, "wb+", vault->fd);
|
||||
if(fwrite(in, tmpsize, 1, vault->fd) != 1) {
|
||||
fatal("Failed to copy %s to %s (write) [keeping %s]\n",
|
||||
fatal(ptx, "Failed to copy %s to %s (write) [keeping %s]\n",
|
||||
tmp->filename, vault->filename, tmp->filename);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(fflush(vault->fd) != 0) {
|
||||
fatal("Failed to copy %s to %s (flush) [keeping %s]\n",
|
||||
fatal(ptx, "Failed to copy %s to %s (flush) [keeping %s]\n",
|
||||
tmp->filename, vault->filename, tmp->filename);
|
||||
return 1;
|
||||
}
|
||||
@@ -363,11 +363,11 @@ void pcpvault_unlink(vault_t *tmp) {
|
||||
free(r);
|
||||
}
|
||||
|
||||
int pcpvault_close(vault_t *vault) {
|
||||
int pcpvault_close(PCPCTX *ptx, vault_t *vault) {
|
||||
if(vault != NULL) {
|
||||
if(vault->fd) {
|
||||
if(vault->unsafed == 1) {
|
||||
pcpvault_writeall(vault);
|
||||
pcpvault_writeall(ptx, vault);
|
||||
}
|
||||
fclose(vault->fd);
|
||||
}
|
||||
@@ -416,7 +416,7 @@ vault_item_header_t * ih2native(vault_item_header_t *h) {
|
||||
}
|
||||
|
||||
|
||||
int pcpvault_fetchall(vault_t *vault) {
|
||||
int pcpvault_fetchall(PCPCTX *ptx, vault_t *vault) {
|
||||
size_t got = 0;
|
||||
fseek(vault->fd, 0, SEEK_SET);
|
||||
|
||||
@@ -424,7 +424,7 @@ int pcpvault_fetchall(vault_t *vault) {
|
||||
vault_item_header_t *item = ucmalloc(sizeof(vault_item_header_t));
|
||||
got = fread(header, 1, sizeof(vault_header_t), vault->fd);
|
||||
if(got < sizeof(vault_header_t)) {
|
||||
fatal("empty or invalid vault header size (got %ld, expected %ld)\n", got, sizeof(vault_header_t));
|
||||
fatal(ptx, "empty or invalid vault header size (got %ld, expected %ld)\n", got, sizeof(vault_header_t));
|
||||
goto err;
|
||||
}
|
||||
vh2native(header);
|
||||
@@ -437,8 +437,6 @@ int pcpvault_fetchall(vault_t *vault) {
|
||||
int bytesleft = 0;
|
||||
int ksize = PCP_RAW_KEYSIGSIZE; /* smallest possbile item */
|
||||
|
||||
pcphash_init();
|
||||
|
||||
vault->version = header->version;
|
||||
memcpy(vault->checksum, header->checksum, 32);
|
||||
|
||||
@@ -461,34 +459,34 @@ int pcpvault_fetchall(vault_t *vault) {
|
||||
key = ucmalloc(sizeof(pcp_key_t));
|
||||
got = fread(key, PCP_RAW_KEYSIZE, 1, vault->fd);
|
||||
key2native(key);
|
||||
pcphash_add((void *)key, item->type);
|
||||
pcphash_add(ptx, (void *)key, item->type);
|
||||
}
|
||||
else if(item->type == PCP_KEY_TYPE_PUBLIC) {
|
||||
/* read a public key */
|
||||
pubkey = ucmalloc(sizeof(pcp_pubkey_t));
|
||||
got = fread(pubkey, PCP_RAW_PUBKEYSIZE, 1, vault->fd);
|
||||
pubkey2native(pubkey);
|
||||
pcphash_add((void *)pubkey, item->type);
|
||||
pcphash_add(ptx, (void *)pubkey, item->type);
|
||||
}
|
||||
else if(item->type == PCP_KEYSIG_NATIVE || item->type == PCP_KEYSIG_PBP) {
|
||||
Buffer *rawks = buffer_new(256, "keysig");
|
||||
buffer_fd_read(rawks, vault->fd, item->size);
|
||||
pcp_keysig_t *s = pcp_keysig_new(rawks);
|
||||
pcphash_add((void *)s, item->type);
|
||||
pcphash_add(ptx, (void *)s, item->type);
|
||||
buffer_free(rawks);
|
||||
}
|
||||
else {
|
||||
fatal("Failed to read vault - invalid key type: %02X! at %d\n", item->type, readpos);
|
||||
fatal(ptx, "Failed to read vault - invalid key type: %02X! at %d\n", item->type, readpos);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
else {
|
||||
fatal("Failed to read vault - that's no pcp key at %d (size %ld)!\n", readpos, bytesleft);
|
||||
fatal(ptx, "Failed to read vault - that's no pcp key at %d (size %ld)!\n", readpos, bytesleft);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
else {
|
||||
fatal("Failed to read vault - invalid key item header size at %d!\n",
|
||||
fatal(ptx, "Failed to read vault - invalid key item header size at %d!\n",
|
||||
readpos);
|
||||
goto err;
|
||||
}
|
||||
@@ -500,22 +498,22 @@ int pcpvault_fetchall(vault_t *vault) {
|
||||
}
|
||||
}
|
||||
else {
|
||||
fatal("Unexpected vault file format!\n");
|
||||
fatal(ptx, "Unexpected vault file format!\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
byte *checksum = NULL;
|
||||
checksum = pcpvault_create_checksum(vault);
|
||||
checksum = pcpvault_create_checksum(ptx);
|
||||
|
||||
/*
|
||||
_dump(" calc checksum", checksum, 32);
|
||||
_dump("vault checksum", vault->checksum, 32);
|
||||
*/
|
||||
|
||||
if(pcphash_count() + pcphash_countpub() > 0) {
|
||||
if(pcphash_count(ptx) + pcphash_countpub(ptx) > 0) {
|
||||
/* only validate the checksum if there are keys */
|
||||
if(memcmp(checksum, vault->checksum, 32) != 0) {
|
||||
fatal("Error: the checksum of the key vault doesn't match its contents!\n");
|
||||
fatal(ptx, "Error: the checksum of the key vault doesn't match its contents!\n");
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
18
libpcp/z85.c
18
libpcp/z85.c
@@ -182,7 +182,7 @@ size_t pcp_unpadfour(byte *src, size_t srclen) {
|
||||
return outlen;
|
||||
}
|
||||
|
||||
byte *pcp_z85_decode(char *z85block, size_t *dstlen) {
|
||||
byte *pcp_z85_decode(PCPCTX *ptx, char *z85block, size_t *dstlen) {
|
||||
byte *bin = NULL;
|
||||
size_t binlen, outlen;
|
||||
size_t srclen;
|
||||
@@ -199,7 +199,7 @@ byte *pcp_z85_decode(char *z85block, size_t *dstlen) {
|
||||
bin = ucmalloc(binlen);
|
||||
|
||||
if(zmq_z85_decode(bin, z85block) == NULL) {
|
||||
fatal("zmq_z85_decode() failed, input size ! mod 5 (got %ld)", strlen(z85block));
|
||||
fatal(ptx, "zmq_z85_decode() failed, input size ! mod 5 (got %ld)", strlen(z85block));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -251,7 +251,7 @@ char *pcp_z85_encode(byte *raw, size_t srclen, size_t *dstlen) {
|
||||
}
|
||||
|
||||
|
||||
char *pcp_readz85file(FILE *infile) {
|
||||
char *pcp_readz85file(PCPCTX *ptx, FILE *infile) {
|
||||
byte *input = NULL;
|
||||
byte *tmp = NULL;
|
||||
size_t bufsize = 0;
|
||||
@@ -269,25 +269,25 @@ char *pcp_readz85file(FILE *infile) {
|
||||
}
|
||||
|
||||
if(bufsize == 0) {
|
||||
fatal("Input file is empty!\n");
|
||||
fatal(ptx, "Input file is empty!\n");
|
||||
free(tmp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return pcp_readz85string(input, bufsize);
|
||||
return pcp_readz85string(ptx, input, bufsize);
|
||||
}
|
||||
|
||||
char *pcp_readz85string(unsigned char *input, size_t bufsize) {
|
||||
char *pcp_readz85string(PCPCTX *ptx, unsigned char *input, size_t bufsize) {
|
||||
size_t i;
|
||||
size_t MAXLINE = 1024;
|
||||
|
||||
if(bufsize == 0) {
|
||||
fatal("Input file is empty!\n");
|
||||
fatal(ptx, "Input file is empty!\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(_buffer_is_binary(input, bufsize) > 0) {
|
||||
fatal("input is not z85 encoded and contains pure binary data");
|
||||
fatal(ptx, "input is not z85 encoded and contains pure binary data");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -339,7 +339,7 @@ char *pcp_readz85string(unsigned char *input, size_t bufsize) {
|
||||
}
|
||||
|
||||
if(buffer_size(z) == 0) {
|
||||
fatal("empty z85 encoded string");
|
||||
fatal(ptx, "empty z85 encoded string");
|
||||
goto rferr;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user