Qu'est-ce qu'un APDU, et quand le code en a-t-il besoin ?
Un APDU est la commande et la réponse d'ISO/IEC 7816-4. Une commande porte quatre octets d'en-tête, CLA, INS, P1 et P2, puis des données facultatives et une longueur attendue ; la réponse porte des données et deux octets de statut. Le code en a besoin sur un tag de type 4 ou une carte, par IsoDep ou NFCISO7816Tag.
Commande et réponse
Un APDU de commande commence par quatre octets. CLA donne la classe de l'instruction, INS l'instruction elle-même, P1 et P2 ses paramètres. Les données suivent quand la commande en envoie, précédées de leur longueur, Lc, et la commande peut finir par Le, la longueur de la réponse qu'elle attend. L'initialiseur NFCISO7816APDU d'Apple en construit un à partir de ces champs exactement.
Les longueurs viennent en deux tailles. Un APDU standard porte au plus 255 octets de données, 261 octets en tout, et un APDU étendu jusqu'à 65535, selon la référence d'IsoDep, et certains contrôleurs Android refusent la forme étendue, comme l'explique la page des limites du contrôleur. L'initialiseur d'Apple encode Le à partir d'un nombre : 256 envoie 00 dans la forme courte, 65536 envoie 0000 dans la forme étendue, et -1 déclare qu'aucune donnée de réponse n'est attendue.
La réponse est faite de données suivies de deux octets de statut, SW1 et SW2. Les données peuvent être vides, et Apple note qu'elles peuvent l'être même quand la commande a abouti.
Quand le code en a besoin
Dès que le tag parle ISO/IEC 7816-4 : les tags de type 4, qui rangent le NDEF dans des fichiers atteints par des APDU, et les cartes bâties sur ISO/IEC 14443-4, qu'Android expose par IsoDep. Un tag de type 2 ne le fait pas ; il répond aux commandes NFC-A décrites sur la page de la mémoire de type 2.
Sur Android, IsoDep.transceive() envoie l'APDU et rend la réponse avec ses deux octets de statut à la fin. Sur iOS, une session de tag délivre NFCISO7816Tag et son sendCommand(apdu:) ; pour les tags MIFARE Plus et DESFire délivrés comme NFCMiFareTag, Apple fournit sendMiFareISO7816Command pour le même usage.
Lire ou écrire du NDEF sur un tag de type 4 ne demande aucun APDU construit à la main : la classe Ndef d'Android et les appels NDEF de Core NFC le font. Le code construit des APDU pour ce que le NDEF ne couvre pas, un fichier autre que le fichier NDEF, une condition d'accès, ou une application à lui. La page du fichier NDEF de type 4 suit la séquence que les plateformes déroulent.
La sélection vient d'abord
Une carte ISO/IEC 7816-4 contient des applications et des fichiers, et une commande agit sur ce qui est sélectionné à cet instant. SELECT, instruction 0xA4, choisit par nom quand P1 vaut 0x04, le nom étant un identifiant d'application, et par identifiant de fichier quand P1 vaut 0x00. Ce sont les valeurs qu'emploie la pile NFC libre d'Android pour atteindre le NDEF sur un tag de type 4.
iOS restreint la première sorte. Un SELECT dont P1 vaut 0x04 doit nommer une application listée dans l'Info.plist de l'application, faute de quoi l'appel échoue avec readerErrorSecurityViolation, selon la référence de sendCommand. La session sélectionne aussi l'une des applications listées quand elle découvre le tag, et dit laquelle dans initialSelectedAID ; la page des déclarations couvre cette liste.
Une sélection ne dure pas plus que l'alimentation du tag. Un tag qui quitte le champ perd les deux, donc un code qui se reconnecte sélectionne à nouveau l'application avant sa commande suivante.
Lire les octets de statut
90 00 veut dire que la commande a abouti. Les autres valeurs viennent d'ISO/IEC 7816-4 ou de l'application de la carte, et la pile Android nomme celles qu'un lecteur de type 4 rencontre le plus souvent :
| SW1 SW2 | Signification |
|---|---|
90 00 | Commande aboutie |
6A 82 | Fichier ou application introuvable |
67 00 | Longueur incorrecte |
69 86 | Commande non autorisée |
6B 00 | Paramètres incorrects |
6D 00 | Instruction non prise en charge |
6E 00 | Classe non prise en charge |
Chaque plateforme les cache à sa façon. Sur Android ce sont les deux derniers octets du tableau que rend transceive(), et un code qui traite tout le tableau comme des données les prend pour du contenu. Sur iOS l'erreur ne couvre que la communication, et une application qui regarde l'erreur et non sw1 et sw2 prend un refus pour un succès.
Questions fréquentes
Un tag de type 2 emploie-t-il des APDU ?
Non. Il répond à des commandes NFC-A comme READ et WRITE ; les APDU appartiennent aux tags de type 4 et aux cartes bâties sur ISO/IEC 14443-4.
Pourquoi iOS refuse-t-il ma commande SELECT ?
Un SELECT par identifiant d'application doit nommer un identifiant listé dans l'Info.plist. Sinon Core NFC fait échouer l'appel avec readerErrorSecurityViolation.
Que veut dire 6A 82 ?
Que le fichier ou l'application nommé dans la commande est introuvable. Après un SELECT de l'application NDEF, cela veut dire que le tag n'en a pas.
Un APDU est-il chiffré ?
Pas par son format. La protection, quand une carte en a une, est définie par l'application de la carte et décrite dans la fiche technique de la puce.