Path: blob/master/test/jdk/java/security/Signature/Offsets.java
41152 views
/*1* Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223import java.security.*;24import java.security.spec.*;25import jdk.test.lib.RandomFactory;2627/*28* @test29* @bug 8050374 8181048 814629330* @key randomness31* @summary This test validates signature verification32* Signature.verify(byte[], int, int). The test uses RandomFactory to33* get random set of clear text data to sign. After the signature34* generation, the test tries to verify signature with the above API35* and passing in different signature offset (0, 33, 66, 99).36* @library /test/lib37* @build jdk.test.lib.RandomFactory38* @run main Offsets SUN NONEwithDSA39* @run main Offsets SUN SHA1withDSA40* @run main Offsets SUN SHA224withDSA41* @run main Offsets SUN SHA256withDSA42* @run main Offsets SunRsaSign SHA224withRSA43* @run main Offsets SunRsaSign SHA256withRSA44* @run main Offsets SunRsaSign SHA384withRSA45* @run main Offsets SunRsaSign SHA512withRSA46* @run main Offsets SunRsaSign SHA512/224withRSA47* @run main Offsets SunRsaSign SHA512/256withRSA48*/49public class Offsets {5051private final int size;52private final byte[] cleartext;53private final PublicKey pubkey;54private final Signature signature;55private final byte[] signed;5657private Offsets(Signature signature, PublicKey pubkey, PrivateKey privkey,58int size, byte[] cleartext) throws InvalidKeyException,59SignatureException {60System.out.println("Testing signature " + signature.getAlgorithm());61this.pubkey = pubkey;62this.signature = signature;63this.size = size;64this.cleartext = cleartext;6566String sigAlg = signature.getAlgorithm();67signature.initSign(privkey);68signature.update(cleartext, 0, size);69signed = signature.sign();70}7172int getDataSize() {73return size;74}7576int getSignatureLength() {77return signed.length;78}7980byte[] shiftSignData(int offset) {81byte[] testSignData = new byte[offset + signed.length];82System.arraycopy(signed, 0, testSignData, offset,83signed.length);84return testSignData;85}8687boolean verifySignature(byte[] sigData, int sigOffset, int sigLength,88int updateOffset, int updateLength)89throws InvalidKeyException, SignatureException {90signature.initVerify(pubkey);91signature.update(cleartext, updateOffset, updateLength);92return signature.verify(sigData, sigOffset, sigLength);93}9495static Offsets init(String provider, String algorithm)96throws NoSuchAlgorithmException, NoSuchProviderException,97InvalidKeyException, SignatureException {98// fill the cleartext data with random bytes99byte[] cleartext = new byte[100];100RandomFactory.getRandom().nextBytes(cleartext);101102// NONEwith requires input to be of 20 bytes103int size = algorithm.contains("NONEwith") ? 20 : 100;104105// create signature instance106Signature signature = Signature.getInstance(algorithm, provider);107108String keyAlgo;109int keySize = 2048;110if (algorithm.contains("RSA")) {111keyAlgo = "RSA";112} else if (algorithm.contains("ECDSA")) {113keyAlgo = "EC";114keySize = 256;115} else if (algorithm.contains("DSA")) {116keyAlgo = "DSA";117if (algorithm.startsWith("SHAwith") ||118algorithm.startsWith("SHA1with")) {119keySize = 1024;120}121} else {122throw new RuntimeException("Test doesn't support this signature "123+ "algorithm: " + algorithm);124}125KeyPairGenerator kpg = null;126// first try matching provider, fallback to most preferred if none available127try {128kpg = KeyPairGenerator.getInstance(keyAlgo, provider);129} catch (NoSuchAlgorithmException nsae) {130kpg = KeyPairGenerator.getInstance(keyAlgo);131}132kpg.initialize(keySize);133KeyPair kp = kpg.generateKeyPair();134PublicKey pubkey = kp.getPublic();135PrivateKey privkey = kp.getPrivate();136137return new Offsets(signature, pubkey, privkey, size, cleartext);138}139140public static void main(String[] args) throws NoSuchAlgorithmException,141InvalidKeyException, SignatureException {142if (args.length < 2) {143throw new RuntimeException("Wrong parameters");144}145146boolean result = true;147try {148Offsets test = init(args[0], args[1]);149150// We are trying 3 different offsets, data size has nothing to do151// with signature length152for (int chunk = 3; chunk > 0; chunk--) {153int signOffset = test.getDataSize() / chunk;154155System.out.println("Running test with offset " + signOffset);156byte[] signData = test.shiftSignData(signOffset);157158boolean success = test.verifySignature(signData, signOffset,159test.getSignatureLength(), 0, test.getDataSize());160161if (success) {162System.out.println("Successfully verified with offset "163+ signOffset);164} else {165System.out.println("Verification failed with offset "166+ signOffset);167result = false;168}169}170171// save signature to offset 0172byte[] signData = test.shiftSignData(0);173174// Negative tests175176// Test signature offset 0.177// Wrong test data will be passed to update,178// so signature verification should fail.179for (int chunk = 3; chunk > 0; chunk--) {180int dataOffset = (test.getDataSize() - 1) / chunk;181boolean success;182try {183success = test.verifySignature(signData, 0,184test.getSignatureLength(), dataOffset,185(test.getDataSize() - dataOffset));186} catch (SignatureException e) {187// Since we are trying different data size, it can throw188// SignatureException189success = false;190}191192if (!success) {193System.out.println("Signature verification failed "194+ "as expected, with data offset " + dataOffset195+ " and length "196+ (test.getDataSize() - dataOffset));197} else {198System.out.println("Signature verification "199+ "should not succeed, with data offset "200+ dataOffset + " and length "201+ (test.getDataSize() - dataOffset));202result = false;203}204}205206// Tests with manipulating offset and length207result &= Offsets.checkFailure(test, signData, -1,208test.getSignatureLength());209210result &= Offsets.checkFailure(test, signData, 0,211test.getSignatureLength() - 1);212213result &= Offsets.checkFailure(test, signData,214test.getSignatureLength() + 1, test.getSignatureLength());215216result &= Offsets.checkFailure(test, signData, 0,217test.getSignatureLength() + 1);218219result &= Offsets.checkFailure(test, signData, 0, 0);220221result &= Offsets.checkFailure(test, signData, 0, -1);222223result &= Offsets.checkFailure(test, signData,2242147483646, test.getSignatureLength());225226result &= Offsets.checkFailure(test, null, 0,227test.getSignatureLength());228} catch (NoSuchProviderException nspe) {229System.out.println("No such provider: " + nspe);230}231232if (!result) {233throw new RuntimeException("Some test cases failed");234}235}236237static boolean checkFailure(Offsets test, byte[] signData, int offset,238int length) {239boolean success;240try {241success = test.verifySignature(signData, offset, length, 0,242test.getDataSize());243} catch (IllegalArgumentException | SignatureException e) {244System.out.println("Expected exception: " + e);245success = false;246} catch (InvalidKeyException e) {247System.out.println("Unexpected exception: " + e);248return false;249}250251if (!success) {252System.out.println("Signature verification failed as expected, "253+ "with signature offset " + offset + " and length "254+ length);255return true;256} else {257System.out.println("Signature verification should not succeed, "258+ "with signature offset " + offset + " and length "259+ length);260return false;261}262}263264}265266267