fix infrequent der formatting bug. start excludelist
This commit is contained in:
parent
644ceaef63
commit
10e50bea48
83
ctap.c
83
ctap.c
@ -344,6 +344,7 @@ static int ctap_make_auth_data(struct rpId * rp, CborEncoder * map, uint8_t * au
|
||||
// @return length of der signature
|
||||
int ctap_calculate_signature(uint8_t * data, int datalen, uint8_t * clientDataHash, uint8_t * hashbuf, uint8_t * sigbuf, uint8_t * sigder)
|
||||
{
|
||||
int i;
|
||||
// calculate attestation sig
|
||||
crypto_sha256_init();
|
||||
crypto_sha256_update(data, datalen);
|
||||
@ -351,27 +352,38 @@ int ctap_calculate_signature(uint8_t * data, int datalen, uint8_t * clientDataHa
|
||||
crypto_sha256_final(hashbuf);
|
||||
|
||||
printf1(TAG_GREEN, "sha256: "); dump_hex1(TAG_DUMP,hashbuf,32);
|
||||
|
||||
crypto_ecc256_sign(hashbuf, 32, sigbuf);
|
||||
|
||||
|
||||
// Need to caress into dumb der format ..
|
||||
uint8_t pad_s = (sigbuf[32] & 0x80) == 0x80;
|
||||
uint8_t pad_r = (sigbuf[0] & 0x80) == 0x80;
|
||||
int8_t pad_s = ((sigbuf[32 + lead_s] & 0x80) == 0x80); // Is MSBit a 1?
|
||||
int8_t pad_r = ((sigbuf[0 + lead_r] & 0x80) == 0x80);
|
||||
|
||||
int8_t lead_s = 0; // leading zeros
|
||||
int8_t lead_r = 0;
|
||||
for (i=0; i < 32; i++)
|
||||
if (sigbuf[i] == 0) lead_r++;
|
||||
else break;
|
||||
|
||||
for (i=0; i < 32; i++)
|
||||
if (sigbuf[i+32] == 0) lead_s++;
|
||||
else break;
|
||||
|
||||
sigder[0] = 0x30;
|
||||
sigder[1] = 0x44 + pad_s + pad_r;
|
||||
sigder[1] = 0x44 + pad_s + pad_r - lead_s - lead_r;
|
||||
|
||||
sigder[2] = 0x02;
|
||||
sigder[3 + pad_r] = 0;
|
||||
sigder[3] = 0x20 + pad_r;
|
||||
memmove(sigder + 4 + pad_r, sigbuf, 32);
|
||||
sigder[3] = 0x20 + pad_r - lead_r;
|
||||
memmove(sigder + 4 + pad_r, sigbuf + lead_r, 32);
|
||||
|
||||
sigder[4 + 32 + pad_r] = 0x02;
|
||||
sigder[5 + 32 + pad_r + pad_s] = 0;
|
||||
sigder[5 + 32 + pad_r] = 0x20 + pad_s;
|
||||
memmove(sigder + 6 + 32 + pad_r + pad_s, sigbuf + 32, 32);
|
||||
sigder[4 + 32 + pad_r - lead_r] = 0x02;
|
||||
sigder[5 + 32 + pad_r + pad_s - lead_r] = 0;
|
||||
sigder[5 + 32 + pad_r - lead_r] = 0x20 + pad_s - lead_s;
|
||||
memmove(sigder + 6 + 32 + pad_r + pad_s - lead_r, sigbuf + 32 + lead_s, 32);
|
||||
//
|
||||
|
||||
return 0x46 + pad_s + pad_r;
|
||||
return 0x46 + pad_s + pad_r - lead_r - lead_s;
|
||||
}
|
||||
|
||||
uint8_t ctap_add_attest_statement(CborEncoder * map, uint8_t * sigder, int len)
|
||||
@ -415,12 +427,29 @@ uint8_t ctap_add_attest_statement(CborEncoder * map, uint8_t * sigder, int len)
|
||||
check_ret(ret);
|
||||
}
|
||||
|
||||
// Return 1 if credential belongs to this token
|
||||
int ctap_authenticate_credential(struct rpId * rp, CTAP_credentialDescriptor * desc)
|
||||
{
|
||||
uint8_t tag[16];
|
||||
if (desc->type != PUB_KEY_CRED_PUB_KEY)
|
||||
{
|
||||
printf1(TAG_GA,"unsupported credential type: %d\n", desc->type);
|
||||
return 0;
|
||||
}
|
||||
|
||||
make_auth_tag(rp, &desc->credential.fields.user, desc->credential.fields.count, tag);
|
||||
|
||||
return (memcmp(desc->credential.fields.tag, tag, CREDENTIAL_TAG_SIZE) == 0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
uint8_t ctap_make_credential(CborEncoder * encoder, uint8_t * request, int length)
|
||||
{
|
||||
CTAP_makeCredential MC;
|
||||
int ret;
|
||||
int ret, i;
|
||||
uint8_t auth_data_buf[300];
|
||||
CTAP_credentialDescriptor * excl_cred = (CTAP_credentialDescriptor *) auth_data_buf;
|
||||
uint8_t * hashbuf = auth_data_buf + 0;
|
||||
uint8_t * sigbuf = auth_data_buf + 32;
|
||||
uint8_t * sigder = auth_data_buf + 32 + 64;
|
||||
@ -451,6 +480,20 @@ uint8_t ctap_make_credential(CborEncoder * encoder, uint8_t * request, int lengt
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < MC.excludeListSize; i++)
|
||||
{
|
||||
ret = parse_credential_descriptor(&MC.excludeList, excl_cred);
|
||||
check_retr(ret);
|
||||
|
||||
if (ctap_authenticate_credential(&MC.rp, excl_cred))
|
||||
{
|
||||
return CTAP2_ERR_CREDENTIAL_EXCLUDED;
|
||||
}
|
||||
|
||||
ret = cbor_value_advance(&MC.excludeList);
|
||||
check_ret(ret);
|
||||
}
|
||||
|
||||
CborEncoder map;
|
||||
ret = cbor_encoder_create_map(encoder, &map, 3);
|
||||
check_ret(ret);
|
||||
@ -478,22 +521,6 @@ uint8_t ctap_make_credential(CborEncoder * encoder, uint8_t * request, int lengt
|
||||
return CTAP1_ERR_SUCCESS;
|
||||
}
|
||||
|
||||
// Return 1 if credential belongs to this token
|
||||
int ctap_authenticate_credential(struct rpId * rp, CTAP_credentialDescriptor * desc)
|
||||
{
|
||||
uint8_t tag[16];
|
||||
if (desc->type != PUB_KEY_CRED_PUB_KEY)
|
||||
{
|
||||
printf1(TAG_GA,"unsupported credential type: %d\n", desc->type);
|
||||
return 0;
|
||||
}
|
||||
|
||||
make_auth_tag(rp, &desc->credential.fields.user, desc->credential.fields.count, tag);
|
||||
|
||||
return (memcmp(desc->credential.fields.tag, tag, CREDENTIAL_TAG_SIZE) == 0);
|
||||
}
|
||||
|
||||
|
||||
static int pick_first_authentic_credential(CTAP_getAssertion * GA)
|
||||
{
|
||||
int i;
|
||||
|
5
ctap.h
5
ctap.h
@ -1,6 +1,8 @@
|
||||
#ifndef _CTAP_H
|
||||
#define _CTAP_H
|
||||
|
||||
#include "cbor.h"
|
||||
|
||||
#define CTAP_MAKE_CREDENTIAL 0x01
|
||||
#define CTAP_GET_ASSERTION 0x02
|
||||
#define CTAP_CANCEL 0x03
|
||||
@ -162,6 +164,9 @@ typedef struct
|
||||
uint8_t publicKeyCredentialType;
|
||||
int32_t COSEAlgorithmIdentifier;
|
||||
|
||||
CborValue excludeList;
|
||||
int excludeListSize;
|
||||
|
||||
uint8_t rk;
|
||||
uint8_t uv;
|
||||
|
||||
|
@ -10,6 +10,7 @@
|
||||
|
||||
#include "util.h"
|
||||
#include "usbhid.h"
|
||||
#include "log.h"
|
||||
|
||||
|
||||
void ctaphid_write_block(uint8_t * data)
|
||||
@ -34,15 +35,16 @@ uint32_t ctap_atomic_count(int sel)
|
||||
{
|
||||
static uint32_t counter1 = 25;
|
||||
static uint32_t counter2 = 25;
|
||||
/*return 713;*/
|
||||
if (sel == 0)
|
||||
{
|
||||
printf1(TAG_RED,"counter1: %d\n", counter1);
|
||||
return counter1++;
|
||||
}
|
||||
else
|
||||
{
|
||||
return counter2++;
|
||||
}
|
||||
return 44;
|
||||
}
|
||||
|
||||
int ctap_generate_rng(uint8_t * dst, size_t num)
|
||||
@ -55,6 +57,9 @@ int ctap_generate_rng(uint8_t * dst, size_t num)
|
||||
}
|
||||
fread(dst, 1, num, urand);
|
||||
fclose(urand);
|
||||
|
||||
/*memset(dst,0xaa,num);*/
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
123
ctap_parse.c
123
ctap_parse.c
@ -556,6 +556,18 @@ uint8_t ctap_parse_make_credential(CTAP_makeCredential * MC, CborEncoder * encod
|
||||
break;
|
||||
case MC_excludeList:
|
||||
printf1(TAG_MC,"CTAP_excludeList\n");
|
||||
if( cbor_value_get_type(&map) == CborArrayType )
|
||||
{
|
||||
ret = cbor_value_enter_container(&map, &MC->excludeList);
|
||||
check_ret(ret);
|
||||
ret = cbor_value_get_int_checked(&map, &MC->excludeListSize);
|
||||
check_ret(ret);
|
||||
}
|
||||
else
|
||||
{
|
||||
return CTAP2_ERR_INVALID_CBOR_TYPE;
|
||||
}
|
||||
|
||||
break;
|
||||
case MC_extensions:
|
||||
printf1(TAG_MC,"CTAP_extensions\n");
|
||||
@ -604,12 +616,68 @@ uint8_t ctap_parse_make_credential(CTAP_makeCredential * MC, CborEncoder * encod
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t parse_credential_descriptor(CborValue * arr, CTAP_credentialDescriptor * cred)
|
||||
{
|
||||
int ret;
|
||||
size_t buflen;
|
||||
uint8_t type[12];
|
||||
CborValue val;
|
||||
if (cbor_value_get_type(arr) != CborMapType)
|
||||
{
|
||||
printf2(TAG_ERR,"Error, CborMapType expected in allow_list\n");
|
||||
return CTAP2_ERR_INVALID_CBOR_TYPE;
|
||||
}
|
||||
|
||||
ret = cbor_value_map_find_value(arr, "id", &val);
|
||||
check_ret(ret);
|
||||
|
||||
if (cbor_value_get_type(&val) != CborByteStringType)
|
||||
{
|
||||
printf2(TAG_ERR,"Error, No valid ID field (%s)\n", cbor_value_get_type_string(&val));
|
||||
return CTAP2_ERR_MISSING_PARAMETER;
|
||||
}
|
||||
|
||||
buflen = CREDENTIAL_ID_SIZE;
|
||||
cbor_value_copy_byte_string(&val, cred->credential.id, &buflen, NULL);
|
||||
if (buflen != CREDENTIAL_ID_SIZE)
|
||||
{
|
||||
printf2(TAG_ERR,"Error, credential is incorrect length\n");
|
||||
return CTAP2_ERR_CBOR_UNEXPECTED_TYPE; // maybe just skip it instead of fail?
|
||||
}
|
||||
|
||||
ret = cbor_value_map_find_value(arr, "type", &val);
|
||||
check_ret(ret);
|
||||
|
||||
if (cbor_value_get_type(&val) != CborTextStringType)
|
||||
{
|
||||
printf2(TAG_ERR,"Error, No valid type field\n");
|
||||
return CTAP2_ERR_MISSING_PARAMETER;
|
||||
}
|
||||
|
||||
buflen = sizeof(type);
|
||||
cbor_value_copy_text_string(&val, type, &buflen, NULL);
|
||||
|
||||
if (strcmp(type, "public-key") == 0)
|
||||
{
|
||||
cred->type = PUB_KEY_CRED_PUB_KEY;
|
||||
}
|
||||
else
|
||||
{
|
||||
cred->type = PUB_KEY_CRED_UNKNOWN;
|
||||
}
|
||||
|
||||
ret = cbor_value_advance(arr);
|
||||
check_ret(ret);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t parse_allow_list(CTAP_getAssertion * GA, CborValue * it)
|
||||
{
|
||||
CborValue arr, val;
|
||||
size_t len,buflen;
|
||||
uint8_t type[12];
|
||||
CborValue arr;
|
||||
size_t len;
|
||||
int i,ret;
|
||||
CTAP_credentialDescriptor * cred;
|
||||
|
||||
if (cbor_value_get_type(it) != CborArrayType)
|
||||
{
|
||||
@ -634,53 +702,10 @@ uint8_t parse_allow_list(CTAP_getAssertion * GA, CborValue * it)
|
||||
}
|
||||
|
||||
GA->credLen += 1;
|
||||
cred = &GA->creds[i];
|
||||
|
||||
if (cbor_value_get_type(&arr) != CborMapType)
|
||||
{
|
||||
printf2(TAG_ERR,"Error, CborMapType expected in allow_list\n");
|
||||
return CTAP2_ERR_INVALID_CBOR_TYPE;
|
||||
}
|
||||
|
||||
ret = cbor_value_map_find_value(&arr, "id", &val);
|
||||
check_ret(ret);
|
||||
|
||||
if (cbor_value_get_type(&val) != CborByteStringType)
|
||||
{
|
||||
printf2(TAG_ERR,"Error, No valid ID field (%s)\n", cbor_value_get_type_string(&val));
|
||||
return CTAP2_ERR_MISSING_PARAMETER;
|
||||
}
|
||||
|
||||
buflen = CREDENTIAL_ID_SIZE;
|
||||
cbor_value_copy_byte_string(&val, GA->creds[i].credential.id, &buflen, NULL);
|
||||
if (buflen != CREDENTIAL_ID_SIZE)
|
||||
{
|
||||
printf2(TAG_ERR,"Error, credential is incorrect length\n");
|
||||
return CTAP2_ERR_CBOR_UNEXPECTED_TYPE; // maybe just skip it instead of fail?
|
||||
}
|
||||
|
||||
ret = cbor_value_map_find_value(&arr, "type", &val);
|
||||
check_ret(ret);
|
||||
|
||||
if (cbor_value_get_type(&val) != CborTextStringType)
|
||||
{
|
||||
printf2(TAG_ERR,"Error, No valid type field\n");
|
||||
return CTAP2_ERR_MISSING_PARAMETER;
|
||||
}
|
||||
|
||||
buflen = sizeof(type);
|
||||
cbor_value_copy_text_string(&val, type, &buflen, NULL);
|
||||
|
||||
if (strcmp(type, "public-key") == 0)
|
||||
{
|
||||
GA->creds[i].type = PUB_KEY_CRED_PUB_KEY;
|
||||
}
|
||||
else
|
||||
{
|
||||
GA->creds[i].type = PUB_KEY_CRED_UNKNOWN;
|
||||
}
|
||||
|
||||
ret = cbor_value_advance(&arr);
|
||||
check_ret(ret);
|
||||
ret = parse_credential_descriptor(&arr,cred);
|
||||
check_retr(ret);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -30,6 +30,7 @@ uint8_t parse_cose_key(CborValue * it, uint8_t * x, uint8_t * y, int * kty, int
|
||||
uint8_t ctap_parse_make_credential(CTAP_makeCredential * MC, CborEncoder * encoder, uint8_t * request, int length);
|
||||
uint8_t ctap_parse_get_assertion(CTAP_getAssertion * GA, uint8_t * request, int length);
|
||||
uint8_t ctap_parse_client_pin(CTAP_clientPin * CP, uint8_t * request, int length);
|
||||
uint8_t parse_credential_descriptor(CborValue * arr, CTAP_credentialDescriptor * cred);
|
||||
|
||||
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user