SignatureProvider.SignXmlDsig method (Office)

Used to sign the XMLDSIG template.

Syntax

expression.SignXmlDsig(QueryContinue, psigsetup, psiginfo, XmlDsigStream)

expression An expression that returns a SignatureProvider object.

Parameters

Name Required/Optional Data type Description
QueryContinue Required IQueryContinue Provides a way to query the host application for permission to continue the verification operation.
psigsetup Required SignatureSetup Specifies configuration information about a signature line.
psiginfo Required SignatureInfo Specifies information captured from the signing ceremony.
XmlDsigStream Required IStream Represents a stream of data containing XML, which represents an XMLDSIG object.

Remarks

XMLDSIG is a standards-based signature format (https://www.w3.org/TR/xmldsig-core/), verifiable by third parties. This is the default format for signatures in Microsoft Office.

Example

The following example, written in C#, shows the implementation of the SignXmlDsig method in a custom signature provider project.

 public void SignXmlDsig(object queryContinue, SignatureSetup sigsetup, SignatureInfo siginfo, object xmldsigStream) 
 { 
 using (COMStream comstream = new COMStream(xmldsigStream)) 
 { 
 XmlDocument xmldsig = new XmlDocument(); 
 xmldsig.PreserveWhitespace = true; 
 xmldsig.Load(comstream); 
 
 XmlNamespaceManager nsmgr = new XmlNamespaceManager(xmldsig.NameTable); 
 nsmgr.AddNamespace("ds", "https://www.w3.org/2000/09/xmldsig#"); 
 
 XmlElement signature = xmldsig.DocumentElement; 
 SignedXml signedXml = new SignedXml(); 
 signedXml.LoadXml(signature); 
 
 // Cert 
 X509Certificate2 cert = TestSignatureProvider.GetSigningCertificate(siginfo); 
 KeyInfo keyInfo = new KeyInfo(); 
 if (cert.PrivateKey is RSA) 
 keyInfo.AddClause(new RSAKeyValue((RSA) cert.PrivateKey)); 
 else if (cert.PrivateKey is DSA) 
 keyInfo.AddClause(new DSAKeyValue((DSA) cert.PrivateKey)); 
 keyInfo.AddClause(new KeyInfoX509Data(cert)); 
 signedXml.SigningKey = cert.PrivateKey; 
 signedXml.KeyInfo = keyInfo; 
 
 // Compute signature 
 signedXml.ComputeSignature(); 
 
 // Copy data from signed signature 
 // REVIEW: Cleaner way to do this? 
 string[] xpathsToCopy = new string[] 
 { 
 "./ds:SignedInfo", 
 "./ds:SignatureValue", 
 "./ds:KeyInfo", 
 }; 
 XmlElement signedSignature = signedXml.GetXml(); 
 foreach (string xpathToCopy in xpathsToCopy) 
 { 
 signature.ReplaceChild( 
 xmldsig.ImportNode(signedSignature.SelectSingleNode(xpathToCopy, nsmgr), true), 
 signature.SelectSingleNode(xpathToCopy, nsmgr)); 
 } 
 
 // Save signature back to stream 
 comstream.SetLength(0); 
 comstream.Position = 0; 
 xmldsig.Save(new XmlTextWriter(comstream, new UTF8Encoding(false))); 
 } 
 }

Note

Signature providers are implemented exclusively in custom COM add-ins created in managed and unmanaged code and cannot be implemented in Microsoft Visual Basic for Applications (VBA).

See also

Support and feedback

Have questions or feedback about Office VBA or this documentation? Please see Office VBA support and feedback for guidance about the ways you can receive support and provide feedback.