Let ACardEmulator provide installed AIDs
This commit is contained in:
committed by
Frank Morgner
parent
dae5622992
commit
3501843159
@@ -23,12 +23,6 @@
|
||||
|
||||
package com.vsmartcard.acardemulator;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import javax.security.cert.CertificateException;
|
||||
import javax.security.cert.X509Certificate;
|
||||
import java.util.Arrays;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageInfo;
|
||||
@@ -37,13 +31,25 @@ import android.content.pm.Signature;
|
||||
import android.os.Binder;
|
||||
import android.os.Handler;
|
||||
import android.os.IBinder;
|
||||
import android.widget.Toast;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.samsung.android.sdk.SsdkUnsupportedException;
|
||||
import com.samsung.android.sdk.accessory.*;
|
||||
import com.samsung.android.sdk.accessory.SA;
|
||||
import com.samsung.android.sdk.accessory.SAAgent;
|
||||
import com.samsung.android.sdk.accessory.SAAuthenticationToken;
|
||||
import com.samsung.android.sdk.accessory.SAPeerAgent;
|
||||
import com.samsung.android.sdk.accessory.SASocket;
|
||||
import com.vsmartcard.acardemulator.emulators.EmulatorSingleton;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
|
||||
import javax.security.cert.CertificateException;
|
||||
import javax.security.cert.X509Certificate;
|
||||
|
||||
public class SmartcardProviderService extends SAAgent {
|
||||
private static final String TAG = "ACardEmulator";
|
||||
private static final int ACCESSORY_CHANNEL_ID = 104;
|
||||
@@ -199,14 +205,34 @@ public class SmartcardProviderService extends SAAgent {
|
||||
if (mConnectionHandler == null) {
|
||||
return;
|
||||
}
|
||||
final byte[] response = EmulatorSingleton.process(getApplicationContext(), data);
|
||||
final byte[] sendResponse;
|
||||
if (data[0] == 'd') {
|
||||
// APDU is sent
|
||||
byte[] newData = new byte[data.length - 1];
|
||||
System.arraycopy(data, 1, newData, 0, data.length - 1);
|
||||
byte[] response = EmulatorSingleton.process(getApplicationContext(), newData);
|
||||
sendResponse = new byte[response.length + 1];
|
||||
sendResponse[0] = 'd';
|
||||
System.arraycopy(response, 0, sendResponse, 1, response.length);
|
||||
} else if (data[0] == 'a') {
|
||||
// request for aids
|
||||
String[] aidList = EmulatorSingleton.getRegisteredAids(getApplicationContext());
|
||||
String aidListJoined = TextUtils.join(",", aidList);
|
||||
sendResponse = new byte[aidListJoined.length() + 1];
|
||||
sendResponse[0] = 'a';
|
||||
byte[] aids = aidListJoined.getBytes();
|
||||
System.arraycopy(aids, 0, sendResponse, 1, aids.length);
|
||||
} else {
|
||||
Log.e(TAG, "unknown message from consumer: " + new String(data));
|
||||
return;
|
||||
}
|
||||
new Thread(new Runnable() {
|
||||
public void run() {
|
||||
try {
|
||||
mConnectionHandler.secureSend(ACCESSORY_CHANNEL_ID, response);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
try {
|
||||
mConnectionHandler.secureSend(ACCESSORY_CHANNEL_ID, sendResponse);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
@@ -22,13 +22,25 @@ package com.vsmartcard.acardemulator.emulators;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.res.Resources;
|
||||
import android.content.res.XmlResourceParser;
|
||||
import android.nfc.NfcAdapter;
|
||||
import android.nfc.cardemulation.CardEmulation;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.support.annotation.XmlRes;
|
||||
import android.support.v4.content.LocalBroadcastManager;
|
||||
import android.util.Log;
|
||||
|
||||
import com.vsmartcard.acardemulator.R;
|
||||
import com.vsmartcard.acardemulator.Util;
|
||||
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
import org.xmlpull.v1.XmlPullParserException;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class EmulatorSingleton {
|
||||
public static final String TAG = "com.vsmartcard.acardemulator.EmulatorService";
|
||||
public static final String EXTRA_CAPDU = "MSG_CAPDU";
|
||||
@@ -90,6 +102,32 @@ public class EmulatorSingleton {
|
||||
return rapdu;
|
||||
}
|
||||
|
||||
public static String[] getRegisteredAids(Context context) {
|
||||
List<String> aidList = new ArrayList<>();
|
||||
XmlResourceParser aidXmlParser = context.getResources().getXml(R.xml.aid_list);
|
||||
|
||||
try {
|
||||
while (aidXmlParser.getEventType() != XmlPullParser.END_DOCUMENT) {
|
||||
if (aidXmlParser.getEventType() == XmlPullParser.START_TAG) {
|
||||
if (aidXmlParser.getName().equals("aid-filter")) {
|
||||
int aid = aidXmlParser.getAttributeResourceValue(0, -1);
|
||||
if (aid != -1) {
|
||||
aidList.add(context.getResources().getString(aid));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
aidXmlParser.next();
|
||||
}
|
||||
|
||||
aidXmlParser.close();
|
||||
} catch (XmlPullParserException | IOException e) {
|
||||
Log.e(TAG.substring(0, 23), "Couldn't parse aid xml list.");
|
||||
}
|
||||
|
||||
return aidList.toArray(new String[0]);
|
||||
}
|
||||
|
||||
public static void deactivate() {
|
||||
emulator.deactivate();
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include <nfc.h>
|
||||
|
||||
void send_apdu_response(nfc_se_h handle, unsigned char *resp, unsigned int resp_len);
|
||||
void install_aids(void *buffer, unsigned int buffer_size);
|
||||
|
||||
extern gboolean agent_connected;
|
||||
|
||||
|
||||
@@ -16,7 +16,6 @@ void initialize_sap();
|
||||
gboolean find_peers();
|
||||
gboolean request_service_connection(void);
|
||||
gboolean terminate_service_connection(void);
|
||||
gboolean send_data(nfc_se_h nfc_handle, void *message, unsigned int message_len);
|
||||
GSList* request_installed_aids();
|
||||
gboolean send_data(nfc_se_h nfc_handle, char* prefix, unsigned int prefix_len, void *message, unsigned int message_len);
|
||||
|
||||
#endif /* __tcardemulator_H__ */
|
||||
|
||||
@@ -25,8 +25,7 @@ static priv_s priv_data = { 0 };
|
||||
void on_peer_agent_updated(sap_peer_agent_h peer_agent,
|
||||
sap_peer_agent_status_e peer_status,
|
||||
sap_peer_agent_found_result_e result,
|
||||
void *user_data)
|
||||
{
|
||||
void *user_data) {
|
||||
switch (result) {
|
||||
case SAP_PEER_AGENT_FOUND_RESULT_DEVICE_NOT_CONNECTED:
|
||||
dlog_print(DLOG_INFO, LOG_TAG, "device is not connected");
|
||||
@@ -61,8 +60,7 @@ void on_peer_agent_updated(sap_peer_agent_h peer_agent,
|
||||
static void on_service_connection_terminated(sap_peer_agent_h peer_agent,
|
||||
sap_socket_h socket,
|
||||
sap_service_connection_terminated_reason_e result,
|
||||
void *user_data)
|
||||
{
|
||||
void *user_data) {
|
||||
switch (result) {
|
||||
case SAP_CONNECTION_TERMINATED_REASON_PEER_DISCONNECTED:
|
||||
dlog_print(DLOG_INFO, LOG_TAG, "disconnected because peer lost");
|
||||
@@ -92,26 +90,41 @@ static void on_data_recieved(sap_socket_h socket,
|
||||
void *user_data) {
|
||||
dlog_print(DLOG_INFO, LOG_TAG, "received data: %p, len:%d", buffer, payload_length);
|
||||
|
||||
send_apdu_response(priv_data.nfc_handle, buffer, payload_length);
|
||||
char* string_buffer = (char*) buffer;
|
||||
if (string_buffer[0] == 'a') {
|
||||
install_aids(buffer + sizeof(char), payload_length - 1);
|
||||
} else if (string_buffer[0] == 'd') {
|
||||
send_apdu_response(priv_data.nfc_handle, buffer + sizeof(char), payload_length - 1);
|
||||
}
|
||||
}
|
||||
|
||||
gboolean send_data(nfc_se_h nfc_handle, void *message, unsigned int message_len) {
|
||||
gboolean send_data(nfc_se_h nfc_handle, char* prefix, unsigned int prefix_len, void *message, unsigned int message_len) {
|
||||
gboolean result;
|
||||
priv_data.nfc_handle = nfc_handle;
|
||||
if (nfc_handle != NULL) {
|
||||
priv_data.nfc_handle = nfc_handle;
|
||||
}
|
||||
void *final_message = malloc(prefix_len + message_len);
|
||||
memcpy(final_message, prefix, prefix_len);
|
||||
memcpy(final_message + prefix_len * sizeof(char), message, message_len);
|
||||
result = sap_socket_send_secure_data(priv_data.socket,
|
||||
ACCESSORY_CHANNELID, message_len, message);
|
||||
ACCESSORY_CHANNELID, prefix_len + message_len, final_message);
|
||||
|
||||
if (result != SAP_RESULT_SUCCESS) {
|
||||
dlog_print(DLOG_INFO, LOG_TAG, "couldn't send sap message: %d", result);
|
||||
}
|
||||
|
||||
free(final_message);
|
||||
return result;
|
||||
}
|
||||
|
||||
gboolean request_installed_aids() {
|
||||
return send_data(NULL, "a", 1, "", 0);
|
||||
}
|
||||
|
||||
static void on_service_connection_created(sap_peer_agent_h peer_agent,
|
||||
sap_socket_h socket,
|
||||
sap_service_connection_result_e result,
|
||||
void *user_data)
|
||||
{
|
||||
void *user_data) {
|
||||
switch (result) {
|
||||
case SAP_CONNECTION_SUCCESS:
|
||||
dlog_print(DLOG_INFO, LOG_TAG, "peer agent connection is successful, pa :%u", peer_agent);
|
||||
@@ -122,6 +135,8 @@ static void on_service_connection_created(sap_peer_agent_h peer_agent,
|
||||
sap_socket_set_data_received_cb(socket, on_data_recieved, peer_agent);
|
||||
priv_data.socket = socket;
|
||||
agent_connected = TRUE;
|
||||
|
||||
request_installed_aids();
|
||||
break;
|
||||
|
||||
case SAP_CONNECTION_IN_PROGRESS:
|
||||
@@ -239,18 +254,6 @@ gboolean find_peers()
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
GSList* request_installed_aids() {
|
||||
GSList* aid_list = g_slist_append(NULL, "A000000397425446590201");
|
||||
aid_list = g_slist_append(aid_list, "A0000003974254465902");
|
||||
aid_list = g_slist_append(aid_list, "A00000039742544659");
|
||||
aid_list = g_slist_append(aid_list, "F276A288BCFBA69D34F31001");
|
||||
aid_list = g_slist_append(aid_list, "F000000001");
|
||||
aid_list = g_slist_append(aid_list, "D27600012401");
|
||||
aid_list = g_slist_append(aid_list, "D2760001240102000000000000010000");
|
||||
aid_list = g_slist_append(aid_list, "A000000527210101");
|
||||
return aid_list;
|
||||
}
|
||||
|
||||
static void on_agent_initialized(sap_agent_h agent,
|
||||
sap_agent_initialized_result_e result,
|
||||
void *user_data)
|
||||
|
||||
@@ -27,7 +27,7 @@ static void hce_event_cb(nfc_se_h handle, nfc_hce_event_type_e event, unsigned c
|
||||
case NFC_HCE_EVENT_APDU_RECEIVED:
|
||||
dlog_print(DLOG_DEBUG, LOG_TAG, "received NFC_HCE_EVENT_APDU_RECEIVED event on NFC handle %d", handle);
|
||||
if (agent_connected) {
|
||||
send_data(handle, apdu, apdu_len);
|
||||
send_data(handle, "d", 1, apdu, apdu_len);
|
||||
} else {
|
||||
dlog_print(DLOG_INFO, LOG_TAG, "couldn't send message on SAP channel because agent is not connected");
|
||||
}
|
||||
@@ -39,7 +39,7 @@ static void hce_event_cb(nfc_se_h handle, nfc_hce_event_type_e event, unsigned c
|
||||
}
|
||||
}
|
||||
|
||||
void register_aid(gpointer data, gpointer user_data) {
|
||||
void register_aid(gpointer data) {
|
||||
int result = nfc_se_register_aid(NFC_SE_TYPE_HCE, NFC_CARD_EMULATION_CATEGORY_OTHER, data);
|
||||
if (result != NFC_ERROR_NONE) {
|
||||
dlog_print(DLOG_ERROR, LOG_TAG, "nfc_se_register_aid for aid %s failed: %d", data, result);
|
||||
@@ -48,9 +48,17 @@ void register_aid(gpointer data, gpointer user_data) {
|
||||
}
|
||||
}
|
||||
|
||||
void install_aids() {
|
||||
GSList* aid_list = request_installed_aids();
|
||||
g_slist_foreach(aid_list, register_aid, NULL);
|
||||
void install_aids(void *buffer, unsigned int buffer_size) {
|
||||
gchar aid_string[buffer_size + 1];
|
||||
g_strlcpy(aid_string, (gchar *)buffer, buffer_size + 1);
|
||||
|
||||
gchar **aid_buffer = g_strsplit(aid_string, ",", 0);
|
||||
int i;
|
||||
int aid_len = g_strv_length(aid_buffer);
|
||||
for (i = 0; i < aid_len; i++) {
|
||||
register_aid((gpointer)aid_buffer[i]);
|
||||
}
|
||||
g_strfreev(aid_buffer);
|
||||
}
|
||||
|
||||
void send_apdu_response(nfc_se_h handle, unsigned char *resp, unsigned int resp_len) {
|
||||
@@ -98,8 +106,6 @@ bool service_app_create(void *data) {
|
||||
|
||||
find_peers();
|
||||
|
||||
install_aids();
|
||||
|
||||
r = true;
|
||||
|
||||
err:
|
||||
|
||||
Reference in New Issue
Block a user