概要
- GSMAはeSIMの仕様策定は行うが、eSIMのテスト・認証に関しては、2018/05からGlobalPlatform及びGCF, PTCRBへ委託
- eSIM (Consumer Model)の場合、下記の2種類のテスト・認証が必要になる
- eUICC (eSIM)自体のテスト・認証 : 主管団体 - GlobalPlatform
- eSIMを使っているハンドセット (device)のテスト・認証 : 主管団体 - GCF, PTCRB
こちらを参照 smartcardguy.hatenablog.jp
package com.sun.jcclassic.samples.service; import javacard.framework.APDU; import javacard.framework.ISOException; import javacard.framework.service.Dispatcher; import javacard.framework.service.Service; /** * */ public class Main extends javacard.framework.Applet { private Dispatcher disp; private Service serv; public Main() { disp = new Dispatcher((short) 1); serv = new TestService(); disp.addService(serv, Dispatcher.PROCESS_COMMAND); register(); } public static void install(byte[] aid, short s, byte b) { new Main(); } @Override public void process(APDU apdu) throws ISOException { if(!selectingApplet()){ disp.process(apdu); } } }
/** * Copyright (c) 1998, 2019, Oracle and/or its affiliates. All rights reserved. * */ package com.sun.jcclassic.samples.service; import javacard.framework.APDU; import javacard.framework.service.BasicService; /** * */ public class TestService extends BasicService { @Override public boolean processCommand(APDU command) { if (getINS(command) == (byte) 0x10) { setOutputLength(command, (short) 1); command.getBuffer()[5] = (byte) 0xAB; succeedWithStatusWord(command, (short) 0x6617); return true; } if (getINS(command) == (byte) 0x20) { setOutputLength(command, (short) 0); succeedWithStatusWord(command, (short) 0x6618); return true; } if (getINS(command) == (byte) 0x30) { setOutputLength(command, (short) 0); succeed(command); return true; } return false; } }
/** * Copyright (c) 1998, 2019, Oracle and/or its affiliates. All rights reserved. * */ package com.sun.jcclassic.samples.service; /** * */ public class PreProcess { /** Creates new PreProcess */ public PreProcess() { } }
package com.sun.jcclassic.samples.service; /** * */ public class PostProcess { /** Creates new PostProcess */ public PostProcess() { } }
//Test script for Applet 'Service' output on; //create Service 0x80 0xB8 0x00 0x00 0x0C 0x0A 0xa0 0x00 0x00 0x00 0x62 0x03 0x01 0x0c 0x09 0x01 0x00 0x7F; // Select Service //aid/A000000062/03010C0901 0x00 0xA4 0x04 0x00 0x0a 0xa0 0x00 0x00 0x00 0x62 0x03 0x01 0x0c 0x09 0x01 0x7F; //Send the APDU here 0x80 0x10 0x00 0x00 0x00 0x7F; 0x80 0x20 0x00 0x00 0x00 0x7F; 0x80 0x30 0x00 0x00 0x00 0x7F;
CMD>//Test script for Applet 'Service' output on; APDU|OUTPUT ON; //create Service 0x80 0xB8 0x00 0x00 0x0C 0x0A 0xa0 0x00 0x00 0x00 0x62 0x03 0x01 0x0c 0x09 0x01 0x00 0x7F; APDU|CLA: 80, INS: b8, P1: 00, P2: 00, Lc: 0c, 0a, a0, 00, 00, 00, 62, 03, 01, 0c, 09, 01, 00, Le: 00, SW1: 64, SW2: 44 // Select Service //aid/A000000062/03010C0901 0x00 0xA4 0x04 0x00 0x0a 0xa0 0x00 0x00 0x00 0x62 0x03 0x01 0x0c 0x09 0x01 0x7F; APDU|CLA: 00, INS: a4, P1: 04, P2: 00, Lc: 0a, a0, 00, 00, 00, 62, 03, 01, 0c, 09, 01, Le: 00, SW1: 90, SW2: 00 //Send the APDU here 0x80 0x10 0x00 0x00 0x00 0x7F; APDU|CLA: 80, INS: 10, P1: 00, P2: 00, Lc: 00, Le: 01, ab, SW1: 66, SW2: 17 0x80 0x20 0x00 0x00 0x00 0x7F; APDU|CLA: 80, INS: 20, P1: 00, P2: 00, Lc: 00, Le: 00, SW1: 66, SW2: 18 0x80 0x30 0x00 0x00 0x00 0x7F; APDU|CLA: 80, INS: 30, P1: 00, P2: 00, Lc: 00, Le: 00, SW1: 90, SW2: 00 CMD>
//Send the APDU here 0x80 0x10 0x00 0x00 0x00 0x7F; <= INS : 10 APDU|CLA: 80, INS: 10, P1: 00, P2: 00, Lc: 00, Le: 01, ab, SW1: 66, SW2: 17 <= Le (Response data length) : 0x01, data : 0xab 0x80 0x20 0x00 0x00 0x00 0x7F; <= INS : 20 APDU|CLA: 80, INS: 20, P1: 00, P2: 00, Lc: 00, Le: 00, SW1: 66, SW2: 18 0x80 0x30 0x00 0x00 0x00 0x7F; <= INS : 30 APDU|CLA: 80, INS: 30, P1: 00, P2: 00, Lc: 00, Le: 00, SW1: 90, SW2: 00
P3 : 0
P3 : Le field
P3 : Lc field
Case 3とCase 2を合わせたCase
public void process(APDU apdu) { byte buffer[] = apdu.getBuffer(); // check SELECT APDU command if ((buffer[ISO7816.OFFSET_CLA] == 0) && (buffer[ISO7816.OFFSET_INS] == (byte) (0xA4))) { return; } short bytesRead = apdu.setIncomingAndReceive(); short echoOffset = (short) 0; while (bytesRead > 0) { Util.arrayCopyNonAtomic(buffer, ISO7816.OFFSET_CDATA, echoBytes, echoOffset, bytesRead); echoOffset += bytesRead; bytesRead = apdu.receiveBytes(ISO7816.OFFSET_CDATA); } apdu.setOutgoing(); apdu.setOutgoingLength((short) (echoOffset + 5)); // echo header apdu.sendBytes((short) 0, (short) 5); // echo data apdu.sendBytesLong(echoBytes, (short) 0, echoOffset); }
Windowsでサンプルを動かす場合、以下の3つだけ!
http://www.oracle.com/technetwork/java/javase/downloads/index.html
https://www.oracle.com/technetwork/java/embedded/javacard/overview/index.html
https://www.eclipse.org/downloads/packages/release
OS : Windows 10 64 bit
正しく取り込んだら下記のように見えるはず。左下の部分がJava Card View。
もしJava Card Viewが見えない場合は、Window => Show View => OthersからJava Card Viewを指定
ST54J : a system-on-chip (SoC) containing an NFC (Near-Field Communication) controller, Secure Element, and eSIM
Java Card ForumのInfographic - How Java Card secures the IoT space