encrypt credential with aes for start

This commit is contained in:
Conor Patrick 2018-05-26 11:36:34 -04:00
parent 2b482f0c43
commit 52cc61a575
4 changed files with 120 additions and 102 deletions

View File

@ -28,10 +28,14 @@ static SHA256_CTX sha256_ctx;
static const struct uECC_Curve_t * _es256_curve = NULL; static const struct uECC_Curve_t * _es256_curve = NULL;
static const uint8_t * _signing_key = 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" 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"; "\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() void crypto_sha256_init()
{ {
@ -65,6 +69,12 @@ void crypto_sha256_hmac_init(uint8_t * key, uint32_t klen, uint8_t * hmac)
int i; int i;
memset(buf, 0, sizeof(buf)); memset(buf, 0, sizeof(buf));
if (key == CRYPTO_MASTER_KEY)
{
key = master_secret;
klen = sizeof(master_secret);
}
if(klen > 64) if(klen > 64)
{ {
printf("Error, key size must be <= 64\n"); 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; int i;
crypto_sha256_final(hmac); crypto_sha256_final(hmac);
memset(buf, 0, sizeof(buf)); memset(buf, 0, sizeof(buf));
if (key == CRYPTO_MASTER_KEY)
{
key = master_secret;
klen = sizeof(master_secret);
}
if(klen > 64) 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); 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() 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) void generate_private_key(uint8_t * data, int len, uint8_t * data2, int len2, uint8_t * privkey)
{ {
// poor man's hmac crypto_sha256_hmac_init(CRYPTO_MASTER_KEY, 0, privkey);
crypto_sha256_init();
crypto_sha256_update(data, len); crypto_sha256_update(data, len);
crypto_sha256_update(data2, len2); crypto_sha256_update(data2, len2);
crypto_sha256_update(master_secret, 32); 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); 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]; static uint8_t privkey[32];
generate_private_key(data,len,NULL,0,privkey); generate_private_key(data,len,data2,len2,privkey);
_signing_key = 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; struct AES_ctx aes_ctx;
void crypto_aes256_init(uint8_t * key) 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); AES_init_ctx(&aes_ctx, key);
memset(aes_ctx.Iv, 0, 16);
} }
if (nonce == NULL)
void crypto_aes256_reset_iv()
{ {
memset(aes_ctx.Iv, 0, 16); 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) void crypto_aes256_decrypt(uint8_t * buf, int length)
{ {

99
ctap.c
View File

@ -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) void make_auth_tag(struct rpId * rp, CTAP_userEntity * user, uint32_t count, uint8_t * tag)
{ {
uint8_t hashbuf[32]; uint8_t hashbuf[32];
crypto_sha256_init(); crypto_sha256_hmac_init(NULL, 0, hashbuf);
crypto_sha256_update(rp->id, rp->size); crypto_sha256_update(rp->id, rp->size);
crypto_sha256_update(user->id, user->id_size); crypto_sha256_update(user->id, user->id_size);
crypto_sha256_update(user->name, strnlen(user->name, USER_NAME_LIMIT)); crypto_sha256_update(user->name, strnlen(user->name, USER_NAME_LIMIT));
crypto_sha256_update((uint8_t*)&count, 4); crypto_sha256_update((uint8_t*)&count, 4);
crypto_sha256_update_secret(); crypto_sha256_hmac_final(NULL,0,hashbuf);
crypto_sha256_final(hashbuf);
memmove(tag, hashbuf, CREDENTIAL_TAG_SIZE); 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.credLenL = CREDENTIAL_ID_SIZE & 0x00FF;
authData->attest.credLenH = (CREDENTIAL_ID_SIZE & 0xFF00) >> 8; 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" #error "need to double check credential ID layout"
#else #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 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)); 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; 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; int i;
for (i = 0; i < GA->credLen; 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; 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); ret = cbor_encode_text_string(&desc, "id", 2);
check_ret(ret); 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); 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 * a = (CTAP_credentialDescriptor * )_a;
CTAP_credentialDescriptor * b = (CTAP_credentialDescriptor * )_b; 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 // @return the number of valid credentials
@ -612,19 +613,24 @@ int ctap_filter_invalid_credentials(CTAP_getAssertion * GA)
{ {
int i; int i;
int count = 0; int count = 0;
crypto_aes256_init(CRYPTO_TRANSPORT_KEY, NULL);
for (i = 0; i < GA->credLen; i++) 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])) if (! ctap_authenticate_credential(&GA->rp, &GA->creds[i]))
{ {
printf1(TAG_GA, "CRED #%d is invalid\n", GA->creds[i].credential.fields.count); printf1(TAG_GA, "CRED #%d is invalid\n", GA->creds[i].credential.enc.count);
GA->creds[i].credential.fields.count = 0; // invalidate GA->creds[i].credential.enc.count = 0; // invalidate
} }
else else
{ {
count++; 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); qsort(GA->creds, GA->credLen, sizeof(CTAP_credentialDescriptor), cred_cmp_func);
return count; return count;
} }
@ -634,6 +640,11 @@ static void save_credential_list(CTAP_authDataHeader * head, uint8_t * clientDat
{ {
if(count) 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.clientDataHash, clientDataHash, CLIENT_DATA_HASH_SIZE);
memmove(&getAssertionState.authData, head, sizeof(CTAP_authDataHeader)); memmove(&getAssertionState.authData, head, sizeof(CTAP_authDataHeader));
memmove(getAssertionState.creds, creds, sizeof(CTAP_credentialDescriptor) * (count)); 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 sigbuf[64];
uint8_t sigder[72]; 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); ret = ctap_add_credential_descriptor(map, cred);
check_retr(ret); check_retr(ret);
ret = ctap_add_user_entity(map, &cred->credential.fields.user); crypto_ecc256_load_key((uint8_t*)&cred->credential, sizeof(struct Credential), NULL, 0);
check_retr(ret);
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,"auth_data_buf: "); dump_hex1(TAG_DUMP, auth_data_buf, sizeof(CTAP_authDataHeader)); /*printf1(TAG_GREEN,"credential: # %d\n", cred->credential.enc.count);*/
printf1(TAG_GREEN,"clientdatahash: "); dump_hex1(TAG_DUMP, clientDataHash, 32);
printf1(TAG_GREEN,"credential: # %d\n", cred->credential.fields.count);
/*dump_hex1(TAG_DUMP, clientDataHash, 32);*/ /*dump_hex1(TAG_DUMP, clientDataHash, 32);*/
int sigder_sz = ctap_calculate_signature(auth_data_buf, sizeof(CTAP_authDataHeader), clientDataHash, auth_data_buf, sigbuf, sigder); 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); 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); printf1(TAG_GA, "ALLOW_LIST has %d creds\n", GA.credLen);
for (int j = 0; j < GA.credLen; j++) /*for (int j = 0; j < GA.credLen; j++)*/
{ /*{*/
printf1(TAG_GA,"CRED ID (# %d): ", GA.creds[j].credential.fields.count); /*printf1(TAG_GA,"CRED ID (# %d): ", GA.creds[j].credential.enc.count);*/
dump_hex1(TAG_GA, GA.creds[j].credential.id, CREDENTIAL_ID_SIZE); /*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 /*if (ctap_authenticate_credential(&GA.rp, &GA.creds[j])) // warning encryption will break this*/
{ /*{*/
printf1(TAG_GA," Authenticated.\n"); /*printf1(TAG_GA," Authenticated.\n");*/
} /*}*/
else /*else*/
{ /*{*/
printf1(TAG_GA," NOT authentic.\n"); /*printf1(TAG_GA," NOT authentic.\n");*/
} /*}*/
} /*}*/
// Decrypt here // 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"); printf1(TAG_RED,"resulting order of creds:\n");
for (int j = 0; j < GA.credLen; j++) 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; 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 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()) if (ctap_is_pin_set())
{ {
crypto_aes256_reset_iv(); crypto_aes256_reset_iv(NULL);
crypto_aes256_decrypt(pinHashEnc, 16); crypto_aes256_decrypt(pinHashEnc, 16);
if (memcmp(pinHashEnc, PIN_CODE_HASH, 16) != 0) 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_update(shared_secret, 32);
crypto_sha256_final(shared_secret); crypto_sha256_final(shared_secret);
crypto_aes256_init(shared_secret); crypto_aes256_init(shared_secret, NULL);
crypto_aes256_decrypt(pinHashEnc, 16); 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(); ctap_reset_pin_attempts();
crypto_aes256_reset_iv(); crypto_aes256_reset_iv(NULL);
// reuse share_secret memory for encrypted pinToken // reuse share_secret memory for encrypted pinToken
memmove(shared_secret, PIN_TOKEN, PIN_TOKEN_SIZE); memmove(shared_secret, PIN_TOKEN, PIN_TOKEN_SIZE);

20
ctap.h
View File

@ -91,8 +91,11 @@
#define CTAP_MAX_MESSAGE_SIZE 1024 #define CTAP_MAX_MESSAGE_SIZE 1024
#define CREDENTIAL_TAG_SIZE 16 #define CREDENTIAL_TAG_SIZE 16
#define CREDENTIAL_NONCE_SIZE 8
#define CREDENTIAL_COUNTER_SIZE (4) #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_PUB_KEY 0x01
#define PUB_KEY_CRED_UNKNOWN 0x3F #define PUB_KEY_CRED_UNKNOWN 0x3F
@ -109,15 +112,16 @@ typedef struct
uint8_t id[USER_ID_MAX_SIZE]; uint8_t id[USER_ID_MAX_SIZE];
uint8_t id_size; uint8_t id_size;
uint8_t name[USER_NAME_LIMIT]; uint8_t name[USER_NAME_LIMIT];
} CTAP_userEntity; }__attribute__((packed)) CTAP_userEntity;
union _credential { struct Credential {
struct {
uint8_t tag[CREDENTIAL_TAG_SIZE]; uint8_t tag[CREDENTIAL_TAG_SIZE];
uint8_t nonce[CREDENTIAL_NONCE_SIZE];
struct {
CTAP_userEntity user; CTAP_userEntity user;
uint32_t count; uint32_t count;
}__attribute__((packed)) fields; uint8_t _pad[CREDENTIAL_PAD_SIZE];
uint8_t id[CREDENTIAL_ID_SIZE]; } __attribute__((packed)) enc;
}; };
typedef struct typedef struct
@ -125,7 +129,7 @@ typedef struct
uint8_t aaguid[16]; uint8_t aaguid[16];
uint8_t credLenH; uint8_t credLenH;
uint8_t credLenL; uint8_t credLenL;
union _credential credential; struct Credential credential;
} __attribute__((packed)) CTAP_attestHeader; } __attribute__((packed)) CTAP_attestHeader;
typedef struct typedef struct
@ -179,7 +183,7 @@ typedef struct
typedef struct typedef struct
{ {
uint8_t type; uint8_t type;
union _credential credential; struct Credential credential;
} CTAP_credentialDescriptor; } CTAP_credentialDescriptor;
typedef struct typedef struct

View File

@ -637,8 +637,8 @@ uint8_t parse_credential_descriptor(CborValue * arr, CTAP_credentialDescriptor *
return CTAP2_ERR_MISSING_PARAMETER; return CTAP2_ERR_MISSING_PARAMETER;
} }
buflen = CREDENTIAL_ID_SIZE; buflen = sizeof(struct Credential);
cbor_value_copy_byte_string(&val, cred->credential.id, &buflen, NULL); cbor_value_copy_byte_string(&val, (uint8_t*)&cred->credential, &buflen, NULL);
if (buflen != CREDENTIAL_ID_SIZE) if (buflen != CREDENTIAL_ID_SIZE)
{ {
printf2(TAG_ERR,"Error, credential is incorrect length\n"); printf2(TAG_ERR,"Error, credential is incorrect length\n");