From 00796149575a278b685f67f889bb34e1245ff6cb Mon Sep 17 00:00:00 2001 From: Daniel Kahn Gillmor Date: Thu, 31 Jul 2025 01:31:27 -0400 Subject: [PATCH] Add NoEncryptionSubkey to openpgp/packet/Config This is a step toward being able to support gosop generate-key --signing-only See https://github.com/ProtonMail/gosop/issues/43 --- openpgp/key_generation.go | 12 +++++++----- openpgp/packet/config.go | 11 +++++++++++ openpgp/v2/key_generation.go | 12 +++++++----- 3 files changed, 25 insertions(+), 10 deletions(-) diff --git a/openpgp/key_generation.go b/openpgp/key_generation.go index 77213f66b..7122e4471 100644 --- a/openpgp/key_generation.go +++ b/openpgp/key_generation.go @@ -74,11 +74,13 @@ func NewEntity(name, comment, email string, config *packet.Config) (*Entity, err return nil, err } - // NOTE: No key expiry here, but we will not return this subkey in EncryptionKey() - // if the primary/master key has expired. - err = e.addEncryptionSubkey(config, creationTime, 0) - if err != nil { - return nil, err + if !config.NoEncryptionSubkey() { + // NOTE: No key expiry here, but we will not return this subkey in EncryptionKey() + // if the primary/master key has expired. + err = e.addEncryptionSubkey(config, creationTime, 0) + if err != nil { + return nil, err + } } return e, nil diff --git a/openpgp/packet/config.go b/openpgp/packet/config.go index 142be0aa0..a1ff0cd9c 100644 --- a/openpgp/packet/config.go +++ b/openpgp/packet/config.go @@ -195,6 +195,10 @@ type Config struct { // read from a compressed packet. This serves as an upper limit to prevent // excessively large decompressed messages. MaxDecompressedMessageSize *int64 + + // NoEncryptionSubkey configures key generation. true results in an + // OpenPGP key that has no encryption-capable subkey + NoEncryptionSubkey bool } func (c *Config) Random() io.Reader { @@ -453,6 +457,13 @@ func (c *Config) DecompressedMessageSizeLimit() *int64 { return c.MaxDecompressedMessageSize } +func (c *Config) NoEncryptionSubkey() bool { + if c == nil { + return false + } + return c.NoEncryptionSubkey +} + // BoolPointer is a helper function to set a boolean pointer in the Config. // e.g., config.CheckPacketSequence = BoolPointer(true) func BoolPointer(value bool) *bool { diff --git a/openpgp/v2/key_generation.go b/openpgp/v2/key_generation.go index f0767cf91..c3fb834f9 100644 --- a/openpgp/v2/key_generation.go +++ b/openpgp/v2/key_generation.go @@ -112,11 +112,13 @@ func newEntity(uid *userIdData, config *packet.Config) (*Entity, error) { } } - // NOTE: No key expiry here, but we will not return this subkey in EncryptionKey() - // if the primary/master key has expired. - err = e.addEncryptionSubkey(config, creationTime, 0) - if err != nil { - return nil, err + if !config.NoEncryptionSubkey() { + // NOTE: No key expiry here, but we will not return this subkey in EncryptionKey() + // if the primary/master key has expired. + err = e.addEncryptionSubkey(config, creationTime, 0) + if err != nil { + return nil, err + } } return e, nil