added signature support (doesn't work yet)

This commit is contained in:
git@daemon.de
2013-11-08 09:40:51 +01:00
parent a2c55c96b4
commit e6733e5e56
15 changed files with 497 additions and 39 deletions

View File

@@ -25,5 +25,6 @@ AM_CFLAGS = -I../include/pcp -Wall -g
bin_PROGRAMS = pcp1
pcp1_LDADD = ../libpcp/.libs/libpcp1.a
pcp1_SOURCES = pcp.c keymgmt.c keyprint.c readpass.c encryption.c z85util.c
pcp1_SOURCES = pcp.c keymgmt.c keyprint.c readpass.c \
encryption.c z85util.c signature.c

View File

@@ -90,7 +90,8 @@ CONFIG_CLEAN_VPATH_FILES =
am__installdirs = "$(DESTDIR)$(bindir)"
PROGRAMS = $(bin_PROGRAMS)
am_pcp1_OBJECTS = pcp.$(OBJEXT) keymgmt.$(OBJEXT) keyprint.$(OBJEXT) \
readpass.$(OBJEXT) encryption.$(OBJEXT) z85util.$(OBJEXT)
readpass.$(OBJEXT) encryption.$(OBJEXT) z85util.$(OBJEXT) \
signature.$(OBJEXT)
pcp1_OBJECTS = $(am_pcp1_OBJECTS)
pcp1_DEPENDENCIES = ../libpcp/.libs/libpcp1.a
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/libpcp
@@ -231,7 +232,9 @@ top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
AM_CFLAGS = -I../include/pcp -Wall -g
pcp1_LDADD = ../libpcp/.libs/libpcp1.a
pcp1_SOURCES = pcp.c keymgmt.c keyprint.c readpass.c encryption.c z85util.c
pcp1_SOURCES = pcp.c keymgmt.c keyprint.c readpass.c \
encryption.c z85util.c signature.c
all: all-am
.SUFFIXES:
@@ -327,6 +330,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/keyprint.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcp.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/readpass.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/signature.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/z85util.Po@am__quote@
.c.o:

View File

@@ -44,10 +44,11 @@ char *default_vault() {
}
int main (int argc, char **argv) {
int opt, mode, usevault, useid, userec;
int opt, mode, usevault, useid, userec, lo;
char *vaultfile = default_vault();
char *outfile = NULL;
char *infile = NULL;
char *sigfile = NULL;
char *keyid = NULL;
char *id = NULL;
char *xpass = NULL;
@@ -64,43 +65,54 @@ int main (int argc, char **argv) {
static struct option longopts[] = {
// generics
{ "vault", required_argument, NULL, 'V' },
{ "outfile", required_argument, NULL, 'O' },
{ "infile", required_argument, NULL, 'I' },
{ "keyid", required_argument, NULL, 'i' },
{ "text", required_argument, NULL, 't' },
{ "xpass", required_argument, NULL, 'x' },
{ "recipient", required_argument, NULL, 'r' },
{ "vault", required_argument, NULL, 'V' },
{ "outfile", required_argument, NULL, 'O' },
{ "infile", required_argument, NULL, 'I' },
{ "keyid", required_argument, NULL, 'i' },
{ "text", required_argument, NULL, 't' },
{ "xpass", required_argument, NULL, 'x' },
{ "recipient", required_argument, NULL, 'r' },
// key management
{ "keygen", no_argument, NULL, 'k' },
{ "listkeys", no_argument, NULL, 'l' },
{ "export-secret", no_argument, NULL, 's' },
{ "export-public", no_argument, NULL, 'p' },
{ "import-secret", no_argument, NULL, 'S' },
{ "import-public", no_argument, NULL, 'P' },
{ "remove-key", no_argument, NULL, 'R' },
{ "edit-key", no_argument, NULL, 'E' },
{ "keygen", no_argument, NULL, 'k' },
{ "listkeys", no_argument, NULL, 'l' },
{ "export-secret", no_argument, NULL, 's' },
{ "export-public", no_argument, NULL, 'p' },
{ "import-secret", no_argument, NULL, 'S' },
{ "import-public", no_argument, NULL, 'P' },
{ "remove-key", no_argument, NULL, 'R' },
{ "edit-key", no_argument, NULL, 'E' },
// crypto
{ "encrypt", no_argument, NULL, 'e' },
{ "decrypt", no_argument, NULL, 'd' },
{ "encrypt", no_argument, NULL, 'e' },
{ "decrypt", no_argument, NULL, 'd' },
// encoding
{ "z85-encode", no_argument, NULL, 'z' },
{ "z85-decode", no_argument, NULL, 'Z' },
{ "z85-encode", no_argument, NULL, 'z' },
{ "z85-decode", no_argument, NULL, 'Z' },
// globals
{ "help", no_argument, NULL, 'h' },
{ "version", no_argument, NULL, 'f' },
{ "debug", no_argument, NULL, 'D' },
{ NULL, 0, NULL, 0 }
{ "help", no_argument, NULL, 'h' },
{ "version", no_argument, NULL, 'f' },
{ "debug", no_argument, NULL, 'D' },
// signing
{ "sign", no_argument, NULL, 'g' },
{ "check-signature", required_argument, NULL, 'c' },
{ NULL, 0, NULL, 0 }
};
while ((opt = getopt_long(argc, argv, "klV:vdehsO:i:I:pSPRtEx:DzZr:",
while ((opt = getopt_long(argc, argv, "klV:vdehsO:i:I:pSPRtEx:DzZr:gc:",
longopts, NULL)) != -1) {
switch (opt) {
case 0:
switch(lo) {
case 's':
printf("sign\n");
break;
}
break;
case 'k':
mode += PCP_MODE_KEYGEN;
@@ -153,7 +165,16 @@ int main (int argc, char **argv) {
case 'Z':
mode += PCP_MODE_ZDECODE;
break;
case 'g':
mode += PCP_MODE_SIGN;
usevault = 1;
break;
case 'c':
mode += PCP_MODE_VERIFY;
sigfile = ucmalloc(strlen(optarg)+1);
strncpy(sigfile, optarg, strlen(optarg)+1);
usevault = 1;
break;
case 'V':
strncpy(vaultfile, optarg, 1024);
@@ -348,6 +369,16 @@ int main (int argc, char **argv) {
free(xpass);
break;
case PCP_MODE_SIGN:
pcpsign(infile, outfile, xpass);
break;
case PCP_MODE_VERIFY:
pcpverify(infile, sigfile);
break;
default:
//
goto ELSEMODE;

View File

@@ -44,6 +44,7 @@
#include "keymgmt.h"
#include "usage.h"
#include "encryption.h"
#include "signature.h"
// operation modi
// perl -e '$x=0; while ($x<100000) { $x++; $x *= 1.7; printf "0x%08X: %d\n", $x, $x }'
@@ -60,10 +61,9 @@
#define PCP_MODE_DECRYPT 0x0000033D
#define PCP_MODE_ZENCODE 0x00000584
#define PCP_MODE_ZDECODE 0x00000962
#define PCP_MODE_SIGN 0x00000FF6
#define PCP_MODE_VERIFY 0x00001B25
/*
0x00000962
0x00000FF6
0x00001B25
0x00002E27
0x00004E77

224
src/signature.c Normal file
View File

@@ -0,0 +1,224 @@
/*
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 "signature.h"
#include "defines.h"
int pcpsign(char *infile, char *outfile, char *passwd) {
FILE *in = NULL;
FILE *out = NULL;
pcp_key_t *secret = NULL;
secret = pcp_find_primary_secret();
if(secret == NULL) {
fatal("Could not find a secret key in vault %s!\n", vault->filename);
goto errs1;
}
if(infile == NULL)
in = stdin;
else {
if((in = fopen(infile, "rb")) == NULL) {
fatal("Could not open input file %s\n", infile);
goto errs2;
}
}
if(outfile == NULL)
out = stdout;
else {
if((out = fopen(outfile, "wb+")) == NULL) {
fatal("Could not open output file %s\n", outfile);
goto errs2;
}
}
if(secret->secret[0] == 0) {
// encrypted, decrypt it
char *passphrase;
if(passwd == NULL) {
pcp_readpass(&passphrase,
"Enter passphrase to decrypt your secret key", NULL, 1);
}
else {
passphrase = ucmalloc(strlen(passwd)+1);
strncpy(passphrase, passwd, strlen(passwd)+1);
}
secret = pcpkey_decrypt(secret, passphrase);
if(secret == NULL)
goto errs3;
}
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 errs4;
}
size_t zlen;
pcp_sig_t *signature = pcp_ed_sign(input, inputBufSize, secret);
if(signature == NULL)
goto errs5;
sig2be(signature);
char *encoded = pcp_z85_encode((unsigned char *)signature, sizeof(pcp_sig_t), &zlen);
if(encoded == NULL)
goto errs6;
fprintf(out, "%s\n%s\n%s\n", PCP_SIG_HEADER, encoded, PCP_SIG_FOOTER);
if(ferror(out) != 0) {
fatal("Failed to write encrypted output!\n");
goto errs7;
}
fprintf(stderr, "Signed %d bytes successfully\n",
(int)inputBufSize);
fclose(out);
free(encoded);
free(signature);
return 0;
errs7:
free(encoded);
errs6:
free(signature);
errs5:
errs4:
free(input);
errs3:
errs2:
errs1:
return 1;
}
int pcpverify(char *infile, char *sigfile) {
FILE *in = NULL;
FILE *sigin = NULL;
pcp_pubkey_t *public = NULL;
if(infile == NULL)
in = stdin;
else {
if((in = fopen(infile, "rb")) == NULL) {
fatal("Could not open input file %s\n", infile);
goto errv1;
}
}
if((sigin = fopen(sigfile, "rb")) == NULL) {
fatal("Could not open signature file %s\n", sigfile);
goto errv1;
}
char *encoded = pcp_readz85file(sigin);
if(encoded == NULL)
goto errv1;
size_t clen;
unsigned char *decoded = pcp_z85_decode((char *)encoded, &clen);
if(decoded == NULL)
goto errv2;
if(clen != sizeof(pcp_sig_t)) {
fatal("Error: decoded signature file didn't result to a proper sized sig! (got %d bytes)\n", clen);
goto errv2;
}
pcp_sig_t *sig = (pcp_sig_t *)decoded;
sig2native(sig);
HASH_FIND_STR(pcppubkey_hash, sig->id, public);
if(public == 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(pcp_ed_verify(input, inputBufSize, sig, public) == 0) {
fprintf(stderr, "Signature verified.\n");
}
free(decoded);
free(encoded);
free(sig);
free(input);
return 0;
errv4:
free(input);
errv3:
free(decoded);
free(sig);
errv2:
// free(encoded); why???
errv1:
return 1;
}

40
src/signature.h Normal file
View File

@@ -0,0 +1,40 @@
/*
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_SIGNATURE_H
#define _HAVE_SIGNATURE_H
#include <stdio.h>
#include <string.h>
#include "defines.h"
#include "key.h"
#include "ed.h"
#include "pcp.h"
#include "uthash.h"
#include "z85.h"
int pcpsign(char *infile, char *outfile, char *passwd);
int pcpverify(char *infile, char *sigfile);
#endif // _HAVE_SIGNATURE_H