crypto/rsa: reject invalid length PKCS#1v1.5 signatures

Per RFC 8017, reject signatures which are not the same length as the RSA
modulus. This matches the behavior of SignPKCS1v15 which properly left pads
the signatures it generates to the size of the modulus.

Fixes #21896

Change-Id: I2c42a0b24cf7fff158ece604b6f0c521a856d932
GitHub-Last-Rev: 6040f7990633630a0ad157cb17e016bb7db98a27
GitHub-Pull-Request: golang/go#38140
Reviewed-on: https://go-review.googlesource.com/c/go/+/226203
Reviewed-by: Filippo Valsorda <filippo@golang.org>
Run-TryBot: Filippo Valsorda <filippo@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
diff --git a/src/crypto/rsa/pkcs1v15.go b/src/crypto/rsa/pkcs1v15.go
index 37790ac..499242f 100644
--- a/src/crypto/rsa/pkcs1v15.go
+++ b/src/crypto/rsa/pkcs1v15.go
@@ -277,6 +277,13 @@
 		return ErrVerification
 	}
 
+	// RFC 8017 Section 8.2.2: If the length of the signature S is not k
+	// octets (where k is the length in octets of the RSA modulus n), output
+	// "invalid signature" and stop.
+	if k != len(sig) {
+		return ErrVerification
+	}
+
 	c := new(big.Int).SetBytes(sig)
 	m := encrypt(new(big.Int), pub, c)
 	em := leftPad(m.Bytes(), k)
diff --git a/src/crypto/rsa/pkcs1v15_test.go b/src/crypto/rsa/pkcs1v15_test.go
index 7e62560..26b8c5f 100644
--- a/src/crypto/rsa/pkcs1v15_test.go
+++ b/src/crypto/rsa/pkcs1v15_test.go
@@ -9,6 +9,7 @@
 	"crypto"
 	"crypto/rand"
 	"crypto/sha1"
+	"crypto/sha256"
 	"encoding/base64"
 	"encoding/hex"
 	"io"
@@ -296,3 +297,20 @@
 		fromBase10("94560208308847015747498523884063394671606671904944666360068158221458669711639"),
 	},
 }
+
+func TestShortPKCS1v15Signature(t *testing.T) {
+	pub := &PublicKey{
+		E: 65537,
+		N: fromBase10("8272693557323587081220342447407965471608219912416565371060697606400726784709760494166080686904546560026343451112103559482851304715739629410219358933351333"),
+	}
+	sig, err := hex.DecodeString("193a310d0dcf64094c6e3a00c8219b80ded70535473acff72c08e1222974bb24a93a535b1dc4c59fc0e65775df7ba2007dd20e9193f4c4025a18a7070aee93")
+	if err != nil {
+		t.Fatalf("failed to decode signature: %s", err)
+	}
+
+	h := sha256.Sum256([]byte("hello"))
+	err = VerifyPKCS1v15(pub, crypto.SHA256, h[:], sig)
+	if err == nil {
+		t.Fatal("VerifyPKCS1v15 accepted a truncated signature")
+	}
+}