Class: Megar::FileDownloader
- Inherits:
-
Object
- Object
- Megar::FileDownloader
- Includes:
- Crypto::Support
- Defined in:
- lib/megar/adapters/file_downloader.rb
Overview
Encapsulates a file download task. This is intended as a one-shot helper.
Javascript reference implementation: function startdownload2(res,ctx)
Instance Attribute Summary collapse
-
#file ⇒ Object
readonly
Returns the value of attribute file.
-
#session ⇒ Object
readonly
Returns the value of attribute session.
Instance Method Summary collapse
- #chunk_mac_iv ⇒ Object
-
#content ⇒ Object
Returns the complete decrypted content.
-
#decomposed_key ⇒ Object
Returns the file key (shortcut).
-
#download_attributes ⇒ Object
Returns the decrypted download attributes.
-
#download_size ⇒ Object
Returns a download size for the file content.
-
#download_url ⇒ Object
Returns a download url for the file content.
-
#download_url_response ⇒ Object
Returns and caches a file download response.
-
#initial_counter_value ⇒ Object
Returns the initial value for AES counter.
-
#initialize(options = {}) ⇒ FileDownloader
constructor
A new instance of FileDownloader.
-
#iv ⇒ Object
Returns the initialisation vector.
-
#key ⇒ Object
Returns the file key (shortcut).
-
#mac ⇒ Object
Returns the expected MAC for the file.
-
#raw_content ⇒ Object
Returns the complete encrypted content (mainly for testing purposes).
-
#stream ⇒ Object
Returns an io stream to the file content.
Methods included from Crypto::Support
#a32_to_base64, #a32_to_str, #accumulate_mac, #aes_cbc_decrypt, #aes_cbc_decrypt_a32, #aes_cbc_encrypt, #aes_cbc_encrypt_a32, #aes_encrypt_a32, #base64_mpi_to_a32, #base64_mpi_to_bn, #base64_to_a32, #base64urldecode, #base64urlencode, #calculate_chunk_mac, #crypto_requirements_met?, #decompose_file_key, #decompose_rsa_private_key, #decompose_rsa_private_key_a32, #decrypt_base64_to_a32, #decrypt_base64_to_str, #decrypt_file_attributes, #decrypt_file_key, #decrypt_key, #decrypt_session_id, #encrypt_file_attributes, #encrypt_key, #get_chunks, #get_file_cipher, #hexstr_to_bstr, #mpi_to_a32, #openssl_rsa_cipher, #openssl_rsa_decrypt, #prepare_key, #prepare_key_pw, #rsa_decrypt, #str_to_a32, #stringhash
Constructor Details
#initialize(options = {}) ⇒ FileDownloader
Returns a new instance of FileDownloader.
13 14 15 16 |
# File 'lib/megar/adapters/file_downloader.rb', line 13 def initialize(={}) @file = [:file] @session = @file && @file.session end |
Instance Attribute Details
#file ⇒ Object (readonly)
Returns the value of attribute file.
11 12 13 |
# File 'lib/megar/adapters/file_downloader.rb', line 11 def file @file end |
#session ⇒ Object (readonly)
Returns the value of attribute session.
10 11 12 |
# File 'lib/megar/adapters/file_downloader.rb', line 10 def session @session end |
Instance Method Details
#chunk_mac_iv ⇒ Object
76 77 78 |
# File 'lib/megar/adapters/file_downloader.rb', line 76 def chunk_mac_iv [iv[0], iv[1], iv[0], iv[1]] end |
#content ⇒ Object
Returns the complete decrypted content. If anything goes wrong here, it’s going to bubble up an unhandled error.
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
# File 'lib/megar/adapters/file_downloader.rb', line 29 def content return unless live_session? decoded_content = '' calculated_mac = [0, 0, 0, 0] decryptor = get_file_cipher(decomposed_key,iv) get_chunks(download_size).each do |chunk_start, chunk_size| chunk = stream.readpartial(chunk_size) decoded_chunk = decryptor.update(chunk) decoded_content << decoded_chunk calculated_mac = accumulate_mac(decoded_chunk,calculated_mac,decomposed_key,chunk_mac_iv) end raise Megar::MacVerificationError.new unless ([calculated_mac[0] ^ calculated_mac[1], calculated_mac[2] ^ calculated_mac[3]] == mac) decoded_content end |
#decomposed_key ⇒ Object
Returns the file key (shortcut)
91 92 93 |
# File 'lib/megar/adapters/file_downloader.rb', line 91 def decomposed_key file.decomposed_key end |
#download_attributes ⇒ Object
Returns the decrypted download attributes
65 66 67 68 69 |
# File 'lib/megar/adapters/file_downloader.rb', line 65 def download_attributes if attributes = download_url_response['at'] decrypt_file_attributes(attributes,decomposed_key) end end |
#download_size ⇒ Object
Returns a download size for the file content
60 61 62 |
# File 'lib/megar/adapters/file_downloader.rb', line 60 def download_size download_url_response['s'] end |
#download_url ⇒ Object
Returns a download url for the file content
55 56 57 |
# File 'lib/megar/adapters/file_downloader.rb', line 55 def download_url download_url_response['g'] end |
#download_url_response ⇒ Object
Returns and caches a file download response
101 102 103 104 105 106 107 |
# File 'lib/megar/adapters/file_downloader.rb', line 101 def download_url_response @download_url_response ||= if live_session? session.get_file_download_url_response(file.id) else {} end end |
#initial_counter_value ⇒ Object
Returns the initial value for AES counter
96 97 98 |
# File 'lib/megar/adapters/file_downloader.rb', line 96 def initial_counter_value ((iv[0] << 32) + iv[1]) << 64 end |
#iv ⇒ Object
Returns the initialisation vector
72 73 74 |
# File 'lib/megar/adapters/file_downloader.rb', line 72 def iv @iv ||= key[4,2] + [0, 0] end |
#key ⇒ Object
Returns the file key (shortcut)
86 87 88 |
# File 'lib/megar/adapters/file_downloader.rb', line 86 def key file.key end |
#mac ⇒ Object
Returns the expected MAC for the file
81 82 83 |
# File 'lib/megar/adapters/file_downloader.rb', line 81 def mac key[6,2] end |
#raw_content ⇒ Object
Returns the complete encrypted content (mainly for testing purposes)
49 50 51 52 |
# File 'lib/megar/adapters/file_downloader.rb', line 49 def raw_content return unless live_session? stream.read end |
#stream ⇒ Object
Returns an io stream to the file content
19 20 21 22 23 24 |
# File 'lib/megar/adapters/file_downloader.rb', line 19 def stream return unless live_session? @stream ||= if url = download_url open(url) end end |