PSSSigner verification improvements
enforce leading zero bits consistency requirement
explicitly zero when cipher output is short
package org.bouncycastle.crypto.signers;
import java.security.SecureRandom;
+import java.util.Arrays;
import org.bouncycastle.crypto.AsymmetricBlockCipher;
import org.bouncycastle.crypto.CipherParameters;
@@ -250,10 +251,11 @@ public void reset()
block[i] ^= dbMask[i];
}
- block[0] &= (0xff >> ((block.length * 8) - emBits));
-
System.arraycopy(h, 0, block, block.length - hLen - 1, hLen);
+ int firstByteMask = 0xff >>> ((block.length * 8) - emBits);
+
+ block[0] &= firstByteMask;
block[block.length - 1] = trailer;
byte[] b = cipher.processBlock(block, 0, block.length);
@@ -275,6 +277,7 @@ public boolean verifySignature(
try
{
byte[] b = cipher.processBlock(signature, 0, signature.length);
+ Arrays.fill(block, 0, block.length - b.length, (byte)0);
System.arraycopy(b, 0, block, block.length - b.length, b.length);
}
catch (Exception e)
@@ -282,7 +285,10 @@ public boolean verifySignature(
return false;
}
- if (block[block.length - 1] != trailer)
+ int firstByteMask = 0xff >>> ((block.length * 8) - emBits);
+
+ if ((block[0] & 0xff) != (block[0] & firstByteMask)
+ || block[block.length - 1] != trailer)
{
clearBlock(block);
return false;
@@ -295,7 +301,7 @@ public boolean verifySignature(
block[i] ^= dbMask[i];
}
- block[0] &= (0xff >> ((block.length * 8) - emBits));
+ block[0] &= firstByteMask;
for (int i = 0; i != block.length - hLen - sLen - 2; i++)
{
