• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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