chibipub

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

commit 4a1d3ba410f6aae3d523bca151bfd026c7454312
parent 1bb5a9fce6f04f11de5c876e00180488cfb6dd9d
Author: William Casarin <jb55@jb55.com>
Date:   Sat, 16 Jan 2021 15:56:09 -0800

build sigbuf from headers

Diffstat:
Msrc/inbox.c | 6+++---
Msrc/inbox.h | 2+-
Msrc/sigcheck.c | 69+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------
Msrc/wolfsocks.c | 2+-
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; }