Remove broken code for mounting encrypted OBB files
Mounting encrypted OBB files has never worked reliably across devices, partly due to its reliance on Twofish encryption support in the kernel. This is because Twofish support (CONFIG_CRYPTO_TWOFISH) has never been required or even recommended for Android. It has never been enabled in GKI, but even before GKI it wasn't required or recommended. Moreover, this is now the only Android feature that still uses dm-crypt (CONFIG_DM_CRYPT), and some devices don't have that enabled either. Therefore, it appears that this feature is unused. That's perhaps not surprising, considering that the documentation for OBBs (https://developer.android.com/google/play/expansion-files) says that they are deprecated, and also it explains OBBs as being app files that are opaque to the platform; the ability of the platform to mount OBBs that happen to be in a particular format is never mentioned. That means that OBB mounting is probably rarely used even with unencrypted OBBs. Finally, the usefulness of OBBs having their own encryption layer (in addition to what the platform already provides via FBE) is not clear either, especially with such an unusual choice of cipher. To avoid the confusion that is being caused by having the broken code for mounting encrypted OBBs still sitting around, let's remove it. Test: atest StorageManagerTest # on Cuttlefish Test: atest StorageManagerIntegrationTest # on Cuttlefish Bug: 216475849 Change-Id: I6e6a6462ab8343299dc5e0145b87dc28b16b0bc1
This commit is contained in:
@@ -54,13 +54,13 @@ interface IStorageManager {
|
|||||||
*/
|
*/
|
||||||
void shutdown(IStorageShutdownObserver observer) = 19;
|
void shutdown(IStorageShutdownObserver observer) = 19;
|
||||||
/**
|
/**
|
||||||
* Mounts an Opaque Binary Blob (OBB) with the specified decryption key and
|
* Mounts an Opaque Binary Blob (OBB). Only allows the calling process's UID
|
||||||
* only allows the calling process's UID access to the contents.
|
* access to the contents. StorageManagerService will call back to the
|
||||||
* StorageManagerService will call back to the supplied IObbActionListener to inform
|
* supplied IObbActionListener to inform it of the terminal state of the
|
||||||
* it of the terminal state of the call.
|
* call.
|
||||||
*/
|
*/
|
||||||
void mountObb(in String rawPath, in String canonicalPath, in String key,
|
void mountObb(in String rawPath, in String canonicalPath, IObbActionListener token,
|
||||||
IObbActionListener token, int nonce, in ObbInfo obbInfo) = 21;
|
int nonce, in ObbInfo obbInfo) = 21;
|
||||||
/**
|
/**
|
||||||
* Unmounts an Opaque Binary Blob (OBB). When the force flag is specified,
|
* Unmounts an Opaque Binary Blob (OBB). When the force flag is specified,
|
||||||
* any program using it will be forcibly killed to unmount the image.
|
* any program using it will be forcibly killed to unmount the image.
|
||||||
|
|||||||
@@ -665,9 +665,7 @@ public class StorageManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mount an Opaque Binary Blob (OBB) file. If a <code>key</code> is
|
* Mount an Opaque Binary Blob (OBB) file.
|
||||||
* specified, it is supplied to the mounting process to be used in any
|
|
||||||
* encryption used in the OBB.
|
|
||||||
* <p>
|
* <p>
|
||||||
* The OBB will remain mounted for as long as the StorageManager reference
|
* The OBB will remain mounted for as long as the StorageManager reference
|
||||||
* is held by the application. As soon as this reference is lost, the OBBs
|
* is held by the application. As soon as this reference is lost, the OBBs
|
||||||
@@ -680,19 +678,22 @@ public class StorageManager {
|
|||||||
* application's OBB that shares its UID.
|
* application's OBB that shares its UID.
|
||||||
*
|
*
|
||||||
* @param rawPath the path to the OBB file
|
* @param rawPath the path to the OBB file
|
||||||
* @param key secret used to encrypt the OBB; may be <code>null</code> if no
|
* @param key must be <code>null</code>. Previously, some Android device
|
||||||
* encryption was used on the OBB.
|
* implementations accepted a non-<code>null</code> key to mount
|
||||||
|
* an encrypted OBB file. However, this never worked reliably and
|
||||||
|
* is no longer supported.
|
||||||
* @param listener will receive the success or failure of the operation
|
* @param listener will receive the success or failure of the operation
|
||||||
* @return whether the mount call was successfully queued or not
|
* @return whether the mount call was successfully queued or not
|
||||||
*/
|
*/
|
||||||
public boolean mountObb(String rawPath, String key, OnObbStateChangeListener listener) {
|
public boolean mountObb(String rawPath, String key, OnObbStateChangeListener listener) {
|
||||||
Preconditions.checkNotNull(rawPath, "rawPath cannot be null");
|
Preconditions.checkNotNull(rawPath, "rawPath cannot be null");
|
||||||
|
Preconditions.checkArgument(key == null, "mounting encrypted OBBs is no longer supported");
|
||||||
Preconditions.checkNotNull(listener, "listener cannot be null");
|
Preconditions.checkNotNull(listener, "listener cannot be null");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
final String canonicalPath = new File(rawPath).getCanonicalPath();
|
final String canonicalPath = new File(rawPath).getCanonicalPath();
|
||||||
final int nonce = mObbActionListener.addListener(listener);
|
final int nonce = mObbActionListener.addListener(listener);
|
||||||
mStorageManager.mountObb(rawPath, canonicalPath, key, mObbActionListener, nonce,
|
mStorageManager.mountObb(rawPath, canonicalPath, mObbActionListener, nonce,
|
||||||
getObbInfo(canonicalPath));
|
getObbInfo(canonicalPath));
|
||||||
return true;
|
return true;
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
@@ -46,11 +46,7 @@ public class StorageManagerBaseTest extends InstrumentationTestCase {
|
|||||||
protected static String OBB_FILE_1_CONTENTS_1 = "OneToOneThousandInts.bin";
|
protected static String OBB_FILE_1_CONTENTS_1 = "OneToOneThousandInts.bin";
|
||||||
protected static String OBB_FILE_2 = "obb_file2.obb";
|
protected static String OBB_FILE_2 = "obb_file2.obb";
|
||||||
protected static String OBB_FILE_3 = "obb_file3.obb";
|
protected static String OBB_FILE_3 = "obb_file3.obb";
|
||||||
protected static String OBB_FILE_1_PASSWORD = "password1";
|
|
||||||
protected static String OBB_FILE_1_ENCRYPTED = "obb_enc_file100_orig1.obb";
|
|
||||||
protected static String OBB_FILE_2_UNSIGNED = "obb_file2_nosign.obb";
|
protected static String OBB_FILE_2_UNSIGNED = "obb_file2_nosign.obb";
|
||||||
protected static String OBB_FILE_3_PASSWORD = "password3";
|
|
||||||
protected static String OBB_FILE_3_ENCRYPTED = "obb_enc_file100_orig3.obb";
|
|
||||||
protected static String OBB_FILE_3_BAD_PACKAGENAME = "obb_file3_bad_packagename.obb";
|
protected static String OBB_FILE_3_BAD_PACKAGENAME = "obb_file3_bad_packagename.obb";
|
||||||
|
|
||||||
protected static boolean FORCE = true;
|
protected static boolean FORCE = true;
|
||||||
@@ -180,22 +176,21 @@ public class StorageManagerBaseTest extends InstrumentationTestCase {
|
|||||||
* Mounts an OBB file
|
* Mounts an OBB file
|
||||||
*
|
*
|
||||||
* @param obbFilePath The full path to the OBB file to mount
|
* @param obbFilePath The full path to the OBB file to mount
|
||||||
* @param key (optional) The key to use to unencrypt the OBB; pass null for no encryption
|
|
||||||
* @param expectedState The expected state resulting from trying to mount the OBB
|
* @param expectedState The expected state resulting from trying to mount the OBB
|
||||||
* @return A {@link String} representing the normalized path to OBB file that was mounted
|
* @return A {@link String} representing the normalized path to OBB file that was mounted
|
||||||
*/
|
*/
|
||||||
protected String mountObb(String obbFilePath, String key, int expectedState) {
|
protected String mountObb(String obbFilePath, int expectedState) {
|
||||||
return doMountObb(obbFilePath, key, expectedState);
|
return doMountObb(obbFilePath, expectedState);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mounts an OBB file with default options (no encryption, mounting succeeds)
|
* Mounts an OBB file with default options.
|
||||||
*
|
*
|
||||||
* @param obbFilePath The full path to the OBB file to mount
|
* @param obbFilePath The full path to the OBB file to mount
|
||||||
* @return A {@link String} representing the normalized path to OBB file that was mounted
|
* @return A {@link String} representing the normalized path to OBB file that was mounted
|
||||||
*/
|
*/
|
||||||
protected String mountObb(String obbFilePath) {
|
protected String mountObb(String obbFilePath) {
|
||||||
return doMountObb(obbFilePath, null, OnObbStateChangeListener.MOUNTED);
|
return doMountObb(obbFilePath, OnObbStateChangeListener.MOUNTED);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -232,13 +227,13 @@ public class StorageManagerBaseTest extends InstrumentationTestCase {
|
|||||||
* @return true if the listener was signaled of a state change by the system; else a fail()
|
* @return true if the listener was signaled of a state change by the system; else a fail()
|
||||||
* is triggered if we timed out
|
* is triggered if we timed out
|
||||||
*/
|
*/
|
||||||
protected String doMountObb_noThrow(String obbFilePath, String key, int expectedState) {
|
protected String doMountObb_noThrow(String obbFilePath, int expectedState) {
|
||||||
Log.i(LOG_TAG, "doMountObb() on " + obbFilePath + " using key: " + key);
|
Log.i(LOG_TAG, "doMountObb() on " + obbFilePath);
|
||||||
assertTrue ("Null path was passed in for OBB file!", obbFilePath != null);
|
assertTrue ("Null path was passed in for OBB file!", obbFilePath != null);
|
||||||
assertTrue ("Null path was passed in for OBB file!", obbFilePath != null);
|
assertTrue ("Null path was passed in for OBB file!", obbFilePath != null);
|
||||||
|
|
||||||
ObbListener obbListener = new ObbListener();
|
ObbListener obbListener = new ObbListener();
|
||||||
boolean success = mSm.mountObb(obbFilePath, key, obbListener);
|
boolean success = mSm.mountObb(obbFilePath, null, obbListener);
|
||||||
success &= obbFilePath.equals(doWaitForObbStateChange(obbListener));
|
success &= obbFilePath.equals(doWaitForObbStateChange(obbListener));
|
||||||
success &= (expectedState == obbListener.state());
|
success &= (expectedState == obbListener.state());
|
||||||
|
|
||||||
@@ -260,17 +255,16 @@ public class StorageManagerBaseTest extends InstrumentationTestCase {
|
|||||||
* Mounts an OBB file without throwing and synchronously waits for it to finish mounting
|
* Mounts an OBB file without throwing and synchronously waits for it to finish mounting
|
||||||
*
|
*
|
||||||
* @param obbFilePath The full path to the OBB file to mount
|
* @param obbFilePath The full path to the OBB file to mount
|
||||||
* @param key (optional) The key to use to unencrypt the OBB; pass null for no encryption
|
|
||||||
* @param expectedState The expected state resulting from trying to mount the OBB
|
* @param expectedState The expected state resulting from trying to mount the OBB
|
||||||
* @return A {@link String} representing the actual normalized path to OBB file that was
|
* @return A {@link String} representing the actual normalized path to OBB file that was
|
||||||
* mounted, or null if the mounting failed
|
* mounted, or null if the mounting failed
|
||||||
*/
|
*/
|
||||||
protected String doMountObb(String obbFilePath, String key, int expectedState) {
|
protected String doMountObb(String obbFilePath, int expectedState) {
|
||||||
Log.i(LOG_TAG, "doMountObb() on " + obbFilePath + " using key: " + key);
|
Log.i(LOG_TAG, "doMountObb() on " + obbFilePath);
|
||||||
assertTrue ("Null path was passed in for OBB file!", obbFilePath != null);
|
assertTrue ("Null path was passed in for OBB file!", obbFilePath != null);
|
||||||
|
|
||||||
ObbListener obbListener = new ObbListener();
|
ObbListener obbListener = new ObbListener();
|
||||||
assertTrue("mountObb call failed", mSm.mountObb(obbFilePath, key, obbListener));
|
assertTrue("mountObb call failed", mSm.mountObb(obbFilePath, null, obbListener));
|
||||||
assertTrue("Failed to get OBB mount status change for file: " + obbFilePath,
|
assertTrue("Failed to get OBB mount status change for file: " + obbFilePath,
|
||||||
doWaitForObbStateChange(obbListener));
|
doWaitForObbStateChange(obbListener));
|
||||||
assertEquals("OBB mount state not what was expected!", expectedState,
|
assertEquals("OBB mount state not what was expected!", expectedState,
|
||||||
|
|||||||
@@ -82,58 +82,6 @@ public class StorageManagerIntegrationTest extends StorageManagerBaseTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Tests mounting a single encrypted OBB file and verifies its contents.
|
|
||||||
*/
|
|
||||||
@LargeTest
|
|
||||||
public void testMountSingleEncryptedObb() throws Exception {
|
|
||||||
final File file = createObbFile(OBB_FILE_3_ENCRYPTED, R.raw.obb_enc_file100_orig3);
|
|
||||||
String filePath = file.getAbsolutePath();
|
|
||||||
mountObb(filePath, OBB_FILE_3_PASSWORD, OnObbStateChangeListener.MOUNTED);
|
|
||||||
verifyObb3Contents(filePath);
|
|
||||||
unmountObb(filePath, DONT_FORCE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tests mounting a single encrypted OBB file using an invalid password.
|
|
||||||
*/
|
|
||||||
@LargeTest
|
|
||||||
public void testMountSingleEncryptedObbInvalidPassword() throws Exception {
|
|
||||||
final File file = createObbFile("bad password@$%#@^*(!&)", R.raw.obb_enc_file100_orig3);
|
|
||||||
String filePath = file.getAbsolutePath();
|
|
||||||
mountObb(filePath, OBB_FILE_1_PASSWORD, OnObbStateChangeListener.ERROR_COULD_NOT_MOUNT);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tests simultaneously mounting 2 encrypted OBBs with different keys and verifies contents.
|
|
||||||
*/
|
|
||||||
@LargeTest
|
|
||||||
public void testMountTwoEncryptedObb() throws Exception {
|
|
||||||
File file3 = null;
|
|
||||||
File file1 = null;
|
|
||||||
try {
|
|
||||||
file3 = createObbFile(OBB_FILE_3_ENCRYPTED, R.raw.obb_enc_file100_orig3);
|
|
||||||
String filePath3 = file3.getAbsolutePath();
|
|
||||||
mountObb(filePath3, OBB_FILE_3_PASSWORD, OnObbStateChangeListener.MOUNTED);
|
|
||||||
verifyObb3Contents(filePath3);
|
|
||||||
|
|
||||||
file1 = createObbFile(OBB_FILE_1_ENCRYPTED, R.raw.obb_enc_file100_orig1);
|
|
||||||
String filePath1 = file1.getAbsolutePath();
|
|
||||||
mountObb(filePath1, OBB_FILE_1_PASSWORD, OnObbStateChangeListener.MOUNTED);
|
|
||||||
verifyObb1Contents(filePath1);
|
|
||||||
|
|
||||||
unmountObb(filePath3, DONT_FORCE);
|
|
||||||
unmountObb(filePath1, DONT_FORCE);
|
|
||||||
} finally {
|
|
||||||
if (file3 != null) {
|
|
||||||
file3.delete();
|
|
||||||
}
|
|
||||||
if (file1 != null) {
|
|
||||||
file1.delete();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests mounting a single OBB that isn't signed.
|
* Tests mounting a single OBB that isn't signed.
|
||||||
*/
|
*/
|
||||||
@@ -142,7 +90,7 @@ public class StorageManagerIntegrationTest extends StorageManagerBaseTest {
|
|||||||
final File file = createObbFile(OBB_FILE_2_UNSIGNED, R.raw.obb_file2_nosign);
|
final File file = createObbFile(OBB_FILE_2_UNSIGNED, R.raw.obb_file2_nosign);
|
||||||
String filePath = file.getAbsolutePath();
|
String filePath = file.getAbsolutePath();
|
||||||
try {
|
try {
|
||||||
mountObb(filePath, OBB_FILE_2_UNSIGNED, OnObbStateChangeListener.ERROR_INTERNAL);
|
mountObb(filePath, OnObbStateChangeListener.ERROR_INTERNAL);
|
||||||
fail("mountObb should've failed with an exception");
|
fail("mountObb should've failed with an exception");
|
||||||
} catch (IllegalArgumentException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
// Expected
|
// Expected
|
||||||
@@ -156,8 +104,7 @@ public class StorageManagerIntegrationTest extends StorageManagerBaseTest {
|
|||||||
public void testMountBadPackageNameObb() throws Exception {
|
public void testMountBadPackageNameObb() throws Exception {
|
||||||
final File file = createObbFile(OBB_FILE_3_BAD_PACKAGENAME, R.raw.obb_file3_bad_packagename);
|
final File file = createObbFile(OBB_FILE_3_BAD_PACKAGENAME, R.raw.obb_file3_bad_packagename);
|
||||||
String filePath = file.getAbsolutePath();
|
String filePath = file.getAbsolutePath();
|
||||||
mountObb(filePath, OBB_FILE_3_BAD_PACKAGENAME,
|
mountObb(filePath, OnObbStateChangeListener.ERROR_PERMISSION_DENIED);
|
||||||
OnObbStateChangeListener.ERROR_PERMISSION_DENIED);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -169,7 +116,7 @@ public class StorageManagerIntegrationTest extends StorageManagerBaseTest {
|
|||||||
String filePath = file.getAbsolutePath();
|
String filePath = file.getAbsolutePath();
|
||||||
mountObb(filePath);
|
mountObb(filePath);
|
||||||
verifyObb1Contents(filePath);
|
verifyObb1Contents(filePath);
|
||||||
mountObb(filePath, null, OnObbStateChangeListener.ERROR_ALREADY_MOUNTED);
|
mountObb(filePath, OnObbStateChangeListener.ERROR_ALREADY_MOUNTED);
|
||||||
verifyObb1Contents(filePath);
|
verifyObb1Contents(filePath);
|
||||||
unmountObb(filePath, DONT_FORCE);
|
unmountObb(filePath, DONT_FORCE);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -442,14 +442,13 @@ public:
|
|||||||
reply.readExceptionCode();
|
reply.readExceptionCode();
|
||||||
}
|
}
|
||||||
|
|
||||||
void mountObb(const String16& rawPath, const String16& canonicalPath, const String16& key,
|
void mountObb(const String16& rawPath, const String16& canonicalPath,
|
||||||
const sp<IObbActionListener>& token, int32_t nonce, const sp<ObbInfo>& obbInfo)
|
const sp<IObbActionListener>& token, int32_t nonce, const sp<ObbInfo>& obbInfo)
|
||||||
{
|
{
|
||||||
Parcel data, reply;
|
Parcel data, reply;
|
||||||
data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
|
data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
|
||||||
data.writeString16(rawPath);
|
data.writeString16(rawPath);
|
||||||
data.writeString16(canonicalPath);
|
data.writeString16(canonicalPath);
|
||||||
data.writeString16(key);
|
|
||||||
data.writeStrongBinder(IInterface::asBinder(token));
|
data.writeStrongBinder(IInterface::asBinder(token));
|
||||||
data.writeInt32(nonce);
|
data.writeInt32(nonce);
|
||||||
obbInfo->writeToParcel(&data);
|
obbInfo->writeToParcel(&data);
|
||||||
|
|||||||
@@ -64,8 +64,8 @@ public:
|
|||||||
virtual void shutdown(const sp<IMountShutdownObserver>& observer) = 0;
|
virtual void shutdown(const sp<IMountShutdownObserver>& observer) = 0;
|
||||||
virtual void finishMediaUpdate() = 0;
|
virtual void finishMediaUpdate() = 0;
|
||||||
virtual void mountObb(const String16& rawPath, const String16& canonicalPath,
|
virtual void mountObb(const String16& rawPath, const String16& canonicalPath,
|
||||||
const String16& key, const sp<IObbActionListener>& token,
|
const sp<IObbActionListener>& token, const int32_t nonce,
|
||||||
const int32_t nonce, const sp<ObbInfo>& obbInfo) = 0;
|
const sp<ObbInfo>& obbInfo) = 0;
|
||||||
virtual void unmountObb(const String16& filename, const bool force,
|
virtual void unmountObb(const String16& filename, const bool force,
|
||||||
const sp<IObbActionListener>& token, const int32_t nonce) = 0;
|
const sp<IObbActionListener>& token, const int32_t nonce) = 0;
|
||||||
virtual bool isObbMounted(const String16& filename) = 0;
|
virtual bool isObbMounted(const String16& filename) = 0;
|
||||||
|
|||||||
@@ -140,8 +140,7 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void mountObb(const char* rawPath, const char* key, AStorageManager_obbCallbackFunc func,
|
void mountObb(const char* rawPath, AStorageManager_obbCallbackFunc func, void* data) {
|
||||||
void* data) {
|
|
||||||
// Resolve path before sending to MountService
|
// Resolve path before sending to MountService
|
||||||
char canonicalPath[PATH_MAX];
|
char canonicalPath[PATH_MAX];
|
||||||
if (realpath(rawPath, canonicalPath) == NULL) {
|
if (realpath(rawPath, canonicalPath) == NULL) {
|
||||||
@@ -158,9 +157,7 @@ public:
|
|||||||
ObbCallback* cb = registerObbCallback(func, data);
|
ObbCallback* cb = registerObbCallback(func, data);
|
||||||
String16 rawPath16(rawPath);
|
String16 rawPath16(rawPath);
|
||||||
String16 canonicalPath16(canonicalPath);
|
String16 canonicalPath16(canonicalPath);
|
||||||
String16 key16(key);
|
mMountService->mountObb(rawPath16, canonicalPath16, mObbActionListener, cb->nonce, obbInfo);
|
||||||
mMountService->mountObb(rawPath16, canonicalPath16, key16, mObbActionListener,
|
|
||||||
cb->nonce, obbInfo);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void unmountObb(const char* filename, const bool force, AStorageManager_obbCallbackFunc func, void* data) {
|
void unmountObb(const char* filename, const bool force, AStorageManager_obbCallbackFunc func, void* data) {
|
||||||
@@ -207,7 +204,11 @@ void AStorageManager_delete(AStorageManager* mgr) {
|
|||||||
|
|
||||||
void AStorageManager_mountObb(AStorageManager* mgr, const char* filename, const char* key,
|
void AStorageManager_mountObb(AStorageManager* mgr, const char* filename, const char* key,
|
||||||
AStorageManager_obbCallbackFunc cb, void* data) {
|
AStorageManager_obbCallbackFunc cb, void* data) {
|
||||||
mgr->mountObb(filename, key, cb, data);
|
if (key != nullptr && key[0] != '\0') {
|
||||||
|
ALOGE("mounting encrypted OBBs is no longer supported");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mgr->mountObb(filename, cb, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AStorageManager_unmountObb(AStorageManager* mgr, const char* filename, const int force,
|
void AStorageManager_unmountObb(AStorageManager* mgr, const char* filename, const int force,
|
||||||
|
|||||||
@@ -173,9 +173,6 @@ import java.io.FileNotFoundException;
|
|||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
import java.math.BigInteger;
|
|
||||||
import java.security.GeneralSecurityException;
|
|
||||||
import java.security.spec.KeySpec;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
@@ -194,10 +191,6 @@ import java.util.concurrent.TimeoutException;
|
|||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
import javax.crypto.SecretKey;
|
|
||||||
import javax.crypto.SecretKeyFactory;
|
|
||||||
import javax.crypto.spec.PBEKeySpec;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Service responsible for various storage media. Connects to {@code vold} to
|
* Service responsible for various storage media. Connects to {@code vold} to
|
||||||
* watch for and manage dynamically added storage, such as SD cards and USB mass
|
* watch for and manage dynamically added storage, such as SD cards and USB mass
|
||||||
@@ -3073,8 +3066,8 @@ class StorageManagerService extends IStorageManager.Stub
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void mountObb(String rawPath, String canonicalPath, String key,
|
public void mountObb(String rawPath, String canonicalPath, IObbActionListener token,
|
||||||
IObbActionListener token, int nonce, ObbInfo obbInfo) {
|
int nonce, ObbInfo obbInfo) {
|
||||||
Objects.requireNonNull(rawPath, "rawPath cannot be null");
|
Objects.requireNonNull(rawPath, "rawPath cannot be null");
|
||||||
Objects.requireNonNull(canonicalPath, "canonicalPath cannot be null");
|
Objects.requireNonNull(canonicalPath, "canonicalPath cannot be null");
|
||||||
Objects.requireNonNull(token, "token cannot be null");
|
Objects.requireNonNull(token, "token cannot be null");
|
||||||
@@ -3083,7 +3076,7 @@ class StorageManagerService extends IStorageManager.Stub
|
|||||||
final int callingUid = Binder.getCallingUid();
|
final int callingUid = Binder.getCallingUid();
|
||||||
final ObbState obbState = new ObbState(rawPath, canonicalPath,
|
final ObbState obbState = new ObbState(rawPath, canonicalPath,
|
||||||
callingUid, token, nonce, null);
|
callingUid, token, nonce, null);
|
||||||
final ObbAction action = new MountObbAction(obbState, key, callingUid, obbInfo);
|
final ObbAction action = new MountObbAction(obbState, callingUid, obbInfo);
|
||||||
mObbActionHandler.sendMessage(mObbActionHandler.obtainMessage(OBB_RUN_ACTION, action));
|
mObbActionHandler.sendMessage(mObbActionHandler.obtainMessage(OBB_RUN_ACTION, action));
|
||||||
|
|
||||||
if (DEBUG_OBB)
|
if (DEBUG_OBB)
|
||||||
@@ -4428,13 +4421,11 @@ class StorageManagerService extends IStorageManager.Stub
|
|||||||
}
|
}
|
||||||
|
|
||||||
class MountObbAction extends ObbAction {
|
class MountObbAction extends ObbAction {
|
||||||
private final String mKey;
|
|
||||||
private final int mCallingUid;
|
private final int mCallingUid;
|
||||||
private ObbInfo mObbInfo;
|
private ObbInfo mObbInfo;
|
||||||
|
|
||||||
MountObbAction(ObbState obbState, String key, int callingUid, ObbInfo obbInfo) {
|
MountObbAction(ObbState obbState, int callingUid, ObbInfo obbInfo) {
|
||||||
super(obbState);
|
super(obbState);
|
||||||
mKey = key;
|
|
||||||
mCallingUid = callingUid;
|
mCallingUid = callingUid;
|
||||||
mObbInfo = obbInfo;
|
mObbInfo = obbInfo;
|
||||||
}
|
}
|
||||||
@@ -4457,29 +4448,8 @@ class StorageManagerService extends IStorageManager.Stub
|
|||||||
"Attempt to mount OBB which is already mounted: " + mObbInfo.filename);
|
"Attempt to mount OBB which is already mounted: " + mObbInfo.filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
final String hashedKey;
|
|
||||||
final String binderKey;
|
|
||||||
if (mKey == null) {
|
|
||||||
hashedKey = "none";
|
|
||||||
binderKey = "";
|
|
||||||
} else {
|
|
||||||
try {
|
|
||||||
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
|
|
||||||
|
|
||||||
KeySpec ks = new PBEKeySpec(mKey.toCharArray(), mObbInfo.salt,
|
|
||||||
PBKDF2_HASH_ROUNDS, CRYPTO_ALGORITHM_KEY_SIZE);
|
|
||||||
SecretKey key = factory.generateSecret(ks);
|
|
||||||
BigInteger bi = new BigInteger(key.getEncoded());
|
|
||||||
hashedKey = bi.toString(16);
|
|
||||||
binderKey = hashedKey;
|
|
||||||
} catch (GeneralSecurityException e) {
|
|
||||||
throw new ObbException(ERROR_INTERNAL, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
mObbState.volId = mVold.createObb(mObbState.canonicalPath, binderKey,
|
mObbState.volId = mVold.createObb(mObbState.canonicalPath, mObbState.ownerGid);
|
||||||
mObbState.ownerGid);
|
|
||||||
mVold.mount(mObbState.volId, 0, -1, null);
|
mVold.mount(mObbState.volId, 0, -1, null);
|
||||||
|
|
||||||
if (DEBUG_OBB)
|
if (DEBUG_OBB)
|
||||||
|
|||||||
Reference in New Issue
Block a user