Commit fdd700f3 authored by topjohnwu's avatar topjohnwu

Update boot signing in InstallMagisk

parent adf930f1
......@@ -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();
......
......@@ -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;
......
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);
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;
}
Shell shell;
if (mode == PATCH_MODE && Shell.rootAccess()) {
// Force non-root shell
Shell shell;
if (Shell.rootAccess())
shell = new Shell("sh");
} else {
else
shell = Shell.getShell();
}
if (shell == null)
return false;
// 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":
try (
TarOutputStream tar = new TarOutputStream(new BufferedOutputStream(new FileOutputStream(dest)));
InputStream in = new FileInputStream(patched_boot)
) {
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);
}
tar.flush();
tar.close();
in.close();
Utils.inToOut(in, tar);
}
break;
}
mList.add("*********************************");
......
......@@ -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();
......
......@@ -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();
}
}
\ No newline at end of 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();
......
......@@ -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;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment