commit c1382e6b640f4805c9b4f8cf0cacd5b2c89cf050
parent c542737153224f9b6dde9d0e2281d67a8d79e02d
Author: William Casarin <jb55@jb55.com>
Date: Sun, 17 Jan 2021 12:33:45 -0800
gather keyids
Diffstat:
5 files changed, 166 insertions(+), 6 deletions(-)
diff --git a/src/ap_json.c b/src/ap_json.c
@@ -208,7 +208,7 @@ static int handle_wssigbuf(struct ap_json *a)
for (i = 0; i < n_headers; i++) {
str = &strs[i];
- if (!push_data(c, str->text, str->size)) {
+ if (!push_escaped(c, str->text, str->size)) {
return 0;
}
if (!push_str(c, ": ")) {
@@ -221,7 +221,8 @@ static int handle_wssigbuf(struct ap_json *a)
return 0;
}
} else if ((header = find_header(a->req->headers, str->text, str->size))) {
- if (!push_str(c, header->value)) {
+ if (!push_escaped(c, (unsigned char*)header->value,
+ strlen(header->value))) {
return 0;
}
} else {
diff --git a/src/cursor.h b/src/cursor.h
@@ -33,6 +33,11 @@ static inline void *cursor_alloc(struct cursor *mem, unsigned long size)
return ret;
}
+static inline void reset_cursor(struct cursor *cur)
+{
+ cur->p = cur->start;
+}
+
static inline void copy_cursor(struct cursor *src, struct cursor *dest)
{
dest->start = src->start;
diff --git a/src/hash.h b/src/hash.h
@@ -0,0 +1,34 @@
+
+
+#ifndef CHIBIPUB_HASH
+#define CHIBIPUB_HASH
+
+#include "blake3/blake3.h"
+
+static inline uint32_t fnv1a_byte(unsigned char b, uint32_t hash)
+{
+ return (b ^ hash) * 0x01000193;
+}
+
+
+static inline uint32_t fnv1a(unsigned char *bytes, int len)
+{
+ uint32_t hash = 0x811C9DC5;
+ unsigned char *p = bytes;
+ while (len--)
+ hash = fnv1a_byte(*p++, 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_update(&hasher, data, data_len);
+ blake3_hasher_finalize(&hasher, dest, BLAKE3_OUT_LEN);
+ return BLAKE3_OUT_LEN;
+}
+
+#endif /* CHIBIPUB_HASH */
diff --git a/src/sigcheck.c b/src/sigcheck.c
@@ -24,7 +24,7 @@ static int verify_signature(struct cursor cur, struct cursor *arena)
ubjson.data_end = cur.p;
static const char *path[] = {"@wssigbuf"};
- if (!ubjson_lookup(&ubjson, path, 2, &val)) {
+ if (!ubjson_lookup(&ubjson, path, ARRAY_SIZE(path), &val)) {
note_error(&ubjson.errs, "Signature header not found");
return 0;
}
@@ -32,10 +32,117 @@ static int verify_signature(struct cursor cur, struct cursor *arena)
return 1;
}
+static inline int push_keyid(struct cursor *c, const char *keyid, int keyid_len)
+{
+ return push_int(c, keyid_len)
+ && push_data(c, (unsigned char *)keyid, keyid_len);
+}
+
+static int has_keyid(struct cursor *keyids, const char *keyid, int keyid_len)
+{
+ struct cursor scan;
+ int size;
+
+ scan.start = keyids->start;
+ scan.p = keyids->start;
+ scan.end = keyids->p;
+
+ while (scan.p < scan.end) {
+ if (!pull_int(&scan, &size))
+ return 0;
+ if (size != keyid_len) {
+ scan.p += size;
+ continue;
+ }
+ if (!memcmp(keyid, scan.p, keyid_len)) {
+ return 1;
+ }
+ scan.p += size;
+ }
+
+ return 0;
+}
+
+static int print_keyids(struct cursor *keyids)
+{
+ struct cursor scan;
+ int size;
+
+ scan.start = keyids->start;
+ scan.p = keyids->start;
+ scan.end = keyids->p;
+
+ printf("keyids\n");
+ while (scan.p < scan.end) {
+ if (!pull_int(&scan, &size))
+ return 0;
+ printf("%.*s\n", size, scan.p);
+ scan.p += size;
+ }
+
+ return 1;
+}
+
+static int gather_keyids(unsigned char *json, int json_len,
+ struct cursor *arena, unsigned char **keyids)
+{
+ 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);
+ 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;
+
+ if (!ubjson_lookup(&ubjson, path, ARRAY_SIZE(path), &val)) {
+ note_error(&parser.errs, "@wskeyid not found");
+ return 0;
+ }
+
+ if (has_keyid(&keyids_cur, val.string, val.len)) {
+ continue;
+ }
+
+ if (!push_keyid(&keyids_cur, val.string, val.len)) {
+ note_error(&parser.errs, "push_keyid");
+ return 0;
+ }
+ }
+
+ print_keyids(&keyids_cur);
+
+ return 1;
+}
+
+static int fetch_signatures(unsigned char *json, int json_len,
+ struct cursor *arena)
+{
+ unsigned char *keyids;
+ if (!gather_keyids(json, json_len, arena, &keyids)) {
+ return 0;
+ }
+
+ return 1;
+}
+
int sigcheck(struct sigcheck *check)
{
int count = 0;
- unsigned char *p, *scratch;
+ unsigned char *p, *start, *scratch;
size_t flen;
struct json_parser jsonp;
struct json_handlers handlers;
@@ -50,11 +157,22 @@ int sigcheck(struct sigcheck *check)
make_ubjson_handlers(&handlers, &out_cur);
init_json_parser(&jsonp, p, flen, &handlers);
+ if (!fetch_signatures(p, flen, &out_cur)) {
+ note_error(&jsonp.errs, "fatal error fetching signature");
+ return 0;
+ }
+
+ start = out_cur.p;
while (parse_json(&jsonp)) {
- printf("success #%d\n", ++count);
+ count++;
+ printf("[%d] parse success, \n", count);
+
if (!verify_signature(out_cur, &out_cur)) {
- printf("bad signature\n");
+ printf("bad signature #%d\n", count);
}
+
+ // overwrite last ubjson
+ out_cur.p = start;
}
munmap(p, flen);
diff --git a/src/util.h b/src/util.h
@@ -7,6 +7,8 @@
#include "cursor.h"
+#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
+
static inline int stricmp(const char *a, const char *b) {
int len, i;