From 06d7e8e9a8a00e880406433a4dd366d2727dab92 Mon Sep 17 00:00:00 2001 From: Michael Kuc Date: Wed, 26 Jun 2019 13:02:45 +0100 Subject: [PATCH] Fixes for cross-platform build. --- .gitignore | 4 ++-- Architecture.hpp | 12 ++++++++---- Controller.cpp | 5 +++++ IO.cpp | 51 +++++++++++++++++++++++++++++++++++++++++------- LED.cpp | 8 ++++---- Packet.cpp | 16 +++++++++++++++ Streams.cpp | 14 ++++++------- U2FDevice.hpp | 2 ++ U2FMessage.cpp | 39 ++++++++++++++++++++++++++++-------- U2F_Msg_CMD.cpp | 2 ++ main.cpp | 36 ++++++++++++++++++++++++++++++++-- 11 files changed, 155 insertions(+), 34 deletions(-) diff --git a/.gitignore b/.gitignore index 70eac42..0347e2c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,5 @@ -libuECC.o -libcppb64.o +libuECC.a +libcppb64.a U2FDevice obj/* U2F_Priv_Keys.txt diff --git a/Architecture.hpp b/Architecture.hpp index 8f0536d..759bc26 100644 --- a/Architecture.hpp +++ b/Architecture.hpp @@ -20,17 +20,21 @@ along with this program. If not, see . #define ARCH_RASPBERRY_PI 1 #define ARCH_ANDROID 2 -#define ARCHITECTURE ARCH_RASPBERRY_PI +#define ARCHITECTURE ARCH_ANDROID #if ARCHITECTURE == ARCH_RASPBERRY_PI #define STORAGE_PREFIX "/usr/share/" #define HID_DEV "/dev/hidg0" - #define DEBUG_STREAMS + #define DEBUG_STREAMS "/tmp/" +// #define DEBUG_MSGS + #define LEDS #elif ARCHITECTURE == ARCH_ANDROID - #define STORAGE_PREFIX "/sdcard/U2F" + #define STORAGE_PREFIX "/sdcard/U2F/" #define HID_DEV "/dev/hidg2" + #define DEBUG_STREAMS "/data/local/tmp/" +// #define DEBUG_MSGS #endif #undef ARCH_ANDROID #undef ARCH_RASPBERRY_PI -#undef ARCHITECTURE \ No newline at end of file +#undef ARCHITECTURE diff --git a/Controller.cpp b/Controller.cpp index 6554d56..97cf7dd 100644 --- a/Controller.cpp +++ b/Controller.cpp @@ -64,6 +64,11 @@ void Controller::handleTransaction() } } +#ifdef DEBUG_MSGS + clog << "Message:" << endl; + clog << "cid: " << msg->cid << ", cmd: " << static_cast(msg->cmd) << endl; +#endif + channels.at(opChannel).handle(msg); } diff --git a/IO.cpp b/IO.cpp index 081e4a3..6f4f0b8 100644 --- a/IO.cpp +++ b/IO.cpp @@ -20,14 +20,17 @@ along with this program. If not, see . #include "Streams.hpp" #include #include -#include //#include #include #include #include #include +#include +#include +#include #include "u2f.hpp" #include "Macro.hpp" +#include "U2FDevice.hpp" using namespace std; @@ -38,7 +41,6 @@ vector readNonBlock(const size_t count) { if (!bytesAvailable(count)) { - //clog << "No bytes available" << endl; return vector{}; } @@ -46,8 +48,6 @@ vector readNonBlock(const size_t count) auto buffStart = buffer.begin(), buffEnd = buffer.begin() + count; vector bytes{ buffStart, buffEnd }; buffer.erase(buffStart, buffEnd); - - fwrite(bytes.data(), 1, bytes.size(), getComHostStream().get()); errno = 0; @@ -74,7 +74,27 @@ void write(const uint8_t* bytes, const size_t count) bool bytesAvailable(const size_t count) { - return getBuffer().size() >= count; + auto startTime = std::chrono::high_resolution_clock::now(); + const timespec iterDelay{ 0, 1000 }; + chrono::duration delay{ 0 }; + + while (delay.count() < U2FHID_TRANS_TIMEOUT && contProc) + { + delay = chrono::high_resolution_clock::now() - startTime; + if (getBuffer().size() >= count) { +#ifdef DEBUG_MSGS + clog << "Requested " << count << " bytes" << endl; +#endif + return true; + } + nanosleep(&iterDelay, nullptr); + } + +#ifdef DEBUG_MSGS + cerr << "Failed to obtain " << count << " bytes, having " << getBuffer().size() << endl; +#endif + + return false; } vector& bufferVar() @@ -92,21 +112,38 @@ vector& getBuffer() while (true) { auto readByteCount = read(hostDescriptor, bytes.data(), HID_RPT_SIZE); - + + if (readByteCount > 0 && readByteCount != HID_RPT_SIZE) + { + //Failed to copy an entire packet in, so log this packet +#ifdef DEBUG_MSGS + cerr << "Only retrieved " << readByteCount << " bytes from expected full packet." << endl; +#endif + } + if (readByteCount > 0) { copy(bytes.begin(), bytes.begin() + readByteCount, back_inserter(buff)); + +#ifdef DEBUG_STREAMS + fwrite(bytes.data(), 1, readByteCount, getComHostStream().get()); +#endif + } else if (errno != EAGAIN && errno != EWOULDBLOCK) //Expect read would block { ERR(); +#if DEBUG_MSGS + cerr << "Unknown stream error: " << errno << endl; +#endif + break; } else { + errno = 0; break; //Escape loop if blocking would occur } } return buff; } - diff --git a/LED.cpp b/LED.cpp index 3a82a56..68045e9 100644 --- a/LED.cpp +++ b/LED.cpp @@ -35,9 +35,9 @@ bool getLEDState() return ledState(); } -void disableACTTrigger(bool nowDisabled) +void disableACTTrigger([[maybe_unused]] bool nowDisabled) { -#if ARCHITECTURE == RASPBERRY_PI +#ifdef LEDS ofstream trigFile{ "/sys/class/leds/led0/trigger", ofstream::out | ofstream::trunc }; if (!trigFile) @@ -48,9 +48,9 @@ void disableACTTrigger(bool nowDisabled) #endif } -void enableACTLED(bool nowOn) +void enableACTLED([[maybe_unused]] bool nowOn) { -#if ARCHITECTURE == RASPBERRY_PI +#ifdef LEDS if (nowOn == getLEDState()) return; diff --git a/Packet.cpp b/Packet.cpp index b030352..1f0e983 100644 --- a/Packet.cpp +++ b/Packet.cpp @@ -80,6 +80,7 @@ shared_ptr InitPacket::getPacket(const uint32_t rCID, const uint8_t p->bcntl = bcntl; p->data = dataBytes; +#ifdef DEBUG_STREAMS auto hPStream = getHostPacketStream().get(); fprintf(hPStream, "\t\t\n" "\t\t\t\n" @@ -107,6 +108,7 @@ shared_ptr InitPacket::getPacket(const uint32_t rCID, const uint8_t "\t\t\t\n" "\t\t
" "\t\t
"); +#endif bytesRead = 0; return p; @@ -136,6 +138,7 @@ shared_ptr ContPacket::getPacket(const uint32_t rCID, const uint8_t p->seq = rSeq; p->data = dataBytes; +#ifdef DEBUG_STREAMS auto hPStream = getHostPacketStream().get(); fprintf(hPStream, "\t\t\n" "\t\t\t\n" @@ -159,6 +162,7 @@ shared_ptr ContPacket::getPacket(const uint32_t rCID, const uint8_t "\t\t\t\n" "\t\t
\n" "\t\t
"); +#endif readBytes = 0; return p; @@ -230,13 +234,18 @@ void Packet::writePacket() void InitPacket::writePacket() { Packet::writePacket(); + +#ifdef DEBUG_STREAMS auto devStream = getComDevStream().get(); +#endif memcpy(this->buf + 4, &cmd, 1); memcpy(this->buf + 5, &bcnth, 1); memcpy(this->buf + 6, &bcntl, 1); memcpy(this->buf + 7, data.data(), data.size()); write(this->buf, sizeof(this->buf)); + +#ifdef DEBUG_STREAMS fwrite(this->buf, 1, sizeof(this->buf), devStream); auto dPStream = getDevPacketStream().get(); @@ -266,16 +275,22 @@ void InitPacket::writePacket() "\t\t\t\n" "\t\t" "\t\t
"); +#endif } void ContPacket::writePacket() { Packet::writePacket(); + +#ifdef DEBUG_STREAMS auto devStream = getComDevStream().get(); +#endif memcpy(this->buf + 4, &seq, 1); memcpy(this->buf + 5, data.data(), data.size()); write(this->buf, HID_RPT_SIZE); + +#ifdef DEBUG_STREAMS fwrite(this->buf, HID_RPT_SIZE, 1, devStream); auto dPStream = getDevPacketStream().get(); @@ -302,4 +317,5 @@ void ContPacket::writePacket() "\t\t\t\n" "\t\t\n" "\t\t
"); +#endif } diff --git a/Streams.cpp b/Streams.cpp index 32c8c7f..4f51ec3 100644 --- a/Streams.cpp +++ b/Streams.cpp @@ -46,9 +46,10 @@ shared_ptr getHostDescriptor() return descriptor; } +#ifdef DEBUG_STREAMS shared_ptr getComHostStream() { - static shared_ptr stream{ fopen("/tmp/comhost.txt", "wb"), [](FILE *f){ + static shared_ptr stream{ fopen(DEBUG_STREAMS "comhost.txt", "wb"), [](FILE *f){ clog << "Closing comhost stream" << endl; fclose(f); } }; @@ -61,7 +62,7 @@ shared_ptr getComHostStream() shared_ptr getHostPacketStream() { - static shared_ptr stream{ initHTML(fopen("/tmp/hostpackets.html", "wb"), "Host Packets"), [](FILE *f){ + static shared_ptr stream{ initHTML(fopen(DEBUG_STREAMS "hostpackets.html", "wb"), "Host Packets"), [](FILE *f){ clog << "Closing hostPackets stream" << endl; closeHTML(f); } }; @@ -74,7 +75,7 @@ shared_ptr getHostPacketStream() shared_ptr getHostAPDUStream() { - static shared_ptr stream{ initHTML(fopen("/tmp/hostAPDU.html", "wb"), "Host APDU"), [](FILE *f){ + static shared_ptr stream{ initHTML(fopen(DEBUG_STREAMS "hostAPDU.html", "wb"), "Host APDU"), [](FILE *f){ clog << "Closing host APDU stream" << endl; closeHTML(f); } }; @@ -87,7 +88,7 @@ shared_ptr getHostAPDUStream() shared_ptr getComDevStream() { - static shared_ptr stream{ fopen("/tmp/comdev.txt", "wb"), [](FILE *f){ + static shared_ptr stream{ fopen(DEBUG_STREAMS "comdev.txt", "wb"), [](FILE *f){ clog << "Closing comdev stream" << endl; fclose(f); } }; @@ -100,7 +101,7 @@ shared_ptr getComDevStream() shared_ptr getDevPacketStream() { - static shared_ptr stream{ initHTML(fopen("/tmp/devpackets.html", "wb"), "Dev Packets"), [](FILE *f){ + static shared_ptr stream{ initHTML(fopen(DEBUG_STREAMS "devpackets.html", "wb"), "Dev Packets"), [](FILE *f){ clog << "Closing devPackets stream" << endl; closeHTML(f); } }; @@ -113,7 +114,7 @@ shared_ptr getDevPacketStream() shared_ptr getDevAPDUStream() { - static shared_ptr stream{ initHTML(fopen("/tmp/devAPDU.html", "wb"), "Dev APDU"), [](FILE *f){ + static shared_ptr stream{ initHTML(fopen(DEBUG_STREAMS "devAPDU.html", "wb"), "Dev APDU"), [](FILE *f){ clog << "Closing dev APDU stream" << endl; closeHTML(f); } }; @@ -124,7 +125,6 @@ shared_ptr getDevAPDUStream() return stream; } -#ifdef DEBUG_STREAMS FILE* initHTML(FILE *fPtr, const string &title) { fprintf(fPtr, "\n" diff --git a/U2FDevice.hpp b/U2FDevice.hpp index fcdb464..5ab1dba 100644 --- a/U2FDevice.hpp +++ b/U2FDevice.hpp @@ -19,6 +19,8 @@ along with this program. If not, see . #pragma once #include +extern volatile bool contProc; + bool initialiseLights(const std::string& prog); bool deinitialiseLights(const std::string& prog); int handleTransactions(const std::string& prog, const std::string& privKeyDir); diff --git a/U2FMessage.cpp b/U2FMessage.cpp index b429d9c..dd5b508 100644 --- a/U2FMessage.cpp +++ b/U2FMessage.cpp @@ -23,12 +23,14 @@ along with this program. If not, see . #include #include "Streams.hpp" #include "u2f.hpp" +#include "IO.hpp" using namespace std; shared_ptr U2FMessage::readNonBlock() { - static size_t currSeq = -1; + const static size_t startSeq = (size_t)-1ull; + static size_t currSeq = startSeq; static uint16_t messageSize; static uint32_t cid; static uint8_t cmd; @@ -36,7 +38,7 @@ shared_ptr U2FMessage::readNonBlock() shared_ptr p{}; - if (currSeq == -1u) + if (currSeq == startSeq) { cid = 0; cmd = 0; @@ -52,6 +54,11 @@ shared_ptr U2FMessage::readNonBlock() return {}; initPack = dynamic_pointer_cast(p); + +#ifdef DEBUG_MSGS + if (!initPack) + cerr << "Spurious cont. packet" << endl; +#endif } while (!initPack); //Spurious cont. packet - spec states ignore messageSize = ((static_cast(initPack->bcnth) << 8u) + initPack->bcntl); @@ -61,7 +68,7 @@ shared_ptr U2FMessage::readNonBlock() cmd = initPack->cmd; copy(initPack->data.begin(), initPack->data.begin() + copyByteCount, back_inserter(dataBytes)); - currSeq++; + currSeq = 0; } while (messageSize > dataBytes.size() && static_cast(p = Packet::getPacket())) //While there is a packet @@ -70,38 +77,50 @@ shared_ptr U2FMessage::readNonBlock() if (!contPack) //Spurious init. packet { - currSeq = -1; //Reset +#ifdef DEBUG_MSGS + cerr << "Spurious init. packet" << endl; +#endif + currSeq = startSeq; //Reset return {}; } if (contPack->cid != cid) //Cont. packet of different CID { +#ifdef DEBUG_MSGS cerr << "Invalid CID: was handling channel 0x" << hex << cid << " and received packet from channel 0x" << contPack->cid << dec << endl; +#endif U2FMessage::error(contPack->cid, ERR_CHANNEL_BUSY); - currSeq = -1; + currSeq = startSeq; return {}; } if (contPack->seq != currSeq) { +#ifdef DEBUG_MSGS cerr << "Invalid packet seq. value" << endl; +#endif U2FMessage::error(cid, ERR_INVALID_SEQ); - currSeq = -1; + currSeq = startSeq; return {}; } const uint16_t remainingBytes = messageSize - dataBytes.size(); const uint16_t copyBytes = min(static_cast(contPack->data.size()), remainingBytes); + dataBytes.insert(dataBytes.end(), contPack->data.begin(), contPack->data.begin() + copyBytes); currSeq++; } - if (messageSize != dataBytes.size()) + if (messageSize != dataBytes.size()) { +#ifdef DEBUG_MSGS + cerr << "Invalid message size: " << messageSize << " when received " << dataBytes.size() << endl; +#endif return {}; + } auto message = make_shared(cid, cmd); message->data.assign(dataBytes.begin(), dataBytes.end()); - currSeq = -1u; + currSeq = startSeq; return message; } @@ -146,6 +165,7 @@ void U2FMessage::write() if (cmd == U2FHID_MSG) { +#ifdef DEBUG_STREAMS auto dAS = getDevAPDUStream().get(); fprintf(dAS, "\n" @@ -161,16 +181,19 @@ void U2FMessage::write() for (size_t i = 0; i < data.size() - 2; i++) fprintf(dAS, "%3u ", data[i]); +#endif uint16_t err = data[data.size() - 2] << 8; err |= data.back(); +#ifdef DEBUG_STREAMS fprintf(dAS, "\n" "\t\t\t\t\t\n" "\t\t\t\t\n" "\t\t\t\n" "\t\t
0x%04X
\n" "\t\t
", err); +#endif } } diff --git a/U2F_Msg_CMD.cpp b/U2F_Msg_CMD.cpp index 3c3907d..b78d0b2 100644 --- a/U2F_Msg_CMD.cpp +++ b/U2F_Msg_CMD.cpp @@ -138,6 +138,7 @@ shared_ptr U2F_Msg_CMD::generate(const shared_ptr uMsg) const auto dBytes = vector(startPtr, endPtr); +#ifdef DEBUG_STREAMS auto hAS = getHostAPDUStream().get(); fprintf(hAS, "\n" @@ -170,6 +171,7 @@ shared_ptr U2F_Msg_CMD::generate(const shared_ptr uMsg) "\t\t\t\n" "\t\t
\n" "\t\t
", cmd.le); +#endif try { diff --git a/main.cpp b/main.cpp index a3745af..4a8ec35 100644 --- a/main.cpp +++ b/main.cpp @@ -1,9 +1,41 @@ #include "U2FDevice.hpp" #include "Architecture.hpp" +#include +#include + +#ifdef DEBUG_MSGS +//Courtesy StackOverflow answer https://stackoverflow.com/a/3356421 +void terminateHandler() +{ + void *trace_elems[20]; + int trace_elem_count(backtrace(trace_elems, 20)); + char **stack_syms(backtrace_symbols(trace_elems, trace_elem_count)); + for (int i = 0; i < trace_elem_count; ++i) + { + std::cout << stack_syms[i] << "\n"; + } + free(stack_syms); + + exit(1); +} +#endif int main(int argc, char **argv) { - initialiseLights(argv[0]); +#ifdef DEBUG_MSGS + std::set_terminate(terminate_handler); +#endif int retCode = handleTransactions(argv[0], argc == 2 ? argv[1] : STORAGE_PREFIX); - deinitialiseLights(argv[0]); + + try + { + initialiseLights(argv[0]); + deinitialiseLights(argv[0]); + } + catch (std::exception &e) + { + std::cerr << "Exception in code: " << e.what() << std::endl; + throw; + } + return retCode; }