blob: c695c4a75d7b44ac3306079c6399aeca16e05ccf [file] [log] [blame]
/*
* Copyright 2022 NXP
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.nxp.sems;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.util.Log;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Vector;
public class SemsFileOperation {
public static final String TAG = "SEMS-SemsFileOperation";
private String mRespOutlog;
private String mEncryptedScriptDirectory = "";
private String mOutDirectory = "";
public String mCallerPackageName;
private static final byte SEMS_RESPONSE = 0x01;
//private static final byte SEResponse = 0x02;
private static final byte ERROR_RESPONSE = 0x03;
//private static final byte SWResponse = 0x04;
private static final byte SEMS_CERT_RESPONSE = 0x05;
private static final byte SEMS_AUTH_RESPONSE = 0x06;
private static final byte SEMS_RESPONSE_LOG_TAG = 0x61;
private static final byte SEMS_FRAME_TYPE_TAG = 0x44; // (CERT/AUTH/SECURE_CMD frame)
private static final byte SEMS_RESPONSE_DATA_TAG = 0x43;
/**
* SemsFileOperation Constructor
* <br/>
* @param void
*
* @return void.
*/
SemsFileOperation() {
// Update start time stamp at beginning
mRespOutlog = getCurrentTimeStamp();
}
/**
* Get current date and time stamp
* <br/>
* Used in response log for debug purpose
* @param void
*
* @return String current data and time stamp.
*/
private String getCurrentTimeStamp() {
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss");
LocalDateTime now = LocalDateTime.now();
return "#######" + dtf.format(now) + "#######"
+ "\r\n";
}
/**
* Logging the response APDU received during SEMS execution
* <br/>
* Agent to provide the SEMS Application with an identifier
* @param byte[] what The Input status bytes
* Byte type The Input type of response
*
* @return void.
*/
public void putIntoLog(byte[] what, byte type) {
byte[] data;
/*Skip SW "6310" as this is not relevant for debug */
if ((what[what.length - 2] == 0x63) && (what[what.length - 1] == 0x10)) {
return;
}
switch (type) {
case ERROR_RESPONSE:
return;
default:
return;
case SEMS_CERT_RESPONSE:
data = new byte[] {0x7F, 0x21};
break;
case SEMS_AUTH_RESPONSE:
data = new byte[] {0x60};
break;
case SEMS_RESPONSE:
data = new byte[] {0x40};
break;
}
data = SemsTLV.make(SEMS_RESPONSE_LOG_TAG,
SemsUtil.append(SemsTLV.make(SEMS_RESPONSE_DATA_TAG, data),
SemsTLV.make(SEMS_RESPONSE_DATA_TAG, what)));
mRespOutlog = mRespOutlog + SemsUtil.toHexString(data) + "\r\n";
}
/**
* Set the current application directory & caller information
* <br/>
* @param context caller application context info
*
* @return {@code SemsStatus} returns SEMS_STATUS_SUCCESS on success
* otherwise SEMS_STATUS_FAILED.
*/
public SemsStatus setDirectories(Context context) {
SemsStatus status = SemsStatus.SEMS_STATUS_FAILED;
PackageInfo pInfo;
PackageManager pm = context.getPackageManager();
String str = context.getPackageName();
synchronized (SemsFileOperation.class) {
try {
pInfo = pm.getPackageInfo(str, 0);
str = pInfo.applicationInfo.dataDir;
mCallerPackageName = pInfo.packageName;
mEncryptedScriptDirectory = str;
mOutDirectory = str;
status = SemsStatus.SEMS_STATUS_SUCCESS;
} catch (Exception e) {
e.printStackTrace();
}
}
return status;
}
/**
* Get path to locate and access file
* <br/>
* @param String dir initial part of path string
* String file filename in the path
*
* @return Path The resulting path.
*/
public Path getPath(String dir, String file) {
return (dir != null) ? FileSystems.getDefault().getPath(dir, file)
: FileSystems.getDefault().getPath(file);
}
/**
* Write the content of accumulated response buffer to out file
* <br/>
* Agent to provide the SEMS Application with an identifier
* @param String scriptOut The file name to write response
*
* @return byte[] Response byte array.
*/
public byte[] writeScriptOutFile(String scriptOut) {
Path p = getPath(mOutDirectory, scriptOut);
// Update finish time stamp at end
mRespOutlog = mRespOutlog + getCurrentTimeStamp();
try {
Files.write(p, mRespOutlog.getBytes());
} catch (IOException e) {
Log.e(TAG, "IOException during writeScriptOutfile: ");
}
return mRespOutlog.getBytes();
}
/**
* Write the content of String buffer to backup file
* <br/>
* @param String filename to which the buffer contents to be copied
* String scriptBuffer input buffer content
*
* @return byte[] response buffer.
*/
public byte[] writeScriptInputFile(String filename, String scriptBuffer) {
Path p = getPath(mOutDirectory, filename);
try {
Files.write(p, scriptBuffer.getBytes());
} catch (IOException e) {
Log.e(TAG, "IOException during writeScriptInputfile: ");
}
return scriptBuffer.getBytes();
}
/**
* Read the file content to String format
* <br/>
* The Input path of the SEMS encrypted script stored,
* @param String scriptIn input SEMS script with metadata
*
* @return String plain script with metadata removed.
*/
public String readScriptFile(String scriptIn) throws Exception {
Path p = getPath(mEncryptedScriptDirectory, scriptIn);
String script = "";
Iterator<String> i;
try {
List<String> lines = Files.readAllLines(p, Charset.defaultCharset());
i = lines.iterator();
while (i.hasNext()) {
String s = i.next();
if (!s.startsWith("%%%")) {
script += s;
}
}
} catch (IOException e) {
Log.e(TAG, "IOException during reading script: ");
throw new Exception();
}
return script;
}
/**
* Get response log buffer string
* <br/>
* @param void
*
* @return String response log buffer.
*/
public String getRespOutLog() {
return mRespOutlog;
}
}