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 char bit_string[MAX_PRINT_STRING_LEN + 1];
53
hex_char_to_nibble(uint8_t c)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 /* NOTREACHED */
105 return -1; /* this keeps compilers from complaining */
106 }
107
nibble_to_hex_char(uint8_t nibble)108 uint8_t nibble_to_hex_char(uint8_t nibble)
109 {
110 char buf[16] = { '0', '1', '2', '3', '4', '5', '6', '7',
111 '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
112
113 return buf[nibble & 0xF];
114 }
115
116 /*
117 * hex_string_to_octet_string converts a hexadecimal string
118 * of length 2 * len to a raw octet string of length len
119 */
hex_string_to_octet_string(char * raw,char * hex,int len)120 int hex_string_to_octet_string(char *raw, char *hex, int len)
121 {
122 uint8_t x;
123 int tmp;
124 int hex_len;
125
126 hex_len = 0;
127 while (hex_len < len) {
128 tmp = hex_char_to_nibble(hex[0]);
129 if (tmp == -1) {
130 return hex_len;
131 }
132 x = (tmp << 4);
133 hex_len++;
134 tmp = hex_char_to_nibble(hex[1]);
135 if (tmp == -1) {
136 return hex_len;
137 }
138 x |= (tmp & 0xff);
139 hex_len++;
140 *raw++ = x;
141 hex += 2;
142 }
143 return hex_len;
144 }
145
octet_string_hex_string(const void * s,int length)146 char *octet_string_hex_string(const void *s, int length)
147 {
148 const uint8_t *str = (const uint8_t *)s;
149 int i;
150
151 /* double length, since one octet takes two hex characters */
152 length *= 2;
153
154 /* truncate string if it would be too long */
155 if (length > MAX_PRINT_STRING_LEN) {
156 length = MAX_PRINT_STRING_LEN;
157 }
158
159 for (i = 0; i < length; i += 2) {
160 bit_string[i] = nibble_to_hex_char(*str >> 4);
161 bit_string[i + 1] = nibble_to_hex_char(*str++ & 0xF);
162 }
163 bit_string[i] = 0; /* null terminate string */
164 return bit_string;
165 }
166
167 static const char b64chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
168 "abcdefghijklmnopqrstuvwxyz0123456789+/";
169
base64_block_to_octet_triple(char * out,char * in)170 static int base64_block_to_octet_triple(char *out, char *in)
171 {
172 unsigned char sextets[4] = { 0 };
173 int j = 0;
174 int i;
175
176 for (i = 0; i < 4; i++) {
177 char *p = strchr(b64chars, in[i]);
178 if (p != NULL) {
179 sextets[i] = p - b64chars;
180 } else {
181 j++;
182 }
183 }
184
185 out[0] = (sextets[0] << 2) | (sextets[1] >> 4);
186 if (j < 2) {
187 out[1] = (sextets[1] << 4) | (sextets[2] >> 2);
188 }
189 if (j < 1) {
190 out[2] = (sextets[2] << 6) | sextets[3];
191 }
192 return j;
193 }
194
base64_string_to_octet_string(char * out,int * pad,char * in,int len)195 int base64_string_to_octet_string(char *out, int *pad, char *in, int len)
196 {
197 int k = 0;
198 int i = 0;
199 int j = 0;
200
201 if (len % 4 != 0) {
202 return 0;
203 }
204
205 while (i < len && j == 0) {
206 j = base64_block_to_octet_triple(out + k, in + i);
207 k += 3;
208 i += 4;
209 }
210 *pad = j;
211 return i;
212 }
213