File: | lib/x509_b64.c |
Location: | line 240, column 8 |
Description: | Value stored to 'ptr' is never read |
1 | /* |
2 | * Copyright (C) 2000-2012 Free Software Foundation, Inc. |
3 | * |
4 | * Author: Nikos Mavrogiannopoulos |
5 | * |
6 | * This file is part of GnuTLS. |
7 | * |
8 | * The GnuTLS 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 3 of |
11 | * the License, or (at your option) any later version. |
12 | * |
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. |
17 | * |
18 | * You should have received a copy of the GNU Lesser General Public License |
19 | * along with this program. If not, see <http://www.gnu.org/licenses/> |
20 | * |
21 | */ |
22 | |
23 | /* Functions that relate to base64 encoding and decoding. |
24 | */ |
25 | |
26 | #include "gnutls_int.h" |
27 | #include "gnutls_errors.h" |
28 | #include <gnutls_datumgnutls_datum_t.h> |
29 | #include <x509_b64.h> |
30 | |
31 | static const uint8_t b64table[] = |
32 | "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; |
33 | |
34 | static const uint8_t asciitable[128] = { |
35 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, |
36 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, |
37 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, |
38 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, |
39 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, |
40 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, |
41 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, |
42 | 0xff, 0x3e, 0xff, 0xff, 0xff, 0x3f, |
43 | 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, |
44 | 0x3a, 0x3b, 0x3c, 0x3d, 0xff, 0xff, |
45 | 0xff, 0xf1, 0xff, 0xff, 0xff, 0x00, /* 0xf1 for '=' */ |
46 | 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, |
47 | 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, |
48 | 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, |
49 | 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, |
50 | 0x19, 0xff, 0xff, 0xff, 0xff, 0xff, |
51 | 0xff, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, |
52 | 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, |
53 | 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, |
54 | 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, |
55 | 0x31, 0x32, 0x33, 0xff, 0xff, 0xff, |
56 | 0xff, 0xff |
57 | }; |
58 | |
59 | inline static int |
60 | encode (char *result, const uint8_t * data, int left) |
61 | { |
62 | |
63 | int data_len; |
64 | |
65 | if (left > 3) |
66 | data_len = 3; |
67 | else |
68 | data_len = left; |
69 | |
70 | switch (data_len) |
71 | { |
72 | case 3: |
73 | result[0] = b64table[(data[0] >> 2)]; |
74 | result[1] = |
75 | b64table[(((((data[0] & 0x03) & 0xff) << 4) & 0xff) | |
76 | (data[1] >> 4))]; |
77 | result[2] = |
78 | b64table[((((data[1] & 0x0f) << 2) & 0xff) | (data[2] >> 6))]; |
79 | result[3] = b64table[(((data[2] << 2) & 0xff) >> 2)]; |
80 | break; |
81 | case 2: |
82 | result[0] = b64table[(data[0] >> 2)]; |
83 | result[1] = |
84 | b64table[(((((data[0] & 0x03) & 0xff) << 4) & 0xff) | |
85 | (data[1] >> 4))]; |
86 | result[2] = b64table[(((data[1] << 4) & 0xff) >> 2)]; |
87 | result[3] = '='; |
88 | break; |
89 | case 1: |
90 | result[0] = b64table[(data[0] >> 2)]; |
91 | result[1] = b64table[(((((data[0] & 0x03) & 0xff) << 4) & 0xff))]; |
92 | result[2] = '='; |
93 | result[3] = '='; |
94 | break; |
95 | default: |
96 | return -1; |
97 | } |
98 | |
99 | return 4; |
100 | |
101 | } |
102 | |
103 | /* data must be 4 bytes |
104 | * result should be 3 bytes |
105 | */ |
106 | #define TOASCII(c)(c < 127 ? asciitable[c] : 0xff) (c < 127 ? asciitable[c] : 0xff) |
107 | inline static int |
108 | decode (uint8_t * result, const opaque * data) |
109 | { |
110 | uint8_t a1, a2; |
111 | int ret = 3; |
112 | |
113 | a1 = TOASCII (data[0])(data[0] < 127 ? asciitable[data[0]] : 0xff); |
114 | a2 = TOASCII (data[1])(data[1] < 127 ? asciitable[data[1]] : 0xff); |
115 | if (a1 == 0xff || a2 == 0xff) |
116 | return -1; |
117 | result[0] = ((a1 << 2) & 0xff) | ((a2 >> 4) & 0xff); |
118 | |
119 | a1 = a2; |
120 | a2 = TOASCII (data[2])(data[2] < 127 ? asciitable[data[2]] : 0xff); |
121 | if (a2 == 0xff) |
122 | return -1; |
123 | result[1] = ((a1 << 4) & 0xff) | ((a2 >> 2) & 0xff); |
124 | |
125 | a1 = a2; |
126 | a2 = TOASCII (data[3])(data[3] < 127 ? asciitable[data[3]] : 0xff); |
127 | if (a2 == 0xff) |
128 | return -1; |
129 | result[2] = ((a1 << 6) & 0xff) | (a2 & 0xff); |
130 | |
131 | if (data[2] == '=') |
132 | ret--; |
133 | |
134 | if (data[3] == '=') |
135 | ret--; |
136 | return ret; |
137 | } |
138 | |
139 | #define INCR(what, size)do { what+=size; if (what > ret) { do { if (__builtin_expect ((_gnutls_log_level >= 2), 0)) _gnutls_log( 2, "ASSERT: %s:%d\n" , "x509_b64.c",139); } while(0);; gnutls_free( (*result)); *result = ((void*)0); return -59; } } while(0) \ |
140 | do { \ |
141 | what+=size; \ |
142 | if (what > ret) { \ |
143 | gnutls_assert()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "x509_b64.c",143); } while(0);; \ |
144 | gnutls_free( (*result)); *result = NULL((void*)0); \ |
145 | return GNUTLS_E_INTERNAL_ERROR-59; \ |
146 | } \ |
147 | } while(0) |
148 | |
149 | /* encodes data and puts the result into result (locally allocated) |
150 | * The result_size (including the null terminator) is the return value. |
151 | */ |
152 | int |
153 | _gnutls_fbase64_encode (const char *msg, const uint8_t * data, |
154 | int data_size, uint8_t ** result) |
155 | { |
156 | int i, ret, tmp, j; |
157 | char tmpres[4]; |
158 | uint8_t *ptr; |
159 | uint8_t top[80]; |
160 | uint8_t bottom[80]; |
161 | int pos, bytes, top_len, bottom_len; |
162 | |
163 | if (msg == NULL((void*)0) || strlen(msg) > 50) |
164 | { |
165 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "x509_b64.c",165); } while(0);; |
166 | return GNUTLS_E_BASE64_ENCODING_ERROR-201; |
167 | } |
168 | |
169 | _gnutls_str_cpy (top, sizeof(top), "-----BEGIN "); |
170 | _gnutls_str_cat (top, sizeof(top), msg); |
171 | _gnutls_str_cat (top, sizeof(top), "-----"); |
172 | |
173 | _gnutls_str_cpy (bottom, sizeof(bottom), "\n-----END "); |
174 | _gnutls_str_cat (bottom, sizeof(bottom), msg); |
175 | _gnutls_str_cat (bottom, sizeof(bottom), "-----\n"); |
176 | |
177 | top_len = strlen (top); |
178 | bottom_len = strlen (bottom); |
179 | |
180 | ret = B64FSIZE (top_len+bottom_len, data_size)(((data_size%3==0)?((data_size*4)/3):(4 +((data_size/3)*4))) + (top_len+bottom_len) + ((data_size%3==0)?((data_size*4)/3):( 4 +((data_size/3)*4)))/64 + (((((data_size%3==0)?((data_size* 4)/3):(4 +((data_size/3)*4))) % 64) > 0) ? 1 : 0)); |
181 | |
182 | (*result) = gnutls_calloc (1, ret + 1); |
183 | if ((*result) == NULL((void*)0)) |
184 | { |
185 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "x509_b64.c",185); } while(0);; |
186 | return GNUTLS_E_MEMORY_ERROR-25; |
187 | } |
188 | |
189 | bytes = pos = 0; |
190 | INCR (bytes, top_len)do { bytes+=top_len; if (bytes > ret) { do { if (__builtin_expect ((_gnutls_log_level >= 2), 0)) _gnutls_log( 2, "ASSERT: %s:%d\n" , "x509_b64.c",190); } while(0);; gnutls_free( (*result)); *result = ((void*)0); return -59; } } while(0); |
191 | pos = top_len; |
192 | |
193 | memcpy (*result, top, top_len); |
194 | |
195 | for (i = j = 0; i < data_size; i += 3, j += 4) |
196 | { |
197 | |
198 | tmp = encode (tmpres, &data[i], data_size - i); |
199 | if (tmp == -1) |
200 | { |
201 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "x509_b64.c",201); } while(0);; |
202 | gnutls_free ((*result)); |
203 | *result = NULL((void*)0); |
204 | return GNUTLS_E_BASE64_ENCODING_ERROR-201; |
205 | } |
206 | |
207 | INCR (bytes, 4)do { bytes+=4; if (bytes > ret) { do { if (__builtin_expect ((_gnutls_log_level >= 2), 0)) _gnutls_log( 2, "ASSERT: %s:%d\n" , "x509_b64.c",207); } while(0);; gnutls_free( (*result)); *result = ((void*)0); return -59; } } while(0); |
208 | ptr = &(*result)[j + pos]; |
209 | |
210 | if ((j) % 64 == 0) |
211 | { |
212 | INCR (bytes, 1)do { bytes+=1; if (bytes > ret) { do { if (__builtin_expect ((_gnutls_log_level >= 2), 0)) _gnutls_log( 2, "ASSERT: %s:%d\n" , "x509_b64.c",212); } while(0);; gnutls_free( (*result)); *result = ((void*)0); return -59; } } while(0); |
213 | pos++; |
214 | *ptr++ = '\n'; |
215 | } |
216 | *ptr++ = tmpres[0]; |
217 | |
218 | if ((j + 1) % 64 == 0) |
219 | { |
220 | INCR (bytes, 1)do { bytes+=1; if (bytes > ret) { do { if (__builtin_expect ((_gnutls_log_level >= 2), 0)) _gnutls_log( 2, "ASSERT: %s:%d\n" , "x509_b64.c",220); } while(0);; gnutls_free( (*result)); *result = ((void*)0); return -59; } } while(0); |
221 | pos++; |
222 | *ptr++ = '\n'; |
223 | } |
224 | *ptr++ = tmpres[1]; |
225 | |
226 | if ((j + 2) % 64 == 0) |
227 | { |
228 | INCR (bytes, 1)do { bytes+=1; if (bytes > ret) { do { if (__builtin_expect ((_gnutls_log_level >= 2), 0)) _gnutls_log( 2, "ASSERT: %s:%d\n" , "x509_b64.c",228); } while(0);; gnutls_free( (*result)); *result = ((void*)0); return -59; } } while(0); |
229 | pos++; |
230 | *ptr++ = '\n'; |
231 | } |
232 | *ptr++ = tmpres[2]; |
233 | |
234 | if ((j + 3) % 64 == 0) |
235 | { |
236 | INCR (bytes, 1)do { bytes+=1; if (bytes > ret) { do { if (__builtin_expect ((_gnutls_log_level >= 2), 0)) _gnutls_log( 2, "ASSERT: %s:%d\n" , "x509_b64.c",236); } while(0);; gnutls_free( (*result)); *result = ((void*)0); return -59; } } while(0); |
237 | pos++; |
238 | *ptr++ = '\n'; |
239 | } |
240 | *ptr++ = tmpres[3]; |
Value stored to 'ptr' is never read | |
241 | } |
242 | |
243 | INCR (bytes, bottom_len)do { bytes+=bottom_len; if (bytes > ret) { do { if (__builtin_expect ((_gnutls_log_level >= 2), 0)) _gnutls_log( 2, "ASSERT: %s:%d\n" , "x509_b64.c",243); } while(0);; gnutls_free( (*result)); *result = ((void*)0); return -59; } } while(0); |
244 | |
245 | memcpy (&(*result)[bytes - bottom_len], bottom, bottom_len); |
246 | (*result)[bytes] = 0; |
247 | |
248 | return ret + 1; |
249 | } |
250 | |
251 | /** |
252 | * gnutls_pem_base64_encode: |
253 | * @msg: is a message to be put in the header |
254 | * @data: contain the raw data |
255 | * @result: the place where base64 data will be copied |
256 | * @result_size: holds the size of the result |
257 | * |
258 | * This function will convert the given data to printable data, using |
259 | * the base64 encoding. This is the encoding used in PEM messages. |
260 | * |
261 | * The output string will be null terminated, although the size will |
262 | * not include the terminating null. |
263 | * |
264 | * Returns: On success %GNUTLS_E_SUCCESS (0) is returned, |
265 | * %GNUTLS_E_SHORT_MEMORY_BUFFER is returned if the buffer given is |
266 | * not long enough, or 0 on success. |
267 | **/ |
268 | int |
269 | gnutls_pem_base64_encode (const char *msg, const gnutls_datum_t * data, |
270 | char *result, size_t * result_size) |
271 | { |
272 | opaque *ret; |
273 | int size; |
274 | |
275 | size = _gnutls_fbase64_encode (msg, data->data, data->size, &ret); |
276 | if (size < 0) |
277 | return size; |
278 | |
279 | if (result == NULL((void*)0) || *result_size < (unsigned) size) |
280 | { |
281 | gnutls_free (ret); |
282 | *result_size = size; |
283 | return GNUTLS_E_SHORT_MEMORY_BUFFER-51; |
284 | } |
285 | else |
286 | { |
287 | memcpy (result, ret, size); |
288 | gnutls_free (ret); |
289 | *result_size = size - 1; |
290 | } |
291 | |
292 | return 0; |
293 | } |
294 | |
295 | /** |
296 | * gnutls_pem_base64_encode_alloc: |
297 | * @msg: is a message to be put in the encoded header |
298 | * @data: contains the raw data |
299 | * @result: will hold the newly allocated encoded data |
300 | * |
301 | * This function will convert the given data to printable data, using |
302 | * the base64 encoding. This is the encoding used in PEM messages. |
303 | * This function will allocate the required memory to hold the encoded |
304 | * data. |
305 | * |
306 | * You should use gnutls_free() to free the returned data. |
307 | * |
308 | * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise |
309 | * an error code is returned. |
310 | **/ |
311 | int |
312 | gnutls_pem_base64_encode_alloc (const char *msg, |
313 | const gnutls_datum_t * data, |
314 | gnutls_datum_t * result) |
315 | { |
316 | opaque *ret; |
317 | int size; |
318 | |
319 | if (result == NULL((void*)0)) |
320 | return GNUTLS_E_INVALID_REQUEST-50; |
321 | |
322 | size = _gnutls_fbase64_encode (msg, data->data, data->size, &ret); |
323 | if (size < 0) |
324 | return size; |
325 | |
326 | result->data = ret; |
327 | result->size = size - 1; |
328 | return 0; |
329 | } |
330 | |
331 | |
332 | /* decodes data and puts the result into result (locally allocated) |
333 | * The result_size is the return value |
334 | */ |
335 | static int |
336 | _gnutls_base64_decode (const uint8_t * data, size_t data_size, |
337 | uint8_t ** result) |
338 | { |
339 | unsigned int i, j; |
340 | int ret, tmp, est; |
341 | uint8_t tmpres[3]; |
342 | |
343 | est = ((data_size * 3) / 4) + 1; |
344 | (*result) = gnutls_malloc (est); |
345 | if ((*result) == NULL((void*)0)) |
346 | return GNUTLS_E_MEMORY_ERROR-25; |
347 | |
348 | ret = 0; |
349 | for (i = j = 0; i < data_size; i += 4, j += 3) |
350 | { |
351 | tmp = decode (tmpres, &data[i]); |
352 | if (tmp < 0) |
353 | { |
354 | gnutls_free (*result); |
355 | *result = NULL((void*)0); |
356 | return tmp; |
357 | } |
358 | memcpy (&(*result)[j], tmpres, tmp); |
359 | ret += tmp; |
360 | } |
361 | return ret; |
362 | } |
363 | |
364 | /* copies data to result but removes newlines and <CR> |
365 | * returns the size of the data copied. |
366 | */ |
367 | inline static int |
368 | cpydata (const uint8_t * data, int data_size, uint8_t ** result) |
369 | { |
370 | int i, j; |
371 | |
372 | (*result) = gnutls_malloc (data_size); |
373 | if (*result == NULL((void*)0)) |
374 | return GNUTLS_E_MEMORY_ERROR-25; |
375 | |
376 | for (j = i = 0; i < data_size; i++) |
377 | { |
378 | if (data[i] == '\n' || data[i] == '\r' || data[i] == ' ' |
379 | || data[i] == '\t') |
380 | continue; |
381 | (*result)[j] = data[i]; |
382 | j++; |
383 | } |
384 | return j; |
385 | } |
386 | |
387 | /* Searches the given string for ONE PEM encoded certificate, and |
388 | * stores it in the result. |
389 | * |
390 | * The result_size is the return value |
391 | */ |
392 | #define ENDSTR"-----" "-----" |
393 | int |
394 | _gnutls_fbase64_decode (const char *header, const opaque * data, |
395 | size_t data_size, uint8_t ** result) |
396 | { |
397 | int ret; |
398 | static const char top[] = "-----BEGIN "; |
399 | static const char bottom[] = "-----END "; |
400 | uint8_t *rdata; |
401 | int rdata_size; |
402 | uint8_t *kdata; |
403 | int kdata_size; |
404 | char pem_header[128]; |
405 | |
406 | _gnutls_str_cpy (pem_header, sizeof (pem_header), top); |
407 | if (header != NULL((void*)0)) |
408 | _gnutls_str_cat (pem_header, sizeof (pem_header), header); |
409 | |
410 | rdata = memmemrpl_memmem (data, data_size, pem_header, strlen (pem_header)); |
411 | |
412 | if (rdata == NULL((void*)0)) |
413 | { |
414 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "x509_b64.c",414); } while(0);; |
415 | _gnutls_debug_log ("Could not find '%s'\n", pem_header)do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "Could not find '%s'\n", pem_header); } while(0); |
416 | return GNUTLS_E_BASE64_UNEXPECTED_HEADER_ERROR-207; |
417 | } |
418 | |
419 | data_size -= (unsigned long int) rdata - (unsigned long int) data; |
420 | |
421 | if (data_size < 4 + strlen (bottom)) |
422 | { |
423 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "x509_b64.c",423); } while(0);; |
424 | return GNUTLS_E_BASE64_DECODING_ERROR-34; |
425 | } |
426 | |
427 | kdata = memmemrpl_memmem (rdata + 1, data_size - 1, ENDSTR"-----", sizeof (ENDSTR"-----") - 1); |
428 | /* allow CR as well. |
429 | */ |
430 | if (kdata == NULL((void*)0)) |
431 | { |
432 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "x509_b64.c",432); } while(0);; |
433 | _gnutls_debug_log ("Could not find '%s'\n", ENDSTR)do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "Could not find '%s'\n", "-----"); } while(0); |
434 | return GNUTLS_E_BASE64_DECODING_ERROR-34; |
435 | } |
436 | data_size -= strlen (ENDSTR"-----"); |
437 | data_size -= (unsigned long int) kdata - (unsigned long int) rdata; |
438 | |
439 | rdata = kdata + strlen (ENDSTR"-----"); |
440 | |
441 | /* position is now after the ---BEGIN--- headers */ |
442 | |
443 | kdata = memmemrpl_memmem (rdata, data_size, bottom, strlen (bottom)); |
444 | if (kdata == NULL((void*)0)) |
445 | { |
446 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "x509_b64.c",446); } while(0);; |
447 | return GNUTLS_E_BASE64_DECODING_ERROR-34; |
448 | } |
449 | |
450 | /* position of kdata is before the ----END--- footer |
451 | */ |
452 | rdata_size = (unsigned long int) kdata - (unsigned long int) rdata; |
453 | |
454 | if (rdata_size < 4) |
455 | { |
456 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "x509_b64.c",456); } while(0);; |
457 | return GNUTLS_E_BASE64_DECODING_ERROR-34; |
458 | } |
459 | |
460 | kdata_size = cpydata (rdata, rdata_size, &kdata); |
461 | |
462 | if (kdata_size < 0) |
463 | { |
464 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "x509_b64.c",464); } while(0);; |
465 | return kdata_size; |
466 | } |
467 | |
468 | if (kdata_size < 4) |
469 | { |
470 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "x509_b64.c",470); } while(0);; |
471 | gnutls_free (kdata); |
472 | return GNUTLS_E_BASE64_DECODING_ERROR-34; |
473 | } |
474 | |
475 | if ((ret = _gnutls_base64_decode (kdata, kdata_size, result)) < 0) |
476 | { |
477 | gnutls_free (kdata); |
478 | gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log ( 2, "ASSERT: %s:%d\n", "x509_b64.c",478); } while(0);; |
479 | return GNUTLS_E_BASE64_DECODING_ERROR-34; |
480 | } |
481 | gnutls_free (kdata); |
482 | |
483 | return ret; |
484 | } |
485 | |
486 | /** |
487 | * gnutls_pem_base64_decode: |
488 | * @header: A null terminated string with the PEM header (eg. CERTIFICATE) |
489 | * @b64_data: contain the encoded data |
490 | * @result: the place where decoded data will be copied |
491 | * @result_size: holds the size of the result |
492 | * |
493 | * This function will decode the given encoded data. If the header |
494 | * given is non null this function will search for "-----BEGIN header" |
495 | * and decode only this part. Otherwise it will decode the first PEM |
496 | * packet found. |
497 | * |
498 | * Returns: On success %GNUTLS_E_SUCCESS (0) is returned, |
499 | * %GNUTLS_E_SHORT_MEMORY_BUFFER is returned if the buffer given is |
500 | * not long enough, or 0 on success. |
501 | **/ |
502 | int |
503 | gnutls_pem_base64_decode (const char *header, |
504 | const gnutls_datum_t * b64_data, |
505 | unsigned char *result, size_t * result_size) |
506 | { |
507 | opaque *ret; |
508 | int size; |
509 | |
510 | size = |
511 | _gnutls_fbase64_decode (header, b64_data->data, b64_data->size, &ret); |
512 | if (size < 0) |
513 | return size; |
514 | |
515 | if (result == NULL((void*)0) || *result_size < (unsigned) size) |
516 | { |
517 | gnutls_free (ret); |
518 | *result_size = size; |
519 | return GNUTLS_E_SHORT_MEMORY_BUFFER-51; |
520 | } |
521 | else |
522 | { |
523 | memcpy (result, ret, size); |
524 | gnutls_free (ret); |
525 | *result_size = size; |
526 | } |
527 | |
528 | return 0; |
529 | } |
530 | |
531 | /** |
532 | * gnutls_pem_base64_decode_alloc: |
533 | * @header: The PEM header (eg. CERTIFICATE) |
534 | * @b64_data: contains the encoded data |
535 | * @result: the place where decoded data lie |
536 | * |
537 | * This function will decode the given encoded data. The decoded data |
538 | * will be allocated, and stored into result. If the header given is |
539 | * non null this function will search for "-----BEGIN header" and |
540 | * decode only this part. Otherwise it will decode the first PEM |
541 | * packet found. |
542 | * |
543 | * You should use gnutls_free() to free the returned data. |
544 | * |
545 | * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise |
546 | * an error code is returned. |
547 | **/ |
548 | int |
549 | gnutls_pem_base64_decode_alloc (const char *header, |
550 | const gnutls_datum_t * b64_data, |
551 | gnutls_datum_t * result) |
552 | { |
553 | opaque *ret; |
554 | int size; |
555 | |
556 | if (result == NULL((void*)0)) |
557 | return GNUTLS_E_INVALID_REQUEST-50; |
558 | |
559 | size = |
560 | _gnutls_fbase64_decode (header, b64_data->data, b64_data->size, &ret); |
561 | if (size < 0) |
562 | return size; |
563 | |
564 | result->data = ret; |
565 | result->size = size; |
566 | return 0; |
567 | } |