--- /dev/null 2018-05-11 10:42:23.849000000 -0700 +++ new/test/jdk/sun/security/rsa/pss/TestSigGenPSS.java 2018-05-11 15:11:02.432546600 -0700 @@ -0,0 +1,155 @@ +/* + * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.security.*; +import java.security.spec.*; +import java.security.interfaces.*; +import java.util.ArrayList; +import java.util.List; + +/* + * @test + * @bug 8146293 + * @summary Known Answer Tests based on NIST 186-3 at: + * @compile SigRecord.java + * @run main/othervm TestSigGenPSS + */ +public class TestSigGenPSS { + + private static final String[] testFiles = { + "SigGenPSS_186-3.txt", "SigGenPSS_186-3_TruncatedSHAs.txt" + }; + + static final class MyKnownRandomSrc extends SecureRandom { + final byte[] srcBytes; + int numBytes; + + MyKnownRandomSrc(String srcString) { + this.srcBytes = SigRecord.toByteArray(srcString); + this.numBytes = this.srcBytes.length; + } + @Override + public void nextBytes(byte[] bytes) { + if (bytes.length > numBytes) { + throw new RuntimeException("Not enough bytes, need " + + bytes.length + ", got " + numBytes); + } + System.arraycopy(this.srcBytes, this.srcBytes.length - numBytes, bytes, 0, bytes.length); + numBytes -= bytes.length; + } + + } + + public static void main(String[] args) throws Exception { + //for (Provider provider : Security.getProviders()) { + Provider p = Security.getProvider("SunRsaSign"); + Signature sig; + try { + sig = Signature.getInstance("RSASSA-PSS", p); + } catch (NoSuchAlgorithmException e) { + System.out.println("Skip testing RSASSA-PSS" + + " due to no support"); + return; + } + + boolean success = true; + for (String f : testFiles) { + System.out.println("[INPUT FILE " + f + "]"); + try { + success &= runTest(SigRecord.read(f), sig); + } catch (IOException e) { + System.out.println("Unexpected exception: " + e); + e.printStackTrace(System.out); + success = false; + } + } + + if (!success) { + throw new RuntimeException("One or more test failed"); + } + System.out.println("Test passed"); + } + + /* + * Run all the tests in the data list with specified algorithm + */ + static boolean runTest(List records, Signature sig) throws Exception { + boolean success = true; + KeyFactory kf = KeyFactory.getInstance("RSA", sig.getProvider()); + for (SigRecord sr : records) { + System.out.println("==Testing Record : " + sr + "=="); + PrivateKey privKey = kf.generatePrivate(sr.privKeySpec); + PublicKey pubKey = kf.generatePublic(sr.pubKeySpec); + success &= check(sig, privKey, pubKey, sr.testVectors); + System.out.println("==Done=="); + } + return success; + } + + /* + * Generate the signature, check against known values and verify. + */ + static boolean check(Signature sig, PrivateKey privKey, PublicKey pubKey, + List vectors) throws Exception { + + boolean success = true; + for (SigRecord.SigVector v : vectors) { + System.out.println("\tAgainst " + v.mdAlg); + byte[] msgBytes = SigRecord.toByteArray(v.msg); + byte[] expSigBytes = SigRecord.toByteArray(v.sig); + + MyKnownRandomSrc saltSrc = new MyKnownRandomSrc(v.salt); + sig.initSign(privKey, saltSrc); + PSSParameterSpec params = new PSSParameterSpec(v.mdAlg, "MGF1", + new MGF1ParameterSpec(v.mdAlg), saltSrc.numBytes, 1); + sig.setParameter(params); + sig.update(msgBytes); + byte[] actualSigBytes = sig.sign(); + + // Check if the supplied salt bytes are used up + if (saltSrc.numBytes != 0) { + throw new RuntimeException("Error: salt length mismatch! " + + saltSrc.numBytes + " bytes leftover"); + } + + success &= MessageDigest.isEqual(actualSigBytes, expSigBytes); + + if (!success) { + System.out.println("\tFailed:"); + System.out.println("\tSHAALG = " + v.mdAlg); + System.out.println("\tMsg = " + v.msg); + System.out.println("\tSalt = " + v.salt); + System.out.println("\tExpected Sig = " + v.sig); + System.out.println("\tActual Sig = " + SigRecord.toHexString(actualSigBytes)); + } else { + System.out.println("\t" + v.mdAlg + " Test Vector Passed"); + } + } + return success; + } +}