sigchk

sign and check files using ed25519
git clone git://z3bra.org/sick
Log | Files | Refs | Submodules | README | LICENSE

commit f24100e00e4478ecd96f036089af37618a36c302
parent 440b40a1a0800600ec6dfa8994a41802cb746069
Author: z3bra <willyatmailoodotorg>
Date:   Thu Apr 28 01:35:23 2016

Append signature at EOF instead of sigfile

Diffstat:
 sick.c | 76 +++++++++++++++++++++++++++++++++++--------------------------------
 1 file changed, 40 insertions(+), 36 deletions(-)

diff --git a/sick.c b/sick.c @@ -30,6 +30,7 @@ enum { void usage(char *name); char *base_name(char *path); +unsigned char *readsig(char *file); int genkey(char *alias); int sign(char *file, char *key); int verify(char *file, char *key); @@ -49,6 +50,30 @@ base_name(char *path) return b ? b + 1 : path; } +unsigned char * +readsig(char *file) +{ + int fd = 0; + struct stat sb; + static unsigned char sig[64]; + + if (stat(file, &sb) < 0) { + perror(file); + return NULL; + } + + fd = open(file, O_RDONLY); + lseek(fd, sb.st_size - 64, SEEK_SET); + if (read(fd, sig, 64) < 64) { + perror(file); + close(fd); + return NULL; + } + close(fd); + + return sig; +} + int genkey(char *alias) { @@ -104,15 +129,9 @@ sign(char *file, char *key) { int fd = 0; size_t len = 0; - char sigfile[PATH_MAX], *base = NULL; + char *base = NULL; unsigned char sig[64], priv[PRIVSIZ], *msg = NULL; - /* set the signature file as <filename>.sig */ - len = strnlen(file, PATH_MAX); - memset(sigfile, 0, PATH_MAX); - memcpy(sigfile, file, len); - memcpy(sigfile+len, ".sig", 4); - /* set the file basename as the message for signing */ base = base_name(file); len = strnlen(base, PATH_MAX); @@ -125,7 +144,7 @@ sign(char *file, char *key) memcpy(msg, base, len); /* read private key content into the priv[] buffer */ - fd = open(key, O_RDONLY); + fd = open(key, O_RDONLY); if (fd < 0) { perror(key); free(msg); @@ -140,20 +159,20 @@ sign(char *file, char *key) ed25519_sign(sig, msg, len + 1, priv); - /* write signature to the sigfile */ - fd = open(sigfile, O_CREAT|O_WRONLY|O_TRUNC, 0600); + /* write signature at the end of the file */ + fd = open(file, O_WRONLY|O_APPEND); if (fd < 0) { - perror(sigfile); + perror(file); free(msg); return fd; } if (write(fd, sig, 64) < 64) { - perror(sigfile); + perror(file); free(msg); return -1; } close(fd); - + free(msg); return 0; } @@ -163,29 +182,10 @@ verify(char *file, char *key) { int fd = 0, check = 0; size_t len = 0; - char *base = NULL, sigfile[PATH_MAX]; + char *base = NULL; unsigned char sig[64], pub[PRIVSIZ], *msg = NULL; - /* - * read content of the sigfile into the sig[] buffer - * We assume here that the sigfile has the same path as - * the file, with the .sig suffix appended - * TODO: extract the signature from the file - */ - len = strnlen(file, PATH_MAX); - memset(sigfile, 0, PATH_MAX); - memcpy(sigfile, file, len); - memcpy(sigfile+len, ".sig", 4); - fd = open(sigfile, O_RDONLY); - if (fd < 0) { - perror(sigfile); - return fd; - } - if (read(fd, sig, 64) < 64) { - perror(sigfile); - return -1; - } - close(fd); + memcpy(sig, readsig(file), 64); /* read the content of the public key into the pub[] buffer */ fd = open(key, O_RDONLY); @@ -253,7 +253,7 @@ main(int argc, char **argv) memset(keyring, 0, PATH_MAX); memcpy(keyring, KEYRING, strnlen(KEYRING, PATH_MAX)); - + ARGBEGIN{ case 'c': action = ACTION_CHECK; @@ -282,7 +282,11 @@ main(int argc, char **argv) genkey(key); break; case ACTION_SIGN: - sign(*argv, key ? key : DEFAULT_ALIAS ".key"); + if (check(*argv, keyring) != 0) { + sign(*argv, key ? key : DEFAULT_ALIAS ".key"); + } else { + fprintf(stderr, "%s: already signed\n", *argv); + } break; default: usage(argv0);