mirror of
https://forge.fsky.io/lda/Parsee.git
synced 2026-03-13 13:45:10 +00:00
[MOD] HMAC-based mediachecking
This commit is contained in:
parent
692cb8aa6f
commit
39cc04fc2e
6 changed files with 115 additions and 9 deletions
4
LICENSE
4
LICENSE
|
|
@ -1,5 +1,5 @@
|
|||
For the files src/XML/*, tools/*, src/include/XML.h, etc/*, and Makefile, see COPYING.CC0
|
||||
to be present.
|
||||
For the files src/Parsee/HMAC.c, src/XML/*, tools/*, src/include/XML.h, etc/*, and Makefile,
|
||||
see COPYING.CC0.
|
||||
For any other file in src/, see COPYING.AGPL as the primary license.
|
||||
|
||||
As Parsee depends on Cytoplasm, its license is left here in COPYING.CYTO
|
||||
|
|
|
|||
|
|
@ -25,8 +25,8 @@ JoinMUC(ParseeData *data, HashMap *event, char *jid, char *muc, char *name)
|
|||
while (!XMPPJoinMUC(data->jabber, jid, rev, true) && nonce < 32)
|
||||
{
|
||||
char *nonce_str = StrInt(nonce);
|
||||
char *input = StrConcat(4, sender, name, data->id, nonce_str);
|
||||
char *hex = ParseeSHA256(input);
|
||||
char *input = StrConcat(3, sender, name, nonce_str);
|
||||
char *hex = ParseeHMACS(data->id, input);
|
||||
|
||||
if (strlen(hex) >= 8)
|
||||
{
|
||||
|
|
|
|||
76
src/Parsee/HMAC.c
Normal file
76
src/Parsee/HMAC.c
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
/* CC0 implementation of a HMAC system based on Cytoplasm.
|
||||
* Ignore the scary "Parsee.h", its practically unused. */
|
||||
#include <Parsee.h>
|
||||
|
||||
#include <Cytoplasm/Memory.h>
|
||||
#include <Cytoplasm/Sha.h>
|
||||
#include <Cytoplasm/Str.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
/* A 64-byte key! */
|
||||
static uint8_t *
|
||||
ComputeKPad(char *key, uint8_t pad)
|
||||
{
|
||||
size_t klen;
|
||||
uint8_t *kp;
|
||||
uint8_t *kopad;
|
||||
size_t i;
|
||||
if ((klen = strlen(key)) <= 64)
|
||||
{
|
||||
kp = Malloc(klen * sizeof(uint8_t));
|
||||
memcpy(kp, key, klen);
|
||||
}
|
||||
else
|
||||
{
|
||||
kp = (uint8_t *) Sha256(key);
|
||||
klen = 32;
|
||||
}
|
||||
|
||||
/* Now that we have K', lets compute it XORd with opad */
|
||||
kopad = Malloc(64 * sizeof(uint8_t));
|
||||
for (i = 0; i < 64; i++)
|
||||
{
|
||||
uint8_t byte = i < klen ? kp[i] : 0x00;
|
||||
kopad[i] = byte ^ pad;
|
||||
}
|
||||
|
||||
Free(kp);
|
||||
return kopad;
|
||||
}
|
||||
|
||||
char *
|
||||
ParseeHMAC(char *key, uint8_t *msg, size_t msglen)
|
||||
{
|
||||
uint8_t *opad, *ipad;
|
||||
uint8_t *innersha;
|
||||
uint8_t *outer;
|
||||
unsigned char *sha;
|
||||
char *str;
|
||||
if (!key || !msg || !msglen)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
opad = ComputeKPad(key, 0x5C);
|
||||
|
||||
ipad = ComputeKPad(key, 0x36);
|
||||
ipad = Realloc(ipad, 64 + msglen);
|
||||
memcpy(ipad + 64, msg, msglen);
|
||||
innersha = Sha256Raw(ipad, 64 + msglen);
|
||||
|
||||
outer = Malloc(64 + 32);
|
||||
memcpy(outer, opad, 64);
|
||||
memcpy(outer + 64, innersha, 32);
|
||||
|
||||
sha = Sha256Raw(outer, 64 + 32);
|
||||
str = ShaToHex(sha, HASH_SHA256);
|
||||
|
||||
Free(innersha);
|
||||
Free(outer);
|
||||
Free(ipad);
|
||||
Free(opad);
|
||||
Free(sha);
|
||||
|
||||
return str;
|
||||
}
|
||||
|
|
@ -667,7 +667,8 @@ ParseeToUnauth(ParseeData *data, char *mxc)
|
|||
{
|
||||
Uri *url = NULL;
|
||||
char *ret;
|
||||
#define PAT "%s/_matrix/client/v1/media/download/%s%s"
|
||||
char *key, *hmac;
|
||||
#define PAT "%s/_matrix/client/v1/media/download/%s%s?hmac=%s"
|
||||
size_t l;
|
||||
if (!data || !mxc)
|
||||
{
|
||||
|
|
@ -684,18 +685,25 @@ ParseeToUnauth(ParseeData *data, char *mxc)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
key = StrConcat(2, url->host, url->path);
|
||||
hmac = ParseeHMACS(data->id, key);
|
||||
Free(key);
|
||||
|
||||
l = snprintf(NULL, 0,
|
||||
PAT,
|
||||
data->config->media_base,
|
||||
url->host, url->path
|
||||
url->host, url->path,
|
||||
hmac
|
||||
);
|
||||
ret = Malloc(l + 3);
|
||||
snprintf(ret, l + 1,
|
||||
PAT,
|
||||
data->config->media_base,
|
||||
url->host, url->path
|
||||
url->host, url->path,
|
||||
hmac
|
||||
);
|
||||
UriFree(url);
|
||||
Free(hmac);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,27 +2,41 @@
|
|||
|
||||
#include <Cytoplasm/Memory.h>
|
||||
#include <Cytoplasm/Str.h>
|
||||
#include <Cytoplasm/Log.h>
|
||||
|
||||
#include <Matrix.h>
|
||||
#include <Parsee.h>
|
||||
#include <AS.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
RouteHead(RouteMedia, arr, argp)
|
||||
{
|
||||
ParseeHttpArg *args = argp;
|
||||
HttpClientContext *cctx;
|
||||
HashMap *reqh;
|
||||
HashMap *reqh, *params;
|
||||
char *server = ArrayGet(arr, 0);
|
||||
char *identi = ArrayGet(arr, 1);
|
||||
char *path, *key, *val;
|
||||
char *hmac, *chkmak = NULL;
|
||||
|
||||
params = HttpRequestParams(args->ctx);
|
||||
hmac = HashMapGet(params, "hmac");
|
||||
|
||||
/* TODO: Make it check the DB for its validicity. "Purging" would be useful.
|
||||
*/
|
||||
if (!server || !identi)
|
||||
{
|
||||
char *concat = StrConcat(3, server, "/", identi);
|
||||
chkmak = ParseeHMACS(args->data->id, concat);
|
||||
Free(concat);
|
||||
}
|
||||
if (!server || !identi || !hmac || !StrEquals(hmac, chkmak))
|
||||
{
|
||||
Free(chkmak);
|
||||
HttpResponseStatus(args->ctx, HTTP_BAD_REQUEST);
|
||||
return MatrixCreateError("M_NOT_YET_UPLOADED", "No server/identifier");
|
||||
}
|
||||
Free(chkmak);
|
||||
|
||||
server = HttpUrlEncode(server);
|
||||
identi = HttpUrlEncode(identi);
|
||||
|
|
|
|||
|
|
@ -361,4 +361,12 @@ extern char * ParseeGenerateMTO(char *common_id);
|
|||
* Modifies: the Parsee config */
|
||||
extern void ParseeSetThreads(int xmpp, int http);
|
||||
|
||||
/** Computes an HMAC (with SHA-256) with a known key, and a generic message.
|
||||
* --------------
|
||||
* Returns: a hex representation of the HMAC[HEAP].
|
||||
* Thrasher: Free
|
||||
* Modifies: NOTHING */
|
||||
extern char * ParseeHMAC(char *key, uint8_t *msg, size_t msglen);
|
||||
#define ParseeHMACS(key, msg) ParseeHMAC(key, (uint8_t *) msg, strlen(msg))
|
||||
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue