mirror of
https://github.com/TanelOrumaa/Estonian-ID-card-mobile-authenticator-POC.git
synced 2024-12-22 20:40:16 +02:00
Added basic notifications to the user
For when exceptions occur when communicating with the ID-card
This commit is contained in:
parent
c51f0e4277
commit
73efb00368
@ -5,7 +5,6 @@ import android.nfc.NfcAdapter
|
|||||||
import android.nfc.tech.IsoDep
|
import android.nfc.tech.IsoDep
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.os.CountDownTimer
|
import android.os.CountDownTimer
|
||||||
import android.util.Log
|
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
@ -15,10 +14,14 @@ import androidx.fragment.app.activityViewModels
|
|||||||
import androidx.navigation.fragment.findNavController
|
import androidx.navigation.fragment.findNavController
|
||||||
import androidx.navigation.fragment.navArgs
|
import androidx.navigation.fragment.navArgs
|
||||||
import com.tarkvaraprojekt.mobileauthapp.NFC.Comms
|
import com.tarkvaraprojekt.mobileauthapp.NFC.Comms
|
||||||
|
import com.tarkvaraprojekt.mobileauthapp.auth.AuthAppException
|
||||||
|
import com.tarkvaraprojekt.mobileauthapp.auth.InvalidCANException
|
||||||
import com.tarkvaraprojekt.mobileauthapp.databinding.FragmentAuthBinding
|
import com.tarkvaraprojekt.mobileauthapp.databinding.FragmentAuthBinding
|
||||||
import com.tarkvaraprojekt.mobileauthapp.model.ParametersViewModel
|
import com.tarkvaraprojekt.mobileauthapp.model.ParametersViewModel
|
||||||
import com.tarkvaraprojekt.mobileauthapp.model.SmartCardViewModel
|
import com.tarkvaraprojekt.mobileauthapp.model.SmartCardViewModel
|
||||||
|
import java.io.IOException
|
||||||
import java.lang.Exception
|
import java.lang.Exception
|
||||||
|
import java.security.GeneralSecurityException
|
||||||
import kotlin.system.exitProcess
|
import kotlin.system.exitProcess
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -80,6 +83,8 @@ class AuthFragment : Fragment() {
|
|||||||
requireActivity().runOnUiThread {
|
requireActivity().runOnUiThread {
|
||||||
binding!!.timeCounter.text = getString(R.string.card_detected)
|
binding!!.timeCounter.text = getString(R.string.card_detected)
|
||||||
}
|
}
|
||||||
|
var msgCode = 0
|
||||||
|
|
||||||
val card = IsoDep.get(tag)
|
val card = IsoDep.get(tag)
|
||||||
card.timeout = 32768
|
card.timeout = 32768
|
||||||
card.use {
|
card.use {
|
||||||
@ -95,17 +100,36 @@ class AuthFragment : Fragment() {
|
|||||||
requireActivity().runOnUiThread {
|
requireActivity().runOnUiThread {
|
||||||
binding!!.timeCounter.text = getString(R.string.data_read)
|
binding!!.timeCounter.text = getString(R.string.data_read)
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
|
||||||
requireActivity().runOnUiThread {
|
} catch (e: android.nfc.TagLostException) {
|
||||||
binding!!.timeCounter.text = getString(R.string.no_success)
|
msgCode = R.string.tag_lost
|
||||||
}
|
} catch (e: InvalidCANException) {
|
||||||
|
msgCode = R.string.invalid_can
|
||||||
// If the CAN is wrong we will also delete the saved CAN so that the user won't use it again.
|
// If the CAN is wrong we will also delete the saved CAN so that the user won't use it again.
|
||||||
viewModel.deleteCan(requireContext())
|
viewModel.deleteCan(requireContext())
|
||||||
|
} catch (e: AuthAppException) {
|
||||||
|
msgCode = when (e.code) {
|
||||||
|
448 -> R.string.err_bad_data
|
||||||
|
500 -> R.string.err_internal
|
||||||
|
else -> R.string.err_unknown
|
||||||
|
}
|
||||||
|
} catch (e: GeneralSecurityException) {
|
||||||
|
msgCode = R.string.err_internal
|
||||||
|
} catch (e: IOException) {
|
||||||
|
msgCode = R.string.err_reading_card
|
||||||
|
} catch (e: Exception) {
|
||||||
|
msgCode = R.string.err_unknown
|
||||||
|
} finally {
|
||||||
|
adapter.disableReaderMode(activity)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (msgCode != 0) {
|
||||||
|
requireActivity().runOnUiThread {
|
||||||
|
binding!!.timeCounter.text = getString(msgCode)
|
||||||
|
}
|
||||||
// Gives user some time to read the error message
|
// Gives user some time to read the error message
|
||||||
Thread.sleep(1000)
|
Thread.sleep(1000)
|
||||||
goToTheStart()
|
goToTheStart()
|
||||||
} finally {
|
|
||||||
adapter.disableReaderMode(activity)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, NfcAdapter.FLAG_READER_NFC_A, null)
|
}, NfcAdapter.FLAG_READER_NFC_A, null)
|
||||||
|
@ -3,6 +3,9 @@ package com.tarkvaraprojekt.mobileauthapp.NFC;
|
|||||||
import android.nfc.tech.IsoDep;
|
import android.nfc.tech.IsoDep;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
|
import com.tarkvaraprojekt.mobileauthapp.auth.AuthAppException;
|
||||||
|
import com.tarkvaraprojekt.mobileauthapp.auth.InvalidCANException;
|
||||||
|
|
||||||
import org.bouncycastle.crypto.BlockCipher;
|
import org.bouncycastle.crypto.BlockCipher;
|
||||||
import org.bouncycastle.crypto.engines.AESEngine;
|
import org.bouncycastle.crypto.engines.AESEngine;
|
||||||
import org.bouncycastle.crypto.macs.CMac;
|
import org.bouncycastle.crypto.macs.CMac;
|
||||||
@ -209,13 +212,13 @@ public class Comms {
|
|||||||
Log.i("Mutual authentication", Hex.toHexString(response));
|
Log.i("Mutual authentication", Hex.toHexString(response));
|
||||||
|
|
||||||
// if the chip-side verification fails, crash and burn
|
// if the chip-side verification fails, crash and burn
|
||||||
if (response.length == 2) throw new RuntimeException("Invalid CAN.");
|
if (response.length == 2) throw new InvalidCANException();
|
||||||
|
|
||||||
// otherwise verify chip's MAC and return session keys
|
// otherwise verify chip's MAC and return session keys
|
||||||
APDU = createAPDU(dataForMACIncomplete, publicKey.getEncoded(false), 65);
|
APDU = createAPDU(dataForMACIncomplete, publicKey.getEncoded(false), 65);
|
||||||
MAC = getMAC(APDU, keyMAC);
|
MAC = getMAC(APDU, keyMAC);
|
||||||
if (!Hex.toHexString(response, 4, 8).equals(Hex.toHexString(MAC))) {
|
if (!Hex.toHexString(response, 4, 8).equals(Hex.toHexString(MAC))) {
|
||||||
throw new RuntimeException("Could not verify chip's MAC."); // Should never happen.
|
throw new AuthAppException("Could not verify chip's MAC.", 448); // Should never happen.
|
||||||
}
|
}
|
||||||
return new byte[][]{keyEnc, keyMAC};
|
return new byte[][]{keyEnc, keyMAC};
|
||||||
|
|
||||||
@ -304,7 +307,7 @@ public class Comms {
|
|||||||
for (int i = 0; i < FID.length; i++) {
|
for (int i = 0; i < FID.length; i++) {
|
||||||
|
|
||||||
byte index = FID[i];
|
byte index = FID[i];
|
||||||
if (index > 15 || index < 1) throw new RuntimeException("Invalid personal data FID.");
|
if (index > 15 || index < 1) throw new AuthAppException("Invalid personal data FID.", 500);
|
||||||
|
|
||||||
data[1] = index;
|
data[1] = index;
|
||||||
APDU = createSecureAPDU(data, personal);
|
APDU = createSecureAPDU(data, personal);
|
||||||
|
@ -0,0 +1,10 @@
|
|||||||
|
package com.tarkvaraprojekt.mobileauthapp.auth
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A specialised RuntimeException class for exceptions related to the mobile authentication app.
|
||||||
|
* Possible error codes can be found at
|
||||||
|
* https://github.com/TanelOrumaa/Estonian-ID-card-mobile-authenticator-POC/wiki/Error-codes
|
||||||
|
* @param message Error message
|
||||||
|
* @param code An error code defined in the project wiki
|
||||||
|
*/
|
||||||
|
open class AuthAppException(message: String, var code: Int) : RuntimeException(message)
|
@ -0,0 +1,7 @@
|
|||||||
|
package com.tarkvaraprojekt.mobileauthapp.auth
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An AuthAppException for when the user entered CAN does not match the one read from the ID-card
|
||||||
|
* @see AuthAppException
|
||||||
|
*/
|
||||||
|
class InvalidCANException : AuthAppException("Invalid CAN", 400)
|
@ -44,7 +44,9 @@
|
|||||||
<string name="auth_instruction_text">Put the ID card against the phone to establish connection</string>
|
<string name="auth_instruction_text">Put the ID card against the phone to establish connection</string>
|
||||||
<string name="time_left">Time left %d sek</string>
|
<string name="time_left">Time left %d sek</string>
|
||||||
<string name="no_time">No time left</string>
|
<string name="no_time">No time left</string>
|
||||||
<string name="no_success">Wrong CAN</string>
|
<string name="err_unknown">Unknown error</string>
|
||||||
|
<string name="invalid_can">Wrong CAN</string>
|
||||||
|
<string name="tag_lost">Connection between device and ID-card lost</string>
|
||||||
|
|
||||||
<!-- string resources for UserFragment layout -->
|
<!-- string resources for UserFragment layout -->
|
||||||
<string name="user_name_label">NAME</string>
|
<string name="user_name_label">NAME</string>
|
||||||
@ -75,4 +77,7 @@
|
|||||||
<string name="hidden_pin">****</string>
|
<string name="hidden_pin">****</string>
|
||||||
<string name="unavailable">Settings currently unavailabe</string>
|
<string name="unavailable">Settings currently unavailabe</string>
|
||||||
<string name="can_save_request">CAN is currently not saved. Do you wish to save the CAN? Saved CAN will be entered automatically in the future. Saved CAN can be changed and deleted in the settings menu.</string>
|
<string name="can_save_request">CAN is currently not saved. Do you wish to save the CAN? Saved CAN will be entered automatically in the future. Saved CAN can be changed and deleted in the settings menu.</string>
|
||||||
|
<string name="err_reading_card">Failed to read data from the ID-card</string>
|
||||||
|
<string name="err_internal">Internal error</string>
|
||||||
|
<string name="err_bad_data">Read bad data from the ID-card, try using the card again</string>
|
||||||
</resources>
|
</resources>
|
@ -43,7 +43,9 @@
|
|||||||
<string name="auth_instruction_text">ID kaardiga ühenduse loomiseks pane kaart vastu telefoni</string>
|
<string name="auth_instruction_text">ID kaardiga ühenduse loomiseks pane kaart vastu telefoni</string>
|
||||||
<string name="time_left">Aega on jäänud %d sek</string>
|
<string name="time_left">Aega on jäänud %d sek</string>
|
||||||
<string name="no_time">Aeg on otsas</string>
|
<string name="no_time">Aeg on otsas</string>
|
||||||
<string name="no_success">Vale CAN</string>
|
<string name="err_unknown">Tundmatu viga</string>
|
||||||
|
<string name="invalid_can">Vale CAN</string>
|
||||||
|
<string name="tag_lost">Ühendus seadme ja kaardi vahel katkes</string>
|
||||||
|
|
||||||
<!-- string resources for UserFragment layout -->
|
<!-- string resources for UserFragment layout -->
|
||||||
<string name="user_name_label">NIMI</string>
|
<string name="user_name_label">NIMI</string>
|
||||||
@ -73,4 +75,7 @@
|
|||||||
<string name="hide">PEIDA</string>
|
<string name="hide">PEIDA</string>
|
||||||
<string name="hidden_pin">****</string>
|
<string name="hidden_pin">****</string>
|
||||||
<string name="unavailable">Seaded pole hetkel saadaval</string>
|
<string name="unavailable">Seaded pole hetkel saadaval</string>
|
||||||
|
<string name="err_reading_card">Ei saanud ID-kaardilt andmeid lugeda</string>
|
||||||
|
<string name="err_internal">Rakendusesisene viga</string>
|
||||||
|
<string name="err_bad_data">ID-kaardilt loeti vigased andmed, proovi uuesti kaarti kasutada</string>
|
||||||
</resources>
|
</resources>
|
@ -43,7 +43,9 @@
|
|||||||
<string name="auth_instruction_text">Put the ID card against the phone to establish connection</string>
|
<string name="auth_instruction_text">Put the ID card against the phone to establish connection</string>
|
||||||
<string name="time_left">Time left %d sek</string>
|
<string name="time_left">Time left %d sek</string>
|
||||||
<string name="no_time">No time left</string>
|
<string name="no_time">No time left</string>
|
||||||
<string name="no_success">Wrong CAN</string>
|
<string name="err_unknown">Unknown error</string>
|
||||||
|
<string name="invalid_can">Wrong CAN</string>
|
||||||
|
<string name="tag_lost">Connection between device and ID-card lost</string>
|
||||||
|
|
||||||
<!-- string resources for UserFragment layout -->
|
<!-- string resources for UserFragment layout -->
|
||||||
<string name="user_name_label">NAME</string>
|
<string name="user_name_label">NAME</string>
|
||||||
@ -73,4 +75,7 @@
|
|||||||
<string name="hide">HIDE</string>
|
<string name="hide">HIDE</string>
|
||||||
<string name="hidden_pin">****</string>
|
<string name="hidden_pin">****</string>
|
||||||
<string name="unavailable">Settings currently unavailable</string>
|
<string name="unavailable">Settings currently unavailable</string>
|
||||||
|
<string name="err_reading_card">Failed to read data from the ID-card</string>
|
||||||
|
<string name="err_internal">Internal error</string>
|
||||||
|
<string name="err_bad_data">Read bad data from the ID-card, try using the card again</string>
|
||||||
</resources>
|
</resources>
|
Loading…
Reference in New Issue
Block a user