Sample code for 30+ languages & platforms
Visual FoxPro Requires Chilkat v11.7.0+

Authenticode Sign a Windows Installer Package (MSI)

See more Code Signing Examples

Demonstrates how to Authenticode sign a Windows Installer package (.msi). Signing MSI packages requires Chilkat v11.7.0 or later. The package is signed in place, and the certificate must have an RSA key: Windows does not accept the signature of an MSI that was signed with an ECDSA certificate.

Chilkat Visual FoxPro Downloads

Visual FoxPro
LOCAL lnSuccess
LOCAL loCert
LOCAL loJson
LOCAL lcMsiPath
LOCAL loSigner
LOCAL loSigInfo
LOCAL lnValid

lnSuccess = 0

*  This example requires the Chilkat API to have been previously unlocked.
*  See Global Unlock Sample for sample code.

*  Signing a Windows Installer package (.msi) requires Chilkat v11.7.0 or later.

*  Load the code signing certificate.  It must have access to its private key.
loCert = CreateObject('Chilkat.Cert')
lnSuccess = loCert.LoadPfxFile("C:/someDir/myCodeSigningCert.pfx","pfx password")
IF (lnSuccess = 0) THEN
    ? loCert.LastErrorText
    RELEASE loCert
    CANCEL
ENDIF

*  Use a certificate with an RSA key to sign an MSI.
*  Windows does not accept the signature of an MSI that was signed with an ECDSA certificate
*  (signtool verify and the Digital Signatures tab of the file's properties report it as invalid).
*  This is a limitation of signed MSI files on Windows.  It does not apply to EXE, DLL, PowerShell,
*  or VBScript files, which can be signed with either kind of certificate.
IF (loCert.IsRsa() = 0) THEN
    ? "Use an RSA code signing certificate to sign an MSI."
    RELEASE loCert
    CANCEL
ENDIF

*  Sign with SHA256, and ask a timestamp authority for a timestamp.  A timestamp lets the
*  signature continue to validate after the code signing certificate has expired.
*  
*  {
*    "hashAlg": "sha256",
*    "timestampToken": {
*      "enabled": true,
*      "tsaUrl": "http://timestamp.digicert.com",
*      "requestTsaCert": true,
*      "hashAlg": "sha256"
*    }
*  }
loJson = CreateObject('Chilkat.JsonObject')
loJson.UpdateString("hashAlg","sha256")
loJson.UpdateBool("timestampToken.enabled",1)
loJson.UpdateString("timestampToken.tsaUrl","http://timestamp.digicert.com")
loJson.UpdateBool("timestampToken.requestTsaCert",1)
loJson.UpdateString("timestampToken.hashAlg","sha256")

lcMsiPath = "C:/someDir/MyAppSetup.msi"

loSigner = CreateObject('Chilkat.CodeSign')

*  The .msi is modified in place.  The signature is stored in the package's digital signature stream.
*  If the package is already signed, the new signature replaces the existing one.
lnSuccess = loSigner.AddSignature(lcMsiPath,loCert,loJson)
IF (lnSuccess = 0) THEN
    ? loSigner.LastErrorText
    RELEASE loCert
    RELEASE loJson
    RELEASE loSigner
    CANCEL
ENDIF

? "Signed the MSI."

*  Verify the signature that was just added.
loSigInfo = CreateObject('Chilkat.JsonObject')
lnValid = loSigner.VerifySignature(lcMsiPath,loSigInfo)
IF (lnValid = 0) THEN
    ? loSigner.LastErrorText
    RELEASE loCert
    RELEASE loJson
    RELEASE loSigner
    RELEASE loSigInfo
    CANCEL
ENDIF

? "The signature is valid."

RELEASE loCert
RELEASE loJson
RELEASE loSigner
RELEASE loSigInfo