Initial project state: .NET reference, design, Rust port (M0+M1), evidence
rust / build / test / clippy / fmt (push) Has been cancelled
rust / build / test / clippy / fmt (push) Has been cancelled
Layout:
- src/ .NET 10 x64 reference: MxNativeCodec, MxNativeClient,
MxAsbClient, probes, tests, harnesses. Executable spec.
- design/ Architectural plan for the Rust port (M0–M6), error
model, protocol invariants, risks (R1–R16), adversarial
review log (review.md).
- rust/ Rust workspace. M0 skeleton + M1 codec parity.
mxaccess-codec: 215 unit tests + 2 cross-implementation
parity tests (byte-identical against .NET reference).
Other crates are M0 stubs awaiting M2+.
- captures/ Frida + netsh + pcap evidence per CLAUDE.md
("captures are evidence, not throwaway logs").
- analysis/ Decompiled C# (frida/proxy/decompiled-*),
Ghidra exports for native DLLs (`exports/` only —
working state at `projects/` and AVEVA's input
binaries at `input/` are gitignored).
- docs/ Reverse-engineering reference docs.
- tools/ Setup-LiveProbeEnv.ps1 (Infisical credential fetcher),
Compute-Crc.ps1 (.NET parity helper).
- .github/workflows/ Rust CI: fmt + build + test + clippy on Windows.
- LICENSE MIT (Joseph Doherty, 2026).
Verified:
- cargo test --workspace → 217 passed (215 unit + 2 .NET parity), 0 failed
- cargo clippy --workspace -- -D warnings → clean
- cargo fmt --all -- --check → clean
- cargo publish --dry-run -p mxaccess-codec → packages cleanly
Excluded from history (see .gitignore):
- **/bin, **/obj, **/target — build artifacts
- analysis/ghidra/projects/ — Ghidra working state (regenerable)
- analysis/ghidra/input/ — AVEVA proprietary DLLs (vendor IP)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
+251
@@ -0,0 +1,251 @@
|
||||
using System;
|
||||
using System.Numerics;
|
||||
using System.Security.Cryptography;
|
||||
using ArchestrAServices.Common;
|
||||
|
||||
namespace Asb.Base.V2;
|
||||
|
||||
public class SysAuthParameters
|
||||
{
|
||||
private const string SDecimal768 = "1552518092300708935130918131258481755631334049434514313202351194902966239949102107258669453876591642442910007680288864229150803718918046342632727613031282983744380820890196288509170691316593175367469551763119843371637221007210577919";
|
||||
|
||||
private static readonly byte[] sOakley768 = new byte[96]
|
||||
{
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 201, 15,
|
||||
218, 162, 33, 104, 194, 52, 196, 198, 98, 139,
|
||||
128, 220, 28, 209, 41, 2, 78, 8, 138, 103,
|
||||
204, 116, 2, 11, 190, 166, 59, 19, 155, 34,
|
||||
81, 74, 8, 121, 142, 52, 4, 221, 239, 149,
|
||||
25, 179, 205, 58, 67, 27, 48, 43, 10, 109,
|
||||
242, 95, 20, 55, 79, 225, 53, 109, 109, 81,
|
||||
194, 69, 228, 133, 181, 118, 98, 94, 126, 198,
|
||||
244, 76, 66, 233, 166, 58, 54, 32, 255, 255,
|
||||
255, 255, 255, 255, 255, 255
|
||||
};
|
||||
|
||||
private const string SDecimal1024 = "179769313486231590770839156793787453197860296048756011706444423684197180216158519368947833795864925541502180565485980503646440548199239100050792877003355816639229553136239076508735759914822574862575007425302077447712589550957937778424442426617334727629299387668709205606050270810842907692932019128194";
|
||||
|
||||
private static readonly byte[] sOakley1024 = new byte[128]
|
||||
{
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 201, 15,
|
||||
218, 162, 33, 104, 194, 52, 196, 198, 98, 139,
|
||||
128, 220, 28, 209, 41, 2, 78, 8, 138, 103,
|
||||
204, 116, 2, 11, 190, 166, 59, 19, 155, 34,
|
||||
81, 74, 8, 121, 142, 52, 4, 221, 239, 149,
|
||||
25, 179, 205, 58, 67, 27, 48, 43, 10, 109,
|
||||
242, 95, 20, 55, 79, 225, 53, 109, 109, 81,
|
||||
194, 69, 228, 133, 181, 118, 98, 94, 126, 198,
|
||||
244, 76, 66, 233, 166, 55, 237, 107, 11, 255,
|
||||
92, 182, 244, 6, 183, 237, 238, 56, 107, 251,
|
||||
90, 137, 159, 165, 174, 159, 36, 17, 124, 75,
|
||||
31, 230, 73, 40, 102, 81, 236, 230, 83, 129,
|
||||
255, 255, 255, 255, 255, 255, 255, 255
|
||||
};
|
||||
|
||||
private const string SDecimal1536 = "2410312426921032588552076022197566074856950548502459942654116941958108831682612228890093858261341614673227141477904012196503648957050582631942730706805009223062734745341073406696246014589361659774041027169249453200378729434170325843778659198143763193776859869524088940195577346119843545301547043747207749969763750084308926339295559968882457872412993810129130294592999947926365264059284647209730384947211681434464714438488520940127459844288859336526896320919633919";
|
||||
|
||||
private static readonly byte[] sOakley1536 = new byte[192]
|
||||
{
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 201, 15,
|
||||
218, 162, 33, 104, 194, 52, 196, 198, 98, 139,
|
||||
128, 220, 28, 209, 41, 2, 78, 8, 138, 103,
|
||||
204, 116, 2, 11, 190, 166, 59, 19, 155, 34,
|
||||
81, 74, 8, 121, 142, 52, 4, 221, 239, 149,
|
||||
25, 179, 205, 58, 67, 27, 48, 43, 10, 109,
|
||||
242, 95, 20, 55, 79, 225, 53, 109, 109, 81,
|
||||
194, 69, 228, 133, 181, 118, 98, 94, 126, 198,
|
||||
244, 76, 66, 233, 166, 55, 237, 107, 11, 255,
|
||||
92, 182, 244, 6, 183, 237, 238, 56, 107, 251,
|
||||
90, 137, 159, 165, 174, 159, 36, 17, 124, 75,
|
||||
31, 230, 73, 40, 102, 81, 236, 228, 91, 61,
|
||||
194, 0, 124, 184, 161, 99, 191, 5, 152, 218,
|
||||
72, 54, 28, 85, 211, 154, 105, 22, 63, 168,
|
||||
253, 36, 207, 95, 131, 101, 93, 35, 220, 163,
|
||||
173, 150, 28, 98, 243, 86, 32, 133, 82, 187,
|
||||
158, 213, 41, 7, 112, 150, 150, 109, 103, 12,
|
||||
53, 78, 74, 188, 152, 4, 241, 116, 108, 8,
|
||||
202, 35, 115, 39, 255, 255, 255, 255, 255, 255,
|
||||
255, 255
|
||||
};
|
||||
|
||||
private const int DhKeySizeDft = 1024;
|
||||
|
||||
private const int DhSecretSizeDft = 160;
|
||||
|
||||
private static readonly string dhPassphraseDft = Environment.MachineName;
|
||||
|
||||
private const uint ConnectionLifetimeDft = 60000u;
|
||||
|
||||
private const string SaltValueDft = "s@1tValue";
|
||||
|
||||
private static readonly string hashAlgorithmDft = CngAlgorithm.MD5.ToString();
|
||||
|
||||
private const int PasswordIterationsDft = 1;
|
||||
|
||||
private const string InitialVectorDft = "ba172e9941be138b";
|
||||
|
||||
private const int KeySizeDft = 256;
|
||||
|
||||
private readonly ISolutionParameters solutionParameterSource;
|
||||
|
||||
private string sysAuthPassphrase;
|
||||
|
||||
public string AsbSolutionName { get; set; }
|
||||
|
||||
public bool AsbSolutionValid { get; set; }
|
||||
|
||||
public int DhKeySize { get; set; }
|
||||
|
||||
public int DhSecretSize { get; set; }
|
||||
|
||||
public BigInteger DhP { get; set; }
|
||||
|
||||
public BigInteger DhG { get; set; }
|
||||
|
||||
public string DhPassphrase
|
||||
{
|
||||
get
|
||||
{
|
||||
return sysAuthPassphrase;
|
||||
}
|
||||
set
|
||||
{
|
||||
ResetToDefaults();
|
||||
sysAuthPassphrase = value;
|
||||
AsbSolutionValid = true;
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] DhCertificate { get; private set; }
|
||||
|
||||
public uint ConnectionLifetime { get; set; }
|
||||
|
||||
public string SaltValue { get; set; }
|
||||
|
||||
public string HashAlgorithm { get; set; }
|
||||
|
||||
public int PasswordIterations { get; set; }
|
||||
|
||||
public string InitialVector { get; set; }
|
||||
|
||||
public int KeySize { get; set; }
|
||||
|
||||
public SysAuthParameters(string asbSolutionName = null)
|
||||
{
|
||||
ServiceTrace.LogVerbose("SysAuthParameters constructor with asbSolutionName = {0}", string.IsNullOrEmpty(asbSolutionName) ? "<null>" : asbSolutionName);
|
||||
AsbSolutionName = asbSolutionName;
|
||||
solutionParameterSource = new SolutionParameters();
|
||||
AsbSolutionValid = false;
|
||||
ResetToDefaults();
|
||||
LoadAsbSolution();
|
||||
}
|
||||
|
||||
internal SysAuthParameters(string asbSolutionName, ISolutionParameters parameters)
|
||||
{
|
||||
ServiceTrace.LogVerbose("SysAuthParameters constructor with asbSolutionName = {0}", string.IsNullOrEmpty(asbSolutionName) ? "<null>" : asbSolutionName);
|
||||
AsbSolutionName = asbSolutionName;
|
||||
solutionParameterSource = parameters;
|
||||
AsbSolutionValid = false;
|
||||
ResetToDefaults();
|
||||
LoadAsbSolution();
|
||||
}
|
||||
|
||||
private void ResetToDefaults()
|
||||
{
|
||||
AsbSolutionValid = false;
|
||||
DhKeySize = 1024;
|
||||
DhSecretSize = 160;
|
||||
sysAuthPassphrase = dhPassphraseDft;
|
||||
DhCertificate = null;
|
||||
ConnectionLifetime = 60000u;
|
||||
SaltValue = "s@1tValue";
|
||||
HashAlgorithm = hashAlgorithmDft;
|
||||
PasswordIterations = 1;
|
||||
InitialVector = "ba172e9941be138b";
|
||||
KeySize = 256;
|
||||
GenerateKey();
|
||||
}
|
||||
|
||||
private void LoadAsbSolution()
|
||||
{
|
||||
ServiceTrace.LogResume("LoadAsbSolution entry");
|
||||
try
|
||||
{
|
||||
if (solutionParameterSource == null)
|
||||
{
|
||||
ServiceTrace.LogError("LoadAsbSolution: No solution source provided");
|
||||
AsbSolutionValid = false;
|
||||
return;
|
||||
}
|
||||
if (string.IsNullOrEmpty(AsbSolutionName))
|
||||
{
|
||||
AsbSolutionName = solutionParameterSource.DefaultAsbSolutionName;
|
||||
if (string.IsNullOrEmpty(AsbSolutionName))
|
||||
{
|
||||
ServiceTrace.LogError("LoadAsbSolution: Unable to get default ASB solution name");
|
||||
AsbSolutionValid = false;
|
||||
}
|
||||
ServiceTrace.LogInfo("LoadAsbSolution created with empty solution name, resetting to default '{0}'", string.IsNullOrEmpty(AsbSolutionName) ? "<null>" : AsbSolutionName);
|
||||
}
|
||||
AsbSolutionValid = false;
|
||||
if (!string.IsNullOrEmpty(AsbSolutionName))
|
||||
{
|
||||
ServiceTrace.LogVerbose("LoadAsbSolution: Using solution {0}", AsbSolutionName);
|
||||
string errorMessage = string.Empty;
|
||||
DhPassphrase = solutionParameterSource.GetSolutionPassphrase(AsbSolutionName, delegate(string msg)
|
||||
{
|
||||
errorMessage = msg;
|
||||
});
|
||||
if (string.IsNullOrEmpty(errorMessage))
|
||||
{
|
||||
DhCertificate = solutionParameterSource.GetSolutionCertificate(AsbSolutionName);
|
||||
SaltValue = solutionParameterSource.GetSolutionSaltValue(AsbSolutionName);
|
||||
HashAlgorithm = solutionParameterSource.GetSolutionHashAlgorithm(AsbSolutionName);
|
||||
PasswordIterations = solutionParameterSource.GetSolutionPasswordIterations(AsbSolutionName);
|
||||
InitialVector = solutionParameterSource.GetSolutionInitialVector(AsbSolutionName);
|
||||
KeySize = solutionParameterSource.GetSolutionKeySize(AsbSolutionName);
|
||||
DhP = solutionParameterSource.GetSolutionPrime(AsbSolutionName);
|
||||
DhG = solutionParameterSource.GetSolutionGenerator(AsbSolutionName);
|
||||
AsbSolutionValid = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
ServiceTrace.LogError("LoadAsbSolution: Error loading passphrase: " + errorMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
ServiceTrace.LogError("LoadAsbSolution: Exception caught: {0}", ex.Message);
|
||||
AsbSolutionValid = false;
|
||||
}
|
||||
ServiceTrace.LogSuspend("LoadAsbSolution exit");
|
||||
}
|
||||
|
||||
private void GenerateKey()
|
||||
{
|
||||
bool flag;
|
||||
BigInteger result;
|
||||
if (DhKeySize == 768)
|
||||
{
|
||||
flag = BigInteger.TryParse("1552518092300708935130918131258481755631334049434514313202351194902966239949102107258669453876591642442910007680288864229150803718918046342632727613031282983744380820890196288509170691316593175367469551763119843371637221007210577919", out result);
|
||||
}
|
||||
else if (DhKeySize == 1024)
|
||||
{
|
||||
flag = BigInteger.TryParse("179769313486231590770839156793787453197860296048756011706444423684197180216158519368947833795864925541502180565485980503646440548199239100050792877003355816639229553136239076508735759914822574862575007425302077447712589550957937778424442426617334727629299387668709205606050270810842907692932019128194", out result);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (DhKeySize != 1536)
|
||||
{
|
||||
throw new ArgumentException("Invalid bit size.");
|
||||
}
|
||||
flag = BigInteger.TryParse("2410312426921032588552076022197566074856950548502459942654116941958108831682612228890093858261341614673227141477904012196503648957050582631942730706805009223062734745341073406696246014589361659774041027169249453200378729434170325843778659198143763193776859869524088940195577346119843545301547043747207749969763750084308926339295559968882457872412993810129130294592999947926365264059284647209730384947211681434464714438488520940127459844288859336526896320919633919", out result);
|
||||
}
|
||||
if (flag)
|
||||
{
|
||||
DhP = result;
|
||||
}
|
||||
DhG = new BigInteger(22);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user