tImplement signing in base64 format - 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 a6d6dd7c102aeed81bed2c7806880a5169072103
 (DIR) parent 2d6981d14b013ef2b573a349dc2bd41a560af285
 (HTM) Author: z3bra <willyatmailoodotorg>
       Date:   Mon,  9 May 2016 13:43:11 +0200
       
       Implement signing in base64 format
       
       The whole stream will be stored in a buffer and used for the signature.
       Signature will be appended at the end of the stream in base64 format,
       between two lines:
       
           -----BEGIN ED25519 SIGNATURE-----
           -----END ED25519 SIGNATURE-----
       
       The base64 encoded lines are wrapped at char 76, as defined by posix.
       
       Diffstat:
         M mkfile                              |       2 +-
         M sick.c                              |      56 ++++++++++++++++++++++++++++++-
       
       2 files changed, 56 insertions(+), 2 deletions(-)
       ---
 (DIR) diff --git a/mkfile b/mkfile
       t@@ -2,7 +2,7 @@
        
        ED25519_SRC = `{find ed25519/src -name '*.c'}
        
       -SRC = sick.c ${ED25519_SRC}
       +SRC = sick.c base64.c ${ED25519_SRC}
        OBJ = ${SRC:%.c=%.o}
        
        sick: $OBJ
 (DIR) diff --git a/sick.c b/sick.c
       t@@ -5,8 +5,18 @@
        #include <string.h>
        
        #include "arg.h"
       +#include "base64.h"
        #include "ed25519.h"
        
       +#define SIGBEGIN "-----BEGIN ED25519 SIGNATURE-----\n"
       +#define SIGEND "-----END ED25519 SIGNATURE-----\n"
       +
       +enum {
       +        ACT_NONE,
       +        ACT_SIGN,
       +        ACT_CHCK
       +};
       +
        static void usage();
        static int createkeypair(const char *);
        
       t@@ -15,7 +25,7 @@ char *argv0;
        static void
        usage()
        {
       -        fprintf(stderr, "usage: %s [-g ALIAS]\n", argv0);
       +        fprintf(stderr, "usage: %s [-g ALIAS] [-f KEY] [-s [FILE..]]\n", argv0);
                exit(EXIT_FAILURE);
        }
        
       t@@ -41,6 +51,7 @@ createkeypair(const char *alias)
                ed25519_create_keypair(pub, priv, seed);
        
                /* write private key to "<alias>.key" */
       +        memset(fn, 0, PATH_MAX);
                memcpy(fn, alias, len);
                memcpy(fn+len, ".key", 4);
                if ((fp = fopen(fn, "w")) == NULL) {
       t@@ -71,15 +82,58 @@ createkeypair(const char *alias)
        }
        
        int
       +sign(FILE *fp, FILE *key)
       +{
       +        size_t len, siz = 0;
       +        char tmp[64], *base64;
       +        unsigned char sig[64], priv[64], *msg = NULL;
       +
       +        while((len = fread(tmp, 1, 64, fp)) > 0) {
       +                siz += len;
       +                msg = realloc(msg, siz);
       +                memcpy(msg + siz - len, tmp, len);
       +        }
       +
       +        fread(priv, 1, 64, key);
       +        ed25519_sign(sig, msg, siz, priv);
       +
       +        len = base64_encode(&base64, sig, 64);
       +        fwrite(msg, 1, siz, stdout);
       +        fwrite(SIGBEGIN, 1, sizeof(SIGBEGIN), stdout);
       +        base64_fold(stdout, base64, len, 0);
       +        fwrite(SIGEND, 1, sizeof(SIGEND), stdout);
       +
       +        return 0;
       +}
       +
       +int
        main(int argc, char *argv[])
        {
       +        FILE *key = NULL, *fp = NULL;
       +        int action = ACT_NONE;
       +
                ARGBEGIN{
       +        case 'f':
       +                key = fopen(EARGF(usage()), "r");
       +                break;
                case 'g':
                        createkeypair(EARGF(usage()));
                        break;
       +        case 's':
       +                action = ACT_SIGN;
       +                break;
                default:
                        usage();
                }ARGEND;
        
       +        if (!argc) {
       +                fp = stdin;
       +                switch (action) {
       +                case ACT_SIGN:
       +                        sign(fp, key);
       +                        break;
       +                }
       +        }
       +
                return 0;
        }