Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
184 changes: 112 additions & 72 deletions generate_sbat_var_defs.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,119 +9,158 @@

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>

typedef struct sbat_revocation sbat_revocation;

struct sbat_revocation {
int date;
unsigned int date;
char *revocations;
sbat_revocation *next;
};

static sbat_revocation *revlisthead;

int
readfile(char *SbatLevel_Variable)
static void
free_revocation_list(void)
{
sbat_revocation *rle = revlisthead;
while (rle) {
sbat_revocation *next = rle->next;
free(rle->revocations);
free(rle);
rle = next;
}
revlisthead = NULL;
}

static int
check_revocation_line(const char *line)
{
int num = -1;
if (sscanf(line, "%*[^, \t],%*[0-9]%n", &num) < 0 ||
num < 0 || line[num] != '\0') {
fprintf(stderr, "Invalid revocation line: %s\n", line);
return -1;
}
return 0;
}

static void
chomp(char *str)
{
size_t len = strlen(str);
if (len > 0 && str[--len] == '\n')
str[len] = '\0';
}

static int
readfile(const char *SbatLevel_Variable)
{
FILE *varfilep;
char line[1024];
int date;
int ret = -1;

unsigned int revocationsp = 0;

sbat_revocation *revlistlast = NULL;
sbat_revocation *revlistentry = NULL;

revlisthead = NULL;
free_revocation_list();

varfilep = fopen(SbatLevel_Variable, "r");
if (varfilep == NULL)
if (varfilep == NULL) {
fprintf(stderr, "Error opening file %s\n", SbatLevel_Variable);
return -1;
}

while (fgets(line, sizeof(line), varfilep) != NULL) {
if (sscanf(line, "sbat,1,%d\n", &date) && strlen(line) == 18) {
revlistentry = calloc(1, sizeof(sbat_revocation));
if (revlistentry == NULL)
unsigned int date;
size_t revocationsp = 0;

if (!sscanf(line, "sbat,1,%u\n", &date) || strlen(line) != 18)
continue;
revlistentry = calloc(1, sizeof(sbat_revocation));
if (revlistentry == NULL) {
fprintf(stderr, "Out of memory\n");
goto err;
}
if (revlisthead == NULL)
revlisthead = revlistentry;
else
revlistlast->next = revlistentry;

revlistlast = revlistentry;

revlistentry->date = date;
while (fgets(line, sizeof(line), varfilep) != NULL) {
chomp(line);

char *new = NULL;
new = realloc(revlistentry->revocations,
revocationsp + strlen(line) + 3);
if (new == NULL) {
fprintf(stderr, "Out of memory\n");
goto err;
if (revlisthead == NULL)
revlisthead = revlistentry;
else
revlistlast->next = revlistentry;

revlistlast = revlistentry;

revlistentry->date = date;
while (line[0] != '\n' &&
fgets(line, sizeof(line), varfilep) != NULL) {
char *new = NULL;
new = realloc(revlistentry->revocations,
revocationsp + strlen(line) + 2);
if (new == NULL) {
ret = -1;
goto err;
}
revlistentry->revocations = new;
if (strlen(line) > 1) {
line[strlen(line) - 1] = 0;
sprintf(revlistentry->revocations +
revocationsp,
"%s\\n", line);
revocationsp =
revocationsp + strlen(line) + 2;
}
}
revocationsp = 0;
new[revocationsp] = '\0';
revlistentry->revocations = new;
if (strlen(line) == 0)
break;

if (check_revocation_line(line))
goto err;
sprintf(revlistentry->revocations + revocationsp,
"%s\\n", line);
revocationsp = strlen(revlistentry->revocations);
}
}

ret = 1;
if (!ferror(varfilep))
ret = 0;
err:
if (ret < 0 && revlisthead) {
sbat_revocation *rle = revlisthead;
while (rle) {
sbat_revocation *next = rle->next;
if (rle->revocations)
free(rle->revocations);
free(rle);
rle = next;
}
revlisthead = NULL;
}
if (ret < 0)
free_revocation_list();
fclose(varfilep);
return ret;
}

int
writefile()
static int
writefile(void)
{
int epochfound = 0;
int epochdate = 2021030218;
int latestdate = 0;
bool epochfound = false;
unsigned int epochdate = 2021030218;
unsigned int latestdate = 0;

sbat_revocation *revlistentry;
sbat_revocation *latest_revlistentry = NULL;
const sbat_revocation *revlistentry;
const sbat_revocation *latest_revlistentry = NULL;

revlistentry = revlisthead;

while (revlistentry != NULL) {
if (revlistentry->date == epochdate) {
printf("#ifndef GEN_SBAT_VAR_DEFS_H_\n"
if (epochfound) {
fprintf(stderr, "Only one epoch expected\n");
return -1;
}
printf("// Autogenerated by generate_sbat_var_defs\n\n"
"#ifndef GEN_SBAT_VAR_DEFS_H_\n"
"#define GEN_SBAT_VAR_DEFS_H_\n"
"#ifndef ENABLE_SHIM_DEVEL\n\n"
"#ifndef SBAT_AUTOMATIC_DATE\n"
"#define SBAT_AUTOMATIC_DATE 2024040900\n"
"#endif /* SBAT_AUTOMATIC_DATE */\n"
"#if SBAT_AUTOMATIC_DATE == %d\n"
"#endif /* SBAT_AUTOMATIC_DATE */\n\n"
"#if SBAT_AUTOMATIC_DATE == %u\n"
"#define SBAT_VAR_AUTOMATIC_REVOCATIONS\n",
revlistentry->date);
epochfound = 1;
} else if (epochfound == 1) {
printf("#elif SBAT_AUTOMATIC_DATE == %d\n"
epochfound = true;
} else if (epochfound) {
printf("#elif SBAT_AUTOMATIC_DATE == %u\n"
"#define SBAT_VAR_AUTOMATIC_REVOCATIONS \"%s\"\n",
revlistentry->date,
revlistentry->revocations);
} else {
fprintf(stderr, "Revocation not expected before epoch\n");
return -1;
}
if (revlistentry->date > latestdate) {
latest_revlistentry = revlistentry;
Expand All @@ -130,25 +169,27 @@ writefile()
revlistentry = revlistentry->next;
}

if (epochfound == 0 || !latest_revlistentry)
if (!epochfound || !latest_revlistentry) {
fprintf(stderr, "Epoch not found\n");
return -1;
}

printf("#else\n"
"#error \"Unknown SBAT_AUTOMATIC_DATE\"\n"
"#endif /* SBAT_AUTOMATIC_DATE == */\n\n"
"#define SBAT_VAR_AUTOMATIC_DATE QUOTEVAL(SBAT_AUTOMATIC_DATE)\n"
"#define SBAT_VAR_AUTOMATIC \\\n"
" SBAT_VAR_SIG SBAT_VAR_VERSION SBAT_VAR_AUTOMATIC_DATE \"\\n\" \\\n"
" SBAT_VAR_AUTOMATIC_REVOCATIONS\n\n");
" SBAT_VAR_SIG SBAT_VAR_VERSION SBAT_VAR_AUTOMATIC_DATE \"\\n\" \\\n"
" SBAT_VAR_AUTOMATIC_REVOCATIONS\n\n");

printf("#define SBAT_VAR_LATEST_DATE \"%d\"\n"
printf("#define SBAT_VAR_LATEST_DATE \"%u\"\n"
"#define SBAT_VAR_LATEST_REVOCATIONS \"%s\"\n",
latest_revlistentry->date,
latest_revlistentry->revocations);

printf("#define SBAT_VAR_LATEST \\\n"
" SBAT_VAR_SIG SBAT_VAR_VERSION SBAT_VAR_LATEST_DATE \"\\n\" \\\n"
" SBAT_VAR_LATEST_REVOCATIONS\n\n"
" SBAT_VAR_SIG SBAT_VAR_VERSION SBAT_VAR_LATEST_DATE \"\\n\" \\\n"
" SBAT_VAR_LATEST_REVOCATIONS\n\n"
"#endif /* !ENABLE_SHIM_DEVEL */\n"
"#endif /* !GEN_SBAT_VAR_DEFS_H_ */\n");

Expand All @@ -161,13 +202,12 @@ main(int argc, char *argv[])
{
char SbatLevel_Variable[2048];

if (argc == 2)
if (argc >= 2)
snprintf(SbatLevel_Variable, 2048, "%s/SbatLevel_Variable.txt", argv[1]);
else
snprintf(SbatLevel_Variable, 2048, "SbatLevel_Variable.txt");

if (readfile(SbatLevel_Variable))
return writefile();
else
return -1;
return writefile();
}