lib/rmega/nodes/node.rb in rmega-0.1.5 vs lib/rmega/nodes/node.rb in rmega-0.1.6

- old
+ new

@@ -9,20 +9,20 @@ include Loggable include Traversable attr_reader :data, :session - delegate :storage, :request, :to => :session + delegate :storage, :request, :shared_keys, :rsa_privk, :to => :session def initialize(session, data) @session = session @data = data end def public_url @public_url ||= begin - b64_dec_key = Utils.a32_to_base64 decrypted_file_key[0..7] + b64_dec_key = Utils.a32_to_base64(decrypted_file_key[0..7]) "https://mega.co.nz/#!#{public_handle}!#{b64_dec_key}" end end def public_url=(url) @@ -39,38 +39,68 @@ def parent_handle data['p'] end - def owner_key - data['k'].split(':').first + def name + attributes['n'] if attributes end - def name - return attributes['n'] if attributes + def file_keys + return {} unless data['k'] + + pairs = data['k'].split('/') + pairs.inject({}) do |hash, pair| + h, k = pair.split(':') + hash[h] = k + hash + end end def file_key - data['k'].split(':').last + file_keys.values.first end - def decrypted_file_key - if data['k'] - Crypto.decrypt_key session.master_key, Utils.base64_to_a32(file_key) + def shared_root? + data['su'] && data['sk'] && data['k'] + end + + def process_shared_key + h = (shared_keys.keys & file_keys.keys).first + return [h, shared_keys[h]] if h + + sk = data['sk'] + + return unless sk + + shared_key = if sk.size > 22 + sk = Rmega::Utils.mpi2b(Rmega::Utils.base64urldecode(sk)) + dec_sk = Rmega::Crypto::Rsa.decrypt(sk, rsa_privk) + Utils.str_to_a32(Rmega::Utils.b2s(dec_sk)[0..15]) else - Utils.base64_to_a32 public_url.split('!').last + Crypto.decrypt_key session.master_key, Utils.base64_to_a32(data['sk']) end + + shared_keys[handle] = shared_key + [handle, shared_key] end - def can_decrypt_attributes? - !data['u'] or data['u'] == owner_key + def decrypted_file_key + h, shared_key = *process_shared_key + + if shared_key + Crypto.decrypt_key(shared_key, Utils.base64_to_a32(file_keys[h])) + elsif file_key + Crypto.decrypt_key(session.master_key, Utils.base64_to_a32(file_key)) + else + Utils.base64_to_a32(public_url.split('!').last) + end end def attributes - @attributes ||= begin - return nil unless can_decrypt_attributes? - Crypto.decrypt_attributes decrypted_file_key, (data['a'] || data['at']) - end + encrypted = data['a'] || data['at'] + return if !encrypted or encrypted.empty? + Crypto.decrypt_attributes(decrypted_file_key, encrypted) end def type Factory.type(data['t']) end