From 6b65ae346008bbd385b428a7f18174ae17eb173f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miloslav=20Trma=C4=8D?= Date: Wed, 25 Jun 2025 22:59:05 +0200 Subject: [PATCH] Add a new Signer API for creating simple signing signatures with Sequoia-PGP MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This API is proven end-to-end in https://github.com/containers/image/pull/2876 and https://github.com/containers/skopeo/pull/2645 , but it is not yet convenient to use becahse the Rust dependency has to be compiled manually. So, for now, add the API as a stub only; that allows building the CLIs and tests on top, and they will light up once the backend is added. Signed-off-by: Miloslav Trmač --- signature/simplesequoia/options.go | 37 ++++++++++++++++++++++++++ signature/simplesequoia/signer_stub.go | 26 ++++++++++++++++++ 2 files changed, 63 insertions(+) create mode 100644 signature/simplesequoia/options.go create mode 100644 signature/simplesequoia/signer_stub.go diff --git a/signature/simplesequoia/options.go b/signature/simplesequoia/options.go new file mode 100644 index 00000000..9e3448d7 --- /dev/null +++ b/signature/simplesequoia/options.go @@ -0,0 +1,37 @@ +package simplesequoia + +import ( + "errors" + "strings" +) + +type Option func(*simpleSequoiaSigner) error + +// WithSequoiaHome returns an Option for NewSigner, specifying a Sequoia home directory to use. +func WithSequoiaHome(sequoiaHome string) Option { + return func(s *simpleSequoiaSigner) error { + s.sequoiaHome = sequoiaHome + return nil + } +} + +// WithKeyFingerprint returns an Option for NewSigner, specifying a key to sign with, using the provided Sequoia-PGP key fingerprint. +func WithKeyFingerprint(keyFingerprint string) Option { + return func(s *simpleSequoiaSigner) error { + s.keyFingerprint = keyFingerprint + return nil + } +} + +// WithPassphrase returns an Option for NewSigner, specifying a passphrase for the private key. +func WithPassphrase(passphrase string) Option { + return func(s *simpleSequoiaSigner) error { + // The gpgme implementation can’t use passphrase with \n; reject it here for consistent behavior. + // FIXME: We don’t need it in this API at all, but the "\n" check exists in the current call stack. That should go away. + if strings.Contains(passphrase, "\n") { + return errors.New("invalid passphrase: must not contain a line break") + } + s.passphrase = passphrase + return nil + } +} diff --git a/signature/simplesequoia/signer_stub.go b/signature/simplesequoia/signer_stub.go new file mode 100644 index 00000000..49fe487e --- /dev/null +++ b/signature/simplesequoia/signer_stub.go @@ -0,0 +1,26 @@ +package simplesequoia + +import ( + "errors" + + "github.com/containers/image/v5/signature/signer" +) + +// simpleSequoiaSigner is a signer.SignerImplementation implementation for simple signing signatures using Sequoia. +type simpleSequoiaSigner struct { + // This is not really used, we just keep the struct fields so that the With… Option functions can be compiled. + + sequoiaHome string // "" if using the system's default + keyFingerprint string + passphrase string // "" if not provided. +} + +// NewSigner returns a signature.Signer which creates "simple signing" signatures using the user's default +// Sequoia PGP configuration. +// +// The set of options must identify a key to sign with, probably using a WithKeyFingerprint. +// +// The caller must call Close() on the returned Signer. +func NewSigner(opts ...Option) (*signer.Signer, error) { + return nil, errors.New("Sequoia-PGP support is not enabled in this build") +}