docs(grpc-events): Path B — ExchangeKey ECDH clears 2 of 3 layers
Records that the pure-managed P-256 ExchangeKey works (cleared the v8 client-key check; error advanced to 132/171 AuthenticationFailed). The remaining layer is the 26-byte credential-token KDF, which requires recovering the native key derivation. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01B6mcaT2PjRFKcogzp9UkfC
This commit is contained in:
@@ -229,3 +229,28 @@ size) — using .NET `ECDiffieHellman`, establish the client key, then reissue t
|
||||
Open question for Path B: whether merely *completing* the ECDH key agreement registers the client key
|
||||
(so the zeroed openParameters token still rides through), or whether the token must also be derived
|
||||
from the shared secret (full KDF/cipher RE).
|
||||
|
||||
### Path B started 2026-06-23 — ExchangeKey ECDH works; cleared 2 of 3 layers
|
||||
|
||||
Implemented `HistoryService.ExchangeKey` as a **pure-managed P-256 ECDH** key exchange
|
||||
(`HistorianNativeHandshake.BuildExchangeKeyClientHello` / `DeriveExchangeKeySecret`, .NET
|
||||
`ECDiffieHellman` over `nistP256`; wire format `"ECK1" + u32(32) + X(32) + Y(32)`) and wired it into
|
||||
`HistorianGrpcHandshake.OpenSession(eventConnection: true)` ahead of the v8 `OpenConnection`,
|
||||
on the same context-key handle. Live result against the server: the **`ExchangeKey` RPC succeeds**
|
||||
(the server accepted our public key), and the v8 `OpenConnection` error **moved one layer deeper**:
|
||||
|
||||
```
|
||||
Path A (no ExchangeKey): 132/34 "Failed to get client key"
|
||||
Path B (ExchangeKey ECDH): 132/171 AuthenticationFailed "EstablishConnection — Authentication failed"
|
||||
```
|
||||
|
||||
So the ECDH cleared the client-key check; the remaining blocker is **authentication**: the 26-byte
|
||||
v8 credential token must be a *valid* value derived from the ECDH shared secret (not zeros). This is
|
||||
the token KDF/cipher — the part that is not yet reverse-engineered and that would require analyzing
|
||||
AVEVA's native ExchangeKey/credential crypto to recover the derivation (the .NET-shipped result stays
|
||||
pure managed either way). The "Path B-lite" hypothesis (zeroed token rides through after key
|
||||
agreement) is therefore disproven at the auth layer — 2 of 3 layers are cleared, the 3rd is the
|
||||
credential-token derivation. ExchangeKey + the v8 serializer are committed and ready; the orchestrator
|
||||
stays on v6 (set `eventConnection: true` to re-arm once the token KDF lands). The token-loop routing
|
||||
guardrail (`HistorianGrpcHandshakeRoutingTests`) was scoped to the closure so the legitimate
|
||||
ExchangeKey call is allowed while still pinning that the Negotiate token loop never routes there.
|
||||
|
||||
Reference in New Issue
Block a user