crypto/openpgp: select newest valid encryption subkey

Change-Id: I5ae662e95d9f0f0cbcbf0b15b6c7c52c51521cca
Reviewed-on: https://go-review.googlesource.com/8726
Reviewed-by: Adam Langley <agl@golang.org>
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 @@
 
 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) 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 @@
 
 	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)
 	}