openpgp/clearsign: Handle truncated messages

When parsing a truncated clearsigned message (one that includes the
opening header but no armored data), the existing implementation of
clearsign.Decode() hangs in an infinite loop. This commit changes
Decode() to detect the end of the buffer and return as if no
clearsigned message was found.

Change-Id: Ibc85b29a08d22868470f48fe300bf8fcb4749768
Reviewed-on: https://go-review.googlesource.com/17693
Reviewed-by: Adam Langley <agl@golang.org>
diff --git a/openpgp/clearsign/clearsign.go b/openpgp/clearsign/clearsign.go
index 6454d22..def4cab 100644
--- a/openpgp/clearsign/clearsign.go
+++ b/openpgp/clearsign/clearsign.go
@@ -118,6 +118,10 @@
 		start := rest
 
 		line, rest = getLine(rest)
+		if len(line) == 0 && len(rest) == 0 {
+			// No armored data was found, so this isn't a complete message.
+			return nil, data
+		}
 		if bytes.Equal(line, endText) {
 			// Back up to the start of the line because armor expects to see the
 			// header line.
diff --git a/openpgp/clearsign/clearsign_test.go b/openpgp/clearsign/clearsign_test.go
index 406377c..2c09480 100644
--- a/openpgp/clearsign/clearsign_test.go
+++ b/openpgp/clearsign/clearsign_test.go
@@ -44,6 +44,12 @@
 	testParse(t, clearsignInput2, "\r\n\r\n(This message has a couple of blank lines at the start and end.)\r\n\r\n", "\n\n(This message has a couple of blank lines at the start and end.)\n\n\n")
 }
 
+func TestParseInvalid(t *testing.T) {
+	if b, _ := Decode(clearsignInput3); b != nil {
+		t.Fatal("decoded a bad clearsigned message without any error")
+	}
+}
+
 func TestParseWithNoNewlineAtEnd(t *testing.T) {
 	input := clearsignInput
 	input = input[:len(input)-len("trailing")-1]
@@ -161,6 +167,13 @@
 
 trailing`)
 
+var clearsignInput3 = []byte(`
+-----BEGIN PGP SIGNED MESSAGE-----
+Hash: SHA256
+
+(This message was truncated.)
+`)
+
 var signingKey = `-----BEGIN PGP PRIVATE KEY BLOCK-----
 Version: GnuPG v1.4.10 (GNU/Linux)