From 58abbcc058336c5329d628fa8b2595ef0504c053 Mon Sep 17 00:00:00 2001 From: danielgrippi Date: Thu, 15 Sep 2011 15:36:40 -0700 Subject: [PATCH 1/8] DG MS; activate dispatcher switch in Dispatcher; remove diasporahq blocker --- app/models/jobs/http_multi.rb | 2 -- lib/postzord/dispatcher.rb | 10 +++++----- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/app/models/jobs/http_multi.rb b/app/models/jobs/http_multi.rb index 3baff5ebb..ae9f8d47f 100644 --- a/app/models/jobs/http_multi.rb +++ b/app/models/jobs/http_multi.rb @@ -13,8 +13,6 @@ module Jobs MAX_RETRIES = 3 def self.perform(user_id, encoded_object_xml, person_ids, dispatcher_class_as_string, retry_count=0) - return true if user_id == '91842' #NOTE 09/08/11 blocking diapsorahqposts - user = User.find(user_id) people = Person.where(:id => person_ids) diff --git a/lib/postzord/dispatcher.rb b/lib/postzord/dispatcher.rb index 7cd8ddc04..8d5e5b0fa 100644 --- a/lib/postzord/dispatcher.rb +++ b/lib/postzord/dispatcher.rb @@ -15,11 +15,11 @@ class Postzord::Dispatcher raise 'this object does not respond_to? to_diaspora xml. try including Diaspora::Webhooks into your object' end - #if self.object_should_be_processed_as_public?(object) - # Postzord::Dispatcher::Public.new(user, object, opts) - #else + if self.object_should_be_processed_as_public?(object) + Postzord::Dispatcher::Public.new(user, object, opts) + else Postzord::Dispatcher::Private.new(user, object, opts) - #end + end end # @param object [Object] @@ -59,7 +59,7 @@ class Postzord::Dispatcher self.deliver_to_local(local_people) end - self.deliver_to_remote(remote_people) unless @sender.username == 'diasporahq' #NOTE: 09/08/11 this is temporary (~3days max) till we fix fanout in federation + self.deliver_to_remote(remote_people) end # @return [Array] Recipients of the object, minus any additional subscribers From 36f5e45c2568c73d8a0f0647598d3cd52b5bfabd Mon Sep 17 00:00:00 2001 From: danielgrippi Date: Wed, 31 Aug 2011 16:26:02 -0700 Subject: [PATCH 2/8] change Base64.encode64 to Base64.encode64s (encode without newlines) --- app/views/publics/webfinger.erb | 2 +- lib/diaspora/encryptable.rb | 2 +- lib/encryptor.rb | 8 ++++---- lib/postzord/dispatcher.rb | 2 +- lib/salmon/salmon.rb | 1 + 5 files changed, 8 insertions(+), 7 deletions(-) diff --git a/app/views/publics/webfinger.erb b/app/views/publics/webfinger.erb index cc6c64b36..c462a13fe 100644 --- a/app/views/publics/webfinger.erb +++ b/app/views/publics/webfinger.erb @@ -9,5 +9,5 @@ /> - + diff --git a/lib/diaspora/encryptable.rb b/lib/diaspora/encryptable.rb index a950e38f5..75bcca4e2 100644 --- a/lib/diaspora/encryptable.rb +++ b/lib/diaspora/encryptable.rb @@ -26,7 +26,7 @@ module Diaspora # @param [OpenSSL::PKey::RSA] key An RSA key # @return [String] A Base64 encoded signature of #signable_string with key def sign_with_key(key) - sig = Base64.encode64(key.sign "SHA", signable_string) + sig = Base64.encode64s(key.sign "SHA", signable_string) log_hash = {:event => :sign_with_key, :status => :complete} log_hash.merge(:model_id => self.id) if self.respond_to?(:persisted?) Rails.logger.info(log_hash) diff --git a/lib/encryptor.rb b/lib/encryptor.rb index a75dc7ba6..0ade6d1b1 100644 --- a/lib/encryptor.rb +++ b/lib/encryptor.rb @@ -9,14 +9,14 @@ module Encryptor ciphertext = aes_encrypt(cleartext, aes_key) encrypted_key = encrypt_aes_key aes_key cipher_hash = {:aes_key => encrypted_key, :ciphertext => ciphertext} - Base64.encode64( cipher_hash.to_json ) + Base64.encode64s( cipher_hash.to_json ) end def gen_aes_key cipher = OpenSSL::Cipher.new('AES-256-CBC') key = cipher.random_key iv = cipher.random_iv - {'key' => Base64.encode64(key), 'iv' => Base64.encode64(iv)} + {'key' => Base64.encode64s(key), 'iv' => Base64.encode64(iv)} end def aes_encrypt(txt, key) @@ -27,11 +27,11 @@ module Encryptor ciphertext = '' ciphertext << cipher.update(txt) ciphertext << cipher.final - Base64.encode64 ciphertext + Base64.encode64s(ciphertext) end def encrypt_aes_key key - Base64.encode64 public_key.public_encrypt( key.to_json ) + Base64.encode64s(public_key.public_encrypt( key.to_json )) end end diff --git a/lib/postzord/dispatcher.rb b/lib/postzord/dispatcher.rb index 8d5e5b0fa..01649d87b 100644 --- a/lib/postzord/dispatcher.rb +++ b/lib/postzord/dispatcher.rb @@ -152,7 +152,7 @@ class Postzord::Dispatcher # @param remote_people [Array] Recipients of the post on other pods # @return [void] def queue_remote_delivery_job(remote_people) - Resque.enqueue(Jobs::HttpMulti, @sender.id, Base64.encode64(@object.to_diaspora_xml), remote_people.map{|p| p.id}, self.class.to_s) + Resque.enqueue(Jobs::HttpMulti, @sender.id, Base64.encode64s(@object.to_diaspora_xml), remote_people.map{|p| p.id}, self.class.to_s) end end diff --git a/lib/salmon/salmon.rb b/lib/salmon/salmon.rb index 20c7c750b..aa0dd4b1d 100644 --- a/lib/salmon/salmon.rb +++ b/lib/salmon/salmon.rb @@ -17,6 +17,7 @@ module Base64 # ArgumentError is raised if +str+ is incorrectly padded or contains # non-alphabet characters. Note that CR or LF are also rejected. def strict_decode64(str) + Rails.logger.info("trying to decode string: " + str) str.unpack("m0").first end From ce9c17fa2e73411896ab45f1047a8712e32560f2 Mon Sep 17 00:00:00 2001 From: danielgrippi Date: Wed, 31 Aug 2011 16:52:12 -0700 Subject: [PATCH 3/8] use ActiveSupport's Base64 encoding methods instead of calling Array#pack directly; strip new lines. --- lib/encryptor.rb | 2 +- lib/salmon/salmon.rb | 20 ++------------------ 2 files changed, 3 insertions(+), 19 deletions(-) diff --git a/lib/encryptor.rb b/lib/encryptor.rb index 0ade6d1b1..165ab91f2 100644 --- a/lib/encryptor.rb +++ b/lib/encryptor.rb @@ -16,7 +16,7 @@ module Encryptor cipher = OpenSSL::Cipher.new('AES-256-CBC') key = cipher.random_key iv = cipher.random_iv - {'key' => Base64.encode64s(key), 'iv' => Base64.encode64(iv)} + {'key' => Base64.encode64s(key), 'iv' => Base64.encode64s(iv)} end def aes_encrypt(txt, key) diff --git a/lib/salmon/salmon.rb b/lib/salmon/salmon.rb index aa0dd4b1d..3d09404d2 100644 --- a/lib/salmon/salmon.rb +++ b/lib/salmon/salmon.rb @@ -5,28 +5,12 @@ # Add URL safe Base64 support module Base64 module_function - # Returns the Base64-encoded version of +bin+. - # This method complies with RFC 4648. - # No line feeds are added. - def strict_encode64(bin) - [bin].pack("m0") - end - - # Returns the Base64-decoded version of +str+. - # This method complies with RFC 4648. - # ArgumentError is raised if +str+ is incorrectly padded or contains - # non-alphabet characters. Note that CR or LF are also rejected. - def strict_decode64(str) - Rails.logger.info("trying to decode string: " + str) - str.unpack("m0").first - end - # Returns the Base64-encoded version of +bin+. # This method complies with ``Base 64 Encoding with URL and Filename Safe # Alphabet'' in RFC 4648. # The alphabet uses '-' instead of '+' and '_' instead of '/'. def urlsafe_encode64(bin) - strict_encode64(bin).tr("+/", "-_") + self.encode64s(bin).tr("+/", "-_") end # Returns the Base64-decoded version of +str+. @@ -34,7 +18,7 @@ module Base64 # Alphabet'' in RFC 4648. # The alphabet uses '-' instead of '+' and '_' instead of '/'. def urlsafe_decode64(str) - strict_decode64(str.tr("-_", "+/")) + self.decode64(str.tr("-_", "+/")) end end From e2e6e7ea5bb6f065b69505df53f046533ad98e27 Mon Sep 17 00:00:00 2001 From: Ilyaaaaaaaaaaaaa Zhitomirskiy Date: Tue, 6 Sep 2011 14:30:30 -0700 Subject: [PATCH 4/8] just noticed the nonadded migration --- ...d_algorithm_fields_to_relayable_objects.rb | 56 +++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 db/migrate/20110826233833_add_algorithm_fields_to_relayable_objects.rb diff --git a/db/migrate/20110826233833_add_algorithm_fields_to_relayable_objects.rb b/db/migrate/20110826233833_add_algorithm_fields_to_relayable_objects.rb new file mode 100644 index 000000000..ac94e7452 --- /dev/null +++ b/db/migrate/20110826233833_add_algorithm_fields_to_relayable_objects.rb @@ -0,0 +1,56 @@ +class AddAlgorithmFieldsToRelayableObjects < ActiveRecord::Migration + def self.up + add_column :comments, :author_signature_algo, :string + add_column :comments, :parent_author_signature_algo, :string + + execute < Date: Thu, 8 Sep 2011 13:48:58 -0700 Subject: [PATCH 5/8] signing with SHA256, have a temp fallback on verification --- lib/diaspora/encryptable.rb | 10 +++++-- spec/lib/diaspora/encryptable_spec.rb | 38 +++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 2 deletions(-) create mode 100644 spec/lib/diaspora/encryptable_spec.rb diff --git a/lib/diaspora/encryptable.rb b/lib/diaspora/encryptable.rb index 75bcca4e2..734df8461 100644 --- a/lib/diaspora/encryptable.rb +++ b/lib/diaspora/encryptable.rb @@ -1,5 +1,7 @@ module Diaspora module Encryptable + + LAST_FALLBACK_TIME = "Sept 15 2011 17:00 UTC " # Check that signature is a correct signature of #signable_string by person # # @param [String] signature The signature to be verified. @@ -17,7 +19,11 @@ module Diaspora return false end log_string = "event=verify_signature status=complete guid=#{self.guid}" - validity = person.public_key.verify "SHA", Base64.decode64(signature), signable_string + validity = person.public_key.verify OpenSSL::Digest::SHA256.new, Base64.decode64(signature), signable_string + if !validity && Time.now < Time.parse(LAST_FALLBACK_TIME) + validity = person.public_key.verify "SHA", Base64.decode64(signature), signable_string + end + #validity = person.public_key.verify "SHA", Base64.decode64(signature), signable_string log_string += " validity=#{validity}" Rails.logger.info(log_string) validity @@ -26,7 +32,7 @@ module Diaspora # @param [OpenSSL::PKey::RSA] key An RSA key # @return [String] A Base64 encoded signature of #signable_string with key def sign_with_key(key) - sig = Base64.encode64s(key.sign "SHA", signable_string) + sig = Base64.encode64s(key.sign( OpenSSL::Digest::SHA256.new, signable_string )) log_hash = {:event => :sign_with_key, :status => :complete} log_hash.merge(:model_id => self.id) if self.respond_to?(:persisted?) Rails.logger.info(log_hash) diff --git a/spec/lib/diaspora/encryptable_spec.rb b/spec/lib/diaspora/encryptable_spec.rb new file mode 100644 index 000000000..9906ad870 --- /dev/null +++ b/spec/lib/diaspora/encryptable_spec.rb @@ -0,0 +1,38 @@ +# Copyright (c) 2010, Diaspora Inc. This file is +# licensed under the Affero General Public License version 3 or later. See +# the COPYRIGHT file. + +require 'spec_helper' + +describe Diaspora::Encryptable do + before do + @comment = Factory(:comment, :author => bob.person) + end + describe '#sign_with_key' do + it 'signs the object with RSA256 signature' do + sig = @comment.sign_with_key bob.encryption_key + bob.public_key.verify(OpenSSL::Digest::SHA256.new, Base64.decode64(sig), @comment.signable_string).should be_true + end + end + + describe '#verify_signature' do + it 'verifies SHA256 signatures' do + sig = @comment.sign_with_key bob.encryption_key + @comment.verify_signature(sig, bob.person).should be_true + end + + context "fallback" do + it "checks the SHA if it's within the week of the rollout window" do + sig = Base64.encode64s(bob.encryption_key.sign( "SHA", @comment.signable_string )) + @comment.verify_signature(sig, bob.person).should be_true + end + + it 'does not verify the fallback after rollout window' do + Kernel::silence_warnings { Diaspora::Encryptable.const_set(:LAST_FALLBACK_TIME,((Time.now - 1.week).to_s))} + + sig = Base64.encode64s(bob.encryption_key.sign( "SHA", @comment.signable_string )) + @comment.verify_signature(sig, bob.person).should be_false + end + end + end +end From b7288c8d8e05824a2b605271eb298681a105c126 Mon Sep 17 00:00:00 2001 From: Ilyaaaaaaaaaaaaa Zhitomirskiy Date: Thu, 8 Sep 2011 14:41:08 -0700 Subject: [PATCH 6/8] removed the algo field and a commented line --- ...d_algorithm_fields_to_relayable_objects.rb | 56 ------------------- lib/diaspora/encryptable.rb | 1 - 2 files changed, 57 deletions(-) delete mode 100644 db/migrate/20110826233833_add_algorithm_fields_to_relayable_objects.rb diff --git a/db/migrate/20110826233833_add_algorithm_fields_to_relayable_objects.rb b/db/migrate/20110826233833_add_algorithm_fields_to_relayable_objects.rb deleted file mode 100644 index ac94e7452..000000000 --- a/db/migrate/20110826233833_add_algorithm_fields_to_relayable_objects.rb +++ /dev/null @@ -1,56 +0,0 @@ -class AddAlgorithmFieldsToRelayableObjects < ActiveRecord::Migration - def self.up - add_column :comments, :author_signature_algo, :string - add_column :comments, :parent_author_signature_algo, :string - - execute < Date: Thu, 15 Sep 2011 15:45:01 -0700 Subject: [PATCH 7/8] refactored the salmon models and the xml, added a pending spec to strip '=' --- lib/diaspora/encryptable.rb | 2 +- lib/postzord/receiver/private.rb | 4 +- lib/postzord/receiver/public.rb | 2 +- lib/salmon/encrypted_slap.rb | 27 +++++++++-- lib/salmon/magic_sig_envelope.rb | 13 +++--- lib/salmon/slap.rb | 40 ++++++++--------- spec/lib/postzord/receiver/private_spec.rb | 2 +- spec/lib/salmon/base64_spec.rb | 11 +++++ spec/lib/salmon/encrypted_slap_spec.rb | 52 ++++++++++++++++++---- spec/lib/salmon/slap_spec.rb | 51 ++++++++++++++++++++- 10 files changed, 156 insertions(+), 48 deletions(-) create mode 100644 spec/lib/salmon/base64_spec.rb diff --git a/lib/diaspora/encryptable.rb b/lib/diaspora/encryptable.rb index 241c15dde..cb31e56d6 100644 --- a/lib/diaspora/encryptable.rb +++ b/lib/diaspora/encryptable.rb @@ -1,7 +1,7 @@ module Diaspora module Encryptable - LAST_FALLBACK_TIME = "Sept 15 2011 17:00 UTC " + LAST_FALLBACK_TIME = "Sept 19 2011 17:00 UTC " # Check that signature is a correct signature of #signable_string by person # # @param [String] signature The signature to be verified. diff --git a/lib/postzord/receiver/private.rb b/lib/postzord/receiver/private.rb index 21d0f872e..969632610 100644 --- a/lib/postzord/receiver/private.rb +++ b/lib/postzord/receiver/private.rb @@ -13,7 +13,7 @@ module Postzord @user_person = @user.person @salmon_xml = opts[:salmon_xml] - @sender = opts[:person] || Webfinger.new(self.salmon.author_email).fetch + @sender = opts[:person] || Webfinger.new(self.salmon.author_id).fetch @author = @sender @object = opts[:object] @@ -23,7 +23,7 @@ module Postzord if @sender && self.salmon.verified_for_key?(@sender.public_key) parse_and_receive(salmon.parsed_data) else - Rails.logger.info("event=receive status=abort recipient=#{@user.diaspora_handle} sender=#{@salmon.author_email} reason='not_verified for key'") + Rails.logger.info("event=receive status=abort recipient=#{@user.diaspora_handle} sender=#{@salmon.author_id} reason='not_verified for key'") nil end end diff --git a/lib/postzord/receiver/public.rb b/lib/postzord/receiver/public.rb index 5ba887afd..0fc4374d4 100644 --- a/lib/postzord/receiver/public.rb +++ b/lib/postzord/receiver/public.rb @@ -9,7 +9,7 @@ module Postzord def initialize(xml) @salmon = Salmon::Slap.from_xml(xml) - @author = Webfinger.new(@salmon.author_email).fetch + @author = Webfinger.new(@salmon.author_id).fetch end # @return [Boolean] diff --git a/lib/salmon/encrypted_slap.rb b/lib/salmon/encrypted_slap.rb index 6cc6feda2..2770f1ad0 100644 --- a/lib/salmon/encrypted_slap.rb +++ b/lib/salmon/encrypted_slap.rb @@ -10,11 +10,21 @@ module Salmon def header(person) < - #{person.encrypt("#{plaintext_header}")} + #{person.encrypt(plaintext_header)} XML end + def plaintext_header + header =<
+ #{iv} + #{aes_key} + #{@author.diaspora_handle} + +HEADER + end + # @return [String, Boolean] False if RSAError; XML if no error def xml_for(person) begin @@ -24,12 +34,21 @@ XML false end end - + + # Takes in a doc of the header and sets the author id + # returns an empty hash + # @return [Hash] + def process_header(doc) + self.author_id = doc.search('author_id').text + self.aes_key = doc.search('aes_key').text + self.iv = doc.search('iv').text + end + # Decrypts an encrypted magic sig envelope # @param key_hash [Hash] Contains 'key' (aes) and 'iv' values # @param user [User] - def parse_data(key_hash, user) - user.aes_decrypt(super, key_hash) + def parse_data(user) + user.aes_decrypt(super, {'key' => self.aes_key, 'iv' => self.iv}) end # Decrypts and parses out the salmon header diff --git a/lib/salmon/magic_sig_envelope.rb b/lib/salmon/magic_sig_envelope.rb index bc15dd78b..d43644b95 100644 --- a/lib/salmon/magic_sig_envelope.rb +++ b/lib/salmon/magic_sig_envelope.rb @@ -10,22 +10,21 @@ module Salmon # @return [MagicSigEnvelope] def self.parse(doc) env = self.new - ns = {'me'=>'http://salmon-protocol.org/ns/magic-env'} - env.encoding = doc.search('//me:env/me:encoding', ns).text.strip + env.encoding = doc.search('//me:env/me:encoding').text.strip if env.encoding != 'base64url' raise ArgumentError, "Magic Signature data must be encoded with base64url, was #{env.encoding}" end - env.data = doc.search('//me:env/me:data', ns).text - env.alg = doc.search('//me:env/me:alg', ns).text.strip + env.data = doc.search('//me:env/me:data').text + env.alg = doc.search('//me:env/me:alg').text.strip unless 'RSA-SHA256' == env.alg raise ArgumentError, "Magic Signature data must be signed with RSA-SHA256, was #{env.alg}" end - env.sig = doc.search('//me:env/me:sig', ns).text - env.data_type = doc.search('//me:env/me:data', ns).first['type'].strip + env.sig = doc.search('//me:env/me:sig').text + env.data_type = doc.search('//me:env/me:data').first['type'].strip env end @@ -54,7 +53,7 @@ module Salmon # @return [String] def to_xml < + #{@data} #{@encoding} #{@alg} diff --git a/lib/salmon/slap.rb b/lib/salmon/slap.rb index 3007188b5..1d67987a6 100644 --- a/lib/salmon/slap.rb +++ b/lib/salmon/slap.rb @@ -4,7 +4,7 @@ module Salmon class Slap - attr_accessor :magic_sig, :author, :author_email, :parsed_data + attr_accessor :magic_sig, :author, :author_id, :parsed_data attr_accessor :aes_key, :iv delegate :sig, :data_type, :to => :magic_sig @@ -29,22 +29,16 @@ module Salmon slap = self.new doc = Nokogiri::XML(xml) - entry_doc = doc.search('entry') + root_doc = doc.search('diaspora') ### Header ## header_doc = slap.salmon_header(doc, receiving_user) - slap.author_email= header_doc.search('uri').text.split("acct:").last + slap.process_header(header_doc) - slap.aes_key = header_doc.search('aes_key').text - slap.iv = header_doc.search('iv').text + ### Envelope ## + slap.magic_sig = MagicSigEnvelope.parse(root_doc) - slap.magic_sig = MagicSigEnvelope.parse(entry_doc) - - - #should be in encrypted salmon only - key_hash = {'key' => slap.aes_key, 'iv' => slap.iv} - - slap.parsed_data = slap.parse_data(key_hash, receiving_user) + slap.parsed_data = slap.parse_data(receiving_user) slap end @@ -54,8 +48,15 @@ module Salmon activity end + # Takes in a doc of the header and sets the author id + # returns an empty hash + # @return [String] Author id + def process_header(doc) + self.author_id = doc.search('author_id').text + end + # @return [String] - def parse_data(key_hash, user=nil) + def parse_data(user=nil) Slap.decode64url(self.magic_sig.data) end @@ -69,10 +70,10 @@ module Salmon def xml_for(person) @xml =< - + #{header(person)} #{@magic_sig.to_xml} - + ENTRY end @@ -86,19 +87,14 @@ ENTRY # @return [String] Header XML (sans
tags) def plaintext_header header =<
#{iv} - #{aes_key} - - #{@author.name} - acct:#{@author.diaspora_handle} - + #{@author.diaspora_handle} HEADER end # @return [Person] Author of the salmon object def author if @author.nil? - @author ||= Person.by_account_identifier @author_email + @author ||= Person.by_account_identifier @author_id raise "did you remember to async webfinger?" if @author.nil? end @author diff --git a/spec/lib/postzord/receiver/private_spec.rb b/spec/lib/postzord/receiver/private_spec.rb index 8399e328b..636b9f220 100644 --- a/spec/lib/postzord/receiver/private_spec.rb +++ b/spec/lib/postzord/receiver/private_spec.rb @@ -36,7 +36,7 @@ describe Postzord::Receiver::Private do salmon_mock = mock() web_mock = mock() web_mock.should_receive(:fetch).and_return true - salmon_mock.should_receive(:author_email).and_return(true) + salmon_mock.should_receive(:author_id).and_return(true) Salmon::EncryptedSlap.should_receive(:from_xml).with(@salmon_xml, @user).and_return(salmon_mock) Webfinger.should_receive(:new).and_return(web_mock) diff --git a/spec/lib/salmon/base64_spec.rb b/spec/lib/salmon/base64_spec.rb new file mode 100644 index 000000000..1fd6bcaf8 --- /dev/null +++ b/spec/lib/salmon/base64_spec.rb @@ -0,0 +1,11 @@ +require 'spec_helper' + +describe Base64 do + describe ".urlsafe_encode64_stripped" do + it "strips the trailing '=' from the url_safe characters" do + pending + Base64.should_receive(:urlsafe_encode64).and_return("MTIzMTIzMQ==") + Base64.urlsafe_encode64_stripped("random stuff").should == "MTIzMTIzMQ" + end + end +end diff --git a/spec/lib/salmon/encrypted_slap_spec.rb b/spec/lib/salmon/encrypted_slap_spec.rb index f76bf6bd9..90ed786a7 100644 --- a/spec/lib/salmon/encrypted_slap_spec.rb +++ b/spec/lib/salmon/encrypted_slap_spec.rb @@ -23,6 +23,25 @@ describe Salmon::EncryptedSlap do end end + describe "#process_header" do + before do + @new_slap = Salmon::EncryptedSlap.new + @new_slap.process_header(Nokogiri::XML(@created_salmon.plaintext_header)) + end + + it 'sets the author id' do + @new_slap.author_id.should == alice.diaspora_handle + end + + it 'sets the aes_key' do + @new_slap.aes_key.should == @created_salmon.aes_key + end + + it 'sets the aes_key' do + @new_slap.iv.should == @created_salmon.iv + end + end + context 'marshalling' do let(:xml) {@created_salmon.xml_for(eve.person)} let(:parsed_salmon) { Salmon::EncryptedSlap.from_xml(xml, alice)} @@ -41,16 +60,33 @@ describe Salmon::EncryptedSlap do end describe '#xml_for' do - let(:xml) {@created_salmon.xml_for eve.person} - - it 'has a encrypted header field' do - xml.include?("encrypted_header").should be true + before do + @xml = @created_salmon.xml_for eve.person end - it 'the encrypted_header field should contain the aes key' do - doc = Nokogiri::XML(xml) - decrypted_header = eve.decrypt(doc.search('encrypted_header').text) - decrypted_header.include?(@created_salmon.aes_key).should be true + it 'has a encrypted header field' do + doc = Nokogiri::XML(@xml) + doc.find("encrypted_header").should_not be_blank + end + + context "encrypted header" do + before do + doc = Nokogiri::XML(@xml) + decrypted_header = eve.decrypt(doc.search('encrypted_header').text) + @dh_doc = Nokogiri::XML(decrypted_header) + end + + it 'contains the aes key' do + @dh_doc.search('aes_key').map(&:text).should == [@created_salmon.aes_key] + end + + it 'contains the initialization vector' do + @dh_doc.search('iv').map(&:text).should == [@created_salmon.iv] + end + + it 'contains the author id' do + @dh_doc.search('author_id').map(&:text).should == [alice.diaspora_handle] + end end end end diff --git a/spec/lib/salmon/slap_spec.rb b/spec/lib/salmon/slap_spec.rb index c1d6cfa85..91d854bda 100644 --- a/spec/lib/salmon/slap_spec.rb +++ b/spec/lib/salmon/slap_spec.rb @@ -24,6 +24,21 @@ describe Salmon::Slap do salmon.parsed_data.should == @post.to_diaspora_xml end + describe '#from_xml' do + it 'procsses the header' do + Salmon::Slap.any_instance.should_receive(:process_header) + Salmon::Slap.from_xml(@created_salmon.xml_for(eve.person)) + end + end + + describe "#process_header" do + it 'sets the author id' do + slap = Salmon::Slap.new + slap.process_header(Nokogiri::XML(@created_salmon.plaintext_header)) + slap.author_id.should == alice.diaspora_handle + end + end + describe '#author' do let(:xml) {@created_salmon.xml_for(eve.person)} let(:parsed_salmon) { Salmon::Slap.from_xml(xml, alice)} @@ -33,7 +48,7 @@ describe Salmon::Slap do end it 'should fail if no author is found' do - parsed_salmon.author_email = 'tom@tom.joindiaspora.com' + parsed_salmon.author_id = 'tom@tom.joindiaspora.com' expect { parsed_salmon.author.public_key }.should raise_error "did you remember to async webfinger?" @@ -45,7 +60,7 @@ describe Salmon::Slap do let(:parsed_salmon) { Salmon::Slap.from_xml(xml)} it 'should parse out the authors diaspora_handle' do - parsed_salmon.author_email.should == alice.person.diaspora_handle + parsed_salmon.author_id.should == alice.person.diaspora_handle end it 'verifies the signature for the sender' do @@ -60,4 +75,36 @@ describe Salmon::Slap do parsed_salmon.parsed_data.should == @post.to_diaspora_xml end end + + describe "#xml_for" do + before do + @xml = @created_salmon.xml_for(eve.person) + end + + it "has diaspora as the root" do + doc = Nokogiri::XML(@xml) + doc.root.name.should == "diaspora" + end + + it "it has the descrypted header" do + doc = Nokogiri::XML(@xml) + doc.search("header").should_not be_blank + end + + context "header" do + + it "it has author_id node " do + doc = Nokogiri::XML(@xml) + search = doc.search("header").search("author_id") + search.map(&:text).should == [alice.diaspora_handle] + end + + end + + it "it has the magic envelope " do + doc = Nokogiri::XML(@xml) + doc.find("/me:env").should_not be_blank + end + end end + From f1a8b1fd6f425557937647770865379689ad897c Mon Sep 17 00:00:00 2001 From: Ilya Zhitomirskiy Date: Thu, 15 Sep 2011 16:35:48 -0700 Subject: [PATCH 8/8] added the namespace constraint back to the envelope, protocol route, data type is now plain xml --- config/routes.rb | 3 +++ lib/salmon/magic_sig_envelope.rb | 13 +++++++------ lib/salmon/slap.rb | 2 +- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/config/routes.rb b/config/routes.rb index 217b17ef6..a86351dce 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -157,6 +157,9 @@ Diaspora::Application.routes.draw do get 'mobile/toggle', :to => 'home#toggle_mobile', :as => 'toggle_mobile' + #Protocol Url + get 'protocol' => redirect("https://github.com/diaspora/diaspora/wiki/Diaspora%27s-federation-protocol") + # Startpage root :to => 'home#show' diff --git a/lib/salmon/magic_sig_envelope.rb b/lib/salmon/magic_sig_envelope.rb index d43644b95..44527513c 100644 --- a/lib/salmon/magic_sig_envelope.rb +++ b/lib/salmon/magic_sig_envelope.rb @@ -10,21 +10,22 @@ module Salmon # @return [MagicSigEnvelope] def self.parse(doc) env = self.new - env.encoding = doc.search('//me:env/me:encoding').text.strip + ns = {'me'=>'http://salmon-protocol.org/ns/magic-env'} + env.encoding = doc.search('//me:env/me:encoding', ns).text.strip if env.encoding != 'base64url' raise ArgumentError, "Magic Signature data must be encoded with base64url, was #{env.encoding}" end - env.data = doc.search('//me:env/me:data').text - env.alg = doc.search('//me:env/me:alg').text.strip + env.data = doc.search('//me:env/me:data', ns).text + env.alg = doc.search('//me:env/me:alg', ns).text.strip unless 'RSA-SHA256' == env.alg raise ArgumentError, "Magic Signature data must be signed with RSA-SHA256, was #{env.alg}" end - env.sig = doc.search('//me:env/me:sig').text - env.data_type = doc.search('//me:env/me:data').first['type'].strip + env.sig = doc.search('//me:env/me:sig', ns).text + env.data_type = doc.search('//me:env/me:data', ns).first['type'].strip env end @@ -69,7 +70,7 @@ ENTRY # @return [String] def get_data_type - 'application/atom+xml' + 'application/xml' end # @return [String] diff --git a/lib/salmon/slap.rb b/lib/salmon/slap.rb index 1d67987a6..61ea14996 100644 --- a/lib/salmon/slap.rb +++ b/lib/salmon/slap.rb @@ -70,7 +70,7 @@ module Salmon def xml_for(person) @xml =< - + #{header(person)} #{@magic_sig.to_xml}