Re: JDK11 & BC & TLS with RSASSA-PSS signature

Michael Schäfer <msknete-S0/[email protected]> Sun, 23 Dec 2018 09:52:54 +0100
Newsgroups gmane.comp.encryption.bouncy-castle.devel
Message-ID <[email protected]>
Hi David,

thanks a lot. Can you please also provide a link to the discussion?

Regards,

Michael

Am 22.12.2018 um 21:51 schrieb David Hook:
>
> We've filled a bug report. Discussions on-going.
>
> Regards,
>
> David.
>
> On 22/12/18 1:08 am, Michael Schäfer wrote:
>>
>> Hi David,
>>
>>
>> thanks for the clarification. Are you going to report the issue to 
>> JSSE or should I?
>>
>>
>> Kind regards,
>>
>> Michael
>>
>>
>> Am 21.12.2018 um 01:01 schrieb David Hook:
>>>
>>> There seem to be a few issues around setParameter() in Java 11.
>>>
>>> The convention on this has always been to call setParameter() first.
>>>
>>> We're going to treat this one as a bug, but I would suggest filing 
>>> this as either a "bug" or a "request for enhancement". I can 
>>> understand how the current maintainers of the JSSE would not be 
>>> aware of it, but the convention was established 20 years ago, and 
>>> the comment above the modified code in SignatureScheme.java makes 
>>> absolutely no sense. It looks like someone made the change will 
>>> trying to fix something else and got confused as to which change 
>>> actually solved the problem.
>>>
>>> Regards,
>>>
>>> David
>>>
>>> On 21/12/18 2:39 am, MSKnete-S0/[email protected] wrote:
>>>> Hello all,
>>>> I run into an issue, when using JDK11, BC and TLS with RSASSA-PSS 
>>>> signature scheme. From JDK10 to JDK11 the handshake classes have 
>>>> been changed and especially the JDK class 
>>>> 'src/java.base/share/classes/sun/security/ssl/SignatureScheme.java' 
>>>> calls the signer object in an unfavourable manner.
>>>> Instead of calling setParameter() first and then initSign(), JDK11 
>>>> does it the other way around (SignatureScheme.java, line 473/480).
>>>> Obviously, BC expect calling these two methods in the opposite 
>>>> order 
>>>> (org.bouncycastle.jcajce.provider.asymmetric.rsa.PSSSignatureSpi.java).
>>>> My remaining question: Who does it right? BC or JDK? Which side 
>>>> must be fixed?
>>>> I also attached a small sample which demonstrates the issue by 
>>>> comparing the BC implementation with the SunRsaSign implementation.
>>>> Further I found another mentioning of this behavior on the openjdk 
>>>> mailing list at 
>>>> http://mail.openjdk.java.net/pipermail/security-dev/2018-September/018265.html 
>>>> but sadly without any continuative response.
>>>> Any suggestion are welcome, to get RSASSA-PSS and BC working with 
>>>> JDK11.
>>>> Kind regards,
>>>> Michael
>>>>
>>>> $ java -version
>>>> openjdk version "11.0.1" 2018-10-16
>>>> OpenJDK Runtime Environment 18.9 (build 11.0.1+13)
>>>> OpenJDK 64-Bit Server VM 18.9 (build 11.0.1+13, mixed mode)
>>>> $ javac -cp bcprov-jdk15on-160.jar Demo.java
>>>> $ java -cp bcprov-jdk15on-160.jar Demo
>>>> BCprov: [...]
>>>> SunJCE: [...]
>>>> FAIL: Signatures are not equal!
>>>> ---------------------
>>>> Sample Source (Demo.java):
>>>> ---------------------
>>>> import java.security.KeyPair;
>>>> import java.security.KeyPairGenerator;
>>>> import java.security.PrivateKey;
>>>> import java.security.SecureRandom;
>>>> import java.security.Security;
>>>> import java.security.Signature;
>>>> import java.security.spec.MGF1ParameterSpec;
>>>> import java.security.spec.PSSParameterSpec;
>>>> import java.util.Arrays;
>>>>
>>>> public class Demo {
>>>>   public static void main(final String[] args) throws Exception {
>>>>     Security.insertProviderAt(new 
>>>> org.bouncycastle.jce.provider.BouncyCastleProvider(), 2);
>>>>     KeyPairGenerator keyPairGenerator = 
>>>> KeyPairGenerator.getInstance("RSA");
>>>>     keyPairGenerator.initialize(2048);
>>>>     KeyPair keyPair = keyPairGenerator.generateKeyPair();
>>>>     PrivateKey privateKey = keyPair.getPrivate();
>>>>     SecureRandom prngBC = SecureRandom.getInstance("SHA1PRNG");
>>>>     prngBC.setSeed(12345678L); //we need equal randomness, dont do 
>>>> this in production!
>>>>     Signature signerBC = Signature.getInstance("RSASSA-PSS", "BC");
>>>>     // this breaks BC, since setParameter() is invoked AFTER init()
>>>>     signerBC.initSign(privateKey, prngBC);
>>>>     signerBC.setParameter(new PSSParameterSpec("SHA-512", "MGF1", 
>>>> new MGF1ParameterSpec("SHA-512"), 64, 1));
>>>>     byte[] resultBC = signerBC.sign();
>>>>     SecureRandom prngSun = SecureRandom.getInstance("SHA1PRNG");
>>>>     prngSun.setSeed(12345678L); //we need equal randomness, dont do 
>>>> this in production!
>>>>     Signature signerSun = Signature.getInstance("RSASSA-PSS", 
>>>> "SunRsaSign");
>>>>     signerSun.initSign(privateKey, prngSun);
>>>>     signerSun.setParameter(new PSSParameterSpec("SHA-512", "MGF1", 
>>>> new MGF1ParameterSpec("SHA-512"), 64, 1));
>>>>     byte[] resultSun = signerSun.sign();
>>>>     System.out.println("BCprov: " + Arrays.toString(resultBC));
>>>>     System.out.println("SunJCE: " + Arrays.toString(resultSun));
>>>>     if (Arrays.equals(resultBC, resultSun)) {
>>>>       System.out.println("OK: Signatures are equal!");
>>>>     } else {
>>>>       System.err.println("FAIL: Signatures are not equal!");
>>>>     }
>>>>   }
>>>> }
>>>
>>>
>