diff --git a/lib/diaspora_federation/entities/comment.rb b/lib/diaspora_federation/entities/comment.rb index b54c5e7..b9f4f3a 100644 --- a/lib/diaspora_federation/entities/comment.rb +++ b/lib/diaspora_federation/entities/comment.rb @@ -4,6 +4,10 @@ module DiasporaFederation # # @see Validators::CommentValidator class Comment < Entity + # old signature order + # @deprecated + LEGACY_SIGNATURE_ORDER = %i(guid parent_guid text diaspora_id).freeze + # @!attribute [r] guid # a random string of at least 16 chars. # @see Validation::Rule::Guid diff --git a/lib/diaspora_federation/entities/like.rb b/lib/diaspora_federation/entities/like.rb index a0d836d..bf1ee42 100644 --- a/lib/diaspora_federation/entities/like.rb +++ b/lib/diaspora_federation/entities/like.rb @@ -4,6 +4,10 @@ module DiasporaFederation # # @see Validators::LikeValidator class Like < Entity + # old signature order + # @deprecated + LEGACY_SIGNATURE_ORDER = %i(positive guid parent_type parent_guid diaspora_id).freeze + # @!attribute [r] positive # If +true+ set a like, if +false+, set a dislike (dislikes are currently not # implemented in the Diaspora frontend). diff --git a/lib/diaspora_federation/entities/message.rb b/lib/diaspora_federation/entities/message.rb index 1a9096f..6a168bf 100644 --- a/lib/diaspora_federation/entities/message.rb +++ b/lib/diaspora_federation/entities/message.rb @@ -4,6 +4,10 @@ module DiasporaFederation # # @see Validators::MessageValidator class Message < Entity + # old signature order + # @deprecated + LEGACY_SIGNATURE_ORDER = %i(guid parent_guid text created_at diaspora_id conversation_guid).freeze + # @!attribute [r] guid # a random string of at least 16 chars. # @see Validation::Rule::Guid diff --git a/lib/diaspora_federation/entities/participation.rb b/lib/diaspora_federation/entities/participation.rb index e57dc20..203c2e1 100644 --- a/lib/diaspora_federation/entities/participation.rb +++ b/lib/diaspora_federation/entities/participation.rb @@ -4,6 +4,10 @@ module DiasporaFederation # # @see Validators::Participation class Participation < Entity + # old signature order + # @deprecated + LEGACY_SIGNATURE_ORDER = %i(guid parent_type parent_guid diaspora_id).freeze + # @!attribute [r] guid # a random string of at least 16 chars. # @see Validation::Rule::Guid diff --git a/lib/diaspora_federation/entities/poll_participation.rb b/lib/diaspora_federation/entities/poll_participation.rb index 964012a..9504f1e 100644 --- a/lib/diaspora_federation/entities/poll_participation.rb +++ b/lib/diaspora_federation/entities/poll_participation.rb @@ -4,6 +4,10 @@ module DiasporaFederation # # @see Validators::PollParticipationValidator class PollParticipation < Entity + # old signature order + # @deprecated + LEGACY_SIGNATURE_ORDER = %i(guid parent_guid diaspora_id poll_answer_guid).freeze + # @!attribute [r] guid # a random string of at least 16 chars. # @see Validation::Rule::Guid diff --git a/lib/diaspora_federation/entities/relayable.rb b/lib/diaspora_federation/entities/relayable.rb index aa1ce4d..bdf48c9 100644 --- a/lib/diaspora_federation/entities/relayable.rb +++ b/lib/diaspora_federation/entities/relayable.rb @@ -109,7 +109,7 @@ module DiasporaFederation # @param [Hash] hash data to sign # @return [String] A Base64 encoded signature of #signable_string with key def sign_with_key(privkey, hash) - Base64.strict_encode64(privkey.sign(DIGEST, signable_string(hash))) + Base64.strict_encode64(privkey.sign(DIGEST, legacy_signature_data(hash))) end # Check that signature is a correct signature @@ -123,17 +123,16 @@ module DiasporaFederation return false end - validity = pubkey.verify(DIGEST, Base64.decode64(signature), signable_string(data)) + validity = pubkey.verify(DIGEST, Base64.decode64(signature), legacy_signature_data(data)) logger.info "event=verify_signature status=complete guid=#{guid} validity=#{validity}" validity end # @param [Hash] hash data to sign # @return [String] signature data string - def signable_string(hash) - hash.map {|name, value| - value.to_s unless name =~ /signature/ - }.compact.join(";") + # @deprecated + def legacy_signature_data(hash) + self.class::LEGACY_SIGNATURE_ORDER.map {|name| hash[name] }.join(";") end # Exception raised when creating the author_signature failes, because the private key was not found diff --git a/spec/lib/diaspora_federation/entities/relayable_spec.rb b/spec/lib/diaspora_federation/entities/relayable_spec.rb index 114e5d0..db7bfd2 100644 --- a/spec/lib/diaspora_federation/entities/relayable_spec.rb +++ b/spec/lib/diaspora_federation/entities/relayable_spec.rb @@ -12,6 +12,8 @@ module DiasporaFederation } class SomeRelayable < Entity + LEGACY_SIGNATURE_ORDER = %i(guid diaspora_id parent_guid).freeze + property :guid property :diaspora_id, xml_name: :diaspora_handle @@ -22,15 +24,19 @@ module DiasporaFederation end end - def legacy_sign_with_key(privkey, hash) - Base64.strict_encode64(privkey.sign(OpenSSL::Digest::SHA256.new, hash.values.join(";"))) - end - describe "#verify_signatures" do - it "doesn't raise anything if correct data were passed" do + def legacy_signature_data + %i(guid diaspora_id parent_guid).map {|name| hash[name] }.join(";") + end + + def sign_with_key(privkey, signature_data) + Base64.strict_encode64(privkey.sign(OpenSSL::Digest::SHA256.new, signature_data)) + end + + it "doesn't raise anything if correct signatures with legacy-string were passed" do signed_hash = hash.dup - signed_hash[:author_signature] = legacy_sign_with_key(author_pkey, hash) - signed_hash[:parent_author_signature] = legacy_sign_with_key(parent_pkey, hash) + signed_hash[:author_signature] = sign_with_key(author_pkey, legacy_signature_data) + signed_hash[:parent_author_signature] = sign_with_key(parent_pkey, legacy_signature_data) expect(DiasporaFederation.callbacks).to receive(:trigger).with( :fetch_public_key_by_diaspora_id, hash[:diaspora_id] @@ -70,7 +76,7 @@ module DiasporaFederation end it "raises when no public key for parent author was fetched" do - hash[:author_signature] = legacy_sign_with_key(author_pkey, hash) + hash[:author_signature] = sign_with_key(author_pkey, legacy_signature_data) expect(DiasporaFederation.callbacks).to receive(:trigger).with( :fetch_public_key_by_diaspora_id, hash[:diaspora_id] @@ -90,7 +96,7 @@ module DiasporaFederation end it "raises when bad parent author signature was passed" do - hash[:author_signature] = legacy_sign_with_key(author_pkey, hash) + hash[:author_signature] = sign_with_key(author_pkey, legacy_signature_data) hash[:parent_author_signature] = nil expect(DiasporaFederation.callbacks).to receive(:trigger).with( @@ -111,7 +117,7 @@ module DiasporaFederation end it "doesn't raise if parent_author_signature isn't set but we're on upstream federation" do - hash[:author_signature] = legacy_sign_with_key(author_pkey, hash) + hash[:author_signature] = sign_with_key(author_pkey, legacy_signature_data) hash[:parent_author_signature] = nil expect(DiasporaFederation.callbacks).to receive(:trigger).with(