aboutsummaryrefslogtreecommitdiffstats
path: root/libs
diff options
context:
space:
mode:
authorChristian Schneppe <christian@pix-art.de>2018-03-12 20:58:37 +0100
committerChristian Schneppe <christian@pix-art.de>2018-03-12 20:58:37 +0100
commitf5854d238e4c8aecb5370e56301bd43015ad8ba9 (patch)
tree4fb9ac1b5741911a03a2345289945b476c14b245 /libs
parent89927cee8ed577e8b285de26e6b7c424e83735f4 (diff)
integrate trust manager into conversations
Diffstat (limited to 'libs')
-rw-r--r--libs/MemorizingTrustManager/.gitignore11
-rw-r--r--libs/MemorizingTrustManager/AndroidManifest.xml12
-rw-r--r--libs/MemorizingTrustManager/LICENSE.txt21
-rw-r--r--libs/MemorizingTrustManager/README.mdwn125
-rw-r--r--libs/MemorizingTrustManager/ant.properties14
-rw-r--r--libs/MemorizingTrustManager/build.gradle33
-rw-r--r--libs/MemorizingTrustManager/build.xml91
-rw-r--r--libs/MemorizingTrustManager/libs/.android_sucks0
-rw-r--r--libs/MemorizingTrustManager/mtm-notification.pngbin50799 -> 0 bytes
-rw-r--r--libs/MemorizingTrustManager/mtm-screenshot.pngbin58053 -> 0 bytes
-rw-r--r--libs/MemorizingTrustManager/mtm-servername.pngbin56935 -> 0 bytes
-rw-r--r--libs/MemorizingTrustManager/proguard-project.txt20
-rw-r--r--libs/MemorizingTrustManager/project.properties11
-rw-r--r--libs/MemorizingTrustManager/res/values-de/strings.xml17
-rw-r--r--libs/MemorizingTrustManager/res/values-es/strings.xml17
-rw-r--r--libs/MemorizingTrustManager/res/values-eu/strings.xml17
-rw-r--r--libs/MemorizingTrustManager/res/values-fi/strings.xml16
-rw-r--r--libs/MemorizingTrustManager/res/values-fr/strings.xml16
-rw-r--r--libs/MemorizingTrustManager/res/values-no/strings.xml16
-rw-r--r--libs/MemorizingTrustManager/res/values/defaults.xml4
-rw-r--r--libs/MemorizingTrustManager/res/values/strings.xml17
-rw-r--r--libs/MemorizingTrustManager/settings.gradle1
-rw-r--r--libs/MemorizingTrustManager/src/de/duenndns/ssl/DomainHostnameVerifier.java10
-rw-r--r--libs/MemorizingTrustManager/src/de/duenndns/ssl/MTMDecision.java33
-rw-r--r--libs/MemorizingTrustManager/src/de/duenndns/ssl/MemorizingActivity.java115
-rw-r--r--libs/MemorizingTrustManager/src/de/duenndns/ssl/MemorizingTrustManager.java898
26 files changed, 0 insertions, 1515 deletions
diff --git a/libs/MemorizingTrustManager/.gitignore b/libs/MemorizingTrustManager/.gitignore
deleted file mode 100644
index c642de10f..000000000
--- a/libs/MemorizingTrustManager/.gitignore
+++ /dev/null
@@ -1,11 +0,0 @@
-bin
-build
-gen
-local.properties
-example/bin
-example/gen
-tags
-.project
-.classpath
-.gradle
-.*.swp
diff --git a/libs/MemorizingTrustManager/AndroidManifest.xml b/libs/MemorizingTrustManager/AndroidManifest.xml
deleted file mode 100644
index 4d3a2b41c..000000000
--- a/libs/MemorizingTrustManager/AndroidManifest.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="de.duenndns.ssl"
- android:versionCode="1"
- android:versionName="1.0">
-
- <application android:label="MemorizingTrustManager">
- <activity
- android:name="de.duenndns.ssl.MemorizingActivity"
- android:theme="@android:style/Theme.Translucent.NoTitleBar" />
- </application>
-</manifest>
diff --git a/libs/MemorizingTrustManager/LICENSE.txt b/libs/MemorizingTrustManager/LICENSE.txt
deleted file mode 100644
index 25012507a..000000000
--- a/libs/MemorizingTrustManager/LICENSE.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-The MIT license.
-
-Copyright (c) 2010 Georg Lukas <georg@op-co.de>
-
-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.
diff --git a/libs/MemorizingTrustManager/README.mdwn b/libs/MemorizingTrustManager/README.mdwn
deleted file mode 100644
index c48f38de3..000000000
--- a/libs/MemorizingTrustManager/README.mdwn
+++ /dev/null
@@ -1,125 +0,0 @@
-# MemorizingTrustManager - Private Cloud Support for Your App
-
-MemorizingTrustManager (MTM) is a project to enable smarter and more secure use
-of SSL on Android. If it encounters an unknown SSL certificate, it asks the
-user whether to accept the certificate once, permanently or to abort the
-connection. This is a step in preventing man-in-the-middle attacks by blindly
-accepting any invalid, self-signed and/or expired certificates.
-
-MTM is aimed at providing seamless integration into your Android application,
-and the source code is available under the MIT license.
-
-## Screenshots
-
-![MemorizingTrustManager dialog](mtm-screenshot.png)
-![MemorizingTrustManager notification](mtm-notification.png)
-![MemorizingTrustManager server name dialog](mtm-servername.png)
-
-## Status
-
-MemorizingTrustManager is in production use in the
-[yaxim XMPP client](https://yaxim.org/). It is usable and easy to integrate,
-though it does not yet support hostname validation (the Java API makes it
-**hard** to integrate).
-
-## Integration
-
-MTM is easy to integrate into your own application. Follow these steps or have
-a look into the demo application in the `example` directory.
-
-### 1. Add MTM to your project
-
-Download the MTM source from GitHub, or add it as a
-[git submodule](http://git-scm.com/docs/git-submodule):
-
- # plain download:
- git clone https://github.com/ge0rg/MemorizingTrustManager
- # submodule:
- git submodule add https://github.com/ge0rg/MemorizingTrustManager
-
-Then add a library project dependency to `default.properties`:
-
- android.library.reference.1=MemorizingTrustManager
-
-### 2. Add the MTM (popup) Activity to your manifest
-
-Edit your `AndroidManifest.xml` and add the MTM activity element right before the
-end of your closing `</application>` tag.
-
- ...
- <activity android:name="de.duenndns.ssl.MemorizingActivity"
- android:theme="@android:style/Theme.Translucent.NoTitleBar"
- />
- </application>
- </manifest>
-
-### 3. Hook MTM as the default TrustManager for your connection type
-
-Hooking MemorizingTrustmanager in HTTPS connections:
-
- // register MemorizingTrustManager for HTTPS
- SSLContext sc = SSLContext.getInstance("TLS");
- MemorizingTrustManager mtm = new MemorizingTrustManager(this);
- sc.init(null, new X509TrustManager[] { mtm }, new java.security.SecureRandom());
- HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
- HttpsURLConnection.setDefaultHostnameVerifier(
- mtm.wrapHostnameVerifier(HttpsURLConnection.getDefaultHostnameVerifier()));
-
-
-Or, for aSmack you can use `setCustomSSLContext()`:
-
- org.jivesoftware.smack.ConnectionConfiguration connectionConfiguration = …
- SSLContext sc = SSLContext.getInstance("TLS");
- MemorizingTrustManager mtm = new MemorizingTrustManager(this);
- sc.init(null, new X509TrustManager[] { mtm }, new java.security.SecureRandom());
- connectionConfiguration.setCustomSSLContext(sc);
- connectionConfiguration.setHostnameVerifier(
- mtm.wrapHostnameVerifier(new org.apache.http.conn.ssl.StrictHostnameVerifier()));
-
-By default, MTM falls back to the system `TrustManager` before asking the user.
-If you do not trust the establishment, you can enforce a dialog on *every new
-connection* by supplying a `defaultTrustManager = null` parameter to the
-constructor:
-
- MemorizingTrustManager mtm = new MemorizingTrustManager(this, null);
-
-If you want to use a different underlying `TrustManager`, like
-[AndroidPinning](https://github.com/moxie0/AndroidPinning), just supply that to
-MTM's constructor:
-
- X509TrustManager pinning = new PinningTrustManager(SystemKeyStore.getInstance(),
- new String[] {"f30012bbc18c231ac1a44b788e410ce754182513"}, 0);
- MemorizingTrustManager mtm = new MemorizingTrustManager(this, pinning);
-
-### 4. Profit!
-
-### Logging
-
-MTM uses java.util.logging (JUL) for logging purposes. If you have not
-configured a Handler for JUL, then Android will by default log all
-messages of Level.INFO or higher. In order to get also the debug log
-messages (those with Level.FINE or lower) you need to configure a
-Handler accordingly. The MTM example project contains
-de.duenndns.mtmexample.JULHandler, which allows to enable and disable
-debug logging at runtime.
-
-## Alternatives
-
-MemorizingTrustManager is not the only one out there.
-
-[**NetCipher**](https://guardianproject.info/code/netcipher/) is an Android
-library made by the [Guardian Project](https://guardianproject.info/) to
-improve network security for mobile apps. It comes with a StrongTrustManager
-to do more thorough certificate checks, an independent Root CA store, and code
-to easily route your traffic through
-[the Tor network](https://www.torproject.org/) using [Orbot](https://guardianproject.info/apps/orbot/).
-
-[**AndroidPinning**](https://github.com/moxie0/AndroidPinning) is another Android
-library, written by [Moxie Marlinspike](http://www.thoughtcrime.org/) to allow
-pinning of server certificates, improving security against government-scale
-MitM attacks. Use this if your app is made to communicate with a specific
-server!
-
-## Contribute
-
-Please [help translating MTM into more languages](https://translations.launchpad.net/yaxim/master/+pots/mtm/)!
diff --git a/libs/MemorizingTrustManager/ant.properties b/libs/MemorizingTrustManager/ant.properties
deleted file mode 100644
index 21ef4e321..000000000
--- a/libs/MemorizingTrustManager/ant.properties
+++ /dev/null
@@ -1,14 +0,0 @@
-# This file is used to override default values used by the Ant build system.
-#
-# This file must be checked in Version Control Systems, as it is
-# integral to the build system of your project.
-# This file is only used by the Ant script.
-# You can use this to override default values such as
-# 'source.dir' for the location of your java source folder and
-# 'out.dir' for the location of your output folder.
-# You can also use it define how the release builds are signed by declaring
-# the following properties:
-# 'key.store' for the location of your keystore and
-# 'key.alias' for the name of the key to use.
-# The password will be asked during the build when you use the 'release' target.
-
diff --git a/libs/MemorizingTrustManager/build.gradle b/libs/MemorizingTrustManager/build.gradle
deleted file mode 100644
index c45f09435..000000000
--- a/libs/MemorizingTrustManager/build.gradle
+++ /dev/null
@@ -1,33 +0,0 @@
-buildscript {
- repositories {
- mavenCentral()
- jcenter()
- }
- dependencies {
- classpath 'com.android.tools.build:gradle:3.0.1'
- }
-}
-
-apply plugin: 'com.android.library'
-
-android {
- compileSdkVersion 27
- buildToolsVersion "27.0.3"
- defaultConfig {
- minSdkVersion 14
- targetSdkVersion 26
- }
-
- sourceSets {
- main {
- manifest.srcFile 'AndroidManifest.xml'
- java.srcDirs = ['src']
- resources.srcDirs = ['src']
- aidl.srcDirs = ['src']
- renderscript.srcDirs = ['src']
- res.srcDirs = ['res']
- assets.srcDirs = ['assets']
- }
- }
-
-}
diff --git a/libs/MemorizingTrustManager/build.xml b/libs/MemorizingTrustManager/build.xml
deleted file mode 100644
index 15b0b0104..000000000
--- a/libs/MemorizingTrustManager/build.xml
+++ /dev/null
@@ -1,91 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project name="MemorizingTrustManager" default="help">
-
- <!-- The local.properties file is created and updated by the 'android' tool.
- It contains the path to the SDK. It should *NOT* be checked into
- Version Control Systems. -->
- <property file="local.properties" />
-
- <!-- The ant.properties file can be created by you. It is only edited by the
- 'android' tool to add properties to it.
- This is the place to change some Ant specific build properties.
- Here are some properties you may want to change/update:
-
- source.dir
- The name of the source directory. Default is 'src'.
- out.dir
- The name of the output directory. Default is 'bin'.
-
- For other overridable properties, look at the beginning of the rules
- files in the SDK, at tools/ant/build.xml
-
- Properties related to the SDK location or the project target should
- be updated using the 'android' tool with the 'update' action.
-
- This file is an integral part of the build system for your
- application and should be checked into Version Control Systems.
-
- -->
- <property file="ant.properties" />
-
- <!-- if sdk.dir was not set from one of the property file, then
- get it from the ANDROID_HOME env var.
- This must be done before we load project.properties since
- the proguard config can use sdk.dir -->
- <property environment="env" />
- <condition property="sdk.dir" value="${env.ANDROID_HOME}">
- <isset property="env.ANDROID_HOME" />
- </condition>
-
- <!-- The project.properties file is created and updated by the 'android'
- tool, as well as ADT.
-
- This contains project specific properties such as project target, and library
- dependencies. Lower level build properties are stored in ant.properties
- (or in .classpath for Eclipse projects).
-
- This file is an integral part of the build system for your
- application and should be checked into Version Control Systems. -->
- <loadproperties srcFile="project.properties" />
-
- <!-- quick check on sdk.dir -->
- <fail
- 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."
- unless="sdk.dir" />
-
- <!--
- Import per project custom build rules if present at the root of the project.
- This is the place to put custom intermediary targets such as:
- -pre-build
- -pre-compile
- -post-compile (This is typically used for code obfuscation.
- Compiled code location: ${out.classes.absolute.dir}
- If this is not done in place, override ${out.dex.input.absolute.dir})
- -post-package
- -post-build
- -pre-clean
- -->
- <import file="custom_rules.xml" optional="true" />
-
- <!-- Import the actual build file.
-
- To customize existing targets, there are two options:
- - Customize only one target:
- - copy/paste the target into this file, *before* the
- <import> task.
- - customize it to your needs.
- - Customize the whole content of build.xml
- - copy/paste the content of the rules files (minus the top node)
- into this file, replacing the <import> task.
- - customize to your needs.
-
- ***********************
- ****** IMPORTANT ******
- ***********************
- In all cases you must update the value of version-tag below to read 'custom' instead of an integer,
- in order to avoid having your file be overridden by tools such as "android update project"
- -->
- <!-- version-tag: 1 -->
- <import file="${sdk.dir}/tools/ant/build.xml" />
-
-</project>
diff --git a/libs/MemorizingTrustManager/libs/.android_sucks b/libs/MemorizingTrustManager/libs/.android_sucks
deleted file mode 100644
index e69de29bb..000000000
--- a/libs/MemorizingTrustManager/libs/.android_sucks
+++ /dev/null
diff --git a/libs/MemorizingTrustManager/mtm-notification.png b/libs/MemorizingTrustManager/mtm-notification.png
deleted file mode 100644
index 20ff61488..000000000
--- a/libs/MemorizingTrustManager/mtm-notification.png
+++ /dev/null
Binary files differ
diff --git a/libs/MemorizingTrustManager/mtm-screenshot.png b/libs/MemorizingTrustManager/mtm-screenshot.png
deleted file mode 100644
index 96db9e4ee..000000000
--- a/libs/MemorizingTrustManager/mtm-screenshot.png
+++ /dev/null
Binary files differ
diff --git a/libs/MemorizingTrustManager/mtm-servername.png b/libs/MemorizingTrustManager/mtm-servername.png
deleted file mode 100644
index 2d76c4e4e..000000000
--- a/libs/MemorizingTrustManager/mtm-servername.png
+++ /dev/null
Binary files differ
diff --git a/libs/MemorizingTrustManager/proguard-project.txt b/libs/MemorizingTrustManager/proguard-project.txt
deleted file mode 100644
index f2fe1559a..000000000
--- a/libs/MemorizingTrustManager/proguard-project.txt
+++ /dev/null
@@ -1,20 +0,0 @@
-# To enable ProGuard in your project, edit project.properties
-# to define the proguard.config property as described in that file.
-#
-# Add project specific ProGuard rules here.
-# By default, the flags in this file are appended to flags specified
-# in ${sdk.dir}/tools/proguard/proguard-android.txt
-# You can edit the include path and order by changing the ProGuard
-# include property in project.properties.
-#
-# 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/libs/MemorizingTrustManager/project.properties b/libs/MemorizingTrustManager/project.properties
deleted file mode 100644
index 7c444cd57..000000000
--- a/libs/MemorizingTrustManager/project.properties
+++ /dev/null
@@ -1,11 +0,0 @@
-# This file is automatically generated by Android Tools.
-# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
-#
-# This file must be checked in Version Control Systems.
-#
-# To customize properties used by the Ant build system use,
-# "ant.properties", and override values to adapt the script to your
-# project structure.
-android.library=true
-# Project target.
-target=android-19
diff --git a/libs/MemorizingTrustManager/res/values-de/strings.xml b/libs/MemorizingTrustManager/res/values-de/strings.xml
deleted file mode 100644
index 17682209f..000000000
--- a/libs/MemorizingTrustManager/res/values-de/strings.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
- <string name="mtm_accept_cert">Unbekanntes Zertifikat akzeptieren?</string>
- <string name="mtm_trust_anchor">Das Serverzertifikat stammt nicht von einer bekannten Ausstellungsstelle (CA).</string>
- <string name="mtm_cert_expired">The server certificate is expired.</string>
- <string name="mtm_accept_servername">Abweichenden Servernamen akzeptieren?</string>
- <string name="mtm_hostname_mismatch">Der Server konnte sich nicht als \"%s\" ausweisen. Das Zertifikat gilt nur für:</string>
-
- <string name="mtm_connect_anyway">Verbindung trotzdem aufbauen?</string>
- <string name="mtm_cert_details">Zertifikat-Details:</string>
-
- <string name="mtm_decision_always">Immer</string>
- <string name="mtm_decision_once">Einmal</string>
- <string name="mtm_decision_abort">Abbrechen</string>
-
- <string name="mtm_notification">Zertifikatsprüfung</string>
-</resources>
diff --git a/libs/MemorizingTrustManager/res/values-es/strings.xml b/libs/MemorizingTrustManager/res/values-es/strings.xml
deleted file mode 100644
index c989db3c4..000000000
--- a/libs/MemorizingTrustManager/res/values-es/strings.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
- <string name="mtm_accept_cert">¿Aceptar certicado desconocido?</string>
- <string name="mtm_trust_anchor">El certificado del servidor no está firmado por una Autoridad Conocida (CA).</string>
- <string name="mtm_cert_expired">The server certificate is expired.</string>
- <string name="mtm_accept_servername">¿Aceptar discordancia en nombre del servidor?</string>
- <string name="mtm_hostname_mismatch">El servidor no ha podido autenticarte como \"%s\". El certificado es solo válido para:</string>
-
- <string name="mtm_connect_anyway">¿Quieres conectar de todas formas?</string>
- <string name="mtm_cert_details">Detalle del certificado:</string>
-
- <string name="mtm_decision_always">Siempre</string>
- <string name="mtm_decision_once">Una vez</string>
- <string name="mtm_decision_abort">Abortar</string>
-
- <string name="mtm_notification">Verificación de Certificado</string>
-</resources>
diff --git a/libs/MemorizingTrustManager/res/values-eu/strings.xml b/libs/MemorizingTrustManager/res/values-eu/strings.xml
deleted file mode 100644
index 97e7c32af..000000000
--- a/libs/MemorizingTrustManager/res/values-eu/strings.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
- <string name="mtm_accept_cert">Ziurtagiri ezezaguna onartu?</string>
- <string name="mtm_trust_anchor">Zerbitzariaren ziurtagiria ez dago Ziurtagiri-emaile Autoritate ezagun batez sinatuta.</string>
- <string name="mtm_cert_expired">Zerbitzariaren ziurtagiria iraungi da.</string>
- <string name="mtm_accept_servername">Zerbitzariaren izeneko desadostasuna onartu?</string>
- <string name="mtm_hostname_mismatch">Zerbitzaria ezin izan da \&quot;%s\&quot; bezala autentifikatu. Ziurtagiria soilik honetarako baliagarria da:</string>
-
- <string name="mtm_connect_anyway">Konektatu hala ere?</string>
- <string name="mtm_cert_details">Ziurtagiriaren xehetasunak:</string>
-
- <string name="mtm_decision_always">Beti</string>
- <string name="mtm_decision_once">Behin</string>
- <string name="mtm_decision_abort">Utzi</string>
-
- <string name="mtm_notification">Ziurtagiriaren egiaztapena</string>
-</resources>
diff --git a/libs/MemorizingTrustManager/res/values-fi/strings.xml b/libs/MemorizingTrustManager/res/values-fi/strings.xml
deleted file mode 100644
index 2dfe31ac9..000000000
--- a/libs/MemorizingTrustManager/res/values-fi/strings.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
- <string name="mtm_accept_cert">Hyväksytäänkö palvelimen antama tuntematon varmenne?</string>
- <string name="mtm_trust_anchor">Palvelimen varmenne ei ole tunnetun varmentajan (CA) allekirjoittama.</string>
- <string name="mtm_accept_servername">Sallitaanko palvelimen nimi, joka ei vastaa varmeenteessa olevaa nimeä?</string>
- <string name="mtm_hostname_mismatch">Palvelimella ei ole varmennetta nimelle \"%s\". Varmenteen sisältämät nimet:</string>
-
- <string name="mtm_connect_anyway">Haluatko jatkaa yhteyden muodostamista?</string>
- <string name="mtm_cert_details">Sertifikaatin tiedot:</string>
-
- <string name="mtm_decision_always">Aina</string>
- <string name="mtm_decision_once">Kerran</string>
- <string name="mtm_decision_abort">Keskeytä</string>
-
- <string name="mtm_notification">Varmenteen tarkistus</string>
-</resources>
diff --git a/libs/MemorizingTrustManager/res/values-fr/strings.xml b/libs/MemorizingTrustManager/res/values-fr/strings.xml
deleted file mode 100644
index db27c9afe..000000000
--- a/libs/MemorizingTrustManager/res/values-fr/strings.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
- <string name="mtm_accept_cert">Accept Unknown Certificate?</string>
- <string name="mtm_trust_anchor">Le certificat du serveur n’est pas signé par une Autorité de Certification reconnue.</string>
- <string name="mtm_accept_servername">Accept Mismatching Server Name?</string>
- <string name="mtm_hostname_mismatch">Server could not authenticate as \"%s\". The certificate is only valid for:</string>
-
- <string name="mtm_connect_anyway">Do you want to connect anyway?</string>
- <string name="mtm_cert_details">Détails du certificat :</string>
-
- <string name="mtm_decision_always">Toujours</string>
- <string name="mtm_decision_once">Une seule fois</string>
- <string name="mtm_decision_abort">Annuler</string>
-
- <string name="mtm_notification">Certificate Verification</string>
-</resources>
diff --git a/libs/MemorizingTrustManager/res/values-no/strings.xml b/libs/MemorizingTrustManager/res/values-no/strings.xml
deleted file mode 100644
index 8cf9614b6..000000000
--- a/libs/MemorizingTrustManager/res/values-no/strings.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
- <string name="mtm_accept_cert">Godta ukjent sertifikat?</string>
- <string name="mtm_trust_anchor">Sertifikatet er ikke utstilt av en kjent utstiller (CA).</string>
- <string name="mtm_accept_servername">Godta feil servernavn?</string>
- <string name="mtm_hostname_mismatch">Serveren heter ikke \"%s\". Sertifikatet gjelder bare for: </string>
-
- <string name="mtm_connect_anyway">Vil du bruke serveren likevel?</string>
- <string name="mtm_cert_details">Sertifikatdetaljer:</string>
-
- <string name="mtm_decision_always">Alltid</string>
- <string name="mtm_decision_once">En gang</string>
- <string name="mtm_decision_abort">Avbryt</string>
-
- <string name="mtm_notification">Sertifikat-sjekk</string>
-</resources>
diff --git a/libs/MemorizingTrustManager/res/values/defaults.xml b/libs/MemorizingTrustManager/res/values/defaults.xml
deleted file mode 100644
index 6fea62719..000000000
--- a/libs/MemorizingTrustManager/res/values/defaults.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
- <string name="theme">light</string>
-</resources>
diff --git a/libs/MemorizingTrustManager/res/values/strings.xml b/libs/MemorizingTrustManager/res/values/strings.xml
deleted file mode 100644
index c38628895..000000000
--- a/libs/MemorizingTrustManager/res/values/strings.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
- <string name="mtm_accept_cert">Accept Unknown Certificate?</string>
- <string name="mtm_trust_anchor">The server certificate is not signed by a known Certificate Authority.</string>
- <string name="mtm_cert_expired">The server certificate is expired.</string>
- <string name="mtm_accept_servername">Accept Mismatching Server Name?</string>
- <string name="mtm_hostname_mismatch">Server could not authenticate as \&quot;%s\&quot;. The certificate is only valid for:</string>
-
- <string name="mtm_connect_anyway">Do you want to connect anyway?</string>
- <string name="mtm_cert_details">Certificate details:</string>
-
- <string name="mtm_decision_always">Always</string>
- <string name="mtm_decision_once">Once</string>
- <string name="mtm_decision_abort">Abort</string>
-
- <string name="mtm_notification">Certificate Verification</string>
-</resources>
diff --git a/libs/MemorizingTrustManager/settings.gradle b/libs/MemorizingTrustManager/settings.gradle
deleted file mode 100644
index ff1d046b1..000000000
--- a/libs/MemorizingTrustManager/settings.gradle
+++ /dev/null
@@ -1 +0,0 @@
-include ':example'
diff --git a/libs/MemorizingTrustManager/src/de/duenndns/ssl/DomainHostnameVerifier.java b/libs/MemorizingTrustManager/src/de/duenndns/ssl/DomainHostnameVerifier.java
deleted file mode 100644
index 62b625ab9..000000000
--- a/libs/MemorizingTrustManager/src/de/duenndns/ssl/DomainHostnameVerifier.java
+++ /dev/null
@@ -1,10 +0,0 @@
-package de.duenndns.ssl;
-
-import javax.net.ssl.HostnameVerifier;
-import javax.net.ssl.SSLSession;
-
-public interface DomainHostnameVerifier extends HostnameVerifier {
-
- boolean verify(String domain, String hostname, SSLSession sslSession);
-
-}
diff --git a/libs/MemorizingTrustManager/src/de/duenndns/ssl/MTMDecision.java b/libs/MemorizingTrustManager/src/de/duenndns/ssl/MTMDecision.java
deleted file mode 100644
index 2b84c3ee5..000000000
--- a/libs/MemorizingTrustManager/src/de/duenndns/ssl/MTMDecision.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/* MemorizingTrustManager - a TrustManager which asks the user about invalid
- * certificates and memorizes their decision.
- *
- * Copyright (c) 2010 Georg Lukas <georg@op-co.de>
- *
- * 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.
- */
-package de.duenndns.ssl;
-
-class MTMDecision {
- public final static int DECISION_INVALID = 0;
- public final static int DECISION_ABORT = 1;
- public final static int DECISION_ONCE = 2;
- public final static int DECISION_ALWAYS = 3;
-
- int state = DECISION_INVALID;
-}
diff --git a/libs/MemorizingTrustManager/src/de/duenndns/ssl/MemorizingActivity.java b/libs/MemorizingTrustManager/src/de/duenndns/ssl/MemorizingActivity.java
deleted file mode 100644
index 29b192093..000000000
--- a/libs/MemorizingTrustManager/src/de/duenndns/ssl/MemorizingActivity.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/* MemorizingTrustManager - a TrustManager which asks the user about invalid
- * certificates and memorizes their decision.
- *
- * Copyright (c) 2010 Georg Lukas <georg@op-co.de>
- *
- * 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.
- */
-package de.duenndns.ssl;
-
-
-import android.app.Activity;
-import android.app.AlertDialog;
-import android.content.DialogInterface;
-import android.content.DialogInterface.OnCancelListener;
-import android.content.DialogInterface.OnClickListener;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.os.Bundle;
-import android.preference.PreferenceManager;
-
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-public class MemorizingActivity extends Activity
- implements OnClickListener, OnCancelListener {
-
- public static final String THEME = "theme";
- private final static Logger LOGGER = Logger.getLogger(MemorizingActivity.class.getName());
- int decisionId;
-
- AlertDialog dialog;
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- LOGGER.log(Level.FINE, "onCreate");
-// setTheme(findTheme());
- super.onCreate(savedInstanceState);
- }
-
- @Override
- public void onResume() {
- super.onResume();
- Intent i = getIntent();
- decisionId = i.getIntExtra(MemorizingTrustManager.DECISION_INTENT_ID, MTMDecision.DECISION_INVALID);
- int titleId = i.getIntExtra(MemorizingTrustManager.DECISION_TITLE_ID, R.string.mtm_accept_cert);
- String cert = i.getStringExtra(MemorizingTrustManager.DECISION_INTENT_CERT);
- LOGGER.log(Level.FINE, "onResume with " + i.getExtras() + " decId=" + decisionId + " data: " + i.getData());
- dialog = new AlertDialog.Builder(this).setTitle(titleId)
- .setMessage(cert)
- .setPositiveButton(R.string.mtm_decision_always, this)
- .setNeutralButton(R.string.mtm_decision_once, this)
- .setNegativeButton(R.string.mtm_decision_abort, this)
- .setOnCancelListener(this)
- .create();
- dialog.show();
- }
-
- @Override
- protected void onPause() {
- if (dialog.isShowing())
- dialog.dismiss();
- super.onPause();
- }
-
- void sendDecision(int decision) {
- LOGGER.log(Level.FINE, "Sending decision: " + decision);
- MemorizingTrustManager.interactResult(decisionId, decision);
- finish();
- }
-
-// protected int findTheme() {
-// return getPreferences().getString(THEME, getResources().getString(R.string.theme)).equals("dark") ? R.style.ConversationsTheme_Dark : R.style.ConversationsTheme;
-// }
-
- protected SharedPreferences getPreferences() {
- return PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
- }
-
- // react on AlertDialog button press
- public void onClick(DialogInterface dialog, int btnId) {
- int decision;
- dialog.dismiss();
- switch (btnId) {
- case DialogInterface.BUTTON_POSITIVE:
- decision = MTMDecision.DECISION_ALWAYS;
- break;
- case DialogInterface.BUTTON_NEUTRAL:
- decision = MTMDecision.DECISION_ONCE;
- break;
- default:
- decision = MTMDecision.DECISION_ABORT;
- }
- sendDecision(decision);
- }
-
- public void onCancel(DialogInterface dialog) {
- sendDecision(MTMDecision.DECISION_ABORT);
- }
-}
diff --git a/libs/MemorizingTrustManager/src/de/duenndns/ssl/MemorizingTrustManager.java b/libs/MemorizingTrustManager/src/de/duenndns/ssl/MemorizingTrustManager.java
deleted file mode 100644
index a3aa561ef..000000000
--- a/libs/MemorizingTrustManager/src/de/duenndns/ssl/MemorizingTrustManager.java
+++ /dev/null
@@ -1,898 +0,0 @@
-/* MemorizingTrustManager - a TrustManager which asks the user about invalid
- * certificates and memorizes their decision.
- *
- * Copyright (c) 2010 Georg Lukas <georg@op-co.de>
- *
- * MemorizingTrustManager.java contains the actual trust manager and interface
- * code to create a MemorizingActivity and obtain the results.
- *
- * 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.
- */
-package de.duenndns.ssl;
-
-import android.app.Activity;
-import android.app.Application;
-import android.app.NotificationManager;
-import android.app.Service;
-import android.content.Context;
-import android.content.Intent;
-import android.net.Uri;
-import android.os.Handler;
-import android.preference.PreferenceManager;
-import android.util.Base64;
-import android.util.Log;
-import android.util.SparseArray;
-
-import org.json.JSONArray;
-import org.json.JSONException;
-import org.json.JSONObject;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.net.URL;
-import java.security.KeyStore;
-import java.security.KeyStoreException;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.security.cert.Certificate;
-import java.security.cert.CertificateEncodingException;
-import java.security.cert.CertificateException;
-import java.security.cert.CertificateExpiredException;
-import java.security.cert.CertificateParsingException;
-import java.security.cert.X509Certificate;
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Enumeration;
-import java.util.List;
-import java.util.Locale;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-import java.util.regex.Pattern;
-
-import javax.net.ssl.HostnameVerifier;
-import javax.net.ssl.HttpsURLConnection;
-import javax.net.ssl.SSLSession;
-import javax.net.ssl.TrustManager;
-import javax.net.ssl.TrustManagerFactory;
-import javax.net.ssl.X509TrustManager;
-
-/**
- * A X509 trust manager implementation which asks the user about invalid
- * certificates and memorizes their decision.
- * <p>
- * The certificate validity is checked using the system default X509
- * TrustManager, creating a query Dialog if the check fails.
- * <p>
- * <b>WARNING:</b> This only works if a dedicated thread is used for
- * opening sockets!
- */
-public class MemorizingTrustManager {
-
-
- private static final Pattern PATTERN_IPV4 = Pattern.compile("\\A(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)(\\.(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)){3}\\z");
- private static final Pattern PATTERN_IPV6_HEX4DECCOMPRESSED = Pattern.compile("\\A((?:[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4})*)?) ::((?:[0-9A-Fa-f]{1,4}:)*)(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)(\\.(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)){3}\\z");
- private static final Pattern PATTERN_IPV6_6HEX4DEC = Pattern.compile("\\A((?:[0-9A-Fa-f]{1,4}:){6,6})(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)(\\.(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)){3}\\z");
- private static final Pattern PATTERN_IPV6_HEXCOMPRESSED = Pattern.compile("\\A((?:[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4})*)?)::((?:[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4})*)?)\\z");
- private static final Pattern PATTERN_IPV6 = Pattern.compile("\\A(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}\\z");
-
- final static String DECISION_INTENT = "de.duenndns.ssl.DECISION";
- final static String DECISION_INTENT_ID = DECISION_INTENT + ".decisionId";
- final static String DECISION_INTENT_CERT = DECISION_INTENT + ".cert";
- final static String DECISION_INTENT_CHOICE = DECISION_INTENT + ".decisionChoice";
-
- private final static Logger LOGGER = Logger.getLogger(MemorizingTrustManager.class.getName());
- final static String DECISION_TITLE_ID = DECISION_INTENT + ".titleId";
- private final static int NOTIFICATION_ID = 100509;
-
- final static String NO_TRUST_ANCHOR = "Trust anchor for certification path not found.";
-
- static String KEYSTORE_DIR = "KeyStore";
- static String KEYSTORE_FILE = "KeyStore.bks";
-
- Context master;
- Activity foregroundAct;
- NotificationManager notificationManager;
- private static int decisionId = 0;
- private static SparseArray<MTMDecision> openDecisions = new SparseArray<MTMDecision>();
-
- Handler masterHandler;
- private File keyStoreFile;
- private KeyStore appKeyStore;
- private X509TrustManager defaultTrustManager;
- private X509TrustManager appTrustManager;
- private String poshCacheDir;
-
- /**
- * Creates an instance of the MemorizingTrustManager class that falls back to a custom TrustManager.
- * <p>
- * You need to supply the application context. This has to be one of:
- * - Application
- * - Activity
- * - Service
- * <p>
- * The context is used for file management, to display the dialog /
- * notification and for obtaining translated strings.
- *
- * @param m Context for the application.
- * @param defaultTrustManager Delegate trust management to this TM. If null, the user must accept every certificate.
- */
- public MemorizingTrustManager(Context m, X509TrustManager defaultTrustManager) {
- init(m);
- this.appTrustManager = getTrustManager(appKeyStore);
- this.defaultTrustManager = defaultTrustManager;
- }
-
- /**
- * Creates an instance of the MemorizingTrustManager class using the system X509TrustManager.
- * <p>
- * You need to supply the application context. This has to be one of:
- * - Application
- * - Activity
- * - Service
- * <p>
- * The context is used for file management, to display the dialog /
- * notification and for obtaining translated strings.
- *
- * @param m Context for the application.
- */
- public MemorizingTrustManager(Context m) {
- init(m);
- this.appTrustManager = getTrustManager(appKeyStore);
- this.defaultTrustManager = getTrustManager(null);
- }
-
- void init(Context m) {
- master = m;
- masterHandler = new Handler(m.getMainLooper());
- notificationManager = (NotificationManager) master.getSystemService(Context.NOTIFICATION_SERVICE);
-
- Application app;
- if (m instanceof Application) {
- app = (Application) m;
- } else if (m instanceof Service) {
- app = ((Service) m).getApplication();
- } else if (m instanceof Activity) {
- app = ((Activity) m).getApplication();
- } else
- throw new ClassCastException("MemorizingTrustManager context must be either Activity or Service!");
-
- File dir = app.getDir(KEYSTORE_DIR, Context.MODE_PRIVATE);
- keyStoreFile = new File(dir + File.separator + KEYSTORE_FILE);
-
- poshCacheDir = app.getFilesDir().getAbsolutePath() + "/posh_cache/";
-
- appKeyStore = loadAppKeyStore();
- }
-
-
- /**
- * Binds an Activity to the MTM for displaying the query dialog.
- * <p>
- * This is useful if your connection is run from a service that is
- * triggered by user interaction -- in such cases the activity is
- * visible and the user tends to ignore the service notification.
- * <p>
- * You should never have a hidden activity bound to MTM! Use this
- * function in onResume() and @see unbindDisplayActivity in onPause().
- *
- * @param act Activity to be bound
- */
- public void bindDisplayActivity(Activity act) {
- foregroundAct = act;
- }
-
- /**
- * Removes an Activity from the MTM display stack.
- * <p>
- * Always call this function when the Activity added with
- * {@link #bindDisplayActivity(Activity)} is hidden.
- *
- * @param act Activity to be unbound
- */
- public void unbindDisplayActivity(Activity act) {
- // do not remove if it was overridden by a different activity
- if (foregroundAct == act)
- foregroundAct = null;
- }
-
- /**
- * Changes the path for the KeyStore file.
- * <p>
- * The actual filename relative to the app's directory will be
- * <code>app_<i>dirname</i>/<i>filename</i></code>.
- *
- * @param dirname directory to store the KeyStore.
- * @param filename file name for the KeyStore.
- */
- public static void setKeyStoreFile(String dirname, String filename) {
- KEYSTORE_DIR = dirname;
- KEYSTORE_FILE = filename;
- }
-
- /**
- * Get a list of all certificate aliases stored in MTM.
- *
- * @return an {@link Enumeration} of all certificates
- */
- public Enumeration<String> getCertificates() {
- try {
- return appKeyStore.aliases();
- } catch (KeyStoreException e) {
- // this should never happen, however...
- throw new RuntimeException(e);
- }
- }
-
- /**
- * Get a certificate for a given alias.
- *
- * @param alias the certificate's alias as returned by {@link #getCertificates()}.
- * @return the certificate associated with the alias or <tt>null</tt> if none found.
- */
- public Certificate getCertificate(String alias) {
- try {
- return appKeyStore.getCertificate(alias);
- } catch (KeyStoreException e) {
- // this should never happen, however...
- throw new RuntimeException(e);
- }
- }
-
- /**
- * Removes the given certificate from MTMs key store.
- * <p>
- * <p>
- * <b>WARNING</b>: this does not immediately invalidate the certificate. It is
- * well possible that (a) data is transmitted over still existing connections or
- * (b) new connections are created using TLS renegotiation, without a new cert
- * check.
- * </p>
- *
- * @param alias the certificate's alias as returned by {@link #getCertificates()}.
- * @throws KeyStoreException if the certificate could not be deleted.
- */
- public void deleteCertificate(String alias) throws KeyStoreException {
- appKeyStore.deleteEntry(alias);
- keyStoreUpdated();
- }
-
- /**
- * Creates a new hostname verifier supporting user interaction.
- * <p>
- * <p>This method creates a new {@link HostnameVerifier} that is bound to
- * the given instance of {@link MemorizingTrustManager}, and leverages an
- * existing {@link HostnameVerifier}. The returned verifier performs the
- * following steps, returning as soon as one of them succeeds:
- * </p>
- * <ol>
- * <li>Success, if the wrapped defaultVerifier accepts the certificate.</li>
- * <li>Success, if the server certificate is stored in the keystore under the given hostname.</li>
- * <li>Ask the user and return accordingly.</li>
- * <li>Failure on exception.</li>
- * </ol>
- *
- * @param defaultVerifier the {@link HostnameVerifier} that should perform the actual check
- * @return a new hostname verifier using the MTM's key store
- * @throws IllegalArgumentException if the defaultVerifier parameter is null
- */
- public DomainHostnameVerifier wrapHostnameVerifier(final HostnameVerifier defaultVerifier, final boolean interactive) {
- if (defaultVerifier == null) {
- throw new IllegalArgumentException("The default verifier may not be null");
- }
- return new MemorizingHostnameVerifier(defaultVerifier, interactive);
- }
-
- X509TrustManager getTrustManager(KeyStore ks) {
- try {
- TrustManagerFactory tmf = TrustManagerFactory.getInstance("X509");
- tmf.init(ks);
- for (TrustManager t : tmf.getTrustManagers()) {
- if (t instanceof X509TrustManager) {
- return (X509TrustManager) t;
- }
- }
- } catch (Exception e) {
- // Here, we are covering up errors. It might be more useful
- // however to throw them out of the constructor so the
- // embedding app knows something went wrong.
- LOGGER.log(Level.SEVERE, "getTrustManager(" + ks + ")", e);
- }
- return null;
- }
-
- KeyStore loadAppKeyStore() {
- KeyStore ks;
- try {
- ks = KeyStore.getInstance(KeyStore.getDefaultType());
- } catch (KeyStoreException e) {
- LOGGER.log(Level.SEVERE, "getAppKeyStore()", e);
- return null;
- }
- try {
- ks.load(null, null);
- ks.load(new java.io.FileInputStream(keyStoreFile), "MTM".toCharArray());
- } catch (java.io.FileNotFoundException e) {
- LOGGER.log(Level.INFO, "getAppKeyStore(" + keyStoreFile + ") - file does not exist");
- } catch (Exception e) {
- LOGGER.log(Level.SEVERE, "getAppKeyStore(" + keyStoreFile + ")", e);
- }
- return ks;
- }
-
- void storeCert(String alias, Certificate cert) {
- try {
- appKeyStore.setCertificateEntry(alias, cert);
- } catch (KeyStoreException e) {
- LOGGER.log(Level.SEVERE, "storeCert(" + cert + ")", e);
- return;
- }
- keyStoreUpdated();
- }
-
- void storeCert(X509Certificate cert) {
- storeCert(cert.getSubjectDN().toString(), cert);
- }
-
- void keyStoreUpdated() {
- // reload appTrustManager
- appTrustManager = getTrustManager(appKeyStore);
-
- // store KeyStore to file
- java.io.FileOutputStream fos = null;
- try {
- fos = new java.io.FileOutputStream(keyStoreFile);
- appKeyStore.store(fos, "MTM".toCharArray());
- } catch (Exception e) {
- LOGGER.log(Level.SEVERE, "storeCert(" + keyStoreFile + ")", e);
- } finally {
- if (fos != null) {
- try {
- fos.close();
- } catch (IOException e) {
- LOGGER.log(Level.SEVERE, "storeCert(" + keyStoreFile + ")", e);
- }
- }
- }
- }
-
- // if the certificate is stored in the app key store, it is considered "known"
- private boolean isCertKnown(X509Certificate cert) {
- try {
- return appKeyStore.getCertificateAlias(cert) != null;
- } catch (KeyStoreException e) {
- return false;
- }
- }
-
- private boolean isExpiredException(Throwable e) {
- do {
- if (e instanceof CertificateExpiredException)
- return true;
- e = e.getCause();
- } while (e != null);
- return false;
- }
-
- public void checkCertTrusted(X509Certificate[] chain, String authType, String domain, boolean isServer, boolean interactive)
- throws CertificateException {
- LOGGER.log(Level.FINE, "checkCertTrusted(" + chain + ", " + authType + ", " + isServer + ")");
- try {
- LOGGER.log(Level.FINE, "checkCertTrusted: trying appTrustManager");
- if (isServer)
- appTrustManager.checkServerTrusted(chain, authType);
- else
- appTrustManager.checkClientTrusted(chain, authType);
- } catch (CertificateException ae) {
- LOGGER.log(Level.FINER, "checkCertTrusted: appTrustManager failed", ae);
- // if the cert is stored in our appTrustManager, we ignore expiredness
- if (isExpiredException(ae)) {
- LOGGER.log(Level.INFO, "checkCertTrusted: accepting expired certificate from keystore");
- return;
- }
- if (isCertKnown(chain[0])) {
- LOGGER.log(Level.INFO, "checkCertTrusted: accepting cert already stored in keystore");
- return;
- }
- try {
- if (defaultTrustManager == null)
- throw ae;
- LOGGER.log(Level.FINE, "checkCertTrusted: trying defaultTrustManager");
- if (isServer)
- defaultTrustManager.checkServerTrusted(chain, authType);
- else
- defaultTrustManager.checkClientTrusted(chain, authType);
- } catch (CertificateException e) {
- boolean trustSystemCAs = !PreferenceManager.getDefaultSharedPreferences(master).getBoolean("dont_trust_system_cas", false);
- if (domain != null && isServer && trustSystemCAs && !isIp(domain)) {
- String hash = getBase64Hash(chain[0], "SHA-256");
- List<String> fingerprints = getPoshFingerprints(domain);
- if (hash != null && fingerprints.contains(hash)) {
- Log.d("mtm", "trusted cert fingerprint of " + domain + " via posh");
- return;
- }
- }
- e.printStackTrace();
- if (interactive) {
- interactCert(chain, authType, e);
- } else {
- throw e;
- }
- }
- }
- }
-
- private List<String> getPoshFingerprints(String domain) {
- List<String> cached = getPoshFingerprintsFromCache(domain);
- if (cached == null) {
- return getPoshFingerprintsFromServer(domain);
- } else {
- return cached;
- }
- }
-
- private List<String> getPoshFingerprintsFromServer(String domain) {
- return getPoshFingerprintsFromServer(domain, "https://" + domain + "/.well-known/posh/xmpp-client.json", -1, true);
- }
-
- private List<String> getPoshFingerprintsFromServer(String domain, String url, int maxTtl, boolean followUrl) {
- Log.d("mtm", "downloading json for " + domain + " from " + url);
- try {
- List<String> results = new ArrayList<>();
- HttpsURLConnection connection = (HttpsURLConnection) new URL(url).openConnection();
- connection.setConnectTimeout(5000);
- connection.setReadTimeout(5000);
- BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
- String inputLine;
- StringBuilder builder = new StringBuilder();
- while ((inputLine = in.readLine()) != null) {
- builder.append(inputLine);
- }
- JSONObject jsonObject = new JSONObject(builder.toString());
- in.close();
- int expires = jsonObject.getInt("expires");
- if (expires <= 0) {
- return new ArrayList<>();
- }
- if (maxTtl >= 0) {
- expires = Math.min(maxTtl, expires);
- }
- String redirect;
- try {
- redirect = jsonObject.getString("url");
- } catch (JSONException e) {
- redirect = null;
- }
- if (followUrl && redirect != null && redirect.toLowerCase().startsWith("https")) {
- return getPoshFingerprintsFromServer(domain, redirect, expires, false);
- }
- JSONArray fingerprints = jsonObject.getJSONArray("fingerprints");
- for (int i = 0; i < fingerprints.length(); i++) {
- JSONObject fingerprint = fingerprints.getJSONObject(i);
- String sha256 = fingerprint.getString("sha-256");
- if (sha256 != null) {
- results.add(sha256);
- }
- }
- writeFingerprintsToCache(domain, results, 1000L * expires + System.currentTimeMillis());
- return results;
- } catch (Exception e) {
- Log.d("mtm", "error fetching posh " + e.getMessage());
- return new ArrayList<>();
- }
- }
-
- private File getPoshCacheFile(String domain) {
- return new File(poshCacheDir + domain + ".json");
- }
-
- private void writeFingerprintsToCache(String domain, List<String> results, long expires) {
- File file = getPoshCacheFile(domain);
- file.getParentFile().mkdirs();
- try {
- file.createNewFile();
- JSONObject jsonObject = new JSONObject();
- jsonObject.put("expires", expires);
- jsonObject.put("fingerprints", new JSONArray(results));
- FileOutputStream outputStream = new FileOutputStream(file);
- outputStream.write(jsonObject.toString().getBytes());
- outputStream.flush();
- outputStream.close();
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
-
- private List<String> getPoshFingerprintsFromCache(String domain) {
- File file = getPoshCacheFile(domain);
- try {
- InputStream is = new FileInputStream(file);
- BufferedReader buf = new BufferedReader(new InputStreamReader(is));
-
- String line = buf.readLine();
- StringBuilder sb = new StringBuilder();
-
- while (line != null) {
- sb.append(line).append("\n");
- line = buf.readLine();
- }
- JSONObject jsonObject = new JSONObject(sb.toString());
- is.close();
- long expires = jsonObject.getLong("expires");
- long expiresIn = expires - System.currentTimeMillis();
- if (expiresIn < 0) {
- file.delete();
- return null;
- } else {
- Log.d("mtm", "posh fingerprints expire in " + (expiresIn / 1000) + "s");
- }
- List<String> result = new ArrayList<>();
- JSONArray jsonArray = jsonObject.getJSONArray("fingerprints");
- for (int i = 0; i < jsonArray.length(); ++i) {
- result.add(jsonArray.getString(i));
- }
- return result;
- } catch (FileNotFoundException e) {
- return null;
- } catch (IOException e) {
- return null;
- } catch (JSONException e) {
- file.delete();
- return null;
- }
- }
-
- private static boolean isIp(final String server) {
- return server != null && (
- PATTERN_IPV4.matcher(server).matches()
- || PATTERN_IPV6.matcher(server).matches()
- || PATTERN_IPV6_6HEX4DEC.matcher(server).matches()
- || PATTERN_IPV6_HEX4DECCOMPRESSED.matcher(server).matches()
- || PATTERN_IPV6_HEXCOMPRESSED.matcher(server).matches());
- }
-
- private static String getBase64Hash(X509Certificate certificate, String digest) throws CertificateEncodingException {
- MessageDigest md;
- try {
- md = MessageDigest.getInstance(digest);
- } catch (NoSuchAlgorithmException e) {
- return null;
- }
- md.update(certificate.getEncoded());
- return Base64.encodeToString(md.digest(), Base64.NO_WRAP);
- }
-
- private X509Certificate[] getAcceptedIssuers() {
- LOGGER.log(Level.FINE, "getAcceptedIssuers()");
- return defaultTrustManager.getAcceptedIssuers();
- }
-
- private int createDecisionId(MTMDecision d) {
- int myId;
- synchronized (openDecisions) {
- myId = decisionId;
- openDecisions.put(myId, d);
- decisionId += 1;
- }
- return myId;
- }
-
- private static String hexString(byte[] data) {
- StringBuffer si = new StringBuffer();
- for (int i = 0; i < data.length; i++) {
- si.append(String.format("%02x", data[i]));
- if (i < data.length - 1)
- si.append(":");
- }
- return si.toString();
- }
-
- private static String certHash(final X509Certificate cert, String digest) {
- try {
- MessageDigest md = MessageDigest.getInstance(digest);
- md.update(cert.getEncoded());
- return hexString(md.digest());
- } catch (java.security.cert.CertificateEncodingException e) {
- return e.getMessage();
- } catch (java.security.NoSuchAlgorithmException e) {
- return e.getMessage();
- }
- }
-
- private void certDetails(StringBuffer si, X509Certificate c) {
- SimpleDateFormat validityDateFormater = new SimpleDateFormat("yyyy-MM-dd");
- si.append("\n");
- si.append(c.getSubjectDN().toString());
- si.append("\n");
- si.append(validityDateFormater.format(c.getNotBefore()));
- si.append(" - ");
- si.append(validityDateFormater.format(c.getNotAfter()));
- si.append("\nSHA-256: ");
- si.append(certHash(c, "SHA-256"));
- si.append("\nSHA-1: ");
- si.append(certHash(c, "SHA-1"));
- si.append("\nSigned by: ");
- si.append(c.getIssuerDN().toString());
- si.append("\n");
- }
-
- private String certChainMessage(final X509Certificate[] chain, CertificateException cause) {
- Throwable e = cause;
- LOGGER.log(Level.FINE, "certChainMessage for " + e);
- StringBuffer si = new StringBuffer();
- if (e.getCause() != null) {
- e = e.getCause();
- // HACK: there is no sane way to check if the error is a "trust anchor
- // not found", so we use string comparison.
- if (NO_TRUST_ANCHOR.equals(e.getMessage())) {
- si.append(master.getString(R.string.mtm_trust_anchor));
- } else
- si.append(e.getLocalizedMessage());
- si.append("\n");
- }
- si.append("\n");
- si.append(master.getString(R.string.mtm_connect_anyway));
- si.append("\n\n");
- si.append(master.getString(R.string.mtm_cert_details));
- for (X509Certificate c : chain) {
- certDetails(si, c);
- }
- return si.toString();
- }
-
- private String hostNameMessage(X509Certificate cert, String hostname) {
- StringBuffer si = new StringBuffer();
-
- si.append(master.getString(R.string.mtm_hostname_mismatch, hostname));
- si.append("\n\n");
- try {
- Collection<List<?>> sans = cert.getSubjectAlternativeNames();
- if (sans == null) {
- si.append(cert.getSubjectDN());
- si.append("\n");
- } else for (List<?> altName : sans) {
- Object name = altName.get(1);
- if (name instanceof String) {
- si.append("[");
- si.append((Integer) altName.get(0));
- si.append("] ");
- si.append(name);
- si.append("\n");
- }
- }
- } catch (CertificateParsingException e) {
- e.printStackTrace();
- si.append("<Parsing error: ");
- si.append(e.getLocalizedMessage());
- si.append(">\n");
- }
- si.append("\n");
- si.append(master.getString(R.string.mtm_connect_anyway));
- si.append("\n\n");
- si.append(master.getString(R.string.mtm_cert_details));
- certDetails(si, cert);
- return si.toString();
- }
-
- /**
- * Returns the top-most entry of the activity stack.
- *
- * @return the Context of the currently bound UI or the master context if none is bound
- */
- Context getUI() {
- return (foregroundAct != null) ? foregroundAct : master;
- }
-
- int interact(final String message, final int titleId) {
- /* prepare the MTMDecision blocker object */
- MTMDecision choice = new MTMDecision();
- final int myId = createDecisionId(choice);
-
- masterHandler.post(new Runnable() {
- public void run() {
- Intent ni = new Intent(master, MemorizingActivity.class);
- ni.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- ni.setData(Uri.parse(MemorizingTrustManager.class.getName() + "/" + myId));
- ni.putExtra(DECISION_INTENT_ID, myId);
- ni.putExtra(DECISION_INTENT_CERT, message);
- ni.putExtra(DECISION_TITLE_ID, titleId);
-
- // we try to directly start the activity and fall back to
- // making a notification
- try {
- getUI().startActivity(ni);
- } catch (Exception e) {
- LOGGER.log(Level.FINE, "startActivity(MemorizingActivity)", e);
- }
- }
- });
-
- LOGGER.log(Level.FINE, "openDecisions: " + openDecisions + ", waiting on " + myId);
- try {
- synchronized (choice) {
- choice.wait();
- }
- } catch (InterruptedException e) {
- LOGGER.log(Level.FINER, "InterruptedException", e);
- }
- LOGGER.log(Level.FINE, "finished wait on " + myId + ": " + choice.state);
- return choice.state;
- }
-
- void interactCert(final X509Certificate[] chain, String authType, CertificateException cause)
- throws CertificateException {
- switch (interact(certChainMessage(chain, cause), R.string.mtm_accept_cert)) {
- case MTMDecision.DECISION_ALWAYS:
- storeCert(chain[0]); // only store the server cert, not the whole chain
- case MTMDecision.DECISION_ONCE:
- break;
- default:
- throw (cause);
- }
- }
-
- boolean interactHostname(X509Certificate cert, String hostname) {
- switch (interact(hostNameMessage(cert, hostname), R.string.mtm_accept_servername)) {
- case MTMDecision.DECISION_ALWAYS:
- storeCert(hostname, cert);
- case MTMDecision.DECISION_ONCE:
- return true;
- default:
- return false;
- }
- }
-
- protected static void interactResult(int decisionId, int choice) {
- MTMDecision d;
- synchronized (openDecisions) {
- d = openDecisions.get(decisionId);
- openDecisions.remove(decisionId);
- }
- if (d == null) {
- LOGGER.log(Level.SEVERE, "interactResult: aborting due to stale decision reference!");
- return;
- }
- synchronized (d) {
- d.state = choice;
- d.notify();
- }
- }
-
- class MemorizingHostnameVerifier implements DomainHostnameVerifier {
- private final HostnameVerifier defaultVerifier;
- private final boolean interactive;
-
- public MemorizingHostnameVerifier(HostnameVerifier wrapped, boolean interactive) {
- this.defaultVerifier = wrapped;
- this.interactive = interactive;
- }
-
- @Override
- public boolean verify(String domain, String hostname, SSLSession session) {
- LOGGER.log(Level.FINE, "hostname verifier for " + domain + ", trying default verifier first");
- // if the default verifier accepts the hostname, we are done
- if (defaultVerifier instanceof DomainHostnameVerifier) {
- if (((DomainHostnameVerifier) defaultVerifier).verify(domain, hostname, session)) {
- return true;
- }
- } else {
- if (defaultVerifier.verify(domain, session)) {
- return true;
- }
- }
-
- // otherwise, we check if the hostname is an alias for this cert in our keystore
- try {
- X509Certificate cert = (X509Certificate) session.getPeerCertificates()[0];
- //Log.d(TAG, "cert: " + cert);
- if (cert.equals(appKeyStore.getCertificate(domain.toLowerCase(Locale.US)))) {
- LOGGER.log(Level.FINE, "certificate for " + domain + " is in our keystore. accepting.");
- return true;
- } else {
- LOGGER.log(Level.FINE, "server " + domain + " provided wrong certificate, asking user.");
- if (interactive) {
- return interactHostname(cert, domain);
- } else {
- return false;
- }
- }
- } catch (Exception e) {
- e.printStackTrace();
- return false;
- }
- }
-
- @Override
- public boolean verify(String domain, SSLSession sslSession) {
- return verify(domain, null, sslSession);
- }
- }
-
- public X509TrustManager getNonInteractive(String domain) {
- return new NonInteractiveMemorizingTrustManager(domain);
- }
-
- public X509TrustManager getInteractive(String domain) {
- return new InteractiveMemorizingTrustManager(domain);
- }
-
- public X509TrustManager getNonInteractive() {
- return new NonInteractiveMemorizingTrustManager(null);
- }
-
- public X509TrustManager getInteractive() {
- return new InteractiveMemorizingTrustManager(null);
- }
-
- private class NonInteractiveMemorizingTrustManager implements X509TrustManager {
-
- private final String domain;
-
- public NonInteractiveMemorizingTrustManager(String domain) {
- this.domain = domain;
- }
-
- @Override
- public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
- MemorizingTrustManager.this.checkCertTrusted(chain, authType, domain, false, false);
- }
-
- @Override
- public void checkServerTrusted(X509Certificate[] chain, String authType)
- throws CertificateException {
- MemorizingTrustManager.this.checkCertTrusted(chain, authType, domain, true, false);
- }
-
- @Override
- public X509Certificate[] getAcceptedIssuers() {
- return MemorizingTrustManager.this.getAcceptedIssuers();
- }
-
- }
-
- private class InteractiveMemorizingTrustManager implements X509TrustManager {
- private final String domain;
-
- public InteractiveMemorizingTrustManager(String domain) {
- this.domain = domain;
- }
-
- @Override
- public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
- MemorizingTrustManager.this.checkCertTrusted(chain, authType, domain, false, true);
- }
-
- @Override
- public void checkServerTrusted(X509Certificate[] chain, String authType)
- throws CertificateException {
- MemorizingTrustManager.this.checkCertTrusted(chain, authType, domain, true, true);
- }
-
- @Override
- public X509Certificate[] getAcceptedIssuers() {
- return MemorizingTrustManager.this.getAcceptedIssuers();
- }
- }
-}