Help us understand the problem. What is going on with this article?

CTAP2 お勉強メモ#7 - NFC

はじめに

これはCTAPのお勉強をしたメモです。
WebAuthn(ウェブオースン)ではなく、CTAP(シータップ)であります。

今回はCTAP2のNFC(Near Field Communication)です。

教科書

教材

復習

目次

1.Yubikeyについて
2.CTAP NFC
2.1 WindowsでNFCで通信するお作法
2.2 APDU Protocol
3.おまけ

1.Yubikeyについて

Yubikey5です。
HIDだけでなくNFCでFIDO2(CTAP2)を話すことができます。
さらにFIDOだけでなく OTP,OpenPGP,PIV,OATH などいろんなことができるらしいです。

本デバイスを検証するにあたっていきなりハマったのですが、どうやらOTPの機能が有効になっているとFIDOの機能が使えないようで、CTAPのコマンドが通りません。
今回はCTAPの検証がしたいので、他の機能は無効にしました。

  • (1) Yubikey ManagerをDLしてインストール
  • (2) USBにYubikey5をさしてYubikey Managerを起動
  • (3) InterfaceメニューからFIDO2関係だけチェックONに変更して「Save」

2. CTAP NFC

NFCでYubikeyとお話する方法はCTAP仕様では
8.2. ISO7816, ISO14443 and Near Field Communication (NFC)
だけです。
つまり、基本的なことを知っていれば簡単です。

基本的なこととは何か?
- CTAP2コマンド
- NFC通信の基本

CTAP2コマンド

これはこれまでのお勉強メモで学習済みです。過去の投稿を見て思い出します。

NFC通信の基本

ISO7816, ISO14443と書いてあります。
これは以前検証したマイナンバーカードと通信する方法と同じで、winscard―APIを使ってAPDUで通信する方法を意味します。
- ICカードとお話する方法
- APDUコマンド

2.1 WindowsでNFCで通信するお作法

エラー処理をちゃんとやるともう少し複雑になりますが、おおざっぱにはこんな感じです。
SCard系のAPIは決められた手順でCallするおまじないみたいなものです。
重要なのはScardTransmitで送信するAPDUです。
APDUというバイナリのパケットにCTAPコマンドを詰めて送ります。この辺のめんどくささはCTAPHIDと同じです。ただCTAPHIDよりはずっと簡単です。

2.2 APDU Protocol

CTAP仕様書 8.2.2. Protocol

The general protocol between a FIDO2 client and an authenticator over ISO7816/ISO14443 is as follows:
- Client sends an applet selection command
- Authenticator replies with success if the applet is present
- Client sends a command for an operation
- Authenticator replies with response data or error

クライアントとAuthenticatorのISO7816/ISO14443手順は以下の通り
- Clientはappletを選択するコマンドを送信する
- Authenticatorからの応答を受ける(appletへの接続)
- Clientは(CTAP)コマンドを送信する
- Authenticatorからの応答を受ける(CTAPコマンドの応答)

appletを選択するコマンド

ISO7816/ISO14443というのはAuthenticatorがいわゆるICカードのふるまいをするということです。
ICカードは中にアプリ(applet)を複数格納できる仕様になっています。
Clientはまず、FIDOアプリに接続(SELECT)します。

CTAP仕様書 8.2.3. Applet selection

  • APDU image.png
  • AID

例 SELECT FILE FIDO applet

// APDU
00 A4 04 00 08 A0 00 00 06 47 2f 00 01 00

// Response
55 32 46 5F 56 32 90 00

APDU解説

APDU = [0x00, 0xA4, 0x04, 0x00], [0x08], [0xA0, 0x00, 0x00, 0x06, 0x47, 0x2f, 0x00, 0x01],[0x00]

固定値のところは仕様書に書いてある値をそのまま使えばいいです。

byte no 項目名 説明
0 CLA 00 命令クラス 固定値
1 INS A4 コマンド名 Select File 固定値
2 P1 04 パラメータ1 固定値
3 P2 00 パラメータ2 固定値
4 Lc 08 データサイズ 固定値
5-12 Data A0...01 データ Selectするアプリ識別子(AID) 固定値
13 Le 00 レスポンスバッファサイズ 00でOK

Response解説

Response = [0x55, 0x32, 0x46, 0x5F, 0x56, 0x32],0x90, 0x00 ← 正常終了という意味

byte no 項目名 説明
0-5 Data 55...32 version information ASCII変換で"U2F_V2"
6 SW1 90 ステータスワード1 0x90で正常終了という意味
7 SW2 00 ステータスワード2

厳密にはversion informationの中身を見て自分とこの実装に対応しているかどうかチェックするみたいです。
ステータスワードはAPDUの仕様で以下のような意味です。
Eternal Windowsより抜粋させていただきました。

CTAPコマンドをAPDUで送信する

FIDO appletをSELECTしてResponseが正常にGETできたら、続けざまにAPDUでCTAPコマンドを送信します。

CTAP仕様書 8.2.4. Framing

  • APDU
    image.png

  • Response

image.png

APDU解説

APDU解説はもういいやってくらいのシンプルさなので Data In のところだけ解説。
CTAPコマンドの長さ(バイト数)を1バイトで指定した後、CTAPコマンド(例によってCBORエンコードしたもの)を設定し、最後のLe0x00を指定します。

Response解説

そうするとレスポンスが返ってきます。
最初の1バイトがCTAPのステータスコード(6.3. Status codes)でその後ろがデータ。最後の2バイトがAPDUのSW1、SW2で0x9000 だったらOKということです。

例 authenticatorGetInfo (0x04)コマンド

例えば CTAPのauthenticatorGetInfo コマンドの場合

CTAPコマンドだけを取り出すとこんな感じ
//CTAP Command authenticatorGetInfo
04

// Response
00
A6 01 82 66 55 32 46 5F 56 32 68 46 49 44 4F 5F
32 5F 30 02 81 6B 68 6D 61 63 2D 73 65 63 72 65
74 03 50 FA 2B 99 DC 9E 39 42 57 8F 92 4A 30 D2
3C 41 18 04 A4 62 72 6B F5 62 75 70 F5 64 70 6C
61 74 F4 69 63 6C 69 65 6E 74 50 69 6E F5 05 19
04 B0 06 81 01
CBORデコードして見やすくするとこんな感じ
//CTAP Command authenticatorGetInfo
0x04

// Response
<Status>
0x00(CTAP1_ERR_SUCCESS Indicates successful response.)

<ResponseData-Decoded COBOR>
{
    "1":["U2F_V2","FIDO_2_0"],
    "2":["hmac-secret"],
    "3":"-iuZ3J45QlePkkow0jxBGA",
    "4":{"rk":true,"up":true,"plat":false,"clientPin":true},
    "5":1200,
    "6":[1]
}

これをAPDUにするとこうなります

APDU
// SendAPDU
80 10 00 00 01 04 00

// Response
00
A6 01 82 66 55 32 46 5F 56 32 68 46 49 44 4F 5F
32 5F 30 02 81 6B 68 6D 61 63 2D 73 65 63 72 65
74 03 50 FA 2B 99 DC 9E 39 42 57 8F 92 4A 30 D2
3C 41 18 04 A4 62 72 6B F5 62 75 70 F5 64 70 6C
61 74 F4 69 63 6C 69 65 6E 74 50 69 6E F5 05 19
04 B0 06 81 01
90 00

CTAPコマンドをAPDUで送信する2

以下のケースに対応する仕様があります。
- 分割送信:送信するCommandが長い時の対応
- 分割受信:受信するResponseが長いときの対応

分割送信

送信するAPDUのData Inでは最初の1byte目でデータのレングスを指定します。
1byteということは0x00~0xFFの範囲です。
つまり、255byteを超える場合は1個のコマンドでは送信しきれません。
そんな時は分割して何回かに分けて送ります。

8.2.5. Fragmentation

  • データにまだ続きがあるよってときは0x90から始まるこっちのAPDUで送ります。
    Data In の書き方がわかりにくいですが、さっき説明したData Inの形式と同じで最初の1byte目がレングスです。つまり CTAP Command Byte || COBR Encoded Data
    image.png
    このコマンドに対する応答は9000の2byteだけ返ってきます。

  • これが最後ってときは先ほど説明した0x80から始まるAPDUで送ります。
    image.png

分割受信

レスポンスにはレングスフィールドがないんですけど、同じように分割して送られて来る時があります。
そんな時はSW1が 0x61 になっています。ISO 7816-4の仕様のようです。

image.png

この辺のサンプルが
8.2.5. Fragmentation
EXAMPLE 9に書いてあります。

3.おまけ

WebAuthnぽいことができるWinデスクトップアプリ用ライブラリ WebAuthnModokiDesktopβのNFC対応を行いました。
ここで勉強した内容を反映しています。
もう、ソースがぐちゃぐちゃ...

おつかれさまでした

NFCは意外と簡単でした。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした