mirror of
https://codeberg.org/scip/pcp.git
synced 2025-12-17 03:50:57 +01:00
added pcp_ed_verify_buffered() [doesnt work yet, needs debugging]
This commit is contained in:
@@ -40,9 +40,10 @@ typedef unsigned int qbyte; // Quad byte = 32 bits
|
|||||||
#define PCP_ZFILE_HEADER "----- BEGIN Z85 ENCODED FILE -----"
|
#define PCP_ZFILE_HEADER "----- BEGIN Z85 ENCODED FILE -----"
|
||||||
#define PCP_ZFILE_FOOTER "------ END Z85 ENCODED FILE ------"
|
#define PCP_ZFILE_FOOTER "------ END Z85 ENCODED FILE ------"
|
||||||
|
|
||||||
#define PCP_SIG_HEADER "----- BEGIN PCP SIGNED MESSAGE -----"
|
#define PCP_SIG_HEADER "----- BEGIN ED25519 SIGNED MESSAGE -----"
|
||||||
#define PCP_SIG_START "----- BEGIN PCP SIGNATURE -----"
|
#define PCP_SIG_START "----- BEGIN ED25519 SIGNATURE -----"
|
||||||
#define PCP_SIG_END "------ END PCP SIGNATURE ------"
|
#define PCP_SIG_END "------ END ED25519 SIGNATURE ------"
|
||||||
|
#define PCP_SIGPREFIX "\nnacl-"
|
||||||
|
|
||||||
#define PCP_ME "Pretty Curved Privacy"
|
#define PCP_ME "Pretty Curved Privacy"
|
||||||
|
|
||||||
|
|||||||
@@ -35,6 +35,8 @@
|
|||||||
#include "platform.h"
|
#include "platform.h"
|
||||||
#include "mem.h"
|
#include "mem.h"
|
||||||
#include "key.h"
|
#include "key.h"
|
||||||
|
#include "keyhash.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
/* sign a message of messagesize using s->edsecret, if it works
|
/* sign a message of messagesize using s->edsecret, if it works
|
||||||
return message+signature (size: messagesize + crypto_sign_BYTES),
|
return message+signature (size: messagesize + crypto_sign_BYTES),
|
||||||
@@ -51,4 +53,6 @@ unsigned char * pcp_ed_verify(unsigned char *signature, size_t siglen, pcp_pubke
|
|||||||
sig only to the output */
|
sig only to the output */
|
||||||
size_t pcp_ed_sign_buffered(FILE *in, FILE *out, pcp_key_t *s, int z85);
|
size_t pcp_ed_sign_buffered(FILE *in, FILE *out, pcp_key_t *s, int z85);
|
||||||
|
|
||||||
|
unsigned char *pcp_ed_verify_buffered(FILE *in, pcp_pubkey_t *p);
|
||||||
|
|
||||||
#endif // _HAVE_PCP_ED_H
|
#endif // _HAVE_PCP_ED_H
|
||||||
|
|||||||
@@ -26,13 +26,31 @@
|
|||||||
#define _HAVE_PCP_UTIL_H
|
#define _HAVE_PCP_UTIL_H
|
||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
#include <wctype.h>
|
||||||
|
|
||||||
|
// lowercase a string
|
||||||
static inline char *_lc(char *in) {
|
static inline char *_lc(char *in) {
|
||||||
size_t len = strlen(in);
|
size_t len = strlen(in);
|
||||||
int i;
|
size_t i;
|
||||||
for(i=0; i<len; ++i)
|
for(i=0; i<len; ++i)
|
||||||
in[i] = towlower(in[i]);
|
in[i] = towlower(in[i]);
|
||||||
return in;
|
return in;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// find the offset of the beginning of a certain string within binary data
|
||||||
|
static inline int _findoffset(unsigned char *bin, size_t binlen, char *sigstart, size_t hlen) {
|
||||||
|
size_t i;
|
||||||
|
int sigfoot = 181; // yes, also bad. that's the armored sig footer
|
||||||
|
int offset = -1;
|
||||||
|
|
||||||
|
for(i=0; i<binlen-sigfoot; ++i) {
|
||||||
|
if(memcmp(&bin[i], sigstart, hlen) == 0) {
|
||||||
|
offset = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return offset;
|
||||||
|
}
|
||||||
|
|
||||||
#endif // _HAVE_PCP_UTIL_H
|
#endif // _HAVE_PCP_UTIL_H
|
||||||
|
|||||||
136
libpcp/ed.c
136
libpcp/ed.c
@@ -79,9 +79,7 @@ size_t pcp_ed_sign_buffered(FILE *in, FILE *out, pcp_key_t *s, int z85) {
|
|||||||
crypto_sign(signature, &mlen, hash, crypto_generichash_BYTES_MAX, s->edsecret);
|
crypto_sign(signature, &mlen, hash, crypto_generichash_BYTES_MAX, s->edsecret);
|
||||||
|
|
||||||
if(z85) {
|
if(z85) {
|
||||||
if(in_buf[cur_bufsize] != '\n')
|
fprintf(out, "\n%s\nVersion: PCP v%d.%d.%d\n\n", PCP_SIG_START, PCP_VERSION_MAJOR, PCP_VERSION_MINOR, PCP_VERSION_PATCH);
|
||||||
fprintf(out, "\n");
|
|
||||||
fprintf(out, "%s\nVersion: PCP v%d.%d.%d\n\n", PCP_SIG_START, PCP_VERSION_MAJOR, PCP_VERSION_MINOR, PCP_VERSION_PATCH);
|
|
||||||
size_t zlen;
|
size_t zlen;
|
||||||
char *z85encoded = pcp_z85_encode((unsigned char*)signature, crypto_sign_BYTES, &zlen);
|
char *z85encoded = pcp_z85_encode((unsigned char*)signature, crypto_sign_BYTES, &zlen);
|
||||||
fprintf(out, "%s\n%s\n", z85encoded, PCP_SIG_END);
|
fprintf(out, "%s\n%s\n", z85encoded, PCP_SIG_END);
|
||||||
@@ -99,3 +97,135 @@ size_t pcp_ed_sign_buffered(FILE *in, FILE *out, pcp_key_t *s, int z85) {
|
|||||||
|
|
||||||
return mlen; // ???
|
return mlen; // ???
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
unsigned char *pcp_ed_verify_buffered(FILE *in, pcp_pubkey_t *p) {
|
||||||
|
unsigned char in_buf[PCP_BLOCK_SIZE];
|
||||||
|
size_t cur_bufsize = 0;
|
||||||
|
int z85 = 0;
|
||||||
|
crypto_generichash_state *st = ucmalloc(sizeof(crypto_generichash_state));
|
||||||
|
unsigned char hash[crypto_generichash_BYTES_MAX];
|
||||||
|
char *zhead;
|
||||||
|
size_t hlen = strlen(PCP_SIG_HEADER);
|
||||||
|
size_t nextsize = 0;
|
||||||
|
size_t restsize = 0;
|
||||||
|
size_t mlen = + crypto_sign_BYTES + crypto_generichash_BYTES_MAX;
|
||||||
|
unsigned char z85encoded[181];
|
||||||
|
unsigned char sighash[mlen];
|
||||||
|
unsigned char sig[crypto_sign_BYTES];
|
||||||
|
char z85sigstart[] = PCP_SIG_START;
|
||||||
|
char binsigstart[] = PCP_SIGPREFIX;
|
||||||
|
int offset = -1;
|
||||||
|
|
||||||
|
crypto_generichash_init(st, NULL, 0, 0);
|
||||||
|
|
||||||
|
// determine sig type, clear or bin
|
||||||
|
cur_bufsize = hlen + 14; // header + hash name + 3x newline
|
||||||
|
fread(&in_buf, 1, cur_bufsize, in);
|
||||||
|
zhead = ucmalloc(cur_bufsize);
|
||||||
|
memcpy(zhead, in_buf, hlen);
|
||||||
|
memset(&zhead[hlen], 0, 1);
|
||||||
|
|
||||||
|
if(strncmp(zhead, PCP_SIG_HEADER, hlen) == 0)
|
||||||
|
z85 = 1;
|
||||||
|
else
|
||||||
|
nextsize = cur_bufsize;
|
||||||
|
|
||||||
|
while(!feof(in)) {
|
||||||
|
if(z85 == 0 && nextsize > 0) {
|
||||||
|
// bin sig, read blocksize - header and put zheader in front of it again
|
||||||
|
cur_bufsize = fread(&in_buf[hlen], 1, PCP_BLOCK_SIZE - hlen, in);
|
||||||
|
memcpy(in_buf, zhead, hlen);
|
||||||
|
cur_bufsize += hlen;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
cur_bufsize = fread(&in_buf, 1, PCP_BLOCK_SIZE, in);
|
||||||
|
|
||||||
|
if(cur_bufsize <= 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if(z85) {
|
||||||
|
// look if we need to cut something from the current block
|
||||||
|
offset = _findoffset(in_buf, cur_bufsize, z85sigstart, strlen(z85sigstart));
|
||||||
|
if(offset > 0) {
|
||||||
|
// we need to cut
|
||||||
|
restsize = cur_bufsize - offset; // the start of the armor sig
|
||||||
|
cur_bufsize -= restsize; // bin stuff in front of it, if any
|
||||||
|
memcpy(z85encoded, &in_buf[offset], restsize); // save the armor sig chunk
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// do the same for the bin sig
|
||||||
|
offset = _findoffset(in_buf, cur_bufsize, binsigstart, strlen(binsigstart));
|
||||||
|
if(offset > 0) {
|
||||||
|
// we need to cut
|
||||||
|
restsize = cur_bufsize - offset + strlen(binsigstart); // the start of the bin sig
|
||||||
|
cur_bufsize -= offset; // bin stuff in front of it, if any
|
||||||
|
memcpy(sighash, &in_buf[offset + strlen(binsigstart)], restsize); // save the armor sig chunk
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(offset == -1)
|
||||||
|
crypto_generichash_update(st, in_buf, cur_bufsize);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(offset == -1) {
|
||||||
|
fatal("Error, the signature doesn't contain the ed25519 signed hash\n");
|
||||||
|
goto errvb1;
|
||||||
|
}
|
||||||
|
|
||||||
|
crypto_generichash_final(st, hash, crypto_generichash_BYTES_MAX);
|
||||||
|
|
||||||
|
// pull in the remainder
|
||||||
|
cur_bufsize = fread(&in_buf, 1, restsize, in);
|
||||||
|
|
||||||
|
// put hashsig together
|
||||||
|
if(z85) {
|
||||||
|
memcpy(&z85encoded[restsize], in_buf, cur_bufsize);
|
||||||
|
char *z85block = pcp_readz85string(z85encoded, restsize + cur_bufsize);
|
||||||
|
if(z85block == NULL)
|
||||||
|
goto errvb1;
|
||||||
|
size_t dstlen;
|
||||||
|
unsigned char *z85decoded = pcp_z85_decode(z85block, &dstlen);
|
||||||
|
if(dstlen != mlen) {
|
||||||
|
fatal("z85 decoded signature didn't result in a proper signed hash\n");
|
||||||
|
goto errvb1;
|
||||||
|
}
|
||||||
|
memcpy(sighash, z85decoded, mlen);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
memcpy(&sighash[restsize], in_buf, cur_bufsize); // FIXME: check if cur_bufsize holds enough
|
||||||
|
}
|
||||||
|
|
||||||
|
// huh, how did we made it til here?
|
||||||
|
unsigned char *verifiedhash = NULL;
|
||||||
|
if(p == NULL) {
|
||||||
|
pcphash_iteratepub(p) {
|
||||||
|
verifiedhash = pcp_ed_verify(sighash, mlen, p);
|
||||||
|
if(verifiedhash != NULL)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
verifiedhash = pcp_ed_verify(sighash, mlen, p);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(verifiedhash == NULL)
|
||||||
|
goto errvb1;
|
||||||
|
|
||||||
|
|
||||||
|
if(memcmp(verifiedhash, hash, crypto_generichash_BYTES_MAX) != 0) {
|
||||||
|
// sig verified, but the hash doesn't
|
||||||
|
fatal("signed hash doesn't match with actual hash of signed file content\n");
|
||||||
|
free(verifiedhash);
|
||||||
|
}
|
||||||
|
|
||||||
|
return verifiedhash;
|
||||||
|
|
||||||
|
|
||||||
|
errvb1:
|
||||||
|
free(st);
|
||||||
|
free(zhead);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -99,60 +99,29 @@ int pcpverify(char *infile, char *id) {
|
|||||||
if(id != NULL)
|
if(id != NULL)
|
||||||
HASH_FIND_STR(pcppubkey_hash, id, pub);
|
HASH_FIND_STR(pcppubkey_hash, id, pub);
|
||||||
|
|
||||||
/*
|
|
||||||
if(pub == NULL) {
|
|
||||||
fatal("Could not find a usable public key in vault %s!\n",
|
|
||||||
vault->filename);
|
|
||||||
goto errv3;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
unsigned char *input = NULL;
|
|
||||||
size_t inputBufSize = 0;
|
|
||||||
unsigned char byte[1];
|
|
||||||
|
|
||||||
while(!feof(in)) {
|
|
||||||
if(!fread(&byte, 1, 1, in))
|
|
||||||
break;
|
|
||||||
unsigned char *tmp = realloc(input, inputBufSize + 1);
|
|
||||||
input = tmp;
|
|
||||||
memmove(&input[inputBufSize], byte, 1);
|
|
||||||
inputBufSize ++;
|
|
||||||
}
|
|
||||||
fclose(in);
|
|
||||||
|
|
||||||
if(inputBufSize == 0) {
|
|
||||||
fatal("Input file is empty!\n");
|
|
||||||
goto errv4;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(pub != NULL) {
|
if(pub != NULL) {
|
||||||
message = pcp_ed_verify(input, inputBufSize, pub);
|
message = pcp_ed_verify_buffered(in, pub);
|
||||||
if(message != NULL) {
|
if(message != NULL) {
|
||||||
fprintf(stderr, "Signature verified (signed by %s <%s>).\n", pub->owner, pub->mail);
|
fprintf(stderr, "Signature verified (signed by %s <%s>).\n", pub->owner, pub->mail);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
pcphash_iteratepub(pub) {
|
// put public key as pub, so verify iterates over our keys
|
||||||
message = pcp_ed_verify(input, inputBufSize, pub);
|
message = pcp_ed_verify_buffered(in, pub);
|
||||||
if(message != NULL) {
|
if(message != NULL) {
|
||||||
fprintf(stderr, "Signature verified (signed by %s <%s>).\n", pub->owner, pub->mail);
|
fprintf(stderr, "Signature verified (signed by %s <%s>).\n", pub->owner, pub->mail);
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(message == NULL) {
|
if(message == NULL) {
|
||||||
fprintf(stderr, "Could not verify ignature\n");
|
fprintf(stderr, "Could not verify signature\n");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
free(message);
|
free(message);
|
||||||
|
|
||||||
free(input);
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
errv4:
|
errv4:
|
||||||
free(input);
|
|
||||||
|
|
||||||
errv1:
|
errv1:
|
||||||
return 1;
|
return 1;
|
||||||
|
|||||||
Reference in New Issue
Block a user