You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
217 lines
3.7 KiB
217 lines
3.7 KiB
#include <stdint.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#include <image.h>
|
|
|
|
size_t read_u8(FILE *fp, uint8_t *val)
|
|
{
|
|
int byte;
|
|
size_t shift = 8, nbytes;
|
|
|
|
*val = 0;
|
|
|
|
for (nbytes = 0; nbytes < sizeof *val; ++nbytes) {
|
|
if ((byte = fgetc(fp)) == EOF)
|
|
return nbytes;
|
|
|
|
shift -= 8;
|
|
*val |= (byte & 0xff) << shift;
|
|
}
|
|
|
|
return nbytes;
|
|
}
|
|
|
|
size_t read_u32(FILE *fp, uint32_t *val)
|
|
{
|
|
int byte;
|
|
size_t shift = 32, nbytes;
|
|
|
|
*val = 0;
|
|
|
|
for (nbytes = 0; nbytes < sizeof *val; ++nbytes) {
|
|
if ((byte = fgetc(fp)) == EOF)
|
|
return nbytes;
|
|
|
|
shift -= 8;
|
|
*val |= (byte & 0xff) << shift;
|
|
}
|
|
|
|
return nbytes;
|
|
}
|
|
|
|
size_t read_u64(FILE *fp, uint64_t *val)
|
|
{
|
|
int byte;
|
|
size_t shift = 64, nbytes;
|
|
|
|
*val = 0;
|
|
|
|
for (nbytes = 0; nbytes < sizeof *val; ++nbytes) {
|
|
if ((byte = fgetc(fp)) == EOF)
|
|
return nbytes;
|
|
|
|
shift -= 8;
|
|
*val |= (byte & 0xff) << shift;
|
|
}
|
|
|
|
return nbytes;
|
|
}
|
|
|
|
size_t write_u8(FILE *fp, uint8_t val)
|
|
{
|
|
size_t shift = 8, nbytes;
|
|
|
|
for (nbytes = 0; nbytes < sizeof val; ++nbytes) {
|
|
shift -= 8;
|
|
|
|
if (fputc((val >> shift) & 0xff, fp) == EOF)
|
|
return nbytes;
|
|
}
|
|
|
|
return nbytes;
|
|
}
|
|
|
|
size_t write_u32(FILE *fp, uint32_t val)
|
|
{
|
|
size_t shift = 32, nbytes;
|
|
|
|
for (nbytes = 0; nbytes < sizeof val; ++nbytes) {
|
|
shift -= 8;
|
|
|
|
if (fputc((val >> shift) & 0xff, fp) == EOF)
|
|
return nbytes;
|
|
}
|
|
|
|
return nbytes;
|
|
}
|
|
|
|
size_t write_u64(FILE *fp, uint64_t val)
|
|
{
|
|
size_t shift = 64, nbytes;
|
|
|
|
for (nbytes = 0; nbytes < sizeof val; ++nbytes) {
|
|
shift -= 8;
|
|
|
|
if (fputc((val >> shift) & 0xff, fp) == EOF)
|
|
return nbytes;
|
|
}
|
|
|
|
return nbytes;
|
|
}
|
|
|
|
int rots_read_hdr(FILE *fp, struct rots_hdr *hdr)
|
|
{
|
|
char magic[8];
|
|
|
|
if (fread(magic, sizeof *magic, sizeof magic, fp) < sizeof magic)
|
|
return -1;
|
|
|
|
if (memcmp(magic, ROTS_MAGIC, 8) != 0)
|
|
return -1;
|
|
|
|
if (read_u64(fp, &hdr->timestamp) < sizeof hdr->timestamp)
|
|
return -1;
|
|
|
|
if (read_u64(fp, &hdr->size) < sizeof hdr->size)
|
|
return -1;
|
|
|
|
return 0;
|
|
}
|
|
|
|
int rots_write_hdr(FILE *fp, struct rots_hdr *hdr)
|
|
{
|
|
if (fwrite(ROTS_MAGIC, sizeof(char), 8, fp) < 8)
|
|
return -1;
|
|
|
|
if (write_u64(fp, hdr->timestamp) < sizeof hdr->timestamp)
|
|
return -1;
|
|
|
|
if (write_u64(fp, hdr->size) < sizeof hdr->size)
|
|
return -1;
|
|
|
|
return 0;
|
|
}
|
|
|
|
int rots_read_sig_hdr(FILE *fp, struct rots_sig_hdr *sig_hdr)
|
|
{
|
|
uint8_t len;
|
|
|
|
if (read_u8(fp, &len) < 1)
|
|
return -1;
|
|
|
|
if (!(sig_hdr->name = calloc(len + 1, sizeof *sig_hdr->name)))
|
|
return -1;
|
|
|
|
if (fread(sig_hdr->name, sizeof *sig_hdr->name, len, fp) < len)
|
|
goto err_free_name;
|
|
|
|
if (read_u8(fp, &len) < 1)
|
|
goto err_free_name;
|
|
|
|
if (!(sig_hdr->digest = calloc(len + 1, sizeof *sig_hdr->digest)))
|
|
goto err_free_name;
|
|
|
|
if (fread(sig_hdr->digest, sizeof *sig_hdr->digest, len, fp) < len)
|
|
goto err_free_digest;
|
|
|
|
if (read_u64(fp, &sig_hdr->timestamp) < sizeof sig_hdr->timestamp)
|
|
goto err_free_digest;
|
|
|
|
if (read_u32(fp, &sig_hdr->size) < sizeof sig_hdr->size)
|
|
goto err_free_digest;
|
|
|
|
return 0;
|
|
|
|
err_free_digest:
|
|
free(sig_hdr->digest);
|
|
err_free_name:
|
|
free(sig_hdr->name);
|
|
return -1;
|
|
}
|
|
|
|
int rots_write_sig_hdr(FILE *fp, struct rots_sig_hdr *sig_hdr)
|
|
{
|
|
size_t len;
|
|
|
|
len = strlen(sig_hdr->name);
|
|
|
|
if (write_u8(fp, len) < 1)
|
|
return -1;
|
|
|
|
if (fwrite(sig_hdr->name, sizeof *sig_hdr->name, len, fp) < len)
|
|
return -1;
|
|
|
|
len = strlen(sig_hdr->digest);
|
|
|
|
if (write_u8(fp, len) < 1)
|
|
return -1;
|
|
|
|
if (fwrite(sig_hdr->digest, sizeof *sig_hdr->digest, len, fp) < len)
|
|
return -1;
|
|
|
|
if (write_u64(fp, sig_hdr->timestamp) < sizeof sig_hdr->timestamp)
|
|
return -1;
|
|
|
|
if (write_u32(fp, sig_hdr->size) < sizeof sig_hdr->size)
|
|
return -1;
|
|
|
|
return 0;
|
|
}
|
|
|
|
void rots_cleanup_sig_hdr(struct rots_sig_hdr *sig_hdr)
|
|
{
|
|
if (!sig_hdr)
|
|
return;
|
|
|
|
if (sig_hdr->name) {
|
|
free(sig_hdr->name);
|
|
sig_hdr->name = NULL;
|
|
}
|
|
|
|
if (sig_hdr->digest) {
|
|
free(sig_hdr->digest);
|
|
sig_hdr->digest = NULL;
|
|
}
|
|
}
|
|
|