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