diff --git a/fido2/ctap.c b/fido2/ctap.c index b062c1b..812d641 100644 --- a/fido2/ctap.c +++ b/fido2/ctap.c @@ -1180,7 +1180,7 @@ uint8_t ctap_request(uint8_t * pkt_raw, int length, CTAP_RESPONSE * resp) } else { - status = CTAP2_ERR_NOT_ALLOWED; + status = CTAP2_ERR_OPERATION_DENIED; } break; case GET_NEXT_ASSERTION: diff --git a/fido2/u2f.c b/fido2/u2f.c index 74b7bba..62a0206 100644 --- a/fido2/u2f.c +++ b/fido2/u2f.c @@ -4,6 +4,7 @@ #include "crypto.h" #include "log.h" #include "device.h" +#include "wallet.h" #include "app.h" // void u2f_response_writeback(uint8_t * buf, uint8_t len); @@ -36,18 +37,10 @@ void u2f_request(struct u2f_request_apdu* req, CTAP_RESPONSE * resp) { if (req->p1 == U2F_AUTHENTICATE_CHECK) { -// if (u2f_appid_eq(&req->kh, req->app) == 0) -// { -// rcode = U2F_SW_CONDITIONS_NOT_SATISFIED; -// } -// else -// { - rcode = U2F_SW_WRONG_DATA; -// } } else { - rcode = bridge_u2f_to_wallet(auth->chal, auth->app, auth->khl, &auth->kh); + rcode = bridge_u2f_to_wallet(auth->chal, auth->app, auth->khl, (uint8_t*)&auth->kh); } } else if (req->ins == U2F_VERSION) @@ -64,7 +57,7 @@ void u2f_request(struct u2f_request_apdu* req, CTAP_RESPONSE * resp) } else { - rcode = U2F_SW_INS_NOT_SUPPORTED; + rcode = U2F_SW_INS_NOT_SUPPORTED; } #else switch(req->ins) diff --git a/fido2/wallet.c b/fido2/wallet.c index 7c3c7ae..a16ee1b 100644 --- a/fido2/wallet.c +++ b/fido2/wallet.c @@ -39,6 +39,8 @@ typedef enum WalletSign = 0x10, WalletRegister = 0x11, WalletPin = 0x12, + WalletReset= 0x13, + WalletVersion= 0x14, } WalletOperation; @@ -80,7 +82,7 @@ int8_t wallet_pin(uint8_t subcmd, uint8_t * pinAuth, uint8_t * arg1, uint8_t * a if ( ctap_device_locked() ) { - return CTAP2_ERR_OPERATION_DENIED; + return CTAP2_ERR_NOT_ALLOWED; } u2f_response_writeback(KEY_AGREEMENT_PUB,sizeof(KEY_AGREEMENT_PUB)); @@ -95,11 +97,16 @@ int8_t wallet_pin(uint8_t subcmd, uint8_t * pinAuth, uint8_t * arg1, uint8_t * a break; case CP_cmdSetPin: printf1(TAG_WALLET,"cmdSetPin\n"); - if (ctap_is_pin_set()) + if (ctap_is_pin_set() || ctap_device_locked()) { return CTAP2_ERR_NOT_ALLOWED; } + if (!ctap_user_presence_test()) + { + return CTAP2_ERR_OPERATION_DENIED; + } + //pinEnc // plat_pubkey ret = ctap_update_pin_if_verified( arg2, len, arg1, pinAuth, NULL); if (ret != 0) @@ -117,10 +124,16 @@ int8_t wallet_pin(uint8_t subcmd, uint8_t * pinAuth, uint8_t * arg1, uint8_t * a } if ( ctap_device_locked() ) + { + return CTAP2_ERR_NOT_ALLOWED; + } + + if (!ctap_user_presence_test()) { return CTAP2_ERR_OPERATION_DENIED; } + //pinEnc // plat_pubkey // pinHashEnc ret = ctap_update_pin_if_verified( arg2, len, arg1, pinAuth, arg3); if (ret != 0) @@ -128,9 +141,16 @@ int8_t wallet_pin(uint8_t subcmd, uint8_t * pinAuth, uint8_t * arg1, uint8_t * a break; case CP_cmdGetPinToken: + + printf1(TAG_WALLET,"cmdGetPinToken\n"); if ( ctap_device_locked() ) + { + return CTAP2_ERR_NOT_ALLOWED; + } + + if (!ctap_user_presence_test()) { return CTAP2_ERR_OPERATION_DENIED; } @@ -339,6 +359,39 @@ int16_t bridge_u2f_to_wallet(uint8_t * _chal, uint8_t * _appid, uint8_t klen, ui printf1(TAG_WALLET,"WalletPin\n"); ret = wallet_pin(req->p1, req->pinAuth, args[0], args[1], args[2], lens[0]); break; + case WalletReset: + // resets device + printf1(TAG_WALLET,"WalletReset\n"); + + if ( ! ctap_device_locked() ) + { + if ( ctap_is_pin_set() ) + { + if ( ! check_pinhash(req->pinAuth, msg_buf, reqlen)) + { + printf1(TAG_WALLET,"pinAuth is NOT valid\n"); + ret = CTAP2_ERR_PIN_AUTH_INVALID; + goto cleanup; + } + + } + } + + if (ctap_user_presence_test()) + { + ctap_reset(); + } + else + { + ret = CTAP2_ERR_OPERATION_DENIED; + goto cleanup; + } + + + break; + case WalletVersion: + u2f_response_writeback(WALLET_VERSION, sizeof(WALLET_VERSION)); + break; default: printf2(TAG_ERR,"Invalid wallet command: %x\n",req->operation); ret = CTAP1_ERR_INVALID_COMMAND; diff --git a/fido2/wallet.h b/fido2/wallet.h index bc450f9..358a54a 100644 --- a/fido2/wallet.h +++ b/fido2/wallet.h @@ -53,6 +53,10 @@ // Resp: modded U2F auth response // Returns public key OR pinAuth +// Only response to this challenge to prevent interference +#define CHALLENGE_PIN "\xf6\xa2\x3c\xa4\x0a\xf9\xda\xd4\x5f\xdc\xba\x7d\xc9\xde\xcb\xed\xb5\x84\x64\x3a\x4c\x9f\x44\xc2\x04\xb0\x17\xd7\xf4\x3e\xe0\x3f" + +#define WALLET_VERSION "WALLET_V1.0" #define MAX_CHALLENGE_SIZE 233 #define MAX_KEYID_SIZE 232 diff --git a/tools/http2udb.py b/tools/http2udb.py index 915abf2..41ea274 100644 --- a/tools/http2udb.py +++ b/tools/http2udb.py @@ -87,7 +87,7 @@ class UDPBridge(BaseHTTPRequestHandler): print(data) msg = from_websafe(data) msg = base64.b64decode(msg) - chal = b'A'*32 + chal = b"\xf6\xa2\x3c\xa4\x0a\xf9\xda\xd4\x5f\xdc\xba\x7d\xc9\xde\xcb\xed\xb5\x84\x64\x3a\x4c\x9f\x44\xc2\x04\xb0\x17\xd7\xf4\x3e\xe0\x3f" appid = b'A'*32 s = ctap.authenticate(chal,appid,msg,) @@ -110,7 +110,7 @@ class UDPBridge(BaseHTTPRequestHandler): self.end_headers() #msg = {'data': read()} - msg = {'data': 'rest'} + msg = {'data': 'rest'}; self.wfile.write(json.dumps(msg).encode())