Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 536e89f0 authored by Thiébaud Weksteen's avatar Thiébaud Weksteen Committed by Android (Google) Code Review
Browse files

Merge "Add checkServerTrusted variant to X509TrustManagerExtensions" into main

parents ab58d648 4f65df85
Loading
Loading
Loading
Loading
+9 −0
Original line number Original line Diff line number Diff line
@@ -106,6 +106,7 @@ aconfig_declarations_group {
        "com.android.server.flags.services-aconfig-java",
        "com.android.server.flags.services-aconfig-java",
        "com.android.text.flags-aconfig-java",
        "com.android.text.flags-aconfig-java",
        "com.android.window.flags.window-aconfig-java",
        "com.android.window.flags.window-aconfig-java",
        "conscrypt_exported_aconfig_flags_lib",
        "device_policy_aconfig_flags_lib",
        "device_policy_aconfig_flags_lib",
        "display_flags_lib",
        "display_flags_lib",
        "dropbox_flags_lib",
        "dropbox_flags_lib",
@@ -195,6 +196,14 @@ java_aconfig_library {
    defaults: ["framework-minus-apex-aconfig-java-defaults"],
    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
// Telecom
java_aconfig_library {
java_aconfig_library {
    name: "telecom_flags_core_java_lib",
    name: "telecom_flags_core_java_lib",
+1 −0
Original line number Original line Diff line number Diff line
@@ -29889,6 +29889,7 @@ package android.net.http {
  public class X509TrustManagerExtensions {
  public class X509TrustManagerExtensions {
    ctor public X509TrustManagerExtensions(javax.net.ssl.X509TrustManager) throws java.lang.IllegalArgumentException;
    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 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 isSameTrustConfiguration(String, String);
    method public boolean isUserAddedCertificate(java.security.cert.X509Certificate);
    method public boolean isUserAddedCertificate(java.security.cert.X509Certificate);
  }
  }
+8 −0
Original line number Original line Diff line number Diff line
@@ -29,3 +29,11 @@ flag {
  }
  }
  is_exported: true
  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"
}
+84 −4
Original line number Original line Diff line number Diff line
@@ -16,6 +16,13 @@


package android.net.http;
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 android.security.net.config.UserCertificateSource;


import com.android.org.conscrypt.TrustManagerImpl;
import com.android.org.conscrypt.TrustManagerImpl;
@@ -24,6 +31,7 @@ import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Method;
import java.security.cert.CertificateException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.security.cert.X509Certificate;
import java.util.Collections;
import java.util.List;
import java.util.List;


import javax.net.ssl.X509TrustManager;
import javax.net.ssl.X509TrustManager;
@@ -31,9 +39,9 @@ import javax.net.ssl.X509TrustManager;
/**
/**
 * X509TrustManager wrapper exposing Android-added features.
 * X509TrustManager wrapper exposing Android-added features.
 * <p>
 * <p>
 * The checkServerTrusted method allows callers to perform additional
 * The checkServerTrusted methods allow callers to provide some additional
 * verification of certificate chains after they have been successfully verified
 * context for the verification. This is particularly useful when an SSLEngine
 * by the platform.
 * or SSLSocket is not available.
 * </p>
 * </p>
 */
 */
public class X509TrustManagerExtensions {
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.
    // Methods to use when mDelegate is not a TrustManagerImpl and duck typing is being used.
    private final X509TrustManager mTrustManager;
    private final X509TrustManager mTrustManager;
    private final Method mCheckServerTrusted;
    private final Method mCheckServerTrusted;
    private final Method mCheckServerTrustedOcspAndTlsData;
    private final Method mIsSameTrustConfiguration;
    private final Method mIsSameTrustConfiguration;


    /**
    /**
@@ -55,6 +64,7 @@ public class X509TrustManagerExtensions {
            mDelegate = (TrustManagerImpl) tm;
            mDelegate = (TrustManagerImpl) tm;
            mTrustManager = null;
            mTrustManager = null;
            mCheckServerTrusted = null;
            mCheckServerTrusted = null;
            mCheckServerTrustedOcspAndTlsData = null;
            mIsSameTrustConfiguration = null;
            mIsSameTrustConfiguration = null;
            return;
            return;
        }
        }
@@ -69,8 +79,19 @@ public class X509TrustManagerExtensions {
                    String.class);
                    String.class);
        } catch (NoSuchMethodException e) {
        } catch (NoSuchMethodException e) {
            throw new IllegalArgumentException("Required method"
            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.
        // Get the option isSameTrustConfiguration method.
        Method isSameTrustConfiguration = null;
        Method isSameTrustConfiguration = null;
        try {
        try {
@@ -114,6 +135,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.
     * Checks whether a CA certificate is added by an user.
     *
     *