source: TI12-security/trunk/NDGSecurity/python/Tests/xmlsec/encrypt4.c @ 7080

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/TI12-security/trunk/NDGSecurity/python/Tests/xmlsec/encrypt4.c@7080
Revision 7080, 9.3 KB checked in by pjkersha, 9 years ago (diff)
  • Property svn:keywords set to Id
Line 
1/**
2 * XML Security Library example: Encrypting XML file with a session key and dynamicaly created template.
3 *
4 * Encrypts XML file using a dynamicaly created template file and a session
5 * DES key (encrypted with an RSA key).
6 *
7 * Usage:
8 *      ./encrypt3 <xml-doc> <rsa-pem-key-file>
9 *
10 * Example:
11 *      ./encrypt3 encrypt3-doc.xml rsakey.pem > encrypt3-res.xml
12 *
13 * The result could be decrypted with decrypt3 example:
14 *      ./decrypt3 encrypt3-res.xml
15 *
16 * This is free software; see Copyright file in the source
17 * distribution for preciese wording.
18 *
19 * Copyright (C) 2002-2003 Aleksey Sanin <aleksey@aleksey.com>
20 */
21#include <stdlib.h>
22#include <string.h>
23#include <assert.h>
24
25#include <libxml/tree.h>
26#include <libxml/xmlmemory.h>
27#include <libxml/parser.h>
28
29#ifndef XMLSEC_NO_XSLT
30#include <libxslt/xslt.h>
31#endif /* XMLSEC_NO_XSLT */
32
33#include <xmlsec/xmlsec.h>
34#include <xmlsec/xmltree.h>
35#include <xmlsec/xmlenc.h>
36#include <xmlsec/templates.h>
37#include <xmlsec/crypto.h>
38
39xmlSecKeysMngrPtr load_rsa_keys(char* key_file, const char *szPriKeyFilePath);
40int encrypt_file(xmlSecKeysMngrPtr mngr, const char* xml_file, const char* key_name);
41
42int 
43main(int argc, char **argv) {
44    xmlSecKeysMngrPtr mngr;
45   
46    assert(argv);
47
48    if(argc != 3) {
49        fprintf(stderr, "Error: wrong number of arguments.\n");
50        fprintf(stderr, "Usage: %s <xml-file> <key-file>\n", argv[0]);
51        return(1);
52    }
53
54    /* Init libxml and libxslt libraries */
55    xmlInitParser();
56    LIBXML_TEST_VERSION
57    xmlLoadExtDtdDefaultValue = XML_DETECT_IDS | XML_COMPLETE_ATTRS;
58    xmlSubstituteEntitiesDefault(1);
59#ifndef XMLSEC_NO_XSLT
60    xmlIndentTreeOutput = 1; 
61#endif /* XMLSEC_NO_XSLT */
62               
63    /* Init xmlsec library */
64    if(xmlSecInit() < 0) {
65        fprintf(stderr, "Error: xmlsec initialization failed.\n");
66        return(-1);
67    }
68
69    /* Check loaded library version */
70    if(xmlSecCheckVersion() != 1) {
71        fprintf(stderr, "Error: loaded xmlsec library version is not compatible.\n");
72        return(-1);
73    }
74
75    /* Load default crypto engine if we are supporting dynamic
76     * loading for xmlsec-crypto libraries. Use the crypto library
77     * name ("openssl", "nss", etc.) to load corresponding
78     * xmlsec-crypto library.
79     */
80#ifdef XMLSEC_CRYPTO_DYNAMIC_LOADING
81    if(xmlSecCryptoDLLoadLibrary(BAD_CAST XMLSEC_CRYPTO) < 0) {
82        fprintf(stderr, "Error: unable to load default xmlsec-crypto library. Make sure\n"
83                        "that you have it installed and check shared libraries path\n"
84                        "(LD_LIBRARY_PATH) envornment variable.\n");
85        return(-1);     
86    }
87#endif /* XMLSEC_CRYPTO_DYNAMIC_LOADING */
88
89    /* Init crypto library */
90    if(xmlSecCryptoAppInit(NULL) < 0) {
91        fprintf(stderr, "Error: crypto initialization failed.\n");
92        return(-1);
93    }
94
95    /* Init xmlsec-crypto library */
96    if(xmlSecCryptoInit() < 0) {
97        fprintf(stderr, "Error: xmlsec-crypto initialization failed.\n");
98        return(-1);
99    }
100
101    /* create keys manager and load keys */
102    mngr = load_rsa_keys(argv[2], "badc-aa-key.pem");
103    if(mngr == NULL) {
104        return(-1);
105    }
106
107    /* we use key filename as key name here */
108    /*
109    if(encrypt_file(mngr, argv[1], argv[2]) < 0)
110    */
111    if (encrypt_file(mngr, argv[1], "badc-aa-key.pem") < 0) 
112    {
113        xmlSecKeysMngrDestroy(mngr);
114        return(-1);
115    }   
116
117    /* destroy keys manager */
118    xmlSecKeysMngrDestroy(mngr);
119   
120    /* Shutdown xmlsec-crypto library */
121    xmlSecCryptoShutdown();
122   
123    /* Shutdown crypto library */
124    xmlSecCryptoAppShutdown();
125   
126    /* Shutdown xmlsec library */
127    xmlSecShutdown();
128
129    /* Shutdown libxslt/libxml */
130#ifndef XMLSEC_NO_XSLT
131    xsltCleanupGlobals();           
132#endif /* XMLSEC_NO_XSLT */
133    xmlCleanupParser();
134   
135    return(0);
136}
137
138/**
139 * load_rsa_keys:
140 * @key_file:           the key filename.
141 *
142 * Creates simple keys manager and load RSA key from #key_file in it.
143 * The caller is responsible for destroing returned keys manager using
144 * @xmlSecKeysMngrDestroy.
145 *
146 * Returns the pointer to newly created keys manager or NULL if an error
147 * occurs.
148 */
149xmlSecKeysMngrPtr
150load_rsa_keys(char* key_file, const char  *szPriKeyFilePath) 
151{
152    xmlSecKeysMngrPtr mngr;
153    xmlSecKeyPtr key;
154   
155    assert(key_file);
156   
157    /* create and initialize keys manager, we use a simple list based
158     * keys manager, implement your own xmlSecKeysStore klass if you need
159     * something more sophisticated
160     */
161    mngr = xmlSecKeysMngrCreate();
162    if(mngr == NULL) {
163        fprintf(stderr, "Error: failed to create keys manager.\n");
164        return(NULL);
165    }
166    if(xmlSecCryptoAppDefaultKeysMngrInit(mngr) < 0) {
167        fprintf(stderr, "Error: failed to initialize keys manager.\n");
168        xmlSecKeysMngrDestroy(mngr);
169        return(NULL);
170    }   
171   
172    /* load private RSA key */
173    /*
174    key = xmlSecCryptoAppKeyLoad(key_file, xmlSecKeyDataFormatPem, NULL, NULL, NULL);
175    */
176    key = xmlSecCryptoAppKeyLoad(key_file, xmlSecKeyDataFormatCertPem, NULL, NULL, NULL);
177    if(key == NULL) {
178        fprintf(stderr,"Error: failed to load rsa key from file \"%s\"\n", key_file);
179        xmlSecKeysMngrDestroy(mngr);
180        return(NULL);
181    }
182
183    /* set key name to the file name, this is just an example! */
184/*    if(xmlSecKeySetName(key, BAD_CAST key_file) < 0) {
185        fprintf(stderr,"Error: failed to set key name for key from \"%s\"\n", key_file);
186        xmlSecKeyDestroy(key); 
187        xmlSecKeysMngrDestroy(mngr);
188        return(NULL);
189    }
190*/
191       
192    /* add key to keys manager, from now on keys manager is responsible
193     * for destroying key
194     */
195    if(xmlSecCryptoAppDefaultKeysMngrAdoptKey(mngr, key) < 0) {
196        fprintf(stderr,"Error: failed to add key from \"%s\" to keys manager\n", key_file);
197        xmlSecKeyDestroy(key);
198        xmlSecKeysMngrDestroy(mngr);
199        return(NULL);
200    }
201
202    return(mngr);
203}
204
205/**
206 * encrypt_file:
207 * @mngr:               the pointer to keys manager.
208 * @xml_file:           the encryption template file name.
209 * @key_name:           the RSA key name.
210 *
211 * Encrypts #xml_file using a dynamicaly created template, a session DES key
212 * and an RSA key from keys manager.
213 *
214 * Returns 0 on success or a negative value if an error occurs.
215 */
216int 
217encrypt_file(xmlSecKeysMngrPtr mngr, const char* xml_file, const char* key_name) {
218    xmlDocPtr doc = NULL;
219    xmlNodePtr encDataNode = NULL;
220    xmlNodePtr keyInfoNode = NULL;
221    xmlNodePtr encKeyNode = NULL;
222    xmlNodePtr keyInfoNode2 = NULL;
223    xmlSecEncCtxPtr encCtx = NULL;
224    int res = -1;
225   
226    assert(mngr);
227    assert(xml_file);
228    assert(key_name);
229
230    /* load template */
231    doc = xmlParseFile(xml_file);
232    if ((doc == NULL) || (xmlDocGetRootElement(doc) == NULL)){
233        fprintf(stderr, "Error: unable to parse file \"%s\"\n", xml_file);
234        goto done;     
235    }
236   
237    /* create encryption template to encrypt XML file and replace
238     * its content with encryption result */
239    encDataNode = xmlSecTmplEncDataCreate(doc, xmlSecTransformDes3CbcId,
240                                NULL, xmlSecTypeEncElement, NULL, NULL);
241    if(encDataNode == NULL) {
242        fprintf(stderr, "Error: failed to create encryption template\n");
243        goto done;   
244    }
245
246    /* we want to put encrypted data in the <enc:CipherValue/> node */
247    if(xmlSecTmplEncDataEnsureCipherValue(encDataNode) == NULL) {
248        fprintf(stderr, "Error: failed to add CipherValue node\n");
249        goto done;   
250    }
251
252    /* add <dsig:KeyInfo/> */
253    keyInfoNode = xmlSecTmplEncDataEnsureKeyInfo(encDataNode, NULL);
254    if(keyInfoNode == NULL) {
255        fprintf(stderr, "Error: failed to add key info\n");
256        goto done;             
257    }
258
259    /* add <enc:EncryptedKey/> to store the encrypted session key */
260    encKeyNode = xmlSecTmplKeyInfoAddEncryptedKey(keyInfoNode, 
261                                    xmlSecTransformRsaPkcs1Id, 
262                                    NULL, NULL, NULL);
263    if(encKeyNode == NULL) {
264        fprintf(stderr, "Error: failed to add key info\n");
265        goto done;             
266    }
267
268    /* we want to put encrypted key in the <enc:CipherValue/> node */
269    if(xmlSecTmplEncDataEnsureCipherValue(encKeyNode) == NULL) {
270        fprintf(stderr, "Error: failed to add CipherValue node\n");
271        goto done;   
272    }
273
274    /* add <dsig:KeyInfo/> and <dsig:KeyName/> nodes to <enc:EncryptedKey/> */
275    keyInfoNode2 = xmlSecTmplEncDataEnsureKeyInfo(encKeyNode, NULL);
276    if(keyInfoNode2 == NULL) {
277        fprintf(stderr, "Error: failed to add key info\n");
278        goto done;             
279    }
280   
281    /* set key name so we can lookup key when needed */
282    if(xmlSecTmplKeyInfoAddKeyName(keyInfoNode2, key_name) == NULL) {
283        fprintf(stderr, "Error: failed to add key name\n");
284        goto done;             
285    }
286
287    /* create encryption context */
288    encCtx = xmlSecEncCtxCreate(mngr);
289    if(encCtx == NULL) {
290        fprintf(stderr,"Error: failed to create encryption context\n");
291        goto done;
292    }
293
294    /* generate a Triple DES key */
295    encCtx->encKey = xmlSecKeyGenerate(xmlSecKeyDataDesId, 192, xmlSecKeyDataTypeSession);
296    if(encCtx->encKey == NULL) {
297        fprintf(stderr,"Error: failed to generate session des key\n");
298        goto done;
299    }
300
301    /* encrypt the data */
302    if(xmlSecEncCtxXmlEncrypt(encCtx, encDataNode, xmlDocGetRootElement(doc)) < 0) {
303        fprintf(stderr,"Error: encryption failed\n");
304        goto done;
305    }
306   
307    /* we template is inserted in the doc */
308    encDataNode = NULL;
309       
310    /* print encrypted data with document to stdout */
311    xmlDocDump(stdout, doc);
312   
313    /* success */
314    res = 0;
315
316done:   
317
318    /* cleanup */
319    if(encCtx != NULL) {
320        xmlSecEncCtxDestroy(encCtx);
321    }
322
323    if(encDataNode != NULL) {
324        xmlFreeNode(encDataNode);
325    }
326       
327    if(doc != NULL) {
328        xmlFreeDoc(doc); 
329    }
330    return(res);
331}
Note: See TracBrowser for help on using the repository browser.