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
32809e56
Commit
32809e56
authored
Aug 04, 2018
by
topjohnwu
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Sign release zips with release-key.jks
Close #408
parent
9f05b182
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
92 additions
and
128 deletions
+92
-128
PatchAPK.java
app/src/full/java/com/topjohnwu/magisk/asyncs/PatchAPK.java
+2
-2
ManagerUpdate.java
...ll/java/com/topjohnwu/magisk/receivers/ManagerUpdate.java
+2
-2
ZipUtils.java
app/src/full/java/com/topjohnwu/magisk/utils/ZipUtils.java
+1
-5
build.py
build.py
+26
-24
config.prop.sample
config.prop.sample
+2
-1
build.gradle
utils/build.gradle
+1
-1
ReusableInputStream.java
...rc/main/java/com/topjohnwu/utils/ReusableInputStream.java
+0
-28
SignAPK.java
utils/src/main/java/com/topjohnwu/utils/SignAPK.java
+35
-33
ZipSigner.java
utils/src/main/java/com/topjohnwu/utils/ZipSigner.java
+23
-32
No files found.
app/src/full/java/com/topjohnwu/magisk/asyncs/PatchAPK.java
View file @
32809e56
...
...
@@ -11,11 +11,11 @@ import com.topjohnwu.magisk.MagiskManager;
import
com.topjohnwu.magisk.R
;
import
com.topjohnwu.magisk.utils.RootUtils
;
import
com.topjohnwu.magisk.utils.Utils
;
import
com.topjohnwu.magisk.utils.ZipUtils
;
import
com.topjohnwu.superuser.ShellUtils
;
import
com.topjohnwu.superuser.io.SuFile
;
import
com.topjohnwu.superuser.io.SuFileOutputStream
;
import
com.topjohnwu.utils.JarMap
;
import
com.topjohnwu.utils.SignAPK
;
import
java.security.SecureRandom
;
import
java.util.jar.JarEntry
;
...
...
@@ -99,7 +99,7 @@ public class PatchAPK {
JarMap
apk
=
new
JarMap
(
mm
.
getPackageCodePath
());
if
(!
patchPackageID
(
apk
,
Const
.
ORIG_PKG_NAME
,
pkg
))
return
false
;
ZipUtils
.
signZip
(
apk
,
new
SuFileOutputStream
(
repack
));
SignAPK
.
sign
(
apk
,
new
SuFileOutputStream
(
repack
));
}
catch
(
Exception
e
)
{
return
false
;
}
...
...
app/src/full/java/com/topjohnwu/magisk/receivers/ManagerUpdate.java
View file @
32809e56
...
...
@@ -9,8 +9,8 @@ import android.os.AsyncTask;
import
com.topjohnwu.magisk.Const
;
import
com.topjohnwu.magisk.asyncs.PatchAPK
;
import
com.topjohnwu.magisk.utils.Download
;
import
com.topjohnwu.magisk.utils.ZipUtils
;
import
com.topjohnwu.utils.JarMap
;
import
com.topjohnwu.utils.SignAPK
;
import
java.io.BufferedOutputStream
;
import
java.io.File
;
...
...
@@ -37,7 +37,7 @@ public class ManagerUpdate extends BroadcastReceiver {
try
{
JarMap
apk
=
new
JarMap
(
orig
);
PatchAPK
.
patchPackageID
(
apk
,
Const
.
ORIG_PKG_NAME
,
context
.
getPackageName
());
ZipUtils
.
signZip
(
apk
,
new
BufferedOutputStream
(
new
FileOutputStream
(
patch
)));
SignAPK
.
sign
(
apk
,
new
BufferedOutputStream
(
new
FileOutputStream
(
patch
)));
super
.
onDownloadDone
(
context
,
Uri
.
fromFile
(
new
File
(
patch
)));
}
catch
(
Exception
ignored
)
{
}
});
...
...
app/src/full/java/com/topjohnwu/magisk/utils/ZipUtils.java
View file @
32809e56
...
...
@@ -59,11 +59,7 @@ public class ZipUtils {
public
static
void
signZip
(
File
input
,
File
output
)
throws
Exception
{
try
(
JarMap
map
=
new
JarMap
(
input
,
false
);
BufferedOutputStream
out
=
new
BufferedOutputStream
(
new
FileOutputStream
(
output
)))
{
signZip
(
map
,
out
);
SignAPK
.
sign
(
map
,
out
);
}
}
public
static
void
signZip
(
JarMap
input
,
OutputStream
output
)
throws
Exception
{
SignAPK
.
signZip
(
null
,
null
,
input
,
output
);
}
}
build.py
View file @
32809e56
...
...
@@ -164,6 +164,27 @@ def build_binary(args):
error
(
'Build binaries failed!'
)
collect_binary
()
def
sign_zip
(
unsigned
,
output
,
release
):
signer_name
=
'zipsigner-3.0.jar'
jarsigner
=
os
.
path
.
join
(
'utils'
,
'build'
,
'libs'
,
signer_name
)
if
not
os
.
path
.
exists
(
jarsigner
):
header
(
'* Building '
+
signer_name
)
proc
=
subprocess
.
run
(
'{} utils:shadowJar'
.
format
(
gradlew
),
shell
=
True
,
stdout
=
STDOUT
)
if
proc
.
returncode
!=
0
:
error
(
'Build {} failed!'
.
format
(
signer_name
))
header
(
'* Signing Zip'
)
if
release
:
proc
=
subprocess
.
run
([
'java'
,
'-jar'
,
jarsigner
,
'release-key.jks'
,
config
[
'keyStorePass'
],
config
[
'keyAlias'
],
config
[
'keyPass'
],
unsigned
,
output
])
else
:
proc
=
subprocess
.
run
([
'java'
,
'-jar'
,
jarsigner
,
unsigned
,
output
])
if
proc
.
returncode
!=
0
:
error
(
'Signing zip failed!'
)
def
sign_apk
(
source
,
target
):
# Find the latest build tools
build_tool
=
os
.
path
.
join
(
os
.
environ
[
'ANDROID_HOME'
],
'build-tools'
,
...
...
@@ -195,9 +216,6 @@ def build_apk(args):
cp
(
source
,
target
)
if
args
.
release
:
if
not
os
.
path
.
exists
(
'release-key.jks'
):
error
(
'Please generate a java keystore and place it in
\'
release-key.jks
\'
'
)
proc
=
subprocess
.
run
(
'{} app:assembleRelease'
.
format
(
gradlew
),
shell
=
True
,
stdout
=
STDOUT
)
if
proc
.
returncode
!=
0
:
error
(
'Build Magisk Manager failed!'
)
...
...
@@ -337,7 +355,7 @@ def zip_main(args):
output
=
os
.
path
.
join
(
config
[
'outdir'
],
'Magisk-v{}.zip'
.
format
(
config
[
'version'
])
if
config
[
'prettyName'
]
else
'magisk-release.zip'
if
args
.
release
else
'magisk-debug.zip'
)
sign_
adjust_zip
(
unsigned
,
output
)
sign_
zip
(
unsigned
,
output
,
args
.
release
)
header
(
'Output: '
+
output
)
def
zip_uninstaller
(
args
):
...
...
@@ -381,27 +399,9 @@ def zip_uninstaller(args):
output
=
os
.
path
.
join
(
config
[
'outdir'
],
'Magisk-uninstaller-{}.zip'
.
format
(
datetime
.
datetime
.
now
()
.
strftime
(
'
%
Y
%
m
%
d'
))
if
config
[
'prettyName'
]
else
'magisk-uninstaller.zip'
)
sign_
adjust_zip
(
unsigned
,
output
)
sign_
zip
(
unsigned
,
output
,
args
.
release
)
header
(
'Output: '
+
output
)
def
sign_adjust_zip
(
unsigned
,
output
):
signer_name
=
'zipsigner-2.2.jar'
jarsigner
=
os
.
path
.
join
(
'utils'
,
'build'
,
'libs'
,
signer_name
)
if
not
os
.
path
.
exists
(
jarsigner
):
header
(
'* Building '
+
signer_name
)
proc
=
subprocess
.
run
(
'{} utils:shadowJar'
.
format
(
gradlew
),
shell
=
True
,
stdout
=
STDOUT
)
if
proc
.
returncode
!=
0
:
error
(
'Build {} failed!'
.
format
(
signer_name
))
header
(
'* Signing Zip'
)
signed
=
tempfile
.
mkstemp
()[
1
]
proc
=
subprocess
.
run
([
'java'
,
'-jar'
,
jarsigner
,
unsigned
,
output
])
if
proc
.
returncode
!=
0
:
error
(
'Signing zip failed!'
)
def
cleanup
(
args
):
if
len
(
args
.
target
)
==
0
:
args
.
target
=
[
'native'
,
'java'
]
...
...
@@ -463,7 +463,7 @@ apk_parser.set_defaults(func=build_apk)
snet_parser
=
subparsers
.
add_parser
(
'snet'
,
help
=
'build snet extention for Magisk Manager'
)
snet_parser
.
set_defaults
(
func
=
build_snet
)
zip_parser
=
subparsers
.
add_parser
(
'zip'
,
help
=
'zip
and sign
Magisk into a flashable zip'
)
zip_parser
=
subparsers
.
add_parser
(
'zip'
,
help
=
'zip Magisk into a flashable zip'
)
zip_parser
.
set_defaults
(
func
=
zip_main
)
uninstaller_parser
=
subparsers
.
add_parser
(
'uninstaller'
,
help
=
'create flashable uninstaller'
)
...
...
@@ -478,5 +478,7 @@ if len(sys.argv) == 1:
sys
.
exit
(
1
)
args
=
parser
.
parse_args
()
if
args
.
release
and
not
os
.
path
.
exists
(
'release-key.jks'
):
error
(
'Please generate a java keystore and place it in
\'
release-key.jks
\'
'
)
STDOUT
=
None
if
args
.
verbose
else
subprocess
.
DEVNULL
args
.
func
(
args
)
config.prop.sample
View file @
32809e56
...
...
@@ -8,7 +8,8 @@ outdir=out
# The default output names are magisk-${release/debug/uninstaller}.zip
prettyName=false
# These pwds are passed to apksigner for release-key.jks. Necessary when building release apks
# Only used when building with release flag
# These passwords are used along with release-key.jks to sign APKs and zips
# keyPass is the pwd for the specified keyAlias
keyStorePass=
keyAlias=
...
...
utils/build.gradle
View file @
32809e56
...
...
@@ -15,7 +15,7 @@ jar {
shadowJar
{
baseName
=
'zipsigner'
classifier
=
null
version
=
2.2
version
=
3.0
}
buildscript
{
...
...
utils/src/main/java/com/topjohnwu/utils/ReusableInputStream.java
deleted
100644 → 0
View file @
9f05b182
package
com
.
topjohnwu
.
utils
;
import
java.io.BufferedInputStream
;
import
java.io.IOException
;
import
java.io.InputStream
;
public
class
ReusableInputStream
extends
BufferedInputStream
{
public
ReusableInputStream
(
InputStream
in
)
{
super
(
in
);
mark
(
Integer
.
MAX_VALUE
);
}
public
ReusableInputStream
(
InputStream
in
,
int
size
)
{
super
(
in
,
size
);
mark
(
Integer
.
MAX_VALUE
);
}
@Override
public
void
close
()
throws
IOException
{
/* Reset at close so we can reuse it */
reset
();
}
public
void
destroy
()
throws
IOException
{
super
.
close
();
}
}
utils/src/main/java/com/topjohnwu/utils/SignAPK.java
View file @
32809e56
...
...
@@ -18,7 +18,6 @@ import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
import
org.bouncycastle.operator.jcajce.JcaDigestCalculatorProviderBuilder
;
import
org.bouncycastle.util.encoders.Base64
;
import
java.io.BufferedInputStream
;
import
java.io.BufferedOutputStream
;
import
java.io.ByteArrayOutputStream
;
import
java.io.File
;
...
...
@@ -32,6 +31,7 @@ import java.io.PrintStream;
import
java.io.RandomAccessFile
;
import
java.security.DigestOutputStream
;
import
java.security.GeneralSecurityException
;
import
java.security.KeyStore
;
import
java.security.MessageDigest
;
import
java.security.PrivateKey
;
import
java.security.Provider
;
...
...
@@ -60,7 +60,7 @@ public class SignAPK {
private
static
final
String
CERT_SF_NAME
=
"META-INF/CERT.SF"
;
private
static
final
String
CERT_SIG_NAME
=
"META-INF/CERT.%s"
;
p
ublic
static
Provider
sBouncyCastleProvider
;
p
rivate
static
Provider
sBouncyCastleProvider
;
// bitmasks for which hash algorithms we need the manifest to include.
private
static
final
int
USE_SHA1
=
1
;
private
static
final
int
USE_SHA256
=
2
;
...
...
@@ -70,59 +70,61 @@ public class SignAPK {
Security
.
insertProviderAt
(
sBouncyCastleProvider
,
1
);
}
public
static
void
signZip
(
InputStream
cert
,
InputStream
key
,
JarMap
input
,
OutputStream
output
)
throws
Exception
{
public
static
void
sign
(
JarMap
input
,
OutputStream
output
)
throws
Exception
{
sign
(
SignAPK
.
class
.
getResourceAsStream
(
"/keys/testkey.x509.pem"
),
SignAPK
.
class
.
getResourceAsStream
(
"/keys/testkey.pk8"
),
input
,
output
);
}
public
static
void
sign
(
InputStream
certIs
,
InputStream
keyIs
,
JarMap
input
,
OutputStream
output
)
throws
Exception
{
X509Certificate
cert
=
CryptoUtils
.
readCertificate
(
certIs
);
PrivateKey
key
=
CryptoUtils
.
readPrivateKey
(
keyIs
);
sign
(
cert
,
key
,
input
,
output
);
}
public
static
void
sign
(
InputStream
jks
,
String
keyStorePass
,
String
alias
,
String
keyPass
,
JarMap
input
,
OutputStream
output
)
throws
Exception
{
KeyStore
ks
=
KeyStore
.
getInstance
(
"JKS"
);
ks
.
load
(
jks
,
keyStorePass
.
toCharArray
());
KeyStore
.
ProtectionParameter
prot
=
new
KeyStore
.
PasswordProtection
(
keyPass
.
toCharArray
());
X509Certificate
cert
=
(
X509Certificate
)
ks
.
getCertificate
(
alias
);
PrivateKey
key
=
((
KeyStore
.
PrivateKeyEntry
)
ks
.
getEntry
(
alias
,
prot
)).
getPrivateKey
();
sign
(
cert
,
key
,
input
,
output
);
}
private
static
void
sign
(
X509Certificate
cert
,
PrivateKey
key
,
JarMap
input
,
OutputStream
output
)
throws
Exception
{
File
temp1
=
File
.
createTempFile
(
"signAPK"
,
null
);
File
temp2
=
File
.
createTempFile
(
"signAPK"
,
null
);
if
(
cert
==
null
)
{
cert
=
SignAPK
.
class
.
getResourceAsStream
(
"/keys/testkey.x509.pem"
);
}
if
(
key
==
null
)
{
key
=
SignAPK
.
class
.
getResourceAsStream
(
"/keys/testkey.pk8"
);
}
ReusableInputStream
c
=
new
ReusableInputStream
(
cert
);
ReusableInputStream
k
=
new
ReusableInputStream
(
key
);
try
{
try
(
OutputStream
out
=
new
BufferedOutputStream
(
new
FileOutputStream
(
temp1
)))
{
sign
Zip
(
c
,
k
,
input
,
out
,
false
);
sign
(
cert
,
key
,
input
,
out
,
false
);
}
ZipAdjust
.
adjust
(
temp1
,
temp2
);
try
(
JarMap
map
=
new
JarMap
(
temp2
,
false
))
{
sign
Zip
(
c
,
k
,
map
,
output
,
true
);
sign
(
cert
,
key
,
map
,
output
,
true
);
}
}
finally
{
temp1
.
delete
();
temp2
.
delete
();
c
.
destroy
();
k
.
destroy
();
}
}
public
static
void
signZip
(
InputStream
cert
,
InputStream
key
,
JarMap
input
,
OutputStream
output
,
boolean
minSign
)
throws
Exception
{
int
alignment
=
4
;
private
static
void
sign
(
X509Certificate
cert
,
PrivateKey
key
,
JarMap
input
,
OutputStream
output
,
boolean
minSign
)
throws
Exception
{
int
hashes
=
0
;
if
(
cert
==
null
)
{
cert
=
SignAPK
.
class
.
getResourceAsStream
(
"/keys/testkey.x509.pem"
);
}
X509Certificate
certificate
=
CryptoUtils
.
readCertificate
(
cert
);
hashes
|=
getDigestAlgorithm
(
certificate
);
hashes
|=
getDigestAlgorithm
(
cert
);
// Set the ZIP file timestamp to the starting valid time
// of the 0th certificate plus one hour (to match what
// we've historically done).
long
timestamp
=
certificate
.
getNotBefore
().
getTime
()
+
3600L
*
1000
;
if
(
key
==
null
)
{
key
=
SignAPK
.
class
.
getResourceAsStream
(
"/keys/testkey.pk8"
);
}
PrivateKey
privateKey
=
CryptoUtils
.
readPrivateKey
(
key
);
long
timestamp
=
cert
.
getNotBefore
().
getTime
()
+
3600L
*
1000
;
if
(
minSign
)
{
signWholeFile
(
input
.
getFile
(),
cert
ificate
,
privateK
ey
,
output
);
signWholeFile
(
input
.
getFile
(),
cert
,
k
ey
,
output
);
}
else
{
JarOutputStream
outputJar
=
new
JarOutputStream
(
output
);
// For signing .apks, use the maximum compression to make
...
...
@@ -133,8 +135,8 @@ public class SignAPK {
// (~0.1% on full OTA packages I tested).
outputJar
.
setLevel
(
9
);
Manifest
manifest
=
addDigestsToManifest
(
input
,
hashes
);
copyFiles
(
manifest
,
input
,
outputJar
,
timestamp
,
alignment
);
signFile
(
manifest
,
input
,
cert
ificate
,
privateK
ey
,
outputJar
);
copyFiles
(
manifest
,
input
,
outputJar
,
timestamp
,
4
);
signFile
(
manifest
,
input
,
cert
,
k
ey
,
outputJar
);
outputJar
.
close
();
}
}
...
...
utils/src/main/java/com/topjohnwu/utils/ZipSigner.java
View file @
32809e56
package
com
.
topjohnwu
.
utils
;
import
org.bouncycastle.jce.provider.BouncyCastleProvider
;
import
java.io.BufferedInputStream
;
import
java.io.BufferedOutputStream
;
import
java.io.File
;
import
java.io.FileInputStream
;
import
java.io.FileOutputStream
;
import
java.io.InputStream
;
import
java.
security.Security
;
import
java.
io.OutputStream
;
public
class
ZipSigner
{
public
static
void
usage
()
{
System
.
err
.
println
(
"Usage: zipsigner [x509.pem] [pk8] input.jar output.jar"
);
System
.
err
.
println
(
"Note: If no certificate/private key pair is specified, it will use the embedded test keys."
);
System
.
err
.
println
(
"ZipSigner usage:"
);
System
.
err
.
println
(
" zipsigner.jar input.jar output.jar"
);
System
.
err
.
println
(
" sign jar with AOSP test keys"
);
System
.
err
.
println
(
" zipsigner.jar x509.pem pk8 input.jar output.jar"
);
System
.
err
.
println
(
" sign jar with certificate / private key pair"
);
System
.
err
.
println
(
" zipsigner.jar jks keyStorePass keyAlias keyPass input.jar output.jar"
);
System
.
err
.
println
(
" sign jar with Java KeyStore"
);
System
.
exit
(
2
);
}
public
static
void
main
(
String
[]
args
)
throws
Exception
{
int
argStart
=
0
;
if
(
args
.
length
<
2
)
if
(
args
.
length
!=
2
&&
args
.
length
!=
4
&&
args
.
length
!=
6
)
usage
();
InputStream
cert
=
null
;
InputStream
key
=
null
;
if
(
args
.
length
-
argStart
==
4
)
{
cert
=
new
FileInputStream
(
new
File
(
args
[
argStart
]));
key
=
new
FileInputStream
(
new
File
(
args
[
argStart
+
1
]));
argStart
+=
2
;
}
if
(
args
.
length
-
argStart
!=
2
)
usage
();
SignAPK
.
sBouncyCastleProvider
=
new
BouncyCastleProvider
();
Security
.
insertProviderAt
(
SignAPK
.
sBouncyCastleProvider
,
1
);
File
input
=
new
File
(
args
[
argStart
]);
File
output
=
new
File
(
args
[
argStart
+
1
]);
try
(
JarMap
jar
=
new
JarMap
(
input
,
false
);
BufferedOutputStream
out
=
new
BufferedOutputStream
(
new
FileOutputStream
(
output
)))
{
SignAPK
.
signZip
(
cert
,
key
,
jar
,
out
);
try
(
JarMap
in
=
new
JarMap
(
args
[
args
.
length
-
2
],
false
);
OutputStream
out
=
new
FileOutputStream
(
args
[
args
.
length
-
1
]))
{
if
(
args
.
length
==
2
)
{
SignAPK
.
sign
(
in
,
out
);
}
else
if
(
args
.
length
==
4
)
{
try
(
InputStream
cert
=
new
FileInputStream
(
args
[
0
]);
InputStream
key
=
new
FileInputStream
(
args
[
1
]))
{
SignAPK
.
sign
(
cert
,
key
,
in
,
out
);
}
}
else
if
(
args
.
length
==
6
)
{
try
(
InputStream
jks
=
new
FileInputStream
(
args
[
0
]))
{
SignAPK
.
sign
(
jks
,
args
[
1
],
args
[
2
],
args
[
3
],
in
,
out
);
}
}
}
}
}
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