chibipub

experimental activitypub node in C
git clone git://jb55.com/chibipub
Log | Files | Refs | README | LICENSE

inbox.c (2639B)


      1 
      2 #include "inbox.h"
      3 #include "http.h"
      4 #include "util.h"
      5 #include "base64.h"
      6 #include "parse.h"
      7 
      8 #include <assert.h>
      9 #include <stdio.h>
     10 
     11 static int parse_until(struct cursor *cur, struct cursor *arena, char match,
     12 		const char **out)
     13 {
     14 	unsigned char *start;
     15 
     16 	start = cur->p;
     17 
     18 	for (; cur->p < cur->end; cur->p++) {
     19 		if (*cur->p == match) {
     20 			*out = (char*)arena->p;
     21 			if (!push_data(arena, start, cur->p - start)) {
     22 				return 0;
     23 			}
     24 			if (!push_byte(arena, 0)) {
     25 				return 0;
     26 			}
     27 			cur->p++;
     28 			return 1;
     29 		}
     30 	}
     31 
     32 	cur->p = start;
     33 
     34 	return 0;
     35 }
     36 
     37 static int parse_kv(struct errors *errs, struct cursor *cur,
     38 		struct cursor *arena, const char **key, const char **val)
     39 {
     40 	char b = 0;
     41 
     42 	if (!parse_until(cur, arena, '=', key)) {
     43 		note_error(errs, "= not found");
     44 		return 0;
     45 	}
     46 
     47 	if (!parse_char(cur, &b, '"')) {
     48 		note_error(errs, "\" expected");
     49 		return 0;
     50 	}
     51 
     52 	if (!parse_until(cur, arena, '"', val)) {
     53 		note_error(errs, "\" expected");
     54 		return 0;
     55 	}
     56 
     57 	if (!parse_char(cur, &b, ',')) {
     58 		//assert(*cur->end == 0);
     59 		return 1;
     60 	}
     61 
     62 	return 1;
     63 }
     64 
     65 int parse_signature_header(struct errors *errs, struct cursor *arena,
     66 		const char *value, int value_len, struct sig_header *out)
     67 {
     68 	const char *key;
     69 	const char *val;
     70 	struct cursor cur;
     71 	size_t out_len;
     72 	make_cursor((unsigned char*)value, (unsigned char*)value + value_len, &cur);
     73 	memset(out, 0, sizeof(*out));
     74 
     75 	while (1) {
     76 		if (out->key_id && out->headers && out->signature)
     77 			break;
     78 
     79 		if (!parse_kv(errs, &cur, arena, &key, &val)) {
     80 			note_error(errs, "keyid:%s headers:%s sig:%s",
     81 				out->key_id,
     82 				out->headers,
     83 				out->signature);
     84 			break;
     85 		}
     86 
     87 		if (stricmp(key, "keyid")) {
     88 			out->key_id = val;
     89 		} else if (stricmp(key, "headers")) {
     90 			out->headers = val;
     91 		} else if (stricmp(key, "signature")) {
     92 			out->signature = arena->p;
     93 			out->b64_sig = (char*)val;
     94 			out->b64_len = strlen(out->b64_sig);
     95 
     96 			if (!base64_decode((const unsigned char*)out->b64_sig,
     97 					   out->b64_len,
     98 			                   arena->p, arena->end - arena->p,
     99 			                   &out_len)) {
    100 				note_error(errs, "base64 decode signature");
    101 				return 0;
    102 			}
    103 
    104 			out->signature_len = out_len;
    105 			arena->p += out_len;
    106 
    107 			if (!push_byte(arena, 0)) {
    108 				note_error(errs, "oom");
    109 				return 0;
    110 			}
    111 		}
    112 	}
    113 
    114 	if (out->key_id == NULL || out->headers == NULL || out->signature == NULL) {
    115 		return 0;
    116 	}
    117 
    118 	return 1;
    119 }
    120 
    121 int verify_signature_header(struct sig_header *sig)
    122 {
    123 	int i;
    124 
    125 	printf("verifying\nkeyid %s\nheaders %s\nsignature ",
    126 	       sig->key_id, sig->headers);
    127 
    128 	for (i = 0; i < sig->signature_len; i++) {
    129 		printf("%02x", sig->signature[i]);
    130 	}
    131 	printf("\n");
    132 
    133 	return 1;
    134 }