commit 4a1d3ba410f6aae3d523bca151bfd026c7454312
parent 1bb5a9fce6f04f11de5c876e00180488cfb6dd9d
Author: William Casarin <jb55@jb55.com>
Date:   Sat, 16 Jan 2021 15:56:09 -0800
build sigbuf from headers
Diffstat:
4 files changed, 68 insertions(+), 11 deletions(-)
diff --git a/src/inbox.c b/src/inbox.c
@@ -55,7 +55,7 @@ static int parse_kv(struct errors *errs, struct cursor *cur,
 	}
 
 	if (!parse_char(cur, &b, ',')) {
-		assert(*cur->end == 0);
+		//assert(*cur->end == 0);
 		return 1;
 	}
 
@@ -63,13 +63,13 @@ static int parse_kv(struct errors *errs, struct cursor *cur,
 }
 
 int parse_signature_header(struct errors *errs, struct cursor *arena,
-		const char *value, struct sig_header *out)
+		const char *value, int value_len, struct sig_header *out)
 {
 	const char *key;
 	const char *val;
 	struct cursor cur;
 	size_t out_len;
-	make_cursor((unsigned char*)value, (unsigned char*)value + strlen(value), &cur);
+	make_cursor((unsigned char*)value, (unsigned char*)value + value_len, &cur);
 	memset(out, 0, sizeof(*out));
 
 	while (1) {
diff --git a/src/inbox.h b/src/inbox.h
@@ -14,7 +14,7 @@ struct sig_header {
 };
 
 
-int parse_signature_header(struct errors *errs, struct cursor *arena, const char *value, struct sig_header *out);
+int parse_signature_header(struct errors *errs, struct cursor *arena, const char *value, int value_len, struct sig_header *out);
 int verify_signature_header(struct sig_header *sig);
 
 #endif
diff --git a/src/sigcheck.c b/src/sigcheck.c
@@ -10,19 +10,76 @@
 #include "io.h"
 #include "sigcheck.h"
 #include "util.h"
+#include "inbox.h"
+#include "errors.h"
 
-static int verify_signature(struct cursor cur)
+#include <ctype.h>
+
+static int push_header(struct ubjson *ubjson, struct cursor *arena,
+		unsigned char *header, int header_len)
+{
+	char tmp[32]={0};
+	const char *path[2];
+	struct json val;
+
+	if (header_len >= sizeof(tmp)-1) {
+		note_error(&ubjson->errs, "header name (len %d) %.*s overflows tmp buf",
+				header_len, header_len, header);
+		return 0;
+	}
+
+	path[0] = "@wsheaders";
+	path[1] = tmp;
+
+	strncpy(tmp, (char*)header, header_len);
+
+	if (!ubjson_lookup(ubjson, path, 2, &val)) {
+		note_error(&ubjson->errs, "header %s not found", path[1]);
+		return 0;
+	}
+
+	return push_data(arena, (unsigned char*)val.string, val.len);
+}
+
+static int verify_signature(struct cursor cur, struct cursor *arena)
 {
 	struct ubjson ubjson;
 	struct json val;
+	struct sig_header sig;
+	unsigned char *p, *pstart, *sigbuf;
+	int sigbuf_len;
 
 	init_ubjson(&ubjson, cur.start, cur.p - cur.start);
 	ubjson.data_end = cur.p;
 
-	const char *path[] = {"@wsheaders", "Signature"};
-	assert(ubjson_lookup(&ubjson, path, 2, &val));
-	printf("sig: %.*s\n", val.len, val.string);
-	//print_around(&val.container.cur, 10);
+	static const char *path[] = {"@wsheaders", "signature"};
+	if (!ubjson_lookup(&ubjson, path, 2, &val)) {
+		note_error(&ubjson.errs, "Signature header not found");
+		return 0;
+	}
+
+	if (!parse_signature_header(&ubjson.errs, arena, val.string, val.len,
+				&sig)) {
+		note_error(&ubjson.errs, "Failed to parse Signature header");
+		return 0;
+	}
+
+	sigbuf = arena->p;
+	pstart = p = (unsigned char*)sig.headers;
+	for (;; p++) {
+		if (*p == ' ' || *p == 0) {
+			if (!push_header(&ubjson, arena, pstart, p-pstart)) {
+				return 0;
+			}
+			pstart = p+1;
+		}
+
+		if (*p == 0)
+			break;
+	}
+
+	sigbuf_len = arena->p - sigbuf;
+	printf("sigbuf: %.*s\n", sigbuf_len, sigbuf);
 
 	return 1;
 }
@@ -48,7 +105,7 @@ int sigcheck(struct sigcheck *check)
 	while (parse_json(&jsonp)) {
 		printf("success! %d\n", ++count);
 
-		if (!verify_signature(out_cur)) {
+		if (!verify_signature(out_cur, &out_cur)) {
 			printf("bad signature\n");
 		}
 	}
diff --git a/src/wolfsocks.c b/src/wolfsocks.c
@@ -170,7 +170,7 @@ static int handle_inbox_request(struct http_req *req, struct cursor *arena)
 
 	printf("signature: %s\n", signature);
 
-	if (!parse_signature_header(&req->errs, arena, signature, &sig)) {
+	if (!parse_signature_header(&req->errs, arena, signature, strlen(signature), &sig)) {
 		note_error(&req->errs, "parse signature header");
 		return 0;
 	}