tAdd a function to discard a signature - sick - sign and check files using ed25519
 (HTM) git clone git://z3bra.org/sick
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit 21c53931e5f71af23cda059dfffbadc94ab59b5c
 (DIR) parent 971109b68dea44b87c6e62538aea62856657f7e4
 (HTM) Author: z3bra <willyatmailoodotorg>
       Date:   Tue, 17 May 2016 08:47:07 +0200
       
       Add a function to discard a signature
       
       Diffstat:
         M README                              |       8 ++++++++
         M sick.1                              |      23 ++++++++++++++++-------
         M sick.c                              |      62 +++++++++++++++++++++++++------
       
       3 files changed, 74 insertions(+), 19 deletions(-)
       ---
 (DIR) diff --git a/README b/README
       t@@ -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
 (DIR) diff --git a/sick.1 b/sick.1
       t@@ -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.
       t@@ -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
       t@@ -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
       t@@ -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 ,
 (DIR) diff --git a/sick.c b/sick.c
       t@@ -16,7 +16,8 @@
        enum {
                ACT_NONE,
                ACT_SIGN,
       -        ACT_CHCK
       +        ACT_CHCK,
       +        ACT_TRIM
        };
        
        enum {
       t@@ -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
       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;
       t@@ -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);
        
       t@@ -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);
       t@@ -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);
                }
       t@@ -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[])
        {
       t@@ -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;
       t@@ -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);