forked from OCram85/PSCredentialStore
#### 📖 Summary <!-- Provide a summary of your changes. Describe the why and not how. --> #### 📑 Test Plan > 💡 Select your test plan for the code changes. - [x] Tested via Drone.io pipeline - [ ] Custom test - [ ] No test plan ##### Details / Justification <!-- Add your test details or justification for missing tests here. --> #### 📚 Additional Notes <!-- A place for additional detail notes. --> Co-authored-by: OCram85 <marco.blessing@googlemail.com> Reviewed-on: OCram85/PSCredentialStore#62
147 lines
5.1 KiB
PowerShell
147 lines
5.1 KiB
PowerShell
function New-CSCertificate {
|
|
<#
|
|
.SYNOPSIS
|
|
Creates a new PFX certificate for the CredentialStore encryption.
|
|
|
|
.DESCRIPTION
|
|
Use this function to create a custom self signed certificate used by the PSCredentialStore module.
|
|
|
|
.PARAMETER CRTAttribute
|
|
Provide certificate related attributes provided by function New-CRTAttribute.
|
|
|
|
.PARAMETER KeyName
|
|
Provide a custom full path and name for the private key. The file extension has to be `*.key`.
|
|
|
|
.PARAMETER CertName
|
|
Provide a custom full path and name for the PFX certificate file. The file extension has to be `*.pfx`
|
|
|
|
.INPUTS
|
|
[PSCredentialStore.Certificate.Attribute]
|
|
|
|
.OUTPUTS
|
|
[None]
|
|
|
|
.EXAMPLE
|
|
New-CSCertificate -CRTAttribute $CRTAttribute -KeyName './myprivate.key' -CertName './mycert.pfx'
|
|
#>
|
|
|
|
[CmdletBinding(SupportsShouldProcess = $true)]
|
|
[Diagnostics.CodeAnalysis.SuppressMessageAttribute(
|
|
'PSAvoidUsingInvokeExpression',
|
|
'',
|
|
Justification = 'needed for openssl wrapping'
|
|
)]
|
|
[OutputType()]
|
|
param (
|
|
[Parameter(Mandatory = $true, ValueFromPipeline = $true)]
|
|
[ValidateNotNullOrEmpty()]
|
|
[PSTypeName('PSCredentialStore.Certificate.Attribute')]$CRTAttribute,
|
|
|
|
[Parameter(Mandatory = $false)]
|
|
[ValidateNotNullOrEmpty()]
|
|
[string]$KeyName = './private.key',
|
|
|
|
[Parameter(Mandatory = $false)]
|
|
[ValidateNotNullOrEmpty()]
|
|
[string]$CertName = './certificate.pfx'
|
|
)
|
|
|
|
begin {
|
|
$ModuleBase = Get-ModuleBase
|
|
if ($isLinux -or $isMacOS) {
|
|
try {
|
|
$openssl = Get-Command -Name 'openssl' -ErrorAction Stop
|
|
}
|
|
catch {
|
|
$_.Exception.Message | Write-Error
|
|
$ErrorParams = @{
|
|
Message = 'Can not find the openssl binary!'
|
|
ErrorAction = 'Stop'
|
|
Exception = [System.IO.FileNotFoundException]::new()
|
|
}
|
|
Write-Error @ErrorParams
|
|
}
|
|
}
|
|
elseif (
|
|
($PSVersionTable.PSEdition -eq 'Desktop' -and $PSVersionTable.PSVersion.Major -lt 6) -or
|
|
($IsWindows -eq $true)
|
|
) {
|
|
$openssl = Join-Path -Path $ModuleBase -ChildPath '/Vendor/libressl255/openssl.exe'
|
|
}
|
|
|
|
$Env:OPENSSL_CONF = Join-Path $ModuleBase -ChildPath '/openssl.conf'
|
|
}
|
|
|
|
process {
|
|
$SubjPattern = "/C={0}/ST={1}/L={2}/O={3}/OU={4}/CN={5}"
|
|
$SubjValues = @(
|
|
$CRTAttribute.Subject.Country,
|
|
$CRTAttribute.Subject.State,
|
|
$CRTAttribute.Subject.City,
|
|
$CRTAttribute.Subject.Organization,
|
|
$CRTAttribute.Subject.OrganizationalUnitName,
|
|
$CRTAttribute.Subject.CommonName
|
|
)
|
|
$Subj = $SubjPattern -f $SubjValues
|
|
|
|
$PEMCertName = $CertName -replace '.pfx', '.crt'
|
|
$ExpPattern = (
|
|
'& ''{0}'' req -x509 -sha256 -nodes -days {1} -newkey rsa:2048 -keyout {2} -out {3} -subj "{4}" *>$null'
|
|
)
|
|
$ExpValues = @(
|
|
$openssl,
|
|
$CRTAttribute.Days
|
|
$KeyName,
|
|
$PEMCertName,
|
|
$Subj
|
|
)
|
|
$PEMExp = $ExpPattern -f $ExpValues
|
|
|
|
Write-Verbose -Message ( 'Expr string is: {0}' -f $PEMExp)
|
|
|
|
# Edit the Error action for the openSLL command to make the redirect *>$null work.
|
|
# There is always a stderr and stdout stream!
|
|
$EAP = $ErrorActionPreference
|
|
$ErrorActionPreference = 'Continue'
|
|
Invoke-Expression -Command $PEMExp
|
|
$ErrorActionPreference = $EAP
|
|
|
|
# manually testing the openssl command results
|
|
|
|
if (! (Test-Path -Path $KeyName)) {
|
|
$ErrorParams = @{
|
|
Message = 'Could not create the private key ${0}' -f $KeyName
|
|
ErrorAction = 'Stop'
|
|
Exception = [System.UnauthorizedAccessException]::new()
|
|
}
|
|
Write-Error @ErrorParams
|
|
}
|
|
if (! (Test-Path -Path $PEMCertName)) {
|
|
$ErrorParams = @{
|
|
Message = 'Could not create the PEM certificate ${0}' -f $PEMCertName
|
|
ErrorAction = 'Stop'
|
|
Exception = [System.Exception]::new()
|
|
}
|
|
Write-Error @ErrorParams
|
|
}
|
|
|
|
$PfxPattern = '& ''{0}'' pkcs12 -export -out {1} -inkey {2} -in {3} -passout pass:'
|
|
$PfxValues = @(
|
|
$openssl,
|
|
$CertName,
|
|
$KeyName,
|
|
($CertName -replace '.pfx', '.crt')
|
|
)
|
|
$PfxExp = $PfxPattern -f $PfxValues
|
|
Write-Verbose -Message ( 'PfxExp string is: {0}' -f $PfxExp)
|
|
Invoke-Expression -Command $PfxExp
|
|
|
|
# Remove private key and crt file. Always ask user
|
|
Remove-Item -Path $KeyName
|
|
Remove-Item -Path ($CertName -replace '.pfx', '.crt')
|
|
}
|
|
end {
|
|
Remove-Item Env:\OPENSSL_CONF -Confirm:$False -Force -ErrorAction SilentlyContinue
|
|
}
|
|
}
|