# 7
>So, in case i want to implement verification, compliant with standard ISO7816-4, i have to implement verify, get data and etc. standard apdu commands processing by my own applet.
Yes, you need to implement the 7816-4 commands you need. The GET DATA command is already a GP command. As an example: SELECT[by file id] = 00 A4 02 00 05 11 22 33 44 55 00
. Your applet would need to process this command and e.g. have one byte array which is identified by '11 22 33 44 55'.
> I also have to import GP package and use it secure channel interface?
You need to import org.globalplatform.SecureChannel;
to use the SecureChannel interface
>And off-card which classes do i have to use in JCOP OffCard API: SecurityDomain and CardManager, or anything else?
Check out the JCOP Tools user guide in Eclipse. You can find there the documentation for CardManager and SecurityDomain classes (including the difference).
>if i want o implement applet verification method, i have to implemen GP platform CVM interface?
I do not know what you mean by 'applet verification method'. The GP CVM
interface is just for handling the "global card PIN".
>Could you give some hints, where can i find any samples of off-card and on-card applications, that use secure messaging to make verification safe?
I will give you one example:
Applet source code:
package com.sun.developerforum.javacard.securechannel.example;
import javacard.framework.APDU;
import javacard.framework.Applet;
import javacard.framework.ISO7816;
import javacard.framework.ISOException;
import javacard.framework.Util;
import org.globalplatform.GPSystem;
import org.globalplatform.SecureChannel;
public class SecChannelExample extends Applet {
private static final byte CLA_DO_TEST = (byte) 0x80;
private static final byte CLA_SEC_AUTH = (byte) 0x80;
private static final byte CLA_SEC_MAC_ENC = (byte) 0x84;
private static final byte INS_DO_TESTS = (byte) 0x20;
private static final byte P1_PROCESS_SECURITY = 1;
private static final byte P1_WRAP = 2;
private static final byte P1_UNWRAP = 3;
private static final byte P1_DECRYPT_DATA = 4;
private static final byte P1_ENCRYPT_DATA = 5;
private static final byte P1_RESET_SECURITY = 6;
private static final byte P1_GET_SECURITY_LEVEL = 7;
private static final byte INS_INIT_UPD = (byte) 0x50;
private static final byte INS_EXT_AUTH = (byte) 0x82;
private static final byte INS_PUT_KEY = (byte) 0xD8;
protected SecChannelExample(byte bArray[], short bOffset, byte bLength) {
register();
}
public static void install(byte[] bArray, short bOffset, byte bLength) {
new SecChannelExample(bArray, bOffset, bLength);
}
public void process(APDU apdu) {
if (selectingApplet())
return;
byte[] buffer = apdu.getBuffer();
short len = 0;
if ((buffer[ISO7816.OFFSET_CLA] == CLA_DO_TEST) || (buffer[ISO7816.OFFSET_CLA] == ISO7816.CLA_ISO7816)
|| (buffer[ISO7816.OFFSET_CLA] == CLA_SEC_AUTH) || (buffer[ISO7816.OFFSET_CLA] == CLA_SEC_MAC_ENC)) {
short bytesReceived = apdu.setIncomingAndReceive();
SecureChannel secCh = GPSystem.getSecureChannel();
switch (buffer[ISO7816.OFFSET_INS]) {
case INS_INIT_UPD:
secCh = GPSystem.getSecureChannel();
len = secCh.processSecurity(apdu);
apdu.setOutgoingAndSend(ISO7816.OFFSET_CDATA, len);
break;
case INS_EXT_AUTH:
secCh = GPSystem.getSecureChannel();
len = secCh.processSecurity(apdu);
apdu.setOutgoingAndSend(ISO7816.OFFSET_CDATA, len);
break;
case INS_PUT_KEY:
len = secCh.unwrap(buffer, (short) 0, (short) (bytesReceived + 5));
buffer[len] = (byte) 0xDE;
buffer[len + 1] = (byte) 0xCA;
buffer[len + 2] = (byte) 0xFF;
buffer[len + 3] = (byte) 0xED;
apdu.setOutgoingAndSend((short) 0, (short) (len + 4));
break;
case INS_DO_TESTS:
switch (buffer[ISO7816.OFFSET_P1]) {
case P1_PROCESS_SECURITY:
len = secCh.processSecurity(apdu);
apdu.setOutgoingAndSend(ISO7816.OFFSET_CDATA, len);
break;
case P1_WRAP:
len = secCh.wrap(buffer, (short) 0, (short) (bytesReceived + 5));
apdu.setOutgoingAndSend(ISO7816.OFFSET_CDATA, (short) (len - 5));
break;
case P1_UNWRAP:
len = secCh.unwrap(buffer, (short) 0, (short) (bytesReceived + 5));
buffer[len] = (byte) 0xDE;
buffer[len + 1] = (byte) 0xCA;
buffer[len + 2] = (byte) 0xFF;
buffer[len + 3] = (byte) 0xED;
apdu.setOutgoingAndSend((short) 0, (short) (len + 4));
break;
case P1_DECRYPT_DATA:
len = secCh.decryptData(buffer, ISO7816.OFFSET_CDATA, (short) (bytesReceived));
apdu.setOutgoingAndSend((short) 0, len);
break;
case P1_ENCRYPT_DATA:
len = secCh.encryptData(buffer, ISO7816.OFFSET_CDATA, (short) (bytesReceived));
apdu.setOutgoingAndSend((short) 0, len);
break;
case P1_RESET_SECURITY:
secCh.resetSecurity();
break;
case P1_GET_SECURITY_LEVEL:
ISOException.throwIt(Util.makeShort((byte) 0x90, secCh.getSecurityLevel()));
break;
default:
ISOException.throwIt(ISO7816.SW_INCORRECT_P1P2); // unsupported P1
break;
}
break;
default: // unsupported INS
ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
}
} else { // unsupported CLA
ISOException.throwIt(ISO7816.SW_CLA_NOT_SUPPORTED);
}
}
}
APDU trace (commented):
cm> /term "Remote|localhost:2825"
--Opening terminal
> /card -a a000000003000000 -c com.ibm.jc.CardManager
resetCard with timeout: 0 (ms)
--Waiting for card...
ATR=3B FA 13 00 00 81 31 FE 45 4A 43 4F 50 34 31 56;.....1.EJCOP41V
322x.
ATR: T=1, FI=1/DI=3 (93clk/etu), N=0, IFSC=254, BWI=4/CWI=5, Hist="JCOP41V2x"
=> 00 A4 04 00 08 A0 00 00 00 03 00 00 00 00 ..............
(1449 usec)
<= 6F 65 84 08 .. ..*.
Status: No Error
cm> set-key 255/1/DES-ECB/404142434445464748494a4b4c4d4e4f 255/2/DES-ECB/404142434445464748494a4b4c4d4e4f 255/3/DES-ECB/404142434445464748494a4b4c4d4e4f
cm> init-update 255
=> 80 50 00 00 08 BE 1D CA AB 3C 0F 01 7D 00 .P.......<..}.
(3928 usec)
<= 00 00 0D B9 90 A3 51 8E 15 4C FF 02 00 00 3D 02......Q..L....=.
9C 31 C7 89 1E 83 A6 E7 DE 28 56 97 90 00 .1.......(V...
Status: No Error
cm> ext-auth plain
=> 84 82 00 00 10 BD F3 26 16 CC BB AF 9B 19 67 CC.......&......g.
A1 A6 17 92 6F ....o
(4313 usec)
<= 90 00 ..
Status: No Error
cm> upload -d -b 250 "xx\com\sun\developerforum\javacard\securechannel\example\javacard\example.cap"
=> 80 E6 02 00 14 07 73 74 75 64 79 47 50 08 A0 00......studyGP...
00 00 03 00 00 00 00 00 00 00 ..........
(5582 usec)
<= 00 90 00...
Status: No Error
=> 80 E8 00 00 ..
..
<= 00 90 00...
Status: No Error
cm> install -i 73747564795343 -q C9#() 73747564794750 73747564795343
=> 80 E6 0C 00 1E 07 73 74 75 64 79 47 50 07 73 74......studyGP.st
75 64 79 53 43 07 73 74 75 64 79 53 43 01 00 02udySC.studySC...
C9 00 00 00....
(5401 usec)
<= 90 00 ..
Status: No Error
cm> card-info
Card Manager AID: A000000003000000
Card Manager state : OP_READY
Application: SELECTABLE (--) "studySC"
Load File :LOADED (--) A0000000035350(Security Domain)
Module:A000000003535041
Load File :LOADED (--) "studyGP"
Module:"studySC"
// install the pre-loaded SSD with SD privilege and install parameter 0x45 --> accept extradition
cm> install -s -i A000000003535041 -q C9#("45") A0000000035350 A000000003535041
=> 80 E6 0C 00 21 07 A0 00 00 00 03 53 50 08 A0 00....!......SP...
00 00 03 53 50 41 08 A0 00 00 00 03 53 50 41 01...SPA......SPA.
80 03 C9 01 45 00 00....E..
(5952 usec)
<= 90 00 ..
Status: No Error
// new key-set for the ISD
cm> set-key 1/1/DES-ECB/505152535455565758595a5b5c5d5e5f 1/2/DES-ECB/505152535455565758595a5b5c5d5e5f 1/3/DES-ECB/505152535455565758595a5b5c5d5e5f
cm> put-keyset 1
=> 80 D8 00 81 43 01 80 10 13 F5 67 38 72 99 BA 1F....C.....g8r...
A1 79 EA AF 18 C8 CD E4 03 A4 B7 D6 80 10 13 F5.y..............
67 38 72 99 BA 1F A1 79 EA AF 18 C8 CD E4 03 A4g8r....y........
B7 D6 80 10 13 F5 67 38 72 99 BA 1F A1 79 EA AF......g8r....y..
18 C8 CD E4 03 A4 B7 D6 00 .........
(10415 usec)
<= 01 A4 B7 D6 A4 B7 D6 A4 B7 D6 90 00............
Status: No Error
cm> /select A000000003535041
=> 00 A4 04 00 08 A0 00 00 00 03 53 50 41 00 ..........SPA.
(1239 usec)
<= 6F 65 84 08 A0 00 00 00 03 53 50 41 A5 59 9F 65oe.......SPA.Y.e
01 FF 9F 6E 06 40 51 70 92 00 00 73 4A 06 07 2A...n.@Qp...sJ..*
86 48 86 FC 6B 01 60 0C 06 0A 2A 86 48 86 FC 6B.H..k.`...*.H..k
02 02 01 01 63 09 06 07 2A 86 48 86 FC 6B 03 64....c...*.H..k.d
0B 06 09 2A 86 48 86 FC 6B 04 02 15 65 0B 06 09...*.H..k...e...
2B 85 10 86 48 64 02 01 03 66 0C 06 0A 2B 06 01+...Hd...f...+..
04 01 2A 02 6E 01 02 90 00 ..*.n....
Status: No Error
cm> init-update 255
=> 80 50 00 00 08 56 47 84 CE BF 68 14 86 00 .P...VG...h...
(5623 usec)
<= 00 00 0D B9 90 A3 51 8E 15 4C 01 02 00 00 83 3A......Q..L.....:
E7 33 25 19 8B 1E 33 E7 74 8D DF B7 90 00 .3%...3.t.....
Status: No Error
cm> ext-auth plain
=> 84 82 00 00 10 82 5F 38 6A 5A 42 BD C4 24 22 8E......_8jZB..$".
E6 6C 27 2C 2E .l',.
(8266 usec)
<= 90 00 ..
Status: No Error
cm> set-key 2/1/DES-ECB/606162636465666768696a6b6c6d6e6f 2/2/DES-ECB/606162636465666768696a6b6c6d6e6f 2/3/DES-ECB/606162636465666768696a6b6c6d6e6f
cm> put-keyset 2
=> 80 D8 00 81 43 02 80 10 CD E5 2D A6 F3 33 C5 5C....C.....-..3.\
16 DD 34 35 8C A8 90 0B 03 9D CB 14 80 10 CD E5..45............
2D A6 F3 33 C5 5C 16 DD 34 35 8C A8 90 0B 03 9D-..3.\..45......
CB 14 80 10 CD E5 2D A6 F3 33 C5 5C 16 DD 34 35......-..3.\..45
8C A8 90 0B 03 9D CB 14 00 .........
(10264 usec)
<= 02 9D CB 14 9D CB 14 9D CB 14 90 00............
Status: No Error
cm> select
=> 00 A4 04 00 08 A0 00 00 00 03 00 00 00 00 ..............
(1417 usec)
<= 6F 65 84 08 A0 00 00 00 03 00 00 00 A5 59 9F 65oe...........Y.e
01 FF 9F 6E 06 40 51 70 92 00 00 73 4A 06 07 2A...n.@Qp...sJ..*
86 48 86 FC 6B 01 60 0C 06 0A 2A 86 48 86 FC 6B.H..k.`...*.H..k
02 02 01 01 63 09 06 07 2A 86 48 86 FC 6B 03 64....c...*.H..k.d
0B 06 09 2A 86 48 86 FC 6B 04 02 15 65 0B 06 09...*.H..k...e...
2B 85 10 86 48 64 02 01 03 66 0C 06 0A 2B 06 01+...Hd...f...+..
04 01 2A 02 6E 01 02 90 00 ..*.n....
Status: No Error
cm> init-update 1
=> 80 50 01 00 08 6A DD 7E 08 C3 F2 D1 E8 00 .P...j.~......
(4225 usec)
<= 00 00 0D B9 90 A3 51 8E 15 4C 01 02 00 01 6C C3......Q..L....l.
58 75 1A 43 4B 16 0A CE 45 71 EE D4 90 00 Xu.CK...Eq....
Status: No Error
cm> ext-auth plain
=> 84 82 00 00 10 F2 2B 91 52 02 5E E0 DE 03 DD A9......+.R.^.....
78 3B B4 0B A3 x;...
(4436 usec)
<= 90 00 ..
Status: No Error
=> card-info
// Pay attention to the SSD: it is now PERSONALIZED! (due to put key)
Card Manager AID: A000000003000000
Card Manager state : OP_READY
Application: SELECTABLE (--) "studySC"
Sec. Domain:PERSONALIZED (S-) A000000003535041
Load File :LOADED (--) A0000000035350(Security Domain)
Module:A000000003535041
Load File :LOADED (--) "studyGP"
Module:"studySC"
// let's give our applet a new home
cm> extradite A000000003535041 |studySC
=> 80 E6 10 00 15 08 A0 00 00 00 03 53 50 41 00 07...........SPA..
73 74 75 64 79 53 43 00 00 00 00studySC....
(2911 usec)
<= 00 90 00...
Status: No Error
// BEHOLD! we are talking with the applet!
cm> /select |studySC
=> 00 A4 04 00 07 73 74 75 64 79 53 43 00 .....studySC.
(2447 usec)
<= 90 00 ..
Status: No Error
// channel init-update
// ISD key-set: 1, SSD key-set: 2 - applet extradited to SSD --> key-set 1 can't work
cm> init-update 1
=> 80 50 01 00 08 87 90 5B EA 3C B8 B1 DA 00 .P.....[.<....
(4230 usec)
<= 6A 88 j.
Status: Reference data not found
jcshell: Error code: 6a88 (Reference data not found)
jcshell: Wrong response APDU: 6A88
// this should work with key-set 2 (SSD)
cm> init-update 2
=> 80 50 02 00 08 E4 00 3A FB F5 0A 30 1E 00 .P.....:...0..
(5369 usec)
<= 50 41 00 00 00 00 00 00 00 00 02 02 00 00 8E 0EPA..............
20 1E E9 2F BB 64 CC 86 84 45 36 F4 90 00../.d...E6...
Status: No Error
// channel ext-auth
cm> ext-auth enc
=> 84 82 03 00 10 54 BD 85 B5 F6 A5 B0 18 7E E2 63.....T.......~.c
8A 6A D4 2C 13 .j.,.
(4883 usec)
<= 90 00 ..
Status: No Error
// nice feature in JCShell: encrypt according to the secure channel setup
cm> send 8020030014|XurAndTheKoDanArmada
=> 84 20 03 00 20 AE CE 46 91 EA 32 84 A7 8D 0A 5C. .. ..F..2....\
7A FC 50 3B EA 9D B3 11 39 0D 73 C1 FA 67 F0 0Ez.P;....9.s..g..
D0 E9 44 94 19 ..D..
(3686 usec)
// WOW! sent encrypted and received decrypted
<= 80 20 03 00 14 58 75 72 41 6E 64 54 68 65 4B 6F. ...XurAndTheKo
44 61 6E 41 72 6D 61 64 61 DE CA FF ED 90 00DanArmada......
Status: No Error
Message was edited by:
lexdabear