Skip to content

Commit

Permalink
Merge pull request #38 from markmcavoy/feature/nextVersion
Browse files Browse the repository at this point in the history
Feature/next version
  • Loading branch information
markmcavoy authored Feb 25, 2021
2 parents 4e749a4 + 70354a5 commit 7ea434c
Show file tree
Hide file tree
Showing 55 changed files with 3,035 additions and 1,650 deletions.
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Copyright Mark McAvoy - www.bitethebullet.co.uk 2009
Copyright Mark McAvoy - www.bitethebullet.co.uk 2009 - 2021

This file is part of Android Token.

Expand Down
17 changes: 10 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
Android Token
Auth Token (formerly, Android Token)
=============
Android Token is a project to create http://www.openauthentication.org/ software tokens for the Android platform. Turning a mobile phone into a One Time Password (OTP) generation device which can be used in the place of hardware tokens.
Auth Token, (formerly Android Token) is an Android applicaion used to generate one time passwords (OTP). The application is open source and written in Java. The application supports both HOTP (event tokens, http://tools.ietf.org/html/rfc4226) and TOTP tokens (time tokens, http://tools.ietf.org/html/draft-mraihi-totp-timebased-00).

Support for provisioning tokens using the https://github.com/google/google-authenticator/wiki/Key-Uri-Format KeyUriFormat and QR codes as well as manual creation.
The application supports provisioning tokens using
- [KeyUriFormat](https://github.com/google/google-authenticator/wiki/Key-Uri-Format)
- QR codes
- Manual creation.

The application can optionally be protected with a PIN to stop unauthorised access to the software tokens.

The project supports both http://tools.ietf.org/html/rfc4226 (Event Tokens) and http://tools.ietf.org/html/draft-mraihi-totp-timebased-00 (Time Tokens) specifications.
Tokens can be exported as a QR code or by manually copying the seed to the clipboard.

Screen Shots
------------

![alt tag](https://github.com/markmcavoy/androidtoken/blob/wiki/screenshot1.png)
![alt tag](https://github.com/markmcavoy/androidtoken/blob/wiki/screenshot2.png)
![Main View](https://github.com/markmcavoy/androidtoken/blob/wiki/mainlist.png)
![Manually adding a new token](https://github.com/markmcavoy/androidtoken/blob/wiki/add_token.png)
![Settings page](https://github.com/markmcavoy/androidtoken/blob/wiki/settings.png)
21 changes: 15 additions & 6 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ buildscript {
}
repositories {
mavenCentral()
jcenter()
maven {
url "https://maven.google.com"
}
Expand All @@ -29,10 +30,10 @@ android {
}

defaultConfig {
minSdkVersion 8
minSdkVersion 21
targetSdkVersion 30
versionCode 6
versionName "2.11"
versionName "3.0"
}

packagingOptions {
Expand All @@ -41,11 +42,19 @@ android {
}

dependencies {

implementation "androidx.preference:preference:1.1.0"
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
implementation 'com.google.android.material:material:1.1.0'
implementation 'androidx.biometric:biometric:1.0.1'
implementation 'androidx.navigation:navigation-fragment:2.3.0'
implementation 'androidx.navigation:navigation-ui:2.3.0'
implementation 'androidmads.library.qrgenearator:QRGenearator:1.0.4'
implementation 'com.google.zxing:core:3.3.2'

testImplementation 'junit:junit:4.13'
testImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
testImplementation 'com.google.truth:truth:1.0.1'

//androidTestImplementation 'junit:junit:4.13'
//androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
//androidTestImplementation 'com.google.truth:truth:0.40'
}
19 changes: 19 additions & 0 deletions gradle.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Project-wide Gradle settings.
# IDE (e.g. Android Studio) users:
# Gradle settings configured through the IDE *will override*
# any settings specified in this file.
# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
org.gradle.jvmargs=-Xmx2048m
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true
# AndroidX package structure to make it clearer which packages are bundled with the
# Android operating system, and which are packaged with your app"s APK
# https://developer.android.com/topic/libraries/support-library/androidx-rn
android.useAndroidX=true
# Automatically convert third-party libraries to use AndroidX
android.enableJetifier=true
2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.5.1-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-6.5.1-all.zip
68 changes: 42 additions & 26 deletions src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,37 +1,53 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="uk.co.bitethebullet.android.token"
android:versionCode="5"
android:versionName="2.10"
android:installLocation="auto">
package="uk.co.bitethebullet.android.token"
android:installLocation="auto"
android:versionCode="6"
android:versionName="3.00">

<supports-screens
android:largeScreens="true"
android:normalScreens="true"
android:smallScreens="true"
android:anyDensity="true" />

<application android:label="@string/app_name" android:icon="@drawable/androidtoken">
<activity android:name=".TokenList"
android:label="@string/app_name">
android:anyDensity="true"
android:largeScreens="true"
android:normalScreens="true"
android:smallScreens="true" />

<uses-permission android:name="android.permission.USE_BIOMETRIC" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

<application
android:icon="@drawable/androidtoken"
android:label="@string/app_name"
android:theme="@style/Theme.AppCompat.Light">
<activity android:name=".QRCodeActivity"></activity>
<activity android:name=".SettingActivity" />
<activity
android:name=".TokenList"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<action android:name="android.intent.action.VIEW" />

<category android:name="android.intent.category.DEFAULT" />

<data android:scheme="otpauth" />
</intent-filter>
</intent-filter>
</activity>
<activity
android:name=".TokenAdd"
android:label="@string/app_name_add" />
<activity
android:name=".PinChange"
android:label="@string/app_name_change_pin" />
<activity
android:name=".PinRemove"
android:label="@string/app_name" />
<activity
android:name=".About"
android:label="@string/app_name_about" />
</application>

<activity android:name=".TokenAdd" android:label="@string/app_name"></activity>
<activity android:name=".PinChange" android:label="@string/app_name"></activity>
<activity android:label="@string/app_name" android:name=".PinRemove"></activity>

<activity android:name="com.google.ads.AdActivity"/>
<activity android:name="Circle"></activity>

</application>

</manifest>
</manifest>
Binary file added src/main/assets/fonts/fa-brands-400.ttf
Binary file not shown.
Binary file added src/main/assets/fonts/fa-regular-400.ttf
Binary file not shown.
Binary file added src/main/assets/fonts/fa-solid-900.ttf
Binary file not shown.
33 changes: 33 additions & 0 deletions src/main/java/uk/co/bitethebullet/android/token/About.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package uk.co.bitethebullet.android.token;

import android.os.Bundle;
import android.text.method.LinkMovementMethod;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

import androidx.appcompat.app.AppCompatActivity;

public class About extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.about);

setupHyperlink();
}

public void closeHandler(View v){
finish();
}

private void setupHyperlink() {
TextView linkTextView = findViewById(R.id.about_url);
TextView linkZalabria = findViewById(R.id.about_info);

linkTextView.setMovementMethod(LinkMovementMethod.getInstance());
linkZalabria.setMovementMethod(LinkMovementMethod.getInstance());
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright Mark McAvoy - www.bitethebullet.co.uk 2009
* Copyright Mark McAvoy - www.bitethebullet.co.uk 2009 - 2020
*
* This file is part of Android Token.
*
Expand Down Expand Up @@ -29,7 +29,9 @@
import android.widget.Button;
import android.widget.EditText;

public class PinChange extends Activity {
import androidx.appcompat.app.AppCompatActivity;

public class PinChange extends AppCompatActivity {

private static final int DIALOG_INVALID_EXISTING_PIN = 0;
private static final int DIALOG_DIFF_NEW_PIN = 1;
Expand Down
70 changes: 30 additions & 40 deletions src/main/java/uk/co/bitethebullet/android/token/PinManager.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright Mark McAvoy - www.bitethebullet.co.uk 2009
* Copyright Mark McAvoy - www.bitethebullet.co.uk 2009 - 2020
*
* This file is part of Android Token.
*
Expand All @@ -23,61 +23,51 @@
import java.security.NoSuchAlgorithmException;

import android.content.Context;
import android.content.SharedPreferences;
import android.database.Cursor;

import androidx.preference.PreferenceManager;

import uk.co.bitethebullet.android.token.datalayer.TokenDbAdapter;
import uk.co.bitethebullet.android.token.tokens.HotpToken;

public class PinManager {

private static final String SALT = "EE08F4A6-8497-4330-8CD5-8A4ABD93CD46";
public static final String PIN_CODE_SETTING = "PIN_CODE";

public static Boolean hasPinDefined(Context c){
TokenDbAdapter db = new TokenDbAdapter(c);
db.open();

Cursor cursor = db.fetchPin();

Boolean hasPin = cursor.getCount() > 0;

cursor.close();
db.close();

return hasPin;
SharedPreferences sharedPreferences =
PreferenceManager.getDefaultSharedPreferences(c);

return sharedPreferences.getString("securityLock", "0").equals("1");
}

public static Boolean validatePin(Context c, String pin){

TokenDbAdapter db = new TokenDbAdapter(c);
db.open();
SharedPreferences sharedPreferences =
PreferenceManager.getDefaultSharedPreferences(c);
String storedPin = sharedPreferences.getString(PIN_CODE_SETTING, "");

Boolean isValid = false;
String userPin = createPinHash(pin);
Cursor cursor = db.fetchPin();

if(cursor != null){
String dbPin = cursor.getString(cursor.getColumnIndexOrThrow(TokenDbAdapter.KEY_PIN_HASH));
isValid = dbPin.contentEquals(userPin);
}

cursor.close();
db.close();

return isValid;
return storedPin.equals(pin);
}

public static void storePin(Context c, String pin){
TokenDbAdapter db = new TokenDbAdapter(c);
db.open();
db.createOrUpdatePin(createPinHash(pin));
db.close();
SharedPreferences sharedPreferences =
PreferenceManager.getDefaultSharedPreferences(c);
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putString(PinManager.PIN_CODE_SETTING, pin);
editor.commit();
}

public static void removePin(Context c){
TokenDbAdapter db = new TokenDbAdapter(c);
db.open();
db.deletePin();
db.close();
}
// public static void removePin(Context c){
// TokenDbAdapter db = new TokenDbAdapter(c);
// db.open();
//
// db.deletePin();
//
// db.close();
// }

private static String createPinHash(String pin) {

Expand All @@ -90,7 +80,7 @@ private static String createPinHash(String pin) {
md.update(toHash.getBytes());
byte[] hashOutput = md.digest();

return HotpToken.byteArrayToHexString(hashOutput);
return HotpToken.byteArrayToHexString(hashOutput);

}catch(NoSuchAlgorithmException ex){
return null;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright Mark McAvoy - www.bitethebullet.co.uk 2009
* Copyright Mark McAvoy - www.bitethebullet.co.uk 2009 - 2020
*
* This file is part of Android Token.
*
Expand Down Expand Up @@ -50,7 +50,8 @@ public void onClick(View v) {
String pin = ((EditText)findViewById(R.id.pinRemoveExistingPinEdit)).getText().toString();

if(PinManager.validatePin(v.getContext(), pin)){
PinManager.removePin(v.getContext());
//todo: MM fix me
//PinManager.removePin(v.getContext());
finish();
}else{
// the pin isn't the same as the one stored, do nothing
Expand Down
Loading

0 comments on commit 7ea434c

Please sign in to comment.