summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author ThiƩbaud Weksteen <tweek@google.com> 2024-11-29 04:30:33 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2024-11-29 04:30:33 +0000
commit536e89f0e61c26b94d4ad296d9511d8d181cf9e7 (patch)
treebcfea08227e42b8e7494ebb6203880072a037cc8
parentab58d64895a7de708784bd451624646229dca46d (diff)
parent4f65df85764670ba5bc997f4d3c13c70a8642be3 (diff)
Merge "Add checkServerTrusted variant to X509TrustManagerExtensions" into main
-rw-r--r--AconfigFlags.bp9
-rw-r--r--core/api/current.txt1
-rw-r--r--core/java/android/net/flags.aconfig8
-rw-r--r--core/java/android/net/http/X509TrustManagerExtensions.java88
4 files changed, 102 insertions, 4 deletions
diff --git a/AconfigFlags.bp b/AconfigFlags.bp
index 76d6e56d0549..3689ff5a7be0 100644
--- a/AconfigFlags.bp
+++ b/AconfigFlags.bp
@@ -106,6 +106,7 @@ aconfig_declarations_group {
"com.android.server.flags.services-aconfig-java",
"com.android.text.flags-aconfig-java",
"com.android.window.flags.window-aconfig-java",
+ "conscrypt_exported_aconfig_flags_lib",
"device_policy_aconfig_flags_lib",
"display_flags_lib",
"dropbox_flags_lib",
@@ -195,6 +196,14 @@ java_aconfig_library {
defaults: ["framework-minus-apex-aconfig-java-defaults"],
}
+// Conscrypt
+java_aconfig_library {
+ name: "conscrypt_exported_aconfig_flags_lib",
+ aconfig_declarations: "conscrypt-aconfig-flags",
+ mode: "exported",
+ defaults: ["framework-minus-apex-aconfig-java-defaults"],
+}
+
// Telecom
java_aconfig_library {
name: "telecom_flags_core_java_lib",
diff --git a/core/api/current.txt b/core/api/current.txt
index d313a795f474..fd8e6102714a 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -29889,6 +29889,7 @@ package android.net.http {
public class X509TrustManagerExtensions {
ctor public X509TrustManagerExtensions(javax.net.ssl.X509TrustManager) throws java.lang.IllegalArgumentException;
method public java.util.List<java.security.cert.X509Certificate> checkServerTrusted(java.security.cert.X509Certificate[], String, String) throws java.security.cert.CertificateException;
+ method @FlaggedApi("android.net.platform.flags.x509_extensions_certificate_transparency") @NonNull public java.util.List<java.security.cert.X509Certificate> checkServerTrusted(@NonNull java.security.cert.X509Certificate[], @Nullable byte[], @Nullable byte[], @NonNull String, @NonNull String) throws java.security.cert.CertificateException;
method public boolean isSameTrustConfiguration(String, String);
method public boolean isUserAddedCertificate(java.security.cert.X509Certificate);
}
diff --git a/core/java/android/net/flags.aconfig b/core/java/android/net/flags.aconfig
index 6799db3f7471..95b5f697969e 100644
--- a/core/java/android/net/flags.aconfig
+++ b/core/java/android/net/flags.aconfig
@@ -29,3 +29,11 @@ flag {
}
is_exported: true
}
+
+flag {
+ name: "x509_extensions_certificate_transparency"
+ is_exported: true
+ namespace: "network_security"
+ description: "Flag to use checkServerTrusted to verify SCTs in OCSP and TLS Data"
+ bug: "319829948"
+}
diff --git a/core/java/android/net/http/X509TrustManagerExtensions.java b/core/java/android/net/http/X509TrustManagerExtensions.java
index 280dad0284b6..b44f75a585d5 100644
--- a/core/java/android/net/http/X509TrustManagerExtensions.java
+++ b/core/java/android/net/http/X509TrustManagerExtensions.java
@@ -16,6 +16,13 @@
package android.net.http;
+import static com.android.org.conscrypt.flags.Flags.certificateTransparencyCheckservertrustedApi;
+
+import android.annotation.FlaggedApi;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SuppressLint;
+import android.net.platform.flags.Flags;
import android.security.net.config.UserCertificateSource;
import com.android.org.conscrypt.TrustManagerImpl;
@@ -24,6 +31,7 @@ import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
+import java.util.Collections;
import java.util.List;
import javax.net.ssl.X509TrustManager;
@@ -31,9 +39,9 @@ import javax.net.ssl.X509TrustManager;
/**
* X509TrustManager wrapper exposing Android-added features.
* <p>
- * The checkServerTrusted method allows callers to perform additional
- * verification of certificate chains after they have been successfully verified
- * by the platform.
+ * The checkServerTrusted methods allow callers to provide some additional
+ * context for the verification. This is particularly useful when an SSLEngine
+ * or SSLSocket is not available.
* </p>
*/
public class X509TrustManagerExtensions {
@@ -42,6 +50,7 @@ public class X509TrustManagerExtensions {
// Methods to use when mDelegate is not a TrustManagerImpl and duck typing is being used.
private final X509TrustManager mTrustManager;
private final Method mCheckServerTrusted;
+ private final Method mCheckServerTrustedOcspAndTlsData;
private final Method mIsSameTrustConfiguration;
/**
@@ -55,6 +64,7 @@ public class X509TrustManagerExtensions {
mDelegate = (TrustManagerImpl) tm;
mTrustManager = null;
mCheckServerTrusted = null;
+ mCheckServerTrustedOcspAndTlsData = null;
mIsSameTrustConfiguration = null;
return;
}
@@ -69,8 +79,19 @@ public class X509TrustManagerExtensions {
String.class);
} catch (NoSuchMethodException e) {
throw new IllegalArgumentException("Required method"
- + " checkServerTrusted(X509Certificate[], String, String, String) missing");
+ + " checkServerTrusted(X509Certificate[], String, String) missing");
}
+ // Check that the OCSP and TlsData aware checkServerTrusted is present.
+ Method checkServerTrustedOcspAndTlsData = null;
+ try {
+ checkServerTrustedOcspAndTlsData = tm.getClass().getMethod("checkServerTrusted",
+ X509Certificate[].class,
+ Byte[].class,
+ Byte[].class,
+ String.class,
+ String.class);
+ } catch (ReflectiveOperationException ignored) { }
+ mCheckServerTrustedOcspAndTlsData = checkServerTrustedOcspAndTlsData;
// Get the option isSameTrustConfiguration method.
Method isSameTrustConfiguration = null;
try {
@@ -115,6 +136,65 @@ public class X509TrustManagerExtensions {
}
/**
+ * Verifies the given certificate chain.
+ *
+ * <p>See {@link X509TrustManager#checkServerTrusted(X509Certificate[], String)} for a
+ * description of the chain and authType parameters. The final parameter, host, should be the
+ * hostname of the server.</p>
+ *
+ * <p>ocspData and tlsSctData may be provided to verify any Signed Certificate Timestamp (SCT)
+ * attached to the connection. These are ASN.1 octet strings (SignedCertificateTimestampList)
+ * as described in RFC 6962, Section 3.3. Note that SCTs embedded in the certificate chain
+ * will automatically be processed.
+ * </p>
+ *
+ * @throws CertificateException if the chain does not verify correctly.
+ * @throws IllegalArgumentException if the TrustManager is not compatible.
+ * @return the properly ordered chain used for verification as a list of X509Certificates.
+ */
+ @FlaggedApi(Flags.FLAG_X509_EXTENSIONS_CERTIFICATE_TRANSPARENCY)
+ @NonNull
+ public List<X509Certificate> checkServerTrusted(
+ @SuppressLint("ArrayReturn") @NonNull X509Certificate[] chain,
+ @Nullable byte[] ocspData,
+ @Nullable byte[] tlsSctData,
+ @NonNull String authType,
+ @NonNull String host) throws CertificateException {
+ List<X509Certificate> result;
+ if (mDelegate != null) {
+ if (certificateTransparencyCheckservertrustedApi()) {
+ result = mDelegate.checkServerTrusted(chain, ocspData, tlsSctData, authType, host);
+ return result == null ? Collections.emptyList() : result;
+ } else {
+ // The conscrypt mainline module does not have the required method.
+ throw new IllegalArgumentException("Required method"
+ + " checkServerTrusted(X509Certificate[], byte[], byte[], String, String)"
+ + " not available in TrustManagerImpl");
+ }
+ }
+ if (mCheckServerTrustedOcspAndTlsData == null) {
+ throw new IllegalArgumentException("Required method"
+ + " checkServerTrusted(X509Certificate[], byte[], byte[], String, String)"
+ + " missing");
+ }
+ try {
+ result = (List<X509Certificate>) mCheckServerTrustedOcspAndTlsData.invoke(mTrustManager,
+ ocspData, tlsSctData, chain, authType, host);
+ return result == null ? Collections.emptyList() : result;
+ } catch (IllegalAccessException e) {
+ throw new CertificateException("Failed to call checkServerTrusted", e);
+ } catch (InvocationTargetException e) {
+ if (e.getCause() instanceof CertificateException) {
+ throw (CertificateException) e.getCause();
+ }
+ if (e.getCause() instanceof RuntimeException) {
+ throw (RuntimeException) e.getCause();
+ }
+ throw new CertificateException("checkServerTrusted failed", e.getCause());
+ }
+ }
+
+ /**
* Checks whether a CA certificate is added by an user.
*
* <p>Since {@link X509TrustManager#checkServerTrusted} may allow its parameter {@code chain} to