all groups > dotnet security > august 2004 >
You're in the

dotnet security

group:

CryptoAPI vs CAPICOM


CryptoAPI vs CAPICOM Kim Madsen
8/30/2004 12:30:34 PM
dotnet security:
Hi,

Im signing a mail with a digital signature, using CAPICOM to get my
certificate and sign my data, that works fine.

My problem is that when I sign my data for the mail:

szSignature = oSignedData.Sign(oSigner, True, CAPICOM_ENCODE_BINARY)

the thirt party (TDC, CA in denmark) comes up with a prompt box to type in
password for the certificate. That is a problem because my code has to be
running on a server.

TDC says that I have to use: CryptSetKeyParam(hash,Password,)

Then I can sign my data without it prompt me for a password.

So my question is:

How do I sign my mail using CryptoAPI when I can not use CAPICOM ?

Best Regards

Kim

Private Function SignMessage(ByRef oMsg As CDO.Message, bClear As Boolean)
As Boolean
Dim oSignedMsg As New CDO.Message
Dim oBodyPart As CDO.IBodyPart
Dim cFields As ADODB.Fields
Dim oStream As ADODB.Stream
Dim oSignedData As New CAPICOM.SignedData
Dim oUtilities As New CAPICOM.Utilities
Dim oAttribute As New CAPICOM.Attribute
Dim oSignerCertificate As CAPICOM.Certificate
Dim cSignerCertificates As CAPICOM.Certificates
Dim oStore As New CAPICOM.Store
'Dim szSignature, byteSignature() As Byte

On Error GoTo ErrorHandler

' create the SignedData object we will use to create the PKCS7
Set oSignedData = New CAPICOM.SignedData

' create the new message
Set oSignedMsg = New CDO.Message

' select the signer certificate
oStore.Open CAPICOM_CURRENT_USER_STORE, "My",
CAPICOM_STORE_OPEN_READ_ONLY
Set cSignerCertificates =
oStore.Certificates.Find(CAPICOM_CERTIFICATE_FIND_EXTENDED_PROPERTY,
CERT_KEY_SPEC_PROP_ID).Find(CAPICOM_CERTIFICATE_FIND_APPLICATION_POLICY,
"Secure Email")

Select Case cSignerCertificates.Count
Case 0
MsgBox ("Error: No signing certificate can be found.")
Case 1
oSigner.Certificate = cSignerCertificates(1)
Case Else
Set cSignerCertificates = cSignerCertificates.Select("S/MIME
Certificates", "Please select a certificate to sign with.")
If (cSignerCertificates.Count = 0) Then
MsgBox ("Error: Certificate selection dialog was
cancelled.")
Exit Function
End If
oSigner.Certificate = cSignerCertificates(1)
End Select

' set the from field based off of the selected certificate
oSignedMsg.From =
oSigner.Certificate.GetInfo(CAPICOM_CERT_INFO_SUBJECT_EMAIL_NAME)


' set the signing time in UTC time
Set oAttribute = New CAPICOM.Attribute
oAttribute.Name = CAPICOM_AUTHENTICATED_ATTRIBUTE_SIGNING_TIME
oAttribute.Value = oUtilities.LocalTimeToUTCTime(Now)
oSigner.AuthenticatedAttributes.Add oAttribute

Select Case bClear
Case True
' this is to be a clear text signed message so we need to copy the
interesting
' parts (sender, recipient, and subject) into the new header
oSignedMsg.To = oMsg.To
oSignedMsg.CC = oMsg.CC
oSignedMsg.Subject = oMsg.Subject

Set oBodyPart = oSignedMsg.BodyPart.AddBodyPart
Set cFields = oBodyPart.Fields
cFields.Item(cdoContentType).Value =
oMsg.BodyPart.BodyParts(1).Fields.Item(cdoContentType).Value
cFields.Update

Set oStream = oBodyPart.GetDecodedContentStream
oStream.WriteText
oMsg.BodyPart.BodyParts(1).GetDecodedContentStream.ReadText
oStream.Flush

' set the content to be signed
oSignedData.Content =
StrConv(oSignedMsg.BodyPart.BodyParts(1).GetStream.ReadText, vbFromUnicode)

' sign the content
szSignature = oSignedData.Sign(oSigner, True, CAPICOM_ENCODE_BINARY)

' Get the string data as a byte array
byteSignature = szSignature

' Attach the signature and let CDO base64 encode it
Set oBodyPart = oSignedMsg.BodyPart.AddBodyPart
Set cFields = oBodyPart.Fields
oBodyPart.Fields.Item("urn:schemas:mailheader:content-type").Value =
"application/x-pkcs7-signature" & vbCrLf & "Name = ""smime.p7s"""

oBodyPart.Fields.Item("urn:schemas:mailheader:content-transfer-encoding").Va
lue = "base64"

oBodyPart.Fields.Item("urn:schemas:mailheader:content-disposition").Value =
"attachment;" & vbCrLf & "FileName=""smime.p7s"""
cFields.Update

Set oStream = oBodyPart.GetDecodedContentStream
oStream.Type = ADODB.StreamTypeEnum.adTypeBinary
oStream.Write (byteSignature)
oStream.Flush

' Set the messages content type, this needs to be done last to
ensure it is not changed when we add the BodyParts
oSignedMsg.Fields.Item("urn:schemas:mailheader:content-type").Value
= "multipart/signed;" & vbCrLf &
"protocol=""application/x-pkcs7-signature"";" & vbCrLf & "micalg=SHA1;"
oSignedMsg.Fields.Update

Case False
' this is to be a opaquely signed message so we need to copy the
entire message into our
' new encrypted message
oSignedMsg.DataSource.OpenObject oMsg, cdoIMessage

' Set up main bodypart
Set oBodyPart = oSignedMsg.BodyPart
oBodyPart.ContentMediaType = "application/pkcs7-mime;" & vbCrLf &
"smime-type=signed-data;" & vbCrLf & "name=""smime.p7m"""
oBodyPart.ContentTransferEncoding = "base64"
oBodyPart.Fields("urn:schemas:mailheader:content-disposition") =
"attachment;" & vbCrLf & "FileName=""smime.p7m"""
oBodyPart.Fields.Update

' set the from field based off of the selected certificate
oMsg.From =
oSigner.Certificate.GetInfo(CAPICOM_CERT_INFO_SUBJECT_EMAIL_NAME)

' set the content to be signed
oSignedData.Content = StrConv(oMsg.BodyPart.GetStream.ReadText,
vbFromUnicode)

' Sign the content
szSignature = oSignedData.Sign(oSigner, False,
CAPICOM_ENCODE_BINARY)

' Get the string data as a byte array
byteSignature = szSignature

' Attach the signature and let CDO base64 encode it
Set oStream = oBodyPart.GetDecodedContentStream
oStream.Type = ADODB.StreamTypeEnum.adTypeBinary
oStream.Write (byteSignature)
oStream.Flush
End Select


' Signing Was sucessfull
SignMessage = True
Set oMsg = oSignedMsg

GoTo CleanUp

ErrorHandler:
'If the user cancels, don't display error message
If Err.Number <> CAPICOM_E_CANCELLED Then
MsgBox "Error: " & Hex(Err.Number) & ": " & Err.Description
End If
Err.Clear

' An error occurred
SignMessage = False
Set oMsg = Nothing

CleanUp:
Set oSignedMsg = Nothing
Set oBodyPart = Nothing
Set cFields = Nothing
Set oStream = Nothing
Set oSignedData = Nothing
Set oUtilities = Nothing
Set oAttribute = Nothing
Set oSignerCertificate = Nothing
Set cSignerCertificates = Nothing
RE: CryptoAPI vs CAPICOM shawnfa NO[at]SPAM online.microsoft.com (
8/30/2004 8:54:38 PM
Hi Kim,

You might want to check out the microsoft.public.security.crypto newsgroup for this question. This newsgroup focuses on CLR security (So
the System.Security.Cryptography namespace).

-Shawn
http://blogs.msdn.com/shawnfa

--

This posting is provided "AS IS" with no warranties, and confers no rights.
Note: For the benefit of the community-at-large, all responses to this message are best directed to the newsgroup/thread from which they
originated.
--------------------
[quoted text, click to view]
Re: CryptoAPI vs CAPICOM news.microsof.com
8/31/2004 11:02:13 AM
Thank you I try that one instead.

Best Regards

Kim

[quoted text, click to view]
AddThis Social Bookmark Button