OSDN Git Service

Start removing ContainerEncryptionParams.
authorJeff Sharkey <jsharkey@android.com>
Sat, 5 Jul 2014 22:46:38 +0000 (15:46 -0700)
committerJeff Sharkey <jsharkey@android.com>
Sat, 5 Jul 2014 22:49:07 +0000 (15:49 -0700)
The new PackageInstallerSession APIs will allow installers to deliver
bits directly into system protected storage, so we no longer need
encrypted containers.

Change-Id: I8b598cb149b7dfd1d41e6626c1359610a573edf1

core/java/com/android/internal/app/IMediaContainerService.aidl
packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java
services/core/java/com/android/server/pm/PackageManagerService.java

index 3cd0417..7904cba 100644 (file)
@@ -17,7 +17,6 @@
 package com.android.internal.app;
 
 import android.os.ParcelFileDescriptor;
-import android.content.pm.ContainerEncryptionParams;
 import android.content.pm.PackageInfoLite;
 import android.content.res.ObbInfo;
 
@@ -25,8 +24,7 @@ interface IMediaContainerService {
     String copyResourceToContainer(String packagePath, String containerId, String key,
             String resFileName, String publicResFileName, boolean isExternal,
             boolean isForwardLocked, String abiOverride);
-    int copyResource(String packagePath, in ContainerEncryptionParams encryptionParams,
-            in ParcelFileDescriptor outStream);
+    int copyResource(String packagePath, in ParcelFileDescriptor outStream);
     PackageInfoLite getMinimalPackageInfo(String packagePath, int flags, long threshold,
             String abiOverride);
     boolean checkInternalFreeStorage(String packagePath, boolean isForwardLocked, long threshold);
index 4a61f1f..1a4bbaa 100644 (file)
@@ -18,7 +18,6 @@ package com.android.defcontainer;
 
 import android.app.IntentService;
 import android.content.Intent;
-import android.content.pm.ContainerEncryptionParams;
 import android.content.pm.IPackageManager;
 import android.content.pm.LimitedLengthInputStream;
 import android.content.pm.MacAuthenticatedInputStream;
@@ -141,32 +140,24 @@ public class DefaultContainerService extends IntentService {
          *         {@link PackageManager}
          */
         @Override
-        public int copyResource(final String packagePath,
-                ContainerEncryptionParams encryptionParams, ParcelFileDescriptor outStream) {
+        public int copyResource(final String packagePath, ParcelFileDescriptor outStream) {
             if (packagePath == null || outStream == null) {
                 return PackageManager.INSTALL_FAILED_INVALID_URI;
             }
 
-            ParcelFileDescriptor.AutoCloseOutputStream autoOut
-                    = new ParcelFileDescriptor.AutoCloseOutputStream(outStream);
-
+            InputStream in = null;
+            OutputStream out = null;
             try {
-                copyFile(packagePath, autoOut, encryptionParams);
+                in = new FileInputStream(packagePath);
+                out = new ParcelFileDescriptor.AutoCloseOutputStream(outStream);
+                Streams.copy(in, out);
                 return PackageManager.INSTALL_SUCCEEDED;
-            } catch (FileNotFoundException e) {
-                Slog.e(TAG, "Could not copy URI " + packagePath.toString() + " FNF: "
-                        + e.getMessage());
-                return PackageManager.INSTALL_FAILED_INVALID_URI;
             } catch (IOException e) {
-                Slog.e(TAG, "Could not copy URI " + packagePath.toString() + " IO: "
-                        + e.getMessage());
+                Slog.e(TAG, "Failed to copy " + packagePath, e);
                 return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
-            } catch (DigestException e) {
-                Slog.e(TAG, "Could not copy URI " + packagePath.toString() + " Security: "
-                                + e.getMessage());
-                return PackageManager.INSTALL_FAILED_INVALID_APK;
             } finally {
-                IoUtils.closeQuietly(autoOut);
+                IoUtils.closeQuietly(out);
+                IoUtils.closeQuietly(in);
             }
         }
 
@@ -484,190 +475,6 @@ public class DefaultContainerService extends IntentService {
         return newCachePath;
     }
 
-    private static void copyToFile(InputStream inputStream, OutputStream out) throws IOException {
-        byte[] buffer = new byte[16384];
-        int bytesRead;
-        while ((bytesRead = inputStream.read(buffer)) >= 0) {
-            out.write(buffer, 0, bytesRead);
-        }
-    }
-
-    private void copyFile(String packagePath, OutputStream outStream,
-            ContainerEncryptionParams encryptionParams) throws FileNotFoundException, IOException,
-            DigestException {
-        InputStream inStream = null;
-        try {
-            final InputStream is = new FileInputStream(new File(packagePath));
-            inStream = new BufferedInputStream(is);
-
-            /*
-             * If this resource is encrypted, get the decrypted stream version
-             * of it.
-             */
-            ApkContainer container = new ApkContainer(inStream, encryptionParams);
-
-            try {
-                /*
-                 * We copy the source package file to a temp file and then
-                 * rename it to the destination file in order to eliminate a
-                 * window where the package directory scanner notices the new
-                 * package file but it's not completely copied yet.
-                 */
-                copyToFile(container.getInputStream(), outStream);
-
-                if (!container.isAuthenticated()) {
-                    throw new DigestException();
-                }
-            } catch (GeneralSecurityException e) {
-                throw new DigestException("A problem occured copying the file.");
-            }
-        } finally {
-            IoUtils.closeQuietly(inStream);
-        }
-    }
-
-    private static class ApkContainer {
-        private static final int MAX_AUTHENTICATED_DATA_SIZE = 16384;
-
-        private final InputStream mInStream;
-
-        private MacAuthenticatedInputStream mAuthenticatedStream;
-
-        private byte[] mTag;
-
-        public ApkContainer(InputStream inStream, ContainerEncryptionParams encryptionParams)
-                throws IOException {
-            if (encryptionParams == null) {
-                mInStream = inStream;
-            } else {
-                mInStream = getDecryptedStream(inStream, encryptionParams);
-                mTag = encryptionParams.getMacTag();
-            }
-        }
-
-        public boolean isAuthenticated() {
-            if (mAuthenticatedStream == null) {
-                return true;
-            }
-
-            return mAuthenticatedStream.isTagEqual(mTag);
-        }
-
-        private Mac getMacInstance(ContainerEncryptionParams encryptionParams) throws IOException {
-            final Mac m;
-            try {
-                final String macAlgo = encryptionParams.getMacAlgorithm();
-
-                if (macAlgo != null) {
-                    m = Mac.getInstance(macAlgo);
-                    m.init(encryptionParams.getMacKey(), encryptionParams.getMacSpec());
-                } else {
-                    m = null;
-                }
-
-                return m;
-            } catch (NoSuchAlgorithmException e) {
-                throw new IOException(e);
-            } catch (InvalidKeyException e) {
-                throw new IOException(e);
-            } catch (InvalidAlgorithmParameterException e) {
-                throw new IOException(e);
-            }
-        }
-
-        public InputStream getInputStream() {
-            return mInStream;
-        }
-
-        private InputStream getDecryptedStream(InputStream inStream,
-                ContainerEncryptionParams encryptionParams) throws IOException {
-            final Cipher c;
-            try {
-                c = Cipher.getInstance(encryptionParams.getEncryptionAlgorithm());
-                c.init(Cipher.DECRYPT_MODE, encryptionParams.getEncryptionKey(),
-                        encryptionParams.getEncryptionSpec());
-            } catch (NoSuchAlgorithmException e) {
-                throw new IOException(e);
-            } catch (NoSuchPaddingException e) {
-                throw new IOException(e);
-            } catch (InvalidKeyException e) {
-                throw new IOException(e);
-            } catch (InvalidAlgorithmParameterException e) {
-                throw new IOException(e);
-            }
-
-            final long encStart = encryptionParams.getEncryptedDataStart();
-            final long end = encryptionParams.getDataEnd();
-            if (end < encStart) {
-                throw new IOException("end <= encStart");
-            }
-
-            final Mac mac = getMacInstance(encryptionParams);
-            if (mac != null) {
-                final long macStart = encryptionParams.getAuthenticatedDataStart();
-                if (macStart >= Integer.MAX_VALUE) {
-                    throw new IOException("macStart >= Integer.MAX_VALUE");
-                }
-
-                final long furtherOffset;
-                if (macStart >= 0 && encStart >= 0 && macStart < encStart) {
-                    /*
-                     * If there is authenticated data at the beginning, read
-                     * that into our MAC first.
-                     */
-                    final long authenticatedLengthLong = encStart - macStart;
-                    if (authenticatedLengthLong > MAX_AUTHENTICATED_DATA_SIZE) {
-                        throw new IOException("authenticated data is too long");
-                    }
-                    final int authenticatedLength = (int) authenticatedLengthLong;
-
-                    final byte[] authenticatedData = new byte[(int) authenticatedLength];
-
-                    Streams.readFully(inStream, authenticatedData, (int) macStart,
-                            authenticatedLength);
-                    mac.update(authenticatedData, 0, authenticatedLength);
-
-                    furtherOffset = 0;
-                } else {
-                    /*
-                     * No authenticated data at the beginning. Just skip the
-                     * required number of bytes to the beginning of the stream.
-                     */
-                    if (encStart > 0) {
-                        furtherOffset = encStart;
-                    } else {
-                        furtherOffset = 0;
-                    }
-                }
-
-                /*
-                 * If there is data at the end of the stream we want to ignore,
-                 * wrap this in a LimitedLengthInputStream.
-                 */
-                if (furtherOffset >= 0 && end > furtherOffset) {
-                    inStream = new LimitedLengthInputStream(inStream, furtherOffset, end - encStart);
-                } else if (furtherOffset > 0) {
-                    inStream.skip(furtherOffset);
-                }
-
-                mAuthenticatedStream = new MacAuthenticatedInputStream(inStream, mac);
-
-                inStream = mAuthenticatedStream;
-            } else {
-                if (encStart >= 0) {
-                    if (end > encStart) {
-                        inStream = new LimitedLengthInputStream(inStream, encStart, end - encStart);
-                    } else {
-                        inStream.skip(encStart);
-                    }
-                }
-            }
-
-            return new CipherInputStream(inStream, c);
-        }
-
-    }
-
     private static final int PREFER_INTERNAL = 1;
     private static final int PREFER_EXTERNAL = 2;
 
index 27b4843..7675f54 100644 (file)
@@ -38,6 +38,7 @@ import static com.android.internal.util.ArrayUtils.appendInt;
 import static com.android.internal.util.ArrayUtils.removeInt;
 
 import android.util.ArrayMap;
+
 import com.android.internal.R;
 import com.android.internal.app.IMediaContainerService;
 import com.android.internal.app.ResolverActivity;
@@ -7705,10 +7706,13 @@ public class PackageManagerService extends IPackageManager.Stub {
         }
         final File fromFile = new File(packageURI.getPath());
 
+        if (encryptionParams != null) {
+            throw new UnsupportedOperationException("ContainerEncryptionParams not supported");
+        }
+
         final Message msg = mHandler.obtainMessage(INIT_COPY);
         msg.obj = new InstallParams(fromFile, observer, observer2, filteredFlags,
-                installerPackageName, verificationParams, encryptionParams, user,
-                packageAbiOverride);
+                installerPackageName, verificationParams, user, packageAbiOverride);
         mHandler.sendMessage(msg);
     }
 
@@ -8419,11 +8423,6 @@ public class PackageManagerService extends IPackageManager.Stub {
          */
         private final File mFromFile;
 
-        /**
-         * Local copy of {@link #mFromFile}, if generated.
-         */
-        private File mLocalFromFile;
-
         final IPackageInstallObserver observer;
         final IPackageInstallObserver2 observer2;
         int flags;
@@ -8431,14 +8430,12 @@ public class PackageManagerService extends IPackageManager.Stub {
         final VerificationParams verificationParams;
         private InstallArgs mArgs;
         private int mRet;
-        final ContainerEncryptionParams encryptionParams;
         final String packageAbiOverride;
         final String packageInstructionSetOverride;
 
         InstallParams(File fromFile, IPackageInstallObserver observer,
                 IPackageInstallObserver2 observer2, int flags, String installerPackageName,
-                VerificationParams verificationParams, ContainerEncryptionParams encryptionParams,
-                UserHandle user, String packageAbiOverride) {
+                VerificationParams verificationParams, UserHandle user, String packageAbiOverride) {
             super(user);
             mFromFile = Preconditions.checkNotNull(fromFile);
             this.observer = observer;
@@ -8446,7 +8443,6 @@ public class PackageManagerService extends IPackageManager.Stub {
             this.flags = flags;
             this.installerPackageName = installerPackageName;
             this.verificationParams = verificationParams;
-            this.encryptionParams = encryptionParams;
             this.packageAbiOverride = packageAbiOverride;
             this.packageInstructionSetOverride = (packageAbiOverride == null) ?
                     packageAbiOverride : VMRuntime.getInstructionSet(packageAbiOverride);
@@ -8556,26 +8552,6 @@ public class PackageManagerService extends IPackageManager.Stub {
                     Log.w(TAG, "Couldn't get low memory threshold; no free limit imposed");
                 }
 
-                if (encryptionParams != null) {
-                    // Make a temporary file for decryption.
-                    mLocalFromFile = createTempPackageFile(mDrmAppPrivateInstallDir);
-                    if (mLocalFromFile != null) {
-                        ParcelFileDescriptor out = null;
-                        try {
-                            out = ParcelFileDescriptor.open(mLocalFromFile,
-                                    ParcelFileDescriptor.MODE_READ_WRITE);
-                            ret = mContainerService.copyResource(mFromFile.getAbsolutePath(),
-                                    encryptionParams, out);
-                        } catch (FileNotFoundException e) {
-                            Slog.e(TAG, "Failed to create temporary file for: " + mFromFile);
-                        } finally {
-                            IoUtils.closeQuietly(out);
-                        }
-
-                        FileUtils.setPermissions(mLocalFromFile, 0644, -1, -1);
-                    }
-                }
-
                 // Remote call to find out default install location
                 final String fromPath = getFromFile().getAbsolutePath();
                 pkgLite = mContainerService.getMinimalPackageInfo(fromPath, flags, lowThreshold,
@@ -8794,12 +8770,6 @@ public class PackageManagerService extends IPackageManager.Stub {
             // will succeed.
             if (mArgs != null) {
                 processPendingInstall(mArgs, mRet);
-
-                if (mLocalFromFile != null) {
-                    if (!mLocalFromFile.delete()) {
-                        Slog.w(TAG, "Couldn't delete temporary file: " + mLocalFromFile);
-                    }
-                }
             }
         }
 
@@ -8814,11 +8784,7 @@ public class PackageManagerService extends IPackageManager.Stub {
         }
 
         public File getFromFile() {
-            if (mLocalFromFile != null) {
-                return mLocalFromFile;
-            } else {
-                return mFromFile;
-            }
+            return mFromFile;
         }
     }
 
@@ -9181,7 +9147,7 @@ public class PackageManagerService extends IPackageManager.Stub {
             // Copy the resource now
             int ret = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
             try {
-                ret = imcs.copyResource(fromFile.getAbsolutePath(), null, out);
+                ret = imcs.copyResource(fromFile.getAbsolutePath(), out);
             } finally {
                 IoUtils.closeQuietly(out);
             }