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>
17 #include <libxml/tree.h>
19 #include <xmlsec/xmlsec.h>
20 #include <xmlsec/xmltree.h>
21 #include <xmlsec/keys.h>
22 #include <xmlsec/keyinfo.h>
23 #include <xmlsec/transforms.h>
24 #include <xmlsec/base64.h>
25 #include <xmlsec/keyinfo.h>
26 #include <xmlsec/errors.h>
29 /**************************************************************************
31 * Global xmlSecKeyDataIds list functions
33 *************************************************************************/
34 static xmlSecPtrList xmlSecAllKeyDataIds;
37 * xmlSecKeyDataIdsGet:
39 * Gets global registered key data klasses list.
41 * Returns: the pointer to list of all registered key data klasses.
44 xmlSecKeyDataIdsGet(void) {
45 return(&xmlSecAllKeyDataIds);
49 * xmlSecKeyDataIdsInit:
51 * Initializes the key data klasses. This function is called from the
52 * #xmlSecInit function and the application should not call it directly.
54 * Returns: 0 on success or a negative value if an error occurs.
57 xmlSecKeyDataIdsInit(void) {
60 ret = xmlSecPtrListInitialize(xmlSecKeyDataIdsGet(), xmlSecKeyDataIdListId);
62 xmlSecError(XMLSEC_ERRORS_HERE,
64 "xmlSecPtrListPtrInitialize",
65 XMLSEC_ERRORS_R_XMLSEC_FAILED,
66 "xmlSecKeyDataIdListId");
70 ret = xmlSecKeyDataIdsRegisterDefault();
72 xmlSecError(XMLSEC_ERRORS_HERE,
74 "xmlSecKeyDataIdsRegisterDefault",
75 XMLSEC_ERRORS_R_XMLSEC_FAILED,
76 XMLSEC_ERRORS_NO_MESSAGE);
84 * xmlSecKeyDataIdsShutdown:
86 * Shuts down the keys data klasses. This function is called from the
87 * #xmlSecShutdown function and the application should not call it directly.
90 xmlSecKeyDataIdsShutdown(void) {
91 xmlSecPtrListFinalize(xmlSecKeyDataIdsGet());
95 * xmlSecKeyDataIdsRegister:
96 * @id: the key data klass.
98 * Registers @id in the global list of key data klasses.
100 * Returns: 0 on success or a negative value if an error occurs.
103 xmlSecKeyDataIdsRegister(xmlSecKeyDataId id) {
106 xmlSecAssert2(id != xmlSecKeyDataIdUnknown, -1);
108 ret = xmlSecPtrListAdd(xmlSecKeyDataIdsGet(), (xmlSecPtr)id);
110 xmlSecError(XMLSEC_ERRORS_HERE,
113 XMLSEC_ERRORS_R_XMLSEC_FAILED,
115 xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)));
123 * xmlSecKeyDataIdsRegisterDefault:
125 * Registers default (implemented by XML Security Library)
126 * key data klasses: <dsig:KeyName/> element processing klass,
127 * <dsig:KeyValue/> element processing klass, ...
129 * Returns: 0 on success or a negative value if an error occurs.
132 xmlSecKeyDataIdsRegisterDefault(void) {
133 if(xmlSecKeyDataIdsRegister(xmlSecKeyDataNameId) < 0) {
134 xmlSecError(XMLSEC_ERRORS_HERE,
136 "xmlSecKeyDataIdsRegister",
137 XMLSEC_ERRORS_R_XMLSEC_FAILED,
138 "xmlSecKeyDataNameId");
142 if(xmlSecKeyDataIdsRegister(xmlSecKeyDataValueId) < 0) {
143 xmlSecError(XMLSEC_ERRORS_HERE,
145 "xmlSecKeyDataIdsRegister",
146 XMLSEC_ERRORS_R_XMLSEC_FAILED,
147 "xmlSecKeyDataValueId");
151 if(xmlSecKeyDataIdsRegister(xmlSecKeyDataRetrievalMethodId) < 0) {
152 xmlSecError(XMLSEC_ERRORS_HERE,
154 "xmlSecKeyDataIdsRegister",
155 XMLSEC_ERRORS_R_XMLSEC_FAILED,
156 "xmlSecKeyDataRetrievalMethodId");
160 #ifndef XMLSEC_NO_XMLENC
161 if(xmlSecKeyDataIdsRegister(xmlSecKeyDataEncryptedKeyId) < 0) {
162 xmlSecError(XMLSEC_ERRORS_HERE,
164 "xmlSecKeyDataIdsRegister",
165 XMLSEC_ERRORS_R_XMLSEC_FAILED,
166 "xmlSecKeyDataEncryptedKeyId");
169 #endif /* XMLSEC_NO_XMLENC */
174 /**************************************************************************
176 * xmlSecKeyData functions
178 *************************************************************************/
180 * xmlSecKeyDataCreate:
183 * Allocates and initializes new key data of the specified type @id.
184 * Caller is responsible for destroing returend object with
185 * #xmlSecKeyDataDestroy function.
187 * Returns: the pointer to newly allocated key data structure
188 * or NULL if an error occurs.
191 xmlSecKeyDataCreate(xmlSecKeyDataId id) {
192 xmlSecKeyDataPtr data;
195 xmlSecAssert2(id != NULL, NULL);
196 xmlSecAssert2(id->klassSize >= sizeof(xmlSecKeyDataKlass), NULL);
197 xmlSecAssert2(id->objSize >= sizeof(xmlSecKeyData), NULL);
198 xmlSecAssert2(id->name != NULL, NULL);
200 /* Allocate a new xmlSecKeyData and fill the fields. */
201 data = (xmlSecKeyDataPtr)xmlMalloc(id->objSize);
203 xmlSecError(XMLSEC_ERRORS_HERE,
204 xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
206 XMLSEC_ERRORS_R_MALLOC_FAILED,
207 "size=%d", id->objSize);
210 memset(data, 0, id->objSize);
213 if(id->initialize != NULL) {
214 ret = (id->initialize)(data);
216 xmlSecError(XMLSEC_ERRORS_HERE,
217 xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
219 XMLSEC_ERRORS_R_XMLSEC_FAILED,
220 XMLSEC_ERRORS_NO_MESSAGE);
221 xmlSecKeyDataDestroy(data);
230 * xmlSecKeyDataDuplicate:
231 * @data: the pointer to the key data.
233 * Creates a duplicate of the given @data. Caller is responsible for
234 * destroing returend object with #xmlSecKeyDataDestroy function.
236 * Returns: the pointer to newly allocated key data structure
237 * or NULL if an error occurs.
240 xmlSecKeyDataDuplicate(xmlSecKeyDataPtr data) {
241 xmlSecKeyDataPtr newData;
244 xmlSecAssert2(xmlSecKeyDataIsValid(data), NULL);
245 xmlSecAssert2(data->id->duplicate != NULL, NULL);
247 newData = xmlSecKeyDataCreate(data->id);
248 if(newData == NULL) {
249 xmlSecError(XMLSEC_ERRORS_HERE,
250 xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
251 "xmlSecKeyDataCreate",
252 XMLSEC_ERRORS_R_XMLSEC_FAILED,
253 XMLSEC_ERRORS_NO_MESSAGE);
257 ret = (data->id->duplicate)(newData, data);
258 if(newData == NULL) {
259 xmlSecError(XMLSEC_ERRORS_HERE,
260 xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
262 XMLSEC_ERRORS_R_XMLSEC_FAILED,
263 XMLSEC_ERRORS_NO_MESSAGE);
264 xmlSecKeyDataDestroy(newData);
272 * xmlSecKeyDataDestroy:
273 * @data: the pointer to the key data.
275 * Destroys the data and frees all allocated memory.
278 xmlSecKeyDataDestroy(xmlSecKeyDataPtr data) {
279 xmlSecAssert(xmlSecKeyDataIsValid(data));
280 xmlSecAssert(data->id->objSize > 0);
282 if(data->id->finalize != NULL) {
283 (data->id->finalize)(data);
285 memset(data, 0, data->id->objSize);
291 * xmlSecKeyDataXmlRead:
292 * @id: the data klass.
293 * @key: the destination key.
294 * @node: the pointer to an XML node.
295 * @keyInfoCtx: the pointer to <dsig:KeyInfo/> element processing context.
297 * Reads the key data of klass @id from XML @node and adds them to @key.
299 * Returns: 0 on success or a negative value otherwise.
302 xmlSecKeyDataXmlRead(xmlSecKeyDataId id, xmlSecKeyPtr key, xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx) {
303 xmlSecAssert2(id != NULL, -1);
304 xmlSecAssert2(id->xmlRead != NULL, -1);
305 xmlSecAssert2(key != NULL, -1);
306 xmlSecAssert2(node != NULL, -1);
308 return((id->xmlRead)(id, key, node, keyInfoCtx));
312 * xmlSecKeyDataXmlWrite:
313 * @id: the data klass.
314 * @key: the source key.
315 * @node: the pointer to an XML node.
316 * @keyInfoCtx: the pointer to <dsig:KeyInfo/> element processing context.
318 * Writes the key data of klass @id from @key to an XML @node.
320 * Returns: 0 on success or a negative value otherwise.
323 xmlSecKeyDataXmlWrite(xmlSecKeyDataId id, xmlSecKeyPtr key, xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx) {
324 xmlSecAssert2(id != NULL, -1);
325 xmlSecAssert2(id->xmlWrite != NULL, -1);
326 xmlSecAssert2(key != NULL, -1);
327 xmlSecAssert2(node != NULL, -1);
329 return((id->xmlWrite)(id, key, node, keyInfoCtx));
333 * xmlSecKeyDataBinRead:
334 * @id: the data klass.
335 * @key: the destination key.
336 * @buf: the input binary buffer.
337 * @bufSize: the input buffer size.
338 * @keyInfoCtx: the <dsig:KeyInfo/> node processing context.
340 * Reads the key data of klass @id from binary buffer @buf to @key.
342 * Returns: 0 on success or a negative value if an error occurs.
345 xmlSecKeyDataBinRead(xmlSecKeyDataId id, xmlSecKeyPtr key,
346 const xmlSecByte* buf, xmlSecSize bufSize,
347 xmlSecKeyInfoCtxPtr keyInfoCtx) {
348 xmlSecAssert2(id != NULL, -1);
349 xmlSecAssert2(id->binRead != NULL, -1);
350 xmlSecAssert2(key != NULL, -1);
351 xmlSecAssert2(buf != NULL, -1);
353 return((id->binRead)(id, key, buf, bufSize, keyInfoCtx));
357 * xmlSecKeyDataBinWrite:
358 * @id: the data klass.
359 * @key: the source key.
360 * @buf: the output binary buffer.
361 * @bufSize: the output buffer size.
362 * @keyInfoCtx: the <dsig:KeyInfo/> node processing context.
364 * Writes the key data of klass @id from the @key to a binary buffer @buf.
366 * Returns: 0 on success or a negative value if an error occurs.
369 xmlSecKeyDataBinWrite(xmlSecKeyDataId id, xmlSecKeyPtr key,
370 xmlSecByte** buf, xmlSecSize* bufSize,
371 xmlSecKeyInfoCtxPtr keyInfoCtx) {
372 xmlSecAssert2(id != NULL, -1);
373 xmlSecAssert2(id->binWrite != NULL, -1);
374 xmlSecAssert2(key != NULL, -1);
375 xmlSecAssert2(buf != NULL, -1);
377 return((id->binWrite)(id, key, buf, bufSize, keyInfoCtx));
381 * xmlSecKeyDataGenerate:
382 * @data: the pointer to key data.
383 * @sizeBits: the desired key data size (in bits).
384 * @type: the desired key data type.
386 * Generates new key data of given size and type.
388 * Returns: 0 on success or a negative value otherwise.
391 xmlSecKeyDataGenerate(xmlSecKeyDataPtr data, xmlSecSize sizeBits,
392 xmlSecKeyDataType type) {
395 xmlSecAssert2(xmlSecKeyDataIsValid(data), -1);
396 xmlSecAssert2(data->id->generate != NULL, -1);
399 ret = data->id->generate(data, sizeBits, type);
401 xmlSecError(XMLSEC_ERRORS_HERE,
402 xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
404 XMLSEC_ERRORS_R_XMLSEC_FAILED,
405 "size=%d", sizeBits);
412 * xmlSecKeyDataGetType:
413 * @data: the pointer to key data.
415 * Gets key data type.
417 * Returns: key data type.
420 xmlSecKeyDataGetType(xmlSecKeyDataPtr data) {
421 xmlSecAssert2(xmlSecKeyDataIsValid(data), xmlSecKeyDataTypeUnknown);
422 xmlSecAssert2(data->id->getType != NULL, xmlSecKeyDataTypeUnknown);
424 return(data->id->getType(data));
428 * xmlSecKeyDataGetSize:
429 * @data: the pointer to key data.
431 * Gets key data size.
433 * Returns: key data size (in bits).
436 xmlSecKeyDataGetSize(xmlSecKeyDataPtr data) {
437 xmlSecAssert2(xmlSecKeyDataIsValid(data), 0);
438 xmlSecAssert2(data->id->getSize != NULL, 0);
440 return(data->id->getSize(data));
444 * xmlSecKeyDataGetIdentifier:
445 * @data: the pointer to key data.
447 * Gets key data identifier string.
449 * Returns: key data id string.
452 xmlSecKeyDataGetIdentifier(xmlSecKeyDataPtr data) {
453 xmlSecAssert2(xmlSecKeyDataIsValid(data), NULL);
454 xmlSecAssert2(data->id->getIdentifier != NULL, NULL);
456 return(data->id->getIdentifier(data));
460 * xmlSecKeyDataDebugDump:
461 * @data: the pointer to key data.
462 * @output: the pointer to output FILE.
464 * Prints key data debug info.
467 xmlSecKeyDataDebugDump(xmlSecKeyDataPtr data, FILE *output) {
468 xmlSecAssert(xmlSecKeyDataIsValid(data));
469 xmlSecAssert(data->id->debugDump != NULL);
470 xmlSecAssert(output != NULL);
472 data->id->debugDump(data, output);
476 * xmlSecKeyDataDebugXmlDump:
477 * @data: the pointer to key data.
478 * @output: the pointer to output FILE.
480 * Prints key data debug info in XML format.
483 xmlSecKeyDataDebugXmlDump(xmlSecKeyDataPtr data, FILE *output) {
484 xmlSecAssert(xmlSecKeyDataIsValid(data));
485 xmlSecAssert(data->id->debugXmlDump != NULL);
486 xmlSecAssert(output != NULL);
488 data->id->debugXmlDump(data, output);
491 /**************************************************************************
493 * xmlSecKeyDataBinary methods
495 * key (xmlSecBuffer) is located after xmlSecKeyData structure
497 *************************************************************************/
499 * xmlSecKeyDataBinaryValueInitialize:
500 * @data: the pointer to binary key data.
502 * Initializes key data.
504 * Returns: 0 on success or a negative value otherwise.
507 xmlSecKeyDataBinaryValueInitialize(xmlSecKeyDataPtr data) {
508 xmlSecBufferPtr buffer;
511 xmlSecAssert2(xmlSecKeyDataIsValid(data), -1);
512 xmlSecAssert2(xmlSecKeyDataCheckSize(data, xmlSecKeyDataBinarySize), -1);
514 /* initialize buffer */
515 buffer = xmlSecKeyDataBinaryValueGetBuffer(data);
516 xmlSecAssert2(buffer != NULL, -1);
518 ret = xmlSecBufferInitialize(buffer, 0);
520 xmlSecError(XMLSEC_ERRORS_HERE,
521 xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
522 "xmlSecBufferInitialize",
523 XMLSEC_ERRORS_R_XMLSEC_FAILED,
524 XMLSEC_ERRORS_NO_MESSAGE);
532 * xmlSecKeyDataBinaryValueDuplicate:
533 * @dst: the pointer to destination binary key data.
534 * @src: the pointer to source binary key data.
536 * Copies binary key data from @src to @dst.
538 * Returns: 0 on success or a negative value otherwise.
541 xmlSecKeyDataBinaryValueDuplicate(xmlSecKeyDataPtr dst, xmlSecKeyDataPtr src) {
542 xmlSecBufferPtr buffer;
545 xmlSecAssert2(xmlSecKeyDataIsValid(dst), -1);
546 xmlSecAssert2(xmlSecKeyDataCheckSize(dst, xmlSecKeyDataBinarySize), -1);
547 xmlSecAssert2(xmlSecKeyDataIsValid(src), -1);
548 xmlSecAssert2(xmlSecKeyDataCheckSize(src, xmlSecKeyDataBinarySize), -1);
550 buffer = xmlSecKeyDataBinaryValueGetBuffer(src);
551 xmlSecAssert2(buffer != NULL, -1);
554 ret = xmlSecKeyDataBinaryValueSetBuffer(dst,
555 xmlSecBufferGetData(buffer),
556 xmlSecBufferGetSize(buffer));
558 xmlSecError(XMLSEC_ERRORS_HERE,
559 xmlSecErrorsSafeString(xmlSecKeyDataGetName(dst)),
560 "xmlSecKeyDataBinaryValueSetBuffer",
561 XMLSEC_ERRORS_R_XMLSEC_FAILED,
562 XMLSEC_ERRORS_NO_MESSAGE);
570 * xmlSecKeyDataBinaryValueFinalize:
571 * @data: the pointer to binary key data.
573 * Cleans up binary key data.
576 xmlSecKeyDataBinaryValueFinalize(xmlSecKeyDataPtr data) {
577 xmlSecBufferPtr buffer;
579 xmlSecAssert(xmlSecKeyDataIsValid(data));
580 xmlSecAssert(xmlSecKeyDataCheckSize(data, xmlSecKeyDataBinarySize));
582 /* initialize buffer */
583 buffer = xmlSecKeyDataBinaryValueGetBuffer(data);
584 xmlSecAssert(buffer != NULL);
586 xmlSecBufferFinalize(buffer);
590 * xmlSecKeyDataBinaryValueXmlRead:
591 * @id: the data klass.
592 * @key: the pointer to destination key.
593 * @node: the pointer to an XML node.
594 * @keyInfoCtx: the pointer to <dsig:KeyInfo/> element processing context.
596 * Reads binary key data from @node to the key by base64 decoding the @node content.
598 * Returns: 0 on success or a negative value otherwise.
601 xmlSecKeyDataBinaryValueXmlRead(xmlSecKeyDataId id, xmlSecKeyPtr key,
602 xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx) {
605 xmlSecKeyDataPtr data;
608 xmlSecAssert2(id != xmlSecKeyDataIdUnknown, -1);
609 xmlSecAssert2(key != NULL, -1);
610 xmlSecAssert2(node != NULL, -1);
611 xmlSecAssert2(keyInfoCtx != NULL, -1);
613 str = xmlNodeGetContent(node);
615 xmlSecError(XMLSEC_ERRORS_HERE,
616 xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
617 xmlSecErrorsSafeString(xmlSecNodeGetName(node)),
618 XMLSEC_ERRORS_R_INVALID_NODE_CONTENT,
619 XMLSEC_ERRORS_NO_MESSAGE);
623 /* usual trick: decode into the same buffer */
624 ret = xmlSecBase64Decode(str, (xmlSecByte*)str, xmlStrlen(str));
626 xmlSecError(XMLSEC_ERRORS_HERE,
627 xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
628 "xmlSecBase64Decode",
629 XMLSEC_ERRORS_R_XMLSEC_FAILED,
630 XMLSEC_ERRORS_NO_MESSAGE);
636 /* check do we have a key already */
637 data = xmlSecKeyGetValue(key);
639 xmlSecBufferPtr buffer;
641 if(!xmlSecKeyDataCheckId(data, id)) {
642 xmlSecError(XMLSEC_ERRORS_HERE,
643 xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
644 xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
645 XMLSEC_ERRORS_R_KEY_DATA_ALREADY_EXIST,
646 XMLSEC_ERRORS_NO_MESSAGE);
651 buffer = xmlSecKeyDataBinaryValueGetBuffer(data);
652 if((buffer != NULL) && ((xmlSecSize)xmlSecBufferGetSize(buffer) != len)) {
653 xmlSecError(XMLSEC_ERRORS_HERE,
654 xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
655 xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
656 XMLSEC_ERRORS_R_KEY_DATA_ALREADY_EXIST,
657 "cur-data-size=%d;new-data-size=%d",
658 xmlSecBufferGetSize(buffer), len);
662 if((buffer != NULL) && (len > 0) && (memcmp(xmlSecBufferGetData(buffer), str, len) != 0)) {
663 xmlSecError(XMLSEC_ERRORS_HERE,
664 xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
665 xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
666 XMLSEC_ERRORS_R_KEY_DATA_ALREADY_EXIST,
667 "key already has a different value");
672 /* we already have exactly the same key */
677 /* we have binary key value with empty buffer */
681 data = xmlSecKeyDataCreate(id);
683 xmlSecError(XMLSEC_ERRORS_HERE,
684 xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
685 "xmlSecKeyDataCreate",
686 XMLSEC_ERRORS_R_XMLSEC_FAILED,
687 XMLSEC_ERRORS_NO_MESSAGE);
692 ret = xmlSecKeyDataBinaryValueSetBuffer(data, (xmlSecByte*)str, len);
694 xmlSecError(XMLSEC_ERRORS_HERE,
695 xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
696 "xmlSecKeyDataBinaryValueSetBuffer",
697 XMLSEC_ERRORS_R_XMLSEC_FAILED,
699 xmlSecKeyDataDestroy(data);
705 if(xmlSecKeyReqMatchKeyValue(&(keyInfoCtx->keyReq), data) != 1) {
706 xmlSecError(XMLSEC_ERRORS_HERE,
707 xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
708 "xmlSecKeyReqMatchKeyValue",
709 XMLSEC_ERRORS_R_XMLSEC_FAILED,
710 XMLSEC_ERRORS_NO_MESSAGE);
711 xmlSecKeyDataDestroy(data);
715 ret = xmlSecKeySetValue(key, data);
717 xmlSecError(XMLSEC_ERRORS_HERE,
718 xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
720 XMLSEC_ERRORS_R_XMLSEC_FAILED,
721 XMLSEC_ERRORS_NO_MESSAGE);
722 xmlSecKeyDataDestroy(data);
730 * xmlSecKeyDataBinaryValueXmlWrite:
731 * @id: the data klass.
732 * @key: the pointer to source key.
733 * @node: the pointer to an XML node.
734 * @keyInfoCtx: the pointer to <dsig:KeyInfo/> element processing context.
736 * Base64 encodes binary key data of klass @id from the @key and
737 * sets to the @node content.
739 * Returns: 0 on success or a negative value otherwise.
742 xmlSecKeyDataBinaryValueXmlWrite(xmlSecKeyDataId id, xmlSecKeyPtr key,
743 xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx) {
744 xmlSecBufferPtr buffer;
745 xmlSecKeyDataPtr value;
748 xmlSecAssert2(id != xmlSecKeyDataIdUnknown, -1);
749 xmlSecAssert2(key != NULL, -1);
750 xmlSecAssert2(node != NULL, -1);
751 xmlSecAssert2(keyInfoCtx != NULL, -1);
753 if((xmlSecKeyDataTypeSymmetric & keyInfoCtx->keyReq.keyType) == 0) {
754 /* we can have only symmetric key */
758 value = xmlSecKeyGetValue(key);
759 xmlSecAssert2(xmlSecKeyDataIsValid(value), -1);
761 buffer = xmlSecKeyDataBinaryValueGetBuffer(value);
762 xmlSecAssert2(buffer != NULL, -1);
764 str = xmlSecBase64Encode(xmlSecBufferGetData(buffer),
765 xmlSecBufferGetSize(buffer),
766 keyInfoCtx->base64LineSize);
768 xmlSecError(XMLSEC_ERRORS_HERE,
769 xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
770 "xmlSecBase64Encode",
771 XMLSEC_ERRORS_R_XMLSEC_FAILED,
772 XMLSEC_ERRORS_NO_MESSAGE);
775 xmlNodeSetContent(node, str);
781 * xmlSecKeyDataBinaryValueBinRead:
782 * @id: the data klass.
783 * @key: the pointer to destination key.
784 * @buf: the source binary buffer.
785 * @bufSize: the source binary buffer size.
786 * @keyInfoCtx: the pointer to <dsig:KeyInfo/> element processing context.
788 * Reads binary key data of the klass @id from @buf to the @key.
790 * Returns: 0 on success or a negative value otherwise.
793 xmlSecKeyDataBinaryValueBinRead(xmlSecKeyDataId id, xmlSecKeyPtr key,
794 const xmlSecByte* buf, xmlSecSize bufSize,
795 xmlSecKeyInfoCtxPtr keyInfoCtx) {
796 xmlSecKeyDataPtr data;
799 xmlSecAssert2(id != xmlSecKeyDataIdUnknown, -1);
800 xmlSecAssert2(key != NULL, -1);
801 xmlSecAssert2(buf != NULL, -1);
802 xmlSecAssert2(bufSize > 0, -1);
803 xmlSecAssert2(keyInfoCtx != NULL, -1);
805 /* check do we have a key already */
806 data = xmlSecKeyGetValue(key);
808 xmlSecBufferPtr buffer;
810 if(!xmlSecKeyDataCheckId(data, id)) {
811 xmlSecError(XMLSEC_ERRORS_HERE,
812 xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
813 xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
814 XMLSEC_ERRORS_R_KEY_DATA_ALREADY_EXIST,
815 XMLSEC_ERRORS_NO_MESSAGE);
819 buffer = xmlSecKeyDataBinaryValueGetBuffer(data);
820 if((buffer != NULL) && ((xmlSecSize)xmlSecBufferGetSize(buffer) != bufSize)) {
821 xmlSecError(XMLSEC_ERRORS_HERE,
822 xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
823 xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
824 XMLSEC_ERRORS_R_KEY_DATA_ALREADY_EXIST,
825 "cur-data-size=%d;new-data-size=%d",
826 xmlSecBufferGetSize(buffer), bufSize);
829 if((buffer != NULL) && (bufSize > 0) && (memcmp(xmlSecBufferGetData(buffer), buf, bufSize) != 0)) {
830 xmlSecError(XMLSEC_ERRORS_HERE,
831 xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
832 xmlSecErrorsSafeString(xmlSecKeyDataGetName(data)),
833 XMLSEC_ERRORS_R_KEY_DATA_ALREADY_EXIST,
834 "key already has a different value");
838 /* we already have exactly the same key */
842 /* we have binary key value with empty buffer */
845 data = xmlSecKeyDataCreate(id);
847 xmlSecError(XMLSEC_ERRORS_HERE,
848 xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
849 "xmlSecKeyDataCreate",
850 XMLSEC_ERRORS_R_XMLSEC_FAILED,
851 XMLSEC_ERRORS_NO_MESSAGE);
855 ret = xmlSecKeyDataBinaryValueSetBuffer(data, buf, bufSize);
857 xmlSecError(XMLSEC_ERRORS_HERE,
858 xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
859 "xmlSecKeyDataBinaryValueSetBuffer",
860 XMLSEC_ERRORS_R_XMLSEC_FAILED,
862 xmlSecKeyDataDestroy(data);
866 if(xmlSecKeyReqMatchKeyValue(&(keyInfoCtx->keyReq), data) != 1) {
867 xmlSecError(XMLSEC_ERRORS_HERE,
868 xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
869 "xmlSecKeyReqMatchKeyValue",
870 XMLSEC_ERRORS_R_XMLSEC_FAILED,
871 XMLSEC_ERRORS_NO_MESSAGE);
872 xmlSecKeyDataDestroy(data);
876 ret = xmlSecKeySetValue(key, data);
878 xmlSecError(XMLSEC_ERRORS_HERE,
879 xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
881 XMLSEC_ERRORS_R_XMLSEC_FAILED,
882 XMLSEC_ERRORS_NO_MESSAGE);
883 xmlSecKeyDataDestroy(data);
891 * xmlSecKeyDataBinaryValueBinWrite:
892 * @id: the data klass.
893 * @key: the pointer to source key.
894 * @buf: the destination binary buffer.
895 * @bufSize: the destination binary buffer size.
896 * @keyInfoCtx: the pointer to <dsig:KeyInfo/> element processing context.
898 * Writes binary key data of klass @id from the @key to @buf.
900 * Returns: 0 on success or a negative value otherwise.
903 xmlSecKeyDataBinaryValueBinWrite(xmlSecKeyDataId id, xmlSecKeyPtr key,
904 xmlSecByte** buf, xmlSecSize* bufSize,
905 xmlSecKeyInfoCtxPtr keyInfoCtx) {
906 xmlSecKeyDataPtr value;
907 xmlSecBufferPtr buffer;
909 xmlSecAssert2(id != xmlSecKeyDataIdUnknown, -1);
910 xmlSecAssert2(key != NULL, -1);
911 xmlSecAssert2(buf != NULL, -1);
912 xmlSecAssert2(bufSize != NULL, -1);
913 xmlSecAssert2(keyInfoCtx != NULL, -1);
915 if((xmlSecKeyDataTypeSymmetric & keyInfoCtx->keyReq.keyType) == 0) {
916 /* we can have only symmetric key */
920 value = xmlSecKeyGetValue(key);
921 xmlSecAssert2(xmlSecKeyDataIsValid(value), -1);
923 buffer = xmlSecKeyDataBinaryValueGetBuffer(key->value);
924 xmlSecAssert2(buffer != NULL, -1);
926 (*bufSize) = xmlSecBufferGetSize(buffer);
927 (*buf) = (xmlSecByte*) xmlMalloc((*bufSize));
929 xmlSecError(XMLSEC_ERRORS_HERE,
930 xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
932 XMLSEC_ERRORS_R_MALLOC_FAILED,
933 XMLSEC_ERRORS_NO_MESSAGE);
936 memcpy((*buf), xmlSecBufferGetData(buffer), (*bufSize));
941 * xmlSecKeyDataBinaryValueDebugDump:
942 * @data: the pointer to binary key data.
943 * @output: the pointer to output FILE.
945 * Prints binary key data debug information to @output.
948 xmlSecKeyDataBinaryValueDebugDump(xmlSecKeyDataPtr data, FILE* output) {
949 xmlSecBufferPtr buffer;
951 xmlSecAssert(xmlSecKeyDataIsValid(data));
952 xmlSecAssert(xmlSecKeyDataCheckSize(data, xmlSecKeyDataBinarySize));
953 xmlSecAssert(data->id->dataNodeName != NULL);
954 xmlSecAssert(output != NULL);
956 buffer = xmlSecKeyDataBinaryValueGetBuffer(data);
957 xmlSecAssert(buffer != NULL);
959 /* print only size, everything else is sensitive */
960 fprintf(output, "=== %s: size=%d\n", data->id->dataNodeName,
961 xmlSecKeyDataGetSize(data));
965 * xmlSecKeyDataBinaryValueDebugXmlDump:
966 * @data: the pointer to binary key data.
967 * @output: the pointer to output FILE.
969 * Prints binary key data debug information to @output in XML format.
972 xmlSecKeyDataBinaryValueDebugXmlDump(xmlSecKeyDataPtr data, FILE* output) {
973 xmlSecBufferPtr buffer;
975 xmlSecAssert(xmlSecKeyDataIsValid(data));
976 xmlSecAssert(xmlSecKeyDataCheckSize(data, xmlSecKeyDataBinarySize));
977 xmlSecAssert(data->id->dataNodeName != NULL);
978 xmlSecAssert(output != NULL);
980 buffer = xmlSecKeyDataBinaryValueGetBuffer(data);
981 xmlSecAssert(buffer != NULL);
983 /* print only size, everything else is sensitive */
984 fprintf(output, "<%s size=\"%d\" />\n", data->id->dataNodeName,
985 xmlSecKeyDataGetSize(data));
989 * xmlSecKeyDataBinaryValueGetSize:
990 * @data: the pointer to binary key data.
992 * Gets the binary key data size.
994 * Returns: binary key data size in bits.
997 xmlSecKeyDataBinaryValueGetSize(xmlSecKeyDataPtr data) {
998 xmlSecBufferPtr buffer;
1000 xmlSecAssert2(xmlSecKeyDataIsValid(data), 0);
1001 xmlSecAssert2(xmlSecKeyDataCheckSize(data, xmlSecKeyDataBinarySize), 0);
1003 buffer = xmlSecKeyDataBinaryValueGetBuffer(data);
1004 xmlSecAssert2(buffer != NULL, 0);
1006 /* return size in bits */
1007 return(8 * xmlSecBufferGetSize(buffer));
1011 * xmlSecKeyDataBinaryValueGetBuffer:
1012 * @data: the pointer to binary key data.
1014 * Gets the binary key data buffer.
1016 * Returns: pointer to binary key data buffer.
1019 xmlSecKeyDataBinaryValueGetBuffer(xmlSecKeyDataPtr data) {
1020 xmlSecAssert2(xmlSecKeyDataIsValid(data), NULL);
1021 xmlSecAssert2(xmlSecKeyDataCheckSize(data, xmlSecKeyDataBinarySize), NULL);
1023 /* key (xmlSecBuffer) is located after xmlSecKeyData structure */
1024 return((xmlSecBufferPtr)(((xmlSecByte*)data) + sizeof(xmlSecKeyData)));
1028 * xmlSecKeyDataBinaryValueSetBuffer:
1029 * @data: the pointer to binary key data.
1030 * @buf: the pointer to binary buffer.
1031 * @bufSize: the binary buffer size.
1033 * Sets the value of @data to @buf.
1035 * Returns: 0 on success or a negative value otherwise.
1038 xmlSecKeyDataBinaryValueSetBuffer(xmlSecKeyDataPtr data,
1039 const xmlSecByte* buf, xmlSecSize bufSize) {
1040 xmlSecBufferPtr buffer;
1042 xmlSecAssert2(xmlSecKeyDataIsValid(data), -1);
1043 xmlSecAssert2(xmlSecKeyDataCheckSize(data, xmlSecKeyDataBinarySize), -1);
1044 xmlSecAssert2(buf != NULL, -1);
1045 xmlSecAssert2(bufSize > 0, -1);
1047 buffer = xmlSecKeyDataBinaryValueGetBuffer(data);
1048 xmlSecAssert2(buffer != NULL, -1);
1050 return(xmlSecBufferSetData(buffer, buf, bufSize));
1053 /***********************************************************************
1057 **********************************************************************/
1058 static xmlSecPtrListKlass xmlSecKeyDataListKlass = {
1059 BAD_CAST "key-data-list",
1060 (xmlSecPtrDuplicateItemMethod)xmlSecKeyDataDuplicate, /* xmlSecPtrDuplicateItemMethod duplicateItem; */
1061 (xmlSecPtrDestroyItemMethod)xmlSecKeyDataDestroy, /* xmlSecPtrDestroyItemMethod destroyItem; */
1062 (xmlSecPtrDebugDumpItemMethod)xmlSecKeyDataDebugDump, /* xmlSecPtrDebugDumpItemMethod debugDumpItem; */
1063 (xmlSecPtrDebugDumpItemMethod)xmlSecKeyDataDebugXmlDump, /* xmlSecPtrDebugDumpItemMethod debugXmlDumpItem; */
1067 * xmlSecKeyDataListGetKlass:
1069 * The key data list klass.
1071 * Returns: pointer to the key data list klass.
1074 xmlSecKeyDataListGetKlass(void) {
1075 return(&xmlSecKeyDataListKlass);
1079 /***********************************************************************
1081 * Keys Data Ids list
1083 **********************************************************************/
1084 static xmlSecPtrListKlass xmlSecKeyDataIdListKlass = {
1085 BAD_CAST "key-data-ids-list",
1086 NULL, /* xmlSecPtrDuplicateItemMethod duplicateItem; */
1087 NULL, /* xmlSecPtrDestroyItemMethod destroyItem; */
1088 NULL, /* xmlSecPtrDebugDumpItemMethod debugDumpItem; */
1089 NULL, /* xmlSecPtrDebugDumpItemMethod debugXmlDumpItem; */
1093 * xmlSecKeyDataIdListGetKlass:
1095 * The key data id list klass.
1097 * Returns: pointer to the key data id list klass.
1100 xmlSecKeyDataIdListGetKlass(void) {
1101 return(&xmlSecKeyDataIdListKlass);
1105 * xmlSecKeyDataIdListFind:
1106 * @list: the pointer to key data ids list.
1107 * @dataId: the key data klass.
1109 * Lookups @dataId in @list.
1111 * Returns: 1 if @dataId is found in the @list, 0 if not and a negative
1112 * value if an error occurs.
1115 xmlSecKeyDataIdListFind(xmlSecPtrListPtr list, xmlSecKeyDataId dataId) {
1118 xmlSecAssert2(xmlSecPtrListCheckId(list, xmlSecKeyDataIdListId), 0);
1119 xmlSecAssert2(dataId != NULL, 0);
1121 size = xmlSecPtrListGetSize(list);
1122 for(i = 0; i < size; ++i) {
1123 if((xmlSecKeyDataId)xmlSecPtrListGetItem(list, i) == dataId) {
1131 * xmlSecKeyDataIdListFindByNode:
1132 * @list: the pointer to key data ids list.
1133 * @nodeName: the desired key data klass XML node name.
1134 * @nodeNs: the desired key data klass XML node namespace.
1135 * @usage: the desired key data usage.
1137 * Lookups data klass in the list with given @nodeName, @nodeNs and
1138 * @usage in the @list.
1140 * Returns: key data klass is found and NULL otherwise.
1143 xmlSecKeyDataIdListFindByNode(xmlSecPtrListPtr list, const xmlChar* nodeName,
1144 const xmlChar* nodeNs, xmlSecKeyDataUsage usage) {
1145 xmlSecKeyDataId dataId;
1148 xmlSecAssert2(xmlSecPtrListCheckId(list, xmlSecKeyDataIdListId), xmlSecKeyDataIdUnknown);
1149 xmlSecAssert2(nodeName != NULL, xmlSecKeyDataIdUnknown);
1151 size = xmlSecPtrListGetSize(list);
1152 for(i = 0; i < size; ++i) {
1153 dataId = (xmlSecKeyDataId)xmlSecPtrListGetItem(list, i);
1154 xmlSecAssert2(dataId != xmlSecKeyDataIdUnknown, xmlSecKeyDataIdUnknown);
1156 if(((usage & dataId->usage) != 0) &&
1157 xmlStrEqual(nodeName, dataId->dataNodeName) &&
1158 xmlStrEqual(nodeNs, dataId->dataNodeNs)) {
1163 return(xmlSecKeyDataIdUnknown);
1167 * xmlSecKeyDataIdListFindByHref:
1168 * @list: the pointer to key data ids list.
1169 * @href: the desired key data klass href.
1170 * @usage: the desired key data usage.
1172 * Lookups data klass in the list with given @href and @usage in @list.
1174 * Returns: key data klass is found and NULL otherwise.
1177 xmlSecKeyDataIdListFindByHref(xmlSecPtrListPtr list, const xmlChar* href,
1178 xmlSecKeyDataUsage usage) {
1179 xmlSecKeyDataId dataId;
1182 xmlSecAssert2(xmlSecPtrListCheckId(list, xmlSecKeyDataIdListId), xmlSecKeyDataIdUnknown);
1183 xmlSecAssert2(href != NULL, xmlSecKeyDataIdUnknown);
1185 size = xmlSecPtrListGetSize(list);
1186 for(i = 0; i < size; ++i) {
1187 dataId = (xmlSecKeyDataId)xmlSecPtrListGetItem(list, i);
1188 xmlSecAssert2(dataId != xmlSecKeyDataIdUnknown, xmlSecKeyDataIdUnknown);
1190 if(((usage & dataId->usage) != 0) && (dataId->href != NULL) &&
1191 xmlStrEqual(href, dataId->href)) {
1196 return(xmlSecKeyDataIdUnknown);
1200 * xmlSecKeyDataIdListFindByName:
1201 * @list: the pointer to key data ids list.
1202 * @name: the desired key data klass name.
1203 * @usage: the desired key data usage.
1205 * Lookups data klass in the list with given @name and @usage in @list.
1207 * Returns: key data klass is found and NULL otherwise.
1210 xmlSecKeyDataIdListFindByName(xmlSecPtrListPtr list, const xmlChar* name,
1211 xmlSecKeyDataUsage usage) {
1212 xmlSecKeyDataId dataId;
1215 xmlSecAssert2(xmlSecPtrListCheckId(list, xmlSecKeyDataIdListId), xmlSecKeyDataIdUnknown);
1216 xmlSecAssert2(name != NULL, xmlSecKeyDataIdUnknown);
1218 size = xmlSecPtrListGetSize(list);
1219 for(i = 0; i < size; ++i) {
1220 dataId = (xmlSecKeyDataId)xmlSecPtrListGetItem(list, i);
1221 xmlSecAssert2(dataId != xmlSecKeyDataIdUnknown, xmlSecKeyDataIdUnknown);
1223 if(((usage & dataId->usage) != 0) && (dataId->name != NULL) &&
1224 xmlStrEqual(name, BAD_CAST dataId->name)) {
1229 return(xmlSecKeyDataIdUnknown);
1233 * xmlSecKeyDataIdListDebugDump:
1234 * @list: the pointer to key data ids list.
1235 * @output: the pointer to output FILE.
1237 * Prints binary key data debug information to @output.
1240 xmlSecKeyDataIdListDebugDump(xmlSecPtrListPtr list, FILE* output) {
1241 xmlSecKeyDataId dataId;
1244 xmlSecAssert(xmlSecPtrListCheckId(list, xmlSecKeyDataIdListId));
1245 xmlSecAssert(output != NULL);
1247 size = xmlSecPtrListGetSize(list);
1248 for(i = 0; i < size; ++i) {
1249 dataId = (xmlSecKeyDataId)xmlSecPtrListGetItem(list, i);
1250 xmlSecAssert(dataId != NULL);
1251 xmlSecAssert(dataId->name != NULL);
1254 fprintf(output, ",\"%s\"", dataId->name);
1256 fprintf(output, "\"%s\"", dataId->name);
1259 fprintf(output, "\n");
1263 * xmlSecKeyDataIdListDebugXmlDump:
1264 * @list: the pointer to key data ids list.
1265 * @output: the pointer to output FILE.
1267 * Prints binary key data debug information to @output in XML format.
1270 xmlSecKeyDataIdListDebugXmlDump(xmlSecPtrListPtr list, FILE* output) {
1271 xmlSecKeyDataId dataId;
1274 xmlSecAssert(xmlSecPtrListCheckId(list, xmlSecKeyDataIdListId));
1275 xmlSecAssert(output != NULL);
1277 fprintf(output, "<KeyDataIdsList>\n");
1278 size = xmlSecPtrListGetSize(list);
1279 for(i = 0; i < size; ++i) {
1280 dataId = (xmlSecKeyDataId)xmlSecPtrListGetItem(list, i);
1281 xmlSecAssert(dataId != NULL);
1282 xmlSecAssert(dataId->name != NULL);
1284 fprintf(output, "<DataId name=\"");
1285 xmlSecPrintXmlString(output, dataId->name);
1286 fprintf(output, "\"/>");
1288 fprintf(output, "</KeyDataIdsList>\n");
1291 /**************************************************************************
1293 * xmlSecKeyDataStore functions
1295 *************************************************************************/
1297 * xmlSecKeyDataStoreCreate:
1298 * @id: the store id.
1300 * Creates new key data store of the specified klass @id. Caller is responsible
1301 * for freeng returned object with #xmlSecKeyDataStoreDestroy function.
1303 * Returns: the pointer to newly allocated key data store structure
1304 * or NULL if an error occurs.
1306 xmlSecKeyDataStorePtr
1307 xmlSecKeyDataStoreCreate(xmlSecKeyDataStoreId id) {
1308 xmlSecKeyDataStorePtr store;
1311 xmlSecAssert2(id != NULL, NULL);
1312 xmlSecAssert2(id->objSize > 0, NULL);
1314 /* Allocate a new xmlSecKeyDataStore and fill the fields. */
1315 store = (xmlSecKeyDataStorePtr)xmlMalloc(id->objSize);
1317 xmlSecError(XMLSEC_ERRORS_HERE,
1318 xmlSecErrorsSafeString(xmlSecKeyDataStoreKlassGetName(id)),
1320 XMLSEC_ERRORS_R_MALLOC_FAILED,
1321 "size=%d", id->objSize);
1324 memset(store, 0, id->objSize);
1327 if(id->initialize != NULL) {
1328 ret = (id->initialize)(store);
1330 xmlSecError(XMLSEC_ERRORS_HERE,
1331 xmlSecErrorsSafeString(xmlSecKeyDataStoreKlassGetName(id)),
1333 XMLSEC_ERRORS_R_XMLSEC_FAILED,
1334 XMLSEC_ERRORS_NO_MESSAGE);
1335 xmlSecKeyDataStoreDestroy(store);
1344 * xmlSecKeyDataStoreDestroy:
1345 * @store: the pointer to the key data store..
1347 * Destroys the key data store created with #xmlSecKeyDataStoreCreate
1351 xmlSecKeyDataStoreDestroy(xmlSecKeyDataStorePtr store) {
1352 xmlSecAssert(xmlSecKeyDataStoreIsValid(store));
1353 xmlSecAssert(store->id->objSize > 0);
1355 if(store->id->finalize != NULL) {
1356 (store->id->finalize)(store);
1358 memset(store, 0, store->id->objSize);
1362 /***********************************************************************
1364 * Keys Data Store list
1366 **********************************************************************/
1367 static xmlSecPtrListKlass xmlSecKeyDataStorePtrListKlass = {
1368 BAD_CAST "keys-data-store-list",
1369 NULL, /* xmlSecPtrDuplicateItemMethod duplicateItem; */
1370 (xmlSecPtrDestroyItemMethod)xmlSecKeyDataStoreDestroy, /* xmlSecPtrDestroyItemMethod destroyItem; */
1371 NULL, /* xmlSecPtrDebugDumpItemMethod debugDumpItem; */
1372 NULL, /* xmlSecPtrDebugDumpItemMethod debugXmlDumpItem; */
1376 * xmlSecKeyDataStorePtrListGetKlass:
1378 * Key data stores list.
1380 * Returns: key data stores list klass.
1383 xmlSecKeyDataStorePtrListGetKlass(void) {
1384 return(&xmlSecKeyDataStorePtrListKlass);