From ae513aa8ec144bcae9b26bbe3ad61bda4ec7ed79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=A2=AD=E5=BB=BA=E5=B8=85?= Date: Thu, 10 Nov 2016 06:21:16 +0800 Subject: [PATCH] Initial Commit --- .gitignore | 72 ++ LICENSE | 0 README.md | 84 ++ assets/walle.png | Bin 0 -> 323528 bytes build.gradle | 53 + gradle.properties | 21 + gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 53637 bytes gradle/wrapper/gradle-wrapper.properties | 3 + gradle_mvn_push.gradle | 206 ++++ gradlew | 160 +++ gradlew.bat | 90 ++ library/build.gradle | 27 + library/gradle.properties | 3 + library/proguard-rules.pro | 17 + library/src/main/AndroidManifest.xml | 8 + .../meituan/android/walle/ChannelReader.java | 8 + plugin/build.gradle | 13 + plugin/gradle.properties | 3 + .../android/walle/ApkSigningBlock.groovy | 101 ++ .../android/walle/ApkSigningPayload.groovy | 29 + .../meituan/android/walle/ChannelMaker.groovy | 200 +++ .../meituan/android/walle/GradlePlugin.groovy | 124 ++ .../apksigner/core/ApkSignerEngine.java | 407 ++++++ .../android/apksigner/core/ApkVerifier.java | 458 +++++++ .../core/DefaultApkSignerEngine.java | 893 ++++++++++++++ .../android/apksigner/core/apk/ApkUtils.java | 158 +++ .../core/internal/apk/v1/DigestAlgorithm.java | 42 + .../core/internal/apk/v1/V1SchemeSigner.java | 573 +++++++++ .../apk/v2/ContentDigestAlgorithm.java | 52 + .../internal/apk/v2/SignatureAlgorithm.java | 142 +++ .../core/internal/apk/v2/V2SchemeSigner.java | 605 +++++++++ .../internal/apk/v2/V2SchemeVerifier.java | 939 ++++++++++++++ .../core/internal/jar/ManifestWriter.java | 124 ++ .../internal/jar/SignatureFileWriter.java | 59 + .../util/ByteArrayOutputStreamSink.java | 62 + .../internal/util/ByteBufferDataSource.java | 126 ++ .../core/internal/util/ByteBufferSink.java | 56 + .../util/DelegatingX509Certificate.java | 179 +++ .../core/internal/util/MessageDigestSink.java | 52 + .../apksigner/core/internal/util/Pair.java | 81 ++ .../apksigner/core/internal/zip/ZipUtils.java | 278 +++++ .../android/apksigner/core/util/DataSink.java | 43 + .../apksigner/core/util/DataSource.java | 98 ++ .../apksigner/core/util/DataSources.java | 24 + .../core/zip/ZipFormatException.java | 32 + .../java/com/android/signapk/SignApk.java | 1094 +++++++++++++++++ .../META-INF/gradle-plugins/walle.properties | 1 + sample/app/.gitignore | 3 + sample/app/build.gradle | 53 + sample/app/keystore/meituan-debug.keystore | Bin 0 -> 2227 bytes sample/app/proguard-rules.pro | 19 + sample/app/src/main/AndroidManifest.xml | 21 + .../android/walle/sample/MainActivity.java | 12 + .../android/walle/sample/MyApplication.java | 8 + .../app/src/main/res/layout/activity_main.xml | 32 + .../src/main/res/mipmap-hdpi/ic_launcher.png | Bin 0 -> 3418 bytes .../src/main/res/mipmap-mdpi/ic_launcher.png | Bin 0 -> 2206 bytes .../src/main/res/mipmap-xhdpi/ic_launcher.png | Bin 0 -> 4842 bytes .../main/res/mipmap-xxhdpi/ic_launcher.png | Bin 0 -> 7718 bytes .../main/res/mipmap-xxxhdpi/ic_launcher.png | Bin 0 -> 10486 bytes .../app/src/main/res/values-w820dp/dimens.xml | 6 + sample/app/src/main/res/values/colors.xml | 6 + sample/app/src/main/res/values/dimens.xml | 5 + sample/app/src/main/res/values/strings.xml | 3 + sample/app/src/main/res/values/styles.xml | 10 + sample/build.gradle | 19 + sample/gradle.properties | 21 + sample/gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 53637 bytes .../gradle/wrapper/gradle-wrapper.properties | 4 + sample/gradlew | 160 +++ sample/gradlew.bat | 90 ++ sample/settings.gradle | 1 + settings.gradle | 1 + 73 files changed, 8274 insertions(+) create mode 100644 .gitignore create mode 100644 LICENSE create mode 100644 README.md create mode 100644 assets/walle.png create mode 100644 build.gradle create mode 100644 gradle.properties create mode 100644 gradle/wrapper/gradle-wrapper.jar create mode 100644 gradle/wrapper/gradle-wrapper.properties create mode 100644 gradle_mvn_push.gradle create mode 100755 gradlew create mode 100644 gradlew.bat create mode 100644 library/build.gradle create mode 100644 library/gradle.properties create mode 100644 library/proguard-rules.pro create mode 100644 library/src/main/AndroidManifest.xml create mode 100644 library/src/main/java/com/meituan/android/walle/ChannelReader.java create mode 100755 plugin/build.gradle create mode 100644 plugin/gradle.properties create mode 100644 plugin/src/main/groovy/com/meituan/android/walle/ApkSigningBlock.groovy create mode 100644 plugin/src/main/groovy/com/meituan/android/walle/ApkSigningPayload.groovy create mode 100644 plugin/src/main/groovy/com/meituan/android/walle/ChannelMaker.groovy create mode 100644 plugin/src/main/groovy/com/meituan/android/walle/GradlePlugin.groovy create mode 100644 plugin/src/main/java/com/android/apksigner/core/ApkSignerEngine.java create mode 100644 plugin/src/main/java/com/android/apksigner/core/ApkVerifier.java create mode 100644 plugin/src/main/java/com/android/apksigner/core/DefaultApkSignerEngine.java create mode 100644 plugin/src/main/java/com/android/apksigner/core/apk/ApkUtils.java create mode 100644 plugin/src/main/java/com/android/apksigner/core/internal/apk/v1/DigestAlgorithm.java create mode 100644 plugin/src/main/java/com/android/apksigner/core/internal/apk/v1/V1SchemeSigner.java create mode 100644 plugin/src/main/java/com/android/apksigner/core/internal/apk/v2/ContentDigestAlgorithm.java create mode 100644 plugin/src/main/java/com/android/apksigner/core/internal/apk/v2/SignatureAlgorithm.java create mode 100644 plugin/src/main/java/com/android/apksigner/core/internal/apk/v2/V2SchemeSigner.java create mode 100644 plugin/src/main/java/com/android/apksigner/core/internal/apk/v2/V2SchemeVerifier.java create mode 100644 plugin/src/main/java/com/android/apksigner/core/internal/jar/ManifestWriter.java create mode 100644 plugin/src/main/java/com/android/apksigner/core/internal/jar/SignatureFileWriter.java create mode 100644 plugin/src/main/java/com/android/apksigner/core/internal/util/ByteArrayOutputStreamSink.java create mode 100644 plugin/src/main/java/com/android/apksigner/core/internal/util/ByteBufferDataSource.java create mode 100644 plugin/src/main/java/com/android/apksigner/core/internal/util/ByteBufferSink.java create mode 100644 plugin/src/main/java/com/android/apksigner/core/internal/util/DelegatingX509Certificate.java create mode 100644 plugin/src/main/java/com/android/apksigner/core/internal/util/MessageDigestSink.java create mode 100644 plugin/src/main/java/com/android/apksigner/core/internal/util/Pair.java create mode 100644 plugin/src/main/java/com/android/apksigner/core/internal/zip/ZipUtils.java create mode 100644 plugin/src/main/java/com/android/apksigner/core/util/DataSink.java create mode 100644 plugin/src/main/java/com/android/apksigner/core/util/DataSource.java create mode 100644 plugin/src/main/java/com/android/apksigner/core/util/DataSources.java create mode 100644 plugin/src/main/java/com/android/apksigner/core/zip/ZipFormatException.java create mode 100644 plugin/src/main/java/com/android/signapk/SignApk.java create mode 100644 plugin/src/main/resources/META-INF/gradle-plugins/walle.properties create mode 100644 sample/app/.gitignore create mode 100644 sample/app/build.gradle create mode 100644 sample/app/keystore/meituan-debug.keystore create mode 100644 sample/app/proguard-rules.pro create mode 100644 sample/app/src/main/AndroidManifest.xml create mode 100644 sample/app/src/main/java/com/meituan/android/walle/sample/MainActivity.java create mode 100644 sample/app/src/main/java/com/meituan/android/walle/sample/MyApplication.java create mode 100644 sample/app/src/main/res/layout/activity_main.xml create mode 100644 sample/app/src/main/res/mipmap-hdpi/ic_launcher.png create mode 100644 sample/app/src/main/res/mipmap-mdpi/ic_launcher.png create mode 100644 sample/app/src/main/res/mipmap-xhdpi/ic_launcher.png create mode 100644 sample/app/src/main/res/mipmap-xxhdpi/ic_launcher.png create mode 100644 sample/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png create mode 100644 sample/app/src/main/res/values-w820dp/dimens.xml create mode 100644 sample/app/src/main/res/values/colors.xml create mode 100644 sample/app/src/main/res/values/dimens.xml create mode 100644 sample/app/src/main/res/values/strings.xml create mode 100644 sample/app/src/main/res/values/styles.xml create mode 100644 sample/build.gradle create mode 100644 sample/gradle.properties create mode 100644 sample/gradle/wrapper/gradle-wrapper.jar create mode 100644 sample/gradle/wrapper/gradle-wrapper.properties create mode 100755 sample/gradlew create mode 100644 sample/gradlew.bat create mode 100644 sample/settings.gradle create mode 100644 settings.gradle diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e14e1d6 --- /dev/null +++ b/.gitignore @@ -0,0 +1,72 @@ +# Created by .ignore support plugin (hsz.mobi) +### Java template +*.class + +# Mobile Tools for Java (J2ME) +.mtj.tmp/ + +# Package Files # +*.jar +*.war +*.ear + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* +### Gradle template +.gradle +build/ + +# Ignore Gradle GUI config +gradle-app.setting + +# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored) +!gradle-wrapper.jar + +# Cache of project +.gradletasknamecache + +# # Work around https://youtrack.jetbrains.com/issue/IDEA-116898 +# gradle/wrapper/gradle-wrapper.properties +### Android template +# Built application files +*.apk +*.ap_ + +# Files for the ART/Dalvik VM +*.dex + +# Java class files +*.class + +# Generated files +bin/ +gen/ +out/ + +# Gradle files +.gradle/ +build/ + +# Local configuration file (sdk path, etc) +local.properties + +# Proguard folder generated by Eclipse +proguard/ + +# Log Files +*.log + +# Android Studio Navigation editor temp files +.navigation/ + +# Android Studio captures folder +captures/ + +# Intellij +*.iml +.idea/workspace.xml +.idea + +# Keystore files +*.jks + diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..e69de29 diff --git a/README.md b/README.md new file mode 100644 index 0000000..5033e75 --- /dev/null +++ b/README.md @@ -0,0 +1,84 @@ +## Walle +[![license](http://img.shields.io/badge/license-BSD3-brightgreen.svg?style=flat)](https://github.com/Tencent/tinker/blob/master/LICENSE) + +支持Android Signature V2 Scheme的渠道包打包神器 + +![walle.png](assets/walle.png) + +## 使用说明 +在位于项目的根目录 `build.gradle` 文件中添加walle plugin的依赖 +Add tinker-gradle-plugin as a dependency in your main in the root of your project: + +```gradle +buildscript { + dependencies { + classpath ('com.meituan.android.walle:plugin:0.0.1') + } +} +``` + +Then you need to "apply" the plugin and add dependencies by adding the following lines to your `app/build.gradle`. + +```gradle +dependencies { + //optional, help to generate the final application + compile('com.tencent.tinker:tinker-android-anno:1.6.0') + //tinker's main Android lib + compile('com.tencent.tinker:tinker-android-lib:1.6.0') +} +... +... +apply plugin: 'com.tencent.tinker.patch' +``` + +If your app has a class that subclasses android.app.Application, then you need to modify that class, and move all its implements to [SampleApplicationLike](https://github.com/Tencent/tinker/blob/master/tinker-sample-android/app/src/main/java/tinker/sample/android/app/SampleApplicationLike.java) rather than Application: + +```java +-public class YourApplication extends Application { ++public class SampleApplicationLike extends DefaultApplicationLike { +``` + +Now you should change your `Application` class, make it a subclass of [TinkerApplication](https://github.com/Tencent/tinker/blob/master/tinker-android/tinker-android-loader/src/main/java/com/tencent/tinker/loader/app/TinkerApplication.java). As you can see from its API, it is an abstract class that does not have a default constructor, so you must define a no-arg constructor: + +```java +public class SampleApplication extends TinkerApplication { + public SampleApplication() { + super( + //tinkerFlags, which types is supported + //dex only, library only, all support + ShareConstants.TINKER_ENABLE_ALL, + // This is passed as a string so the shell application does not + // have a binary dependency on your ApplicationLifeCycle class. + "tinker.sample.android.SampleApplicationLike"); + } +} +``` + +Use `tinker-android-anno` to generate your `Application` is recommended, you just need to add an annotation for your [SampleApplicationLike](https://github.com/Tencent/tinker/blob/master/tinker-sample-android/app/src/main/java/tinker/sample/android/app/SampleApplicationLike.java) class + +```java +@DefaultLifeCycle( +application = "tinker.sample.android.app.SampleApplication", //application name to generate +flags = ShareConstants.TINKER_ENABLE_ALL) //tinkerFlags above +public class SampleApplicationLike extends DefaultApplicationLike +``` + +How to install tinker? learn more at the sample [SampleApplicationLike](https://github.com/Tencent/tinker/blob/master/tinker-sample-android/app/src/main/java/tinker/sample/android/app/SampleApplicationLike.java). + +For proguard, we have already made the proguard config automatic, and tinker will also generate the multiDex keep proguard file for you. + +For more tinker configurations, learn more at the sample [app/build.gradle](https://github.com/Tencent/tinker/blob/master/tinker-sample-android/app/build.gradle). + +## Support +Any problem? + +1. Learn more from [tinker-sample-android](https://github.com/Tencent/tinker/tree/master/tinker-sample-android). +2. Read the [source code](https://github.com/Tencent/tinker/tree/master). +3. Read the [wiki](https://github.com/Tencent/tinker/wiki) or [FAQ](https://github.com/Tencent/tinker/wiki/Tinker-%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98) for help. +4. Contact us for help. + +## Contributing + + +## License + diff --git a/assets/walle.png b/assets/walle.png new file mode 100644 index 0000000000000000000000000000000000000000..20412f915510923d146d5e381192d5fe8a924602 GIT binary patch literal 323528 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

Mg~G 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

2${aWy!apqNa}Kl&idS%-k}%_Ili^x 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

QkD+N1D(zQtvO|SFV*;UA)P`VN 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

55&8j%QW)n5s*aH~q1$fp!fKNf=jS-M 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 t9m@SZ!E*7&jsr?!t7TL-WYI4eM@gAug8 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 + uploadArchives { + repositories { + mavenDeployer { + beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) } + + pom.groupId = GROUP + pom.artifactId = POM_ARTIFACT_ID + pom.version = VERSION_NAME + + repository(url: getReleaseRepositoryUrl()) { + authentication(userName: getRepositoryUsername(), password: getRepositoryPassword()) + } + snapshotRepository(url: getSnapshotRepositoryUrl()) { + authentication(userName: getRepositoryUsername(), password: getRepositoryPassword()) + } + + pom.project { + name POM_NAME + packaging POM_PACKAGING + description POM_DESCRIPTION + url POM_URL + + scm { + url POM_SCM_URL + connection POM_SCM_CONNECTION + developerConnection POM_SCM_DEV_CONNECTION + } + + licenses { + license { + name POM_LICENCE_NAME + url POM_LICENCE_URL + distribution POM_LICENCE_DIST + } + } + + developers { + developer { + id POM_DEVELOPER_ID + name POM_DEVELOPER_NAME + } + } + } + } + } + } + + signing { + required { isReleaseBuild() && gradle.taskGraph.hasTask("uploadArchives") } + sign configurations.archives + } + + if (project.getPlugins().hasPlugin('com.android.application') || project.getPlugins().hasPlugin('com.android.library')) { + task install(type: Upload, dependsOn: assemble) { + repositories.mavenInstaller { + configuration = configurations.archives + + pom.groupId = GROUP + pom.artifactId = POM_ARTIFACT_ID + pom.version = VERSION_NAME + + pom.project { + name POM_NAME + packaging POM_PACKAGING + description POM_DESCRIPTION + url POM_URL + + scm { + url POM_SCM_URL + connection POM_SCM_CONNECTION + developerConnection POM_SCM_DEV_CONNECTION + } + + licenses { + license { + name POM_LICENCE_NAME + url POM_LICENCE_URL + distribution POM_LICENCE_DIST + } + } + + developers { + developer { + id POM_DEVELOPER_ID + name POM_DEVELOPER_NAME + } + } + } + } + } + + task androidJavadocs(type: Javadoc) { + failOnError false + source = android.sourceSets.main.java.source + classpath += project.files(android.getBootClasspath().join(File.pathSeparator)) + } + + task androidJavadocsJar(type: Jar, dependsOn: androidJavadocs) { + classifier = 'javadoc' + from androidJavadocs.destinationDir + } + + task androidSourcesJar(type: Jar) { + classifier = 'sources' + from android.sourceSets.main.java.source + } + } else { + install { + repositories.mavenInstaller { + pom.groupId = GROUP + pom.artifactId = POM_ARTIFACT_ID + pom.version = VERSION_NAME + + pom.project { + name POM_NAME + packaging POM_PACKAGING + description POM_DESCRIPTION + url POM_URL + + scm { + url POM_SCM_URL + connection POM_SCM_CONNECTION + developerConnection POM_SCM_DEV_CONNECTION + } + + licenses { + license { + name POM_LICENCE_NAME + url POM_LICENCE_URL + distribution POM_LICENCE_DIST + } + } + + developers { + developer { + id POM_DEVELOPER_ID + name POM_DEVELOPER_NAME + } + } + } + } + } + + task sourcesJar(type: Jar, dependsOn:classes) { + classifier = 'sources' + from sourceSets.main.allSource + } + + task javadocJar(type: Jar, dependsOn:javadoc) { + classifier = 'javadoc' + from javadoc.destinationDir + } + } + + artifacts { + if (project.getPlugins().hasPlugin('com.android.application') || project.getPlugins().hasPlugin('com.android.library')) { + archives androidSourcesJar + archives androidJavadocsJar + } else { + archives sourcesJar + archives javadocJar + } + } +} \ No newline at end of file diff --git a/gradlew b/gradlew new file mode 100755 index 0000000..9d82f78 --- /dev/null +++ b/gradlew @@ -0,0 +1,160 @@ +#!/usr/bin/env bash + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn ( ) { + echo "$*" +} + +die ( ) { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; +esac + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules +function splitJvmOpts() { + JVM_OPTS=("$@") +} +eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS +JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" + +exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 0000000..8a0b282 --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,90 @@ +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windowz variants + +if not "%OS%" == "Windows_NT" goto win9xME_args +if "%@eval[2+2]" == "4" goto 4NT_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* +goto execute + +:4NT_args +@rem Get arguments from the 4NT Shell from JP Software +set CMD_LINE_ARGS=%$ + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/library/build.gradle b/library/build.gradle new file mode 100644 index 0000000..34a949d --- /dev/null +++ b/library/build.gradle @@ -0,0 +1,27 @@ +apply plugin: 'com.android.library' +apply from: file('../gradle_mvn_push.gradle') + +android { + compileSdkVersion rootProject.ext.compileSdkVersion + buildToolsVersion rootProject.ext.buildToolsVersion + + defaultConfig { + minSdkVersion rootProject.ext.minSdkVersion + targetSdkVersion rootProject.ext.targetSdkVersion + } + + buildTypes { + debug { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + } + release { + minifyEnabled true + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + } + } +} + +dependencies { + compile fileTree(dir: 'libs', include: ['*.jar']) +} \ No newline at end of file diff --git a/library/gradle.properties b/library/gradle.properties new file mode 100644 index 0000000..fb6855e --- /dev/null +++ b/library/gradle.properties @@ -0,0 +1,3 @@ +POM_ARTIFACT_ID=library +POM_NAME=Walle Android library +POM_PACKAGING=aar \ No newline at end of file diff --git a/library/proguard-rules.pro b/library/proguard-rules.pro new file mode 100644 index 0000000..ca7ea79 --- /dev/null +++ b/library/proguard-rules.pro @@ -0,0 +1,17 @@ +# Add project specific ProGuard rules here. +# By default, the flags in this file are appended to flags specified +# in /Users/zhangshaowen/Library/Android/sdk/tools/proguard/proguard-android.txt +# You can edit the include path and order by changing the proguardFiles +# directive in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# Add any project specific keep options here: + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} diff --git a/library/src/main/AndroidManifest.xml b/library/src/main/AndroidManifest.xml new file mode 100644 index 0000000..838cbc3 --- /dev/null +++ b/library/src/main/AndroidManifest.xml @@ -0,0 +1,8 @@ + + + + + + + diff --git a/library/src/main/java/com/meituan/android/walle/ChannelReader.java b/library/src/main/java/com/meituan/android/walle/ChannelReader.java new file mode 100644 index 0000000..a712f78 --- /dev/null +++ b/library/src/main/java/com/meituan/android/walle/ChannelReader.java @@ -0,0 +1,8 @@ +package com.meituan.android.walle; + +/** + * Created by achellies on 16/11/10. + */ + +public class ChannelReader { +} diff --git a/plugin/build.gradle b/plugin/build.gradle new file mode 100755 index 0000000..3a31eff --- /dev/null +++ b/plugin/build.gradle @@ -0,0 +1,13 @@ +apply plugin: 'groovy' +apply from: file('../gradle_mvn_push.gradle') + +dependencies { + compile gradleApi() + compile localGroovy() + compile fileTree(dir: "./src/main/libs", include: ['*.jar']) + compile 'commons-io:commons-io:2.4' + compile 'commons-codec:commons-codec:1.6' + compile 'org.apache.commons:commons-lang3:3.4' + compile 'com.android.tools.build:gradle:2.2.0' +} + diff --git a/plugin/gradle.properties b/plugin/gradle.properties new file mode 100644 index 0000000..d47b2ba --- /dev/null +++ b/plugin/gradle.properties @@ -0,0 +1,3 @@ +POM_ARTIFACT_ID=plugin +POM_NAME=Walle Gradle Plugin +POM_PACKAGING=jar \ No newline at end of file diff --git a/plugin/src/main/groovy/com/meituan/android/walle/ApkSigningBlock.groovy b/plugin/src/main/groovy/com/meituan/android/walle/ApkSigningBlock.groovy new file mode 100644 index 0000000..43fbf4b --- /dev/null +++ b/plugin/src/main/groovy/com/meituan/android/walle/ApkSigningBlock.groovy @@ -0,0 +1,101 @@ +package com.meituan.android.walle + +import com.android.apksigner.core.internal.apk.v2.V2SchemeVerifier + +import java.nio.ByteBuffer +import java.nio.ByteOrder + +/** + * https://source.android.com/security/apksigning/v2.html + * https://en.wikipedia.org/wiki/Zip_(file_format) + * + */ +class ApkSigningBlock { + // The format of the APK Signing Block is as follows (all numeric fields are little-endian): + + // .size of block in bytes (excluding this field) (uint64) + // .Sequence of uint64-length-prefixed ID-value pairs: + // *ID (uint32) + // *value (variable-length: length of the pair - 4 bytes) + // .size of block in bytes—same as the very first field (uint64) + // .magic “APK Sig Block 42” (16 bytes) + + // FORMAT: + // OFFSET DATA TYPE DESCRIPTION + // * @+0 bytes uint64: size in bytes (excluding this field) + // * @+8 bytes payload + // * @-24 bytes uint64: size in bytes (same as the one above) + // * @-16 bytes uint128: magic + + // payload 有 8字节的大小,4字节的ID,还有payload的内容组成 + + private final List payloads; + + ApkSigningBlock() { + super(); + + payloads = new ArrayList<>(); + } + + public final List getPayloads() { + return payloads; + } + + public void addPayload(ApkSigningPayload payload) { + payloads.add(payload); + } + + public long writeApkSigningBlock(DataOutput dataOutput) { + long length = 24; + for (int index = 0; index < payloads.size(); ++index) { + ApkSigningPayload payload = payloads.get(index); + byte[] bytes = payload.getByteBuffer(); + length += 4 + 8 + bytes.length; + } + + ByteBuffer byteBuffer = ByteBuffer.allocate(Long.BYTES); + byteBuffer.order(ByteOrder.LITTLE_ENDIAN); + byteBuffer.putLong(length); + byteBuffer.flip(); + dataOutput.write(byteBuffer.array()); + + for (int index = 0; index < payloads.size(); ++index) { + ApkSigningPayload payload = payloads.get(index); + byte[] bytes = payload.getByteBuffer(); + + byteBuffer = ByteBuffer.allocate(Long.BYTES); + byteBuffer.order(ByteOrder.LITTLE_ENDIAN); + byteBuffer.putLong(bytes.length + (Long.BYTES - Integer.BYTES)); + byteBuffer.flip(); + dataOutput.write(byteBuffer.array()); + + byteBuffer = ByteBuffer.allocate(Integer.BYTES); + byteBuffer.order(ByteOrder.LITTLE_ENDIAN); + byteBuffer.putInt(payload.getId()); + byteBuffer.flip(); + dataOutput.write(byteBuffer.array()); + + dataOutput.write(bytes); + } + + byteBuffer = ByteBuffer.allocate(Long.BYTES); + byteBuffer.order(ByteOrder.LITTLE_ENDIAN); + byteBuffer.putLong(length); + byteBuffer.flip(); + dataOutput.write(byteBuffer.array()); + + byteBuffer = ByteBuffer.allocate(Long.BYTES); + byteBuffer.order(ByteOrder.LITTLE_ENDIAN); + byteBuffer.putLong(V2SchemeVerifier.APK_SIG_BLOCK_MAGIC_LO); + byteBuffer.flip(); + dataOutput.write(byteBuffer.array()); + + byteBuffer = ByteBuffer.allocate(Long.BYTES); + byteBuffer.order(ByteOrder.LITTLE_ENDIAN); + byteBuffer.putLong(V2SchemeVerifier.APK_SIG_BLOCK_MAGIC_HI); + byteBuffer.flip(); + dataOutput.write(byteBuffer.array()); + + return length; + } +} diff --git a/plugin/src/main/groovy/com/meituan/android/walle/ApkSigningPayload.groovy b/plugin/src/main/groovy/com/meituan/android/walle/ApkSigningPayload.groovy new file mode 100644 index 0000000..7c62731 --- /dev/null +++ b/plugin/src/main/groovy/com/meituan/android/walle/ApkSigningPayload.groovy @@ -0,0 +1,29 @@ +package com.meituan.android.walle + +import java.nio.ByteBuffer +import java.nio.ByteOrder + +class ApkSigningPayload { + private final int id; + private final ByteBuffer buffer + + ApkSigningPayload(int id, ByteBuffer buffer) { + super(); + this.id = id; + if (buffer.order() != ByteOrder.LITTLE_ENDIAN) { + throw new IllegalArgumentException("ByteBuffer byte order must be little endian"); + } + this.buffer = buffer; + } + + public int getId() { + return id; + } + + public byte[] getByteBuffer() { + final byte[] array = buffer.array(); + final int arrayOffset = buffer.arrayOffset(); + return Arrays.copyOfRange(array, arrayOffset + buffer.position(), + arrayOffset + buffer.limit()); ; + } +} diff --git a/plugin/src/main/groovy/com/meituan/android/walle/ChannelMaker.groovy b/plugin/src/main/groovy/com/meituan/android/walle/ChannelMaker.groovy new file mode 100644 index 0000000..e1b6226 --- /dev/null +++ b/plugin/src/main/groovy/com/meituan/android/walle/ChannelMaker.groovy @@ -0,0 +1,200 @@ +package com.meituan.android.walle + +import com.android.apksigner.core.ApkVerifier +import com.android.apksigner.core.apk.ApkUtils +import com.android.apksigner.core.internal.apk.v2.V2SchemeVerifier +import com.android.apksigner.core.internal.util.ByteBufferDataSource +import com.android.apksigner.core.internal.util.Pair +import com.android.apksigner.core.util.DataSource +import com.android.build.gradle.api.BaseVariant +import com.google.gson.JsonObject +import org.apache.commons.io.IOUtils +import org.gradle.api.DefaultTask +import org.gradle.api.GradleException +import org.gradle.api.Project +import org.gradle.api.tasks.TaskAction + +import java.nio.ByteBuffer +import java.nio.ByteOrder +import java.nio.channels.FileChannel + +class ChannelMaker extends DefaultTask { + public BaseVariant variant; + public Project project; + public File apkFile; + + public void setup() { + description "Make Multi-Channel" + group "Package" + } + + @TaskAction + public void packaging() { + if (apkFile == null || !apkFile.exists()) { + throw new GradleException("${apkFile} is not existed!"); + } + + ApkVerifier.Result result = verifyV2SignatureScheme(apkFile); + if (!result.verified || !result.verifiedUsingV2Scheme) { + throw new GradleException("${apkFile} has no v2 signature in Apk Signing Block!"); + } + + JsonObject jsonObject = new JsonObject(); + jsonObject.addProperty("channel", (variant.flavorName != null && variant.flavorName.length() > 0) ? variant.flavorName : 'undefined'); + jsonObject.addProperty("buildType:", variant.buildType.name); + jsonObject.addProperty("timestamp", System.currentTimeMillis()); + + addSaltForV2SignatureScheme(apkFile, jsonObject); + } + + ApkVerifier.Result verifyV2SignatureScheme(File apkFile) { + FileInputStream fIn; + FileChannel fChan; + long fSize; + ByteBuffer byteBuffer; + + ApkVerifier.Result result = new ApkVerifier.Result(); + try { + fIn = new FileInputStream(apkFile); + fChan = fIn.getChannel(); + fSize = fChan.size(); + byteBuffer = ByteBuffer.allocate((int) fSize); + fChan.read(byteBuffer); + byteBuffer.rewind(); + + ApkVerifier apkVerifier = new ApkVerifier(); + + result = apkVerifier.verify(new ByteBufferDataSource(byteBuffer), 0); + } catch (IOException ignore) { + ignore.printStackTrace(); + } finally { + IOUtils.closeQuietly(fChan); + IOUtils.closeQuietly(fIn); + } + + return result; + } + + void addSaltForV2SignatureScheme(File apkFile, JsonObject jsonObject) { + FileInputStream fIn; + FileChannel fChan; + long fSize; + ByteBuffer byteBuffer; + + ApkSigningBlock apkSigningBlock = new ApkSigningBlock(); + long centralDirStartOffset = 0; + long apkSigningBlockOffset = 0; + try { + fIn = new FileInputStream(apkFile); + fChan = fIn.getChannel(); + fSize = fChan.size(); + byteBuffer = ByteBuffer.allocate((int) fSize); + fChan.read(byteBuffer); + byteBuffer.rewind(); + + byte[] zipData = byteBuffer.array(); + + // For a zip with no archive comment, the + // end-of-central-directory record will be 22 bytes long, so + // we expect to find the EOCD marker 22 bytes from the end. + if (zipData[zipData.length - 22] != 0x50 || + zipData[zipData.length - 21] != 0x4b || + zipData[zipData.length - 20] != 0x05 || + zipData[zipData.length - 19] != 0x06) { + throw new IllegalArgumentException("zip data already has an archive comment"); + } + + + V2SchemeVerifier.Result result = new V2SchemeVerifier.Result(); + + DataSource apk = new ByteBufferDataSource(byteBuffer); + ApkUtils.ZipSections zipSections = ApkUtils.findZipSections(apk); + + centralDirStartOffset = zipSections.getZipCentralDirectoryOffset(); + long centralDirEndOffset = + centralDirStartOffset + zipSections.getZipCentralDirectorySizeBytes(); + long eocdStartOffset = zipSections.getZipEndOfCentralDirectoryOffset(); + if (centralDirEndOffset != eocdStartOffset) { + throw new V2SchemeVerifier.SignatureNotFoundException( + "ZIP Central Directory is not immediately followed by End of Central Directory" + + ". CD end: " + centralDirEndOffset + + ", EoCD start: " + eocdStartOffset); + } + + // Find the APK Signing Block. The block immediately precedes the Central Directory. + ByteBuffer eocd = zipSections.getZipEndOfCentralDirectory(); + Pair apkSigningBlockAndOffset = + V2SchemeVerifier.findApkSigningBlock(apk, centralDirStartOffset); + ByteBuffer apkSigningBlock2 = apkSigningBlockAndOffset.getFirst(); + apkSigningBlockOffset = apkSigningBlockAndOffset.getSecond(); + + // Find the APK Signature Scheme v2 Block inside the APK Signing Block. + ByteBuffer apkSignatureSchemeV2Block = + V2SchemeVerifier.findApkSignatureSchemeV2Block(apkSigningBlock2, result); + + ApkSigningPayload payload = new ApkSigningPayload(V2SchemeVerifier.APK_SIGNATURE_SCHEME_V2_BLOCK_ID, apkSignatureSchemeV2Block); + apkSigningBlock.addPayload(payload); + } catch (IOException ignore) { + ignore.printStackTrace(); + } finally { + IOUtils.closeQuietly(fChan); + IOUtils.closeQuietly(fIn); + } + + def salt = jsonObject.toString(); + println "********* add ID-value ${salt} to Apk Signing Block."; + byte[] bytes = salt.bytes; + ByteBuffer byteBuffer1 = ByteBuffer.allocate(bytes.length); + byteBuffer1.order(ByteOrder.LITTLE_ENDIAN); + byteBuffer1.put(bytes, 0, bytes.length); + byteBuffer1.flip(); + ApkSigningPayload payload = new ApkSigningPayload(0xff01, byteBuffer1); + apkSigningBlock.addPayload(payload); + + if (!apkSigningBlock.getPayloads().isEmpty() && apkSigningBlockOffset != 0 && centralDirStartOffset != 0) { + RandomAccessFile randomAccessFile = null; + try { + randomAccessFile = new RandomAccessFile(apkFile, "rw"); + + randomAccessFile.seek(centralDirStartOffset); + // 读取CentralDir + byte[] centralDirBytes = new byte[randomAccessFile.getChannel().size() - centralDirStartOffset]; + randomAccessFile.read(centralDirBytes); + + randomAccessFile.setLength(apkSigningBlockOffset); + randomAccessFile.seek(apkSigningBlockOffset); + + long length = apkSigningBlock.writeApkSigningBlock(randomAccessFile); + + // 存储CentralDir + randomAccessFile.write(centralDirBytes); + + // 更新CentralDir Offset + + // End of central directory record (EOCD) + // Offset Bytes Description[23] + // 0 4 End of central directory signature = 0x06054b50 + // 4 2 Number of this disk + // 6 2 Disk where central directory starts + // 8 2 Number of central directory records on this disk + // 10 2 Total number of central directory records + // 12 4 Size of central directory (bytes) + // 16 4 Offset of start of central directory, relative to start of archive + // 20 2 Comment length (n) + // 22 n Comment + + randomAccessFile.seek(randomAccessFile.getChannel().size() - 6); + ByteBuffer temp = ByteBuffer.allocate(Integer.BYTES); + temp.order(ByteOrder.LITTLE_ENDIAN); + temp.putInt((int) (centralDirStartOffset + length + 8 - (centralDirStartOffset - apkSigningBlockOffset))); + temp.flip(); + randomAccessFile.write(temp.array()); + + } catch (IOException ignore) { + ignore.printStackTrace(); + } finally { + IOUtils.closeQuietly(randomAccessFile); + } + } + } +} diff --git a/plugin/src/main/groovy/com/meituan/android/walle/GradlePlugin.groovy b/plugin/src/main/groovy/com/meituan/android/walle/GradlePlugin.groovy new file mode 100644 index 0000000..879d028 --- /dev/null +++ b/plugin/src/main/groovy/com/meituan/android/walle/GradlePlugin.groovy @@ -0,0 +1,124 @@ +package com.meituan.android.walle + +import com.android.build.gradle.api.BaseVariant +import com.android.builder.Version +import com.android.builder.model.SigningConfig +import org.gradle.api.GradleException +import org.gradle.api.Project +import org.gradle.api.ProjectConfigurationException + +class GradlePlugin implements org.gradle.api.Plugin { + + public static final String sPluginExtensionName = "walle"; + + @Override + void apply(Project project) { + if (!project.plugins.hasPlugin("com.android.application")) { + throw new ProjectConfigurationException("Plugin requires the 'com.android.application' plugin to be configured.", null); + } + + if (versionCompare(Version.getAndroidGradlePluginVersion(), "2.2.0") < 0) { + throw new ProjectConfigurationException("Plugin requires the 'com.android.tools.build:gradle' version 2.2.0 or above to be configured.", null); + } + + applyExtension(project); + + applyTask(project); + } + + void applyTask(Project project) { + project.afterEvaluate { + project.android.applicationVariants.all { BaseVariant variant -> + def variantName = variant.name.capitalize(); + + if (!isV2SignatureSchemeEnabled(variant)) { + throw new ProjectConfigurationException("Plugin requires 'APK Signature Scheme v2 Enabled' for ${variant.name}.", null); + } + + ChannelMaker channelMaker = project.tasks.create("assemble${variantName}V2SignatureSchemeChannel", ChannelMaker); + def File apkFile = variant.outputs[0].outputFile + channelMaker.project = project; + channelMaker.variant = variant; + channelMaker.apkFile = apkFile; + channelMaker.setup(); + + variant.assemble.finalizedBy channelMaker; + } + } + } + + SigningConfig getSigningConfig(BaseVariant variant) { + return variant.buildType.signingConfig == null ? variant.mergedFlavor.signingConfig : variant.buildType.signingConfig; + } + + boolean isV2SignatureSchemeEnabled(BaseVariant variant) throws GradleException { + def signingConfig = getSigningConfig(variant); + if (signingConfig == null) { + return false; + } + + // check whether APK Signature Scheme v2 is enabled. + if (signingConfig.hasProperty("v2SigningEnabled") && + signingConfig.v2SigningEnabled == true) { + return true; + } + + return false; + } + + /** + * Compares two version strings. + * + * Use this instead of String.compareTo() for a non-lexicographical + * comparison that works for version strings. e.g. "1.10".compareTo("1.6"). + * + * @note It does not work if "1.10" is supposed to be equal to "1.10.0". + * + * @param str1 a string of ordinal numbers separated by decimal points. + * @param str2 a string of ordinal numbers separated by decimal points. + * @return The result is a negative integer if str1 is _numerically_ less than str2. + * The result is a positive integer if str1 is _numerically_ greater than str2. + * The result is zero if the strings are _numerically_ equal. + */ + private static int versionCompare(String str1, String str2) { + String[] vals1 = str1.split("-")[0].split("\\."); + String[] vals2 = str2.split("-")[0].split("\\."); + int i = 0; + // set index to first non-equal ordinal or length of shortest version string + while (i < vals1.length && i < vals2.length && vals1[i].equals(vals2[i])) { + i++; + } + + // compare first non-equal ordinal number + if (i < vals1.length && i < vals2.length) { + int diff = Integer.valueOf(vals1[i]).compareTo(Integer.valueOf(vals2[i])); + return Integer.signum(diff); + } + + // the strings are equal or one string is a substring of the other + // e.g. "1.2.3" = "1.2.3" or "1.2.3" < "1.2.3.4" + else { + return Integer.signum(vals1.length - vals2.length); + } + } + + void applyExtension(Project project) { + project.extensions.create(sPluginExtensionName, Extension); + } + + public static class Extension { + + Extension() { + } + + public static Extension getConfig(Project project) { + Extension config = + project.getExtensions().findByType(Extension.class); + if (config == null) { + config = new Extension(); + } + return config; + } + + } +} diff --git a/plugin/src/main/java/com/android/apksigner/core/ApkSignerEngine.java b/plugin/src/main/java/com/android/apksigner/core/ApkSignerEngine.java new file mode 100644 index 0000000..a0c77f9 --- /dev/null +++ b/plugin/src/main/java/com/android/apksigner/core/ApkSignerEngine.java @@ -0,0 +1,407 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.apksigner.core; + +import java.io.Closeable; +import java.io.IOException; +import java.security.InvalidKeyException; +import java.security.SignatureException; +import java.util.List; + +import com.android.apksigner.core.util.DataSink; +import com.android.apksigner.core.util.DataSource; + +/** + * APK signing logic which is independent of how input and output APKs are stored, parsed, and + * generated. + * + *

Operating Model

+ * + * The abstract operating model is that there is an input APK which is being signed, thus producing + * an output APK. In reality, there may be just an output APK being built from scratch, or the input APK and + * the output APK may be the same file. Because this engine does not deal with reading and writing + * files, it can handle all of these scenarios. + * + *

In the engine's operating model, a signed APK is produced as follows. + *

    + *
  1. JAR entries to be signed are output,
  2. + *
  3. JAR archive is signed using JAR signing, thus adding the so-called v1 signature to the + * output,
  4. + *
  5. JAR archive is signed using APK Signature Scheme v2, thus adding the so-called v2 signature + * to the output.
  6. + *
+ * + *

The input APK may contain JAR entries which, depending on the engine's configuration, may or + * may not be output (e.g., existing signatures may need to be preserved or stripped) or which the + * engine will overwrite as part of signing. The engine thus offers {@link #inputJarEntry(String)} + * which tells the client whether the input JAR entry needs to be output. This avoids the need for + * the client to hard-code the aspects of APK signing which determine which parts of input must be + * ignored. Similarly, the engine offers {@link #inputApkSigningBlock(DataSource)} to help the + * client avoid dealing with preserving or stripping APK Signature Scheme v2 signature of the input + * APK. + * + *

To use the engine to sign an input APK (or a collection of JAR entries), follow these + * steps: + *

    + *
  1. Obtain a new instance of the engine -- engine instances are stateful and thus cannot be used + * for signing multiple APKs.
  2. + *
  3. Locate the input APK's APK Signing Block and provide it to + * {@link #inputApkSigningBlock(DataSource)}.
  4. + *
  5. For each JAR entry in the input APK, invoke {@link #inputJarEntry(String)} to determine + * whether this entry should be output. The engine may request to inspect the entry.
  6. + *
  7. For each output JAR entry, invoke {@link #outputJarEntry(String)} which may request to + * inspect the entry.
  8. + *
  9. Once all JAR entries have been output, invoke {@link #outputJarEntries()} which may request + * that additional JAR entries are output. These entries comprise the output APK's JAR + * signature.
  10. + *
  11. Locate the ZIP Central Directory and ZIP End of Central Directory sections in the output and + * invoke {@link #outputZipSections(DataSource, DataSource, DataSource)} which may request that + * an APK Signature Block is inserted before the ZIP Central Directory. The block contains the + * output APK's APK Signature Scheme v2 signature.
  12. + *
  13. Invoke {@link #outputDone()} to signal that the APK was output in full. The engine will + * confirm that the output APK is signed.
  14. + *
  15. Invoke {@link #close()} to signal that the engine will no longer be used. This lets the + * engine free any resources it no longer needs. + *
+ * + *

Some invocations of the engine may provide the client with a task to perform. The client is + * expected to perform all requested tasks before proceeding to the next stage of signing. See + * documentation of each method about the deadlines for performing the tasks requested by the + * method. + * + *

Incremental Operation

+ * + * The engine supports incremental operation where a signed APK is produced, then modified and + * re-signed. This may be useful for IDEs, where an app is frequently re-signed after small changes + * by the developer. Re-signing may be more efficient than signing from scratch. + * + *

To use the engine in incremental mode, keep notifying the engine of changes to the APK through + * {@link #inputApkSigningBlock(DataSource)}, {@link #inputJarEntry(String)}, + * {@link #inputJarEntryRemoved(String)}, {@link #outputJarEntry(String)}, + * and {@link #outputJarEntryRemoved(String)}, perform the tasks requested by the engine through + * these methods, and, when a new signed APK is desired, run through steps 5 onwards to re-sign the + * APK. + * + *

Output-only Operation

+ * + * The engine's abstract operating model consists of an input APK and an output APK. However, it is + * possible to use the engine in output-only mode where the engine's {@code input...} methods are + * not invoked. In this mode, the engine has less control over output because it cannot request that + * some JAR entries are not output. Nevertheless, the engine will attempt to make the output APK + * signed and will report an error if cannot do so. + */ +public interface ApkSignerEngine extends Closeable { + + /** + * Indicates to this engine that the input APK contains the provided APK Signing Block. The + * block may contain signatures of the input APK, such as APK Signature Scheme v2 signatures. + * + * @param apkSigningBlock APK signing block of the input APK. The provided data source is + * guaranteed to not be used by the engine after this method terminates. + * + * @throws IllegalStateException if this engine is closed + */ + void inputApkSigningBlock(DataSource apkSigningBlock) throws IllegalStateException; + + /** + * Indicates to this engine that the specified JAR entry was encountered in the input APK. + * + *

When an input entry is updated/changed, it's OK to not invoke + * {@link #inputJarEntryRemoved(String)} before invoking this method. + * + * @return instructions about how to proceed with this entry + * + * @throws IllegalStateException if this engine is closed + */ + InputJarEntryInstructions inputJarEntry(String entryName) throws IllegalStateException; + + /** + * Indicates to this engine that the specified JAR entry was output. + * + *

It is unnecessary to invoke this method for entries added to output by this engine (e.g., + * requested by {@link #outputJarEntries()}) provided the entries were output with exactly the + * data requested by the engine. + * + *

When an already output entry is updated/changed, it's OK to not invoke + * {@link #outputJarEntryRemoved(String)} before invoking this method. + * + * @return request to inspect the entry or {@code null} if the engine does not need to inspect + * the entry. The request must be fulfilled before {@link #outputJarEntries()} is + * invoked. + * + * @throws IllegalStateException if this engine is closed + */ + InspectJarEntryRequest outputJarEntry(String entryName) throws IllegalStateException; + + /** + * Indicates to this engine that the specified JAR entry was removed from the input. It's safe + * to invoke this for entries for which {@link #inputJarEntry(String)} hasn't been invoked. + * + * @return output policy of this JAR entry. The policy indicates how this input entry affects + * the output APK. The client of this engine should use this information to determine + * how the removal of this input APK's JAR entry affects the output APK. + * + * @throws IllegalStateException if this engine is closed + */ + InputJarEntryInstructions.OutputPolicy inputJarEntryRemoved(String entryName) + throws IllegalStateException; + + /** + * Indicates to this engine that the specified JAR entry was removed from the output. It's safe + * to invoke this for entries for which {@link #outputJarEntry(String)} hasn't been invoked. + * + * @throws IllegalStateException if this engine is closed + */ + void outputJarEntryRemoved(String entryName) throws IllegalStateException; + + /** + * Indicates to this engine that all JAR entries have been output. + * + * + * @return request to add JAR signature to the output or {@code null} if there is no need to add + * a JAR signature. The request will contain additional JAR entries to be output. The + * request must be fulfilled before + * {@link #outputZipSections(DataSource, DataSource, DataSource)} is invoked. + * + * @throws InvalidKeyException if a signature could not be generated because a signing key is + * not suitable for generating the signature + * @throws SignatureException if an error occurred while generating the JAR signature + * @throws IllegalStateException if there are unfulfilled requests, such as to inspect some JAR + * entries, or if the engine is closed + */ + OutputJarSignatureRequest outputJarEntries() throws InvalidKeyException, SignatureException; + + /** + * Indicates to this engine that the ZIP sections comprising the output APK have been output. + * + *

The provided data sources are guaranteed to not be used by the engine after this method + * terminates. + * + * @param zipEntries the section of ZIP archive containing Local File Header records and data of + * the ZIP entries. In a well-formed archive, this section starts at the start of the + * archive and extends all the way to the ZIP Central Directory. + * @param zipCentralDirectory ZIP Central Directory section + * @param zipEocd ZIP End of Central Directory (EoCD) record + * + * @return request to add an APK Signing Block to the output or {@code null} if the output must + * not contain an APK Signing Block. The request must be fulfilled before + * {@link #outputDone()} is invoked. + * + * @throws IOException if an I/O error occurs while reading the provided ZIP sections + * @throws InvalidKeyException if a signature could not be generated because a signing key is + * not suitable for generating the signature + * @throws SignatureException if an error occurred while generating the APK's signature + * @throws IllegalStateException if there are unfulfilled requests, such as to inspect some JAR + * entries or to output JAR signature, or if the engine is closed + */ + OutputApkSigningBlockRequest outputZipSections( + DataSource zipEntries, + DataSource zipCentralDirectory, + DataSource zipEocd) throws IOException, InvalidKeyException, SignatureException; + + /** + * Indicates to this engine that the signed APK was output. + * + *

This does not change the output APK. The method helps the client confirm that the current + * output is signed. + * + * @throws IllegalStateException if there are unfulfilled requests, such as to inspect some JAR + * entries or to output signatures, or if the engine is closed + */ + void outputDone() throws IllegalStateException; + + /** + * Indicates to this engine that it will no longer be used. Invoking this on an already closed + * engine is OK. + * + *

This does not change the output APK. For example, if the output APK is not yet fully + * signed, it will remain so after this method terminates. + */ + @Override + void close(); + + /** + * Instructions about how to handle an input APK's JAR entry. + * + *

The instructions indicate whether to output the entry (see {@link #getOutputPolicy()}) and + * may contain a request to inspect the entry (see {@link #getInspectJarEntryRequest()}), in + * which case the request must be fulfilled before {@link ApkSignerEngine#outputJarEntries()} is + * invoked. + */ + public static class InputJarEntryInstructions { + private final OutputPolicy mOutputPolicy; + private final InspectJarEntryRequest mInspectJarEntryRequest; + + /** + * Constructs a new {@code InputJarEntryInstructions} instance with the provided entry + * output policy and without a request to inspect the entry. + */ + public InputJarEntryInstructions(OutputPolicy outputPolicy) { + this(outputPolicy, null); + } + + /** + * Constructs a new {@code InputJarEntryInstructions} instance with the provided entry + * output mode and with the provided request to inspect the entry. + * + * @param inspectJarEntryRequest request to inspect the entry or {@code null} if there's no + * need to inspect the entry. + */ + public InputJarEntryInstructions( + OutputPolicy outputPolicy, + InspectJarEntryRequest inspectJarEntryRequest) { + mOutputPolicy = outputPolicy; + mInspectJarEntryRequest = inspectJarEntryRequest; + } + + /** + * Returns the output policy for this entry. + */ + public OutputPolicy getOutputPolicy() { + return mOutputPolicy; + } + + /** + * Returns the request to inspect the JAR entry or {@code null} if there is no need to + * inspect the entry. + */ + public InspectJarEntryRequest getInspectJarEntryRequest() { + return mInspectJarEntryRequest; + } + + /** + * Output policy for an input APK's JAR entry. + */ + public static enum OutputPolicy { + /** Entry must not be output. */ + SKIP, + + /** Entry should be output. */ + OUTPUT, + + /** Entry will be output by the engine. The client can thus ignore this input entry. */ + OUTPUT_BY_ENGINE, + } + } + + /** + * Request to inspect the specified JAR entry. + * + *

The entry's uncompressed data must be provided to the data sink returned by + * {@link #getDataSink()}. Once the entry's data has been provided to the sink, {@link #done()} + * must be invoked. + */ + interface InspectJarEntryRequest { + + /** + * Returns the data sink into which the entry's uncompressed data should be sent. + */ + DataSink getDataSink(); + + /** + * Indicates that entry's data has been provided in full. + */ + void done(); + + /** + * Returns the name of the JAR entry. + */ + String getEntryName(); + } + + /** + * Request to add JAR signature (aka v1 signature) to the output APK. + * + *

Entries listed in {@link #getAdditionalJarEntries()} must be added to the output APK after + * which {@link #done()} must be invoked. + */ + interface OutputJarSignatureRequest { + + /** + * Returns JAR entries that must be added to the output APK. + */ + List getAdditionalJarEntries(); + + /** + * Indicates that the JAR entries contained in this request were added to the output APK. + */ + void done(); + + /** + * JAR entry. + */ + public static class JarEntry { + private final String mName; + private final byte[] mData; + + /** + * Constructs a new {@code JarEntry} with the provided name and data. + * + * @param data uncompressed data of the entry. Changes to this array will not be + * reflected in {@link #getData()}. + */ + public JarEntry(String name, byte[] data) { + mName = name; + mData = data.clone(); + } + + /** + * Returns the name of this ZIP entry. + */ + public String getName() { + return mName; + } + + /** + * Returns the uncompressed data of this JAR entry. + */ + public byte[] getData() { + return mData.clone(); + } + } + } + + /** + * Request to add the specified APK Signing Block to the output APK. APK Signature Scheme v2 + * signature(s) of the APK are contained in this block. + * + *

The APK Signing Block returned by {@link #getApkSigningBlock()} must be placed into the + * output APK such that the block is immediately before the ZIP Central Directory, the offset of + * ZIP Central Directory in the ZIP End of Central Directory record must be adjusted + * accordingly, and then {@link #done()} must be invoked. + * + *

If the output contains an APK Signing Block, that block must be replaced by the block + * contained in this request. + */ + interface OutputApkSigningBlockRequest { + + /** + * Returns the APK Signing Block. + */ + byte[] getApkSigningBlock(); + + /** + * Indicates that the APK Signing Block was output as requested. + */ + void done(); + } +} diff --git a/plugin/src/main/java/com/android/apksigner/core/ApkVerifier.java b/plugin/src/main/java/com/android/apksigner/core/ApkVerifier.java new file mode 100644 index 0000000..931c7b2 --- /dev/null +++ b/plugin/src/main/java/com/android/apksigner/core/ApkVerifier.java @@ -0,0 +1,458 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.apksigner.core; + +import com.android.apksigner.core.apk.ApkUtils; +import com.android.apksigner.core.internal.apk.v2.ContentDigestAlgorithm; +import com.android.apksigner.core.internal.apk.v2.SignatureAlgorithm; +import com.android.apksigner.core.internal.apk.v2.V2SchemeVerifier; +import com.android.apksigner.core.util.DataSource; +import com.android.apksigner.core.zip.ZipFormatException; + +import java.io.IOException; +import java.security.cert.X509Certificate; +import java.util.ArrayList; +import java.util.List; + +/** + * APK signature verifier which mimics the behavior of the Android platform. + * + *

The verifier is designed to closely mimic the behavior of Android platforms. This is to enable + * the verifier to be used for checking whether an APK's signatures will verify on Android. + */ +public class ApkVerifier { + + /** + * Verifies the APK's signatures and returns the result of verification. The APK can be + * considered verified iff the result's {@link Result#isVerified()} returns {@code true}. + * The verification result also includes errors, warnings, and information about signers. + * + * @param apk APK file contents + * @param minSdkVersion API Level of the oldest Android platform on which the APK's signatures + * may need to be verified + * + * @throws IOException if an I/O error is encountered while reading the APK + * @throws ZipFormatException if the APK is malformed at ZIP format level + */ + public Result verify(DataSource apk, int minSdkVersion) throws IOException, ZipFormatException { + ApkUtils.ZipSections zipSections = ApkUtils.findZipSections(apk); + + // Attempt to verify the APK using APK Signature Scheme v2 + Result result = new Result(); + try { + V2SchemeVerifier.Result v2Result = V2SchemeVerifier.verify(apk, zipSections); + result.mergeFrom(v2Result); + } catch (V2SchemeVerifier.SignatureNotFoundException ignored) {} + if (result.containsErrors()) { + return result; + } + + // TODO: Verify JAR signature if necessary + if (!result.isVerifiedUsingV2Scheme()) { + return result; + } + + // Verified + result.setVerified(); + for (Result.V2SchemeSignerInfo signerInfo : result.getV2SchemeSigners()) { + result.addSignerCertificate(signerInfo.getCertificate()); + } + + return result; + } + + /** + * Result of verifying an APKs signatures. The APK can be considered verified iff + * {@link #isVerified()} returns {@code true}. + */ + public static class Result { + private final List mErrors = new ArrayList<>(); + private final List mWarnings = new ArrayList<>(); + private final List mSignerCerts = new ArrayList<>(); + private final List mV2SchemeSigners = new ArrayList<>(); + + private boolean mVerified; + private boolean mVerifiedUsingV2Scheme; + + /** + * Returns {@code true} if the APK's signatures verified. + */ + public boolean isVerified() { + return mVerified; + } + + private void setVerified() { + mVerified = true; + } + + /** + * Returns {@code true} if the APK's APK Signature Scheme v2 signatures verified. + */ + public boolean isVerifiedUsingV2Scheme() { + return mVerifiedUsingV2Scheme; + } + + /** + * Returns the verified signers' certificates, one per signer. + */ + public List getSignerCertificates() { + return mSignerCerts; + } + + private void addSignerCertificate(X509Certificate cert) { + mSignerCerts.add(cert); + } + + /** + * Returns information about APK Signature Scheme v2 signers associated with the APK's + * signature. + */ + public List getV2SchemeSigners() { + return mV2SchemeSigners; + } + + /** + * Returns errors encountered while verifying the APK's signatures. + */ + public List getErrors() { + return mErrors; + } + + /** + * Returns warnings encountered while verifying the APK's signatures. + */ + public List getWarnings() { + return mWarnings; + } + + private void mergeFrom(V2SchemeVerifier.Result source) { + mVerifiedUsingV2Scheme = source.verified; + mErrors.addAll(source.getErrors()); + mWarnings.addAll(source.getWarnings()); + for (V2SchemeVerifier.Result.SignerInfo signer : source.signers) { + mV2SchemeSigners.add(new V2SchemeSignerInfo(signer)); + } + } + + /** + * Returns {@code true} if an error was encountered while verifying the APK. Any error + * prevents the APK from being considered verified. + */ + public boolean containsErrors() { + if (!mErrors.isEmpty()) { + return true; + } + if (!mV2SchemeSigners.isEmpty()) { + for (V2SchemeSignerInfo signer : mV2SchemeSigners) { + if (signer.containsErrors()) { + return true; + } + } + } + + return false; + } + + /** + * Information about an APK Signature Scheme v2 signer associated with the APK's signature. + */ + public static class V2SchemeSignerInfo { + private final int mIndex; + private final List mCerts; + + private final List mErrors; + private final List mWarnings; + + private V2SchemeSignerInfo(V2SchemeVerifier.Result.SignerInfo result) { + mIndex = result.index; + mCerts = result.certs; + mErrors = result.getErrors(); + mWarnings = result.getWarnings(); + } + + /** + * Returns this signer's {@code 0}-based index in the list of signers contained in the + * APK's APK Signature Scheme v2 signature. + */ + public int getIndex() { + return mIndex; + } + + /** + * Returns this signer's signing certificate or {@code null} if not available. The + * certificate is guaranteed to be available if no errors were encountered during + * verification (see {@link #containsErrors()}. + * + *

This certificate contains the signer's public key. + */ + public X509Certificate getCertificate() { + return mCerts.isEmpty() ? null : mCerts.get(0); + } + + /** + * Returns this signer's certificates. The first certificate is for the signer's public + * key. An empty list may be returned if an error was encountered during verification + * (see {@link #containsErrors()}). + */ + public List getCertificates() { + return mCerts; + } + + public boolean containsErrors() { + return !mErrors.isEmpty(); + } + + public List getErrors() { + return mErrors; + } + + public List getWarnings() { + return mWarnings; + } + } + } + + /** + * Error or warning encountered while verifying an APK's signatures. + */ + public static enum Issue { + + /** + * Failed to parse the list of signers contained in the APK Signature Scheme v2 signature. + */ + V2_SIG_MALFORMED_SIGNERS("Malformed list of signers"), + + /** + * Failed to parse this signer's signer block contained in the APK Signature Scheme v2 + * signature. + */ + V2_SIG_MALFORMED_SIGNER("Malformed signer block"), + + /** + * Public key embedded in the APK Signature Scheme v2 signature of this signer could not be + * parsed. + * + *

    + *
  • Parameter 1: error details ({@code Throwable})
  • + *
+ */ + V2_SIG_MALFORMED_PUBLIC_KEY("Malformed public key: %1$s"), + + /** + * This APK Signature Scheme v2 signer's certificate could not be parsed. + * + *
    + *
  • Parameter 1: index ({@code 0}-based) of the certificate in the signer's list of + * certificates ({@code Integer})
  • + *
  • Parameter 2: sequence number ({@code 1}-based) of the certificate in the signer's + * list of certificates ({@code Integer})
  • + *
  • Parameter 3: error details ({@code Throwable})
  • + *
+ */ + V2_SIG_MALFORMED_CERTIFICATE("Malformed certificate #%2$d: %3$s"), + + /** + * Failed to parse this signer's signature record contained in the APK Signature Scheme v2 + * signature. + * + *
    + *
  • Parameter 1: record number (first record is {@code 1}) ({@code Integer})
  • + *
+ */ + V2_SIG_MALFORMED_SIGNATURE("Malformed APK Signature Scheme v2 signature record #%1$d"), + + /** + * Failed to parse this signer's digest record contained in the APK Signature Scheme v2 + * signature. + * + *
    + *
  • Parameter 1: record number (first record is {@code 1}) ({@code Integer})
  • + *
+ */ + V2_SIG_MALFORMED_DIGEST("Malformed APK Signature Scheme v2 digest record #%1$d"), + + /** + * This APK Signature Scheme v2 signer contains a malformed additional attribute. + * + *
    + *
  • Parameter 1: attribute number (first attribute is {@code 1}) {@code Integer})
  • + *
+ */ + V2_SIG_MALFORMED_ADDITIONAL_ATTRIBUTE("Malformed additional attribute #%1$d"), + + /** + * APK Signature Scheme v2 signature contains no signers. + */ + V2_SIG_NO_SIGNERS("No signers in APK Signature Scheme v2 signature"), + + /** + * This APK Signature Scheme v2 signer contains a signature produced using an unknown + * algorithm. + * + *
    + *
  • Parameter 1: algorithm ID ({@code Integer})
  • + *
+ */ + V2_SIG_UNKNOWN_SIG_ALGORITHM("Unknown signature algorithm: %1$#x"), + + /** + * This APK Signature Scheme v2 signer contains an unknown additional attribute. + * + *
    + *
  • Parameter 1: attribute ID ({@code Integer})
  • + *
+ */ + V2_SIG_UNKNOWN_ADDITIONAL_ATTRIBUTE("Unknown additional attribute: ID %1$#x"), + + /** + * An exception was encountered while verifying APK Signature Scheme v2 signature of this + * signer. + * + *
    + *
  • Parameter 1: signature algorithm ({@link SignatureAlgorithm})
  • + *
  • Parameter 2: exception ({@code Throwable})
  • + *
+ */ + V2_SIG_VERIFY_EXCEPTION("Failed to verify %1$s signature: %2$s"), + + /** + * APK Signature Scheme v2 signature over this signer's signed-data block did not verify. + * + *
    + *
  • Parameter 1: signature algorithm ({@link SignatureAlgorithm})
  • + *
+ */ + V2_SIG_DID_NOT_VERIFY("%1$s signature over signed-data did not verify"), + + /** + * This APK Signature Scheme v2 signer offers no signatures. + */ + V2_SIG_NO_SIGNATURES("No signatures"), + + /** + * This APK Signature Scheme v2 signer offers signatures but none of them are supported. + */ + V2_SIG_NO_SUPPORTED_SIGNATURES("No supported signatures"), + + /** + * This APK Signature Scheme v2 signer offers no certificates. + */ + V2_SIG_NO_CERTIFICATES("No certificates"), + + /** + * This APK Signature Scheme v2 signer's public key listed in the signer's certificate does + * not match the public key listed in the signatures record. + * + *
    + *
  • Parameter 1: hex-encoded public key from certificate ({@code String})
  • + *
  • Parameter 2: hex-encoded public key from signatures record ({@code String})
  • + *
+ */ + V2_SIG_PUBLIC_KEY_MISMATCH_BETWEEN_CERTIFICATE_AND_SIGNATURES_RECORD( + "Public key mismatch between certificate and signature record: <%1$s> vs <%2$s>"), + + /** + * This APK Signature Scheme v2 signer's signature algorithms listed in the signatures + * record do not match the signature algorithms listed in the signatures record. + * + *
    + *
  • Parameter 1: signature algorithms from signatures record ({@code List})
  • + *
  • Parameter 2: signature algorithms from digests record ({@code List})
  • + *
+ */ + V2_SIG_SIG_ALG_MISMATCH_BETWEEN_SIGNATURES_AND_DIGESTS_RECORDS( + "Signature algorithms mismatch between signatures and digests records" + + ": %1$s vs %2$s"), + + /** + * The APK's digest does not match the digest contained in the APK Signature Scheme v2 + * signature. + * + *
    + *
  • Parameter 1: content digest algorithm ({@link ContentDigestAlgorithm})
  • + *
  • Parameter 2: hex-encoded expected digest of the APK ({@code String})
  • + *
  • Parameter 3: hex-encoded actual digest of the APK ({@code String})
  • + *
+ */ + V2_SIG_APK_DIGEST_DID_NOT_VERIFY( + "APK integrity check failed. %1$s digest mismatch." + + " Expected: <%2$s>, actual: <%3$s>"), + + /** + * APK Signing Block contains an unknown entry. + * + *
    + *
  • Parameter 1: entry ID ({@code Integer})
  • + *
+ */ + APK_SIG_BLOCK_UNKNOWN_ENTRY_ID("APK Signing Block contains unknown entry: ID %1$#x"); + + private final String mFormat; + + private Issue(String format) { + mFormat = format; + } + + /** + * Returns the format string suitable for combining the parameters of this issue into a + * readable string. See {@link java.util.Formatter} for format. + */ + private String getFormat() { + return mFormat; + } + } + + /** + * {@link Issue} with associated parameters. {@link #toString()} produces a readable formatted + * form. + */ + public static class IssueWithParams { + private final Issue mIssue; + private final Object[] mParams; + + /** + * Constructs a new {@code IssueWithParams} of the specified type and with provided + * parameters. + */ + public IssueWithParams(Issue issue, Object[] params) { + mIssue = issue; + mParams = params; + } + + /** + * Returns the type of this issue. + */ + public Issue getIssue() { + return mIssue; + } + + /** + * Returns the parameters of this issue. + */ + public Object[] getParams() { + return mParams.clone(); + } + + /** + * Returns a readable form of this issue. + */ + @Override + public String toString() { + return String.format(mIssue.getFormat(), mParams); + } + } +} diff --git a/plugin/src/main/java/com/android/apksigner/core/DefaultApkSignerEngine.java b/plugin/src/main/java/com/android/apksigner/core/DefaultApkSignerEngine.java new file mode 100644 index 0000000..612f4fd --- /dev/null +++ b/plugin/src/main/java/com/android/apksigner/core/DefaultApkSignerEngine.java @@ -0,0 +1,893 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.apksigner.core; + +import com.android.apksigner.core.internal.apk.v1.DigestAlgorithm; +import com.android.apksigner.core.internal.apk.v1.V1SchemeSigner; +import com.android.apksigner.core.internal.apk.v2.V2SchemeSigner; +import com.android.apksigner.core.internal.util.ByteArrayOutputStreamSink; +import com.android.apksigner.core.internal.util.MessageDigestSink; +import com.android.apksigner.core.internal.util.Pair; +import com.android.apksigner.core.util.DataSink; +import com.android.apksigner.core.util.DataSource; + +import java.io.IOException; +import java.security.InvalidKeyException; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.security.SignatureException; +import java.security.cert.CertificateEncodingException; +import java.security.cert.X509Certificate; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * Default implementation of {@link ApkSignerEngine}. + * + *

Use {@link Builder} to obtain instances of this engine. + */ +public class DefaultApkSignerEngine implements ApkSignerEngine { + + // IMPLEMENTATION NOTE: This engine generates a signed APK as follows: + // 1. The engine asks its client to output input JAR entries which are not part of JAR + // signature. + // 2. If JAR signing (v1 signing) is enabled, the engine inspects the output JAR entries to + // compute their digests, to be placed into output META-INF/MANIFEST.MF. It also inspects + // the contents of input and output META-INF/MANIFEST.MF to borrow the main section of the + // file. It does not care about individual (i.e., JAR entry-specific) sections. It then + // emits the v1 signature (a set of JAR entries) and asks the client to output them. + // 3. If APK Signature Scheme v2 (v2 signing) is enabled, the engine emits an APK Signing Block + // from outputZipSections() and asks its client to insert this block into the output. + + private final boolean mV1SigningEnabled; + private final boolean mV2SigningEnabled; + private final boolean mOtherSignersSignaturesPreserved; + private final List mV1SignerConfigs; + private final DigestAlgorithm mV1ContentDigestAlgorithm; + private final List mV2SignerConfigs; + + private boolean mClosed; + + private boolean mV1SignaturePending; + + /** + * Names of JAR entries which this engine is expected to output as part of v1 signing. + */ + private final Set mSignatureExpectedOutputJarEntryNames; + + /** Requests for digests of output JAR entries. */ + private final Map mOutputJarEntryDigestRequests = + new HashMap<>(); + + /** Digests of output JAR entries. */ + private final Map mOutputJarEntryDigests = new HashMap<>(); + + /** Data of JAR entries emitted by this engine as v1 signature. */ + private final Map mEmittedSignatureJarEntryData = new HashMap<>(); + + /** Requests for data of output JAR entries which comprise the v1 signature. */ + private final Map mOutputSignatureJarEntryDataRequests = + new HashMap<>(); + /** + * Request to obtain the data of MANIFEST.MF or {@code null} if the request hasn't been issued. + */ + private GetJarEntryDataRequest mInputJarManifestEntryDataRequest; + + /** + * Request to output the emitted v1 signature or {@code null} if the request hasn't been issued. + */ + private OutputJarSignatureRequestImpl mAddV1SignatureRequest; + + private boolean mV2SignaturePending; + + /** + * Request to output the emitted v2 signature or {@code null} if the request hasn't been issued. + */ + private OutputApkSigningBlockRequestImpl mAddV2SignatureRequest; + + private DefaultApkSignerEngine( + List signerConfigs, + int minSdkVersion, + boolean v1SigningEnabled, + boolean v2SigningEnabled, + boolean otherSignersSignaturesPreserved) throws InvalidKeyException { + if (signerConfigs.isEmpty()) { + throw new IllegalArgumentException("At least one signer config must be provided"); + } + if (otherSignersSignaturesPreserved) { + throw new UnsupportedOperationException( + "Preserving other signer's signatures is not yet implemented"); + } + + mV1SigningEnabled = v1SigningEnabled; + mV2SigningEnabled = v2SigningEnabled; + mOtherSignersSignaturesPreserved = otherSignersSignaturesPreserved; + mV1SignerConfigs = + (v1SigningEnabled) + ? new ArrayList<>(signerConfigs.size()) : Collections.emptyList(); + mV2SignerConfigs = + (v2SigningEnabled) + ? new ArrayList<>(signerConfigs.size()) : Collections.emptyList(); + mV1ContentDigestAlgorithm = + (v1SigningEnabled) + ? V1SchemeSigner.getSuggestedContentDigestAlgorithm(minSdkVersion) : null; + for (SignerConfig signerConfig : signerConfigs) { + List certificates = signerConfig.getCertificates(); + PublicKey publicKey = certificates.get(0).getPublicKey(); + + if (v1SigningEnabled) { + DigestAlgorithm v1SignatureDigestAlgorithm = + V1SchemeSigner.getSuggestedSignatureDigestAlgorithm( + publicKey, minSdkVersion); + V1SchemeSigner.SignerConfig v1SignerConfig = new V1SchemeSigner.SignerConfig(); + v1SignerConfig.name = signerConfig.getName(); + v1SignerConfig.privateKey = signerConfig.getPrivateKey(); + v1SignerConfig.certificates = certificates; + v1SignerConfig.contentDigestAlgorithm = mV1ContentDigestAlgorithm; + v1SignerConfig.signatureDigestAlgorithm = v1SignatureDigestAlgorithm; + mV1SignerConfigs.add(v1SignerConfig); + } + + if (v2SigningEnabled) { + V2SchemeSigner.SignerConfig v2SignerConfig = new V2SchemeSigner.SignerConfig(); + v2SignerConfig.privateKey = signerConfig.getPrivateKey(); + v2SignerConfig.certificates = certificates; + v2SignerConfig.signatureAlgorithms = + V2SchemeSigner.getSuggestedSignatureAlgorithms(publicKey, minSdkVersion); + mV2SignerConfigs.add(v2SignerConfig); + } + } + mSignatureExpectedOutputJarEntryNames = + (v1SigningEnabled) + ? V1SchemeSigner.getOutputEntryNames(mV1SignerConfigs) + : Collections.emptySet(); + } + + @Override + public void inputApkSigningBlock(DataSource apkSigningBlock) { + checkNotClosed(); + + if ((apkSigningBlock == null) || (apkSigningBlock.size() == 0)) { + return; + } + + if (mOtherSignersSignaturesPreserved) { + // TODO: Preserve blocks other than APK Signature Scheme v2 blocks of signers configured + // in this engine. + return; + } + // TODO: Preserve blocks other than APK Signature Scheme v2 blocks. + } + + @Override + public InputJarEntryInstructions inputJarEntry(String entryName) { + checkNotClosed(); + + InputJarEntryInstructions.OutputPolicy outputPolicy = + getInputJarEntryOutputPolicy(entryName); + switch (outputPolicy) { + case SKIP: + return new InputJarEntryInstructions(InputJarEntryInstructions.OutputPolicy.SKIP); + case OUTPUT: + return new InputJarEntryInstructions(InputJarEntryInstructions.OutputPolicy.OUTPUT); + case OUTPUT_BY_ENGINE: + if (V1SchemeSigner.MANIFEST_ENTRY_NAME.equals(entryName)) { + // We copy the main section of the JAR manifest from input to output. Thus, this + // invalidates v1 signature and we need to see the entry's data. + mInputJarManifestEntryDataRequest = new GetJarEntryDataRequest(entryName); + return new InputJarEntryInstructions( + InputJarEntryInstructions.OutputPolicy.OUTPUT_BY_ENGINE, + mInputJarManifestEntryDataRequest); + } + return new InputJarEntryInstructions( + InputJarEntryInstructions.OutputPolicy.OUTPUT_BY_ENGINE); + default: + throw new RuntimeException("Unsupported output policy: " + outputPolicy); + } + } + + @Override + public InspectJarEntryRequest outputJarEntry(String entryName) { + checkNotClosed(); + invalidateV2Signature(); + if (!mV1SigningEnabled) { + // No need to inspect JAR entries when v1 signing is not enabled. + return null; + } + // v1 signing is enabled + + if (V1SchemeSigner.isJarEntryDigestNeededInManifest(entryName)) { + // This entry is covered by v1 signature. We thus need to inspect the entry's data to + // compute its digest(s) for v1 signature. + + // TODO: Handle the case where other signer's v1 signatures are present and need to be + // preserved. In that scenario we can't modify MANIFEST.MF and add/remove JAR entries + // covered by v1 signature. + invalidateV1Signature(); + GetJarEntryDataDigestRequest dataDigestRequest = + new GetJarEntryDataDigestRequest( + entryName, + V1SchemeSigner.getJcaMessageDigestAlgorithm(mV1ContentDigestAlgorithm)); + mOutputJarEntryDigestRequests.put(entryName, dataDigestRequest); + mOutputJarEntryDigests.remove(entryName); + return dataDigestRequest; + } + + if (mSignatureExpectedOutputJarEntryNames.contains(entryName)) { + // This entry is part of v1 signature generated by this engine. We need to check whether + // the entry's data is as output by the engine. + invalidateV1Signature(); + GetJarEntryDataRequest dataRequest; + if (V1SchemeSigner.MANIFEST_ENTRY_NAME.equals(entryName)) { + dataRequest = new GetJarEntryDataRequest(entryName); + mInputJarManifestEntryDataRequest = dataRequest; + } else { + // If this entry is part of v1 signature which has been emitted by this engine, + // check whether the output entry's data matches what the engine emitted. + dataRequest = + (mEmittedSignatureJarEntryData.containsKey(entryName)) + ? new GetJarEntryDataRequest(entryName) : null; + } + + if (dataRequest != null) { + mOutputSignatureJarEntryDataRequests.put(entryName, dataRequest); + } + return dataRequest; + } + + // This entry is not covered by v1 signature and isn't part of v1 signature. + return null; + } + + @Override + public InputJarEntryInstructions.OutputPolicy inputJarEntryRemoved(String entryName) { + checkNotClosed(); + return getInputJarEntryOutputPolicy(entryName); + } + + @Override + public void outputJarEntryRemoved(String entryName) { + checkNotClosed(); + invalidateV2Signature(); + if (!mV1SigningEnabled) { + return; + } + + if (V1SchemeSigner.isJarEntryDigestNeededInManifest(entryName)) { + // This entry is covered by v1 signature. + invalidateV1Signature(); + mOutputJarEntryDigests.remove(entryName); + mOutputJarEntryDigestRequests.remove(entryName); + mOutputSignatureJarEntryDataRequests.remove(entryName); + return; + } + + if (mSignatureExpectedOutputJarEntryNames.contains(entryName)) { + // This entry is part of the v1 signature generated by this engine. + invalidateV1Signature(); + return; + } + } + + @Override + public OutputJarSignatureRequest outputJarEntries() + throws InvalidKeyException, SignatureException { + checkNotClosed(); + + if (!mV1SignaturePending) { + return null; + } + + if ((mInputJarManifestEntryDataRequest != null) + && (!mInputJarManifestEntryDataRequest.isDone())) { + throw new IllegalStateException( + "Still waiting to inspect input APK's " + + mInputJarManifestEntryDataRequest.getEntryName()); + } + + for (GetJarEntryDataDigestRequest digestRequest + : mOutputJarEntryDigestRequests.values()) { + String entryName = digestRequest.getEntryName(); + if (!digestRequest.isDone()) { + throw new IllegalStateException( + "Still waiting to inspect output APK's " + entryName); + } + mOutputJarEntryDigests.put(entryName, digestRequest.getDigest()); + } + mOutputJarEntryDigestRequests.clear(); + + for (GetJarEntryDataRequest dataRequest : mOutputSignatureJarEntryDataRequests.values()) { + if (!dataRequest.isDone()) { + throw new IllegalStateException( + "Still waiting to inspect output APK's " + dataRequest.getEntryName()); + } + } + + List apkSigningSchemeIds = + (mV2SigningEnabled) ? Collections.singletonList(2) : Collections.emptyList(); + byte[] inputJarManifest = + (mInputJarManifestEntryDataRequest != null) + ? mInputJarManifestEntryDataRequest.getData() : null; + + // Check whether the most recently used signature (if present) is still fine. + List> signatureZipEntries; + if ((mAddV1SignatureRequest == null) || (!mAddV1SignatureRequest.isDone())) { + try { + signatureZipEntries = + V1SchemeSigner.sign( + mV1SignerConfigs, + mV1ContentDigestAlgorithm, + mOutputJarEntryDigests, + apkSigningSchemeIds, + inputJarManifest); + } catch (CertificateEncodingException e) { + throw new SignatureException("Failed to generate v1 signature", e); + } + } else { + V1SchemeSigner.OutputManifestFile newManifest = + V1SchemeSigner.generateManifestFile( + mV1ContentDigestAlgorithm, mOutputJarEntryDigests, inputJarManifest); + byte[] emittedSignatureManifest = + mEmittedSignatureJarEntryData.get(V1SchemeSigner.MANIFEST_ENTRY_NAME); + if (!Arrays.equals(newManifest.contents, emittedSignatureManifest)) { + // Emitted v1 signature is no longer valid. + try { + signatureZipEntries = + V1SchemeSigner.signManifest( + mV1SignerConfigs, + mV1ContentDigestAlgorithm, + apkSigningSchemeIds, + newManifest); + } catch (CertificateEncodingException e) { + throw new SignatureException("Failed to generate v1 signature", e); + } + } else { + // Emitted v1 signature is still valid. Check whether the signature is there in the + // output. + signatureZipEntries = new ArrayList<>(); + for (Map.Entry expectedOutputEntry + : mEmittedSignatureJarEntryData.entrySet()) { + String entryName = expectedOutputEntry.getKey(); + byte[] expectedData = expectedOutputEntry.getValue(); + GetJarEntryDataRequest actualDataRequest = + mOutputSignatureJarEntryDataRequests.get(entryName); + if (actualDataRequest == null) { + // This signature entry hasn't been output. + signatureZipEntries.add(Pair.of(entryName, expectedData)); + continue; + } + byte[] actualData = actualDataRequest.getData(); + if (!Arrays.equals(expectedData, actualData)) { + signatureZipEntries.add(Pair.of(entryName, expectedData)); + } + } + if (signatureZipEntries.isEmpty()) { + // v1 signature in the output is valid + return null; + } + // v1 signature in the output is not valid. + } + } + + if (signatureZipEntries.isEmpty()) { + // v1 signature in the output is valid + mV1SignaturePending = false; + return null; + } + + List sigEntries = + new ArrayList<>(signatureZipEntries.size()); + for (Pair entry : signatureZipEntries) { + String entryName = entry.getFirst(); + byte[] entryData = entry.getSecond(); + sigEntries.add(new OutputJarSignatureRequest.JarEntry(entryName, entryData)); + mEmittedSignatureJarEntryData.put(entryName, entryData); + } + mAddV1SignatureRequest = new OutputJarSignatureRequestImpl(sigEntries); + return mAddV1SignatureRequest; + } + + @Override + public OutputApkSigningBlockRequest outputZipSections( + DataSource zipEntries, + DataSource zipCentralDirectory, + DataSource zipEocd) throws IOException, InvalidKeyException, SignatureException { + checkNotClosed(); + checkV1SigningDoneIfEnabled(); + if (!mV2SigningEnabled) { + return null; + } + invalidateV2Signature(); + + byte[] apkSigningBlock = + V2SchemeSigner.generateApkSigningBlock( + zipEntries, zipCentralDirectory, zipEocd, mV2SignerConfigs); + + mAddV2SignatureRequest = new OutputApkSigningBlockRequestImpl(apkSigningBlock); + return mAddV2SignatureRequest; + } + + @Override + public void outputDone() { + checkNotClosed(); + checkV1SigningDoneIfEnabled(); + checkV2SigningDoneIfEnabled(); + } + + @Override + public void close() { + mClosed = true; + + mAddV1SignatureRequest = null; + mInputJarManifestEntryDataRequest = null; + mOutputJarEntryDigestRequests.clear(); + mOutputJarEntryDigests.clear(); + mEmittedSignatureJarEntryData.clear(); + mOutputSignatureJarEntryDataRequests.clear(); + + mAddV2SignatureRequest = null; + } + + private void invalidateV1Signature() { + if (mV1SigningEnabled) { + mV1SignaturePending = true; + } + invalidateV2Signature(); + } + + private void invalidateV2Signature() { + if (mV2SigningEnabled) { + mV2SignaturePending = true; + mAddV2SignatureRequest = null; + } + } + + private void checkNotClosed() { + if (mClosed) { + throw new IllegalStateException("Engine closed"); + } + } + + private void checkV1SigningDoneIfEnabled() { + if (!mV1SignaturePending) { + return; + } + + if (mAddV1SignatureRequest == null) { + throw new IllegalStateException( + "v1 signature (JAR signature) not yet generated. Skipped outputJarEntries()?"); + } + if (!mAddV1SignatureRequest.isDone()) { + throw new IllegalStateException( + "v1 signature (JAR signature) addition requested by outputJarEntries() hasn't" + + " been fulfilled"); + } + for (Map.Entry expectedOutputEntry + : mEmittedSignatureJarEntryData.entrySet()) { + String entryName = expectedOutputEntry.getKey(); + byte[] expectedData = expectedOutputEntry.getValue(); + GetJarEntryDataRequest actualDataRequest = + mOutputSignatureJarEntryDataRequests.get(entryName); + if (actualDataRequest == null) { + throw new IllegalStateException( + "APK entry " + entryName + " not yet output despite this having been" + + " requested"); + } else if (!actualDataRequest.isDone()) { + throw new IllegalStateException( + "Still waiting to inspect output APK's " + entryName); + } + byte[] actualData = actualDataRequest.getData(); + if (!Arrays.equals(expectedData, actualData)) { + throw new IllegalStateException( + "Output APK entry " + entryName + " data differs from what was requested"); + } + } + mV1SignaturePending = false; + } + + private void checkV2SigningDoneIfEnabled() { + if (!mV2SignaturePending) { + return; + } + if (mAddV2SignatureRequest == null) { + throw new IllegalStateException( + "v2 signature (APK Signature Scheme v2 signature) not yet generated." + + " Skipped outputZipSections()?"); + } + if (!mAddV2SignatureRequest.isDone()) { + throw new IllegalStateException( + "v2 signature (APK Signature Scheme v2 signature) addition requested by" + + " outputZipSections() hasn't been fulfilled yet"); + } + mAddV2SignatureRequest = null; + mV2SignaturePending = false; + } + + /** + * Returns the output policy for the provided input JAR entry. + */ + private InputJarEntryInstructions.OutputPolicy getInputJarEntryOutputPolicy(String entryName) { + if (mSignatureExpectedOutputJarEntryNames.contains(entryName)) { + return InputJarEntryInstructions.OutputPolicy.OUTPUT_BY_ENGINE; + } + if ((mOtherSignersSignaturesPreserved) + || (V1SchemeSigner.isJarEntryDigestNeededInManifest(entryName))) { + return InputJarEntryInstructions.OutputPolicy.OUTPUT; + } + return InputJarEntryInstructions.OutputPolicy.SKIP; + } + + private static class OutputJarSignatureRequestImpl implements OutputJarSignatureRequest { + private final List mAdditionalJarEntries; + private volatile boolean mDone; + + private OutputJarSignatureRequestImpl(List additionalZipEntries) { + mAdditionalJarEntries = + Collections.unmodifiableList(new ArrayList<>(additionalZipEntries)); + } + + @Override + public List getAdditionalJarEntries() { + return mAdditionalJarEntries; + } + + @Override + public void done() { + mDone = true; + } + + private boolean isDone() { + return mDone; + } + } + + private static class OutputApkSigningBlockRequestImpl implements OutputApkSigningBlockRequest { + private final byte[] mApkSigningBlock; + private volatile boolean mDone; + + private OutputApkSigningBlockRequestImpl(byte[] apkSigingBlock) { + mApkSigningBlock = apkSigingBlock.clone(); + } + + @Override + public byte[] getApkSigningBlock() { + return mApkSigningBlock.clone(); + } + + @Override + public void done() { + mDone = true; + } + + private boolean isDone() { + return mDone; + } + } + + /** + * JAR entry inspection request which obtain the entry's uncompressed data. + */ + private static class GetJarEntryDataRequest implements InspectJarEntryRequest { + private final String mEntryName; + private final Object mLock = new Object(); + + private boolean mDone; + private ByteArrayOutputStreamSink mBuf; + + private GetJarEntryDataRequest(String entryName) { + mEntryName = entryName; + } + + @Override + public String getEntryName() { + return mEntryName; + } + + @Override + public DataSink getDataSink() { + synchronized (mLock) { + checkNotDone(); + if (mBuf == null) { + mBuf = new ByteArrayOutputStreamSink(); + } + return mBuf; + } + } + + @Override + public void done() { + synchronized (mLock) { + if (mDone) { + return; + } + mDone = true; + } + } + + private boolean isDone() { + synchronized (mLock) { + return mDone; + } + } + + private void checkNotDone() throws IllegalStateException { + synchronized (mLock) { + if (mDone) { + throw new IllegalStateException("Already done"); + } + } + } + + private byte[] getData() { + synchronized (mLock) { + if (!mDone) { + throw new IllegalStateException("Not yet done"); + } + return (mBuf != null) ? mBuf.getData() : new byte[0]; + } + } + } + + /** + * JAR entry inspection request which obtains the digest of the entry's uncompressed data. + */ + private static class GetJarEntryDataDigestRequest implements InspectJarEntryRequest { + private final String mEntryName; + private final String mJcaDigestAlgorithm; + private final Object mLock = new Object(); + + private boolean mDone; + private DataSink mDataSink; + private MessageDigest mMessageDigest; + private byte[] mDigest; + + private GetJarEntryDataDigestRequest(String entryName, String jcaDigestAlgorithm) { + mEntryName = entryName; + mJcaDigestAlgorithm = jcaDigestAlgorithm; + } + + @Override + public String getEntryName() { + return mEntryName; + } + + @Override + public DataSink getDataSink() { + synchronized (mLock) { + checkNotDone(); + if (mDataSink == null) { + mDataSink = new MessageDigestSink(new MessageDigest[] {getMessageDigest()}); + } + return mDataSink; + } + } + + private MessageDigest getMessageDigest() { + synchronized (mLock) { + if (mMessageDigest == null) { + try { + mMessageDigest = MessageDigest.getInstance(mJcaDigestAlgorithm); + } catch (NoSuchAlgorithmException e) { + throw new RuntimeException( + mJcaDigestAlgorithm + " MessageDigest not available", e); + } + } + return mMessageDigest; + } + } + + @Override + public void done() { + synchronized (mLock) { + if (mDone) { + return; + } + mDone = true; + mDigest = getMessageDigest().digest(); + mMessageDigest = null; + mDataSink = null; + } + } + + private boolean isDone() { + synchronized (mLock) { + return mDone; + } + } + + private void checkNotDone() throws IllegalStateException { + synchronized (mLock) { + if (mDone) { + throw new IllegalStateException("Already done"); + } + } + } + + private byte[] getDigest() { + synchronized (mLock) { + if (!mDone) { + throw new IllegalStateException("Not yet done"); + } + return mDigest.clone(); + } + } + } + + /** + * Configuration of a signer. + * + *

Use {@link Builder} to obtain configuration instances. + */ + public static class SignerConfig { + private final String mName; + private final PrivateKey mPrivateKey; + private final List mCertificates; + + private SignerConfig( + String name, + PrivateKey privateKey, + List certificates) { + mName = name; + mPrivateKey = privateKey; + mCertificates = Collections.unmodifiableList(new ArrayList<>(certificates)); + } + + /** + * Returns the name of this signer. + */ + public String getName() { + return mName; + } + + /** + * Returns the signing key of this signer. + */ + public PrivateKey getPrivateKey() { + return mPrivateKey; + } + + /** + * Returns the certificate(s) of this signer. The first certificate's public key corresponds + * to this signer's private key. + */ + public List getCertificates() { + return mCertificates; + } + + /** + * Builder of {@link SignerConfig} instances. + */ + public static class Builder { + private final String mName; + private final PrivateKey mPrivateKey; + private final List mCertificates; + + /** + * Constructs a new {@code Builder}. + * + * @param name signer's name. The name is reflected in the name of files comprising the + * JAR signature of the APK. + * @param privateKey signing key + * @param certificates list of one or more X.509 certificates. The subject public key of + * the first certificate must correspond to the {@code privateKey}. + */ + public Builder( + String name, + PrivateKey privateKey, + List certificates) { + mName = name; + mPrivateKey = privateKey; + mCertificates = new ArrayList<>(certificates); + } + + /** + * Returns a new {@code SignerConfig} instance configured based on the configuration of + * this builder. + */ + public SignerConfig build() { + return new SignerConfig( + mName, + mPrivateKey, + mCertificates); + } + } + } + + /** + * Builder of {@link DefaultApkSignerEngine} instances. + */ + public static class Builder { + private final List mSignerConfigs; + private final int mMinSdkVersion; + + private boolean mV1SigningEnabled = true; + private boolean mV2SigningEnabled = true; + private boolean mOtherSignersSignaturesPreserved; + + /** + * Constructs a new {@code Builder}. + * + * @param signerConfigs information about signers with which the APK will be signed. At + * least one signer configuration must be provided. + * @param minSdkVersion API Level of the oldest Android platform on which the APK is + * supposed to be installed. See {@code minSdkVersion} attribute in the APK's + * {@code AndroidManifest.xml}. The higher the version, the stronger signing features + * will be enabled. + */ + public Builder( + List signerConfigs, + int minSdkVersion) { + if (signerConfigs.isEmpty()) { + throw new IllegalArgumentException("At least one signer config must be provided"); + } + mSignerConfigs = new ArrayList<>(signerConfigs); + mMinSdkVersion = minSdkVersion; + } + + /** + * Returns a new {@code DefaultApkSignerEngine} instance configured based on the + * configuration of this builder. + */ + public DefaultApkSignerEngine build() throws InvalidKeyException { + return new DefaultApkSignerEngine( + mSignerConfigs, + mMinSdkVersion, + mV1SigningEnabled, + mV2SigningEnabled, + mOtherSignersSignaturesPreserved); + } + + /** + * Sets whether the APK should be signed using JAR signing (aka v1 signature scheme). + * + *

By default, the APK will be signed using this scheme. + */ + public Builder setV1SigningEnabled(boolean enabled) { + mV1SigningEnabled = enabled; + return this; + } + + /** + * Sets whether the APK should be signed using APK Signature Scheme v2 (aka v2 signature + * scheme). + * + *

By default, the APK will be signed using this scheme. + */ + public Builder setV2SigningEnabled(boolean enabled) { + mV2SigningEnabled = enabled; + return this; + } + + /** + * Sets whether signatures produced by signers other than the ones configured in this engine + * should be copied from the input APK to the output APK. + * + *

By default, signatures of other signers are omitted from the output APK. + */ + public Builder setOtherSignersSignaturesPreserved(boolean preserved) { + mOtherSignersSignaturesPreserved = preserved; + return this; + } + } +} diff --git a/plugin/src/main/java/com/android/apksigner/core/apk/ApkUtils.java b/plugin/src/main/java/com/android/apksigner/core/apk/ApkUtils.java new file mode 100644 index 0000000..8cc8c90 --- /dev/null +++ b/plugin/src/main/java/com/android/apksigner/core/apk/ApkUtils.java @@ -0,0 +1,158 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.apksigner.core.apk; + +import com.android.apksigner.core.internal.util.Pair; +import com.android.apksigner.core.internal.zip.ZipUtils; +import com.android.apksigner.core.util.DataSource; +import com.android.apksigner.core.zip.ZipFormatException; + +import java.io.IOException; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; + +/** + * APK utilities. + */ +public class ApkUtils { + + private ApkUtils() {} + + /** + * Finds the main ZIP sections of the provided APK. + * + * @throws IOException if an I/O error occurred while reading the APK + * @throws ZipFormatException if the APK is malformed + */ + public static ZipSections findZipSections(DataSource apk) + throws IOException, ZipFormatException { + Pair eocdAndOffsetInFile = + ZipUtils.findZipEndOfCentralDirectoryRecord(apk); + if (eocdAndOffsetInFile == null) { + throw new ZipFormatException("ZIP End of Central Directory record not found"); + } + + ByteBuffer eocdBuf = eocdAndOffsetInFile.getFirst(); + long eocdOffset = eocdAndOffsetInFile.getSecond(); + if (ZipUtils.isZip64EndOfCentralDirectoryLocatorPresent(apk, eocdOffset)) { + throw new ZipFormatException("ZIP64 APK not supported"); + } + eocdBuf.order(ByteOrder.LITTLE_ENDIAN); + long cdStartOffset = ZipUtils.getZipEocdCentralDirectoryOffset(eocdBuf); + if (cdStartOffset >= eocdOffset) { + throw new ZipFormatException( + "ZIP Central Directory start offset out of range: " + cdStartOffset + + ". ZIP End of Central Directory offset: " + eocdOffset); + } + + long cdSizeBytes = ZipUtils.getZipEocdCentralDirectorySizeBytes(eocdBuf); + long cdEndOffset = cdStartOffset + cdSizeBytes; + if (cdEndOffset > eocdOffset) { + throw new ZipFormatException( + "ZIP Central Directory overlaps with End of Central Directory" + + ". CD end: " + cdEndOffset + + ", EoCD start: " + eocdOffset); + } + + int cdRecordCount = ZipUtils.getZipEocdCentralDirectoryTotalRecordCount(eocdBuf); + + return new ZipSections( + cdStartOffset, + cdSizeBytes, + cdRecordCount, + eocdOffset, + eocdBuf); + } + + /** + * Information about the ZIP sections of an APK. + */ + public static class ZipSections { + private final long mCentralDirectoryOffset; + private final long mCentralDirectorySizeBytes; + private final int mCentralDirectoryRecordCount; + private final long mEocdOffset; + private final ByteBuffer mEocd; + + public ZipSections( + long centralDirectoryOffset, + long centralDirectorySizeBytes, + int centralDirectoryRecordCount, + long eocdOffset, + ByteBuffer eocd) { + mCentralDirectoryOffset = centralDirectoryOffset; + mCentralDirectorySizeBytes = centralDirectorySizeBytes; + mCentralDirectoryRecordCount = centralDirectoryRecordCount; + mEocdOffset = eocdOffset; + mEocd = eocd; + } + + /** + * Returns the start offset of the ZIP Central Directory. This value is taken from the + * ZIP End of Central Directory record. + */ + public long getZipCentralDirectoryOffset() { + return mCentralDirectoryOffset; + } + + /** + * Returns the size (in bytes) of the ZIP Central Directory. This value is taken from the + * ZIP End of Central Directory record. + */ + public long getZipCentralDirectorySizeBytes() { + return mCentralDirectorySizeBytes; + } + + /** + * Returns the number of records in the ZIP Central Directory. This value is taken from the + * ZIP End of Central Directory record. + */ + public int getZipCentralDirectoryRecordCount() { + return mCentralDirectoryRecordCount; + } + + /** + * Returns the start offset of the ZIP End of Central Directory record. The record extends + * until the very end of the APK. + */ + public long getZipEndOfCentralDirectoryOffset() { + return mEocdOffset; + } + + /** + * Returns the contents of the ZIP End of Central Directory. + */ + public ByteBuffer getZipEndOfCentralDirectory() { + return mEocd; + } + } + + /** + * Sets the offset of the start of the ZIP Central Directory in the APK's ZIP End of Central + * Directory record. + * + * @param zipEndOfCentralDirectory APK's ZIP End of Central Directory record + * @param offset offset of the ZIP Central Directory relative to the start of the archive. Must + * be between {@code 0} and {@code 2^32 - 1} inclusive. + */ + public static void setZipEocdCentralDirectoryOffset( + ByteBuffer zipEndOfCentralDirectory, long offset) { + ByteBuffer eocd = zipEndOfCentralDirectory.slice(); + eocd.order(ByteOrder.LITTLE_ENDIAN); + ZipUtils.setZipEocdCentralDirectoryOffset(eocd, offset); + } +} diff --git a/plugin/src/main/java/com/android/apksigner/core/internal/apk/v1/DigestAlgorithm.java b/plugin/src/main/java/com/android/apksigner/core/internal/apk/v1/DigestAlgorithm.java new file mode 100644 index 0000000..71e698b --- /dev/null +++ b/plugin/src/main/java/com/android/apksigner/core/internal/apk/v1/DigestAlgorithm.java @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.apksigner.core.internal.apk.v1; + +/** + * Digest algorithm used with JAR signing (aka v1 signing scheme). + */ +public enum DigestAlgorithm { + /** SHA-1 */ + SHA1("SHA-1"), + + /** SHA2-256 */ + SHA256("SHA-256"); + + private final String mJcaMessageDigestAlgorithm; + + private DigestAlgorithm(String jcaMessageDigestAlgoritm) { + mJcaMessageDigestAlgorithm = jcaMessageDigestAlgoritm; + } + + /** + * Returns the {@link java.security.MessageDigest} algorithm represented by this digest + * algorithm. + */ + String getJcaMessageDigestAlgorithm() { + return mJcaMessageDigestAlgorithm; + } +} diff --git a/plugin/src/main/java/com/android/apksigner/core/internal/apk/v1/V1SchemeSigner.java b/plugin/src/main/java/com/android/apksigner/core/internal/apk/v1/V1SchemeSigner.java new file mode 100644 index 0000000..9f4ccce --- /dev/null +++ b/plugin/src/main/java/com/android/apksigner/core/internal/apk/v1/V1SchemeSigner.java @@ -0,0 +1,573 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.apksigner.core.internal.apk.v1; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.security.InvalidKeyException; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.security.SignatureException; +import java.security.cert.CertificateEncodingException; +import java.security.cert.X509Certificate; +import java.util.ArrayList; +import java.util.Base64; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Set; +import java.util.SortedMap; +import java.util.TreeMap; +import java.util.jar.Attributes; +import java.util.jar.Manifest; + +import org.bouncycastle.asn1.ASN1InputStream; +import org.bouncycastle.asn1.ASN1ObjectIdentifier; +import org.bouncycastle.asn1.DERNull; +import org.bouncycastle.asn1.DEROutputStream; +import org.bouncycastle.asn1.x509.AlgorithmIdentifier; +import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; +import org.bouncycastle.cert.jcajce.JcaCertStore; +import org.bouncycastle.cert.jcajce.JcaX509CertificateHolder; +import org.bouncycastle.cms.CMSException; +import org.bouncycastle.cms.CMSProcessableByteArray; +import org.bouncycastle.cms.CMSSignatureEncryptionAlgorithmFinder; +import org.bouncycastle.cms.CMSSignedData; +import org.bouncycastle.cms.CMSSignedDataGenerator; +import org.bouncycastle.cms.DefaultCMSSignatureEncryptionAlgorithmFinder; +import org.bouncycastle.cms.SignerInfoGeneratorBuilder; +import org.bouncycastle.operator.ContentSigner; +import org.bouncycastle.operator.OperatorCreationException; +import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; +import org.bouncycastle.operator.jcajce.JcaDigestCalculatorProviderBuilder; + +import com.android.apksigner.core.internal.jar.ManifestWriter; +import com.android.apksigner.core.internal.jar.SignatureFileWriter; +import com.android.apksigner.core.internal.util.Pair; + +/** + * APK signer which uses JAR signing (aka v1 signing scheme). + * + * @see Signed JAR File + */ +public abstract class V1SchemeSigner { + + public static final String MANIFEST_ENTRY_NAME = "META-INF/MANIFEST.MF"; + + private static final Attributes.Name ATTRIBUTE_NAME_CREATED_BY = + new Attributes.Name("Created-By"); + private static final String ATTRIBUTE_DEFALT_VALUE_CREATED_BY = "1.0 (Android apksigner)"; + private static final String ATTRIBUTE_VALUE_MANIFEST_VERSION = "1.0"; + private static final String ATTRIBUTE_VALUE_SIGNATURE_VERSION = "1.0"; + + private static final Attributes.Name SF_ATTRIBUTE_NAME_ANDROID_APK_SIGNED_NAME = + new Attributes.Name("X-Android-APK-Signed"); + + /** + * Signer configuration. + */ + public static class SignerConfig { + /** Name. */ + public String name; + + /** Private key. */ + public PrivateKey privateKey; + + /** + * Certificates, with the first certificate containing the public key corresponding to + * {@link #privateKey}. + */ + public List certificates; + + /** + * Digest algorithm used for the signature. + */ + public DigestAlgorithm signatureDigestAlgorithm; + + /** + * Digest algorithm used for digests of JAR entries and MANIFEST.MF. + */ + public DigestAlgorithm contentDigestAlgorithm; + } + + /** Hidden constructor to prevent instantiation. */ + private V1SchemeSigner() {} + + /** + * Gets the JAR signing digest algorithm to be used for signing an APK using the provided key. + * + * @param minSdkVersion minimum API Level of the platform on which the APK may be installed (see + * AndroidManifest.xml minSdkVersion attribute) + * + * @throws InvalidKeyException if the provided key is not suitable for signing APKs using + * JAR signing (aka v1 signature scheme) + */ + public static DigestAlgorithm getSuggestedSignatureDigestAlgorithm( + PublicKey signingKey, int minSdkVersion) throws InvalidKeyException { + String keyAlgorithm = signingKey.getAlgorithm(); + if ("RSA".equalsIgnoreCase(keyAlgorithm)) { + // Prior to API Level 18, only SHA-1 can be used with RSA. + if (minSdkVersion < 18) { + return DigestAlgorithm.SHA1; + } + return DigestAlgorithm.SHA256; + } else if ("DSA".equalsIgnoreCase(keyAlgorithm)) { + // Prior to API Level 21, only SHA-1 can be used with DSA + if (minSdkVersion < 21) { + return DigestAlgorithm.SHA1; + } else { + return DigestAlgorithm.SHA256; + } + } else if ("EC".equalsIgnoreCase(keyAlgorithm)) { + if (minSdkVersion < 18) { + throw new InvalidKeyException( + "ECDSA signatures only supported for minSdkVersion 18 and higher"); + } + // Prior to API Level 21, only SHA-1 can be used with ECDSA + if (minSdkVersion < 21) { + return DigestAlgorithm.SHA1; + } else { + return DigestAlgorithm.SHA256; + } + } else { + throw new InvalidKeyException("Unsupported key algorithm: " + keyAlgorithm); + } + } + + /** + * Returns the JAR signing digest algorithm to be used for JAR entry digests. + * + * @param minSdkVersion minimum API Level of the platform on which the APK may be installed (see + * AndroidManifest.xml minSdkVersion attribute) + */ + public static DigestAlgorithm getSuggestedContentDigestAlgorithm(int minSdkVersion) { + return (minSdkVersion >= 18) ? DigestAlgorithm.SHA256 : DigestAlgorithm.SHA1; + } + + /** + * Returns a new {@link MessageDigest} instance corresponding to the provided digest algorithm. + */ + public static MessageDigest getMessageDigestInstance(DigestAlgorithm digestAlgorithm) { + String jcaAlgorithm = digestAlgorithm.getJcaMessageDigestAlgorithm(); + try { + return MessageDigest.getInstance(jcaAlgorithm); + } catch (NoSuchAlgorithmException e) { + throw new RuntimeException("Failed to obtain " + jcaAlgorithm + " MessageDigest", e); + } + } + + /** + * Returns the JCA {@link MessageDigest} algorithm corresponding to the provided digest + * algorithm. + */ + public static String getJcaMessageDigestAlgorithm(DigestAlgorithm digestAlgorithm) { + return digestAlgorithm.getJcaMessageDigestAlgorithm(); + } + + /** + * Returns {@code true} if the provided JAR entry must be mentioned in signed JAR archive's + * manifest. + */ + public static boolean isJarEntryDigestNeededInManifest(String entryName) { + // See https://docs.oracle.com/javase/8/docs/technotes/guides/jar/jar.html#Signed_JAR_File + + // Entries outside of META-INF must be listed in the manifest. + if (!entryName.startsWith("META-INF/")) { + return true; + } + // Entries in subdirectories of META-INF must be listed in the manifest. + if (entryName.indexOf('/', "META-INF/".length()) != -1) { + return true; + } + + // Ignored file names (case-insensitive) in META-INF directory: + // MANIFEST.MF + // *.SF + // *.RSA + // *.DSA + // *.EC + // SIG-* + String fileNameLowerCase = + entryName.substring("META-INF/".length()).toLowerCase(Locale.US); + if (("manifest.mf".equals(fileNameLowerCase)) + || (fileNameLowerCase.endsWith(".sf")) + || (fileNameLowerCase.endsWith(".rsa")) + || (fileNameLowerCase.endsWith(".dsa")) + || (fileNameLowerCase.endsWith(".ec")) + || (fileNameLowerCase.startsWith("sig-"))) { + return false; + } + return true; + } + + /** + * Signs the provided APK using JAR signing (aka v1 signature scheme) and returns the list of + * JAR entries which need to be added to the APK as part of the signature. + * + * @param signerConfigs signer configurations, one for each signer. At least one signer config + * must be provided. + * + * @throws InvalidKeyException if a signing key is not suitable for this signature scheme or + * cannot be used in general + * @throws SignatureException if an error occurs when computing digests of generating + * signatures + */ + public static List> sign( + List signerConfigs, + DigestAlgorithm jarEntryDigestAlgorithm, + Map jarEntryDigests, + List apkSigningSchemeIds, + byte[] sourceManifestBytes) + throws InvalidKeyException, CertificateEncodingException, SignatureException { + if (signerConfigs.isEmpty()) { + throw new IllegalArgumentException("At least one signer config must be provided"); + } + OutputManifestFile manifest = + generateManifestFile(jarEntryDigestAlgorithm, jarEntryDigests, sourceManifestBytes); + + return signManifest(signerConfigs, jarEntryDigestAlgorithm, apkSigningSchemeIds, manifest); + } + + /** + * Signs the provided APK using JAR signing (aka v1 signature scheme) and returns the list of + * JAR entries which need to be added to the APK as part of the signature. + * + * @param signerConfigs signer configurations, one for each signer. At least one signer config + * must be provided. + * + * @throws InvalidKeyException if a signing key is not suitable for this signature scheme or + * cannot be used in general + * @throws SignatureException if an error occurs when computing digests of generating + * signatures + */ + public static List> signManifest( + List signerConfigs, + DigestAlgorithm digestAlgorithm, + List apkSigningSchemeIds, + OutputManifestFile manifest) + throws InvalidKeyException, CertificateEncodingException, SignatureException { + if (signerConfigs.isEmpty()) { + throw new IllegalArgumentException("At least one signer config must be provided"); + } + + // For each signer output .SF and .(RSA|DSA|EC) file, then output MANIFEST.MF. + List> signatureJarEntries = + new ArrayList<>(2 * signerConfigs.size() + 1); + byte[] sfBytes = + generateSignatureFile(apkSigningSchemeIds, digestAlgorithm, manifest); + for (SignerConfig signerConfig : signerConfigs) { + String signerName = signerConfig.name; + byte[] signatureBlock; + try { + signatureBlock = generateSignatureBlock(signerConfig, sfBytes); + } catch (InvalidKeyException e) { + throw new InvalidKeyException( + "Failed to sign using signer \"" + signerName + "\"", e); + } catch (CertificateEncodingException e) { + throw new CertificateEncodingException( + "Failed to sign using signer \"" + signerName + "\"", e); + } catch (SignatureException e) { + throw new SignatureException( + "Failed to sign using signer \"" + signerName + "\"", e); + } + signatureJarEntries.add(Pair.of("META-INF/" + signerName + ".SF", sfBytes)); + PublicKey publicKey = signerConfig.certificates.get(0).getPublicKey(); + String signatureBlockFileName = + "META-INF/" + signerName + "." + + publicKey.getAlgorithm().toUpperCase(Locale.US); + signatureJarEntries.add( + Pair.of(signatureBlockFileName, signatureBlock)); + } + signatureJarEntries.add(Pair.of(MANIFEST_ENTRY_NAME, manifest.contents)); + return signatureJarEntries; + } + + /** + * Returns the names of JAR entries which this signer will produce as part of v1 signature. + */ + public static Set getOutputEntryNames(List signerConfigs) { + Set result = new HashSet<>(2 * signerConfigs.size() + 1); + for (SignerConfig signerConfig : signerConfigs) { + String signerName = signerConfig.name; + result.add("META-INF/" + signerName + ".SF"); + PublicKey publicKey = signerConfig.certificates.get(0).getPublicKey(); + String signatureBlockFileName = + "META-INF/" + signerName + "." + + publicKey.getAlgorithm().toUpperCase(Locale.US); + result.add(signatureBlockFileName); + } + result.add(MANIFEST_ENTRY_NAME); + return result; + } + + /** + * Generated and returns the {@code META-INF/MANIFEST.MF} file based on the provided (optional) + * input {@code MANIFEST.MF} and digests of JAR entries covered by the manifest. + */ + public static OutputManifestFile generateManifestFile( + DigestAlgorithm jarEntryDigestAlgorithm, + Map jarEntryDigests, + byte[] sourceManifestBytes) { + Manifest sourceManifest = null; + if (sourceManifestBytes != null) { + try { + sourceManifest = new Manifest(new ByteArrayInputStream(sourceManifestBytes)); + } catch (IOException e) { + throw new IllegalArgumentException("Failed to parse source MANIFEST.MF", e); + } + } + ByteArrayOutputStream manifestOut = new ByteArrayOutputStream(); + Attributes mainAttrs = new Attributes(); + // Copy the main section from the source manifest (if provided). Otherwise use defaults. + if (sourceManifest != null) { + mainAttrs.putAll(sourceManifest.getMainAttributes()); + } else { + mainAttrs.put(Attributes.Name.MANIFEST_VERSION, ATTRIBUTE_VALUE_MANIFEST_VERSION); + mainAttrs.put(ATTRIBUTE_NAME_CREATED_BY, ATTRIBUTE_DEFALT_VALUE_CREATED_BY); + } + + try { + ManifestWriter.writeMainSection(manifestOut, mainAttrs); + } catch (IOException e) { + throw new RuntimeException("Failed to write in-memory MANIFEST.MF", e); + } + + List sortedEntryNames = new ArrayList<>(jarEntryDigests.keySet()); + Collections.sort(sortedEntryNames); + SortedMap invidualSectionsContents = new TreeMap<>(); + String entryDigestAttributeName = getEntryDigestAttributeName(jarEntryDigestAlgorithm); + for (String entryName : sortedEntryNames) { + byte[] entryDigest = jarEntryDigests.get(entryName); + Attributes entryAttrs = new Attributes(); + entryAttrs.putValue( + entryDigestAttributeName, + Base64.getEncoder().encodeToString(entryDigest)); + ByteArrayOutputStream sectionOut = new ByteArrayOutputStream(); + byte[] sectionBytes; + try { + ManifestWriter.writeIndividualSection(sectionOut, entryName, entryAttrs); + sectionBytes = sectionOut.toByteArray(); + manifestOut.write(sectionBytes); + } catch (IOException e) { + throw new RuntimeException("Failed to write in-memory MANIFEST.MF", e); + } + invidualSectionsContents.put(entryName, sectionBytes); + } + + OutputManifestFile result = new OutputManifestFile(); + result.contents = manifestOut.toByteArray(); + result.mainSectionAttributes = mainAttrs; + result.individualSectionsContents = invidualSectionsContents; + return result; + } + + public static class OutputManifestFile { + public byte[] contents; + public SortedMap individualSectionsContents; + public Attributes mainSectionAttributes; + } + + private static byte[] generateSignatureFile( + List apkSignatureSchemeIds, + DigestAlgorithm manifestDigestAlgorithm, + OutputManifestFile manifest) { + Manifest sf = new Manifest(); + Attributes mainAttrs = sf.getMainAttributes(); + mainAttrs.put(Attributes.Name.SIGNATURE_VERSION, ATTRIBUTE_VALUE_SIGNATURE_VERSION); + mainAttrs.put(ATTRIBUTE_NAME_CREATED_BY, ATTRIBUTE_DEFALT_VALUE_CREATED_BY); + if (!apkSignatureSchemeIds.isEmpty()) { + // Add APK Signature Scheme v2 (and newer) signature stripping protection. + // This attribute indicates that this APK is supposed to have been signed using one or + // more APK-specific signature schemes in addition to the standard JAR signature scheme + // used by this code. APK signature verifier should reject the APK if it does not + // contain a signature for the signature scheme the verifier prefers out of this set. + StringBuilder attrValue = new StringBuilder(); + for (int id : apkSignatureSchemeIds) { + if (attrValue.length() > 0) { + attrValue.append(", "); + } + attrValue.append(String.valueOf(id)); + } + mainAttrs.put( + SF_ATTRIBUTE_NAME_ANDROID_APK_SIGNED_NAME, + attrValue.toString()); + } + + // Add main attribute containing the digest of MANIFEST.MF. + MessageDigest md = getMessageDigestInstance(manifestDigestAlgorithm); + mainAttrs.putValue( + getManifestDigestAttributeName(manifestDigestAlgorithm), + Base64.getEncoder().encodeToString(md.digest(manifest.contents))); + ByteArrayOutputStream out = new ByteArrayOutputStream(); + try { + SignatureFileWriter.writeMainSection(out, mainAttrs); + } catch (IOException e) { + throw new RuntimeException("Failed to write in-memory .SF file", e); + } + String entryDigestAttributeName = getEntryDigestAttributeName(manifestDigestAlgorithm); + for (Map.Entry manifestSection + : manifest.individualSectionsContents.entrySet()) { + String sectionName = manifestSection.getKey(); + byte[] sectionContents = manifestSection.getValue(); + byte[] sectionDigest = md.digest(sectionContents); + Attributes attrs = new Attributes(); + attrs.putValue( + entryDigestAttributeName, + Base64.getEncoder().encodeToString(sectionDigest)); + + try { + SignatureFileWriter.writeIndividualSection(out, sectionName, attrs); + } catch (IOException e) { + throw new RuntimeException("Failed to write in-memory .SF file", e); + } + } + + // A bug in the java.util.jar implementation of Android platforms up to version 1.6 will + // cause a spurious IOException to be thrown if the length of the signature file is a + // multiple of 1024 bytes. As a workaround, add an extra CRLF in this case. + if ((out.size() > 0) && ((out.size() % 1024) == 0)) { + try { + SignatureFileWriter.writeSectionDelimiter(out); + } catch (IOException e) { + throw new RuntimeException("Failed to write to ByteArrayOutputStream", e); + } + } + + return out.toByteArray(); + } + + private static byte[] generateSignatureBlock( + SignerConfig signerConfig, byte[] signatureFileBytes) + throws InvalidKeyException, CertificateEncodingException, SignatureException { + JcaCertStore certs = new JcaCertStore(signerConfig.certificates); + X509Certificate signerCert = signerConfig.certificates.get(0); + String jcaSignatureAlgorithm = + getJcaSignatureAlgorithm( + signerCert.getPublicKey(), signerConfig.signatureDigestAlgorithm); + try { + ContentSigner signer = + new JcaContentSignerBuilder(jcaSignatureAlgorithm) + .build(signerConfig.privateKey); + CMSSignedDataGenerator gen = new CMSSignedDataGenerator(); + gen.addSignerInfoGenerator( + new SignerInfoGeneratorBuilder( + new JcaDigestCalculatorProviderBuilder().build(), + SignerInfoSignatureAlgorithmFinder.INSTANCE) + .setDirectSignature(true) + .build(signer, new JcaX509CertificateHolder(signerCert))); + gen.addCertificates(certs); + + CMSSignedData sigData = + gen.generate(new CMSProcessableByteArray(signatureFileBytes), false); + + ByteArrayOutputStream out = new ByteArrayOutputStream(); + try (ASN1InputStream asn1 = new ASN1InputStream(sigData.getEncoded())) { + DEROutputStream dos = new DEROutputStream(out); + dos.writeObject(asn1.readObject()); + } + return out.toByteArray(); + } catch (OperatorCreationException | CMSException | IOException e) { + throw new SignatureException("Failed to generate signature", e); + } + } + + /** + * Chooser of SignatureAlgorithm for PKCS #7 CMS SignerInfo. + */ + private static class SignerInfoSignatureAlgorithmFinder + implements CMSSignatureEncryptionAlgorithmFinder { + private static final SignerInfoSignatureAlgorithmFinder INSTANCE = + new SignerInfoSignatureAlgorithmFinder(); + + private static final AlgorithmIdentifier DSA = + new AlgorithmIdentifier(X9ObjectIdentifiers.id_dsa, DERNull.INSTANCE); + + private final CMSSignatureEncryptionAlgorithmFinder mDefault = + new DefaultCMSSignatureEncryptionAlgorithmFinder(); + + @Override + public AlgorithmIdentifier findEncryptionAlgorithm(AlgorithmIdentifier id) { + // Use the default chooser, but replace dsaWithSha1 with dsa. This is because "dsa" is + // accepted by any Android platform whereas "dsaWithSha1" is accepted only since + // API Level 9. + id = mDefault.findEncryptionAlgorithm(id); + if (id != null) { + ASN1ObjectIdentifier oid = id.getAlgorithm(); + if (X9ObjectIdentifiers.id_dsa_with_sha1.equals(oid)) { + return DSA; + } + } + + return id; + } + } + + private static String getEntryDigestAttributeName(DigestAlgorithm digestAlgorithm) { + switch (digestAlgorithm) { + case SHA1: + return "SHA1-Digest"; + case SHA256: + return "SHA-256-Digest"; + default: + throw new IllegalArgumentException( + "Unexpected content digest algorithm: " + digestAlgorithm); + } + } + + private static String getManifestDigestAttributeName(DigestAlgorithm digestAlgorithm) { + switch (digestAlgorithm) { + case SHA1: + return "SHA1-Digest-Manifest"; + case SHA256: + return "SHA-256-Digest-Manifest"; + default: + throw new IllegalArgumentException( + "Unexpected content digest algorithm: " + digestAlgorithm); + } + } + + private static String getJcaSignatureAlgorithm( + PublicKey publicKey, DigestAlgorithm digestAlgorithm) throws InvalidKeyException { + String keyAlgorithm = publicKey.getAlgorithm(); + String digestPrefixForSigAlg; + switch (digestAlgorithm) { + case SHA1: + digestPrefixForSigAlg = "SHA1"; + break; + case SHA256: + digestPrefixForSigAlg = "SHA256"; + break; + default: + throw new IllegalArgumentException( + "Unexpected digest algorithm: " + digestAlgorithm); + } + if ("RSA".equalsIgnoreCase(keyAlgorithm)) { + return digestPrefixForSigAlg + "withRSA"; + } else if ("DSA".equalsIgnoreCase(keyAlgorithm)) { + return digestPrefixForSigAlg + "withDSA"; + } else if ("EC".equalsIgnoreCase(keyAlgorithm)) { + return digestPrefixForSigAlg + "withECDSA"; + } else { + throw new InvalidKeyException("Unsupported key algorithm: " + keyAlgorithm); + } + } +} diff --git a/plugin/src/main/java/com/android/apksigner/core/internal/apk/v2/ContentDigestAlgorithm.java b/plugin/src/main/java/com/android/apksigner/core/internal/apk/v2/ContentDigestAlgorithm.java new file mode 100644 index 0000000..7c136be --- /dev/null +++ b/plugin/src/main/java/com/android/apksigner/core/internal/apk/v2/ContentDigestAlgorithm.java @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.apksigner.core.internal.apk.v2; + +/** + * APK Signature Scheme v2 content digest algorithm. + */ +public enum ContentDigestAlgorithm { + /** SHA2-256 over 1 MB chunks. */ + CHUNKED_SHA256("SHA-256", 256 / 8), + + /** SHA2-512 over 1 MB chunks. */ + CHUNKED_SHA512("SHA-512", 512 / 8); + + private final String mJcaMessageDigestAlgorithm; + private final int mChunkDigestOutputSizeBytes; + + private ContentDigestAlgorithm( + String jcaMessageDigestAlgorithm, int chunkDigestOutputSizeBytes) { + mJcaMessageDigestAlgorithm = jcaMessageDigestAlgorithm; + mChunkDigestOutputSizeBytes = chunkDigestOutputSizeBytes; + } + + /** + * Returns the {@link java.security.MessageDigest} algorithm used for computing digests of + * chunks by this content digest algorithm. + */ + String getJcaMessageDigestAlgorithm() { + return mJcaMessageDigestAlgorithm; + } + + /** + * Returns the size (in bytes) of the digest of a chunk of content. + */ + int getChunkDigestOutputSizeBytes() { + return mChunkDigestOutputSizeBytes; + } +} \ No newline at end of file diff --git a/plugin/src/main/java/com/android/apksigner/core/internal/apk/v2/SignatureAlgorithm.java b/plugin/src/main/java/com/android/apksigner/core/internal/apk/v2/SignatureAlgorithm.java new file mode 100644 index 0000000..20f890d --- /dev/null +++ b/plugin/src/main/java/com/android/apksigner/core/internal/apk/v2/SignatureAlgorithm.java @@ -0,0 +1,142 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.apksigner.core.internal.apk.v2; + +import com.android.apksigner.core.internal.util.Pair; + +import java.security.spec.AlgorithmParameterSpec; +import java.security.spec.MGF1ParameterSpec; +import java.security.spec.PSSParameterSpec; + +/** + * APK Signature Scheme v2 signature algorithm. + */ +public enum SignatureAlgorithm { + /** + * RSASSA-PSS with SHA2-256 digest, SHA2-256 MGF1, 32 bytes of salt, trailer: 0xbc, content + * digested using SHA2-256 in 1 MB chunks. + */ + RSA_PSS_WITH_SHA256( + 0x0101, + ContentDigestAlgorithm.CHUNKED_SHA256, + "RSA", + Pair.of("SHA256withRSA/PSS", + new PSSParameterSpec( + "SHA-256", "MGF1", MGF1ParameterSpec.SHA256, 256 / 8, 1))), + + /** + * RSASSA-PSS with SHA2-512 digest, SHA2-512 MGF1, 64 bytes of salt, trailer: 0xbc, content + * digested using SHA2-512 in 1 MB chunks. + */ + RSA_PSS_WITH_SHA512( + 0x0102, + ContentDigestAlgorithm.CHUNKED_SHA512, + "RSA", + Pair.of( + "SHA512withRSA/PSS", + new PSSParameterSpec( + "SHA-512", "MGF1", MGF1ParameterSpec.SHA512, 512 / 8, 1))), + + /** RSASSA-PKCS1-v1_5 with SHA2-256 digest, content digested using SHA2-256 in 1 MB chunks. */ + RSA_PKCS1_V1_5_WITH_SHA256( + 0x0103, + ContentDigestAlgorithm.CHUNKED_SHA256, + "RSA", + Pair.of("SHA256withRSA", null)), + + /** RSASSA-PKCS1-v1_5 with SHA2-512 digest, content digested using SHA2-512 in 1 MB chunks. */ + RSA_PKCS1_V1_5_WITH_SHA512( + 0x0104, + ContentDigestAlgorithm.CHUNKED_SHA512, + "RSA", + Pair.of("SHA512withRSA", null)), + + /** ECDSA with SHA2-256 digest, content digested using SHA2-256 in 1 MB chunks. */ + ECDSA_WITH_SHA256( + 0x0201, + ContentDigestAlgorithm.CHUNKED_SHA256, + "EC", + Pair.of("SHA256withECDSA", null)), + + /** ECDSA with SHA2-512 digest, content digested using SHA2-512 in 1 MB chunks. */ + ECDSA_WITH_SHA512( + 0x0202, + ContentDigestAlgorithm.CHUNKED_SHA512, + "EC", + Pair.of("SHA512withECDSA", null)), + + /** DSA with SHA2-256 digest, content digested using SHA2-256 in 1 MB chunks. */ + DSA_WITH_SHA256( + 0x0301, + ContentDigestAlgorithm.CHUNKED_SHA256, + "DSA", + Pair.of("SHA256withDSA", null)); + + private final int mId; + private final String mJcaKeyAlgorithm; + private final ContentDigestAlgorithm mContentDigestAlgorithm; + private final Pair mJcaSignatureAlgAndParams; + + private SignatureAlgorithm(int id, + ContentDigestAlgorithm contentDigestAlgorithm, + String jcaKeyAlgorithm, + Pair jcaSignatureAlgAndParams) { + mId = id; + mContentDigestAlgorithm = contentDigestAlgorithm; + mJcaKeyAlgorithm = jcaKeyAlgorithm; + mJcaSignatureAlgAndParams = jcaSignatureAlgAndParams; + } + + /** + * Returns the ID of this signature algorithm as used in APK Signature Scheme v2 wire format. + */ + int getId() { + return mId; + } + + /** + * Returns the content digest algorithm associated with this signature algorithm. + */ + ContentDigestAlgorithm getContentDigestAlgorithm() { + return mContentDigestAlgorithm; + } + + /** + * Returns the JCA {@link java.security.Key} algorithm used by this signature scheme. + */ + String getJcaKeyAlgorithm() { + return mJcaKeyAlgorithm; + } + + /** + * Returns the {@link java.security.Signature} algorithm and the {@link AlgorithmParameterSpec} + * (or null if not needed) to parameterize the {@code Signature}. + */ + Pair getJcaSignatureAlgorithmAndParams() { + return mJcaSignatureAlgAndParams; + } + + static SignatureAlgorithm findById(int id) { + for (SignatureAlgorithm alg : SignatureAlgorithm.values()) { + if (alg.getId() == id) { + return alg; + } + } + + return null; + } +} diff --git a/plugin/src/main/java/com/android/apksigner/core/internal/apk/v2/V2SchemeSigner.java b/plugin/src/main/java/com/android/apksigner/core/internal/apk/v2/V2SchemeSigner.java new file mode 100644 index 0000000..aba390b --- /dev/null +++ b/plugin/src/main/java/com/android/apksigner/core/internal/apk/v2/V2SchemeSigner.java @@ -0,0 +1,605 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.apksigner.core.internal.apk.v2; + +import com.android.apksigner.core.internal.util.MessageDigestSink; +import com.android.apksigner.core.internal.util.Pair; +import com.android.apksigner.core.internal.zip.ZipUtils; +import com.android.apksigner.core.util.DataSource; +import com.android.apksigner.core.util.DataSources; + +import java.io.IOException; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.security.DigestException; +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; +import java.security.KeyFactory; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.security.Signature; +import java.security.SignatureException; +import java.security.cert.CertificateEncodingException; +import java.security.cert.X509Certificate; +import java.security.interfaces.ECKey; +import java.security.interfaces.RSAKey; +import java.security.spec.AlgorithmParameterSpec; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.X509EncodedKeySpec; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * APK Signature Scheme v2 signer. + * + *

APK Signature Scheme v2 is a whole-file signature scheme which aims to protect every single + * bit of the APK, as opposed to the JAR Signature Scheme which protects only the names and + * uncompressed contents of ZIP entries. + * + *

TODO: Link to APK Signature Scheme v2 documentation once it's available. + */ +public abstract class V2SchemeSigner { + /* + * The two main goals of APK Signature Scheme v2 are: + * 1. Detect any unauthorized modifications to the APK. This is achieved by making the signature + * cover every byte of the APK being signed. + * 2. Enable much faster signature and integrity verification. This is achieved by requiring + * only a minimal amount of APK parsing before the signature is verified, thus completely + * bypassing ZIP entry decompression and by making integrity verification parallelizable by + * employing a hash tree. + * + * The generated signature block is wrapped into an APK Signing Block and inserted into the + * original APK immediately before the start of ZIP Central Directory. This is to ensure that + * JAR and ZIP parsers continue to work on the signed APK. The APK Signing Block is designed for + * extensibility. For example, a future signature scheme could insert its signatures there as + * well. The contract of the APK Signing Block is that all contents outside of the block must be + * protected by signatures inside the block. + */ + + private static final int CONTENT_DIGESTED_CHUNK_MAX_SIZE_BYTES = 1024 * 1024; + + private static final byte[] APK_SIGNING_BLOCK_MAGIC = + new byte[] { + 0x41, 0x50, 0x4b, 0x20, 0x53, 0x69, 0x67, 0x20, + 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x20, 0x34, 0x32, + }; + private static final int APK_SIGNATURE_SCHEME_V2_BLOCK_ID = 0x7109871a; + + /** + * Signer configuration. + */ + public static class SignerConfig { + /** Private key. */ + public PrivateKey privateKey; + + /** + * Certificates, with the first certificate containing the public key corresponding to + * {@link #privateKey}. + */ + public List certificates; + + /** + * List of signature algorithms with which to sign. + */ + public List signatureAlgorithms; + } + + /** Hidden constructor to prevent instantiation. */ + private V2SchemeSigner() {} + + /** + * Gets the APK Signature Scheme v2 signature algorithms to be used for signing an APK using the + * provided key. + * + * @param minSdkVersion minimum API Level of the platform on which the APK may be installed (see + * AndroidManifest.xml minSdkVersion attribute). + * + * @throws InvalidKeyException if the provided key is not suitable for signing APKs using + * APK Signature Scheme v2 + */ + public static List getSuggestedSignatureAlgorithms( + PublicKey signingKey, int minSdkVersion) throws InvalidKeyException { + String keyAlgorithm = signingKey.getAlgorithm(); + if ("RSA".equalsIgnoreCase(keyAlgorithm)) { + // Use RSASSA-PKCS1-v1_5 signature scheme instead of RSASSA-PSS to guarantee + // deterministic signatures which make life easier for OTA updates (fewer files + // changed when deterministic signature schemes are used). + + // Pick a digest which is no weaker than the key. + int modulusLengthBits = ((RSAKey) signingKey).getModulus().bitLength(); + if (modulusLengthBits <= 3072) { + // 3072-bit RSA is roughly 128-bit strong, meaning SHA-256 is a good fit. + return Collections.singletonList(SignatureAlgorithm.RSA_PKCS1_V1_5_WITH_SHA256); + } else { + // Keys longer than 3072 bit need to be paired with a stronger digest to avoid the + // digest being the weak link. SHA-512 is the next strongest supported digest. + return Collections.singletonList(SignatureAlgorithm.RSA_PKCS1_V1_5_WITH_SHA512); + } + } else if ("DSA".equalsIgnoreCase(keyAlgorithm)) { + // DSA is supported only with SHA-256. + return Collections.singletonList(SignatureAlgorithm.DSA_WITH_SHA256); + } else if ("EC".equalsIgnoreCase(keyAlgorithm)) { + // Pick a digest which is no weaker than the key. + int keySizeBits = ((ECKey) signingKey).getParams().getOrder().bitLength(); + if (keySizeBits <= 256) { + // 256-bit Elliptic Curve is roughly 128-bit strong, meaning SHA-256 is a good fit. + return Collections.singletonList(SignatureAlgorithm.ECDSA_WITH_SHA256); + } else { + // Keys longer than 256 bit need to be paired with a stronger digest to avoid the + // digest being the weak link. SHA-512 is the next strongest supported digest. + return Collections.singletonList(SignatureAlgorithm.ECDSA_WITH_SHA512); + } + } else { + throw new InvalidKeyException("Unsupported key algorithm: " + keyAlgorithm); + } + } + + /** + * Signs the provided APK using APK Signature Scheme v2 and returns the APK Signing Block + * containing the signature. + * + * @param signerConfigs signer configurations, one for each signer At least one signer config + * must be provided. + * + * @throws IOException if an I/O error occurs + * @throws InvalidKeyException if a signing key is not suitable for this signature scheme or + * cannot be used in general + * @throws SignatureException if an error occurs when computing digests of generating + * signatures + */ + public static byte[] generateApkSigningBlock( + DataSource beforeCentralDir, + DataSource centralDir, + DataSource eocd, + List signerConfigs) + throws IOException, InvalidKeyException, SignatureException { + if (signerConfigs.isEmpty()) { + throw new IllegalArgumentException( + "No signer configs provided. At least one is required"); + } + + // Figure out which digest(s) to use for APK contents. + Set contentDigestAlgorithms = new HashSet<>(1); + for (SignerConfig signerConfig : signerConfigs) { + for (SignatureAlgorithm signatureAlgorithm : signerConfig.signatureAlgorithms) { + contentDigestAlgorithms.add(signatureAlgorithm.getContentDigestAlgorithm()); + } + } + + // Ensure that, when digesting, ZIP End of Central Directory record's Central Directory + // offset field is treated as pointing to the offset at which the APK Signing Block will + // start. + long centralDirOffsetForDigesting = beforeCentralDir.size(); + ByteBuffer eocdBuf = ByteBuffer.allocate((int) eocd.size()); + eocdBuf.order(ByteOrder.LITTLE_ENDIAN); + eocd.copyTo(0, (int) eocd.size(), eocdBuf); + eocdBuf.flip(); + ZipUtils.setZipEocdCentralDirectoryOffset(eocdBuf, centralDirOffsetForDigesting); + + // Compute digests of APK contents. + Map contentDigests; // digest algorithm ID -> digest + try { + contentDigests = + computeContentDigests( + contentDigestAlgorithms, + new DataSource[] { + beforeCentralDir, + centralDir, + DataSources.asDataSource(eocdBuf)}); + } catch (IOException e) { + throw new IOException("Failed to read APK being signed", e); + } catch (DigestException e) { + throw new SignatureException("Failed to compute digests of APK", e); + } + + // Sign the digests and wrap the signatures and signer info into an APK Signing Block. + return generateApkSigningBlock(signerConfigs, contentDigests); + } + + static Map computeContentDigests( + Set digestAlgorithms, + DataSource[] contents) throws IOException, DigestException { + // For each digest algorithm the result is computed as follows: + // 1. Each segment of contents is split into consecutive chunks of 1 MB in size. + // The final chunk will be shorter iff the length of segment is not a multiple of 1 MB. + // No chunks are produced for empty (zero length) segments. + // 2. The digest of each chunk is computed over the concatenation of byte 0xa5, the chunk's + // length in bytes (uint32 little-endian) and the chunk's contents. + // 3. The output digest is computed over the concatenation of the byte 0x5a, the number of + // chunks (uint32 little-endian) and the concatenation of digests of chunks of all + // segments in-order. + + long chunkCountLong = 0; + for (DataSource input : contents) { + chunkCountLong += + getChunkCount(input.size(), CONTENT_DIGESTED_CHUNK_MAX_SIZE_BYTES); + } + if (chunkCountLong > Integer.MAX_VALUE) { + throw new DigestException("Input too long: " + chunkCountLong + " chunks"); + } + int chunkCount = (int) chunkCountLong; + + ContentDigestAlgorithm[] digestAlgorithmsArray = + digestAlgorithms.toArray(new ContentDigestAlgorithm[digestAlgorithms.size()]); + MessageDigest[] mds = new MessageDigest[digestAlgorithmsArray.length]; + byte[][] digestsOfChunks = new byte[digestAlgorithmsArray.length][]; + int[] digestOutputSizes = new int[digestAlgorithmsArray.length]; + for (int i = 0; i < digestAlgorithmsArray.length; i++) { + ContentDigestAlgorithm digestAlgorithm = digestAlgorithmsArray[i]; + int digestOutputSizeBytes = digestAlgorithm.getChunkDigestOutputSizeBytes(); + digestOutputSizes[i] = digestOutputSizeBytes; + byte[] concatenationOfChunkCountAndChunkDigests = + new byte[5 + chunkCount * digestOutputSizeBytes]; + concatenationOfChunkCountAndChunkDigests[0] = 0x5a; + setUnsignedInt32LittleEndian( + chunkCount, concatenationOfChunkCountAndChunkDigests, 1); + digestsOfChunks[i] = concatenationOfChunkCountAndChunkDigests; + String jcaAlgorithm = digestAlgorithm.getJcaMessageDigestAlgorithm(); + try { + mds[i] = MessageDigest.getInstance(jcaAlgorithm); + } catch (NoSuchAlgorithmException e) { + throw new RuntimeException(jcaAlgorithm + " MessageDigest not supported", e); + } + } + + MessageDigestSink mdSink = new MessageDigestSink(mds); + byte[] chunkContentPrefix = new byte[5]; + chunkContentPrefix[0] = (byte) 0xa5; + int chunkIndex = 0; + // Optimization opportunity: digests of chunks can be computed in parallel. However, + // determining the number of computations to be performed in parallel is non-trivial. This + // depends on a wide range of factors, such as data source type (e.g., in-memory or fetched + // from file), CPU/memory/disk cache bandwidth and latency, interconnect architecture of CPU + // cores, load on the system from other threads of execution and other processes, size of + // input. + // For now, we compute these digests sequentially and thus have the luxury of improving + // performance by writing the digest of each chunk into a pre-allocated buffer at exactly + // the right position. This avoids unnecessary allocations, copying, and enables the final + // digest to be more efficient because it's presented with all of its input in one go. + for (DataSource input : contents) { + long inputOffset = 0; + long inputRemaining = input.size(); + while (inputRemaining > 0) { + int chunkSize = + (int) Math.min(inputRemaining, CONTENT_DIGESTED_CHUNK_MAX_SIZE_BYTES); + setUnsignedInt32LittleEndian(chunkSize, chunkContentPrefix, 1); + for (int i = 0; i < mds.length; i++) { + mds[i].update(chunkContentPrefix); + } + try { + input.feed(inputOffset, chunkSize, mdSink); + } catch (IOException e) { + throw new IOException("Failed to read chunk #" + chunkIndex, e); + } + for (int i = 0; i < digestAlgorithmsArray.length; i++) { + MessageDigest md = mds[i]; + byte[] concatenationOfChunkCountAndChunkDigests = digestsOfChunks[i]; + int expectedDigestSizeBytes = digestOutputSizes[i]; + int actualDigestSizeBytes = + md.digest( + concatenationOfChunkCountAndChunkDigests, + 5 + chunkIndex * expectedDigestSizeBytes, + expectedDigestSizeBytes); + if (actualDigestSizeBytes != expectedDigestSizeBytes) { + throw new RuntimeException( + "Unexpected output size of " + md.getAlgorithm() + + " digest: " + actualDigestSizeBytes); + } + } + inputOffset += chunkSize; + inputRemaining -= chunkSize; + chunkIndex++; + } + } + + Map result = new HashMap<>(digestAlgorithmsArray.length); + for (int i = 0; i < digestAlgorithmsArray.length; i++) { + ContentDigestAlgorithm digestAlgorithm = digestAlgorithmsArray[i]; + byte[] concatenationOfChunkCountAndChunkDigests = digestsOfChunks[i]; + MessageDigest md = mds[i]; + byte[] digest = md.digest(concatenationOfChunkCountAndChunkDigests); + result.put(digestAlgorithm, digest); + } + return result; + } + + private static final long getChunkCount(long inputSize, int chunkSize) { + return (inputSize + chunkSize - 1) / chunkSize; + } + + private static void setUnsignedInt32LittleEndian(int value, byte[] result, int offset) { + result[offset] = (byte) (value & 0xff); + result[offset + 1] = (byte) ((value >> 8) & 0xff); + result[offset + 2] = (byte) ((value >> 16) & 0xff); + result[offset + 3] = (byte) ((value >> 24) & 0xff); + } + + private static byte[] generateApkSigningBlock( + List signerConfigs, + Map contentDigests) + throws InvalidKeyException, SignatureException { + byte[] apkSignatureSchemeV2Block = + generateApkSignatureSchemeV2Block(signerConfigs, contentDigests); + return generateApkSigningBlock(apkSignatureSchemeV2Block); + } + + private static byte[] generateApkSigningBlock(byte[] apkSignatureSchemeV2Block) { + // FORMAT: + // uint64: size (excluding this field) + // repeated ID-value pairs: + // uint64: size (excluding this field) + // uint32: ID + // (size - 4) bytes: value + // uint64: size (same as the one above) + // uint128: magic + + int resultSize = + 8 // size + + 8 + 4 + apkSignatureSchemeV2Block.length // v2Block as ID-value pair + + 8 // size + + 16 // magic + ; + ByteBuffer result = ByteBuffer.allocate(resultSize); + result.order(ByteOrder.LITTLE_ENDIAN); + long blockSizeFieldValue = resultSize - 8; + result.putLong(blockSizeFieldValue); + + long pairSizeFieldValue = 4 + apkSignatureSchemeV2Block.length; + result.putLong(pairSizeFieldValue); + result.putInt(APK_SIGNATURE_SCHEME_V2_BLOCK_ID); + result.put(apkSignatureSchemeV2Block); + + result.putLong(blockSizeFieldValue); + result.put(APK_SIGNING_BLOCK_MAGIC); + + return result.array(); + } + + private static byte[] generateApkSignatureSchemeV2Block( + List signerConfigs, + Map contentDigests) + throws InvalidKeyException, SignatureException { + // FORMAT: + // * length-prefixed sequence of length-prefixed signer blocks. + + List signerBlocks = new ArrayList<>(signerConfigs.size()); + int signerNumber = 0; + for (SignerConfig signerConfig : signerConfigs) { + signerNumber++; + byte[] signerBlock; + try { + signerBlock = generateSignerBlock(signerConfig, contentDigests); + } catch (InvalidKeyException e) { + throw new InvalidKeyException("Signer #" + signerNumber + " failed", e); + } catch (SignatureException e) { + throw new SignatureException("Signer #" + signerNumber + " failed", e); + } + signerBlocks.add(signerBlock); + } + + return encodeAsSequenceOfLengthPrefixedElements( + new byte[][] { + encodeAsSequenceOfLengthPrefixedElements(signerBlocks), + }); + } + + private static byte[] generateSignerBlock( + SignerConfig signerConfig, + Map contentDigests) + throws InvalidKeyException, SignatureException { + if (signerConfig.certificates.isEmpty()) { + throw new SignatureException("No certificates configured for signer"); + } + PublicKey publicKey = signerConfig.certificates.get(0).getPublicKey(); + + byte[] encodedPublicKey = encodePublicKey(publicKey); + + V2SignatureSchemeBlock.SignedData signedData = new V2SignatureSchemeBlock.SignedData(); + try { + signedData.certificates = encodeCertificates(signerConfig.certificates); + } catch (CertificateEncodingException e) { + throw new SignatureException("Failed to encode certificates", e); + } + + List> digests = + new ArrayList<>(signerConfig.signatureAlgorithms.size()); + for (SignatureAlgorithm signatureAlgorithm : signerConfig.signatureAlgorithms) { + ContentDigestAlgorithm contentDigestAlgorithm = + signatureAlgorithm.getContentDigestAlgorithm(); + byte[] contentDigest = contentDigests.get(contentDigestAlgorithm); + if (contentDigest == null) { + throw new RuntimeException( + contentDigestAlgorithm + " content digest for " + signatureAlgorithm + + " not computed"); + } + digests.add(Pair.of(signatureAlgorithm.getId(), contentDigest)); + } + signedData.digests = digests; + + V2SignatureSchemeBlock.Signer signer = new V2SignatureSchemeBlock.Signer(); + // FORMAT: + // * length-prefixed sequence of length-prefixed digests: + // * uint32: signature algorithm ID + // * length-prefixed bytes: digest of contents + // * length-prefixed sequence of certificates: + // * length-prefixed bytes: X.509 certificate (ASN.1 DER encoded). + // * length-prefixed sequence of length-prefixed additional attributes: + // * uint32: ID + // * (length - 4) bytes: value + signer.signedData = encodeAsSequenceOfLengthPrefixedElements(new byte[][] { + encodeAsSequenceOfLengthPrefixedPairsOfIntAndLengthPrefixedBytes(signedData.digests), + encodeAsSequenceOfLengthPrefixedElements(signedData.certificates), + // additional attributes + new byte[0], + }); + signer.publicKey = encodedPublicKey; + signer.signatures = new ArrayList<>(signerConfig.signatureAlgorithms.size()); + for (SignatureAlgorithm signatureAlgorithm : signerConfig.signatureAlgorithms) { + Pair sigAlgAndParams = + signatureAlgorithm.getJcaSignatureAlgorithmAndParams(); + String jcaSignatureAlgorithm = sigAlgAndParams.getFirst(); + AlgorithmParameterSpec jcaSignatureAlgorithmParams = sigAlgAndParams.getSecond(); + byte[] signatureBytes; + try { + Signature signature = Signature.getInstance(jcaSignatureAlgorithm); + signature.initSign(signerConfig.privateKey); + if (jcaSignatureAlgorithmParams != null) { + signature.setParameter(jcaSignatureAlgorithmParams); + } + signature.update(signer.signedData); + signatureBytes = signature.sign(); + } catch (InvalidKeyException e) { + throw new InvalidKeyException("Failed sign using " + jcaSignatureAlgorithm, e); + } catch (NoSuchAlgorithmException | InvalidAlgorithmParameterException + | SignatureException e) { + throw new SignatureException("Failed sign using " + jcaSignatureAlgorithm, e); + } + + try { + Signature signature = Signature.getInstance(jcaSignatureAlgorithm); + signature.initVerify(publicKey); + if (jcaSignatureAlgorithmParams != null) { + signature.setParameter(jcaSignatureAlgorithmParams); + } + signature.update(signer.signedData); + if (!signature.verify(signatureBytes)) { + throw new SignatureException("Signature did not verify"); + } + } catch (InvalidKeyException e) { + throw new InvalidKeyException("Failed to verify generated " + jcaSignatureAlgorithm + + " signature using public key from certificate", e); + } catch (NoSuchAlgorithmException | InvalidAlgorithmParameterException + | SignatureException e) { + throw new SignatureException("Failed to verify generated " + jcaSignatureAlgorithm + + " signature using public key from certificate", e); + } + + signer.signatures.add(Pair.of(signatureAlgorithm.getId(), signatureBytes)); + } + + // FORMAT: + // * length-prefixed signed data + // * length-prefixed sequence of length-prefixed signatures: + // * uint32: signature algorithm ID + // * length-prefixed bytes: signature of signed data + // * length-prefixed bytes: public key (X.509 SubjectPublicKeyInfo, ASN.1 DER encoded) + return encodeAsSequenceOfLengthPrefixedElements( + new byte[][] { + signer.signedData, + encodeAsSequenceOfLengthPrefixedPairsOfIntAndLengthPrefixedBytes( + signer.signatures), + signer.publicKey, + }); + } + + private static final class V2SignatureSchemeBlock { + private static final class Signer { + public byte[] signedData; + public List> signatures; + public byte[] publicKey; + } + + private static final class SignedData { + public List> digests; + public List certificates; + } + } + + private static byte[] encodePublicKey(PublicKey publicKey) throws InvalidKeyException { + byte[] encodedPublicKey = null; + if ("X.509".equals(publicKey.getFormat())) { + encodedPublicKey = publicKey.getEncoded(); + } + if (encodedPublicKey == null) { + try { + encodedPublicKey = + KeyFactory.getInstance(publicKey.getAlgorithm()) + .getKeySpec(publicKey, X509EncodedKeySpec.class) + .getEncoded(); + } catch (NoSuchAlgorithmException e) { + throw new InvalidKeyException( + "Failed to obtain X.509 encoded form of public key " + publicKey + + " of class " + publicKey.getClass().getName(), + e); + } catch (InvalidKeySpecException e) { + throw new InvalidKeyException( + "Failed to obtain X.509 encoded form of public key " + publicKey + + " of class " + publicKey.getClass().getName(), + e); + } + } + if ((encodedPublicKey == null) || (encodedPublicKey.length == 0)) { + throw new InvalidKeyException( + "Failed to obtain X.509 encoded form of public key " + publicKey + + " of class " + publicKey.getClass().getName()); + } + return encodedPublicKey; + } + + private static List encodeCertificates(List certificates) + throws CertificateEncodingException { + List result = new ArrayList<>(certificates.size()); + for (X509Certificate certificate : certificates) { + result.add(certificate.getEncoded()); + } + return result; + } + + private static byte[] encodeAsSequenceOfLengthPrefixedElements(List sequence) { + return encodeAsSequenceOfLengthPrefixedElements( + sequence.toArray(new byte[sequence.size()][])); + } + + private static byte[] encodeAsSequenceOfLengthPrefixedElements(byte[][] sequence) { + int payloadSize = 0; + for (byte[] element : sequence) { + payloadSize += 4 + element.length; + } + ByteBuffer result = ByteBuffer.allocate(payloadSize); + result.order(ByteOrder.LITTLE_ENDIAN); + for (byte[] element : sequence) { + result.putInt(element.length); + result.put(element); + } + return result.array(); + } + + private static byte[] encodeAsSequenceOfLengthPrefixedPairsOfIntAndLengthPrefixedBytes( + List> sequence) { + int resultSize = 0; + for (Pair element : sequence) { + resultSize += 12 + element.getSecond().length; + } + ByteBuffer result = ByteBuffer.allocate(resultSize); + result.order(ByteOrder.LITTLE_ENDIAN); + for (Pair element : sequence) { + byte[] second = element.getSecond(); + result.putInt(8 + second.length); + result.putInt(element.getFirst()); + result.putInt(second.length); + result.put(second); + } + return result.array(); + } +} diff --git a/plugin/src/main/java/com/android/apksigner/core/internal/apk/v2/V2SchemeVerifier.java b/plugin/src/main/java/com/android/apksigner/core/internal/apk/v2/V2SchemeVerifier.java new file mode 100644 index 0000000..509752e --- /dev/null +++ b/plugin/src/main/java/com/android/apksigner/core/internal/apk/v2/V2SchemeVerifier.java @@ -0,0 +1,939 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.apksigner.core.internal.apk.v2; + +import com.android.apksigner.core.ApkVerifier.Issue; +import com.android.apksigner.core.ApkVerifier.IssueWithParams; +import com.android.apksigner.core.apk.ApkUtils; +import com.android.apksigner.core.internal.util.ByteBufferDataSource; +import com.android.apksigner.core.internal.util.DelegatingX509Certificate; +import com.android.apksigner.core.internal.util.Pair; +import com.android.apksigner.core.internal.zip.ZipUtils; +import com.android.apksigner.core.util.DataSource; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.nio.BufferUnderflowException; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.security.DigestException; +import java.security.KeyFactory; +import java.security.PublicKey; +import java.security.Signature; +import java.security.cert.CertificateEncodingException; +import java.security.cert.CertificateException; +import java.security.cert.CertificateFactory; +import java.security.cert.X509Certificate; +import java.security.spec.AlgorithmParameterSpec; +import java.security.spec.X509EncodedKeySpec; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * APK Signature Scheme v2 verifier. + * + *

APK Signature Scheme v2 is a whole-file signature scheme which aims to protect every single + * bit of the APK, as opposed to the JAR Signature Scheme which protects only the names and + * uncompressed contents of ZIP entries. + * + *

TODO: Link to APK Signature Scheme v2 documentation once it's available. + */ +public abstract class V2SchemeVerifier { + + public static final long APK_SIG_BLOCK_MAGIC_HI = 0x3234206b636f6c42L; + public static final long APK_SIG_BLOCK_MAGIC_LO = 0x20676953204b5041L; + private static final int APK_SIG_BLOCK_MIN_SIZE = 32; + + private static final int APK_SIGNATURE_SCHEME_V2_BLOCK_ID = 0x7109871a; + + /** Hidden constructor to prevent instantiation. */ + private V2SchemeVerifier() {} + + /** + * Verifies the provided APK's APK Signature Scheme v2 signatures and returns the result of + * verification. APK is considered verified only if {@link Result#verified} is {@code true}. If + * verification fails, the result will contain errors -- see {@link Result#getErrors()}. + * + * @throws SignatureNotFoundException if no APK Signature Scheme v2 signatures are found + * @throws IOException if an I/O error occurs when reading the APK + */ + public static Result verify(DataSource apk, ApkUtils.ZipSections zipSections) + throws IOException, SignatureNotFoundException { + Result result = new Result(); + SignatureInfo signatureInfo = findSignature(apk, zipSections, result); + + DataSource beforeApkSigningBlock = apk.slice(0, signatureInfo.apkSigningBlockOffset); + DataSource centralDir = + apk.slice( + signatureInfo.centralDirOffset, + signatureInfo.eocdOffset - signatureInfo.centralDirOffset); + ByteBuffer eocd = signatureInfo.eocd; + + verify(beforeApkSigningBlock, + signatureInfo.signatureBlock, + centralDir, + eocd, + result); + return result; + } + + /** + * Verifies the provided APK's v2 signatures and outputs the results into the provided + * {@code result}. APK is considered verified only if there are no errors reported in the + * {@code result}. + */ + private static void verify( + DataSource beforeApkSigningBlock, + ByteBuffer apkSignatureSchemeV2Block, + DataSource centralDir, + ByteBuffer eocd, + Result result) throws IOException { + Set contentDigestsToVerify = new HashSet<>(1); + parseSigners(apkSignatureSchemeV2Block, contentDigestsToVerify, result); + if (result.containsErrors()) { + return; + } + verifyIntegrity( + beforeApkSigningBlock, centralDir, eocd, contentDigestsToVerify, result); + if (!result.containsErrors()) { + result.verified = true; + } + } + + /** + * Parses each signer in the provided APK Signature Scheme v2 block and populates + * {@code signerInfos} of the provided {@code result}. + * + *

This verifies signatures over {@code signed-data} block contained in each signer block. + * However, this does not verify the integrity of the rest of the APK but rather simply reports + * the expected digests of the rest of the APK (see {@code contentDigestsToVerify}). + */ + private static void parseSigners( + ByteBuffer apkSignatureSchemeV2Block, + Set contentDigestsToVerify, + Result result) { + ByteBuffer signers; + try { + signers = getLengthPrefixedSlice(apkSignatureSchemeV2Block); + } catch (IOException e) { + result.addError(Issue.V2_SIG_MALFORMED_SIGNERS); + return; + } + if (!signers.hasRemaining()) { + result.addError(Issue.V2_SIG_NO_SIGNERS); + return; + } + + CertificateFactory certFactory; + try { + certFactory = CertificateFactory.getInstance("X.509"); + } catch (CertificateException e) { + throw new RuntimeException("Failed to obtain X.509 CertificateFactory", e); + } + int signerCount = 0; + while (signers.hasRemaining()) { + int signerIndex = signerCount; + signerCount++; + Result.SignerInfo signerInfo = new Result.SignerInfo(); + signerInfo.index = signerIndex; + result.signers.add(signerInfo); + try { + ByteBuffer signer = getLengthPrefixedSlice(signers); + parseSigner(signer, certFactory, signerInfo, contentDigestsToVerify); + } catch (IOException | BufferUnderflowException e) { + signerInfo.addError(Issue.V2_SIG_MALFORMED_SIGNER); + return; + } + } + } + + /** + * Parses the provided signer block and populates the {@code result}. + * + *

This verifies signatures over {@code signed-data} contained in this block but does not + * verify the integrity of the rest of the APK. Rather, this method adds to the + * {@code contentDigestsToVerify}. + */ + private static void parseSigner( + ByteBuffer signerBlock, + CertificateFactory certFactory, + Result.SignerInfo result, + Set contentDigestsToVerify) throws IOException { + ByteBuffer signedData = getLengthPrefixedSlice(signerBlock); + byte[] signedDataBytes = new byte[signedData.remaining()]; + signedData.get(signedDataBytes); + signedData.flip(); + result.signedData = signedDataBytes; + + ByteBuffer signatures = getLengthPrefixedSlice(signerBlock); + byte[] publicKeyBytes = readLengthPrefixedByteArray(signerBlock); + + // Parse the signatures block and identify supported signatures + int signatureCount = 0; + List supportedSignatures = new ArrayList<>(1); + while (signatures.hasRemaining()) { + signatureCount++; + try { + ByteBuffer signature = getLengthPrefixedSlice(signatures); + int sigAlgorithmId = signature.getInt(); + byte[] sigBytes = readLengthPrefixedByteArray(signature); + result.signatures.add( + new Result.SignerInfo.Signature(sigAlgorithmId, sigBytes)); + SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.findById(sigAlgorithmId); + if (signatureAlgorithm == null) { + result.addWarning(Issue.V2_SIG_UNKNOWN_SIG_ALGORITHM, sigAlgorithmId); + continue; + } + supportedSignatures.add(new SupportedSignature(signatureAlgorithm, sigBytes)); + } catch (IOException | BufferUnderflowException e) { + result.addError(Issue.V2_SIG_MALFORMED_SIGNATURE, signatureCount); + return; + } + } + if (result.signatures.isEmpty()) { + result.addError(Issue.V2_SIG_NO_SIGNATURES); + return; + } + + // Verify signatures over signed-data block using the public key + List signaturesToVerify = getSignaturesToVerify(supportedSignatures); + if (signaturesToVerify.isEmpty()) { + result.addError(Issue.V2_SIG_NO_SUPPORTED_SIGNATURES); + return; + } + for (SupportedSignature signature : signaturesToVerify) { + SignatureAlgorithm signatureAlgorithm = signature.algorithm; + String jcaSignatureAlgorithm = + signatureAlgorithm.getJcaSignatureAlgorithmAndParams().getFirst(); + AlgorithmParameterSpec jcaSignatureAlgorithmParams = + signatureAlgorithm.getJcaSignatureAlgorithmAndParams().getSecond(); + String keyAlgorithm = signatureAlgorithm.getJcaKeyAlgorithm(); + PublicKey publicKey; + try { + publicKey = + KeyFactory.getInstance(keyAlgorithm).generatePublic( + new X509EncodedKeySpec(publicKeyBytes)); + } catch (Exception e) { + result.addError(Issue.V2_SIG_MALFORMED_PUBLIC_KEY, e); + return; + } + try { + Signature sig = Signature.getInstance(jcaSignatureAlgorithm); + sig.initVerify(publicKey); + if (jcaSignatureAlgorithmParams != null) { + sig.setParameter(jcaSignatureAlgorithmParams); + } + signedData.position(0); + sig.update(signedData); + byte[] sigBytes = signature.signature; + if (!sig.verify(sigBytes)) { + result.addError(Issue.V2_SIG_DID_NOT_VERIFY, signatureAlgorithm); + return; + } + result.verifiedSignatures.put(signatureAlgorithm, sigBytes); + contentDigestsToVerify.add(signatureAlgorithm.getContentDigestAlgorithm()); + } catch (Exception e) { + result.addError(Issue.V2_SIG_VERIFY_EXCEPTION, signatureAlgorithm, e); + return; + } + } + + // At least one signature over signedData has verified. We can now parse signed-data. + signedData.position(0); + ByteBuffer digests = getLengthPrefixedSlice(signedData); + ByteBuffer certificates = getLengthPrefixedSlice(signedData); + ByteBuffer additionalAttributes = getLengthPrefixedSlice(signedData); + + // Parse the certificates block + int certificateIndex = -1; + while (certificates.hasRemaining()) { + certificateIndex++; + byte[] encodedCert = readLengthPrefixedByteArray(certificates); + X509Certificate certificate; + try { + certificate = + (X509Certificate) + certFactory.generateCertificate( + new ByteArrayInputStream(encodedCert)); + } catch (CertificateException e) { + result.addError( + Issue.V2_SIG_MALFORMED_CERTIFICATE, + certificateIndex, + certificateIndex + 1, + e); + return; + } + // Wrap the cert so that the result's getEncoded returns exactly the original encoded + // form. Without this, getEncoded may return a different form from what was stored in + // the signature. This is becase some X509Certificate(Factory) implementations re-encode + // certificates. + certificate = new GuaranteedEncodedFormX509Certificate(certificate, encodedCert); + result.certs.add(certificate); + } + + if (result.certs.isEmpty()) { + result.addError(Issue.V2_SIG_NO_CERTIFICATES); + return; + } + X509Certificate mainCertificate = result.certs.get(0); + byte[] certificatePublicKeyBytes = mainCertificate.getPublicKey().getEncoded(); + if (!Arrays.equals(publicKeyBytes, certificatePublicKeyBytes)) { + result.addError( + Issue.V2_SIG_PUBLIC_KEY_MISMATCH_BETWEEN_CERTIFICATE_AND_SIGNATURES_RECORD, + toHex(certificatePublicKeyBytes), + toHex(publicKeyBytes)); + return; + } + + // Parse the digests block + int digestCount = 0; + while (digests.hasRemaining()) { + digestCount++; + try { + ByteBuffer digest = getLengthPrefixedSlice(digests); + int sigAlgorithmId = digest.getInt(); + byte[] digestBytes = readLengthPrefixedByteArray(digest); + result.contentDigests.add( + new Result.SignerInfo.ContentDigest(sigAlgorithmId, digestBytes)); + } catch (IOException | BufferUnderflowException e) { + result.addError(Issue.V2_SIG_MALFORMED_DIGEST, digestCount); + return; + } + } + + List sigAlgsFromSignaturesRecord = new ArrayList<>(result.signatures.size()); + for (Result.SignerInfo.Signature signature : result.signatures) { + sigAlgsFromSignaturesRecord.add(signature.getAlgorithmId()); + } + List sigAlgsFromDigestsRecord = new ArrayList<>(result.contentDigests.size()); + for (Result.SignerInfo.ContentDigest digest : result.contentDigests) { + sigAlgsFromDigestsRecord.add(digest.getSignatureAlgorithmId()); + } + + if (!sigAlgsFromSignaturesRecord.equals(sigAlgsFromDigestsRecord)) { + result.addError( + Issue.V2_SIG_SIG_ALG_MISMATCH_BETWEEN_SIGNATURES_AND_DIGESTS_RECORDS, + sigAlgsFromSignaturesRecord, + sigAlgsFromDigestsRecord); + return; + } + + // Parse the additional attributes block. + int additionalAttributeCount = 0; + while (additionalAttributes.hasRemaining()) { + additionalAttributeCount++; + try { + ByteBuffer attribute = getLengthPrefixedSlice(additionalAttributes); + int id = attribute.getInt(); + byte[] value = readLengthPrefixedByteArray(attribute); + result.additionalAttributes.add( + new Result.SignerInfo.AdditionalAttribute(id, value)); + result.addWarning(Issue.V2_SIG_UNKNOWN_ADDITIONAL_ATTRIBUTE, id); + } catch (IOException | BufferUnderflowException e) { + result.addError( + Issue.V2_SIG_MALFORMED_ADDITIONAL_ATTRIBUTE, additionalAttributeCount); + return; + } + } + } + + private static List getSignaturesToVerify( + List signatures) { + // Pick the signature with the strongest algorithm, to mimic Android's behavior. + SignatureAlgorithm bestSigAlgorithm = null; + byte[] bestSigAlgorithmSignatureBytes = null; + for (SupportedSignature sig : signatures) { + SignatureAlgorithm sigAlgorithm = sig.algorithm; + if ((bestSigAlgorithm == null) + || (compareSignatureAlgorithm(sigAlgorithm, bestSigAlgorithm) > 0)) { + bestSigAlgorithm = sigAlgorithm; + bestSigAlgorithmSignatureBytes = sig.signature; + } + } + + if (bestSigAlgorithm == null) { + return Collections.emptyList(); + } else { + return Collections.singletonList( + new SupportedSignature(bestSigAlgorithm, bestSigAlgorithmSignatureBytes)); + } + } + + private static class SupportedSignature { + private final SignatureAlgorithm algorithm; + private final byte[] signature; + + private SupportedSignature(SignatureAlgorithm algorithm, byte[] signature) { + this.algorithm = algorithm; + this.signature = signature; + } + } + + /** + * Returns positive number if {@code alg1} is preferred over {@code alg2}, {@code -1} if + * {@code alg2} is preferred over {@code alg1}, and {@code 0} if there is no preference. + */ + private static int compareSignatureAlgorithm(SignatureAlgorithm alg1, SignatureAlgorithm alg2) { + ContentDigestAlgorithm digestAlg1 = alg1.getContentDigestAlgorithm(); + ContentDigestAlgorithm digestAlg2 = alg2.getContentDigestAlgorithm(); + return compareContentDigestAlgorithm(digestAlg1, digestAlg2); + } + + /** + * Returns positive number if {@code alg1} is preferred over {@code alg2}, {@code -1} if + * {@code alg2} is preferred over {@code alg1}, and {@code 0} if there is no preference. + */ + private static int compareContentDigestAlgorithm( + ContentDigestAlgorithm alg1, + ContentDigestAlgorithm alg2) { + switch (alg1) { + case CHUNKED_SHA256: + switch (alg2) { + case CHUNKED_SHA256: + return 0; + case CHUNKED_SHA512: + return -1; + default: + throw new IllegalArgumentException("Unknown alg2: " + alg2); + } + case CHUNKED_SHA512: + switch (alg2) { + case CHUNKED_SHA256: + return 1; + case CHUNKED_SHA512: + return 0; + default: + throw new IllegalArgumentException("Unknown alg2: " + alg2); + } + default: + throw new IllegalArgumentException("Unknown alg1: " + alg1); + } + } + + /** + * Verifies integrity of the APK outside of the APK Signing Block by computing digests of the + * APK and comparing them against the digests listed in APK Signing Block. The expected digests + * taken from {@code v2SchemeSignerInfos} of the provided {@code result}. + */ + private static void verifyIntegrity( + DataSource beforeApkSigningBlock, + DataSource centralDir, + ByteBuffer eocd, + Set contentDigestAlgorithms, + Result result) throws IOException { + if (contentDigestAlgorithms.isEmpty()) { + // This should never occur because this method is invoked once at least one signature + // is verified, meaning at least one content digest is known. + throw new RuntimeException("No content digests found"); + } + + // For the purposes of verifying integrity, ZIP End of Central Directory (EoCD) must be + // treated as though its Central Directory offset points to the start of APK Signing Block. + // We thus modify the EoCD accordingly. + ByteBuffer modifiedEocd = ByteBuffer.allocate(eocd.remaining()); + modifiedEocd.order(ByteOrder.LITTLE_ENDIAN); + modifiedEocd.put(eocd); + modifiedEocd.flip(); + ZipUtils.setZipEocdCentralDirectoryOffset(modifiedEocd, beforeApkSigningBlock.size()); + Map actualContentDigests; + try { + actualContentDigests = + V2SchemeSigner.computeContentDigests( + contentDigestAlgorithms, + new DataSource[] { + beforeApkSigningBlock, + centralDir, + new ByteBufferDataSource(modifiedEocd) + }); + } catch (DigestException e) { + throw new RuntimeException("Failed to compute content digests", e); + } + if (!contentDigestAlgorithms.equals(actualContentDigests.keySet())) { + throw new RuntimeException( + "Mismatch between sets of requested and computed content digests" + + " . Requested: " + contentDigestAlgorithms + + ", computed: " + actualContentDigests.keySet()); + } + + // Compare digests computed over the rest of APK against the corresponding expected digests + // in signer blocks. + for (Result.SignerInfo signerInfo : result.signers) { + for (Result.SignerInfo.ContentDigest expected : signerInfo.contentDigests) { + SignatureAlgorithm signatureAlgorithm = + SignatureAlgorithm.findById(expected.getSignatureAlgorithmId()); + if (signatureAlgorithm == null) { + continue; + } + ContentDigestAlgorithm contentDigestAlgorithm = + signatureAlgorithm.getContentDigestAlgorithm(); + byte[] expectedDigest = expected.getValue(); + byte[] actualDigest = actualContentDigests.get(contentDigestAlgorithm); + if (!Arrays.equals(expectedDigest, actualDigest)) { + signerInfo.addError( + Issue.V2_SIG_APK_DIGEST_DID_NOT_VERIFY, + contentDigestAlgorithm, + toHex(expectedDigest), + toHex(actualDigest)); + continue; + } + signerInfo.verifiedContentDigests.put(contentDigestAlgorithm, actualDigest); + } + } + } + + /** + * APK Signature Scheme v2 block and additional information relevant to verifying the signatures + * contained in the block against the file. + */ + private static class SignatureInfo { + /** Contents of APK Signature Scheme v2 block. */ + private final ByteBuffer signatureBlock; + + /** Position of the APK Signing Block in the file. */ + private final long apkSigningBlockOffset; + + /** Position of the ZIP Central Directory in the file. */ + private final long centralDirOffset; + + /** Position of the ZIP End of Central Directory (EoCD) in the file. */ + private final long eocdOffset; + + /** Contents of ZIP End of Central Directory (EoCD) of the file. */ + private final ByteBuffer eocd; + + private SignatureInfo( + ByteBuffer signatureBlock, + long apkSigningBlockOffset, + long centralDirOffset, + long eocdOffset, + ByteBuffer eocd) { + this.signatureBlock = signatureBlock; + this.apkSigningBlockOffset = apkSigningBlockOffset; + this.centralDirOffset = centralDirOffset; + this.eocdOffset = eocdOffset; + this.eocd = eocd; + } + } + + /** + * Returns the APK Signature Scheme v2 block contained in the provided APK file and the + * additional information relevant for verifying the block against the file. + * + * @throws SignatureNotFoundException if the APK is not signed using APK Signature Scheme v2 + * @throws IOException if an I/O error occurs while reading the APK + */ + private static SignatureInfo findSignature( + DataSource apk, ApkUtils.ZipSections zipSections, Result result) + throws IOException, SignatureNotFoundException { + long centralDirStartOffset = zipSections.getZipCentralDirectoryOffset(); + long centralDirEndOffset = + centralDirStartOffset + zipSections.getZipCentralDirectorySizeBytes(); + long eocdStartOffset = zipSections.getZipEndOfCentralDirectoryOffset(); + if (centralDirEndOffset != eocdStartOffset) { + throw new SignatureNotFoundException( + "ZIP Central Directory is not immediately followed by End of Central Directory" + + ". CD end: " + centralDirEndOffset + + ", EoCD start: " + eocdStartOffset); + } + + // Find the APK Signing Block. The block immediately precedes the Central Directory. + ByteBuffer eocd = zipSections.getZipEndOfCentralDirectory(); + Pair apkSigningBlockAndOffset = + findApkSigningBlock(apk, centralDirStartOffset); + ByteBuffer apkSigningBlock = apkSigningBlockAndOffset.getFirst(); + long apkSigningBlockOffset = apkSigningBlockAndOffset.getSecond(); + + // Find the APK Signature Scheme v2 Block inside the APK Signing Block. + ByteBuffer apkSignatureSchemeV2Block = + findApkSignatureSchemeV2Block(apkSigningBlock, result); + + return new SignatureInfo( + apkSignatureSchemeV2Block, + apkSigningBlockOffset, + centralDirStartOffset, + eocdStartOffset, + eocd); + } + + public static Pair findApkSigningBlock( + DataSource apk, long centralDirOffset) throws IOException, SignatureNotFoundException { + // FORMAT: + // OFFSET DATA TYPE DESCRIPTION + // * @+0 bytes uint64: size in bytes (excluding this field) + // * @+8 bytes payload + // * @-24 bytes uint64: size in bytes (same as the one above) + // * @-16 bytes uint128: magic + + if (centralDirOffset < APK_SIG_BLOCK_MIN_SIZE) { + throw new SignatureNotFoundException( + "APK too small for APK Signing Block. ZIP Central Directory offset: " + + centralDirOffset); + } + // Read the magic and offset in file from the footer section of the block: + // * uint64: size of block + // * 16 bytes: magic + ByteBuffer footer = apk.getByteBuffer(centralDirOffset - 24, 24); + footer.order(ByteOrder.LITTLE_ENDIAN); + if ((footer.getLong(8) != APK_SIG_BLOCK_MAGIC_LO) + || (footer.getLong(16) != APK_SIG_BLOCK_MAGIC_HI)) { + throw new SignatureNotFoundException( + "No APK Signing Block before ZIP Central Directory"); + } + // Read and compare size fields + long apkSigBlockSizeInFooter = footer.getLong(0); + if ((apkSigBlockSizeInFooter < footer.capacity()) + || (apkSigBlockSizeInFooter > Integer.MAX_VALUE - 8)) { + throw new SignatureNotFoundException( + "APK Signing Block size out of range: " + apkSigBlockSizeInFooter); + } + int totalSize = (int) (apkSigBlockSizeInFooter + 8); + long apkSigBlockOffset = centralDirOffset - totalSize; + if (apkSigBlockOffset < 0) { + throw new SignatureNotFoundException( + "APK Signing Block offset out of range: " + apkSigBlockOffset); + } + ByteBuffer apkSigBlock = apk.getByteBuffer(apkSigBlockOffset, totalSize); + apkSigBlock.order(ByteOrder.LITTLE_ENDIAN); + long apkSigBlockSizeInHeader = apkSigBlock.getLong(0); + if (apkSigBlockSizeInHeader != apkSigBlockSizeInFooter) { + throw new SignatureNotFoundException( + "APK Signing Block sizes in header and footer do not match: " + + apkSigBlockSizeInHeader + " vs " + apkSigBlockSizeInFooter); + } + return Pair.of(apkSigBlock, apkSigBlockOffset); + } + + public static ByteBuffer findApkSignatureSchemeV2Block( + ByteBuffer apkSigningBlock, + Result result) throws SignatureNotFoundException { + checkByteOrderLittleEndian(apkSigningBlock); + // FORMAT: + // OFFSET DATA TYPE DESCRIPTION + // * @+0 bytes uint64: size in bytes (excluding this field) + // * @+8 bytes pairs + // * @-24 bytes uint64: size in bytes (same as the one above) + // * @-16 bytes uint128: magic + ByteBuffer pairs = sliceFromTo(apkSigningBlock, 8, apkSigningBlock.capacity() - 24); + + int entryCount = 0; + while (pairs.hasRemaining()) { + entryCount++; + if (pairs.remaining() < 8) { + throw new SignatureNotFoundException( + "Insufficient data to read size of APK Signing Block entry #" + entryCount); + } + long lenLong = pairs.getLong(); + if ((lenLong < 4) || (lenLong > Integer.MAX_VALUE)) { + throw new SignatureNotFoundException( + "APK Signing Block entry #" + entryCount + + " size out of range: " + lenLong); + } + int len = (int) lenLong; + int nextEntryPos = pairs.position() + len; + if (len > pairs.remaining()) { + throw new SignatureNotFoundException( + "APK Signing Block entry #" + entryCount + " size out of range: " + len + + ", available: " + pairs.remaining()); + } + int id = pairs.getInt(); + if (id == APK_SIGNATURE_SCHEME_V2_BLOCK_ID) { + return getByteBuffer(pairs, len - 4); + } + result.addWarning(Issue.APK_SIG_BLOCK_UNKNOWN_ENTRY_ID, id); + pairs.position(nextEntryPos); + } + + throw new SignatureNotFoundException( + "No APK Signature Scheme v2 block in APK Signing Block"); + } + + private static void checkByteOrderLittleEndian(ByteBuffer buffer) { + if (buffer.order() != ByteOrder.LITTLE_ENDIAN) { + throw new IllegalArgumentException("ByteBuffer byte order must be little endian"); + } + } + + public static class SignatureNotFoundException extends Exception { + private static final long serialVersionUID = 1L; + + public SignatureNotFoundException(String message) { + super(message); + } + + public SignatureNotFoundException(String message, Throwable cause) { + super(message, cause); + } + } + + /** + * Returns new byte buffer whose content is a shared subsequence of this buffer's content + * between the specified start (inclusive) and end (exclusive) positions. As opposed to + * {@link ByteBuffer#slice()}, the returned buffer's byte order is the same as the source + * buffer's byte order. + */ + private static ByteBuffer sliceFromTo(ByteBuffer source, int start, int end) { + if (start < 0) { + throw new IllegalArgumentException("start: " + start); + } + if (end < start) { + throw new IllegalArgumentException("end < start: " + end + " < " + start); + } + int capacity = source.capacity(); + if (end > source.capacity()) { + throw new IllegalArgumentException("end > capacity: " + end + " > " + capacity); + } + int originalLimit = source.limit(); + int originalPosition = source.position(); + try { + source.position(0); + source.limit(end); + source.position(start); + ByteBuffer result = source.slice(); + result.order(source.order()); + return result; + } finally { + source.position(0); + source.limit(originalLimit); + source.position(originalPosition); + } + } + + /** + * Relative get method for reading {@code size} number of bytes from the current + * position of this buffer. + * + *

This method reads the next {@code size} bytes at this buffer's current position, + * returning them as a {@code ByteBuffer} with start set to 0, limit and capacity set to + * {@code size}, byte order set to this buffer's byte order; and then increments the position by + * {@code size}. + */ + public static ByteBuffer getByteBuffer(ByteBuffer source, int size) + throws BufferUnderflowException { + if (size < 0) { + throw new IllegalArgumentException("size: " + size); + } + int originalLimit = source.limit(); + int position = source.position(); + int limit = position + size; + if ((limit < position) || (limit > originalLimit)) { + throw new BufferUnderflowException(); + } + source.limit(limit); + try { + ByteBuffer result = source.slice(); + result.order(source.order()); + source.position(limit); + return result; + } finally { + source.limit(originalLimit); + } + } + + public static ByteBuffer getLengthPrefixedSlice(ByteBuffer source) throws IOException { + if (source.remaining() < 4) { + throw new IOException( + "Remaining buffer too short to contain length of length-prefixed field." + + " Remaining: " + source.remaining()); + } + int len = source.getInt(); + if (len < 0) { + throw new IllegalArgumentException("Negative length"); + } else if (len > source.remaining()) { + throw new IOException("Length-prefixed field longer than remaining buffer." + + " Field length: " + len + ", remaining: " + source.remaining()); + } + return getByteBuffer(source, len); + } + + public static byte[] readLengthPrefixedByteArray(ByteBuffer buf) throws IOException { + int len = buf.getInt(); + if (len < 0) { + throw new IOException("Negative length"); + } else if (len > buf.remaining()) { + throw new IOException("Underflow while reading length-prefixed value. Length: " + len + + ", available: " + buf.remaining()); + } + byte[] result = new byte[len]; + buf.get(result); + return result; + } + + /** + * {@link X509Certificate} whose {@link #getEncoded()} returns the data provided at construction + * time. + */ + public static class GuaranteedEncodedFormX509Certificate extends DelegatingX509Certificate { + private byte[] mEncodedForm; + + public GuaranteedEncodedFormX509Certificate(X509Certificate wrapped, byte[] encodedForm) { + super(wrapped); + this.mEncodedForm = (encodedForm != null) ? encodedForm.clone() : null; + } + + @Override + public byte[] getEncoded() throws CertificateEncodingException { + return (mEncodedForm != null) ? mEncodedForm.clone() : null; + } + } + + private static final char[] HEX_DIGITS = "01234567890abcdef".toCharArray(); + + private static String toHex(byte[] value) { + StringBuilder sb = new StringBuilder(value.length * 2); + int len = value.length; + for (int i = 0; i < len; i++) { + int hi = (value[i] & 0xff) >>> 4; + int lo = value[i] & 0x0f; + sb.append(HEX_DIGITS[hi]).append(HEX_DIGITS[lo]); + } + return sb.toString(); + } + + public static class Result { + + /** Whether the APK's APK Signature Scheme v2 signature verifies. */ + public boolean verified; + + public final List signers = new ArrayList<>(); + private final List mWarnings = new ArrayList<>(); + private final List mErrors = new ArrayList<>(); + + public boolean containsErrors() { + if (!mErrors.isEmpty()) { + return true; + } + if (!signers.isEmpty()) { + for (SignerInfo signer : signers) { + if (signer.containsErrors()) { + return true; + } + } + } + return false; + } + + public void addError(Issue msg, Object... parameters) { + mErrors.add(new IssueWithParams(msg, parameters)); + } + + public void addWarning(Issue msg, Object... parameters) { + mWarnings.add(new IssueWithParams(msg, parameters)); + } + + public List getErrors() { + return mErrors; + } + + public List getWarnings() { + return mWarnings; + } + + public static class SignerInfo { + public int index; + public List certs = new ArrayList<>(); + public List contentDigests = new ArrayList<>(); + public Map verifiedContentDigests = new HashMap<>(); + public List signatures = new ArrayList<>(); + public Map verifiedSignatures = new HashMap<>(); + public List additionalAttributes = new ArrayList<>(); + public byte[] signedData; + + private final List mWarnings = new ArrayList<>(); + private final List mErrors = new ArrayList<>(); + + public void addError(Issue msg, Object... parameters) { + mErrors.add(new IssueWithParams(msg, parameters)); + } + + public void addWarning(Issue msg, Object... parameters) { + mWarnings.add(new IssueWithParams(msg, parameters)); + } + + public boolean containsErrors() { + return !mErrors.isEmpty(); + } + + public List getErrors() { + return mErrors; + } + + public List getWarnings() { + return mWarnings; + } + + public static class ContentDigest { + private final int mSignatureAlgorithmId; + private final byte[] mValue; + + public ContentDigest(int signatureAlgorithmId, byte[] value) { + mSignatureAlgorithmId = signatureAlgorithmId; + mValue = value; + } + + public int getSignatureAlgorithmId() { + return mSignatureAlgorithmId; + } + + public byte[] getValue() { + return mValue; + } + } + + public static class Signature { + private final int mAlgorithmId; + private final byte[] mValue; + + public Signature(int algorithmId, byte[] value) { + mAlgorithmId = algorithmId; + mValue = value; + } + + public int getAlgorithmId() { + return mAlgorithmId; + } + + public byte[] getValue() { + return mValue; + } + } + + public static class AdditionalAttribute { + private final int mId; + private final byte[] mValue; + + public AdditionalAttribute(int id, byte[] value) { + mId = id; + mValue = value.clone(); + } + + public int getId() { + return mId; + } + + public byte[] getValue() { + return mValue.clone(); + } + } + } + } +} diff --git a/plugin/src/main/java/com/android/apksigner/core/internal/jar/ManifestWriter.java b/plugin/src/main/java/com/android/apksigner/core/internal/jar/ManifestWriter.java new file mode 100644 index 0000000..449953a --- /dev/null +++ b/plugin/src/main/java/com/android/apksigner/core/internal/jar/ManifestWriter.java @@ -0,0 +1,124 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.apksigner.core.internal.jar; + +import java.io.IOException; +import java.io.OutputStream; +import java.util.Map; +import java.util.Set; +import java.util.SortedMap; +import java.util.TreeMap; +import java.util.jar.Attributes; + +/** + * Producer of {@code META-INF/MANIFEST.MF} file. + */ +public abstract class ManifestWriter { + + private static final byte[] CRLF = new byte[] {'\r', '\n'}; + private static final int MAX_LINE_LENGTH = 70; + + private ManifestWriter() {} + + public static void writeMainSection(OutputStream out, Attributes attributes) + throws IOException { + + // Main section must start with the Manifest-Version attribute. + // See https://docs.oracle.com/javase/8/docs/technotes/guides/jar/jar.html#Signed_JAR_File. + String manifestVersion = attributes.getValue(Attributes.Name.MANIFEST_VERSION); + if (manifestVersion == null) { + throw new IllegalArgumentException( + "Mandatory " + Attributes.Name.MANIFEST_VERSION + " attribute missing"); + } + writeAttribute(out, Attributes.Name.MANIFEST_VERSION, manifestVersion); + + if (attributes.size() > 1) { + SortedMap namedAttributes = getAttributesSortedByName(attributes); + namedAttributes.remove(Attributes.Name.MANIFEST_VERSION.toString()); + writeAttributes(out, namedAttributes); + } + writeSectionDelimiter(out); + } + + public static void writeIndividualSection(OutputStream out, String name, Attributes attributes) + throws IOException { + writeAttribute(out, "Name", name); + + if (!attributes.isEmpty()) { + writeAttributes(out, getAttributesSortedByName(attributes)); + } + writeSectionDelimiter(out); + } + + static void writeSectionDelimiter(OutputStream out) throws IOException { + out.write(CRLF); + } + + static void writeAttribute(OutputStream out, Attributes.Name name, String value) + throws IOException { + writeAttribute(out, name.toString(), value); + } + + private static void writeAttribute(OutputStream out, String name, String value) + throws IOException { + writeLine(out, name + ": " + value); + } + + private static void writeLine(OutputStream out, String line) throws IOException { + byte[] lineBytes = line.getBytes("UTF-8"); + int offset = 0; + int remaining = lineBytes.length; + boolean firstLine = true; + while (remaining > 0) { + int chunkLength; + if (firstLine) { + // First line + chunkLength = Math.min(remaining, MAX_LINE_LENGTH); + } else { + // Continuation line + out.write(CRLF); + out.write(' '); + chunkLength = Math.min(remaining, MAX_LINE_LENGTH - 1); + } + out.write(lineBytes, offset, chunkLength); + offset += chunkLength; + remaining -= chunkLength; + firstLine = false; + } + out.write(CRLF); + } + + static SortedMap getAttributesSortedByName(Attributes attributes) { + Set> attributesEntries = attributes.entrySet(); + SortedMap namedAttributes = new TreeMap(); + for (Map.Entry attribute : attributesEntries) { + String attrName = attribute.getKey().toString(); + String attrValue = attribute.getValue().toString(); + namedAttributes.put(attrName, attrValue); + } + return namedAttributes; + } + + static void writeAttributes( + OutputStream out, SortedMap attributesSortedByName) throws IOException { + for (Map.Entry attribute : attributesSortedByName.entrySet()) { + String attrName = attribute.getKey(); + String attrValue = attribute.getValue(); + writeAttribute(out, attrName, attrValue); + } + } +} diff --git a/plugin/src/main/java/com/android/apksigner/core/internal/jar/SignatureFileWriter.java b/plugin/src/main/java/com/android/apksigner/core/internal/jar/SignatureFileWriter.java new file mode 100644 index 0000000..9cd25f3 --- /dev/null +++ b/plugin/src/main/java/com/android/apksigner/core/internal/jar/SignatureFileWriter.java @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.apksigner.core.internal.jar; + +import java.io.IOException; +import java.io.OutputStream; +import java.util.SortedMap; +import java.util.jar.Attributes; + +/** + * Producer of JAR signature file ({@code *.SF}). + */ +public abstract class SignatureFileWriter { + private SignatureFileWriter() {} + + public static void writeMainSection(OutputStream out, Attributes attributes) + throws IOException { + + // Main section must start with the Signature-Version attribute. + // See https://docs.oracle.com/javase/8/docs/technotes/guides/jar/jar.html#Signed_JAR_File. + String signatureVersion = attributes.getValue(Attributes.Name.SIGNATURE_VERSION); + if (signatureVersion == null) { + throw new IllegalArgumentException( + "Mandatory " + Attributes.Name.SIGNATURE_VERSION + " attribute missing"); + } + ManifestWriter.writeAttribute(out, Attributes.Name.SIGNATURE_VERSION, signatureVersion); + + if (attributes.size() > 1) { + SortedMap namedAttributes = + ManifestWriter.getAttributesSortedByName(attributes); + namedAttributes.remove(Attributes.Name.SIGNATURE_VERSION.toString()); + ManifestWriter.writeAttributes(out, namedAttributes); + } + writeSectionDelimiter(out); + } + + public static void writeIndividualSection(OutputStream out, String name, Attributes attributes) + throws IOException { + ManifestWriter.writeIndividualSection(out, name, attributes); + } + + public static void writeSectionDelimiter(OutputStream out) throws IOException { + ManifestWriter.writeSectionDelimiter(out); + } +} diff --git a/plugin/src/main/java/com/android/apksigner/core/internal/util/ByteArrayOutputStreamSink.java b/plugin/src/main/java/com/android/apksigner/core/internal/util/ByteArrayOutputStreamSink.java new file mode 100644 index 0000000..ca79df7 --- /dev/null +++ b/plugin/src/main/java/com/android/apksigner/core/internal/util/ByteArrayOutputStreamSink.java @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.apksigner.core.internal.util; + +import com.android.apksigner.core.util.DataSink; + +import java.io.ByteArrayOutputStream; +import java.nio.ByteBuffer; + +/** + * Data sink which stores all input data into an internal {@link ByteArrayOutputStream}, thus + * accepting an arbitrary amount of data. + */ +public class ByteArrayOutputStreamSink implements DataSink { + + private final ByteArrayOutputStream mBuf = new ByteArrayOutputStream(); + + @Override + public void consume(byte[] buf, int offset, int length) { + mBuf.write(buf, offset, length); + } + + @Override + public void consume(ByteBuffer buf) { + if (!buf.hasRemaining()) { + return; + } + + if (buf.hasArray()) { + mBuf.write( + buf.array(), + buf.arrayOffset() + buf.position(), + buf.remaining()); + buf.position(buf.limit()); + } else { + byte[] tmp = new byte[buf.remaining()]; + buf.get(tmp); + mBuf.write(tmp, 0, tmp.length); + } + } + + /** + * Returns the data received so far. + */ + public byte[] getData() { + return mBuf.toByteArray(); + } +} diff --git a/plugin/src/main/java/com/android/apksigner/core/internal/util/ByteBufferDataSource.java b/plugin/src/main/java/com/android/apksigner/core/internal/util/ByteBufferDataSource.java new file mode 100644 index 0000000..b2d9ca1 --- /dev/null +++ b/plugin/src/main/java/com/android/apksigner/core/internal/util/ByteBufferDataSource.java @@ -0,0 +1,126 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.apksigner.core.internal.util; + +import com.android.apksigner.core.util.DataSink; +import com.android.apksigner.core.util.DataSource; + +import java.io.IOException; +import java.nio.ByteBuffer; + +/** + * {@link DataSource} backed by a {@link ByteBuffer}. + */ +public class ByteBufferDataSource implements DataSource { + + private final ByteBuffer mBuffer; + private final int mSize; + + /** + * Constructs a new {@code ByteBufferDigestSource} based on the data contained in the provided + * buffer between the buffer's position and limit. + */ + public ByteBufferDataSource(ByteBuffer buffer) { + this(buffer, true); + } + + /** + * Constructs a new {@code ByteBufferDigestSource} based on the data contained in the provided + * buffer between the buffer's position and limit. + */ + private ByteBufferDataSource(ByteBuffer buffer, boolean sliceRequired) { + mBuffer = (sliceRequired) ? buffer.slice() : buffer; + mSize = buffer.remaining(); + } + + @Override + public long size() { + return mSize; + } + + @Override + public ByteBuffer getByteBuffer(long offset, int size) { + checkChunkValid(offset, size); + + // checkChunkValid ensures that it's OK to cast offset to int. + int chunkPosition = (int) offset; + int chunkLimit = chunkPosition + size; + // Creating a slice of ByteBuffer modifies the state of the source ByteBuffer (position + // and limit fields, to be more specific). We thus use synchronization around these + // state-changing operations to make instances of this class thread-safe. + synchronized (mBuffer) { + // ByteBuffer.limit(int) and .position(int) check that that the position >= limit + // invariant is not broken. Thus, the only way to safely change position and limit + // without caring about their current values is to first set position to 0 or set the + // limit to capacity. + mBuffer.position(0); + + mBuffer.limit(chunkLimit); + mBuffer.position(chunkPosition); + return mBuffer.slice(); + } + } + + @Override + public void copyTo(long offset, int size, ByteBuffer dest) { + dest.put(getByteBuffer(offset, size)); + } + + @Override + public void feed(long offset, long size, DataSink sink) throws IOException { + if ((size < 0) || (size > mSize)) { + throw new IllegalArgumentException("size: " + size + ", source size: " + mSize); + } + sink.consume(getByteBuffer(offset, (int) size)); + } + + @Override + public ByteBufferDataSource slice(long offset, long size) { + if ((offset == 0) && (size == mSize)) { + return this; + } + if ((size < 0) || (size > mSize)) { + throw new IllegalArgumentException("size: " + size + ", source size: " + mSize); + } + return new ByteBufferDataSource( + getByteBuffer(offset, (int) size), + false // no need to slice -- it's already a slice + ); + } + + private void checkChunkValid(long offset, long size) { + if (offset < 0) { + throw new IllegalArgumentException("offset: " + offset); + } + if (size < 0) { + throw new IllegalArgumentException("size: " + size); + } + if (offset > mSize) { + throw new IllegalArgumentException( + "offset (" + offset + ") > source size (" + mSize + ")"); + } + long endOffset = offset + size; + if (endOffset < offset) { + throw new IllegalArgumentException( + "offset (" + offset + ") + size (" + size + ") overflow"); + } + if (endOffset > mSize) { + throw new IllegalArgumentException( + "offset (" + offset + ") + size (" + size + ") > source size (" + mSize +")"); + } + } +} diff --git a/plugin/src/main/java/com/android/apksigner/core/internal/util/ByteBufferSink.java b/plugin/src/main/java/com/android/apksigner/core/internal/util/ByteBufferSink.java new file mode 100644 index 0000000..8c57905 --- /dev/null +++ b/plugin/src/main/java/com/android/apksigner/core/internal/util/ByteBufferSink.java @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.apksigner.core.internal.util; + +import com.android.apksigner.core.util.DataSink; + +import java.io.IOException; +import java.nio.BufferOverflowException; +import java.nio.ByteBuffer; + +/** + * Data sink which stores all received data into the associated {@link ByteBuffer}. + */ +public class ByteBufferSink implements DataSink { + + private final ByteBuffer mBuffer; + + public ByteBufferSink(ByteBuffer buffer) { + mBuffer = buffer; + } + + @Override + public void consume(byte[] buf, int offset, int length) throws IOException { + try { + mBuffer.put(buf, offset, length); + } catch (BufferOverflowException e) { + throw new IOException( + "Insufficient space in output buffer for " + length + " bytes", e); + } + } + + @Override + public void consume(ByteBuffer buf) throws IOException { + int length = buf.remaining(); + try { + mBuffer.put(buf); + } catch (BufferOverflowException e) { + throw new IOException( + "Insufficient space in output buffer for " + length + " bytes", e); + } + } +} diff --git a/plugin/src/main/java/com/android/apksigner/core/internal/util/DelegatingX509Certificate.java b/plugin/src/main/java/com/android/apksigner/core/internal/util/DelegatingX509Certificate.java new file mode 100644 index 0000000..936cfa9 --- /dev/null +++ b/plugin/src/main/java/com/android/apksigner/core/internal/util/DelegatingX509Certificate.java @@ -0,0 +1,179 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.apksigner.core.internal.util; + +import java.math.BigInteger; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.Principal; +import java.security.PublicKey; +import java.security.SignatureException; +import java.security.cert.CertificateEncodingException; +import java.security.cert.CertificateException; +import java.security.cert.CertificateExpiredException; +import java.security.cert.CertificateNotYetValidException; +import java.security.cert.X509Certificate; +import java.util.Date; +import java.util.Set; + +/** + * {@link X509Certificate} which delegates all method invocations to the provided delegate + * {@code X509Certificate}. + */ +public class DelegatingX509Certificate extends X509Certificate { + private final X509Certificate mDelegate; + + public DelegatingX509Certificate(X509Certificate delegate) { + this.mDelegate = delegate; + } + + @Override + public Set getCriticalExtensionOIDs() { + return mDelegate.getCriticalExtensionOIDs(); + } + + @Override + public byte[] getExtensionValue(String oid) { + return mDelegate.getExtensionValue(oid); + } + + @Override + public Set getNonCriticalExtensionOIDs() { + return mDelegate.getNonCriticalExtensionOIDs(); + } + + @Override + public boolean hasUnsupportedCriticalExtension() { + return mDelegate.hasUnsupportedCriticalExtension(); + } + + @Override + public void checkValidity() + throws CertificateExpiredException, CertificateNotYetValidException { + mDelegate.checkValidity(); + } + + @Override + public void checkValidity(Date date) + throws CertificateExpiredException, CertificateNotYetValidException { + mDelegate.checkValidity(date); + } + + @Override + public int getVersion() { + return mDelegate.getVersion(); + } + + @Override + public BigInteger getSerialNumber() { + return mDelegate.getSerialNumber(); + } + + @Override + public Principal getIssuerDN() { + return mDelegate.getIssuerDN(); + } + + @Override + public Principal getSubjectDN() { + return mDelegate.getSubjectDN(); + } + + @Override + public Date getNotBefore() { + return mDelegate.getNotBefore(); + } + + @Override + public Date getNotAfter() { + return mDelegate.getNotAfter(); + } + + @Override + public byte[] getTBSCertificate() throws CertificateEncodingException { + return mDelegate.getTBSCertificate(); + } + + @Override + public byte[] getSignature() { + return mDelegate.getSignature(); + } + + @Override + public String getSigAlgName() { + return mDelegate.getSigAlgName(); + } + + @Override + public String getSigAlgOID() { + return mDelegate.getSigAlgOID(); + } + + @Override + public byte[] getSigAlgParams() { + return mDelegate.getSigAlgParams(); + } + + @Override + public boolean[] getIssuerUniqueID() { + return mDelegate.getIssuerUniqueID(); + } + + @Override + public boolean[] getSubjectUniqueID() { + return mDelegate.getSubjectUniqueID(); + } + + @Override + public boolean[] getKeyUsage() { + return mDelegate.getKeyUsage(); + } + + @Override + public int getBasicConstraints() { + return mDelegate.getBasicConstraints(); + } + + @Override + public byte[] getEncoded() throws CertificateEncodingException { + return mDelegate.getEncoded(); + } + + @Override + public void verify(PublicKey key) throws CertificateException, NoSuchAlgorithmException, + InvalidKeyException, NoSuchProviderException, SignatureException { + mDelegate.verify(key); + } + + @Override + public void verify(PublicKey key, String sigProvider) + throws CertificateException, NoSuchAlgorithmException, InvalidKeyException, + NoSuchProviderException, SignatureException { + mDelegate.verify(key, sigProvider); + } + + @Override + public String toString() { + return mDelegate.toString(); + } + + @Override + public PublicKey getPublicKey() { + return mDelegate.getPublicKey(); + } +} diff --git a/plugin/src/main/java/com/android/apksigner/core/internal/util/MessageDigestSink.java b/plugin/src/main/java/com/android/apksigner/core/internal/util/MessageDigestSink.java new file mode 100644 index 0000000..45bb30e --- /dev/null +++ b/plugin/src/main/java/com/android/apksigner/core/internal/util/MessageDigestSink.java @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.apksigner.core.internal.util; + +import com.android.apksigner.core.util.DataSink; + +import java.nio.ByteBuffer; +import java.security.MessageDigest; + +/** + * Data sink which feeds all received data into the associated {@link MessageDigest} instances. Each + * {@code MessageDigest} instance receives the same data. + */ +public class MessageDigestSink implements DataSink { + + private final MessageDigest[] mMessageDigests; + + public MessageDigestSink(MessageDigest[] digests) { + mMessageDigests = digests; + } + + @Override + public void consume(byte[] buf, int offset, int length) { + for (MessageDigest md : mMessageDigests) { + md.update(buf, offset, length); + } + } + + @Override + public void consume(ByteBuffer buf) { + int originalPosition = buf.position(); + for (MessageDigest md : mMessageDigests) { + // Reset the position back to the original because the previous iteration's + // MessageDigest.update set the buffer's position to the buffer's limit. + buf.position(originalPosition); + md.update(buf); + } + } +} diff --git a/plugin/src/main/java/com/android/apksigner/core/internal/util/Pair.java b/plugin/src/main/java/com/android/apksigner/core/internal/util/Pair.java new file mode 100644 index 0000000..d59af41 --- /dev/null +++ b/plugin/src/main/java/com/android/apksigner/core/internal/util/Pair.java @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.apksigner.core.internal.util; + +/** + * Pair of two elements. + */ +public final class Pair { + private final A mFirst; + private final B mSecond; + + private Pair(A first, B second) { + mFirst = first; + mSecond = second; + } + + public static Pair of(A first, B second) { + return new Pair(first, second); + } + + public A getFirst() { + return mFirst; + } + + public B getSecond() { + return mSecond; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((mFirst == null) ? 0 : mFirst.hashCode()); + result = prime * result + ((mSecond == null) ? 0 : mSecond.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + @SuppressWarnings("rawtypes") + Pair other = (Pair) obj; + if (mFirst == null) { + if (other.mFirst != null) { + return false; + } + } else if (!mFirst.equals(other.mFirst)) { + return false; + } + if (mSecond == null) { + if (other.mSecond != null) { + return false; + } + } else if (!mSecond.equals(other.mSecond)) { + return false; + } + return true; + } +} diff --git a/plugin/src/main/java/com/android/apksigner/core/internal/zip/ZipUtils.java b/plugin/src/main/java/com/android/apksigner/core/internal/zip/ZipUtils.java new file mode 100644 index 0000000..5e724a2 --- /dev/null +++ b/plugin/src/main/java/com/android/apksigner/core/internal/zip/ZipUtils.java @@ -0,0 +1,278 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.apksigner.core.internal.zip; + +import java.io.IOException; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; + +import com.android.apksigner.core.internal.util.Pair; +import com.android.apksigner.core.util.DataSource; + +/** + * Assorted ZIP format helpers. + * + *

NOTE: Most helper methods operating on {@code ByteBuffer} instances expect that the byte + * order of these buffers is little-endian. + */ +public abstract class ZipUtils { + private ZipUtils() {} + + public static final short COMPRESSION_METHOD_STORED = 0; + public static final short COMPRESSION_METHOD_DEFLATED = 8; + + private static final int ZIP_EOCD_REC_MIN_SIZE = 22; + private static final int ZIP_EOCD_REC_SIG = 0x06054b50; + private static final int ZIP_EOCD_CENTRAL_DIR_TOTAL_RECORD_COUNT_OFFSET = 10; + private static final int ZIP_EOCD_CENTRAL_DIR_SIZE_FIELD_OFFSET = 12; + private static final int ZIP_EOCD_CENTRAL_DIR_OFFSET_FIELD_OFFSET = 16; + private static final int ZIP_EOCD_COMMENT_LENGTH_FIELD_OFFSET = 20; + + private static final int ZIP64_EOCD_LOCATOR_SIZE = 20; + private static final int ZIP64_EOCD_LOCATOR_SIG = 0x07064b50; + + private static final int UINT16_MAX_VALUE = 0xffff; + + /** + * Sets the offset of the start of the ZIP Central Directory in the archive. + * + *

NOTE: Byte order of {@code zipEndOfCentralDirectory} must be little-endian. + */ + public static void setZipEocdCentralDirectoryOffset( + ByteBuffer zipEndOfCentralDirectory, long offset) { + assertByteOrderLittleEndian(zipEndOfCentralDirectory); + setUnsignedInt32( + zipEndOfCentralDirectory, + zipEndOfCentralDirectory.position() + ZIP_EOCD_CENTRAL_DIR_OFFSET_FIELD_OFFSET, + offset); + } + + /** + * Returns the offset of the start of the ZIP Central Directory in the archive. + * + *

NOTE: Byte order of {@code zipEndOfCentralDirectory} must be little-endian. + */ + public static long getZipEocdCentralDirectoryOffset(ByteBuffer zipEndOfCentralDirectory) { + assertByteOrderLittleEndian(zipEndOfCentralDirectory); + return getUnsignedInt32( + zipEndOfCentralDirectory, + zipEndOfCentralDirectory.position() + ZIP_EOCD_CENTRAL_DIR_OFFSET_FIELD_OFFSET); + } + + /** + * Returns the size (in bytes) of the ZIP Central Directory. + * + *

NOTE: Byte order of {@code zipEndOfCentralDirectory} must be little-endian. + */ + public static long getZipEocdCentralDirectorySizeBytes(ByteBuffer zipEndOfCentralDirectory) { + assertByteOrderLittleEndian(zipEndOfCentralDirectory); + return getUnsignedInt32( + zipEndOfCentralDirectory, + zipEndOfCentralDirectory.position() + ZIP_EOCD_CENTRAL_DIR_SIZE_FIELD_OFFSET); + } + + /** + * Returns the total number of records in ZIP Central Directory. + * + *

NOTE: Byte order of {@code zipEndOfCentralDirectory} must be little-endian. + */ + public static int getZipEocdCentralDirectoryTotalRecordCount( + ByteBuffer zipEndOfCentralDirectory) { + assertByteOrderLittleEndian(zipEndOfCentralDirectory); + return getUnsignedInt16( + zipEndOfCentralDirectory, + zipEndOfCentralDirectory.position() + + ZIP_EOCD_CENTRAL_DIR_TOTAL_RECORD_COUNT_OFFSET); + } + + /** + * Returns the ZIP End of Central Directory record of the provided ZIP file. + * + * @return contents of the ZIP End of Central Directory record and the record's offset in the + * file or {@code null} if the file does not contain the record. + * + * @throws IOException if an I/O error occurs while reading the file. + */ + public static Pair findZipEndOfCentralDirectoryRecord(DataSource zip) + throws IOException { + // ZIP End of Central Directory (EOCD) record is located at the very end of the ZIP archive. + // The record can be identified by its 4-byte signature/magic which is located at the very + // beginning of the record. A complication is that the record is variable-length because of + // the comment field. + // The algorithm for locating the ZIP EOCD record is as follows. We search backwards from + // end of the buffer for the EOCD record signature. Whenever we find a signature, we check + // the candidate record's comment length is such that the remainder of the record takes up + // exactly the remaining bytes in the buffer. The search is bounded because the maximum + // size of the comment field is 65535 bytes because the field is an unsigned 16-bit number. + + long fileSize = zip.size(); + if (fileSize < ZIP_EOCD_REC_MIN_SIZE) { + return null; + } + + // Optimization: 99.99% of APKs have a zero-length comment field in the EoCD record and thus + // the EoCD record offset is known in advance. Try that offset first to avoid unnecessarily + // reading more data. + Pair result = findZipEndOfCentralDirectoryRecord(zip, 0); + if (result != null) { + return result; + } + + // EoCD does not start where we expected it to. Perhaps it contains a non-empty comment + // field. Expand the search. The maximum size of the comment field in EoCD is 65535 because + // the comment length field is an unsigned 16-bit number. + return findZipEndOfCentralDirectoryRecord(zip, UINT16_MAX_VALUE); + } + + /** + * Returns the ZIP End of Central Directory record of the provided ZIP file. + * + * @param maxCommentSize maximum accepted size (in bytes) of EoCD comment field. The permitted + * value is from 0 to 65535 inclusive. The smaller the value, the faster this method + * locates the record, provided its comment field is no longer than this value. + * + * @return contents of the ZIP End of Central Directory record and the record's offset in the + * file or {@code null} if the file does not contain the record. + * + * @throws IOException if an I/O error occurs while reading the file. + */ + private static Pair findZipEndOfCentralDirectoryRecord( + DataSource zip, int maxCommentSize) throws IOException { + // ZIP End of Central Directory (EOCD) record is located at the very end of the ZIP archive. + // The record can be identified by its 4-byte signature/magic which is located at the very + // beginning of the record. A complication is that the record is variable-length because of + // the comment field. + // The algorithm for locating the ZIP EOCD record is as follows. We search backwards from + // end of the buffer for the EOCD record signature. Whenever we find a signature, we check + // the candidate record's comment length is such that the remainder of the record takes up + // exactly the remaining bytes in the buffer. The search is bounded because the maximum + // size of the comment field is 65535 bytes because the field is an unsigned 16-bit number. + + if ((maxCommentSize < 0) || (maxCommentSize > UINT16_MAX_VALUE)) { + throw new IllegalArgumentException("maxCommentSize: " + maxCommentSize); + } + + long fileSize = zip.size(); + if (fileSize < ZIP_EOCD_REC_MIN_SIZE) { + // No space for EoCD record in the file. + return null; + } + // Lower maxCommentSize if the file is too small. + maxCommentSize = (int) Math.min(maxCommentSize, fileSize - ZIP_EOCD_REC_MIN_SIZE); + + int maxEocdSize = ZIP_EOCD_REC_MIN_SIZE + maxCommentSize; + long bufOffsetInFile = fileSize - maxEocdSize; + ByteBuffer buf = zip.getByteBuffer(bufOffsetInFile, maxEocdSize); + buf.order(ByteOrder.LITTLE_ENDIAN); + int eocdOffsetInBuf = findZipEndOfCentralDirectoryRecord(buf); + if (eocdOffsetInBuf == -1) { + // No EoCD record found in the buffer + return null; + } + // EoCD found + buf.position(eocdOffsetInBuf); + ByteBuffer eocd = buf.slice(); + eocd.order(ByteOrder.LITTLE_ENDIAN); + return Pair.of(eocd, bufOffsetInFile + eocdOffsetInBuf); + } + + /** + * Returns the position at which ZIP End of Central Directory record starts in the provided + * buffer or {@code -1} if the record is not present. + * + *

NOTE: Byte order of {@code zipContents} must be little-endian. + */ + private static int findZipEndOfCentralDirectoryRecord(ByteBuffer zipContents) { + assertByteOrderLittleEndian(zipContents); + + // ZIP End of Central Directory (EOCD) record is located at the very end of the ZIP archive. + // The record can be identified by its 4-byte signature/magic which is located at the very + // beginning of the record. A complication is that the record is variable-length because of + // the comment field. + // The algorithm for locating the ZIP EOCD record is as follows. We search backwards from + // end of the buffer for the EOCD record signature. Whenever we find a signature, we check + // the candidate record's comment length is such that the remainder of the record takes up + // exactly the remaining bytes in the buffer. The search is bounded because the maximum + // size of the comment field is 65535 bytes because the field is an unsigned 16-bit number. + + int archiveSize = zipContents.capacity(); + if (archiveSize < ZIP_EOCD_REC_MIN_SIZE) { + return -1; + } + int maxCommentLength = Math.min(archiveSize - ZIP_EOCD_REC_MIN_SIZE, UINT16_MAX_VALUE); + int eocdWithEmptyCommentStartPosition = archiveSize - ZIP_EOCD_REC_MIN_SIZE; + for (int expectedCommentLength = 0; expectedCommentLength < maxCommentLength; + expectedCommentLength++) { + int eocdStartPos = eocdWithEmptyCommentStartPosition - expectedCommentLength; + if (zipContents.getInt(eocdStartPos) == ZIP_EOCD_REC_SIG) { + int actualCommentLength = + getUnsignedInt16( + zipContents, eocdStartPos + ZIP_EOCD_COMMENT_LENGTH_FIELD_OFFSET); + if (actualCommentLength == expectedCommentLength) { + return eocdStartPos; + } + } + } + + return -1; + } + + /** + * Returns {@code true} if the provided file contains a ZIP64 End of Central Directory + * Locator. + * + * @param zipEndOfCentralDirectoryPosition offset of the ZIP End of Central Directory record + * in the file. + * + * @throws IOException if an I/O error occurs while reading the data source + */ + public static final boolean isZip64EndOfCentralDirectoryLocatorPresent( + DataSource zip, long zipEndOfCentralDirectoryPosition) throws IOException { + + // ZIP64 End of Central Directory Locator immediately precedes the ZIP End of Central + // Directory Record. + long locatorPosition = zipEndOfCentralDirectoryPosition - ZIP64_EOCD_LOCATOR_SIZE; + if (locatorPosition < 0) { + return false; + } + + ByteBuffer sig = zip.getByteBuffer(locatorPosition, 4); + sig.order(ByteOrder.LITTLE_ENDIAN); + return sig.getInt(0) == ZIP64_EOCD_LOCATOR_SIG; + } + + private static void assertByteOrderLittleEndian(ByteBuffer buffer) { + if (buffer.order() != ByteOrder.LITTLE_ENDIAN) { + throw new IllegalArgumentException("ByteBuffer byte order must be little endian"); + } + } + + private static int getUnsignedInt16(ByteBuffer buffer, int offset) { + return buffer.getShort(offset) & 0xffff; + } + + private static void setUnsignedInt32(ByteBuffer buffer, int offset, long value) { + if ((value < 0) || (value > 0xffffffffL)) { + throw new IllegalArgumentException("uint32 value of out range: " + value); + } + buffer.putInt(offset, (int) value); + } + + private static long getUnsignedInt32(ByteBuffer buffer, int offset) { + return buffer.getInt(offset) & 0xffffffffL; + } +} \ No newline at end of file diff --git a/plugin/src/main/java/com/android/apksigner/core/util/DataSink.java b/plugin/src/main/java/com/android/apksigner/core/util/DataSink.java new file mode 100644 index 0000000..35a61fc --- /dev/null +++ b/plugin/src/main/java/com/android/apksigner/core/util/DataSink.java @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.apksigner.core.util; + +import java.io.IOException; +import java.nio.ByteBuffer; + +/** + * Consumer of input data which may be provided in one go or in chunks. + */ +public interface DataSink { + + /** + * Consumes the provided chunk of data. + * + *

This data sink guarantees to not hold references to the provided buffer after this method + * terminates. + */ + void consume(byte[] buf, int offset, int length) throws IOException; + + /** + * Consumes all remaining data in the provided buffer and advances the buffer's position + * to the buffer's limit. + * + *

This data sink guarantees to not hold references to the provided buffer after this method + * terminates. + */ + void consume(ByteBuffer buf) throws IOException; +} diff --git a/plugin/src/main/java/com/android/apksigner/core/util/DataSource.java b/plugin/src/main/java/com/android/apksigner/core/util/DataSource.java new file mode 100644 index 0000000..e268dd2 --- /dev/null +++ b/plugin/src/main/java/com/android/apksigner/core/util/DataSource.java @@ -0,0 +1,98 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.apksigner.core.util; + +import java.io.IOException; +import java.nio.ByteBuffer; + +/** + * Abstract representation of a source of data. + * + *

This abstraction serves three purposes: + *

    + *
  • Transparent handling of different types of sources, such as {@code byte[]}, + * {@link java.nio.ByteBuffer}, {@link java.io.RandomAccessFile}, memory-mapped file.
  • + *
  • Support sources larger than 2 GB. If all sources were smaller than 2 GB, {@code ByteBuffer} + * may have worked as the unifying abstraction.
  • + *
  • Support sources which do not fit into logical memory as a contiguous region.
  • + *
+ * + *

There are following ways to obtain a chunk of data from the data source: + *

    + *
  • Stream the chunk's data into a {@link DataSink} using + * {@link #feed(long, long, DataSink) feed}. This is best suited for scenarios where there is no + * need to have the chunk's data accessible at the same time, for example, when computing the + * digest of the chunk. If you need to keep the chunk's data around after {@code feed} + * completes, you must create a copy during {@code feed}. However, in that case the following + * methods of obtaining the chunk's data may be more appropriate.
  • + *
  • Obtain a {@link ByteBuffer} containing the chunk's data using + * {@link #getByteBuffer(long, int) getByteBuffer}. Depending on the data source, the chunk's + * data may or may not be copied by this operation. This is best suited for scenarios where + * you need to access the chunk's data in arbitrary order, but don't need to modify the data and + * thus don't require a copy of the data.
  • + *
  • Copy the chunk's data to a {@link ByteBuffer} using + * {@link #copyTo(long, int, ByteBuffer) copyTo}. This is best suited for scenarios where + * you require a copy of the chunk's data, such as to when you need to modify the data. + *
  • + *
+ */ +public interface DataSource { + + /** + * Returns the amount of data (in bytes) contained in this data source. + */ + long size(); + + /** + * Feeds the specified chunk from this data source into the provided sink. + * + * @param offset index (in bytes) at which the chunk starts inside data source + * @param size size (in bytes) of the chunk + */ + void feed(long offset, long size, DataSink sink) throws IOException; + + /** + * Returns a buffer holding the contents of the specified chunk of data from this data source. + * Changes to the data source are not guaranteed to be reflected in the returned buffer. + * Similarly, changes in the buffer are not guaranteed to be reflected in the data source. + * + *

The returned buffer's position is {@code 0}, and the buffer's limit and capacity is + * {@code size}. + * + * @param offset index (in bytes) at which the chunk starts inside data source + * @param size size (in bytes) of the chunk + */ + ByteBuffer getByteBuffer(long offset, int size) throws IOException; + + /** + * Copies the specified chunk from this data source into the provided destination buffer, + * advancing the destination buffer's position by {@code size}. + * + * @param offset index (in bytes) at which the chunk starts inside data source + * @param size size (in bytes) of the chunk + */ + void copyTo(long offset, int size, ByteBuffer dest) throws IOException; + + /** + * Returns a data source representing the specified region of data of this data source. Changes + * to data represented by this data source will also be visible in the returned data source. + * + * @param offset index (in bytes) at which the region starts inside data source + * @param size size (in bytes) of the region + */ + DataSource slice(long offset, long size); +} diff --git a/plugin/src/main/java/com/android/apksigner/core/util/DataSources.java b/plugin/src/main/java/com/android/apksigner/core/util/DataSources.java new file mode 100644 index 0000000..6ce0ac8 --- /dev/null +++ b/plugin/src/main/java/com/android/apksigner/core/util/DataSources.java @@ -0,0 +1,24 @@ +package com.android.apksigner.core.util; + +import com.android.apksigner.core.internal.util.ByteBufferDataSource; + +import java.nio.ByteBuffer; + +/** + * Utility methods for working with {@link DataSource} abstraction. + */ +public abstract class DataSources { + private DataSources() {} + + /** + * Returns a {@link DataSource} backed by the provided {@link ByteBuffer}. The data source + * represents the data contained between the position and limit of the buffer. Changes to the + * buffer's contents will be visible in the data source. + */ + public static DataSource asDataSource(ByteBuffer buffer) { + if (buffer == null) { + throw new NullPointerException(); + } + return new ByteBufferDataSource(buffer); + } +} diff --git a/plugin/src/main/java/com/android/apksigner/core/zip/ZipFormatException.java b/plugin/src/main/java/com/android/apksigner/core/zip/ZipFormatException.java new file mode 100644 index 0000000..7da57d9 --- /dev/null +++ b/plugin/src/main/java/com/android/apksigner/core/zip/ZipFormatException.java @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.apksigner.core.zip; + +/** + * Indicates that a ZIP archive is not well-formed. + */ +public class ZipFormatException extends Exception { + private static final long serialVersionUID = 1L; + + public ZipFormatException(String message) { + super(message); + } + + public ZipFormatException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/plugin/src/main/java/com/android/signapk/SignApk.java b/plugin/src/main/java/com/android/signapk/SignApk.java new file mode 100644 index 0000000..b8f4cb9 --- /dev/null +++ b/plugin/src/main/java/com/android/signapk/SignApk.java @@ -0,0 +1,1094 @@ +///* +// * Copyright (C) 2008 The Android Open Source Project +// * +// * Licensed under the Apache License, Version 2.0 (the "License"); +// * you may not use this file except in compliance with the License. +// * You may obtain a copy of the License at +// * +// * http://www.apache.org/licenses/LICENSE-2.0 +// * +// * Unless required by applicable law or agreed to in writing, software +// * distributed under the License is distributed on an "AS IS" BASIS, +// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// * See the License for the specific language governing permissions and +// * limitations under the License. +// */ +// +//package com.android.signapk; +// +//import org.bouncycastle.asn1.ASN1InputStream; +//import org.bouncycastle.asn1.ASN1ObjectIdentifier; +//import org.bouncycastle.asn1.DEROutputStream; +//import org.bouncycastle.asn1.cms.CMSObjectIdentifiers; +//import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; +//import org.bouncycastle.cert.jcajce.JcaCertStore; +//import org.bouncycastle.cms.CMSException; +//import org.bouncycastle.cms.CMSSignedData; +//import org.bouncycastle.cms.CMSSignedDataGenerator; +//import org.bouncycastle.cms.CMSTypedData; +//import org.bouncycastle.cms.jcajce.JcaSignerInfoGeneratorBuilder; +//import org.bouncycastle.jce.provider.BouncyCastleProvider; +//import org.bouncycastle.operator.ContentSigner; +//import org.bouncycastle.operator.OperatorCreationException; +//import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; +//import org.bouncycastle.operator.jcajce.JcaDigestCalculatorProviderBuilder; +//import org.conscrypt.OpenSSLProvider; +// +//import com.android.apksigner.core.ApkSignerEngine; +//import com.android.apksigner.core.DefaultApkSignerEngine; +//import com.android.apksigner.core.apk.ApkUtils; +//import com.android.apksigner.core.util.DataSink; +//import com.android.apksigner.core.util.DataSources; +//import com.android.apksigner.core.zip.ZipFormatException; +// +//import java.io.Console; +//import java.io.BufferedReader; +//import java.io.ByteArrayInputStream; +//import java.io.ByteArrayOutputStream; +//import java.io.DataInputStream; +//import java.io.File; +//import java.io.FileInputStream; +//import java.io.FileOutputStream; +//import java.io.FilterOutputStream; +//import java.io.IOException; +//import java.io.InputStream; +//import java.io.InputStreamReader; +//import java.io.OutputStream; +//import java.lang.reflect.Constructor; +//import java.nio.ByteBuffer; +//import java.nio.ByteOrder; +//import java.security.GeneralSecurityException; +//import java.security.Key; +//import java.security.KeyFactory; +//import java.security.PrivateKey; +//import java.security.Provider; +//import java.security.Security; +//import java.security.cert.CertificateEncodingException; +//import java.security.cert.CertificateFactory; +//import java.security.cert.X509Certificate; +//import java.security.spec.InvalidKeySpecException; +//import java.security.spec.PKCS8EncodedKeySpec; +//import java.util.ArrayList; +//import java.util.Collections; +//import java.util.Enumeration; +//import java.util.List; +//import java.util.Locale; +//import java.util.TimeZone; +//import java.util.jar.JarEntry; +//import java.util.jar.JarFile; +//import java.util.jar.JarOutputStream; +//import java.util.regex.Pattern; +// +//import javax.crypto.Cipher; +//import javax.crypto.EncryptedPrivateKeyInfo; +//import javax.crypto.SecretKeyFactory; +//import javax.crypto.spec.PBEKeySpec; +// +///** +// * HISTORICAL NOTE: +// * +// * Prior to the keylimepie release, SignApk ignored the signature +// * algorithm specified in the certificate and always used SHA1withRSA. +// * +// * Starting with JB-MR2, the platform supports SHA256withRSA, so we use +// * the signature algorithm in the certificate to select which to use +// * (SHA256withRSA or SHA1withRSA). Also in JB-MR2, EC keys are supported. +// * +// * Because there are old keys still in use whose certificate actually +// * says "MD5withRSA", we treat these as though they say "SHA1withRSA" +// * for compatibility with older releases. This can be changed by +// * altering the getAlgorithm() function below. +// */ +// +// +///** +// * Command line tool to sign JAR files (including APKs and OTA updates) in a way +// * compatible with the mincrypt verifier, using EC or RSA keys and SHA1 or +// * SHA-256 (see historical note). The tool can additionally sign APKs using +// * APK Signature Scheme v2. +// */ +//class SignApk { +// private static final String OTACERT_NAME = "META-INF/com/android/otacert"; +// +// /** +// * Extensible data block/field header ID used for storing information about alignment of +// * uncompressed entries as well as for aligning the entries's data. See ZIP appnote.txt section +// * 4.5 Extensible data fields. +// */ +// private static final short ALIGNMENT_ZIP_EXTRA_DATA_FIELD_HEADER_ID = (short) 0xd935; +// +// /** +// * Minimum size (in bytes) of the extensible data block/field used for alignment of uncompressed +// * entries. +// */ +// private static final short ALIGNMENT_ZIP_EXTRA_DATA_FIELD_MIN_SIZE_BYTES = 6; +// +// // 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; +// +// /** +// * Returns the digest algorithm ID (one of {@code USE_SHA1} or {@code USE_SHA256}) to be used +// * for signing an OTA update package using the private key corresponding to the provided +// * certificate. +// */ +// private static int getDigestAlgorithmForOta(X509Certificate cert) { +// String sigAlg = cert.getSigAlgName().toUpperCase(Locale.US); +// if ("SHA1WITHRSA".equals(sigAlg) || "MD5WITHRSA".equals(sigAlg)) { +// // see "HISTORICAL NOTE" above. +// return USE_SHA1; +// } else if (sigAlg.startsWith("SHA256WITH")) { +// return USE_SHA256; +// } else { +// throw new IllegalArgumentException("unsupported signature algorithm \"" + sigAlg + +// "\" in cert [" + cert.getSubjectDN()); +// } +// } +// +// /** +// * Returns the JCA {@link java.security.Signature} algorithm to be used for signing and OTA +// * update package using the private key corresponding to the provided certificate and the +// * provided digest algorithm (see {@code USE_SHA1} and {@code USE_SHA256} constants). +// */ +// private static String getJcaSignatureAlgorithmForOta( +// X509Certificate cert, int hash) { +// String sigAlgDigestPrefix; +// switch (hash) { +// case USE_SHA1: +// sigAlgDigestPrefix = "SHA1"; +// break; +// case USE_SHA256: +// sigAlgDigestPrefix = "SHA256"; +// break; +// default: +// throw new IllegalArgumentException("Unknown hash ID: " + hash); +// } +// +// String keyAlgorithm = cert.getPublicKey().getAlgorithm(); +// if ("RSA".equalsIgnoreCase(keyAlgorithm)) { +// return sigAlgDigestPrefix + "withRSA"; +// } else if ("EC".equalsIgnoreCase(keyAlgorithm)) { +// return sigAlgDigestPrefix + "withECDSA"; +// } else { +// throw new IllegalArgumentException("Unsupported key algorithm: " + keyAlgorithm); +// } +// } +// +// private static X509Certificate readPublicKey(File file) +// throws IOException, GeneralSecurityException { +// FileInputStream input = new FileInputStream(file); +// try { +// CertificateFactory cf = CertificateFactory.getInstance("X.509"); +// return (X509Certificate) cf.generateCertificate(input); +// } finally { +// input.close(); +// } +// } +// +// /** +// * If a console doesn't exist, reads the password from stdin +// * If a console exists, reads the password from console and returns it as a string. +// * +// * @param keyFile The file containing the private key. Used to prompt the user. +// */ +// private static String readPassword(File keyFile) { +// Console console; +// char[] pwd; +// if ((console = System.console()) == null) { +// System.out.print("Enter password for " + keyFile + " (password will not be hidden): "); +// System.out.flush(); +// BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in)); +// try { +// return stdin.readLine(); +// } catch (IOException ex) { +// return null; +// } +// } else { +// if ((pwd = console.readPassword("[%s]", "Enter password for " + keyFile)) != null) { +// return String.valueOf(pwd); +// } else { +// return null; +// } +// } +// } +// +// /** +// * Decrypt an encrypted PKCS#8 format private key. +// * +// * Based on ghstark's post on Aug 6, 2006 at +// * http://forums.sun.com/thread.jspa?threadID=758133&messageID=4330949 +// * +// * @param encryptedPrivateKey The raw data of the private key +// * @param keyFile The file containing the private key +// */ +// private static PKCS8EncodedKeySpec decryptPrivateKey(byte[] encryptedPrivateKey, File keyFile) +// throws GeneralSecurityException { +// EncryptedPrivateKeyInfo epkInfo; +// try { +// epkInfo = new EncryptedPrivateKeyInfo(encryptedPrivateKey); +// } catch (IOException ex) { +// // Probably not an encrypted key. +// return null; +// } +// +// char[] password = readPassword(keyFile).toCharArray(); +// +// SecretKeyFactory skFactory = SecretKeyFactory.getInstance(epkInfo.getAlgName()); +// Key key = skFactory.generateSecret(new PBEKeySpec(password)); +// +// Cipher cipher = Cipher.getInstance(epkInfo.getAlgName()); +// cipher.init(Cipher.DECRYPT_MODE, key, epkInfo.getAlgParameters()); +// +// try { +// return epkInfo.getKeySpec(cipher); +// } catch (InvalidKeySpecException ex) { +// System.err.println("signapk: Password for " + keyFile + " may be bad."); +// throw ex; +// } +// } +// +// /** Read a PKCS#8 format private key. */ +// private static PrivateKey readPrivateKey(File file) +// throws IOException, GeneralSecurityException { +// DataInputStream input = new DataInputStream(new FileInputStream(file)); +// try { +// byte[] bytes = new byte[(int) file.length()]; +// input.read(bytes); +// +// /* Check to see if this is in an EncryptedPrivateKeyInfo structure. */ +// PKCS8EncodedKeySpec spec = decryptPrivateKey(bytes, file); +// if (spec == null) { +// spec = new PKCS8EncodedKeySpec(bytes); +// } +// +// /* +// * Now it's in a PKCS#8 PrivateKeyInfo structure. Read its Algorithm +// * OID and use that to construct a KeyFactory. +// */ +// PrivateKeyInfo pki; +// try (ASN1InputStream bIn = +// new ASN1InputStream(new ByteArrayInputStream(spec.getEncoded()))) { +// pki = PrivateKeyInfo.getInstance(bIn.readObject()); +// } +// String algOid = pki.getPrivateKeyAlgorithm().getAlgorithm().getId(); +// +// return KeyFactory.getInstance(algOid).generatePrivate(spec); +// } finally { +// input.close(); +// } +// } +// +// /** +// * Add a copy of the public key to the archive; this should +// * exactly match one of the files in +// * /system/etc/security/otacerts.zip on the device. (The same +// * cert can be extracted from the OTA update package's signature +// * block but this is much easier to get at.) +// */ +// private static void addOtacert(JarOutputStream outputJar, +// File publicKeyFile, +// long timestamp) +// throws IOException { +// +// JarEntry je = new JarEntry(OTACERT_NAME); +// je.setTime(timestamp); +// outputJar.putNextEntry(je); +// FileInputStream input = new FileInputStream(publicKeyFile); +// byte[] b = new byte[4096]; +// int read; +// while ((read = input.read(b)) != -1) { +// outputJar.write(b, 0, read); +// } +// input.close(); +// } +// +// +// /** Sign data and write the digital signature to 'out'. */ +// private static void writeSignatureBlock( +// CMSTypedData data, X509Certificate publicKey, PrivateKey privateKey, int hash, +// OutputStream out) +// throws IOException, +// CertificateEncodingException, +// OperatorCreationException, +// CMSException { +// ArrayList certList = new ArrayList(1); +// certList.add(publicKey); +// JcaCertStore certs = new JcaCertStore(certList); +// +// CMSSignedDataGenerator gen = new CMSSignedDataGenerator(); +// ContentSigner signer = +// new JcaContentSignerBuilder( +// getJcaSignatureAlgorithmForOta(publicKey, hash)) +// .build(privateKey); +// gen.addSignerInfoGenerator( +// new JcaSignerInfoGeneratorBuilder( +// new JcaDigestCalculatorProviderBuilder() +// .build()) +// .setDirectSignature(true) +// .build(signer, publicKey)); +// gen.addCertificates(certs); +// CMSSignedData sigData = gen.generate(data, false); +// +// try (ASN1InputStream asn1 = new ASN1InputStream(sigData.getEncoded())) { +// DEROutputStream dos = new DEROutputStream(out); +// dos.writeObject(asn1.readObject()); +// } +// } +// +// /** +// * Adds ZIP entries which represent the v1 signature (JAR signature scheme). +// */ +// private static void addV1Signature( +// ApkSignerEngine apkSigner, +// ApkSignerEngine.OutputJarSignatureRequest v1Signature, +// JarOutputStream out, +// long timestamp) throws IOException { +// for (ApkSignerEngine.OutputJarSignatureRequest.JarEntry entry +// : v1Signature.getAdditionalJarEntries()) { +// String entryName = entry.getName(); +// JarEntry outEntry = new JarEntry(entryName); +// outEntry.setTime(timestamp); +// out.putNextEntry(outEntry); +// byte[] entryData = entry.getData(); +// out.write(entryData); +// ApkSignerEngine.InspectJarEntryRequest inspectEntryRequest = +// apkSigner.outputJarEntry(entryName); +// if (inspectEntryRequest != null) { +// inspectEntryRequest.getDataSink().consume(entryData, 0, entryData.length); +// inspectEntryRequest.done(); +// } +// } +// } +// +// /** +// * Copy all JAR entries from input to output. We set the modification times in the output to a +// * fixed time, so as to reduce variation in the output file and make incremental OTAs more +// * efficient. +// */ +// private static void copyFiles( +// JarFile in, +// Pattern ignoredFilenamePattern, +// ApkSignerEngine apkSigner, +// JarOutputStream out, +// long timestamp, +// int defaultAlignment) throws IOException { +// byte[] buffer = new byte[4096]; +// int num; +// +// ArrayList names = new ArrayList(); +// for (Enumeration e = in.entries(); e.hasMoreElements();) { +// JarEntry entry = e.nextElement(); +// if (entry.isDirectory()) { +// continue; +// } +// String entryName = entry.getName(); +// if ((ignoredFilenamePattern != null) +// && (ignoredFilenamePattern.matcher(entryName).matches())) { +// continue; +// } +// names.add(entryName); +// } +// Collections.sort(names); +// +// boolean firstEntry = true; +// long offset = 0L; +// +// // We do the copy in two passes -- first copying all the +// // entries that are STORED, then copying all the entries that +// // have any other compression flag (which in practice means +// // DEFLATED). This groups all the stored entries together at +// // the start of the file and makes it easier to do alignment +// // on them (since only stored entries are aligned). +// +// List remainingNames = new ArrayList<>(names.size()); +// for (String name : names) { +// JarEntry inEntry = in.getJarEntry(name); +// if (inEntry.getMethod() != JarEntry.STORED) { +// // Defer outputting this entry until we're ready to output compressed entries. +// remainingNames.add(name); +// continue; +// } +// +// if (!shouldOutputApkEntry(apkSigner, in, inEntry, buffer)) { +// continue; +// } +// +// // Preserve the STORED method of the input entry. +// JarEntry outEntry = new JarEntry(inEntry); +// outEntry.setTime(timestamp); +// // Discard comment and extra fields of this entry to +// // simplify alignment logic below and for consistency with +// // how compressed entries are handled later. +// outEntry.setComment(null); +// outEntry.setExtra(null); +// +// int alignment = getStoredEntryDataAlignment(name, defaultAlignment); +// // Alignment of the entry's data is achieved by adding a data block to the entry's Local +// // File Header extra field. The data block contains information about the alignment +// // value and the necessary padding bytes (0x00) to achieve the alignment. This works +// // because the entry's data will be located immediately after the extra field. +// // See ZIP APPNOTE.txt section "4.5 Extensible data fields" for details about the format +// // of the extra field. +// +// // 'offset' is the offset into the file at which we expect the entry's data to begin. +// // This is the value we need to make a multiple of 'alignment'. +// offset += JarFile.LOCHDR + outEntry.getName().length(); +// if (firstEntry) { +// // The first entry in a jar file has an extra field of four bytes that you can't get +// // rid of; any extra data you specify in the JarEntry is appended to these forced +// // four bytes. This is JAR_MAGIC in JarOutputStream; the bytes are 0xfeca0000. +// // See http://bugs.java.com/bugdatabase/view_bug.do?bug_id=6808540 +// // and http://bugs.java.com/bugdatabase/view_bug.do?bug_id=4138619. +// offset += 4; +// firstEntry = false; +// } +// int extraPaddingSizeBytes = 0; +// if (alignment > 0) { +// long paddingStartOffset = offset + ALIGNMENT_ZIP_EXTRA_DATA_FIELD_MIN_SIZE_BYTES; +// extraPaddingSizeBytes = alignment - (int) (paddingStartOffset % alignment); +// } +// byte[] extra = +// new byte[ALIGNMENT_ZIP_EXTRA_DATA_FIELD_MIN_SIZE_BYTES + extraPaddingSizeBytes]; +// ByteBuffer extraBuf = ByteBuffer.wrap(extra); +// extraBuf.order(ByteOrder.LITTLE_ENDIAN); +// extraBuf.putShort(ALIGNMENT_ZIP_EXTRA_DATA_FIELD_HEADER_ID); // Header ID +// extraBuf.putShort((short) (2 + extraPaddingSizeBytes)); // Data Size +// extraBuf.putShort((short) alignment); +// outEntry.setExtra(extra); +// offset += extra.length; +// +// out.putNextEntry(outEntry); +// ApkSignerEngine.InspectJarEntryRequest inspectEntryRequest = +// (apkSigner != null) ? apkSigner.outputJarEntry(name) : null; +// DataSink entryDataSink = +// (inspectEntryRequest != null) ? inspectEntryRequest.getDataSink() : null; +// +// try (InputStream data = in.getInputStream(inEntry)) { +// while ((num = data.read(buffer)) > 0) { +// out.write(buffer, 0, num); +// if (entryDataSink != null) { +// entryDataSink.consume(buffer, 0, num); +// } +// offset += num; +// } +// } +// out.flush(); +// if (inspectEntryRequest != null) { +// inspectEntryRequest.done(); +// } +// } +// +// // Copy all the non-STORED entries. We don't attempt to +// // maintain the 'offset' variable past this point; we don't do +// // alignment on these entries. +// +// for (String name : remainingNames) { +// JarEntry inEntry = in.getJarEntry(name); +// if (!shouldOutputApkEntry(apkSigner, in, inEntry, buffer)) { +// continue; +// } +// +// // Create a new entry so that the compressed len is recomputed. +// JarEntry outEntry = new JarEntry(name); +// outEntry.setTime(timestamp); +// out.putNextEntry(outEntry); +// ApkSignerEngine.InspectJarEntryRequest inspectEntryRequest = +// (apkSigner != null) ? apkSigner.outputJarEntry(name) : null; +// DataSink entryDataSink = +// (inspectEntryRequest != null) ? inspectEntryRequest.getDataSink() : null; +// +// InputStream data = in.getInputStream(inEntry); +// while ((num = data.read(buffer)) > 0) { +// out.write(buffer, 0, num); +// if (entryDataSink != null) { +// entryDataSink.consume(buffer, 0, num); +// } +// } +// out.flush(); +// if (inspectEntryRequest != null) { +// inspectEntryRequest.done(); +// } +// } +// } +// +// private static boolean shouldOutputApkEntry( +// ApkSignerEngine apkSigner, JarFile inFile, JarEntry inEntry, byte[] tmpbuf) +// throws IOException { +// if (apkSigner == null) { +// return true; +// } +// +// ApkSignerEngine.InputJarEntryInstructions instructions = +// apkSigner.inputJarEntry(inEntry.getName()); +// ApkSignerEngine.InspectJarEntryRequest inspectEntryRequest = +// instructions.getInspectJarEntryRequest(); +// if (inspectEntryRequest != null) { +// provideJarEntry(inFile, inEntry, inspectEntryRequest, tmpbuf); +// } +// switch (instructions.getOutputPolicy()) { +// case OUTPUT: +// return true; +// case SKIP: +// case OUTPUT_BY_ENGINE: +// return false; +// default: +// throw new RuntimeException( +// "Unsupported output policy: " + instructions.getOutputPolicy()); +// } +// } +// +// private static void provideJarEntry( +// JarFile jarFile, +// JarEntry jarEntry, +// ApkSignerEngine.InspectJarEntryRequest request, +// byte[] tmpbuf) throws IOException { +// DataSink dataSink = request.getDataSink(); +// try (InputStream in = jarFile.getInputStream(jarEntry)) { +// int chunkSize; +// while ((chunkSize = in.read(tmpbuf)) > 0) { +// dataSink.consume(tmpbuf, 0, chunkSize); +// } +// request.done(); +// } +// } +// +// /** +// * Returns the multiple (in bytes) at which the provided {@code STORED} entry's data must start +// * relative to start of file or {@code 0} if alignment of this entry's data is not important. +// */ +// private static int getStoredEntryDataAlignment(String entryName, int defaultAlignment) { +// if (defaultAlignment <= 0) { +// return 0; +// } +// +// if (entryName.endsWith(".so")) { +// // Align .so contents to memory page boundary to enable memory-mapped +// // execution. +// return 4096; +// } else { +// return defaultAlignment; +// } +// } +// +// private static class WholeFileSignerOutputStream extends FilterOutputStream { +// private boolean closing = false; +// private ByteArrayOutputStream footer = new ByteArrayOutputStream(); +// private OutputStream tee; +// +// public WholeFileSignerOutputStream(OutputStream out, OutputStream tee) { +// super(out); +// this.tee = tee; +// } +// +// public void notifyClosing() { +// closing = true; +// } +// +// public void finish() throws IOException { +// closing = false; +// +// byte[] data = footer.toByteArray(); +// if (data.length < 2) +// throw new IOException("Less than two bytes written to footer"); +// write(data, 0, data.length - 2); +// } +// +// public byte[] getTail() { +// return footer.toByteArray(); +// } +// +// @Override +// public void write(byte[] b) throws IOException { +// write(b, 0, b.length); +// } +// +// @Override +// public void write(byte[] b, int off, int len) throws IOException { +// if (closing) { +// // if the jar is about to close, save the footer that will be written +// footer.write(b, off, len); +// } +// else { +// // write to both output streams. out is the CMSTypedData signer and tee is the file. +// out.write(b, off, len); +// tee.write(b, off, len); +// } +// } +// +// @Override +// public void write(int b) throws IOException { +// if (closing) { +// // if the jar is about to close, save the footer that will be written +// footer.write(b); +// } +// else { +// // write to both output streams. out is the CMSTypedData signer and tee is the file. +// out.write(b); +// tee.write(b); +// } +// } +// } +// +// private static class CMSSigner implements CMSTypedData { +// private final JarFile inputJar; +// private final File publicKeyFile; +// private final X509Certificate publicKey; +// private final PrivateKey privateKey; +// private final int hash; +// private final long timestamp; +// private final OutputStream outputStream; +// private final ASN1ObjectIdentifier type; +// private WholeFileSignerOutputStream signer; +// +// // Files matching this pattern are not copied to the output. +// private static final Pattern STRIP_PATTERN = +// Pattern.compile("^(META-INF/((.*)[.](SF|RSA|DSA|EC)|com/android/otacert))|(" +// + Pattern.quote(JarFile.MANIFEST_NAME) + ")$"); +// +// public CMSSigner(JarFile inputJar, File publicKeyFile, +// X509Certificate publicKey, PrivateKey privateKey, int hash, +// long timestamp, OutputStream outputStream) { +// this.inputJar = inputJar; +// this.publicKeyFile = publicKeyFile; +// this.publicKey = publicKey; +// this.privateKey = privateKey; +// this.hash = hash; +// this.timestamp = timestamp; +// this.outputStream = outputStream; +// this.type = new ASN1ObjectIdentifier(CMSObjectIdentifiers.data.getId()); +// } +// +// /** +// * This should actually return byte[] or something similar, but nothing +// * actually checks it currently. +// */ +// @Override +// public Object getContent() { +// return this; +// } +// +// @Override +// public ASN1ObjectIdentifier getContentType() { +// return type; +// } +// +// @Override +// public void write(OutputStream out) throws IOException { +// try { +// signer = new WholeFileSignerOutputStream(out, outputStream); +// JarOutputStream outputJar = new JarOutputStream(signer); +// +// copyFiles(inputJar, STRIP_PATTERN, null, outputJar, timestamp, 0); +// addOtacert(outputJar, publicKeyFile, timestamp); +// +// signer.notifyClosing(); +// outputJar.close(); +// signer.finish(); +// } +// catch (Exception e) { +// throw new IOException(e); +// } +// } +// +// public void writeSignatureBlock(ByteArrayOutputStream temp) +// throws IOException, +// CertificateEncodingException, +// OperatorCreationException, +// CMSException { +// SignApk.writeSignatureBlock(this, publicKey, privateKey, hash, temp); +// } +// +// public WholeFileSignerOutputStream getSigner() { +// return signer; +// } +// } +// +// private static void signWholeFile(JarFile inputJar, File publicKeyFile, +// X509Certificate publicKey, PrivateKey privateKey, +// int hash, long timestamp, +// OutputStream outputStream) throws Exception { +// CMSSigner cmsOut = new CMSSigner(inputJar, publicKeyFile, +// publicKey, privateKey, hash, timestamp, outputStream); +// +// ByteArrayOutputStream temp = new ByteArrayOutputStream(); +// +// // put a readable message and a null char at the start of the +// // archive comment, so that tools that display the comment +// // (hopefully) show something sensible. +// // TODO: anything more useful we can put in this message? +// byte[] message = "signed by SignApk".getBytes("UTF-8"); +// temp.write(message); +// temp.write(0); +// +// cmsOut.writeSignatureBlock(temp); +// +// byte[] zipData = cmsOut.getSigner().getTail(); +// +// // For a zip with no archive comment, the +// // end-of-central-directory record will be 22 bytes long, so +// // we expect to find the EOCD marker 22 bytes from the end. +// if (zipData[zipData.length-22] != 0x50 || +// zipData[zipData.length-21] != 0x4b || +// zipData[zipData.length-20] != 0x05 || +// zipData[zipData.length-19] != 0x06) { +// throw new IllegalArgumentException("zip data already has an archive comment"); +// } +// +// int total_size = temp.size() + 6; +// if (total_size > 0xffff) { +// throw new IllegalArgumentException("signature is too big for ZIP file comment"); +// } +// // signature starts this many bytes from the end of the file +// int signature_start = total_size - message.length - 1; +// temp.write(signature_start & 0xff); +// temp.write((signature_start >> 8) & 0xff); +// // Why the 0xff bytes? In a zip file with no archive comment, +// // bytes [-6:-2] of the file are the little-endian offset from +// // the start of the file to the central directory. So for the +// // two high bytes to be 0xff 0xff, the archive would have to +// // be nearly 4GB in size. So it's unlikely that a real +// // commentless archive would have 0xffs here, and lets us tell +// // an old signed archive from a new one. +// temp.write(0xff); +// temp.write(0xff); +// temp.write(total_size & 0xff); +// temp.write((total_size >> 8) & 0xff); +// temp.flush(); +// +// // Signature verification checks that the EOCD header is the +// // last such sequence in the file (to avoid minzip finding a +// // fake EOCD appended after the signature in its scan). The +// // odds of producing this sequence by chance are very low, but +// // let's catch it here if it does. +// byte[] b = temp.toByteArray(); +// for (int i = 0; i < b.length-3; ++i) { +// if (b[i] == 0x50 && b[i+1] == 0x4b && b[i+2] == 0x05 && b[i+3] == 0x06) { +// throw new IllegalArgumentException("found spurious EOCD header at " + i); +// } +// } +// +// outputStream.write(total_size & 0xff); +// outputStream.write((total_size >> 8) & 0xff); +// temp.writeTo(outputStream); +// } +// +// /** +// * Tries to load a JSE Provider by class name. This is for custom PrivateKey +// * types that might be stored in PKCS#11-like storage. +// */ +// private static void loadProviderIfNecessary(String providerClassName) { +// if (providerClassName == null) { +// return; +// } +// +// final Class klass; +// try { +// final ClassLoader sysLoader = ClassLoader.getSystemClassLoader(); +// if (sysLoader != null) { +// klass = sysLoader.loadClass(providerClassName); +// } else { +// klass = Class.forName(providerClassName); +// } +// } catch (ClassNotFoundException e) { +// e.printStackTrace(); +// System.exit(1); +// return; +// } +// +// Constructor constructor = null; +// for (Constructor c : klass.getConstructors()) { +// if (c.getParameterTypes().length == 0) { +// constructor = c; +// break; +// } +// } +// if (constructor == null) { +// System.err.println("No zero-arg constructor found for " + providerClassName); +// System.exit(1); +// return; +// } +// +// final Object o; +// try { +// o = constructor.newInstance(); +// } catch (Exception e) { +// e.printStackTrace(); +// System.exit(1); +// return; +// } +// if (!(o instanceof Provider)) { +// System.err.println("Not a Provider class: " + providerClassName); +// System.exit(1); +// } +// +// Security.insertProviderAt((Provider) o, 1); +// } +// +// private static List createSignerConfigs( +// PrivateKey[] privateKeys, X509Certificate[] certificates) { +// if (privateKeys.length != certificates.length) { +// throw new IllegalArgumentException( +// "The number of private keys must match the number of certificates: " +// + privateKeys.length + " vs" + certificates.length); +// } +// List signerConfigs = new ArrayList<>(); +// String signerNameFormat = (privateKeys.length == 1) ? "CERT" : "CERT%s"; +// for (int i = 0; i < privateKeys.length; i++) { +// String signerName = String.format(Locale.US, signerNameFormat, (i + 1)); +// DefaultApkSignerEngine.SignerConfig signerConfig = +// new DefaultApkSignerEngine.SignerConfig.Builder( +// signerName, +// privateKeys[i], +// Collections.singletonList(certificates[i])) +// .build(); +// signerConfigs.add(signerConfig); +// } +// return signerConfigs; +// } +// +// private static class ZipSections { +// ByteBuffer beforeCentralDir; +// ByteBuffer centralDir; +// ByteBuffer eocd; +// } +// +// private static ZipSections findMainZipSections(ByteBuffer apk) +// throws IOException, ZipFormatException { +// apk.slice(); +// ApkUtils.ZipSections sections = ApkUtils.findZipSections(DataSources.asDataSource(apk)); +// long centralDirStartOffset = sections.getZipCentralDirectoryOffset(); +// long centralDirSizeBytes = sections.getZipCentralDirectorySizeBytes(); +// long centralDirEndOffset = centralDirStartOffset + centralDirSizeBytes; +// long eocdStartOffset = sections.getZipEndOfCentralDirectoryOffset(); +// if (centralDirEndOffset != eocdStartOffset) { +// throw new ZipFormatException( +// "ZIP Central Directory is not immediately followed by End of Central Directory" +// + ". CD end: " + centralDirEndOffset +// + ", EoCD start: " + eocdStartOffset); +// } +// apk.position(0); +// apk.limit((int) centralDirStartOffset); +// ByteBuffer beforeCentralDir = apk.slice(); +// +// apk.position((int) centralDirStartOffset); +// apk.limit((int) centralDirEndOffset); +// ByteBuffer centralDir = apk.slice(); +// +// apk.position((int) eocdStartOffset); +// apk.limit(apk.capacity()); +// ByteBuffer eocd = apk.slice(); +// +// apk.position(0); +// apk.limit(apk.capacity()); +// +// ZipSections result = new ZipSections(); +// result.beforeCentralDir = beforeCentralDir; +// result.centralDir = centralDir; +// result.eocd = eocd; +// return result; +// } +// +// private static void usage() { +// System.err.println("Usage: signapk [-w] " + +// "[-a ] " + +// "[-providerClass ] " + +// "[--min-sdk-version ] " + +// "[--disable-v2] " + +// "publickey.x509[.pem] privatekey.pk8 " + +// "[publickey2.x509[.pem] privatekey2.pk8 ...] " + +// "input.jar output.jar"); +// System.exit(2); +// } +// +// public static void main(String[] args) { +// if (args.length < 4) usage(); +// +// // Install Conscrypt as the highest-priority provider. Its crypto primitives are faster than +// // the standard or Bouncy Castle ones. +// Security.insertProviderAt(new OpenSSLProvider(), 1); +// // Install Bouncy Castle (as the lowest-priority provider) because Conscrypt does not offer +// // DSA which may still be needed. +// // TODO: Stop installing Bouncy Castle provider once DSA is no longer needed. +// Security.addProvider(new BouncyCastleProvider()); +// +// boolean signWholeFile = false; +// String providerClass = null; +// int alignment = 4; +// int minSdkVersion = 0; +// boolean signUsingApkSignatureSchemeV2 = true; +// +// int argstart = 0; +// while (argstart < args.length && args[argstart].startsWith("-")) { +// if ("-w".equals(args[argstart])) { +// signWholeFile = true; +// ++argstart; +// } else if ("-providerClass".equals(args[argstart])) { +// if (argstart + 1 >= args.length) { +// usage(); +// } +// providerClass = args[++argstart]; +// ++argstart; +// } else if ("-a".equals(args[argstart])) { +// alignment = Integer.parseInt(args[++argstart]); +// ++argstart; +// } else if ("--min-sdk-version".equals(args[argstart])) { +// String minSdkVersionString = args[++argstart]; +// try { +// minSdkVersion = Integer.parseInt(minSdkVersionString); +// } catch (NumberFormatException e) { +// throw new IllegalArgumentException( +// "--min-sdk-version must be a decimal number: " + minSdkVersionString); +// } +// ++argstart; +// } else if ("--disable-v2".equals(args[argstart])) { +// signUsingApkSignatureSchemeV2 = false; +// ++argstart; +// } else { +// usage(); +// } +// } +// +// if ((args.length - argstart) % 2 == 1) usage(); +// int numKeys = ((args.length - argstart) / 2) - 1; +// if (signWholeFile && numKeys > 1) { +// System.err.println("Only one key may be used with -w."); +// System.exit(2); +// } +// +// loadProviderIfNecessary(providerClass); +// +// String inputFilename = args[args.length-2]; +// String outputFilename = args[args.length-1]; +// +// JarFile inputJar = null; +// FileOutputStream outputFile = null; +// +// try { +// File firstPublicKeyFile = new File(args[argstart+0]); +// +// X509Certificate[] publicKey = new X509Certificate[numKeys]; +// try { +// for (int i = 0; i < numKeys; ++i) { +// int argNum = argstart + i*2; +// publicKey[i] = readPublicKey(new File(args[argNum])); +// } +// } catch (IllegalArgumentException e) { +// System.err.println(e); +// System.exit(1); +// } +// +// // Set all ZIP file timestamps to Jan 1 2009 00:00:00. +// long timestamp = 1230768000000L; +// // The Java ZipEntry API we're using converts milliseconds since epoch into MS-DOS +// // timestamp using the current timezone. We thus adjust the milliseconds since epoch +// // value to end up with MS-DOS timestamp of Jan 1 2009 00:00:00. +// timestamp -= TimeZone.getDefault().getOffset(timestamp); +// +// PrivateKey[] privateKey = new PrivateKey[numKeys]; +// for (int i = 0; i < numKeys; ++i) { +// int argNum = argstart + i*2 + 1; +// privateKey[i] = readPrivateKey(new File(args[argNum])); +// } +// inputJar = new JarFile(new File(inputFilename), false); // Don't verify. +// +// outputFile = new FileOutputStream(outputFilename); +// +// // NOTE: Signing currently recompresses any compressed entries using Deflate (default +// // compression level for OTA update files and maximum compession level for APKs). +// if (signWholeFile) { +// int digestAlgorithm = getDigestAlgorithmForOta(publicKey[0]); +// signWholeFile(inputJar, firstPublicKeyFile, +// publicKey[0], privateKey[0], digestAlgorithm, +// timestamp, +// outputFile); +// } else { +// try (ApkSignerEngine apkSigner = +// new DefaultApkSignerEngine.Builder( +// createSignerConfigs(privateKey, publicKey), minSdkVersion) +// .setV1SigningEnabled(true) +// .setV2SigningEnabled(signUsingApkSignatureSchemeV2) +// .setOtherSignersSignaturesPreserved(false) +// .build()) { +// // We don't preserve the input APK's APK Signing Block (which contains v2 +// // signatures) +// apkSigner.inputApkSigningBlock(null); +// +// // Build the output APK in memory, by copying input APK's ZIP entries across +// // and then signing the output APK. +// ByteArrayOutputStream v1SignedApkBuf = new ByteArrayOutputStream(); +// JarOutputStream outputJar = new JarOutputStream(v1SignedApkBuf); +// // Use maximum compression for compressed entries because the APK lives forever +// // on the system partition. +// outputJar.setLevel(9); +// copyFiles(inputJar, null, apkSigner, outputJar, timestamp, alignment); +// ApkSignerEngine.OutputJarSignatureRequest addV1SignatureRequest = +// apkSigner.outputJarEntries(); +// if (addV1SignatureRequest != null) { +// addV1Signature(apkSigner, addV1SignatureRequest, outputJar, timestamp); +// addV1SignatureRequest.done(); +// } +// outputJar.close(); +// ByteBuffer v1SignedApk = ByteBuffer.wrap(v1SignedApkBuf.toByteArray()); +// v1SignedApkBuf.reset(); +// ByteBuffer[] outputChunks = new ByteBuffer[] {v1SignedApk}; +// +// ZipSections zipSections = findMainZipSections(v1SignedApk); +// ApkSignerEngine.OutputApkSigningBlockRequest addV2SignatureRequest = +// apkSigner.outputZipSections( +// DataSources.asDataSource(zipSections.beforeCentralDir), +// DataSources.asDataSource(zipSections.centralDir), +// DataSources.asDataSource(zipSections.eocd)); +// if (addV2SignatureRequest != null) { +// // Need to insert the returned APK Signing Block before ZIP Central +// // Directory. +// byte[] apkSigningBlock = addV2SignatureRequest.getApkSigningBlock(); +// // Because the APK Signing Block is inserted before the Central Directory, +// // we need to adjust accordingly the offset of Central Directory inside the +// // ZIP End of Central Directory (EoCD) record. +// ByteBuffer modifiedEocd = ByteBuffer.allocate(zipSections.eocd.remaining()); +// modifiedEocd.put(zipSections.eocd); +// modifiedEocd.flip(); +// modifiedEocd.order(ByteOrder.LITTLE_ENDIAN); +// ApkUtils.setZipEocdCentralDirectoryOffset( +// modifiedEocd, +// zipSections.beforeCentralDir.remaining() + apkSigningBlock.length); +// outputChunks = +// new ByteBuffer[] { +// zipSections.beforeCentralDir, +// ByteBuffer.wrap(apkSigningBlock), +// zipSections.centralDir, +// modifiedEocd}; +// addV2SignatureRequest.done(); +// } +// +// // This assumes outputChunks are array-backed. To avoid this assumption, the +// // code could be rewritten to use FileChannel. +// for (ByteBuffer outputChunk : outputChunks) { +// outputFile.write( +// outputChunk.array(), +// outputChunk.arrayOffset() + outputChunk.position(), +// outputChunk.remaining()); +// outputChunk.position(outputChunk.limit()); +// } +// +// outputFile.close(); +// outputFile = null; +// apkSigner.outputDone(); +// } +// +// return; +// } +// } catch (Exception e) { +// e.printStackTrace(); +// System.exit(1); +// } finally { +// try { +// if (inputJar != null) inputJar.close(); +// if (outputFile != null) outputFile.close(); +// } catch (IOException e) { +// e.printStackTrace(); +// System.exit(1); +// } +// } +// } +//} diff --git a/plugin/src/main/resources/META-INF/gradle-plugins/walle.properties b/plugin/src/main/resources/META-INF/gradle-plugins/walle.properties new file mode 100644 index 0000000..97647ca --- /dev/null +++ b/plugin/src/main/resources/META-INF/gradle-plugins/walle.properties @@ -0,0 +1 @@ +implementation-class=com.meituan.android.walle.GradlePlugin \ No newline at end of file diff --git a/sample/app/.gitignore b/sample/app/.gitignore new file mode 100644 index 0000000..c125ebd --- /dev/null +++ b/sample/app/.gitignore @@ -0,0 +1,3 @@ +/build + +/version.properties diff --git a/sample/app/build.gradle b/sample/app/build.gradle new file mode 100644 index 0000000..24e7b03 --- /dev/null +++ b/sample/app/build.gradle @@ -0,0 +1,53 @@ +apply plugin: 'com.android.application' +apply plugin: 'walle' + +android { + + compileSdkVersion 24 + buildToolsVersion '24.0.1' + + defaultConfig { + minSdkVersion 16 + targetSdkVersion 24 + versionCode 1 + versionName "0.0.1" + applicationId "com.meituan.android.walle.sample" + } + + signingConfigs { + sankuai { + storeFile file("keystore/meituan-debug.keystore") + storePassword "1234567" + keyAlias "meituan" + keyPassword "12345678" + } + } + + buildTypes { + release { + minifyEnabled true + shrinkResources true + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + + signingConfig signingConfigs.sankuai + } + + debug { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + + signingConfig signingConfigs.sankuai + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_7 + targetCompatibility JavaVersion.VERSION_1_7 + } +} + +dependencies { + compile fileTree(dir: 'libs', include: ['*.jar']) + compile 'com.android.support:support-v4:24.1.1' + compile 'com.android.support:appcompat-v7:24.1.1' +} diff --git a/sample/app/keystore/meituan-debug.keystore b/sample/app/keystore/meituan-debug.keystore new file mode 100644 index 0000000000000000000000000000000000000000..4d52fb7407b12e863a5b87e55f379b59d90f02a1 GIT binary patch literal 2227 zcmchYS5y;-5{8oyA}xSHM5TnP(vy(T35v^7RtQRq2tf#7D25^^2x16QE{IB31f)uk zt|*`wr3g|(4blYxsZv9gxLnWfIX>Ly`!EmRf97H4pE)z^CH4{k0012X@K+qV=IZVr z;6y%Pvu`R}wg3Pp2tft25&RGyMF(_Bdx=pmfTaznxZ5X_rjXPmwb3xy15qq zsE%5vj@j2OaW4>T5QV7;%J+l1Dp_d{Gqz2aUqL>9c2;|~e;{}6wj2MaW z2<^oIIU#&oM6$V(zPT88TP5j4IefxAQ&^)aJJEi^slG&9(^8tt>9blL@|oXw-j{q7 zod1?$a@VAoIMn);$jw=HY0G4Pk0;lRU}%Zlon6kkjVFOL;Rk6lC8yioAYU38F)5ZA z5-wh(K3U|(aUVST5cxPN#>DqQS~YT{{jI8#K~ta6s09mTo(_m1T0Qxc5^Qk)6qYbk z`_sN8N_qKwyKhGLrQFIFk3?tz_nge$8!AiLai&*1uTP9v$0ibWE>ieINlE8j&RIhC zB4={Ce z^_K7;F>-RLFbm8gA-oGTW1 zwg%k?2+;~NvRfuC^I#cGw-oErw_Al1(qc;;*5Vx^Hezq+t%?$!MQ$N;-}|YbbtW+V zeRI)6H#ga^V4h>ZhI_ZMp~2s9O|S027He!Z=4ReTGT)7<=%Kfx8d7tr;ty%uI4 zyK@9eybC`)lamRQW?Y|j)L8Tr*f=JQJne0`XYklhQw%j;*tPh)Ib-9sZs!7EN)n4&hea6lAuf5O9@9BQ?tPKtUl@Cylt}wop|AP%k*L zE+$LL+KrzM(#or~N@fO_JjyA@@+rPhdK*HhY7eH=+a^l&bh8ZE3%y=>Ty%Qq+_hzC z(CM4mQa2pbLzHbDgL2De>t`o7;CSku^Z;= z7CdO~)_?)|Sq1r;zgw@zv71;?mh3!Q4j~1rNU_$FtK<$rR8tB@lADuy+ygzv!8X4u|L3`pEr)e!Kn)5wWe!638%01kHq zmBST51({`WfPf$n7=E%M83BcGD?}PcZb5-SUQPglh~!0ZLpZF#5FyYx^M8R$2xMve zFC6*>FofWL(|Clqy}XG|UL^19{>Xnc-v6O-{H7r!M4(6vLLG@hXkkzYw4DePjY1+& zn*ZScrwA%g`uFA!egg*;C;&iEfjl585D19q?PI2~h%9Fvqg8U*gt-7-5+%c&+hUk# z;_d`*tQToMz2A)JzuBfcT6M@sBM_;VGgiIIOIO*ix&1C51S^YX79!dbp3GHwqoY3D zs&DCEK4Y^E8Lg8kU>!Y)yQH74sdKmO&GY8dA5Fb|1Mbx+!jVFlcqFw;5d$o4o{HMVxeMqCfq8cEMjADruLweHH{U6IoqRX*0HCKwT-m$upx!12W}q!OKZbRA(aSBu + + + + + + + + + + + + + + + diff --git a/sample/app/src/main/java/com/meituan/android/walle/sample/MainActivity.java b/sample/app/src/main/java/com/meituan/android/walle/sample/MainActivity.java new file mode 100644 index 0000000..fe57d04 --- /dev/null +++ b/sample/app/src/main/java/com/meituan/android/walle/sample/MainActivity.java @@ -0,0 +1,12 @@ +package com.meituan.android.walle.sample; + +import android.os.Bundle; +import android.support.v7.app.AppCompatActivity; + +public class MainActivity extends AppCompatActivity { + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_main); + } +} diff --git a/sample/app/src/main/java/com/meituan/android/walle/sample/MyApplication.java b/sample/app/src/main/java/com/meituan/android/walle/sample/MyApplication.java new file mode 100644 index 0000000..1922f0d --- /dev/null +++ b/sample/app/src/main/java/com/meituan/android/walle/sample/MyApplication.java @@ -0,0 +1,8 @@ + +package com.meituan.android.walle.sample; + +import android.app.Application; + +public class MyApplication extends Application { + +} diff --git a/sample/app/src/main/res/layout/activity_main.xml b/sample/app/src/main/res/layout/activity_main.xml new file mode 100644 index 0000000..f9a033c --- /dev/null +++ b/sample/app/src/main/res/layout/activity_main.xml @@ -0,0 +1,32 @@ + + + + + + + + + diff --git a/sample/app/src/main/res/mipmap-hdpi/ic_launcher.png b/sample/app/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..cde69bcccec65160d92116f20ffce4fce0b5245c GIT binary patch literal 3418 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 literal 0 HcmV?d00001 diff --git a/sample/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/sample/app/src/main/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..bfa42f0e7b91d006d22352c9ff2f134e504e3c1d GIT binary patch literal 4842 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 literal 0 HcmV?d00001 diff --git a/sample/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/sample/app/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..324e72cdd7480cb983fa1bcc7ce686e51ef87fe7 GIT binary patch literal 7718 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 literal 0 HcmV?d00001 diff --git a/sample/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/sample/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..aee44e138434630332d88b1680f33c4b24c70ab3 GIT binary patch literal 10486 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 + + 64dp + diff --git a/sample/app/src/main/res/values/colors.xml b/sample/app/src/main/res/values/colors.xml new file mode 100644 index 0000000..3ab3e9c --- /dev/null +++ b/sample/app/src/main/res/values/colors.xml @@ -0,0 +1,6 @@ + + + #3F51B5 + #303F9F + #FF4081 + diff --git a/sample/app/src/main/res/values/dimens.xml b/sample/app/src/main/res/values/dimens.xml new file mode 100644 index 0000000..47c8224 --- /dev/null +++ b/sample/app/src/main/res/values/dimens.xml @@ -0,0 +1,5 @@ + + + 16dp + 16dp + diff --git a/sample/app/src/main/res/values/strings.xml b/sample/app/src/main/res/values/strings.xml new file mode 100644 index 0000000..facfe8a --- /dev/null +++ b/sample/app/src/main/res/values/strings.xml @@ -0,0 +1,3 @@ + + Walle-Sample + diff --git a/sample/app/src/main/res/values/styles.xml b/sample/app/src/main/res/values/styles.xml new file mode 100644 index 0000000..391ec9a --- /dev/null +++ b/sample/app/src/main/res/values/styles.xml @@ -0,0 +1,10 @@ + + + + + diff --git a/sample/build.gradle b/sample/build.gradle new file mode 100644 index 0000000..11130f4 --- /dev/null +++ b/sample/build.gradle @@ -0,0 +1,19 @@ + +buildscript { + repositories { + mavenLocal() + jcenter() + } + dependencies { + classpath 'com.android.tools.build:gradle:2.2.0' + classpath "com.meituan.android.walle:plugin:${WALLE_PLUGIN_VERSION}" + } +} + +allprojects { + repositories { + mavenLocal() + jcenter() + } +} + diff --git a/sample/gradle.properties b/sample/gradle.properties new file mode 100644 index 0000000..429e196 --- /dev/null +++ b/sample/gradle.properties @@ -0,0 +1,21 @@ +# Project-wide Gradle settings. + +# IDE (e.g. Android Studio) users: +# Gradle settings configured through the IDE *will override* +# any settings specified in this file. + +# For more details on how to configure your build environment visit +# http://www.gradle.org/docs/current/userguide/build_environment.html + +# Specifies the JVM arguments used for the daemon process. +# The setting is particularly useful for tweaking memory settings. +# Default value: -Xmx10248m -XX:MaxPermSize=256m + org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=1024m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 + +# When configured, Gradle will run in incubating parallel mode. +# This option should only be used with decoupled projects. More details, visit +# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects +# org.gradle.parallel=true + +WALLE_PLUGIN_VERSION=0.0.1 + diff --git a/sample/gradle/wrapper/gradle-wrapper.jar b/sample/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..05ef575b0cd0173fc735f2857ce4bd594ce4f6bd GIT binary patch literal 53637 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 t9m@SZ!E*7&jsr?!t7TL-WYI4eM@gAug8 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 \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules +function splitJvmOpts() { + JVM_OPTS=("$@") +} +eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS +JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" + +exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" diff --git a/sample/gradlew.bat b/sample/gradlew.bat new file mode 100644 index 0000000..8a0b282 --- /dev/null +++ b/sample/gradlew.bat @@ -0,0 +1,90 @@ +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windowz variants + +if not "%OS%" == "Windows_NT" goto win9xME_args +if "%@eval[2+2]" == "4" goto 4NT_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* +goto execute + +:4NT_args +@rem Get arguments from the 4NT Shell from JP Software +set CMD_LINE_ARGS=%$ + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/sample/settings.gradle b/sample/settings.gradle new file mode 100644 index 0000000..e7b4def --- /dev/null +++ b/sample/settings.gradle @@ -0,0 +1 @@ +include ':app' diff --git a/settings.gradle b/settings.gradle new file mode 100644 index 0000000..d796d23 --- /dev/null +++ b/settings.gradle @@ -0,0 +1 @@ +include ':plugin', ':library'

The engine is stateful and thus cannot be used for signing multiple APKs. However, once + * the engine signed an APK, the engine can be used to re-sign the APK after it has been modified. + * This may be more efficient than signing the APK using a new instance of the engine. See + * Incremental Operation. + * + *