diff --git a/app/src/main/cpp/api.cpp b/app/src/main/cpp/api.cpp index 6a0717e..c6c3052 100644 --- a/app/src/main/cpp/api.cpp +++ b/app/src/main/cpp/api.cpp @@ -142,10 +142,10 @@ Connector::Response Connector::sendICC(int cla, int ins, int p1, int p2, int ne, } sm->decrypt(DO->value); response.data = DO->value; - logBytes("decrypted %s", response.data); if (isPadded) { iso9797_unpad(response.data); } + logBytes("decrypted %s", response.data); response.success = true; response.code = (do99->value[0] << 8) | do99->value[1]; } @@ -196,11 +196,24 @@ Connector::Response Connector::readBinaryBySFI(int sfi, int offset) { return sendICC(ISO7816_CLA::NO_SM, ISO7816_INS::READ_BINARY, sfi, offset, readAheadLength, t); } -Connector::Response Connector::readBinaryExt(int offset, int ne) { - // make data with TLV 0x54 for offset - bytes data; - int truncated_offset; - return sendICC(ISO7816_CLA::NO_SM, ISO7816_INS::READ_BINARY_EXT, 0, 0, truncated_offset, data); +Connector::Response Connector::readBinaryExt(size_t offset, size_t ne) { + int ne_nbyte = bytecount(ne); + int addBytes = 1 + ne_nbyte + (ne > 0x80 ? 1 : 0); + if (ne <= 256) { + ne = ne + addBytes < 256 ? ne + addBytes : 256; + } else { + ne = ne + addBytes; + } + + bytes data = num2bytes(offset); + data.erase(data.begin(), data.end() - bytecount(offset)); + TLV(0x54, data); + return sendICC(ISO7816_CLA::NO_SM, ISO7816_INS::READ_BINARY_EXT, 0, 0, ne, data); +} +Connector::Response Connector::readBinaryNormal(size_t offset, size_t toRead) { + LOGI("Read normal offset=%d len=%d"); + bytes t; + return sendICC(ISO7816_CLA::NO_SM, ISO7816_INS::READ_BINARY, offset >> 8, offset & 0xff, toRead, t); } bool Connector::selectDf1() { @@ -314,7 +327,82 @@ void Connector::initBAC() { return; } +bytes Connector::readFileBySFI(int sfi) { + auto seek = readBinaryBySFI(sfi, 0); + auto t = TLV(seek.data, false); + + // [TAG | LENGTH | DATA] + // LENGTH denotes DATA length + // but we seek 8 bytes a head so we must offset with correct length + auto length = t.length - (seek.data.size() - t.size); + auto rest = readBinary(seek.data.size(), length); + + bytes content; + content.insert(content.end(), seek.data.begin(), seek.data.end()); + content.insert(content.end(), rest.begin(), rest.end()); + return content; +} + +bytes Connector::readBinary(size_t offset, size_t length) { + bytes r; + const size_t maxToRead = 256; + + LOGI("INIT READ FILE offset=%d len=%d", offset, length); + while (length > 0) { + size_t toRead = length > maxToRead ? maxToRead : length; + LOGI("READ FILE offset=%d len=%d", offset, toRead); + Connector::Response response; + if (offset > 0x7fff) { + // extended read + response = readBinaryExt(offset, toRead); + } else { + // normal read + if (offset + toRead > 0x7fff) { + toRead = 0x7fff - offset; + } + response = readBinaryNormal(offset, toRead); + } + + const int s = response.data.size(); + r.insert(r.end(), response.data.begin(), response.data.end()); + offset += s; + length -= s; + } + return r; +} + void Connector::readEFCOM() { - auto binary = readBinaryBySFI(EFCOM_SFI, 0); - auto decoded = TLV(binary.data); + auto content = readFileBySFI(EFCOM_SFI); + LOGI("FILE COM size %d", content.size()); + logBytes("FILE COM %s", content); +} +void Connector::readEFDG1() { + auto content = readFileBySFI(EFDG1_SFI); + LOGI("FILE DG1 size %d", content.size()); + logBytes("FILE DG1 %s", content); +} +void Connector::readEFDG2() { + auto content = readFileBySFI(EFDG2_SFI); + LOGI("FILE DG2 size %d", content.size()); + logBytes("FILE DG2 %s", content); +} +void Connector::readEFDG13() { + auto content = readFileBySFI(EFDG13_SFI); + LOGI("FILE DG13 size %d", content.size()); + logBytes("FILE DG13 %s", content); +} +void Connector::readEFDG14() { + auto content = readFileBySFI(EFDG14_SFI); + LOGI("FILE DG14 size %d", content.size()); + logBytes("FILE DG14 %s", content); +} +void Connector::readEFDG15() { + auto content = readFileBySFI(EFDG15_SFI); + LOGI("FILE DG15 size %d", content.size()); + logBytes("FILE DG15 %s", content); +} +void Connector::readEFSOD() { + auto content = readFileBySFI(EFSOD_SFI); + LOGI("FILE SOD size %d", content.size()); + logBytes("FILE SOD %s", content); } \ No newline at end of file diff --git a/app/src/main/cpp/api.h b/app/src/main/cpp/api.h index 6ea229d..a59744a 100644 --- a/app/src/main/cpp/api.h +++ b/app/src/main/cpp/api.h @@ -27,7 +27,7 @@ public: } // decode to TLV - TLV(bytes data) { + TLV(bytes data, bool full = true) { size_t offset = 0; tag = data[offset++]; if (tag == 0x1f) { @@ -43,12 +43,16 @@ public: if (length_nbyte > 3) { throw "length too big to decode"; } + length = 0; for (size_t i = 0; i < length_nbyte; i++) { length <<= 8; length |= data[offset++]; } } + size = offset; + if (!full) return; + value.insert(value.end(), data.begin() + offset, data.begin() + offset + length); size = offset + length; } @@ -72,7 +76,7 @@ public: bytes encoded; encoded.insert(encoded.end(), tag_encoded.begin(), tag_encoded.end()); encoded.insert(encoded.end(), len_encoded.begin(), len_encoded.end()); - encoded.insert(value.end(), value.begin(), value.end()); + encoded.insert(encoded.end(), value.begin(), value.end()); return encoded; } }; @@ -218,9 +222,11 @@ private: Connector::Response externalAuthenticate(bytes& eifd, uint64_t mifd); Connector::Response readBinaryBySFI(int sfi, int offset); - Connector::Response readBinaryExt(int offset, int ne); + Connector::Response readBinaryExt(size_t offset, size_t ne); + Connector::Response readBinaryNormal(size_t offset, size_t ne); -// setupSecureMessaging(); + bytes readFileBySFI(int sfi); + bytes readBinary(size_t offset, size_t length); public: transceive_type transceive; @@ -233,6 +239,13 @@ public: bool selectDf1(); void initBAC(); void readEFCOM(); + void readEFDG1(); + void readEFDG2(); + void readEFDG13(); + void readEFDG14(); + void readEFDG15(); + void readEFSOD(); + }; #endif //CCCC_API_H diff --git a/app/src/main/cpp/consts.h b/app/src/main/cpp/consts.h index aa8b573..6bb6731 100644 --- a/app/src/main/cpp/consts.h +++ b/app/src/main/cpp/consts.h @@ -65,4 +65,14 @@ constexpr int defaultSelectP2 = (ISO97816_SelectFileP2::returnFCP | ISO constexpr uint8_t Df1Name[] = {0xA0,0x00,0x00,0x02,0x47,0x10,0x01}; constexpr uint8_t EFCOM_SFI = 0x1e; +constexpr uint8_t EFDG1_SFI = 0x01; +constexpr uint8_t EFDG2_SFI = 0x02; +constexpr uint8_t EFDG13_SFI = 0x0d; +constexpr uint8_t EFDG14_SFI = 0x0e; +constexpr uint8_t EFDG15_SFI = 0x0f; +constexpr uint8_t EFSOD_SFI = 0x1d; + + + + #endif //CCCC_CONSTS_H diff --git a/app/src/main/cpp/native-lib.cpp b/app/src/main/cpp/native-lib.cpp index 9f562ed..2d89d39 100644 --- a/app/src/main/cpp/native-lib.cpp +++ b/app/src/main/cpp/native-lib.cpp @@ -22,7 +22,14 @@ Java_com_bshield_cccc_MainActivity_initNFCScan( connector->selectDf1(); connector->initBAC(); + connector->readEFCOM(); + connector->readEFDG1(); + connector->readEFDG2(); + connector->readEFDG13(); + connector->readEFDG14(); + connector->readEFDG15(); + connector->readEFSOD(); return 1; }