Coverage Report

Created: 2026-09-01 06:15

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/xmlsec/src/keys.c
Line
Count
Source
1
/**
2
 * XML Security Library (http://www.aleksey.com/xmlsec).
3
 *
4
 * This is free software; see the Copyright file in the source distribution for precise wording.
5
 *
6
 * Copyright (C) 2002-2026 Aleksey Sanin <aleksey@aleksey.com>. All Rights Reserved.
7
 */
8
/**
9
 * @addtogroup xmlsec_core_keys
10
 * @brief Crypto key object functions.
11
 */
12
#include "globals.h"
13
14
#include <stdlib.h>
15
#include <string.h>
16
17
#include <libxml/tree.h>
18
19
#include <xmlsec/xmlsec.h>
20
#include <xmlsec/xmltree.h>
21
#include <xmlsec/list.h>
22
#include <xmlsec/keys.h>
23
#include <xmlsec/keysmngr.h>
24
#include <xmlsec/transforms.h>
25
#include <xmlsec/keyinfo.h>
26
#include <xmlsec/errors.h>
27
28
#include "cast_helpers.h"
29
30
/******************************************************************************
31
 *
32
 * xmlSecKeyUseWith
33
 *
34
  *****************************************************************************/
35
/**
36
 * @brief Initializes @p keyUseWith object.
37
 * @param keyUseWith the pointer to information about key application/user.
38
 *
39
 * @return 0 on success or a negative value if an error occurs.
40
 */
41
int
42
0
xmlSecKeyUseWithInitialize(xmlSecKeyUseWithPtr keyUseWith) {
43
0
    xmlSecAssert2(keyUseWith != NULL, -1);
44
45
0
    memset(keyUseWith, 0, sizeof(xmlSecKeyUseWith));
46
0
    return(0);
47
0
}
48
49
/**
50
 * @brief Finalizes @p keyUseWith object.
51
 * @param keyUseWith the pointer to information about key application/user.
52
 */
53
void
54
0
xmlSecKeyUseWithFinalize(xmlSecKeyUseWithPtr keyUseWith) {
55
0
    xmlSecAssert(keyUseWith != NULL);
56
57
0
    xmlSecKeyUseWithReset(keyUseWith);
58
0
    memset(keyUseWith, 0, sizeof(xmlSecKeyUseWith));
59
0
}
60
61
/**
62
 * @brief Resets a keyUseWith to its initial state.
63
 * @details Resets the @p keyUseWith to its state after initialization.
64
 * @param keyUseWith the pointer to information about key application/user.
65
 */
66
void
67
0
xmlSecKeyUseWithReset(xmlSecKeyUseWithPtr keyUseWith) {
68
0
    xmlSecAssert(keyUseWith != NULL);
69
70
0
    xmlSecKeyUseWithSet(keyUseWith, NULL, NULL);
71
0
}
72
73
/**
74
 * @brief Copies information from @p src to @p dst.
75
 * @param dst the pointer to destination object.
76
 * @param src the pointer to source object.
77
 *
78
 * @return 0 on success or a negative value if an error occurs.
79
 */
80
int
81
0
xmlSecKeyUseWithCopy(xmlSecKeyUseWithPtr dst, xmlSecKeyUseWithPtr src) {
82
0
    xmlSecAssert2(dst != NULL, -1);
83
0
    xmlSecAssert2(src != NULL, -1);
84
85
0
    return(xmlSecKeyUseWithSet(dst, src->application, src->identifier));
86
0
}
87
88
/**
89
 * @brief Creates a new xmlSecKeyUseWith object.
90
 * @details Creates new xmlSecKeyUseWith object. The caller is responsible for destroying
91
 * returned object with #xmlSecKeyUseWithDestroy function.
92
 * @param application the application value.
93
 * @param identifier the identifier value.
94
 *
95
 * @return pointer to newly created object or NULL if an error occurs.
96
 */
97
xmlSecKeyUseWithPtr
98
0
xmlSecKeyUseWithCreate(const xmlChar* application, const xmlChar* identifier) {
99
0
    xmlSecKeyUseWithPtr keyUseWith;
100
0
    int ret;
101
102
    /* Allocate a new xmlSecKeyUseWith and fill the fields. */
103
0
    keyUseWith = (xmlSecKeyUseWithPtr)xmlMalloc(sizeof(xmlSecKeyUseWith));
104
0
    if(keyUseWith == NULL) {
105
0
        xmlSecMallocError(sizeof(xmlSecKeyUseWith), NULL);
106
0
        return(NULL);
107
0
    }
108
0
    memset(keyUseWith, 0, sizeof(xmlSecKeyUseWith));
109
110
0
    ret = xmlSecKeyUseWithInitialize(keyUseWith);
111
0
    if(ret < 0) {
112
0
        xmlSecInternalError("xmlSecKeyUseWithInitialize", NULL);
113
0
        xmlSecKeyUseWithDestroy(keyUseWith);
114
0
        return(NULL);
115
0
    }
116
117
0
    ret = xmlSecKeyUseWithSet(keyUseWith, application, identifier);
118
0
    if(ret < 0) {
119
0
        xmlSecInternalError("xmlSecKeyUseWithSet", NULL);
120
0
        xmlSecKeyUseWithDestroy(keyUseWith);
121
0
        return(NULL);
122
0
    }
123
124
0
    return(keyUseWith);
125
0
}
126
127
/**
128
 * @brief Duplicates a keyUseWith object.
129
 * @details Duplicates @p keyUseWith object. The caller is responsible for destroying
130
 * returned object with #xmlSecKeyUseWithDestroy function.
131
 * @param keyUseWith the pointer to information about key application/user.
132
 *
133
 * @return pointer to newly created object or NULL if an error occurs.
134
 */
135
xmlSecKeyUseWithPtr
136
0
xmlSecKeyUseWithDuplicate(xmlSecKeyUseWithPtr keyUseWith) {
137
0
    int ret;
138
139
0
    xmlSecKeyUseWithPtr newKeyUseWith;
140
141
0
    xmlSecAssert2(keyUseWith != NULL, NULL);
142
143
0
    newKeyUseWith = xmlSecKeyUseWithCreate(NULL, NULL);
144
0
    if(newKeyUseWith == NULL) {
145
0
        xmlSecInternalError("xmlSecKeyUseWithCreate", NULL);
146
0
        return(NULL);
147
0
    }
148
149
0
    ret = xmlSecKeyUseWithCopy(newKeyUseWith, keyUseWith);
150
0
    if(ret < 0) {
151
0
        xmlSecInternalError("xmlSecKeyUseWithCopy", NULL);
152
0
        xmlSecKeyUseWithDestroy(newKeyUseWith);
153
0
        return(NULL);
154
0
    }
155
156
0
    return(newKeyUseWith);
157
0
}
158
159
/**
160
 * @brief Destroys a keyUseWith object.
161
 * @details Destroys @p keyUseWith created with #xmlSecKeyUseWithCreate or #xmlSecKeyUseWithDuplicate
162
 * functions.
163
 * @param keyUseWith the pointer to information about key application/user.
164
 */
165
void
166
0
xmlSecKeyUseWithDestroy(xmlSecKeyUseWithPtr keyUseWith) {
167
0
    xmlSecAssert(keyUseWith != NULL);
168
169
0
    xmlSecKeyUseWithFinalize(keyUseWith);
170
0
    xmlFree(keyUseWith);
171
0
}
172
173
/**
174
 * @brief Sets application and identifier in a keyUseWith object.
175
 * @details Sets @p application and @p identifier in the @p keyUseWith.
176
 * @param keyUseWith the pointer to information about key application/user.
177
 * @param application the new application value.
178
 * @param identifier the new identifier value.
179
 *
180
 * @return 0 on success or a negative value if an error occurs.
181
 */
182
int
183
0
xmlSecKeyUseWithSet(xmlSecKeyUseWithPtr keyUseWith, const xmlChar* application, const xmlChar* identifier) {
184
0
    xmlSecAssert2(keyUseWith != NULL, -1);
185
186
0
    if(keyUseWith->application != NULL) {
187
0
        xmlFree(keyUseWith->application);
188
0
        keyUseWith->application = NULL;
189
0
    }
190
0
    if(keyUseWith->identifier != NULL) {
191
0
        xmlFree(keyUseWith->identifier);
192
0
        keyUseWith->identifier = NULL;
193
0
    }
194
195
0
    if(application != NULL) {
196
0
        keyUseWith->application = xmlStrdup(application);
197
0
        if(keyUseWith->application == NULL) {
198
0
            xmlSecStrdupError(application, NULL);
199
0
            return(-1);
200
0
        }
201
0
    }
202
0
    if(identifier != NULL) {
203
0
        keyUseWith->identifier = xmlStrdup(identifier);
204
0
        if(keyUseWith->identifier == NULL) {
205
0
            xmlSecStrdupError(identifier, NULL);
206
0
            return(-1);
207
0
        }
208
0
    }
209
210
0
    return(0);
211
0
}
212
213
/**
214
 * @brief Prints keyUseWith debug information to a file.
215
 * @details Prints xmlSecKeyUseWith debug information to a file @p output.
216
 * @param keyUseWith the pointer to information about key application/user.
217
 * @param output the pointer to output FILE.
218
 */
219
void
220
0
xmlSecKeyUseWithDebugDump(xmlSecKeyUseWithPtr keyUseWith, FILE* output) {
221
0
    xmlSecAssert(keyUseWith != NULL);
222
0
    xmlSecAssert(output != NULL);
223
224
0
    fprintf(output, "=== KeyUseWith: application=\"%s\",identifier=\"%s\"\n",
225
0
                (keyUseWith->application) ? keyUseWith->application : BAD_CAST "",
226
0
                (keyUseWith->identifier) ? keyUseWith->identifier : BAD_CAST "");
227
0
}
228
229
/**
230
 * @brief Prints keyUseWith debug information in XML format.
231
 * @details Prints xmlSecKeyUseWith debug information to a file @p output in XML format.
232
 * @param keyUseWith the pointer to information about key application/user.
233
 * @param output the pointer to output FILE.
234
 */
235
void
236
0
xmlSecKeyUseWithDebugXmlDump(xmlSecKeyUseWithPtr keyUseWith, FILE* output) {
237
0
    xmlSecAssert(keyUseWith != NULL);
238
0
    xmlSecAssert(output != NULL);
239
240
0
    fprintf(output, "<KeyUseWith>\n");
241
242
0
    fprintf(output, "<Application>");
243
0
    xmlSecPrintXmlString(output, keyUseWith->application);
244
0
    fprintf(output, "</Application>");
245
246
0
    fprintf(output, "<Identifier>");
247
0
    xmlSecPrintXmlString(output, keyUseWith->identifier);
248
0
    fprintf(output, "</Identifier>");
249
250
0
    fprintf(output, "</KeyUseWith>\n");
251
0
}
252
253
/******************************************************************************
254
 *
255
 * KeyUseWith list
256
 *
257
  *****************************************************************************/
258
static xmlSecPtrListKlass xmlSecKeyUseWithPtrListKlass = {
259
    BAD_CAST "key-use-with-list",
260
    (xmlSecPtrDuplicateItemMethod)xmlSecKeyUseWithDuplicate,    /* xmlSecPtrDuplicateItemMethod duplicateItem; */
261
    (xmlSecPtrDestroyItemMethod)xmlSecKeyUseWithDestroy,        /* xmlSecPtrDestroyItemMethod destroyItem; */
262
    (xmlSecPtrDebugDumpItemMethod)xmlSecKeyUseWithDebugDump,    /* xmlSecPtrDebugDumpItemMethod debugDumpItem; */
263
    (xmlSecPtrDebugDumpItemMethod)xmlSecKeyUseWithDebugXmlDump, /* xmlSecPtrDebugDumpItemMethod debugXmlDumpItem; */
264
};
265
266
/**
267
 * @brief The key data list klass.
268
 *
269
 * @return pointer to the key data list klass.
270
 */
271
xmlSecPtrListId
272
0
xmlSecKeyUseWithPtrListGetKlass(void) {
273
0
    return(&xmlSecKeyUseWithPtrListKlass);
274
0
}
275
276
/******************************************************************************
277
 *
278
 * xmlSecKeyReq - what key are we looking for?
279
 *
280
  *****************************************************************************/
281
/**
282
 * @brief Initializes a key requirements object.
283
 * @details Initialize key requirements object. Caller is responsible for
284
 * cleaning it with #xmlSecKeyReqFinalize function.
285
 * @param keyReq the pointer to key requirements object.
286
 *
287
 * @return 0 on success or a negative value if an error occurs.
288
 */
289
int
290
0
xmlSecKeyReqInitialize(xmlSecKeyReqPtr keyReq) {
291
0
    int ret;
292
293
0
    xmlSecAssert2(keyReq != NULL, -1);
294
295
0
    memset(keyReq, 0, sizeof(xmlSecKeyReq));
296
297
0
    keyReq->keyUsage    = xmlSecKeyUsageAny;    /* by default you can do whatever you want with the key */
298
0
    ret = xmlSecPtrListInitialize(&keyReq->keyUseWithList, xmlSecKeyUseWithPtrListId);
299
0
    if(ret < 0) {
300
0
        xmlSecInternalError("xmlSecPtrListInitialize", NULL);
301
0
        return(-1);
302
0
    }
303
304
305
0
    return(0);
306
0
}
307
308
/**
309
 * @brief Cleans up a key requirements object.
310
 * @details Cleans the key requirements object initialized with #xmlSecKeyReqInitialize
311
 * function.
312
 * @param keyReq the pointer to key requirements object.
313
 */
314
void
315
0
xmlSecKeyReqFinalize(xmlSecKeyReqPtr keyReq) {
316
0
    xmlSecAssert(keyReq != NULL);
317
318
0
    xmlSecPtrListFinalize(&keyReq->keyUseWithList);
319
0
    memset(keyReq, 0, sizeof(xmlSecKeyReq));
320
0
}
321
322
/**
323
 * @brief Resets key requirements for a new key search.
324
 * @details Resets key requirements object for new key search.
325
 * @param keyReq the pointer to key requirements object.
326
 */
327
void
328
0
xmlSecKeyReqReset(xmlSecKeyReqPtr keyReq) {
329
0
    xmlSecAssert(keyReq != NULL);
330
331
0
    xmlSecPtrListEmpty(&keyReq->keyUseWithList);
332
0
    keyReq->keyId       = NULL;
333
0
    keyReq->keyType     = 0;
334
0
    keyReq->keyUsage    = xmlSecKeyUsageAny;
335
0
    keyReq->keyBitsSize = 0;
336
0
}
337
338
/**
339
 * @brief Copies key requirements between objects.
340
 * @details Copies key requirements from @p src object to @p dst object.
341
 * @param dst the pointer to destination object.
342
 * @param src the pointer to source object.
343
 *
344
 * @return 0 on success and a negative value if an error occurs.
345
 */
346
int
347
0
xmlSecKeyReqCopy(xmlSecKeyReqPtr dst, xmlSecKeyReqPtr src) {
348
0
    int ret;
349
350
0
    xmlSecAssert2(dst != NULL, -1);
351
0
    xmlSecAssert2(src != NULL, -1);
352
353
0
    if(dst == src) {
354
0
        return(0);
355
0
    }
356
357
0
    xmlSecPtrListEmpty(&dst->keyUseWithList);
358
359
0
    dst->keyId          = src->keyId;
360
0
    dst->keyType        = src->keyType;
361
0
    dst->keyUsage       = src->keyUsage;
362
0
    dst->keyBitsSize    = src->keyBitsSize;
363
364
0
    ret = xmlSecPtrListCopy(&dst->keyUseWithList, &src->keyUseWithList);
365
0
    if(ret < 0) {
366
0
        xmlSecInternalError("xmlSecPtrListCopy", NULL);
367
0
        return(-1);
368
0
    }
369
370
0
    return(0);
371
0
}
372
373
/**
374
 * @brief Checks whether a key matches the given requirements.
375
 * @details Checks whether @p key matches key requirements @p keyReq.
376
 * @param keyReq the pointer to key requirements object.
377
 * @param key the pointer to key.
378
 *
379
 * @return 1 if key matches requirements, 0 if not and a negative value
380
 * if an error occurs.
381
 */
382
int
383
0
xmlSecKeyReqMatchKey(xmlSecKeyReqPtr keyReq, xmlSecKeyPtr key) {
384
0
    xmlSecAssert2(keyReq != NULL, -1);
385
0
    xmlSecAssert2(xmlSecKeyIsValid(key), -1);
386
387
0
    if((keyReq->keyType != xmlSecKeyDataTypeUnknown) && ((xmlSecKeyGetType(key) & keyReq->keyType) == 0)) {
388
0
        return(0);
389
0
    }
390
0
    if((keyReq->keyUsage != xmlSecKeyDataUsageUnknown) && ((keyReq->keyUsage & key->usage) == 0)) {
391
0
        return(0);
392
0
    }
393
394
0
    return(xmlSecKeyReqMatchKeyValue(keyReq, xmlSecKeyGetValue(key)));
395
0
}
396
397
/**
398
 * @brief Checks whether a key value matches the given requirements.
399
 * @details Checks whether @p keyValue matches key requirements @p keyReq.
400
 * @param keyReq the pointer to key requirements.
401
 * @param value the pointer to key value.
402
 *
403
 * @return 1 if key value matches requirements, 0 if not and a negative value
404
 * if an error occurs.
405
 */
406
int
407
0
xmlSecKeyReqMatchKeyValue(xmlSecKeyReqPtr keyReq, xmlSecKeyDataPtr value) {
408
0
    xmlSecAssert2(keyReq != NULL, -1);
409
0
    xmlSecAssert2(value != NULL, -1);
410
411
0
    if((keyReq->keyId != xmlSecKeyDataIdUnknown) &&
412
0
       (!xmlSecKeyDataCheckId(value, keyReq->keyId))) {
413
0
        return(0);
414
0
    }
415
0
    if((keyReq->keyBitsSize > 0) &&
416
0
       (xmlSecKeyDataGetSize(value) > 0) &&
417
0
       (xmlSecKeyDataGetSize(value) < keyReq->keyBitsSize)) {
418
0
        return(0);
419
0
    }
420
0
    return(1);
421
0
}
422
423
/**
424
 * @brief Prints key requirements debug information.
425
 * @details Prints debug information about @p keyReq into @p output.
426
 * @param keyReq the pointer to key requirements object.
427
 * @param output the pointer to output FILE.
428
 */
429
void
430
0
xmlSecKeyReqDebugDump(xmlSecKeyReqPtr keyReq, FILE* output) {
431
0
    xmlSecAssert(keyReq != NULL);
432
0
    xmlSecAssert(output != NULL);
433
434
0
    fprintf(output, "=== KeyReq:\n");
435
0
    fprintf(output, "==== keyId: %s\n",
436
0
            (xmlSecKeyDataKlassGetName(keyReq->keyId)) ?
437
0
                xmlSecKeyDataKlassGetName(keyReq->keyId) :
438
0
                BAD_CAST "NULL");
439
0
    fprintf(output, "==== keyType: 0x%08x\n", keyReq->keyType);
440
0
    fprintf(output, "==== keyUsage: 0x%08x\n", keyReq->keyUsage);
441
0
    fprintf(output, "==== keyBitsSize: " XMLSEC_SIZE_FMT "\n", keyReq->keyBitsSize);
442
0
    xmlSecPtrListDebugDump(&(keyReq->keyUseWithList), output);
443
0
}
444
445
/**
446
 * @brief Prints key requirements debug information in XML format.
447
 * @details Prints debug information about @p keyReq into @p output in XML format.
448
 * @param keyReq the pointer to key requirements object.
449
 * @param output the pointer to output FILE.
450
 */
451
void
452
0
xmlSecKeyReqDebugXmlDump(xmlSecKeyReqPtr keyReq, FILE* output) {
453
0
    xmlSecAssert(keyReq != NULL);
454
0
    xmlSecAssert(output != NULL);
455
456
0
    fprintf(output, "<KeyReq>\n");
457
458
0
    fprintf(output, "<KeyId>");
459
0
    xmlSecPrintXmlString(output, xmlSecKeyDataKlassGetName(keyReq->keyId));
460
0
    fprintf(output, "</KeyId>\n");
461
462
0
    fprintf(output, "<KeyType>0x%08x</KeyType>\n", keyReq->keyType);
463
0
    fprintf(output, "<KeyUsage>0x%08x</KeyUsage>\n", keyReq->keyUsage);
464
0
    fprintf(output, "<KeyBitsSize>" XMLSEC_SIZE_FMT "</KeyBitsSize>\n", keyReq->keyBitsSize);
465
0
    xmlSecPtrListDebugXmlDump(&(keyReq->keyUseWithList), output);
466
0
    fprintf(output, "</KeyReq>\n");
467
0
}
468
469
470
/******************************************************************************
471
 *
472
 * xmlSecKey
473
 *
474
  *****************************************************************************/
475
/**
476
 * @brief Allocates and initializes a new key object.
477
 * @details Allocates and initializes new key. Caller is responsible for
478
 * freeing returned object with #xmlSecKeyDestroy function.
479
 *
480
 * @return the pointer to newly allocated xmlSecKey structure
481
 * or NULL if an error occurs.
482
 */
483
xmlSecKeyPtr
484
0
xmlSecKeyCreate(void)  {
485
0
    xmlSecKeyPtr key;
486
487
    /* Allocate a new xmlSecKey and fill the fields. */
488
0
    key = (xmlSecKeyPtr)xmlMalloc(sizeof(xmlSecKey));
489
0
    if(key == NULL) {
490
0
        xmlSecMallocError(sizeof(xmlSecKey), NULL);
491
0
        return(NULL);
492
0
    }
493
0
    memset(key, 0, sizeof(xmlSecKey));
494
0
    key->usage = xmlSecKeyUsageAny;
495
0
    return(key);
496
0
}
497
498
/**
499
 * @brief Clears the @p key data.
500
 * @param key the pointer to key.
501
 */
502
void
503
0
xmlSecKeyEmpty(xmlSecKeyPtr key) {
504
0
    xmlSecAssert(key != NULL);
505
506
0
    if(key->value != NULL) {
507
0
        xmlSecKeyDataDestroy(key->value);
508
0
    }
509
0
    if(key->name != NULL) {
510
0
        xmlFree(key->name);
511
0
    }
512
0
    if(key->dataList != NULL) {
513
0
        xmlSecPtrListDestroy(key->dataList);
514
0
    }
515
516
0
    memset(key, 0, sizeof(xmlSecKey));
517
0
}
518
519
/**
520
 * @brief Destroys a key object.
521
 * @details Destroys the key created using #xmlSecKeyCreate function.
522
 * @param key the pointer to key.
523
 */
524
void
525
0
xmlSecKeyDestroy(xmlSecKeyPtr key) {
526
0
    xmlSecAssert(key != NULL);
527
528
0
    xmlSecKeyEmpty(key);
529
0
    xmlFree(key);
530
0
}
531
532
/**
533
 * @brief Copies key data from @p keySrc to @p keyDst.
534
 * @param keyDst the destination key.
535
 * @param keySrc the source key.
536
 *
537
 * @return 0 on success or a negative value if an error occurs.
538
 */
539
int
540
0
xmlSecKeyCopy(xmlSecKeyPtr keyDst, xmlSecKeyPtr keySrc) {
541
0
    xmlSecAssert2(keyDst != NULL, -1);
542
0
    xmlSecAssert2(keySrc != NULL, -1);
543
544
0
    if(keyDst == keySrc) {
545
0
        return(0);
546
0
    }
547
548
    /* empty destination */
549
0
    xmlSecKeyEmpty(keyDst);
550
551
    /* copy everything */
552
0
    if(keySrc->name != NULL) {
553
0
        keyDst->name = xmlStrdup(keySrc->name);
554
0
        if(keyDst->name == NULL) {
555
0
            xmlSecStrdupError(keySrc->name, NULL);
556
0
            return(-1);
557
0
        }
558
0
    }
559
560
0
    if(keySrc->value != NULL) {
561
0
        keyDst->value = xmlSecKeyDataDuplicate(keySrc->value);
562
0
        if(keyDst->value == NULL) {
563
0
            xmlSecInternalError("xmlSecKeyDataDuplicate", NULL);
564
0
            return(-1);
565
0
        }
566
0
    }
567
568
0
    if(keySrc->dataList != NULL) {
569
0
        keyDst->dataList = xmlSecPtrListDuplicate(keySrc->dataList);
570
0
        if(keyDst->dataList == NULL) {
571
0
            xmlSecInternalError("xmlSecPtrListDuplicate", NULL);
572
0
            return(-1);
573
0
        }
574
0
    }
575
576
0
    keyDst->usage          = keySrc->usage;
577
0
    keyDst->notValidBefore = keySrc->notValidBefore;
578
0
    keyDst->notValidAfter  = keySrc->notValidAfter;
579
0
    return(0);
580
0
}
581
582
#define XMLSEC_SWAP(val1, val2, TYPE)   \
583
0
    {                                   \
584
0
        TYPE _tmp = (val1);             \
585
0
        (val1) = (val2);                \
586
0
        (val2) = _tmp;                  \
587
0
    }
588
589
/**
590
 * @brief Swaps key data for @p key1 and @p key2
591
 * @param key1 the first key.
592
 * @param key2 the second key.
593
 *
594
 * @return 0 on success or a negative value if an error occurs.
595
 */
596
int
597
0
xmlSecKeySwap(xmlSecKeyPtr key1, xmlSecKeyPtr key2) {
598
0
    xmlSecAssert2(key1 != NULL, -1);
599
0
    xmlSecAssert2(key2 != NULL, -1);
600
601
0
    XMLSEC_SWAP(key1->name,             key2->name,             xmlChar*);
602
0
    XMLSEC_SWAP(key1->value,            key2->value,            xmlSecKeyDataPtr);
603
0
    XMLSEC_SWAP(key1->dataList,         key2->dataList,         xmlSecPtrListPtr);
604
0
    XMLSEC_SWAP(key1->usage,            key2->usage,            xmlSecKeyUsage);
605
0
    XMLSEC_SWAP(key1->notValidBefore,   key2->notValidBefore,   time_t);
606
0
    XMLSEC_SWAP(key1->notValidAfter,    key2->notValidAfter,    time_t);
607
608
0
    return(0);
609
0
}
610
611
/**
612
 * @brief Creates a duplicate of the given @p key.
613
 * @param key the pointer to the xmlSecKey structure.
614
 *
615
 * @return the pointer to newly allocated xmlSecKey structure
616
 * or NULL if an error occurs.
617
 */
618
xmlSecKeyPtr
619
0
xmlSecKeyDuplicate(xmlSecKeyPtr key) {
620
0
    xmlSecKeyPtr newKey;
621
0
    int ret;
622
623
0
    xmlSecAssert2(key != NULL, NULL);
624
625
0
    newKey = xmlSecKeyCreate();
626
0
    if(newKey == NULL) {
627
0
        xmlSecInternalError("xmlSecKeyCreate", NULL);
628
0
        return(NULL);
629
0
    }
630
631
0
    ret = xmlSecKeyCopy(newKey, key);
632
0
    if(ret < 0) {
633
0
        xmlSecInternalError("xmlSecKeyCopy", NULL);
634
0
        xmlSecKeyDestroy(newKey);
635
0
        return(NULL);
636
0
    }
637
638
0
    return(newKey);
639
0
}
640
641
/**
642
 * @brief Checks whether a key matches the given criteria.
643
 * @details Checks whether the @p key matches the given criteria.
644
 * @param key the pointer to key.
645
 * @param name the pointer to key name (may be NULL).
646
 * @param keyReq the pointer to key requirements.
647
 *
648
 * @return 1 if the key satisfies the given criteria or 0 otherwise.
649
 */
650
int
651
0
xmlSecKeyMatch(xmlSecKeyPtr key, const xmlChar *name, xmlSecKeyReqPtr keyReq) {
652
0
    xmlSecAssert2(xmlSecKeyIsValid(key), -1);
653
0
    xmlSecAssert2(keyReq != NULL, -1);
654
655
0
    if((name != NULL) && (!xmlStrEqual(xmlSecKeyGetName(key), name))) {
656
0
        return(0);
657
0
    }
658
0
    return(xmlSecKeyReqMatchKey(keyReq, key));
659
0
}
660
661
/**
662
 * @brief Gets @p key type.
663
 * @param key the pointer to key.
664
 *
665
 * @return key type.
666
 */
667
xmlSecKeyDataType
668
0
xmlSecKeyGetType(xmlSecKeyPtr key) {
669
0
    xmlSecKeyDataPtr data;
670
671
0
    xmlSecAssert2(key != NULL, xmlSecKeyDataTypeUnknown);
672
673
0
    data = xmlSecKeyGetValue(key);
674
0
    if(data == NULL) {
675
0
        return(xmlSecKeyDataTypeUnknown);
676
0
    }
677
0
    return(xmlSecKeyDataGetType(data));
678
0
}
679
680
/**
681
 * @brief Gets the key name.
682
 * @details Gets key name (see also #xmlSecKeySetName function).
683
 * @param key the pointer to key.
684
 *
685
 * @return key name.
686
 */
687
const xmlChar*
688
0
xmlSecKeyGetName(xmlSecKeyPtr key) {
689
0
    xmlSecAssert2(key != NULL, NULL);
690
691
0
    return(key->name);
692
0
}
693
694
/**
695
 * @brief Sets the key name.
696
 * @details Sets key name (see also #xmlSecKeyGetName function).
697
 * @param key the pointer to key.
698
 * @param name the new key name.
699
 *
700
 * @return 0 on success or a negative value if an error occurs.
701
 */
702
int
703
0
xmlSecKeySetName(xmlSecKeyPtr key, const xmlChar* name) {
704
0
    xmlSecAssert2(key != NULL, -1);
705
706
0
    if(key->name != NULL) {
707
0
        xmlFree(key->name);
708
0
        key->name = NULL;
709
0
    }
710
711
0
    if(name != NULL) {
712
0
        key->name = xmlStrdup(name);
713
0
        if(key->name == NULL) {
714
0
            xmlSecStrdupError(name, NULL);
715
0
            return(-1);
716
0
        }
717
0
    }
718
719
0
    return(0);
720
0
}
721
722
/**
723
 * @brief Sets the key name with a specific length.
724
 * @details Sets key name (see also #xmlSecKeyGetName function).
725
 * @param key the pointer to key.
726
 * @param name the new key name.
727
 * @param nameSize the size of @p name.
728
 *
729
 * @return 0 on success or a negative value if an error occurs.
730
 */
731
int
732
0
xmlSecKeySetNameEx(xmlSecKeyPtr key, const xmlChar* name, xmlSecSize nameSize) {
733
0
    xmlSecAssert2(key != NULL, -1);
734
735
0
    if(key->name != NULL) {
736
0
        xmlFree(key->name);
737
0
        key->name = NULL;
738
0
    }
739
740
0
    if((name != NULL) && (nameSize > 0)) {
741
0
        int nameLen;
742
743
0
        XMLSEC_SAFE_CAST_SIZE_TO_INT(nameSize, nameLen, return(-1), NULL);
744
0
        key->name = xmlStrndup(name, nameLen);
745
0
        if(key->name == NULL) {
746
0
            xmlSecStrdupError(name, NULL);
747
0
            return(-1);
748
0
        }
749
0
    }
750
751
0
    return(0);
752
0
}
753
754
/**
755
 * @brief Gets the key value (crypto material).
756
 * @details Gets key value (see also #xmlSecKeySetValue function).
757
 * @param key the pointer to key.
758
 *
759
 * @return key value (crypto material).
760
 */
761
xmlSecKeyDataPtr
762
0
xmlSecKeyGetValue(xmlSecKeyPtr key) {
763
0
    xmlSecAssert2(key != NULL, NULL);
764
765
0
    return(key->value);
766
0
}
767
768
/**
769
 * @brief Sets the key value (crypto material).
770
 * @details Sets key value (see also #xmlSecKeyGetValue function).
771
 * @param key the pointer to key.
772
 * @param value the new value.
773
 *
774
 * @return 0 on success or a negative value if an error occurs.
775
 */
776
int
777
0
xmlSecKeySetValue(xmlSecKeyPtr key, xmlSecKeyDataPtr value) {
778
0
    xmlSecAssert2(key != NULL, -1);
779
780
0
    if(key->value != NULL) {
781
0
        xmlSecKeyDataDestroy(key->value);
782
0
        key->value = NULL;
783
0
    }
784
0
    key->value = value;
785
786
0
    return(0);
787
0
}
788
789
/**
790
 * @brief Gets the key size in bits.
791
 * @details Gets key size (in bits). Also see #xmlSecKeyDataGetSize function.
792
 * @param key the pointer to key.
793
 *
794
 * @return key size (in bits).
795
 */
796
xmlSecSize
797
0
xmlSecKeyGetSize(xmlSecKeyPtr key) {
798
0
    xmlSecAssert2(key != NULL, 0);
799
800
0
    if(key->value == NULL) {
801
0
        return(0);
802
0
    }
803
0
    return(xmlSecKeyDataGetSize(key->value));
804
0
}
805
806
/**
807
 * @brief Gets key's data.
808
 * @param key the pointer to key.
809
 * @param dataId the requested data klass.
810
 *
811
 * @return additional data associated with the @p key (see also
812
 * #xmlSecKeyAdoptData function).
813
 */
814
xmlSecKeyDataPtr
815
0
xmlSecKeyGetData(xmlSecKeyPtr key, xmlSecKeyDataId dataId) {
816
817
0
    xmlSecAssert2(key != NULL, NULL);
818
0
    xmlSecAssert2(dataId != xmlSecKeyDataIdUnknown, NULL);
819
820
    /* special cases */
821
0
    if(dataId == xmlSecKeyDataValueId) {
822
0
        return(key->value);
823
0
    } else if(key->dataList != NULL) {
824
0
        xmlSecKeyDataPtr tmp;
825
0
        xmlSecSize pos, size;
826
827
0
        size = xmlSecPtrListGetSize(key->dataList);
828
0
        for(pos = 0; pos < size; ++pos) {
829
0
            tmp = (xmlSecKeyDataPtr)xmlSecPtrListGetItem(key->dataList, pos);
830
0
            if((tmp != NULL) && (tmp->id == dataId)) {
831
0
                return(tmp);
832
0
            }
833
0
        }
834
0
    }
835
0
    return(NULL);
836
0
}
837
838
/**
839
 * @brief Ensures key data of the requested klass exists.
840
 * @details If necessary, creates key data of @p dataId klass and adds to @p key.
841
 * @param key the pointer to key.
842
 * @param dataId the requested data klass.
843
 *
844
 * @return pointer to key data or NULL if an error occurs.
845
 */
846
xmlSecKeyDataPtr
847
0
xmlSecKeyEnsureData(xmlSecKeyPtr key, xmlSecKeyDataId dataId) {
848
0
    xmlSecKeyDataPtr data;
849
0
    int ret;
850
851
0
    xmlSecAssert2(key != NULL, NULL);
852
0
    xmlSecAssert2(dataId != xmlSecKeyDataIdUnknown, NULL);
853
854
0
    data = xmlSecKeyGetData(key, dataId);
855
0
    if(data != NULL) {
856
0
        return(data);
857
0
    }
858
859
0
    data = xmlSecKeyDataCreate(dataId);
860
0
    if(data == NULL) {
861
0
        xmlSecInternalError2("xmlSecKeyDataCreate", NULL,
862
0
                             "dataId=%s",
863
0
                             xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(dataId)));
864
0
        return(NULL);
865
0
    }
866
867
0
    ret = xmlSecKeyAdoptData(key, data);
868
0
    if(ret < 0) {
869
0
        xmlSecInternalError2("xmlSecKeyAdoptData", NULL,
870
0
                             "dataId=%s",
871
0
                             xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(dataId)));
872
0
        xmlSecKeyDataDestroy(data);
873
0
        return(NULL);
874
0
    }
875
876
0
    return(data);
877
0
}
878
879
/**
880
 * @brief Adds key data to a key object (takes ownership).
881
 * @details Adds @p data to the @p key. The @p data object will be destroyed
882
 * by @p key.
883
 * @param key the pointer to key.
884
 * @param data the pointer to key data.
885
 *
886
 * @return 0 on success or a negative value otherwise.
887
 */
888
int
889
0
xmlSecKeyAdoptData(xmlSecKeyPtr key, xmlSecKeyDataPtr data) {
890
0
    xmlSecKeyDataPtr tmp;
891
0
    xmlSecSize pos, size;
892
893
0
    xmlSecAssert2(key != NULL, -1);
894
0
    xmlSecAssert2(xmlSecKeyDataIsValid(data), -1);
895
896
    /* special cases */
897
0
    if(data->id == xmlSecKeyDataValueId) {
898
0
        if(key->value != NULL) {
899
0
            xmlSecKeyDataDestroy(key->value);
900
0
        }
901
0
        key->value = data;
902
0
        return(0);
903
0
    }
904
905
0
    if(key->dataList == NULL) {
906
0
        key->dataList = xmlSecPtrListCreate(xmlSecKeyDataListId);
907
0
        if(key->dataList == NULL) {
908
0
            xmlSecInternalError("xmlSecPtrListCreate", NULL);
909
0
            return(-1);
910
0
        }
911
0
    }
912
913
914
0
    size = xmlSecPtrListGetSize(key->dataList);
915
0
    for(pos = 0; pos < size; ++pos) {
916
0
        tmp = (xmlSecKeyDataPtr)xmlSecPtrListGetItem(key->dataList, pos);
917
0
        if((tmp != NULL) && (tmp->id == data->id)) {
918
0
            return(xmlSecPtrListSet(key->dataList, data, pos));
919
0
        }
920
0
    }
921
922
0
    return(xmlSecPtrListAdd(key->dataList, data));
923
0
}
924
925
/**
926
 * @brief Prints key information for debugging.
927
 * @details Prints the information about the @p key to the @p output.
928
 * @param key the pointer to key.
929
 * @param output the pointer to output FILE.
930
 */
931
void
932
0
xmlSecKeyDebugDump(xmlSecKeyPtr key, FILE *output) {
933
0
    xmlSecAssert(xmlSecKeyIsValid(key));
934
0
    xmlSecAssert(output != NULL);
935
936
0
    fprintf(output, "== KEY\n");
937
0
    fprintf(output, "=== method: %s\n",
938
0
            (key->value->id->dataNodeName != NULL) ?
939
0
            (char*)(key->value->id->dataNodeName) : "NULL");
940
941
0
    fprintf(output, "=== key type: ");
942
0
    if((xmlSecKeyGetType(key) & xmlSecKeyDataTypeSymmetric) != 0) {
943
0
        fprintf(output, "Symmetric\n");
944
0
    } else if((xmlSecKeyGetType(key) & xmlSecKeyDataTypePrivate) != 0) {
945
0
        fprintf(output, "Private\n");
946
0
    } else if((xmlSecKeyGetType(key) & xmlSecKeyDataTypePublic) != 0) {
947
0
        fprintf(output, "Public\n");
948
0
    } else {
949
0
        fprintf(output, "Unknown\n");
950
0
    }
951
952
0
    if(key->name != NULL) {
953
0
        fprintf(output, "=== key name: %s\n", key->name);
954
0
    }
955
0
    fprintf(output, "=== key usage: %u\n", key->usage);
956
0
    if(key->notValidBefore < key->notValidAfter) {
957
0
        fprintf(output, "=== key not valid before: %.lf\n",
958
0
            difftime(key->notValidBefore, (time_t)0));
959
0
        fprintf(output, "=== key not valid after: %.lf\n",
960
0
            difftime(key->notValidAfter, (time_t)0));
961
0
    }
962
0
    if(key->value != NULL) {
963
0
        xmlSecKeyDataDebugDump(key->value, output);
964
0
    }
965
0
    if(key->dataList != NULL) {
966
0
        xmlSecPtrListDebugDump(key->dataList, output);
967
0
    }
968
0
}
969
970
/**
971
 * @brief Prints key information in XML format for debugging.
972
 * @details Prints the information about the @p key to the @p output in XML format.
973
 * @param key the pointer to key.
974
 * @param output the pointer to output FILE.
975
 */
976
void
977
0
xmlSecKeyDebugXmlDump(xmlSecKeyPtr key, FILE *output) {
978
0
    xmlSecAssert(xmlSecKeyIsValid(key));
979
0
    xmlSecAssert(output != NULL);
980
981
0
    fprintf(output, "<KeyInfo>\n");
982
983
0
    fprintf(output, "<KeyMethod>");
984
0
    xmlSecPrintXmlString(output, key->value->id->dataNodeName);
985
0
    fprintf(output, "</KeyMethod>\n");
986
987
0
    fprintf(output, "<KeyType>");
988
0
    if((xmlSecKeyGetType(key) & xmlSecKeyDataTypeSymmetric) != 0) {
989
0
        fprintf(output, "Symmetric\n");
990
0
    } else if((xmlSecKeyGetType(key) & xmlSecKeyDataTypePrivate) != 0) {
991
0
        fprintf(output, "Private\n");
992
0
    } else if((xmlSecKeyGetType(key) & xmlSecKeyDataTypePublic) != 0) {
993
0
        fprintf(output, "Public\n");
994
0
    } else {
995
0
        fprintf(output, "Unknown\n");
996
0
    }
997
0
    fprintf(output, "</KeyType>\n");
998
999
0
    fprintf(output, "<KeyName>");
1000
0
    xmlSecPrintXmlString(output, key->name);
1001
0
    fprintf(output, "</KeyName>\n");
1002
1003
0
    if(key->notValidBefore < key->notValidAfter) {
1004
0
        fprintf(output, "<KeyValidity notValidBefore=\"%.lf\" notValidAfter=\"%.lf\"/>\n",
1005
0
            difftime(key->notValidBefore, (time_t)0),
1006
0
            difftime(key->notValidAfter, (time_t)0));
1007
0
    }
1008
1009
0
    if(key->value != NULL) {
1010
0
        xmlSecKeyDataDebugXmlDump(key->value, output);
1011
0
    }
1012
0
    if(key->dataList != NULL) {
1013
0
        xmlSecPtrListDebugXmlDump(key->dataList, output);
1014
0
    }
1015
1016
0
    fprintf(output, "</KeyInfo>\n");
1017
0
}
1018
1019
/**
1020
 * @brief Generates a new key of the requested klass and type.
1021
 * @details Generates new key of requested klass @p dataId and @p type.
1022
 * @param dataId the requested key klass (rsa, dsa, aes, ...).
1023
 * @param sizeBits the new key size (in bits!).
1024
 * @param type the new key type (session, permanent, ...).
1025
 *
1026
 * @return pointer to newly created key or NULL if an error occurs.
1027
 */
1028
xmlSecKeyPtr
1029
0
xmlSecKeyGenerate(xmlSecKeyDataId dataId, xmlSecSize sizeBits, xmlSecKeyDataType type) {
1030
0
    xmlSecKeyPtr key;
1031
0
    xmlSecKeyDataPtr data;
1032
0
    int ret;
1033
1034
0
    xmlSecAssert2(dataId != xmlSecKeyDataIdUnknown, NULL);
1035
1036
0
    data = xmlSecKeyDataCreate(dataId);
1037
0
    if(data == NULL) {
1038
0
        xmlSecInternalError("xmlSecKeyDataCreate",
1039
0
                            xmlSecKeyDataKlassGetName(dataId));
1040
0
        return(NULL);
1041
0
    }
1042
1043
0
    ret = xmlSecKeyDataGenerate(data, sizeBits, type);
1044
0
    if(ret < 0) {
1045
0
        xmlSecInternalError3("xmlSecKeyDataGenerate",
1046
0
                             xmlSecKeyDataKlassGetName(dataId),
1047
0
                             "size=" XMLSEC_SIZE_FMT ";type=%u", sizeBits, type);
1048
0
        xmlSecKeyDataDestroy(data);
1049
0
        return(NULL);
1050
0
    }
1051
1052
0
    key = xmlSecKeyCreate();
1053
0
    if(key == NULL) {
1054
0
        xmlSecInternalError("xmlSecKeyCreate",
1055
0
                            xmlSecKeyDataKlassGetName(dataId));
1056
0
        xmlSecKeyDataDestroy(data);
1057
0
        return(NULL);
1058
0
    }
1059
1060
0
    ret = xmlSecKeySetValue(key, data);
1061
0
    if(ret < 0) {
1062
0
        xmlSecInternalError("xmlSecKeySetValue",
1063
0
                            xmlSecKeyDataKlassGetName(dataId));
1064
0
        xmlSecKeyDataDestroy(data);
1065
0
        xmlSecKeyDestroy(key);
1066
0
        return(NULL);
1067
0
    }
1068
1069
0
    return(key);
1070
0
}
1071
1072
/**
1073
 * @brief Generates a new key by klass name and type.
1074
 * @details Generates new key of requested @p klass and @p type.
1075
 * @param name the requested key klass name (rsa, dsa, aes, ...).
1076
 * @param sizeBits the new key size (in bits!).
1077
 * @param type the new key type (session, permanent, ...).
1078
 *
1079
 * @return pointer to newly created key or NULL if an error occurs.
1080
 */
1081
xmlSecKeyPtr
1082
0
xmlSecKeyGenerateByName(const xmlChar* name, xmlSecSize sizeBits, xmlSecKeyDataType type) {
1083
0
    xmlSecKeyDataId dataId;
1084
1085
0
    xmlSecAssert2(name != NULL, NULL);
1086
1087
0
    dataId = xmlSecKeyDataIdListFindByName(xmlSecKeyDataIdsGet(), name, xmlSecKeyDataUsageAny);
1088
0
    if(dataId == xmlSecKeyDataIdUnknown) {
1089
0
        xmlSecOtherError(XMLSEC_ERRORS_R_KEY_DATA_NOT_FOUND, name, NULL);
1090
0
        return(NULL);
1091
0
    }
1092
1093
0
    return(xmlSecKeyGenerate(dataId, sizeBits, type));
1094
0
}
1095
1096
/**
1097
 * @brief Reads a key value from a buffer.
1098
 * @details Reads the key value of klass @p dataId from a buffer.
1099
 * @param dataId the key value data klass.
1100
 * @param buffer the buffer that contains the binary data.
1101
 *
1102
 * @return pointer to newly created key or NULL if an error occurs.
1103
 */
1104
xmlSecKeyPtr
1105
0
xmlSecKeyReadBuffer(xmlSecKeyDataId dataId, xmlSecBuffer* buffer) {
1106
0
    xmlSecKeyInfoCtx keyInfoCtx;
1107
0
    xmlSecKeyPtr key;
1108
0
    int ret;
1109
1110
0
    xmlSecAssert2(dataId != xmlSecKeyDataIdUnknown, NULL);
1111
0
    xmlSecAssert2(buffer != NULL, NULL);
1112
1113
    /* mark buffer as sensitive */
1114
0
    buffer->flags |= XMLSEC_BUFFER_FLAG_SECURE;
1115
1116
    /* create key data */
1117
0
    key = xmlSecKeyCreate();
1118
0
    if(key == NULL) {
1119
0
        xmlSecInternalError("xmlSecKeyCreate",
1120
0
                            xmlSecKeyDataKlassGetName(dataId));
1121
0
        return(NULL);
1122
0
    }
1123
1124
0
    ret = xmlSecKeyInfoCtxInitialize(&keyInfoCtx, NULL);
1125
0
    if(ret < 0) {
1126
0
        xmlSecInternalError("xmlSecKeyInfoCtxInitialize",
1127
0
                            xmlSecKeyDataKlassGetName(dataId));
1128
0
        xmlSecKeyDestroy(key);
1129
0
        return(NULL);
1130
0
    }
1131
1132
0
    keyInfoCtx.keyReq.keyType = xmlSecKeyDataTypeAny;
1133
0
    ret = xmlSecKeyDataBinRead(dataId, key,
1134
0
                        xmlSecBufferGetData(buffer),
1135
0
                        xmlSecBufferGetSize(buffer),
1136
0
                        &keyInfoCtx);
1137
0
    if(ret < 0) {
1138
0
        xmlSecInternalError("xmlSecKeyDataBinRead",
1139
0
                            xmlSecKeyDataKlassGetName(dataId));
1140
0
        xmlSecKeyInfoCtxFinalize(&keyInfoCtx);
1141
0
        xmlSecKeyDestroy(key);
1142
0
        return(NULL);
1143
0
    }
1144
0
    xmlSecKeyInfoCtxFinalize(&keyInfoCtx);
1145
1146
0
    return(key);
1147
0
}
1148
1149
/**
1150
 * @brief Reads a key value from a binary file.
1151
 * @details Reads the key value of klass @p dataId from a binary file @p filename.
1152
 * @param dataId the key value data klass.
1153
 * @param filename the key binary filename.
1154
 *
1155
 * @return pointer to newly created key or NULL if an error occurs.
1156
 */
1157
xmlSecKeyPtr
1158
0
xmlSecKeyReadBinaryFile(xmlSecKeyDataId dataId, const char* filename) {
1159
0
    xmlSecKeyPtr key;
1160
0
    xmlSecBuffer buffer;
1161
0
    int ret;
1162
1163
0
    xmlSecAssert2(dataId != xmlSecKeyDataIdUnknown, NULL);
1164
0
    xmlSecAssert2(filename != NULL, NULL);
1165
1166
    /* read file to buffer */
1167
0
    ret = xmlSecBufferInitialize(&buffer, 0);
1168
0
    if(ret < 0) {
1169
0
        xmlSecInternalError("xmlSecBufferInitialize",
1170
0
                            xmlSecKeyDataKlassGetName(dataId));
1171
0
        return(NULL);
1172
0
    }
1173
1174
0
    ret = xmlSecBufferReadFile(&buffer, filename);
1175
0
    if(ret < 0) {
1176
0
        xmlSecInternalError2("xmlSecBufferReadFile",
1177
0
                             xmlSecKeyDataKlassGetName(dataId),
1178
0
                             "filename=%s",
1179
0
                             xmlSecErrorsSafeString(filename));
1180
0
        xmlSecBufferFinalize(&buffer);
1181
0
        return(NULL);
1182
0
    }
1183
1184
0
    key = xmlSecKeyReadBuffer(dataId, &buffer);
1185
0
    if(key == NULL) {
1186
0
        xmlSecInternalError2("xmlSecKeyReadBuffer",
1187
0
                             xmlSecKeyDataKlassGetName(dataId),
1188
0
                             "filename=%s",
1189
0
                             xmlSecErrorsSafeString(filename));
1190
0
        xmlSecBufferFinalize(&buffer);
1191
0
        return(NULL);
1192
0
    }
1193
1194
0
    xmlSecBufferFinalize(&buffer);
1195
0
    return (key);
1196
0
}
1197
1198
/**
1199
 * @brief Reads a key value from a memory block.
1200
 * @details Reads the key value of klass @p dataId from a memory block @p data.
1201
 * @param dataId the key value data klass.
1202
 * @param data the memory containing the key
1203
 * @param dataSize the size of the memory block
1204
 *
1205
 * @return pointer to newly created key or NULL if an error occurs.
1206
 */
1207
xmlSecKeyPtr
1208
0
xmlSecKeyReadMemory(xmlSecKeyDataId dataId, const xmlSecByte* data, xmlSecSize dataSize) {
1209
0
    xmlSecBuffer buffer;
1210
0
    xmlSecKeyPtr key;
1211
0
    int ret;
1212
1213
0
    xmlSecAssert2(dataId != xmlSecKeyDataIdUnknown, NULL);
1214
0
    xmlSecAssert2(data != NULL, NULL);
1215
0
    xmlSecAssert2(dataSize > 0, NULL);
1216
1217
    /* read file to buffer */
1218
0
    ret = xmlSecBufferInitialize(&buffer, 0);
1219
0
    if(ret < 0) {
1220
0
        xmlSecInternalError("xmlSecBufferInitialize",
1221
0
                            xmlSecKeyDataKlassGetName(dataId));
1222
0
        return(NULL);
1223
0
    }
1224
1225
0
    if (xmlSecBufferAppend(&buffer, data, dataSize) < 0) {
1226
0
        xmlSecInternalError("xmlSecBufferAppend",
1227
0
                            xmlSecKeyDataKlassGetName(dataId));
1228
0
        xmlSecBufferFinalize(&buffer);
1229
0
        return(NULL);
1230
0
    }
1231
1232
0
    key = xmlSecKeyReadBuffer(dataId, &buffer);
1233
0
    if(key == NULL) {
1234
0
        xmlSecInternalError("xmlSecKeyReadBuffer",
1235
0
                            xmlSecKeyDataKlassGetName(dataId));
1236
0
        xmlSecBufferFinalize(&buffer);
1237
0
        return(NULL);
1238
0
    }
1239
1240
0
    xmlSecBufferFinalize(&buffer);
1241
0
    return (key);
1242
0
}
1243
1244
/**
1245
 * @brief Reads a KeyInfo node and extracts the key.
1246
 * @details Reads the &lt;dsig:KeyInfo/&gt; node @p keyInfoNode and extracts the key.
1247
 * @param keyInfoNode the pointer to &lt;dsig:KeyInfo/&gt; node.
1248
 * @param keyInfoCtx the pointer to &lt;dsig:KeyInfo/&gt; node processing context.
1249
 *
1250
 * @return the pointer to key or NULL if the key is not found or
1251
 * an error occurs.
1252
 */
1253
xmlSecKeyPtr
1254
0
xmlSecKeysMngrGetKey(xmlNodePtr keyInfoNode, xmlSecKeyInfoCtxPtr keyInfoCtx) {
1255
0
    xmlSecKeyPtr key;
1256
0
    int ret;
1257
1258
0
    xmlSecAssert2(keyInfoCtx != NULL, NULL);
1259
1260
    /* first try to read data from &lt;dsig:KeyInfo/&gt; node */
1261
0
    key = xmlSecKeyCreate();
1262
0
    if(key == NULL) {
1263
0
        xmlSecInternalError("xmlSecKeyCreate", NULL);
1264
0
        return(NULL);
1265
0
    }
1266
1267
0
    if(keyInfoNode != NULL) {
1268
0
        ret = xmlSecKeyInfoNodeRead(keyInfoNode, key, keyInfoCtx);
1269
0
        if(ret < 0) {
1270
0
            xmlSecInternalError2("xmlSecKeyInfoNodeRead",
1271
0
                                 NULL,
1272
0
                                 "node=%s",
1273
0
                                 xmlSecErrorsSafeString(xmlSecNodeGetName(keyInfoNode)));
1274
0
            xmlSecKeyDestroy(key);
1275
0
            return(NULL);
1276
0
        }
1277
1278
0
        if((xmlSecKeyGetValue(key) != NULL) &&
1279
0
           (xmlSecKeyMatch(key, NULL, &(keyInfoCtx->keyReq)) != 0)) {
1280
0
            return(key);
1281
0
        }
1282
0
    }
1283
0
    xmlSecKeyDestroy(key);
1284
1285
    /* if we have keys manager, try to find any key that matches the required key (if lax key search is allowed) */
1286
0
    if(((keyInfoCtx->flags & XMLSEC_KEYINFO_FLAGS_LAX_KEY_SEARCH) != 0) &&  (keyInfoCtx->keysMngr != NULL)) {
1287
0
        key = xmlSecKeysMngrFindKey(keyInfoCtx->keysMngr, NULL, keyInfoCtx);
1288
0
        if(key == NULL) {
1289
0
            xmlSecInternalError("xmlSecKeysMngrFindKey", NULL);
1290
0
            return(NULL);
1291
0
        }
1292
0
        if(xmlSecKeyGetValue(key) != NULL) {
1293
0
            return(key);
1294
0
        }
1295
0
        xmlSecKeyDestroy(key);
1296
0
    }
1297
1298
0
    xmlSecOtherError(XMLSEC_ERRORS_R_KEY_NOT_FOUND, NULL, NULL);
1299
0
    return(NULL);
1300
0
}
1301
1302
/******************************************************************************
1303
 *
1304
 * Keys list
1305
 *
1306
  *****************************************************************************/
1307
static xmlSecPtrListKlass xmlSecKeyPtrListKlass = {
1308
    BAD_CAST "keys-list",
1309
    (xmlSecPtrDuplicateItemMethod)xmlSecKeyDuplicate,   /* xmlSecPtrDuplicateItemMethod duplicateItem; */
1310
    (xmlSecPtrDestroyItemMethod)xmlSecKeyDestroy,       /* xmlSecPtrDestroyItemMethod destroyItem; */
1311
    (xmlSecPtrDebugDumpItemMethod)xmlSecKeyDebugDump,   /* xmlSecPtrDebugDumpItemMethod debugDumpItem; */
1312
    (xmlSecPtrDebugDumpItemMethod)xmlSecKeyDebugXmlDump,/* xmlSecPtrDebugDumpItemMethod debugXmlDumpItem; */
1313
};
1314
1315
/**
1316
 * @brief The keys list klass.
1317
 *
1318
 * @return keys list id.
1319
 */
1320
xmlSecPtrListId
1321
0
xmlSecKeyPtrListGetKlass(void) {
1322
0
    return(&xmlSecKeyPtrListKlass);
1323
0
}