You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@santuario.apache.org by Pe...@elekta.com on 2004/10/28 14:19:43 UTC

How do I sign several nodes at once? C++




I have a problem to sign several nodes at once.
I have started with the simpleHMAC program and extended it a bit.
See code below.
I am a newbie with XML security, so it may be obvious to
someone what is wrong.
The few things that differs from the original simpleHMAC
is that I added some alternative code for creating references.
I also use code provided with Xerces to output the document.

By using 2 different Ids I can sign the 2 ToAdress elements
as expected, but that is not what I want to do.
Run the program as follows:
  ./simplesignaturetest 1 2 >tmp.xml;./checksig -h secret tmp.xml
  Output:
  Signature verified OK!

Now, if I want to get hold of the 2 ToAdress elements _without_ having to
deal with
Ids, how do I do?

I tried with an xpointer expession, which didn't work. First of all, I
don't know
xpointer to well. Second off, I do not really understand how this
referencing
stuff works either.

I have tried to get hold of the referenceList. I thought that I could add
references
by inserting nodes directly somehow, but I could not figure out how to do
it.

My try, which doesn't work:
  ./simplesignaturetest 1 2 3 >tmp.xml
  Now, if I edit the FromAdress, the verification fails.

Best regards,
Peter


#include <iostream>
// Xerces
#include <xercesc/util/PlatformUtils.hpp>
#include <xercesc/framework/StdOutFormatTarget.hpp>

// XML-Security-C (XSEC)
#include <xsec/framework/XSECProvider.hpp>
#include <xsec/dsig/DSIGReference.hpp>
#include <xsec/enc/OpenSSL/OpenSSLCryptoKeyHMAC.hpp>
#include <xsec/framework/XSECException.hpp>

// Xalan
#ifndef XSEC_NO_XALAN
#include <xalanc/XalanTransformer/XalanTransformer.hpp>
XALAN_USING_XALAN(XalanTransformer)
#endif

XERCES_CPP_NAMESPACE_USE
using namespace std;

DOMDocument *createLetter1(DOMImplementation *impl) {

  DOMDocument *doc = impl->createDocument(
                                0,
                                MAKE_UNICODE_STRING("Letter"),
                                NULL);

  DOMElement *rootElem = doc->getDocumentElement();
  // Add the ToAddress
  DOMElement *addressElem =
doc->createElement(MAKE_UNICODE_STRING("ToAddress"));
  rootElem->appendChild(doc->createTextNode(MAKE_UNICODE_STRING("\n")));
  rootElem->appendChild(addressElem);
  rootElem->setAttribute(MAKE_UNICODE_STRING("Id"),
                   MAKE_UNICODE_STRING("ToSign1"));

  addressElem->appendChild(doc->createTextNode(
                                     MAKE_UNICODE_STRING("The address of
Recipient 1")));
  addressElem->setAttribute(MAKE_UNICODE_STRING("Id"),
                      MAKE_UNICODE_STRING("ToSign2"));
  // A second ToAddress
  addressElem = doc->createElement(MAKE_UNICODE_STRING("ToAddress"));
  rootElem->appendChild(doc->createTextNode(MAKE_UNICODE_STRING("\n")));
  rootElem->appendChild(addressElem);
  addressElem->appendChild(doc->createTextNode(
                                     MAKE_UNICODE_STRING("The address of
Recipient 2")));

  // Add the FromAddress
  addressElem = doc->createElement(MAKE_UNICODE_STRING("FromAddress"));
  rootElem->appendChild(doc->createTextNode(MAKE_UNICODE_STRING("\n")));
  rootElem->appendChild(addressElem);
  addressElem->appendChild(doc->createTextNode(
                                     MAKE_UNICODE_STRING("The address of
the Sender")));
  addressElem->setAttribute(MAKE_UNICODE_STRING("Id"),
                      MAKE_UNICODE_STRING("ToSign3"));

  // Add some text
  DOMElement *textElem = doc->createElement(MAKE_UNICODE_STRING("Text"));
  rootElem->appendChild(doc->createTextNode(MAKE_UNICODE_STRING("\n")));
  rootElem->appendChild(textElem);
  textElem->appendChild(doc->createTextNode(
                                  MAKE_UNICODE_STRING("\nTo whom it may
concern\n\n...\n")));
  return doc;
}

// A document with a schema declaration.
DOMDocument *createLetter2(DOMImplementation *impl) {
  DOMDocument *doc = createLetter1(impl);
  DOMElement *docElem = doc->getDocumentElement();

docElem->setAttributeNS(MAKE_UNICODE_STRING("http://www.w3.org/2001/XMLSchema-instance"),
                    MAKE_UNICODE_STRING("xsi:noNamespaceSchemaLocation"),
                    MAKE_UNICODE_STRING("los-v1.xsd"));
  return doc;
}

int main (int argc, char **argv) {

  try {
    XMLPlatformUtils::Initialize();
#ifndef XSEC_NO_XALAN
    XalanTransformer::initialize();
#endif
    XSECPlatformUtils::Initialise();
  }
  catch (const XMLException &e) {
    cerr << "Error during initialisation of Xerces" << endl;
    cerr << "Error Message = : " << e.getMessage() << endl;
  }

  // Create a blank Document

  DOMImplementation *impl =

DOMImplementationRegistry::getDOMImplementation(MAKE_UNICODE_STRING("Core"));

  // Create a letter
  DOMDocument *doc;
  if (argc == 2)
    doc = createLetter2(impl);
  else// if (argc == 2)
    doc = createLetter1(impl);

  DOMElement *rootElem = doc->getDocumentElement();

  // The signature

  XSECProvider prov;
  DSIGSignature *sig;
  DOMElement *sigNode;
  try {

    // Create a signature object
    sig = prov.newSignature();
    sig->setDSIGNSPrefix(MAKE_UNICODE_STRING("ds"));

    // Use it to create a blank signature DOM structure from the doc
    sigNode = sig->createBlankSignature(doc, CANON_C14N_COM,
SIGNATURE_HMAC, HASH_SHA1);

    // Insert the signature DOM nodes into the doc
    rootElem->appendChild(doc->createTextNode(MAKE_UNICODE_STRING("\n")));
    rootElem->appendChild(sigNode);
    rootElem->appendChild(doc->createTextNode(MAKE_UNICODE_STRING("\n")));

    // Create an envelope reference for the text to be signed
    DSIGReference * ref;
    if (argc == 3) { // Works ok
      cerr << "Signing ToAddresses" << endl;
      ref = sig->createReference(MAKE_UNICODE_STRING("#ToSign2"));
      ref->appendEnvelopedSignatureTransform();
      ref = sig->createReference(MAKE_UNICODE_STRING("#ToSign3"));
      ref->appendEnvelopedSignatureTransform();
    }
    else if (argc == 4){ // Does not work as expected.
      cerr << "Trying to sign all ToAddresses at once" << endl;
      // None of the 2 next lines works as I expect.
      ref =
sig->createReference(MAKE_UNICODE_STRING("#xpointer(id('ToSign1')//ToAddress)"));
      //ref =
sig->createReference(MAKE_UNICODE_STRING("#xpointer(id('ToSign1')/ToAddress)"));

      //ref =
sig->createReference(MAKE_UNICODE_STRING("#xpointer(id('ToSign1'))"));//Works
 as expected.
      ref->appendEnvelopedSignatureTransform();
    } else {
      ref = sig->createReference(MAKE_UNICODE_STRING(""));
      ref->appendEnvelopedSignatureTransform();
    }

    // Set the HMAC Key to be the string "secret"
    OpenSSLCryptoKeyHMAC * hmacKey = new OpenSSLCryptoKeyHMAC();
    hmacKey->setKey((unsigned char *) "secret", (unsigned int)
strlen("secret"));
    sig->setSigningKey(hmacKey);

    // Add a KeyInfo element
    sig->appendKeyName(MAKE_UNICODE_STRING("The secret key is
\"secret\""));

    // Sign
    sig->sign();
  }
  catch (XSECException &e) {
    cerr << "An error occured during a signature load\n   Message: "
       << e.getMsg() << endl;
    throw;
  }

  // Output

  // StdOutFormatTarget prints the resultant XML stream
  // to stdout once it receives any thing from the serializer.
  //
  XMLFormatTarget *myFormTarget = new StdOutFormatTarget();
  // Output
  // get a serializer, an instance of DOMWriter
  XMLCh tempStr[100];
  XMLString::transcode("LS", tempStr, 99);
  DOMWriter         *theSerializer =
((DOMImplementationLS*)impl)->createDOMWriter();
  //theSerializer->setFeature(XMLUni::fgDOMWRTFormatPrettyPrint, true);

  theSerializer->writeNode(myFormTarget, *doc);

  return 0;
}



*******************Internet Email Confidentiality Footer*******************
The contents of this e-mail message (including any attachments hereto) are
confidential to and are intended to be conveyed for the use of the
recipient to whom it is addressed only. If you receive this transmission in
error, please notify the sender of this immediately and delete the message
from your system. Any distribution, reproduction or use of this message by
someone other than recipient is not authorized and may be unlawful.