Class: Omnizip::Formats::SevenZip::EncryptedHeader

Inherits:
Object
  • Object
show all
Includes:
Constants
Defined in:
lib/omnizip/formats/seven_zip/encrypted_header.rb

Overview

Encrypted header model for .7z archives Stores metadata for header encryption

Constant Summary

Constants included from Constants

Constants::MAJOR_VERSION, Constants::MAX_NUM_BONDS, Constants::MAX_NUM_CODERS, Constants::MAX_NUM_PACK_STREAMS, Constants::MINOR_VERSION, Constants::SIGNATURE, Constants::SIGNATURE_SIZE, Constants::START_HEADER_SIZE

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(encrypted_data: nil, salt: nil, iv: nil, original_size: 0, crc: nil) ⇒ EncryptedHeader

Initialize encrypted header

Parameters:

  • encrypted_data (String) (defaults to: nil)

    Encrypted header bytes

  • salt (String) (defaults to: nil)

    PBKDF2 salt

  • iv (String) (defaults to: nil)

    AES initialization vector

  • original_size (Integer) (defaults to: 0)

    Size before encryption

  • crc (Integer, nil) (defaults to: nil)

    CRC32 of encrypted data (optional)



20
21
22
23
24
25
26
27
# File 'lib/omnizip/formats/seven_zip/encrypted_header.rb', line 20

def initialize(encrypted_data: nil, salt: nil, iv: nil,
               original_size: 0, crc: nil)
  @encrypted_data = encrypted_data
  @salt = salt
  @iv = iv
  @original_size = original_size
  @crc = crc
end

Instance Attribute Details

#crcObject

Returns the value of attribute crc.



11
12
13
# File 'lib/omnizip/formats/seven_zip/encrypted_header.rb', line 11

def crc
  @crc
end

#encrypted_dataObject

Returns the value of attribute encrypted_data.



11
12
13
# File 'lib/omnizip/formats/seven_zip/encrypted_header.rb', line 11

def encrypted_data
  @encrypted_data
end

#ivObject

Returns the value of attribute iv.



11
12
13
# File 'lib/omnizip/formats/seven_zip/encrypted_header.rb', line 11

def iv
  @iv
end

#original_sizeObject

Returns the value of attribute original_size.



11
12
13
# File 'lib/omnizip/formats/seven_zip/encrypted_header.rb', line 11

def original_size
  @original_size
end

#saltObject

Returns the value of attribute salt.



11
12
13
# File 'lib/omnizip/formats/seven_zip/encrypted_header.rb', line 11

def salt
  @salt
end

Class Method Details

.from_binary(data) ⇒ EncryptedHeader

Parse encrypted header from binary data

Parameters:

  • data (String)

    Binary data

Returns:

Raises:

  • (RuntimeError)

    if data is invalid



71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
# File 'lib/omnizip/formats/seven_zip/encrypted_header.rb', line 71

def self.from_binary(data)
  raise "Invalid encrypted header: too short" if data.bytesize < 54

  pos = 0

  # Check marker
  marker = data.getbyte(pos)
  pos += 1
  unless marker == PropertyId::ENCODED_HEADER
    raise "Invalid encrypted header marker: expected #{PropertyId::ENCODED_HEADER}, got #{marker}"
  end

  # Read encrypted data size
  encrypted_size = data[pos, 8].unpack1("Q<")
  pos += 8

  # Read salt
  salt = data[pos, 16]
  pos += 16

  # Read IV
  iv = data[pos, 16]
  pos += 16

  # Read original size
  original_size = data[pos, 8].unpack1("Q<")
  pos += 8

  # Read CRC
  crc = data[pos, 4].unpack1("V")
  pos += 4

  # Read encrypted data
  encrypted_data = data[pos, encrypted_size]

  new(
    encrypted_data: encrypted_data,
    salt: salt,
    iv: iv,
    original_size: original_size,
    crc: crc.zero? ? nil : crc,
  )
end

Instance Method Details

#to_binaryString

Serialize encrypted header to binary format

Format:

- 1 byte: PropertyId::ENCODED_HEADER marker
- 8 bytes: Encrypted data size (little-endian)
- 16 bytes: Salt
- 16 bytes: IV
- 8 bytes: Original size (little-endian)
- 4 bytes: CRC32 (optional, 0 if not set)
- N bytes: Encrypted data

Returns:

  • (String)

    Binary representation



41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/omnizip/formats/seven_zip/encrypted_header.rb', line 41

def to_binary
  data = String.new(encoding: "BINARY")

  # Marker for encoded header
  data << [PropertyId::ENCODED_HEADER].pack("C")

  # Encrypted data size
  data << [@encrypted_data.bytesize].pack("Q<")

  # Encryption parameters
  data << @salt
  data << @iv

  # Original size
  data << [@original_size].pack("Q<")

  # CRC (0 if not set)
  data << [crc || 0].pack("V")

  # Encrypted data
  data << @encrypted_data

  data
end

#valid?Boolean

Check if header is valid

Returns:

  • (Boolean)

    true if has all required fields



118
119
120
121
122
123
124
# File 'lib/omnizip/formats/seven_zip/encrypted_header.rb', line 118

def valid?
  !@encrypted_data.nil? &&
    !@salt.nil? &&
    !@iv.nil? &&
    @original_size.positive? &&
    @encrypted_data.bytesize.positive?
end

#verify_crcBoolean

Verify CRC if set

Returns:

  • (Boolean)

    true if CRC matches or not set



129
130
131
132
133
134
135
# File 'lib/omnizip/formats/seven_zip/encrypted_header.rb', line 129

def verify_crc
  return true if @crc.nil?

  calc_crc = Omnizip::Checksums::Crc32.new
  calc_crc.update(@encrypted_data)
  calc_crc.value == @crc
end