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-2016 Aleksey Sanin <aleksey@aleksey.com>. All Rights Reserved.
9  */
10 /**
11  * SECTION:symkeys
12  * @Short_description: Symmetric keys implementation for GCrypt.
13  * @Stability: Private
14  *
15  */
16 
17 #include "globals.h"
18 
19 #include <stdlib.h>
20 #include <stdio.h>
21 #include <string.h>
22 
23 #include <xmlsec/xmlsec.h>
24 #include <xmlsec/xmltree.h>
25 #include <xmlsec/keys.h>
26 #include <xmlsec/keyinfo.h>
27 #include <xmlsec/transforms.h>
28 #include <xmlsec/errors.h>
29 
30 #include <xmlsec/gcrypt/crypto.h>
31 
32 
33 /*****************************************************************************
34  *
35  * Symmetic (binary) keys - just a wrapper for xmlSecKeyDataBinary
36  *
37  ****************************************************************************/
38 static int      xmlSecGCryptSymKeyDataInitialize        (xmlSecKeyDataPtr data);
39 static int      xmlSecGCryptSymKeyDataDuplicate         (xmlSecKeyDataPtr dst,
40                                                          xmlSecKeyDataPtr src);
41 static void     xmlSecGCryptSymKeyDataFinalize          (xmlSecKeyDataPtr data);
42 static int      xmlSecGCryptSymKeyDataXmlRead           (xmlSecKeyDataId id,
43                                                          xmlSecKeyPtr key,
44                                                          xmlNodePtr node,
45                                                          xmlSecKeyInfoCtxPtr keyInfoCtx);
46 static int      xmlSecGCryptSymKeyDataXmlWrite          (xmlSecKeyDataId id,
47                                                          xmlSecKeyPtr key,
48                                                          xmlNodePtr node,
49                                                          xmlSecKeyInfoCtxPtr keyInfoCtx);
50 static int      xmlSecGCryptSymKeyDataBinRead           (xmlSecKeyDataId id,
51                                                          xmlSecKeyPtr key,
52                                                          const xmlSecByte* buf,
53                                                          xmlSecSize bufSize,
54                                                          xmlSecKeyInfoCtxPtr keyInfoCtx);
55 static int      xmlSecGCryptSymKeyDataBinWrite          (xmlSecKeyDataId id,
56                                                          xmlSecKeyPtr key,
57                                                          xmlSecByte** buf,
58                                                          xmlSecSize* bufSize,
59                                                          xmlSecKeyInfoCtxPtr keyInfoCtx);
60 static int      xmlSecGCryptSymKeyDataGenerate          (xmlSecKeyDataPtr data,
61                                                          xmlSecSize sizeBits,
62                                                          xmlSecKeyDataType type);
63 
64 static xmlSecKeyDataType xmlSecGCryptSymKeyDataGetType  (xmlSecKeyDataPtr data);
65 static xmlSecSize        xmlSecGCryptSymKeyDataGetSize  (xmlSecKeyDataPtr data);
66 static void     xmlSecGCryptSymKeyDataDebugDump         (xmlSecKeyDataPtr data,
67                                                          FILE* output);
68 static void     xmlSecGCryptSymKeyDataDebugXmlDump      (xmlSecKeyDataPtr data,
69                                                          FILE* output);
70 static int      xmlSecGCryptSymKeyDataKlassCheck        (xmlSecKeyDataKlass* klass);
71 
72 #define xmlSecGCryptSymKeyDataCheckId(data) \
73     (xmlSecKeyDataIsValid((data)) && \
74      xmlSecGCryptSymKeyDataKlassCheck((data)->id))
75 
76 static int
xmlSecGCryptSymKeyDataInitialize(xmlSecKeyDataPtr data)77 xmlSecGCryptSymKeyDataInitialize(xmlSecKeyDataPtr data) {
78     xmlSecAssert2(xmlSecGCryptSymKeyDataCheckId(data), -1);
79 
80     return(xmlSecKeyDataBinaryValueInitialize(data));
81 }
82 
83 static int
xmlSecGCryptSymKeyDataDuplicate(xmlSecKeyDataPtr dst,xmlSecKeyDataPtr src)84 xmlSecGCryptSymKeyDataDuplicate(xmlSecKeyDataPtr dst, xmlSecKeyDataPtr src) {
85     xmlSecAssert2(xmlSecGCryptSymKeyDataCheckId(dst), -1);
86     xmlSecAssert2(xmlSecGCryptSymKeyDataCheckId(src), -1);
87     xmlSecAssert2(dst->id == src->id, -1);
88 
89     return(xmlSecKeyDataBinaryValueDuplicate(dst, src));
90 }
91 
92 static void
xmlSecGCryptSymKeyDataFinalize(xmlSecKeyDataPtr data)93 xmlSecGCryptSymKeyDataFinalize(xmlSecKeyDataPtr data) {
94     xmlSecAssert(xmlSecGCryptSymKeyDataCheckId(data));
95 
96     xmlSecKeyDataBinaryValueFinalize(data);
97 }
98 
99 static int
xmlSecGCryptSymKeyDataXmlRead(xmlSecKeyDataId id,xmlSecKeyPtr key,xmlNodePtr node,xmlSecKeyInfoCtxPtr keyInfoCtx)100 xmlSecGCryptSymKeyDataXmlRead(xmlSecKeyDataId id, xmlSecKeyPtr key,
101                                xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx) {
102     xmlSecAssert2(xmlSecGCryptSymKeyDataKlassCheck(id), -1);
103 
104     return(xmlSecKeyDataBinaryValueXmlRead(id, key, node, keyInfoCtx));
105 }
106 
107 static int
xmlSecGCryptSymKeyDataXmlWrite(xmlSecKeyDataId id,xmlSecKeyPtr key,xmlNodePtr node,xmlSecKeyInfoCtxPtr keyInfoCtx)108 xmlSecGCryptSymKeyDataXmlWrite(xmlSecKeyDataId id, xmlSecKeyPtr key,
109                                     xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx) {
110     xmlSecAssert2(xmlSecGCryptSymKeyDataKlassCheck(id), -1);
111 
112     return(xmlSecKeyDataBinaryValueXmlWrite(id, key, node, keyInfoCtx));
113 }
114 
115 static int
xmlSecGCryptSymKeyDataBinRead(xmlSecKeyDataId id,xmlSecKeyPtr key,const xmlSecByte * buf,xmlSecSize bufSize,xmlSecKeyInfoCtxPtr keyInfoCtx)116 xmlSecGCryptSymKeyDataBinRead(xmlSecKeyDataId id, xmlSecKeyPtr key,
117                                     const xmlSecByte* buf, xmlSecSize bufSize,
118                                     xmlSecKeyInfoCtxPtr keyInfoCtx) {
119     xmlSecAssert2(xmlSecGCryptSymKeyDataKlassCheck(id), -1);
120 
121     return(xmlSecKeyDataBinaryValueBinRead(id, key, buf, bufSize, keyInfoCtx));
122 }
123 
124 static int
xmlSecGCryptSymKeyDataBinWrite(xmlSecKeyDataId id,xmlSecKeyPtr key,xmlSecByte ** buf,xmlSecSize * bufSize,xmlSecKeyInfoCtxPtr keyInfoCtx)125 xmlSecGCryptSymKeyDataBinWrite(xmlSecKeyDataId id, xmlSecKeyPtr key,
126                                     xmlSecByte** buf, xmlSecSize* bufSize,
127                                     xmlSecKeyInfoCtxPtr keyInfoCtx) {
128     xmlSecAssert2(xmlSecGCryptSymKeyDataKlassCheck(id), -1);
129 
130     return(xmlSecKeyDataBinaryValueBinWrite(id, key, buf, bufSize, keyInfoCtx));
131 }
132 
133 static int
xmlSecGCryptSymKeyDataGenerate(xmlSecKeyDataPtr data,xmlSecSize sizeBits,xmlSecKeyDataType type ATTRIBUTE_UNUSED)134 xmlSecGCryptSymKeyDataGenerate(xmlSecKeyDataPtr data, xmlSecSize sizeBits, xmlSecKeyDataType type ATTRIBUTE_UNUSED) {
135     xmlSecBufferPtr buffer;
136 
137     xmlSecAssert2(xmlSecGCryptSymKeyDataCheckId(data), -1);
138     xmlSecAssert2(sizeBits > 0, -1);
139 
140     buffer = xmlSecKeyDataBinaryValueGetBuffer(data);
141     xmlSecAssert2(buffer != NULL, -1);
142 
143     return(xmlSecGCryptGenerateRandom(buffer, (sizeBits + 7) / 8));
144 }
145 
146 static xmlSecKeyDataType
xmlSecGCryptSymKeyDataGetType(xmlSecKeyDataPtr data)147 xmlSecGCryptSymKeyDataGetType(xmlSecKeyDataPtr data) {
148     xmlSecBufferPtr buffer;
149 
150     xmlSecAssert2(xmlSecGCryptSymKeyDataCheckId(data), xmlSecKeyDataTypeUnknown);
151 
152     buffer = xmlSecKeyDataBinaryValueGetBuffer(data);
153     xmlSecAssert2(buffer != NULL, xmlSecKeyDataTypeUnknown);
154 
155     return((xmlSecBufferGetSize(buffer) > 0) ? xmlSecKeyDataTypeSymmetric : xmlSecKeyDataTypeUnknown);
156 }
157 
158 static xmlSecSize
xmlSecGCryptSymKeyDataGetSize(xmlSecKeyDataPtr data)159 xmlSecGCryptSymKeyDataGetSize(xmlSecKeyDataPtr data) {
160     xmlSecAssert2(xmlSecGCryptSymKeyDataCheckId(data), 0);
161 
162     return(xmlSecKeyDataBinaryValueGetSize(data));
163 }
164 
165 static void
xmlSecGCryptSymKeyDataDebugDump(xmlSecKeyDataPtr data,FILE * output)166 xmlSecGCryptSymKeyDataDebugDump(xmlSecKeyDataPtr data, FILE* output) {
167     xmlSecAssert(xmlSecGCryptSymKeyDataCheckId(data));
168 
169     xmlSecKeyDataBinaryValueDebugDump(data, output);
170 }
171 
172 static void
xmlSecGCryptSymKeyDataDebugXmlDump(xmlSecKeyDataPtr data,FILE * output)173 xmlSecGCryptSymKeyDataDebugXmlDump(xmlSecKeyDataPtr data, FILE* output) {
174     xmlSecAssert(xmlSecGCryptSymKeyDataCheckId(data));
175 
176     xmlSecKeyDataBinaryValueDebugXmlDump(data, output);
177 }
178 
179 static int
xmlSecGCryptSymKeyDataKlassCheck(xmlSecKeyDataKlass * klass)180 xmlSecGCryptSymKeyDataKlassCheck(xmlSecKeyDataKlass* klass) {
181 #ifndef XMLSEC_NO_DES
182     if(klass == xmlSecGCryptKeyDataDesId) {
183         return(1);
184     }
185 #endif /* XMLSEC_NO_DES */
186 
187 #ifndef XMLSEC_NO_AES
188     if(klass == xmlSecGCryptKeyDataAesId) {
189         return(1);
190     }
191 #endif /* XMLSEC_NO_AES */
192 
193 #ifndef XMLSEC_NO_HMAC
194     if(klass == xmlSecGCryptKeyDataHmacId) {
195         return(1);
196     }
197 #endif /* XMLSEC_NO_HMAC */
198 
199     return(0);
200 }
201 
202 #ifndef XMLSEC_NO_AES
203 /**************************************************************************
204  *
205  * <xmlsec:AESKeyValue> processing
206  *
207  *************************************************************************/
208 static xmlSecKeyDataKlass xmlSecGCryptKeyDataAesKlass = {
209     sizeof(xmlSecKeyDataKlass),
210     xmlSecKeyDataBinarySize,
211 
212     /* data */
213     xmlSecNameAESKeyValue,
214     xmlSecKeyDataUsageKeyValueNode | xmlSecKeyDataUsageRetrievalMethodNodeXml,
215                                                 /* xmlSecKeyDataUsage usage; */
216     xmlSecHrefAESKeyValue,                      /* const xmlChar* href; */
217     xmlSecNodeAESKeyValue,                      /* const xmlChar* dataNodeName; */
218     xmlSecNs,                                   /* const xmlChar* dataNodeNs; */
219 
220     /* constructors/destructor */
221     xmlSecGCryptSymKeyDataInitialize,           /* xmlSecKeyDataInitializeMethod initialize; */
222     xmlSecGCryptSymKeyDataDuplicate,            /* xmlSecKeyDataDuplicateMethod duplicate; */
223     xmlSecGCryptSymKeyDataFinalize,             /* xmlSecKeyDataFinalizeMethod finalize; */
224     xmlSecGCryptSymKeyDataGenerate,             /* xmlSecKeyDataGenerateMethod generate; */
225 
226     /* get info */
227     xmlSecGCryptSymKeyDataGetType,              /* xmlSecKeyDataGetTypeMethod getType; */
228     xmlSecGCryptSymKeyDataGetSize,              /* xmlSecKeyDataGetSizeMethod getSize; */
229     NULL,                                       /* xmlSecKeyDataGetIdentifier getIdentifier; */
230 
231     /* read/write */
232     xmlSecGCryptSymKeyDataXmlRead,              /* xmlSecKeyDataXmlReadMethod xmlRead; */
233     xmlSecGCryptSymKeyDataXmlWrite,             /* xmlSecKeyDataXmlWriteMethod xmlWrite; */
234     xmlSecGCryptSymKeyDataBinRead,              /* xmlSecKeyDataBinReadMethod binRead; */
235     xmlSecGCryptSymKeyDataBinWrite,             /* xmlSecKeyDataBinWriteMethod binWrite; */
236 
237     /* debug */
238     xmlSecGCryptSymKeyDataDebugDump,            /* xmlSecKeyDataDebugDumpMethod debugDump; */
239     xmlSecGCryptSymKeyDataDebugXmlDump,         /* xmlSecKeyDataDebugDumpMethod debugXmlDump; */
240 
241     /* reserved for the future */
242     NULL,                                       /* void* reserved0; */
243     NULL,                                       /* void* reserved1; */
244 };
245 
246 /**
247  * xmlSecGCryptKeyDataAesGetKlass:
248  *
249  * The AES key data klass.
250  *
251  * Returns: AES key data klass.
252  */
253 xmlSecKeyDataId
xmlSecGCryptKeyDataAesGetKlass(void)254 xmlSecGCryptKeyDataAesGetKlass(void) {
255     return(&xmlSecGCryptKeyDataAesKlass);
256 }
257 
258 /**
259  * xmlSecGCryptKeyDataAesSet:
260  * @data:               the pointer to AES key data.
261  * @buf:                the pointer to key value.
262  * @bufSize:            the key value size (in bytes).
263  *
264  * Sets the value of AES key data.
265  *
266  * Returns: 0 on success or a negative value if an error occurs.
267  */
268 int
xmlSecGCryptKeyDataAesSet(xmlSecKeyDataPtr data,const xmlSecByte * buf,xmlSecSize bufSize)269 xmlSecGCryptKeyDataAesSet(xmlSecKeyDataPtr data, const xmlSecByte* buf, xmlSecSize bufSize) {
270     xmlSecBufferPtr buffer;
271 
272     xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecGCryptKeyDataAesId), -1);
273     xmlSecAssert2(buf != NULL, -1);
274     xmlSecAssert2(bufSize > 0, -1);
275 
276     buffer = xmlSecKeyDataBinaryValueGetBuffer(data);
277     xmlSecAssert2(buffer != NULL, -1);
278 
279     return(xmlSecBufferSetData(buffer, buf, bufSize));
280 }
281 #endif /* XMLSEC_NO_AES */
282 
283 #ifndef XMLSEC_NO_DES
284 /**************************************************************************
285  *
286  * <xmlsec:DESKeyValue> processing
287  *
288  *************************************************************************/
289 static xmlSecKeyDataKlass xmlSecGCryptKeyDataDesKlass = {
290     sizeof(xmlSecKeyDataKlass),
291     xmlSecKeyDataBinarySize,
292 
293     /* data */
294     xmlSecNameDESKeyValue,
295     xmlSecKeyDataUsageKeyValueNode | xmlSecKeyDataUsageRetrievalMethodNodeXml,
296                                                 /* xmlSecKeyDataUsage usage; */
297     xmlSecHrefDESKeyValue,                      /* const xmlChar* href; */
298     xmlSecNodeDESKeyValue,                      /* const xmlChar* dataNodeName; */
299     xmlSecNs,                                   /* const xmlChar* dataNodeNs; */
300 
301     /* constructors/destructor */
302     xmlSecGCryptSymKeyDataInitialize,           /* xmlSecKeyDataInitializeMethod initialize; */
303     xmlSecGCryptSymKeyDataDuplicate,            /* xmlSecKeyDataDuplicateMethod duplicate; */
304     xmlSecGCryptSymKeyDataFinalize,             /* xmlSecKeyDataFinalizeMethod finalize; */
305     xmlSecGCryptSymKeyDataGenerate,             /* xmlSecKeyDataGenerateMethod generate; */
306 
307     /* get info */
308     xmlSecGCryptSymKeyDataGetType,              /* xmlSecKeyDataGetTypeMethod getType; */
309     xmlSecGCryptSymKeyDataGetSize,              /* xmlSecKeyDataGetSizeMethod getSize; */
310     NULL,                                       /* xmlSecKeyDataGetIdentifier getIdentifier; */
311 
312     /* read/write */
313     xmlSecGCryptSymKeyDataXmlRead,              /* xmlSecKeyDataXmlReadMethod xmlRead; */
314     xmlSecGCryptSymKeyDataXmlWrite,             /* xmlSecKeyDataXmlWriteMethod xmlWrite; */
315     xmlSecGCryptSymKeyDataBinRead,              /* xmlSecKeyDataBinReadMethod binRead; */
316     xmlSecGCryptSymKeyDataBinWrite,             /* xmlSecKeyDataBinWriteMethod binWrite; */
317 
318     /* debug */
319     xmlSecGCryptSymKeyDataDebugDump,            /* xmlSecKeyDataDebugDumpMethod debugDump; */
320     xmlSecGCryptSymKeyDataDebugXmlDump,         /* xmlSecKeyDataDebugDumpMethod debugXmlDump; */
321 
322     /* reserved for the future */
323     NULL,                                       /* void* reserved0; */
324     NULL,                                       /* void* reserved1; */
325 };
326 
327 /**
328  * xmlSecGCryptKeyDataDesGetKlass:
329  *
330  * The DES key data klass.
331  *
332  * Returns: DES key data klass.
333  */
334 xmlSecKeyDataId
xmlSecGCryptKeyDataDesGetKlass(void)335 xmlSecGCryptKeyDataDesGetKlass(void) {
336     return(&xmlSecGCryptKeyDataDesKlass);
337 }
338 
339 /**
340  * xmlSecGCryptKeyDataDesSet:
341  * @data:               the pointer to DES key data.
342  * @buf:                the pointer to key value.
343  * @bufSize:            the key value size (in bytes).
344  *
345  * Sets the value of DES key data.
346  *
347  * Returns: 0 on success or a negative value if an error occurs.
348  */
349 int
xmlSecGCryptKeyDataDesSet(xmlSecKeyDataPtr data,const xmlSecByte * buf,xmlSecSize bufSize)350 xmlSecGCryptKeyDataDesSet(xmlSecKeyDataPtr data, const xmlSecByte* buf, xmlSecSize bufSize) {
351     xmlSecBufferPtr buffer;
352 
353     xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecGCryptKeyDataDesId), -1);
354     xmlSecAssert2(buf != NULL, -1);
355     xmlSecAssert2(bufSize > 0, -1);
356 
357     buffer = xmlSecKeyDataBinaryValueGetBuffer(data);
358     xmlSecAssert2(buffer != NULL, -1);
359 
360     return(xmlSecBufferSetData(buffer, buf, bufSize));
361 }
362 
363 #endif /* XMLSEC_NO_DES */
364 
365 #ifndef XMLSEC_NO_HMAC
366 /**************************************************************************
367  *
368  * <xmlsec:HMACKeyValue> processing
369  *
370  *************************************************************************/
371 static xmlSecKeyDataKlass xmlSecGCryptKeyDataHmacKlass = {
372     sizeof(xmlSecKeyDataKlass),
373     xmlSecKeyDataBinarySize,
374 
375     /* data */
376     xmlSecNameHMACKeyValue,
377     xmlSecKeyDataUsageKeyValueNode | xmlSecKeyDataUsageRetrievalMethodNodeXml,
378                                                 /* xmlSecKeyDataUsage usage; */
379     xmlSecHrefHMACKeyValue,                     /* const xmlChar* href; */
380     xmlSecNodeHMACKeyValue,                     /* const xmlChar* dataNodeName; */
381     xmlSecNs,                                   /* const xmlChar* dataNodeNs; */
382 
383     /* constructors/destructor */
384     xmlSecGCryptSymKeyDataInitialize,           /* xmlSecKeyDataInitializeMethod initialize; */
385     xmlSecGCryptSymKeyDataDuplicate,            /* xmlSecKeyDataDuplicateMethod duplicate; */
386     xmlSecGCryptSymKeyDataFinalize,             /* xmlSecKeyDataFinalizeMethod finalize; */
387     xmlSecGCryptSymKeyDataGenerate,             /* xmlSecKeyDataGenerateMethod generate; */
388 
389     /* get info */
390     xmlSecGCryptSymKeyDataGetType,              /* xmlSecKeyDataGetTypeMethod getType; */
391     xmlSecGCryptSymKeyDataGetSize,              /* xmlSecKeyDataGetSizeMethod getSize; */
392     NULL,                                       /* xmlSecKeyDataGetIdentifier getIdentifier; */
393 
394     /* read/write */
395     xmlSecGCryptSymKeyDataXmlRead,              /* xmlSecKeyDataXmlReadMethod xmlRead; */
396     xmlSecGCryptSymKeyDataXmlWrite,             /* xmlSecKeyDataXmlWriteMethod xmlWrite; */
397     xmlSecGCryptSymKeyDataBinRead,              /* xmlSecKeyDataBinReadMethod binRead; */
398     xmlSecGCryptSymKeyDataBinWrite,             /* xmlSecKeyDataBinWriteMethod binWrite; */
399 
400     /* debug */
401     xmlSecGCryptSymKeyDataDebugDump,            /* xmlSecKeyDataDebugDumpMethod debugDump; */
402     xmlSecGCryptSymKeyDataDebugXmlDump,         /* xmlSecKeyDataDebugDumpMethod debugXmlDump; */
403 
404     /* reserved for the future */
405     NULL,                                       /* void* reserved0; */
406     NULL,                                       /* void* reserved1; */
407 };
408 
409 /**
410  * xmlSecGCryptKeyDataHmacGetKlass:
411  *
412  * The HMAC key data klass.
413  *
414  * Returns: HMAC key data klass.
415  */
416 xmlSecKeyDataId
xmlSecGCryptKeyDataHmacGetKlass(void)417 xmlSecGCryptKeyDataHmacGetKlass(void) {
418     return(&xmlSecGCryptKeyDataHmacKlass);
419 }
420 
421 /**
422  * xmlSecGCryptKeyDataHmacSet:
423  * @data:               the pointer to HMAC key data.
424  * @buf:                the pointer to key value.
425  * @bufSize:            the key value size (in bytes).
426  *
427  * Sets the value of HMAC key data.
428  *
429  * Returns: 0 on success or a negative value if an error occurs.
430  */
431 int
xmlSecGCryptKeyDataHmacSet(xmlSecKeyDataPtr data,const xmlSecByte * buf,xmlSecSize bufSize)432 xmlSecGCryptKeyDataHmacSet(xmlSecKeyDataPtr data, const xmlSecByte* buf, xmlSecSize bufSize) {
433     xmlSecBufferPtr buffer;
434 
435     xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecGCryptKeyDataHmacId), -1);
436     xmlSecAssert2(buf != NULL, -1);
437     xmlSecAssert2(bufSize > 0, -1);
438 
439     buffer = xmlSecKeyDataBinaryValueGetBuffer(data);
440     xmlSecAssert2(buffer != NULL, -1);
441 
442     return(xmlSecBufferSetData(buffer, buf, bufSize));
443 }
444 
445 #endif /* XMLSEC_NO_HMAC */
446 
447