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;
...
@@ -11,11 +11,11 @@ import com.topjohnwu.magisk.MagiskManager;
import
com.topjohnwu.magisk.R
;
import
com.topjohnwu.magisk.R
;
import
com.topjohnwu.magisk.utils.RootUtils
;
import
com.topjohnwu.magisk.utils.RootUtils
;
import
com.topjohnwu.magisk.utils.Utils
;
import
com.topjohnwu.magisk.utils.Utils
;
import
com.topjohnwu.magisk.utils.ZipUtils
;
import
com.topjohnwu.superuser.ShellUtils
;
import
com.topjohnwu.superuser.ShellUtils
;
import
com.topjohnwu.superuser.io.SuFile
;
import
com.topjohnwu.superuser.io.SuFile
;
import
com.topjohnwu.superuser.io.SuFileOutputStream
;
import
com.topjohnwu.superuser.io.SuFileOutputStream
;
import
com.topjohnwu.utils.JarMap
;
import
com.topjohnwu.utils.JarMap
;
import
com.topjohnwu.utils.SignAPK
;
import
java.security.SecureRandom
;
import
java.security.SecureRandom
;
import
java.util.jar.JarEntry
;
import
java.util.jar.JarEntry
;
...
@@ -99,7 +99,7 @@ public class PatchAPK {
...
@@ -99,7 +99,7 @@ public class PatchAPK {
JarMap
apk
=
new
JarMap
(
mm
.
getPackageCodePath
());
JarMap
apk
=
new
JarMap
(
mm
.
getPackageCodePath
());
if
(!
patchPackageID
(
apk
,
Const
.
ORIG_PKG_NAME
,
pkg
))
if
(!
patchPackageID
(
apk
,
Const
.
ORIG_PKG_NAME
,
pkg
))
return
false
;
return
false
;
ZipUtils
.
signZip
(
apk
,
new
SuFileOutputStream
(
repack
));
SignAPK
.
sign
(
apk
,
new
SuFileOutputStream
(
repack
));
}
catch
(
Exception
e
)
{
}
catch
(
Exception
e
)
{
return
false
;
return
false
;
}
}
...
...
app/src/full/java/com/topjohnwu/magisk/receivers/ManagerUpdate.java
View file @
32809e56
...
@@ -9,8 +9,8 @@ import android.os.AsyncTask;
...
@@ -9,8 +9,8 @@ import android.os.AsyncTask;
import
com.topjohnwu.magisk.Const
;
import
com.topjohnwu.magisk.Const
;
import
com.topjohnwu.magisk.asyncs.PatchAPK
;
import
com.topjohnwu.magisk.asyncs.PatchAPK
;
import
com.topjohnwu.magisk.utils.Download
;
import
com.topjohnwu.magisk.utils.Download
;
import
com.topjohnwu.magisk.utils.ZipUtils
;
import
com.topjohnwu.utils.JarMap
;
import
com.topjohnwu.utils.JarMap
;
import
com.topjohnwu.utils.SignAPK
;
import
java.io.BufferedOutputStream
;
import
java.io.BufferedOutputStream
;
import
java.io.File
;
import
java.io.File
;
...
@@ -37,7 +37,7 @@ public class ManagerUpdate extends BroadcastReceiver {
...
@@ -37,7 +37,7 @@ public class ManagerUpdate extends BroadcastReceiver {
try
{
try
{
JarMap
apk
=
new
JarMap
(
orig
);
JarMap
apk
=
new
JarMap
(
orig
);
PatchAPK
.
patchPackageID
(
apk
,
Const
.
ORIG_PKG_NAME
,
context
.
getPackageName
());
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
)));
super
.
onDownloadDone
(
context
,
Uri
.
fromFile
(
new
File
(
patch
)));
}
catch
(
Exception
ignored
)
{
}
}
catch
(
Exception
ignored
)
{
}
});
});
...
...
app/src/full/java/com/topjohnwu/magisk/utils/ZipUtils.java
View file @
32809e56
...
@@ -59,11 +59,7 @@ public class ZipUtils {
...
@@ -59,11 +59,7 @@ public class ZipUtils {
public
static
void
signZip
(
File
input
,
File
output
)
throws
Exception
{
public
static
void
signZip
(
File
input
,
File
output
)
throws
Exception
{
try
(
JarMap
map
=
new
JarMap
(
input
,
false
);
try
(
JarMap
map
=
new
JarMap
(
input
,
false
);
BufferedOutputStream
out
=
new
BufferedOutputStream
(
new
FileOutputStream
(
output
)))
{
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):
...
@@ -164,6 +164,27 @@ def build_binary(args):
error
(
'Build binaries failed!'
)
error
(
'Build binaries failed!'
)
collect_binary
()
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
):
def
sign_apk
(
source
,
target
):
# Find the latest build tools
# Find the latest build tools
build_tool
=
os
.
path
.
join
(
os
.
environ
[
'ANDROID_HOME'
],
'build-tools'
,
build_tool
=
os
.
path
.
join
(
os
.
environ
[
'ANDROID_HOME'
],
'build-tools'
,
...
@@ -195,9 +216,6 @@ def build_apk(args):
...
@@ -195,9 +216,6 @@ def build_apk(args):
cp
(
source
,
target
)
cp
(
source
,
target
)
if
args
.
release
:
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
)
proc
=
subprocess
.
run
(
'{} app:assembleRelease'
.
format
(
gradlew
),
shell
=
True
,
stdout
=
STDOUT
)
if
proc
.
returncode
!=
0
:
if
proc
.
returncode
!=
0
:
error
(
'Build Magisk Manager failed!'
)
error
(
'Build Magisk Manager failed!'
)
...
@@ -337,7 +355,7 @@ def zip_main(args):
...
@@ -337,7 +355,7 @@ def zip_main(args):
output
=
os
.
path
.
join
(
config
[
'outdir'
],
'Magisk-v{}.zip'
.
format
(
config
[
'version'
])
if
config
[
'prettyName'
]
else
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'
)
'magisk-release.zip'
if
args
.
release
else
'magisk-debug.zip'
)
sign_
adjust_zip
(
unsigned
,
output
)
sign_
zip
(
unsigned
,
output
,
args
.
release
)
header
(
'Output: '
+
output
)
header
(
'Output: '
+
output
)
def
zip_uninstaller
(
args
):
def
zip_uninstaller
(
args
):
...
@@ -381,27 +399,9 @@ 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'
))
output
=
os
.
path
.
join
(
config
[
'outdir'
],
'Magisk-uninstaller-{}.zip'
.
format
(
datetime
.
datetime
.
now
()
.
strftime
(
'
%
Y
%
m
%
d'
))
if
config
[
'prettyName'
]
else
'magisk-uninstaller.zip'
)
if
config
[
'prettyName'
]
else
'magisk-uninstaller.zip'
)
sign_
adjust_zip
(
unsigned
,
output
)
sign_
zip
(
unsigned
,
output
,
args
.
release
)
header
(
'Output: '
+
output
)
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
):
def
cleanup
(
args
):
if
len
(
args
.
target
)
==
0
:
if
len
(
args
.
target
)
==
0
:
args
.
target
=
[
'native'
,
'java'
]
args
.
target
=
[
'native'
,
'java'
]
...
@@ -463,7 +463,7 @@ apk_parser.set_defaults(func=build_apk)
...
@@ -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
=
subparsers
.
add_parser
(
'snet'
,
help
=
'build snet extention for Magisk Manager'
)
snet_parser
.
set_defaults
(
func
=
build_snet
)
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
)
zip_parser
.
set_defaults
(
func
=
zip_main
)
uninstaller_parser
=
subparsers
.
add_parser
(
'uninstaller'
,
help
=
'create flashable uninstaller'
)
uninstaller_parser
=
subparsers
.
add_parser
(
'uninstaller'
,
help
=
'create flashable uninstaller'
)
...
@@ -478,5 +478,7 @@ if len(sys.argv) == 1:
...
@@ -478,5 +478,7 @@ if len(sys.argv) == 1:
sys
.
exit
(
1
)
sys
.
exit
(
1
)
args
=
parser
.
parse_args
()
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
STDOUT
=
None
if
args
.
verbose
else
subprocess
.
DEVNULL
args
.
func
(
args
)
args
.
func
(
args
)
config.prop.sample
View file @
32809e56
...
@@ -8,7 +8,8 @@ outdir=out
...
@@ -8,7 +8,8 @@ outdir=out
# The default output names are magisk-${release/debug/uninstaller}.zip
# The default output names are magisk-${release/debug/uninstaller}.zip
prettyName=false
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
# keyPass is the pwd for the specified keyAlias
keyStorePass=
keyStorePass=
keyAlias=
keyAlias=
...
...
utils/build.gradle
View file @
32809e56
...
@@ -15,7 +15,7 @@ jar {
...
@@ -15,7 +15,7 @@ jar {
shadowJar
{
shadowJar
{
baseName
=
'zipsigner'
baseName
=
'zipsigner'
classifier
=
null
classifier
=
null
version
=
2.2
version
=
3.0
}
}
buildscript
{
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;
...
@@ -18,7 +18,6 @@ import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
import
org.bouncycastle.operator.jcajce.JcaDigestCalculatorProviderBuilder
;
import
org.bouncycastle.operator.jcajce.JcaDigestCalculatorProviderBuilder
;
import
org.bouncycastle.util.encoders.Base64
;
import
org.bouncycastle.util.encoders.Base64
;
import
java.io.BufferedInputStream
;
import
java.io.BufferedOutputStream
;
import
java.io.BufferedOutputStream
;
import
java.io.ByteArrayOutputStream
;
import
java.io.ByteArrayOutputStream
;
import
java.io.File
;
import
java.io.File
;
...
@@ -32,6 +31,7 @@ import java.io.PrintStream;
...
@@ -32,6 +31,7 @@ import java.io.PrintStream;
import
java.io.RandomAccessFile
;
import
java.io.RandomAccessFile
;
import
java.security.DigestOutputStream
;
import
java.security.DigestOutputStream
;
import
java.security.GeneralSecurityException
;
import
java.security.GeneralSecurityException
;
import
java.security.KeyStore
;
import
java.security.MessageDigest
;
import
java.security.MessageDigest
;
import
java.security.PrivateKey
;
import
java.security.PrivateKey
;
import
java.security.Provider
;
import
java.security.Provider
;
...
@@ -60,7 +60,7 @@ public class SignAPK {
...
@@ -60,7 +60,7 @@ public class SignAPK {
private
static
final
String
CERT_SF_NAME
=
"META-INF/CERT.SF"
;
private
static
final
String
CERT_SF_NAME
=
"META-INF/CERT.SF"
;
private
static
final
String
CERT_SIG_NAME
=
"META-INF/CERT.%s"
;
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.
// bitmasks for which hash algorithms we need the manifest to include.
private
static
final
int
USE_SHA1
=
1
;
private
static
final
int
USE_SHA1
=
1
;
private
static
final
int
USE_SHA256
=
2
;
private
static
final
int
USE_SHA256
=
2
;
...
@@ -70,59 +70,61 @@ public class SignAPK {
...
@@ -70,59 +70,61 @@ public class SignAPK {
Security
.
insertProviderAt
(
sBouncyCastleProvider
,
1
);
Security
.
insertProviderAt
(
sBouncyCastleProvider
,
1
);
}
}
public
static
void
signZip
(
InputStream
cert
,
InputStream
key
,
public
static
void
sign
(
JarMap
input
,
OutputStream
output
)
throws
Exception
{
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
temp1
=
File
.
createTempFile
(
"signAPK"
,
null
);
File
temp2
=
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
{
try
(
OutputStream
out
=
new
BufferedOutputStream
(
new
FileOutputStream
(
temp1
)))
{
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
);
ZipAdjust
.
adjust
(
temp1
,
temp2
);
try
(
JarMap
map
=
new
JarMap
(
temp2
,
false
))
{
try
(
JarMap
map
=
new
JarMap
(
temp2
,
false
))
{
sign
Zip
(
c
,
k
,
map
,
output
,
true
);
sign
(
cert
,
key
,
map
,
output
,
true
);
}
}
}
finally
{
}
finally
{
temp1
.
delete
();
temp1
.
delete
();
temp2
.
delete
();
temp2
.
delete
();
c
.
destroy
();
k
.
destroy
();
}
}
}
}
public
static
void
signZip
(
InputStream
cert
,
InputStream
key
,
private
static
void
sign
(
X509Certificate
cert
,
PrivateKey
key
,
JarMap
input
,
OutputStream
output
,
boolean
minSign
)
throws
Exception
{
JarMap
input
,
OutputStream
output
,
boolean
minSign
)
throws
Exception
{
int
alignment
=
4
;
int
hashes
=
0
;
int
hashes
=
0
;
if
(
cert
==
null
)
{
hashes
|=
getDigestAlgorithm
(
cert
);
cert
=
SignAPK
.
class
.
getResourceAsStream
(
"/keys/testkey.x509.pem"
);
}
X509Certificate
certificate
=
CryptoUtils
.
readCertificate
(
cert
);
hashes
|=
getDigestAlgorithm
(
certificate
);
// Set the ZIP file timestamp to the starting valid time
// Set the ZIP file timestamp to the starting valid time
// of the 0th certificate plus one hour (to match what
// of the 0th certificate plus one hour (to match what
// we've historically done).
// we've historically done).
long
timestamp
=
certificate
.
getNotBefore
().
getTime
()
+
3600L
*
1000
;
long
timestamp
=
cert
.
getNotBefore
().
getTime
()
+
3600L
*
1000
;
if
(
key
==
null
)
{
key
=
SignAPK
.
class
.
getResourceAsStream
(
"/keys/testkey.pk8"
);
}
PrivateKey
privateKey
=
CryptoUtils
.
readPrivateKey
(
key
);
if
(
minSign
)
{
if
(
minSign
)
{
signWholeFile
(
input
.
getFile
(),
cert
ificate
,
privateK
ey
,
output
);
signWholeFile
(
input
.
getFile
(),
cert
,
k
ey
,
output
);
}
else
{
}
else
{
JarOutputStream
outputJar
=
new
JarOutputStream
(
output
);
JarOutputStream
outputJar
=
new
JarOutputStream
(
output
);
// For signing .apks, use the maximum compression to make
// For signing .apks, use the maximum compression to make
...
@@ -133,8 +135,8 @@ public class SignAPK {
...
@@ -133,8 +135,8 @@ public class SignAPK {
// (~0.1% on full OTA packages I tested).
// (~0.1% on full OTA packages I tested).
outputJar
.
setLevel
(
9
);
outputJar
.
setLevel
(
9
);
Manifest
manifest
=
addDigestsToManifest
(
input
,
hashes
);
Manifest
manifest
=
addDigestsToManifest
(
input
,
hashes
);
copyFiles
(
manifest
,
input
,
outputJar
,
timestamp
,
alignment
);
copyFiles
(
manifest
,
input
,
outputJar
,
timestamp
,
4
);
signFile
(
manifest
,
input
,
cert
ificate
,
privateK
ey
,
outputJar
);
signFile
(
manifest
,
input
,
cert
,
k
ey
,
outputJar
);
outputJar
.
close
();
outputJar
.
close
();
}
}
}
}
...
...
utils/src/main/java/com/topjohnwu/utils/ZipSigner.java
View file @
32809e56
package
com
.
topjohnwu
.
utils
;
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.FileInputStream
;
import
java.io.FileOutputStream
;
import
java.io.FileOutputStream
;
import
java.io.InputStream
;
import
java.io.InputStream
;
import
java.
security.Security
;
import
java.
io.OutputStream
;
public
class
ZipSigner
{
public
class
ZipSigner
{
public
static
void
usage
()
{
public
static
void
usage
()
{
System
.
err
.
println
(
"Usage: zipsigner [x509.pem] [pk8] input.jar output.jar"
);
System
.
err
.
println
(
"ZipSigner usage:"
);
System
.
err
.
println
(
"Note: If no certificate/private key pair is specified, it will use the embedded test keys."
);
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
);
System
.
exit
(
2
);
}
}
public
static
void
main
(
String
[]
args
)
throws
Exception
{
public
static
void
main
(
String
[]
args
)
throws
Exception
{
int
argStart
=
0
;
if
(
args
.
length
!=
2
&&
args
.
length
!=
4
&&
args
.
length
!=
6
)
if
(
args
.
length
<
2
)
usage
();
usage
();
InputStream
cert
=
null
;
try
(
JarMap
in
=
new
JarMap
(
args
[
args
.
length
-
2
],
false
);
InputStream
key
=
null
;
OutputStream
out
=
new
FileOutputStream
(
args
[
args
.
length
-
1
]))
{
if
(
args
.
length
==
2
)
{
if
(
args
.
length
-
argStart
==
4
)
{
SignAPK
.
sign
(
in
,
out
);
cert
=
new
FileInputStream
(
new
File
(
args
[
argStart
]));
}
else
if
(
args
.
length
==
4
)
{
key
=
new
FileInputStream
(
new
File
(
args
[
argStart
+
1
]));
try
(
InputStream
cert
=
new
FileInputStream
(
args
[
0
]);
argStart
+=
2
;
InputStream
key
=
new
FileInputStream
(
args
[
1
]))
{
}
SignAPK
.
sign
(
cert
,
key
,
in
,
out
);
}
if
(
args
.
length
-
argStart
!=
2
)
}
else
if
(
args
.
length
==
6
)
{
usage
();
try
(
InputStream
jks
=
new
FileInputStream
(
args
[
0
]))
{
SignAPK
.
sign
(
jks
,
args
[
1
],
args
[
2
],
args
[
3
],
in
,
out
);
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
);
}
}
}
}
}
}
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