undefect. CWE-407 — 63 sites patched across 27 ecosystems
Authors: russell@unturf.com · brackishbert@gmail.com · foxhop.net · TimeHexOn.com Patches, unit tests, benchmarks, whitepaper, and outreach briefs. Public domain — no copyright claimed. Use freely.
This commit is contained in:
commit
0a580b313d
70422 changed files with 17213626 additions and 0 deletions
408
test/jdk/java/security/KeyAgreement/NegativeTest.java
Normal file
408
test/jdk/java/security/KeyAgreement/NegativeTest.java
Normal file
|
|
@ -0,0 +1,408 @@
|
|||
/*
|
||||
* Copyright (c) 2018, 2024, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8200219
|
||||
* @summary Negative tests for Key related Test with DiffieHellman, ECDH, XDH.
|
||||
* It Tests,
|
||||
* Use modified encoding while generating Public/Private Keys
|
||||
* Short, long, unsupported keysize
|
||||
* Invalid Algo names including Null
|
||||
* Invalid provider names including Null
|
||||
* Invalid curve names
|
||||
* Invalid spec usage
|
||||
* Arguments order <KeyExchangeAlgorithm> <Provider> <KeyGenAlgorithm>
|
||||
* <keySize> <Curve*>
|
||||
* @library /test/lib
|
||||
* @run main NegativeTest DiffieHellman SunJCE DiffieHellman 2048
|
||||
* @run main NegativeTest ECDH SunEC EC 256
|
||||
* @run main NegativeTest XDH SunEC XDH 255 X25519
|
||||
* @run main NegativeTest XDH SunEC XDH 448 X448
|
||||
*/
|
||||
import java.math.BigInteger;
|
||||
import java.security.InvalidAlgorithmParameterException;
|
||||
import java.security.InvalidParameterException;
|
||||
import java.security.KeyFactory;
|
||||
import java.security.KeyPair;
|
||||
import java.security.KeyPairGenerator;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.NoSuchProviderException;
|
||||
import java.security.Security;
|
||||
import java.security.spec.InvalidKeySpecException;
|
||||
import java.security.spec.NamedParameterSpec;
|
||||
import java.security.spec.KeySpec;
|
||||
import java.security.spec.PKCS8EncodedKeySpec;
|
||||
import java.security.spec.X509EncodedKeySpec;
|
||||
import java.security.spec.XECPrivateKeySpec;
|
||||
import java.security.spec.XECPublicKeySpec;
|
||||
import java.util.Arrays;
|
||||
import java.util.HexFormat;
|
||||
import javax.crypto.KeyAgreement;
|
||||
import jdk.test.lib.security.SecurityUtils;
|
||||
|
||||
public class NegativeTest {
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
|
||||
String kaAlgo = args[0];
|
||||
String provider = System.getProperty("test.provider.name", args[1]);
|
||||
String kpgAlgo = args[2];
|
||||
int keySize = Integer.parseInt(args[3]);
|
||||
String kpgInit = (args.length > 4) ? args[4] : args[2];
|
||||
testModifiedKeyEncodingTest(provider, kpgAlgo, kpgInit);
|
||||
testInvalidKeyLen(provider, kaAlgo, kpgAlgo, kpgInit);
|
||||
testInvalidKpgAlgo(provider, kaAlgo, keySize);
|
||||
testInvalidKaAlgo(provider, kpgAlgo, keySize);
|
||||
testInvalidProvider(kaAlgo, kpgAlgo, keySize);
|
||||
if (!kaAlgo.equals("DiffieHellman")) {
|
||||
testNamedParameter(provider, kpgAlgo);
|
||||
}
|
||||
if (kaAlgo.equals("XDH")) {
|
||||
testInvalidSpec(provider, kpgAlgo, kpgInit);
|
||||
testInCompatibleSpec(provider, kpgAlgo, kpgInit);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate keyPair based on KeyPairGenerator algorithm.
|
||||
*/
|
||||
private static KeyPair genKeyPair(String provider, String kpgAlgo,
|
||||
String kpgInit) throws Exception {
|
||||
|
||||
KeyPairGenerator kpg = KeyPairGenerator.getInstance(kpgAlgo,
|
||||
Security.getProvider(provider));
|
||||
switch (kpgInit) {
|
||||
case "DiffieHellman":
|
||||
kpg.initialize(SecurityUtils.getTestKeySize(kpgInit));
|
||||
break;
|
||||
case "EC":
|
||||
kpg.initialize(256);
|
||||
break;
|
||||
case "X25519":
|
||||
kpg.initialize(255);
|
||||
break;
|
||||
case "X448":
|
||||
kpg.initialize(448);
|
||||
break;
|
||||
default:
|
||||
throw new RuntimeException("Invalid Algo name " + kpgInit);
|
||||
}
|
||||
return kpg.generateKeyPair();
|
||||
}
|
||||
|
||||
private static void testModifiedKeyEncodingTest(String provider,
|
||||
String kpgAlgo, String kpgInit) throws Exception {
|
||||
|
||||
KeyFactory kf = KeyFactory.getInstance(kpgAlgo, provider);
|
||||
KeyPair kp = genKeyPair(provider, kpgAlgo, kpgInit);
|
||||
// Test modified PrivateKey encoding
|
||||
byte[] encoded = kp.getPrivate().getEncoded();
|
||||
byte[] modified = modifyEncoded(encoded);
|
||||
PKCS8EncodedKeySpec priSpec = new PKCS8EncodedKeySpec(modified);
|
||||
try {
|
||||
// Generate PrivateKey with modified encoding
|
||||
kf.generatePrivate(priSpec);
|
||||
throw new RuntimeException(
|
||||
"testModifiedKeyTest should fail but passed.");
|
||||
} catch (InvalidKeySpecException e) {
|
||||
System.out.printf("Expected InvalidKeySpecException for invalid "
|
||||
+ "PrivateKey %s%n and modified encoding: %s, %s%n",
|
||||
HexFormat.of().withUpperCase().formatHex(encoded),
|
||||
HexFormat.of().withUpperCase().formatHex(modified), e.getMessage());
|
||||
}
|
||||
// Test modified PublicKey encoding
|
||||
encoded = kp.getPublic().getEncoded();
|
||||
modified = modifyEncoded(encoded);
|
||||
X509EncodedKeySpec pubSpec = new X509EncodedKeySpec(modified);
|
||||
try {
|
||||
// Generate PublicKey with modified encoding
|
||||
kf.generatePublic(pubSpec);
|
||||
throw new RuntimeException(
|
||||
"testModifiedKeyTest should fail but passed.");
|
||||
} catch (InvalidKeySpecException e) {
|
||||
System.out.printf("Expected InvalidKeySpecException for invalid "
|
||||
+ "PublicKey %s%n and modified encoding: %s, %s%n",
|
||||
HexFormat.of().withUpperCase().formatHex(encoded),
|
||||
HexFormat.of().withUpperCase().formatHex(modified), e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test with all Invalid key length.
|
||||
*/
|
||||
private static void testInvalidKeyLen(String provider, String kaAlgo,
|
||||
String kpgAlgo, String kpgInit) throws Exception {
|
||||
|
||||
for (int keySize : selectInvalidKeylength(kpgInit)) {
|
||||
try {
|
||||
startKeyAgreement(provider, kaAlgo, kpgAlgo, keySize);
|
||||
throw new RuntimeException(
|
||||
"testInvalidKeyLen should fail but passed.");
|
||||
} catch (InvalidParameterException e) {
|
||||
System.out.printf("Expected InvalidParameterException for "
|
||||
+ "keyLength: %s, %s%n", keySize, e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test with all Invalid KeyPairGenerator algorithms.
|
||||
*/
|
||||
private static void testInvalidKpgAlgo(String provider, String algo,
|
||||
int keySize) throws Exception {
|
||||
|
||||
for (String kpgAlgo : new String[]{null, " ", "", "NoSuchAlgorithm"}) {
|
||||
try {
|
||||
startKeyAgreement(provider, algo, kpgAlgo, keySize);
|
||||
throw new RuntimeException(
|
||||
"testInvalidKpgAlgo should fail but passed.");
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
System.out.printf("Expected NoSuchAlgorithmException for "
|
||||
+ "KeyAgreement algo: %s, %s%n",
|
||||
kpgAlgo, e.getMessage());
|
||||
} catch (NullPointerException e) {
|
||||
if (kpgAlgo == null) {
|
||||
System.out.printf("Expected NullPointerException for "
|
||||
+ "KeyPairGenerator algo: %s, %s%n",
|
||||
kpgAlgo, e.getMessage());
|
||||
continue;
|
||||
}
|
||||
throw new RuntimeException(
|
||||
"Unknown failure in testInvalidKpgAlgo.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test with all Invalid KeyAgreement algorithms.
|
||||
*/
|
||||
private static void testInvalidKaAlgo(String provider, String kpgAlgo,
|
||||
int keySize) throws Exception {
|
||||
|
||||
for (String algo : new String[]{null, " ", "", "NoSuchAlgorithm"}) {
|
||||
try {
|
||||
startKeyAgreement(provider, algo, kpgAlgo, keySize);
|
||||
throw new RuntimeException(
|
||||
"testInvalidKaAlgo should fail but passed.");
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
System.out.printf("Expected NoSuchAlgorithmException for "
|
||||
+ "KeyAgreement algo: %s, %s%n", algo, e.getMessage());
|
||||
} catch (NullPointerException e) {
|
||||
if (algo == null) {
|
||||
System.out.printf("Expected NullPointerException for "
|
||||
+ "KeyAgreement algo: %s, %s%n",
|
||||
algo, e.getMessage());
|
||||
continue;
|
||||
}
|
||||
throw new RuntimeException(
|
||||
"Unknown failure in testInvalidKaAlgo.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test with all Invalid Provider names.
|
||||
*/
|
||||
private static void testInvalidProvider(String kaAlgo, String kpgAlgo,
|
||||
int keySize) throws Exception {
|
||||
|
||||
for (String provider : new String[]{null, " ", "", "NoSuchProvider"}) {
|
||||
try {
|
||||
startKeyAgreement(provider, kaAlgo, kpgAlgo, keySize);
|
||||
throw new RuntimeException(
|
||||
"testInvalidProvider should fail but passed.");
|
||||
} catch (NoSuchProviderException e) {
|
||||
System.out.printf("Expected NoSuchProviderException for "
|
||||
+ "Provider: %s, %s%n", provider, e.getMessage());
|
||||
} catch (IllegalArgumentException e) {
|
||||
System.out.printf("Expected IllegalArgumentException for "
|
||||
+ "Provider: %s, %s%n", provider, e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for (in)valid curve names as argument to NamedParameterSpec
|
||||
*/
|
||||
private static void testNamedParameter(String provider, String kpgAlgo)
|
||||
throws Exception {
|
||||
|
||||
for (String name : new String[]{null, " ", "", "NoSuchCurve"}) {
|
||||
try {
|
||||
NamedParameterSpec spec = new NamedParameterSpec(name);
|
||||
KeyPairGenerator kpg
|
||||
= KeyPairGenerator.getInstance(kpgAlgo, provider);
|
||||
kpg.initialize(spec);
|
||||
kpg.generateKeyPair();
|
||||
throw new RuntimeException(
|
||||
"testNamedParameter should fail but passed.");
|
||||
} catch (NullPointerException e) {
|
||||
if (name == null) {
|
||||
System.out.printf("Expected NullPointerException for "
|
||||
+ "NamedParameterSpec name: %s, %s%n",
|
||||
name, e.getMessage());
|
||||
continue;
|
||||
}
|
||||
throw new RuntimeException(
|
||||
"Unknown failure in testNamedParameter.");
|
||||
} catch (InvalidAlgorithmParameterException e) {
|
||||
System.out.printf("Expected InvalidAlgorithmParameterException"
|
||||
+ " for NamedParameterSpec name: %s, %s%n",
|
||||
name, e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test to generate Public/Private keys using (in)valid coordinate/scalar.
|
||||
*/
|
||||
private static void testInvalidSpec(String provider,
|
||||
String kpgAlgo, String curve) throws Exception {
|
||||
|
||||
NamedParameterSpec spec = new NamedParameterSpec(curve);
|
||||
KeyFactory kf = KeyFactory.getInstance(kpgAlgo, provider);
|
||||
int validLen = curve.equalsIgnoreCase("X448") ? 56 : 32;
|
||||
for (byte[] scalarBytes : new byte[][]{null, new byte[]{},
|
||||
new byte[32], new byte[56], new byte[65535]}) {
|
||||
try {
|
||||
KeySpec privateSpec = new XECPrivateKeySpec(spec, scalarBytes);
|
||||
kf.generatePrivate(privateSpec);
|
||||
if (scalarBytes.length != validLen) {
|
||||
throw new RuntimeException(String.format("testInvalidSpec "
|
||||
+ "should fail but passed when Scalar bytes length "
|
||||
+ "!= %s for curve %s", validLen, curve));
|
||||
}
|
||||
} catch (NullPointerException e) {
|
||||
if (scalarBytes == null) {
|
||||
System.out.printf("Expected NullPointerException for "
|
||||
+ "scalar: %s, %s%n", scalarBytes, e.getMessage());
|
||||
continue;
|
||||
}
|
||||
throw new RuntimeException(e);
|
||||
} catch (InvalidKeySpecException e) {
|
||||
if (scalarBytes.length != validLen) {
|
||||
System.out.printf("Expected InvalidKeySpecException for "
|
||||
+ "scalar length %s and curve %s: %s%n",
|
||||
scalarBytes.length, curve, e.getMessage());
|
||||
continue;
|
||||
}
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
for (BigInteger coordinate : new BigInteger[]{null, BigInteger.ZERO,
|
||||
BigInteger.ONE, new BigInteger("2").pow(255),
|
||||
new BigInteger("2").pow(448)}) {
|
||||
try {
|
||||
KeySpec publicSpec = new XECPublicKeySpec(spec, coordinate);
|
||||
kf.generatePublic(publicSpec);
|
||||
} catch (NullPointerException e) {
|
||||
if (coordinate == null) {
|
||||
System.out.printf("Expected NullPointerException for "
|
||||
+ "coordinate : %s, %s%n", coordinate,
|
||||
e.getMessage());
|
||||
continue;
|
||||
}
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void testInCompatibleSpec(String provider,
|
||||
String kpgAlgo, String curve) throws Exception {
|
||||
|
||||
int validLen = curve.equalsIgnoreCase("X448") ? 56 : 32;
|
||||
NamedParameterSpec spec = new NamedParameterSpec(curve);
|
||||
KeyFactory kf = KeyFactory.getInstance(kpgAlgo, provider);
|
||||
KeySpec privateSpec = new XECPrivateKeySpec(spec, new byte[validLen]);
|
||||
KeySpec publicSpec = new XECPublicKeySpec(spec, BigInteger.ONE);
|
||||
try {
|
||||
kf.generatePrivate(publicSpec);
|
||||
throw new RuntimeException(
|
||||
"testInCompatibleSpec should fail but passed.");
|
||||
} catch (InvalidKeySpecException e) {
|
||||
System.out.printf("Expected XECPublicKeySpec to XECPrivateKeySpec :"
|
||||
+ " %s%n", e.getMessage());
|
||||
}
|
||||
try {
|
||||
kf.generatePublic(privateSpec);
|
||||
throw new RuntimeException(
|
||||
"testInCompatibleSpec should fail but passed.");
|
||||
} catch (InvalidKeySpecException e) {
|
||||
System.out.printf("Expected XECPrivateKeySpec to XECPublicKeySpec :"
|
||||
+ " %s%n", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform KeyAgreement operation.
|
||||
*/
|
||||
private static void startKeyAgreement(String provider, String kaAlgo,
|
||||
String kpgAlgo, int keySize) throws Exception {
|
||||
|
||||
KeyPairGenerator kpg = KeyPairGenerator.getInstance(kpgAlgo, provider);
|
||||
kpg.initialize(keySize);
|
||||
KeyPair kp = kpg.generateKeyPair();
|
||||
KeyAgreement ka = KeyAgreement.getInstance(kaAlgo, provider);
|
||||
ka.init(kp.getPrivate());
|
||||
ka.doPhase(kp.getPublic(), true);
|
||||
ka.generateSecret();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return manipulated encoded bytes.
|
||||
*/
|
||||
private static byte[] modifyEncoded(byte[] encoded) {
|
||||
|
||||
byte[] copy = Arrays.copyOf(encoded, encoded.length);
|
||||
for (int i = 0; i < copy.length; i++) {
|
||||
copy[i] = (byte) ~copy[i];
|
||||
}
|
||||
return copy;
|
||||
}
|
||||
|
||||
/**
|
||||
* Select invalid key sizes for different Key generation algorithms.
|
||||
*/
|
||||
private static int[] selectInvalidKeylength(String kpgInit) {
|
||||
|
||||
int[] keySize = new int[]{};
|
||||
switch (kpgInit) {
|
||||
case "DiffieHellman":
|
||||
keySize = new int[]{256, 513, 1023, 2176, 4032, 6400, 8200};
|
||||
break;
|
||||
case "EC":
|
||||
keySize = new int[]{100, 300};
|
||||
break;
|
||||
case "X25519":
|
||||
keySize = new int[]{100, 300};
|
||||
break;
|
||||
case "X448":
|
||||
keySize = new int[]{100, 500};
|
||||
break;
|
||||
default:
|
||||
throw new RuntimeException("Invalid Algo name " + kpgInit);
|
||||
}
|
||||
return keySize;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue