From b2b88253f5cc4221b01ed860b02ae156941e03ce Mon Sep 17 00:00:00 2001 From: pdp8 Date: Sun, 23 Apr 2023 16:37:01 +0200 Subject: http signatures (beware of encodings!) --- application.rb | 49 ++++++++++++++++++++++++++++--------------------- 1 file changed, 28 insertions(+), 21 deletions(-) (limited to 'application.rb') diff --git a/application.rb b/application.rb index 6abf490..7618855 100644 --- a/application.rb +++ b/application.rb @@ -1,6 +1,7 @@ require 'json' require 'net/http' require 'uri' +require 'base64' USER = "pdp8" WWW_DOMAIN = "pdp8.info" @@ -26,29 +27,35 @@ class Application when "/inbox" type = "text/plain" signature_header = {} - env["HTTP_SIGNATURE"].split(',').each do |pair| - k, v = pair.split('=') - signature_header[k] = v.gsub('"', '') - end - key_id = signature_header['keyId'] - headers = signature_header['headers'] - signature = Base64.decode64(signature_header['signature']) - uri = URI(key_id) - res = Net::HTTP.get_response(uri) - actor = JSON.parse(res.body) - key = OpenSSL::PKey::RSA.new(actor['publicKey']['publicKeyPem']) + if env["HTTP_SIGNATURE"].split(',') + env["HTTP_SIGNATURE"].split(',').each do |pair| + k, v = pair.split('=') + signature_header[k] = v.gsub('"', '') + end + key_id = signature_header['keyId'] + headers = signature_header['headers'] + signature = Base64.urlsafe_decode64(signature_header['signature'].encode("ascii-8bit")) + uri = URI(key_id) + res = Net::HTTP.get_response(uri) + actor = JSON.parse(res.body) + key = OpenSSL::PKey::RSA.new(actor['publicKey']['publicKeyPem']) - comparison_string = headers.split(' ').map do |signed_header_name| - if signed_header_name == '(request-target)' - '(request-target): post /inbox' + comparison_string = headers.split(' ').map do |signed_header_name| + if signed_header_name == '(request-target)' + '(request-target): post /inbox' + else + "#{signed_header_name}: #{env["HTTP_" + signed_header_name.upcase]}" + end + end.join("\n") + if key.verify(OpenSSL::Digest::SHA256.new, signature, comparison_string.encode("ascii-8bit")) + input = JSON.parse(env["rack.input"].gets) + # p input + code = 200 + response = "OK" else - "#{signed_header_name}: #{env["HTTP_" + signed_header_name.upcase]}" + code = 401 + response = 'Request signature could not be verified' end - end.join("\n") - if key.verify(OpenSSL::Digest::SHA256.new, signature, comparison_string) - input = JSON.parse(env["rack.input"].gets) - code = 200 - response = "OK" else code = 401 response = 'Request signature could not be verified' @@ -105,7 +112,7 @@ class Application { "type": "PropertyValue", "name": "Matrix", - "value": "MATRIX" + "value": "#{MATRIX}" } ], "publicKey" => { -- cgit v1.2.3