Commit 54fd5e0d authored by Steppschuh's avatar Steppschuh
Browse files

Release 1.6.1

parents
# Stuff
.DS_Store
# Built application files
*.apk
*.aar
*.ap_
*.aab
# Files for the ART/Dalvik VM
*.dex
# Java class files
*.class
# Generated files
bin/
gen/
out/
# Uncomment the following line in case you need and you don't have the release build type files in your app
# release/
# Gradle files
.gradle/
build/
# Local configuration file (sdk path, etc)
local.properties
# Proguard folder generated by Eclipse
proguard/
# Log Files
*.log
# Android Studio Navigation editor temp files
.navigation/
# Android Studio captures folder
captures/
# IntelliJ
*.iml
.idea/workspace.xml
.idea/tasks.xml
.idea/gradle.xml
.idea/assetWizardSettings.xml
.idea/dictionaries
.idea/libraries
# Android Studio 3 in .gitignore file.
.idea/caches
.idea/modules.xml
# Comment next line if keeping position of elements in Navigation Editor is relevant for you
.idea/navEditor.xml
# Keystore files
# Uncomment the following lines if you do not want to check your keystore files in.
#*.jks
#*.keystore
# External native build folder generated in Android Studio 2.2 and later
.externalNativeBuild
.cxx/
# Google Services (e.g. APIs or Firebase)
# google-services.json
# Freeline
freeline.py
freeline/
freeline_project_description.json
# fastlane
fastlane/report.xml
fastlane/Preview.html
fastlane/screenshots
fastlane/test_output
fastlane/readme.md
# Version control
vcs.xml
# lint
lint/intermediates/
lint/generated/
lint/outputs/
lint/tmp/
# lint/reports/
# Android Profiling
*.hprof
# Stuff
.DS_Store
# Default ignored files
/shelf/
<component name="ProjectCodeStyleConfiguration">
<code_scheme name="Project" version="173">
<codeStyleSettings language="XML">
<indentOptions>
<option name="CONTINUATION_INDENT_SIZE" value="4" />
</indentOptions>
<arrangement>
<rules>
<section>
<rule>
<match>
<AND>
<NAME>xmlns:android</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>xmlns:.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*:id</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*:name</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>name</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>style</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
<order>ANDROID_ATTRIBUTE_ORDER</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>.*</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
</rules>
</arrangement>
</codeStyleSettings>
</code_scheme>
</component>
\ No newline at end of file
<component name="ProjectCodeStyleConfiguration">
<state>
<option name="PREFERRED_PROJECT_CODE_STYLE" value="neXenio" />
</state>
</component>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<bytecodeTargetLevel target="1.8" />
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RemoteRepositoriesConfiguration">
<remote-repository>
<option name="id" value="central" />
<option name="name" value="Maven Central repository" />
<option name="url" value="https://repo1.maven.org/maven2" />
</remote-repository>
<remote-repository>
<option name="id" value="jboss.community" />
<option name="name" value="JBoss Community repository" />
<option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" />
</remote-repository>
<remote-repository>
<option name="id" value="maven" />
<option name="name" value="maven" />
<option name="url" value="https://artifactory.seamlessme.local/artifactory/seamlessme-android-development" />
</remote-repository>
<remote-repository>
<option name="id" value="BintrayJCenter" />
<option name="name" value="BintrayJCenter" />
<option name="url" value="https://jcenter.bintray.com/" />
</remote-repository>
<remote-repository>
<option name="id" value="Google" />
<option name="name" value="Google" />
<option name="url" value="https://dl.google.com/dl/android/maven2/" />
</remote-repository>
<remote-repository>
<option name="id" value="maven" />
<option name="name" value="maven" />
<option name="url" value="https://jitpack.io" />
</remote-repository>
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" />
</component>
<component name="ProjectType">
<option name="id" value="Android" />
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RunConfigurationProducerService">
<option name="ignoredProducers">
<set>
<option value="org.jetbrains.plugins.gradle.execution.test.runner.AllInPackageGradleConfigurationProducer" />
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestClassGradleConfigurationProducer" />
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestMethodGradleConfigurationProducer" />
</set>
</option>
</component>
</project>
\ No newline at end of file
/build
\ No newline at end of file
apply plugin: 'com.android.application'
android {
compileSdkVersion 30
buildToolsVersion "29.0.2"
defaultConfig {
applicationId "de.culture4life.luca"
minSdkVersion 21
targetSdkVersion 30
versionCode 52
versionName "1.6.1"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
signingConfigs {
culture4life {
keyAlias project.property("C4L_SIGNING_KEY_ALIAS")
keyPassword project.property("C4L_SIGNING_KEY_PASSWORD")
storeFile file(project.property("C4L_SIGNING_STORE_FILE"))
storePassword project.property("C4L_SIGNING_STORE_PASSWORD")
}
}
buildTypes {
release {
debuggable false
minifyEnabled true
shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.culture4life
}
debug {
debuggable true
minifyEnabled false
versionNameSuffix " Debug"
applicationIdSuffix ".debug"
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
dependencies {
implementation 'androidx.annotation:annotation:1.1.0'
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'androidx.camera:camera-camera2:1.0.0-rc03'
implementation 'androidx.camera:camera-lifecycle:1.0.0-beta02'
implementation 'androidx.camera:camera-view:1.0.0-alpha22'
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
implementation 'androidx.core:core:1.3.2'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
implementation 'androidx.multidex:multidex:2.0.1'
implementation 'androidx.navigation:navigation-fragment:2.3.4'
implementation 'androidx.navigation:navigation-ui:2.3.4'
implementation 'androidx.work:work-runtime:2.5.0'
implementation 'androidx.work:work-rxjava3:2.5.0'
implementation 'com.github.akarnokd:rxjava3-extensions:3.0.1'
implementation 'com.github.akarnokd:rxjava3-bridge:3.0.0'
implementation 'com.github.kenglxn.QRGen:android:2.6.0'
implementation 'com.github.neXenio:RxKeyStore:0.5.1'
implementation 'com.github.neXenio:RxPreferences:1.1.0'
implementation 'com.github.Nivador:RxPermissions:0.11.2'
implementation 'com.google.android.gms:play-services-location:18.0.0'
implementation 'com.google.android.gms:play-services-instantapps:17.0.0'
implementation 'com.google.android.gms:play-services-mlkit-barcode-scanning:16.1.4'
implementation 'com.google.android.material:material:1.3.0'
implementation 'com.google.code.gson:gson:2.8.6'
implementation 'com.googlecode.libphonenumber:libphonenumber:8.2.0'
implementation 'com.jakewharton.timber:timber:4.7.1'
implementation 'com.ncorti:slidetoact:0.9.0'
implementation 'com.squareup.okhttp3:okhttp:4.9.0'
implementation 'com.squareup.okhttp3:logging-interceptor:4.9.0'
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:adapter-rxjava3:2.9.0'
implementation 'com.squareup.retrofit2:converter-gson:2.1.0'
implementation 'com.uber.rxdogtag2:rxdogtag:2.0.1'
implementation 'io.reactivex.rxjava3:rxjava:3.0.6'
implementation 'io.reactivex.rxjava3:rxandroid:3.0.0'
implementation 'net.grandcentrix.tray:tray:0.12.0'
implementation 'org.bouncycastle:bcpkix-jdk15on:1.56'
testImplementation 'androidx.test:core:1.3.0'
testImplementation 'com.android.support.test:rules:1.0.2'
testImplementation 'com.android.support.test:runner:1.0.2'
testImplementation 'junit:junit:4.13'
testImplementation 'net.lachlanmckee:timber-junit-rule:1.0.1'
testImplementation 'org.mockito:mockito-core:2.21.0'
testImplementation 'org.powermock:powermock-api-mockito2:2.0.0-beta.5'
testImplementation 'org.powermock:powermock-classloading-xstream:2.0.0-beta.5'
testImplementation 'org.powermock:powermock-module-junit4:2.0.0-beta.5'
testImplementation 'org.powermock:powermock-module-junit4-common:2.0.0-beta.5'
testImplementation 'org.powermock:powermock-module-junit4-rule:2.0.0-beta.5'
testImplementation 'org.robolectric:robolectric:4.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
androidTestImplementation 'androidx.test.uiautomator:uiautomator:2.2.0'
androidTestImplementation('com.android.support.test.espresso:espresso-core:3.0.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'net.lachlanmckee:timber-junit-rule:1.0.1'
androidTestImplementation 'org.mockito:mockito-android:2.21.0'
}
{
"version": 1,
"artifactType": {
"type": "APK",
"kind": "Directory"
},
"applicationId": "de.culture4life.luca.debug",
"variantName": "debug",
"elements": [
{
"type": "SINGLE",
"filters": [],
"properties": [],
"versionCode": 3,
"versionName": "0.3.0 Debug",
"enabled": true,
"outputFile": "app-debug.apk"
}
]
}
\ No newline at end of file
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# 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 *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
##---------------Begin: proguard configuration for Gson ----------
# Gson uses generic type information stored in a class file when working with fields. Proguard
# removes such information by default, so configure it to keep all of it.
# See https://github.com/google/gson/blob/master/examples/android-proguard-example/proguard.cfg
-keepattributes Signature
# For using GSON @Expose annotation
-keepattributes *Annotation*
# Gson specific classes
-dontnote sun.misc.**
-keep class sun.misc.Unsafe { *; }
-keep class com.google.gson.stream.** { *; }
-keep class * implements com.google.gson.TypeAdapterFactory
-keep class * implements com.google.gson.JsonSerializer
-keep class * implements com.google.gson.JsonDeserializer
# Prevent R8 from leaving Data object members always null
-keepclassmembers,allowobfuscation class * {
@com.google.gson.annotations.SerializedName <fields>;
}
# Application classes that will be serialized/deserialized over Gson
-keep class de.culture4life.luca.** { *; }
-keep class org.bouncycastle.jcajce.provider.** { *; }
-keep class org.bouncycastle.jce.provider.** { *; }
##---------------End: proguard configuration for Gson ----------
package de.culture4life.luca;
import androidx.test.platform.app.InstrumentationRegistry;
public class LucaInstrumentationTest {
protected LucaApplication application;
public LucaInstrumentationTest() {
this.application = getInstrumentedApplication();
}
protected LucaApplication getInstrumentedApplication() {
return (LucaApplication) InstrumentationRegistry.getInstrumentation().getTargetContext().getApplicationContext();
}
}
package de.culture4life.luca.crypto;
import android.content.Context;
import android.util.Base64;
import com.nexenio.rxkeystore.RxKeyStore;
import com.nexenio.rxkeystore.util.RxBase64;
import org.junit.Before;
import org.junit.Test;
import java.math.BigInteger;
import java.security.interfaces.ECPrivateKey;
import java.security.interfaces.ECPublicKey;
import androidx.test.platform.app.InstrumentationRegistry;
public class AsymmetricCipherProviderTest {
private static final String ENCODED_UNCOMPRESSED_PUBLIC_KEY = "BAIDQ7/zTOcV+XXX5io9XZn1t4MUOAswVfZKd6Fpup/MwlNssx4mCEPcO34AIiV0TbL2ywOP3QoHs41cfvv7uTo=";
private static final String ENCODED_COMPRESSED_PUBLIC_KEY = "AgIDQ7/zTOcV+XXX5io9XZn1t4MUOAswVfZKd6Fpup/M";
private static final String ENCODED_PRIVATE_KEY = "2J9dWi+NKANgXznZVthBygcElRk3XNy7IUPrqwGtEZE=";
private Context context;
private AsymmetricCipherProvider asymmetricCipherProvider;
@Before
public void setup() {
CryptoManager.setupSecurityProviders().blockingAwait();
context = InstrumentationRegistry.getInstrumentation().getTargetContext();
RxKeyStore keyStore = new RxKeyStore(RxKeyStore.TYPE_BKS, RxKeyStore.PROVIDER_BOUNCY_CASTLE);
asymmetricCipherProvider = new AsymmetricCipherProvider(keyStore);
}
@Test
public void encode_validPublicKeyUncompressed_emitsEncodedUncompressedKey() {
ECPublicKey publicKey = decodePublicKey(ENCODED_UNCOMPRESSED_PUBLIC_KEY);
AsymmetricCipherProvider.encode(publicKey, false)
.flatMap(bytes -> RxBase64.encode(bytes, Base64.NO_WRAP))
.test()
.assertValue(ENCODED_UNCOMPRESSED_PUBLIC_KEY);
}
@Test
public void encode_validPublicKeyCompressed_emitsEncodedCompressedKey() {
ECPublicKey publicKey = decodePublicKey(ENCODED_COMPRESSED_PUBLIC_KEY);
AsymmetricCipherProvider.encode(publicKey, true)
.flatMap(bytes -> RxBase64.encode(bytes, Base64.NO_WRAP))
.test()
.assertValue(ENCODED_COMPRESSED_PUBLIC_KEY);
}
@Test
public void decodePublicKey_validUncompressedEncodedKey_emitsDecodedKey() {
ECPublicKey publicKey = decodePublicKey(ENCODED_UNCOMPRESSED_PUBLIC_KEY);
byte[] encodedPublicKey = AsymmetricCipherProvider.encode(publicKey, false)
.blockingGet();
AsymmetricCipherProvider.decodePublicKey(encodedPublicKey)
.test()
.assertValue(publicKey);
}
@Test
public void decodePublicKey_validCompressedEncodedKey_emitsDecodedKey() {
ECPublicKey publicKey = decodePublicKey(ENCODED_UNCOMPRESSED_PUBLIC_KEY);
byte[] encodedPublicKey = AsymmetricCipherProvider.encode(publicKey, true)
.blockingGet();
AsymmetricCipherProvider.decodePublicKey(encodedPublicKey)
.test()
.assertValue(publicKey);
}
@Test
public void decodePrivateKey_validEncodedKey_emitsDecodedKey() {
byte[] encodedPrivateKey = RxBase64.decode(ENCODED_PRIVATE_KEY, Base64.NO_WRAP)
.blockingGet();
AsymmetricCipherProvider.decodePrivateKey(encodedPrivateKey)
.test()
.assertValue(ecPrivateKey -> ecPrivateKey.getAlgorithm().equals("ECDSA"))
.assertValue(ecPrivateKey -> ecPrivateKey.getFormat().equals("PKCS#8"))
.assertValue(ecPrivateKey -> ecPrivateKey.getS().equals(new BigInteger("97981148271098500605815445696501709458330601205038959054259534545461596459409")));
}
public static ECPublicKey decodePublicKey(String encodedKey) {
return RxBase64.decode(encodedKey)
.flatMap(AsymmetricCipherProvider::decodePublicKey)
.blockingGet();
}
public static ECPrivateKey decodePrivateKey(String encodedKey) {
return RxBase64.decode(encodedKey)
.flatMap(AsymmetricCipherProvider::decodePrivateKey)
.blockingGet();
}
}
\ No newline at end of file
package de.culture4life.luca.crypto;
import android.util.Base64;
import com.nexenio.rxkeystore.util.RxBase64;