]> Cypherpunks repositories - gostls13.git/commitdiff
encoding/pem: be stricter about the ending line.
authorAdam Langley <agl@golang.org>
Thu, 18 Aug 2016 23:20:44 +0000 (16:20 -0700)
committerAdam Langley <agl@golang.org>
Fri, 19 Aug 2016 16:29:44 +0000 (16:29 +0000)
Previously the code didn't check the type and final five dashes of the
ending line of a PEM block.

Fixes #16335.

Change-Id: Ia544e8739ea738d767cfe56c8d46204214ec0b5a
Reviewed-on: https://go-review.googlesource.com/27391
Run-TryBot: Adam Langley <agl@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
src/encoding/pem/pem.go
src/encoding/pem/pem_test.go

index ff2bed161adf7ca7c24768737ae7e094eef50525..fbf49997d5ed05f37fdf0820c2015c72b8a038d5 100644 (file)
@@ -119,19 +119,36 @@ func Decode(data []byte) (p *Block, rest []byte) {
                rest = next
        }
 
-       var endIndex int
+       var endIndex, endTrailerIndex int
+
        // If there were no headers, the END line might occur
        // immediately, without a leading newline.
        if len(p.Headers) == 0 && bytes.HasPrefix(rest, pemEnd[1:]) {
                endIndex = 0
+               endTrailerIndex = len(pemEnd) - 1
        } else {
                endIndex = bytes.Index(rest, pemEnd)
+               endTrailerIndex = endIndex + len(pemEnd)
        }
 
        if endIndex < 0 {
                return decodeError(data, rest)
        }
 
+       // After the "-----" of the ending line should be the same type and a
+       // final five dashes.
+       endTrailer := rest[endTrailerIndex:]
+       endTrailerLen := len(typeLine) + len(pemEndOfLine)
+       if len(endTrailer) < endTrailerLen {
+               return decodeError(data, rest)
+       }
+
+       endTrailer = endTrailer[:endTrailerLen]
+       if !bytes.HasPrefix(endTrailer, typeLine) ||
+               !bytes.HasSuffix(endTrailer, pemEndOfLine) {
+               return decodeError(data, rest)
+       }
+
        base64Data := removeWhitespace(rest[:endIndex])
        p.Bytes = make([]byte, base64.StdEncoding.DecodedLen(len(base64Data)))
        n, err := base64.StdEncoding.Decode(p.Bytes, base64Data)
index 958dbc1a3a6d1026e3bb0a6b976ee14b5b03d691..6321dec382008766f8865f10d48f8a3802ccd9fd 100644 (file)
@@ -78,6 +78,48 @@ func TestDecode(t *testing.T) {
        }
 }
 
+const pemTooFewEndingDashes = `
+-----BEGIN FOO-----
+dGVzdA==
+-----END FOO----`
+
+const pemWrongEndingType = `
+-----BEGIN FOO-----
+dGVzdA==
+-----END BAR-----`
+
+const pemMissingEndingSpace = `
+-----BEGIN FOO-----
+dGVzdA==
+-----ENDBAR-----`
+
+var badPEMTests = []struct {
+       name  string
+       input string
+}{
+       {
+               "too few trailing dashes",
+               pemTooFewEndingDashes,
+       },
+       {
+               "incorrect ending type",
+               pemWrongEndingType,
+       },
+       {
+               "missing ending space",
+               pemMissingEndingSpace,
+       },
+}
+
+func TestBadDecode(t *testing.T) {
+       for _, test := range badPEMTests {
+               result, _ := Decode([]byte(test.input))
+               if result != nil {
+                       t.Errorf("unexpected success while parsing %q", test.name)
+               }
+       }
+}
+
 func TestEncode(t *testing.T) {
        r := EncodeToMemory(privateKey2)
        if string(r) != pemPrivateKey2 {