Imported pfx certificate is not saved on disk

Viewed 37

I wrote a script in PowerShell to import a certificate on Windows Server 2016/2019. The script is added to an Azure DevOps pipeline and the agent is an Environment Agent running as NT AUTHORITY\SYSTEM. It first imports the certificate into the LocalMachine\My store and sets read permissions on the certificate right after that. It comes with quite weird behavior while running as a pipeline or executed manually. I'll write out the different kinds of behavior:

  1. Import certificate on a server (successful)
  2. Check the existence of the file on the physical disk (successful -> found in C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys)
  3. Set read permissions for account x (successful)

  1. Import certificate on a server (successful)
  2. Check the existence of the file on the physical disk (failed. File is not stored programdata\machinekeys, but in C:\ProgramData\Microsoft\Crypto\Keys)
  3. Set read permissions for account x (failed --> can't find the file on the proper location)

  1. Import certificate on a server (successful)
  2. Check the existence of the file on the physical disk (successful)
  3. Set read permissions for account x (failed --> can't find the file on the proper location. does not exist on the server )

There is no way to predict which one of the scenario's will occur while running the script. I monitored server and file behavior with ProcMon (SysInternal Suite) during the import and did see the file being created and saved in while in C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys during both successful and failed attempts.

Import PFX code:

$FilePath = 'e:\folder\certificate.pfx'
$password = 'iLoveChocolateyCookies'    
$cert = New-Object system.Security.Cryptography.X509Certificates.X509Certificate2($FilePath, $password, "PersistKeySet,MachineKeySet")
$store = New-object System.Security.Cryptography.X509Certificates.X509Store -argumentlist "My", "LocalMachine"
$store.Open([System.Security.Cryptography.X509Certificates.OpenFlags]::"ReadWrite")
$store.Add($cert)
$store.Close()

Physical disk location check code:

$checkCert = Get-ChildItem "Cert:\LocalMachine\My" | Where-Object { $_.thumbprint -eq '<insertThumbhere>' }
$rsaCertCheck = [System.Security.Cryptography.X509Certificates.RSACertificateExtensions]::GetRSAPrivateKey($checkCert)
$checkCertDirectory = (Get-ChildItem -Path 'C:\Programdata\Microsoft\Crypto' -Include $rsaCertCheck.Key.UniqueName -File -Recurse).DirectoryName
if ($checkCertDirectory -eq "C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys") { 
    Write-Host "Certificate found on physical disk."
} else {
    throw 'nope'
}

Import-PfxCertificate showed the same behaviour. That is why I decided to use the .Net approach after consulting StackOverflow and Google, but ended up with the same issues.

A helpful hand will be very much appreciated :)

0 Answers
Related