Update trusted certificates when the trust store is changed

This CL flushes the trusted cert cache of all active Network Security
Configs and their TrustManagers. Previously CA addition mostly worked
however removed CAs would remain cached in the X509TrustManager causing
the removed CA to still be trusted.

Change-Id: I0f5fd39932f8f8ed3ec5dfd088a82e982b366c43
This commit is contained in:
Chad Brubaker
2016-04-27 16:35:11 -07:00
parent 4de59ef323
commit c72875b01e
7 changed files with 60 additions and 11 deletions

View File

@@ -34406,7 +34406,6 @@ package android.security {
public class NetworkSecurityPolicy {
method public static android.security.NetworkSecurityPolicy getInstance();
method public void handleTrustStorageUpdate();
method public boolean isCleartextTrafficPermitted();
method public boolean isCleartextTrafficPermitted(java.lang.String);
}

View File

@@ -81,6 +81,7 @@ import android.os.Trace;
import android.os.TransactionTooLargeException;
import android.os.UserHandle;
import android.provider.Settings;
import android.security.NetworkSecurityPolicy;
import android.security.net.config.NetworkSecurityConfigProvider;
import android.util.AndroidRuntimeException;
import android.util.ArrayMap;
@@ -1324,6 +1325,11 @@ public final class ActivityThread {
args.arg2 = voiceInteractor;
sendMessage(H.LOCAL_VOICE_INTERACTION_STARTED, args);
}
@Override
public void handleTrustStorageUpdate() {
NetworkSecurityPolicy.getInstance().handleTrustStorageUpdate();
}
}
private int getLifecycleSeq() {

View File

@@ -749,6 +749,12 @@ public abstract class ApplicationThreadNative extends Binder
schedulePictureInPictureModeChanged(b, inPip);
return true;
}
case HANDLE_TRUST_STORAGE_UPDATE_TRANSACTION:
{
data.enforceInterface(IApplicationThread.descriptor);
handleTrustStorageUpdate();
return true;
}
}
@@ -1522,4 +1528,12 @@ class ApplicationThreadProxy implements IApplicationThread {
IBinder.FLAG_ONEWAY);
data.recycle();
}
@Override
public void handleTrustStorageUpdate() throws RemoteException {
Parcel data = Parcel.obtain();
data.writeInterfaceToken(IApplicationThread.descriptor);
mRemote.transact(HANDLE_TRUST_STORAGE_UPDATE_TRANSACTION, data, null, IBinder.FLAG_ONEWAY);
data.recycle();
}
}

View File

@@ -161,6 +161,7 @@ public interface IApplicationThread extends IInterface {
void scheduleMultiWindowModeChanged(IBinder token, boolean isInMultiWindowMode) throws RemoteException;
void schedulePictureInPictureModeChanged(IBinder token, boolean isInPictureInPictureMode) throws RemoteException;
void scheduleLocalVoiceInteractionStarted(IBinder token, IVoiceInteractor voiceInteractor) throws RemoteException;
void handleTrustStorageUpdate() throws RemoteException;
String descriptor = "android.app.IApplicationThread";
@@ -224,4 +225,5 @@ public interface IApplicationThread extends IInterface {
int SCHEDULE_MULTI_WINDOW_CHANGED_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+58;
int SCHEDULE_PICTURE_IN_PICTURE_CHANGED_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+59;
int SCHEDULE_LOCAL_VOICE_INTERACTION_STARTED_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+60;
int HANDLE_TRUST_STORAGE_UPDATE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+61;
}

View File

@@ -97,9 +97,11 @@ public class NetworkSecurityPolicy {
* Handle an update to the system or user certificate stores.
* @hide
*/
@TestApi
public void handleTrustStorageUpdate() {
ApplicationConfig.getDefaultInstance().handleTrustStorageUpdate();
ApplicationConfig config = ApplicationConfig.getDefaultInstance();
if (config != null) {
config.handleTrustStorageUpdate();
}
}
/**

View File

@@ -148,14 +148,20 @@ public final class ApplicationConfig {
}
public void handleTrustStorageUpdate() {
ensureInitialized();
mDefaultConfig.handleTrustStorageUpdate();
if (mConfigs != null) {
Set<NetworkSecurityConfig> updatedConfigs =
new HashSet<NetworkSecurityConfig>(mConfigs.size());
for (Pair<Domain, NetworkSecurityConfig> entry : mConfigs) {
if (updatedConfigs.add(entry.second)) {
entry.second.handleTrustStorageUpdate();
synchronized(mLock) {
// If the config is uninitialized then there is no work to be done to handle an update,
// avoid needlessly parsing configs.
if (!mInitialized) {
return;
}
mDefaultConfig.handleTrustStorageUpdate();
if (mConfigs != null) {
Set<NetworkSecurityConfig> updatedConfigs =
new HashSet<NetworkSecurityConfig>(mConfigs.size());
for (Pair<Domain, NetworkSecurityConfig> entry : mConfigs) {
if (updatedConfigs.add(entry.second)) {
entry.second.handleTrustStorageUpdate();
}
}
}
}

View File

@@ -286,6 +286,7 @@ import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
import static android.provider.Settings.Global.LENIENT_BACKGROUND_CHECK;
import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
import static android.provider.Settings.System.FONT_SCALE;
import static android.security.KeyChain.ACTION_TRUST_STORE_CHANGED;
import static com.android.internal.util.XmlUtils.readBooleanAttribute;
import static com.android.internal.util.XmlUtils.readIntAttribute;
import static com.android.internal.util.XmlUtils.readLongAttribute;
@@ -1522,6 +1523,7 @@ public final class ActivityManagerService extends ActivityManagerNative
static final int NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG = 68;
static final int VR_MODE_APPLY_IF_NEEDED_MSG = 69;
static final int SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG = 70;
static final int HANDLE_TRUST_STORAGE_UPDATE_MSG = 71;
static final int FIRST_ACTIVITY_STACK_MSG = 100;
static final int FIRST_BROADCAST_QUEUE_MSG = 200;
@@ -2322,6 +2324,21 @@ public final class ActivityManagerService extends ActivityManagerNative
r.info.getComponentName(), false);
}
} break;
case HANDLE_TRUST_STORAGE_UPDATE_MSG: {
synchronized (ActivityManagerService.this) {
for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
ProcessRecord r = mLruProcesses.get(i);
if (r.thread != null) {
try {
r.thread.handleTrustStorageUpdate();
} catch (RemoteException ex) {
Slog.w(TAG, "Failed to handle trust storage update for: " +
r.info.processName);
}
}
}
}
} break;
}
}
};
@@ -17959,6 +17976,9 @@ public final class ActivityManagerService extends ActivityManagerNative
}
// Lie; we don't want to crash the app.
return ActivityManager.BROADCAST_SUCCESS;
case android.security.KeyChain.ACTION_TRUST_STORE_CHANGED:
mHandler.sendEmptyMessage(HANDLE_TRUST_STORAGE_UPDATE_MSG);
break;
}
}