How to: Work with Digital Signatures Using the InfoPath 2003 Object Model

The InfoPath 2003-compatible object model provides features for working with digital signatures programmatically.

Digital Signature Features

The digital signatures features available in InfoPath allow you to:

  • Enable signatures for the entire form, or for specific sets of data in the form that can be signed separately.

  • Specify, for each set of data that can be signed, whether a single signature or multiple signatures are allowed and what their relationship will be. For example, you can specify whether they are parallel co-signatures or whether each new signature countersigns all the earlier signatures.

  • Specify a message to be shown to form users as they sign the form.

  • Insert and see a signature in the document.

  • View verifiable non-repudiation information that has been added to each signature for increased security. This additional information, which includes a view of the form as it was presented to each signer, is part of the signature and cannot be removed without invalidating the signature. At any time, you can recall this data by clicking on the signature in the form to display the Verify Digital Signature dialog box.

  • Take advantage of an object model for working with digital signatures. Add custom information to the signature block in fully trusted forms through the digital signature object model.

Overview of the Digital Signatures Object Model

Events

The object model for digital signatures provides the following event.

Name Description

OnSign

Occurs after a set of signable data has been selected to sign.

You can use this event to manipulate the data stored within the digital signature. For example, you can add data from a trusted timestamp server, or add a server-side countersignature of the transaction. You can also use this event to block signing if the current user is not a member of a particular group.

The OnSign event returns a reference to the SignEventObject object, which provides the following properties.

Name Description

ReturnStatus

Gets or sets a Boolean value indicating the return status of the OnSign event.

SignedDataBlock

Gets the signed data block that triggered the OnSign event.

XDocument

Gets a reference to the XDocument object associated with the OnSign event.

Collections and Objects

The object model for digital signatures provides the following collections.

Name Description

SignedDataBlocksCollection

The collection of the SignedDataBlockObject objects in the form template as defined in the form definition file (.xsf).

The SignedDataBlocksCollection collection implements properties that can be used to access the SignedDataBlockObjects objects associated with a form. The SignedDataBlocks collection is accessible through the SignedDataBlocks property of the XDocument object.

SignaturesCollection

Contains a collection of SignatureObject objects for each SignedDataBlockObject in the form.

The SignaturesCollection collection implements properties and a method that can be used to access a form's associated SignatureObject objects and to create a signature. It is accessible through the SignedDataBlockObject object.

When you use the Create method of the SignaturesCollection collection, keep in mind that the signature is not written until the Sign method is called on the SignatureObject object. These methods can be called only from the OnSign event handler of a fully trusted form template.

The object model for digital signatures provides the following objects.

Name Description

SignedDataBlockObject

Represents a set of signable data in a form. The SignedDataBlock object provides a number of properties and one method that can be used to programmatically interact with a set of signable data.

SignatureObject

Represents a digital signature that has been added to a form or set of signable data in a form. The SignatureObject collection implements properties that can be used to retrieve information about the digital signature, and the Sign method for writing the XML digital signature block and computing its cryptographic hash value.

CertificateObject

Represents the X.509 digital certificate that has been used to create the signature.

Working with Digital Signatures Programmatically

The InfoPath 2003-compatible object model provides members for interacting with digital signatures programmatically. In particular, fully-trusted forms can add custom information to the signature block before it is committed, according to the following timeline:

  1. User chooses to add a digital signature to a form.

  2. The first panel of the Digital Signature Wizard is displayed.

  3. The OnSign event for the selected data represented by the SignedDataBlockObject object is raised, and the Sign method of SignedDataBlockObject and the Create method of the SignaturesCollection collection are executed.

  4. Any optional custom actions are executed.

  5. The Sign method of the SignatureObject is executed.

  6. Second and third panes of the wizard are displayed for selecting a certificate to sign with and to enter comments.

  7. The non-repudiation information is displayed (which can be viewed later with the Verify Digital Signature dialog box).

  8. When the Sign button is clicked, the signature is added to collection of signatures for the form.

The following example invokes the Sign dialog box and countersigns the signature with a timestamp value retrieved from a trusted timestamp service.

[InfoPathEventHandler(EventType=InfoPathEventType.OnSign)]
public void OnSign(SignEvent e)
{
    Signature signature = e.SignedDataBlock.Signatures.Create();
    // Invoke the Sign dialog box to sign the data block.
    signature.Sign();
    // Countersign the signature with a trusted timestamp
    // Get the XML node storing the signature block
    IXMLDOMNode oNodeSig = signature.SignatureBlockXmlNode;
    IXMLDOMNode oNodeSigValue = oNodeSig.selectSingleNode(".//*[local-name(.)='signatureValue']");
    // Get timestamp from a trusted timestamp service (fictitious).
    MyTrustedTimeStampService s = new MyTrustedTimeStampService();
    string strVerifiedTimeStamp = s.AddTimeStamp(oNodeSigValue.text);
    
    //Add the value returned from the timestamp service to the 
    //unsigned part of the signature block
    IXMLDOMNode oNodeObj = oNodeSig.selectSingleNode(".//*[local-name(.)='Object']");
    IXMLDOMNode oNode = oNodeObj.cloneNode(false);
    oNode.text = strVerifiedTimeStamp;
    oNodeObj.parentNode.appendChild(oNode);

    e.ReturnStatus = true;
}