Git init
[external/xmlsec1.git] / examples / decrypt1.c
1 /** 
2  * XML Security Library example: Decrypting an encrypted file using a single key.
3  * 
4  * Decrypts encrypted XML file using a single DES key from a binary file
5  * 
6  * Usage: 
7  *      ./decrypt1 <xml-enc> <des-key-file> 
8  *
9  * Example:
10  *      ./decrypt1 encrypt1-res.xml deskey.bin
11  *      ./decrypt1 encrypt2-res.xml deskey.bin
12  *
13  * This is free software; see Copyright file in the source
14  * distribution for preciese wording.
15  * 
16  * Copyright (C) 2002-2003 Aleksey Sanin <aleksey@aleksey.com>
17  */
18 #include <stdlib.h>
19 #include <string.h>
20 #include <assert.h>
21
22 #include <libxml/tree.h>
23 #include <libxml/xmlmemory.h>
24 #include <libxml/parser.h>
25
26 #ifndef XMLSEC_NO_XSLT
27 #include <libxslt/xslt.h>
28 #endif /* XMLSEC_NO_XSLT */
29
30 #include <xmlsec/xmlsec.h>
31 #include <xmlsec/xmltree.h>
32 #include <xmlsec/xmlenc.h>
33 #include <xmlsec/crypto.h>
34
35 int decrypt_file(const char* enc_file, const char* key_file);
36
37 int 
38 main(int argc, char **argv) {
39     assert(argv);
40
41     if(argc != 3) {
42         fprintf(stderr, "Error: wrong number of arguments.\n");
43         fprintf(stderr, "Usage: %s <enc-file> <key-file>\n", argv[0]);
44         return(1);
45     }
46
47     /* Init libxml and libxslt libraries */
48     xmlInitParser();
49     LIBXML_TEST_VERSION
50     xmlLoadExtDtdDefaultValue = XML_DETECT_IDS | XML_COMPLETE_ATTRS;
51     xmlSubstituteEntitiesDefault(1);
52 #ifndef XMLSEC_NO_XSLT
53     xmlIndentTreeOutput = 1; 
54 #endif /* XMLSEC_NO_XSLT */
55                 
56     /* Init xmlsec library */
57     if(xmlSecInit() < 0) {
58         fprintf(stderr, "Error: xmlsec initialization failed.\n");
59         return(-1);
60     }
61
62     /* Check loaded library version */
63     if(xmlSecCheckVersion() != 1) {
64         fprintf(stderr, "Error: loaded xmlsec library version is not compatible.\n");
65         return(-1);
66     }
67
68     /* Load default crypto engine if we are supporting dynamic
69      * loading for xmlsec-crypto libraries. Use the crypto library
70      * name ("openssl", "nss", etc.) to load corresponding 
71      * xmlsec-crypto library.
72      */
73 #ifdef XMLSEC_CRYPTO_DYNAMIC_LOADING
74     if(xmlSecCryptoDLLoadLibrary(BAD_CAST XMLSEC_CRYPTO) < 0) {
75         fprintf(stderr, "Error: unable to load default xmlsec-crypto library. Make sure\n"
76                         "that you have it installed and check shared libraries path\n"
77                         "(LD_LIBRARY_PATH) envornment variable.\n");
78         return(-1);     
79     }
80 #endif /* XMLSEC_CRYPTO_DYNAMIC_LOADING */
81
82     /* Init crypto library */
83     if(xmlSecCryptoAppInit(NULL) < 0) {
84         fprintf(stderr, "Error: crypto initialization failed.\n");
85         return(-1);
86     }
87
88     /* Init xmlsec-crypto library */
89     if(xmlSecCryptoInit() < 0) {
90         fprintf(stderr, "Error: xmlsec-crypto initialization failed.\n");
91         return(-1);
92     }
93
94     if(decrypt_file(argv[1], argv[2]) < 0) {
95         return(-1);
96     }    
97     
98     /* Shutdown xmlsec-crypto library */
99     xmlSecCryptoShutdown();
100     
101     /* Shutdown crypto library */
102     xmlSecCryptoAppShutdown();
103     
104     /* Shutdown xmlsec library */
105     xmlSecShutdown();
106
107     /* Shutdown libxslt/libxml */
108 #ifndef XMLSEC_NO_XSLT
109     xsltCleanupGlobals();            
110 #endif /* XMLSEC_NO_XSLT */
111     xmlCleanupParser();
112     
113     return(0);
114 }
115
116 /**
117  * decrypt_file:
118  * @enc_file:           the encrypted XML  file name.
119  * @key_file:           the Triple DES key file.
120  *
121  * Decrypts the XML file #enc_file using DES key from #key_file and 
122  * prints results to stdout.
123  *
124  * Returns 0 on success or a negative value if an error occurs.
125  */
126 int 
127 decrypt_file(const char* enc_file, const char* key_file) {
128     xmlDocPtr doc = NULL;
129     xmlNodePtr node = NULL;
130     xmlSecEncCtxPtr encCtx = NULL;
131     int res = -1;
132     
133     assert(enc_file);
134     assert(key_file);
135
136     /* load template */
137     doc = xmlParseFile(enc_file);
138     if ((doc == NULL) || (xmlDocGetRootElement(doc) == NULL)){
139         fprintf(stderr, "Error: unable to parse file \"%s\"\n", enc_file);
140         goto done;      
141     }
142     
143     /* find start node */
144     node = xmlSecFindNode(xmlDocGetRootElement(doc), xmlSecNodeEncryptedData, xmlSecEncNs);
145     if(node == NULL) {
146         fprintf(stderr, "Error: start node not found in \"%s\"\n", enc_file);
147         goto done;      
148     }
149
150     /* create encryption context, we don't need keys manager in this example */
151     encCtx = xmlSecEncCtxCreate(NULL);
152     if(encCtx == NULL) {
153         fprintf(stderr,"Error: failed to create encryption context\n");
154         goto done;
155     }
156
157     /* load DES key */
158     encCtx->encKey = xmlSecKeyReadBinaryFile(xmlSecKeyDataDesId, key_file);
159     if(encCtx->encKey == NULL) {
160         fprintf(stderr,"Error: failed to load des key from binary file \"%s\"\n", key_file);
161         goto done;
162     }
163     
164     /* set key name to the file name, this is just an example! */
165     if(xmlSecKeySetName(encCtx->encKey, key_file) < 0) {
166         fprintf(stderr,"Error: failed to set key name for key from \"%s\"\n", key_file);
167         goto done;
168     }
169
170     /* decrypt the data */
171     if((xmlSecEncCtxDecrypt(encCtx, node) < 0) || (encCtx->result == NULL)) {
172         fprintf(stderr,"Error: decryption failed\n");
173         goto done;
174     }
175         
176     /* print decrypted data to stdout */
177     if(encCtx->resultReplaced != 0) {
178         fprintf(stdout, "Decrypted XML data:\n");
179         xmlDocDump(stdout, doc);
180     } else {
181         fprintf(stdout, "Decrypted binary data (%d bytes):\n", xmlSecBufferGetSize(encCtx->result));
182         if(xmlSecBufferGetData(encCtx->result) != NULL) {
183             fwrite(xmlSecBufferGetData(encCtx->result), 
184                   1, 
185                   xmlSecBufferGetSize(encCtx->result),
186                   stdout);
187         }
188     }
189     fprintf(stdout, "\n");
190         
191     /* success */
192     res = 0;
193
194 done:    
195     /* cleanup */
196     if(encCtx != NULL) {
197         xmlSecEncCtxDestroy(encCtx);
198     }
199     
200     if(doc != NULL) {
201         xmlFreeDoc(doc); 
202     }
203     return(res);
204 }
205