PSCertUtils.Java.psm1
# Installs an X509Certificate to all default java keystore certca files found on the system Function Install-X509CertificateToJavaTrustedCaKeystores { [CmdletBinding()] Param( [Parameter(Mandatory = $True, ValueFromPipelineByPropertyName=$True, Position = 0)] [ValidateNotNullOrEmpty()] [Alias("CertificateObject", "X509CertificateObject", "X509Certificate2")] [System.Security.Cryptography.X509Certificates.X509Certificate2] $X509Certificate, [Parameter(Mandatory = $False, ValueFromPipelineByPropertyName=$True, Position = 1)] [Alias("FriendlyName", "Name", "Alias", "CertificateAlias")] [String] $CertAlias, [Parameter(Mandatory = $True, Position = 3)] [ValidateNotNullOrEmpty()] [Alias("StorePassword", "StorePass", "Password", "Pass")] [String] $KeyStorePass = "changeit" ) BEGIN { # Gather all java keystores - this is only required once when running multiple times $JavaKeystores = Get-JavaCertStores } PROCESS { # Use the common name as alias if no alias has been given If ([String]::IsNullOrWhiteSpace($CertAlias)) { $CertAlias = Get-X509CommonNameFromSubject -X509Subject $X509Certificate.Subject } # Remove invalid characters from alias $CertAlias = Get-SafeCertificateAlias $CertAlias # Export certificate to temporary file $TempCertFile = Export-X509Certificate -X509Certificate $X509Certificate Try { # Import the certificate to all given java keystores $JavaKeyStores | Import-TrustedCaCertificateToJavaKeystore -CertAlias $CertAlias -CertFile $TempCertFile -KeyStorePass $KeyStorePass } Finally { # Remove the exported certificate after importing to all stores Remove-Item $TempCertFile } } } # Check if certificate exists before adding it Function Import-TrustedCaCertificateToJavaKeystore { [CmdletBinding()] Param( [Parameter(Mandatory = $True, Position = 0)] [ValidateNotNullOrEmpty()] [Alias("File", "Certificate", "CertificateFile")] [String] $CertFile, [Parameter(Mandatory = $True, Position = 1)] [ValidateNotNullOrEmpty()] [Alias("FriendlyName", "Name", "Alias", "CertificateAlias")] [String] $CertAlias, [Parameter(Mandatory = $True, ValueFromPipelineByPropertyName=$True, Position = 2)] [ValidateNotNullOrEmpty()] [Alias("Store", "CertificateStore", "cacerts")] [String] $KeyStore, [Parameter(Mandatory = $True, ValueFromPipelineByPropertyName=$True, Position = 3)] [ValidateNotNullOrEmpty()] [Alias("StorePassword", "StorePass", "Password", "Pass")] [String] $KeyStorePass = "changeit", [Parameter(Mandatory = $True, ValueFromPipelineByPropertyName=$True, Position = 4)] [ValidateNotNullOrEmpty()] [Alias("JavaKeyTool", "Command")] [String] $KeyTool = "keytool" ) If (Test-CertificateExistsWithinJavaKeystore -CertAlias $CertAlias -KeyStore $KeyStore -KeyStorePass $KeyStorePass -KeyTool $KeyTool) { Write-Verbose ("Certificate with the alias {0} already exists in {1}." -f $CertAlias, $KeyStore) return } Add-TrustedCaCertificateToJavaKeystore -CertFile $CertFile -CertAlias $CertAlias -KeyStore $KeyStore -KeyStorePass $KeyStorePass -KeyTool $KeyTool } # Add certificate to java keystore Function Add-TrustedCaCertificateToJavaKeystore { [CmdletBinding()] Param( [Parameter(Mandatory = $True, Position = 0)] [ValidateNotNullOrEmpty()] [Alias("File", "Certificate", "CertificateFile")] [String] $CertFile, [Parameter(Mandatory = $True, Position = 1)] [ValidateNotNullOrEmpty()] [Alias("FriendlyName", "Name", "Alias", "CertificateAlias")] [String] $CertAlias, [Parameter(Mandatory = $True, Position = 2)] [ValidateNotNullOrEmpty()] [Alias("Store", "CertificateStore", "cacerts")] [String] $KeyStore, [Parameter(Mandatory = $True, Position = 3)] [ValidateNotNullOrEmpty()] [Alias("StorePassword", "StorePass", "Password", "Pass")] [String] $KeyStorePass, [Parameter(Mandatory = $True, Position = 4)] [ValidateNotNullOrEmpty()] [Alias("JavaKeyTool", "Command")] [String] $KeyTool ) $KeyToolCommand = Get-Command "$KeyTool" -ErrorAction Stop Try { $ExecutionResult = $(& $KeyToolCommand -import -noprompt -trustcacerts -keystore "$KeyStore" -alias "$CertAlias" -file "$CertFile" -storepass "$KeyStorePass") } Catch { Throw ("Encountered problems while trying to import trusted root certificate with alias: {0} to java certificate store {1} - Exception: {2}" -f $CertAlias, $KeyStore, $_.Exception.Message) } If ($LastExitCode -ne 0) { Write-Error ("Unable to import certificate with given alias: {0} to {1}. Keytool Output: `n{2}" -f $CertAlias, $KeyStore, $ExecutionResult) } } # Test if a certificate with the given alias exists in a java keystore Function Test-CertificateExistsWithinJavaKeystore { [CmdletBinding()] Param( [Parameter(Mandatory = $True, Position = 0)] [ValidateNotNullOrEmpty()] [Alias("FriendlyName", "Name", "Alias", "CertificateAlias")] [String] $CertAlias, [Parameter(Mandatory = $True, Position = 1)] [ValidateNotNullOrEmpty()] [Alias("Store", "CertificateStore", "cacerts")] [String] $KeyStore, [Parameter(Mandatory = $True, Position = 2)] [ValidateNotNullOrEmpty()] [Alias("StorePassword", "StorePass", "Password", "Pass")] [String] $KeyStorePass, [Parameter(Mandatory = $True, Position = 3)] [ValidateNotNullOrEmpty()] [Alias("JavaKeyTool", "Command")] [String] $KeyTool ) $KeyToolCommand = Get-Command "$KeyTool" -ErrorAction Stop Try { $ExecutionResult = $(& $KeyToolCommand -list -noprompt -keystore "$KeyStore" -alias "$CertAlias" -storepass "$KeyStorePass") } Catch { Throw ("Encountered problems while trying to check if given alias: {0} is already present in java certificate store {1} - Exception: {2}" -f $CertAlias, $KeyStore, $_.Exception.Message) } If ($LastExitCode -eq 0) { return $True } Write-Verbose ("Unable to find a certificate with given alias: {0} in {1}. Keytool Output: `n{2}" -f $CertAlias, $KeyStore, $ExecutionResult) return $False } # Returns a list of all java installations within windows default application paths Function Get-JavaHomes { $ValidRoots = @("C:/Program Files/Java", "C:/Program Files (x86)/Java") | Where-Object { Test-Path -Path "$_" -PathType Container } return Get-ChildItem -Path $ValidRoots -Directory | Where-Object { Test-Path -Path $(Join-Path -Path $_.FullName -ChildPath "bin/java.exe") -PathType Leaf } | Select-Object -ExpandProperty FullName } # Returns a list of cacert keystore files and keytool within a java home under windows Function Get-JavaHomeCertStoreLocations { [CmdletBinding()] Param( [Parameter(Mandatory = $True, ValueFromPipeline = $True, Position = 0)] [String] $JavaHome ) Process { # do not check if directory does not exist If (!(Test-Path -Path $JavaHome)) { return } # use keytool as executeable if no keytool.exe can be found within bin/keytool.exe of java home $KeyTool = $(Join-Path -Path $JavaHome -ChildPath "/bin/keytool.exe") If (!(Test-Path -Path $KeyTool -PathType Leaf)) { $KeyTool = "keytool" } # find existing cacerts files at different locations within java home $KeyStores = @("lib/security/cacerts", "jre/lib/security/cacerts") | Foreach-Object { Join-Path -Path $JavaHome -ChildPath $_ } | Where-Object { Test-Path -Path $_ -PathType Leaf } # return PSCustomObject with keystore and keytool locations $KeyStores | ForEach-Object { [PSCustomObject] @{ KeyStore = $_ KeyTool = $KeyTool }} } } # Returns a list of cacert keystore files and keytool within default windows application paths Function Get-JavaCertStores { Get-JavaHomes | Get-JavaHomeCertStoreLocations } |