openpgp: use latest subkey binding signature Rather than using the first subkey binding signature encountered, use the one with the most recent creation data, as per the recommendation from RFC 4880: > An implementation that encounters multiple self-signatures on the > same object may resolve the ambiguity in any way it sees fit, but it > is RECOMMENDED that priority be given to the most recent self- > signature. This allows subkeys to approach expiry then be re-signed with a new expiry. This extends the recent commit 0e37d00 by @aviau and @FiloSottile. Fixes golang/go#26468 Change-Id: I7f12706727373259c188bfee4254306ef9d4e935 GitHub-Last-Rev: 0da814166411a3c3334312576d3f7f8f2bba4ff4 GitHub-Pull-Request: golang/crypto#57 Reviewed-on: https://go-review.googlesource.com/135357 Reviewed-by: Filippo Valsorda <filippo@golang.org>
diff --git a/openpgp/keys.go b/openpgp/keys.go index d8b896d..3e25186 100644 --- a/openpgp/keys.go +++ b/openpgp/keys.go
@@ -465,7 +465,8 @@ case packet.SigTypeSubkeyRevocation: subKey.Sig = sig case packet.SigTypeSubkeyBinding: - if subKey.Sig == nil { + + if shouldReplaceSubkeySig(subKey.Sig, sig) { subKey.Sig = sig } } @@ -480,6 +481,22 @@ return nil } +func shouldReplaceSubkeySig(existingSig, potentialNewSig *packet.Signature) bool { + if potentialNewSig == nil { + return false + } + + if existingSig == nil { + return true + } + + if existingSig.SigType == packet.SigTypeSubkeyRevocation { + return false // never override a revocation signature + } + + return potentialNewSig.CreationTime.After(existingSig.CreationTime) +} + const defaultRSAKeyBits = 2048 // NewEntity returns an Entity that contains a fresh RSA/RSA keypair with a