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;
}