version 1.5, 2016/09/03 11:22:09 |
version 1.6, 2016/09/03 12:12:21 |
|
|
#include <sha2.h> |
#include <sha2.h> |
#include <string.h> |
#include <string.h> |
#include <sys/stat.h> |
#include <sys/stat.h> |
|
#include <time.h> |
#include <fcntl.h> |
#include <fcntl.h> |
#include "signify.h" |
#include "signify.h" |
|
|
|
|
#define MYBUFSIZE 65536LU |
#define MYBUFSIZE 65536LU |
|
|
|
|
static uint8_t fake[10] = { 0x1f, 0x8b, 8, 0, 0, 0, 0, 0, 0, 3 }; |
static uint8_t fake[10] = { 0x1f, 0x8b, 8, FCOMMENT_FLAG, 0, 0, 0, 0, 0, 3 }; |
|
|
/* XXX no static there, confuses the hell out of gcc which displays |
/* XXX no static there, confuses the hell out of gcc which displays |
* non-existent warnings. |
* non-existent warnings. |
|
|
{ |
{ |
uint8_t *buffer; |
uint8_t *buffer; |
uint8_t *residual; |
uint8_t *residual; |
uint8_t output[SHA256_DIGEST_STRING_LENGTH]; |
uint8_t output[SHA512_DIGEST_STRING_LENGTH]; |
|
|
buffer = xmalloc(bufsize); |
buffer = xmalloc(bufsize); |
residual = (uint8_t *)endsha + 1; |
residual = (uint8_t *)endsha + 1; |
|
|
if (more == 0) |
if (more == 0) |
break; |
break; |
} |
} |
SHA256Data(buffer, n, output); |
SHA512Data(buffer, n, output); |
if (endsha - sha < SHA256_DIGEST_STRING_LENGTH-1) |
if (endsha - sha < SHA256_DIGEST_STRING_LENGTH-1) |
errx(4, "signature truncated"); |
errx(4, "signature truncated"); |
if (memcmp(output, sha, SHA256_DIGEST_STRING_LENGTH-1) != 0) |
if (memcmp(output, sha, SHA256_DIGEST_STRING_LENGTH-1) != 0) |
|
|
{ |
{ |
struct gzheader h; |
struct gzheader h; |
size_t bufsize; |
size_t bufsize; |
char *p; |
char *p, *meta; |
uint8_t *bufend; |
uint8_t *bufend; |
int fdin, fdout; |
int fdin, fdout; |
|
|
|
|
|
|
bufsize = MYBUFSIZE; |
bufsize = MYBUFSIZE; |
|
|
/* allow for arbitrary blocksize */ |
meta = p; |
if (sscanf(p, "blocksize=%zu\n", &bufsize)) { |
#define BEGINS_WITH(x, y) memcmp((x), (y), sizeof(y)-1) == 0 |
|
|
|
while (BEGINS_WITH(p, "algorithm=SHA512/256") || |
|
BEGINS_WITH(p, "date=") || |
|
sscanf(p, "blocksize=%zu\n", &bufsize) > 0) { |
while (*(p++) != '\n') |
while (*(p++) != '\n') |
continue; |
continue; |
} |
} |
|
|
|
if (*p != '\n') |
|
errx(1, "invalid signature"); |
|
*(p++) = 0; |
|
|
fdout = xopen(msgfile, O_CREAT|O_TRUNC|O_NOFOLLOW|O_WRONLY, 0666); |
fdout = xopen(msgfile, O_CREAT|O_TRUNC|O_NOFOLLOW|O_WRONLY, 0666); |
/* we don't actually copy the header, but put in a fake one with about |
/* we don't actually copy the header, but put in a fake one with about |
* zero useful information. |
* zero useful information. |
*/ |
*/ |
writeall(fdout, fake, sizeof fake, msgfile); |
writeall(fdout, fake, sizeof fake, msgfile); |
|
writeall(fdout, meta, p - meta, msgfile); |
copy_blocks(fdout, fdin, p, h.endcomment, bufsize, bufend); |
copy_blocks(fdout, fdin, p, h.endcomment, bufsize, bufend); |
free(h.buffer); |
free(h.buffer); |
close(fdout); |
close(fdout); |
|
|
char *p; |
char *p; |
uint8_t *buffer; |
uint8_t *buffer; |
uint8_t *sighdr; |
uint8_t *sighdr; |
|
char date[80]; |
|
time_t clock; |
|
|
fdin = xopen(msgfile, O_RDONLY, 0); |
fdin = xopen(msgfile, O_RDONLY, 0); |
if (fstat(fdin, &sb) == -1 || !S_ISREG(sb.st_mode)) |
if (fstat(fdin, &sb) == -1 || !S_ISREG(sb.st_mode)) |
|
|
if (lseek(fdin, h.headerlength, SEEK_SET) == -1) |
if (lseek(fdin, h.headerlength, SEEK_SET) == -1) |
err(1, "seek in %s", msgfile); |
err(1, "seek in %s", msgfile); |
|
|
space = (sb.st_size / MYBUFSIZE+1) * SHA256_DIGEST_STRING_LENGTH + |
space = (sb.st_size / MYBUFSIZE+2) * SHA256_DIGEST_STRING_LENGTH + |
80; /* long enough for blocksize=.... */ |
1024; /* long enough for extra header information */ |
|
|
msg = xmalloc(space); |
msg = xmalloc(space); |
buffer = xmalloc(bufsize); |
buffer = xmalloc(bufsize); |
snprintf(msg, space, "blocksize=%zu\n", bufsize); |
time(&clock); |
|
strftime(date, sizeof date, "%Y-%m-%dT%H:%M:%SZ", gmtime(&clock)); |
|
snprintf(msg, space, |
|
"date=%s\n" |
|
"algorithm=SHA512/256\n" |
|
"blocksize=%zu\n\n", |
|
date, bufsize); |
p = strchr(msg, 0); |
p = strchr(msg, 0); |
|
|
while (1) { |
while (1) { |
|
|
err(1, "read from %s", msgfile); |
err(1, "read from %s", msgfile); |
if (n == 0) |
if (n == 0) |
break; |
break; |
SHA256Data(buffer, n, p); |
SHA512Data(buffer, n, p); |
p += SHA256_DIGEST_STRING_LENGTH; |
p += SHA256_DIGEST_STRING_LENGTH; |
p[-1] = '\n'; |
p[-1] = '\n'; |
if (msg + space < p) |
if (msg + space < p) |
|
|
|
|
fdout = xopen(sigfile, O_CREAT|O_TRUNC|O_NOFOLLOW|O_WRONLY, 0666); |
fdout = xopen(sigfile, O_CREAT|O_TRUNC|O_NOFOLLOW|O_WRONLY, 0666); |
sighdr = createsig(seckeyfile, msgfile, msg, p-msg); |
sighdr = createsig(seckeyfile, msgfile, msg, p-msg); |
fake[3] = FCOMMENT_FLAG; |
|
fake[8] = h.xflg; |
fake[8] = h.xflg; |
|
|
writeall(fdout, fake, sizeof fake, sigfile); |
writeall(fdout, fake, sizeof fake, sigfile); |