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 "rpm-installer-util.h"
24 #include "rpm-installer-signature.h"
27 static int _ri_next_child_element(xmlTextReaderPtr reader, int depth)
29 int ret = xmlTextReaderRead(reader);
30 int cur = xmlTextReaderDepth(reader);
33 switch (xmlTextReaderNodeType(reader)) {
34 case XML_READER_TYPE_ELEMENT:
38 case XML_READER_TYPE_TEXT:
42 case XML_READER_TYPE_END_ELEMENT:
51 ret = xmlTextReaderRead(reader);
52 cur = xmlTextReaderDepth(reader);
57 static void _ri_free_transform(transform_x *transform)
59 if (transform == NULL)
61 if (transform->algorithm) {
62 free((void *)transform->algorithm);
63 transform->algorithm = NULL;
65 free((void*)transform);
69 static void _ri_free_cannonicalizationmethod(cannonicalizationmethod_x *cannonicalizationmethod)
71 if (cannonicalizationmethod == NULL)
73 if (cannonicalizationmethod->algorithm) {
74 free((void *)cannonicalizationmethod->algorithm);
75 cannonicalizationmethod->algorithm = NULL;
77 free((void*)cannonicalizationmethod);
78 cannonicalizationmethod = NULL;
81 static void _ri_free_signaturemethod(signaturemethod_x *signaturemethod)
83 if (signaturemethod == NULL)
85 if (signaturemethod->algorithm) {
86 free((void *)signaturemethod->algorithm);
87 signaturemethod->algorithm = NULL;
89 free((void*)signaturemethod);
90 signaturemethod = NULL;
93 static void _ri_free_digestmethod(digestmethod_x *digestmethod)
95 if (digestmethod == NULL)
97 if (digestmethod->algorithm) {
98 free((void *)digestmethod->algorithm);
99 digestmethod->algorithm = NULL;
101 free((void*)digestmethod);
105 static void _ri_free_digestvalue(digestvalue_x *digestvalue)
107 if (digestvalue == NULL)
109 if (digestvalue->text) {
110 free((void *)digestvalue->text);
111 digestvalue->text = NULL;
113 free((void*)digestvalue);
117 static void _ri_free_signaturevalue(signaturevalue_x *signaturevalue)
119 if (signaturevalue == NULL)
121 if (signaturevalue->text) {
122 free((void *)signaturevalue->text);
123 signaturevalue->text = NULL;
125 free((void*)signaturevalue);
126 signaturevalue = NULL;
129 static void _ri_free_x509certificate(x509certificate_x *x509certificate)
131 if (x509certificate == NULL)
133 if (x509certificate->text) {
134 free((void *)x509certificate->text);
135 x509certificate->text = NULL;
137 free((void*)x509certificate);
138 x509certificate = NULL;
141 static void _ri_free_x509data(x509data_x *x509data)
143 if (x509data == NULL)
145 if (x509data->x509certificate) {
146 x509certificate_x *x509certificate = x509data->x509certificate;
147 x509certificate_x *tmp = NULL;
148 while(x509certificate != NULL) {
149 tmp = x509certificate->next;
150 _ri_free_x509certificate(x509certificate);
151 x509certificate = tmp;
154 free((void*)x509data);
158 static void _ri_free_keyinfo(keyinfo_x *keyinfo)
162 if (keyinfo->x509data) {
163 x509data_x *x509data = keyinfo->x509data;
164 x509data_x *tmp = NULL;
165 while(x509data != NULL) {
166 tmp = x509data->next;
167 _ri_free_x509data(x509data);
171 free((void*)keyinfo);
175 static void _ri_free_transforms(transforms_x *transforms)
177 if (transforms == NULL)
179 if (transforms->transform) {
180 transform_x *transform = transforms->transform;
181 transform_x *tmp = NULL;
182 while(transform != NULL) {
183 tmp = transform->next;
184 _ri_free_transform(transform);
188 free((void*)transforms);
192 static void _ri_free_reference(reference_x *reference)
194 if (reference == NULL)
196 if (reference->digestmethod) {
197 digestmethod_x *digestmethod = reference->digestmethod;
198 digestmethod_x *tmp = NULL;
199 while(digestmethod != NULL) {
200 tmp = digestmethod->next;
201 _ri_free_digestmethod(digestmethod);
205 if (reference->digestvalue) {
206 digestvalue_x *digestvalue = reference->digestvalue;
207 digestvalue_x *tmp = NULL;
208 while(digestvalue != NULL) {
209 tmp = digestvalue->next;
210 _ri_free_digestvalue(digestvalue);
214 if (reference->transforms) {
215 transforms_x *transforms = reference->transforms;
216 transforms_x *tmp = NULL;
217 while(transforms != NULL) {
218 tmp = transforms->next;
219 _ri_free_transforms(transforms);
224 free((void*)reference->uri);
226 free((void*)reference);
230 static void _ri_free_signedinfo(signedinfo_x *signedinfo)
232 if (signedinfo == NULL)
234 if (signedinfo->cannonicalizationmethod) {
235 cannonicalizationmethod_x *cannonicalizationmethod = signedinfo->cannonicalizationmethod;
236 cannonicalizationmethod_x *tmp = NULL;
237 while(cannonicalizationmethod != NULL) {
238 tmp = cannonicalizationmethod->next;
239 _ri_free_cannonicalizationmethod(cannonicalizationmethod);
240 cannonicalizationmethod = tmp;
243 if (signedinfo->signaturemethod) {
244 signaturemethod_x *signaturemethod = signedinfo->signaturemethod;
245 signaturemethod_x *tmp = NULL;
246 while(signaturemethod != NULL) {
247 tmp = signaturemethod->next;
248 _ri_free_signaturemethod(signaturemethod);
249 signaturemethod = tmp;
252 if (signedinfo->reference) {
253 reference_x *reference = signedinfo->reference;
254 reference_x *tmp = NULL;
255 while(reference != NULL) {
256 tmp = reference->next;
257 _ri_free_reference(reference);
261 free((void*)signedinfo);
265 void _ri_free_signature_xml(signature_x *sigx)
270 free((void *)sigx->id);
274 free((void *)sigx->xmlns);
277 if (sigx->signedinfo) {
278 signedinfo_x *signedinfo = sigx->signedinfo;
279 signedinfo_x *tmp = NULL;
280 while(signedinfo != NULL) {
281 tmp = signedinfo->next;
282 _ri_free_signedinfo(signedinfo);
286 if (sigx->signaturevalue) {
287 signaturevalue_x *signaturevalue = sigx->signaturevalue;
288 signaturevalue_x *tmp = NULL;
289 while(signaturevalue != NULL) {
290 tmp = signaturevalue->next;
291 _ri_free_signaturevalue(signaturevalue);
292 signaturevalue = tmp;
296 keyinfo_x *keyinfo = sigx->keyinfo;
297 keyinfo_x *tmp = NULL;
298 while(keyinfo != NULL) {
300 _ri_free_keyinfo(keyinfo);
304 /*Object will be freed when it will be parsed in future*/
309 static int _ri_process_digestmethod(xmlTextReaderPtr reader, digestmethod_x *digestmethod)
312 ret = _ri_get_attribute(reader,"Algorithm",&digestmethod->algorithm);
314 _LOGE("@Error in getting the attribute value");
319 static int _ri_process_digestvalue(xmlTextReaderPtr reader, digestvalue_x *digestvalue)
321 xmlTextReaderRead(reader);
323 tmp = xmlTextReaderValue(reader);
325 digestvalue->text = ASCII(tmp);
329 static int _ri_process_transform(xmlTextReaderPtr reader, transform_x *transform)
332 ret = _ri_get_attribute(reader,"Algorithm",&transform->algorithm);
334 _LOGE("@Error in getting the attribute value");
339 static int _ri_process_transforms(xmlTextReaderPtr reader, transforms_x *transforms)
341 const xmlChar *node = NULL;
344 transform_x *tmp1 = NULL;
346 depth = xmlTextReaderDepth(reader);
347 while ((ret = _ri_next_child_element(reader, depth))) {
348 node = xmlTextReaderConstName(reader);
350 _LOGE("node is NULL\n");
353 if (strcmp(ASCII(node), "Transform") == 0) {
354 transform_x *transform = calloc(1, sizeof(transform_x));
355 if (transform == NULL) {
356 _LOGE("Calloc Failed\n");
359 LISTADD(transforms->transform, transform);
360 ret = _ri_process_transform(reader, transform);
362 _LOGD("Invalid tag %s", ASCII(node));
368 if (transforms->transform) {
369 LISTHEAD(transforms->transform, tmp1);
370 transforms->transform = tmp1;
375 static int _ri_process_cannonicalizationmethod(xmlTextReaderPtr reader, cannonicalizationmethod_x *cannonicalizationmethod)
378 ret = _ri_get_attribute(reader,"Algorithm",&cannonicalizationmethod->algorithm);
380 _LOGE("@Error in getting the attribute value");
385 static int _ri_process_signaturemethod(xmlTextReaderPtr reader, signaturemethod_x *signaturemethod)
388 ret = _ri_get_attribute(reader,"Algorithm",&signaturemethod->algorithm);
390 _LOGE("@Error in getting the attribute value");
395 static int _ri_process_reference(xmlTextReaderPtr reader, reference_x *reference)
397 const xmlChar *node = NULL;
400 digestmethod_x *tmp1 = NULL;
401 digestvalue_x *tmp2 = NULL;
402 transforms_x *tmp3 = NULL;
404 ret = _ri_get_attribute(reader,"URI",&reference->uri);
406 _LOGE("@Error in getting the attribute value");
410 depth = xmlTextReaderDepth(reader);
411 while ((ret = _ri_next_child_element(reader, depth))) {
412 node = xmlTextReaderConstName(reader);
414 _LOGE("node is NULL\n");
417 if (strcmp(ASCII(node), "DigestMethod") == 0) {
418 digestmethod_x *digestmethod = calloc(1, sizeof(digestmethod_x));
419 if (digestmethod == NULL) {
420 _LOGE("Calloc Failed\n");
423 LISTADD(reference->digestmethod, digestmethod);
424 ret = _ri_process_digestmethod(reader, digestmethod);
425 } else if (strcmp(ASCII(node), "DigestValue") == 0) {
426 digestvalue_x *digestvalue = calloc(1, sizeof(digestvalue_x));
427 if (digestvalue == NULL) {
428 _LOGE("Calloc Failed\n");
431 LISTADD(reference->digestvalue, digestvalue);
432 ret = _ri_process_digestvalue(reader, digestvalue);
433 } else if (strcmp(ASCII(node), "Transforms") == 0) {
434 transforms_x *transforms = calloc(1, sizeof(transforms_x));
435 if (transforms == NULL) {
436 _LOGE("Calloc Failed\n");
439 LISTADD(reference->transforms, transforms);
440 ret = _ri_process_transforms(reader, transforms);
442 _LOGD("Invalid tag %s", ASCII(node));
448 if (reference->digestmethod) {
449 LISTHEAD(reference->digestmethod, tmp1);
450 reference->digestmethod = tmp1;
452 if (reference->digestvalue) {
453 LISTHEAD(reference->digestvalue, tmp2);
454 reference->digestvalue = tmp2;
456 if (reference->transforms) {
457 LISTHEAD(reference->transforms, tmp3);
458 reference->transforms = tmp3;
463 static int _ri_process_x509certificate(xmlTextReaderPtr reader, x509certificate_x *x509certificate)
465 xmlTextReaderRead(reader);
467 tmp = xmlTextReaderValue(reader);
469 x509certificate->text = ASCII(tmp);
470 _LOGD("x509certificate, len=[%d]\n%s", strlen(x509certificate->text), x509certificate->text);
475 static int _ri_process_x509data(xmlTextReaderPtr reader, x509data_x *x509data)
477 const xmlChar *node = NULL;
480 x509certificate_x *tmp1 = NULL;
482 depth = xmlTextReaderDepth(reader);
483 while ((ret = _ri_next_child_element(reader, depth))) {
484 node = xmlTextReaderConstName(reader);
486 _LOGE("node is NULL\n");
489 if (strcmp(ASCII(node), "X509Certificate") == 0) {
490 x509certificate_x *x509certificate = calloc(1, sizeof(x509certificate_x));
491 if (x509certificate == NULL) {
492 _LOGE("Calloc Failed\n");
495 LISTADD(x509data->x509certificate, x509certificate);
496 ret = _ri_process_x509certificate(reader, x509certificate);
498 _LOGD("Invalid tag %s", ASCII(node));
504 if (x509data->x509certificate) {
505 LISTHEAD(x509data->x509certificate, tmp1);
506 x509data->x509certificate = tmp1;
512 static int _ri_process_object(xmlTextReaderPtr reader, object_x *object)
514 /*To be parsed later*/
519 static int _ri_process_keyinfo(xmlTextReaderPtr reader, keyinfo_x *keyinfo)
521 const xmlChar *node = NULL;
524 x509data_x *tmp1 = NULL;
526 depth = xmlTextReaderDepth(reader);
527 while ((ret = _ri_next_child_element(reader, depth))) {
528 node = xmlTextReaderConstName(reader);
530 _LOGE("node is NULL\n");
533 if (strcmp(ASCII(node), "X509Data") == 0) {
534 x509data_x *x509data = calloc(1, sizeof(x509data_x));
535 if (x509data == NULL) {
536 _LOGE("Calloc Failed\n");
539 LISTADD(keyinfo->x509data, x509data);
540 ret = _ri_process_x509data(reader, x509data);
542 _LOGD("Invalid tag %s", ASCII(node));
548 if (keyinfo->x509data) {
549 LISTHEAD(keyinfo->x509data, tmp1);
550 keyinfo->x509data = tmp1;
555 static int _ri_process_signaturevalue(xmlTextReaderPtr reader, signaturevalue_x *signaturevalue)
557 xmlTextReaderRead(reader);
559 tmp = xmlTextReaderValue(reader);
561 signaturevalue->text = ASCII(tmp);
562 _LOGD("SignatureValue, len=[%d]\n%s", strlen(signaturevalue->text), signaturevalue->text);
567 static int _ri_process_signedinfo(xmlTextReaderPtr reader, signedinfo_x *signedinfo)
569 const xmlChar *node = NULL;
572 cannonicalizationmethod_x *tmp1 = NULL;
573 signaturemethod_x *tmp2 = NULL;
574 reference_x *tmp3 = NULL;
576 depth = xmlTextReaderDepth(reader);
577 while ((ret = _ri_next_child_element(reader, depth))) {
578 node = xmlTextReaderConstName(reader);
580 _LOGE("node is NULL\n");
583 if (strcmp(ASCII(node), "CanonicalizationMethod") == 0) {
584 cannonicalizationmethod_x *cannonicalizationmethod = calloc(1, sizeof(cannonicalizationmethod_x));
585 if (cannonicalizationmethod == NULL) {
586 _LOGE("Calloc Failed\n");
589 LISTADD(signedinfo->cannonicalizationmethod, cannonicalizationmethod);
590 ret = _ri_process_cannonicalizationmethod(reader, cannonicalizationmethod);
591 } else if (strcmp(ASCII(node), "SignatureMethod") == 0) {
592 signaturemethod_x *signaturemethod = calloc(1, sizeof(signaturemethod_x));
593 if (signaturemethod == NULL) {
594 _LOGE("Calloc Failed\n");
597 LISTADD(signedinfo->signaturemethod, signaturemethod);
598 ret = _ri_process_signaturemethod(reader, signaturemethod);
599 } else if (strcmp(ASCII(node), "Reference") == 0) {
600 reference_x *reference = calloc(1, sizeof(reference_x));
601 if (reference == NULL) {
602 _LOGE("Calloc Failed\n");
605 LISTADD(signedinfo->reference, reference);
606 ret = _ri_process_reference(reader, reference);
608 _LOGD("Invalid tag %s", ASCII(node));
614 if (signedinfo->cannonicalizationmethod) {
615 LISTHEAD(signedinfo->cannonicalizationmethod, tmp1);
616 signedinfo->cannonicalizationmethod = tmp1;
618 if (signedinfo->signaturemethod) {
619 LISTHEAD(signedinfo->signaturemethod, tmp2);
620 signedinfo->signaturemethod = tmp2;
622 if (signedinfo->reference) {
623 LISTHEAD(signedinfo->reference, tmp3);
624 signedinfo->reference = tmp3;
629 static int _ri_process_sign(xmlTextReaderPtr reader, signature_x *sigx)
631 const xmlChar *node = NULL;
634 signedinfo_x *tmp1 = NULL;
635 signaturevalue_x *tmp2 = NULL;
636 keyinfo_x *tmp3 = NULL;
637 object_x *tmp4 = NULL;
639 depth = xmlTextReaderDepth(reader);
640 while ((ret = _ri_next_child_element(reader, depth))) {
641 node = xmlTextReaderConstName(reader);
643 _LOGE("node is NULL\n");
646 if (strcmp(ASCII(node), "SignedInfo") == 0) {
647 signedinfo_x *signedinfo = calloc(1, sizeof(signedinfo_x));
648 if (signedinfo == NULL) {
649 _LOGE("Calloc Failed\n");
652 LISTADD(sigx->signedinfo, signedinfo);
653 ret = _ri_process_signedinfo(reader, signedinfo);
654 } else if (strcmp(ASCII(node), "SignatureValue") == 0) {
655 signaturevalue_x *signaturevalue = calloc(1, sizeof(signaturevalue_x));
656 if (signaturevalue == NULL) {
657 _LOGE("Calloc Failed\n");
660 LISTADD(sigx->signaturevalue, signaturevalue);
661 ret = _ri_process_signaturevalue(reader, signaturevalue);
662 } else if (strcmp(ASCII(node), "KeyInfo") == 0) {
663 keyinfo_x *keyinfo = calloc(1, sizeof(keyinfo_x));
664 if (keyinfo == NULL) {
665 _LOGE("Calloc Failed\n");
668 LISTADD(sigx->keyinfo, keyinfo);
669 ret = _ri_process_keyinfo(reader, keyinfo);
670 } else if (strcmp(ASCII(node), "Object") == 0) {
672 object_x *object = calloc(1, sizeof(object_x));
673 if (object == NULL) {
674 _LOGE("Calloc Failed\n");
677 LISTADD(sigx->object, object);
678 ret = _ri_process_object(reader, object);
682 _LOGD("Invalid tag %s", ASCII(node));
688 if (sigx->signedinfo) {
689 LISTHEAD(sigx->signedinfo, tmp1);
690 sigx->signedinfo = tmp1;
692 if (sigx->signaturevalue) {
693 LISTHEAD(sigx->signaturevalue, tmp2);
694 sigx->signaturevalue = tmp2;
697 LISTHEAD(sigx->keyinfo, tmp3);
698 sigx->keyinfo = tmp3;
701 LISTHEAD(sigx->object, tmp4);
707 static int _ri_process_signature(xmlTextReaderPtr reader, signature_x *sigx)
709 const xmlChar *node = NULL;
712 if ((ret = _ri_next_child_element(reader, -1))) {
713 node = xmlTextReaderConstName(reader);
715 _LOGE("Node is null");
718 if (!strcmp(ASCII(node), "Signature")) {
719 ret = _ri_get_attribute(reader,"Id",&sigx->id);
721 _LOGE("@Error in getting the attribute value");
725 ret = _ri_get_attribute(reader,"xmlns",&sigx->xmlns);
727 _LOGE("@Error in getting the attribute value");
731 ret = _ri_process_sign(reader, sigx);
733 _LOGE("No Signature element found\n");
740 signature_x *_ri_process_signature_xml(const char *signature_file)
742 xmlTextReaderPtr reader;
743 signature_x *sigx = NULL;
745 reader = xmlReaderForFile(signature_file, NULL, 0);
748 sigx = calloc(1, sizeof(signature_x));
750 if (_ri_process_signature(reader, sigx) < 0) {
751 /* error in parsing. Let's display some hint where we failed */
752 _LOGE("Syntax error in processing signature in the above line\n");
753 _ri_free_signature_xml(sigx);
754 xmlFreeTextReader(reader);
758 _LOGE("Calloc failed\n");
760 xmlFreeTextReader(reader);
762 _LOGE("Unable to create xml reader\n");