diff --git a/OpenKeychain/build.gradle b/OpenKeychain/build.gradle index 9f0e2eeb4..1c2e97ffb 100644 --- a/OpenKeychain/build.gradle +++ b/OpenKeychain/build.gradle @@ -52,6 +52,7 @@ dependencies { compile 'com.fidesmo:nordpol-android:0.1.20' // libs as submodules + compile project(':libkeychain') compile project(':openpgp-api-lib') compile project(':extern:bouncycastle:core') compile project(':extern:bouncycastle:pg') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/IteratorWithSize.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/IteratorWithSize.java deleted file mode 100644 index 96cf5a47e..000000000 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/IteratorWithSize.java +++ /dev/null @@ -1,17 +0,0 @@ -package org.sufficientlysecure.keychain.util; - -import java.util.Iterator; - -/** - * An extended iterator interface, which knows the total number of its entries beforehand. - */ -public interface IteratorWithSize extends Iterator { - - /** - * Returns the total number of entries in this iterator. - * - * @return the number of entries in this iterator. - */ - int getSize(); - -} diff --git a/libkeychain/.gitignore b/libkeychain/.gitignore new file mode 100644 index 000000000..a44cc0f0f --- /dev/null +++ b/libkeychain/.gitignore @@ -0,0 +1,33 @@ +#Android specific +bin +gen +obj +lint.xml +local.properties +release.properties +ant.properties +*.class +*.apk + +#Gradle +.gradle +build +gradle.properties + +#Maven +target +pom.xml.* + +#Eclipse +.project +.classpath +.settings +.metadata + +#IntelliJ IDEA +.idea +*.iml + +#Lint output +lint-report.html +lint-report_files/* \ No newline at end of file diff --git a/libkeychain/build.gradle b/libkeychain/build.gradle new file mode 100644 index 000000000..a6a30c8d8 --- /dev/null +++ b/libkeychain/build.gradle @@ -0,0 +1,40 @@ +apply plugin: 'com.android.library' + +dependencies { + // NOTE: Always use fixed version codes not dynamic ones, e.g. 0.7.3 instead of 0.7.+, see README for more information + // NOTE: libraries are pinned to a specific build, see below + + // from local Android SDK + compile 'com.android.support:support-v4:25.0.1' + + // libs as submodules + compile project(':openpgp-api-lib') // TODO: get rid of this dependency + compile project(':extern:bouncycastle:core') + compile project(':extern:bouncycastle:pg') + compile project(':extern:bouncycastle:prov') + + // Unit tests in the local JVM with Robolectric + // https://developer.android.com/training/testing/unit-testing/local-unit-tests.html + // http://robolectric.org/getting-started/ + // http://www.vogella.com/tutorials/Robolectric/article.html + testCompile 'junit:junit:4.12' + testCompile ('org.robolectric:robolectric:3.2.2') { + exclude group: 'org.bouncycastle', module: 'bcprov-jdk16' + } + testCompile 'org.mockito:mockito-core:1.10.19' + +} + +android { + compileSdkVersion rootProject.ext.compileSdkVersion + buildToolsVersion rootProject.ext.buildToolsVersion + + defaultConfig { + minSdkVersion 14 + } + + // Do not abort build if lint finds errors + lintOptions { + abortOnError false + } +} diff --git a/libkeychain/src/main/AndroidManifest.xml b/libkeychain/src/main/AndroidManifest.xml new file mode 100644 index 000000000..6a035abfa --- /dev/null +++ b/libkeychain/src/main/AndroidManifest.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/OpenKeychain/src/main/java/org/bouncycastle/openpgp/jcajce/JcaSkipMarkerPGPObjectFactory.java b/libkeychain/src/main/java/org/bouncycastle/openpgp/jcajce/JcaSkipMarkerPGPObjectFactory.java similarity index 85% rename from OpenKeychain/src/main/java/org/bouncycastle/openpgp/jcajce/JcaSkipMarkerPGPObjectFactory.java rename to libkeychain/src/main/java/org/bouncycastle/openpgp/jcajce/JcaSkipMarkerPGPObjectFactory.java index 72d6036ab..ff87087e9 100644 --- a/OpenKeychain/src/main/java/org/bouncycastle/openpgp/jcajce/JcaSkipMarkerPGPObjectFactory.java +++ b/libkeychain/src/main/java/org/bouncycastle/openpgp/jcajce/JcaSkipMarkerPGPObjectFactory.java @@ -1,3 +1,9 @@ +/** + * Copyright (c) 2016 Vincent Breitmoser + * + * Licensed under the Bouncy Castle License (MIT license). See LICENSE file for details. + */ + package org.bouncycastle.openpgp.jcajce; diff --git a/OpenKeychain/src/main/java/org/bouncycastle/openpgp/operator/jcajce/CachingDataDecryptorFactory.java b/libkeychain/src/main/java/org/bouncycastle/openpgp/operator/jcajce/CachingDataDecryptorFactory.java similarity index 100% rename from OpenKeychain/src/main/java/org/bouncycastle/openpgp/operator/jcajce/CachingDataDecryptorFactory.java rename to libkeychain/src/main/java/org/bouncycastle/openpgp/operator/jcajce/CachingDataDecryptorFactory.java diff --git a/OpenKeychain/src/main/java/org/bouncycastle/openpgp/operator/jcajce/NfcSyncPGPContentSignerBuilder.java b/libkeychain/src/main/java/org/bouncycastle/openpgp/operator/jcajce/NfcSyncPGPContentSignerBuilder.java similarity index 100% rename from OpenKeychain/src/main/java/org/bouncycastle/openpgp/operator/jcajce/NfcSyncPGPContentSignerBuilder.java rename to libkeychain/src/main/java/org/bouncycastle/openpgp/operator/jcajce/NfcSyncPGPContentSignerBuilder.java diff --git a/OpenKeychain/src/main/java/org/bouncycastle/openpgp/operator/jcajce/SessionKeySecretKeyDecryptorBuilder.java b/libkeychain/src/main/java/org/bouncycastle/openpgp/operator/jcajce/SessionKeySecretKeyDecryptorBuilder.java similarity index 100% rename from OpenKeychain/src/main/java/org/bouncycastle/openpgp/operator/jcajce/SessionKeySecretKeyDecryptorBuilder.java rename to libkeychain/src/main/java/org/bouncycastle/openpgp/operator/jcajce/SessionKeySecretKeyDecryptorBuilder.java diff --git a/libkeychain/src/main/java/org/sufficientlysecure/keychain/LibConstants.java b/libkeychain/src/main/java/org/sufficientlysecure/keychain/LibConstants.java new file mode 100644 index 000000000..6da752417 --- /dev/null +++ b/libkeychain/src/main/java/org/sufficientlysecure/keychain/LibConstants.java @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2017 Dominik Schürmann + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package org.sufficientlysecure.keychain; + +import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.sufficientlysecure.libkeychain.BuildConfig; + +public final class LibConstants { + + public static final boolean DEBUG = BuildConfig.DEBUG; + + public static final String TAG = DEBUG ? "Keychain D" : "Keychain"; + + public static final String BOUNCY_CASTLE_PROVIDER_NAME = BouncyCastleProvider.PROVIDER_NAME; + +} diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/CharsetVerifier.java b/libkeychain/src/main/java/org/sufficientlysecure/keychain/util/CharsetVerifier.java similarity index 87% rename from OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/CharsetVerifier.java rename to libkeychain/src/main/java/org/sufficientlysecure/keychain/util/CharsetVerifier.java index c03decc89..821117487 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/CharsetVerifier.java +++ b/libkeychain/src/main/java/org/sufficientlysecure/keychain/util/CharsetVerifier.java @@ -1,3 +1,20 @@ +/* + * Copyright (C) 2017 Dominik Schürmann + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + package org.sufficientlysecure.keychain.util; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/CountingOutputStream.java b/libkeychain/src/main/java/org/sufficientlysecure/keychain/util/CountingOutputStream.java similarity index 100% rename from OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/CountingOutputStream.java rename to libkeychain/src/main/java/org/sufficientlysecure/keychain/util/CountingOutputStream.java diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/InputData.java b/libkeychain/src/main/java/org/sufficientlysecure/keychain/util/InputData.java similarity index 100% rename from OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/InputData.java rename to libkeychain/src/main/java/org/sufficientlysecure/keychain/util/InputData.java diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/IterableIterator.java b/libkeychain/src/main/java/org/sufficientlysecure/keychain/util/IterableIterator.java similarity index 100% rename from OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/IterableIterator.java rename to libkeychain/src/main/java/org/sufficientlysecure/keychain/util/IterableIterator.java diff --git a/libkeychain/src/main/java/org/sufficientlysecure/keychain/util/IteratorWithSize.java b/libkeychain/src/main/java/org/sufficientlysecure/keychain/util/IteratorWithSize.java new file mode 100644 index 000000000..03f66e1ca --- /dev/null +++ b/libkeychain/src/main/java/org/sufficientlysecure/keychain/util/IteratorWithSize.java @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2017 Dominik Schürmann + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package org.sufficientlysecure.keychain.util; + +import java.util.Iterator; + +/** + * An extended iterator interface, which knows the total number of its entries beforehand. + */ +public interface IteratorWithSize extends Iterator { + + /** + * Returns the total number of entries in this iterator. + * + * @return the number of entries in this iterator. + */ + int getSize(); + +} diff --git a/libkeychain/src/main/java/org/sufficientlysecure/keychain/util/LibLog.java b/libkeychain/src/main/java/org/sufficientlysecure/keychain/util/LibLog.java new file mode 100644 index 000000000..47526f67a --- /dev/null +++ b/libkeychain/src/main/java/org/sufficientlysecure/keychain/util/LibLog.java @@ -0,0 +1,161 @@ +/* + * Copyright (C) 2012-2014 Dominik Schürmann + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package org.sufficientlysecure.keychain.util; + +import android.os.Bundle; + +import org.sufficientlysecure.keychain.LibConstants; + +import java.util.Iterator; +import java.util.Set; + +/** + * Wraps Android Logging to enable or disable debug output using Constants + */ +public final class LibLog { + + public static void v(String tag, String msg) { + if (LibConstants.DEBUG) { + android.util.Log.v(tag, msg); + } + } + + public static void v(String tag, String msg, Throwable tr) { + if (LibConstants.DEBUG) { + android.util.Log.v(tag, msg, tr); + } + } + + public static void d(String tag, String msg) { + if (LibConstants.DEBUG) { + android.util.Log.d(tag, msg); + } + } + + public static void d(String tag, String msg, Throwable tr) { + if (LibConstants.DEBUG) { + android.util.Log.d(tag, msg, tr); + } + } + + public static void dEscaped(String tag, String msg) { + if (LibConstants.DEBUG) { + android.util.Log.d(tag, removeUnicodeAndEscapeChars(msg)); + } + } + + public static void dEscaped(String tag, String msg, Throwable tr) { + if (LibConstants.DEBUG) { + android.util.Log.d(tag, removeUnicodeAndEscapeChars(msg), tr); + } + } + + public static void i(String tag, String msg) { + if (LibConstants.DEBUG) { + android.util.Log.i(tag, msg); + } + } + + public static void i(String tag, String msg, Throwable tr) { + if (LibConstants.DEBUG) { + android.util.Log.i(tag, msg, tr); + } + } + + public static void w(String tag, String msg) { + android.util.Log.w(tag, msg); + } + + public static void w(String tag, String msg, Throwable tr) { + android.util.Log.w(tag, msg, tr); + } + + public static void w(String tag, Throwable tr) { + android.util.Log.w(tag, tr); + } + + public static void e(String tag, String msg) { + android.util.Log.e(tag, msg); + } + + public static void e(String tag, String msg, Throwable tr) { + android.util.Log.e(tag, msg, tr); + } + + + /** + * Logs bundle content to debug for inspecting the content + * + * @param bundle + * @param bundleName + */ + public static void logDebugBundle(Bundle bundle, String bundleName) { + if (LibConstants.DEBUG) { + if (bundle != null) { + Set ks = bundle.keySet(); + Iterator iterator = ks.iterator(); + + LibLog.d(LibConstants.TAG, "Bundle " + bundleName + ":"); + LibLog.d(LibConstants.TAG, "------------------------------"); + while (iterator.hasNext()) { + String key = iterator.next(); + Object value = bundle.get(key); + + if (value != null) { + LibLog.d(LibConstants.TAG, key + " : " + value.toString()); + } else { + LibLog.d(LibConstants.TAG, key + " : null"); + } + } + LibLog.d(LibConstants.TAG, "------------------------------"); + } else { + LibLog.d(LibConstants.TAG, "Bundle " + bundleName + ": null"); + } + } + } + + public static String removeUnicodeAndEscapeChars(String input) { + StringBuilder buffer = new StringBuilder(input.length()); + for (int i = 0; i < input.length(); i++) { + if ((int) input.charAt(i) > 256) { + buffer.append("\\u").append(Integer.toHexString((int) input.charAt(i))); + } else { + if (input.charAt(i) == '\n') { + buffer.append("\\n"); + } else if (input.charAt(i) == '\t') { + buffer.append("\\t"); + } else if (input.charAt(i) == '\r') { + buffer.append("\\r"); + } else if (input.charAt(i) == '\b') { + buffer.append("\\b"); + } else if (input.charAt(i) == '\f') { + buffer.append("\\f"); + } else if (input.charAt(i) == '\'') { + buffer.append("\\'"); + } else if (input.charAt(i) == '\"') { + buffer.append("\\"); + } else if (input.charAt(i) == '\\') { + buffer.append("\\\\"); + } else { + buffer.append(input.charAt(i)); + } + } + } + return buffer.toString(); + } +} diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/PositionAwareInputStream.java b/libkeychain/src/main/java/org/sufficientlysecure/keychain/util/PositionAwareInputStream.java similarity index 100% rename from OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/PositionAwareInputStream.java rename to libkeychain/src/main/java/org/sufficientlysecure/keychain/util/PositionAwareInputStream.java diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/Utf8Util.java b/libkeychain/src/main/java/org/sufficientlysecure/keychain/util/Utf8Util.java similarity index 93% rename from OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/Utf8Util.java rename to libkeychain/src/main/java/org/sufficientlysecure/keychain/util/Utf8Util.java index bed3e28ed..408b204ac 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/Utf8Util.java +++ b/libkeychain/src/main/java/org/sufficientlysecure/keychain/util/Utf8Util.java @@ -17,7 +17,7 @@ package org.sufficientlysecure.keychain.util; -import org.sufficientlysecure.keychain.Constants; +import org.sufficientlysecure.keychain.LibConstants; import java.nio.ByteBuffer; import java.nio.charset.CharacterCodingException; @@ -46,7 +46,7 @@ public class Utf8Util { try { return charsetDecoder.decode(ByteBuffer.wrap(input)).toString(); } catch (CharacterCodingException e) { - Log.e(Constants.TAG, "Decoding failed!", e); + LibLog.e(LibConstants.TAG, "Decoding failed!", e); return charsetDecoder.replacement(); } } diff --git a/settings.gradle b/settings.gradle index 69ddb206a..828239ce0 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,10 +1,14 @@ include ':OpenKeychain' +include ':libkeychain' include ':extern:bouncycastle:core' include ':extern:bouncycastle:pg' include ':extern:bouncycastle:prov' include ':extern:minidns' // Workaround for Android Gradle Plugin 2.0, as described in http://stackoverflow.com/a/36544850 +//include ':libkeychain' +include ':libkeychain' +project(':libkeychain').projectDir = new File('libkeychain') //include ':extern:safeslinger-exchange:safeslinger-exchange' include ':safeslinger-exchange' project(':safeslinger-exchange').projectDir = new File('extern/safeslinger-exchange/safeslinger-exchange')