2 * XML Security Library (http://www.aleksey.com/xmlsec).
6 * This is free software; see Copyright file in the source
7 * distribution for preciese wording.
9 * Copyright (C) 2002-2003 Aleksey Sanin <aleksey@aleksey.com>
16 #include <libxml/tree.h>
18 #include <xmlsec/xmlsec.h>
19 #include <xmlsec/xmltree.h>
20 #include <xmlsec/list.h>
21 #include <xmlsec/keys.h>
22 #include <xmlsec/keysmngr.h>
23 #include <xmlsec/transforms.h>
24 #include <xmlsec/keyinfo.h>
25 #include <xmlsec/errors.h>
27 /**************************************************************************
31 *************************************************************************/
33 * xmlSecKeyUseWithInitialize:
34 * @keyUseWith: the pointer to information about key application/user.
36 * Initializes @keyUseWith object.
38 * Returns: 0 on success or a negative value if an error occurs.
41 xmlSecKeyUseWithInitialize(xmlSecKeyUseWithPtr keyUseWith) {
42 xmlSecAssert2(keyUseWith != NULL, -1);
44 memset(keyUseWith, 0, sizeof(xmlSecKeyUseWith));
49 * xmlSecKeyUseWithFinalize:
50 * @keyUseWith: the pointer to information about key application/user.
52 * Finalizes @keyUseWith object.
55 xmlSecKeyUseWithFinalize(xmlSecKeyUseWithPtr keyUseWith) {
56 xmlSecAssert(keyUseWith != NULL);
58 xmlSecKeyUseWithReset(keyUseWith);
59 memset(keyUseWith, 0, sizeof(xmlSecKeyUseWith));
63 * xmlSecKeyUseWithReset:
64 * @keyUseWith: the pointer to information about key application/user.
66 * Resets the @keyUseWith to its state after initialization.
69 xmlSecKeyUseWithReset(xmlSecKeyUseWithPtr keyUseWith) {
70 xmlSecAssert(keyUseWith != NULL);
72 xmlSecKeyUseWithSet(keyUseWith, NULL, NULL);
76 * xmlSecKeyUseWithCopy:
77 * @dst: the pointer to destination object.
78 * @src: the pointer to source object.
80 * Copies information from @dst to @src.
82 * Returns: 0 on success or a negative value if an error occurs.
85 xmlSecKeyUseWithCopy(xmlSecKeyUseWithPtr dst, xmlSecKeyUseWithPtr src) {
86 xmlSecAssert2(dst != NULL, -1);
87 xmlSecAssert2(src != NULL, -1);
89 return(xmlSecKeyUseWithSet(dst, src->application, src->identifier));
93 * xmlSecKeyUseWithCreate:
94 * @application: the application value.
95 * @identifier: the identifier value.
97 * Creates new xmlSecKeyUseWith object. The caller is responsible for destroying
98 * returned object with @xmlSecKeyUseWithDestroy function.
100 * Returns: pointer to newly created object or NULL if an error occurs.
103 xmlSecKeyUseWithCreate(const xmlChar* application, const xmlChar* identifier) {
104 xmlSecKeyUseWithPtr keyUseWith;
107 /* Allocate a new xmlSecKeyUseWith and fill the fields. */
108 keyUseWith = (xmlSecKeyUseWithPtr)xmlMalloc(sizeof(xmlSecKeyUseWith));
109 if(keyUseWith == NULL) {
110 xmlSecError(XMLSEC_ERRORS_HERE,
113 XMLSEC_ERRORS_R_MALLOC_FAILED,
114 "sizeof(xmlSecKeyUseWith)=%d",
115 sizeof(xmlSecKeyUseWith));
118 memset(keyUseWith, 0, sizeof(xmlSecKeyUseWith));
120 ret = xmlSecKeyUseWithInitialize(keyUseWith);
122 xmlSecError(XMLSEC_ERRORS_HERE,
124 "xmlSecKeyUseWithInitialize",
125 XMLSEC_ERRORS_R_XMLSEC_FAILED,
126 XMLSEC_ERRORS_NO_MESSAGE);
127 xmlSecKeyUseWithDestroy(keyUseWith);
131 ret = xmlSecKeyUseWithSet(keyUseWith, application, identifier);
133 xmlSecError(XMLSEC_ERRORS_HERE,
135 "xmlSecKeyUseWithSet",
136 XMLSEC_ERRORS_R_XMLSEC_FAILED,
137 XMLSEC_ERRORS_NO_MESSAGE);
138 xmlSecKeyUseWithDestroy(keyUseWith);
146 * xmlSecKeyUseWithDuplicate:
147 * @keyUseWith: the pointer to information about key application/user.
149 * Duplicates @keyUseWith object. The caller is responsible for destroying
150 * returned object with @xmlSecKeyUseWithDestroy function.
152 * Returns: pointer to newly created object or NULL if an error occurs.
155 xmlSecKeyUseWithDuplicate(xmlSecKeyUseWithPtr keyUseWith) {
158 xmlSecKeyUseWithPtr newKeyUseWith;
160 xmlSecAssert2(keyUseWith != NULL, NULL);
162 newKeyUseWith = xmlSecKeyUseWithCreate(NULL, NULL);
163 if(newKeyUseWith == NULL) {
164 xmlSecError(XMLSEC_ERRORS_HERE,
166 "xmlSecKeyUseWithCreate",
167 XMLSEC_ERRORS_R_XMLSEC_FAILED,
168 XMLSEC_ERRORS_NO_MESSAGE);
172 ret = xmlSecKeyUseWithCopy(newKeyUseWith, keyUseWith);
174 xmlSecError(XMLSEC_ERRORS_HERE,
176 "xmlSecKeyUseWithCopy",
177 XMLSEC_ERRORS_R_XMLSEC_FAILED,
178 XMLSEC_ERRORS_NO_MESSAGE);
179 xmlSecKeyUseWithDestroy(keyUseWith);
183 return(newKeyUseWith);
187 * xmlSecKeyUseWithDestroy:
188 * @keyUseWith: the pointer to information about key application/user.
190 * Destroys @keyUseWith created with @xmlSecKeyUseWithCreate or @xmlSecKeyUseWithDuplicate
194 xmlSecKeyUseWithDestroy(xmlSecKeyUseWithPtr keyUseWith) {
195 xmlSecAssert(keyUseWith != NULL);
197 xmlSecKeyUseWithFinalize(keyUseWith);
202 * xmlSecKeyUseWithSet:
203 * @keyUseWith: the pointer to information about key application/user.
204 * @application: the new application value.
205 * @identifier: the new identifier value.
207 * Sets @application and @identifier in the @keyUseWith.
209 * Returns: 0 on success or a negative value if an error occurs.
212 xmlSecKeyUseWithSet(xmlSecKeyUseWithPtr keyUseWith, const xmlChar* application, const xmlChar* identifier) {
213 xmlSecAssert2(keyUseWith != NULL, -1);
215 if(keyUseWith->application != NULL) {
216 xmlFree(keyUseWith->application);
217 keyUseWith->application = NULL;
219 if(keyUseWith->identifier != NULL) {
220 xmlFree(keyUseWith->identifier);
221 keyUseWith->identifier = NULL;
224 if(application != NULL) {
225 keyUseWith->application = xmlStrdup(application);
226 if(keyUseWith->application == NULL) {
227 xmlSecError(XMLSEC_ERRORS_HERE,
230 XMLSEC_ERRORS_R_MALLOC_FAILED,
231 "xmlStrlen(application)=%d",
232 xmlStrlen(application));
236 if(identifier != NULL) {
237 keyUseWith->identifier = xmlStrdup(identifier);
238 if(keyUseWith->identifier == NULL) {
239 xmlSecError(XMLSEC_ERRORS_HERE,
242 XMLSEC_ERRORS_R_MALLOC_FAILED,
243 "xmlStrlen(identifier)=%d",
244 xmlStrlen(identifier));
253 * xmlSecKeyUseWithDebugDump:
254 * @keyUseWith: the pointer to information about key application/user.
255 * @output: the pointer to output FILE.
257 * Prints xmlSecKeyUseWith debug information to a file @output.
260 xmlSecKeyUseWithDebugDump(xmlSecKeyUseWithPtr keyUseWith, FILE* output) {
261 xmlSecAssert(keyUseWith != NULL);
262 xmlSecAssert(output != NULL);
264 fprintf(output, "=== KeyUseWith: application=\"%s\",identifier=\"%s\"\n",
265 (keyUseWith->application) ? keyUseWith->application : BAD_CAST "",
266 (keyUseWith->identifier) ? keyUseWith->identifier : BAD_CAST "");
270 * xmlSecKeyUseWithDebugXmlDump:
271 * @keyUseWith: the pointer to information about key application/user.
272 * @output: the pointer to output FILE.
274 * Prints xmlSecKeyUseWith debug information to a file @output in XML format.
277 xmlSecKeyUseWithDebugXmlDump(xmlSecKeyUseWithPtr keyUseWith, FILE* output) {
278 xmlSecAssert(keyUseWith != NULL);
279 xmlSecAssert(output != NULL);
281 fprintf(output, "<KeyUseWith>\n");
283 fprintf(output, "<Application>");
284 xmlSecPrintXmlString(output, keyUseWith->application);
285 fprintf(output, "</Application>");
287 fprintf(output, "<Identifier>");
288 xmlSecPrintXmlString(output, keyUseWith->identifier);
289 fprintf(output, "</Identifier>");
291 fprintf(output, "</KeyUseWith>\n");
294 /***********************************************************************
298 **********************************************************************/
299 static xmlSecPtrListKlass xmlSecKeyUseWithPtrListKlass = {
300 BAD_CAST "key-use-with-list",
301 (xmlSecPtrDuplicateItemMethod)xmlSecKeyUseWithDuplicate, /* xmlSecPtrDuplicateItemMethod duplicateItem; */
302 (xmlSecPtrDestroyItemMethod)xmlSecKeyUseWithDestroy, /* xmlSecPtrDestroyItemMethod destroyItem; */
303 (xmlSecPtrDebugDumpItemMethod)xmlSecKeyUseWithDebugDump, /* xmlSecPtrDebugDumpItemMethod debugDumpItem; */
304 (xmlSecPtrDebugDumpItemMethod)xmlSecKeyUseWithDebugXmlDump, /* xmlSecPtrDebugDumpItemMethod debugXmlDumpItem; */
308 * xmlSecKeyUseWithPtrListGetKlass:
310 * The key data list klass.
312 * Returns: pointer to the key data list klass.
315 xmlSecKeyUseWithPtrListGetKlass(void) {
316 return(&xmlSecKeyUseWithPtrListKlass);
319 /**************************************************************************
321 * xmlSecKeyReq - what key are we looking for?
323 *************************************************************************/
325 * xmlSecKeyReqInitialize:
326 * @keyReq: the pointer to key requirements object.
328 * Initialize key requirements object. Caller is responsible for
329 * cleaning it with #xmlSecKeyReqFinalize function.
331 * Returns: 0 on success or a negative value if an error occurs.
334 xmlSecKeyReqInitialize(xmlSecKeyReqPtr keyReq) {
337 xmlSecAssert2(keyReq != NULL, -1);
339 memset(keyReq, 0, sizeof(xmlSecKeyReq));
341 keyReq->keyUsage = xmlSecKeyUsageAny; /* by default you can do whatever you want with the key */
342 ret = xmlSecPtrListInitialize(&keyReq->keyUseWithList, xmlSecKeyUseWithPtrListId);
344 xmlSecError(XMLSEC_ERRORS_HERE,
346 "xmlSecPtrListInitialize",
347 XMLSEC_ERRORS_R_XMLSEC_FAILED,
348 XMLSEC_ERRORS_NO_MESSAGE);
357 * xmlSecKeyReqFinalize:
358 * @keyReq: the pointer to key requirements object.
360 * Cleans the key requirements object initialized with #xmlSecKeyReqInitialize
364 xmlSecKeyReqFinalize(xmlSecKeyReqPtr keyReq) {
365 xmlSecAssert(keyReq != NULL);
367 xmlSecPtrListFinalize(&keyReq->keyUseWithList);
368 memset(keyReq, 0, sizeof(xmlSecKeyReq));
373 * @keyReq: the pointer to key requirements object.
375 * Resets key requirements object for new key search.
378 xmlSecKeyReqReset(xmlSecKeyReqPtr keyReq) {
379 xmlSecAssert(keyReq != NULL);
381 xmlSecPtrListEmpty(&keyReq->keyUseWithList);
382 keyReq->keyId = NULL;
384 keyReq->keyUsage = xmlSecKeyUsageAny;
385 keyReq->keyBitsSize = 0;
390 * @dst: the pointer to destination object.
391 * @src: the pointer to source object.
393 * Copies key requirements from @src object to @dst object.
395 * Returns: 0 on success and a negative value if an error occurs.
398 xmlSecKeyReqCopy(xmlSecKeyReqPtr dst, xmlSecKeyReqPtr src) {
401 xmlSecAssert2(dst != NULL, -1);
402 xmlSecAssert2(src != NULL, -1);
404 dst->keyId = src->keyId;
405 dst->keyType = src->keyType;
406 dst->keyUsage = src->keyUsage;
407 dst->keyBitsSize = src->keyBitsSize;
409 ret = xmlSecPtrListCopy(&dst->keyUseWithList, &src->keyUseWithList);
411 xmlSecError(XMLSEC_ERRORS_HERE,
414 XMLSEC_ERRORS_R_XMLSEC_FAILED,
415 XMLSEC_ERRORS_NO_MESSAGE);
423 * xmlSecKeyReqMatchKey:
424 * @keyReq: the pointer to key requirements object.
425 * @key: the pointer to key.
427 * Checks whether @key matches key requirements @keyReq.
429 * Returns: 1 if key matches requirements, 0 if not and a negative value
430 * if an error occurs.
433 xmlSecKeyReqMatchKey(xmlSecKeyReqPtr keyReq, xmlSecKeyPtr key) {
434 xmlSecAssert2(keyReq != NULL, -1);
435 xmlSecAssert2(xmlSecKeyIsValid(key), -1);
437 if((keyReq->keyType != xmlSecKeyDataTypeUnknown) && ((xmlSecKeyGetType(key) & keyReq->keyType) == 0)) {
440 if((keyReq->keyUsage != xmlSecKeyDataUsageUnknown) && ((keyReq->keyUsage & key->usage) == 0)) {
444 return(xmlSecKeyReqMatchKeyValue(keyReq, xmlSecKeyGetValue(key)));
448 * xmlSecKeyReqMatchKeyValue:
449 * @keyReq: the pointer to key requirements.
450 * @value: the pointer to key value.
452 * Checks whether @keyValue matches key requirements @keyReq.
454 * Returns: 1 if key value matches requirements, 0 if not and a negative value
455 * if an error occurs.
458 xmlSecKeyReqMatchKeyValue(xmlSecKeyReqPtr keyReq, xmlSecKeyDataPtr value) {
459 xmlSecAssert2(keyReq != NULL, -1);
460 xmlSecAssert2(value != NULL, -1);
462 if((keyReq->keyId != xmlSecKeyDataIdUnknown) &&
463 (!xmlSecKeyDataCheckId(value, keyReq->keyId))) {
467 if((keyReq->keyBitsSize > 0) &&
468 (xmlSecKeyDataGetSize(value) > 0) &&
469 (xmlSecKeyDataGetSize(value) < keyReq->keyBitsSize)) {
477 * xmlSecKeyReqDebugDump:
478 * @keyReq: the pointer to key requirements object.
479 * @output: the pointer to output FILE.
481 * Prints debug information about @keyReq into @output.
484 xmlSecKeyReqDebugDump(xmlSecKeyReqPtr keyReq, FILE* output) {
485 xmlSecAssert(keyReq != NULL);
486 xmlSecAssert(output != NULL);
488 fprintf(output, "=== KeyReq:\n");
489 fprintf(output, "==== keyId: %s\n",
490 (xmlSecKeyDataKlassGetName(keyReq->keyId)) ?
491 xmlSecKeyDataKlassGetName(keyReq->keyId) :
493 fprintf(output, "==== keyType: 0x%08x\n", keyReq->keyType);
494 fprintf(output, "==== keyUsage: 0x%08x\n", keyReq->keyUsage);
495 fprintf(output, "==== keyBitsSize: %d\n", keyReq->keyBitsSize);
496 xmlSecPtrListDebugDump(&(keyReq->keyUseWithList), output);
500 * xmlSecKeyReqDebugXmlDump:
501 * @keyReq: the pointer to key requirements object.
502 * @output: the pointer to output FILE.
504 * Prints debug information about @keyReq into @output in XML format.
507 xmlSecKeyReqDebugXmlDump(xmlSecKeyReqPtr keyReq, FILE* output) {
508 xmlSecAssert(keyReq != NULL);
509 xmlSecAssert(output != NULL);
511 fprintf(output, "<KeyReq>\n");
513 fprintf(output, "<KeyId>");
514 xmlSecPrintXmlString(output, xmlSecKeyDataKlassGetName(keyReq->keyId));
515 fprintf(output, "</KeyId>\n");
517 fprintf(output, "<KeyType>0x%08x</KeyType>\n", keyReq->keyType);
518 fprintf(output, "<KeyUsage>0x%08x</KeyUsage>\n", keyReq->keyUsage);
519 fprintf(output, "<KeyBitsSize>%d</KeyBitsSize>\n", keyReq->keyBitsSize);
520 xmlSecPtrListDebugXmlDump(&(keyReq->keyUseWithList), output);
521 fprintf(output, "</KeyReq>\n");
525 /**************************************************************************
529 *************************************************************************/
533 * Allocates and initializes new key. Caller is responsible for
534 * freeing returned object with #xmlSecKeyDestroy function.
536 * Returns: the pointer to newly allocated @xmlSecKey structure
537 * or NULL if an error occurs.
540 xmlSecKeyCreate(void) {
543 /* Allocate a new xmlSecKey and fill the fields. */
544 key = (xmlSecKeyPtr)xmlMalloc(sizeof(xmlSecKey));
546 xmlSecError(XMLSEC_ERRORS_HERE,
549 XMLSEC_ERRORS_R_MALLOC_FAILED,
550 "sizeof(xmlSecKey)=%d",
554 memset(key, 0, sizeof(xmlSecKey));
555 key->usage = xmlSecKeyUsageAny;
561 * @key: the pointer to key.
563 * Clears the @key data.
566 xmlSecKeyEmpty(xmlSecKeyPtr key) {
567 xmlSecAssert(key != NULL);
569 if(key->value != NULL) {
570 xmlSecKeyDataDestroy(key->value);
572 if(key->name != NULL) {
575 if(key->dataList != NULL) {
576 xmlSecPtrListDestroy(key->dataList);
579 memset(key, 0, sizeof(xmlSecKey));
584 * @key: the pointer to key.
586 * Destroys the key created using #xmlSecKeyCreate function.
589 xmlSecKeyDestroy(xmlSecKeyPtr key) {
590 xmlSecAssert(key != NULL);
598 * @keyDst: the destination key.
599 * @keySrc: the source key.
601 * Copies key data from @keySrc to @keyDst.
603 * Returns: 0 on success or a negative value if an error occurs.
606 xmlSecKeyCopy(xmlSecKeyPtr keyDst, xmlSecKeyPtr keySrc) {
607 xmlSecAssert2(keyDst != NULL, -1);
608 xmlSecAssert2(keySrc != NULL, -1);
610 /* empty destination */
611 xmlSecKeyEmpty(keyDst);
613 /* copy everything */
614 if(keySrc->name != NULL) {
615 keyDst->name = xmlStrdup(keySrc->name);
616 if(keyDst->name == NULL) {
617 xmlSecError(XMLSEC_ERRORS_HERE,
620 XMLSEC_ERRORS_R_STRDUP_FAILED,
621 "len=%d", xmlStrlen(keySrc->name));
626 if(keySrc->value != NULL) {
627 keyDst->value = xmlSecKeyDataDuplicate(keySrc->value);
628 if(keyDst->value == NULL) {
629 xmlSecError(XMLSEC_ERRORS_HERE,
631 "xmlSecKeyDataDuplicate",
632 XMLSEC_ERRORS_R_XMLSEC_FAILED,
633 XMLSEC_ERRORS_NO_MESSAGE);
638 if(keySrc->dataList != NULL) {
639 keyDst->dataList = xmlSecPtrListDuplicate(keySrc->dataList);
640 if(keyDst->dataList == NULL) {
641 xmlSecError(XMLSEC_ERRORS_HERE,
643 "xmlSecPtrListDuplicate",
644 XMLSEC_ERRORS_R_XMLSEC_FAILED,
645 XMLSEC_ERRORS_NO_MESSAGE);
650 keyDst->usage = keySrc->usage;
651 keyDst->notValidBefore = keySrc->notValidBefore;
652 keyDst->notValidAfter = keySrc->notValidAfter;
657 * xmlSecKeyDuplicate:
658 * @key: the pointer to the #xmlSecKey structure.
660 * Creates a duplicate of the given @key.
662 * Returns: the pointer to newly allocated #xmlSecKey structure
663 * or NULL if an error occurs.
666 xmlSecKeyDuplicate(xmlSecKeyPtr key) {
670 xmlSecAssert2(key != NULL, NULL);
672 newKey = xmlSecKeyCreate();
674 xmlSecError(XMLSEC_ERRORS_HERE,
677 XMLSEC_ERRORS_R_XMLSEC_FAILED,
678 XMLSEC_ERRORS_NO_MESSAGE);
682 ret = xmlSecKeyCopy(newKey, key);
684 xmlSecError(XMLSEC_ERRORS_HERE,
687 XMLSEC_ERRORS_R_XMLSEC_FAILED,
688 XMLSEC_ERRORS_NO_MESSAGE);
689 xmlSecKeyDestroy(newKey);
698 * @key: the pointer to key.
699 * @name: the pointer to key name (may be NULL).
700 * @keyReq: the pointer to key requirements.
702 * Checks whether the @key matches the given criteria.
704 * Returns: 1 if the key satisfies the given criteria or 0 otherwise.
707 xmlSecKeyMatch(xmlSecKeyPtr key, const xmlChar *name, xmlSecKeyReqPtr keyReq) {
708 xmlSecAssert2(xmlSecKeyIsValid(key), -1);
709 xmlSecAssert2(keyReq != NULL, -1);
711 if((name != NULL) && (!xmlStrEqual(xmlSecKeyGetName(key), name))) {
714 return(xmlSecKeyReqMatchKey(keyReq, key));
719 * @key: the pointer to key.
726 xmlSecKeyGetType(xmlSecKeyPtr key) {
727 xmlSecKeyDataPtr data;
729 xmlSecAssert2(key != NULL, xmlSecKeyDataTypeUnknown);
731 data = xmlSecKeyGetValue(key);
733 return(xmlSecKeyDataTypeUnknown);
735 return(xmlSecKeyDataGetType(data));
740 * @key: the pointer to key.
742 * Gets key name (see also #xmlSecKeySetName function).
747 xmlSecKeyGetName(xmlSecKeyPtr key) {
748 xmlSecAssert2(key != NULL, NULL);
755 * @key: the pointer to key.
756 * @name: the new key name.
758 * Sets key name (see also #xmlSecKeyGetName function).
760 * Returns: 0 on success or a negative value if an error occurs.
763 xmlSecKeySetName(xmlSecKeyPtr key, const xmlChar* name) {
764 xmlSecAssert2(key != NULL, -1);
766 if(key->name != NULL) {
772 key->name = xmlStrdup(name);
773 if(key->name == NULL) {
774 xmlSecError(XMLSEC_ERRORS_HERE,
777 XMLSEC_ERRORS_R_STRDUP_FAILED,
778 "len=%d", xmlStrlen(name));
788 * @key: the pointer to key.
790 * Gets key value (see also #xmlSecKeySetValue function).
792 * Returns: key value (crypto material).
795 xmlSecKeyGetValue(xmlSecKeyPtr key) {
796 xmlSecAssert2(key != NULL, NULL);
803 * @key: the pointer to key.
804 * @value: the new value.
806 * Sets key value (see also #xmlSecKeyGetValue function).
808 * Returns: 0 on success or a negative value if an error occurs.
811 xmlSecKeySetValue(xmlSecKeyPtr key, xmlSecKeyDataPtr value) {
812 xmlSecAssert2(key != NULL, -1);
814 if(key->value != NULL) {
815 xmlSecKeyDataDestroy(key->value);
825 * @key: the pointer to key.
826 * @dataId: the requested data klass.
830 * Returns: additional data associated with the @key (see also
831 * #xmlSecKeyAdoptData function).
834 xmlSecKeyGetData(xmlSecKeyPtr key, xmlSecKeyDataId dataId) {
836 xmlSecAssert2(key != NULL, NULL);
837 xmlSecAssert2(dataId != xmlSecKeyDataIdUnknown, NULL);
840 if(dataId == xmlSecKeyDataValueId) {
842 } else if(key->dataList != NULL) {
843 xmlSecKeyDataPtr tmp;
844 xmlSecSize pos, size;
846 size = xmlSecPtrListGetSize(key->dataList);
847 for(pos = 0; pos < size; ++pos) {
848 tmp = (xmlSecKeyDataPtr)xmlSecPtrListGetItem(key->dataList, pos);
849 if((tmp != NULL) && (tmp->id == dataId)) {
858 * xmlSecKeyEnsureData:
859 * @key: the pointer to key.
860 * @dataId: the requested data klass.
862 * If necessary, creates key data of @dataId klass and adds to @key.
864 * Returns: pointer to key data or NULL if an error occurs.
867 xmlSecKeyEnsureData(xmlSecKeyPtr key, xmlSecKeyDataId dataId) {
868 xmlSecKeyDataPtr data;
871 xmlSecAssert2(key != NULL, NULL);
872 xmlSecAssert2(dataId != xmlSecKeyDataIdUnknown, NULL);
874 data = xmlSecKeyGetData(key, dataId);
879 data = xmlSecKeyDataCreate(dataId);
881 xmlSecError(XMLSEC_ERRORS_HERE,
883 "xmlSecKeyDataCreate",
884 XMLSEC_ERRORS_R_XMLSEC_FAILED,
886 xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(dataId)));
890 ret = xmlSecKeyAdoptData(key, data);
892 xmlSecError(XMLSEC_ERRORS_HERE,
894 "xmlSecKeyAdoptData",
895 XMLSEC_ERRORS_R_XMLSEC_FAILED,
897 xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(dataId)));
898 xmlSecKeyDataDestroy(data);
906 * xmlSecKeyAdoptData:
907 * @key: the pointer to key.
908 * @data: the pointer to key data.
910 * Adds @data to the @key. The @data object will be destroyed
913 * Returns: 0 on success or a negative value otherwise.
916 xmlSecKeyAdoptData(xmlSecKeyPtr key, xmlSecKeyDataPtr data) {
917 xmlSecKeyDataPtr tmp;
918 xmlSecSize pos, size;
920 xmlSecAssert2(key != NULL, -1);
921 xmlSecAssert2(xmlSecKeyDataIsValid(data), -1);
924 if(data->id == xmlSecKeyDataValueId) {
925 if(key->value != NULL) {
926 xmlSecKeyDataDestroy(key->value);
932 if(key->dataList == NULL) {
933 key->dataList = xmlSecPtrListCreate(xmlSecKeyDataListId);
934 if(key->dataList == NULL) {
935 xmlSecError(XMLSEC_ERRORS_HERE,
937 "xmlSecPtrListCreate",
938 XMLSEC_ERRORS_R_XMLSEC_FAILED,
939 XMLSEC_ERRORS_NO_MESSAGE);
945 size = xmlSecPtrListGetSize(key->dataList);
946 for(pos = 0; pos < size; ++pos) {
947 tmp = (xmlSecKeyDataPtr)xmlSecPtrListGetItem(key->dataList, pos);
948 if((tmp != NULL) && (tmp->id == data->id)) {
949 return(xmlSecPtrListSet(key->dataList, data, pos));
953 return(xmlSecPtrListAdd(key->dataList, data));
957 * xmlSecKeyDebugDump:
958 * @key: the pointer to key.
959 * @output: the pointer to output FILE.
961 * Prints the information about the @key to the @output.
964 xmlSecKeyDebugDump(xmlSecKeyPtr key, FILE *output) {
965 xmlSecAssert(xmlSecKeyIsValid(key));
966 xmlSecAssert(output != NULL);
968 fprintf(output, "== KEY\n");
969 fprintf(output, "=== method: %s\n",
970 (key->value->id->dataNodeName != NULL) ?
971 (char*)(key->value->id->dataNodeName) : "NULL");
973 fprintf(output, "=== key type: ");
974 if((xmlSecKeyGetType(key) & xmlSecKeyDataTypeSymmetric) != 0) {
975 fprintf(output, "Symmetric\n");
976 } else if((xmlSecKeyGetType(key) & xmlSecKeyDataTypePrivate) != 0) {
977 fprintf(output, "Private\n");
978 } else if((xmlSecKeyGetType(key) & xmlSecKeyDataTypePublic) != 0) {
979 fprintf(output, "Public\n");
981 fprintf(output, "Unknown\n");
984 if(key->name != NULL) {
985 fprintf(output, "=== key name: %s\n", key->name);
987 fprintf(output, "=== key usage: %d\n", key->usage);
988 if(key->notValidBefore < key->notValidAfter) {
989 fprintf(output, "=== key not valid before: %ld\n", (unsigned long)key->notValidBefore);
990 fprintf(output, "=== key not valid after: %ld\n", (unsigned long)key->notValidAfter);
992 if(key->value != NULL) {
993 xmlSecKeyDataDebugDump(key->value, output);
995 if(key->dataList != NULL) {
996 xmlSecPtrListDebugDump(key->dataList, output);
1001 * xmlSecKeyDebugXmlDump:
1002 * @key: the pointer to key.
1003 * @output: the pointer to output FILE.
1005 * Prints the information about the @key to the @output in XML format.
1008 xmlSecKeyDebugXmlDump(xmlSecKeyPtr key, FILE *output) {
1009 xmlSecAssert(xmlSecKeyIsValid(key));
1010 xmlSecAssert(output != NULL);
1012 fprintf(output, "<KeyInfo>\n");
1014 fprintf(output, "<KeyMethod>");
1015 xmlSecPrintXmlString(output, key->value->id->dataNodeName);
1016 fprintf(output, "</KeyMethod>\n");
1018 fprintf(output, "<KeyType>");
1019 if((xmlSecKeyGetType(key) & xmlSecKeyDataTypeSymmetric) != 0) {
1020 fprintf(output, "Symmetric\n");
1021 } else if((xmlSecKeyGetType(key) & xmlSecKeyDataTypePrivate) != 0) {
1022 fprintf(output, "Private\n");
1023 } else if((xmlSecKeyGetType(key) & xmlSecKeyDataTypePublic) != 0) {
1024 fprintf(output, "Public\n");
1026 fprintf(output, "Unknown\n");
1028 fprintf(output, "</KeyType>\n");
1030 fprintf(output, "<KeyName>");
1031 xmlSecPrintXmlString(output, key->name);
1032 fprintf(output, "</KeyName>\n");
1034 if(key->notValidBefore < key->notValidAfter) {
1035 fprintf(output, "<KeyValidity notValidBefore=\"%ld\" notValidAfter=\"%ld\"/>\n",
1036 (unsigned long)key->notValidBefore,
1037 (unsigned long)key->notValidAfter);
1040 if(key->value != NULL) {
1041 xmlSecKeyDataDebugXmlDump(key->value, output);
1043 if(key->dataList != NULL) {
1044 xmlSecPtrListDebugXmlDump(key->dataList, output);
1047 fprintf(output, "</KeyInfo>\n");
1051 * xmlSecKeyGenerate:
1052 * @dataId: the requested key klass (rsa, dsa, aes, ...).
1053 * @sizeBits: the new key size (in bits!).
1054 * @type: the new key type (session, permanent, ...).
1056 * Generates new key of requested klass @dataId and @type.
1058 * Returns: pointer to newly created key or NULL if an error occurs.
1061 xmlSecKeyGenerate(xmlSecKeyDataId dataId, xmlSecSize sizeBits, xmlSecKeyDataType type) {
1063 xmlSecKeyDataPtr data;
1066 xmlSecAssert2(dataId != xmlSecKeyDataIdUnknown, NULL);
1068 data = xmlSecKeyDataCreate(dataId);
1070 xmlSecError(XMLSEC_ERRORS_HERE,
1071 xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(dataId)),
1072 "xmlSecKeyDataCreate",
1073 XMLSEC_ERRORS_R_XMLSEC_FAILED,
1074 XMLSEC_ERRORS_NO_MESSAGE);
1078 ret = xmlSecKeyDataGenerate(data, sizeBits, type);
1080 xmlSecError(XMLSEC_ERRORS_HERE,
1081 xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(dataId)),
1082 "xmlSecKeyDataGenerate",
1083 XMLSEC_ERRORS_R_XMLSEC_FAILED,
1084 "size=%d;type=%d", sizeBits, type);
1085 xmlSecKeyDataDestroy(data);
1089 key = xmlSecKeyCreate();
1091 xmlSecError(XMLSEC_ERRORS_HERE,
1092 xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(dataId)),
1094 XMLSEC_ERRORS_R_XMLSEC_FAILED,
1095 XMLSEC_ERRORS_NO_MESSAGE);
1096 xmlSecKeyDataDestroy(data);
1100 ret = xmlSecKeySetValue(key, data);
1102 xmlSecError(XMLSEC_ERRORS_HERE,
1103 xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(dataId)),
1104 "xmlSecKeySetValue",
1105 XMLSEC_ERRORS_R_XMLSEC_FAILED,
1106 XMLSEC_ERRORS_NO_MESSAGE);
1107 xmlSecKeyDataDestroy(data);
1108 xmlSecKeyDestroy(key);
1116 * xmlSecKeyGenerateByName:
1117 * @name: the requested key klass name (rsa, dsa, aes, ...).
1118 * @sizeBits: the new key size (in bits!).
1119 * @type: the new key type (session, permanent, ...).
1121 * Generates new key of requested @klass and @type.
1123 * Returns: pointer to newly created key or NULL if an error occurs.
1126 xmlSecKeyGenerateByName(const xmlChar* name, xmlSecSize sizeBits, xmlSecKeyDataType type) {
1127 xmlSecKeyDataId dataId;
1129 xmlSecAssert2(name != NULL, NULL);
1131 dataId = xmlSecKeyDataIdListFindByName(xmlSecKeyDataIdsGet(), name, xmlSecKeyDataUsageAny);
1132 if(dataId == xmlSecKeyDataIdUnknown) {
1133 xmlSecError(XMLSEC_ERRORS_HERE,
1135 xmlSecErrorsSafeString(name),
1136 XMLSEC_ERRORS_R_KEY_DATA_NOT_FOUND,
1137 XMLSEC_ERRORS_NO_MESSAGE);
1141 return(xmlSecKeyGenerate(dataId, sizeBits, type));
1145 * xmlSecKeyReadBuffer:
1146 * @dataId: the key value data klass.
1147 * @buffer: the buffer that contains the binary data.
1149 * Reads the key value of klass @dataId from a buffer.
1151 * Returns: pointer to newly created key or NULL if an error occurs.
1154 xmlSecKeyReadBuffer(xmlSecKeyDataId dataId, xmlSecBuffer* buffer) {
1155 xmlSecKeyInfoCtx keyInfoCtx;
1159 xmlSecAssert2(dataId != xmlSecKeyDataIdUnknown, NULL);
1160 xmlSecAssert2(buffer != NULL, NULL);
1162 /* create key data */
1163 key = xmlSecKeyCreate();
1165 xmlSecError(XMLSEC_ERRORS_HERE,
1166 xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(dataId)),
1168 XMLSEC_ERRORS_R_XMLSEC_FAILED,
1169 XMLSEC_ERRORS_NO_MESSAGE);
1173 ret = xmlSecKeyInfoCtxInitialize(&keyInfoCtx, NULL);
1175 xmlSecError(XMLSEC_ERRORS_HERE,
1176 xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(dataId)),
1177 "xmlSecKeyInfoCtxInitialize",
1178 XMLSEC_ERRORS_R_XMLSEC_FAILED,
1179 XMLSEC_ERRORS_NO_MESSAGE);
1180 xmlSecKeyDestroy(key);
1184 keyInfoCtx.keyReq.keyType = xmlSecKeyDataTypeAny;
1185 ret = xmlSecKeyDataBinRead(dataId, key,
1186 xmlSecBufferGetData(buffer),
1187 xmlSecBufferGetSize(buffer),
1190 xmlSecError(XMLSEC_ERRORS_HERE,
1191 xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(dataId)),
1192 "xmlSecKeyDataBinRead",
1193 XMLSEC_ERRORS_R_XMLSEC_FAILED,
1194 XMLSEC_ERRORS_NO_MESSAGE);
1195 xmlSecKeyInfoCtxFinalize(&keyInfoCtx);
1196 xmlSecKeyDestroy(key);
1199 xmlSecKeyInfoCtxFinalize(&keyInfoCtx);
1205 * xmlSecKeyReadBinaryFile:
1206 * @dataId: the key value data klass.
1207 * @filename: the key binary filename.
1209 * Reads the key value of klass @dataId from a binary file @filename.
1211 * Returns: pointer to newly created key or NULL if an error occurs.
1214 xmlSecKeyReadBinaryFile(xmlSecKeyDataId dataId, const char* filename) {
1216 xmlSecBuffer buffer;
1219 xmlSecAssert2(dataId != xmlSecKeyDataIdUnknown, NULL);
1220 xmlSecAssert2(filename != NULL, NULL);
1222 /* read file to buffer */
1223 ret = xmlSecBufferInitialize(&buffer, 0);
1225 xmlSecError(XMLSEC_ERRORS_HERE,
1226 xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(dataId)),
1227 "xmlSecBufferInitialize",
1228 XMLSEC_ERRORS_R_XMLSEC_FAILED,
1229 XMLSEC_ERRORS_NO_MESSAGE);
1233 ret = xmlSecBufferReadFile(&buffer, filename);
1235 xmlSecError(XMLSEC_ERRORS_HERE,
1236 xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(dataId)),
1237 "xmlSecBufferReadFile",
1238 XMLSEC_ERRORS_R_XMLSEC_FAILED,
1240 xmlSecErrorsSafeString(filename));
1241 xmlSecBufferFinalize(&buffer);
1245 key = xmlSecKeyReadBuffer(dataId, &buffer);
1247 xmlSecError(XMLSEC_ERRORS_HERE,
1248 xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(dataId)),
1249 "xmlSecKeyReadBuffer",
1250 XMLSEC_ERRORS_R_XMLSEC_FAILED,
1252 xmlSecErrorsSafeString(filename));
1253 xmlSecBufferFinalize(&buffer);
1257 xmlSecBufferFinalize(&buffer);
1262 * xmlSecKeyReadMemory:
1263 * @dataId: the key value data klass.
1264 * @data: the memory containing the key
1265 * @dataSize: the size of the memory block
1267 * Reads the key value of klass @dataId from a memory block @data.
1269 * Returns: pointer to newly created key or NULL if an error occurs.
1272 xmlSecKeyReadMemory(xmlSecKeyDataId dataId, const xmlSecByte* data, xmlSecSize dataSize) {
1273 xmlSecBuffer buffer;
1277 xmlSecAssert2(dataId != xmlSecKeyDataIdUnknown, NULL);
1278 xmlSecAssert2(data != NULL, NULL);
1279 xmlSecAssert2(dataSize > 0, NULL);
1281 /* read file to buffer */
1282 ret = xmlSecBufferInitialize(&buffer, 0);
1284 xmlSecError(XMLSEC_ERRORS_HERE,
1285 xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(dataId)),
1286 "xmlSecBufferInitialize",
1287 XMLSEC_ERRORS_R_XMLSEC_FAILED,
1288 XMLSEC_ERRORS_NO_MESSAGE);
1292 if (xmlSecBufferAppend(&buffer, data, dataSize) < 0) {
1293 xmlSecError(XMLSEC_ERRORS_HERE,
1294 xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(dataId)),
1295 "xmlSecBufferAppend",
1296 XMLSEC_ERRORS_R_XMLSEC_FAILED,
1297 XMLSEC_ERRORS_NO_MESSAGE);
1298 xmlSecBufferFinalize(&buffer);
1302 key = xmlSecKeyReadBuffer(dataId, &buffer);
1304 xmlSecError(XMLSEC_ERRORS_HERE,
1305 xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(dataId)),
1306 "xmlSecKeyReadBuffer",
1307 XMLSEC_ERRORS_R_XMLSEC_FAILED,
1308 XMLSEC_ERRORS_NO_MESSAGE);
1309 xmlSecBufferFinalize(&buffer);
1313 xmlSecBufferFinalize(&buffer);
1318 * xmlSecKeysMngrGetKey:
1319 * @keyInfoNode: the pointer to <dsig:KeyInfo/> node.
1320 * @keyInfoCtx: the pointer to <dsig:KeyInfo/> node processing context.
1322 * Reads the <dsig:KeyInfo/> node @keyInfoNode and extracts the key.
1324 * Returns: the pointer to key or NULL if the key is not found or
1328 xmlSecKeysMngrGetKey(xmlNodePtr keyInfoNode, xmlSecKeyInfoCtxPtr keyInfoCtx) {
1332 xmlSecAssert2(keyInfoCtx != NULL, NULL);
1335 /* first try to read data from <dsig:KeyInfo/> node */
1336 key = xmlSecKeyCreate();
1338 xmlSecError(XMLSEC_ERRORS_HERE,
1341 XMLSEC_ERRORS_R_XMLSEC_FAILED,
1342 XMLSEC_ERRORS_NO_MESSAGE);
1346 if(keyInfoNode != NULL) {
1347 ret = xmlSecKeyInfoNodeRead(keyInfoNode, key, keyInfoCtx);
1349 xmlSecError(XMLSEC_ERRORS_HERE,
1351 "xmlSecKeyInfoNodeRead",
1352 XMLSEC_ERRORS_R_XMLSEC_FAILED,
1354 xmlSecErrorsSafeString(xmlSecNodeGetName(keyInfoNode)));
1355 xmlSecKeyDestroy(key);
1359 if((xmlSecKeyGetValue(key) != NULL) &&
1360 (xmlSecKeyMatch(key, NULL, &(keyInfoCtx->keyReq)) != 0)) {
1364 xmlSecKeyDestroy(key);
1366 /* if we have keys manager, try it */
1367 if(keyInfoCtx->keysMngr != NULL) {
1368 key = xmlSecKeysMngrFindKey(keyInfoCtx->keysMngr, NULL, keyInfoCtx);
1370 xmlSecError(XMLSEC_ERRORS_HERE,
1372 "xmlSecKeysMngrFindKey",
1373 XMLSEC_ERRORS_R_XMLSEC_FAILED,
1374 XMLSEC_ERRORS_NO_MESSAGE);
1377 if(xmlSecKeyGetValue(key) != NULL) {
1380 xmlSecKeyDestroy(key);
1383 xmlSecError(XMLSEC_ERRORS_HERE,
1386 XMLSEC_ERRORS_R_KEY_NOT_FOUND,
1387 XMLSEC_ERRORS_NO_MESSAGE);
1391 /***********************************************************************
1395 **********************************************************************/
1396 static xmlSecPtrListKlass xmlSecKeyPtrListKlass = {
1397 BAD_CAST "keys-list",
1398 (xmlSecPtrDuplicateItemMethod)xmlSecKeyDuplicate, /* xmlSecPtrDuplicateItemMethod duplicateItem; */
1399 (xmlSecPtrDestroyItemMethod)xmlSecKeyDestroy, /* xmlSecPtrDestroyItemMethod destroyItem; */
1400 (xmlSecPtrDebugDumpItemMethod)xmlSecKeyDebugDump, /* xmlSecPtrDebugDumpItemMethod debugDumpItem; */
1401 (xmlSecPtrDebugDumpItemMethod)xmlSecKeyDebugXmlDump,/* xmlSecPtrDebugDumpItemMethod debugXmlDumpItem; */
1405 * xmlSecKeyPtrListGetKlass:
1407 * The keys list klass.
1409 * Returns: keys list id.
1412 xmlSecKeyPtrListGetKlass(void) {
1413 return(&xmlSecKeyPtrListKlass);