Class: DRM::Unwrapper

Inherits:
Object
  • Object
show all
Defined in:
lib/drm/unwrapper.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(read_proc) ⇒ Unwrapper

new unwrapper for a DRM-wrapped file read_proc(length, offset) reads length bytes at offset from the DRM-wrapped file



4
5
6
7
8
9
10
# File 'lib/drm/unwrapper.rb', line 4

def initialize(read_proc)
  @data_offset = [0].pack('N').length
   = read_proc.call @data_offset, 0
   = read_proc.call .unpack('N').first, @data_offset
  @data_offset += .length
  @metadata = DRM::Metadata.new_from_yaml_str 
end

Instance Attribute Details

#metadataObject (readonly)

the DRM metadata for the wrapped file



13
14
15
# File 'lib/drm/unwrapper.rb', line 13

def 
  @metadata
end

Instance Method Details

#unwrap(start_byte, end_byte, read_proc, write_proc, subkey_proc) ⇒ Object

unwraps bytes start_byte..+end_byte+ from the content of a DRM-wrapped file read_proc(length, offset) reads length bytes at offset from the file to be wrapped write_proc(data) appends the given data to the file containing the wrapped content subkey_proc(metadata, index) produces the +index+th DRM subkey for the contents identified by metadata



19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/drm/unwrapper.rb', line 19

def unwrap(start_byte, end_byte, read_proc, write_proc, subkey_proc)
  block_size = @metadata.block_size
  start_block = start_byte / block_size
  end_block = end_byte / block_size

  in_offset = @data_offset + start_block * block_size
  old_ski = nil
  subkey = nil
  start_block.upto(end_block) do |block_index|
    # read
    crypted_data = read_proc.call block_size, in_offset
    in_offset += crypted_data.length
    # decrypt
    ski = @metadata.subkey_index(block_index)
    subkey = subkey_proc.call @metadata, ski unless ski == old_ski
    old_ski = ski
    block_data = @metadata.decrypt_block crypted_data, block_index, subkey
    # write
    write_proc.call block_data[((block_index == start_block) ? start_byte % block_size : 0)..((block_index == end_block) ? end_byte % block_size : block_size - 1)]
  end
end