commit 431f3822009b5a961e7e62953d5da4baa2fcaad1
parent c1382e6b640f4805c9b4f8cf0cacd5b2c89cf050
Author: William Casarin <jb55@jb55.com>
Date: Sun, 17 Jan 2021 22:24:41 -0800
initial sigcache logic
Diffstat:
5 files changed, 165 insertions(+), 21 deletions(-)
diff --git a/Makefile b/Makefile
@@ -19,7 +19,8 @@ BLAKE3_OBJS = deps/blake3/blake3.o \
deps/blake3/blake3_portable.o \
deps/blake3/blake3_sse2_x86-64_unix.o \
deps/blake3/blake3_sse41_x86-64_unix.o \
- deps/blake3/blake3_avx2_x86-64_unix.o
+ deps/blake3/blake3_avx2_x86-64_unix.o \
+ deps/blake3/blake3_avx512_x86-64_unix.o \
HEADERS = $(wildcard src/*.h) deps/sha256/sha256.h
diff --git a/src/hash.h b/src/hash.h
@@ -18,14 +18,14 @@ static inline uint32_t fnv1a(unsigned char *bytes, int len)
while (len--)
hash = fnv1a_byte(*p++, hash);
- return hash
+ return hash;
}
static inline int blake3_hash(unsigned char *data, int data_len,
unsigned char *dest)
{
blake3_hasher hasher;
- blake3_hadher_init(&hasher);
+ blake3_hasher_init(&hasher);
blake3_hasher_update(&hasher, data, data_len);
blake3_hasher_finalize(&hasher, dest, BLAKE3_OUT_LEN);
return BLAKE3_OUT_LEN;
diff --git a/src/io.c b/src/io.c
@@ -22,3 +22,30 @@ int map_file(const char *filename, unsigned char **p, size_t *flen)
return *p != MAP_FAILED;
}
+int read_fd(FILE *fd, unsigned char *buf, int buflen, int *written)
+{
+ unsigned char *p = buf;
+ int len = 0;
+ *written = 0;
+
+ do {
+ len = fread(p, 1, 4096, fd);
+ *written += len;
+ p += len;
+ if (p > buf + buflen)
+ return 0;
+ } while (len == 4096);
+
+ return 1;
+}
+
+int read_file(const char *filename, unsigned char *out, int out_len, int *written)
+{
+ FILE *file = NULL;
+
+ file = fopen(filename, "rb");
+ if (file == NULL)
+ return 0;
+
+ return read_fd(file, out, out_len, written);
+}
diff --git a/src/io.h b/src/io.h
@@ -3,7 +3,11 @@
#define CHIBIPUB_IO
#include <stddef.h>
+#include <stdio.h>
int map_file(const char *filename, unsigned char **p, size_t *flen);
+int read_fd(FILE *fd, unsigned char *buf, int buflen, int *written);
+int read_file(const char *filename, unsigned char *out, int out_len, int *written);
+
#endif /* CHIBIPUB_IO */
diff --git a/src/sigcheck.c b/src/sigcheck.c
@@ -2,11 +2,15 @@
#define SCRATCH_SIZE 1048576
#include <sys/mman.h>
+#include <sys/stat.h>
+#include <sys/types.h>
#include <stdlib.h>
#include <assert.h>
+#include <unistd.h>
#include "json.h"
#include "ubjson.h"
+#include "hash.h"
#include "io.h"
#include "sigcheck.h"
#include "util.h"
@@ -32,32 +36,55 @@ static int verify_signature(struct cursor cur, struct cursor *arena)
return 1;
}
+struct keyid {
+ unsigned char *pubkey;
+ int pubkey_size;
+};
+
static inline int push_keyid(struct cursor *c, const char *keyid, int keyid_len)
{
+ struct keyid offset = {0};
return push_int(c, keyid_len)
- && push_data(c, (unsigned char *)keyid, keyid_len);
+ && push_data(c, (unsigned char *)keyid, keyid_len)
+ && push_data(c, (unsigned char *)&offset, sizeof(offset)); // reserved for pubkey data index
+}
+
+static int pull_keyid(struct cursor *c, unsigned char **keyid_str,
+ int *keyid_len, struct keyid **keyid)
+{
+ if (!pull_int(c, keyid_len)) {
+ return 0;
+ }
+
+ *keyid_str = c->p;
+ c->p += *keyid_len;
+ *keyid = (struct keyid*)c->p;
+ c->p += sizeof(struct keyid);
+
+ return 1;
}
static int has_keyid(struct cursor *keyids, const char *keyid, int keyid_len)
{
struct cursor scan;
int size;
+ unsigned char *keyid_str;
+ struct keyid *offset;
scan.start = keyids->start;
scan.p = keyids->start;
scan.end = keyids->p;
while (scan.p < scan.end) {
- if (!pull_int(&scan, &size))
+ if (!pull_keyid(&scan, &keyid_str, &size, &offset)) {
return 0;
+ }
if (size != keyid_len) {
- scan.p += size;
continue;
}
- if (!memcmp(keyid, scan.p, keyid_len)) {
+ if (!memcmp(keyid, keyid_str, keyid_len)) {
return 1;
}
- scan.p += size;
}
return 0;
@@ -67,6 +94,8 @@ static int print_keyids(struct cursor *keyids)
{
struct cursor scan;
int size;
+ unsigned char *keyid_str;
+ struct keyid *keyid;
scan.start = keyids->start;
scan.p = keyids->start;
@@ -74,36 +103,32 @@ static int print_keyids(struct cursor *keyids)
printf("keyids\n");
while (scan.p < scan.end) {
- if (!pull_int(&scan, &size))
+ if (!pull_keyid(&scan, &keyid_str, &size, &keyid))
return 0;
- printf("%.*s\n", size, scan.p);
- scan.p += size;
+ printf("%.*s\n", size, keyid_str);
}
return 1;
}
static int gather_keyids(unsigned char *json, int json_len,
- struct cursor *arena, unsigned char **keyids)
+ struct cursor *arena, struct cursor *keyids_cur)
{
static const char *path[] = {"@wskeyid"};
const int ubjson_mem_size = 1024 * 256;
struct ubjson ubjson;
struct json val;
- struct cursor keyids_cur;
struct json_parser parser;
struct json_handlers handlers;
unsigned char *ubjson_mem;
ubjson_mem = cursor_alloc(arena, ubjson_mem_size);
- make_cursor(arena->p, arena->end, &keyids_cur);
+ make_cursor(arena->p, arena->end, keyids_cur);
init_ubjson(&ubjson, ubjson_mem, ubjson_mem_size);
make_ubjson_handlers(&handlers, &ubjson.cur);
init_json_parser(&parser, json, json_len, &handlers);
- *keyids = keyids_cur.start;
-
while (parse_json(&parser)) {
init_ubjson(&ubjson, ubjson_mem, ubjson_mem_size);
ubjson.data_end = ubjson.cur.p;
@@ -113,29 +138,116 @@ static int gather_keyids(unsigned char *json, int json_len,
return 0;
}
- if (has_keyid(&keyids_cur, val.string, val.len)) {
+ if (has_keyid(keyids_cur, val.string, val.len)) {
continue;
}
- if (!push_keyid(&keyids_cur, val.string, val.len)) {
+ if (!push_keyid(keyids_cur, val.string, val.len)) {
note_error(&parser.errs, "push_keyid");
return 0;
}
}
- print_keyids(&keyids_cur);
+ print_keyids(keyids_cur);
+
+ return 1;
+}
+
+static int hex_bytes(unsigned char *bytes, int n_bytes, unsigned char *buf,
+ int buf_size)
+{
+ static const char *hex = "0123456789abcdef";
+ int b;
+
+ if (n_bytes * 2 < buf_size)
+ return 0;
+
+ for (int i = 0; i < buf_size; i++) {
+ b = bytes[i/2];
+ b = i % 2 ? b & 0x0F : (b & 0xF0) >> 4;
+ buf[i] = hex[b];
+ }
return 1;
}
+static int get_cached_pubkey(unsigned char *keyid, int size,
+ unsigned char *buf, int buflen, int *pubkey_size)
+{
+ unsigned char hash[32];
+ unsigned char hash_str[64];
+ char path[128] = {0};
+ mode_t mode = 0777;
+
+ // if we sucessfully created a directory, then we definitely
+ // don't have any cached pubkeys
+ if (0 == mkdir(".chibipub", mode)) {
+ return 0;
+ }
+
+ if (0 == mkdir(".chibipub/objects", mode)) {
+ return 0;
+ }
+
+ blake3_hash(keyid, size, hash);
+ if (!hex_bytes(hash, 32, hash_str, 64)) {
+ assert(0);
+ }
+
+ sprintf(path, ".chibipub/objects/%c%c/%.*s",
+ hash_str[0], hash_str[1], 64, hash_str);
+
+ fprintf(stderr, "sig cache exists? '%s' ", path);
+ if (access(path, F_OK)) {
+ fprintf(stderr, "no.\n");
+ return 0;
+ }
+ fprintf(stderr, "yes!\n");
+
+ return read_file(path, buf, buflen, pubkey_size);
+}
+
+static int fetch_signature(unsigned char *keyid, int keyid_len)
+{
+ printf("fetch signature %.*s\n", keyid_len, keyid);
+ return 1;
+}
+
static int fetch_signatures(unsigned char *json, int json_len,
struct cursor *arena)
{
- unsigned char *keyids;
+ struct cursor keyids;
+ struct cursor scan;
+ int size;
+ unsigned char *keyid_str;
+ struct keyid *keyid;
+
if (!gather_keyids(json, json_len, arena, &keyids)) {
return 0;
}
+ scan.start = keyids.start;
+ scan.p = scan.start;
+ scan.end = keyids.p;
+ while (scan.p < scan.end) {
+ if (!pull_keyid(&scan, &keyid_str, &size, &keyid)) {
+ return 0;
+ }
+
+ if (get_cached_pubkey(scan.p, size, arena->p,
+ arena->end - arena->p,
+ &keyid->pubkey_size)) {
+ keyid->pubkey = arena->p;
+ arena->p += keyid->pubkey_size;
+ printf("got cached pubkey of size %d... do something\n",
+ keyid->pubkey_size);
+
+ continue;
+ }
+
+ fetch_signature(keyid_str, size);
+ }
+
return 1;
}
@@ -165,7 +277,7 @@ int sigcheck(struct sigcheck *check)
start = out_cur.p;
while (parse_json(&jsonp)) {
count++;
- printf("[%d] parse success, \n", count);
+ printf("[%d] parse success\n", count);
if (!verify_signature(out_cur, &out_cur)) {
printf("bad signature #%d\n", count);