TLS Restriction with Private APN

Using TLS implies configuring a hostname, instead of an IP, in the SiTef server address parameter. In order for the TLS component to attest to the authenticity of the server, this hostname must be must be the same as the name on the TLS certificate.

Due to this restriction, TLS communication cannot be used in the GPRS scenario with Private APN. This is because, in general, there is no hostname resolution in this scenario — normally only the VPN IPs are used — which results in the authenticity check of the server's TLS certificate failing. Therefore, if the terminal uses a GPRS chip with Private APN, the application will not be able to use the TLS configuration.

If the application alternates between different forms of communication that include both the public Internet — where the use of TLS is mandatory by standard — as a Private APN — where there needs to be a secure VPN —, the application will need develop a configuration switching mechanism to turn on and off the TLS configuration according to the communication channel.

In other words, if the terminal is using public Internet communication (WiFi, Ethernet, Public APN), the application must activate the TLS configuration and define the Sitef address accordingly (i.e. use hostname instead of IP). And if the terminal is using Private APN communication with VPN, the application must disable the TLS configuration and set the SiTef address accordingly (i.e. use the VPN IP). In this case, it is important to make sure that the rules security measures applied to the application environment allow TLS to be turned off.

The application can implement this behavior in the most appropriate way for the structure of your source code. But, in general terms, the procedure to obtain this behavior must follow the following basic logic:

  1. Before starting each transaction, check which means of communication is currently active.
    1. If the communication requires TLS (if it is WiFi, Ethernet or Cellular with Public APN), enable TLS and set the SiTef address as the SiTef hostname.
    2. If the communication does not support TLS (Cellular with Private APN), disable TLS and set SiTef address as the SiTef IP in the VPN.
  2. Start the transaction.

Below, we illustrate this logic in code snippets considering the scenarios integration with CliSiTef and m-SiTef.

Communication Detection#

public static boolean comunicacaoPermiteTls(Context context) {
boolean result = true;
// Here we are assuming that Cellular communication always uses a
// Private APN. If this is not true, the application must implement a
// additional mechanism to determine whether APN is private or not.
// This check will probably depend on the Android model.
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (cm != null) {
NetworkCapabilities networkCapabilities = cm.getNetworkCapabilities(cm.getActiveNetwork());
if (networkCapabilities != null) {
if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
result = true;
} else if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
result = false;
} else if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET)) {
result = true;
}
}
}
} else {
if (cm != null) {
NetworkInfo activeNetworkInfo = cm.getActiveNetworkInfo();
if (activeNetworkInfo != null) {
if (activeNetworkInfo.getType() == ConnectivityManager.TYPE_WIFI) {
result = true;
} else if (activeNetworkInfo.getType() == ConnectivityManager.TYPE_MOBILE) {
result = false;
} else if (activeNetworkInfo.getType() == ConnectivityManager.TYPE_ETHERNET) {
result = true;
}
}
}
}
return result;
}

CliSiTef Scenario#

// The instantiation and call flow to CliSiTef has been simplified
// to illustrate the connection switching mechanism.
CliSiTef clisitef = new CliSiTef(this.getApplicationContext());
//...
String sitefAddr;
String storeId = "00000000";
String terminalId = "TERM0000";
String comParams;
// Before starting each transaction, check which means of communication is active
// at the time.
if (comunicacaoPermiteTls(getApplicationContext())) {
// If the communication requires TLS (if it is WiFi, Ethernet or Cellular with Public APN),
// enable TLS and set the SiTef address as the SiTef hostname.
comParams = "[TipoComunicacaoExterna=SSL;CaminhoCertificadoCA=ca_cert.pem]";
sitefAddr = "sitef.exemplotls.com.br:20000";
} else {
// If the communication does not support TLS (Cellular with Private APN), disable TLS and
// set SiTef address as the SiTef IP in the VPN.
// (Check if security rules allow you to turn off TLS in your environment!)
comParams = "";
sitefAddr = "192.168.0.2:10000";
}
int res = clisitef.configure(sitefAddr, storeId, terminalId, comParams);
if (res != 0) {
// handle error
}
//...
int modalidade = 0;
String valor = "1000";
String docFiscal = "123456";
String dataFiscal = "20230518";
String horaFiscal = "160000";
String operador = "OPERADOR";
String restricoes = "";
clisitef.startTransaction (this, modalidade, valor, docFiscal, dataFiscal, horaFiscal, operador, restricoes);
//...

m-SiTef Scenario#

Intent i = new Intent("br.com.softwareexpress.sitef.msitef.ACTIVITY_CLISITEF");
i.putExtra("empresaSitef", "00000000");
i.putExtra("operador", "OPERADOR");
i.putExtra("data", "20230519");
i.putExtra("hora", "150000");
i.putExtra("numeroCupom", "123456");
i.putExtra("numParcelas", "3");
i.putExtra("modalidade", "0");
i.putExtra("valor", "9000");
i.putExtra("CNPJ_CPF", "12345678909");
i.putExtra("timeoutColeta", "30");
i.putExtra("acessibilidadeVisual", "0");
// Before starting each transaction, check which means of communication is active
// at the time.
if (comunicacaoPermiteTls(getApplicationContext())) {
// If the communication requires TLS (if it is WiFi, Ethernet or Cellular with Public APN),
// enable TLS and set the SiTef address as the SiTef hostname.
i.putExtra("comExterna", "1");
i.putExtra("enderecoSitef", "sitef.exemplotls.com.br:20000");
} else {
// If the communication does not support TLS (Cellular with Private APN), disable TLS and
// set SiTef address as the SiTef IP in the VPN.
// (Check if security rules allow you to turn off TLS in your environment!)
i.putExtra("comExterna", "0");
i.putExtra("enderecoSitef", "192.168.0.2:10000");
}
// Start the transaction via m-SiTef.
startActivityForResult(i,1234);