class Capsium::Package::Security
Loads, generates and verifies security.json (ARCHITECTURE.md section 6). Checksums cover every file in the package except security.json itself and signature.sig (the signature signs the checksum-covered payload, so it cannot be part of it).
Constants
- ChecksumMismatch
- MissingFile
- UncheckedFile
Attributes
path
[R]
String
Public Class Methods
(String package_path) → Hash[String, String]
Source
# File lib/capsium/package/security.rb, line 56 def self.checksums_for(package_path) package_files(package_path).sort.to_h do |relative_path| [relative_path, Digest::SHA256.file(File.join(package_path, relative_path)).hexdigest] end end
(String relative_path) → bool
Source
# File lib/capsium/package/security.rb, line 70 def self.excluded?(relative_path) [SECURITY_FILE, SIGNATURE_FILE].include?(relative_path) end
(String package_path, ?digital_signatures: DigitalSignatures? digital_signatures) → Security
Source
# File lib/capsium/package/security.rb, line 43 def self.generate(package_path, digital_signatures: nil) config = SecurityConfig.new( security: SecurityData.new( integrity_checks: IntegrityChecks.new( checksum_algorithm: "SHA-256", checksums: checksums_for(package_path) ), digital_signatures: digital_signatures ) ) new(File.join(package_path, SECURITY_FILE), config) end
(String path, ?SecurityConfig? config) → void
Source
# File lib/capsium/package/security.rb, line 38 def initialize(path, config = nil) @path = path @config = config || load_config end
(String package_path) → Array[String]
Source
# File lib/capsium/package/security.rb, line 62 def self.package_files(package_path) files = Dir.glob(File.join(package_path, "**", "*")).select do |file| File.file?(file) end files.map { |file| file.delete_prefix("#{package_path}/") } .reject { |relative_path| excluded?(relative_path) } end
Public Instance Methods
() → Hash[String, String]
Source
# File lib/capsium/package/security.rb, line 89 def checksums present? ? config.checksums : {} end
Source
# File lib/capsium/package/security.rb, line 79 def digital_signatures return unless present? && config.security config.security.digital_signatures end
The declared digitalSignatures block, or nil when absent.
() → bool
Source
# File lib/capsium/package/security.rb, line 74 def present? !@config.nil? end
(?String output_path) → void
Source
# File lib/capsium/package/security.rb, line 112 def save_to_file(output_path = @path) File.write(output_path, to_json) end
() → bool
Source
# File lib/capsium/package/security.rb, line 85 def signed? !digital_signatures&.signature_file.nil? end
(String package_path) → Array[ChecksumMismatch | MissingFile | UncheckedFile]
Source
# File lib/capsium/package/security.rb, line 93 def verify(package_path) expected = checksums errors = verify_present_files(package_path, expected) expected.each do |relative_path, checksum| next if File.file?(File.join(package_path, relative_path)) errors << MissingFile.new(path: relative_path, expected: checksum) end errors end
(String package_path) → void
Source
# File lib/capsium/package/security.rb, line 104 def verify!(package_path) errors = verify(package_path) return if errors.empty? raise IntegrityError, "Package integrity check failed: #{errors.map(&:path).join(', ')}" end