138 lines
5.3 KiB
PowerShell
138 lines
5.3 KiB
PowerShell
function Export-ACMCertificatesByName {
|
|
|
|
<#
|
|
.SYNOPSIS
|
|
Exports ACM certificates by domain name to the local filesystem.
|
|
|
|
.DESCRIPTION
|
|
Exports ACM certificates by domain name to the local filesystem. Unfortunately, AWS did not accomodate
|
|
this use case when they wrote 'Export-ACMCertificate'.
|
|
|
|
Note that this function may generate more than one set of files because domain name uniqueness is not enforced in ACM.
|
|
|
|
.PARAMETER DomainName
|
|
[string] The domain name of the ACM certificates to retrieve.
|
|
|
|
.PARAMETER ProfileName
|
|
[string] The AWS profile to use during ACM queries.
|
|
|
|
.PARAMETER Region
|
|
[string] The AWS region to use during ACM queries.
|
|
|
|
.PARAMETER Passphrase
|
|
[string] The passphrase to associate with the encrypted exported private key. If not provided, a generated passphrase will be used.
|
|
|
|
.PARAMETER GeneratePfx
|
|
[switch] Flag indicating whether or not the function should generate a PFX file. Note that this functionality requires OpenSSL
|
|
to be installed on your machine; if not installed, this flag will result in an error.
|
|
|
|
.EXAMPLE
|
|
Export-ACMCertificatesByName -DomainName '*.sandbox.alkami.net' -Passphrase "Secret" -ProfileName 'temp-prod' -Region 'us-east-1'
|
|
|
|
.EXAMPLE
|
|
Export-ACMCertificatesByName -DomainName '*.sandbox.alkami.net' -ProfileName 'temp-prod' -Region 'us-east-1' -GeneratePfx
|
|
|
|
.LINK
|
|
https://confluence.alkami.com/x/5ILiBg
|
|
#>
|
|
|
|
[CmdletBinding()]
|
|
[OutputType([PSObject[]])]
|
|
param (
|
|
[Parameter(Mandatory = $true)]
|
|
[ValidateNotNullOrEmpty()]
|
|
[string] $DomainName,
|
|
|
|
[Parameter(Mandatory = $true)]
|
|
[ValidateNotNullOrEmpty()]
|
|
[string] $ProfileName,
|
|
|
|
[Parameter(Mandatory = $true)]
|
|
[ValidateScript({$_ -in (Get-AWSRegion).region})]
|
|
[string] $Region,
|
|
|
|
[Parameter(Mandatory = $false)]
|
|
[ValidateNotNullOrEmpty()]
|
|
[string] $Passphrase,
|
|
|
|
[Parameter(Mandatory = $false)]
|
|
[switch] $GeneratePfx
|
|
)
|
|
|
|
$logLead = (Get-LogLeadName)
|
|
|
|
if ( $GeneratePfx ) {
|
|
|
|
# Either find OpenSSL or die trying.
|
|
$openSslPath = ( Get-Command -Name 'openssl' -CommandType Application -ErrorAction SilentlyContinue -TotalCount 1 ).Source
|
|
if ( $null -eq $openSslPath ) {
|
|
|
|
Write-Error "$logLead : GeneratePfx flag was provided but OpenSSL command was not found on your system. Please install OpenSSL and retry."
|
|
return
|
|
}
|
|
}
|
|
|
|
# Create the top-level temporary directory.
|
|
$tempDir = ( Join-Path ([System.IO.Path]::GetTempPath()) 'CertificateExport' )
|
|
New-Item -Path $tempDir -ItemType Directory -Force | Out-Null
|
|
|
|
# Sanitize the domain name (if necessary).
|
|
$pfxDomainName = $DomainName -replace '\*', '_'
|
|
|
|
$certificateDetailsList = Get-ACMCertificateDetailsListByName -DomainName $DomainName -ProfileName $ProfileName -Region $Region
|
|
foreach ( $cert in $certificateDetailsList ) {
|
|
|
|
Write-Host "$logLead : Processing certificate ARN [$($cert.CertificateArn)]."
|
|
|
|
if ( $false -eq $PSBoundParameters.ContainsKey( 'Passphrase' ) ) {
|
|
|
|
$actualPassphrase = New-SecurePassword -PasswordLength 15 -ProfileName $ProfileName -Region $Region
|
|
Write-Host "$logLead : Generated passphrase for certificate: $actualPassphrase"
|
|
|
|
} else {
|
|
|
|
$actualPassphrase = $Passphrase
|
|
}
|
|
|
|
try {
|
|
|
|
# Ref: https://docs.aws.amazon.com/powershell/latest/reference/items/Export-ACMCertificate.html
|
|
$exportedCert = ( Export-ACMCertificate -CertificateArn $cert.CertificateArn -Passphrase $actualPassphrase.ToCharArray() -ProfileName $ProfileName -Region $Region )
|
|
if ( $null -ne $exportedCert ) {
|
|
|
|
$certDirName = ( $cert.CertificateArn -split '/' )[-1]
|
|
$certDir = ( Join-Path $tempDir $certDirName )
|
|
$certPath = ( Join-Path $certDir "certificate.pem")
|
|
$chainPath = ( Join-Path $certDir "certificate_chain.pem")
|
|
$keyPath = ( Join-Path $certDir "private.key")
|
|
|
|
# Create the temporary directory for this certificate
|
|
New-Item -Path $certDir -ItemType Directory -Force | Out-Null
|
|
|
|
Set-Content -Path $certPath -Value $exportedCert.Certificate -Encoding ASCII
|
|
Write-Verbose "$logLead : Generated [$certPath]."
|
|
|
|
Set-Content -Path $chainPath -Value $exportedCert.CertificateChain -Encoding ASCII
|
|
Write-Verbose "$logLead : Generated [$chainPath]."
|
|
|
|
Set-Content -Path $keyPath -Value $exportedCert.PrivateKey -Encoding ASCII
|
|
Write-Verbose "$logLead : Generated [$keyPath]."
|
|
|
|
if ( $GeneratePfx ) {
|
|
|
|
$pfxPath = ( Join-Path $certDir "$pfxDomainName.pfx")
|
|
|
|
Start-Process -FilePath $openSslPath -Wait -argumentlist "pkcs12 -export -out $pfxPath -in $certPath -inkey $keyPath -certfile $chainPath -passin `"pass:$actualPassphrase`" -passout `"pass:$actualPassphrase`""
|
|
Write-Verbose "$logLead : Generated [$pfxPath]."
|
|
}
|
|
|
|
Write-Host "$logLead : Files generated at [$certDir]."
|
|
}
|
|
|
|
} catch {
|
|
|
|
Write-Warning "$logLead : Unable to export ACM certificate ARN [$($cert.CertificateArn)] : $($_.Exception.Message)"
|
|
}
|
|
}
|
|
}
|