Finalize bootsigner commandline
This commit is contained in:
parent
05f41928cd
commit
adf930f126
@ -1,46 +1,56 @@
|
|||||||
package com.topjohnwu.magisk.utils;
|
package com.topjohnwu.magisk.utils;
|
||||||
|
|
||||||
import android.content.res.AssetManager;
|
import android.support.annotation.Keep;
|
||||||
|
|
||||||
import com.topjohnwu.crypto.SignBoot;
|
import com.topjohnwu.crypto.SignBoot;
|
||||||
|
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
import java.util.jar.JarEntry;
|
||||||
|
import java.util.jar.JarFile;
|
||||||
|
|
||||||
public class BootSigner {
|
public class BootSigner {
|
||||||
|
|
||||||
|
@Keep
|
||||||
public static void main(String[] args) throws Exception {
|
public static void main(String[] args) throws Exception {
|
||||||
if ("-verify".equals(args[0])) {
|
if (args.length > 0 && "-verify".equals(args[0])) {
|
||||||
String certPath = "";
|
String certPath = "";
|
||||||
if (args.length >= 4 && "-certificate".equals(args[2])) {
|
if (args.length >= 3 && "-certificate".equals(args[1])) {
|
||||||
/* args[3] is the path to a public key certificate */
|
/* args[2] is the path to a public key certificate */
|
||||||
certPath = args[3];
|
certPath = args[2];
|
||||||
}
|
}
|
||||||
/* args[1] is the path to a signed boot image */
|
/* args[1] is the path to a signed boot image */
|
||||||
boolean signed = SignBoot.verifySignature(args[1],
|
boolean signed = SignBoot.verifySignature(System.in,
|
||||||
certPath.isEmpty() ? null : new FileInputStream(certPath));
|
certPath.isEmpty() ? null : new FileInputStream(certPath));
|
||||||
System.exit(signed ? 0 : 1);
|
System.exit(signed ? 0 : 1);
|
||||||
} else {
|
} else if (args.length > 0 && "-sign".equals(args[0])) {
|
||||||
/* args[0] is the target name, typically /boot
|
InputStream keyIn, certIn;
|
||||||
args[1] is the path to a boot image to sign
|
if (args.length >= 3) {
|
||||||
args[2] is the path where to output the signed boot image
|
keyIn = new FileInputStream(args[1]);
|
||||||
args[3] is the path to a private key
|
certIn = new FileInputStream(args[2]);
|
||||||
args[4] is the path to the matching public key certificate
|
|
||||||
*/
|
|
||||||
InputStream keyIn, sigIn;
|
|
||||||
if (args.length >= 5) {
|
|
||||||
keyIn = new FileInputStream(args[3]);
|
|
||||||
sigIn = new FileInputStream(args[4]);
|
|
||||||
} else {
|
} else {
|
||||||
/* Use internal test keys */
|
/* Use internal test keys */
|
||||||
AssetManager asset = Utils.getAssets(System.getProperty("java.class.path"));
|
JarFile apk = new JarFile(System.getProperty("java.class.path"));
|
||||||
if (asset == null)
|
JarEntry keyEntry = apk.getJarEntry("assets/" + ZipUtils.PRIVATE_KEY_NAME);
|
||||||
System.exit(1);
|
JarEntry sigEntry = apk.getJarEntry("assets/" + ZipUtils.PUBLIC_KEY_NAME);
|
||||||
keyIn = asset.open(ZipUtils.PRIVATE_KEY_NAME);
|
|
||||||
sigIn = asset.open(ZipUtils.PUBLIC_KEY_NAME);
|
keyIn = apk.getInputStream(keyEntry);
|
||||||
|
certIn = apk.getInputStream(sigEntry);
|
||||||
}
|
}
|
||||||
|
|
||||||
SignBoot.doSignature(args[0], args[1], args[2], keyIn, sigIn);
|
boolean success = SignBoot.doSignature("/boot", System.in, System.out, keyIn, certIn);
|
||||||
|
System.exit(success ? 0 : 1);
|
||||||
|
} else {
|
||||||
|
System.err.println(
|
||||||
|
"BootSigner <actions> [args]\n" +
|
||||||
|
"Input from stdin, outputs to stdout\n" +
|
||||||
|
"\n" +
|
||||||
|
"Actions:\n" +
|
||||||
|
" -verify [x509.pem]\n" +
|
||||||
|
" verify image, cert is optional\n" +
|
||||||
|
" -sign [pk8] [x509.pem]\n" +
|
||||||
|
" sign image, key and cert are optional\n"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -36,19 +36,13 @@ public class SignBoot {
|
|||||||
Security.addProvider(new BouncyCastleProvider());
|
Security.addProvider(new BouncyCastleProvider());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void doSignature(String target, String imagePath, String outPath,
|
public static boolean doSignature(String target, InputStream imgIn, OutputStream imgOut,
|
||||||
InputStream keyIn, InputStream certIn) throws Exception {
|
InputStream keyIn, InputStream certIn) {
|
||||||
doSignature(target, new FileInputStream(imagePath),
|
try {
|
||||||
new FileOutputStream(outPath), keyIn, certIn);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void doSignature(String target, InputStream imgIn, OutputStream imgOut,
|
|
||||||
InputStream keyIn, InputStream certIn) throws Exception {
|
|
||||||
ByteArrayStream bas = new ByteArrayStream();
|
ByteArrayStream bas = new ByteArrayStream();
|
||||||
bas.readFrom(imgIn);
|
bas.readFrom(imgIn);
|
||||||
byte[] image = bas.toByteArray();
|
byte[] image = bas.toByteArray();
|
||||||
bas.close();
|
bas.close();
|
||||||
imgIn.close();
|
|
||||||
int signableSize = getSignableImageSize(image);
|
int signableSize = getSignableImageSize(image);
|
||||||
if (signableSize < image.length) {
|
if (signableSize < image.length) {
|
||||||
System.err.println("NOTE: truncating input from " +
|
System.err.println("NOTE: truncating input from " +
|
||||||
@ -68,12 +62,17 @@ public class SignBoot {
|
|||||||
imgOut.write(image);
|
imgOut.write(image);
|
||||||
imgOut.write(encoded_bootsig);
|
imgOut.write(encoded_bootsig);
|
||||||
imgOut.flush();
|
imgOut.flush();
|
||||||
imgOut.close();
|
return true;
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace(System.err);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean verifySignature(String imagePath, InputStream certPath) throws Exception {
|
public static boolean verifySignature(InputStream imgIn, InputStream certPath) {
|
||||||
|
try {
|
||||||
ByteArrayStream bas = new ByteArrayStream();
|
ByteArrayStream bas = new ByteArrayStream();
|
||||||
bas.readFrom(new FileInputStream(imagePath));
|
bas.readFrom(imgIn);
|
||||||
byte[] image = bas.toByteArray();
|
byte[] image = bas.toByteArray();
|
||||||
bas.close();
|
bas.close();
|
||||||
int signableSize = getSignableImageSize(image);
|
int signableSize = getSignableImageSize(image);
|
||||||
@ -86,7 +85,6 @@ public class SignBoot {
|
|||||||
if (certPath != null) {
|
if (certPath != null) {
|
||||||
bootsig.setCertificate(CryptoUtils.readPublicKey(certPath));
|
bootsig.setCertificate(CryptoUtils.readPublicKey(certPath));
|
||||||
}
|
}
|
||||||
try {
|
|
||||||
if (bootsig.verify(Arrays.copyOf(image, signableSize))) {
|
if (bootsig.verify(Arrays.copyOf(image, signableSize))) {
|
||||||
System.err.println("Signature is VALID");
|
System.err.println("Signature is VALID");
|
||||||
return true;
|
return true;
|
||||||
@ -94,7 +92,8 @@ public class SignBoot {
|
|||||||
System.err.println("Signature is INVALID");
|
System.err.println("Signature is INVALID");
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace(System.err);
|
||||||
|
System.err.println("Invalid image: not signed");
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user