#include <stdio.h> #import <msxml5.dll> using namespace MSXML2; #define PROV_RSA_FULL 1 #import <CAPICOM.dll> using namespace CAPICOM; #define DSIGNS "xmlns:ds='http://www.w3.org/2000/09/xmldsig#'" //Change this key container name to your own if necessary.#define RSA_KEY "MyRSAFullKeys"#define INFILE "signature_template.store.rsa.xml"_bstr_t infile, outfile;IXMLDOMDocument3Ptr xmldoc = NULL;IXMLDigitalSignaturePtr xmldsig = NULL;IStore2Ptr certStore = NULL;VARIANT_BOOL objectsAreInitialized = VARIANT_FALSE;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;}return VARIANT_TRUE;}VARIANT_BOOL SignXML(XMLDSIG_WRITEKEYINFO fwWriteKeyInfo){if (xmldsig->signature == NULL) {printf("Invalid signature template\n");return false;}IXMLDSigKeyPtr pKey = xmldsig->createKeyFromCSP(PROV_RSA_FULL, "", RSA_KEY, 0);if (pKey==NULL) {printf("Invalid key\n");return false;}IXMLDSigKeyPtr pKeyOut = xmldsig->sign(pKey, fwWriteKeyInfo);if (NULL == pKeyOut) {printf("sign failed.\n");return false;}printf("The speicfied data was signed successfully.\n");printf("Resultant signature:\n");printf((LPCSTR)xmldoc->xml);printf("\n");return true;}VARIANT_BOOL initObjects(){HRESULT hr;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;xmldoc->resolveExternals = VARIANT_FALSE;hr = certStore.CreateInstance(__uuidof(Store));if (FAILED( hr )) {printf("Installatioin of CAPICOM Store 2 failed.\n");return VARIANT_FALSE;}hr = certStore->Open(CAPICOM_CURRENT_USER_STORE, "MY", CAPICOM_STORE_OPEN_READ_ONLY);if (FAILED(hr)) {printf("certStore->Open failed.\n");return VARIANT_FALSE;}objectsAreInitialized = VARIANT_TRUE;return VARIANT_TRUE;}void cleanObjects(){if (xmldoc) xmldoc.Release();if (xmldsig) xmldsig.Release();if (certStore) certStore.Release();}void main(){if ( CoInitialize(NULL) == E_FAIL) {printf("can't initialize COM Lib\n");exit(-1);}if (!initObjects()) {cleanObjects();exit(-1);}infile = INFILE;if (VARIANT_TRUE == LoadXML(infile)) {printf("Sign with fwWriteKeyInfo = CERTIFICATES:\n");SignXML(CERTIFICATES);if (certStore) {xmldsig->store = certStore;printf("store set on xmldsig.\n");printf("number of certificates in the store = %d\n\n",certStore->Certificates->Count);}else {printf("invalid certstore\n");}printf("Sign with fwWriteKeyInfo = CERTIFICATES:\n");SignXML(XMLDSIG_WRITEKEYINFO(CERTIFICATES|PURGE));}cleanObjects();CoUninitialize();}
Try It!