Skip to content

Commit

Permalink
Bug 1838680 - Do not force --min-sdk-version anymore because of outda… (
Browse files Browse the repository at this point in the history
#852)

* Bug 1838680 - part 1: Add a second test APK in TestSignaturePass() to include minSdkVersion

* Bug 1838680 - part 2: Only use `--min-sdk-version` if APK doesn't provide it
  • Loading branch information
JohanLorenzo authored Jul 11, 2023
1 parent 8ddfa38 commit 7bc7ab2
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 4 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ _testmain.go
*.prof

*.out
*.log
.DS_Store

docs/*.html
Expand Down
10 changes: 9 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,14 @@ staticcheck:
test:
go test -v -coverprofile coverage.out -covermode=count -count=1 $(PACKAGE_NAMES)

test-in-docker:
$(SHELL) -c " \
docker compose up 2>&1 | tee test-in-docker.log \
| (grep --silent 'autograph-unit-test exited with code' && docker compose down; \
grep 'autograph-unit-test' test-in-docker.log >unit-test.log ; \
tail -2 unit-test.log)"


showcoverage: test
go tool cover -html=coverage.out

Expand Down Expand Up @@ -105,4 +113,4 @@ dummy-statsd:
nc -kluvw 0 localhost 8125

.SUFFIXES: # Delete the default suffixes
.PHONY: all dummy-statsd test generate vendor integration-test check-no-crypto11-in-signers
.PHONY: all dummy-statsd test generate vendor integration-test check-no-crypto11-in-signers test-in-docker
24 changes: 23 additions & 1 deletion handlers_racing_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ func TestSignaturePass(t *testing.T) {
},
},
{
// Sign an APK file
// Sign an APK file that has no min-sdk-version so we have to manually force it
"/sign/file",
[]formats.SignatureRequest{
formats.SignatureRequest{
Expand All @@ -87,6 +87,28 @@ func TestSignaturePass(t *testing.T) {
},
},
},
{
// Sign an APK file
/*
How to create a small-enough APK:
1. Create a new Android project with Android Studio, the official Android IDE
2. Initialize a git repository, in case you make a mistake with one of the steps above
3. Delete all files that seem unnecessary
4. Strip out unnecessary metadata in AndroidManifest.xml
5. Add <uses-sdk android:minSdkVersion="21"/> to AndroidManifest.xml. 21 matches Android 5.0: https://apilevels.com/
6. Remove all dependencies in build.gradle
7. `./gradlew clean assemble && ls -lh app/build/outputs/apk/release/app-release-unsigned.apk` says the generated APK is 1.2 kB.
8. `unzip -l app-release-unsigned.apk` to show all files contained in the APK. Only AndroidManifest.xml is needed. Purge all others with `zip -d app-release-unsigned.apk $file`
9. base64 the APK and paste the content in this file.
*/
"/sign/file",
[]formats.SignatureRequest{
formats.SignatureRequest{
Input: "UEsDBAAAAAAIACEIIQJ3XNdl0gIAAMwHAAATAAAAQW5kcm9pZE1hbmlmZXN0LnhtbJ2VTU9TQRSGz/QCrZYiFMq3RhMTjQlFkYVxYYJEokllodGFKyoFIbTQ9F5QEmNYu3bpwoV7/QX+AhcuWPhr1GfOndtOr238uM17Z+adc945c+bcaSA5+ZoVMTIvrwdELkjneef1R8AsKIMK2AYn4CP4Ar6DH2DZiNwBa2AbHIG34D04BdMZkSWwBt6Ab+BqwBg8A3XwAZyCQalLVZ7LFq3IgOwzajASYt6SV9KUA2lJRL8GV2BuF5vHjPbkKWxLQpgDOJG8HHUxq7xrqpWeWW+vMop2lZkXjKK+ulWiqzN6KXfpb2JzSGR2JtReEmUoj3jbnYxhdcAaTVTq6PVWnvkLq2QXncwEcoMzuk4vQ++mntxDOZYVjaSO3ya2kfNfYn5Io47a6+ba4yMQ4SuShdtnpRY2u5rt2RRT1txHGkvEyNcsE8GKPCCzIhf/4BdHt0XObdaOYSr4PsF3Ve7LPXIY57zXbmzsaX8baZzHstZMVTNq81mmd9xHyeblyn/52b1WdU8rv2XxmuzQi/C7LYv8Qix2UGzgEWrOujMTr7+oa+3RtrANddx9FoWuHC7wbdqKibRSbE4a6rELb/0jPc+mq9WqVjffpe7G7mRbM9egmg9Vp9an5v7FZ937cg9hbRwLwFY094jJybLYO8iYAIyC4Ywxc2AeNMEJ+BQY0xo0JgSC1bRWuchPnlHaKTuG/+zx9pmhP8Ev6+6yKb1N4vkcn7lx3KDWlo1Rgrzjznh2lxx3Fgw7u2E3b+/GkuNKjptL+dr+vMcVXLwVPZFOvOddvBkv3sDzKzluKKUfuJyktZI18h4/3mONbEevaNupeD9dnNXacP8HidY5pxV4WqJ1Geej4Dib50nHTSbn1UP/MlzR0592+sljbW7Rjns2I87GeDEYvWvj9ca8/KT9Er2Sx0/00Ss6vaKnl/ZL+PQeEj6du4RPn0+QqvGklk2f2v8FUEsBAgAAAAAAAAgAIQghAndc12XSAgAAzAcAABMAAAAAAAAAAAAAAAAAAAAAAEFuZHJvaWRNYW5pZmVzdC54bWxQSwUGAAAAAAEAAQBBAAAAAwMAAAAA",
KeyID: "testapp-android",
},
},
},
{
// Sign MAR data
"/sign/data",
Expand Down
30 changes: 28 additions & 2 deletions signer/apk2/apk2.go
Original file line number Diff line number Diff line change
Expand Up @@ -158,14 +158,27 @@ func (s *APK2Signer) SignFile(file []byte, options interface{}) (signer.SignedFi
args = append(args,
"--key", keyPath.Name(),
"--cert", certPath.Name(),
"--min-sdk-version", s.minSdkVersion,
tmpAPKFile.Name(),
)
apkSigCmd := exec.Command("java", args...)

out, err := apkSigCmd.CombinedOutput()
if err != nil {
return nil, fmt.Errorf("apk2: failed to sign\n%s: %w", out, err)
if !bytes.Contains(out, []byte("com.android.apksig.apk.MinSdkVersionException")) {
return nil, fmt.Errorf("apk2: failed to sign\n%s: %w", out, err)
} else {
log.Printf("apk2: APK does not provide minSdkVersion. Attempting to sign again with: --min-sdk-version %s", s.minSdkVersion)

args = insertIntoSliceAtIndex(args, "--min-sdk-version", len(args)-1)
args = insertIntoSliceAtIndex(args, s.minSdkVersion, len(args)-1)

apkSigCmd = exec.Command("java", args...)
out, err = apkSigCmd.CombinedOutput()

if err != nil {
return nil, fmt.Errorf("apk2: failed to sign even when forcing --min-sdk-version\n%s: %w", out, err)
}
}
}
log.Debugf("signed as:\n%s\n", string(out))

Expand All @@ -176,6 +189,19 @@ func (s *APK2Signer) SignFile(file []byte, options interface{}) (signer.SignedFi
return signer.SignedFile(signedApk), nil
}

// go 1.16 doesn't support generics.
// TODO: Replace string by T in function signature once we use go 1.18+
func insertIntoSliceAtIndex(destination []string, element string, index int) []string {
if len(destination) == index {
return append(destination, element)
}

destination = append(destination[:index+1], destination[index:]...) // index < len(a)
destination[index] = element

return destination
}

// Options are not implemented for this signer
type Options struct {
}
Expand Down

0 comments on commit 7bc7ab2

Please sign in to comment.