Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in / Register
Toggle navigation
M
Magisk
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Administrator
Magisk
Commits
adf930f1
Commit
adf930f1
authored
Oct 30, 2017
by
topjohnwu
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Finalize bootsigner commandline
parent
05f41928
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
80 additions
and
71 deletions
+80
-71
BootSigner.java
app/src/main/java/com/topjohnwu/magisk/utils/BootSigner.java
+33
-23
SignBoot.java
crypto/src/main/java/com/topjohnwu/crypto/SignBoot.java
+47
-48
No files found.
app/src/main/java/com/topjohnwu/magisk/utils/BootSigner.java
View file @
adf930f1
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"
);
}
}
}
}
}
}
crypto/src/main/java/com/topjohnwu/crypto/SignBoot.java
View file @
adf930f1
...
@@ -36,57 +36,55 @@ public class SignBoot {
...
@@ -36,57 +36,55 @@ 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
);
ByteArrayStream
bas
=
new
ByteArrayStream
();
}
bas
.
readFrom
(
imgIn
);
byte
[]
image
=
bas
.
toByteArray
();
public
static
void
doSignature
(
String
target
,
InputStream
imgIn
,
OutputStream
imgOut
,
bas
.
close
();
InputStream
keyIn
,
InputStream
certIn
)
throws
Exception
{
int
signableSize
=
getSignableImageSize
(
image
);
ByteArrayStream
bas
=
new
ByteArrayStream
();
if
(
signableSize
<
image
.
length
)
{
bas
.
readFrom
(
imgIn
);
System
.
err
.
println
(
"NOTE: truncating input from "
+
byte
[]
image
=
bas
.
toByteArray
();
image
.
length
+
" to "
+
signableSize
+
" bytes"
);
bas
.
close
();
image
=
Arrays
.
copyOf
(
image
,
signableSize
);
imgIn
.
close
();
}
else
if
(
signableSize
>
image
.
length
)
{
int
signableSize
=
getSignableImageSize
(
image
);
throw
new
IllegalArgumentException
(
"Invalid image: too short, expected "
+
if
(
signableSize
<
image
.
length
)
{
signableSize
+
" bytes"
);
System
.
err
.
println
(
"NOTE: truncating input from "
+
}
image
.
length
+
" to "
+
signableSize
+
" bytes"
);
BootSignature
bootsig
=
new
BootSignature
(
target
,
image
.
length
);
image
=
Arrays
.
copyOf
(
image
,
signableSize
);
X509Certificate
cert
=
CryptoUtils
.
readPublicKey
(
certIn
);
}
else
if
(
signableSize
>
image
.
length
)
{
bootsig
.
setCertificate
(
cert
);
throw
new
IllegalArgumentException
(
"Invalid image: too short, expected "
+
PrivateKey
key
=
CryptoUtils
.
readPrivateKey
(
keyIn
);
signableSize
+
" bytes"
);
bootsig
.
setSignature
(
bootsig
.
sign
(
image
,
key
),
CryptoUtils
.
getSignatureAlgorithmIdentifier
(
key
));
byte
[]
encoded_bootsig
=
bootsig
.
getEncoded
();
imgOut
.
write
(
image
);
imgOut
.
write
(
encoded_bootsig
);
imgOut
.
flush
();
return
true
;
}
catch
(
Exception
e
)
{
e
.
printStackTrace
(
System
.
err
);
return
false
;
}
}
BootSignature
bootsig
=
new
BootSignature
(
target
,
image
.
length
);
X509Certificate
cert
=
CryptoUtils
.
readPublicKey
(
certIn
);
bootsig
.
setCertificate
(
cert
);
PrivateKey
key
=
CryptoUtils
.
readPrivateKey
(
keyIn
);
bootsig
.
setSignature
(
bootsig
.
sign
(
image
,
key
),
CryptoUtils
.
getSignatureAlgorithmIdentifier
(
key
));
byte
[]
encoded_bootsig
=
bootsig
.
getEncoded
();
imgOut
.
write
(
image
);
imgOut
.
write
(
encoded_bootsig
);
imgOut
.
flush
();
imgOut
.
close
();
}
}
public
static
boolean
verifySignature
(
String
imagePath
,
InputStream
certPath
)
throws
Exception
{
public
static
boolean
verifySignature
(
InputStream
imgIn
,
InputStream
certPath
)
{
ByteArrayStream
bas
=
new
ByteArrayStream
();
bas
.
readFrom
(
new
FileInputStream
(
imagePath
));
byte
[]
image
=
bas
.
toByteArray
();
bas
.
close
();
int
signableSize
=
getSignableImageSize
(
image
);
if
(
signableSize
>=
image
.
length
)
{
System
.
err
.
println
(
"Invalid image: not signed"
);
return
false
;
}
byte
[]
signature
=
Arrays
.
copyOfRange
(
image
,
signableSize
,
image
.
length
);
BootSignature
bootsig
=
new
BootSignature
(
signature
);
if
(
certPath
!=
null
)
{
bootsig
.
setCertificate
(
CryptoUtils
.
readPublicKey
(
certPath
));
}
try
{
try
{
ByteArrayStream
bas
=
new
ByteArrayStream
();
bas
.
readFrom
(
imgIn
);
byte
[]
image
=
bas
.
toByteArray
();
bas
.
close
();
int
signableSize
=
getSignableImageSize
(
image
);
if
(
signableSize
>=
image
.
length
)
{
System
.
err
.
println
(
"Invalid image: not signed"
);
return
false
;
}
byte
[]
signature
=
Arrays
.
copyOfRange
(
image
,
signableSize
,
image
.
length
);
BootSignature
bootsig
=
new
BootSignature
(
signature
);
if
(
certPath
!=
null
)
{
bootsig
.
setCertificate
(
CryptoUtils
.
readPublicKey
(
certPath
));
}
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 {
...
@@ -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
;
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment