FUNCTION SignMessage LPARAMETERS toMsg As CDO.Message #define CAPICOM_AUTHENTICATED_ATTRIBUTE_SIGNING_TIME 0 && The attribute contains the time that the signature was created. #define CAPICOM_AUTHENTICATED_ATTRIBUTE_DOCUMENT_NAME 1 && The attribute contains the name of the signed document. #define CAPICOM_AUTHENTICATED_ATTRIBUTE_DOCUMENT_DESCRIPTION 2 && The attribute contains a description of the signed document PRIVATE loSecMsg As CDO.Message PRIVATE loBodyPart As CDO.IBodyPart PRIVATE loSignedData As CAPICOM.SignedData PRIVATE lcData As String PRIVATE lcContent As String PRIVATE loStream As ADODB.Stream PRIVATE loSigner As CAPICOM.Signer PRIVATE loCert As CAPICOM.Certificate PRIVATE loAttr As CAPICOM.Attribute loSecMsg=CREATEOBJECT('CDO.Message') loSignedData=CREATEOBJECT('CAPICOM.SignedData') loSigner=CREATEOBJECT('CAPICOM.Signer') loAttr=CREATEOBJECT('CAPICOM.Attribute') loSecMsg.DataSource.OpenObject(toMsg,'IMessage') *!* Set up main bodypart loBodyPart = loSecMsg.BodyPart loBodyPart.ContentMediaType = 'application/pkcs7-mime;smime-type=signed-data;name=""smime.p7m""' loBodyPart.ContentTransferEncoding = "base64" loBodyPart.Fields("urn:schemas:mailheader:content-disposition") = 'attachment;FileName=""smime.p7m""' loBodyPart.Fields.Update *!* Get certificate *!* loCert = GetCertForSignature(loSecMsg.From) LOCAL loStore As CAPICOM.Store #define CAPICOM_CURRENT_USER_STORE 2 #define CAPICOM_STORE_OPEN_READ_ONLY 0 #define CAPICOM_CERT_INFO_SUBJECT_SIMPLE_NAME 0 && Returns the display name of the certificate subject. #define CAPICOM_CERT_INFO_ISSUER_SIMPLE_NAME 1 && Returns the display name of the issuer of the certificate. #define CAPICOM_CERT_INFO_SUBJECT_EMAIL_NAME 2 && Returns the e-mail address of the certificate subject. #define CAPICOM_CERT_INFO_ISSUER_EMAIL_NAME 3 && Returns the e-mail address of the issuer of the certificate. #define CAPICOM_CERT_INFO_SUBJECT_UPN 4 && Returns the UPN of the certificate subject. Introduced in CAPICOM 2.0. #define CAPICOM_CERT_INFO_ISSUER_UPN 5 && Returns the UPN of the issuer of the certificate. Introduced in CAPICOM 2.0. #define CAPICOM_CERT_INFO_SUBJECT_DNS_NAME 6 && Returns the DNS name of the certificate subject. Introduced in CAPICOM 2.0. #define CAPICOM_CERT_INFO_ISSUER_DNS_NAME 7 && Returns the DNS name of the issuer of the certificate. Introduced in CAPICOM 2.0. LOCAL loPom loCert=.NULL. loStore=CREATEOBJECT('CAPICOM.Store') loStore.Open(CAPICOM_CURRENT_USER_STORE, "My", CAPICOM_STORE_OPEN_READ_ONLY) FOR EACH loPom IN loStore.Certificates IF (loPom.IsValid.Result) AND ; (UPPER(loPom.GetInfo(CAPICOM_CERT_INFO_SUBJECT_EMAIL_NAME)) $ UPPER(loSecMsg.From)) AND ; (loPom.KeyUsage.IsDigitalSignatureEnabled) loCert=loPom EXIT ENDIF ENDFOR IF !ISNULL(loCert) *!* Add cert to signer object loSigner.Certificate = loCert *!* Add signing time attribute to signer object loAttr.Name = CAPICOM_AUTHENTICATED_ATTRIBUTE_SIGNING_TIME loAttr.Value = DATE() loSigner.AuthenticatedAttributes.Add(loAttr) *!* Sign the content (root bodypart) lcContent = toMsg.BodyPart.GetStream.ReadText() * loSignedData.Content = STRCONV(lcContent, vbFromUnicode) loSignedData.Content = CREATEBINARY(lcContent) #define CAPICOM_ENCODE_BINARY 0 lcData = loSignedData.Sign(loSigner,.f., CAPICOM_ENCODE_BINARY) *!* Write the cms blob into the main bodypart *!* let CDO do the base64 encoding loStream = loSecMsg.BodyPart.GetDecodedContentStream() #define adTypeBinary 1 #define adTypeText 2 loStream.Type = adTypeBinary *!* Get the string data as a byte array loStream.Write(CREATEBINARY(lcData)) loStream.Flush *!* GoTo cleanup *!* Report error ELSE =MESSAGEBOX("No valid certificate found for sender.",16) ENDIF *!* Clean up memory loBodyPart = .NULL. loSignedData = .NULL. loStream = .NULL. loSigner = .NULL. loCert = .NULL. loAttr = .NULL. *!* Return new message RETURN loSecMsg