parent
c0fc70c7c0
commit
6d579368af
@ -1,4 +1,5 @@
|
|||||||
apply plugin: 'com.android.application'
|
apply plugin: 'com.android.application'
|
||||||
|
apply plugin: 'witness'
|
||||||
if (!hasProperty('sourceDeps')) {
|
if (!hasProperty('sourceDeps')) {
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
@ -84,6 +85,26 @@ if (!hasProperty('sourceDeps')) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
// Only do the libraries imported from maven repositories. Our own libraries
|
||||||
|
// (like privileged-api-lib) and the prebuilt jars already checked into the
|
||||||
|
// source code don't need to be here.
|
||||||
|
dependencyVerification {
|
||||||
|
verify = [
|
||||||
|
'com.android.support:support-v4:c62f0d025dafa86f423f48df9185b0d89496adbc5f6a9be5a7c394d84cf91423',
|
||||||
|
'com.android.support:appcompat-v7:9a2355537c2f01cf0b95523605c18606b8d824017e6e94a05c77b0cfc8f21c96',
|
||||||
|
'com.android.support:support-annotations:104f353b53d5dd8d64b2f77eece4b37f6b961de9732eb6b706395e91033ec70a',
|
||||||
|
'org.thoughtcrime.ssl.pinning:AndroidPinning:afa1d74e699257fa75cb109ff29bac50726ef269c6e306bdeffe8223cee06ef4',
|
||||||
|
'com.nostra13.universalimageloader:universal-image-loader:b99382c5536c7325ef8dc0a0fe9a6cad803cf3488942bea7e1cca4db3e5dec43',
|
||||||
|
'com.google.zxing:core:b4d82452e7a6bf6ec2698904b332431717ed8f9a850224f295aec89de80f2259',
|
||||||
|
'eu.chainfire:libsuperuser:507f5f9703a7578406e672a96ff038fd8aeefd6e2fcb14dd0daba796239d6eaf',
|
||||||
|
'cc.mvdan.accesspoint:library:dc89a085d6bc40381078b8dd7776b12bde0dbaf8ffbcddb17ec4ebc3edecc7ba',
|
||||||
|
'info.guardianproject.netcipher:netcipher:a8eef6c3bf190e360c44c9364044b8050f0d387418acdae8d7ec78bd105a32a6',
|
||||||
|
'com.madgag.spongycastle:pkix:0d9cca6991f68eb373cfad309d5268c9fc38db5efb5fe00dcccf5c973af1eca1',
|
||||||
|
'com.madgag.spongycastle:prov:b8c3fec3a59aac1aa04ccf4dad7179351e54ef7672f53f508151b614c131398a',
|
||||||
|
'com.madgag.spongycastle:core:8d6240b974b0aca4d3da9c7dd44d42339d8a374358aca5fc98e50a995764511f',
|
||||||
|
'commons-net:commons-net:b35ad597f17a6f221575df2f729a9de8f70390509e047680771e713bad713fb9',
|
||||||
|
]
|
||||||
|
}
|
||||||
task binaryDeps(type: Copy, dependsOn: ':F-Droid:prepareReleaseDependencies') {
|
task binaryDeps(type: Copy, dependsOn: ':F-Droid:prepareReleaseDependencies') {
|
||||||
|
|
||||||
enabled = project.hasProperty('sourceDeps')
|
enabled = project.hasProperty('sourceDeps')
|
||||||
|
@ -4,5 +4,6 @@ buildscript {
|
|||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath 'com.android.tools.build:gradle:1.3.1'
|
classpath 'com.android.tools.build:gradle:1.3.1'
|
||||||
|
classpath files('libs/gradle-witness.jar')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
19
extern/gradle-witness/LICENSE
vendored
Normal file
19
extern/gradle-witness/LICENSE
vendored
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
Copyright (c) 2014 Open Whisper Systems
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
127
extern/gradle-witness/README.md
vendored
Normal file
127
extern/gradle-witness/README.md
vendored
Normal file
@ -0,0 +1,127 @@
|
|||||||
|
# Gradle Witness
|
||||||
|
|
||||||
|
A gradle plugin that enables static verification for remote dependencies.
|
||||||
|
|
||||||
|
Build systems like gradle and maven allow one to specify dependencies for versioned artifacts. An
|
||||||
|
Android project might list dependencies like this:
|
||||||
|
|
||||||
|
dependency {
|
||||||
|
compile 'com.actionbarsherlock:actionbarsherlock:4.4.0@aar'
|
||||||
|
compile 'com.android.support:support-v4:19.0.1'
|
||||||
|
compile 'com.google.android.gcm:gcm-client:1.0.2'
|
||||||
|
compile 'se.emilsjolander:stickylistheaders:2.2.0'
|
||||||
|
}
|
||||||
|
|
||||||
|
This allows the sample Android project to very easily make use of versioned third party libraries like
|
||||||
|
[ActionBarSherlock](http://actionbarsherlock.com/), or [StickyListHeaders](https://github.com/emilsjolander/StickyListHeaders).
|
||||||
|
During the build process, gradle will automatically retrieve the libraries from the configured
|
||||||
|
maven repositories and incorporate them into the build. This makes it easy to manage dependencies
|
||||||
|
without having to check jars into a project's source tree.
|
||||||
|
|
||||||
|
## Dependency Problems
|
||||||
|
|
||||||
|
A "published" maven/gradle artifact [looks like this](https://github.com/WhisperSystems/maven/tree/master/gson/releases/org/whispersystems/gson/2.2.4):
|
||||||
|
|
||||||
|
gson-2.2.4.jar
|
||||||
|
gson-2.2.4.jar.md5
|
||||||
|
gson-2.2.4.jar.sha1
|
||||||
|
gson-2.2.4.pom
|
||||||
|
gson-2.2.4.pom.md5
|
||||||
|
gson-2.2.4.pom.sha1
|
||||||
|
|
||||||
|
In the remote directory, the artifact consists of a POM file and a jar or aar, along with md5sum and
|
||||||
|
sha1sum hash values for those files.
|
||||||
|
|
||||||
|
When gradle retrieves the artifact, it will also retrieve the md5sum and sha1sums to verify that
|
||||||
|
they match the calculated md5sum and sha1sum of the retrieved files. The problem, obviously, is
|
||||||
|
that if someone is able to compromise the remote maven repository and change the jar/aar for a
|
||||||
|
dependency to include some malicious functionality, they could just as easily change the md5sum
|
||||||
|
and sha1sum values the repository advertises as well.
|
||||||
|
|
||||||
|
## The Witness Solution
|
||||||
|
|
||||||
|
This gradle plugin simply allows the author of a project to statically specify the sha256sum of
|
||||||
|
the dependencies that it uses. For our dependency example above, `gradle-witness` would allow
|
||||||
|
the project to specify:
|
||||||
|
|
||||||
|
dependency {
|
||||||
|
compile 'com.actionbarsherlock:actionbarsherlock:4.4.0@aar'
|
||||||
|
compile 'com.android.support:support-v4:19.0.1'
|
||||||
|
compile 'com.google.android.gcm:gcm-client:1.0.2'
|
||||||
|
compile 'se.emilsjolander:stickylistheaders:2.2.0'
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencyVerification {
|
||||||
|
verify = [
|
||||||
|
'com.actionbarsherlock:actionbarsherlock:5ab04d74101f70024b222e3ff9c87bee151ec43331b4a2134b6cc08cf8565819',
|
||||||
|
'com.android.support:support-v4:a4268abd6370c3fd3f94d2a7f9e6e755f5ddd62450cf8bbc62ba789e1274d585',
|
||||||
|
'com.google.android.gcm:gcm-client:5ff578202f93dcba1c210d015deb4241c7cdad9b7867bd1b32e0a5f4c16986ca',
|
||||||
|
'se.emilsjolander:stickylistheaders:89146b46c96fea0e40200474a2625cda10fe94891e4128f53cdb42375091b9b6',
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
The `dependency` definition is the same, but `gradle-witness` allows one to also specify a
|
||||||
|
`dependencyVerification` definition as well. That definition should include a single list called
|
||||||
|
`verify` with elements in the format of `group_id:name:sha256sum`.
|
||||||
|
|
||||||
|
At this point, running `gradle build` will first verify that all of the listed dependencies have
|
||||||
|
the specified sha256sums. If there's a mismatch, the build is aborted. If the remote repository
|
||||||
|
is later compromised, an attacker won't be able to undetectably modify these artifacts.
|
||||||
|
|
||||||
|
## Using Witness
|
||||||
|
|
||||||
|
Unfortunately, it doesn't make sense to publish `gradle-witness` as an artifact, since that
|
||||||
|
creates a bootstrapping problem. To use `gradle-witness`, the jar needs to be built and included
|
||||||
|
in your project:
|
||||||
|
|
||||||
|
$ git clone https://github.com/WhisperSystems/gradle-witness.git
|
||||||
|
$ cd gradle-witness
|
||||||
|
$ gradle build
|
||||||
|
$ cp build/libs/gradle-witness.jar /path/to/your/project/libs/gradle-witness.jar
|
||||||
|
|
||||||
|
Then in your project's `build.gradle`, the buildscript needs to add a `gradle-witness` dependency.
|
||||||
|
It might look something like:
|
||||||
|
|
||||||
|
buildscript {
|
||||||
|
repositories {
|
||||||
|
mavenCentral()
|
||||||
|
}
|
||||||
|
dependencies {
|
||||||
|
classpath 'com.android.tools.build:gradle:0.9.+'
|
||||||
|
classpath files('libs/gradle-witness.jar')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
apply plugin: 'witness'
|
||||||
|
|
||||||
|
At this point you can use `gradle-witness` in your project. If you're feeling "trusting on first
|
||||||
|
use," you can have `gradle-witness` calculate the sha256sum for all your project's dependencies
|
||||||
|
(and transitive dependencies!) for you:
|
||||||
|
|
||||||
|
$ gradle -q calculateChecksums
|
||||||
|
|
||||||
|
This will print the full `dependencyVerification` definition to include in the project's `build.gradle`.
|
||||||
|
For a project that has a dependency definition like:
|
||||||
|
|
||||||
|
dependency {
|
||||||
|
compile 'com.actionbarsherlock:actionbarsherlock:4.4.0@aar'
|
||||||
|
compile 'com.android.support:support-v4:19.0.1'
|
||||||
|
compile 'com.google.android.gcm:gcm-client:1.0.2'
|
||||||
|
compile 'se.emilsjolander:stickylistheaders:2.2.0'
|
||||||
|
}
|
||||||
|
|
||||||
|
Running `gradle -q calculateChecksums` will print:
|
||||||
|
|
||||||
|
dependencyVerification {
|
||||||
|
verify = [
|
||||||
|
'com.actionbarsherlock:actionbarsherlock:5ab04d74101f70024b222e3ff9c87bee151ec43331b4a2134b6cc08cf8565819',
|
||||||
|
'com.android.support:support-v4:a4268abd6370c3fd3f94d2a7f9e6e755f5ddd62450cf8bbc62ba789e1274d585',
|
||||||
|
'com.google.android.gcm:gcm-client:5ff578202f93dcba1c210d015deb4241c7cdad9b7867bd1b32e0a5f4c16986ca',
|
||||||
|
'se.emilsjolander:stickylistheaders:89146b46c96fea0e40200474a2625cda10fe94891e4128f53cdb42375091b9b6',
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
...which you can then include directly below the `dependency` definition in the project's `build.gradle`.
|
||||||
|
|
||||||
|
And that's it! From then on, running a standard `gradle build` will verify the integrity of
|
||||||
|
the project's dependencies.
|
10
extern/gradle-witness/build.gradle
vendored
Normal file
10
extern/gradle-witness/build.gradle
vendored
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
apply plugin: 'groovy'
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
compile gradleApi()
|
||||||
|
compile localGroovy()
|
||||||
|
}
|
||||||
|
|
||||||
|
sourceCompatibility = '1.7'
|
||||||
|
targetCompatibility = '1.7'
|
||||||
|
|
64
extern/gradle-witness/src/main/groovy/org/whispersystems/witness/WitnessPlugin.groovy
vendored
Normal file
64
extern/gradle-witness/src/main/groovy/org/whispersystems/witness/WitnessPlugin.groovy
vendored
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
package org.whispersystems.witness
|
||||||
|
|
||||||
|
import org.gradle.api.InvalidUserDataException
|
||||||
|
import org.gradle.api.Plugin
|
||||||
|
import org.gradle.api.Project
|
||||||
|
import org.gradle.api.artifacts.ResolvedArtifact
|
||||||
|
|
||||||
|
import java.security.MessageDigest
|
||||||
|
|
||||||
|
class WitnessPluginExtension {
|
||||||
|
List verify
|
||||||
|
}
|
||||||
|
|
||||||
|
class WitnessPlugin implements Plugin<Project> {
|
||||||
|
|
||||||
|
static String calculateSha256(file) {
|
||||||
|
MessageDigest md = MessageDigest.getInstance("SHA-256");
|
||||||
|
file.eachByte 4096, {bytes, size ->
|
||||||
|
md.update(bytes, 0, size);
|
||||||
|
}
|
||||||
|
return md.digest().collect {String.format "%02x", it}.join();
|
||||||
|
}
|
||||||
|
|
||||||
|
void apply(Project project) {
|
||||||
|
project.extensions.create("dependencyVerification", WitnessPluginExtension)
|
||||||
|
project.afterEvaluate {
|
||||||
|
project.dependencyVerification.verify.each {
|
||||||
|
assertion ->
|
||||||
|
List parts = assertion.tokenize(":")
|
||||||
|
String group = parts.get(0)
|
||||||
|
String name = parts.get(1)
|
||||||
|
String hash = parts.get(2)
|
||||||
|
|
||||||
|
ResolvedArtifact dependency = project.configurations.compile.resolvedConfiguration.resolvedArtifacts.find {
|
||||||
|
return it.name.equals(name) && it.moduleVersion.id.group.equals(group)
|
||||||
|
}
|
||||||
|
|
||||||
|
println "Verifying " + group + ":" + name
|
||||||
|
|
||||||
|
if (dependency == null) {
|
||||||
|
throw new InvalidUserDataException("No dependency for integrity assertion found: " + group + ":" + name)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hash.equals(calculateSha256(dependency.file))) {
|
||||||
|
throw new InvalidUserDataException("Checksum failed for " + assertion)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
project.task('calculateChecksums') << {
|
||||||
|
println "dependencyVerification {"
|
||||||
|
println " verify = ["
|
||||||
|
|
||||||
|
project.configurations.compile.resolvedConfiguration.resolvedArtifacts.each {
|
||||||
|
dep ->
|
||||||
|
println " '" + dep.moduleVersion.id.group+ ":" + dep.name + ":" + calculateSha256(dep.file) + "',"
|
||||||
|
}
|
||||||
|
|
||||||
|
println " ]"
|
||||||
|
println "}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
1
extern/gradle-witness/src/main/resources/META-INF/gradle-plugins/witness.properties
vendored
Normal file
1
extern/gradle-witness/src/main/resources/META-INF/gradle-plugins/witness.properties
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
implementation-class=org.whispersystems.witness.WitnessPlugin
|
BIN
libs/gradle-witness.jar
Normal file
BIN
libs/gradle-witness.jar
Normal file
Binary file not shown.
6
libs/gradle-witness.txt
Normal file
6
libs/gradle-witness.txt
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
gradle-witness.jar was obtained by running `gradle build` inside the directory
|
||||||
|
extern/gradle-witness/ in this repository. The source code for the groovy
|
||||||
|
plugin and its license can be found there.
|
||||||
|
|
||||||
|
We must prebuild a jar for this plugin since gradle plugins can't be used
|
||||||
|
directly from source.
|
Loading…
x
Reference in New Issue
Block a user