1 //-----------------------------------------------------------------------------
2 // Copyright (C) 2021 iceman
4 // This code is licensed to you under the terms of the GNU GPL, version 2 or,
5 // at your option, any later version. See the LICENSE.txt file for the text of
7 //-----------------------------------------------------------------------------
9 //-----------------------------------------------------------------------------
10 #include "cmdhfseos.h"
13 #include <ctype.h> // tolower
14 #include "cliparser.h"
15 #include "cmdparser.h" // command_t
16 #include "comms.h" // clearCommandBuffer
20 #include "cmdhf14a.h" // manufacture
21 #include "protocols.h" // definitions of ISO14A/7816 protocol
22 #include "iso7816/apduinfo.h" // GetAPDUCodeDescription
23 #include "crypto/asn1utils.h" // ASN1 decode / print
25 static int CmdHelp(const char *Cmd
);
27 static uint16_t get_sw(uint8_t *d
, uint8_t n
) {
32 return d
[n
] * 0x0100 + d
[n
+ 1];
35 static int seos_select(void) {
36 bool activate_field
= true;
37 bool keep_field_on
= true;
38 uint8_t response
[PM3_CMD_DATA_SIZE
];
41 // --------------- Select SEOS applet ----------------
42 uint8_t aSELECT_AID
[80];
43 int aSELECT_AID_n
= 0;
44 param_gethex_to_eol("00a404000aa000000440000101000100", 0, aSELECT_AID
, sizeof(aSELECT_AID
), &aSELECT_AID_n
);
45 int res
= ExchangeAPDU14a(aSELECT_AID
, aSELECT_AID_n
, activate_field
, keep_field_on
, response
, sizeof(response
), &resplen
);
46 if (res
!= PM3_SUCCESS
) {
56 uint16_t sw
= get_sw(response
, resplen
);
58 PrintAndLogEx(ERR
, "Selecting SEOS applet aid failed (%04x - %s).", sw
, GetAPDUCodeDescription(sw
>> 8, sw
& 0xff));
63 activate_field
= false;
64 keep_field_on
= false;
65 // --------------- CC file reading ----------------
67 uint8_t aSELECT_FILE_ADF
[30];
68 int aSELECT_FILE_ADF_n
= 0;
69 param_gethex_to_eol("80a504001306112b0601040181e43801010201180101020200", 0, aSELECT_FILE_ADF
, sizeof(aSELECT_FILE_ADF
), &aSELECT_FILE_ADF_n
);
70 res
= ExchangeAPDU14a(aSELECT_FILE_ADF
, aSELECT_FILE_ADF_n
, activate_field
, keep_field_on
, response
, sizeof(response
), &resplen
);
71 if (res
!= PM3_SUCCESS
) {
76 sw
= get_sw(response
, resplen
);
78 PrintAndLogEx(ERR
, "Selecting ADF file failed (%04x - %s).", sw
, GetAPDUCodeDescription(sw
>> 8, sw
& 0xff));
83 // remove the 2byte SW
84 asn1_print(response
, resplen
- 2, " ");
88 int infoSeos(bool verbose
) {
89 int res
= seos_select();
90 if (res
== PM3_SUCCESS
) {
91 PrintAndLogEx(NORMAL
, "");
92 PrintAndLogEx(INFO
, "--- " _CYAN_("Tag Information") " ---------------------------");
97 static int CmdHfSeosInfo(const char *Cmd
) {
98 CLIParserContext
*ctx
;
99 CLIParserInit(&ctx
, "hf seos info",
100 "Get info from SEOS tags",
107 CLIExecWithReturn(ctx
, Cmd
, argtable
, true);
109 return infoSeos(true);
112 static int CmdHfSeosList(const char *Cmd
) {
113 return CmdTraceListAlias(Cmd
, "hf seos", "7816");
116 static command_t CommandTable
[] = {
117 {"help", CmdHelp
, AlwaysAvailable
, "This help"},
118 {"info", CmdHfSeosInfo
, IfPm3NfcBarcode
, "Tag information"},
119 {"list", CmdHfSeosList
, AlwaysAvailable
, "List SEOS history"},
120 {NULL
, NULL
, NULL
, NULL
}
123 static int CmdHelp(const char *Cmd
) {
124 (void)Cmd
; // Cmd is not used so far
125 CmdsHelp(CommandTable
);
129 int CmdHFSeos(const char *Cmd
) {
130 clearCommandBuffer();
131 return CmdsParse(CommandTable
, Cmd
);