From 4ec946ce95226b9e1b5258bdc3d46090d828d896 Mon Sep 17 00:00:00 2001 From: Adam Langley Date: Sun, 14 Jun 2015 16:41:31 -0700 Subject: [PATCH] crypto/x509: don't panic when decrypting invalid PEM data. If an encrypted PEM block contained ciphertext that was not a multiple of the block size then the code would panic. This change tests for that case and returns an error. Fixes #11215. Change-Id: I7b700f99e20810c4f545519b1e9d766b4640e8a7 Reviewed-on: https://go-review.googlesource.com/11097 Reviewed-by: Brad Fitzpatrick Reviewed-by: Russ Cox --- src/crypto/x509/pem_decrypt.go | 4 ++++ src/crypto/x509/pem_decrypt_test.go | 24 ++++++++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/src/crypto/x509/pem_decrypt.go b/src/crypto/x509/pem_decrypt.go index 1d2c1c6ef6..49ceadb436 100644 --- a/src/crypto/x509/pem_decrypt.go +++ b/src/crypto/x509/pem_decrypt.go @@ -144,6 +144,10 @@ func DecryptPEMBlock(b *pem.Block, password []byte) ([]byte, error) { return nil, err } + if len(b.Bytes)%block.BlockSize() != 0 { + return nil, errors.New("x509: encrypted PEM data is not a multiple of the block size") + } + data := make([]byte, len(b.Bytes)) dec := cipher.NewCBCDecrypter(block, iv) dec.CryptBlocks(data, b.Bytes) diff --git a/src/crypto/x509/pem_decrypt_test.go b/src/crypto/x509/pem_decrypt_test.go index 13e4700bdd..685d5ee156 100644 --- a/src/crypto/x509/pem_decrypt_test.go +++ b/src/crypto/x509/pem_decrypt_test.go @@ -9,6 +9,7 @@ import ( "crypto/rand" "encoding/base64" "encoding/pem" + "strings" "testing" ) @@ -221,3 +222,26 @@ AgkA8SEfu/2i3g0CCQDGNlXbBHX7kQIIK3Ww5o0cYbECCQDCimPb0dYGsQIIeQ7A jryIst8=`, }, } + +const incompleteBlockPEM = ` +-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: AES-128-CBC,74611ABC2571AF11B1BF9B69E62C89E7 + +6L8yXK2MTQUWBk4ZD6OvCiYp+mXyR1594TQ1K38MxGvDw5pwcDME2Lek8RrR5fd40P2XsL2Z4KKt +ai+OP1BZUetfK6AW4MiqB2FDyIdOAJ8XeWuZy21Wtsh8wPD6yYOFM/w7WZL8weX3Y0TSeG/T +-----END RSA PRIVATE KEY-----` + +func TestIncompleteBlock(t *testing.T) { + // incompleteBlockPEM contains ciphertext that is not a multiple of the + // block size. This previously panicked. See #11215. + block, _ := pem.Decode([]byte(incompleteBlockPEM)) + _, err := DecryptPEMBlock(block, []byte("foo")) + if err == nil { + t.Fatal("Bad PEM data decrypted successfully") + } + const expectedSubstr = "block size" + if e := err.Error(); !strings.Contains(e, expectedSubstr) { + t.Fatalf("Expected error containing %q but got: %q", expectedSubstr, e) + } +} -- 2.48.1