MPU ready for certification

This commit is contained in:
kizzy 2026-06-09 12:52:45 +07:00
parent 68dd5eebd7
commit 8e6fde9856
3 changed files with 132 additions and 13 deletions

View File

@ -15,6 +15,7 @@ import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.* import androidx.compose.material.icons.filled.*
import androidx.compose.material3.* import androidx.compose.material3.*
import androidx.compose.runtime.* import androidx.compose.runtime.*
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip 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.mob.utsmyanmar.ui.theme.Color
import com.utsmyanmar.paylibs.sign_on.EchoTestProcess import com.utsmyanmar.paylibs.sign_on.EchoTestProcess
import com.utsmyanmar.paylibs.sign_on.SignOnListener import com.utsmyanmar.paylibs.sign_on.SignOnListener
import com.utsmyanmar.paylibs.utils.core_utils.SystemParamsOperation
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@ -232,6 +234,20 @@ fun DashboardScreen2(
fontWeight = FontWeight.Medium, fontWeight = FontWeight.Medium,
modifier = Modifier.padding(horizontal = 16.dp) 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) { DrawerItem("Function", Icons.Default.Dashboard) {
scope.launch { drawerState.close() } scope.launch { drawerState.close() }
} }
@ -290,21 +306,44 @@ fun DashboardScreen2(
@Composable @Composable
private fun DrawerItem( 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( NavigationDrawerItem(
label = { label = {
Text( Text(
text = title, fontWeight = FontWeight.Medium text = title,
fontWeight = FontWeight.Medium
) )
}, },
selected = false, 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 = {
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), modifier = Modifier.padding(horizontal = 12.dp, vertical = 2.dp),
colors = NavigationDrawerItemDefaults.colors( colors = NavigationDrawerItemDefaults.colors(
unselectedContainerColor = androidx.compose.ui.graphics.Color.Transparent, unselectedContainerColor = androidx.compose.ui.graphics.Color.Transparent,

View File

@ -26,11 +26,14 @@ import java.security.KeyManagementException;
import java.security.KeyStore; import java.security.KeyStore;
import java.security.KeyStoreException; import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.cert.Certificate; import java.security.cert.Certificate;
import java.security.cert.CertificateException; import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory; import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate; import java.security.cert.X509Certificate;
import java.text.SimpleDateFormat;
import java.util.Arrays; import java.util.Arrays;
import java.util.Date;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException; import java.util.concurrent.TimeoutException;
import java.util.regex.Matcher; import java.util.regex.Matcher;
@ -64,6 +67,7 @@ import sunmi.sunmiui.utils.LogUtil;
public class ISOSocket { public class ISOSocket {
private static final String TAG = ISOSocket.class.getSimpleName();
private static final int DEFAULT_TIMEOUT = 30 * 1000; private static final int DEFAULT_TIMEOUT = 30 * 1000;
private String serverIP; private String serverIP;
private int serverPort; private int serverPort;
@ -326,6 +330,7 @@ public class ISOSocket {
} }
return port; return port;
} }
private String formatDate(Date d) { return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(d); }
public void switchIp() { public void switchIp() {
isSwitchIp = true; isSwitchIp = true;
@ -359,7 +364,7 @@ public class ISOSocket {
// serverPort = 5001; // serverPort = 5001;
serverIP = "103.84.101.82"; serverIP = "103.84.101.82";
serverPort = 60147; serverPort = 60147;
SystemParamsOperation.getInstance().setSslSwitchStatus(false); SystemParamsOperation.getInstance().setSslSwitchStatus(true);
// serverIP = "posuat.myanmarorientalbank.com"; // serverIP = "posuat.myanmarorientalbank.com";
// serverPort = 5033; // serverPort = 5033;
} else { } else {
@ -397,8 +402,54 @@ public class ISOSocket {
if (SystemParamsOperation.getInstance().isSslOn()) { if (SystemParamsOperation.getInstance().isSslOn()) {
try { try {
OkHttpClient client = getClient(); TrustManager[] trustAll = new TrustManager[]{new X509TrustManager() {
sslSocket = (SSLSocket) client.sslSocketFactory().createSocket(); 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)) { // while (!isSSLOnline(timeout,subscriber)) {
// Thread.sleep(150); // Thread.sleep(150);
// subscriber.onError(new Throwable("java.net.SocketTimeoutException: connect timed out")); // subscriber.onError(new Throwable("java.net.SocketTimeoutException: connect timed out"));
@ -407,6 +458,28 @@ public class ISOSocket {
sslSocket.setSoTimeout(60000); sslSocket.setSoTimeout(60000);
sslSocket.connect(new InetSocketAddress(serverIP, serverPort), connectTimeout); 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(); inputStream = sslSocket.getInputStream();
outputStream = sslSocket.getOutputStream(); outputStream = sslSocket.getOutputStream();
@ -434,7 +507,7 @@ public class ISOSocket {
subscriber.onComplete(); subscriber.onComplete();
} catch (CertificateException | KeyStoreException | IOException | } catch ( IOException |
NoSuchAlgorithmException | KeyManagementException e) { NoSuchAlgorithmException | KeyManagementException e) {
e.printStackTrace(); e.printStackTrace();
subscriber.onError(e); subscriber.onError(e);

View File

@ -120,7 +120,9 @@ public class SignOnProcess {
byte[] field62 = Objects.requireNonNull(responseMap.get("F062")).getDataBytes(); byte[] field62 = Objects.requireNonNull(responseMap.get("F062")).getDataBytes();
byte[] encryptedPIK = new byte[16]; 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 { try {
byte[] kcv = ByteUtil.hexStr2Bytes(TriDes.getKcv(encryptedPIK)); byte[] kcv = ByteUtil.hexStr2Bytes(TriDes.getKcv(encryptedPIK));
@ -130,8 +132,11 @@ public class SignOnProcess {
if (!TextUtils.equals(SystemParamsOperation.getInstance().getTMKIndex(), "")) { if (!TextUtils.equals(SystemParamsOperation.getInstance().getTMKIndex(), "")) {
tmkIndex = Integer.parseInt(SystemParamsOperation.getInstance().getTMKIndex()); tmkIndex = Integer.parseInt(SystemParamsOperation.getInstance().getTMKIndex());
} }
LogUtil.d(TAG, "TMK Index:" + tmkIndex); LogUtil.d(TAG, "TMK Index:" + tmkIndex);
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); int res = PayLibsUtils.getInstance().securityOptV2.saveCiphertextKey(AidlConstantsV2.Security.KEY_TYPE_PIK, encryptedPIK, null, tmkIndex, AidlConstantsV2.Security.KEY_ALG_TYPE_3DES, 11);
resultCode = res; resultCode = res;
if (res < 0) { if (res < 0) {
@ -141,8 +146,10 @@ public class SignOnProcess {
flag = true; flag = true;
LogUtil.d(TAG, "Success PIK result code:" + res); LogUtil.d(TAG, "Success PIK result code:" + res);
} }
} catch (RemoteException | GeneralSecurityException e) { } catch (GeneralSecurityException e) {
e.printStackTrace(); e.printStackTrace();
} catch (RemoteException e) {
throw new RuntimeException(e);
} }
} }