This commit is contained in:
2019-08-23 13:32:41 +01:00
parent 55d1fd738f
commit f7dea03132
42 changed files with 850 additions and 985 deletions

View File

@@ -18,15 +18,9 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
#pragma once
enum APDU : uint8_t
{
U2F_REG = 0x01,
U2F_AUTH = 0x02,
U2F_VER = 0x03
};
enum APDU : uint8_t { U2F_REG = 0x01, U2F_AUTH = 0x02, U2F_VER = 0x03 };
enum APDU_STATUS : uint16_t
{
enum APDU_STATUS : uint16_t {
SW_NO_ERROR = 0x9000,
SW_WRONG_LENGTH = 0x6700,
SW_CONDITIONS_NOT_SATISFIED = 0x6985,

View File

@@ -31,7 +31,9 @@ template <typename InContainer, typename Elem, size_t count>
void b64decode(const InContainer& iContainer, std::array<Elem, count>& oArr);
template <typename InContainerIter, typename OutContainerIter>
void b64encode(const InContainerIter beginIter, const InContainerIter endIter, OutContainerIter oBeginIter);
void b64encode(const InContainerIter beginIter, const InContainerIter endIter,
OutContainerIter oBeginIter);
template <typename InContainerIter, typename OutContainerIter>
void b64decode(const InContainerIter beginIter, const InContainerIter endIter, OutContainerIter oBeginIter);
void b64decode(const InContainerIter beginIter, const InContainerIter endIter,
OutContainerIter oBeginIter);

View File

@@ -25,66 +25,50 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
// You can generate your own using the method detailed in the README.
uint8_t attestCert[] = {
0x30, 0x82, 0x02, 0x29, 0x30, 0x82, 0x01, 0xd0, 0xa0, 0x03, 0x02, 0x01,
0x02, 0x02, 0x09, 0x00, 0x8a, 0xe2, 0x21, 0x3f, 0x2f, 0x8b, 0x72, 0x52,
0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02,
0x30, 0x70, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
0x02, 0x55, 0x4b, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08,
0x0c, 0x0a, 0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65,
0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x18, 0x49,
0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, 0x67,
0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c, 0x74, 0x64, 0x31,
0x29, 0x30, 0x27, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x20, 0x55, 0x32,
0x46, 0x20, 0x4b, 0x65, 0x79, 0x20, 0x74, 0x50, 0x46, 0x53, 0x71, 0x54,
0x71, 0x6f, 0x5a, 0x6d, 0x62, 0x37, 0x38, 0x61, 0x6a, 0x6f, 0x2f, 0x75,
0x58, 0x50, 0x73, 0x51, 0x3d, 0x3d, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x38,
0x30, 0x36, 0x33, 0x30, 0x31, 0x39, 0x30, 0x37, 0x35, 0x31, 0x5a, 0x17,
0x0d, 0x32, 0x38, 0x30, 0x36, 0x32, 0x37, 0x31, 0x39, 0x30, 0x37, 0x35,
0x31, 0x5a, 0x30, 0x70, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04,
0x06, 0x13, 0x02, 0x55, 0x4b, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55,
0x04, 0x08, 0x0c, 0x0a, 0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61,
0x74, 0x65, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c,
0x18, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69,
0x64, 0x67, 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c, 0x74,
0x64, 0x31, 0x29, 0x30, 0x27, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x20,
0x55, 0x32, 0x46, 0x20, 0x4b, 0x65, 0x79, 0x20, 0x74, 0x50, 0x46, 0x53,
0x71, 0x54, 0x71, 0x6f, 0x5a, 0x6d, 0x62, 0x37, 0x38, 0x61, 0x6a, 0x6f,
0x2f, 0x75, 0x58, 0x50, 0x73, 0x51, 0x3d, 0x3d, 0x30, 0x59, 0x30, 0x13,
0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a,
0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0x32,
0x41, 0xc3, 0xb8, 0x96, 0x97, 0xd8, 0x90, 0x66, 0x41, 0x88, 0x96, 0xd4,
0x73, 0xb6, 0x37, 0xf7, 0x85, 0x29, 0xaf, 0x3b, 0x15, 0x0f, 0x83, 0x61,
0x67, 0xea, 0xc9, 0xb2, 0xdb, 0x82, 0xb3, 0x2c, 0x99, 0x60, 0x8a, 0x98,
0x7c, 0xd4, 0x04, 0xa0, 0x92, 0x22, 0x05, 0xaa, 0xf7, 0x7a, 0x91, 0x02,
0x03, 0xdd, 0x15, 0x88, 0x87, 0x6a, 0x26, 0xe9, 0xee, 0xcf, 0x99, 0xb1,
0x66, 0xc0, 0x01, 0xa3, 0x53, 0x30, 0x51, 0x30, 0x1d, 0x06, 0x03, 0x55,
0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xcf, 0x7f, 0xfa, 0x7d, 0xc4, 0x8d,
0xba, 0x60, 0x52, 0x4c, 0xb6, 0x16, 0x2e, 0x88, 0x62, 0xc7, 0x8c, 0xfc,
0xe0, 0x63, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30,
0x16, 0x80, 0x14, 0xcf, 0x7f, 0xfa, 0x7d, 0xc4, 0x8d, 0xba, 0x60, 0x52,
0x4c, 0xb6, 0x16, 0x2e, 0x88, 0x62, 0xc7, 0x8c, 0xfc, 0xe0, 0x63, 0x30,
0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30,
0x03, 0x01, 0x01, 0xff, 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce,
0x3d, 0x04, 0x03, 0x02, 0x03, 0x47, 0x00, 0x30, 0x44, 0x02, 0x20, 0x72,
0x25, 0x89, 0xc1, 0x32, 0x54, 0x66, 0xf8, 0x0e, 0x58, 0x77, 0xe3, 0xb5,
0x62, 0x47, 0x33, 0x18, 0x5a, 0xdc, 0x28, 0x6a, 0x4a, 0x56, 0xcb, 0x58,
0x63, 0xe3, 0xa1, 0x02, 0x6a, 0xf0, 0xd8, 0x02, 0x20, 0x65, 0x26, 0x84,
0x7c, 0xc3, 0x3b, 0x7d, 0x6a, 0x22, 0x0c, 0x22, 0x3d, 0xc8, 0x43, 0xb7,
0x84, 0x8b, 0x7b, 0x48, 0x23, 0xb0, 0x1e, 0x13, 0x35, 0x1d, 0x1a, 0x90,
0x44, 0x62, 0x6c, 0xab, 0x9b
0x30, 0x82, 0x02, 0x29, 0x30, 0x82, 0x01, 0xd0, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x09, 0x00,
0x8a, 0xe2, 0x21, 0x3f, 0x2f, 0x8b, 0x72, 0x52, 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce,
0x3d, 0x04, 0x03, 0x02, 0x30, 0x70, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
0x02, 0x55, 0x4b, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x0a, 0x53, 0x6f,
0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04,
0x0a, 0x0c, 0x18, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, 0x67,
0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c, 0x74, 0x64, 0x31, 0x29, 0x30, 0x27, 0x06,
0x03, 0x55, 0x04, 0x03, 0x0c, 0x20, 0x55, 0x32, 0x46, 0x20, 0x4b, 0x65, 0x79, 0x20, 0x74, 0x50,
0x46, 0x53, 0x71, 0x54, 0x71, 0x6f, 0x5a, 0x6d, 0x62, 0x37, 0x38, 0x61, 0x6a, 0x6f, 0x2f, 0x75,
0x58, 0x50, 0x73, 0x51, 0x3d, 0x3d, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x38, 0x30, 0x36, 0x33, 0x30,
0x31, 0x39, 0x30, 0x37, 0x35, 0x31, 0x5a, 0x17, 0x0d, 0x32, 0x38, 0x30, 0x36, 0x32, 0x37, 0x31,
0x39, 0x30, 0x37, 0x35, 0x31, 0x5a, 0x30, 0x70, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04,
0x06, 0x13, 0x02, 0x55, 0x4b, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x0a,
0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03,
0x55, 0x04, 0x0a, 0x0c, 0x18, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69,
0x64, 0x67, 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c, 0x74, 0x64, 0x31, 0x29, 0x30,
0x27, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x20, 0x55, 0x32, 0x46, 0x20, 0x4b, 0x65, 0x79, 0x20,
0x74, 0x50, 0x46, 0x53, 0x71, 0x54, 0x71, 0x6f, 0x5a, 0x6d, 0x62, 0x37, 0x38, 0x61, 0x6a, 0x6f,
0x2f, 0x75, 0x58, 0x50, 0x73, 0x51, 0x3d, 0x3d, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86,
0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03,
0x42, 0x00, 0x04, 0x32, 0x41, 0xc3, 0xb8, 0x96, 0x97, 0xd8, 0x90, 0x66, 0x41, 0x88, 0x96, 0xd4,
0x73, 0xb6, 0x37, 0xf7, 0x85, 0x29, 0xaf, 0x3b, 0x15, 0x0f, 0x83, 0x61, 0x67, 0xea, 0xc9, 0xb2,
0xdb, 0x82, 0xb3, 0x2c, 0x99, 0x60, 0x8a, 0x98, 0x7c, 0xd4, 0x04, 0xa0, 0x92, 0x22, 0x05, 0xaa,
0xf7, 0x7a, 0x91, 0x02, 0x03, 0xdd, 0x15, 0x88, 0x87, 0x6a, 0x26, 0xe9, 0xee, 0xcf, 0x99, 0xb1,
0x66, 0xc0, 0x01, 0xa3, 0x53, 0x30, 0x51, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16,
0x04, 0x14, 0xcf, 0x7f, 0xfa, 0x7d, 0xc4, 0x8d, 0xba, 0x60, 0x52, 0x4c, 0xb6, 0x16, 0x2e, 0x88,
0x62, 0xc7, 0x8c, 0xfc, 0xe0, 0x63, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30,
0x16, 0x80, 0x14, 0xcf, 0x7f, 0xfa, 0x7d, 0xc4, 0x8d, 0xba, 0x60, 0x52, 0x4c, 0xb6, 0x16, 0x2e,
0x88, 0x62, 0xc7, 0x8c, 0xfc, 0xe0, 0x63, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01,
0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce,
0x3d, 0x04, 0x03, 0x02, 0x03, 0x47, 0x00, 0x30, 0x44, 0x02, 0x20, 0x72, 0x25, 0x89, 0xc1, 0x32,
0x54, 0x66, 0xf8, 0x0e, 0x58, 0x77, 0xe3, 0xb5, 0x62, 0x47, 0x33, 0x18, 0x5a, 0xdc, 0x28, 0x6a,
0x4a, 0x56, 0xcb, 0x58, 0x63, 0xe3, 0xa1, 0x02, 0x6a, 0xf0, 0xd8, 0x02, 0x20, 0x65, 0x26, 0x84,
0x7c, 0xc3, 0x3b, 0x7d, 0x6a, 0x22, 0x0c, 0x22, 0x3d, 0xc8, 0x43, 0xb7, 0x84, 0x8b, 0x7b, 0x48,
0x23, 0xb0, 0x1e, 0x13, 0x35, 0x1d, 0x1a, 0x90, 0x44, 0x62, 0x6c, 0xab, 0x9b
};
uint8_t attestPrivKey[] = {
0x7e, 0xbd, 0x91, 0x05, 0x5a, 0x80, 0x9f, 0x36, 0xe5, 0x2f, 0xe0, 0xd0,
0xa9, 0x63, 0x0c, 0x86, 0x04, 0xb1, 0x04, 0xe3, 0xd1, 0xfb, 0xd0, 0x83,
0xc7, 0x2e, 0x2f, 0x34, 0xb6, 0xd6, 0xa4, 0xb2
};
uint8_t attestPrivKey[] = { 0x7e, 0xbd, 0x91, 0x05, 0x5a, 0x80, 0x9f, 0x36, 0xe5, 0x2f, 0xe0,
0xd0, 0xa9, 0x63, 0x0c, 0x86, 0x04, 0xb1, 0x04, 0xe3, 0xd1, 0xfb,
0xd0, 0x83, 0xc7, 0x2e, 0x2f, 0x34, 0xb6, 0xd6, 0xa4, 0xb2 };
uint8_t attestPubKey[] = {
0x04, 0x32, 0x41, 0xc3, 0xb8, 0x96, 0x97, 0xd8, 0x90, 0x66, 0x41, 0x88,
0x96, 0xd4, 0x73, 0xb6, 0x37, 0xf7, 0x85, 0x29, 0xaf, 0x3b, 0x15, 0x0f,
0x83, 0x61, 0x67, 0xea, 0xc9, 0xb2, 0xdb, 0x82, 0xb3, 0x2c, 0x99, 0x60,
0x8a, 0x98, 0x7c, 0xd4, 0x04, 0xa0, 0x92, 0x22, 0x05, 0xaa, 0xf7, 0x7a,
0x91, 0x02, 0x03, 0xdd, 0x15, 0x88, 0x87, 0x6a, 0x26, 0xe9, 0xee, 0xcf,
0x99, 0xb1, 0x66, 0xc0, 0x01
};
uint8_t attestPubKey[] = { 0x04, 0x32, 0x41, 0xc3, 0xb8, 0x96, 0x97, 0xd8, 0x90, 0x66, 0x41,
0x88, 0x96, 0xd4, 0x73, 0xb6, 0x37, 0xf7, 0x85, 0x29, 0xaf, 0x3b,
0x15, 0x0f, 0x83, 0x61, 0x67, 0xea, 0xc9, 0xb2, 0xdb, 0x82, 0xb3,
0x2c, 0x99, 0x60, 0x8a, 0x98, 0x7c, 0xd4, 0x04, 0xa0, 0x92, 0x22,
0x05, 0xaa, 0xf7, 0x7a, 0x91, 0x02, 0x03, 0xdd, 0x15, 0x88, 0x87,
0x6a, 0x26, 0xe9, 0xee, 0xcf, 0x99, 0xb1, 0x66, 0xc0, 0x01 };

View File

@@ -17,24 +17,23 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "Channel.hpp"
#include <stdexcept>
#include "u2f.hpp"
#include "U2F_CMD.hpp"
#include "u2f.hpp"
#include <iostream>
#include <stdexcept>
using namespace std;
Channel::Channel(const uint32_t channelID)
: cid{ channelID }, initState{ ChannelInitState::Unitialised }, lockedState{ ChannelLockedState::Unlocked }
{}
: cid{ channelID }, initState{ ChannelInitState::Unitialised }, lockedState{
ChannelLockedState::Unlocked
} {}
uint32_t Channel::getCID() const
{
uint32_t Channel::getCID() const {
return cid;
}
void Channel::handle(const shared_ptr<U2FMessage> uMsg)
{
void Channel::handle(const shared_ptr<U2FMessage> uMsg) {
if (uMsg->cmd == U2FHID_INIT)
this->initState = ChannelInitState::Initialised;
else if (uMsg->cid != this->cid)
@@ -51,12 +50,10 @@ void Channel::handle(const shared_ptr<U2FMessage> uMsg)
return cmd->respond(this->cid);
}
void Channel::init(const ChannelInitState newInitState)
{
void Channel::init(const ChannelInitState newInitState) {
this->initState = newInitState;
}
void Channel::lock(const ChannelLockedState newLockedState)
{
void Channel::lock(const ChannelLockedState newLockedState) {
this->lockedState = newLockedState;
}

View File

@@ -17,24 +17,15 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#pragma once
#include "U2FMessage.hpp"
#include <cstdint>
#include <memory>
#include "U2FMessage.hpp"
enum class ChannelInitState
{
Unitialised,
Initialised
};
enum class ChannelInitState { Unitialised, Initialised };
enum class ChannelLockedState
{
Locked,
Unlocked
};
enum class ChannelLockedState { Locked, Unlocked };
class Channel
{
class Channel {
protected:
uint32_t cid;
ChannelInitState initState;

View File

@@ -17,28 +17,25 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "Controller.hpp"
#include "u2f.hpp"
#include <iostream>
#include "IO.hpp"
#include "LED.hpp"
#include "u2f.hpp"
#include <iostream>
using namespace std;
Controller::Controller(const uint32_t startChannel)
: channels{}, currChannel{ startChannel }
{}
Controller::Controller(const uint32_t startChannel) : channels{}, currChannel{ startChannel } {}
void Controller::handleTransaction()
{
try
{
if (channels.size() != 0 && chrono::duration_cast<chrono::seconds>(chrono::system_clock::now() - lastMessage) < chrono::seconds(5))
void Controller::handleTransaction() {
try {
if (channels.size() != 0 &&
chrono::duration_cast<chrono::seconds>(chrono::system_clock::now() - lastMessage) <
chrono::seconds(5))
toggleACTLED();
else
enableACTLED(false);
} catch (runtime_error& ignored) {
}
catch (runtime_error& ignored)
{}
auto msg = U2FMessage::readNonBlock();
@@ -49,17 +46,13 @@ void Controller::handleTransaction()
auto opChannel = msg->cid;
if (msg->cmd == U2FHID_INIT)
{
if (msg->cmd == U2FHID_INIT) {
opChannel = nextChannel();
auto channel = Channel{ opChannel };
try
{
try {
channels.emplace(opChannel, channel); // In case of wrap-around replace existing one
}
catch (...)
{
} catch (...) {
channels.insert(make_pair(opChannel, channel));
}
}
@@ -72,8 +65,7 @@ void Controller::handleTransaction()
channels.at(opChannel).handle(msg);
}
uint32_t Controller::nextChannel()
{
uint32_t Controller::nextChannel() {
do
currChannel++;
while (currChannel == 0xFFFFFFFF || currChannel == 0);

View File

@@ -17,12 +17,11 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#pragma once
#include <map>
#include <chrono>
#include "Channel.hpp"
#include <chrono>
#include <map>
class Controller
{
class Controller {
protected:
std::map<uint32_t, Channel> channels;
uint32_t currChannel;

View File

@@ -20,7 +20,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
using namespace std;
vector<uint8_t> beEncode(const uint8_t* val, const size_t byteCount)
{
return { reverse_iterator<const uint8_t *>(val + byteCount), reverse_iterator<const uint8_t *>(val) };
vector<uint8_t> beEncode(const uint8_t* val, const size_t byteCount) {
return { reverse_iterator<const uint8_t*>(val + byteCount),
reverse_iterator<const uint8_t*>(val) };
}

View File

@@ -17,13 +17,17 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#pragma once
#include <vector>
#include <cstdint>
#include <vector>
template <typename Type>
std::vector<uint8_t> beEncode(const Type val);
std::vector<uint8_t> beEncode(const uint8_t* val, const std::size_t byteCount);
#define FIELD(name) reinterpret_cast<const uint8_t*>(&name), (reinterpret_cast<const uint8_t*>(&name) + sizeof(name))
#define FIELD_BE(name) reverse_iterator<const uint8_t*>(reinterpret_cast<const uint8_t*>(&name) + sizeof(name)), reverse_iterator<const uint8_t*>(reinterpret_cast<const uint8_t*>(&name))
#define FIELD(name) \
reinterpret_cast<const uint8_t*>(&name), \
(reinterpret_cast<const uint8_t*>(&name) + sizeof(name))
#define FIELD_BE(name) \
reverse_iterator<const uint8_t*>(reinterpret_cast<const uint8_t*>(&name) + sizeof(name)), \
reverse_iterator<const uint8_t*>(reinterpret_cast<const uint8_t*>(&name))

62
IO.cpp
View File

@@ -21,26 +21,24 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
#include <iostream>
#include <unistd.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"
#include "u2f.hpp"
#include <chrono>
#include <fcntl.h>
#include <ratio>
#include <sys/stat.h>
#include <sys/types.h>
#include <time.h>
#include <unistd.h>
using namespace std;
bool bytesAvailable(const size_t count);
vector<uint8_t>& getBuffer();
vector<uint8_t> readNonBlock(const size_t count)
{
if (!bytesAvailable(count))
{
vector<uint8_t> readNonBlock(const size_t count) {
if (!bytesAvailable(count)) {
return vector<uint8_t>{};
}
@@ -54,32 +52,29 @@ vector<uint8_t> readNonBlock(const size_t count)
return bytes;
}
void write(const uint8_t* bytes, const size_t count)
{
void write(const uint8_t* bytes, const size_t count) {
size_t totalBytes = 0;
auto hostDescriptor = *getHostDescriptor();
while (totalBytes < count)
{
while (totalBytes < count) {
auto writtenBytes = write(hostDescriptor, bytes + totalBytes, count - totalBytes);
if (writtenBytes > 0)
totalBytes += writtenBytes;
else if (errno != 0 && errno != EAGAIN && errno != EWOULDBLOCK) //Expect file blocking behaviour
else if (errno != 0 && errno != EAGAIN &&
errno != EWOULDBLOCK) // Expect file blocking behaviour
ERR();
}
errno = 0;
}
bool bytesAvailable(const size_t count)
{
bool bytesAvailable(const size_t 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)
{
while (delay.count() < U2FHID_TRANS_TIMEOUT && contProc) {
delay = chrono::high_resolution_clock::now() - startTime;
if (getBuffer().size() >= count) {
#ifdef DEBUG_MSGS
@@ -97,49 +92,42 @@ bool bytesAvailable(const size_t count)
return false;
}
vector<uint8_t>& bufferVar()
{
vector<uint8_t>& bufferVar() {
static vector<uint8_t> buffer{};
return buffer;
}
vector<uint8_t>& getBuffer()
{
vector<uint8_t>& getBuffer() {
auto& buff = bufferVar();
array<uint8_t, HID_RPT_SIZE> bytes{};
auto hostDescriptor = *getHostDescriptor();
while (true)
{
while (true) {
auto readByteCount = read(hostDescriptor, bytes.data(), HID_RPT_SIZE);
if (readByteCount > 0 && readByteCount != 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;
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));
#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();
#ifdef DEBUG_MSGS
cerr << "Unknown stream error: " << errno << endl;
#endif
break;
}
else
{
} else {
errno = 0;
break; // Escape loop if blocking would occur
}

15
LED.cpp
View File

@@ -24,19 +24,16 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
using namespace std;
bool& ledState()
{
bool& ledState() {
static bool state = true;
return state;
}
bool getLEDState()
{
bool getLEDState() {
return ledState();
}
void disableACTTrigger([[maybe_unused]] bool nowDisabled)
{
void disableACTTrigger([[maybe_unused]] bool nowDisabled) {
#ifdef LEDS
ofstream trigFile{ "/sys/class/leds/led0/trigger", ofstream::out | ofstream::trunc };
@@ -48,8 +45,7 @@ void disableACTTrigger([[maybe_unused]] bool nowDisabled)
#endif
}
void enableACTLED([[maybe_unused]] bool nowOn)
{
void enableACTLED([[maybe_unused]] bool nowOn) {
#ifdef LEDS
if (nowOn == getLEDState())
return;
@@ -66,7 +62,6 @@ void enableACTLED([[maybe_unused]] bool nowOn)
#endif
}
void toggleACTLED()
{
void toggleACTLED() {
enableACTLED(!getLEDState());
}

View File

@@ -17,7 +17,12 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#pragma once
#include <unistd.h>
#include <string>
#include <unistd.h>
#define ERR() if (errno != 0) perror((string{ "(" } + __FILE__ + ":" + to_string(__LINE__) + ")" + " " + __PRETTY_FUNCTION__).c_str()), errno = 0
#define ERR() \
if (errno != 0) \
perror( \
(string{ "(" } + __FILE__ + ":" + to_string(__LINE__) + ")" + " " + __PRETTY_FUNCTION__) \
.c_str()), \
errno = 0

View File

@@ -18,24 +18,22 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
#include "Packet.hpp"
#include "IO.hpp"
#include "Streams.hpp"
#include "u2f.hpp"
#include <cstring>
#include <iostream>
#include <unistd.h>
#include "Streams.hpp"
using namespace std;
shared_ptr<InitPacket> InitPacket::getPacket(const uint32_t rCID, const uint8_t rCMD)
{
shared_ptr<InitPacket> InitPacket::getPacket(const uint32_t rCID, const uint8_t rCMD) {
static size_t bytesRead = 0;
static uint8_t bcnth;
static uint8_t bcntl;
static decltype(InitPacket::data) dataBytes;
vector<uint8_t> bytes{};
switch (bytesRead)
{
switch (bytesRead) {
case 0:
bytes = readNonBlock(1);
@@ -62,7 +60,8 @@ shared_ptr<InitPacket> InitPacket::getPacket(const uint32_t rCID, const uint8_t
if (bytes.size() == 0)
return {};
copy(bytes.begin(), bytes.end(), dataBytes.begin());;
copy(bytes.begin(), bytes.end(), dataBytes.begin());
;
bytesRead += bytes.size();
[[fallthrough]];
@@ -82,7 +81,8 @@ shared_ptr<InitPacket> InitPacket::getPacket(const uint32_t rCID, const uint8_t
#ifdef DEBUG_STREAMS
auto hPStream = getHostPacketStream().get();
fprintf(hPStream, "\t\t<table>\n"
fprintf(hPStream,
"\t\t<table>\n"
"\t\t\t<thead>\n"
"\t\t\t\t<tr>\n"
"\t\t\t\t\t<th>CID</th>\n"
@@ -98,7 +98,8 @@ shared_ptr<InitPacket> InitPacket::getPacket(const uint32_t rCID, const uint8_t
"\t\t\t\t\t<td>%u</td>\n"
"\t\t\t\t\t<td>%u</td>\n"
"\t\t\t\t\t<td>%u</td>\n"
"\t\t\t\t\t<td class=\"data\">", p->cid, p->cmd, p->bcnth, p->bcntl);
"\t\t\t\t\t<td class=\"data\">",
p->cid, p->cmd, p->bcnth, p->bcntl);
for (auto elem : dataBytes)
fprintf(hPStream, "%3u ", elem);
@@ -114,16 +115,14 @@ shared_ptr<InitPacket> InitPacket::getPacket(const uint32_t rCID, const uint8_t
return p;
}
shared_ptr<ContPacket> ContPacket::getPacket(const uint32_t rCID, const uint8_t rSeq)
{
shared_ptr<ContPacket> ContPacket::getPacket(const uint32_t rCID, const uint8_t rSeq) {
static size_t readBytes = 0;
static decltype(ContPacket::data) dataBytes;
vector<uint8_t> bytes{};
auto p = make_shared<ContPacket>();
if (readBytes != dataBytes.size())
{
if (readBytes != dataBytes.size()) {
dataBytes = {};
bytes = readNonBlock(dataBytes.size());
@@ -140,7 +139,8 @@ shared_ptr<ContPacket> ContPacket::getPacket(const uint32_t rCID, const uint8_t
#ifdef DEBUG_STREAMS
auto hPStream = getHostPacketStream().get();
fprintf(hPStream, "\t\t<table>\n"
fprintf(hPStream,
"\t\t<table>\n"
"\t\t\t<thead>\n"
"\t\t\t\t<tr>\n"
"\t\t\t\t\t<th>CID</th>\n"
@@ -152,7 +152,8 @@ shared_ptr<ContPacket> ContPacket::getPacket(const uint32_t rCID, const uint8_t
"\t\t\t\t<tr>\n"
"\t\t\t\t\t<td>0x%08X</td>\n"
"\t\t\t\t\t<td>%u</td>\n"
"\t\t\t\t\t<td class=\"data\">", p->cid, p->seq);
"\t\t\t\t\t<td class=\"data\">",
p->cid, p->seq);
for (auto elem : dataBytes)
fprintf(hPStream, "%3u ", elem);
@@ -168,8 +169,7 @@ shared_ptr<ContPacket> ContPacket::getPacket(const uint32_t rCID, const uint8_t
return p;
}
shared_ptr<Packet> Packet::getPacket()
{
shared_ptr<Packet> Packet::getPacket() {
static size_t bytesRead = 0;
vector<uint8_t> bytes{};
@@ -177,8 +177,7 @@ shared_ptr<Packet> Packet::getPacket()
static uint8_t b;
shared_ptr<Packet> packet{};
switch (bytesRead)
{
switch (bytesRead) {
case 0:
bytes = readNonBlock(4);
@@ -200,8 +199,7 @@ shared_ptr<Packet> Packet::getPacket()
[[fallthrough]];
case 5:
if (b & TYPE_MASK)
{
if (b & TYPE_MASK) {
// Init packet
packet = InitPacket::getPacket(cid, b);
@@ -209,9 +207,7 @@ shared_ptr<Packet> Packet::getPacket()
bytesRead = 0;
return packet;
}
else
{
} else {
// Cont packet
packet = ContPacket::getPacket(cid, b);
@@ -225,14 +221,12 @@ shared_ptr<Packet> Packet::getPacket()
}
}
void Packet::writePacket()
{
void Packet::writePacket() {
memset(this->buf, 0, HID_RPT_SIZE);
memcpy(this->buf, &cid, 4);
}
void InitPacket::writePacket()
{
void InitPacket::writePacket() {
Packet::writePacket();
#ifdef DEBUG_STREAMS
@@ -249,7 +243,8 @@ void InitPacket::writePacket()
fwrite(this->buf, 1, sizeof(this->buf), devStream);
auto dPStream = getDevPacketStream().get();
fprintf(dPStream, "\t\t<table>\n"
fprintf(dPStream,
"\t\t<table>\n"
"\t\t\t<thead>\n"
"\t\t\t\t<tr>\n"
"\t\t\t\t\t<th>CID</th>\n"
@@ -265,7 +260,8 @@ void InitPacket::writePacket()
"\t\t\t\t\t<td>%u</td>\n"
"\t\t\t\t\t<td>%u</td>\n"
"\t\t\t\t\t<td>%u</td>\n"
"\t\t\t\t\t<td class=\"data\">", cid, cmd, bcnth, bcntl);
"\t\t\t\t\t<td class=\"data\">",
cid, cmd, bcnth, bcntl);
for (auto elem : data)
fprintf(dPStream, "%3u ", elem);
@@ -278,8 +274,7 @@ void InitPacket::writePacket()
#endif
}
void ContPacket::writePacket()
{
void ContPacket::writePacket() {
Packet::writePacket();
#ifdef DEBUG_STREAMS
@@ -295,7 +290,8 @@ void ContPacket::writePacket()
auto dPStream = getDevPacketStream().get();
fprintf(dPStream, "\t\t<table>\n"
fprintf(dPStream,
"\t\t<table>\n"
"\t\t\t<thead>\n"
"\t\t\t\t<tr>\n"
"\t\t\t\t\t<th>CID</th>\n"
@@ -307,7 +303,8 @@ void ContPacket::writePacket()
"\t\t\t\t<tr>\n"
"\t\t\t\t\t<td>0x%08X</td>\n"
"\t\t\t\t\t<td>%u</td>\n"
"\t\t\t\t\t<td class=\"data\">", cid, seq);
"\t\t\t\t\t<td class=\"data\">",
cid, seq);
for (auto elem : data)
fprintf(dPStream, "%3u ", elem);

View File

@@ -17,13 +17,12 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#pragma once
#include "u2f.hpp"
#include <array>
#include <cstdint>
#include <memory>
#include <array>
#include "u2f.hpp"
struct Packet
{
struct Packet {
public:
uint32_t cid;
uint8_t buf[HID_RPT_SIZE];
@@ -37,8 +36,7 @@ struct Packet
virtual ~Packet() = default;
};
struct InitPacket : Packet
{
struct InitPacket : Packet {
public:
uint8_t cmd;
uint8_t bcnth;
@@ -51,8 +49,7 @@ struct InitPacket : Packet
void writePacket() override;
};
struct ContPacket : Packet
{
struct ContPacket : Packet {
public:
uint8_t seq;
std::array<uint8_t, HID_RPT_SIZE - 5> data{};

View File

@@ -22,21 +22,18 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
using namespace std;
// Ripped from https://github.com/pratikd650/Teensy_U2F/blob/master/Teensy_U2F.cpp
void appendSignatureAsDER(vector<uint8_t> &response, const array<uint8_t, 64> &signature)
{
void appendSignatureAsDER(vector<uint8_t>& response, const array<uint8_t, 64>& signature) {
response.push_back(0x30); // Start of ASN.1 SEQUENCE
response.push_back(68); // total length from (2 * (32 + 2)) to (2 * (33 + 2))
size_t countByte = response.size() - 1;
// Loop twice - for R and S
for(unsigned int i = 0; i < 2; i++)
{
for (unsigned int i = 0; i < 2; i++) {
unsigned int sigOffs = i * 32;
auto offset = signature.begin() + sigOffs;
response.push_back(0x02); // header: integer
response.push_back(32); // 32 byte
if (signature[sigOffs] > 0x7f)
{
if (signature[sigOffs] > 0x7f) {
// Integer needs to be represented in 2's completement notion
response.back()++;
response.push_back(0); // add leading 0, to indicate it is a positive number

View File

@@ -17,8 +17,8 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#pragma once
#include <vector>
#include <array>
#include <vector>
using Digest = std::array<uint8_t, 32>;
using Signature = std::array<uint8_t, 64>;

View File

@@ -17,10 +17,10 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "Storage.hpp"
#include <exception>
#include <sstream>
#include "Base64.tpp"
#include <exception>
#include <iostream>
#include <sstream>
using namespace std;
@@ -30,15 +30,13 @@ std::map<Storage::KeyHandle, Storage::PrivKey> Storage::privKeys{};
std::map<Storage::KeyHandle, Storage::PubKey> Storage::pubKeys{};
std::map<Storage::KeyHandle, Storage::KeyCount> Storage::keyCounts{};
void Storage::init(const string &dirPrefix)
{
void Storage::init(const string& dirPrefix) {
Storage::filename = dirPrefix + "U2F_Priv_Keys.txt";
ifstream file{ Storage::filename };
string line;
size_t lineNumber = 0;
while (getline(file, line))
{
while (getline(file, line)) {
auto strLineNum = to_string(lineNumber);
stringstream ss{ line };
string keyHStr, appStr, privStr, pubStr, keyCStr;
@@ -48,13 +46,15 @@ void Storage::init(const string &dirPrefix)
throw runtime_error{ string{ "Invalid syntax of line " } + strLineNum };
char* endP = nullptr;
Storage::KeyHandle keyH{ static_cast<Storage::KeyHandle>(strtoull(keyHStr.c_str(), &endP, 10)) };
Storage::KeyHandle keyH{ static_cast<Storage::KeyHandle>(
strtoull(keyHStr.c_str(), &endP, 10)) };
if (!endP)
throw runtime_error{ "Invalid keyhandle format on line " + strLineNum };
endP = nullptr;
Storage::KeyCount keyC{ static_cast<Storage::KeyCount>(strtoull(keyCStr.c_str(), &endP, 10)) };
Storage::KeyCount keyC{ static_cast<Storage::KeyCount>(
strtoull(keyCStr.c_str(), &endP, 10)) };
if (!endP)
throw runtime_error{ "Invalid key count format on line " + strLineNum };
@@ -77,12 +77,10 @@ void Storage::init(const string &dirPrefix)
}
}
void Storage::save()
{
void Storage::save() {
ofstream file{ Storage::filename };
for (auto &keypair : Storage::appParams)
{
for (auto& keypair : Storage::appParams) {
const auto& keyID = keypair.first;
const auto& appParam = keypair.second;
const auto& privKey = Storage::privKeys[keyID];

View File

@@ -17,13 +17,12 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#pragma once
#include <map>
#include <array>
#include <string>
#include <fstream>
#include <map>
#include <string>
class Storage
{
class Storage {
public:
using KeyHandle = uint32_t;
using KeyCount = uint32_t;

View File

@@ -17,11 +17,11 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "Streams.hpp"
#include <iostream>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <cstdio>
#include <fcntl.h>
#include <iostream>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
using namespace std;
@@ -31,8 +31,7 @@ FILE* initHTML(FILE *fPtr, const string &title);
void closeHTML(FILE* fPtr);
#endif
shared_ptr<int> getHostDescriptor()
{
shared_ptr<int> getHostDescriptor() {
static shared_ptr<int> descriptor{};
descriptor.reset(new int{ open(HID_DEV, O_RDWR | O_NONBLOCK | O_APPEND) }, [](int* fd) {
@@ -47,8 +46,7 @@ shared_ptr<int> getHostDescriptor()
}
#ifdef DEBUG_STREAMS
shared_ptr<FILE> getComHostStream()
{
shared_ptr<FILE> getComHostStream() {
static shared_ptr<FILE> stream{ fopen(DEBUG_STREAMS "comhost.txt", "wb"), [](FILE* f) {
clog << "Closing comhost stream" << endl;
fclose(f);
@@ -60,9 +58,10 @@ shared_ptr<FILE> getComHostStream()
return stream;
}
shared_ptr<FILE> getHostPacketStream()
{
static shared_ptr<FILE> stream{ initHTML(fopen(DEBUG_STREAMS "hostpackets.html", "wb"), "Host Packets"), [](FILE *f){
shared_ptr<FILE> getHostPacketStream() {
static shared_ptr<FILE> stream{ initHTML(fopen(DEBUG_STREAMS "hostpackets.html", "wb"),
"Host Packets"),
[](FILE* f) {
clog << "Closing hostPackets stream" << endl;
closeHTML(f);
} };
@@ -73,9 +72,10 @@ shared_ptr<FILE> getHostPacketStream()
return stream;
}
shared_ptr<FILE> getHostAPDUStream()
{
static shared_ptr<FILE> stream{ initHTML(fopen(DEBUG_STREAMS "hostAPDU.html", "wb"), "Host APDU"), [](FILE *f){
shared_ptr<FILE> getHostAPDUStream() {
static shared_ptr<FILE> stream{ initHTML(fopen(DEBUG_STREAMS "hostAPDU.html", "wb"),
"Host APDU"),
[](FILE* f) {
clog << "Closing host APDU stream" << endl;
closeHTML(f);
} };
@@ -86,8 +86,7 @@ shared_ptr<FILE> getHostAPDUStream()
return stream;
}
shared_ptr<FILE> getComDevStream()
{
shared_ptr<FILE> getComDevStream() {
static shared_ptr<FILE> stream{ fopen(DEBUG_STREAMS "comdev.txt", "wb"), [](FILE* f) {
clog << "Closing comdev stream" << endl;
fclose(f);
@@ -99,9 +98,10 @@ shared_ptr<FILE> getComDevStream()
return stream;
}
shared_ptr<FILE> getDevPacketStream()
{
static shared_ptr<FILE> stream{ initHTML(fopen(DEBUG_STREAMS "devpackets.html", "wb"), "Dev Packets"), [](FILE *f){
shared_ptr<FILE> getDevPacketStream() {
static shared_ptr<FILE> stream{ initHTML(fopen(DEBUG_STREAMS "devpackets.html", "wb"),
"Dev Packets"),
[](FILE* f) {
clog << "Closing devPackets stream" << endl;
closeHTML(f);
} };
@@ -112,9 +112,9 @@ shared_ptr<FILE> getDevPacketStream()
return stream;
}
shared_ptr<FILE> getDevAPDUStream()
{
static shared_ptr<FILE> stream{ initHTML(fopen(DEBUG_STREAMS "devAPDU.html", "wb"), "Dev APDU"), [](FILE *f){
shared_ptr<FILE> getDevAPDUStream() {
static shared_ptr<FILE> stream{ initHTML(fopen(DEBUG_STREAMS "devAPDU.html", "wb"), "Dev APDU"),
[](FILE* f) {
clog << "Closing dev APDU stream" << endl;
closeHTML(f);
} };
@@ -125,9 +125,9 @@ shared_ptr<FILE> getDevAPDUStream()
return stream;
}
FILE* initHTML(FILE *fPtr, const string &title)
{
fprintf(fPtr, "<html>\n"
FILE* initHTML(FILE* fPtr, const string& title) {
fprintf(fPtr,
"<html>\n"
"\t<head>\n"
"\t\t<title>%s</title>\n"
"\t\t<style>\n"
@@ -164,13 +164,13 @@ FILE* initHTML(FILE *fPtr, const string &title)
"\t\t</style>\n"
"\t</head>\n"
"\n"
"\t<body>", title.c_str());
"\t<body>",
title.c_str());
return fPtr;
}
void closeHTML(FILE *fPtr)
{
void closeHTML(FILE* fPtr) {
fprintf(fPtr, "\t</body>\n"
"</html>");
fclose(fPtr);

View File

@@ -17,9 +17,9 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#pragma once
#include "Architecture.hpp"
#include <cstdio>
#include <memory>
#include "Architecture.hpp"
std::shared_ptr<int> getHostDescriptor();

View File

@@ -17,10 +17,10 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "Architecture.hpp"
#include <iostream>
#include "Storage.hpp"
#include "Controller.hpp"
#include "LED.hpp"
#include "Storage.hpp"
#include <iostream>
#include <signal.h>
#include <unistd.h>
@@ -31,13 +31,10 @@ void signalCallback(int signum);
volatile bool contProc = true;
bool initialiseLights(const string& prog) {
try
{
try {
disableACTTrigger(true);
enableACTLED(false);
}
catch (runtime_error &e)
{
} catch (runtime_error& e) {
cerr << e.what() << endl;
if (getuid() != 0)
@@ -49,20 +46,15 @@ bool initialiseLights(const string& prog) {
return true;
}
int handleTransactions(const string& prog, const string& privKeyDir)
{
int handleTransactions(const string& prog, const string& privKeyDir) {
signal(SIGINT, signalCallback);
Storage::init(privKeyDir);
Controller ch{ 0xF1D00000 };
while (contProc)
{
try
{
while (contProc) {
try {
ch.handleTransaction();
}
catch (const runtime_error &e)
{
} catch (const runtime_error& e) {
cerr << e.what() << endl;
if (getuid() != 0)
@@ -79,13 +71,10 @@ int handleTransactions(const string& prog, const string& privKeyDir)
}
bool deinitialiseLights(const string& prog) {
try
{
try {
disableACTTrigger(false);
enableACTLED(true);
}
catch (runtime_error &e)
{
} catch (runtime_error& e) {
cerr << e.what() << endl;
if (getuid() != 0)
@@ -97,8 +86,7 @@ bool deinitialiseLights(const string& prog) {
return true;
}
void signalCallback([[maybe_unused]] int signum)
{
void signalCallback([[maybe_unused]] int signum) {
contProc = false;
clog << "\nClosing" << endl;
}

View File

@@ -24,4 +24,3 @@ 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);

View File

@@ -17,18 +17,17 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "U2FMessage.hpp"
#include "IO.hpp"
#include "Packet.hpp"
#include <stdexcept>
#include <iostream>
#include <iomanip>
#include "Streams.hpp"
#include "u2f.hpp"
#include "IO.hpp"
#include <iomanip>
#include <iostream>
#include <stdexcept>
using namespace std;
shared_ptr<U2FMessage> U2FMessage::readNonBlock()
{
shared_ptr<U2FMessage> U2FMessage::readNonBlock() {
const static size_t startSeq = (size_t)-1ull;
static size_t currSeq = startSeq;
static uint16_t messageSize;
@@ -38,16 +37,14 @@ shared_ptr<U2FMessage> U2FMessage::readNonBlock()
shared_ptr<Packet> p{};
if (currSeq == startSeq)
{
if (currSeq == startSeq) {
cid = 0;
cmd = 0;
messageSize = 0;
dataBytes = {};
shared_ptr<InitPacket> initPack{};
do
{
do {
p = Packet::getPacket();
if (!p)
@@ -62,16 +59,19 @@ shared_ptr<U2FMessage> U2FMessage::readNonBlock()
} while (!initPack); // Spurious cont. packet - spec states ignore
messageSize = ((static_cast<uint16_t>(initPack->bcnth) << 8u) + initPack->bcntl);
const uint16_t copyByteCount = min(static_cast<uint16_t>(initPack->data.size()), messageSize);
const uint16_t copyByteCount =
min(static_cast<uint16_t>(initPack->data.size()), messageSize);
cid = initPack->cid;
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 = 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
{
auto contPack = dynamic_pointer_cast<ContPacket>(p);
@@ -87,15 +87,15 @@ shared_ptr<U2FMessage> U2FMessage::readNonBlock()
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);
currSeq = startSeq;
return {};
}
if (contPack->seq != currSeq)
{
if (contPack->seq != currSeq) {
#ifdef DEBUG_MSGS
cerr << "Invalid packet seq. value" << endl;
#endif
@@ -105,15 +105,18 @@ shared_ptr<U2FMessage> U2FMessage::readNonBlock()
}
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++;
}
if (messageSize != dataBytes.size()) {
#ifdef DEBUG_MSGS
cerr << "Invalid message size: " << messageSize << " when received " << dataBytes.size() << endl;
cerr << "Invalid message size: " << messageSize << " when received " << dataBytes.size()
<< endl;
#endif
return {};
}
@@ -125,8 +128,7 @@ shared_ptr<U2FMessage> U2FMessage::readNonBlock()
return message;
}
void U2FMessage::write()
{
void U2FMessage::write() {
const uint16_t bytesToWrite = this->data.size();
uint16_t bytesWritten = 0;
@@ -141,7 +143,8 @@ void U2FMessage::write()
p.bcntl = bcntl;
{
uint16_t initialByteCount = min(static_cast<uint16_t>(p.data.size()), static_cast<uint16_t>(bytesToWrite - bytesWritten));
uint16_t initialByteCount = min(static_cast<uint16_t>(p.data.size()),
static_cast<uint16_t>(bytesToWrite - bytesWritten));
copy(data.begin(), data.begin() + initialByteCount, p.data.begin());
bytesWritten += initialByteCount;
}
@@ -151,20 +154,20 @@ void U2FMessage::write()
uint8_t seq = 0;
while (bytesWritten != bytesToWrite)
{
while (bytesWritten != bytesToWrite) {
ContPacket p{};
p.cid = cid;
p.seq = seq;
uint16_t newByteCount = min(static_cast<uint16_t>(p.data.size()), static_cast<uint16_t>(bytesToWrite - bytesWritten));
copy(data.begin() + bytesWritten, data.begin() + bytesWritten + newByteCount, p.data.begin());
uint16_t newByteCount = min(static_cast<uint16_t>(p.data.size()),
static_cast<uint16_t>(bytesToWrite - bytesWritten));
copy(data.begin() + bytesWritten, data.begin() + bytesWritten + newByteCount,
p.data.begin());
p.writePacket();
seq++;
bytesWritten += newByteCount;
}
if (cmd == U2FHID_MSG)
{
if (cmd == U2FHID_MSG) {
#ifdef DEBUG_STREAMS
auto dAS = getDevAPDUStream().get();
@@ -187,22 +190,21 @@ void U2FMessage::write()
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</tr>\n"
"\t\t\t</tbody>\n"
"\t\t</table>\n"
"\t\t<br />", err);
"\t\t<br />",
err);
#endif
}
}
U2FMessage::U2FMessage(const uint32_t nCID, const uint8_t nCMD)
: cid{ nCID }, cmd{ nCMD }
{}
U2FMessage::U2FMessage(const uint32_t nCID, const uint8_t nCMD) : cid{ nCID }, cmd{ nCMD } {}
void U2FMessage::error(const uint32_t tCID, const uint8_t tErr)
{
void U2FMessage::error(const uint32_t tCID, const uint8_t tErr) {
U2FMessage msg{};
msg.cid = tCID;
msg.cmd = U2FHID_ERROR;

View File

@@ -18,12 +18,10 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
#pragma once
#include <cstdint>
#include <vector>
#include <memory>
#include <cstdint>
#include <vector>
struct U2FMessage
{
struct U2FMessage {
public:
uint32_t cid;
uint8_t cmd;

View File

@@ -17,28 +17,24 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "U2F_Authenticate_APDU.hpp"
#include "Field.hpp"
#include "U2FMessage.hpp"
#include "u2f.hpp"
#include "Field.tpp"
#include "APDU.hpp"
#include <iostream>
#include "Field.hpp"
#include "Field.tpp"
#include "Signature.hpp"
#include "U2FMessage.hpp"
#include "micro-ecc/uECC.h"
#include "u2f.hpp"
#include <iostream>
#include <mbedtls/sha256.h>
using namespace std;
U2F_Authenticate_APDU::U2F_Authenticate_APDU(const U2F_Msg_CMD& msg, const vector<uint8_t>& data)
: U2F_Msg_CMD{ msg }
{
if (p2 != 0)
{
: U2F_Msg_CMD{ msg } {
if (p2 != 0) {
// Invalid U2F (APDU) parameter detected
throw APDU_STATUS::SW_CONDITIONS_NOT_SATISFIED;
}
else if (data.size() < 66)
{
} else if (data.size() < 66) {
// Invalid authentication request
throw APDU_STATUS::SW_WRONG_LENGTH;
}
@@ -51,10 +47,8 @@ U2F_Authenticate_APDU::U2F_Authenticate_APDU(const U2F_Msg_CMD &msg, const vecto
copy(data.begin() + 65, data.begin() + 65 + keyHLen, back_inserter(keyH));
}
void U2F_Authenticate_APDU::respond(const uint32_t channelID) const
{
if (keyH.size() != sizeof(Storage::KeyHandle))
{
void U2F_Authenticate_APDU::respond(const uint32_t channelID) const {
if (keyH.size() != sizeof(Storage::KeyHandle)) {
// Respond with error code - key handle is of wrong size
cerr << "Invalid key handle length" << endl;
this->error(channelID, APDU_STATUS::SW_WRONG_DATA);
@@ -63,8 +57,7 @@ void U2F_Authenticate_APDU::respond(const uint32_t channelID) const
auto keyHB = *reinterpret_cast<const Storage::KeyHandle*>(keyH.data());
if (Storage::appParams.find(keyHB) == Storage::appParams.end())
{
if (Storage::appParams.find(keyHB) == Storage::appParams.end()) {
// Respond with error code - key handle doesn't exist in storage
cerr << "Invalid key handle" << endl;
this->error(channelID, SW_WRONG_DATA);
@@ -80,8 +73,7 @@ void U2F_Authenticate_APDU::respond(const uint32_t channelID) const
auto& response = msg.data;
APDU_STATUS statusCode = APDU_STATUS::SW_NO_ERROR;
switch (p1)
{
switch (p1) {
case ControlCode::CheckOnly:
if (appMatches)
statusCode = APDU_STATUS::SW_CONDITIONS_NOT_SATISFIED;
@@ -117,7 +109,8 @@ void U2F_Authenticate_APDU::respond(const uint32_t channelID) const
mbedtls_sha256_init(&shaContext);
mbedtls_sha256_starts(&shaContext, 0);
mbedtls_sha256_update(&shaContext, reinterpret_cast<const uint8_t *>(appParam.data()), sizeof(appParam));
mbedtls_sha256_update(&shaContext, reinterpret_cast<const uint8_t*>(appParam.data()),
sizeof(appParam));
uint8_t userPresence{ 1u };
mbedtls_sha256_update(&shaContext, &userPresence, 1);
const auto beCounter = beEncode(keyCount);

View File

@@ -17,11 +17,10 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#pragma once
#include "U2F_Msg_CMD.hpp"
#include "Storage.hpp"
#include "U2F_Msg_CMD.hpp"
struct U2F_Authenticate_APDU : U2F_Msg_CMD
{
struct U2F_Authenticate_APDU : U2F_Msg_CMD {
uint8_t controlByte;
std::array<uint8_t, 32> challengeP;
Storage::AppParam appParam;
@@ -32,8 +31,7 @@ struct U2F_Authenticate_APDU : U2F_Msg_CMD
virtual void respond(const uint32_t channelID) const override;
enum ControlCode
{
enum ControlCode {
CheckOnly = 0x07,
EnforcePresenceSign = 0x03,
DontEnforcePresenceSign = 0x08

View File

@@ -17,19 +17,16 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "U2F_CMD.hpp"
#include "u2f.hpp"
#include "U2F_Msg_CMD.hpp"
#include "U2F_Init_CMD.hpp"
#include "U2F_Msg_CMD.hpp"
#include "U2F_Ping_CMD.hpp"
#include "u2f.hpp"
using namespace std;
shared_ptr<U2F_CMD> U2F_CMD::get(const shared_ptr<U2FMessage> uMsg)
{
try
{
switch (uMsg->cmd)
{
shared_ptr<U2F_CMD> U2F_CMD::get(const shared_ptr<U2FMessage> uMsg) {
try {
switch (uMsg->cmd) {
case U2FHID_PING:
return make_shared<U2F_Ping_CMD>(uMsg);
case U2FHID_MSG:
@@ -40,9 +37,7 @@ shared_ptr<U2F_CMD> U2F_CMD::get(const shared_ptr<U2FMessage> uMsg)
U2FMessage::error(uMsg->cid, ERR_INVALID_CMD);
return {};
}
}
catch (runtime_error& ignored)
{
} catch (runtime_error& ignored) {
U2FMessage::error(uMsg->cid, ERR_OTHER);
return {};
}

View File

@@ -17,11 +17,10 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#pragma once
#include <memory>
#include "U2FMessage.hpp"
#include <memory>
struct U2F_CMD
{
struct U2F_CMD {
protected:
U2F_CMD() = default;

View File

@@ -17,23 +17,19 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "U2F_Init_CMD.hpp"
#include <stdexcept>
#include "u2f.hpp"
#include "Field.hpp"
#include "u2f.hpp"
#include <stdexcept>
using namespace std;
U2F_Init_CMD::U2F_Init_CMD(const shared_ptr<U2FMessage> uMsg)
{
U2F_Init_CMD::U2F_Init_CMD(const shared_ptr<U2FMessage> uMsg) {
if (uMsg->cmd != U2FHID_INIT)
throw runtime_error{ "Failed to get U2F Init message" };
else if (uMsg->cid != CID_BROADCAST)
{
else if (uMsg->cid != CID_BROADCAST) {
U2FMessage::error(uMsg->cid, ERR_OTHER);
throw runtime_error{ "Invalid CID for init command" };
}
else if (uMsg->data.size() != INIT_NONCE_SIZE)
{
} else if (uMsg->data.size() != INIT_NONCE_SIZE) {
U2FMessage::error(uMsg->cid, ERR_INVALID_LEN);
throw runtime_error{ "Init nonce is incorrect size" };
}
@@ -41,8 +37,7 @@ U2F_Init_CMD::U2F_Init_CMD(const shared_ptr<U2FMessage> uMsg)
this->nonce = *reinterpret_cast<const uint64_t*>(uMsg->data.data());
}
void U2F_Init_CMD::respond(const uint32_t channelID) const
{
void U2F_Init_CMD::respond(const uint32_t channelID) const {
U2FMessage msg{};
msg.cid = CID_BROADCAST;
msg.cmd = U2FHID_INIT;

View File

@@ -17,13 +17,12 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#pragma once
#include "U2FMessage.hpp"
#include "U2F_CMD.hpp"
#include <cstdint>
#include <memory>
#include "U2F_CMD.hpp"
#include "U2FMessage.hpp"
struct U2F_Init_CMD : U2F_CMD
{
struct U2F_Init_CMD : U2F_CMD {
uint64_t nonce;
public:

View File

@@ -18,26 +18,22 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
#include "U2F_Msg_CMD.hpp"
#include "APDU.hpp"
#include "Field.hpp"
#include "Streams.hpp"
#include "U2FMessage.hpp"
#include "U2F_Authenticate_APDU.hpp"
#include "U2F_Register_APDU.hpp"
#include "U2F_Version_APDU.hpp"
#include "U2F_Authenticate_APDU.hpp"
#include "U2FMessage.hpp"
#include "u2f.hpp"
#include "APDU.hpp"
#include <iostream>
#include "Streams.hpp"
#include "Field.hpp"
using namespace std;
uint32_t U2F_Msg_CMD::getLe(const uint32_t byteCount, vector<uint8_t> bytes)
{
if (byteCount != 0)
{
uint32_t U2F_Msg_CMD::getLe(const uint32_t byteCount, vector<uint8_t> bytes) {
if (byteCount != 0) {
// Le must be length of data in bytes
switch (byteCount)
{
switch (byteCount) {
case 1:
return (bytes[0] == 0 ? 256 : bytes[0]);
case 2:
@@ -55,17 +51,14 @@ uint32_t U2F_Msg_CMD::getLe(const uint32_t byteCount, vector<uint8_t> bytes)
default:
throw runtime_error{ "Too much data for command" };
}
}
else
} else
return 0;
}
shared_ptr<U2F_Msg_CMD> U2F_Msg_CMD::generate(const shared_ptr<U2FMessage> uMsg)
{
shared_ptr<U2F_Msg_CMD> U2F_Msg_CMD::generate(const shared_ptr<U2FMessage> uMsg) {
if (uMsg->cmd != U2FHID_MSG)
throw runtime_error{ "Failed to get U2F Msg uMsg" };
else if (uMsg->data.size() < 4)
{
else if (uMsg->data.size() < 4) {
U2F_Msg_CMD::error(uMsg->cid, APDU_STATUS::SW_WRONG_LENGTH);
throw runtime_error{ "Msg data is incorrect size" };
}
@@ -75,8 +68,7 @@ shared_ptr<U2F_Msg_CMD> U2F_Msg_CMD::generate(const shared_ptr<U2FMessage> uMsg)
cmd.cla = dat[0];
if (cmd.cla != 0)
{
if (cmd.cla != 0) {
U2F_Msg_CMD::error(uMsg->cid, APDU_STATUS::SW_COMMAND_NOT_ALLOWED);
throw runtime_error{ "Invalid CLA value in U2F Message" };
}
@@ -89,10 +81,8 @@ shared_ptr<U2F_Msg_CMD> U2F_Msg_CMD::generate(const shared_ptr<U2FMessage> uMsg)
const uint32_t cBCount = data.size();
auto startPtr = data.begin(), endPtr = data.end();
if (usesData.at(cmd.ins) || data.size() > 3)
{
if (cBCount == 0)
{
if (usesData.at(cmd.ins) || data.size() > 3) {
if (cBCount == 0) {
U2F_Msg_CMD::error(uMsg->cid, APDU_STATUS::SW_WRONG_LENGTH);
throw runtime_error{ "Invalid command - should have attached data" };
}
@@ -101,36 +91,26 @@ shared_ptr<U2F_Msg_CMD> U2F_Msg_CMD::generate(const shared_ptr<U2FMessage> uMsg)
{
cmd.lc = data[0];
startPtr++;
}
else
{
} else {
cmd.lc = (data[1] << 8) + data[2];
startPtr += 3;
}
endPtr = startPtr + cmd.lc;
try
{
try {
cmd.le = getLe(data.end() - endPtr, vector<uint8_t>(endPtr, data.end()));
}
catch (runtime_error& ignored)
{
} catch (runtime_error& ignored) {
U2F_Msg_CMD::error(uMsg->cid, APDU_STATUS::SW_WRONG_LENGTH);
throw;
}
}
else
{
} else {
cmd.lc = 0;
endPtr = startPtr;
try
{
try {
cmd.le = getLe(cBCount, data);
}
catch (runtime_error& ignored)
{
} catch (runtime_error& ignored) {
U2F_Msg_CMD::error(uMsg->cid, APDU_STATUS::SW_WRONG_LENGTH);
throw;
}
@@ -141,7 +121,8 @@ shared_ptr<U2F_Msg_CMD> U2F_Msg_CMD::generate(const shared_ptr<U2FMessage> uMsg)
#ifdef DEBUG_STREAMS
auto hAS = getHostAPDUStream().get();
fprintf(hAS, "<table>\n"
fprintf(hAS,
"<table>\n"
"\t\t\t<thead>\n"
"\t\t\t\t<tr>\n"
"\t\t\t\t\t<th>CLA</th>\n"
@@ -160,23 +141,24 @@ shared_ptr<U2F_Msg_CMD> U2F_Msg_CMD::generate(const shared_ptr<U2FMessage> uMsg)
"\t\t\t\t\t<td>%u</td>\n"
"\t\t\t\t\t<td>%u</td>\n"
"\t\t\t\t\t<td>%3u</td>\n"
"\t\t\t\t\t<td class=\"data\">", cmd.cla, cmd.ins, cmd.p1, cmd.p2, cmd.lc);
"\t\t\t\t\t<td class=\"data\">",
cmd.cla, cmd.ins, cmd.p1, cmd.p2, cmd.lc);
for (auto b : dBytes)
fprintf(hAS, "%3u ", b);
fprintf(hAS, "</td>\n"
fprintf(hAS,
"</td>\n"
"\t\t\t\t\t<td>%5u</td>\n"
"\t\t\t\t</tr>\n"
"\t\t\t</tbody>\n"
"\t\t</table>\n"
"\t\t<br />", cmd.le);
"\t\t<br />",
cmd.le);
#endif
try
{
switch (cmd.ins)
{
try {
switch (cmd.ins) {
case APDU::U2F_REG:
return make_shared<U2F_Register_APDU>(cmd, dBytes);
case APDU::U2F_AUTH:
@@ -187,17 +169,14 @@ shared_ptr<U2F_Msg_CMD> U2F_Msg_CMD::generate(const shared_ptr<U2FMessage> uMsg)
cerr << "Invalid command used" << endl;
throw APDU_STATUS::SW_INS_NOT_SUPPORTED;
}
}
catch (const APDU_STATUS e)
{
} catch (const APDU_STATUS e) {
U2F_Msg_CMD::error(uMsg->cid, e);
throw runtime_error{ "APDU construction error" };
return {};
}
}
void U2F_Msg_CMD::error(const uint32_t channelID, const uint16_t errCode)
{
void U2F_Msg_CMD::error(const uint32_t channelID, const uint16_t errCode) {
clog << "U2F_Msg_CMD::error " << errCode << endl;
U2FMessage msg{};
msg.cid = channelID;
@@ -206,13 +185,10 @@ void U2F_Msg_CMD::error(const uint32_t channelID, const uint16_t errCode)
msg.write();
}
const map<uint8_t, bool> U2F_Msg_CMD::usesData = {
{ U2F_REG, true },
const map<uint8_t, bool> U2F_Msg_CMD::usesData = { { U2F_REG, true },
{ U2F_AUTH, true },
{ U2F_VER, false }
};
{ U2F_VER, false } };
void U2F_Msg_CMD::respond(const uint32_t channelID) const
{
void U2F_Msg_CMD::respond(const uint32_t channelID) const {
U2F_Msg_CMD::error(channelID, static_cast<uint16_t>(APDU_STATUS::SW_INS_NOT_SUPPORTED));
}

View File

@@ -20,11 +20,10 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
#include "U2F_CMD.hpp"
#include <cstdint>
#include <map>
#include <vector>
#include <memory>
#include <vector>
struct U2F_Msg_CMD : U2F_CMD
{
struct U2F_Msg_CMD : U2F_CMD {
uint8_t cla;
uint8_t ins;
uint8_t p1;
@@ -43,4 +42,3 @@ struct U2F_Msg_CMD : U2F_CMD
static void error(const uint32_t channelID, const uint16_t errCode);
void respond(const uint32_t channelID) const;
};

View File

@@ -21,15 +21,12 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
using namespace std;
U2F_Ping_CMD::U2F_Ping_CMD(const shared_ptr<U2FMessage> uMsg)
: nonce{ uMsg->data }
{
U2F_Ping_CMD::U2F_Ping_CMD(const shared_ptr<U2FMessage> uMsg) : nonce{ uMsg->data } {
if (uMsg->cmd != U2FHID_PING)
throw runtime_error{ "Failed to get U2F ping message" };
}
void U2F_Ping_CMD::respond(const uint32_t channelID) const
{
void U2F_Ping_CMD::respond(const uint32_t channelID) const {
U2FMessage msg{};
msg.cid = channelID;
msg.cmd = U2FHID_PING;

View File

@@ -17,13 +17,12 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#pragma once
#include "U2FMessage.hpp"
#include "U2F_CMD.hpp"
#include <cstdint>
#include <memory>
#include "U2F_CMD.hpp"
#include "U2FMessage.hpp"
struct U2F_Ping_CMD : U2F_CMD
{
struct U2F_Ping_CMD : U2F_CMD {
std::vector<uint8_t> nonce;
public:

View File

@@ -17,28 +17,25 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "U2F_Register_APDU.hpp"
#include <exception>
#include <cstring>
#include "micro-ecc/uECC.h"
#include "Certificates.hpp"
#include <mbedtls/sha256.h>
#include <iostream>
#include "APDU.hpp"
#include "U2FMessage.hpp"
#include "u2f.hpp"
#include "Certificates.hpp"
#include "Signature.hpp"
#include "U2FMessage.hpp"
#include "micro-ecc/uECC.h"
#include "u2f.hpp"
#include <cstring>
#include <exception>
#include <iostream>
#include <mbedtls/sha256.h>
using namespace std;
U2F_Register_APDU::U2F_Register_APDU(const U2F_Msg_CMD& msg, const vector<uint8_t>& data)
: U2F_Msg_CMD{ msg }
{
if (data.size() != 64)
{
: U2F_Msg_CMD{ msg } {
if (data.size() != 64) {
// Incorrect registration size
throw APDU_STATUS::SW_WRONG_LENGTH;
}
else if ((p1 != 0x00 && p1 != 0x03) || p2 != 0x00) //According to spec, 0x03 not allowed here
} else if ((p1 != 0x00 && p1 != 0x03) || p2 != 0x00) // According to spec, 0x03 not allowed here
// However, browsers seem to do it, so...
{
// Invalid U2F Message (APDU) parameters detected
@@ -64,8 +61,7 @@ U2F_Register_APDU::U2F_Register_APDU(const U2F_Msg_CMD &msg, const vector<uint8_
Storage::keyCounts[this->keyH] = 0;
}
void U2F_Register_APDU::respond(const uint32_t channelID) const
{
void U2F_Register_APDU::respond(const uint32_t channelID) const {
U2FMessage m{};
m.cid = channelID;
m.cmd = U2FHID_MSG;
@@ -94,13 +90,18 @@ void U2F_Register_APDU::respond(const uint32_t channelID) const
uint8_t byteReserved = 0;
mbedtls_sha256_update(&shaContext, reinterpret_cast<unsigned char*>(&byteReserved), 1);
mbedtls_sha256_update(&shaContext, reinterpret_cast<const unsigned char*>(appParam.data()), appParam.size());
mbedtls_sha256_update(&shaContext, reinterpret_cast<const unsigned char*>(appParam.data()),
appParam.size());
mbedtls_sha256_update(&shaContext, reinterpret_cast<const unsigned char*>(challengeP.data()), challengeP.size());
mbedtls_sha256_update(&shaContext,
reinterpret_cast<const unsigned char*>(challengeP.data()),
challengeP.size());
mbedtls_sha256_update(&shaContext, reinterpret_cast<const unsigned char*>(&keyH), sizeof(keyH));
mbedtls_sha256_update(&shaContext, reinterpret_cast<const unsigned char*>(&keyH),
sizeof(keyH));
mbedtls_sha256_update(&shaContext, reinterpret_cast<const unsigned char*>(pubKey.data()), pubKey.size());
mbedtls_sha256_update(&shaContext, reinterpret_cast<const unsigned char*>(pubKey.data()),
pubKey.size());
mbedtls_sha256_finish(&shaContext, digest.data());
mbedtls_sha256_free(&shaContext);

View File

@@ -17,11 +17,10 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#pragma once
#include "U2F_Msg_CMD.hpp"
#include "Storage.hpp"
#include "U2F_Msg_CMD.hpp"
struct U2F_Register_APDU : U2F_Msg_CMD
{
struct U2F_Register_APDU : U2F_Msg_CMD {
std::array<uint8_t, 32> challengeP;
Storage::AppParam appP;
Storage::KeyHandle keyH;
@@ -31,4 +30,3 @@ struct U2F_Register_APDU : U2F_Msg_CMD
void respond(const uint32_t channelID) const override;
};

View File

@@ -17,16 +17,15 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "U2F_Version_APDU.hpp"
#include <iostream>
#include "APDU.hpp"
#include "Field.hpp"
#include "U2FMessage.hpp"
#include "u2f.hpp"
#include "Field.hpp"
#include "APDU.hpp"
#include <iostream>
using namespace std;
U2F_Version_APDU::U2F_Version_APDU(const U2F_Msg_CMD &msg, const std::vector<uint8_t> &data)
{
U2F_Version_APDU::U2F_Version_APDU(const U2F_Msg_CMD& msg, const std::vector<uint8_t>& data) {
// Don't actually respond yet unless invalid
if (msg.p1 != 0 || msg.p2 != 0)
throw APDU_STATUS::SW_INS_NOT_SUPPORTED;
@@ -34,8 +33,7 @@ U2F_Version_APDU::U2F_Version_APDU(const U2F_Msg_CMD &msg, const std::vector<uin
throw APDU_STATUS::SW_WRONG_LENGTH;
}
void U2F_Version_APDU::respond(const uint32_t channelID) const
{
void U2F_Version_APDU::respond(const uint32_t channelID) const {
char ver[]{ 'U', '2', 'F', '_', 'V', '2' };
U2FMessage m{};

View File

@@ -19,8 +19,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
#pragma once
#include "U2F_Msg_CMD.hpp"
struct U2F_Version_APDU : U2F_Msg_CMD
{
struct U2F_Version_APDU : U2F_Msg_CMD {
public:
U2F_Version_APDU(const U2F_Msg_CMD& msg, const std::vector<uint8_t>& data);
void respond(const uint32_t channelID) const override;

View File

@@ -1,17 +1,15 @@
#include "U2FDevice.hpp"
#include "Architecture.hpp"
#include "U2FDevice.hpp"
#include <execinfo.h>
#include <iostream>
#ifdef DEBUG_MSGS
// Courtesy StackOverflow answer https://stackoverflow.com/a/3356421
void terminateHandler()
{
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)
{
for (int i = 0; i < trace_elem_count; ++i) {
std::cout << stack_syms[i] << "\n";
}
free(stack_syms);
@@ -26,13 +24,10 @@ int main(int argc, char **argv) {
#endif
int retCode = handleTransactions(argv[0], argc == 2 ? argv[1] : STORAGE_PREFIX);
try
{
try {
initialiseLights(argv[0]);
deinitialiseLights(argv[0]);
}
catch (std::exception &e)
{
} catch (std::exception& e) {
std::cerr << "Exception in code: " << e.what() << std::endl;
throw;
}

View File

@@ -124,4 +124,3 @@ typedef struct {
#endif
#endif // __U2FHID_H_INCLUDED__