util.c (5254B)
1 /* 2 * util.c 3 * 4 * Utilities used by the test apps 5 * 6 * John A. Foley 7 * Cisco Systems, Inc. 8 */ 9 /* 10 * 11 * Copyright (c) 2014-2017, Cisco Systems, Inc. 12 * All rights reserved. 13 * 14 * Redistribution and use in source and binary forms, with or without 15 * modification, are permitted provided that the following conditions 16 * are met: 17 * 18 * Redistributions of source code must retain the above copyright 19 * notice, this list of conditions and the following disclaimer. 20 * 21 * Redistributions in binary form must reproduce the above 22 * copyright notice, this list of conditions and the following 23 * disclaimer in the documentation and/or other materials provided 24 * with the distribution. 25 * 26 * Neither the name of the Cisco Systems, Inc. nor the names of its 27 * contributors may be used to endorse or promote products derived 28 * from this software without specific prior written permission. 29 * 30 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 31 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 32 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 33 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 34 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 35 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 36 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 37 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 40 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 41 * OF THE POSSIBILITY OF SUCH DAMAGE. 42 * 43 */ 44 45 #include "config.h" 46 #include "util.h" 47 48 #include <string.h> 49 #include <stdint.h> 50 51 /* include space for null terminator */ 52 static char bit_string[MAX_PRINT_STRING_LEN + 1]; 53 54 static inline int hex_char_to_nibble(uint8_t c) 55 { 56 switch (c) { 57 case ('0'): 58 return 0x0; 59 case ('1'): 60 return 0x1; 61 case ('2'): 62 return 0x2; 63 case ('3'): 64 return 0x3; 65 case ('4'): 66 return 0x4; 67 case ('5'): 68 return 0x5; 69 case ('6'): 70 return 0x6; 71 case ('7'): 72 return 0x7; 73 case ('8'): 74 return 0x8; 75 case ('9'): 76 return 0x9; 77 case ('a'): 78 return 0xa; 79 case ('A'): 80 return 0xa; 81 case ('b'): 82 return 0xb; 83 case ('B'): 84 return 0xb; 85 case ('c'): 86 return 0xc; 87 case ('C'): 88 return 0xc; 89 case ('d'): 90 return 0xd; 91 case ('D'): 92 return 0xd; 93 case ('e'): 94 return 0xe; 95 case ('E'): 96 return 0xe; 97 case ('f'): 98 return 0xf; 99 case ('F'): 100 return 0xf; 101 default: 102 return -1; /* this flags an error */ 103 } 104 } 105 106 uint8_t nibble_to_hex_char(uint8_t nibble) 107 { 108 char buf[16] = { '0', '1', '2', '3', '4', '5', '6', '7', 109 '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; 110 111 return buf[nibble & 0xF]; 112 } 113 114 /* 115 * hex_string_to_octet_string converts a hexadecimal string 116 * of length 2 * len to a raw octet string of length len 117 */ 118 int hex_string_to_octet_string(char *raw, char *hex, int len) 119 { 120 uint8_t x; 121 int tmp; 122 int hex_len; 123 124 hex_len = 0; 125 while (hex_len < len) { 126 tmp = hex_char_to_nibble(hex[0]); 127 if (tmp == -1) { 128 return hex_len; 129 } 130 x = (uint8_t)(tmp << 4); 131 hex_len++; 132 tmp = hex_char_to_nibble(hex[1]); 133 if (tmp == -1) { 134 return hex_len; 135 } 136 x |= (tmp & 0xff); 137 hex_len++; 138 *raw++ = x; 139 hex += 2; 140 } 141 return hex_len; 142 } 143 144 char *octet_string_hex_string(const void *s, int length) 145 { 146 const uint8_t *str = (const uint8_t *)s; 147 int i; 148 149 /* double length, since one octet takes two hex characters */ 150 length *= 2; 151 152 /* truncate string if it would be too long */ 153 if (length > MAX_PRINT_STRING_LEN) { 154 length = MAX_PRINT_STRING_LEN; 155 } 156 157 for (i = 0; i < length; i += 2) { 158 bit_string[i] = nibble_to_hex_char(*str >> 4); 159 bit_string[i + 1] = nibble_to_hex_char(*str++ & 0xF); 160 } 161 bit_string[i] = 0; /* null terminate string */ 162 return bit_string; 163 } 164 165 static const char b64chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 166 "abcdefghijklmnopqrstuvwxyz0123456789+/"; 167 168 static int base64_block_to_octet_triple(char *out, char *in) 169 { 170 unsigned char sextets[4] = { 0 }; 171 int j = 0; 172 int i; 173 174 for (i = 0; i < 4; i++) { 175 char *p = strchr(b64chars, in[i]); 176 if (p != NULL) { 177 sextets[i] = (unsigned char)(p - b64chars); 178 } else { 179 j++; 180 } 181 } 182 183 out[0] = (sextets[0] << 2) | (sextets[1] >> 4); 184 if (j < 2) { 185 out[1] = (sextets[1] << 4) | (sextets[2] >> 2); 186 } 187 if (j < 1) { 188 out[2] = (sextets[2] << 6) | sextets[3]; 189 } 190 return j; 191 } 192 193 int base64_string_to_octet_string(char *out, int *pad, char *in, int len) 194 { 195 int k = 0; 196 int i = 0; 197 int j = 0; 198 199 if (len % 4 != 0) { 200 return 0; 201 } 202 203 while (i < len && j == 0) { 204 j = base64_block_to_octet_triple(out + k, in + i); 205 k += 3; 206 i += 4; 207 } 208 *pad = j; 209 return i; 210 }