Fixes for cross-platform build.
This commit is contained in:
4
.gitignore
vendored
4
.gitignore
vendored
@@ -1,5 +1,5 @@
|
||||
libuECC.o
|
||||
libcppb64.o
|
||||
libuECC.a
|
||||
libcppb64.a
|
||||
U2FDevice
|
||||
obj/*
|
||||
U2F_Priv_Keys.txt
|
||||
|
||||
@@ -20,17 +20,21 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#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
|
||||
#undef ARCHITECTURE
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
51
IO.cpp
51
IO.cpp
@@ -20,14 +20,17 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
#include "Streams.hpp"
|
||||
#include <iostream>
|
||||
#include <unistd.h>
|
||||
#include <stropts.h>
|
||||
//#include <sys/ioctl.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <time.h>
|
||||
#include <chrono>
|
||||
#include <ratio>
|
||||
#include "u2f.hpp"
|
||||
#include "Macro.hpp"
|
||||
#include "U2FDevice.hpp"
|
||||
|
||||
using namespace std;
|
||||
|
||||
@@ -38,7 +41,6 @@ vector<uint8_t> readNonBlock(const size_t count)
|
||||
{
|
||||
if (!bytesAvailable(count))
|
||||
{
|
||||
//clog << "No bytes available" << endl;
|
||||
return vector<uint8_t>{};
|
||||
}
|
||||
|
||||
@@ -46,8 +48,6 @@ vector<uint8_t> readNonBlock(const size_t count)
|
||||
auto buffStart = buffer.begin(), buffEnd = buffer.begin() + count;
|
||||
vector<uint8_t> 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<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()
|
||||
@@ -92,21 +112,38 @@ vector<uint8_t>& 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;
|
||||
}
|
||||
|
||||
|
||||
8
LED.cpp
8
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;
|
||||
|
||||
|
||||
16
Packet.cpp
16
Packet.cpp
@@ -80,6 +80,7 @@ shared_ptr<InitPacket> 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<table>\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</table>"
|
||||
"\t\t<br />");
|
||||
#endif
|
||||
|
||||
bytesRead = 0;
|
||||
return p;
|
||||
@@ -136,6 +138,7 @@ shared_ptr<ContPacket> 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<table>\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</table>\n"
|
||||
"\t\t<br />");
|
||||
#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</tbody>\n"
|
||||
"\t\t</table>"
|
||||
"\t\t<br />");
|
||||
#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</tbody>\n"
|
||||
"\t\t</table>\n"
|
||||
"\t\t<br />");
|
||||
#endif
|
||||
}
|
||||
|
||||
14
Streams.cpp
14
Streams.cpp
@@ -46,9 +46,10 @@ shared_ptr<int> getHostDescriptor()
|
||||
return descriptor;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_STREAMS
|
||||
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;
|
||||
fclose(f);
|
||||
} };
|
||||
@@ -61,7 +62,7 @@ shared_ptr<FILE> getComHostStream()
|
||||
|
||||
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;
|
||||
closeHTML(f);
|
||||
} };
|
||||
@@ -74,7 +75,7 @@ shared_ptr<FILE> getHostPacketStream()
|
||||
|
||||
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;
|
||||
closeHTML(f);
|
||||
} };
|
||||
@@ -87,7 +88,7 @@ shared_ptr<FILE> getHostAPDUStream()
|
||||
|
||||
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;
|
||||
fclose(f);
|
||||
} };
|
||||
@@ -100,7 +101,7 @@ shared_ptr<FILE> getComDevStream()
|
||||
|
||||
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;
|
||||
closeHTML(f);
|
||||
} };
|
||||
@@ -113,7 +114,7 @@ shared_ptr<FILE> getDevPacketStream()
|
||||
|
||||
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;
|
||||
closeHTML(f);
|
||||
} };
|
||||
@@ -124,7 +125,6 @@ shared_ptr<FILE> getDevAPDUStream()
|
||||
return stream;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_STREAMS
|
||||
FILE* initHTML(FILE *fPtr, const string &title)
|
||||
{
|
||||
fprintf(fPtr, "<html>\n"
|
||||
|
||||
@@ -19,6 +19,8 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
#pragma once
|
||||
#include <string>
|
||||
|
||||
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);
|
||||
|
||||
@@ -23,12 +23,14 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
#include <iomanip>
|
||||
#include "Streams.hpp"
|
||||
#include "u2f.hpp"
|
||||
#include "IO.hpp"
|
||||
|
||||
using namespace std;
|
||||
|
||||
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 uint32_t cid;
|
||||
static uint8_t cmd;
|
||||
@@ -36,7 +38,7 @@ shared_ptr<U2FMessage> U2FMessage::readNonBlock()
|
||||
|
||||
shared_ptr<Packet> p{};
|
||||
|
||||
if (currSeq == -1u)
|
||||
if (currSeq == startSeq)
|
||||
{
|
||||
cid = 0;
|
||||
cmd = 0;
|
||||
@@ -52,6 +54,11 @@ shared_ptr<U2FMessage> U2FMessage::readNonBlock()
|
||||
return {};
|
||||
|
||||
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
|
||||
|
||||
messageSize = ((static_cast<uint16_t>(initPack->bcnth) << 8u) + initPack->bcntl);
|
||||
@@ -61,7 +68,7 @@ shared_ptr<U2FMessage> 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<bool>(p = Packet::getPacket())) //While there is a packet
|
||||
@@ -70,38 +77,50 @@ shared_ptr<U2FMessage> 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<uint16_t>(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<U2FMessage>(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, "<table>\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, "</td>\n"
|
||||
"\t\t\t\t\t<td>0x%04X</td>\n"
|
||||
"\t\t\t\t</tr>\n"
|
||||
"\t\t\t</tbody>\n"
|
||||
"\t\t</table>\n"
|
||||
"\t\t<br />", err);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
#ifdef DEBUG_STREAMS
|
||||
auto hAS = getHostAPDUStream().get();
|
||||
|
||||
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</table>\n"
|
||||
"\t\t<br />", cmd.le);
|
||||
#endif
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
36
main.cpp
36
main.cpp
@@ -1,9 +1,41 @@
|
||||
#include "U2FDevice.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) {
|
||||
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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user