2 * XML Security Library example: Decrypting an encrypted file using keys manager.
4 * Decrypts encrypted XML file using keys manager and a list of
5 * DES key from a binary file
8 * ./decrypt2 <xml-enc> <des-key-file1> [<des-key-file2> [...]]
11 * ./decrypt2 encrypt1-res.xml deskey.bin
12 * ./decrypt2 encrypt2-res.xml deskey.bin
14 * This is free software; see Copyright file in the source
15 * distribution for preciese wording.
17 * Copyright (C) 2002-2003 Aleksey Sanin <aleksey@aleksey.com>
23 #include <libxml/tree.h>
24 #include <libxml/xmlmemory.h>
25 #include <libxml/parser.h>
27 #ifndef XMLSEC_NO_XSLT
28 #include <libxslt/xslt.h>
29 #endif /* XMLSEC_NO_XSLT */
31 #include <xmlsec/xmlsec.h>
32 #include <xmlsec/xmltree.h>
33 #include <xmlsec/xmlenc.h>
34 #include <xmlsec/crypto.h>
36 xmlSecKeysMngrPtr load_des_keys(char** files, int files_size);
37 int decrypt_file(xmlSecKeysMngrPtr mngr, const char* enc_file);
40 main(int argc, char **argv) {
41 xmlSecKeysMngrPtr mngr;
46 fprintf(stderr, "Error: wrong number of arguments.\n");
47 fprintf(stderr, "Usage: %s <enc-file> <key-file1> [<key-file2> [...]]\n", argv[0]);
51 /* Init libxml and libxslt libraries */
54 xmlLoadExtDtdDefaultValue = XML_DETECT_IDS | XML_COMPLETE_ATTRS;
55 xmlSubstituteEntitiesDefault(1);
56 #ifndef XMLSEC_NO_XSLT
57 xmlIndentTreeOutput = 1;
58 #endif /* XMLSEC_NO_XSLT */
60 /* Init xmlsec library */
61 if(xmlSecInit() < 0) {
62 fprintf(stderr, "Error: xmlsec initialization failed.\n");
66 /* Check loaded library version */
67 if(xmlSecCheckVersion() != 1) {
68 fprintf(stderr, "Error: loaded xmlsec library version is not compatible.\n");
72 /* Load default crypto engine if we are supporting dynamic
73 * loading for xmlsec-crypto libraries. Use the crypto library
74 * name ("openssl", "nss", etc.) to load corresponding
75 * xmlsec-crypto library.
77 #ifdef XMLSEC_CRYPTO_DYNAMIC_LOADING
78 if(xmlSecCryptoDLLoadLibrary(BAD_CAST XMLSEC_CRYPTO) < 0) {
79 fprintf(stderr, "Error: unable to load default xmlsec-crypto library. Make sure\n"
80 "that you have it installed and check shared libraries path\n"
81 "(LD_LIBRARY_PATH) envornment variable.\n");
84 #endif /* XMLSEC_CRYPTO_DYNAMIC_LOADING */
86 /* Init crypto library */
87 if(xmlSecCryptoAppInit(NULL) < 0) {
88 fprintf(stderr, "Error: crypto initialization failed.\n");
92 /* Init xmlsec-crypto library */
93 if(xmlSecCryptoInit() < 0) {
94 fprintf(stderr, "Error: xmlsec-crypto initialization failed.\n");
98 /* create keys manager and load keys */
99 mngr = load_des_keys(&(argv[2]), argc - 2);
104 if(decrypt_file(mngr, argv[1]) < 0) {
105 xmlSecKeysMngrDestroy(mngr);
109 /* destroy keys manager */
110 xmlSecKeysMngrDestroy(mngr);
112 /* Shutdown xmlsec-crypto library */
113 xmlSecCryptoShutdown();
115 /* Shutdown crypto library */
116 xmlSecCryptoAppShutdown();
118 /* Shutdown xmlsec library */
121 /* Shutdown libxslt/libxml */
122 #ifndef XMLSEC_NO_XSLT
123 xsltCleanupGlobals();
124 #endif /* XMLSEC_NO_XSLT */
132 * @files: the list of filenames.
133 * @files_size: the number of filenames in #files.
135 * Creates simple keys manager and load DES keys from #files in it.
136 * The caller is responsible for destroing returned keys manager using
137 * @xmlSecKeysMngrDestroy.
139 * Returns the pointer to newly created keys manager or NULL if an error
143 load_des_keys(char** files, int files_size) {
144 xmlSecKeysMngrPtr mngr;
149 assert(files_size > 0);
151 /* create and initialize keys manager, we use a simple list based
152 * keys manager, implement your own xmlSecKeysStore klass if you need
153 * something more sophisticated
155 mngr = xmlSecKeysMngrCreate();
157 fprintf(stderr, "Error: failed to create keys manager.\n");
160 if(xmlSecCryptoAppDefaultKeysMngrInit(mngr) < 0) {
161 fprintf(stderr, "Error: failed to initialize keys manager.\n");
162 xmlSecKeysMngrDestroy(mngr);
166 for(i = 0; i < files_size; ++i) {
170 key = xmlSecKeyReadBinaryFile(xmlSecKeyDataDesId, files[i]);
172 fprintf(stderr,"Error: failed to load des key from binary file \"%s\"\n", files[i]);
173 xmlSecKeysMngrDestroy(mngr);
177 /* set key name to the file name, this is just an example! */
178 if(xmlSecKeySetName(key, BAD_CAST files[i]) < 0) {
179 fprintf(stderr,"Error: failed to set key name for key from \"%s\"\n", files[i]);
180 xmlSecKeyDestroy(key);
181 xmlSecKeysMngrDestroy(mngr);
185 /* add key to keys manager, from now on keys manager is responsible
188 if(xmlSecCryptoAppDefaultKeysMngrAdoptKey(mngr, key) < 0) {
189 fprintf(stderr,"Error: failed to add key from \"%s\" to keys manager\n", files[i]);
190 xmlSecKeyDestroy(key);
191 xmlSecKeysMngrDestroy(mngr);
201 * @mngr: the pointer to keys manager.
202 * @enc_file: the encrypted XML file name.
204 * Decrypts the XML file #enc_file using DES key from #key_file and
205 * prints results to stdout.
207 * Returns 0 on success or a negative value if an error occurs.
210 decrypt_file(xmlSecKeysMngrPtr mngr, const char* enc_file) {
211 xmlDocPtr doc = NULL;
212 xmlNodePtr node = NULL;
213 xmlSecEncCtxPtr encCtx = NULL;
220 doc = xmlParseFile(enc_file);
221 if ((doc == NULL) || (xmlDocGetRootElement(doc) == NULL)){
222 fprintf(stderr, "Error: unable to parse file \"%s\"\n", enc_file);
226 /* find start node */
227 node = xmlSecFindNode(xmlDocGetRootElement(doc), xmlSecNodeEncryptedData, xmlSecEncNs);
229 fprintf(stderr, "Error: start node not found in \"%s\"\n", enc_file);
233 /* create encryption context */
234 encCtx = xmlSecEncCtxCreate(mngr);
236 fprintf(stderr,"Error: failed to create encryption context\n");
240 /* decrypt the data */
241 if((xmlSecEncCtxDecrypt(encCtx, node) < 0) || (encCtx->result == NULL)) {
242 fprintf(stderr,"Error: decryption failed\n");
246 /* print decrypted data to stdout */
247 if(encCtx->resultReplaced != 0) {
248 fprintf(stdout, "Decrypted XML data:\n");
249 xmlDocDump(stdout, doc);
251 fprintf(stdout, "Decrypted binary data (%d bytes):\n", xmlSecBufferGetSize(encCtx->result));
252 if(xmlSecBufferGetData(encCtx->result) != NULL) {
253 fwrite(xmlSecBufferGetData(encCtx->result),
255 xmlSecBufferGetSize(encCtx->result),
259 fprintf(stdout, "\n");
267 xmlSecEncCtxDestroy(encCtx);