2 * Copyright (C) 2002, 2004, 2005, 2007, 2008 Free Software Foundation
4 * Author: Nikos Mavrogiannopoulos
6 * This file is part of GNUTLS.
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
25 #include <gnutls_int.h>
26 #include <gnutls_errors.h>
27 #include <gnutls_num.h>
28 #include <gnutls_str.h>
30 /* These function are like strcat, strcpy. They only
31 * do bound checking (they shouldn't cause buffer overruns),
32 * and they always produce null terminated strings.
34 * They should be used only with null terminated strings.
37 _gnutls_str_cat (char *dest
, size_t dest_tot_size
, const char *src
)
39 size_t str_size
= strlen (src
);
40 size_t dest_size
= strlen (dest
);
42 if (dest_tot_size
- dest_size
> str_size
)
48 if (dest_tot_size
- dest_size
> 0)
50 strncat (dest
, src
, (dest_tot_size
- dest_size
) - 1);
51 dest
[dest_tot_size
- 1] = 0;
57 _gnutls_str_cpy (char *dest
, size_t dest_tot_size
, const char *src
)
59 size_t str_size
= strlen (src
);
61 if (dest_tot_size
> str_size
)
67 if (dest_tot_size
> 0)
69 strncpy (dest
, src
, (dest_tot_size
) - 1);
70 dest
[dest_tot_size
- 1] = 0;
76 _gnutls_mem_cpy (char *dest
, size_t dest_tot_size
, const char *src
,
80 if (dest_tot_size
>= src_size
)
82 memcpy (dest
, src
, src_size
);
86 if (dest_tot_size
> 0)
88 memcpy (dest
, src
, dest_tot_size
);
94 _gnutls_string_init (gnutls_string
* str
,
95 gnutls_alloc_function alloc_func
,
96 gnutls_realloc_function realloc_func
,
97 gnutls_free_function free_func
)
103 str
->alloc_func
= alloc_func
;
104 str
->free_func
= free_func
;
105 str
->realloc_func
= realloc_func
;
109 _gnutls_string_clear (gnutls_string
* str
)
111 if (str
== NULL
|| str
->data
== NULL
)
113 str
->free_func (str
->data
);
120 /* This one does not copy the string.
123 _gnutls_string2datum (gnutls_string
* str
)
127 ret
.data
= str
->data
;
128 ret
.size
= str
->length
;
133 #define MIN_CHUNK 256
136 _gnutls_string_copy_str (gnutls_string
* dest
, const char *src
)
138 size_t src_len
= strlen (src
);
140 if (dest
->max_length
>= src_len
)
142 memcpy (dest
->data
, src
, src_len
);
143 dest
->length
= src_len
;
149 dest
->data
= dest
->realloc_func (dest
->data
, MAX (src_len
, MIN_CHUNK
));
150 if (dest
->data
== NULL
)
153 return GNUTLS_E_MEMORY_ERROR
;
155 dest
->max_length
= MAX (MIN_CHUNK
, src_len
);
157 memcpy (dest
->data
, src
, src_len
);
158 dest
->length
= src_len
;
165 _gnutls_string_append_str (gnutls_string
* dest
, const char *src
)
167 size_t src_len
= strlen (src
);
168 size_t tot_len
= src_len
+ dest
->length
;
170 if (dest
->max_length
>= tot_len
)
172 memcpy (&dest
->data
[dest
->length
], src
, src_len
);
173 dest
->length
= tot_len
;
180 MAX (src_len
, MIN_CHUNK
) + MAX (dest
->max_length
, MIN_CHUNK
);
182 dest
->data
= dest
->realloc_func (dest
->data
, new_len
);
183 if (dest
->data
== NULL
)
186 return GNUTLS_E_MEMORY_ERROR
;
188 dest
->max_length
= new_len
;
190 memcpy (&dest
->data
[dest
->length
], src
, src_len
);
191 dest
->length
= tot_len
;
198 _gnutls_string_append_data (gnutls_string
* dest
, const void *data
,
201 size_t tot_len
= data_size
+ dest
->length
;
203 if (dest
->max_length
>= tot_len
)
205 memcpy (&dest
->data
[dest
->length
], data
, data_size
);
206 dest
->length
= tot_len
;
213 MAX (data_size
, MIN_CHUNK
) + MAX (dest
->max_length
, MIN_CHUNK
);
215 dest
->data
= dest
->realloc_func (dest
->data
, new_len
);
216 if (dest
->data
== NULL
)
219 return GNUTLS_E_MEMORY_ERROR
;
221 dest
->max_length
= new_len
;
223 memcpy (&dest
->data
[dest
->length
], data
, data_size
);
224 dest
->length
= tot_len
;
231 _gnutls_string_append_printf (gnutls_string
* dest
, const char *fmt
, ...)
237 va_start (args
, fmt
);
238 len
= vasprintf (&str
, fmt
, args
);
244 len
= _gnutls_string_append_str (dest
, str
);
251 /* Converts the given string (old) to hex. A buffer must be provided
252 * to hold the new hex string. The new string will be null terminated.
253 * If the buffer does not have enough space to hold the string, a
254 * truncated hex string is returned (always null terminated).
257 _gnutls_bin2hex (const void *_old
, size_t oldlen
,
258 char *buffer
, size_t buffer_size
)
261 const opaque
*old
= _old
;
263 for (i
= j
= 0; i
< oldlen
&& j
+ 2 < buffer_size
; j
+= 2)
265 sprintf (&buffer
[j
], "%.2x", old
[i
]);
274 * gnutls_hex2bin - convert hex string into binary buffer.
275 * @hex_data: string with data in hex format
276 * @hex_size: size of hex data
277 * @bin_data: output array with binary data
278 * @bin_size: when calling *@bin_size should hold size of @bin_data,
279 * on return will hold actual size of @bin_data.
281 * Convert a buffer with hex data to binary data.
283 * Returns: %GNUTLS_E_SUCCESS on success, otherwise an error.
286 gnutls_hex2bin (const char * hex_data
,
291 return _gnutls_hex2bin (hex_data
, (int)hex_size
, bin_data
, bin_size
);
295 _gnutls_hex2bin (const opaque
* hex_data
, int hex_size
, opaque
* bin_data
,
302 /* FIXME: we don't handle whitespace.
306 if (*bin_size
< (size_t) hex_size
)
309 return GNUTLS_E_SHORT_MEMORY_BUFFER
;
312 for (i
= j
= 0; j
< hex_size
; i
+= 2, j
++)
314 hex2_data
[0] = hex_data
[i
];
315 hex2_data
[1] = hex_data
[i
+ 1];
317 val
= strtoul ((char *) hex2_data
, NULL
, 16);
318 if (val
== ULONG_MAX
)
321 return GNUTLS_E_SRP_PWD_PARSING_ERROR
;
330 /* compare hostname against certificate, taking account of wildcards
331 * return 1 on success or 0 on error
334 _gnutls_hostname_compare (const char *certname
, const char *hostname
)
336 const char *cmpstr1
, *cmpstr2
;
338 if (strlen (certname
) == 0 || strlen (hostname
) == 0)
341 if (strlen (certname
) > 2 && strncmp (certname
, "*.", 2) == 0)
343 /* a wildcard certificate */
345 cmpstr1
= certname
+ 1;
347 /* find the first dot in hostname, compare from there on */
348 cmpstr2
= strchr (hostname
, '.');
352 /* error, the hostname we're connecting to is only a local part */
356 if (strcasecmp (cmpstr1
, cmpstr2
) == 0)
364 if (strcasecmp (certname
, hostname
) == 0)