You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@santuario.apache.org by bl...@apache.org on 2003/09/08 14:07:50 UTC

cvs commit: xml-security/c/src/xenc/impl XENCCipherDataImpl.cpp XENCCipherDataImpl.hpp XENCCipherImpl.cpp XENCCipherImpl.hpp XENCCipherValueImpl.cpp XENCCipherValueImpl.hpp XENCEncryptedDataImpl.cpp XENCEncryptedDataImpl.hpp XENCEncryptedTypeImpl.cpp XENCEncryptedTypeImpl.hpp

blautenb    2003/09/08 05:07:50

  Modified:    c/src/enc XSECCryptoSymmetricKey.hpp
               c/src/enc/OpenSSL OpenSSLCryptoSymmetricKey.cpp
                        OpenSSLCryptoSymmetricKey.hpp
               c/src/tools/xtest xtest.cpp
               c/src/transformers TXFMBase64.cpp TXFMBase64.hpp
                        TXFMCipher.cpp
               c/src/utils XSECDOMUtils.cpp XSECDOMUtils.hpp
                        XSECSafeBuffer.cpp XSECSafeBuffer.hpp
               c/src/xenc XENCCipher.hpp XENCCipherData.hpp
                        XENCEncryptedData.hpp XENCEncryptedType.hpp
               c/src/xenc/impl XENCCipherDataImpl.cpp
                        XENCCipherDataImpl.hpp XENCCipherImpl.cpp
                        XENCCipherImpl.hpp XENCCipherValueImpl.cpp
                        XENCCipherValueImpl.hpp XENCEncryptedDataImpl.cpp
                        XENCEncryptedDataImpl.hpp XENCEncryptedTypeImpl.cpp
                        XENCEncryptedTypeImpl.hpp
  Log:
  Working skeleton for XML Encryption
  
  Revision  Changes    Path
  1.2       +65 -1     xml-security/c/src/enc/XSECCryptoSymmetricKey.hpp
  
  Index: XSECCryptoSymmetricKey.hpp
  ===================================================================
  RCS file: /home/cvs/xml-security/c/src/enc/XSECCryptoSymmetricKey.hpp,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- XSECCryptoSymmetricKey.hpp	31 Aug 2003 12:48:50 -0000	1.1
  +++ XSECCryptoSymmetricKey.hpp	8 Sep 2003 12:07:48 -0000	1.2
  @@ -243,6 +243,70 @@
   	virtual unsigned int decryptFinish(unsigned char * plainBuf,
   									   unsigned int maxOutLength) = 0;
   
  +	/**
  +	 * \brief Initialise an encryption process
  +	 *
  +	 * Setup the key to get ready for a decryption session.
  +	 * Callers can pass in an IV.  If one is not provided, 
  +	 * but the algorithm requires one (e.g. 3DES_CBC), then
  +	 * implementations are required to generate one.
  +	 *
  +	 * @param iv Initialisation Vector to be used.  NULL if one is
  +	 * not required, or if IV is to be generated
  +	 * @returns true if the initialisation succeeded.
  +	 */
  +
  +	virtual bool encryptInit(const unsigned char * iv = NULL) = 0;
  +
  +	/**
  +	 * \brief Continue an encryption operation using this key.
  +	 *
  +	 * Encryption must have been set up using an encryptInit
  +	 * call.  Takes the inBuf and continues a encryption operation,
  +	 * writing the output to outBuf.
  +	 *
  +	 * This function does not have to guarantee that all input
  +	 * will be encrypted.  In cases where the input is not a length
  +	 * of the block size, the implementation will need to hold back
  +	 * plain-text to be handled during the next operation.
  +	 *
  +	 * @param inBuf Octets to be encrypted
  +	 * @param cipherBuf Buffer to place output in
  +	 * @param inLength Number of bytes to encrypt
  +	 * @param maxOutLength Maximum number of bytes to place in output 
  +	 * buffer
  +	 * @returns Bytes placed in output Buffer
  +	 */
  +
  +	virtual unsigned int encrypt(const unsigned char * inBuf, 
  +								 unsigned char * cipherBuf, 
  +								 unsigned int inLength,
  +								 unsigned int maxOutLength) = 0;
  +
  +	/**
  +	 * \brief Finish a encryption operation
  +	 *
  +	 * Complete a encryption process.  No plain text is passed in,
  +	 * as this should simply be removing any remaining text from
  +	 * the plain storage buffer and creating a final padded block.
  +	 *
  +	 * Padding is performed by taking the remaining block, and
  +	 * setting the last byte to equal the number of bytes of
  +	 * padding.  If the plain was an exact multiple of the block size,
  +	 * then an extra block of padding will be used.  For example, if 
  +	 * the block size is 8 bytes, and there were three remaining plain
  +	 * text bytes (0x01, 0x02 and 0x03), the final block will be :
  +	 *
  +	 * 0x010203????????05
  +	 *
  +	 * @param cipherBuf Buffer to place final block of cipher text in
  +	 * @param maxOutLength Maximum number of bytes to pace in output
  +	 * @returns Bytes placed in output buffer
  +	 */
  +
  +	virtual unsigned int encryptFinish(unsigned char * plainBuf,
  +									   unsigned int maxOutLength) = 0;
  +
   	//@}
   
   };
  
  
  
  1.2       +126 -1    xml-security/c/src/enc/OpenSSL/OpenSSLCryptoSymmetricKey.cpp
  
  Index: OpenSSLCryptoSymmetricKey.cpp
  ===================================================================
  RCS file: /home/cvs/xml-security/c/src/enc/OpenSSL/OpenSSLCryptoSymmetricKey.cpp,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- OpenSSLCryptoSymmetricKey.cpp	31 Aug 2003 12:48:50 -0000	1.1
  +++ OpenSSLCryptoSymmetricKey.cpp	8 Sep 2003 12:07:48 -0000	1.2
  @@ -290,3 +290,128 @@
   
   }
   
  +// --------------------------------------------------------------------------------
  +//           Encrypt
  +// --------------------------------------------------------------------------------
  +
  +bool OpenSSLCryptoSymmetricKey::encryptInit(const unsigned char * iv) {
  +
  +	if (m_initialised == true)
  +		return true;
  +	
  +	if (m_keyLen == 0) {
  +
  +		throw XSECCryptoException(XSECCryptoException::SymmetricError,
  +			"OpenSSL:SymmetricKey - Cannot initialise without key"); 
  +
  +	}
  +
  +	m_initialised = true;
  +
  +	// Set up the context according to the required cipher type
  +
  +	const unsigned char * usedIV;
  +	const unsigned char tstIV[] = "abcdefghijklmnopqrstuvwxyz";
  +
  +	// Tell the library that the IV still has to be sent
  +	m_ivSent = false;
  +
  +	switch (m_keyType) {
  +
  +	case (XSECCryptoSymmetricKey::KEY_3DES_CBC_192) :
  +
  +		// A 3DES key
  +
  +		if (iv == NULL) {
  +			
  +			usedIV = tstIV;
  +			//return 0;	// Cannot initialise without an IV
  +
  +		}
  +		else
  +			usedIV = iv;
  +
  +		EVP_EncryptInit_ex(&m_ctx, EVP_des_ede3_cbc(), NULL, m_keyBuf.rawBuffer(), usedIV);
  +		// Turn off padding
  +		// EVP_CIPHER_CTX_set_padding(&m_ctx, 0);
  +
  +		// That means we have to handle padding, so we always hold back
  +		// 8 bytes of data.
  +		m_blockSize = 8;
  +		m_ivSize = 8;
  +		memcpy(m_lastBlock, usedIV, m_ivSize);
  +		m_bytesInLastBlock = 0;
  +
  +		break;
  +
  +	default :
  +
  +		// Cannot do this without an IV
  +		throw XSECCryptoException(XSECCryptoException::SymmetricError,
  +			"OpenSSL:SymmetricKey - Unknown key type"); 
  +
  +	}
  +
  +	return true;
  +
  +}
  +
  +unsigned int OpenSSLCryptoSymmetricKey::encrypt(const unsigned char * inBuf, 
  +								 unsigned char * cipherBuf, 
  +								 unsigned int inLength,
  +								 unsigned int maxOutLength) {
  +
  +	if (m_initialised == false) {
  +
  +		encryptInit();
  +
  +	}
  +
  +	// NOTE: This won't actually stop OpenSSL blowing the buffer, so the onus is
  +	// on the caller.
  +
  +	unsigned int offset = 0;
  +	if (m_ivSent == false && m_ivSize > 0) {
  +
  +		memcpy(cipherBuf, m_lastBlock, m_ivSize);
  +		m_ivSent = true;
  +
  +		offset = m_ivSize;
  +
  +	}
  +
  +	int outl = maxOutLength - offset;
  +
  +	if (inLength + offset > maxOutLength) {
  +
  +		throw XSECCryptoException(XSECCryptoException::SymmetricError,
  +			"OpenSSL:SymmetricKey - Not enough space in output buffer for encrypt"); 
  +
  +	}
  +
  +	if (EVP_EncryptUpdate(&m_ctx, &cipherBuf[offset], &outl, inBuf, inLength) == 0) {
  +
  +		throw XSECCryptoException(XSECCryptoException::SymmetricError,
  +			"OpenSSL:SymmetricKey - Error during OpenSSL encrypt"); 
  +
  +	}
  +
  +	return outl + offset;
  +
  +}
  +
  +unsigned int OpenSSLCryptoSymmetricKey::encryptFinish(unsigned char * cipherBuf,
  +													  unsigned int maxOutLength) {
  +
  +	int outl = maxOutLength;
  +
  +	if (EVP_EncryptFinal_ex(&m_ctx, cipherBuf, &outl) == 0) {
  +
  +		throw XSECCryptoException(XSECCryptoException::SymmetricError,
  +			"OpenSSL:SymmetricKey - Error during OpenSSL decrypt finalisation"); 
  +
  +	}
  +
  +	return outl;
  +
  +}
  
  
  
  1.2       +67 -1     xml-security/c/src/enc/OpenSSL/OpenSSLCryptoSymmetricKey.hpp
  
  Index: OpenSSLCryptoSymmetricKey.hpp
  ===================================================================
  RCS file: /home/cvs/xml-security/c/src/enc/OpenSSL/OpenSSLCryptoSymmetricKey.hpp,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- OpenSSLCryptoSymmetricKey.hpp	31 Aug 2003 12:48:50 -0000	1.1
  +++ OpenSSLCryptoSymmetricKey.hpp	8 Sep 2003 12:07:48 -0000	1.2
  @@ -233,6 +233,70 @@
   	virtual unsigned int decryptFinish(unsigned char * plainBuf,
   									   unsigned int maxOutLength);
   
  +	/**
  +	 * \brief Initialise an encryption process
  +	 *
  +	 * Setup the key to get ready for a decryption session.
  +	 * Callers can pass in an IV.  If one is not provided, 
  +	 * but the algorithm requires one (e.g. 3DES_CBC), then
  +	 * implementations are required to generate one.
  +	 *
  +	 * @param iv Initialisation Vector to be used.  NULL if one is
  +	 * not required, or if IV is to be generated
  +	 * @returns true if the initialisation succeeded.
  +	 */
  +
  +	virtual bool encryptInit(const unsigned char * iv = NULL);
  +
  +	/**
  +	 * \brief Continue an encryption operation using this key.
  +	 *
  +	 * Encryption must have been set up using an encryptInit
  +	 * call.  Takes the inBuf and continues a encryption operation,
  +	 * writing the output to outBuf.
  +	 *
  +	 * This function does not have to guarantee that all input
  +	 * will be encrypted.  In cases where the input is not a length
  +	 * of the block size, the implementation will need to hold back
  +	 * plain-text to be handled during the next operation.
  +	 *
  +	 * @param inBuf Octets to be encrypted
  +	 * @param cipherBuf Buffer to place output in
  +	 * @param inLength Number of bytes to encrypt
  +	 * @param maxOutLength Maximum number of bytes to place in output 
  +	 * buffer
  +	 * @returns Bytes placed in output Buffer
  +	 */
  +
  +	virtual unsigned int encrypt(const unsigned char * inBuf, 
  +								 unsigned char * cipherBuf, 
  +								 unsigned int inLength,
  +								 unsigned int maxOutLength);
  +
  +	/**
  +	 * \brief Finish a encryption operation
  +	 *
  +	 * Complete a encryption process.  No plain text is passed in,
  +	 * as this should simply be removing any remaining text from
  +	 * the plain storage buffer and creating a final padded block.
  +	 *
  +	 * Padding is performed by taking the remaining block, and
  +	 * setting the last byte to equal the number of bytes of
  +	 * padding.  If the plain was an exact multiple of the block size,
  +	 * then an extra block of padding will be used.  For example, if 
  +	 * the block size is 8 bytes, and there were three remaining plain
  +	 * text bytes (0x01, 0x02 and 0x03), the final block will be :
  +	 *
  +	 * 0x010203????????05
  +	 *
  +	 * @param cipherBuf Buffer to place final block of cipher text in
  +	 * @param maxOutLength Maximum number of bytes to pace in output
  +	 * @returns Bytes placed in output buffer
  +	 */
  +
  +	virtual unsigned int encryptFinish(unsigned char * plainBuf,
  +									   unsigned int maxOutLength);
  +
   	//@}
   
   private:
  @@ -254,7 +318,9 @@
   	bool							m_initialised;	// Is the context ready to work?
   	unsigned char					m_lastBlock[MAX_BLOCK_SIZE];
   	int								m_blockSize;
  +	int								m_ivSize;
   	int								m_bytesInLastBlock;
  +	bool							m_ivSent;		// Has the IV been put in the stream
   
   };
   
  
  
  
  1.18      +572 -323  xml-security/c/src/tools/xtest/xtest.cpp
  
  Index: xtest.cpp
  ===================================================================
  RCS file: /home/cvs/xml-security/c/src/tools/xtest/xtest.cpp,v
  retrieving revision 1.17
  retrieving revision 1.18
  diff -u -r1.17 -r1.18
  --- xtest.cpp	5 Aug 2003 11:36:09 -0000	1.17
  +++ xtest.cpp	8 Sep 2003 12:07:48 -0000	1.18
  @@ -122,9 +122,12 @@
   #include <xsec/dsig/DSIGKeyInfoPGPData.hpp>
   #include <xsec/dsig/DSIGKeyInfoSPKIData.hpp>
   #include <xsec/dsig/DSIGKeyInfoMgmtData.hpp>
  +#include <xsec/xenc/XENCCipher.hpp>
  +#include <xsec/xenc/XENCEncryptedData.hpp>
   
   #if defined (HAVE_OPENSSL)
   #	include <xsec/enc/OpenSSL/OpenSSLCryptoKeyHMAC.hpp>
  +#	include <xsec/enc/OpenSSL/OpenSSLCryptoSymmetricKey.hpp>
   #endif
   #if defined (HAVE_WINCAPI)
   #	include <xsec/enc/WinCAPI/WinCAPICryptoKeyHMAC.hpp>
  @@ -137,13 +140,18 @@
   using std::flush;
   
   /*
  - * Because of all the characters, it's easiest to put the entire program
  - * in the Xerces namespace
  + * Because of all the characters, it's easiest to inject entire Xerces namespace
  + * into global
    */
   
   XERCES_CPP_NAMESPACE_USE
   
   // --------------------------------------------------------------------------------
  +//           Global variables
  +// --------------------------------------------------------------------------------
  +
  +bool	g_printDocs = false;
  +// --------------------------------------------------------------------------------
   //           Known "Good" Values
   // --------------------------------------------------------------------------------
   
  @@ -235,6 +243,35 @@
   };
   
   // --------------------------------------------------------------------------------
  +//           Find a node
  +// --------------------------------------------------------------------------------
  +
  +DOMNode * findNode(DOMNode * n, XMLCh * name) {
  +
  +	if (XMLString::compareString(name, n->getNodeName()) == 0)
  +		return n;
  +
  +	DOMNode * c = n->getFirstChild();
  +
  +	while (c != NULL) {
  +
  +		if (c->getNodeType() == DOMNode::ELEMENT_NODE) {
  +
  +			DOMNode * s = findNode(c, name);
  +			if (s != NULL)
  +				return s;
  +
  +		}
  +
  +		c = c->getNextSibling();
  +
  +	}
  +
  +	return NULL;
  +
  +}
  +
  +// --------------------------------------------------------------------------------
   //           Create a key
   // --------------------------------------------------------------------------------
   
  @@ -279,449 +316,661 @@
   }
   
   // --------------------------------------------------------------------------------
  -//           Main
  +//           Create a basic document
   // --------------------------------------------------------------------------------
   
  -int main(int argc, char **argv) {
  +DOMDocument * createTestDoc(DOMImplementation * impl) {
   
  -	/* We output a version number to overcome a "feature" in Microsoft's memory
  -	   leak detection */
  +	DOMDocument *doc = impl->createDocument(
  +				0,                    // root element namespace URI.
  +				MAKE_UNICODE_STRING("ADoc"),            // root element name
  +				NULL);// DOMDocumentType());  // document type object (DTD).
   
  -	cerr << "DSIG Info (Using Apache XML-Security-C Library v" << XSEC_VERSION_MAJOR <<
  -		"." << XSEC_VERSION_MEDIUM << "." << XSEC_VERSION_MINOR << ")\n";
  +	DOMElement *rootElem = doc->getDocumentElement();
  +	rootElem->setAttributeNS(DSIGConstants::s_unicodeStrURIXMLNS, 
  +		MAKE_UNICODE_STRING("xmlns:foo"), MAKE_UNICODE_STRING("http://www.foo.org"));
   
  -#if defined (_DEBUG) && defined (_MSC_VER)
  +	DOMElement  * prodElem = doc->createElement(MAKE_UNICODE_STRING("product"));
  +	rootElem->appendChild(prodElem);
   
  -	// Do some memory debugging under Visual C++
  +	DOMText    * prodDataVal = doc->createTextNode(MAKE_UNICODE_STRING("XMLSecurityC"));
  +	prodElem->appendChild(prodDataVal);
   
  -	_CrtMemState s1, s2, s3;
  +	DOMElement  *catElem = doc->createElement(MAKE_UNICODE_STRING("category"));
  +	rootElem->appendChild(catElem);
  +	catElem->setAttribute(MAKE_UNICODE_STRING("idea"), MAKE_UNICODE_STRING("great"));
   
  -	// At this point we are about to start really using XSEC, so
  -	// Take a "before" checkpoing
  +	DOMText    *catDataVal = doc->createTextNode(MAKE_UNICODE_STRING("XML Security Tools"));
  +	catElem->appendChild(catDataVal);
   
  -	_CrtMemCheckpoint( &s1 );
  +	return doc;
   
  -#endif
  +}
  +// --------------------------------------------------------------------------------
  +//           Output a document if so required
  +// --------------------------------------------------------------------------------
   
  -	// First initialise the XML system
  +void outputDoc(DOMImplementation * impl, DOMDocument * doc) {
  +
  +	if (g_printDocs == false)
  +		return;
  +
  +	DOMWriter         *theSerializer = ((DOMImplementationLS*)impl)->createDOMWriter();
  +
  +	theSerializer->setEncoding(MAKE_UNICODE_STRING("UTF-8"));
  +	if (theSerializer->canSetFeature(XMLUni::fgDOMWRTFormatPrettyPrint, false))
  +		theSerializer->setFeature(XMLUni::fgDOMWRTFormatPrettyPrint, false);
  +
  +
  +	XMLFormatTarget *formatTarget = new StdOutFormatTarget();
  +
  +	theSerializer->writeNode(formatTarget, *doc);
  +	
  +	cout << endl;
  +
  +	delete theSerializer;
  +	delete formatTarget;
  +
  +}
  +
  +// --------------------------------------------------------------------------------
  +//           Basic tests of signature function
  +// --------------------------------------------------------------------------------
  +
  +void testSignature(DOMImplementation *impl) {
  +
  +	cerr << "Creating a known doc and signing (HMAC-SHA1)" << endl;
  +	
  +	// Create a document
  +    
  +	DOMDocument * doc = createTestDoc(impl);
  +
  +	// Check signature functions
  +
  +	XSECProvider prov;
  +	DSIGSignature *sig;
  +	DSIGReference *ref[10];
  +	DOMElement *sigNode;
  +	int refCount;
   
   	try {
  +		
  +		/*
  +		 * Now we have a document, create a signature for it.
  +		 */
  +		
  +		sig = prov.newSignature();
  +		sig->setDSIGNSPrefix(MAKE_UNICODE_STRING("ds"));
   
  -		XMLPlatformUtils::Initialize();
  -#ifndef XSEC_NO_XALAN
  -		XPathEvaluator::initialize();
  -		XalanTransformer::initialize();
  -#endif
  -		XSECPlatformUtils::Initialise();
  +		sigNode = sig->createBlankSignature(doc, CANON_C14N_COM, SIGNATURE_HMAC, HASH_SHA1);
  +		DOMElement * rootElem = doc->getDocumentElement();
  +		DOMNode * prodElem = rootElem->getFirstChild();
  +
  +		rootElem->appendChild(doc->createTextNode(DSIGConstants::s_unicodeStrNL));
  +		rootElem->insertBefore(doc->createComment(MAKE_UNICODE_STRING(" a comment ")), prodElem);
  +		rootElem->appendChild(sigNode);
  +		rootElem->insertBefore(doc->createTextNode(DSIGConstants::s_unicodeStrNL), prodElem);
   
  -	}
  -	catch (const XMLException &e) {
  +		/*
  +		 * Add some test references
  +		 */
   
  -		cerr << "Error during initialisation of Xerces" << endl;
  -		cerr << "Error Message = : "
  -		     << e.getMessage() << endl;
  +		ref[0] = sig->createReference(MAKE_UNICODE_STRING(""));
  +		ref[0]->appendEnvelopedSignatureTransform();
   
  -	}
  +		ref[1] = sig->createReference(MAKE_UNICODE_STRING("#xpointer(/)"));
  +		ref[1]->appendEnvelopedSignatureTransform();
  +		ref[1]->appendCanonicalizationTransform(CANON_C14N_NOC);
  +
  +		ref[2] = sig->createReference(MAKE_UNICODE_STRING("#xpointer(/)"));
  +		ref[2]->appendEnvelopedSignatureTransform();
  +		ref[2]->appendCanonicalizationTransform(CANON_C14N_COM);
  +
  +		ref[3] = sig->createReference(MAKE_UNICODE_STRING("#xpointer(/)"));
  +		ref[3]->appendEnvelopedSignatureTransform();
  +		ref[3]->appendCanonicalizationTransform(CANON_C14NE_NOC);
  +
  +		ref[4] = sig->createReference(MAKE_UNICODE_STRING("#xpointer(/)"));
  +		ref[4]->appendEnvelopedSignatureTransform();
  +		ref[4]->appendCanonicalizationTransform(CANON_C14NE_COM);
  +
  +		ref[5] = sig->createReference(MAKE_UNICODE_STRING("#xpointer(/)"));
  +		ref[5]->appendEnvelopedSignatureTransform();
  +		DSIGTransformC14n * ce = ref[5]->appendCanonicalizationTransform(CANON_C14NE_COM);
  +		ce->addInclusiveNamespace("foo");
  +
  +		sig->setECNSPrefix(MAKE_UNICODE_STRING("ec"));
  +		ref[6] = sig->createReference(MAKE_UNICODE_STRING("#xpointer(/)"));
  +		ref[6]->appendEnvelopedSignatureTransform();
  +		ce = ref[6]->appendCanonicalizationTransform(CANON_C14NE_COM);
  +		ce->addInclusiveNamespace("foo");
   
  -	{
  +#ifdef XSEC_NO_XALAN
   
  +		cerr << "WARNING : No testing of XPath being performed as Xalan not present" << endl;
  +		refCount = 7;
  +
  +#else
   		/*
  -		 * First we create a document from scratch
  +		 * Create some XPath/XPathFilter references
   		 */
   
  -		cerr << "Creating a known doc and signing (HMAC-SHA1)" << endl;
  -		
  -		// Create a blank Document
   
  -		//DOMImplementation impl;
  +		ref[7] = sig->createReference(MAKE_UNICODE_STRING(""));
  +		sig->setXPFNSPrefix(MAKE_UNICODE_STRING("xpf"));
  +		DSIGTransformXPathFilter * xpf = ref[7]->appendXPathFilterTransform();
  +		xpf->appendFilter(FILTER_INTERSECT, MAKE_UNICODE_STRING("//ADoc/category"));
  +
  +		ref[8] = sig->createReference(MAKE_UNICODE_STRING(""));
  +		/*		ref[5]->appendXPathTransform("ancestor-or-self::dsig:Signature", 
  +				"xmlns:dsig=http://www.w3.org/2000/09/xmldsig#"); */
  +
  +		DSIGTransformXPath * x = ref[8]->appendXPathTransform("count(ancestor-or-self::dsig:Signature | \
  +here()/ancestor::dsig:Signature[1]) > \
  +count(ancestor-or-self::dsig:Signature)");
  +		x->setNamespace("dsig", "http://www.w3.org/2000/09/xmldsig#");
   
  -		XMLCh tempStr[100];
  -		XMLString::transcode("Core", tempStr, 99);    
  -		DOMImplementation *impl = DOMImplementationRegistry::getDOMImplementation(tempStr);
  -        
  +		refCount = 9;
   
  -		DOMDocument *doc = impl->createDocument(
  -					0,                    // root element namespace URI.
  -					MAKE_UNICODE_STRING("ADoc"),            // root element name
  -					NULL);// DOMDocumentType());  // document type object (DTD).
  +#endif
  +	
  +		/*
  +		 * Sign the document, using an HMAC algorithm and the key "secret"
  +		 */
   
  -		DOMElement *rootElem = doc->getDocumentElement();
  -		rootElem->setAttributeNS(DSIGConstants::s_unicodeStrURIXMLNS, 
  -			MAKE_UNICODE_STRING("xmlns:foo"), MAKE_UNICODE_STRING("http://www.foo.org"));
   
  -		DOMElement  * prodElem = doc->createElement(MAKE_UNICODE_STRING("product"));
  -		rootElem->appendChild(prodElem);
  +		sig->appendKeyName(MAKE_UNICODE_STRING("The secret key is \"secret\""));
   
  -		DOMText    * prodDataVal = doc->createTextNode(MAKE_UNICODE_STRING("XMLSecurityC"));
  -		prodElem->appendChild(prodDataVal);
  +		// Append a test DNames
   
  -		DOMElement  *catElem = doc->createElement(MAKE_UNICODE_STRING("category"));
  -		rootElem->appendChild(catElem);
  -		catElem->setAttribute(MAKE_UNICODE_STRING("idea"), MAKE_UNICODE_STRING("great"));
  +		DSIGKeyInfoX509 * x509 = sig->appendX509Data();
  +		x509->setX509SubjectName(s_tstDName);
   
  -		DOMText    *catDataVal = doc->createTextNode(MAKE_UNICODE_STRING("XML Security Tools"));
  -		catElem->appendChild(catDataVal);
  +		// Append a test PGPData element
  +		sig->appendPGPData(s_tstPGPKeyID, s_tstPGPKeyPacket);
   
  -		XSECProvider prov;
  -		DSIGSignature *sig;
  -		DSIGReference *ref[10];
  -		DOMElement *sigNode;
  -		int refCount;
  +		// Append an SPKIData element
  +		DSIGKeyInfoSPKIData * spki = sig->appendSPKIData(s_tstSexp1);
  +		spki->appendSexp(s_tstSexp2);
   
  -		try {
  -			
  -			/*
  -			 * Now we have a document, create a signature for it.
  -			 */
  -			
  -			sig = prov.newSignature();
  -			sig->setDSIGNSPrefix(MAKE_UNICODE_STRING("ds"));
  +		// Append a MgmtData element
  +		sig->appendMgmtData(s_tstMgmtData);
   
  -			sigNode = sig->createBlankSignature(doc, CANON_C14N_COM, SIGNATURE_HMAC, HASH_SHA1);
  -			rootElem->appendChild(doc->createTextNode(DSIGConstants::s_unicodeStrNL));
  -			rootElem->insertBefore(doc->createComment(MAKE_UNICODE_STRING(" a comment ")), prodElem);
  -			rootElem->appendChild(sigNode);
  -			rootElem->insertBefore(doc->createTextNode(DSIGConstants::s_unicodeStrNL), prodElem);
  +		sig->setSigningKey(createHMACKey((unsigned char *) "secret"));
  +		sig->sign();
   
  -			/*
  -			 * Add some test references
  -			 */
  +		cerr << "Doc signed OK - Checking values against Known Good" << endl;
   
  -			ref[0] = sig->createReference(MAKE_UNICODE_STRING(""));
  -			ref[0]->appendEnvelopedSignatureTransform();
  +		unsigned char buf[128];
  +		int len;
   
  -			ref[1] = sig->createReference(MAKE_UNICODE_STRING("#xpointer(/)"));
  -			ref[1]->appendEnvelopedSignatureTransform();
  -			ref[1]->appendCanonicalizationTransform(CANON_C14N_NOC);
  +		/*
  +		 * Validate the reference hash values from known good
  +		 */
   
  -			ref[2] = sig->createReference(MAKE_UNICODE_STRING("#xpointer(/)"));
  -			ref[2]->appendEnvelopedSignatureTransform();
  -			ref[2]->appendCanonicalizationTransform(CANON_C14N_COM);
  +		int i;
  +		for (i = 0; i < refCount; ++i) {
   
  -			ref[3] = sig->createReference(MAKE_UNICODE_STRING("#xpointer(/)"));
  -			ref[3]->appendEnvelopedSignatureTransform();
  -			ref[3]->appendCanonicalizationTransform(CANON_C14NE_NOC);
  +			cerr << "Calculating hash for reference " << i << " ... ";
   
  -			ref[4] = sig->createReference(MAKE_UNICODE_STRING("#xpointer(/)"));
  -			ref[4]->appendEnvelopedSignatureTransform();
  -			ref[4]->appendCanonicalizationTransform(CANON_C14NE_COM);
  +			len = (int) ref[i]->calculateHash(buf, 128);
   
  -			ref[5] = sig->createReference(MAKE_UNICODE_STRING("#xpointer(/)"));
  -			ref[5]->appendEnvelopedSignatureTransform();
  -			DSIGTransformC14n * ce = ref[5]->appendCanonicalizationTransform(CANON_C14NE_COM);
  -			ce->addInclusiveNamespace("foo");
  +			cerr << " Done\nChecking -> ";
   
  -			sig->setECNSPrefix(MAKE_UNICODE_STRING("ec"));
  -			ref[6] = sig->createReference(MAKE_UNICODE_STRING("#xpointer(/)"));
  -			ref[6]->appendEnvelopedSignatureTransform();
  -			ce = ref[6]->appendCanonicalizationTransform(CANON_C14NE_COM);
  -			ce->addInclusiveNamespace("foo");
  +			if (len != 20) {
  +				cerr << "Bad (Length = " << len << ")" << endl;
  +				exit (1);
  +			}
   
  -	#ifdef XSEC_NO_XALAN
  +			for (int j = 0; j < 20; ++j) {
   
  -			cerr << "WARNING : No testing of XPath being performed as Xalan not present" << endl;
  -			refCount = 7;
  +				if (buf[j] != createdDocRefs[i][j]) {
  +					cerr << "Bad at location " << j << endl;
  +					exit (1);
  +				}
  +			
  +			}
  +			cerr << "Good.\n";
   
  -	#else
  -			/*
  -			 * Create some XPath/XPathFilter references
  -			 */
  +		}
   
  +		/*
  +		 * Verify the signature check works
  +		 */
   
  -			ref[7] = sig->createReference(MAKE_UNICODE_STRING(""));
  -			sig->setXPFNSPrefix(MAKE_UNICODE_STRING("xpf"));
  -			DSIGTransformXPathFilter * xpf = ref[7]->appendXPathFilterTransform();
  -			xpf->appendFilter(FILTER_INTERSECT, MAKE_UNICODE_STRING("//ADoc/category"));
  +		cerr << "Running \"verifySignatureOnly()\" on calculated signature ... ";
  +		if (sig->verifySignatureOnly()) {
  +			cerr << "OK" << endl;
  +		}
  +		else {
  +			cerr << "Failed" << endl;
  +			char * e = XMLString::transcode(sig->getErrMsgs());
  +			cout << e << endl;
  +			delete [] e;
  +			exit(1);
  +		}
   
  -			ref[8] = sig->createReference(MAKE_UNICODE_STRING(""));
  -			/*		ref[5]->appendXPathTransform("ancestor-or-self::dsig:Signature", 
  -					"xmlns:dsig=http://www.w3.org/2000/09/xmldsig#"); */
  +		/*
  +		 * Change the document and ensure the signature fails.
  +		 */
   
  -			DSIGTransformXPath * x = ref[8]->appendXPathTransform("count(ancestor-or-self::dsig:Signature | \
  -	here()/ancestor::dsig:Signature[1]) > \
  -	count(ancestor-or-self::dsig:Signature)");
  -			x->setNamespace("dsig", "http://www.w3.org/2000/09/xmldsig#");
  +		cerr << "Setting incorrect key in Signature object" << endl;
  +		sig->setSigningKey(createHMACKey((unsigned char *) "badsecret"));
   
  -			refCount = 9;
  +		cerr << "Running \"verifySignatureOnly()\" on calculated signature ... ";
  +		if (!sig->verifySignatureOnly()) {
  +			cerr << "OK (Signature bad)" << endl;
  +		}
  +		else {
  +			cerr << "Failed (signature OK but should be bad)" << endl;
  +			exit(1);
  +		}
   
  -	#endif
  -		
  -			/*
  -			 * Sign the document, using an HMAC algorithm and the key "secret"
  -			 */
  +		// Don't need the signature now the DOM structure is in place
  +		prov.releaseSignature(sig);
  +
  +		/*
  +		 * Now serialise the document to memory so we can re-parse and check from scratch
  +		 */
  +
  +		cerr << "Serialising the document to a memory buffer ... ";
  +
  +		DOMWriter         *theSerializer = ((DOMImplementationLS*)impl)->createDOMWriter();
  +
  +		theSerializer->setEncoding(MAKE_UNICODE_STRING("UTF-8"));
  +		if (theSerializer->canSetFeature(XMLUni::fgDOMWRTFormatPrettyPrint, false))
  +			theSerializer->setFeature(XMLUni::fgDOMWRTFormatPrettyPrint, false);
  +
  +
  +		MemBufFormatTarget *formatTarget = new MemBufFormatTarget();
  +
  +		theSerializer->writeNode(formatTarget, *doc);
   
  +		// Copy to a new buffer
  +		len = formatTarget->getLen();
  +		char * mbuf = new char [len + 1];
  +		memcpy(mbuf, formatTarget->getRawBuffer(), len);
  +		mbuf[len] = '\0';
  +#if 0
  +		cout << mbuf << endl;
  +#endif
  +		delete theSerializer;
  +		delete formatTarget;
  +
  +		cerr << "done\nParsing memory buffer back to DOM ... ";
  +
  +		// Also release the document so that we can re-load from scratch
  +
  +		doc->release();
   
  -			sig->appendKeyName(MAKE_UNICODE_STRING("The secret key is \"secret\""));
  +		/*
  +		 * Re-parse
  +		 */
   
  -			// Append a test DNames
  +		XercesDOMParser parser;
  +		
  +		parser.setDoNamespaces(true);
  +		parser.setCreateEntityReferenceNodes(true);
   
  -			DSIGKeyInfoX509 * x509 = sig->appendX509Data();
  -			x509->setX509SubjectName(s_tstDName);
  +		MemBufInputSource* memIS = new MemBufInputSource ((const XMLByte*) mbuf, 
  +																len, "XSECMem");
   
  -			// Append a test PGPData element
  -			sig->appendPGPData(s_tstPGPKeyID, s_tstPGPKeyPacket);
  +		parser.parse(*memIS);
  +		doc = parser.adoptDocument();
   
  -			// Append an SPKIData element
  -			DSIGKeyInfoSPKIData * spki = sig->appendSPKIData(s_tstSexp1);
  -			spki->appendSexp(s_tstSexp2);
   
  -			// Append a MgmtData element
  -			sig->appendMgmtData(s_tstMgmtData);
  +		delete(memIS);
  +		delete[] mbuf;
   
  -			sig->setSigningKey(createHMACKey((unsigned char *) "secret"));
  -			sig->sign();
  +		cerr << "done\nValidating signature ...";
   
  -			cerr << "Doc signed OK - Checking values against Known Good" << endl;
  +		/*
  +		 * Validate signature
  +		 */
   
  -			unsigned char buf[128];
  -			int len;
  +		sig = prov.newSignatureFromDOM(doc);
  +		sig->load();
  +		sig->setSigningKey(createHMACKey((unsigned char *) "secret"));
   
  -			/*
  -			 * Validate the reference hash values from known good
  -			 */
  +		if (sig->verify()) {
  +			cerr << "OK" << endl;
  +		}
  +		else {
  +			cerr << "Failed\n" << endl;
  +			char * e = XMLString::transcode(sig->getErrMsgs());
  +			cerr << e << endl;
  +			delete [] e;
  +			exit(1);
  +		}
   
  -			int i;
  -			for (i = 0; i < refCount; ++i) {
  +		/*
  +		 * Ensure DNames are read back in and decoded properly
  +		 */
   
  -				cerr << "Calculating hash for reference " << i << " ... ";
  +		DSIGKeyInfoList * kil = sig->getKeyInfoList();
  +		int nki = kil->getSize();
   
  -				len = (int) ref[i]->calculateHash(buf, 128);
  +		cerr << "Checking Distinguished name is decoded correctly ... ";
  +		for (i = 0; i < nki; ++i) {
   
  -				cerr << " Done\nChecking -> ";
  +			if (kil->item(i)->getKeyInfoType() == DSIGKeyInfo::KEYINFO_X509) {
   
  -				if (len != 20) {
  -					cerr << "Bad (Length = " << len << ")" << endl;
  +				if (strEquals(s_tstDName, ((DSIGKeyInfoX509 *) kil->item(i))->getX509SubjectName())) {
  +					cerr << "yes" << endl;
  +				}
  +				else {
  +					cerr << "decoded incorrectly" << endl;;
   					exit (1);
   				}
  +			}
  +			if (kil->item(i)->getKeyInfoType() == DSIGKeyInfo::KEYINFO_PGPDATA) {
  +				
  +				cerr << "Validating PGPData read back OK ... ";
   
  -				for (int j = 0; j < 20; ++j) {
  +				DSIGKeyInfoPGPData * p = (DSIGKeyInfoPGPData *)kil->item(i);
   
  -					if (buf[j] != createdDocRefs[i][j]) {
  -						cerr << "Bad at location " << j << endl;
  -						exit (1);
  -					}
  -				
  +				if (!(strEquals(p->getKeyID(), s_tstPGPKeyID) &&
  +					strEquals(p->getKeyPacket(), s_tstPGPKeyPacket))) {
  +
  +					cerr << "no!";
  +					exit(1);
   				}
  -				cerr << "Good.\n";
   
  +				cerr << "yes\n";
   			}
  +			if (kil->item(i)->getKeyInfoType() == DSIGKeyInfo::KEYINFO_SPKIDATA) {
  +				
  +				cerr << "Validating SPKIData read back OK ... ";
   
  -			/*
  -			 * Verify the signature check works
  -			 */
  -
  -			cerr << "Running \"verifySignatureOnly()\" on calculated signature ... ";
  -			if (sig->verifySignatureOnly()) {
  -				cerr << "OK" << endl;
  -			}
  -			else {
  -				cerr << "Failed" << endl;
  -				char * e = XMLString::transcode(sig->getErrMsgs());
  -				cout << e << endl;
  -				delete [] e;
  -				exit(1);
  -			}
  +				DSIGKeyInfoSPKIData * s = (DSIGKeyInfoSPKIData *)kil->item(i);
  +
  +				if (s->getSexpSize() != 2) {
  +					cerr << "no - expected two S-expressions";
  +					exit(1);
  +				}
  +
  +				if (!(strEquals(s->getSexp(0), s_tstSexp1) &&
  +					strEquals(s->getSexp(1), s_tstSexp2))) {
   
  -			/*
  -			 * Change the document and ensure the signature fails.
  -			 */
  -
  -			cerr << "Setting incorrect key in Signature object" << endl;
  -			sig->setSigningKey(createHMACKey((unsigned char *) "badsecret"));
  -
  -			cerr << "Running \"verifySignatureOnly()\" on calculated signature ... ";
  -			if (!sig->verifySignatureOnly()) {
  -				cerr << "OK (Signature bad)" << endl;
  +					cerr << "no!";
  +					exit(1);
  +				}
  +
  +				cerr << "yes\n";
   			}
  -			else {
  -				cerr << "Failed (signature OK but should be bad)" << endl;
  -				exit(1);
  +			if (kil->item(i)->getKeyInfoType() == DSIGKeyInfo::KEYINFO_MGMTDATA) {
  +				
  +				cerr << "Validating MgmtData read back OK ... ";
  +
  +				DSIGKeyInfoMgmtData * m = (DSIGKeyInfoMgmtData *)kil->item(i);
  +
  +				if (!strEquals(m->getData(), s_tstMgmtData)) {
  +
  +					cerr << "no!";
  +					exit(1);
  +				}
  +
  +				cerr << "yes\n";
   			}
  +		}
  +	}
   
  -			// Don't need the signature now the DOM structure is in place
  -			prov.releaseSignature(sig);
  +	catch (XSECException &e)
  +	{
  +		cerr << "An error occured during signature processing\n   Message: ";
  +		char * ce = XMLString::transcode(e.getMsg());
  +		cerr << ce << endl;
  +		delete ce;
  +		exit(1);
  +		
  +	}	
  +	catch (XSECCryptoException &e)
  +	{
  +		cerr << "A cryptographic error occured during signature processing\n   Message: "
  +		<< e.getMsg() << endl;
  +		exit(1);
  +	}
   
  -			/*
  -			 * Now serialise the document to memory so we can re-parse and check from scratch
  -			 */
  +	// Output the document post signature if necessary
  +	outputDoc(impl, doc);
   
  -			cerr << "Serialising the document to a memory buffer ... ";
  +	doc->release();
   
  -			DOMWriter         *theSerializer = ((DOMImplementationLS*)impl)->createDOMWriter();
  +}
   
  -			theSerializer->setEncoding(MAKE_UNICODE_STRING("UTF-8"));
  -			if (theSerializer->canSetFeature(XMLUni::fgDOMWRTFormatPrettyPrint, false))
  -				theSerializer->setFeature(XMLUni::fgDOMWRTFormatPrettyPrint, false);
  +// --------------------------------------------------------------------------------
  +//           Test encrypt/Decrypt
  +// --------------------------------------------------------------------------------
   
  +void testEncrypt(DOMImplementation *impl) {
   
  -			MemBufFormatTarget *formatTarget = new MemBufFormatTarget();
  +	cerr << "Creating a known doc encrypting a portion of it" << endl;
  +	
  +	// Create a document
  +    
  +	DOMDocument * doc = createTestDoc(impl);
  +	DOMNode * categoryNode = findNode(doc, MAKE_UNICODE_STRING("category"));
  +	if (categoryNode == NULL) {
   
  -			theSerializer->writeNode(formatTarget, *doc);
  +		cerr << "Error finding category node for encryption test" << endl;
  +		exit(1);
   
  -			// Copy to a new buffer
  -			len = formatTarget->getLen();
  -			char * mbuf = new char [len + 1];
  -			memcpy(mbuf, formatTarget->getRawBuffer(), len);
  -			mbuf[len] = '\0';
  -#if 0
  -			cout << mbuf << endl;
  -#endif
  -			delete theSerializer;
  -			delete formatTarget;
  +	}
   
  -			cerr << "done\nParsing memory buffer back to DOM ... ";
  +	// Check signature functions
   
  -			// Also release the document so that we can re-load from scratch
  +	XSECProvider prov;
  +	XENCCipher * cipher;
   
  -			doc->release();
  +	try {
  +		
  +		/*
  +		 * Now we have a document, find the data node.
  +		 */
   
  -			/*
  -			 * Re-parse
  -			 */
  +		static char keyStr[] = "abcdefghijklmnopqrstuvwx";
   
  -			XercesDOMParser parser;
  -			
  -			parser.setDoNamespaces(true);
  -			parser.setCreateEntityReferenceNodes(true);
  +		cipher = prov.newCipher(doc);
  +		cipher->setXENCNSPrefix(MAKE_UNICODE_STRING("xenc"));
   
  -			MemBufInputSource* memIS = new MemBufInputSource ((const XMLByte*) mbuf, 
  -																	len, "XSECMem");
  +		// Set a key
   
  -			parser.parse(*memIS);
  -			doc = parser.adoptDocument();
  +		OpenSSLCryptoSymmetricKey * k;
  +		k = new OpenSSLCryptoSymmetricKey(XSECCryptoSymmetricKey::KEY_3DES_CBC_192);
  +		k->setKey((unsigned char *) keyStr, strlen(keyStr));
  +		cipher->setKey(k);
  +	
  +		// Now encrypt!
  +		cerr << "Performing 3DES encryption on <category> element ... ";
  +		cipher->encryptElement((DOMElement *) categoryNode);
  +		cerr << "done\nSearching for <category> ... ";
   
  +		DOMNode * t = findNode(doc, MAKE_UNICODE_STRING("category"));
  +		if (t != NULL) {
   
  -			delete(memIS);
  -			delete[] mbuf;
  +			cerr << "found!\nError - category is not encrypted" << endl;
  +			exit(1);
   
  -			cerr << "done\nValidating signature ...";
  +		}
  +		else
  +			cerr << "not found (OK - now encrypted)" << endl;
   
  -			/*
  -			 * Validate signature
  -			 */
  +		outputDoc(impl, doc);
   
  -			sig = prov.newSignatureFromDOM(doc);
  -			sig->load();
  -			sig->setSigningKey(createHMACKey((unsigned char *) "secret"));
  +		// OK - Now we try to decrypt
  +		// Find the EncryptedData node
  +		DOMNode * n = findXENCNode(doc, "EncryptedData");
   
  -			if (sig->verify()) {
  -				cerr << "OK" << endl;
  -			}
  -			else {
  -				cerr << "Failed\n" << endl;
  -				char * e = XMLString::transcode(sig->getErrMsgs());
  -				cerr << e << endl;
  -				delete [] e;
  -				exit(1);
  -			}
  +		XENCCipher * cipher2 = prov.newCipher(doc);
   
  -			/*
  -			 * Ensure DNames are read back in and decoded properly
  -			 */
  -
  -			DSIGKeyInfoList * kil = sig->getKeyInfoList();
  -			int nki = kil->getSize();
  -
  -			cerr << "Checking Distinguished name is decoded correctly ... ";
  -			for (i = 0; i < nki; ++i) {
  -
  -				if (kil->item(i)->getKeyInfoType() == DSIGKeyInfo::KEYINFO_X509) {
  -
  -					if (strEquals(s_tstDName, ((DSIGKeyInfoX509 *) kil->item(i))->getX509SubjectName())) {
  -						cerr << "yes" << endl;
  -					}
  -					else {
  -						cerr << "decoded incorrectly" << endl;;
  -						exit (1);
  -					}
  -				}
  -				if (kil->item(i)->getKeyInfoType() == DSIGKeyInfo::KEYINFO_PGPDATA) {
  -					
  -					cerr << "Validating PGPData read back OK ... ";
  +		OpenSSLCryptoSymmetricKey * k2;
  +		k2 = new OpenSSLCryptoSymmetricKey(XSECCryptoSymmetricKey::KEY_3DES_CBC_192);
  +		k2->setKey((unsigned char *) keyStr, strlen(keyStr));
  +		cipher2->setKey(k2);
   
  -					DSIGKeyInfoPGPData * p = (DSIGKeyInfoPGPData *)kil->item(i);
  +		cerr << "Decrypting ... ";
  +		cipher->decryptElement(static_cast<DOMElement *>(n));
  +		cerr << "done" << endl;
   
  -					if (!(strEquals(p->getKeyID(), s_tstPGPKeyID) &&
  -						strEquals(p->getKeyPacket(), s_tstPGPKeyPacket))) {
  +		cerr << "Checking for <category> element ... ";
   
  -						cerr << "no!";
  -						exit(1);
  -					}
  +		t = findNode(doc, MAKE_UNICODE_STRING("category"));
   
  -					cerr << "yes\n";
  -				}
  -				if (kil->item(i)->getKeyInfoType() == DSIGKeyInfo::KEYINFO_SPKIDATA) {
  -					
  -					cerr << "Validating SPKIData read back OK ... ";
  +		if (t == NULL) {
   
  -					DSIGKeyInfoSPKIData * s = (DSIGKeyInfoSPKIData *)kil->item(i);
  +			cerr << " not found!\nError - category did not decrypt properly" << endl;
  +			exit(1);
   
  -					if (s->getSexpSize() != 2) {
  -						cerr << "no - expected two S-expressions";
  -						exit(1);
  -					}
  +		}
  +		else
  +			cerr << "found" << endl;
   
  -					if (!(strEquals(s->getSexp(0), s_tstSexp1) &&
  -						strEquals(s->getSexp(1), s_tstSexp2))) {
  +	}
  +	catch (XSECException &e)
  +	{
  +		cerr << "An error occured during signature processing\n   Message: ";
  +		char * ce = XMLString::transcode(e.getMsg());
  +		cerr << ce << endl;
  +		delete ce;
  +		exit(1);
  +		
  +	}	
  +	catch (XSECCryptoException &e)
  +	{
  +		cerr << "A cryptographic error occured during signature processing\n   Message: "
  +		<< e.getMsg() << endl;
  +		exit(1);
  +	}
   
  -						cerr << "no!";
  -						exit(1);
  -					}
  +	outputDoc(impl, doc);
  +	doc->release();
   
  -					cerr << "yes\n";
  -				}
  -				if (kil->item(i)->getKeyInfoType() == DSIGKeyInfo::KEYINFO_MGMTDATA) {
  -					
  -					cerr << "Validating MgmtData read back OK ... ";
  +}
   
  -					DSIGKeyInfoMgmtData * m = (DSIGKeyInfoMgmtData *)kil->item(i);
  +	
  +// --------------------------------------------------------------------------------
  +//           Print usage instructions
  +// --------------------------------------------------------------------------------
   
  -					if (!strEquals(m->getData(), s_tstMgmtData)) {
  +void printUsage(void) {
   
  -						cerr << "no!";
  -						exit(1);
  -					}
  +	cerr << "\nUsage: xtest [options]\n\n";
  +	cerr << "     Where options are :\n\n";
  +	cerr << "     --help/-h\n";
  +	cerr << "         This help message\n\n";
  +	cerr << "     --print-docs/-p\n";
  +	cerr << "         Print the test documents\n\n";
  +	cerr << "     --signature-only/-s\n";
  +	cerr << "         Only run signature tests\n\n";
  +	cerr << "     --encryption-only/-e\n";
  +	cerr << "         Only run encryption tests\n\n";
   
  -					cerr << "yes\n";
  -				}
  -			}
  -		}
  +}
  +// --------------------------------------------------------------------------------
  +//           Main
  +// --------------------------------------------------------------------------------
   
  -		catch (XSECException &e)
  -		{
  -			cerr << "An error occured during signature processing\n   Message: ";
  -			char * ce = XMLString::transcode(e.getMsg());
  -			cerr << ce << endl;
  -			delete ce;
  -			exit(1);
  -			
  -		}	
  -		catch (XSECCryptoException &e)
  -		{
  -			cerr << "A cryptographic error occured during signature processing\n   Message: "
  -			<< e.getMsg() << endl;
  -			exit(1);
  +int main(int argc, char **argv) {
  +
  +	/* We output a version number to overcome a "feature" in Microsoft's memory
  +	   leak detection */
  +
  +	cerr << "DSIG Info (Using Apache XML-Security-C Library v" << XSEC_VERSION_MAJOR <<
  +		"." << XSEC_VERSION_MEDIUM << "." << XSEC_VERSION_MINOR << ")\n";
  +
  +	// Check parameters
  +	bool		doEncryptionTest = true;
  +	bool		doSignatureTest = true;
  +
  +	int paramCount = 1;
  +
  +	while (paramCount < argc) {
  +
  +		if (stricmp(argv[paramCount], "--help") == 0 || stricmp(argv[paramCount], "-h") == 0) {
  +			printUsage();
  +			exit(0);
  +		}
  +		else if (stricmp(argv[paramCount], "--print-docs") == 0 || stricmp(argv[paramCount], "-p") == 0) {
  +			g_printDocs = true;
  +			paramCount++;
  +		}
  +		else if (stricmp(argv[paramCount], "--signature-only") == 0 || stricmp(argv[paramCount], "-s") == 0) {
  +			doEncryptionTest = false;
  +			paramCount++;
   		}
  +		else if (stricmp(argv[paramCount], "--encryption-only") == 0 || stricmp(argv[paramCount], "-e") == 0) {
  +			doSignatureTest = false;
  +			paramCount++;
  +		}
  +		else {
  +			printUsage();
  +			return 2;
  +		}
  +	}
   
  -		DOMWriter         *theSerializer = ((DOMImplementationLS*)impl)->createDOMWriter();
   
  -		theSerializer->setEncoding(MAKE_UNICODE_STRING("UTF-8"));
  -		if (theSerializer->canSetFeature(XMLUni::fgDOMWRTFormatPrettyPrint, false))
  -			theSerializer->setFeature(XMLUni::fgDOMWRTFormatPrettyPrint, false);
  +#if defined (_DEBUG) && defined (_MSC_VER)
   
  +	// Do some memory debugging under Visual C++
   
  -		XMLFormatTarget *formatTarget = new StdOutFormatTarget();
  +	_CrtMemState s1, s2, s3;
   
  -		theSerializer->writeNode(formatTarget, *doc);
  -		
  -		cout << endl;
  +	// At this point we are about to start really using XSEC, so
  +	// Take a "before" checkpoing
   
  -		delete theSerializer;
  -		delete formatTarget;
  +	_CrtMemCheckpoint( &s1 );
   
  -		doc->release();
  +#endif
  +
  +	// First initialise the XML system
  +
  +	try {
  +
  +		XMLPlatformUtils::Initialize();
  +#ifndef XSEC_NO_XALAN
  +		XPathEvaluator::initialize();
  +		XalanTransformer::initialize();
  +#endif
  +		XSECPlatformUtils::Initialise();
  +
  +	}
  +	catch (const XMLException &e) {
  +
  +		cerr << "Error during initialisation of Xerces" << endl;
  +		cerr << "Error Message = : "
  +		     << e.getMessage() << endl;
  +
  +	}
  +
  +	{
  +
  +		// Set up for tests
  +
  +		XMLCh tempStr[100];
  +		XMLString::transcode("Core", tempStr, 99);    
  +		DOMImplementation *impl = DOMImplementationRegistry::getDOMImplementation(tempStr);
  +
  +		// Test signature functions
  +		if (doSignatureTest) {
  +			cerr << endl << "====================================";
  +			cerr << endl << "Testing Signature Functions";
  +			cerr << endl << "====================================";
  +			cerr << endl << endl;
  +
  +			testSignature(impl);
  +		}
  +
  +		// Test encrypt function
  +		if (doEncryptionTest) {
  +			cerr << endl << "====================================";
  +			cerr << endl << "Testing Encryption Function";
  +			cerr << endl << "====================================";
  +			cerr << endl << endl;
  +
  +			testEncrypt(impl);
  +		}
   
  -		cerr << "All tests passed" << endl;
  +		cerr << endl << "All tests passed" << endl;
   
   	}
   
  
  
  
  1.5       +24 -10    xml-security/c/src/transformers/TXFMBase64.cpp
  
  Index: TXFMBase64.cpp
  ===================================================================
  RCS file: /home/cvs/xml-security/c/src/transformers/TXFMBase64.cpp,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- TXFMBase64.cpp	5 Jul 2003 10:30:36 -0000	1.4
  +++ TXFMBase64.cpp	8 Sep 2003 12:07:49 -0000	1.5
  @@ -74,9 +74,10 @@
   #include <xsec/utils/XSECPlatformUtils.hpp>
   #include <xsec/framework/XSECException.hpp>
   
  -TXFMBase64::TXFMBase64(DOMDocument *doc) : TXFMBase(doc) {
  +TXFMBase64::TXFMBase64(DOMDocument *doc, bool decode) : TXFMBase(doc) {
   
   	m_complete = false;					// Nothing yet to output
  +	m_doDecode = decode;
   
   	mp_b64 = XSECPlatformUtils::g_cryptoProvider->base64();
   	
  @@ -86,8 +87,10 @@
   				"Error requesting Base64 object from Crypto Provider");
   
   	}
  -
  -	mp_b64->decodeInit();
  +	if (decode)
  +		mp_b64->decodeInit();
  +	else
  +		mp_b64->encodeInit();
   
   };
   
  @@ -142,13 +145,24 @@
   
   	unsigned int sz = input->readBytes(m_base64Buffer, fill);
   
  -	if (sz == 0)
  -		ret = mp_b64->decodeFinish((unsigned char *) toFill, maxToFill);
  -	else
  -		ret = mp_b64->decode(m_base64Buffer, sz, (unsigned char *) toFill, maxToFill);
  +	if (m_doDecode) {
  +		if (sz == 0)
  +			ret = mp_b64->decodeFinish((unsigned char *) toFill, maxToFill);
  +		else
  +			ret = mp_b64->decode(m_base64Buffer, sz, (unsigned char *) toFill, maxToFill);
   
  -	if (ret == 0)
  -		m_complete = true;
  +		if (ret == 0)
  +			m_complete = true;
  +	}
  +	else {
  +		if (sz == 0)
  +			ret = mp_b64->encodeFinish((unsigned char *) toFill, maxToFill);
  +		else 
  +			ret = mp_b64->encode(m_base64Buffer, sz, (unsigned char *) toFill, maxToFill);
  +
  +		if (ret == 0)
  +			m_complete = true;
  +	}
   
   	return ret;
   
  
  
  
  1.7       +7 -8      xml-security/c/src/transformers/TXFMBase64.hpp
  
  Index: TXFMBase64.hpp
  ===================================================================
  RCS file: /home/cvs/xml-security/c/src/transformers/TXFMBase64.hpp,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- TXFMBase64.hpp	5 Jul 2003 10:30:36 -0000	1.6
  +++ TXFMBase64.hpp	8 Sep 2003 12:07:49 -0000	1.7
  @@ -80,17 +80,11 @@
   
   class DSIG_EXPORT TXFMBase64 : public TXFMBase {
   
  -private:
  -
  -	bool				m_complete;					// Is the work done
  -	unsigned char		m_base64Buffer[2050];		// Always keep 2K of data
  -	XSECCryptoBase64 *	mp_b64;
  -	
   public:
   
   	// Constructors and destructors
   
  -	TXFMBase64(DOMDocument *doc);
  +	TXFMBase64(DOMDocument *doc, bool decode = true);
   	~TXFMBase64();
   
   	// Methods to get tranform output type and input requirement
  @@ -112,5 +106,10 @@
   	
   private:
   	TXFMBase64();
  +
  +	bool				m_complete;					// Is the work done
  +	unsigned char		m_base64Buffer[2050];		// Always keep 2K of data
  +	XSECCryptoBase64 *	mp_b64;
  +	bool				m_doDecode;					// Are we encoding or decoding?
   };
   
  
  
  
  1.2       +22 -8     xml-security/c/src/transformers/TXFMCipher.cpp
  
  Index: TXFMCipher.cpp
  ===================================================================
  RCS file: /home/cvs/xml-security/c/src/transformers/TXFMCipher.cpp,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- TXFMCipher.cpp	31 Aug 2003 12:50:04 -0000	1.1
  +++ TXFMCipher.cpp	8 Sep 2003 12:07:49 -0000	1.2
  @@ -93,7 +93,9 @@
   	m_complete = false;
   
   	try {
  -		if (mp_cipher->getKeyType() == XSECCryptoKey::KEY_SYMMETRIC)
  +		if (mp_cipher->getKeyType() == XSECCryptoKey::KEY_SYMMETRIC && m_doEncrypt)
  +			(dynamic_cast<XSECCryptoSymmetricKey *>(mp_cipher))->encryptInit();
  +		else
   			(dynamic_cast<XSECCryptoSymmetricKey *>(mp_cipher))->decryptInit();
   	}
   	catch (...) {
  @@ -167,7 +169,7 @@
   			ret += fill;
   		}
   
  -		// Now do some decrypting
  +		// Now do some crypting
   
   		if (m_complete == false) {
   
  @@ -176,12 +178,24 @@
   			if (mp_cipher->getKeyType() == XSECCryptoKey::KEY_SYMMETRIC) {
   				XSECCryptoSymmetricKey * symCipher = 
   					dynamic_cast<XSECCryptoSymmetricKey*>(mp_cipher);
  -				if (sz == 0) {
  -					m_complete = true;
  -					m_remaining = symCipher->decryptFinish(m_outputBuffer, 3072);
  +				if (m_doEncrypt) {
  +					
  +					if (sz == 0) {
  +						m_complete = true;
  +						m_remaining = symCipher->encryptFinish(m_outputBuffer, 3072);
  +					}
  +					else
  +						m_remaining = symCipher->encrypt(m_inputBuffer, m_outputBuffer, sz, 3072);
  +				}
  +				else {
  +
  +					if (sz == 0) {
  +						m_complete = true;
  +						m_remaining = symCipher->decryptFinish(m_outputBuffer, 3072);
  +					}
  +					else
  +						m_remaining = symCipher->decrypt(m_inputBuffer, m_outputBuffer, sz, 3072);
   				}
  -				else
  -					m_remaining = symCipher->decrypt(m_inputBuffer, m_outputBuffer, sz, 3072);
   			}
   		}
   
  
  
  
  1.13      +14 -0     xml-security/c/src/utils/XSECDOMUtils.cpp
  
  Index: XSECDOMUtils.cpp
  ===================================================================
  RCS file: /home/cvs/xml-security/c/src/utils/XSECDOMUtils.cpp,v
  retrieving revision 1.12
  retrieving revision 1.13
  diff -u -r1.12 -r1.13
  --- XSECDOMUtils.cpp	7 Sep 2003 00:52:26 -0000	1.12
  +++ XSECDOMUtils.cpp	8 Sep 2003 12:07:49 -0000	1.13
  @@ -261,6 +261,20 @@
   	return qname;
   }
   
  +safeBuffer &makeQName(safeBuffer & qname, const XMLCh *prefix, const XMLCh * localName) {
  +
  +	if (prefix == NULL || prefix[0] == 0) {
  +		qname.sbXMLChIn(localName);
  +	}
  +	else {
  +		qname.sbXMLChIn(prefix);
  +		qname.sbXMLChAppendCh(XERCES_CPP_NAMESPACE_QUALIFIER chColon);
  +		qname.sbXMLChCat(localName);
  +	}
  +
  +	return qname;
  +}
  +
   // --------------------------------------------------------------------------------
   //           "Quick" Transcode (low performance)
   // --------------------------------------------------------------------------------
  
  
  
  1.11      +2 -1      xml-security/c/src/utils/XSECDOMUtils.hpp
  
  Index: XSECDOMUtils.hpp
  ===================================================================
  RCS file: /home/cvs/xml-security/c/src/utils/XSECDOMUtils.hpp,v
  retrieving revision 1.10
  retrieving revision 1.11
  diff -u -r1.10 -r1.11
  --- XSECDOMUtils.hpp	31 Aug 2003 12:50:47 -0000	1.10
  +++ XSECDOMUtils.hpp	8 Sep 2003 12:07:49 -0000	1.11
  @@ -145,6 +145,7 @@
   
   safeBuffer DSIG_EXPORT &makeQName(safeBuffer & qname, safeBuffer &prefix, const char * localName);
   safeBuffer DSIG_EXPORT &makeQName(safeBuffer & qname, const XMLCh *prefix, const char * localName);
  +safeBuffer DSIG_EXPORT &makeQName(safeBuffer & qname, const XMLCh *prefix, const XMLCh * localName);
   
   // --------------------------------------------------------------------------------
   //           Gather text from children
  
  
  
  1.11      +23 -1     xml-security/c/src/utils/XSECSafeBuffer.cpp
  
  Index: XSECSafeBuffer.cpp
  ===================================================================
  RCS file: /home/cvs/xml-security/c/src/utils/XSECSafeBuffer.cpp,v
  retrieving revision 1.10
  retrieving revision 1.11
  diff -u -r1.10 -r1.11
  --- XSECSafeBuffer.cpp	31 Aug 2003 12:50:47 -0000	1.10
  +++ XSECSafeBuffer.cpp	8 Sep 2003 12:07:49 -0000	1.11
  @@ -73,6 +73,7 @@
   #include <xsec/utils/XSECSafeBuffer.hpp>
   #include <xsec/utils/XSECDOMUtils.hpp>
   #include <xsec/framework/XSECError.hpp>
  +#include <xsec/transformers/TXFMBase.hpp>
   
   #include <xercesc/util/XMLUniDefs.hpp>
   #include <xercesc/util/Janitor.hpp>
  @@ -554,6 +555,27 @@
   	m_bufferType = BUFFER_UNICODE;
   	return *this;
   
  +}
  +
  +safeBuffer & safeBuffer::operator << (TXFMBase * t) {
  +
  +	// Read into buffer the output of the transform
  +	unsigned offset = 0;
  +	unsigned char inBuf[2048];
  +	unsigned int bytesRead;
  +
  +	while ((bytesRead = t->readBytes(inBuf, 2000)) > 0) {
  +
  +		checkAndExpand(offset + bytesRead + 1);
  +		memcpy(&buffer[offset], inBuf, bytesRead);
  +		offset += bytesRead;
  +
  +	}
  +
  +	m_bufferType = BUFFER_CHAR;
  +	buffer[offset] = '\0';
  +
  +	return *this;
   }
   
   
  
  
  
  1.13      +4 -1      xml-security/c/src/utils/XSECSafeBuffer.hpp
  
  Index: XSECSafeBuffer.hpp
  ===================================================================
  RCS file: /home/cvs/xml-security/c/src/utils/XSECSafeBuffer.hpp,v
  retrieving revision 1.12
  retrieving revision 1.13
  diff -u -r1.12 -r1.13
  --- XSECSafeBuffer.hpp	31 Aug 2003 12:50:47 -0000	1.12
  +++ XSECSafeBuffer.hpp	8 Sep 2003 12:07:49 -0000	1.13
  @@ -75,6 +75,8 @@
   #include <xsec/framework/XSECDefs.hpp>
   #include <xercesc/util/XMLString.hpp>
   
  +class TXFMBase;
  +
   /** 
    * \addtogroup internal
    * @{
  @@ -160,6 +162,7 @@
   	unsigned char & operator[](int n);
   	safeBuffer & operator= (const safeBuffer & cpy);
   	safeBuffer & operator= (const XMLCh * inStr);
  +	safeBuffer & operator << (TXFMBase * t);
   
   	// Get functions
   
  
  
  
  1.2       +73 -3     xml-security/c/src/xenc/XENCCipher.hpp
  
  Index: XENCCipher.hpp
  ===================================================================
  RCS file: /home/cvs/xml-security/c/src/xenc/XENCCipher.hpp,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- XENCCipher.hpp	31 Aug 2003 12:47:19 -0000	1.1
  +++ XENCCipher.hpp	8 Sep 2003 12:07:49 -0000	1.2
  @@ -72,6 +72,7 @@
   // XSEC Includes
   
   #include <xsec/framework/XSECDefs.hpp>
  +#include <xsec/xenc/XENCCipherData.hpp>
   
   // Xerces
   
  @@ -79,6 +80,7 @@
   XSEC_DECLARE_XERCES_CLASS(DOMDocument);
   
   class XSECCryptoKey;
  +class XENCEncryptedData;
   
   /**
    * @defgroup xenc XML Encryption Implementation
  @@ -100,6 +102,10 @@
    * library to generate encrypted XML information and to decrypt
    * information held in XML Encryption structures.
    *
  + * All encryption and decryption work performed by the library is
  + * handled within this class.  The other XENC classes simply
  + * handle marshalling and unmarshalling of the DOM data.
  + *
    */
   
   
  @@ -140,6 +146,24 @@
   
   	//@}
   
  +	/** @name Encryption Functions */
  +	//@{
  +
  +	/**
  +	 * \brief Encrypt the nominated element.
  +	 * 
  +	 * Encrypts the passed in element and all children.  The element
  +	 * is replaced with an EncryptedData element
  +	 *
  +	 * @param element Element (and children) to encrypt
  +	 * @returns The owning document with the element replaced, or NULL
  +	 * if the decryption fails for some reason (normally an exception).
  +	 * @throws XSECException if the encryption fails.
  +	 */
  +
  +	virtual DOMDocument * encryptElement(DOMElement * element) = 0;
  +
  +	//@}
   	/** @name Getter Functions */
   	//@{
   
  @@ -154,6 +178,17 @@
   
   	virtual DOMDocument * getDocument(void) = 0;
   
  +	/**
  +	 * \brief Get namespace prefix for XENC nodes
  +	 *
  +	 * Find the string being used by the library to prefix nodes in the 
  +	 * xenc: namespace.
  +	 *
  +	 * @returns XENC namespace prefix
  +	 */
  +
  +	virtual const XMLCh * getXENCNSPrefix(void) const = 0;
  +
   	//@}
   
   	/** @name Setter Functions */
  @@ -166,11 +201,46 @@
   	 * operation.
   	 *
   	 * @param key Key to use
  -	 * @note Unlike the EncryptedType element and its derivatives, this
  -	 * function will take ownership of the key and delete it when done.
  +	 * @note This function will take ownership of the key and delete it when done.
   	 */
   
   	virtual void setKey(XSECCryptoKey * key) = 0;
  +
  +	/**
  +	 * \brief Set prefix for XENC nodes
  +	 *
  +	 * Set the namespace prefix the library will use when creating
  +	 * nodes in the XENC namespace
  +	 */
  +
  +	virtual void setXENCNSPrefix(const XMLCh * prefix) = 0;
  +
  +	//@}
  +
  +	/** @name Creation Functions */
  +	//@{
  +
  +	/**
  +	 * \brief Create a new EncryptedData element
  +	 *
  +	 * Method for creating a basic Encrypted Data element.  Can be used
  +	 * in cases where an application needs to build this from scratch.
  +	 *
  +	 * In general, applications should use the higher level methods such
  +	 * as #encryptElement or #encryptElementContent.
  +	 *
  +	 * @note The Cipher object will take on this new object as the current
  +	 * EncryptedData and delete any currently being held.
  +	 *
  +	 * @param type Should this set up a CipherReference or a CipherValue
  +	 * @param value String to set the cipher data to if the type is VALUE_TYPE
  +	 * @returns An XENCEncryptedData object
  +	 */
  +
  +	virtual XENCEncryptedData * createEncryptedData(XENCCipherData::XENCCipherDataType type, 
  +													XMLCh * value) = 0;
  +
  +	//@}
   
   };
   
  
  
  
  1.2       +4 -4      xml-security/c/src/xenc/XENCCipherData.hpp
  
  Index: XENCCipherData.hpp
  ===================================================================
  RCS file: /home/cvs/xml-security/c/src/xenc/XENCCipherData.hpp,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- XENCCipherData.hpp	31 Aug 2003 12:47:19 -0000	1.1
  +++ XENCCipherData.hpp	8 Sep 2003 12:07:49 -0000	1.2
  @@ -104,9 +104,9 @@
   
   	enum XENCCipherDataType {
   
  -		CipherNone      = 0,    /** Not Set */
  -		CipherValue		= 1,
  -		CipherReference	= 2,
  +		NO_TYPE			= 0,    /** Not Set */
  +		VALUE_TYPE		= 1,
  +		REFERENCE_TYPE	= 2,
   
   	};
   
  
  
  
  1.2       +1 -11     xml-security/c/src/xenc/XENCEncryptedData.hpp
  
  Index: XENCEncryptedData.hpp
  ===================================================================
  RCS file: /home/cvs/xml-security/c/src/xenc/XENCEncryptedData.hpp,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- XENCEncryptedData.hpp	31 Aug 2003 12:47:19 -0000	1.1
  +++ XENCEncryptedData.hpp	8 Sep 2003 12:07:49 -0000	1.2
  @@ -110,16 +110,6 @@
   	/** @name Get Interface Methods */
   	//@{
   
  -	/**
  -	 * \brief Retrieve the CipherData element
  -	 *
  -	 * CipherData elements are the sub part of the EncryptedData
  -	 * that hold the actual enciphered information.
  -	 *
  -	 * @returns The CipherData object
  -	 */
  -
  -	virtual XENCCipherData * getCipherData(void) = 0;
   
   	//@}
   
  
  
  
  1.2       +18 -7     xml-security/c/src/xenc/XENCEncryptedType.hpp
  
  Index: XENCEncryptedType.hpp
  ===================================================================
  RCS file: /home/cvs/xml-security/c/src/xenc/XENCEncryptedType.hpp,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- XENCEncryptedType.hpp	31 Aug 2003 12:47:19 -0000	1.1
  +++ XENCEncryptedType.hpp	8 Sep 2003 12:07:49 -0000	1.2
  @@ -76,7 +76,7 @@
   
   #include <xsec/framework/XSECDefs.hpp>
   
  -class XSECCryptoKey;
  +class XENCCipherData;
   
   /**
    * @ingroup xenc
  @@ -116,15 +116,26 @@
   	//@{
   
   	/**
  -	 * \brief Set the encryption key to be used to decrypt
  +	 * \brief Retrieve the CipherData element
   	 *
  -	 * The decrypt functions use this key to decrypt the cipher data.
  +	 * CipherData elements are the sub part of the EncryptedData
  +	 * that hold the actual enciphered information.
   	 *
  -	 * @param key The key to use for encryption/decryption
  -	 * @note The object will take a copy of the key (using XSECCryptoKey::clone()).
  +	 * @returns The CipherData object
   	 */
   
  -	virtual void setKey(XSECCryptoKey * key) = 0;
  +	virtual XENCCipherData * getCipherData(void) = 0;
  +
  +	/**
  +	 * \brief Retrieve the DOM Node that heads up the structure
  +	 *
  +	 * If this object has been fully created, this call will provide
  +	 * the element node that heads up this structure
  +	 *
  +	 * @returns the DOMNode that heads up this structure
  +	 */
  +
  +	virtual DOMElement * getDOMNode() = 0;
   
   	//@}
   
  
  
  
  1.2       +43 -3     xml-security/c/src/xenc/impl/XENCCipherDataImpl.cpp
  
  Index: XENCCipherDataImpl.cpp
  ===================================================================
  RCS file: /home/cvs/xml-security/c/src/xenc/impl/XENCCipherDataImpl.cpp,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- XENCCipherDataImpl.cpp	31 Aug 2003 12:47:19 -0000	1.1
  +++ XENCCipherDataImpl.cpp	8 Sep 2003 12:07:49 -0000	1.2
  @@ -184,7 +184,7 @@
   
   	if (tmpElt != NULL && strEquals(getXENCLocalName(tmpElt), s_CipherValue)) {
   
  -		m_cipherDataType = CipherValue;
  +		m_cipherDataType = VALUE_TYPE;
   		XSECnew(mp_cipherValue, XENCCipherValueImpl(mp_cipher, tmpElt));
   		mp_cipherValue->load();
   
  @@ -192,7 +192,7 @@
   
   	else if (tmpElt != NULL && strEquals(getXENCLocalName(tmpElt), s_CipherReference)) {
   
  -		m_cipherDataType = CipherNone;
  +		m_cipherDataType = NO_TYPE;
   
   	}
   
  @@ -205,8 +205,48 @@
   
   }
   
  +// --------------------------------------------------------------------------------
  +//			Create a blank structure
  +// --------------------------------------------------------------------------------
  +
  +DOMElement * XENCCipherDataImpl::createBlankCipherData(
  +						XENCCipherData::XENCCipherDataType type, 
  +						const XMLCh * value) {
  +
  +	// Reset
  +	if (mp_cipherValue != NULL) {
  +		delete mp_cipherValue;
  +		mp_cipherValue = NULL;
  +	}
  +
  +	m_cipherDataType = NO_TYPE;
  +
  +	// Get some setup values
  +	safeBuffer str;
  +	DOMDocument *doc = mp_cipher->getDocument();
  +	const XMLCh * prefix = mp_cipher->getXENCNSPrefix();
  +
  +	makeQName(str, prefix, s_CipherData);
  +
  +	DOMElement *ret = doc->createElementNS(DSIGConstants::s_unicodeStrURIXENC, str.rawXMLChBuffer());
  +	mp_cipherDataNode = ret;
  +
  +	// Set the type
  +	if (type == VALUE_TYPE) {
  +		
  +		// Should set the type attribute
   
  +		// Create the Cipher Value
  +		XSECnew(mp_cipherValue, XENCCipherValueImpl(mp_cipher));
  +		DOMNode * cipherValueNode = mp_cipherValue->createBlankCipherValue(value);
   
  +		ret->appendChild(cipherValueNode);
  +
  +	}
  +
  +	return ret;
  +
  +}
   
   // --------------------------------------------------------------------------------
   //			Constructors and Destructors
  
  
  
  1.2       +4 -1      xml-security/c/src/xenc/impl/XENCCipherDataImpl.hpp
  
  Index: XENCCipherDataImpl.hpp
  ===================================================================
  RCS file: /home/cvs/xml-security/c/src/xenc/impl/XENCCipherDataImpl.hpp,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- XENCCipherDataImpl.hpp	31 Aug 2003 12:47:19 -0000	1.1
  +++ XENCCipherDataImpl.hpp	8 Sep 2003 12:07:49 -0000	1.2
  @@ -91,6 +91,9 @@
   
   	// Load elements
   	void load();
  +	// Create
  +	DOMElement * createBlankCipherData(XENCCipherData::XENCCipherDataType type, const XMLCh * value);
  +
   
   	// Interface methods
   	virtual XENCCipherDataType getCipherDataType(void);
  
  
  
  1.2       +163 -5    xml-security/c/src/xenc/impl/XENCCipherImpl.cpp
  
  Index: XENCCipherImpl.cpp
  ===================================================================
  RCS file: /home/cvs/xml-security/c/src/xenc/impl/XENCCipherImpl.cpp,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- XENCCipherImpl.cpp	31 Aug 2003 12:47:19 -0000	1.1
  +++ XENCCipherImpl.cpp	8 Sep 2003 12:07:49 -0000	1.2
  @@ -73,6 +73,10 @@
   #include <xsec/enc/XSECCryptoKey.hpp>
   #include <xsec/transformers/TXFMChain.hpp>
   #include <xsec/transformers/TXFMBase.hpp>
  +#include <xsec/transformers/TXFMBase64.hpp>
  +#include <xsec/transformers/TXFMC14n.hpp>
  +#include <xsec/transformers/TXFMCipher.hpp>
  +#include <xsec/transformers/TXFMDocObject.hpp>
   #include <xsec/utils/XSECDOMUtils.hpp>
   
   #include "XENCCipherImpl.hpp"
  @@ -110,6 +114,15 @@
   	XERCES_CPP_NAMESPACE :: chNull
   };
   
  +const XMLCh s_defaultXENCPrefix[] = {
  +
  +	XERCES_CPP_NAMESPACE :: chLatin_x,
  +	XERCES_CPP_NAMESPACE :: chLatin_e,
  +	XERCES_CPP_NAMESPACE :: chLatin_n,
  +	XERCES_CPP_NAMESPACE :: chLatin_c,
  +	XERCES_CPP_NAMESPACE :: chNull
  +
  +};
   
   // --------------------------------------------------------------------------------
   //			Constructors
  @@ -120,6 +133,8 @@
   mp_encryptedData(NULL),
   mp_key(NULL) {
   
  +	mp_xencPrefixNS = XMLString::replicate(s_defaultXENCPrefix);
  +
   }
   
   XENCCipherImpl::~XENCCipherImpl() {
  @@ -129,6 +144,30 @@
   
   	if (mp_key != NULL)
   		delete mp_key;
  +
  +	if (mp_xencPrefixNS != NULL)
  +		delete mp_xencPrefixNS;
  +
  +}
  +
  +// --------------------------------------------------------------------------------
  +//			Set/get the namespace prefix to be used when creating nodes
  +// --------------------------------------------------------------------------------
  +
  +void XENCCipherImpl::setXENCNSPrefix(const XMLCh * prefix) {
  +
  +	if (mp_xencPrefixNS != NULL)
  +		delete mp_xencPrefixNS;
  +
  +	// Copy in new one
  +	mp_xencPrefixNS = XMLString::replicate(prefix);
  +
  +}
  +
  +const XMLCh * XENCCipherImpl::getXENCNSPrefix(void) const {
  +
  +	return mp_xencPrefixNS;
  +
   }
   
   // --------------------------------------------------------------------------------
  @@ -262,6 +301,38 @@
       return result;
   }
   
  +// --------------------------------------------------------------------------------
  +//			Build a set of decryption transforms
  +// --------------------------------------------------------------------------------
  +
  +TXFMChain * XENCCipherImpl::createDecryptionTXFMChain(void) {
  +
  +	// First obtain the raw encrypted data
  +	if (mp_key == NULL) {
  +		throw XSECException(XSECException::CipherError, 
  +			"XENCCipherImpl::createDecryptionTXFMChain - No key set");
  +	}
  +
  +	if (mp_encryptedData == NULL) {
  +		throw XSECException(XSECException::CipherError, 
  +			"XENCCipherImpl::createDecryptionTXFMChain - Encrypted Data");
  +	}
  +
  +	// Get the raw encrypted data
  +	TXFMChain * c = mp_encryptedData->createCipherTXFMChain();
  +
  +	Janitor<TXFMChain> j_c(c);
  +
  +	// Now add the decryption TXFM
  +	TXFMCipher * tcipher;
  +	XSECnew(tcipher, TXFMCipher(mp_doc, mp_key, false));
  +
  +	c->appendTxfm(tcipher);
  +
  +	j_c.release();
  +	return c;
  +
  +}
   
   // --------------------------------------------------------------------------------
   //			Decrypt an Element and replace in original document
  @@ -285,11 +356,9 @@
   	// Load
   	mp_encryptedData->load();
   
  -	// Do the decrypt
  -	mp_encryptedData->setKey(mp_key);
  -	TXFMChain * c = mp_encryptedData->createDecryptionTXFMChain();
  +	// Get the raw encrypted data
  +	TXFMChain * c = createDecryptionTXFMChain();
   	Janitor<TXFMChain> j_c(c);
  -
   	TXFMBase * b = c->getLastTxfm();
   
   	// Read the result into a safeBuffer
  @@ -321,5 +390,94 @@
   	}
   
   	return NULL;
  +
  +}
  +
  +// --------------------------------------------------------------------------------
  +//			Create an EncryptedData element
  +// --------------------------------------------------------------------------------
  +
  +XENCEncryptedData * XENCCipherImpl::createEncryptedData(
  +						XENCCipherData::XENCCipherDataType type, 
  +						XMLCh * value) {
  +
  +	// Clean out anything currently being used
  +	if (mp_encryptedData != NULL) {
  +		delete mp_encryptedData;
  +		mp_encryptedData = NULL;
  +	}
  +	// Create a new EncryptedData element
  +
  +	XSECnew(mp_encryptedData, XENCEncryptedDataImpl(this));
  +	mp_encryptedData->createBlankEncryptedData(type, value);
  +
  +	return mp_encryptedData;
  +}
  +
  +// --------------------------------------------------------------------------------
  +//			Encrypt an element
  +// --------------------------------------------------------------------------------
  +
  +DOMDocument * XENCCipherImpl::encryptElement(DOMElement * element) {
  +
  +	// Make sure we have a key before we do anything too drastic
  +	if (mp_key == NULL) {
  +		throw XSECException(XSECException::CipherError, 
  +			"XENCCipherImpl::encryptElement - No key set");
  +	}
  +
  +	// Create a transform chain to do the encryption
  +	TXFMDocObject * tdocObj;
  +	XSECnew(tdocObj, TXFMDocObject(mp_doc));
  +	TXFMChain * c;
  +	XSECnew(c, TXFMChain(tdocObj));
  +
  +	Janitor<TXFMChain> j_c(c);
  +
  +	tdocObj->setInput(mp_doc, element);
  +
  +	// Now need to serialise the element - easiest to just use a canonicaliser
  +	TXFMC14n *tc14n;
  +	XSECnew(tc14n, TXFMC14n(mp_doc));
  +	c->appendTxfm(tc14n);
  +
  +	tc14n->activateComments();
  +	tc14n->setExclusive();
  +
  +	// Do the encryption
  +	TXFMCipher *tcipher;
  +	XSECnew(tcipher, TXFMCipher(mp_doc, mp_key, true));
  +	c->appendTxfm(tcipher);
  +
  +	// Transform to Base64
  +	TXFMBase64 * tb64;
  +	XSECnew(tb64, TXFMBase64(mp_doc, false));
  +	c->appendTxfm(tb64);
  +
  +	// Read into a safeBuffer
  +	safeBuffer sb;
  +	sb << c->getLastTxfm();
  +
  +	// Create the element!
  +
  +	if (mp_encryptedData != NULL) {
  +		delete mp_encryptedData;
  +		mp_encryptedData = NULL;
  +	}
  +	
  +	XSECnew(mp_encryptedData, XENCEncryptedDataImpl(this));
  +	mp_encryptedData->createBlankEncryptedData(XENCCipherData::VALUE_TYPE, sb.sbStrToXMLCh());
  +
  +	// Replace original element
  +	DOMNode * p = element->getParentNode();
  +	
  +	if (p == NULL) {
  +		throw XSECException(XSECException::CipherError, 
  +			"XENCCipherImpl::encryptElement - Passed in element has no parent");
  +	}
  +
  +	p->replaceChild(mp_encryptedData->getDOMNode(), element);
  +
  +	return mp_doc;
   
   }
  
  
  
  1.2       +18 -1     xml-security/c/src/xenc/impl/XENCCipherImpl.hpp
  
  Index: XENCCipherImpl.hpp
  ===================================================================
  RCS file: /home/cvs/xml-security/c/src/xenc/impl/XENCCipherImpl.hpp,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- XENCCipherImpl.hpp	31 Aug 2003 12:47:19 -0000	1.1
  +++ XENCCipherImpl.hpp	8 Sep 2003 12:07:49 -0000	1.2
  @@ -77,6 +77,7 @@
   class safeBuffer;
   class XSECProvider;
   class XENCEncryptedDataImpl;
  +class TXFMChain;
   
   XSEC_DECLARE_XERCES_CLASS(DOMNode);
   XSEC_DECLARE_XERCES_CLASS(DOMDocumentFragment);
  @@ -91,17 +92,29 @@
   
   	DOMDocument * decryptElement(DOMElement * element);
   
  +	// Implementation for encryption Elements
  +	DOMDocument * encryptElement(DOMElement * element);
  +
   	// Getter methods
   	DOMDocument * getDocument(void) {return mp_doc;}
  +	const XMLCh * getXENCNSPrefix(void) const;
   
   	// Setter methods
   	void setKey(XSECCryptoKey * key) {mp_key = key;}
  +	void setXENCNSPrefix(const XMLCh * prefix);
  +	
  +	// Creation methods
  +	XENCEncryptedData * createEncryptedData(XENCCipherData::XENCCipherDataType type, 
  +											XMLCh * value);
  +
   
   protected:
   
   	// Protected to prevent direct creation of objects
   	XENCCipherImpl(DOMDocument * doc);
   
  +	// Creates a transform chain that gives the decrypted data
  +	TXFMChain * createDecryptionTXFMChain(void);
   private:
   
   	// Internal functions
  @@ -117,6 +130,10 @@
   
   	// Key
   	XSECCryptoKey			* mp_key;
  +
  +	// Prefix
  +	XMLCh					* mp_xencPrefixNS;
  +
   
   	friend XSECProvider;
   
  
  
  
  1.2       +37 -3     xml-security/c/src/xenc/impl/XENCCipherValueImpl.cpp
  
  Index: XENCCipherValueImpl.cpp
  ===================================================================
  RCS file: /home/cvs/xml-security/c/src/xenc/impl/XENCCipherValueImpl.cpp,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- XENCCipherValueImpl.cpp	31 Aug 2003 12:47:19 -0000	1.1
  +++ XENCCipherValueImpl.cpp	8 Sep 2003 12:07:49 -0000	1.2
  @@ -103,13 +103,15 @@
   
   XENCCipherValueImpl::XENCCipherValueImpl(XENCCipherImpl * cipher) :
   mp_cipher(cipher),
  -mp_cipherValueNode(NULL) {
  +mp_cipherValueNode(NULL),
  +mp_cipherString(NULL) {
   
   }
   
   XENCCipherValueImpl::XENCCipherValueImpl(XENCCipherImpl * cipher, DOMNode * node) :
   mp_cipher(cipher),
  -mp_cipherValueNode(node) {
  +mp_cipherValueNode(node),
  +mp_cipherString(NULL) {
   
   }
   
  @@ -149,6 +151,38 @@
   
   	// Get a copy
   	mp_cipherString = XMLString::replicate(txt.rawXMLChBuffer());
  +
  +}
  +
  +// --------------------------------------------------------------------------------
  +//			Create a blank structure
  +// --------------------------------------------------------------------------------
  +
  +DOMElement * XENCCipherValueImpl::createBlankCipherValue(
  +						const XMLCh * value) {
  +
  +	// Rest
  +	if (mp_cipherString != NULL) {
  +		delete[] mp_cipherString;
  +		mp_cipherString = NULL;
  +	}
  +
  +	// Get some setup values
  +	safeBuffer str;
  +	DOMDocument *doc = mp_cipher->getDocument();
  +	const XMLCh * prefix = mp_cipher->getXENCNSPrefix();
  +
  +	makeQName(str, prefix, s_CipherValue);
  +
  +	DOMElement *ret = doc->createElementNS(DSIGConstants::s_unicodeStrURIXENC, str.rawXMLChBuffer());
  +	mp_cipherValueNode = ret;
  +
  +	// Append the value
  +	ret->appendChild(doc->createTextNode(value));
  +	
  +	mp_cipherString = XMLString::replicate(value);;
  +
  +	return ret;
   
   }
   
  
  
  
  1.2       +3 -1      xml-security/c/src/xenc/impl/XENCCipherValueImpl.hpp
  
  Index: XENCCipherValueImpl.hpp
  ===================================================================
  RCS file: /home/cvs/xml-security/c/src/xenc/impl/XENCCipherValueImpl.hpp,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- XENCCipherValueImpl.hpp	31 Aug 2003 12:47:19 -0000	1.1
  +++ XENCCipherValueImpl.hpp	8 Sep 2003 12:07:49 -0000	1.2
  @@ -90,6 +90,8 @@
   
   	// Load
   	void load(void);
  +	// Create
  +	DOMElement * createBlankCipherValue(const XMLCh * value);
   
   	// Interface methods
   
  
  
  
  1.2       +11 -5     xml-security/c/src/xenc/impl/XENCEncryptedDataImpl.cpp
  
  Index: XENCEncryptedDataImpl.cpp
  ===================================================================
  RCS file: /home/cvs/xml-security/c/src/xenc/impl/XENCEncryptedDataImpl.cpp,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- XENCEncryptedDataImpl.cpp	31 Aug 2003 12:47:19 -0000	1.1
  +++ XENCEncryptedDataImpl.cpp	8 Sep 2003 12:07:49 -0000	1.2
  @@ -144,14 +144,20 @@
   	XENCEncryptedTypeImpl::load();
   
   }
  -
   // --------------------------------------------------------------------------------
  -//			Interface Methods
  +//			Create from scratch
   // --------------------------------------------------------------------------------
   
  -XENCCipherData * XENCEncryptedDataImpl::getCipherData(void) {
  +DOMElement * XENCEncryptedDataImpl::createBlankEncryptedData(
  +									XENCCipherData::XENCCipherDataType type, 
  +									const XMLCh * value) {
   
  -	return mp_cipherData;
  +	return createBlankEncryptedType(s_EncryptedData, type, value);
   
   }
  +
  +// --------------------------------------------------------------------------------
  +//			Interface Methods
  +// --------------------------------------------------------------------------------
  +
   
  
  
  
  1.2       +11 -4     xml-security/c/src/xenc/impl/XENCEncryptedDataImpl.hpp
  
  Index: XENCEncryptedDataImpl.hpp
  ===================================================================
  RCS file: /home/cvs/xml-security/c/src/xenc/impl/XENCEncryptedDataImpl.hpp,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- XENCEncryptedDataImpl.hpp	31 Aug 2003 12:47:19 -0000	1.1
  +++ XENCEncryptedDataImpl.hpp	8 Sep 2003 12:07:49 -0000	1.2
  @@ -79,7 +79,7 @@
   
   XSEC_DECLARE_XERCES_CLASS(DOMNode);
   
  -class XENCEncryptedDataImpl : public XENCEncryptedTypeImpl, XENCEncryptedData {
  +class XENCEncryptedDataImpl : public XENCEncryptedData, public XENCEncryptedTypeImpl {
   
   public:
   
  @@ -89,11 +89,18 @@
   
   	void load(void);
   
  +	// Create a blank EncryptedData DOM structure
  +
  +	DOMElement * createBlankEncryptedData(XENCCipherData::XENCCipherDataType type, const XMLCh * value);
  +
   	// Interface methods
   
  -	virtual XENCCipherData * getCipherData(void);
  +	// Inherited from XENCEncryptedData - need to re-implement
  +	virtual XENCCipherData * getCipherData(void) 
  +		{return XENCEncryptedTypeImpl::getCipherData();}
  +	virtual DOMElement * getDOMNode()
  +		{return XENCEncryptedTypeImpl::getDOMNode();}
   
  -	virtual void setKey(XSECCryptoKey * key) {XENCEncryptedTypeImpl::setKey(key);}
   
   private:
   
  
  
  
  1.2       +59 -26    xml-security/c/src/xenc/impl/XENCEncryptedTypeImpl.cpp
  
  Index: XENCEncryptedTypeImpl.cpp
  ===================================================================
  RCS file: /home/cvs/xml-security/c/src/xenc/impl/XENCEncryptedTypeImpl.cpp,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- XENCEncryptedTypeImpl.cpp	31 Aug 2003 12:47:19 -0000	1.1
  +++ XENCEncryptedTypeImpl.cpp	8 Sep 2003 12:07:49 -0000	1.2
  @@ -76,7 +76,6 @@
   #include <xsec/framework/XSECError.hpp>
   #include <xsec/utils/XSECDOMUtils.hpp>
   #include <xsec/transformers/TXFMBase64.hpp>
  -#include <xsec/transformers/TXFMCipher.hpp>
   #include <xsec/transformers/TXFMChain.hpp>
   #include <xsec/transformers/TXFMSB.hpp>
   
  @@ -146,8 +145,7 @@
   XENCEncryptedTypeImpl::XENCEncryptedTypeImpl(XENCCipherImpl * cipher) :
   mp_cipher(cipher),
   mp_encryptedTypeNode(NULL),
  -mp_cipherData(NULL),
  -mp_key(NULL) {
  +mp_cipherData(NULL) {
   
   }
   
  @@ -155,8 +153,7 @@
   XENCEncryptedTypeImpl::XENCEncryptedTypeImpl(XENCCipherImpl * cipher, DOMNode * node) :
   mp_cipher(cipher),
   mp_encryptedTypeNode(node),
  -mp_cipherData(NULL),
  -mp_key(NULL) {
  +mp_cipherData(NULL) {
   
   }
   
  @@ -165,9 +162,6 @@
   	if (mp_cipherData != NULL)
   		delete mp_cipherData;
   
  -	if (mp_key != NULL)
  -		delete mp_key;
  -
   }
   
   // --------------------------------------------------------------------------------
  @@ -225,18 +219,49 @@
   }
   
   // --------------------------------------------------------------------------------
  -//			Create a txfm chain for this transform list
  +//			Create a blank structure
   // --------------------------------------------------------------------------------
   
  -void XENCEncryptedTypeImpl::setKey(XSECCryptoKey * key) {
  +DOMElement * XENCEncryptedTypeImpl::createBlankEncryptedType(
  +						XMLCh * localName,
  +						XENCCipherData::XENCCipherDataType type, 
  +						const XMLCh * value) {
  +
  +	// Reset
  +	mp_cipherData = NULL;
  +
  +	// Get some setup values
  +	safeBuffer str;
  +	DOMDocument *doc = mp_cipher->getDocument();
  +	const XMLCh * prefix = mp_cipher->getXENCNSPrefix();
  +
  +	makeQName(str, prefix, localName);
  +
  +	DOMElement *ret = doc->createElementNS(DSIGConstants::s_unicodeStrURIXENC, str.rawXMLChBuffer());
  +	mp_encryptedTypeNode = ret;
  +
  +	// Set namespace
  +	if (prefix[0] == XERCES_CPP_NAMESPACE::chNull) {
  +		str.sbTranscodeIn("xmlns");
  +	}
  +	else {
  +		str.sbTranscodeIn("xmlns:");
  +		str.sbXMLChCat(prefix);
  +	}
   
  -	if (key == NULL)
  -		return;
  +	ret->setAttributeNS(DSIGConstants::s_unicodeStrURIXMLNS, 
  +							str.rawXMLChBuffer(), 
  +							DSIGConstants::s_unicodeStrURIXENC);
   
  -	if (mp_key != NULL)
  -		delete mp_key;
   
  -	mp_key = key->clone();
  +	// Create the cipher Data
  +	XSECnew(mp_cipherData, XENCCipherDataImpl(mp_cipher));
  +	DOMNode * cipherDataNode = mp_cipherData->createBlankCipherData(type, value);
  +
  +	// Add to EncryptedType
  +	ret->appendChild(cipherDataNode);
  +
  +	return ret;
   
   }
   
  @@ -244,11 +269,11 @@
   //			Create a txfm chain for this transform list
   // --------------------------------------------------------------------------------
   
  -TXFMChain * XENCEncryptedTypeImpl::createDecryptionTXFMChain(void) {
  +TXFMChain * XENCEncryptedTypeImpl::createCipherTXFMChain(void) {
   
  -	TXFMChain * chain;
  +	if (mp_cipherData->getCipherDataType() == XENCCipherData::VALUE_TYPE) {
   
  -	if (mp_cipherData->getCipherDataType() == XENCCipherData::CipherValue) {
  +		TXFMChain * chain;
   
   		// Given we already have this in memory, we transcode to
   		// local code page and then transform
  @@ -270,6 +295,8 @@
   
   		chain->appendTxfm(tb64);
   
  +		return chain;
  +
   	}
   
   	else {
  @@ -279,17 +306,23 @@
   
   	}
   
  -	Janitor<TXFMChain> j_chain(chain);
   
  -	// Now add the decryption TXFM
  -	TXFMCipher * tcipher;
  -	XSECnew(tcipher, TXFMCipher(mp_cipher->getDocument(), mp_key, false));
  +}
   
  -	chain->appendTxfm(tcipher);
  +// --------------------------------------------------------------------------------
  +//			Get Methods
  +// --------------------------------------------------------------------------------
   
  -	j_chain.release();
  +XENCCipherData * XENCEncryptedTypeImpl::getCipherData(void) {
   
  -	return chain;
  +	return mp_cipherData;
   
   }
   
  +DOMElement * XENCEncryptedTypeImpl::getDOMNode() {
  +
  +	if (mp_encryptedTypeNode->getNodeType() == DOMNode::ELEMENT_NODE)
  +		return static_cast<DOMElement*>(mp_encryptedTypeNode);
  +
  +	return NULL;
  +}
  
  
  
  1.2       +13 -5     xml-security/c/src/xenc/impl/XENCEncryptedTypeImpl.hpp
  
  Index: XENCEncryptedTypeImpl.hpp
  ===================================================================
  RCS file: /home/cvs/xml-security/c/src/xenc/impl/XENCEncryptedTypeImpl.hpp,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- XENCEncryptedTypeImpl.hpp	31 Aug 2003 12:47:19 -0000	1.1
  +++ XENCEncryptedTypeImpl.hpp	8 Sep 2003 12:07:49 -0000	1.2
  @@ -95,19 +95,27 @@
   	// Load elements
   	void load();
   
  -	virtual void setKey(XSECCryptoKey * key);
  +	// Create from scratch.  LocalName is the name of the owning element
  +
  +	DOMElement * createBlankEncryptedType(
  +						XMLCh * localName,
  +						XENCCipherData::XENCCipherDataType type, 
  +						const XMLCh * value);
  +
  +	// Interface Methods
  +	virtual XENCCipherData * getCipherData(void);
  +	virtual DOMElement * getDOMNode();
   
   protected:
   
   	// Create the txfm list - gives as output a TXFM chain with
  -	// the output being the decrypted data
  +	// the output being the raw encrypted data
   
  -	TXFMChain * createDecryptionTXFMChain(void);
  +	TXFMChain * createCipherTXFMChain(void);
   
   	XENCCipherImpl			* mp_cipher;
   	DOMNode					* mp_encryptedTypeNode;		// Node at head of structure
   	XENCCipherDataImpl		* mp_cipherData;
  -	XSECCryptoKey			* mp_key;
   
   	friend XENCCipherImpl;
   };