From 8e6fde98569964ede8830210ec8a491b46c9303a Mon Sep 17 00:00:00 2001 From: kizzy Date: Tue, 9 Jun 2026 12:52:45 +0700 Subject: [PATCH] MPU ready for certification --- .../ui/dashboard/DashboardScreen2.kt | 47 ++++++++++- .../utsmyanmar/paylibs/network/ISOSocket.java | 81 ++++++++++++++++++- .../paylibs/sign_on/SignOnProcess.java | 17 ++-- 3 files changed, 132 insertions(+), 13 deletions(-) diff --git a/app/src/main/java/com/mob/utsmyanmar/ui/dashboard/DashboardScreen2.kt b/app/src/main/java/com/mob/utsmyanmar/ui/dashboard/DashboardScreen2.kt index 9ea31d9..0bb9afe 100644 --- a/app/src/main/java/com/mob/utsmyanmar/ui/dashboard/DashboardScreen2.kt +++ b/app/src/main/java/com/mob/utsmyanmar/ui/dashboard/DashboardScreen2.kt @@ -15,6 +15,7 @@ import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.* import androidx.compose.material3.* import androidx.compose.runtime.* +import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip @@ -35,6 +36,7 @@ import com.mob.utsmyanmar.ui.preview.P3Preview import com.mob.utsmyanmar.ui.theme.Color import com.utsmyanmar.paylibs.sign_on.EchoTestProcess import com.utsmyanmar.paylibs.sign_on.SignOnListener +import com.utsmyanmar.paylibs.utils.core_utils.SystemParamsOperation import kotlinx.coroutines.delay import kotlinx.coroutines.launch @@ -232,6 +234,20 @@ fun DashboardScreen2( fontWeight = FontWeight.Medium, modifier = Modifier.padding(horizontal = 16.dp) ) + + var switchChecked by remember { mutableStateOf(SystemParamsOperation.getInstance().isReversalOn) } + DrawerItem( + title = "Reversal On/Off", + icon = Icons.Default.Sync, + showSwitch = true, + isChecked = switchChecked, + onCheckedChange = { isChecked -> + switchChecked = isChecked + SystemParamsOperation.getInstance().setReversalFlag(isChecked) + + }, + onClick = {} + ) DrawerItem("Function", Icons.Default.Dashboard) { scope.launch { drawerState.close() } } @@ -290,21 +306,44 @@ fun DashboardScreen2( @Composable private fun DrawerItem( - title: String, icon: ImageVector, onClick: () -> Unit + title: String, + icon: ImageVector, + showSwitch: Boolean = false, // New: Flag to enable switch mode + isChecked: Boolean = false, // New: Switch state + onCheckedChange: (Boolean) -> Unit = {}, // New: Switch callback + onClick: () -> Unit ) { NavigationDrawerItem( label = { Text( - text = title, fontWeight = FontWeight.Medium + text = title, + fontWeight = FontWeight.Medium ) }, selected = false, - onClick = onClick, + // If it's a switch item, clicking the whole row toggles the switch instead of navigating + onClick = { + if (showSwitch) { + onCheckedChange(!isChecked) + } else { + onClick() + } + }, icon = { Icon( - imageVector = icon, contentDescription = title + imageVector = icon, + contentDescription = title ) }, + + badge = { + if (showSwitch) { + Switch( + checked = isChecked, + onCheckedChange = onCheckedChange + ) + } + }, modifier = Modifier.padding(horizontal = 12.dp, vertical = 2.dp), colors = NavigationDrawerItemDefaults.colors( unselectedContainerColor = androidx.compose.ui.graphics.Color.Transparent, diff --git a/paylibs/src/main/java/com/utsmyanmar/paylibs/network/ISOSocket.java b/paylibs/src/main/java/com/utsmyanmar/paylibs/network/ISOSocket.java index 6068dc9..2ff115d 100644 --- a/paylibs/src/main/java/com/utsmyanmar/paylibs/network/ISOSocket.java +++ b/paylibs/src/main/java/com/utsmyanmar/paylibs/network/ISOSocket.java @@ -26,11 +26,14 @@ import java.security.KeyManagementException; import java.security.KeyStore; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; import java.security.cert.Certificate; import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; +import java.text.SimpleDateFormat; import java.util.Arrays; +import java.util.Date; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import java.util.regex.Matcher; @@ -64,6 +67,7 @@ import sunmi.sunmiui.utils.LogUtil; public class ISOSocket { + private static final String TAG = ISOSocket.class.getSimpleName(); private static final int DEFAULT_TIMEOUT = 30 * 1000; private String serverIP; private int serverPort; @@ -326,6 +330,7 @@ public class ISOSocket { } return port; } + private String formatDate(Date d) { return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(d); } public void switchIp() { isSwitchIp = true; @@ -359,7 +364,7 @@ public class ISOSocket { // serverPort = 5001; serverIP = "103.84.101.82"; serverPort = 60147; - SystemParamsOperation.getInstance().setSslSwitchStatus(false); + SystemParamsOperation.getInstance().setSslSwitchStatus(true); // serverIP = "posuat.myanmarorientalbank.com"; // serverPort = 5033; } else { @@ -397,8 +402,54 @@ public class ISOSocket { if (SystemParamsOperation.getInstance().isSslOn()) { try { - OkHttpClient client = getClient(); - sslSocket = (SSLSocket) client.sslSocketFactory().createSocket(); + TrustManager[] trustAll = new TrustManager[]{new X509TrustManager() { + public void checkClientTrusted(X509Certificate[] chain, String authType) {} + public void checkServerTrusted(X509Certificate[] chain, String authType) {} + public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[0]; } + }}; + SSLContext ctx = SSLContext.getInstance("TLS"); + ctx.init(null, trustAll, new SecureRandom()); + + SSLSocketFactory factory = ctx.getSocketFactory(); + +// try (SSLSocket sslsock = (SSLSocket) factory.createSocket()) { +// +// sslsock.setEnabledProtocols(new String[]{"TLSv1.2"}); +//// while (!isSSLOnline(timeout,subscriber)) { +//// Thread.sleep(150); +//// subscriber.onError(new Throwable("java.net.SocketTimeoutException: connect timed out")); +//// } +// +// sslsock.setSoTimeout(60000); +// sslsock.connect(new InetSocketAddress(serverIP, serverPort), connectTimeout); +// +// sslsock.startHandshake(); +// +// SSLSession session = sslsock.getSession(); +// +// LogUtil.d(TAG, "SSL handshake success to " + serverIP + ":" + serverPort + "\n"); +// LogUtil.d(TAG, "TLS handshake success to " + serverIP + ":" + serverPort + "\n"); +// LogUtil.d(TAG, "TLS version: " + session.getProtocol() + "\n"); +// LogUtil.d(TAG,"Cipher suite: " + session.getCipherSuite() + "\n"); +// +// try { +// java.security.cert.Certificate[] chain = session.getPeerCertificates(); +// if (chain != null && chain.length > 0) { +// LogUtil.d(TAG,"Peer certificates:\n"); +// for (int i = 0; i < chain.length; i++) { +// X509Certificate x = (X509Certificate) chain[i]; +// LogUtil.d(TAG, " [" + i + "] Subject: " + x.getSubjectX500Principal().getName() + "\n"); +// LogUtil.d(TAG," Issuer: " + x.getIssuerX500Principal().getName() + "\n"); +// LogUtil.d(TAG," Valid: " + formatDate(x.getNotBefore()) + " - " + formatDate(x.getNotAfter()) + "\n"); +// } +// } +// } catch (Exception ignored) { } +// } + +// OkHttpClient client = getClient(); + sslSocket = (SSLSocket) factory.createSocket(); + sslSocket.setEnabledProtocols(new String[]{"TLSv1.2"}); +// sslSocket.setEnabledProtocols(new String[]{"TLSv1", "TLSv1.1", "TLSv1.2", "TLSv1.3"}); // while (!isSSLOnline(timeout,subscriber)) { // Thread.sleep(150); // subscriber.onError(new Throwable("java.net.SocketTimeoutException: connect timed out")); @@ -407,6 +458,28 @@ public class ISOSocket { sslSocket.setSoTimeout(60000); sslSocket.connect(new InetSocketAddress(serverIP, serverPort), connectTimeout); + sslSocket.startHandshake(); + + SSLSession session = sslSocket.getSession(); + + LogUtil.d(TAG, "SSL handshake success to " + serverIP + ":" + serverPort + "\n"); + LogUtil.d(TAG, "TLS handshake success to " + serverIP + ":" + serverPort + "\n"); + LogUtil.d(TAG, "TLS version: " + session.getProtocol() + "\n"); + LogUtil.d(TAG,"Cipher suite: " + session.getCipherSuite() + "\n"); + + try { + java.security.cert.Certificate[] chain = session.getPeerCertificates(); + if (chain != null && chain.length > 0) { + LogUtil.d(TAG,"Peer certificates:\n"); + for (int i = 0; i < chain.length; i++) { + X509Certificate x = (X509Certificate) chain[i]; + LogUtil.d(TAG, " [" + i + "] Subject: " + x.getSubjectX500Principal().getName() + "\n"); + LogUtil.d(TAG," Issuer: " + x.getIssuerX500Principal().getName() + "\n"); + LogUtil.d(TAG," Valid: " + formatDate(x.getNotBefore()) + " - " + formatDate(x.getNotAfter()) + "\n"); + } + } + } catch (Exception ignored) { } + inputStream = sslSocket.getInputStream(); outputStream = sslSocket.getOutputStream(); @@ -434,7 +507,7 @@ public class ISOSocket { subscriber.onComplete(); - } catch (CertificateException | KeyStoreException | IOException | + } catch ( IOException | NoSuchAlgorithmException | KeyManagementException e) { e.printStackTrace(); subscriber.onError(e); diff --git a/paylibs/src/main/java/com/utsmyanmar/paylibs/sign_on/SignOnProcess.java b/paylibs/src/main/java/com/utsmyanmar/paylibs/sign_on/SignOnProcess.java index 2f2931f..c319786 100644 --- a/paylibs/src/main/java/com/utsmyanmar/paylibs/sign_on/SignOnProcess.java +++ b/paylibs/src/main/java/com/utsmyanmar/paylibs/sign_on/SignOnProcess.java @@ -120,7 +120,9 @@ public class SignOnProcess { byte[] field62 = Objects.requireNonNull(responseMap.get("F062")).getDataBytes(); byte[] encryptedPIK = new byte[16]; - System.arraycopy(field62, 2, encryptedPIK, 0, 16); + System.arraycopy(field62, 0, encryptedPIK, 0, 8); + System.arraycopy(field62, 0, encryptedPIK, 8, 8); +// System.arraycopy(field62, 0, encryptedPIK, 0, 16); try { byte[] kcv = ByteUtil.hexStr2Bytes(TriDes.getKcv(encryptedPIK)); @@ -130,10 +132,13 @@ public class SignOnProcess { if (!TextUtils.equals(SystemParamsOperation.getInstance().getTMKIndex(), "")) { tmkIndex = Integer.parseInt(SystemParamsOperation.getInstance().getTMKIndex()); } - LogUtil.d(TAG, "TMK Index:" + tmkIndex); - int res = PayLibsUtils.getInstance().securityOptV2.saveCiphertextKey(AidlConstantsV2.Security.KEY_TYPE_PIK, encryptedPIK, null, tmkIndex, AidlConstantsV2.Security.KEY_ALG_TYPE_3DES, 11); - resultCode = res; + + SystemParamsOperation.getInstance().saveKeyPIK(encryptedPIK, kcv); + +// int res = PayLibNex.getInstance().deviceEngine.getPinPad().writeWKey(9, WorkKeyTypeEnum.PINKEY,encryptedPIK,encryptedPIK.length); + int res = PayLibsUtils.getInstance().securityOptV2.saveCiphertextKey(AidlConstantsV2.Security.KEY_TYPE_PIK, encryptedPIK, null, tmkIndex, AidlConstantsV2.Security.KEY_ALG_TYPE_3DES, 11); + resultCode = res; if (res < 0) { flag = false; LogUtil.d(TAG, "Fail PIK result code:" + res); @@ -141,8 +146,10 @@ public class SignOnProcess { flag = true; LogUtil.d(TAG, "Success PIK result code:" + res); } - } catch (RemoteException | GeneralSecurityException e) { + } catch (GeneralSecurityException e) { e.printStackTrace(); + } catch (RemoteException e) { + throw new RuntimeException(e); } }