Don't check parent_author_signature for relayables
This isn't needed, but we need to check if the sender of the Magic Envelope is the parent author (so we have a valid signature from the parent author there).
This commit is contained in:
parent
99a703ff5d
commit
6817579072
7 changed files with 36 additions and 121 deletions
|
|
@ -16,7 +16,6 @@ See also: [Relayable][relayable]
|
|||
| `text` | [Markdown][markdown] (65535) | The comment text. |
|
||||
| `created_at` | [Timestamp][timestamp] | The create timestamp of the comment. |
|
||||
| `author_signature` | [Signature][signature] | The signature from the author of the comment. |
|
||||
| `parent_author_signature` | [Signature][signature] | The signature from the parent entity author. |
|
||||
|
||||
## Optional Properties
|
||||
|
||||
|
|
@ -26,8 +25,6 @@ See also: [Relayable][relayable]
|
|||
|
||||
## Examples
|
||||
|
||||
### From author
|
||||
|
||||
~~~xml
|
||||
<comment>
|
||||
<author>alice@example.org</author>
|
||||
|
|
@ -36,21 +33,6 @@ See also: [Relayable][relayable]
|
|||
<parent_guid>c3893bf029e7013487753131731751e9</parent_guid>
|
||||
<text>this is a very informative comment</text>
|
||||
<author_signature>cGIsxB5hU/94+rmgIg/Z+OUvXVYcY/kMOvc267ybpk1pT44P1JiWfnI26F1Mta62UjzIW/SjeAO0RIsJRguaISLpXX/d5DJCMpePAZaZiagUbdgH/w4L++fXiPxBKkSm+PB4txxmHGN8FHjwEUJFHJ1m3VfU4w2JC8+IBU93eag=</author_signature>
|
||||
<parent_author_signature/>
|
||||
</comment>
|
||||
~~~
|
||||
|
||||
### From parent author
|
||||
|
||||
~~~xml
|
||||
<comment>
|
||||
<author>alice@example.org</author>
|
||||
<guid>5c241a3029f8013487763131731751e9</guid>
|
||||
<created_at>2016-07-12T00:49:06Z</created_at>
|
||||
<parent_guid>c3893bf029e7013487753131731751e9</parent_guid>
|
||||
<text>this is a very informative comment</text>
|
||||
<author_signature>cGIsxB5hU/94+rmgIg/Z+OUvXVYcY/kMOvc267ybpk1pT44P1JiWfnI26F1Mta62UjzIW/SjeAO0RIsJRguaISLpXX/d5DJCMpePAZaZiagUbdgH/w4L++fXiPxBKkSm+PB4txxmHGN8FHjwEUJFHJ1m3VfU4w2JC8+IBU93eag=</author_signature>
|
||||
<parent_author_signature>uzjxUSqR8DQBSBa6abY7R/s9DVzT6UAgTctRcUu5rV5o0iXJD2MR6kp6bsVH3nMbbNvOjwAtrdfz3SVHT2gD8M5PmoFagxK7m5T1c9FB0i+wknoAah0Si0c2sP/BPLnkQ83DgLjF+JZCzMX4sWKvYfyaMjnih1MtQILGyuiwA0E=</parent_author_signature>
|
||||
</comment>
|
||||
~~~
|
||||
|
||||
|
|
|
|||
|
|
@ -21,12 +21,9 @@ See also: [Relayable][relayable]
|
|||
| `parent_type` | [Type][type] | The entity type of the parent. |
|
||||
| `positive` | [Boolean][boolean] | `true` if it is a like, `false` if it is a dislike. |
|
||||
| `author_signature` | [Signature][signature] | The signature from the author of the like. |
|
||||
| `parent_author_signature` | [Signature][signature] | The signature from the parent entity author. |
|
||||
|
||||
## Examples
|
||||
|
||||
### From author
|
||||
|
||||
~~~xml
|
||||
<like>
|
||||
<positive>true</positive>
|
||||
|
|
@ -35,21 +32,6 @@ See also: [Relayable][relayable]
|
|||
<parent_guid>947a854029f7013487753131731751e9</parent_guid>
|
||||
<author>alice@example.org</author>
|
||||
<author_signature>gk8e+K7XRjVRblv8B8PVOf7BpURbf5HrXO5rmq8D/AkPO7lA0+Akwouu5JGKAHIhPR3dfXVp0o6bIDD+e8gtMYRdDd5IHRfBGNk3WsQecnbhmesHy40Qca/dCQcdcXd5aeWHJKeyUrSAvS55U6VUpk/DK/4IIEZfnr0T9+jM8I0=</author_signature>
|
||||
<parent_author_signature/>
|
||||
</like>
|
||||
~~~
|
||||
|
||||
### From parent author
|
||||
|
||||
~~~xml
|
||||
<like>
|
||||
<positive>true</positive>
|
||||
<guid>947a88f029f7013487753131731751e9</guid>
|
||||
<parent_type>Post</parent_type>
|
||||
<parent_guid>947a854029f7013487753131731751e9</parent_guid>
|
||||
<author>alice@example.org</author>
|
||||
<author_signature>gk8e+K7XRjVRblv8B8PVOf7BpURbf5HrXO5rmq8D/AkPO7lA0+Akwouu5JGKAHIhPR3dfXVp0o6bIDD+e8gtMYRdDd5IHRfBGNk3WsQecnbhmesHy40Qca/dCQcdcXd5aeWHJKeyUrSAvS55U6VUpk/DK/4IIEZfnr0T9+jM8I0=</author_signature>
|
||||
<parent_author_signature>0oAjHO8uIn2Z3Gcmo1KF8su0c7bqI6MzTRq5JagGaZVkFVU8WlNqtwamu6xlmpcAoClGpI5xvbnHzyw5YA8NS8KmUy8BUpg67Mq4QsHHBtueNxHuhgRjszN2V0S8BUKFHGJnnvXmZ/P6YGOOomDgp9I/7zIOownvIm5wj2MotWw=</parent_author_signature>
|
||||
</like>
|
||||
~~~
|
||||
|
||||
|
|
|
|||
|
|
@ -15,12 +15,9 @@ See also: [Relayable][relayable]
|
|||
| `parent_guid` | [GUID][guid] | The GUID of the [Poll][poll]. |
|
||||
| `poll_answer_guid` | [GUID][guid] | The GUID of the [PollAnswer][poll_answer]. |
|
||||
| `author_signature` | [Signature][signature] | The signature from the author of the poll participation. |
|
||||
| `parent_author_signature` | [Signature][signature] | The signature from the author of the [Poll][poll]. |
|
||||
|
||||
## Examples
|
||||
|
||||
### From author
|
||||
|
||||
~~~xml
|
||||
<poll_participation>
|
||||
<guid>f1eb866029f7013487753131731751e9</guid>
|
||||
|
|
@ -28,20 +25,6 @@ See also: [Relayable][relayable]
|
|||
<author>alice@example.org</author>
|
||||
<poll_answer_guid>2a22db2029e9013487753131731751e9</poll_answer_guid>
|
||||
<author_signature>dT6KbT7kp0bE+s3//ZErxO1wvVIqtD0lY67i81+dO43B4D2m5kjCdzW240eWt/jZmcHIsdxXf4WHNdrb6ZDnamA8I1FUVnLjHA9xexBITQsSLXrcV88UdammSmmOxl1Ac4VUXqFpdavm6a7/MwOJ7+JHP8TbUO9siN+hMfgUbtY=</author_signature>
|
||||
<parent_author_signature/>
|
||||
</poll_participation>
|
||||
~~~
|
||||
|
||||
### From parent author
|
||||
|
||||
~~~xml
|
||||
<poll_participation>
|
||||
<guid>f1eb866029f7013487753131731751e9</guid>
|
||||
<parent_guid>2a22d6c029e9013487753131731751e9</parent_guid>
|
||||
<author>alice@example.org</author>
|
||||
<poll_answer_guid>2a22db2029e9013487753131731751e9</poll_answer_guid>
|
||||
<author_signature>dT6KbT7kp0bE+s3//ZErxO1wvVIqtD0lY67i81+dO43B4D2m5kjCdzW240eWt/jZmcHIsdxXf4WHNdrb6ZDnamA8I1FUVnLjHA9xexBITQsSLXrcV88UdammSmmOxl1Ac4VUXqFpdavm6a7/MwOJ7+JHP8TbUO9siN+hMfgUbtY=</author_signature>
|
||||
<parent_author_signature>gWasNPpSnMcKBIMWyzfoVO6sr8eRYkhUqy3PIkkh53n/ki+DM9mnh3ayotI0+6un9aq1N3XkS7Vn05ZD3+nHVby6i21XkYgPnbD8pWYuBBj7VGPyahT70BUs/vSvY8KX8V3wYfsPsaiAgJsAFg2UHYdY3r4/oWdIIbBZc21O3zk=</parent_author_signature>
|
||||
</poll_participation>
|
||||
~~~
|
||||
|
||||
|
|
|
|||
|
|
@ -21,24 +21,22 @@ All relayables have the following properties:
|
|||
| `guid` | [GUID][guid] | The GUID of the relayable. |
|
||||
| `parent_guid` | [GUID][guid] | The GUID of the parent entity. |
|
||||
| `author_signature` | [Signature][signature] | The signature from the author of the relayable. |
|
||||
| `parent_author_signature` | [Signature][signature] | The signature from the parent entity author. |
|
||||
|
||||
## Relaying
|
||||
|
||||
The author of the relayable sends the entity to the parent author. The author must include the `author_signature`. The
|
||||
`parent_author_signature` may be empty or missing.
|
||||
The author of the relayable sends the entity to the parent author. The author must include the `author_signature`.
|
||||
|
||||
The parent author then must add the `parent_author_signature` and send the entity to all the recipients of the parent
|
||||
entity.
|
||||
The parent author then must envelop it in a new [Magic Envelope][magicsig] and send the entity to all the recipients
|
||||
of the parent entity. If the author and the parent author are on the same server, the author must sign the
|
||||
`author_signature` and the parent author needs to sign the Magic Envelope.
|
||||
|
||||
If someone other then the parent author receives an relayable without a valid `parent_author_signature`, it must be
|
||||
ignored. If the `author_signature` is missing or invalid, it also must be ignored.
|
||||
If someone other then the parent author receives a relayable without a valid Magic Envelope signed from
|
||||
the parent author, it must be ignored. If the `author_signature` is missing or invalid, it also must be ignored.
|
||||
|
||||
## Signatures
|
||||
|
||||
The string to sign is built with the content of all properties (except the `author_signature` and
|
||||
`parent_author_signature` itself), concatenated using `;` as separator in the same order as they appear in the XML. The
|
||||
order in the XML is not specified.
|
||||
The string to sign is built with the content of all properties (except the `author_signature` itself),
|
||||
concatenated using `;` as separator in the same order as they appear in the XML. The order in the XML is not specified.
|
||||
|
||||
This ensures that relayables even work, if the parent author or another recipient does not know all properties of the
|
||||
relayable entity (e.g. older version of diaspora\*).
|
||||
|
|
|
|||
|
|
@ -28,16 +28,15 @@ module DiasporaFederation
|
|||
# @return [String] parent guid
|
||||
#
|
||||
# @!attribute [r] author_signature
|
||||
# Contains a signature of the entity using the private key of the author of a post itself
|
||||
# Contains a signature of the entity using the private key of the author of a relayable itself.
|
||||
# The presence of this signature is mandatory. Without it the entity won't be accepted by
|
||||
# a target pod.
|
||||
# @return [String] author signature
|
||||
#
|
||||
# @!attribute [r] parent_author_signature
|
||||
# Contains a signature of the entity using the private key of the author of a parent post
|
||||
# This signature is required only when federating from upstream (parent) post author to
|
||||
# downstream subscribers. This is the case when the parent author has to resend a relayable
|
||||
# received from one of their subscribers to all others.
|
||||
# Contains a signature of the entity using the private key of the author of a parent post.
|
||||
# @deprecated This signature isn't required anymore, because we can check the signature from
|
||||
# the parent author in the MagicEnvelope.
|
||||
# @return [String] parent author signature
|
||||
#
|
||||
# @!attribute [r] parent
|
||||
|
|
@ -71,18 +70,17 @@ module DiasporaFederation
|
|||
super(data)
|
||||
end
|
||||
|
||||
# Verifies the signatures (+author_signature+ and +parent_author_signature+ if needed).
|
||||
# Verifies the +author_signature+.
|
||||
# @see DiasporaFederation::Entities::Signable#verify_signature
|
||||
#
|
||||
# @raise [SignatureVerificationFailed] if the signature is not valid
|
||||
# @raise [PublicKeyNotFound] if no public key is found
|
||||
def verify_signatures
|
||||
verify_signature(author, :author_signature)
|
||||
|
||||
# This happens only on downstream federation.
|
||||
verify_signature(parent.author, :parent_author_signature) unless parent.local
|
||||
def verify_signature
|
||||
super(author, :author_signature)
|
||||
end
|
||||
|
||||
def sender_valid?(sender)
|
||||
sender == author || sender == parent.author
|
||||
(sender == author && parent.local) || sender == parent.author
|
||||
end
|
||||
|
||||
# @return [String] string representation of this object
|
||||
|
|
@ -178,7 +176,7 @@ module DiasporaFederation
|
|||
additional_data = properties_hash.reject {|key, _| class_props.has_key?(key) }
|
||||
|
||||
fetch_parent(properties_hash)
|
||||
new(properties_hash, property_order, additional_data).tap(&:verify_signatures)
|
||||
new(properties_hash, property_order, additional_data).tap(&:verify_signature)
|
||||
end
|
||||
|
||||
private
|
||||
|
|
|
|||
|
|
@ -224,7 +224,6 @@ XML
|
|||
|
||||
before do
|
||||
expect_callback(:fetch_public_key, author).and_return(author_key.public_key)
|
||||
expect_callback(:fetch_public_key, parent.author).and_return(parent_key.public_key)
|
||||
expect_callback(:fetch_related_entity, "Post", parent_guid).and_return(parent)
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -25,16 +25,15 @@ module DiasporaFederation
|
|||
end
|
||||
end
|
||||
|
||||
describe "#verify_signatures" do
|
||||
describe "#verify_signature" do
|
||||
it "doesn't raise anything if correct signatures were passed" do
|
||||
hash[:author_signature] = sign_with_key(author_pkey, signature_data)
|
||||
hash[:parent_author_signature] = sign_with_key(parent_pkey, signature_data)
|
||||
hash[:parent] = remote_parent
|
||||
|
||||
expect_callback(:fetch_public_key, author).and_return(author_pkey.public_key)
|
||||
expect_callback(:fetch_public_key, remote_parent.author).and_return(parent_pkey.public_key)
|
||||
|
||||
expect { Entities::SomeRelayable.new(hash, signature_order).verify_signatures }.not_to raise_error
|
||||
expect { Entities::SomeRelayable.new(hash, signature_order).verify_signature }.not_to raise_error
|
||||
end
|
||||
|
||||
it "doesn't raise anything if correct signatures with new property were passed" do
|
||||
|
|
@ -46,10 +45,9 @@ module DiasporaFederation
|
|||
hash[:parent] = remote_parent
|
||||
|
||||
expect_callback(:fetch_public_key, author).and_return(author_pkey.public_key)
|
||||
expect_callback(:fetch_public_key, remote_parent.author).and_return(parent_pkey.public_key)
|
||||
|
||||
expect {
|
||||
Entities::SomeRelayable.new(hash, signature_order, "new_property" => new_property).verify_signatures
|
||||
Entities::SomeRelayable.new(hash, signature_order, "new_property" => new_property).verify_signature
|
||||
}.not_to raise_error
|
||||
end
|
||||
|
||||
|
|
@ -57,7 +55,7 @@ module DiasporaFederation
|
|||
expect_callback(:fetch_public_key, anything).and_return(nil)
|
||||
|
||||
expect {
|
||||
Entities::SomeRelayable.new(hash, signature_order).verify_signatures
|
||||
Entities::SomeRelayable.new(hash, signature_order).verify_signature
|
||||
}.to raise_error Entities::Relayable::PublicKeyNotFound
|
||||
end
|
||||
|
||||
|
|
@ -67,7 +65,7 @@ module DiasporaFederation
|
|||
expect_callback(:fetch_public_key, author).and_return(author_pkey.public_key)
|
||||
|
||||
expect {
|
||||
Entities::SomeRelayable.new(hash, signature_order).verify_signatures
|
||||
Entities::SomeRelayable.new(hash, signature_order).verify_signature
|
||||
}.to raise_error Entities::Relayable::SignatureVerificationFailed
|
||||
end
|
||||
|
||||
|
|
@ -77,56 +75,28 @@ module DiasporaFederation
|
|||
expect_callback(:fetch_public_key, author).and_return(author_pkey.public_key)
|
||||
|
||||
expect {
|
||||
Entities::SomeRelayable.new(hash, signature_order).verify_signatures
|
||||
Entities::SomeRelayable.new(hash, signature_order).verify_signature
|
||||
}.to raise_error Entities::Relayable::SignatureVerificationFailed
|
||||
end
|
||||
|
||||
it "raises when no public key for parent author was fetched" do
|
||||
hash[:author_signature] = sign_with_key(author_pkey, signature_data)
|
||||
hash[:parent] = remote_parent
|
||||
|
||||
expect_callback(:fetch_public_key, author).and_return(author_pkey.public_key)
|
||||
expect_callback(:fetch_public_key, remote_parent.author).and_return(nil)
|
||||
|
||||
expect {
|
||||
Entities::SomeRelayable.new(hash, signature_order).verify_signatures
|
||||
}.to raise_error Entities::Relayable::PublicKeyNotFound
|
||||
end
|
||||
|
||||
it "raises when no parent author signature was passed" do
|
||||
it "doesn't raise when no parent author signature was passed" do
|
||||
hash[:author_signature] = sign_with_key(author_pkey, signature_data)
|
||||
hash[:parent_author_signature] = nil
|
||||
hash[:parent] = remote_parent
|
||||
|
||||
expect_callback(:fetch_public_key, author).and_return(author_pkey.public_key)
|
||||
expect_callback(:fetch_public_key, remote_parent.author).and_return(parent_pkey.public_key)
|
||||
|
||||
expect {
|
||||
Entities::SomeRelayable.new(hash, signature_order).verify_signatures
|
||||
}.to raise_error Entities::Relayable::SignatureVerificationFailed
|
||||
expect { Entities::SomeRelayable.new(hash, signature_order).verify_signature }.not_to raise_error
|
||||
end
|
||||
|
||||
it "raises when bad parent author signature was passed" do
|
||||
hash[:author_signature] = sign_with_key(author_pkey, signature_data)
|
||||
hash[:parent_author_signature] = sign_with_key(parent_pkey, "bad signed string")
|
||||
hash[:parent] = remote_parent
|
||||
|
||||
expect_callback(:fetch_public_key, author).and_return(author_pkey.public_key)
|
||||
expect_callback(:fetch_public_key, remote_parent.author).and_return(parent_pkey.public_key)
|
||||
|
||||
expect {
|
||||
Entities::SomeRelayable.new(hash, signature_order).verify_signatures
|
||||
}.to raise_error Entities::Relayable::SignatureVerificationFailed
|
||||
end
|
||||
|
||||
it "doesn't raise if parent_author_signature isn't set but we're on upstream federation" do
|
||||
it "doesn't raise when no parent author signature was passed and we're on upstream federation" do
|
||||
hash[:author_signature] = sign_with_key(author_pkey, signature_data)
|
||||
hash[:parent_author_signature] = nil
|
||||
hash[:parent] = local_parent
|
||||
|
||||
expect_callback(:fetch_public_key, author).and_return(author_pkey.public_key)
|
||||
|
||||
expect { Entities::SomeRelayable.new(hash, signature_order).verify_signatures }.not_to raise_error
|
||||
expect { Entities::SomeRelayable.new(hash, signature_order).verify_signature }.not_to raise_error
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -228,7 +198,6 @@ XML
|
|||
before do
|
||||
expect_callback(:fetch_related_entity, "Parent", parent_guid).and_return(remote_parent)
|
||||
expect_callback(:fetch_public_key, author).and_return(author_pkey.public_key)
|
||||
expect_callback(:fetch_public_key, remote_parent.author).and_return(parent_pkey.public_key)
|
||||
end
|
||||
|
||||
let(:new_signature_data) { "#{author};#{guid};#{parent_guid};#{new_property};#{property}" }
|
||||
|
|
@ -374,7 +343,6 @@ XML
|
|||
before do
|
||||
expect_callback(:fetch_related_entity, "Parent", parent_guid).and_return(remote_parent)
|
||||
expect_callback(:fetch_public_key, author).and_return(author_pkey.public_key)
|
||||
expect_callback(:fetch_public_key, remote_parent.author).and_return(parent_pkey.public_key)
|
||||
end
|
||||
|
||||
context "when properties are sorted and there is an unknown property" do
|
||||
|
|
@ -475,7 +443,6 @@ XML
|
|||
context "fetch parent" do
|
||||
before do
|
||||
expect_callback(:fetch_public_key, author).and_return(author_pkey.public_key)
|
||||
expect_callback(:fetch_public_key, remote_parent.author).and_return(parent_pkey.public_key)
|
||||
expect_callback(:fetch_private_key, author).and_return(author_pkey)
|
||||
expect_callback(:fetch_private_key, remote_parent.author).and_return(parent_pkey)
|
||||
end
|
||||
|
|
@ -508,12 +475,18 @@ XML
|
|||
end
|
||||
|
||||
describe "#sender_valid?" do
|
||||
it "allows author" do
|
||||
it "allows author if the parent is local" do
|
||||
entity = Entities::SomeRelayable.new(hash)
|
||||
|
||||
expect(entity.sender_valid?(author)).to be_truthy
|
||||
end
|
||||
|
||||
it "does not allow the author if the parent is not local" do
|
||||
entity = Entities::SomeRelayable.new(hash.merge(parent: remote_parent))
|
||||
|
||||
expect(entity.sender_valid?(author)).to be_falsey
|
||||
end
|
||||
|
||||
it "allows parent author" do
|
||||
entity = Entities::SomeRelayable.new(hash)
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue