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 <dsig:KeyInfo/> node @p keyInfoNode and extracts the key. |
1247 | | * @param keyInfoNode the pointer to <dsig:KeyInfo/> node. |
1248 | | * @param keyInfoCtx the pointer to <dsig:KeyInfo/> 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 <dsig:KeyInfo/> 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 | } |