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