#include <stdio.h> #import <msxml5.dll> using namespace MSXML2; #define PROV_RSA_FULL 1 IXMLDOMDocument3Ptr xmldoc = NULL; IXMLDigitalSignaturePtr xmldsig = NULL; VARIANT_BOOL objectsAreInitialized = VARIANT_FALSE; VARIANT_BOOL loadSignature(_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; } printf("\nInput signature template:\n\n%s\n", (LPCSTR)xmldoc->xml); xmldoc->setProperty("SelectionNamespaces", "xmlns:ds='http://www.w3.org/2000/09/xmldsig#'"); // 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; } return VARIANT_TRUE; } VARIANT_BOOL signWithKey(long CspType, _bstr_t keyContainer) { if (!objectsAreInitialized) { printf("Must initialize object for signing.\n"); return VARIANT_FALSE; } // Get the value of the signature property and see if // it has been set. if (xmldsig->signature == NULL) { printf("Must set signature template before signing.\n"); return VARIANT_FALSE; } IXMLDSigKeyPtr dsigKey = xmldsig->createKeyFromCSP(CspType, "", keyContainer,0); if (dsigKey == NULL) { printf("Failed to create key from CSP\n"); return VARIANT_FALSE; } IXMLDSigKeyPtr signedKey = xmldsig->sign(dsigKey, KEYVALUE); if (signedKey != NULL) { printf("\nThe data referenced in the signature template "); printf("was signed successfully.\nResultant signature:\n\n"); printf("%s\n",(LPCSTR)xmldoc->xml); } else { printf("Signing failed.\n"); if (dsigKey) dsigKey.Release(); return VARIANT_FALSE; } if (dsigKey) dsigKey.Release(); if (signedKey) signedKey.Release(); return VARIANT_TRUE; } 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; objectsAreInitialized = VARIANT_TRUE; return VARIANT_TRUE; } void cleanObjects() { if (xmldoc) xmldoc.Release(); if (xmldsig) xmldsig.Release(); } void main() { if ( CoInitialize(NULL) == E_FAIL) { printf("can't initialize COM Lib\n"); exit(-1); } if (!initObjects()) { cleanObjects(); exit(-1); } if(VARIANT_TRUE == loadSignature("signature_template.xml")) { // Change this key container name to your own if necessary. if (VARIANT_TRUE != signWithKey(PROV_RSA_FULL, "MyRSAFullKeys")) { printf("exit with failure.\n"); } } cleanObjects(); CoUninitialize(); }
Try It!