diff --git a/.gitignore b/.gitignore index 068f14a..9db9633 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ node_modules dist -wrangler.* \ No newline at end of file +wrangler.* +config.json \ No newline at end of file diff --git a/hmac_sha256.py b/hmac_sha256.py new file mode 100755 index 0000000..d7d6a87 --- /dev/null +++ b/hmac_sha256.py @@ -0,0 +1,11 @@ +#!/usr/bin/env python +# HMAC_SHA256 implemented in Python +# used to test our implementation for signature verification +# usage: hmac_sha256.py [key] [str] +# in [str], all ';' will be replaced with '\0' +import hmac +import hashlib +import sys + +signature = hmac.new(bytes(sys.argv[1] , 'utf-8'), msg = bytes(sys.argv[2].replace(";", "\0"), 'utf-8'), digestmod = hashlib.sha256).hexdigest() +print(signature) \ No newline at end of file diff --git a/src/index.coffee b/src/index.coffee index 7e698bd..b59bfe4 100644 --- a/src/index.coffee +++ b/src/index.coffee @@ -1,2 +1,35 @@ +import config from "../config.json" +import * as crypto from "./crypto" + addEventListener 'fetch', (event) => - event.respondWith new Response "Hello World" \ No newline at end of file + event.respondWith handleRequest event + +handleRequest = ({ request }) -> + if request.method is "PUT" + return handlePUT request + + return new Response "Not Found", + status: 404 + +handlePUT = (request) -> + url = new URL request.url + if url.searchParams.has "v2" + valid = await verifySignatureV2 url.searchParams.get("v2"), url, request + return verifyFailure() unless valid + return new Response "Valid" + +verifyFailure = -> + return new Response "Invalid signature", + status: 403 + +verifySignatureV2 = (sig, url, request) -> + content_length = request.headers.get "Content-Length" + content_type = request.headers.get "Content-Type" + if not (content_length? and content_type?) + return false + + sign_str = url.pathname[1..] + "\0" + content_length + "\0" + content_type + local_sig = await crypto.HMAC_SHA256 crypto.utf8Bytes(config.xmpp_secret), sign_str + local_sig = crypto.hex local_sig + + return local_sig is sig \ No newline at end of file