|
|
|
|
|
|
|
|
|
|
|
#include <stdio.h> |
|
|
|
|
|
#include <stdlib.h> |
|
|
|
|
|
#include <string.h> |
|
|
|
|
|
#include <endian.h> |
|
|
|
|
|
#include <assert.h> |
|
|
|
|
|
#include <arpa/inet.h> |
|
|
|
|
|
|
|
|
|
|
|
#include "../inc/lc6_msg.h" |
|
|
|
|
|
#include "../inc/lc6_base64.h" |
|
|
|
|
|
#include "../inc/lc6_time.h" |
|
|
|
|
|
#include "../inc/lc6_crypto.h" |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
unsigned char* lc6msg_compose(unsigned char *srckey, unsigned char *dstkey, LC6_MSG *msg) { |
|
|
|
|
|
unsigned char *ret = NULL; |
|
|
|
|
|
unsigned char *timestamp = lc6time_getstr(); |
|
|
|
|
|
unsigned char *type = NULL; |
|
|
|
|
|
LC6_MSG_TLV *tlv = NULL; |
|
|
|
|
|
int total_len = 0; |
|
|
|
|
|
|
|
|
|
|
|
assert(srckey); |
|
|
|
|
|
assert(dstkey); |
|
|
|
|
|
assert(msg); |
|
|
|
|
|
|
|
|
|
|
|
/* <proof> |
|
|
|
|
|
* <msghash> |
|
|
|
|
|
* <timestamp> |
|
|
|
|
|
* <type> |
|
|
|
|
|
* <optional tlvs> name=value<space>name=value... |
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
|
|
type = LC6_MSG_TYPE_STR[msg->type]; |
|
|
|
|
|
|
|
|
|
|
|
total_len += LC6_CRYPTO_HASHSIGNLEN; // proof |
|
|
|
|
|
total_len++; // space |
|
|
|
|
|
total_len += LC6_CRYPTO_HASHLEN; // msghash |
|
|
|
|
|
total_len++; // space |
|
|
|
|
|
total_len += strlen((char*)timestamp); // timestamp |
|
|
|
|
|
total_len++; // space |
|
|
|
|
|
total_len += strlen((char*)type); // type |
|
|
|
|
|
|
|
|
|
|
|
if ( msg->tlv ) |
|
|
|
|
|
tlv = *msg->tlv; |
|
|
|
|
|
|
|
|
|
|
|
while(tlv) { |
|
|
|
|
|
int len = 0; |
|
|
|
|
|
len += sizeof(LC6_MSG_TLV_STR[tlv->type]); // name |
|
|
|
|
|
len++; // equal sign |
|
|
|
|
|
len += tlv->length; |
|
|
|
|
|
|
|
|
|
|
|
total_len++; // space |
|
|
|
|
|
total_len+=len; // tlv |
|
|
|
|
|
|
|
|
|
|
|
tlv++; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
ret = malloc(total_len+1); // all + nulchar |
|
|
|
|
|
assert(ret); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return ret; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void lc6msg_tlv_add_utf8(LC6_MSG *msg, int type, int length, void *value) { |
|
|
|
|
|
lc6msg_tlv_add_binary(msg, type, length, value); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void lc6msg_tlv_add_uuid(LC6_MSG *msg, int type, int length, void *value) { |
|
|
|
|
|
lc6msg_tlv_add_binary(msg, type, length, value); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void lc6msg_tlv_add_binary(LC6_MSG *msg, int type, int length, void *value) { |
|
|
|
|
|
LC6_MSG_TLV *tlv; |
|
|
|
|
|
unsigned char *b64; |
|
|
|
|
|
size_t b64len = 0; |
|
|
|
|
|
|
|
|
|
|
|
assert(msg); |
|
|
|
|
|
assert(value); |
|
|
|
|
|
|
|
|
|
|
|
tlv = malloc(sizeof(LC6_MSG_TLV)); |
|
|
|
|
|
assert(tlv); |
|
|
|
|
|
memset(tlv, 0, sizeof(LC6_MSG_TLV)); |
|
|
|
|
|
|
|
|
|
|
|
tlv->type = type; |
|
|
|
|
|
|
|
|
|
|
|
b64 = lc6base64_encode(value, length, &b64len); |
|
|
|
|
|
|
|
|
|
|
|
tlv->length = b64len; |
|
|
|
|
|
tlv->value = b64; |
|
|
|
|
|
assert(tlv->value); |
|
|
|
|
|
|
|
|
|
|
|
lc6msg_tlv_append(msg, tlv); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void lc6msg_tlv_add_ipport(LC6_MSG *msg, int type, LC6_IPADDR *ip, uint16_t port) { |
|
|
|
|
|
LC6_MSG_TLV *tlv; |
|
|
|
|
|
char temp[INET6_ADDRSTRLEN+7]; |
|
|
|
|
|
|
|
|
|
|
|
assert(msg); |
|
|
|
|
|
assert(ip); |
|
|
|
|
|
|
|
|
|
|
|
tlv = malloc(sizeof(LC6_MSG_TLV)); |
|
|
|
|
|
assert(tlv); |
|
|
|
|
|
memset(tlv, 0, sizeof(LC6_MSG_TLV)); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if ( ip->af == 4 ) { |
|
|
|
|
|
struct in_addr addr; |
|
|
|
|
|
addr.s_addr = ip->addr.inet; |
|
|
|
|
|
inet_ntop(AF_INET, &addr, temp, sizeof(addr)); |
|
|
|
|
|
} |
|
|
|
|
|
else if ( ip->af == 6 ) { |
|
|
|
|
|
struct in6_addr addr; |
|
|
|
|
|
memcpy(&addr, ip->addr.inet6, 16); |
|
|
|
|
|
inet_ntop(AF_INET6, &addr, temp, sizeof(addr)); |
|
|
|
|
|
} |
|
|
|
|
|
else { |
|
|
|
|
|
assert(0); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
sprintf(temp, "%s/%u", temp, port); |
|
|
|
|
|
|
|
|
|
|
|
tlv->value = malloc(strlen(temp)+1); |
|
|
|
|
|
assert(tlv->value); |
|
|
|
|
|
strcpy((char*)tlv->value, temp); |
|
|
|
|
|
|
|
|
|
|
|
lc6msg_tlv_append(msg, tlv); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void lc6msg_tlv_add_integer(LC6_MSG *msg, int type, uint64_t value) { |
|
|
|
|
|
LC6_MSG_TLV *tlv; |
|
|
|
|
|
char temp[21]; // 2^64 = 20 + nulchar |
|
|
|
|
|
|
|
|
|
|
|
assert(msg); |
|
|
|
|
|
|
|
|
|
|
|
tlv = malloc(sizeof(LC6_MSG_TLV)); |
|
|
|
|
|
assert(tlv); |
|
|
|
|
|
memset(tlv, 0, sizeof(LC6_MSG_TLV)); |
|
|
|
|
|
|
|
|
|
|
|
sprintf(temp, "%lu", value); |
|
|
|
|
|
tlv->value = malloc(strlen(temp)+1); |
|
|
|
|
|
assert(tlv->value); |
|
|
|
|
|
strcpy((char*)tlv->value, temp); |
|
|
|
|
|
|
|
|
|
|
|
lc6msg_tlv_append(msg, tlv); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void lc6msg_tlv_append(LC6_MSG *msg, LC6_MSG_TLV *tlv) { |
|
|
|
|
|
assert(msg); |
|
|
|
|
|
assert(tlv); |
|
|
|
|
|
|
|
|
|
|
|
if ( ! msg->tlv ) { |
|
|
|
|
|
msg->tlv = malloc(sizeof(LC6_MSG_TLV*)*2); |
|
|
|
|
|
assert(msg->tlv); |
|
|
|
|
|
memset(msg->tlv, 0, sizeof(LC6_MSG_TLV*)*2); |
|
|
|
|
|
msg->tlv[0] = tlv; |
|
|
|
|
|
} |
|
|
|
|
|
else { |
|
|
|
|
|
int i; |
|
|
|
|
|
for(i=0; ; i++) { |
|
|
|
|
|
if ( ! msg->tlv[i] ) { |
|
|
|
|
|
msg->tlv = realloc(msg->tlv, sizeof(LC6_MSG_TLV*)*(i+1)); |
|
|
|
|
|
msg->tlv[i] = tlv; |
|
|
|
|
|
msg->tlv[i+1] = NULL; |
|
|
|
|
|
break; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void lc6msg_free(LC6_MSG *msg) { |
|
|
|
|
|
int i; |
|
|
|
|
|
|
|
|
|
|
|
if ( msg->tlv ) { |
|
|
|
|
|
for(i=0; msg->tlv[i]; i++) { |
|
|
|
|
|
if ( msg->tlv[i]->value ) |
|
|
|
|
|
free(msg->tlv[i]->value); |
|
|
|
|
|
free(msg->tlv[i]); |
|
|
|
|
|
} |
|
|
|
|
|
free(msg->tlv); |
|
|
|
|
|
} |
|
|
|
|
|
free(msg); |
|
|
|
|
|
} |