Fixes for cross-platform build.

This commit is contained in:
2019-06-26 13:02:45 +01:00
parent 605fa0b691
commit 06d7e8e9a8
11 changed files with 155 additions and 34 deletions

4
.gitignore vendored
View File

@@ -1,5 +1,5 @@
libuECC.o libuECC.a
libcppb64.o libcppb64.a
U2FDevice U2FDevice
obj/* obj/*
U2F_Priv_Keys.txt U2F_Priv_Keys.txt

View File

@@ -20,15 +20,19 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
#define ARCH_RASPBERRY_PI 1 #define ARCH_RASPBERRY_PI 1
#define ARCH_ANDROID 2 #define ARCH_ANDROID 2
#define ARCHITECTURE ARCH_RASPBERRY_PI #define ARCHITECTURE ARCH_ANDROID
#if ARCHITECTURE == ARCH_RASPBERRY_PI #if ARCHITECTURE == ARCH_RASPBERRY_PI
#define STORAGE_PREFIX "/usr/share/" #define STORAGE_PREFIX "/usr/share/"
#define HID_DEV "/dev/hidg0" #define HID_DEV "/dev/hidg0"
#define DEBUG_STREAMS #define DEBUG_STREAMS "/tmp/"
// #define DEBUG_MSGS
#define LEDS
#elif ARCHITECTURE == ARCH_ANDROID #elif ARCHITECTURE == ARCH_ANDROID
#define STORAGE_PREFIX "/sdcard/U2F" #define STORAGE_PREFIX "/sdcard/U2F/"
#define HID_DEV "/dev/hidg2" #define HID_DEV "/dev/hidg2"
#define DEBUG_STREAMS "/data/local/tmp/"
// #define DEBUG_MSGS
#endif #endif
#undef ARCH_ANDROID #undef ARCH_ANDROID

View File

@@ -64,6 +64,11 @@ void Controller::handleTransaction()
} }
} }
#ifdef DEBUG_MSGS
clog << "Message:" << endl;
clog << "cid: " << msg->cid << ", cmd: " << static_cast<unsigned int>(msg->cmd) << endl;
#endif
channels.at(opChannel).handle(msg); channels.at(opChannel).handle(msg);
} }

49
IO.cpp
View File

@@ -20,14 +20,17 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
#include "Streams.hpp" #include "Streams.hpp"
#include <iostream> #include <iostream>
#include <unistd.h> #include <unistd.h>
#include <stropts.h>
//#include <sys/ioctl.h> //#include <sys/ioctl.h>
#include <unistd.h> #include <unistd.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <fcntl.h> #include <fcntl.h>
#include <time.h>
#include <chrono>
#include <ratio>
#include "u2f.hpp" #include "u2f.hpp"
#include "Macro.hpp" #include "Macro.hpp"
#include "U2FDevice.hpp"
using namespace std; using namespace std;
@@ -38,7 +41,6 @@ vector<uint8_t> readNonBlock(const size_t count)
{ {
if (!bytesAvailable(count)) if (!bytesAvailable(count))
{ {
//clog << "No bytes available" << endl;
return vector<uint8_t>{}; return vector<uint8_t>{};
} }
@@ -47,8 +49,6 @@ vector<uint8_t> readNonBlock(const size_t count)
vector<uint8_t> bytes{ buffStart, buffEnd }; vector<uint8_t> bytes{ buffStart, buffEnd };
buffer.erase(buffStart, buffEnd); buffer.erase(buffStart, buffEnd);
fwrite(bytes.data(), 1, bytes.size(), getComHostStream().get());
errno = 0; errno = 0;
return bytes; return bytes;
@@ -74,7 +74,27 @@ void write(const uint8_t* bytes, const size_t count)
bool bytesAvailable(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<double, milli> 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<uint8_t>& bufferVar() vector<uint8_t>& bufferVar()
@@ -93,20 +113,37 @@ vector<uint8_t>& getBuffer()
{ {
auto readByteCount = read(hostDescriptor, bytes.data(), HID_RPT_SIZE); 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) if (readByteCount > 0)
{ {
copy(bytes.begin(), bytes.begin() + readByteCount, back_inserter(buff)); 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 else if (errno != EAGAIN && errno != EWOULDBLOCK) //Expect read would block
{ {
ERR(); ERR();
#if DEBUG_MSGS
cerr << "Unknown stream error: " << errno << endl;
#endif
break;
} }
else else
{ {
errno = 0;
break; //Escape loop if blocking would occur break; //Escape loop if blocking would occur
} }
} }
return buff; return buff;
} }

View File

@@ -35,9 +35,9 @@ bool getLEDState()
return ledState(); 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 }; ofstream trigFile{ "/sys/class/leds/led0/trigger", ofstream::out | ofstream::trunc };
if (!trigFile) if (!trigFile)
@@ -48,9 +48,9 @@ void disableACTTrigger(bool nowDisabled)
#endif #endif
} }
void enableACTLED(bool nowOn) void enableACTLED([[maybe_unused]] bool nowOn)
{ {
#if ARCHITECTURE == RASPBERRY_PI #ifdef LEDS
if (nowOn == getLEDState()) if (nowOn == getLEDState())
return; return;

View File

@@ -80,6 +80,7 @@ shared_ptr<InitPacket> InitPacket::getPacket(const uint32_t rCID, const uint8_t
p->bcntl = bcntl; p->bcntl = bcntl;
p->data = dataBytes; p->data = dataBytes;
#ifdef DEBUG_STREAMS
auto hPStream = getHostPacketStream().get(); auto hPStream = getHostPacketStream().get();
fprintf(hPStream, "\t\t<table>\n" fprintf(hPStream, "\t\t<table>\n"
"\t\t\t<thead>\n" "\t\t\t<thead>\n"
@@ -107,6 +108,7 @@ shared_ptr<InitPacket> InitPacket::getPacket(const uint32_t rCID, const uint8_t
"\t\t\t</tbody>\n" "\t\t\t</tbody>\n"
"\t\t</table>" "\t\t</table>"
"\t\t<br />"); "\t\t<br />");
#endif
bytesRead = 0; bytesRead = 0;
return p; return p;
@@ -136,6 +138,7 @@ shared_ptr<ContPacket> ContPacket::getPacket(const uint32_t rCID, const uint8_t
p->seq = rSeq; p->seq = rSeq;
p->data = dataBytes; p->data = dataBytes;
#ifdef DEBUG_STREAMS
auto hPStream = getHostPacketStream().get(); auto hPStream = getHostPacketStream().get();
fprintf(hPStream, "\t\t<table>\n" fprintf(hPStream, "\t\t<table>\n"
"\t\t\t<thead>\n" "\t\t\t<thead>\n"
@@ -159,6 +162,7 @@ shared_ptr<ContPacket> ContPacket::getPacket(const uint32_t rCID, const uint8_t
"\t\t\t</tbody>\n" "\t\t\t</tbody>\n"
"\t\t</table>\n" "\t\t</table>\n"
"\t\t<br />"); "\t\t<br />");
#endif
readBytes = 0; readBytes = 0;
return p; return p;
@@ -230,13 +234,18 @@ void Packet::writePacket()
void InitPacket::writePacket() void InitPacket::writePacket()
{ {
Packet::writePacket(); Packet::writePacket();
#ifdef DEBUG_STREAMS
auto devStream = getComDevStream().get(); auto devStream = getComDevStream().get();
#endif
memcpy(this->buf + 4, &cmd, 1); memcpy(this->buf + 4, &cmd, 1);
memcpy(this->buf + 5, &bcnth, 1); memcpy(this->buf + 5, &bcnth, 1);
memcpy(this->buf + 6, &bcntl, 1); memcpy(this->buf + 6, &bcntl, 1);
memcpy(this->buf + 7, data.data(), data.size()); memcpy(this->buf + 7, data.data(), data.size());
write(this->buf, sizeof(this->buf)); write(this->buf, sizeof(this->buf));
#ifdef DEBUG_STREAMS
fwrite(this->buf, 1, sizeof(this->buf), devStream); fwrite(this->buf, 1, sizeof(this->buf), devStream);
auto dPStream = getDevPacketStream().get(); auto dPStream = getDevPacketStream().get();
@@ -266,16 +275,22 @@ void InitPacket::writePacket()
"\t\t\t</tbody>\n" "\t\t\t</tbody>\n"
"\t\t</table>" "\t\t</table>"
"\t\t<br />"); "\t\t<br />");
#endif
} }
void ContPacket::writePacket() void ContPacket::writePacket()
{ {
Packet::writePacket(); Packet::writePacket();
#ifdef DEBUG_STREAMS
auto devStream = getComDevStream().get(); auto devStream = getComDevStream().get();
#endif
memcpy(this->buf + 4, &seq, 1); memcpy(this->buf + 4, &seq, 1);
memcpy(this->buf + 5, data.data(), data.size()); memcpy(this->buf + 5, data.data(), data.size());
write(this->buf, HID_RPT_SIZE); write(this->buf, HID_RPT_SIZE);
#ifdef DEBUG_STREAMS
fwrite(this->buf, HID_RPT_SIZE, 1, devStream); fwrite(this->buf, HID_RPT_SIZE, 1, devStream);
auto dPStream = getDevPacketStream().get(); auto dPStream = getDevPacketStream().get();
@@ -302,4 +317,5 @@ void ContPacket::writePacket()
"\t\t\t</tbody>\n" "\t\t\t</tbody>\n"
"\t\t</table>\n" "\t\t</table>\n"
"\t\t<br />"); "\t\t<br />");
#endif
} }

View File

@@ -46,9 +46,10 @@ shared_ptr<int> getHostDescriptor()
return descriptor; return descriptor;
} }
#ifdef DEBUG_STREAMS
shared_ptr<FILE> getComHostStream() shared_ptr<FILE> getComHostStream()
{ {
static shared_ptr<FILE> stream{ fopen("/tmp/comhost.txt", "wb"), [](FILE *f){ static shared_ptr<FILE> stream{ fopen(DEBUG_STREAMS "comhost.txt", "wb"), [](FILE *f){
clog << "Closing comhost stream" << endl; clog << "Closing comhost stream" << endl;
fclose(f); fclose(f);
} }; } };
@@ -61,7 +62,7 @@ shared_ptr<FILE> getComHostStream()
shared_ptr<FILE> getHostPacketStream() shared_ptr<FILE> getHostPacketStream()
{ {
static shared_ptr<FILE> stream{ initHTML(fopen("/tmp/hostpackets.html", "wb"), "Host Packets"), [](FILE *f){ static shared_ptr<FILE> stream{ initHTML(fopen(DEBUG_STREAMS "hostpackets.html", "wb"), "Host Packets"), [](FILE *f){
clog << "Closing hostPackets stream" << endl; clog << "Closing hostPackets stream" << endl;
closeHTML(f); closeHTML(f);
} }; } };
@@ -74,7 +75,7 @@ shared_ptr<FILE> getHostPacketStream()
shared_ptr<FILE> getHostAPDUStream() shared_ptr<FILE> getHostAPDUStream()
{ {
static shared_ptr<FILE> stream{ initHTML(fopen("/tmp/hostAPDU.html", "wb"), "Host APDU"), [](FILE *f){ static shared_ptr<FILE> stream{ initHTML(fopen(DEBUG_STREAMS "hostAPDU.html", "wb"), "Host APDU"), [](FILE *f){
clog << "Closing host APDU stream" << endl; clog << "Closing host APDU stream" << endl;
closeHTML(f); closeHTML(f);
} }; } };
@@ -87,7 +88,7 @@ shared_ptr<FILE> getHostAPDUStream()
shared_ptr<FILE> getComDevStream() shared_ptr<FILE> getComDevStream()
{ {
static shared_ptr<FILE> stream{ fopen("/tmp/comdev.txt", "wb"), [](FILE *f){ static shared_ptr<FILE> stream{ fopen(DEBUG_STREAMS "comdev.txt", "wb"), [](FILE *f){
clog << "Closing comdev stream" << endl; clog << "Closing comdev stream" << endl;
fclose(f); fclose(f);
} }; } };
@@ -100,7 +101,7 @@ shared_ptr<FILE> getComDevStream()
shared_ptr<FILE> getDevPacketStream() shared_ptr<FILE> getDevPacketStream()
{ {
static shared_ptr<FILE> stream{ initHTML(fopen("/tmp/devpackets.html", "wb"), "Dev Packets"), [](FILE *f){ static shared_ptr<FILE> stream{ initHTML(fopen(DEBUG_STREAMS "devpackets.html", "wb"), "Dev Packets"), [](FILE *f){
clog << "Closing devPackets stream" << endl; clog << "Closing devPackets stream" << endl;
closeHTML(f); closeHTML(f);
} }; } };
@@ -113,7 +114,7 @@ shared_ptr<FILE> getDevPacketStream()
shared_ptr<FILE> getDevAPDUStream() shared_ptr<FILE> getDevAPDUStream()
{ {
static shared_ptr<FILE> stream{ initHTML(fopen("/tmp/devAPDU.html", "wb"), "Dev APDU"), [](FILE *f){ static shared_ptr<FILE> stream{ initHTML(fopen(DEBUG_STREAMS "devAPDU.html", "wb"), "Dev APDU"), [](FILE *f){
clog << "Closing dev APDU stream" << endl; clog << "Closing dev APDU stream" << endl;
closeHTML(f); closeHTML(f);
} }; } };
@@ -124,7 +125,6 @@ shared_ptr<FILE> getDevAPDUStream()
return stream; return stream;
} }
#ifdef DEBUG_STREAMS
FILE* initHTML(FILE *fPtr, const string &title) FILE* initHTML(FILE *fPtr, const string &title)
{ {
fprintf(fPtr, "<html>\n" fprintf(fPtr, "<html>\n"

View File

@@ -19,6 +19,8 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
#pragma once #pragma once
#include <string> #include <string>
extern volatile bool contProc;
bool initialiseLights(const std::string& prog); bool initialiseLights(const std::string& prog);
bool deinitialiseLights(const std::string& prog); bool deinitialiseLights(const std::string& prog);
int handleTransactions(const std::string& prog, const std::string& privKeyDir); int handleTransactions(const std::string& prog, const std::string& privKeyDir);

View File

@@ -23,12 +23,14 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
#include <iomanip> #include <iomanip>
#include "Streams.hpp" #include "Streams.hpp"
#include "u2f.hpp" #include "u2f.hpp"
#include "IO.hpp"
using namespace std; using namespace std;
shared_ptr<U2FMessage> U2FMessage::readNonBlock() shared_ptr<U2FMessage> 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 uint16_t messageSize;
static uint32_t cid; static uint32_t cid;
static uint8_t cmd; static uint8_t cmd;
@@ -36,7 +38,7 @@ shared_ptr<U2FMessage> U2FMessage::readNonBlock()
shared_ptr<Packet> p{}; shared_ptr<Packet> p{};
if (currSeq == -1u) if (currSeq == startSeq)
{ {
cid = 0; cid = 0;
cmd = 0; cmd = 0;
@@ -52,6 +54,11 @@ shared_ptr<U2FMessage> U2FMessage::readNonBlock()
return {}; return {};
initPack = dynamic_pointer_cast<InitPacket>(p); initPack = dynamic_pointer_cast<InitPacket>(p);
#ifdef DEBUG_MSGS
if (!initPack)
cerr << "Spurious cont. packet" << endl;
#endif
} while (!initPack); //Spurious cont. packet - spec states ignore } while (!initPack); //Spurious cont. packet - spec states ignore
messageSize = ((static_cast<uint16_t>(initPack->bcnth) << 8u) + initPack->bcntl); messageSize = ((static_cast<uint16_t>(initPack->bcnth) << 8u) + initPack->bcntl);
@@ -61,7 +68,7 @@ shared_ptr<U2FMessage> U2FMessage::readNonBlock()
cmd = initPack->cmd; cmd = initPack->cmd;
copy(initPack->data.begin(), initPack->data.begin() + copyByteCount, back_inserter(dataBytes)); copy(initPack->data.begin(), initPack->data.begin() + copyByteCount, back_inserter(dataBytes));
currSeq++; currSeq = 0;
} }
while (messageSize > dataBytes.size() && static_cast<bool>(p = Packet::getPacket())) //While there is a packet while (messageSize > dataBytes.size() && static_cast<bool>(p = Packet::getPacket())) //While there is a packet
@@ -70,38 +77,50 @@ shared_ptr<U2FMessage> U2FMessage::readNonBlock()
if (!contPack) //Spurious init. packet if (!contPack) //Spurious init. packet
{ {
currSeq = -1; //Reset #ifdef DEBUG_MSGS
cerr << "Spurious init. packet" << endl;
#endif
currSeq = startSeq; //Reset
return {}; return {};
} }
if (contPack->cid != cid) //Cont. packet of different CID 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; 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); U2FMessage::error(contPack->cid, ERR_CHANNEL_BUSY);
currSeq = -1; currSeq = startSeq;
return {}; return {};
} }
if (contPack->seq != currSeq) if (contPack->seq != currSeq)
{ {
#ifdef DEBUG_MSGS
cerr << "Invalid packet seq. value" << endl; cerr << "Invalid packet seq. value" << endl;
#endif
U2FMessage::error(cid, ERR_INVALID_SEQ); U2FMessage::error(cid, ERR_INVALID_SEQ);
currSeq = -1; currSeq = startSeq;
return {}; return {};
} }
const uint16_t remainingBytes = messageSize - dataBytes.size(); const uint16_t remainingBytes = messageSize - dataBytes.size();
const uint16_t copyBytes = min(static_cast<uint16_t>(contPack->data.size()), remainingBytes); const uint16_t copyBytes = min(static_cast<uint16_t>(contPack->data.size()), remainingBytes);
dataBytes.insert(dataBytes.end(), contPack->data.begin(), contPack->data.begin() + copyBytes); dataBytes.insert(dataBytes.end(), contPack->data.begin(), contPack->data.begin() + copyBytes);
currSeq++; currSeq++;
} }
if (messageSize != dataBytes.size()) if (messageSize != dataBytes.size()) {
#ifdef DEBUG_MSGS
cerr << "Invalid message size: " << messageSize << " when received " << dataBytes.size() << endl;
#endif
return {}; return {};
}
auto message = make_shared<U2FMessage>(cid, cmd); auto message = make_shared<U2FMessage>(cid, cmd);
message->data.assign(dataBytes.begin(), dataBytes.end()); message->data.assign(dataBytes.begin(), dataBytes.end());
currSeq = -1u; currSeq = startSeq;
return message; return message;
} }
@@ -146,6 +165,7 @@ void U2FMessage::write()
if (cmd == U2FHID_MSG) if (cmd == U2FHID_MSG)
{ {
#ifdef DEBUG_STREAMS
auto dAS = getDevAPDUStream().get(); auto dAS = getDevAPDUStream().get();
fprintf(dAS, "<table>\n" fprintf(dAS, "<table>\n"
@@ -161,16 +181,19 @@ void U2FMessage::write()
for (size_t i = 0; i < data.size() - 2; i++) for (size_t i = 0; i < data.size() - 2; i++)
fprintf(dAS, "%3u ", data[i]); fprintf(dAS, "%3u ", data[i]);
#endif
uint16_t err = data[data.size() - 2] << 8; uint16_t err = data[data.size() - 2] << 8;
err |= data.back(); err |= data.back();
#ifdef DEBUG_STREAMS
fprintf(dAS, "</td>\n" fprintf(dAS, "</td>\n"
"\t\t\t\t\t<td>0x%04X</td>\n" "\t\t\t\t\t<td>0x%04X</td>\n"
"\t\t\t\t</tr>\n" "\t\t\t\t</tr>\n"
"\t\t\t</tbody>\n" "\t\t\t</tbody>\n"
"\t\t</table>\n" "\t\t</table>\n"
"\t\t<br />", err); "\t\t<br />", err);
#endif
} }
} }

View File

@@ -138,6 +138,7 @@ shared_ptr<U2F_Msg_CMD> U2F_Msg_CMD::generate(const shared_ptr<U2FMessage> uMsg)
const auto dBytes = vector<uint8_t>(startPtr, endPtr); const auto dBytes = vector<uint8_t>(startPtr, endPtr);
#ifdef DEBUG_STREAMS
auto hAS = getHostAPDUStream().get(); auto hAS = getHostAPDUStream().get();
fprintf(hAS, "<table>\n" fprintf(hAS, "<table>\n"
@@ -170,6 +171,7 @@ shared_ptr<U2F_Msg_CMD> U2F_Msg_CMD::generate(const shared_ptr<U2FMessage> uMsg)
"\t\t\t</tbody>\n" "\t\t\t</tbody>\n"
"\t\t</table>\n" "\t\t</table>\n"
"\t\t<br />", cmd.le); "\t\t<br />", cmd.le);
#endif
try try
{ {

View File

@@ -1,9 +1,41 @@
#include "U2FDevice.hpp" #include "U2FDevice.hpp"
#include "Architecture.hpp" #include "Architecture.hpp"
#include <execinfo.h>
#include <iostream>
#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) { 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); int retCode = handleTransactions(argv[0], argc == 2 ? argv[1] : STORAGE_PREFIX);
try
{
initialiseLights(argv[0]);
deinitialiseLights(argv[0]); deinitialiseLights(argv[0]);
}
catch (std::exception &e)
{
std::cerr << "Exception in code: " << e.what() << std::endl;
throw;
}
return retCode; return retCode;
} }