Emulating a PKI smart card with CyanogenMod 9.1
We discussed the embedded secure element available in recent Android devices, it's execution environment and how Google Wallet makes use if it in the last series of articles. We also saw that unless you have a contract with Google and have them (or the TSM they use) distribute your applets to supported devices, there is currently no way to install anything on the embedded secure element. We briefly mentioned that CyanogenMod 9.1 supports software card emulation and it is a more practical way to create your own NFC-enabled applications. We'll now see how software card emulation works and show how you can use it to create a simple PKI 'applet' that can be accessed via NFC from any machine with a contactless card reader.
Both of the newly introduced tag technologies extend
Now that we know (basically) how it works, let's try to use software card emulation in practice.
PKI has been getting a lot of bad rep due to major CAs getting compromised every other month, and it has been stated multiple times that it doesn't really work on the Internet. It is however still a valid means of authentication in a corporate environment where personal certificates are used for anything from desktop login to remote VPN access. Certificates and associated private keys are often distributed on smart cards, sometimes contactless or dual-interface. Since Android now has standard credential storage which can be protected by hardware on supported devices, we could use an Android phone with software card emulation in place of a PKI card. Let's try to write a simple PKI 'applet' and an associated host-side client application to see if this is indeed feasible.
Software card emulation
We already know that if the embedded secure element is put in virtual mode it is visible to external readers as a contactless smartcard. Software card emulation (sometimes referred to as Host Card Emulation or HCE) does something very similar, but instead of routing commands received by the NFC controller to the SE, it delivers them to the application processor, and they can be processed by regular applications. Responses are then sent via NFC to the reader, and thus your app takes the role of a virtual contactless 'smartcard' (refer to this paper for a more thorough discussion). Software card emulation is currently available on BlackBerry phones, which offer standard APIs for apps to register with the OS and process card commands received over NFC. Besides a BlackBerry device, you can use some contactless readers in emulation mode to emulate NFC tags or a full-featured smart card. Stock Android doesn't (yet) support software card emulation, even though the NFC controllers in most current phones have this capability. Fortunately, recent version of CyanogenMod integrate a set of patches that unlock this functionality of the PN544 NFC controller found in recent Nexus (and other) devices. Let's see how it works in a bit more detail.
CyanogenMod implementation
Android doesn't provide a direct interface to its NFC subsystem to user-level apps. Instead, it leverages the OS's intent and intent filter infrastructure to let apps register for a particular NFC event (ACTION_NDEF_DISCOVERED
, ACTION_TAG_DISCOVERED
and ACTION_TECH_DISCOVERED
) and specify additional filters based on tag type or features. When a matching NFC tag is found, interested applications are notified and one of them is selected to handle the event, either by the user or automatically if it is in the foreground and has registered for foreground dispatch. The app can then access a generic Tag
object representing the target NFC device and use it to retrieve a concrete tag technology interface such as MifareClassic
or IsoDep
that lets it communicate with the device and use its native features. Card emulation support in CyanogenMod doesn't attempt to change or amend Android's NFC architecture, but integrates with it by adding support for two new tag technologies: IsoPcdA
and IsoPcdB
. 'ISO' here is the International Organization for Standardization, which among other things, is responsible for defining NFC communication standards. 'PCD' stands for Proximity Coupling Device, which is simply ISO-speak for a contactless reader. The two classes cover the two main NFC flavours in use today (outside of Japan, at least) -- Type A (based on NXP technology) and Type B (based on Motorolla technology). As you might have guessed by now, the patch reverses the usual roles in the Android NFC API: the external contactless reader is presented as a 'tag', and 'commands' you send from the phone are actually replies to the reader-initiated communication. If you have Google Wallet installed the embedded secure element is activated as well, so touching the phone to a reader would produce a potential conflict: should it route commands to the embedded SE or to applications than can handle IsoPcdA/B
tags? The CyanogenMod patch handles this by using Android's native foreground dispatch mechanism: software card emulation is only enabled for apps that register for foreground dispatch of the relevant tag technologies. So unless you have an emulation app in the foreground, all communication would be routed to Google Wallet (i.e., the embedded SE). In practice though, starting up Google Wallet on ROMs with the current version of the patch might block software card emulation, so it works best if Google Wallet is not installed. A fix is available, but not yet merged in CyanogenMod master (Updated: now merged, should roll out with CM10 nightlies) .Both of the newly introduced tag technologies extend
BasicTagTechnology
and offer methods to open, check and close the connection to the reader. They add a public transceive()
method that acts as the main communication interface: it receives reader commands and sends the responses generated by your app to the PCD. Here's a summary of the interface: abstract class BasicTagTechnology implements TagTechnology { public boolean isConnected() {...} public void connect() throws IOException {...} public void reconnect() throws IOException {...} public void close() throws IOException {...} byte[] transceive(byte[] data, boolean raw) throws IOException {...} }
Now that we know (basically) how it works, let's try to use software card emulation in practice.
Emulating a contactless card
As discussed in the previous section, to be able to respond to reader commands we need to register our app for one of the PCD tag technologies and enable foreground dispatch. This is no different than handling stock-supported NFC technologies. We need to add an intent filter and a reference to a technology filter file to the app's manifest:
We register the
And then use the same technology list to register for foreground dispatch in our activity:
With this in place, each time the phone is touched to an active reader, we will get notified via the activity's
Now after we
<activity android:label="@string/app_name" android:launchmode="singleTop" android:name=".MainActivity" <intent-filter> <action android:name="android.nfc.action.TECH_DISCOVERED" /> </intent-filter> <meta-data android:name="android.nfc.action.TECH_DISCOVERED" android:resource="@xml/filter_nfc" /> </activity>
We register the
IsoPcdA
tag technology in filter_nfc.xml
: <resources> <tech-list> <tech>android.nfc.tech.IsoPcdA</tech> </tech-list> </resources>
And then use the same technology list to register for foreground dispatch in our activity:
public class MainActivity extends Activity { public void onCreate(Bundle savedInstanceState) { pendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0); filters = new IntentFilter[] { new IntentFilter( NfcAdapter.ACTION_TECH_DISCOVERED) }; techLists = new String[][] { { "android.nfc.tech.IsoPcdA" } }; } public void onResume() { super.onResume(); if (adapter != null) { adapter.enableForegroundDispatch(this, pendingIntent, filters, techLists); } } public void onPause() { super.onPause(); if (adapter != null) { adapter.disableForegroundDispatch(this); } } }
With this in place, each time the phone is touched to an active reader, we will get notified via the activity's
onNewIntent()
method. We can get a reference to the Tag
object using the intent's extras as usual. However, since neither IsoPcdA
nor its superclass are part of the public SDK, we need to either build the app as part of CyanogenMod's source, or, as usual, resort to reflection. We choose to create a simple wrapper class that calls IsoPcdA
methods via reflection, after getting an instance using the static get()
method like this: Class cls = Class.forName("android.nfc.tech.IsoPcdA"); Method get = cls.getMethod("get", Tag.class); // this returns an IsoPcdA instance tagTech = get.invoke(null, tag);
Now after we
connect()
we can use the transceive()
method to reply to reader commands. Note that since the API is not event-driven, you won't get notified with the reader command automatically. You need to send a dummy payload to retrieve the first reader command APDU. This can be a bit awkward at first, but you just have to keep in mind that each time you call transceive()
the next reader command comes in via the return value. Unfortunately this means that after you send your last response, the thread will block on I/O waiting for transceive()
to return, which only happens after the reader sends its next command, which might be never. The thread will only stop if an exception is thrown, such as when communication is lost after separating the phone from the reader. Needless to say, this makes writing robust code a bit tricky. Here's how to start off the communication: // send dummy data to get first command APDU // at least two bytes to keep smartcardio happy byte[] cmd = transceive(new byte[] { (byte) 0x90, 0x00 });
Writing a virtual PKI applet
Software card emulation in CyanogneMod is limited to ISO 14443-4 (used mostly for APDU-based communication), which means that you cannot emulate cards that operate on a lower-level protocol such as MIFARE Classic. This leaves out opening door locks that rely on the card UID with your phone (the UID of the emulated card is random) or getting a free ride on the subway (you cannot clone a traffic card with software alone), but allows for emulating payment (EMV) cards which use an APDU-based protocol. In fact, the first commercial application (company started by patch author Doug Yeager) that makes use of Android software card emulation, Tapp, emulates a contactless Visa card and does all necessary processing 'in the cloud', i.e., on a remote server. Payment applications are the ones most likely to be developed using software card emulation because of the potentially higher revenue: at least one other company has announced that it is building a cloud-based NFC secure element. We, however, will look at a different use case: PKI.PKI has been getting a lot of bad rep due to major CAs getting compromised every other month, and it has been stated multiple times that it doesn't really work on the Internet. It is however still a valid means of authentication in a corporate environment where personal certificates are used for anything from desktop login to remote VPN access. Certificates and associated private keys are often distributed on smart cards, sometimes contactless or dual-interface. Since Android now has standard credential storage which can be protected by hardware on supported devices, we could use an Android phone with software card emulation in place of a PKI card. Let's try to write a simple PKI 'applet' and an associated host-side client application to see if this is indeed feasible.
A PKI JavaCard applet can offers various features, but the essential ones are:
- generating or importing keys
- importing a public key certificate
- user authentication (PIN verification)
- signing and/or encryption with card keys
VERIFY PIN
and SIGN DATA
. The protocol is summarized in the table below:Command | CLA | INS | P1 | P2 | Lc | Data | Response |
---|---|---|---|---|---|---|---|
SELECT | 00 | A4 | 04 | 00 | 06 | AID: A0000000010110 | 9000/6985/6A82/6F00 |
VERIFY PIN | 80 | 01 | XX | XX | PIN length (bytes) | PIN characters (ASCII) | 9000/6982/6985/6F00 |
SIGN DATA | 80 | 02 | XX | XX | Signed data length (bytes) | Signed data | 9000+signature bytes/6982/6985/6F00 |
The applet behaviour is rather simple: it returns a generic error if you try to send any commands before selecting it, and then requires you to authenticate by verifying the PIN before signing data. To implement the applet, we first handle new connections from a reader in the main activity's
The applet in turn starts a background thread that reads commands until available and exits if communication with the reader is lost. The implementation is not terribly robust, but is works well enough for our POC:
onNewIntent()
method, where we receive an Intent
containing a reference to the IsoPcdA
object we use to communicate with the PCD. We verify that the request comes from a card reader, create a wrapper for the Tag
object, connect()
to the reader and finally pass control to the PkiApplet
by calling it's start()
method. Tag tag = (Tag) intent.getExtras().get(NfcAdapter.EXTRA_TAG); ListtechList = Arrays.asList(tag.getTechList()); if (!techList.contains("android.nfc.tech.IsoPcdA")) { return; } TagWrapper tw = new TagWrapper(tag, "android.nfc.tech.IsoPcdA"); if (!tw.isConnected()) { tw.connect(); } pkiApplet.start(tw);
The applet in turn starts a background thread that reads commands until available and exits if communication with the reader is lost. The implementation is not terribly robust, but is works well enough for our POC:
Runnable r = new Runnable() { public void run() { try { // send dummy data to get first command APDU byte[] cmd = transceive(new byte[] { (byte) 0x90, 0x00 }); do { // process commands } while (cmd != null && !Thread.interrupted()); } catch (IOException e) { // connection with reader lost return; } } }; appletThread = new Thread(r); appletThread.start();
Before the applet can be used it needs to be 'personalized'. In our case this means importing the private key the applet will use for signing and setting a PIN. To initialize the private key we import a PKCS#12 file using the
To make things simple, applet clients send the PIN in clear text, so it could theoretically be sniffed if NFC traffic is intercepted. This can be avoided by using some sort of a challenge-response mechanism, similar to what 'real' (e.g., EMV) cards do. Once the PIN is verified, clients can send the data to be signed and receive the signature bytes in the response. Since the size of APDU data is limited to 255 bytes (due to the single byte length field) and the applet doesn't support any sort of chaining, we are limited to using RSA keys up to 1024 bits long (a 2048-bit key needs 256 bytes). The actual applet implementation is quite straightforward: it does some minimal checks on received APDU commands, gets the PIN or signed data and uses it to execute the corresponding operation. It then selects a status code based on operation success or failure and returns it along with the result data in the response APDU. See the source code for details.
And to prove that this all works, here's the output from a test run of the client application:
This software implementation comes, of course, with the disadvantage that while the actual private key might be protected by Android's system key store, PIN verification and other operations not directly protected by the OS will be executed in a regular app. An Android app, unlike a dedicated smart card, could be compromised by other (malicious) apps with sufficient privileges. However, since recent Android devices do have (some) support for a Trusted Execution Environment (TEE), the sensitive parts of our virtual applet can be implemented as Trusted Application (TA) running within the TEE. The user-level app would then communicate with the TA using the controlled TEE interface, and the security level of the system could come very close to running an actual applet in a dedicated SE.
KeyChain
API and store the private key alias in shared preferences. The PIN is protected using 5000 iterations of PBKDF2 with a 64-bit salt. We store the resulting PIN hash and the salt in shared preferences as well and repeat the calculation against the PIN we receive from applet clients to check if it matches. This avoids storing the PIN in clear text, but keep in mind that a short numeric-only PIN can be brute-forced in minutes (the app doesn't restrict PIN size, it can be up to 255 characters (bytes), the maximum size of APDU data). Here's how our 'personalization' UI looks like:To make things simple, applet clients send the PIN in clear text, so it could theoretically be sniffed if NFC traffic is intercepted. This can be avoided by using some sort of a challenge-response mechanism, similar to what 'real' (e.g., EMV) cards do. Once the PIN is verified, clients can send the data to be signed and receive the signature bytes in the response. Since the size of APDU data is limited to 255 bytes (due to the single byte length field) and the applet doesn't support any sort of chaining, we are limited to using RSA keys up to 1024 bits long (a 2048-bit key needs 256 bytes). The actual applet implementation is quite straightforward: it does some minimal checks on received APDU commands, gets the PIN or signed data and uses it to execute the corresponding operation. It then selects a status code based on operation success or failure and returns it along with the result data in the response APDU. See the source code for details.
Writing a host-side applet client
Now that we have an applet, we need a host-side client to actually make use of it. As we mentioned above, for a real-world implementation this would be a standard PKCS#11 or CSP module for the host operating system that plugs into PKI-enabled applications such as browsers or email and VPN clients. We'll however create our own test Java client using the Smart Card I/O API (JSR 268). This API comes with Sun/Oracle Java SDKs since version 1.6 (Java 6), but is not officially a part of the SDK, because it is apparently not 'of sufficiently wide interest' according to the JSR expert group (committee BS at its best!). Eclipse goes as far as to flag it as a 'forbidden reference API', so you'll need to change error handling preferences to compile in Eclipse. In practice though, JSR 268 is a standard API that works fine on Windows, Solaris, Linux an Mac OS X (you may have to set thesun.security.smartcardio.library
system property to point to your system's PC/SC library), so we'll use it for our POC application. The API comes with classes representing card readers, the communication channel and command and response APDUs. After we get a reference to a reader and then a card, we can create a channel and exchange APDUs with the card. Our PKI applet client is a basic command line program that waits for card availability and then simply sends the SELECT
, VERIFY PIN
and SIGN DATA
commands in sequence, bailing out on any error (card response with status different from 0x9000
). The PIN is specified in the first command line parameter and if you pass a certificate file path as the second one, it will use it to verify the signature it gets from the applet. See full code for details, but here's how to connect to a card and send a command:TerminalFactory factory = TerminalFactory.getDefault(); CardTerminals terminals = factory.terminals(); Card card = waitForCard(terminals); CardChannel channel = card.getBasicChannel(); CommandAPDU cmd = new CommandAPDU(CMD); ResponseAPDU response = channel.transmit(cmd); Card waitForCard(CardTerminals terminals) throws CardException { while (true) { for (CardTerminal ct : terminals .list(CardTerminals.State.CARD_INSERTION)) { return ct.connect("*"); } terminals.waitForChange(); } }
And to prove that this all works, here's the output from a test run of the client application:
$ ./run.sh 1234 mycert.crt Place phone/card on reader to start --> 00A4040006A0000000010101 <-- 9000 --> 800100000431323334 <-- 9000 --> 80020000087369676E206D6521 <-- 11C44A5448... 9000 (128) Got signature from card: 11C44A5448... Will use certificate from 'mycert.crt' to verify signature Issuer: CN=test-CA, ST=Tokyo, C=JP Subject: CN=test, ST=Tokyo, C=JP Not Before: Wed Nov 30 00:04:31 JST 2011 Not After: Thu Nov 29 00:04:31 JST 2012 Signature is valid: true
This software implementation comes, of course, with the disadvantage that while the actual private key might be protected by Android's system key store, PIN verification and other operations not directly protected by the OS will be executed in a regular app. An Android app, unlike a dedicated smart card, could be compromised by other (malicious) apps with sufficient privileges. However, since recent Android devices do have (some) support for a Trusted Execution Environment (TEE), the sensitive parts of our virtual applet can be implemented as Trusted Application (TA) running within the TEE. The user-level app would then communicate with the TA using the controlled TEE interface, and the security level of the system could come very close to running an actual applet in a dedicated SE.
Summary
Android already supports NFC card emulation using an embedded SE (stock Android) or the UICC (various vendor firmwares). However, both of those are tightly controlled by their owning entities (Google or MNOs), and there is currently no way for third party developers to install applets and create card emulation apps. An alternative to SE-based card emulation is software card emulation, where an user-level app processes reader commands and returns responses via the NFC controller. This is supported by commonly deployed NFC controller chips, but is not implemented in the stock Andorid NFC subsystem. Recent versions of CyanogneMod however do enable it by adding support for two more tag technologies (
IsoPcdA
and IsoPcdB
) that represent contactless readers instead of actual tags. This allows Android applications to emulate pretty much any ISO 14443-4 compliant contactless card application: from EMV payment applications to any custom JavaCard applet. We presented a sample app that emulates a PKI card, allowing you to store PKI credentials on your phone and potentially use it for desktop login or VPN access on any machine equipped with a contacltess reader. Hopefully software card emulation will become a part of stock Android in the future, making this and other card emulation NFC applications mainstream.
Comments
I would like to thank you about your current documentation. Now, we have the ability to enable software card emulation as well as to implement our payment applications on Android phones. On the current documentation, the host-side applet client is a Java client using the Smart Card I/O API (PC). Is it possible the host-side applet client to be an Android NFC Reader app (Android phone) and it will communicate with your software card emulation?
br,
Anargyros
in the blog post you wrote:
"Software card emulation in CyanogneMod is limited to ISO 14443-4 (used mostly for APDU-based communication), which means that you cannot emulate cards that operate on a lower-level protocol such as MIFARE Classic. This leaves out opening door locks that rely on the card UID with your phone (the UID of the emulated card is random)"
In the past I've tested certain implementations (for a research project) that use Mifare Classic 1K and 4K cards. My tests with copied cards have shown that the implemented systems do not use the Sector 0 of the Mifare Classic card. Would that mean that with the current Cyanogen NFC emulation mode it could be possible to emulate a Mifare Classic Card successfully ? Given that the backend system of a lock does not care about Sector 0 of the card?
Thank you very much for the fast reply and for clearing up my confusion. I read up a bit on the ISO standard from my understanding (as far as the standardization goes) Mifare Classic uses the standards ISO 14443-1,2,3 and instead of using ISO 14443-4 they use their own proprietary protocol. So please correct me if I am wrong, it's not a lower level ( technically ) but rather a different implementation? I am basing this on the fact that Mifare Classic is ISO 14443-3 compliant ( so it has to build on top of that standard ).
I also wanted to clear one more thing up if you have the time. Where does ISO 14443-A (like Mifare Classic) and ISO 14443-B come into play here? The information that I could find is a bit messy and there seems to be a bit too much confusion around it. If you could point me to a decent source or a Ven diagram :D .
Regards,
Sebastian Carlier.
You might want to read the ISO standards to clear any confusion. You need to pay for the final versions, but you can find the final drafts on the Internet for free. For example here: http://wg8.de/sd1.html#14443
Thanks again for the fast reply, you saved me a lot of time. I will look into the details of those documents knowing more or less what to expect.
Thanks a lot for the superb tutorial and all the provided information+code.
Using the ideas in your post, I could export a javacard applet that we used for a access system embedded in an UICC to a android-app running on a CM10 "Nexus S" and "Galaxy Nexus". Having done this, we could not only test the app running on the mobile device, successfully but it was also way faster than card emulation on the UICC variant.
I have in this point 2 questions:
1) The instability problem. You also mention this problem in your post. I observed that after the last APDU exchange with the reader and mobile device, the transceive() of the BasicTechTechnology method throws an "transceive failed" exception which I cannot analyze further from the SDK. Is it a behavior that you also encountered? If yes, would you have hint or idea to fix or make the transaction flow more robust?
In the current situation, only after removing and retouching the handset the transaction flow can be repeated successfully again.
2) This question is more essential tough I'm not sure you can comment on that: Having HCE enabled in the CM, developers can start to focusing on real-world applications such as payment and access - like SimplyTapp just doing it. In order to make these solutions widespread tough, HCE must be available in the android's official releases as you can't say common mobile users to root and flash their handsets with CM before they can start using your app. How do you see the chances that Google would sooner or later accept and release the HCE functionality?
Thanks in advance.
Tunc
For 1), I don' know of any solution. Once you receive an APDU, it will block waiting for the next one and you cannot really interrupt it. Look at the latest source in CM, maybe something has been done about that. As for being much faster, that is expected, since you are running on the application processor, which is light-speed compared to the SIM.
As for 2), unfortunately I don't think it's very likely. HCE is not in 4.2 and the Nexus 4 is running a completely different NFC stack (the chip is not from NXP), so even the CM patch won't work anymore.
Anyone tried this on Nexus7 and CM10?
I have downloaded the se-emulator and the se-pki-client. When I tap the phone on the nfc reader (ACS ACR122), the APDU logged (received?) by the phone aren't the same sent by the se-pki-client app. Furthermore, the se-pki-client doesn't receive any response to the select apdu command.
When se-pki-client starts and I tap the phone to the reader, I see the following log:
'Place phone/card on reader to start'.
When I remove the phone from the reader, the following exception are thrown:
'Exception in thread "main" java.lang.RuntimeException: javax.smartcardio.CardException: connect() failed
at org.nick.sepkiclient.Main.main(Main.java:105)
Caused by: javax.smartcardio.CardException: connect() failed
at sun.security.smartcardio.TerminalImpl.connect(Unknown Source)
at org.nick.sepkiclient.Main.waitForCard(Main.java:183)
at org.nick.sepkiclient.Main.main(Main.java:48)
Caused by: sun.security.smartcardio.PCSCException: SCARD_E_READER_UNAVAILABLE
at sun.security.smartcardio.PCSC.SCardConnect(Native Method)
at sun.security.smartcardio.CardImpl.(Unknown Source)
... 3 more'
Below the logs on phone side:
'D/MainActivity(1410): onResume()
D/PkiApplet(1410): Started applet thread 'PKI applet thread#139'
D/MainActivity(1410): Acquiring wakelock
D/PkiApplet(1410): [PKI applet thread#139] --> 9000
D/PkiApplet(1410): [PKI applet thread#139] <-- 00A4040009A00000039742544659
E/PkiApplet(1410): Invalid AID: 00A4040009A00000039742544659
D/PkiApplet(1410): [PKI applet thread#139] --> 6A82
D/PkiApplet(1410): [PKI applet thread#139] <-- 00A4040009A00000030800001000'
Have you some suggestions??
Thanks in advance,
Salvatore
I use windows7.
Thanks,
Salvatore
[0] http://www.nxp.com/documents/leaflet/75016890.pdf
[1] http://lxr.free-electrons.com/source/drivers/nfc/pn544.c?v=3.0
First possibility: Do not use Windows 7 ;)
Second possibility (worked for me as well): Get exclusive access to the card:
System.out.println("Place phone/card on reader to start");
Card card = waitForCard(terminals);
card.beginExclusive(); // <-- add this line
See also http://docs.oracle.com/javase/6/docs/jre/api/security/smartcardio/spec/javax/smartcardio/Card.html#beginExclusive%28%29
I am currently using a rooted Nexus 4 with Cyanogen Mod 10.1 running. Also using a VivoPay 4800 Card Reader.
I have been able to get access to the secure element and activate card emulation using the nfc_extras package through reflection. I have also added my app to nfcee_access.xml. My debugger is showing me NFC-EE ON and NFC-C ON when the app runs and all seems to working fine.
The problem occurs when I try to communicate with the card reader. The reader detects the phone upon contact and beeps twice (suppose to beep once when successful), but the phone does not detect anything whatsoever. I expected either onResume() or onNewIntent() to be called when the reader is brought into close contact, but that does not happen. In fact, nothing at all appears in the debugger. Google Wallet on the other hand works fine with the reader and it respons back with the selected AID of the card reader.
I would like to send a command using transceive upon the tech being discovered. My question is, how does the phone detect the card reader when it is near by? How can I initiate/trigger the communication between the two?
Thank you for the many blogposts and reply, you have been a great help!
I'm trying to explore EMV Contactless as a part of my dissertation in University?
Can I use your source code and modify it. Appropriate reference will be included.
I'm struggling with my phone emulating a 14443 Type B card. I read your documentation (compliments) and used your source as the base for my app. However, when I present the phone (galaxy SIII w/CM10.1) to the reader I just can't seem to intercept the event/Intent.
The phone DOES send an ATP to the reader, which actually is:
11 e1 13 01 02 10 21 02 01 00 91 7d de 6d 00 00 00 00 33 81 84 00 b5 8a
which is a pure Type B card answer to poll.
On the device (looking at LogCat) nothing seems to happens, although earlier I do see;
06-22 22:29:17.160: D/NfcDispatcher(2528): Set Foreground Dispatch.
Probably I'm missing something here. Do you have *any* idea what is happening?
Thank you very much for any help.
Tony.
Reading some more last night (particularly your article on the secure element access) can it be that the phone's secure element is talking to the reader, and software doesn't even come into play here? SOMEONE is talking to the reader. As shown above, I can trace the reader at low level.
I'm sorry if these seem ignorant questions, I come from the field of card readers and smartcards (public transportation), but android and smart phones are really new to me. What I'm trying to achieve here is have the phone talk to the legacy reader. I'm not trying to do anything fancy (yet), just have the reader detect the phone (which it seems to do) and send from the phone some apdu when it fires the Found Reader! event (which I am clearly missing).
Thanks again,
tony.
The reader is a standard reader which does talk 14443 with other cards (through adpu exchange) and I don't have Google Wallet installed. Just a clean CM10.1 and gapps-jb-20130301.
It is definitely the app that activates card emulation, because if I don't start it, the reader does not detect the phone. Btw; what exactly activates the card emulation in your app? Is it the enableForegroundDispatch() with the PcdB tech?
Problem is only that I don't get an onNewIntent() call when the phone gets into the field, and the reader detects it.
Thanks again,
tony.
Look, I really don't want to bother you too much. If you want I can send you the zipped project for a quick look. It is really a reduced version of your application, with all the PKI stuff removed. Other than that, I you don't see anything fundamentally wrong with the concept, I'll just try and debug further, and see where I get.
adapter.enableForegroundDispatch(this, pendingIntent, null, null);
I get a whole bunch of the following when presenting the phone to the reader:
06-23 17:41:32.595: W/NfceeAccess(5833): denied NFCEE access for it.point44.vvcard with signature: ....
Adapting the signature in the nfcee_access.xml file will say "GRANTED", but it still doesn't change the behavior with onNewIntent(). Is this significant?
Thanks a lot,
Tony.
I just can't figure it out, the phone DOES send a correct type B sequence to the reader(s), but the phone just won't fire off an onNewIntent(). Well, such is life.
Thanks for all your help,
Tony.
Thanks for your valuable explanations. I have a question, I am planning to develop a prototype that has the ability to read from smartcard and also phone. In the prototype, there are a nfc reader connecting to the pc, a smartphone, and a smartcard. Which smartcard and smartcard reader is the easiest(also unproblematic) one for this? I was going to try with Mifare but you said Mifare is not working with card emulation. Which card type can you suggest? The model and platform do not matter. You may say any platform rather than Android. Thank you.
Does anyone know that will it work with HTC One or Galaxy S4? If not, what is your recomm for the newest device that will work?
i am working with slc011 reader, and i'am using your code but it didnt work is the probleme with this kind of reader because i saw that you are working with the AC.. reader.
Thanks for your detail explanation on how to emulate a smart card with CM9.1. However, do you think its possible to emulate a smart card without CM? As I am having a project for a NFC android phone to communicate with readers that through ISO7816 but SE seems cannot be skipped even security is not my concern. Just like SimplyTapp that it doesn't have any SE in the device but in cloud and no CM is used. That means technically it can be done if I can emulate the "cloud SE" like SimplyTapp. Do you think it works? Thanks and again thanks for your sharing.
The client: Card card = waitForCard(terminals) don't work. I think the progress is run the client first,then wait me to push the phone on....the client don't wait. So i play the phone on the reader first then run the client and i can't keep it happy. so I let the code byte[] cmd = transceive(new byte[] { (byte) 0x90, 0x00 }); run more times, it works at some time.
I think there would be some problems in javax.smartcardio, my windows 7,and my new acsReader, I had try some windows SCardGetStatusChange() code, It can wait my card, but it seemly the phone can't paly as a real card, it can't response the reader intime。
http://www.mifarecards-rfid.com
Sorry a litlle bit of topic
I like to know if a card like ATR14w , 125 khz modulatian ASK ,is possible to emulate on android ,knowing android it is working on 13,56 mhz ?