diff options
| -rw-r--r-- | activitypub.c | 5 | ||||
| -rw-r--r-- | http.c | 54 | ||||
| -rw-r--r-- | snac.h | 1 |
3 files changed, 59 insertions, 1 deletions
diff --git a/activitypub.c b/activitypub.c index cebefca..7a30010 100644 --- a/activitypub.c +++ b/activitypub.c | |||
| @@ -594,7 +594,10 @@ int process_message(snac *snac, char *msg, char *req) | |||
| 594 | } | 594 | } |
| 595 | 595 | ||
| 596 | /* check the signature */ | 596 | /* check the signature */ |
| 597 | /* ... */ | 597 | if (!check_signature(snac, req)) { |
| 598 | snac_log(snac, xs_fmt("bad signature")); | ||
| 599 | return 1; | ||
| 600 | } | ||
| 598 | 601 | ||
| 599 | if (strcmp(type, "Follow") == 0) { | 602 | if (strcmp(type, "Follow") == 0) { |
| 600 | xs *reply = msg_accept(snac, msg, actor); | 603 | xs *reply = msg_accept(snac, msg, actor); |
| @@ -99,3 +99,57 @@ d_char *http_signed_request(snac *snac, char *method, char *url, | |||
| 99 | 99 | ||
| 100 | return response; | 100 | return response; |
| 101 | } | 101 | } |
| 102 | |||
| 103 | |||
| 104 | int check_signature(snac *snac, char *req) | ||
| 105 | /* check the signature */ | ||
| 106 | { | ||
| 107 | char *sig_hdr = xs_dict_get(req, "signature"); | ||
| 108 | xs *keyId = NULL; | ||
| 109 | xs *headers = NULL; | ||
| 110 | xs *signature = NULL; | ||
| 111 | char *pubkey; | ||
| 112 | char *p; | ||
| 113 | |||
| 114 | { | ||
| 115 | /* extract the values */ | ||
| 116 | xs *l = xs_split(sig_hdr, ","); | ||
| 117 | char *v; | ||
| 118 | |||
| 119 | p = l; | ||
| 120 | while (xs_list_iter(&p, &v)) { | ||
| 121 | if (xs_startswith(v, "keyId")) | ||
| 122 | keyId = xs_crop(xs_dup(v), 7, -1); | ||
| 123 | else | ||
| 124 | if (xs_startswith(v, "headers")) | ||
| 125 | headers = xs_crop(xs_dup(v), 9, -1); | ||
| 126 | else | ||
| 127 | if (xs_startswith(v, "signature")) | ||
| 128 | signature = xs_crop(xs_dup(v), 12, -1); | ||
| 129 | } | ||
| 130 | } | ||
| 131 | |||
| 132 | if (keyId == NULL || headers == NULL || signature == NULL) { | ||
| 133 | snac_debug(snac, 1, xs_fmt("bad signature header")); | ||
| 134 | return 0; | ||
| 135 | } | ||
| 136 | |||
| 137 | /* strip the # from the keyId */ | ||
| 138 | if ((p = strchr(keyId, '#')) != NULL) | ||
| 139 | *p = '\0'; | ||
| 140 | |||
| 141 | /* the actor must already be here */ | ||
| 142 | xs *actor = NULL; | ||
| 143 | if (!valid_status(actor_get(snac, keyId, &actor))) { | ||
| 144 | snac_debug(snac, 1, xs_fmt("check_signature unknown actor %s", keyId)); | ||
| 145 | return 0; | ||
| 146 | } | ||
| 147 | |||
| 148 | if ((p = xs_dict_get(actor, "publicKey")) == NULL || | ||
| 149 | ((pubkey = xs_dict_get(p, "publicKeyPem")) == NULL)) { | ||
| 150 | snac_debug(snac, 1, xs_fmt("cannot get pubkey from actor %s", keyId)); | ||
| 151 | return 0; | ||
| 152 | } | ||
| 153 | |||
| 154 | return 1; | ||
| 155 | } | ||
| @@ -94,6 +94,7 @@ d_char *http_signed_request(snac *snac, char *method, char *url, | |||
| 94 | d_char *headers, | 94 | d_char *headers, |
| 95 | d_char *body, int b_size, | 95 | d_char *body, int b_size, |
| 96 | int *status, d_char **payload, int *p_size); | 96 | int *status, d_char **payload, int *p_size); |
| 97 | int check_signature(snac *snac, char *req); | ||
| 97 | 98 | ||
| 98 | void httpd(void); | 99 | void httpd(void); |
| 99 | 100 | ||