Git init
[external/xmlsec1.git] / docs / api / chapters / verify-and-decrypt.sgml
1 <chapter id="xmlsec-notes-verify-decrypt">
2     <title>Verifing and decrypting documents.</title>
3     <sect1 id="xmlsec-notes-verify-decrypt-overview">
4         <title>Overview.</title>
5         <para>Since the template is just an XML file, it might be created in advance 
6         and saved in a file. It's also possible for application to create 
7         templates without using XML Security Library functions. Also in some 
8         cases template should be inserted in the signed or encrypted data 
9         (for example, if you want to create an enveloped or enveloping 
10         signature).</para>
11         <para>Signature verification and data decryption do not require template 
12         because all the necessary information is provided in the signed or 
13         encrypted document.
14           <figure>
15             <title>The verification or decryption processing model.</title>
16             <graphic fileref="images/verif-dec-model.png" align="center"></graphic>
17           </figure>      
18         </para>
19     </sect1>
20     
21     <sect1 id="xmlsec-notes-verify" >
22         <title>Verifying a signed document</title>
23         <para>The typical siganture verification process includes following steps:
24           <itemizedlist>
25             <listitem><para>
26                 Load keys, X509 certificates, etc. in the <link linkend="xmlSecKeysMngr">keys manager</link> .
27             </para></listitem>
28             <listitem><para>
29                 Create signature context <link linkend="xmlSecDSigCtx">xmlSecDSigCtx</link>
30                 using <link linkend="xmlSecDSigCtxCreate">xmlSecDSigCtxCreate</link> or
31                 <link linkend="xmlSecDSigCtxInitialize">xmlSecDSigCtxInitialize</link>
32                 functions.
33             </para></listitem>
34             <listitem><para>
35                 Select start verification 
36                 <ulink URL="http://www.w3.org/TR/xmldsig-core/#sec-Signature">&lt;dsig:Signature/&gt;</ulink>
37                 node in the signed XML document.
38             </para></listitem>
39             <listitem><para>
40                 Verify signature by calling <link linkend="xmlSecDSigCtxVerify">xmlSecDSigCtxVerify</link> 
41                 function.
42             </para></listitem>
43             <listitem><para>
44                 Check returned value and verification status (<structfield>status</structfield>
45                 member of <link linkend="xmlSecDSigCtx">xmlSecDSigCtx</link> structure).
46                 If necessary, consume returned data from the <link linkend="xmlSecDSigCtx">context</link>.
47             </para></listitem>
48             <listitem><para>
49                 Destroy signature context <link linkend="xmlSecDSigCtx">xmlSecDSigCtx</link>
50                 using <link linkend="xmlSecDSigCtxDestroy">xmlSecDSigCtxDestroy</link> or
51                 <link linkend="xmlSecDSigCtxFinalize">xmlSecDSigCtxFinalize</link>
52                 functions.
53             </para></listitem>
54           </itemizedlist>
55         </para>
56         <para>
57              <example>
58                 <title>Verifying a document.</title>
59                 <programlisting><![CDATA[
60 /** 
61  * verify_file:
62  * @xml_file:           the signed XML file name.
63  * @key_file:           the PEM public key file name.
64  *
65  * Verifies XML signature in #xml_file using public key from #key_file.
66  *
67  * Returns 0 on success or a negative value if an error occurs.
68  */
69 int 
70 verify_file(const char* xml_file, const char* key_file) {
71     xmlDocPtr doc = NULL;
72     xmlNodePtr node = NULL;
73     xmlSecDSigCtxPtr dsigCtx = NULL;
74     int res = -1;
75     
76     assert(xml_file);
77     assert(key_file);
78
79     /* load file */
80     doc = xmlParseFile(xml_file);
81     if ((doc == NULL) || (xmlDocGetRootElement(doc) == NULL)){
82         fprintf(stderr, "Error: unable to parse file \"%s\"\n", xml_file);
83         goto done;      
84     }
85     
86     /* find start node */
87     node = xmlSecFindNode(xmlDocGetRootElement(doc), xmlSecNodeSignature, xmlSecDSigNs);
88     if(node == NULL) {
89         fprintf(stderr, "Error: start node not found in \"%s\"\n", xml_file);
90         goto done;      
91     }
92
93     /* create signature context, we don't need keys manager in this example */
94     dsigCtx = xmlSecDSigCtxCreate(NULL);
95     if(dsigCtx == NULL) {
96         fprintf(stderr,"Error: failed to create signature context\n");
97         goto done;
98     }
99
100     /* load public key */
101     dsigCtx->signKey = xmlSecCryptoAppKeyLoad(key_file,xmlSecKeyDataFormatPem, NULL, NULL, NULL);
102     if(dsigCtx->signKey == NULL) {
103         fprintf(stderr,"Error: failed to load public pem key from \"%s\"\n", key_file);
104         goto done;
105     }
106
107     /* set key name to the file name, this is just an example! */
108     if(xmlSecKeySetName(dsigCtx->signKey, key_file) < 0) {
109         fprintf(stderr,"Error: failed to set key name for key from \"%s\"\n", key_file);
110         goto done;
111     }
112
113     /* Verify signature */
114     if(xmlSecDSigCtxVerify(dsigCtx, node) < 0) {
115         fprintf(stderr,"Error: signature verify\n");
116         goto done;
117     }
118         
119     /* print verification result to stdout */
120     if(dsigCtx->status == xmlSecDSigStatusSucceeded) {
121         fprintf(stdout, "Signature is OK\n");
122     } else {
123         fprintf(stdout, "Signature is INVALID\n");
124     }    
125
126     /* success */
127     res = 0;
128
129 done:    
130     /* cleanup */
131     if(dsigCtx != NULL) {
132         xmlSecDSigCtxDestroy(dsigCtx);
133     }
134     
135     if(doc != NULL) {
136         xmlFreeDoc(doc); 
137     }
138     return(res);
139 }
140                 ]]></programlisting>
141             <simpara><link linkend="xmlsec-example-verify1">Full Program Listing</link></simpara>
142             </example>
143         </para>
144     </sect1>
145
146     <sect1 id="xmlsec-notes-decrypt" >
147         <title>Decrypting an encrypted document</title>
148         <para>The typical decryption process includes following steps:
149           <itemizedlist>
150             <listitem><para>
151                 Load keys, X509 certificates, etc. in the <link linkend="xmlSecKeysMngr">keys manager</link> .
152             </para></listitem>
153             <listitem><para>
154                 Create encryption context <link linkend="xmlSecEncCtx">xmlSecEncCtx</link>
155                 using <link linkend="xmlSecEncCtxCreate">xmlSecEncCtxCreate</link> or
156                 <link linkend="xmlSecEncCtxInitialize">xmlSecEncCtxInitialize</link>
157                 functions.
158             </para></listitem>
159             <listitem><para>
160                 Select start decryption &lt;enc:EncryptedData&gt; node.
161             </para></listitem>
162             <listitem><para>
163                 Decrypt by calling <link linkend="xmlSecEncCtxDecrypt">xmlSecencCtxDecrypt</link> 
164                 function.
165             </para></listitem>
166             <listitem><para>
167                 Check returned value and if necessary consume encrypted data.
168             </para></listitem>
169             <listitem><para>
170                 Destroy encryption context <link linkend="xmlSecEncCtx">xmlSecEncCtx</link>
171                 using <link linkend="xmlSecEncCtxDestroy">xmlSecEncCtxDestroy</link> or
172                 <link linkend="xmlSecEncCtxFinalize">xmlSecEncCtxFinalize</link>
173                 functions.
174             </para></listitem>
175           </itemizedlist>
176         </para>
177         <para>
178              <example>
179                 <title>Decrypting a document.</title>
180                 <programlisting><![CDATA[
181 int 
182 decrypt_file(const char* enc_file, const char* key_file) {
183     xmlDocPtr doc = NULL;
184     xmlNodePtr node = NULL;
185     xmlSecEncCtxPtr encCtx = NULL;
186     int res = -1;
187     
188     assert(enc_file);
189     assert(key_file);
190
191     /* load template */
192     doc = xmlParseFile(enc_file);
193     if ((doc == NULL) || (xmlDocGetRootElement(doc) == NULL)){
194         fprintf(stderr, "Error: unable to parse file \"%s\"\n", enc_file);
195         goto done;      
196     }
197     
198     /* find start node */
199     node = xmlSecFindNode(xmlDocGetRootElement(doc), xmlSecNodeEncryptedData, xmlSecEncNs);
200     if(node == NULL) {
201         fprintf(stderr, "Error: start node not found in \"%s\"\n", enc_file);
202         goto done;      
203     }
204
205     /* create encryption context, we don't need keys manager in this example */
206     encCtx = xmlSecEncCtxCreate(NULL);
207     if(encCtx == NULL) {
208         fprintf(stderr,"Error: failed to create encryption context\n");
209         goto done;
210     }
211
212     /* load DES key */
213     encCtx->encKey = xmlSecKeyReadBinaryFile(xmlSecKeyDataDesId, key_file);
214     if(encCtx->encKey == NULL) {
215         fprintf(stderr,"Error: failed to load des key from binary file \"%s\"\n", key_file);
216         goto done;
217     }
218
219     /* set key name to the file name, this is just an example! */
220     if(xmlSecKeySetName(encCtx->encKey, key_file) < 0) {
221         fprintf(stderr,"Error: failed to set key name for key from \"%s\"\n", key_file);
222         goto done;
223     }
224
225     /* decrypt the data */
226     if((xmlSecEncCtxDecrypt(encCtx, node) < 0) || (encCtx->result == NULL)) {
227         fprintf(stderr,"Error: decryption failed\n");
228         goto done;
229     }
230         
231     /* print decrypted data to stdout */
232     if(encCtx->resultReplaced != 0) {
233         fprintf(stdout, "Decrypted XML data:\n");
234         xmlDocDump(stdout, doc);
235     } else {
236         fprintf(stdout, "Decrypted binary data (%d bytes):\n", xmlSecBufferGetSize(encCtx->result));
237         if(xmlSecBufferGetData(encCtx->result) != NULL) {
238             fwrite(xmlSecBufferGetData(encCtx->result), 
239                   1, 
240                   xmlSecBufferGetSize(encCtx->result),
241                   stdout);
242         }
243     }
244     fprintf(stdout, "\n");
245         
246     /* success */
247     res = 0;
248
249 done:    
250     /* cleanup */
251     if(encCtx != NULL) {
252         xmlSecEncCtxDestroy(encCtx);
253     }
254     
255     if(doc != NULL) {
256         xmlFreeDoc(doc); 
257     }
258     return(res);
259 }
260                 ]]></programlisting>
261             <simpara><link linkend="xmlsec-example-decrypt1">Full Program Listing</link></simpara>
262             </example>
263         </para>
264     </sect1>
265 </chapter>