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
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user