feat: Get-OffsetSignature (Authenticode provenance); strip long dashes - 3.3.0 - #21
Conversation
Reviewer's GuideImplements a new Windows-only Authenticode provenance feature centered around the public Get-OffsetSignature cmdlet and its OffsetInspect.SignatureInfo output type, wires it into the module manifest/exports, adds unit and end-to-end tests for signature shaping, bumps the module to v3.3.0, and updates README/CHANGELOG/docs to document the new command and normalize dash usage. Sequence diagram for Get-OffsetSignature Authenticode verification flowsequenceDiagram
actor User
participant Get_OffsetSignature
participant Test_OIIsWindows
participant Get_AuthenticodeSignature
participant ConvertTo_OISignatureInfo
User->>Get_OffsetSignature: Get-OffsetSignature FilePath
Get_OffsetSignature->>Test_OIIsWindows: Test-OIIsWindows
Test_OIIsWindows-->>Get_OffsetSignature: isWindows
alt [not Windows]
Get_OffsetSignature-->>User: throw "requires Windows"
else [Windows]
Get_OffsetSignature->>Get_OffsetSignature: Resolve-Path / Get-Item
Get_OffsetSignature->>Get_AuthenticodeSignature: Get-AuthenticodeSignature LiteralPath
Get_AuthenticodeSignature-->>Get_OffsetSignature: Signature
Get_OffsetSignature->>ConvertTo_OISignatureInfo: ConvertTo-OISignatureInfo Signature File FileSize
ConvertTo_OISignatureInfo-->>Get_OffsetSignature: SignatureInfo
Get_OffsetSignature-->>User: OffsetInspect.SignatureInfo
end
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Hey - I've found 1 issue
Prompt for AI Agents
Please address the comments from this code review:
## Individual Comments
### Comment 1
<location path="module/OffsetInspect/Private/Threat.Signature.ps1" line_range="25-36" />
<code_context>
+ [CmdletBinding()]
+ param([AllowNull()][string]$DistinguishedName)
+ if ([string]::IsNullOrWhiteSpace($DistinguishedName)) { return $null }
+ foreach ($part in $DistinguishedName -split ',') {
+ $trimmed = $part.Trim()
+ if ($trimmed -match '^CN=(.+)$') { return $Matches[1].Trim() }
</code_context>
<issue_to_address>
**suggestion:** Distinguished name parsing may break on escaped commas or differently formatted DNs.
Splitting on a plain comma will misparse DNs with escaped commas (e.g. `CN=Example\, Inc.,O=Example`). If those are possible, use `System.Security.Cryptography.X509Certificates.X500DistinguishedName` (`Decode` with appropriate `X500DistinguishedNameFlags`) to extract CN, or at least use a DN-aware parsing approach instead of a raw `-split ','`.
```suggestion
function Get-OICommonName {
# Pull the CN (common name) out of an X.500 subject/issuer for a readable label, falling
# back to the full distinguished name.
[CmdletBinding()]
param([AllowNull()][string]$DistinguishedName)
if ([string]::IsNullOrWhiteSpace($DistinguishedName)) { return $null }
# Prefer DN-aware parsing via X500DistinguishedName to handle escaped commas and formatting
try {
$dnObject = [System.Security.Cryptography.X509Certificates.X500DistinguishedName]::new($DistinguishedName)
$decoded = $dnObject.Decode(
[System.Security.Cryptography.X509Certificates.X500DistinguishedNameFlags]::UseNewLines
)
if (-not [string]::IsNullOrWhiteSpace($decoded)) {
foreach ($line in $decoded -split "`n") {
$trimmed = $line.Trim()
if ($trimmed -match '^CN=(.+)$') {
return $Matches[1].Trim()
}
}
}
}
catch {
# Fall through to the simple fallback below on invalid or unparsable DNs
}
# Fallback: if we couldn't parse via X500DistinguishedName, return the original DN trimmed
return $DistinguishedName.Trim()
}
```
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
| function Get-OICommonName { | ||
| # Pull the CN (common name) out of an X.500 subject/issuer for a readable label, falling | ||
| # back to the full distinguished name. | ||
| [CmdletBinding()] | ||
| param([AllowNull()][string]$DistinguishedName) | ||
| if ([string]::IsNullOrWhiteSpace($DistinguishedName)) { return $null } | ||
| foreach ($part in $DistinguishedName -split ',') { | ||
| $trimmed = $part.Trim() | ||
| if ($trimmed -match '^CN=(.+)$') { return $Matches[1].Trim() } | ||
| } | ||
| return $DistinguishedName.Trim() | ||
| } |
There was a problem hiding this comment.
suggestion: Distinguished name parsing may break on escaped commas or differently formatted DNs.
Splitting on a plain comma will misparse DNs with escaped commas (e.g. CN=Example\, Inc.,O=Example). If those are possible, use System.Security.Cryptography.X509Certificates.X500DistinguishedName (Decode with appropriate X500DistinguishedNameFlags) to extract CN, or at least use a DN-aware parsing approach instead of a raw -split ','.
| function Get-OICommonName { | |
| # Pull the CN (common name) out of an X.500 subject/issuer for a readable label, falling | |
| # back to the full distinguished name. | |
| [CmdletBinding()] | |
| param([AllowNull()][string]$DistinguishedName) | |
| if ([string]::IsNullOrWhiteSpace($DistinguishedName)) { return $null } | |
| foreach ($part in $DistinguishedName -split ',') { | |
| $trimmed = $part.Trim() | |
| if ($trimmed -match '^CN=(.+)$') { return $Matches[1].Trim() } | |
| } | |
| return $DistinguishedName.Trim() | |
| } | |
| function Get-OICommonName { | |
| # Pull the CN (common name) out of an X.500 subject/issuer for a readable label, falling | |
| # back to the full distinguished name. | |
| [CmdletBinding()] | |
| param([AllowNull()][string]$DistinguishedName) | |
| if ([string]::IsNullOrWhiteSpace($DistinguishedName)) { return $null } | |
| # Prefer DN-aware parsing via X500DistinguishedName to handle escaped commas and formatting | |
| try { | |
| $dnObject = [System.Security.Cryptography.X509Certificates.X500DistinguishedName]::new($DistinguishedName) | |
| $decoded = $dnObject.Decode( | |
| [System.Security.Cryptography.X509Certificates.X500DistinguishedNameFlags]::UseNewLines | |
| ) | |
| if (-not [string]::IsNullOrWhiteSpace($decoded)) { | |
| foreach ($line in $decoded -split "`n") { | |
| $trimmed = $line.Trim() | |
| if ($trimmed -match '^CN=(.+)$') { | |
| return $Matches[1].Trim() | |
| } | |
| } | |
| } | |
| } | |
| catch { | |
| # Fall through to the simple fallback below on invalid or unparsable DNs | |
| } | |
| # Fallback: if we couldn't parse via X500DistinguishedName, return the original DN trimmed | |
| return $DistinguishedName.Trim() | |
| } |
Summary by Sourcery
Add Authenticode provenance verification to OffsetInspect and release it as version 3.3.0.
New Features:
Enhancements:
Documentation:
Tests: