4 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Jayoun Lee <airjany@samsung.com>, Sewook Park <sewook7.park@samsung.com>,
7 * Jaeho Lee <jaeho81.lee@samsung.com>, Shobhit Srivastava <shobhit.s@samsung.com>
9 * Licensed under the Apache License, Version 2.0 (the "License");
10 * you may not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
13 * http://www.apache.org/licenses/LICENSE-2.0
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS,
17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
22 #include <pkgmgr_parser.h>
23 #include "pkgmgr_parser_signature.h"
25 #define ASCII(s) (const char *)s
26 #define XMLCHAR(s) (const xmlChar *)s
28 static int _ri_next_child_element(xmlTextReaderPtr reader, int depth)
30 int ret = xmlTextReaderRead(reader);
31 int cur = xmlTextReaderDepth(reader);
34 switch (xmlTextReaderNodeType(reader)) {
35 case XML_READER_TYPE_ELEMENT:
39 case XML_READER_TYPE_TEXT:
43 case XML_READER_TYPE_END_ELEMENT:
52 ret = xmlTextReaderRead(reader);
53 cur = xmlTextReaderDepth(reader);
58 static void _ri_free_transform(transform_x *transform)
60 if (transform == NULL)
62 if (transform->algorithm) {
63 free((void *)transform->algorithm);
64 transform->algorithm = NULL;
66 free((void*)transform);
70 static void _ri_free_cannonicalizationmethod(cannonicalizationmethod_x *cannonicalizationmethod)
72 if (cannonicalizationmethod == NULL)
74 if (cannonicalizationmethod->algorithm) {
75 free((void *)cannonicalizationmethod->algorithm);
76 cannonicalizationmethod->algorithm = NULL;
78 free((void*)cannonicalizationmethod);
79 cannonicalizationmethod = NULL;
82 static void _ri_free_signaturemethod(signaturemethod_x *signaturemethod)
84 if (signaturemethod == NULL)
86 if (signaturemethod->algorithm) {
87 free((void *)signaturemethod->algorithm);
88 signaturemethod->algorithm = NULL;
90 free((void*)signaturemethod);
91 signaturemethod = NULL;
94 static void _ri_free_digestmethod(digestmethod_x *digestmethod)
96 if (digestmethod == NULL)
98 if (digestmethod->algorithm) {
99 free((void *)digestmethod->algorithm);
100 digestmethod->algorithm = NULL;
102 free((void*)digestmethod);
106 static void _ri_free_digestvalue(digestvalue_x *digestvalue)
108 if (digestvalue == NULL)
110 if (digestvalue->text) {
111 free((void *)digestvalue->text);
112 digestvalue->text = NULL;
114 free((void*)digestvalue);
118 static void _ri_free_signaturevalue(signaturevalue_x *signaturevalue)
120 if (signaturevalue == NULL)
122 if (signaturevalue->text) {
123 free((void *)signaturevalue->text);
124 signaturevalue->text = NULL;
126 free((void*)signaturevalue);
127 signaturevalue = NULL;
130 static void _ri_free_x509certificate(x509certificate_x *x509certificate)
132 if (x509certificate == NULL)
134 if (x509certificate->text) {
135 free((void *)x509certificate->text);
136 x509certificate->text = NULL;
138 free((void*)x509certificate);
139 x509certificate = NULL;
142 static void _ri_free_x509data(x509data_x *x509data)
144 if (x509data == NULL)
146 if (x509data->x509certificate) {
147 x509certificate_x *x509certificate = x509data->x509certificate;
148 x509certificate_x *tmp = NULL;
149 while(x509certificate != NULL) {
150 tmp = x509certificate->next;
151 _ri_free_x509certificate(x509certificate);
152 x509certificate = tmp;
155 free((void*)x509data);
159 static void _ri_free_keyinfo(keyinfo_x *keyinfo)
163 if (keyinfo->x509data) {
164 x509data_x *x509data = keyinfo->x509data;
165 x509data_x *tmp = NULL;
166 while(x509data != NULL) {
167 tmp = x509data->next;
168 _ri_free_x509data(x509data);
172 free((void*)keyinfo);
176 static void _ri_free_transforms(transforms_x *transforms)
178 if (transforms == NULL)
180 if (transforms->transform) {
181 transform_x *transform = transforms->transform;
182 transform_x *tmp = NULL;
183 while(transform != NULL) {
184 tmp = transform->next;
185 _ri_free_transform(transform);
189 free((void*)transforms);
193 static void _ri_free_reference(reference_x *reference)
195 if (reference == NULL)
197 if (reference->digestmethod) {
198 digestmethod_x *digestmethod = reference->digestmethod;
199 digestmethod_x *tmp = NULL;
200 while(digestmethod != NULL) {
201 tmp = digestmethod->next;
202 _ri_free_digestmethod(digestmethod);
206 if (reference->digestvalue) {
207 digestvalue_x *digestvalue = reference->digestvalue;
208 digestvalue_x *tmp = NULL;
209 while(digestvalue != NULL) {
210 tmp = digestvalue->next;
211 _ri_free_digestvalue(digestvalue);
215 if (reference->transforms) {
216 transforms_x *transforms = reference->transforms;
217 transforms_x *tmp = NULL;
218 while(transforms != NULL) {
219 tmp = transforms->next;
220 _ri_free_transforms(transforms);
224 free((void*)reference);
228 static void _ri_free_signedinfo(signedinfo_x *signedinfo)
230 if (signedinfo == NULL)
232 if (signedinfo->cannonicalizationmethod) {
233 cannonicalizationmethod_x *cannonicalizationmethod = signedinfo->cannonicalizationmethod;
234 cannonicalizationmethod_x *tmp = NULL;
235 while(cannonicalizationmethod != NULL) {
236 tmp = cannonicalizationmethod->next;
237 _ri_free_cannonicalizationmethod(cannonicalizationmethod);
238 cannonicalizationmethod = tmp;
241 if (signedinfo->signaturemethod) {
242 signaturemethod_x *signaturemethod = signedinfo->signaturemethod;
243 signaturemethod_x *tmp = NULL;
244 while(signaturemethod != NULL) {
245 tmp = signaturemethod->next;
246 _ri_free_signaturemethod(signaturemethod);
247 signaturemethod = tmp;
250 if (signedinfo->reference) {
251 reference_x *reference = signedinfo->reference;
252 reference_x *tmp = NULL;
253 while(reference != NULL) {
254 tmp = reference->next;
255 _ri_free_reference(reference);
259 free((void*)signedinfo);
263 void _ri_free_signature_xml(signature_x *sigx)
268 free((void *)sigx->id);
272 free((void *)sigx->xmlns);
275 if (sigx->signedinfo) {
276 signedinfo_x *signedinfo = sigx->signedinfo;
277 signedinfo_x *tmp = NULL;
278 while(signedinfo != NULL) {
279 tmp = signedinfo->next;
280 _ri_free_signedinfo(signedinfo);
284 if (sigx->signaturevalue) {
285 signaturevalue_x *signaturevalue = sigx->signaturevalue;
286 signaturevalue_x *tmp = NULL;
287 while(signaturevalue != NULL) {
288 tmp = signaturevalue->next;
289 _ri_free_signaturevalue(signaturevalue);
290 signaturevalue = tmp;
294 keyinfo_x *keyinfo = sigx->keyinfo;
295 keyinfo_x *tmp = NULL;
296 while(keyinfo != NULL) {
298 _ri_free_keyinfo(keyinfo);
302 /*Object will be freed when it will be parsed in future*/
307 static int _ri_process_digestmethod(xmlTextReaderPtr reader, digestmethod_x *digestmethod)
309 if (xmlTextReaderGetAttribute(reader, XMLCHAR("Algorithm")))
310 digestmethod->algorithm = ASCII(xmlTextReaderGetAttribute(reader, XMLCHAR("Algorithm")));
314 static int _ri_process_digestvalue(xmlTextReaderPtr reader, digestvalue_x *digestvalue)
316 xmlTextReaderRead(reader);
317 if (xmlTextReaderValue(reader))
318 digestvalue->text = ASCII(xmlTextReaderValue(reader));
322 static int _ri_process_transform(xmlTextReaderPtr reader, transform_x *transform)
324 if (xmlTextReaderGetAttribute(reader, XMLCHAR("Algorithm")))
325 transform->algorithm = ASCII(xmlTextReaderGetAttribute(reader, XMLCHAR("Algorithm")));
329 static int _ri_process_transforms(xmlTextReaderPtr reader, transforms_x *transforms)
331 const xmlChar *node = NULL;
334 transform_x *tmp1 = NULL;
336 depth = xmlTextReaderDepth(reader);
337 while ((ret = _ri_next_child_element(reader, depth))) {
338 node = xmlTextReaderConstName(reader);
340 // _d_msg(DEBUG_ERR, "node is NULL\n");
343 if (strcmp(ASCII(node), "Transform") == 0) {
344 transform_x *transform = calloc(1, sizeof(transform_x));
345 if (transform == NULL) {
346 // _d_msg(DEBUG_ERR, "Calloc Failed\n");
349 LISTADD(transforms->transform, transform);
350 ret = _ri_process_transform(reader, transform);
352 // _d_msg(DEBUG_INFO, "Invalid tag %s", ASCII(node));
358 if (transforms->transform) {
359 LISTHEAD(transforms->transform, tmp1);
360 transforms->transform = tmp1;
365 static int _ri_process_cannonicalizationmethod(xmlTextReaderPtr reader, cannonicalizationmethod_x *cannonicalizationmethod)
367 if (xmlTextReaderGetAttribute(reader, XMLCHAR("Algorithm")))
368 cannonicalizationmethod->algorithm = ASCII(xmlTextReaderGetAttribute(reader, XMLCHAR("Algorithm")));
372 static int _ri_process_signaturemethod(xmlTextReaderPtr reader, signaturemethod_x *signaturemethod)
374 if (xmlTextReaderGetAttribute(reader, XMLCHAR("Algorithm")))
375 signaturemethod->algorithm = ASCII(xmlTextReaderGetAttribute(reader, XMLCHAR("Algorithm")));
379 static int _ri_process_reference(xmlTextReaderPtr reader, reference_x *reference)
381 const xmlChar *node = NULL;
384 digestmethod_x *tmp1 = NULL;
385 digestvalue_x *tmp2 = NULL;
386 transforms_x *tmp3 = NULL;
388 if (xmlTextReaderGetAttribute(reader, XMLCHAR("URI")))
389 reference->uri = ASCII(xmlTextReaderGetAttribute(reader, XMLCHAR("URI")));
391 depth = xmlTextReaderDepth(reader);
392 while ((ret = _ri_next_child_element(reader, depth))) {
393 node = xmlTextReaderConstName(reader);
395 // _d_msg(DEBUG_ERR, "node is NULL\n");
398 if (strcmp(ASCII(node), "DigestMethod") == 0) {
399 digestmethod_x *digestmethod = calloc(1, sizeof(digestmethod_x));
400 if (digestmethod == NULL) {
401 // _d_msg(DEBUG_ERR, "Calloc Failed\n");
404 LISTADD(reference->digestmethod, digestmethod);
405 ret = _ri_process_digestmethod(reader, digestmethod);
406 } else if (strcmp(ASCII(node), "DigestValue") == 0) {
407 digestvalue_x *digestvalue = calloc(1, sizeof(digestvalue_x));
408 if (digestvalue == NULL) {
409 // _d_msg(DEBUG_ERR, "Calloc Failed\n");
412 LISTADD(reference->digestvalue, digestvalue);
413 ret = _ri_process_digestvalue(reader, digestvalue);
414 } else if (strcmp(ASCII(node), "Transforms") == 0) {
415 transforms_x *transforms = calloc(1, sizeof(transforms_x));
416 if (transforms == NULL) {
417 // _d_msg(DEBUG_ERR, "Calloc Failed\n");
420 LISTADD(reference->transforms, transforms);
421 ret = _ri_process_transforms(reader, transforms);
423 // _d_msg(DEBUG_INFO, "Invalid tag %s", ASCII(node));
429 if (reference->digestmethod) {
430 LISTHEAD(reference->digestmethod, tmp1);
431 reference->digestmethod = tmp1;
433 if (reference->digestvalue) {
434 LISTHEAD(reference->digestvalue, tmp2);
435 reference->digestvalue = tmp2;
437 if (reference->transforms) {
438 LISTHEAD(reference->transforms, tmp3);
439 reference->transforms = tmp3;
444 static int _ri_process_x509certificate(xmlTextReaderPtr reader, x509certificate_x *x509certificate)
446 xmlTextReaderRead(reader);
447 if (xmlTextReaderValue(reader)) {
448 x509certificate->text = ASCII(xmlTextReaderValue(reader));
449 // _d_msg(DEBUG_INFO, "certlen=%d, x509certificate : %s", strlen(x509certificate->text), x509certificate->text);
454 static int _ri_process_x509data(xmlTextReaderPtr reader, x509data_x *x509data)
456 const xmlChar *node = NULL;
459 x509certificate_x *tmp1 = NULL;
461 depth = xmlTextReaderDepth(reader);
462 while ((ret = _ri_next_child_element(reader, depth))) {
463 node = xmlTextReaderConstName(reader);
465 // _d_msg(DEBUG_ERR, "node is NULL\n");
468 if (strcmp(ASCII(node), "X509Certificate") == 0) {
469 x509certificate_x *x509certificate = calloc(1, sizeof(x509certificate_x));
470 if (x509certificate == NULL) {
471 // _d_msg(DEBUG_ERR, "Calloc Failed\n");
474 LISTADD(x509data->x509certificate, x509certificate);
475 ret = _ri_process_x509certificate(reader, x509certificate);
477 // _d_msg(DEBUG_INFO, "Invalid tag %s", ASCII(node));
483 if (x509data->x509certificate) {
484 LISTHEAD(x509data->x509certificate, tmp1);
485 x509data->x509certificate = tmp1;
491 static int _ri_process_object(xmlTextReaderPtr reader, object_x *object)
493 /*To be parsed later*/
498 static int _ri_process_keyinfo(xmlTextReaderPtr reader, keyinfo_x *keyinfo)
500 const xmlChar *node = NULL;
503 x509data_x *tmp1 = NULL;
505 depth = xmlTextReaderDepth(reader);
506 while ((ret = _ri_next_child_element(reader, depth))) {
507 node = xmlTextReaderConstName(reader);
509 // _d_msg(DEBUG_ERR, "node is NULL\n");
512 if (strcmp(ASCII(node), "X509Data") == 0) {
513 x509data_x *x509data = calloc(1, sizeof(x509data_x));
514 if (x509data == NULL) {
515 // _d_msg(DEBUG_ERR, "Calloc Failed\n");
518 LISTADD(keyinfo->x509data, x509data);
519 ret = _ri_process_x509data(reader, x509data);
521 // _d_msg(DEBUG_INFO, "Invalid tag %s", ASCII(node));
527 if (keyinfo->x509data) {
528 LISTHEAD(keyinfo->x509data, tmp1);
529 keyinfo->x509data = tmp1;
534 static int _ri_process_signaturevalue(xmlTextReaderPtr reader, signaturevalue_x *signaturevalue)
536 xmlTextReaderRead(reader);
537 if (xmlTextReaderValue(reader)) {
538 signaturevalue->text = ASCII(xmlTextReaderValue(reader));
539 // _d_msg(DEBUG_INFO, "siglen=%d SignatureValue %s", strlen(signaturevalue->text), signaturevalue->text);
544 static int _ri_process_signedinfo(xmlTextReaderPtr reader, signedinfo_x *signedinfo)
546 const xmlChar *node = NULL;
549 cannonicalizationmethod_x *tmp1 = NULL;
550 signaturemethod_x *tmp2 = NULL;
551 reference_x *tmp3 = NULL;
553 depth = xmlTextReaderDepth(reader);
554 while ((ret = _ri_next_child_element(reader, depth))) {
555 node = xmlTextReaderConstName(reader);
557 // _d_msg(DEBUG_ERR, "node is NULL\n");
560 if (strcmp(ASCII(node), "CanonicalizationMethod") == 0) {
561 cannonicalizationmethod_x *cannonicalizationmethod = calloc(1, sizeof(cannonicalizationmethod_x));
562 if (cannonicalizationmethod == NULL) {
563 // _d_msg(DEBUG_ERR, "Calloc Failed\n");
566 LISTADD(signedinfo->cannonicalizationmethod, cannonicalizationmethod);
567 ret = _ri_process_cannonicalizationmethod(reader, cannonicalizationmethod);
568 } else if (strcmp(ASCII(node), "SignatureMethod") == 0) {
569 signaturemethod_x *signaturemethod = calloc(1, sizeof(signaturemethod_x));
570 if (signaturemethod == NULL) {
571 // _d_msg(DEBUG_ERR, "Calloc Failed\n");
574 LISTADD(signedinfo->signaturemethod, signaturemethod);
575 ret = _ri_process_signaturemethod(reader, signaturemethod);
576 } else if (strcmp(ASCII(node), "Reference") == 0) {
577 reference_x *reference = calloc(1, sizeof(reference_x));
578 if (reference == NULL) {
579 // _d_msg(DEBUG_ERR, "Calloc Failed\n");
582 LISTADD(signedinfo->reference, reference);
583 ret = _ri_process_reference(reader, reference);
585 // _d_msg(DEBUG_INFO, "Invalid tag %s", ASCII(node));
591 if (signedinfo->cannonicalizationmethod) {
592 LISTHEAD(signedinfo->cannonicalizationmethod, tmp1);
593 signedinfo->cannonicalizationmethod = tmp1;
595 if (signedinfo->signaturemethod) {
596 LISTHEAD(signedinfo->signaturemethod, tmp2);
597 signedinfo->signaturemethod = tmp2;
599 if (signedinfo->reference) {
600 LISTHEAD(signedinfo->reference, tmp3);
601 signedinfo->reference = tmp3;
606 static int _ri_process_sign(xmlTextReaderPtr reader, signature_x *sigx)
608 const xmlChar *node = NULL;
611 signedinfo_x *tmp1 = NULL;
612 signaturevalue_x *tmp2 = NULL;
613 keyinfo_x *tmp3 = NULL;
614 object_x *tmp4 = NULL;
616 depth = xmlTextReaderDepth(reader);
617 while ((ret = _ri_next_child_element(reader, depth))) {
618 node = xmlTextReaderConstName(reader);
620 // _d_msg(DEBUG_ERR, "node is NULL\n");
623 if (strcmp(ASCII(node), "SignedInfo") == 0) {
624 signedinfo_x *signedinfo = calloc(1, sizeof(signedinfo_x));
625 if (signedinfo == NULL) {
626 // _d_msg(DEBUG_ERR, "Calloc Failed\n");
629 LISTADD(sigx->signedinfo, signedinfo);
630 ret = _ri_process_signedinfo(reader, signedinfo);
631 } else if (strcmp(ASCII(node), "SignatureValue") == 0) {
632 signaturevalue_x *signaturevalue = calloc(1, sizeof(signaturevalue_x));
633 if (signaturevalue == NULL) {
634 // _d_msg(DEBUG_ERR, "Calloc Failed\n");
637 LISTADD(sigx->signaturevalue, signaturevalue);
638 ret = _ri_process_signaturevalue(reader, signaturevalue);
639 } else if (strcmp(ASCII(node), "KeyInfo") == 0) {
640 keyinfo_x *keyinfo = calloc(1, sizeof(keyinfo_x));
641 if (keyinfo == NULL) {
642 // _d_msg(DEBUG_ERR, "Calloc Failed\n");
645 LISTADD(sigx->keyinfo, keyinfo);
646 ret = _ri_process_keyinfo(reader, keyinfo);
647 } else if (strcmp(ASCII(node), "Object") == 0) {
649 object_x *object = calloc(1, sizeof(object_x));
650 if (object == NULL) {
651 // _d_msg(DEBUG_ERR, "Calloc Failed\n");
654 LISTADD(sigx->object, object);
655 ret = _ri_process_object(reader, object);
659 // _d_msg(DEBUG_INFO, "Invalid tag %s", ASCII(node));
665 if (sigx->signedinfo) {
666 LISTHEAD(sigx->signedinfo, tmp1);
667 sigx->signedinfo = tmp1;
669 if (sigx->signaturevalue) {
670 LISTHEAD(sigx->signaturevalue, tmp2);
671 sigx->signaturevalue = tmp2;
674 LISTHEAD(sigx->keyinfo, tmp3);
675 sigx->keyinfo = tmp3;
678 LISTHEAD(sigx->object, tmp4);
684 static int _ri_process_signature(xmlTextReaderPtr reader, signature_x *sigx)
686 const xmlChar *node = NULL;
689 if ((ret = _ri_next_child_element(reader, -1))) {
690 node = xmlTextReaderConstName(reader);
692 // _d_msg(DEBUG_ERR, "Node is null");
695 if (!strcmp(ASCII(node), "Signature")) {
696 if (xmlTextReaderGetAttribute(reader, XMLCHAR("Id")))
697 sigx->id = ASCII(xmlTextReaderGetAttribute(reader, XMLCHAR("Id")));
698 if (xmlTextReaderGetAttribute(reader, XMLCHAR("xmlns")))
699 sigx->xmlns = ASCII(xmlTextReaderGetAttribute(reader, XMLCHAR("xmlns")));
700 ret = _ri_process_sign(reader, sigx);
702 // _d_msg(DEBUG_ERR, "No Signature element found\n");
709 signature_x *_ri_process_signature_xml(const char *signature_file)
711 xmlTextReaderPtr reader;
712 signature_x *sigx = NULL;
714 reader = xmlReaderForFile(signature_file, NULL, 0);
717 sigx = calloc(1, sizeof(signature_x));
719 if (_ri_process_signature(reader, sigx) < 0) {
720 /* error in parsing. Let's display some hint where we failed */
721 // _d_msg(DEBUG_ERR, "Syntax error in processing signature in the above line\n");
722 _ri_free_signature_xml(sigx);
723 xmlFreeTextReader(reader);
727 // _d_msg(DEBUG_ERR, "Calloc failed\n");
729 xmlFreeTextReader(reader);
731 // _d_msg(DEBUG_ERR, "Unable to create xml reader\n");