Revert "Merge Conscrypt Upstream master."
This reverts commit 1e24ad219694fc0f449451a039788e147ff85e71.
Reason for revert: Need to resubmit this as multiple CLs to allow selective cherry-picking to Mainline branches.
Change-Id: Idb762f8469618b83ca17c09fd84bd19edbc8ed67
diff --git a/Android.bp b/Android.bp
index b0d7754..bc1be6a 100644
--- a/Android.bp
+++ b/Android.bp
@@ -100,6 +100,7 @@
"common/src/jni/main/cpp/conscrypt/jniutil.cc",
"common/src/jni/main/cpp/conscrypt/native_crypto.cc",
"common/src/jni/main/cpp/conscrypt/netutil.cc",
+ "common/src/jni/main/cpp/conscrypt/trace.cc",
],
header_libs: ["jni_headers"],
diff --git a/android/CMakeLists.txt b/android/CMakeLists.txt
index 7b5e7ca..064e12a 100644
--- a/android/CMakeLists.txt
+++ b/android/CMakeLists.txt
@@ -6,6 +6,7 @@
../common/src/jni/main/cpp/conscrypt/jniutil.cc
../common/src/jni/main/cpp/conscrypt/native_crypto.cc
../common/src/jni/main/cpp/conscrypt/netutil.cc
+ ../common/src/jni/main/cpp/conscrypt/trace.cc
)
include_directories(../common/src/jni/main/include/
../common/src/jni/unbundled/include/
diff --git a/android/proguard-rules.pro b/android/proguard-rules.pro
index 8f7b25c..e966c43 100644
--- a/android/proguard-rules.pro
+++ b/android/proguard-rules.pro
@@ -24,6 +24,4 @@
-dontwarn com.android.org.conscrypt.AbstractConscryptSocket
-dontwarn com.android.org.conscrypt.ConscryptFileDescriptorSocket
-dontwarn com.android.org.conscrypt.OpenSSLSocketImpl
--dontwarn com.android.org.conscrypt.SSLParametersImpl
-dontwarn org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl
--dontwarn org.apache.harmony.xnet.provider.jsse.SSLParametersImpl
diff --git a/build.gradle b/build.gradle
index 52afe3c..08b9ebd 100644
--- a/build.gradle
+++ b/build.gradle
@@ -110,7 +110,7 @@
// Test dependencies.
bouncycastle_apis: 'org.bouncycastle:bcpkix-jdk15on:1.63',
bouncycastle_provider: 'org.bouncycastle:bcprov-jdk15on:1.63',
- junit : 'junit:junit:4.13.2',
+ junit : 'junit:junit:4.12',
mockito: 'org.mockito:mockito-core:2.28.2',
truth : 'com.google.truth:truth:1.0',
diff --git a/common/src/jni/main/cpp/conscrypt/native_crypto.cc b/common/src/jni/main/cpp/conscrypt/native_crypto.cc
index cd305e4..f1e3ff5 100644
--- a/common/src/jni/main/cpp/conscrypt/native_crypto.cc
+++ b/common/src/jni/main/cpp/conscrypt/native_crypto.cc
@@ -10286,50 +10286,6 @@
return FIPS_mode();
}
-/**
- * Scrypt support
- */
-
-static jbyteArray NativeCrypto_Scrypt_generate_key(JNIEnv* env, jclass, jbyteArray password, jbyteArray salt,
- jint n, jint r, jint p, jint key_len) {
- CHECK_ERROR_QUEUE_ON_RETURN;
- JNI_TRACE("Scrypt_generate_key(%p, %p, %d, %d, %d, %d)", password, salt, n, r, p, key_len);
-
- if (password == nullptr) {
- conscrypt::jniutil::throwNullPointerException(env, "password == null");
- JNI_TRACE("Scrypt_generate_key() => password == null");
- return nullptr;
- }
- if (salt == nullptr) {
- conscrypt::jniutil::throwNullPointerException(env, "salt == null");
- JNI_TRACE("Scrypt_generate_key() => salt == null");
- return nullptr;
- }
-
- jbyteArray key_bytes = env->NewByteArray(static_cast<jsize>(key_len));
- ScopedByteArrayRW out_key(env, key_bytes);
- if (out_key.get() == nullptr) {
- conscrypt::jniutil::throwNullPointerException(env, "out_key == null");
- JNI_TRACE("Scrypt_generate_key() => out_key == null");
- return nullptr;
- }
-
- size_t memory_limit = 1u << 29;
- ScopedByteArrayRO password_bytes(env, password);
- ScopedByteArrayRO salt_bytes(env, salt);
-
- int result = EVP_PBE_scrypt(reinterpret_cast<const char*>(password_bytes.get()), password_bytes.size(),
- reinterpret_cast<const uint8_t*>(salt_bytes.get()), salt_bytes.size(),
- n, r, p, memory_limit,
- reinterpret_cast<uint8_t*>(out_key.get()), key_len);
-
- if (result <= 0) {
- conscrypt::jniutil::throwExceptionFromBoringSSLError(env, "Scrypt_generate_key");
- return nullptr;
- }
- return key_bytes;
-}
-
// TESTING METHODS BEGIN
static int NativeCrypto_BIO_read(JNIEnv* env, jclass, jlong bioRef, jbyteArray outputJavaBytes) {
@@ -10791,7 +10747,6 @@
CONSCRYPT_NATIVE_METHOD(ENGINE_SSL_force_read, "(J" REF_SSL SSL_CALLBACKS ")V"),
CONSCRYPT_NATIVE_METHOD(ENGINE_SSL_shutdown, "(J" REF_SSL SSL_CALLBACKS ")V"),
CONSCRYPT_NATIVE_METHOD(usesBoringSSL_FIPS_mode, "()Z"),
- CONSCRYPT_NATIVE_METHOD(Scrypt_generate_key, "([B[BIIII)[B"),
// Used for testing only.
CONSCRYPT_NATIVE_METHOD(BIO_read, "(J[B)I"),
diff --git a/common/src/jni/main/cpp/conscrypt/trace.cc b/common/src/jni/main/cpp/conscrypt/trace.cc
new file mode 100644
index 0000000..858545f
--- /dev/null
+++ b/common/src/jni/main/cpp/conscrypt/trace.cc
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <conscrypt/trace.h>
+
+namespace conscrypt {
+namespace trace {
+
+const bool kWithJniTrace = false;
+const bool kWithJniTraceMd = false;
+const bool kWithJniTraceData = false;
+const bool kWithJniTracePackets = false;
+const bool kWithJniTraceKeys = false;
+const std::size_t kWithJniTraceDataChunkSize = 512;
+
+} // namespace trace
+} // namespace conscrypt
diff --git a/common/src/jni/main/include/conscrypt/trace.h b/common/src/jni/main/include/conscrypt/trace.h
index 1a3fceb..766214b 100644
--- a/common/src/jni/main/include/conscrypt/trace.h
+++ b/common/src/jni/main/include/conscrypt/trace.h
@@ -24,11 +24,9 @@
namespace conscrypt {
namespace trace {
-constexpr bool kWithJniTrace = false;
-constexpr bool kWithJniTraceMd = false;
-constexpr bool kWithJniTraceData = false;
-// Don't overwhelm logcat when tracing data.
-constexpr std::size_t kWithJniTraceDataChunkSize = 512;
+extern const bool kWithJniTrace;
+extern const bool kWithJniTraceMd;
+extern const bool kWithJniTraceData;
/*
* To print create a pcap-style dump you can take the log output and
@@ -40,7 +38,7 @@
* awk "match(\$0,/ssl=$address SSL_DATA: (.*)\$/,a){print a[1]}" | text2pcap -T 443,1337 -t
* '%s.' -n -D - $address.pcapng
*/
-constexpr bool kWithJniTracePackets = false;
+extern const bool kWithJniTracePackets;
/*
* How to use this for debugging with Wireshark:
@@ -59,7 +57,10 @@
* 4. Follow the stream that corresponds to the desired "Session-ID" in
* the Server Hello.
*/
- constexpr bool kWithJniTraceKeys = false;
+extern const bool kWithJniTraceKeys;
+
+// don't overwhelm logcat
+extern const std::size_t kWithJniTraceDataChunkSize;
} // namespace trace
} // namespace conscrypt
diff --git a/common/src/main/java/org/conscrypt/NativeCrypto.java b/common/src/main/java/org/conscrypt/NativeCrypto.java
index a2a6438..b5f80fb 100644
--- a/common/src/main/java/org/conscrypt/NativeCrypto.java
+++ b/common/src/main/java/org/conscrypt/NativeCrypto.java
@@ -1444,11 +1444,6 @@
throws IOException;
/**
- * Generates a key from a password and salt using Scrypt.
- */
- static native byte[] Scrypt_generate_key(byte[] password, byte[] salt, int n, int r, int p, int key_len);
-
- /**
* Return {@code true} if BoringSSL has been built in FIPS mode.
*/
static native boolean usesBoringSSL_FIPS_mode();
diff --git a/common/src/main/java/org/conscrypt/OpenSSLProvider.java b/common/src/main/java/org/conscrypt/OpenSSLProvider.java
index 9fc5226..607ae1e 100644
--- a/common/src/main/java/org/conscrypt/OpenSSLProvider.java
+++ b/common/src/main/java/org/conscrypt/OpenSSLProvider.java
@@ -211,9 +211,6 @@
/* == SecretKeyFactory == */
put("SecretKeyFactory.DESEDE", PREFIX + "DESEDESecretKeyFactory");
put("Alg.Alias.SecretKeyFactory.TDEA", "DESEDE");
- put("SecretKeyFactory.SCRYPT", PREFIX + "ScryptSecretKeyFactory");
- put("Alg.Alias.SecretKeyFactory.1.3.6.1.4.1.11591.4.11", "SCRYPT");
- put("Alg.Alias.SecretKeyFactory.OID.1.3.6.1.4.1.11591.4.11", "SCRYPT");
/* == KeyAgreement == */
putECDHKeyAgreementImplClass("OpenSSLECDHKeyAgreement");
diff --git a/common/src/main/java/org/conscrypt/ScryptKeySpec.java b/common/src/main/java/org/conscrypt/ScryptKeySpec.java
deleted file mode 100644
index 809459f..0000000
--- a/common/src/main/java/org/conscrypt/ScryptKeySpec.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.security.spec.KeySpec;
-
-/**
- * Mirrors the <a
- * href="https://javadoc.io/static/org.bouncycastle/bcprov-jdk15on/1.68/org/bouncycastle/jcajce/spec/ScryptKeySpec.html">class
- * of the same name</a> from BouncyCastle.
- */
-public class ScryptKeySpec implements KeySpec {
- private final char[] password;
- private final byte[] salt;
- private final int costParameter;
- private final int blockSize;
- private final int parallelizationParameter;
- private final int keyOutputBits;
-
- public ScryptKeySpec(
- char[] password,
- byte[] salt,
- int costParameter,
- int blockSize,
- int parallelizationParameter,
- int keyOutputBits) {
- this.password = password;
- this.salt = salt;
- this.costParameter = costParameter;
- this.blockSize = blockSize;
- this.parallelizationParameter = parallelizationParameter;
- this.keyOutputBits = keyOutputBits;
- }
-
- public char[] getPassword() {
- return password;
- }
-
- public byte[] getSalt() {
- return salt;
- }
-
- public int getCostParameter() {
- return costParameter;
- }
-
- public int getBlockSize() {
- return blockSize;
- }
-
- public int getParallelizationParameter() {
- return parallelizationParameter;
- }
-
- public int getKeyLength() {
- return keyOutputBits;
- }
-}
diff --git a/common/src/main/java/org/conscrypt/ScryptSecretKeyFactory.java b/common/src/main/java/org/conscrypt/ScryptSecretKeyFactory.java
deleted file mode 100644
index 9714bcf..0000000
--- a/common/src/main/java/org/conscrypt/ScryptSecretKeyFactory.java
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.UnsupportedEncodingException;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.security.InvalidKeyException;
-import java.security.spec.InvalidKeySpecException;
-import java.security.spec.KeySpec;
-import javax.crypto.SecretKey;
-import javax.crypto.SecretKeyFactorySpi;
-
-@Internal
-public class ScryptSecretKeyFactory extends SecretKeyFactorySpi {
-
- @Override
- protected SecretKey engineGenerateSecret(KeySpec inKeySpec) throws InvalidKeySpecException {
-
- char[] password;
- byte[] salt;
- int n, r, p, keyOutputBits;
-
- if (inKeySpec instanceof ScryptKeySpec) {
- ScryptKeySpec spec = (ScryptKeySpec) inKeySpec;
- password = spec.getPassword();
- salt = spec.getSalt();
- n = spec.getCostParameter();
- r = spec.getBlockSize();
- p = spec.getParallelizationParameter();
- keyOutputBits = spec.getKeyLength();
- } else {
- // Extract parameters from any `KeySpec` that has getters with the correct name. This
- // allows, for example, code to use BouncyCastle's KeySpec with the Conscrypt provider.
- try {
- password = (char[]) getValue(inKeySpec, "getPassword");
- salt = (byte[]) getValue(inKeySpec, "getSalt");
- n = (int) getValue(inKeySpec, "getCostParameter");
- r = (int) getValue(inKeySpec, "getBlockSize");
- p = (int) getValue(inKeySpec, "getParallelizationParameter");
- keyOutputBits = (int) getValue(inKeySpec, "getKeyLength");
- } catch (Exception e) {
- throw new InvalidKeySpecException("Not a valid scrypt KeySpec", e);
- }
- }
-
- if (keyOutputBits % 8 != 0) {
- throw new InvalidKeySpecException("Cannot produce fractional-byte outputs");
- }
-
- try {
- return new ScryptKey(
- NativeCrypto.Scrypt_generate_key(
- new String(password).getBytes("UTF-8"),
- salt, n, r, p, keyOutputBits / 8));
- } catch (UnsupportedEncodingException e) {
- // Impossible according to the Java docs: UTF-8 is always supported.
- throw new IllegalStateException(e);
- }
- }
-
- private Object getValue(KeySpec spec, String methodName)
- throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
- Method method = spec.getClass().getMethod(methodName, (Class<?>[]) null);
- return method.invoke(spec);
- }
-
- @Override
- protected KeySpec engineGetKeySpec(
- SecretKey secretKey, @SuppressWarnings("rawtypes") Class aClass)
- throws InvalidKeySpecException {
- if (secretKey == null) {
- throw new InvalidKeySpecException("Null KeySpec");
- }
- throw new NotImplementedException();
- }
-
- @Override
- protected SecretKey engineTranslateKey(SecretKey secretKey) throws InvalidKeyException {
- if (secretKey == null) {
- throw new InvalidKeyException("Null SecretKey");
- }
- throw new NotImplementedException();
- }
-
- private static class ScryptKey implements SecretKey {
- private static final long serialVersionUID = 2024924811854189128L;
- private final byte[] key;
-
- public ScryptKey(byte[] key) {
- this.key = key;
- }
-
- @Override
- public String getAlgorithm() {
- // Capitalised because BouncyCastle does it.
- return "SCRYPT";
- }
-
- @Override
- public String getFormat() {
- return "RAW";
- }
-
- @Override
- public byte[] getEncoded() {
- return key;
- }
- }
-
- private static class NotImplementedException extends RuntimeException {
- NotImplementedException() {
- super("Not implemented");
- }
- }
-}
diff --git a/common/src/test/java/org/conscrypt/ConscryptSuite.java b/common/src/test/java/org/conscrypt/ConscryptSuite.java
index d29dbd9..cce41d5 100644
--- a/common/src/test/java/org/conscrypt/ConscryptSuite.java
+++ b/common/src/test/java/org/conscrypt/ConscryptSuite.java
@@ -51,7 +51,6 @@
import org.conscrypt.javax.crypto.CipherTest;
import org.conscrypt.javax.crypto.ECDHKeyAgreementTest;
import org.conscrypt.javax.crypto.KeyGeneratorTest;
-import org.conscrypt.javax.crypto.ScryptTest;
import org.conscrypt.javax.crypto.XDHKeyAgreementTest;
import org.conscrypt.javax.net.ssl.HttpsURLConnectionTest;
import org.conscrypt.javax.net.ssl.KeyManagerFactoryTest;
@@ -131,7 +130,6 @@
KeyStoreBuilderParametersTest.class,
OptionalMethodTest.class,
ProtocolTest.class,
- ScryptTest.class,
SNIHostNameTest.class,
SSLContextTest.class,
SSLEngineTest.class,
diff --git a/common/src/test/java/org/conscrypt/javax/crypto/ScryptTest.java b/common/src/test/java/org/conscrypt/javax/crypto/ScryptTest.java
deleted file mode 100644
index 133306c..0000000
--- a/common/src/test/java/org/conscrypt/javax/crypto/ScryptTest.java
+++ /dev/null
@@ -1,201 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt.javax.crypto;
-
-import static org.conscrypt.TestUtils.decodeHex;
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotEquals;
-import static org.junit.Assert.assertNotNull;
-
-import java.io.IOException;
-import java.nio.charset.StandardCharsets;
-import java.security.spec.KeySpec;
-import java.util.List;
-import javax.crypto.Cipher;
-import javax.crypto.SecretKey;
-import javax.crypto.SecretKeyFactory;
-import javax.crypto.spec.SecretKeySpec;
-import org.conscrypt.ScryptKeySpec;
-import org.conscrypt.TestUtils;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameter;
-import org.junit.runners.Parameterized.Parameters;
-
-@RunWith(Parameterized.class)
-public final class ScryptTest {
- @Parameters(name = "{0}")
- public static String[] params() {
- return new String[] {
- "SCRYPT",
- "1.3.6.1.4.1.11591.4.11",
- "OID.1.3.6.1.4.1.11591.4.11"
- };
- }
-
- @Parameter
- public String alias;
-
- // One of the test vectors from RFC 7914
- private static final char[] TEST_PASSWORD = "password".toCharArray();
- private static final byte[] TEST_SALT = "NaCl".getBytes(StandardCharsets.UTF_8);
- private static final int TEST_COST = 1024;
- private static final int TEST_BLOCKSIZE = 8;
- private static final int TEST_PARALLELIZATION = 16;
- private static final int TEST_KEY_SIZE = 512;
- private static final byte[] TEST_KEY = decodeHex(
- "fdbabe1c9d3472007856e7190d01e9fe7c6ad7cbc8237830e77376634b373162"
- + "2eaf30d92e22a3886ff109279d9830dac727afb94a83ee6d8360cbdfa2cc0640");
-
-
- private final List<String[]> testVectors = readTestVectors();
-
- // Column indices in test vector CSV file
- private static final int PASSWORD_INDEX = 0;
- private static final int SALT_INDEX = 1;
- private static final int N_INDEX = 2;
- private static final int R_INDEX = 3;
- private static final int P_INDEX = 4;
- private static final int KEY_INDEX = 5;
-
- @BeforeClass
- public static void setUp() {
- TestUtils.assumeAllowsUnsignedCrypto();
- }
-
- @Test
- public void smokeTest() throws Exception {
- SecretKeyFactory factory = SecretKeyFactory.getInstance(alias);
- assertEquals(alias, factory.getAlgorithm());
-
- ScryptKeySpec spec = new ScryptKeySpec(TEST_PASSWORD, TEST_SALT,
- TEST_COST, TEST_BLOCKSIZE, TEST_PARALLELIZATION, TEST_KEY_SIZE);
- SecretKey key = factory.generateSecret(spec);
- assertArrayEquals(TEST_KEY, key.getEncoded());
-
- // Convert for use with AES
- SecretKeySpec aesKey = makeAesKeySpec(key);
-
- // Make sure we can actually use the result
- checkKeyIsUsableWithAes(aesKey);
- }
-
- @Test
- public void duckTypingTest() throws Exception {
- SecretKeyFactory factory = SecretKeyFactory.getInstance(alias);
-
- KeySpec spec = new MyPrivateKeySpec(TEST_PASSWORD, TEST_SALT,
- TEST_COST, TEST_BLOCKSIZE, TEST_PARALLELIZATION, TEST_KEY_SIZE);
-
- SecretKey key = factory.generateSecret(spec);
- assertArrayEquals(TEST_KEY, key.getEncoded());
- }
-
- private SecretKeySpec makeAesKeySpec(SecretKey key) {
- assertEquals("RAW", key.getFormat());
- byte[] bytes = key.getEncoded();
- // Truncate to first 32 bytes if necessary
- int len = Math.min(32, bytes.length);
- return new SecretKeySpec(bytes, 0, len, "AES");
- }
-
- private void checkKeyIsUsableWithAes(SecretKeySpec spec) throws Exception {
- // Terrible encryption mode but saves messing with IVs which don't matter here.
- Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
-
- cipher.init(Cipher.ENCRYPT_MODE, spec);
- byte[] input = "The quick brown fox jumps over the lazy dog".getBytes(StandardCharsets.UTF_8);
- byte[] encrypted = cipher.doFinal(input);
- assertNotEquals(encrypted[0], input[0]);
-
- cipher.init(Cipher.DECRYPT_MODE, spec);
- byte[] decrypted = cipher.doFinal(encrypted);
- assertArrayEquals(input, decrypted);
- }
-
- @Test
- public void knownAnswerTest() throws Exception {
- for (String[] entry : testVectors) {
- char[] password = entry[PASSWORD_INDEX].toCharArray();
- byte[] salt = entry[SALT_INDEX].getBytes(StandardCharsets.UTF_8);
- int n = Integer.parseInt(entry[N_INDEX]);
- int r = Integer.parseInt(entry[R_INDEX]);
- int p = Integer.parseInt(entry[P_INDEX]);
- byte[] expectedBytes = decodeHex(entry[KEY_INDEX]);
-
- ScryptKeySpec spec = new ScryptKeySpec(password, salt, n, r, p, expectedBytes.length * 8);
- SecretKeyFactory factory = SecretKeyFactory.getInstance(alias);
- SecretKey key = factory.generateSecret(spec);
- assertNotNull(key);
- assertArrayEquals(expectedBytes, key.getEncoded());
- }
- }
-
- private List<String[]> readTestVectors() {
- try {
- return TestUtils.readCsvResource("crypto/scrypt.csv");
-
- } catch (IOException e) {
- throw new AssertionError("Unable to load Scrypt test vectors", e);
- }
- }
-
- public static class MyPrivateKeySpec implements KeySpec {
- private final char[] password;
- private final byte[] salt;
- private final int n;
- private final int r;
- private final int p;
- private final int keyOutputBits;
-
- public MyPrivateKeySpec(char[] password, byte[] salt, int n, int r, int p, int keyOutputBits) {
- this.password = password;
- this.salt = salt;
- this.n = n;
- this.r = r;
- this.p = p;
- this.keyOutputBits = keyOutputBits;
- }
-
- public char[] getPassword() {
- return password;
- }
-
- public byte[] getSalt() {
- return salt;
- }
-
- public int getCostParameter() {
- return n;
- }
-
- public int getBlockSize() {
- return r;
- }
-
- public int getParallelizationParameter() {
- return p;
- }
-
- public int getKeyLength() {
- return keyOutputBits;
- }
- }
-}
diff --git a/common/src/test/java/org/conscrypt/javax/net/ssl/SSLContextTest.java b/common/src/test/java/org/conscrypt/javax/net/ssl/SSLContextTest.java
index 40acd1b..2c68c6f 100644
--- a/common/src/test/java/org/conscrypt/javax/net/ssl/SSLContextTest.java
+++ b/common/src/test/java/org/conscrypt/javax/net/ssl/SSLContextTest.java
@@ -22,7 +22,6 @@
import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
-import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
@@ -650,7 +649,7 @@
testContext.close();
}
- @Test
+ @Test(expected = NoSuchAlgorithmException.class)
public void test_SSLContext_SSLv3Unsupported() throws Exception {
// Find the default provider for TLS and verify that it does NOT support SSLv3.
Provider defaultTlsProvider = null;
@@ -663,10 +662,7 @@
}
}
assertNotNull(defaultTlsProvider);
- Provider finalDefaultTlsProvider = defaultTlsProvider;
- assertThrows(
- NoSuchAlgorithmException.class,
- () -> SSLContext.getInstance("SSLv3", finalDefaultTlsProvider));
+ SSLContext.getInstance("SSLv3", defaultTlsProvider);
}
private static void assertContentsInOrder(List<String> expected, String... actual) {
diff --git a/common/src/test/java/org/conscrypt/metrics/OptionalMethodTest.java b/common/src/test/java/org/conscrypt/metrics/OptionalMethodTest.java
index eba0537..5e85539 100644
--- a/common/src/test/java/org/conscrypt/metrics/OptionalMethodTest.java
+++ b/common/src/test/java/org/conscrypt/metrics/OptionalMethodTest.java
@@ -3,7 +3,6 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertThrows;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -30,11 +29,9 @@
assertNull(substring.invoke("input", 2, 5));
}
- @Test
+ @Test(expected = NullPointerException.class)
public void nullMethodName() {
- assertThrows(
- NullPointerException.class,
- () -> new OptionalMethod(String.class, null, int.class, int.class));
+ new OptionalMethod(String.class, null, int.class, int.class);
}
@Test
diff --git a/common/src/test/resources/crypto/scrypt.csv b/common/src/test/resources/crypto/scrypt.csv
deleted file mode 100644
index 88bdfb8..0000000
--- a/common/src/test/resources/crypto/scrypt.csv
+++ /dev/null
@@ -1,8 +0,0 @@
-# Scrypt test vectors from RFC 7914
-# Data is in the format:
-# password,salt,n,r,p,key
-,,16,1,1,77d6576238657b203b19ca42c18a0497f16b4844e3074ae8dfdffa3fede21442fcd0069ded0948f8326a753a0fc81f17e8d3e0fb2e0d3628cf35e20c38d18906
-password,NaCl,1024,8,16,fdbabe1c9d3472007856e7190d01e9fe7c6ad7cbc8237830e77376634b3731622eaf30d92e22a3886ff109279d9830dac727afb94a83ee6d8360cbdfa2cc0640
-pleaseletmein,SodiumChloride,16384,8,1,7023bdcb3afd7348461c06cd81fd38ebfda8fbba904f8e3ea9b543f6545da1f2d5432955613f0fcf62d49705242a9af9e61e85dc0d651e40dfcf017b45575887
-# Following vector exceeds memory limits with defaults
-# pleaseletmein,SodiumChloride,1048576,8,1,2101cb9b6a511aaeaddbbe09cf70f881ec568d574a2ffd4dabe5ee9820adaa478e56fd8f4ba5d09ffa1c6d927c40f4c337304049e8a952fbcbf45c6fa77a41a4
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/NativeCrypto.java b/repackaged/common/src/main/java/com/android/org/conscrypt/NativeCrypto.java
index f1a575e..1edbd50 100644
--- a/repackaged/common/src/main/java/com/android/org/conscrypt/NativeCrypto.java
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/NativeCrypto.java
@@ -1485,12 +1485,6 @@
throws IOException;
/**
- * Generates a key from a password and salt using Scrypt.
- */
- static native byte[] Scrypt_generate_key(
- byte[] password, byte[] salt, int n, int r, int p, int key_len);
-
- /**
* Return {@code true} if BoringSSL has been built in FIPS mode.
*/
static native boolean usesBoringSSL_FIPS_mode();
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLProvider.java b/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLProvider.java
index 5756aeb..16241e3 100644
--- a/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLProvider.java
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLProvider.java
@@ -218,9 +218,6 @@
/* == SecretKeyFactory == */
put("SecretKeyFactory.DESEDE", PREFIX + "DESEDESecretKeyFactory");
put("Alg.Alias.SecretKeyFactory.TDEA", "DESEDE");
- put("SecretKeyFactory.SCRYPT", PREFIX + "ScryptSecretKeyFactory");
- put("Alg.Alias.SecretKeyFactory.1.3.6.1.4.1.11591.4.11", "SCRYPT");
- put("Alg.Alias.SecretKeyFactory.OID.1.3.6.1.4.1.11591.4.11", "SCRYPT");
/* == KeyAgreement == */
putECDHKeyAgreementImplClass("OpenSSLECDHKeyAgreement");
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/ScryptKeySpec.java b/repackaged/common/src/main/java/com/android/org/conscrypt/ScryptKeySpec.java
deleted file mode 100644
index d6e12dd..0000000
--- a/repackaged/common/src/main/java/com/android/org/conscrypt/ScryptKeySpec.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/* GENERATED SOURCE. DO NOT MODIFY. */
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.org.conscrypt;
-
-import java.security.spec.KeySpec;
-
-/**
- * Mirrors the <a
- * href="https://javadoc.io/static/org.bouncycastle/bcprov-jdk15on/1.68/org/bouncycastle/jcajce/spec/ScryptKeySpec.html">class
- * of the same name</a> from BouncyCastle.
- * @hide This class is not part of the Android public SDK API
- */
-public class ScryptKeySpec implements KeySpec {
- private final char[] password;
- private final byte[] salt;
- private final int costParameter;
- private final int blockSize;
- private final int parallelizationParameter;
- private final int keyOutputBits;
-
- public ScryptKeySpec(
- char[] password,
- byte[] salt,
- int costParameter,
- int blockSize,
- int parallelizationParameter,
- int keyOutputBits) {
- this.password = password;
- this.salt = salt;
- this.costParameter = costParameter;
- this.blockSize = blockSize;
- this.parallelizationParameter = parallelizationParameter;
- this.keyOutputBits = keyOutputBits;
- }
-
- public char[] getPassword() {
- return password;
- }
-
- public byte[] getSalt() {
- return salt;
- }
-
- public int getCostParameter() {
- return costParameter;
- }
-
- public int getBlockSize() {
- return blockSize;
- }
-
- public int getParallelizationParameter() {
- return parallelizationParameter;
- }
-
- public int getKeyLength() {
- return keyOutputBits;
- }
-}
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/ScryptSecretKeyFactory.java b/repackaged/common/src/main/java/com/android/org/conscrypt/ScryptSecretKeyFactory.java
deleted file mode 100644
index 4a29a58..0000000
--- a/repackaged/common/src/main/java/com/android/org/conscrypt/ScryptSecretKeyFactory.java
+++ /dev/null
@@ -1,134 +0,0 @@
-/* GENERATED SOURCE. DO NOT MODIFY. */
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.org.conscrypt;
-
-import java.io.UnsupportedEncodingException;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.security.InvalidKeyException;
-import java.security.spec.InvalidKeySpecException;
-import java.security.spec.KeySpec;
-import javax.crypto.SecretKey;
-import javax.crypto.SecretKeyFactorySpi;
-
-/**
- * @hide This class is not part of the Android public SDK API
- */
-@Internal
-public class ScryptSecretKeyFactory extends SecretKeyFactorySpi {
-
- @Override
- protected SecretKey engineGenerateSecret(KeySpec inKeySpec) throws InvalidKeySpecException {
-
- char[] password;
- byte[] salt;
- int n, r, p, keyOutputBits;
-
- if (inKeySpec instanceof ScryptKeySpec) {
- ScryptKeySpec spec = (ScryptKeySpec) inKeySpec;
- password = spec.getPassword();
- salt = spec.getSalt();
- n = spec.getCostParameter();
- r = spec.getBlockSize();
- p = spec.getParallelizationParameter();
- keyOutputBits = spec.getKeyLength();
- } else {
- // Extract parameters from any `KeySpec` that has getters with the correct name. This
- // allows, for example, code to use BouncyCastle's KeySpec with the Conscrypt provider.
- try {
- password = (char[]) getValue(inKeySpec, "getPassword");
- salt = (byte[]) getValue(inKeySpec, "getSalt");
- n = (int) getValue(inKeySpec, "getCostParameter");
- r = (int) getValue(inKeySpec, "getBlockSize");
- p = (int) getValue(inKeySpec, "getParallelizationParameter");
- keyOutputBits = (int) getValue(inKeySpec, "getKeyLength");
- } catch (Exception e) {
- throw new InvalidKeySpecException("Not a valid scrypt KeySpec", e);
- }
- }
-
- if (keyOutputBits % 8 != 0) {
- throw new InvalidKeySpecException("Cannot produce fractional-byte outputs");
- }
-
- try {
- return new ScryptKey(
- NativeCrypto.Scrypt_generate_key(
- new String(password).getBytes("UTF-8"),
- salt, n, r, p, keyOutputBits / 8));
- } catch (UnsupportedEncodingException e) {
- // Impossible according to the Java docs: UTF-8 is always supported.
- throw new IllegalStateException(e);
- }
- }
-
- private Object getValue(KeySpec spec, String methodName)
- throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
- Method method = spec.getClass().getMethod(methodName, (Class<?>[]) null);
- return method.invoke(spec);
- }
-
- @Override
- protected KeySpec engineGetKeySpec(
- SecretKey secretKey, @SuppressWarnings("rawtypes") Class aClass)
- throws InvalidKeySpecException {
- if (secretKey == null) {
- throw new InvalidKeySpecException("Null KeySpec");
- }
- throw new NotImplementedException();
- }
-
- @Override
- protected SecretKey engineTranslateKey(SecretKey secretKey) throws InvalidKeyException {
- if (secretKey == null) {
- throw new InvalidKeyException("Null SecretKey");
- }
- throw new NotImplementedException();
- }
-
- private static class ScryptKey implements SecretKey {
- private static final long serialVersionUID = 2024924811854189128L;
- private final byte[] key;
-
- public ScryptKey(byte[] key) {
- this.key = key;
- }
-
- @Override
- public String getAlgorithm() {
- // Capitalised because BouncyCastle does it.
- return "SCRYPT";
- }
-
- @Override
- public String getFormat() {
- return "RAW";
- }
-
- @Override
- public byte[] getEncoded() {
- return key;
- }
- }
-
- private static class NotImplementedException extends RuntimeException {
- NotImplementedException() {
- super("Not implemented");
- }
- }
-}
diff --git a/repackaged/common/src/test/java/com/android/org/conscrypt/javax/crypto/ScryptTest.java b/repackaged/common/src/test/java/com/android/org/conscrypt/javax/crypto/ScryptTest.java
deleted file mode 100644
index 9d0c5b1..0000000
--- a/repackaged/common/src/test/java/com/android/org/conscrypt/javax/crypto/ScryptTest.java
+++ /dev/null
@@ -1,208 +0,0 @@
-/* GENERATED SOURCE. DO NOT MODIFY. */
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.org.conscrypt.javax.crypto;
-
-import static com.android.org.conscrypt.TestUtils.decodeHex;
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotEquals;
-import static org.junit.Assert.assertNotNull;
-
-import java.io.IOException;
-import java.nio.charset.StandardCharsets;
-import java.security.spec.KeySpec;
-import java.util.List;
-import javax.crypto.Cipher;
-import javax.crypto.SecretKey;
-import javax.crypto.SecretKeyFactory;
-import javax.crypto.spec.SecretKeySpec;
-import com.android.org.conscrypt.ScryptKeySpec;
-import com.android.org.conscrypt.TestUtils;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameter;
-import org.junit.runners.Parameterized.Parameters;
-
-/**
- * @hide This class is not part of the Android public SDK API
- */
-@RunWith(Parameterized.class)
-public final class ScryptTest {
- @Parameters(name = "{0}")
- public static String[] params() {
- return new String[] {
- "SCRYPT",
- "1.3.6.1.4.1.11591.4.11",
- "OID.1.3.6.1.4.1.11591.4.11"
- };
- }
-
- @Parameter
- public String alias;
-
- // One of the test vectors from RFC 7914
- private static final char[] TEST_PASSWORD = "password".toCharArray();
- private static final byte[] TEST_SALT = "NaCl".getBytes(StandardCharsets.UTF_8);
- private static final int TEST_COST = 1024;
- private static final int TEST_BLOCKSIZE = 8;
- private static final int TEST_PARALLELIZATION = 16;
- private static final int TEST_KEY_SIZE = 512;
- private static final byte[] TEST_KEY = decodeHex(
- "fdbabe1c9d3472007856e7190d01e9fe7c6ad7cbc8237830e77376634b373162"
- + "2eaf30d92e22a3886ff109279d9830dac727afb94a83ee6d8360cbdfa2cc0640");
-
-
- private final List<String[]> testVectors = readTestVectors();
-
- // Column indices in test vector CSV file
- private static final int PASSWORD_INDEX = 0;
- private static final int SALT_INDEX = 1;
- private static final int N_INDEX = 2;
- private static final int R_INDEX = 3;
- private static final int P_INDEX = 4;
- private static final int KEY_INDEX = 5;
-
- @BeforeClass
- public static void setUp() {
- TestUtils.assumeAllowsUnsignedCrypto();
- }
-
- @Test
- public void smokeTest() throws Exception {
- SecretKeyFactory factory = SecretKeyFactory.getInstance(alias);
- assertEquals(alias, factory.getAlgorithm());
-
- ScryptKeySpec spec = new ScryptKeySpec(TEST_PASSWORD, TEST_SALT,
- TEST_COST, TEST_BLOCKSIZE, TEST_PARALLELIZATION, TEST_KEY_SIZE);
- SecretKey key = factory.generateSecret(spec);
- assertArrayEquals(TEST_KEY, key.getEncoded());
-
- // Convert for use with AES
- SecretKeySpec aesKey = makeAesKeySpec(key);
-
- // Make sure we can actually use the result
- checkKeyIsUsableWithAes(aesKey);
- }
-
- @Test
- public void duckTypingTest() throws Exception {
- SecretKeyFactory factory = SecretKeyFactory.getInstance(alias);
-
- KeySpec spec = new MyPrivateKeySpec(TEST_PASSWORD, TEST_SALT,
- TEST_COST, TEST_BLOCKSIZE, TEST_PARALLELIZATION, TEST_KEY_SIZE);
-
- SecretKey key = factory.generateSecret(spec);
- assertArrayEquals(TEST_KEY, key.getEncoded());
- }
-
- private SecretKeySpec makeAesKeySpec(SecretKey key) {
- assertEquals("RAW", key.getFormat());
- byte[] bytes = key.getEncoded();
- // Truncate to first 32 bytes if necessary
- int len = Math.min(32, bytes.length);
- return new SecretKeySpec(bytes, 0, len, "AES");
- }
-
- private void checkKeyIsUsableWithAes(SecretKeySpec spec) throws Exception {
- // Terrible encryption mode but saves messing with IVs which don't matter here.
- Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
-
- cipher.init(Cipher.ENCRYPT_MODE, spec);
- byte[] input = "The quick brown fox jumps over the lazy dog".getBytes(StandardCharsets.UTF_8);
- byte[] encrypted = cipher.doFinal(input);
- assertNotEquals(encrypted[0], input[0]);
-
- cipher.init(Cipher.DECRYPT_MODE, spec);
- byte[] decrypted = cipher.doFinal(encrypted);
- assertArrayEquals(input, decrypted);
- }
-
- @Test
- public void knownAnswerTest() throws Exception {
- for (String[] entry : testVectors) {
- char[] password = entry[PASSWORD_INDEX].toCharArray();
- byte[] salt = entry[SALT_INDEX].getBytes(StandardCharsets.UTF_8);
- int n = Integer.parseInt(entry[N_INDEX]);
- int r = Integer.parseInt(entry[R_INDEX]);
- int p = Integer.parseInt(entry[P_INDEX]);
- byte[] expectedBytes = decodeHex(entry[KEY_INDEX]);
-
- ScryptKeySpec spec = new ScryptKeySpec(password, salt, n, r, p, expectedBytes.length * 8);
- SecretKeyFactory factory = SecretKeyFactory.getInstance(alias);
- SecretKey key = factory.generateSecret(spec);
- assertNotNull(key);
- assertArrayEquals(expectedBytes, key.getEncoded());
- }
- }
-
- private List<String[]> readTestVectors() {
- try {
- return TestUtils.readCsvResource("crypto/scrypt.csv");
-
- } catch (IOException e) {
- throw new AssertionError("Unable to load Scrypt test vectors", e);
- }
- }
-
- /**
- * @hide This class is not part of the Android public SDK API
- */
- public static class MyPrivateKeySpec implements KeySpec {
- private final char[] password;
- private final byte[] salt;
- private final int n;
- private final int r;
- private final int p;
- private final int keyOutputBits;
-
- public MyPrivateKeySpec(char[] password, byte[] salt, int n, int r, int p, int keyOutputBits) {
- this.password = password;
- this.salt = salt;
- this.n = n;
- this.r = r;
- this.p = p;
- this.keyOutputBits = keyOutputBits;
- }
-
- public char[] getPassword() {
- return password;
- }
-
- public byte[] getSalt() {
- return salt;
- }
-
- public int getCostParameter() {
- return n;
- }
-
- public int getBlockSize() {
- return r;
- }
-
- public int getParallelizationParameter() {
- return p;
- }
-
- public int getKeyLength() {
- return keyOutputBits;
- }
- }
-}
diff --git a/repackaged/common/src/test/java/com/android/org/conscrypt/javax/net/ssl/SSLContextTest.java b/repackaged/common/src/test/java/com/android/org/conscrypt/javax/net/ssl/SSLContextTest.java
index 5f382d1..972928b 100644
--- a/repackaged/common/src/test/java/com/android/org/conscrypt/javax/net/ssl/SSLContextTest.java
+++ b/repackaged/common/src/test/java/com/android/org/conscrypt/javax/net/ssl/SSLContextTest.java
@@ -23,7 +23,6 @@
import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
-import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
@@ -663,7 +662,7 @@
testContext.close();
}
- @Test
+ @Test(expected = NoSuchAlgorithmException.class)
public void test_SSLContext_SSLv3Unsupported() throws Exception {
// Find the default provider for TLS and verify that it does NOT support SSLv3.
Provider defaultTlsProvider = null;
@@ -676,9 +675,7 @@
}
}
assertNotNull(defaultTlsProvider);
- Provider finalDefaultTlsProvider = defaultTlsProvider;
- assertThrows(NoSuchAlgorithmException.class,
- () -> SSLContext.getInstance("SSLv3", finalDefaultTlsProvider));
+ SSLContext.getInstance("SSLv3", defaultTlsProvider);
}
private static void assertContentsInOrder(List<String> expected, String... actual) {
diff --git a/repackaged/common/src/test/java/com/android/org/conscrypt/metrics/OptionalMethodTest.java b/repackaged/common/src/test/java/com/android/org/conscrypt/metrics/OptionalMethodTest.java
index 143a8f1..4675042 100644
--- a/repackaged/common/src/test/java/com/android/org/conscrypt/metrics/OptionalMethodTest.java
+++ b/repackaged/common/src/test/java/com/android/org/conscrypt/metrics/OptionalMethodTest.java
@@ -4,7 +4,6 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertThrows;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -34,10 +33,9 @@
assertNull(substring.invoke("input", 2, 5));
}
- @Test
+ @Test(expected = NullPointerException.class)
public void nullMethodName() {
- assertThrows(NullPointerException.class,
- () -> new OptionalMethod(String.class, null, int.class, int.class));
+ new OptionalMethod(String.class, null, int.class, int.class);
}
@Test