CryptMsgCountersignEncoded

The CryptMsgCountersignEncoded function countersigns an already existing signature (encoded SignerInfo, as defined by PKCS # 7). Outputs an encoded SignerInfo blob, suitable for use as a countersignature attribute in the unauthenticated attributes of a signed-data or signed-and-enveloped-data message.

#include <wincrypt.h>
BOOL WINAPI CryptMsgCountersignEncoded(
  DWORD dwMsgAndCertEncodingType,             // in
  PBYTE pbSignerInfo,                         // in
  DWORD cbSignerInfo,                         // in
  DWORD cCountersigners,                      // in
  PCMSG_SIGNER_ENCODE_INFO rgCountersigners,  // in
  PBYTE pbCountersignature,                   // out
  PDWORD pcbCountersignature                  // in/out
);
 

Parameters

dwMsgAndCertEncodingType
Type of encoding used. Note that both a certificate and message encoding type is required to be specified by combining them with a bitwise OR operation, as shown in the following example:
CRYPT_ASN_ENCODING | PKCS_7_ASN_ENCODING
 

Currently defined encoding types are shown in the following table.
Encoding type Value
CRYPT_ASN_ENCODING 0x00000001
PKCS_7_ASN_ENCODING 0x00010000

pbSignerInfo
Pointer to the encoded SignerInfo that is to be countersigned.
cbSignerInfo
Count, in bytes, of the encoded SignerInfo data.
cCountersigners
Number of countersigners in the rgCountersigners array.
rgCountersigners
Array of countersigners to be added.
pbCountersignature
Pointer to a buffer that receives an encoded countersignature attribute as defined in PKCS #9.

This parameter can be NULL to set the size of this information for memory allocation purposes. For more information, see Common In/Out Parameter Conventions.

pcbCountersignature
Pointer to a variable that specifies the size, in bytes, of the buffer pointed to by the pbCountersignature parameter. When the function returns, the variable pointed to by the pcbCountersignature parameter contains the number of bytes stored in the buffer. This parameter can be NULL, only if pbCountersignature is NULL.

Return Values

If the function fails, the return value is FALSE (zero). If it succeeds, the return value is TRUE (non-zero).

To retrieve extended error information, use the GetLastError function.

The following table lists the error codes most commonly returned by the GetLastError function.

Error code Description
CRYPT_E_OID_FORMAT The object identifier is badly formatted.
CRYPT_E_OSS_ERROR OSS Certificate encode/decode error code base. Note, to get the OSS error subtract CRYPT_E_OSS_ERROR from the returned error and see asn1code.h for details on the error.
E_INVALIDARG One or more arguments are invalid.
E_OUTOFMEMORY Ran out of memory.
Propagated errors that may be encountered: An error can be propagated from
CryptCreateHash
CryptHashData
CryptGetHashParam
CryptSignHash
CryptMsgOpenToEncode
CryptMsgUpdate

An error can be propagated from
CryptMsgControl if dwCtrlType == CMSG_CTRL_ADD_SIGNER_UNAUTH_ATTR.


Example

// EXAMPLE CODE FOR USING CryptMsgCountersignEncoded().
// Countersigns an already existing signature.
// Assume that pointers to the encoded SignerInfo
// (pbSignerInfo) and the array of countersigners
// (rgCountersigners) have already been defined.

// Set up the variables.
DWORD dwMsgAndCertEncodingType = CRYPT_ASN_ENCODING | PKCS_7_ASN_ENCODING;
                              // Type of encoding
PBYTE pbSignerInfo;           // Pointer to encoded SignerInfo
DWORD cbSignerInfo = 128;     // #, in bytes, of encoded SignerInfo
DWORD cCountersigners = 3;    // # of countersigners
PCMSG_SIGNER_ENCODE_INFO rgCountersigners;
                              // Pointer to array of countersigners
PBYTE pbCountersignature;     // Pointer to countersignature attribute
PDWORD cbCountersignature;    // Pointer to size, in bytes, of
                              //   pbCountersignature
BOOL fResult;                 // Return TRUE if function succeeds
                              //   FALSE if function fails

// Function called the first time to retrieve a pointer to
// the size of the countersignature (cbCounteresignature)
fResult= CryptMsgCountersignEncoded(
           dwMsgAndCertEncodingType,
           pbSignerInfo,
           cbSignerInfo,
           cCountersigners,
           rgCountersigners,
           NULL,                            // NULL on first call
           cbCountersignature);

if (!fResult){
  cout << "first call to CryptMsgCountersignEncoded failed"<< endl;
}
else {
  cout<< "first call to CryptMsgCountersignEncoded successful"<< endl;
  pbCountersignature = (PBYTE) malloc (*cbCountersignature);
  cout<< "memory allocated"<< endl;
}

// Function call to getSignerInfo blob
fResult= CryptMsgCountersignEncoded(
           dwMsgAndCertEncodingType,       // in
           pbSignerInfo,                   // in
           cbSignerInfo,                   // in
           cCountersigners,                // in
           rgCountersigners,               // in
           pbCountersignature,             // out
           cbCountersignature);            // in/out

if (!fResult) {                            // FALSE
 cout<< "Function failed"<< endl
     << "error code = "<< GetLastError()<< endl;
}
else {                                     // TRUE
 cout<< "Function succeeded"<< endl
     << "size = "<< &cbCountersignature<< endl
     << "countersignature attribute = "<< &pbCountersignature;
}
free (pbCountersignature);
 

QuickInfo

  Windows NT: Requires version 4.0 SP3 or later. Available also in IE 3.02 and later.
  Windows: Requires Windows 98 (or Windows 95 with IE 3.02 or later).
  Windows CE: Unsupported.
  Header: Declared in wincrypt.h.
  Import Library: Use crypt32.lib.

See Also

CryptMsgCountersign, CryptMsgVerifyCountersignatureEncoded