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;
};