Update boot signing in InstallMagisk

This commit is contained in:
topjohnwu 2017-10-31 16:31:58 +08:00
parent adf930f126
commit fdd700f3e5
7 changed files with 75 additions and 58 deletions

View File

@ -19,15 +19,13 @@ public class DownloadBusybox extends ParallelTask<Void, Void, Void> {
private static final String BUSYBOX_ARM = "https://github.com/topjohnwu/ndk-busybox/releases/download/1.27.2/busybox-arm";
private static final String BUSYBOX_X86 = "https://github.com/topjohnwu/ndk-busybox/releases/download/1.27.2/busybox-x86";
private File busybox;
@Override
protected Void doInBackground(Void... voids) {
Context context = MagiskManager.get();
busybox = new File(context.getCacheDir(), "busybox");
File busybox = new File(context.getCacheDir(), "busybox");
Utils.removeItem(context.getApplicationInfo().dataDir + "/busybox");
try {
FileOutputStream out = new FileOutputStream(busybox);
try (FileOutputStream out = new FileOutputStream(busybox)) {
HttpURLConnection conn = WebService.request(
Build.SUPPORTED_32_BIT_ABIS[0].contains("x86") ?
BUSYBOX_X86 :
@ -36,12 +34,7 @@ public class DownloadBusybox extends ParallelTask<Void, Void, Void> {
);
if (conn == null) throw new IOException();
BufferedInputStream bis = new BufferedInputStream(conn.getInputStream());
byte[] buffer = new byte[4096];
int len;
while ((len = bis.read(buffer)) != -1) {
out.write(buffer, 0, len);
}
out.close();
Utils.inToOut(bis, out);
conn.disconnect();
} catch (IOException e) {
e.printStackTrace();

View File

@ -64,10 +64,7 @@ public class FlashZip extends ParallelTask<Void, Void, Integer> {
) {
if (in == null) throw new FileNotFoundException();
InputStream buf= new BufferedInputStream(in);
byte buffer[] = new byte[4096];
int length;
while ((length = buf.read(buffer)) > 0)
out.write(buffer, 0, length);
Utils.inToOut(buf, out);
} catch (FileNotFoundException e) {
mList.add("! Invalid Uri");
throw e;

View File

@ -1,11 +1,13 @@
package com.topjohnwu.magisk.asyncs;
import android.app.Activity;
import android.content.res.AssetManager;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.text.TextUtils;
import com.topjohnwu.crypto.SignBoot;
import com.topjohnwu.magisk.MagiskManager;
import com.topjohnwu.magisk.container.AdaptiveList;
import com.topjohnwu.magisk.container.TarEntry;
@ -103,6 +105,7 @@ public class InstallMagisk extends ParallelTask<Void, Void, Boolean> {
ZipUtils.unzip(buf, install, "chromeos/", false);
buf.reset();
ZipUtils.unzip(buf, install, "META-INF/com/google/android/update-binary", true);
buf.close();
} catch (FileNotFoundException e) {
mList.add("! Invalid Uri");
throw e;
@ -111,10 +114,9 @@ public class InstallMagisk extends ParallelTask<Void, Void, Boolean> {
throw e;
}
File boot;
File boot = new File(install, "boot.img");
switch (mode) {
case PATCH_MODE:
boot = new File(install, "boot.img");
// Copy boot image to local
try (
InputStream in = mm.getContentResolver().openInputStream(mBootImg);
@ -136,10 +138,7 @@ public class InstallMagisk extends ParallelTask<Void, Void, Boolean> {
// Direct copy raw image
source = new BufferedInputStream(in);
}
byte buffer[] = new byte[1024];
int length;
while ((length = source.read(buffer)) > 0)
out.write(buffer, 0, length);
Utils.inToOut(source, out);
} catch (FileNotFoundException e) {
mList.add("! Invalid Uri");
throw e;
@ -147,26 +146,41 @@ public class InstallMagisk extends ParallelTask<Void, Void, Boolean> {
mList.add("! Copy failed");
throw e;
}
mList.add("- Use boot image: " + boot);
break;
case DIRECT_MODE:
boot = new File(mBootLocation);
try (OutputStream out = new FileOutputStream(boot)) {
Process process = Runtime.getRuntime().exec(new String[] { "su", "-c", "cat " + mBootLocation });
Utils.inToOut(process.getInputStream(), out);
process.waitFor();
process.destroy();
} catch (Exception e) {
mList.add("! Dump boot image failed");
throw e;
}
mList.add("- Use boot image: " + mBootLocation);
break;
default:
return false;
}
mList.add("- Use boot image: " + boot);
Shell shell;
if (mode == PATCH_MODE && Shell.rootAccess()) {
// Force non-root shell
shell = new Shell("sh");
} else {
shell = Shell.getShell();
boolean isSigned;
try (InputStream in = new FileInputStream(boot)) {
isSigned = SignBoot.verifySignature(in, null);
if (isSigned) {
mList.add("- Signed boot image detected");
}
} catch (Exception e) {
mList.add("! Unable to check signature");
throw e;
}
if (shell == null)
return false;
// Force non-root shell
Shell shell;
if (Shell.rootAccess())
shell = new Shell("sh");
else
shell = Shell.getShell();
// Patch boot image
shell.run(mList,
@ -180,6 +194,22 @@ public class InstallMagisk extends ParallelTask<Void, Void, Boolean> {
return false;
File patched_boot = new File(install, "new-boot.img");
if (isSigned) {
mList.add("- Signing boot image");
File signed = new File(install, "signed.img");
AssetManager assets = mm.getAssets();
try (
InputStream in = new FileInputStream(patched_boot);
OutputStream out = new BufferedOutputStream(new FileOutputStream(signed));
InputStream keyIn = assets.open(ZipUtils.PRIVATE_KEY_NAME);
InputStream certIn = assets.open(ZipUtils.PUBLIC_KEY_NAME)
) {
SignBoot.doSignature("/boot", in, out, keyIn, certIn);
}
shell.run_raw(false, "mv -f " + signed + " " + patched_boot);
}
mList.add("");
switch (mode) {
case PATCH_MODE:
@ -190,17 +220,13 @@ public class InstallMagisk extends ParallelTask<Void, Void, Boolean> {
shell.run_raw(false, "cp -f " + patched_boot + " " + dest);
break;
case ".img.tar":
TarOutputStream tar = new TarOutputStream(new BufferedOutputStream(new FileOutputStream(dest)));
tar.putNextEntry(new TarEntry(patched_boot, "boot.img"));
byte buffer[] = new byte[4096];
BufferedInputStream in = new BufferedInputStream(new FileInputStream(patched_boot));
int len;
while ((len = in.read(buffer)) != -1) {
tar.write(buffer, 0, len);
try (
TarOutputStream tar = new TarOutputStream(new BufferedOutputStream(new FileOutputStream(dest)));
InputStream in = new FileInputStream(patched_boot)
) {
tar.putNextEntry(new TarEntry(patched_boot, "boot.img"));
Utils.inToOut(in, tar);
}
tar.flush();
tar.close();
in.close();
break;
}
mList.add("*********************************");

View File

@ -54,8 +54,6 @@ public class ProcessRepoZip extends ParallelTask<Void, Object, Boolean> {
JarOutputStream dest = new JarOutputStream(new BufferedOutputStream(new FileOutputStream(output)));
JarEntry entry;
String path;
int size;
byte buffer[] = new byte[4096];
while ((entry = source.getNextJarEntry()) != null) {
// Remove the top directory from the path
path = entry.getName().substring(entry.getName().indexOf("/") + 1);
@ -68,9 +66,7 @@ public class ProcessRepoZip extends ParallelTask<Void, Object, Boolean> {
continue;
}
dest.putNextEntry(new JarEntry(path));
while((size = source.read(buffer)) != -1) {
dest.write(buffer, 0, size);
}
Utils.inToOut(source, dest);
}
source.close();
dest.close();

View File

@ -28,6 +28,9 @@ import com.topjohnwu.magisk.components.SnackbarMaker;
import com.topjohnwu.magisk.receivers.DownloadReceiver;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
@ -215,4 +218,13 @@ public class Utils {
return null;
}
}
public static void inToOut(InputStream in, OutputStream out) throws IOException {
int read;
byte buffer[] = new byte[4096];
while ((read = in.read(buffer)) > 0) {
out.write(buffer, 0, read);
}
out.flush();
}
}

View File

@ -16,8 +16,8 @@ import java.util.jar.JarInputStream;
public class ZipUtils {
// File name in assets
static final String PUBLIC_KEY_NAME = "public.certificate.x509.pem";
static final String PRIVATE_KEY_NAME = "private.key.pk8";
public static final String PUBLIC_KEY_NAME = "public.certificate.x509.pem";
public static final String PRIVATE_KEY_NAME = "private.key.pk8";
static {
System.loadLibrary("zipadjust");
@ -32,7 +32,6 @@ public class ZipUtils {
}
public static void unzip(InputStream zip, File folder, String path, boolean junkPath) throws Exception {
byte data[] = new byte[4096];
try {
JarInputStream zipfile = new JarInputStream(zip);
JarEntry entry;
@ -49,13 +48,9 @@ public class ZipUtils {
}
File dest = new File(folder, name);
dest.getParentFile().mkdirs();
FileOutputStream out = new FileOutputStream(dest);
int count;
while ((count = zipfile.read(data)) != -1) {
out.write(data, 0, count);
try (FileOutputStream out = new FileOutputStream(dest)) {
Utils.inToOut(zipfile, out);
}
out.flush();
out.close();
}
} catch(Exception e) {
e.printStackTrace();

View File

@ -15,8 +15,6 @@ import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import java.io.ByteArrayInputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;