1616
1717package com .android .commands .pm ;
1818
19+ import com .android .internal .content .PackageHelper ;
20+
1921import android .app .ActivityManagerNative ;
2022import android .content .ComponentName ;
2123import android .content .pm .ApplicationInfo ;
24+ import android .content .pm .ContainerEncryptionParams ;
2225import android .content .pm .FeatureInfo ;
2326import android .content .pm .IPackageDataObserver ;
2427import android .content .pm .IPackageDeleteObserver ;
4043import android .os .RemoteException ;
4144import android .os .ServiceManager ;
4245
43- import com .android .internal .content .PackageHelper ;
44-
4546import java .io .File ;
4647import java .lang .reflect .Field ;
4748import java .lang .reflect .Modifier ;
49+ import java .security .InvalidAlgorithmParameterException ;
4850import java .util .ArrayList ;
4951import java .util .Collections ;
5052import java .util .Comparator ;
5153import java .util .List ;
5254import java .util .WeakHashMap ;
5355
56+ import javax .crypto .SecretKey ;
57+ import javax .crypto .spec .IvParameterSpec ;
58+ import javax .crypto .spec .SecretKeySpec ;
59+
5460public final class Pm {
5561 IPackageManager mPm ;
5662
@@ -763,6 +769,15 @@ private void runInstall() {
763769 String installerPackageName = null ;
764770
765771 String opt ;
772+
773+ String algo = null ;
774+ byte [] iv = null ;
775+ byte [] key = null ;
776+
777+ String macAlgo = null ;
778+ byte [] macKey = null ;
779+ byte [] tag = null ;
780+
766781 while ((opt =nextOption ()) != null ) {
767782 if (opt .equals ("-l" )) {
768783 installFlags |= PackageManager .INSTALL_FORWARD_LOCK ;
@@ -783,13 +798,93 @@ private void runInstall() {
783798 } else if (opt .equals ("-f" )) {
784799 // Override if -s option is specified.
785800 installFlags |= PackageManager .INSTALL_INTERNAL ;
801+ } else if (opt .equals ("--algo" )) {
802+ algo = nextOptionData ();
803+ if (algo == null ) {
804+ System .err .println ("Error: must supply argument for --algo" );
805+ showUsage ();
806+ return ;
807+ }
808+ } else if (opt .equals ("--iv" )) {
809+ iv = hexToBytes (nextOptionData ());
810+ if (iv == null ) {
811+ System .err .println ("Error: must supply argument for --iv" );
812+ showUsage ();
813+ return ;
814+ }
815+ } else if (opt .equals ("--key" )) {
816+ key = hexToBytes (nextOptionData ());
817+ if (key == null ) {
818+ System .err .println ("Error: must supply argument for --key" );
819+ showUsage ();
820+ return ;
821+ }
822+ } else if (opt .equals ("--macalgo" )) {
823+ macAlgo = nextOptionData ();
824+ if (macAlgo == null ) {
825+ System .err .println ("Error: must supply argument for --macalgo" );
826+ showUsage ();
827+ return ;
828+ }
829+ } else if (opt .equals ("--mackey" )) {
830+ macKey = hexToBytes (nextOptionData ());
831+ if (macKey == null ) {
832+ System .err .println ("Error: must supply argument for --mackey" );
833+ showUsage ();
834+ return ;
835+ }
836+ } else if (opt .equals ("--tag" )) {
837+ tag = hexToBytes (nextOptionData ());
838+ if (tag == null ) {
839+ System .err .println ("Error: must supply argument for --tag" );
840+ showUsage ();
841+ return ;
842+ }
786843 } else {
787844 System .err .println ("Error: Unknown option: " + opt );
788845 showUsage ();
789846 return ;
790847 }
791848 }
792849
850+ final ContainerEncryptionParams encryptionParams ;
851+ if (algo != null || iv != null || key != null || macAlgo != null || macKey != null
852+ || tag != null ) {
853+ if (algo == null || iv == null || key == null ) {
854+ System .err .println ("Error: all of --algo, --iv, and --key must be specified" );
855+ showUsage ();
856+ return ;
857+ }
858+
859+ if (macAlgo != null || macKey != null || tag != null ) {
860+ if (macAlgo == null || macKey == null || tag == null ) {
861+ System .err .println ("Error: all of --macalgo, --mackey, and --tag must "
862+ + "be specified" );
863+ showUsage ();
864+ return ;
865+ }
866+ }
867+
868+ try {
869+ final SecretKey encKey = new SecretKeySpec (key , "RAW" );
870+
871+ final SecretKey macSecretKey ;
872+ if (macKey == null || macKey .length == 0 ) {
873+ macSecretKey = null ;
874+ } else {
875+ macSecretKey = new SecretKeySpec (macKey , "RAW" );
876+ }
877+
878+ encryptionParams = new ContainerEncryptionParams (algo , new IvParameterSpec (iv ),
879+ encKey , macAlgo , null , macSecretKey , tag , -1 , -1 , -1 );
880+ } catch (InvalidAlgorithmParameterException e ) {
881+ e .printStackTrace ();
882+ return ;
883+ }
884+ } else {
885+ encryptionParams = null ;
886+ }
887+
793888 final Uri apkURI ;
794889 final Uri verificationURI ;
795890
@@ -816,7 +911,7 @@ private void runInstall() {
816911 PackageInstallObserver obs = new PackageInstallObserver ();
817912 try {
818913 mPm .installPackageWithVerification (apkURI , obs , installFlags , installerPackageName ,
819- verificationURI , null );
914+ verificationURI , null , encryptionParams );
820915
821916 synchronized (obs ) {
822917 while (!obs .finished ) {
@@ -839,6 +934,37 @@ private void runInstall() {
839934 }
840935 }
841936
937+ /**
938+ * Convert a string containing hex-encoded bytes to a byte array.
939+ *
940+ * @param input String containing hex-encoded bytes
941+ * @return input as an array of bytes
942+ */
943+ private byte [] hexToBytes (String input ) {
944+ if (input == null ) {
945+ return null ;
946+ }
947+
948+ final int inputLength = input .length ();
949+ if ((inputLength % 2 ) != 0 ) {
950+ System .err .print ("Invalid length; must be multiple of 2" );
951+ return null ;
952+ }
953+
954+ final int byteLength = inputLength / 2 ;
955+ final byte [] output = new byte [byteLength ];
956+
957+ int inputIndex = 0 ;
958+ int byteIndex = 0 ;
959+ while (inputIndex < inputLength ) {
960+ output [byteIndex ++] = (byte ) Integer .parseInt (
961+ input .substring (inputIndex , inputIndex + 2 ), 16 );
962+ inputIndex += 2 ;
963+ }
964+
965+ return output ;
966+ }
967+
842968 public void runCreateUser () {
843969 // Need to be run as root
844970 if (Process .myUid () != ROOT_UID ) {
@@ -1236,7 +1362,8 @@ private static void showUsage() {
12361362 System .err .println (" pm list libraries" );
12371363 System .err .println (" pm list users" );
12381364 System .err .println (" pm path PACKAGE" );
1239- System .err .println (" pm install [-l] [-r] [-t] [-i INSTALLER_PACKAGE_NAME] [-s] [-f] PATH" );
1365+ System .err .println (" pm install [-l] [-r] [-t] [-i INSTALLER_PACKAGE_NAME] [-s] [-f]" );
1366+ System .err .println (" [--algo <algorithm name> --key <key-in-hex> --iv <IV-in-hex>] PATH" );
12401367 System .err .println (" pm uninstall [-k] PACKAGE" );
12411368 System .err .println (" pm clear PACKAGE" );
12421369 System .err .println (" pm enable [--user USER_ID] PACKAGE_OR_COMPONENT" );
0 commit comments