sigchk

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

commit 30872d3953840775356662d75abf9ee34f6fe598
parent f39d086127af39db3433b140143bfc7174472e12
Author: z3bra <willyatmailoodotorg>
Date:   Wed Apr 27 12:04:51 2016

Write signatures to a .sig file

Diffstat:
 sick.c | 103 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 101 insertions(+), 2 deletions(-)

diff --git a/sick.c b/sick.c @@ -12,18 +12,38 @@ #define PUBSIZ 32 #define PRIVSIZ ((PUBSIZ) * 2) +#define SIGSIZ 64 #define DEFAULT_ALIAS "ed25519" +enum { + ACTION_INVALID = -1, + ACTION_NONE = 0, + ACTION_GENKEY, + ACTION_SIGN, + ACTION_CHECK, + ACTION_DEFAULT = ACTION_CHECK +}; + void usage(char *name); + +char *base_name(char *path); int genkey(char *alias); +int sign(char *file, char *key); void usage(char *name) { - fprintf(stderr, "usage: %s [-g]\n", name); + fprintf(stderr, "usage: %s [-gs] [-f key] [file]\n", name); exit(1); } +char * +base_name(char *path) +{ + char *b = strrchr(path, '/'); + return b ? b + 1 : path; +} + int genkey(char *alias) { @@ -75,17 +95,96 @@ genkey(char *alias) } int +sign(char *file, char *key) +{ + int fd = 0; + size_t len = 0; + char sigfile[PATH_MAX], *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); + msg = malloc(len + 1); + if (msg == NULL) { + perror("malloc"); + return -1; + } + memset(msg, 0, len + 1); + memcpy(msg, base, len); + + /* read private key content into the priv[] buffer */ + fd = open(key, O_RDONLY); + if (fd < 0) { + perror(key); + free(msg); + return fd; + } + if (read(fd, priv, PRIVSIZ) < PRIVSIZ) { + perror(key); + free(msg); + return -1; + } + close(fd); + + ed25519_sign(sig, msg, len + 1, priv); + + /* write signature to the sigfile */ + fd = open(sigfile, O_CREAT|O_WRONLY|O_TRUNC, 0600); + if (fd < 0) { + perror(sigfile); + free(msg); + return fd; + } + if (write(fd, sig, 64) < 64) { + perror(sigfile); + free(msg); + return -1; + } + close(fd); + + free(msg); + return 0; +} + +int main(int argc, char **argv) { + int action = ACTION_DEFAULT; + char *key = NULL; char *argv0 = NULL; ARGBEGIN{ + case 'f': + key = EARGF(usage(argv0)); + break; case 'g': - genkey(argc > 1 ? ARGF() : NULL); + key = argc > 1 ? ARGF() : NULL; + action = ACTION_GENKEY; + break; + case 's': + action = ACTION_SIGN; break; default: usage(argv0); }ARGEND; + switch(action) { + case ACTION_GENKEY: + genkey(key); + break; + case ACTION_SIGN: + sign(*argv, key ? key : "ed25519.key"); + break; + default: + usage(argv0); + } + return 0; } \ No newline at end of file