[codex] Harden PKCS#7 and certificate detection#68
Conversation
PR Review: Harden PKCS#7 and certificate detectionOverall this is a solid improvement — replacing OID substring scanning with proper top-level ASN.1 structural validation eliminates a real class of false positives, and the bounded-read protection is the right call for a hot-path library. A few things worth addressing: Potential Issues1. All three On .NET 6+, 2. Duplicate
3. Redundant preprocessor condition #if NET5_0_OR_GREATER || NET8_0_OR_GREATER
4. Test isolation: shared mutable Several tests (e.g. Options: disable parallelism on this class with Minor Observations5. Real RSA 2048-bit key generation in unit tests Tests like 6. When What's Done Well
🤖 Generated with Claude Code |
PR Review: Harden PKCS#7 and Certificate DetectionOverall this is a solid, well-motivated change. Replacing raw OID-byte window scanning with proper top-level ASN.1 structure validation is the right approach for a security-adjacent library, and the test overhaul is a clear improvement. The following are observations across correctness, code quality, and tests. Correctness IssuesPKCS#12 version check allows non-standard versions
if (version < 3)
{
return false;
}RFC 7292 §4 states the PFX if (version != 3)
{
return false;
}
WriteLe32(header, 0x2C, 1); // total FAT sectors = 1
WriteLe32(header, 0x30, 2); // first directory sector = sector 2 → offset 1536
WriteLe32(header, 0x4C, 0); // DIFAT[0] (first FAT sector) = sector 0 → offset 512
...
fs.Position = 1024; // FAT written here → sector 1
fs.Write(fat, 0, fat.Length);
fs.Position = 2048; // directory written here → sector 3
fs.Write(dir, 0, dir.Length);With a 512-byte sector size, sector N begins at offset
If WriteLe32(header, 0x30, 3); // directory at sector 3 → offset 2048
WriteLe32(header, 0x4C, 1); // FAT at sector 1 → offset 1024Code Quality / Design NotesUnnecessary array copies in span overloads internal static bool TryMatchPkcs12(ReadOnlySpan<byte> src, out ContentTypeDetectionResult? result)
=> TryMatchPkcs12(new ReadOnlyMemory<byte>(src.ToArray()), out result);
if (pfx.HasData)
{
pfx.ReadEncodedValue();
}
return !pfx.HasData;This consumes at most one optional element after AuthSafe. PKCS#12
If any other test class in the suite ever modifies Tests: What's Good
Summary
The core detection logic change is well-reasoned and the test coverage is substantially better than what it replaces. Fixing the version check and verifying the OLE sector helper are the two items I'd want resolved before merging. |
PR Review: Harden PKCS#7 and certificate detectionOverall this is a solid, well-motivated PR. The move from OID substring scanning to proper top-level ASN.1 shape verification is the right architectural direction, and the regression coverage is comprehensive. A few items worth addressing before merge: Issues1. Allocation in In internal static bool TryMatchTopLevelContentInfo(ReadOnlySpan<byte> src, string expectedContentTypeOid)
=> TryMatchTopLevelContentInfo(new ReadOnlyMemory<byte>(src.ToArray()), expectedContentTypeOid);
Similarly in internal static bool TryMatchPkcs12(ReadOnlySpan<byte> src, out ContentTypeDetectionResult? result)
=> TryMatchPkcs12(new ReadOnlyMemory<byte>(src.ToArray()), out result);The 2. In the 3. if (pfx.HasData)
{
pfx.ReadEncodedValue();
}
return !pfx.HasData;This reads at most one extra TLV (the optional 4. Test:
5.
Minor / Non-blocking
SummaryThe core detection logic changes are sound and well-tested. The main ask before merge is addressing the unnecessary |
PR Review: Harden PKCS#7 and certificate detectionOverall this is a solid improvement. Replacing loose OID substring scans with proper A few issues worth discussing before merging: Bug: Encrypted PFX/P12 files will not be detected
if (!string.Equals(contentTypeOid, "1.2.840.113549.1.7.1", StringComparison.Ordinal))
return false;Password-protected (encrypted) The fix is to also accept if (!string.Equals(contentTypeOid, "1.2.840.113549.1.7.1", StringComparison.Ordinal) &&
!string.Equals(contentTypeOid, "1.2.840.113549.1.7.6", StringComparison.Ordinal))
{
return false;
}The test Performance: unnecessary heap copies in
|
| Severity | Issue |
|---|---|
| Bug | Encrypted PFX/P12 not detected (authSafe OID 1.2.840.113549.1.7.6 not accepted) |
| Medium | Span-to-memory shims allocate unnecessarily; worth documenting or fixing |
| Medium | #if NET8_0_OR_GREATER may silently skip critical new tests on older CI TFMs |
| Low | Cross-collection parallelism could cause flaky budget-sensitive tests |
| Nit | Strict trailing-data check in TryReadTopLevelContentInfo — add a comment |
| Nit | OLE helper comment/DIFAT value mismatch |
The structural hardening approach is correct and the budget-bounding logic is well-designed. The encrypted PFX case is the only change I'd flag as a blocker before merging.
PR Review: Harden PKCS#7 and Certificate DetectionOverall this is a solid, well-motivated change. Replacing brittle OID substring scanning with proper ASN.1 structural validation is the right approach for a hot-path detector, and the test coverage is comprehensive. A few points worth discussing: Design / Architecture
if (dataMemory.HasValue)
{
if (Signatures.TryMatchPkcs12(dataMemory.Value, ...)) ...
if (Signatures.TryMatchPkcs7SignedData(dataMemory.Value, ...)) ...
if (Signatures.TryMatchDerCertificate(dataMemory.Value, ...)) ...
}
else
{
if (Signatures.TryMatchPkcs12(data, ...)) ... // ToArray() inside
if (Signatures.TryMatchPkcs7SignedData(data, ...)) ...
if (Signatures.TryMatchDerCertificate(data, ...)) ...
}If a 4th crypto detector is added later, both arms need updating. A small helper that produces a Span-to-Memory bridge allocations — The span overloads in Correctness
Performance
Tests
Global mutable state — Minor / Cosmetic
SummaryThe core approach — replacing OID-scan heuristics with strict top-level ASN.1 envelope validation using |
What changed
.spcand.p7swhile keeping bounded certificate parsing on the analysis path.p7b/.spc/.p7sand.p12files, oversized.p7bbudget skips, and multiple malformed ASN.1 lookalikesWhy
TierBridge calls FileInspectorX on the service hot path, so the PKCS#7 bundle path needed to stay inside the existing read budget and to classify crypto containers precisely. This PR hardens the detector behavior around PKCS#7, PKCS#12, and DER certificates so we reduce both avoidable memory risk and ASN.1 false positives.
Validation
dotnet test FileInspectorX.Tests/FileInspectorX.Tests.csproj --nologo --filter "FullyQualifiedName~CryptoDetectionsTests"dotnet test FileInspectorX.Tests/FileInspectorX.Tests.csproj --nologo