1<chapter id="xmlsec-notes-sign-encrypt"> 2 <title>Signing and encrypting documents.</title> 3 <sect1 id="xmlsec-notes-sign-encrypt-overview"> 4 <title>Overview.</title> 5 <para>XML Security Library performs signature or encryption by processing 6 input xml or binary data and a template that specifies a signature or 7 encryption skeleton: the transforms, algorithms, the key selection 8 process. A template has the same structure as the desired result but 9 some of the nodes are empty. XML Security Library gets the key for 10 signature/encryption from keys managers using the information from 11 the template, does necessary computations and puts the results in 12 the template. Signature or encryption context controls the whole 13 process and stores the required temporary data. 14 <figure> 15 <title>The signature or encryption processing model.</title> 16 <graphic fileref="images/sign-enc-model.png" align="center"></graphic> 17 </figure> 18 </para> 19 </sect1> 20 21 <sect1 id="xmlsec-notes-sign" > 22 <title>Signing a document.</title> 23 <para>The typical signature process includes following steps: 24 <itemizedlist> 25 <listitem><para> 26 Prepare data for signature. 27 </para></listitem> 28 <listitem><para> 29 Create or load signature template and select start 30 <ulink URL="http://www.w3.org/TR/xmldsig-core/#sec-Signature"><dsig:Signature/></ulink> 31 node. 32 </para></listitem> 33 <listitem><para> 34 Create signature context <link linkend="xmlSecDSigCtx">xmlSecDSigCtx</link> 35 using <link linkend="xmlSecDSigCtxCreate">xmlSecDSigCtxCreate</link> or 36 <link linkend="xmlSecDSigCtxInitialize">xmlSecDSigCtxInitialize</link> 37 functions. 38 </para></listitem> 39 <listitem><para> 40 Load signature key in <link linkend="xmlSecKeysMngr">keys manager</link> 41 or generate a session key and set it in the signature context 42 (<structfield>signKey</structfield> member of 43 <link linkend="xmlSecDSigCtx">xmlSecDSigCtx</link> structure). 44 </para></listitem> 45 <listitem><para> 46 Sign data by calling <link linkend="xmlSecDSigCtxSign">xmlSecDSigCtxSign</link> 47 function. 48 </para></listitem> 49 <listitem><para> 50 Check returned value and consume signed data. 51 </para></listitem> 52 <listitem><para> 53 Destroy signature context <link linkend="xmlSecDSigCtx">xmlSecDSigCtx</link> 54 using <link linkend="xmlSecDSigCtxDestroy">xmlSecDSigCtxDestroy</link> or 55 <link linkend="xmlSecDSigCtxFinalize">xmlSecDSigCtxFinalize</link> 56 functions. 57 </para></listitem> 58 </itemizedlist> 59 </para> 60 <para> 61 <example> 62 <title>Signing a template.</title> 63 <programlisting><![CDATA[ 64/** 65 * sign_file: 66 * @tmpl_file: the signature template file name. 67 * @key_file: the PEM private key file name. 68 * 69 * Signs the #tmpl_file using private key from #key_file. 70 * 71 * Returns 0 on success or a negative value if an error occurs. 72 */ 73int 74sign_file(const char* tmpl_file, const char* key_file) { 75 xmlDocPtr doc = NULL; 76 xmlNodePtr node = NULL; 77 xmlSecDSigCtxPtr dsigCtx = NULL; 78 int res = -1; 79 80 assert(tmpl_file); 81 assert(key_file); 82 83 /* load template */ 84 doc = xmlParseFile(tmpl_file); 85 if ((doc == NULL) || (xmlDocGetRootElement(doc) == NULL)){ 86 fprintf(stderr, "Error: unable to parse file \"%s\"\n", tmpl_file); 87 goto done; 88 } 89 90 /* find start node */ 91 node = xmlSecFindNode(xmlDocGetRootElement(doc), xmlSecNodeSignature, xmlSecDSigNs); 92 if(node == NULL) { 93 fprintf(stderr, "Error: start node not found in \"%s\"\n", tmpl_file); 94 goto done; 95 } 96 97 /* create signature context, we don't need keys manager in this example */ 98 dsigCtx = xmlSecDSigCtxCreate(NULL); 99 if(dsigCtx == NULL) { 100 fprintf(stderr,"Error: failed to create signature context\n"); 101 goto done; 102 } 103 104 /* load private key, assuming that there is not password */ 105 dsigCtx->signKey = xmlSecCryptoAppKeyLoad(key_file, xmlSecKeyDataFormatPem, NULL, NULL, NULL); 106 if(dsigCtx->signKey == NULL) { 107 fprintf(stderr,"Error: failed to load private pem key from \"%s\"\n", key_file); 108 goto done; 109 } 110 111 /* set key name to the file name, this is just an example! */ 112 if(xmlSecKeySetName(dsigCtx->signKey, key_file) < 0) { 113 fprintf(stderr,"Error: failed to set key name for key from \"%s\"\n", key_file); 114 goto done; 115 } 116 117 /* sign the template */ 118 if(xmlSecDSigCtxSign(dsigCtx, node) < 0) { 119 fprintf(stderr,"Error: signature failed\n"); 120 goto done; 121 } 122 123 /* print signed document to stdout */ 124 xmlDocDump(stdout, doc); 125 126 /* success */ 127 res = 0; 128 129done: 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-sign1">Full program listing</link></simpara> 142 <simpara><link linkend="xmlsec-example-sign1-tmpl">Simple signature template file</link></simpara> 143 </example> 144 </para> 145 </sect1> 146 147 <sect1 id="xmlsec-notes-encrypt"> 148 <title>Encrypting data.</title> 149 <para>The typical encryption process includes following steps: 150 <itemizedlist> 151 <listitem><para> 152 Prepare data for encryption. 153 </para></listitem> 154 <listitem><para> 155 Create or load encryption template and select start 156 <enc:EncryptedData/> node. 157 </para></listitem> 158 <listitem><para> 159 Create encryption context <link linkend="xmlSecEncCtx">xmlSecEncCtx</link> 160 using <link linkend="xmlSecEncCtxCreate">xmlSecEncCtxCreate</link> or 161 <link linkend="xmlSecEncCtxInitialize">xmlSecEncCtxInitialize</link> 162 functions. 163 </para></listitem> 164 <listitem><para> 165 Load encryption key in <link linkend="xmlSecKeysMngr">keys manager</link> 166 or generate a session key and set it in the encryption context 167 (<structfield>encKey</structfield> member of 168 <link linkend="xmlSecEncCtx">xmlSecEncCtx</link> structure). 169 </para></listitem> 170 <listitem><para> 171 Encrypt data by calling one of the following functions: 172 <itemizedlist> 173 <listitem><para> 174 <link linkend="xmlSecEncCtxBinaryEncrypt">xmlSecEncCtxBinaryEncrypt</link> 175 </para></listitem> 176 <listitem><para> 177 <link linkend="xmlSecEncCtxXmlEncrypt">xmlSecEncCtxXmlEncrypt</link> 178 </para></listitem> 179 <listitem><para> 180 <link linkend="xmlSecEncCtxUriEncrypt">xmlSecEncCtxUriEncrypt</link> 181 </para></listitem> 182 </itemizedlist> 183 </para></listitem> 184 <listitem><para> 185 Check returned value and if necessary consume encrypted data. 186 </para></listitem> 187 <listitem><para> 188 Destroy encryption context <link linkend="xmlSecEncCtx">xmlSecEncCtx</link> 189 using <link linkend="xmlSecEncCtxDestroy">xmlSecEncCtxDestroy</link> or 190 <link linkend="xmlSecEncCtxFinalize">xmlSecEncCtxFinalize</link> 191 functions. 192 </para></listitem> 193 </itemizedlist> 194 </para> 195 <para> 196 <example> 197 <title>Encrypting binary data with a template.</title> 198 <programlisting><![CDATA[ 199/** 200 * encrypt_file: 201 * @tmpl_file: the encryption template file name. 202 * @key_file: the Triple DES key file. 203 * @data: the binary data to encrypt. 204 * @dataSize: the binary data size. 205 * 206 * Encrypts binary #data using template from #tmpl_file and DES key from 207 * #key_file. 208 * 209 * Returns 0 on success or a negative value if an error occurs. 210 */ 211int 212encrypt_file(const char* tmpl_file, const char* key_file, const unsigned char* data, size_t dataSize) { 213 xmlDocPtr doc = NULL; 214 xmlNodePtr node = NULL; 215 xmlSecEncCtxPtr encCtx = NULL; 216 int res = -1; 217 218 assert(tmpl_file); 219 assert(key_file); 220 assert(data); 221 222 /* load template */ 223 doc = xmlParseFile(tmpl_file); 224 if ((doc == NULL) || (xmlDocGetRootElement(doc) == NULL)){ 225 fprintf(stderr, "Error: unable to parse file \"%s\"\n", tmpl_file); 226 goto done; 227 } 228 229 /* find start node */ 230 node = xmlSecFindNode(xmlDocGetRootElement(doc), xmlSecNodeEncryptedData, xmlSecEncNs); 231 if(node == NULL) { 232 fprintf(stderr, "Error: start node not found in \"%s\"\n", tmpl_file); 233 goto done; 234 } 235 236 /* create encryption context, we don't need keys manager in this example */ 237 encCtx = xmlSecEncCtxCreate(NULL); 238 if(encCtx == NULL) { 239 fprintf(stderr,"Error: failed to create encryption context\n"); 240 goto done; 241 } 242 243 /* load DES key */ 244 encCtx->encKey = xmlSecKeyReadBinaryFile(xmlSecKeyDataDesId, key_file); 245 if(encCtx->encKey == NULL) { 246 fprintf(stderr,"Error: failed to load des key from binary file \"%s\"\n", key_file); 247 goto done; 248 } 249 250 /* set key name to the file name, this is just an example! */ 251 if(xmlSecKeySetName(encCtx->encKey, key_file) < 0) { 252 fprintf(stderr,"Error: failed to set key name for key from \"%s\"\n", key_file); 253 goto done; 254 } 255 256 /* encrypt the data */ 257 if(xmlSecEncCtxBinaryEncrypt(encCtx, node, data, dataSize) < 0) { 258 fprintf(stderr,"Error: encryption failed\n"); 259 goto done; 260 } 261 262 /* print encrypted data with document to stdout */ 263 xmlDocDump(stdout, doc); 264 265 /* success */ 266 res = 0; 267 268done: 269 /* cleanup */ 270 if(encCtx != NULL) { 271 xmlSecEncCtxDestroy(encCtx); 272 } 273 274 if(doc != NULL) { 275 xmlFreeDoc(doc); 276 } 277 return(res); 278} 279 ]]></programlisting> 280 <simpara><link linkend="xmlsec-example-encrypt1">Full program listing</link></simpara> 281 <simpara><link linkend="xmlsec-example-encrypt1-tmpl">Simple encryption template file</link></simpara> 282 </example> 283 </para> 284 </sect1> 285</chapter> 286 287