class Capsium::Package::Signer
Signs and verifies Capsium packages with RSA-SHA256 digital signatures (05x-packaging “Digital Signature Using X.509”, 05x-security “Digital Signatures”).
Signed payload construction (deterministic, openssl-verifiable): the concatenation, in sorted package-relative path order, of the raw bytes of every file covered by the security.json integrity checksums — i.e. every package file except security.json and signature.sig. The signature itself is the raw RSA-SHA256 signature over that payload, stored in signature.sig. Equivalent openssl verification:
openssl dgst -sha256 -verify pubkey.pem -signature signature.sig payload.bin
where payload.bin is the concatenation described above.
Constants
- ALGORITHM
- MIN_KEY_BITS
- PUBLIC_KEY_FILE
-
Package-relative name of the embedded public key PEM recorded in security.json digitalSignatures.publicKey.
Attributes
String
Public Class Methods
(String package_path) → void
Source
# File lib/capsium/package/signer.rb, line 42 def initialize(package_path) @package_path = package_path end
(String path, String private_key_path, ?String? certificate_path) → String
Source
# File lib/capsium/package/signer.rb, line 48 def self.sign_package(path, private_key_path, certificate_path = nil) return new(path).sign(private_key_path, certificate_path) unless cap?(path) Packager.new.transform_cap(path) { |dir| new(dir).sign(private_key_path, certificate_path) } path end
Signs a package directory in place, or a .cap file (unpacked, signed, recompressed). Returns the signed path.
(String package_path) → (singleton(Signer) | singleton(OpenPgpSigner))
Source
# File lib/capsium/package/signer.rb, line 71 def self.signer_class_for(package_path) security = Security.new(File.join(package_path, Package::SECURITY_FILE)) return OpenPgpSigner if security.digital_signatures&.certificate_type == OpenPgpSigner::CERTIFICATE_TYPE self end
The signer class matching a package’s declared signature scheme: OpenPgpSigner when security.json declares digitalSignatures.certificateType “OpenPGP”, Signer otherwise.
(String path, ?String? public_key_path) → bool
Source
# File lib/capsium/package/signer.rb, line 60 def self.verify_package(path, public_key_path = nil) return signer_class_for(path).new(path).verify(public_key_path) unless cap?(path) Packager.new.with_unpacked_cap(path) do |dir| signer_class_for(dir).new(dir).verify(public_key_path) end end
Verifies the declared signature of a package directory or .cap file (false on mismatch; raises typed SignatureError subclasses on structural problems, e.g. an unsigned package). The signer is selected from the declared digitalSignatures certificateType: OpenPGP packages verify through OpenPgpSigner.
Public Instance Methods
(String private_key_path, ?String? certificate_path) → String
Source
# File lib/capsium/package/signer.rb, line 89 def sign(private_key_path, certificate_path = nil) private_key = load_private_key(private_key_path) File.write(public_key_path, public_pem_for(private_key, certificate_path)) security = Security.generate(@package_path, digital_signatures: digital_signatures) security.save_to_file File.binwrite(signature_path, private_key.sign("SHA256", payload(security))) signature_path end
Signs the package directory in place: embeds the public key PEM, regenerates security.json (checksums plus digitalSignatures) and writes the raw RSA-SHA256 signature to signature.sig. When a certificate is given it must match the private key, and the certificate’s public key is embedded instead.
() → bool
Source
# File lib/capsium/package/signer.rb, line 116 def signed? declared_security.signed? end
(?String? public_key_path) → bool
Source
# File lib/capsium/package/signer.rb, line 101 def verify(public_key_path = nil) signature = read_signature data = payload(declared_security) public_key(public_key_path).verify("SHA256", signature, data) rescue OpenSSL::PKey::PKeyError false end
True when the declared signature verifies against the payload. Without an explicit key path, the embedded public key is used. Raises typed SignatureError subclasses on structural problems.
(?String? public_key_path) → bool
Source
# File lib/capsium/package/signer.rb, line 109 def verify!(public_key_path = nil) return true if verify(public_key_path) raise SignatureMismatchError, "digital signature does not match the package contents" end