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 }