From 76f6929668e144bf75e5bc27eaf66897049bf4ff Mon Sep 17 00:00:00 2001 From: Benjamin Neff Date: Sat, 6 Feb 2016 02:32:42 +0100 Subject: [PATCH] add unknown xml elements to the xml again --- lib/diaspora_federation/entities/relayable.rb | 10 +++ .../entities/relayable_spec.rb | 63 +++++++++++++++---- spec/support/shared_entity_specs.rb | 6 +- 3 files changed, 64 insertions(+), 15 deletions(-) diff --git a/lib/diaspora_federation/entities/relayable.rb b/lib/diaspora_federation/entities/relayable.rb index 269526a..7055d40 100644 --- a/lib/diaspora_federation/entities/relayable.rb +++ b/lib/diaspora_federation/entities/relayable.rb @@ -77,6 +77,8 @@ module DiasporaFederation hash = to_signed_h xml.at_xpath("author_signature").content = hash[:author_signature] xml.at_xpath("parent_author_signature").content = hash[:parent_author_signature] + + add_additional_elements_to(xml) if additional_xml_elements end end @@ -105,6 +107,14 @@ module DiasporaFederation end end + # Adds additional unknown elements to the xml + # @param [Nokogiri::XML::Element] xml entity xml + def add_additional_elements_to(xml) + additional_xml_elements.each do |element, value| + xml << Nokogiri::XML::Element.new(element, xml.document).tap {|node| node.content = value } + end + end + # this happens only on downstream federation def verify_parent_author_signature pubkey = DiasporaFederation.callbacks.trigger(:fetch_author_public_key_by_entity_guid, parent_type, parent_guid) diff --git a/spec/lib/diaspora_federation/entities/relayable_spec.rb b/spec/lib/diaspora_federation/entities/relayable_spec.rb index c961462..092aa96 100644 --- a/spec/lib/diaspora_federation/entities/relayable_spec.rb +++ b/spec/lib/diaspora_federation/entities/relayable_spec.rb @@ -6,26 +6,30 @@ module DiasporaFederation let(:guid) { FactoryGirl.generate(:guid) } let(:parent_guid) { FactoryGirl.generate(:guid) } let(:diaspora_id) { FactoryGirl.generate(:diaspora_id) } + let(:property) { "hello" } let(:new_property) { "some text" } - let(:hash) { {guid: guid, diaspora_id: diaspora_id, parent_guid: parent_guid} } + let(:hash) { {guid: guid, diaspora_id: diaspora_id, parent_guid: parent_guid, property: property} } - let(:signature_data) { "#{diaspora_id};#{guid};#{parent_guid}" } - let(:signature_data_with_new_property) { "#{diaspora_id};#{guid};#{new_property};#{parent_guid}" } - let(:legacy_signature_data) { "#{guid};#{diaspora_id};#{parent_guid}" } + let(:signature_data) { "#{diaspora_id};#{guid};#{parent_guid};#{property}" } + let(:signature_data_with_new_property) { "#{diaspora_id};#{guid};#{new_property};#{parent_guid};#{property}" } + let(:legacy_signature_data) { "#{guid};#{diaspora_id};#{property};#{parent_guid}" } class SomeRelayable < Entity - LEGACY_SIGNATURE_ORDER = %i(guid diaspora_id parent_guid).freeze - - property :guid - property :diaspora_id, xml_name: :diaspora_handle + LEGACY_SIGNATURE_ORDER = %i(guid diaspora_id property parent_guid).freeze include Entities::Relayable + property :property + def parent_type "Parent" end end + def verify_signature(pubkey, signature, signed_string) + pubkey.verify(OpenSSL::Digest::SHA256.new, Base64.decode64(signature), signed_string) + end + describe "#verify_signatures" do def sign_with_key(privkey, signature_data) Base64.strict_encode64(privkey.sign(OpenSSL::Digest::SHA256.new, signature_data)) @@ -186,10 +190,6 @@ module DiasporaFederation end describe "#to_signed_h" do - def verify_signature(pubkey, signature, signed_string) - pubkey.verify(OpenSSL::Digest::SHA256.new, Base64.decode64(signature), signed_string) - end - it "updates signatures when they were nil and keys were supplied" do expect(DiasporaFederation.callbacks).to receive(:trigger).with( :fetch_private_key_by_diaspora_id, diaspora_id @@ -251,5 +251,44 @@ module DiasporaFederation end end end + + describe "#to_xml" do + it "adds new unknown xml elements to the xml again" do + hash.merge!(author_signature: "aa", parent_author_signature: "bb") + xml = SomeRelayable.new(hash, "new_property" => new_property).to_xml + + expected_xml = <<-XML + + #{diaspora_id} + #{guid} + #{parent_guid} + aa + bb + #{property} + #{new_property} + +XML + + expect(xml.to_s.strip).to eq(expected_xml.strip) + end + + it "computes correct signatures for the entity" do + expect(DiasporaFederation.callbacks).to receive(:trigger).with( + :fetch_private_key_by_diaspora_id, diaspora_id + ).and_return(author_pkey) + + expect(DiasporaFederation.callbacks).to receive(:trigger).with( + :fetch_author_private_key_by_entity_guid, "Parent", parent_guid + ).and_return(parent_pkey) + + xml = DiasporaFederation::Salmon::XmlPayload.pack(SomeRelayable.new(hash)) + + author_signature = xml.at_xpath("post/*[1]/author_signature").text + parent_author_signature = xml.at_xpath("post/*[1]/parent_author_signature").text + + expect(verify_signature(author_pkey, author_signature, legacy_signature_data)).to be_truthy + expect(verify_signature(parent_pkey, parent_author_signature, legacy_signature_data)).to be_truthy + end + end end end diff --git a/spec/support/shared_entity_specs.rb b/spec/support/shared_entity_specs.rb index 4830b77..1f00f99 100644 --- a/spec/support/shared_entity_specs.rb +++ b/spec/support/shared_entity_specs.rb @@ -75,7 +75,7 @@ shared_examples "a relayable Entity" do let(:instance) { described_class.new(data.merge(author_signature: nil, parent_author_signature: nil)) } context "signatures generation" do - def legacy_verify_signature(pubkey, signature, signed_string) + def verify_signature(pubkey, signature, signed_string) pubkey.verify(OpenSSL::Digest::SHA256.new, Base64.decode64(signature), signed_string) end @@ -89,8 +89,8 @@ shared_examples "a relayable Entity" do alice_public_key = OpenSSL::PKey::RSA.new(alice.serialized_public_key) bob_public_key = OpenSSL::PKey::RSA.new(bob.serialized_public_key) - expect(legacy_verify_signature(alice_public_key, author_signature, signed_string)).to be_truthy - expect(legacy_verify_signature(bob_public_key, parent_author_signature, signed_string)).to be_truthy + expect(verify_signature(alice_public_key, author_signature, signed_string)).to be_truthy + expect(verify_signature(bob_public_key, parent_author_signature, signed_string)).to be_truthy end end end