Merge "Use X509ExtendedTrustManagers" into nyc-dev
diff --git a/core/java/android/security/net/config/NetworkSecurityTrustManager.java b/core/java/android/security/net/config/NetworkSecurityTrustManager.java
index f2c718cd..3c292ca 100644
--- a/core/java/android/security/net/config/NetworkSecurityTrustManager.java
+++ b/core/java/android/security/net/config/NetworkSecurityTrustManager.java
@@ -20,6 +20,7 @@
import android.util.ArrayMap;
import java.io.IOException;
+import java.net.Socket;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.security.GeneralSecurityException;
@@ -29,14 +30,15 @@
import java.util.Map;
import java.util.Set;
-import javax.net.ssl.X509TrustManager;
+import javax.net.ssl.SSLEngine;
+import javax.net.ssl.X509ExtendedTrustManager;
/**
- * {@link X509TrustManager} that implements the trust anchor and pinning for a
+ * {@link X509ExtendedTrustManager} that implements the trust anchor and pinning for a
* given {@link NetworkSecurityConfig}.
* @hide
*/
-public class NetworkSecurityTrustManager implements X509TrustManager {
+public class NetworkSecurityTrustManager extends X509ExtendedTrustManager {
// TODO: Replace this with a general X509TrustManager and use duck-typing.
private final TrustManagerImpl mDelegate;
private final NetworkSecurityConfig mNetworkSecurityConfig;
@@ -68,9 +70,37 @@
}
@Override
+ public void checkClientTrusted(X509Certificate[] certs, String authType, Socket socket)
+ throws CertificateException {
+ mDelegate.checkClientTrusted(certs, authType, socket);
+ }
+
+ @Override
+ public void checkClientTrusted(X509Certificate[] certs, String authType, SSLEngine engine)
+ throws CertificateException {
+ mDelegate.checkClientTrusted(certs, authType, engine);
+ }
+
+ @Override
public void checkServerTrusted(X509Certificate[] certs, String authType)
throws CertificateException {
- checkServerTrusted(certs, authType, null);
+ checkServerTrusted(certs, authType, (String) null);
+ }
+
+ @Override
+ public void checkServerTrusted(X509Certificate[] certs, String authType, Socket socket)
+ throws CertificateException {
+ List<X509Certificate> trustedChain =
+ mDelegate.getTrustedChainForServer(certs, authType, socket);
+ checkPins(trustedChain);
+ }
+
+ @Override
+ public void checkServerTrusted(X509Certificate[] certs, String authType, SSLEngine engine)
+ throws CertificateException {
+ List<X509Certificate> trustedChain =
+ mDelegate.getTrustedChainForServer(certs, authType, engine);
+ checkPins(trustedChain);
}
/**
diff --git a/core/java/android/security/net/config/RootTrustManager.java b/core/java/android/security/net/config/RootTrustManager.java
index b4e58e6..19f6887 100644
--- a/core/java/android/security/net/config/RootTrustManager.java
+++ b/core/java/android/security/net/config/RootTrustManager.java
@@ -16,24 +16,28 @@
package android.security.net.config;
+import java.net.Socket;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.List;
-import javax.net.ssl.X509TrustManager;
+import javax.net.ssl.SSLSocket;
+import javax.net.ssl.SSLEngine;
+import javax.net.ssl.SSLSession;
+import javax.net.ssl.X509ExtendedTrustManager;
/**
- * {@link X509TrustManager} based on an {@link ApplicationConfig}.
+ * {@link X509ExtendedTrustManager} based on an {@link ApplicationConfig}.
*
- * <p>This {@code X509TrustManager} delegates to the specific trust manager for the hostname
- * being used for the connection (See {@link ApplicationConfig#getConfigForHostname(String)} and
+ * <p>This trust manager delegates to the specific trust manager for the hostname being used for
+ * the connection (See {@link ApplicationConfig#getConfigForHostname(String)} and
* {@link NetworkSecurityTrustManager}).</p>
*
* Note that if the {@code ApplicationConfig} has per-domain configurations the hostname aware
* {@link #checkServerTrusted(X509Certificate[], String String)} must be used instead of the normal
* non-aware call.
* @hide */
-public class RootTrustManager implements X509TrustManager {
+public class RootTrustManager extends X509ExtendedTrustManager {
private final ApplicationConfig mConfig;
public RootTrustManager(ApplicationConfig config) {
@@ -53,6 +57,54 @@
}
@Override
+ public void checkClientTrusted(X509Certificate[] certs, String authType, Socket socket)
+ throws CertificateException {
+ // Use the default configuration for all client authentication. Domain specific configs are
+ // only for use in checking server trust not client trust.
+ NetworkSecurityConfig config = mConfig.getConfigForHostname("");
+ config.getTrustManager().checkClientTrusted(certs, authType, socket);
+ }
+
+ @Override
+ public void checkClientTrusted(X509Certificate[] certs, String authType, SSLEngine engine)
+ throws CertificateException {
+ // Use the default configuration for all client authentication. Domain specific configs are
+ // only for use in checking server trust not client trust.
+ NetworkSecurityConfig config = mConfig.getConfigForHostname("");
+ config.getTrustManager().checkClientTrusted(certs, authType, engine);
+ }
+
+ @Override
+ public void checkServerTrusted(X509Certificate[] certs, String authType, Socket socket)
+ throws CertificateException {
+ if (socket instanceof SSLSocket) {
+ SSLSocket sslSocket = (SSLSocket) socket;
+ SSLSession session = sslSocket.getHandshakeSession();
+ if (session == null) {
+ throw new CertificateException("Not in handshake; no session available");
+ }
+ String host = session.getPeerHost();
+ NetworkSecurityConfig config = mConfig.getConfigForHostname(host);
+ config.getTrustManager().checkServerTrusted(certs, authType, socket);
+ } else {
+ // Not an SSLSocket, use the hostname unaware checkServerTrusted.
+ checkServerTrusted(certs, authType);
+ }
+ }
+
+ @Override
+ public void checkServerTrusted(X509Certificate[] certs, String authType, SSLEngine engine)
+ throws CertificateException {
+ SSLSession session = engine.getHandshakeSession();
+ if (session == null) {
+ throw new CertificateException("Not in handshake; no session available");
+ }
+ String host = session.getPeerHost();
+ NetworkSecurityConfig config = mConfig.getConfigForHostname(host);
+ config.getTrustManager().checkServerTrusted(certs, authType, engine);
+ }
+
+ @Override
public void checkServerTrusted(X509Certificate[] certs, String authType)
throws CertificateException {
if (mConfig.hasPerDomainConfigs()) {