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 "util.h"
46
47 #include <string.h>
48 #include <stdint.h>
49
50 char bit_string[MAX_PRINT_STRING_LEN];
51
hex_char_to_nibble(uint8_t c)52 static inline int hex_char_to_nibble(uint8_t c)
53 {
54 switch (c) {
55 case ('0'):
56 return 0x0;
57 case ('1'):
58 return 0x1;
59 case ('2'):
60 return 0x2;
61 case ('3'):
62 return 0x3;
63 case ('4'):
64 return 0x4;
65 case ('5'):
66 return 0x5;
67 case ('6'):
68 return 0x6;
69 case ('7'):
70 return 0x7;
71 case ('8'):
72 return 0x8;
73 case ('9'):
74 return 0x9;
75 case ('a'):
76 return 0xa;
77 case ('A'):
78 return 0xa;
79 case ('b'):
80 return 0xb;
81 case ('B'):
82 return 0xb;
83 case ('c'):
84 return 0xc;
85 case ('C'):
86 return 0xc;
87 case ('d'):
88 return 0xd;
89 case ('D'):
90 return 0xd;
91 case ('e'):
92 return 0xe;
93 case ('E'):
94 return 0xe;
95 case ('f'):
96 return 0xf;
97 case ('F'):
98 return 0xf;
99 default:
100 return -1; /* this flags an error */
101 }
102 /* NOTREACHED */
103 return -1; /* this keeps compilers from complaining */
104 }
105
nibble_to_hex_char(uint8_t nibble)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 */
hex_string_to_octet_string(char * raw,char * hex,int len)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 = (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
octet_string_hex_string(const void * s,int length)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 - 1;
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
base64_block_to_octet_triple(char * out,char * in)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] = 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
base64_string_to_octet_string(char * out,int * pad,char * in,int len)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 }
211