From 326f0c56aaa360d621f27fe3ff4a89735582822c Mon Sep 17 00:00:00 2001 From: Keith Ball Date: Fri, 10 Apr 2015 16:41:19 +0200 Subject: [PATCH] crypto/openpgp: select newest valid encryption subkey Change-Id: I5ae662e95d9f0f0cbcbf0b15b6c7c52c51521cca Reviewed-on: https://go-review.googlesource.com/8726 Reviewed-by: Adam Langley --- openpgp/keys.go | 12 ++++++++---- openpgp/keys_test.go | 11 ++++++----- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/openpgp/keys.go b/openpgp/keys.go index c4a6640..fe12cfa 100644 --- a/openpgp/keys.go +++ b/openpgp/keys.go @@ -6,11 +6,12 @@ package openpgp import ( "crypto/rsa" + "io" + "time" + "golang.org/x/crypto/openpgp/armor" "golang.org/x/crypto/openpgp/errors" "golang.org/x/crypto/openpgp/packet" - "io" - "time" ) // PublicKeyType is the armor type for a PGP public key. @@ -90,13 +91,16 @@ func (e *Entity) primaryIdentity() *Identity { func (e *Entity) encryptionKey(now time.Time) (Key, bool) { candidateSubkey := -1 + // Iterate the keys to find the newest key + var maxTime time.Time for i, subkey := range e.Subkeys { if subkey.Sig.FlagsValid && subkey.Sig.FlagEncryptCommunications && subkey.PublicKey.PubKeyAlgo.CanEncrypt() && - !subkey.Sig.KeyExpired(now) { + !subkey.Sig.KeyExpired(now) && + (maxTime.IsZero() || subkey.Sig.CreationTime.After(maxTime)) { candidateSubkey = i - break + maxTime = subkey.Sig.CreationTime } } diff --git a/openpgp/keys_test.go b/openpgp/keys_test.go index e0625cb..32c78f2 100644 --- a/openpgp/keys_test.go +++ b/openpgp/keys_test.go @@ -13,15 +13,16 @@ func TestKeyExpiry(t *testing.T) { const timeFormat = "2006-01-02" time1, _ := time.Parse(timeFormat, "2013-07-01") + // The expiringKeyHex key is structured as: // - // pub 1024R/5E237D8C created: 2013-07-01 expires: 2013-07-31 usage: SC - // sub 1024R/1ABB25A0 created: 2013-07-01 expires: 2013-07-08 usage: E - // sub 1024R/96A672F5 created: 2013-07-01 expires: 2013-07-31 usage: E + // pub 1024R/5E237D8C created: 2013-07-01 expires: 2013-07-31 usage: SC + // sub 1024R/1ABB25A0 created: 2013-07-01 23:11:07 +0200 CEST expires: 2013-07-08 usage: E + // sub 1024R/96A672F5 created: 2013-07-01 23:11:23 +0200 CEST expires: 2013-07-31 usage: E // - // So this should select the first, non-expired encryption key. + // So this should select the newest, non-expired encryption key. key, _ := entity.encryptionKey(time1) - if id := key.PublicKey.KeyIdShortString(); id != "1ABB25A0" { + if id := key.PublicKey.KeyIdShortString(); id != "96A672F5" { t.Errorf("Expected key 1ABB25A0 at time %s, but got key %s", time1.Format(timeFormat), id) }