diff options
author | pdp8 <pdp8@pdp8.info> | 2023-04-23 16:37:01 +0200 |
---|---|---|
committer | pdp8 <pdp8@pdp8.info> | 2023-04-23 16:37:01 +0200 |
commit | b2b88253f5cc4221b01ed860b02ae156941e03ce (patch) | |
tree | 5f7515c52f5937dc594ed460bb20a1e12567d4e7 | |
parent | f8afb7dec94bf9248b4032b7e95549361f190f3c (diff) |
http signatures (beware of encodings!)
-rw-r--r-- | application.rb | 49 | ||||
-rw-r--r-- | config.ru | 1 | ||||
-rwxr-xr-x[-rw-r--r--] | post.rb | 32 |
3 files changed, 53 insertions, 29 deletions
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": "<a rel=\"me\" href=\"https://matrix.to/#/#{MATRIX}\">MATRIX</a>" + "value": "<a rel=\"me\" href=\"https://matrix.to/#/#{MATRIX}\">#{MATRIX}</a>" } ], "publicKey" => { @@ -2,5 +2,4 @@ require_relative './application.rb' require 'rack/protection' use Rack::Protection, :except => :session_hijacking use Rack::Reloader -# use Rack::ContentType, "application/ld+json" run Application.new @@ -1,12 +1,30 @@ -require 'http' +#!/usr/bin/env ruby +require 'json' +require 'time' require 'openssl' +require 'base64' +require 'net/http' +require 'uri' -document = File.read('create-hello-world.json') +document = { "a" => 2 } # .to_json date = Time.now.utc.httpdate keypair = OpenSSL::PKey::RSA.new(File.read('private.pem')) -signed_string = "(request-target): post /inbox\nhost: mastodon.social\ndate: #{date}" -signature = Base64.strict_encode64(keypair.sign(OpenSSL::Digest::SHA256.new, signed_string)) -header = 'keyId="https://my-example.com/actor",headers="(request-target) host date",signature="' + signature + '"' +signed_string = "(request-target): post /inbox\nhost: social.pdp8.info\ndate: #{date}" +signed_string = keypair.sign(OpenSSL::Digest::SHA256.new, signed_string) +signature = Base64.urlsafe_encode64(signed_string).encode("UTF-8") +signed_header = 'keyId="https://social.pdp8.info/pdp8",headers="(request-target) host date",signature="' + signature + '"' -HTTP.headers({ 'Host': 'mastodon.social', 'Date': date, 'Signature': header }) - .post('https://mastodon.social/inbox', body: document) +uri = URI.parse("https://social.pdp8.info/inbox") +http = Net::HTTP.new(uri.host, uri.port) +http.use_ssl = true +http.verify_mode = OpenSSL::SSL::VERIFY_NONE +header = { + 'Host' => 'social.pdp8.info', + 'Date' => date, + 'Signature' => signed_header, +} +request = Net::HTTP::Post.new(uri.request_uri, header) +request.body = document.to_json + +response = http.request(request) +puts(response.body, response.code) |