Path: blob/master/test/jdk/java/security/KeyAgreement/NegativeTest.java
41149 views
/*1* Copyright (c) 2018, 2021, 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*/2223/*24* @test25* @bug 820021926* @summary Negative tests for Key related Test with DiffieHellman, ECDH, XDH.27* It Tests,28* Use modified encoding while generating Public/Private Keys29* Short, long, unsupported keysize30* Invalid Algo names including Null31* Invalid provider names including Null32* Invalid curve names33* Invalid spec usage34* Arguments order <KeyExchangeAlgorithm> <Provider> <KeyGenAlgorithm>35* <keySize> <Curve*>36* @library /test/lib37* @run main NegativeTest DiffieHellman SunJCE DiffieHellman 102438* @run main NegativeTest ECDH SunEC EC 25639* @run main NegativeTest XDH SunEC XDH 255 X2551940* @run main NegativeTest XDH SunEC XDH 448 X44841*/42import java.math.BigInteger;43import java.security.InvalidAlgorithmParameterException;44import java.security.InvalidParameterException;45import java.security.KeyFactory;46import java.security.KeyPair;47import java.security.KeyPairGenerator;48import java.security.NoSuchAlgorithmException;49import java.security.NoSuchProviderException;50import java.security.Security;51import java.security.spec.InvalidKeySpecException;52import java.security.spec.NamedParameterSpec;53import java.security.spec.KeySpec;54import java.security.spec.PKCS8EncodedKeySpec;55import java.security.spec.X509EncodedKeySpec;56import java.security.spec.XECPrivateKeySpec;57import java.security.spec.XECPublicKeySpec;58import java.util.Arrays;59import java.util.HexFormat;60import javax.crypto.KeyAgreement;6162public class NegativeTest {6364public static void main(String[] args) throws Exception {6566String kaAlgo = args[0];67String provider = args[1];68String kpgAlgo = args[2];69int keySize = Integer.parseInt(args[3]);70String kpgInit = (args.length > 4) ? args[4] : args[2];71testModifiedKeyEncodingTest(provider, kpgAlgo, kpgInit);72testInvalidKeyLen(provider, kaAlgo, kpgAlgo, kpgInit);73testInvalidKpgAlgo(provider, kaAlgo, keySize);74testInvalidKaAlgo(provider, kpgAlgo, keySize);75testInvalidProvider(kaAlgo, kpgAlgo, keySize);76if (!kaAlgo.equals("DiffieHellman")) {77testNamedParameter(provider, kpgAlgo);78}79if (kaAlgo.equals("XDH")) {80testInvalidSpec(provider, kpgAlgo, kpgInit);81testInCompatibleSpec(provider, kpgAlgo, kpgInit);82}83}8485/**86* Generate keyPair based on KeyPairGenerator algorithm.87*/88private static KeyPair genKeyPair(String provider, String kpgAlgo,89String kpgInit) throws Exception {9091KeyPairGenerator kpg = KeyPairGenerator.getInstance(kpgAlgo,92Security.getProvider(provider));93switch (kpgInit) {94case "DiffieHellman":95kpg.initialize(512);96break;97case "EC":98kpg.initialize(256);99break;100case "X25519":101kpg.initialize(255);102break;103case "X448":104kpg.initialize(448);105break;106default:107throw new RuntimeException("Invalid Algo name " + kpgInit);108}109return kpg.generateKeyPair();110}111112private static void testModifiedKeyEncodingTest(String provider,113String kpgAlgo, String kpgInit) throws Exception {114115KeyFactory kf = KeyFactory.getInstance(kpgAlgo, provider);116KeyPair kp = genKeyPair(provider, kpgAlgo, kpgInit);117// Test modified PrivateKey encoding118byte[] encoded = kp.getPrivate().getEncoded();119byte[] modified = modifyEncoded(encoded);120PKCS8EncodedKeySpec priSpec = new PKCS8EncodedKeySpec(modified);121try {122// Generate PrivateKey with modified encoding123kf.generatePrivate(priSpec);124throw new RuntimeException(125"testModifiedKeyTest should fail but passed.");126} catch (InvalidKeySpecException e) {127System.out.printf("Expected InvalidKeySpecException for invalid "128+ "PrivateKey %s%n and modified encoding: %s, %s%n",129HexFormat.of().withUpperCase().formatHex(encoded),130HexFormat.of().withUpperCase().formatHex(modified), e.getMessage());131}132// Test modified PublicKey encoding133encoded = kp.getPublic().getEncoded();134modified = modifyEncoded(encoded);135X509EncodedKeySpec pubSpec = new X509EncodedKeySpec(modified);136try {137// Generate PublicKey with modified encoding138kf.generatePublic(pubSpec);139throw new RuntimeException(140"testModifiedKeyTest should fail but passed.");141} catch (InvalidKeySpecException e) {142System.out.printf("Expected InvalidKeySpecException for invalid "143+ "PublicKey %s%n and modified encoding: %s, %s%n",144HexFormat.of().withUpperCase().formatHex(encoded),145HexFormat.of().withUpperCase().formatHex(modified), e.getMessage());146}147}148149/**150* Test with all Invalid key length.151*/152private static void testInvalidKeyLen(String provider, String kaAlgo,153String kpgAlgo, String kpgInit) throws Exception {154155for (int keySize : selectInvalidKeylength(kpgInit)) {156try {157startKeyAgreement(provider, kaAlgo, kpgAlgo, keySize);158throw new RuntimeException(159"testInvalidKeyLen should fail but passed.");160} catch (InvalidParameterException e) {161System.out.printf("Expected InvalidParameterException for "162+ "keyLength: %s, %s%n", keySize, e.getMessage());163}164}165}166167/**168* Test with all Invalid KeyPairGenerator algorithms.169*/170private static void testInvalidKpgAlgo(String provider, String algo,171int keySize) throws Exception {172173for (String kpgAlgo : new String[]{null, " ", "", "NoSuchAlgorithm"}) {174try {175startKeyAgreement(provider, algo, kpgAlgo, keySize);176throw new RuntimeException(177"testInvalidKpgAlgo should fail but passed.");178} catch (NoSuchAlgorithmException e) {179System.out.printf("Expected NoSuchAlgorithmException for "180+ "KeyAgreement algo: %s, %s%n",181kpgAlgo, e.getMessage());182} catch (NullPointerException e) {183if (kpgAlgo == null) {184System.out.printf("Expected NullPointerException for "185+ "KeyPairGenerator algo: %s, %s%n",186kpgAlgo, e.getMessage());187continue;188}189throw new RuntimeException(190"Unknown failure in testInvalidKpgAlgo.");191}192}193}194195/**196* Test with all Invalid KeyAgreement algorithms.197*/198private static void testInvalidKaAlgo(String provider, String kpgAlgo,199int keySize) throws Exception {200201for (String algo : new String[]{null, " ", "", "NoSuchAlgorithm"}) {202try {203startKeyAgreement(provider, algo, kpgAlgo, keySize);204throw new RuntimeException(205"testInvalidKaAlgo should fail but passed.");206} catch (NoSuchAlgorithmException e) {207System.out.printf("Expected NoSuchAlgorithmException for "208+ "KeyAgreement algo: %s, %s%n", algo, e.getMessage());209} catch (NullPointerException e) {210if (algo == null) {211System.out.printf("Expected NullPointerException for "212+ "KeyAgreement algo: %s, %s%n",213algo, e.getMessage());214continue;215}216throw new RuntimeException(217"Unknown failure in testInvalidKaAlgo.");218}219}220}221222/**223* Test with all Invalid Provider names.224*/225private static void testInvalidProvider(String kaAlgo, String kpgAlgo,226int keySize) throws Exception {227228for (String provider : new String[]{null, " ", "", "NoSuchProvider"}) {229try {230startKeyAgreement(provider, kaAlgo, kpgAlgo, keySize);231throw new RuntimeException(232"testInvalidProvider should fail but passed.");233} catch (NoSuchProviderException e) {234System.out.printf("Expected NoSuchProviderException for "235+ "Provider: %s, %s%n", provider, e.getMessage());236} catch (IllegalArgumentException e) {237System.out.printf("Expected IllegalArgumentException for "238+ "Provider: %s, %s%n", provider, e.getMessage());239}240}241}242243/**244* Test for (in)valid curve names as argument to NamedParameterSpec245*/246private static void testNamedParameter(String provider, String kpgAlgo)247throws Exception {248249for (String name : new String[]{null, " ", "", "NoSuchCurve"}) {250try {251NamedParameterSpec spec = new NamedParameterSpec(name);252KeyPairGenerator kpg253= KeyPairGenerator.getInstance(kpgAlgo, provider);254kpg.initialize(spec);255kpg.generateKeyPair();256throw new RuntimeException(257"testNamedParameter should fail but passed.");258} catch (NullPointerException e) {259if (name == null) {260System.out.printf("Expected NullPointerException for "261+ "NamedParameterSpec name: %s, %s%n",262name, e.getMessage());263continue;264}265throw new RuntimeException(266"Unknown failure in testNamedParameter.");267} catch (InvalidAlgorithmParameterException e) {268System.out.printf("Expected InvalidAlgorithmParameterException"269+ " for NamedParameterSpec name: %s, %s%n",270name, e.getMessage());271}272}273}274275/**276* Test to generate Public/Private keys using (in)valid coordinate/scalar.277*/278private static void testInvalidSpec(String provider,279String kpgAlgo, String curve) throws Exception {280281NamedParameterSpec spec = new NamedParameterSpec(curve);282KeyFactory kf = KeyFactory.getInstance(kpgAlgo, provider);283int validLen = curve.equalsIgnoreCase("X448") ? 56 : 32;284for (byte[] scalarBytes : new byte[][]{null, new byte[]{},285new byte[32], new byte[56], new byte[65535]}) {286try {287KeySpec privateSpec = new XECPrivateKeySpec(spec, scalarBytes);288kf.generatePrivate(privateSpec);289if (scalarBytes.length != validLen) {290throw new RuntimeException(String.format("testInvalidSpec "291+ "should fail but passed when Scalar bytes length "292+ "!= %s for curve %s", validLen, curve));293}294} catch (NullPointerException e) {295if (scalarBytes == null) {296System.out.printf("Expected NullPointerException for "297+ "scalar: %s, %s%n", scalarBytes, e.getMessage());298continue;299}300throw new RuntimeException(e);301} catch (InvalidKeySpecException e) {302if (scalarBytes.length != validLen) {303System.out.printf("Expected InvalidKeySpecException for "304+ "scalar length %s and curve %s: %s%n",305scalarBytes.length, curve, e.getMessage());306continue;307}308throw new RuntimeException(e);309}310}311for (BigInteger coordinate : new BigInteger[]{null, BigInteger.ZERO,312BigInteger.ONE, new BigInteger("2").pow(255),313new BigInteger("2").pow(448)}) {314try {315KeySpec publicSpec = new XECPublicKeySpec(spec, coordinate);316kf.generatePublic(publicSpec);317} catch (NullPointerException e) {318if (coordinate == null) {319System.out.printf("Expected NullPointerException for "320+ "coordinate : %s, %s%n", coordinate,321e.getMessage());322continue;323}324throw new RuntimeException(e);325}326}327}328329private static void testInCompatibleSpec(String provider,330String kpgAlgo, String curve) throws Exception {331332int validLen = curve.equalsIgnoreCase("X448") ? 56 : 32;333NamedParameterSpec spec = new NamedParameterSpec(curve);334KeyFactory kf = KeyFactory.getInstance(kpgAlgo, provider);335KeySpec privateSpec = new XECPrivateKeySpec(spec, new byte[validLen]);336KeySpec publicSpec = new XECPublicKeySpec(spec, BigInteger.ONE);337try {338kf.generatePrivate(publicSpec);339throw new RuntimeException(340"testInCompatibleSpec should fail but passed.");341} catch (InvalidKeySpecException e) {342System.out.printf("Expected XECPublicKeySpec to XECPrivateKeySpec :"343+ " %s%n", e.getMessage());344}345try {346kf.generatePublic(privateSpec);347throw new RuntimeException(348"testInCompatibleSpec should fail but passed.");349} catch (InvalidKeySpecException e) {350System.out.printf("Expected XECPrivateKeySpec to XECPublicKeySpec :"351+ " %s%n", e.getMessage());352}353}354355/**356* Perform KeyAgreement operation.357*/358private static void startKeyAgreement(String provider, String kaAlgo,359String kpgAlgo, int keySize) throws Exception {360361KeyPairGenerator kpg = KeyPairGenerator.getInstance(kpgAlgo, provider);362kpg.initialize(keySize);363KeyPair kp = kpg.generateKeyPair();364KeyAgreement ka = KeyAgreement.getInstance(kaAlgo, provider);365ka.init(kp.getPrivate());366ka.doPhase(kp.getPublic(), true);367ka.generateSecret();368}369370/**371* Return manipulated encoded bytes.372*/373private static byte[] modifyEncoded(byte[] encoded) {374375byte[] copy = Arrays.copyOf(encoded, encoded.length);376for (int i = 0; i < copy.length; i++) {377copy[i] = (byte) ~copy[i];378}379return copy;380}381382/**383* Select invalid key sizes for different Key generation algorithms.384*/385private static int[] selectInvalidKeylength(String kpgInit) {386387int[] keySize = new int[]{};388switch (kpgInit) {389case "DiffieHellman":390keySize = new int[]{256, 513, 1023, 2176, 4032, 6400, 8200};391break;392case "EC":393keySize = new int[]{100, 300};394break;395case "X25519":396keySize = new int[]{100, 300};397break;398case "X448":399keySize = new int[]{100, 500};400break;401default:402throw new RuntimeException("Invalid Algo name " + kpgInit);403}404return keySize;405}406}407408409