Download the Cryptlib manual

Transcript
86
S/MIME
CRYPT_CONTEXT hashContext;
CRYPT_ENVELOPE cryptEnvelope;
int bytesCopied, sigCheckStatus;
/* Create the hash context and hash the signed data */
cryptCreateContext( &hashContext, cryptUser, CRYPT_ALGO_SHA1 );
cryptEncrypt( hashContext, signedData, dataLength );
cryptEncrypt( hashContext, signedData, 0 );
/* Create the envelope and add the hash */
cryptCreateEnvelope( &cryptEnvelope, cryptUser, CRYPT_FORMAT_AUTO );
cryptSetAttribute( cryptEnvelope, CRYPT_ENVINFO_HASH, hashContext );
cryptDestroyContext( hashContext );
/* Add the detached signature */
cryptPushData( cryptEnvelope, signatureData, signatureDataLength,
&bytesCopied );
cryptFlushData( cryptEnvelope );
/* Determine the result of the signature check */
cryptGetAttribute( cryptEnvelope, CRYPT_ENVINFO_SIGNATURE_RESULT,
&sigCheckStatus );
cryptDestroyEnvelope( cryptEnvelope );
When you push in the detached signature cryptlib will verify that the hash
information in the signature matches the hash that you’ve supplied. If the two don’t
match, cryptlib will return CRYPT_ERROR_SIGNATURE to indicate that the
signature can’t be verified using the given values. Because of this check, you must
add the hash before you push in the detached signature.
Extra Signature Information
S/MIME signatures can include with them extra information such as the time at
which the message was signed. Normally cryptlib will add and verify this
information for you automatically, with the details of what’s added based on the
setting of the CRYPT_OPTION_CMS_DEFAULTATTRIBUTES option as
described in “Working with Configuration Options” on page 275. If this option is set
to false (zero), cryptlib won’t add any additional signature information, which
minimises the size of the resulting signature. If this option is set to true (any nonzero
value), cryptlib will add default signing attributes such as the signing time for you.
You can also handle the extra signing information yourself if you require extra
control over what’s included with the signature. The extra information is specified as
a CRYPT_CERTTYPE_CMS_ATTRIBUTES certificate object. To include this
information with the signature you should add it to the envelope alongside the signing
key as CRYPT_ENVINFO_SIGNATURE_EXTRADATA:
CRYPT_ENVELOPE cryptEnvelope;
CRYPT_CERTIFICATE cmsAttributes;
/* Create the CMS attribute object */
cryptCreateCert( &cmsAttributes, cryptUser,
CRYPT_CERTTYPE_CMS_ATTRIBUTES );
/* ... */
/* Create the envelope and add the signing key and signature
information */
cryptCreateEnvelope( &cryptEnvelope, cryptUser, CRYPT_FORMAT_CMS );
cryptSetAttribute( cryptEnvelope, CRYPT_ENVINFO_SIGNATURE,
sigKeyContext );
cryptSetAttribute( cryptEnvelope, CRYPT_ENVINFO_SIGNATURE_EXTRADATA,
cmsAttributes );
cryptDestroyCert( cmsAttributes );
/* Add the data size information and data, wrap up the processing, and
pop out the processed data */
cryptSetAttribute( cryptEnvelope, CRYPT_ENVINFO_DATASIZE,
messageLength );
cryptPushData( cryptEnvelope, message, messageLength, &bytesCopied );
cryptFlushData( cryptEnvelope );
cryptPopData( cryptEnvelope, envelopedData, envelopedDataBufferSize,
&bytesCopied );