Skip to content

Commit 9098125

Browse files
committed
Migrate to an Android library project.
1 parent 5224988 commit 9098125

23 files changed

+1518
-274
lines changed

.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
.idea
2+
*.iml
3+
local.properties
4+
gen
5+
out
6+
*~

AndroidManifest.xml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
3+
package="org.thoughtcrime.ssl.pinning"
4+
android:versionCode="1"
5+
android:versionName="1.0">
6+
7+
<uses-sdk android:minSdkVersion="8" android:targetSdkVersion="16"/>
8+
9+
</manifest>

README.md

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
Android Pinning
2+
=================
3+
4+
libpinning is a standalone Android library project that facilitates certificate pinning for SSL
5+
connections from Android apps, in order to minimize dependence on Certificate Authorities.
6+
7+
CA signatures are necessary for *general purpose* network communication tools: things like web
8+
browsers, which connect to arbitrary network endpoints and have no advance knowledge of what the SSL
9+
certificates for those endpoint should look like.
10+
11+
Most mobile apps are not *general purpose* communication tools. Instead, they typically connect
12+
directly to a narrow set of backend services that the app's author either controls, or can
13+
predict ahead of time.
14+
15+
This creates an opportunity for app developers to sidestep the security problems inherent with
16+
Certificate Authorities. The best way is to throw CA certificates out the window entirely by
17+
signing your own endpoint certificates with your own offline signing certificate, which you then
18+
distribute with your app. See [this blog post](http://thoughtcrime.org/blog/authenticity-is-broken-in-ssl-but-your-app-ha/)
19+
for examples of the no-CA technique.
20+
21+
Sometimes, however, that's not possible, and you need to continue using CA certificates for one
22+
reason or another. Perhaps the API endpoint is shared with a web browser's endpoint, for instance.
23+
24+
In that case, it's necessary to employ "pinning," which is simply the act of verifying that the
25+
certificate chain looks the way you know it should, even if it's signed by a CA. This prevents
26+
*other* CAs from being able to effectively create forged certificates for your domain, as with the
27+
many Comodo breaches, the DigiNotar breach, and the TurkTrust breach.
28+
29+
This library is designed to make pinning easier on Android. It's structured as an Android library
30+
project, so you can simply link it to your own project and begin.
31+
32+
Examples
33+
-----------
34+
35+
Using a simple `HttpsURLConnection` with a `PinningTrustManager`:
36+
37+
``// Define an array of pins. One of these must be present
38+
// in the certificate chain you receive. A pin is a hex-encoded
39+
// hash of a X.509 certificate's SubjectPublicKeyInfo. A pin can
40+
// be generated using the provided pin.py script:
41+
// python ./tools/pin.py certificate_file.pem
42+
String[] pins = new String[] {"f30012bbc18c231ac1a44b788e410ce754182513"};
43+
URL url = new URL("https://www.google.com");
44+
HttpsURLConnection connection = PinningHelper.getPinnedHttpsURLConnection(context, pins, url);
45+
46+
return connection.getInputStream();
47+
``
48+
49+
Using a simple ``HttpClient` with a `PinningTrustManager`:
50+
51+
``String[] pins = new String[] {"f30012bbc18c231ac1a44b788e410ce754182513"};
52+
HttpClient httpClient = PinningHelper.getPinnedHttpClient(context, pins);
53+
54+
HttpResponse response = httpClient.execute(new HttpGet("https://www.google.com/"));
55+
``
56+
57+
It's also possible to work with `PinningTrustManager` and `PinningSSLSocketFactory` more directly:
58+
59+
``String[] pins = new String[] {"40c5401d6f8cbaf08b00edefb1ee87d005b3b9cd"};
60+
SchemeRegistry schemeRegistry = new SchemeRegistry();
61+
schemeRegistry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
62+
schemeRegistry.register(new Scheme("https", new PinningSSLSocketFactory(getContext() ,pins, 0), 443));
63+
64+
HttpParams httpParams = new BasicHttpParams();
65+
ClientConnectionManager connectionManager = new ThreadSafeClientConnManager(httpParams, schemeRegistry);
66+
DefaultHttpClient httpClient = new DefaultHttpClient(connectionManager, httpParams);
67+
68+
HttpResponse response = httpClient.execute(new HttpGet("https://www.google.com/"));
69+
``
70+
71+
Issues
72+
-----------
73+
74+
Have a bug? Please create an issue here on GitHub!
75+
76+
https://github.com/moxie0/AndroidPinning/issues
77+
78+
License
79+
---------------------
80+
81+
Copyright 2011-2013 Moxie Marlinspike
82+
83+
Licensed under the GPLv3: http://www.gnu.org/licenses/gpl-3.0.html
84+
85+
Please contact me if this license doesn't work for you.

ant.properties

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# This file is used to override default values used by the Ant build system.
2+
#
3+
# This file must be checked into Version Control Systems, as it is
4+
# integral to the build system of your project.
5+
6+
# This file is only used by the Ant script.
7+
8+
# You can use this to override default values such as
9+
# 'source.dir' for the location of your java source folder and
10+
# 'out.dir' for the location of your output folder.
11+
12+
# You can also use it define how the release builds are signed by declaring
13+
# the following properties:
14+
# 'key.store' for the location of your keystore and
15+
# 'key.alias' for the name of the key to use.
16+
# The password will be asked during the build when you use the 'release' target.
17+

build.xml

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project name="libpinning" default="help">
3+
4+
<!-- The local.properties file is created and updated by the 'android' tool.
5+
It contains the path to the SDK. It should *NOT* be checked into
6+
Version Control Systems. -->
7+
<property file="local.properties" />
8+
9+
<!-- The ant.properties file can be created by you. It is only edited by the
10+
'android' tool to add properties to it.
11+
This is the place to change some Ant specific build properties.
12+
Here are some properties you may want to change/update:
13+
14+
source.dir
15+
The name of the source directory. Default is 'src'.
16+
out.dir
17+
The name of the output directory. Default is 'bin'.
18+
19+
For other overridable properties, look at the beginning of the rules
20+
files in the SDK, at tools/ant/build.xml
21+
22+
Properties related to the SDK location or the project target should
23+
be updated using the 'android' tool with the 'update' action.
24+
25+
This file is an integral part of the build system for your
26+
application and should be checked into Version Control Systems.
27+
28+
-->
29+
<property file="ant.properties" />
30+
31+
<!-- if sdk.dir was not set from one of the property file, then
32+
get it from the ANDROID_HOME env var.
33+
This must be done before we load project.properties since
34+
the proguard config can use sdk.dir -->
35+
<property environment="env" />
36+
<condition property="sdk.dir" value="${env.ANDROID_HOME}">
37+
<isset property="env.ANDROID_HOME" />
38+
</condition>
39+
40+
<!-- The project.properties file is created and updated by the 'android'
41+
tool, as well as ADT.
42+
43+
This contains project specific properties such as project target, and library
44+
dependencies. Lower level build properties are stored in ant.properties
45+
(or in .classpath for Eclipse projects).
46+
47+
This file is an integral part of the build system for your
48+
application and should be checked into Version Control Systems. -->
49+
<loadproperties srcFile="project.properties" />
50+
51+
<!-- quick check on sdk.dir -->
52+
<fail
53+
message="sdk.dir is missing. Make sure to generate local.properties using 'android update project' or to inject it through the ANDROID_HOME environment variable."
54+
unless="sdk.dir"
55+
/>
56+
57+
<!--
58+
Import per project custom build rules if present at the root of the project.
59+
This is the place to put custom intermediary targets such as:
60+
-pre-build
61+
-pre-compile
62+
-post-compile (This is typically used for code obfuscation.
63+
Compiled code location: ${out.classes.absolute.dir}
64+
If this is not done in place, override ${out.dex.input.absolute.dir})
65+
-post-package
66+
-post-build
67+
-pre-clean
68+
-->
69+
<import file="custom_rules.xml" optional="true" />
70+
71+
<!-- Import the actual build file.
72+
73+
To customize existing targets, there are two options:
74+
- Customize only one target:
75+
- copy/paste the target into this file, *before* the
76+
<import> task.
77+
- customize it to your needs.
78+
- Customize the whole content of build.xml
79+
- copy/paste the content of the rules files (minus the top node)
80+
into this file, replacing the <import> task.
81+
- customize to your needs.
82+
83+
***********************
84+
****** IMPORTANT ******
85+
***********************
86+
In all cases you must update the value of version-tag below to read 'custom' instead of an integer,
87+
in order to avoid having your file be overridden by tools such as "android update project"
88+
-->
89+
<!-- version-tag: 1 -->
90+
<import file="${sdk.dir}/tools/ant/build.xml" />
91+
92+
</project>

0 commit comments

Comments
 (0)