From cf8402aec021e9ea2e0352148e4e35ee4e300c14 Mon Sep 17 00:00:00 2001 From: TLINDEN Date: Sat, 15 Feb 2014 17:39:16 +0100 Subject: [PATCH] added pcpstream usage to signature lib code as well --- bindings/cpp/sign++.h | 2 ++ bindings/cpp/sign.cpp | 67 +++++++++++++++++++++++++++++++++++++------ include/pcp/ed.h | 9 +++--- libpcp/ed.c | 65 +++++++++++++++++++---------------------- src/signature.c | 26 +++++++++++++---- src/signature.h | 1 + 6 files changed, 116 insertions(+), 54 deletions(-) diff --git a/bindings/cpp/sign++.h b/bindings/cpp/sign++.h index 6350be1..6328200 100644 --- a/bindings/cpp/sign++.h +++ b/bindings/cpp/sign++.h @@ -43,6 +43,7 @@ namespace pcp { Key S; Vault vault; unsigned char *sig; + PubKey Signedby; // constructors Signature(Key &skey); // sign only @@ -57,6 +58,7 @@ namespace pcp { // sender pubkey is P unsigned char *sign(std::vector message); unsigned char *sign(unsigned char *message, size_t mlen); + unsigned char *sign(Pcpstream *message); // verify using P or use vault if defined bool verify(std::vector message); diff --git a/bindings/cpp/sign.cpp b/bindings/cpp/sign.cpp index 4941547..55761fc 100644 --- a/bindings/cpp/sign.cpp +++ b/bindings/cpp/sign.cpp @@ -56,10 +56,27 @@ Signature::~Signature() { } unsigned char *Signature::sign(std::vector message) { - unsigned char *m = (unsigned char *)ucmalloc(message.size()); + if(! S) + throw exception("Error: cannot sign without a secret key, use another constructor."); + + if(S.is_encrypted()) + throw exception("Error: cannot sign with an encrypted secret key, decrypt it before using."); + + char n[] = "signvec"; + Buffer *m = buffer_new(32, n); + for(size_t i=0; i 0) { + Buffer *o = ps_buffer(out); + sigsize = buffer_size(o); + buffer_dump(o); + sig = (unsigned char*)ucmalloc(sigsize); + buffer_get_chunk(o, sig, sigsize); + } + + ps_close(out); + + return sig; +} + bool Signature::verify(vector message) { unsigned char *m = (unsigned char *)ucmalloc(message.size()); for(size_t i=0; i message) { } bool Signature::verify(unsigned char *signature, size_t mlen) { - unsigned char *message; - if(!P) { throw exception("No public key specified, unable to verify."); } - message = pcp_ed_verify(signature, mlen, P.K); - if(message != NULL) { + char n[] = "verify"; + Buffer *m = buffer_new(32, n); + buffer_add(m, signature, mlen); + Pcpstream *p = ps_new_inbuffer(m); + + pcp_pubkey_t *pub = pcp_ed_verify_buffered(p, P.K); + + ps_close(p); + + + if(pub != NULL) { + Signedby = PubKey(pub); return true; } else { diff --git a/include/pcp/ed.h b/include/pcp/ed.h index d468c5b..695fa1f 100644 --- a/include/pcp/ed.h +++ b/include/pcp/ed.h @@ -37,6 +37,7 @@ #include "key.h" #include "keyhash.h" #include "util.h" +#include "pcpstream.h" /* sign a message of messagesize using s->edsecret, if it works return message+signature (size: messagesize + crypto_sign_BYTES), @@ -57,11 +58,11 @@ unsigned char *pcp_ed_verify_key(unsigned char *signature, size_t siglen, pcp_pu /* same as pcp_ed_sign() but work on i/o directly, we're making a hash of the input 32k-wise, copy in=>out, sign the hash and append the 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(Pcpstream *in, Pcpstream *out, pcp_key_t *s, int z85); -pcp_pubkey_t *pcp_ed_verify_buffered(FILE *in, pcp_pubkey_t *p); +pcp_pubkey_t *pcp_ed_verify_buffered(Pcpstream *in, pcp_pubkey_t *p); -size_t pcp_ed_detachsign_buffered(FILE *in, FILE *out, pcp_key_t *s); -pcp_pubkey_t *pcp_ed_detachverify_buffered(FILE *in, FILE *sigfd, pcp_pubkey_t *p); +size_t pcp_ed_detachsign_buffered(Pcpstream *in, Pcpstream *out, pcp_key_t *s); +pcp_pubkey_t *pcp_ed_detachverify_buffered(Pcpstream *in, Pcpstream *sigfd, pcp_pubkey_t *p); #endif /* _HAVE_PCP_ED_H */ diff --git a/libpcp/ed.c b/libpcp/ed.c index d60b5fb..de021e1 100644 --- a/libpcp/ed.c +++ b/libpcp/ed.c @@ -38,7 +38,7 @@ unsigned char * pcp_ed_verify_key(unsigned char *signature, size_t siglen, pcp_p } unsigned char * pcp_ed_verify(unsigned char *signature, size_t siglen, pcp_pubkey_t *p) { - unsigned char *message = ucmalloc(siglen - crypto_sign_BYTES); + unsigned char *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) { @@ -71,7 +71,7 @@ unsigned char *pcp_ed_sign(unsigned char *message, size_t messagesize, pcp_key_t return signature; } -size_t pcp_ed_sign_buffered(FILE *in, FILE *out, pcp_key_t *s, int z85) { +size_t pcp_ed_sign_buffered(Pcpstream *in, Pcpstream* out, pcp_key_t *s, int z85) { unsigned char in_buf[PCP_BLOCK_SIZE]; size_t cur_bufsize = 0; size_t outsize = 0; @@ -81,18 +81,18 @@ size_t pcp_ed_sign_buffered(FILE *in, FILE *out, pcp_key_t *s, int z85) { crypto_generichash_init(st, NULL, 0, 0); if(z85) - fprintf(out, "%s\nHash: Blake2\n\n", PCP_SIG_HEADER); + ps_print(out, "%s\nHash: Blake2\n\n", PCP_SIG_HEADER); - while(!feof(in)) { - cur_bufsize = fread(&in_buf, 1, PCP_BLOCK_SIZE, in); + while(!ps_end(in)) { + cur_bufsize = ps_read(in, &in_buf, PCP_BLOCK_SIZE); /* fread(&in_buf, 1, PCP_BLOCK_SIZE, in); */ if(cur_bufsize <= 0) break; outsize += cur_bufsize; crypto_generichash_update(st, in_buf, cur_bufsize); - fwrite(in_buf, cur_bufsize, 1, out); + ps_write(out, in_buf, cur_bufsize); /* fwrite(in_buf, cur_bufsize, 1, out); */ } - if(ferror(out) != 0) { + if(ps_err(out) != 0) { fatal("Failed to write encrypted output!\n"); free(st); return 0; @@ -104,27 +104,22 @@ size_t pcp_ed_sign_buffered(FILE *in, FILE *out, pcp_key_t *s, int z85) { size_t mlen = + crypto_sign_BYTES + crypto_generichash_BYTES_MAX; if(z85) { - fprintf(out, "\n%s\n Version: PCP v%d.%d.%d\n\n", PCP_SIG_START, PCP_VERSION_MAJOR, PCP_VERSION_MINOR, PCP_VERSION_PATCH); + ps_print(out, "\n%s\n Version: PCP v%d.%d.%d\n\n", PCP_SIG_START, PCP_VERSION_MAJOR, PCP_VERSION_MINOR, PCP_VERSION_PATCH); size_t zlen; char *z85encoded = pcp_z85_encode((unsigned char*)signature, mlen, &zlen); - fprintf(out, "%s\n%s\n", z85encoded, PCP_SIG_END); + ps_print(out, "%s\n%s\n", z85encoded, PCP_SIG_END); } else { - fprintf(out, "%s", PCP_SIGPREFIX); - fwrite(signature, mlen, 1, out); + ps_print(out, "%s", PCP_SIGPREFIX); + ps_write(out, signature, mlen); /* fwrite(signature, mlen, 1, out); */ } - if(fileno(in) != 0) - fclose(in); - if(fileno(out) != 1) - fclose(out); - free(st); return outsize; } -pcp_pubkey_t *pcp_ed_verify_buffered(FILE *in, pcp_pubkey_t *p) { +pcp_pubkey_t *pcp_ed_verify_buffered(Pcpstream *in, pcp_pubkey_t *p) { unsigned char in_buf[PCP_BLOCK_SIZE/2]; unsigned char in_next[PCP_BLOCK_SIZE/2]; unsigned char in_full[PCP_BLOCK_SIZE]; @@ -154,7 +149,7 @@ pcp_pubkey_t *pcp_ed_verify_buffered(FILE *in, pcp_pubkey_t *p) { crypto_generichash_init(st, NULL, 0, 0); /* use two half blocks, to overcome sigs spanning block boundaries */ - cur_bufsize = fread(&in_buf, 1, PCP_BLOCK_SIZE/2, in); + cur_bufsize = ps_read(in, &in_buf, PCP_BLOCK_SIZE/2); /* fread(&in_buf, 1, PCP_BLOCK_SIZE/2, in); */ /* look for z85 header and cut it out */ if(_findoffset(in_buf, cur_bufsize, zhead, hlen) == 0) { @@ -164,7 +159,8 @@ pcp_pubkey_t *pcp_ed_verify_buffered(FILE *in, pcp_pubkey_t *p) { memcpy(in_buf, in_next, next_bufsize); /* put into inbuf without header */ if(cur_bufsize == PCP_BLOCK_SIZE/2) { /* more to come */ - cur_bufsize = fread(&in_buf[next_bufsize], 1, ((PCP_BLOCK_SIZE/2) - next_bufsize), in); + cur_bufsize = ps_read(in, &in_buf[next_bufsize], ((PCP_BLOCK_SIZE/2) - next_bufsize)); + /* cur_bufsize = fread(&in_buf[next_bufsize], 1, ((PCP_BLOCK_SIZE/2) - next_bufsize), in); */ cur_bufsize += next_bufsize; next_bufsize = 0; /* now we've got the 1st half block in in_buf */ @@ -189,7 +185,7 @@ pcp_pubkey_t *pcp_ed_verify_buffered(FILE *in, pcp_pubkey_t *p) { while (cur_bufsize > 0) { if(cur_bufsize == PCP_BLOCK_SIZE/2) { /* probably not eof */ - next_bufsize = fread(&in_next, 1, PCP_BLOCK_SIZE/2, in); + next_bufsize = ps_read(in, &in_next, PCP_BLOCK_SIZE/2); /* fread(&in_next, 1, PCP_BLOCK_SIZE/2, in); */ } else next_bufsize = 0; /* <= this is eof */ @@ -302,7 +298,7 @@ pcp_pubkey_t *pcp_ed_verify_buffered(FILE *in, pcp_pubkey_t *p) { return NULL; } -size_t pcp_ed_detachsign_buffered(FILE *in, FILE *out, pcp_key_t *s) { +size_t pcp_ed_detachsign_buffered(Pcpstream *in, Pcpstream *out, pcp_key_t *s) { unsigned char in_buf[PCP_BLOCK_SIZE]; size_t cur_bufsize = 0; size_t outsize = 0; @@ -311,8 +307,8 @@ size_t pcp_ed_detachsign_buffered(FILE *in, FILE *out, pcp_key_t *s) { crypto_generichash_init(st, NULL, 0, 0); - while(!feof(in)) { - cur_bufsize = fread(&in_buf, 1, PCP_BLOCK_SIZE, in); + while(!ps_end(in)) { + cur_bufsize = ps_read(in, &in_buf, PCP_BLOCK_SIZE); /* fread(&in_buf, 1, PCP_BLOCK_SIZE, in); */ if(cur_bufsize <= 0) break; outsize += cur_bufsize; @@ -324,23 +320,18 @@ size_t pcp_ed_detachsign_buffered(FILE *in, FILE *out, pcp_key_t *s) { unsigned char *signature = pcp_ed_sign(hash, crypto_generichash_BYTES_MAX, s); size_t mlen = + crypto_sign_BYTES + crypto_generichash_BYTES_MAX; - fprintf(out, "\n%s\n Version: PCP v%d.%d.%d\n\n", + ps_print(out, "\n%s\n Version: PCP v%d.%d.%d\n\n", PCP_SIG_START, PCP_VERSION_MAJOR, PCP_VERSION_MINOR, PCP_VERSION_PATCH); size_t zlen; char *z85encoded = pcp_z85_encode((unsigned char*)signature, mlen, &zlen); - fprintf(out, "%s\n%s\n", z85encoded, PCP_SIG_END); - - if(fileno(in) != 0) - fclose(in); - if(fileno(out) != 1) - fclose(out); + ps_print(out, "%s\n%s\n", z85encoded, PCP_SIG_END); free(st); return outsize; } -pcp_pubkey_t *pcp_ed_detachverify_buffered(FILE *in, FILE *sigfd, pcp_pubkey_t *p) { +pcp_pubkey_t *pcp_ed_detachverify_buffered(Pcpstream *in, Pcpstream *sigfd, pcp_pubkey_t *p) { unsigned char in_buf[PCP_BLOCK_SIZE]; size_t cur_bufsize = 0; size_t outsize = 0; @@ -350,8 +341,8 @@ pcp_pubkey_t *pcp_ed_detachverify_buffered(FILE *in, FILE *sigfd, pcp_pubkey_t * crypto_generichash_init(st, NULL, 0, 0); - while(!feof(in)) { - cur_bufsize = fread(&in_buf, 1, PCP_BLOCK_SIZE, in); + while(!ps_end(in)) { + cur_bufsize = ps_read(in, &in_buf, PCP_BLOCK_SIZE); /* fread(&in_buf, 1, PCP_BLOCK_SIZE, in); */ if(cur_bufsize <= 0) break; outsize += cur_bufsize; @@ -365,15 +356,17 @@ pcp_pubkey_t *pcp_ed_detachverify_buffered(FILE *in, FILE *sigfd, pcp_pubkey_t * size_t inputBufSize = 0; unsigned char byte[1]; - while(!feof(sigfd)) { - if(!fread(&byte, 1, 1, sigfd)) + while(!ps_end(sigfd)) { + if(!ps_read(sigfd, &byte, 1)) break; + /* + if(!fread(&byte, 1, 1, sigfd)) + break;*/ unsigned char *tmp = realloc(sig, inputBufSize + 1); sig = tmp; memmove(&sig[inputBufSize], byte, 1); inputBufSize ++; } - fclose(sigfd); if(sig == NULL) { fatal("Invalid detached signature\n"); diff --git a/src/signature.c b/src/signature.c index 713f4dd..5018240 100644 --- a/src/signature.c +++ b/src/signature.c @@ -71,11 +71,17 @@ int pcpsign(char *infile, char *outfile, char *passwd, int z85, int detach) { goto errs1; } + Pcpstream *pin = ps_new_file(in); + Pcpstream *pout = ps_new_file(out); + size_t sigsize; if(detach == 1) - sigsize = pcp_ed_detachsign_buffered(in, out, secret); + sigsize = pcp_ed_detachsign_buffered(pin, pout, secret); else - sigsize = pcp_ed_sign_buffered(in, out, secret, z85); + sigsize = pcp_ed_sign_buffered(pin, pout, secret, z85); + + ps_close(pin); + ps_close(pout); if(sigsize == 0) goto errs1; @@ -111,11 +117,19 @@ int pcpverify(char *infile, char *sigfile, char *id, int detach) { if(id != NULL) HASH_FIND_STR(pcppubkey_hash, id, pub); - - if(detach) - pub = pcp_ed_detachverify_buffered(in, sigfd, pub); + + Pcpstream *pin = ps_new_file(in); + + if(detach) { + Pcpstream *psigfd = ps_new_file(sigfd); + pub = pcp_ed_detachverify_buffered(pin, psigfd, pub); + ps_close(psigfd); + } else - pub = pcp_ed_verify_buffered(in, pub); + pub = pcp_ed_verify_buffered(pin, pub); + + ps_close(pin); + if(pub != NULL) fprintf(stderr, "Signature verified (signed by %s <%s>).\n", pub->owner, pub->mail); diff --git a/src/signature.h b/src/signature.h index 9dda88e..4a055d6 100644 --- a/src/signature.h +++ b/src/signature.h @@ -31,6 +31,7 @@ #include "pcp.h" #include "uthash.h" #include "z85.h" +#include "pcpstream.h" int pcpsign(char *infile, char *outfile, char *passwd, int z85, int detach); int pcpverify(char *infile, char *sigfile, char *id, int detach);