Decrypting data with keys manager.

Home Download News Documentation FAQ Tutorial API reference Examples XML Digital Signature Online Verifier XML Encryption XML Canonicalization Reporting Bugs Mailing list Related
XML Security Library Reference Manual
<<< Previous Page | Home | Up | Next Page >>>
# Decrypting data with keys manager. ## decrypt2.c
    /**
     * XML Security Library example: Decrypting an encrypted file using keys manager.
     *
     * Decrypts encrypted XML file using keys manager and a list of
     * DES key from a binary file
     *
     * Usage:
     *	./decrypt2 <xml-enc> <des-key-file1> [<des-key-file2> [...]]
     *
     * Example:
     *	./decrypt2 encrypt1-res.xml deskey.bin
     *	./decrypt2 encrypt2-res.xml deskey.bin
     *
     * This is free software; see Copyright file in the source
     * distribution for preciese wording.
     *
     * Copyrigth (C) 2002-2003 Aleksey Sanin <aleksey@aleksey.com>
     */
    #include <stdlib.h>
    #include <string.h>
    #include <assert.h>

    #include <libxml/tree.h>
    #include <libxml/xmlmemory.h>
    #include <libxml/parser.h>

    #ifndef XMLSEC_NO_XSLT
    #include <libxslt/xslt.h>
    #endif /* XMLSEC_NO_XSLT */

    #include <xmlsec/xmlsec.h>
    #include <xmlsec/xmltree.h>
    #include <xmlsec/xmlenc.h>
    #include <xmlsec/crypto.h>

    xmlSecKeysMngrPtr load_des_keys(char** files, int files_size);
    int decrypt_file(xmlSecKeysMngrPtr mngr, const char* enc_file);

    int
    main(int argc, char **argv) {
        xmlSecKeysMngrPtr mngr;

        assert(argv);

        if(argc != 3) {
    	fprintf(stderr, "Error: wrong number of arguments.\n");
    	fprintf(stderr, "Usage: %s <enc-file> <key-file1> [<key-file2> [...]]\n", argv[0]);
    	return(1);
        }

        /* Init libxml and libxslt libraries */
        xmlInitParser();
        LIBXML_TEST_VERSION
        xmlLoadExtDtdDefaultValue = XML_DETECT_IDS | XML_COMPLETE_ATTRS;
        xmlSubstituteEntitiesDefault(1);
    #ifndef XMLSEC_NO_XSLT
        xmlIndentTreeOutput = 1;
    #endif /* XMLSEC_NO_XSLT */

        /* Init xmlsec library */
        if(xmlSecInit() < 0) {
    	fprintf(stderr, "Error: xmlsec initialization failed.\n");
    	return(-1);
        }

        /* Init crypto library */
        if(xmlSecCryptoAppInit(NULL) < 0) {
    	fprintf(stderr, "Error: crypto initialization failed.\n");
    	return(-1);
        }

        /* Init xmlsec-crypto library */
        if(xmlSecCryptoInit() < 0) {
    	fprintf(stderr, "Error: xmlsec-crypto initialization failed.\n");
    	return(-1);
        }

        /* create keys manager and load keys */
        mngr = load_des_keys(&(argv[2]), argc - 2);
        if(mngr == NULL) {
    	return(-1);
        }

        if(decrypt_file(mngr, argv[1]) < 0) {
    	xmlSecKeysMngrDestroy(mngr);
    	return(-1);
        }

        /* destroy keys manager */
        xmlSecKeysMngrDestroy(mngr);

        /* Shutdown xmlsec-crypto library */
        xmlSecCryptoShutdown();

        /* Shutdown crypto library */
        xmlSecCryptoAppShutdown();

        /* Shutdown xmlsec library */
        xmlSecShutdown();

        /* Shutdown libxslt/libxml */
    #ifndef XMLSEC_NO_XSLT
        xsltCleanupGlobals();
    #endif /* XMLSEC_NO_XSLT */
        xmlCleanupParser();

        return(0);
    }

    /**
     * load_des_keys:
     * @files:		the list of filenames.
     * @files_size:		the number of filenames in #files.
     *
     * Creates simple keys manager and load DES keys from #files in it.
     * The caller is responsible for destroing returned keys manager using
     * @xmlSecKeysMngrDestroy.
     *
     * Returns the pointer to newly created keys manager or NULL if an error
     * occurs.
     */
    xmlSecKeysMngrPtr
    load_des_keys(char** files, int files_size) {
        xmlSecKeysMngrPtr mngr;
        xmlSecKeyPtr key;
        int i;

        assert(files);
        assert(files_size > 0);

        /* create and initialize keys manager, we use a simple list based
         * keys manager, implement your own xmlSecKeysStore klass if you need
         * something more sophisticated
         */
        mngr = xmlSecKeysMngrCreate();
        if(mngr == NULL) {
    	fprintf(stderr, "Error: failed to create keys manager.\n");
    	return(NULL);
        }
        if(xmlSecCryptoAppDefaultKeysMngrInit(mngr) < 0) {
    	fprintf(stderr, "Error: failed to initialize keys manager.\n");
    	xmlSecKeysMngrDestroy(mngr);
    	return(NULL);
        }

        for(i = 0; i < files_size; ++i) {
    	assert(files[i]);

    	/* load DES key */
    	key = xmlSecKeyReadBinaryFile(xmlSecKeyDataDesId, files[i]);
    	if(key == NULL) {
        	    fprintf(stderr,"Error: failed to load des key from binary file \"%s\"\n", files[i]);
    	    xmlSecKeysMngrDestroy(mngr);
    	    return(NULL);
    	}

    	/* set key name to the file name, this is just an example! */
    	if(xmlSecKeySetName(key, BAD_CAST files[i]) < 0) {
        	    fprintf(stderr,"Error: failed to set key name for key from \"%s\"\n", files[i]);
    	    xmlSecKeyDestroy(key);
    	    xmlSecKeysMngrDestroy(mngr);
    	    return(NULL);
    	}

    	/* add key to keys manager, from now on keys manager is responsible
    	 * for destroying key
    	 */
    	if(xmlSecCryptoAppDefaultKeysMngrAdoptKey(mngr, key) < 0) {
        	    fprintf(stderr,"Error: failed to add key from \"%s\" to keys manager\n", files[i]);
    	    xmlSecKeyDestroy(key);
    	    xmlSecKeysMngrDestroy(mngr);
    	    return(NULL);
    	}
        }

        return(mngr);
    }

    /**
     * decrypt_file:
     * @mngr:		the pointer to keys manager.
     * @enc_file:		the encrypted XML  file name.
     *
     * Decrypts the XML file #enc_file using DES key from #key_file and
     * prints results to stdout.
     *
     * Returns 0 on success or a negative value if an error occurs.
     */
    int
    decrypt_file(xmlSecKeysMngrPtr mngr, const char* enc_file) {
        xmlDocPtr doc = NULL;
        xmlNodePtr node = NULL;
        xmlSecEncCtxPtr encCtx = NULL;
        int res = -1;

        assert(mngr);
        assert(enc_file);

        /* load template */
        doc = xmlParseFile(enc_file);
        if ((doc == NULL) || (xmlDocGetRootElement(doc) == NULL)){
    	fprintf(stderr, "Error: unable to parse file \"%s\"\n", enc_file);
    	goto done;
        }

        /* find start node */
        node = xmlSecFindNode(xmlDocGetRootElement(doc), xmlSecNodeEncryptedData, xmlSecEncNs);
        if(node == NULL) {
    	fprintf(stderr, "Error: start node not found in \"%s\"\n", enc_file);
    	goto done;
        }

        /* create encryption context */
        encCtx = xmlSecEncCtxCreate(mngr);
        if(encCtx == NULL) {
            fprintf(stderr,"Error: failed to create encryption context\n");
    	goto done;
        }

        /* decrypt the data */
        if((xmlSecEncCtxDecrypt(encCtx, node) < 0) || (encCtx->result == NULL)) {
            fprintf(stderr,"Error: decryption failed\n");
    	goto done;
        }

        /* print decrypted data to stdout */
        if(encCtx->resultReplaced != 0) {
    	fprintf(stdout, "Decrypted XML data:\n");
    	xmlDocDump(stdout, doc);
        } else {
    	fprintf(stdout, "Decrypted binary data (%d bytes):\n", xmlSecBufferGetSize(encCtx->result));
    	if(xmlSecBufferGetData(encCtx->result) != NULL) {
    	    fwrite(xmlSecBufferGetData(encCtx->result),
    	          1,
    	          xmlSecBufferGetSize(encCtx->result),
    	          stdout);
    	}
        }
        fprintf(stdout, "\n");

        /* success */
        res = 0;

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

        if(doc != NULL) {
    	xmlFreeDoc(doc);
        }
        return(res);
    }
<<< Previous Page | Home | Up | Next Page >>>
Decrypting data with a single key. | Writing a custom keys manager.
Aleksey Sanin