diff options
author | Jason parks <jparks@google.com> | 2010-11-29 09:05:25 -0600 |
---|---|---|
committer | Jason parks <jparks@google.com> | 2011-01-05 12:32:49 -0600 |
commit | 5af0b916f850486cff4797355bf9e7dc3352fe00 (patch) | |
tree | 596919e498d72eadbc42b3307ac4f81542d34746 | |
parent | cf7775a88f8c88fc3a902799fc1d5100f6f7e0d6 (diff) | |
download | frameworks_base-5af0b916f850486cff4797355bf9e7dc3352fe00.zip frameworks_base-5af0b916f850486cff4797355bf9e7dc3352fe00.tar.gz frameworks_base-5af0b916f850486cff4797355bf9e7dc3352fe00.tar.bz2 |
Add decryption support to MountService.
* Implement the decryptStorage() method on the Mount Service.
This method makes the calls into vold to decrypt the encrypted
volumes and mount them.
Change-Id: I4f6e07a111cf0b36611d590debf9f6579c5ac5f7
-rw-r--r-- | core/java/android/os/storage/IMountService.java | 32 | ||||
-rw-r--r-- | include/storage/IMountService.h | 1 | ||||
-rw-r--r-- | libs/storage/IMountService.cpp | 18 | ||||
-rw-r--r-- | services/java/com/android/server/MountService.java | 37 |
4 files changed, 86 insertions, 2 deletions
diff --git a/core/java/android/os/storage/IMountService.java b/core/java/android/os/storage/IMountService.java index 3a2add4..23ed31f 100644 --- a/core/java/android/os/storage/IMountService.java +++ b/core/java/android/os/storage/IMountService.java @@ -586,6 +586,23 @@ public interface IMountService extends IInterface { } return _result; } + + public int decryptStorage(String password) throws RemoteException { + Parcel _data = Parcel.obtain(); + Parcel _reply = Parcel.obtain(); + int _result; + try { + _data.writeInterfaceToken(DESCRIPTOR); + _data.writeString(password); + mRemote.transact(Stub.TRANSACTION_decryptStorage, _data, _reply, 0); + _reply.readException(); + _result = _reply.readInt(); + } finally { + _reply.recycle(); + _data.recycle(); + } + return _result; + } } private static final String DESCRIPTOR = "IMountService"; @@ -642,6 +659,8 @@ public interface IMountService extends IInterface { static final int TRANSACTION_isExternalStorageEmulated = IBinder.FIRST_CALL_TRANSACTION + 25; + static final int TRANSACTION_decryptStorage = IBinder.FIRST_CALL_TRANSACTION + 26; + /** * Cast an IBinder object into an IMountService interface, generating a * proxy if needed. @@ -923,6 +942,14 @@ public interface IMountService extends IInterface { reply.writeInt(emulated ? 1 : 0); return true; } + case TRANSACTION_decryptStorage: { + data.enforceInterface(DESCRIPTOR); + String password = data.readString(); + int result = decryptStorage(password); + reply.writeNoException(); + reply.writeInt(result); + return true; + } } return super.onTransact(code, data, reply, flags); } @@ -1082,4 +1109,9 @@ public interface IMountService extends IInterface { * Returns whether or not the external storage is emulated. */ public boolean isExternalStorageEmulated() throws RemoteException; + + /** + * Decrypts any encrypted volumes. + */ + public int decryptStorage(String password) throws RemoteException; } diff --git a/include/storage/IMountService.h b/include/storage/IMountService.h index 51f9aeb..68ccd95 100644 --- a/include/storage/IMountService.h +++ b/include/storage/IMountService.h @@ -66,6 +66,7 @@ public: const sp<IObbActionListener>& token, const int32_t nonce) = 0; virtual bool isObbMounted(const String16& filename) = 0; virtual bool getMountedObbPath(const String16& filename, String16& path) = 0; + virtual int32_t decryptStorage(const String16& password) = 0; }; // ---------------------------------------------------------------------------- diff --git a/libs/storage/IMountService.cpp b/libs/storage/IMountService.cpp index b5f9c47..a7ab824 100644 --- a/libs/storage/IMountService.cpp +++ b/libs/storage/IMountService.cpp @@ -48,6 +48,7 @@ enum { TRANSACTION_isObbMounted, TRANSACTION_getMountedObbPath, TRANSACTION_isExternalStorageEmulated, + TRANSACTION_decryptStorage, }; class BpMountService: public BpInterface<IMountService> @@ -504,6 +505,23 @@ public: path = reply.readString16(); return true; } + + int32_t decryptStorage(const String16& password) + { + Parcel data, reply; + data.writeInterfaceToken(IMountService::getInterfaceDescriptor()); + data.writeString16(password); + if (remote()->transact(TRANSACTION_decryptStorage, data, &reply) != NO_ERROR) { + LOGD("decryptStorage could not contact remote\n"); + return -1; + } + int32_t err = reply.readExceptionCode(); + if (err < 0) { + LOGD("decryptStorage caught exception %d\n", err); + return err; + } + return reply.readInt32(); + } }; IMPLEMENT_META_INTERFACE(MountService, "IMountService"); diff --git a/services/java/com/android/server/MountService.java b/services/java/com/android/server/MountService.java index 64cd661..bf81457 100644 --- a/services/java/com/android/server/MountService.java +++ b/services/java/com/android/server/MountService.java @@ -73,8 +73,8 @@ import javax.crypto.spec.PBEKeySpec; * @hide - Applications should use android.os.storage.StorageManager * to access the MountService. */ -class MountService extends IMountService.Stub - implements INativeDaemonConnectorCallbacks { +class MountService extends IMountService.Stub implements INativeDaemonConnectorCallbacks { + private static final boolean LOCAL_LOGD = false; private static final boolean DEBUG_UNMOUNT = false; private static final boolean DEBUG_EVENTS = false; @@ -334,6 +334,7 @@ class MountService extends IMountService.Stub super(l); } + @Override public void handleMessage(Message msg) { switch (msg.what) { case H_UNMOUNT_PM_UPDATE: { @@ -427,6 +428,7 @@ class MountService extends IMountService.Stub } private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { + @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); @@ -442,6 +444,7 @@ class MountService extends IMountService.Stub return; } new Thread() { + @Override public void run() { try { String path = Environment.getExternalStorageDirectory().getPath(); @@ -565,6 +568,7 @@ class MountService extends IMountService.Stub * we need to do our work in a new thread. */ new Thread() { + @Override public void run() { /** * Determine media state and UMS detection status @@ -678,6 +682,7 @@ class MountService extends IMountService.Stub if (code == VoldResponseCode.VolumeDiskInserted) { new Thread() { + @Override public void run() { try { int rc; @@ -1007,6 +1012,7 @@ class MountService extends IMountService.Stub * USB mass storage disconnected while enabled */ new Thread() { + @Override public void run() { try { int rc; @@ -1624,6 +1630,29 @@ class MountService extends IMountService.Stub Slog.i(TAG, "Send to OBB handler: " + action.toString()); } + public int decryptStorage(String password) { + if (password == null) { + throw new IllegalArgumentException("password cannot be null"); + } + + // TODO: Enforce a permission + + waitForReady(); + + if (DEBUG_EVENTS) { + Slog.i(TAG, "decrypting storage..."); + } + + try { + mConnector.doCommand(String.format("cryptfs checkpw %s", password)); + } catch (NativeDaemonConnectorException e) { + // Decryption failed + return e.getCode(); + } + + return 0; + } + private void addObbStateLocked(ObbState obbState) throws RemoteException { final IBinder binder = obbState.getBinder(); List<ObbState> obbStates = mObbMounts.get(binder); @@ -1911,6 +1940,7 @@ class MountService extends IMountService.Stub mKey = key; } + @Override public void handleExecute() throws IOException, RemoteException { waitForReady(); warnOnNotMounted(); @@ -1991,6 +2021,7 @@ class MountService extends IMountService.Stub } } + @Override public void handleError() { sendNewStatusOrIgnore(OnObbStateChangeListener.ERROR_INTERNAL); } @@ -2020,6 +2051,7 @@ class MountService extends IMountService.Stub mForceUnmount = force; } + @Override public void handleExecute() throws IOException { waitForReady(); warnOnNotMounted(); @@ -2074,6 +2106,7 @@ class MountService extends IMountService.Stub } } + @Override public void handleError() { sendNewStatusOrIgnore(OnObbStateChangeListener.ERROR_INTERNAL); } |