mirror of
https://github.com/TanelOrumaa/Estonian-ID-card-mobile-authenticator-POC.git
synced 2025-08-30 07:10:59 +03:00
Compare commits
2 Commits
MOB-24-use
...
compatibil
Author | SHA1 | Date | |
---|---|---|---|
|
1e26f83db2 | ||
|
74d97827f8 |
@@ -4,6 +4,7 @@ import android.app.Activity
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.nfc.NfcAdapter
|
import android.nfc.NfcAdapter
|
||||||
|
import android.nfc.TagLostException
|
||||||
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
|
||||||
@@ -17,16 +18,11 @@ 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.Authenticator
|
import com.tarkvaraprojekt.mobileauthapp.auth.Authenticator
|
||||||
import com.tarkvaraprojekt.mobileauthapp.auth.InvalidCANException
|
|
||||||
import com.tarkvaraprojekt.mobileauthapp.auth.InvalidPINException
|
|
||||||
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
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -111,9 +107,6 @@ 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
|
|
||||||
var msgArg : Int? = null
|
|
||||||
|
|
||||||
val card = IsoDep.get(tag)
|
val card = IsoDep.get(tag)
|
||||||
card.timeout = 32768
|
card.timeout = 32768
|
||||||
card.use {
|
card.use {
|
||||||
@@ -126,48 +119,30 @@ class AuthFragment : Fragment() {
|
|||||||
)
|
)
|
||||||
paramsModel.setToken(jws)
|
paramsModel.setToken(jws)
|
||||||
requireActivity().runOnUiThread {
|
requireActivity().runOnUiThread {
|
||||||
binding.timeCounter.text = getString(R.string.data_read)
|
|
||||||
goToNextFragment()
|
goToNextFragment()
|
||||||
}
|
}
|
||||||
} catch (e: android.nfc.TagLostException) {
|
|
||||||
msgCode = R.string.tag_lost
|
|
||||||
} catch (e: InvalidCANException) {
|
|
||||||
msgCode = R.string.wrong_can_text
|
|
||||||
// If the CAN is wrong we will also delete the saved CAN so that the user won't use it again.
|
|
||||||
viewModel.deleteCan(requireContext())
|
|
||||||
} catch (e: InvalidPINException) {
|
|
||||||
msgCode = R.string.wrong_pin
|
|
||||||
msgArg = e.remainingAttempts
|
|
||||||
viewModel.deletePin(requireContext())
|
|
||||||
} catch (e: AuthAppException) {
|
|
||||||
msgCode = when (e.code) {
|
|
||||||
400 -> R.string.err_parameter
|
|
||||||
401 -> R.string.err_authentication
|
|
||||||
446 -> R.string.err_card_locked
|
|
||||||
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) {
|
} catch (e: Exception) {
|
||||||
msgCode = R.string.err_unknown
|
when(e) {
|
||||||
} finally {
|
is TagLostException -> requireActivity().runOnUiThread { binding!!.timeCounter.text = getString(R.string.id_card_removed_early) }
|
||||||
adapter.disableReaderMode(activity)
|
else -> {
|
||||||
}
|
when ("invalid pin") {
|
||||||
|
in e.message.toString().lowercase() -> requireActivity().runOnUiThread {
|
||||||
if (msgCode != 0) {
|
val messagePieces = e.message.toString().split(" ")
|
||||||
requireActivity().runOnUiThread {
|
binding.timeCounter.text = getString(R.string.wrong_pin, messagePieces[messagePieces.size - 1])
|
||||||
var msg = getString(msgCode)
|
viewModel.deletePin(requireContext())
|
||||||
if (msgArg != null)
|
}
|
||||||
msg = String.format(msg, msgArg)
|
else -> requireActivity().runOnUiThread {
|
||||||
binding.timeCounter.text = msg
|
binding.timeCounter.text = getString(R.string.wrong_can_text)
|
||||||
|
viewModel.deleteCan(requireContext())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Gives user some time to read the error message
|
// Give user some time to read the error message
|
||||||
Thread.sleep(2000)
|
Thread.sleep(2000)
|
||||||
cancelAuth()
|
cancelAuth()
|
||||||
|
} finally {
|
||||||
|
adapter.disableReaderMode(activity)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, NfcAdapter.FLAG_READER_NFC_A, null)
|
}, NfcAdapter.FLAG_READER_NFC_A, null)
|
||||||
|
@@ -20,11 +20,14 @@ import androidx.fragment.app.Fragment
|
|||||||
import androidx.fragment.app.activityViewModels
|
import androidx.fragment.app.activityViewModels
|
||||||
import androidx.navigation.fragment.findNavController
|
import androidx.navigation.fragment.findNavController
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||||
|
import com.koushikdutta.ion.Ion
|
||||||
import com.tarkvaraprojekt.mobileauthapp.NFC.Comms
|
import com.tarkvaraprojekt.mobileauthapp.NFC.Comms
|
||||||
import com.tarkvaraprojekt.mobileauthapp.databinding.FragmentHomeBinding
|
import com.tarkvaraprojekt.mobileauthapp.databinding.FragmentHomeBinding
|
||||||
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.lang.Exception
|
import java.lang.Exception
|
||||||
|
import java.lang.RuntimeException
|
||||||
|
import java.net.URL
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* HomeFragment is only shown to the user when then the user launches the application. When the application
|
* HomeFragment is only shown to the user when then the user launches the application. When the application
|
||||||
@@ -104,15 +107,42 @@ class HomeFragment : Fragment() {
|
|||||||
intentParams.setChallenge(requireActivity().intent.getStringExtra("challenge")!!)
|
intentParams.setChallenge(requireActivity().intent.getStringExtra("challenge")!!)
|
||||||
intentParams.setAuthUrl(requireActivity().intent.getStringExtra("authUrl")!!)
|
intentParams.setAuthUrl(requireActivity().intent.getStringExtra("authUrl")!!)
|
||||||
intentParams.setOrigin(requireActivity().intent.getStringExtra("originUrl")!!)
|
intentParams.setOrigin(requireActivity().intent.getStringExtra("originUrl")!!)
|
||||||
|
goToTheNextFragment(mobile)
|
||||||
} else { //Website
|
} else { //Website
|
||||||
|
/*
|
||||||
var challenge = requireActivity().intent.data!!.getQueryParameter("challenge")!!
|
var challenge = requireActivity().intent.data!!.getQueryParameter("challenge")!!
|
||||||
// TODO: Since due to encoding plus gets converted to space, temporary solution is to replace it back.
|
// TODO: Since due to encoding plus gets converted to space, temporary solution is to replace it back.
|
||||||
challenge = challenge.replace(" ", "+")
|
challenge = challenge.replace(" ", "+")
|
||||||
intentParams.setChallenge(challenge)
|
intentParams.setChallenge(challenge)
|
||||||
intentParams.setAuthUrl(requireActivity().intent.data!!.getQueryParameter("authUrl")!!)
|
intentParams.setAuthUrl(requireActivity().intent.data!!.getQueryParameter("authUrl")!!)
|
||||||
intentParams.setOrigin(requireActivity().intent.data!!.getQueryParameter("originUrl")!!)
|
intentParams.setOrigin(requireActivity().intent.data!!.getQueryParameter("originUrl")!!)
|
||||||
|
*/
|
||||||
|
var getAuthChallengeUrl = requireActivity().intent.data!!.getQueryParameter("getAuthChallengeUrl")!!
|
||||||
|
getAuthChallengeUrl = getAuthChallengeUrl.substring(1, getAuthChallengeUrl.length - 1)
|
||||||
|
var postAuthTokenUrl = requireActivity().intent.data!!.getQueryParameter("postAuthTokenUrl")!!
|
||||||
|
postAuthTokenUrl = postAuthTokenUrl.substring(1, postAuthTokenUrl.length - 1)
|
||||||
|
val headers = requireActivity().intent.data!!.getQueryParameter("headers")!!
|
||||||
|
intentParams.setAuthUrl(postAuthTokenUrl)
|
||||||
|
val address = "https://" + URL(getAuthChallengeUrl).host
|
||||||
|
intentParams.setOrigin(address)
|
||||||
|
intentParams.setHeaders(headers)
|
||||||
|
Ion.getDefault(activity).conscryptMiddleware.enable(false)
|
||||||
|
Ion.with(activity)
|
||||||
|
.load(getAuthChallengeUrl)
|
||||||
|
.asJsonObject()
|
||||||
|
.setCallback { _, result ->
|
||||||
|
try {
|
||||||
|
// Get data from the result and call launchAuth method
|
||||||
|
val challenge = result.asJsonObject["nonce"].toString().replace("\"", "")
|
||||||
|
intentParams.setChallenge(challenge)
|
||||||
|
goToTheNextFragment(mobile)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Log.i("GETrequest", "was unsuccessful")
|
||||||
|
throw RuntimeException()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
goToTheNextFragment(mobile)
|
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
// There was a problem with parameters, which means that authentication is not possible.
|
// There was a problem with parameters, which means that authentication is not possible.
|
||||||
// In that case we will cancel the authentication immediately as it would be waste of the user's time to carry on
|
// In that case we will cancel the authentication immediately as it would be waste of the user's time to carry on
|
||||||
|
@@ -3,9 +3,6 @@ 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.InvalidPINException;
|
|
||||||
|
|
||||||
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;
|
||||||
@@ -159,7 +156,7 @@ public class Comms {
|
|||||||
private byte[] getResponse(byte[] APDU, String log) throws IOException {
|
private byte[] getResponse(byte[] APDU, String log) throws IOException {
|
||||||
byte[] response = idCard.transceive(APDU);
|
byte[] response = idCard.transceive(APDU);
|
||||||
if (response[response.length - 2] != (byte) 0x90 || response[response.length - 1] != 0x00) {
|
if (response[response.length - 2] != (byte) 0x90 || response[response.length - 1] != 0x00) {
|
||||||
throw new AuthAppException(String.format("%s failed.", log), 500);
|
throw new RuntimeException(String.format("%s failed.", log));
|
||||||
}
|
}
|
||||||
Log.i(log, Hex.toHexString(response));
|
Log.i(log, Hex.toHexString(response));
|
||||||
return response;
|
return response;
|
||||||
@@ -207,7 +204,7 @@ public class Comms {
|
|||||||
// verify chip's MAC and return session keys
|
// verify chip's MAC and return session keys
|
||||||
MAC = getMAC(createAPDU(dataForMACIncomplete, publicKey.getEncoded(false), 65), keyMAC);
|
MAC = getMAC(createAPDU(dataForMACIncomplete, publicKey.getEncoded(false), 65), keyMAC);
|
||||||
if (!Hex.toHexString(response, 4, 8).equals(Hex.toHexString(MAC))) {
|
if (!Hex.toHexString(response, 4, 8).equals(Hex.toHexString(MAC))) {
|
||||||
throw new AuthAppException("Could not verify chip's MAC.", 448); // *Should* never happen.
|
throw new RuntimeException("Could not verify chip's MAC."); // *Should* never happen.
|
||||||
}
|
}
|
||||||
return new byte[][]{keyEnc, keyMAC};
|
return new byte[][]{keyEnc, keyMAC};
|
||||||
|
|
||||||
@@ -224,7 +221,7 @@ public class Comms {
|
|||||||
selectFile(FID, info);
|
selectFile(FID, info);
|
||||||
byte[] response = getResponse(new byte[0], readFile, "Read binary");
|
byte[] response = getResponse(new byte[0], readFile, "Read binary");
|
||||||
if (response[response.length - 2] != (byte) 0x90 || response[response.length - 1] != 0x00) {
|
if (response[response.length - 2] != (byte) 0x90 || response[response.length - 1] != 0x00) {
|
||||||
throw new AuthAppException(String.format("Could not read %s", info), 500);
|
throw new RuntimeException(String.format("Could not read %s", info));
|
||||||
}
|
}
|
||||||
return encryptDecryptData(Arrays.copyOfRange(response, 3, 19), Cipher.DECRYPT_MODE);
|
return encryptDecryptData(Arrays.copyOfRange(response, 3, 19), Cipher.DECRYPT_MODE);
|
||||||
}
|
}
|
||||||
@@ -293,7 +290,7 @@ public class Comms {
|
|||||||
private void selectFile(byte[] FID, String info) throws NoSuchPaddingException, InvalidKeyException, NoSuchAlgorithmException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException, IOException {
|
private void selectFile(byte[] FID, String info) throws NoSuchPaddingException, InvalidKeyException, NoSuchAlgorithmException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException, IOException {
|
||||||
byte[] response = getResponse(FID, selectFile, String.format("Select %s", info));
|
byte[] response = getResponse(FID, selectFile, String.format("Select %s", info));
|
||||||
if (response[response.length - 2] != (byte) 0x90 || response[response.length - 1] != 0x00) {
|
if (response[response.length - 2] != (byte) 0x90 || response[response.length - 1] != 0x00) {
|
||||||
throw new AuthAppException(String.format("Could not select %s", info), 500);
|
throw new RuntimeException(String.format("Could not select %s", info));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -318,7 +315,7 @@ public class Comms {
|
|||||||
// select and read the personal data elementary files
|
// select and read the personal data elementary files
|
||||||
for (byte index : lastBytes) {
|
for (byte index : lastBytes) {
|
||||||
|
|
||||||
if (index > 15 || index < 1) throw new AuthAppException("Invalid personal data FID.", 500);
|
if (index > 15 || index < 1) throw new RuntimeException("Invalid personal data FID.");
|
||||||
FID[1] = index;
|
FID[1] = index;
|
||||||
|
|
||||||
// store the decrypted datum
|
// store the decrypted datum
|
||||||
@@ -351,9 +348,9 @@ public class Comms {
|
|||||||
|
|
||||||
if (response[response.length - 2] != (byte) 0x90 || response[response.length - 1] != 0x00) {
|
if (response[response.length - 2] != (byte) 0x90 || response[response.length - 1] != 0x00) {
|
||||||
if (response[response.length - 2] == 0x69 && response[response.length - 1] == (byte) 0x83) {
|
if (response[response.length - 2] == 0x69 && response[response.length - 1] == (byte) 0x83) {
|
||||||
throw new AuthAppException("Invalid PIN. Authentication method blocked.", 446);
|
throw new RuntimeException("Invalid PIN. Authentication method blocked.");
|
||||||
} else {
|
} else {
|
||||||
throw new InvalidPINException(response[response.length - 1] + 64);
|
throw new RuntimeException(String.format("Invalid PIN. Attempts left: %d.", response[response.length - 1] + 64));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -382,7 +379,7 @@ public class Comms {
|
|||||||
readCert[3] = (byte) (certificate.length % 256);
|
readCert[3] = (byte) (certificate.length % 256);
|
||||||
byte[] response = getResponse(new byte[0], readCert, "Read the certificate");
|
byte[] response = getResponse(new byte[0], readCert, "Read the certificate");
|
||||||
if (response[response.length - 2] == 0x6b && response[response.length - 1] == 0x00) {
|
if (response[response.length - 2] == 0x6b && response[response.length - 1] == 0x00) {
|
||||||
throw new AuthAppException("Wrong read parameters.", 400);
|
throw new RuntimeException("Wrong read parameters.");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the range containing a portion of the certificate and decrypt it
|
// Set the range containing a portion of the certificate and decrypt it
|
||||||
@@ -417,7 +414,7 @@ public class Comms {
|
|||||||
|
|
||||||
byte[] response = getResponse(Env, MSESetEnv, "Set environment");
|
byte[] response = getResponse(Env, MSESetEnv, "Set environment");
|
||||||
if (response[response.length - 2] != (byte) 0x90 || response[response.length - 1] != 0x00) {
|
if (response[response.length - 2] != (byte) 0x90 || response[response.length - 1] != 0x00) {
|
||||||
throw new AuthAppException("Setting the environment failed.", 500);
|
throw new RuntimeException("Setting the environment failed.");
|
||||||
}
|
}
|
||||||
|
|
||||||
InternalAuthenticate[4] = (byte) (0x1d + 16 * (token.length / 16));
|
InternalAuthenticate[4] = (byte) (0x1d + 16 * (token.length / 16));
|
||||||
@@ -425,7 +422,7 @@ public class Comms {
|
|||||||
response = getResponse(token, InternalAuthenticate, "Internal Authenticate");
|
response = getResponse(token, InternalAuthenticate, "Internal Authenticate");
|
||||||
|
|
||||||
if (response[response.length - 2] != (byte) 0x90 || response[response.length - 1] != 0x00) {
|
if (response[response.length - 2] != (byte) 0x90 || response[response.length - 1] != 0x00) {
|
||||||
throw new AuthAppException("Signing the token failed.", 500);
|
throw new RuntimeException("Signing the token failed.");
|
||||||
}
|
}
|
||||||
|
|
||||||
byte[] signature = encryptDecryptData(Arrays.copyOfRange(response, 3, 115), Cipher.DECRYPT_MODE);
|
byte[] signature = encryptDecryptData(Arrays.copyOfRange(response, 3, 115), Cipher.DECRYPT_MODE);
|
||||||
|
@@ -1,10 +0,0 @@
|
|||||||
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)
|
|
@@ -1,7 +0,0 @@
|
|||||||
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)
|
|
@@ -1,10 +0,0 @@
|
|||||||
package com.tarkvaraprojekt.mobileauthapp.auth
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An AuthAppException for when the user entered PIN is not correct
|
|
||||||
* @see AuthAppException
|
|
||||||
*/
|
|
||||||
class InvalidPINException(val remainingAttempts: Int) : AuthAppException(
|
|
||||||
"Invalid PIN" + (if (remainingAttempts>0) "" else ". Authentication method blocked."),
|
|
||||||
if (remainingAttempts>0) 401 else 446
|
|
||||||
)
|
|
@@ -16,6 +16,9 @@ class ParametersViewModel: ViewModel() {
|
|||||||
private var _origin: String = ""
|
private var _origin: String = ""
|
||||||
val origin get() = _origin
|
val origin get() = _origin
|
||||||
|
|
||||||
|
private var _headers: String = ""
|
||||||
|
val headers get() =_headers
|
||||||
|
|
||||||
fun setChallenge(newChallenge: String) {
|
fun setChallenge(newChallenge: String) {
|
||||||
_challenge = newChallenge
|
_challenge = newChallenge
|
||||||
}
|
}
|
||||||
@@ -31,4 +34,8 @@ class ParametersViewModel: ViewModel() {
|
|||||||
fun setOrigin(newOrigin: String) {
|
fun setOrigin(newOrigin: String) {
|
||||||
_origin = newOrigin
|
_origin = newOrigin
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun setHeaders(newHeaders: String) {
|
||||||
|
_headers = newHeaders
|
||||||
|
}
|
||||||
}
|
}
|
@@ -19,7 +19,7 @@
|
|||||||
<string name="nfc_not_available">NFC is not turned on or is not supported by the phone</string>
|
<string name="nfc_not_available">NFC is not turned on or is not supported by the phone</string>
|
||||||
<string name="nfc_reading_error">The provided CAN does not match the ID card</string>
|
<string name="nfc_reading_error">The provided CAN does not match the ID card</string>
|
||||||
<string name="id_card_removed_early">ID card was removed too early</string>
|
<string name="id_card_removed_early">ID card was removed too early</string>
|
||||||
<string name="wrong_pin">Wrong PIN 1. %s tries left on the card</string>
|
<string name="wrong_pin">Wrong PIN 1. Tries on the card left %s</string>
|
||||||
|
|
||||||
<!-- string resources for HomeFragment -->
|
<!-- string resources for HomeFragment -->
|
||||||
<string name="pin_status_saved">PIN 1 saved</string>
|
<string name="pin_status_saved">PIN 1 saved</string>
|
||||||
@@ -75,8 +75,8 @@
|
|||||||
<string name="saved_can">CAN: %s</string>
|
<string name="saved_can">CAN: %s</string>
|
||||||
<string name="can_delete">Delete CAN</string>
|
<string name="can_delete">Delete CAN</string>
|
||||||
<string name="saved_pin">PIN1: %s</string>
|
<string name="saved_pin">PIN1: %s</string>
|
||||||
<string name="pin1_add">Add PIN 1</string>
|
<string name="pin1_add">Add PIN1</string>
|
||||||
<string name="pin1_delete">Delete PIN 1</string>
|
<string name="pin1_delete">Delete PIN1</string>
|
||||||
<string name="missing">not saved</string>
|
<string name="missing">not saved</string>
|
||||||
<string name="show">SHOW</string>
|
<string name="show">SHOW</string>
|
||||||
<string name="hide">HIDE</string>
|
<string name="hide">HIDE</string>
|
||||||
@@ -84,13 +84,4 @@
|
|||||||
<string name="menu_unavailable_message">Settings are currently unavailable</string>
|
<string name="menu_unavailable_message">Settings are currently unavailable</string>
|
||||||
<string name="can_deleted">CAN deleted</string>
|
<string name="can_deleted">CAN deleted</string>
|
||||||
<string name="pin_deleted">PIN 1 deleted</string>
|
<string name="pin_deleted">PIN 1 deleted</string>
|
||||||
|
|
||||||
<string name="err_unknown">Unknown error</string>
|
|
||||||
<string name="tag_lost">Connection between device and ID-card lost</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>
|
|
||||||
<string name="err_parameter">Required parameter is missing or invalid</string>
|
|
||||||
<string name="err_authentication">Failed to authenticate</string>
|
|
||||||
<string name="err_card_locked">Card locked</string>
|
|
||||||
</resources>
|
</resources>
|
@@ -18,7 +18,7 @@
|
|||||||
<string name="nfc_not_available">NFC ei ole sisse lülitatud või puudub telefonil NFC võimekus</string>
|
<string name="nfc_not_available">NFC ei ole sisse lülitatud või puudub telefonil NFC võimekus</string>
|
||||||
<string name="nfc_reading_error">Sisestatud CAN ei ole vastavuses ID kaardiga</string>
|
<string name="nfc_reading_error">Sisestatud CAN ei ole vastavuses ID kaardiga</string>
|
||||||
<string name="id_card_removed_early">ID kaart eemaldati liiga vara</string>
|
<string name="id_card_removed_early">ID kaart eemaldati liiga vara</string>
|
||||||
<string name="wrong_pin">Vale PIN 1. ID kaardil PIN 1 sisetamise katseid järel: %s</string>
|
<string name="wrong_pin">Vale PIN 1. ID kaardil PIN 1 sisetamise kordi alles: %s</string>
|
||||||
|
|
||||||
<!-- string resources for HomeFragment -->
|
<!-- string resources for HomeFragment -->
|
||||||
<string name="pin_status_saved">PIN 1 on salvestatud</string>
|
<string name="pin_status_saved">PIN 1 on salvestatud</string>
|
||||||
@@ -83,13 +83,4 @@
|
|||||||
<string name="menu_unavailable_message">Seaded pole hetkel saadaval</string>
|
<string name="menu_unavailable_message">Seaded pole hetkel saadaval</string>
|
||||||
<string name="can_deleted">CAN kustatud</string>
|
<string name="can_deleted">CAN kustatud</string>
|
||||||
<string name="pin_deleted">PIN 1 kustatud</string>
|
<string name="pin_deleted">PIN 1 kustatud</string>
|
||||||
|
|
||||||
<string name="err_unknown">Tundmatu viga</string>
|
|
||||||
<string name="tag_lost">Ühendus seadme ja kaardi vahel katkes</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>
|
|
||||||
<string name="err_parameter">Vigane või puuduv parameeter</string>
|
|
||||||
<string name="err_authentication">Autentimine ebaõnnestus</string>
|
|
||||||
<string name="err_card_locked">Kaart lukus</string>
|
|
||||||
</resources>
|
</resources>
|
@@ -17,7 +17,7 @@
|
|||||||
<string name="nfc_not_available">NFC is not turned on or is not supported by the phone</string>
|
<string name="nfc_not_available">NFC is not turned on or is not supported by the phone</string>
|
||||||
<string name="nfc_reading_error">The provided CAN does not match the ID card</string>
|
<string name="nfc_reading_error">The provided CAN does not match the ID card</string>
|
||||||
<string name="id_card_removed_early">ID card was removed too early</string>
|
<string name="id_card_removed_early">ID card was removed too early</string>
|
||||||
<string name="wrong_pin">Wrong PIN 1. %s tries left on the card</string>
|
<string name="wrong_pin">Wrong PIN 1. Tries on the card left %s</string>
|
||||||
|
|
||||||
<!-- string resources for HomeFragment -->
|
<!-- string resources for HomeFragment -->
|
||||||
<string name="pin_status_saved">PIN 1 saved</string>
|
<string name="pin_status_saved">PIN 1 saved</string>
|
||||||
@@ -82,13 +82,4 @@
|
|||||||
<string name="menu_unavailable_message">Settings are currently unavailable</string>
|
<string name="menu_unavailable_message">Settings are currently unavailable</string>
|
||||||
<string name="can_deleted">CAN deleted</string>
|
<string name="can_deleted">CAN deleted</string>
|
||||||
<string name="pin_deleted">PIN 1 deleted</string>
|
<string name="pin_deleted">PIN 1 deleted</string>
|
||||||
|
|
||||||
<string name="err_unknown">Unknown error</string>
|
|
||||||
<string name="tag_lost">Connection between device and ID-card lost</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>
|
|
||||||
<string name="err_parameter">Required parameter is missing or invalid</string>
|
|
||||||
<string name="err_authentication">Failed to authenticate</string>
|
|
||||||
<string name="err_card_locked">Card locked</string>
|
|
||||||
</resources>
|
</resources>
|
@@ -11,6 +11,7 @@ import androidx.activity.result.contract.ActivityResultContracts
|
|||||||
import com.example.testmobileapp.databinding.ActivityMainBinding
|
import com.example.testmobileapp.databinding.ActivityMainBinding
|
||||||
import com.koushikdutta.ion.Ion
|
import com.koushikdutta.ion.Ion
|
||||||
import org.json.JSONObject
|
import org.json.JSONObject
|
||||||
|
import java.net.URL
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base url where the requests should be made. Add yours here. It must use https.
|
* Base url where the requests should be made. Add yours here. It must use https.
|
||||||
@@ -31,7 +32,7 @@ class MainActivity : AppCompatActivity() {
|
|||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
binding = ActivityMainBinding.inflate(layoutInflater)
|
binding = ActivityMainBinding.inflate(layoutInflater)
|
||||||
setContentView(binding.root)
|
setContentView(binding.root)
|
||||||
|
Log.i("myLoggingStuff", URL("https://www.google.ee/?hl=et").host.toString())
|
||||||
authLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { response ->
|
authLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { response ->
|
||||||
if (response.resultCode == Activity.RESULT_OK) {
|
if (response.resultCode == Activity.RESULT_OK) {
|
||||||
binding.loginTextView.text = getString(R.string.auth_success)
|
binding.loginTextView.text = getString(R.string.auth_success)
|
||||||
|
Reference in New Issue
Block a user