Skip to content

Commit

Permalink
Refactor code
Browse files Browse the repository at this point in the history
- split off duplicated code into util.h
- use u32/u64 consistently
- clean up rpm signature insertion code
  • Loading branch information
mlschroe committed Nov 16, 2022
1 parent da78887 commit ac43c42
Show file tree
Hide file tree
Showing 13 changed files with 665 additions and 840 deletions.
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ CFLAGS = -O3 -Wall -D_FILE_OFFSET_BITS=64 -g

all: sign

sign: sign.o hash.o base64.o pgp.o x509.o rpm.o appimage.o sock.o clearsign.o appx.o zip.o pe.o ko.o
sign: sign.o hash.o base64.o pgp.o x509.o rpm.o appimage.o sock.o clearsign.o appx.o zip.o pe.o ko.o util.o

clean:
rm -f sign sign.o hash.o base64.o pgp.o x509.o rpm.o appimage.o sock.o clearsign.o appx.o zip.o pe.o ko.o
rm -f sign sign.o hash.o base64.o pgp.o x509.o rpm.o appimage.o sock.o clearsign.o appx.o zip.o pe.o ko.o util.o
test:
prove t/*.t
93 changes: 32 additions & 61 deletions appimage.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,15 @@ elf16(unsigned char *buf, int le)
return buf[0] << 8 | buf[1];
}

static inline unsigned int
static inline u32
elf32(unsigned char *buf, int le)
{
if (le)
return buf[0] | buf[1] << 8 | buf[2] << 16 | buf[3] << 24;
return buf[0] << 24 | buf[1] << 16 | buf[2] << 8 | buf[3];
}

static inline unsigned int
static inline u32
elf64(unsigned char *buf, int le, int is64)
{
if (is64)
Expand All @@ -54,27 +54,17 @@ elf64(unsigned char *buf, int le, int is64)
return buf[0] << 24 | buf[1] << 16 | buf[2] << 8 | buf[3];
}

static void
perror_exit(const char *s)
{
perror(s);
exit(1);
}

int
appimage_read(char *filename, HASH_CONTEXT *ctx)
{
unsigned char appimagedigest[64]; /* sha256 sum */
char *digestfilename;
FILE *fp;

digestfilename = malloc(strlen(filename) + 8);
digestfilename = doalloc(strlen(filename) + 8);
sprintf(digestfilename, "%s.digest", filename);
if ((fp = fopen(digestfilename, "r")) == 0 || 64 != fread(appimagedigest, 1, 64, fp))
{
perror(digestfilename);
exit(1);
}
dodie_errno(digestfilename);
fclose(fp);
free(digestfilename);
hash_write(ctx, appimagedigest, 64);
Expand All @@ -94,98 +84,79 @@ appimage_write_signature(char *filename, byte *signature, int length)
FILE *fp;
char *armored_signature;
size_t siglen;
unsigned int sha256_sig_offset = 0;
unsigned int sha256_sig_size = 0;
off_t sha256_sig_offset = 0;
u32 sha256_sig_size = 0;
unsigned char *sects, *strsect;
unsigned int slen;
unsigned int o;
u32 slen;

if ((fp = fopen(filename, "r+")) == 0)
perror_exit(filename);
dodie_errno(filename);
l = fread(elfbuf, 1, 128, fp);
if (l < 128)
perror_exit("offset 1");
dodie("offset 1");
if (elfbuf[0] != 0x7f || elfbuf[1] != 'E' || elfbuf[2] != 'L' || elfbuf[3] != 'F')
perror_exit("offset 2");
dodie("not an ELF appimage file");
is64 = elfbuf[4] == 2;
le = elfbuf[5] != 2;
if (is64 && l < 0x40)
perror_exit("offset 3");
dodie("appimage EOF");
soff = elf64(is64 ? elfbuf + 40 : elfbuf + 32, le, is64);
if (soff == (off_t)~0)
perror_exit("offset 4");
if (soff == (off_t)(u32)~0)
dodie("bad soff");
ssiz = elf16(elfbuf + (is64 ? 0x40 - 6 : 0x34 - 6), le);
if (ssiz < (is64 ? 64 : 40) || ssiz >= 32768)
perror_exit("offset 5");
dodie("bad ssiz");
snum = elf16(elfbuf + (is64 ? 0x40 - 4 : 0x34 - 4), le);
stridx = elf16(elfbuf + (is64 ? 0x40 - 2 : 0x34 - 2), le);
if (stridx >= snum)
perror_exit("offset 6");
sects = malloc(snum * ssiz);
if (!sects)
perror_exit("offset 7");
dodie("bad stridx");
sects = doalloc(snum * ssiz);
if (fseek(fp, soff, SEEK_SET) != 0 || fread(sects, 1, snum * ssiz, fp) != snum * ssiz)
{
free(sects);
perror_exit("offset");
}
dodie_errno("seek/read sects");
strsect = sects + stridx * ssiz;
if (elf32(strsect + 4, le) != 3)
{
free(sects);
perror_exit("offset");
}
dodie("bad strsect");
soff = elf64(is64 ? strsect + 24 : strsect + 16, le, is64);
slen = elf64(is64 ? strsect + 32 : strsect + 20, le, is64);
if (soff == (off_t)~0 || slen == ~0 || (int)slen < 0)
{
free(sects);
perror_exit("offset");
}
strsect = malloc(slen);
if (!strsect)
{
free(sects);
perror_exit("offset");
}
if (soff == (off_t)(u32)~0 || slen > 0xfffffff)
dodie("bad soff/slen");
strsect = doalloc(slen);
if (fseek(fp, soff, SEEK_SET) != 0 || fread(strsect, 1, slen, fp) != slen)
{
free(sects);
free(strsect);
perror_exit("offset");
}
dodie("seek/read strsect");
for (i = 0; i < snum; i++)
{
o = elf32(sects + i * ssiz, le);
u32 o = elf32(sects + i * ssiz, le);
if (o > slen)
continue;
// printf("sect #%d %s (o=%d)\n", i, strsect + o, o);

if (o + 11 <= slen && memcmp(strsect + o, ".sha256_sig", 11) == 0) {
unsigned int sh_offset = i * ssiz + (is64 ? 24 : 16);
u32 sh_offset = i * ssiz + (is64 ? 24 : 16);
sha256_sig_offset = elf64(sects + sh_offset, le, is64);
sha256_sig_size = elf64(sects + sh_offset + (is64 ? 8 : 4), le, is64);
if (sha256_sig_offset == (off_t)(u32)~0 || sha256_sig_size > 0xfffffff)
dodie("bad signature soff/slen");
break;
}
}
free(strsect);
free(sects);

if (sha256_sig_offset == 0)
perror_exit(".sha256_sig not found");
dodie(".sha256_sig not found");

armored_signature = get_armored_signature(signature, length);
siglen = strlen(armored_signature) + 1;
if (siglen > sha256_sig_size)
perror_exit("section too small for signature");
dodie("section too small for signature");

if (fseek(fp, sha256_sig_offset, SEEK_SET) == (off_t)-1)
perror_exit("lseek");
dodie_errno("fseek");
if (fwrite(armored_signature, siglen, 1, fp) != 1)
perror_exit("signature write");
dodie_errno("signature write");
for(; siglen < sha256_sig_size; siglen++)
fputc(0x0, fp);
if (fclose(fp))
perror_exit("fclose error");
dodie_errno("fclose error");
free(armored_signature);
}

48 changes: 15 additions & 33 deletions appx.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,44 +17,31 @@
*
***************************************************************/

#include <unistd.h>

#include "inc.h"

extern int appxsig2stdout;

static void
dosha256hash(int fd, unsigned long long size, unsigned char *out)
dosha256hash(int fd, u64 size, unsigned char *out)
{
unsigned char buf[65536];
HASH_CONTEXT ctx;

hash_init(&ctx);
while (size > 0)
{
int r = read(fd, buf, size > 65536 ? 65536 : size);
if (r < 0)
{
perror("read");
exit(1);
}
if (r == 0)
{
fprintf(stderr, "dosha256hash: unexpeced EOF\n");
exit(1);
}
hash_write(&ctx, buf, r);
size -= r;
int chunk = size > sizeof(buf) ? sizeof(buf) : size;
doread(fd, buf, chunk);
hash_write(&ctx, buf, chunk);
size -= chunk;
}
hash_final(&ctx);
memcpy(out, hash_read(&ctx), 32);
}

static unsigned int
static u32
hashfileentry(struct zip *zip, int fd, char *fn, unsigned char *dig)
{
unsigned char *entry;
unsigned long long datasize;
u64 datasize;

entry = zip_findentry(zip, fn);
if (!entry)
Expand All @@ -79,11 +66,7 @@ appx_create_contentinfo(struct appxdata *appxdata, int fd)
static const unsigned char axcisig[4] = { 0x41, 0x58, 0x43, 0x49 };

/* rewind */
if (lseek(fd, 0, SEEK_SET) == (off_t)-1)
{
perror("seek");
exit(1);
}
doseek(fd, 0);
/* create digests */
memset(digest, 0, sizeof(digest));
memcpy(digest, axmgsig, 4);
Expand Down Expand Up @@ -125,10 +108,7 @@ appx_read(struct appxdata *appxdata, int fd, char *filename, HASH_CONTEXT *ctx,
int offset;

if (hashalgo != HASH_SHA256)
{
fprintf(stderr, "can only use sha256 for hashing\n");
exit(1);
}
dodie("can only use sha256 for appx hashing");
memset(appxdata, 0, sizeof(*appxdata));
zip_read(&appxdata->zip, fd);

Expand All @@ -149,15 +129,17 @@ appx_write(struct appxdata *appxdata, int outfd, int fd, struct x509 *cert, unsi
{
static const unsigned char p7xmagic[4] = { 0x50, 0x4b, 0x43, 0x58 };
struct x509 cb;
extern int appxdetached;

x509_init(&cb);
x509_pkcs7_signed_data(&cb, &appxdata->cb_content, &appxdata->cb_signedattrs, sig, siglen, cert, othercerts, 0);
/* add file magic */
/* prepend file magic */
x509_insert(&cb, 0, p7xmagic, sizeof(p7xmagic));
if (appxsig2stdout)
if (appxdetached)
{
write(1, cb.buf, cb.len);
exit(0);
dowrite(outfd, cb.buf, cb.len);
x509_free(&cb);
return;
}
/* append file to zip, must use deflated compression */
zip_appendfile(&appxdata->zip, "AppxSignature.p7x", cb.buf, cb.len, 8, appxdata->datetime);
Expand Down
4 changes: 2 additions & 2 deletions base64.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ printr64(FILE *f, const byte *str, int len)
}

char *
r64dec1(char *p, unsigned int *vp, int *eofp)
r64dec1(char *p, u32 *vp, int *eofp)
{
int i, x;
unsigned int v = 0;
Expand Down Expand Up @@ -89,7 +89,7 @@ r64dec1(char *p, unsigned int *vp, int *eofp)
char *
r64dec(char *p, unsigned char **bpp)
{
unsigned int v;
u32 v;
int eof = 0;
unsigned char *bp = *bpp;
while (!eof)
Expand Down
45 changes: 45 additions & 0 deletions bele.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@

static inline unsigned int
getle2(const unsigned char *b)
{
return b[0] | b[1] << 8;
}

static inline unsigned int
getle4(const unsigned char *b)
{
return b[0] | b[1] << 8 | b[2] << 16 | b[3] << 24;
}

static inline void
setle2(unsigned char *b, unsigned int v)
{
b[0] = v & 255;
b[1] = (v >> 8) & 255;
}

static inline void
setle4(unsigned char *b, unsigned int v)
{
b[0] = v & 255;
b[1] = (v >> 8) & 255;
b[2] = (v >> 16) & 255;
b[3] = (v >> 24) & 255;
}


static inline unsigned int
getbe4(const unsigned char *b)
{
return b[0] << 24 | b[1] << 16 | b[2] << 8 | b[3];
}

static inline void
setbe4(unsigned char *b, unsigned int x)
{
b[0] = x >> 24;
b[1] = x >> 16;
b[2] = x >> 8;
b[3] = x;
}

Loading

0 comments on commit ac43c42

Please sign in to comment.