aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2021-12-14 00:02:21 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2021-12-14 00:02:21 +0000
commita84934d98c03b9a2bd114deaac61ff49cedbb83a (patch)
treea8748a3b0be654cbcbece385320d45412a1f97f7
parent2ab719a035455c8af74e70a5fdfbfff596192a2b (diff)
parentd53d08067882b9da11228febf4f04c4d1950e22e (diff)
downloadconscrypt-a84934d98c03b9a2bd114deaac61ff49cedbb83a.tar.gz
Change-Id: I0a5a29b7a417ddd7863ce9a6423b69afff05779e
-rw-r--r--Android.bp6
-rw-r--r--android-stub/build.gradle4
-rw-r--r--build.gradle4
-rw-r--r--common/src/jni/main/cpp/conscrypt/native_crypto.cc124
-rw-r--r--common/src/test/java/org/conscrypt/ConscryptSuite.java5
-rw-r--r--common/src/test/java/org/conscrypt/NativeCryptoArgTest.java331
-rw-r--r--common/src/test/java/org/conscrypt/java/security/KeyFactoryTestRSA.java16
-rw-r--r--common/src/test/java/org/conscrypt/java/security/KeyFactoryTestRSACrt.java5
-rw-r--r--common/src/test/java/org/conscrypt/javax/crypto/CipherTest.java75
-rw-r--r--repackaged/common/src/test/java/com/android/org/conscrypt/NativeCryptoArgTest.java335
-rw-r--r--repackaged/common/src/test/java/com/android/org/conscrypt/java/security/KeyFactoryTestRSA.java14
-rw-r--r--repackaged/common/src/test/java/com/android/org/conscrypt/java/security/KeyFactoryTestRSACrt.java5
-rw-r--r--repackaged/common/src/test/java/com/android/org/conscrypt/javax/crypto/CipherTest.java71
-rw-r--r--repackaged/testing/src/main/java/com/android/org/conscrypt/MethodFilter.java201
-rw-r--r--testing/src/main/java/org/conscrypt/MethodFilter.java196
15 files changed, 101 insertions, 1291 deletions
diff --git a/Android.bp b/Android.bp
index af9e01ef..ff3a903e 100644
--- a/Android.bp
+++ b/Android.bp
@@ -525,7 +525,7 @@ java_library_host {
":conscrypt-unbundled_generated_constants",
],
javacflags: ["-XDignore.symbol.file"],
- java_version: "1.8",
+ java_version: "1.7",
}
// Static unbundled Conscrypt crypto JNI library
@@ -599,7 +599,7 @@ java_test {
enabled: false,
},
},
- java_version: "1.8",
+ java_version: "1.7",
}
// Make the conscrypt-benchmarks library.
@@ -636,7 +636,7 @@ java_test {
enabled: false,
},
},
- java_version: "1.8",
+ java_version: "1.7",
}
// Device SDK exposed by the Conscrypt module.
diff --git a/android-stub/build.gradle b/android-stub/build.gradle
index 874f5996..f1a911f5 100644
--- a/android-stub/build.gradle
+++ b/android-stub/build.gradle
@@ -1,5 +1,9 @@
description = 'Conscrypt: Android-Stub'
+// Needs to be binary-compatible with Android minSdkVersion.
+sourceCompatibility = androidMinJavaVersion
+targetCompatibility = androidMinJavaVersion
+
dependencies {
compileOnly project(':conscrypt-libcore-stub')
}
diff --git a/build.gradle b/build.gradle
index 08b9ebd8..162c491b 100644
--- a/build.gradle
+++ b/build.gradle
@@ -165,8 +165,8 @@ subprojects {
}
if (!androidProject) {
- sourceCompatibility = JavaVersion.VERSION_1_8
- targetCompatibility = JavaVersion.VERSION_1_8
+ sourceCompatibility = JavaVersion.VERSION_1_7
+ targetCompatibility = JavaVersion.VERSION_1_7
[tasks.named("compileJava"), tasks.named("compileTestJava")].forEach { t ->
t.configure {
diff --git a/common/src/jni/main/cpp/conscrypt/native_crypto.cc b/common/src/jni/main/cpp/conscrypt/native_crypto.cc
index 98d7dbc7..5b0acf0d 100644
--- a/common/src/jni/main/cpp/conscrypt/native_crypto.cc
+++ b/common/src/jni/main/cpp/conscrypt/native_crypto.cc
@@ -2204,9 +2204,7 @@ static jbyteArray NativeCrypto_EC_KEY_marshal_curve_name(JNIEnv* env, jclass, jo
const EC_GROUP* group = fromContextObject<EC_GROUP>(env, groupRef);
JNI_TRACE("EC_KEY_marshal_curve_name(%p)", group);
if (group == nullptr) {
- env->ExceptionClear();
conscrypt::jniutil::throwIOException(env, "Invalid group pointer");
- JNI_TRACE("group=%p EC_KEY_marshal_curve_name => Invalid group pointer", group);
return nullptr;
}
@@ -2233,9 +2231,8 @@ static jlong NativeCrypto_EC_KEY_parse_curve_name(JNIEnv* env, jclass, jbyteArra
ScopedByteArrayRO bytes(env, curveNameBytes);
if (bytes.get() == nullptr) {
- env->ExceptionClear();
- conscrypt::jniutil::throwIOException(env, "Null EC curve name");
- JNI_TRACE("bytes=%p EC_KEY_parse_curve_name => curveNameBytes == null ", curveNameBytes);
+ conscrypt::jniutil::throwIOException(env, "Error reading ASN.1 encoding");
+ JNI_TRACE("bytes=%p EC_KEY_parse_curve_name => threw exception", curveNameBytes);
return 0;
}
@@ -3211,12 +3208,6 @@ static jlong NativeCrypto_EVP_get_cipherbyname(JNIEnv* env, jclass, jstring algo
CHECK_ERROR_QUEUE_ON_RETURN;
JNI_TRACE("EVP_get_cipherbyname(%p)", algorithm);
- if (algorithm == nullptr) {
- conscrypt::jniutil::throwNullPointerException(env, "algorithm == null");
- JNI_TRACE("EVP_get_cipherbyname(%p) => algorithm == null", algorithm);
- return -1;
- }
-
ScopedUtfChars scoped_alg(env, algorithm);
const char* alg = scoped_alg.c_str();
const EVP_CIPHER* cipher;
@@ -3254,7 +3245,7 @@ static jlong NativeCrypto_EVP_get_cipherbyname(JNIEnv* env, jclass, jstring algo
} else if (strcasecmp(alg, "aes-256-gcm") == 0) {
cipher = EVP_aes_256_gcm();
} else {
- JNI_TRACE("NativeCrypto_EVP_get_cipherbyname(%s) => error", alg);
+ JNI_TRACE("NativeCrypto_EVP_get_digestbyname(%s) => error", alg);
return 0;
}
@@ -4387,12 +4378,6 @@ static long NativeCrypto_X509_get_version(JNIEnv* env, jclass, jlong x509Ref,
X509* x509 = reinterpret_cast<X509*>(static_cast<uintptr_t>(x509Ref));
JNI_TRACE("X509_get_version(%p)", x509);
- if (x509 == nullptr) {
- conscrypt::jniutil::throwNullPointerException(env, "x509 == null");
- JNI_TRACE("X509_get_version(%p) => x509 == null", x509);
- return 0;
- }
-
// NOLINTNEXTLINE(runtime/int)
long version = X509_get_version(x509);
JNI_TRACE("X509_get_version(%p) => %ld", x509, version);
@@ -4432,12 +4417,6 @@ static jbyteArray NativeCrypto_X509_get_serialNumber(JNIEnv* env, jclass, jlong
CHECK_ERROR_QUEUE_ON_RETURN;
X509* x509 = reinterpret_cast<X509*>(static_cast<uintptr_t>(x509Ref));
JNI_TRACE("X509_get_serialNumber(%p)", x509);
-
- if (x509 == nullptr) {
- conscrypt::jniutil::throwNullPointerException(env, "x509 == null");
- JNI_TRACE("X509_get_serialNumber(%p) => x509 == null", x509);
- return nullptr;
- }
return get_X509Type_serialNumber<X509>(env, x509, X509_get0_serialNumber);
}
@@ -4446,12 +4425,6 @@ static jbyteArray NativeCrypto_X509_REVOKED_get_serialNumber(JNIEnv* env, jclass
CHECK_ERROR_QUEUE_ON_RETURN;
X509_REVOKED* revoked = reinterpret_cast<X509_REVOKED*>(static_cast<uintptr_t>(x509RevokedRef));
JNI_TRACE("X509_REVOKED_get_serialNumber(%p)", revoked);
-
- if (revoked == nullptr) {
- conscrypt::jniutil::throwNullPointerException(env, "revoked == null");
- JNI_TRACE("X509_REVOKED_get_serialNumber(%p) => revoked == null", revoked);
- return 0;
- }
return get_X509Type_serialNumber<X509_REVOKED>(env, revoked, X509_REVOKED_get0_serialNumber);
}
@@ -4573,16 +4546,6 @@ static jint NativeCrypto_X509_check_issued(JNIEnv* env, jclass, jlong x509Ref1,
X509* x509_2 = reinterpret_cast<X509*>(static_cast<uintptr_t>(x509Ref2));
JNI_TRACE("X509_check_issued(%p, %p)", x509_1, x509_2);
- if (x509_1 == nullptr) {
- conscrypt::jniutil::throwNullPointerException(env, "x509Ref1 == null");
- JNI_TRACE("X509_check_issued(%p, %p) => x509_1 == null", x509_1, x509_2);
- return 0;
- }
- if (x509_2 == nullptr) {
- conscrypt::jniutil::throwNullPointerException(env, "x509Ref2 == null");
- JNI_TRACE("X509_check_issued(%p, %p) => x509_2 == null", x509_1, x509_2);
- return 0;
- }
int ret = X509_check_issued(x509_1, x509_2);
JNI_TRACE("X509_check_issued(%p, %p) => %d", x509_1, x509_2, ret);
return ret;
@@ -4638,12 +4601,6 @@ static jbyteArray NativeCrypto_get_X509_signature(JNIEnv* env, jclass, jlong x50
CHECK_ERROR_QUEUE_ON_RETURN;
X509* x509 = reinterpret_cast<X509*>(static_cast<uintptr_t>(x509Ref));
JNI_TRACE("get_X509_signature(%p)", x509);
-
- if (x509 == nullptr) {
- conscrypt::jniutil::throwNullPointerException(env, "x509 == null");
- JNI_TRACE("get_X509_signature(%p) => x509 == null", x509);
- return nullptr;
- }
return get_X509Type_signature<X509>(env, x509, get_X509_signature);
}
@@ -4652,12 +4609,6 @@ static jbyteArray NativeCrypto_get_X509_CRL_signature(JNIEnv* env, jclass, jlong
CHECK_ERROR_QUEUE_ON_RETURN;
X509_CRL* crl = reinterpret_cast<X509_CRL*>(static_cast<uintptr_t>(x509CrlRef));
JNI_TRACE("get_X509_CRL_signature(%p)", crl);
-
- if (crl == nullptr) {
- conscrypt::jniutil::throwNullPointerException(env, "crl == null");
- JNI_TRACE("X509_CRL_signature(%p) => crl == null", crl);
- return nullptr;
- }
return get_X509Type_signature<X509_CRL>(env, crl, get_X509_CRL_signature);
}
@@ -4743,7 +4694,6 @@ static jlongArray NativeCrypto_X509_CRL_get_REVOKED(JNIEnv* env, jclass, jlong x
if (crl == nullptr) {
conscrypt::jniutil::throwNullPointerException(env, "crl == null");
- JNI_TRACE("X509_CRL_get_REVOKED(%p) => crl == null", crl);
return nullptr;
}
@@ -4771,12 +4721,6 @@ static jbyteArray NativeCrypto_i2d_X509_CRL(JNIEnv* env, jclass, jlong x509CrlRe
CHECK_ERROR_QUEUE_ON_RETURN;
X509_CRL* crl = reinterpret_cast<X509_CRL*>(static_cast<uintptr_t>(x509CrlRef));
JNI_TRACE("i2d_X509_CRL(%p)", crl);
-
- if (crl == nullptr) {
- conscrypt::jniutil::throwNullPointerException(env, "crl == null");
- JNI_TRACE("i2d_X509_CRL(%p) => crl == null", crl);
- return nullptr;
- }
return ASN1ToByteArray<X509_CRL>(env, crl, i2d_X509_CRL);
}
@@ -4883,12 +4827,6 @@ static jbyteArray NativeCrypto_X509_CRL_get_issuer_name(JNIEnv* env, jclass, jlo
CONSCRYPT_UNUSED jobject holder) {
CHECK_ERROR_QUEUE_ON_RETURN;
X509_CRL* crl = reinterpret_cast<X509_CRL*>(static_cast<uintptr_t>(x509CrlRef));
-
- if (crl == nullptr) {
- conscrypt::jniutil::throwNullPointerException(env, "crl == null");
- JNI_TRACE("X509_CRL_get_issuer_name(%p) => crl == null", crl);
- return nullptr;
- }
JNI_TRACE("X509_CRL_get_issuer_name(%p)", crl);
return ASN1ToByteArray<X509_NAME>(env, X509_CRL_get_issuer(crl), i2d_X509_NAME);
}
@@ -4900,11 +4838,6 @@ static long NativeCrypto_X509_CRL_get_version(JNIEnv* env, jclass, jlong x509Crl
X509_CRL* crl = reinterpret_cast<X509_CRL*>(static_cast<uintptr_t>(x509CrlRef));
JNI_TRACE("X509_CRL_get_version(%p)", crl);
- if (crl == nullptr) {
- conscrypt::jniutil::throwNullPointerException(env, "crl == null");
- JNI_TRACE("X509_CRL_get_version(%p) => crl == null", crl);
- return 0;
- }
// NOLINTNEXTLINE(runtime/int)
long version = X509_CRL_get_version(crl);
JNI_TRACE("X509_CRL_get_version(%p) => %ld", crl, version);
@@ -4965,12 +4898,6 @@ static jlong NativeCrypto_X509_CRL_get_ext(JNIEnv* env, jclass, jlong x509CrlRef
CHECK_ERROR_QUEUE_ON_RETURN;
X509_CRL* crl = reinterpret_cast<X509_CRL*>(static_cast<uintptr_t>(x509CrlRef));
JNI_TRACE("X509_CRL_get_ext(%p, %p)", crl, oid);
-
- if (crl == nullptr) {
- conscrypt::jniutil::throwNullPointerException(env, "crl == null");
- JNI_TRACE("X509_CRL_get_ext(%p) => crl == null", crl);
- return 0;
- }
X509_EXTENSION* ext =
X509Type_get_ext<X509_CRL, X509_CRL_get_ext_by_OBJ, X509_CRL_get_ext>(env, crl, oid);
JNI_TRACE("X509_CRL_get_ext(%p, %p) => %p", crl, oid, ext);
@@ -5064,12 +4991,6 @@ static jbyteArray NativeCrypto_get_X509_CRL_crl_enc(JNIEnv* env, jclass, jlong x
CHECK_ERROR_QUEUE_ON_RETURN;
X509_CRL* crl = reinterpret_cast<X509_CRL*>(static_cast<uintptr_t>(x509CrlRef));
JNI_TRACE("get_X509_CRL_crl_enc(%p)", crl);
-
- if (crl == nullptr) {
- conscrypt::jniutil::throwNullPointerException(env, "crl == null");
- JNI_TRACE("get_X509_CRL_crl_enc(%p) => crl == null", crl);
- return nullptr;
- }
return ASN1ToByteArray<X509_CRL>(env, crl, i2d_X509_CRL_tbs);
}
@@ -5607,12 +5528,6 @@ static jbyteArray NativeCrypto_i2d_X509(JNIEnv* env, jclass, jlong x509Ref,
CHECK_ERROR_QUEUE_ON_RETURN;
X509* x509 = reinterpret_cast<X509*>(static_cast<uintptr_t>(x509Ref));
JNI_TRACE("i2d_X509(%p)", x509);
-
- if (x509 == nullptr) {
- conscrypt::jniutil::throwNullPointerException(env, "x509 == null");
- JNI_TRACE("i2d_X509(%p) => x509 == null", x509);
- return nullptr;
- }
return ASN1ToByteArray<X509>(env, x509, i2d_X509);
}
@@ -5621,12 +5536,6 @@ static jbyteArray NativeCrypto_i2d_X509_PUBKEY(JNIEnv* env, jclass, jlong x509Re
CHECK_ERROR_QUEUE_ON_RETURN;
X509* x509 = reinterpret_cast<X509*>(static_cast<uintptr_t>(x509Ref));
JNI_TRACE("i2d_X509_PUBKEY(%p)", x509);
-
- if (x509 == nullptr) {
- conscrypt::jniutil::throwNullPointerException(env, "x509 == null");
- JNI_TRACE("i2d_X509_PUBKEY(%p) => x509 == null", x509);
- return nullptr;
- }
return ASN1ToByteArray<X509_PUBKEY>(env, X509_get_X509_PUBKEY(x509), i2d_X509_PUBKEY);
}
@@ -6040,12 +5949,6 @@ static jbyteArray NativeCrypto_X509_get_issuer_name(JNIEnv* env, jclass, jlong x
CHECK_ERROR_QUEUE_ON_RETURN;
X509* x509 = reinterpret_cast<X509*>(static_cast<uintptr_t>(x509Ref));
JNI_TRACE("X509_get_issuer_name(%p)", x509);
-
- if (x509 == nullptr) {
- conscrypt::jniutil::throwNullPointerException(env, "x509 == null");
- JNI_TRACE("X509_get_issuer_name(%p) => x509 == null", x509);
- return nullptr;
- }
return ASN1ToByteArray<X509_NAME>(env, X509_get_issuer_name(x509), i2d_X509_NAME);
}
@@ -6054,12 +5957,6 @@ static jbyteArray NativeCrypto_X509_get_subject_name(JNIEnv* env, jclass, jlong
CHECK_ERROR_QUEUE_ON_RETURN;
X509* x509 = reinterpret_cast<X509*>(static_cast<uintptr_t>(x509Ref));
JNI_TRACE("X509_get_subject_name(%p)", x509);
-
- if (x509 == nullptr) {
- conscrypt::jniutil::throwNullPointerException(env, "x509 == null");
- JNI_TRACE("X509_get_subject_name(%p) => x509 == null", x509);
- return nullptr;
- }
return ASN1ToByteArray<X509_NAME>(env, X509_get_subject_name(x509), i2d_X509_NAME);
}
@@ -6302,12 +6199,6 @@ static jbyteArray NativeCrypto_X509_CRL_get_ext_oid(JNIEnv* env, jclass, jlong x
CHECK_ERROR_QUEUE_ON_RETURN;
X509_CRL* crl = reinterpret_cast<X509_CRL*>(static_cast<uintptr_t>(x509CrlRef));
JNI_TRACE("X509_CRL_get_ext_oid(%p, %p)", crl, oidString);
-
- if (crl == nullptr) {
- conscrypt::jniutil::throwNullPointerException(env, "crl == null");
- JNI_TRACE("X509_CRL_get_ext_oid(%p) => crl == null", crl);
- return nullptr;
- }
return X509Type_get_ext_oid<X509_CRL, X509_CRL_get_ext_by_OBJ, X509_CRL_get_ext>(env, crl,
oidString);
}
@@ -6317,12 +6208,6 @@ static jbyteArray NativeCrypto_X509_REVOKED_get_ext_oid(JNIEnv* env, jclass, jlo
CHECK_ERROR_QUEUE_ON_RETURN;
X509_REVOKED* revoked = reinterpret_cast<X509_REVOKED*>(static_cast<uintptr_t>(x509RevokedRef));
JNI_TRACE("X509_REVOKED_get_ext_oid(%p, %p)", revoked, oidString);
-
- if (revoked == nullptr) {
- conscrypt::jniutil::throwNullPointerException(env, "revoked == null");
- JNI_TRACE("X509_REVOKED_get_ext_oid(%p) => revoked == null", revoked);
- return nullptr;
- }
return X509Type_get_ext_oid<X509_REVOKED, X509_REVOKED_get_ext_by_OBJ, X509_REVOKED_get_ext>(
env, revoked, oidString);
}
@@ -7260,7 +7145,8 @@ static jlong NativeCrypto_SSL_new(JNIEnv* env, jclass, jlong ssl_ctx_address,
}
static void NativeCrypto_SSL_enable_tls_channel_id(JNIEnv* env, jclass, jlong ssl_address,
- CONSCRYPT_UNUSED jobject ssl_holder) {
+ CONSCRYPT_UNUSED CONSCRYPT_UNUSED jobject
+ ssl_holder) {
CHECK_ERROR_QUEUE_ON_RETURN;
SSL* ssl = to_SSL(env, ssl_address, true);
JNI_TRACE("ssl=%p NativeCrypto_SSL_enable_tls_channel_id", ssl);
diff --git a/common/src/test/java/org/conscrypt/ConscryptSuite.java b/common/src/test/java/org/conscrypt/ConscryptSuite.java
index cce41d5d..263afcd0 100644
--- a/common/src/test/java/org/conscrypt/ConscryptSuite.java
+++ b/common/src/test/java/org/conscrypt/ConscryptSuite.java
@@ -35,7 +35,6 @@ import org.conscrypt.java.security.KeyFactoryTestDH;
import org.conscrypt.java.security.KeyFactoryTestDSA;
import org.conscrypt.java.security.KeyFactoryTestEC;
import org.conscrypt.java.security.KeyFactoryTestRSA;
-import org.conscrypt.java.security.KeyFactoryTestRSACrt;
import org.conscrypt.java.security.KeyPairGeneratorTest;
import org.conscrypt.java.security.KeyPairGeneratorTestDH;
import org.conscrypt.java.security.KeyPairGeneratorTestDSA;
@@ -81,9 +80,8 @@ import org.junit.runners.Suite;
// org.conscrypt tests
CertPinManagerTest.class,
ChainStrengthAnalyzerTest.class,
- HostnameVerifierTest.class,
- NativeCryptoArgTest.class,
TrustManagerImplTest.class,
+ HostnameVerifierTest.class,
// org.conscrypt.ct tests
CTVerifierTest.class,
SerializationTest.class,
@@ -108,7 +106,6 @@ import org.junit.runners.Suite;
KeyFactoryTestDSA.class,
KeyFactoryTestEC.class,
KeyFactoryTestRSA.class,
- KeyFactoryTestRSACrt.class,
KeyPairGeneratorTest.class,
KeyPairGeneratorTestDH.class,
KeyPairGeneratorTestDSA.class,
diff --git a/common/src/test/java/org/conscrypt/NativeCryptoArgTest.java b/common/src/test/java/org/conscrypt/NativeCryptoArgTest.java
deleted file mode 100644
index 76e8beb7..00000000
--- a/common/src/test/java/org/conscrypt/NativeCryptoArgTest.java
+++ /dev/null
@@ -1,331 +0,0 @@
-/*
- * Copyright (C) 2020 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 static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import java.io.FileDescriptor;
-import java.io.IOException;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import org.junit.AfterClass;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-@RunWith(JUnit4.class)
-public class NativeCryptoArgTest {
- // Null value passed in for a long which represents a native address
- private static final long NULL = 0L;
- /*
- * Non-null value passed in for a long which represents a native address. Shouldn't
- * ever get de-referenced but we make it a multiple of 4 to avoid any alignment errors.
- * Used in the case where there are multiple checks we want to test in a native method,
- * so we can get past the first check and test the second one.
- */
- private static final long NOT_NULL = 4L;
- private static final String CONSCRYPT_PACKAGE = NativeCryptoArgTest.class.getCanonicalName()
- .substring(0, NativeCryptoArgTest.class.getCanonicalName().lastIndexOf('.') + 1);
- private static final Set<String> testedMethods = new HashSet<>();
- private final Map<String, Class<?>> classCache = new HashMap<>();
- private final Map<String, Method> methodMap = buildMethodMap();
-
- @AfterClass
- public static void after() {
- // TODO(prb): Temporary hacky check - remove
- assertTrue(testedMethods.size() >= 190);
- }
-
- @Test
- public void ecMethods() throws Throwable {
- String[] illegalArgMethods = new String[] {
- "EC_GROUP_new_arbitrary"
- };
- String[] ioExMethods = new String[] {
- "EC_KEY_parse_curve_name",
- "EC_KEY_marshal_curve_name"
- };
-
- // All of the EC_* methods apart from the exceptions below throw NPE if their
- // first argument is null.
- MethodFilter filter = MethodFilter.newBuilder("EC_ methods")
- .hasPrefix("EC_")
- .except(illegalArgMethods)
- .except(ioExMethods)
- .expectSize(16)
- .build();
- testMethods(filter, NullPointerException.class);
-
- filter = MethodFilter.nameFilter("EC_ methods (IllegalArgument)", illegalArgMethods);
- testMethods(filter, IllegalArgumentException.class);
-
- filter = MethodFilter.nameFilter("EC_ methods (IOException)", ioExMethods);
- testMethods(filter, IOException.class);
- }
-
- @Test
- public void macMethods() throws Throwable {
- // All of the non-void HMAC and CMAC methods throw NPE when passed a null pointer
- MethodFilter filter = MethodFilter.newBuilder("HMAC methods")
- .hasPrefix("HMAC_")
- .takesArguments()
- .expectSize(5)
- .build();
- testMethods(filter, NullPointerException.class);
-
- filter = MethodFilter.newBuilder("CMAC methods")
- .hasPrefix("CMAC_")
- .takesArguments()
- .expectSize(5)
- .build();
- testMethods(filter, NullPointerException.class);
- }
-
- @Test
- public void sslMethods() throws Throwable {
- // These methods don't throw on a null first arg as they can get called before the
- // connection is fully initialised. However if the first arg is non-NULL, any subsequent
- // null args should throw NPE.
- String[] nonThrowingMethods = new String[] {
- "SSL_interrupt",
- "SSL_shutdown",
- "ENGINE_SSL_shutdown",
- };
-
- // Most of the NativeSsl methods take a long holding a pointer to the native
- // object followed by a {@code NativeSsl} holder object. However the second arg
- // is unused(!) so we don't need to test it.
- MethodFilter filter = MethodFilter.newBuilder("NativeSsl methods")
- .hasArg(0, long.class)
- .hasArg(1, conscryptClass("NativeSsl"))
- .except(nonThrowingMethods)
- .expectSize(60)
- .build();
-
- testMethods(filter, NullPointerException.class);
-
- // Many of the SSL_* methods take a single long which points
- // to a native object.
- filter = MethodFilter.newBuilder("1-arg SSL methods")
- .hasPrefix("SSL_")
- .hasArgLength(1)
- .hasArg(0, long.class)
- .expectSize(10)
- .build();
-
- testMethods(filter, NullPointerException.class);
-
- filter = MethodFilter.nameFilter("Non throwing NativeSsl methods", nonThrowingMethods);
- testMethods(filter, null);
-
- expectVoid("SSL_shutdown", NOT_NULL, null, null, null);
- expectNPE("SSL_shutdown", NOT_NULL, null, new FileDescriptor(), null);
- expectNPE("ENGINE_SSL_shutdown", NOT_NULL, null, null);
- expectVoid("SSL_set_session", NOT_NULL, null, NULL);
- }
-
- @Test
- public void evpMethods() throws Throwable {
- String[] illegalArgMethods = new String[] {
- "EVP_AEAD_CTX_open_buf",
- "EVP_AEAD_CTX_seal_buf",
- "EVP_PKEY_new_RSA"
- };
- String[] nonThrowingMethods = new String[] {
- "EVP_MD_CTX_destroy",
- "EVP_PKEY_CTX_free",
- "EVP_PKEY_free",
- "EVP_CIPHER_CTX_free"
- };
-
- // All of the non-void EVP_ methods apart from the above should throw on a null
- // first argument.
- MethodFilter filter = MethodFilter.newBuilder("EVP methods")
- .hasPrefix("EVP_")
- .takesArguments()
- .except(illegalArgMethods)
- .except(nonThrowingMethods)
- .expectSize(45)
- .build();
-
- testMethods(filter, NullPointerException.class);
-
- filter = MethodFilter.nameFilter("EVP methods (IllegalArgument)", illegalArgMethods);
- testMethods(filter, IllegalArgumentException.class);
-
- filter = MethodFilter.nameFilter("EVP methods (non-throwing)", nonThrowingMethods);
- testMethods(filter, null);
- }
-
- @Test
- public void x509Methods() throws Throwable {
- // A number of X509 methods have a native pointer as arg 0 and an
- // OpenSSLX509Certificate or OpenSSLX509CRL as arg 1.
- MethodFilter filter = MethodFilter.newBuilder("X509 methods")
- .hasArgLength(2)
- .hasArg(0, long.class)
- .hasArg(1, conscryptClass("OpenSSLX509Certificate"),
- conscryptClass("OpenSSLX509CRL"))
- .expectSize(32)
- .build();
- // TODO(prb): test null second argument
- testMethods(filter, NullPointerException.class);
-
- // The rest of the X509 methods are somewhat ad hoc.
- expectNPE("d2i_X509", (Object) null);
-
- invokeAndExpect( conscryptThrowable("OpenSSLX509CertificateFactory$ParsingException"),
- "d2i_X509", new byte[]{0, 0, 0, 0, 0, 0, 0, 0, 0});
-
- expectNPE("d2i_X509_bio", NULL);
- expectNPE("PEM_read_bio_X509", NULL);
- expectNPE("ASN1_seq_pack_X509", (Object) null);
-
- // TODO(prb): Check what this should really throw
- // expectNPE("ASN1_seq_pack_X509", (Object) new long[] { NULL });
-
- expectNPE("ASN1_seq_unpack_X509_bio", NULL);
-
- //
- expectNPE("X509_cmp", NULL, null, NULL, null);
- expectNPE("X509_cmp", NOT_NULL, null, NULL, null);
- expectNPE("X509_cmp", NULL, null, NOT_NULL, null);
-
- expectNPE("X509_print_ex", NULL, NULL, null, NULL, NULL);
- expectNPE("X509_print_ex", NOT_NULL, NULL, null, NULL, NULL);
- expectNPE("X509_print_ex", NULL, NOT_NULL, null, NULL, NULL);
- }
-
- private void testMethods(MethodFilter filter, Class<? extends Throwable> exceptionClass)
- throws Throwable {
- List<Method> methods = filter.filter(methodMap.values());
-
- for (Method method : methods) {
- List<Object[]> argsLists = permuteArgs(method);
- for (Object[] args : argsLists) {
- invokeAndExpect(exceptionClass, method, args);
- }
- }
- }
-
- private List<Object[]> permuteArgs(Method method) {
- // For now just supply 0 for integral types and null for everything else
- // TODO: allow user defined strategy, e.g. if two longs passed as native refs,
- // generate {NULL,NULL}, {NULL,NOT_NULL}, {NOT_NULL,NULL} to test both null checks
- List<Object[]> result = new ArrayList<>(1);
-
- Class<?>[] argTypes = method.getParameterTypes();
-
- int argCount = argTypes.length;
- assertTrue(argCount > 0);
- Object[] args = new Object[argCount];
-
- for (int arg = 0; arg < argCount; arg++) {
- if (argTypes[arg] == int.class) {
- args[arg] = 0;
- } else if (argTypes[arg] == long.class) {
- args[arg] = NULL;
- } else if (argTypes[arg] == boolean.class) {
- args[arg] = false;
- } else {
- args[arg] = null;
- }
- }
- result.add(args);
- return result;
- }
-
- private void expectVoid(String methodName, Object... args) throws Throwable {
- invokeAndExpect(null, methodName, args);
- }
-
- private void expectNPE(String methodName, Object... args) throws Throwable {
- invokeAndExpect(NullPointerException.class, methodName, args);
- }
-
- private void invokeAndExpect(Class<? extends Throwable> expectedThrowable, String methodName,
- Object... args) throws Throwable {
- Method method = methodMap.get(methodName);
- assertNotNull(method);
- assertEquals(methodName, method.getName());
- invokeAndExpect(expectedThrowable, method, args);
- }
-
- private void invokeAndExpect(Class<? extends Throwable> expectedThrowable, Method method,
- Object... args) throws Throwable {
- try {
- method.invoke(null, args);
- if (expectedThrowable != null) {
- fail("No exception thrown by method " + method.getName());
- }
- } catch (IllegalAccessException e) {
- throw new AssertionError("Illegal access", e);
- } catch (InvocationTargetException e) {
- Throwable cause = e.getCause();
- if (expectedThrowable != null) {
- assertEquals("Method: " + method.getName(), expectedThrowable, cause.getClass());
- } else {
- throw cause;
- }
- }
- testedMethods.add(method.getName());
- }
-
- @SuppressWarnings("unchecked")
- private Class<? extends Throwable> conscryptThrowable(String name) {
- Class<?> klass = conscryptClass(name);
- assertNotNull(klass);
- assertTrue(Throwable.class.isAssignableFrom(klass));
- return (Class<? extends Throwable>) klass;
- }
-
- private Class<?> conscryptClass(String className) {
- return classCache.computeIfAbsent(className, s -> {
- try {
- return Class.forName(CONSCRYPT_PACKAGE + className);
- } catch (ClassNotFoundException e) {
- return null;
- }
- });
- }
-
- private Map<String, Method> buildMethodMap() {
- Map<String, Method> classMap = new HashMap<>();
- assertNotNull(classMap);
- Class<?> nativeCryptoClass = conscryptClass("NativeCrypto");
- assertNotNull(nativeCryptoClass);
- for (Method method : nativeCryptoClass.getDeclaredMethods()) {
- int modifiers = method.getModifiers();
- if (!Modifier.isNative(modifiers)) {
- continue;
- }
- method.setAccessible(true);
- classMap.put(method.getName(), method);
- }
- return classMap;
- }
-}
diff --git a/common/src/test/java/org/conscrypt/java/security/KeyFactoryTestRSA.java b/common/src/test/java/org/conscrypt/java/security/KeyFactoryTestRSA.java
index 571c1a79..ff9be813 100644
--- a/common/src/test/java/org/conscrypt/java/security/KeyFactoryTestRSA.java
+++ b/common/src/test/java/org/conscrypt/java/security/KeyFactoryTestRSA.java
@@ -42,6 +42,7 @@ import libcore.junit.util.EnableDeprecatedBouncyCastleAlgorithmsRule;
import java.util.Arrays;
import java.util.List;
import org.junit.ClassRule;
+import org.junit.Ignore;
import org.junit.Test;
import org.junit.rules.TestRule;
import org.junit.runner.RunWith;
@@ -68,6 +69,7 @@ public class KeyFactoryTestRSA extends
}
@Test
+ @Ignore("b/209335673 Base image has fix for b/191150645 but release version of module does not")
public void getEncodedFailsWhenCrtValuesMissing() throws Exception {
PrivateKey privateKey = getPrivateKey();
try {
@@ -119,6 +121,7 @@ public class KeyFactoryTestRSA extends
}
@Test
+ @Ignore("b/209335673 Base image has fix for b/191150645 but release version of module does not")
public void javaSerialization() throws Exception{
PrivateKey privatekey = getPrivateKey();
@@ -133,12 +136,13 @@ public class KeyFactoryTestRSA extends
assertEquals(privatekey, copy);
}
- @Override
- protected List<KeyPair> getKeys() throws NoSuchAlgorithmException, InvalidKeySpecException {
- return Arrays.asList(
- new KeyPair(DefaultKeys.getPublicKey(algorithmName), getPrivateKey())
- );
- }
+ // b/209335673 Base image has fix for b/191150645 but release version of module does not,
+ // @Override
+ // protected List<KeyPair> getKeys() throws NoSuchAlgorithmException, InvalidKeySpecException {
+ // return Arrays.asList(
+ // new KeyPair(DefaultKeys.getPublicKey(algorithmName), getPrivateKey())
+ // );
+ // }
// The private RSA key returned by DefaultKeys.getPrivateKey() is built from a PKCS#8
// KeySpec and so will be an instance of RSAPrivateCrtKey, but we want to test RSAPrivateKey
diff --git a/common/src/test/java/org/conscrypt/java/security/KeyFactoryTestRSACrt.java b/common/src/test/java/org/conscrypt/java/security/KeyFactoryTestRSACrt.java
index bddd898c..3afa73f6 100644
--- a/common/src/test/java/org/conscrypt/java/security/KeyFactoryTestRSACrt.java
+++ b/common/src/test/java/org/conscrypt/java/security/KeyFactoryTestRSACrt.java
@@ -30,6 +30,7 @@ import java.security.interfaces.RSAPrivateCrtKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.RSAPrivateCrtKeySpec;
import java.security.spec.RSAPublicKeySpec;
+import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
@@ -59,7 +60,8 @@ public class KeyFactoryTestRSACrt extends
@Test
public void testExtraBufferSpace_Private() throws Exception {
PrivateKey privateKey = DefaultKeys.getPrivateKey("RSA");
- assertTrue(privateKey instanceof RSAPrivateCrtKey);
+ // b/209335673 Base image has fix for b/191150645 but release version of module does not
+ // assertTrue(privateKey instanceof RSAPrivateCrtKey);
byte[] encoded = privateKey.getEncoded();
byte[] longBuffer = new byte[encoded.length + 147];
@@ -70,6 +72,7 @@ public class KeyFactoryTestRSACrt extends
}
@Test
+ @Ignore("b/209335673 Base image has fix for b/191150645 but release version of module does not")
public void javaSerialization() throws Exception{
PrivateKey privateKey = DefaultKeys.getPrivateKey("RSA");
assertTrue(privateKey instanceof RSAPrivateCrtKey);
diff --git a/common/src/test/java/org/conscrypt/javax/crypto/CipherTest.java b/common/src/test/java/org/conscrypt/javax/crypto/CipherTest.java
index ad5b52ab..439b554d 100644
--- a/common/src/test/java/org/conscrypt/javax/crypto/CipherTest.java
+++ b/common/src/test/java/org/conscrypt/javax/crypto/CipherTest.java
@@ -147,33 +147,6 @@ public final class CipherTest {
|| algorithm.equals("AES/OFB/PKCS7PADDING"))) {
return false;
}
-
- if (provider.equals("BC")) {
- return isSupportedByBC(algorithm);
- }
-
- return true;
- }
-
- /**
- * Checks for algorithms removed from BC in Android 12 and so not usable for these
- * tests.
- *
- * TODO(prb): make this version aware, as this test runs against BC on older Android
- * versions via MTS and should continue to test these algorithms there.
- *
- */
- private static boolean isSupportedByBC(String algorithm) {
- String[] removedBcPrefices = new String[]{
- "AES/ECB",
- "AES/CBC",
- "AES/GCM"
- };
- for (String prefix : removedBcPrefices) {
- if (algorithm.startsWith(prefix)) {
- return false;
- }
- }
return true;
}
@@ -1106,9 +1079,7 @@ public final class CipherTest {
for (String padding : paddings) {
final String algorithmName = algorithm + "/" + mode + "/" + padding;
try {
- if (isSupported(algorithmName, provider.getName())) {
- test_Cipher_Algorithm(provider, algorithmName);
- }
+ test_Cipher_Algorithm(provider, algorithmName);
} catch (Throwable e) {
out.append("Error encountered checking " + algorithmName
+ " with provider " + provider.getName() + "\n");
@@ -3503,9 +3474,6 @@ public final class CipherTest {
if (provider.equals("SunJCE") && transformation.endsWith("/PKCS7PADDING")) {
return false;
}
- if (provider.equals("BC")) {
- return isSupportedByBC(transformation);
- }
return true;
}
}
@@ -4133,9 +4101,6 @@ public final class CipherTest {
final ByteArrayOutputStream errBuffer = new ByteArrayOutputStream();
PrintStream out = new PrintStream(errBuffer);
for (CipherTestParam p : CIPHER_TEST_PARAMS) {
- if (!p.compatibleWith(provider)) {
- continue;
- }
try {
checkCipher_ShortBlock_Failure(p, provider);
} catch (Exception e) {
@@ -4335,6 +4300,32 @@ public final class CipherTest {
}
}
+ // Test that when reading GCM parameters encoded using ASN1, a value for the tag size
+ // not present indicates a value of 12.
+ // https://b/29876633
+ @Test
+ public void test_DefaultGCMTagSizeAlgorithmParameterSpec() throws Exception {
+ Assume.assumeNotNull(Security.getProvider("BC"));
+ final String AES = "AES";
+ final String AES_GCM = "AES/GCM/NoPadding";
+ byte[] input = new byte[16];
+ byte[] key = new byte[16];
+ Cipher cipher = Cipher.getInstance(AES_GCM, "BC");
+ AlgorithmParameters param = AlgorithmParameters.getInstance("GCM");
+ param.init(new byte[] {
+ (byte) 48, // DER encoding : tag_Sequence
+ (byte) 14, // DER encoding : total length
+ (byte) 4, // DER encoding : tag_OctetString
+ (byte) 12, // DER encoding : counter length
+ (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0,
+ (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0 });
+ cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(key, AES), param);
+ byte[] ciphertext = cipher.update(input);
+ assertEquals(16, ciphertext.length);
+ byte[] tag = cipher.doFinal();
+ assertEquals(12, tag.length);
+ }
+
@Test
public void testAES_ECB_PKCS5Padding_ShortBuffer_Failure() throws Exception {
for (String provider : AES_PROVIDERS) {
@@ -4397,11 +4388,7 @@ public final class CipherTest {
}
private void testAES_ECB_NoPadding_IncrementalUpdate_Success(String provider) throws Exception {
- String algorithm = "AES/ECB/NoPadding";
- if (!isSupported(algorithm, provider)) {
- return;
- }
- Cipher c = Cipher.getInstance(algorithm, provider);
+ Cipher c = Cipher.getInstance("AES/ECB/NoPadding", provider);
assertEquals(provider, c.getProvider().getName());
c.init(Cipher.ENCRYPT_MODE, AES_128_KEY);
@@ -4435,11 +4422,7 @@ public final class CipherTest {
}
private void testAES_ECB_NoPadding_IvParameters_Failure(String provider) throws Exception {
- String algorithm = "AES/ECB/NoPadding";
- if (!isSupported(algorithm, provider)) {
- return;
- }
- Cipher c = Cipher.getInstance(algorithm, provider);
+ Cipher c = Cipher.getInstance("AES/ECB/NoPadding", provider);
AlgorithmParameterSpec spec = new IvParameterSpec(AES_IV_ZEROES);
try {
diff --git a/repackaged/common/src/test/java/com/android/org/conscrypt/NativeCryptoArgTest.java b/repackaged/common/src/test/java/com/android/org/conscrypt/NativeCryptoArgTest.java
deleted file mode 100644
index db096a0f..00000000
--- a/repackaged/common/src/test/java/com/android/org/conscrypt/NativeCryptoArgTest.java
+++ /dev/null
@@ -1,335 +0,0 @@
-/* GENERATED SOURCE. DO NOT MODIFY. */
-/*
- * Copyright (C) 2020 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 static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import java.io.FileDescriptor;
-import java.io.IOException;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import org.junit.AfterClass;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-/**
- * @hide This class is not part of the Android public SDK API
- */
-@RunWith(JUnit4.class)
-public class NativeCryptoArgTest {
- // Null value passed in for a long which represents a native address
- private static final long NULL = 0L;
- /*
- * Non-null value passed in for a long which represents a native address. Shouldn't
- * ever get de-referenced but we make it a multiple of 4 to avoid any alignment errors.
- * Used in the case where there are multiple checks we want to test in a native method,
- * so we can get past the first check and test the second one.
- */
- private static final long NOT_NULL = 4L;
- private static final String CONSCRYPT_PACKAGE = NativeCryptoArgTest.class.getCanonicalName()
- .substring(0, NativeCryptoArgTest.class.getCanonicalName().lastIndexOf('.') + 1);
- private static final Set<String> testedMethods = new HashSet<>();
- private final Map<String, Class<?>> classCache = new HashMap<>();
- private final Map<String, Method> methodMap = buildMethodMap();
-
- @AfterClass
- public static void after() {
- // TODO(prb): Temporary hacky check - remove
- assertTrue(testedMethods.size() >= 190);
- }
-
- @Test
- public void ecMethods() throws Throwable {
- String[] illegalArgMethods = new String[] {
- "EC_GROUP_new_arbitrary"
- };
- String[] ioExMethods = new String[] {
- "EC_KEY_parse_curve_name",
- "EC_KEY_marshal_curve_name"
- };
-
- // All of the EC_* methods apart from the exceptions below throw NPE if their
- // first argument is null.
- MethodFilter filter = MethodFilter.newBuilder("EC_ methods")
- .hasPrefix("EC_")
- .except(illegalArgMethods)
- .except(ioExMethods)
- .expectSize(16)
- .build();
- testMethods(filter, NullPointerException.class);
-
- filter = MethodFilter.nameFilter("EC_ methods (IllegalArgument)", illegalArgMethods);
- testMethods(filter, IllegalArgumentException.class);
-
- filter = MethodFilter.nameFilter("EC_ methods (IOException)", ioExMethods);
- testMethods(filter, IOException.class);
- }
-
- @Test
- public void macMethods() throws Throwable {
- // All of the non-void HMAC and CMAC methods throw NPE when passed a null pointer
- MethodFilter filter = MethodFilter.newBuilder("HMAC methods")
- .hasPrefix("HMAC_")
- .takesArguments()
- .expectSize(5)
- .build();
- testMethods(filter, NullPointerException.class);
-
- filter = MethodFilter.newBuilder("CMAC methods")
- .hasPrefix("CMAC_")
- .takesArguments()
- .expectSize(5)
- .build();
- testMethods(filter, NullPointerException.class);
- }
-
- @Test
- public void sslMethods() throws Throwable {
- // These methods don't throw on a null first arg as they can get called before the
- // connection is fully initialised. However if the first arg is non-NULL, any subsequent
- // null args should throw NPE.
- String[] nonThrowingMethods = new String[] {
- "SSL_interrupt",
- "SSL_shutdown",
- "ENGINE_SSL_shutdown",
- };
-
- // Most of the NativeSsl methods take a long holding a pointer to the native
- // object followed by a {@code NativeSsl} holder object. However the second arg
- // is unused(!) so we don't need to test it.
- MethodFilter filter = MethodFilter.newBuilder("NativeSsl methods")
- .hasArg(0, long.class)
- .hasArg(1, conscryptClass("NativeSsl"))
- .except(nonThrowingMethods)
- .expectSize(60)
- .build();
-
- testMethods(filter, NullPointerException.class);
-
- // Many of the SSL_* methods take a single long which points
- // to a native object.
- filter = MethodFilter.newBuilder("1-arg SSL methods")
- .hasPrefix("SSL_")
- .hasArgLength(1)
- .hasArg(0, long.class)
- .expectSize(10)
- .build();
-
- testMethods(filter, NullPointerException.class);
-
- filter = MethodFilter.nameFilter("Non throwing NativeSsl methods", nonThrowingMethods);
- testMethods(filter, null);
-
- expectVoid("SSL_shutdown", NOT_NULL, null, null, null);
- expectNPE("SSL_shutdown", NOT_NULL, null, new FileDescriptor(), null);
- expectNPE("ENGINE_SSL_shutdown", NOT_NULL, null, null);
- expectVoid("SSL_set_session", NOT_NULL, null, NULL);
- }
-
- @Test
- public void evpMethods() throws Throwable {
- String[] illegalArgMethods = new String[] {
- "EVP_AEAD_CTX_open_buf",
- "EVP_AEAD_CTX_seal_buf",
- "EVP_PKEY_new_RSA"
- };
- String[] nonThrowingMethods = new String[] {
- "EVP_MD_CTX_destroy",
- "EVP_PKEY_CTX_free",
- "EVP_PKEY_free",
- "EVP_CIPHER_CTX_free"
- };
-
- // All of the non-void EVP_ methods apart from the above should throw on a null
- // first argument.
- MethodFilter filter = MethodFilter.newBuilder("EVP methods")
- .hasPrefix("EVP_")
- .takesArguments()
- .except(illegalArgMethods)
- .except(nonThrowingMethods)
- .expectSize(45)
- .build();
-
- testMethods(filter, NullPointerException.class);
-
- filter = MethodFilter.nameFilter("EVP methods (IllegalArgument)", illegalArgMethods);
- testMethods(filter, IllegalArgumentException.class);
-
- filter = MethodFilter.nameFilter("EVP methods (non-throwing)", nonThrowingMethods);
- testMethods(filter, null);
- }
-
- @Test
- public void x509Methods() throws Throwable {
- // A number of X509 methods have a native pointer as arg 0 and an
- // OpenSSLX509Certificate or OpenSSLX509CRL as arg 1.
- MethodFilter filter = MethodFilter.newBuilder("X509 methods")
- .hasArgLength(2)
- .hasArg(0, long.class)
- .hasArg(1, conscryptClass("OpenSSLX509Certificate"),
- conscryptClass("OpenSSLX509CRL"))
- .expectSize(32)
- .build();
- // TODO(prb): test null second argument
- testMethods(filter, NullPointerException.class);
-
- // The rest of the X509 methods are somewhat ad hoc.
- expectNPE("d2i_X509", (Object) null);
-
- invokeAndExpect( conscryptThrowable("OpenSSLX509CertificateFactory$ParsingException"),
- "d2i_X509", new byte[]{0, 0, 0, 0, 0, 0, 0, 0, 0});
-
- expectNPE("d2i_X509_bio", NULL);
- expectNPE("PEM_read_bio_X509", NULL);
- expectNPE("ASN1_seq_pack_X509", (Object) null);
-
- // TODO(prb): Check what this should really throw
- // expectNPE("ASN1_seq_pack_X509", (Object) new long[] { NULL });
-
- expectNPE("ASN1_seq_unpack_X509_bio", NULL);
-
- //
- expectNPE("X509_cmp", NULL, null, NULL, null);
- expectNPE("X509_cmp", NOT_NULL, null, NULL, null);
- expectNPE("X509_cmp", NULL, null, NOT_NULL, null);
-
- expectNPE("X509_print_ex", NULL, NULL, null, NULL, NULL);
- expectNPE("X509_print_ex", NOT_NULL, NULL, null, NULL, NULL);
- expectNPE("X509_print_ex", NULL, NOT_NULL, null, NULL, NULL);
- }
-
- private void testMethods(MethodFilter filter, Class<? extends Throwable> exceptionClass)
- throws Throwable {
- List<Method> methods = filter.filter(methodMap.values());
-
- for (Method method : methods) {
- List<Object[]> argsLists = permuteArgs(method);
- for (Object[] args : argsLists) {
- invokeAndExpect(exceptionClass, method, args);
- }
- }
- }
-
- private List<Object[]> permuteArgs(Method method) {
- // For now just supply 0 for integral types and null for everything else
- // TODO: allow user defined strategy, e.g. if two longs passed as native refs,
- // generate {NULL,NULL}, {NULL,NOT_NULL}, {NOT_NULL,NULL} to test both null checks
- List<Object[]> result = new ArrayList<>(1);
-
- Class<?>[] argTypes = method.getParameterTypes();
-
- int argCount = argTypes.length;
- assertTrue(argCount > 0);
- Object[] args = new Object[argCount];
-
- for (int arg = 0; arg < argCount; arg++) {
- if (argTypes[arg] == int.class) {
- args[arg] = 0;
- } else if (argTypes[arg] == long.class) {
- args[arg] = NULL;
- } else if (argTypes[arg] == boolean.class) {
- args[arg] = false;
- } else {
- args[arg] = null;
- }
- }
- result.add(args);
- return result;
- }
-
- private void expectVoid(String methodName, Object... args) throws Throwable {
- invokeAndExpect(null, methodName, args);
- }
-
- private void expectNPE(String methodName, Object... args) throws Throwable {
- invokeAndExpect(NullPointerException.class, methodName, args);
- }
-
- private void invokeAndExpect(Class<? extends Throwable> expectedThrowable, String methodName,
- Object... args) throws Throwable {
- Method method = methodMap.get(methodName);
- assertNotNull(method);
- assertEquals(methodName, method.getName());
- invokeAndExpect(expectedThrowable, method, args);
- }
-
- private void invokeAndExpect(Class<? extends Throwable> expectedThrowable, Method method,
- Object... args) throws Throwable {
- try {
- method.invoke(null, args);
- if (expectedThrowable != null) {
- fail("No exception thrown by method " + method.getName());
- }
- } catch (IllegalAccessException e) {
- throw new AssertionError("Illegal access", e);
- } catch (InvocationTargetException e) {
- Throwable cause = e.getCause();
- if (expectedThrowable != null) {
- assertEquals("Method: " + method.getName(), expectedThrowable, cause.getClass());
- } else {
- throw cause;
- }
- }
- testedMethods.add(method.getName());
- }
-
- @SuppressWarnings("unchecked")
- private Class<? extends Throwable> conscryptThrowable(String name) {
- Class<?> klass = conscryptClass(name);
- assertNotNull(klass);
- assertTrue(Throwable.class.isAssignableFrom(klass));
- return (Class<? extends Throwable>) klass;
- }
-
- private Class<?> conscryptClass(String className) {
- return classCache.computeIfAbsent(className, s -> {
- try {
- return Class.forName(CONSCRYPT_PACKAGE + className);
- } catch (ClassNotFoundException e) {
- return null;
- }
- });
- }
-
- private Map<String, Method> buildMethodMap() {
- Map<String, Method> classMap = new HashMap<>();
- assertNotNull(classMap);
- Class<?> nativeCryptoClass = conscryptClass("NativeCrypto");
- assertNotNull(nativeCryptoClass);
- for (Method method : nativeCryptoClass.getDeclaredMethods()) {
- int modifiers = method.getModifiers();
- if (!Modifier.isNative(modifiers)) {
- continue;
- }
- method.setAccessible(true);
- classMap.put(method.getName(), method);
- }
- return classMap;
- }
-}
diff --git a/repackaged/common/src/test/java/com/android/org/conscrypt/java/security/KeyFactoryTestRSA.java b/repackaged/common/src/test/java/com/android/org/conscrypt/java/security/KeyFactoryTestRSA.java
index b4287f90..1c51b59d 100644
--- a/repackaged/common/src/test/java/com/android/org/conscrypt/java/security/KeyFactoryTestRSA.java
+++ b/repackaged/common/src/test/java/com/android/org/conscrypt/java/security/KeyFactoryTestRSA.java
@@ -43,6 +43,7 @@ import java.util.Arrays;
import java.util.List;
import libcore.junit.util.EnableDeprecatedBouncyCastleAlgorithmsRule;
import org.junit.ClassRule;
+import org.junit.Ignore;
import org.junit.Test;
import org.junit.rules.TestRule;
import org.junit.runner.RunWith;
@@ -71,6 +72,7 @@ public class KeyFactoryTestRSA extends AbstractKeyFactoryTest<RSAPublicKeySpec,
}
@Test
+ @Ignore("b/209335673 Base image has fix for b/191150645 but release version of module does not")
public void getEncodedFailsWhenCrtValuesMissing() throws Exception {
PrivateKey privateKey = getPrivateKey();
try {
@@ -122,6 +124,7 @@ public class KeyFactoryTestRSA extends AbstractKeyFactoryTest<RSAPublicKeySpec,
}
@Test
+ @Ignore("b/209335673 Base image has fix for b/191150645 but release version of module does not")
public void javaSerialization() throws Exception {
PrivateKey privatekey = getPrivateKey();
@@ -136,10 +139,13 @@ public class KeyFactoryTestRSA extends AbstractKeyFactoryTest<RSAPublicKeySpec,
assertEquals(privatekey, copy);
}
- @Override
- protected List<KeyPair> getKeys() throws NoSuchAlgorithmException, InvalidKeySpecException {
- return Arrays.asList(new KeyPair(DefaultKeys.getPublicKey(algorithmName), getPrivateKey()));
- }
+ // b/209335673 Base image has fix for b/191150645 but release version of module does not,
+ // @Override
+ // protected List<KeyPair> getKeys() throws NoSuchAlgorithmException, InvalidKeySpecException {
+ // return Arrays.asList(
+ // new KeyPair(DefaultKeys.getPublicKey(algorithmName), getPrivateKey())
+ // );
+ // }
// The private RSA key returned by DefaultKeys.getPrivateKey() is built from a PKCS#8
// KeySpec and so will be an instance of RSAPrivateCrtKey, but we want to test RSAPrivateKey
diff --git a/repackaged/common/src/test/java/com/android/org/conscrypt/java/security/KeyFactoryTestRSACrt.java b/repackaged/common/src/test/java/com/android/org/conscrypt/java/security/KeyFactoryTestRSACrt.java
index 5e84e7cf..d8d8ebeb 100644
--- a/repackaged/common/src/test/java/com/android/org/conscrypt/java/security/KeyFactoryTestRSACrt.java
+++ b/repackaged/common/src/test/java/com/android/org/conscrypt/java/security/KeyFactoryTestRSACrt.java
@@ -31,6 +31,7 @@ import java.security.interfaces.RSAPrivateCrtKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.RSAPrivateCrtKeySpec;
import java.security.spec.RSAPublicKeySpec;
+import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
@@ -63,7 +64,8 @@ public class KeyFactoryTestRSACrt extends
@Test
public void testExtraBufferSpace_Private() throws Exception {
PrivateKey privateKey = DefaultKeys.getPrivateKey("RSA");
- assertTrue(privateKey instanceof RSAPrivateCrtKey);
+ // b/209335673 Base image has fix for b/191150645 but release version of module does not
+ // assertTrue(privateKey instanceof RSAPrivateCrtKey);
byte[] encoded = privateKey.getEncoded();
byte[] longBuffer = new byte[encoded.length + 147];
@@ -74,6 +76,7 @@ public class KeyFactoryTestRSACrt extends
}
@Test
+ @Ignore("b/209335673 Base image has fix for b/191150645 but release version of module does not")
public void javaSerialization() throws Exception {
PrivateKey privateKey = DefaultKeys.getPrivateKey("RSA");
assertTrue(privateKey instanceof RSAPrivateCrtKey);
diff --git a/repackaged/common/src/test/java/com/android/org/conscrypt/javax/crypto/CipherTest.java b/repackaged/common/src/test/java/com/android/org/conscrypt/javax/crypto/CipherTest.java
index 37c702b6..a418d672 100644
--- a/repackaged/common/src/test/java/com/android/org/conscrypt/javax/crypto/CipherTest.java
+++ b/repackaged/common/src/test/java/com/android/org/conscrypt/javax/crypto/CipherTest.java
@@ -151,29 +151,6 @@ public final class CipherTest {
|| algorithm.equals("AES/OFB/PKCS7PADDING"))) {
return false;
}
-
- if (provider.equals("BC")) {
- return isSupportedByBC(algorithm);
- }
-
- return true;
- }
-
- /**
- * Checks for algorithms removed from BC in Android 12 and so not usable for these
- * tests.
- *
- * TODO(prb): make this version aware, as this test runs against BC on older Android
- * versions via MTS and should continue to test these algorithms there.
- *
- */
- private static boolean isSupportedByBC(String algorithm) {
- String[] removedBcPrefices = new String[] {"AES/ECB", "AES/CBC", "AES/GCM"};
- for (String prefix : removedBcPrefices) {
- if (algorithm.startsWith(prefix)) {
- return false;
- }
- }
return true;
}
@@ -1106,9 +1083,7 @@ public final class CipherTest {
for (String padding : paddings) {
final String algorithmName = algorithm + "/" + mode + "/" + padding;
try {
- if (isSupported(algorithmName, provider.getName())) {
- test_Cipher_Algorithm(provider, algorithmName);
- }
+ test_Cipher_Algorithm(provider, algorithmName);
} catch (Throwable e) {
out.append("Error encountered checking " + algorithmName
+ " with provider " + provider.getName() + "\n");
@@ -3494,9 +3469,6 @@ public final class CipherTest {
if (provider.equals("SunJCE") && transformation.endsWith("/PKCS7PADDING")) {
return false;
}
- if (provider.equals("BC")) {
- return isSupportedByBC(transformation);
- }
return true;
}
}
@@ -4125,9 +4097,6 @@ public final class CipherTest {
final ByteArrayOutputStream errBuffer = new ByteArrayOutputStream();
PrintStream out = new PrintStream(errBuffer);
for (CipherTestParam p : CIPHER_TEST_PARAMS) {
- if (!p.compatibleWith(provider)) {
- continue;
- }
try {
checkCipher_ShortBlock_Failure(p, provider);
} catch (Exception e) {
@@ -4327,6 +4296,32 @@ public final class CipherTest {
}
}
+ // Test that when reading GCM parameters encoded using ASN1, a value for the tag size
+ // not present indicates a value of 12.
+ // https://b/29876633
+ @Test
+ public void test_DefaultGCMTagSizeAlgorithmParameterSpec() throws Exception {
+ Assume.assumeNotNull(Security.getProvider("BC"));
+ final String AES = "AES";
+ final String AES_GCM = "AES/GCM/NoPadding";
+ byte[] input = new byte[16];
+ byte[] key = new byte[16];
+ Cipher cipher = Cipher.getInstance(AES_GCM, "BC");
+ AlgorithmParameters param = AlgorithmParameters.getInstance("GCM");
+ param.init(new byte[] {
+ (byte) 48, // DER encoding : tag_Sequence
+ (byte) 14, // DER encoding : total length
+ (byte) 4, // DER encoding : tag_OctetString
+ (byte) 12, // DER encoding : counter length
+ (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0,
+ (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0 });
+ cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(key, AES), param);
+ byte[] ciphertext = cipher.update(input);
+ assertEquals(16, ciphertext.length);
+ byte[] tag = cipher.doFinal();
+ assertEquals(12, tag.length);
+ }
+
@Test
public void testAES_ECB_PKCS5Padding_ShortBuffer_Failure() throws Exception {
for (String provider : AES_PROVIDERS) {
@@ -4389,11 +4384,7 @@ public final class CipherTest {
}
private void testAES_ECB_NoPadding_IncrementalUpdate_Success(String provider) throws Exception {
- String algorithm = "AES/ECB/NoPadding";
- if (!isSupported(algorithm, provider)) {
- return;
- }
- Cipher c = Cipher.getInstance(algorithm, provider);
+ Cipher c = Cipher.getInstance("AES/ECB/NoPadding", provider);
assertEquals(provider, c.getProvider().getName());
c.init(Cipher.ENCRYPT_MODE, AES_128_KEY);
@@ -4427,11 +4418,7 @@ public final class CipherTest {
}
private void testAES_ECB_NoPadding_IvParameters_Failure(String provider) throws Exception {
- String algorithm = "AES/ECB/NoPadding";
- if (!isSupported(algorithm, provider)) {
- return;
- }
- Cipher c = Cipher.getInstance(algorithm, provider);
+ Cipher c = Cipher.getInstance("AES/ECB/NoPadding", provider);
AlgorithmParameterSpec spec = new IvParameterSpec(AES_IV_ZEROES);
try {
diff --git a/repackaged/testing/src/main/java/com/android/org/conscrypt/MethodFilter.java b/repackaged/testing/src/main/java/com/android/org/conscrypt/MethodFilter.java
deleted file mode 100644
index 680abd72..00000000
--- a/repackaged/testing/src/main/java/com/android/org/conscrypt/MethodFilter.java
+++ /dev/null
@@ -1,201 +0,0 @@
-/* GENERATED SOURCE. DO NOT MODIFY. */
-package com.android.org.conscrypt;
-
-import static org.junit.Assert.assertTrue;
-
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.function.Predicate;
-
-
-/**
- * Test support class for filtering collections of {@link Method}. Each filter is a list of
- * predicates which must all be true for a Method in order for it to be included it the output.
- * @hide This class is not part of the Android public SDK API
- */
-public class MethodFilter {
- private final String name;
- private final CompoundMethodPredicate predicates = new CompoundMethodPredicate();
- private int expectedSize = 0;
-
- public MethodFilter(String name) {
- this.name = name;
- }
-
- public List<Method> filter(Iterable<Method> input) {
- List<Method> result = new ArrayList<>();
- for (Method method : input) {
- if (predicates.test(method)) {
- result.add(method);
- }
- }
- if (expectedSize != 0) {
- assertTrue(String.format("Filter %s only returned %d methods, expected at least %d",
- name, result.size(), expectedSize), result.size() >= expectedSize);
- }
- return result;
- }
-
- /** Returns a new {@link Builder} */
- public static Builder newBuilder(String name) {
- return new Builder(name);
- }
-
- /** Returns a filter which selects only methods named in {@code methodNames} */
- public static MethodFilter nameFilter(String name, String... methodNames) {
- return newBuilder(name)
- .named(methodNames)
- .expectSize(methodNames.length)
- .build();
- }
-
- private void addPredicate(Predicate<Method> predicate) {
- predicates.add(predicate);
- }
-
- /**
- * @hide This class is not part of the Android public SDK API
- */
- public static class Builder {
- private final MethodFilter filter;
-
- private Builder(String name) {
- filter = new MethodFilter(name);
- }
-
- /** Method's simple name must start with {@code prefix}. */
- public Builder hasPrefix(String prefix) {
- filter.addPredicate(new MethodNamePrefixPredicate(prefix));
- return this;
- }
-
- /** Argument at {@code position} must be one of the supplied {@code classes}. */
- public Builder hasArg(int position, Class<?>... classes) {
- filter.addPredicate(new MethodArgPredicate(position, classes));
- return this;
- }
-
- /** Method must take exactly {@code length} args. */
- public Builder hasArgLength(int length) {
- filter.addPredicate(new MethodArgLengthPredicate(length));
- return this;
- }
-
- /* Method must take one or more arguments, i.e. not void. */
- public Builder takesArguments() {
- filter.addPredicate(new MethodArgLengthPredicate(0).negate());
- return this;
- }
-
- /** Method's simple name is in the list of {@code names} provided. */
- public Builder named(String... names) {
- filter.addPredicate(new MethodNamePredicate(names));
- return this;
- }
-
- /** Method's simple name is NOT in the list of {@code names} provided. */
- public Builder except(String... names) {
- filter.addPredicate(new MethodNamePredicate(names).negate());
- return this;
- }
-
- /** Expect at least {@code size} matching methods when filtering, otherwise filter()
- * will throw {@code AssertionError} */
- public Builder expectSize(int size) {
- filter.expectedSize = size;
- return this;
- }
-
- public MethodFilter build() {
- return filter;
- }
- }
-
- // Implements Builder.hasPrefix()
- private static class MethodNamePrefixPredicate implements Predicate<Method> {
- private final String prefix;
-
- public MethodNamePrefixPredicate(String prefix) {
- this.prefix = prefix;
- }
-
- @Override
- public boolean test(Method method) {
- return method.getName().startsWith(prefix);
- }
- }
-
- // Implements Builder.named()
- private static class MethodNamePredicate implements Predicate<Method> {
- private final List<String> names;
-
- public MethodNamePredicate(String... names) {
- this.names = Arrays.asList(names);
- }
-
- @Override
- public boolean test(Method method) {
- return names.contains(method.getName());
- }
- }
-
- // Implements Builder.hasArg()
- private static class MethodArgPredicate implements Predicate<Method> {
- private final int position;
- private final List<Class<?>> allowedClasses;
-
- public MethodArgPredicate(int position, Class<?>... classes) {
- this.position = position;
- allowedClasses = Arrays.asList(classes);
- }
-
- @Override
- public boolean test(Method method) {
- Class<?>[] argTypes = method.getParameterTypes();
- if (argTypes.length > position) {
- for (Class<?> c : allowedClasses) {
- if (argTypes[position] == c) {
- return true;
- }
- }
- }
- return false;
- }
- }
-
- // Implements Builder.hasArgLength()
- private static class MethodArgLengthPredicate implements Predicate<Method> {
- private final int length;
-
- public MethodArgLengthPredicate(int length) {
- this.length = length;
- }
-
- @Override
- public boolean test(Method method) {
- return method.getParameterCount() == length;
- }
- }
-
- // A Predicate which contains a list of sub-Predicates, all of which must be true
- // for this one to be true.
- private static class CompoundMethodPredicate implements Predicate<Method> {
- private final List<Predicate<Method>> predicates = new ArrayList<>();
-
- @Override
- public boolean test(Method method) {
- for (Predicate<Method> p : predicates) {
- if (!p.test(method)) {
- return false;
- }
- }
- return true;
- }
-
- public void add(Predicate<Method> predicate) {
- predicates.add(predicate);
- }
- }
-} \ No newline at end of file
diff --git a/testing/src/main/java/org/conscrypt/MethodFilter.java b/testing/src/main/java/org/conscrypt/MethodFilter.java
deleted file mode 100644
index 0939d4b3..00000000
--- a/testing/src/main/java/org/conscrypt/MethodFilter.java
+++ /dev/null
@@ -1,196 +0,0 @@
-package org.conscrypt;
-
-import static org.junit.Assert.assertTrue;
-
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.function.Predicate;
-
-
-/**
- * Test support class for filtering collections of {@link Method}. Each filter is a list of
- * predicates which must all be true for a Method in order for it to be included it the output.
- */
-public class MethodFilter {
- private final String name;
- private final CompoundMethodPredicate predicates = new CompoundMethodPredicate();
- private int expectedSize = 0;
-
- public MethodFilter(String name) {
- this.name = name;
- }
-
- public List<Method> filter(Iterable<Method> input) {
- List<Method> result = new ArrayList<>();
- for (Method method : input) {
- if (predicates.test(method)) {
- result.add(method);
- }
- }
- if (expectedSize != 0) {
- assertTrue(String.format("Filter %s only returned %d methods, expected at least %d",
- name, result.size(), expectedSize), result.size() >= expectedSize);
- }
- return result;
- }
-
- /** Returns a new {@link Builder} */
- public static Builder newBuilder(String name) {
- return new Builder(name);
- }
-
- /** Returns a filter which selects only methods named in {@code methodNames} */
- public static MethodFilter nameFilter(String name, String... methodNames) {
- return newBuilder(name)
- .named(methodNames)
- .expectSize(methodNames.length)
- .build();
- }
-
- private void addPredicate(Predicate<Method> predicate) {
- predicates.add(predicate);
- }
-
- public static class Builder {
- private final MethodFilter filter;
-
- private Builder(String name) {
- filter = new MethodFilter(name);
- }
-
- /** Method's simple name must start with {@code prefix}. */
- public Builder hasPrefix(String prefix) {
- filter.addPredicate(new MethodNamePrefixPredicate(prefix));
- return this;
- }
-
- /** Argument at {@code position} must be one of the supplied {@code classes}. */
- public Builder hasArg(int position, Class<?>... classes) {
- filter.addPredicate(new MethodArgPredicate(position, classes));
- return this;
- }
-
- /** Method must take exactly {@code length} args. */
- public Builder hasArgLength(int length) {
- filter.addPredicate(new MethodArgLengthPredicate(length));
- return this;
- }
-
- /* Method must take one or more arguments, i.e. not void. */
- public Builder takesArguments() {
- filter.addPredicate(new MethodArgLengthPredicate(0).negate());
- return this;
- }
-
- /** Method's simple name is in the list of {@code names} provided. */
- public Builder named(String... names) {
- filter.addPredicate(new MethodNamePredicate(names));
- return this;
- }
-
- /** Method's simple name is NOT in the list of {@code names} provided. */
- public Builder except(String... names) {
- filter.addPredicate(new MethodNamePredicate(names).negate());
- return this;
- }
-
- /** Expect at least {@code size} matching methods when filtering, otherwise filter()
- * will throw {@code AssertionError} */
- public Builder expectSize(int size) {
- filter.expectedSize = size;
- return this;
- }
-
- public MethodFilter build() {
- return filter;
- }
- }
-
- // Implements Builder.hasPrefix()
- private static class MethodNamePrefixPredicate implements Predicate<Method> {
- private final String prefix;
-
- public MethodNamePrefixPredicate(String prefix) {
- this.prefix = prefix;
- }
-
- @Override
- public boolean test(Method method) {
- return method.getName().startsWith(prefix);
- }
- }
-
- // Implements Builder.named()
- private static class MethodNamePredicate implements Predicate<Method> {
- private final List<String> names;
-
- public MethodNamePredicate(String... names) {
- this.names = Arrays.asList(names);
- }
-
- @Override
- public boolean test(Method method) {
- return names.contains(method.getName());
- }
- }
-
- // Implements Builder.hasArg()
- private static class MethodArgPredicate implements Predicate<Method> {
- private final int position;
- private final List<Class<?>> allowedClasses;
-
- public MethodArgPredicate(int position, Class<?>... classes) {
- this.position = position;
- allowedClasses = Arrays.asList(classes);
- }
-
- @Override
- public boolean test(Method method) {
- Class<?>[] argTypes = method.getParameterTypes();
- if (argTypes.length > position) {
- for (Class<?> c : allowedClasses) {
- if (argTypes[position] == c) {
- return true;
- }
- }
- }
- return false;
- }
- }
-
- // Implements Builder.hasArgLength()
- private static class MethodArgLengthPredicate implements Predicate<Method> {
- private final int length;
-
- public MethodArgLengthPredicate(int length) {
- this.length = length;
- }
-
- @Override
- public boolean test(Method method) {
- return method.getParameterCount() == length;
- }
- }
-
- // A Predicate which contains a list of sub-Predicates, all of which must be true
- // for this one to be true.
- private static class CompoundMethodPredicate implements Predicate<Method> {
- private final List<Predicate<Method>> predicates = new ArrayList<>();
-
- @Override
- public boolean test(Method method) {
- for (Predicate<Method> p : predicates) {
- if (!p.test(method)) {
- return false;
- }
- }
- return true;
- }
-
- public void add(Predicate<Method> predicate) {
- predicates.add(predicate);
- }
- }
-} \ No newline at end of file