From cb175486286da5458a5391642421742d81c7f66b Mon Sep 17 00:00:00 2001 From: Andrew Gallagher Date: Sat, 16 May 2026 10:19:24 +0100 Subject: [PATCH 1/8] add sig.IssuerFingerprintVersion (closes #296) --- openpgp/packet/signature.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/openpgp/packet/signature.go b/openpgp/packet/signature.go index 4490fdf8..48fa601c 100644 --- a/openpgp/packet/signature.go +++ b/openpgp/packet/signature.go @@ -93,6 +93,7 @@ type Signature struct { PreferredCipherSuites [][2]uint8 IssuerKeyId *uint64 IssuerFingerprint []byte + IssuerFingerprintVersion *uint8 SignerUserId *string IsPrimaryId *bool Notations []*Notation @@ -638,6 +639,7 @@ func parseSignatureSubpacket(sig *Signature, subpacket []byte, isHashed bool) (r return nil, errors.StructuralError("bad fingerprint length") } sig.IssuerFingerprint = make([]byte, l) + sig.IssuerFingerprintVersion = &subpacket[0] copy(sig.IssuerFingerprint, subpacket[1:]) sig.IssuerKeyId = new(uint64) if v >= 5 { From 1908138593fc98c4bbc8703120d3b0b3a1ec3c77 Mon Sep 17 00:00:00 2001 From: Andrew Gallagher Date: Sat, 16 May 2026 10:19:51 +0100 Subject: [PATCH 2/8] DRIVEBY: remove redundant nil check --- openpgp/packet/signature.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openpgp/packet/signature.go b/openpgp/packet/signature.go index 48fa601c..44bec003 100644 --- a/openpgp/packet/signature.go +++ b/openpgp/packet/signature.go @@ -696,14 +696,14 @@ func subpacketLengthLength(length int) int { } func (sig *Signature) CheckKeyIdOrFingerprint(pk *PublicKey) bool { - if sig.IssuerFingerprint != nil && len(sig.IssuerFingerprint) >= 20 { + if len(sig.IssuerFingerprint) >= 20 { return bytes.Equal(sig.IssuerFingerprint, pk.Fingerprint) } return sig.IssuerKeyId != nil && *sig.IssuerKeyId == pk.KeyId } func (sig *Signature) CheckKeyIdOrFingerprintExplicit(fingerprint []byte, keyId uint64) bool { - if sig.IssuerFingerprint != nil && len(sig.IssuerFingerprint) >= 20 && fingerprint != nil { + if len(sig.IssuerFingerprint) >= 20 && fingerprint != nil { return bytes.Equal(sig.IssuerFingerprint, fingerprint) } return sig.IssuerKeyId != nil && *sig.IssuerKeyId == keyId From 5b8516562072d3be374e97d21a9cce183eab71bc Mon Sep 17 00:00:00 2001 From: Andrew Gallagher Date: Mon, 18 May 2026 17:38:53 +0100 Subject: [PATCH 3/8] IFPV no longer a ref; fully roundtrip IFPV; drop issuer param from buildSubpackets --- openpgp/clearsign/clearsign.go | 1 + openpgp/packet/signature.go | 18 +++++++------- openpgp/v2/read.go | 44 ++++++++++++++++++---------------- openpgp/v2/write.go | 19 ++++++++------- openpgp/write.go | 19 ++++++++------- 5 files changed, 55 insertions(+), 46 deletions(-) diff --git a/openpgp/clearsign/clearsign.go b/openpgp/clearsign/clearsign.go index 460347af..949d3d7b 100644 --- a/openpgp/clearsign/clearsign.go +++ b/openpgp/clearsign/clearsign.go @@ -338,6 +338,7 @@ func (d *dashEscaper) Close() (err error) { sig.CreationTime = t sig.IssuerKeyId = &k.KeyId sig.IssuerFingerprint = k.Fingerprint + sig.IssuerFingerprintVersion = uint8(k.Version) sig.Notations = d.config.Notations() sigLifetimeSecs := d.config.SigLifetime() sig.SigLifetimeSecs = &sigLifetimeSecs diff --git a/openpgp/packet/signature.go b/openpgp/packet/signature.go index 44bec003..6c5c10f7 100644 --- a/openpgp/packet/signature.go +++ b/openpgp/packet/signature.go @@ -87,13 +87,14 @@ type Signature struct { // The following are optional so are nil when not included in the // signature. + // The exception is IssuerFingerprintVersion, which defaults to 0. SigLifetimeSecs, KeyLifetimeSecs *uint32 PreferredSymmetric, PreferredHash, PreferredCompression []uint8 PreferredCipherSuites [][2]uint8 IssuerKeyId *uint64 IssuerFingerprint []byte - IssuerFingerprintVersion *uint8 + IssuerFingerprintVersion uint8 SignerUserId *string IsPrimaryId *bool Notations []*Notation @@ -639,7 +640,7 @@ func parseSignatureSubpacket(sig *Signature, subpacket []byte, isHashed bool) (r return nil, errors.StructuralError("bad fingerprint length") } sig.IssuerFingerprint = make([]byte, l) - sig.IssuerFingerprintVersion = &subpacket[0] + sig.IssuerFingerprintVersion = subpacket[0] copy(sig.IssuerFingerprint, subpacket[1:]) sig.IssuerKeyId = new(uint64) if v >= 5 { @@ -696,8 +697,8 @@ func subpacketLengthLength(length int) int { } func (sig *Signature) CheckKeyIdOrFingerprint(pk *PublicKey) bool { - if len(sig.IssuerFingerprint) >= 20 { - return bytes.Equal(sig.IssuerFingerprint, pk.Fingerprint) + if len(sig.IssuerFingerprint) >= 20 && sig.IssuerFingerprintVersion != 0 { + return int(sig.IssuerFingerprintVersion) == pk.Version && bytes.Equal(sig.IssuerFingerprint, pk.Fingerprint) } return sig.IssuerKeyId != nil && *sig.IssuerKeyId == pk.KeyId } @@ -921,6 +922,7 @@ func (sig *Signature) Sign(h hash.Hash, priv *PrivateKey, config *Config) (err e } sig.Version = priv.PublicKey.Version sig.IssuerFingerprint = priv.PublicKey.Fingerprint + sig.IssuerFingerprintVersion = uint8(priv.PublicKey.Version) if sig.Version < 6 && config.RandomizeSignaturesViaNotation() { sig.removeNotationsWithName(SaltNotationName) salt, err := SignatureSaltForHash(sig.Hash, config.Random()) @@ -935,7 +937,7 @@ func (sig *Signature) Sign(h hash.Hash, priv *PrivateKey, config *Config) (err e } sig.Notations = append(sig.Notations, ¬ation) } - sig.outSubpackets, err = sig.buildSubpackets(priv.PublicKey, config) + sig.outSubpackets, err = sig.buildSubpackets(config) if err != nil { return err } @@ -1256,7 +1258,7 @@ type outputSubpacket struct { contents []byte } -func (sig *Signature) buildSubpackets(issuer PublicKey, config *Config) (subpackets []outputSubpacket, err error) { +func (sig *Signature) buildSubpackets(config *Config) (subpackets []outputSubpacket, err error) { creationTime := make([]byte, 4) binary.BigEndian.PutUint32(creationTime, uint32(sig.CreationTime.Unix())) // Signature Creation Time @@ -1393,8 +1395,8 @@ func (sig *Signature) buildSubpackets(issuer PublicKey, config *Config) (subpack subpackets = append(subpackets, outputSubpacket{true, embeddedSignatureSubpacket, true, buf.Bytes()}) } // Issuer Fingerprint - if sig.IssuerFingerprint != nil { - contents := append([]uint8{uint8(issuer.Version)}, sig.IssuerFingerprint...) + if sig.IssuerFingerprint != nil && sig.IssuerFingerprintVersion != 0 { + contents := append([]uint8{sig.IssuerFingerprintVersion}, sig.IssuerFingerprint...) subpackets = append(subpackets, outputSubpacket{true, issuerFingerprintSubpacket, sig.Version >= 5, contents}) } // Intended Recipient Fingerprint diff --git a/openpgp/v2/read.go b/openpgp/v2/read.go index 7980c9b2..05b76453 100644 --- a/openpgp/v2/read.go +++ b/openpgp/v2/read.go @@ -275,13 +275,14 @@ FindKey: // SignatureCandidate keeps state about a signature that can be potentially verified. type SignatureCandidate struct { - OPSVersion int - SigType packet.SignatureType - HashAlgorithm crypto.Hash - PubKeyAlgo packet.PublicKeyAlgorithm - IssuerKeyId uint64 - IssuerFingerprint []byte - Salt []byte // v6 only + OPSVersion int + SigType packet.SignatureType + HashAlgorithm crypto.Hash + PubKeyAlgo packet.PublicKeyAlgorithm + IssuerKeyId uint64 + IssuerFingerprint []byte + IssuerFingerprintVersion uint8 + Salt []byte // v6 only SignedByEntity *Entity SignedBy *Key // the key of the signer, if available. (OPS) @@ -292,13 +293,14 @@ type SignatureCandidate struct { func newSignatureCandidate(ops *packet.OnePassSignature) (sigCandidate *SignatureCandidate) { sigCandidate = &SignatureCandidate{ - OPSVersion: ops.Version, - SigType: ops.SigType, - HashAlgorithm: ops.Hash, - PubKeyAlgo: ops.PubKeyAlgo, - IssuerKeyId: ops.KeyId, - Salt: ops.Salt, - IssuerFingerprint: ops.KeyFingerprint, + OPSVersion: ops.Version, + SigType: ops.SigType, + HashAlgorithm: ops.Hash, + PubKeyAlgo: ops.PubKeyAlgo, + IssuerKeyId: ops.KeyId, + Salt: ops.Salt, + IssuerFingerprint: ops.KeyFingerprint, + IssuerFingerprintVersion: uint8(ops.Version), } sigCandidate.Hash, sigCandidate.WrappedHash, sigCandidate.SignatureError = hashForSignature( sigCandidate.HashAlgorithm, @@ -310,12 +312,13 @@ func newSignatureCandidate(ops *packet.OnePassSignature) (sigCandidate *Signatur func newSignatureCandidateFromSignature(sig *packet.Signature) (sigCandidate *SignatureCandidate) { sigCandidate = &SignatureCandidate{ - SigType: sig.SigType, - HashAlgorithm: sig.Hash, - PubKeyAlgo: sig.PubKeyAlgo, - IssuerKeyId: *sig.IssuerKeyId, - IssuerFingerprint: sig.IssuerFingerprint, - Salt: sig.Salt(), + SigType: sig.SigType, + HashAlgorithm: sig.Hash, + PubKeyAlgo: sig.PubKeyAlgo, + IssuerKeyId: *sig.IssuerKeyId, + IssuerFingerprint: sig.IssuerFingerprint, + IssuerFingerprintVersion: sig.IssuerFingerprintVersion, + Salt: sig.Salt(), } sigCandidate.OPSVersion = 3 if sig.Version == 6 { @@ -334,6 +337,7 @@ func (sc *SignatureCandidate) validate() bool { correspondingSig := sc.CorrespondingSig invalidV3 := sc.OPSVersion == 3 && correspondingSig.Version == 6 invalidV6 := (sc.OPSVersion == 6 && correspondingSig.Version != 6) || + (sc.OPSVersion == 6 && sc.IssuerFingerprintVersion != correspondingSig.IssuerFingerprintVersion) || (sc.OPSVersion == 6 && !bytes.Equal(sc.IssuerFingerprint, correspondingSig.IssuerFingerprint)) || (sc.OPSVersion == 6 && !bytes.Equal(sc.Salt, correspondingSig.Salt())) return correspondingSig != nil && diff --git a/openpgp/v2/write.go b/openpgp/v2/write.go index 0692cec6..886704e4 100644 --- a/openpgp/v2/write.go +++ b/openpgp/v2/write.go @@ -904,15 +904,16 @@ func createSignaturePacket(signer *packet.PublicKey, sigType packet.SignatureTyp sigLifetimeSecs := config.SigLifetime() hash := selectHashForSigningKey(config, signer) return &packet.Signature{ - Version: signer.Version, - SigType: sigType, - PubKeyAlgo: signer.PubKeyAlgo, - Hash: hash, - CreationTime: config.Now(), - IssuerKeyId: &signer.KeyId, - IssuerFingerprint: signer.Fingerprint, - Notations: config.Notations(), - SigLifetimeSecs: &sigLifetimeSecs, + Version: signer.Version, + SigType: sigType, + PubKeyAlgo: signer.PubKeyAlgo, + Hash: hash, + CreationTime: config.Now(), + IssuerKeyId: &signer.KeyId, + IssuerFingerprint: signer.Fingerprint, + IssuerFingerprintVersion: uint8(signer.Version), + Notations: config.Notations(), + SigLifetimeSecs: &sigLifetimeSecs, } } diff --git a/openpgp/write.go b/openpgp/write.go index 84bc27d8..6c7802d6 100644 --- a/openpgp/write.go +++ b/openpgp/write.go @@ -560,15 +560,16 @@ func createSignaturePacket(signer *packet.PublicKey, sigType packet.SignatureTyp sigLifetimeSecs := config.SigLifetime() hash := selectHashForSigningKey(config, signer) return &packet.Signature{ - Version: signer.Version, - SigType: sigType, - PubKeyAlgo: signer.PubKeyAlgo, - Hash: hash, - CreationTime: config.Now(), - IssuerKeyId: &signer.KeyId, - IssuerFingerprint: signer.Fingerprint, - Notations: config.Notations(), - SigLifetimeSecs: &sigLifetimeSecs, + Version: signer.Version, + SigType: sigType, + PubKeyAlgo: signer.PubKeyAlgo, + Hash: hash, + CreationTime: config.Now(), + IssuerKeyId: &signer.KeyId, + IssuerFingerprint: signer.Fingerprint, + IssuerFingerprintVersion: uint8(signer.Version), + Notations: config.Notations(), + SigLifetimeSecs: &sigLifetimeSecs, } } From 68a919eb263fd4742737523cc0ecf99266c20643 Mon Sep 17 00:00:00 2001 From: Daniel Huigens Date: Mon, 18 May 2026 21:17:04 +0200 Subject: [PATCH 4/8] Rename IssuerFingerprintVersion to IssuerKeyVersion --- openpgp/clearsign/clearsign.go | 2 +- openpgp/packet/signature.go | 18 ++++++------- openpgp/v2/read.go | 48 +++++++++++++++++----------------- openpgp/v2/write.go | 20 +++++++------- openpgp/write.go | 20 +++++++------- 5 files changed, 54 insertions(+), 54 deletions(-) diff --git a/openpgp/clearsign/clearsign.go b/openpgp/clearsign/clearsign.go index 949d3d7b..245a66f1 100644 --- a/openpgp/clearsign/clearsign.go +++ b/openpgp/clearsign/clearsign.go @@ -337,8 +337,8 @@ func (d *dashEscaper) Close() (err error) { sig.Hash = d.hashTypes[i] sig.CreationTime = t sig.IssuerKeyId = &k.KeyId + sig.IssuerKeyVersion = uint8(k.Version) sig.IssuerFingerprint = k.Fingerprint - sig.IssuerFingerprintVersion = uint8(k.Version) sig.Notations = d.config.Notations() sigLifetimeSecs := d.config.SigLifetime() sig.SigLifetimeSecs = &sigLifetimeSecs diff --git a/openpgp/packet/signature.go b/openpgp/packet/signature.go index 6c5c10f7..8dd6213b 100644 --- a/openpgp/packet/signature.go +++ b/openpgp/packet/signature.go @@ -87,14 +87,14 @@ type Signature struct { // The following are optional so are nil when not included in the // signature. - // The exception is IssuerFingerprintVersion, which defaults to 0. + // The exception is IssuerKeyVersion, which defaults to 0. SigLifetimeSecs, KeyLifetimeSecs *uint32 PreferredSymmetric, PreferredHash, PreferredCompression []uint8 PreferredCipherSuites [][2]uint8 IssuerKeyId *uint64 + IssuerKeyVersion uint8 IssuerFingerprint []byte - IssuerFingerprintVersion uint8 SignerUserId *string IsPrimaryId *bool Notations []*Notation @@ -639,8 +639,8 @@ func parseSignatureSubpacket(sig *Signature, subpacket []byte, isHashed bool) (r if v >= 5 && l != 32 || v < 5 && l != 20 { return nil, errors.StructuralError("bad fingerprint length") } + sig.IssuerKeyVersion = subpacket[0] sig.IssuerFingerprint = make([]byte, l) - sig.IssuerFingerprintVersion = subpacket[0] copy(sig.IssuerFingerprint, subpacket[1:]) sig.IssuerKeyId = new(uint64) if v >= 5 { @@ -697,14 +697,14 @@ func subpacketLengthLength(length int) int { } func (sig *Signature) CheckKeyIdOrFingerprint(pk *PublicKey) bool { - if len(sig.IssuerFingerprint) >= 20 && sig.IssuerFingerprintVersion != 0 { - return int(sig.IssuerFingerprintVersion) == pk.Version && bytes.Equal(sig.IssuerFingerprint, pk.Fingerprint) + if sig.IssuerKeyVersion != 0 && len(sig.IssuerFingerprint) >= 20 { + return int(sig.IssuerKeyVersion) == pk.Version && bytes.Equal(sig.IssuerFingerprint, pk.Fingerprint) } return sig.IssuerKeyId != nil && *sig.IssuerKeyId == pk.KeyId } func (sig *Signature) CheckKeyIdOrFingerprintExplicit(fingerprint []byte, keyId uint64) bool { - if len(sig.IssuerFingerprint) >= 20 && fingerprint != nil { + if sig.IssuerKeyVersion != 0 && len(sig.IssuerFingerprint) >= 20 && fingerprint != nil { return bytes.Equal(sig.IssuerFingerprint, fingerprint) } return sig.IssuerKeyId != nil && *sig.IssuerKeyId == keyId @@ -921,8 +921,8 @@ func (sig *Signature) Sign(h hash.Hash, priv *PrivateKey, config *Config) (err e return errors.ErrDummyPrivateKey("dummy key found") } sig.Version = priv.PublicKey.Version + sig.IssuerKeyVersion = uint8(priv.PublicKey.Version) sig.IssuerFingerprint = priv.PublicKey.Fingerprint - sig.IssuerFingerprintVersion = uint8(priv.PublicKey.Version) if sig.Version < 6 && config.RandomizeSignaturesViaNotation() { sig.removeNotationsWithName(SaltNotationName) salt, err := SignatureSaltForHash(sig.Hash, config.Random()) @@ -1395,8 +1395,8 @@ func (sig *Signature) buildSubpackets(config *Config) (subpackets []outputSubpac subpackets = append(subpackets, outputSubpacket{true, embeddedSignatureSubpacket, true, buf.Bytes()}) } // Issuer Fingerprint - if sig.IssuerFingerprint != nil && sig.IssuerFingerprintVersion != 0 { - contents := append([]uint8{sig.IssuerFingerprintVersion}, sig.IssuerFingerprint...) + if sig.IssuerKeyVersion != 0 && sig.IssuerFingerprint != nil { + contents := append([]uint8{sig.IssuerKeyVersion}, sig.IssuerFingerprint...) subpackets = append(subpackets, outputSubpacket{true, issuerFingerprintSubpacket, sig.Version >= 5, contents}) } // Intended Recipient Fingerprint diff --git a/openpgp/v2/read.go b/openpgp/v2/read.go index 05b76453..b3ff590e 100644 --- a/openpgp/v2/read.go +++ b/openpgp/v2/read.go @@ -275,14 +275,14 @@ FindKey: // SignatureCandidate keeps state about a signature that can be potentially verified. type SignatureCandidate struct { - OPSVersion int - SigType packet.SignatureType - HashAlgorithm crypto.Hash - PubKeyAlgo packet.PublicKeyAlgorithm - IssuerKeyId uint64 - IssuerFingerprint []byte - IssuerFingerprintVersion uint8 - Salt []byte // v6 only + OPSVersion int + SigType packet.SignatureType + HashAlgorithm crypto.Hash + PubKeyAlgo packet.PublicKeyAlgorithm + IssuerKeyId uint64 + IssuerKeyVersion uint8 + IssuerFingerprint []byte + Salt []byte // v6 only SignedByEntity *Entity SignedBy *Key // the key of the signer, if available. (OPS) @@ -293,14 +293,14 @@ type SignatureCandidate struct { func newSignatureCandidate(ops *packet.OnePassSignature) (sigCandidate *SignatureCandidate) { sigCandidate = &SignatureCandidate{ - OPSVersion: ops.Version, - SigType: ops.SigType, - HashAlgorithm: ops.Hash, - PubKeyAlgo: ops.PubKeyAlgo, - IssuerKeyId: ops.KeyId, - Salt: ops.Salt, - IssuerFingerprint: ops.KeyFingerprint, - IssuerFingerprintVersion: uint8(ops.Version), + OPSVersion: ops.Version, + SigType: ops.SigType, + HashAlgorithm: ops.Hash, + PubKeyAlgo: ops.PubKeyAlgo, + IssuerKeyId: ops.KeyId, + Salt: ops.Salt, + IssuerKeyVersion: uint8(ops.Version), + IssuerFingerprint: ops.KeyFingerprint, } sigCandidate.Hash, sigCandidate.WrappedHash, sigCandidate.SignatureError = hashForSignature( sigCandidate.HashAlgorithm, @@ -312,13 +312,13 @@ func newSignatureCandidate(ops *packet.OnePassSignature) (sigCandidate *Signatur func newSignatureCandidateFromSignature(sig *packet.Signature) (sigCandidate *SignatureCandidate) { sigCandidate = &SignatureCandidate{ - SigType: sig.SigType, - HashAlgorithm: sig.Hash, - PubKeyAlgo: sig.PubKeyAlgo, - IssuerKeyId: *sig.IssuerKeyId, - IssuerFingerprint: sig.IssuerFingerprint, - IssuerFingerprintVersion: sig.IssuerFingerprintVersion, - Salt: sig.Salt(), + SigType: sig.SigType, + HashAlgorithm: sig.Hash, + PubKeyAlgo: sig.PubKeyAlgo, + IssuerKeyId: *sig.IssuerKeyId, + IssuerKeyVersion: sig.IssuerKeyVersion, + IssuerFingerprint: sig.IssuerFingerprint, + Salt: sig.Salt(), } sigCandidate.OPSVersion = 3 if sig.Version == 6 { @@ -337,7 +337,7 @@ func (sc *SignatureCandidate) validate() bool { correspondingSig := sc.CorrespondingSig invalidV3 := sc.OPSVersion == 3 && correspondingSig.Version == 6 invalidV6 := (sc.OPSVersion == 6 && correspondingSig.Version != 6) || - (sc.OPSVersion == 6 && sc.IssuerFingerprintVersion != correspondingSig.IssuerFingerprintVersion) || + (sc.OPSVersion == 6 && sc.IssuerKeyVersion != correspondingSig.IssuerKeyVersion) || (sc.OPSVersion == 6 && !bytes.Equal(sc.IssuerFingerprint, correspondingSig.IssuerFingerprint)) || (sc.OPSVersion == 6 && !bytes.Equal(sc.Salt, correspondingSig.Salt())) return correspondingSig != nil && diff --git a/openpgp/v2/write.go b/openpgp/v2/write.go index 886704e4..804a895a 100644 --- a/openpgp/v2/write.go +++ b/openpgp/v2/write.go @@ -904,16 +904,16 @@ func createSignaturePacket(signer *packet.PublicKey, sigType packet.SignatureTyp sigLifetimeSecs := config.SigLifetime() hash := selectHashForSigningKey(config, signer) return &packet.Signature{ - Version: signer.Version, - SigType: sigType, - PubKeyAlgo: signer.PubKeyAlgo, - Hash: hash, - CreationTime: config.Now(), - IssuerKeyId: &signer.KeyId, - IssuerFingerprint: signer.Fingerprint, - IssuerFingerprintVersion: uint8(signer.Version), - Notations: config.Notations(), - SigLifetimeSecs: &sigLifetimeSecs, + Version: signer.Version, + SigType: sigType, + PubKeyAlgo: signer.PubKeyAlgo, + Hash: hash, + CreationTime: config.Now(), + IssuerKeyId: &signer.KeyId, + IssuerKeyVersion: uint8(signer.Version), + IssuerFingerprint: signer.Fingerprint, + Notations: config.Notations(), + SigLifetimeSecs: &sigLifetimeSecs, } } diff --git a/openpgp/write.go b/openpgp/write.go index 6c7802d6..f66f8ff5 100644 --- a/openpgp/write.go +++ b/openpgp/write.go @@ -560,16 +560,16 @@ func createSignaturePacket(signer *packet.PublicKey, sigType packet.SignatureTyp sigLifetimeSecs := config.SigLifetime() hash := selectHashForSigningKey(config, signer) return &packet.Signature{ - Version: signer.Version, - SigType: sigType, - PubKeyAlgo: signer.PubKeyAlgo, - Hash: hash, - CreationTime: config.Now(), - IssuerKeyId: &signer.KeyId, - IssuerFingerprint: signer.Fingerprint, - IssuerFingerprintVersion: uint8(signer.Version), - Notations: config.Notations(), - SigLifetimeSecs: &sigLifetimeSecs, + Version: signer.Version, + SigType: sigType, + PubKeyAlgo: signer.PubKeyAlgo, + Hash: hash, + CreationTime: config.Now(), + IssuerKeyId: &signer.KeyId, + IssuerKeyVersion: uint8(signer.Version), + IssuerFingerprint: signer.Fingerprint, + Notations: config.Notations(), + SigLifetimeSecs: &sigLifetimeSecs, } } From fe59f811be6df5b66176d08cf34471efe8fbe3f0 Mon Sep 17 00:00:00 2001 From: Andrew Gallagher Date: Tue, 19 May 2026 13:28:40 +0100 Subject: [PATCH 5/8] tidy up ops version handling --- openpgp/v2/read.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/openpgp/v2/read.go b/openpgp/v2/read.go index b3ff590e..f9448a26 100644 --- a/openpgp/v2/read.go +++ b/openpgp/v2/read.go @@ -298,9 +298,11 @@ func newSignatureCandidate(ops *packet.OnePassSignature) (sigCandidate *Signatur HashAlgorithm: ops.Hash, PubKeyAlgo: ops.PubKeyAlgo, IssuerKeyId: ops.KeyId, - Salt: ops.Salt, - IssuerKeyVersion: uint8(ops.Version), IssuerFingerprint: ops.KeyFingerprint, + Salt: ops.Salt, + } + if ops.Version == 6 { + sigCandidate.IssuerKeyVersion = uint8(ops.Version) } sigCandidate.Hash, sigCandidate.WrappedHash, sigCandidate.SignatureError = hashForSignature( sigCandidate.HashAlgorithm, From a22ee6b975de77e5b681039b7a8c05cc3df31d7b Mon Sep 17 00:00:00 2001 From: Andrew Gallagher Date: Tue, 19 May 2026 13:33:32 +0100 Subject: [PATCH 6/8] DRIVEBY: fix nil deref check, early fail order --- openpgp/v2/read.go | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/openpgp/v2/read.go b/openpgp/v2/read.go index f9448a26..c2461bc6 100644 --- a/openpgp/v2/read.go +++ b/openpgp/v2/read.go @@ -336,19 +336,20 @@ func newSignatureCandidateFromSignature(sig *packet.Signature) (sigCandidate *Si } func (sc *SignatureCandidate) validate() bool { + if sc.CorrespondingSig == nil { + return false + } correspondingSig := sc.CorrespondingSig invalidV3 := sc.OPSVersion == 3 && correspondingSig.Version == 6 invalidV6 := (sc.OPSVersion == 6 && correspondingSig.Version != 6) || (sc.OPSVersion == 6 && sc.IssuerKeyVersion != correspondingSig.IssuerKeyVersion) || (sc.OPSVersion == 6 && !bytes.Equal(sc.IssuerFingerprint, correspondingSig.IssuerFingerprint)) || (sc.OPSVersion == 6 && !bytes.Equal(sc.Salt, correspondingSig.Salt())) - return correspondingSig != nil && + return !invalidV3 && !invalidV6 && sc.SigType == correspondingSig.SigType && sc.HashAlgorithm == correspondingSig.Hash && sc.PubKeyAlgo == correspondingSig.PubKeyAlgo && - sc.IssuerKeyId == *correspondingSig.IssuerKeyId && - !invalidV3 && - !invalidV6 + sc.IssuerKeyId == *correspondingSig.IssuerKeyId } // readSignedMessage reads a possibly signed message if mdin is non-zero then From 4223fb55cea037a5a60d84921213fd4d416cf28e Mon Sep 17 00:00:00 2001 From: Andrew Gallagher Date: Tue, 19 May 2026 14:56:54 +0100 Subject: [PATCH 7/8] remove IssuerKeyVersion from SignatureCandidate --- openpgp/v2/read.go | 6 ------ 1 file changed, 6 deletions(-) diff --git a/openpgp/v2/read.go b/openpgp/v2/read.go index c2461bc6..62fec52e 100644 --- a/openpgp/v2/read.go +++ b/openpgp/v2/read.go @@ -280,7 +280,6 @@ type SignatureCandidate struct { HashAlgorithm crypto.Hash PubKeyAlgo packet.PublicKeyAlgorithm IssuerKeyId uint64 - IssuerKeyVersion uint8 IssuerFingerprint []byte Salt []byte // v6 only @@ -301,9 +300,6 @@ func newSignatureCandidate(ops *packet.OnePassSignature) (sigCandidate *Signatur IssuerFingerprint: ops.KeyFingerprint, Salt: ops.Salt, } - if ops.Version == 6 { - sigCandidate.IssuerKeyVersion = uint8(ops.Version) - } sigCandidate.Hash, sigCandidate.WrappedHash, sigCandidate.SignatureError = hashForSignature( sigCandidate.HashAlgorithm, sigCandidate.SigType, @@ -318,7 +314,6 @@ func newSignatureCandidateFromSignature(sig *packet.Signature) (sigCandidate *Si HashAlgorithm: sig.Hash, PubKeyAlgo: sig.PubKeyAlgo, IssuerKeyId: *sig.IssuerKeyId, - IssuerKeyVersion: sig.IssuerKeyVersion, IssuerFingerprint: sig.IssuerFingerprint, Salt: sig.Salt(), } @@ -342,7 +337,6 @@ func (sc *SignatureCandidate) validate() bool { correspondingSig := sc.CorrespondingSig invalidV3 := sc.OPSVersion == 3 && correspondingSig.Version == 6 invalidV6 := (sc.OPSVersion == 6 && correspondingSig.Version != 6) || - (sc.OPSVersion == 6 && sc.IssuerKeyVersion != correspondingSig.IssuerKeyVersion) || (sc.OPSVersion == 6 && !bytes.Equal(sc.IssuerFingerprint, correspondingSig.IssuerFingerprint)) || (sc.OPSVersion == 6 && !bytes.Equal(sc.Salt, correspondingSig.Salt())) return !invalidV3 && !invalidV6 && From 2832a920251e4abf1425ef409e56c9c26e11dfe7 Mon Sep 17 00:00:00 2001 From: Andrew Gallagher Date: Tue, 19 May 2026 14:59:17 +0100 Subject: [PATCH 8/8] DRIVEBY: simplify test logic --- openpgp/v2/read.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/openpgp/v2/read.go b/openpgp/v2/read.go index 62fec52e..b04c67e4 100644 --- a/openpgp/v2/read.go +++ b/openpgp/v2/read.go @@ -336,9 +336,10 @@ func (sc *SignatureCandidate) validate() bool { } correspondingSig := sc.CorrespondingSig invalidV3 := sc.OPSVersion == 3 && correspondingSig.Version == 6 - invalidV6 := (sc.OPSVersion == 6 && correspondingSig.Version != 6) || - (sc.OPSVersion == 6 && !bytes.Equal(sc.IssuerFingerprint, correspondingSig.IssuerFingerprint)) || - (sc.OPSVersion == 6 && !bytes.Equal(sc.Salt, correspondingSig.Salt())) + invalidV6 := sc.OPSVersion == 6 && + (correspondingSig.Version != 6 || + !bytes.Equal(sc.IssuerFingerprint, correspondingSig.IssuerFingerprint) || + !bytes.Equal(sc.Salt, correspondingSig.Salt())) return !invalidV3 && !invalidV6 && sc.SigType == correspondingSig.SigType && sc.HashAlgorithm == correspondingSig.Hash &&