sick

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

commit 509b9259ed6fa5424460a2947a8cae2fcc952814
parent 1e699f32b8e2a0cfeaae3ac182b7ca0db6cb9c92
Author: z3bra <contactatz3bradotorg>
Date:   Thu Jan 19 15:39:58 +0100

Handle non-armored signatures

sick(1) now defaults to non-armored signatures, as they don't make sense
for binary streams. Armored format can be brought back using a flag.

A few points worth noticing:

* There is no smart guessing about the format to use
* In raw format, the last 64 bytes are assumed to be the signature
* In raw format, a trailing \n is *NOT* appended
* The armored flag does not apply to the key pair generation

Diffstat:
sick.1 | 16+++++++++++-----
sick.c | 96++++++++++++++++++++++++++++++++++++++++++++++++-------------------------------
2 files changed, 70 insertions(+), 42 deletions(-)
diff --git a/sick.1 b/sick.1 @@ -6,7 +6,7 @@ .Nd sign/check files using ed25519 signatures .Sh SYNOPSIS .Nm sick -.Op Fl stv +.Op Fl astv .Op Fl g Ar ALIAS .Op Fl f Ar KEY .Sh DESCRIPTION @@ -17,6 +17,11 @@ 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 a +Deal with armored signature. The signature are base64 encoded, wrapped +at 76 characters and surrounded with two context lines. See +.Sx SIGNATURE FORMAT +For more information on the signature format. .It Fl s Make .Nm @@ -40,10 +45,11 @@ 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 -will base64 encode them prior to appending them to stdout. The base64 signature -is wrapped at 76 bytes as specified by POSIX uuencode. -In order to make it easier to detect the signature, it will be wrapped between -two lines, as follows: +can base64 encode them (see +.Fl a +flag) prior to appending them to stdout. The base64 signature is wrapped +at 76 bytes as specified by POSIX uuencode. In order to make it easier +to detect the signature, it will be wrapped between two lines, as follows: .Bd -literal -----BEGIN ED25519 SIGNATURE----- base64 encoded signature diff --git a/sick.c b/sick.c @@ -40,11 +40,12 @@ static int trimsig(FILE *fp); char *argv0; static int verbose = 0; +static int armored = 0; static void usage() { - fprintf(stderr, "usage: %s [-stv] [-g ALIAS] [-f KEY] [FILE]\n", + fprintf(stderr, "usage: %s [-astv] [-g ALIAS] [-f KEY] [FILE]\n", argv0); exit(EXIT_FAILURE); } @@ -112,8 +113,13 @@ extractmsg(unsigned char **msg, char *buf, size_t buflen) size_t len = 0; char *sig; - /* signature start is identified by SIGBEGIN */ - sig = memstr(buf, buflen, SIGBEGIN, strlen(SIGBEGIN)); + if (armored) { + /* signature start is identified by SIGBEGIN */ + sig = memstr(buf, buflen, SIGBEGIN, strlen(SIGBEGIN)); + } else { + /* signatures are 64 bytes long, appended to the stream */ + sig = buf + buflen - 64; + } /* if signature is not found, return the whole buffer */ if (sig == NULL) { @@ -139,11 +145,13 @@ extractsig(unsigned char **sig, char *buf, size_t len) char *begin, *end, *tmp; unsigned char base64[76]; - /* search start and end strings for the signatures */ - begin = memstr(buf, len, SIGBEGIN, strlen(SIGBEGIN)) + strlen(SIGBEGIN); - end = memstr(buf, len, SIGEND, strlen(SIGEND)); - if (!(begin && end) || end != (buf + len - strlen(SIGEND))) - return 0; + if (armored) { + /* search start and end strings for the signatures */ + begin = memstr(buf, len, SIGBEGIN, strlen(SIGBEGIN)) + strlen(SIGBEGIN); + end = memstr(buf, len, SIGEND, strlen(SIGEND)); + if (!(begin && end) || end != (buf + len - strlen(SIGEND))) + return 0; + } /* ed25519 signatures are 64 bytes longs */ *sig = malloc(64); @@ -152,28 +160,34 @@ extractsig(unsigned char **sig, char *buf, size_t len) memset(*sig, 0, 64); - /* - * base64 signature are wrapped at 76 chars. - * 76 being a multiple of 4, it means we can decode the signature in - * chunks of 76 bytes, and concatenate them together to get the - * original data. - */ - for (i = 0; begin+i < end; i+=77) { + if (armored) { /* - * black magic pointer arithmetic there.. - * if we reached the "end" pointer, it means we're at the end - * of the signature. - * The line length is either 76 bytes long, or less (for the - * last line) + * base64 signature are wrapped at 76 chars. + * 76 being a multiple of 4, it means we can decode the signature in + * chunks of 76 bytes, and concatenate them together to get the + * original data. */ - n = begin+i+76 < end ? 76 : end - (begin + i); - memset(base64, 0, 76); - memcpy(base64, begin+i, n); - - n = base64_decode(&tmp, base64, n); - memcpy((*sig) + siglen, tmp, n); - siglen += n; - free(tmp); + for (i = 0; begin+i < end; i+=77) { + /* + * black magic pointer arithmetic there.. + * if we reached the "end" pointer, it means we're at the end + * of the signature. + * The line length is either 76 bytes long, or less (for the + * last line) + */ + n = begin+i+76 < end ? 76 : end - (begin + i); + memset(base64, 0, 76); + memcpy(base64, begin+i, n); + + n = base64_decode(&tmp, base64, n); + memcpy((*sig) + siglen, tmp, n); + siglen += n; + free(tmp); + } + } else { + /* assume the signature is the last 64 bytes of the stream */ + if (memcpy((*sig), buf + len - 64, 64)) + siglen = 64; } return siglen; @@ -268,16 +282,21 @@ sign(FILE *fp, FILE *key) fwrite(msg, 1, len, stdout); free(msg); - /* .. followed by the signature delimiter .. */ - fwrite(SIGBEGIN, 1, strlen(SIGBEGIN), stdout); + if (armored) { + /* .. followed by the signature delimiter .. */ + fwrite(SIGBEGIN, 1, strlen(SIGBEGIN), stdout); - /* .. then the base64 encoded signature .. */ - len = base64_encode(&base64, sig, 64); - base64_fold(stdout, base64, len, 0); - free(base64); + /* .. then the base64 encoded signature .. */ + len = base64_encode(&base64, sig, 64); + base64_fold(stdout, base64, len, 0); + free(base64); - /* .. and the final signature delimiter! */ - fwrite(SIGEND, 1, strlen(SIGEND), stdout); + /* .. and the final signature delimiter! */ + fwrite(SIGEND, 1, strlen(SIGEND), stdout); + } else { + /* simply write the signature as-is */ + fwrite(sig, 1, 64, stdout); + } return 0; } @@ -369,7 +388,7 @@ check(FILE *fp, FILE *key) if (verbose) fprintf(stderr, "Extracting signature from input\n"); - if (extractsig(&sig, buf, len) != 65) { + if (extractsig(&sig, buf, len) < 64) { if (verbose) fprintf(stderr, "ERROR: No valid signature found\n"); @@ -446,6 +465,9 @@ main(int argc, char *argv[]) FILE *key = NULL, *fp = NULL; ARGBEGIN{ + case 'a': + armored = 1; + break; case 'f': key = fopen(EARGF(usage()), "r"); break;