functions/invoke-fscpssignbinaryfile.ps1
<# .SYNOPSIS Function to sign the files with digicert .DESCRIPTION Function to sign the files with digicert .PARAMETER SM_HOST Digicert host URL. Default value "https://clientauth.one.digicert.com" .PARAMETER SM_API_KEY The DigiCert API Key .PARAMETER SM_CLIENT_CERT_FILE The DigiCert certificate local path (p12) .PARAMETER SM_CLIENT_CERT_FILE_URL The DigiCert certificate URL (p12) .PARAMETER SM_CLIENT_CERT_PASSWORD The DigiCert certificate password .PARAMETER SM_CODE_SIGNING_CERT_SHA1_HASH The DigiCert certificate thumbprint(fingerprint) .PARAMETER FILE A file to sign .EXAMPLE PS C:\> Invoke-FSCPSSignBinaryFile -SM_API_KEY "$codeSignDigiCertAPISecretName" ` -SM_CLIENT_CERT_FILE_URL "$codeSignDigiCertUrlSecretName" ` -SM_CLIENT_CERT_PASSWORD $(ConvertTo-SecureString $codeSignDigiCertPasswordSecretName -AsPlainText -Force) ` -SM_CODE_SIGNING_CERT_SHA1_HASH "$codeSignDigiCertHashSecretName" ` -FILE "$filePath" This will sign the target file with the DigiCert certificate .NOTES Author: Oleksandr Nikolaiev (@onikolaiev) #> function Invoke-FSCPSSignBinaryFile { param ( [Parameter(HelpMessage = "The DigiCert host", Mandatory = $false)] [string] $SM_HOST = "https://clientauth.one.digicert.com", [Parameter(HelpMessage = "The DigiCert API Key", Mandatory = $true)] [string] $SM_API_KEY, [Parameter(HelpMessage = "The DigiCert certificate local path (p12)", Mandatory = $false)] [string] $SM_CLIENT_CERT_FILE = "c:\temp\digicert.p12", [Parameter(HelpMessage = "The DigiCert certificate URL (p12)", Mandatory = $false)] [string] $SM_CLIENT_CERT_FILE_URL, [Parameter(HelpMessage = "The DigiCert certificate password", Mandatory = $true)] [SecureString] $SM_CLIENT_CERT_PASSWORD, [Parameter(HelpMessage = "The DigiCert certificate thumbprint(fingerprint)", Mandatory = $true)] [string] $SM_CODE_SIGNING_CERT_SHA1_HASH, [Parameter(HelpMessage = "A file to sign", Mandatory = $true)] [string] $FILE ) begin{ $tempDirectory = "c:\temp" if (!(Test-Path -Path $tempDirectory)) { [System.IO.Directory]::CreateDirectory($tempDirectory) } $certLocation = "$tempDirectory\digicert.p12" if(-not (Test-Path $FILE )) { Write-Error "File $FILE is not found! Check the path." exit 1; } if(-not (Test-Path $SM_CLIENT_CERT_FILE )) { if(![string]::IsNullOrEmpty($SM_CLIENT_CERT_FILE_URL)) { $certLocation = Join-Path $tempDirectory "digiCert.p12" Invoke-WebRequest -Uri "$SM_CLIENT_CERT_FILE_URL" -OutFile $certLocation if(Test-Path $certLocation) { $SM_CLIENT_CERT_FILE = $certLocation } } if(-not (Test-Path $SM_CLIENT_CERT_FILE )) { Write-Error "Certificate $SM_CLIENT_CERT_FILE is not found! Check the path." exit 1; } } $currentLocation = Get-Location $signMessage = "" #set env variables $env:SM_CLIENT_CERT_FILE = $SM_CLIENT_CERT_FILE $env:SM_HOST = $SM_HOST $env:SM_API_KEY = $SM_API_KEY $BSTR = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($SM_CLIENT_CERT_PASSWORD) $UnsecurePassword = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR) $env:SM_CLIENT_CERT_PASSWORD = $UnsecurePassword Set-Location $tempDirectory if(-not (Test-Path -Path .\smtools-windows-x64.msi )) { Write-Output "===============smtools-windows-x64.msi================" $smtools = "smtools-windows-x64.msi" Write-Output "The '$smtools' not found. Downloading..." Invoke-WebRequest -Method Get https://one.digicert.com/signingmanager/api-ui/v1/releases/smtools-windows-x64.msi/download -Headers @{ "x-api-key" = "$($SM_API_KEY)"} -OutFile .\$smtools -Verbose Write-Output "Downloaded. Installing..." msiexec /i $smtools /quiet /qn /le smtools.log Get-Content smtools.log -ErrorAction SilentlyContinue Write-Output "Installed." Start-Sleep -Seconds 5 } Write-Output "Checking DigiCert location..." $smctlLocation = (Get-ChildItem "$Env:Programfiles\DigiCert" -Recurse | Where-Object { $_.BaseName -like "smctl" }) if(Test-Path $smctlLocation.FullName) { Write-Output "DigiCert directory found at: $($smctlLocation.Directory)" } else { Write-Error "DigiCert directory not found. Check the installation." exit 1 } $appCertKitPath = "${env:ProgramFiles(x86)}\Windows Kits\10\App Certification Kit" Set-PathVariable -Scope Process -RemovePath $appCertKitPath -ErrorAction SilentlyContinue Set-PathVariable -Scope Process -AddPath $appCertKitPath -ErrorAction SilentlyContinue & certutil.exe -csp "DigiCert Software Trust Manager KSP" -key -user & $($smctlLocation.FullName) windows certsync } process{ try { try { if($PSCmdlet.MyInvocation.BoundParameters["Verbose"].IsPresent){ Write-Output "===============Healthcheck================" & $($smctlLocation.FullName) healthcheck Write-Output "===============KeyPair list================" & $($smctlLocation.FullName) keypair ls } } catch { Write-Output "Healchcheck failed. please check it" } Write-Output "Set-Location of DigiCert" Set-Location $($smctlLocation.Directory) $signMessage = $(& $($smctlLocation.FullName) sign --fingerprint $SM_CODE_SIGNING_CERT_SHA1_HASH --input $FILE --verbose) Write-Output $($signMessage) if($signMessage.Contains("FAILED")){ Write-Output (Get-Content "$env:USERPROFILE\.signingmanager\logs\smctl.log" -ErrorAction SilentlyContinue) throw; } if($PSCmdlet.MyInvocation.BoundParameters["Verbose"].IsPresent){ & $($smctlLocation.FullName) sign verify --input $FILE } Write-Output "File '$($FILE)' was signed successful!" } catch { Write-Output "Something went wrong! Read the healthcheck." # & $smctlLocation.FullName healthcheck } } end{ Clear-Content $env:SM_HOST -Force -ErrorAction SilentlyContinue Clear-Content $env:SM_API_KEY -Force -ErrorAction SilentlyContinue Clear-Content $env:SM_CLIENT_CERT_PASSWORD -Force -ErrorAction SilentlyContinue Set-Location $currentLocation if((Test-Path $certLocation )) { Remove-Item $certLocation -Force -ErrorAction SilentlyContinue } } } |