Remove additional MagicEnvelope wrapper with diaspora header

Related to #30
This commit is contained in:
Benjamin Neff 2017-04-28 03:00:29 +02:00
parent 221d87d7fe
commit 1f99518706
No known key found for this signature in database
GPG key ID: 971464C3F1A90194
7 changed files with 53 additions and 110 deletions

View file

@ -115,7 +115,7 @@ module DiasporaFederation
magic_envelope = MagicEnvelope.new(entity) magic_envelope = MagicEnvelope.new(entity)
slap.cipher_params = magic_envelope.encrypt! slap.cipher_params = magic_envelope.encrypt!
slap.magic_envelope_xml = magic_envelope.envelop(privkey) slap.magic_envelope_xml = magic_envelope.envelop(privkey).root
end end
end end

View file

@ -153,7 +153,7 @@ module DiasporaFederation
def build_xml def build_xml
Nokogiri::XML::Builder.new(encoding: "UTF-8") {|xml| Nokogiri::XML::Builder.new(encoding: "UTF-8") {|xml|
yield xml yield xml
}.doc.root }.doc
end end
# Creates the signature for all fields according to specification # Creates the signature for all fields according to specification

View file

@ -49,27 +49,6 @@ module DiasporaFederation
MagicEnvelope.unenvelop(magic_env_from_doc(doc), sender) MagicEnvelope.unenvelop(magic_env_from_doc(doc), sender)
end end
# Creates an unencrypted Salmon Slap and returns the XML string.
#
# @param [String] author_id diaspora* ID of the author
# @param [OpenSSL::PKey::RSA] privkey sender private_key for signing the magic envelope
# @param [Entity] entity payload
# @return [String] Salmon XML string
# @raise [ArgumentError] if any of the arguments is not the correct type
def self.generate_xml(author_id, privkey, entity)
raise ArgumentError unless author_id.instance_of?(String) &&
privkey.instance_of?(OpenSSL::PKey::RSA) &&
entity.is_a?(Entity)
build_xml do |xml|
xml.header {
xml.author_id(author_id)
}
xml.parent << MagicEnvelope.new(entity, author_id).envelop(privkey)
end
end
# Builds the xml for the Salmon Slap. # Builds the xml for the Salmon Slap.
# #
# @yield [xml] Invokes the block with the # @yield [xml] Invokes the block with the

View file

@ -24,7 +24,13 @@ module DiasporaFederation
it "parses the entity with legacy slap receiver" do it "parses the entity with legacy slap receiver" do
expect_callback(:fetch_public_key, post.author).and_return(sender_key) expect_callback(:fetch_public_key, post.author).and_return(sender_key)
data = DiasporaFederation::Salmon::Slap.generate_xml(post.author, sender_key, post) data = DiasporaFederation::Salmon::Slap.build_xml do |xml|
xml.header {
xml.author_id(post.author)
}
xml.parent << Salmon::MagicEnvelope.new(post, post.author).envelop(sender_key).root
end
expect_callback(:receive_entity, kind_of(Entities::StatusMessage), post.author, nil) do |_, entity| expect_callback(:receive_entity, kind_of(Entities::StatusMessage), post.author, nil) do |_, entity|
expect(entity.guid).to eq(post.guid) expect(entity.guid).to eq(post.guid)

View file

@ -32,7 +32,7 @@ module DiasporaFederation
xml = Salmon::AES.decrypt(json["encrypted_magic_envelope"], key["key"], key["iv"]) xml = Salmon::AES.decrypt(json["encrypted_magic_envelope"], key["key"], key["iv"])
expect(Nokogiri::XML::Document.parse(xml).root.to_xml).to eq(magic_env.to_xml) expect(Nokogiri::XML::Document.parse(xml).to_xml).to eq(magic_env.to_xml)
end end
end end

View file

@ -6,10 +6,10 @@ module DiasporaFederation
let(:envelope) { Salmon::MagicEnvelope.new(payload, sender) } let(:envelope) { Salmon::MagicEnvelope.new(payload, sender) }
def sig_subj(env) def sig_subj(env)
data = Base64.urlsafe_decode64(env.at_xpath("me:data").content) data = Base64.urlsafe_decode64(env.at_xpath("me:env/me:data").content)
type = env.at_xpath("me:data")["type"] type = env.at_xpath("me:env/me:data")["type"]
enc = env.at_xpath("me:encoding").content enc = env.at_xpath("me:env/me:encoding").content
alg = env.at_xpath("me:alg").content alg = env.at_xpath("me:env/me:alg").content
[data, type, enc, alg].map {|i| Base64.urlsafe_encode64(i) }.join(".") [data, type, enc, alg].map {|i| Base64.urlsafe_encode64(i) }.join(".")
end end
@ -41,12 +41,12 @@ module DiasporaFederation
end end
end end
it "should be an instance of Nokogiri::XML::Element" do it "should be an instance of Nokogiri::XML::Document" do
expect(envelope.envelop(privkey)).to be_an_instance_of Nokogiri::XML::Element expect(envelope.envelop(privkey)).to be_an_instance_of Nokogiri::XML::Document
end end
it "returns a magic envelope of correct structure" do it "returns a magic envelope of correct structure" do
env_xml = envelope.envelop(privkey) env_xml = envelope.envelop(privkey).root
expect(env_xml.name).to eq("env") expect(env_xml.name).to eq("env")
control = %w(data encoding alg sig) control = %w(data encoding alg sig)
@ -59,13 +59,13 @@ module DiasporaFederation
end end
it "adds the sender to the signature" do it "adds the sender to the signature" do
key_id = envelope.envelop(privkey).at_xpath("me:sig")["key_id"] key_id = envelope.envelop(privkey).at_xpath("me:env/me:sig")["key_id"]
expect(Base64.urlsafe_decode64(key_id)).to eq(sender) expect(Base64.urlsafe_decode64(key_id)).to eq(sender)
end end
it "adds the data_type" do it "adds the data_type" do
data_type = envelope.envelop(privkey).at_xpath("me:data")["type"] data_type = envelope.envelop(privkey).at_xpath("me:env/me:data")["type"]
expect(data_type).to eq("application/xml") expect(data_type).to eq("application/xml")
end end
@ -74,7 +74,7 @@ module DiasporaFederation
env_xml = envelope.envelop(privkey) env_xml = envelope.envelop(privkey)
subj = sig_subj(env_xml) subj = sig_subj(env_xml)
sig = Base64.urlsafe_decode64(env_xml.at_xpath("me:sig").content) sig = Base64.urlsafe_decode64(env_xml.at_xpath("me:env/me:sig").content)
expect(privkey.public_key.verify(OpenSSL::Digest::SHA256.new, sig, subj)).to be_truthy expect(privkey.public_key.verify(OpenSSL::Digest::SHA256.new, sig, subj)).to be_truthy
end end
@ -103,6 +103,8 @@ module DiasporaFederation
end end
describe ".unenvelop" do describe ".unenvelop" do
let(:envelope_root) { envelope.envelop(privkey).root }
context "sanity" do context "sanity" do
before do before do
allow(DiasporaFederation.callbacks).to receive(:trigger).with( allow(DiasporaFederation.callbacks).to receive(:trigger).with(
@ -112,7 +114,7 @@ module DiasporaFederation
it "works with sane input" do it "works with sane input" do
expect { expect {
Salmon::MagicEnvelope.unenvelop(envelope.envelop(privkey), sender) Salmon::MagicEnvelope.unenvelop(envelope_root, sender)
}.not_to raise_error }.not_to raise_error
end end
@ -131,10 +133,9 @@ module DiasporaFederation
end end
it "raises if missing signature" do it "raises if missing signature" do
bad_env = envelope.envelop(privkey) envelope_root.at_xpath("me:sig").remove
bad_env.at_xpath("me:sig").remove
expect { expect {
Salmon::MagicEnvelope.unenvelop(bad_env, sender) Salmon::MagicEnvelope.unenvelop(envelope_root, sender)
}.to raise_error Salmon::InvalidEnvelope, "missing me:sig" }.to raise_error Salmon::InvalidEnvelope, "missing me:sig"
end end
@ -145,70 +146,63 @@ module DiasporaFederation
expect_callback(:fetch_public_key, other_sender).and_return(other_key) expect_callback(:fetch_public_key, other_sender).and_return(other_key)
expect { expect {
Salmon::MagicEnvelope.unenvelop(envelope.envelop(privkey), other_sender) Salmon::MagicEnvelope.unenvelop(envelope_root, other_sender)
}.to raise_error Salmon::InvalidSignature }.to raise_error Salmon::InvalidSignature
end end
it "raises if missing data" do it "raises if missing data" do
bad_env = envelope.envelop(privkey) envelope_root.at_xpath("me:data").remove
bad_env.at_xpath("me:data").remove
expect { expect {
Salmon::MagicEnvelope.unenvelop(bad_env, sender) Salmon::MagicEnvelope.unenvelop(envelope_root, sender)
}.to raise_error Salmon::InvalidEnvelope, "missing me:data" }.to raise_error Salmon::InvalidEnvelope, "missing me:data"
end end
it "raises if missing encoding" do it "raises if missing encoding" do
bad_env = envelope.envelop(privkey) envelope_root.at_xpath("me:encoding").remove
bad_env.at_xpath("me:encoding").remove
expect { expect {
Salmon::MagicEnvelope.unenvelop(bad_env, sender) Salmon::MagicEnvelope.unenvelop(envelope_root, sender)
}.to raise_error Salmon::InvalidEncoding, "missing encoding" }.to raise_error Salmon::InvalidEncoding, "missing encoding"
end end
it "verifies the encoding" do it "verifies the encoding" do
bad_env = envelope.envelop(privkey) envelope_root.at_xpath("me:encoding").content = "invalid_enc"
bad_env.at_xpath("me:encoding").content = "invalid_enc"
expect { expect {
Salmon::MagicEnvelope.unenvelop(bad_env, sender) Salmon::MagicEnvelope.unenvelop(envelope_root, sender)
}.to raise_error Salmon::InvalidEncoding, "invalid encoding: invalid_enc" }.to raise_error Salmon::InvalidEncoding, "invalid encoding: invalid_enc"
end end
it "raises if missing algorithm" do it "raises if missing algorithm" do
bad_env = envelope.envelop(privkey) envelope_root.at_xpath("me:alg").remove
bad_env.at_xpath("me:alg").remove
expect { expect {
Salmon::MagicEnvelope.unenvelop(bad_env, sender) Salmon::MagicEnvelope.unenvelop(envelope_root, sender)
}.to raise_error Salmon::InvalidAlgorithm, "missing algorithm" }.to raise_error Salmon::InvalidAlgorithm, "missing algorithm"
end end
it "verifies the algorithm" do it "verifies the algorithm" do
bad_env = envelope.envelop(privkey) envelope_root.at_xpath("me:alg").content = "invalid_alg"
bad_env.at_xpath("me:alg").content = "invalid_alg"
expect { expect {
Salmon::MagicEnvelope.unenvelop(bad_env, sender) Salmon::MagicEnvelope.unenvelop(envelope_root, sender)
}.to raise_error Salmon::InvalidAlgorithm, "invalid algorithm: invalid_alg" }.to raise_error Salmon::InvalidAlgorithm, "invalid algorithm: invalid_alg"
end end
it "raises if missing data type" do it "raises if missing data type" do
bad_env = envelope.envelop(privkey) envelope_root.at_xpath("me:data").attributes["type"].remove
bad_env.at_xpath("me:data").attributes["type"].remove
expect { expect {
Salmon::MagicEnvelope.unenvelop(bad_env, sender) Salmon::MagicEnvelope.unenvelop(envelope_root, sender)
}.to raise_error Salmon::InvalidDataType, "missing data type" }.to raise_error Salmon::InvalidDataType, "missing data type"
end end
it "verifies the data type" do it "verifies the data type" do
bad_env = envelope.envelop(privkey) envelope_root.at_xpath("me:data")["type"] = "invalid_type"
bad_env.at_xpath("me:data")["type"] = "invalid_type"
expect { expect {
Salmon::MagicEnvelope.unenvelop(bad_env, sender) Salmon::MagicEnvelope.unenvelop(envelope_root, sender)
}.to raise_error Salmon::InvalidDataType, "invalid data type: invalid_type" }.to raise_error Salmon::InvalidDataType, "invalid data type: invalid_type"
end end
end end
context "generated instance" do context "generated instance" do
it_behaves_like "a MagicEnvelope instance" do it_behaves_like "a MagicEnvelope instance" do
subject { Salmon::MagicEnvelope.unenvelop(envelope.envelop(privkey), sender) } subject { Salmon::MagicEnvelope.unenvelop(envelope_root, sender) }
end end
end end
@ -217,7 +211,7 @@ module DiasporaFederation
env = Salmon::MagicEnvelope.new(payload) env = Salmon::MagicEnvelope.new(payload)
params = env.encrypt! params = env.encrypt!
env_xml = env.envelop(privkey) env_xml = env.envelop(privkey).root
magic_env = Salmon::MagicEnvelope.unenvelop(env_xml, sender, params) magic_env = Salmon::MagicEnvelope.unenvelop(env_xml, sender, params)
expect(magic_env.payload).to be_an_instance_of Entities::TestEntity expect(magic_env.payload).to be_an_instance_of Entities::TestEntity
@ -227,17 +221,15 @@ module DiasporaFederation
context "use key_id from magic envelope" do context "use key_id from magic envelope" do
context "generated instance" do context "generated instance" do
it_behaves_like "a MagicEnvelope instance" do it_behaves_like "a MagicEnvelope instance" do
subject { Salmon::MagicEnvelope.unenvelop(envelope.envelop(privkey)) } subject { Salmon::MagicEnvelope.unenvelop(envelope_root) }
end end
end end
it "raises if the magic envelope has no key_id" do it "raises if the magic envelope has no key_id" do
bad_env = envelope.envelop(privkey) envelope_root.at_xpath("me:sig").attributes["key_id"].remove
bad_env.at_xpath("me:sig").attributes["key_id"].remove
expect { expect {
Salmon::MagicEnvelope.unenvelop(bad_env) Salmon::MagicEnvelope.unenvelop(envelope_root)
}.to raise_error Salmon::InvalidEnvelope }.to raise_error Salmon::InvalidEnvelope
end end
@ -245,7 +237,7 @@ module DiasporaFederation
expect_callback(:fetch_public_key, sender).and_return(nil) expect_callback(:fetch_public_key, sender).and_return(nil)
expect { expect {
Salmon::MagicEnvelope.unenvelop(envelope.envelop(privkey)) Salmon::MagicEnvelope.unenvelop(envelope_root)
}.to raise_error Salmon::SenderKeyNotFound }.to raise_error Salmon::SenderKeyNotFound
end end
end end

View file

@ -3,49 +3,15 @@ module DiasporaFederation
let(:sender) { "test_user@pod.somedomain.tld" } let(:sender) { "test_user@pod.somedomain.tld" }
let(:privkey) { OpenSSL::PKey::RSA.generate(512) } # use small key for speedy specs let(:privkey) { OpenSSL::PKey::RSA.generate(512) } # use small key for speedy specs
let(:payload) { Entities::TestEntity.new(test: "qwertzuiop") } let(:payload) { Entities::TestEntity.new(test: "qwertzuiop") }
let(:slap_xml) { Salmon::Slap.generate_xml(sender, privkey, payload) } let(:slap_xml) {
Salmon::Slap.build_xml do |xml|
xml.header {
xml.author_id(sender)
}
describe ".generate_xml" do xml.parent << Salmon::MagicEnvelope.new(payload, sender).envelop(privkey).root
context "sanity" do
it "accepts correct params" do
expect {
Salmon::Slap.generate_xml(sender, privkey, payload)
}.not_to raise_error
end
it "raises an error when the sender is the wrong type" do
[1234, true, :symbol, payload, privkey].each do |val|
expect {
Salmon::Slap.generate_xml(val, privkey, payload)
}.to raise_error ArgumentError
end
end
it "raises an error when the privkey is the wrong type" do
["asdf", 1234, true, :symbol, payload].each do |val|
expect {
Salmon::Slap.generate_xml(sender, val, payload)
}.to raise_error ArgumentError
end
end
it "raises an error when the payload is the wrong type" do
["asdf", 1234, true, :symbol, privkey].each do |val|
expect {
Salmon::Slap.generate_xml(sender, privkey, val)
}.to raise_error ArgumentError
end
end
end end
}
it "generates valid xml" do
ns = {d: Salmon::XMLNS, me: Salmon::MagicEnvelope::XMLNS}
doc = Nokogiri::XML::Document.parse(slap_xml)
expect(doc.root.name).to eq("diaspora")
expect(doc.at_xpath("d:diaspora/d:header/d:author_id", ns).content).to eq(sender)
expect(doc.xpath("d:diaspora/me:env", ns)).to have(1).item
end
end
describe ".from_xml" do describe ".from_xml" do
context "sanity" do context "sanity" do