- Added Pocket Security Functionality (still in progress...)
This commit is contained in:
parent
5b21c0719e
commit
6117fc0f99
14 changed files with 429 additions and 6 deletions
|
@ -1,4 +1,5 @@
|
|||
apply plugin: 'com.android.application'
|
||||
apply plugin: 'kotlin-android'
|
||||
|
||||
android {
|
||||
compileSdkVersion 27
|
||||
|
@ -79,4 +80,6 @@ dependencies {
|
|||
implementation 'id.zelory:compressor:2.1.0'
|
||||
implementation 'com.vincent.filepicker:MultiTypeFilePicker:1.0.7'
|
||||
implementation 'com.andrognito.patternlockview:patternlockview:1.0.0'
|
||||
implementation 'commons-codec:commons-codec:1.11'
|
||||
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.NFC" />
|
||||
|
||||
<application
|
||||
android:name=".application.CrystalApplication"
|
||||
|
@ -52,6 +53,21 @@
|
|||
<activity android:name=".activities.PatternRequestActivity"
|
||||
android:noHistory="true">
|
||||
</activity>
|
||||
<activity android:name=".activities.PocketRequestActivity"
|
||||
android:noHistory="true">
|
||||
<!--<meta-data
|
||||
android:name="android.nfc.action.TECH_DISCOVERED"
|
||||
android:resource="@xml/tech" />-->
|
||||
<intent-filter>
|
||||
<action android:name="android.nfc.action.NDEF_DISCOVERED"/>
|
||||
<category android:name="android.intent.category.DEFAULT"/>
|
||||
<data
|
||||
android:scheme="https"
|
||||
android:host="my.yubico.com"
|
||||
android:pathPrefix="/neo"/>
|
||||
</intent-filter>
|
||||
|
||||
</activity>
|
||||
<activity android:name=".activities.CryptoNetAccountSettingsActivity"
|
||||
android:theme="@style/AppTheme.NoActionBar"
|
||||
android:windowSoftInputMode="adjustPan">
|
||||
|
@ -60,6 +76,14 @@
|
|||
android:name=".activities.SettingsActivity"
|
||||
android:theme="@style/AppTheme.NoActionBar"
|
||||
android:windowSoftInputMode="adjustPan">
|
||||
<intent-filter>
|
||||
<action android:name="android.nfc.action.NDEF_DISCOVERED"/>
|
||||
<category android:name="android.intent.category.DEFAULT"/>
|
||||
<data
|
||||
android:scheme="https"
|
||||
android:host="my.yubico.com"
|
||||
android:pathPrefix="/neo"/>
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".activities.AccountsActivity"
|
||||
|
|
|
@ -95,6 +95,7 @@ public class IntroActivity extends AppCompatActivity {
|
|||
} else {
|
||||
//Intent intent = new Intent(this, CreateSeedActivity.class);
|
||||
Intent intent = new Intent(this, BoardActivity.class);
|
||||
//Intent intent = new Intent(this, PocketRequestActivity.class);
|
||||
startActivity(intent);
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,130 @@
|
|||
package cy.agorise.crystalwallet.activities;
|
||||
|
||||
import android.app.PendingIntent;
|
||||
import android.arch.lifecycle.LiveData;
|
||||
import android.arch.lifecycle.Observer;
|
||||
import android.arch.lifecycle.ViewModelProviders;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.nfc.NfcAdapter;
|
||||
import android.nfc.Tag;
|
||||
import android.nfc.tech.IsoDep;
|
||||
import android.nfc.tech.MifareClassic;
|
||||
import android.nfc.tech.NdefFormatable;
|
||||
import android.nfc.tech.NfcA;
|
||||
import android.nfc.tech.NfcF;
|
||||
import android.nfc.tech.NfcV;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.util.Log;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.andrognito.patternlockview.PatternLockView;
|
||||
import com.andrognito.patternlockview.listener.PatternLockViewListener;
|
||||
|
||||
import org.apache.commons.codec.binary.Base32;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import cy.agorise.crystalwallet.R;
|
||||
import cy.agorise.crystalwallet.models.GeneralSetting;
|
||||
import cy.agorise.crystalwallet.util.PasswordManager;
|
||||
import cy.agorise.crystalwallet.util.yubikey.Algorithm;
|
||||
import cy.agorise.crystalwallet.util.yubikey.OathType;
|
||||
import cy.agorise.crystalwallet.util.yubikey.YkOathApi;
|
||||
import cy.agorise.crystalwallet.viewmodels.GeneralSettingListViewModel;
|
||||
|
||||
public class PocketRequestActivity extends AppCompatActivity {
|
||||
|
||||
private NfcAdapter mNfcAdapter;
|
||||
private PendingIntent pendingIntent;
|
||||
private IntentFilter ndef;
|
||||
IntentFilter[] intentFiltersArray;
|
||||
String[][] techList;
|
||||
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
//Do nothing to prevent the user to use the back button
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_pocket_request);
|
||||
ButterKnife.bind(this);
|
||||
|
||||
mNfcAdapter = NfcAdapter.getDefaultAdapter(this);
|
||||
|
||||
this.configureForegroundDispatch();
|
||||
}
|
||||
|
||||
public void configureForegroundDispatch(){
|
||||
if (mNfcAdapter != null) {
|
||||
pendingIntent = PendingIntent.getActivity(
|
||||
this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
|
||||
|
||||
ndef = new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED);
|
||||
try {
|
||||
ndef.addDataType("*/*"); /* Handles all MIME based dispatches.
|
||||
You should specify only the ones that you need. */
|
||||
} catch (IntentFilter.MalformedMimeTypeException e) {
|
||||
throw new RuntimeException("fail", e);
|
||||
}
|
||||
intentFiltersArray = new IntentFilter[]{ndef,};
|
||||
techList = new String[][]{ new String[] {IsoDep.class.getName(), NfcA.class.getName(), MifareClassic.class.getName(), NdefFormatable.class.getName()} };
|
||||
|
||||
} else {
|
||||
Toast.makeText(this, "This device doesn't support NFC.", Toast.LENGTH_LONG).show();
|
||||
}
|
||||
}
|
||||
|
||||
public void onPause() {
|
||||
super.onPause();
|
||||
if (mNfcAdapter != null) {
|
||||
mNfcAdapter.disableForegroundDispatch(this);
|
||||
}
|
||||
}
|
||||
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
if (mNfcAdapter != null) {
|
||||
mNfcAdapter.enableForegroundDispatch(this, pendingIntent, intentFiltersArray, techList);
|
||||
}
|
||||
}
|
||||
|
||||
public void onNewIntent(Intent intent) {
|
||||
Tag tagFromIntent = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
|
||||
IsoDep tagIsoDep = IsoDep.get(tagFromIntent);
|
||||
Log.i("Tag from nfc","New Intent");
|
||||
try {
|
||||
|
||||
String encodedSecret = "hola";
|
||||
Base32 decoder = new Base32();
|
||||
|
||||
if ((encodedSecret != null) && (!encodedSecret.equals("")) && decoder.isInAlphabet(encodedSecret)) {
|
||||
byte[] secret = decoder.decode(encodedSecret);
|
||||
YkOathApi ykOathApi = new YkOathApi();
|
||||
tagIsoDep.connect();
|
||||
tagIsoDep.setTimeout(15000);
|
||||
|
||||
//byte[] keyBytes = {0x68,0x6f,0x6c,0x61};
|
||||
ykOathApi.putCode(tagIsoDep,"prueba",secret, OathType.TOTP, Algorithm.SHA256,(byte)6,0,false);
|
||||
tagIsoDep.close();
|
||||
|
||||
Toast.makeText(this, "Credential saved!", Toast.LENGTH_LONG).show();
|
||||
} else {
|
||||
Toast.makeText(this, "Invalid password for credential", Toast.LENGTH_LONG).show();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
Toast.makeText(this, "Tag from nfc: "+tagFromIntent, Toast.LENGTH_LONG).show();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
package cy.agorise.crystalwallet.activities;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.media.MediaPlayer;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.Fragment;
|
||||
|
@ -47,6 +48,8 @@ public class SettingsActivity extends AppCompatActivity{
|
|||
@BindView(R.id.tvBuildVersion)
|
||||
public TextView tvBuildVersion;
|
||||
|
||||
private SecuritySettingsFragment securitySettingsFragment;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
@ -97,7 +100,8 @@ public class SettingsActivity extends AppCompatActivity{
|
|||
case 0:
|
||||
return new GeneralSettingsFragment();
|
||||
case 1:
|
||||
return new SecuritySettingsFragment();
|
||||
securitySettingsFragment = new SecuritySettingsFragment();
|
||||
return securitySettingsFragment;
|
||||
case 2:
|
||||
return new BackupsSettingsFragment();
|
||||
//case 3:
|
||||
|
@ -123,4 +127,12 @@ public class SettingsActivity extends AppCompatActivity{
|
|||
public void goBack(){
|
||||
onBackPressed();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onNewIntent(Intent intent) {
|
||||
super.onNewIntent(intent);
|
||||
if (this.securitySettingsFragment != null){
|
||||
this.securitySettingsFragment.onNewIntent(intent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@ public class CrystalSecurityMonitor implements Application.ActivityLifecycleCall
|
|||
private int numStarted = 0;
|
||||
private String passwordEncrypted;
|
||||
private String patternEncrypted;
|
||||
private String yubikeyOathTotpPasswordEncrypted;
|
||||
|
||||
private static CrystalSecurityMonitor instance;
|
||||
private GeneralSettingListViewModel generalSettingListViewModel;
|
||||
|
@ -38,8 +39,10 @@ public class CrystalSecurityMonitor implements Application.ActivityLifecycleCall
|
|||
|
||||
this.passwordEncrypted = "";
|
||||
this.patternEncrypted = "";
|
||||
this.yubikeyOathTotpPasswordEncrypted = "";
|
||||
GeneralSetting passwordGeneralSetting = generalSettingListViewModel.getGeneralSettingByName(GeneralSetting.SETTING_PASSWORD);;
|
||||
GeneralSetting patternGeneralSetting = generalSettingListViewModel.getGeneralSettingByName(GeneralSetting.SETTING_PATTERN);;
|
||||
GeneralSetting yubikeyOathTotpPasswordSetting = generalSettingListViewModel.getGeneralSettingByName(GeneralSetting.SETTING_YUBIKEY_OATH_TOTP_PASSWORD);;
|
||||
|
||||
if (passwordGeneralSetting != null){
|
||||
this.passwordEncrypted = passwordGeneralSetting.getValue();
|
||||
|
@ -47,6 +50,9 @@ public class CrystalSecurityMonitor implements Application.ActivityLifecycleCall
|
|||
if (patternGeneralSetting != null){
|
||||
this.patternEncrypted = patternGeneralSetting.getValue();
|
||||
}
|
||||
if (yubikeyOathTotpPasswordSetting != null){
|
||||
this.yubikeyOathTotpPasswordEncrypted = yubikeyOathTotpPasswordSetting.getValue();
|
||||
}
|
||||
}
|
||||
|
||||
public static CrystalSecurityMonitor getInstance(final FragmentActivity fragmentActivity){
|
||||
|
@ -57,6 +63,10 @@ public class CrystalSecurityMonitor implements Application.ActivityLifecycleCall
|
|||
return instance;
|
||||
}
|
||||
|
||||
public static String getServiceName(){
|
||||
return "cy.agorise.crystalwallet";
|
||||
}
|
||||
|
||||
public void clearSecurity(){
|
||||
this.patternEncrypted = "";
|
||||
this.passwordEncrypted = "";
|
||||
|
@ -65,6 +75,12 @@ public class CrystalSecurityMonitor implements Application.ActivityLifecycleCall
|
|||
generalSettingListViewModel.deleteGeneralSettingByName(GeneralSetting.SETTING_PATTERN);
|
||||
}
|
||||
|
||||
public void clearSecurity2ndFactor(){
|
||||
this.yubikeyOathTotpPasswordEncrypted = "";
|
||||
|
||||
generalSettingListViewModel.deleteGeneralSettingByName(GeneralSetting.SETTING_YUBIKEY_OATH_TOTP_PASSWORD);
|
||||
}
|
||||
|
||||
public void setPasswordSecurity(String password){
|
||||
clearSecurity();
|
||||
this.passwordEncrypted = password;
|
||||
|
@ -95,6 +111,15 @@ public class CrystalSecurityMonitor implements Application.ActivityLifecycleCall
|
|||
return "";
|
||||
}
|
||||
|
||||
public void setYubikeyOathTotpSecurity(String name, String password){
|
||||
this.yubikeyOathTotpPasswordEncrypted = password;
|
||||
GeneralSetting yubikeyOathTotpSetting = new GeneralSetting();
|
||||
yubikeyOathTotpSetting.setName(GeneralSetting.SETTING_YUBIKEY_OATH_TOTP_PASSWORD);
|
||||
yubikeyOathTotpSetting.setValue(password);
|
||||
|
||||
generalSettingListViewModel.saveGeneralSetting(yubikeyOathTotpSetting);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityStarted(Activity activity) {
|
||||
if (numStarted == 0) {
|
||||
|
|
|
@ -1,20 +1,42 @@
|
|||
package cy.agorise.crystalwallet.fragments;
|
||||
|
||||
import android.app.PendingIntent;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.nfc.NfcAdapter;
|
||||
import android.nfc.Tag;
|
||||
import android.nfc.tech.IsoDep;
|
||||
import android.nfc.tech.MifareClassic;
|
||||
import android.nfc.tech.NdefFormatable;
|
||||
import android.nfc.tech.NfcA;
|
||||
import android.os.Bundle;
|
||||
import android.support.design.widget.TabLayout;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.app.FragmentManager;
|
||||
import android.support.v4.app.FragmentPagerAdapter;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.CompoundButton;
|
||||
import android.widget.EditText;
|
||||
import android.widget.Switch;
|
||||
import android.widget.Toast;
|
||||
|
||||
import org.apache.commons.codec.binary.Base32;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.OnCheckedChanged;
|
||||
import cy.agorise.crystalwallet.R;
|
||||
import cy.agorise.crystalwallet.application.CrystalSecurityMonitor;
|
||||
import cy.agorise.crystalwallet.models.GeneralSetting;
|
||||
import cy.agorise.crystalwallet.util.ChildViewPager;
|
||||
import cy.agorise.crystalwallet.util.yubikey.Algorithm;
|
||||
import cy.agorise.crystalwallet.util.yubikey.OathType;
|
||||
import cy.agorise.crystalwallet.util.yubikey.YkOathApi;
|
||||
|
||||
/**
|
||||
* Created by xd on 1/17/18.
|
||||
|
@ -34,11 +56,23 @@ public class SecuritySettingsFragment extends Fragment {
|
|||
return fragment;
|
||||
}
|
||||
|
||||
private NfcAdapter mNfcAdapter;
|
||||
private PendingIntent pendingIntent;
|
||||
private IntentFilter ndef;
|
||||
IntentFilter[] intentFiltersArray;
|
||||
String[][] techList;
|
||||
|
||||
|
||||
@BindView(R.id.pager)
|
||||
public ChildViewPager mPager;
|
||||
|
||||
public SecurityPagerAdapter securityPagerAdapter;
|
||||
|
||||
@BindView(R.id.sPocketSecurity)
|
||||
Switch sPocketSecurity;
|
||||
@BindView(R.id.etPocketPassword)
|
||||
EditText etPocketPassword;
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
|
@ -66,6 +100,9 @@ public class SecuritySettingsFragment extends Fragment {
|
|||
mPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
|
||||
tabLayout.addOnTabSelectedListener(new TabLayout.ViewPagerOnTabSelectedListener(mPager));
|
||||
|
||||
mNfcAdapter = NfcAdapter.getDefaultAdapter(this.getActivity());
|
||||
this.configureForegroundDispatch();
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
|
@ -101,4 +138,87 @@ public class SecuritySettingsFragment extends Fragment {
|
|||
return 3;
|
||||
}
|
||||
}
|
||||
|
||||
@OnCheckedChanged(R.id.sPocketSecurity)
|
||||
public void onPocketSecurityActivated(CompoundButton button, boolean checked){
|
||||
if (checked) {
|
||||
enableNfc();
|
||||
} else {
|
||||
disableNfc();
|
||||
}
|
||||
}
|
||||
|
||||
public void configureForegroundDispatch(){
|
||||
if (mNfcAdapter != null) {
|
||||
pendingIntent = PendingIntent.getActivity(
|
||||
this.getActivity(), 0, new Intent(this.getActivity(), getActivity().getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
|
||||
|
||||
ndef = new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED);
|
||||
try {
|
||||
ndef.addDataType("*/*"); /* Handles all MIME based dispatches.
|
||||
You should specify only the ones that you need. */
|
||||
} catch (IntentFilter.MalformedMimeTypeException e) {
|
||||
throw new RuntimeException("fail", e);
|
||||
}
|
||||
intentFiltersArray = new IntentFilter[]{ndef,};
|
||||
techList = new String[][]{ new String[] {IsoDep.class.getName(), NfcA.class.getName(), MifareClassic.class.getName(), NdefFormatable.class.getName()} };
|
||||
|
||||
} else {
|
||||
Toast.makeText(this.getContext(), "This device doesn't support NFC.", Toast.LENGTH_LONG).show();
|
||||
}
|
||||
}
|
||||
|
||||
public void enableNfc(){
|
||||
mNfcAdapter.enableForegroundDispatch(this.getActivity(), pendingIntent, intentFiltersArray, techList);
|
||||
Toast.makeText(this.getContext(), "Tap with your yubikey", Toast.LENGTH_LONG).show();
|
||||
}
|
||||
|
||||
public void disableNfc(){
|
||||
mNfcAdapter.disableForegroundDispatch(this.getActivity());
|
||||
}
|
||||
|
||||
public void onPause() {
|
||||
super.onPause();
|
||||
disableNfc();
|
||||
}
|
||||
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
if (mNfcAdapter != null) {
|
||||
enableNfc();
|
||||
}
|
||||
}
|
||||
|
||||
public void onNewIntent(Intent intent) {
|
||||
Tag tagFromIntent = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
|
||||
IsoDep tagIsoDep = IsoDep.get(tagFromIntent);
|
||||
Log.i("Tag from nfc","New Intent");
|
||||
try {
|
||||
|
||||
String serviceName = "cy.agorise.crystalwallet";
|
||||
String encodedSecret = etPocketPassword.getText().toString();
|
||||
Base32 decoder = new Base32();
|
||||
|
||||
if ((encodedSecret != null) && (!encodedSecret.equals("")) && decoder.isInAlphabet(encodedSecret)) {
|
||||
byte[] secret = decoder.decode(encodedSecret);
|
||||
YkOathApi ykOathApi = new YkOathApi();
|
||||
tagIsoDep.connect();
|
||||
tagIsoDep.setTimeout(15000);
|
||||
|
||||
try {
|
||||
ykOathApi.putCode(tagIsoDep, serviceName, secret, OathType.TOTP, Algorithm.SHA256, (byte) 6, 0, false);
|
||||
CrystalSecurityMonitor.getInstance(null).setYubikeyOathTotpSecurity(CrystalSecurityMonitor.getServiceName(),encodedSecret);
|
||||
} catch(IOException e) {
|
||||
Toast.makeText(this.getContext(), "There's no space for new credentials!", Toast.LENGTH_LONG).show();
|
||||
}
|
||||
|
||||
tagIsoDep.close();
|
||||
Toast.makeText(this.getContext(), "Credential saved!", Toast.LENGTH_LONG).show();
|
||||
} else {
|
||||
Toast.makeText(this.getContext(), "Invalid password for credential", Toast.LENGTH_LONG).show();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,6 +23,8 @@ public class GeneralSetting {
|
|||
public final static String SETTING_PATTERN = "PATTERN";
|
||||
public final static String SETTING_NAME_RECEIVED_FUNDS_SOUND_PATH = "RECEIVED_FUNDS_SOUND_PATH";
|
||||
public final static String SETTING_LAST_LICENSE_READ = "LAST_LICENSE_READ";
|
||||
public final static String SETTING_YUBIKEY_OATH_TOTP_NAME = "YUBIKEY_OATH_TOTP_NAME";
|
||||
public final static String SETTING_YUBIKEY_OATH_TOTP_PASSWORD = "YUBIKEY_OATH_TOTP_PASSWORD";
|
||||
|
||||
/**
|
||||
* The id on the database
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
package cy.agorise.crystalwallet.util.yubikey;
|
||||
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.Arrays;
|
||||
|
||||
import kotlin.jvm.internal.Intrinsics;
|
||||
|
||||
public enum Algorithm {
|
||||
SHA1((byte)1, "SHA1", 64),
|
||||
SHA256((byte)2, "SHA256", 64),
|
||||
SHA512((byte)3, "SHA512", 128);
|
||||
|
||||
protected Byte byteVal;
|
||||
protected String name;
|
||||
protected int blockSize;
|
||||
protected MessageDigest messageDigest;
|
||||
|
||||
Algorithm(Byte byteVal, String name, int blockSize){
|
||||
this.byteVal = byteVal;
|
||||
this.name = name;
|
||||
this.blockSize = blockSize;
|
||||
|
||||
try {
|
||||
this.messageDigest = MessageDigest.getInstance(name);
|
||||
} catch (NoSuchAlgorithmException e){
|
||||
this.messageDigest = null;
|
||||
}
|
||||
}
|
||||
|
||||
public Byte getByteVal(){
|
||||
return this.byteVal;
|
||||
}
|
||||
|
||||
public String getName(){
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public int getBlockSize() {
|
||||
return this.blockSize;
|
||||
}
|
||||
|
||||
public byte[] prepareKey(byte[] key){
|
||||
int keyLength = key.length;
|
||||
byte[] keyPrepared;
|
||||
if ((0 <= keyLength) && (keyLength <= 13)) {
|
||||
keyPrepared = Arrays.copyOf(key, 14);
|
||||
return keyPrepared;
|
||||
}
|
||||
if ((14 <= keyLength) && (keyLength <= this.blockSize)){
|
||||
keyPrepared = key;
|
||||
return keyPrepared;
|
||||
}
|
||||
|
||||
keyPrepared = this.messageDigest.digest(key);
|
||||
return keyPrepared;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
package cy.agorise.crystalwallet.util.yubikey;
|
||||
|
||||
public enum OathType {
|
||||
HOTP((byte)0x10),
|
||||
TOTP((byte)0x20);
|
||||
|
||||
protected Byte byteVal;
|
||||
|
||||
OathType(Byte byteVal){
|
||||
this.byteVal = byteVal;
|
||||
}
|
||||
|
||||
public Byte getByteVal(){
|
||||
return this.byteVal;
|
||||
}
|
||||
}
|
18
app/src/main/res/layout/activity_pocket_request.xml
Normal file
18
app/src/main/res/layout/activity_pocket_request.xml
Normal file
|
@ -0,0 +1,18 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:gravity="center"
|
||||
android:padding="5dp"
|
||||
android:background="@color/colorPrimary">
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Please tap pocket!"/>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
|
@ -68,7 +68,7 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="140dp"
|
||||
android:background="@color/lightGray"
|
||||
android:visibility="gone"
|
||||
android:visibility="visible"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
@ -107,10 +107,9 @@
|
|||
android:id="@+id/etPocketPassword"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:inputType="numberPassword"
|
||||
app:layout_constraintTop_toBottomOf="@id/tvPocketSecurityUser"
|
||||
app:layout_constraintStart_toStartOf="@id/tvPocketSecurity"
|
||||
app:layout_constraintEnd_toEndOf="@id/sPocketSecurity"
|
||||
app:layout_constraintStart_toStartOf="@id/tvPocketSecurity"
|
||||
app:layout_constraintTop_toBottomOf="@id/tvPocketSecurityUser"
|
||||
tools:ignore="LabelFor" />
|
||||
|
||||
</android.support.constraint.ConstraintLayout>
|
13
app/src/main/res/xml/tech.xml
Normal file
13
app/src/main/res/xml/tech.xml
Normal file
|
@ -0,0 +1,13 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<tech-list>
|
||||
<tech>android.nfc.tech.MifareUltralight</tech>
|
||||
<tech>android.nfc.tech.Ndef</tech>
|
||||
<tech>android.nfc.tech.NfcA</tech>
|
||||
</tech-list>
|
||||
<tech-list>
|
||||
<tech>android.nfc.tech.MifareClassic</tech>
|
||||
<tech>android.nfc.tech.Ndef</tech>
|
||||
<tech>android.nfc.tech.NfcA</tech>
|
||||
</tech-list>
|
||||
</resources>
|
|
@ -5,9 +5,11 @@ buildscript {
|
|||
jcenter()
|
||||
google()
|
||||
}
|
||||
ext.kotlin_version = '1.2.51'
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:3.1.3'
|
||||
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
// in the individual module build.gradle files
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue