175 lines
3.8 KiB
C
175 lines
3.8 KiB
C
/*
|
|
* libZRTP SDK library, implements the ZRTP secure VoIP protocol.
|
|
* Copyright (c) 2006-2009 Philip R. Zimmermann. All rights reserved.
|
|
* Contact: http://philzimmermann.com
|
|
* For licensing and other legal details, see the file zrtp_legal.c.
|
|
*
|
|
* Viktor Krykun <v.krikun at zfoneproject.com>
|
|
*/
|
|
|
|
#include "zrtp.h"
|
|
|
|
#if ZRTP_HAVE_STRING_H == 1
|
|
# include <string.h>
|
|
#endif
|
|
|
|
|
|
/*----------------------------------------------------------------------------*/
|
|
int zrtp_zstrcmp(const zrtp_stringn_t *left, const zrtp_stringn_t *right)
|
|
{
|
|
if (left->length == right->length) {
|
|
return zrtp_memcmp(left->buffer, right->buffer, left->length);
|
|
} else {
|
|
return left->length - right->length;
|
|
}
|
|
}
|
|
|
|
void zrtp_zstrcpy(zrtp_stringn_t *dst, const zrtp_stringn_t *src)
|
|
{
|
|
dst->length = ZRTP_MIN(dst->max_length, src->length);
|
|
zrtp_memcpy(dst->buffer, src->buffer, dst->length);
|
|
if (dst->length < dst->max_length) {
|
|
dst->buffer[dst->length] = 0;
|
|
}
|
|
}
|
|
|
|
void zrtp_zstrcpyc(zrtp_stringn_t *dst, const char *src)
|
|
{
|
|
dst->length = ZRTP_MIN(dst->max_length, strlen(src));
|
|
zrtp_memcpy(dst->buffer, src, dst->length);
|
|
if (dst->length < dst->max_length) {
|
|
dst->buffer[dst->length] = 0;
|
|
}
|
|
}
|
|
|
|
void zrtp_zstrncpy(zrtp_stringn_t *dst, const zrtp_stringn_t *src, uint16_t size)
|
|
{
|
|
dst->length = ZRTP_MIN(dst->max_length, size);
|
|
zrtp_memcpy(dst->buffer, src->buffer, dst->length);
|
|
if (dst->length < dst->max_length) {
|
|
dst->buffer[dst->length] = 0;
|
|
}
|
|
}
|
|
|
|
void zrtp_zstrncpyc(zrtp_stringn_t *dst, const char *src, uint16_t size)
|
|
{
|
|
dst->length = ZRTP_MIN(dst->max_length, size);
|
|
zrtp_memcpy(dst->buffer, src, dst->length);
|
|
if (dst->length < dst->max_length) {
|
|
dst->buffer[dst->length] = 0;
|
|
}
|
|
}
|
|
|
|
void zrtp_zstrcat(zrtp_stringn_t *dst, const zrtp_stringn_t *src)
|
|
{
|
|
uint16_t count = ZRTP_MIN((dst->max_length - dst->length), src->length);
|
|
zrtp_memcpy(dst->buffer + dst->length, src->buffer, count);
|
|
dst->length += count;
|
|
if (dst->length < dst->max_length) {
|
|
dst->buffer[dst->length] = 0;
|
|
}
|
|
}
|
|
|
|
void zrtp_wipe_zstring(zrtp_stringn_t *zstr)
|
|
{
|
|
if (zstr && zstr->length) {
|
|
zrtp_memset(zstr->buffer, 0, zstr->max_length);
|
|
zstr->length = 0;
|
|
}
|
|
}
|
|
|
|
int zrtp_memcmp(const void* s1, const void* s2, uint32_t n)
|
|
{
|
|
uint32_t i = 0;
|
|
uint8_t* s1uc = (uint8_t*) s1;
|
|
uint8_t* s2uc = (uint8_t*) s2;
|
|
|
|
for (i=0; i<n; i++) {
|
|
if (s1uc[i] < s2uc[i]) {
|
|
return -1;
|
|
} else if (s1uc[i] > s2uc[i]) {
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/*----------------------------------------------------------------------------*/
|
|
static char* hex2char(char *dst, unsigned char b)
|
|
{
|
|
unsigned char v = b >> 4;
|
|
*dst++ = (v<=9) ? '0'+v : 'a'+ (v-10);
|
|
v = b & 0x0f;
|
|
*dst++ = (v<=9) ? '0'+v : 'a'+ (v-10);
|
|
|
|
return dst;
|
|
}
|
|
|
|
const char* hex2str(const char* bin, int bin_size, char* buff, int buff_size)
|
|
{
|
|
char* nptr = buff;
|
|
|
|
if (NULL == buff) {
|
|
return "buffer is NULL";
|
|
}
|
|
if (buff_size < bin_size*2) {
|
|
return "buffer too small";
|
|
}
|
|
|
|
while (bin_size--) {
|
|
nptr = hex2char(nptr, *bin++);
|
|
}
|
|
|
|
if (buff_size >= bin_size*2+1)
|
|
*nptr = 0;
|
|
|
|
return buff;
|
|
}
|
|
|
|
/*----------------------------------------------------------------------------*/
|
|
static int char2hex(char v)
|
|
{
|
|
if (v >= 'a' && v <= 'f') {
|
|
return v - 'a' + 10;
|
|
}
|
|
if (v >= 'A' && v <= 'F') {
|
|
return v - 'A' + 10;
|
|
}
|
|
if (v >= '0' && v <= '9') {
|
|
return v - '0';
|
|
}
|
|
return 0x10;
|
|
}
|
|
|
|
char *str2hex(const char* buff, int buff_size, char* bin, int bin_size)
|
|
{
|
|
char tmp = 0;
|
|
|
|
if (NULL == buff || !buff_size) {
|
|
return "buffer is NULL || !buf_size";
|
|
}
|
|
if (buff_size % 2) {
|
|
return "buff_size has to be even";
|
|
}
|
|
if (buff_size > bin_size*2) {
|
|
return "buffer too small";
|
|
}
|
|
|
|
while (buff_size--)
|
|
{
|
|
int value = char2hex(*buff++);
|
|
if (value > 0x0F) {
|
|
return "wrong symbol in buffer";
|
|
}
|
|
if (buff_size % 2) {
|
|
tmp = (char)value;
|
|
} else {
|
|
value |= (char)(tmp << 4);
|
|
*bin++ = value;
|
|
}
|
|
}
|
|
|
|
return bin;
|
|
}
|