diff options
author | SoniEx2 <endermoneymod@gmail.com> | 2021-04-09 07:19:03 -0300 |
---|---|---|
committer | SoniEx2 <endermoneymod@gmail.com> | 2021-04-09 07:19:03 -0300 |
commit | 0e752a6e215aee21dc73da097c3225495d54a5b6 (patch) | |
tree | b81be02cbf2f06aebf322ac4a5d014b44176bba5 /libotr/libotr-4.1.1/src/tlv.c | |
parent | 7754076c715285173311a1b6811ce377950e18a6 (diff) |
Add libotr/etc sources
Diffstat (limited to 'libotr/libotr-4.1.1/src/tlv.c')
-rw-r--r-- | libotr/libotr-4.1.1/src/tlv.c | 109 |
1 files changed, 109 insertions, 0 deletions
diff --git a/libotr/libotr-4.1.1/src/tlv.c b/libotr/libotr-4.1.1/src/tlv.c new file mode 100644 index 0000000..fa76c3d --- /dev/null +++ b/libotr/libotr-4.1.1/src/tlv.c @@ -0,0 +1,109 @@ +/* + * Off-the-Record Messaging library + * Copyright (C) 2004-2012 Ian Goldberg, Chris Alexander, Willy Lew, + * Nikita Borisov + * <otr@cypherpunks.ca> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of version 2.1 of the GNU Lesser General + * Public License as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include <stdlib.h> +#include <string.h> +#include <assert.h> + +#include "tlv.h" + +/* Make a single TLV, copying the supplied data */ +OtrlTLV *otrl_tlv_new(unsigned short type, unsigned short len, + const unsigned char *data) +{ + OtrlTLV *tlv = malloc(sizeof(OtrlTLV)); + assert(tlv != NULL); + tlv->type = type; + tlv->len = len; + tlv->data = malloc(len + 1); + assert(tlv->data != NULL); + memmove(tlv->data, data, len); + tlv->data[tlv->len] = '\0'; + tlv->next = NULL; + return tlv; +} + +/* Construct a chain of TLVs from the given data */ +OtrlTLV *otrl_tlv_parse(const unsigned char *serialized, size_t seriallen) +{ + OtrlTLV *tlv = NULL; + OtrlTLV **tlvp = &tlv; + while (seriallen >= 4) { + unsigned short type = (serialized[0] << 8) + serialized[1]; + unsigned short len = (serialized[2] << 8) + serialized[3]; + serialized += 4; seriallen -=4; + if (seriallen < len) break; + *tlvp = otrl_tlv_new(type, len, serialized); + serialized += len; + seriallen -= len; + tlvp = &((*tlvp)->next); + } + return tlv; +} + +/* Deallocate a chain of TLVs */ +void otrl_tlv_free(OtrlTLV *tlv) +{ + while (tlv) { + OtrlTLV *next = tlv->next; + free(tlv->data); + free(tlv); + tlv = next; + } +} + +/* Find the serialized length of a chain of TLVs */ +size_t otrl_tlv_seriallen(const OtrlTLV *tlv) +{ + size_t totlen = 0; + while (tlv) { + totlen += tlv->len + 4; + tlv = tlv->next; + } + return totlen; +} + +/* Serialize a chain of TLVs. The supplied buffer must already be large + * enough. */ +void otrl_tlv_serialize(unsigned char *buf, const OtrlTLV *tlv) +{ + while (tlv) { + buf[0] = (tlv->type >> 8) & 0xff; + buf[1] = tlv->type & 0xff; + buf[2] = (tlv->len >> 8) & 0xff; + buf[3] = tlv->len & 0xff; + buf += 4; + memmove(buf, tlv->data, tlv->len); + buf += tlv->len; + tlv = tlv->next; + } +} + +/* Return the first TLV with the given type in the chain, or NULL if one + * isn't found. (The tlvs argument isn't const because the return type + * needs to be non-const.) */ +OtrlTLV *otrl_tlv_find(OtrlTLV *tlvs, unsigned short type) +{ + while (tlvs) { + if (tlvs->type == type) return tlvs; + tlvs = tlvs->next; + } + return NULL; +} |