Bug Summary

File:libpskc/parser.c
Location:line 50, column 8
Description:Null pointer passed as an argument to a 'nonnull' parameter

Annotated Source Code

1/*
2 * parser.c - Parse PSKC data structure in XML and convert to internal format.
3 * Copyright (C) 2012-2013 Simon Josefsson
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public License
7 * as published by the Free Software Foundation; either version 2.1 of
8 * the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18 * 02110-1301 USA
19 *
20 */
21
22#include <config.h>
23
24#include <pskc/pskc.h>
25
26#define INTERNAL_NEED_PSKC_STRUCT
27#define INTERNAL_NEED_PSKC_KEY_STRUCT
28#include "internal.h"
29
30#include <string.h>
31#include "base64.h"
32
33static void
34parse_deviceinfo (xmlNode * x, struct pskc_key *kp, int *rc)
35{
36 xmlNode *cur_node = NULL((void*)0);
37
38 for (cur_node = x; cur_node; cur_node = cur_node->next)
1
Loop condition is true. Entering loop body
12
Loop condition is true. Entering loop body
39 {
40 const char *name = (const char *) cur_node->name;
41 const char *content = (const char *)
42 (cur_node->children ? cur_node->children->content : NULL((void*)0));
2
'?' condition is false
13
'?' condition is false
43
44 if (cur_node->type != XML_ELEMENT_NODE)
3
Taking false branch
14
Taking false branch
45 continue;
46
47 if (strcmp ("Manufacturer", name) == 0)
4
Taking false branch
15
Taking true branch
48 {
49 kp->device_manufacturer = content;
50 if (strncmp ("oath.", content, 5) != 0
16
Null pointer passed as an argument to a 'nonnull' parameter
51 && strncmp ("iana.", content, 5) != 0)
52 _pskc_debug ("non-compliant Manufacturer value: %s", content);
53 }
54 else if (strcmp ("SerialNo", name) == 0)
5
Taking false branch
55 kp->device_serialno = content;
56 else if (strcmp ("Model", name) == 0)
6
Taking false branch
57 kp->device_model = content;
58 else if (strcmp ("IssueNo", name) == 0)
7
Taking false branch
59 kp->device_issueno = content;
60 else if (strcmp ("DeviceBinding", name) == 0)
8
Taking false branch
61 kp->device_devicebinding = content;
62 else if (strcmp ("StartDate", name) == 0)
9
Taking false branch
63 {
64 const char *p;
65 kp->device_startdate_str = content;
66 memset (&kp->device_startdate, 0, sizeof(struct tm));
67 p = strptime (kp->device_startdate_str,
68 "%Y-%m-%dT%H:%M:%SZ", &kp->device_startdate);
69 if (p == NULL((void*)0) || *p != '\0')
70 {
71 _pskc_debug ("cannot convert time string '%s'",
72 kp->device_startdate_str);
73 *rc = PSKC_PARSE_ERROR;
74 }
75 }
76 else if (strcmp ("ExpiryDate", name) == 0)
10
Taking false branch
77 {
78 const char *p;
79 kp->device_expirydate_str = content;
80 memset (&kp->device_expirydate, 0, sizeof(struct tm));
81 p = strptime (kp->device_expirydate_str,
82 "%Y-%m-%dT%H:%M:%SZ", &kp->device_expirydate);
83 if (p == NULL((void*)0) || *p != '\0')
84 {
85 _pskc_debug ("cannot convert time string '%s'",
86 kp->device_expirydate_str);
87 *rc = PSKC_PARSE_ERROR;
88 }
89 }
90 else if (strcmp ("UserId", name) == 0)
11
Taking false branch
91 kp->device_userid = content;
92 else
93 {
94 _pskc_debug ("unknown <%s> element <%s>", x->parent->name, name);
95 *rc = PSKC_PARSE_ERROR;
96 }
97 }
98}
99
100static void
101parse_cryptomoduleinfo (xmlNode * x, struct pskc_key *kp, int *rc)
102{
103 xmlNode *cur_node = NULL((void*)0);
104
105 for (cur_node = x; cur_node; cur_node = cur_node->next)
106 {
107 const char *name = (const char *) cur_node->name;
108 const char *content = (const char *)
109 (cur_node->children ? cur_node->children->content : NULL((void*)0));
110
111 if (cur_node->type != XML_ELEMENT_NODE)
112 continue;
113
114 if (strcmp ("Id", name) == 0)
115 kp->cryptomodule_id = content;
116 else
117 {
118 _pskc_debug ("unknown <%s> element <%s>", x->parent->name, name);
119 *rc = PSKC_PARSE_ERROR;
120 }
121 }
122}
123
124static void
125parse_intlongstrdatatype (xmlNode * x, const char **var, int *rc)
126{
127 xmlNode *cur_node = NULL((void*)0);
128
129 *var = NULL((void*)0);
130
131 for (cur_node = x; cur_node; cur_node = cur_node->next)
132 {
133 const char *name = (const char *) cur_node->name;
134 const char *content = (const char *)
135 (cur_node->children ? cur_node->children->content : NULL((void*)0));
136
137 if (cur_node->type != XML_ELEMENT_NODE)
138 continue;
139
140 if (strcmp ("PlainValue", name) == 0)
141 *var = content;
142 else
143 {
144 _pskc_debug ("unknown <%s> element <%s>", x->parent->name, name);
145 *rc = PSKC_PARSE_ERROR;
146 }
147 }
148}
149
150static char *
151remove_whitespace (const char *str, size_t *outlen)
152{
153 size_t len = strlen (str);
154 char *out = malloc (len + 1);
155 size_t i, j;
156
157 if (out == NULL((void*)0))
158 return NULL((void*)0);
159
160 for (i = 0, j = 0; i < len; i++)
161 if (isbase64 (str[i]) || str[i] == '=')
162 out[j++] = str[i];
163
164 out[j] = '\0';
165
166 *outlen = j;
167
168 return out;
169}
170
171static void
172parse_data (xmlNode * x, struct pskc_key *kp, int *rc)
173{
174 xmlNode *cur_node = NULL((void*)0);
175
176 for (cur_node = x; cur_node; cur_node = cur_node->next)
177 {
178 const char *name = (const char *) cur_node->name;
179
180 if (cur_node->type != XML_ELEMENT_NODE)
181 continue;
182
183 if (strcmp ("Secret", name) == 0)
184 {
185 parse_intlongstrdatatype (cur_node->children,
186 &kp->key_secret_str, rc);
187 if (kp->key_secret_str)
188 {
189 bool_Bool ok;
190 size_t l;
191
192 kp->key_b64secret = remove_whitespace (kp->key_secret_str, &l);
193 if (kp->key_b64secret == NULL((void*)0))
194 {
195 _pskc_debug ("base64 whitespace malloc failed");
196 *rc = PSKC_MALLOC_ERROR;
197 }
198 else
199 {
200 ok = base64_decode_alloc (kp->key_b64secret, l,base64_decode_alloc_ctx (((void*)0), kp->key_b64secret, l,
&kp->key_secret, &kp->key_secret_len)
201 &kp->key_secret,base64_decode_alloc_ctx (((void*)0), kp->key_b64secret, l,
&kp->key_secret, &kp->key_secret_len)
202 &kp->key_secret_len)base64_decode_alloc_ctx (((void*)0), kp->key_b64secret, l,
&kp->key_secret, &kp->key_secret_len)
;
203 if (!ok)
204 {
205 _pskc_debug ("base64 decoding failed");
206 *rc = PSKC_BASE64_ERROR;
207 }
208 if (kp->key_secret == NULL((void*)0))
209 {
210 _pskc_debug ("base64 malloc failed");
211 *rc = PSKC_MALLOC_ERROR;
212 }
213 }
214 }
215 }
216 else if (strcmp ("Counter", name) == 0)
217 {
218 parse_intlongstrdatatype (cur_node->children,
219 &kp->key_counter_str, rc);
220 if (kp->key_counter_str)
221 kp->key_counter = strtoull (kp->key_counter_str, NULL((void*)0), 10);
222 }
223 else if (strcmp ("Time", name) == 0)
224 {
225 parse_intlongstrdatatype (cur_node->children,
226 &kp->key_time_str, rc);
227 if (kp->key_time_str)
228 kp->key_time = strtoul (kp->key_time_str, NULL((void*)0), 10);
229 }
230 else if (strcmp ("TimeInterval", name) == 0)
231 {
232 parse_intlongstrdatatype (cur_node->children,
233 &kp->key_timeinterval_str, rc);
234 if (kp->key_timeinterval_str)
235 kp->key_timeinterval = strtoul (kp->key_timeinterval_str,
236 NULL((void*)0), 10);
237 }
238 else if (strcmp ("TimeDrift", name) == 0)
239 {
240 parse_intlongstrdatatype (cur_node->children,
241 &kp->key_timedrift_str, rc);
242 if (kp->key_timedrift_str)
243 kp->key_timedrift = strtoul (kp->key_timedrift_str, NULL((void*)0), 10);
244 }
245 else
246 {
247 _pskc_debug ("unknown <%s> element <%s>", x->parent->name, name);
248 *rc = PSKC_PARSE_ERROR;
249 }
250 }
251}
252
253static void
254parse_algorithmparameters (xmlNode * x, struct pskc_key *kp, int *rc)
255{
256 xmlNode *cur_node = NULL((void*)0);
257
258 for (cur_node = x; cur_node; cur_node = cur_node->next)
259 {
260 const char *name = (const char *) cur_node->name;
261 const char *content = (const char *)
262 (cur_node->children ? cur_node->children->content : NULL((void*)0));
263
264 if (cur_node->type != XML_ELEMENT_NODE)
265 continue;
266
267 if (strcmp ("Suite", name) == 0)
268 kp->key_algparm_suite = content;
269 else if (strcmp ("ChallengeFormat", name) == 0)
270 {
271 xmlAttr *cur_attr = NULL((void*)0);
272
273 for (cur_attr = cur_node->properties; cur_attr;
274 cur_attr = cur_attr->next)
275 {
276 const char *attr_name = (const char *) cur_attr->name;
277 const char *attr_content =
278 (const char *) cur_attr->children->content;
279
280 if (strcmp ("Encoding", attr_name) == 0)
281 {
282 kp->key_algparm_chall_encoding_str = attr_content;
283 kp->key_algparm_chall_encoding =
284 pskc_str2valueformat
285 (kp->key_algparm_chall_encoding_str);
286 }
287 else if (strcmp ("Min", attr_name) == 0)
288 {
289 kp->key_algparm_chall_min_str = attr_content;
290 kp->key_algparm_chall_min =
291 strtoul (kp->key_algparm_chall_min_str, NULL((void*)0), 10);
292 }
293 else if (strcmp ("Max", attr_name) == 0)
294 {
295 kp->key_algparm_chall_max_str = attr_content;
296 kp->key_algparm_chall_max =
297 strtoul (kp->key_algparm_chall_max_str, NULL((void*)0), 10);
298 }
299 else if (strcmp ("CheckDigits", attr_name) == 0)
300 {
301 kp->key_algparm_chall_checkdigits_str = attr_content;
302 if (strcmp ("1", kp->key_algparm_chall_checkdigits_str) == 0)
303 kp->key_algparm_chall_checkdigits = 1;
304 else if (strcmp ("true",
305 kp->key_algparm_chall_checkdigits_str) == 0)
306 kp->key_algparm_chall_checkdigits = 1;
307 else
308 kp->key_algparm_chall_checkdigits = 0;
309 }
310 else
311 {
312 _pskc_debug ("unknown <%s> attribute <%s>",
313 name, attr_name);
314 *rc = PSKC_PARSE_ERROR;
315 }
316 }
317 }
318 else if (strcmp ("ResponseFormat", name) == 0)
319 {
320 xmlAttr *cur_attr = NULL((void*)0);
321
322 for (cur_attr = cur_node->properties; cur_attr;
323 cur_attr = cur_attr->next)
324 {
325 const char *attr_name = (const char *) cur_attr->name;
326 const char *attr_content =
327 (const char *) cur_attr->children->content;
328
329 if (strcmp ("Encoding", attr_name) == 0)
330 {
331 kp->key_algparm_resp_encoding_str = attr_content;
332 kp->key_algparm_resp_encoding =
333 pskc_str2valueformat
334 (kp->key_algparm_resp_encoding_str);
335 }
336 else if (strcmp ("Length", attr_name) == 0)
337 {
338 kp->key_algparm_resp_length_str = attr_content;
339 kp->key_algparm_resp_length =
340 strtoul (kp->key_algparm_resp_length_str, NULL((void*)0), 10);
341 }
342 else if (strcmp ("CheckDigits", attr_name) == 0)
343 {
344 kp->key_algparm_resp_checkdigits_str = attr_content;
345 if (strcmp ("1", kp->key_algparm_resp_checkdigits_str) == 0)
346 kp->key_algparm_resp_checkdigits = 1;
347 else if (strcmp ("true",
348 kp->key_algparm_resp_checkdigits_str) == 0)
349 kp->key_algparm_resp_checkdigits = 1;
350 else
351 kp->key_algparm_resp_checkdigits = 0;
352 }
353 else
354 {
355 _pskc_debug ("unknown <%s> attribute <%s>",
356 name, attr_name);
357 *rc = PSKC_PARSE_ERROR;
358 }
359 }
360 }
361 else
362 {
363 _pskc_debug ("unknown <%s> element <%s>", x->parent->name, name);
364 *rc = PSKC_PARSE_ERROR;
365 }
366 }
367}
368
369static void
370parse_policy (xmlNode * x, struct pskc_key *kp, int *rc)
371{
372 xmlNode *cur_node = NULL((void*)0);
373
374 for (cur_node = x; cur_node; cur_node = cur_node->next)
375 {
376 const char *name = (const char *) cur_node->name;
377 const char *content = (const char *)
378 (cur_node->children ? cur_node->children->content : NULL((void*)0));
379
380 if (cur_node->type != XML_ELEMENT_NODE)
381 continue;
382
383 if (strcmp ("StartDate", name) == 0)
384 {
385 const char *p;
386 kp->key_policy_startdate_str = content;
387 memset (&kp->key_policy_startdate, 0, sizeof(struct tm));
388 p = strptime (kp->key_policy_startdate_str,
389 "%Y-%m-%dT%H:%M:%SZ", &kp->key_policy_startdate);
390 if (p == NULL((void*)0) || *p != '\0')
391 {
392 _pskc_debug ("cannot convert time string '%s'",
393 kp->key_policy_startdate_str);
394 *rc = PSKC_PARSE_ERROR;
395 }
396 }
397 else if (strcmp ("ExpiryDate", name) == 0)
398 {
399 const char *p;
400 kp->key_policy_expirydate_str = content;
401 memset (&kp->key_policy_expirydate, 0, sizeof(struct tm));
402 p = strptime (kp->key_policy_expirydate_str,
403 "%Y-%m-%dT%H:%M:%SZ", &kp->key_policy_expirydate);
404 if (p == NULL((void*)0) || *p != '\0')
405 {
406 _pskc_debug ("cannot convert time string '%s'",
407 kp->key_policy_startdate_str);
408 *rc = PSKC_PARSE_ERROR;
409 }
410 }
411 else if (strcmp ("PINPolicy", name) == 0)
412 {
413 xmlAttr *cur_attr = NULL((void*)0);
414
415 for (cur_attr = cur_node->properties; cur_attr;
416 cur_attr = cur_attr->next)
417 {
418 const char *attr_name = (const char *) cur_attr->name;
419 const char *attr_content =
420 (const char *) cur_attr->children->content;
421
422 if (strcmp ("PINKeyId", attr_name) == 0)
423 kp->key_policy_pinkeyid = attr_content;
424 else if (strcmp ("PINUsageMode", attr_name) == 0)
425 {
426 kp->key_policy_pinusagemode_str = attr_content;
427 kp->key_policy_pinusagemode =
428 pskc_str2pinusagemode (kp->
429 key_policy_pinusagemode_str);
430 }
431 else if (strcmp ("MaxFailedAttempts", attr_name) == 0)
432 {
433 kp->key_policy_pinmaxfailedattempts_str = attr_content;
434 kp->key_policy_pinmaxfailedattempts =
435 strtoull (kp->key_policy_pinmaxfailedattempts_str,
436 NULL((void*)0), 10);
437 }
438 else if (strcmp ("MinLength", attr_name) == 0)
439 {
440 kp->key_policy_pinminlength_str = attr_content;
441 kp->key_policy_pinminlength =
442 strtoull (kp->key_policy_pinminlength_str, NULL((void*)0), 10);
443 }
444 else if (strcmp ("MaxLength", attr_name) == 0)
445 {
446 kp->key_policy_pinmaxlength_str = attr_content;
447 kp->key_policy_pinmaxlength =
448 strtoull (kp->key_policy_pinmaxlength_str, NULL((void*)0), 10);
449 }
450 else if (strcmp ("PINEncoding", attr_name) == 0)
451 {
452 kp->key_policy_pinencoding_str = attr_content;
453 kp->key_policy_pinencoding =
454 pskc_str2valueformat (kp->key_policy_pinencoding_str);
455 }
456 else
457 {
458 _pskc_debug ("unknown <%s> attribute <%s>", name, attr_name);
459 *rc = PSKC_PARSE_ERROR;
460 }
461 }
462 }
463 else if (strcmp ("KeyUsage", name) == 0)
464 {
465 kp->key_policy_keyusage_str = content;
466 kp->key_policy_keyusages |=
467 pskc_str2keyusage (kp->key_policy_keyusage_str);
468 }
469 else if (strcmp ("NumberOfTransactions", name) == 0)
470 {
471 kp->key_policy_numberoftransactions_str = content;
472 if (kp->key_policy_numberoftransactions_str)
473 kp->key_policy_numberoftransactions =
474 strtoull (kp->key_policy_numberoftransactions_str, NULL((void*)0), 10);
475 }
476 else
477 {
478 _pskc_debug ("unknown <%s> element <%s>", x->parent->name, name);
479 *rc = PSKC_PARSE_ERROR;
480 }
481 }
482}
483
484static void
485parse_key (xmlNode * x, struct pskc_key *kp, int *rc)
486{
487 xmlNode *cur_node = NULL((void*)0);
488
489 for (cur_node = x; cur_node; cur_node = cur_node->next)
490 {
491 const char *name = (const char *) cur_node->name;
492 const char *content = (const char *)
493 (cur_node->children ? cur_node->children->content : NULL((void*)0));
494
495 if (cur_node->type != XML_ELEMENT_NODE)
496 continue;
497
498 if (strcmp ("Issuer", name) == 0)
499 kp->key_issuer = content;
500 else if (strcmp ("AlgorithmParameters", name) == 0)
501 parse_algorithmparameters (cur_node->children, kp, rc);
502 else if (strcmp ("KeyProfileId", name) == 0)
503 kp->key_profileid = content;
504 else if (strcmp ("KeyReference", name) == 0)
505 kp->key_reference = content;
506 else if (strcmp ("FriendlyName", name) == 0)
507 kp->key_friendlyname = content;
508 else if (strcmp ("Data", name) == 0)
509 parse_data (cur_node->children, kp, rc);
510 else if (strcmp ("UserId", name) == 0)
511 kp->key_userid = content;
512 else if (strcmp ("Policy", name) == 0)
513 parse_policy (cur_node->children, kp, rc);
514 else
515 {
516 _pskc_debug ("unknown <%s> element <%s>", x->parent->name, name);
517 *rc = PSKC_PARSE_ERROR;
518 }
519 }
520}
521
522static void
523parse_keypackage (xmlNode * x, struct pskc_key *kp, int *rc)
524{
525 xmlNode *cur_node = NULL((void*)0);
526
527 for (cur_node = x; cur_node; cur_node = cur_node->next)
528 {
529 const char *name = (const char *) cur_node->name;
530
531 if (cur_node->type != XML_ELEMENT_NODE)
532 continue;
533
534 if (strcmp ("DeviceInfo", name) == 0)
535 parse_deviceinfo (cur_node->children, kp, rc);
536 else if (strcmp ("CryptoModuleInfo", name) == 0)
537 parse_cryptomoduleinfo (cur_node->children, kp, rc);
538 else if (strcmp ("Key", name) == 0)
539 {
540 xmlAttr *cur_attr = NULL((void*)0);
541
542 for (cur_attr = cur_node->properties; cur_attr;
543 cur_attr = cur_attr->next)
544 {
545 const char *attr_name = (const char *) cur_attr->name;
546 const char *attr_content =
547 (const char *) cur_attr->children->content;
548
549 if (strcmp ("Id", attr_name) == 0)
550 kp->key_id = attr_content;
551 else if (strcmp ("Algorithm", attr_name) == 0)
552 kp->key_algorithm = attr_content;
553 else
554 {
555 _pskc_debug ("unknown <%s> attribute <%s>", name, attr_name);
556 *rc = PSKC_PARSE_ERROR;
557 }
558 }
559
560 parse_key (cur_node->children, kp, rc);
561 }
562 else
563 {
564 _pskc_debug ("unknown <%s> element <%s>", x->parent->name, name);
565 *rc = PSKC_PARSE_ERROR;
566 }
567 }
568}
569
570static void
571parse_keypackages (pskc_t * pd, xmlNode * x, int *rc)
572{
573 xmlNode *cur_node = NULL((void*)0);
574
575 for (cur_node = x; cur_node; cur_node = cur_node->next)
576 {
577 const char *name = (const char *) cur_node->name;
578
579 if (cur_node->type != XML_ELEMENT_NODE)
580 continue;
581
582 if (strcmp ("KeyPackage", name) == 0)
583 {
584 struct pskc_key *tmp;
585
586 tmp = realloc (pd->keypackages,
587 sizeof (*pd->keypackages) *
588 (pd->nkeypackages + 1));
589 if (tmp == NULL((void*)0))
590 {
591 *rc = PSKC_MALLOC_ERROR;
592 return;
593 }
594
595 pd->keypackages = tmp;
596 pd->nkeypackages++;
597
598 memset (&pd->keypackages[pd->nkeypackages - 1], 0,
599 sizeof (*pd->keypackages));
600
601 parse_keypackage (cur_node->children,
602 &pd->keypackages[pd->nkeypackages - 1], rc);
603 }
604 else if (strcmp ("Signature", name) == 0)
605 pd->signed_p = 1;
606 else
607 {
608 _pskc_debug ("unknown <%s> element <%s>", x->parent->name, name);
609 *rc = PSKC_PARSE_ERROR;
610 }
611 }
612}
613
614static void
615parse_keycontainer (pskc_t * pd, xmlNode * x, int *rc)
616{
617 xmlAttr *cur_attr = NULL((void*)0);
618 const char *name = (const char *) x->name;
619
620 if (strcmp ("KeyContainer", name) != 0)
621 {
622 _pskc_debug ("unknown top-level element <%s>", name);
623 *rc = PSKC_PARSE_ERROR;
624 }
625
626 for (cur_attr = x->properties; cur_attr; cur_attr = cur_attr->next)
627 {
628 const char *attr_name = (const char *) cur_attr->name;
629 const char *attr_content = (const char *) cur_attr->children->content;
630
631 if (strcmp ("Version", attr_name) == 0)
632 pd->version = attr_content;
633 else if (strcmp ("Id", attr_name) == 0)
634 pd->id = attr_content;
635 else
636 {
637 _pskc_debug ("unknown <%s> attribute <%s>", name, attr_name);
638 *rc = PSKC_PARSE_ERROR;
639 }
640 }
641
642 parse_keypackages (pd, x->children, rc);
643}
644
645/**
646 * pskc_init:
647 * @container: pointer to a #pskc_t handle to initialize.
648 *
649 * This function initializes the PSKC @container handle. The memory
650 * allocate can be released by calling pskc_done().
651 *
652 * Returns: On success, %PSKC_OK (zero) is returned, on memory
653 * allocation errors %PSKC_MALLOC_ERROR is returned.
654 **/
655int
656pskc_init (pskc_t ** container)
657{
658 *container = calloc (1, sizeof (**container));
659 if (*container == NULL((void*)0))
660 return PSKC_MALLOC_ERROR;
661 return PSKC_OK;
662}
663
664/**
665 * pskc_done:
666 * @container: a #pskc_t handle, from pskc_init().
667 *
668 * This function releases the resources associated with the PSKC
669 * @container handle.
670 **/
671void
672pskc_done (pskc_t * container)
673{
674 size_t i;
675
676 if (container == NULL((void*)0))
677 return;
678
679 xmlFreeDoc (container->xmldoc);
680
681 for (i = 0; i < container->nkeypackages; i++)
682 {
683 pskc_key_t *kp = &container->keypackages[i];
684 free (kp->key_secret);
685 free (kp->key_b64secret);
686 }
687
688 free (container->keypackages);
689 free (container);
690}
691
692/**
693 * pskc_parse_from_memory:
694 * @container: a #pskc_t handle, from pskc_init().
695 * @len: length of @buffer.
696 * @buffer: XML data to parse.
697 *
698 * This function will parse the XML data in @buffer of @len size into
699 * @container. If %PSKC_PARSE_ERROR is returned, parsing of some
700 * elements have failed but the @container is still valid and contain
701 * partially parsed information. In this situation, you may continue
702 * but raise a warning.
703 *
704 * Returns: On success, %PSKC_OK (zero) is returned, on memory
705 * allocation errors %PSKC_MALLOC_ERROR is returned, on XML library
706 * errors %PSKC_XML_ERROR is returned, on PSKC parse errors
707 * %PSKC_PARSE_ERROR is returned.
708 **/
709int
710pskc_parse_from_memory (pskc_t *container, size_t len, const char *buffer)
711{
712 xmlDocPtr xmldoc;
713 xmlNode *root;
714 int rc = PSKC_OK;
715
716 xmldoc = xmlReadMemory (buffer, len, NULL((void*)0), NULL((void*)0), XML_PARSE_NONET);
717 if (xmldoc == NULL((void*)0))
718 return PSKC_XML_ERROR;
719
720 container->xmldoc = xmldoc;
721
722 root = xmlDocGetRootElement (xmldoc);
723 parse_keycontainer (container, root, &rc);
724
725 return rc;
726}