Countersigning Signed Messages

Sometimes you may want to countersign a signed message. For example, assume that user A sends a document, in the form of a signed-data message, to user B, expecting B to confirm agreement to the terms contained in the document. User B decodes the message, reads the terms and, if in agreement, countersigns the message. The countersigned message is then sent the back to user A. User A now knows, and can prove, that user B agreed to the terms.

There are some CryptoAPI low-level message functions that assist with the countersigning process.

Note  Although the syntax of these functions allows for multiple countersigners, only a single countersigner is currently supported.

    To countersign a signed message by using CryptMsgCountersign
  1. Call CryptMsgOpenToDecode to get a handle to the signed message.
  2. Initialize a PCMSG_SIGNER_ENCODE_INFO structure for the countersigner.
  3. Add the PCMSG_SIGNER_ENCODE_INFO structure to an array of countersigners (only one countersigner is currently supported).
  4. Call CryptMsgCountersign to add the countersignature(s).

If the function call succeeds, the original message now has a countersignature included as an unauthenticated attribute.

    To countersign a signed message by using CryptMsgCountersignEncoded
  1. Call CryptMsgOpenToDecode to get a handle to the signed message.
  2. Call CryptMsgGetParam to retrieve the encoded SignerInfo of the signed message.
  3. Initialize a PCMSG_SIGNER_ENCODE_INFO structure for the countersigner.
  4. Add PCMSG_SIGNER_ENCODE_INFO structure to an array of countersigners (only one countersigner is currently supported).
  5. Call CryptMsgCountersignEncoded to create the encoded countersignature attribute.
  6. Call CryptMsgControl to add the countersignature attribute to the original message as an unauthenticated attribute.

If all of the function calls succeed, a countersignature attribute was added to the original message.

    To Verify a Countersignature
  1. Call CryptMsgOpenToDecode to get a handle to the signed message.
  2. Get a pointer to the countersigner's certificate (PCERT_INFO).
  3. Call CryptMsgGetParam to retrieve the SignerInfo from the message.
  4. Call CryptMsgGetParam to retrieve the Countersignature from the message.
  5. Call CryptMsgVerifyCountersignatureEncoded to verify the countersignature.

If the CryptMsgVerifyCountersignatureEncoded function call succeeds, the countersignature is verified.