XML Security Library

LibXML2
LibXSLT
OpenSSL

Creating dynamic encryption templates.

The encryption template has structure similar to the XML Encryption structure as it is described in specification. The only difference is that some nodes (for example, <enc:CipherValue/>) are empty. The XML Security Library sets the content of these nodes after doing necessary calculations.

Figure 4. XML Encryption structure

<enc:EncryptedData Id? Type? MimeType? Encoding?>
    <enc:EncryptionMethod Algorithm />?
    (<dsig:KeyInfo>
	<dsig:KeyName>?
	<dsig:KeyValue>?
	<dsig:RetrievalMethod>?
	<dsig:X509Data>?
	<dsig:PGPData>?
	<enc:EncryptedKey>?
	<enc:AgreementMethod>?
	<dsig:KeyName>?
	<dsig:RetrievalMethod>?
	<*>?
    </dsig:KeyInfo>)?
    <enc:CipherData>
	<enc:CipherValue>?
	<enc:CipherReference URI?>?
    </enc:CipherData>
    <enc:EncryptionProperties>?
</enc:EncryptedData>	
	    

Example 13. Creating dynamic encrytion template.

/**
 * encrypt_file:
 * @xml_file:		the encryption template file name.
 * @key_file:		the Triple DES key file.
 *
 * Encrypts #xml_file using a dynamicaly created template and DES key from
 * #key_file.
 *
 * Returns 0 on success or a negative value if an error occurs.
 */
int 
encrypt_file(const char* xml_file, const char* key_file) {
    xmlDocPtr doc = NULL;
    xmlNodePtr encDataNode = NULL;
    xmlNodePtr keyInfoNode = NULL;
    xmlSecEncCtxPtr encCtx = NULL;
    int res = -1;
    
    assert(xml_file);
    assert(key_file);

    /* load template */
    doc = xmlParseFile(xml_file);
    if ((doc == NULL) || (xmlDocGetRootElement(doc) == NULL)){
	fprintf(stderr, "Error: unable to parse file \"%s\"\n", xml_file);
	goto done;	
    }
    
    /* create encryption template to encrypt XML file and replace 
     * its content with encryption result */
    encDataNode = xmlSecTmplEncDataCreate(doc, xmlSecTransformDes3CbcId,
				NULL, xmlSecTypeEncElement, NULL, NULL);
    if(encDataNode == NULL) {
	fprintf(stderr, "Error: failed to create encryption template\n");
	goto done;   
    }

    /* we want to put encrypted data in the <enc:CipherValue/> node */
    if(xmlSecTmplEncDataEnsureCipherValue(encDataNode) == NULL) {
	fprintf(stderr, "Error: failed to add CipherValue node\n");
	goto done;   
    }

    /* add <dsig:KeyInfo/> and <dsig:KeyName/> nodes to put key name in the signed document */
    keyInfoNode = xmlSecTmplEncDataEnsureKeyInfo(encDataNode, NULL);
    if(keyInfoNode == NULL) {
	fprintf(stderr, "Error: failed to add key info\n");
	goto done;		
    }

    if(xmlSecTmplKeyInfoAddKeyName(keyInfoNode, NULL) == NULL) {
	fprintf(stderr, "Error: failed to add key name\n");
	goto done;		
    }

    /* create encryption context, we don't need keys manager in this example */
    encCtx = xmlSecEncCtxCreate(NULL);
    if(encCtx == NULL) {
        fprintf(stderr,"Error: failed to create encryption context\n");
	goto done;
    }

    /* load DES key, assuming that there is not password */
    encCtx->encKey = xmlSecKeyReadBinaryFile(xmlSecKeyDataDesId, key_file);
    if(encCtx->encKey == NULL) {
        fprintf(stderr,"Error: failed to load des key from binary file \"%s\"\n", key_file);
	goto done;
    }

    /* set key name to the file name, this is just an example! */
    if(xmlSecKeySetName(encCtx->encKey, key_file) < 0) {
    	fprintf(stderr,"Error: failed to set key name for key from \"%s\"\n", key_file);
	goto done;
    }

    /* encrypt the data */
    if(xmlSecEncCtxXmlEncrypt(encCtx, encDataNode, xmlDocGetRootElement(doc)) < 0) {
        fprintf(stderr,"Error: encryption failed\n");
	goto done;
    }
    
    /* we template is inserted in the doc */
    encDataNode = NULL;
        
    /* print encrypted data with document to stdout */
    xmlDocDump(stdout, doc);
    
    /* success */
    res = 0;

done:    

    /* cleanup */
    if(encCtx != NULL) {
	xmlSecEncCtxDestroy(encCtx);
    }

    if(encDataNode != NULL) {
	xmlFreeNode(encDataNode);
    }
        
    if(doc != NULL) {
	xmlFreeDoc(doc); 
    }
    return(res);
}
		

Full program listing