Files
natsdotnet/gaps/tls-security.md
2026-02-25 15:12:52 -05:00

30 KiB

TLS / Security — Gap Analysis

This file tracks what has and hasn't been ported from Go to .NET for the TLS / Security module. See stillmissing.md for the full LOC comparison across all modules.

LLM Instructions: How to Analyze This Category

Step 1: Read the Go Reference Files

Read each Go source file listed below. For every file:

  1. Extract all exported types (structs, interfaces, type aliases)
  2. Extract all exported methods on those types (receiver functions)
  3. Extract all exported standalone functions
  4. Note key constants, enums, and protocol states
  5. Note important unexported helpers that implement core logic (functions >20 lines)
  6. Pay attention to concurrency patterns (goroutines, mutexes, channels) — these map to different .NET patterns

Step 2: Read the .NET Implementation Files

Read all .cs files in the .NET directories listed below. For each Go symbol found in Step 1:

  1. Search for a matching type, method, or function in .NET
  2. If found, compare the behavior: does it handle the same edge cases? Same error paths?
  3. If partially implemented, note what's missing
  4. If not found, note it as MISSING

Step 3: Cross-Reference Tests

Compare Go test functions against .NET test methods:

  1. For each Go Test* function, check if a corresponding .NET [Fact] or [Theory] exists
  2. Note which test scenarios are covered and which are missing
  3. Check the parity DB (docs/test_parity.db) for existing mappings:
    sqlite3 docs/test_parity.db "SELECT go_test, dotnet_test, confidence FROM test_mappings tm JOIN go_tests gt ON tm.go_test_id=gt.rowid JOIN dotnet_tests dt ON tm.dotnet_test_id=dt.rowid WHERE gt.go_file LIKE '%PATTERN%'"
    

Step 4: Classify Each Item

Use these status values:

Status Meaning
PORTED Equivalent exists in .NET with matching behavior
PARTIAL .NET implementation exists but is incomplete (missing edge cases, error handling, or features)
MISSING No .NET equivalent found — needs to be ported
NOT_APPLICABLE Go-specific pattern that doesn't apply to .NET (build tags, platform-specific goroutine tricks, etc.)
DEFERRED Intentionally skipped for now (document why)

Step 5: Fill In the Gap Inventory

Add rows to the Gap Inventory table below. Group by Go source file. Include the Go file and line number so a porting LLM can jump directly to the reference implementation.

Key Porting Notes for TLS / Security

  • This category is at 12% LOC parity — one of the largest gaps.
  • OCSP stapling and peer validation are critical for mutual TLS deployments.
  • Cipher suite filtering allows operators to restrict which TLS ciphers are accepted.
  • PROXY protocol support enables running NATS behind HAProxy/nginx with real client IPs.
  • certstore provides OS certificate store access (Windows-specific parts may be NOT_APPLICABLE).
  • certidp implements certificate identity validation via OCSP responders.

Go Reference Files (Source)

  • golang/nats-server/server/ocsp.go — OCSP stapling configuration
  • golang/nats-server/server/ocsp_peer.go — OCSP peer certificate validation
  • golang/nats-server/server/ocsp_responsecache.go — OCSP response caching
  • golang/nats-server/server/ciphersuites.go — TLS cipher suite management and filtering
  • golang/nats-server/server/client_proxyproto.go — PROXY protocol v1/v2 support (HAProxy)
  • golang/nats-server/server/certidp/certidp.go — Certificate identity provider
  • golang/nats-server/server/certidp/messages.go — CertIDP message types
  • golang/nats-server/server/certidp/ocsp_responder.go — OCSP responder client
  • golang/nats-server/server/certstore/certstore.go — OS certificate store access
  • golang/nats-server/server/certstore/certstore_other.go — Non-Windows cert store
  • golang/nats-server/server/certstore/certstore_windows.go — Windows cert store
  • golang/nats-server/server/certstore/errors.go — Cert store errors

Go Reference Files (Tests)

  • golang/nats-server/test/ocsp_test.go (integration)
  • golang/nats-server/test/ocsp_peer_test.go (integration)
  • golang/nats-server/test/tls_test.go (integration)
  • golang/nats-server/server/certstore/certstore_windows_test.go
  • golang/nats-server/server/certidp/*_test.go

.NET Implementation Files (Source)

  • src/NATS.Server/Tls/TlsHelper.cs
  • src/NATS.Server/Tls/TlsCertificateProvider.cs
  • src/NATS.Server/Tls/TlsConnectionState.cs
  • src/NATS.Server/Tls/TlsConnectionWrapper.cs
  • src/NATS.Server/Tls/TlsRateLimiter.cs
  • src/NATS.Server/Tls/PeekableStream.cs
  • src/NATS.Server/Tls/OcspConfig.cs

.NET Implementation Files (Tests)

  • tests/NATS.Server.Tests/ (TLS-related test files in root)

Gap Inventory

ocsp.go — OCSP stapling configuration

Go Symbol Go File:Line Status .NET Equivalent Notes
OCSPMode (type) golang/nats-server/server/ocsp.go:46 PORTED src/NATS.Server/Tls/OcspConfig.cs:8 Mapped to OcspMode enum with matching values
OCSPModeAuto golang/nats-server/server/ocsp.go:49 PORTED src/NATS.Server/Tls/OcspConfig.cs:10 OcspMode.Auto = 0
OCSPModeAlways golang/nats-server/server/ocsp.go:52 PORTED src/NATS.Server/Tls/OcspConfig.cs:11 OcspMode.Always = 1
OCSPModeNever golang/nats-server/server/ocsp.go:55 PORTED src/NATS.Server/Tls/OcspConfig.cs:13 OcspMode.Never = 3
OCSPModeMust golang/nats-server/server/ocsp.go:60 PORTED src/NATS.Server/Tls/OcspConfig.cs:12 OcspMode.Must = 2
OCSPMonitor (struct) golang/nats-server/server/ocsp.go:65 MISSING No dedicated OCSP monitor struct; .NET delegates to SslStreamCertificateContext for stapling
OCSPMonitor.getNextRun golang/nats-server/server/ocsp.go:80 MISSING No periodic OCSP refresh loop
OCSPMonitor.getStatus golang/nats-server/server/ocsp.go:102 MISSING No cache/local/remote OCSP status retrieval
OCSPMonitor.getCacheStatus golang/nats-server/server/ocsp.go:119 MISSING No in-memory OCSP response caching
OCSPMonitor.getLocalStatus golang/nats-server/server/ocsp.go:125 MISSING No file-based OCSP status persistence
OCSPMonitor.getRemoteStatus golang/nats-server/server/ocsp.go:160 MISSING No manual OCSP responder HTTP callout; .NET relies on runtime OCSP
OCSPMonitor.run golang/nats-server/server/ocsp.go:272 MISSING No background goroutine for OCSP staple renewal
OCSPMonitor.stop golang/nats-server/server/ocsp.go:348 MISSING No explicit stop channel for OCSP monitor
Server.NewOCSPMonitor golang/nats-server/server/ocsp.go:357 PARTIAL src/NATS.Server/Tls/TlsHelper.cs:75 BuildCertificateContext delegates stapling to .NET runtime; missing per-kind config, VerifyConnection callbacks, shutdown-on-revoke
Server.setupOCSPStapleStoreDir golang/nats-server/server/ocsp.go:560 MISSING No OCSP store directory setup
tlsConfigKind (struct) golang/nats-server/server/ocsp.go:577 MISSING No per-listener TLS config kind abstraction
Server.configureOCSP golang/nats-server/server/ocsp.go:585 MISSING No multi-listener OCSP configuration loop
Server.enableOCSP golang/nats-server/server/ocsp.go:680 MISSING No server-level OCSP enablement orchestrator
Server.startOCSPMonitoring golang/nats-server/server/ocsp.go:717 MISSING No OCSP monitor goroutine dispatcher
Server.reloadOCSP golang/nats-server/server/ocsp.go:734 MISSING No OCSP hot-reload support
hasOCSPStatusRequest golang/nats-server/server/ocsp.go:804 MISSING No MustStaple TLS extension detection
OCSPMonitor.writeOCSPStatus golang/nats-server/server/ocsp.go:840 MISSING No atomic file write for OCSP status persistence
parseCertPEM golang/nats-server/server/ocsp.go:867 PARTIAL src/NATS.Server/Tls/TlsHelper.cs:17 LoadCaCertificates uses ImportFromPemFile but does not validate PEM block type
getOCSPIssuerLocally golang/nats-server/server/ocsp.go:892 MISSING No local issuer resolution from cert bundle
getOCSPIssuer golang/nats-server/server/ocsp.go:932 MISSING No issuer resolution logic
ocspStatusString golang/nats-server/server/ocsp.go:968 PORTED src/NATS.Server/Events/EventTypes.cs:647 OcspEventBuilder.ParseStatus and OcspStatus enum
validOCSPResponse golang/nats-server/server/ocsp.go:979 MISSING No manual OCSP response time validation

ocsp_peer.go — OCSP peer certificate validation

Go Symbol Go File:Line Status .NET Equivalent Notes
parseOCSPPeer golang/nats-server/server/ocsp_peer.go:29 MISSING No config-file parsing for OCSP peer options
peerFromVerifiedChains golang/nats-server/server/ocsp_peer.go:130 MISSING No peer extraction from verified chains
Server.plugTLSOCSPPeer golang/nats-server/server/ocsp_peer.go:138 PARTIAL src/NATS.Server/Tls/TlsHelper.cs:36 .NET uses X509RevocationMode.Online when OcspPeerVerify set; missing full OCSP peer plugin pattern with per-chain validation
Server.plugClientTLSOCSPPeer golang/nats-server/server/ocsp_peer.go:163 PARTIAL src/NATS.Server/Tls/TlsHelper.cs:41 RemoteCertificateValidationCallback with revocation check, but no OCSP-specific chain walking or event publishing
Server.plugServerTLSOCSPPeer golang/nats-server/server/ocsp_peer.go:183 MISSING No leaf-spoke server-side OCSP peer plug
Server.tlsServerOCSPValid golang/nats-server/server/ocsp_peer.go:209 MISSING No server-side verified-chain OCSP evaluation
Server.tlsClientOCSPValid golang/nats-server/server/ocsp_peer.go:220 MISSING No client-side verified-chain OCSP evaluation
Server.peerOCSPValid golang/nats-server/server/ocsp_peer.go:225 MISSING No multi-chain OCSP eligibility walker
Server.certOCSPGood golang/nats-server/server/ocsp_peer.go:286 MISSING No per-link OCSP response fetch, cache check, delegation validation, and policy overrides (WarnOnly, AllowWhenCAUnreachable)
sendOCSPPeerRejectEvent golang/nats-server/server/ocsp_peer.go (ref) PARTIAL src/NATS.Server/Events/EventTypes.cs:612 OcspEventBuilder.BuildPeerReject exists as data builder but no actual event publishing to system account
sendOCSPPeerChainlinkInvalidEvent golang/nats-server/server/ocsp_peer.go (ref) PARTIAL src/NATS.Server/Events/EventTypes.cs:628 OcspEventBuilder.BuildChainValidation exists as data builder but no actual event publishing

ocsp_responsecache.go — OCSP response caching

Go Symbol Go File:Line Status .NET Equivalent Notes
OCSPResponseCacheType (type) golang/nats-server/server/ocsp_responsecache.go:44 MISSING No cache type enum (NONE/LOCAL)
OCSPResponseCacheConfig golang/nats-server/server/ocsp_responsecache.go:56 MISSING No OCSP cache configuration struct
NewOCSPResponseCacheConfig golang/nats-server/server/ocsp_responsecache.go:63 MISSING No cache config factory
OCSPResponseCacheStats golang/nats-server/server/ocsp_responsecache.go:72 MISSING No cache statistics tracking
OCSPResponseCacheItem golang/nats-server/server/ocsp_responsecache.go:81 MISSING No cache item model
OCSPResponseCache (interface) golang/nats-server/server/ocsp_responsecache.go:89 MISSING No cache interface (Put/Get/Delete/Start/Stop)
NoOpCache (struct) golang/nats-server/server/ocsp_responsecache.go:102 MISSING No no-op cache implementation
LocalCache (struct) golang/nats-server/server/ocsp_responsecache.go:155 MISSING No local file-backed OCSP response cache
LocalCache.Put golang/nats-server/server/ocsp_responsecache.go:167 MISSING No cache insert with S2 compression
LocalCache.Get golang/nats-server/server/ocsp_responsecache.go:201 MISSING No cache lookup with decompression
LocalCache.Delete golang/nats-server/server/ocsp_responsecache.go:245 MISSING No cache delete with preserve-revoked policy
LocalCache.Start golang/nats-server/server/ocsp_responsecache.go:272 MISSING No cache initialization from disk
LocalCache.Stop golang/nats-server/server/ocsp_responsecache.go:281 MISSING No cache shutdown and save
LocalCache.Compress / Decompress golang/nats-server/server/ocsp_responsecache.go:344 MISSING No S2 compression for OCSP responses
LocalCache.loadCache / saveCache golang/nats-server/server/ocsp_responsecache.go:371 MISSING No JSON-based disk persistence
Server.initOCSPResponseCache golang/nats-server/server/ocsp_responsecache.go:508 MISSING No cache initialization on server startup
Server.startOCSPResponseCache golang/nats-server/server/ocsp_responsecache.go:546 MISSING No cache start on server startup
Server.stopOCSPResponseCache golang/nats-server/server/ocsp_responsecache.go:564 MISSING No cache stop on server shutdown
parseOCSPResponseCache golang/nats-server/server/ocsp_responsecache.go:574 MISSING No config-file parsing for OCSP cache options

ciphersuites.go — TLS cipher suite management and filtering

Go Symbol Go File:Line Status .NET Equivalent Notes
cipherMap (var) golang/nats-server/server/ciphersuites.go:32 MISSING No cipher name-to-suite mapping; .NET handles cipher suites via SslServerAuthenticationOptions
cipherMapByID (var) golang/nats-server/server/ciphersuites.go:33 MISSING No cipher ID-to-suite mapping
defaultCipherSuites golang/nats-server/server/ciphersuites.go:35 NOT_APPLICABLE .NET TLS stack manages default cipher suites internally; no explicit enumeration needed
curvePreferenceMap (var) golang/nats-server/server/ciphersuites.go:45 NOT_APPLICABLE .NET does not expose curve preference ordering at application level
defaultCurvePreferences golang/nats-server/server/ciphersuites.go:55 NOT_APPLICABLE .NET runtime handles curve negotiation; FIPS mode handled by OS/.NET runtime config
init() cipher registration golang/nats-server/server/ciphersuites.go:21 NOT_APPLICABLE Go-specific init pattern; .NET populates cipher lists differently

client_proxyproto.go — PROXY protocol v1/v2 support

Go Symbol Go File:Line Status .NET Equivalent Notes
proxyProtoV2 constants golang/nats-server/server/client_proxyproto.go:28 PORTED src/NATS.Server/Protocol/ProxyProtocol.cs:54 All v2 constants mirrored
proxyProtoV1 constants golang/nats-server/server/client_proxyproto.go:63 PORTED src/NATS.Server/Protocol/ProxyProtocol.cs:82 All v1 constants mirrored
proxyProtoAddr (struct) golang/nats-server/server/client_proxyproto.go:81 PORTED src/NATS.Server/Protocol/ProxyProtocol.cs:11 ProxyAddress class with SrcIp, SrcPort, DstIp, DstPort
proxyProtoAddr.String golang/nats-server/server/client_proxyproto.go:89 PORTED src/NATS.Server/Protocol/ProxyProtocol.cs:20 ProxyAddress.ToString() with IPv6 bracket formatting
proxyProtoAddr.Network golang/nats-server/server/client_proxyproto.go:94 PORTED src/NATS.Server/Protocol/ProxyProtocol.cs:18 ProxyAddress.Network property
proxyConn (struct) golang/nats-server/server/client_proxyproto.go:102 MISSING No connection wrapper; .NET parser is pure buffer-based, integration with accept loop not yet wired
proxyConn.RemoteAddr golang/nats-server/server/client_proxyproto.go:109 MISSING Part of proxyConn; accept loop integration needed
detectProxyProtoVersion golang/nats-server/server/client_proxyproto.go:116 PORTED src/NATS.Server/Protocol/ProxyProtocol.cs:91 ProxyProtocolParser.Parse auto-detects v1/v2 from first 6 bytes
readProxyProtoV1Header golang/nats-server/server/client_proxyproto.go:134 PORTED src/NATS.Server/Protocol/ProxyProtocol.cs:117 ProxyProtocolParser.ParseV1 — buffer-based, all edge cases handled
readProxyProtoHeader golang/nats-server/server/client_proxyproto.go:226 PORTED src/NATS.Server/Protocol/ProxyProtocol.cs:91 ProxyProtocolParser.Parse covers both versions
readProxyProtoV2Header golang/nats-server/server/client_proxyproto.go:274 PORTED src/NATS.Server/Protocol/ProxyProtocol.cs:190 ProxyProtocolParser.ParseV2
parseProxyProtoV2Header golang/nats-server/server/client_proxyproto.go:301 PORTED src/NATS.Server/Protocol/ProxyProtocol.cs:208 ProxyProtocolParser.ParseV2AfterSig
parseIPv4Addr golang/nats-server/server/client_proxyproto.go:365 PORTED src/NATS.Server/Protocol/ProxyProtocol.cs:250 ParseIPv4 private method
parseIPv6Addr golang/nats-server/server/client_proxyproto.go:383 PORTED src/NATS.Server/Protocol/ProxyProtocol.cs:269 ParseIPv6 private method
error variables golang/nats-server/server/client_proxyproto.go:73 PORTED src/NATS.Server/Protocol/ProxyProtocol.cs:353 ProxyProtocolException and ProxyProtocolUnsupportedException

certidp/certidp.go — Certificate identity provider

Go Symbol Go File:Line Status .NET Equivalent Notes
DefaultAllowedClockSkew golang/nats-server/server/certidp/certidp.go:30 MISSING No OCSP clock skew constant
DefaultOCSPResponderTimeout golang/nats-server/server/certidp/certidp.go:31 MISSING No OCSP responder timeout constant
DefaultTTLUnsetNextUpdate golang/nats-server/server/certidp/certidp.go:32 MISSING No default TTL when NextUpdate is unset
StatusAssertion (type) golang/nats-server/server/certidp/certidp.go:35 PARTIAL src/NATS.Server/Events/EventTypes.cs:595 OcspStatus enum exists (Good, Revoked, Unknown) but no JSON marshal/unmarshal or bidirectional maps
GetStatusAssertionStr golang/nats-server/server/certidp/certidp.go:56 PORTED src/NATS.Server/Events/EventTypes.cs:647 OcspEventBuilder.ParseStatus provides string-to-enum; reverse mapping implicit
ChainLink (struct) golang/nats-server/server/certidp/certidp.go:93 MISSING No chain link struct with Leaf/Issuer/OCSPWebEndpoints
OCSPPeerConfig (struct) golang/nats-server/server/certidp/certidp.go:100 MISSING No OCSP peer config struct (Verify, Timeout, ClockSkew, WarnOnly, UnknownIsGood, AllowWhenCAUnreachable, TTLUnsetNextUpdate)
NewOCSPPeerConfig golang/nats-server/server/certidp/certidp.go:110 MISSING No peer config factory
Log (struct) golang/nats-server/server/certidp/certidp.go:123 NOT_APPLICABLE .NET uses ILogger injection; no need for function-pointer log struct
CertInfo (struct) golang/nats-server/server/certidp/certidp.go:131 MISSING No cert info DTO for events
GenerateFingerprint golang/nats-server/server/certidp/certidp.go:179 PARTIAL src/NATS.Server/Tls/TlsHelper.cs:88 GetCertificateHash uses SHA256 on SPKI (not raw cert as Go does); different hash input
getWebEndpoints golang/nats-server/server/certidp/certidp.go:184 MISSING No OCSP endpoint URL extraction/filtering
GetSubjectDNForm golang/nats-server/server/certidp/certidp.go:203 MISSING No subject RDN sequence formatting
GetIssuerDNForm golang/nats-server/server/certidp/certidp.go:212 MISSING No issuer RDN sequence formatting
CertOCSPEligible golang/nats-server/server/certidp/certidp.go:221 MISSING No OCSP eligibility check based on AIA extension
GetLeafIssuerCert golang/nats-server/server/certidp/certidp.go:237 MISSING No positional issuer extraction from chain
OCSPResponseCurrent golang/nats-server/server/certidp/certidp.go:250 MISSING No OCSP response currency check with clock skew and TTL fallback
ValidDelegationCheck golang/nats-server/server/certidp/certidp.go:288 MISSING No OCSP response delegation validation per RFC 6960 section 4.2.2.2

certidp/messages.go — CertIDP message types

Go Symbol Go File:Line Status .NET Equivalent Notes
Error message constants golang/nats-server/server/certidp/messages.go:17 MISSING No equivalent error/debug message constants; .NET uses structured logging
Debug message constants golang/nats-server/server/certidp/messages.go:47 MISSING Debug format strings not ported; .NET logs differently
MsgTLSClientRejectConnection golang/nats-server/server/certidp/messages.go:81 PARTIAL src/NATS.Server/Events/EventTypes.cs:520 Reject event type exists but literal reject reason string not exposed
MsgTLSServerRejectConnection golang/nats-server/server/certidp/messages.go:82 PARTIAL src/NATS.Server/Events/EventTypes.cs:520 Same as above
MsgCacheOnline / MsgCacheOffline golang/nats-server/server/certidp/messages.go:96 MISSING No cache status notification messages

certidp/ocsp_responder.go — OCSP responder client

Go Symbol Go File:Line Status .NET Equivalent Notes
FetchOCSPResponse golang/nats-server/server/certidp/ocsp_responder.go:29 MISSING No HTTP-based OCSP response fetcher (GET with base64 encoding); .NET relies on X509Chain revocation
encodeOCSPRequest golang/nats-server/server/certidp/ocsp_responder.go:89 MISSING No DER-to-base64-to-URL encoding for OCSP requests

certstore/certstore.go — OS certificate store access

Go Symbol Go File:Line Status .NET Equivalent Notes
StoreType (type) golang/nats-server/server/certstore/certstore.go:24 NOT_APPLICABLE .NET has native X509Store; no need for Windows-specific store type enum
StoreMap / StoreOSMap golang/nats-server/server/certstore/certstore.go:34 NOT_APPLICABLE .NET handles store locations via X509StoreLocation enum
MatchByType (type) golang/nats-server/server/certstore/certstore.go:44 NOT_APPLICABLE .NET can use X509FindType enum for similar functionality
MatchByMap golang/nats-server/server/certstore/certstore.go:52 NOT_APPLICABLE .NET equivalent: X509FindType
ParseCertStore golang/nats-server/server/certstore/certstore.go:68 NOT_APPLICABLE .NET has built-in X509Store with StoreLocation
ParseCertMatchBy golang/nats-server/server/certstore/certstore.go:80 NOT_APPLICABLE .NET has X509FindType
GetLeafIssuer golang/nats-server/server/certstore/certstore.go:88 MISSING Could port using X509Chain verification to find issuer
credential (interface) golang/nats-server/server/certstore/certstore.go:99 NOT_APPLICABLE .NET uses X509Certificate2 with private key; no separate credential interface needed

certstore/certstore_other.go — Non-Windows cert store stub

Go Symbol Go File:Line Status .NET Equivalent Notes
otherKey (struct) golang/nats-server/server/certstore/certstore_other.go:27 NOT_APPLICABLE Go build-tag stub for non-Windows; .NET X509Store is cross-platform
TLSConfig (stub) golang/nats-server/server/certstore/certstore_other.go:29 NOT_APPLICABLE Build-tag stub; not needed in .NET

certstore/certstore_windows.go — Windows cert store

Go Symbol Go File:Line Status .NET Equivalent Notes
Windows CNG/NCrypt constants golang/nats-server/server/certstore/certstore_windows.go:42 NOT_APPLICABLE .NET X509Store abstracts away Windows CNG; no P/Invoke needed
winCertStore (struct) golang/nats-server/server/certstore/certstore_windows.go:352 NOT_APPLICABLE .NET X509Store handles store access natively
TLSConfig (Windows) golang/nats-server/server/certstore/certstore_windows.go:202 NOT_APPLICABLE .NET can use X509Store + X509Certificate2 directly; no syscall-level TLS config needed
winKey (struct) golang/nats-server/server/certstore/certstore_windows.go:528 NOT_APPLICABLE .NET X509Certificate2.GetRSAPrivateKey/GetECDsaPrivateKey handles this
winSignECDSA / winSignRSA* golang/nats-server/server/certstore/certstore_windows.go:562 NOT_APPLICABLE .NET runtime handles signing through X509Certificate2 private key
createCACertsPool golang/nats-server/server/certstore/certstore_windows.go:173 NOT_APPLICABLE .NET uses X509Certificate2Collection / X509Chain for CA pool
certByIssuer / certBySubject / certByThumbprint golang/nats-server/server/certstore/certstore_windows.go:390 NOT_APPLICABLE .NET uses X509Store.Certificates.Find() with X509FindType
unmarshalECC / winUnmarshalRSA golang/nats-server/server/certstore/certstore_windows.go:844 NOT_APPLICABLE .NET BCL handles key deserialization

certstore/errors.go — Cert store errors

Go Symbol Go File:Line Status .NET Equivalent Notes
ErrBadCryptoStoreProvider golang/nats-server/server/certstore/errors.go:9 NOT_APPLICABLE .NET X509Store throws its own exceptions
ErrBadRSAHashAlgorithm golang/nats-server/server/certstore/errors.go:12 NOT_APPLICABLE .NET runtime handles hash algorithm validation
ErrBadSigningAlgorithm golang/nats-server/server/certstore/errors.go:15 NOT_APPLICABLE .NET runtime handles signing
ErrStoreRSASigningError golang/nats-server/server/certstore/errors.go:18 NOT_APPLICABLE .NET CryptographicException covers this
ErrStoreECDSASigningError golang/nats-server/server/certstore/errors.go:21 NOT_APPLICABLE .NET CryptographicException covers this
ErrNoPrivateKeyStoreRef golang/nats-server/server/certstore/errors.go:24 NOT_APPLICABLE .NET checks HasPrivateKey
ErrExtractingPrivateKeyMetadata golang/nats-server/server/certstore/errors.go:27 NOT_APPLICABLE .NET handles internally
ErrExtractingECCPublicKey golang/nats-server/server/certstore/errors.go:30 NOT_APPLICABLE .NET handles internally
ErrExtractingRSAPublicKey golang/nats-server/server/certstore/errors.go:33 NOT_APPLICABLE .NET handles internally
ErrExtractingPublicKey golang/nats-server/server/certstore/errors.go:36 NOT_APPLICABLE .NET handles internally
ErrBadPublicKeyAlgorithm golang/nats-server/server/certstore/errors.go:39 NOT_APPLICABLE .NET handles internally
ErrExtractPropertyFromKey golang/nats-server/server/certstore/errors.go:42 NOT_APPLICABLE .NET handles internally
ErrBadECCCurveName golang/nats-server/server/certstore/errors.go:45 NOT_APPLICABLE .NET handles internally
ErrFailedCertSearch golang/nats-server/server/certstore/errors.go:48 NOT_APPLICABLE .NET X509Store.Find returns empty collection
ErrFailedX509Extract golang/nats-server/server/certstore/errors.go:51 NOT_APPLICABLE .NET handles internally
ErrBadMatchByType golang/nats-server/server/certstore/errors.go:54 NOT_APPLICABLE .NET uses enum
ErrBadCertStore golang/nats-server/server/certstore/errors.go:57 NOT_APPLICABLE .NET uses enum
ErrConflictCertFileAndStore golang/nats-server/server/certstore/errors.go:60 MISSING Config validation for conflicting cert_file + cert_store not ported
ErrBadCertStoreField golang/nats-server/server/certstore/errors.go:63 NOT_APPLICABLE Config validation
ErrBadCertMatchByField golang/nats-server/server/certstore/errors.go:66 NOT_APPLICABLE Config validation
ErrBadCertMatchField golang/nats-server/server/certstore/errors.go:69 NOT_APPLICABLE Config validation
ErrBadCaCertMatchField golang/nats-server/server/certstore/errors.go:72 NOT_APPLICABLE Config validation
ErrBadCertMatchSkipInvalidField golang/nats-server/server/certstore/errors.go:75 NOT_APPLICABLE Config validation
ErrOSNotCompatCertStore golang/nats-server/server/certstore/errors.go:78 NOT_APPLICABLE .NET X509Store is cross-platform

Keeping This File Updated

After porting work is completed:

  1. Update status: Change MISSING → PORTED or PARTIAL → PORTED for each item completed
  2. Add .NET path: Fill in the ".NET Equivalent" column with the actual file:line
  3. Re-count LOC: Update the LOC numbers in stillmissing.md:
    # Re-count .NET source LOC for this module
    find src/NATS.Server/Tls/ -name '*.cs' -type f -exec cat {} + | wc -l
    # Re-count .NET test LOC for this module
    # TLS tests are in root test directory — filter manually
    
  4. Add a changelog entry below with date and summary of what was ported
  5. Update the parity DB if new test mappings were created:
    sqlite3 docs/test_parity.db "INSERT INTO test_mappings (go_test_id, dotnet_test_id, confidence, notes) VALUES (?, ?, 'manual', 'ported in YYYY-MM-DD session')"
    

Change Log

Date Change By
2026-02-25 File created with LLM analysis instructions auto
2026-02-25 Completed full gap inventory: 12 Go source files analyzed, 144 symbols classified (20 PORTED, 9 PARTIAL, 70 MISSING, 45 NOT_APPLICABLE, 0 DEFERRED) claude-opus