diff --git a/src/main/java/com/wolfssl/provider/jce/WolfCryptSignature.java b/src/main/java/com/wolfssl/provider/jce/WolfCryptSignature.java index 2017c7b8..929945af 100644 --- a/src/main/java/com/wolfssl/provider/jce/WolfCryptSignature.java +++ b/src/main/java/com/wolfssl/provider/jce/WolfCryptSignature.java @@ -952,6 +952,16 @@ protected synchronized boolean engineVerify(byte[] sigBytes) throw new SignatureException(e.getMessage()); } + /* RSA signature must be modulus length, check after digest so + * hash state is reset */ + if (this.keyType == KeyType.WC_RSA) { + int modLen = this.rsa.getEncryptSize(); + if (sigBytes == null || sigBytes.length != modLen) { + throw new SignatureException( + "Bad RSA signature length, expected " + modLen); + } + } + /* verify digest */ switch (this.keyType) { case WC_RSA: diff --git a/src/test/java/com/wolfssl/provider/jce/test/WolfCryptSignatureTest.java b/src/test/java/com/wolfssl/provider/jce/test/WolfCryptSignatureTest.java index 1f3400f8..6e344a5d 100644 --- a/src/test/java/com/wolfssl/provider/jce/test/WolfCryptSignatureTest.java +++ b/src/test/java/com/wolfssl/provider/jce/test/WolfCryptSignatureTest.java @@ -31,6 +31,7 @@ import org.junit.Assume; import java.util.ArrayList; +import java.util.Arrays; import java.util.concurrent.TimeUnit; import java.util.concurrent.Executors; import java.util.concurrent.ExecutorService; @@ -2336,6 +2337,55 @@ public void testRsaPssMultipleUpdates() } } + @Test + public void testRsaVerifyRejectsWrongLengthSignature() + throws Exception { + + byte[] data = "Everyone gets Friday off.".getBytes(); + String[] algs = { "SHA256withRSA", "RSASSA-PSS" }; + + for (String alg : algs) { + if (!enabledAlgos.contains(alg) || (alg.equals("RSASSA-PSS") && + !FeatureDetect.RsaPssEnabled())) { + continue; + } + + KeyPair pair = rsaPair; + assertNotNull(pair); + + Signature sig = Signature.getInstance(alg, "wolfJCE"); + if (alg.equals("RSASSA-PSS")) { + sig.setParameter(new PSSParameterSpec("SHA-256", "MGF1", + MGF1ParameterSpec.SHA256, 32, 1)); + } + sig.initSign(pair.getPrivate()); + sig.update(data); + byte[] good = sig.sign(); + + /* Extra leading zero, and first byte dropped */ + byte[] longer = new byte[good.length + 1]; + System.arraycopy(good, 0, longer, 1, good.length); + byte[] shorter = Arrays.copyOfRange(good, 1, good.length); + + sig.initVerify(pair.getPublic()); + for (byte[] bad : new byte[][] { longer, shorter }) { + sig.update(data); + try { + sig.verify(bad); + fail(alg + " should reject sig length " + bad.length); + + } catch (SignatureException e) { + /* expected */ + } + } + + /* Failed verify resets state, correct sig still verifies */ + sig.update(data); + assertTrue(alg + " verify after bad length failed", + sig.verify(good)); + } + } + @Test public void testECDSASignatureOIDMappings() throws NoSuchProviderException, NoSuchAlgorithmException,