Level Extreme platform
Subscription
Corporate profile
Products & Services
Support
Legal
Français
Digitall Sign in Message via CDO and CAPICOM
Message
From
16/11/2007 12:39:02
 
 
To
All
General information
Forum:
Visual FoxPro
Category:
COM/DCOM and OLE Automation
Title:
Digitall Sign in Message via CDO and CAPICOM
Miscellaneous
Thread ID:
01269458
Message ID:
01269458
Views:
182
Hello friends.

I'm using CDO (Microsoft Collaboration Data Objects) for sending
messages in my application. It works fine. Just now I need add
a digitall sign to the sended messages. I found some solution (with CAPICOM)
on Microsoft page:

http://support.microsoft.com/default.aspx?scid=kb;en-us;280391

There is only Visual Basic code. I tried to translate it to VFP with success.
I'm able run VFP code (signing the message), send the message, receive the message,
but I can't open recieved message in Microsoft Outlook (ver.2007).
Error message is something like this:

"... Security system of lower level didn't loacte name of your digitall ID ..."
(This is my own translation of Czech message text).

Could somebody help me. I will accept different solutions too.

Thank you and have a nice days.

Here is my VFP version of code from http://support.microsoft.com/default.aspx?scid=kb;en-us;280391 :
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
Reply
Map
View

Click here to load this message in the networking platform