encrypt credential with aes for start
This commit is contained in:
parent
2b482f0c43
commit
52cc61a575
97
crypto.c
97
crypto.c
@ -28,10 +28,14 @@ static SHA256_CTX sha256_ctx;
|
||||
static const struct uECC_Curve_t * _es256_curve = NULL;
|
||||
static const uint8_t * _signing_key = NULL;
|
||||
|
||||
// Secret for testing only
|
||||
// Secrets for testing only
|
||||
static uint8_t master_secret[32] = "\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xaa\xbb\xcc\xdd\xee\xff"
|
||||
"\xff\xee\xdd\xcc\xbb\xaa\x99\x88\x77\x66\x55\x44\x33\x22\x11\x00";
|
||||
|
||||
static uint8_t transport_secret[32] = "\x10\x01\x22\x33\x44\x55\x66\x77\x87\x90\x0a\xbb\x3c\xd8\xee\xff"
|
||||
"\xff\xee\x8d\x1c\x3b\xfa\x99\x88\x77\x86\x55\x44\xd3\xff\x33\x00";
|
||||
|
||||
|
||||
|
||||
void crypto_sha256_init()
|
||||
{
|
||||
@ -65,6 +69,12 @@ void crypto_sha256_hmac_init(uint8_t * key, uint32_t klen, uint8_t * hmac)
|
||||
int i;
|
||||
memset(buf, 0, sizeof(buf));
|
||||
|
||||
if (key == CRYPTO_MASTER_KEY)
|
||||
{
|
||||
key = master_secret;
|
||||
klen = sizeof(master_secret);
|
||||
}
|
||||
|
||||
if(klen > 64)
|
||||
{
|
||||
printf("Error, key size must be <= 64\n");
|
||||
@ -88,6 +98,12 @@ void crypto_sha256_hmac_final(uint8_t * key, uint32_t klen, uint8_t * hmac)
|
||||
int i;
|
||||
crypto_sha256_final(hmac);
|
||||
memset(buf, 0, sizeof(buf));
|
||||
if (key == CRYPTO_MASTER_KEY)
|
||||
{
|
||||
key = master_secret;
|
||||
klen = sizeof(master_secret);
|
||||
}
|
||||
|
||||
|
||||
if(klen > 64)
|
||||
{
|
||||
@ -107,44 +123,6 @@ void crypto_sha256_hmac_final(uint8_t * key, uint32_t klen, uint8_t * hmac)
|
||||
crypto_sha256_final(hmac);
|
||||
}
|
||||
|
||||
/*void crypto_sha256_hmac(uint8_t * key, uint32_t klen, uint8_t * data, uint32_t datalen, uint8_t * hmac)*/
|
||||
/*{*/
|
||||
/*uint8_t buf[64];*/
|
||||
/*int i;*/
|
||||
/*memset(buf, 0, sizeof(buf));*/
|
||||
|
||||
/*if(klen > 64)*/
|
||||
/*{*/
|
||||
/*printf("Error, key size must be <= 64\n");*/
|
||||
/*exit(1);*/
|
||||
/*}*/
|
||||
|
||||
/*memmove(buf, key, klen);*/
|
||||
|
||||
/*for (i = 0; i < sizeof(buf); i++)*/
|
||||
/*{*/
|
||||
/*buf[i] = buf[i] ^ 0x36;*/
|
||||
/*}*/
|
||||
|
||||
/*crypto_sha256_init();*/
|
||||
/*crypto_sha256_update(buf, 64);*/
|
||||
/*crypto_sha256_update(data, datalen);*/
|
||||
/*crypto_sha256_final(hmac);*/
|
||||
|
||||
/*memset(buf, 0, sizeof(buf));*/
|
||||
/*memmove(buf, key, klen);*/
|
||||
|
||||
/*for (i = 0; i < sizeof(buf); i++)*/
|
||||
/*{*/
|
||||
/*buf[i] = buf[i] ^ 0x5c;*/
|
||||
/*}*/
|
||||
|
||||
/*crypto_sha256_init();*/
|
||||
/*crypto_sha256_update(buf, 64);*/
|
||||
/*crypto_sha256_update(hmac, 32);*/
|
||||
/*crypto_sha256_final(hmac);*/
|
||||
/*}*/
|
||||
|
||||
|
||||
void crypto_ecc256_init()
|
||||
{
|
||||
@ -169,12 +147,11 @@ void crypto_ecc256_sign(uint8_t * data, int len, uint8_t * sig)
|
||||
|
||||
void generate_private_key(uint8_t * data, int len, uint8_t * data2, int len2, uint8_t * privkey)
|
||||
{
|
||||
// poor man's hmac
|
||||
crypto_sha256_init();
|
||||
crypto_sha256_hmac_init(CRYPTO_MASTER_KEY, 0, privkey);
|
||||
crypto_sha256_update(data, len);
|
||||
crypto_sha256_update(data2, len2);
|
||||
crypto_sha256_update(master_secret, 32);
|
||||
crypto_sha256_final(privkey);
|
||||
crypto_sha256_hmac_final(CRYPTO_MASTER_KEY, 0, privkey);
|
||||
}
|
||||
|
||||
|
||||
@ -192,10 +169,10 @@ void crypto_ecc256_derive_public_key(uint8_t * data, int len, uint8_t * x, uint8
|
||||
memmove(y,pubkey+32,32);
|
||||
}
|
||||
|
||||
void crypto_ecc256_load_key(uint8_t * data, int len)
|
||||
void crypto_ecc256_load_key(uint8_t * data, int len, uint8_t * data2, int len2)
|
||||
{
|
||||
static uint8_t privkey[32];
|
||||
generate_private_key(data,len,NULL,0,privkey);
|
||||
generate_private_key(data,len,data2,len2,privkey);
|
||||
_signing_key = privkey;
|
||||
}
|
||||
|
||||
@ -218,17 +195,39 @@ void crypto_ecc256_shared_secret(const uint8_t * pubkey, const uint8_t * privkey
|
||||
|
||||
}
|
||||
|
||||
static struct AES_ctx aes_ctx;
|
||||
void crypto_aes256_init(uint8_t * key)
|
||||
struct AES_ctx aes_ctx;
|
||||
void crypto_aes256_init(uint8_t * key, uint8_t * nonce)
|
||||
{
|
||||
if (key == CRYPTO_TRANSPORT_KEY)
|
||||
{
|
||||
AES_init_ctx(&aes_ctx, transport_secret);
|
||||
}
|
||||
else
|
||||
{
|
||||
AES_init_ctx(&aes_ctx, key);
|
||||
memset(aes_ctx.Iv, 0, 16);
|
||||
}
|
||||
|
||||
void crypto_aes256_reset_iv()
|
||||
if (nonce == NULL)
|
||||
{
|
||||
memset(aes_ctx.Iv, 0, 16);
|
||||
}
|
||||
else
|
||||
{
|
||||
memmove(aes_ctx.Iv, nonce, 16);
|
||||
}
|
||||
}
|
||||
|
||||
// prevent round key recomputation
|
||||
void crypto_aes256_reset_iv(uint8_t * nonce)
|
||||
{
|
||||
if (nonce == NULL)
|
||||
{
|
||||
memset(aes_ctx.Iv, 0, 16);
|
||||
}
|
||||
else
|
||||
{
|
||||
memmove(aes_ctx.Iv, nonce, 16);
|
||||
}
|
||||
}
|
||||
|
||||
void crypto_aes256_decrypt(uint8_t * buf, int length)
|
||||
{
|
||||
|
99
ctap.c
99
ctap.c
@ -242,13 +242,12 @@ static int ctap_generate_cose_key(CborEncoder * cose_key, uint8_t * hmac_input,
|
||||
void make_auth_tag(struct rpId * rp, CTAP_userEntity * user, uint32_t count, uint8_t * tag)
|
||||
{
|
||||
uint8_t hashbuf[32];
|
||||
crypto_sha256_init();
|
||||
crypto_sha256_hmac_init(NULL, 0, hashbuf);
|
||||
crypto_sha256_update(rp->id, rp->size);
|
||||
crypto_sha256_update(user->id, user->id_size);
|
||||
crypto_sha256_update(user->name, strnlen(user->name, USER_NAME_LIMIT));
|
||||
crypto_sha256_update((uint8_t*)&count, 4);
|
||||
crypto_sha256_update_secret();
|
||||
crypto_sha256_final(hashbuf);
|
||||
crypto_sha256_hmac_final(NULL,0,hashbuf);
|
||||
|
||||
memmove(tag, hashbuf, CREDENTIAL_TAG_SIZE);
|
||||
}
|
||||
@ -300,19 +299,21 @@ static int ctap_make_auth_data(struct rpId * rp, CborEncoder * map, uint8_t * au
|
||||
authData->attest.credLenL = CREDENTIAL_ID_SIZE & 0x00FF;
|
||||
authData->attest.credLenH = (CREDENTIAL_ID_SIZE & 0xFF00) >> 8;
|
||||
|
||||
#if CREDENTIAL_ID_SIZE != 150
|
||||
#if CREDENTIAL_ID_SIZE != 168
|
||||
#error "need to double check credential ID layout"
|
||||
#else
|
||||
memset(authData->attest.credential.id, 0, CREDENTIAL_ID_SIZE);
|
||||
memset((uint8_t*)&authData->attest.credential, 0, sizeof(struct Credential));
|
||||
|
||||
// Make a tag we can later check to make sure this is a token we made
|
||||
make_auth_tag(rp, user, count, authData->attest.credential.fields.tag);
|
||||
make_auth_tag(rp, user, count, authData->attest.credential.tag);
|
||||
|
||||
memmove(&authData->attest.credential.fields.user, user, sizeof(CTAP_userEntity)); //TODO encrypt this
|
||||
memmove(&authData->attest.credential.enc.user, user, sizeof(CTAP_userEntity)); //TODO encrypt this
|
||||
authData->attest.credential.enc.count = count;
|
||||
|
||||
authData->attest.credential.fields.count = count;
|
||||
crypto_aes256_init(CRYPTO_TRANSPORT_KEY, NULL);
|
||||
crypto_aes256_encrypt((uint8_t*)&authData->attest.credential.enc, CREDENTIAL_ENC_SIZE);
|
||||
|
||||
ctap_generate_cose_key(&cose_key, authData->attest.credential.id, CREDENTIAL_ID_SIZE, credtype, algtype);
|
||||
ctap_generate_cose_key(&cose_key, (uint8_t*)&authData->attest.credential, sizeof(struct Credential), credtype, algtype);
|
||||
|
||||
printf1(TAG_MC,"COSE_KEY: "); dump_hex1(TAG_MC, cose_key_buf, cbor_encoder_get_buffer_size(&cose_key, cose_key_buf));
|
||||
|
||||
@ -436,9 +437,9 @@ int ctap_authenticate_credential(struct rpId * rp, CTAP_credentialDescriptor * d
|
||||
return 0;
|
||||
}
|
||||
|
||||
make_auth_tag(rp, &desc->credential.fields.user, desc->credential.fields.count, tag);
|
||||
make_auth_tag(rp, &desc->credential.enc.user, desc->credential.enc.count, tag);
|
||||
|
||||
return (memcmp(desc->credential.fields.tag, tag, CREDENTIAL_TAG_SIZE) == 0);
|
||||
return (memcmp(desc->credential.tag, tag, CREDENTIAL_TAG_SIZE) == 0);
|
||||
}
|
||||
|
||||
|
||||
@ -529,7 +530,7 @@ static int pick_first_authentic_credential(CTAP_getAssertion * GA)
|
||||
int i;
|
||||
for (i = 0; i < GA->credLen; i++)
|
||||
{
|
||||
if (GA->creds[i].credential.fields.count != 0)
|
||||
if (GA->creds[i].credential.enc.count != 0)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
@ -557,7 +558,7 @@ static uint8_t ctap_add_credential_descriptor(CborEncoder * map, CTAP_credential
|
||||
ret = cbor_encode_text_string(&desc, "id", 2);
|
||||
check_ret(ret);
|
||||
|
||||
ret = cbor_encode_byte_string(&desc, cred->credential.id, CREDENTIAL_ID_SIZE);
|
||||
ret = cbor_encode_byte_string(&desc, (uint8_t*)&cred->credential, sizeof(struct Credential));
|
||||
check_ret(ret);
|
||||
}
|
||||
|
||||
@ -603,7 +604,7 @@ static int cred_cmp_func(const void * _a, const void * _b)
|
||||
{
|
||||
CTAP_credentialDescriptor * a = (CTAP_credentialDescriptor * )_a;
|
||||
CTAP_credentialDescriptor * b = (CTAP_credentialDescriptor * )_b;
|
||||
return b->credential.fields.count - a->credential.fields.count;
|
||||
return b->credential.enc.count - a->credential.enc.count;
|
||||
}
|
||||
|
||||
// @return the number of valid credentials
|
||||
@ -612,19 +613,24 @@ int ctap_filter_invalid_credentials(CTAP_getAssertion * GA)
|
||||
{
|
||||
int i;
|
||||
int count = 0;
|
||||
crypto_aes256_init(CRYPTO_TRANSPORT_KEY, NULL);
|
||||
|
||||
|
||||
for (i = 0; i < GA->credLen; i++)
|
||||
{
|
||||
crypto_aes256_reset_iv(NULL);
|
||||
crypto_aes256_decrypt((uint8_t*)&GA->creds[i].credential.enc, CREDENTIAL_ENC_SIZE);
|
||||
if (! ctap_authenticate_credential(&GA->rp, &GA->creds[i]))
|
||||
{
|
||||
printf1(TAG_GA, "CRED #%d is invalid\n", GA->creds[i].credential.fields.count);
|
||||
GA->creds[i].credential.fields.count = 0; // invalidate
|
||||
printf1(TAG_GA, "CRED #%d is invalid\n", GA->creds[i].credential.enc.count);
|
||||
GA->creds[i].credential.enc.count = 0; // invalidate
|
||||
}
|
||||
else
|
||||
{
|
||||
count++;
|
||||
}
|
||||
}
|
||||
printf("qsort length: %d\n", GA->credLen);
|
||||
printf1(TAG_GA, "qsort length: %d\n", GA->credLen);
|
||||
qsort(GA->creds, GA->credLen, sizeof(CTAP_credentialDescriptor), cred_cmp_func);
|
||||
return count;
|
||||
}
|
||||
@ -634,6 +640,11 @@ static void save_credential_list(CTAP_authDataHeader * head, uint8_t * clientDat
|
||||
{
|
||||
if(count)
|
||||
{
|
||||
if (count > ALLOW_LIST_MAX_SIZE-1)
|
||||
{
|
||||
printf2(TAG_ERR, "ALLOW_LIST_MAX_SIZE Exceeded\n");
|
||||
exit(1);
|
||||
}
|
||||
memmove(getAssertionState.clientDataHash, clientDataHash, CLIENT_DATA_HASH_SIZE);
|
||||
memmove(&getAssertionState.authData, head, sizeof(CTAP_authDataHeader));
|
||||
memmove(getAssertionState.creds, creds, sizeof(CTAP_credentialDescriptor) * (count));
|
||||
@ -661,18 +672,22 @@ uint8_t ctap_end_get_assertion(CborEncoder * map, CTAP_credentialDescriptor * cr
|
||||
uint8_t sigbuf[64];
|
||||
uint8_t sigder[72];
|
||||
|
||||
ret = ctap_add_user_entity(map, &cred->credential.enc.user);
|
||||
check_retr(ret);
|
||||
|
||||
// Re-encrypt the credential
|
||||
crypto_aes256_init(CRYPTO_TRANSPORT_KEY, NULL);
|
||||
crypto_aes256_encrypt((uint8_t*)&cred->credential.enc, CREDENTIAL_ENC_SIZE);
|
||||
//
|
||||
|
||||
ret = ctap_add_credential_descriptor(map, cred);
|
||||
check_retr(ret);
|
||||
|
||||
ret = ctap_add_user_entity(map, &cred->credential.fields.user);
|
||||
check_retr(ret);
|
||||
crypto_ecc256_load_key((uint8_t*)&cred->credential, sizeof(struct Credential), NULL, 0);
|
||||
|
||||
crypto_ecc256_load_key(cred->credential.id, CREDENTIAL_ID_SIZE);
|
||||
|
||||
printf1(TAG_GREEN,"auth_data_buf: "); dump_hex1(TAG_DUMP, auth_data_buf, sizeof(CTAP_authDataHeader));
|
||||
printf1(TAG_GREEN,"clientdatahash: "); dump_hex1(TAG_DUMP, clientDataHash, 32);
|
||||
printf1(TAG_GREEN,"credential: # %d\n", cred->credential.fields.count);
|
||||
/*printf1(TAG_GREEN,"auth_data_buf: "); dump_hex1(TAG_DUMP, auth_data_buf, sizeof(CTAP_authDataHeader));*/
|
||||
/*printf1(TAG_GREEN,"clientdatahash: "); dump_hex1(TAG_DUMP, clientDataHash, 32);*/
|
||||
/*printf1(TAG_GREEN,"credential: # %d\n", cred->credential.enc.count);*/
|
||||
/*dump_hex1(TAG_DUMP, clientDataHash, 32);*/
|
||||
|
||||
int sigder_sz = ctap_calculate_signature(auth_data_buf, sizeof(CTAP_authDataHeader), clientDataHash, auth_data_buf, sigbuf, sigder);
|
||||
@ -755,19 +770,19 @@ uint8_t ctap_get_assertion(CborEncoder * encoder, uint8_t * request, int length)
|
||||
ctap_make_auth_data(&GA.rp, &map, auth_data_buf, sizeof(auth_data_buf), NULL, 0,0);
|
||||
|
||||
printf1(TAG_GA, "ALLOW_LIST has %d creds\n", GA.credLen);
|
||||
for (int j = 0; j < GA.credLen; j++)
|
||||
{
|
||||
printf1(TAG_GA,"CRED ID (# %d): ", GA.creds[j].credential.fields.count);
|
||||
dump_hex1(TAG_GA, GA.creds[j].credential.id, CREDENTIAL_ID_SIZE);
|
||||
if (ctap_authenticate_credential(&GA.rp, &GA.creds[j])) // warning encryption will break this
|
||||
{
|
||||
printf1(TAG_GA," Authenticated.\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
printf1(TAG_GA," NOT authentic.\n");
|
||||
}
|
||||
}
|
||||
/*for (int j = 0; j < GA.credLen; j++)*/
|
||||
/*{*/
|
||||
/*printf1(TAG_GA,"CRED ID (# %d): ", GA.creds[j].credential.enc.count);*/
|
||||
/*dump_hex1(TAG_GA, (uint8_t*)&GA.creds[j].credential, sizeof(struct Credential));*/
|
||||
/*if (ctap_authenticate_credential(&GA.rp, &GA.creds[j])) // warning encryption will break this*/
|
||||
/*{*/
|
||||
/*printf1(TAG_GA," Authenticated.\n");*/
|
||||
/*}*/
|
||||
/*else*/
|
||||
/*{*/
|
||||
/*printf1(TAG_GA," NOT authentic.\n");*/
|
||||
/*}*/
|
||||
/*}*/
|
||||
|
||||
// Decrypt here
|
||||
|
||||
@ -786,7 +801,7 @@ uint8_t ctap_get_assertion(CborEncoder * encoder, uint8_t * request, int length)
|
||||
printf1(TAG_RED,"resulting order of creds:\n");
|
||||
for (int j = 0; j < GA.credLen; j++)
|
||||
{
|
||||
printf1(TAG_RED,"CRED ID (# %d)\n", GA.creds[j].credential.fields.count);
|
||||
printf1(TAG_RED,"CRED ID (# %d)\n", GA.creds[j].credential.enc.count);
|
||||
}
|
||||
|
||||
{
|
||||
@ -839,7 +854,7 @@ uint8_t ctap_update_pin_if_verified(uint8_t * pinEnc, int len, uint8_t * platfor
|
||||
return CTAP2_ERR_PIN_AUTH_INVALID;
|
||||
}
|
||||
|
||||
crypto_aes256_init(shared_secret);
|
||||
crypto_aes256_init(shared_secret, NULL);
|
||||
|
||||
while((len & 0xf) != 0) // round up to nearest AES block size multiple
|
||||
{
|
||||
@ -864,7 +879,7 @@ uint8_t ctap_update_pin_if_verified(uint8_t * pinEnc, int len, uint8_t * platfor
|
||||
|
||||
if (ctap_is_pin_set())
|
||||
{
|
||||
crypto_aes256_reset_iv();
|
||||
crypto_aes256_reset_iv(NULL);
|
||||
crypto_aes256_decrypt(pinHashEnc, 16);
|
||||
if (memcmp(pinHashEnc, PIN_CODE_HASH, 16) != 0)
|
||||
{
|
||||
@ -894,7 +909,7 @@ uint8_t ctap_add_pin_if_verified(CborEncoder * map, uint8_t * platform_pubkey, u
|
||||
crypto_sha256_update(shared_secret, 32);
|
||||
crypto_sha256_final(shared_secret);
|
||||
|
||||
crypto_aes256_init(shared_secret);
|
||||
crypto_aes256_init(shared_secret, NULL);
|
||||
|
||||
crypto_aes256_decrypt(pinHashEnc, 16);
|
||||
|
||||
@ -911,7 +926,7 @@ uint8_t ctap_add_pin_if_verified(CborEncoder * map, uint8_t * platform_pubkey, u
|
||||
}
|
||||
|
||||
ctap_reset_pin_attempts();
|
||||
crypto_aes256_reset_iv();
|
||||
crypto_aes256_reset_iv(NULL);
|
||||
|
||||
// reuse share_secret memory for encrypted pinToken
|
||||
memmove(shared_secret, PIN_TOKEN, PIN_TOKEN_SIZE);
|
||||
|
20
ctap.h
20
ctap.h
@ -91,8 +91,11 @@
|
||||
#define CTAP_MAX_MESSAGE_SIZE 1024
|
||||
|
||||
#define CREDENTIAL_TAG_SIZE 16
|
||||
#define CREDENTIAL_NONCE_SIZE 8
|
||||
#define CREDENTIAL_COUNTER_SIZE (4)
|
||||
#define CREDENTIAL_ID_SIZE (CREDENTIAL_TAG_SIZE + USER_ID_MAX_SIZE + USER_NAME_LIMIT + CREDENTIAL_COUNTER_SIZE + 1)
|
||||
#define CREDENTIAL_ENC_SIZE 144 // pad to multiple of 16 bytes
|
||||
#define CREDENTIAL_PAD_SIZE (CREDENTIAL_ENC_SIZE - (USER_ID_MAX_SIZE + USER_NAME_LIMIT + CREDENTIAL_COUNTER_SIZE + 1))
|
||||
#define CREDENTIAL_ID_SIZE (CREDENTIAL_TAG_SIZE + CREDENTIAL_NONCE_SIZE + CREDENTIAL_ENC_SIZE)
|
||||
|
||||
#define PUB_KEY_CRED_PUB_KEY 0x01
|
||||
#define PUB_KEY_CRED_UNKNOWN 0x3F
|
||||
@ -109,15 +112,16 @@ typedef struct
|
||||
uint8_t id[USER_ID_MAX_SIZE];
|
||||
uint8_t id_size;
|
||||
uint8_t name[USER_NAME_LIMIT];
|
||||
} CTAP_userEntity;
|
||||
}__attribute__((packed)) CTAP_userEntity;
|
||||
|
||||
union _credential {
|
||||
struct {
|
||||
struct Credential {
|
||||
uint8_t tag[CREDENTIAL_TAG_SIZE];
|
||||
uint8_t nonce[CREDENTIAL_NONCE_SIZE];
|
||||
struct {
|
||||
CTAP_userEntity user;
|
||||
uint32_t count;
|
||||
}__attribute__((packed)) fields;
|
||||
uint8_t id[CREDENTIAL_ID_SIZE];
|
||||
uint8_t _pad[CREDENTIAL_PAD_SIZE];
|
||||
} __attribute__((packed)) enc;
|
||||
};
|
||||
|
||||
typedef struct
|
||||
@ -125,7 +129,7 @@ typedef struct
|
||||
uint8_t aaguid[16];
|
||||
uint8_t credLenH;
|
||||
uint8_t credLenL;
|
||||
union _credential credential;
|
||||
struct Credential credential;
|
||||
} __attribute__((packed)) CTAP_attestHeader;
|
||||
|
||||
typedef struct
|
||||
@ -179,7 +183,7 @@ typedef struct
|
||||
typedef struct
|
||||
{
|
||||
uint8_t type;
|
||||
union _credential credential;
|
||||
struct Credential credential;
|
||||
} CTAP_credentialDescriptor;
|
||||
|
||||
typedef struct
|
||||
|
@ -637,8 +637,8 @@ uint8_t parse_credential_descriptor(CborValue * arr, CTAP_credentialDescriptor *
|
||||
return CTAP2_ERR_MISSING_PARAMETER;
|
||||
}
|
||||
|
||||
buflen = CREDENTIAL_ID_SIZE;
|
||||
cbor_value_copy_byte_string(&val, cred->credential.id, &buflen, NULL);
|
||||
buflen = sizeof(struct Credential);
|
||||
cbor_value_copy_byte_string(&val, (uint8_t*)&cred->credential, &buflen, NULL);
|
||||
if (buflen != CREDENTIAL_ID_SIZE)
|
||||
{
|
||||
printf2(TAG_ERR,"Error, credential is incorrect length\n");
|
||||
|
Loading…
x
Reference in New Issue
Block a user