Attribute VB_Name = "basSMIMEex"
Option Explicit
' $Id: basSMIMEex $
' Reproduces examples from RFC 4134 "Examples of S/MIME Messages"
' Last Updated:
' $Date: 2006-08-10 06:57:00 $
' $Revision: 2.9.0 $
' Output is directed to the Immediate Window using oDebug.PPrint
' Errors are flagged with a MsgBox and then a Stop
' Requires these test files to exist in the same directory as the executable:
' 4.2.bin
' AlicePrivRSASign.pri
' AliceRSASignByCarl.cer
' BobPrivRSAEncrypt.pri
' BobRSASignByCarl.cer
' CarlPrivRSASign.pri
' CarlRSASelf.cer
' excontent.txt
' Functions further down depend on files being created by previous functions.
Private msTestDir As String
Public oDebug As New CDebug
Public Function smime_DoAll()
' Creates a new temp dir
' Copies test files to it from current directory
' Then does a series of tests based on "Examples of S/MIME Messages"
On Error GoTo OnError
Dim strTestDir As String
strTestDir = SetupTestDir()
oDebug.PPrint "Created new test folder '" & strTestDir & "'"
smime_Ex5_1_MakeEnvData
smime_Ex5_1b_MakeEnvDataFromString
SavePrivateKeys
smime_Ex5_1_ReadToFile
smime_Ex5_1_ReadToString
smime_Ex4_2_MakeSigData
smime_Ex4_2_MakeSigDataWithMD5
smime_MakeDetachedSig
smime_ReadSigData
smime_ReadSigDataIntoString
smime_GetSigDataDigest
smime_GetSigDataDigestMD5
sime_GetDigestFromDetSig
smime_FullSigDataDigestCheck
smime_FullSigDataDigestCheckMD5
Test_DecryptRaw
Test_X509_CertThumb
Test_X509_CertIsValidNow
Test_X509_VerifyCert
oDebug.PPrint ""
oDebug.PPrint "All done."
oDebug.PPrint "Files saved in temp folder " & strTestDir
ChDir ".."
Call PromptToKillFolder(strTestDir)
Done:
Exit Function
OnError:
Dim sErrMsg As String
sErrMsg = "Error " & Err.Number & " has occurred:" & vbCrLf & Err.Description
Select Case Err.Number
Case 75
sErrMsg = sErrMsg & vbCrLf & vbCrLf _
& "You do not have permission to create the test sub-folder here. Unzip the test files in a different directory."
Case 53
sErrMsg = sErrMsg & vbCrLf & vbCrLf _
& "A required test file is missing. Make sure the test files from smimetestfiles.zip are in the same folder as the executable"
End Select
MsgBox sErrMsg, vbCritical
Resume Done
End Function
Public Function SetupTestDir() As String
Dim strTestDir As String
Dim nRand As Long
Dim strSrcDir As String
Dim strDestDir As String
Randomize
nRand = CLng(Rnd() * 2 ^ 31)
' Create a new random test dir in the application folder
strTestDir = App.Path & "\pkitest." & Hex(nRand)
MkDir strTestDir
' Make this the current dir
ChDir strTestDir
' Set default path to empty
msTestDir = ""
' Copy files from app dir to test dir
CopyFileToTest "AliceRSASignByCarl.cer", App.Path, strTestDir
CopyFileToTest "AlicePrivRSASign.pri", App.Path, strTestDir
CopyFileToTest "BobRSASignByCarl.cer", App.Path, strTestDir
CopyFileToTest "BobPrivRSAEncrypt.pri", App.Path, strTestDir
CopyFileToTest "CarlRSASelf.cer", App.Path, strTestDir
CopyFileToTest "CarlPrivRSASign.pri", App.Path, strTestDir
CopyFileToTest "excontent.txt", App.Path, strTestDir
CopyFileToTest "4.2.bin", App.Path, strTestDir
' Write a text file as a memo
WriteFileFromString "!ThisFolderIsSafeToDelete.txt", _
"This folder was created as a test for the CryptoSys PKI Toolkit by the program '" _
& App.EXEName & "'. The folder and all files in it may be safely deleted at any time."
SetupTestDir = strTestDir
End Function
Public Function PromptToKillFolder(strFolder As String)
Dim sMsg As String
sMsg = "The directory '" & strFolder & "' has been created by this test program." _
& vbCrLf & vbCrLf & "Do you want to remove it now?"
If vbYes = MsgBox(sMsg, vbYesNo, "Remove test directory") Then
If apiKillDirectory(strFolder) Then
oDebug.PPrint "Temp folder has been deleted."
End If
End If
End Function
Public Function CopyFileToTest(strFileName As String, ByVal strSrcDir As String, ByVal strDestDir As String)
strSrcDir = Trim(strSrcDir)
If Right(strSrcDir, 1) = "\" Then
strSrcDir = Left(strSrcDir, Len(strSrcDir) - 1)
End If
strDestDir = Trim(strDestDir)
If Right(strDestDir, 1) = "\" Then
strDestDir = Left(strDestDir, Len(strDestDir) - 1)
End If
FileCopy strSrcDir & "\" & strFileName, strDestDir & "\" & strFileName
End Function
Public Function smime_Ex5_1_MakeEnvData()
' Reproduces example 5.1 - EnvelopedData from Alice to Bob
' of ExContent using TripleDES and RSA.
' NB output will always be different from smime-examples
' because the content-encryption key, encryption-IV
' and eContent will be different each time.
Dim lngRet As Long
Dim strOutputFile As String
Dim strInputFile As String
Dim strCertFile As String
strOutputFile = msTestDir & "cmsalice2bob.p7m"
strInputFile = msTestDir & "excontent.txt"
strCertFile = msTestDir & "BobRSASignByCarl.cer"
' This should return 1 (indicating one successful recipient)
lngRet = CMS_MakeEnvData(strOutputFile, strInputFile, strCertFile, "", 0, 0)
oDebug.PPrint "CMS_MakeEnvData returns " & lngRet & " (expected 1)"
If lngRet = 1 Then
oDebug.PPrint "Created file " & strOutputFile
Else
MsgBox pkiGetLastError(), vbCritical, "CMS_MakeEnvData"
Stop
End If
End Function
Public Function smime_Ex5_1b_MakeEnvDataFromString()
' Reproduces example 5.1 - EnvelopedData from Alice to Bob
' of ExContent using TripleDES and RSA.
Dim lngRet As Long
Dim strOutputFile As String
strOutputFile = msTestDir & "cmsalice2bob1.p7m"
' This should return 1 (indicating one successful recipient)
lngRet = CMS_MakeEnvDataFromString(strOutputFile, _
"This is some sample content.", msTestDir & "BobRSASignByCarl.cer", "", 0, 0)
oDebug.PPrint "CMS_MakeEnvDataFromString returns " & lngRet & " (expected 1)"
If lngRet = 1 Then
oDebug.PPrint "Created file " & strOutputFile
Else
MsgBox pkiGetLastError(), vbCritical, "CMS_MakeEnvDataFromString"
Stop
End If
End Function
' The private keys (*.pri) given with smime-examples are in
' unencrypted private-key-info format
' We want to save them encrypted with a password
' Use a generic function to do this
Public Function CopyPriKeyToEncFile(strEPKFile As String, strPRIFile As String, strPassword As String) As Boolean
Dim strPrivateKey As String
Dim strPK1 As String
Dim nKeyLen As String
Dim lngRet As Long
' Read in unencrypted PrivateKeyInfo data
nKeyLen = RSA_ReadPrivateKeyInfo("", 0, strPRIFile, 0)
If nKeyLen <= 0 Then
MsgBox pkiGetLastError(), vbCritical, "RSA_ReadPrivateKeyInfo"
Exit Function
End If
strPrivateKey = String(nKeyLen, " ")
lngRet = RSA_ReadPrivateKeyInfo(strPrivateKey, nKeyLen, strPRIFile, 0)
If lngRet <= 0 Then
MsgBox pkiGetLastError(), vbCritical, "RSA_ReadPrivateKeyInfo"
Exit Function
End If
' Now we save it with a password
lngRet = RSA_SaveEncPrivateKey(strEPKFile, strPrivateKey, 1000, strPassword, 0)
oDebug.PPrint "RSA_SaveEncPrivateKey returns " & lngRet
' Check we can read it
strPK1 = rsaReadPrivateKey(strEPKFile, strPassword)
oDebug.PPrint strPK1
oDebug.PPrint strPrivateKey
If strPK1 <> strPrivateKey Then
MsgBox "Private keys do not match!", vbCritical, "CopyPriKeyToEncFile"
Stop
Else
CopyPriKeyToEncFile = True
End If
End Function
Public Function SavePrivateKeys()
If CopyPriKeyToEncFile(msTestDir & "AlicePrivRSASign.epk", msTestDir & "AlicePrivRSASign.pri", "password") Then
oDebug.PPrint "Encrypted Alice's private key"
End If
If CopyPriKeyToEncFile(msTestDir & "BobPrivRSAEncrypt.epk", msTestDir & "BobPrivRSAEncrypt.pri", "password") Then
oDebug.PPrint "Encrypted Bob's private key"
End If
If CopyPriKeyToEncFile(msTestDir & "CarlPrivRSASign.epk", msTestDir & "CarlPrivRSASign.pri", "password") Then
oDebug.PPrint "Encrypted Carl's private key"
End If
End Function
Public Function smime_Ex5_1_ReadToFile()
' Bob reads the enveloped-data message sent by Alice
' Wrting output directly to a file
Dim lngRet As Long
Dim strFileIn As String
Dim strFileOut As String
Dim strPrivateKey As String
' Bob reads his private key into a string
strPrivateKey = rsaReadPrivateKey(msTestDir & "BobPrivRSAEncrypt.epk", "password")
If Len(strPrivateKey) = 0 Then
MsgBox "Cannot read private key", vbCritical
Stop
Exit Function
End If
' Decrypt the input file; send plaintext to new output file
strFileIn = msTestDir & "cmsalice2bob.p7m"
strFileOut = msTestDir & "fromalice.txt"
lngRet = CMS_ReadEnvData(strFileOut, strFileIn, "", strPrivateKey, 0)
oDebug.PPrint "CMS_ReadEnvData returns " & lngRet & " (expected 0)"
If lngRet = 0 Then
oDebug.PPrint "Created plaintext file " & strFileOut
Else
MsgBox pkiGetLastError(), vbCritical, "CMS_ReadEnvData"
Stop
End If
' Clean up
WIPE_String strPrivateKey, Len(strPrivateKey)
strPrivateKey = ""
End Function
Public Function smime_Ex5_1_ReadToString()
' Bob reads the enveloped-data message sent by Alice
' directly into a string
Dim lngRet As Long
Dim strPrivateKey As String
Dim strFileIn As String
Dim strDataOut As String
Dim nDataLen As Long
' First, Bob reads his private key into a string
strPrivateKey = rsaReadPrivateKey(msTestDir & "BobPrivRSAEncrypt.epk", "password")
If Len(strPrivateKey) = 0 Then
MsgBox "Cannot read private key", vbCritical
Stop
Exit Function
End If
' Decrypt the input file - how long is the plaintext?
strFileIn = msTestDir & "cmsalice2bob.p7m"
nDataLen = CMS_ReadEnvDataToString("", 0, strFileIn, "", strPrivateKey, 0)
oDebug.PPrint "CMS_ReadEnvDataToString returns " & nDataLen & " (expected > 0)"
If nDataLen <= 0 Then
GoTo CleanUp
End If
' Pre-dimension string and read in the plaintext
strDataOut = String(nDataLen, " ")
nDataLen = CMS_ReadEnvDataToString(strDataOut, nDataLen, strFileIn, "", strPrivateKey, 0)
oDebug.PPrint "CMS_ReadEnvDataToString returns " & nDataLen
If nDataLen > 0 Then
oDebug.PPrint "Plaintext is '" & strDataOut & "'"
Else
MsgBox pkiGetLastError(), vbCritical, "CMS_ReadEnvDataToString"
Stop
End If
CleanUp:
WIPE_String strPrivateKey, Len(strPrivateKey)
strPrivateKey = ""
End Function
Public Function smime_Ex4_2_MakeSigData()
' This example should reproduce exactly the signed-data
' file from Example 4.2
' The output should be identical to 4.2.bin
Dim strEPKFile As String
Dim strPrivateKey As String
Dim lngRet As Long
Dim strInputFile As String
Dim strOutputFile As String
Dim strCertFile As String
strEPKFile = msTestDir & "AlicePrivRSASign.epk"
strCertFile = msTestDir & "AliceRSASignByCarl.cer"
strInputFile = msTestDir & "excontent.txt"
strOutputFile = msTestDir & "BasicSignByAlice.bin"
' Alice reads in her private string (which we encrypted earlier)
strPrivateKey = rsaReadPrivateKey(strEPKFile, "password")
If Len(strPrivateKey) = 0 Then
MsgBox "Cannot read private key", vbCritical
Stop
Exit Function
End If
' Now we can sign our message
lngRet = CMS_MakeSigData(strOutputFile, strInputFile, strCertFile, strPrivateKey, 0)
oDebug.PPrint "CMS_MakeSigData returns " & lngRet & " (expected 0)"
If lngRet = 0 Then
oDebug.PPrint "Created signed-data file " & strOutputFile
Else
MsgBox pkiGetLastError(), vbCritical, "CMS_MakeSigData"
Stop
End If
End Function
Public Function smime_Ex4_2_MakeSigDataWithMD5()
' As above but using input directly from a string and using
' MD5 instead of SHA-1
Dim strEPKFile As String
Dim strPrivateKey As String
Dim lngKeyLen As Long
Dim lngRet As Long
Dim strInputFile As String
Dim strOutputFile As String
Dim strCertFile As String
strEPKFile = msTestDir & "AlicePrivRSASign.epk"
strCertFile = msTestDir & "AliceRSASignByCarl.cer"
strOutputFile = msTestDir & "BasicSignByAliceMD5.bin"
' Alice reads in her private string (which we encrypted earlier)
strPrivateKey = rsaReadPrivateKey(strEPKFile, "password")
If Len(strPrivateKey) = 0 Then
MsgBox "Cannot read private key", vbCritical
Stop
Exit Function
End If
' Now we can sign our message using MD5
lngRet = CMS_MakeSigDataFromString(strOutputFile, "This is some sample content.", _
strCertFile, strPrivateKey, PKI_HASH_MD5)
oDebug.PPrint "CMS_MakeSigDataFromString returns " & lngRet & " (expected 0)"
If lngRet = 0 Then
oDebug.PPrint "Created signed-data file " & strOutputFile
Else
MsgBox pkiGetLastError(), vbCritical, "CMS_MakeSigDataFromString"
Stop
End If
End Function
Public Function smime_MakeDetachedSig()
' Alice creates a detached signature starting with the message digest in hex format
Dim lngRet As Long
Dim strEPKFile As String
Dim strCertFile As String
Dim strOutFile As String
Dim strHexDigest As String
Dim strPrivateKey As String
strEPKFile = msTestDir & "AlicePrivRSASign.epk"
strCertFile = msTestDir & "AliceRSASignByCarl.cer"
strOutFile = msTestDir & "DetSignByAlice.bin"
strHexDigest = "406aec085279ba6e16022d9e0629c0229687dd48"
' First, Alice reads her private key into a string
strPrivateKey = rsaReadPrivateKey(strEPKFile, "password")
If Len(strPrivateKey) = 0 Then
MsgBox "Cannot read private key"
Stop
Exit Function
End If
' Alice makes a detached signature using
' the hash of the content and her private key
lngRet = CMS_MakeDetachedSig(strOutFile, strHexDigest, _
strCertFile, strPrivateKey, 0)
oDebug.PPrint "CMS_MakeDetachedSig returns " & lngRet & " (expected 0)"
If lngRet = 0 Then
oDebug.PPrint "Created detached signature file " & strOutFile
Else
MsgBox pkiGetLastError(), vbCritical, "CMS_MakeDetachedSig"
Stop
End If
End Function
Public Function smime_ReadSigData()
' Read Alice's signed-data, writing directly to a file
Dim lngRet As Long
Dim strFileIn As String
Dim strFileOut As String
strFileIn = msTestDir & "BasicSignByAlice.bin"
strFileOut = msTestDir & "BasicSignByAlice.dat"
lngRet = CMS_ReadSigData(strFileOut, strFileIn, 0)
oDebug.PPrint "CMS_ReadSigData returns " & lngRet & " (expected > 0)"
If lngRet > 0 Then
oDebug.PPrint lngRet & " bytes of signed data are in file " & strFileOut
Else
MsgBox pkiGetLastError(), vbCritical, "CMS_ReadSigData"
Stop
End If
End Function
Public Function smime_ReadSigDataIntoString()
' Extract signed data from original file, reading into a string
Dim strFileIn As String
Dim strData As String
Dim nDataLen As Long
strFileIn = msTestDir & "4.2.bin"
' How long is the content to be read?
nDataLen = CMS_ReadSigDataToString("", 0, strFileIn, 0)
oDebug.PPrint "CMS_ReadSigDataToString returns " & nDataLen & " (expected > 0)"
If nDataLen <= 0 Then
MsgBox pkiGetLastError(), vbCritical, "CMS_ReadSigDataToString"
Stop
Exit Function
End If
' Pre-dimension string to receive data then get it
strData = String(nDataLen, " ")
nDataLen = CMS_ReadSigDataToString(strData, nDataLen, strFileIn, 0)
If nDataLen > 0 Then
oDebug.PPrint "Signed data is [" & strData & "]"
Else
MsgBox pkiGetLastError(), vbCritical, "CMS_ReadSigDataToString"
Stop
End If
End Function
Public Function smime_GetSigDataDigest()
' Get the message digest from the original signed-data file
Dim strCMSFile As String
Dim strHexDigest As String
Dim nDigAlg As Long
strCMSFile = msTestDir & "4.2.bin"
strHexDigest = String(PKI_MAX_HASH_LEN, " ")
nDigAlg = CMS_GetSigDataDigest(strHexDigest, Len(strHexDigest), strCMSFile, "", 0)
' Should return zero for SHA-1 algorithm
oDebug.PPrint "CMS_GetSigDataDigest returns " & nDigAlg & " (expected 0)"
If nDigAlg = 0 Then
oDebug.PPrint "Digest is [" & strHexDigest & "]"
Else
MsgBox pkiGetLastError(), vbCritical, "CMS_GetSigDataDigest"
Stop
End If
End Function
Public Function smime_GetSigDataDigestMD5()
' As above but this time its an MD5 digest
Dim strCMSFile As String
Dim strHexDigest As String
Dim nDigAlg As Long
strCMSFile = msTestDir & "BasicSignByAliceMD5.bin"
strHexDigest = String(PKI_MAX_HASH_LEN, " ")
nDigAlg = CMS_GetSigDataDigest(strHexDigest, Len(strHexDigest), strCMSFile, "", 0)
oDebug.PPrint "CMS_GetSigDataDigest returns " & nDigAlg & " (expected 1)"
If nDigAlg = 1 Then
oDebug.PPrint "Digest is [" & strHexDigest & "]"
Else
MsgBox pkiGetLastError(), vbCritical, "CMS_GetSigDataDigest"
Stop
End If
End Function
Public Function sime_GetDigestFromDetSig()
' Get the digest value from the detached signature
Dim nDigAlg As Long
Dim strCMSFile As String
Dim strHexDigest As String
strCMSFile = msTestDir & "DetSignByAlice.bin"
strHexDigest = String(PKI_MAX_HASH_LEN, " ")
nDigAlg = CMS_GetSigDataDigest(strHexDigest, Len(strHexDigest), strCMSFile, "", 0)
oDebug.PPrint "CMS_GetSigDataDigest returns " & nDigAlg
If nDigAlg >= 0 Then
oDebug.PPrint "Extracted digest is"
oDebug.PPrint "[" & strHexDigest & "]"
Else
MsgBox pkiGetLastError(), vbCritical, "CMS_GetSigDataDigest"
Stop
End If
End Function
Public Function smime_FullSigDataDigestCheck()
' Do a full check on the original signed-data object
Dim strCMSFile As String
Dim strHexDigest As String
Dim nDigAlg As Long
Dim strData As String
Dim nDataLen As Long
Dim strContentDigest As String
Dim nHashLen As Long
strCMSFile = msTestDir & "4.2.bin"
' Get the digest value
strHexDigest = String(PKI_MAX_HASH_LEN, " ")
nDigAlg = CMS_GetSigDataDigest(strHexDigest, Len(strHexDigest), strCMSFile, "", 0)
oDebug.PPrint "CMS_GetSigDataDigest returns " & nDigAlg
If nDigAlg < 0 Then
MsgBox pkiGetLastError(), vbCritical, "CMS_GetSigDataDigest"
Stop
Exit Function
End If
oDebug.PPrint "Extracted digest is"
oDebug.PPrint "[" & strHexDigest & "]"
' Go get the content - in this case it's in the signed-data object
nDataLen = CMS_ReadSigDataToString("", 0, strCMSFile, 0)
If nDataLen <= 0 Then
MsgBox pkiGetLastError(), vbCritical, "CMS_ReadSigDataToString"
Stop
Exit Function
End If
strData = String(nDataLen, " ")
nDataLen = CMS_ReadSigDataToString(strData, nDataLen, strCMSFile, 0)
oDebug.PPrint "CMS_ReadSigDataToString returns " & nDataLen
oDebug.PPrint "Data is [" & strData & "]"
' Compute independently the hash of what we found
strContentDigest = String(PKI_MAX_HASH_LEN, " ")
' (Note how we use the digest algorithm code returned above)
nHashLen = HASH_HexFromString(strContentDigest, Len(strContentDigest), strData, nDataLen, nDigAlg)
oDebug.PPrint "Computed hash of content is"
oDebug.PPrint "[" & strContentDigest & "]"
' Can we match this hash digest with what we extracted from the signed-data?
strContentDigest = Left(strContentDigest, nHashLen)
strHexDigest = Left(strHexDigest, nHashLen)
If strContentDigest = strHexDigest Then
oDebug.PPrint "SUCCESS - digests match!"
Else
oDebug.PPrint "FAILS! - no match"
MsgBox "Digests are not equal", vbCritical
Stop
End If
End Function
Public Function smime_FullSigDataDigestCheckMD5()
' Ditto using signed-data file with MD5 digest
Dim strCMSFile As String
Dim strHexDigest As String
Dim nDigAlg As Long
Dim strData As String
Dim nDataLen As Long
Dim strContentDigest As String
Dim nHashLen As Long
strCMSFile = msTestDir & "BasicSignByAliceMD5.bin"
' Get the digest value
strHexDigest = String(PKI_MAX_HASH_LEN, " ")
nDigAlg = CMS_GetSigDataDigest(strHexDigest, Len(strHexDigest), strCMSFile, "", 0)
oDebug.PPrint "CMS_GetSigDataDigest returns " & nDigAlg
If nDigAlg < 0 Then
MsgBox pkiGetLastError(), vbCritical, "CMS_GetSigDataDigest"
Stop
Exit Function
End If
oDebug.PPrint "Extracted digest is"
oDebug.PPrint "[" & strHexDigest & "]"
' Go get the content - in this case it's in the signed-data object
nDataLen = CMS_ReadSigDataToString("", 0, strCMSFile, 0)
If nDataLen <= 0 Then
MsgBox pkiGetLastError(), vbCritical, "CMS_ReadSigDataToString"
Stop
Exit Function
End If
strData = String(nDataLen, " ")
nDataLen = CMS_ReadSigDataToString(strData, nDataLen, strCMSFile, 0)
oDebug.PPrint "CMS_ReadSigDataToString returns " & nDataLen
oDebug.PPrint "Data is [" & strData & "]"
' Compute independently the hash of what we found
strContentDigest = String(PKI_MAX_HASH_LEN, " ")
' (Note how we use the digest algorithm code returned above)
nHashLen = HASH_HexFromString(strContentDigest, Len(strContentDigest), strData, nDataLen, nDigAlg)
oDebug.PPrint "Computed hash of content is"
oDebug.PPrint "[" & strContentDigest & "]"
' Can we match this hash digest with what we extracted from the signed-data?
strContentDigest = Left(strContentDigest, nHashLen)
strHexDigest = Left(strHexDigest, nHashLen)
If strContentDigest = strHexDigest Then
oDebug.PPrint "SUCCESS - digests match!"
Else
oDebug.PPrint "FAILS! - no match"
MsgBox "Digests are not equal", vbCritical
Stop
End If
End Function
Public Function Test_DecryptRaw()
' This is from Example 4.2 of smime-examples-12
Dim sEncDataHex As String
Dim abData() As Byte
Dim nDataLen As Long
Dim strCertFile As String
Dim nKeyLen As Long
Dim strPublicKey As String
Dim lngRet As Long
' Cut and paste from DUMPASN1 output
sEncDataHex = "2F 23 82 D2 F3 09 5F B8 0C 58 EB 4E" & _
"9D BF 89 9A 81 E5 75 C4 91 3D D3 D0" & _
"D5 7B B6 D5 FE 94 A1 8A AC E3 C4 84" & _
"F5 CD 60 4E 27 95 F6 CF 00 86 76 75" & _
"3F 2B F0 E7 D4 02 67 A7 F5 C7 8D 16" & _
"04 A5 B3 B5 E7 D9 32 F0 24 EF E7 20" & _
"44 D5 9F 07 C5 53 24 FA CE 01 1D 0F" & _
"17 13 A7 2A 95 9D 2B E4 03 95 14 0B" & _
"E9 39 0D BA CE 6E 9C 9E 0C E8 98 E6" & _
"55 13 D4 68 6F D0 07 D7 A2 B1 62 4C" & _
"E3 8F AF FD E0 D5 5D C7"
' Convert to bytes
abData = cnvBytesFromHexStr(sEncDataHex)
' Check
oDebug.PPrint cnvHexStrFromBytes(abData)
strCertFile = msTestDir & "AliceRSASignByCarl.cer"
' Read in PublicKey as base64 string - pre-dimension first
nKeyLen = RSA_GetPublicKeyFromCert(vbNullString, 0, strCertFile, 0)
oDebug.PPrint "KeyLen = " & nKeyLen
If nKeyLen <= 0 Then
oDebug.PPrint pkiGetLastError()
MsgBox "Unable to retrieve private key"
Exit Function
End If
' Pre-dimension the string to receive data
strPublicKey = String(nKeyLen, " ")
' Read in the Key
nKeyLen = RSA_GetPublicKeyFromCert(strPublicKey, nKeyLen, strCertFile, 0)
oDebug.PPrint "PubKey= " & strPublicKey
' Verify using the public key
nDataLen = UBound(abData) + 1
oDebug.PPrint "Input: " & cnvHexStrFromBytes(abData)
lngRet = RSA_RawPublic(abData(0), nDataLen, strPublicKey, 0)
oDebug.PPrint "Output: " & cnvHexStrFromBytes(abData)
' Stripping the PKCS-1.5 header, we should get
' 3021300906052B0E03021A05000414406AEC085279BA6E16022D9E0629C0229687DD48
' which is a DigestInfo containing the 20-byte SHA-1 hash
' 406AEC085279BA6E16022D9E0629C0229687DD48
End Function
Public Function Test_X509_CertThumb()
Dim lngRet As Long
Dim strCertName As String
Dim strHexHash As String
' The Windows Certificate Manager gives the correct
' SHA-1 hash as 'B30C 4885 5055 C2E6 4CE3 1964 92D4 B838 31A6 B3CB'
strHexHash = String(40, " ")
strCertName = msTestDir & "AliceRSASignByCarl.cer"
lngRet = X509_CertThumb(strCertName, strHexHash, Len(strHexHash), 0)
oDebug.PPrint "X509_CertThumb returns " & lngRet & " for " & strCertName
oDebug.PPrint "Thumb =" & strHexHash
oDebug.PPrint "Correct=B30C48855055C2E64CE3196492D4B83831A6B3CB"
End Function
Public Function Test_X509_CertIsValidNow()
Dim lngRet As Long
Dim strCertName As String
strCertName = msTestDir & "AliceRSASignByCarl.cer"
lngRet = X509_CertIsValidNow(strCertName, 0)
oDebug.PPrint "X509_CertIsValidNow returns " & lngRet & " for " & strCertName
If lngRet = 0 Then
oDebug.PPrint "Certificate is still valid"
Else
oDebug.PPrint "Certificate has expired or is not yet valid"
End If
End Function
Public Function Test_X509_VerifyCert()
' Verify that Alice's certficate was signed by Carl
' Returns 0 if OK, -1 if fails to validate, or +ve if other error
Dim lngRet As Long
lngRet = X509_VerifyCert(msTestDir & "AliceRSASignByCarl.cer", msTestDir & "CarlRSASelf.cer", 0)
If lngRet = 0 Then
oDebug.PPrint "Verification is OK"
ElseIf lngRet > 0 Then
oDebug.PPrint "Error: " & lngRet & pkiGetLastError()
Else
oDebug.PPrint "Cert not issued by this Issuer"
End If
End Function