Coverage Report

Created: 2025-08-26 07:06

/src/xmlsec/src/keysdata.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * XML Security Library (http://www.aleksey.com/xmlsec).
3
 *
4
 *
5
 * This is free software; see Copyright file in the source
6
 * distribution for preciese wording.
7
 *
8
 * Copyright (C) 2002-2024 Aleksey Sanin <aleksey@aleksey.com>. All Rights Reserved.
9
 */
10
/**
11
 * SECTION:keysdata
12
 * @Short_description: Crypto key data object functions.
13
 * @Stability: Stable
14
 *
15
 */
16
17
#include "globals.h"
18
19
#include <stdlib.h>
20
#include <string.h>
21
#include <ctype.h>
22
23
#include <libxml/tree.h>
24
25
#include <xmlsec/xmlsec.h>
26
#include <xmlsec/xmltree.h>
27
#include <xmlsec/keys.h>
28
#include <xmlsec/keyinfo.h>
29
#include <xmlsec/transforms.h>
30
#include <xmlsec/base64.h>
31
#include <xmlsec/keyinfo.h>
32
#include <xmlsec/errors.h>
33
#include <xmlsec/private.h>
34
#include <xmlsec/x509.h>
35
36
#include "cast_helpers.h"
37
#include "keysdata_helpers.h"
38
39
/**************************************************************************
40
 *
41
 * Global xmlSecKeyDataIds list functions
42
 *
43
 *************************************************************************/
44
static xmlSecPtrList xmlSecAllKeyDataIds;
45
static xmlSecPtrList xmlSecEnabledKeyDataIds;
46
static int xmlSecImportPersistKey = 0;
47
48
/**
49
 * xmlSecKeyDataIdsGet:
50
 *
51
 * Gets global registered key data klasses list.
52
 *
53
 * Returns: the pointer to list of all registered key data klasses.
54
 */
55
xmlSecPtrListPtr
56
0
xmlSecKeyDataIdsGet(void) {
57
0
    return(&xmlSecAllKeyDataIds);
58
0
}
59
60
/**
61
 * xmlSecKeyDataIdsGetEnabled:
62
 *
63
 * Gets global enabled key data klasses list.
64
 *
65
 * Returns: the pointer to list of all enabled key data klasses.
66
 */
67
xmlSecPtrListPtr
68
0
xmlSecKeyDataIdsGetEnabled(void) {
69
0
    return(&xmlSecEnabledKeyDataIds);
70
0
}
71
72
73
/**
74
 * xmlSecKeyDataIdsInit:
75
 *
76
 * Initializes the key data klasses. This function is called from the
77
 * #xmlSecInit function and the application should not call it directly.
78
 *
79
 * Returns: 0 on success or a negative value if an error occurs.
80
 */
81
int
82
0
xmlSecKeyDataIdsInit(void) {
83
0
    int ret;
84
85
0
    ret = xmlSecPtrListInitialize(&xmlSecAllKeyDataIds, xmlSecKeyDataIdListId);
86
0
    if(ret < 0) {
87
0
        xmlSecInternalError("xmlSecPtrListInitialize(xmlSecKeyDataIdListId)", NULL);
88
0
        return(-1);
89
0
    }
90
91
0
    ret = xmlSecPtrListInitialize(&xmlSecEnabledKeyDataIds, xmlSecKeyDataIdListId);
92
0
    if(ret < 0) {
93
0
        xmlSecInternalError("xmlSecPtrListInitialize(xmlSecKeyDataIdListId)", NULL);
94
0
        return(-1);
95
0
    }
96
97
0
    ret = xmlSecKeyDataIdsRegisterDefault();
98
0
    if(ret < 0) {
99
0
        xmlSecInternalError("xmlSecKeyDataIdsRegisterDefault", NULL);
100
0
        return(-1);
101
0
    }
102
103
0
    return(0);
104
0
}
105
106
/**
107
 * xmlSecKeyDataIdsShutdown:
108
 *
109
 * Shuts down the keys data klasses. This function is called from the
110
 * #xmlSecShutdown function and the application should not call it directly.
111
 */
112
void
113
0
xmlSecKeyDataIdsShutdown(void) {
114
0
    xmlSecPtrListFinalize(&xmlSecAllKeyDataIds);
115
0
    xmlSecPtrListFinalize(&xmlSecEnabledKeyDataIds);
116
0
}
117
118
/**
119
 * xmlSecKeyDataIdsRegister:
120
 * @id:                 the key data klass.
121
 *
122
 * Registers @id in the global list of key data klasses and enable this key data.
123
 *
124
 * Returns: 0 on success or a negative value if an error occurs.
125
 */
126
int
127
0
xmlSecKeyDataIdsRegister(xmlSecKeyDataId id) {
128
0
    int ret;
129
130
0
    xmlSecAssert2(id != xmlSecKeyDataIdUnknown, -1);
131
132
0
    ret = xmlSecPtrListAdd(&xmlSecAllKeyDataIds, (xmlSecPtr)id);
133
0
    if(ret < 0) {
134
0
        xmlSecInternalError("xmlSecPtrListAdd(&xmlSecAllKeyDataIds)", xmlSecKeyDataKlassGetName(id));
135
0
        return(-1);
136
0
    }
137
138
0
    ret = xmlSecPtrListAdd(&xmlSecEnabledKeyDataIds, (xmlSecPtr)id);
139
0
    if(ret < 0) {
140
0
        xmlSecInternalError("xmlSecPtrListAdd(&xmlSecEnabledKeyDataIds)", xmlSecKeyDataKlassGetName(id));
141
0
        return(-1);
142
0
    }
143
144
0
    return(0);
145
0
}
146
147
/**
148
 * xmlSecKeyDataIdsRegisterDisabled:
149
 * @id:                 the key data klass.
150
 *
151
 * Registers @id in the global list of key data klasses and but DO NOT enable this key data.
152
 *
153
 * Returns: 0 on success or a negative value if an error occurs.
154
 */
155
int
156
0
xmlSecKeyDataIdsRegisterDisabled(xmlSecKeyDataId id) {
157
0
    int ret;
158
159
0
    xmlSecAssert2(id != xmlSecKeyDataIdUnknown, -1);
160
161
0
    ret = xmlSecPtrListAdd(&xmlSecAllKeyDataIds, (xmlSecPtr)id);
162
0
    if(ret < 0) {
163
0
        xmlSecInternalError("xmlSecPtrListAdd(&xmlSecAllKeyDataIds)", xmlSecKeyDataKlassGetName(id));
164
0
        return(-1);
165
0
    }
166
167
0
    return(0);
168
0
}
169
170
/**
171
 * xmlSecKeyDataIdsRegisterDefault:
172
 *
173
 * Registers default (implemented by XML Security Library)
174
 * key data klasses: &lt;dsig:KeyName/&gt; element processing klass,
175
 * &lt;dsig:KeyValue/&gt; element processing klass, ...
176
 *
177
 * Returns: 0 on success or a negative value if an error occurs.
178
 */
179
int
180
0
xmlSecKeyDataIdsRegisterDefault(void) {
181
0
    if(xmlSecKeyDataIdsRegister(xmlSecKeyDataNameId) < 0) {
182
0
        xmlSecInternalError("xmlSecKeyDataIdsRegister(xmlSecKeyDataNameId)", NULL);
183
0
        return(-1);
184
0
    }
185
186
0
    if(xmlSecKeyDataIdsRegister(xmlSecKeyDataRetrievalMethodId) < 0) {
187
0
        xmlSecInternalError("xmlSecKeyDataIdsRegister(xmlSecKeyDataRetrievalMethodId", NULL);
188
0
        return(-1);
189
0
    }
190
191
0
    if(xmlSecKeyDataIdsRegister(xmlSecKeyDataKeyInfoReferenceId) < 0) {
192
0
        xmlSecInternalError("xmlSecKeyDataIdsRegister(xmlSecKeyDataKeyInfoReferenceId", NULL);
193
0
        return(-1);
194
0
    }
195
196
0
#ifndef XMLSEC_NO_XMLENC
197
0
    if(xmlSecKeyDataIdsRegister(xmlSecKeyDataEncryptedKeyId) < 0) {
198
0
        xmlSecInternalError("xmlSecKeyDataIdsRegister(xmlSecKeyDataEncryptedKeyId)", NULL);
199
0
        return(-1);
200
0
    }
201
0
    if(xmlSecKeyDataIdsRegister(xmlSecKeyDataAgreementMethodId) < 0) {
202
0
        xmlSecInternalError("xmlSecKeyDataIdsRegister(xmlSecKeyDataAgreementMethodId)", NULL);
203
0
        return(-1);
204
0
    }
205
0
    if(xmlSecKeyDataIdsRegister(xmlSecKeyDataDerivedKeyId) < 0) {
206
0
        xmlSecInternalError("xmlSecKeyDataIdsRegister(xmlSecKeyDataDerivedKeyId)", NULL);
207
0
        return(-1);
208
0
    }
209
0
#endif /* XMLSEC_NO_XMLENC */
210
211
    /* KeyValue key data should not be used in production w/o understanding of the security risks */
212
0
    if(xmlSecKeyDataIdsRegisterDisabled(xmlSecKeyDataValueId) < 0) {
213
0
        xmlSecInternalError("xmlSecKeyDataIdsRegister(xmlSecKeyDataValueId)", NULL);
214
0
        return(-1);
215
0
    }
216
217
0
    return(0);
218
0
}
219
220
/**************************************************************************
221
 *
222
 * xmlSecKeyData functions
223
 *
224
 *************************************************************************/
225
/**
226
 * xmlSecKeyDataCreate:
227
 * @id:                 the data id.
228
 *
229
 * Allocates and initializes new key data of the specified type @id.
230
 * Caller is responsible for destroying returned object with
231
 * #xmlSecKeyDataDestroy function.
232
 *
233
 * Returns: the pointer to newly allocated key data structure
234
 * or NULL if an error occurs.
235
 */
236
xmlSecKeyDataPtr
237
0
xmlSecKeyDataCreate(xmlSecKeyDataId id)  {
238
0
    xmlSecKeyDataPtr data;
239
0
    int ret;
240
241
0
    xmlSecAssert2(id != NULL, NULL);
242
0
    xmlSecAssert2(id->klassSize >= sizeof(xmlSecKeyDataKlass), NULL);
243
0
    xmlSecAssert2(id->objSize >= sizeof(xmlSecKeyData), NULL);
244
0
    xmlSecAssert2(id->name != NULL, NULL);
245
246
    /* Allocate a new xmlSecKeyData and fill the fields. */
247
0
    data = (xmlSecKeyDataPtr)xmlMalloc(id->objSize);
248
0
    if(data == NULL) {
249
0
        xmlSecMallocError(id->objSize,
250
0
                          xmlSecKeyDataKlassGetName(id));
251
0
        return(NULL);
252
0
    }
253
0
    memset(data, 0, id->objSize);
254
0
    data->id = id;
255
256
0
    if(id->initialize != NULL) {
257
0
        ret = (id->initialize)(data);
258
0
        if(ret < 0) {
259
0
            xmlSecInternalError("id->initialize",
260
0
                                xmlSecKeyDataKlassGetName(id));
261
0
            xmlSecKeyDataDestroy(data);
262
0
            return(NULL);
263
0
        }
264
0
    }
265
266
0
    return(data);
267
0
}
268
269
/**
270
 * xmlSecKeyDataDuplicate:
271
 * @data:               the pointer to the key data.
272
 *
273
 * Creates a duplicate of the given @data. Caller is responsible for
274
 * destroying returned object with #xmlSecKeyDataDestroy function.
275
 *
276
 * Returns: the pointer to newly allocated key data structure
277
 * or NULL if an error occurs.
278
 */
279
xmlSecKeyDataPtr
280
0
xmlSecKeyDataDuplicate(xmlSecKeyDataPtr data) {
281
0
    xmlSecKeyDataPtr newData;
282
0
    int ret;
283
284
0
    xmlSecAssert2(xmlSecKeyDataIsValid(data), NULL);
285
0
    xmlSecAssert2(data->id->duplicate != NULL, NULL);
286
287
0
    newData = xmlSecKeyDataCreate(data->id);
288
0
    if(newData == NULL) {
289
0
        xmlSecInternalError("xmlSecKeyDataCreate",
290
0
                            xmlSecKeyDataGetName(data));
291
0
        return(NULL);
292
0
    }
293
294
0
    ret = (data->id->duplicate)(newData, data);
295
0
    if(ret < 0) {
296
0
        xmlSecInternalError("id->duplicate",
297
0
                            xmlSecKeyDataGetName(data));
298
0
        xmlSecKeyDataDestroy(newData);
299
0
        return(NULL);
300
0
    }
301
302
0
    return(newData);
303
0
}
304
305
/**
306
 * xmlSecKeyDataDestroy:
307
 * @data:               the pointer to the key data.
308
 *
309
 * Destroys the data and frees all allocated memory.
310
 */
311
void
312
0
xmlSecKeyDataDestroy(xmlSecKeyDataPtr data) {
313
0
    xmlSecAssert(xmlSecKeyDataIsValid(data));
314
0
    xmlSecAssert(data->id->objSize > 0);
315
316
0
    if(data->id->finalize != NULL) {
317
0
        (data->id->finalize)(data);
318
0
    }
319
0
    memset(data, 0, data->id->objSize);
320
0
    xmlFree(data);
321
0
}
322
323
324
/**
325
 * xmlSecKeyDataXmlRead:
326
 * @id:                 the data klass.
327
 * @key:                the destination key.
328
 * @node:               the pointer to an XML node.
329
 * @keyInfoCtx:         the pointer to &lt;dsig:KeyInfo/&gt; element processing context.
330
 *
331
 * Reads the key data of klass @id from XML @node and adds them to @key.
332
 *
333
 * Returns: 0 on success or a negative value otherwise.
334
 */
335
int
336
0
xmlSecKeyDataXmlRead(xmlSecKeyDataId id, xmlSecKeyPtr key, xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx) {
337
0
    xmlSecAssert2(id != NULL, -1);
338
0
    xmlSecAssert2(id->xmlRead != NULL, -1);
339
0
    xmlSecAssert2(key != NULL, -1);
340
0
    xmlSecAssert2(node != NULL, -1);
341
342
0
    return((id->xmlRead)(id, key, node, keyInfoCtx));
343
0
}
344
345
/**
346
 * xmlSecKeyDataXmlWrite:
347
 * @id:                 the data klass.
348
 * @key:                the source key.
349
 * @node:               the pointer to an XML node.
350
 * @keyInfoCtx:         the pointer to &lt;dsig:KeyInfo/&gt; element processing context.
351
 *
352
 * Writes the key data of klass @id from @key to an XML @node.
353
 *
354
 * Returns: 0 on success or a negative value otherwise.
355
 */
356
int
357
0
xmlSecKeyDataXmlWrite(xmlSecKeyDataId id, xmlSecKeyPtr key, xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx) {
358
0
    xmlSecAssert2(id != NULL, -1);
359
0
    xmlSecAssert2(id->xmlWrite != NULL, -1);
360
0
    xmlSecAssert2(key != NULL, -1);
361
0
    xmlSecAssert2(node != NULL, -1);
362
363
0
    return((id->xmlWrite)(id, key, node, keyInfoCtx));
364
0
}
365
366
/**
367
 * xmlSecKeyDataBinRead:
368
 * @id:                 the data klass.
369
 * @key:                the destination key.
370
 * @buf:                the input binary buffer.
371
 * @bufSize:            the input buffer size.
372
 * @keyInfoCtx:         the &lt;dsig:KeyInfo/&gt; node processing context.
373
 *
374
 * Reads the key data of klass @id from binary buffer @buf to @key.
375
 *
376
 * Returns: 0 on success or a negative value if an error occurs.
377
 */
378
int
379
xmlSecKeyDataBinRead(xmlSecKeyDataId id, xmlSecKeyPtr key,
380
                    const xmlSecByte* buf, xmlSecSize bufSize,
381
0
                    xmlSecKeyInfoCtxPtr keyInfoCtx) {
382
0
    xmlSecAssert2(id != NULL, -1);
383
0
    xmlSecAssert2(id->binRead != NULL, -1);
384
0
    xmlSecAssert2(key != NULL, -1);
385
0
    xmlSecAssert2(buf != NULL, -1);
386
387
0
    return((id->binRead)(id, key, buf, bufSize, keyInfoCtx));
388
0
}
389
390
/**
391
 * xmlSecKeyDataBinWrite:
392
 * @id:                 the data klass.
393
 * @key:                the source key.
394
 * @buf:                the output binary buffer.
395
 * @bufSize:            the output buffer size.
396
 * @keyInfoCtx:         the &lt;dsig:KeyInfo/&gt; node processing context.
397
 *
398
 * Writes the key data of klass @id from the @key to a binary buffer @buf.
399
 *
400
 * Returns: 0 on success or a negative value if an error occurs.
401
 */
402
int
403
xmlSecKeyDataBinWrite(xmlSecKeyDataId id, xmlSecKeyPtr key,
404
                    xmlSecByte** buf, xmlSecSize* bufSize,
405
0
                    xmlSecKeyInfoCtxPtr keyInfoCtx) {
406
0
    xmlSecAssert2(id != NULL, -1);
407
0
    xmlSecAssert2(id->binWrite != NULL, -1);
408
0
    xmlSecAssert2(key != NULL, -1);
409
0
    xmlSecAssert2(buf != NULL, -1);
410
411
0
    return((id->binWrite)(id, key, buf, bufSize, keyInfoCtx));
412
0
}
413
414
/**
415
 * xmlSecKeyDataGenerate:
416
 * @data:               the pointer to key data.
417
 * @sizeBits:           the desired key data size (in bits).
418
 * @type:               the desired key data type.
419
 *
420
 * Generates new key data of given size and type.
421
 *
422
 * Returns: 0 on success or a negative value otherwise.
423
 */
424
int
425
xmlSecKeyDataGenerate(xmlSecKeyDataPtr data, xmlSecSize sizeBits,
426
0
                      xmlSecKeyDataType type) {
427
0
    int ret;
428
429
0
    xmlSecAssert2(xmlSecKeyDataIsValid(data), -1);
430
0
    xmlSecAssert2(data->id->generate != NULL, -1);
431
432
    /* write data */
433
0
    ret = data->id->generate(data, sizeBits, type);
434
0
    if(ret < 0) {
435
0
        xmlSecInternalError2("id->generate", xmlSecKeyDataGetName(data),
436
0
            "size=" XMLSEC_SIZE_FMT, sizeBits);
437
0
        return(-1);
438
0
    }
439
0
    return(0);
440
0
}
441
442
/**
443
 * xmlSecKeyDataGetType:
444
 * @data:               the pointer to key data.
445
 *
446
 * Gets key data type.
447
 *
448
 * Returns: key data type.
449
 */
450
xmlSecKeyDataType
451
0
xmlSecKeyDataGetType(xmlSecKeyDataPtr data) {
452
0
    xmlSecAssert2(xmlSecKeyDataIsValid(data), xmlSecKeyDataTypeUnknown);
453
0
    xmlSecAssert2(data->id->getType != NULL, xmlSecKeyDataTypeUnknown);
454
455
0
    return(data->id->getType(data));
456
0
}
457
458
/**
459
 * xmlSecKeyDataGetSize:
460
 * @data:               the pointer to key data.
461
 *
462
 * Gets key data size (in bits).
463
 *
464
 * Returns: key data size (in bits).
465
 */
466
xmlSecSize
467
0
xmlSecKeyDataGetSize(xmlSecKeyDataPtr data) {
468
0
    xmlSecAssert2(xmlSecKeyDataIsValid(data), 0);
469
0
    xmlSecAssert2(data->id->getSize != NULL, 0);
470
471
0
    return(data->id->getSize(data));
472
0
}
473
474
/**
475
 * xmlSecKeyDataGetIdentifier:
476
 * @data:               the pointer to key data.
477
 *
478
 * Gets key data identifier string.
479
 *
480
 * Returns: key data id string.
481
 */
482
const xmlChar*
483
0
xmlSecKeyDataGetIdentifier(xmlSecKeyDataPtr data) {
484
0
    xmlSecAssert2(xmlSecKeyDataIsValid(data), NULL);
485
0
    xmlSecAssert2(data->id->getIdentifier != NULL, NULL);
486
487
0
    return(data->id->getIdentifier(data));
488
0
}
489
490
/**
491
 * xmlSecKeyDataDebugDump:
492
 * @data:               the pointer to key data.
493
 * @output:             the pointer to output FILE.
494
 *
495
 * Prints key data debug info.
496
 */
497
void
498
0
xmlSecKeyDataDebugDump(xmlSecKeyDataPtr data, FILE *output) {
499
0
    xmlSecAssert(xmlSecKeyDataIsValid(data));
500
0
    xmlSecAssert(data->id->debugDump != NULL);
501
0
    xmlSecAssert(output != NULL);
502
503
0
    data->id->debugDump(data, output);
504
0
}
505
506
/**
507
 * xmlSecKeyDataDebugXmlDump:
508
 * @data:               the pointer to key data.
509
 * @output:             the pointer to output FILE.
510
 *
511
 * Prints key data debug info in XML format.
512
 */
513
void
514
0
xmlSecKeyDataDebugXmlDump(xmlSecKeyDataPtr data, FILE *output) {
515
0
    xmlSecAssert(xmlSecKeyDataIsValid(data));
516
0
    xmlSecAssert(data->id->debugXmlDump != NULL);
517
0
    xmlSecAssert(output != NULL);
518
519
0
    data->id->debugXmlDump(data, output);
520
0
}
521
522
/**************************************************************************
523
 *
524
 * xmlSecKeyDataBinary methods
525
 *
526
 *************************************************************************/
527
528
/**
529
 * xmlSecKeyDataBinaryValueInitialize:
530
 * @data:               the pointer to binary key data.
531
 *
532
 * Initializes binary key data.
533
 *
534
 * Returns: 0 on success or a negative value otherwise.
535
 */
536
int
537
0
xmlSecKeyDataBinaryValueInitialize(xmlSecKeyDataPtr data) {
538
0
    xmlSecBufferPtr buffer;
539
0
    int ret;
540
541
0
    xmlSecAssert2(xmlSecKeyDataIsValid(data), -1);
542
0
    xmlSecAssert2(xmlSecKeyDataCheckSize(data, xmlSecKeyDataBinarySize), -1);
543
544
    /* initialize buffer */
545
0
    buffer = xmlSecKeyDataBinaryValueGetBuffer(data);
546
0
    xmlSecAssert2(buffer != NULL, -1);
547
548
0
    ret = xmlSecBufferInitialize(buffer, 0);
549
0
    if(ret < 0) {
550
0
        xmlSecInternalError("xmlSecBufferInitialize",
551
0
                            xmlSecKeyDataGetName(data));
552
0
        return(-1);
553
0
    }
554
555
0
    return(0);
556
0
}
557
558
/**
559
 * xmlSecKeyDataBinaryValueDuplicate:
560
 * @dst:                the pointer to destination binary key data.
561
 * @src:                the pointer to source binary key data.
562
 *
563
 * Copies binary key data from @src to @dst.
564
 *
565
 * Returns: 0 on success or a negative value otherwise.
566
 */
567
int
568
0
xmlSecKeyDataBinaryValueDuplicate(xmlSecKeyDataPtr dst, xmlSecKeyDataPtr src) {
569
0
    xmlSecBufferPtr buffer;
570
0
    int ret;
571
572
0
    xmlSecAssert2(xmlSecKeyDataIsValid(dst), -1);
573
0
    xmlSecAssert2(xmlSecKeyDataCheckSize(dst, xmlSecKeyDataBinarySize), -1);
574
0
    xmlSecAssert2(xmlSecKeyDataIsValid(src), -1);
575
0
    xmlSecAssert2(xmlSecKeyDataCheckSize(src, xmlSecKeyDataBinarySize), -1);
576
577
0
    buffer = xmlSecKeyDataBinaryValueGetBuffer(src);
578
0
    xmlSecAssert2(buffer != NULL, -1);
579
580
    /* copy data */
581
0
    ret = xmlSecKeyDataBinaryValueSetBuffer(dst,
582
0
                    xmlSecBufferGetData(buffer),
583
0
                    xmlSecBufferGetSize(buffer));
584
0
    if(ret < 0) {
585
0
        xmlSecInternalError("xmlSecKeyDataBinaryValueSetBuffer",
586
0
                            xmlSecKeyDataGetName(dst));
587
0
        return(-1);
588
0
    }
589
590
0
    return(0);
591
0
}
592
593
/**
594
 * xmlSecKeyDataBinaryValueFinalize:
595
 * @data:               the pointer to binary key data.
596
 *
597
 * Cleans up binary key data.
598
 */
599
void
600
0
xmlSecKeyDataBinaryValueFinalize(xmlSecKeyDataPtr data) {
601
0
    xmlSecBufferPtr buffer;
602
603
0
    xmlSecAssert(xmlSecKeyDataIsValid(data));
604
0
    xmlSecAssert(xmlSecKeyDataCheckSize(data, xmlSecKeyDataBinarySize));
605
606
    /* initialize buffer */
607
0
    buffer = xmlSecKeyDataBinaryValueGetBuffer(data);
608
0
    xmlSecAssert(buffer != NULL);
609
610
0
    xmlSecBufferFinalize(buffer);
611
0
}
612
613
/**
614
 * xmlSecKeyDataBinaryValueXmlRead:
615
 * @id:                 the data klass.
616
 * @key:                the pointer to destination key.
617
 * @node:               the pointer to an XML node.
618
 * @keyInfoCtx:         the pointer to &lt;dsig:KeyInfo/&gt; element processing context.
619
 *
620
 * Reads binary key data from @node to the key by base64 decoding the @node content.
621
 *
622
 * Returns: 0 on success or a negative value otherwise.
623
 */
624
int
625
xmlSecKeyDataBinaryValueXmlRead(xmlSecKeyDataId id, xmlSecKeyPtr key,
626
0
                                xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx) {
627
0
    xmlChar* str = NULL;
628
0
    xmlSecKeyDataPtr data = NULL;
629
0
    xmlSecSize decodedSize;
630
0
    int ret;
631
0
    int res = -1;
632
633
0
    xmlSecAssert2(id != xmlSecKeyDataIdUnknown, -1);
634
0
    xmlSecAssert2(key != NULL, -1);
635
0
    xmlSecAssert2(node != NULL, -1);
636
0
    xmlSecAssert2(keyInfoCtx != NULL, -1);
637
638
0
    str = xmlNodeGetContent(node);
639
0
    if(str == NULL) {
640
0
        xmlSecInvalidNodeContentError(node, xmlSecKeyDataKlassGetName(id), "empty");
641
0
        goto done;
642
0
    }
643
644
    /* usual trick: decode into the same buffer */
645
0
    decodedSize = 0;
646
0
    ret = xmlSecBase64DecodeInPlace(str, &decodedSize);
647
0
    if(ret < 0) {
648
0
        xmlSecInternalError("xmlSecBase64Decode_ex", xmlSecKeyDataKlassGetName(id));
649
0
        goto done;
650
0
    }
651
652
    /* check do we have a key already */
653
0
    data = xmlSecKeyGetValue(key);
654
0
    if(data != NULL) {
655
0
        xmlSecBufferPtr buffer;
656
657
0
        if(!xmlSecKeyDataCheckId(data, id)) {
658
0
            xmlSecOtherError2(XMLSEC_ERRORS_R_KEY_DATA_ALREADY_EXIST, xmlSecKeyDataGetName(data),
659
0
                "id=%s", xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)));
660
0
            goto done;
661
0
        }
662
663
0
        buffer = xmlSecKeyDataBinaryValueGetBuffer(data);
664
0
        if(buffer != NULL) {
665
0
            if(xmlSecBufferGetSize(buffer) != decodedSize) {
666
0
                xmlSecOtherError3(XMLSEC_ERRORS_R_KEY_DATA_ALREADY_EXIST,
667
0
                    xmlSecKeyDataGetName(data),
668
0
                    "cur-data-size=" XMLSEC_SIZE_FMT "; new-data-size=" XMLSEC_SIZE_FMT,
669
0
                    xmlSecBufferGetSize(buffer), decodedSize);
670
0
                goto done;
671
0
            }
672
0
            if((decodedSize > 0) && (memcmp(xmlSecBufferGetData(buffer), str, decodedSize) != 0)) {
673
0
                xmlSecOtherError(XMLSEC_ERRORS_R_KEY_DATA_ALREADY_EXIST,
674
0
                    xmlSecKeyDataGetName(data),
675
0
                    "key already has a different value");
676
0
                goto done;
677
0
            }
678
679
            /* we already have exactly the same key */
680
0
            res = 0;
681
0
            goto done;
682
0
        }
683
684
        /* we have binary key value with empty buffer */
685
0
    }
686
687
688
0
    data = xmlSecKeyDataCreate(id);
689
0
    if(data == NULL ) {
690
0
        xmlSecInternalError("xmlSecKeyDataCreate", xmlSecKeyDataKlassGetName(id));
691
0
        goto done;
692
0
    }
693
694
0
    ret = xmlSecKeyDataBinaryValueSetBuffer(data, (xmlSecByte*)str, decodedSize);
695
0
    if(ret < 0) {
696
0
        xmlSecInternalError2("xmlSecKeyDataBinaryValueSetBuffer",
697
0
            xmlSecKeyDataKlassGetName(id),
698
0
            "size=" XMLSEC_SIZE_FMT, decodedSize);
699
0
        goto done;
700
0
    }
701
702
0
    if(xmlSecKeyReqMatchKeyValue(&(keyInfoCtx->keyReq), data) != 1) {
703
0
        xmlSecInternalError("xmlSecKeyReqMatchKeyValue", xmlSecKeyDataKlassGetName(id));
704
0
        goto done;
705
0
    }
706
707
0
    ret = xmlSecKeySetValue(key, data);
708
0
    if(ret < 0) {
709
0
        xmlSecInternalError("xmlSecKeySetValue", xmlSecKeyDataKlassGetName(id));
710
0
        goto done;
711
0
    }
712
0
    data = NULL; /* data is owned by key */
713
714
    /* success */
715
0
    res = 0;
716
717
0
done:
718
0
    if(data != NULL) {
719
0
        xmlSecKeyDataDestroy(data);
720
0
    }
721
0
    if(str != NULL) {
722
0
        xmlFree(str);
723
0
    }
724
0
    return(res);
725
0
}
726
727
/**
728
 * xmlSecKeyDataBinaryValueXmlWrite:
729
 * @id:                 the data klass.
730
 * @key:                the pointer to source key.
731
 * @node:               the pointer to an XML node.
732
 * @keyInfoCtx:         the pointer to &lt;dsig:KeyInfo/&gt; element processing context.
733
 *
734
 * Base64 encodes binary key data of klass @id from the @key and
735
 * sets to the @node content.
736
 *
737
 * Returns: 0 on success or a negative value otherwise.
738
 */
739
int
740
xmlSecKeyDataBinaryValueXmlWrite(xmlSecKeyDataId id, xmlSecKeyPtr key,
741
0
                            xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx) {
742
0
    xmlSecBufferPtr buffer;
743
0
    xmlSecKeyDataPtr value;
744
0
    xmlChar* str;
745
746
0
    xmlSecAssert2(id != xmlSecKeyDataIdUnknown, -1);
747
0
    xmlSecAssert2(key != NULL, -1);
748
0
    xmlSecAssert2(node != NULL, -1);
749
0
    xmlSecAssert2(keyInfoCtx != NULL, -1);
750
751
0
    if((xmlSecKeyDataTypeSymmetric & keyInfoCtx->keyReq.keyType) == 0) {
752
        /* we can have only symmetric key */
753
0
        return(0);
754
0
    }
755
756
0
    value = xmlSecKeyGetValue(key);
757
0
    xmlSecAssert2(xmlSecKeyDataIsValid(value), -1);
758
759
0
    buffer = xmlSecKeyDataBinaryValueGetBuffer(value);
760
0
    xmlSecAssert2(buffer != NULL, -1);
761
762
0
    str = xmlSecBase64Encode(xmlSecBufferGetData(buffer),
763
0
                             xmlSecBufferGetSize(buffer),
764
0
                             keyInfoCtx->base64LineSize);
765
0
    if(str == NULL) {
766
0
        xmlSecInternalError("xmlSecBase64Encode",
767
0
                            xmlSecKeyDataKlassGetName(id));
768
0
        return(-1);
769
0
    }
770
0
    xmlNodeSetContent(node, str);
771
0
    xmlFree(str);
772
0
    return(0);
773
0
}
774
775
/**
776
 * xmlSecKeyDataBinaryValueBinRead:
777
 * @id:                 the data klass.
778
 * @key:                the pointer to destination key.
779
 * @buf:                the source binary buffer.
780
 * @bufSize:            the source binary buffer size.
781
 * @keyInfoCtx:         the pointer to &lt;dsig:KeyInfo/&gt; element processing context.
782
 *
783
 * Reads binary key data of the klass @id from @buf to the @key.
784
 *
785
 * Returns: 0 on success or a negative value otherwise.
786
 */
787
int
788
xmlSecKeyDataBinaryValueBinRead(xmlSecKeyDataId id, xmlSecKeyPtr key,
789
                                const xmlSecByte* buf, xmlSecSize bufSize,
790
0
                                xmlSecKeyInfoCtxPtr keyInfoCtx) {
791
0
    xmlSecKeyDataPtr data;
792
0
    int ret;
793
794
0
    xmlSecAssert2(id != xmlSecKeyDataIdUnknown, -1);
795
0
    xmlSecAssert2(key != NULL, -1);
796
0
    xmlSecAssert2(buf != NULL, -1);
797
0
    xmlSecAssert2(bufSize > 0, -1);
798
0
    xmlSecAssert2(keyInfoCtx != NULL, -1);
799
800
    /* check do we have a key already */
801
0
    data = xmlSecKeyGetValue(key);
802
0
    if(data != NULL) {
803
0
        xmlSecBufferPtr buffer;
804
805
0
        if(!xmlSecKeyDataCheckId(data, id)) {
806
0
            xmlSecOtherError2(XMLSEC_ERRORS_R_KEY_DATA_ALREADY_EXIST,
807
0
                              xmlSecKeyDataGetName(data),
808
0
                              "id=%s",
809
0
                              xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)));
810
0
            return(-1);
811
0
        }
812
813
0
        buffer = xmlSecKeyDataBinaryValueGetBuffer(data);
814
0
        if(buffer != NULL) {
815
0
            if(xmlSecBufferGetSize(buffer) != bufSize) {
816
0
                xmlSecOtherError3(XMLSEC_ERRORS_R_KEY_DATA_ALREADY_EXIST,
817
0
                    xmlSecKeyDataGetName(data),
818
0
                    "cur-data-size=" XMLSEC_SIZE_FMT "; new-data-size=" XMLSEC_SIZE_FMT,
819
0
                    xmlSecBufferGetSize(buffer), bufSize);
820
0
                return(-1);
821
0
            }
822
0
            if((bufSize > 0) && (memcmp(xmlSecBufferGetData(buffer), buf, bufSize) != 0)) {
823
0
                xmlSecOtherError(XMLSEC_ERRORS_R_KEY_DATA_ALREADY_EXIST,
824
0
                    xmlSecKeyDataGetName(data),
825
0
                    "key already has a different value");
826
0
                return(-1);
827
0
            }
828
829
            /* we already have exactly the same key */
830
0
            return(0);
831
0
        }
832
833
        /* we have binary key value with empty buffer */
834
0
    }
835
836
0
    data = xmlSecKeyDataCreate(id);
837
0
    if(data == NULL ) {
838
0
        xmlSecInternalError("xmlSecKeyDataCreate", xmlSecKeyDataKlassGetName(id));
839
0
        return(-1);
840
0
    }
841
842
0
    ret = xmlSecKeyDataBinaryValueSetBuffer(data, buf, bufSize);
843
0
    if(ret < 0) {
844
0
        xmlSecInternalError2("xmlSecKeyDataBinaryValueSetBuffer",
845
0
            xmlSecKeyDataKlassGetName(id),
846
0
            "size=" XMLSEC_SIZE_FMT, bufSize);
847
0
        xmlSecKeyDataDestroy(data);
848
0
        return(-1);
849
0
    }
850
851
0
    if(xmlSecKeyReqMatchKeyValue(&(keyInfoCtx->keyReq), data) != 1) {
852
0
        xmlSecInternalError("xmlSecKeyReqMatchKeyValue",
853
0
            xmlSecKeyDataKlassGetName(id));
854
0
        xmlSecKeyDataDestroy(data);
855
0
        return(0);
856
0
    }
857
858
0
    ret = xmlSecKeySetValue(key, data);
859
0
    if(ret < 0) {
860
0
        xmlSecInternalError("xmlSecKeySetValue",
861
0
            xmlSecKeyDataKlassGetName(id));
862
0
        xmlSecKeyDataDestroy(data);
863
0
        return(-1);
864
0
    }
865
866
0
    return(0);
867
0
}
868
869
/**
870
 * xmlSecKeyDataBinaryValueBinWrite:
871
 * @id:                 the data klass.
872
 * @key:                the pointer to source key.
873
 * @buf:                the destination binary buffer.
874
 * @bufSize:            the destination binary buffer size.
875
 * @keyInfoCtx:         the pointer to &lt;dsig:KeyInfo/&gt; element processing context.
876
 *
877
 * Writes binary key data of klass @id from the @key to @buf.
878
 *
879
 * Returns: 0 on success or a negative value otherwise.
880
 */
881
int
882
xmlSecKeyDataBinaryValueBinWrite(xmlSecKeyDataId id, xmlSecKeyPtr key,
883
                                xmlSecByte** buf, xmlSecSize* bufSize,
884
0
                                xmlSecKeyInfoCtxPtr keyInfoCtx) {
885
0
    xmlSecKeyDataPtr value;
886
0
    xmlSecBufferPtr buffer;
887
888
0
    xmlSecAssert2(id != xmlSecKeyDataIdUnknown, -1);
889
0
    xmlSecAssert2(key != NULL, -1);
890
0
    xmlSecAssert2(buf != NULL, -1);
891
0
    xmlSecAssert2(bufSize != NULL, -1);
892
0
    xmlSecAssert2(keyInfoCtx != NULL, -1);
893
894
0
    if((xmlSecKeyDataTypeSymmetric & keyInfoCtx->keyReq.keyType) == 0) {
895
        /* we can have only symmetric key */
896
0
        return(0);
897
0
    }
898
899
0
    value = xmlSecKeyGetValue(key);
900
0
    xmlSecAssert2(xmlSecKeyDataIsValid(value), -1);
901
902
0
    buffer = xmlSecKeyDataBinaryValueGetBuffer(key->value);
903
0
    xmlSecAssert2(buffer != NULL, -1);
904
905
0
    (*bufSize) = xmlSecBufferGetSize(buffer);
906
0
    (*buf) = (xmlSecByte*) xmlMalloc((*bufSize));
907
0
    if((*buf) == NULL) {
908
0
        xmlSecMallocError((*bufSize),
909
0
                          xmlSecKeyDataKlassGetName(id));
910
0
        return(-1);
911
0
    }
912
0
    memcpy((*buf), xmlSecBufferGetData(buffer), (*bufSize));
913
0
    return(0);
914
0
}
915
916
/**
917
 * xmlSecKeyDataBinaryValueDebugDump:
918
 * @data:               the pointer to binary key data.
919
 * @output:             the pointer to output FILE.
920
 *
921
 * Prints binary key data debug information to @output.
922
 */
923
void
924
0
xmlSecKeyDataBinaryValueDebugDump(xmlSecKeyDataPtr data, FILE* output) {
925
0
    xmlSecBufferPtr buffer;
926
927
0
    xmlSecAssert(xmlSecKeyDataIsValid(data));
928
0
    xmlSecAssert(xmlSecKeyDataCheckSize(data, xmlSecKeyDataBinarySize));
929
0
    xmlSecAssert(data->id->dataNodeName != NULL);
930
0
    xmlSecAssert(output != NULL);
931
932
0
    buffer = xmlSecKeyDataBinaryValueGetBuffer(data);
933
0
    xmlSecAssert(buffer != NULL);
934
935
    /* print only size, everything else is sensitive */
936
0
    fprintf(output, "=== %s: size=" XMLSEC_SIZE_FMT "\n",
937
0
        data->id->dataNodeName, xmlSecKeyDataGetSize(data));
938
0
}
939
940
/**
941
 * xmlSecKeyDataBinaryValueDebugXmlDump:
942
 * @data:               the pointer to binary key data.
943
 * @output:             the pointer to output FILE.
944
 *
945
 * Prints binary key data debug information to @output in XML format.
946
 */
947
void
948
0
xmlSecKeyDataBinaryValueDebugXmlDump(xmlSecKeyDataPtr data, FILE* output) {
949
0
    xmlSecBufferPtr buffer;
950
951
0
    xmlSecAssert(xmlSecKeyDataIsValid(data));
952
0
    xmlSecAssert(xmlSecKeyDataCheckSize(data, xmlSecKeyDataBinarySize));
953
0
    xmlSecAssert(data->id->dataNodeName != NULL);
954
0
    xmlSecAssert(output != NULL);
955
956
0
    buffer = xmlSecKeyDataBinaryValueGetBuffer(data);
957
0
    xmlSecAssert(buffer != NULL);
958
959
    /* print only size, everything else is sensitive */
960
0
    fprintf(output, "<%s size=\"" XMLSEC_SIZE_FMT "\" />\n",
961
0
        data->id->dataNodeName, xmlSecKeyDataGetSize(data));
962
0
}
963
964
/**
965
 * xmlSecKeyDataBinaryValueGetSize:
966
 * @data:               the pointer to binary key data.
967
 *
968
 * Gets the binary key data size.
969
 *
970
 * Returns: binary key data size in bits.
971
 */
972
xmlSecSize
973
0
xmlSecKeyDataBinaryValueGetSize(xmlSecKeyDataPtr data) {
974
0
    xmlSecBufferPtr buffer;
975
976
0
    xmlSecAssert2(xmlSecKeyDataIsValid(data), 0);
977
0
    xmlSecAssert2(xmlSecKeyDataCheckSize(data, xmlSecKeyDataBinarySize), 0);
978
979
0
    buffer = xmlSecKeyDataBinaryValueGetBuffer(data);
980
0
    xmlSecAssert2(buffer != NULL, 0);
981
982
    /* return size in bits */
983
0
    return(8 * xmlSecBufferGetSize(buffer));
984
0
}
985
986
/**
987
 * xmlSecKeyDataBinaryValueGetBuffer:
988
 * @data:               the pointer to binary key data.
989
 *
990
 * Gets the binary key data buffer.
991
 *
992
 * Returns: pointer to binary key data buffer.
993
 */
994
xmlSecBufferPtr
995
0
xmlSecKeyDataBinaryValueGetBuffer(xmlSecKeyDataPtr data) {
996
0
    xmlSecAssert2(xmlSecKeyDataIsValid(data), NULL);
997
0
    xmlSecAssert2(xmlSecKeyDataCheckSize(data, xmlSecKeyDataBinarySize), NULL);
998
999
0
    return(&(((xmlSecKeyDataBinary *)data)->buffer));
1000
0
}
1001
1002
/**
1003
 * xmlSecKeyDataBinaryValueSetBuffer:
1004
 * @data:               the pointer to binary key data.
1005
 * @buf:                the pointer to binary buffer.
1006
 * @bufSize:            the binary buffer size.
1007
 *
1008
 * Sets the value of @data to @buf.
1009
 *
1010
 * Returns: 0 on success or a negative value otherwise.
1011
 */
1012
int
1013
xmlSecKeyDataBinaryValueSetBuffer(xmlSecKeyDataPtr data,
1014
0
                        const xmlSecByte* buf, xmlSecSize bufSize) {
1015
0
    xmlSecBufferPtr buffer;
1016
1017
0
    xmlSecAssert2(xmlSecKeyDataIsValid(data), -1);
1018
0
    xmlSecAssert2(xmlSecKeyDataCheckSize(data, xmlSecKeyDataBinarySize), -1);
1019
0
    xmlSecAssert2(buf != NULL, -1);
1020
0
    xmlSecAssert2(bufSize > 0, -1);
1021
1022
0
    buffer = xmlSecKeyDataBinaryValueGetBuffer(data);
1023
0
    xmlSecAssert2(buffer != NULL, -1);
1024
1025
0
    return(xmlSecBufferSetData(buffer, buf, bufSize));
1026
0
}
1027
1028
#if !defined(XMLSEC_NO_EC)
1029
/**************************************************************************
1030
 *
1031
 * Helper functions to read/write EC keys
1032
 *
1033
 *************************************************************************/
1034
0
#define XMLSEC_KEY_DATA_EC_INIT_BUF_SIZE                               256
1035
1036
static int                      xmlSecKeyValueEcInitialize              (xmlSecKeyValueEcPtr data);
1037
static void                     xmlSecKeyValueEcFinalize                (xmlSecKeyValueEcPtr data);
1038
static int                      xmlSecKeyValueEcXmlRead                 (xmlSecKeyValueEcPtr data,
1039
                                                                         xmlNodePtr node);
1040
static int                      xmlSecKeyValueEcXmlWrite                (xmlSecKeyValueEcPtr data,
1041
                                                                         xmlNodePtr node,
1042
                                                                         int base64LineSize,
1043
                                                                         int addLineBreaks);
1044
1045
/**
1046
 * xmlSecKeyDataEcXmlRead:
1047
 * @id:                 the data id.
1048
 * @key:                the key.
1049
 * @node:               the pointer to data's value XML node.
1050
 * @keyInfoCtx:         the &lt;dsig:KeyInfo/&gt; node processing context.
1051
 * @readFunc:           the pointer to the function that converts
1052
 *                      @xmlSecKeyValueEc to @xmlSecKeyData.
1053
 *
1054
 * DSA Key data method for reading XML node.
1055
 *
1056
 * Returns: 0 on success or a negative value if an error occurs.
1057
 */
1058
int
1059
xmlSecKeyDataEcXmlRead(xmlSecKeyDataId id, xmlSecKeyPtr key,
1060
    xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx,
1061
    xmlSecKeyDataEcRead readFunc)
1062
0
{
1063
0
    xmlSecKeyDataPtr data = NULL;
1064
0
    xmlSecKeyValueEc ecValue;
1065
0
    int ecDataInitialized = 0;
1066
0
    int res = -1;
1067
0
    int ret;
1068
1069
0
    xmlSecAssert2(id != NULL, -1);
1070
0
    xmlSecAssert2(key != NULL, -1);
1071
0
    xmlSecAssert2(node != NULL, -1);
1072
0
    xmlSecAssert2(keyInfoCtx != NULL, -1);
1073
0
    xmlSecAssert2(readFunc != NULL, -1);
1074
1075
0
    if(xmlSecKeyGetValue(key) != NULL) {
1076
0
        xmlSecOtherError(XMLSEC_ERRORS_R_INVALID_KEY_DATA,
1077
0
            xmlSecKeyDataKlassGetName(id), "key already has a value");
1078
0
        goto done;
1079
0
    }
1080
1081
0
    ret = xmlSecKeyValueEcInitialize(&ecValue);
1082
0
    if(ret < 0) {
1083
0
        xmlSecInternalError("xmlSecKeyValueEcInitialize",
1084
0
            xmlSecKeyDataKlassGetName(id));
1085
0
        goto done;
1086
0
    }
1087
0
    ecDataInitialized = 1;
1088
1089
0
    ret = xmlSecKeyValueEcXmlRead(&ecValue, node);
1090
0
    if(ret < 0) {
1091
0
        xmlSecInternalError("xmlSecKeyValueEcXmlRead",
1092
0
            xmlSecKeyDataKlassGetName(id));
1093
0
        goto done;
1094
0
    }
1095
1096
0
    data = readFunc(id, &ecValue);
1097
0
    if(data == NULL) {
1098
0
        xmlSecInternalError("xmlSecKeyDataEcRead",
1099
0
            xmlSecKeyDataKlassGetName(id));
1100
0
        goto done;
1101
0
    }
1102
1103
    /* set key value */
1104
0
    ret = xmlSecKeySetValue(key, data);
1105
0
    if(ret < 0) {
1106
0
        xmlSecInternalError("xmlSecKeySetValue",
1107
0
                            xmlSecKeyDataGetName(data));
1108
0
        goto done;
1109
0
    }
1110
0
    data = NULL; /* data is owned by key now */
1111
1112
    /* success */
1113
0
    res = 0;
1114
1115
0
done:
1116
    /* cleanup */
1117
0
    if(ecDataInitialized != 0) {
1118
0
        xmlSecKeyValueEcFinalize(&ecValue);
1119
0
    }
1120
0
    if(data != NULL) {
1121
0
        xmlSecKeyDataDestroy(data);
1122
0
    }
1123
0
    return(res);
1124
0
}
1125
1126
/**
1127
 * xmlSecKeyDataEcXmlWrite:
1128
 * @id:                 the data id.
1129
 * @key:                the key.
1130
 * @node:               the pointer to data's value XML node.
1131
 * @keyInfoCtx:         the &lt;dsig:KeyInfo/&gt; node processing context.
1132
 * @base64LineSize:     the base64 max line size.
1133
 * @addLineBreaks:      the flag indicating if we need to add line breaks around base64 output.
1134
 * @writeFunc:          the pointer to the function that converts
1135
 *                      @xmlSecKeyData to  @xmlSecKeyValueEc.
1136
 *
1137
 * DSA Key data  method for writing XML node.
1138
 *
1139
 * Returns: 0 on success or a negative value if an error occurs.
1140
 */
1141
int
1142
xmlSecKeyDataEcXmlWrite(xmlSecKeyDataId id, xmlSecKeyPtr key,
1143
                        xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx,
1144
                        int base64LineSize, int addLineBreaks,
1145
0
                        xmlSecKeyDataEcWrite writeFunc) {
1146
0
    xmlSecKeyDataPtr data;
1147
0
    xmlSecKeyValueEc ecValue;
1148
0
    int ecDataInitialized = 0;
1149
0
    int res = -1;
1150
0
    int ret;
1151
1152
0
    xmlSecAssert2(id != NULL, -1);
1153
0
    xmlSecAssert2(key != NULL, -1);
1154
0
    xmlSecAssert2(node != NULL, -1);
1155
0
    xmlSecAssert2(keyInfoCtx != NULL, -1);
1156
0
    xmlSecAssert2(writeFunc != NULL, -1);
1157
0
    xmlSecAssert2(base64LineSize > 0, -1);
1158
1159
0
    if(((xmlSecKeyDataTypePublic | xmlSecKeyDataTypePrivate) & keyInfoCtx->keyReq.keyType) == 0) {
1160
        /* we can have only private key or public key */
1161
0
        return(0);
1162
0
    }
1163
1164
0
    data = xmlSecKeyGetValue(key);
1165
0
    if(data == NULL) {
1166
0
        xmlSecOtherError(XMLSEC_ERRORS_R_INVALID_KEY_DATA,
1167
0
            xmlSecKeyDataKlassGetName(id), "key has no value");
1168
0
        goto done;
1169
0
    }
1170
1171
0
    ret = xmlSecKeyValueEcInitialize(&ecValue);
1172
0
    if(ret < 0) {
1173
0
        xmlSecInternalError("xmlSecKeyValueEcInitialize",
1174
0
            xmlSecKeyDataKlassGetName(id));
1175
0
        goto done;
1176
0
    }
1177
0
    ecDataInitialized = 1;
1178
1179
0
    ret = writeFunc(id, data, &ecValue);
1180
0
    if(ret < 0) {
1181
0
        xmlSecInternalError("xmlSecKeyDataEcWrite",
1182
0
            xmlSecKeyDataKlassGetName(id));
1183
0
        goto done;
1184
0
    }
1185
1186
0
    ret = xmlSecKeyValueEcXmlWrite(&ecValue, node, base64LineSize, addLineBreaks);
1187
0
    if(ret < 0) {
1188
0
        xmlSecInternalError("xmlSecKeyValueEcXmlWrite",
1189
0
            xmlSecKeyDataKlassGetName(id));
1190
0
        goto done;
1191
0
    }
1192
1193
    /* success */
1194
0
    res = 0;
1195
1196
0
done:
1197
    /* cleanup */
1198
0
    if(ecDataInitialized != 0) {
1199
0
        xmlSecKeyValueEcFinalize(&ecValue);
1200
0
    }
1201
0
    return(res);
1202
0
}
1203
1204
static int
1205
0
xmlSecKeyValueEcInitialize(xmlSecKeyValueEcPtr data) {
1206
0
    int ret;
1207
1208
0
    xmlSecAssert2(data != NULL, -1);
1209
0
    memset(data, 0, sizeof(xmlSecKeyValueEc));
1210
1211
0
    ret = xmlSecBufferInitialize(&(data->pubkey), XMLSEC_KEY_DATA_EC_INIT_BUF_SIZE);
1212
0
    if(ret < 0) {
1213
0
        xmlSecInternalError("xmlSecBufferInitialize(pubkey)", NULL);
1214
0
        xmlSecKeyValueEcFinalize(data);
1215
0
        return(-1);
1216
0
    }
1217
0
    ret = xmlSecBufferInitialize(&(data->pub_x), XMLSEC_KEY_DATA_EC_INIT_BUF_SIZE);
1218
0
    if(ret < 0) {
1219
0
        xmlSecInternalError("xmlSecBufferInitialize(pub_x)", NULL);
1220
0
        xmlSecKeyValueEcFinalize(data);
1221
0
        return(-1);
1222
0
    }
1223
0
    ret = xmlSecBufferInitialize(&(data->pub_y), XMLSEC_KEY_DATA_EC_INIT_BUF_SIZE);
1224
0
    if(ret < 0) {
1225
0
        xmlSecInternalError("xmlSecBufferInitialize(pub_y)", NULL);
1226
0
        xmlSecKeyValueEcFinalize(data);
1227
0
        return(-1);
1228
0
    }
1229
0
    return(0);
1230
0
}
1231
1232
static void
1233
0
xmlSecKeyValueEcFinalize(xmlSecKeyValueEcPtr data) {
1234
0
    xmlSecAssert(data != NULL);
1235
1236
0
    if(data->curve != NULL) {
1237
0
        xmlFree(data->curve);
1238
0
    }
1239
0
    xmlSecBufferFinalize(&(data->pubkey));
1240
0
    xmlSecBufferFinalize(&(data->pub_x));
1241
0
    xmlSecBufferFinalize(&(data->pub_y));
1242
1243
0
    memset(data, 0, sizeof(xmlSecKeyValueEc));
1244
0
}
1245
1246
1247
/*
1248
 * The PublicKey element contains a Base64 encoding of a binary representation of the x and y coordinates of
1249
 * the point. Its value is computed as follows:
1250
 *  1/ Convert the elliptic curve point (x,y) to an octet string by first converting the field elements
1251
 *     x and y to octet strings as specified in Section 6.2 of [ECC-ALGS] (note), and then prepend the
1252
 *     concatenated result of the conversion with 0x04. Support for Elliptic-Curve-Point-to-Octet-String
1253
 *     conversion without point compression is REQUIRED.
1254
 *  2/ Base64 encode the octet string resulting from the conversion in Step 1.
1255
 */
1256
0
#define XMLSEC_ECKEYVALYU_ECPOINT_MAGIC_BYTE        0x04
1257
1258
int
1259
0
xmlSecKeyDataEcPublicKeySplitComponents (xmlSecKeyValueEcPtr ecValue) {
1260
0
    xmlSecSize size;
1261
0
    xmlSecByte* data;
1262
0
    int ret;
1263
1264
0
    xmlSecAssert2(ecValue != NULL, -1);
1265
1266
    /* check size and magic number */
1267
0
    data = xmlSecBufferGetData(&(ecValue->pubkey));
1268
0
    size = xmlSecBufferGetSize(&(ecValue->pubkey));
1269
0
    if((data == NULL) || (size <= 1) || ((size % 2) != 1)) {
1270
0
        xmlSecInvalidSizeDataError("PublicKey", size, "ECPoint data should have an odd size > 1 ", NULL);
1271
0
        return(-1);
1272
0
    }
1273
0
    if(data[0] != XMLSEC_ECKEYVALYU_ECPOINT_MAGIC_BYTE) {
1274
0
        xmlSecInvalidDataError("PublicKey must start from a magic number", NULL);
1275
0
        return(-1);
1276
0
    }
1277
0
    ++data;
1278
0
    size = (size - 1) / 2;
1279
1280
    /* set pub_y */
1281
0
    ret = xmlSecBufferSetData(&(ecValue->pub_x), data, size);
1282
0
    if(ret < 0) {
1283
0
        xmlSecInternalError2("xmlSecBufferSetData(pub_x)", NULL,
1284
0
            "size=" XMLSEC_SIZE_FMT, size);
1285
0
        return(-1);
1286
0
    }
1287
1288
    /* set pub_y */
1289
0
    ret = xmlSecBufferSetData(&(ecValue->pub_y), data + size, size);
1290
0
    if(ret < 0) {
1291
0
        xmlSecInternalError2("xmlSecBufferSetData(pub_y)", NULL,
1292
0
            "size=" XMLSEC_SIZE_FMT, size);
1293
0
        return(-1);
1294
0
    }
1295
1296
    /* done */
1297
0
    return(0);
1298
0
}
1299
1300
int
1301
0
xmlSecKeyDataEcPublicKeyCombineComponents (xmlSecKeyValueEcPtr ecValue) {
1302
0
    xmlSecByte * dataX, * dataY, * data;
1303
0
    xmlSecSize sizeX, sizeY, sizeKey, size;
1304
0
    int ret;
1305
1306
0
    xmlSecAssert2(ecValue != NULL, -1);
1307
1308
0
    dataX = xmlSecBufferGetData(&(ecValue->pub_x));
1309
0
    sizeX = xmlSecBufferGetSize(&(ecValue->pub_x));
1310
0
    dataY = xmlSecBufferGetData(&(ecValue->pub_y));
1311
0
    sizeY = xmlSecBufferGetSize(&(ecValue->pub_y));
1312
1313
0
    xmlSecAssert2(dataX != NULL, -1);
1314
0
    xmlSecAssert2(dataY != NULL, -1);
1315
0
    xmlSecAssert2(sizeX > 0, -1);
1316
0
    xmlSecAssert2(sizeY > 0, -1);
1317
1318
    /* max of the two sizes (prepend 0s if needed) */
1319
0
    sizeKey = (sizeX >= sizeY) ? sizeX : sizeY;
1320
0
    size = 1 + 2 * sizeKey; /* <magic byte> || x || y */
1321
0
    ret = xmlSecBufferSetSize(&(ecValue->pubkey), size);
1322
0
    if(ret < 0) {
1323
0
        xmlSecInternalError2("xmlSecBufferSetSize(pubkeyy)", NULL,
1324
0
            "size=" XMLSEC_SIZE_FMT, size);
1325
0
        return(-1);
1326
0
    }
1327
0
    data = xmlSecBufferGetData(&(ecValue->pubkey));
1328
0
    xmlSecAssert2(data != NULL, -1);
1329
1330
    /*  <magic byte> || x || y,  prepend 0s if needed */
1331
0
    memset(data, 0, size);
1332
0
    data[0] = XMLSEC_ECKEYVALYU_ECPOINT_MAGIC_BYTE;
1333
0
    memcpy(data + 1 + sizeKey - sizeX, dataX, sizeX);
1334
0
    memcpy(data + 1 + sizeKey + sizeKey - sizeY, dataY, sizeY);
1335
1336
    /* done */
1337
0
    return(0);
1338
0
}
1339
1340
1341
/* See https://www.w3.org/TR/xmldsig-core/#sec-ECKeyValue
1342
 *
1343
 * <!-- targetNamespace="http://www.w3.org/2009/xmldsig11#" -->
1344
 *
1345
 * <element name="ECKeyValue" type="dsig11:ECKeyValueType" />
1346
 *
1347
 * <complexType name="ECKeyValueType">
1348
 *  <sequence>
1349
 *      <choice>
1350
 *          <element name="ECParameters" type="dsig11:ECParametersType" />
1351
 *          <element name="NamedCurve" type="dsig11:NamedCurveType" />
1352
 *      </choice>
1353
 *      <element name="PublicKey" type="dsig11:ECPointType" />
1354
 *  </sequence>
1355
 *  <attribute name="Id" type="ID" use="optional" />
1356
 * </complexType>
1357
 *
1358
 * <complexType name="NamedCurveType">
1359
 *  <attribute name="URI" type="anyURI" use="required" />
1360
 * </complexType>
1361
 *
1362
 * <simpleType name="ECPointType">
1363
 *  <restriction base="ds:CryptoBinary" />
1364
 * </simpleType>
1365
 *
1366
 * Note that ECParameters node is not supported for now (https://github.com/lsh123/xmlsec/issues/516).
1367
 *
1368
*/
1369
0
#define XMLSEC_KEYVALUE_EC_OID_PREFIX   (BAD_CAST "urn:oid:")
1370
1371
static int
1372
0
xmlSecKeyValueEcXmlRead(xmlSecKeyValueEcPtr data, xmlNodePtr node) {
1373
0
    xmlNodePtr cur;
1374
0
    int ret;
1375
1376
0
    xmlSecAssert2(data != NULL, -1);
1377
0
    xmlSecAssert2(data->curve == NULL, -1);
1378
0
    xmlSecAssert2(node != NULL, -1);
1379
1380
0
    cur = xmlSecGetNextElementNode(node->children);
1381
1382
    /* first is NamedCurve node with a required URI parameter (ECParameters is not supported)*/
1383
0
    if((cur == NULL) || (!xmlSecCheckNodeName(cur, xmlSecNodeNamedCurve, xmlSecDSig11Ns))) {
1384
0
        xmlSecInvalidNodeError(cur, xmlSecNodeNamedCurve, NULL);
1385
0
        return(-1);
1386
0
    }
1387
0
    data->curve = xmlGetProp(cur, xmlSecAttrURI);
1388
0
    if(data->curve == NULL) {
1389
0
        xmlSecInvalidNodeAttributeError(cur, xmlSecAttrURI, NULL, "empty");
1390
0
        return(-1);
1391
0
    }
1392
    /* remove the oid prefix if needed */
1393
0
    if((xmlStrncmp(data->curve, XMLSEC_KEYVALUE_EC_OID_PREFIX, xmlStrlen(XMLSEC_KEYVALUE_EC_OID_PREFIX)) == 0)) {
1394
0
        xmlChar * curve = xmlStrdup(data->curve + xmlStrlen(XMLSEC_KEYVALUE_EC_OID_PREFIX));
1395
0
        if(curve == NULL) {
1396
0
            xmlSecStrdupError(data->curve, NULL);
1397
0
            return(-1);
1398
0
        }
1399
0
        xmlFree(data->curve);
1400
0
        data->curve = curve;
1401
0
    }
1402
0
    cur = xmlSecGetNextElementNode(cur->next);
1403
1404
    /* second node is PublicKey node: read the "combined" public key only since many
1405
     * crypto libraries don't need a split into (x, y) pair */
1406
0
    if((cur == NULL) || (!xmlSecCheckNodeName(cur, xmlSecNodePublicKey, xmlSecDSig11Ns))) {
1407
0
        xmlSecInvalidNodeError(cur, xmlSecNodePublicKey, NULL);
1408
0
        return(-1);
1409
0
    }
1410
0
    ret = xmlSecBufferBase64NodeContentRead(&(data->pubkey), node);
1411
0
    if(ret < 0) {
1412
0
        xmlSecInternalError("xmlSecBufferBase64NodeContentRead(pubkey)", NULL);
1413
0
        return(-1);
1414
0
    }
1415
0
    cur = xmlSecGetNextElementNode(cur->next);
1416
1417
    /* we are done, any other node is not expected */
1418
0
    if(cur != NULL) {
1419
0
        xmlSecUnexpectedNodeError(cur, NULL);
1420
0
        return(-1);
1421
0
    }
1422
1423
    /* success */
1424
0
    return(0);
1425
0
}
1426
1427
static int
1428
0
xmlSecKeyValueEcXmlWrite(xmlSecKeyValueEcPtr data, xmlNodePtr node,  int base64LineSize, int addLineBreaks) {
1429
0
    xmlNodePtr cur;
1430
0
    int ret;
1431
1432
0
    xmlSecAssert2(data != NULL, -1);
1433
0
    xmlSecAssert2(data->curve != NULL, -1);
1434
0
    xmlSecAssert2(node != NULL, -1);
1435
1436
    /* first is NamedCurve node */
1437
0
    cur = xmlSecAddChild(node, xmlSecNodeNamedCurve, xmlSecDSig11Ns);
1438
0
    if(cur == NULL) {
1439
0
        xmlSecInternalError("xmlSecAddChild(NamedCurve)", NULL);
1440
0
        return(-1);
1441
0
    }
1442
    /* add the oid prefix if needed */
1443
0
    if((xmlStrncmp(data->curve, XMLSEC_KEYVALUE_EC_OID_PREFIX, xmlStrlen(XMLSEC_KEYVALUE_EC_OID_PREFIX)) != 0)) {
1444
0
        xmlSecSize size;
1445
0
        xmlChar * curve;
1446
0
        int len;
1447
1448
0
        len = xmlStrlen(XMLSEC_KEYVALUE_EC_OID_PREFIX) + xmlStrlen(data->curve) + 1;
1449
0
        XMLSEC_SAFE_CAST_INT_TO_SIZE(len, size, return(-1), NULL);
1450
1451
0
        curve = (xmlChar *)xmlMalloc(size);
1452
0
        if(curve == NULL) {
1453
0
            xmlSecMallocError(size, NULL);
1454
0
            return(-1);
1455
0
        }
1456
1457
0
        ret = xmlStrPrintf(curve, len, "%s%s", XMLSEC_KEYVALUE_EC_OID_PREFIX, data->curve);
1458
0
        if(ret < 0) {
1459
0
            xmlSecXmlError("xmlStrPrintf", NULL);
1460
0
            xmlFree(curve);
1461
0
            return(-1);
1462
0
        }
1463
0
        xmlSetProp(cur, xmlSecAttrURI, curve);
1464
0
        xmlFree(curve);
1465
0
    } else {
1466
0
        xmlSetProp(cur, xmlSecAttrURI, data->curve);
1467
0
    }
1468
1469
    /* second node is PublicKey node */
1470
0
    cur = xmlSecAddChild(node, xmlSecNodePublicKey, xmlSecDSig11Ns);
1471
0
    if(cur == NULL) {
1472
0
        xmlSecInternalError("xmlSecAddChild(PublicKey)", NULL);
1473
0
        return(-1);
1474
0
    }
1475
0
    if(addLineBreaks) {
1476
0
        xmlNodeSetContent(cur, xmlSecGetDefaultLineFeed());
1477
0
    } else {
1478
0
        xmlNodeSetContent(cur, xmlSecStringEmpty);
1479
0
    }
1480
1481
0
    ret = xmlSecBufferBase64NodeContentWrite(&(data->pubkey), cur, base64LineSize);
1482
0
    if(ret < 0) {
1483
0
        xmlSecInternalError("xmlSecBufferBase64NodeContentWrite(q)", NULL);
1484
0
        return(-1);
1485
0
    }
1486
0
    if(addLineBreaks) {
1487
0
        xmlNodeAddContent(cur, xmlSecGetDefaultLineFeed());
1488
0
    }
1489
1490
    /* done */
1491
0
    return(0);
1492
0
}
1493
#endif /* !defined(XMLSEC_NO_EC) */
1494
1495
#if !defined(XMLSEC_NO_DH)
1496
/**************************************************************************
1497
 *
1498
 * Helper functions to read/write DH keys
1499
 *
1500
 *  <element name="DHKeyValue" type="xenc:DHKeyValueType"/>
1501
 *  <complexType name="DHKeyValueType">
1502
 *      <sequence>
1503
 *          <sequence minOccurs="0">
1504
 *              <element name="P" type="ds:CryptoBinary"/>
1505
 *              <element name="Q" type="ds:CryptoBinary"/>
1506
 *              <element name="Generator"type="ds:CryptoBinary"/>
1507
 *          </sequence>
1508
 *          <element name="Public" type="ds:CryptoBinary"/>
1509
 *          <sequence minOccurs="0">
1510
 *              <element name="seed" type="ds:CryptoBinary"/>
1511
 *              <element name="pgenCounter" type="ds:CryptoBinary"/>
1512
 *          </sequence>
1513
 *      </sequence>
1514
 *  </complexType>
1515
 *
1516
 *************************************************************************/
1517
0
#define XMLSEC_KEY_DATA_DH_INIT_BUF_SIZE                               512
1518
1519
static int                      xmlSecKeyValueDhInitialize             (xmlSecKeyValueDhPtr data);
1520
static void                     xmlSecKeyValueDhFinalize               (xmlSecKeyValueDhPtr data);
1521
static int                      xmlSecKeyValueDhXmlRead                (xmlSecKeyValueDhPtr data,
1522
                                                                        xmlNodePtr node);
1523
static int                      xmlSecKeyValueDhXmlWrite               (xmlSecKeyValueDhPtr data,
1524
                                                                        xmlNodePtr node,
1525
                                                                        int base64LineSize,
1526
                                                                        int addLineBreaks);
1527
1528
/**
1529
 * xmlSecKeyDataDhXmlRead:
1530
 * @id:                 the data id.
1531
 * @key:                the key.
1532
 * @node:               the pointer to data's value XML node.
1533
 * @keyInfoCtx:         the &lt;dsig:KeyInfo/&gt; node processing context.
1534
 * @readFunc:           the pointer to the function that converts
1535
 *                      @xmlSecKeyValueDh to @xmlSecKeyData.
1536
 *
1537
 * DH Key data method for reading XML node.
1538
 *
1539
 * Returns: 0 on success or a negative value if an error occurs.
1540
 */
1541
int
1542
xmlSecKeyDataDhXmlRead(xmlSecKeyDataId id, xmlSecKeyPtr key,
1543
                        xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx,
1544
                        xmlSecKeyDataDhRead readFunc
1545
0
) {
1546
0
    xmlSecKeyDataPtr data = NULL;
1547
0
    xmlSecKeyValueDh dhValue;
1548
0
    int dhDataInitialized = 0;
1549
0
    int res = -1;
1550
0
    int ret;
1551
1552
0
    xmlSecAssert2(id != NULL, -1);
1553
0
    xmlSecAssert2(key != NULL, -1);
1554
0
    xmlSecAssert2(node != NULL, -1);
1555
0
    xmlSecAssert2(keyInfoCtx != NULL, -1);
1556
0
    xmlSecAssert2(readFunc != NULL, -1);
1557
1558
0
    if(xmlSecKeyGetValue(key) != NULL) {
1559
0
        xmlSecOtherError(XMLSEC_ERRORS_R_INVALID_KEY_DATA,
1560
0
            xmlSecKeyDataKlassGetName(id), "key already has a value");
1561
0
        goto done;
1562
0
    }
1563
1564
0
    ret = xmlSecKeyValueDhInitialize(&dhValue);
1565
0
    if(ret < 0) {
1566
0
        xmlSecInternalError("xmlSecKeyValueDhInitialize",
1567
0
            xmlSecKeyDataKlassGetName(id));
1568
0
        goto done;
1569
0
    }
1570
0
    dhDataInitialized = 1;
1571
1572
0
    ret = xmlSecKeyValueDhXmlRead(&dhValue, node);
1573
0
    if(ret < 0) {
1574
0
        xmlSecInternalError("xmlSecKeyValueDhXmlRead",
1575
0
            xmlSecKeyDataKlassGetName(id));
1576
0
        goto done;
1577
0
    }
1578
1579
0
    data = readFunc(id, &dhValue);
1580
0
    if(data == NULL) {
1581
0
        xmlSecInternalError("xmlSecKeyDataDhRead",
1582
0
            xmlSecKeyDataKlassGetName(id));
1583
0
        goto done;
1584
0
    }
1585
1586
    /* set key value */
1587
0
    ret = xmlSecKeySetValue(key, data);
1588
0
    if(ret < 0) {
1589
0
        xmlSecInternalError("xmlSecKeySetValue",
1590
0
                            xmlSecKeyDataGetName(data));
1591
0
        goto done;
1592
0
    }
1593
0
    data = NULL; /* data is owned by key now */
1594
1595
    /* success */
1596
0
    res = 0;
1597
1598
0
done:
1599
    /* cleanup */
1600
0
    if(dhDataInitialized != 0) {
1601
0
        xmlSecKeyValueDhFinalize(&dhValue);
1602
0
    }
1603
0
    if(data != NULL) {
1604
0
        xmlSecKeyDataDestroy(data);
1605
0
    }
1606
0
    return(res);
1607
0
}
1608
1609
/**
1610
 * xmlSecKeyDataDhXmlWrite:
1611
 * @id:                 the data id.
1612
 * @key:                the key.
1613
 * @node:               the pointer to data's value XML node.
1614
 * @keyInfoCtx:         the &lt;dsig:KeyInfo/&gt; node processing context.
1615
 * @base64LineSize:     the base64 max line size.
1616
 * @addLineBreaks:      the flag indicating if we need to add line breaks around base64 output.
1617
 * @writeFunc:          the pointer to the function that converts
1618
 *                      @xmlSecKeyData to  @xmlSecKeyValueDh.
1619
 *
1620
 * DH Key data  method for writing XML node.
1621
 *
1622
 * Returns: 0 on success or a negative value if an error occurs.
1623
 */
1624
int
1625
xmlSecKeyDataDhXmlWrite(xmlSecKeyDataId id, xmlSecKeyPtr key,
1626
                        xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx,
1627
                        int base64LineSize, int addLineBreaks,
1628
                        xmlSecKeyDataDhWrite writeFunc
1629
0
) {
1630
0
    xmlSecKeyDataPtr data;
1631
0
    xmlSecKeyValueDh dhValue;
1632
0
    int dhDataInitialized = 0;
1633
0
    int res = -1;
1634
0
    int ret;
1635
1636
0
    xmlSecAssert2(id != NULL, -1);
1637
0
    xmlSecAssert2(key != NULL, -1);
1638
0
    xmlSecAssert2(node != NULL, -1);
1639
0
    xmlSecAssert2(keyInfoCtx != NULL, -1);
1640
0
    xmlSecAssert2(writeFunc != NULL, -1);
1641
0
    xmlSecAssert2(base64LineSize > 0, -1);
1642
1643
0
    if(((xmlSecKeyDataTypePublic | xmlSecKeyDataTypePrivate) & keyInfoCtx->keyReq.keyType) == 0) {
1644
        /* we can have only private key or public key */
1645
0
        return(0);
1646
0
    }
1647
1648
0
    data = xmlSecKeyGetValue(key);
1649
0
    if(data == NULL) {
1650
0
        xmlSecOtherError(XMLSEC_ERRORS_R_INVALID_KEY_DATA,
1651
0
            xmlSecKeyDataKlassGetName(id), "key has no value");
1652
0
        goto done;
1653
0
    }
1654
1655
0
    ret = xmlSecKeyValueDhInitialize(&dhValue);
1656
0
    if(ret < 0) {
1657
0
        xmlSecInternalError("xmlSecKeyValueDhInitialize",
1658
0
            xmlSecKeyDataKlassGetName(id));
1659
0
        goto done;
1660
0
    }
1661
0
    dhDataInitialized = 1;
1662
1663
0
    ret = writeFunc(id, data, &dhValue, 0 /* writePrivateKey is not supported */);
1664
0
    if(ret < 0) {
1665
0
        xmlSecInternalError("xmlSecKeyDataDhWrite",
1666
0
            xmlSecKeyDataKlassGetName(id));
1667
0
        goto done;
1668
0
    }
1669
1670
0
    ret = xmlSecKeyValueDhXmlWrite(&dhValue, node, base64LineSize, addLineBreaks);
1671
0
    if(ret < 0) {
1672
0
        xmlSecInternalError("xmlSecKeyValueDhXmlWrite",
1673
0
            xmlSecKeyDataKlassGetName(id));
1674
0
        goto done;
1675
0
    }
1676
1677
    /* success */
1678
0
    res = 0;
1679
1680
0
done:
1681
    /* cleanup */
1682
0
    if(dhDataInitialized != 0) {
1683
0
        xmlSecKeyValueDhFinalize(&dhValue);
1684
0
    }
1685
0
    return(res);
1686
0
}
1687
1688
static int
1689
0
xmlSecKeyValueDhInitialize(xmlSecKeyValueDhPtr data) {
1690
0
    int ret;
1691
1692
0
    xmlSecAssert2(data != NULL, -1);
1693
0
    memset(data, 0, sizeof(xmlSecKeyValueDh));
1694
1695
0
    ret = xmlSecBufferInitialize(&(data->p), XMLSEC_KEY_DATA_DH_INIT_BUF_SIZE);
1696
0
    if(ret < 0) {
1697
0
        xmlSecInternalError("xmlSecBufferInitialize(p)", NULL);
1698
0
        xmlSecKeyValueDhFinalize(data);
1699
0
        return(-1);
1700
0
    }
1701
0
    ret = xmlSecBufferInitialize(&(data->q), XMLSEC_KEY_DATA_DH_INIT_BUF_SIZE);
1702
0
    if(ret < 0) {
1703
0
        xmlSecInternalError("xmlSecBufferInitialize(q)", NULL);
1704
0
        xmlSecKeyValueDhFinalize(data);
1705
0
        return(-1);
1706
0
    }
1707
0
    ret = xmlSecBufferInitialize(&(data->generator), XMLSEC_KEY_DATA_DH_INIT_BUF_SIZE);
1708
0
    if(ret < 0) {
1709
0
        xmlSecInternalError("xmlSecBufferInitialize(generator)", NULL);
1710
0
        xmlSecKeyValueDhFinalize(data);
1711
0
        return(-1);
1712
0
    }
1713
0
    ret = xmlSecBufferInitialize(&(data->public), XMLSEC_KEY_DATA_DH_INIT_BUF_SIZE);
1714
0
    if(ret < 0) {
1715
0
        xmlSecInternalError("xmlSecBufferInitialize(public)", NULL);
1716
0
        xmlSecKeyValueDhFinalize(data);
1717
0
        return(-1);
1718
0
    }
1719
0
    ret = xmlSecBufferInitialize(&(data->seed), XMLSEC_KEY_DATA_DH_INIT_BUF_SIZE);
1720
0
    if(ret < 0) {
1721
0
        xmlSecInternalError("xmlSecBufferInitialize(seed)", NULL);
1722
0
        xmlSecKeyValueDhFinalize(data);
1723
0
        return(-1);
1724
0
    }
1725
0
    ret = xmlSecBufferInitialize(&(data->pgenCounter), XMLSEC_KEY_DATA_DH_INIT_BUF_SIZE);
1726
0
    if(ret < 0) {
1727
0
        xmlSecInternalError("xmlSecBufferInitialize(pgenCounter)", NULL);
1728
0
        xmlSecKeyValueDhFinalize(data);
1729
0
        return(-1);
1730
0
    }
1731
1732
0
    return(0);
1733
0
}
1734
1735
static void
1736
0
xmlSecKeyValueDhFinalize(xmlSecKeyValueDhPtr data) {
1737
0
    xmlSecAssert(data != NULL);
1738
1739
0
    xmlSecBufferFinalize(&(data->p));
1740
0
    xmlSecBufferFinalize(&(data->q));
1741
0
    xmlSecBufferFinalize(&(data->generator));
1742
0
    xmlSecBufferFinalize(&(data->public));
1743
0
    xmlSecBufferFinalize(&(data->seed));
1744
0
    xmlSecBufferFinalize(&(data->pgenCounter));
1745
0
    memset(data, 0, sizeof(xmlSecKeyValueDh));
1746
0
}
1747
1748
static int
1749
0
xmlSecKeyValueDhXmlRead(xmlSecKeyValueDhPtr data, xmlNodePtr node) {
1750
0
    xmlNodePtr cur;
1751
0
    int ret;
1752
1753
0
    xmlSecAssert2(data != NULL, -1);
1754
0
    xmlSecAssert2(node != NULL, -1);
1755
1756
0
    cur = xmlSecGetNextElementNode(node->children);
1757
1758
    /* first is P node. It is OPTIONAL */
1759
0
    if((cur != NULL) && (xmlSecCheckNodeName(cur,  xmlSecNodeDHP, xmlSecEncNs))) {
1760
0
        ret = xmlSecBufferBase64NodeContentRead(&(data->p), cur);
1761
0
        if(ret < 0) {
1762
0
            xmlSecInternalError("xmlSecBufferBase64NodeContentRead(p)", NULL);
1763
0
            return(-1);
1764
0
        }
1765
0
        cur = xmlSecGetNextElementNode(cur->next);
1766
0
    }
1767
    /* next is Q node. It is OPTIONAL */
1768
0
    if((cur != NULL) && (xmlSecCheckNodeName(cur,  xmlSecNodeDHQ, xmlSecEncNs))) {
1769
0
        ret = xmlSecBufferBase64NodeContentRead(&(data->q), cur);
1770
0
        if(ret < 0) {
1771
0
            xmlSecInternalError("xmlSecBufferBase64NodeContentRead(q)", NULL);
1772
0
            return(-1);
1773
0
        }
1774
0
        cur = xmlSecGetNextElementNode(cur->next);
1775
0
    }
1776
    /* next is Generator node. It is OPTIONAL */
1777
0
    if((cur != NULL) && (xmlSecCheckNodeName(cur,  xmlSecNodeDHGenerator, xmlSecEncNs))) {
1778
0
        ret = xmlSecBufferBase64NodeContentRead(&(data->generator), cur);
1779
0
        if(ret < 0) {
1780
0
            xmlSecInternalError("xmlSecBufferBase64NodeContentRead(generator)", NULL);
1781
0
            return(-1);
1782
0
        }
1783
0
        cur = xmlSecGetNextElementNode(cur->next);
1784
0
    }
1785
1786
    /* next is Public node. It is REQUIRED */
1787
0
    if((cur == NULL) || (!xmlSecCheckNodeName(cur, xmlSecNodeDHPublic, xmlSecEncNs))) {
1788
0
        xmlSecInvalidNodeError(cur, xmlSecNodeDHPublic, NULL);
1789
0
        return(-1);
1790
0
    }
1791
0
    ret = xmlSecBufferBase64NodeContentRead(&(data->public), cur);
1792
0
    if(ret < 0) {
1793
0
        xmlSecInternalError("xmlSecBufferBase64NodeContentRead(public)", NULL);
1794
0
        return(-1);
1795
0
    }
1796
0
    cur = xmlSecGetNextElementNode(cur->next);
1797
1798
    /* next is seed node. It is OPTIONAL */
1799
0
    if((cur != NULL) && (xmlSecCheckNodeName(cur,  xmlSecNodeDHSeed, xmlSecEncNs))) {
1800
0
        ret = xmlSecBufferBase64NodeContentRead(&(data->seed), cur);
1801
0
        if(ret < 0) {
1802
0
            xmlSecInternalError("xmlSecBufferBase64NodeContentRead(seed)", NULL);
1803
0
            return(-1);
1804
0
        }
1805
0
        cur = xmlSecGetNextElementNode(cur->next);
1806
0
    }
1807
1808
    /* next is pgenCounter node. It is OPTIONAL */
1809
0
    if((cur != NULL) && (xmlSecCheckNodeName(cur,  xmlSecNodeDHPgenCounter, xmlSecEncNs))) {
1810
0
        ret = xmlSecBufferBase64NodeContentRead(&(data->pgenCounter), cur);
1811
0
        if(ret < 0) {
1812
0
            xmlSecInternalError("xmlSecBufferBase64NodeContentRead(pgenCounter)", NULL);
1813
0
            return(-1);
1814
0
        }
1815
0
        cur = xmlSecGetNextElementNode(cur->next);
1816
0
    }
1817
1818
    /* nothing else is expected */
1819
0
    if(cur != NULL) {
1820
0
        xmlSecUnexpectedNodeError(cur, NULL);
1821
0
        return(-1);
1822
0
    }
1823
1824
    /* success */
1825
0
    return(0);
1826
0
}
1827
1828
static int
1829
0
xmlSecKeyValueDhXmlWrite(xmlSecKeyValueDhPtr data, xmlNodePtr node, int base64LineSize, int addLineBreaks) {
1830
0
    xmlNodePtr cur;
1831
0
    int ret;
1832
1833
0
    xmlSecAssert2(data != NULL, -1);
1834
0
    xmlSecAssert2(node != NULL, -1);
1835
1836
    /* first is optional P node */
1837
0
    if(xmlSecBufferGetSize(&(data->p)) > 0) {
1838
0
        cur = xmlSecAddChild(node, xmlSecNodeDHP, xmlSecEncNs);
1839
0
        if(cur == NULL) {
1840
0
            xmlSecInternalError("xmlSecAddChild(NodeDHP)", NULL);
1841
0
            return(-1);
1842
0
        }
1843
0
        if(addLineBreaks) {
1844
0
            xmlNodeSetContent(cur, xmlSecGetDefaultLineFeed());
1845
0
        } else {
1846
0
            xmlNodeSetContent(cur, xmlSecStringEmpty);
1847
0
        }
1848
0
        ret = xmlSecBufferBase64NodeContentWrite(&(data->p), cur, base64LineSize);
1849
0
        if(ret < 0) {
1850
0
            xmlSecInternalError("xmlSecBufferBase64NodeContentWrite(p)", NULL);
1851
0
            return(-1);
1852
0
        }
1853
0
        if(addLineBreaks) {
1854
0
            xmlNodeAddContent(cur, xmlSecGetDefaultLineFeed());
1855
0
        }
1856
0
    }
1857
1858
    /* next is optional Q node. */
1859
0
    if(xmlSecBufferGetSize(&(data->q)) > 0) {
1860
0
        cur = xmlSecAddChild(node, xmlSecNodeDHQ, xmlSecEncNs);
1861
0
        if(cur == NULL) {
1862
0
            xmlSecInternalError("xmlSecAddChild(NodeDHQ)", NULL);
1863
0
            return(-1);
1864
0
        }
1865
0
        if(addLineBreaks) {
1866
0
            xmlNodeSetContent(cur, xmlSecGetDefaultLineFeed());
1867
0
        } else {
1868
0
            xmlNodeSetContent(cur, xmlSecStringEmpty);
1869
0
        }
1870
0
        ret = xmlSecBufferBase64NodeContentWrite(&(data->q), cur, base64LineSize);
1871
0
        if(ret < 0) {
1872
0
            xmlSecInternalError("xmlSecBufferBase64NodeContentWrite(q)", NULL);
1873
0
            return(-1);
1874
0
        }
1875
0
        if(addLineBreaks) {
1876
0
            xmlNodeAddContent(cur, xmlSecGetDefaultLineFeed());
1877
0
        }
1878
0
    }
1879
1880
    /* next is optional Generator node. */
1881
0
    if(xmlSecBufferGetSize(&(data->generator)) > 0) {
1882
0
        cur = xmlSecAddChild(node, xmlSecNodeDHGenerator, xmlSecEncNs);
1883
0
        if(cur == NULL) {
1884
0
            xmlSecInternalError("xmlSecAddChild(NodeDHGenerator)", NULL);
1885
0
            return(-1);
1886
0
        }
1887
0
        if(addLineBreaks) {
1888
0
            xmlNodeSetContent(cur, xmlSecGetDefaultLineFeed());
1889
0
        } else {
1890
0
            xmlNodeSetContent(cur, xmlSecStringEmpty);
1891
0
        }
1892
0
        ret = xmlSecBufferBase64NodeContentWrite(&(data->generator), cur, base64LineSize);
1893
0
        if(ret < 0) {
1894
0
            xmlSecInternalError("xmlSecBufferBase64NodeContentWrite(g)", NULL);
1895
0
            return(-1);
1896
0
        }
1897
0
        if(addLineBreaks) {
1898
0
            xmlNodeAddContent(cur, xmlSecGetDefaultLineFeed());
1899
0
        }
1900
0
    }
1901
1902
    /* next is required Public node. */
1903
0
    cur = xmlSecAddChild(node, xmlSecNodeDHPublic, xmlSecEncNs);
1904
0
    if(cur == NULL) {
1905
0
        xmlSecInternalError("xmlSecAddChild(xmlSecNodeDHPublic)", NULL);
1906
0
        return(-1);
1907
0
    }
1908
0
    if(addLineBreaks) {
1909
0
        xmlNodeSetContent(cur, xmlSecGetDefaultLineFeed());
1910
0
    } else {
1911
0
        xmlNodeSetContent(cur, xmlSecStringEmpty);
1912
0
    }
1913
0
    ret = xmlSecBufferBase64NodeContentWrite(&(data->public), cur, base64LineSize);
1914
0
    if(ret < 0) {
1915
0
        xmlSecInternalError("xmlSecBufferBase64NodeContentWrite(g)", NULL);
1916
0
        return(-1);
1917
0
    }
1918
0
    if(addLineBreaks) {
1919
0
        xmlNodeAddContent(cur, xmlSecGetDefaultLineFeed());
1920
0
    }
1921
1922
    /* next is optional seed node. */
1923
0
    if(xmlSecBufferGetSize(&(data->seed)) > 0) {
1924
0
        cur = xmlSecAddChild(node, xmlSecNodeDHSeed, xmlSecEncNs);
1925
0
        if(cur == NULL) {
1926
0
            xmlSecInternalError("xmlSecAddChild(xmlSecNodeDHSeed)", NULL);
1927
0
            return(-1);
1928
0
        }
1929
0
        if(addLineBreaks) {
1930
0
            xmlNodeSetContent(cur, xmlSecGetDefaultLineFeed());
1931
0
        } else {
1932
0
            xmlNodeSetContent(cur, xmlSecStringEmpty);
1933
0
        }
1934
0
        ret = xmlSecBufferBase64NodeContentWrite(&(data->seed), cur, base64LineSize);
1935
0
        if(ret < 0) {
1936
0
            xmlSecInternalError("xmlSecBufferBase64NodeContentWrite(g)", NULL);
1937
0
            return(-1);
1938
0
        }
1939
0
        if(addLineBreaks) {
1940
0
            xmlNodeAddContent(cur, xmlSecGetDefaultLineFeed());
1941
0
        }
1942
0
    }
1943
1944
    /* next is optional pgenCounter node. */
1945
0
    if(xmlSecBufferGetSize(&(data->pgenCounter)) > 0) {
1946
0
        cur = xmlSecAddChild(node, xmlSecNodeDHPgenCounter, xmlSecEncNs);
1947
0
        if(cur == NULL) {
1948
0
            xmlSecInternalError("xmlSecAddChild(xmlSecNodeDHPgenCounter)", NULL);
1949
0
            return(-1);
1950
0
        }
1951
0
        if(addLineBreaks) {
1952
0
            xmlNodeSetContent(cur, xmlSecGetDefaultLineFeed());
1953
0
        } else {
1954
0
            xmlNodeSetContent(cur, xmlSecStringEmpty);
1955
0
        }
1956
0
        ret = xmlSecBufferBase64NodeContentWrite(&(data->pgenCounter), cur, base64LineSize);
1957
0
        if(ret < 0) {
1958
0
            xmlSecInternalError("xmlSecBufferBase64NodeContentWrite(g)", NULL);
1959
0
            return(-1);
1960
0
        }
1961
0
        if(addLineBreaks) {
1962
0
            xmlNodeAddContent(cur, xmlSecGetDefaultLineFeed());
1963
0
        }
1964
0
    }
1965
1966
    /* success */
1967
0
    return(0);
1968
0
}
1969
#endif /* !defined(XMLSEC_NO_DH) */
1970
1971
1972
#if !defined(XMLSEC_NO_DSA)
1973
/**************************************************************************
1974
 *
1975
 * Helper functions to read/write DSA keys
1976
 *
1977
 *************************************************************************/
1978
0
#define XMLSEC_KEY_DATA_DSA_INIT_BUF_SIZE                               512
1979
1980
static int                      xmlSecKeyValueDsaInitialize             (xmlSecKeyValueDsaPtr data);
1981
static void                     xmlSecKeyValueDsaFinalize               (xmlSecKeyValueDsaPtr data);
1982
static int                      xmlSecKeyValueDsaXmlRead                (xmlSecKeyValueDsaPtr data,
1983
                                                                         xmlNodePtr node);
1984
static int                      xmlSecKeyValueDsaXmlWrite               (xmlSecKeyValueDsaPtr data,
1985
                                                                         xmlNodePtr node,
1986
                                                                         int writePrivateKey,
1987
                                                                         int base64LineSize,
1988
                                                                         int addLineBreaks);
1989
1990
/**
1991
 * xmlSecKeyDataDsaXmlRead:
1992
 * @id:                 the data id.
1993
 * @key:                the key.
1994
 * @node:               the pointer to data's value XML node.
1995
 * @keyInfoCtx:         the &lt;dsig:KeyInfo/&gt; node processing context.
1996
 * @readFunc:           the pointer to the function that converts
1997
 *                      @xmlSecKeyValueDsa to @xmlSecKeyData.
1998
 *
1999
 * DSA Key data method for reading XML node.
2000
 *
2001
 * Returns: 0 on success or a negative value if an error occurs.
2002
 */
2003
int
2004
xmlSecKeyDataDsaXmlRead(xmlSecKeyDataId id, xmlSecKeyPtr key,
2005
                        xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx,
2006
0
                        xmlSecKeyDataDsaRead readFunc) {
2007
0
    xmlSecKeyDataPtr data = NULL;
2008
0
    xmlSecKeyValueDsa dsaValue;
2009
0
    int dsaDataInitialized = 0;
2010
0
    int res = -1;
2011
0
    int ret;
2012
2013
0
    xmlSecAssert2(id != NULL, -1);
2014
0
    xmlSecAssert2(key != NULL, -1);
2015
0
    xmlSecAssert2(node != NULL, -1);
2016
0
    xmlSecAssert2(keyInfoCtx != NULL, -1);
2017
0
    xmlSecAssert2(readFunc != NULL, -1);
2018
2019
0
    if(xmlSecKeyGetValue(key) != NULL) {
2020
0
        xmlSecOtherError(XMLSEC_ERRORS_R_INVALID_KEY_DATA,
2021
0
            xmlSecKeyDataKlassGetName(id), "key already has a value");
2022
0
        goto done;
2023
0
    }
2024
2025
0
    ret = xmlSecKeyValueDsaInitialize(&dsaValue);
2026
0
    if(ret < 0) {
2027
0
        xmlSecInternalError("xmlSecKeyValueDsaInitialize",
2028
0
            xmlSecKeyDataKlassGetName(id));
2029
0
        goto done;
2030
0
    }
2031
0
    dsaDataInitialized = 1;
2032
2033
0
    ret = xmlSecKeyValueDsaXmlRead(&dsaValue, node);
2034
0
    if(ret < 0) {
2035
0
        xmlSecInternalError("xmlSecKeyValueDsaXmlRead",
2036
0
            xmlSecKeyDataKlassGetName(id));
2037
0
        goto done;
2038
0
    }
2039
2040
0
    data = readFunc(id, &dsaValue);
2041
0
    if(data == NULL) {
2042
0
        xmlSecInternalError("xmlSecKeyDataDsaRead",
2043
0
            xmlSecKeyDataKlassGetName(id));
2044
0
        goto done;
2045
0
    }
2046
2047
    /* set key value */
2048
0
    ret = xmlSecKeySetValue(key, data);
2049
0
    if(ret < 0) {
2050
0
        xmlSecInternalError("xmlSecKeySetValue",
2051
0
                            xmlSecKeyDataGetName(data));
2052
0
        goto done;
2053
0
    }
2054
0
    data = NULL; /* data is owned by key now */
2055
2056
    /* success */
2057
0
    res = 0;
2058
2059
0
done:
2060
    /* cleanup */
2061
0
    if(dsaDataInitialized != 0) {
2062
0
        xmlSecKeyValueDsaFinalize(&dsaValue);
2063
0
    }
2064
0
    if(data != NULL) {
2065
0
        xmlSecKeyDataDestroy(data);
2066
0
    }
2067
0
    return(res);
2068
0
}
2069
2070
/**
2071
 * xmlSecKeyDataDsaXmlWrite:
2072
 * @id:                 the data id.
2073
 * @key:                the key.
2074
 * @node:               the pointer to data's value XML node.
2075
 * @keyInfoCtx:         the &lt;dsig:KeyInfo/&gt; node processing context.
2076
 * @base64LineSize:     the base64 max line size.
2077
 * @addLineBreaks:      the flag indicating if we need to add line breaks around base64 output.
2078
 * @writeFunc:          the pointer to the function that converts
2079
 *                      @xmlSecKeyData to  @xmlSecKeyValueDsa.
2080
 *
2081
 * DSA Key data  method for writing XML node.
2082
 *
2083
 * Returns: 0 on success or a negative value if an error occurs.
2084
 */
2085
int
2086
xmlSecKeyDataDsaXmlWrite(xmlSecKeyDataId id, xmlSecKeyPtr key,
2087
                        xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx,
2088
                        int base64LineSize, int addLineBreaks,
2089
0
                        xmlSecKeyDataDsaWrite writeFunc) {
2090
0
    xmlSecKeyDataPtr data;
2091
0
    xmlSecKeyValueDsa dsaValue;
2092
0
    int dsaDataInitialized = 0;
2093
0
    int writePrivateKey = 0;
2094
0
    int res = -1;
2095
0
    int ret;
2096
2097
0
    xmlSecAssert2(id != NULL, -1);
2098
0
    xmlSecAssert2(key != NULL, -1);
2099
0
    xmlSecAssert2(node != NULL, -1);
2100
0
    xmlSecAssert2(keyInfoCtx != NULL, -1);
2101
0
    xmlSecAssert2(writeFunc != NULL, -1);
2102
0
    xmlSecAssert2(base64LineSize > 0, -1);
2103
2104
0
    if(((xmlSecKeyDataTypePublic | xmlSecKeyDataTypePrivate) & keyInfoCtx->keyReq.keyType) == 0) {
2105
        /* we can have only private key or public key */
2106
0
        return(0);
2107
0
    }
2108
0
    if((keyInfoCtx->keyReq.keyType & xmlSecKeyDataTypePrivate) != 0) {
2109
0
        writePrivateKey = 1;
2110
0
    }
2111
2112
0
    data = xmlSecKeyGetValue(key);
2113
0
    if(data == NULL) {
2114
0
        xmlSecOtherError(XMLSEC_ERRORS_R_INVALID_KEY_DATA,
2115
0
            xmlSecKeyDataKlassGetName(id), "key has no value");
2116
0
        goto done;
2117
0
    }
2118
2119
0
    ret = xmlSecKeyValueDsaInitialize(&dsaValue);
2120
0
    if(ret < 0) {
2121
0
        xmlSecInternalError("xmlSecKeyValueDsaInitialize",
2122
0
            xmlSecKeyDataKlassGetName(id));
2123
0
        goto done;
2124
0
    }
2125
0
    dsaDataInitialized = 1;
2126
2127
0
    ret = writeFunc(id, data, &dsaValue, writePrivateKey);
2128
0
    if(ret < 0) {
2129
0
        xmlSecInternalError("xmlSecKeyDataDsaWrite",
2130
0
            xmlSecKeyDataKlassGetName(id));
2131
0
        goto done;
2132
0
    }
2133
2134
0
    ret = xmlSecKeyValueDsaXmlWrite(&dsaValue, node, writePrivateKey,
2135
0
        base64LineSize, addLineBreaks);
2136
0
    if(ret < 0) {
2137
0
        xmlSecInternalError("xmlSecKeyValueDsaXmlWrite",
2138
0
            xmlSecKeyDataKlassGetName(id));
2139
0
        goto done;
2140
0
    }
2141
2142
    /* success */
2143
0
    res = 0;
2144
2145
0
done:
2146
    /* cleanup */
2147
0
    if(dsaDataInitialized != 0) {
2148
0
        xmlSecKeyValueDsaFinalize(&dsaValue);
2149
0
    }
2150
0
    return(res);
2151
0
}
2152
2153
static int
2154
0
xmlSecKeyValueDsaInitialize(xmlSecKeyValueDsaPtr data) {
2155
0
    int ret;
2156
2157
0
    xmlSecAssert2(data != NULL, -1);
2158
0
    memset(data, 0, sizeof(xmlSecKeyValueDsa));
2159
2160
0
    ret = xmlSecBufferInitialize(&(data->p), XMLSEC_KEY_DATA_DSA_INIT_BUF_SIZE);
2161
0
    if(ret < 0) {
2162
0
        xmlSecInternalError("xmlSecBufferInitialize(p)", NULL);
2163
0
        xmlSecKeyValueDsaFinalize(data);
2164
0
        return(-1);
2165
0
    }
2166
0
    ret = xmlSecBufferInitialize(&(data->q), XMLSEC_KEY_DATA_DSA_INIT_BUF_SIZE);
2167
0
    if(ret < 0) {
2168
0
        xmlSecInternalError("xmlSecBufferInitialize(q)", NULL);
2169
0
        xmlSecKeyValueDsaFinalize(data);
2170
0
        return(-1);
2171
0
    }
2172
0
    ret = xmlSecBufferInitialize(&(data->g), XMLSEC_KEY_DATA_DSA_INIT_BUF_SIZE);
2173
0
    if(ret < 0) {
2174
0
        xmlSecInternalError("xmlSecBufferInitialize(g)", NULL);
2175
0
        xmlSecKeyValueDsaFinalize(data);
2176
0
        return(-1);
2177
0
    }
2178
0
    ret = xmlSecBufferInitialize(&(data->x), XMLSEC_KEY_DATA_DSA_INIT_BUF_SIZE);
2179
0
    if(ret < 0) {
2180
0
        xmlSecInternalError("xmlSecBufferInitialize(x)", NULL);
2181
0
        xmlSecKeyValueDsaFinalize(data);
2182
0
        return(-1);
2183
0
    }
2184
0
    ret = xmlSecBufferInitialize(&(data->y), XMLSEC_KEY_DATA_DSA_INIT_BUF_SIZE);
2185
0
    if(ret < 0) {
2186
0
        xmlSecInternalError("xmlSecBufferInitialize(y)", NULL);
2187
0
        xmlSecKeyValueDsaFinalize(data);
2188
0
        return(-1);
2189
0
    }
2190
2191
0
    return(0);
2192
0
}
2193
2194
static void
2195
0
xmlSecKeyValueDsaFinalize(xmlSecKeyValueDsaPtr data) {
2196
0
    xmlSecAssert(data != NULL);
2197
2198
0
    xmlSecBufferFinalize(&(data->p));
2199
0
    xmlSecBufferFinalize(&(data->q));
2200
0
    xmlSecBufferFinalize(&(data->g));
2201
0
    xmlSecBufferFinalize(&(data->x));
2202
0
    xmlSecBufferFinalize(&(data->y));
2203
0
    memset(data, 0, sizeof(xmlSecKeyValueDsa));
2204
0
}
2205
2206
static int
2207
0
xmlSecKeyValueDsaXmlRead(xmlSecKeyValueDsaPtr data, xmlNodePtr node) {
2208
0
    xmlNodePtr cur;
2209
0
    int ret;
2210
2211
0
    xmlSecAssert2(data != NULL, -1);
2212
0
    xmlSecAssert2(node != NULL, -1);
2213
2214
0
    cur = xmlSecGetNextElementNode(node->children);
2215
2216
    /* first is P node. It is REQUIRED because we do not support Seed and PgenCounter*/
2217
0
    if((cur == NULL) || (!xmlSecCheckNodeName(cur,  xmlSecNodeDSAP, xmlSecDSigNs))) {
2218
0
        xmlSecInvalidNodeError(cur, xmlSecNodeDSAP, NULL);
2219
0
        return(-1);
2220
0
    }
2221
0
    ret = xmlSecBufferBase64NodeContentRead(&(data->p), cur);
2222
0
    if(ret < 0) {
2223
0
        xmlSecInternalError("xmlSecBufferBase64NodeContentRead(p)", NULL);
2224
0
        return(-1);
2225
0
    }
2226
0
    cur = xmlSecGetNextElementNode(cur->next);
2227
2228
    /* next is Q node. It is REQUIRED because we do not support Seed and PgenCounter*/
2229
0
    if((cur == NULL) || (!xmlSecCheckNodeName(cur, xmlSecNodeDSAQ, xmlSecDSigNs))) {
2230
0
        xmlSecInvalidNodeError(cur, xmlSecNodeDSAQ, NULL);
2231
0
        return(-1);
2232
0
    }
2233
0
    ret = xmlSecBufferBase64NodeContentRead(&(data->q), cur);
2234
0
    if(ret < 0) {
2235
0
        xmlSecInternalError("xmlSecBufferBase64NodeContentRead(q)", NULL);
2236
0
        return(-1);
2237
0
    }
2238
0
    cur = xmlSecGetNextElementNode(cur->next);
2239
2240
    /* next is G node. It is REQUIRED because we do not support Seed and PgenCounter*/
2241
0
    if((cur == NULL) || (!xmlSecCheckNodeName(cur, xmlSecNodeDSAG, xmlSecDSigNs))) {
2242
0
        xmlSecInvalidNodeError(cur, xmlSecNodeDSAG, NULL);
2243
0
        return(-1);
2244
0
    }
2245
0
    ret = xmlSecBufferBase64NodeContentRead(&(data->g), cur);
2246
0
    if(ret < 0) {
2247
0
        xmlSecInternalError("xmlSecBufferBase64NodeContentRead(g)", NULL);
2248
0
        return(-1);
2249
0
    }
2250
0
    cur = xmlSecGetNextElementNode(cur->next);
2251
2252
0
    if((cur != NULL) && (xmlSecCheckNodeName(cur, xmlSecNodeDSAX, xmlSecNs))) {
2253
        /* next is X node. It is REQUIRED for private key but
2254
         * we are not sure exactly what do we read */
2255
0
        ret = xmlSecBufferBase64NodeContentRead(&(data->x), cur);
2256
0
        if(ret < 0) {
2257
0
            xmlSecInternalError("xmlSecBufferBase64NodeContentRead(x)", NULL);
2258
0
            return(-1);
2259
0
        }
2260
0
        cur = xmlSecGetNextElementNode(cur->next);
2261
0
    } else {
2262
        /* make sure it's empty */
2263
0
        ret = xmlSecBufferSetSize(&(data->x), 0);
2264
0
        if(ret < 0) {
2265
0
            xmlSecInternalError("xmlSecBufferSetSize(0)", NULL);
2266
0
            return(-1);
2267
0
        }
2268
0
    }
2269
2270
    /* next is Y node. */
2271
0
    if((cur == NULL) || (!xmlSecCheckNodeName(cur, xmlSecNodeDSAY, xmlSecDSigNs))) {
2272
0
        xmlSecInvalidNodeError(cur, xmlSecNodeDSAY, NULL);
2273
0
        return(-1);
2274
0
    }
2275
0
    ret = xmlSecBufferBase64NodeContentRead(&(data->y), cur);
2276
0
    if(ret < 0) {
2277
0
        xmlSecInternalError("xmlSecBufferBase64NodeContentRead(y)", NULL);
2278
0
        return(-1);
2279
0
    }
2280
0
    cur = xmlSecGetNextElementNode(cur->next);
2281
2282
    /* todo: add support for J */
2283
0
    if((cur != NULL) && (xmlSecCheckNodeName(cur, xmlSecNodeDSAJ, xmlSecDSigNs))) {
2284
0
        cur = xmlSecGetNextElementNode(cur->next);
2285
0
    }
2286
2287
    /* todo: add support for seed */
2288
0
    if((cur != NULL) && (xmlSecCheckNodeName(cur, xmlSecNodeDSASeed, xmlSecDSigNs))) {
2289
0
        cur = xmlSecGetNextElementNode(cur->next);
2290
0
    }
2291
2292
    /* todo: add support for pgencounter */
2293
0
    if((cur != NULL) && (xmlSecCheckNodeName(cur, xmlSecNodeDSAPgenCounter, xmlSecDSigNs))) {
2294
0
        cur = xmlSecGetNextElementNode(cur->next);
2295
0
    }
2296
2297
0
    if(cur != NULL) {
2298
0
        xmlSecUnexpectedNodeError(cur, NULL);
2299
0
        return(-1);
2300
0
    }
2301
2302
    /* success */
2303
0
    return(0);
2304
0
}
2305
2306
static int
2307
xmlSecKeyValueDsaXmlWrite(xmlSecKeyValueDsaPtr data, xmlNodePtr node,
2308
0
                      int writePrivateKey, int base64LineSize, int addLineBreaks) {
2309
0
    xmlNodePtr cur;
2310
0
    int ret;
2311
2312
0
    xmlSecAssert2(data != NULL, -1);
2313
0
    xmlSecAssert2(node != NULL, -1);
2314
2315
    /* first is P node */
2316
0
    cur = xmlSecAddChild(node, xmlSecNodeDSAP, xmlSecDSigNs);
2317
0
    if(cur == NULL) {
2318
0
        xmlSecInternalError("xmlSecAddChild(NodeDSAP)", NULL);
2319
0
        return(-1);
2320
0
    }
2321
0
    if(addLineBreaks) {
2322
0
        xmlNodeSetContent(cur, xmlSecGetDefaultLineFeed());
2323
0
    } else {
2324
0
        xmlNodeSetContent(cur, xmlSecStringEmpty);
2325
0
    }
2326
0
    ret = xmlSecBufferBase64NodeContentWrite(&(data->p), cur, base64LineSize);
2327
0
    if(ret < 0) {
2328
0
        xmlSecInternalError("xmlSecBufferBase64NodeContentWrite(p)", NULL);
2329
0
        return(-1);
2330
0
    }
2331
0
    if(addLineBreaks) {
2332
0
        xmlNodeAddContent(cur, xmlSecGetDefaultLineFeed());
2333
0
    }
2334
2335
    /* next is Q node. */
2336
0
    cur = xmlSecAddChild(node, xmlSecNodeDSAQ, xmlSecDSigNs);
2337
0
    if(cur == NULL) {
2338
0
        xmlSecInternalError("xmlSecAddChild(NodeDSAQ)", NULL);
2339
0
        return(-1);
2340
0
    }
2341
0
    if(addLineBreaks) {
2342
0
        xmlNodeSetContent(cur, xmlSecGetDefaultLineFeed());
2343
0
    } else {
2344
0
        xmlNodeSetContent(cur, xmlSecStringEmpty);
2345
0
    }
2346
0
    ret = xmlSecBufferBase64NodeContentWrite(&(data->q), cur, base64LineSize);
2347
0
    if(ret < 0) {
2348
0
        xmlSecInternalError("xmlSecBufferBase64NodeContentWrite(q)", NULL);
2349
0
        return(-1);
2350
0
    }
2351
0
    if(addLineBreaks) {
2352
0
        xmlNodeAddContent(cur, xmlSecGetDefaultLineFeed());
2353
0
    }
2354
2355
    /* next is G node. */
2356
0
    cur = xmlSecAddChild(node, xmlSecNodeDSAG, xmlSecDSigNs);
2357
0
    if(cur == NULL) {
2358
0
        xmlSecInternalError("xmlSecAddChild(NodeDSAG)", NULL);
2359
0
        return(-1);
2360
0
    }
2361
0
    if(addLineBreaks) {
2362
0
        xmlNodeSetContent(cur, xmlSecGetDefaultLineFeed());
2363
0
    } else {
2364
0
        xmlNodeSetContent(cur, xmlSecStringEmpty);
2365
0
    }
2366
0
    ret = xmlSecBufferBase64NodeContentWrite(&(data->g), cur, base64LineSize);
2367
0
    if(ret < 0) {
2368
0
        xmlSecInternalError("xmlSecBufferBase64NodeContentWrite(g)", NULL);
2369
0
        return(-1);
2370
0
    }
2371
0
    if(addLineBreaks) {
2372
0
        xmlNodeAddContent(cur, xmlSecGetDefaultLineFeed());
2373
0
    }
2374
2375
    /* next is X node: write it ONLY for private keys and ONLY if it is requested */
2376
0
    if((writePrivateKey != 0) && (xmlSecBufferGetSize(&(data->x)) > 0)) {
2377
0
        cur = xmlSecAddChild(node, xmlSecNodeDSAX, xmlSecNs);
2378
0
        if(cur == NULL) {
2379
0
            xmlSecInternalError("xmlSecAddChild(NodeDSAX)", NULL);
2380
0
            return(-1);
2381
0
        }
2382
0
        if(addLineBreaks) {
2383
0
            xmlNodeSetContent(cur, xmlSecGetDefaultLineFeed());
2384
0
        } else {
2385
0
            xmlNodeSetContent(cur, xmlSecStringEmpty);
2386
0
        }
2387
0
        ret = xmlSecBufferBase64NodeContentWrite(&(data->x), cur, base64LineSize);
2388
0
        if(ret < 0) {
2389
0
            xmlSecInternalError("xmlSecBufferBase64NodeContentWrite(x)", NULL);
2390
0
            return(-1);
2391
0
        }
2392
0
        if(addLineBreaks) {
2393
0
            xmlNodeAddContent(cur, xmlSecGetDefaultLineFeed());
2394
0
        }
2395
0
    }
2396
2397
    /* next is Y node. */
2398
0
    cur = xmlSecAddChild(node, xmlSecNodeDSAY, xmlSecDSigNs);
2399
0
    if(cur == NULL) {
2400
0
        xmlSecInternalError("xmlSecAddChild(NodeDSAY)", NULL);
2401
0
        return(-1);
2402
0
    }
2403
0
    if(addLineBreaks) {
2404
0
        xmlNodeSetContent(cur, xmlSecGetDefaultLineFeed());
2405
0
    } else {
2406
0
        xmlNodeSetContent(cur, xmlSecStringEmpty);
2407
0
    }
2408
0
    ret = xmlSecBufferBase64NodeContentWrite(&(data->y), cur, base64LineSize);
2409
0
    if(ret < 0) {
2410
0
        xmlSecInternalError("xmlSecBufferBase64NodeContentWrite(y)", NULL);
2411
0
        return(-1);
2412
0
    }
2413
0
    if(addLineBreaks) {
2414
0
        xmlNodeAddContent(cur, xmlSecGetDefaultLineFeed());
2415
0
    }
2416
2417
0
    return(0);
2418
0
}
2419
#endif /* !defined(XMLSEC_NO_DSA) */
2420
2421
2422
#if !defined(XMLSEC_NO_RSA)
2423
/**************************************************************************
2424
 *
2425
 * Helper functions to read/write RSA keys
2426
 *
2427
 *************************************************************************/
2428
0
#define XMLSEC_KEY_DATA_RSA_INIT_BUF_SIZE     512
2429
2430
static int                      xmlSecKeyValueRsaInitialize             (xmlSecKeyValueRsaPtr data);
2431
static void                     xmlSecKeyValueRsaFinalize               (xmlSecKeyValueRsaPtr data);
2432
static int                      xmlSecKeyValueRsaXmlRead                (xmlSecKeyValueRsaPtr data,
2433
                                                                         xmlNodePtr node);
2434
static int                      xmlSecKeyValueRsaXmlWrite               (xmlSecKeyValueRsaPtr data,
2435
                                                                         xmlNodePtr node,
2436
                                                                         int writePrivateKey,
2437
                                                                         int base64LineSize,
2438
                                                                         int addLineBreaks);
2439
2440
/**
2441
 * xmlSecKeyDataRsaXmlRead:
2442
 * @id:                 the data id.
2443
 * @key:                the key.
2444
 * @node:               the pointer to data's value XML node.
2445
 * @keyInfoCtx:         the &lt;dsig:KeyInfo/&gt; node processing context.
2446
 * @readFunc:           the pointer to the function that converts
2447
 *                      @xmlSecKeyValueRsa to @xmlSecKeyData.
2448
 *
2449
 * DSA Key data method for reading XML node.
2450
 *
2451
 * Returns: 0 on success or a negative value if an error occurs.
2452
 */
2453
int
2454
xmlSecKeyDataRsaXmlRead(xmlSecKeyDataId id, xmlSecKeyPtr key,
2455
                        xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx,
2456
0
                        xmlSecKeyDataRsaRead readFunc) {
2457
0
    xmlSecKeyDataPtr data = NULL;
2458
0
    xmlSecKeyValueRsa rsaValue;
2459
0
    int rsaDataInitialized = 0;
2460
0
    int res = -1;
2461
0
    int ret;
2462
2463
0
    xmlSecAssert2(id != NULL, -1);
2464
0
    xmlSecAssert2(key != NULL, -1);
2465
0
    xmlSecAssert2(node != NULL, -1);
2466
0
    xmlSecAssert2(keyInfoCtx != NULL, -1);
2467
0
    xmlSecAssert2(readFunc != NULL, -1);
2468
2469
0
    if(xmlSecKeyGetValue(key) != NULL) {
2470
0
        xmlSecOtherError(XMLSEC_ERRORS_R_INVALID_KEY_DATA,
2471
0
            xmlSecKeyDataKlassGetName(id), "key already has a value");
2472
0
        goto done;
2473
0
    }
2474
2475
0
    ret = xmlSecKeyValueRsaInitialize(&rsaValue);
2476
0
    if(ret < 0) {
2477
0
        xmlSecInternalError("xmlSecKeyValueRsaInitialize",
2478
0
            xmlSecKeyDataKlassGetName(id));
2479
0
        goto done;
2480
0
    }
2481
0
    rsaDataInitialized = 1;
2482
2483
0
    ret = xmlSecKeyValueRsaXmlRead(&rsaValue, node);
2484
0
    if(ret < 0) {
2485
0
        xmlSecInternalError("xmlSecKeyValueRsaXmlRead",
2486
0
            xmlSecKeyDataKlassGetName(id));
2487
0
        goto done;
2488
0
    }
2489
2490
0
    data = readFunc(id, &rsaValue);
2491
0
    if(data == NULL) {
2492
0
        xmlSecInternalError("xmlSecKeyDataRsaRead",
2493
0
            xmlSecKeyDataKlassGetName(id));
2494
0
        goto done;
2495
0
    }
2496
2497
    /* set key value */
2498
0
    ret = xmlSecKeySetValue(key, data);
2499
0
    if(ret < 0) {
2500
0
        xmlSecInternalError("xmlSecKeySetValue",
2501
0
                            xmlSecKeyDataGetName(data));
2502
0
        goto done;
2503
0
    }
2504
0
    data = NULL; /* data is owned by key now */
2505
2506
    /* success */
2507
0
    res = 0;
2508
2509
0
done:
2510
    /* cleanup */
2511
0
    if(rsaDataInitialized != 0) {
2512
0
        xmlSecKeyValueRsaFinalize(&rsaValue);
2513
0
    }
2514
0
    if(data != NULL) {
2515
0
        xmlSecKeyDataDestroy(data);
2516
0
    }
2517
0
    return(res);
2518
0
}
2519
2520
/**
2521
 * xmlSecKeyDataRsaXmlWrite:
2522
 * @id:                 the data id.
2523
 * @key:                the key.
2524
 * @node:               the pointer to data's value XML node.
2525
 * @keyInfoCtx:         the &lt;dsig:KeyInfo/&gt; node processing context.
2526
 * @base64LineSize:     the base64 max line size.
2527
 * @addLineBreaks:      the flag indicating if we need to add line breaks around base64 output.
2528
 * @writeFunc:          the pointer to the function that converts
2529
 *                      @xmlSecKeyData to  @xmlSecKeyValueRsa.
2530
 *
2531
 * DSA Key data  method for writing XML node.
2532
 *
2533
 * Returns: 0 on success or a negative value if an error occurs.
2534
 */
2535
int
2536
xmlSecKeyDataRsaXmlWrite(xmlSecKeyDataId id, xmlSecKeyPtr key,
2537
                        xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx,
2538
                        int base64LineSize, int addLineBreaks,
2539
0
                        xmlSecKeyDataRsaWrite writeFunc) {
2540
0
    xmlSecKeyDataPtr data;
2541
0
    xmlSecKeyValueRsa rsaValue;
2542
0
    int rsaDataInitialized = 0;
2543
0
    int writePrivateKey = 0;
2544
0
    int res = -1;
2545
0
    int ret;
2546
2547
0
    xmlSecAssert2(id != NULL, -1);
2548
0
    xmlSecAssert2(key != NULL, -1);
2549
0
    xmlSecAssert2(node != NULL, -1);
2550
0
    xmlSecAssert2(keyInfoCtx != NULL, -1);
2551
0
    xmlSecAssert2(writeFunc != NULL, -1);
2552
0
    xmlSecAssert2(base64LineSize > 0, -1);
2553
2554
0
    if(((xmlSecKeyDataTypePublic | xmlSecKeyDataTypePrivate) & keyInfoCtx->keyReq.keyType) == 0) {
2555
        /* we can only write private key or public key */
2556
0
        return(0);
2557
0
    }
2558
0
    if((keyInfoCtx->keyReq.keyType & xmlSecKeyDataTypePrivate) != 0) {
2559
0
        writePrivateKey = 1;
2560
0
    }
2561
2562
0
    data = xmlSecKeyGetValue(key);
2563
0
    if(data == NULL) {
2564
0
        xmlSecOtherError(XMLSEC_ERRORS_R_INVALID_KEY_DATA,
2565
0
            xmlSecKeyDataKlassGetName(id), "key has no value");
2566
0
        goto done;
2567
0
    }
2568
2569
0
    ret = xmlSecKeyValueRsaInitialize(&rsaValue);
2570
0
    if(ret < 0) {
2571
0
        xmlSecInternalError("xmlSecKeyValueRsaInitialize",
2572
0
            xmlSecKeyDataKlassGetName(id));
2573
0
        goto done;
2574
0
    }
2575
0
    rsaDataInitialized = 1;
2576
2577
0
    ret = writeFunc(id, data, &rsaValue, writePrivateKey);
2578
0
    if(ret < 0) {
2579
0
        xmlSecInternalError("xmlSecKeyDataRsaWrite",
2580
0
            xmlSecKeyDataKlassGetName(id));
2581
0
        goto done;
2582
0
    }
2583
2584
0
    ret = xmlSecKeyValueRsaXmlWrite(&rsaValue, node, writePrivateKey,
2585
0
        base64LineSize, addLineBreaks);
2586
0
    if(ret < 0) {
2587
0
        xmlSecInternalError("xmlSecKeyValueRsaXmlWrite",
2588
0
            xmlSecKeyDataKlassGetName(id));
2589
0
        goto done;
2590
0
    }
2591
2592
    /* success */
2593
0
    res = 0;
2594
2595
0
done:
2596
    /* cleanup */
2597
0
    if(rsaDataInitialized != 0) {
2598
0
        xmlSecKeyValueRsaFinalize(&rsaValue);
2599
0
    }
2600
0
    return(res);
2601
0
}
2602
2603
static int
2604
0
xmlSecKeyValueRsaInitialize(xmlSecKeyValueRsaPtr data) {
2605
0
    int ret;
2606
2607
0
    xmlSecAssert2(data != NULL, -1);
2608
0
    memset(data, 0, sizeof(xmlSecKeyValueRsa));
2609
2610
0
    ret = xmlSecBufferInitialize(&(data->modulus), XMLSEC_KEY_DATA_RSA_INIT_BUF_SIZE);
2611
0
    if(ret < 0) {
2612
0
        xmlSecInternalError("xmlSecBufferInitialize(modulus)", NULL);
2613
0
        xmlSecKeyValueRsaFinalize(data);
2614
0
        return(-1);
2615
0
    }
2616
0
    ret = xmlSecBufferInitialize(&(data->publicExponent), XMLSEC_KEY_DATA_RSA_INIT_BUF_SIZE);
2617
0
    if(ret < 0) {
2618
0
        xmlSecInternalError("xmlSecBufferInitialize(q)", NULL);
2619
0
        xmlSecKeyValueRsaFinalize(data);
2620
0
        return(-1);
2621
0
    }
2622
0
    ret = xmlSecBufferInitialize(&(data->privateExponent), XMLSEC_KEY_DATA_RSA_INIT_BUF_SIZE);
2623
0
    if(ret < 0) {
2624
0
        xmlSecInternalError("xmlSecBufferInitialize(g)", NULL);
2625
0
        xmlSecKeyValueRsaFinalize(data);
2626
0
        return(-1);
2627
0
    }
2628
0
    return(0);
2629
0
}
2630
2631
static void
2632
0
xmlSecKeyValueRsaFinalize(xmlSecKeyValueRsaPtr data) {
2633
0
    xmlSecAssert(data != NULL);
2634
2635
0
    xmlSecBufferFinalize(&(data->modulus));
2636
0
    xmlSecBufferFinalize(&(data->publicExponent));
2637
0
    xmlSecBufferFinalize(&(data->privateExponent));
2638
0
    memset(data, 0, sizeof(xmlSecKeyValueRsa));
2639
0
}
2640
2641
static int
2642
0
xmlSecKeyValueRsaXmlRead(xmlSecKeyValueRsaPtr data, xmlNodePtr node) {
2643
0
    xmlNodePtr cur;
2644
0
    int ret;
2645
2646
0
    xmlSecAssert2(data != NULL, -1);
2647
0
    xmlSecAssert2(node != NULL, -1);
2648
2649
0
    cur = xmlSecGetNextElementNode(node->children);
2650
2651
    /* first is REQUIRED  Modulus node. */
2652
0
    if((cur == NULL) || (!xmlSecCheckNodeName(cur,  xmlSecNodeRSAModulus, xmlSecDSigNs))) {
2653
0
        xmlSecInvalidNodeError(cur, xmlSecNodeDSAP, NULL);
2654
0
        return(-1);
2655
0
    }
2656
0
    ret = xmlSecBufferBase64NodeContentRead(&(data->modulus), cur);
2657
0
    if(ret < 0) {
2658
0
        xmlSecInternalError("xmlSecBufferBase64NodeContentRead(p)", NULL);
2659
0
        return(-1);
2660
0
    }
2661
0
    cur = xmlSecGetNextElementNode(cur->next);
2662
2663
    /* next is REQUIRED Exponent node. */
2664
0
    if((cur == NULL) || (!xmlSecCheckNodeName(cur, xmlSecNodeRSAExponent, xmlSecDSigNs))) {
2665
0
        xmlSecInvalidNodeError(cur, xmlSecNodeDSAQ, NULL);
2666
0
        return(-1);
2667
0
    }
2668
0
    ret = xmlSecBufferBase64NodeContentRead(&(data->publicExponent), cur);
2669
0
    if(ret < 0) {
2670
0
        xmlSecInternalError("xmlSecBufferBase64NodeContentRead(q)", NULL);
2671
0
        return(-1);
2672
0
    }
2673
0
    cur = xmlSecGetNextElementNode(cur->next);
2674
2675
    /* next is PrivateExponent node. It is REQUIRED for private key but
2676
    * we are not sure exactly what are we reading */
2677
0
    if((cur != NULL) && (xmlSecCheckNodeName(cur, xmlSecNodeRSAPrivateExponent, xmlSecNs))) {
2678
0
        ret = xmlSecBufferBase64NodeContentRead(&(data->privateExponent), cur);
2679
0
        if(ret < 0) {
2680
0
            xmlSecInternalError("xmlSecBufferBase64NodeContentRead(x)", NULL);
2681
0
            return(-1);
2682
0
        }
2683
0
        cur = xmlSecGetNextElementNode(cur->next);
2684
0
    } else {
2685
        /* make sure it's empty */
2686
0
        ret = xmlSecBufferSetSize(&(data->privateExponent), 0);
2687
0
        if(ret < 0) {
2688
0
            xmlSecInternalError("xmlSecBufferSetSize(0)", NULL);
2689
0
            return(-1);
2690
0
        }
2691
0
    }
2692
2693
0
    if(cur != NULL) {
2694
0
        xmlSecUnexpectedNodeError(cur, NULL);
2695
0
        return(-1);
2696
0
    }
2697
2698
    /* success */
2699
0
    return(0);
2700
0
}
2701
2702
static int
2703
xmlSecKeyValueRsaXmlWrite(xmlSecKeyValueRsaPtr data, xmlNodePtr node,
2704
0
                      int writePrivateKey, int base64LineSize, int addLineBreaks) {
2705
0
    xmlNodePtr cur;
2706
0
    int ret;
2707
2708
0
    xmlSecAssert2(data != NULL, -1);
2709
0
    xmlSecAssert2(node != NULL, -1);
2710
2711
    /* first is Modulus node */
2712
0
    cur = xmlSecAddChild(node, xmlSecNodeRSAModulus, xmlSecDSigNs);
2713
0
    if(cur == NULL) {
2714
0
        xmlSecInternalError("xmlSecAddChild(Modulus)", NULL);
2715
0
        return(-1);
2716
0
    }
2717
0
    if(addLineBreaks) {
2718
0
        xmlNodeSetContent(cur, xmlSecGetDefaultLineFeed());
2719
0
    } else {
2720
0
        xmlNodeSetContent(cur, xmlSecStringEmpty);
2721
0
    }
2722
0
    ret = xmlSecBufferBase64NodeContentWrite(&(data->modulus), cur, base64LineSize);
2723
0
    if(ret < 0) {
2724
0
        xmlSecInternalError("xmlSecBufferBase64NodeContentWrite(modulus)", NULL);
2725
0
        return(-1);
2726
0
    }
2727
0
    if(addLineBreaks) {
2728
0
        xmlNodeAddContent(cur, xmlSecGetDefaultLineFeed());
2729
0
    }
2730
2731
    /* next is Exponent node. */
2732
0
    cur = xmlSecAddChild(node, xmlSecNodeRSAExponent, xmlSecDSigNs);
2733
0
    if(cur == NULL) {
2734
0
        xmlSecInternalError("xmlSecAddChild(Exponent)", NULL);
2735
0
        return(-1);
2736
0
    }
2737
0
    if(addLineBreaks) {
2738
0
        xmlNodeSetContent(cur, xmlSecGetDefaultLineFeed());
2739
0
    } else {
2740
0
        xmlNodeSetContent(cur, xmlSecStringEmpty);
2741
0
    }
2742
0
    ret = xmlSecBufferBase64NodeContentWrite(&(data->publicExponent), cur, base64LineSize);
2743
0
    if(ret < 0) {
2744
0
        xmlSecInternalError("xmlSecBufferBase64NodeContentWrite(exponent)", NULL);
2745
0
        return(-1);
2746
0
    }
2747
0
    if(addLineBreaks) {
2748
0
        xmlNodeAddContent(cur, xmlSecGetDefaultLineFeed());
2749
0
    }
2750
2751
    /* next is PrivateExponent node: write it ONLY for private keys and ONLY if it is requested */
2752
0
    if((writePrivateKey != 0) && (xmlSecBufferGetSize(&(data->privateExponent)) > 0)) {
2753
0
        cur = xmlSecAddChild(node, xmlSecNodeRSAPrivateExponent, xmlSecNs);
2754
0
        if(cur == NULL) {
2755
0
            xmlSecInternalError("xmlSecAddChild(PrivateExponent)", NULL);
2756
0
            return(-1);
2757
0
        }
2758
0
        if(addLineBreaks) {
2759
0
            xmlNodeSetContent(cur, xmlSecGetDefaultLineFeed());
2760
0
        } else {
2761
0
            xmlNodeSetContent(cur, xmlSecStringEmpty);
2762
0
        }
2763
0
        ret = xmlSecBufferBase64NodeContentWrite(&(data->privateExponent), cur, base64LineSize);
2764
0
        if(ret < 0) {
2765
0
            xmlSecInternalError("xmlSecBufferBase64NodeContentWrite(privateExponent)", NULL);
2766
0
            return(-1);
2767
0
        }
2768
0
        if(addLineBreaks) {
2769
0
            xmlNodeAddContent(cur, xmlSecGetDefaultLineFeed());
2770
0
        }
2771
0
    }
2772
2773
0
    return(0);
2774
0
}
2775
#endif /* !defined(XMLSEC_NO_RSA) */
2776
2777
2778
#if !defined(XMLSEC_NO_X509)
2779
/**************************************************************************
2780
 *
2781
 * Helper functions to read/write &lt;dsig:X509Data/&gt;
2782
 *
2783
 *
2784
 * The X509Data Element (http://www.w3.org/TR/xmldsig-core/#sec-X509Data)
2785
 *
2786
 * An X509Data element within KeyInfo contains one or more identifiers of keys
2787
 * or X509 certificates (or certificates' identifiers or a revocation list).
2788
 * The content of X509Data is:
2789
 *
2790
 *  1. At least one element, from the following set of element types; any of these may appear together or more than once iff (if and only if) each instance describes or is related to the same certificate:
2791
 *  2.
2792
 *    * The X509IssuerSerial element, which contains an X.509 issuer
2793
 *      distinguished name/serial number pair that SHOULD be compliant
2794
 *      with RFC2253 [LDAP-DN],
2795
 *    * The X509SubjectName element, which contains an X.509 subject
2796
 *      distinguished name that SHOULD be compliant with RFC2253 [LDAP-DN],
2797
 *    * The X509SKI element, which contains the base64 encoded plain (i.e.
2798
 *      non-DER-encoded) value of a X509 V.3 SubjectKeyIdentifier extension.
2799
 *    * The X509Certificate element, which contains a base64-encoded [X509v3]
2800
 *      certificate, and
2801
 *    * Elements from an external namespace which accompanies/complements any
2802
 *      of the elements above.
2803
 *    * The X509CRL element, which contains a base64-encoded certificate
2804
 *      revocation list (CRL) [X509v3].
2805
 *
2806
 * Any X509IssuerSerial, X509SKI, and X509SubjectName elements that appear
2807
 * MUST refer to the certificate or certificates containing the validation key.
2808
 * All such elements that refer to a particular individual certificate MUST be
2809
 * grouped inside a single X509Data element and if the certificate to which
2810
 * they refer appears, it MUST also be in that X509Data element.
2811
 *
2812
 * Any X509IssuerSerial, X509SKI, and X509SubjectName elements that relate to
2813
 * the same key but different certificates MUST be grouped within a single
2814
 * KeyInfo but MAY occur in multiple X509Data elements.
2815
 *
2816
 * All certificates appearing in an X509Data element MUST relate to the
2817
 * validation key by either containing it or being part of a certification
2818
 * chain that terminates in a certificate containing the validation key.
2819
 *
2820
 * No ordering is implied by the above constraints.
2821
 *
2822
 * Note, there is no direct provision for a PKCS#7 encoded "bag" of
2823
 * certificates or CRLs. However, a set of certificates and CRLs can occur
2824
 * within an X509Data element and multiple X509Data elements can occur in a
2825
 * KeyInfo. Whenever multiple certificates occur in an X509Data element, at
2826
 * least one such certificate must contain the public key which verifies the
2827
 * signature.
2828
 *
2829
 * <programlisting><![CDATA[
2830
 *  Schema Definition:
2831
 *
2832
 *  <element name="X509Data" type="ds:X509DataType"/>
2833
 *  <complexType name="X509DataType">
2834
 *    <sequence maxOccurs="unbounded">
2835
 *      <choice>
2836
 *        <element name="X509IssuerSerial" type="ds:X509IssuerSerialType"/>
2837
 *        <element name="X509SKI" type="base64Binary"/>
2838
 *        <element name="X509SubjectName" type="string"/>
2839
 *        <element name="X509Certificate" type="base64Binary"/>
2840
 *        <element name="X509CRL" type="base64Binary"/>
2841
 *        <any namespace="##other" processContents="lax"/>
2842
 *      </choice>
2843
 *    </sequence>
2844
 *  </complexType>
2845
 *  <complexType name="X509IssuerSerialType">
2846
 *    <sequence>
2847
 *       <element name="X509IssuerName" type="string"/>
2848
 *       <element name="X509SerialNumber" type="integer"/>
2849
 *     </sequence>
2850
 *  </complexType>
2851
 *
2852
 *  DTD:
2853
 *
2854
 *    <!ELEMENT X509Data ((X509IssuerSerial | X509SKI | X509SubjectName |
2855
 *                          X509Certificate | X509CRL)+ %X509.ANY;)>
2856
 *    <!ELEMENT X509IssuerSerial (X509IssuerName, X509SerialNumber) >
2857
 *    <!ELEMENT X509IssuerName (#PCDATA) >
2858
 *    <!ELEMENT X509SubjectName (#PCDATA) >
2859
 *    <!ELEMENT X509SerialNumber (#PCDATA) >
2860
 *    <!ELEMENT X509SKI (#PCDATA) >
2861
 *    <!ELEMENT X509Certificate (#PCDATA) >
2862
 *    <!ELEMENT X509CRL (#PCDATA) >
2863
 * ]]></programlisting>
2864
 *
2865
 *************************************************************************/
2866
0
#define XMLSEC_KEY_DATA_X509_INIT_BUF_SIZE     512
2867
2868
static int                      xmlSecKeyX509DataValueInitialize            (xmlSecKeyX509DataValuePtr x509Value);
2869
static void                     xmlSecKeyX509DataValueFinalize              (xmlSecKeyX509DataValuePtr x509Value);
2870
static void                     xmlSecKeyX509DataValueReset                 (xmlSecKeyX509DataValuePtr x509Value,
2871
                                                                             int writeMode);
2872
static int                      xmlSecKeyX509DataValueXmlRead               (xmlSecKeyX509DataValuePtr x509Value,
2873
                                                                             xmlNodePtr node,
2874
                                                                             xmlSecKeyInfoCtxPtr keyInfoCtx);
2875
static int                      xmlSecKeyX509DataValueXmlWrite              (xmlSecKeyX509DataValuePtr x509Value,
2876
                                                                             xmlNodePtr node,
2877
                                                                             int base64LineSize,
2878
                                                                             int addLineBreaks);
2879
2880
/**
2881
 * xmlSecKeyDataX509XmlRead:
2882
 * @key:                the resulting key
2883
 * @data:               the X509 key data.
2884
 * @node:               the pointer to data's value XML node.
2885
 * @keyInfoCtx:         the &lt;dsig:KeyInfo/&gt; node processing context.
2886
 * @readFunc:           the pointer to the function that converts
2887
 *                      @xmlSecKeyX509DataValue to @xmlSecKeyData.
2888
 *
2889
 * X509 Key data method for reading XML node.
2890
 *
2891
 * Returns: 0 on success or a negative value if an error occurs.
2892
 */
2893
int
2894
xmlSecKeyDataX509XmlRead(xmlSecKeyPtr key, xmlSecKeyDataPtr data, xmlNodePtr node,
2895
    xmlSecKeyInfoCtxPtr keyInfoCtx, xmlSecKeyDataX509Read readFunc
2896
0
) {
2897
0
    xmlSecKeyX509DataValue x509Value;
2898
0
    int x509ValueInitialized = 0;
2899
0
    xmlNodePtr cur;
2900
0
    int keyFound = 0;
2901
0
    int res = -1;
2902
0
    int ret;
2903
2904
0
    xmlSecAssert2(data != NULL, -1);
2905
0
    xmlSecAssert2(node != NULL, -1);
2906
0
    xmlSecAssert2(keyInfoCtx != NULL, -1);
2907
0
    xmlSecAssert2(keyInfoCtx->keysMngr != NULL, -1);
2908
2909
0
    ret = xmlSecKeyX509DataValueInitialize(&x509Value);
2910
0
    if(ret < 0) {
2911
0
        xmlSecInternalError("xmlSecKeyX509DataValueInitialize", NULL);
2912
0
        goto done;
2913
0
    }
2914
0
    x509ValueInitialized = 1;
2915
2916
0
    for(cur = xmlSecGetNextElementNode(node->children); cur != NULL; cur = xmlSecGetNextElementNode(cur->next)) {
2917
0
        ret = xmlSecKeyX509DataValueXmlRead(&x509Value, cur, keyInfoCtx);
2918
0
        if(ret < 0) {
2919
0
            xmlSecInternalError("xmlSecKeyX509DataValueXmlRead", NULL);
2920
0
            goto done;
2921
0
        }
2922
2923
        /* first try to lookup key in keys manager using x509 data */
2924
0
        if(keyFound == 0) {
2925
0
            xmlSecKeyPtr tmpKey;
2926
2927
0
            tmpKey = xmlSecKeysMngrFindKeyFromX509Data(keyInfoCtx->keysMngr, &x509Value, keyInfoCtx);
2928
0
            if(tmpKey != NULL) {
2929
0
                ret = xmlSecKeySwap(key, tmpKey);
2930
0
                if(ret < 0) {
2931
0
                    xmlSecInternalError("xmlSecKeysMngrFindKeyFromX509Data", NULL);
2932
0
                    xmlSecKeyDestroy(tmpKey);
2933
0
                    goto done;
2934
0
                }
2935
0
                xmlSecKeyDestroy(tmpKey);
2936
2937
                /* key was found but we want to keep reading X509Data node to ensure it is valid */
2938
0
                keyFound = 1;
2939
0
            }
2940
0
        }
2941
2942
        /* otherwise, see if we can get it from certs, etc */
2943
0
        if((keyFound == 0) && (readFunc != NULL)) {
2944
            /* xmlSecKeyDataX509Read: 0 on success and a negative value otherwise */
2945
0
            ret = readFunc(data, &x509Value, keyInfoCtx->keysMngr, keyInfoCtx->flags);
2946
0
            if(ret < 0) {
2947
0
                xmlSecInternalError("xmlSecKeyDataX509Read", NULL);
2948
0
                goto done;
2949
0
            }
2950
0
        }
2951
2952
        /* cleanup for the next node */
2953
0
        xmlSecKeyX509DataValueReset(&x509Value, 0);
2954
0
    }
2955
2956
    /* success */
2957
0
    res = 0;
2958
2959
0
done:
2960
    /* cleanup */
2961
0
    if(x509ValueInitialized != 0) {
2962
0
        xmlSecKeyX509DataValueFinalize(&x509Value);
2963
0
    }
2964
2965
0
    return(res);
2966
0
}
2967
2968
2969
static int
2970
0
xmlSecX509DataGetNodeContent(xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx, xmlChar** digestAlgorithm) {
2971
0
    xmlNodePtr cur;
2972
0
    int content = 0;
2973
2974
0
    xmlSecAssert2(node != NULL, 0);
2975
0
    xmlSecAssert2(keyInfoCtx != NULL, -1);
2976
0
    xmlSecAssert2(digestAlgorithm != NULL, -1);
2977
0
    xmlSecAssert2((*digestAlgorithm) == NULL, -1);
2978
2979
    /* determine the current node content */
2980
0
    cur = xmlSecGetNextElementNode(node->children);
2981
0
    while(cur != NULL) {
2982
0
        if(xmlSecCheckNodeName(cur, xmlSecNodeX509Certificate, xmlSecDSigNs)) {
2983
0
            if(xmlSecIsEmptyNode(cur) == 1) {
2984
0
                content |= XMLSEC_X509DATA_CERTIFICATE_NODE;
2985
0
            } else {
2986
                /* ensure return value isn't 0 if there are non-empty elements */
2987
0
                content |= (XMLSEC_X509DATA_CERTIFICATE_NODE << XMLSEC_X509DATA_SHIFT_IF_NOT_EMPTY);
2988
0
            }
2989
0
        } else if(xmlSecCheckNodeName(cur, xmlSecNodeX509SubjectName, xmlSecDSigNs)) {
2990
0
            if(xmlSecIsEmptyNode(cur) == 1) {
2991
0
                content |= XMLSEC_X509DATA_SUBJECTNAME_NODE;
2992
0
            } else {
2993
0
                content |= (XMLSEC_X509DATA_SUBJECTNAME_NODE << XMLSEC_X509DATA_SHIFT_IF_NOT_EMPTY);
2994
0
            }
2995
0
        } else if(xmlSecCheckNodeName(cur, xmlSecNodeX509IssuerSerial, xmlSecDSigNs)) {
2996
0
            if(xmlSecIsEmptyNode(cur) == 1) {
2997
0
                content |= XMLSEC_X509DATA_ISSUERSERIAL_NODE;
2998
0
            } else {
2999
0
                content |= (XMLSEC_X509DATA_ISSUERSERIAL_NODE << XMLSEC_X509DATA_SHIFT_IF_NOT_EMPTY);
3000
0
            }
3001
0
        } else if(xmlSecCheckNodeName(cur, xmlSecNodeX509SKI, xmlSecDSigNs)) {
3002
0
            if(xmlSecIsEmptyNode(cur) == 1) {
3003
0
                content |= XMLSEC_X509DATA_SKI_NODE;
3004
0
            } else {
3005
0
                content |= (XMLSEC_X509DATA_SKI_NODE << XMLSEC_X509DATA_SHIFT_IF_NOT_EMPTY);
3006
0
            }
3007
0
        } else if(xmlSecCheckNodeName(cur, xmlSecNodeX509Digest, xmlSecDSig11Ns)) {
3008
0
            if(xmlSecIsEmptyNode(cur) == 1) {
3009
0
                content |= XMLSEC_X509DATA_DIGEST_NODE;
3010
0
            } else {
3011
0
                content |= (XMLSEC_X509DATA_DIGEST_NODE << XMLSEC_X509DATA_SHIFT_IF_NOT_EMPTY);
3012
0
            }
3013
            /* only read the first digestAlgorithm */
3014
0
            if((*digestAlgorithm) == NULL) {
3015
0
                (*digestAlgorithm) = xmlGetProp(cur, xmlSecAttrAlgorithm);
3016
0
                if((*digestAlgorithm) == NULL) {
3017
0
                    xmlSecInvalidNodeAttributeError(cur, xmlSecAttrAlgorithm, NULL, "empty");
3018
0
                    return(-1);
3019
0
                }
3020
0
            }
3021
0
        } else if(xmlSecCheckNodeName(cur, xmlSecNodeX509CRL, xmlSecDSigNs)) {
3022
0
            if(xmlSecIsEmptyNode(cur) == 1) {
3023
0
                content |= XMLSEC_X509DATA_CRL_NODE;
3024
0
            } else {
3025
0
                content |= (XMLSEC_X509DATA_CRL_NODE << 16);
3026
0
            }
3027
0
        } else {
3028
            /* todo: fail on unknown child node? */
3029
0
        }
3030
0
        cur = xmlSecGetNextElementNode(cur->next);
3031
0
    }
3032
3033
0
    return (content);
3034
0
}
3035
3036
/**
3037
 * xmlSecKeyDataDsaXmlWrite:
3038
 * @data:               the x509 key data.
3039
 * @x509ObjNum:         the number of X509 objects in @data.
3040
 * @node:               the pointer to data's value XML node.
3041
 * @keyInfoCtx:         the &lt;dsig:KeyInfo/&gt; node processing context.
3042
 * @base64LineSize:     the base64 max line size.
3043
 * @addLineBreaks:      the flag indicating if we need to add line breaks around base64 output.
3044
 * @writeFunc:          the pointer to the function that converts
3045
 *                      @xmlSecKeyData to  @xmlSecKeyValueDsa.
3046
 *
3047
 * DSA Key data  method for writing XML node.
3048
 *
3049
 * Returns: 0 on success or a negative value if an error occurs.
3050
 */
3051
int
3052
xmlSecKeyDataX509XmlWrite(xmlSecKeyDataPtr data, xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx,
3053
                          int base64LineSize, int addLineBreaks,
3054
0
                          xmlSecKeyDataX509Write writeFunc, void* writeFuncContext) {
3055
0
    xmlSecKeyX509DataValue x509Value;
3056
0
    int x509ValueInitialized = 0;
3057
0
    int content;
3058
0
    int ret;
3059
0
    int res = -1;
3060
3061
0
    xmlSecAssert2(data != NULL, -1);
3062
0
    xmlSecAssert2(node != NULL, -1);
3063
0
    xmlSecAssert2(keyInfoCtx != NULL, -1);
3064
0
    xmlSecAssert2(base64LineSize > 0, -1);
3065
0
    xmlSecAssert2(writeFunc != NULL, -1);
3066
3067
0
    if(((xmlSecKeyDataTypePublic) & keyInfoCtx->keyReq.keyType) == 0) {
3068
        /* we can only write public key */
3069
0
        return(0);
3070
0
    }
3071
3072
0
    ret = xmlSecKeyX509DataValueInitialize(&x509Value);
3073
0
    if(ret < 0) {
3074
0
        xmlSecInternalError("xmlSecKeyX509DataValueInitialize",
3075
0
            xmlSecKeyDataGetName(data));
3076
0
        goto done;
3077
0
    }
3078
0
    x509ValueInitialized = 1;
3079
3080
3081
0
    content = xmlSecX509DataGetNodeContent(node, keyInfoCtx, &(x509Value.digestAlgorithm));
3082
0
    if (content < 0) {
3083
0
        xmlSecInternalError2("xmlSecX509DataGetNodeContent",
3084
0
            xmlSecKeyDataGetName(data), "content=%d", content);
3085
0
        goto done;
3086
0
    } else if(content == 0) {
3087
        /* by default we are writing certificates and crls */
3088
0
        content = XMLSEC_X509DATA_DEFAULT;
3089
0
    }
3090
3091
0
    while(1) {
3092
        /* xmlSecKeyDataX509Write: returns 1 on success, 0 if no more certs/crls are available,
3093
         * or a negative value if an error occurs.
3094
         */
3095
0
        ret = writeFunc(data, &x509Value, content, writeFuncContext);
3096
0
        if(ret < 0) {
3097
0
            xmlSecInternalError("writeFunc", xmlSecKeyDataGetName(data));
3098
0
            goto done;
3099
0
        } else if (ret == 0) {
3100
0
            break;
3101
0
        }
3102
3103
0
        ret = xmlSecKeyX509DataValueXmlWrite(&x509Value, node, base64LineSize, addLineBreaks);
3104
0
        if(ret < 0) {
3105
0
            xmlSecInternalError("xmlSecKeyX509DataValueXmlWrite", xmlSecKeyDataGetName(data));
3106
0
            goto done;
3107
0
        }
3108
3109
         /* cleanup for the next obj */
3110
0
        xmlSecKeyX509DataValueReset(&x509Value, 1);
3111
0
    }
3112
3113
    /* success */
3114
0
    res = 0;
3115
3116
0
done:
3117
    /* cleanup */
3118
0
    if(x509ValueInitialized != 0) {
3119
0
        xmlSecKeyX509DataValueFinalize(&x509Value);
3120
0
    }
3121
3122
0
    return(res);
3123
0
}
3124
3125
static int
3126
0
xmlSecKeyX509DataValueInitialize(xmlSecKeyX509DataValuePtr x509Value) {
3127
0
    int ret;
3128
3129
0
    xmlSecAssert2(x509Value != NULL, -1);
3130
0
    memset(x509Value, 0, sizeof(xmlSecKeyX509DataValue));
3131
3132
0
    ret = xmlSecBufferInitialize(&(x509Value->cert), XMLSEC_KEY_DATA_X509_INIT_BUF_SIZE);
3133
0
    if(ret < 0) {
3134
0
        xmlSecInternalError("xmlSecBufferInitialize(cert)", NULL);
3135
0
        xmlSecKeyX509DataValueFinalize(x509Value);
3136
0
        return(-1);
3137
0
    }
3138
0
    ret = xmlSecBufferInitialize(&(x509Value->crl), XMLSEC_KEY_DATA_X509_INIT_BUF_SIZE);
3139
0
    if(ret < 0) {
3140
0
        xmlSecInternalError("xmlSecBufferInitialize(crl)", NULL);
3141
0
        xmlSecKeyX509DataValueFinalize(x509Value);
3142
0
        return(-1);
3143
0
    }
3144
0
    ret = xmlSecBufferInitialize(&(x509Value->ski), XMLSEC_KEY_DATA_X509_INIT_BUF_SIZE);
3145
0
    if(ret < 0) {
3146
0
        xmlSecInternalError("xmlSecBufferInitialize(ski)", NULL);
3147
0
        xmlSecKeyX509DataValueFinalize(x509Value);
3148
0
        return(-1);
3149
0
    }
3150
0
    ret = xmlSecBufferInitialize(&(x509Value->digest), XMLSEC_KEY_DATA_X509_INIT_BUF_SIZE);
3151
0
    if(ret < 0) {
3152
0
        xmlSecInternalError("xmlSecBufferInitialize(digest)", NULL);
3153
0
        xmlSecKeyX509DataValueFinalize(x509Value);
3154
0
        return(-1);
3155
0
    }
3156
0
    return(0);
3157
0
}
3158
3159
static void
3160
0
xmlSecKeyX509DataValueFinalize(xmlSecKeyX509DataValuePtr x509Value) {
3161
0
    xmlSecAssert(x509Value != NULL);
3162
3163
0
    xmlSecBufferFinalize(&(x509Value->cert));
3164
0
    xmlSecBufferFinalize(&(x509Value->crl));
3165
0
    xmlSecBufferFinalize(&(x509Value->ski));
3166
3167
0
    if(x509Value->subject != NULL) {
3168
0
        xmlFree(x509Value->subject);
3169
0
    }
3170
3171
0
    if(x509Value->issuerName != NULL) {
3172
0
        xmlFree(x509Value->issuerName);
3173
0
    }
3174
0
    if(x509Value->issuerSerial != NULL) {
3175
0
        xmlFree(x509Value->issuerSerial);
3176
0
    }
3177
3178
0
    if(x509Value->digestAlgorithm != NULL) {
3179
0
        xmlFree(x509Value->digestAlgorithm);
3180
0
    }
3181
0
    xmlSecBufferFinalize(&(x509Value->digest));
3182
3183
0
    memset(x509Value, 0, sizeof(xmlSecKeyX509DataValue));
3184
0
}
3185
3186
static void
3187
0
xmlSecKeyX509DataValueReset(xmlSecKeyX509DataValuePtr x509Value, int writeMode) {
3188
0
    xmlSecAssert(x509Value != NULL);
3189
3190
0
    xmlSecBufferEmpty(&(x509Value->cert));
3191
0
    xmlSecBufferEmpty(&(x509Value->crl));
3192
0
    xmlSecBufferEmpty(&(x509Value->ski));
3193
3194
0
    if(x509Value->subject != NULL) {
3195
0
        xmlFree(x509Value->subject);
3196
0
        x509Value->subject = NULL;
3197
0
    }
3198
3199
0
    if(x509Value->issuerName != NULL) {
3200
0
        xmlFree(x509Value->issuerName);
3201
0
        x509Value->issuerName = NULL;
3202
0
    }
3203
0
    if(x509Value->issuerSerial != NULL) {
3204
0
        xmlFree(x509Value->issuerSerial);
3205
0
        x509Value->issuerSerial = NULL;
3206
0
    }
3207
3208
    /* we keep digest algorithm as-is for the next certificate if we are writing it out */
3209
0
    if((writeMode == 0) && (x509Value->digestAlgorithm != NULL)) {
3210
0
        xmlFree(x509Value->digestAlgorithm);
3211
0
        x509Value->digestAlgorithm = NULL;
3212
0
    }
3213
0
    xmlSecBufferEmpty(&(x509Value->digest));
3214
3215
0
}
3216
3217
static int
3218
0
xmlSecKeyX509DataValueXmlReadBase64Blob(xmlSecBufferPtr buf, xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx) {
3219
0
    xmlChar *content;
3220
0
    xmlSecSize decodedSize;
3221
0
    int ret;
3222
0
    int res = -1;
3223
3224
0
    xmlSecAssert2(buf != NULL, -1);
3225
0
    xmlSecAssert2(node != NULL, -1);
3226
0
    xmlSecAssert2(keyInfoCtx != NULL, -1);
3227
3228
0
    content = xmlNodeGetContent(node);
3229
0
    if((content == NULL) || (xmlSecIsEmptyString(content) == 1)) {
3230
0
        if((keyInfoCtx->flags & XMLSEC_KEYINFO_FLAGS_STOP_ON_EMPTY_NODE) != 0) {
3231
0
            xmlSecInvalidNodeContentError(node, NULL, "empty");
3232
0
            goto done;
3233
0
        }
3234
3235
        /* success */
3236
0
        res = 0;
3237
0
        goto done;
3238
0
    }
3239
3240
    /* usual trick with base64 decoding "in-place" */
3241
0
    decodedSize = 0;
3242
0
    ret = xmlSecBase64DecodeInPlace(content, &decodedSize);
3243
0
    if(ret < 0) {
3244
0
        xmlSecInternalError2("xmlSecBase64DecodeInPlace", NULL,
3245
0
            "node=%s", xmlSecErrorsSafeString(xmlSecNodeGetName(node)));
3246
0
        goto done;
3247
0
    }
3248
3249
0
    ret = xmlSecBufferSetData(buf, (xmlSecByte*)content, decodedSize);
3250
0
    if(ret < 0) {
3251
0
        xmlSecInternalError3("xmlSecBufferSetData", NULL,
3252
0
            "node=%s; size=" XMLSEC_SIZE_FMT,
3253
0
            xmlSecErrorsSafeString(xmlSecNodeGetName(node)),
3254
0
            decodedSize);
3255
0
        goto done;
3256
0
    }
3257
3258
    /* success */
3259
0
    res = 0;
3260
3261
0
done:
3262
    /* cleanup */
3263
0
    if(content != NULL) {
3264
0
        xmlFree(content);
3265
0
    }
3266
0
    return(res);
3267
0
}
3268
3269
static void
3270
0
xmlSecKeyX509DataValueTrim(xmlChar * str) {
3271
0
    xmlChar * p, * q;
3272
0
    int len;
3273
3274
0
    xmlSecAssert(str != NULL);
3275
3276
0
    len = xmlStrlen(str);
3277
0
    if(len <= 0) {
3278
0
        return;
3279
0
    }
3280
3281
    /* skip spaces from the beggining */
3282
0
    p = str;
3283
0
    q = str + len - 1;
3284
0
    while(isspace(*p) && (p != q)) {
3285
0
        ++p;
3286
0
    }
3287
0
    while(isspace(*q) && (p != q)) {
3288
0
        --q;
3289
0
    }
3290
3291
    /* all the cases */
3292
0
    if((p == q) && isspace(*p)) {
3293
0
        (*str) = '\0';
3294
0
        return;
3295
0
    } else if(p == str) {
3296
0
        *(q + 1) = '\0';
3297
0
    } else {
3298
0
        xmlSecAssert(q >= p);
3299
3300
0
        len = (int)(q - p + 1);
3301
0
        memmove(str, p, (size_t)len);
3302
0
        str[len] = '\0';
3303
0
    }
3304
0
}
3305
3306
static int
3307
0
xmlSecKeyX509DataValueXmlReadString(xmlChar **str, xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx) {
3308
0
    xmlChar *content;
3309
0
    int res = -1;
3310
3311
0
    xmlSecAssert2(str != NULL, -1);
3312
0
    xmlSecAssert2((*str) == NULL, -1);
3313
0
    xmlSecAssert2(node != NULL, -1);
3314
0
    xmlSecAssert2(keyInfoCtx != NULL, -1);
3315
3316
0
    content = xmlNodeGetContent(node);
3317
0
    if(content != NULL) {
3318
0
        xmlSecKeyX509DataValueTrim(content);
3319
0
    }
3320
0
    if((content == NULL) || (xmlStrlen(content) <= 0)) {
3321
0
        if((keyInfoCtx->flags & XMLSEC_KEYINFO_FLAGS_STOP_ON_EMPTY_NODE) != 0) {
3322
0
            xmlSecInvalidNodeContentError(node, NULL, "empty");
3323
0
            goto done;
3324
0
        }
3325
3326
        /* success */
3327
0
        res = 0;
3328
0
        goto done;
3329
0
    }
3330
3331
    /* success */
3332
0
    (*str) = content;
3333
0
    content = NULL;
3334
0
    res = 0;
3335
3336
0
done:
3337
    /* cleanup */
3338
0
    if(content != NULL) {
3339
0
        xmlFree(content);
3340
0
    }
3341
0
    return(res);
3342
0
}
3343
3344
static int
3345
xmlSecKeyX509DataValueXmlReadIssuerSerial(xmlSecKeyX509DataValuePtr x509Value, xmlNodePtr node,
3346
    xmlSecKeyInfoCtxPtr keyInfoCtx
3347
0
) {
3348
0
    xmlNodePtr cur;
3349
3350
0
    xmlSecAssert2(x509Value != NULL, -1);
3351
0
    xmlSecAssert2(x509Value->issuerName == NULL, -1);
3352
0
    xmlSecAssert2(x509Value->issuerSerial == NULL, -1);
3353
0
    xmlSecAssert2(node != NULL, -1);
3354
0
    xmlSecAssert2(keyInfoCtx != NULL, -1);
3355
3356
0
    cur = xmlSecGetNextElementNode(node->children);
3357
0
    if(cur == NULL) {
3358
0
        if((keyInfoCtx->flags & XMLSEC_KEYINFO_FLAGS_STOP_ON_EMPTY_NODE) != 0) {
3359
0
            xmlSecNodeNotFoundError("xmlSecGetNextElementNode", node, NULL, NULL);
3360
0
            return(-1);
3361
0
        }
3362
0
        return(0);
3363
0
    }
3364
3365
    /* the first is required node X509IssuerName */
3366
0
    if(!xmlSecCheckNodeName(cur, xmlSecNodeX509IssuerName, xmlSecDSigNs)) {
3367
0
        xmlSecInvalidNodeError(cur, xmlSecNodeX509IssuerName, NULL);
3368
0
        return(-1);
3369
0
    }
3370
0
    x509Value->issuerName = xmlNodeGetContent(cur);
3371
0
    if((x509Value->issuerName == NULL) || (xmlSecIsEmptyString(x509Value->issuerName) == 1)) {
3372
0
        xmlSecInvalidNodeContentError(cur, NULL, "empty");
3373
0
        return(-1);
3374
0
    }
3375
0
    cur = xmlSecGetNextElementNode(cur->next);
3376
3377
    /* next is required node X509SerialNumber */
3378
0
    if((cur == NULL) || !xmlSecCheckNodeName(cur, xmlSecNodeX509SerialNumber, xmlSecDSigNs)) {
3379
0
        xmlSecInvalidNodeError(cur, xmlSecNodeX509SerialNumber, NULL);
3380
0
        return(-1);
3381
0
    }
3382
0
    x509Value->issuerSerial  = xmlNodeGetContent(cur);
3383
0
    if((x509Value->issuerSerial == NULL) || (xmlSecIsEmptyString(x509Value->issuerSerial) == 1)) {
3384
0
        xmlSecInvalidNodeContentError(cur, NULL, "empty");
3385
0
        return(-1);
3386
0
    }
3387
0
    cur = xmlSecGetNextElementNode(cur->next);
3388
3389
    /* nothing else is expected */
3390
0
    if(cur != NULL) {
3391
0
        xmlSecUnexpectedNodeError(cur, NULL);
3392
0
        return(-1);
3393
0
    }
3394
3395
    /* success */
3396
0
    return(0);
3397
0
}
3398
3399
static int
3400
0
xmlSecKeyX509DataValueXmlRead(xmlSecKeyX509DataValuePtr x509Value, xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx) {
3401
0
    int ret;
3402
3403
0
    xmlSecAssert2(x509Value != NULL, -1);
3404
0
    xmlSecAssert2(node != NULL, -1);
3405
0
    xmlSecAssert2(keyInfoCtx != NULL, -1);
3406
3407
0
    if(xmlSecCheckNodeName(node, xmlSecNodeX509Certificate, xmlSecDSigNs)) {
3408
0
        ret = xmlSecKeyX509DataValueXmlReadBase64Blob(&(x509Value->cert), node, keyInfoCtx);
3409
0
        if(ret < 0) {
3410
0
            xmlSecInternalError("xmlSecKeyX509DataValueXmlReadBase64Blob(cert)", NULL);
3411
0
            return(-1);
3412
0
        }
3413
0
    } else if(xmlSecCheckNodeName(node, xmlSecNodeX509CRL, xmlSecDSigNs)) {
3414
0
        ret = xmlSecKeyX509DataValueXmlReadBase64Blob(&(x509Value->crl), node, keyInfoCtx);
3415
0
        if(ret < 0) {
3416
0
            xmlSecInternalError("xmlSecKeyX509DataValueXmlReadBase64Blob(crl)", NULL);
3417
0
            return(-1);
3418
0
        }
3419
0
    } else if(xmlSecCheckNodeName(node, xmlSecNodeX509SKI, xmlSecDSigNs)) {
3420
0
        ret = xmlSecKeyX509DataValueXmlReadBase64Blob(&(x509Value->ski), node, keyInfoCtx);
3421
0
        if(ret < 0) {
3422
0
            xmlSecInternalError("xmlSecKeyX509DataValueXmlReadBase64Blob(ski)", NULL);
3423
0
            return(-1);
3424
0
        }
3425
0
    } else if(xmlSecCheckNodeName(node, xmlSecNodeX509SubjectName, xmlSecDSigNs)) {
3426
0
        ret = xmlSecKeyX509DataValueXmlReadString(&(x509Value->subject), node, keyInfoCtx);
3427
0
        if(ret < 0) {
3428
0
            xmlSecInternalError("xmlSecKeyX509DataValueXmlReadString(subject)", NULL);
3429
0
            return(-1);
3430
0
        }
3431
0
    } else if(xmlSecCheckNodeName(node, xmlSecNodeX509IssuerSerial, xmlSecDSigNs)) {
3432
0
        ret = xmlSecKeyX509DataValueXmlReadIssuerSerial(x509Value, node, keyInfoCtx);
3433
0
        if(ret < 0) {
3434
0
            xmlSecInternalError("xmlSecKeyX509DataValueXmlReadIssuerSerial", NULL);
3435
0
            return(-1);
3436
0
        }
3437
0
    } else if(xmlSecCheckNodeName(node, xmlSecNodeX509Digest, xmlSecDSig11Ns)) {
3438
0
        xmlSecAssert2(x509Value->digestAlgorithm == NULL, -1);
3439
3440
        /*  The digest algorithm URI is identified with a required Algorithm attribute */
3441
0
        x509Value->digestAlgorithm = xmlGetProp(node, xmlSecAttrAlgorithm);
3442
0
        if(x509Value->digestAlgorithm == NULL) {
3443
0
            xmlSecInvalidNodeAttributeError(node, xmlSecAttrAlgorithm, NULL, "empty");
3444
0
            return(-1);
3445
0
        }
3446
3447
        /* The&lt;dsig11:X509Digest/&gt; element contains a base64-encoded digest of a certificate. */
3448
0
        ret = xmlSecKeyX509DataValueXmlReadBase64Blob(&(x509Value->digest), node, keyInfoCtx);
3449
0
        if(ret < 0) {
3450
0
            xmlSecInternalError("xmlSecKeyX509DataValueXmlReadBase64Blob(digest)", NULL);
3451
0
            return(-1);
3452
0
        }
3453
3454
0
    } else if((keyInfoCtx->flags & XMLSEC_KEYINFO_FLAGS_X509DATA_STOP_ON_UNKNOWN_CHILD) != 0) {
3455
        /* laxi schema validation: ignore unknown nodes */
3456
0
        xmlSecUnexpectedNodeError(node, NULL);
3457
0
        return(-1);
3458
0
    }
3459
3460
    /* done */
3461
0
    return(0);
3462
0
}
3463
3464
static xmlNodePtr
3465
xmlSecKeyX509DataValueXmlWriteBase64Blob(xmlSecBufferPtr buf, xmlNodePtr node,
3466
                                    const xmlChar* nodeName, const xmlChar* nodeNs,
3467
0
                                    int base64LineSize, int addLineBreaks) {
3468
0
    xmlNodePtr child = NULL;
3469
0
    xmlChar *content;
3470
3471
0
    xmlSecAssert2(buf != NULL, NULL);
3472
0
    xmlSecAssert2(node != NULL, NULL);
3473
0
    xmlSecAssert2(nodeName != NULL, NULL);
3474
3475
0
    content = xmlSecBase64Encode(xmlSecBufferGetData(buf), xmlSecBufferGetSize(buf),
3476
0
        base64LineSize);
3477
0
    if(content == NULL) {
3478
0
        xmlSecInternalError("xmlSecBase64Encode", NULL);
3479
0
        goto done;
3480
0
    }
3481
3482
0
    child = xmlSecEnsureEmptyChild(node, nodeName, nodeNs);
3483
0
    if(child == NULL) {
3484
0
        xmlSecInternalError2("xmlSecEnsureEmptyChild()", NULL,
3485
0
            "nodeName=%s", xmlSecErrorsSafeString(nodeName));
3486
0
        goto done;
3487
0
    }
3488
3489
0
    if(addLineBreaks) {
3490
0
        xmlNodeAddContent(child, xmlSecGetDefaultLineFeed());
3491
0
    }
3492
3493
0
    xmlNodeSetContent(child, content);
3494
3495
0
    if(addLineBreaks) {
3496
0
        xmlNodeAddContent(child, xmlSecGetDefaultLineFeed());
3497
0
    }
3498
3499
    /* success */
3500
3501
0
done:
3502
    /* cleanup */
3503
0
    if(content != NULL) {
3504
0
        xmlFree(content);
3505
0
    }
3506
0
    return(child);
3507
0
}
3508
3509
3510
static int
3511
xmlSecKeyX509DataValueXmlWriteString(const xmlChar* content, xmlNodePtr node,
3512
0
                                 const xmlChar* nodeName, const xmlChar* nodeNs) {
3513
0
    xmlNodePtr cur;
3514
3515
0
    xmlSecAssert2(content != NULL, -1);
3516
0
    xmlSecAssert2(node != NULL, -1);
3517
0
    xmlSecAssert2(nodeName != NULL, -1);
3518
3519
0
    cur = xmlSecEnsureEmptyChild(node, nodeName, nodeNs);
3520
0
    if(cur == NULL) {
3521
0
        xmlSecInternalError2("xmlSecEnsureEmptyChild()", NULL,
3522
0
            "nodeName=%s", xmlSecErrorsSafeString(nodeName));
3523
0
        return(-1);
3524
0
    }
3525
3526
0
    xmlNodeSetContent(cur, content);
3527
3528
    /* success */
3529
0
    return(0);
3530
0
}
3531
3532
static int
3533
xmlSecKeyX509DataValueXmlWrite(xmlSecKeyX509DataValuePtr x509Value, xmlNodePtr node,
3534
0
                           int base64LineSize, int addLineBreaks) {
3535
0
    xmlSecAssert2(x509Value != NULL, -1);
3536
0
    xmlSecAssert2(node != NULL, -1);
3537
3538
0
    if(!xmlSecBufferIsEmpty(&(x509Value->cert))) {
3539
0
        xmlNodePtr child;
3540
3541
0
        child = xmlSecKeyX509DataValueXmlWriteBase64Blob(&(x509Value->cert), node,
3542
0
            xmlSecNodeX509Certificate, xmlSecDSigNs,
3543
0
            base64LineSize, addLineBreaks);
3544
0
        if(child == NULL) {
3545
0
            xmlSecInternalError("xmlSecKeyX509DataValueXmlWriteBase64Blob(cert)", NULL);
3546
0
            return(-1);
3547
0
        }
3548
0
    }
3549
0
    if(!xmlSecBufferIsEmpty(&(x509Value->crl))) {
3550
0
        xmlNodePtr child;
3551
3552
0
        child = xmlSecKeyX509DataValueXmlWriteBase64Blob(&(x509Value->crl), node,
3553
0
            xmlSecNodeX509CRL, xmlSecDSigNs,
3554
0
            base64LineSize, addLineBreaks);
3555
0
        if(child == NULL) {
3556
0
            xmlSecInternalError("xmlSecKeyX509DataValueXmlWriteBase64Blob(cert)", NULL);
3557
0
            return(-1);
3558
0
        }
3559
0
    }
3560
0
    if(!xmlSecBufferIsEmpty(&(x509Value->ski))) {
3561
0
        xmlNodePtr child;
3562
3563
0
        child = xmlSecKeyX509DataValueXmlWriteBase64Blob(&(x509Value->ski), node,
3564
0
            xmlSecNodeX509SKI, xmlSecDSigNs,
3565
0
            base64LineSize, addLineBreaks);
3566
0
        if(child == NULL) {
3567
0
            xmlSecInternalError("xmlSecKeyX509DataValueXmlWriteBase64Blob(ski)", NULL);
3568
0
            return(-1);
3569
0
        }
3570
0
    }
3571
0
    if(x509Value->subject != NULL) {
3572
0
        int ret;
3573
3574
0
        ret = xmlSecKeyX509DataValueXmlWriteString(x509Value->subject, node,
3575
0
            xmlSecNodeX509SubjectName, xmlSecDSigNs);
3576
0
        if(ret < 0) {
3577
0
            xmlSecInternalError2("xmlSecKeyX509DataValueXmlWriteString", NULL,
3578
0
                "subject=%s", xmlSecErrorsSafeString(x509Value->subject));
3579
0
            return(-1);
3580
0
        }
3581
0
    }
3582
0
    if((x509Value->issuerName != NULL) && (x509Value->issuerSerial != NULL)) {
3583
0
        xmlNodePtr issuerSerial;
3584
0
        int ret;
3585
3586
0
        issuerSerial = xmlSecEnsureEmptyChild(node, xmlSecNodeX509IssuerSerial, xmlSecDSigNs);
3587
0
        if(issuerSerial == NULL) {
3588
0
            xmlSecInternalError("xmlSecEnsureEmptyChild(xmlSecNodeX509IssuerSerial)", NULL);
3589
0
            return(-1);
3590
0
        }
3591
0
        ret = xmlSecKeyX509DataValueXmlWriteString(x509Value->issuerName, issuerSerial,
3592
0
            xmlSecNodeX509IssuerName, xmlSecDSigNs);
3593
0
        if(ret < 0) {
3594
0
            xmlSecInternalError2("xmlSecKeyX509DataValueXmlWriteString", NULL,
3595
0
                "issuerName=%s", xmlSecErrorsSafeString(x509Value->issuerName));
3596
0
            return(-1);
3597
0
        }
3598
3599
0
        ret = xmlSecKeyX509DataValueXmlWriteString(x509Value->issuerSerial, issuerSerial,
3600
0
            xmlSecNodeX509SerialNumber, xmlSecDSigNs);
3601
0
        if(ret < 0) {
3602
0
            xmlSecInternalError2("xmlSecKeyX509DataValueXmlWriteString", NULL,
3603
0
                "issuerSerial=%s", xmlSecErrorsSafeString(x509Value->issuerSerial));
3604
0
            return(-1);
3605
0
        }
3606
0
    }
3607
0
    if((!xmlSecBufferIsEmpty(&(x509Value->digest))) && (x509Value->digestAlgorithm != NULL)) {
3608
0
        xmlNodePtr child;
3609
3610
0
        child = xmlSecKeyX509DataValueXmlWriteBase64Blob(&(x509Value->digest), node,
3611
0
            xmlSecNodeX509Digest, xmlSecDSig11Ns,
3612
0
            base64LineSize, addLineBreaks);
3613
0
        if(child == NULL) {
3614
0
            xmlSecInternalError("xmlSecKeyX509DataValueXmlWriteBase64Blob(digest)", NULL);
3615
0
            return(-1);
3616
0
        }
3617
3618
0
        if(xmlSetProp(child, xmlSecAttrAlgorithm, x509Value->digestAlgorithm) == NULL) {
3619
0
            xmlSecXmlError2("xmlSetProp", NULL, "name=%s", xmlSecErrorsSafeString(xmlSecAttrAlgorithm));
3620
0
            return(-1);
3621
0
        }
3622
0
    }
3623
0
    return(0);
3624
0
}
3625
3626
3627
#endif /* !defined(XMLSEC_NO_X509) */
3628
3629
/***********************************************************************
3630
 *
3631
 * Keys Data list
3632
 *
3633
 **********************************************************************/
3634
static xmlSecPtrListKlass xmlSecKeyDataListKlass = {
3635
    BAD_CAST "key-data-list",
3636
    (xmlSecPtrDuplicateItemMethod)xmlSecKeyDataDuplicate,       /* xmlSecPtrDuplicateItemMethod duplicateItem; */
3637
    (xmlSecPtrDestroyItemMethod)xmlSecKeyDataDestroy,           /* xmlSecPtrDestroyItemMethod destroyItem; */
3638
    (xmlSecPtrDebugDumpItemMethod)xmlSecKeyDataDebugDump,       /* xmlSecPtrDebugDumpItemMethod debugDumpItem; */
3639
    (xmlSecPtrDebugDumpItemMethod)xmlSecKeyDataDebugXmlDump,    /* xmlSecPtrDebugDumpItemMethod debugXmlDumpItem; */
3640
};
3641
3642
/**
3643
 * xmlSecKeyDataListGetKlass:
3644
 *
3645
 * The key data list klass.
3646
 *
3647
 * Returns: pointer to the key data list klass.
3648
 */
3649
xmlSecPtrListId
3650
0
xmlSecKeyDataListGetKlass(void) {
3651
0
    return(&xmlSecKeyDataListKlass);
3652
0
}
3653
3654
3655
/***********************************************************************
3656
 *
3657
 * Keys Data Ids list
3658
 *
3659
 **********************************************************************/
3660
static xmlSecPtrListKlass xmlSecKeyDataIdListKlass = {
3661
    BAD_CAST "key-data-ids-list",
3662
    NULL,                                                       /* xmlSecPtrDuplicateItemMethod duplicateItem; */
3663
    NULL,                                                       /* xmlSecPtrDestroyItemMethod destroyItem; */
3664
    NULL,                                                       /* xmlSecPtrDebugDumpItemMethod debugDumpItem; */
3665
    NULL,                                                       /* xmlSecPtrDebugDumpItemMethod debugXmlDumpItem; */
3666
};
3667
3668
/**
3669
 * xmlSecKeyDataIdListGetKlass:
3670
 *
3671
 * The key data id list klass.
3672
 *
3673
 * Returns: pointer to the key data id list klass.
3674
 */
3675
xmlSecPtrListId
3676
0
xmlSecKeyDataIdListGetKlass(void) {
3677
0
    return(&xmlSecKeyDataIdListKlass);
3678
0
}
3679
3680
/**
3681
 * xmlSecKeyDataIdListFind:
3682
 * @list:               the pointer to key data ids list.
3683
 * @dataId:             the key data klass.
3684
 *
3685
 * Lookups @dataId in @list.
3686
 *
3687
 * Returns: 1 if @dataId is found in the @list, 0 if not and a negative
3688
 * value if an error occurs.
3689
 */
3690
int
3691
0
xmlSecKeyDataIdListFind(xmlSecPtrListPtr list, xmlSecKeyDataId dataId) {
3692
0
    xmlSecSize i, size;
3693
3694
0
    xmlSecAssert2(xmlSecPtrListCheckId(list, xmlSecKeyDataIdListId), 0);
3695
0
    xmlSecAssert2(dataId != NULL, 0);
3696
3697
0
    size = xmlSecPtrListGetSize(list);
3698
0
    for(i = 0; i < size; ++i) {
3699
0
        if((xmlSecKeyDataId)xmlSecPtrListGetItem(list, i) == dataId) {
3700
0
            return(1);
3701
0
        }
3702
0
    }
3703
0
    return(0);
3704
0
}
3705
3706
/**
3707
 * xmlSecKeyDataIdListFindByNode:
3708
 * @list:               the pointer to key data ids list.
3709
 * @nodeName:           the desired key data klass XML node name.
3710
 * @nodeNs:             the desired key data klass XML node namespace.
3711
 * @usage:              the desired key data usage.
3712
 *
3713
 * Lookups data klass in the list with given @nodeName, @nodeNs and
3714
 * @usage in the @list.
3715
 *
3716
 * Returns: key data klass is found and NULL otherwise.
3717
 */
3718
xmlSecKeyDataId
3719
xmlSecKeyDataIdListFindByNode(xmlSecPtrListPtr list, const xmlChar* nodeName,
3720
0
                            const xmlChar* nodeNs, xmlSecKeyDataUsage usage) {
3721
0
    xmlSecKeyDataId dataId;
3722
0
    xmlSecSize i, size;
3723
3724
0
    xmlSecAssert2(xmlSecPtrListCheckId(list, xmlSecKeyDataIdListId), xmlSecKeyDataIdUnknown);
3725
0
    xmlSecAssert2(nodeName != NULL, xmlSecKeyDataIdUnknown);
3726
3727
0
    size = xmlSecPtrListGetSize(list);
3728
0
    for(i = 0; i < size; ++i) {
3729
0
        dataId = (xmlSecKeyDataId)xmlSecPtrListGetItem(list, i);
3730
0
        xmlSecAssert2(dataId != xmlSecKeyDataIdUnknown, xmlSecKeyDataIdUnknown);
3731
3732
0
        if(((usage & dataId->usage) != 0) &&
3733
0
           xmlStrEqual(nodeName, dataId->dataNodeName) &&
3734
0
           xmlStrEqual(nodeNs, dataId->dataNodeNs)) {
3735
3736
0
           return(dataId);
3737
0
        }
3738
0
    }
3739
0
    return(xmlSecKeyDataIdUnknown);
3740
0
}
3741
3742
/**
3743
 * xmlSecKeyDataIdListFindByHref:
3744
 * @list:               the pointer to key data ids list.
3745
 * @href:               the desired key data klass href.
3746
 * @usage:              the desired key data usage.
3747
 *
3748
 * Lookups data klass in the list with given @href and @usage in @list.
3749
 *
3750
 * Returns: key data klass is found and NULL otherwise.
3751
 */
3752
xmlSecKeyDataId
3753
xmlSecKeyDataIdListFindByHref(xmlSecPtrListPtr list, const xmlChar* href,
3754
0
                            xmlSecKeyDataUsage usage) {
3755
0
    xmlSecKeyDataId dataId;
3756
0
    xmlSecSize i, size;
3757
3758
0
    xmlSecAssert2(xmlSecPtrListCheckId(list, xmlSecKeyDataIdListId), xmlSecKeyDataIdUnknown);
3759
0
    xmlSecAssert2(href != NULL, xmlSecKeyDataIdUnknown);
3760
3761
0
    size = xmlSecPtrListGetSize(list);
3762
0
    for(i = 0; i < size; ++i) {
3763
0
        dataId = (xmlSecKeyDataId)xmlSecPtrListGetItem(list, i);
3764
0
        xmlSecAssert2(dataId != xmlSecKeyDataIdUnknown, xmlSecKeyDataIdUnknown);
3765
3766
0
        if(((usage & dataId->usage) != 0) && (dataId->href != NULL) &&
3767
0
           xmlStrEqual(href, dataId->href)) {
3768
3769
0
           return(dataId);
3770
0
        }
3771
0
    }
3772
0
    return(xmlSecKeyDataIdUnknown);
3773
0
}
3774
3775
/**
3776
 * xmlSecKeyDataIdListFindByName:
3777
 * @list:               the pointer to key data ids list.
3778
 * @name:               the desired key data klass name.
3779
 * @usage:              the desired key data usage.
3780
 *
3781
 * Lookups data klass in the list with given @name and @usage in @list.
3782
 *
3783
 * Returns: key data klass is found and NULL otherwise.
3784
 */
3785
xmlSecKeyDataId
3786
xmlSecKeyDataIdListFindByName(xmlSecPtrListPtr list, const xmlChar* name,
3787
0
                            xmlSecKeyDataUsage usage) {
3788
0
    xmlSecKeyDataId dataId;
3789
0
    xmlSecSize i, size;
3790
3791
0
    xmlSecAssert2(xmlSecPtrListCheckId(list, xmlSecKeyDataIdListId), xmlSecKeyDataIdUnknown);
3792
0
    xmlSecAssert2(name != NULL, xmlSecKeyDataIdUnknown);
3793
3794
0
    size = xmlSecPtrListGetSize(list);
3795
0
    for(i = 0; i < size; ++i) {
3796
0
        dataId = (xmlSecKeyDataId)xmlSecPtrListGetItem(list, i);
3797
0
        xmlSecAssert2(dataId != xmlSecKeyDataIdUnknown, xmlSecKeyDataIdUnknown);
3798
3799
0
        if(((usage & dataId->usage) != 0) && (dataId->name != NULL) &&
3800
0
           xmlStrEqual(name, BAD_CAST dataId->name)) {
3801
3802
0
           return(dataId);
3803
0
        }
3804
0
    }
3805
0
    return(xmlSecKeyDataIdUnknown);
3806
0
}
3807
3808
/**
3809
 * xmlSecKeyDataIdListDebugDump:
3810
 * @list:               the pointer to key data ids list.
3811
 * @output:             the pointer to output FILE.
3812
 *
3813
 * Prints binary key data debug information to @output.
3814
 */
3815
void
3816
0
xmlSecKeyDataIdListDebugDump(xmlSecPtrListPtr list, FILE* output) {
3817
0
    xmlSecKeyDataId dataId;
3818
0
    xmlSecSize i, size;
3819
3820
0
    xmlSecAssert(xmlSecPtrListCheckId(list, xmlSecKeyDataIdListId));
3821
0
    xmlSecAssert(output != NULL);
3822
3823
0
    size = xmlSecPtrListGetSize(list);
3824
0
    for(i = 0; i < size; ++i) {
3825
0
        dataId = (xmlSecKeyDataId)xmlSecPtrListGetItem(list, i);
3826
0
        xmlSecAssert(dataId != NULL);
3827
0
        xmlSecAssert(dataId->name != NULL);
3828
3829
0
        if(i > 0) {
3830
0
            fprintf(output, ",\"%s\"", dataId->name);
3831
0
        } else {
3832
0
            fprintf(output, "\"%s\"", dataId->name);
3833
0
        }
3834
0
    }
3835
0
    fprintf(output, "\n");
3836
0
}
3837
3838
/**
3839
 * xmlSecKeyDataIdListDebugXmlDump:
3840
 * @list:               the pointer to key data ids list.
3841
 * @output:             the pointer to output FILE.
3842
 *
3843
 * Prints binary key data debug information to @output in XML format.
3844
 */
3845
void
3846
0
xmlSecKeyDataIdListDebugXmlDump(xmlSecPtrListPtr list, FILE* output) {
3847
0
    xmlSecKeyDataId dataId;
3848
0
    xmlSecSize i, size;
3849
3850
0
    xmlSecAssert(xmlSecPtrListCheckId(list, xmlSecKeyDataIdListId));
3851
0
    xmlSecAssert(output != NULL);
3852
3853
0
    fprintf(output, "<KeyDataIdsList>\n");
3854
0
    size = xmlSecPtrListGetSize(list);
3855
0
    for(i = 0; i < size; ++i) {
3856
0
        dataId = (xmlSecKeyDataId)xmlSecPtrListGetItem(list, i);
3857
0
        xmlSecAssert(dataId != NULL);
3858
0
        xmlSecAssert(dataId->name != NULL);
3859
3860
0
        fprintf(output, "<DataId name=\"");
3861
0
        xmlSecPrintXmlString(output, dataId->name);
3862
0
        fprintf(output, "\"/>");
3863
0
    }
3864
0
    fprintf(output, "</KeyDataIdsList>\n");
3865
0
}
3866
3867
/**************************************************************************
3868
 *
3869
 * xmlSecKeyDataStore functions
3870
 *
3871
 *************************************************************************/
3872
/**
3873
 * xmlSecKeyDataStoreCreate:
3874
 * @id:                 the store id.
3875
 *
3876
 * Creates new key data store of the specified klass @id. Caller is responsible
3877
 * for freeing returned object with #xmlSecKeyDataStoreDestroy function.
3878
 *
3879
 * Returns: the pointer to newly allocated key data store structure
3880
 * or NULL if an error occurs.
3881
 */
3882
xmlSecKeyDataStorePtr
3883
0
xmlSecKeyDataStoreCreate(xmlSecKeyDataStoreId id)  {
3884
0
    xmlSecKeyDataStorePtr store;
3885
0
    int ret;
3886
3887
0
    xmlSecAssert2(id != NULL, NULL);
3888
0
    xmlSecAssert2(id->objSize > 0, NULL);
3889
3890
    /* Allocate a new xmlSecKeyDataStore and fill the fields. */
3891
0
    store = (xmlSecKeyDataStorePtr)xmlMalloc(id->objSize);
3892
0
    if(store == NULL) {
3893
0
        xmlSecMallocError(id->objSize,
3894
0
                          xmlSecKeyDataStoreKlassGetName(id));
3895
0
        return(NULL);
3896
0
    }
3897
0
    memset(store, 0, id->objSize);
3898
0
    store->id = id;
3899
3900
0
    if(id->initialize != NULL) {
3901
0
        ret = (id->initialize)(store);
3902
0
        if(ret < 0) {
3903
0
            xmlSecInternalError("id->initialize",
3904
0
                                xmlSecKeyDataStoreKlassGetName(id));
3905
0
            xmlSecKeyDataStoreDestroy(store);
3906
0
            return(NULL);
3907
0
        }
3908
0
    }
3909
3910
0
    return(store);
3911
0
}
3912
3913
/**
3914
 * xmlSecKeyDataStoreDestroy:
3915
 * @store:              the pointer to the key data store..
3916
 *
3917
 * Destroys the key data store created with #xmlSecKeyDataStoreCreate
3918
 * function.
3919
 */
3920
void
3921
0
xmlSecKeyDataStoreDestroy(xmlSecKeyDataStorePtr store) {
3922
0
    xmlSecAssert(xmlSecKeyDataStoreIsValid(store));
3923
0
    xmlSecAssert(store->id->objSize > 0);
3924
3925
0
    if(store->id->finalize != NULL) {
3926
0
        (store->id->finalize)(store);
3927
0
    }
3928
0
    memset(store, 0, store->id->objSize);
3929
0
    xmlFree(store);
3930
0
}
3931
3932
/***********************************************************************
3933
 *
3934
 * Keys Data Store list
3935
 *
3936
 **********************************************************************/
3937
static xmlSecPtrListKlass xmlSecKeyDataStorePtrListKlass = {
3938
    BAD_CAST "keys-data-store-list",
3939
    NULL,                                                       /* xmlSecPtrDuplicateItemMethod duplicateItem; */
3940
    (xmlSecPtrDestroyItemMethod)xmlSecKeyDataStoreDestroy,      /* xmlSecPtrDestroyItemMethod destroyItem; */
3941
    NULL,                                                       /* xmlSecPtrDebugDumpItemMethod debugDumpItem; */
3942
    NULL,                                                       /* xmlSecPtrDebugDumpItemMethod debugXmlDumpItem; */
3943
};
3944
3945
/**
3946
 * xmlSecKeyDataStorePtrListGetKlass:
3947
 *
3948
 * Key data stores list.
3949
 *
3950
 * Returns: key data stores list klass.
3951
 */
3952
xmlSecPtrListId
3953
0
xmlSecKeyDataStorePtrListGetKlass(void) {
3954
0
    return(&xmlSecKeyDataStorePtrListKlass);
3955
0
}
3956
3957
/**
3958
 * xmlSecImportSetPersistKey:
3959
 *
3960
 * Sets global flag to import keys to persistent storage (MSCrypto and MSCNG).
3961
 * Also see PKCS12_NO_PERSIST_KEY.
3962
 *
3963
 */
3964
0
void xmlSecImportSetPersistKey(void) {
3965
0
    xmlSecImportPersistKey = 1;
3966
0
}
3967
3968
/**
3969
 * xmlSecImportGetPersistKey:
3970
 *
3971
 * Gets global flag to import keys to persistent storage (MSCrypto and MSCNG).
3972
 * Also see PKCS12_NO_PERSIST_KEY.
3973
 *
3974
 * Returns: 1 if keys should be imported into persistent storage and 0 otherwise.
3975
 */
3976
0
int xmlSecImportGetPersistKey(void) {
3977
0
    return xmlSecImportPersistKey;
3978
0
}