Public/New-PWSHYBKPIVSelfSignedCertificate.ps1

function New-PWSHYBKPIVSelfSignedCertificate {
    <#
    .SYNOPSIS
        Creates a self-signed certificate from the key in a PIV slot of a locally attached
        YubiKey.
    .DESCRIPTION
        Wraps "yubico-piv-tool.exe --action selfsign-certificate". Does not change any state on
        the YubiKey itself (it only reads the existing key in the slot and signs a certificate;
        storing the result back onto the device is a separate Import-PWSHYBKPIVCertificate step),
        but can overwrite a local file when -Output is used, so it supports -WhatIf/-Confirm
        (ConfirmImpact 'Low', well below the slot-mutating cmdlets in this module).

        Accepts the "selfsign-certificate" action's config-declared options (-Slot, -Subject,
        -Hash, -ValidDays, -Output, -Pin, -Serial, -Reader) as dynamic parameters built from
        Config\Posh-YBKPIV.json.
    .PARAMETER Slot
        The PIV slot holding the key to self-sign a certificate for, e.g. '9a'.
    .PARAMETER Subject
        The certificate subject, e.g. '/CN=example.com/'.
    .PARAMETER Hash
        Hash algorithm to sign the certificate with: SHA1, SHA256, SHA384, or SHA512. Defaults to
        SHA256 when omitted.
    .PARAMETER ValidDays
        Number of days the certificate is valid for. Defaults to 365 when omitted.
    .PARAMETER Output
        Path to write the self-signed certificate to. Defaults to '-' (stdout) when omitted.
    .PARAMETER Pin
        The PIN authorizing the signing operation, as a SecureString.
    .PARAMETER Serial
        Certificate serial number to use. When omitted, yubico-piv-tool.exe generates one.
    .PARAMETER Reader
        Name of the smart card reader to target, when more than one is attached. If omitted,
        yubico-piv-tool.exe uses its own default reader selection.
    .INPUTS
        None. This cmdlet does not accept pipeline input.
    .OUTPUTS
        String[]. yubico-piv-tool.exe's raw output - the self-signed certificate, unless -Output
        redirects it to a file.
    .NOTES
        -Slot, -Subject, -Hash, -ValidDays, -Output, -Pin, -Serial, and -Reader are declared
        dynamically from Config\Posh-YBKPIV.json and therefore do not appear in Get-Help's
        PARAMETERS/SYNTAX sections. Run `Get-Command New-PWSHYBKPIVSelfSignedCertificate -Syntax`
        for the authoritative, current parameter list.
    .EXAMPLE
        New-PWSHYBKPIVSelfSignedCertificate -Slot '9a' -Subject '/CN=example.com/'
        Returns a self-signed certificate for the key in slot 9a.
    .LINK
        https://developers.yubico.com/yubico-piv-tool/Actions/
    .LINK
        New-PWSHYBKPIVCertificateRequest
    .LINK
        Import-PWSHYBKPIVCertificate
    #>

    [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'Low')]
    [OutputType([string[]])]
    param()

    DynamicParam {
        $dynamicConfig = Read-PWSHYBKPIVConfigFile
        Get-PWSHYBKPIVActionParameter -Action 'selfsign-certificate' -CmdletWrapping $dynamicConfig.cmdletWrapping
    }

    begin {
        $config = Read-PWSHYBKPIVConfigFile
        Write-PWSHYBKPIVLog -Config $config -Level Debug -CmdletName $MyInvocation.MyCommand.Name `
            -Message 'Cmdlet invoked' -BoundParameters $PSBoundParameters

        $architecture = Resolve-PWSHYBKPIVArchitecture -Architecture $config.installation.architecture
        $exePath = Get-PWSHYBKPIVInstallPath -Installation $config.installation -Architecture $architecture
        if (-not (Test-Path -Path $exePath -PathType Leaf)) {
            throw "yubico-piv-tool.exe was not found at '$exePath'. Run Install-PWSHYBKPIVTool first."
        }
    }

    end {
        if (-not $PSCmdlet.ShouldProcess("PIV slot $($PSBoundParameters['Slot'])", 'Create self-signed certificate')) {
            return
        }

        try {
            $result = Invoke-PWSHYBKPIVTool -ExePath $exePath -Action 'selfsign-certificate' `
                -CmdletWrapping $config.cmdletWrapping -BoundParameters $PSBoundParameters
            Write-PWSHYBKPIVLog -Config $config -Level Information -CmdletName $MyInvocation.MyCommand.Name `
                -Message 'Self-signed certificate created successfully'
            $result.Output
        } catch {
            Write-PWSHYBKPIVLog -Config $config -Level Error -CmdletName $MyInvocation.MyCommand.Name -Message "Failed: $_"
            throw
        }
    }
}