The first post in this series described the permissions model for accessing the Android secure element from its contact interface. (Not to be confused with access from contactless aka NFC interface, which is open to any external device in NFC range.) This model can be viewed as a generalization of standard Android signature-based permissions— in fact for Gingerbread it was a vanilla signature permission based on matching the certificate used for signing NFC service.
Starting with ICS, there is an explicit whitelist of allowed signing certificates. Any user application signed with one of these keys can obtain access to the secure element, and more broadly to administrative actions involving the NFC controller such as toggling card emulation mode. These certificates can be retrieved and inspected from any Android device. With adb debugging enabled, an incantation such as “adb shell cat /etc/nfcee_access.xml | xmlstarlet select -T -o -t -v //signer/@signature | xxd -r -ps | openssl x509 -inform DER -text -noout” will dump the certificate on a command line. [Full output]
Step by step:
- Get the XML file containing the whitelist [nfcee_access.xml]
- Locate the first signer element, then its signature attribute. In the above example this is done with an XPath query, with plain text output. On all production devices this blogger has encountered, there is exactly one such node. Development builds can have more. (As an aside, that XML attribute is a misnomer: “signature” contains an X509 certificate, instead of the signature on a particular APK. Same confusion exists in the Android API, where signatures field inside the package description actually contain certificates.)
- Decode the value of the attribute as hex string
- Interpret the result as an X509 certificate in ASN1 encoding, and parse the certificate.
But it is easier to save the certificate output after the third-step with a .der extension [certificate] and open the file using the built-in Windows UI for inspecting certificates:
Android code authentication model uses self-signed certificates– in the above example, the issuer and subject are identical. This is in contrast to Authenticode, where publishers obtain certificates from a trusted third-party certificate authority such as Verisign. When an external issuer is involved, the subject name in the certificate is verified during the issuance process. A competent CA is not supposed to issue a Google certificate to someone not affiliated with Google. (In reality, process failures have occurred, but nowhere with the same frequency as SSL certificate issuance mistakes.) With self-signed certificates, anything goes for the subject name since it is decided entirely by the software publisher, with no external sanity checks. Luckily in this case the field contains sensible information, identifying the publisher as associated with Android and specifically the NFC stack. The important property is that other applications signed using the same key will have access to the secure element. Additional publishers can be granted access by also including their certificates in the whitelist.
That solves half the problem: communicating with the SE from contact interface, or in other words being able to exchange APDUs in terms of developer view. The logical next step is determining what can be done with that capability, which boils down to two questions:
- What features/functionality is present in the SE out of the box?
- If the built-in feature set proves insufficient for some use case, how does one update the SE contents to add new capabilities?
The final post in this series will attempt to elaborate on these questions, which are also discussed in a Stack Overflow thread dedicated to the access control mechanism in ICS.