sick

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

commit 21c53931e5f71af23cda059dfffbadc94ab59b5c
parent 971109b68dea44b87c6e62538aea62856657f7e4
Author: z3bra <willyatmailoodotorg>
Date:   Tue May 17 08:47:07 2016

Add a function to discard a signature

Diffstat:
 README |  8 ++++++++
 sick.1 | 23 ++++++++++++++++-------
 sick.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++------------
 3 files changed, 74 insertions(+), 19 deletions(-)

diff --git a/README b/README @@ -48,3 +48,11 @@ the files located in the $KEYRING directory. $ mkdir $KEYRING $ mv alice.pub $KEYRING/ $ sick < SIGNED + +Trim a signature +---------------- + +You can discard a signature on a stream by using the `-t` (trim) flag. It will +dump the input stream to stdout without the signature: + + $ sick -t SIGNED > UNSIGNED diff --git a/sick.1 b/sick.1 @@ -6,9 +6,9 @@ .Nd sign/check files using ed25519 signatures .Sh SYNOPSIS .Nm sick +.Op Fl stv .Op Fl g Ar ALIAS .Op Fl f Ar KEY -.Op Fl sv .Sh DESCRIPTION .Nm generates key pairs, signs, checks and remove signatures for a file or stream. @@ -17,10 +17,6 @@ generates key pairs, signs, checks and remove signatures for a file or stream. The default action is to check the signature appended to the message given on stdin. If the signature can be verified, the message will be written to stdout without the signature. -.It Fl g Ar ALIAS -Generates an ed25519 key pairs: `ALIAS.key` and `ALIAS.pub` -.It Fl f Ar KEY -Specifies the key file to be used for the current operation (sign or check). .It Fl s Make .Nm @@ -28,6 +24,19 @@ perform a signing operation on the current stream. This will append the base64 encoded signature to the stream and dump them both to stdout. See .Sx SIGNATURE FORMAT for information on what will be appended to the stream. +.It Fl t +Make +.Nm +trim the signature at the end of the stream if there is one, and write the +message to stdout. If there is no signature, the whole stream gets written. +.It Fl v +Enable verbose mode. +.Nm +will log informative messages to stderr. +.It Fl g Ar ALIAS +Generates an ed25519 key pairs: `ALIAS.key` and `ALIAS.pub` +.It Fl f Ar KEY +Specifies the key file to be used for the current operation (sign or check). .Sh SIGNATURE FORMAT ed25519 signatures are 64 bytes long. For easier reading in text/plain format, .Nm @@ -57,10 +66,10 @@ Signing a stream: $ sick -f ${USER}.key < FILE > SIGNED .Ed -Checking a signed stream (FILE will be empty if the signature doesn't match the +Checking a signed file (FILE will be empty if the signature doesn't match the public key): .Bd -literal - $ sick -f ${USER}.pub < SIGNED > FILE + $ sick -f ${USER}.pub SIGNED > FILE .Ed .Sh SEE ALSO .Xr ed25519 7 , diff --git a/sick.c b/sick.c @@ -16,7 +16,8 @@ enum { ACT_NONE, ACT_SIGN, - ACT_CHCK + ACT_CHCK, + ACT_TRIM }; enum { @@ -28,26 +29,27 @@ enum { static void usage(); static size_t bufferize(char **buf, FILE *fp); -static size_t extractmsg(unsigned char *msg[], char *buf); +static size_t extractmsg(unsigned char *msg[], char *buf, size_t len); static size_t extractsig(unsigned char *sig[], char *buf); static int createkeypair(const char *); static int check_keyring(unsigned char *sig, unsigned char *msg, size_t len); static int sign(FILE *fp, FILE *key); static int check(FILE *fp, FILE *key); +static int trimsig(FILE *fp); -static int verbose = 0; char *argv0; +static int verbose = 0; static void usage() { - fprintf(stderr, "usage: %s [-sv] [-g ALIAS] [-f KEY] [FILE]\n", + fprintf(stderr, "usage: %s [-stv] [-g ALIAS] [-f KEY] [FILE]\n", argv0); exit(EXIT_FAILURE); } /* - * read chunks of data from a stream into a buffer, and return the size of the + * read chunks of data from a stream into a buffer, and return the size of the * buffer */ static size_t @@ -80,7 +82,7 @@ bufferize(char **buf, FILE *fp) * pointer */ static size_t -extractmsg(unsigned char **msg, char *buf) +extractmsg(unsigned char **msg, char *buf, size_t buflen) { size_t len = 0; char *sig; @@ -88,11 +90,13 @@ extractmsg(unsigned char **msg, char *buf) /* signature start is identified by SIGBEGIN */ sig = strstr(buf, SIGBEGIN); - /* if signature is not found, return an error */ - if (sig == NULL) - return 0; + /* if signature is not found, return the whole buffer */ + if (sig == NULL) { + len = buflen; + } else { + len = sig - buf; + } - len = sig - buf; *msg = malloc(len); memcpy(*msg, buf, len); @@ -292,7 +296,7 @@ check_keyring(unsigned char *sig, unsigned char *msg, size_t len) /* ignore all entries that are not 32 bytes long */ if (dt->d_reclen != 32) - continue + continue; /* set public key file path and store its content */ n = strnlen(keyring, PATH_MAX); @@ -350,7 +354,7 @@ check(FILE *fp, FILE *key) return ERR_NOSIG; } - if ((len = extractmsg(&msg, buf)) == 0) { + if ((len = extractmsg(&msg, buf, len)) == 0) { free(buf); free(sig); } @@ -384,6 +388,34 @@ check(FILE *fp, FILE *key) return ret; } +/* + * Remove a signature from a stream, and dump it to stdout + */ +static int +trimsig(FILE *fp) +{ + size_t len = 0; + char *buf = NULL; + unsigned char *msg = NULL; + + len = bufferize(&buf, fp); + if (!buf) + return -1; + + len = extractmsg(&msg, buf, len); + if (!msg) { + free(buf); + return ERR_NOMSG; + } + + fwrite(msg, 1, len, stdout); + + free(buf); + free(msg); + + return 0; +} + int main(int argc, char *argv[]) { @@ -400,6 +432,9 @@ main(int argc, char *argv[]) case 's': action = ACT_SIGN; break; + case 't': + action = ACT_TRIM; + break; case 'v': verbose = 1; break; @@ -417,6 +452,9 @@ main(int argc, char *argv[]) case ACT_CHCK: ret |= check(fp, key); break; + case ACT_TRIM: + ret |= trimsig(fp); + break; } fclose(fp);