diff options
| author | Randy Morgan <[email protected]> | 2012-06-20 08:21:06 +0900 |
|---|---|---|
| committer | Randy Morgan <[email protected]> | 2012-06-20 08:21:06 +0900 |
| commit | 53235912acc99ef8801e43edf3fccfa2dced3d3e (patch) | |
| tree | 5534d319259a40b1404f19a2b1c8de8252a329b0 /lib/axlsx/util/cbf.rb | |
| parent | 16a7fd2450581353efc9ec0daf267b28ea87fe02 (diff) | |
| download | caxlsx-53235912acc99ef8801e43edf3fccfa2dced3d3e.tar.gz caxlsx-53235912acc99ef8801e43edf3fccfa2dced3d3e.zip | |
remove crypto play
Diffstat (limited to 'lib/axlsx/util/cbf.rb')
| -rw-r--r-- | lib/axlsx/util/cbf.rb | 333 |
1 files changed, 0 insertions, 333 deletions
diff --git a/lib/axlsx/util/cbf.rb b/lib/axlsx/util/cbf.rb deleted file mode 100644 index f8fc057b..00000000 --- a/lib/axlsx/util/cbf.rb +++ /dev/null @@ -1,333 +0,0 @@ -# encoding: UTF-8 -module Axlsx - - # The Cfb class is a MS-OFF-CRYPTOGRAPHY specific OLE (MS-CBF) writer implementation. No attempt is made to re-invent the wheel for read/write of compound binary files. - class Cbf - - # the serialization for the CBF FAT - FAT_PACKING = "s128" - - # the serialization for the MS-OFF-CRYPTO version stream - VERSION_PACKING = 'l s30 l3' - - # The serialization for the MS-OFF-CRYPTO dataspace map stream - DATA_SPACE_MAP_PACKING = 'l6 s16 l s25 x2' - - # The serialization for the MS-OFF-CRYPTO strong encrytion data space stream - STRONG_ENCRYPTION_DATA_SPACE_PACKING = 'l3 s26' - - # The serialization for the MS-OFF-CRYPTO primary stream - PRIMARY_PACKING = 'l3 s38 l s40 l3 x12 l' - - # The cutoff size that determines if a stream should be in the mini-fat or the fat - MINI_CUTOFF = 4096 - - # The serialization for CBF header - HEADER_PACKING = "q x16 l s3 x10 l l x4 l*" - - # Creates a new Cbf object based on the ms_off_crypto object provided. - # @param [MsOffCrypto] ms_off_crypto - def initialize(ms_off_crypto) - @file_name = ms_off_crypto.file_name - @ms_off_crypto = ms_off_crypto - create_storages - mini_fat_stream - mini_fat - fat - header - end - - # creates or returns the version storage - # @return [Storage] - def version - @version ||= create_version - end - - # returns the data space map storage - # @return [Storage] - def data_space_map - @data_space_map ||= create_data_space_map - end - - # returns the primary storage - # @return [Storgae] - def primary - @primary ||= create_primary - end - - # returns the summary information storage - # @return [Storage] - def summary_information - @summary_information ||= create_summary_information - end - - # returns the document summary information - # @return [Storage] - def document_summary_information - @document_summary_information ||= create_document_summary_information - end - - # returns the stream of data allocated in the fat - # @return [String] - def fat_stream - @fat_stream ||= create_fat_stream - end - - # returns the stream allocated in the mini fat. - # return [String] - def mini_fat_stream - @mini_fat_stream ||= create_mini_fat_stream - end - - # returns the mini fat - # return [String] - def mini_fat - @mini_fat ||= create_mini_fat - end - - # returns the fat - # @return [String] - def fat - @fat ||= create_fat - end - - # returns the CFB header - # @return [String] - def header - @header ||= create_header - end - - # returns the encryption info from the ms_off_crypt object provided during intialization - # @return [String] encryption info - def encryption_info - @ms_off_crypto.encryption_info - end - - # returns the encrypted package from the ms_off_crypt object provided during initalization - # @return [String] encrypted package - def encrypted_package - @ms_off_crypto.encrypted_package - end - - # writes the compound binary file to disk - def save - ole = File.open(@file_name, 'w') - ole << header - ole << fat - @storages.each { |s| ole << s.to_s } - ole << Array.new((512-(ole.pos % 512)), 0).pack('c*') - ole << mini_fat - ole << mini_fat_stream - ole << fat_stream - ole.close - end - - private - - # Generates the storages required for ms-office-cryptography cfb - def create_storages - @storages = [] - @encryption_info = @ms_off_crypto.encryption_info - @encrypted_package = @ms_off_crypto.encrypted_package - - @storages << Storage.new('EncryptionInfo', :data=>encryption_info, :left=>3, :right=>11) # example shows right child. do we need the summary info???? - @storages << Storage.new('EncryptedPackage', :data=>encrypted_package, :color=>Storage::COLORS[:red]) - @storages << Storage.new([6].pack("c")+"DataSpaces", :child=>5, :modified =>129685612740945580, :created=>129685612740819979) - @storages << version - @storages << data_space_map - @storages << Storage.new('DataSpaceInfo', :right=>8, :child=>7, :created=>129685612740828880,:modified=>129685612740831800) - @storages << strong_encryption_data_space - @storages << Storage.new('TransformInfo', :color => Storage::COLORS[:red], :child=>9, :created=>129685612740834130, :modified=>129685612740943959) - @storages << Storage.new('StrongEncryptionTransform', :child=>10, :created=>129685612740834169, :modified=>129685612740942280) - @storages << primary - # @storages << summary_information - # @storages << document_summary_information - - # we do this at the end as we need to build the minifat stream to determine the size. #HOWEVER - it looks like the size should not include the padding? - @storages.unshift Storage.new('Root Entry', :type=>Storage::TYPES[:root], :color=>Storage::COLORS[:red], :child=>1, :data => mini_fat_stream) - - end - - # generates the mini fat stream - # @return [String] - def create_mini_fat_stream - mfs = [] - @storages.select{ |s| s.type == Storage::TYPES[:stream] && s.size < MINI_CUTOFF}.each_with_index do |stream, index| - puts "#{stream.name.pack('c*')}: #{stream.data.size}" - mfs.concat stream.data - mfs.concat Array.new(64 - (mfs.size % 64), 0) if mfs.size % 64 > 0 - puts "mini fat stream size: #{mfs.size}" - end - mfs.concat(Array.new(512 - (mfs.size % 512), 0)) - mfs.pack 'c*' - end - - # generates the fat stream. - # @return [String] - def create_fat_stream - mfs = [] - @storages.select{ |s| s.type == Storage::TYPES[:stream] && s.size >= MINI_CUTOFF}.each_with_index do |stream, index| - mfs.concat stream.data - mfs.concat Array.new(512 - (mfs.size % 512), 0) if mfs.size % 512 > 0 - end - mfs.pack 'c*' - end - - # creates the mini fat - # @return [String] - def create_mini_fat - v_mf = [] - @storages.select{ |s| s.type == Storage::TYPES[:stream] && s.size < MINI_CUTOFF}.each do |stream| - allocate_stream(v_mf, stream, 64) - end - v_mf.concat Array.new(128 - v_mf.size, -1) - v_mf.pack 'l*' - end - - # creates the fat - # @return [String] - def create_fat - v_fat = [-3] - # storages four per sector, allocation forces directories to start at sector ID 0 - allocate_stream(v_fat, @storages, 4) - # fat entry for minifat - allocate_stream(v_fat, 0, 512) - # fat entry for minifat stream - @storages[0].sector = v_fat.size - allocate_stream(v_fat, mini_fat_stream, 512) - # fat entries for encrypted package storage - # what to do about DIFAT for larger packages... - if @encrypted_package.size > (109 - v_fat.size) * 512 - raise ArgumentError, "Your package is too big!" - end - - if @encrypted_package.size >= MINI_CUTOFF - allocate_stream(v_fat, @encrypted_package, 512) - end - - v_fat.concat Array.new(128 - v_fat.size, -1) if v_fat.size < 128 #pack in unused sectors - v_fat.pack 'l*' - end - - # Creates the version storage - # @return [Storage] - def create_version - v_stream= [60, "Microsoft.Container.DataSpaces".bytes.to_a, 1, 1, 1].flatten!.pack VERSION_PACKING - Storage.new('Version', :data=>v_stream, :size=>v_stream.size) - end - - # returns the strong encryption data space storage - # @return [Storgae] - def strong_encryption_data_space - @strong_encryption_data_space ||= create_strong_encryption_data_space - end - - # Creates the data space map storage - # @return [Storgae] - def create_data_space_map - v_stream = [8,1,104, 1,0, 32, "EncryptedPackage".bytes.to_a, 50, "StrongEncryptionDataSpace".bytes.to_a].flatten!.pack DATA_SPACE_MAP_PACKING - Storage.new('DataSpaceMap', :data=>v_stream, :left => 4, :right => 6, :size=>v_stream.size) - end - - - # creates the stron encryption data space storage - # @return [Storgae] - def create_strong_encryption_data_space - v_stream = [8,1,50,"StrongEncryptionTransform".bytes.to_a,0].flatten.pack STRONG_ENCRYPTION_DATA_SPACE_PACKING - Storage.new("StrongEncryptionDataSpace", :data=>v_stream, :size => v_stream.size) - end - - # creates the primary storage - # @return [Storgae] - def create_primary - v_stream = [88,1,76,"{FF9A3F03-56EF-4613-BDD5-5A41C1D07246}".bytes.to_a].flatten - v_stream.concat [78, "Microsoft.Container.EncryptionTransform".bytes.to_a,0,1,1,1,4].flatten - v_stream = v_stream.pack PRIMARY_PACKING - Storage.new([6].pack("c")+"Primary", :data=>v_stream) - end - - - # creates the summary information storage - # @return [Storage] - def create_summary_information - v_stream = [] - v_stream.concat [0xFEFF, 0x0000, 0x030A, 0x0100, 0x0000, 0x0000, 0x0000, 0x0000] - v_stream.concat [0x0000, 0x0000, 0x0000, 0x0000, 0x0100, 0x0000, 0xE085, 0x9FF2] - v_stream.concat [0xF94F, 0x6810, 0xAB91, 0x0800, 0x2B27, 0xB3D9, 0x3000, 0x0000] - v_stream.concat [0xAC00, 0x0000, 0x0700, 0x0000, 0x0100, 0x0000, 0x4000, 0x0000] - v_stream.concat [0x0400, 0x0000, 0x4800, 0x0000, 0x0800, 0x0000, 0x5800, 0x0000] - v_stream.concat [0x1200, 0x0000, 0x6800, 0x0000, 0x0C00, 0x0000, 0x8C00, 0x0000] - v_stream.concat [0x0D00, 0x0000, 0x9800, 0x0000, 0x1300, 0x0000, 0xA400, 0x0000] - v_stream.concat [0x0200, 0x0000, 0xE9FD, 0x0000, 0x1E00, 0x0000, 0x0800, 0x0000] - v_stream.concat [0x7261, 0x6E64, 0x796D, 0x0000, 0x1E00, 0x0000, 0x0800, 0x0000] - v_stream.concat [0x7261, 0x6E64, 0x796D, 0x0000, 0x1E00, 0x0000, 0x1C00, 0x0000] - v_stream.concat [0x4D69, 0x6372, 0x6F73, 0x6F66, 0x7420, 0x4D61, 0x6369, 0x6E74] - v_stream.concat [0x6F73, 0x6820, 0x4578, 0x6365, 0x6C00, 0x0000, 0x4000, 0x0000] - v_stream.concat [0x10AC, 0x5396, 0x60BC, 0xCC01, 0x4000, 0x0000, 0x40F4, 0xFDAF] - v_stream.concat [0x60BC, 0xCC01, 0x0300, 0x0000, 0x0100, 0x0000] - - v_stream = v_stream.pack "s*" - - Storage.new([5].pack('c')+"SummaryInformation", :data=>v_stream, :left => 2) - end - - - # creates the document summary information storage - # @return [Storage] - def create_document_summary_information - v_stream = [] - v_stream.concat [0xFEFF, 0x0000, 0x030A, 0x0100, 0x0000, 0x0000, 0x0000, 0x0000] - v_stream.concat [0x0000, 0x0000, 0x0000, 0x0000, 0x0100, 0x0000, 0x02D5, 0xCDD5] - v_stream.concat [0x9C2E, 0x1B10, 0x9397, 0x0800, 0x2B2C, 0xF9AE, 0x3000, 0x0000] - v_stream.concat [0xCC00, 0x0000, 0x0900, 0x0000, 0x0100, 0x0000, 0x5000, 0x0000] - v_stream.concat [0x0F00, 0x0000, 0x5800, 0x0000, 0x1700, 0x0000, 0x6400, 0x0000] - v_stream.concat [0x0B00, 0x0000, 0x6C00, 0x0000, 0x1000, 0x0000, 0x7400, 0x0000] - v_stream.concat [0x1300, 0x0000, 0x7C00, 0x0000, 0x1600, 0x0000, 0x8400, 0x0000] - v_stream.concat [0x0D00, 0x0000, 0x8C00, 0x0000, 0x0C00, 0x0000, 0x9F00, 0x0000] - v_stream.concat [0x0200, 0x0000, 0xE9FD, 0x0000, 0x1E00, 0x0000, 0x0400, 0x0000] - v_stream.concat [0x0000, 0x0000, 0x0300, 0x0000, 0x0000, 0x0C00, 0x0B00, 0x0000] - v_stream.concat [0x0000, 0x0000, 0x0B00, 0x0000, 0x0000, 0x0000, 0x0B00, 0x0000] - v_stream.concat [0x0000, 0x0000, 0x0B00, 0x0000, 0x0000, 0x0000, 0x1E10, 0x0000] - v_stream.concat [0x0100, 0x0000, 0x0700, 0x0000, 0x5368, 0x6565, 0x7431, 0x000C] - v_stream.concat [0x1000, 0x0002, 0x0000, 0x001E, 0x0000, 0x0013, 0x0000, 0x00E3] - v_stream.concat [0x83AF, 0xE383, 0xBCE3, 0x82AF, 0xE382, 0xB7E3, 0x83BC, 0xE383] - v_stream.concat [0x8800, 0x0300, 0x0000, 0x0100, 0x0000, 0x0000] - v_stream = v_stream.pack 'c*' - Storage.new([5].pack('c')+"DocumentSummaryInformation", :data=>v_stream) - end - - # Creates the header - # @return [String] - def create_header - header = [] - header << -2226271756974174256 # identifier pack as q - header << 196670 # version pack as L - header << 65534 # byte order pack as s - header << 9 # sector shift - header << 6 # mini-sector shift - header << (fat.size/512.0).ceil # this is the number of FAT sectors in the file at index 6 pack as L - header << header.last # this is the first directory sector, index of 7 pack as L - header << MINI_CUTOFF # minfat cutoff pack as L - # MiniFat starts after directories - header << (fat.size/512.0).ceil + (@storages.size/4.0).ceil # this is the sector id for the first minifat index 10 pack as L - header << (mini_fat.size/512.0).ceil # minifat sector count index 11 pack as L - header << -2 # the first DIFAT - set to end of chain until we exceed a single FAT pack as L - header << 0 # number of DIFAT sectors, unless we go beyond 109 FAT sectors this will always be 0 pack as L - header << 0 # first FAT sector defined in the DIFAT pack as L - header.concat Array.new(108, -1) # Difat sectors pack as L108 - header.pack(HEADER_PACKING) - end - - # Allocates sector chains in a allocation table based on the sector size and stream provided - # If a storage obeject is provided, the starting sector value for the storage is updated based on the allocation performed here. - # @param [Array] table Allocation table array - # @param [Storage | String] stream - # @param [Integer] size The cutoff size for the stream. - def allocate_stream(table, stream, size) - stream.sector = table.size if stream.respond_to?(:sector) - ((stream.size / size.to_f).ceil).times { table << table.size } - table[table.size-1] = -2 # this is the CBF chain terminator - end - - end -end |
