added a chunk_printable() function (replaces sanitize_chunk)
[strongswan.git] / src / libstrongswan / chunk.h
1 /*
2 * Copyright (C) 2008-2009 Tobias Brunner
3 * Copyright (C) 2005-2008 Martin Willi
4 * Copyright (C) 2005 Jan Hutter
5 * Hochschule fuer Technik Rapperswil
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 * for more details.
16 */
17
18 /**
19 * @defgroup chunk chunk
20 * @{ @ingroup libstrongswan
21 */
22
23 #ifndef CHUNK_H_
24 #define CHUNK_H_
25
26 #include <string.h>
27 #include <stdarg.h>
28 #include <sys/types.h>
29
30 typedef struct chunk_t chunk_t;
31
32 /**
33 * General purpose pointer/length abstraction.
34 */
35 struct chunk_t {
36 /** Pointer to start of data */
37 u_char *ptr;
38 /** Length of data in bytes */
39 size_t len;
40 };
41
42 #include <utils.h>
43
44 /**
45 * A { NULL, 0 }-chunk handy for initialization.
46 */
47 extern chunk_t chunk_empty;
48
49 /**
50 * Create a new chunk pointing to "ptr" with length "len"
51 */
52 static inline chunk_t chunk_create(u_char *ptr, size_t len)
53 {
54 chunk_t chunk = {ptr, len};
55 return chunk;
56 }
57
58 /**
59 * Create a clone of a chunk pointing to "ptr"
60 */
61 chunk_t chunk_create_clone(u_char *ptr, chunk_t chunk);
62
63 /**
64 * Calculate length of multiple chunks
65 */
66 size_t chunk_length(const char *mode, ...);
67
68 /**
69 * Concatenate chunks into a chunk pointing to "ptr",
70 * "mode" is a string of "c" (copy) and "m" (move), which says
71 * how to handle the chunks in "..."
72 */
73 chunk_t chunk_create_cat(u_char *ptr, const char* mode, ...);
74
75 /**
76 * Split up a chunk into parts, "mode" is a string of "a" (alloc),
77 * "c" (copy) and "m" (move). Each letter say for the corresponding chunk if
78 * it should get allocated on heap, copied into existing chunk, or the chunk
79 * should point into "chunk". The length of each part is an argument before
80 * each target chunk. E.g.:
81 * chunk_split(chunk, "mcac", 3, &a, 7, &b, 5, &c, d.len, &d);
82 */
83 void chunk_split(chunk_t chunk, const char *mode, ...);
84
85 /**
86 * Write the binary contents of a chunk_t to a file
87 *
88 * @param path path where file is written to
89 * @param label label specifying file type
90 * @param mask file mode creation mask
91 * @param force overwrite existing file by force
92 * @return TRUE if write operation was successful
93 */
94 bool chunk_write(chunk_t chunk, char *path, char *label, mode_t mask, bool force);
95
96 /**
97 * Convert a chunk of data to hex encoding.
98 *
99 * The resulting string is '\\0' terminated, but the chunk does not include
100 * the '\\0'. If buf is supplied, it must hold at least (chunk.len * 2 + 1).
101 *
102 * @param buf buffer to write to, NULL to malloc
103 * @param uppercase TRUE to use uppercase letters
104 * @return chunk of encoded data
105 */
106 chunk_t chunk_to_hex(chunk_t chunk, char *buf, bool uppercase);
107
108 /**
109 * Convert a hex encoded in a binary chunk.
110 *
111 * If buf is supplied, it must hold at least (hex.len / 2) + (hex.len % 2)
112 * bytes. It is filled by the right to give correct values for short inputs.
113 *
114 * @param hex hex encoded input data
115 * @param buf buffer to write decoded data, NULL to malloc
116 * @return converted data
117 */
118 chunk_t chunk_from_hex(chunk_t hex, char *buf);
119
120 /**
121 * Convert a chunk of data to its base64 encoding.
122 *
123 * The resulting string is '\\0' terminated, but the chunk does not include
124 * the '\\0'. If buf is supplied, it must hold at least (chunk.len * 4 / 3 + 1).
125 *
126 * @param chunk data to convert
127 * @param buf buffer to write to, NULL to malloc
128 * @return chunk of encoded data
129 */
130 chunk_t chunk_to_base64(chunk_t chunk, char *buf);
131
132 /**
133 * Convert a base64 in a binary chunk.
134 *
135 * If buf is supplied, it must hold at least (base64.len / 4 * 3).
136 *
137 * @param base64 base64 encoded input data
138 * @param buf buffer to write decoded data, NULL to malloc
139 * @return converted data
140 */
141 chunk_t chunk_from_base64(chunk_t base64, char *buf);
142
143 /**
144 * Free contents of a chunk
145 */
146 static inline void chunk_free(chunk_t *chunk)
147 {
148 free(chunk->ptr);
149 *chunk = chunk_empty;
150 }
151
152 /**
153 * Overwrite the contents of a chunk and free it
154 */
155 static inline void chunk_clear(chunk_t *chunk)
156 {
157 if (chunk->ptr)
158 {
159 memset(chunk->ptr, 0, chunk->len);
160 chunk_free(chunk);
161 }
162 }
163
164 /**
165 * Initialize a chunk to point to buffer inspectable by sizeof()
166 */
167 #define chunk_from_buf(str) { str, sizeof(str) }
168
169 /**
170 * Initialize a chunk to point to a thing
171 */
172 #define chunk_from_thing(thing) chunk_create((char*)&(thing), sizeof(thing))
173
174 /**
175 * Allocate a chunk on the heap
176 */
177 #define chunk_alloc(bytes) chunk_create(malloc(bytes), bytes)
178
179 /**
180 * Allocate a chunk on the stack
181 */
182 #define chunk_alloca(bytes) chunk_create(alloca(bytes), bytes)
183
184 /**
185 * Clone a chunk on heap
186 */
187 #define chunk_clone(chunk) chunk_create_clone((chunk).len ? malloc((chunk).len) : NULL, chunk)
188
189 /**
190 * Clone a chunk on stack
191 */
192 #define chunk_clonea(chunk) chunk_create_clone(alloca((chunk).len), chunk)
193
194 /**
195 * Concatenate chunks into a chunk on heap
196 */
197 #define chunk_cat(mode, ...) chunk_create_cat(malloc(chunk_length(mode, __VA_ARGS__)), mode, __VA_ARGS__)
198
199 /**
200 * Concatenate chunks into a chunk on stack
201 */
202 #define chunk_cata(mode, ...) chunk_create_cat(alloca(chunk_length(mode, __VA_ARGS__)), mode, __VA_ARGS__)
203
204 /**
205 * Skip n bytes in chunk (forward pointer, shorten length)
206 */
207 static inline chunk_t chunk_skip(chunk_t chunk, size_t bytes)
208 {
209 if (chunk.len > bytes)
210 {
211 chunk.ptr += bytes;
212 chunk.len -= bytes;
213 return chunk;
214 }
215 return chunk_empty;
216 }
217
218 /**
219 * Compare two chunks, returns zero if a equals b
220 * or negative/positive if a is small/greater than b
221 */
222 int chunk_compare(chunk_t a, chunk_t b);
223
224 /**
225 * Compare two chunks for equality,
226 * NULL chunks are never equal.
227 */
228 static inline bool chunk_equals(chunk_t a, chunk_t b)
229 {
230 return a.ptr != NULL && b.ptr != NULL &&
231 a.len == b.len && memeq(a.ptr, b.ptr, a.len);
232 }
233
234 /**
235 * Check if a chunk has printable characters only.
236 *
237 * If sane is given, chunk is cloned into sane and all non printable characters
238 * get replaced by "replace".
239 *
240 * @param chunk chunk to check for printability
241 * @param sane pointer where sane version is allocated, or NULL
242 * @param replace character to use for replaceing unprintable characters
243 * @return TRUE if all characters in chunk are printable
244 */
245 bool chunk_printable(chunk_t chunk, chunk_t *sane, char replace);
246
247 /**
248 * Computes a 32 bit hash of the given chunk.
249 * Note: This hash is only intended for hash tables not for cryptographic purposes.
250 */
251 u_int32_t chunk_hash(chunk_t chunk);
252
253 /**
254 * Incremental version of chunk_hash. Use this to hash two or more chunks.
255 */
256 u_int32_t chunk_hash_inc(chunk_t chunk, u_int32_t hash);
257
258 /**
259 * printf hook function for chunk_t.
260 *
261 * Arguments are:
262 * chunk_t *chunk
263 * Use #-modifier to print a compact version
264 */
265 int chunk_printf_hook(char *dst, size_t len, printf_hook_spec_t *spec,
266 const void *const *args);
267
268 #endif /** CHUNK_H_ @}*/