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
c61135ee
Commit
c61135ee
authored
Jan 26, 2018
by
topjohnwu
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Embed testkeys into jar
parent
97cf1500
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
70 additions
and
56 deletions
+70
-56
app
app
+1
-1
build.py
build.py
+3
-13
build.gradle
crypto/build.gradle
+2
-2
CryptoUtils.java
crypto/src/main/java/com/topjohnwu/crypto/CryptoUtils.java
+4
-4
SignAPK.java
crypto/src/main/java/com/topjohnwu/crypto/SignAPK.java
+14
-9
SignBoot.java
crypto/src/main/java/com/topjohnwu/crypto/SignBoot.java
+16
-11
ZipSigner.java
crypto/src/main/java/com/topjohnwu/crypto/ZipSigner.java
+30
-16
testkey.pk8
crypto/src/main/resources/keys/testkey.pk8
+0
-0
testkey.x509.pem
crypto/src/main/resources/keys/testkey.x509.pem
+0
-0
No files found.
app
@
f37f3306
Subproject commit
00d655f346fe6182d508d76d6b75d8e7357fcb9d
Subproject commit
f37f330670b1dba2cc76d52d07587c7c605e096a
build.py
View file @
c61135ee
...
@@ -127,11 +127,6 @@ def build_binary(args):
...
@@ -127,11 +127,6 @@ def build_binary(args):
def
build_apk
(
args
):
def
build_apk
(
args
):
header
(
'* Building Magisk Manager'
)
header
(
'* Building Magisk Manager'
)
for
key
in
[
'public.certificate.x509.pem'
,
'private.key.pk8'
]:
source
=
os
.
path
.
join
(
'ziptools'
,
key
)
target
=
os
.
path
.
join
(
'app'
,
'src'
,
'main'
,
'assets'
,
key
)
cp
(
source
,
target
)
for
script
in
[
'magisk_uninstaller.sh'
,
'util_functions.sh'
]:
for
script
in
[
'magisk_uninstaller.sh'
,
'util_functions.sh'
]:
source
=
os
.
path
.
join
(
'scripts'
,
script
)
source
=
os
.
path
.
join
(
'scripts'
,
script
)
target
=
os
.
path
.
join
(
'app'
,
'src'
,
'main'
,
'assets'
,
script
)
target
=
os
.
path
.
join
(
'app'
,
'src'
,
'main'
,
'assets'
,
script
)
...
@@ -331,7 +326,7 @@ def zip_uninstaller(args):
...
@@ -331,7 +326,7 @@ def zip_uninstaller(args):
sign_adjust_zip
(
unsigned
,
output
)
sign_adjust_zip
(
unsigned
,
output
)
def
sign_adjust_zip
(
unsigned
,
output
):
def
sign_adjust_zip
(
unsigned
,
output
):
signer_name
=
'zipsigner-
1.1
.jar'
signer_name
=
'zipsigner-
2.0
.jar'
jarsigner
=
os
.
path
.
join
(
'crypto'
,
'build'
,
'libs'
,
signer_name
)
jarsigner
=
os
.
path
.
join
(
'crypto'
,
'build'
,
'libs'
,
signer_name
)
if
os
.
name
!=
'nt'
and
not
os
.
path
.
exists
(
os
.
path
.
join
(
'ziptools'
,
'zipadjust'
)):
if
os
.
name
!=
'nt'
and
not
os
.
path
.
exists
(
os
.
path
.
join
(
'ziptools'
,
'zipadjust'
)):
...
@@ -348,14 +343,10 @@ def sign_adjust_zip(unsigned, output):
...
@@ -348,14 +343,10 @@ def sign_adjust_zip(unsigned, output):
header
(
'* Signing / Adjusting Zip'
)
header
(
'* Signing / Adjusting Zip'
)
publicKey
=
os
.
path
.
join
(
'ziptools'
,
'public.certificate.x509.pem'
)
privateKey
=
os
.
path
.
join
(
'ziptools'
,
'private.key.pk8'
)
signed
=
tempfile
.
mkstemp
()[
1
]
signed
=
tempfile
.
mkstemp
()[
1
]
# Unsigned->signed
# Unsigned->signed
proc
=
subprocess
.
run
([
'java'
,
'-jar'
,
jarsigner
,
proc
=
subprocess
.
run
([
'java'
,
'-jar'
,
jarsigner
,
unsigned
,
signed
])
publicKey
,
privateKey
,
unsigned
,
signed
])
if
proc
.
returncode
!=
0
:
if
proc
.
returncode
!=
0
:
error
(
'First sign flashable zip failed!'
)
error
(
'First sign flashable zip failed!'
)
...
@@ -367,8 +358,7 @@ def sign_adjust_zip(unsigned, output):
...
@@ -367,8 +358,7 @@ def sign_adjust_zip(unsigned, output):
error
(
'Adjust flashable zip failed!'
)
error
(
'Adjust flashable zip failed!'
)
# Adjusted -> output
# Adjusted -> output
proc
=
subprocess
.
run
([
'java'
,
'-jar'
,
jarsigner
,
proc
=
subprocess
.
run
([
'java'
,
'-jar'
,
jarsigner
,
"-m"
,
adjusted
,
output
])
"-m"
,
publicKey
,
privateKey
,
adjusted
,
output
])
if
proc
.
returncode
!=
0
:
if
proc
.
returncode
!=
0
:
error
(
'Second sign flashable zip failed!'
)
error
(
'Second sign flashable zip failed!'
)
...
...
crypto/build.gradle
View file @
c61135ee
...
@@ -15,7 +15,7 @@ jar {
...
@@ -15,7 +15,7 @@ jar {
shadowJar
{
shadowJar
{
baseName
=
'zipsigner'
baseName
=
'zipsigner'
classifier
=
null
classifier
=
null
version
=
1.1
version
=
2.0
}
}
buildscript
{
buildscript
{
...
@@ -23,7 +23,7 @@ buildscript {
...
@@ -23,7 +23,7 @@ buildscript {
jcenter
()
jcenter
()
}
}
dependencies
{
dependencies
{
classpath
'com.github.jengelman.gradle.plugins:shadow:2.0.
1
'
classpath
'com.github.jengelman.gradle.plugins:shadow:2.0.
2
'
}
}
}
}
...
...
crypto/src/main/java/com/topjohnwu/crypto/CryptoUtils.java
View file @
c61135ee
...
@@ -102,7 +102,7 @@ class CryptoUtils {
...
@@ -102,7 +102,7 @@ class CryptoUtils {
return
signer
.
sign
();
return
signer
.
sign
();
}
}
static
X509Certificate
read
PublicKey
(
InputStream
input
)
static
X509Certificate
read
Certificate
(
InputStream
input
)
throws
IOException
,
GeneralSecurityException
{
throws
IOException
,
GeneralSecurityException
{
try
{
try
{
CertificateFactory
cf
=
CertificateFactory
.
getInstance
(
"X.509"
);
CertificateFactory
cf
=
CertificateFactory
.
getInstance
(
"X.509"
);
...
@@ -116,9 +116,9 @@ class CryptoUtils {
...
@@ -116,9 +116,9 @@ class CryptoUtils {
static
PrivateKey
readPrivateKey
(
InputStream
input
)
static
PrivateKey
readPrivateKey
(
InputStream
input
)
throws
IOException
,
GeneralSecurityException
{
throws
IOException
,
GeneralSecurityException
{
try
{
try
{
byte
[]
buffer
=
new
byte
[
4096
]
;
ByteArrayStream
buf
=
new
ByteArrayStream
()
;
int
size
=
input
.
read
(
buffer
);
buf
.
readFrom
(
input
);
byte
[]
bytes
=
Arrays
.
copyOf
(
buffer
,
size
);
byte
[]
bytes
=
buf
.
toByteArray
(
);
/* Check to see if this is in an EncryptedPrivateKeyInfo structure. */
/* Check to see if this is in an EncryptedPrivateKeyInfo structure. */
PKCS8EncodedKeySpec
spec
=
new
PKCS8EncodedKeySpec
(
bytes
);
PKCS8EncodedKeySpec
spec
=
new
PKCS8EncodedKeySpec
(
bytes
);
/*
/*
...
...
crypto/src/main/java/com/topjohnwu/crypto/SignAPK.java
View file @
c61135ee
...
@@ -18,11 +18,9 @@ import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
...
@@ -18,11 +18,9 @@ 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.BufferedOutputStream
;
import
java.io.ByteArrayOutputStream
;
import
java.io.ByteArrayOutputStream
;
import
java.io.File
;
import
java.io.File
;
import
java.io.FileNotFoundException
;
import
java.io.FileNotFoundException
;
import
java.io.FileOutputStream
;
import
java.io.FilterOutputStream
;
import
java.io.FilterOutputStream
;
import
java.io.IOException
;
import
java.io.IOException
;
import
java.io.InputStream
;
import
java.io.InputStream
;
...
@@ -69,21 +67,27 @@ public class SignAPK {
...
@@ -69,21 +67,27 @@ public class SignAPK {
Security
.
insertProviderAt
(
sBouncyCastleProvider
,
1
);
Security
.
insertProviderAt
(
sBouncyCastleProvider
,
1
);
}
}
public
static
void
signZip
(
InputStream
publicIn
,
InputStream
privateIn
,
public
static
void
signZip
(
InputStream
cert
,
InputStream
key
,
JarMap
input
,
OutputStream
output
,
boolean
minSign
)
throws
Exception
{
JarMap
input
,
OutputStream
output
,
boolean
minSign
)
throws
Exception
{
int
alignment
=
4
;
int
alignment
=
4
;
int
hashes
=
0
;
int
hashes
=
0
;
X509Certificate
publicKey
=
CryptoUtils
.
readPublicKey
(
publicIn
);
if
(
cert
==
null
)
{
hashes
|=
getDigestAlgorithm
(
publicKey
);
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
=
publicKey
.
getNotBefore
().
getTime
()
+
3600L
*
1000
;
long
timestamp
=
certificate
.
getNotBefore
().
getTime
()
+
3600L
*
1000
;
PrivateKey
privateKey
=
CryptoUtils
.
readPrivateKey
(
privateIn
);
if
(
key
==
null
)
{
key
=
SignAPK
.
class
.
getResourceAsStream
(
"/keys/testkey.pk8"
);
}
PrivateKey
privateKey
=
CryptoUtils
.
readPrivateKey
(
key
);
if
(
minSign
)
{
if
(
minSign
)
{
signWholeFile
(
input
.
getFile
(),
publicKey
,
privateKey
,
output
);
signWholeFile
(
input
.
getFile
(),
certificate
,
privateKey
,
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
...
@@ -95,7 +99,8 @@ public class SignAPK {
...
@@ -95,7 +99,8 @@ public class SignAPK {
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
,
alignment
);
signFile
(
manifest
,
input
,
publicKey
,
privateKey
,
outputJar
);
signFile
(
manifest
,
input
,
certificate
,
privateKey
,
outputJar
);
outputJar
.
close
();
}
}
}
}
...
...
crypto/src/main/java/com/topjohnwu/crypto/SignBoot.java
View file @
c61135ee
...
@@ -35,7 +35,7 @@ public class SignBoot {
...
@@ -35,7 +35,7 @@ public class SignBoot {
}
}
public
static
boolean
doSignature
(
String
target
,
InputStream
imgIn
,
OutputStream
imgOut
,
public
static
boolean
doSignature
(
String
target
,
InputStream
imgIn
,
OutputStream
imgOut
,
InputStream
keyIn
,
InputStream
certIn
)
{
InputStream
cert
,
InputStream
key
)
{
try
{
try
{
ByteArrayStream
bas
=
new
ByteArrayStream
();
ByteArrayStream
bas
=
new
ByteArrayStream
();
bas
.
readFrom
(
imgIn
);
bas
.
readFrom
(
imgIn
);
...
@@ -51,23 +51,29 @@ public class SignBoot {
...
@@ -51,23 +51,29 @@ public class SignBoot {
signableSize
+
" bytes"
);
signableSize
+
" bytes"
);
}
}
BootSignature
bootsig
=
new
BootSignature
(
target
,
image
.
length
);
BootSignature
bootsig
=
new
BootSignature
(
target
,
image
.
length
);
X509Certificate
cert
=
CryptoUtils
.
readPublicKey
(
certIn
);
if
(
cert
==
null
)
{
bootsig
.
setCertificate
(
cert
);
cert
=
SignBoot
.
class
.
getResourceAsStream
(
"/keys/testkey.x509.pem"
);
PrivateKey
key
=
CryptoUtils
.
readPrivateKey
(
keyIn
);
}
bootsig
.
setSignature
(
bootsig
.
sign
(
image
,
key
),
X509Certificate
certificate
=
CryptoUtils
.
readCertificate
(
cert
);
CryptoUtils
.
getSignatureAlgorithmIdentifier
(
key
));
bootsig
.
setCertificate
(
certificate
);
if
(
key
==
null
)
{
key
=
SignBoot
.
class
.
getResourceAsStream
(
"/keys/testkey.pk8"
);
}
PrivateKey
privateKey
=
CryptoUtils
.
readPrivateKey
(
key
);
bootsig
.
setSignature
(
bootsig
.
sign
(
image
,
privateKey
),
CryptoUtils
.
getSignatureAlgorithmIdentifier
(
privateKey
));
byte
[]
encoded_bootsig
=
bootsig
.
getEncoded
();
byte
[]
encoded_bootsig
=
bootsig
.
getEncoded
();
imgOut
.
write
(
image
);
imgOut
.
write
(
image
);
imgOut
.
write
(
encoded_bootsig
);
imgOut
.
write
(
encoded_bootsig
);
imgOut
.
flush
();
imgOut
.
flush
();
return
true
;
return
true
;
}
catch
(
Exception
e
)
{
}
catch
(
Exception
e
)
{
e
.
printStackTrace
(
System
.
err
);
e
.
printStackTrace
();
return
false
;
return
false
;
}
}
}
}
public
static
boolean
verifySignature
(
InputStream
imgIn
,
InputStream
cert
Path
)
{
public
static
boolean
verifySignature
(
InputStream
imgIn
,
InputStream
cert
In
)
{
try
{
try
{
ByteArrayStream
bas
=
new
ByteArrayStream
();
ByteArrayStream
bas
=
new
ByteArrayStream
();
bas
.
readFrom
(
imgIn
);
bas
.
readFrom
(
imgIn
);
...
@@ -80,8 +86,8 @@ public class SignBoot {
...
@@ -80,8 +86,8 @@ public class SignBoot {
}
}
byte
[]
signature
=
Arrays
.
copyOfRange
(
image
,
signableSize
,
image
.
length
);
byte
[]
signature
=
Arrays
.
copyOfRange
(
image
,
signableSize
,
image
.
length
);
BootSignature
bootsig
=
new
BootSignature
(
signature
);
BootSignature
bootsig
=
new
BootSignature
(
signature
);
if
(
cert
Path
!=
null
)
{
if
(
cert
In
!=
null
)
{
bootsig
.
setCertificate
(
CryptoUtils
.
read
PublicKey
(
certPath
));
bootsig
.
setCertificate
(
CryptoUtils
.
read
Certificate
(
certIn
));
}
}
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"
);
...
@@ -90,7 +96,6 @@ public class SignBoot {
...
@@ -90,7 +96,6 @@ public class SignBoot {
System
.
err
.
println
(
"Signature is INVALID"
);
System
.
err
.
println
(
"Signature is INVALID"
);
}
}
}
catch
(
Exception
e
)
{
}
catch
(
Exception
e
)
{
e
.
printStackTrace
(
System
.
err
);
System
.
err
.
println
(
"Invalid image: not signed"
);
System
.
err
.
println
(
"Invalid image: not signed"
);
}
}
return
false
;
return
false
;
...
...
crypto/src/main/java/com/topjohnwu/crypto/ZipSigner.java
View file @
c61135ee
...
@@ -2,44 +2,58 @@ package com.topjohnwu.crypto;
...
@@ -2,44 +2,58 @@ package com.topjohnwu.crypto;
import
org.bouncycastle.jce.provider.BouncyCastleProvider
;
import
org.bouncycastle.jce.provider.BouncyCastleProvider
;
import
java.io.BufferedInputStream
;
import
java.io.BufferedOutputStream
;
import
java.io.BufferedOutputStream
;
import
java.io.File
;
import
java.io.File
;
import
java.io.FileInputStream
;
import
java.io.FileInputStream
;
import
java.io.FileNotFoundException
;
import
java.io.FileOutputStream
;
import
java.io.FileOutputStream
;
import
java.io.IOException
;
import
java.io.InputStream
;
import
java.io.InputStream
;
import
java.security.Security
;
import
java.security.Security
;
public
class
ZipSigner
{
public
class
ZipSigner
{
public
static
void
main
(
String
[]
args
)
{
public
static
void
usage
()
{
System
.
err
.
println
(
"Usage: zipsigner [-m] [x509.pem] [pk8] input.jar output.jar"
);
System
.
err
.
println
(
"If no certificate/private key pair is specified, it will use the embedded test keys."
);
System
.
err
.
println
(
" -m: enable minimal signing"
);
System
.
exit
(
2
);
}
public
static
void
main
(
String
[]
args
)
throws
Exception
{
boolean
minSign
=
false
;
boolean
minSign
=
false
;
int
argStart
=
0
;
int
argStart
=
0
;
if
(
args
.
length
<
4
)
{
if
(
args
.
length
<
2
)
System
.
err
.
println
(
"Usage: zipsigner [-m] publickey.x509[.pem] privatekey.pk8 input.jar output.jar"
);
usage
();
System
.
exit
(
2
);
}
if
(
args
[
0
].
equals
(
"-m"
))
{
if
(
args
[
0
].
equals
(
"-m"
))
{
minSign
=
true
;
minSign
=
true
;
argStart
=
1
;
argStart
=
1
;
}
}
InputStream
cert
=
null
;
InputStream
key
=
null
;
if
(
args
.
length
-
argStart
==
4
)
{
cert
=
new
BufferedInputStream
(
new
FileInputStream
(
new
File
(
args
[
argStart
])));
key
=
new
BufferedInputStream
(
new
FileInputStream
(
new
File
(
args
[
argStart
+
1
])));
argStart
+=
2
;
}
if
(
args
.
length
-
argStart
!=
2
)
usage
();
SignAPK
.
sBouncyCastleProvider
=
new
BouncyCastleProvider
();
SignAPK
.
sBouncyCastleProvider
=
new
BouncyCastleProvider
();
Security
.
insertProviderAt
(
SignAPK
.
sBouncyCastleProvider
,
1
);
Security
.
insertProviderAt
(
SignAPK
.
sBouncyCastleProvider
,
1
);
File
pubKey
=
new
File
(
args
[
argStart
]);
File
input
=
new
File
(
args
[
argStart
]);
File
privKey
=
new
File
(
args
[
argStart
+
1
]);
File
output
=
new
File
(
args
[
argStart
+
1
]);
File
input
=
new
File
(
args
[
argStart
+
2
]);
File
output
=
new
File
(
args
[
argStart
+
3
]);
try
(
InputStream
pub
=
new
FileInputStream
(
pubKey
);
try
(
JarMap
jar
=
new
JarMap
(
input
,
false
);
InputStream
priv
=
new
FileInputStream
(
privKey
);
JarMap
jar
=
new
JarMap
(
input
,
false
);
BufferedOutputStream
out
=
new
BufferedOutputStream
(
new
FileOutputStream
(
output
)))
{
BufferedOutputStream
out
=
new
BufferedOutputStream
(
new
FileOutputStream
(
output
)))
{
SignAPK
.
signZip
(
pub
,
priv
,
jar
,
out
,
minSign
);
SignAPK
.
signZip
(
cert
,
key
,
jar
,
out
,
minSign
);
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
System
.
exit
(
1
);
}
}
}
}
}
}
ziptools/private.
key.pk8
→
crypto/src/main/resources/keys/test
key.pk8
View file @
c61135ee
File moved
ziptools/public.certificate
.x509.pem
→
crypto/src/main/resources/keys/testkey
.x509.pem
View file @
c61135ee
File moved
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