Index: test/util.c |
diff --git a/test/util.c b/test/util.c |
new file mode 100644 |
index 0000000000000000000000000000000000000000..c75ab3762dd38d997f5f7c056744c1c7b0b55b18 |
--- /dev/null |
+++ b/test/util.c |
@@ -0,0 +1,185 @@ |
+/* |
+ * util.c |
+ * |
+ * Utilities used by the test apps |
+ * |
+ * John A. Foley |
+ * Cisco Systems, Inc. |
+ */ |
+/* |
+ * |
+ * Copyright (c) 2014, Cisco Systems, Inc. |
+ * All rights reserved. |
+ * |
+ * Redistribution and use in source and binary forms, with or without |
+ * modification, are permitted provided that the following conditions |
+ * are met: |
+ * |
+ * Redistributions of source code must retain the above copyright |
+ * notice, this list of conditions and the following disclaimer. |
+ * |
+ * Redistributions in binary form must reproduce the above |
+ * copyright notice, this list of conditions and the following |
+ * disclaimer in the documentation and/or other materials provided |
+ * with the distribution. |
+ * |
+ * Neither the name of the Cisco Systems, Inc. nor the names of its |
+ * contributors may be used to endorse or promote products derived |
+ * from this software without specific prior written permission. |
+ * |
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
+ * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, |
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, |
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED |
+ * OF THE POSSIBILITY OF SUCH DAMAGE. |
+ * |
+ */ |
+ |
+#include <string.h> |
+#include <stdint.h> |
+#include "util.h" |
+ |
+char bit_string[MAX_PRINT_STRING_LEN]; |
+ |
+static inline int hex_char_to_nibble (uint8_t c) |
+{ |
+ switch (c) { |
+ case ('0'): return 0x0; |
+ case ('1'): return 0x1; |
+ case ('2'): return 0x2; |
+ case ('3'): return 0x3; |
+ case ('4'): return 0x4; |
+ case ('5'): return 0x5; |
+ case ('6'): return 0x6; |
+ case ('7'): return 0x7; |
+ case ('8'): return 0x8; |
+ case ('9'): return 0x9; |
+ case ('a'): return 0xa; |
+ case ('A'): return 0xa; |
+ case ('b'): return 0xb; |
+ case ('B'): return 0xb; |
+ case ('c'): return 0xc; |
+ case ('C'): return 0xc; |
+ case ('d'): return 0xd; |
+ case ('D'): return 0xd; |
+ case ('e'): return 0xe; |
+ case ('E'): return 0xe; |
+ case ('f'): return 0xf; |
+ case ('F'): return 0xf; |
+ default: return -1; /* this flags an error */ |
+ } |
+ /* NOTREACHED */ |
+ return -1; /* this keeps compilers from complaining */ |
+} |
+ |
+uint8_t nibble_to_hex_char (uint8_t nibble) |
+{ |
+ char buf[16] = { '0', '1', '2', '3', '4', '5', '6', '7', |
+ '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; |
+ |
+ return buf[nibble & 0xF]; |
+} |
+ |
+/* |
+ * hex_string_to_octet_string converts a hexadecimal string |
+ * of length 2 * len to a raw octet string of length len |
+ */ |
+int hex_string_to_octet_string (char *raw, char *hex, int len) |
+{ |
+ uint8_t x; |
+ int tmp; |
+ int hex_len; |
+ |
+ hex_len = 0; |
+ while (hex_len < len) { |
+ tmp = hex_char_to_nibble(hex[0]); |
+ if (tmp == -1) { |
+ return hex_len; |
+ } |
+ x = (tmp << 4); |
+ hex_len++; |
+ tmp = hex_char_to_nibble(hex[1]); |
+ if (tmp == -1) { |
+ return hex_len; |
+ } |
+ x |= (tmp & 0xff); |
+ hex_len++; |
+ *raw++ = x; |
+ hex += 2; |
+ } |
+ return hex_len; |
+} |
+ |
+char * octet_string_hex_string (const void *s, int length) |
+{ |
+ const uint8_t *str = (const uint8_t*)s; |
+ int i; |
+ |
+ /* double length, since one octet takes two hex characters */ |
+ length *= 2; |
+ |
+ /* truncate string if it would be too long */ |
+ if (length > MAX_PRINT_STRING_LEN) { |
+ length = MAX_PRINT_STRING_LEN - 1; |
+ } |
+ |
+ for (i = 0; i < length; i += 2) { |
+ bit_string[i] = nibble_to_hex_char(*str >> 4); |
+ bit_string[i + 1] = nibble_to_hex_char(*str++ & 0xF); |
+ } |
+ bit_string[i] = 0; /* null terminate string */ |
+ return bit_string; |
+} |
+ |
+static const char b64chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" |
+ "abcdefghijklmnopqrstuvwxyz0123456789+/"; |
+ |
+static int base64_block_to_octet_triple (char *out, char *in) |
+{ |
+ unsigned char sextets[4] = {}; |
+ int j = 0; |
+ int i; |
+ |
+ for (i = 0; i < 4; i++) { |
+ char *p = strchr(b64chars, in[i]); |
+ if (p != NULL) { |
+ sextets[i] = p - b64chars; |
+ } else{ j++; } |
+ } |
+ |
+ out[0] = (sextets[0] << 2) | (sextets[1] >> 4); |
+ if (j < 2) { |
+ out[1] = (sextets[1] << 4) | (sextets[2] >> 2); |
+ } |
+ if (j < 1) { |
+ out[2] = (sextets[2] << 6) | sextets[3]; |
+ } |
+ return j; |
+} |
+ |
+int base64_string_to_octet_string (char *out, int *pad, char *in, int len) |
+{ |
+ int k = 0; |
+ int i = 0; |
+ int j = 0; |
+ |
+ if (len % 4 != 0) { |
+ return 0; |
+ } |
+ |
+ while (i < len && j == 0) { |
+ j = base64_block_to_octet_triple(out + k, in + i); |
+ k += 3; |
+ i += 4; |
+ } |
+ *pad = j; |
+ return i; |
+} |
+ |