class Kdbx::Header
Constants
- FILEMAGIC
Public Class Methods
load(file)
click to toggle source
# File lib/kdbx/header.rb, line 7 def self.load(file) if file.readpartial(12) != FILEMAGIC fail ParseError, "bad magic number" end fields = {} loop do (id, sz) = file.readpartial(3).unpack("CS<") fields[id] = file.readpartial sz break if id == 0 end new fields rescue TypeError, EOFError fail ParseError, "truncated header" end
new(fields = {})
click to toggle source
# File lib/kdbx/header.rb, line 25 def initialize(fields = {}) @fields = fields validate end
Public Instance Methods
dump()
click to toggle source
# File lib/kdbx/header.rb, line 30 def dump merge_defaults and validate StringIO.new.binmode.tap do |io| io.write FILEMAGIC @fields.each do |k, v| io.write [k, v.bytesize].pack("CS<") + v if k != 0 end io.write [0, @fields[0].bytesize].pack("CS<") + @fields[0] end.string end
validate()
click to toggle source
# File lib/kdbx/header.rb, line 41 def validate @fields.each do |k, v| fail FormatError, "header #{k.inspect}: #{v}" unless k.is_a? Integer fail FormatError, "header #{k}: #{v.inspect}" unless v.is_a? String @fields[k] = v = v.b unless v.encoding == Encoding::ASCII_8BIT case k when 2 if v != "\x31\xC1\xF2\xE6\xBF\x71\x43\x50\xBE\x58\x05\x21\x6A\xFC\x5A\xFF".b fail FormatError, "header #{k}: #{v.inspect}" end when 3 if v.bytesize != 4 || !(0..1).include?(v.unpack("L").first) fail FormatError, "header #{k}: #{v.inspect}" end when 4, 5 fail FormatError, "header #{k}: #{v.inspect}" if v.bytesize != 32 when 6 fail FormatError, "header #{k}: #{v.inspect}" if v.bytesize != 8 when 7 fail FormatError, "header #{k}: #{v.inspect}" if v.bytesize != 16 when 8 if @fields[10] == "\x02\x00\x00\x00".b && v.bytesize != 32 fail FormatError, "header #{k}: #{v.inspect}" end when 10 fail FormatError, "header #{k}: #{v.inspect}" if v.bytesize != 4 if (n = v.unpack("L<").first) != 0 && n != 2 fail FormatError, "header #{k}: #{v.inspect}" end end end end
Private Instance Methods
merge_defaults()
click to toggle source
# File lib/kdbx/header.rb, line 76 def merge_defaults @fields.merge!({ 0 => "\x00\xD0\xAD\x0A", 2 => "\x31\xC1\xF2\xE6\xBF\x71\x43\x50\xBE\x58\x05\x21\x6A\xFC\x5A\xFF", 3 => "\x01\x00\x00\x00", 4 => OpenSSL::Random.random_bytes(32), 5 => OpenSSL::Random.random_bytes(32), 6 => "\x70\x17\x00\x00\x00\x00\x00\x00", 7 => OpenSSL::Random.random_bytes(16), 8 => OpenSSL::Random.random_bytes(32), 9 => OpenSSL::Random.random_bytes(32), 10 => "\x02\x00\x00\x00" }) { |_k, v1, _v2| v1 } true end