Git init
[external/xmlsec1.git] / src / mscrypto / symkeys.c
1 /** 
2  *
3  * XMLSec library
4  * 
5  * DES Algorithm support
6  * 
7  * This is free software; see Copyright file in the source
8  * distribution for preciese wording.
9  * 
10  * Copyrigth (C) 2003 Cordys R&D BV, All rights reserved.
11  */
12 #include "globals.h"
13
14 #include <stdlib.h>
15 #include <stdio.h>
16 #include <string.h>
17
18 #include <windows.h>
19 #include <wincrypt.h>
20
21 #include <xmlsec/xmlsec.h>
22 #include <xmlsec/xmltree.h>
23 #include <xmlsec/keys.h>
24 #include <xmlsec/keyinfo.h>
25 #include <xmlsec/transforms.h>
26 #include <xmlsec/errors.h>
27
28 #include <xmlsec/mscrypto/crypto.h>
29
30 /*****************************************************************************
31  * 
32  * Symmetic (binary) keys - just a wrapper for xmlSecKeyDataBinary
33  *
34  ****************************************************************************/
35 static int      xmlSecMSCryptoSymKeyDataInitialize      (xmlSecKeyDataPtr data);
36 static int      xmlSecMSCryptoSymKeyDataDuplicate       (xmlSecKeyDataPtr dst,
37                                                          xmlSecKeyDataPtr src);
38 static void     xmlSecMSCryptoSymKeyDataFinalize        (xmlSecKeyDataPtr data);
39 static int      xmlSecMSCryptoSymKeyDataXmlRead         (xmlSecKeyDataId id,
40                                                          xmlSecKeyPtr key,
41                                                          xmlNodePtr node,
42                                                          xmlSecKeyInfoCtxPtr keyInfoCtx);
43 static int      xmlSecMSCryptoSymKeyDataXmlWrite        (xmlSecKeyDataId id,
44                                                          xmlSecKeyPtr key,
45                                                          xmlNodePtr node,
46                                                          xmlSecKeyInfoCtxPtr keyInfoCtx);
47 static int      xmlSecMSCryptoSymKeyDataBinRead         (xmlSecKeyDataId id,
48                                                          xmlSecKeyPtr key,
49                                                          const unsigned char* buf,
50                                                          size_t bufSize,
51                                                          xmlSecKeyInfoCtxPtr keyInfoCtx);
52 static int      xmlSecMSCryptoSymKeyDataBinWrite        (xmlSecKeyDataId id,
53                                                          xmlSecKeyPtr key,
54                                                          unsigned char** buf,
55                                                          size_t* bufSize,
56                                                          xmlSecKeyInfoCtxPtr keyInfoCtx);
57 static int      xmlSecMSCryptoSymKeyDataGenerate        (xmlSecKeyDataPtr data,
58                                                          size_t sizeBits,
59                                                          xmlSecKeyDataType type);
60
61 static xmlSecKeyDataType xmlSecMSCryptoSymKeyDataGetType(xmlSecKeyDataPtr data);
62 static size_t   xmlSecMSCryptoSymKeyDataGetSize         (xmlSecKeyDataPtr data);
63 static void     xmlSecMSCryptoSymKeyDataDebugDump       (xmlSecKeyDataPtr data,
64                                                          FILE* output);
65 static void     xmlSecMSCryptoSymKeyDataDebugXmlDump    (xmlSecKeyDataPtr data,
66                                                          FILE* output);
67 static int      xmlSecMSCryptoSymKeyDataKlassCheck      (xmlSecKeyDataKlass* klass);
68
69 #ifndef XMLSEC_NO_AES
70 /**************************************************************************
71  *
72  * <xmlsec:AESKeyValue> processing
73  *
74  *************************************************************************/
75 static xmlSecKeyDataKlass xmlSecMSCryptoKeyDataAesKlass = {
76     sizeof(xmlSecKeyDataKlass),
77     xmlSecKeyDataBinarySize,
78
79     /* data */
80     xmlSecNameAESKeyValue,
81     xmlSecKeyDataUsageKeyValueNode | xmlSecKeyDataUsageRetrievalMethodNodeXml, 
82                                                 /* xmlSecKeyDataUsage usage; */
83     xmlSecHrefAESKeyValue,                      /* const xmlChar* href; */
84     xmlSecNodeAESKeyValue,                      /* const xmlChar* dataNodeName; */
85     xmlSecNs,                                   /* const xmlChar* dataNodeNs; */
86     
87     /* constructors/destructor */
88     xmlSecMSCryptoSymKeyDataInitialize,         /* xmlSecKeyDataInitializeMethod initialize; */
89     xmlSecMSCryptoSymKeyDataDuplicate,          /* xmlSecKeyDataDuplicateMethod duplicate; */
90     xmlSecMSCryptoSymKeyDataFinalize,           /* xmlSecKeyDataFinalizeMethod finalize; */
91     xmlSecMSCryptoSymKeyDataGenerate,           /* xmlSecKeyDataGenerateMethod generate; */
92     
93     /* get info */
94     xmlSecMSCryptoSymKeyDataGetType,            /* xmlSecKeyDataGetTypeMethod getType; */
95     xmlSecMSCryptoSymKeyDataGetSize,            /* xmlSecKeyDataGetSizeMethod getSize; */
96     NULL,                                       /* xmlSecKeyDataGetIdentifier getIdentifier; */
97
98     /* read/write */
99     xmlSecMSCryptoSymKeyDataXmlRead,            /* xmlSecKeyDataXmlReadMethod xmlRead; */
100     xmlSecMSCryptoSymKeyDataXmlWrite,           /* xmlSecKeyDataXmlWriteMethod xmlWrite; */
101     xmlSecMSCryptoSymKeyDataBinRead,            /* xmlSecKeyDataBinReadMethod binRead; */
102     xmlSecMSCryptoSymKeyDataBinWrite,           /* xmlSecKeyDataBinWriteMethod binWrite; */
103
104     /* debug */
105     xmlSecMSCryptoSymKeyDataDebugDump,          /* xmlSecKeyDataDebugDumpMethod debugDump; */
106     xmlSecMSCryptoSymKeyDataDebugXmlDump,       /* xmlSecKeyDataDebugDumpMethod debugXmlDump; */
107
108     /* reserved for the future */
109     NULL,                                       /* void* reserved0; */
110     NULL,                                       /* void* reserved1; */
111 };
112
113 /** 
114  * xmlSecMSCryptoKeyDataAesGetKlass:
115  * 
116  * The AES key data klass.
117  *
118  * Returns: AES key data klass.
119  */
120 xmlSecKeyDataId 
121 xmlSecMSCryptoKeyDataAesGetKlass(void) {
122     return(&xmlSecMSCryptoKeyDataAesKlass);
123 }
124
125 /**
126  * xmlSecMSCryptoKeyDataAesSet:
127  * @data:               the pointer to AES key data.
128  * @buf:                the pointer to key value.
129  * @bufSize:            the key value size (in bytes).
130  *
131  * Sets the value of AES key data.
132  *
133  * Returns: 0 on success or a negative value if an error occurs.
134  */
135 int
136 xmlSecMSCryptoKeyDataAesSet(xmlSecKeyDataPtr data, const xmlSecByte* buf, xmlSecSize bufSize) {
137     xmlSecBufferPtr buffer;
138     
139     xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecMSCryptoKeyDataAesId), -1);
140     xmlSecAssert2(buf != NULL, -1);
141     xmlSecAssert2(bufSize > 0, -1);
142     
143     buffer = xmlSecKeyDataBinaryValueGetBuffer(data);
144     xmlSecAssert2(buffer != NULL, -1);
145     
146     return(xmlSecBufferSetData(buffer, buf, bufSize));
147 }
148 #endif /* XMLSEC_NO_AES */
149
150 #ifndef XMLSEC_NO_DES
151 /**************************************************************************
152  *
153  * <xmlsec:DESKeyValue> processing
154  *
155  *************************************************************************/
156 static xmlSecKeyDataKlass xmlSecMSCryptoKeyDataDesKlass = {
157     sizeof(xmlSecKeyDataKlass),
158     xmlSecKeyDataBinarySize,
159
160     /* data */
161     xmlSecNameDESKeyValue,
162     xmlSecKeyDataUsageKeyValueNode | xmlSecKeyDataUsageRetrievalMethodNodeXml, 
163                                                                         /* xmlSecKeyDataUsage usage; */
164     xmlSecHrefDESKeyValue,                      /* const xmlChar* href; */
165     xmlSecNodeDESKeyValue,                      /* const xmlChar* dataNodeName; */
166     xmlSecNs,                                   /* const xmlChar* dataNodeNs; */
167     
168     /* constructors/destructor */
169     xmlSecMSCryptoSymKeyDataInitialize,         /* xmlSecKeyDataInitializeMethod initialize; */
170     xmlSecMSCryptoSymKeyDataDuplicate,          /* xmlSecKeyDataDuplicateMethod duplicate; */
171     xmlSecMSCryptoSymKeyDataFinalize,           /* xmlSecKeyDataFinalizeMethod finalize; */
172     xmlSecMSCryptoSymKeyDataGenerate,           /* xmlSecKeyDataGenerateMethod generate; */
173     
174     /* get info */
175     xmlSecMSCryptoSymKeyDataGetType,            /* xmlSecKeyDataGetTypeMethod getType; */
176     xmlSecMSCryptoSymKeyDataGetSize,            /* xmlSecKeyDataGetSizeMethod getSize; */
177         NULL,                                   /* xmlSecKeyDataGetIdentifier getIdentifier; */
178
179     /* read/write */
180     xmlSecMSCryptoSymKeyDataXmlRead,            /* xmlSecKeyDataXmlReadMethod xmlRead; */
181     xmlSecMSCryptoSymKeyDataXmlWrite,           /* xmlSecKeyDataXmlWriteMethod xmlWrite; */
182     xmlSecMSCryptoSymKeyDataBinRead,            /* xmlSecKeyDataBinReadMethod binRead; */
183     xmlSecMSCryptoSymKeyDataBinWrite,           /* xmlSecKeyDataBinWriteMethod binWrite; */
184
185     /* debug */
186     xmlSecMSCryptoSymKeyDataDebugDump,          /* xmlSecKeyDataDebugDumpMethod debugDump; */
187     xmlSecMSCryptoSymKeyDataDebugXmlDump,       /* xmlSecKeyDataDebugDumpMethod debugXmlDump; */
188
189     /* reserved for the future */
190     NULL,                                       /* void* reserved0; */
191     NULL,                                       /* void* reserved1; */
192 };
193
194 /** 
195  * xmlSecMSCryptoKeyDataDesGetKlass:
196  * 
197  * The DES key data klass.
198  *
199  * Returns: DES key data klass.
200  */
201 xmlSecKeyDataId 
202 xmlSecMSCryptoKeyDataDesGetKlass(void) {
203     return(&xmlSecMSCryptoKeyDataDesKlass);
204 }
205 #endif /* XMLSEC_NO_DES */
206
207 /*
208  * GENERIC HELPER FUNCTIONS 
209  */
210
211 #define xmlSecMSCryptoSymKeyDataCheckId(data) \
212     (xmlSecKeyDataIsValid((data)) && \
213      xmlSecMSCryptoSymKeyDataKlassCheck((data)->id))
214
215 static int
216 xmlSecMSCryptoSymKeyDataInitialize(xmlSecKeyDataPtr data) {
217     xmlSecAssert2(xmlSecMSCryptoSymKeyDataCheckId(data), -1);
218     
219     return(xmlSecKeyDataBinaryValueInitialize(data));
220 }
221
222 static int
223 xmlSecMSCryptoSymKeyDataDuplicate(xmlSecKeyDataPtr dst, xmlSecKeyDataPtr src) {
224     xmlSecAssert2(xmlSecMSCryptoSymKeyDataCheckId(dst), -1);
225     xmlSecAssert2(xmlSecMSCryptoSymKeyDataCheckId(src), -1);
226     xmlSecAssert2(dst->id == src->id, -1);
227         
228     return(xmlSecKeyDataBinaryValueDuplicate(dst, src));
229 }
230
231 static void
232 xmlSecMSCryptoSymKeyDataFinalize(xmlSecKeyDataPtr data) {
233     xmlSecAssert(xmlSecMSCryptoSymKeyDataCheckId(data));
234     
235     xmlSecKeyDataBinaryValueFinalize(data);
236 }
237
238 static int
239 xmlSecMSCryptoSymKeyDataXmlRead(xmlSecKeyDataId id, xmlSecKeyPtr key,
240                                xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx) {
241     xmlSecAssert2(xmlSecMSCryptoSymKeyDataKlassCheck(id), -1);
242     
243     return(xmlSecKeyDataBinaryValueXmlRead(id, key, node, keyInfoCtx));
244 }
245
246 static int 
247 xmlSecMSCryptoSymKeyDataXmlWrite(xmlSecKeyDataId id, xmlSecKeyPtr key,
248                                     xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx) {
249     xmlSecAssert2(xmlSecMSCryptoSymKeyDataKlassCheck(id), -1);
250     
251     return(xmlSecKeyDataBinaryValueXmlWrite(id, key, node, keyInfoCtx));
252 }
253
254 static int
255 xmlSecMSCryptoSymKeyDataBinRead(xmlSecKeyDataId id, xmlSecKeyPtr key,
256                                 const unsigned char* buf, size_t bufSize,
257                                 xmlSecKeyInfoCtxPtr keyInfoCtx) {
258     xmlSecAssert2(xmlSecMSCryptoSymKeyDataKlassCheck(id), -1);
259     
260     return(xmlSecKeyDataBinaryValueBinRead(id, key, buf, bufSize, keyInfoCtx));
261 }
262
263 static int
264 xmlSecMSCryptoSymKeyDataBinWrite(xmlSecKeyDataId id, xmlSecKeyPtr key,
265                                  unsigned char** buf, size_t* bufSize,
266                                  xmlSecKeyInfoCtxPtr keyInfoCtx) {
267     xmlSecAssert2(xmlSecMSCryptoSymKeyDataKlassCheck(id), -1);
268     
269     return(xmlSecKeyDataBinaryValueBinWrite(id, key, buf, bufSize, keyInfoCtx));
270 }
271
272 static int
273 xmlSecMSCryptoSymKeyDataGenerate(xmlSecKeyDataPtr data, size_t sizeBits, xmlSecKeyDataType type ATTRIBUTE_UNUSED) {
274     xmlSecBufferPtr buffer;
275
276     xmlSecAssert2(xmlSecMSCryptoSymKeyDataCheckId(data), -1);
277     xmlSecAssert2(sizeBits > 0, -1);
278
279     buffer = xmlSecKeyDataBinaryValueGetBuffer(data);
280     xmlSecAssert2(buffer != NULL, -1);
281     
282     return(xmlSecMSCryptoGenerateRandom(buffer, (sizeBits + 7) / 8));
283 }
284
285 static xmlSecKeyDataType
286 xmlSecMSCryptoSymKeyDataGetType(xmlSecKeyDataPtr data) {
287     xmlSecBufferPtr buffer;
288
289     xmlSecAssert2(xmlSecMSCryptoSymKeyDataCheckId(data), xmlSecKeyDataTypeUnknown);
290
291     buffer = xmlSecKeyDataBinaryValueGetBuffer(data);
292     xmlSecAssert2(buffer != NULL, xmlSecKeyDataTypeUnknown);
293
294     return((xmlSecBufferGetSize(buffer) > 0) ? xmlSecKeyDataTypeSymmetric : xmlSecKeyDataTypeUnknown);
295 }
296
297 static size_t 
298 xmlSecMSCryptoSymKeyDataGetSize(xmlSecKeyDataPtr data) {
299     xmlSecAssert2(xmlSecMSCryptoSymKeyDataCheckId(data), 0);
300     
301     return(xmlSecKeyDataBinaryValueGetSize(data));
302 }
303
304 static void 
305 xmlSecMSCryptoSymKeyDataDebugDump(xmlSecKeyDataPtr data, FILE* output) {
306     xmlSecAssert(xmlSecMSCryptoSymKeyDataCheckId(data));
307     
308     xmlSecKeyDataBinaryValueDebugDump(data, output);    
309 }
310
311 static void
312 xmlSecMSCryptoSymKeyDataDebugXmlDump(xmlSecKeyDataPtr data, FILE* output) {
313     xmlSecAssert(xmlSecMSCryptoSymKeyDataCheckId(data));
314     
315     xmlSecKeyDataBinaryValueDebugXmlDump(data, output);    
316 }
317
318 static int 
319 xmlSecMSCryptoSymKeyDataKlassCheck(xmlSecKeyDataKlass* klass) {    
320 #ifndef XMLSEC_NO_DES
321     if(klass == xmlSecMSCryptoKeyDataDesId) {
322         return(1);
323     }
324 #endif /* XMLSEC_NO_DES */
325
326 #ifndef XMLSEC_NO_AES
327     if(klass == xmlSecMSCryptoKeyDataAesId) {
328                 return(1);
329     }
330 #endif /* XMLSEC_NO_AES */
331
332     return(0);
333 }