summaryrefslogtreecommitdiff
path: root/src/libstrongswan/chunk.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libstrongswan/chunk.c')
-rw-r--r--src/libstrongswan/chunk.c690
1 files changed, 0 insertions, 690 deletions
diff --git a/src/libstrongswan/chunk.c b/src/libstrongswan/chunk.c
deleted file mode 100644
index 9397c4e44..000000000
--- a/src/libstrongswan/chunk.c
+++ /dev/null
@@ -1,690 +0,0 @@
-/*
- * Copyright (C) 2008-2009 Tobias Brunner
- * Copyright (C) 2005-2006 Martin Willi
- * Copyright (C) 2005 Jan Hutter
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program 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 General Public License
- * for more details.
- */
-
-#include <stdio.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <errno.h>
-#include <ctype.h>
-
-#include "chunk.h"
-#include "debug.h"
-
-/* required for chunk_hash */
-#undef get16bits
-#if (defined(__GNUC__) && defined(__i386__))
-#define get16bits(d) (*((const u_int16_t*)(d)))
-#endif
-#if !defined (get16bits)
-#define get16bits(d) ((((u_int32_t)(((const u_int8_t*)(d))[1])) << 8)\
- + (u_int32_t)(((const u_int8_t*)(d))[0]) )
-#endif
-
-/**
- * Empty chunk.
- */
-chunk_t chunk_empty = { NULL, 0 };
-
-/**
- * Described in header.
- */
-chunk_t chunk_create_clone(u_char *ptr, chunk_t chunk)
-{
- chunk_t clone = chunk_empty;
-
- if (chunk.ptr && chunk.len > 0)
- {
- clone.ptr = ptr;
- clone.len = chunk.len;
- memcpy(clone.ptr, chunk.ptr, chunk.len);
- }
-
- return clone;
-}
-
-/**
- * Described in header.
- */
-size_t chunk_length(const char* mode, ...)
-{
- va_list chunks;
- size_t length = 0;
-
- va_start(chunks, mode);
- while (TRUE)
- {
- switch (*mode++)
- {
- case 'm':
- case 'c':
- case 's':
- {
- chunk_t ch = va_arg(chunks, chunk_t);
- length += ch.len;
- continue;
- }
- default:
- break;
- }
- break;
- }
- va_end(chunks);
- return length;
-}
-
-/**
- * Described in header.
- */
-chunk_t chunk_create_cat(u_char *ptr, const char* mode, ...)
-{
- va_list chunks;
- chunk_t construct = chunk_create(ptr, 0);
-
- va_start(chunks, mode);
- while (TRUE)
- {
- bool free_chunk = FALSE, clear_chunk = FALSE;
- chunk_t ch;
-
- switch (*mode++)
- {
- case 's':
- clear_chunk = TRUE;
- /* FALL */
- case 'm':
- free_chunk = TRUE;
- /* FALL */
- case 'c':
- ch = va_arg(chunks, chunk_t);
- memcpy(ptr, ch.ptr, ch.len);
- ptr += ch.len;
- construct.len += ch.len;
- if (clear_chunk)
- {
- chunk_clear(&ch);
- }
- else if (free_chunk)
- {
- free(ch.ptr);
- }
- continue;
- default:
- break;
- }
- break;
- }
- va_end(chunks);
-
- return construct;
-}
-
-/**
- * Described in header.
- */
-void chunk_split(chunk_t chunk, const char *mode, ...)
-{
- va_list chunks;
- u_int len;
- chunk_t *ch;
-
- va_start(chunks, mode);
- while (TRUE)
- {
- if (*mode == '\0')
- {
- break;
- }
- len = va_arg(chunks, u_int);
- ch = va_arg(chunks, chunk_t*);
- /* a null chunk means skip len bytes */
- if (ch == NULL)
- {
- chunk = chunk_skip(chunk, len);
- continue;
- }
- switch (*mode++)
- {
- case 'm':
- {
- ch->len = min(chunk.len, len);
- if (ch->len)
- {
- ch->ptr = chunk.ptr;
- }
- else
- {
- ch->ptr = NULL;
- }
- chunk = chunk_skip(chunk, ch->len);
- continue;
- }
- case 'a':
- {
- ch->len = min(chunk.len, len);
- if (ch->len)
- {
- ch->ptr = malloc(ch->len);
- memcpy(ch->ptr, chunk.ptr, ch->len);
- }
- else
- {
- ch->ptr = NULL;
- }
- chunk = chunk_skip(chunk, ch->len);
- continue;
- }
- case 'c':
- {
- ch->len = min(ch->len, chunk.len);
- ch->len = min(ch->len, len);
- if (ch->len)
- {
- memcpy(ch->ptr, chunk.ptr, ch->len);
- }
- else
- {
- ch->ptr = NULL;
- }
- chunk = chunk_skip(chunk, ch->len);
- continue;
- }
- default:
- break;
- }
- break;
- }
- va_end(chunks);
-}
-
-/**
- * Described in header.
- */
-bool chunk_write(chunk_t chunk, char *path, char *label, mode_t mask, bool force)
-{
- mode_t oldmask;
- FILE *fd;
- bool good = FALSE;
-
- if (!force && access(path, F_OK) == 0)
- {
- DBG1(DBG_LIB, " %s file '%s' already exists", label, path);
- return FALSE;
- }
- oldmask = umask(mask);
- fd = fopen(path, "w");
- if (fd)
- {
- if (fwrite(chunk.ptr, sizeof(u_char), chunk.len, fd) == chunk.len)
- {
- DBG1(DBG_LIB, " written %s file '%s' (%d bytes)",
- label, path, chunk.len);
- good = TRUE;
- }
- else
- {
- DBG1(DBG_LIB, " writing %s file '%s' failed: %s",
- label, path, strerror(errno));
- }
- fclose(fd);
- }
- else
- {
- DBG1(DBG_LIB, " could not open %s file '%s': %s", label, path,
- strerror(errno));
- }
- umask(oldmask);
- return good;
-}
-
-
-/** hex conversion digits */
-static char hexdig_upper[] = "0123456789ABCDEF";
-static char hexdig_lower[] = "0123456789abcdef";
-
-/**
- * Described in header.
- */
-chunk_t chunk_to_hex(chunk_t chunk, char *buf, bool uppercase)
-{
- int i, len;
- char *hexdig = hexdig_lower;
-
- if (uppercase)
- {
- hexdig = hexdig_upper;
- }
-
- len = chunk.len * 2;
- if (!buf)
- {
- buf = malloc(len + 1);
- }
- buf[len] = '\0';
-
- for (i = 0; i < chunk.len; i++)
- {
- buf[i*2] = hexdig[(chunk.ptr[i] >> 4) & 0xF];
- buf[i*2+1] = hexdig[(chunk.ptr[i] ) & 0xF];
- }
- return chunk_create(buf, len);
-}
-
-/**
- * convert a signle hex character to its binary value
- */
-static char hex2bin(char hex)
-{
- switch (hex)
- {
- case '0' ... '9':
- return hex - '0';
- case 'A' ... 'F':
- return hex - 'A' + 10;
- case 'a' ... 'f':
- return hex - 'a' + 10;
- default:
- return 0;
- }
-}
-
-/**
- * Described in header.
- */
-chunk_t chunk_from_hex(chunk_t hex, char *buf)
-{
- int i, len;
- u_char *ptr;
- bool odd = FALSE;
-
- /* subtract the number of optional ':' separation characters */
- len = hex.len;
- ptr = hex.ptr;
- for (i = 0; i < hex.len; i++)
- {
- if (*ptr++ == ':')
- {
- len--;
- }
- }
-
- /* compute the number of binary bytes */
- if (len % 2)
- {
- odd = TRUE;
- len++;
- }
- len /= 2;
-
- /* allocate buffer memory unless provided by caller */
- if (!buf)
- {
- buf = malloc(len);
- }
-
- /* buffer is filled from the right */
- memset(buf, 0, len);
- hex.ptr += hex.len;
-
- for (i = len - 1; i >= 0; i--)
- {
- /* skip separation characters */
- if (*(--hex.ptr) == ':')
- {
- --hex.ptr;
- }
- buf[i] = hex2bin(*hex.ptr);
- if (i > 0 || !odd)
- {
- buf[i] |= hex2bin(*(--hex.ptr)) << 4;
- }
- }
- return chunk_create(buf, len);
-}
-
-/** base 64 conversion digits */
-static char b64digits[] =
- "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
-
-/**
- * Described in header.
- */
-chunk_t chunk_to_base64(chunk_t chunk, char *buf)
-{
- int i, len;
- char *pos;
-
- len = chunk.len + ((3 - chunk.len % 3) % 3);
- if (!buf)
- {
- buf = malloc(len * 4 / 3 + 1);
- }
- pos = buf;
- for (i = 0; i < len; i+=3)
- {
- *pos++ = b64digits[chunk.ptr[i] >> 2];
- if (i+1 >= chunk.len)
- {
- *pos++ = b64digits[(chunk.ptr[i] & 0x03) << 4];
- *pos++ = '=';
- *pos++ = '=';
- break;
- }
- *pos++ = b64digits[((chunk.ptr[i] & 0x03) << 4) | (chunk.ptr[i+1] >> 4)];
- if (i+2 >= chunk.len)
- {
- *pos++ = b64digits[(chunk.ptr[i+1] & 0x0F) << 2];
- *pos++ = '=';
- break;
- }
- *pos++ = b64digits[((chunk.ptr[i+1] & 0x0F) << 2) | (chunk.ptr[i+2] >> 6)];
- *pos++ = b64digits[chunk.ptr[i+2] & 0x3F];
- }
- *pos = '\0';
- return chunk_create(buf, len * 4 / 3);
-}
-
-/**
- * convert a base 64 digit to its binary form (inversion of b64digits array)
- */
-static int b642bin(char b64)
-{
- switch (b64)
- {
- case 'A' ... 'Z':
- return b64 - 'A';
- case 'a' ... 'z':
- return ('Z' - 'A' + 1) + b64 - 'a';
- case '0' ... '9':
- return ('Z' - 'A' + 1) + ('z' - 'a' + 1) + b64 - '0';
- case '+':
- case '-':
- return 62;
- case '/':
- case '_':
- return 63;
- case '=':
- return 0;
- default:
- return -1;
- }
-}
-
-/**
- * Described in header.
- */
-chunk_t chunk_from_base64(chunk_t base64, char *buf)
-{
- u_char *pos, byte[4];
- int i, j, len, outlen;
-
- len = base64.len / 4 * 3;
- if (!buf)
- {
- buf = malloc(len);
- }
- pos = base64.ptr;
- outlen = 0;
- for (i = 0; i < len; i+=3)
- {
- outlen += 3;
- for (j = 0; j < 4; j++)
- {
- if (*pos == '=')
- {
- outlen--;
- }
- byte[j] = b642bin(*pos++);
- }
- buf[i] = (byte[0] << 2) | (byte[1] >> 4);
- buf[i+1] = (byte[1] << 4) | (byte[2] >> 2);
- buf[i+2] = (byte[2] << 6) | (byte[3]);
- }
- return chunk_create(buf, outlen);
-}
-
-/** base 32 conversion digits */
-static char b32digits[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
-
-/**
- * Described in header.
- */
-chunk_t chunk_to_base32(chunk_t chunk, char *buf)
-{
- int i, len;
- char *pos;
-
- len = chunk.len + ((5 - chunk.len % 5) % 5);
- if (!buf)
- {
- buf = malloc(len * 8 / 5 + 1);
- }
- pos = buf;
- for (i = 0; i < len; i+=5)
- {
- *pos++ = b32digits[chunk.ptr[i] >> 3];
- if (i+1 >= chunk.len)
- {
- *pos++ = b32digits[(chunk.ptr[i] & 0x07) << 2];
- memset(pos, '=', 6);
- pos += 6;
- break;
- }
- *pos++ = b32digits[((chunk.ptr[i] & 0x07) << 2) |
- (chunk.ptr[i+1] >> 6)];
- *pos++ = b32digits[(chunk.ptr[i+1] & 0x3E) >> 1];
- if (i+2 >= chunk.len)
- {
- *pos++ = b32digits[(chunk.ptr[i+1] & 0x01) << 4];
- memset(pos, '=', 4);
- pos += 4;
- break;
- }
- *pos++ = b32digits[((chunk.ptr[i+1] & 0x01) << 4) |
- (chunk.ptr[i+2] >> 4)];
- if (i+3 >= chunk.len)
- {
- *pos++ = b32digits[(chunk.ptr[i+2] & 0x0F) << 1];
- memset(pos, '=', 3);
- pos += 3;
- break;
- }
- *pos++ = b32digits[((chunk.ptr[i+2] & 0x0F) << 1) |
- (chunk.ptr[i+3] >> 7)];
- *pos++ = b32digits[(chunk.ptr[i+3] & 0x7F) >> 2];
- if (i+4 >= chunk.len)
- {
- *pos++ = b32digits[(chunk.ptr[i+3] & 0x03) << 3];
- *pos++ = '=';
- break;
- }
- *pos++ = b32digits[((chunk.ptr[i+3] & 0x03) << 3) |
- (chunk.ptr[i+4] >> 5)];
- *pos++ = b32digits[chunk.ptr[i+4] & 0x1F];
- }
- *pos = '\0';
- return chunk_create(buf, len * 8 / 5);
-}
-
-/**
- * Described in header.
- */
-int chunk_compare(chunk_t a, chunk_t b)
-{
- int compare_len = a.len - b.len;
- int len = (compare_len < 0)? a.len : b.len;
-
- if (compare_len != 0 || len == 0)
- {
- return compare_len;
- }
- return memcmp(a.ptr, b.ptr, len);
-};
-
-
-/**
- * Described in header.
- */
-bool chunk_increment(chunk_t chunk)
-{
- int i;
-
- for (i = chunk.len - 1; i >= 0; i--)
- {
- if (++chunk.ptr[i] != 0)
- {
- return FALSE;
- }
- }
- return TRUE;
-}
-
-/**
- * Remove non-printable characters from a chunk.
- */
-bool chunk_printable(chunk_t chunk, chunk_t *sane, char replace)
-{
- bool printable = TRUE;
- int i;
-
- if (sane)
- {
- *sane = chunk_clone(chunk);
- }
- for (i = 0; i < chunk.len; i++)
- {
- if (!isprint(chunk.ptr[i]))
- {
- if (sane)
- {
- sane->ptr[i] = replace;
- }
- printable = FALSE;
- }
- }
- return printable;
-}
-
-/**
- * Described in header.
- *
- * The implementation is based on Paul Hsieh's SuperFastHash:
- * http://www.azillionmonkeys.com/qed/hash.html
- */
-u_int32_t chunk_hash_inc(chunk_t chunk, u_int32_t hash)
-{
- u_char *data = chunk.ptr;
- size_t len = chunk.len;
- u_int32_t tmp;
- int rem;
-
- if (!len || data == NULL)
- {
- return 0;
- }
-
- rem = len & 3;
- len >>= 2;
-
- /* Main loop */
- for (; len > 0; --len)
- {
- hash += get16bits(data);
- tmp = (get16bits(data + 2) << 11) ^ hash;
- hash = (hash << 16) ^ tmp;
- data += 2 * sizeof(u_int16_t);
- hash += hash >> 11;
- }
-
- /* Handle end cases */
- switch (rem)
- {
- case 3:
- {
- hash += get16bits(data);
- hash ^= hash << 16;
- hash ^= data[sizeof(u_int16_t)] << 18;
- hash += hash >> 11;
- break;
- }
- case 2:
- {
- hash += get16bits(data);
- hash ^= hash << 11;
- hash += hash >> 17;
- break;
- }
- case 1:
- {
- hash += *data;
- hash ^= hash << 10;
- hash += hash >> 1;
- break;
- }
- }
-
- /* Force "avalanching" of final 127 bits */
- hash ^= hash << 3;
- hash += hash >> 5;
- hash ^= hash << 4;
- hash += hash >> 17;
- hash ^= hash << 25;
- hash += hash >> 6;
-
- return hash;
-}
-
-/**
- * Described in header.
- */
-u_int32_t chunk_hash(chunk_t chunk)
-{
- return chunk_hash_inc(chunk, chunk.len);
-}
-
-/**
- * Described in header.
- */
-int chunk_printf_hook(char *dst, size_t len, printf_hook_spec_t *spec,
- const void *const *args)
-{
- chunk_t *chunk = *((chunk_t**)(args[0]));
- bool first = TRUE;
- chunk_t copy = *chunk;
- int written = 0;
-
- if (!spec->hash)
- {
- u_int chunk_len = chunk->len;
- const void *new_args[] = {&chunk->ptr, &chunk_len};
- return mem_printf_hook(dst, len, spec, new_args);
- }
-
- while (copy.len > 0)
- {
- if (first)
- {
- first = FALSE;
- }
- else
- {
- written += print_in_hook(dst, len, ":");
- }
- written += print_in_hook(dst, len, "%02x", *copy.ptr++);
- copy.len--;
- }
- return written;
-}