@@ 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 {
@@ 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 */
@@ 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);