diff options
Diffstat (limited to 'packages/BackupEncryption/src')
3 files changed, 224 insertions, 0 deletions
diff --git a/packages/BackupEncryption/src/com/android/server/backup/encryption/BackupEncryptionService.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/BackupEncryptionService.java new file mode 100644 index 000000000000..84fb0e62dbca --- /dev/null +++ b/packages/BackupEncryption/src/com/android/server/backup/encryption/BackupEncryptionService.java @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2019 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.server.backup.encryption; + +import android.app.Service; +import android.content.Intent; +import android.os.IBinder; +import android.util.Log; + +import com.android.internal.backup.IBackupTransport; +import com.android.server.backup.encryption.transport.IntermediateEncryptingTransport; +import com.android.server.backup.encryption.transport.IntermediateEncryptingTransportManager; + +/** + * This service provides encryption of backup data. For an intent used to bind to this service, it + * provides an {@link IntermediateEncryptingTransport} which is an implementation of {@link + * IBackupTransport} that encrypts (or decrypts) the data when sending it (or receiving it) from the + * real {@link IBackupTransport}. + */ +public class BackupEncryptionService extends Service { + public static final String TAG = "BackupEncryption"; + private static IntermediateEncryptingTransportManager sTransportManager = null; + + @Override + public void onCreate() { + Log.i(TAG, "onCreate:" + this); + if (sTransportManager == null) { + Log.i(TAG, "Creating IntermediateEncryptingTransportManager"); + sTransportManager = new IntermediateEncryptingTransportManager(this); + } + } + + @Override + public void onDestroy() { + Log.i(TAG, "onDestroy:" + this); + } + + @Override + public IBinder onBind(Intent intent) { + // TODO (b141536117): Check connection with TransportClient.connect and return null on fail. + return sTransportManager.get(intent); + } + + @Override + public boolean onUnbind(Intent intent) { + sTransportManager.cleanup(intent); + return false; + } +} diff --git a/packages/BackupEncryption/src/com/android/server/backup/encryption/transport/IntermediateEncryptingTransport.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/transport/IntermediateEncryptingTransport.java new file mode 100644 index 000000000000..da47781d77d1 --- /dev/null +++ b/packages/BackupEncryption/src/com/android/server/backup/encryption/transport/IntermediateEncryptingTransport.java @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2019 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.server.backup.encryption.transport; + +import android.os.RemoteException; + +import com.android.internal.annotations.VisibleForTesting; +import com.android.internal.backup.IBackupTransport; +import com.android.server.backup.transport.DelegatingTransport; +import com.android.server.backup.transport.TransportClient; + +/** + * This is an implementation of {@link IBackupTransport} that encrypts (or decrypts) the data when + * sending it (or receiving it) from the {@link IBackupTransport} returned by {@link + * TransportClient.connect(String)}. + */ +public class IntermediateEncryptingTransport extends DelegatingTransport { + private final TransportClient mTransportClient; + private final Object mConnectLock = new Object(); + private volatile IBackupTransport mRealTransport; + + @VisibleForTesting + IntermediateEncryptingTransport(TransportClient transportClient) { + mTransportClient = transportClient; + } + + @Override + protected IBackupTransport getDelegate() throws RemoteException { + if (mRealTransport == null) { + connect(); + } + return mRealTransport; + } + + private void connect() throws RemoteException { + synchronized (mConnectLock) { + if (mRealTransport == null) { + mRealTransport = mTransportClient.connect("IntermediateEncryptingTransport"); + if (mRealTransport == null) { + throw new RemoteException("Could not connect: " + mTransportClient); + } + } + } + } + + @VisibleForTesting + TransportClient getClient() { + return mTransportClient; + } +} diff --git a/packages/BackupEncryption/src/com/android/server/backup/encryption/transport/IntermediateEncryptingTransportManager.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/transport/IntermediateEncryptingTransportManager.java new file mode 100644 index 000000000000..5a8b05c9f0fe --- /dev/null +++ b/packages/BackupEncryption/src/com/android/server/backup/encryption/transport/IntermediateEncryptingTransportManager.java @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2019 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.server.backup.encryption.transport; + +import static com.android.server.backup.encryption.BackupEncryptionService.TAG; + +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.os.UserHandle; +import android.util.Log; + +import com.android.internal.annotations.VisibleForTesting; +import com.android.internal.backup.IBackupTransport; +import com.android.server.backup.transport.TransportClientManager; +import com.android.server.backup.transport.TransportStats; + +import java.util.HashMap; +import java.util.Map; + +/** + * Handles creation and cleanup of {@link IntermediateEncryptingTransport} instances. + */ +public class IntermediateEncryptingTransportManager { + private static final String CALLER = "IntermediateEncryptingTransportManager"; + private final TransportClientManager mTransportClientManager; + private final Object mTransportsLock = new Object(); + private final Map<ComponentName, IntermediateEncryptingTransport> mTransports = new HashMap<>(); + + @VisibleForTesting + IntermediateEncryptingTransportManager(TransportClientManager transportClientManager) { + mTransportClientManager = transportClientManager; + } + + public IntermediateEncryptingTransportManager(Context context) { + this(new TransportClientManager(UserHandle.myUserId(), context, new TransportStats())); + } + + /** + * Extract the {@link ComponentName} corresponding to the real {@link IBackupTransport}, and + * provide a {@link IntermediateEncryptingTransport} which is an implementation of {@link + * IBackupTransport} that encrypts (or decrypts) the data when sending it (or receiving it) from + * the real {@link IBackupTransport}. + * @param intent {@link Intent} created with a call to {@link + * TransportClientManager.getEncryptingTransportIntent(ComponentName)}. + * @return + */ + public IntermediateEncryptingTransport get(Intent intent) { + Intent transportIntent = TransportClientManager.getRealTransportIntent(intent); + Log.i(TAG, "get: intent:" + intent + " transportIntent:" + transportIntent); + synchronized (mTransportsLock) { + return mTransports.computeIfAbsent(transportIntent.getComponent(), + c -> create(transportIntent)); + } + } + + /** + * Create an instance of {@link IntermediateEncryptingTransport}. + */ + private IntermediateEncryptingTransport create(Intent realTransportIntent) { + return new IntermediateEncryptingTransport(mTransportClientManager.getTransportClient( + realTransportIntent.getComponent(), realTransportIntent.getExtras(), CALLER)); + } + + /** + * Cleanup the {@link IntermediateEncryptingTransport} which was created by a call to + * {@link #get(Intent)} with this {@link Intent}. + */ + public void cleanup(Intent intent) { + Intent transportIntent = TransportClientManager.getRealTransportIntent(intent); + Log.i(TAG, "cleanup: intent:" + intent + " transportIntent:" + transportIntent); + + IntermediateEncryptingTransport transport; + synchronized (mTransportsLock) { + transport = mTransports.remove(transportIntent.getComponent()); + } + if (transport != null) { + mTransportClientManager.disposeOfTransportClient(transport.getClient(), CALLER); + } else { + Log.i(TAG, "Could not find IntermediateEncryptingTransport"); + } + } +} |