6
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

CTAP2 お勉強メモ#7 - NFC

Last updated at Posted at 2019-01-14

#はじめに
これは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で通信する方法を意味します。

##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は意外と簡単でした。

6
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?