C/C++ Source: setDebugOutput.cpp
This is the main program for the setDebugOutput Method example. This code performs the following steps:
- Instantiates
DBStream
. - Calls
setDebugOutput
. - Calls on an XML DOM object that has loaded the signature.template.xml file.
- Calls
verify
on the signed signature document, signature.document.xml.
#include <stdio.h> #import <msxml5.dll> using namespace MSXML2; #include "DBStream.h" #define DSIGNS "xmlns:ds='http://www.w3.org/2000/09/xmldsig#'" #define SIG_TEMP "signature.template.xml" #define SIG_DOC "signature.document.xml" // Change this key container name to your own if necessary. #define RSA_KEY "myRSAFullKeys" IXMLDOMDocument3Ptr xmldoc = NULL; IXMLDigitalSignatureExPtr xmldsig = NULL; VARIANT_BOOL objectsAreInitialized = VARIANT_FALSE; DBStream * dbStream = NULL; ////////////////////////////////////////////////// // Load a signature document into dom and assign it to the xmldsig object. // VARIANT_BOOL LoadXML(_bstr_t sigFile) { if (!objectsAreInitialized) { printf("Must initialize objects before loading signature.\n"); return VARIANT_FALSE; } if (xmldoc->load(sigFile) == VARIANT_FALSE) { printf("Can't load %s\n", (LPCSTR)sigFile); return VARIANT_FALSE; } xmldoc->setProperty("SelectionNamespaces", DSIGNS); // Set the signature property to a <ds:Signature> DOM node. xmldsig->signature = xmldoc->selectSingleNode(".//ds:Signature"); if (xmldsig->signature == NULL) { printf("Failed to set the signature property.\n"); return VARIANT_FALSE; } printf("\n%s has been loaded into an XML DOM\n\n",(LPCSTR)sigFile); return VARIANT_TRUE; } ///////////////////////////////////////////// // Verify signature with a key embedded in the signature document. // VARIANT_BOOL VerifyXML() { IXMLDSigKeyPtr pKeyOut; pKeyOut = xmldsig->verify(NULL); if (pKeyOut== NULL) { printf("Invalid signature.\n"); return VARIANT_FALSE; } printf("\nSignature verified.\n\n"); return VARIANT_TRUE; } VARIANT_BOOL SignXML(XMLDSIG_WRITEKEYINFO fwWriteKeyInfo) { if (xmldsig->signature == NULL) { printf("Invalid signature template\n"); return VARIANT_FALSE; } IXMLDSigKeyPtr pKey = xmldsig->createKeyFromCSP( PROV_RSA_FULL, "", RSA_KEY, 0); if (pKey==NULL) { printf("Invalid key\n"); return VARIANT_FALSE; } IXMLDSigKeyPtr pKeyOut = xmldsig->sign(pKey, fwWriteKeyInfo); if (NULL == pKeyOut) { printf("sign failed.\n"); return VARIANT_FALSE; } printf("\nData signed.\n\n"); return VARIANT_TRUE; } ///////////////////////////////// // Helper function to create dom and dsig objects: // VARIANT_BOOL initObjects() { if (FAILED(xmldsig.CreateInstance(__uuidof(MXDigitalSignature50)) )) { printf("Installation of msxml5 is required to run this app.\n"); return VARIANT_FALSE; } if (FAILED(xmldoc.CreateInstance(__uuidof(DOMDocument50)) )) { printf("Installation of msxml5 is required to run this app.\n"); return VARIANT_FALSE; } xmldoc->async = VARIANT_FALSE; xmldoc->validateOnParse = VARIANT_FALSE; xmldoc->preserveWhiteSpace = VARIANT_TRUE; dbStream = new DBStream(); if (dbStream==NULL) { printf("Can't instantiate DBStream\n"); return VARIANT_FALSE; } HRESULT hr = xmldsig->setDebugOutput(dbStream); if (FAILED(hr)) { printf("Can't setDebugOutput\n"); return VARIANT_FALSE; } objectsAreInitialized = VARIANT_TRUE; return VARIANT_TRUE; } //////////////////////////////// // Helper function to release dom and dsig objects: // void cleanObjects() { if (xmldoc) xmldoc.Release(); if (xmldsig) xmldsig.Release(); if (dbStream) dbStream->Release(); } ///////////////////////////////// // Main function: // void main() { if ( CoInitialize(NULL) == E_FAIL) { printf("can't initialize COM Lib\n"); exit(-1); } if (!initObjects()) { cleanObjects(); exit(-1); } if(VARIANT_TRUE == LoadXML(SIG_TEMP)) { if (VARIANT_TRUE != SignXML(KEYVALUE)) { printf("exit with failure.\n"); } xmldoc->save(SIG_DOC); } if(VARIANT_TRUE == LoadXML(SIG_DOC)) { if (VARIANT_TRUE != VerifyXML()) { printf("exit with failure.\n"); } } cleanObjects(); CoUninitialize(); }